diff --git a/.gitignore b/.gitignore index 2b880085b..b4dfddcac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team +# SPDX-FileCopyrightText: (C) 2004-2022 Retroshare Team # SPDX-License-Identifier: CC0-1.0 *.o @@ -15,3 +15,23 @@ Thumbs.db *.pro.user .kdev4 *.kdev4 + +.qmake.stash + +!supportlibs/libsam3/Makefile + +# QtCreator cruft +*CMakeLists.txt.user + +# Build artifacts +/jsonapi-generator/src/jsonapi-generator +/jsonapi-generator/src/jsonapi-generator-doxygen-final.conf +/jsonapi-generator/src/jsonapi-includes.inl +/jsonapi-generator/src/jsonapi-wrappers.inl +/jsonapi-generator/src/xml/ +/retroshare-friendserver/src/retroshare-friendserver +/retroshare-gui/src/include/ +/retroshare-gui/src/retroshare +/retroshare-gui/src/temp/ +/retroshare-service/src/retroshare-service +/*.tar.?z diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d620b3719..c91f867a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,32 +1,48 @@ image: docker:stable services: - - docker:stable-dind + - docker:stable-dind + +stages: + - build + - test workflow: rules: - if: $CI_MERGE_REQUEST_ID - if: $CI_COMMIT_BRANCH -build-and-test: +variables: + UBUNTU_TESTING_IMAGE_TAG: "$CI_REGISTRY_IMAGE/gitlabci_outputs/ubuntu_testing:$CI_COMMIT_SHA" + +build-ubuntu-test-image: + stage: build script: - - > - if [ -n "$CI_MERGE_REQUEST_ID" ]; then - REPO_ARGS="--build-arg REPO_URL=$CI_MERGE_REQUEST_SOURCE_PROJECT_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" ; - else - REPO_ARGS="--build-arg REPO_URL=$CI_REPOSITORY_URL" ; - REPO_ARGS="$REPO_ARGS --build-arg REPO_BRANCH=$CI_COMMIT_BRANCH" ; - fi ; - export REPO_ARGS ; - echo REPO_ARGS=$REPO_ARGS ; + - > + docker login "$CI_REGISTRY" + --username "$CI_REGISTRY_USER" + --password "$CI_REGISTRY_PASSWORD" - mkdir Dockercontext - > - docker build -t retroshare:testing $REPO_ARGS + docker build + -t $UBUNTU_TESTING_IMAGE_TAG + $($CI_PROJECT_DIR/build_scripts/GitlabCI/getRepoArgs.sh) --file $CI_PROJECT_DIR/build_scripts/GitlabCI/gitlabCI.Dockerfile Dockercontext + - docker push $UBUNTU_TESTING_IMAGE_TAG + - echo UBUNTU_TESTING_IMAGE_TAG=$UBUNTU_TESTING_IMAGE_TAG + +test-ubuntu: + stage: test + script: + - > + docker login "$CI_REGISTRY" + --username "$CI_REGISTRY_USER" + --password "$CI_REGISTRY_PASSWORD" + - echo UBUNTU_TESTING_IMAGE_TAG=$UBUNTU_TESTING_IMAGE_TAG + - docker pull $UBUNTU_TESTING_IMAGE_TAG - > - docker run --name retroshare --detach --tty retroshare:testing + docker run --name retroshare --detach --tty $UBUNTU_TESTING_IMAGE_TAG retroshare-service --jsonApiPort 9092 - apk add jq - > diff --git a/.gitmodules b/.gitmodules index c35876fc6..3c767cf19 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,24 @@ [submodule "supportlibs/rapidjson"] path = supportlibs/rapidjson url = https://github.com/Tencent/rapidjson.git +[submodule "supportlibs/libsam3"] + path = supportlibs/libsam3 + url = https://github.com/i2p/libsam3.git +[submodule "supportlibs/jni.hpp"] + path = supportlibs/jni.hpp + url = https://github.com/RetroShare/jni.hpp.git +[submodule "openpgpsdk"] + path = openpgpsdk + url = ../OpenPGP-SDK + branch = master +[submodule "libbitdht"] + path = libbitdht + url = ../BitDHT + branch = master +[submodule "libretroshare"] + path = libretroshare + url = ../libretroshare + branch = master +[submodule "retroshare-webui"] + path = retroshare-webui + url = ../RSNewWebUI diff --git a/.travis.yml b/.travis.yml index cfe2eac21..ef38661ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,12 @@ language: cpp matrix: include: - - os: linux - dist: bionic - sudo: required - compiler: gcc +# - os: linux +# dist: bionic +# sudo: required +# compiler: gcc - os: osx - osx_image: xcode10.1 + osx_image: xcode10.2 compiler: clang sudo: false @@ -68,11 +68,11 @@ before_script: fi script: - - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j4; fi + - if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then travis_wait 30 make -j$(nproc); fi after_success: - if [ $TRAVIS_OS_NAME == osx ]; then build_scripts/OSX/travis_makeOSXPackage.sh ; fi - - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi +# - if [ $TRAVIS_OS_NAME == linux ] && [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then make -j2; fi # branches: diff --git a/README.asciidoc b/README.asciidoc index 734c3d083..e1f41e74d 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -10,10 +10,21 @@ RetroShare provides file sharing, chat, messages, forums, channels and more. .Build Status |=============================================================================== |GNU/Linux (via Gitlab CI) | image:https://gitlab.com/RetroShare/RetroShare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/RetroShare/-/commits/master",title="pipeline status"] -|GNU/Linux, macOS, (via Travis CI) | image:https://travis-ci.org/RetroShare/RetroShare.svg?branch=master[link="https://travis-ci.org/RetroShare/RetroShare"] |Windows (via AppVeyor) | image:https://ci.appveyor.com/api/projects/status/github/RetroShare/RetroShare?svg=true[link="https://ci.appveyor.com/project/RetroShare58622/retroshare"] +|macOS, (via Travis CI) | image:https://app.travis-ci.com/RetroShare/RetroShare.svg?branch=master[link="https://app.travis-ci.com/github/RetroShare/RetroShare"] +|libretroshare GNU/Linux, Android (via Gitlab CI) | image:https://gitlab.com/RetroShare/libretroshare/badges/master/pipeline.svg[link="https://gitlab.com/RetroShare/libretroshare/-/commits/master",title="pipeline status"] |=============================================================================== +== Get the source + +Clone this repository, enter the directory and then get the submodules with the +following command + +[source,bash] +-------- +git submodule update --init --remote --force libbitdht/ libretroshare/ openpgpsdk/ +-------- + == Compilation diff --git a/RetroShare.pro b/RetroShare.pro index dc590dd17..944e8204e 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -55,6 +55,12 @@ retroshare_service { retroshare_service.target = retroshare_service } +retroshare_friendserver { + SUBDIRS += retroshare_friendserver + retroshare_friendserver.file = retroshare-friendserver/src/retroshare-friendserver.pro + retroshare_friendserver.depends = libretroshare + retroshare_friendserver.target = retroshare_friendserver +} retroshare_plugins { SUBDIRS += plugins plugins.file = plugins/plugins.pro @@ -62,6 +68,13 @@ retroshare_plugins { plugins.target = plugins } +rs_webui { + SUBDIRS += retroshare-webui + retroshare-webui.file = retroshare-webui/webui.pro + retroshare-webui.target = rs_webui + retroshare-webui.depends = retroshare_gui +} + wikipoos { SUBDIRS += pegmarkdown pegmarkdown.file = supportlibs/pegmarkdown/pegmarkdown.pro diff --git a/appveyor.yml b/appveyor.yml index cd706d02c..5bc004fa1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -258,10 +258,10 @@ after_build: # artifacts configuration # #---------------------------------# -#artifacts: -# - path: '**\*.exe' -# - path: filelist.txt -# - path: $(RS_DEPLOY) +artifacts: + - path: '**\*.exe' + - path: filelist.txt + - path: $(RS_DEPLOY) # # # pushing a single file diff --git a/build_scripts/Android/README.asciidoc b/build_scripts/Android/README.asciidoc deleted file mode 100644 index 3f978cfd1..000000000 --- a/build_scripts/Android/README.asciidoc +++ /dev/null @@ -1,399 +0,0 @@ -= RetroShare development on Android - -// SPDX-FileCopyrightText: RetroShare Team -// SPDX-License-Identifier: CC-BY-SA-4.0 - - -Compiling an application for Android is not as easy as one would imagine, -expecially one like RetroShare that has a big codebase and is not well -documented. This document is aimed to empower the reader so she can hopefully -succed or at least have a significant help in compiling her own RetroShare APK -installable on Android. - - -== Preparing The Environement - -First of all setup your Qt for Android development environement following the -guide on the link:http://doc.qt.io/qt-5/androidgs.html[Qt for android web site]. -At this point you should have Android SDK, Android NDK, and Qt for Android -working fine, and you should be capable of executing on an Android emulator or -on your Android phone Qt for Android examples. - -But RetroShare is not as simple to compile as those examples. The good news is -that Android NDK ships all the necessary to build a custom toolchain that is -suitable to build RetroShare. -In order to build the toolchain with needed libraries RetroShare provides the -+android-prepare-toolchain.sh+ script; before you execute it you should define -some variables the script cannot determine in an easy and reliable manner by -itself in your terminal. - -[source,bash] -------------------------------------------------------------------------------- -## The path where Android NDK is installed in your system -export ANDROID_NDK_PATH="/opt/android-ndk/" - -## The path where your fresh compiled toolchain will be installed, make sure -## the parent exists -export NATIVE_LIBS_TOOLCHAIN_PATH="${HOME}/Builds/android-toolchains/retroshare-android/" - -## The CPU architecture of the Android device you want to target -export ANDROID_NDK_ARCH="arm" - -## The Android API level the Android device you want to target -export ANDROID_PLATFORM_VER="16" - -## The number of core that yout host CPU have (just to speed up compilation) set -## it to 1 if unsure -export HOST_NUM_CPU=1 - -./android-prepare-toolchain.sh -------------------------------------------------------------------------------- - - -== Preparing Qt Creator - -Now that your environement is set up you should configure Qt Creator for Android -following the -link:http://doc.qt.io/qtcreator/creator-developing-android.html[official guide]. -At the end of this step your Qt Creator should recognize the Android compiler -and the Qt for Android kit. - -Your Kit is now ready to use. Now you can open RetroShare as a Qt Creator -project and in the Projects left menu add the newly created kit if not already -present, so you can select it on the build type selection button down on the -left. - -Now you need to set properly a few options like `JSONAPI_GENERATOR_EXE` and -disable some of RetroShare modules like `retroshare-gui` that are not available -on Android so you will have to go to - -_Qt Creator left pane -> Projects -> Build and Run -> Android SOMESTUFF kit -> -Build Steps -> qmake -> Additional arguments_ + - -and add the following configurations (change `Your_Path` according to your -deployment) - -[source,makefile] -------------------------------------------------------------------------------- -CONFIG+=retroshare_service CONFIG+=rs_jsonapi CONFIG+=rs_deep_search -RS_UPNP_LIB=miniupnpc -JSONAPI_GENERATOR_EXE=Your_Path/jsonapi-generator/src/jsonapi-generator -NATIVE_LIBS_TOOLCHAIN_PATH=Your_Path/retroshare-android-16-arm/ -CONFIG+=no_retroshare_gui CONFIG+=no_rs_service_webui_terminal_password -CONFIG+=no_rs_service_terminal_login -------------------------------------------------------------------------------- - -TIP: Some versions of QtCreator try to find the Android SDK in -`/opt/android/sdk`. A workaround to this is to make a symbolic link there -pointing to your SDK installation path, like -+mkdir -p /opt/android/sdk && ln -s /home/user/android-sdk-linux -/opt/android/sdk+ - - -== Quircks - -=== Protected Apps - -On some Android devices like +Huawei ALE-L21+ background applications are -killed when screen is turned off unless they are in the _protected app_ list. -At moment seems apps developers don't have a way to have the application -_protected_ by default, unless the phone vendor decide the app is _popular_ so -the user have to enable _protection_ for RetroShare manually on those mobile -phones. + - -{empty} + -To enable enable _protection_: +Android menu -> Settings -> Privacy & security --> Protected apps -> RetroShare+ + -{empty} + - -Other devices may offer similar _features_ please report them. - - -=== APK signature mismatch - -If you try to install a RetroShare APK that comes from a different source -(eg: if you try to upgrade from F-Droid when you originally installed an APK -build by yourself) Android will prevent that from happening. In that case the -only solution is to uninstall the app and then install the new APK but if you do -it also the application data and your precious cryptographic keys, friend list -etc. will be lost forever. -To avoid that you can attempt to manually backup and then restore from the -command-line (`adb backup` seems not working either) to change the app source -without erasing the appliation data. - -CAUTION: Following steps require root access on your Android device - -.Backup RetroShare Android application data -[source,bash] --------------------------------------------------------------------------------- -export ORIG_DIR="/data/data/org.retroshare.android.qml_app" -export BACKUP_DIR="org.retroshare.android.qml_app.backup" - -adb root - -adb shell am force-stop org.retroshare.android.qml_app -sleep 1s - -mkdir ${BACKUP_DIR} - -# Avoid adb pull failing -adb shell rm ${ORIG_DIR}/files/.retroshare/libresapi.sock -adb pull ${ORIG_DIR}/files/ ${BACKUP_DIR}/files/ --------------------------------------------------------------------------------- - -After this you should be able to uninstall the old APK with your preferred -method, as example from the command-line. - -.Uninstall RetroShare Android from the command-line -[source,bash] --------------------------------------------------------------------------------- -adb uninstall org.retroshare.android.qml_app --------------------------------------------------------------------------------- - -Now you can install a different signature APK and then restore the application -data with the following commands. - -[source,bash] --------------------------------------------------------------------------------- -export ORIG_DIR="/data/data/org.retroshare.android.qml_app" -export BACKUP_DIR="org.retroshare.android.qml_app.backup" - -adb root - -## Launch the app to make sure the parent directory exists and has proper owner -adb shell monkey -p org.retroshare.android.qml_app -c android.intent.category.LAUNCHER 1 -sleep 1s - -adb shell am force-stop org.retroshare.android.qml_app -sleep 1s - - -APP_OWNER="$(adb shell busybox ls -lnd ${ORIG_DIR} | awk '{print $3":"$4}')" -adb shell rm -rf ${ORIG_DIR}/files -adb push ${BACKUP_DIR}/files/ ${ORIG_DIR}/files/ -adb shell busybox chown -R ${APP_OWNER} ${ORIG_DIR}/files/ --------------------------------------------------------------------------------- - -Opening RetroShare android app now should show your old profile. - - -== Debugging with GDB - -If building RetroShare Android package seems tricky, setting up a functional -debugging environement for it feels like black magic. This section is meant to -help you doing it with less headache and hopefully in a reproducible way. - -Unfortunately at the time of the last update to this guide, Qt build system -strips debugging symbols from the package and from the buildroot also if you -compile with debugging enabled. Fiddling with `qmake` configurations and -variables like `CONFIG+=debug`, `CONFIG+=force_debug_info` or `QMAKE_STRIP` -either as commandline arguments or inside retroshare `.pro` and `.pri` files is -uneffective. IMHO Qt should handle this on itself so it is probably worth -reporting a bug to them. So to workaround this problem you need to fiddle a bit -with the Android NDK. In my case I always keep +Debug+ or +Release+ suffix in -my build directory name depending on what kind of build it is, so I use this -information and modify `llvm-strip` in a way that it will strip only if stripped -file path doesn't contain +Debug+. - -.Modify llvm-strip inside Android NDK --------------------------------------------------------------------------------- -## Set ANDROID_NDK_PATH to your Android NDK installation path -export ANDROID_NDK_PATH="/opt/android-ndk/" - -## Define a convenience variable with llvm-strip path -export ANDROID_NDK_LLVM_STRIP="${ANDROID_NDK_PATH}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip" - -## If not existing yer create a backup of the original llvm-strip -[ -f "${ANDROID_NDK_LLVM_STRIP}.back" ] || - cp "${ANDROID_NDK_LLVM_STRIP}" "${ANDROID_NDK_LLVM_STRIP}.back" - -## Create a new llvm-strip that does nothing if the argument path contains Debug -cat > "${ANDROID_NDK_LLVM_STRIP}" << LLVMSTRIPTRICK -#!/bin/bash - -echo "\${2}" | grep -q Debug || - "${ANDROID_NDK_LLVM_STRIP}.back" --strip-all "\${2}" - -LLVMSTRIPTRICK - -## Eventually you can revert back simply by running -# `mv "${ANDROID_NDK_LLVM_STRIP}.back" "${ANDROID_NDK_LLVM_STRIP}"` --------------------------------------------------------------------------------- - - -To attach to the `retroshare-service` running on Android you need also to pull a -debugging sysroot out of your device first, RetroShare sources provides an -helper script to do that. - -.Prepare debugging sysroot with helper script -[source,bash] --------------------------------------------------------------------------------- -## Set RetroShare source path -export RS_SOURCE_DIR="${HOME}/Development/rs-develop" - -## Optionally set your device ID first available will be used, you can run -## `adb devices` to list available devices. -#export ANDROID_SERIAL="YT013PSPGK" - -## Optionally set a path where to save the debugging sysroot otherwise default -## is used. -#export DEBUG_SYSROOT="${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" - -## Run the helper script -${RS_SOURCE_DIR}/build_scripts/Android/pull_sysroot.sh --------------------------------------------------------------------------------- - -.Prepare Android NDK GDB configurations -[source,bash] --------------------------------------------------------------------------------- -## Optionally set Qt version variable consistently with your installation -export QT_VERSION="5.12.7" - -## Optionally set Qt architecture variable consistently with Android device -export QT_ARCH="arm64_v8a" - -## Optionally set Qt path variable consistently with your installation -export QT_DIR="/opt/Qt-${QT_VERSION}/${QT_VERSION}/" - -## Optionally set RetroShare buildroot path -export RS_BUILD_DIR="${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/" - -## Optionally set gdb config file path -export GDB_CONFIGS_FILE="${HOME}/Builds/gdb_configs_${QT_ARCH}" - -## Generate Android NDK GDB configuration -${RS_SOURCE_DIR}/build_scripts/Android/generate_gdb_init_commands.sh --------------------------------------------------------------------------------- - - -You will need to run the following steps everytime you want to debug -`retroshare-service` on Android. - -Make sure `retroshare-service` is running on your connected Android device. - -.Run GDB server on your Android device from your host console -[source,bash] --------------------------------------------------------------------------------- -${RS_SOURCE_DIR}/build_scripts/Android/start_gdbserver.sh --------------------------------------------------------------------------------- - - -.Run Android NDK GDB on your workstation and attach -[source,bash] --------------------------------------------------------------------------------- -## Start NDK gdb -${ANDROID_NDK_PATH}/prebuilt/linux-x86_64/bin/gdb - -## Instruct GDB how and where to find debugging symbols -(gdb) source $GDB_CONFIGS_FILE - -## Connect to the gdbserver running on the phone -(gdb) target remote 127.0.01:5039 - -## Have fun debugging -(gdb) --------------------------------------------------------------------------------- - - -== Debugging with Qt Creator - -WARNING: As of the last update to this guide, debugging retroshare-service -running on Android via Qt creator doesn't wrok even with all the trickery -explained in this section, you better learn how to debug with GDB reading -carefully previous section. - -Qt Creator actually support debugging only for the foreground activity, so to -debug what's happening in the core extra trickery is needed. - -- Run the App in Debug mode from QtCreator "Start Debugging" button -- Enable QtCreator debugger console view Menu->Window->Debugger Log -- Run +show solib-search-path+ in the QtCreator GDB console -- Take note of the output you get in the right pane of the console -- Thanks https://stackoverflow.com/a/31164313 for the idea - -TIP: QtCreator GDB console seems a bit buggy and easly trigger timeout -message when a command is run, in that case attempt to run the command while the -debugging is paused or at breakpoint, or with other similar tricks. - -CAUTION: Following steps require root access on your Android device - -Now on your phone yuo need to authorize root access to applications, then once -you plug your sacrifical Android phone run this commands - -.Run gdbserver as root on Android phone -[source,bash] --------------------------------------------------------------------------------- -## Open a shell from your workstation on the connected Android phone -adb shell - -## take the note of the phone IP address -ip address show - -## Gain root permissions on the shell -su - -## Attach with gdbserver and listen on one TCP port -gdbserver :4567 --attach $(pgrep org.retroshare.android.qml_app:rs) --------------------------------------------------------------------------------- - - -.Prepare and run Android NDK GDB on your workstation -[source,bash] --------------------------------------------------------------------------------- -## Setup some convenience variables -NDK_GDB="${ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb" -RS_BUILD_PATH="${HOME}/Builds/RetroShare-Android_for_armeabi_v7a_GCC_4_9_Qt_5_9_2_android_armv7-Debug/" - -## Start Android NDK GDB of your phone architecture passing the executable -$NDK_GDB $RS_BUILD_PATH/retroshare-android-service/src/libretroshare-android-service.so - -## Instruct GDB how and where to find debugging symbols -(gdb) set auto-solib-add on -(gdb) set solib-search-path THE:BIG:LIST:OF:DIRECTORIES:YOU:TAKE:NOTE:BEFORE - -## Connect to the gdbserver running on the phone -(gdb) target remote $PHONE_IP:4567 - -## Have fun debugging -(gdb) --------------------------------------------------------------------------------- - -TIP: Some time WiFi power saving on Android mess with the GDB connection, -to prevent that from appening open another +adb shell+ and live +ping+ toward -your work-station running - -== Embedding into other Android packages - -As showed by https://elrepo.io/[elRepo.io] developers it is possible and quite -easy to embed `retroshare-service` into other Android packages see description - -https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/README.adoc - -And implementation details - -https://gitlab.com/elRepo.io/elRepo.io-android/-/blob/master/android/app/build.gradle - - -== Furter Readings - -- link:http://doc.qt.io/qt-5/android-support.html[] -- link:https://developer.android.com/ndk/guides/libs.html[] -- link:retroshare://forum?name=Compiling%20nogui%20for%20android&id=8fd22bd8f99754461e7ba1ca8a727995&msgid=4e0f92330600bba9cf978f384f4b7b2f2ca64eff[] -- link:retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136[] -- link:https://groups.google.com/forum/#!topic/android-developers/srATPaL0aRU[] -- link:https://stackoverflow.com/questions/31638986/protected-apps-setting-on-huawei-phones-and-how-to-handle-it[] -- link:https://tthtlc.wordpress.com/2012/09/19/how-to-do-remote-debugging-via-gdbserver-running-inside-the-android-phone/[] -- link:https://source.android.com/devices/tech/debug/[] -- link:https://source.android.com/devices/tech/debug/gdb[] -- link:https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html[] -- link:https://fragglet.livejournal.com/19646.html[] -- link:https://github.com/android-ndk/ndk/issues/773[How to build without using standalone toolchain?] - -== License - -Copyright (C) 2016-2020 Gioacchino Mazzurco + -Copyright (C) 2020 Asociación Civil Altermundi + - -This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. - -image::https://i.creativecommons.org/l/by-sa/4.0/88x31.png[Creative Commons License, link=http://creativecommons.org/licenses/by-sa/4.0/] diff --git a/build_scripts/Android/generate_gdb_init_commands.sh b/build_scripts/Android/generate_gdb_init_commands.sh deleted file mode 100755 index 3a9883950..000000000 --- a/build_scripts/Android/generate_gdb_init_commands.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# Script to prepare Android NDK GDB configurations to debug retroshare-service -# -# Copyright (C) 2020 Gioacchino Mazzurco -# Copyright (C) 2020 Asociación Civil Altermundi -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation, version 3. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License along -# with this program. If not, see - - -## Define default value for variable, take two arguments, $1 variable name, -## $2 default variable value, if the variable is not already define define it -## with default value. -function define_default_value() -{ - VAR_NAME="${1}" - DEFAULT_VALUE="${2}" - - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" -} - -define_default_value QT_VERSION "5.12.4" -define_default_value QT_ARCH "arm64_v8a" -define_default_value QT_DIR "/opt/Qt-${QT_VERSION}/${QT_VERSION}/" -define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" -define_default_value RS_BUILD_DIR "${HOME}/Builds/RetroShare-Android_for_${QT_ARCH}_Clang_Qt_${QT_VERSION//./_}_android_${QT_ARCH}-Debug/" -define_default_value RS_SOURCE_DIR "${HOME}/Development/rs-develop/" -define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" -define_default_value GDB_CONFIGS_FILE "${HOME}/Builds/gdb_configs_${QT_ARCH}" - -scanDir() -{ - find "$1" -type d -not -path '*/\.git/*' | tr '\n' ':' >> $GDB_CONFIGS_FILE -} - -putSeparator() -{ - echo >> $GDB_CONFIGS_FILE - echo >> $GDB_CONFIGS_FILE -} - -echo "set sysroot ${DEBUG_SYSROOT}" > $GDB_CONFIGS_FILE -putSeparator - -echo "set auto-solib-add on" >> $GDB_CONFIGS_FILE -echo -n "set solib-search-path " >> $GDB_CONFIGS_FILE -scanDir "${RS_BUILD_DIR}" -scanDir "${DEBUG_SYSROOT}" -scanDir "${QT_DIR}/android_${QT_ARCH}/lib/" -scanDir "${QT_DIR}/android_${QT_ARCH}/plugins/" -scanDir "${QT_DIR}/android_${QT_ARCH}/qml/" -putSeparator - -echo -n "directory " >> $GDB_CONFIGS_FILE -scanDir ${RS_SOURCE_DIR}/jsonapi-generator/src -scanDir ${RS_SOURCE_DIR}/libbitdht/src -scanDir ${RS_SOURCE_DIR}/openpgpsdk/src -scanDir ${RS_SOURCE_DIR}/libretroshare/src -scanDir ${RS_SOURCE_DIR}/retroshare-service/src -scanDir ${RS_SOURCE_DIR}/supportlibs/rapidjson/include/ -scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/source/ -scanDir ${RS_SOURCE_DIR}/supportlibs/udp-discovery-cpp/ -scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/asio/asio/include/ -scanDir ${RS_SOURCE_DIR}/supportlibs/restbed/dependency/catch/include/ -putSeparator - -## see https://stackoverflow.com/questions/28972367/gdb-backtrace-without-stopping -echo "catch signal SIGSEGV" >> $GDB_CONFIGS_FILE -echo "commands - bt - continue - end" >> $GDB_CONFIGS_FILE -putSeparator - -echo GDB_CONFIGS_FILE=$GDB_CONFIGS_FILE diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh deleted file mode 100755 index 2c64a5186..000000000 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ /dev/null @@ -1,549 +0,0 @@ -#!/bin/bash - -# Script to prepare RetroShare Android package building toolchain -# -# Copyright (C) 2016-2020 Gioacchino Mazzurco -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation, version 3. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License along -# with this program. If not, see -# -# SPDX-FileCopyrightText: Retroshare Team -# SPDX-License-Identifier: AGPL-3.0-only - - -## Define default value for variable, take two arguments, $1 variable name, -## $2 default variable value, if the variable is not already define define it -## with default value. -function define_default_value() -{ - VAR_NAME="${1}" - DEFAULT_VALUE="${2}" - - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" -} - -## You are supposed to provide the following variables according to your system setup -define_default_value ANDROID_NDK_PATH "/opt/android-ndk/" -define_default_value ANDROID_NDK_ARCH "arm" -define_default_value ANDROID_PLATFORM_VER "16" -define_default_value NATIVE_LIBS_TOOLCHAIN_PATH "${HOME}/Builds/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}/" -define_default_value HOST_NUM_CPU $(nproc) - -define_default_value BZIP2_SOURCE_VERSION "1.0.6" -define_default_value BZIP2_SOURCE_SHA256 a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd - -define_default_value OPENSSL_SOURCE_VERSION "1.1.1c" -define_default_value OPENSSL_SOURCE_SHA256 f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90 - -define_default_value SQLITE_SOURCE_YEAR "2018" -define_default_value SQLITE_SOURCE_VERSION "3250200" -define_default_value SQLITE_SOURCE_SHA256 da9a1484423d524d3ac793af518cdf870c8255d209e369bd6a193e9f9d0e3181 - -define_default_value SQLCIPHER_SOURCE_VERSION "4.2.0" -define_default_value SQLCIPHER_SOURCE_SHA256 105c1b813f848da038c03647a8bfc9d42fb46865e6aaf4edfd46ff3b18cdccfc - -define_default_value LIBUPNP_SOURCE_VERSION "1.8.4" -define_default_value LIBUPNP_SOURCE_SHA256 976c3e4555604cdd8391ed2f359c08c9dead3b6bf131c24ce78e64d6669af2ed - -define_default_value INSTALL_QT_ANDROID "false" -define_default_value QT_VERSION "5.12.0" -define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763 - -define_default_value RESTBED_SOURCE_VERSION f74f9329dac82e662c1d570b7cd72c192b729eb4 - -define_default_value UDP_DISCOVERY_CPP_SOURCE "https://github.com/truvorskameikin/udp-discovery-cpp.git" -define_default_value UDP_DISCOVERY_CPP_VERSION "develop" - -define_default_value XAPIAN_SOURCE_VERSION "1.4.7" -define_default_value XAPIAN_SOURCE_SHA256 13f08a0b649c7afa804fa0e85678d693fd6069dd394c9b9e7d41973d74a3b5d3 - -define_default_value RAPIDJSON_SOURCE_VERSION "1.1.0" -define_default_value RAPIDJSON_SOURCE_SHA256 bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e - -define_default_value MINIUPNPC_SOURCE_VERSION "2.1.20190625" -define_default_value MINIUPNPC_SOURCE_SHA256 8723f5d7fd7970de23635547700878cd29a5c2bb708b5e5475b2d1d2510317fb - - -## $1 filename, $2 sha256 hash -function check_sha256() -{ - echo ${2} "${1}" | sha256sum -c &> /dev/null -} - -## $1 filename, $2 sha256 hash, $3 url -function verified_download() -{ - FILENAME="$1" - SHA256="$2" - URL="$3" - - check_sha256 "${FILENAME}" "${SHA256}" || - { - rm -rf "${FILENAME}" - - wget -O "${FILENAME}" "$URL" || - { - echo "Failed downloading ${FILENAME} from $URL" - exit 1 - } - - check_sha256 "${FILENAME}" "${SHA256}" || - { - echo "SHA256 mismatch for ${FILENAME} from ${URL} expected sha256 ${SHA256} got $(sha256sum ${FILENAME} | awk '{print $1}')" - exit 1 - } - } -} - -cArch="" -eABI="" - -case "${ANDROID_NDK_ARCH}" in -"arm") - cArch="${ANDROID_NDK_ARCH}" - eABI="eabi" - ;; -"arm64") - cArch="aarch64" - eABI="" - ;; -"x86") - cArch="i686" - eABI="" - ;; -esac - -export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/" -export PREFIX="${SYSROOT}/usr/" -export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang" -export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++" -export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar" -export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib" - - -## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html -build_toolchain() -{ - echo "build_toolchain() -################################################################################ -################################################################################ -################################################################################ -" - - rm -rf ${NATIVE_LIBS_TOOLCHAIN_PATH} - ${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \ - --arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \ - --api ${ANDROID_PLATFORM_VER} - find "${PREFIX}/include/" -not -type d > "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" -} - -## This avoid include errors due to -isystem and -I ordering issue -delete_copied_includes() -{ - echo "delete_copied_includes() -################################################################################ -################################################################################ -################################################################################ -" - cat "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" | while read delFile ; do - rm "$delFile" - done -} - -## More information available at https://gitlab.com/relan/provisioners/merge_requests/1 and http://stackoverflow.com/a/34032216 -install_qt_android() -{ - echo "install_qt_android() -################################################################################ -################################################################################ -################################################################################ -" - - QT_VERSION_CODE=$(echo $QT_VERSION | tr -d .) - QT_INSTALL_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt - QT_INSTALLER="qt-unified-linux-x64-3.0.2-online.run" - - verified_download $QT_INSTALLER $QT_ANDROID_INSTALLER_SHA256 \ - http://master.qt.io/archive/online_installers/3.0/${QT_INSTALLER} - - chmod a+x ${QT_INSTALLER} - - QT_INSTALLER_SCRIPT="qt_installer_script.js" - cat << EOF > "${QT_INSTALLER_SCRIPT}" -function Controller() { - installer.autoRejectMessageBoxes(); - installer.installationFinished.connect(function() { - gui.clickButton(buttons.NextButton); - }); - - var welcomePage = gui.pageWidgetByObjectName("WelcomePage"); - welcomePage.completeChanged.connect(function() { - if (gui.currentPageWidget().objectName == welcomePage.objectName) - gui.clickButton(buttons.NextButton); - }); -} - -Controller.prototype.WelcomePageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.CredentialsPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.IntroductionPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.TargetDirectoryPageCallback = function() { - gui.currentPageWidget().TargetDirectoryLineEdit.setText("$QT_INSTALL_PATH"); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ComponentSelectionPageCallback = function() { - var widget = gui.currentPageWidget(); - - // You can get these component names by running the installer with the - // --verbose flag. It will then print out a resource tree. - - widget.deselectComponent("qt.tools.qtcreator"); - widget.deselectComponent("qt.tools.doc"); - widget.deselectComponent("qt.tools.examples"); - - widget.selectComponent("qt.$QT_VERSION_CODE.android_armv7"); - - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.LicenseAgreementPageCallback = function() { - gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.StartMenuDirectoryPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.ReadyForInstallationPageCallback = function() { - gui.clickButton(buttons.NextButton); -} - -Controller.prototype.FinishedPageCallback = function() { - var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; - if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) - checkBoxForm.launchQtCreatorCheckBox.checked = false; - gui.clickButton(buttons.FinishButton); -} -EOF - -QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} --script ${QT_INSTALLER_SCRIPT} -} - -## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136 -build_bzlib() -{ - echo "build_bzlib() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="bzip2-${BZIP2_SOURCE_VERSION}" - rm -rf $B_dir - - verified_download $B_dir.tar.gz $BZIP2_SOURCE_SHA256 \ - http://distfiles.gentoo.org/distfiles/bzip2-${BZIP2_SOURCE_VERSION}.tar.gz - - tar -xf $B_dir.tar.gz - cd $B_dir - sed -i "/^CC=.*/d" Makefile - sed -i "/^AR=.*/d" Makefile - sed -i "/^RANLIB=.*/d" Makefile - sed -i "/^LDFLAGS=.*/d" Makefile - sed -i "s/^all: libbz2.a bzip2 bzip2recover test/all: libbz2.a bzip2 bzip2recover/" Makefile - make -j${HOST_NUM_CPU} - make install PREFIX=${PREFIX} -# sed -i "/^CC=.*/d" Makefile-libbz2_so -# make -f Makefile-libbz2_so -j${HOST_NUM_CPU} -# cp libbz2.so.1.0.6 ${SYSROOT}/usr/lib/libbz2.so - cd .. -} - -## More information available at http://doc.qt.io/qt-5/opensslsupport.html -build_openssl() -{ - echo "build_openssl() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="openssl-${OPENSSL_SOURCE_VERSION}" - rm -rf $B_dir - - verified_download $B_dir.tar.gz $OPENSSL_SOURCE_SHA256 \ - https://www.openssl.org/source/$B_dir.tar.gz - - tar -xf $B_dir.tar.gz - cd $B_dir -## We link openssl statically to avoid android silently sneaking in his own -## version of libssl.so (we noticed this because it had some missing symbol -## that made RS crash), the crash in some android version is only one of the -## possible problems the fact that android insert his own binary libssl.so pose -## non neglegible security concerns. - oBits="32" - [[ ${ANDROID_NDK_ARCH} =~ .*64.* ]] && oBits=64 - - ANDROID_NDK="${ANDROID_NDK_PATH}" PATH="${SYSROOT}/bin/:${PATH}" \ - ./Configure linux-generic${oBits} -fPIC --prefix="${PREFIX}" \ - --openssldir="${SYSROOT}/etc/ssl" -# sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile -# sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile - make -j${HOST_NUM_CPU} - make install - rm -f ${PREFIX}/lib/libssl.so* - rm -f ${PREFIX}/lib/libcrypto.so* - cd .. -} - -build_sqlite() -{ - echo "build_sqlite() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="sqlite-autoconf-${SQLITE_SOURCE_VERSION}" - rm -rf $B_dir - - verified_download $B_dir.tar.gz $SQLITE_SOURCE_SHA256 \ - https://www.sqlite.org/${SQLITE_SOURCE_YEAR}/$B_dir.tar.gz - - tar -xf $B_dir.tar.gz - cd $B_dir - ./configure --with-pic --prefix="${PREFIX}" --host=${cArch}-linux - make -j${HOST_NUM_CPU} - make install - rm -f ${PREFIX}/lib/libsqlite3.so* -# ${CC} -shared -o libsqlite3.so -fPIC sqlite3.o -ldl -# cp libsqlite3.so "${SYSROOT}/usr/lib" - cd .. -} - -build_sqlcipher() -{ - echo "build_sqlcipher() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="sqlcipher-${SQLCIPHER_SOURCE_VERSION}" - rm -rf $B_dir - - T_file="${B_dir}.tar.gz" - - verified_download $T_file $SQLCIPHER_SOURCE_SHA256 \ - https://github.com/sqlcipher/sqlcipher/archive/v${SQLCIPHER_SOURCE_VERSION}.tar.gz - - tar -xf $T_file - cd $B_dir - case "${ANDROID_NDK_ARCH}" in - "arm64") - # SQLCipher config.sub is outdated and doesn't recognize newer architectures - rm config.sub - autoreconf --verbose --install --force - automake --add-missing --copy --force-missing - ;; - esac - ./configure --with-pic --build=$(sh ./config.guess) \ - --host=${cArch}-linux \ - --prefix="${PREFIX}" --with-sysroot="${SYSROOT}" \ - --enable-tempstore=yes \ - --disable-tcl --disable-shared \ - CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="${PREFIX}/lib/libcrypto.a" - make -j${HOST_NUM_CPU} - make install - cd .. -} - -build_libupnp() -{ - echo "build_libupnp() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="pupnp-release-${LIBUPNP_SOURCE_VERSION}" - B_ext=".tar.gz" - B_file="${B_dir}${B_ext}" - rm -rf $B_dir - - verified_download $B_file $LIBUPNP_SOURCE_SHA256 \ - https://github.com/mrjimenez/pupnp/archive/release-${LIBUPNP_SOURCE_VERSION}${B_ext} - - tar -xf $B_file - cd $B_dir - ./bootstrap -## liupnp must be configured as static library because if not the linker will -## look for libthreadutils.so.6 at runtime that cannot be packaged on android -## as it supports only libname.so format for libraries, thus resulting in a -## crash at startup. - ./configure --with-pic --enable-static --disable-shared --disable-samples \ - --disable-largefile \ - --prefix="${PREFIX}" --host=${cArch}-linux - make -j${HOST_NUM_CPU} - make install - cd .. -} - -build_rapidjson() -{ - echo "build_rapidjson() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="rapidjson-${RAPIDJSON_SOURCE_VERSION}" - D_file="${B_dir}.tar.gz" - verified_download $D_file $RAPIDJSON_SOURCE_SHA256 \ - https://github.com/Tencent/rapidjson/archive/v${RAPIDJSON_SOURCE_VERSION}.tar.gz - tar -xf $D_file - cp -r "${B_dir}/include/rapidjson/" "${PREFIX}/include/rapidjson" -} - -build_restbed() -{ - echo "build_restbed() -################################################################################ -################################################################################ -################################################################################ -" - - [ -d restbed ] || git clone --depth=2000 https://github.com/Corvusoft/restbed.git - cd restbed -# git fetch --tags -# git checkout tags/${RESTBED_SOURCE_VERSION} - git checkout ${RESTBED_SOURCE_VERSION} - git submodule update --init dependency/asio - git submodule update --init dependency/catch - git submodule update --init dependency/kashmir - cd .. - - rm -rf restbed-build; mkdir restbed-build ; cd restbed-build - cmake \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON BUILD_TESTS=OFF \ - -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../restbed - make -j${HOST_NUM_CPU} - make install - cp "${PREFIX}/library/librestbed.a" "${PREFIX}/lib/" - cd .. -} - -build_udp-discovery-cpp() -{ - echo "build_udp-discovery-cpp() -################################################################################ -################################################################################ -################################################################################ -" - - S_dir="udp-discovery-cpp" - [ -d $S_dir ] || git clone $UDP_DISCOVERY_CPP_SOURCE $S_dir - cd $S_dir - git checkout $UDP_DISCOVERY_CPP_VERSION - cd .. - - B_dir="udp-discovery-cpp-build" - rm -rf ${B_dir}; mkdir ${B_dir}; cd ${B_dir} - cmake \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../udp-discovery-cpp - make -j${HOST_NUM_CPU} - cp libudp-discovery.a "${PREFIX}/lib/" - cp ../$S_dir/*.hpp "${PREFIX}/include/" - cd .. -} - -build_xapian() -{ - echo "build_xapian() -################################################################################ -################################################################################ -################################################################################ -" - - B_dir="xapian-core-${XAPIAN_SOURCE_VERSION}" - D_file="$B_dir.tar.xz" - verified_download $D_file $XAPIAN_SOURCE_SHA256 \ - https://oligarchy.co.uk/xapian/${XAPIAN_SOURCE_VERSION}/$D_file - rm -rf $B_dir - tar -xf $D_file - cd $B_dir - B_endiannes_detection_failure_workaround="ac_cv_c_bigendian=no" - B_large_file="" - [ "${ANDROID_PLATFORM_VER}" -lt "24" ] && B_large_file="--disable-largefile" - ./configure ${B_endiannes_detection_failure_workaround} ${B_large_file} \ - --with-pic \ - --disable-backend-inmemory --disable-backend-remote \ - --disable--backend-chert --enable-backend-glass \ - --host=${cArch}-linux --enable-static --disable-shared \ - --prefix="${PREFIX}" --with-sysroot="${SYSROOT}" - make -j${HOST_NUM_CPU} - make install -} - -build_miniupnpc() -{ - echo "build_miniupnpc() -################################################################################ -################################################################################ -################################################################################ -" - S_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}" - B_dir="miniupnpc-${MINIUPNPC_SOURCE_VERSION}-build" - D_file="$S_dir.tar.gz" - verified_download $D_file $MINIUPNPC_SOURCE_SHA256 \ - http://miniupnp.free.fr/files/${D_file} - rm -rf $S_dir $B_dir - tar -xf $D_file - mkdir $B_dir - cd $B_dir - cmake \ - -DUPNPC_BUILD_STATIC=TRUE \ - -DUPNPC_BUILD_SHARED=FALSE \ - -DUPNPC_BUILD_TESTS=FALSE \ - -DUPNPC_BUILD_SAMPLE=FALSE \ - -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -S../$S_dir - make -j${HOST_NUM_CPU} - make install -} - -build_toolchain -[ "${INSTALL_QT_ANDROID}X" != "trueX" ] || install_qt_android -build_bzlib -build_openssl -build_sqlite -build_sqlcipher -build_libupnp -build_rapidjson -build_restbed -build_udp-discovery-cpp -build_xapian -build_miniupnpc -delete_copied_includes - -echo NATIVE_LIBS_TOOLCHAIN_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH} diff --git a/build_scripts/Android/pull_sysroot.sh b/build_scripts/Android/pull_sysroot.sh deleted file mode 100755 index d474610e4..000000000 --- a/build_scripts/Android/pull_sysroot.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -# Script to pull debugging sysroot from Android devices -# -# Copyright (C) 2020 Gioacchino Mazzurco -# Copyright (C) 2020 Asociación Civil Altermundi -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation, version 3. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License along -# with this program. If not, see - -<<"ASCIIDOC" - -Pull files from Android device to prepare a debugging sysroot -Inspired by: -https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html - -The goal is to have a local copy of the sysroot of the connected device. -For that we use the command `adb pull ` - -We will get a copy of: - -- `/system/lib/` -- `/vendor/lib/` -- `libc.so` -- `libcutils.so` - -As well as the binaries `linker` and `app_process` - -IMPORTANT: -from one device to another, the remote file `app_process` can be a binary file -or a symlink to a binary file - which is NOT ok for us. -That's so we will try to pull every known possible variants of `app_process`, -e.g. `app_process32` or `app_process_init` - -ASCIIDOC - - -## Define default value for variable, take two arguments, $1 variable name, -## $2 default variable value, if the variable is not already define define it -## with default value. -function define_default_value() -{ - VAR_NAME="${1}" - DEFAULT_VALUE="${2}" - - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" -} - -define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" -define_default_value DEBUG_SYSROOT "${HOME}/Builds/debug_sysroot/${ANDROID_SERIAL}/" - -rm -rf "${DEBUG_SYSROOT}" - -for mDir in "/system/lib/" "/vendor/lib/"; do - mkdir -p "${DEBUG_SYSROOT}/${mDir}" - # adb pull doesn't behave like rsync dirA/ dirB/ so avoid nesting the - # directory by deleting last one before copying - rmdir "${DEBUG_SYSROOT}/${mDir}" - adb pull "${mDir}" "${DEBUG_SYSROOT}/${mDir}" -done - -# Retrieve the specific binaries - some of these adb commands will fail, since -# some files may not exist, but that's ok. - -mkdir -p "${DEBUG_SYSROOT}/system/bin/" -for mBin in "/system/bin/linker" "/system/bin/app_process" \ - "/system/bin/app_process_init" "/system/bin/app_process32" \ - "/system/bin/app_process64" ; do - adb pull "${mBin}" "${DEBUG_SYSROOT}/${mBin}" -done - -# Verify which variants of the specific binaries could be pulled -echo -echo "Found the following specific binaries:" -echo -ls -1 "${DEBUG_SYSROOT}/system/bin/"* -ls -1 "${DEBUG_SYSROOT}/system/lib/libc.so"* -ls -1 "${DEBUG_SYSROOT}/system/lib/libcutils.so"* -echo - -echo DEBUG_SYSROOT="${DEBUG_SYSROOT}" diff --git a/build_scripts/Android/start_gdbserver.sh b/build_scripts/Android/start_gdbserver.sh deleted file mode 100755 index af25e3be1..000000000 --- a/build_scripts/Android/start_gdbserver.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash - -# Script to start gdbserver on Android device and attach to retroshare-service -# -# Copyright (C) 2020 Gioacchino Mazzurco -# Copyright (C) 2020 Asociación Civil Altermundi -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation, version 3. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License along -# with this program. If not, see - -<<"ASCIIDOC" - -Start gdbserver on Android device and attach it to the retroshare service -process - -Inspired by: -https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html - -ASCIIDOC - - -## Define default value for variable, take two arguments, $1 variable name, -## $2 default variable value, if the variable is not already define define it -## with default value. -function define_default_value() -{ - VAR_NAME="${1}" - DEFAULT_VALUE="${2}" - - [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" -} - -define_default_value ANDROID_APK_PACKAGE "org.retroshare.service" -define_default_value ANDROID_PROCESS_NAME "org.retroshare.service:rs" -define_default_value ANDROID_INSTALL_PATH "" -define_default_value LIB_GDB_SERVER_PATH "" -define_default_value ANDROID_SERIAL "$(adb devices | head -n 2 | tail -n 1 | awk '{print $1}')" -define_default_value GDB_SERVER_PORT 5039 - -adb_ushell() -{ - adb shell run-as ${ANDROID_APK_PACKAGE} $@ -} - -[ -z "${ANDROID_INSTALL_PATH}" ] && -{ - ANDROID_INSTALL_PATH="$(adb_ushell pm path "${ANDROID_APK_PACKAGE}")" - ANDROID_INSTALL_PATH="$(dirname ${ANDROID_INSTALL_PATH#"package:"})" - [ -z "${ANDROID_INSTALL_PATH}" ] && - cat < New -> Import Project -> Git Clone -> Choose +Add Repository and Continoue + + Repository: https://github.com/RetroShare/RetroShare.git + +via Terminal: + + cd + git clone https://github.com/RetroShare/RetroShare.git retroshare + +via GitHub Desktop: [GitHub Desktop Download](https://central.github.com/deployments/desktop/desktop/latest/darwin) + +In GitHub Desktop -> Clone Repository -> URL + + Add Repository URL: https://github.com/RetroShare/RetroShare.git and Clone + ## ***Choose if you use MacPort or HomeBrew*** ### MacPort Installation @@ -22,15 +40,16 @@ Start XCode to get it updated and to able C compiler to create executables. #### Install libraries - $sudo port -v selfupdate - $sudo port install openssl - $sudo port install miniupnpc - $sudo port install libmicrohttpd + $ sudo port -v selfupdate + $ sudo port install openssl + $ sudo port install miniupnpc + $ sudo port install libmicrohttpd For VOIP Plugin: - $sudo port install speex-devel - $sudo port install opencv + $ sudo port install speex-devel + $ sudo port install opencv + $ sudo port install ffmpeg Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) @@ -46,9 +65,11 @@ Start XCode to get it updated and to able C compiler to create executables. #### Install libraries - $brew install openssl - $brew install miniupnpc - $brew install libmicrohttpd + $ brew install openssl + $ brew install miniupnpc + $ brew install libmicrohttpd + $ brew install rapidjson + $ brew install sqlcipher If you have error in linking, run this: @@ -56,37 +77,99 @@ If you have error in linking, run this: For VOIP Plugin: - $brew install speex - $brew install speexdsp - $brew install homebrew/science/opencv - $brew install ffmpeg + $ brew install speex + $ brew install speexdsp + $ brew install opencv + $ brew install ffmpeg + +For FeedReader Plugin: + + $ brew install libxslt Get Your OSX SDK if missing: [MacOSX-SDKs](https://github.com/phracker/MacOSX-SDKs) ## Last Settings -In QtCreator Option Git select "Pull" with "Rebase" +In QtCreator Projects -> Manage Kits > Version Control > Git: -## Compil missing libraries -### SQLCipher - - cd - git clone https://github.com/sqlcipher/sqlcipher.git - cd sqlcipher - ./configure --disable-shared --disable-tcl --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I/opt/local/include" LDFLAGS="-lcrypto" - make - sudo make install + select "Pull with rebase" -NOTE, might be necessary to *chmod 000 /usr/local/ssl* temporarily during *./configure* if -homebrew uses newer, non-stock ssl dependencies found there. Configure might get confused. +In QtCreator Projects -> Build -> Build Settings -> Build Environment -> Add this path: -You can now compile RS into Qt Creator or with terminal + /usr/local/bin + +In QtCreator Projects -> Build -> Build Settings -> Build Steps -> Add Additional arguments: + + "CONFIG+=rs_autologin" "CONFIG+=rs_use_native_dialogs" + +## Set your Mac OS SDK version + +Edit RetroShare.pro + + CONFIG += c++14 rs_macos11.1 + +and then retroshare.pri + + macx:CONFIG *= rs_macos11.1 + rs_macos10.8:CONFIG -= rs_macos11.1 + rs_macos10.9:CONFIG -= rs_macos11.1 + rs_macos10.10:CONFIG -= rs_macos11.1 + rs_macos10.12:CONFIG -= rs_macos11.1 + rs_macos10.13:CONFIG -= rs_macos11.1 + rs_macos10.14:CONFIG -= rs_macos11.1 + rs_macos10.15:CONFIG -= rs_macos11.1 + + +## Link Include & Libraries + +Edit your retroshare.pri and add to macx-* section + + INCLUDEPATH += "/usr/local/opt/openssl/include" + QMAKE_LIBDIR += "/usr/local/opt/openssl/lib" + QMAKE_LIBDIR += "/usr/local/opt/sqlcipher/lib" + QMAKE_LIBDIR += "/usr/local/opt/miniupnpc/lib" + +alternative via Terminal + + $ qmake INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" + +For FeedReader Plugin: + + INCLUDEPATH += "/usr/local/opt/libxml2/include/libxml2" + +For building RetroShare with plugins: + + $ qmake \ + INCLUDEPATH+="/usr/local/opt/openssl/include" QMAKE_LIBDIR+="/usr/local/opt/openssl/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/sqlcipher/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/miniupnpc/lib" \ + INCLUDEPATH+="/usr/local/opt/opencv/include/opencv4" QMAKE_LIBDIR+="/usr/local/opt/opencv/lib" \ + INCLUDEPATH+="/usr/local/opt/speex/include" QMAKE_LIBDIR+="/usr/local/opt/speex/lib/" \ + INCLUDEPATH+="/usr/local/opt/speexdsp/include" QMAKE_LIBDIR+="/usr/local/opt/speexdsp/lib/" \ + INCLUDEPATH+="/usr/local/opt/libxslt/include" QMAKE_LIBDIR+="/usr/local/opt/libxslt/lib" \ + QMAKE_LIBDIR+="/usr/local/opt/ffmpeg/lib" \ + LIBS+=-lopencv_videoio \ + CONFIG+=retroshare_plugins \ + CONFIG+=rs_autologin \ + CONFIG+=rs_use_native_dialogs \ + CONFIG+=release \ + .. + +## Compile RetroShare + +You can now compile RetroShare into Qt Creator or with Terminal - cd - git clone https://github.com/RetroShare/RetroShare.git retroshare cd retroshare qmake; make You can change Target and SDK in *./retroshare.pri:82* changing value of QMAKE_MACOSX_DEPLOYMENT_TARGET and QMAKE_MAC_SDK -You can find compiled application on *./retroshare/retroshare-gui/src/retroshare.app* +You can find the compiled application at *./retroshare/retroshare-gui/src/retroshare.app* + +## Copy Plugins + + $ cp \ + ./plugins/FeedReader/lib/libFeedReader.dylib \ + ./plugins/VOIP/lib/libVOIP.dylib \ + ./plugins/RetroChess/lib/libRetroChess.dylib \ + ./retroshare-gui/src/RetroShare.app/Contents/Resources/ diff --git a/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt b/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt deleted file mode 100644 index 684c45f3e..000000000 --- a/build_scripts/OSX/OSX_RS_Compilation_Instructions.txt +++ /dev/null @@ -1,66 +0,0 @@ - -Mac OSX Build Instructions. -------------------------------------------- - -There are several complications with building Retroshare under OSX. - 1) Support Libraries must be built and installed seperately. - 2) Universal and OSX 10.5 support is a little tricky, mainly due to the support libraries. - -Additional Libraries ---------------------- - - * GnuPG Package, that comes with Retroshare OSX install image. (GnuPG-1.4.9.dmg) - -GPG Development libraries - * libassuan (I'm using 2.0.1) - * libgpg-error (I'm using 1.9) - * libgpgme (I'm using 1.3.0) - -These libraries use standard UNIX installation systems: AUTOCONF/AUTOMAKE (configure, make, etc) -Unfortunately, this makes it difficult and a little manual to compile Universal and 10.5 libraries. - -UPNPC (for OSX and windows) - * miniupnpc (I'm using 1.0) - -You will also need to install - * XCode (available on the Apple Install CDs) - * Qt4 (from trolltech.com) - -First Compilation... --------------------- - -The First challenge is to build Retroshare on your Mac. For this first compilation, -we only build for your specific machine, and not attempt a Generic / 10.5 / Univeral build. - - -1) Install / Compile all the packages listed above. - be sure to use a configure command like this where applicable to only create a static library. - ./configure --enable-static=yes --enable-shared=no CFLAGS="-arch i386" CPPFLAGS="-arch i386" - -2) Check out the Retroshare SVN. - -3) compile libbitdht: - cd libbitdht/src - qmake - - This recreates a xcodeproj file for compilation using XCode. - Open with Xcode, and build. - -4) compile libretroshare: same way. -5) compile retroshare-gui: same way. - - -Creating Retroshare OSX Distribution Packages. ------------------------------------------------ - TODO, once I've got feedback on First Compilation! - - - - - - - - - - - diff --git a/build_scripts/OSX/retroshare-mac-build.patch b/build_scripts/OSX/retroshare-mac-build.patch deleted file mode 100644 index 7023ad7c2..000000000 --- a/build_scripts/OSX/retroshare-mac-build.patch +++ /dev/null @@ -1,94 +0,0 @@ -commit 51f554f909086f4baca7be215d5edacab744dea4 -Author: Kartikaya Gupta -Date: Wed Mar 7 23:30:48 2012 -0500 - - Modifications needed to get build working on Mac OS X 10.6 - -diff --git a/.gitignore b/.gitignore -new file mode 100644 -index 0000000..3e90033 ---- /dev/null -+++ b/.gitignore -@@ -0,0 +1,6 @@ -+*.o -+Makefile -+libbitdht/src/lib/ -+libretroshare/src/lib/ -+retroshare-gui/src/RetroShare.app/ -+retroshare-gui/src/temp/ -diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro -index 6f35e01..267cc91 100644 ---- a/libretroshare/src/libretroshare.pro -+++ b/libretroshare/src/libretroshare.pro -@@ -312,7 +312,7 @@ mac { - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW -- #DEFINES *= MINIUPNPC_VERSION=13 -+ DEFINES *= MINIUPNPC_VERSION=13 - DESTDIR = lib - - #miniupnp implementation files -@@ -326,12 +326,11 @@ mac { - # 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 -+ UPNPC_DIR = ../../../miniupnpc-1.3 -+ GPG_ERROR_DIR = ../../../libgpg-error-1.10 -+ GPGME_DIR = ../../../gpgme-1.3.1 - -- INCLUDEPATH += . $${UPNPC_DIR} -- #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src -+ INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src - } - - ################################# FreeBSD ########################################## -diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc -index 2588cb8..305433f 100644 ---- a/libretroshare/src/pqi/sslfns.cc -+++ b/libretroshare/src/pqi/sslfns.cc -@@ -586,8 +586,8 @@ X509 *loadX509FromDER(const uint8_t *ptr, uint32_t len) - X509 *tmp = NULL; - #ifdef __APPLE__ - // This depends on which version you are compiling for... OSX10.5 doesn't have consts (old OpenSSL!) -- unsigned char **certptr = (unsigned char **) &ptr; -- //const unsigned char **certptr = (const unsigned char **) &ptr; -+ //unsigned char **certptr = (unsigned char **) &ptr; -+ const unsigned char **certptr = (const unsigned char **) &ptr; - #else - const unsigned char **certptr = (const unsigned char **) &ptr; - #endif -diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro -index adcb5a0..ffbf669 100644 ---- a/retroshare-gui/src/RetroShare.pro -+++ b/retroshare-gui/src/RetroShare.pro -@@ -140,19 +140,21 @@ 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.6 - - CONFIG += version_detail_bash_script - LIBS += ../../libretroshare/src/lib/libretroshare.a -- LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan -- LIBS += ../../../miniupnpc-1.0/libminiupnpc.a -+ LIBS += ../../../libgpg-error-1.10/build/lib/libgpg-error.a -+ LIBS += ../../../gpgme-1.3.1/build/lib/libgpgme.a -+ LIBS += ../../../miniupnpc-1.3/libminiupnpc.a -+ LIBS += -lssl -lcrypto -lz -lassuan - LIBS += -framework CoreFoundation - LIBS += -framework Security - - # LIBS += -framework CoreServices - -- INCLUDEPATH += . -+ INCLUDEPATH += . ../../../gpgme-1.3.1/src - #DEFINES* = MAC_IDLE # for idle feature - CONFIG -= uitools - diff --git a/build_scripts/Windows-msys2/build/build.bat b/build_scripts/Windows-msys2/build/build.bat index 4d366f28c..4fdaff09f 100644 --- a/build_scripts/Windows-msys2/build/build.bat +++ b/build_scripts/Windows-msys2/build/build.bat @@ -32,6 +32,16 @@ if not "%ParamNoupdate%"=="1" ( if "%ParamIndexing%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-xapian-core mingw-w64-%RsMSYS2Architecture%-libvorbis mingw-w64-%RsMSYS2Architecture%-flac mingw-w64-%RsMSYS2Architecture%-taglib" ) +:: Fix webui compilation (TODO: remove when whole RS switched to cmake) +if "%ParamWebui%"=="1" ( + pushd "%SourcePath%" + copy "%SourcePath%\libretroshare\src\jsonapi\jsonapi-generator-doxygen.conf" "%SourcePath%\jsonapi-generator\src\jsonapi-generator-doxygen.conf" %Quite% + copy "%SourcePath%\libretroshare\src\jsonapi\async-method-wrapper-template.cpp.tmpl" "%SourcePath%\jsonapi-generator\src\async-method-wrapper-template.cpp.tmpl" %Quite% + copy "%SourcePath%\libretroshare\src\jsonapi\method-wrapper-template.cpp.tmpl" "%SourcePath%\jsonapi-generator\src\method-wrapper-template.cpp.tmpl" %Quite% + git update-index --assume-unchanged "jsonapi-generator\src\jsonapi-generator-doxygen.conf" "jsonapi-generator\src\async-method-wrapper-template.cpp.tmpl" "jsonapi-generator\src\method-wrapper-template.cpp.tmpl" + popd +) + :: Initialize environment call "%~dp0env.bat" %* if errorlevel 2 exit /B 2 @@ -66,6 +76,7 @@ echo %RS_QMAKE_CONFIG% > buildinfo.txt echo %RsBuildConfig% >> buildinfo.txt echo %RsArchitecture% >> buildinfo.txt echo Qt %QtVersion% >> buildinfo.txt +echo %RsToolchain% >> buildinfo.txt echo %RsCompiler% >> buildinfo.txt call "%ToolsPath%\msys2-path.bat" "%SourcePath%" MSYS2SourcePath @@ -86,11 +97,6 @@ title Build - %SourceName%-%RsBuildConfig% [make] %EnvMSYS2Cmd% "make -j %CoreCount%" if errorlevel 1 goto error -:: Webui -if "%ParamWebui%"=="1" ( - call "%~dp0..\tools\webui.bat" -) - :error popd diff --git a/build_scripts/Windows-msys2/build/env-base.bat b/build_scripts/Windows-msys2/build/env-base.bat index 9d9fa5379..01a7a8f12 100644 --- a/build_scripts/Windows-msys2/build/env-base.bat +++ b/build_scripts/Windows-msys2/build/env-base.bat @@ -1,6 +1,4 @@ :: Process commandline parameter -set Param32=0 -set Param64=0 set ParamRelease=0 set ParamDebug=0 set ParamAutologin=0 @@ -9,17 +7,40 @@ set ParamTor=0 set ParamWebui=0 set ParamClang=0 set ParamIndexing=0 +set ParamFriendserver=0 set ParamNoupdate=0 set CoreCount=%NUMBER_OF_PROCESSORS% set RS_QMAKE_CONFIG= +set RsToolchain= +set tcc=0 :parameter_loop if "%~1" NEQ "" ( for /f "tokens=1,2 delims==" %%a in ("%~1") do ( if "%%~a"=="32" ( - set Param32=1 + set RsToolchain=mingw32 + set /A tcc=tcc+1 ) else if "%%~a"=="64" ( - set Param64=1 + set RsToolchain=mingw64 + set /A tcc=tcc+1 + ) else if "%%~a"=="mingw32" ( + set RsToolchain=mingw32 + set /A tcc=tcc+1 + ) else if "%%~a"=="mingw64" ( + set RsToolchain=mingw64 + set /A tcc=tcc+1 + ) else if "%%~a"=="ucrt64" ( + set RsToolchain=ucrt64 + set /A tcc=tcc+1 + ) else if "%%~a"=="clang64" ( + set RsToolchain=clang64 + set /A tcc=tcc+1 + ) else if "%%~a"=="clang32" ( + set RsToolchain=clang32 + set /A tcc=tcc+1 + ) else if "%%~a"=="clangarm64" ( + set RsToolchain=clangarm64 + set /A tcc=tcc+1 ) else if "%%~a"=="release" ( set ParamRelease=1 ) else if "%%~a"=="debug" ( @@ -38,6 +59,8 @@ if "%~1" NEQ "" ( set ParamClang=1 ) else if "%%~a"=="indexing" ( set ParamIndexing=1 + ) else if "%%~a"=="friendserver" ( + set ParamFriendserver=1 ) else if "%%~a"=="noupdate" ( set ParamNoupdate=1 ) else if "%%~a"=="CONFIG+" ( @@ -52,22 +75,37 @@ if "%~1" NEQ "" ( goto parameter_loop ) -if "%Param32%"=="1" ( - if "%Param64%"=="1" ( - echo. - echo 32-bit or 64-bit? - goto :usage - ) - - set RsBit=32 - set RsArchitecture=x86 - set RsMSYS2Architecture=i686 +if %tcc% NEQ 1 ( + echo Multiple or no toolchain specified + goto :usage ) -if "%Param64%"=="1" ( - set RsBit=64 +if "%RsToolchain%"=="mingw32" ( + set RsArchitecture=x86 + set RsMSYS2Architecture=i686 + set MSYSTEM=MINGW32 +) else if "%RsToolchain%"=="mingw64" ( set RsArchitecture=x64 set RsMSYS2Architecture=x86_64 + set MSYSTEM=MINGW64 +) else if "%RsToolchain%"=="ucrt64" ( + set RsArchitecture=x64 + set RsMSYS2Architecture=ucrt-x86_64 + set MSYSTEM=UCRT64 +) else if "%RsToolchain%"=="clang64" ( + set RsArchitecture=x64 + set RsMSYS2Architecture=clang-x86_64 + set MSYSTEM=CLANG64 + set ParamClang=1 +) else if "%RsToolchain%"=="clang32" ( + set RsArchitecture=x86 + set RsMSYS2Architecture=clang-i686 + set MSYSTEM=CLANG32 + set ParamClang=1 +) else if "%RsToolchain%"=="clangarm64" ( + set RsArchitecture=arm64 + set RsMSYS2Architecture=clang-aarch64 + set MSYSTEM=CLANGARM64 ) if "%ParamClang%"=="1" ( @@ -76,8 +114,6 @@ if "%ParamClang%"=="1" ( set RsCompiler=GCC ) -if "%RsBit%"=="" goto :usage - if "%ParamRelease%"=="1" ( if "%ParamDebug%"=="1" ( echo. @@ -104,14 +140,21 @@ if "%ParamIndexing%"=="1" ( set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=rs_deep_channels_index" "CONFIG+=rs_deep_files_index" "CONFIG+=rs_deep_files_index_ogg" "CONFIG+=rs_deep_files_index_flac" "CONFIG+=rs_deep_files_index_taglib" ) +if "%ParamFriendserver%"=="1" ( + set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=rs_efs" +) + exit /B 0 :usage echo. -echo Usage: 32^|64 release^|debug [autologin plugins webui singlethread clang indexing noupdate] ["CONFIG+=..."] +echo Usage: 32^|64^|other release^|debug [autologin plugins webui singlethread clang indexing friendserver noupdate] ["CONFIG+=..."] echo. echo Mandatory parameter -echo 32^|64 32-bit or 64-bit Version +echo 32^|64 32-bit or 64-bit version (same as mingw32 or mingw64) +echo Or you can specify any other toolchain supported by msys2: +echo mingw32^|mingw64^|clang32^|clang64^|ucrt64^|clangarm64 +echo More info: https://www.msys2.org/docs/environments echo release^|debug Build release or debug version echo. echo Optional parameter (need clean when changed) @@ -121,6 +164,7 @@ echo webui Enable JsonAPI and pack webui files echo singlethread Use only 1 thread for building echo clang Use clang compiler instead of GCC echo indexing Build with deep channel and file indexing support +echo friendserver Enable friendserver support echo noupdate Skip updating the libraries echo "CONFIG+=..." Enable some extra features, you can find the almost complete list in retroshare.pri echo. diff --git a/build_scripts/Windows-msys2/build/env.bat b/build_scripts/Windows-msys2/build/env.bat index bfe2afeba..ccba33db3 100644 --- a/build_scripts/Windows-msys2/build/env.bat +++ b/build_scripts/Windows-msys2/build/env.bat @@ -2,8 +2,6 @@ call "%~dp0env-base.bat" %* if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env -set MSYSTEM=MINGW%RsBit% - set BuildPath=%EnvRootPath%\builds set DeployPath=%EnvRootPath%\deploy @@ -14,13 +12,13 @@ if not exist "%DeployPath%" mkdir "%DeployPath%" call "%ToolsPath%\get-qt-version.bat" QtVersion if "%QtVersion%"=="" %cecho% error "Cannot get Qt version." & exit /B 1 -set RsMinGWPath=%EnvMSYS2BasePath%\mingw%RsBit% +set RsMinGWPath=%EnvMSYS2BasePath%\%RsToolchain% -set RsBuildPath=%BuildPath%\Qt-%QtVersion%-%RsArchitecture%-%RsCompiler%-%RsBuildConfig% -set RsDeployPath=%DeployPath%\Qt-%QtVersion%%RsType%-%RsArchitecture%-%RsCompiler%-%RsBuildConfig% +set RsBuildPath=%BuildPath%\Qt-%QtVersion%-%RsToolchain%-%RsCompiler%-%RsBuildConfig% +set RsDeployPath=%DeployPath%\Qt-%QtVersion%%RsType%-%RsToolchain%-%RsCompiler%-%RsBuildConfig% set RsPackPath=%DeployPath% set RsArchiveAdd= -set RsWebuiPath=%RootPath%\%SourceName%-webui +set RsWebuiBuildPath=%RsBuildPath%\retroshare-webui\webui if not exist "%~dp0env-mod.bat" goto no_mod call "%~dp0env-mod.bat" diff --git a/build_scripts/Windows-msys2/build/pack.bat b/build_scripts/Windows-msys2/build/pack.bat index 20fb72c4d..313da7479 100644 --- a/build_scripts/Windows-msys2/build/pack.bat +++ b/build_scripts/Windows-msys2/build/pack.bat @@ -105,6 +105,9 @@ copy "%RsBuildPath%\retroshare-nogui\src\%RsBuildConfig%\retroshare*-nogui.exe" copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite% copy "%RsBuildPath%\supportlibs\cmark\build\src\libcmark.dll" "%RsDeployPath%" %Quite% if exist "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" copy "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" "%RsDeployPath%" %Quite% +if exist "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" ( + copy "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" "%RsDeployPath%" %Quite% +) echo copy extensions for /D %%D in ("%RsBuildPath%\plugins\*") do ( @@ -132,8 +135,14 @@ del /Q "%RsDeployPath%\imageformats\*d?.dll" %Quite% if "%ParamTor%"=="1" ( echo copy tor - copy "%RsMinGWPath%\bin\tor.exe" "%RsDeployPath%" %Quite% - copy "%RsMinGWPath%\bin\tor-gencert.exe" "%RsDeployPath%" %Quite% + if not exist "%RsDeployPath%\tor" mkdir "%RsDeployPath%\tor" + copy "%RsMinGWPath%\bin\tor.exe" "%RsDeployPath%\tor" %Quite% + copy "%RsMinGWPath%\bin\tor-gencert.exe" "%RsDeployPath%\tor" %Quite% + + echo copy tor dependencies + for /R "%RsDeployPath%\tor" %%D in (*.exe) do ( + call :copy_dependencies "%%D" "%RsDeployPath%\tor" + ) ) echo copy dependencies @@ -141,14 +150,15 @@ for /R "%RsDeployPath%" %%D in (*.dll, *.exe) do ( call :copy_dependencies "%%D" "%RsDeployPath%" ) -echo copy qss -xcopy /S "%SourcePath%\retroshare-gui\src\qss" "%RsDeployPath%\qss" %Quite% +if exist "%SourcePath%\retroshare-gui\src\qss" ( + echo copy qss + xcopy /S "%SourcePath%\retroshare-gui\src\qss" "%RsDeployPath%\qss" %Quite% +) echo copy stylesheets xcopy /S "%SourcePath%\retroshare-gui\src\gui\qss\chat" "%RsDeployPath%\stylesheets" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\compact" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\standard" %Quite% -rmdir /S /Q "%RsDeployPath%\stylesheets\__MACOSX__Bubble" %Quite% echo copy sounds xcopy /S "%SourcePath%\retroshare-gui\src\sounds" "%RsDeployPath%\sounds" %Quite% @@ -177,12 +187,12 @@ echo copy buildinfo.txt copy "%RsBuildPath%\buildinfo.txt" "%RsDeployPath%" %Quite% if "%ParamWebui%"=="1" ( - if exist "%RsWebuiPath%\webui" ( + if exist "%RsWebuiBuildPath%" ( echo copy webui mkdir "%RsDeployPath%\webui" - xcopy /S "%RsWebuiPath%\webui" "%RsDeployPath%\webui" %Quite% + xcopy /S "%RsWebuiBuildPath%" "%RsDeployPath%\webui" %Quite% ) else ( - %cecho% error "Webui is enabled, but no webui data found at %RsWebuiPath%\webui" + %cecho% error "Webui is enabled, but no webui data found at %RsWebuiBuildPath%" goto error ) ) diff --git a/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat b/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat index 2f85c42be..d07c7a058 100644 --- a/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat +++ b/build_scripts/Windows-msys2/env/tools/prepare-msys2.bat @@ -25,8 +25,11 @@ if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( ) ) -set MSYS2Install=msys2-base-%MSYS2Architecture%-20200720.tar.xz -set MSYS2Url=http://sourceforge.net/projects/msys2/files/Base/%MSYS2Architecture%/%MSYS2Install%/download +if "%MSYS2Architecture%"=="i686" set MSYS2Version=20210705 +if "%MSYS2Architecture%"=="x86_64" set MSYS2Version=20210725 + +set MSYS2Install=msys2-base-%MSYS2Architecture%-%MSYS2Version%.tar.xz +set MSYS2Url=https://repo.msys2.org/distrib/%MSYS2Architecture%/%MSYS2Install% %cecho% info "Remove previous MSYS2 version" call "%ToolsPath%\remove-dir.bat" "%EnvMSYS2Path%" @@ -41,12 +44,11 @@ if not exist "%EnvDownloadPath%\%MSYS2Install%" %cecho% error "Cannot download M set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh %cecho% info "Initialize MSYS2" -"%MSYS2SH%" -lc "pacman -Sy" -"%MSYS2SH%" -lc "pacman --noconfirm --needed -S bash pacman pacman-mirrors msys2-runtime" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Sy" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat" -call "%EnvRootPath%\update-msys2.bat" -call "%EnvRootPath%\update-msys2.bat" :exit endlocal diff --git a/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat b/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat index 3075e392b..a3d2398cd 100644 --- a/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat +++ b/build_scripts/Windows-msys2/env/tools/root/update-msys2.bat @@ -8,11 +8,11 @@ if exist "%~dp0msys2\msys64" call :update 64 goto :EOF :update -set MSYSSH=%~dp0msys2\msys%~1\usr\bin\sh +set MSYS2SH=%~dp0msys2\msys%~1\usr\bin\sh echo Update MSYS2 %~1 -"%MSYSSH%" -lc "pacman -Sy" -"%MSYSSH%" -lc "pacman --noconfirm -Su" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" :exit endlocal diff --git a/build_scripts/Windows-msys2/installer/retroshare-Qt5.nsi b/build_scripts/Windows-msys2/installer/retroshare-Qt5.nsi index b30300634..cd4a7867e 100644 --- a/build_scripts/Windows-msys2/installer/retroshare-Qt5.nsi +++ b/build_scripts/Windows-msys2/installer/retroshare-Qt5.nsi @@ -218,7 +218,7 @@ Section $(Section_Data) Section_Data ; Stylesheets SetOutPath "$INSTDIR\qss" - File /r "${DEPLOYDIR}\qss\*.*" + File /nonfatal /r "${DEPLOYDIR}\qss\*.*" SectionEnd ;Section $(Section_Link) Section_Link diff --git a/build_scripts/Windows-msys2/tools/webui.bat b/build_scripts/Windows-msys2/tools/webui.bat deleted file mode 100644 index b7af01e53..000000000 --- a/build_scripts/Windows-msys2/tools/webui.bat +++ /dev/null @@ -1,22 +0,0 @@ -setlocal - -echo. -echo === webui -echo. -title Build webui - -if not exist "%RsWebuiPath%" ( - echo Checking out webui source into %RsWebuiPath% - if not "%ParamNoupdate%"=="1" ( - %EnvMSYS2Cmd% "pacman --noconfirm --needed -S git" - ) - git clone https://github.com/RetroShare/RSNewWebUI.git "%RsWebuiPath%" -) else ( - echo Webui source found at %RsWebuiPath% -) - -pushd "%RsWebuiPath%\webui-src\make-src" -%EnvMSYS2Cmd% "sh build.sh" -popd - -endlocal \ No newline at end of file diff --git a/build_scripts/Windows/build-libs/Makefile b/build_scripts/Windows/build-libs/Makefile index e6927150f..b7efeaa37 100644 --- a/build_scripts/Windows/build-libs/Makefile +++ b/build_scripts/Windows/build-libs/Makefile @@ -1,25 +1,24 @@ -ZLIB_VERSION=1.2.3 -BZIP2_VERSION=1.0.6 -MINIUPNPC_VERSION=2.0 -OPENSSL_VERSION=1.1.1h +ZLIB_VERSION=1.2.11 +BZIP2_VERSION=1.0.8 +MINIUPNPC_VERSION=2.2.3 +OPENSSL_VERSION=1.1.1p SPEEX_VERSION=1.2.0 -SPEEXDSP_VERSION=1.2rc3 -OPENCV_VERSION=4.5.0 -LIBXML2_VERSION=2.9.7 -LIBXSLT_VERSION=1.1.32 -CURL_VERSION=7.58.0 +SPEEXDSP_VERSION=1.2.0 +LIBXML2_VERSION=2.9.12 +LIBXSLT_VERSION=1.1.34 +CURL_VERSION=7.81.0 TCL_VERSION=8.6.10 -SQLCIPHER_VERSION=4.4.0 -LIBMICROHTTPD_VERSION=0.9.59 -FFMPEG_VERSION=3.4 +SQLCIPHER_VERSION=4.5.0 +LIBMICROHTTPD_VERSION=0.9.75 +FFMPEG_VERSION=4.4 RAPIDJSON_VERSION=1.1.0 -XAPIAN_VERSION=1.4.7 +XAPIAN_VERSION=1.4.19 DOWNLOAD_PATH?=download BUILD_PATH=build LIBS_PATH?=libs -all: dirs zlib bzip2 miniupnpc openssl speex speexdsp opencv libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs +all: dirs zlib bzip2 miniupnpc openssl speex speexdsp libxml2 libxslt curl sqlcipher libmicrohttpd ffmpeg rapidjson xapian copylibs download: \ $(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz \ @@ -28,7 +27,6 @@ download: \ $(DOWNLOAD_PATH)/openssl-$(OPENSSL_VERSION).tar.gz \ $(DOWNLOAD_PATH)/speex-$(SPEEX_VERSION).tar.gz \ $(DOWNLOAD_PATH)/speexdsp-$(SPEEXDSP_VERSION).tar.gz \ - $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz \ $(DOWNLOAD_PATH)/libxml2-$(LIBXML2_VERSION).tar.gz \ $(DOWNLOAD_PATH)/libxslt-$(LIBXSLT_VERSION).tar.gz \ $(DOWNLOAD_PATH)/curl-$(CURL_VERSION).tar.gz \ @@ -58,8 +56,7 @@ $(BUILD_PATH)/zlib-$(ZLIB_VERSION): $(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz rm -r -f $(BUILD_PATH)/zlib-* tar xvf $(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz # build - cd zlib-$(ZLIB_VERSION) && ./configure - #cd zlib-$(ZLIB_VERSION) && make install prefix="`pwd`/../$(BUILD_PATH)" + cd zlib-$(ZLIB_VERSION) && make -f win32/Makefile.gcc libz.a cd zlib-$(ZLIB_VERSION) && make # copy files mkdir -p $(BUILD_PATH)/zlib-$(ZLIB_VERSION).tmp/include @@ -74,7 +71,7 @@ $(BUILD_PATH)/zlib-$(ZLIB_VERSION): $(DOWNLOAD_PATH)/zlib-$(ZLIB_VERSION).tar.gz bzip2: $(BUILD_PATH)/bzip2-$(BZIP2_VERSION) $(DOWNLOAD_PATH)/bzip2-$(BZIP2_VERSION).tar.gz: - wget https://sourceforge.net/projects/bzip2/files/bzip2-$(BZIP2_VERSION).tar.gz/download -O $(DOWNLOAD_PATH)/bzip2-$(BZIP2_VERSION).tar.gz + wget https://www.sourceware.org/pub/bzip2/bzip2-$(BZIP2_VERSION).tar.gz -O $(DOWNLOAD_PATH)/bzip2-$(BZIP2_VERSION).tar.gz $(BUILD_PATH)/bzip2-$(BZIP2_VERSION): $(DOWNLOAD_PATH)/bzip2-$(BZIP2_VERSION).tar.gz # prepare @@ -102,10 +99,10 @@ $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION): $(DOWNLOAD_PATH)/miniupnpc-$(MINIU rm -r -f $(BUILD_PATH)/miniupnpc-* tar xvf $(DOWNLOAD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tar.gz # build - cd miniupnpc-$(MINIUPNPC_VERSION) && export CC=gcc && export PATH=.:$$PATH && make -f Makefile.mingw init libminiupnpc.a miniupnpc.dll + cd miniupnpc-$(MINIUPNPC_VERSION) && export CC=gcc && export PATH=.:$$PATH && make -f Makefile.mingw libminiupnpc.a miniupnpc.dll # copy files mkdir -p $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/include/miniupnpc - cp miniupnpc-$(MINIUPNPC_VERSION)/*.h $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/include/miniupnpc/ + cp miniupnpc-$(MINIUPNPC_VERSION)/include/*.h $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/include/miniupnpc/ mkdir -p $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/lib cp miniupnpc-$(MINIUPNPC_VERSION)/miniupnpc.lib $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/lib/ mkdir -p $(BUILD_PATH)/miniupnpc-$(MINIUPNPC_VERSION).tmp/bin @@ -187,31 +184,6 @@ $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION): $(DOWNLOAD_PATH)/speexdsp-$(SPEEXDSP rm -r -f speexdsp-$(SPEEXDSP_VERSION) mv $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION).tmp $(BUILD_PATH)/speexdsp-$(SPEEXDSP_VERSION) -opencv: $(BUILD_PATH)/opencv-$(OPENCV_VERSION) - -$(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz: - wget --no-check-certificate https://github.com/opencv/opencv/archive/$(OPENCV_VERSION).tar.gz -O $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - -$(BUILD_PATH)/opencv-$(OPENCV_VERSION): $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - # prepare - rm -r -f $(BUILD_PATH)/opencv-* - tar xvf $(DOWNLOAD_PATH)/opencv-$(OPENCV_VERSION).tar.gz - # Remove version numbers from libraries. Is there a switch? - sed -i -e's/\(ocv_update(OPENCV_DLLVERSION \).*$$/\1"")/' opencv-$(OPENCV_VERSION)/CMakeLists.txt - # build - 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`/../../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 -DENABLE_CXX11=ON -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -DSTRSAFE_NO_DEPRECATE" -DCMAKE_INSTALL_PREFIX="`pwd`/install" - cd opencv-$(OPENCV_VERSION)/build && make install - # copy files - mkdir -p $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/include - cp -r opencv-$(OPENCV_VERSION)/build/install/include/* $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/include/ - mkdir -p $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/lib/opencv - cp -r opencv-$(OPENCV_VERSION)/build/install/x64/mingw/staticlib/* $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp/lib/opencv/ - # cleanup - rm -r -f opencv-$(OPENCV_VERSION) - mv $(BUILD_PATH)/opencv-$(OPENCV_VERSION).tmp $(BUILD_PATH)/opencv-$(OPENCV_VERSION) - libxml2: $(BUILD_PATH)/libxml2-$(LIBXML2_VERSION) $(DOWNLOAD_PATH)/libxml2-$(LIBXML2_VERSION).tar.gz: @@ -341,7 +313,7 @@ $(BUILD_PATH)/ffmpeg-$(FFMPEG_VERSION): $(DOWNLOAD_PATH)/ffmpeg-$(FFMPEG_VERSION rm -r -f $(BUILD_PATH)/ffmpeg-* tar xvf $(DOWNLOAD_PATH)/ffmpeg-$(FFMPEG_VERSION).tar.gz # build - cd ffmpeg-$(FFMPEG_VERSION) && ./configure --disable-shared --enable-static --disable-programs --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-ffserver --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-yasm --disable-everything --enable-encoder=mpeg4 --enable-decoder=mpeg4 --prefix="`pwd`/../$(BUILD_PATH)/ffmpeg-$(FFMPEG_VERSION).tmp" + cd ffmpeg-$(FFMPEG_VERSION) && ./configure --disable-shared --enable-static --disable-programs --disable-ffmpeg --disable-ffplay --disable-ffprobe --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-yasm --disable-everything --enable-encoder=mpeg4 --enable-decoder=mpeg4 --prefix="`pwd`/../$(BUILD_PATH)/ffmpeg-$(FFMPEG_VERSION).tmp" cd ffmpeg-$(FFMPEG_VERSION) && make install # cleanup rm -r -f ffmpeg-$(FFMPEG_VERSION) diff --git a/build_scripts/Windows/build.bat b/build_scripts/Windows/build.bat index 9dd51cc16..90bf2ae1c 100644 --- a/build_scripts/Windows/build.bat +++ b/build_scripts/Windows/build.bat @@ -13,11 +13,11 @@ call "%~dp0build-libs\build-libs.bat" if errorlevel 1 %cecho% error "Failed to build libraries." & exit /B %ERRORLEVEL% %cecho% info "Build %SourceName%" -call "%~dp0build\build.bat" release autologin jsonapi plugins nativedialogs +call "%~dp0build\build.bat" release autologin webui plugins nativedialogs service if errorlevel 1 %cecho% error "Failed to build %SourceName%." & exit /B %ERRORLEVEL% %cecho% info "Pack %SourceName%" -call "%~dp0build\pack.bat" release plugins +call "%~dp0build\pack.bat" release webui plugins service if errorlevel 1 %cecho% error "Failed to pack %SourceName%." & exit /B %ERRORLEVEL% %cecho% info "Build installer" diff --git a/build_scripts/Windows/build/build-installer.bat b/build_scripts/Windows/build/build-installer.bat index b34e76157..7209afb6e 100644 --- a/build_scripts/Windows/build/build-installer.bat +++ b/build_scripts/Windows/build/build-installer.bat @@ -9,7 +9,7 @@ call "%EnvPath%\env.bat" if errorlevel 1 goto error_env :: Initialize environment -call "%~dp0env.bat" release +call "%~dp0env.bat" installer release if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env @@ -40,6 +40,7 @@ set NSIS_PARAM=%NSIS_PARAM% /DARCHITECTURE="%GCCArchitecture%" set NSIS_PARAM=%NSIS_PARAM% /DDATE="%RsDate%" if exist "%EnvTorPath%\Tor\tor.exe" set NSIS_PARAM=%NSIS_PARAM% /DTORDIR="%EnvTorPath%\Tor" +if exist "%RsWebuiBuildPath%" set NSIS_PARAM=%NSIS_PARAM% /DWEBUIDIR="%RsWebuiBuildPath%" :: Get compiled version call "%ToolsPath%\get-rs-version.bat" "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\retroshare.exe" RsVersion diff --git a/build_scripts/Windows/build/build.bat b/build_scripts/Windows/build/build.bat index 095fc6081..487647568 100644 --- a/build_scripts/Windows/build/build.bat +++ b/build_scripts/Windows/build/build.bat @@ -9,7 +9,7 @@ call "%EnvPath%\env.bat" if errorlevel 1 goto error_env :: Initialize environment -call "%~dp0env.bat" %* +call "%~dp0env.bat" build %* if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env @@ -49,11 +49,15 @@ echo. title Build - %SourceName%-%RsBuildConfig% [qmake] -set RS_QMAKE_CONFIG=%RsBuildConfig% no_rs_cppwarning +set RS_QMAKE_CONFIG=%RsBuildConfig% if "%ParamAutologin%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_autologin if "%ParamJsonApi%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_jsonapi +if "%ParamWebui%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_webui if "%ParamPlugins%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% retroshare_plugins if "%ParamUseNativeDialogs%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_use_native_dialogs +if "%ParamService%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_retroshare_service +if "%ParamFriendServer%" NEQ "1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% no_rs_friendserver +if "%ParamEmbeddedFriendServer%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% rs_efs qmake "%SourcePath%\RetroShare.pro" -r -spec win32-g++ "CONFIG+=%RS_QMAKE_CONFIG%" "EXTERNAL_LIB_DIR=%BuildLibsPath%\libs" if errorlevel 1 goto error diff --git a/build_scripts/Windows/build/clean.bat b/build_scripts/Windows/build/clean.bat index e8d5aa7b8..4ab752d4d 100644 --- a/build_scripts/Windows/build/clean.bat +++ b/build_scripts/Windows/build/clean.bat @@ -8,7 +8,7 @@ if errorlevel 1 goto error_env call "%EnvPath%\env.bat" if errorlevel 1 goto error_env -call "%~dp0env.bat" %* +call "%~dp0env.bat" clean %* if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env diff --git a/build_scripts/Windows/build/env.bat b/build_scripts/Windows/build/env.bat index 883077173..98f70c87f 100644 --- a/build_scripts/Windows/build/env.bat +++ b/build_scripts/Windows/build/env.bat @@ -4,11 +4,18 @@ set ParamDebug=0 set ParamAutologin=0 set ParamPlugins=0 set ParamJsonApi=0 +set ParamWebui=0 +set ParamService=0 +set ParamFriendServer=0 +set ParamEmbeddedFriendServer=0 set ParamUseNativeDialogs=0 set ParamTor=0 set NonInteractive=0 set CoreCount=%NUMBER_OF_PROCESSORS% +set Module=%~1 +shift /1 + :parameter_loop if "%~1" NEQ "" ( for /f "tokens=1,2 delims==" %%a in ("%~1") do ( @@ -20,6 +27,15 @@ if "%~1" NEQ "" ( set ParamAutologin=1 ) else if "%%~a"=="jsonapi" ( set ParamJsonApi=1 + ) else if "%%~a"=="webui" ( + set ParamJsonApi=1 + set ParamWebui=1 + ) else if "%%~a"=="service" ( + set ParamService=1 + ) else if "%%~a"=="friendserver" ( + set ParamFriendServer=1 + ) else if "%%~a"=="embedded-friendserver" ( + set ParamEmbeddedFriendServer=1 ) else if "%%~a"=="plugins" ( set ParamPlugins=1 ) else if "%%~a"=="tor" ( @@ -32,7 +48,7 @@ if "%~1" NEQ "" ( set ParamUseNativeDialogs=1 ) else ( echo. - echo Unknown parameter %1 + echo Unknown parameter %1 for %Module% goto :usage ) ) @@ -89,6 +105,7 @@ set RsBuildPath=%BuildPath%\Qt-%QtVersion%-%GCCArchitecture%-%RsBuildConfig% set RsDeployPath=%DeployPath%\Qt-%QtVersion%-%GCCArchitecture%%RsType%-%RsBuildConfig% set RsPackPath=%DeployPath% set RsArchiveAdd= +set RsWebuiBuildPath=%RsBuildPath%\retroshare-webui\webui if not exist "%~dp0env-mod.bat" goto no_mod call "%~dp0env-mod.bat" @@ -102,21 +119,33 @@ echo. echo Usage: release^|debug [^] echo. echo Mandatory parameter -echo release^|debug Build release or debug version +echo release^|debug Build release or debug version echo. -echo Optional parameter (need clean when changed) -echo autologin Build with autologin -echo jsonapi Build with jsonapi -echo plugins Build plugins -echo nativedialogs Build with native dialogs -echo. -echo Optional parameter -echo singlethread Use only 1 thread for building -echo. -echo Parameter for pack -echo tor Pack tor version -echo. -echo Parameter for git-log -echo non-interactive Non-interactive mode +if "%Module%"=="build" ( + echo Optional parameter ^(need clean when changed^) + echo autologin Build with autologin + echo jsonapi Build with jsonapi + echo webui Build with jsonapi and webui + echo service Build service + echo friendserver Build Friend Server + echo embedded-friendserver Build with embedded Friend Server + echo plugins Build plugins + echo nativedialogs Build with native dialogs + echo. + echo Optional parameter + echo singlethread Use only 1 thread for building +) +if "%Module%"=="pack" ( + echo Optional parameter + echo webui Pack webui + echo service Pack service + echo friendserver Pack Friend Server ^(needs Tor^) + echo tor Pack Tor version + echo plugins Pack plugins +) +if "%Module%"=="git-log" ( + echo Optional parameter + echo non-interactive Non-interactive mode +) echo. exit /B 2 diff --git a/build_scripts/Windows/build/git-log.bat b/build_scripts/Windows/build/git-log.bat index 4d479fc3f..b2328d853 100644 --- a/build_scripts/Windows/build/git-log.bat +++ b/build_scripts/Windows/build/git-log.bat @@ -8,7 +8,7 @@ if errorlevel 1 goto error_env call "%EnvPath%\env.bat" if errorlevel 1 goto error_env -call "%~dp0env.bat" %* +call "%~dp0env.bat" git-log %* if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env @@ -88,6 +88,10 @@ echo %RsRef%>"%RsLastRefFile%" exit /B %ERRORLEVEL% +:error +%cecho% error "\n%~n0 failed\n" +exit /B 1 + :error_env echo Failed to initialize environment. endlocal diff --git a/build_scripts/Windows/build/pack.bat b/build_scripts/Windows/build/pack.bat index 204158ae3..1c844efa0 100644 --- a/build_scripts/Windows/build/pack.bat +++ b/build_scripts/Windows/build/pack.bat @@ -11,7 +11,7 @@ call "%EnvPath%\env.bat" if errorlevel 1 goto error_env :: Initialize environment -call "%~dp0env.bat" %* +call "%~dp0env.bat" pack %* if errorlevel 2 exit /B 2 if errorlevel 1 goto error_env @@ -95,9 +95,23 @@ copy nul "%RsDeployPath%\portable" %Quite% echo copy binaries copy "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\retroshare*.exe" "%RsDeployPath%" %Quite% -copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite% if exist "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" copy "%RsBuildPath%\libretroshare\src\lib\retroshare.dll" "%RsDeployPath%" %Quite% +if "%ParamService%"=="1" ( + copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite% + if errorlevel 1 %cecho% error "Service not found"& goto error +) + +if "%ParamFriendServer%"=="1" ( + if "%ParamTor%"=="1" ( + copy "%RsBuildPath%\retroshare-friendserver\src\%RsBuildConfig%\retroshare-friendserver.exe" "%RsDeployPath%" %Quite% + if errorlevel 1 %cecho% error "Friend Server not found"& goto error + ) else ( + %cecho% error "Friend Server needs Tor" + goto error + ) +) + echo copy extensions if "%ParamPlugins%"=="1" ( for /D %%D in ("%RsBuildPath%\plugins\*") do ( @@ -132,14 +146,15 @@ if exist "%QtPath%\..\plugins\styles\qwindowsvistastyle.dll" ( copy "%QtPath%\..\plugins\imageformats\*.dll" "%RsDeployPath%\imageformats" %Quite% del /Q "%RsDeployPath%\imageformats\*d?.dll" %Quite% -echo copy qss -xcopy /S "%SourcePath%\retroshare-gui\src\qss" "%RsDeployPath%\qss" %Quite% +if exist "%SourcePath%\retroshare-gui\src\qss" ( + echo copy qss + xcopy /S "%SourcePath%\retroshare-gui\src\qss" "%RsDeployPath%\qss" %Quite% +) echo copy stylesheets xcopy /S "%SourcePath%\retroshare-gui\src\gui\qss\chat" "%RsDeployPath%\stylesheets" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\compact" %Quite% rmdir /S /Q "%RsDeployPath%\stylesheets\standard" %Quite% -rmdir /S /Q "%RsDeployPath%\stylesheets\__MACOSX__Bubble" %Quite% echo copy sounds xcopy /S "%SourcePath%\retroshare-gui\src\sounds" "%RsDeployPath%\sounds" %Quite% @@ -166,15 +181,17 @@ copy "%SourcePath%\libbitdht\src\bitdht\bdboot.txt" "%RsDeployPath%" %Quite% echo copy changelog.txt copy "%RsBuildPath%\changelog.txt" "%RsDeployPath%" %Quite% -if exist "%SourcePath%\libresapi\src\webui" ( +if defined ParamWebui ( echo copy webui mkdir "%RsDeployPath%\webui" - xcopy /S "%SourcePath%\libresapi\src\webui" "%RsDeployPath%\webui" %Quite% + xcopy /S "%RsWebuiBuildPath%" "%RsDeployPath%\webui" %Quite% + if errorlevel 1 %cecho% error "WebUi not found"& goto error ) if "%ParamTor%"=="1" ( echo copy tor - echo n | copy /-y "%EnvTorPath%\Tor\*.*" "%RsDeployPath%" %Quite% + if not exist "%RsDeployPath%\tor" mkdir "%RsDeployPath%\tor" + echo n | copy /-y "%EnvTorPath%\Tor\*.*" "%RsDeployPath%\tor" %Quite% ) rem pack files diff --git a/build_scripts/Windows/env/env-msys2.bat b/build_scripts/Windows/env/env-msys2.bat index b99ede679..fee7e46b9 100644 --- a/build_scripts/Windows/env/env-msys2.bat +++ b/build_scripts/Windows/env/env-msys2.bat @@ -5,7 +5,6 @@ call "%~dp0env.bat" if errorlevel 1 goto error_env -rem openssl x86 doesn't compile with mingw64 x64 :: Get gcc versions call "%ToolsPath%\get-gcc-version.bat" GCCVersion GCCArchitecture if "%GCCVersion%"=="" %cecho% error "Cannot get gcc version." & exit /B 1 @@ -27,7 +26,7 @@ set EnvMSYS2Path=%EnvRootPath%\msys2 call "%~dp0tools\prepare-msys2.bat" %1 if errorlevel 1 exit /B %ERRORLEVEL% -set EnvMSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh.exe +set EnvMSYS2SH=%EnvMSYS2Path%\msys64\usr\bin\sh.exe if not exist "%EnvMSYS2SH%" if errorlevel 1 goto error_env set EnvMSYS2Cmd="%EnvMSYS2SH%" -lc diff --git a/build_scripts/Windows/env/env.bat b/build_scripts/Windows/env/env.bat index bc95045b0..185a421a9 100644 --- a/build_scripts/Windows/env/env.bat +++ b/build_scripts/Windows/env/env.bat @@ -28,6 +28,9 @@ if errorlevel 1 exit /B %ERRORLEVEL% set PATH=%EnvToolsPath%\MinGit\cmd;%EnvToolsPath%\cmake\bin;%PATH% set HOME=%EnvToolsPath%\MinGit\home +:: Add Doxygen to PATH +set PATH=%EnvToolsPath%\doxygen;%PATH% + exit /B 0 :error_env diff --git a/build_scripts/Windows/env/tools/prepare-msys2.bat b/build_scripts/Windows/env/tools/prepare-msys2.bat index 0a649ae0e..17fe6c36e 100644 --- a/build_scripts/Windows/env/tools/prepare-msys2.bat +++ b/build_scripts/Windows/env/tools/prepare-msys2.bat @@ -16,7 +16,15 @@ if "%~1"=="clean" ( goto exit ) -if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( +set MSYS2Version=20230318 + +set MSYS2Install=msys2-base-x86_64-%MSYS2Version%.sfx.exe +set MSYS2Url=https://github.com/msys2/msys2-installer/releases/download/%MSYS2Version:~0,4%-%MSYS2Version:~4,2%-%MSYS2Version:~6,2%/%MSYS2Install% +set CMakeInstall=cmake-3.19.0-win32-x86.zip +set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall% +set CMakeUnpackPath=%EnvMSYS2Path%\msys64 + +if exist "%CMakeUnpackPath%\usr\bin\pacman.exe" ( if "%~1"=="reinstall" ( choice /M "Found existing MSYS2 version. Do you want to proceed?" if !ERRORLEVEL!==2 goto exit @@ -25,15 +33,10 @@ if exist "%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\pacman.exe" ( ) ) -set MSYS2Install=msys2-base-%MSYS2Architecture%-20190524.tar.xz -set MSYS2Url=http://sourceforge.net/projects/msys2/files/Base/%MSYS2Architecture%/%MSYS2Install%/download -set CMakeInstall=cmake-3.19.0-win32-x86.zip -set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall% -set CMakeUnpackPath=%EnvMSYS2Path%\msys%MSYS2Base% -if exist "%EnvMSYS2Path%\msys%MSYS2Base%" ( +if exist "%CMakeUnpackPath%" ( %cecho% info "Remove previous MSYS2 version" - call "%ToolsPath%\remove-dir.bat" "%EnvMSYS2Path%\msys%MSYS2Base%" + call "%ToolsPath%\remove-dir.bat" "%CMakeUnpackPath%" ) %cecho% info "Download installation files" @@ -44,7 +47,7 @@ if not exist "%EnvDownloadPath%\%CMakeInstall%" call "%ToolsPath%\download-file. if not exist "%EnvDownloadPath%\%CMakeInstall%" %cecho% error "Cannot download CMake" & goto error %cecho% info "Unpack MSYS2" -"%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%MSYS2Install%" | "%EnvSevenZipExe%" x -y -si -ttar -o"%EnvMSYS2Path%" +"%EnvDownloadPath%\%MSYS2Install%" -y -o"%EnvMSYS2Path%" %cecho% info "Unpack CMake" "%EnvSevenZipExe%" x -o"%CMakeUnpackPath%" "%EnvDownloadPath%\%CMakeInstall%" @@ -56,25 +59,20 @@ if "%CMakeVersion%"=="" %cecho% error "CMake version not found." & goto :exit %cecho% info "Found CMake version %CMakeVersion%" set FoundProfile= -for /f "tokens=3" %%F in ('find /c /i "%CMakeVersion%" "%EnvMSYS2Path%\msys%MSYS2Base%\etc\profile"') do set FoundProfile=%%F +for /f "tokens=3" %%F in ('find /c /i "%CMakeVersion%" "%CMakeUnpackPath%\etc\profile"') do set FoundProfile=%%F if "%FoundProfile%"=="0" ( - echo export PATH="${PATH}:/%CMakeVersion%/bin">>"%EnvMSYS2Path%\msys%MSYS2Base%\etc\profile" + echo export PATH="${PATH}:/%CMakeVersion%/bin">>"%CMakeUnpackPath%\etc\profile" ) -set MSYS2SH=%EnvMSYS2Path%\msys%MSYS2Base%\usr\bin\sh - -%cecho% info "Update keyring" -"%MSYS2SH%" -lc "curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" -"%MSYS2SH%" -lc "pacman --noconfirm -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" +set MSYS2SH=%CMakeUnpackPath%\usr\bin\sh %cecho% info "Initialize MSYS2" -"%MSYS2SH%" -lc "pacman -Sy" -"%MSYS2SH%" -lc "pacman --noconfirm --needed -S bash pacman pacman-mirrors msys2-runtime" +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Sy" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" -call "%EnvMSYS2Path%\msys%MSYS2Base%\autorebase.bat" -call "%EnvRootPath%\update-msys2.bat" -call "%EnvRootPath%\update-msys2.bat" +call "%CMakeUnpackPath%\autorebase.bat" :exit endlocal diff --git a/build_scripts/Windows/env/tools/prepare-tools.bat b/build_scripts/Windows/env/tools/prepare-tools.bat index d53a70cf6..c2c1e1bdd 100644 --- a/build_scripts/Windows/env/tools/prepare-tools.bat +++ b/build_scripts/Windows/env/tools/prepare-tools.bat @@ -16,6 +16,9 @@ set NSISInstallPath=%EnvToolsPath%\NSIS set MinGitInstall=MinGit-2.28.0-32-bit.zip set MinGitUrl=https://github.com/git-for-windows/git/releases/download/v2.28.0.windows.1/%MinGitInstall% set MinGitInstallPath=%EnvToolsPath%\MinGit +set DoxygenInstall=doxygen-1.9.6.windows.x64.bin.zip +set DoxygenUrl=https://github.com/doxygen/doxygen/releases/download/Release_1_9_6/%DoxygenInstall% +set DoxygenInstallPath=%EnvToolsPath%\doxygen set CMakeVersion=cmake-3.19.0-win32-x86 set CMakeInstall=%CMakeVersion%.zip set CMakeUrl=https://github.com/Kitware/CMake/releases/download/v3.19.0/%CMakeInstall% @@ -135,6 +138,19 @@ if not exist "%MinGitInstallPath%\cmd\git.exe" ( "%EnvSevenZipExe%" x -o"%MinGitInstallPath%" "%EnvDownloadPath%\%MinGitInstall%" ) +if not exist "%EnvDownloadPath%\%DoxygenInstall%" call "%ToolsPath%\remove-dir.bat" "%DoxygenInstallPath%" +if not exist "%DoxygenInstallPath%\doxygen.exe" ( + if exist "%DoxygenInstallPath%" call "%ToolsPath%\remove-dir.bat" "%DoxygenInstallPath%" + + %cecho% info "Download Doxygen installation" + + if not exist "%EnvDownloadPath%\%DoxygenInstall%" call "%ToolsPath%\download-file.bat" "%DoxygenUrl%" "%EnvDownloadPath%\%DoxygenInstall%" + if not exist "%EnvDownloadPath%\%DoxygenInstall%" %cecho% error "Cannot download doxygen installation" & goto error + + %cecho% info "Unpack Doxygen" + "%EnvSevenZipExe%" x -o"%DoxygenInstallPath%" "%EnvDownloadPath%\%DoxygenInstall%" +) + if not exist "%EnvDownloadPath%\%CMakeInstall%" call "%ToolsPath%\remove-dir.bat" "%CMakeInstallPath%" if not exist "%CMakeInstallPath%\bin\cmake.exe" ( %cecho% info "Download CMake installation" @@ -160,7 +176,7 @@ mkdir "%EnvTempPath%" call "%ToolsPath%\download-file.bat" "%TorDownloadIndexUrl%" "%EnvTempPath%\index.html" if not exist "%EnvTempPath%\index.html" %cecho% error "Cannot download Tor installation" & goto error -for /F "tokens=1,2 delims= " %%A in ('%EnvSedExe% -r -n -e"s/.*href=\"^(.*^)^(tor-win32.*\.zip^)\".*/\2 \1\2/p" "%EnvTempPath%\index.html"') do set TorInstall=%%A& set TorDownloadUrl=%TorProjectUrl%%%B +for /F "tokens=1,2 delims= " %%A in ('%EnvSedExe% -r -n -e"s/.*href=\"^(.*^)^(tor-.*windows-i686\.tar\.gz^)\".*/\2 \1\2/p" "%EnvTempPath%\index.html"') do set TorInstall=%%A& set TorDownloadUrl=%%B call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%" if "%TorInstall%"=="" %cecho% error "Cannot download Tor installation" & goto error if "%TorDownloadUrl%"=="" %cecho% error "Cannot download Tor installation" & goto error @@ -173,7 +189,7 @@ if not exist "%EnvTorPath%\Tor\tor.exe" ( if not exist "%EnvDownloadPath%\%TorInstall%" %cecho% error "Cannot download Tor installation" & goto error %cecho% info "Unpack Tor" - "%EnvSevenZipExe%" x -o"%EnvTorPath%" "%EnvDownloadPath%\%TorInstall%" + "%EnvSevenZipExe%" x -so "%EnvDownloadPath%\%TorInstall%" | "%EnvSevenZipExe%" x -si -ttar -o"%EnvTorPath%" ) :exit diff --git a/build_scripts/Windows/env/tools/root/update-msys2.bat b/build_scripts/Windows/env/tools/root/update-msys2.bat index 3075e392b..ddd5bdd0f 100644 --- a/build_scripts/Windows/env/tools/root/update-msys2.bat +++ b/build_scripts/Windows/env/tools/root/update-msys2.bat @@ -2,18 +2,13 @@ setlocal -if exist "%~dp0msys2\msys32" call :update 32 -if exist "%~dp0msys2\msys64" call :update 64 +if not exist "%~dp0msys2\msys64" goto :EOF -goto :EOF +set MSYS2SH=%~dp0msys2\msys64\usr\bin\sh -:update -set MSYSSH=%~dp0msys2\msys%~1\usr\bin\sh +echo Update MSYS2 +"%MSYS2SH%" -lc "yes | pacman --noconfirm -Syuu msys2-keyring" +"%MSYS2SH%" -lc "pacman --noconfirm -Su" -echo Update MSYS2 %~1 -"%MSYSSH%" -lc "pacman -Sy" -"%MSYSSH%" -lc "pacman --noconfirm -Su" - -:exit endlocal goto :EOF diff --git a/build_scripts/Windows/installer/lang/ca_ES.nsh b/build_scripts/Windows/installer/lang/ca_ES.nsh index 74f92ffe5..4279f8174 100644 --- a/build_scripts/Windows/installer/lang/ca_ES.nsh +++ b/build_scripts/Windows/installer/lang/ca_ES.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Instal·la ${APPNAME} i els components necessaris." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Pells" !insertmacro LANG_STRING Section_Data_Desc "Instal·la pells." !insertmacro LANG_STRING Section_Shortcuts "Icones d'accés directe" diff --git a/build_scripts/Windows/installer/lang/de.nsh b/build_scripts/Windows/installer/lang/de.nsh index 663e9e786..d67eb3e6f 100644 --- a/build_scripts/Windows/installer/lang/de.nsh +++ b/build_scripts/Windows/installer/lang/de.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Installiert ${APPNAME} und die benötigten Komponenten." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installiert Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installiert WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installiert Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installiert Friend Server." !insertmacro LANG_STRING Section_Data "Skins" !insertmacro LANG_STRING Section_Data_Desc "Skins installieren." !insertmacro LANG_STRING Section_Shortcuts "Verknüpfungssymbole" diff --git a/build_scripts/Windows/installer/lang/en.nsh b/build_scripts/Windows/installer/lang/en.nsh index a709eec24..7ecb92979 100644 --- a/build_scripts/Windows/installer/lang/en.nsh +++ b/build_scripts/Windows/installer/lang/en.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Installs ${APPNAME} and required components." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Skins" !insertmacro LANG_STRING Section_Data_Desc "Installs skins." !insertmacro LANG_STRING Section_Shortcuts "Shortcut icons" diff --git a/build_scripts/Windows/installer/lang/es.nsh b/build_scripts/Windows/installer/lang/es.nsh index 66021c14e..5f0a8aeee 100644 --- a/build_scripts/Windows/installer/lang/es.nsh +++ b/build_scripts/Windows/installer/lang/es.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Instala ${APPNAME} y los componentes requeridos." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Coberturas (skins)" !insertmacro LANG_STRING Section_Data_Desc "Instalar coberturas" !insertmacro LANG_STRING Section_Shortcuts "Iconos de accesos directos" diff --git a/build_scripts/Windows/installer/lang/fr.nsh b/build_scripts/Windows/installer/lang/fr.nsh index 680746da0..e55ca2466 100644 --- a/build_scripts/Windows/installer/lang/fr.nsh +++ b/build_scripts/Windows/installer/lang/fr.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Installe ${APPNAME} et les composants requis." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Habillages" !insertmacro LANG_STRING Section_Data_Desc "Installe des habillages." !insertmacro LANG_STRING Section_Shortcuts "Icônes de raccourci" diff --git a/build_scripts/Windows/installer/lang/pl.nsh b/build_scripts/Windows/installer/lang/pl.nsh index 53fc42934..44b3b70a1 100644 --- a/build_scripts/Windows/installer/lang/pl.nsh +++ b/build_scripts/Windows/installer/lang/pl.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Instaluje ${APPNAME} oraz wymagane komponenty." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Skórki" !insertmacro LANG_STRING Section_Data_Desc "Instaluje skórki." !insertmacro LANG_STRING Section_Shortcuts "Ikony skrótów" diff --git a/build_scripts/Windows/installer/lang/ru.nsh b/build_scripts/Windows/installer/lang/ru.nsh index b8ba2df89..969d58629 100644 --- a/build_scripts/Windows/installer/lang/ru.nsh +++ b/build_scripts/Windows/installer/lang/ru.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Установка ${APPNAME} и необходимых компонентов." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Оболочки" !insertmacro LANG_STRING Section_Data_Desc "Установка оболочек." !insertmacro LANG_STRING Section_Shortcuts "Ярлыки" diff --git a/build_scripts/Windows/installer/lang/tr.nsh b/build_scripts/Windows/installer/lang/tr.nsh index 85abeaac2..70a475a86 100644 --- a/build_scripts/Windows/installer/lang/tr.nsh +++ b/build_scripts/Windows/installer/lang/tr.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "${APPNAME} ve gerekli bileşenleri kurar." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "Temalar" !insertmacro LANG_STRING Section_Data_Desc "Tema yükleyin." !insertmacro LANG_STRING Section_Shortcuts "Kısayol simgeleri" diff --git a/build_scripts/Windows/installer/lang/ts/en.ts b/build_scripts/Windows/installer/lang/ts/en.ts index e95f6939f..cb38b6d94 100644 --- a/build_scripts/Windows/installer/lang/ts/en.ts +++ b/build_scripts/Windows/installer/lang/ts/en.ts @@ -22,6 +22,48 @@ + + Section_WebUI + + WebUI + + + + + Section_WebUI_Desc + + Installs WebUI. + + + + + Section_Service + + Service + + + + + Section_Service_Desc + + Installs Service. + + + + + Section_FriendServer + + Friend Server + + + + + Section_FriendServer_Desc + + Installs Friend Server. + + + Section_Data diff --git a/build_scripts/Windows/installer/lang/zh_CN.nsh b/build_scripts/Windows/installer/lang/zh_CN.nsh index 330de33ab..7d9a3cc02 100644 --- a/build_scripts/Windows/installer/lang/zh_CN.nsh +++ b/build_scripts/Windows/installer/lang/zh_CN.nsh @@ -2,6 +2,12 @@ !insertmacro LANG_STRING Section_Main_Desc "Installs ${APPNAME} and required components." !insertmacro LANG_STRING Section_Tor "Tor" !insertmacro LANG_STRING Section_Tor_Desc "Installs Tor." +!insertmacro LANG_STRING Section_WebUI "WebUI" +!insertmacro LANG_STRING Section_WebUI_Desc "Installs WebUI." +!insertmacro LANG_STRING Section_Service "Service" +!insertmacro LANG_STRING Section_Service_Desc "Installs Service." +!insertmacro LANG_STRING Section_FriendServer "Friend Server" +!insertmacro LANG_STRING Section_FriendServer_Desc "Installs Friend Server." !insertmacro LANG_STRING Section_Data "皮肤" !insertmacro LANG_STRING Section_Data_Desc "安装皮肤" !insertmacro LANG_STRING Section_Shortcuts "快捷方式图标" diff --git a/build_scripts/Windows/installer/retroshare-Qt5.nsi b/build_scripts/Windows/installer/retroshare-Qt5.nsi index a6ebbc81b..3a7fbf37f 100644 --- a/build_scripts/Windows/installer/retroshare-Qt5.nsi +++ b/build_scripts/Windows/installer/retroshare-Qt5.nsi @@ -60,6 +60,9 @@ !define /date DATE "%Y%m%d" !endif +# Service +${!defineifexist} SERVICE_EXISTS "${RELEASEDIR}\retroshare-service\src\release\retroshare-service.exe" + # Tor !ifdef TORDIR ${!defineifexist} TOR_EXISTS "${TORDIR}\tor.exe" @@ -68,6 +71,20 @@ ${!defineifexist} TOR_EXISTS "${TORDIR}\tor.exe" !endif !endif +# WebUI +!ifdef WEBUIDIR +${!defineifexist} WEBUI_EXISTS "${WEBUIDIR}\index.html" +!ifndef WEBUI_EXISTS +!error "WebUI files not found" +!endif +!endif + +# Friend Server +!ifdef TOR_EXISTS +# Add Friend Server with Tor only +#${!defineifexist} FRIENDSERVER_EXISTS "${RELEASEDIR}\retroshare-friendserver\src\release\retroshare-friendserver.exe" +!endif + # Application name and version !define APPNAME "RetroShare" !define APPNAMEANDVERSION "${APPNAME} ${VERSION}" @@ -193,7 +210,6 @@ Section $(Section_Main) Section_Main ; Main binaries SetOutPath "$INSTDIR" File "${RELEASEDIR}\retroshare-gui\src\release\retroshare.exe" - File "${RELEASEDIR}\retroshare-service\src\release\retroshare-service.exe" File /nonfatal "${RELEASEDIR}\libretroshare\src\lib\retroshare.dll" ; Qt binaries @@ -282,14 +298,38 @@ Section $(Section_Main) Section_Main File /r "${SOURCEDIR}\retroshare-gui\src\license\*.*" SectionEnd +# Service +!ifdef SERVICE_EXISTS + Section /o $(Section_Service) Section_Service + SetOutPath "$INSTDIR" + File "${RELEASEDIR}\retroshare-service\src\release\retroshare-service.exe" + SectionEnd +!endif + +# Friend Server +!ifdef FRIENDSERVER_EXISTS + Section /o $(Section_FriendServer) Section_FriendServer + SetOutPath "$INSTDIR" + File "${RELEASEDIR}\retroshare-friendserver\src\release\retroshare-friendserver.exe" + SectionEnd +!endif + # Tor !ifdef TOR_EXISTS Section /o $(Section_Tor) Section_Tor - SetOutPath "$INSTDIR" + SetOutPath "$INSTDIR\tor" File /r "${TORDIR}\*" SectionEnd !endif +# WebUI +!ifdef WEBUI_EXISTS + Section /o $(Section_WebUI) Section_WebUI + SetOutPath "$INSTDIR\webui" + File /r "${WEBUIDIR}\*" + SectionEnd +!endif + # Plugins ${!defineifexist} PLUGIN_FEEDREADER_EXISTS "${RELEASEDIR}\plugins\FeedReader\lib\FeedReader.dll" ${!defineifexist} PLUGIN_VOIP_EXISTS "${RELEASEDIR}\plugins\VOIP\lib\VOIP.dll" @@ -334,7 +374,7 @@ Section $(Section_Data) Section_Data ; Stylesheets SetOutPath "$INSTDIR\qss" - File /r "${SOURCEDIR}\retroshare-gui\src\qss\*.*" + File /nonfatal /r "${SOURCEDIR}\retroshare-gui\src\qss\*.*" SectionEnd ;Section $(Section_Link) Section_Link @@ -355,6 +395,22 @@ Section $(Section_StartMenu) Section_StartMenu CreateDirectory "$SMPROGRAMS\${APPNAME}" CreateShortCut "$SMPROGRAMS\${APPNAME}\$(Link_Uninstall).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\retroshare.exe" "" "$INSTDIR\retroshare.exe" 0 + +!ifdef SERVICE_EXISTS + SectionGetFlags ${Section_Service} $0 + IntOp $0 $0 & ${SF_SELECTED} + ${If} $0 == ${SF_SELECTED} + CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME} Service.lnk" "$INSTDIR\retroshare-service.exe" "" "$INSTDIR\retroshare-service.exe" 0 + ${EndIf} +!endif + +!ifdef FRIENDSERVER_EXISTS + SectionGetFlags ${Section_FriendServer} $0 + IntOp $0 $0 & ${SF_SELECTED} + ${If} $0 == ${SF_SELECTED} + CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME} Friend Server.lnk" "$INSTDIR\retroshare-friendserver.exe" "" "$INSTDIR\retroshare-friendserver.exe" 0 + ${EndIf} +!endif SectionEnd Section $(Section_Desktop) Section_Desktop @@ -407,6 +463,9 @@ SectionEnd ; !insertmacro MUI_DESCRIPTION_TEXT ${Section_Link} $(Section_Link_Desc) !insertmacro MUI_DESCRIPTION_TEXT ${Section_AutoStart} $(Section_AutoStart_Desc) !insertmacro MUI_DESCRIPTION_TEXT ${Section_Tor} $(Section_Tor_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_WebUI} $(Section_WebUI_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_Service} $(Section_Service_Desc) + !insertmacro MUI_DESCRIPTION_TEXT ${Section_FriendServer} $(Section_FriendServer_Desc) !insertmacro MUI_FUNCTION_DESCRIPTION_END # Uninstall @@ -461,6 +520,26 @@ Function .onInit !insertmacro MUI_LANGDLL_DISPLAY FunctionEnd +!ifdef FRIENDSERVER_EXISTS +Function .onSelChange + SectionGetFlags ${Section_FriendServer} $0 + IntOp $0 $0 & ${SF_SELECTED} + ${If} $0 == ${SF_SELECTED} + # Activate Tor and set readonly + SectionGetFlags ${Section_Tor} $1 + IntOp $1 $1 | ${SF_SELECTED} + IntOp $1 $1 | ${SF_RO} + SectionSetFlags ${Section_Tor} $1 + ${Else} + # Remove readonly from Tor + SectionGetFlags ${Section_Tor} $1 + IntOp $2 ${SF_RO} ~ + IntOp $1 $1 & $2 + SectionSetFlags ${Section_Tor} $1 + ${EndIf} +FunctionEnd +!endif + # Installation mode Function RequireAdmin diff --git a/build_scripts/Windows/tools/generate-changelog.bat b/build_scripts/Windows/tools/generate-changelog.bat index c38225045..2eb87ced6 100644 --- a/build_scripts/Windows/tools/generate-changelog.bat +++ b/build_scripts/Windows/tools/generate-changelog.bat @@ -18,6 +18,8 @@ copy nul %logfile% > nul pushd %~1 +set Percent=%% + set last=HEAD for /f %%t in ('git tag --sort=-taggerdate --merged ^| findstr v') do ( echo generating changelog for !last!..%%t @@ -30,7 +32,7 @@ for /f %%t in ('git tag --sort=-taggerdate --merged ^| findstr v') do ( rem echo !last! ---^> %%t >> %logfile% echo ----------------------------------------------- >> %logfile% echo. >> %logfile% - git log %%t..!last! --no-merges "--pretty=format:%%h %%ai %%<(10,trunc)%%an %%s" >> %logfile% + git log %%t..!last! --no-merges "--pretty=format:!Percent!h !Percent!ai !Percent!<(10,trunc)!Percent!an !Percent!s" >> %logfile% echo. >> %logfile% echo. >> %logfile% set last=%%t diff --git a/jsonapi-generator/README.adoc b/jsonapi-generator/README.adoc index 64284b85c..cea59a117 100644 --- a/jsonapi-generator/README.adoc +++ b/jsonapi-generator/README.adoc @@ -1,447 +1,10 @@ -// SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team +// SPDX-FileCopyrightText: (C) 2021 Retroshare Team // SPDX-License-Identifier: CC0-1.0 -RetroShare JSON API -=================== += Moved -:Cxx: C++ +JSON API generator is now part of `libretroshare` look under `src/jsonapi/` +directory in `libretroshare` repository. -== How to use RetroShare JSON API - -Look for methods marked with +@jsonapi+ doxygen custom command into -+libretroshare/src/retroshare+. The method path is composed by service instance -pointer name like +rsGxsChannels+ for +RsGxsChannels+, and the method name like -+createGroup+ and pass the input paramethers as a JSON object. - -.Service instance pointer in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsGxsChannels* rsGxsChannels; --------------------------------------------------------------------------------- - -.Method declaration in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- - /** - * @brief Request channel creation. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @jsonapi{development} - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] group Channel data (name, description...) - * @return false on error, true otherwise - */ - virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0; --------------------------------------------------------------------------------- - -.paramethers.json -[source,json] --------------------------------------------------------------------------------- -{ - "group":{ - "mMeta":{ - "mGroupName":"JSON test group", - "mGroupFlags":4, - "mSignFlags":520 - }, - "mDescription":"JSON test group description" - }, - "caller_data":"Here can go any kind of JSON data (even objects) that the caller want to get back together with the response" -} --------------------------------------------------------------------------------- - -.Calling the JSON API with curl on the terminal -[source,bash] --------------------------------------------------------------------------------- -curl -u $API_USER --data @paramethers.json http://127.0.0.1:9092/rsGxsChannels/createGroup --------------------------------------------------------------------------------- - -.JSON API call result -[source,json] --------------------------------------------------------------------------------- -{ - "caller_data": "Here can go any kind of JSON data (even objects) that the caller want to get back together with the response", - "retval": true, - "token": 3 -} --------------------------------------------------------------------------------- - -Even if it is less efficient because of URL encoding HTTP +GET+ method is -supported too, so in cases where the client cannot use +POST+ she can still use -+GET+ taking care of encoding the JSON data. With +curl+ this can be done at -least in two different ways. - -.Calling the JSON API with GET method with curl on the terminal -[source,bash] --------------------------------------------------------------------------------- -curl -u $API_USER --get --data-urlencode jsonData@paramethers.json \ - http://127.0.0.1:9092/rsGxsChannels/createGroup --------------------------------------------------------------------------------- - -Letting +curl+ do the encoding is much more elegant but it is semantically -equivalent to the following. - -.Calling the JSON API with GET method and pre-encoded data with curl on the terminal --------------------------------------------------------------------------------- -curl -u $API_USER http://127.0.0.1:9092/rsGxsChannels/createGroup?jsonData=%7B%0A%20%20%20%20%22group%22%3A%7B%0A%20%20%20%20%20%20%20%20%22mMeta%22%3A%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupName%22%3A%22JSON%20test%20group%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mGroupFlags%22%3A4%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mSignFlags%22%3A520%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%22mDescription%22%3A%22JSON%20test%20group%20description%22%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22caller_data%22%3A%22Here%20can%20go%20any%20kind%20of%20JSON%20data%20%28even%20objects%29%20that%20the%20caller%20want%20to%20get%20back%20together%20with%20the%20response%22%0A%7D --------------------------------------------------------------------------------- - -Note that using +GET+ method +?jsonData=+ and then the JSON data URL encoded are -added after the path in the HTTP request. - - -== JSON API authentication - -Most of JSON API methods require authentication as they give access to -RetroShare user data, and we don't want any application running on the system -eventually by other users be able to access private data indiscriminately. -JSON API support HTTP Basic as authentication scheme, this is enough as JSON API -server is intented for usage on the same system (127.0.0.1) not over an -untrusted network. -If you need to use JSON API over an untrusted network consider using a reverse -proxy with HTTPS such as NGINX in front of JSON API server. -If RetroShare login has been effectuated through the JSON API you can use your -location SSLID as username and your PGP password as credential for the JSON API, -but we suggests you use specific meaningful and human readable credentials for -each JSON API client so the human user can have better control over which client -can access the JSON API. - -.NewToken.json -[source,json] --------------------------------------------------------------------------------- -{ - "token": "myNewUser:myNewPassword" -} --------------------------------------------------------------------------------- - -.An authenticated client can authorize new tokens like this --------------------------------------------------------------------------------- -curl -u $API_USER --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/authorizeToken --------------------------------------------------------------------------------- - -.An unauthenticated JSON API client can request access with --------------------------------------------------------------------------------- -curl --data @NewToken.json http://127.0.0.1:9092/jsonApiServer/requestNewTokenAutorization --------------------------------------------------------------------------------- - -When an unauthenticated client request his token to be authorized, JSON API -server will try to ask confirmation to the human user if possible through -+mNewAccessRequestCallback+, if it is not possible or the user didn't authorized -the token +false+ is returned. - - -== Offer new RetroShare services through JSON API - -To offer a retroshare service through the JSON API, first of all one need find -the global pointer to the service instance and document it in doxygen syntax, -plus marking with the custom doxygen command +@jsonapi{RS_VERSION}+ where -+RS_VERSION+ is the retroshare version in which this service became available -with the current semantic (major changes to the service semantic, changes the -meaning of the service itself, so the version should be updated in the -documentation in that case). - -.Service instance pointer in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsGxsChannels* rsGxsChannels; --------------------------------------------------------------------------------- - - -Once the service instance itself is known to the JSON API you need to document -in doxygen syntax and mark with the custom doxygen command -+@jsonapi{RS_VERSION}+ the methods of the service that you want to make -available through JSON API. - -.Offering RsGxsChannels::getChannelDownloadDirectory in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- - /** - * Get download directory for the given channel - * @jsonapi{development} - * @param[in] channelId id of the channel - * @param[out] directory reference to string where to store the path - * @return false on error, true otherwise - */ - virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId, - std::string& directory ) = 0; --------------------------------------------------------------------------------- - -For each paramether you must specify if it is used as input +@param[in]+ as -output +@param[out]+ or both +@param[inout]+. Paramethers and return value -types must be of a type supported by +RsTypeSerializer+ which already support -most basic types (+bool+, +std::string+...), +RsSerializable+ and containers of -them like +std::vector+. Paramethers passed by value and by -reference of those types are both supported, while passing by pointer is not -supported. If your paramether or return +class+/+struct+ type is not supported -yet by +RsTypeSerializer+ most convenient approach is to make it derive from -+RsSerializable+ and implement +serial_process+ method like I did with -+RsGxsChannelGroup+. - -.Deriving RsGxsChannelGroup from RsSerializable in rsgxschannels.h -[source,cpp] --------------------------------------------------------------------------------- -struct RsGxsChannelGroup : RsSerializable -{ - RsGroupMetaData mMeta; - std::string mDescription; - RsGxsImage mImage; - - bool mAutoDownload; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mDescription); - RS_SERIAL_PROCESS(mImage); - RS_SERIAL_PROCESS(mAutoDownload); - } -}; --------------------------------------------------------------------------------- - -You can do the same recursively for any member of your +struct+ that is not yet -supported by +RsTypeSerializer+. - -Some Retroshare {Cxx} API functions are asyncronous, historically RetroShare -didn't follow a policy on how to expose asyncronous API so differents services -and some times even differents method of the same service follow differents -asyncronous patterns, thus making automatic generation of JSON API wrappers for -those methods impractical. Instead of dealing with all those differents patterns -I have chosed to support only one new pattern taking advantage of modern {Cxx}11 -and restbed features. On the {Cxx}11 side lambdas and +std::function+s are used, -on the restbed side Server Side Events are used to send asyncronous results. - -Lets see an example so it will be much esier to understand. - -.RsGxsChannels::turtleSearchRequest asyncronous API -[source,cpp] --------------------------------------------------------------------------------- - /** - * @brief Request remote channels search - * @jsonapi{development} - * @param[in] matchString string to look for in the search - * @param multiCallback function that will be called each time a search - * result is received - * @param[in] maxWait maximum wait time in seconds for search results - * @return false on error, true otherwise - */ - virtual bool turtleSearchRequest( - const std::string& matchString, - const std::function& multiCallback, - std::time_t maxWait = 300 ) = 0; --------------------------------------------------------------------------------- - -+RsGxsChannels::turtleSearchRequest(...)+ is an asyncronous method because it -send a channel search request on turtle network and then everytime a result is -received from the network +multiCallback+ is called and the result is passed as -parameter. To be supported by the automatic JSON API wrappers generator an -asyncronous method need a parameter of type +std::function+ called -+callback+ if the callback will be called only once or +multiCallback+ if the -callback is expected to be called more then once like in this case. -A second mandatory parameter is +maxWait+ of type +std::time_t+ it indicates the -maximum amount of time in seconds for which the caller is willing to wait for -results, in case the timeout is reached the callback will not be called anymore. - -[IMPORTANT] -================================================================================ -+callback+ and +multiCallback+ parameters documentation must *not* specify -+[in]+, +[out]+, +[inout]+, in Doxygen documentation as this would fool the -automatic wrapper generator, and ultimately break the compilation. -================================================================================ - -.RsFiles::turtleSearchRequest asyncronous JSON API usage example -[source,bash] --------------------------------------------------------------------------------- -$ cat turtle_search.json -{ - "matchString":"linux" -} -$ curl --data @turtle_search.json http://127.0.0.1:9092/rsFiles/turtleSearchRequest -data: {"retval":true} - -data: {"results":[{"size":157631,"hash":"69709b4d01025584a8def5cd78ebbd1a3cf3fd05","name":"kill_bill_linux_1024x768.jpg"},{"size":192560,"hash":"000000000000000000009a93e5be8486c496f46c","name":"coffee_box_linux2.jpg"},{"size":455087,"hash":"9a93e5be8486c496f46c00000000000000000000","name":"Linux.png"},{"size":182004,"hash":"e8845280912ebf3779e400000000000000000000","name":"Linux_2_6.png"}]} - -data: {"results":[{"size":668,"hash":"e8845280912ebf3779e400000000000000000000","name":"linux.png"},{"size":70,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.txt.sha1sum"},{"size":3076767744,"hash":"e8845280912ebf3779e400000000000000000000","name":"kali-linux-2016.2-amd64.iso"},{"size":2780872,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.bin"},{"size":917504,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.lzma"},{"size":2278404096,"hash":"e8845280912ebf3779e400000000000000000000","name":"gentoo-linux-livedvd-amd64-multilib-20160704.iso"},{"size":151770333,"hash":"e8845280912ebf3779e400000000000000000000","name":"flashtool-0.9.23.0-linux.tar.7z"},{"size":2847372,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.elf"},{"size":1310720,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux.gz"},{"size":987809,"hash":"e8845280912ebf3779e400000000000000000000","name":"openwrt-ar71xx-generic-vmlinux-lzma.elf"}]} - --------------------------------------------------------------------------------- - -By default JSON API methods requires client authentication and their wrappers -are automatically generated by +json-api-generator+. -In some cases methods need do be accessible without authentication such as -+rsLoginHelper/getLocations+ so in the doxygen documentaion they have the custom -command +@jsonapi{RS_VERSION,unauthenticated}+. -Other methods such as +/rsControl/rsGlobalShutDown+ need special care so they -are marked with the custom doxygen command +@jsonapi{RS_VERSION,manualwrapper}+ -and their wrappers are not automatically generated but written manually into -+JsonApiServer::JsonApiServer(...)+. - -== Quirks - -=== 64 bits integers handling - -While JSON doesn't have problems representing 64 bits integers JavaScript, Dart -and other languages are not capable to handle those numbers natively. -To overcome this limitation JSON API output 64 bit integers as an object with -two keys, one as proper integer and one as string representation. - -.JSON API 64 bit integer output example -[source,json] --------------------------------------------------------------------------------- -"lobby_id": { "xint64": 6215642878098695544, "xstr64": "6215642878098695544" } --------------------------------------------------------------------------------- - -So from languages that have proper 64bit integers support like Python or C++ one -better read from `xint64` which is represented as a JSON integer, from languages -where there is no proper 64bit integers support like JavaScript one can read from -`xstr64` which is represented as JSON string (note that the first is not wrapped -in "" while the latter is). - -When one input a 64bit integer into the JSON API it first try to parse it as if -it was sent the old way for retrocompatibility. - -.JSON API 64 bit integer deprecated format input example -[source,json] --------------------------------------------------------------------------------- -"lobby_id":6215642878098695544 --------------------------------------------------------------------------------- - -This way is *DEPRECATED* and may disappear in the future, it is TEMPORALLY kept -only for retrocompatibiliy with old clients. - -If retrocompatible parsing attempt fail then it try to parse with the new way -with proper JSON integer format. - -.JSON API 64 bit integer new proper integer format input example -[source,json] --------------------------------------------------------------------------------- -lobby_id": { "xint64": 6215642878098695544 } --------------------------------------------------------------------------------- - -If this fails then it try to parse with the new way with JSON string format. - -.JSON API 64 bit integer new string format input example -[source,json] --------------------------------------------------------------------------------- -"lobby_id": { "xstr64": "6215642878098695544" } --------------------------------------------------------------------------------- - -[WARNING] -================================================================================ -Clients written in languages without proper 64bit integers support must -use *ONLY* the string format otherwise they will send approximated values and -get unexpected results from the JSON API, because parsing will success but the -value will not be exactly the one you believe you sent. -================================================================================ - - -== A bit of history - -=== First writings about this - -The previous attempt of exposing a RetroShare JSON API is called +libresapi+ and -unfortunatley it requires a bunch of boilerplate code when we want to expose -something present in the {Cxx} API in the JSON API. - -As an example here you can see the libresapi that exposes part of the retroshare -chat {Cxx} API and lot of boilerplate code just to convert {Cxx} objects to JSON - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L44 - -To avoid the {Cxx} to JSON and back conversion boilerplate code I have worked out -an extension to our {Cxx} serialization code so it is capable to serialize and -deserialize to JSON you can see it in this pull request - -https://github.com/RetroShare/RetroShare/pull/1155 - -So first step toward having a good API is to take advantage of the fact that RS -is now capable of converting C++ objects from and to JSON. - -The current API is accessible via HTTP and unix socket, there is no -authentication in both of them, so anyone having access to the HTTP server or to -the unix socket can access the API without extra restrictions. -Expecially for the HTTP API this is a big risk because also if the http server -listen on 127.0.0.1 every application on the machine (even rogue javascript -running on your web browser) can access that and for example on android it is -not safe at all (because of that I implemented the unix socket access so at -least in android API was reasonably safe) because of this. - -A second step to improve the API would be to implement some kind of API -authentication mechanism (it would be nice that the mechanism is handled at API -level and not at transport level so we can use it for any API trasport not just -HTTP for example) - -The HTTP server used by libresapi is libmicrohttpd server that is very minimal, -it doesn't provide HTTPS nor modern HTTP goodies, like server notifications, -websockets etc. because the lack of support we have a token polling mechanism in -libresapi to avoid polling for every thing but it is still ugly, so if we can -completely get rid of polling in the API that would be really nice. -I have done a crawl to look for a replacement and briefly looked at - -- https://www.gnu.org/software/libmicrohttpd/ -- http://wolkykim.github.io/libasyncd/ -- https://github.com/corvusoft/restbed -- https://code.facebook.com/posts/1503205539947302/introducing-proxygen-facebook-s-c-http-framework/ -- https://github.com/cmouse/yahttp - -taking in account a few metrics like modern HTTP goodies support, license, -platform support, external dependencies and documentation it seemed to me that -restbed is the more appropriate. - -Another source of boilerplate code into libresapi is the mapping between JSON -API requests and C++ API methods as an example you can look at this - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ChatHandler.cpp#L158 - -and this - -https://github.com/RetroShare/RetroShare/blob/v0.6.4/libresapi/src/api/ApiServer.cpp#L253 - -The abstract logic of this thing is, when libreasapi get a request like -+/chat/initiate_distant_chat+ then call -+ChatHandler::handleInitiateDistantChatConnexion+ which in turn is just a -wrapper of +RsMsgs::initiateDistantChatConnexion+ all this process is basically -implemented as boilerplate code and would be unnecessary in a smarter design of -the API because almost all the information needed is already present in the -C++ API +libretroshare/src/retroshare+. - -So a third step to improve the JSON API would be to remove this source of -boilerplate code by automatizing the mapping between C++ and JSON API call. - -This may result a little tricky as language parsing or other adevanced things -may be required. - -Hope this dive is useful for you + -Cheers + -G10h4ck - -=== Second writings about this - -I have been investigating a bit more about: -[verse, G10h4ck] -________________________________________________________________________________ -So a third step to improve the JSON API would be to remove this source of -boilerplate code by automatizing the mapping between C++ and JSON API call -________________________________________________________________________________ - -After spending some hours investigating this topic the most reasonable approach -seems to: - -1. Properly document headers in +libretroshare/src/retroshare/+ in doxygen syntax -specifying wihich params are input and/or output (doxygen sysntax for this is -+@param[in/out/inout]+) this will be the API documentation too. - -2. At compile time use doxygen to generate XML description of the headers and use -the XML to generate the JSON api server stub. -http://www.stack.nl/~dimitri/doxygen/manual/customize.html#xmlgenerator - -3. Enjoy +This directory and all it's content is kept as is only for retro-compatibility +with the old, deprecated `qmake` build system. diff --git a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl deleted file mode 100644 index 29f53ad48..000000000 --- a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * RetroShare JSON API * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -registerHandler( "$%apiPath%$", - [this](const std::shared_ptr session) -{ - const std::multimap headers - { - { "Connection", "keep-alive" }, - { "Content-Type", "text/event-stream" } - }; - session->yield(rb::OK, headers); - - size_t reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( reqSize, [this]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if( !checkRsServicePtrReady( - $%instanceName%$, "$%instanceName%$", cAns, session ) ) - return; - -$%paramsDeclaration%$ - -$%inputParamsDeserialization%$ - - const std::weak_ptr weakService(mService); - const std::weak_ptr weakSession(session); - $%callbackName%$ = [weakService, weakSession]($%callbackParams%$) - { - auto session = weakSession.lock(); - if(!session || session->is_closed()) return; - - auto lService = weakService.lock(); - if(!lService || lService->is_down()) return; - -$%callbackParamsSerialization%$ - - std::stringstream sStream; - sStream << "data: " << compactJSON << ctx.mJson << "\n\n"; - const std::string message = sStream.str(); - - lService->schedule( [weakSession, message]() - { - auto session = weakSession.lock(); - if(!session || session->is_closed()) return; - session->yield(message); - $%sessionEarlyClose%$ - } ); - }; - -$%functionCall%$ - -$%outputParamsSerialization%$ - - // return them to the API caller - std::stringstream message; - message << "data: " << compactJSON << cAns.mJson << "\n\n"; - session->yield(message.str()); - $%sessionDelayedClose%$ - } ); -}, $%requiresAuth%$ ); diff --git a/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl new file mode 120000 index 000000000..1ae671997 --- /dev/null +++ b/jsonapi-generator/src/async-method-wrapper-template.cpp.tmpl @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/async-method-wrapper-template.cpp.tmpl \ No newline at end of file diff --git a/jsonapi-generator/src/jsonapi-generator-doxygen.conf b/jsonapi-generator/src/jsonapi-generator-doxygen.conf deleted file mode 100644 index 0edd1de3e..000000000 --- a/jsonapi-generator/src/jsonapi-generator-doxygen.conf +++ /dev/null @@ -1,230 +0,0 @@ -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "libretroshare" - -ALIASES += jsonapi{1}="\xmlonly\endxmlonly" -ALIASES += jsonapi{2}="\xmlonly\endxmlonly" - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -#INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.idl \ - *.ddl \ - *.odl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.cs \ - *.d \ - *.php \ - *.php4 \ - *.php5 \ - *.phtml \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.pyw \ - *.f90 \ - *.f95 \ - *.f03 \ - *.f08 \ - *.f \ - *.for \ - *.tcl \ - *.vhd \ - *.vhdl \ - *.ucf \ - *.qsf - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = NO - -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. -# The default value is: YES. - -GENERATE_LATEX = NO - -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that -# captures the structure of the code including all documentation. -# The default value is: NO. - -GENERATE_XML = YES - - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all -# C-preprocessor directives found in the sources and include files. -# The default value is: YES. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names -# in the source code. If set to NO, only conditional compilation will be -# performed. Macro expansion can be done in a controlled way by setting -# EXPAND_ONLY_PREDEF to YES. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then -# the macro expansion is limited to the macros specified with the PREDEFINED and -# EXPAND_AS_DEFINED tags. -# The default value is: NO. -# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. - -EXPAND_ONLY_PREDEF = NO - diff --git a/jsonapi-generator/src/jsonapi-generator-doxygen.conf b/jsonapi-generator/src/jsonapi-generator-doxygen.conf new file mode 120000 index 000000000..9aff33c39 --- /dev/null +++ b/jsonapi-generator/src/jsonapi-generator-doxygen.conf @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/jsonapi-generator-doxygen.conf \ No newline at end of file diff --git a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl deleted file mode 100644 index a3927fba9..000000000 --- a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * RetroShare JSON API * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -registerHandler( "$%apiPath%$", - [](const std::shared_ptr session) -{ - size_t reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( reqSize, []( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if( !checkRsServicePtrReady( - $%instanceName%$, "$%instanceName%$", cAns, session ) ) - return; - -$%paramsDeclaration%$ - - // deserialize input parameters from JSON -$%inputParamsDeserialization%$ - - // call retroshare C++ API -$%functionCall%$ - - // serialize out parameters and return value to JSON -$%outputParamsSerialization%$ - - // return them to the API caller - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - } ); -}, $%requiresAuth%$ ); - diff --git a/jsonapi-generator/src/method-wrapper-template.cpp.tmpl b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl new file mode 120000 index 000000000..717044ed2 --- /dev/null +++ b/jsonapi-generator/src/method-wrapper-template.cpp.tmpl @@ -0,0 +1 @@ +../../libretroshare/src/jsonapi/method-wrapper-template.cpp.tmpl \ No newline at end of file diff --git a/libbitdht b/libbitdht new file mode 160000 index 000000000..659423769 --- /dev/null +++ b/libbitdht @@ -0,0 +1 @@ +Subproject commit 659423769541169457c41f71c8a038e2d64ba079 diff --git a/libbitdht/src/README.txt b/libbitdht/src/README.txt deleted file mode 100644 index a1dff67e4..000000000 --- a/libbitdht/src/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -What's in the Package ---------------------------------------------------------------- -bitdht - base BitDHT Code. -util - generic utils for networking and threading. -udp - UDP interfacing code. -lib - Where the library is created. -tests - basic unit tests. -example - example code of how to use libbitdht. -libbitdht.pro - build script for Qt's qmake. -README.txt - this file. - - -HOWTO libbitdht. ----------------------------------------------- -This version is build using Qt's qmake system. - -1) Install Qt's qmake system: libqt-dev -2) type ./qmake -3) type ./make -4) check out the example and tests to learn how to interface with libbitdht. - - diff --git a/libbitdht/src/bitdht/bdaccount.cc b/libbitdht/src/bitdht/bdaccount.cc deleted file mode 100644 index 57de177f7..000000000 --- a/libbitdht/src/bitdht/bdaccount.cc +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * bitdht/bdaccount.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdaccount.h" - -#include -#include - -#include -#include - - -#define LPF_FACTOR (0.90) - -bdAccount::bdAccount() - :mNoStats(BDACCOUNT_NUM_ENTRIES), - mCountersOut(BDACCOUNT_NUM_ENTRIES), mCountersRecv(BDACCOUNT_NUM_ENTRIES), - mLpfOut(BDACCOUNT_NUM_ENTRIES), mLpfRecv(BDACCOUNT_NUM_ENTRIES), - mLabel(BDACCOUNT_NUM_ENTRIES) -{ - - mLabel[BDACCOUNT_MSG_OUTOFDATEPING] = "OUTOFDATEPING "; - mLabel[BDACCOUNT_MSG_PING] = "PING "; - mLabel[BDACCOUNT_MSG_PONG] = "PONG "; - mLabel[BDACCOUNT_MSG_QUERYNODE] = "QUERYNODE "; - mLabel[BDACCOUNT_MSG_QUERYHASH] = "QUERYHASH "; - mLabel[BDACCOUNT_MSG_REPLYFINDNODE] = "REPLYFINDNODE "; - mLabel[BDACCOUNT_MSG_REPLYQUERYHASH] = "REPLYQUERYHASH "; - - mLabel[BDACCOUNT_MSG_POSTHASH] = "POSTHASH "; - mLabel[BDACCOUNT_MSG_REPLYPOSTHASH] = "REPLYPOSTHASH "; - - mLabel[BDACCOUNT_MSG_CONNECTREQUEST] = "CONNECTREQUEST "; - mLabel[BDACCOUNT_MSG_CONNECTREPLY] = "CONNECTREPLY "; - mLabel[BDACCOUNT_MSG_CONNECTSTART] = "CONNECTSTART "; - mLabel[BDACCOUNT_MSG_CONNECTACK] = "CONNECTACK "; - - resetStats(); -} - - -void bdAccount::incCounter(uint32_t idx, bool out) -{ - if ((signed) idx > mNoStats-1) - { - std::cerr << "bdAccount::incCounter() Invalid Index"; - std::cerr << std::endl; - } - - if (out) - { - mCountersOut[idx]++; - } - else - { - mCountersRecv[idx]++; - } - return; -} - - -void bdAccount::doStats() -{ - int i; - for(i = 0; i < mNoStats; i++) - { - mLpfOut[i] *= (LPF_FACTOR) ; - mLpfOut[i] += (1.0 - LPF_FACTOR) * mCountersOut[i]; - - mLpfRecv[i] *= (LPF_FACTOR) ; - mLpfRecv[i] += (1.0 - LPF_FACTOR) * mCountersRecv[i]; - } - resetCounters(); -} - -void bdAccount::printStats(std::ostream &out) -{ - int i; - out << " Send Recv: "; - out << std::endl; - for(i = 0; i < mNoStats; i++) - { - - out << "Send" << mLabel[i] << " : " << std::setw(10) << mLpfOut[i]; - out << " "; - out << "Recv" << mLabel[i] << " : " << std::setw(10) << mLpfRecv[i]; - out << std::endl; - } -} - -void bdAccount::resetCounters() -{ - int i; - for(i = 0; i < mNoStats; i++) - { - mCountersOut[i] = 0; - mCountersRecv[i] = 0; - } -} - -void bdAccount::resetStats() -{ - int i; - for(i = 0; i < mNoStats; i++) - { - mLpfOut[i] = 0; - mLpfRecv[i] = 0; - } - resetCounters(); -} - - - - diff --git a/libbitdht/src/bitdht/bdaccount.h b/libbitdht/src/bitdht/bdaccount.h deleted file mode 100644 index 7116e3ced..000000000 --- a/libbitdht/src/bitdht/bdaccount.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BITDHT_ACCOUNT_H -#define BITDHT_ACCOUNT_H - -/******************************************************************************* - * bitdht/bdaccount.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include - -#define BDACCOUNT_MSG_OUTOFDATEPING 0 -#define BDACCOUNT_MSG_PING 1 -#define BDACCOUNT_MSG_PONG 2 -#define BDACCOUNT_MSG_QUERYNODE 3 -#define BDACCOUNT_MSG_QUERYHASH 4 -#define BDACCOUNT_MSG_REPLYFINDNODE 5 -#define BDACCOUNT_MSG_REPLYQUERYHASH 6 - -#define BDACCOUNT_MSG_POSTHASH 7 -#define BDACCOUNT_MSG_REPLYPOSTHASH 8 - -#define BDACCOUNT_MSG_CONNECTREQUEST 9 -#define BDACCOUNT_MSG_CONNECTREPLY 10 -#define BDACCOUNT_MSG_CONNECTSTART 11 -#define BDACCOUNT_MSG_CONNECTACK 12 - -#define BDACCOUNT_NUM_ENTRIES 13 - -class bdAccount -{ - public: - - bdAccount(); - - void incCounter(uint32_t idx, bool out); - void doStats(); - void printStats(std::ostream &out); - void resetCounters(); - void resetStats(); - - private: - - int mNoStats; - - std::vector mCountersOut; - std::vector mCountersRecv; - - std::vector mLpfOut; - std::vector mLpfRecv; - - std::vector mLabel; - // Statistics. -}; - - - -#endif // BITDHT_ACCOUNT_H diff --git a/libbitdht/src/bitdht/bdboot.txt b/libbitdht/src/bitdht/bdboot.txt deleted file mode 100644 index 273a35afc..000000000 --- a/libbitdht/src/bitdht/bdboot.txt +++ /dev/null @@ -1,267 +0,0 @@ -1.162.168.21 8956 -2.6.224.136 17320 -5.116.142.222 13755 -5.189.185.57 6968 -5.202.101.3 4000 -5.227.124.122 1024 -5.227.124.122 20600 -5.227.124.122 64196 -5.39.94.218 6991 -5.79.102.9 6881 -5.89.120.163 2457 -14.117.182.22 1091 -14.8.109.32 17160 -23.115.236.180 42375 -24.153.98.173 1024 -24.38.199.13 10583 -27.150.87.242 1123 -27.151.179.38 51413 -27.152.212.182 1424 -31.24.186.40 16143 -31.36.78.93 30020 -31.44.90.218 51413 -37.120.213.132 19525 -37.14.113.18 3815 -37.146.76.158 51413 -37.187.105.230 5169 -37.232.184.93 6881 -37.46.150.58 51413 -39.111.152.200 17527 -39.154.68.57 28007 -42.200.116.4 18578 -42.3.188.207 19771 -45.176.111.21 1434 -45.32.43.51 49091 -45.76.218.165 52911 -45.77.214.200 44350 -46.172.86.23 46039 -46.223.161.46 23693 -46.237.96.68 16536 -46.52.174.214 24012 -46.7.227.47 27644 -46.7.9.41 21374 -49.64.73.215 51413 -49.74.50.28 60893 -49.75.73.147 51413 -49.79.26.15 51413 -49.83.226.50 20864 -49.83.241.222 51413 -52.9.197.152 6881 -58.209.188.12 20994 -59.149.118.196 51413 -59.2.250.243 57099 -59.6.53.18 57437 -60.104.89.4 51413 -60.124.114.239 16925 -60.178.44.27 1050 -60.99.229.14 20617 -61.223.34.21 17881 -61.227.127.222 22223 -61.239.28.169 18873 -62.210.82.193 51413 -64.191.5.92 56891 -65.92.141.96 58361 -67.215.246.10 6881 -68.151.213.83 20047 -69.40.178.254 50793 -71.34.2.150 8053 -72.95.247.56 12956 -73.157.77.166 5477 -74.109.243.24 7250 -74.140.153.59 24757 -74.72.13.99 9613 -76.29.106.98 41447 -77.202.207.190 33034 -77.21.64.116 22222 -77.245.14.94 9910 -78.131.78.35 51238 -78.158.1.15 7433 -78.231.125.98 12162 -78.242.250.55 55946 -79.164.245.5 49001 -80.147.23.201 32746 -80.200.171.90 16294 -80.99.222.34 51414 -81.171.17.30 42254 -82.221.103.244 6881 -82.235.78.193 44097 -82.244.32.78 43518 -82.64.181.170 38240 -82.64.249.25 51413 -82.64.44.119 51413 -82.65.164.218 15726 -82.65.68.9 51413 -82.77.146.109 53713 -83.46.92.34 50000 -84.195.46.218 54600 -84.40.106.115 12046 -85.149.0.42 21045 -86.121.194.1 51413 -86.98.50.30 21455 -87.123.166.45 4145 -87.169.199.211 10496 -88.7.217.202 31348 -88.99.25.154 38051 -89.135.26.33 51413 -89.17.134.184 10327 -89.245.86.20 32417 -89.253.118.133 8621 -90.101.94.104 20780 -90.151.95.110 2199 -90.219.241.30 51413 -90.219.8.170 11916 -91.121.136.132 59001 -91.123.72.241 49001 -91.142.65.40 51413 -91.173.208.204 16300 -91.211.245.40 7369 -91.92.194.144 1031 -91.98.96.76 5385 -92.244.238.115 3115 -92.97.68.210 58000 -93.100.182.236 32249 -93.11.175.113 22948 -93.115.202.240 64493 -93.152.132.9 12332 -94.154.81.100 12345 -94.222.188.14 29299 -95.211.117.105 62086 -95.219.143.102 10360 -95.222.119.133 43087 -95.42.138.33 16550 -96.39.191.231 52000 -99.192.24.198 52552 -103.226.250.79 3521 -103.82.242.163 8083 -104.156.238.118 34731 -104.237.149.26 64879 -107.155.5.39 6881 -109.129.202.63 11076 -109.148.168.121 21651 -109.24.244.111 33334 -110.81.114.66 24732 -111.175.84.3 6881 -111.216.9.68 13493 -113.105.18.227 16001 -113.194.69.53 53858 -113.219.200.7 12935 -113.252.78.238 23474 -113.68.239.87 6396 -113.69.96.171 51443 -114.188.193.161 22555 -114.231.190.193 51413 -114.232.201.253 30350 -114.32.153.245 26233 -114.32.1.94 7788 -114.38.137.40 24062 -114.75.44.238 6881 -115.133.66.181 9460 -115.205.157.105 51413 -116.1.193.182 51413 -117.247.200.35 5353 -117.60.240.145 35709 -117.60.62.8 51413 -117.93.101.232 51413 -118.123.245.182 5060 -119.177.21.161 27048 -119.64.245.112 56265 -121.171.118.184 11566 -121.178.169.67 49259 -121.234.117.237 15398 -122.116.102.22 14054 -123.202.146.112 23118 -123.217.135.139 7830 -128.68.229.32 51413 -134.209.114.242 8000 -139.28.218.4 34826 -142.113.115.71 26453 -148.251.68.55 50000 -148.70.53.219 2551 -150.117.108.250 21902 -150.117.44.190 25052 -151.224.15.227 51413 -157.157.157.41 51413 -161.97.102.243 51902 -162.208.6.211 51413 -167.179.83.227 60220 -168.70.68.30 18325 -169.0.60.179 64494 -171.5.165.129 6881 -172.104.76.77 60542 -172.104.93.28 35617 -172.98.144.81 19186 -173.176.138.246 9545 -173.199.70.134 39045 -173.212.205.73 51432 -173.212.219.143 6881 -174.89.174.228 51413 -175.197.1.120 52574 -176.9.8.143 58250 -178.118.86.145 51413 -178.162.139.87 10029 -178.32.220.92 6881 -178.67.121.182 49001 -182.138.217.58 6881 -182.138.90.72 50288 -182.139.213.160 39587 -183.131.239.178 57835 -183.22.252.15 21568 -185.126.33.59 50024 -185.156.175.187 1025 -185.157.221.247 25401 -185.252.60.243 49001 -185.45.195.156 28074 -185.45.195.181 28185 -185.45.195.190 28136 -185.61.148.114 64879 -188.133.192.123 19967 -188.235.1.208 7890 -188.240.208.187 51413 -192.181.103.63 19627 -192.241.151.29 6881 -193.242.205.145 49001 -193.77.153.124 59835 -194.176.114.54 51413 -194.35.233.206 20124 -195.154.172.169 36097 -195.154.172.169 38340 -195.154.172.169 48043 -195.154.172.169 48799 -195.154.179.2 22794 -195.154.179.2 41210 -195.154.179.2 42687 -195.154.179.2 49156 -195.154.179.2 50385 -195.154.179.2 50944 -195.154.181.225 37558 -195.191.246.240 1026 -196.191.92.25 22937 -197.157.219.137 22629 -197.61.66.105 24612 -198.13.48.70 37360 -199.254.238.193 15374 -200.63.107.82 13323 -201.241.63.68 38705 -203.130.242.178 28280 -203.213.61.76 50559 -207.154.222.13 51111 -210.195.211.60 49771 -210.6.145.50 15207 -212.102.42.202 7611 -212.129.19.188 27096 -212.129.19.188 29812 -212.129.19.188 50117 -212.129.19.188 51965 -212.129.33.59 6881 -212.32.231.67 51413 -212.86.51.7 65148 -213.136.79.7 11910 -218.161.100.192 51413 -218.219.199.148 18753 -220.189.94.56 13279 -222.211.148.83 8080 -222.77.110.143 46016 -223.116.81.154 10655 -223.16.153.107 51413 -223.26.31.77 21440 -223.65.101.235 25159 diff --git a/libbitdht/src/bitdht/bdboot_generate.sh b/libbitdht/src/bitdht/bdboot_generate.sh deleted file mode 100755 index 97618f0df..000000000 --- a/libbitdht/src/bitdht/bdboot_generate.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash - -< - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . - -LICENSE - -< bdboot.txt --------------------------------- -README - -function check_dht_host() -{ - mHost="$1" - mPort="$2" - - sudo nmap -oG - -sU -p $mPort $mHost | grep open | \ - awk '{print $2" "$5}' | awk -F/ '{print $1}' -} - -cat | while read line; do - hostIP="$(echo $line | awk '{print $1}')" - hostPort="$(echo $line | awk '{print $2}')" - check_dht_host $hostIP $hostPort -done - -check_dht_host router.utorrent.com 6881 -check_dht_host router.bittorrent.com 6881 -check_dht_host dht.libtorrent.org 25401 -check_dht_host dht.transmissionbt.com 6881 - diff --git a/libbitdht/src/bitdht/bdconnection.cc b/libbitdht/src/bitdht/bdconnection.cc deleted file mode 100644 index 494e076f3..000000000 --- a/libbitdht/src/bitdht/bdconnection.cc +++ /dev/null @@ -1,3528 +0,0 @@ -/******************************************************************************* - * bitdht/bdconnection.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include "bitdht/bdiface.h" - -#include "bitdht/bdnode.h" -#include "bitdht/bdquerymgr.h" -#include "bitdht/bdconnection.h" -#include "bitdht/bdmsgs.h" -#include "bitdht/bdstddht.h" -#include "util/bdnet.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" - -/* - * #define DEBUG_PROXY_CONNECTION 1 - * #define DEBUG_NODE_CONNECTION 1 - * #define DEBUG_NODE_CONNECTION_EXTRA 1 - * #define DEBUG_CONNECTION_DELAY 1 - */ - -//#define DEBUG_PROXY_CONNECTION 1 -//#define DEBUG_NODE_CONNECTION 1 -//#define DEBUG_CONNECTION_DELAY 1 - - -#define BITDHT_CR_PAUSE_SHORT_PERIOD 1 -#define BITDHT_CR_PAUSE_START_PERIOD 10 - -#define MAX_NUM_RETRIES 3 - -uint32_t createConnectionErrorCode(uint32_t userProvided, uint32_t fallback, uint32_t point); - -/************************************************************************************************************ -******************************************** Connection Config ********************************************** -************************************************************************************************************/ - -bdConnectManager::bdConnectManager(bdNodeId *ownId, bdSpace *space, bdQueryManager *qmgr, bdDhtFunctions *fns, bdNodePublisher *pub) - :mOwnId(*ownId), mNodeSpace(space), mQueryMgr(qmgr), mFns(fns), mPub(pub) -{ - defaultConnectionOptions(); -} - - - - -void bdConnectManager::defaultConnectionOptions() -{ - /* by default we want to help people proxy connections. - * As this involves no interaction at higher levels, - * we want ALL BitDHT clients to support - unless explicitly disabled. - */ - - setConnectionOptions(BITDHT_CONNECT_MODE_PROXY, - BITDHT_CONNECT_OPTION_AUTOPROXY); -} - -void bdConnectManager::setConnectionOptions(uint32_t allowedModes, uint32_t flags) -{ - mConfigAllowedModes = allowedModes; - mConfigAutoProxy = false; - - if (flags & BITDHT_CONNECT_OPTION_AUTOPROXY) - { - mConfigAutoProxy = true; - } - -} - -/* Setup Relay Mode */ -void bdConnectManager::setRelayMode(uint32_t mode) -{ - mRelayMode = mode; -} - - -void bdConnectManager::shutdownConnections() -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::shutdownConnections() Brutal Shutdown of the following connections: "; - std::cerr << std::endl; - - printConnections(); -#endif - - mConnectionRequests.clear(); - mConnections.clear(); - -} - -void bdConnectManager::printConnections() -{ - std::cerr << "bdConnectManager::printConnections()"; - std::cerr << std::endl; - - std::map::iterator it; - for(it = mConnectionRequests.begin(); it != mConnectionRequests.end(); it++) - { - std::cerr << "bdConnectManager::printConnections() Connect Request:"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; - } - - std::map::iterator tit; - for(tit = mConnections.begin(); tit != mConnections.end(); tit++) - { - std::cerr << "bdConnectManager::printConnections() ConnectAttempt:"; - std::cerr << std::endl; - std::cerr << tit->second; - std::cerr << std::endl; - } -} - - - - - - -/************************************************************************************************************ -****************************************** Connection Initiation ******************************************** -************************************************************************************************************/ - - -/* This is called to initialise a connection. - * the callback could be with regard to: - * a Direct EndPoint. - * a Proxy Proxy, or an Proxy EndPoint. - * a Relay Proxy, or an Relay EndPoint. - * - * We have two alternatives: - * 1) Direct Endpoint. - * 2) Using a Proxy. - */ - -int bdConnectManager::requestConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) -{ - /* check if connection obj already exists */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection() Mode: " << mode; - std::cerr << " Start: " << start; - std::cerr << " Target: "; - mFns->bdPrintNodeId(std::cerr, target); - std::cerr << " Local NetAddress: " << inet_ntoa(laddr->sin_addr); - std::cerr << ":" << ntohs(laddr->sin_port); - std::cerr << std::endl; -#endif - - if (!start) - { - return killConnectionRequest(laddr, target, mode); - } - - if (!(mConfigAllowedModes & mode)) - { - /* MODE not supported */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection() Mode Not Supported"; - std::cerr << std::endl; -#endif - return 0; - } - - // Seems like a dumb one, but the testing picked it up. - if (*target == mOwnId) - { - /* MODE not supported */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection() WARNING Not allowing connection to self"; - std::cerr << std::endl; -#endif - return 0; - } - - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { - return requestConnection_direct(laddr, target); - } - else - { - return requestConnection_proxy(laddr, target, mode, delay); - } -} - -int bdConnectManager::checkExistingConnectionAttempt(bdNodeId *target) -{ - std::map::iterator it; - it = mConnectionRequests.find(*target); - if (it != mConnectionRequests.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::checkExistingConnectAttempt() Found Existing Connection!"; - std::cerr << std::endl; -#endif - return 1; - } - return 0; -} - - -int bdConnectManager::killConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode) -{ - /* remove unused parameter warnings */ - (void) laddr; - (void) mode; - - /* check if connection obj already exists */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::killConnectionRequest() Mode: " << mode; - std::cerr << " Target: "; - mFns->bdPrintNodeId(std::cerr, target); - std::cerr << " Local NetAddress: " << inet_ntoa(laddr->sin_addr); - std::cerr << ":" << ntohs(laddr->sin_port); - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mConnectionRequests.find(*target); - if (it == mConnectionRequests.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::killConnectionRequest() ERROR Request not there!"; - std::cerr << std::endl; -#endif - return 0; - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::killConnectionRequest() Flagging Connection Request as DONE"; - std::cerr << std::endl; -#endif - - time_t now = time(NULL); - it->second.mState = BITDHT_CONNREQUEST_DONE; - it->second.mStateTS = now; - it->second.mErrCode = BITDHT_CONNECT_ERROR_SOURCE_START | - BITDHT_CONNECT_ERROR_USER; - - -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::killConnectionRequest() Flagging Connection Request as DONE"; - std::cerr << std::endl; - // Print Connection Attempt. - std::cerr << it->second << std::endl; -#endif - - return 1; -} - - - - -#define MIN_START_DIRECT_COUNT 1 -#define MIN_START_PROXY_COUNT 3 -#define MED_START_PROXY_COUNT 5 -#define CONNECT_NUM_PROXY_ATTEMPTS 10 - - -int bdConnectManager::requestConnection_direct(struct sockaddr_in *laddr, bdNodeId *target) -{ - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection_direct()"; - std::cerr << std::endl; -#endif - /* create a bdConnect, and put into the queue */ - bdConnectionRequest connreq; - - if (checkExistingConnectionAttempt(target)) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection_direct() Existing ConnectionRequest... NOOP"; - std::cerr << std::endl; -#endif - return 0; - } - - connreq.setupDirectConnection(laddr, target); - - std::list goodProxies; - std::list::iterator pit; - mQueryMgr->result(target, goodProxies); - for(pit = goodProxies.begin(); pit != goodProxies.end(); pit++) - { - connreq.mGoodProxies.push_back(bdProxyId(*pit, BD_PI_SRC_QUERYRESULT, 0)); - } - - /* now look in the bdSpace as well */ - if (connreq.mGoodProxies.size() < MIN_START_DIRECT_COUNT) - { - int number = CONNECT_NUM_PROXY_ATTEMPTS; - int with_flag = BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; - std::list matchIds; - std::list::iterator it; - std::list::iterator git; - - mNodeSpace->find_node(target, number, matchIds, with_flag); - - /* merge lists (costly should use sets or something) */ - for(it = matchIds.begin(); it != matchIds.end(); it++) - { - for(git = connreq.mGoodProxies.begin(); git != connreq.mGoodProxies.end(); git++) - { - if (git->id == *it) - break; - } - - if (git == connreq.mGoodProxies.end()) - { - connreq.mGoodProxies.push_back(bdProxyId(*it, BD_PI_SRC_NODESPACE_ENGINEVERSION, 0)); - } - } - } - - /* Actually if we lots of ids at this point... its likely that something is wrong - */ - - if (connreq.mGoodProxies.size() > 1) - { - std::cerr << "bdConnectManager::requestConnection_direct() ERROR Multiple Peers for DIRECT connection"; - std::cerr << std::endl; - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection_direct() CRINITSTATE Init Connection State"; - std::cerr << std::endl; - std::cerr << connreq; - std::cerr << std::endl; -#endif - - /* push connect onto queue, for later completion */ - - mConnectionRequests[*target] = connreq; - - /* connection continued via iterator */ - return 1; -} - - -int bdConnectManager::requestConnection_proxy(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay) -{ - -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy()"; - std::cerr << std::endl; -#endif - - - if (checkExistingConnectionAttempt(target)) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Existing ConnectionRequest... NOOP"; - std::cerr << std::endl; -#endif - return 0; - } - - /* create a bdConnect, and put into the queue */ - bdConnectionRequest connreq; - connreq.setupProxyConnection(laddr, target, mode, delay); - - /**** - * We want different behaviour here - depending on whether it is a proxy or a relay request - * furthermore if we are in relay server mode - we should only use those. - * - * Try to unify logic. - * - * Proxy - take potential proxies... - * - if RelayServerMode then relays. - * - take friends, friends of friends. - * - * Relay - - * - if RelayServerMode take relays. - * - take friends, friends of friends - * - take potential proxies. - */ - - - /* get the proxy lists from existing query */ - std::list::iterator pit; - std::list goodProxies; - std::list potentialProxies; - mQueryMgr->proxies(target, goodProxies); - mQueryMgr->potentialProxies(target, potentialProxies); - - /* check any potential proxies, must be same DHT Type */ - for(pit = potentialProxies.begin(); pit != potentialProxies.end(); ) - { - /* check the type in bdSpace */ - if (checkPeerForFlag(&(*pit), BITDHT_PEER_STATUS_DHT_ENGINE_VERSION)) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Shifting Pot -> Good: "; - mFns->bdPrintId(std::cerr, &(*pit)); - std::cerr << std::endl; -#endif - goodProxies.push_back(*pit); - pit = potentialProxies.erase(pit); - } - else - { - pit++; - } - } - - /* in proxy mode - put Good Proxies First */ - if (mode == BITDHT_CONNECT_MODE_PROXY) - { - for(pit = goodProxies.begin(); pit != goodProxies.end(); pit++) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Adding Good Proxy: "; - mFns->bdPrintId(std::cerr, &(*pit)); - std::cerr << std::endl; -#endif - connreq.mGoodProxies.push_back(bdProxyId(*pit, BD_PI_SRC_QUERYPROXY, 0)); - } - } - - - if (mRelayMode) - { - /* Add Relay Servers */ -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() In RelayMode... adding Relays"; -#endif - - std::list excluding; - std::multimap nearest; - - int number = CONNECT_NUM_PROXY_ATTEMPTS; - - mNodeSpace->find_nearest_nodes_with_flags(target, number, excluding, nearest, - BITDHT_PEER_STATUS_DHT_RELAY_SERVER); - - std::multimap::iterator it; - for(it = nearest.begin(); it != nearest.end(); it++) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Adding Relay Server: "; - mFns->bdPrintId(std::cerr, &(it->second)); - std::cerr << std::endl; -#endif - connreq.mGoodProxies.push_back(bdProxyId(it->second, BD_PI_SRC_NODESPACE_SERVER, 0)); - } - } - - { - std::list excluding; - std::multimap nearest; - - int number = CONNECT_NUM_PROXY_ATTEMPTS; - - mNodeSpace->find_nearest_nodes_with_flags(target, number, excluding, nearest, - BITDHT_PEER_STATUS_DHT_FRIEND); - - std::multimap::iterator it; - for(it = nearest.begin(); it != nearest.end(); it++) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Adding Friend: "; - mFns->bdPrintId(std::cerr, &(it->second)); - std::cerr << std::endl; -#endif - connreq.mGoodProxies.push_back(bdProxyId(it->second, BD_PI_SRC_NODESPACE_FRIEND, 0)); - } - } - - - /* in relay mode - Good Proxies are the BackUp */ - if (mode == BITDHT_CONNECT_MODE_RELAY) - { - for(pit = goodProxies.begin(); pit != goodProxies.end(); pit++) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Adding Good Proxy: "; - mFns->bdPrintId(std::cerr, &(*pit)); - std::cerr << std::endl; -#endif - connreq.mGoodProxies.push_back(bdProxyId(*pit, BD_PI_SRC_QUERYPROXY, 0)); - } - } - - // Final Desperate Measures! - if (connreq.mGoodProxies.size() < MED_START_PROXY_COUNT) - { - std::list excluding; - std::multimap nearest; - - int number = CONNECT_NUM_PROXY_ATTEMPTS; - - mNodeSpace->find_nearest_nodes_with_flags(target, number, excluding, nearest, - BITDHT_PEER_STATUS_DHT_FOF); - - std::multimap::iterator it; - for(it = nearest.begin(); it != nearest.end(); it++) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Querying FOF: "; - mFns->bdPrintId(std::cerr, &(it->second)); - std::cerr << std::endl; -#endif - //connreq.mGoodProxies.push_back(it->second); - mPub->send_query(&(it->second), target, true); - } - } - - - /* if we don't have enough proxies ... ping the potentials */ - if (connreq.mGoodProxies.size() < MED_START_PROXY_COUNT) - { - /* unknown, add to potential list, and ping! */ - for(pit = potentialProxies.begin(); pit != potentialProxies.end(); pit++) - { - - connreq.mPotentialProxies.push_back(*pit); - // If the pings come back will be handled by - // updatePotentialConnectionProxy() - - mPub->send_ping(&(*pit)); - -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() Pinging Potential Proxy"; - mFns->bdPrintId(std::cerr, &(*pit)); - std::cerr << std::endl; -#endif - } - } - - /*** ORIGINAL CODE - TRIES TO PING/SEARCH PEERS - INSTEAD OF JUST TRYING THEM - * NOT SURE WHAT THE BEST PLAN IS..... - * LEAVE THIS CODE HERE FOR REFERENCE.... - ***/ - -#if 0 - // Final Desperate Measures! - if (connreq.mGoodProxies.size() < MED_START_PROXY_COUNT) - { - /* now find closest acceptable peers, - * and trigger a search for target... - * this will hopefully find more suitable proxies. - */ - - std::list excluding; - std::multimap nearest; - - - int number = CONNECT_NUM_PROXY_ATTEMPTS; - - mNodeSpace->find_nearest_nodes_with_flags(target, number, excluding, nearest, - BITDHT_PEER_STATUS_DHT_FOF | - BITDHT_PEER_STATUS_DHT_FRIEND); - - // just ask for the same number of closest (above doesn't return anything atm) - //int nFound = nearest.size(); - //number = CONNECT_NUM_PROXY_ATTEMPTS - nFound; - - mNodeSpace->find_nearest_nodes_with_flags(target, number, excluding, nearest, - BITDHT_PEER_STATUS_DHT_ENGINE_VERSION ); - - std::multimap::iterator it; - for(it = nearest.begin(); it != nearest.end(); it++) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() is Entry it connected to Friend? : "; - mFns->bdPrintId(std::cerr, &(it->second)); - std::cerr << std::endl; -#endif - - //bdNodeId midId; - //mFns->bdRandomMidId(target, &(it->second.id), &midId); - /* trigger search */ - //mPub->send_query(&(it->second), &midId); - mPub->send_query(&(it->second), target); - } - } -#endif - - - if (connreq.mGoodProxies.size() < 1) - { - std::cerr << "bdConnectManager::requestConnection_proxy() ERROR initial proxyList.size() == 0"; - std::cerr << std::endl; - } - - if (connreq.mGoodProxies.size() < MIN_START_PROXY_COUNT) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() WARNING initial proxyList.size() == SMALL PAUSING"; - std::cerr << std::endl; -#endif - - time_t now = time(NULL); - /* PAUSE the connection Attempt, so we can wait for responses */ - connreq.mState = BITDHT_CONNREQUEST_PAUSED; - connreq.mPauseTS = now + BITDHT_CR_PAUSE_START_PERIOD; - } - -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::requestConnection_proxy() CRINITSTATE Init Connection State"; - std::cerr << std::endl; - std::cerr << connreq; - std::cerr << std::endl; -#endif - - - /* push connect onto queue, for later completion */ - mConnectionRequests[*target] = connreq; - - return 1; -} - - - - -void bdConnectManager::addPotentialConnectionProxy(const bdId *srcId, const bdId *target) -{ -#ifdef DEBUG_NODE_CONNECTION_EXTRA - std::cerr << "bdConnectManager::addPotentialConnectionProxy() "; - std::cerr << " srcId: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << " target: "; - bdStdPrintId(std::cerr, target); - std::cerr << std::endl; -#endif - - if (!srcId) - { - /* not one of our targets... drop it */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::addPotentialConnectionProxy() srcID = NULL, useless to us"; - std::cerr << std::endl; -#endif - return; - } - - std::map::iterator it; - it = mConnectionRequests.find(target->id); - if (it == mConnectionRequests.end()) - { - /* not one of our targets... drop it */ -#ifdef DEBUG_NODE_CONNECTION_EXTRA - std::cerr << "bdConnectManager::addPotentialConnectionProxy() Dropping Not one of Our Targets"; - std::cerr << std::endl; -#endif - return; - } - - if (it->second.mMode == BITDHT_CONNECT_MODE_DIRECT) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::addPotentialConnectionProxy() Dropping Target is DIRECT"; - std::cerr << std::endl; -#endif - return; - } - - /* This is one is strange elsewhere.... srcId = targetId. - * This means that peer is actually reachable! and we should be connecting directly. - * however there is not much we can do about it here. Really up to higher level logic. - */ - if (srcId->id == target->id) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::addPotentialConnectionProxy() ERROR srcId.id == target.id (more of a WARNING)"; - std::cerr << std::endl; - std::cerr << "bdConnectManager::addPotentialConnectionProxy() NB: This means peer is actually reachable...."; - std::cerr << std::endl; - std::cerr << "bdConnectManager::addPotentialConnectionProxy() and we should be connecting directly. Oh Well!"; - std::cerr << std::endl; -#endif - return; - } - - if (checkPeerForFlag(srcId, BITDHT_PEER_STATUS_DHT_ENGINE_VERSION)) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::addPotentialConnectionProxy() Src passes FLAG test"; - std::cerr << std::endl; -#endif - it->second.addGoodProxy(srcId); - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::addPotentialConnectionProxy() Dropping SrcId failed FLAG test"; - std::cerr << std::endl; -#endif - } -} - - -int bdConnectManager::checkPeerForFlag(const bdId *id, uint32_t with_flag) -{ - /* check the type in bdSpace */ - bdPeer peer; - if (mNodeSpace->find_exactnode(id, peer)) - { - if (peer.mPeerFlags & with_flag) - { - return 1; - } - } - /* XXX eventually we'll need to check against extra peer lists. - * with our friends, etc - * - * ideally we'll track this info in the query! - */ - - return 0; -} - - -void bdConnectManager::updatePotentialConnectionProxy(const bdId *id, uint32_t mode) -{ - if (mode & BITDHT_PEER_STATUS_DHT_ENGINE_VERSION) - { -#ifdef DEBUG_NODE_CONNECTION_EXTRA - std::cerr << "bdConnectManager::updatePotentialConnectionProxy() Peer is GOOD : "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; - std::cerr << "bdConnectManager::updatePotentialConnectionProxy() checking Connection Requests"; - std::cerr << std::endl; -#endif - /* good peer, see if any of our connectionrequests can use it */ - std::map::iterator it; - for(it = mConnectionRequests.begin(); it != mConnectionRequests.end(); it++) - { - it->second.checkGoodProxyPeer(id); - } - } -} - - -int bdConnectManager::tickConnections() -{ - iterateConnectionRequests(); - iterateConnections(); - - return 1; -} - - -void bdConnectManager::iterateConnectionRequests() -{ - time_t now = time(NULL); - - std::list eraseList; - std::list::iterator eit; - - std::map::iterator it; - for(it = mConnectionRequests.begin(); it != mConnectionRequests.end(); it++) - { - bool erase = false; - -#ifdef DEBUG_NODE_CONNECTION_EXTRA - std::cerr << "bdConnectManager::iterateConnectionAttempt() Request is:"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - - /* check status of connection */ - if (it->second.mState == BITDHT_CONNREQUEST_READY) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() Request is READY, starting"; - std::cerr << std::endl; -#endif - - /* kick off the connection if possible */ - // goes to BITDHT_CONNREQUEST_INPROGRESS; - if (!startConnectionAttempt(&(it->second))) - { -#ifdef DEBUG_NODE_CONNECTION - // FAILS if proxy is bad / nonexistent - std::cerr << "bdConnectManager::iterateConnectionAttempt() Failed startup => KILLED"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - - it->second.mErrCode = BITDHT_CONNECT_ERROR_SOURCE_START | - BITDHT_CONNECT_ERROR_OUTOFPROXY; - it->second.mState = BITDHT_CONNREQUEST_DONE; - it->second.mStateTS = now; - - } - } - else if (it->second.mState == BITDHT_CONNREQUEST_PAUSED) - { - /* forced pause, with period specified at PAUSE point */ - if (now > it->second.mPauseTS) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() PAUSED has reached timout -> READY"; - std::cerr << std::endl; -#endif - - /* if we have run out of proxies, or recycled too many times. kill it */ - if (it->second.mGoodProxies.size() == 0) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() no more proxies => DONE"; - std::cerr << std::endl; -#endif - - it->second.mErrCode = BITDHT_CONNECT_ERROR_SOURCE_START | - BITDHT_CONNECT_ERROR_OUTOFPROXY; - it->second.mState = BITDHT_CONNREQUEST_DONE; - it->second.mStateTS = now; - } - else if ((unsigned) it->second.mRecycled > it->second.mGoodProxies.size() * MAX_NUM_RETRIES) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() to many retries => DONE"; - std::cerr << std::endl; -#endif - - it->second.mErrCode = BITDHT_CONNECT_ERROR_SOURCE_START | - BITDHT_CONNECT_ERROR_TOOMANYRETRY; - it->second.mState = BITDHT_CONNREQUEST_DONE; - it->second.mStateTS = now; - } - else - { - /* timeout and restart */ - it->second.mState = BITDHT_CONNREQUEST_READY; - it->second.mStateTS = now; - } - } - } - else if (it->second.mState == BITDHT_CONNREQUEST_INPROGRESS) - { - /* single connection attempt */ - if (now - it->second.mStateTS > BITDHT_CONNREQUEST_TIMEOUT_INPROGRESS) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() INPROGRESS has reached timout -> READY"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - - /* timeout and restart */ - it->second.mState = BITDHT_CONNREQUEST_PAUSED; - it->second.mStateTS = now; - it->second.mPauseTS = now + BITDHT_CR_PAUSE_SHORT_PERIOD; - } - } - else if (it->second.mState == BITDHT_CONNREQUEST_EXTCONNECT) - { - /* connection completed, doing UDP connection */ - if (now - it->second.mStateTS > BITDHT_CONNREQUEST_TIMEOUT_CONNECT) - { - std::cerr << "bdConnectManager::iterateConnectionAttempt() ERROR EXTCONNECT has reached timout -> SHOULD NEVER HAPPEN... KILL this query:"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; - - /* timeout and restart */ - it->second.mErrCode = BITDHT_CONNECT_ERROR_SOURCE_START | - BITDHT_CONNECT_ERROR_PROTOCOL; - it->second.mState = BITDHT_CONNREQUEST_DONE; - it->second.mStateTS = now; - } - } - else if (it->second.mState == BITDHT_CONNREQUEST_DONE) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() DONE -> erase"; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - - erase = true; - - } - - // Cleanup - if (now - it->second.mStateTS > BITDHT_CONNREQUEST_MAX_AGE) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() Should clean Old ConnReq???: "; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - } - - if (erase) - { - /* do callback */ - bdId srcId; - bdId proxyId; - bdId destId; - - destId.id = it->second.mTarget; - int param = 0; - callbackConnect(&srcId, &proxyId, &destId, it->second.mMode, - BD_PROXY_CONNECTION_START_POINT, param, - BITDHT_CONNECT_CB_REQUEST, it->second.mErrCode); - - /* cleanup */ - eraseList.push_back(it->first); - } - } - - for(eit = eraseList.begin(); eit != eraseList.end(); eit++) - { - it = mConnectionRequests.find(*eit); - if (it != mConnectionRequests.end()) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::iterateConnectionAttempt() Erasing Old Connection Request: "; - std::cerr << std::endl; - std::cerr << it->second; - std::cerr << std::endl; -#endif - - mConnectionRequests.erase(it); - } - } -} - - - -int bdConnectManager::startConnectionAttempt(bdConnectionRequest *req) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectionAttempt() ConnReq: "; - std::cerr << std::endl; - std::cerr << *req; - std::cerr << std::endl; -#endif - - if (req->mGoodProxies.size() < 1) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectionAttempt() No Potential Proxies... delaying attempt"; - std::cerr << std::endl; -#endif - return 0; - } - - bdId proxyId; - bdId srcConnAddr; - bdId destConnAddr; - - int mode = req->mMode; - - /* calculate the delay... accounting for the time since the request */ - time_t now = time(NULL); - int timeElapsed = (now - req->mRequestTS); - int delay = req->mDelay - timeElapsed; - int absDelay = 0; - if (delay > 0) - { - absDelay = delay; - } -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectionAttempt() TimeSinceReq: " << timeElapsed << " Original Delay: " << req->mDelay; - std::cerr << " AbsDelay: " << absDelay; - std::cerr << std::endl; -#endif - - destConnAddr.id = req->mTarget; - bdsockaddr_clear(&(destConnAddr.addr)); - - srcConnAddr.id = mOwnId; - srcConnAddr.addr = req->mLocalAddr; - - bdProxyId pidset = req->mGoodProxies.front(); - proxyId = pidset.id; - req->mGoodProxies.pop_front(); - - req->mCurrentAttempt = proxyId; - req->mCurrentSrcType = pidset.srcType; - - //req->mPeersTried.push_back(proxyId); - - req->mState = BITDHT_CONNREQUEST_INPROGRESS; - req->mStateTS = time(NULL); - - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { - // ONE BUG I HAVE SEEN. - if (!(req->mTarget == proxyId.id)) - { - std::cerr << "bdConnectManager::startConnectionAttempt() ERROR Trying to use a Proxy for DIRECT"; - std::cerr << std::endl; - - return 0; - } - } - else - { - if (req->mTarget == proxyId.id) - { - std::cerr << "bdConnectManager::startConnectionAttempt() ERROR Trying connect direct for PROXY|RELAY"; - std::cerr << std::endl; - - return 0; - } - } - - - return startConnectionAttempt(&proxyId, &srcConnAddr, &destConnAddr, mode, absDelay); -} - - - -/************************************************************************************************************ -****************************************** Outgoing Triggers ************************************************ -************************************************************************************************************/ - -/************************************************************************************************************ -****************************************** Outgoing Triggers ************************************************ -************************************************************************************************************/ - -/************************************************************************************************************ -*************************************** Connection Requests Callback **************************************** -************************************************************************************************************/ - -/* Lots of Callbacks come through here... The Connection Request gets flagged, and the message - * get passed on up if necessary. - */ - -void bdConnectManager::callbackConnectRequest(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode) -{ - /* Check if we are the originator of the Connect Request. If so, then we do stuff to the CR. - */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "mode: " << mode; - std::cerr << " point: " << point; - std::cerr << " param: " << param; - std::cerr << " cbtype: " << cbtype; - std::cerr << " errcode: " << errcode; - std::cerr << std::endl; - - std::cerr << "\tsrcId: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << std::endl; - std::cerr << "\tproxyId: "; - bdStdPrintId(std::cerr, proxyId); - std::cerr << std::endl; - std::cerr << "\tdestId: "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; -#endif - - - if (point != BD_PROXY_CONNECTION_START_POINT) - { - /* ONLY ONE CASE THAT GOES HERE -> for sanity testing */ - if ((cbtype == BITDHT_CONNECT_CB_START) && (point == BD_PROXY_CONNECTION_END_POINT)) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() END & START checking ConnectRequest state"; - std::cerr << std::endl; -#endif - - // Reverse lookup (srcId). - std::map::iterator it = mConnectionRequests.find(srcId->id); - if (it != mConnectionRequests.end()) - { - if (it->second.mState == BITDHT_CONNREQUEST_INPROGRESS) - { - /* AT THIS POINT - WE SHOULD SWITCH IT INTO EXTCONNECT MODE????, - * which will timeout - if it fails... - * THIS is effectively the end of the connection attempt anyway. - * if UDP succeeds or fails, will Kill either way. - */ - std::cerr << "bdConnectManager::callbackConnectRequest() ERROR ALT CR also in progress!"; - std::cerr << std::endl; - - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() WARNING Switching ALT CR to EXTCONNECT Mode"; - std::cerr << std::endl; -#endif - - time_t now = time(NULL); - it->second.mState = BITDHT_CONNREQUEST_EXTCONNECT; - it->second.mStateTS = now; - - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() No ALT CR - Good"; - std::cerr << std::endl; -#endif - - } - callbackConnect(srcId, proxyId, destId, mode, point, param, cbtype, errcode); - return; - } - - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR point != START, should not be receiving this callback, ignoring"; - std::cerr << std::endl; - return; - } - - /* now find our peer in the map */ - std::map::iterator it = mConnectionRequests.find(destId->id); - if (it == mConnectionRequests.end()) - { - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR no associated Connection Request, ignoring"; - std::cerr << std::endl; - return; - } - bdConnectionRequest *cr = &(it->second); - time_t now = time(NULL); - - /* what types of cbtype can we get? - * BITDHT_CONNECT_CB_AUTH not as START - * BITDHT_CONNECT_CB_PENDING not as START - * BITDHT_CONNECT_CB_START YES important, change state to PAUSED and pass up - * BITDHT_CONNECT_CB_PROXY not as START - * BITDHT_CONNECT_CB_FAILED YES most important, trigger next one - */ - - switch(cbtype) - { - default: // all fallthrough. - case BITDHT_CONNECT_CB_AUTH: - case BITDHT_CONNECT_CB_PENDING: - case BITDHT_CONNECT_CB_PROXY: - { - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR unexpected CBTYPE: AUTH/PENDING/PROXY/other. ignoring"; - std::cerr << std::endl; - return; - } - - case BITDHT_CONNECT_CB_FAILED: - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "Connection FAILED.... determining if fatal/recycle/next"; - std::cerr << std::endl; -#endif - - // one more big switch statement, to decide: fatal/delay/or next - // default is move to next proxy/peer. - bool fatal = false; - bool recycle = false; - - int errtype = errcode & BITDHT_CONNECT_ERROR_MASK_TYPE; - int errsrc = errcode & BITDHT_CONNECT_ERROR_MASK_SOURCE; - - switch(errtype) - { - default: - // (These could be fatal or recycle cases... but really ERROR, try NEXT. - case BITDHT_CONNECT_ERROR_GENERIC: - case BITDHT_CONNECT_ERROR_PROTOCOL: - case BITDHT_CONNECT_ERROR_TIMEOUT: // SHould never receive. - { - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR unexpected errcode: " << errcode; - std::cerr << std::endl; - } - break; - - // FATAL ONES. - case BITDHT_CONNECT_ERROR_UNREACHABLE: // END has Unstable ExtAddr. ONLY(PROXYMODE,END) - { - if ((errsrc == BITDHT_CONNECT_ERROR_SOURCE_END) && - (mode == BITDHT_CONNECT_MODE_PROXY)) - { - // fatal. - fatal = true; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "END says UNREACHABLE. FATAL ;("; - std::cerr << std::endl; -#endif - } - else - { - // error. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR, UNREACHABLE, but !END"; - std::cerr << std::endl; - } - } - break; - case BITDHT_CONNECT_ERROR_AUTH_DENIED: // END won't accept conn END|PROXY, RELAY|PROXY - { - if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_END) - { - // fatal. - fatal = true; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "END says AUTH_DENIED, fatal"; - std::cerr << std::endl; -#endif - } - else if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_MID) - { - // next. (unlikely). -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "WARNING MID says AUTH_DENIED"; - std::cerr << std::endl; -#endif - } - else - { - // error. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR strange AUTH_DENIED"; - std::cerr << std::endl; - } - } - break; - case BITDHT_CONNECT_ERROR_UNSUPPORTED: // mode is unsupprted. fatal or next ANY/ANY - { - if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_END) - { - // fatal. - fatal = true; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "END says UNSUPPORTED, fatal"; - std::cerr << std::endl; -#endif - } - else if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_MID) - { - // next. -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "MID says UNSUPPORTED"; - std::cerr << std::endl; -#endif - - } - else - { - // error. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR strange UNSUPPORTED"; - std::cerr << std::endl; - - } - } - break; - - // RECYCLE PROXY - case BITDHT_CONNECT_ERROR_TEMPUNAVAIL: // only END | PROXY, no extAddress - { - if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_END) - { - fatal = true; - //recycle = true; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "END says TEMPUNAVAIL, fatal (retried at higher level)"; - std::cerr << std::endl; -#endif - } - else - { - // next. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR strange TEMPUNAVAIL"; - std::cerr << std::endl; - - } - } - break; - case BITDHT_CONNECT_ERROR_DUPLICATE: // similar attempt. delay/recycle (ANY/ANY) - { - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << " DUPLICATE, fatal"; - std::cerr << std::endl; -#endif - - fatal = true; - //recycle = true; - } - break; - case BITDHT_CONNECT_ERROR_OVERLOADED: // not more space. PROXY in RELAY mode. - { - if ((errsrc == BITDHT_CONNECT_ERROR_SOURCE_MID) && - (mode == BITDHT_CONNECT_MODE_RELAY)) - { - recycle = true; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "MID says OVERLOADED, recycle"; - std::cerr << std::endl; -#endif - - } - else - { - //ERROR. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR strange OVERLOADED"; - std::cerr << std::endl; - } - } - break; - - // NEXT PROXY. - case BITDHT_CONNECT_ERROR_NOADDRESS: //Proxy doesn't know peer MID/(RELAY|PROXY) - { - if (errsrc == BITDHT_CONNECT_ERROR_SOURCE_MID) - { - // could recycle? probably still won't work. -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "MID says NOADDRESS"; - std::cerr << std::endl; -#endif - } - else - { - //ERROR. - std::cerr << "bdConnectManager::callbackConnectRequest() "; - std::cerr << "ERROR strange NOADDRESS"; - std::cerr << std::endl; - } - } - break; - } // end of error code switch. - - // Now act on the decision. - if (fatal) - { - /* kill connection request, do callback */ - /* setup for next one */ - cr->mState = BITDHT_CONNREQUEST_DONE; - } - else - { - if (recycle) - { - /* rotate around */ - cr->mGoodProxies.push_back(bdProxyId(cr->mCurrentAttempt, cr->mCurrentSrcType, errcode)); - cr->mRecycled++; - } - else - { - cr->mPeersTried.push_back(bdProxyId(cr->mCurrentAttempt, cr->mCurrentSrcType, errcode)); - } - - /* setup for next one */ - cr->mState = BITDHT_CONNREQUEST_PAUSED; - cr->mPauseTS = now + BITDHT_CR_PAUSE_SHORT_PERIOD; - } - - cr->mStateTS = now; - cr->mErrCode = errcode; - - /* just pass on the callbackConnect() */ - callbackConnect(srcId, proxyId, destId, mode, point, param, cbtype, errcode); - - return; // CALLBACK FINISHED for FAILURE CODES. - - } - break; - case BITDHT_CONNECT_CB_START: - { - - cr->mState = BITDHT_CONNREQUEST_EXTCONNECT; - cr->mStateTS = now; - - callbackConnect(srcId, proxyId, destId, mode, point, param, cbtype, errcode); - - } - break; - } -} - - - -/************************************************************************************************************ -************************************** END of Connection Requests ******************************************* -************************************************************************************************************/ - -/************************************************************************************************************ -****************************************** Outgoing Triggers ************************************************ -************************************************************************************************************/ - -/*** Called by iterator. - * initiates the connection startup - * - * srcConnAddr must contain Own ID + Connection Port (DHT or TOU depending on Mode). - * - * For a DIRECT Connection: proxyId == destination Id, and mode == DIRECT. - * - * For RELAY | PROXY Connection: - * - * In all cases, destConnAddr doesn't need to contain a valid address. - */ - -int bdConnectManager::startConnectionAttempt(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectionAttempt()"; - std::cerr << std::endl; -#endif - - if (!(mConfigAllowedModes & mode)) - { - /* MODE not supported */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectionAttempt() ERROR Mode Not Supported"; - std::cerr << std::endl; -#endif - return 0; - } - - /* Check for existing Connection */ - bdConnection *conn = findExistingConnectionBySender(proxyId, srcConnAddr, destConnAddr); - if (conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectAttempt() ERROR EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return 0; - } - - - /* Switch the order of peers around to test for "opposite connections" */ - if (NULL != findSimilarConnection(&(destConnAddr->id), &(srcConnAddr->id))) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::startConnectAttempt() WARNING Found Similar Connection. returning 0"; - std::cerr << std::endl; -#endif - - return 0; - } - - - { - // DO A CALLBACK to TELL higher levels, we are starting a connection attempt. - int point = BD_PROXY_CONNECTION_START_POINT; - int cbtype = BITDHT_CONNECT_CB_REQUEST; - int errcode = 0; - int param = 0; - callbackConnect(srcConnAddr, proxyId, destConnAddr, mode, point, param, cbtype, errcode); - } - - /* INSTALL a NEW CONNECTION */ - // not offically playing by the rules, but it should work. - conn = newConnectionBySender(proxyId, srcConnAddr, destConnAddr); - - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { - /* proxy is the real peer address, destConnAddr has an invalid address */ - conn->ConnectionSetupDirect(proxyId, srcConnAddr); - } - else - { - conn->ConnectionSetup(proxyId, srcConnAddr, destConnAddr, mode, delay); - } - - - int msgtype = BITDHT_MSG_TYPE_CONNECT_REQUEST; - int status = BITDHT_CONNECT_ANSWER_OKAY; - mPub->send_connect_msg(&(conn->mProxyId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), conn->mMode, conn->mMaxDelay, status); - - return 1; -} - -/* This will be called in response to a callback. - * the callback could be with regard to: - * a Direct EndPoint. - * a Proxy Proxy, or an Proxy EndPoint. - * a Relay Proxy, or an Relay EndPoint. - * - * If we are going to store the minimal amount in the bdNode about connections, - * then the parameters must contain all the information: - * - * case 1: - * - */ - -void bdConnectManager::AuthConnectionOk(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int bandwidth, int delay) -{ - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk()"; - std::cerr << std::endl; -#endif - - /* Check for existing Connection */ - bdConnection *conn = findExistingConnection(&(srcId->id), &(proxyId->id), &(destId->id)); - if (!conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() ERROR NO EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return; - } - - /* we need to continue the connection */ - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { - if (conn->mState == BITDHT_CONNECTION_WAITING_AUTH) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() Direct Connection, in WAITING_AUTH state... Authorising Direct Connect"; - std::cerr << std::endl; -#endif - /* This pushes it into the START/ACK cycle, - * which handles messages elsewhere - */ - conn->AuthoriseDirectConnection(srcId, proxyId, destId, mode, loc); - } - else - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() ERROR Direct Connection, !WAITING_AUTH state... Ignoring"; - std::cerr << std::endl; -#endif - - } - return; - } - - if (loc == BD_PROXY_CONNECTION_END_POINT) - { - if (conn->mState == BITDHT_CONNECTION_WAITING_AUTH) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() Proxy End Connection, in WAITING_AUTH state... Authorising"; - std::cerr << std::endl; -#endif - /*** XXX MUST RECEIVE THE ADDRESS FROM DEST for connection */ - conn->AuthoriseEndConnection(srcId, proxyId, destId, mode, loc, delay); - - /* we respond to the proxy which will finalise connection */ - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - int status = BITDHT_CONNECT_ANSWER_OKAY; - mPub->send_connect_msg(&(conn->mProxyId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), conn->mMode, conn->mMaxDelay, status); - - return; - } - else - { - - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() ERROR Proxy End Connection, !WAITING_AUTH state... Ignoring"; - std::cerr << std::endl; -#endif - } - } - - if (conn->mState == BITDHT_CONNECTION_WAITING_AUTH) - { - /* otherwise we are the proxy (for either), pass on the request */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() Proxy Mid Connection, in WAITING_AUTH state... Authorising"; - std::cerr << std::endl; -#endif - - /* SEARCH for IP:Port of destination is done before AUTH */ - conn->AuthoriseProxyConnection(srcId, proxyId, destId, mode, loc, bandwidth); - - int msgtype = BITDHT_MSG_TYPE_CONNECT_REQUEST; - int status = BITDHT_CONNECT_ANSWER_OKAY; - int param = 0; - mPub->send_connect_msg(&(conn->mDestId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), conn->mMode, param, status); - } - else - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionOk() ERROR Proxy Mid Connection, !WAITING_AUTH state... Ignoring"; - std::cerr << std::endl; -#endif - } - - return; -} - - - - -void bdConnectManager::AuthConnectionNo(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int errCode) -{ - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionNo()"; - std::cerr << std::endl; -#endif - - /* Check for existing Connection */ - bdConnection *conn = findExistingConnection(&(srcId->id), &(proxyId->id), &(destId->id)); - if (!conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionNo() ERROR NO EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return; - } - - /* we need indicate failure of the connection */ - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - uint32_t status = createConnectionErrorCode(errCode, BITDHT_CONNECT_ERROR_AUTH_DENIED, conn->mPoint); - - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { - /* we respond to the proxy which will finalise connection */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionNo() Direct End Connection Cleaning up"; - std::cerr << std::endl; -#endif - mPub->send_connect_msg(&(conn->mSrcId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), mode, 0, status); - - cleanConnection(&(srcId->id), &(proxyId->id), &(destId->id)); - return; - } - - if (loc == BD_PROXY_CONNECTION_END_POINT) - { - /* we respond to the proxy which will finalise connection */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionNo() Proxy End Connection Cleaning up"; - std::cerr << std::endl; -#endif - mPub->send_connect_msg(&(conn->mProxyId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), mode, 0, status); - - cleanConnection(&(srcId->id), &(proxyId->id), &(destId->id)); - - return; - } - - /* otherwise we are the proxy (for either), reply FAIL */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::AuthConnectionNo() Proxy Mid Connection Cleaning up"; - std::cerr << std::endl; -#endif - mPub->send_connect_msg(&(conn->mSrcId), msgtype, - &(conn->mSrcConnAddr), &(conn->mDestConnAddr), mode, 0, status); - - cleanConnection(&(srcId->id), &(proxyId->id), &(destId->id)); - - return; -} - - - - - -void bdConnectManager::iterateConnections() -{ - std::map::iterator it; - std::list eraseList; - time_t now = time(NULL); - - for(it = mConnections.begin(); it != mConnections.end(); it++) - { - if (now - it->second.mLastEvent > BD_CONNECTION_MAX_TIMEOUT) - { - /* cleanup event */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnections() Connection Timed Out: " << (it->first); - std::cerr << std::endl; -#endif - eraseList.push_back(it->first); - continue; - } - - /* Can I add a Quick Kill for connections that just haven't worked? TODO */ - - if ((it->second.mState == BITDHT_CONNECTION_WAITING_ACK) && - (now - it->second.mLastStart > BD_CONNECTION_START_RETRY_PERIOD)) - { - if (it->second.mRetryCount > BD_CONNECTION_START_MAX_RETRY) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnections() Start/ACK cycle, Too many iterations: " << it->first; - std::cerr << std::endl; -#endif - /* connection failed! cleanup */ - if ((it->second.mMode != BITDHT_CONNECT_MODE_PROXY) || (!mConfigAutoProxy)) - { - uint32_t errCode = createConnectionErrorCode(0, - BITDHT_CONNECT_ERROR_TIMEOUT,it->second.mPoint); - int param = 0; - callbackConnect(&(it->second.mSrcId),&(it->second.mProxyId), - &(it->second.mDestId), it->second.mMode, it->second.mPoint, param, - BITDHT_CONNECT_CB_FAILED, errCode); - } - - /* add to erase list */ - eraseList.push_back(it->first); - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnections() Start/ACK cycle, Retransmitting START: " << it->first; - std::cerr << std::endl; -#endif - it->second.mLastStart = now; - it->second.mRetryCount++; - - int bandwidth = it->second.mBandwidth; - int delay = it->second.mMaxDelay; - time_t elapsedTime = (time(NULL) - it->second.mConnectionStartTS); - int remainingDelay = delay - elapsedTime; - if (remainingDelay < 0) - { - remainingDelay = 0; - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::iterateConnections() Start/ACK cycle: remaining Delay: " << remainingDelay; - std::cerr << std::endl; - std::cerr << "bdConnectManager::iterateConnections() Start/ACK cycle: Bandwidth: " << bandwidth; - std::cerr << std::endl; -#endif - - // Must calculate the correct delay's here!!!! - int delayOrBandwidth = remainingDelay; - if (it->second.mMode == BITDHT_CONNECT_MODE_RELAY) - { - delayOrBandwidth = bandwidth; - } - - if (!it->second.mSrcAck) - { - int msgtype = BITDHT_MSG_TYPE_CONNECT_START; - mPub->send_connect_msg(&(it->second.mSrcId), msgtype, - &(it->second.mSrcConnAddr), &(it->second.mDestConnAddr), - it->second.mMode, delayOrBandwidth, BITDHT_CONNECT_ANSWER_OKAY); - } - if (!it->second.mDestAck) - { - int msgtype = BITDHT_MSG_TYPE_CONNECT_START; - mPub->send_connect_msg(&(it->second.mDestId), msgtype, - &(it->second.mSrcConnAddr), &(it->second.mDestConnAddr), - it->second.mMode, delayOrBandwidth, BITDHT_CONNECT_ANSWER_OKAY); - } - } - } - } - - /* clean up */ - while(eraseList.size() > 0) - { - bdProxyTuple tuple = eraseList.front(); - eraseList.pop_front(); - - std::map::iterator eit = mConnections.find(tuple); - mConnections.erase(eit); - } -} - - - - -/************************************************************************************************************ -****************************************** Callback Functions ******************************************** -************************************************************************************************************/ - - -void bdConnectManager::callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode) -{ - /* This is overloaded at a higher level */ - mPub->callbackConnect(srcId, proxyId, destId, mode, point, param, cbtype, errcode); -} - - -/************************************************************************************************************ -************************************** ProxyTuple + Connection State **************************************** -************************************************************************************************************/ - -int operator<(const bdProxyTuple &a, const bdProxyTuple &b) -{ - if (a.srcId < b.srcId) - { - return 1; - } - - if (a.srcId == b.srcId) - { - if (a.proxyId < b.proxyId) - { - return 1; - } - else if (a.proxyId == b.proxyId) - { - if (a.destId < b.destId) - { - return 1; - } - } - } - return 0; -} - -int operator==(const bdProxyTuple &a, const bdProxyTuple &b) -{ - if ((a.srcId == b.srcId) && (a.proxyId == b.proxyId) && (a.destId == b.destId)) - { - return 1; - } - return 0; -} - -std::ostream &operator<<(std::ostream &out, const bdProxyTuple &t) -{ - out << "[---"; - bdStdPrintNodeId(out, &(t.srcId)); - out << "---"; - bdStdPrintNodeId(out, &(t.proxyId)); - out << "---"; - bdStdPrintNodeId(out, &(t.destId)); - out << "---]"; - - return out; -} - -bdConnection::bdConnection() -{ - /* DUMMY INITIALISATION FOR ALL DATA - DON"T THINK IT MATTERS - * But keeps Valgrind happy - */ - - /* Connection State, and TimeStamp of Update */ - mState = 0; - mLastEvent = 0; - // - ///* Addresses of Start/Proxy/End Nodes */ - //bdId mSrcId; - //bdId mDestId; - //bdId mProxyId; - // - ///* Where we are in the connection, - //* and what connection mode. - //*/ - mPoint = 0; - mMode = 0; - // - ///* must have ip:ports of connection ends (if proxied) */ - //bdId mSrcConnAddr; - //bdId mDestConnAddr; - // - mBandwidth = 0; - mMaxDelay = 0; - mConnectionStartTS = 0; - - // - ///* START/ACK Finishing ****/ - mLastStart = 0; /* timer for retries */ - mRetryCount = 0; /* retry counter */ - // - mSrcAck = false; - mDestAck = false; - // - //// Completion TS. - mCompletedTS = 0; -} - - /* heavy check, used to check for alternative connections, coming from other direction - * Caller must switch src/dest to use it properly (otherwise it'll find your connection!) - */ -bdConnection *bdConnectManager::findSimilarConnection(bdNodeId *srcId, bdNodeId *destId) -{ - std::map::iterator it; - for(it = mConnections.begin(); it != mConnections.end(); it++) - { - if ((it->first.srcId == *srcId) && (it->first.destId == *destId)) - { - /* found similar connection */ - return &(it->second); - } - } - return NULL; -} - -bdConnection *bdConnectManager::findExistingConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId) -{ - bdProxyTuple tuple(srcId, proxyId, destId); - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::findExistingConnection() Looking For: " << tuple << std::endl; -#endif - - std::map::iterator it = mConnections.find(tuple); - if (it == mConnections.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::findExistingConnection() Failed to Find: " << tuple << std::endl; -#endif - return NULL; - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::findExistingConnection() Found: " << tuple << std::endl; -#endif - return &(it->second); -} - -bdConnection *bdConnectManager::newConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId) -{ - bdProxyTuple tuple(srcId, proxyId, destId); - bdConnection conn; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::newConnection() Installing: " << tuple << std::endl; -#endif - - mConnections[tuple] = conn; - std::map::iterator it = mConnections.find(tuple); - if (it == mConnections.end()) - { - std::cerr << "bdConnectManager::newConnection() ERROR Installing: " << tuple << std::endl; - return NULL; - } - return &(it->second); -} - -int bdConnectManager::cleanConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId) -{ - bdProxyTuple tuple(srcId, proxyId, destId); - bdConnection conn; - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::cleanConnection() Removing: " << tuple << std::endl; -#endif - - std::map::iterator it = mConnections.find(tuple); - if (it == mConnections.end()) - { - std::cerr << "bdConnectManager::cleanConnection() ERROR Removing: " << tuple << std::endl; - return 0; - } - mConnections.erase(it); - - return 1; -} - - -int bdConnectManager::determinePosition(bdNodeId */*sender*/, bdNodeId *src, bdNodeId *dest) -{ - int pos = BD_PROXY_CONNECTION_UNKNOWN_POINT; - if (mOwnId == *src) - { - pos = BD_PROXY_CONNECTION_START_POINT; - } - else if (mOwnId == *dest) - { - pos = BD_PROXY_CONNECTION_END_POINT; - } - else - { - pos = BD_PROXY_CONNECTION_MID_POINT; - } - return pos; -} - -int bdConnectManager::determineProxyId(bdNodeId *sender, bdNodeId *src, bdNodeId *dest, bdNodeId *proxyId) -{ - int pos = determinePosition(sender, src, dest); - switch(pos) - { - case BD_PROXY_CONNECTION_START_POINT: - case BD_PROXY_CONNECTION_END_POINT: - *proxyId = *sender; - return 1; - break; - default: - case BD_PROXY_CONNECTION_MID_POINT: - *proxyId = mOwnId; - return 1; - break; - } - return 0; -} - - - -bdConnection *bdConnectManager::findExistingConnectionBySender(bdId *sender, bdId *src, bdId *dest) -{ - bdNodeId proxyId; - bdNodeId *senderId = &(sender->id); - bdNodeId *srcId = &(src->id); - bdNodeId *destId = &(dest->id); - determineProxyId(senderId, srcId, destId, &proxyId); - - return findExistingConnection(srcId, &proxyId, destId); -} - -bdConnection *bdConnectManager::newConnectionBySender(bdId *sender, bdId *src, bdId *dest) -{ - bdNodeId proxyId; - bdNodeId *senderId = &(sender->id); - bdNodeId *srcId = &(src->id); - bdNodeId *destId = &(dest->id); - determineProxyId(senderId, srcId, destId, &proxyId); - - return newConnection(srcId, &proxyId, destId); -} - - -int bdConnectManager::cleanConnectionBySender(bdId *sender, bdId *src, bdId *dest) -{ - bdNodeId proxyId; - bdNodeId *senderId = &(sender->id); - bdNodeId *srcId = &(src->id); - bdNodeId *destId = &(dest->id); - determineProxyId(senderId, srcId, destId, &proxyId); - - return cleanConnection(srcId, &proxyId, destId); -} - - -/************************************************************************************************************ -****************************************** Received Connect Msgs ******************************************** -************************************************************************************************************/ - - -/* This function is triggered by a CONNECT_REQUEST message. - * it will occur on both the Proxy/Dest in the case of a Proxy (PROXY | RELAY) and on the Dest (DIRECT) nodes. - * - * In all cases, we store the request and ask for authentication. - * - */ - - - -int bdConnectManager::recvedConnectionRequest(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest()"; - std::cerr << std::endl; -#endif - - if (!(mConfigAllowedModes & mode)) - { - /* MODE not supported */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING Mode Not Supported"; - std::cerr << std::endl; -#endif - /* reply existing connection */ - int pos = determinePosition(&(id->id), &(srcConnAddr->id), &(destConnAddr->id)); - uint32_t status = createConnectionErrorCode(0, BITDHT_CONNECT_ERROR_UNSUPPORTED, pos); - - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - mPub->send_connect_msg(id, msgtype, srcConnAddr, destConnAddr, mode, 0, status); - - return 0; - } - - /* Check for existing Connection */ - bdConnection *conn = findExistingConnectionBySender(id, srcConnAddr, destConnAddr); - if (conn) - { - /* Likely ERROR: Warning */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING Existing Connection: "; - std::cerr << std::endl; - std::cerr << std::endl; -#endif - /* reply existing connection */ - uint32_t status = createConnectionErrorCode(0, BITDHT_CONNECT_ERROR_DUPLICATE, conn->mPoint); - - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - int param = 0; - mPub->send_connect_msg(id, msgtype, srcConnAddr, destConnAddr, mode, param, status); - - return 0; - } - - - /* Switch the order of peers around to test for "opposite connections" */ - if (NULL != findSimilarConnection(&(destConnAddr->id), &(srcConnAddr->id))) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING Found Similar Connection. Replying NO"; - std::cerr << std::endl; -#endif - - /* reply existing connection */ - int pos = determinePosition(&(id->id), &(srcConnAddr->id), &(destConnAddr->id)); - uint32_t status = createConnectionErrorCode(0, BITDHT_CONNECT_ERROR_DUPLICATE, pos); - - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - int param = 0; - mPub->send_connect_msg(id, msgtype, srcConnAddr, destConnAddr, mode, param, status); - return 0; - } - - /* INSTALL a NEW CONNECTION */ - conn = bdConnectManager::newConnectionBySender(id, srcConnAddr, destConnAddr); - - int point = 0; - if (mode == BITDHT_CONNECT_MODE_DIRECT) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() Installing DIRECT CONNECTION"; - std::cerr << std::endl; -#endif - - /* we are actually the end node, store stuff, get auth and on with it! */ - point = BD_PROXY_CONNECTION_END_POINT; - - conn->ConnectionRequestDirect(id, srcConnAddr, destConnAddr); - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() Connection State:"; - std::cerr << std::endl; - std::cerr << *conn; - std::cerr << std::endl; -#endif - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_AUTH, - BITDHT_CONNECT_ERROR_NONE); - } - else - { - /* check if we are proxy, or end point */ - bool areProxy = (srcConnAddr->id == id->id); - if (areProxy) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() We are MID Point for Proxy / Relay Connection."; - std::cerr << std::endl; -#endif - - point = BD_PROXY_CONNECTION_MID_POINT; - - /* SEARCH for IP:Port of destination before AUTH */ - int numNodes = 10; - std::list matchingIds; - - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING searching for \"VERSION\" flag... TO FIX LATER"; - std::cerr << std::endl; - - uint32_t with_flag = BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; - //BITDHT_PEER_STATUS_DHT_APPL | BITDHT_PEER_STATUS_DHT_APPL_VERSION); - - bool proxyOk = false; - bdId destId; - - if (mNodeSpace->find_node(&(destConnAddr->id), numNodes, matchingIds, with_flag)) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() Found Suitable Destination Addr"; - std::cerr << std::endl; -#endif - - if (matchingIds.size() > 1) - { - /* WARNING multiple matches */ - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING Found Multiple Matching Destination Addr"; - std::cerr << std::endl; - } - - proxyOk = true; - destId = matchingIds.front(); - } - - if (proxyOk) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() Proxy Addr Ok: "; - bdStdPrintId(std::cerr, destConnAddr); - std::cerr << "asking for AUTH to continue"; - std::cerr << std::endl; -#endif - - conn->ConnectionRequestProxy(id, srcConnAddr, &mOwnId, &destId, mode, delay); - - /* ALLOW AUTO AUTH for MID Proxy Connections. */ - if ((mConfigAutoProxy) && (mode == BITDHT_CONNECT_MODE_PROXY)) - { - AuthConnectionOk(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, 0, 0); - } - else - { - - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_AUTH, - BITDHT_CONNECT_ERROR_NONE); - } - } - else - { - /* clean up connection... its not going to work */ -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() WARNING No Proxy Addr, Shutting Connect Attempt"; - std::cerr << std::endl; -#endif - - - /* send FAIL message to SRC */ - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - uint32_t status = createConnectionErrorCode(0, BITDHT_CONNECT_ERROR_NOADDRESS, point); - int param = 0; - mPub->send_connect_msg(id, msgtype, srcConnAddr, destConnAddr, mode, param, status); - - - /* WILL NEED CALLBACK FOR FAILED PROXY ATTEMPT - TO SUPPORT RELAYS PROPERLY - * NODE needs to know PEERS to potentially WHITELIST! - */ - if (mRelayMode == BITDHT_RELAYS_SERVER) - { -#ifdef DEBUG_PROXY_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() In RelayServer Mode, doing FAIL callbackConnect()"; - std::cerr << std::endl; -#endif - - bdId proxyId; - proxyId.id = mOwnId; - callbackConnect(srcConnAddr, &proxyId, destConnAddr, mode, point, param, BITDHT_CONNECT_CB_AUTH, - BITDHT_CONNECT_ERROR_NOADDRESS); - } - - /* remove connection */ - bdConnectManager::cleanConnectionBySender(id, srcConnAddr, destConnAddr); - } - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionRequest() END Proxy/Relay Connection, asking for AUTH to continue"; - std::cerr << std::endl; -#endif - - point = BD_PROXY_CONNECTION_END_POINT; - - conn->ConnectionRequestEnd(id, srcConnAddr, destConnAddr, mode); - - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_AUTH, - BITDHT_CONNECT_ERROR_NONE); - } - } - return 1; -} - - -/* This function is triggered by a CONNECT_REPLY message. - * it will occur on either the Proxy or Source. And indicates YES / NO to the connection, - * as well as supplying address info to the proxy. - * - */ - -int bdConnectManager::recvedConnectionReply(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay, int status) -{ - /* retrieve existing connection data */ - bdConnection *conn = findExistingConnectionBySender(id, srcConnAddr, destConnAddr); - if (!conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionReply() ERROR NO EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return 0; - } - - switch(conn->mPoint) - { - case BD_PROXY_CONNECTION_START_POINT: - case BD_PROXY_CONNECTION_END_POINT: /* NEVER EXPECT THIS */ - case BD_PROXY_CONNECTION_UNKNOWN_POINT: /* NEVER EXPECT THIS */ - default: /* NEVER EXPECT THIS */ - { - - - /* Only situation we expect this, is if the connection is not allowed. - * DEST has sent back an ERROR Message - */ - uint32_t errCode = BITDHT_CONNECT_ERROR_GENERIC; - if ((status != BITDHT_CONNECT_ANSWER_OKAY) && (conn->mPoint == BD_PROXY_CONNECTION_START_POINT)) - { - /* connection is killed */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionReply() WARNING Connection Rejected. Error: "; - std::cerr << decodeConnectionError(status); - std::cerr << ", Killing It: "; - std::cerr << std::endl; - std::cerr << *conn; - std::cerr << std::endl; -#endif - errCode = status; // Pass on the Error Message. - - } - else - { - /* ERROR in protocol */ - std::cerr << "bdConnectManager::recvedConnectionReply() ERROR Unexpected Message, Killing It: "; - std::cerr << std::endl; - std::cerr << *conn; - std::cerr << std::endl; - errCode = createConnectionErrorCode(0, BITDHT_CONNECT_ERROR_PROTOCOL, conn->mPoint ); - } - - /* do Callback for Failed Connection */ - if (conn->mPoint == BD_PROXY_CONNECTION_START_POINT) - { - /* As we started the connection, callback internally first! */ - int param = 0; - callbackConnectRequest(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_FAILED, errCode); - } - else - { - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_FAILED, errCode); - } - - /* Kill Connection always */ - cleanConnectionBySender(id, srcConnAddr, destConnAddr); - - return 0; - } - break; - - case BD_PROXY_CONNECTION_MID_POINT: - { - /* We are proxy. and OK / NOK for connection proceed. - */ - - if ((status == BITDHT_CONNECT_ANSWER_OKAY) && (conn->mState == BITDHT_CONNECTION_WAITING_REPLY)) - { - /* OK, continue connection! */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionReply() @MIDPOINT. Reply + State OK, continuing connection"; - std::cerr << std::endl; -#endif - - /* Upgrade Connection to Finishing Mode */ - conn->upgradeProxyConnectionToFinish(id, srcConnAddr, destConnAddr, mode, delay, status); - - /* do Callback for Pending Connection */ - /* DONT CALLBACK in AutoProxy Mode: (PROXY & mConfigAutoProxy) */ - if ((conn->mMode != BITDHT_CONNECT_MODE_PROXY) || (!mConfigAutoProxy)) - { - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_PENDING, - BITDHT_CONNECT_ERROR_NONE); - } - - return 1; - } - else - { - - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionReply() WARNING @MIDPOINT recved Error: "; - std::cerr << decodeConnectionError(status); - std::cerr << " Killing It: "; - std::cerr << std::endl; - std::cerr << *conn; - std::cerr << std::endl; -#endif - - uint32_t errCode = status; - if (errCode == BITDHT_CONNECT_ERROR_NONE) - { - errCode = createConnectionErrorCode(0, - BITDHT_CONNECT_ERROR_PROTOCOL, conn->mPoint ); - } - - /* do Callback for Failed Connection */ - /* DONT CALLBACK in AutoProxy Mode: (PROXY & mConfigAutoProxy) */ - if ((conn->mMode != BITDHT_CONNECT_MODE_PROXY) || (!mConfigAutoProxy)) - { - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_FAILED, errCode); - } - - - /* send on message to SRC */ - int msgtype = BITDHT_MSG_TYPE_CONNECT_REPLY; - int param = 0; - mPub->send_connect_msg(&(conn->mSrcId), msgtype, &(conn->mSrcConnAddr), &(conn->mDestConnAddr), mode, param, errCode); - - /* connection is killed */ - cleanConnectionBySender(id, srcConnAddr, destConnAddr); - } - return 0; - } - break; - } - return 0; -} - - -/* This function is triggered by a CONNECT_START message. - * it will occur on both the Src/Dest in the case of a Proxy (PROXY | RELAY) and on the Src (DIRECT) nodes. - * - * parameters are checked against pending connections. - * Acks are set, and connections completed if possible (including callback!). - */ - -int bdConnectManager::recvedConnectionStart(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delayOrBandwidth) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart()"; - std::cerr << std::endl; -#endif - - /* retrieve existing connection data */ - bdConnection *conn = findExistingConnectionBySender(id, srcConnAddr, destConnAddr); - if (!conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart() ERROR NO EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return 0; - } - - - if (conn->mPoint == BD_PROXY_CONNECTION_MID_POINT) - { - std::cerr << "bdConnectManager::recvedConnectionStart() ERROR We Are Connection MID Point"; - std::cerr << std::endl; - /* ERROR */ - } - - /* check state */ - if ((conn->mState != BITDHT_CONNECTION_WAITING_START) && (conn->mState != BITDHT_CONNECTION_COMPLETED)) - { - /* ERROR */ - std::cerr << "bdConnectManager::recvedConnectionStart() ERROR State != WAITING_START && != COMPLETED"; - std::cerr << std::endl; - - return 0; - } - - /* ALL Okay, Send ACK */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart() Passed basic tests, Okay to send ACK"; - std::cerr << std::endl; -#endif - - int msgtype = BITDHT_MSG_TYPE_CONNECT_ACK; - int status = BITDHT_CONNECT_ANSWER_OKAY; - mPub->send_connect_msg(id, msgtype, &(conn->mSrcId), &(conn->mDestId), mode, 0, status); - - /* do complete Callback */ - - /* flag as completed */ - if (conn->mState != BITDHT_CONNECTION_COMPLETED) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart() Switching State to COMPLETED, doing callback"; - std::cerr << std::endl; -#endif - - int param = delayOrBandwidth; - int bandwidth = 0; - int delay = 0; - if (conn->mMode == BITDHT_CONNECT_MODE_RELAY) - { - bandwidth = param; - } - else - { - delay = param; - } - - conn->CompleteConnection(id, srcConnAddr, destConnAddr, bandwidth, delay); - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart() Connection State: "; - std::cerr << *conn; - std::cerr << std::endl; -#endif - - - if (conn->mPoint == BD_PROXY_CONNECTION_START_POINT) - { - /* internal callback first */ - callbackConnectRequest(&(conn->mSrcConnAddr),&(conn->mProxyId),&(conn->mDestConnAddr), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_START, - BITDHT_CONNECT_ERROR_NONE); - - } - else - { - /* internal callback first */ - callbackConnectRequest(&(conn->mSrcConnAddr),&(conn->mProxyId),&(conn->mDestConnAddr), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_START, - BITDHT_CONNECT_ERROR_NONE); - } - - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionStart() Just sent duplicate ACK"; - std::cerr << std::endl; -#endif - } - /* don't delete, if ACK is lost, we want to be able to re-respond */ - - return 1; -} - - -/* This function is triggered by a CONNECT_ACK message. - * it will occur on both the Proxy (PROXY | RELAY) and on the Dest (DIRECT) nodes. - * - * parameters are checked against pending connections. - * Acks are set, and connections completed if possible (including callback!). - */ - -int bdConnectManager::recvedConnectionAck(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int /*mode*/) -{ - /* retrieve existing connection data */ - bdConnection *conn = findExistingConnectionBySender(id, srcConnAddr, destConnAddr); - if (!conn) - { - /* ERROR */ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionAck() ERROR NO EXISTING CONNECTION"; - std::cerr << std::endl; -#endif - return 0; - } - - if (conn->mPoint == BD_PROXY_CONNECTION_START_POINT) - { - /* ERROR */ - std::cerr << "bdConnectManager::recvedConnectionAck() ERROR ACK received at START POINT"; - std::cerr << std::endl; - - return 0; - } - - /* check state */ - if (conn->mState != BITDHT_CONNECTION_WAITING_ACK) - { - /* ERROR */ - std::cerr << "bdConnectManager::recvedConnectionAck() ERROR conn->mState != WAITING_ACK, actual State: " << conn->mState; - std::cerr << std::endl; - - return 0; - } - - if (id->id == srcConnAddr->id) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionAck() from Src, marking So"; - std::cerr << std::endl; -#endif - - /* recved Ack from source */ - conn->mSrcAck = true; - } - else if (id->id == destConnAddr->id) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionAck() from Dest, marking So"; - std::cerr << std::endl; -#endif - /* recved Ack from dest */ - conn->mDestAck = true; - } - - if (conn->mSrcAck && conn->mDestAck) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::recvedConnectionAck() ACKs from Both Src & Dest, Connection Complete: callback & cleanup"; - std::cerr << std::endl; -#endif - - /* connection complete! cleanup */ - if (conn->mMode == BITDHT_CONNECT_MODE_DIRECT) - { -// int mode = conn->mMode | BITDHT_CONNECT_ANSWER_OKAY; - /* callback to connect to Src address! */ - // Slightly different callback, use ConnAddr for start message! - // Also callback to ConnectionRequest first. - // ACTUALLY we are END, so shouldn't (AT This Point do this). - // MUST callback via ConnectRequest - to prevent duplicate REQUESTS. - int param = 0; - callbackConnectRequest(&(conn->mSrcConnAddr),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_START, - BITDHT_CONNECT_ERROR_NONE); - - } - else - { - /* DONT CALLBACK in AutoProxy Mode: (PROXY & mConfigAutoProxy) */ - if ((conn->mMode != BITDHT_CONNECT_MODE_PROXY) || (!mConfigAutoProxy)) - { - int param = 0; - callbackConnect(&(conn->mSrcId),&(conn->mProxyId),&(conn->mDestId), - conn->mMode, conn->mPoint, param, BITDHT_CONNECT_CB_PROXY, - BITDHT_CONNECT_ERROR_NONE); - } - - - } - - /* Finished Connection! */ - cleanConnectionBySender(id, srcConnAddr, destConnAddr); - } - return 1; -} - - - -/************************************************************************************************************ -********************************* Connection / ConnectionRequest Functions ********************************** -************************************************************************************************************/ - -// Initialise a new Connection (request by User) - -// Any Connection initialised at Source (START_POINT), prior to Auth. -int bdConnection::ConnectionSetup(bdId *proxyId, bdId *srcConnAddr, bdId *destId, int mode, int delay) -{ - mState = BITDHT_CONNECTION_WAITING_START; /* or REPLY, no AUTH required */ - mLastEvent = time(NULL); - mSrcId = *srcConnAddr; /* self, IP unknown */ - mDestId = *destId; /* dest, IP unknown */ - mProxyId = *proxyId; /* full proxy/dest address */ - - mPoint = BD_PROXY_CONNECTION_START_POINT; - mMode = mode; - - mSrcConnAddr = *srcConnAddr; /* self, full ID/IP */ - mDestConnAddr = *destId; /* IP unknown */ - - mBandwidth = 0; - mMaxDelay = delay; - mConnectionStartTS = time(NULL); - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::ConnectionSetup(): delay: " << mMaxDelay; - std::cerr << std::endl; -#endif - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mSrcId.addr)); - bdsockaddr_clear(&(mDestId.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - -int bdConnection::ConnectionSetupDirect(bdId *destId, bdId *srcConnAddr) -{ - mState = BITDHT_CONNECTION_WAITING_START; /* or REPLY, no AUTH required */ - mLastEvent = time(NULL); - mSrcId = *srcConnAddr; /* self, IP unknown */ - mDestId = *destId; /* full proxy/dest address */ - mProxyId = *destId; /* full proxy/dest address */ - - mPoint = BD_PROXY_CONNECTION_START_POINT; - mMode = BITDHT_CONNECT_MODE_DIRECT; - - mSrcConnAddr = *srcConnAddr; /* self, full ID/IP */ - mDestConnAddr = *destId; /* IP unknown */ - - mBandwidth = 0; - mMaxDelay = 0; - mConnectionStartTS = time(NULL); - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mSrcId.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - - - -// Initialise a new Connection. (receiving a Connection Request) -// Direct Connection initialised at Destination (END_POINT), prior to Auth. -int bdConnection::ConnectionRequestDirect(bdId *id, bdId *srcConnAddr, bdId *destId) -{ - mState = BITDHT_CONNECTION_WAITING_AUTH; - mLastEvent = time(NULL); - mSrcId = *id; /* peer ID/IP known */ - mDestId = *destId; /* self, IP unknown */ - mProxyId = *id; /* src ID/IP known */ - - mPoint = BD_PROXY_CONNECTION_END_POINT; - mMode = BITDHT_CONNECT_MODE_DIRECT; - - mSrcConnAddr = *srcConnAddr; /* connect address ID/IP known */ - mDestConnAddr = *destId; /* self IP unknown */ - - mBandwidth = 0; - mMaxDelay = 0; - mConnectionStartTS = time(NULL); - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mDestId.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - - -// Proxy Connection initialised at Proxy (MID_POINT), prior to Auth. -int bdConnection::ConnectionRequestProxy(bdId *id, bdId *srcConnAddr, bdNodeId *ownId, bdId *destId, int mode, int delay) -{ - mState = BITDHT_CONNECTION_WAITING_AUTH; - mLastEvent = time(NULL); - mSrcId = *id; /* ID/IP Known */ - mDestId = *destId; /* destination, ID/IP known */ - mProxyId.id = *ownId; /* own id, must be set for callback, IP Unknown */ - - mPoint = BD_PROXY_CONNECTION_MID_POINT; - mMode = mode; - - mSrcConnAddr = *srcConnAddr; - mDestConnAddr = *destId; /* other peer, IP unknown */ - - mBandwidth = 0; - mMaxDelay = delay; - mConnectionStartTS = time(NULL); - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::ConnectionRequestProxy(): received Initial delay: " << mMaxDelay; - std::cerr << std::endl; -#endif - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mProxyId.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - - -// Proxy Connection initialised at Destination (END_POINT), prior to Auth. -int bdConnection::ConnectionRequestEnd(bdId *id, bdId *srcId, bdId *destId, int mode) -{ - mState = BITDHT_CONNECTION_WAITING_AUTH; - mLastEvent = time(NULL); - mSrcId = *srcId; /* src IP unknown */ - mDestId = *destId; /* self, IP unknown */ - mProxyId = *id; /* src of message, full ID/IP of proxy */ - - mPoint = BD_PROXY_CONNECTION_END_POINT; - mMode = mode; - - mSrcConnAddr = *srcId; /* ID, not IP */ - mDestConnAddr = *destId; /* ID, not IP */ - - mBandwidth = 0; - mMaxDelay = 0; - mConnectionStartTS = time(NULL); - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mSrcId.addr)); - bdsockaddr_clear(&(mDestId.addr)); - bdsockaddr_clear(&(mSrcConnAddr.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - -// Received AUTH, step up to next stage. -// Search for dest ID/IP is done before AUTH. so actually nothing to do here, except set the state -int bdConnection::AuthoriseProxyConnection(bdId */*srcId*/, bdId */*proxyId*/, bdId */*destId*/, int /*mode*/, int /*loc*/, int bandwidth) -{ - mState = BITDHT_CONNECTION_WAITING_REPLY; - mLastEvent = time(NULL); - - //mSrcId, (peer) (ID/IP known) - //mDestId (other peer) (ID/IP known) - //mProxyId (self) (IP unknown) - - // mPoint, mMode should be okay. - - mBandwidth = bandwidth; - //mMaxDelay Already set. - //mConnectionStartTS Already Set - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::AuthoriseProxyConnection(): received Bandwidth Limitation: " << mBandwidth; - std::cerr << std::endl; -#endif - - // mSrcConnAddr (ID/IP known) - // mDestConnAddr is still pending. - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mProxyId.addr)); - bdsockaddr_clear(&(mDestConnAddr.addr)); - - /* don't bother with START/ACK parameters */ - - return 1; -} - - -/* we are end of a Proxy Connection */ -int bdConnection::AuthoriseEndConnection(bdId */*srcId*/, bdId */*proxyId*/, bdId *destConnAddr, int /*mode*/, int /*loc*/, int delay) -{ - mState = BITDHT_CONNECTION_WAITING_START; - mLastEvent = time(NULL); - - //mSrcId, (peer) should be okay. (IP unknown) - //mDestId (self) doesn't matter. (IP unknown) - //mProxyId (peer) should be okay. (ID/IP known) - - // mPoint, mMode should be okay. - - //mBandwidth not set by us. - time_t elapsedTime = (time(NULL) - mConnectionStartTS); - mMaxDelay = delay + elapsedTime; // relative to mConnectionStartTS. - //mConnectionStartTS // Already Set - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::AuthoriseEndConnection(): adjusting delay: " << delay << " by elapsedTime: " << elapsedTime; - std::cerr << " for MaxDelay: " << mMaxDelay; - std::cerr << std::endl; -#endif - - // mSrcConnAddr should be okay. (IP unknown) - // Install the correct destConnAddr. (just received) - mDestConnAddr = *destConnAddr; - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mSrcId.addr)); - bdsockaddr_clear(&(mDestId.addr)); - bdsockaddr_clear(&(mSrcConnAddr.addr)); - - - // Initialise the START/ACK Parameters. - mRetryCount = 0; - mLastStart = 0; - mSrcAck = false; - mDestAck = true; // Automatic ACK, as it is from us. - mCompletedTS = 0; - - return 1; -} - - - - -// Auth of the Direct Connection, means we move straight to WAITING_ACK mode. -int bdConnection::AuthoriseDirectConnection(bdId */*srcId*/, bdId */*proxyId*/, bdId *destConnAddr, int /*mode*/, int /*loc*/) -{ - mState = BITDHT_CONNECTION_WAITING_ACK; - mLastEvent = time(NULL); - - //mSrcId, (peer) should be okay. (ID/IP known) - //mDestId (self) doesn't matter. (IP Unknown) - //mProxyId (peer) should be okay. (ID/IP known) - - // mPoint, mMode should be okay. - - //mBandwidth doesn't matter - //mMaxDelay doesn't matter - //mConnectionStartTS // Already Set - - // mSrcConnAddr should be okay. (ID/IP known) - // Install the correct destConnAddr. (just received) - mDestConnAddr = *destConnAddr; - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mDestId.addr)); - - // Should we check for these? This will not help for the Dest address, as we just blanked it above! */ - checkForDefaultConnectAddress(); - - // Initialise the START/ACK Parameters. - mRetryCount = 0; - mLastStart = 0; - mSrcAck = false; - mDestAck = true; // Automatic ACK, as it is from us. - mCompletedTS = 0; - - return 1; -} - -// Proxy Connection => at Proxy, Ready to send out Start and get back ACKs!! -int bdConnection::upgradeProxyConnectionToFinish(bdId */*id*/, bdId */*srcConnAddr*/, bdId *destConnAddr, int /*mode*/, int secondDelay, int /*status*/) -{ - mState = BITDHT_CONNECTION_WAITING_ACK; - mLastEvent = time(NULL); - - //mSrcId,mDestId should be okay. (ID/IP okay) - //mProxyId, not set, doesn't matter. (IP Unknown) - - // mPoint, mMode should be okay. - - //mBandwidth already set. - time_t elapsedTime = (time(NULL) - mConnectionStartTS); - int remainingDelayOne = mMaxDelay - elapsedTime; - if (secondDelay > remainingDelayOne) - { - /* maxDelay provided by Peer 2.... update calculations */ - mMaxDelay = secondDelay + elapsedTime; // relative to mConnectionStartTS. - } - //mConnectionStartTS // Already Set - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::upgradeProxyConnectionToFinish(): elapsedTime: " << elapsedTime << " remainingDelayOne: "; - std::cerr << remainingDelayOne << " secondDelay: " << secondDelay << " => maxDelay: " << mMaxDelay; - std::cerr << std::endl; -#endif - - - if ((secondDelay > 100 || mMaxDelay > 100) || (mBandwidth > 1050)) - { - std::cerr << "bdConnection::upgradeProxyConnectionToFinish(): ERROR Bandwidth or Delay rather large"; - std::cerr << std::endl; - } -#ifdef DEBUG_CONNECTION_DELAY -#endif - - - // mSrcConnAddr should be okay. (ID/IP known) - // Install the correct destConnAddr. (just received) - mDestConnAddr = *destConnAddr; - - /* clear IP Addresses to enforce this */ - bdsockaddr_clear(&(mProxyId.addr)); - - checkForDefaultConnectAddress(); - - // Initialise the START/ACK Parameters. - mRetryCount = 0; - mLastStart = 0; - mSrcAck = false; - mDestAck = false; - mCompletedTS = 0; - - return 1; -} - - -// Final Sorting out of Addresses. -// This is called at the Connection Ends, on receiving the START message. -// This will contain either Bandwidth or Delay. -int bdConnection::CompleteConnection(bdId */*id*/, bdId *srcConnAddr, bdId *destConnAddr, int bandwidth, int delay) -{ - /* Store Final Addresses */ - time_t now = time(NULL); - - mState = BITDHT_CONNECTION_COMPLETED; - mCompletedTS = now; - mLastEvent = now; - - mBandwidth = bandwidth; // Received from the Proxy (in the case of a Relay). - time_t elapsedTime = (time(NULL) - mConnectionStartTS); - int remainingOrigDelay = mMaxDelay - elapsedTime; - if (delay > remainingOrigDelay) - { - /* maxDelay provided by Peer 2.... update calculations */ - mMaxDelay = delay + elapsedTime; // relative to mConnectionStartTS. - } - - - if ((delay > 100 || mMaxDelay > 100) || (mBandwidth > 1050)) - { - std::cerr << "bdConnection::CompleteConnection(): ERROR Bandwidth or Delay rather large"; - std::cerr << std::endl; - } -#ifdef DEBUG_CONNECTION_DELAY -#endif - -#ifdef DEBUG_CONNECTION_DELAY - std::cerr << "bdConnection::CompleteConnection(): Bandwidth: " << mBandwidth; - std::cerr << std::endl; - std::cerr << "bdConnection::CompleteConnection(): elapsedTime: " << elapsedTime << " remainingOrigDelay: "; - std::cerr << remainingOrigDelay << " newDelay: " << delay << " => maxDelay: " << mMaxDelay; - std::cerr << std::endl; -#endif - - if (delay < remainingOrigDelay) - { - // ERROR - std::cerr << "bdConnection::CompleteConnection(): ERROR delay: " << delay << " is smaller than remainingOrigDelay: "; - std::cerr << remainingOrigDelay; - std::cerr << std::endl; - } - - // Received Definitive Final Addresses from Proxy. - // These have to be done by proxy, as its the only one who know both our addresses. - - mSrcConnAddr = *srcConnAddr; - mDestConnAddr = *destConnAddr; - - checkForDefaultConnectAddress(); - - return 1; -} - - - -int bdConnection::checkForDefaultConnectAddress() -{ - // We can check if the DestConnAddr / SrcConnAddr are real. - // If there is nothing there, we assume that that want to connect on the - // same IP:Port as the DHT Node. - - if (mSrcConnAddr.addr.sin_addr.s_addr == 0) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::checkForDefaultConnectAddress() SrcConnAddr.addr is BLANK, installing Dht Node Address"; - std::cerr << std::endl; -#endif - - mSrcConnAddr.addr = mSrcId.addr; - } - - if (mDestConnAddr.addr.sin_addr.s_addr == 0) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectManager::checkForDefaultConnectAddress() DestConnAddr.addr is BLANK, installing Dht Node Address"; - std::cerr << std::endl; -#endif - - mDestConnAddr.addr = mDestId.addr; - } - - return 1; - -} - - -int bdConnectionRequest::setupDirectConnection(struct sockaddr_in *laddr, bdNodeId *target) -{ - mState = BITDHT_CONNREQUEST_READY; - mStateTS = time(NULL); - mPauseTS = 0; - mTarget = *target; - mLocalAddr = *laddr; - mMode = BITDHT_CONNECT_MODE_DIRECT; - mRecycled = 0; - mErrCode = 0; - - mDelay = 0; - mRequestTS = time(NULL); - - return 1; -} - -int bdConnectionRequest::setupProxyConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay) -{ - mState = BITDHT_CONNREQUEST_READY; - mStateTS = time(NULL); - mPauseTS = 0; - mTarget = *target; - mLocalAddr = *laddr; - mMode = mode; - mRecycled = 0; - mErrCode = 0; - - mDelay = delay; - mRequestTS = time(NULL); - - return 1; -} - -/* this is a good proxy peer (with flags already checked). - * if it is in the potential proxy list, then we can add it into the good proxy list. - */ - -int bdConnectionRequest::checkGoodProxyPeer(const bdId *id) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::checkProxyPeer() "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - std::list::iterator it = std::find(mPotentialProxies.begin(), mPotentialProxies.end(), *id); - if (it != mPotentialProxies.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::checkProxyPeer() Found in PotentialProxies List, adding in"; - std::cerr << std::endl; -#endif - - it = mPotentialProxies.erase(it); - - /* now add it in */ - addGoodProxy(id); - } - return 1; -} - - -int bdConnectionRequest::addGoodProxy(const bdId *srcId) -{ -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() "; - bdStdPrintId(std::cerr, srcId); - std::cerr << std::endl; -#endif - - if (*srcId == mCurrentAttempt) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() Duplicate with CurrentAttempt"; - std::cerr << std::endl; -#endif - return 0; - } - - std::list::iterator it; - for(it = mPeersTried.begin(); it != mPeersTried.end(); it++) - { - if (*srcId == it->id) - break; - } - - if (it == mPeersTried.end()) - { - for(it = mGoodProxies.begin(); it != mGoodProxies.end(); it++) - { - if (*srcId == it->id) - break; - } - - if (it == mGoodProxies.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() CRINITSTATE Found New Proxy: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << std::endl; -#endif - - mGoodProxies.push_back(bdProxyId(*srcId, BD_PI_SRC_ADDGOODPROXY, 0)); - - /* if it is potentialProxies then remove */ - std::list::iterator pit; - pit = std::find(mPotentialProxies.begin(), mPotentialProxies.end(), *srcId); - if (pit != mPotentialProxies.end()) - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() Removing from PotentialProxy List"; - std::cerr << std::endl; -#endif - - pit = mPotentialProxies.erase(pit); - } - return 1; - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() Duplicate in mPotentialProxies List"; - std::cerr << std::endl; -#endif - } - } - else - { -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdConnectionRequest::addGoodProxy() Already tried this peer"; - std::cerr << std::endl; -#endif - } - return 0; -} - - -std::ostream &operator<<(std::ostream &out, const bdConnectionRequest &req) -{ - time_t now = time(NULL); - out << "bdConnectionRequest: "; - out << "State: " << req.mState; - out << " StateTS: " << now - req.mStateTS; - out << " Recycled: " << req.mRecycled; - out << std::endl; - out << "\tTargetId: "; - bdStdPrintNodeId(out, &(req.mTarget)); - out << std::endl; - out << "\tMode: " << req.mMode; - out << std::endl; - out << "\tDelay: " << req.mDelay; - out << " RequestTS: " << now - req.mRequestTS; - out << std::endl; - - out << "CurrentAttempt:"; - bdStdPrintId(out, &(req.mCurrentAttempt)); - out << std::endl; - - out << "GoodProxies:"; - out << std::endl; - - std::list::const_iterator it; - std::list::const_iterator pit; - for(it = req.mGoodProxies.begin(); it != req.mGoodProxies.end(); it++) - { - out << "\t"; - bdStdPrintId(out, &(it->id)); - out << ", " << it->proxySrcType(); - out << ", " << decodeConnectionError(it->errcode); - out << std::endl; - } - - out << "PotentialProxies:"; - out << std::endl; - - for(pit = req.mPotentialProxies.begin(); pit != req.mPotentialProxies.end(); pit++) - { - out << "\t"; - bdStdPrintId(out, &(*pit)); - out << std::endl; - } - - out << "PeersTried:"; - out << std::endl; - - for(it = req.mPeersTried.begin(); it != req.mPeersTried.end(); it++) - { - out << "\t"; - bdStdPrintId(out, &(it->id)); - out << ", " << it->proxySrcType(); - out << ", " << decodeConnectionError(it->errcode); - out << std::endl; - } - return out; -} - -std::ostream &operator<<(std::ostream &out, const bdConnection &conn) -{ - time_t now = time(NULL); - out << "bdConnection: "; - out << "State: " << conn.mState; - out << " LastEvent: " << now - conn.mLastEvent; - out << " Point: " << conn.mPoint; - out << " Mode: " << conn.mMode; - out << std::endl; - - out << "\tsrcId: "; - bdStdPrintId(out, &(conn.mSrcId)); - out << std::endl; - out << "\tproxyId: "; - bdStdPrintId(out, &(conn.mProxyId)); - out << std::endl; - out << "\tdestId: "; - bdStdPrintId(out, &(conn.mDestId)); - out << std::endl; - - out << "\tsrcConnAddr: "; - bdStdPrintId(out, &(conn.mSrcConnAddr)); - out << std::endl; - - out << "\tdestConnAddr: "; - bdStdPrintId(out, &(conn.mDestConnAddr)); - out << std::endl; - - out << "\tretryCount: " << conn.mRetryCount; - out << " retryCount: " << conn.mLastStart; - out << " srcAck: " << conn.mSrcAck; - out << " destAck: " << conn.mDestAck; - out << " completedTS: " << now - conn.mCompletedTS; - - out << "\tBandwidth: " << conn.mBandwidth; - out << " maxDelay: " << conn.mMaxDelay; - out << " startTS: " << now - conn.mConnectionStartTS; - - out << std::endl; - - return out; - -} - - -uint32_t createConnectionErrorCode(uint32_t userProvided, uint32_t fallback, uint32_t point) -{ - int status = userProvided & BITDHT_CONNECT_ERROR_MASK_TYPE; - if (status == BITDHT_CONNECT_ERROR_NONE) - { - status = fallback; - } - /* backup, backup. */ - if (status == BITDHT_CONNECT_ERROR_NONE) - { - status = BITDHT_CONNECT_ERROR_GENERIC; /* FALLBACK ERROR CODE */ - } - - switch(point) - { - case BD_PROXY_CONNECTION_START_POINT: - status |= BITDHT_CONNECT_ERROR_SOURCE_START; - break; - case BD_PROXY_CONNECTION_MID_POINT: - status |= BITDHT_CONNECT_ERROR_SOURCE_MID; - break; - case BD_PROXY_CONNECTION_END_POINT: - status |= BITDHT_CONNECT_ERROR_SOURCE_END; - break; - } - - return status; -} - - - -std::string decodeConnectionErrorType(uint32_t errcode) -{ - uint32_t errtype = errcode & BITDHT_CONNECT_ERROR_MASK_TYPE; - std::string namedtype = "UNKNOWN"; - switch(errtype) - { - default: - bd_sprintf_append(namedtype, "(%lu)", errtype); - break; - case BITDHT_CONNECT_ERROR_GENERIC: - namedtype = "GENERIC"; - break; - case BITDHT_CONNECT_ERROR_PROTOCOL: - namedtype = "PROTOCOL"; - break; - case BITDHT_CONNECT_ERROR_TIMEOUT: - namedtype = "TIMEOUT"; - break; - case BITDHT_CONNECT_ERROR_TEMPUNAVAIL: - namedtype = "TEMPUNAVAIL"; - break; - case BITDHT_CONNECT_ERROR_NOADDRESS: - namedtype = "NOADDRESS"; - break; - case BITDHT_CONNECT_ERROR_UNREACHABLE: - namedtype = "UNREACHABLE"; - break; - case BITDHT_CONNECT_ERROR_UNSUPPORTED: - namedtype = "UNSUPPORTED"; - break; - case BITDHT_CONNECT_ERROR_OVERLOADED: - namedtype = "OVERLOADED"; - break; - case BITDHT_CONNECT_ERROR_AUTH_DENIED: - namedtype = "AUTH_DENIED"; - break; - case BITDHT_CONNECT_ERROR_DUPLICATE: - namedtype = "DUPLICATE"; - break; - case BITDHT_CONNECT_ERROR_TOOMANYRETRY: - namedtype = "TOOMANYRETRY"; - break; - case BITDHT_CONNECT_ERROR_OUTOFPROXY: - namedtype = "OUTOFPROXY"; - break; - case BITDHT_CONNECT_ERROR_USER: - namedtype = "USER DEFINED"; - break; - } - return namedtype; -} - - -std::string decodeConnectionErrorSource(uint32_t errcode) -{ - uint32_t errsrc = errcode & BITDHT_CONNECT_ERROR_MASK_SOURCE; - std::string namedtype = "ERROR SRC UNKNOWN"; - switch(errsrc) - { - default: - bd_sprintf_append(namedtype, "(%lu)", errsrc); - break; - case BITDHT_CONNECT_ERROR_SOURCE_START: - namedtype = "START"; - break; - case BITDHT_CONNECT_ERROR_SOURCE_MID: - namedtype = "MID"; - break; - case BITDHT_CONNECT_ERROR_SOURCE_END: - namedtype = "END"; - break; - case BITDHT_CONNECT_ERROR_SOURCE_OTHER: - namedtype = "OTHER"; - break; - } - return namedtype; -} - - -#if 0 -std::string decodeConnectionErrorCRMove(uint32_t errcode) -{ - uint32_t errcr = errcode & BITDHT_CONNECT_ERROR_MASK_CRMOVE; - std::string namedtype = "UNKNOWN"; - switch(errcr) - { - default: - break; - case 0: - namedtype = "REMOTE"; - break; - case BITDHT_CONNECT_ERROR_CRMOVE_FATAL: - namedtype = "FATAL"; - break; - case BITDHT_CONNECT_ERROR_SOURCE_NOMOREIDS: - namedtype = "NOMOREIDS"; - break; - case BITDHT_CONNECT_ERROR_SOURCE_NEXTID: - namedtype = "NEXTID"; - break; - case BITDHT_CONNECT_ERROR_CRMOVE_PAUSED: - namedtype = "PAUSED"; - break; - } - return namedtype; -} -#endif - - - -std::string decodeConnectionError(uint32_t errcode) -{ - std::string totalerror; - if (!errcode) - { - totalerror = "NoError"; - } - else - { - //totalerror = decodeConnectionErrorCRMove(errcode); - //totalerror += ":"; - totalerror = decodeConnectionErrorSource(errcode); - totalerror += ":"; - totalerror += decodeConnectionErrorType(errcode); - } - - return totalerror; -} - -std::string bdProxyId::proxySrcType() const -{ - std::string str("Unknown"); - - switch (srcType) { - case BD_PI_SRC_QUERYRESULT: - str = "QueryResult"; - break; - case BD_PI_SRC_QUERYPROXY: - str = "QueryProxy"; - break; - case BD_PI_SRC_NODESPACE_FRIEND: - str = "NodeSpaceFriend"; - break; - case BD_PI_SRC_NODESPACE_SERVER: - str = "NodeSpaceServer"; - break; - case BD_PI_SRC_NODESPACE_ENGINEVERSION: - str = "NodeSpaceEngineVersion"; - break; - case BD_PI_SRC_ADDGOODPROXY: - str = "AddGoodProxy"; - break; - case BD_PI_SRC_UNKNOWN: - default: - break; - } - return str; -} - diff --git a/libbitdht/src/bitdht/bdconnection.h b/libbitdht/src/bitdht/bdconnection.h deleted file mode 100644 index c55d95c09..000000000 --- a/libbitdht/src/bitdht/bdconnection.h +++ /dev/null @@ -1,314 +0,0 @@ -/******************************************************************************* - * bitdht/bdconnection.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_CONNECTION_H -#define BITDHT_CONNECTION_H - -#include "bitdht/bdiface.h" - -class bdQueryManager; -class bdNodePublisher; - -/************************************************************************************************************ -************************************** ProxyTuple + Connection State **************************************** -************************************************************************************************************/ - -#define BITDHT_CONNREQUEST_READY 1 -#define BITDHT_CONNREQUEST_PAUSED 2 -#define BITDHT_CONNREQUEST_INPROGRESS 3 -#define BITDHT_CONNREQUEST_EXTCONNECT 4 -#define BITDHT_CONNREQUEST_DONE 5 - -#define BITDHT_CONNREQUEST_TIMEOUT_CONNECT 300 // MAKE THIS LARGE - SHOULD NEVER HAPPEN. -#define BITDHT_CONNREQUEST_TIMEOUT_INPROGRESS 30 -#define BITDHT_CONNREQUEST_MAX_AGE 60 - - -#define BITDHT_CONNECTION_WAITING_AUTH 1 -#define BITDHT_CONNECTION_WAITING_REPLY 2 -#define BITDHT_CONNECTION_WAITING_START 3 -#define BITDHT_CONNECTION_WAITING_ACK 4 -#define BITDHT_CONNECTION_COMPLETED 5 - - -#define BD_CONNECTION_START_RETRY_PERIOD 3 // Should only take a couple of seconds to get reply. -#define BD_CONNECTION_START_MAX_RETRY 3 -#define BD_CONNECTION_MAX_TIMEOUT 20 /* should be quick */ - - - -class bdProxyTuple -{ - public: - bdProxyTuple() { return; } - bdProxyTuple(bdNodeId *s, bdNodeId *p, bdNodeId *d) - :srcId(*s), proxyId(*p), destId(*d) { return; } - - bdNodeId srcId; - bdNodeId proxyId; - bdNodeId destId; -}; - -std::ostream &operator<<(std::ostream &out, const bdProxyTuple &t); -int operator<(const bdProxyTuple &a, const bdProxyTuple &b); -int operator==(const bdProxyTuple &a, const bdProxyTuple &b); - - -class bdConnection -{ - public: - bdConnection(); - - /** Functions to tweak the connection status */ - - // User initialised Connection. - int ConnectionSetup(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay); - int ConnectionSetupDirect(bdId *destId, bdId *srcConnAddr); - - // Initialise a new Connection. (receiving a Connection Request) - int ConnectionRequestDirect(bdId *id, bdId *srcConnAddr, bdId *destConnAddr); - int ConnectionRequestProxy(bdId *id, bdId *srcConnAddr, bdNodeId *ownId, bdId *destConnAddr, int mode, int delay); - int ConnectionRequestEnd(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode); - - // Setup Finishing Stage, (receiving a Connection Reply). - int upgradeProxyConnectionToFinish(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay, int status); - - int AuthoriseDirectConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc); - int AuthoriseProxyConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int bandwidth); - int AuthoriseEndConnection(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int delay); - - int CompleteConnection(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int bandwidth, int delay); - - int checkForDefaultConnectAddress(); - - /* Connection State, and TimeStamp of Update */ - int mState; - time_t mLastEvent; - - /* Addresses of Start/Proxy/End Nodes */ - bdId mSrcId; - bdId mDestId; - bdId mProxyId; - - /* Where we are in the connection, - * and what connection mode. - */ - int mPoint; - int mMode; - - /* must have ip:ports of connection ends (if proxied) */ - bdId mSrcConnAddr; - bdId mDestConnAddr; - - int mBandwidth; - int mMaxDelay; - time_t mConnectionStartTS; - - /* START/ACK Finishing ****/ - time_t mLastStart; /* timer for retries */ - int mRetryCount; /* retry counter */ - - bool mSrcAck; - bool mDestAck; - - // Completion TS. - time_t mCompletedTS; - - -}; - -#define BD_PI_SRC_UNKNOWN 0 -#define BD_PI_SRC_QUERYRESULT 1 -#define BD_PI_SRC_QUERYPROXY 2 -#define BD_PI_SRC_NODESPACE_FRIEND 3 -#define BD_PI_SRC_NODESPACE_SERVER 4 -#define BD_PI_SRC_NODESPACE_ENGINEVERSION 5 -#define BD_PI_SRC_ADDGOODPROXY 6 - - -class bdProxyId -{ -public: - bdProxyId(const bdId &in_id, uint32_t in_srctype, uint32_t in_errcode) - :id(in_id), srcType(in_srctype), errcode(in_errcode) { return; } - - bdProxyId() :srcType(BD_PI_SRC_UNKNOWN), errcode(0) { return; } - - std::string proxySrcType() const; - - bdId id; - uint32_t srcType; - uint32_t errcode; -}; - - -class bdConnectionRequest -{ -public: - bdConnectionRequest() : mMode(0), mState(0), mStateTS(0), mPauseTS(0), mErrCode(0), mDelay(0), mRequestTS(0), mRecycled(0), mCurrentSrcType(0) - { - bdsockaddr_clear(&mLocalAddr); - } - -public: - int setupDirectConnection(struct sockaddr_in *laddr, bdNodeId *target); - int setupProxyConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay); - - int addGoodProxy(const bdId *srcId); - int checkGoodProxyPeer(const bdId *Id); - - bdNodeId mTarget; - struct sockaddr_in mLocalAddr; - int mMode; - - int mState; - time_t mStateTS; - - time_t mPauseTS; - uint32_t mErrCode; - - int mDelay; - time_t mRequestTS; // reference Time for mDelay. - - std::list mGoodProxies; - std::list mPotentialProxies; - //std::list mGoodProxies; - int mRecycled; - - bdId mCurrentAttempt; - uint32_t mCurrentSrcType; - - std::list mPeersTried; - //std::list mPeersTried; -}; - -std::ostream &operator<<(std::ostream &out, const bdConnectionRequest &req); -std::ostream &operator<<(std::ostream &out, const bdConnection &conn); - - -/********* - * The Connection Management Class. - * this encapsulates all of the functionality.. - * except for a couple of message in/outs + callback. - */ - -class bdConnectManager -{ - public: - - bdConnectManager(bdNodeId *ownid, bdSpace *space, bdQueryManager *qmgr, bdDhtFunctions *fns, bdNodePublisher *pub); - - - /* connection functions */ - void requestConnection(bdNodeId *id, uint32_t modes); - void allowConnection(bdNodeId *id, uint32_t modes); - - - /* high level */ - - void shutdownConnections(); - void printConnections(); - - /* Connections: Configuration */ - void defaultConnectionOptions(); - virtual void setConnectionOptions(uint32_t allowedModes, uint32_t flags); - - /* Connections: Initiation */ - - int requestConnection(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start); - int requestConnection_direct(struct sockaddr_in *laddr, bdNodeId *target); - int requestConnection_proxy(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay); - - int killConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode); - - int checkExistingConnectionAttempt(bdNodeId *target); - void addPotentialConnectionProxy(const bdId *srcId, const bdId *target); - void updatePotentialConnectionProxy(const bdId *id, uint32_t mode); - - int checkPeerForFlag(const bdId *id, uint32_t with_flag); - - int tickConnections(); - void iterateConnectionRequests(); - int startConnectionAttempt(bdConnectionRequest *req); - - // internal Callback -> normally continues to callbackConnect(). - void callbackConnectRequest(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode); - - /* Connections: Outgoing */ - - int startConnectionAttempt(bdId *proxyId, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay); - void AuthConnectionOk(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int bandwidth, int delay); - void AuthConnectionNo(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int loc, int errcode); - void iterateConnections(); - - - /* Connections: Utility State */ - - bdConnection *findExistingConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId); - bdConnection *newConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId); - int cleanConnection(bdNodeId *srcId, bdNodeId *proxyId, bdNodeId *destId); - - int determinePosition(bdNodeId *sender, bdNodeId *src, bdNodeId *dest); - int determineProxyId(bdNodeId *sender, bdNodeId *src, bdNodeId *dest, bdNodeId *proxyId); - - bdConnection *findSimilarConnection(bdNodeId *srcId, bdNodeId *destId); - bdConnection *findExistingConnectionBySender(bdId *sender, bdId *src, bdId *dest); - bdConnection *newConnectionBySender(bdId *sender, bdId *src, bdId *dest); - int cleanConnectionBySender(bdId *sender, bdId *src, bdId *dest); - - // Overloaded Generalised Connection Callback. - virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode); - - /* Connections: */ - int recvedConnectionRequest(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay); - int recvedConnectionReply(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delay, int status); - int recvedConnectionStart(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode, int delayOrBandwidth); - int recvedConnectionAck(bdId *id, bdId *srcConnAddr, bdId *destConnAddr, int mode); - - /* setup Relay Mode */ - void setRelayMode(uint32_t mode); - - private: - - std::map mConnections; - std::map mConnectionRequests; - - uint32_t mConfigAllowedModes; - bool mConfigAutoProxy; - - uint32_t mRelayMode; - - /****************************** Connection Code (in bdconnection.cc) ****************************/ - - private: - - bdNodeId mOwnId; - bdSpace *mNodeSpace; - bdQueryManager *mQueryMgr; - bdDhtFunctions *mFns; - bdNodePublisher *mPub; -}; - - -#endif // BITDHT_CONNECTION_H diff --git a/libbitdht/src/bitdht/bdfilter.cc b/libbitdht/src/bitdht/bdfilter.cc deleted file mode 100644 index 1ba7d3aca..000000000 --- a/libbitdht/src/bitdht/bdfilter.cc +++ /dev/null @@ -1,318 +0,0 @@ -/******************************************************************************* - * bitdht/bdfilter.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdfilter.h" -#include "bitdht/bdmanager.h" -#include "util/bdfile.h" - -#include -#include -#include -#include -#include - -/** - * #define DEBUG_FILTER 1 -**/ -#define BDFILTER_ENTRY_DROP_PERIOD (7 * 24 * 3600) - -bdFilter::bdFilter(const std::string &fname, const bdNodeId *ownid, uint32_t filterFlags, bdDhtFunctions *fns, bdNodeManager *manager) -{ - /* */ - mOwnId = *ownid; - mFns = fns; - mFilename = fname ; - - loadBannedIpFile() ; - - mFilterFlags = filterFlags; - mNodeManager = manager; -} - -void bdFilter::writeBannedIpFile() -{ - std::string filetmp = mFilename + ".tmp" ; - - FILE *fd = fopen(filetmp.c_str(), "w"); - - if (!fd) - { - std::cerr << "(EE) bdFilter::writeBannedIpFile() FAILED to Open File " << mFilename << std::endl; - return; - } - - for( std::map::iterator it=mFiltered.begin();it!=mFiltered.end();++it) - { - fprintf(fd, "%s %u %lu %lu\n", bdnet_inet_ntoa(it->second.mAddr.sin_addr).c_str(), it->second.mFilterFlags, it->second.mFilterTS, it->second.mLastSeen) ; -#ifdef DEBUG_FILTER - fprintf(stderr, "Storing Peer Address: %s \n", bdnet_inet_ntoa(it->second.mAddr.sin_addr).c_str()) ; -#endif - - } - fclose(fd); - - if(!bdFile::renameFile(filetmp,mFilename)) - std::cerr << "Could not rename file !!" << std::endl; -#ifdef DEBUG_FILTER - else - std::cerr << "Successfully renamed file " << filetmp << " to " << mFilename << std::endl; -#endif -} - -void bdFilter::loadBannedIpFile() -{ - char line[10240]; - char addr_str[10240]; - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = PF_INET; - - FILE *fd = fopen(mFilename.c_str(),"r") ; - - if(fd == NULL) - { - std::cerr << "(EE) Cannot load filter file " << mFilename << std::endl; - return ; - } - - while(line == fgets(line, 10240, fd)) - { - uint32_t filter_flags ; - unsigned long long int filter_ts ; - unsigned long long int last_seen ; - - if (4 == sscanf(line, "%s %u %llu %llu", addr_str, &filter_flags,&filter_ts,&last_seen)) - { - if (bdnet_inet_aton(addr_str, &(addr.sin_addr))) - { - addr.sin_port = 0; - - bdFilteredPeer peer; - - peer.mAddr = addr; - peer.mFilterTS = filter_ts; - peer.mLastSeen = last_seen; - peer.mFilterFlags = filter_flags; - - mFiltered[addr.sin_addr.s_addr] = peer ; - #ifdef DEBUG_FILTER - std::cerr << "Loaded filtered IP: " << std::string(addr_str) << " last seen: " << last_seen << ", TS=" << filter_ts << std::endl; - #endif - } - } - } - - fclose(fd); -} - -//bool bdFilter::filtered(std::list &answer) -//{ -// answer = mFiltered; -// return (answer.size() > 0); -//} - -bool bdFilter::filteredIPs(std::list &answer) -{ - std::map::iterator it; - for(it = mFiltered.begin(); it != mFiltered.end(); it++) - { - answer.push_back(it->second.mAddr); - } - return (answer.size() > 0); -} - -int bdFilter::checkPeer(const bdId *id, uint32_t mode) -{ - bool add = false; - uint32_t flags = 0; - if ((mFilterFlags & BITDHT_FILTER_REASON_OWNID) && - isOwnIdWithoutBitDhtFlags(id, mode)) - { - add = true; - flags |= BITDHT_FILTER_REASON_OWNID; - } - - if (add) - { - bool isNew = addPeerToFilter(id->addr, flags); - - if (isNew) - { - return 1; - } - } - - return 0; -} - -int bdFilter::addPeerToFilter(const struct sockaddr_in& addr, uint32_t flags) -{ - std::map::iterator it = mFiltered.find(addr.sin_addr.s_addr) ; - - if(it != mFiltered.end()) - { - it->second.mLastSeen = time(NULL); - it->second.mFilterFlags |= flags; - } - else - { - time_t now = time(NULL); - bdFilteredPeer fp; - - fp.mAddr = addr; - fp.mAddr.sin_port = 0; - fp.mFilterFlags = flags; - fp.mFilterTS = now; - fp.mLastSeen = now; - - uint32_t saddr = addr.sin_addr.s_addr; - - mFiltered[saddr] = fp; - - std::cerr << "Adding New Banned Ip Address: " << bdnet_inet_ntoa(addr.sin_addr); - std::cerr << std::endl; - } - writeBannedIpFile() ; - - return true; -} - -// void bdFilter::loadFilteredPeers(const std::list& peers) -// { -// for(std::list::iterator it = peers.begin(); it != peers.end();++it) -// { -// #ifdef DEBUG_FILTER -// std::cerr << "Loading filtered peer " << inet_ntoa(it->mAddr.sin_addr) << " Flags: " << it->mFilterFlags << " FilterTS: " -// << now - it->mFilterTS << " LastSeen: " << now - it->mLastSeen << std::endl; -// #endif -// uint32_t saddr = it->mAddr.sin_addr.s_addr; -// mFiltered[saddr] = *it ; -// } -// } -void bdFilter::getFilteredPeers(std::list& peers) -{ - for(std::map::iterator it = mFiltered.begin(); it != mFiltered.end();++it) - peers.push_back(it->second) ; -} -/* fast check if the addr is in the structure */ -int bdFilter::addrOkay(struct sockaddr_in *addr) -{ - // first check upper layer - bool isAvailable, isBanned; - mNodeManager->doIsBannedCallback(addr, &isAvailable, &isBanned); - - if(isAvailable) { -#ifdef DEBUG_FILTER - std::cerr << "bdFilter::addrOkay addr: " << inet_ntoa(addr->sin_addr) << " result from upper layer: " << (isBanned ? "banned" : "ok") << std::endl; -#endif - return !isBanned; - } else { - // fallback to own ban list - - std::map::const_iterator it = mFiltered.find(addr->sin_addr.s_addr); - if (it == mFiltered.end()) - return 1; // Address is Okay - } - -#ifdef DEBUG_FILTER - std::cerr << "Detected Packet From Banned Ip Address: " << inet_ntoa(addr->sin_addr); - std::cerr << std::endl; -#endif - return 0; -} - - -bool bdFilter::isOwnIdWithoutBitDhtFlags(const bdId *id, uint32_t peerFlags) -{ - if (peerFlags & BITDHT_PEER_STATUS_RECV_PONG) - { - if (peerFlags & BITDHT_PEER_STATUS_DHT_ENGINE) - { - /* okay! */ - return false; - } - - /* now check distance */ - bdMetric dist; - mFns->bdDistance(&mOwnId, &(id->id), &dist); - int bucket = mFns->bdBucketDistance(&dist); - - /* if they match us... kill it */ - if (bucket == 0) - { - return true; - } - } - return false; -} - - -/* periodically we want to cleanup the filter.... - * if we haven't had an IP address reported as filtered for several hours. - * remove it from the list. - */ - -bool bdFilter::cleanupFilter() -{ -#ifdef DEBUG_FILTER - std::cerr << "bdFilter: Checking current filter List:" << std::endl; -#endif - - time_t now = time(NULL); - time_t dropTime = now - BDFILTER_ENTRY_DROP_PERIOD; - - for(std::map::iterator it = mFiltered.begin(); it != mFiltered.end();) - { -#ifdef DEBUG_FILTER - std::cerr << "\t" << bdnet_inet_ntoa(it->second.mAddr.sin_addr); - std::cerr << " Flags: " << it->second.mFilterFlags; - std::cerr << " FilterTS: " << now - it->second.mFilterTS; - std::cerr << " LastSeen: " << now - it->second.mLastSeen; -#endif - - if (it->second.mLastSeen < dropTime) - { - /* remove from filter */ -#ifdef DEBUG_FILTER - std::cerr << " OLD DROPPING" << std::endl; -#endif - std::map::iterator tmp(it) ; - ++tmp ; - - mFiltered.erase(it); - it = tmp ; - } - else - { -#ifdef DEBUG_FILTER - std::cerr << " OK" << std::endl; -#endif - it++; - } - } - - return true; -} - - - diff --git a/libbitdht/src/bitdht/bdfilter.h b/libbitdht/src/bitdht/bdfilter.h deleted file mode 100644 index 27d32a7d4..000000000 --- a/libbitdht/src/bitdht/bdfilter.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * bitdht/bdfilter.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_FILTER_H -#define BITDHT_FILTER_H - -#include "bitdht/bdiface.h" -#include - -/* Query result flags are in bdiface.h */ - -#define BITDHT_FILTER_REASON_OWNID 0x0001 - -class bdFilteredPeer -{ - public: - struct sockaddr_in mAddr; - uint32_t mFilterFlags; /* reasons why we are filtering */ - time_t mFilterTS; - time_t mLastSeen; -}; - -class bdNodeManager; - -class bdFilter -{ - public: - bdFilter(const std::string& fname, const bdNodeId *ownid, uint32_t filterFlags, bdDhtFunctions *fns, bdNodeManager *manager); - - // get the answer. -//bool filtered(std::list &answer); -bool filteredIPs(std::list &answer); - -//void loadFilteredPeers(const std::list& peers) ; -void getFilteredPeers(std::list &peers); - -int checkPeer(const bdId *id, uint32_t peerFlags); - -int addrOkay(struct sockaddr_in *addr); -int addPeerToFilter(const struct sockaddr_in &addr, uint32_t flags); - -bool cleanupFilter(); - -void loadBannedIpFile() ; -void writeBannedIpFile() ; - -private: - -bool isOwnIdWithoutBitDhtFlags(const bdId *id, uint32_t peerFlags); - - // searching for - bdNodeId mOwnId; - uint32_t mFilterFlags; - - std::map mFiltered; - bdDhtFunctions *mFns; - std::string mFilename ; - - // have access to the manager for isBanned callback - bdNodeManager* mNodeManager; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdfriendlist.cc b/libbitdht/src/bitdht/bdfriendlist.cc deleted file mode 100644 index 487f0a75c..000000000 --- a/libbitdht/src/bitdht/bdfriendlist.cc +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************************* - * bitdht/bdfriendlist.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdfriendlist.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdpeer.h" - -#include - -/***** - * #define DEBUG_FRIENDLIST 1 - ****/ - -bdFriendEntry::bdFriendEntry() -{ - mFlags = 0; - mLastSeen = 0; -} - -bool bdFriendEntry::addrKnown(struct sockaddr_in *addr) -{ - if (mFlags & BD_FRIEND_ENTRY_ADDR_OK) - { - if (mFlags & BD_FRIEND_ENTRY_ONLINE) - { - *addr = mPeerId.addr; - return true; - } - - - if (time(NULL) - mLastSeen < BD_FRIEND_ENTRY_TIMEOUT) - { - *addr = mPeerId.addr; - return true; - } - } - return false; -} - -uint32_t bdFriendEntry::getPeerFlags() -{ - return mFlags & BD_FRIEND_ENTRY_MASK_KNOWN; -} - - -bdFriendList::bdFriendList(const bdNodeId *ownId) -{ - bdId tmpId; - tmpId.id = *ownId; - updatePeer(&tmpId, BD_FRIEND_ENTRY_SELF); -} - -/****** - * Simple logic: timestamp is set with address. - * if ONLINE, then address will be dropped as soon as OFFLINE. - * if ADDR_OK, then address will be dropped after XX seconds. - * - * ONLINE - will be used with friends. - * ADDR_OK - will potentially be used for friends of friends (but not for now). - *****/ - - /* catch-all interface function */ -bool bdFriendList::updatePeer(const bdId *id, uint32_t flags) -{ -#ifdef DEBUG_FRIENDLIST - std::cerr << "bdFriendList::updatePeer() Peer("; - bdStdPrintId(std::cerr, id); - std::cerr << ") Flags: " << flags; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mPeers.find(id->id); - if (it == mPeers.end()) - { - bdFriendEntry entry; - entry.mPeerId.id = id->id; - entry.mFlags = 0; - entry.mLastSeen = 0; - - mPeers[id->id] = entry; - it = mPeers.find(id->id); - } - - /* update all */ - it->second.mFlags = flags; - if (it->second.mFlags & (BD_FRIEND_ENTRY_ADDR_OK | BD_FRIEND_ENTRY_ONLINE)) - { - it->second.mFlags |= BD_FRIEND_ENTRY_ADDR_OK; - - it->second.mPeerId.addr = id->addr; - it->second.mLastSeen = time(NULL); - } - return true; -} - -bool bdFriendList::removePeer(const bdNodeId *id) -{ - /* see if it exists... */ - std::map::iterator it; - it = mPeers.find(*id); - if (it == mPeers.end()) - { -#ifdef DEBUG_FRIENDLIST - std::cerr << "bdFriendList::removeFriend() Peer("; - bdStdPrintNodeId(std::cerr, id); - std::cerr << ") is unknown!"; - std::cerr << std::endl; -#endif - - return false; - } - - mPeers.erase(*id); - - return true; -} - -bool bdFriendList::findPeerEntry(const bdNodeId *id, bdFriendEntry &entry) -{ - /* see if it exists... */ - std::map::iterator it; - it = mPeers.find(*id); - if (it == mPeers.end()) - { -#ifdef DEBUG_FRIENDLIST - std::cerr << "bdFriendList::getPeerEntry() Peer("; - bdStdPrintNodeId(std::cerr, id); - std::cerr << ") is unknown!"; - std::cerr << std::endl; -#endif - - return false; - } - - entry = it->second; - - - return true; -} - - -bool bdFriendList::findPeersWithFlags(uint32_t flags, std::list &peerList) -{ -#ifdef DEBUG_FRIENDLIST - std::cerr << "bdFriendList::findPeersWithFlags(" << flags << ")"; - std::cerr << std::endl; -#endif - - /* see if it exists... */ - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); it++) - { - /* if they have ALL of the flags we specified */ - if ((it->second.getPeerFlags() & flags) == flags) - { -#ifdef DEBUG_FRIENDLIST - std::cerr << "bdFriendList::findPeersWithFlags() Found: "; - bdStdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - peerList.push_back(it->second.mPeerId.id); - } - } - return (peerList.size() > 0); -} - - - -bool bdFriendList::print(std::ostream &out) -{ - time_t now = time(NULL); - - out << "bdFriendList::print()"; - out << std::endl; - - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); it++) - { - bdStdPrintId(out, &(it->second.mPeerId)); - out << " Flags: " << it->second.mFlags; - out << " Seen: " << now - it->second.mLastSeen; - out << std::endl; - } - - return true; -} - - - - -bdPeerQueue::bdPeerQueue() -{ - return; -} - -bool bdPeerQueue::queuePeer(const bdId *id, uint32_t flags) -{ - bdFriendEntry entry; - entry.mPeerId = *id; - entry.mFlags = flags; - entry.mLastSeen = time(NULL); - - mPeerQueue.push_back(entry); - return true; -} - -bool bdPeerQueue::popPeer(bdId *id, uint32_t &flags) -{ - if (mPeerQueue.size() > 0) - { - bdFriendEntry entry = mPeerQueue.front(); - mPeerQueue.pop_front(); - *id = entry.mPeerId; - flags = entry.mFlags; - - return true; - } - - return false; -} - - - diff --git a/libbitdht/src/bitdht/bdfriendlist.h b/libbitdht/src/bitdht/bdfriendlist.h deleted file mode 100644 index a58888ed8..000000000 --- a/libbitdht/src/bitdht/bdfriendlist.h +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * bitdht/bdfriendlist.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_FRIEND_LIST_H -#define BITDHT_FRIEND_LIST_H - -/* - * This class maintains a list of current friends and friends-of-friends. - * It should also be updated when a peer's address has been identified. - * - * It is used for selecting preferential peers for DHT Connections. - * and for detecting bad peers that are duplicating real RS peers. - * - */ - - -#include "bitdht/bdiface.h" -#include - -#define BD_FRIEND_ENTRY_TIMEOUT 10 - - -//#define BD_FRIEND_ENTRY_ONLINE 0x0001 -//#define BD_FRIEND_ENTRY_ADDR_OK 0x0002 - -//#define BD_FRIEND_ENTRY_WHITELIST BITDHT_PEER_STATUS_DHT_WHITELIST -//#define BD_FRIEND_ENTRY_FOF BITDHT_PEER_STATUS_DHT_FOF -//#define BD_FRIEND_ENTRY_FRIEND BITDHT_PEER_STATUS_DHT_FRIEND -//#define BD_FRIEND_ENTRY_RELAY_SERVER BITDHT_PEER_STATUS_DHT_RELAY_SERVER - -//#define BD_FRIEND_ENTRY_SELF BITDHT_PEER_STATUS_DHT_SELF - -//#define BD_FRIEND_ENTRY_MASK_KNOWN BITDHT_PEER_STATUS_MASK_KNOWN - -class bdFriendEntry -{ - public: - bdFriendEntry(); - -bool addrKnown(struct sockaddr_in *addr); -uint32_t getPeerFlags(); - - bdId mPeerId; - uint32_t mFlags; - time_t mLastSeen; -}; - -class bdFriendList -{ - - public: - bdFriendList(const bdNodeId *ownid); - -bool updatePeer(const bdId *id, uint32_t flags); -bool removePeer(const bdNodeId *id); - -bool findPeerEntry(const bdNodeId *id, bdFriendEntry &entry); -bool findPeersWithFlags(uint32_t flags, std::list &peerList); - -bool print(std::ostream &out); - private: - - std::map mPeers; -}; - -class bdPeerQueue -{ - - public: - bdPeerQueue(); - -bool queuePeer(const bdId *id, uint32_t flags); -bool popPeer(bdId *id, uint32_t &flags); - - private: - - std::list mPeerQueue; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdhash.cc b/libbitdht/src/bitdht/bdhash.cc deleted file mode 100644 index 5eabd3d95..000000000 --- a/libbitdht/src/bitdht/bdhash.cc +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* - * bitdht/bdhash.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdhash.h" -#include "bitdht/bdstddht.h" -#include - -bdHashEntry::bdHashEntry(std::string value, std::string secret, time_t lifetime, time_t store) - :mValue(value), mStoreTS(store), mSecret(secret), mLifetime(lifetime) -{ - return; -} - - -/**************************** class bdHashSet ********************************/ - -bdHashSet::bdHashSet(bdNodeId *id) - :mId(*id) -{ - return; -} - -int bdHashSet::search(std::string key, uint32_t maxAge, std::list &entries) -{ - std::multimap::iterator sit, eit, it; - sit = mEntries.lower_bound(key); - eit = mEntries.upper_bound(key); - - time_t now = time(NULL); - - for(it = sit; it != eit; it++) - { - time_t age = now - it->second.mStoreTS; - if (age < (int32_t) maxAge) - { - entries.push_back(it->second); - } - } - return (0 < entries.size()); -} - -/*** - * With modification. - * If there is no secret -> it cannot be deleted (must timeout), but can be extended. - * If there is a secret -> must include it to modify. - * - * Therefore if identical entry without secret comes along - what do I do? - * -> create duplicate? - */ - -int bdHashSet::modify(std::string key, bdHashEntry *entry, uint32_t modFlags) -{ - std::multimap::iterator sit, eit, it; - sit = mEntries.lower_bound(key); - eit = mEntries.upper_bound(key); - - time_t now = time(NULL); - - bool updated = false; - for(it = sit; it != eit; it++) - { - /* check it all */ - if (it->second.mValue == entry->mValue) - { - bool noSecret = (it->second.mSecret == ""); - bool sameSecret = (it->second.mSecret == entry->mSecret); - bool update = false; - - if (noSecret && sameSecret) - { - /* only allowed to increase lifetime */ - if (modFlags == BITDHT_HASH_ENTRY_ADD) - { - time_t existKillTime = it->second.mLifetime + it->second.mStoreTS; - time_t newKillTime = entry->mLifetime + now; - if (newKillTime > existKillTime) - { - update = true; - } - } - } - else if (sameSecret) - { - if (modFlags == BITDHT_HASH_ENTRY_ADD) - { - update = true; - } - else if (modFlags == BITDHT_HASH_ENTRY_DELETE) - { - /* do it here */ - mEntries.erase(it); - return 1; - } - } - - if (update) - { - it->second.mStoreTS = now; - it->second.mLifetime = entry->mLifetime; - updated = true; - } - } - } - - if ((!updated) && (modFlags == BITDHT_HASH_ENTRY_ADD)) - { - /* create a new entry */ - bdHashEntry newEntry(entry->mValue, entry->mSecret, entry->mLifetime, now); - mEntries.insert(std::pair(key, newEntry)); - updated = true; - } - return updated; -} - -int bdHashSet::printHashSet(std::ostream &out) -{ - time_t now = time(NULL); - std::multimap::iterator it; - out << "Hash: "; - bdStdPrintNodeId(out, &mId); // Allowing "Std" as we dont need dht functions everywhere. - out << std::endl; - - for(it = mEntries.begin(); it != mEntries.end();it++) - { - time_t age = now - it->second.mStoreTS; - out << "\tK:" << bdStdConvertToPrintable(it->first); - out << " V:" << bdStdConvertToPrintable(it->second.mValue); - out << " A:" << age << " L:" << it->second.mLifetime; - out << " S:" << bdStdConvertToPrintable(it->second.mSecret); - out << std::endl; - } - return 1; -} - - - - -int bdHashSet::cleanupHashSet(uint32_t maxAge) -{ - time_t now = time(NULL); - - /* this is nasty... but don't know how to effectively remove from multimaps - * * Must do full repeat for each removal. - */ - - std::multimap::iterator it; - for(it = mEntries.begin(); it != mEntries.end();) - { - time_t age = now - it->second.mStoreTS; - if ((age > (int32_t) maxAge) || (age > it->second.mLifetime)) - { - mEntries.erase(it); - it = mEntries.begin(); - } - else - { - it++; - } - } - return 1; -} - - - - - - -/******************************* class bdHashSpace ***************************/ - -bdHashSpace::bdHashSpace() -{ - return; -} - - /* accessors */ -int bdHashSpace::search(bdNodeId *id, std::string key, uint32_t maxAge, std::list &entries) -{ - std::map::iterator it; - it = mHashTable.find(*id); - if (it == mHashTable.end()) - { - /* no entry */ - return 1; - } - - return it->second.search(key, maxAge, entries); -} - -int bdHashSpace::modify(bdNodeId *id, std::string key, bdHashEntry *entry, uint32_t modFlags) -{ - std::map::iterator it; - it = mHashTable.find(*id); - if (it == mHashTable.end()) - { - if (modFlags == BITDHT_HASH_ENTRY_DELETE) - { - /* done already */ - return 1; - } - - //mHashTable[*id] = bdHashSet(id); - mHashTable.insert(std::pair(*id, bdHashSet(id))); - it = mHashTable.find(*id); - } - - return it->second.modify(key, entry, modFlags); -} - -int bdHashSpace::printHashSpace(std::ostream &out) -{ - std::map::iterator it; - out << "bdHashSpace::printHashSpace()" << std::endl; - out << "--------------------------------------------" << std::endl; - - for(it = mHashTable.begin(); it != mHashTable.end(); it++) - { - it->second.printHashSet(out); - } - out << "--------------------------------------------" << std::endl; - return 1; -} - -int bdHashSpace::cleanHashSpace(bdNodeId *min, bdNodeId *max, time_t maxAge) -{ - std::map::iterator it; - std::list eraseList; - std::list::iterator eit; - - for(it = mHashTable.begin(); it != mHashTable.end(); it++) - { - if ((it->first < *min) || - (*max < it->first)) - { - /* schedule for erasure */ - eraseList.push_back(it->first); - } - else - { - /* clean up Hash Set */ - it->second.cleanupHashSet(maxAge); - } - } - - /* cleanup */ - while(eraseList.size() > 0) - { - bdNodeId &eId = eraseList.front(); - it = mHashTable.find(eId); - if (it != mHashTable.end()) - { - mHashTable.erase(it); - } - } - return 1; -} - - -int bdHashSpace::clear() -{ - mHashTable.clear(); - return 1; -} - - diff --git a/libbitdht/src/bitdht/bdhash.h b/libbitdht/src/bitdht/bdhash.h deleted file mode 100644 index 680169665..000000000 --- a/libbitdht/src/bitdht/bdhash.h +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * bitdht/bdhash.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_HASH_SPACE_H -#define BITDHT_HASH_SPACE_H - -#include "bitdht/bdpeer.h" - -#include -#include -#include - -#define BITDHT_HASH_ENTRY_ADD 1 -#define BITDHT_HASH_ENTRY_DELETE 2 - -class bdHashEntry -{ - public: - - bdHashEntry(std::string value, std::string secret, time_t lifetime, time_t store); - std::string mValue; - time_t mStoreTS; - - /* These are nice features that OpenDHT had */ - std::string mSecret; - time_t mLifetime; -}; - - -class bdHashSet -{ - public: - - bdHashSet(bdNodeId *id); - -int search(std::string key, uint32_t maxAge, std::list &entries); -int modify(std::string key, bdHashEntry *entry, uint32_t modFlags); -int printHashSet(std::ostream &out); -int cleanupHashSet(uint32_t maxAge); - - bdNodeId mId; - std::multimap mEntries; -}; - -class bdHashSpace -{ - public: - - bdHashSpace(); - - /* accessors */ -int search(bdNodeId *id, std::string key, uint32_t maxAge, std::list &entries); -int modify(bdNodeId *id, std::string key, bdHashEntry *entry, uint32_t modFlags); - -int printHashSpace(std::ostream&); -int cleanHashSpace(bdNodeId *min, bdNodeId *max, time_t maxAge); -int clear(); - - private: - - std::map mHashTable; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdhistory.cc b/libbitdht/src/bitdht/bdhistory.cc deleted file mode 100644 index 05bb73fa0..000000000 --- a/libbitdht/src/bitdht/bdhistory.cc +++ /dev/null @@ -1,647 +0,0 @@ -/******************************************************************************* - * bitdht/bdhistory.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - - -#include "bitdht/bdhistory.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdmsgs.h" -#include - -#define MIN_RESEND_PERIOD 60 - -bdMsgHistoryList::bdMsgHistoryList() -:mPeerVersion("Unknown") -{ - return; -} - - - -void bdMsgHistoryList::addMsg(time_t ts, uint32_t msgType, bool incoming, const bdNodeId *aboutId) -{ -// std::cerr << "bdMsgHistoryList::addMsg()"; -// std::cerr << std::endl; - - bdMsgHistoryItem msg(msgType, incoming, aboutId); - msgHistory.insert(std::make_pair(ts, msg)); -} - -void bdMsgHistoryList::setPeerType(time_t /* ts */, std::string version) -{ - mPeerVersion = version; -} - -int bdMsgHistoryList::msgCount(time_t start_ts, time_t end_ts) -{ - std::multimap::iterator sit, eit, it; - sit = msgHistory.lower_bound(start_ts); - eit = msgHistory.upper_bound(end_ts); - int count = 0; - for (it = sit; it != eit; it++, count++) ; // empty loop. - - return count; -} - -bool bdMsgHistoryList::msgClear(time_t before) -{ - if (before == 0) - { - msgHistory.clear(); - return true; - } - - // Delete the old stuff in the list. - while((msgHistory.begin() != msgHistory.end()) && (msgHistory.begin()->first < before)) - { - msgHistory.erase(msgHistory.begin()); - } - - // return true if empty. - if (msgHistory.begin() == msgHistory.end()) - { - return true; - } - return false; -} - -void bdMsgHistoryList::msgClear() -{ - msgHistory.clear(); -} - - -void bdMsgHistoryList::clearHistory() -{ - msgClear(); -} - -void bdMsgHistoryList::printHistory(std::ostream &out, int mode, time_t start_ts, time_t end_ts) -{ - //out << "AGE: MSGS => incoming, <= outgoing" << std::endl; - std::multimap::iterator sit, eit, it; - sit = msgHistory.lower_bound(start_ts); - eit = msgHistory.upper_bound(end_ts); - time_t curr_ts = 0; - bool time_changed = false; - bool first_line = true; - - for(it = sit; it != eit; it++) - { - time_changed = false; - if (curr_ts != it->first) - { - curr_ts = it->first; - time_changed = true; - } - switch(mode) - { - default: - { - /* print one line per ts */ - if (time_changed) - { - if (!first_line) - { - /* finish existing line */ - out << " " << std::endl; - } - else - { - first_line = false; - } - out << "\tTS: " << time(NULL) - curr_ts << " "; - } - - std::string name; - bitdht_msgtype(it->second.msgType, name); - - if (it->second.incoming) - { - out << "( =I> "; - } - else - { - out << "( second.aboutId.data[0] == 0) - && (it->second.aboutId.data[3] == 0) - && (it->second.aboutId.data[3] == 0) - && (it->second.aboutId.data[3] == 0)) - { - /* don't print anything */ - } - else - { - bdStdPrintNodeId(out, &(it->second.aboutId)); - } - out << " )"; - - } - break; - } // end of switch. - } - - /* finish up last line */ - if (!first_line) - { - out << " " << std::endl; - } -} - - -bool bdMsgHistoryList::canSend() -{ - std::cerr << "bdMsgHistoryList::canSend()"; - - std::multimap::reverse_iterator rit; - - rit = msgHistory.rbegin(); - if (rit != msgHistory.rend()) - { - time_t now = time(NULL); - if (now - rit->first > MIN_RESEND_PERIOD) - { - std::cerr << " OVER RESEND_PERIOD... true"; - std::cerr << std::endl; - - return true; - } - } - - if (msgHistory.size() % 2 == 0) - { - std::cerr << " SIZE: " << msgHistory.size() << " % 2 = 0 ... true"; - std::cerr << std::endl; - - return true; - } - - std::cerr << " false"; - std::cerr << std::endl; - - return false; -} - -bool bdMsgHistoryList::validPeer() -{ - std::cerr << "bdMsgHistoryList::validPeer()"; - - std::multimap::iterator it; - - for(it = msgHistory.begin(); it != msgHistory.end(); it++) - { - if (it->second.incoming) - { - std::cerr << " Incoming Msg... so validPeer"; - std::cerr << std::endl; - - return true; - } - } - - std::cerr << " false"; - std::cerr << std::endl; - - return false; -} - - -#define MAX_PING_PER_MINUTE 2 -#define MAX_QUERY_PER_MINUTE 2 - -bool bdMsgHistoryList::analysePeer() - -{ - /* analyse and print out details of the peers messages */ - bool flagged = false; - - //out << "AGE: MSGS => incoming, <= outgoing" << std::endl; - std::multimap::iterator sit, eit, it; - sit = msgHistory.begin(); - eit = msgHistory.end(); - if (sit == eit) - { - // nothing here. - return false; - } - - time_t start_ts = sit->first; - time_t end_ts = msgHistory.rbegin()->first; // must exist. - - - // don't divide by zero. - if (end_ts - start_ts < 60) - { - end_ts = start_ts + 60; - } - - - /* what do we want to analyse? */ - - /* if we have sent / recved too many queries or pings */ - - int in_ping = 0; - int out_ping = 0; - int in_query = 0; - int out_query = 0; - int in_other = 0; - int out_other = 0; - - for(it = sit; it != eit; it++) - { - if (it->second.incoming) - { - switch(it->second.msgType) - { - case BITDHT_MSG_TYPE_PING: - in_ping++; - break; - case BITDHT_MSG_TYPE_FIND_NODE: - in_query++; - break; - default: - in_other++; - break; - } - } - else - { - switch(it->second.msgType) - { - case BITDHT_MSG_TYPE_PING: - out_ping++; - break; - case BITDHT_MSG_TYPE_FIND_NODE: - out_query++; - break; - default: - out_other++; - break; - } - } - - } - - float in_ping_per_min = in_ping * 60.0 / (end_ts - start_ts); - float out_ping_per_min = out_ping * 60.0 / (end_ts - start_ts); - float in_query_per_min = in_query * 60.0 / (end_ts - start_ts); - float out_query_per_min = out_query * 60.0 / (end_ts - start_ts); - - if ((in_ping_per_min > MAX_PING_PER_MINUTE) || - (out_ping_per_min > MAX_PING_PER_MINUTE) || - (in_query_per_min > MAX_PING_PER_MINUTE) || - (out_query_per_min > MAX_PING_PER_MINUTE)) - { - flagged = true; - } - - if (flagged) - { - /* print header */ - std::ostream &out = std::cerr; - out << "BdHistoryAnalysis has flagged peer: "; - bdStdPrintId(out, &mId); - out << std::endl; - - out << "PeerType: " << mPeerVersion; - out << std::endl; - - out << "Ping In Per Min : " << in_ping_per_min << std::endl; - out << "Ping Out Per Min : " << out_ping_per_min << std::endl; - out << "Query In Per Min : " << in_query_per_min << std::endl; - out << "Query Out Per Min: " << out_query_per_min << std::endl; - - out << "Message History: "; - out << std::endl; - - printHistory(out, 0, 0, time(NULL)); - } - return true; -} - -bdHistory::bdHistory(time_t store_period) - :mStorePeriod(store_period) { return; } - -void bdHistory::addMsg(const bdId *id, bdToken * /*transId*/, uint32_t msgType, bool incoming, const bdNodeId *aboutId) -{ - //std::cerr << "bdHistory::addMsg() "; - //bdStdPrintId(std::cerr, id); - //std::cerr << std::endl; - - time_t now = time(NULL); - - std::map::iterator it; - bdMsgHistoryList &histRef = mHistory[*id]; /* will instaniate empty */ - histRef.mId = *id; - histRef.addMsg(now, msgType, incoming, aboutId); - - /* add to mMsgTimeline */ - mMsgTimeline.insert(std::make_pair(now, MsgRegister(id, msgType, incoming, aboutId))); -} - -void bdHistory::setPeerType(const bdId *id, std::string version) -{ - std::map::iterator it; - bdMsgHistoryList &histRef = mHistory[*id]; /* will instaniate empty */ - histRef.setPeerType(time(NULL), version); -} - -void bdHistory::printMsgs() -{ - /* print and clear msgs */ - std::ostream &out = std::cerr; - - std::cerr << "bdHistory::printMsgs()"; - std::cerr << std::endl; - - - std::map ::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); it++) - { - if (it->second.msgCount(0, time(NULL))) // all msg count. - { - /* print header */ - out << "Msgs for "; - bdStdPrintId(out, &(it->first)); - out << " v:" << it->second.mPeerVersion; - out << std::endl; - - it->second.printHistory(out, 0, 0, time(NULL)); - } - } - - out << "Msg Timeline:"; - time_t now = time(NULL); - std::multimap::iterator hit; - for(hit = mMsgTimeline.begin(); hit != mMsgTimeline.end(); hit++) - { - out << now - hit->first << " "; - bdStdPrintId(out, &(hit->second.id)); - - if (hit->second.incoming) - { - out << " =I> "; - } - else - { - out << " second.msgType, name)) - { - out << name; - } - else - { - out << "UNKNOWN MSG"; - } - out << std::endl; - } -} - - -void bdHistory::cleanupOldMsgs() -{ - std::cerr << "bdHistory::cleanupOldMsgs()"; - std::cerr << std::endl; - - if (mStorePeriod == 0) - { - return; // no cleanup - } - - std::set to_cleanup; - std::set::iterator cit; - - time_t before = time(NULL) - mStorePeriod; - - // Delete the old stuff in the list. - while((mMsgTimeline.begin() != mMsgTimeline.end()) && (mMsgTimeline.begin()->first < before)) - { - std::multimap::iterator it = mMsgTimeline.begin(); - to_cleanup.insert(it->second.id); - mMsgTimeline.erase(it); - } - - // remove old msgs, delete entry if its empty. - std::map::iterator hit; - for(cit = to_cleanup.begin(); cit != to_cleanup.end(); cit++) - { - hit = mHistory.find(*cit); - if (hit != mHistory.end()) - { - if (hit->second.msgClear(before)) - { - // don't erase actual entry (so we remember peer type). - //mHistory.erase(hit); - } - } - } -} - - - -void bdHistory::clearHistory() -{ - // Switched to a alternative clear, so we don't drop peers, and remember their type. - //mHistory.clear(); - - - std::map ::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); it++) - { - it->second.clearHistory(); - } -} - -bool bdHistory::canSend(const bdId *id) -{ - - std::map ::iterator it; - it = mHistory.find(*id); - if (it != mHistory.end()) - { - return (it->second.canSend()); - } - - /* if not found - then can send */ - return true; -} - - -bool bdHistory::validPeer(const bdId *id) -{ - std::map ::iterator it; - it = mHistory.find(*id); - if (it != mHistory.end()) - { - return (it->second.validPeer()); - } - - /* if not found - then can send */ - return false; -} - -bool bdHistory::analysePeers() -{ - std::map ::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); it++) - { - it->second.analysePeer(); - } - return true; -} - - - -/* Temp data class. */ -class TypeStats -{ - public: - - TypeStats() :nodes(0) { return; } - - std::map incoming, outgoing; - int nodes; - - -void printStats(std::ostream &out, const TypeStats *refStats) -{ - std::map::iterator it; - std::map::const_iterator rit; - - out << " Nodes: " << nodes; - if (refStats) - { - out << " (" << 100.0 * nodes / (float) refStats->nodes << " %)"; - } - out << std::endl; - - out << " Incoming Msgs"; - out << std::endl; - for(it = incoming.begin(); it != incoming.end(); it++) - { - uint32_t count = 0; - if (refStats) - { - rit = refStats->incoming.find(it->first); - if (rit != refStats->incoming.end()) - { - count = rit->second; - } - } - printStatsLine(out, it->first, it->second, count); - } - - out << " Outgoing Msgs"; - out << std::endl; - for(it = outgoing.begin(); it != outgoing.end(); it++) - { - uint32_t count = 0; - if (refStats) - { - rit = refStats->outgoing.find(it->first); - if (rit != refStats->outgoing.end()) - { - count = rit->second; - } - } - printStatsLine(out, it->first, it->second, count); - } -} - - - -void printStatsLine(std::ostream &out, uint32_t msgType, uint32_t count, uint32_t global) -{ - std::string name; - bitdht_msgtype(msgType, name); - out << "\t" << name << " " << count; - if (global != 0) - { - out << " (" << 100.0 * count / (float) global << " %)"; - } - out << std::endl; -} - -}; /* end of TypeStats */ - -bool bdHistory::peerTypeAnalysis() -{ - - std::map mTypeStats; - TypeStats globalStats; - - std::map ::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); it++) - { - if (it->second.msgHistory.empty()) - { - continue; - } - - std::string version = it->second.mPeerVersion; - // group be first two bytes. - version = it->second.mPeerVersion.substr(0,2); - TypeStats &stats = mTypeStats[version]; - - stats.nodes++; - globalStats.nodes++; - - std::multimap::iterator lit; - for (lit = it->second.msgHistory.begin(); lit != it->second.msgHistory.end(); lit++) - { - if (lit->second.incoming) - { - stats.incoming[lit->second.msgType]++; - globalStats.incoming[lit->second.msgType]++; - } - else - { - stats.outgoing[lit->second.msgType]++; - globalStats.outgoing[lit->second.msgType]++; - } - } - } - - - std::map::iterator tit; - for(tit = mTypeStats.begin(); tit != mTypeStats.end(); tit++) - { - std::cerr << "Stats for Peer Type: " << tit->first; - std::cerr << std::endl; - tit->second.printStats(std::cerr, &globalStats); - } - - std::cerr << "Global Stats: "; - std::cerr << std::endl; - - globalStats.printStats(std::cerr, NULL); - return true; - -} - - - diff --git a/libbitdht/src/bitdht/bdhistory.h b/libbitdht/src/bitdht/bdhistory.h deleted file mode 100644 index 79e420d92..000000000 --- a/libbitdht/src/bitdht/bdhistory.h +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * bitdht/bdhistory.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_HISTORY_H -#define BITDHT_HISTORY_H - -#include "bitdht/bdpeer.h" -#include "bitdht/bdobj.h" -#include "bitdht/bdstddht.h" -#include - -#define MSG_TYPE_DIRECTION_MASK 0x000f0000 - -#define MSG_DIRECTION_INCOMING 0x00010000 -#define MSG_DIRECTION_OUTGOING 0x00020000 - -/**** DEBUGGING HISTORY ****/ - -class MsgRegister -{ - public: - MsgRegister() { return; } - MsgRegister(const bdId *inId, uint32_t inMsgType, bool inIncoming, const bdNodeId *inAboutId) - :id(*inId), msgType(inMsgType), incoming(inIncoming) - { - if (inAboutId) - { - aboutId = *inAboutId; - } - else - { - bdStdZeroNodeId(&aboutId); - } - - return; - } - - bdId id; - uint32_t msgType; - bool incoming; - bdNodeId aboutId; // filled in for queries. -}; - - -class bdMsgHistoryItem -{ - public: - bdMsgHistoryItem() - :msgType(0), incoming(false) - { - bdStdZeroNodeId(&aboutId); - return; - } - - bdMsgHistoryItem(uint32_t inMsgType, bool inIncoming, const bdNodeId *inAboutId) - :msgType(inMsgType), incoming(inIncoming) - { - if (inAboutId) - { - aboutId = *inAboutId; - } - else - { - bdStdZeroNodeId(&aboutId); - } - - return; - } - - uint32_t msgType; - bool incoming; - bdNodeId aboutId; // filled in for queries. -}; - - -class bdMsgHistoryList -{ - public: - bdMsgHistoryList(); -void addMsg(time_t ts, uint32_t msgType, bool incoming, const bdNodeId *aboutId); -void setPeerType(time_t ts, std::string version); -int msgCount(time_t start_ts, time_t end_ts); -bool msgClear(time_t before); // 0 => clear all. -void msgClear(); -void printHistory(std::ostream &out, int mode, time_t start_ts, time_t end_ts); -bool analysePeer(); -void clearHistory(); - -bool canSend(); -bool validPeer(); - - std::multimap msgHistory; - std::string mPeerVersion; - bdId mId; -}; - - - -class bdHistory -{ - public: - bdHistory(time_t store_period); - -void addMsg(const bdId *id, bdToken *transId, uint32_t msgType, bool incoming, const bdNodeId *aboutId); -void setPeerType(const bdId *id, std::string version); -void printMsgs(); - -void cleanupOldMsgs(); -void clearHistory(); -bool analysePeers(); -bool peerTypeAnalysis(); - -bool canSend(const bdId *id); -bool validPeer(const bdId *id); - - /* recent history */ - //std::list lastMsgs; - std::map mHistory; - std::multimap mMsgTimeline; - - int mStorePeriod; - -}; - - - -#endif - diff --git a/libbitdht/src/bitdht/bdiface.h b/libbitdht/src/bitdht/bdiface.h deleted file mode 100644 index 4e571ccdb..000000000 --- a/libbitdht/src/bitdht/bdiface.h +++ /dev/null @@ -1,413 +0,0 @@ -/******************************************************************************* - * bitdht/bdiface.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BIT_DHT_INTERFACE_H -#define BIT_DHT_INTERFACE_H - -#include -#include -#include -#include -#include - -#include "util/bdnet.h" - -/* - * Functions and Classes required for Interfacing with the BitDht. - * This should be the sole header file required to talk to Dht. - * ... though setting it up will require including udpbitdht.h as well. - * - */ - -#define BITDHT_KEY_LEN 20 -#define BITDHT_KEY_INTLEN 5 -#define BITDHT_KEY_BITLEN 160 - - - - -#define BITDHT_MAX_PKTSIZE 1024 - -#define BITDHT_TTL 64 - -#define BITDHT_SEARCH_ONE_SHOT 1 -#define BITDHT_SEARCH_REPEATING 2 - -class bdNodeId -{ - public: - unsigned char data[BITDHT_KEY_LEN]; -}; - -class bdMetric: public bdNodeId {}; - -class bdId -{ - public: - - bdId(); - bdId(bdNodeId in_id, struct sockaddr_in in_addr); - - struct sockaddr_in addr; - bdNodeId id; -}; - -#define BITDHT_LIKELY_SAME_NO 0x00000000 -#define BITDHT_LIKELY_SAME_YES 0x00000001 -#define BITDHT_LIKELY_SAME_PORT_CHANGED 0x00000002 -#define BITDHT_LIKELY_SAME_LOC_CHANGED 0x00000004 -#define BITDHT_LIKELY_SAME_IDENTICAL 0x00000008 - - -class bdDhtFunctions -{ - public: - -// bdDhtFunctions(); - /* setup variables */ -virtual uint16_t bdNumBuckets() = 0; -virtual uint16_t bdNodesPerBucket() = 0; /* used for bdspace */ -virtual uint16_t bdNumQueryNodes() = 0; /* used for queries */ -virtual uint16_t bdBucketBitSize() = 0; - -virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric) = 0; -virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2) = 0; -virtual int bdBucketDistance(const bdMetric *metric) = 0; - -virtual bool bdSimilarId(const bdId *id1, const bdId *id2) = 0; -virtual bool bdUpdateSimilarId(bdId *dest, const bdId *src) = 0; - -virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid) = 0; - -virtual void bdPrintId(std::ostream &out, const bdId *a) = 0; -virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a) = 0; - -}; - - - -// DHT MODES -#define BITDHT_MODE_TRAFFIC_MASK 0x00000f00 -#define BITDHT_MODE_RELAYSERVER_MASK 0x0000f000 - -// These are not ORd - only one can apply. -#define BITDHT_MODE_TRAFFIC_HIGH 0x00000100 -#define BITDHT_MODE_TRAFFIC_MED 0x00000200 -#define BITDHT_MODE_TRAFFIC_LOW 0x00000300 -#define BITDHT_MODE_TRAFFIC_TRICKLE 0x00000400 -#define BITDHT_MODE_TRAFFIC_DEFAULT BITDHT_MODE_TRAFFIC_LOW - -// These are not ORd - only one can apply. -#define BITDHT_MODE_RELAYSERVERS_IGNORED 0x00001000 -#define BITDHT_MODE_RELAYSERVERS_FLAGGED 0x00002000 -#define BITDHT_MODE_RELAYSERVERS_ONLY 0x00003000 -#define BITDHT_MODE_RELAYSERVERS_SERVER 0x00004000 - - -/* NODE OPTIONS */ -#define BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT 0x00000001 -#define BITDHT_OPTIONS_ENABLE_RELAYS 0x00000002 - - -/* peer flags - * order is important! - * higher bits = more priority. - * BITDHT_PEER_STATUS_RECVPING - * BITDHT_PEER_STATUS_RECVPONG - * BITDHT_PEER_STATUS_RECVNODES - * BITDHT_PEER_STATUS_RECVHASHES - * BITDHT_PEER_STATUS_DHT_ENGINE (dbXXxx) - * BITDHT_PEER_STATUS_DHT_APPL (XXRSxx) - * BITDHT_PEER_STATUS_DHT_VERSION (XXxx50) - * - */ - -#define BITDHT_PEER_STATUS_MASK_RECVD 0x000000ff -#define BITDHT_PEER_STATUS_MASK_DHT 0x0000ff00 -#define BITDHT_PEER_STATUS_MASK_KNOWN 0x00ff0000 - -#define BITDHT_PEER_STATUS_RECV_PING 0x00000001 -#define BITDHT_PEER_STATUS_RECV_PONG 0x00000002 -#define BITDHT_PEER_STATUS_RECV_NODES 0x00000004 -#define BITDHT_PEER_STATUS_RECV_HASHES 0x00000008 -#define BITDHT_PEER_STATUS_RECV_CONNECT_MSG 0x00000010 - -#define BITDHT_PEER_STATUS_DHT_ENGINE 0x00000100 -#define BITDHT_PEER_STATUS_DHT_ENGINE_VERSION 0x00000200 -#define BITDHT_PEER_STATUS_DHT_APPL 0x00000400 -#define BITDHT_PEER_STATUS_DHT_APPL_VERSION 0x00000800 - -#define BITDHT_PEER_STATUS_DHT_WHITELIST 0x00010000 -#define BITDHT_PEER_STATUS_DHT_FOF 0x00020000 -#define BITDHT_PEER_STATUS_DHT_FRIEND 0x00040000 -#define BITDHT_PEER_STATUS_DHT_RELAY_SERVER 0x00080000 // (Flag must be enabled) -#define BITDHT_PEER_STATUS_DHT_SELF 0x00100000 - - -// EXTRA FLAGS are our internal thoughts about the peer. -#define BITDHT_PEER_EXFLAG_MASK_BASIC 0x000000ff -#define BITDHT_PEER_EXFLAG_UNSTABLE 0x00000001 // Port changes. -#define BITDHT_PEER_EXFLAG_ATTACHED 0x00000002 // We will ping in heavily. (if unstable) -#define BITDHT_PEER_EXFLAG_BADPEER 0x00000004 // For testing, we flag rather than discard. - - - - - -#define BITDHT_CONNECT_MODE_DIRECT 0x00000001 -#define BITDHT_CONNECT_MODE_PROXY 0x00000002 -#define BITDHT_CONNECT_MODE_RELAY 0x00000004 - -#define BITDHT_CONNECT_OPTION_AUTOPROXY 0x00000001 - -// STATUS CODES. == 0 is okay, != 0 is error. -#define BITDHT_CONNECT_ANSWER_OKAY 0x00000000 -#define BITDHT_CONNECT_ERROR_NONE (BITDHT_CONNECT_ANSWER_OKAY) - -#define BITDHT_CONNECT_ERROR_MASK_TYPE 0x0000ffff -#define BITDHT_CONNECT_ERROR_MASK_SOURCE 0x00ff0000 -#define BITDHT_CONNECT_ERROR_MASK_CRMOVE 0xff000000 - -#define BITDHT_CONNECT_ERROR_SOURCE_START 0x00010000 -#define BITDHT_CONNECT_ERROR_SOURCE_MID 0x00020000 -#define BITDHT_CONNECT_ERROR_SOURCE_END 0x00040000 -#define BITDHT_CONNECT_ERROR_SOURCE_OTHER 0x00080000 - -#define BITDHT_CONNECT_ERROR_CRMOVE_FATAL 0x01000000 -#define BITDHT_CONNECT_ERROR_CRMOVE_NOMOREIDS 0x02000000 -#define BITDHT_CONNECT_ERROR_CRMOVE_NEXTID 0x04000000 -#define BITDHT_CONNECT_ERROR_CRMOVE_PAUSED 0x08000000 - -// ERROR CODES. -#define BITDHT_CONNECT_ERROR_GENERIC 0x00000001 -#define BITDHT_CONNECT_ERROR_PROTOCOL 0x00000002 -#define BITDHT_CONNECT_ERROR_TIMEOUT 0x00000003 -#define BITDHT_CONNECT_ERROR_TEMPUNAVAIL 0x00000004 // Haven't got ext address yet. -#define BITDHT_CONNECT_ERROR_NOADDRESS 0x00000005 // Can't find the peer in tables. -#define BITDHT_CONNECT_ERROR_UNREACHABLE 0x00000006 // Symmetric NAT - -#define BITDHT_CONNECT_ERROR_UNSUPPORTED 0x00000007 -#define BITDHT_CONNECT_ERROR_OVERLOADED 0x00000008 -#define BITDHT_CONNECT_ERROR_AUTH_DENIED 0x00000009 -#define BITDHT_CONNECT_ERROR_DUPLICATE 0x0000000a - -// These are slightly special ones used for CB_REQUEST -#define BITDHT_CONNECT_ERROR_TOOMANYRETRY 0x0000000b -#define BITDHT_CONNECT_ERROR_OUTOFPROXY 0x0000000c -#define BITDHT_CONNECT_ERROR_USER 0x0000000d - - -/*************/ -// FRIEND_ENTRY_FLAGS... used by updateKnownPeers(). - -#define BD_FRIEND_ENTRY_ONLINE 0x0001 -#define BD_FRIEND_ENTRY_ADDR_OK 0x0002 - -#define BD_FRIEND_ENTRY_WHITELIST BITDHT_PEER_STATUS_DHT_WHITELIST -#define BD_FRIEND_ENTRY_FOF BITDHT_PEER_STATUS_DHT_FOF -#define BD_FRIEND_ENTRY_FRIEND BITDHT_PEER_STATUS_DHT_FRIEND -#define BD_FRIEND_ENTRY_RELAY_SERVER BITDHT_PEER_STATUS_DHT_RELAY_SERVER - -#define BD_FRIEND_ENTRY_SELF BITDHT_PEER_STATUS_DHT_SELF - -#define BD_FRIEND_ENTRY_MASK_KNOWN BITDHT_PEER_STATUS_MASK_KNOWN - - - - -/* Definitions of bdSpace Peer and Bucket are publically available, - * so we can expose the bucket entries for the gui. - */ - -class bdPeer -{ - public: - bdPeer():mPeerFlags(0), mLastSendTime(0), mLastRecvTime(0), mFoundTime(0), mExtraFlags(0) { return; } - - bdId mPeerId; - uint32_t mPeerFlags; - time_t mLastSendTime; - time_t mLastRecvTime; - time_t mFoundTime; /* time stamp that peer was found */ - - uint32_t mExtraFlags; -}; - -class bdBucket -{ - public: - - bdBucket(); - /* list so we can queue properly */ - std::list entries; -}; - -class bdQueryStatus -{ - public: - uint32_t mStatus; - uint32_t mQFlags; - std::list mResults; -}; - -class bdQuerySummary -{ - public: - - bdNodeId mId; - bdMetric mLimit; - uint32_t mState; - time_t mQueryTS; - uint32_t mQueryFlags; - int32_t mSearchTime; - - int32_t mQueryIdlePeerRetryPeriod; // seconds between retries. - - // closest peers - std::multimap mClosest; - std::multimap mPotentialPeers; - std::list mProxiesUnknown; - std::list mProxiesFlagged; -}; - - - - -/* Status options */ -#define BITDHT_QUERY_READY 1 -#define BITDHT_QUERY_QUERYING 2 -#define BITDHT_QUERY_FAILURE 3 -#define BITDHT_QUERY_FOUND_CLOSEST 4 -#define BITDHT_QUERY_PEER_UNREACHABLE 5 -#define BITDHT_QUERY_SUCCESS 6 - -/* Query Flags */ -#define BITDHT_QFLAGS_NONE 0x0000 -#define BITDHT_QFLAGS_DISGUISE 0x0001 // Don't search directly for target. -#define BITDHT_QFLAGS_DO_IDLE 0x0002 -#define BITDHT_QFLAGS_INTERNAL 0x0004 // runs through startup. (limited callback) -#define BITDHT_QFLAGS_UPDATES 0x0008 // Do regular updates. - -/* Connect Callback Flags */ -#define BITDHT_CONNECT_CB_AUTH 1 -#define BITDHT_CONNECT_CB_PENDING 2 -#define BITDHT_CONNECT_CB_START 3 -#define BITDHT_CONNECT_CB_PROXY 4 -#define BITDHT_CONNECT_CB_FAILED 5 -#define BITDHT_CONNECT_CB_REQUEST 6 - -#define BD_PROXY_CONNECTION_UNKNOWN_POINT 0 -#define BD_PROXY_CONNECTION_START_POINT 1 -#define BD_PROXY_CONNECTION_MID_POINT 2 -#define BD_PROXY_CONNECTION_END_POINT 3 - -#define BITDHT_INFO_CB_TYPE_BADPEER 1 - -/* Relay Modes */ -#define BITDHT_RELAYS_OFF 0 -#define BITDHT_RELAYS_ON 1 -#define BITDHT_RELAYS_ONLY 2 -#define BITDHT_RELAYS_SERVER 3 - - -class BitDhtCallback -{ - public: -// ~BitDhtCallback(); - - // dummy cos not needed for standard dht behaviour; - virtual int dhtNodeCallback(const bdId * /*id*/, uint32_t /*peerflags*/) { return 0; } - - // must be implemented. - virtual int dhtPeerCallback(const bdId *id, uint32_t status) = 0; - virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status) = 0; - - // connection callback. Not required for basic behaviour, but forced for initial development. - virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) = 0; /* { return 0; } */ - - // Generic Info callback - initially will be used to provide bad peers. - virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info) = 0; - - // ask upper layer whether an IP is banned or not - // must not be implemented - // when set it will be used instead of the own ban list - // return code is used to express availability/absence - virtual int dhtIsBannedCallback(const sockaddr_in */*addr*/, bool */*isBanned*/) { return 0;} -}; - - -class BitDhtInterface -{ - public: - - /* bad peer notification */ -virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age) = 0; - - /* Friend Tracking */ -virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags) = 0; - - /***** Request Lookup (DHT Peer & Keyword) *****/ -virtual void addFindNode(bdNodeId *id, uint32_t mode) = 0; -virtual void removeFindNode(bdNodeId *id) = 0; -virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode) = 0; - - /***** Connections Requests *****/ -virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) = 0; -virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, - uint32_t bandwidth, uint32_t delay, uint32_t answer) = 0; -virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags) = 0; - -virtual bool setAttachMode(bool on) = 0; - - - /***** Add / Remove Callback Clients *****/ -virtual void addCallback(BitDhtCallback *cb) = 0; -virtual void removeCallback(BitDhtCallback *cb) = 0; - - /***** Get Results Details *****/ -virtual int getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from) = 0; -virtual int getDhtValue(const bdNodeId *id, std::string key, std::string &value) = 0; -virtual int getDhtBucket(const int idx, bdBucket &bucket) = 0; - -virtual int getDhtQueries(std::map &queries) = 0; -virtual int getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query) = 0; - - /* stats and Dht state */ -virtual int startDht() = 0; -virtual int stopDht() = 0; -virtual int stateDht() = 0; /* STOPPED, STARTING, ACTIVE, FAILED */ -virtual uint32_t statsNetworkSize() = 0; -virtual uint32_t statsBDVersionSize() = 0; /* same version as us! */ - -virtual uint32_t setDhtMode(uint32_t dhtFlags) = 0; -}; - - -// general helper functions for decoding error messages. -std::string decodeConnectionError(uint32_t errcode); -std::string decodeConnectionErrorCRMove(uint32_t errcode); -std::string decodeConnectionErrorSource(uint32_t errcode); -std::string decodeConnectionErrorType(uint32_t errcode); - - -#endif - diff --git a/libbitdht/src/bitdht/bdmanager.cc b/libbitdht/src/bitdht/bdmanager.cc deleted file mode 100644 index dadbfb264..000000000 --- a/libbitdht/src/bitdht/bdmanager.cc +++ /dev/null @@ -1,1485 +0,0 @@ -/******************************************************************************* - * bitdht/bdmanager.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/******* - * Node Manager. - ******/ - -/****************************************** - * 1) Maintains a list of ids to search for. - * 2) Sets up initial search for own node. - * 3) Checks on status of queries. - * 4) Callback on successful searches. - * - * This is pretty specific to RS requirements. - ****/ - -#include "bitdht/bdiface.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdmanager.h" -#include "bitdht/bdmsgs.h" -#include "bitdht/bencode.h" -#include "bitdht/bdquerymgr.h" -#include "bitdht/bdfilter.h" - -#include -#include -#include - -#include "util/bdnet.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" - -/*** - * #define DEBUG_MGR 1 - * #define DEBUG_MGR_PKT 1 - ***/ - -//#define DEBUG_MGR 1 - -//#define LOCAL_NET_FLAG (BITDHT_PEER_STATUS_DHT_APPL) -#define LOCAL_NET_FLAG (BITDHT_PEER_STATUS_DHT_ENGINE) -// This is eventually what we want. -//#define LOCAL_NET_FLAG (BITDHT_PEER_STATUS_DHT_ENGINE_VERSION) - -#define QUERY_UPDATE_PERIOD 8 // under refresh period - so it'll happen at the MAX_REFRESH_PERIOD - - -bdNodeManager::bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string bootfile, std::string bootfilebak, const std::string& filterfile, bdDhtFunctions *fns) - :bdNode(id, dhtVersion, bootfile, bootfilebak,filterfile, fns, this) -{ - mMode = BITDHT_MGR_STATE_OFF; - mDhtFns = fns; - mModeTS = 0 ; - mStartTS = 0; - mSearchingDone = false; - mSearchTS = 0; - - mNetworkSize = 0; - mBdNetworkSize = 0; - - std::string bfilter = "edff727f3a49f55c0504ad99d4282f7a26b3f69b59ebc6ca496879c6805a0aa567dffb755f17fdfd44dd24180bf2b61ebfbe68e9a53e79d7893f002140882daf7efbfed66f36eb170064208286040001fbefbbbbef1fa7fdf4a21128d050a208cd3a529a7efdc672c8255130e022b134bc6c77dfbf455d054349c575774d427b"; - - mBloomFilter.setFilterBits(bfilter); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::bdNodeManager() ID: "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - - mLocalNetEnhancements = true; -} - -int bdNodeManager::stopDht() -{ - time_t now = time(NULL); - - /* clean up node */ - shutdownNode(); - - /* flag queries as inactive */ - /* check if exists already */ - std::map::iterator it; - for(it = mActivePeers.begin(); it != mActivePeers.end(); it++) - { - it->second.mStatus = BITDHT_QUERY_READY; - } - - /* set state flag */ - mMode = BITDHT_MGR_STATE_OFF; - mModeTS = now; - - return 1; -} - -int bdNodeManager::startDht() -{ - time_t now = time(NULL); - - /* set startup mode */ - restartNode(); - - mMode = BITDHT_MGR_STATE_STARTUP; - mModeTS = now; - - mStartTS = now; - mSearchingDone = false; - mSearchTS = now; - - return 1; -} - - /* STOPPED, STARTING, ACTIVE, FAILED */ -int bdNodeManager::stateDht() -{ - return mMode; -} - -uint32_t bdNodeManager::statsNetworkSize() -{ - return mNetworkSize; -} - -/* same version as us! */ -uint32_t bdNodeManager::statsBDVersionSize() -{ - return mBdNetworkSize; -} - -uint32_t bdNodeManager::setDhtMode(uint32_t dhtFlags) -{ - /* handle options here? */ - setNodeDhtMode(dhtFlags); - - return dhtFlags; -} - - -bool bdNodeManager::setAttachMode(bool on) -{ - if (on) - { - setNodeOptions(BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT); - } - else - { - setNodeOptions(0); - } - return on; -} - - /* Friend Tracking */ -void bdNodeManager::addBadPeer(const struct sockaddr_in &/*addr*/, uint32_t /*source*/, uint32_t /*reason*/, uint32_t /*age*/) -{ - std::cerr << "bdNodeManager::addBadPeer() not implemented yet!"; - std::cerr << std::endl; -} - -void bdNodeManager::updateKnownPeer(const bdId *id, uint32_t /* type */, uint32_t flags) -{ - mFriendList.updatePeer(id, flags); -} - -void bdNodeManager::addFindNode(bdNodeId *id, uint32_t qflags) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::addFindNode() "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - /* check if exists already */ - std::map::iterator it; - it = mActivePeers.find(*id); - if (it != mActivePeers.end()) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::addFindNode() Found existing...."; - std::cerr << std::endl; -#endif - return; - } - - /* add to map */ - bdQueryPeer peer; - peer.mId.id = (*id); - peer.mStatus = BITDHT_QUERY_READY; //QUERYING; - peer.mQFlags = qflags; - - peer.mDhtAddr.sin_addr.s_addr = 0; - peer.mDhtAddr.sin_port = 0; - - peer.mCallbackTS = 0; - - mActivePeers[*id] = peer; -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::addFindNode() Added QueryPeer as READY...."; - std::cerr << std::endl; -#endif - //addQuery(id, qflags | BITDHT_QFLAGS_DISGUISE); - return; -} - - /* finds a queued query, and starts it */ -void bdNodeManager::startQueries() -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::startQueries() "; - std::cerr << std::endl; -#endif - /* check if exists already */ - std::map::iterator it; - for(it = mActivePeers.begin(); it != mActivePeers.end(); it++) - { - if (it->second.mStatus == BITDHT_QUERY_READY) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::startQueries() Found READY Query."; - std::cerr << std::endl; -#endif - it->second.mStatus = BITDHT_QUERY_QUERYING; - - uint32_t qflags = it->second.mQFlags | BITDHT_QFLAGS_DISGUISE; - mQueryMgr->addQuery(&(it->first), qflags); - - // add all queries at the same time! - //return; - } - } - return; -} - - -void bdNodeManager::removeFindNode(bdNodeId *id) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::removeFindNode() "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - std::map::iterator it; - it = mActivePeers.find(*id); - if (it == mActivePeers.end()) - { - return; - } - - /* cleanup any actions */ - mQueryMgr->clearQuery(&(it->first)); - //clearPing(&(it->first)); - - /* remove from map */ - mActivePeers.erase(it); - return; -} - -void bdNodeManager::iteration() -{ - - time_t now = time(NULL); - time_t modeAge = now - mModeTS; - switch(mMode) - { - case BITDHT_MGR_STATE_OFF: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): OFF"; - std::cerr << std::endl; -#endif - } - break; - - case BITDHT_MGR_STATE_STARTUP: - /* 10 seconds startup .... then switch to ACTIVE */ - - if (modeAge > MAX_STARTUP_TIME) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): STARTUP -> REFRESH"; - std::cerr << std::endl; -#endif - bdNodeId id; - getOwnId(&id); - mQueryMgr->addQuery(&id, BITDHT_QFLAGS_DO_IDLE | BITDHT_QFLAGS_DISGUISE); - - mMode = BITDHT_MGR_STATE_FINDSELF; - mModeTS = now; - } - break; - - case BITDHT_MGR_STATE_FINDSELF: - /* 60 seconds further startup .... then switch to ACTIVE - * if we reach TRANSITION_OP_SPACE_SIZE before this time, transition immediately... - * if, after 60 secs, we haven't reached MIN_OP_SPACE_SIZE, restart.... - */ - -#define TRANSITION_OP_SPACE_SIZE 50 /* 1 query / sec, should take 12-15 secs */ -#define MAX_FINDSELF_TIME 180 /* increased, as std rate has been dropped */ -#define MIN_OP_SPACE_SIZE 10 -// testing parameters. -//#define MAX_FINDSELF_TIME 10 -//#define MIN_OP_SPACE_SIZE 2 // for testing. self + oneother. - - { - uint32_t nodeSpaceSize = mNodeSpace.calcSpaceSize(); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration() Finding Oneself: "; - std::cerr << "NodeSpace Size:" << nodeSpaceSize; - std::cerr << std::endl; -#endif - - if (nodeSpaceSize > TRANSITION_OP_SPACE_SIZE) - { - mMode = BITDHT_MGR_STATE_REFRESH; - mModeTS = now; - } - - if (modeAge > MAX_FINDSELF_TIME) - { - if (nodeSpaceSize >= MIN_OP_SPACE_SIZE) - { - mMode = BITDHT_MGR_STATE_REFRESH; - mModeTS = now; - } - else - { - mMode = BITDHT_MGR_STATE_FAILED; - mModeTS = now; - } - } - } - - break; - - case BITDHT_MGR_STATE_ACTIVE: - if (modeAge >= MAX_REFRESH_TIME) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): ACTIVE -> REFRESH"; - std::cerr << std::endl; -#endif - mMode = BITDHT_MGR_STATE_REFRESH; - mModeTS = now; - } - - break; - - case BITDHT_MGR_STATE_REFRESH: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): REFRESH -> ACTIVE"; - std::cerr << std::endl; -#endif - /* select random ids, and perform searchs to refresh space */ - mMode = BITDHT_MGR_STATE_ACTIVE; - mModeTS = now; - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): Starting Query"; - std::cerr << std::endl; -#endif - - startQueries(); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): Updating Stores"; - std::cerr << std::endl; -#endif - - updateStore(); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): Cleaning up Filter (should do less frequently)"; - std::cerr << std::endl; -#endif - - mFilterPeers.cleanupFilter(); - - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): Do App Search"; - std::cerr << std::endl; -#endif - - - /* This stuff is only important for "LocalNet based Features */ - if (mLocalNetEnhancements) - { - /* run a random search for ourselves, from own App DHT peer */ - QueryRandomLocalNet(); - -#define SEARCH_MAX_SIZE 10 - if (mBdNetworkSize < SEARCH_MAX_SIZE) - { -#ifdef DEBUG_MGR - std::cerr << "Local Netsize: " << mBdNetworkSize << " to small...searching"; - std::cerr << std::endl; -#endif - - /* if the network size is very small */ - SearchForLocalNet(); - mSearchingDone = false; - } - else - { - if (!mSearchingDone) - { - mSearchingDone = true; - mSearchTS = now; -#ifdef DEBUG_MGR - std::cerr << "Completed LocalNet Search in : " << mSearchTS-mStartTS; - std::cerr << std::endl; -#endif - } - } - } - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): REFRESH "; - std::cerr << std::endl; -#endif - - status(); /* calculates mNetworkSize */ - -#ifdef DEBUG_MGR - mAccount.printStats(std::cerr); -#endif - - /* Finally, Fail, and restart if we lose all peers */ - uint32_t nodeSpaceSize = mNodeSpace.calcSpaceSize(); - if (nodeSpaceSize < MIN_OP_SPACE_SIZE) - { - std::cerr << "bdNodeManager::iteration(): SpaceSize to Small: " << nodeSpaceSize; - std::cerr << std::endl; - std::cerr << "bdNodeManager::iteration(): REFRESH ==> FAILED"; - std::cerr << std::endl; - - mMode = BITDHT_MGR_STATE_FAILED; - mModeTS = now; - } - } - break; - - case BITDHT_MGR_STATE_QUIET: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::iteration(): QUIET"; - std::cerr << std::endl; -#endif - - - } - break; - - default: - case BITDHT_MGR_STATE_FAILED: - { - std::cerr << "bdNodeManager::iteration(): FAILED ==> STARTUP"; - std::cerr << std::endl; -#ifdef DEBUG_MGR -#endif - stopDht(); - startDht(); - } - break; - } - - if (mMode == BITDHT_MGR_STATE_OFF) - { - bdNode::iterationOff(); - } - else - { - /* tick parent */ - bdNode::iteration(); - } -} - - /* NB: This is a bit of a hack, the code is duplicated from bdnode & bdquery. - * should use fn calls into their functions for good generality - */ - -#define RANDOM_SEARCH_FRAC (0.1) - -int bdNodeManager::QueryRandomLocalNet() -{ - bdId id; - bdNodeId targetNodeId; - - uint32_t withFlag = LOCAL_NET_FLAG; - if (mNodeSpace.findRandomPeerWithFlag(id, withFlag)) - { - /* if we've got a very small network size... then ask them about a random peer. - * (so we get there 159/158 boxes! - */ - bool isRandom = false; - if ((mBdNetworkSize < SEARCH_MAX_SIZE) || (RANDOM_SEARCH_FRAC > bdRandom::random_f32())) - { - bdStdRandomNodeId(&targetNodeId); - isRandom = true; - } - else - { - /* calculate mid point */ - mDhtFns->bdRandomMidId(&mOwnId, &(id.id), &targetNodeId); - } - - /* do standard find_peer message */ - mQueryMgr->addWorthyPeerSource(&id); /* Tell BitDHT that we really want to ping their peers */ - send_query(&id, &targetNodeId, true); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::QueryRandomLocalNet() Querying : "; - mDhtFns->bdPrintId(std::cerr, &id); - std::cerr << " searching for : "; - mDhtFns->bdPrintNodeId(std::cerr, &targetNodeId); - - bdMetric dist; - mDhtFns->bdDistance(&targetNodeId, &(mOwnId), &dist); - int bucket = mDhtFns->bdBucketDistance(&dist); - std::cerr << " in Bucket: " << bucket; - std::cerr << std::endl; -#endif - - if (isRandom) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::QueryRandomLocalNet() Search is Random!"; - std::cerr << std::endl; -#endif - } - - return 1; - } - else - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::QueryRandomLocalNet() No LocalNet Peer Found"; - std::cerr << std::endl; -#endif - } - - return 0; -} - - - -void bdNodeManager::SearchForLocalNet() -{ - - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchForLocalNet()"; - std::cerr << std::endl; -#endif - - /* Check how many "Search Queries" we've got going. */ - - /* check queries */ - std::map::iterator it; - std::map queryStatus; - - - mQueryMgr->QueryStatus(queryStatus); - - int numSearchQueries = 0; - for(it = queryStatus.begin(); it != queryStatus.end(); it++) - { - if (it->second.mQFlags & BITDHT_QFLAGS_INTERNAL) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchForLocalNet() Existing Internal Search: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - - numSearchQueries++; - } - } - -#define MAX_SEARCH_QUERIES 5 - - for(;numSearchQueries < MAX_SEARCH_QUERIES; numSearchQueries++) - { - /* install a new query */ - bdNodeId targetNodeId; - - /* get something that filter approves of */ - bool filterOk = false; - int i; - -#define MAX_FILTER_ATTEMPTS 3000 - - for(i = 0; (!filterOk) && (i < MAX_FILTER_ATTEMPTS); i++) - { - bdStdRandomNodeId(&targetNodeId); - std::string tststr; - bdStdPrintNodeId(tststr, &targetNodeId, false); - - if (mBloomFilter.test(tststr)) - { - filterOk = true; - } - } - - if (filterOk) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchForLocalNet() " << i << " Attempts to find OkNode: "; - mDhtFns->bdPrintNodeId(std::cerr, &targetNodeId); - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchForLocalNet() Failed to Find FilterOk this time: "; - mDhtFns->bdPrintNodeId(std::cerr, &targetNodeId); - std::cerr << std::endl; -#endif - } - - - uint32_t qflags = BITDHT_QFLAGS_INTERNAL | BITDHT_QFLAGS_DISGUISE; - mQueryMgr->addQuery(&targetNodeId, qflags); - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchForLocalNet() Adding New Internal Search: "; - mDhtFns->bdPrintNodeId(std::cerr, &(targetNodeId)); - std::cerr << std::endl; -#endif - } -} - - -int bdNodeManager::status() -{ - /* do status of bdNode */ -#ifdef DEBUG_MGR - printState(); -#endif - - checkStatus(); - checkBadPeerStatus(); - - /* update the network numbers */ - mNetworkSize = mNodeSpace.calcNetworkSize(); - mBdNetworkSize = mNodeSpace.calcNetworkSizeWithFlag( - LOCAL_NET_FLAG); - -#ifdef DEBUG_MGR - std::cerr << "BitDHT NetworkSize: " << mNetworkSize << std::endl; - std::cerr << "BitDHT App NetworkSize: " << mBdNetworkSize << std::endl; -#endif - - return 1; -} - - -int bdNodeManager::checkStatus() -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus()"; - std::cerr << std::endl; -#endif - - /* check queries */ - std::map::iterator it; - std::map queryStatus; - - - mQueryMgr->QueryStatus(queryStatus); - - for(it = queryStatus.begin(); it != queryStatus.end(); it++) - { - bool doPing = false; - bool doRemove = false; - bool doCallback = false; - bool doSaveAddress = false; - uint32_t callbackStatus = 0; - - switch(it->second.mStatus) - { - default: - case BITDHT_QUERY_QUERYING: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Query in Progress id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - } - break; - - case BITDHT_QUERY_FAILURE: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Query Failed: id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - // BAD. - doRemove = true; - doCallback = true; - callbackStatus = BITDHT_MGR_QUERY_FAILURE; - } - break; - - case BITDHT_QUERY_FOUND_CLOSEST: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Found Closest: id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - - doRemove = true; - doCallback = true; - callbackStatus = BITDHT_MGR_QUERY_PEER_OFFLINE; - } - break; - - case BITDHT_QUERY_PEER_UNREACHABLE: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() the Peer Online but Unreachable: id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - - doRemove = true; - doCallback = true; - callbackStatus = BITDHT_MGR_QUERY_PEER_UNREACHABLE; - } - break; - - case BITDHT_QUERY_SUCCESS: - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Found Query: id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - //foundId = - doRemove = true; - doCallback = true; - doSaveAddress = true; - callbackStatus = BITDHT_MGR_QUERY_PEER_ONLINE; - } - break; - } - - /* remove done queries */ - if (doRemove) - { - if (it->second.mQFlags & BITDHT_QFLAGS_DO_IDLE) - { - doRemove = false; - } - } - - if (doRemove) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Removing query: id: "; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - mQueryMgr->clearQuery(&(it->first)); - } - - /* FIND in activePeers */ - std::map::iterator pit; - pit = mActivePeers.find(it->first); - - if (pit == mActivePeers.end()) - { - /* only internal! - disable Callback / Ping */ - doPing = false; - doCallback = false; -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Internal: no cb for id: "; - mDhtFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - } - else - { - if (pit->second.mStatus == it->second.mStatus) - { - /* status is unchanged */ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Status unchanged for : "; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << " status: " << it->second.mStatus; - std::cerr << std::endl; -#endif - - - time_t now = time(NULL); - /* now we check if we've done a callback before... */ - if (it->second.mQFlags & BITDHT_QFLAGS_UPDATES) - { - if (now - pit->second.mCallbackTS > QUERY_UPDATE_PERIOD) - { - // keep flags. -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Doing Update Callback for"; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << " status: " << it->second.mStatus; - std::cerr << std::endl; -#endif - } - else - { - /* no callback this time */ - doPing = false; - doCallback = false; - } - } - else - { - doPing = false; - doCallback = false; - } - } - else - { - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Updating External Status for : "; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << " to: " << it->second.mStatus; - std::cerr << std::endl; -#endif - /* update status */ - pit->second.mStatus = it->second.mStatus; - } - - if (doSaveAddress) - { - if (it->second.mResults.size() > 0) - { - pit->second.mDhtAddr = it->second.mResults.front().addr; - } - else - { - pit->second.mDhtAddr.sin_addr.s_addr = 0; - pit->second.mDhtAddr.sin_port = 0; - } - } - - /* add successful queries to ping list */ - if (doPing) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Starting Ping (TODO): id: "; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - /* add first matching peer */ - //addPeerPing(foundId); - } - - /* callback on new successful queries */ - if (doCallback) - { -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::checkStatus() Doing Callback: id: "; - mFns->bdPrintNodeId(std::cerr, &(it->first)); - std::cerr << std::endl; -#endif - - time_t now = time(NULL); - pit->second.mCallbackTS = now; - bdId id(it->first,pit->second.mDhtAddr); - doPeerCallback(&id, callbackStatus); - } - } - } - return 1; -} - -#if 0 -bdNodeManager::checkPingStatus() -{ - - /* check queries */ - std::map::iterator it; - std::map pingStatus; - - PingStatus(pingStatus); - - for(it = pingStatus.begin(); it != pingStatus.end(); it++) - { - switch(it->second.mStatus) - { - case BITDHT_QUERY_QUERYING: - { - - } - break; - - case BITDHT_QUERY_FAILURE: - { - // BAD. - doRemove = true; - } - break; - - case BITDHT_QUERY_FOUND_CLOSEST: - { - - doRemove = true; - } - break; - - case BITDHT_QUERY_SUCCESS: - { - foundId = - doRemove = true; - } - break; - } - - /* remove done queries */ - if (doRemove) - { - clearQuery(it->first); - } - - /* add successful queries to ping list */ - if (doPing) - { - /* add first matching peer */ - addPeerPing(foundId); - } - - /* callback on new successful queries */ - if (doCallback) - { - - } - } -} -#endif - -int bdNodeManager::checkBadPeerStatus() -{ - bdId id; - uint32_t flags; - std::string nullstr; - - while(mBadPeerQueue.popPeer(&id, flags)) - { - doInfoCallback(&id, BITDHT_INFO_CB_TYPE_BADPEER, flags, nullstr); - } - return 1; -} - -int bdNodeManager::SearchOutOfDate() -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::SearchOutOfDate()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - - /* search for out-of-date peers */ - for(it = mActivePeers.begin(); it != mActivePeers.end(); it++) - { -#if 0 - if (old) - { - addQuery(it->first); - } -#endif - } - - return 1; -} - - - - /***** Functions to Call down to bdNodeManager ****/ - /* Request DHT Peer Lookup */ - /* Request Keyword Lookup */ - -void bdNodeManager::findDhtValue(bdNodeId * /*id*/, std::string /*key*/, uint32_t /*mode*/) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::findDhtValue() TODO"; - std::cerr << std::endl; -#endif -} - - - /***** Get Results Details *****/ -int bdNodeManager::getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::getDhtPeerAddress() Id: "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << " ... ? TODO" << std::endl; -#else - (void) id; -#endif - - std::map::iterator pit; - pit = mActivePeers.find(*id); - - std::cerr << "bdNodeManager::getDhtPeerAddress() Id: "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << std::endl; - - if (pit != mActivePeers.end()) - { - std::cerr << "bdNodeManager::getDhtPeerAddress() Found ActiveQuery"; - std::cerr << std::endl; - - if (pit->second.mStatus == BITDHT_QUERY_SUCCESS) - { - from = pit->second.mDhtAddr; - - std::cerr << "bdNodeManager::getDhtPeerAddress() Found Peer Address:"; - std::cerr << bdnet_inet_ntoa(from.sin_addr) << ":" << htons(from.sin_port); - std::cerr << std::endl; - - return 1; - } - } - return 0; - -} - -int bdNodeManager::getDhtValue(const bdNodeId *id, std::string key, std::string & /*value*/) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::getDhtValue() Id: "; - mDhtFns->bdPrintNodeId(std::cerr, id); - std::cerr << " key: " << key; - std::cerr << " ... ? TODO" << std::endl; -#else - (void) id; - (void) key; -#endif - - return 1; -} - -int bdNodeManager::getDhtBucket(const int idx, bdBucket &bucket) -{ - return mNodeSpace.getDhtBucket(idx, bucket); -} - -int bdNodeManager::getDhtQueries(std::map &queries) -{ - mQueryMgr->QueryStatus(queries); - return 1; -} - -int bdNodeManager::getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query) -{ - return mQueryMgr->QuerySummary(id, query); -} - - - /***** Add / Remove Callback Clients *****/ -void bdNodeManager::addCallback(BitDhtCallback *cb) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::addCallback()"; - std::cerr << std::endl; -#endif - /* search list */ - std::list::iterator it; - it = std::find(mCallbacks.begin(), mCallbacks.end(), cb); - if (it == mCallbacks.end()) - { - /* add it */ - mCallbacks.push_back(cb); - } -} - -void bdNodeManager::removeCallback(BitDhtCallback *cb) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::removeCallback()"; - std::cerr << std::endl; -#endif - /* search list */ - std::list::iterator it; - it = std::find(mCallbacks.begin(), mCallbacks.end(), cb); - if (it == mCallbacks.end()) - { - /* not found! */ - return; - } - it = mCallbacks.erase(it); -} - - -void bdNodeManager::addPeer(const bdId *id, uint32_t peerflags) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::addPeer() Overloaded (doing Callback)"; - std::cerr << std::endl; -#endif - doNodeCallback(id, peerflags); - - // call parent. - bdNode::addPeer(id, peerflags); - - return; -} - - - -void bdNodeManager::doNodeCallback(const bdId *id, uint32_t peerflags) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::doNodeCallback() "; - mDhtFns->bdPrintId(std::cerr, id); - std::cerr << "peerflags: " << peerflags; - std::cerr << std::endl; -#endif - - /* search list */ - std::list::iterator it; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - (*it)->dhtNodeCallback(id, peerflags); - } - return; -} - -void bdNodeManager::doPeerCallback(const bdId *id, uint32_t status) -{ - -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::doPeerCallback()"; - mDhtFns->bdPrintId(std::cerr, id); - std::cerr << "status: " << status; - std::cerr << std::endl; -#endif - - /* search list */ - std::list::iterator it; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - (*it)->dhtPeerCallback(id, status); - } - return; -} - -void bdNodeManager::doValueCallback(const bdNodeId *id, std::string key, uint32_t status) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::doValueCallback()"; - std::cerr << std::endl; -#endif - /* search list */ - std::list::iterator it; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - (*it)->dhtValueCallback(id, key, status); - } - return; -} - - -void bdNodeManager::doInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::doInfoCallback()"; - std::cerr << std::endl; -#endif - /* search list */ - std::list::iterator it; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - (*it)->dhtInfoCallback(id, type, flags, info); - } - return; -} - -void bdNodeManager::doIsBannedCallback(const sockaddr_in *addr, bool *isAvailable, bool *isBanned) -{ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::doIsBannedCallback()"; - std::cerr << std::endl; -#endif - /* search list */ - std::list::iterator it; - *isBanned = false; - *isAvailable = false; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - // set isBanned to true as soon as one callback answers with true - bool banned; - if((*it)->dhtIsBannedCallback(addr, &banned)) - { - *isBanned = *isBanned || banned; - *isAvailable = true; - } - } -} - - -#define BITDHT_IDENTITY_STRING_V1 "d1:" -#define BITDHT_IDENTITY_SIZE_V1 3 -#define BITDHT_PACKET_MIN_SIZE 4 - - /******************* Internals *************************/ -int bdNodeManager::isBitDhtPacket(char *data, int size, struct sockaddr_in & from) - -{ - - /* use a very simple initial check */ - if (size < BITDHT_PACKET_MIN_SIZE) - return 0; - - return (0 == strncmp(data, BITDHT_IDENTITY_STRING_V1, BITDHT_IDENTITY_SIZE_V1)); - - /* Below is the old version! */ - - -#ifdef DEBUG_MGR_PKT - std::cerr << "bdNodeManager::isBitDhtPacket() *******************************"; - std::cerr << " from " << inet_ntoa(from.sin_addr); - std::cerr << ":" << ntohs(from.sin_port); - std::cerr << std::endl; - { - /* print the fucker... only way to catch bad ones */ - std::string out; - for(int i = 0; i < size; i++) - { - if (isascii(data[i])) - { - out += data[i]; - } - else - { - bd_sprintf_append(out, "[%02lx]", (uint32_t) data[i]); - } - if ((i % 16 == 0) && (i != 0)) - { - out += "\n"; - } - } - std::cerr << out; - } - std::cerr << "bdNodeManager::isBitDhtPacket() *******************************"; - std::cerr << std::endl; -#else - (void) from; -#endif - - /* try to parse it! */ - /* convert to a be_node */ - be_node *node = be_decoden(data, size); - if (!node) - { - /* invalid decode */ -#ifdef DEBUG_MGR - std::cerr << "bdNodeManager::isBitDhtPacket() be_decode failed. dropping"; - std::cerr << std::endl; - std::cerr << "bdNodeManager::BadPacket ******************************"; - std::cerr << " from " << inet_ntoa(from.sin_addr); - std::cerr << ":" << ntohs(from.sin_port); - std::cerr << std::endl; - { - /* print the fucker... only way to catch bad ones */ - std::string out; - for(int i = 0; i < size; i++) - { - if (isascii(data[i])) - { - out += data[i]; - } - else - { - bd_sprintf_append(out, "[%02lx]", (uint32_t) data[i]); - } - if ((i % 16 == 0) && (i != 0)) - { - out += "\n"; - } - } - std::cerr << out; - } - std::cerr << "bdNodeManager::BadPacket ******************************"; - std::cerr << std::endl; -#endif - return 0; - } - - /* find message type */ - uint32_t beType = beMsgType(node); - int ans = (beType != BITDHT_MSG_TYPE_UNKNOWN); - be_free(node); - -#ifdef DEBUG_MGR_PKT - if (ans) - { - std::cerr << "bdNodeManager::isBitDhtPacket() YES"; - std::cerr << std::endl; - } - else - { - std::cerr << "bdNodeManager::isBitDhtPacket() NO: Unknown Type"; - std::cerr << std::endl; - } - -#endif - return ans; -} - - -bdDebugCallback::~bdDebugCallback() -{ -} - -int bdDebugCallback::dhtPeerCallback(const bdId *id, uint32_t status) -{ - /* remove unused parameter warnings */ - (void) status; - -#ifdef DEBUG_MGR - std::cerr << "bdDebugCallback::dhtPeerCallback() Id: "; -#endif - bdStdPrintId(std::cerr, id); -#ifdef DEBUG_MGR - std::cerr << " status: " << std::hex << status << std::dec << std::endl; -#endif - return 1; -} - -int bdDebugCallback::dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status) -{ - /* remove unused parameter warnings */ - (void) key; - (void) status; - -#ifdef DEBUG_MGR - std::cerr << "bdDebugCallback::dhtValueCallback() Id: "; -#endif - bdStdPrintNodeId(std::cerr, id); -#ifdef DEBUG_MGR - std::cerr << " key: " << key; - std::cerr << " status: " << std::hex << status << std::dec << std::endl; -#endif - - return 1; -} - - - - - -/******************* Connection Stuff ********************/ - - - -bool bdNodeManager::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) -{ - std::cerr << "bdNodeManager::ConnectionRequest()"; - std::cerr << std::endl; - - return mConnMgr->requestConnection(laddr, target, mode, delay, start); -} - -void bdNodeManager::ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, uint32_t bandwidth, uint32_t delay, uint32_t answer) -{ - std::cerr << "bdNodeManager::ConnectionAuth()"; - std::cerr << std::endl; - - if (answer == BITDHT_CONNECT_ANSWER_OKAY) - { - mConnMgr->AuthConnectionOk(srcId, proxyId, destId, mode, loc, bandwidth, delay); - } - else - { - mConnMgr->AuthConnectionNo(srcId, proxyId, destId, mode, loc, answer); - } -} - -void bdNodeManager::ConnectionOptions(uint32_t allowedModes, uint32_t flags) -{ - mConnMgr->setConnectionOptions(allowedModes, flags); -} - - - /***** Connections Requests *****/ - - // Overloaded from bdnode for external node callback. -void bdNodeManager::callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, int mode, int point, int param, int cbtype, int errcode) -{ - std::cerr << "bdNodeManager::callbackConnect()"; - std::cerr << std::endl; - -#ifdef DEBUG_MGR -#endif - /* search list */ - std::list::iterator it; - for(it = mCallbacks.begin(); it != mCallbacks.end(); it++) - { - (*it)->dhtConnectCallback(srcId, proxyId, destId, mode, point, param, cbtype, errcode); - } - return; -} - -int bdDebugCallback::dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) -{ - /* remove unused parameter warnings */ - (void) srcId; - (void) proxyId; - (void) destId; - (void) mode; - (void) point; - (void) param; - (void) cbtype; - (void) errcode; - -#ifdef DEBUG_MGR - std::cerr << "bdDebugCallback::dhtConnectCallback() Type: " << cbtype; - std::cerr << " errCode: " << errcode; - std::cerr << " srcId: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << " proxyId: "; - bdStdPrintId(std::cerr, proxyId); - std::cerr << " destId: "; - bdStdPrintId(std::cerr, destId); - std::cerr << " mode: " << mode; - std::cerr << " param: " << param; - std::cerr << " point: " << point << std::endl; -#endif - - return 1; -} - - -int bdDebugCallback::dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info) -{ - /* remove unused parameter warnings */ - (void) id; - (void) type; - (void) flags; - (void) info; - -#ifdef DEBUG_MGR - std::cerr << "bdDebugCallback::dhtInfoCallback() Type: " << type; - std::cerr << " Id: "; - bdStdPrintId(std::cerr, id); - std::cerr << " flags: " << flags; - std::cerr << " info: " << info; - std::cerr << std::endl; -#endif - - return 1; -} - - - diff --git a/libbitdht/src/bitdht/bdmanager.h b/libbitdht/src/bitdht/bdmanager.h deleted file mode 100644 index e1440c154..000000000 --- a/libbitdht/src/bitdht/bdmanager.h +++ /dev/null @@ -1,209 +0,0 @@ -/******************************************************************************* - * bitdht/bdmanager.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_MANAGER_H -#define BITDHT_MANAGER_H - -/******* - * Node Manager. - ******/ - -/****************************************** - * 1) Maintains a list of ids to search for. - * 2) Sets up initial search for own node. - * 3) Checks on status of queries. - * 4) Callback on successful searches. - * - * This is pretty specific to RS requirements. - ****/ - -#define BITDHT_PS_MASK_ACTIONS (0x000000ff) -#define BITDHT_PS_MASK_STATE (0x0000ff00) - -#define BITDHT_PS_ACTION_SEARCHING (0x00000001) -#define BITDHT_PS_ACTION_WAITING (0x00000002) -#define BITDHT_PS_ACTION_PINGING (0x00000004) - -#define BITDHT_PS_STATE_UNKNOWN (0x00000100) -#define BITDHT_PS_STATE_OFFLINE (0x00000200) -#define BITDHT_PS_STATE_ONLINE (0x00000400) -#define BITDHT_PS_STATE_CONNECTED (0x00000800) - -#include "bitdht/bdiface.h" -#include "bitdht/bdnode.h" -#include "util/bdbloom.h" - - - -class bdQueryPeer -{ - public: - bdId mId; - uint32_t mStatus; - uint32_t mQFlags; - //time_t mLastQuery; - //time_t mLastFound; - struct sockaddr_in mDhtAddr; - time_t mCallbackTS; // for UPDATES flag. -}; - - -#define BITDHT_MGR_STATE_OFF 0 -#define BITDHT_MGR_STATE_STARTUP 1 -#define BITDHT_MGR_STATE_FINDSELF 2 -#define BITDHT_MGR_STATE_ACTIVE 3 -#define BITDHT_MGR_STATE_REFRESH 4 -#define BITDHT_MGR_STATE_QUIET 5 -#define BITDHT_MGR_STATE_FAILED 6 - -#define MAX_STARTUP_TIME 10 -#define MAX_REFRESH_TIME 10 - -#define BITDHT_MGR_QUERY_FAILURE 1 -#define BITDHT_MGR_QUERY_PEER_OFFLINE 2 -#define BITDHT_MGR_QUERY_PEER_UNREACHABLE 3 -#define BITDHT_MGR_QUERY_PEER_ONLINE 4 - - -/*** NB: Nothing in here is protected by mutexes - * must be done at a higher level! - ***/ - -class bdNodeManager: public bdNode, public BitDhtInterface -{ - public: - bdNodeManager(bdNodeId *id, std::string dhtVersion, std::string bootfile, std::string bootfilebak, const std::string &filterfile, bdDhtFunctions *fns); - - -void iteration(); - - /***** Functions to Call down to bdNodeManager ****/ - - - /* Friend Tracking */ -virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age); -virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags); - - /* Request DHT Peer Lookup */ - /* Request Keyword Lookup */ -virtual void addFindNode(bdNodeId *id, uint32_t mode); -virtual void removeFindNode(bdNodeId *id); -virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode); - - /***** Add / Remove Callback Clients *****/ -virtual void addCallback(BitDhtCallback *cb); -virtual void removeCallback(BitDhtCallback *cb); - - /***** Get Results Details *****/ -virtual int getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from); -virtual int getDhtValue(const bdNodeId *id, std::string key, std::string &value); -virtual int getDhtBucket(const int idx, bdBucket &bucket); - -virtual int getDhtQueries(std::map &queries); -virtual int getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query); - - /***** Connection Interface ****/ -virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start); -virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, - uint32_t mode, uint32_t loc, uint32_t bandwidth, uint32_t delay, uint32_t answer); -virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags); - -virtual bool setAttachMode(bool on); - - /* stats and Dht state */ -virtual int startDht(); -virtual int stopDht(); -virtual int stateDht(); /* STOPPED, STARTING, ACTIVE, FAILED */ -virtual uint32_t statsNetworkSize(); -virtual uint32_t statsBDVersionSize(); /* same version as us! */ - -virtual uint32_t setDhtMode(uint32_t dhtFlags); - - /******************* Internals *************************/ - - // Overloaded from bdnode for external node callback. -virtual void addPeer(const bdId *id, uint32_t peerflags); - // Overloaded from bdnode for external node callback. -virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode); - -int isBitDhtPacket(char *data, int size, struct sockaddr_in &from); - - // this function is used by bdFilter (must be public!) -void doIsBannedCallback(const sockaddr_in *addr, bool *isAvailable, bool* isBanned); - -private: - - -void doNodeCallback(const bdId *id, uint32_t peerflags); -void doPeerCallback(const bdId *id, uint32_t status); -void doValueCallback(const bdNodeId *id, std::string key, uint32_t status); -void doInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info); - -int status(); -int checkStatus(); -int checkPingStatus(); -int checkBadPeerStatus(); -int SearchOutOfDate(); -void startQueries(); - -int QueryRandomLocalNet(); -void SearchForLocalNet(); - - std::map mActivePeers; - std::list mCallbacks; - - uint32_t mMode; - time_t mModeTS; - - time_t mStartTS; - time_t mSearchTS; - bool mSearchingDone; - - bdDhtFunctions *mDhtFns; - - uint32_t mNetworkSize; - uint32_t mBdNetworkSize; - - bdBloom mBloomFilter; - - bool mLocalNetEnhancements; - - /* future node functions */ - //addPeerPing(foundId); - //clearPing(it->first); - //PingStatus(it->first); -}; - -class bdDebugCallback: public BitDhtCallback -{ - public: - ~bdDebugCallback(); -virtual int dhtPeerCallback(const bdId *id, uint32_t status); -virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status); -virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode); -virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info); - -}; - - -#endif diff --git a/libbitdht/src/bitdht/bdmsgs.cc b/libbitdht/src/bitdht/bdmsgs.cc deleted file mode 100644 index 07114dbab..000000000 --- a/libbitdht/src/bitdht/bdmsgs.cc +++ /dev/null @@ -1,1087 +0,0 @@ -/******************************************************************************* - * bitdht/bdmsgs.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include "bitdht/bencode.h" -#include "bitdht/bdmsgs.h" - - -int create_ping_message(); -int response_ping_message(); - -int find_node_message(); -int response_node_message(); - -int get_peers_message(); -int response_peers_message(); -int response_closestnodes_message(); - - /* -ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}} -bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe - */ - -/**** - * #define DEBUG_MSG_DUMP 1 - * #define DEBUG_MSG_TYPE 1 - * #define DEBUG_MSGS 1 - ****/ - - -int bitdht_create_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid, char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_create_ping_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - be_add_keypair(iddict, "id", idnode); - - be_node *pingnode = be_create_str("ping"); - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *qynode = be_create_str("q"); - - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "q", pingnode); - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", qynode); - - if (vid) - { - be_node *vnode = be_create_str_wlen((char *) vid->data, vid->len); - be_add_keypair(dict, "v", vnode); - } - - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; - - -} - - - /* -Response = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} -bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re - */ - -int bitdht_response_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_response_ping_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("r"); - - be_node *vnode = be_create_str_wlen((char *) vid->data, vid->len); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(dict, "r", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "v", vnode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - /* -find_node Query = {"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}} -bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe - */ - - -int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target, bool localoption, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_find_node_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - be_node *targetnode = be_create_str_wlen((char *) target->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("q"); - be_node *findnode = be_create_str("find_node"); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(iddict, "target", targetnode); - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "q", findnode); - - if (localoption) - { - be_node *optionnode = be_create_str("l"); - be_add_keypair(dict, "o", optionnode); - } - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - - /* -Response = {"t":"aa", "y":"r", "r": {"id":"0123456789abcdefghij", "nodes": "def456..."}} -bencoded = d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re - */ - -int bitdht_resp_node_msg(bdToken *tid, bdNodeId *id, std::list &nodes, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_resp_node_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *replydict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - - be_node *peersnode = makeCompactNodeIdString(nodes); - - be_node *yqrnode = be_create_str("r"); - - be_add_keypair(replydict, "id", idnode); - be_add_keypair(replydict, "nodes", peersnode); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "r", replydict); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - -#ifdef DEBUG_MSG_DUMP - fprintf(stderr, "bitdht_resp_node_msg() len = %d / %d\n", blen, avail); -#endif - - return blen; -} - - - /* -get_peers Query = {"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456"}} -bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe - */ - -int bitdht_get_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_get_peers_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - be_node *hashnode = be_create_str_wlen((char *) info_hash->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("q"); - be_node *findnode = be_create_str("get_peers"); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(iddict, "info_hash", hashnode); - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "q", findnode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - /* -Response with peers = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}} -bencoded = d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re - */ - -int bitdht_peers_reply_hash_msg(bdToken *tid, bdNodeId *id, - bdToken *token, std::list &values, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_peers_reply_hash_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *replydict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *tokennode = be_create_str_wlen((char *) token->data, token->len); - be_node *valuesnode = makeCompactPeerIds(values); - - be_node *yqrnode = be_create_str("r"); - - be_add_keypair(replydict, "id", idnode); - be_add_keypair(replydict, "token", tokennode); - be_add_keypair(replydict, "values", valuesnode); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "r", replydict); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - /** - -Response with closest nodes = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."}} -bencoded = d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re - - **/ - - -int bitdht_peers_reply_closest_msg(bdToken *tid, bdNodeId *id, - bdToken *token, std::list &nodes, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_peers_reply_closest_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *replydict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *tokennode = be_create_str_wlen((char *) token->data, token->len); - - be_node *peersnode = makeCompactNodeIdString(nodes); - - be_node *yqrnode = be_create_str("r"); - - be_add_keypair(replydict, "id", idnode); - be_add_keypair(replydict, "token", tokennode); - be_add_keypair(replydict, "nodes", peersnode); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "r", replydict); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - -/**** FINAL TWO MESSAGES! ***/ - -/**** -announce_peers Query = {"t":"aa", "y":"q", "q":"announce_peer", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456", "port": 6881, "token": "aoeusnth"}} -bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe - -****/ - -int bitdht_announce_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash, uint32_t port, bdToken *token, char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_announce_peers_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - be_node *iddict = be_create_dict(); - - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - be_node *hashnode = be_create_str_wlen((char *) info_hash->data, BITDHT_KEY_LEN); - be_node *portnode = be_create_int(port); - be_node *tokennode = be_create_str_wlen((char *) token->data, token->len); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(iddict, "info_hash", hashnode); - be_add_keypair(iddict, "port", portnode); - be_add_keypair(iddict, "token", tokennode); - - be_node *announcenode = be_create_str("announce_peer"); - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *qynode = be_create_str("q"); - - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "q", announcenode); - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", qynode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; - -} - - -/***** -Response to Announce Peers = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} -bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re -****/ - -/**** - * NB: This is the same as a PONG msg! - ***/ - -int bitdht_reply_announce_msg(bdToken *tid, bdNodeId *id, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_response_ping_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("r"); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(dict, "r", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - -/************************ Parsing Messages ********************* - * - */ - -be_node *beMsgGetDictNode(be_node *node, const char *key) -{ - /* make sure its a dictionary */ - if (node->type != BE_DICT) - { - return NULL; - } - - /* get dictionary entry 'y' */ - int i; - for(i = 0; node->val.d[i].val; i++) - { - if (0 == strcmp(key, node->val.d[i].key)) - { - return node->val.d[i].val; - } - } - return NULL; -} - - - -int beMsgMatchString(be_node *n, const char *str, int len) -{ - if (n->type != BE_STR) - { - return 0; - } - if (len != be_str_len(n)) - { - return 0; - } - - int i; - for(i = 0; i < len; i++) - { - if (n->val.s[i] != str[i]) - return 0; - } - return 1; -} - - -uint32_t beMsgGetY(be_node *n) -{ - be_node *val = beMsgGetDictNode(n, "y"); - - if(val == NULL) - return BE_Y_UNKNOWN ; - - if (val->type != BE_STR) - { - return BE_Y_UNKNOWN; - } - - if (val->val.s[0] == 'q') - { - return BE_Y_Q; - } - else if (val->val.s[0] == 'r') - { - return BE_Y_R; - } - - return BE_Y_UNKNOWN; -} - - - -uint32_t beMsgType(be_node *n) -{ - /* check for - * y: q or r - */ - uint32_t beY = beMsgGetY(n); - -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() beY: " << beY << std::endl; -#endif - - if (beY == BE_Y_UNKNOWN) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() UNKNOWN MSG TYPE" << std::endl; -#endif - - return BITDHT_MSG_TYPE_UNKNOWN; - } - - if (beY == BE_Y_Q) /* query */ - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY MSG TYPE" << std::endl; -#endif - be_node *query = beMsgGetDictNode(n, "q"); - - if(query == NULL) - return BITDHT_MSG_TYPE_UNKNOWN; - - if (beMsgMatchString(query, "ping", 4)) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:ping MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_PING; - } - else if (beMsgMatchString(query, "find_node", 9)) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:find_node MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_FIND_NODE; - } - else if (beMsgMatchString(query, "get_peers", 9)) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:get_peers MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_GET_HASH; - } - else if (beMsgMatchString(query, "announce_peer", 13)) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:announce_peer MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_POST_HASH; - } - else if (beMsgMatchString(query, "connect", 7)) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:connect MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_CONNECT; - } -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() QUERY:UNKNOWN MSG TYPE, dumping dict" << std::endl; - /* dump answer */ - be_dump(n); -#endif - return BITDHT_MSG_TYPE_UNKNOWN; - } - - if (beY != BE_Y_R) - { -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() UNKNOWN2 MSG TYPE" << std::endl; -#endif - return BITDHT_MSG_TYPE_UNKNOWN; - } - -#ifdef DEBUG_MSG_TYPE - std::cerr << "bsMsgType() REPLY MSG TYPE" << std::endl; -#endif - - /* otherwise a reply or - invalid - pong {"id":"mnopqrstuvwxyz123456"} - reply_neigh { "id":"0123456789abcdefghij", "nodes": "def456..."}} - reply_hash { "id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}} - reply_near { "id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."} - */ - - be_node *reply = beMsgGetDictNode(n, "r"); - if (!reply) - { - return BITDHT_MSG_TYPE_UNKNOWN; - } - - be_node *id = beMsgGetDictNode(reply, "id"); - be_node *token = beMsgGetDictNode(reply, "token"); - be_node *values = beMsgGetDictNode(reply, "values"); - be_node *nodes = beMsgGetDictNode(reply, "nodes"); - - if (!id) - { - return BITDHT_MSG_TYPE_UNKNOWN; - } - - if (token && values) - { - /* reply hash */ - return BITDHT_MSG_TYPE_REPLY_HASH; - } - else if (token && nodes) - { - /* reply near */ - return BITDHT_MSG_TYPE_REPLY_NEAR; - } - else if (nodes) - { - /* reply neigh */ - return BITDHT_MSG_TYPE_REPLY_NODE; - } - else - { - /* pong */ - return BITDHT_MSG_TYPE_PONG; - } - /* TODO reply_post */ - //return BITDHT_MSG_TYPE_REPLY_POST; - /* can't get here! */ - return BITDHT_MSG_TYPE_UNKNOWN; -} - -/* extract specific types here */ - -int beMsgGetToken(be_node *n, bdToken &token) -{ - if (n->type != BE_STR) - { - return 0; - } - int len = be_str_len(n); - - if(len > BITDHT_TOKEN_MAX_LEN) - return 0 ; - - for(int i = 0; i < len; i++) - { - token.data[i] = n->val.s[i]; - } - token.len = len; - return 1; -} - -int beMsgGetNodeId(be_node *n, bdNodeId &nodeId) -{ - if (n->type != BE_STR) - { - return 0; - } - int len = be_str_len(n); - if (len != BITDHT_KEY_LEN) - { - return 0; - } - for(int i = 0; i < len; i++) - { - nodeId.data[i] = n->val.s[i]; - } - return 1; -} - -be_node *makeCompactNodeIdString(std::list &nodes) -{ - int len = BITDHT_COMPACTNODEID_LEN * nodes.size(); - std::string cni; - std::list::iterator it; - for(it = nodes.begin(); it != nodes.end(); it++) - { - cni += encodeCompactNodeId(&(*it)); - } - - - be_node *cninode = be_create_str_wlen((char *) cni.c_str(), len); - return cninode; -} - -be_node *makeCompactPeerIds(std::list &values) -{ - be_node *valuesnode = be_create_list(); - std::list::iterator it; - for(it = values.begin(); it != values.end(); it++) - { - be_node *val1 = be_create_str_wlen((char *) it->c_str(), it->length()); - be_add_list(valuesnode, val1); - } - return valuesnode; -} - - -int beMsgGetListBdIds(be_node *n, std::list &nodes) -{ - /* extract the string pointer, and size */ - /* split into parts */ - - if (n->type != BE_STR) - { - return 0; - } - - int len = be_str_len(n); - int count = len / BITDHT_COMPACTNODEID_LEN; - for(int i = 0; i < count; i++) - { - bdId id; - if (decodeCompactNodeId(&id, &(n->val.s[i*BITDHT_COMPACTNODEID_LEN]), BITDHT_COMPACTNODEID_LEN)) - { - nodes.push_back(id); - } - } - return 1; -} - -int beMsgGetBdId(be_node *n, bdId &id) -{ - /* extract the string pointer, and size */ - /* split into parts */ - - if (n->type != BE_STR) - { - return 0; - } - - int len = be_str_len(n); - if (len < BITDHT_COMPACTNODEID_LEN) - { - return 0; - } - if (decodeCompactNodeId(&id, n->val.s, BITDHT_COMPACTNODEID_LEN)) - { - return 1; - } - return 0; -} - -std::string encodeCompactNodeId(bdId *id) -{ - std::string enc; - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - enc += id->id.data[i]; - } - /* convert ip address (already in network order) */ - enc += encodeCompactPeerId(&(id->addr)); - return enc; -} - -int decodeCompactNodeId(bdId *id, char *enc, int len) -{ - if (len < BITDHT_COMPACTNODEID_LEN) - { - return 0; - } - - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - id->id.data[i] = enc[i]; - } - - char *ipenc = &(enc[BITDHT_COMPACTNODEID_LEN - BITDHT_COMPACTPEERID_LEN]); - if (!decodeCompactPeerId(&(id->addr), ipenc, BITDHT_COMPACTPEERID_LEN)) - { - return 0; - } - - return 1; -} - -std::string encodeCompactPeerId(struct sockaddr_in *addr) -{ - std::string encstr; - char enc[BITDHT_COMPACTPEERID_LEN]; - uint32_t *ip = (uint32_t *) (enc); - uint16_t *port = (uint16_t *) (&enc[4]); - (*ip) = addr->sin_addr.s_addr; - (*port) = addr->sin_port; - - encstr.append(enc, BITDHT_COMPACTPEERID_LEN); - return encstr; -} - -int decodeCompactPeerId(struct sockaddr_in *addr, char *enc, int len) -{ - if (len < BITDHT_COMPACTPEERID_LEN) - return 0; - - memset(addr, 0, sizeof(struct sockaddr_in)); - - //uint32_t *ip = (uint32_t *) (enc); - uint16_t *port = (uint16_t *) (&enc[4]); - - memcpy(& addr->sin_addr.s_addr, enc, sizeof(in_addr_t)); // aligned version of "addr->sin_addr.s_addr = (*ip); " - addr->sin_port = (*port); - addr->sin_family = AF_INET; - - return 1; -} - - -int beMsgGetListStrings(be_node *n, std::list &values) -{ - if (n->type != BE_LIST) - { - return 0; - } - for(int i = 0; n->val.l[i] != NULL; i++) - { - be_node *val = n->val.l[i]; - - if (val == NULL || val->type != BE_STR) - return 0; - - int len = be_str_len(val); - std::string str; - str.append(val->val.s, len); - values.push_back(str); - } - return 1; -} - - -int beMsgGetUInt32(be_node *n, uint32_t *port) -{ - if (n->type != BE_INT) - { - return 0; - } - *port = n->val.i; - return 1; -} - - - - - - - -/******************************************************************************************************************** - * CONNECTION EXTENSIONS - * - */ - - /* -ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}} -bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe - */ - - /* -Response = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} -bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re - */ - - /* -find_node Query = {"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}} -bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe - */ - -#if 0 -int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target, - char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_find_node_msg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - be_node *targetnode = be_create_str_wlen((char *) target->data, BITDHT_KEY_LEN); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("q"); - be_node *findnode = be_create_str("find_node"); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(iddict, "target", targetnode); - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "q", findnode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} -#endif - -/**** - * Thinking about the format of this message. - * id: ownId is stanard in all other messages, so should keep the same!. - * src: - * target: - * mode: d,p or r - * - * A -> B -> C - * direct: A ------> B - * ---> id:A src:A target:B mode:d - * <--- id:B src:A target:B mode:d a:OK - * - * proxy: A ------> B -------> C - * A->B id:A src:A target:C mode:p q - * - * a) - * B->A id:B src:A target:C mode:p r:NOK - * - * b) - * B->C id:B src:A target:C mode:p q - * C->B id:C src:A target:C mode:p r:NOK - * B->A id:B src:A target:C mode:p r:NOK - * - * c) - * B->C id:B src:A target:C mode:p q - * C->B id:C src:A target:C mode:p r:OK - * B->A id:B src:A target:C mode:p r:OK - * connect happens. - * Dropped packets will affect this! - * - * - * REQUIRED BITS FOR A MESSAGE - * 1) DIRECT - * -> REQUEST, ownId, targetId, transId, mode. - * -> RESPONSE, ownId, targetId, transId, mode, answer. - * - * 2) PROXY - */ - - -int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int param, int status, char *msg, int avail) -{ -#ifdef DEBUG_MSGS - fprintf(stderr, "bitdht_connect_genmsg()\n"); -#endif - - be_node *dict = be_create_dict(); - - be_node *iddict = be_create_dict(); - - be_node *idnode = be_create_str_wlen((char *) id->data, BITDHT_KEY_LEN); - - std::string srcEnc = encodeCompactNodeId(src); - std::string destEnc = encodeCompactNodeId(dest); - - be_node *srcnode = be_create_str_wlen(srcEnc.c_str(), BITDHT_COMPACTNODEID_LEN); - be_node *destnode = be_create_str_wlen(destEnc.c_str(), BITDHT_COMPACTNODEID_LEN); - be_node *typenode = be_create_int(msgtype); - be_node *statusnode = be_create_int(status); - be_node *modenode = be_create_int(mode); - be_node *paramnode = be_create_int(param); - - be_node *tidnode = be_create_str_wlen((char *) tid->data, tid->len); - be_node *yqrnode = be_create_str("q"); - be_node *cmdnode = be_create_str("connect"); - - be_add_keypair(iddict, "id", idnode); - be_add_keypair(iddict, "src", srcnode); - be_add_keypair(iddict, "dest", destnode); - be_add_keypair(iddict, "mode", modenode); - be_add_keypair(iddict, "param", paramnode); - be_add_keypair(iddict, "status", statusnode); - be_add_keypair(iddict, "type", typenode); - - be_add_keypair(dict, "a", iddict); - - be_add_keypair(dict, "t", tidnode); - be_add_keypair(dict, "y", yqrnode); - be_add_keypair(dict, "q", cmdnode); - -#ifdef DEBUG_MSG_DUMP - /* dump answer */ - be_dump(dict); -#endif - - int blen = be_encode(dict, msg, avail); - be_free(dict); - - return blen; -} - - - -bool bitdht_msgtype(uint32_t msg_type, std::string &name) -{ - switch(msg_type) - { - case BITDHT_MSG_TYPE_PING: - name = "PING"; - break; - case BITDHT_MSG_TYPE_PONG: - name = "PONG"; - break; - case BITDHT_MSG_TYPE_FIND_NODE: - name = "FIND_NODE"; - break; - case BITDHT_MSG_TYPE_REPLY_NODE: - name = "REPLY_NODE"; - break; - case BITDHT_MSG_TYPE_GET_HASH: - name = "GET_HASH"; - break; - case BITDHT_MSG_TYPE_REPLY_HASH: - name = "REPLY_HASH"; - break; - case BITDHT_MSG_TYPE_REPLY_NEAR: - name = "REPLY_NEAR"; - break; - case BITDHT_MSG_TYPE_POST_HASH: - name = "POST_HASH"; - break; - case BITDHT_MSG_TYPE_REPLY_POST: - name = "REPLY_POST"; - break; - - case BITDHT_MSG_TYPE_CONNECT: - name = "CONNECT"; - break; - case BITDHT_MSG_TYPE_CONNECT_REQUEST: - name = "CONNECT_REQUEST"; - break; - case BITDHT_MSG_TYPE_CONNECT_REPLY: - name = "CONNECT_REPLY"; - break; - case BITDHT_MSG_TYPE_CONNECT_START: - name = "CONNECT_START"; - break; - case BITDHT_MSG_TYPE_CONNECT_ACK: - name = "CONNECT_ACK"; - break; - default: - name = "UNKNOWN"; - return false; - break; - } - - return true; -} - - - diff --git a/libbitdht/src/bitdht/bdmsgs.h b/libbitdht/src/bitdht/bdmsgs.h deleted file mode 100644 index 99a26d76a..000000000 --- a/libbitdht/src/bitdht/bdmsgs.h +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * bitdht/bdmsgs.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_MSGS_H -#define BITDHT_MSGS_H - -#include -#include -#include -#include "bitdht/bencode.h" -#include "bitdht/bdobj.h" -#include "bitdht/bdpeer.h" - -#define BITDHT_MSG_TYPE_UNKNOWN 0 -#define BITDHT_MSG_TYPE_PING 1 -#define BITDHT_MSG_TYPE_PONG 2 -#define BITDHT_MSG_TYPE_FIND_NODE 3 -#define BITDHT_MSG_TYPE_REPLY_NODE 4 -#define BITDHT_MSG_TYPE_GET_HASH 5 -#define BITDHT_MSG_TYPE_REPLY_HASH 6 -#define BITDHT_MSG_TYPE_REPLY_NEAR 7 -#define BITDHT_MSG_TYPE_POST_HASH 8 -#define BITDHT_MSG_TYPE_REPLY_POST 9 - - - -// THESE ARE EXTENSIONS -#define BITDHT_MSG_TYPE_CONNECT 20 - -// CONNECTIONS. -#define BITDHT_MSG_TYPE_CONNECT_REQUEST 101 -#define BITDHT_MSG_TYPE_CONNECT_REPLY 102 -#define BITDHT_MSG_TYPE_CONNECT_START 103 -#define BITDHT_MSG_TYPE_CONNECT_ACK 104 - -// FANCY HASHES. - - -#define BITDHT_COMPACTNODEID_LEN 26 -#define BITDHT_COMPACTPEERID_LEN 6 - -#define BE_Y_UNKNOWN 0 -#define BE_Y_R 1 -#define BE_Y_Q 2 - - -/****** Known BD Version Strings ******/ - -#define BITDHT_VID_RS1 1 -#define BITDHT_VID_UT 2 - - -int bitdht_create_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid, char *msg, int avail); -int bitdht_response_ping_msg(bdToken *tid, bdNodeId *id, bdToken *vid, char *msg, int avail); -int bitdht_find_node_msg(bdToken *tid, bdNodeId *id, bdNodeId *target, bool localnet, char *msg, int avail); -int bitdht_resp_node_msg(bdToken *tid, bdNodeId *id, std::list &nodes, - char *msg, int avail); -int bitdht_get_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash, - char *msg, int avail); -int bitdht_peers_reply_hash_msg(bdToken *tid, bdNodeId *id, - bdToken *token, std::list &values, - char *msg, int avail); -int bitdht_peers_reply_closest_msg(bdToken *tid, bdNodeId *id, - bdToken *token, std::list &nodes, - char *msg, int avail); -int bitdht_announce_peers_msg(bdToken *tid, bdNodeId *id, bdNodeId *info_hash, - uint32_t port, bdToken *token, char *msg, int avail); -int bitdht_reply_announce_msg(bdToken *tid, bdNodeId *id, - char *msg, int avail); - - -// Extensions. -int bitdht_connect_genmsg(bdToken *tid, bdNodeId *id, int msgtype, bdId *src, bdId *dest, int mode, int param, int status, char *msg, int avail); - - -//int response_peers_message() -//int response_closestnodes_message() - -be_node *beMsgGetDictNode(be_node *node, const char *key); -int beMsgMatchString(be_node *n, const char *str, int len); -uint32_t beMsgGetY(be_node *n); -uint32_t beMsgType(be_node *n); - -bool bitdht_msgtype(uint32_t msg_type, std::string &name); - - -uint32_t convertBdVersionToVID(bdVersion *version); - -be_node *makeCompactPeerIds(std::list &values); -be_node *makeCompactNodeIdString(std::list &nodes); - -int beMsgGetToken(be_node *n, bdToken &token); -int beMsgGetNodeId(be_node *n, bdNodeId &nodeId); -int beMsgGetBdId(be_node *n, bdId &id); -int beMsgGetListBdIds(be_node *n, std::list &nodes); - -int beMsgGetListStrings(be_node *n, std::list &values); -int beMsgGetUInt32(be_node *n, uint32_t *port); - -/* Low Level conversion functions */ -int decodeCompactPeerId(struct sockaddr_in *addr, char *enc, int len); -std::string encodeCompactPeerId(struct sockaddr_in *addr); - -int decodeCompactNodeId(bdId *id, char *enc, int len); -std::string encodeCompactNodeId(bdId *id); - - - -#endif diff --git a/libbitdht/src/bitdht/bdnode.cc b/libbitdht/src/bitdht/bdnode.cc deleted file mode 100644 index 5d3e4fd25..000000000 --- a/libbitdht/src/bitdht/bdnode.cc +++ /dev/null @@ -1,2478 +0,0 @@ -/******************************************************************************* - * bitdht/bdnode.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdnode.h" - -#include "bitdht/bencode.h" -#include "bitdht/bdmsgs.h" - -#include "bitdht/bdquerymgr.h" -#include "bitdht/bdfilter.h" - -#include "util/bdnet.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" - -#include -#include - -#include -#include - - -#define BITDHT_QUERY_START_PEERS 10 -#define BITDHT_QUERY_NEIGHBOUR_PEERS 8 - -#define BITDHT_MAX_REMOTE_QUERY_AGE 3 // 3 seconds, keep it fresh. -#define MAX_REMOTE_PROCESS_PER_CYCLE 5 - -/**** - * #define USE_HISTORY 1 - * - * #define DEBUG_NODE_MULTIPEER 1 - * #define DEBUG_NODE_PARSE 1 - - * #define DEBUG_NODE_MSGS 1 - * #define DEBUG_NODE_ACTIONS 1 - - * #define DEBUG_NODE_MSGIN 1 - * #define DEBUG_NODE_MSGOUT 1 - * - * #define DISABLE_BAD_PEER_FILTER 1 - * - ***/ - -//#define DISABLE_BAD_PEER_FILTER 1 - -//#define USE_HISTORY 1 - -#define HISTORY_PERIOD 60 - -bdNode::bdNode(bdNodeId *ownId, std::string dhtVersion, const std::string& bootfile, const std::string &bootfilebak, const std::string& filterfile, bdDhtFunctions *fns, bdNodeManager *manager) - :mNodeSpace(ownId, fns), - mFilterPeers(filterfile,ownId, BITDHT_FILTER_REASON_OWNID, fns, manager), - mQueryMgr(NULL), - mConnMgr(NULL), - mOwnId(*ownId), mDhtVersion(dhtVersion), mStore(bootfile, bootfilebak, fns), mFns(fns), - mFriendList(ownId), mHistory(HISTORY_PERIOD) -{ - init(); /* (uses this pointers) stuff it - do it here! */ -} - -void bdNode::init() -{ - mQueryMgr = new bdQueryManager(&mNodeSpace, mFns, this); - mConnMgr = new bdConnectManager(&mOwnId, &mNodeSpace, mQueryMgr, mFns, this); - - //setNodeOptions(BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT); - setNodeOptions(0); - - mNodeDhtMode = 0; - setNodeDhtMode(BITDHT_MODE_TRAFFIC_DEFAULT); - -} -bool bdNode::getFilteredPeers(std::list& peers) -{ - mFilterPeers.getFilteredPeers(peers) ; - return true ; -} -// -//void bdNode::loadFilteredPeers(const std::list& peers) -//{ -// mFilterPeers.loadFilteredPeers(peers) ; -//} -/* Unfortunately I've ended up with 2 calls down through the heirarchy... - * not ideal - must clean this up one day. - */ - -#define ATTACH_NUMBER 5 -void bdNode::setNodeOptions(uint32_t optFlags) -{ - mNodeOptionFlags = optFlags; - if (optFlags & BITDHT_OPTIONS_MAINTAIN_UNSTABLE_PORT) - { - mNodeSpace.setAttachedFlag(BITDHT_PEER_STATUS_DHT_ENGINE | BITDHT_PEER_STATUS_DHT_ENGINE_VERSION, ATTACH_NUMBER); - } - else - { - mNodeSpace.setAttachedFlag(BITDHT_PEER_STATUS_DHT_ENGINE | BITDHT_PEER_STATUS_DHT_ENGINE_VERSION, 0); - } -} - -#define BDNODE_HIGH_MSG_RATE 50 -#define BDNODE_MED_MSG_RATE 10 -#define BDNODE_LOW_MSG_RATE 5 -#define BDNODE_TRICKLE_MSG_RATE 3 - -/* So we are setting this up so you can independently update each parameter.... - * if the mask is empty - it'll use the previous parameter. - * - */ - - -uint32_t bdNode::setNodeDhtMode(uint32_t dhtFlags) -{ - std::cerr << "bdNode::setNodeDhtMode(" << dhtFlags << "), origFlags: " << mNodeDhtMode; - std::cerr << std::endl; - - uint32_t origFlags = mNodeDhtMode; - - - uint32_t traffic = dhtFlags & BITDHT_MODE_TRAFFIC_MASK; - if (traffic) - { - switch(traffic) - { - default: - case BITDHT_MODE_TRAFFIC_LOW: - mMaxAllowedMsgs = BDNODE_LOW_MSG_RATE; - break; - case BITDHT_MODE_TRAFFIC_MED: - mMaxAllowedMsgs = BDNODE_MED_MSG_RATE; - break; - case BITDHT_MODE_TRAFFIC_HIGH: - mMaxAllowedMsgs = BDNODE_HIGH_MSG_RATE; - break; - case BITDHT_MODE_TRAFFIC_TRICKLE: - mMaxAllowedMsgs = BDNODE_TRICKLE_MSG_RATE; - break; - } - } - else - { - dhtFlags |= (origFlags & BITDHT_MODE_TRAFFIC_MASK); - } - - uint32_t relay = dhtFlags & BITDHT_MODE_RELAYSERVER_MASK; - if ((relay) && (relay != (origFlags & BITDHT_MODE_RELAYSERVER_MASK))) - { - /* changed */ - switch(relay) - { - default: - case BITDHT_MODE_RELAYSERVERS_IGNORED: - mRelayMode = BITDHT_RELAYS_OFF; - dropRelayServers(); - break; - case BITDHT_MODE_RELAYSERVERS_FLAGGED: - mRelayMode = BITDHT_RELAYS_ON; - pingRelayServers(); - break; - case BITDHT_MODE_RELAYSERVERS_ONLY: - mRelayMode = BITDHT_RELAYS_ONLY; - pingRelayServers(); - break; - case BITDHT_MODE_RELAYSERVERS_SERVER: - mRelayMode = BITDHT_RELAYS_SERVER; - pingRelayServers(); - break; - } - mConnMgr->setRelayMode(mRelayMode); - } - else - { - dhtFlags |= (origFlags & BITDHT_MODE_RELAYSERVER_MASK); - } - - mNodeDhtMode = dhtFlags; - - std::cerr << "bdNode::setNodeDhtMode() newFlags: " << mNodeDhtMode; - std::cerr << std::endl; - - return dhtFlags; -} - - -void bdNode::getOwnId(bdNodeId *id) -{ - *id = mOwnId; -} - -/***** Startup / Shutdown ******/ -void bdNode::restartNode() -{ - mAccount.resetStats(); - - mStore.reloadFromStore(); - - /* setup */ - bdPeer peer; - while(mStore.getPeer(&peer)) - { - addPotentialPeer(&(peer.mPeerId), NULL); - } -} - - -void bdNode::shutdownNode() -{ - /* clear the queries */ - mQueryMgr->shutdownQueries(); - mConnMgr->shutdownConnections(); - - mRemoteQueries.clear(); - - /* clear the space */ - mNodeSpace.clear(); - mHashSpace.clear(); - - /* clear other stuff */ - mPotentialPeers.clear(); - mStore.clear(); - - /* clean up any outgoing messages */ - while(mOutgoingMsgs.size() > 0) - { - bdNodeNetMsg *msg = mOutgoingMsgs.front(); - mOutgoingMsgs.pop_front(); - - /* cleanup message */ - delete msg; - } -} - - -/* Crappy initial store... use bdspace as answer */ -void bdNode::updateStore() -{ - mStore.writeStore(); -} - -bool bdNode::addressBanned(const sockaddr_in& raddr) -{ - return !mFilterPeers.addrOkay(const_cast(&raddr)) ; -} - -void bdNode::printState() -{ - std::cerr << "bdNode::printState() for Peer: "; - mFns->bdPrintNodeId(std::cerr, &mOwnId); - std::cerr << std::endl; - - mNodeSpace.printDHT(); - - mQueryMgr->printQueries(); - mConnMgr->printConnections(); - - std::cerr << "Outstanding Potential Peers: " << mPotentialPeers.size(); - std::cerr << std::endl; - -#ifdef USE_HISTORY - mHistory.cleanupOldMsgs(); - mHistory.printMsgs(); - mHistory.analysePeers(); - mHistory.peerTypeAnalysis(); - - // Incoming Query Analysis. - std::cerr << "Outstanding Query Requests: " << mRemoteQueries.size(); - std::cerr << std::endl; - - mQueryHistory.printMsgs(); -#endif - - mAccount.printStats(std::cerr); -} - -void bdNode::iterationOff() -{ - /* clean up any incoming messages */ - while(mIncomingMsgs.size() > 0) - { - bdNodeNetMsg *msg = mIncomingMsgs.front(); - mIncomingMsgs.pop_front(); - - /* cleanup message */ - delete msg; - } -} - -void bdNode::iteration() -{ -#ifdef DEBUG_NODE_MULTIPEER - std::cerr << "bdNode::iteration() of Peer: "; - mFns->bdPrintNodeId(std::cerr, &mOwnId); - std::cerr << std::endl; -#endif - - /* process incoming msgs */ - while(mIncomingMsgs.size() > 0) - { - bdNodeNetMsg *msg = mIncomingMsgs.front(); - mIncomingMsgs.pop_front(); - - recvPkt(msg->data, msg->mSize, msg->addr); - - /* cleanup message */ - delete msg; - } - - - /* assume that this is called once per second... limit the messages - * in theory, a query can generate up to 10 peers (which will all require a ping!). - * we want to handle all the pings we can... so we don't hold up the process. - * but we also want enough queries to keep things moving. - * so allow up to 90% of messages to be pings. - * - * ignore responses to other peers... as the number is very small generally - * - * The Rate IS NOW DEFINED IN NodeDhtMode. - */ - - int allowedPings = 0.9 * mMaxAllowedMsgs; - int sentMsgs = 0; - int sentPings = 0; - -#define BDNODE_MAX_POTENTIAL_PEERS_MULTIPLIER 5 - - /* Disable Queries if our Ping Queue is too long */ - if (mPotentialPeers.size() > mMaxAllowedMsgs * BDNODE_MAX_POTENTIAL_PEERS_MULTIPLIER) - { -#ifdef DEBUG_NODE_MULTIPEER - std::cerr << "bdNode::iteration() Disabling Queries until PotentialPeer Queue reduced"; - std::cerr << std::endl; -#endif - allowedPings = mMaxAllowedMsgs; - } - - - while((mPotentialPeers.size() > 0) && (sentMsgs < allowedPings)) - { - /* check history ... is we have pinged them already... - * then simulate / pretend we have received a pong, - * and don't bother sending another ping. - */ - - bdId pid = mPotentialPeers.front(); - mPotentialPeers.pop_front(); - - - /* don't send too many queries ... check history first */ -#if 0 -#ifdef USE_HISTORY - if (mHistory.validPeer(&pid)) - { - /* just add as peer */ - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::iteration() Pinging Known Potential Peer : "; - mFns->bdPrintId(std::cerr, &pid); - std::cerr << std::endl; -#endif - - } -#endif -#endif - - /**** TEMP ****/ - - { - send_ping(&pid); - - sentMsgs++; - sentPings++; - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::iteration() Pinging Potential Peer : "; - mFns->bdPrintId(std::cerr, &pid); - std::cerr << std::endl; -#endif - - } - - } - - /* allow each query to send up to one query... until maxMsgs has been reached */ - int sentQueries = mQueryMgr->iterateQueries(mMaxAllowedMsgs-sentMsgs); - sentMsgs += sentQueries; - - -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdNode::iteration() maxMsgs: " << maxMsgs << " sentPings: " << sentPings; - std::cerr << " / " << allowedPings; - std::cerr << " sentQueries: " << sentQueries; - std::cerr << std::endl; -#endif - - /* process remote query too */ - processRemoteQuery(); - - std::list peerIds; - std::list::iterator oit; - mNodeSpace.scanOutOfDatePeers(peerIds); - - for(oit = peerIds.begin(); oit != peerIds.end(); oit++) - { - send_ping(&(*oit)); - mAccount.incCounter(BDACCOUNT_MSG_OUTOFDATEPING, true); - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::iteration() Pinging Out-Of-Date Peer: "; - mFns->bdPrintId(std::cerr, &(*oit)); - std::cerr << std::endl; -#endif - } - - // Handle Connection loops. - mConnMgr->tickConnections(); - - mAccount.doStats(); -} - - - -/*************************************************************************************** - *************************************************************************************** - ***************************************************************************************/ - -void bdNode::send_ping(bdId *id) -{ - bdToken transId; - genNewTransId(&transId); - - msgout_ping(id, &transId); -} - - -void bdNode::send_query(bdId *id, bdNodeId *targetNodeId, bool localnet) -{ - /* push out query */ - bdToken transId; - genNewTransId(&transId); - - msgout_find_node(id, &transId, targetNodeId, localnet); - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::send_query() Find Node Req for : "; - mFns->bdPrintId(std::cerr, &id); - std::cerr << " searching for : "; - mFns->bdPrintNodeId(std::cerr, &targetNodeId); - std::cerr << std::endl; -#endif -} - - -void bdNode::send_connect_msg(bdId *id, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int param, int status) -{ - /* push out query */ - bdToken transId; - genNewTransId(&transId); - - msgout_connect_genmsg(id, &transId, msgtype, srcAddr, destAddr, mode, param, status); - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::send_connect_msg() to: "; - mFns->bdPrintId(std::cerr, &id); - std::cerr << std::endl; -#endif -} - - -void bdNode::checkPotentialPeer(bdId *id, bdId *src) -{ - /* Check BadPeer Filters for Potential Peers too */ - - /* first check the filters */ - if (!mFilterPeers.addrOkay(&(id->addr))) - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::checkPotentialPeer("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ") BAD ADDRESS!!!! SHOULD DISCARD POTENTIAL PEER"; - std::cerr << std::endl; -#endif - - return; - } - - /* is it masquarading? */ - bdFriendEntry entry; - if (mFriendList.findPeerEntry(&(id->id), entry)) - { - struct sockaddr_in knownAddr; - if (entry.addrKnown(&knownAddr)) - { - if (knownAddr.sin_addr.s_addr != id->addr.sin_addr.s_addr) - { -#ifndef DISABLE_BAD_PEER_FILTER - std::cerr << "bdNode::checkPotentialPeer("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ") MASQUERADING AS KNOWN PEER - FLAGGING AS BAD"; - std::cerr << std::endl; - - // Stores in queue for later callback and desemination around the network. - mBadPeerQueue.queuePeer(id, 0); - - mFilterPeers.addPeerToFilter(id->addr, 0); - - std::list filteredIPs; - mFilterPeers.filteredIPs(filteredIPs); - mStore.filterIpList(filteredIPs); - - return; -#endif - } - } - } - - bool isWorthyPeer = mQueryMgr->checkPotentialPeer(id, src); - - if (isWorthyPeer) - { - addPotentialPeer(id, src); - - } - - if (src) // src can be NULL! - { - mConnMgr->addPotentialConnectionProxy(src, id); // CAUTION: Order switched! - } - -} - - -void bdNode::addPotentialPeer(bdId *id, bdId * /*src*/) -{ - mPotentialPeers.push_back(*id); -} - - // virtual so manager can do callback. - // peer flags defined in bdiface.h -void bdNode::addPeer(const bdId *id, uint32_t peerflags) -{ - -#ifdef DEBUG_NODE_ACTIONS - fprintf(stderr, "bdNode::addPeer("); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, ")\n"); -#endif - - /* first check the filters */ - if (mFilterPeers.checkPeer(id, peerflags)) - { - std::cerr << "bdNode::addPeer("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ", " << std::hex << peerflags << std::dec; - std::cerr << ") FAILED the BAD PEER FILTER!!!! DISCARDING MSG"; - std::cerr << std::endl; - - std::list filteredIPs; - mFilterPeers.filteredIPs(filteredIPs); - mStore.filterIpList(filteredIPs); - - mBadPeerQueue.queuePeer(id, peerflags); - - return; - } - - /* next we check if it is a friend, whitelist etc, and adjust flags */ - bdFriendEntry entry; - - if (mFriendList.findPeerEntry(&(id->id), entry)) - { - /* found! */ - peerflags |= entry.getPeerFlags(); // translates internal into general ones. - - struct sockaddr_in knownAddr; - if (entry.addrKnown(&knownAddr)) - { - if (knownAddr.sin_addr.s_addr != id->addr.sin_addr.s_addr) - { -#ifndef DISABLE_BAD_PEER_FILTER - std::cerr << "bdNode::addPeer("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ", " << std::hex << peerflags << std::dec; - std::cerr << ") MASQUERADING AS KNOWN PEER - FLAGGING AS BAD"; - std::cerr << std::endl; - - - // Stores in queue for later callback and desemination around the network. - mBadPeerQueue.queuePeer(id, peerflags); - - mFilterPeers.addPeerToFilter(id->addr, peerflags); - - std::list filteredIPs; - mFilterPeers.filteredIPs(filteredIPs); - mStore.filterIpList(filteredIPs); - - // DO WE EXPLICITLY NEED TO DO THIS, OR WILL THEY JUST BE DROPPED? - //mNodeSpace.remove_badpeer(id); - //mQueryMgr->remove_badpeer(id); - - // FLAG in NodeSpace (Should be dropped very quickly anyway) - mNodeSpace.flagpeer(id, 0, BITDHT_PEER_EXFLAG_BADPEER); - - return; -#endif - } - } - } - - mQueryMgr->addPeer(id, peerflags); - mNodeSpace.add_peer(id, peerflags); - - bdPeer peer; - peer.mPeerId = *id; - peer.mPeerFlags = peerflags; - peer.mLastRecvTime = time(NULL); - mStore.addStore(&peer); - - // Finally we pass to connections for them to use. - mConnMgr->updatePotentialConnectionProxy(id, peerflags); - - -//#define DISPLAY_BITDHTNODES 1 -#ifdef DISPLAY_BITDHTNODES - /* TEMP to extract IDS for BloomFilter */ - if (peerflags & BITDHT_PEER_STATUS_DHT_ENGINE) - { - std::cerr << "bdNode::addPeer() FOUND BITDHT PEER"; - std::cerr << std::endl; - mFns->bdPrintNodeId(std::cerr, &(id->id)); - std::cerr << std::endl; - } -#endif -} - -/************************************ Process Remote Query *************************/ - -/* increased the allowed processing rate from 1/sec => 5/sec */ -void bdNode::processRemoteQuery() -{ - int nProcessed = 0; - time_t oldTS = time(NULL) - BITDHT_MAX_REMOTE_QUERY_AGE; - while(nProcessed < MAX_REMOTE_PROCESS_PER_CYCLE) - { - /* extra exit clause */ - if (mRemoteQueries.size() < 1) - { -#ifdef USE_HISTORY - if (nProcessed) - { - mQueryHistory.cleanupOldMsgs(); - } -#endif - return; - } - - bdRemoteQuery &query = mRemoteQueries.front(); - - // filtering. - bool badPeer = false; -#ifdef USE_HISTORY - // store result in badPeer to activate the filtering. - mQueryHistory.addIncomingQuery(query.mQueryTS, &(query.mId), &(query.mQuery)); -#endif - - /* discard older ones (stops queue getting overloaded) */ - if ((query.mQueryTS > oldTS) && (!badPeer)) - { - /* recent enough to process! */ - nProcessed++; - - switch(query.mQueryType) - { - case BD_QUERY_NEIGHBOURS: - case BD_QUERY_LOCALNET: - { - /* search bdSpace for neighbours */ - - std::list nearList; - std::multimap nearest; - std::multimap::iterator it; - - if (query.mQueryType == BD_QUERY_LOCALNET) - { - std::list excludeList; - mNodeSpace.find_nearest_nodes_with_flags(&(query.mQuery), - BITDHT_QUERY_NEIGHBOUR_PEERS, - excludeList, nearest, BITDHT_PEER_STATUS_DHT_APPL); - } - else - { - if (mRelayMode == BITDHT_RELAYS_SERVER) - { - std::list excludeList; - mNodeSpace.find_nearest_nodes_with_flags(&(query.mQuery), - BITDHT_QUERY_NEIGHBOUR_PEERS, - excludeList, nearest, BITDHT_PEER_STATUS_DHT_RELAY_SERVER); - } - else - { - mNodeSpace.find_nearest_nodes(&(query.mQuery), BITDHT_QUERY_NEIGHBOUR_PEERS, nearest); - } - } - - for(it = nearest.begin(); it != nearest.end(); it++) - { - nearList.push_back(it->second); - } - msgout_reply_find_node(&(query.mId), &(query.mTransId), nearList); -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::processRemoteQuery() Reply to Find Node: "; - mFns->bdPrintId(std::cerr, &(query.mId)); - std::cerr << " searching for : "; - mFns->bdPrintNodeId(std::cerr, &(query.mQuery)); - std::cerr << ", found " << nearest.size() << " nodes "; - std::cerr << std::endl; -#endif - - break; - } - case BD_QUERY_HASH: - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::processRemoteQuery() Reply to Query Node: "; - mFns->bdPrintId(std::cerr, &(query.mId)); - std::cerr << " TODO"; - std::cerr << std::endl; -#endif - - /* TODO */ - /* for now drop */ - /* unprocess! */ - nProcessed--; - break; - } - default: - { - /* drop */ - /* unprocess! */ - nProcessed--; - break; - } - } - - - - } - else - { - if (badPeer) - { - std::cerr << "bdNode::processRemoteQuery() Query from BadPeer: Discarding: "; - } -#ifdef DEBUG_NODE_MSGS - else - { - std::cerr << "bdNode::processRemoteQuery() Query Too Old: Discarding: "; - } -#endif -#ifdef DEBUG_NODE_MSGS - mFns->bdPrintId(std::cerr, &(query.mId)); - std::cerr << std::endl; -#endif - } - - mRemoteQueries.pop_front(); - - } - -#ifdef USE_HISTORY - mQueryHistory.cleanupOldMsgs(); -#endif -} - - - - - -/************************************ Message Buffering ****************************/ - - /* interaction with outside world */ -int bdNode::outgoingMsg(struct sockaddr_in *addr, char *msg, int *len) -{ - if (mOutgoingMsgs.size() > 0) - { - bdNodeNetMsg *bdmsg = mOutgoingMsgs.front(); - //bdmsg->print(std::cerr); - mOutgoingMsgs.pop_front(); - //bdmsg->print(std::cerr); - - /* truncate if necessary */ - if (bdmsg->mSize < *len) - { - //std::cerr << "bdNode::outgoingMsg space(" << *len << ") msgsize(" << bdmsg->mSize << ")"; - //std::cerr << std::endl; - *len = bdmsg->mSize; - } - else - { - //std::cerr << "bdNode::outgoingMsg space(" << *len << ") small - trunc from: " - //<< bdmsg->mSize; - //std::cerr << std::endl; - } - - - memcpy(msg, bdmsg->data, *len); - *addr = bdmsg->addr; - - //bdmsg->print(std::cerr); - - delete bdmsg; - return 1; - } - return 0; -} - -void bdNode::incomingMsg(struct sockaddr_in *addr, char *msg, int len) -{ - /* check against the filter */ - if (mFilterPeers.addrOkay(addr)) - { - bdNodeNetMsg *bdmsg = new bdNodeNetMsg(msg, len, addr); - mIncomingMsgs.push_back(bdmsg); - } -#ifdef DEBUG_NODE_MSGOUT - else - { - std::cerr << "bdNode::incomingMsg() Incoming Packet Filtered"; - std::cerr << std::endl; - } -#endif -} - -/************************************ Message Handling *****************************/ - -/* Outgoing Messages */ - -void bdNode::msgout_ping(bdId *id, bdToken *transId) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_ping() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - // THIS IS CRASHING HISTORY. - // LIKELY ID is not always valid! - // Either PotentialPeers or Out-Of-Date Peers. - //registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_PING); - - bdId dupId(*id); - registerOutgoingMsg(&dupId, transId, BITDHT_MSG_TYPE_PING, NULL); - - /* generate message, send to udp */ - bdToken vid; - uint32_t vlen = BITDHT_TOKEN_MAX_LEN; - if (mDhtVersion.size() < vlen) - { - vlen = mDhtVersion.size(); - } - memcpy(vid.data, mDhtVersion.c_str(), vlen); - vid.len = vlen; - - /* create string */ - char msg[10240]; - int avail = 10240; - - int blen = bitdht_create_ping_msg(transId, &(mOwnId), &vid, msg, avail-1); - sendPkt(msg, blen, id->addr); - - mAccount.incCounter(BDACCOUNT_MSG_PING, true); - -} - - -void bdNode::msgout_pong(bdId *id, bdToken *transId) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_pong() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " Version: " << version; - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_PONG, NULL); - - /* generate message, send to udp */ - bdToken vid; - uint32_t vlen = BITDHT_TOKEN_MAX_LEN; - if (mDhtVersion.size() < vlen) - { - vlen = mDhtVersion.size(); - } - memcpy(vid.data, mDhtVersion.c_str(), vlen); - vid.len = vlen; - - char msg[10240]; - int avail = 10240; - - int blen = bitdht_response_ping_msg(transId, &(mOwnId), &vid, msg, avail-1); - - sendPkt(msg, blen, id->addr); - - mAccount.incCounter(BDACCOUNT_MSG_PONG, true); - -} - - -void bdNode::msgout_find_node(bdId *id, bdToken *transId, bdNodeId *query, bool localnet) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_find_node() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Query: "; - mFns->bdPrintNodeId(std::cerr, query); - std::cerr << std::endl; -#endif - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_FIND_NODE, query); - - - - char msg[10240]; - int avail = 10240; - - int blen = bitdht_find_node_msg(transId, &(mOwnId), query, localnet, msg, avail-1); - - sendPkt(msg, blen, id->addr); - - mAccount.incCounter(BDACCOUNT_MSG_QUERYNODE, true); - -} - -void bdNode::msgout_reply_find_node(bdId *id, bdToken *transId, std::list &peers) -{ - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_REPLY_NODE, NULL); - - mAccount.incCounter(BDACCOUNT_MSG_REPLYFINDNODE, true); - - int blen = bitdht_resp_node_msg(transId, &(mOwnId), peers, msg, avail-1); - - sendPkt(msg, blen, id->addr); - -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_reply_find_node() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Peers:"; - std::list::iterator it; - for(it = peers.begin(); it != peers.end(); it++) - { - std::cerr << " "; - mFns->bdPrintId(std::cerr, &(*it)); - } - std::cerr << std::endl; -#endif -} - -/***************** - * SECOND HALF - * - *****/ - -void bdNode::msgout_get_hash(bdId *id, bdToken *transId, bdNodeId *info_hash) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_get_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " InfoHash: "; - mFns->bdPrintNodeId(std::cerr, info_hash); - std::cerr << std::endl; -#endif - - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_GET_HASH, info_hash); - - - int blen = bitdht_get_peers_msg(transId, &(mOwnId), info_hash, msg, avail-1); - - sendPkt(msg, blen, id->addr); - - mAccount.incCounter(BDACCOUNT_MSG_QUERYHASH, true); - -} - -void bdNode::msgout_reply_hash(bdId *id, bdToken *transId, bdToken *token, std::list &values) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_reply_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - - std::cerr << " Peers: "; - std::list::iterator it; - for(it = values.begin(); it != values.end(); it++) - { - std::cerr << " "; - bdPrintCompactPeerId(std::cerr, *it); - } - std::cerr << std::endl; -#endif - - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_REPLY_HASH, NULL); - - int blen = bitdht_peers_reply_hash_msg(transId, &(mOwnId), token, values, msg, avail-1); - - sendPkt(msg, blen, id->addr); - - mAccount.incCounter(BDACCOUNT_MSG_REPLYQUERYHASH, true); - -} - -void bdNode::msgout_reply_nearest(bdId *id, bdToken *transId, bdToken *token, std::list &nodes) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_reply_nearest() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - std::cerr << " Nodes:"; - - std::list::iterator it; - for(it = nodes.begin(); it != nodes.end(); it++) - { - std::cerr << " "; - mFns->bdPrintId(std::cerr, &(*it)); - } - std::cerr << std::endl; -#endif - - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_REPLY_NEAR, NULL); - - - - int blen = bitdht_peers_reply_closest_msg(transId, &(mOwnId), token, nodes, msg, avail-1); - - sendPkt(msg, blen, id->addr); - mAccount.incCounter(BDACCOUNT_MSG_REPLYQUERYHASH, true); - - -} - -void bdNode::msgout_post_hash(bdId *id, bdToken *transId, bdNodeId *info_hash, uint32_t port, bdToken *token) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_post_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Info_Hash: "; - mFns->bdPrintNodeId(std::cerr, info_hash); - std::cerr << " Port: " << port; - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - std::cerr << std::endl; -#endif - - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_POST_HASH, info_hash); - - - int blen = bitdht_announce_peers_msg(transId,&(mOwnId),info_hash,port,token,msg,avail-1); - - sendPkt(msg, blen, id->addr); - mAccount.incCounter(BDACCOUNT_MSG_POSTHASH, true); - - -} - -void bdNode::msgout_reply_post(bdId *id, bdToken *transId) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdNode::msgout_reply_post() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - /* generate message, send to udp */ - char msg[10240]; - int avail = 10240; - - registerOutgoingMsg(id, transId, BITDHT_MSG_TYPE_REPLY_POST, NULL); - - int blen = bitdht_reply_announce_msg(transId, &(mOwnId), msg, avail-1); - - sendPkt(msg, blen, id->addr); - mAccount.incCounter(BDACCOUNT_MSG_REPLYPOSTHASH, true); - -} - - -void bdNode::sendPkt(char *msg, int len, struct sockaddr_in addr) -{ - //fprintf(stderr, "bdNode::sendPkt(%d) to %s:%d\n", - // len, inet_ntoa(addr.sin_addr), htons(addr.sin_port)); - - /* filter outgoing packets */ - if (mFilterPeers.addrOkay(&addr)) - { - bdNodeNetMsg *bdmsg = new bdNodeNetMsg(msg, len, &addr); - //bdmsg->print(std::cerr); - mOutgoingMsgs.push_back(bdmsg); - //bdmsg->print(std::cerr); - } - else - { - std::cerr << "bdNode::sendPkt() Outgoing Packet Filtered"; - std::cerr << std::endl; - } - - return; -} - - -/********************* Incoming Messages *************************/ -/* - * These functions are holding up udp queue -> so quickly - * parse message, and get on with it! - */ - -void bdNode::recvPkt(char *msg, int len, struct sockaddr_in addr) -{ -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() msg[" << len << "] = "; - for(int i = 0; i < len; i++) - { - if ((msg[i] > 31) && (msg[i] < 127)) - { - std::cerr << msg[i]; - } - else - { - std::cerr << "[" << (int) msg[i] << "]"; - } - } - std::cerr << std::endl; -#endif - - /* convert to a be_node */ - be_node *node = be_decoden(msg, len); - if (!node) - { - /* invalid decode */ -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Failure to decode. Dropping Msg"; - std::cerr << std::endl; - std::cerr << "message length: " << len; - std::cerr << std::endl; - std::cerr << "msg[] = "; - for(int i = 0; i < len; i++) - { - if ((msg[i] > 31) && (msg[i] < 127)) - { - std::cerr << msg[i]; - } - else - { - std::cerr << "[" << (int) msg[i] << "]"; - } - } - std::cerr << std::endl; -#endif - return; - } - - /* find message type */ - uint32_t beType = beMsgType(node); - bool beQuery = (BE_Y_Q == beMsgGetY(node)); - - if (!beType) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Invalid Message Type. Dropping Msg"; - std::cerr << std::endl; -#endif - /* invalid message */ - be_free(node); - return; - } - - /************************* handle token (all) **************************/ - be_node *be_transId = beMsgGetDictNode(node, "t"); - bdToken transId; - if (be_transId) - { - beMsgGetToken(be_transId, transId); - } - else - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() TransId Failure. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /************************* handle data (all) **************************/ - - /* extract common features */ - char dictkey[2] = "r"; - if (beQuery) - { - dictkey[0] = 'a'; - } - - be_node *be_data = beMsgGetDictNode(node, dictkey); - if (!be_data) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Data Body. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /************************** handle id (all) ***************************/ - be_node *be_id = beMsgGetDictNode(be_data, "id"); - bdNodeId id; - if(!be_id || !beMsgGetNodeId(be_id, id)) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Peer Id. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /************************ handle version (optional:pong) **************/ - be_node *be_version = NULL; - bdToken versionId; - if ((beType == BITDHT_MSG_TYPE_PONG) || (beType == BITDHT_MSG_TYPE_PING)) - { - be_version = beMsgGetDictNode(node, "v"); - if (!be_version) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() NOTE: PONG missing Optional Version."; - std::cerr << std::endl; -#endif - } - } - - if (be_version) - { - beMsgGetToken(be_version, versionId); - } - - /************************ handle options (optional:bitdht extension) **************/ - be_node *be_options = beMsgGetDictNode(node, "o"); - bool localnet = false; - if (be_options) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Found Options Node, localnet"; - std::cerr << std::endl; -#endif - localnet = true; - } - - /*********** handle target (query) or info_hash (get_hash) ************/ - bdNodeId target_info_hash; - be_node *be_target = NULL; - if (beType == BITDHT_MSG_TYPE_FIND_NODE) - { - be_target = beMsgGetDictNode(be_data, "target"); - if (!be_target) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Target / Info_Hash. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - } - else if ((beType == BITDHT_MSG_TYPE_GET_HASH) || - (beType == BITDHT_MSG_TYPE_POST_HASH)) - { - be_target = beMsgGetDictNode(be_data, "info_hash"); - if (!be_target) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Target / Info_Hash. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_target) - { - beMsgGetNodeId(be_target, target_info_hash); - } - - /*********** handle nodes (reply_query or reply_near) *****************/ - std::list nodes; - be_node *be_nodes = NULL; - if ((beType == BITDHT_MSG_TYPE_REPLY_NODE) || - (beType == BITDHT_MSG_TYPE_REPLY_NEAR)) - { - be_nodes = beMsgGetDictNode(be_data, "nodes"); - if (!be_nodes) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Nodes. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_nodes) - { - beMsgGetListBdIds(be_nodes, nodes); - } - - /******************* handle values (reply_hash) ***********************/ - std::list values; - be_node *be_values = NULL; - if (beType == BITDHT_MSG_TYPE_REPLY_HASH) - { - be_values = beMsgGetDictNode(be_data, "values"); - if (!be_values) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Values. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_values) - { - beMsgGetListStrings(be_values, values); - } - - /************ handle token (reply_hash, reply_near, post hash) ********/ - bdToken token; - be_node *be_token = NULL; - if ((beType == BITDHT_MSG_TYPE_REPLY_HASH) || - (beType == BITDHT_MSG_TYPE_REPLY_NEAR) || - (beType == BITDHT_MSG_TYPE_POST_HASH)) - { - be_token = beMsgGetDictNode(be_data, "token"); - if (!be_token) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() Missing Token. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_token) - { - beMsgGetToken(be_transId, transId); - } - - /****************** handle port (post hash) ***************************/ - uint32_t port; - be_node *be_port = NULL; - if (beType == BITDHT_MSG_TYPE_POST_HASH) - { - be_port = beMsgGetDictNode(be_data, "port"); - if (!be_port) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() POST_HASH Missing Port. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_port) - { - beMsgGetUInt32(be_port, &port); - } - - /****************** handle Connect (lots) ***************************/ - bdId connSrcAddr; - bdId connDestAddr; - uint32_t connMode; - uint32_t connParam = 0; - uint32_t connStatus; - uint32_t connType; - - be_node *be_ConnSrcAddr = NULL; - be_node *be_ConnDestAddr = NULL; - be_node *be_ConnMode = NULL; - be_node *be_ConnParam = NULL; - be_node *be_ConnStatus = NULL; - be_node *be_ConnType = NULL; - if (beType == BITDHT_MSG_TYPE_CONNECT) - { - /* SrcAddr */ - be_ConnSrcAddr = beMsgGetDictNode(be_data, "src"); - if (!be_ConnSrcAddr) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing SrcAddr. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /* DestAddr */ - be_ConnDestAddr = beMsgGetDictNode(be_data, "dest"); - if (!be_ConnDestAddr) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing DestAddr. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /* Mode */ - be_ConnMode = beMsgGetDictNode(be_data, "mode"); - if (!be_ConnMode) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing Mode. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /* Param */ - be_ConnParam = beMsgGetDictNode(be_data, "param"); - if (!be_ConnParam) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing Param. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /* Status */ - be_ConnStatus = beMsgGetDictNode(be_data, "status"); - if (!be_ConnStatus) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing Status. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - - /* Type */ - be_ConnType = beMsgGetDictNode(be_data, "type"); - if (!be_ConnType) - { -#ifdef DEBUG_NODE_PARSE - std::cerr << "bdNode::recvPkt() CONNECT Missing Type. Dropping Msg"; - std::cerr << std::endl; -#endif - be_free(node); - return; - } - } - - if (be_ConnSrcAddr) - { - beMsgGetBdId(be_ConnSrcAddr, connSrcAddr); - } - - if (be_ConnDestAddr) - { - beMsgGetBdId(be_ConnDestAddr, connDestAddr); - } - - if (be_ConnMode) - { - beMsgGetUInt32(be_ConnMode, &connMode); - } - - if (be_ConnParam) - { - beMsgGetUInt32(be_ConnParam, &connParam); - } - - if (be_ConnStatus) - { - beMsgGetUInt32(be_ConnStatus, &connStatus); - } - - if (be_ConnType) - { - beMsgGetUInt32(be_ConnType, &connType); - } - - - - /****************** Bits Parsed Ok. Process Msg ***********************/ - /* Construct Source Id */ - bdId srcId(id, addr); - - if (be_target) - { - registerIncomingMsg(&srcId, &transId, beType, &target_info_hash); - } - else - { - registerIncomingMsg(&srcId, &transId, beType, NULL); - } - - switch(beType) - { - case BITDHT_MSG_TYPE_PING: /* a: id, transId */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Responding to Ping : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - if (be_version) - { - msgin_ping(&srcId, &transId, &versionId); - } - else - { - msgin_ping(&srcId, &transId, NULL); - } - break; - } - case BITDHT_MSG_TYPE_PONG: /* r: id, transId */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Received Pong from : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - if (be_version) - { - msgin_pong(&srcId, &transId, &versionId); - } - else - { - msgin_pong(&srcId, &transId, NULL); - } - - break; - } - case BITDHT_MSG_TYPE_FIND_NODE: /* a: id, transId, target */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Req Find Node from : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << " Looking for: "; - mFns->bdPrintNodeId(std::cerr, &target_info_hash); - std::cerr << std::endl; -#endif - msgin_find_node(&srcId, &transId, &target_info_hash, localnet); - break; - } - case BITDHT_MSG_TYPE_REPLY_NODE: /* r: id, transId, nodes */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Received Reply Node from : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - msgin_reply_find_node(&srcId, &transId, nodes); - break; - } - case BITDHT_MSG_TYPE_GET_HASH: /* a: id, transId, info_hash */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Received SearchHash : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << " for Hash: "; - mFns->bdPrintNodeId(std::cerr, &target_info_hash); - std::cerr << std::endl; -#endif - msgin_get_hash(&srcId, &transId, &target_info_hash); - break; - } - case BITDHT_MSG_TYPE_REPLY_HASH: /* r: id, transId, token, values */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Received Reply Hash : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - msgin_reply_hash(&srcId, &transId, &token, values); - break; - } - case BITDHT_MSG_TYPE_REPLY_NEAR: /* r: id, transId, token, nodes */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Received Reply Near : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - msgin_reply_nearest(&srcId, &transId, &token, nodes); - break; - } - case BITDHT_MSG_TYPE_POST_HASH: /* a: id, transId, info_hash, port, token */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Post Hash from : "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << " to post: "; - mFns->bdPrintNodeId(std::cerr, &target_info_hash); - std::cerr << " with port: " << port; - std::cerr << std::endl; -#endif - msgin_post_hash(&srcId, &transId, &target_info_hash, port, &token); - break; - } - case BITDHT_MSG_TYPE_REPLY_POST: /* r: id, transId */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() Reply Post from: "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - msgin_reply_post(&srcId, &transId); - break; - } - case BITDHT_MSG_TYPE_CONNECT: /* a: id, src, dest, mode, status, type */ - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() ConnectMsg from: "; - mFns->bdPrintId(std::cerr, &srcId); - std::cerr << std::endl; -#endif - msgin_connect_genmsg(&srcId, &transId, connType, - &connSrcAddr, &connDestAddr, - connMode, connParam, connStatus); - break; - } - default: - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::recvPkt() ERROR"; - std::cerr << std::endl; -#endif - /* ERROR */ - break; - } - } - - be_free(node); - return; -} - -/* Input: id, token. - * Response: pong(id, token) - */ - -void bdNode::msgin_ping(bdId *id, bdToken *transId, bdToken *versionId) -{ -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_ping() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - mAccount.incCounter(BDACCOUNT_MSG_PING, false); - - /* peer is alive */ - uint32_t peerflags = BITDHT_PEER_STATUS_RECV_PING; /* no id typically, so cant get version */ - peerflags |= parseVersion(versionId); - addPeer(id, peerflags); - - /* reply */ - msgout_pong(id, transId); - -} - -/* Input: id, token, (+optional version) - * Response: store peer. - */ - -void bdNode::msgin_pong(bdId *id, bdToken *transId, bdToken *versionId) -{ -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_pong() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " Version: TODO!"; // << version; - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#else - (void) transId; -#endif - - uint32_t peerflags = BITDHT_PEER_STATUS_RECV_PONG; - peerflags |= parseVersion(versionId); - - mAccount.incCounter(BDACCOUNT_MSG_PONG, false); - addPeer(id, peerflags); -} - - -uint32_t bdNode::parseVersion(bdToken *versionId) -{ - /* recv pong, and peer is alive. add to DHT */ - //uint32_t vId = 0; // TODO XXX convertBdVersionToVID(versionId); - - /* calculate version match with peer */ - bool sameDhtEngine = false; - bool sameDhtVersion = false; - bool sameAppl = false; - bool sameApplVersion = false; - - if (versionId) - { - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::parseVersion() Peer Version: "; - for(int i = 0; i < versionId->len; i++) - { - std::cerr << versionId->data[i]; - } - std::cerr << std::endl; -#endif - -#ifdef USE_HISTORY - std::string version; - for(int i = 0; i < versionId->len; i++) - { - if (isalnum(versionId->data[i])) - { - version += versionId->data[i]; - } - else - { - version += 'X'; - } - } - mHistory.setPeerType(id, version); -#endif - - /* check two bytes */ - if ((versionId->len >= 2) && (mDhtVersion.size() >= 2) && - (versionId->data[0] == mDhtVersion[0]) && (versionId->data[1] == mDhtVersion[1])) - { - sameDhtEngine = true; - } - - /* check two bytes. - * Due to Old Versions not having this field, we need to check that they are numbers. - * We have a Major version, and minor version.... - * This flag is set if Major is same, and minor is greater or equal to our version. - */ - if ((versionId->len >= 4) && (mDhtVersion.size() >= 4)) - { - if ((isdigit(versionId->data[2]) && isdigit(versionId->data[3])) && - (versionId->data[2] == mDhtVersion[2]) && (versionId->data[3] >= mDhtVersion[3])) - { - sameDhtVersion = true; - } - } - - if ((sameDhtVersion) && (!sameDhtEngine)) - { - sameDhtVersion = false; -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::parseVersion() STRANGE Peer Version: "; - for(uint32_t i = 0; i < versionId->len; i++) - { - std::cerr << versionId->data[i]; - } - std::cerr << std::endl; -#endif - } - - /* check two bytes */ - if ((versionId->len >= 6) && (mDhtVersion.size() >= 6) && - (versionId->data[4] == mDhtVersion[4]) && (versionId->data[5] == mDhtVersion[5])) - { - sameAppl = true; - } - - - /* check two bytes */ - if ((versionId->len >= 8) && (mDhtVersion.size() >= 8)) - { - if ((isdigit(versionId->data[6]) && isdigit(versionId->data[7])) && - (versionId->data[6] == mDhtVersion[6]) && (versionId->data[7] >= mDhtVersion[7])) - { - sameApplVersion = true; - } - } - } - else - { - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::parseVersion() No Version"; - std::cerr << std::endl; -#endif - } - - uint32_t peerflags = BITDHT_PEER_STATUS_RECV_PONG; /* should have id too */ - if (sameDhtEngine) - { - peerflags |= BITDHT_PEER_STATUS_DHT_ENGINE; - } - if (sameDhtVersion) - { - peerflags |= BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; - } - if (sameAppl) - { - peerflags |= BITDHT_PEER_STATUS_DHT_APPL; - } - if (sameApplVersion) - { - peerflags |= BITDHT_PEER_STATUS_DHT_APPL_VERSION; - } - return peerflags; -} - - - -/* Input: id, token, queryId */ - -void bdNode::msgin_find_node(bdId *id, bdToken *transId, bdNodeId *query, bool localnet) -{ -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_find_node() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Query: "; - mFns->bdPrintNodeId(std::cerr, query); - std::cerr << std::endl; -#endif - - mAccount.incCounter(BDACCOUNT_MSG_QUERYNODE, false); - - - /* store query... */ - uint32_t query_type = BD_QUERY_NEIGHBOURS; - if (localnet) - { - query_type = BD_QUERY_LOCALNET; - } - queueQuery(id, query, transId, query_type); - - - uint32_t peerflags = 0; /* no id, and no help! */ - addPeer(id, peerflags); -} - -void bdNode::msgin_reply_find_node(bdId *id, bdToken *transId, std::list &nodes) -{ - std::list::iterator it; - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::msgin_reply_find_node() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Peers:"; - for(it = nodes.begin(); it != nodes.end(); it++) - { - std::cerr << " "; - mFns->bdPrintId(std::cerr, &(*it)); - } - std::cerr << std::endl; -#else - (void) transId; -#endif - - mAccount.incCounter(BDACCOUNT_MSG_REPLYFINDNODE, false); - - /* add neighbours to the potential list */ - for(it = nodes.begin(); it != nodes.end(); it++) - { - checkPotentialPeer(&(*it), id); - } - - /* received reply - so peer must be good */ - uint32_t peerflags = BITDHT_PEER_STATUS_RECV_NODES; /* no id ;( */ - addPeer(id, peerflags); -} - -/********* THIS IS THE SECOND STAGE - * - */ - -void bdNode::msgin_get_hash(bdId *id, bdToken *transId, bdNodeId *info_hash) -{ - - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_get_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " InfoHash: "; - mFns->bdPrintNodeId(std::cerr, info_hash); - std::cerr << std::endl; -#endif - - - mAccount.incCounter(BDACCOUNT_MSG_QUERYHASH, false); - - /* generate message, send to udp */ - queueQuery(id, info_hash, transId, BD_QUERY_HASH); - -} - -void bdNode::msgin_reply_hash(bdId *id, bdToken *transId, bdToken *token, std::list &values) -{ - mAccount.incCounter(BDACCOUNT_MSG_REPLYQUERYHASH, false); - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_reply_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - - std::cerr << " Peers: "; - std::list::iterator it; - for(it = values.begin(); it != values.end(); it++) - { - std::cerr << " "; - bdPrintCompactPeerId(std::cerr, *it); - } - std::cerr << std::endl; -#else - (void) id; - (void) transId; - (void) token; - (void) values; -#endif -} - -void bdNode::msgin_reply_nearest(bdId *id, bdToken *transId, bdToken *token, std::list &nodes) -{ - mAccount.incCounter(BDACCOUNT_MSG_REPLYQUERYHASH, false); - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_reply_nearest() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - std::cerr << " Nodes:"; - - std::list::iterator it; - for(it = nodes.begin(); it != nodes.end(); it++) - { - std::cerr << " "; - mFns->bdPrintId(std::cerr, &(*it)); - } - std::cerr << std::endl; -#else - (void) id; - (void) transId; - (void) token; - (void) nodes; -#endif -} - - - -void bdNode::msgin_post_hash(bdId *id, bdToken *transId, bdNodeId *info_hash, uint32_t port, bdToken *token) -{ - - mAccount.incCounter(BDACCOUNT_MSG_POSTHASH, false); - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_post_hash() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " Info_Hash: "; - mFns->bdPrintNodeId(std::cerr, info_hash); - std::cerr << " Port: " << port; - std::cerr << " Token: "; - bdPrintToken(std::cerr, token); - std::cerr << std::endl; -#else - (void) id; - (void) transId; - (void) info_hash; - (void) port; - (void) token; -#endif - -} - - -void bdNode::msgin_reply_post(bdId *id, bdToken *transId) -{ - /* generate message, send to udp */ - mAccount.incCounter(BDACCOUNT_MSG_REPLYPOSTHASH, false); - -#ifdef DEBUG_NODE_MSGIN - std::cerr << "bdNode::msgin_reply_post() TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#else - (void) id; - (void) transId; -#endif -} - - - -/************************************************************************************************************ -******************************************** Message Interface ********************************************** -************************************************************************************************************/ - -/* Outgoing Messages */ -std::string getConnectMsgType(int msgtype) -{ - switch(msgtype) - { - case BITDHT_MSG_TYPE_CONNECT_REQUEST: - return "ConnectRequest"; - break; - case BITDHT_MSG_TYPE_CONNECT_REPLY: - return "ConnectReply"; - break; - case BITDHT_MSG_TYPE_CONNECT_START: - return "ConnectStart"; - break; - case BITDHT_MSG_TYPE_CONNECT_ACK: - return "ConnectAck"; - break; - default: - return "ConnectUnknown"; - break; - } -} - -void bdNode::msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, bdId *srcAddr, bdId *destAddr, int mode, int param, int status) -{ -#ifdef DEBUG_NODE_MSGOUT - std::cerr << "bdConnectManager::msgout_connect_genmsg() Type: " << getConnectMsgType(msgtype); - std::cerr << " TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " To: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " SrcAddr: "; - mFns->bdPrintId(std::cerr, srcAddr); - std::cerr << " DestAddr: "; - mFns->bdPrintId(std::cerr, destAddr); - std::cerr << " Mode: " << mode; - std::cerr << " Param: " << param; - std::cerr << " Status: " << status; - std::cerr << std::endl; -#endif - - switch(msgtype) - { - default: - case BITDHT_MSG_TYPE_CONNECT_REQUEST: - mAccount.incCounter(BDACCOUNT_MSG_CONNECTREQUEST, true); - break; - case BITDHT_MSG_TYPE_CONNECT_REPLY: - mAccount.incCounter(BDACCOUNT_MSG_CONNECTREPLY, true); - break; - case BITDHT_MSG_TYPE_CONNECT_START: - mAccount.incCounter(BDACCOUNT_MSG_CONNECTSTART, true); - break; - case BITDHT_MSG_TYPE_CONNECT_ACK: - mAccount.incCounter(BDACCOUNT_MSG_CONNECTACK, true); - break; - } - - registerOutgoingMsg(id, transId, msgtype, NULL); - - /* create string */ - char msg[10240]; - int avail = 10240; - - int blen = bitdht_connect_genmsg(transId, &(mOwnId), msgtype, srcAddr, destAddr, mode, param, status, msg, avail-1); - sendPkt(msg, blen, id->addr); -} - - -void bdNode::msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype, - bdId *srcAddr, bdId *destAddr, int mode, int param, int status) -{ - std::list::iterator it; - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdConnectManager::msgin_connect_genmsg() Type: " << getConnectMsgType(msgtype); - std::cerr << " TransId: "; - bdPrintTransId(std::cerr, transId); - std::cerr << " From: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << " SrcAddr: "; - mFns->bdPrintId(std::cerr, srcAddr); - std::cerr << " DestAddr: "; - mFns->bdPrintId(std::cerr, destAddr); - std::cerr << " Mode: " << mode; - std::cerr << " Param: " << param; - std::cerr << " Status: " << status; - std::cerr << std::endl; -#else - (void) transId; -#endif - - /* switch to actual work functions */ - uint32_t peerflags = 0; - switch(msgtype) - { - case BITDHT_MSG_TYPE_CONNECT_REQUEST: - peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG; - mAccount.incCounter(BDACCOUNT_MSG_CONNECTREQUEST, false); - - - mConnMgr->recvedConnectionRequest(id, srcAddr, destAddr, mode, param); - - break; - case BITDHT_MSG_TYPE_CONNECT_REPLY: - peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG; - mAccount.incCounter(BDACCOUNT_MSG_CONNECTREPLY, false); - - mConnMgr->recvedConnectionReply(id, srcAddr, destAddr, mode, param, status); - - break; - case BITDHT_MSG_TYPE_CONNECT_START: - peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG; - mAccount.incCounter(BDACCOUNT_MSG_CONNECTSTART, false); - - mConnMgr->recvedConnectionStart(id, srcAddr, destAddr, mode, param); - - break; - case BITDHT_MSG_TYPE_CONNECT_ACK: - peerflags = BITDHT_PEER_STATUS_RECV_CONNECT_MSG; - mAccount.incCounter(BDACCOUNT_MSG_CONNECTACK, false); - - mConnMgr->recvedConnectionAck(id, srcAddr, destAddr, mode); - - break; - default: - break; - } - - /* received message - so peer must be good */ - addPeer(id, peerflags); - -} - - - - - - - - - - - -/****************** Other Functions ******************/ - -void bdNode::genNewToken(bdToken *token) -{ -#ifdef DEBUG_NODE_ACTIONS - fprintf(stderr, "bdNode::genNewToken()"); - fprintf(stderr, ")\n"); -#endif - - // XXX is this a good way to do it? - // Variable length, from 4 chars up to lots... 10? - // leave for the moment, but fix. - std::string num; - bd_sprintf(num, "%04lx", bdRandom::random_u32()); - int len = num.size(); - if (len > BITDHT_TOKEN_MAX_LEN) - len = BITDHT_TOKEN_MAX_LEN; - - for(int i = 0; i < len; i++) - { - token->data[i] = num[i]; - } - token->len = len; - -} - -uint32_t transIdCounter = 0; -void bdNode::genNewTransId(bdToken *token) -{ - /* generate message, send to udp */ -#ifdef DEBUG_NODE_ACTIONS - fprintf(stderr, "bdNode::genNewTransId()"); - fprintf(stderr, ")\n"); -#endif - - std::string num; - bd_sprintf(num, "%02lx", transIdCounter++); - int len = num.size(); - if (len > BITDHT_TOKEN_MAX_LEN) - len = BITDHT_TOKEN_MAX_LEN; - - for(int i = 0; i < len; i++) - { - token->data[i] = num[i]; - } - token->len = len; -} - - -/* Store Remote Query for processing */ -int bdNode::queueQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type) -{ -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdnode::queueQuery()" << std::endl; -#endif - - mRemoteQueries.push_back(bdRemoteQuery(id, query, transId, query_type)); - - return 1; -} - -/*************** Register Transaction Ids *************/ - -void bdNode::registerOutgoingMsg(bdId *id, bdToken *transId, uint32_t msgType, bdNodeId *aboutId) -{ - -#ifdef DEBUG_MSG_CHECKS - std::cerr << "bdNode::registerOutgoingMsg("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ", " << msgType << ")"; - std::cerr << std::endl; -#else - (void) id; - (void) msgType; -#endif - -#ifdef USE_HISTORY - - // splitting up - to see if we can isolate the crash causes. - switch(msgType) - { - // disabled types (which appear to crash it!) - case BITDHT_MSG_TYPE_PING: - if (!id) - { - return; - } - if ((id->id.data[0] == 0) - && (id->id.data[1] == 0) - && (id->id.data[2] == 0) - && (id->id.data[3] == 0)) - { - return; - } - break; - case BITDHT_MSG_TYPE_UNKNOWN: - case BITDHT_MSG_TYPE_PONG: - case BITDHT_MSG_TYPE_FIND_NODE: - case BITDHT_MSG_TYPE_REPLY_NODE: - case BITDHT_MSG_TYPE_GET_HASH: - case BITDHT_MSG_TYPE_REPLY_HASH: - case BITDHT_MSG_TYPE_REPLY_NEAR: - case BITDHT_MSG_TYPE_POST_HASH: - case BITDHT_MSG_TYPE_REPLY_POST: - break; - } - - // This line appears to cause crashes on OSX. - mHistory.addMsg(id, transId, msgType, false, aboutId); -#else - (void) transId; - (void) aboutId; -#endif - - - -/**** -#define BITDHT_MSG_TYPE_UNKNOWN 0 -#define BITDHT_MSG_TYPE_PING 1 -#define BITDHT_MSG_TYPE_PONG 2 -#define BITDHT_MSG_TYPE_FIND_NODE 3 -#define BITDHT_MSG_TYPE_REPLY_NODE 4 -#define BITDHT_MSG_TYPE_GET_HASH 5 -#define BITDHT_MSG_TYPE_REPLY_HASH 6 -#define BITDHT_MSG_TYPE_REPLY_NEAR 7 -#define BITDHT_MSG_TYPE_POST_HASH 8 -#define BITDHT_MSG_TYPE_REPLY_POST 9 -***/ - -} - - - -uint32_t bdNode::registerIncomingMsg(bdId *id, bdToken *transId, uint32_t msgType, bdNodeId *aboutId) -{ - -#ifdef DEBUG_MSG_CHECKS - std::cerr << "bdNode::registerIncomingMsg("; - mFns->bdPrintId(std::cerr, id); - std::cerr << ", " << msgType << ")"; - std::cerr << std::endl; -#else - (void) id; - (void) msgType; -#endif - -#ifdef USE_HISTORY - mHistory.addMsg(id, transId, msgType, true, aboutId); -#else - (void) transId; - (void) aboutId; -#endif - - return 0; -} - -void bdNode::cleanupTransIdRegister() -{ - return; -} - - - -/*************** Internal Msg Storage *****************/ - -bdNodeNetMsg::bdNodeNetMsg(char *msg, int len, struct sockaddr_in *in_addr) - :data(NULL), mSize(len), addr(*in_addr) -{ - data = (char *) malloc(len); - - if(data == NULL) - { - std::cerr << "(EE) " << __PRETTY_FUNCTION__ << ": ERROR. cannot allocate memory for " << len << " bytes." << std::endl; - return ; - } - - memcpy(data, msg, len); - //print(std::cerr); -} - -void bdNodeNetMsg::print(std::ostream &out) -{ - out << "bdNodeNetMsg::print(" << mSize << ") to " - << bdnet_inet_ntoa(addr.sin_addr) << ":" << htons(addr.sin_port); - out << std::endl; -} - - -bdNodeNetMsg::~bdNodeNetMsg() -{ - free(data); -} - - - -/**************** In/Out of Relay Mode ******************/ - -void bdNode::dropRelayServers() -{ - /* We leave them there... just drop the flags */ - uint32_t flags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER; - std::list peerList; - std::list::iterator it; - - mFriendList.findPeersWithFlags(flags, peerList); - for(it = peerList.begin(); it != peerList.end(); it++) - { - mFriendList.removePeer(&(*it)); - } - - mNodeSpace.clean_node_flags(flags); -} - -void bdNode::pingRelayServers() -{ - /* if Relay's have been switched on, do search/ping to locate servers */ -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::pingRelayServers()"; - std::cerr << std::endl; -#endif - - bool doSearch = true; - - uint32_t flags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER; - std::list peerList; - std::list::iterator it; - - mFriendList.findPeersWithFlags(flags, peerList); - for(it = peerList.begin(); it != peerList.end(); it++) - { - if (doSearch) - { - uint32_t qflags = BITDHT_QFLAGS_INTERNAL | BITDHT_QFLAGS_DISGUISE; - mQueryMgr->addQuery(&(*it), qflags); - -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdNode::pingRelayServers() Adding Internal Search for Relay Server: "; - mFns->bdPrintNodeId(std::cerr, &(*it)); - std::cerr << std::endl; -#endif - - } - else - { - /* try ping - if we have an address??? */ - - } - } -} - - diff --git a/libbitdht/src/bitdht/bdnode.h b/libbitdht/src/bitdht/bdnode.h deleted file mode 100644 index 39abbb435..000000000 --- a/libbitdht/src/bitdht/bdnode.h +++ /dev/null @@ -1,284 +0,0 @@ -/******************************************************************************* - * bitdht/bdnode.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_NODE_H -#define BITDHT_NODE_H - -#include "bitdht/bdpeer.h" -#include "bitdht/bdquery.h" -#include "bitdht/bdstore.h" -#include "bitdht/bdobj.h" -#include "bitdht/bdhash.h" -#include "bitdht/bdhistory.h" -#include "bitdht/bdfilter.h" - -#include "bitdht/bdconnection.h" -#include "bitdht/bdaccount.h" - -#include "bitdht/bdfriendlist.h" - -class bdFilter; - - -#define BD_QUERY_NEIGHBOURS 1 -#define BD_QUERY_LOCALNET 2 -#define BD_QUERY_HASH 3 - -/********************************** - * Running a node.... - * - * run(). - * loops through and checks out of date peers. - * handles searches. - * prints out dht Table. - * - -The node handles the i/o traffic from peers. -It - - - -ping, return -peers, return -hash store, return -hash get, return - - - -respond queue. - -query queue. - - - - - -input -> call into recvFunction() -output -> call back to Udp(). - - - - - *********/ - -class bdFilteredPeer ; -class bdNodeManager; - -class bdNodeNetMsg -{ - - public: - bdNodeNetMsg(char *data, int size, struct sockaddr_in *addr); - ~bdNodeNetMsg(); - - void print(std::ostream &out); - - char *data; - int mSize; - struct sockaddr_in addr; - -}; - -class bdNodePublisher -{ - public: - /* simplified outgoing msg functions (for the managers) */ - virtual void send_ping(bdId *id) = 0; /* message out */ - virtual void send_query(bdId *id, bdNodeId *targetNodeId, bool localnet) = 0; /* message out */ - virtual void send_connect_msg(bdId *id, int msgtype, - bdId *srcAddr, bdId *destAddr, int mode, int param, int status) = 0; - - // internal Callback -> normally continues to callbackConnect(). - virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, - int mode, int point, int param, int cbtype, int errcode) = 0; - -}; - - -class bdNode: public bdNodePublisher -{ - public: - - bdNode(bdNodeId *id, std::string dhtVersion, const std::string& bootfile, const std::string& bootfilebak, const std::string& filterfile, - bdDhtFunctions *fns, bdNodeManager* manager); - - void init(); /* sets up the self referential classes (mQueryMgr & mConnMgr) */ - - void setNodeOptions(uint32_t optFlags); - uint32_t setNodeDhtMode(uint32_t dhtFlags); - - /* startup / shutdown node */ - void restartNode(); - void shutdownNode(); - - void getOwnId(bdNodeId *id); - - // virtual so manager can do callback. - // peer flags defined in bdiface.h - virtual void addPeer(const bdId *id, uint32_t peerflags); - - void printState(); - void checkPotentialPeer(bdId *id, bdId *src); - void addPotentialPeer(bdId *id, bdId *src); - - void iterationOff(); - void iteration(); - void processRemoteQuery(); - void updateStore(); - - bool addressBanned(const sockaddr_in &raddr) ; - bool getFilteredPeers(std::list &peers); - //void loadFilteredPeers(const std::list &peers); - - /* simplified outgoing msg functions (for the managers) */ - virtual void send_ping(bdId *id); /* message out */ - virtual void send_query(bdId *id, bdNodeId *targetNodeId, bool localnet); /* message out */ - virtual void send_connect_msg(bdId *id, int msgtype, - bdId *srcAddr, bdId *destAddr, int mode, int param, int status); - -// This is implemented in bdManager. -// virtual void callbackConnect(bdId *srcId, bdId *proxyId, bdId *destId, -// int mode, int point, int param, int cbtype, int errcode); - - /* interaction with outside world (Accessed by controller to deliver us msgs) */ -int outgoingMsg(struct sockaddr_in *addr, char *msg, int *len); -void incomingMsg(struct sockaddr_in *addr, char *msg, int len); - - // For Relay Mode switching. -void dropRelayServers(); -void pingRelayServers(); - -// Below is internal Management of incoming / outgoing messages. - -private: - - /* internal interaction with network */ -void sendPkt(char *msg, int len, struct sockaddr_in addr); -void recvPkt(char *msg, int len, struct sockaddr_in addr); - - - /* output functions (send msg) */ - void msgout_ping(bdId *id, bdToken *transId); - void msgout_pong(bdId *id, bdToken *transId); - void msgout_find_node(bdId *id, bdToken *transId, bdNodeId *query, bool localnet); - void msgout_reply_find_node(bdId *id, bdToken *transId, - std::list &peers); - void msgout_get_hash(bdId *id, bdToken *transId, bdNodeId *info_hash); - void msgout_reply_hash(bdId *id, bdToken *transId, - bdToken *token, std::list &values); - void msgout_reply_nearest(bdId *id, bdToken *transId, - bdToken *token, std::list &peers); - - void msgout_post_hash(bdId *id, bdToken *transId, bdNodeId *info_hash, - uint32_t port, bdToken *token); - void msgout_reply_post(bdId *id, bdToken *transId); - - - /* input functions (once mesg is parsed) */ - uint32_t parseVersion(bdToken *versionId); - void msgin_ping(bdId *id, bdToken *token, bdToken *versionId); - void msgin_pong(bdId *id, bdToken *transId, bdToken *versionId); - - void msgin_find_node(bdId *id, bdToken *transId, bdNodeId *query, bool localnet); - void msgin_reply_find_node(bdId *id, bdToken *transId, - std::list &entries); - - void msgin_get_hash(bdId *id, bdToken *transId, bdNodeId *nodeid); - void msgin_reply_hash(bdId *id, bdToken *transId, - bdToken *token, std::list &values); - void msgin_reply_nearest(bdId *id, bdToken *transId, - bdToken *token, std::list &nodes); - - void msgin_post_hash(bdId *id, bdToken *transId, - bdNodeId *info_hash, uint32_t port, bdToken *token); - void msgin_reply_post(bdId *id, bdToken *transId); - - void msgout_connect_genmsg(bdId *id, bdToken *transId, int msgtype, - bdId *srcAddr, bdId *destAddr, int mode, int param, int status); - void msgin_connect_genmsg(bdId *id, bdToken *transId, int msgtype, - bdId *srcAddr, bdId *destAddr, int mode, int param, int status); - - - - /* token handling */ - void genNewToken(bdToken *token); - int queueQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type); - - /* transId handling */ - void genNewTransId(bdToken *token); - void registerOutgoingMsg(bdId *id, bdToken *transId, uint32_t msgType, bdNodeId *aboutId); - uint32_t registerIncomingMsg(bdId *id, bdToken *transId, uint32_t msgType, bdNodeId *aboutId); - - void cleanupTransIdRegister(); - - - void doStats(); - - /********** Variables **********/ - private: - - /**** Some Variables are Protected to allow inherited classes to use *****/ - protected: - - bdSpace mNodeSpace; - bdFilter mFilterPeers; - - bdQueryManager *mQueryMgr; - bdConnectManager *mConnMgr; - - bdNodeId mOwnId; - bdId mLikelyOwnId; // Try to workout own id address. - std::string mDhtVersion; - - bdAccount mAccount; - bdStore mStore; - - bdDhtFunctions *mFns; - bdHashSpace mHashSpace; - - bdFriendList mFriendList; - bdPeerQueue mBadPeerQueue; - - bdHistory mHistory; /* for understanding the DHT */ - - bdQueryHistory mQueryHistory; /* for determining old peers */ - - private: - - uint32_t mNodeOptionFlags; - uint32_t mNodeDhtMode; - - uint32_t mMaxAllowedMsgs; - uint32_t mRelayMode; - - - std::list mRemoteQueries; - - std::list mPotentialPeers; - - std::list mOutgoingMsgs; - std::list mIncomingMsgs; - -}; - - - -#endif // BITDHT_NODE_H diff --git a/libbitdht/src/bitdht/bdobj.cc b/libbitdht/src/bitdht/bdobj.cc deleted file mode 100644 index 9832796d2..000000000 --- a/libbitdht/src/bitdht/bdobj.cc +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * bitdht/bdobj.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdobj.h" - - -void bdPrintTransId(std::ostream &out, bdToken *transId) -{ - //out << transId->data; - bdPrintToken(out, transId); - return; -} - - -void bdPrintToken(std::ostream &out, bdToken *token) -{ - for(unsigned int i = 0; i < token->len; i++) - { - out << std::hex << (uint32_t) token->data[i]; - } - out << std::dec; -} - -void bdPrintCompactPeerId(std::ostream &out, std::string /*cpi*/ ) -{ - out << "DummyCompactPeerId"; -} - - diff --git a/libbitdht/src/bitdht/bdobj.h b/libbitdht/src/bitdht/bdobj.h deleted file mode 100644 index d193c59a8..000000000 --- a/libbitdht/src/bitdht/bdobj.h +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * bitdht/bdobj.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_OBJECTS_H -#define BITDHT_OBJECTS_H - -#define BITDHT_TOKEN_MAX_LEN 20 - -#include -#include - -class bdToken -{ - public: - bdToken() :len(0) { return; } - uint32_t len; - unsigned char data[BITDHT_TOKEN_MAX_LEN]; -}; - -class bdCompactIds -{ - public: - bdCompactIds() :len(0) { return; } - uint32_t len; - unsigned char data[BITDHT_TOKEN_MAX_LEN]; -}; - -class bdVersion -{ - public: - bdVersion() :len(0) { return; } - uint32_t len; - unsigned char data[BITDHT_TOKEN_MAX_LEN]; -}; - -void bdPrintTransId(std::ostream &out, bdToken *transId); -void bdPrintToken(std::ostream &out, bdToken *transId); -void bdPrintCompactPeerId(std::ostream &out, std::string cpi); - -#endif - diff --git a/libbitdht/src/bitdht/bdpeer.cc b/libbitdht/src/bitdht/bdpeer.cc deleted file mode 100644 index 65cfb31b5..000000000 --- a/libbitdht/src/bitdht/bdpeer.cc +++ /dev/null @@ -1,1276 +0,0 @@ -/******************************************************************************* - * bitdht/bdpeer.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdpeer.h" -#include "util/bdnet.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" -#include "bitdht/bdiface.h" - -#include -#include -#include - -#include -#include - -/** - * #define BITDHT_DEBUG 1 -**/ - -void bdSockAddrInit(struct sockaddr_in *addr) -{ - memset(addr, 0, sizeof(struct sockaddr_in)); - addr->sin_family = AF_INET; -} - -bdId::bdId() -{ - /* blank everything */ - bdSockAddrInit(&addr); - memset(&id.data, 0, BITDHT_KEY_LEN); -} - - -bdId::bdId(bdNodeId in_id, struct sockaddr_in in_addr) -{ - /* this bit is to ensure the address is valid for windows / osx */ - bdSockAddrInit(&addr); - addr.sin_addr.s_addr = in_addr.sin_addr.s_addr; - addr.sin_port = in_addr.sin_port; - - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - id.data[i] = in_id.data[i]; - } -}; - - -void bdZeroNodeId(bdNodeId *id) -{ - uint32_t *a_data = (uint32_t *) id->data; - for(int i = 0; i < BITDHT_KEY_INTLEN; i++) - { - a_data[i] = 0; - } - return; -} - - -int operator<(const bdNodeId &a, const bdNodeId &b) -{ -#if 0 - std::cerr << "operator<("); - bdPrintNodeId(std::cerr, &a); - std::cerr << ","; - bdPrintNodeId(std::cerr, &b); - std::cerr << ")" << std::endl; -#endif - - uint8_t *a_data = (uint8_t *) a.data; - uint8_t *b_data = (uint8_t *) b.data; - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - if (*a_data < *b_data) - { - //fprintf(stderr, "Return 1, at i = %d\n", i); - return 1; - } - else if (*a_data > *b_data) - { - //fprintf(stderr, "Return 0, at i = %d\n", i); - return 0; - } - a_data++; - b_data++; - } - //fprintf(stderr, "Return 0, at i = KEYLEN\n"); - return 0; -} - -#if 0 -int operator<(const struct sockaddr_in &a, const struct sockaddr_in &b) -{ - /* else NodeIds the same - check id addresses */ - if (a.sin_addr.s_addr < b.sin_addr.s_addr) - return 1; - if (b.sin_addr.s_addr > a.sin_addr.s_addr) - return 0; - - if (a.sin_port < b.sin_port) - return 1; - - return 0; -} -#endif - -int operator<(const bdId &a, const bdId &b) -{ - if (a.id < b.id) - return 1; - if (b.id < a.id) - return 0; - - /* else NodeIds the same - check id addresses */ - if (a.addr.sin_addr.s_addr < b.addr.sin_addr.s_addr) - return 1; - if (b.addr.sin_addr.s_addr > a.addr.sin_addr.s_addr) - return 0; - - if (a.addr.sin_port < b.addr.sin_port) - return 1; - - return 0; -} - - -int operator==(const bdNodeId &a, const bdNodeId &b) -{ - uint8_t *a_data = (uint8_t *) a.data; - uint8_t *b_data = (uint8_t *) b.data; - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - if (*a_data < *b_data) - { - return 0; - } - else if (*a_data > *b_data) - { - return 0; - } - a_data++; - b_data++; - } - return 1; -} - -int operator==(const bdId &a, const bdId &b) -{ - if (!(a.id == b.id)) - return 0; - - if ((a.addr.sin_addr.s_addr == b.addr.sin_addr.s_addr) && - (a.addr.sin_port == b.addr.sin_port)) - { - return 1; - } - return 0; -} - - - -bdBucket::bdBucket() -{ - return; -} - -bdSpace::bdSpace(bdNodeId *ownId, bdDhtFunctions *fns) - :mOwnId(*ownId), mFns(fns) -{ - /* make some space for data */ - buckets.resize(mFns->bdNumBuckets()); - - mAttachTS = 0; - mAttachedFlags = 0; - mAttachedCount = 0; - - return; -} - - /* empty the buckets */ -int bdSpace::clear() -{ - std::vector::iterator it; - /* iterate through the buckets, and sort by distance */ - for(it = buckets.begin(); it != buckets.end(); it++) - { - it->entries.clear(); - } - return 1; -} - -int bdSpace::setAttachedFlag(uint32_t withflags, int count) -{ - mAttachedFlags = withflags; - mAttachedCount = count; - mAttachTS = 0; - return 1; -} - -int bdSpace::find_nearest_nodes_with_flags(const bdNodeId *id, int number, - std::list /* excluding */, - std::multimap &nearest, uint32_t with_flags) -{ - std::multimap closest; - std::multimap::iterator mit; - - bdMetric dist; - mFns->bdDistance(id, &(mOwnId), &dist); - -#ifdef DEBUG_BD_SPACE - int bucket = mFns->bdBucketDistance(&dist); - - std::cerr << "bdSpace::find_nearest_nodes(NodeId:"; - mFns->bdPrintNodeId(std::cerr, id); - - std::cerr << " Number: " << number; - std::cerr << " Query Bucket #: " << bucket; - std::cerr << std::endl; -#endif - - std::vector::iterator it; - std::list::iterator eit; - /* iterate through the buckets, and sort by distance */ - for(it = buckets.begin(); it != buckets.end(); it++) - { - for(eit = it->entries.begin(); eit != it->entries.end(); eit++) - { - if ((!with_flags) || ((with_flags & eit->mPeerFlags) == with_flags)) - { - mFns->bdDistance(id, &(eit->mPeerId.id), &dist); - closest.insert(std::pair(dist, eit->mPeerId)); - -#if 0 - std::cerr << "Added NodeId: "; - bdPrintNodeId(std::cerr, &(eit->mPeerId.id)); - std::cerr << " Metric: "; - bdPrintNodeId(std::cerr, &(dist)); - std::cerr << std::endl; -#endif - } - } - } - - /* take the first number of nodes */ - int i = 0; - for(mit = closest.begin(); (mit != closest.end()) && (i < number); mit++, i++) - { - mFns->bdDistance(&(mOwnId), &(mit->second.id), &dist); - -#ifdef DEBUG_BD_SPACE - int iBucket = mFns->bdBucketDistance(&(mit->first)); - - std::cerr << "Closest " << i << ": "; - mFns->bdPrintNodeId(std::cerr, &(mit->second.id)); - std::cerr << " Bucket: " << iBucket; - std::cerr << std::endl; -#endif - - -#if 0 - std::cerr << "\tNodeId: "; - mFns->bdPrintNodeId(std::cerr, &(mit->second.id)); - std::cerr << std::endl; - - std::cerr << "\tOwn Id: "; - mFns->bdPrintNodeId(std::cerr, &(mOwnId)); - std::cerr << std::endl; - - std::cerr << " Us Metric: "; - mFns->bdPrintNodeId(std::cerr, &dist); - std::cerr << " Bucket: " << oBucket; - std::cerr << std::endl; - - std::cerr << "\tFindId: "; - mFns->bdPrintNodeId(std::cerr, id); - std::cerr << std::endl; - - std::cerr << " Id Metric: "; - mFns->bdPrintNodeId(std::cerr, &(mit->first)); - std::cerr << " Bucket: " << iBucket; - std::cerr << std::endl; -#endif - - nearest.insert(*mit); - } - -#ifdef DEBUG_BD_SPACE - std::cerr << "#Nearest: " << (int) nearest.size(); - std::cerr << " #Closest: " << (int) closest.size(); - std::cerr << " #Requested: " << number; - std::cerr << std::endl << std::endl; -#endif - - return 1; -} - -int bdSpace::find_nearest_nodes(const bdNodeId *id, int number, - std::multimap &nearest) -{ - std::list excluding; - uint32_t with_flag = 0; - - return find_nearest_nodes_with_flags(id, number, excluding, nearest, with_flag); -} - - -/* This is much cheaper than find nearest... we only look in the one bucket - */ - -int bdSpace::find_node(const bdNodeId *id, int number, std::list &matchIds, uint32_t with_flags) -{ - bdMetric dist; - mFns->bdDistance(id, &(mOwnId), &dist); - int buckno = mFns->bdBucketDistance(&dist); - -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_node(NodeId:"; - mFns->bdPrintNodeId(std::cerr, id); - std::cerr << ")"; - - std::cerr << " Number: " << number; - std::cerr << " Bucket #: " << buckno; - std::cerr << std::endl; -#else - (void)number; -#endif - - bdBucket &buck = buckets[buckno]; - - std::list::iterator eit; - int matchCount = 0; - for(eit = buck.entries.begin(); eit != buck.entries.end(); eit++) - { -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_node() Checking Against Peer: "; - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - std::cerr << " withFlags: " << eit->mPeerFlags; - std::cerr << std::endl; -#endif - - if ((!with_flags) || ((with_flags & eit->mPeerFlags) == with_flags)) - { - if (*id == eit->mPeerId.id) - { - matchIds.push_back(eit->mPeerId); - matchCount++; - -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_node() Found Matching Peer: "; - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - std::cerr << " withFlags: " << eit->mPeerFlags; - std::cerr << std::endl; -#endif - } - } - else - { - if (*id == eit->mPeerId.id) - { - //matchIds.push_back(eit->mPeerId); - //matchCount++; - -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_node() Found (WITHOUT FLAGS) Matching Peer: "; - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - std::cerr << " withFlags: " << eit->mPeerFlags; - std::cerr << std::endl; -#endif - } - } - } - -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_node() Found " << matchCount << " Matching Peers"; - std::cerr << std::endl << std::endl; -#endif - - return matchCount; -} - -/* even cheaper again... no big lists */ -int bdSpace::find_exactnode(const bdId *id, bdPeer &peer) -{ - bdMetric dist; - mFns->bdDistance(&(id->id), &(mOwnId), &dist); - int buckno = mFns->bdBucketDistance(&dist); - -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_exactnode(Id:"; - mFns->bdPrintId(std::cerr, id); - std::cerr << ")"; - - std::cerr << " Bucket #: " << buckno; - std::cerr << std::endl; -#endif - - bdBucket &buck = buckets[buckno]; - - std::list::iterator eit; - for(eit = buck.entries.begin(); eit != buck.entries.end(); eit++) - { - if (*id == eit->mPeerId) - { -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_exactnode() Found Matching Peer: "; - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - std::cerr << " withFlags: " << eit->mPeerFlags; - std::cerr << std::endl; -#endif - - peer = (*eit); - return 1; - } - } -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::find_exactnode() WARNING Failed to find Matching Peer: "; - std::cerr << std::endl; -#endif - - return 0; -} - - - -int bdSpace::clean_node_flags(uint32_t flags) -{ - std::cerr << "bdSpace::clean_node_flags(" << flags << ")"; - std::cerr << std::endl; - - int count = 0; - std::vector::iterator bit; - for(bit = buckets.begin(); bit != buckets.end(); bit++) - { - std::list::iterator eit; - for(eit = bit->entries.begin(); eit != bit->entries.end(); eit++) - { - if (flags & eit->mPeerFlags) - { -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::clean_node_flags() Found Match: "; - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - std::cerr << " withFlags: " << eit->mPeerFlags; - std::cerr << std::endl; -#endif - - count++; - eit->mPeerFlags &= ~flags; - } - } - } -#ifdef DEBUG_BD_SPACE - std::cerr << "bdSpace::clean_node_flags() Cleaned " << count << " Matching Peers"; - std::cerr << std::endl; -#endif - - return count; -} - - - -#define BITDHT_ATTACHED_SEND_PERIOD 17 - -int bdSpace::scanOutOfDatePeers(std::list &peerIds) -{ - /* - * - */ - bool doAttached = (mAttachedCount > 0); - uint32_t attachedCount = 0; - - std::map closest; - std::map::iterator mit; - - std::vector::iterator it; - std::list::iterator eit; - time_t ts = time(NULL); - - /* iterate through the buckets, and sort by distance */ - for(it = buckets.begin(); it != buckets.end(); it++) - { - for(eit = it->entries.begin(); eit != it->entries.end(); ) - { - bool added = false; - if (doAttached) - { - if (eit->mExtraFlags & BITDHT_PEER_EXFLAG_ATTACHED) - { - /* add to send list, if we haven't pinged recently */ - if ((ts - eit->mLastSendTime > BITDHT_ATTACHED_SEND_PERIOD ) && - (ts - eit->mLastRecvTime > BITDHT_ATTACHED_SEND_PERIOD )) - { - peerIds.push_back(eit->mPeerId); - eit->mLastSendTime = ts; - added = true; - } - attachedCount++; - } - } - - - /* timeout on last send time! */ - if ((!added) && (ts - eit->mLastSendTime > BITDHT_MAX_SEND_PERIOD )) - { - /* We want to ping a peer iff: - * 1) They are out-of-date: mLastRecvTime is too old. - * 2) They don't have 0x0001 flag (we haven't received a PONG) and never sent. - */ - if ((ts - eit->mLastRecvTime > BITDHT_MAX_SEND_PERIOD ) || - !(eit->mPeerFlags & BITDHT_PEER_STATUS_RECV_PONG)) - { - peerIds.push_back(eit->mPeerId); - eit->mLastSendTime = ts; - } - } - - - /* we also want to remove very old entries (should it happen here?) - * which are not pushed out by newer entries (will happen in for closer buckets) - */ - - bool discard = false; - /* discard very old entries */ - if (ts - eit->mLastRecvTime > BITDHT_DISCARD_PERIOD) - { - discard = true; - } - - /* discard peers which have not responded to anything (ie have no flags set) */ - /* changed into have not id'ed themselves, as we've added ping to list of flags. */ - if ((ts - eit->mFoundTime > BITDHT_MAX_RESPONSE_PERIOD ) && - !(eit->mPeerFlags & BITDHT_PEER_STATUS_RECV_PONG)) - { - discard = true; - } - - - /* INCREMENT */ - if (discard) - { - eit = it->entries.erase(eit); - } - else - { - eit++; - } - } - } - -#define ATTACH_UPDATE_PERIOD 600 - - if ((ts - mAttachTS > ATTACH_UPDATE_PERIOD) || (attachedCount != mAttachedCount)) - { - //std::cerr << "Updating ATTACH Stuff"; - //std::cerr << std::endl; - updateAttachedPeers(); /* XXX TEMP HACK to look at stability */ - mAttachTS = ts; - } - - return (peerIds.size()); -} - - -/* Attached should be changed to preferentially choose the ones we want - * If we have RELAYS enabled - then we want them to attach to the RELAYS - * Not sure about this yet! - * - * Have to think about it a bit more. (and redesign code to handle multiple passes) - */ - -int bdSpace::updateAttachedPeers() -{ - /* - * - */ - bool doAttached = (mAttachedCount > 0); - uint32_t attachedCount = 0; - - // Must scan through - otherwise we can never remove Attached state. - // It is only once every 10 minutes or so! -#if 0 - if (!doAttached) - { - return 0; - } -#endif - - std::map closest; - std::map::iterator mit; - - std::vector::iterator it; - std::list::reverse_iterator eit; - - - /* skip the first bucket, as we don't want to ping ourselves! */ - it = buckets.begin(); - if (it != buckets.end()) - { - it++; - } - - /* iterate through the buckets (sorted by distance) */ - for(; it != buckets.end(); it++) - { - /* start from the back, as these are the most recently seen (and more likely to be the old ATTACHED) */ - for(eit = it->entries.rbegin(); eit != it->entries.rend(); eit++) - { - if (doAttached) - { - if ((eit->mPeerFlags & mAttachedFlags) == mAttachedFlags) - { - /* flag as attached */ - eit->mExtraFlags |= BITDHT_PEER_EXFLAG_ATTACHED; - - /* inc count, and cancel search if we've found them */ - attachedCount++; - if (attachedCount >= mAttachedCount) - { - doAttached = false; - } - } - else - { - eit->mExtraFlags &= ~BITDHT_PEER_EXFLAG_ATTACHED; - } - } - else - { - eit->mExtraFlags &= ~BITDHT_PEER_EXFLAG_ATTACHED; - } - } - } - return 1; -} - - - - -/* Called to add or update peer. - * sorts bucket lists by lastRecvTime. - * updates requested node. - */ - -/* peer flags - * order is important! - * higher bits = more priority. - * BITDHT_PEER_STATUS_RECVPING - * BITDHT_PEER_STATUS_RECVPONG - * BITDHT_PEER_STATUS_RECVNODES - * BITDHT_PEER_STATUS_RECVHASHES - * BITDHT_PEER_STATUS_DHT_ENGINE (dbXXxx) - * BITDHT_PEER_STATUS_DHT_APPL (XXRSxx) - * BITDHT_PEER_STATUS_DHT_VERSION (XXxx50) - * - */ - -int bdSpace::add_peer(const bdId *id, uint32_t peerflags) -{ - /* find the peer */ - bool add = false; - time_t ts = time(NULL); - -#ifdef DEBUG_BD_SPACE - fprintf(stderr, "bdSpace::add_peer()\n"); -#endif - - /* calculate metric */ - bdMetric met; - mFns->bdDistance(&(mOwnId), &(id->id), &met); - int bucket = mFns->bdBucketDistance(&met); - -#ifdef DEBUG_BD_SPACE - fprintf(stderr, "peer:"); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, " bucket: %d", bucket); - fprintf(stderr, "\n"); -#endif - - /* select correct bucket */ - bdBucket &buck = buckets[bucket]; - - - std::list::iterator it; - - /* calculate the score for this new peer */ - uint32_t minScore = peerflags; - - /* loop through ids, to find it */ - for(it = buck.entries.begin(); it != buck.entries.end(); it++) - { - /* similar id check */ - if (mFns->bdSimilarId(id, &(it->mPeerId))) - { - bdPeer peer = *it; - it = buck.entries.erase(it); - - peer.mLastRecvTime = ts; - peer.mPeerFlags |= peerflags; /* must be cumulative ... so can do online, replynodes, etc */ - - /* also update port from incoming id, as we have definitely recved from it */ - if (mFns->bdUpdateSimilarId(&(peer.mPeerId), id)) - { - /* updated it... must be Unstable */ - peer.mExtraFlags |= BITDHT_PEER_EXFLAG_UNSTABLE; - } - - buck.entries.push_back(peer); - -#ifdef DEBUG_BD_SPACE - std::cerr << "Peer already in bucket: moving to back of the list" << std::endl; -#endif - - return 1; - } - - /* find lowest score */ - if (it->mPeerFlags < minScore) - { - minScore = it->mPeerFlags; - } - } - - /* not in the list! */ - - if (buck.entries.size() < mFns->bdNodesPerBucket()) - { -#ifdef DEBUG_BD_SPACE - std::cerr << "Bucket not full: allowing add" << std::endl; -#endif - add = true; - } - else - { - /* check head of list */ - bdPeer &peer = buck.entries.front(); - if (ts - peer.mLastRecvTime > BITDHT_MAX_RECV_PERIOD) - { -#ifdef DEBUG_BD_SPACE - std::cerr << "Dropping Out-of-Date peer in bucket" << std::endl; -#endif - buck.entries.pop_front(); - add = true; - } - else if (peerflags > minScore) - { - /* find one to drop */ - for(it = buck.entries.begin(); it != buck.entries.end(); it++) - { - if (it->mPeerFlags == minScore) - { - /* delete low priority peer */ - it = buck.entries.erase(it); - add = true; - break; - } - } - -#ifdef DEBUG_BD_SPACE - std::cerr << "Inserting due to Priority: minScore: " << minScore - << " new Peer Score: " << peerscore << << std::endl; -#endif - } - else - { -#ifdef DEBUG_BD_SPACE - std::cerr << "No Out-Of-Date peers in bucket... dropping new entry" << std::endl; -#endif - } - } - - if (add) - { - bdPeer newPeer; - - newPeer.mPeerId = *id; - newPeer.mLastRecvTime = ts; - newPeer.mLastSendTime = 0; // ts; //???? - newPeer.mFoundTime = ts; - newPeer.mPeerFlags = peerflags; - newPeer.mExtraFlags = 0; - - buck.entries.push_back(newPeer); - -#ifdef DEBUG_BD_SPACE - /* useful debug */ - std::cerr << "bdSpace::add_peer() Added Bucket["; - std::cerr << bucket << "] Entry: "; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - } - return add; -} - - /* flag peer */ -bool bdSpace::flagpeer(const bdId *id, uint32_t flags, uint32_t ex_flags) -{ -#ifdef DEBUG_BD_SPACE - fprintf(stderr, "bdSpace::flagpeer()\n"); -#endif - - /* calculate metric */ - bdMetric met; - mFns->bdDistance(&(mOwnId), &(id->id), &met); - int bucket = mFns->bdBucketDistance(&met); - - - /* select correct bucket */ - bdBucket &buck = buckets[bucket]; - - /* loop through ids, to find it */ - std::list::iterator it; - for(it = buck.entries.begin(); it != buck.entries.end(); it++) - { - /* similar id check */ - if (mFns->bdSimilarId(id, &(it->mPeerId))) - { -#ifdef DEBUG_BD_SPACE - fprintf(stderr, "peer:"); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, " bucket: %d", bucket); - fprintf(stderr, "\n"); - fprintf(stderr, "Original Flags: %x Extra: %x\n", - it->mPeerFlags, it->mExtraFlags); -#endif - it->mPeerFlags |= flags; - it->mExtraFlags |= ex_flags; - -#ifdef DEBUG_BD_SPACE - fprintf(stderr, "Updated Flags: %x Extra: %x\n", - it->mPeerFlags, it->mExtraFlags); -#endif - } - } - return true; -} - -/* print tables. - */ - -int bdSpace::printDHT() -{ - std::map closest; - std::map::iterator mit; - - std::vector::iterator it; - std::list::iterator eit; - - /* iterate through the buckets, and sort by distance */ - int i = 0; - -#ifdef BITDHT_DEBUG - fprintf(stderr, "bdSpace::printDHT()\n"); - for(it = buckets.begin(); it != buckets.end(); it++, i++) - { - if (it->entries.size() > 0) - { - fprintf(stderr, "Bucket %d ----------------------------\n", i); - } - - for(eit = it->entries.begin(); eit != it->entries.end(); eit++) - { - bdMetric dist; - mFns->bdDistance(&(mOwnId), &(eit->mPeerId.id), &dist); - - fprintf(stderr, " Metric: "); - mFns->bdPrintNodeId(std::cerr, &(dist)); - fprintf(stderr, " Id: "); - mFns->bdPrintId(std::cerr, &(eit->mPeerId)); - fprintf(stderr, " PeerFlags: %08x", eit->mPeerFlags); - fprintf(stderr, "\n"); - } - } -#endif - - fprintf(stderr, "--------------------------------------\n"); - fprintf(stderr, "DHT Table Summary --------------------\n"); - fprintf(stderr, "--------------------------------------\n"); - - /* little summary */ - unsigned long long sum = 0; - unsigned long long no_peers = 0; - uint32_t count = 0; - bool doPrint = false; - bool doAvg = false; - - i = 0; - for(it = buckets.begin(); it != buckets.end(); it++, i++) - { - int size = it->entries.size(); - int shift = BITDHT_KEY_BITLEN - i; - bool toBig = false; - - if (shift > BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1) - { - toBig = true; - shift = BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1; - } - unsigned long long no_nets = ((unsigned long long) 1 << shift); - - /* use doPrint so it acts as a single switch */ - if (size && !doAvg && !doPrint) - { - doAvg = true; - } - - if (size && !doPrint) - { - doPrint = true; - } - - if (size == 0) - { - /* reset counters - if empty slot - to discount outliers in average */ - sum = 0; - no_peers = 0; - count = 0; - } - - if (doPrint) - { - if (size) - fprintf(stderr, "Bucket %d: %d peers: ", i, size); -#ifdef BITDHT_DEBUG - else - fprintf(stderr, "Bucket %d: %d peers: ", i, size); -#endif - } - if (toBig) - { - if (size) - { - if (doPrint) - bd_fprintf(stderr, "Estimated NetSize >> %llu\n", no_nets); - } - else - { -#ifdef BITDHT_DEBUG - if (doPrint) - bd_fprintf(stderr, " Bucket = Net / >> %llu\n", no_nets); -#endif - } - } - else - { - no_peers = no_nets * size; - if (size) - { - if (doPrint) - bd_fprintf(stderr, "Estimated NetSize = %llu\n", no_peers); - } - else - { - -#ifdef BITDHT_DEBUG - if (doPrint) - bd_fprintf(stderr, " Bucket = Net / %llu\n", no_nets); -#endif - - } - } - if (doPrint && doAvg && !toBig) - { - if (size == mFns->bdNodesPerBucket()) - { - /* last average */ - doAvg = false; - } - if (no_peers != 0) - { - sum += no_peers; - count++; -#ifdef BITDHT_DEBUG - fprintf(stderr, "Est: %d: %llu => %llu / %d\n", - i, no_peers, sum, count); -#endif - } - } - - } - if (count == 0) - { - fprintf(stderr, "Zero Network Size (count = 0)\n"); - } - else - { - bd_fprintf(stderr, "Estimated Network Size = (%llu / %d) = %llu\n", sum, count, sum / count); - } - - return 1; -} - - -int bdSpace::getDhtBucket(const int idx, bdBucket &bucket) -{ - if ((idx < 0) || (idx > (int) buckets.size() - 1 )) - { - return 0; - } - bucket = buckets[idx]; - return 1; -} - -uint32_t bdSpace::calcNetworkSize() -{ - return calcNetworkSizeWithFlag(~0u) ; -} - -uint32_t bdSpace::calcNetworkSizeWithFlag(uint32_t withFlag) -{ - std::vector::iterator it; - - /* little summary */ - unsigned long long sum = 0; - unsigned long long no_peers = 0; - uint32_t count = 0; - -#ifdef BITDHT_DEBUG - std::cerr << "Estimating DHT network size. Flags=" << std::hex << withFlag << std::dec << std::endl; -#endif - - int i = 0; - for(it = buckets.begin(); it != buckets.end(); it++, i++) - { - int size = 0; - std::list::iterator lit; - for(lit = it->entries.begin(); lit != it->entries.end(); lit++) - if (withFlag & lit->mPeerFlags) - size++; - - int shift = BITDHT_KEY_BITLEN - i; - - if (shift > BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1) - continue ; - - unsigned long long no_nets = ((unsigned long long) 1 << shift); - - no_peers = no_nets * size; - - if(size < mFns->bdNodesPerBucket() && size > 0) - { - sum += no_peers; - count++; - } - -#ifdef BITDHT_DEBUG - if(size > 0) - std::cerr << " Bucket " << shift << ": " << size << " / " << mFns->bdNodesPerBucket() << " peers. no_nets=" << no_nets << ". no_peers=" << no_peers << "." << std::endl; -#endif - } - - - uint32_t NetSize = 0; - if (count != 0) - NetSize = sum / count; - -#ifdef BITDHT_DEBUG - std::cerr << "Estimated net size: " << NetSize << ". Old style estimate: " << calcNetworkSizeWithFlag_old(withFlag) << std::endl; -#endif - - return NetSize; -} - -/* (csoler) This is the old method for computing the DHT size estimate. The method is based on averaging the - * estimate given by each bucket: n 2^b where n is the bucket size and b is the number of similar bits - * in this bucket. The idea is that buckets that are not empty nor full give a estimate of the network - * size. - * - * The existing implementation of this method was not using all non empty/full buckets, in order to avoid - * outliers, but this method is also biased, and tends to give a lower value (because it skips the largest buckets) - * especially when the network is very sparse. - * - * The new implementation respects the original estimate without bias, but it still notoriously wrong. Only averaging - * the estimate over a large period of time would produce a reliable value. - */ -uint32_t bdSpace::calcNetworkSizeWithFlag_old(uint32_t withFlag) -{ - std::vector::iterator it; - - /* little summary */ - unsigned long long sum = 0; - unsigned long long no_peers = 0; - uint32_t count = 0; - uint32_t totalcount = 0; - bool doPrint = false; - bool doAvg = false; - - int i = 0; - for(it = buckets.begin(); it != buckets.end(); it++, i++) - { - int size = 0; - std::list::iterator lit; - for(lit = it->entries.begin(); lit != it->entries.end(); lit++) - { - if (withFlag & lit->mPeerFlags) - { - size++; - } - } - - totalcount += size; - - int shift = BITDHT_KEY_BITLEN - i; - bool toBig = false; - - if (shift > BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1) - { - toBig = true; - shift = BITDHT_ULLONG_BITS - mFns->bdBucketBitSize() - 1; - } - unsigned long long no_nets = ((unsigned long long) 1 << shift); - - - /* use doPrint so it acts as a single switch */ - if (size && !doAvg && !doPrint) - { - doAvg = true; - } - - if (size && !doPrint) - { - doPrint = true; - } - - if (size == 0) - { - /* reset counters - if empty slot - to discount outliers in average */ - sum = 0; - no_peers = 0; - count = 0; - } - - if (!toBig) - { - no_peers = no_nets * size; - } - - if (doPrint && doAvg && !toBig) - { - if (size == mFns->bdNodesPerBucket()) - { - /* last average */ - doAvg = false; - } - if (no_peers != 0) - { - sum += no_peers; - count++; - } - } - } - - - uint32_t NetSize = 0; - if (count != 0) - { - NetSize = sum / count; - } - - //std::cerr << "bdSpace::calcNetworkSize() : " << NetSize; - //std::cerr << std::endl; - - return NetSize; -} - -uint32_t bdSpace::calcSpaceSize() -{ - std::vector::iterator it; - - /* little summary */ - uint32_t totalcount = 0; - for(it = buckets.begin(); it != buckets.end(); it++) - { - totalcount += it->entries.size(); - } - return totalcount; -} - -uint32_t bdSpace::calcSpaceSizeWithFlag(uint32_t withFlag) -{ - std::vector::iterator it; - - /* little summary */ - uint32_t totalcount = 0; - - it = buckets.begin(); - if (it != buckets.end()) - { - it++; /* skip own bucket! */ - } - for(; it != buckets.end(); it++) - { - int size = 0; - std::list::iterator lit; - for(lit = it->entries.begin(); lit != it->entries.end(); lit++) - { - if (withFlag & lit->mPeerFlags) - { - size++; - } - } - totalcount += size; - } - return totalcount; -} - - /* special function to enable DHT localisation (i.e find peers from own network) */ -bool bdSpace::findRandomPeerWithFlag(bdId &id, uint32_t withFlag) -{ - std::vector::iterator it; - uint32_t totalcount = calcSpaceSizeWithFlag(withFlag); - - if(totalcount == 0) - return false ; - - uint32_t rnd = bdRandom::random_u32() % totalcount; - uint32_t i = 0; - uint32_t buck = 0; - - //std::cerr << "bdSpace::findRandomPeerWithFlag()"; - //std::cerr << std::endl; - - it = buckets.begin(); - if (it != buckets.end()) - { - it++; /* skip own bucket! */ - buck++; - } - for(; it != buckets.end(); it++, buck++) - { - std::list::iterator lit; - for(lit = it->entries.begin(); lit != it->entries.end(); lit++) - { - if (withFlag & lit->mPeerFlags) - { - if (i == rnd) - { -#ifdef BITDHT_DEBUG - std::cerr << "bdSpace::findRandomPeerWithFlag() found #" << i; - std::cerr << " in bucket #" << buck; - std::cerr << std::endl; -#endif - /* found */ - id = lit->mPeerId; - return true; - } - i++; - } - } - } - std::cerr << "bdSpace::findRandomPeerWithFlag() failed to find " << rnd << " / " << totalcount; - std::cerr << std::endl; -#ifdef BITDHT_DEBUG -#endif - - return false; -} - diff --git a/libbitdht/src/bitdht/bdpeer.h b/libbitdht/src/bitdht/bdpeer.h deleted file mode 100644 index d663a7ecd..000000000 --- a/libbitdht/src/bitdht/bdpeer.h +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * bitdht/bdpeer.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_PEER_H -#define BITDHT_PEER_H - -#include "bitdht/bdiface.h" -#include - -/******* - * These type of parameters are now DHT Function dependent - * -#define BITDHT_BUCKET_SIZE 20 -#define BITDHT_BUCKET_SIZE_BITS 5 - -#define BITDHT_N_BUCKETS BITDHT_KEY_BITLEN - * - * - ***/ - -/*** - * DEFINED in bdiface.h - * #define BITDHT_KEY_LEN 20 - * #define BITDHT_KEY_INTLEN 5 - * #define BITDHT_KEY_BITLEN 160 - ***/ - -#define BITDHT_ULLONG_BITS 64 - -#define BITDHT_MAX_RESPONSE_PERIOD (15) -#define BITDHT_MAX_SEND_PERIOD 300 // 5 minutes. -#define BITDHT_MAX_RECV_PERIOD (BITDHT_MAX_SEND_PERIOD + BITDHT_MAX_RESPONSE_PERIOD) // didn't respond to a ping. - -// Properly out of date. -#define BITDHT_DISCARD_PERIOD (2 * BITDHT_MAX_SEND_PERIOD + BITDHT_MAX_RESPONSE_PERIOD) // didn't respond to two pings. - -// Must have a FLAG by this time. (Make it really quick - so we through away the rubbish). - - -#include -#include -#include -#include - -/**** - * DEFINED in bdiface.h - * - * class bdNodeId - * { - * public: - * unsigned char data[BITDHT_KEY_LEN]; - * }; - ****/ - - -/**** - * DEFINED in bdiface.h - * - -class bdMetric: public bdNodeId {}; - -class bdId -{ - public: - - bdId(); - bdId(bdNodeId in_id, struct sockaddr_in in_addr); - - struct sockaddr_in addr; - bdNodeId id; -}; - * - *********/ - - - -//void bdRandomNodeId(bdNodeId *id); - -// Only Functions that are common for all Dhts. -// zero, basic comparisons.. -void bdZeroNodeId(bdNodeId *id); - -//void bdRandomId(bdId *id); -//int bdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r); -//int bdBucketDistance(const bdMetric *m); -//int bdBucketDistance(const bdNodeId *a, const bdNodeId *b); -//int operator<(const bdMetric &a, const bdMetric &b); - -//int operator<(const struct sockaddr_in &a, const struct sockaddr_in &b); - -int operator<(const bdNodeId &a, const bdNodeId &b); -int operator<(const bdId &a, const bdId &b); -int operator==(const bdNodeId &a, const bdNodeId &b); -int operator==(const bdId &a, const bdId &b); - -//void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid); - -//void bdPrintId(std::ostream &out, const bdId *a); -//void bdPrintNodeId(std::ostream &out, const bdNodeId *a); - -//std::string bdConvertToPrintable(std::string input); - -/**** - * DEFINED in bdiface.h - * - -class bdPeer -{ - public: - - bdId mPeerId; - uint32_t mPeerFlags; - time_t mLastSendTime; - time_t mLastRecvTime; - time_t mFoundTime; // time stamp that peer was found -}; - - -class bdBucket -{ - public: - - bdBucket(); - - // list so we can queue properly - std::list entries; -}; - * - * - *****/ - -class bdSpace -{ - public: - - bdSpace(bdNodeId *ownId, bdDhtFunctions *fns); - -int clear(); - -int setAttachedFlag(uint32_t withflags, int count); - - /* accessors */ -int find_nearest_nodes(const bdNodeId *id, int number, - std::multimap &nearest); - -int find_nearest_nodes_with_flags(const bdNodeId *id, int number, - std::list excluding, - std::multimap &nearest, uint32_t with_flag); - -int find_node(const bdNodeId *id, int number, - std::list &matchIds, uint32_t with_flag); -int find_exactnode(const bdId *id, bdPeer &peer); - -// switched to more efficient single sweep. -//int out_of_date_peer(bdId &id); // side-effect updates, send flag on peer. -int scanOutOfDatePeers(std::list &peerIds); -int updateAttachedPeers(); - -int add_peer(const bdId *id, uint32_t mode); -int printDHT(); -int getDhtBucket(const int idx, bdBucket &bucket); - -uint32_t calcNetworkSize(); -uint32_t calcNetworkSizeWithFlag(uint32_t withFlag); -uint32_t calcNetworkSizeWithFlag_old(uint32_t withFlag); -uint32_t calcSpaceSize(); -uint32_t calcSpaceSizeWithFlag(uint32_t withFlag); - - /* special function to enable DHT localisation (i.e find peers from own network) */ -bool findRandomPeerWithFlag(bdId &id, uint32_t withFlag); - - /* strip out flags - to switch in/out of relay mode */ -int clean_node_flags(uint32_t flags); - - /* to add later */ -int updateOwnId(bdNodeId *newOwnId); - - /* flag peer */ -bool flagpeer(const bdId *id, uint32_t flags, uint32_t ex_flags); - - private: - - std::vector buckets; - bdNodeId mOwnId; - bdDhtFunctions *mFns; - - uint32_t mAttachedFlags; - uint32_t mAttachedCount; - time_t mAttachTS; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdquery.cc b/libbitdht/src/bitdht/bdquery.cc deleted file mode 100644 index f9b77002d..000000000 --- a/libbitdht/src/bitdht/bdquery.cc +++ /dev/null @@ -1,1198 +0,0 @@ -/******************************************************************************* - * bitdht/bdquery.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdquery.h" -#include "bitdht/bdstddht.h" -#include "util/bdnet.h" - -#include -#include -#include - -/** - * #define DEBUG_QUERY 1 -**/ - -#define EXPECTED_REPLY 10 // Speed up queries -#define QUERY_IDLE_RETRY_PEER_PERIOD 600 // 10min = (mFns->bdNumQueryNodes() * 60) -#define MAX_QUERY_IDLE_PERIOD 1200 // 20min. - - -/************************************************************ - * bdQuery logic: - * 1) as replies come in ... maintain list of M closest peers to ID. - * 2) select non-queried peer from list, and query. - * 3) halt when we have asked all M closest peers about the ID. - * - * Flags can be set to disguise the target of the search. - * This involves - */ - -bdQuery::bdQuery(const bdNodeId *id, std::list &startList, uint32_t queryFlags, - bdDhtFunctions *fns) -{ - /* */ - mId = *id; - mFns = fns; - - time_t now = time(NULL); - std::list::iterator it; - for(it = startList.begin(); it != startList.end(); it++) - { - bdPeer peer; - peer.mLastSendTime = 0; - peer.mLastRecvTime = 0; - peer.mPeerFlags = 0; - peer.mFoundTime = now; - peer.mPeerId = *it; - - bdMetric dist; - - mFns->bdDistance(&mId, &(peer.mPeerId.id), &dist); - - mClosest.insert(std::pair(dist, peer)); - - - } - - mState = BITDHT_QUERY_QUERYING; - mQueryFlags = queryFlags; - mQueryTS = now; - mSearchTime = 0; - mClosestListSize = (int) (1.5 * mFns->bdNumQueryNodes()); - mPotPeerCleanTS = now; - - mQueryIdlePeerRetryPeriod = QUERY_IDLE_RETRY_PEER_PERIOD; - mRequiredPeerFlags = BITDHT_PEER_STATUS_DHT_ENGINE_VERSION; // XXX to update later. - - /* setup the limit of the search - * by default it is setup to 000000 = exact match - */ - bdZeroNodeId(&mLimit); -} - -bool bdQuery::result(std::list &answer) -{ - /* get all the matches to our query */ - std::multimap::iterator sit, eit; - sit = mClosest.begin(); - eit = mClosest.upper_bound(mLimit); - int i = 0; - for(; sit != eit; sit++) - { - if ((sit->second).mLastRecvTime != 0) - { - answer.push_back(sit->second.mPeerId); - i++; - } - } - return (i > 0); -} - - -int bdQuery::nextQuery(bdId &id, bdNodeId &targetNodeId) -{ - if ((mState != BITDHT_QUERY_QUERYING) && !(mQueryFlags & BITDHT_QFLAGS_DO_IDLE)) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Query is done\n"); -#endif - return 0; - } - - /* search through through list, find closest not queried */ - time_t now = time(NULL); - - /* update IdlePeerRetry */ - if ((now - mQueryTS) / 2 > mQueryIdlePeerRetryPeriod) - { - mQueryIdlePeerRetryPeriod = (now-mQueryTS) / 2; - if (mQueryIdlePeerRetryPeriod > MAX_QUERY_IDLE_PERIOD) - { - mQueryIdlePeerRetryPeriod = MAX_QUERY_IDLE_PERIOD; - } - } - - bool notFinished = false; - std::multimap::iterator it; - int i = 0; - for(it = mClosest.begin(); it != mClosest.end(); it++, i++) - { - bool queryPeer = false; - - /* if never queried */ - if (it->second.mLastSendTime == 0) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Found non-sent peer. queryPeer = true : "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - std::cerr << std::endl; -#endif - queryPeer = true; - } - - /* re-request every so often */ - if ((!queryPeer) && (mQueryFlags & BITDHT_QFLAGS_DO_IDLE) && - (now - it->second.mLastSendTime > mQueryIdlePeerRetryPeriod)) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Found out-of-date. queryPeer = true : "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - std::cerr << std::endl; -#endif - queryPeer = true; - } - - /* expecting every peer to be up-to-date is too hard... - * enough just to have received lists from each - * - replacement policy will still work. - * - * Need to wait at least EXPECTED_REPLY, to make sure their answers are pinged - */ - - if (((it->second.mLastRecvTime == 0) || (now - it->second.mLastRecvTime < EXPECTED_REPLY)) && - (i < mFns->bdNumQueryNodes())) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Never Received @Idx(%d) notFinished = true: ", i); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - std::cerr << std::endl; -#endif - notFinished = true; - } - - if (queryPeer) - { - id = it->second.mPeerId; - it->second.mLastSendTime = now; - - if (mQueryFlags & BITDHT_QFLAGS_DISGUISE) - { - /* calc Id mid point between Target and Peer */ - bdNodeId midRndId; - mFns->bdRandomMidId(&mId, &(id.id), &midRndId); - - targetNodeId = midRndId; - } - else - { - targetNodeId = mId; - } -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Querying Peer: "); - mFns->bdPrintId(std::cerr, &id); - std::cerr << std::endl; -#endif - return 1; - } - } - - /* allow query to run for a minimal amount of time - * This is important as startup - when we might not have any peers. - * Probably should be handled elsewhere. - */ - time_t age = now - mQueryTS; - - if (age < BITDHT_MIN_QUERY_AGE) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() under Min Time: Query not finished / No Query\n"); -#endif - return 0; - } - - if (age > BITDHT_MAX_QUERY_AGE) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() over Max Time: Query force to Finish\n"); -#endif - /* fall through and stop */ - } - else if ((mClosest.size() < mFns->bdNumQueryNodes()) || (notFinished)) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() notFinished | !size(): Query not finished / No Query\n"); -#endif - /* not full yet... */ - return 0; - } - -#ifdef DEBUG_QUERY - fprintf(stderr, "NextQuery() Finished\n"); -#endif - - /* if we get here - query finished */ - if (mState == BITDHT_QUERY_QUERYING) - { - /* store query time */ - mSearchTime = now - mQueryTS; - } - - /* cleanup PotentialPeers before doing the final State */; - removeOldPotentialPeers(); - /* check if we found the node */ - if (mClosest.size() > 0) - { - if (((mClosest.begin()->second).mPeerId.id == mId) && - ((mClosest.begin()->second).mLastRecvTime != 0)) - { - mState = BITDHT_QUERY_SUCCESS; - } - else if ((mPotentialPeers.begin()->second).mPeerId.id == mId) - { - mState = BITDHT_QUERY_PEER_UNREACHABLE; - } - else - { - mState = BITDHT_QUERY_FOUND_CLOSEST; - } - } - else - { - mState = BITDHT_QUERY_FAILURE; - } - return 0; -} - -int bdQuery::addClosestPeer(const bdId *id, uint32_t mode) -{ - bdMetric dist; - time_t ts = time(NULL); - - mFns->bdDistance(&mId, &(id->id), &dist); - -#ifdef DEBUG_QUERY - fprintf(stderr, "bdQuery::addPeer("); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, ", %u)\n", mode); -#endif - - std::multimap::iterator it, sit, eit; - sit = mClosest.lower_bound(dist); - eit = mClosest.upper_bound(dist); - int i = 0; - int actualCloser = 0; - int toDrop = 0; - // switched end condition to upper_bound to provide stability for NATTED peers. - // we will favour the older entries! - for(it = mClosest.begin(); it != eit; it++, i++, actualCloser++) - { - time_t sendts = ts - it->second.mLastSendTime; - bool hasSent = (it->second.mLastSendTime != 0); - bool hasReply = (it->second.mLastRecvTime >= it->second.mLastSendTime); - if ((hasSent) && (!hasReply) && (sendts > EXPECTED_REPLY)) - { - i--; /* dont count this one */ - toDrop++; - } - } - // Counts where we are. -#ifdef DEBUG_QUERY - fprintf(stderr, "Searching.... %di = %d - %d peers closer than this one\n", i, actualCloser, toDrop); -#endif - - - if (i > mClosestListSize - 1) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Distance to far... dropping\n"); -#endif - /* drop it */ - return 0; - } - - for(it = sit; it != eit; it++, i++) - { - /* full id check */ - if (mFns->bdSimilarId(id, &(it->second.mPeerId))) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Peer Already here!\n"); -#endif - if (mode) - { - /* also update port from incoming id, as we have definitely recved from it */ - if (mFns->bdUpdateSimilarId(&(it->second.mPeerId), id)) - { - /* updated it... must be Unstable */ - it->second.mExtraFlags |= BITDHT_PEER_EXFLAG_UNSTABLE; - } - } - if (mode & BITDHT_PEER_STATUS_RECV_NODES) - { - /* only update recvTime if sendTime > checkTime.... (then its our query) */ -#ifdef DEBUG_QUERY - fprintf(stderr, "Updating LastRecvTime\n"); -#endif - it->second.mLastRecvTime = ts; - it->second.mPeerFlags |= mode; - } - return 1; - } - } - -#ifdef DEBUG_QUERY - fprintf(stderr, "Peer not in Query\n"); -#endif - /* firstly drop unresponded (bit ugly - but hard structure to extract from) */ - int j; - for(j = 0; j < toDrop; j++) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Dropping Peer that dont reply\n"); -#endif - for(it = mClosest.begin(); it != mClosest.end(); ++it) - { - time_t sendts = ts - it->second.mLastSendTime; - bool hasSent = (it->second.mLastSendTime != 0); - bool hasReply = (it->second.mLastRecvTime >= it->second.mLastSendTime); - - if ((hasSent) && (!hasReply) && (sendts > EXPECTED_REPLY)) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Dropped: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, "\n"); -#endif - mClosest.erase(it); - break ; - } - } - } - - /* trim it back */ - while(mClosest.size() > (uint32_t) (mClosestListSize - 1)) - { - std::multimap::iterator it; - it = mClosest.end(); - if (!mClosest.empty()) - { - it--; -#ifdef DEBUG_QUERY - fprintf(stderr, "Removing Furthest Peer: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, "\n"); -#endif - - mClosest.erase(it); - } - } - -#ifdef DEBUG_QUERY - fprintf(stderr, "bdQuery::addPeer(): Closer Peer!: "); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, "\n"); -#endif - - /* add it in */ - bdPeer peer; - peer.mPeerId = *id; - peer.mPeerFlags = mode; - peer.mLastSendTime = 0; - peer.mLastRecvTime = 0; - peer.mFoundTime = ts; - - if (mode & BITDHT_PEER_STATUS_RECV_NODES) - { - peer.mLastRecvTime = ts; - } - - mClosest.insert(std::pair(dist, peer)); - return 1; -} - - -/******************************************************************************************* - ********************************* Add Peer Interface ************************************* - *******************************************************************************************/ - -/**** These functions are called by bdNode to add peers to the query - * They add/update the three sets of lists. - * - * int bdQuery::addPeer(const bdId *id, uint32_t mode) - * Proper message from a peer. - * - * int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode) - * This returns 1 if worthy of pinging, 0 if to ignore. - */ - -#define PEER_MESSAGE 0 -#define FIND_NODE_RESPONSE 1 - -int bdQuery::addPeer(const bdId *id, uint32_t mode) -{ - addClosestPeer(id, mode); - updatePotentialPeer(id, mode, PEER_MESSAGE); - updateProxy(id, mode); - return 1; -} - -int bdQuery::addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode) -{ - // is it a Potential Proxy? Always Check This. - addProxy(id, src, srcmode); - - int worthy = worthyPotentialPeer(id); - int shouldPing = 0; - if (worthy) - { - shouldPing = updatePotentialPeer(id, 0, FIND_NODE_RESPONSE); - } - return shouldPing; -} - - -/******************************************************************************************* - ********************************* Closest Peer ******************************************** - *******************************************************************************************/ - - -/******************************************************************************************* - ******************************** Potential Peer ******************************************* - *******************************************************************************************/ - - - - -/******* - * Potential Peers are a list of the closest answers to our queries. - * Lots of these peers will not be reachable.... so will only exist in this list. - * They will also never have there PeerFlags set ;( - * - */ - - -/*** utility functions ***/ - -int bdQuery::worthyPotentialPeer(const bdId *id) -{ - bdMetric dist; - mFns->bdDistance(&mId, &(id->id), &dist); - -#ifdef DEBUG_QUERY - std::cerr << "bdQuery::worthyPotentialPeer("; - mFns->bdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - /* we check if this is a worthy potential peer.... - * if it is already in mClosest -> false. old peer. - * if it is > mClosest.rbegin() -> false. too far way. - */ - - std::multimap::iterator it, sit, eit; - sit = mClosest.lower_bound(dist); - eit = mClosest.upper_bound(dist); - - /* check if outside range, & bucket is full */ - if ((sit == mClosest.end()) && (mClosest.size() >= mFns->bdNumQueryNodes())) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Peer to far away for Potential\n"); -#endif - return 0; /* too far way */ - } - - - for(it = sit; it != eit; it++) - { - if (mFns->bdSimilarId(id, &(it->second.mPeerId))) - { - // Not updating Full Peer Id here... as inspection function. -#ifdef DEBUG_QUERY - fprintf(stderr, "Peer already in mClosest\n"); -#endif - return 0; - } - } - - return 1; /* either within mClosest Range (but not there!), or there aren't enough peers */ -} - - -/***** - * - * mLastSendTime ... is the last FIND_NODE_RESPONSE that we returned 1. (indicating to PING). - * mLastRecvTime ... is the last time we received an updatei about/from them - * - * The update is dependent on the flags passed in the function call. (saves duplicate code). - * - * - * XXX IMPORTANT TO DECIDE WHAT IS RETURNED HERE. - * original algorithm return 0 if exists in potential peers, 1 if unknown. - * This is used to limit the number of pings to non-responding potentials. - * - * MUST think about this. Need to install HISTORY tracking again. to look at the statistics. - * - * It is important that the potential Peers list extends all the way back to == mClosest().end(). - * Otherwise we end up with [TARGET] .... [ POTENTIAL ] ..... [ CLOSEST ] ...... - * and the gap between POT and CLOSEST will get hammered with pings. - * - */ - -#define MIN_PING_POTENTIAL_PERIOD 300 - -int bdQuery::updatePotentialPeer(const bdId *id, uint32_t mode, uint32_t addType) -{ - bdMetric dist; - time_t now = time(NULL); - - mFns->bdDistance(&mId, &(id->id), &dist); - - std::multimap::iterator it, sit, eit; - sit = mPotentialPeers.lower_bound(dist); - eit = mPotentialPeers.upper_bound(dist); - - for(it = sit; it != eit; it++) - { - if (mFns->bdSimilarId(id, &(it->second.mPeerId))) - { - - it->second.mPeerFlags |= mode; - it->second.mLastRecvTime = now; - if (addType == FIND_NODE_RESPONSE) - { - // We could lose peers here by not updating port... but should be okay. - if (now - it->second.mLastSendTime > MIN_PING_POTENTIAL_PERIOD) - { - it->second.mLastSendTime = now; - return 1; - } - } - else if (mode) - { - /* also update port from incoming id, as we have definitely recved from it */ - if (mFns->bdUpdateSimilarId(&(it->second.mPeerId), id)) - { - /* updated it... must be Unstable */ - it->second.mExtraFlags |= BITDHT_PEER_EXFLAG_UNSTABLE; - } - } - return 0; - } - } - -// Removing this check - so that we can have varying length PotentialPeers. -// Peer will always be added, then probably removed straight away. - -#if 0 - /* check if outside range, & bucket is full */ - if ((sit == mPotentialPeers.end()) && (mPotentialPeers.size() >= mFns->bdNumQueryNodes())) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Peer to far away for Potential\n"); -#endif - return 0; - } -#endif - - /* add it in */ - bdPeer peer; - peer.mPeerId = *id; - peer.mPeerFlags = mode; - peer.mFoundTime = now; - peer.mLastRecvTime = now; - peer.mLastSendTime = 0; - if (addType == FIND_NODE_RESPONSE) - { - peer.mLastSendTime = now; - } - - mPotentialPeers.insert(std::pair(dist, peer)); - -#ifdef DEBUG_QUERY - fprintf(stderr, "Flagging as Potential Peer!\n"); -#endif - - trimPotentialPeers_toClosest(); - - return 1; -} - - -int bdQuery::trimPotentialPeers_FixedLength() -{ - /* trim it back */ - while(mPotentialPeers.size() > (uint32_t) (mFns->bdNumQueryNodes())) - { - std::multimap::iterator it; - it = mPotentialPeers.end(); - it--; // must be more than 1 peer here? -#ifdef DEBUG_QUERY - fprintf(stderr, "Removing Furthest Peer: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, "\n"); -#endif - mPotentialPeers.erase(it); - } - return 1; -} - - -int bdQuery::trimPotentialPeers_toClosest() -{ - if (mPotentialPeers.size() <= (uint32_t) (mFns->bdNumQueryNodes())) - return 1; - - std::multimap::reverse_iterator it; - it = mClosest.rbegin(); - bdMetric lastClosest = it->first; - - /* trim it back */ - while(mPotentialPeers.size() > (uint32_t) (mFns->bdNumQueryNodes())) - { - std::multimap::iterator it; - it = mPotentialPeers.end(); - it--; // must be more than 1 peer here? - if (lastClosest < it->first) - { -#ifdef DEBUG_QUERY - fprintf(stderr, "Removing Furthest Peer: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, "\n"); -#endif - mPotentialPeers.erase(it); - } - else - { - return 1; - } - } - return 1; -} - - -/* as Potential Peeers are to determine if a peer is CLOSEST or UNREACHABLE - * we need to drop ones that we haven't heard about in ages. - * - * only do this in IDLE mode... - * The timeout period is dependent on our RetryPeriod. - */ - -#define POT_PEER_CLEAN_PERIOD 60 -#define POT_PEER_RECV_TIMEOUT_PERIOD (mQueryIdlePeerRetryPeriod + EXPECTED_REPLY) - -int bdQuery::removeOldPotentialPeers() -{ - if (!(mQueryFlags & BITDHT_QFLAGS_DO_IDLE)) - { - return 0; - } - - time_t now = time(NULL); - if (now - mPotPeerCleanTS < POT_PEER_CLEAN_PERIOD) - { - return 0; - } - - mPotPeerCleanTS = now; - - /* painful loop */ - std::multimap::iterator it; - for(it = mPotentialPeers.begin(); it != mPotentialPeers.end();) - { - /* which timestamp do we care about? */ - if (now - it->second.mLastRecvTime > POT_PEER_RECV_TIMEOUT_PERIOD) - { -#ifdef DEBUG_QUERY - std::cerr << "bdQuery::removeOldPotentialPeers() removing: "; - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, "\n"); -#endif - std::multimap::iterator it2 = it; - ++it2 ; - mPotentialPeers.erase(it); - it = it2 ; - - // Unfortunately have to start again... as pointers invalidated. - //it = mPotentialPeers.begin(); - } - else - { - ++it; - } - } - return 1 ; -} - - - -/******************************************************************************************* - ******************************** Potential Proxies **************************************** - *******************************************************************************************/ - -/******** - * Potential Proxies. a list of peers that have returned our target in response to a query. - * - * We are particularly interested in peers with specific flags... - * But all the peers have been pinged already by the time they reach this list. - * So there are two options: - * 1) Track everythings mode history - which is a waste of resources. - * 2) Store the list, and ping later. - * - * We will store these in two lists: Flags & Unknown. - * we keep the most recent of each, and move around as required. - * - * we could also check the Closest/PotentialPeer lists to grab the flags, - * for an unknown peer? - * - * All Functions manipulating PotentialProxies are here. - * We need several functions: - * - * For Extracting Proxies. -bool bdQuery::proxies(std::list &answer) -bool bdQuery::potentialProxies(std::list &answer) - * - * For Adding/Updating Proxies. -int bdQuery::addProxy(const bdId *id, const bdId *src, uint32_t srcmode) -int bdQuery::updateProxy(const bdId *id, uint32_t mode) - * - */ - -/*** Two Functions to extract Proxies... ***/ -bool bdQuery::proxies(std::list &answer) -{ - /* get all the matches to our query */ - std::list::iterator it; - int i = 0; - for(it = mProxiesFlagged.begin(); it != mProxiesFlagged.end(); it++, i++) - { - answer.push_back(it->mPeerId); - } - return (i > 0); -} - -bool bdQuery::potentialProxies(std::list &answer) -{ - /* get all the matches to our query */ - std::list::iterator it; - int i = 0; - for(it = mProxiesUnknown.begin(); it != mProxiesUnknown.end(); it++, i++) - { - answer.push_back(it->mPeerId); - } - return (i > 0); -} - - - -int bdQuery::addProxy(const bdId *id, const bdId *src, uint32_t srcmode) -{ - bdMetric dist; - time_t now = time(NULL); - - mFns->bdDistance(&mId, &(id->id), &dist); - - /* finally if it is an exact match, add as potential proxy */ - int bucket = mFns->bdBucketDistance(&dist); - if ((bucket != 0) || (src == NULL)) - { - /* not a potential proxy */ - return 0; - } - -#ifdef DEBUG_QUERY - fprintf(stderr, "Bucket = 0, Have Potential Proxy!\n"); -#endif - - bool found = false; - if (updateProxyList(src, srcmode, mProxiesUnknown)) - { - found = true; - } - - if (!found) - { - if (updateProxyList(src, srcmode, mProxiesFlagged)) - { - found = true; - } - } - - if (!found) - { - /* if we get here. its not in the list */ -#ifdef DEBUG_QUERY - fprintf(stderr, "Adding Source to Proxy List:\n"); -#endif - bdPeer peer; - peer.mPeerId = *src; - peer.mPeerFlags = srcmode; - peer.mLastSendTime = 0; - peer.mLastRecvTime = now; - peer.mFoundTime = now; - - /* add it in */ - if ((srcmode & mRequiredPeerFlags) == mRequiredPeerFlags) - { - mProxiesFlagged.push_front(peer); - } - else - { - mProxiesUnknown.push_front(peer); - } - } - - - trimProxies(); - - return 1; -} - - -int bdQuery::updateProxy(const bdId *id, uint32_t mode) -{ - if (!updateProxyList(id, mode, mProxiesUnknown)) - { - updateProxyList(id, mode, mProxiesFlagged); - } - - trimProxies(); - return 1; -} - - -/**** Utility functions that do all the work! ****/ - -int bdQuery::updateProxyList(const bdId *id, uint32_t mode, std::list &searchProxyList) -{ - std::list::iterator it; - for(it = searchProxyList.begin(); it != searchProxyList.end(); it++) - { - if (mFns->bdSimilarId(id, &(it->mPeerId))) - { - /* found it ;( */ -#ifdef DEBUG_QUERY - std::cerr << "bdQuery::updateProxyList() Found peer, updating"; - std::cerr << std::endl; -#endif - - time_t now = time(NULL); - if (mode) - { - /* also update port from incoming id, as we have definitely recved from it */ - if (mFns->bdUpdateSimilarId(&(it->mPeerId), id)) - { - /* updated it... must be Unstable */ - it->mExtraFlags |= BITDHT_PEER_EXFLAG_UNSTABLE; - } - } - it->mPeerFlags |= mode; - it->mLastRecvTime = now; - - /* now move it to the front of required list... - * note this could be exactly the same list as &searchProxyList, or a different one! - */ - - bdPeer peer = *it; - it = searchProxyList.erase(it); - - if ((peer.mPeerFlags & mRequiredPeerFlags) == mRequiredPeerFlags) - { - mProxiesFlagged.push_front(peer); - } - else - { - mProxiesUnknown.push_front(peer); - } - - return 1; - break; - } - } - - return 0; -} - -#define MAX_POTENTIAL_PROXIES 10 - -int bdQuery::trimProxies() -{ - - /* drop excess Potential Proxies */ - while(mProxiesUnknown.size() > MAX_POTENTIAL_PROXIES) - { - mProxiesUnknown.pop_back(); - } - - while(mProxiesFlagged.size() > MAX_POTENTIAL_PROXIES) - { - mProxiesFlagged.pop_back(); - } - return 1; -} - - -/******************************************************************************************* - ******************************** Potential Proxies **************************************** - *******************************************************************************************/ - - - -/* print query. - */ - -int bdQuery::printQuery() -{ -#ifdef DEBUG_QUERY - fprintf(stderr, "bdQuery::printQuery()\n"); -#endif - - time_t ts = time(NULL); - fprintf(stderr, "Query for: "); - mFns->bdPrintNodeId(std::cerr, &mId); - fprintf(stderr, " Query State: %d", mState); - fprintf(stderr, " Query Age %ld secs", ts-mQueryTS); - if (mState >= BITDHT_QUERY_FAILURE) - { - fprintf(stderr, " Search Time: %d secs", mSearchTime); - } - fprintf(stderr, "\n"); - -#ifdef DEBUG_QUERY - fprintf(stderr, "Closest Available Peers:\n"); - std::multimap::iterator it; - for(it = mClosest.begin(); it != mClosest.end(); it++) - { - fprintf(stderr, "Id: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first))); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime); - fprintf(stderr, "\n"); - } - - fprintf(stderr, "\nClosest Potential Peers:\n"); - for(it = mPotentialPeers.begin(); it != mPotentialPeers.end(); it++) - { - fprintf(stderr, "Id: "); - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first))); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime); - fprintf(stderr, "\n"); - } -#else - // shortened version. - fprintf(stderr, "Closest Available Peer: "); - std::multimap::iterator it = mClosest.begin(); - if (it != mClosest.end()) - { - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first))); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime); - } - fprintf(stderr, "\n"); - - fprintf(stderr, "Closest Potential Peer: "); - it = mPotentialPeers.begin(); - if (it != mPotentialPeers.end()) - { - mFns->bdPrintId(std::cerr, &(it->second.mPeerId)); - fprintf(stderr, " Bucket: %d ", mFns->bdBucketDistance(&(it->first))); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-it->second.mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-it->second.mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-it->second.mLastRecvTime); - } - fprintf(stderr, "\n"); - -#endif - std::list::iterator lit; - fprintf(stderr, "Flagged Proxies:\n"); - for(lit = mProxiesFlagged.begin(); lit != mProxiesFlagged.end(); lit++) - { - fprintf(stderr, "ProxyId: "); - mFns->bdPrintId(std::cerr, &(lit->mPeerId)); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-lit->mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-lit->mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-lit->mLastRecvTime); - fprintf(stderr, "\n"); - } - - fprintf(stderr, "Potential Proxies:\n"); - for(lit = mProxiesUnknown.begin(); lit != mProxiesUnknown.end(); lit++) - { - fprintf(stderr, "ProxyId: "); - mFns->bdPrintId(std::cerr, &(lit->mPeerId)); - fprintf(stderr," Flags: %x", it->second.mPeerFlags); - fprintf(stderr," Found: %ld ago", ts-lit->mFoundTime); - fprintf(stderr," LastSent: %ld ago", ts-lit->mLastSendTime); - fprintf(stderr," LastRecv: %ld ago", ts-lit->mLastRecvTime); - fprintf(stderr, "\n"); - } - - return 1; -} - - - - -/********************************* Remote Query **************************************/ - -#define QUERY_HISTORY_LIMIT 10 // Typically get max of 4-6 per 10minutes. -#define QUERY_HISTORY_PERIOD 600 - -bdRemoteQuery::bdRemoteQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type) - :mId(*id), mQuery(*query), mTransId(*transId), mQueryType(query_type) -{ - mQueryTS = time(NULL); -} - - - - -bdQueryHistoryList::bdQueryHistoryList() - :mBadPeer(false) -{ - -} - - -bool bdQueryHistoryList::addIncomingQuery(time_t recvd, const bdNodeId *aboutId) -{ - mList.insert(std::make_pair(recvd, *aboutId)); - mBadPeer = (mList.size() > QUERY_HISTORY_LIMIT); - return mBadPeer; -} - - -// returns true if empty. -bool bdQueryHistoryList::cleanupMsgs(time_t before) -{ - if (before == 0) - { - mList.clear(); - return true; - } - - // Delete the old stuff in the list. - while((mList.begin() != mList.end()) && (mList.begin()->first < before)) - { - mList.erase(mList.begin()); - } - - // return true if empty. - if (mList.begin() == mList.end()) - { - return true; - } - return false; -} - -bdQueryHistory::bdQueryHistory() - :mStorePeriod(QUERY_HISTORY_PERIOD) -{ - return; -} - -bool bdQueryHistory::addIncomingQuery(time_t recvd, const bdId *id, const bdNodeId *aboutId) -{ - std::map::iterator it; - - it = mHistory.find(*id); - if (it == mHistory.end()) - { - mHistory[*id] = bdQueryHistoryList(); - it = mHistory.find(*id); - } - - return (it->second).addIncomingQuery(recvd, aboutId); -} - -bool bdQueryHistory::isBadPeer(const bdId *id) -{ - std::map::iterator it; - - it = mHistory.find(*id); - if (it == mHistory.end()) - { - return false; - } - - return it->second.mBadPeer; -} - - -void bdQueryHistory::cleanupOldMsgs() -{ - if (mStorePeriod == 0) - { - return; // no cleanup. - } - - time_t before = time(NULL) - mStorePeriod; - std::map::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); ) - { - if (it->second.cleanupMsgs(before)) - { - std::map::iterator tit(it); - ++tit; - mHistory.erase(it); - it = tit; - } - else - { - ++it; - } - } -} - - -void bdQueryHistory::printMsgs() -{ - std::ostream &out = std::cerr; - - out << "bdQueryHistory::printMsgs() IncomingQueries in last " << mStorePeriod; - out << " secs" << std::endl; - - std::map::iterator it; - for(it = mHistory.begin(); it != mHistory.end(); it++) - { - out << "\t"; - bdStdPrintId(out, &(it->first)); - out << " " << it->second.mList.size(); - if (it->second.mBadPeer) - { - out << " BadPeer"; - } - out << std::endl; - } -} - - - - - - - - - diff --git a/libbitdht/src/bitdht/bdquery.h b/libbitdht/src/bitdht/bdquery.h deleted file mode 100644 index 4cb08f165..000000000 --- a/libbitdht/src/bitdht/bdquery.h +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * bitdht/bdquery.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_QUERY_H -#define BITDHT_QUERY_H - -#include "bitdht/bdiface.h" -#include "bitdht/bdpeer.h" -#include "bitdht/bdobj.h" - -/* Query result flags are in bdiface.h */ - -#define BITDHT_MIN_QUERY_AGE 10 -#define BITDHT_MAX_QUERY_AGE 300 /* Query Should take <1 minute, so 5 minutes sounds reasonable */ - -class bdQuery -{ - public: - bdQuery(const bdNodeId *id, std::list &startList, uint32_t queryFlags, - bdDhtFunctions *fns); - - // get the answer. -bool result(std::list &answer); -bool proxies(std::list &answer); -bool potentialProxies(std::list &answer); - - // returning results get passed to all queries. -//void addNode(const bdId *id, int mode); -int nextQuery(bdId &id, bdNodeId &targetId); -int addPeer(const bdId *id, uint32_t mode); -int addPotentialPeer(const bdId *id, const bdId *src, uint32_t srcmode); -int printQuery(); - - // searching for - bdNodeId mId; - bdMetric mLimit; - uint32_t mState; - time_t mQueryTS; - uint32_t mQueryFlags; - int32_t mSearchTime; - - int32_t mQueryIdlePeerRetryPeriod; // seconds between retries. - - //private: - - // Closest Handling Fns. -int addClosestPeer(const bdId *id, uint32_t mode); - - // Potential Handling Fns. -int worthyPotentialPeer(const bdId *id); -int updatePotentialPeer(const bdId *id, uint32_t mode, uint32_t addType); -int trimPotentialPeers_FixedLength(); -int trimPotentialPeers_toClosest(); -int removeOldPotentialPeers(); - - // Proxy Handling Fns. -int addProxy(const bdId *id, const bdId *src, uint32_t srcmode); -int updateProxy(const bdId *id, uint32_t mode); -int updateProxyList(const bdId *id, uint32_t mode, std::list &searchProxyList); -int trimProxies(); - - - // closest peers. - std::multimap mClosest; - std::multimap mPotentialPeers; - time_t mPotPeerCleanTS; // periodic cleanup of PotentialPeers. - - uint32_t mRequiredPeerFlags; - std::list mProxiesUnknown; - std::list mProxiesFlagged; - - int mClosestListSize; - bdDhtFunctions *mFns; - -}; - -#if 0 - -class bdQueryStatus -{ - public: - uint32_t mStatus; - uint32_t mQFlags; - std::list mResults; -}; - -#endif - - - -/* this is just a container class. - * we locally seach for this, once then discard. - */ -class bdRemoteQuery -{ - public: - bdRemoteQuery(bdId *id, bdNodeId *query, bdToken *transId, uint32_t query_type); - - bdId mId; - bdNodeId mQuery; - bdToken mTransId; - uint32_t mQueryType; - - time_t mQueryTS; -}; - - - -class bdQueryHistoryList -{ - public: - bdQueryHistoryList(); - -bool addIncomingQuery(time_t recvd, const bdNodeId *aboutId); // calcs and returns mBadPeer -bool cleanupMsgs(time_t before); // returns true if empty. - - bool mBadPeer; - std::multimap mList; -}; - -class bdQueryHistory -{ - public: - bdQueryHistory(); - -bool addIncomingQuery(time_t recvd, const bdId *id, const bdNodeId *aboutId); -void printMsgs(); - -void cleanupOldMsgs(); - -bool isBadPeer(const bdId *id); - - int mStorePeriod; - std::map mHistory; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdquerymgr.cc b/libbitdht/src/bitdht/bdquerymgr.cc deleted file mode 100644 index 70f58ce90..000000000 --- a/libbitdht/src/bitdht/bdquerymgr.cc +++ /dev/null @@ -1,379 +0,0 @@ -/******************************************************************************* - * bitdht/bdquerymgr.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdquerymgr.h" -#include "bitdht/bdnode.h" - -#include -#include -#include -#include - -#include -#include - - -#define BITDHT_QUERY_START_PEERS 10 -#define BITDHT_QUERY_NEIGHBOUR_PEERS 8 -#define BITDHT_MAX_REMOTE_QUERY_AGE 10 - -/**** - * #define DEBUG_NODE_MULTIPEER 1 - * #define DEBUG_NODE_MSGS 1 - * #define DEBUG_NODE_ACTIONS 1 - - * #define DEBUG_NODE_MSGIN 1 - * #define DEBUG_NODE_MSGOUT 1 - ***/ - -//#define DEBUG_NODE_MSGS 1 - - -bdQueryManager::bdQueryManager(bdSpace *space, bdDhtFunctions *fns, bdNodePublisher *pub) - :mNodeSpace(space), mFns(fns), mPub(pub) -{ -} - -/***** Startup / Shutdown ******/ -void bdQueryManager::shutdownQueries() -{ - /* clear the queries */ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end();it++) - { - delete (*it); - } - - mLocalQueries.clear(); -} - - -void bdQueryManager::printQueries() -{ - std::cerr << "bdQueryManager::printQueries()"; - std::cerr << std::endl; - - int i = 0; - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++, i++) - { - fprintf(stderr, "Query #%d:\n", i); - (*it)->printQuery(); - fprintf(stderr, "\n"); - } -} - - -int bdQueryManager::iterateQueries(int maxQueries) -{ -#ifdef DEBUG_NODE_MULTIPEER - std::cerr << "bdQueryManager::iterateQueries() of Peer: "; - mFns->bdPrintNodeId(std::cerr, &mOwnId); - std::cerr << std::endl; -#endif - - /* allow each query to send up to one query... until maxMsgs has been reached */ - int numQueries = mLocalQueries.size(); - int sentQueries = 0; - int i = 0; - - bdId id; - bdNodeId targetNodeId; - - while((i < numQueries) && (sentQueries < maxQueries)) - { - bdQuery *query = mLocalQueries.front(); - mLocalQueries.pop_front(); - mLocalQueries.push_back(query); - - /* go through the possible queries */ - if (query->nextQuery(id, targetNodeId)) - { -#ifdef DEBUG_NODE_MSGS - std::cerr << "bdQueryManager::iteration() send_query("; - mFns->bdPrintId(std::cerr, &id); - std::cerr << ","; - mFns->bdPrintNodeId(std::cerr, &targetNodeId); - std::cerr << ")"; - std::cerr << std::endl; -#endif - mPub->send_query(&id, &targetNodeId, false); - sentQueries++; - } - i++; - } - -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdQueryManager::iteration() maxMsgs: " << maxMsgs << " sentPings: " << sentPings; - std::cerr << " / " << allowedPings; - std::cerr << " sentQueries: " << sentQueries; - std::cerr << " / " << numQueries; - std::cerr << std::endl; -#endif - - //printQueries(); - - return sentQueries; -} - - -bool bdQueryManager::checkPotentialPeer(bdId *id, bdId *src) -{ - bool isWorthyPeer = false; - /* also push to queries */ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++) - { - if ((*it)->addPotentialPeer(id, src, 0)) - { - isWorthyPeer = true; - } - } - - if (!isWorthyPeer) - { - isWorthyPeer = checkWorthyPeerSources(src); - } - - return isWorthyPeer; -} - - -void bdQueryManager::addPeer(const bdId *id, uint32_t peerflags) -{ - -#ifdef DEBUG_NODE_ACTIONS - fprintf(stderr, "bdQueryManager::addPeer("); - mFns->bdPrintId(std::cerr, id); - fprintf(stderr, ")\n"); -#endif - - /* iterate through queries */ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++) - { - (*it)->addPeer(id, peerflags); - } -} - - -/************************************ Query Details *************************/ -void bdQueryManager::addQuery(const bdNodeId *id, uint32_t qflags) -{ - - std::list startList; - std::multimap nearest; - std::multimap::iterator it; - - mNodeSpace->find_nearest_nodes(id, BITDHT_QUERY_START_PEERS, nearest); - -#ifdef DEBUG_NODE_ACTIONS - fprintf(stderr, "bdQueryManager::addQuery("); - mFns->bdPrintNodeId(std::cerr, id); - fprintf(stderr, ")\n"); -#endif - - for(it = nearest.begin(); it != nearest.end(); it++) - { - startList.push_back(it->second); - } - - bdQuery *query = new bdQuery(id, startList, qflags, mFns); - mLocalQueries.push_back(query); -} - - -void bdQueryManager::clearQuery(const bdNodeId *rmId) -{ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end();) - { - if ((*it)->mId == *rmId) - { - bdQuery *query = (*it); - it = mLocalQueries.erase(it); - delete query; - } - else - { - it++; - } - } -} - -void bdQueryManager::QueryStatus(std::map &statusMap) -{ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++) - { - bdQueryStatus status; - status.mStatus = (*it)->mState; - status.mQFlags = (*it)->mQueryFlags; - (*it)->result(status.mResults); - statusMap[(*it)->mId] = status; - } -} - -int bdQueryManager::QuerySummary(const bdNodeId *id, bdQuerySummary &query) -{ - std::list::iterator it; - for(it = mLocalQueries.begin(); it != mLocalQueries.end(); it++) - { - if ((*it)->mId == *id) - { - query.mId = (*it)->mId; - query.mLimit = (*it)->mLimit; - query.mState = (*it)->mState; - query.mQueryTS = (*it)->mQueryTS; - query.mQueryFlags = (*it)->mQueryFlags; - query.mSearchTime = (*it)->mSearchTime; - query.mClosest = (*it)->mClosest; - query.mPotentialPeers = (*it)->mPotentialPeers; - query.mProxiesUnknown = (*it)->mProxiesUnknown; - query.mProxiesFlagged = (*it)->mProxiesFlagged; - query.mQueryIdlePeerRetryPeriod = (*it)->mQueryIdlePeerRetryPeriod; - - return 1; - } - } - return 0; -} - -/* Extract Results from Peer Queries */ - -#define BDQRYMGR_RESULTS 1 -#define BDQRYMGR_PROXIES 2 -#define BDQRYMGR_POTPROXIES 3 - -int bdQueryManager::getResults(bdNodeId *target, std::list &answer, int querytype) -{ - - /* grab any peers from any existing query */ - int results = 0; - std::list::iterator qit; - for(qit = mLocalQueries.begin(); qit != mLocalQueries.end(); qit++) - { - if (!((*qit)->mId == (*target))) - { - continue; - } - -#ifdef DEBUG_NODE_CONNECTION - std::cerr << "bdQueryManager::getResults() Found Matching Query"; - std::cerr << std::endl; -#endif - switch(querytype) - { - default: - case BDQRYMGR_RESULTS: - results = (*qit)->result(answer); - break; - case BDQRYMGR_PROXIES: - results = (*qit)->proxies(answer); - break; - case BDQRYMGR_POTPROXIES: - results = (*qit)->potentialProxies(answer); - break; - } - /* will only be one matching query.. so end loop */ - return results; - } - return 0; -} - - -int bdQueryManager::result(bdNodeId *target, std::list &answer) -{ - return getResults(target, answer, BDQRYMGR_RESULTS); -} - -int bdQueryManager::proxies(bdNodeId *target, std::list &answer) -{ - return getResults(target, answer, BDQRYMGR_PROXIES); -} - -int bdQueryManager::potentialProxies(bdNodeId *target, std::list &answer) -{ - return getResults(target, answer, BDQRYMGR_POTPROXIES); -} - - -/************ WORTHY PEERS **********/ - -#define MAX_WORTHY_PEER_AGE 15 - -void bdQueryManager::addWorthyPeerSource(bdId *src) -{ - time_t now = time(NULL); - - bdPeer peer; - peer.mPeerId = *src; - peer.mFoundTime = now; - -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdQueryManager::addWorthyPeerSource("; - mFns->bdPrintId(std::cerr, src); - std::cerr << ")" << std::endl; -#endif - - mWorthyPeerSources.push_back(peer); -} - -bool bdQueryManager::checkWorthyPeerSources(bdId *src) -{ - if (!src) - return false; - - time_t now = time(NULL); - std::list::iterator it; - for(it = mWorthyPeerSources.begin(); it != mWorthyPeerSources.end(); ) - { - if (now - it->mFoundTime > MAX_WORTHY_PEER_AGE) - { -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdQueryManager::checkWorthyPeerSource() Discard old Source: "; - mFns->bdPrintId(std::cerr, &(it->mPeerId)); - std::cerr << std::endl; -#endif - - it = mWorthyPeerSources.erase(it); - } - else - { - if (it->mPeerId == *src) - { -#ifdef DEBUG_NODE_ACTIONS - std::cerr << "bdQueryManager::checkWorthyPeerSource("; - mFns->bdPrintId(std::cerr, src); - std::cerr << ") = true" << std::endl; -#endif - - return true; - } - it++; - } - } - return false; -} - - - diff --git a/libbitdht/src/bitdht/bdquerymgr.h b/libbitdht/src/bitdht/bdquerymgr.h deleted file mode 100644 index 355781244..000000000 --- a/libbitdht/src/bitdht/bdquerymgr.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * bitdht/bdquerymgr.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_QUERY_MANAGER_H -#define BITDHT_QUERY_MANAGER_H - -#include "bitdht/bdquery.h" -class bdNodePublisher; - - -class bdQueryManager -{ - public: - - bdQueryManager(bdSpace *space, bdDhtFunctions *fns, bdNodePublisher *pub); - - void shutdownQueries(); - void printQueries(); - - int iterateQueries(int maxqueries); - - bool checkPotentialPeer(bdId *id, bdId *src); - void addPeer(const bdId *id, uint32_t peerflags); - - void addQuery(const bdNodeId *id, uint32_t qflags); - void clearQuery(const bdNodeId *id); - void QueryStatus(std::map &statusMap); - int QuerySummary(const bdNodeId *id, bdQuerySummary &query); - - int result(bdNodeId *target, std::list &answer); - int proxies(bdNodeId *target, std::list &answer); - int potentialProxies(bdNodeId *target, std::list &answer); - - // extra "Worthy Peers" we will want to ping. - void addWorthyPeerSource(bdId *src); - bool checkWorthyPeerSources(bdId *src); - - private: - - int getResults(bdNodeId *target, std::list &answer, int querytype); - - /* NB: No Mutex Protection... Single threaded, Mutex at higher level! - */ - - bdSpace *mNodeSpace; - bdDhtFunctions *mFns; - bdNodePublisher *mPub; - - std::list mLocalQueries; - std::list mWorthyPeerSources; -}; - - - -#endif // BITDHT_QUERY_MANAGER_H diff --git a/libbitdht/src/bitdht/bdstddht.cc b/libbitdht/src/bitdht/bdstddht.cc deleted file mode 100644 index eac5c148e..000000000 --- a/libbitdht/src/bitdht/bdstddht.cc +++ /dev/null @@ -1,347 +0,0 @@ -/******************************************************************************* - * bitdht/bdstddht.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdstddht.h" -#include "bitdht/bdpeer.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" - -#include -#include -#include -#include - -#include -#include - -/** - * #define BITDHT_DEBUG 1 -**/ - -void bdStdRandomId(bdId *id) -{ - bdStdRandomNodeId(&(id->id)); - id->addr.sin_addr.s_addr = bdRandom::random_u32(); - id->addr.sin_port = (bdRandom::random_u32() % USHRT_MAX); - - return; -} - -void bdStdRandomNodeId(bdNodeId *id) -{ - uint32_t *a_data = (uint32_t *) id->data; - for(int i = 0; i < BITDHT_KEY_INTLEN; i++) - { - a_data[i] = bdRandom::random_u32(); - } - return; -} - -void bdStdZeroNodeId(bdNodeId *id) -{ - uint32_t *a_data = (uint32_t *) id->data; - for(int i = 0; i < BITDHT_KEY_INTLEN; i++) - { - a_data[i] = 0; - } - return; -} - -// Ignore differences in port.... -// must be careful which one we accept after this. -// can could end-up with the wrong port. -// However this only matters with firewalled peers anyway. -// So not too serious. -bool bdStdSimilarId(const bdId *n1, const bdId *n2) -{ - if (n1->id == n2->id) - { - if (n1->addr.sin_addr.s_addr == n2->addr.sin_addr.s_addr) - { - return true; - } - } - return false; -} - -bool bdStdUpdateSimilarId(bdId *dest, const bdId *src) -{ - /* only difference that's currently allowed */ - if (dest->addr.sin_port == src->addr.sin_port) - { - /* no update required */ - return false; - } - - dest->addr.sin_port = src->addr.sin_port; - return true; -} - - -/* fills in bdNodeId r, with XOR of a and b */ -int bdStdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r) -{ - uint8_t *a_data = (uint8_t *) a->data; - uint8_t *b_data = (uint8_t *) b->data; - uint8_t *ans = (uint8_t *) r->data; - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - *(ans++) = *(a_data++) ^ *(b_data++); - } - return 1; -} - -void bdStdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *midId) -{ - bdMetric dist; - - /* get distance between a & c */ - bdStdDistance(target, other, &dist); - - /* generate Random Id */ - bdStdRandomNodeId(midId); - - /* zero bits of Random Id until under 1/2 of distance - * done in bytes for ease... matches one extra byte than distance = 0 - * -> hence wierd order of operations - */ - //bool done = false; - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - midId->data[i] = target->data[i]; - - if (dist.data[i] != 0) - break; - } -} - -int bdStdLoadNodeId(bdNodeId *id, std::string input) -{ - uint8_t *a_data = (uint8_t *) id->data; - uint32_t reqlen = BITDHT_KEY_LEN * 2; - if (input.size() < reqlen) - { - return 0; - } - - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - char ch1 = input[2 * i]; - char ch2 = input[2 * i + 1]; - uint8_t value1 = 0; - uint8_t value2 = 0; - - /* do char1 */ - if (ch1 >= '0' && ch1 <= '9') - value1 = (ch1 - '0'); - else if (ch1 >= 'A' && ch1 <= 'F') - value1 = (ch1 - 'A' + 10); - else if (ch1 >= 'a' && ch1 <= 'f') - value1 = (ch1 - 'a' + 10); - - /* do char2 */ - if (ch2 >= '0' && ch2 <= '9') - value2 = (ch2 - '0'); - else if (ch2 >= 'A' && ch2 <= 'F') - value2 = (ch2 - 'A' + 10); - else if (ch2 >= 'a' && ch2 <= 'f') - value2 = (ch2 - 'a' + 10); - - a_data[i] = (value1 << 4) + value2; - } - return 1; -} - -std::string bdStdConvertToPrintable(std::string input) -{ - std::string out; - for(uint32_t i = 0; i < input.length(); i++) - { - /* sensible chars */ - if ((input[i] > 31) && (input[i] < 127)) - { - out += input[i]; - } - else - { - bd_sprintf_append(out, "[0x%x]", (uint32_t) input[i]); - } - } - return out; -} - -void bdStdPrintNodeId(std::ostream &out, const bdNodeId *a) -{ - std::string s; - bdStdPrintNodeId(s, a, true); - out << s; -} - -void bdStdPrintNodeId(std::string &out, const bdNodeId *a, bool append) -{ - if (!append) - { - out.clear(); - } - - for(int i = 0; i < BITDHT_KEY_LEN; i++) - { - bd_sprintf_append(out, "%02x", (uint32_t) (a->data)[i]); - } -} - -void bdStdPrintId(std::ostream &out, const bdId *a) -{ - std::string s; - bdStdPrintId(s, a, false); - out << s; -} - -void bdStdPrintId(std::string &out, const bdId *a, bool append) -{ - bdStdPrintNodeId(out, &(a->id), append); - bd_sprintf_append(out, " ip:%s:%u", bdnet_inet_ntoa(a->addr.sin_addr).c_str(), ntohs(a->addr.sin_port)); -} - -/* returns 0-160 depending on bucket */ -int bdStdBucketDistance(const bdNodeId *a, const bdNodeId *b) -{ - bdMetric m; - bdStdDistance(a, b, &m); - return bdStdBucketDistance(&m); -} - -/* returns 0-160 depending on bucket */ -int bdStdBucketDistance(const bdMetric *m) -{ - for(int i = 0; i < BITDHT_KEY_BITLEN; i++) - { - int bit = BITDHT_KEY_BITLEN - i - 1; - int byte = i / 8; - int bbit = 7 - (i % 8); - unsigned char comp = (1 << bbit); - -#ifdef BITDHT_DEBUG - fprintf(stderr, "bdStdBucketDistance: bit:%d byte:%d bbit:%d comp:%x, data:%x\n", bit, byte, bbit, comp, m->data[byte]); -#endif - - if (comp & m->data[byte]) - { - return bit; - } - } - return 0; -} - - -bdStdDht::bdStdDht() -{ - return; -} - /* setup variables */ -uint16_t bdStdDht::bdNumBuckets() -{ - - return BITDHT_STANDARD_N_BUCKETS; -} - -uint16_t bdStdDht::bdNodesPerBucket() /* used for bdspace */ -{ - return BITDHT_STANDARD_BUCKET_SIZE; -} - -uint16_t bdStdDht::bdNumQueryNodes() /* used for queries */ -{ - return BITDHT_STANDARD_BUCKET_SIZE; -} - -uint16_t bdStdDht::bdBucketBitSize() -{ - return BITDHT_STANDARD_BUCKET_SIZE_BITS; -} - -int bdStdDht::bdDistance(const bdNodeId *n1, const bdNodeId *n2, class bdMetric *metric) -{ - return bdStdDistance(n1, n2, metric); -} - -int bdStdDht::bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2) -{ - return bdStdBucketDistance(n1, n2); -} - -int bdStdDht::bdBucketDistance(const bdMetric *metric) -{ - return bdStdBucketDistance(metric); -} - - -bool bdStdDht::bdSimilarId(const bdId *id1, const bdId *id2) -{ - return bdStdSimilarId(id1, id2); -} - - -bool bdStdDht::bdUpdateSimilarId(bdId *dest, const bdId *src) -{ - return bdStdUpdateSimilarId(dest, src); -} - - -void bdStdDht::bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid) -{ - return bdStdRandomMidId(target, other, mid); -} - - -void bdStdDht::bdPrintId(std::ostream &out, const bdId *a) -{ - return bdStdPrintId(out, a); -} - -void bdStdDht::bdPrintNodeId(std::ostream &out, const bdNodeId *a) -{ - return bdStdPrintNodeId(out, a); -} - - -/**************************/ - -bdModDht::bdModDht() - :mNodesPerBucket(BITDHT_STANDARD_BUCKET_SIZE) -{ - return; -} - -void bdModDht::setNodesPerBucket(uint16_t nodesPerBucket) -{ - mNodesPerBucket = nodesPerBucket; - return; -} - - -uint16_t bdModDht::bdNodesPerBucket() /* used for bdspace */ -{ - return mNodesPerBucket; -} - - diff --git a/libbitdht/src/bitdht/bdstddht.h b/libbitdht/src/bitdht/bdstddht.h deleted file mode 100644 index d38c19724..000000000 --- a/libbitdht/src/bitdht/bdstddht.h +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * bitdht/bdstddht.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_STANDARD_DHT_H -#define BITDHT_STANDARD_DHT_H - -#include "bitdht/bdiface.h" - -#define BITDHT_STANDARD_BUCKET_SIZE 10 // 20 too many per query? -#define BITDHT_STANDARD_BUCKET_SIZE_BITS 5 - -#define BITDHT_STANDARD_N_BUCKETS BITDHT_KEY_BITLEN - -#include -#include -#include -#include - - - - -void bdStdRandomNodeId(bdNodeId *id); -void bdStdZeroNodeId(bdNodeId *id); - -void bdStdRandomId(bdId *id); -int bdStdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r); -int bdStdBucketDistance(const bdMetric *m); -int bdStdBucketDistance(const bdNodeId *a, const bdNodeId *b); - -void bdStdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid); - -int bdStdLoadNodeId(bdNodeId *id, std::string input); - -void bdStdPrintId(std::ostream &out, const bdId *a); -void bdStdPrintId(std::string &out, const bdId *a, bool append); -void bdStdPrintNodeId(std::ostream &out, const bdNodeId *a); -void bdStdPrintNodeId(std::string &out, const bdNodeId *a, bool append); - -std::string bdStdConvertToPrintable(std::string input); - -//uint32_t bdStdSimilarNode(const bdId*, const bdId*); - - -class bdStdDht: public bdDhtFunctions -{ - public: - - bdStdDht(); - /* setup variables */ -virtual uint16_t bdNumBuckets(); -virtual uint16_t bdNodesPerBucket(); /* used for bdspace */ -virtual uint16_t bdNumQueryNodes(); /* used for queries */ -virtual uint16_t bdBucketBitSize(); - -virtual int bdDistance(const bdNodeId *n1, const bdNodeId *n2, bdMetric *metric); -virtual int bdBucketDistance(const bdNodeId *n1, const bdNodeId *n2); -virtual int bdBucketDistance(const bdMetric *metric); - -virtual bool bdSimilarId(const bdId *id1, const bdId *id2); -virtual bool bdUpdateSimilarId(bdId *dest, const bdId *src); /* returns true if update was necessary */ - -virtual void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *mid); - -virtual void bdPrintId(std::ostream &out, const bdId *a); -virtual void bdPrintNodeId(std::ostream &out, const bdNodeId *a); - -}; - -class bdModDht: public bdStdDht -{ - public: - bdModDht(); -virtual void setNodesPerBucket(uint16_t nodesPerBucket); -virtual uint16_t bdNodesPerBucket(); /* used for bdspace */ - - private: - uint16_t mNodesPerBucket; -}; - - -#endif - diff --git a/libbitdht/src/bitdht/bdstore.cc b/libbitdht/src/bitdht/bdstore.cc deleted file mode 100644 index 2cce6840c..000000000 --- a/libbitdht/src/bitdht/bdstore.cc +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * bitdht/bdstore.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bitdht/bdstore.h" -#include "util/bdnet.h" -#include "util/bdfile.h" - -#include -#include - -//#define DEBUG_STORE 1 - -bdStore::bdStore(std::string file, std::string backupfile, bdDhtFunctions *fns) - :mFns(fns) -{ -#ifdef DEBUG_STORE - std::cerr << "bdStore::bdStore(" << file << ")"; - std::cerr << std::endl; -#endif - - /* read data from file */ - mStoreFile = file; - mStoreFileBak = backupfile; - - reloadFromStore(); -} - -int bdStore::clear() -{ - mIndex = 0; - store.clear(); - return 1; -} - -int bdStore::reloadFromStore() -{ - int result = reloadFromStore(mStoreFile); - if( result != 0 && store.size() > 0){ - return result; - } else if(mStoreFileBak != "") { //Nothing loaded, try the backup file - return reloadFromStore(mStoreFileBak); - } else { - return 0; - } -} - -int bdStore::reloadFromStore(std::string file) -{ - clear(); - - FILE *fd = fopen(file.c_str(), "r"); - if (!fd) - { - fprintf(stderr, "Failed to Open File: %s ... No Peers\n", file.c_str()); - return 0; - } - - - char line[10240]; - char addr_str[10240]; - struct sockaddr_in addr; - addr.sin_family = PF_INET; - unsigned short port; - - while(line == fgets(line, 10240, fd)) - { - if (2 == sscanf(line, "%s %hd", addr_str, &port)) - { - if (bdnet_inet_aton(addr_str, &(addr.sin_addr))) - { - addr.sin_port = htons(port); - bdPeer peer; - bdZeroNodeId(&(peer.mPeerId.id)); - peer.mPeerId.addr = addr; - peer.mLastSendTime = 0; - peer.mLastRecvTime = 0; - store.push_back(peer); -#ifdef DEBUG_STORE - fprintf(stderr, "Read: %s %d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); -#endif - } - } - } - - fclose(fd); - -#ifdef DEBUG_STORE - fprintf(stderr, "Read %ld Peers\n", (long) store.size()); -#endif - - return 1; - -} - -// This is a very ugly function! -int bdStore::getPeer(bdPeer *peer) -{ -#ifdef DEBUG_STORE - fprintf(stderr, "bdStore::getPeer() %ld Peers left\n", (long) store.size()); -#endif - - std::list::iterator it; - int i = 0; - for(it = store.begin(); (it != store.end()) && (i < mIndex); it++, i++) ; /* empty loop */ - if (it != store.end()) - { - *peer = *it; - mIndex++; - return 1; - } - return 0; -} - -int bdStore::filterIpList(const std::list &filteredIPs) -{ - // Nasty O(n^2) iteration over 500 entries!!!. - // hope its not used to often. - - std::list::const_iterator it; - for(it = filteredIPs.begin(); it != filteredIPs.end(); it++) - { - std::list::iterator sit; - for(sit = store.begin(); sit != store.end();) - { - if (it->sin_addr.s_addr == sit->mPeerId.addr.sin_addr.s_addr) - { - std::cerr << "bdStore::filterIpList() Found Bad entry in Store. Erasing!"; - std::cerr << std::endl; - - sit = store.erase(sit); - } - else - { - sit++; - } - } - } - return 1; -} - - - -#define MAX_ENTRIES 500 - - /* maintain a sorted list */ -void bdStore::addStore(bdPeer *peer) -{ -#ifdef DEBUG_STORE - std::cerr << "bdStore::addStore() "; - mFns->bdPrintId(std::cerr, &(peer->mPeerId)); - std::cerr << std::endl; -#endif - - /* remove old entry */ - - std::list::iterator it; - for(it = store.begin(); it != store.end(); ) - { - if ((it->mPeerId.addr.sin_addr.s_addr == peer->mPeerId.addr.sin_addr.s_addr) && - (it->mPeerId.addr.sin_port == peer->mPeerId.addr.sin_port)) - { -#ifdef DEBUG_STORE - std::cerr << "bdStore::addStore() Removed Existing Entry: "; - mFns->bdPrintId(std::cerr, &(it->mPeerId)); - std::cerr << std::endl; -#endif - it = store.erase(it); - } - else - { - it++; - } - } - -#ifdef DEBUG_STORE - std::cerr << "bdStore::addStore() Push_back"; - std::cerr << std::endl; -#endif - store.push_back(*peer); - - while(store.size() > MAX_ENTRIES) - { -#ifdef DEBUG_STORE - std::cerr << "bdStore::addStore() pop_front()"; - std::cerr << std::endl; -#endif - store.pop_front(); - } -} - -void bdStore::writeStore(std::string file) -{ - /* write out store */ -#ifdef DEBUG_STORE - fprintf(stderr, "bdStore::writeStore(%s) = %d entries\n", file.c_str(), store.size()); -#endif - - if (store.size() < 0.9 * MAX_ENTRIES) - { - /* don't save yet! */ -#ifdef DEBUG_STORE - fprintf(stderr, "bdStore::writeStore() Delaying until more entries\n"); -#endif - return; - } - - std::string filetmp = file + ".tmp" ; - - FILE *fd = fopen(filetmp.c_str(), "w"); - - if (!fd) - { -#ifdef DEBUG_STORE -#endif - fprintf(stderr, "bdStore::writeStore() FAILED to Open File\n"); - return; - } - - std::list::iterator it; - for(it = store.begin(); it != store.end(); it++) - { - fprintf(fd, "%s %d\n", bdnet_inet_ntoa(it->mPeerId.addr.sin_addr).c_str(), ntohs(it->mPeerId.addr.sin_port)); -#ifdef DEBUG_STORE - fprintf(stderr, "Storing Peer Address: %s %d\n", inet_ntoa(it->mPeerId.addr.sin_addr), ntohs(it->mPeerId.addr.sin_port)); -#endif - - } - fclose(fd); - - if(!bdFile::renameFile(filetmp,file)) - std::cerr << "Could not rename file !!" << std::endl; -#ifdef DEBUG_STORE - else - std::cerr << "Successfully renamed file " << filetmp << " to " << file << std::endl; -#endif -} - -void bdStore::writeStore() -{ -#if 0 - if (mStoreFile == "") - { - return; - } -#endif - return writeStore(mStoreFile); -} - - - diff --git a/libbitdht/src/bitdht/bdstore.h b/libbitdht/src/bitdht/bdstore.h deleted file mode 100644 index 2202f0553..000000000 --- a/libbitdht/src/bitdht/bdstore.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * bitdht/bdstore.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_STORE_H -#define BITDHT_STORE_H - -#include -#include "bitdht/bdiface.h" -#include "bitdht/bdpeer.h" - -class bdStore -{ -public: - - bdStore(std::string file, std::string backupfile, bdDhtFunctions *fns); - - int reloadFromStore(); /* for restarts */ - int reloadFromStore(std::string file); - int filterIpList(const std::list &filteredIPs); - int clear(); - - int getPeer(bdPeer *peer); - void addStore(bdPeer *peer); - void writeStore(std::string file); - void writeStore(); - -protected: - std::string mStoreFile; - std::string mStoreFileBak; - std::list store; - int mIndex; - bdDhtFunctions *mFns; -}; - - -#endif diff --git a/libbitdht/src/bitdht/bencode.c b/libbitdht/src/bitdht/bencode.c deleted file mode 100644 index a496f5bc3..000000000 --- a/libbitdht/src/bitdht/bencode.c +++ /dev/null @@ -1,649 +0,0 @@ -/******************************************************************************* - * bitdht/bdencode.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * by Mike Frysinger * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* - * This implementation isn't optimized at all as I wrote it to support - * a bogus system. I have no real interest in this format. Feel free - * to send me patches (so long as you don't copyright them and you release - * your changes into the public domain as well). - */ - -#include -#include /* malloc() realloc() free() strtoll() */ -#include /* memset() */ -#include "util/bdstring.h" - -#include "bitdht/bencode.h" - -/*** - * #define BE_DEBUG_DECODE 1 - * #define BE_DEBUG 1 // controlled from Makefile too. - ***/ - -#ifdef BE_DEBUG_DECODE - #include /* debug */ -#endif - -static be_node *be_alloc(be_type type) -{ - be_node *ret = (be_node *) malloc(sizeof(*ret)); - if (ret) { - memset(ret, 0x00, sizeof(*ret)); - ret->type = type; - } - return ret; -} - -static long long _be_decode_int(const char **data, long long *data_len) -{ - char *endp; - long long ret = strtoll(*data, &endp, 10); - *data_len -= (endp - *data); - *data = endp; - -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_int(pnt: %p, rem: %lld) = %lld\n", *data, *data_len, ret); -#endif - return ret; -} - -long long be_str_len(be_node *node) -{ - long long ret = 0; - if (node->val.s) - memcpy(&ret, node->val.s - sizeof(ret), sizeof(ret)); - return ret; -} - -static char *_be_decode_str(const char **data, long long *data_len) -{ -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str(pnt: %p, rem: %lld)\n", *data, *data_len); -#endif - long long sllen = _be_decode_int(data, data_len); - long slen = sllen; - unsigned long len; - char *ret = NULL; - - /* slen is signed, so negative values get rejected */ - if (sllen < 0) - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str() reject bad length\n"); -#endif - return ret; - } - - /* reject attempts to allocate large values that overflow the - * size_t type which is used with malloc() - */ - if (sizeof(long long) != sizeof(long)) - if (sllen != slen) - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str() reject large_values\n"); -#endif - return ret; - } - - /* make sure we have enough data left */ - if (sllen > *data_len - 1) - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str() reject large_values\n"); -#endif - return ret; - } - - /* switch from signed to unsigned so we don't overflow below */ - len = slen; - - if (**data == ':') { - char *_ret = (char *) malloc(sizeof(sllen) + len + 1); - - if(_ret == NULL) - { - fprintf(stderr, "(EE) bencode::_be_decode_str(): " - "ERROR. cannot allocate memory for %lu bytes.\n" - , len+1+sizeof(sllen) ); - return ret; - } - - memcpy(_ret, &sllen, sizeof(sllen)); - ret = _ret + sizeof(sllen); - memcpy(ret, *data + 1, len); - ret[len] = '\0'; - *data += len + 1; - *data_len -= len + 1; - -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str() read %ld bytes\n", len+1); -#endif - } - else - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode_str() reject missing :\n"); -#endif - } - return ret; -} - -static be_node *_be_decode(const char **data, long long *data_len) -{ -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode(pnt: %p, rem: %lld)\n", *data, *data_len); -#endif - be_node *ret = NULL; - - if (!*data_len) - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() reject invalid datalen\n"); -#endif - return ret; - } - - switch (**data) { - /* lists */ - case 'l': { - unsigned int i = 0; -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() found list\n"); -#endif - - ret = be_alloc(BE_LIST); - - --(*data_len); - ++(*data); - while (**data != 'e') { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() list get item (%d)\n", i); -#endif - ret->val.l = (be_node **) realloc(ret->val.l, (i + 2) * sizeof(*ret->val.l)); - ret->val.l[i] = _be_decode(data, data_len); - if (ret->val.l[i] == NULL) - { - /* failed decode - kill decode */ -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() failed list decode - kill\n"); -#endif - be_free(ret); - return NULL; - } - ++i; - } - --(*data_len); - ++(*data); - - /* empty list case. */ - if (i == 0) - { - ret->val.l = (be_node **) realloc(ret->val.l, 1 * sizeof(*ret->val.l)); - } - - ret->val.l[i] = NULL; - - return ret; - } - - /* dictionaries */ - case 'd': { - unsigned int i = 0; -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() found dictionary\n"); -#endif - - ret = be_alloc(BE_DICT); - - --(*data_len); - ++(*data); - while (**data != 'e') { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() dictionary get key (%d)\n", i); -#endif - ret->val.d = (be_dict *) realloc(ret->val.d, (i + 2) * sizeof(*ret->val.d)); - ret->val.d[i].key = _be_decode_str(data, data_len); -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() dictionary get val\n"); -#endif - ret->val.d[i ].val = _be_decode(data, data_len); - ret->val.d[i+1].val = NULL ; // ensures termination of loops based on 0x0 value, otherwise, uninitialized - // memory occurs if(ret->val.d[i].key == 0x0 && ret->val.d[i].val != NULL) - // when calling be_free 8 lines below this point... - - if ((ret->val.d[i].key == NULL) || (ret->val.d[i].val == NULL)) - { - /* failed decode - kill decode */ -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() failed dict decode - kill\n"); -#endif - be_free(ret); - return NULL; - } - ++i; - } - --(*data_len); - ++(*data); - - /* empty dictionary case. */ - if (i == 0) - { - ret->val.d = (be_dict *) realloc(ret->val.d, 1 * sizeof(*ret->val.d)); - } - - - ret->val.d[i].val = NULL; - return ret; - } - - /* integers */ - case 'i': { - ret = be_alloc(BE_INT); -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() found int\n"); -#endif - - --(*data_len); - ++(*data); - ret->val.i = _be_decode_int(data, data_len); - if (**data != 'e') - { -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() reject data != e - kill\n"); -#endif - be_free(ret); - return NULL; - } - --(*data_len); - ++(*data); - - return ret; - } - - /* byte strings */ - case '0'...'9': { - ret = be_alloc(BE_STR); -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() found string\n"); -#endif - - ret->val.s = _be_decode_str(data, data_len); - - return ret; - } - - /* invalid */ - default: -#ifdef BE_DEBUG_DECODE - fprintf(stderr, "bencode::_be_decode() found invalid - kill\n"); -#endif - return NULL; - break; - } - - return ret; -} - -be_node *be_decoden(const char *data, long long len) -{ - return _be_decode(&data, &len); -} - -be_node *be_decode(const char *data) -{ - return be_decoden(data, strlen(data)); -} - -static inline void _be_free_str(char *str) -{ - if (str) - free(str - sizeof(long long)); -} -void be_free(be_node *node) -{ - switch (node->type) { - case BE_STR: - _be_free_str(node->val.s); - break; - - case BE_INT: - break; - - case BE_LIST: { - unsigned int i; - for (i = 0; node->val.l[i]; ++i) - be_free(node->val.l[i]); - free(node->val.l); - break; - } - - case BE_DICT: { - unsigned int i; - for (i = 0; node->val.d[i].val; ++i) { - _be_free_str(node->val.d[i].key); - be_free(node->val.d[i].val); - } - free(node->val.d); - break; - } - } - free(node); -} - -#ifdef BE_DEBUG -#include -#include - -static void _be_dump_indent(ssize_t indent) -{ - while (indent-- > 0) - printf(" "); -} -static void _be_dump(be_node *node, ssize_t indent) -{ - size_t i; - - _be_dump_indent(indent); - indent = abs(indent); - - switch (node->type) { - case BE_STR: - be_dump_str(node); - //printf("str = %s (len = %lli)\n", node->val.s, be_str_len(node)); - break; - - case BE_INT: - printf("int = %lli\n", node->val.i); - break; - - case BE_LIST: - puts("list ["); - - for (i = 0; node->val.l[i]; ++i) - _be_dump(node->val.l[i], indent + 1); - - _be_dump_indent(indent); - puts("]"); - break; - - case BE_DICT: - puts("dict {"); - - for (i = 0; node->val.d[i].val; ++i) { - _be_dump_indent(indent + 1); - printf("%s => ", node->val.d[i].key); - _be_dump(node->val.d[i].val, -(indent + 1)); - } - - _be_dump_indent(indent); - puts("}"); - break; - } -} -void be_dump(be_node *node) -{ - _be_dump(node, 0); -} - -void be_dump_str(be_node *node) -{ - if (node->type != BE_STR) - { - printf("be_dump_str(): error not a string\n"); - return; - } - - int len = be_str_len(node); - int i = 0; - printf("str[%d] = ", len); - for(i = 0; i < len; i++) - { - /* sensible chars */ - if ((node->val.s[i] > 31) && (node->val.s[i] < 127)) - { - printf("%c", node->val.s[i]); - } - else - { - printf("[%d]", node->val.s[i]); - } - } - printf("\n"); -} - - -#endif - -/******************** New Functions added by drBob ************* - * Output bencode - * - */ - -int be_encode(be_node *node, char *str, int len) -{ - size_t i; - int loc = 0; - - switch (node->type) { - case BE_STR: - bd_snprintf(str, len, "%lli:", be_str_len(node)); - loc += strlen(&(str[loc])); - - memcpy(&(str[loc]), node->val.s, be_str_len(node)); - loc += be_str_len(node); - break; - - case BE_INT: - bd_snprintf(str, len, "i%llie", node->val.i); - loc += strlen(&(str[loc])); - break; - - case BE_LIST: - - snprintf(str, len, "l"); - loc += 1; - - for (i = 0; node->val.l[i]; ++i) - { - loc += be_encode(node->val.l[i], &(str[loc]), len-loc); - } - - snprintf(&(str[loc]), len - loc, "e"); - loc += 1; - - break; - - case BE_DICT: - snprintf(str, len, "d"); - loc += 1; - - for (i = 0; node->val.d[i].val; ++i) { - - /* assumption that key must be ascii! */ - snprintf(&(str[loc]), len-loc, "%i:%s", - (int) strlen(node->val.d[i].key), - node->val.d[i].key); - loc += strlen(&(str[loc])); - loc += be_encode(node->val.d[i].val, &(str[loc]), len-loc); - } - - snprintf(&(str[loc]), len - loc, "e"); - loc += 1; - - break; - } - return loc; -} - -/* hackish way to create nodes! */ -be_node *be_create_dict() -{ - be_node *n = be_decode("de"); - return n; -} - - -be_node *be_create_list() -{ - be_node *n = be_decode("le"); - return n; -} - -be_node *be_create_str(const char *str) -{ - - /* must */ - be_node *n = NULL; - int len = strlen(str); - long long int sllen = len; - char *_ret = (char *) malloc(sizeof(sllen) + len + 1); - if(_ret == NULL) - { - fprintf(stderr, "(EE) bencode::be_create_str(): " - "ERROR. cannot allocate memory for %lu bytes.\n" - , len+1+sizeof(sllen) ); - return n; - } - char *ret = NULL; - n = be_alloc(BE_STR); - - memcpy(_ret, &sllen, sizeof(sllen)); - ret = _ret + sizeof(sllen); - memcpy(ret, str, len); - ret[len] = '\0'; - - n->val.s = ret; - - return n; -} - -be_node *be_create_str_wlen(const char *str, int len) /* not including \0 */ -{ - - /* must */ - be_node *n = NULL; - long long int sllen = len; - char *_ret = (char *) malloc(sizeof(sllen) + len + 1); - if(_ret == NULL) - { - fprintf(stderr, "(EE) bencode::be_create_str_wlen(): " - "ERROR. cannot allocate memory for %lu bytes.\n" - , len+1+sizeof(sllen) ); - return n; - } - char *ret = NULL; - n = be_alloc(BE_STR); - - memcpy(_ret, &sllen, sizeof(sllen)); - ret = _ret + sizeof(sllen); - memcpy(ret, str, len); - ret[len] = '\0'; - - n->val.s = ret; - - return n; -} - -be_node *be_create_int(long long int num) -{ - /* must */ - be_node *n = be_alloc(BE_INT); - n->val.i = num; - return n; -} - -int be_add_keypair(be_node *dict, const char *str, be_node *node) -{ - int i = 0; - - /* only if dict type */ - if (dict->type != BE_DICT) - { - return 0; - } - - // get to end of dict. - for(i = 0; dict->val.d[i].val; i++) - ;//Silent empty body for loop for clang - - //fprintf(stderr, "be_add_keypair() i = %d\n",i); - - /* realloc space */ - dict->val.d = (be_dict *) realloc(dict->val.d, (i + 2) * sizeof(*dict->val.d)); - - /* stupid key storage system */ - int len = strlen(str); - long long int sllen = len; - char *_ret = (char *) malloc(sizeof(sllen) + len + 1); - if(_ret == NULL) - { - fprintf(stderr, "(EE) bencode::be_create_str_wlen(): " - "ERROR. cannot allocate memory for %lu bytes.\n" - , len+1+sizeof(sllen) ); - return 0; - } - char *ret = NULL; - - //fprintf(stderr, "be_add_keypair() key len = %d\n",len); - - memcpy(_ret, &sllen, sizeof(sllen)); - ret = _ret + sizeof(sllen); - memcpy(ret, str, len); - ret[len] = '\0'; - - dict->val.d[i].key = ret; - dict->val.d[i].val = node; - i++; - dict->val.d[i].val = NULL; - - return 1; -} - - -int be_add_list(be_node *list, be_node *node) -{ - int i = 0; - - /* only if dict type */ - if (list->type != BE_LIST) - { - return 0; - } - - // get to end of dict. - for(i = 0; list->val.l[i]; i++) - ;//Silent empty body for loop for clang - - /* realloc space */ - list->val.l = (be_node **) realloc(list->val.l, (i + 2) * sizeof(*list->val.l)); - list->val.l[i] = node; - ++i; - list->val.l[i] = NULL; - - return 1; -} - - - - diff --git a/libbitdht/src/bitdht/bencode.h b/libbitdht/src/bitdht/bencode.h deleted file mode 100644 index 4e733b66f..000000000 --- a/libbitdht/src/bitdht/bencode.h +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * bitdht/bdencode.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * by Mike Frysinger * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef _BENCODE_H -#define _BENCODE_H - -/* USAGE: - * - pass the string full of the bencoded data to be_decode() - * - parse the resulting tree however you like - * - call be_free() on the tree to release resources - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - BE_STR, - BE_INT, - BE_LIST, - BE_DICT, -} be_type; - -struct be_dict; -struct be_node; - -/* - * XXX: the "val" field of be_dict and be_node can be confusing ... - */ - -typedef struct be_dict { - char *key; - struct be_node *val; -} be_dict; - -typedef struct be_node { - be_type type; - union { - char *s; - long long i; - struct be_node **l; - struct be_dict *d; - } val; -} be_node; - -extern long long be_str_len(be_node *node); -// This function uses strlen, so is unreliable. -//extern be_node *be_decode(const char *bencode); -extern be_node *be_decoden(const char *bencode, long long bencode_len); -extern void be_free(be_node *node); -extern void be_dump(be_node *node); -extern void be_dump_str(be_node *node); - -// New Functions for the other half of the work - encoding */ - -extern int be_encode(be_node *node, char *str, int len); - - -// Creating the data structure. -extern int be_add_list(be_node *list, be_node *node); -extern int be_add_keypair(be_node *dict, const char *str, be_node *node); -extern be_node *be_create_int(long long int num); -extern be_node *be_create_list(); -extern be_node *be_create_str(const char *str); -extern be_node *be_create_str_wlen(const char *str, int len); /* not including \0 */ -extern be_node *be_create_dict(); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libbitdht/src/example/bdboot.txt b/libbitdht/src/example/bdboot.txt deleted file mode 100644 index 1d0d204af..000000000 --- a/libbitdht/src/example/bdboot.txt +++ /dev/null @@ -1,500 +0,0 @@ -77.196.18.56 22750 -77.84.97.16 31837 -213.174.60.46 17919 -50.113.92.209 6881 -184.89.243.73 43344 -210.195.47.196 19861 -83.49.197.212 61627 -184.145.109.37 31067 -180.18.98.235 29543 -186.254.61.185 40200 -78.213.113.102 9182 -89.92.251.113 16946 -195.240.45.224 6881 -188.142.164.252 43063 -41.45.41.123 18636 -219.84.184.204 61337 -95.26.91.94 6881 -79.114.193.207 17966 -83.213.185.157 43235 -37.110.127.110 6881 -178.35.204.111 6881 -174.48.201.143 41918 -109.214.57.82 1042 -121.214.57.226 51413 -90.184.93.164 22828 -98.214.166.21 38072 -50.0.146.178 51413 -81.13.253.217 46370 -81.249.29.121 7812 -92.80.201.189 20026 -95.37.18.51 59118 -50.53.143.88 57568 -180.183.213.112 11823 -112.206.13.117 41825 -79.169.77.54 63189 -76.174.205.156 8605 -2.1.187.15 50269 -175.151.131.80 16001 -82.7.124.219 12334 -217.209.125.15 26155 -93.181.201.89 54631 -197.87.68.102 25317 -183.109.112.49 58359 -203.198.141.201 7453 -82.192.32.151 58864 -184.146.76.179 13586 -37.107.121.203 18429 -186.54.1.246 38354 -184.18.8.33 8784 -77.101.130.178 61762 -109.8.154.28 19120 -74.96.156.188 31749 -94.96.167.130 64130 -93.81.126.53 6881 -79.136.243.46 46486 -78.29.75.248 6881 -114.42.47.178 9089 -31.147.61.11 23853 -193.253.220.184 6881 -80.57.45.239 28239 -72.192.215.39 30028 -91.74.119.134 49246 -85.250.43.217 41490 -188.176.218.22 35407 -98.119.4.86 1024 -89.143.138.33 64606 -46.138.37.148 59039 -178.120.85.170 24550 -67.185.95.9 32173 -98.197.42.116 19866 -114.38.21.113 7694 -77.46.26.128 38127 -93.80.96.134 23683 -60.241.209.107 57588 -171.97.173.243 9327 -50.43.117.21 42660 -87.244.169.128 55807 -94.190.105.157 6881 -178.122.199.251 16480 -76.88.254.191 27137 -112.120.144.128 60152 -77.249.124.77 49187 -165.132.236.14 25390 -87.16.197.67 20787 -80.103.109.43 55260 -195.234.21.119 6881 -176.212.60.108 60378 -178.185.98.43 12420 -124.149.151.181 33603 -85.220.66.170 35131 -109.130.31.27 11460 -72.223.102.189 11614 -111.15.147.164 16001 -83.202.163.16 6881 -92.246.22.40 33576 -94.41.249.131 10613 -95.24.101.211 6881 -98.232.199.100 29721 -174.101.153.252 38195 -91.157.230.16 1885 -109.211.143.205 13722 -84.123.4.247 29043 -112.209.16.158 19102 -114.34.46.63 6881 -85.138.230.74 56197 -62.169.127.9 26665 -211.217.2.251 41870 -81.221.84.77 20214 -109.197.191.45 19604 -46.118.116.209 20711 -46.42.23.240 53559 -199.127.250.15 29015 -78.220.115.99 49482 -71.232.195.149 56530 -84.123.59.159 13963 -213.251.184.146 64347 -67.164.23.233 7119 -86.194.215.166 14316 -89.224.149.142 25365 -94.23.49.143 8000 -78.119.193.151 55227 -78.222.160.139 37995 -89.209.82.248 12425 -178.137.112.35 14571 -94.23.0.84 51582 -78.247.176.4 18105 -90.41.206.239 30502 -78.241.70.65 22014 -98.194.6.21 51413 -174.119.150.115 17065 -189.5.22.202 52412 -93.124.97.171 49001 -186.4.42.27 20837 -24.144.184.102 14888 -78.173.175.56 53453 -79.114.14.206 4602 -109.184.163.146 11789 -98.200.252.137 18502 -79.82.130.49 20757 -5.165.66.132 63326 -46.29.147.201 20232 -114.32.184.15 25962 -94.21.70.206 50541 -92.98.171.108 51413 -188.49.25.79 46883 -90.149.227.168 49241 -92.99.221.105 51405 -123.139.45.71 16001 -68.98.108.234 24290 -88.169.60.195 17108 -114.37.154.22 16120 -121.219.232.47 65073 -46.119.196.109 19075 -123.110.104.200 29499 -77.73.46.124 28966 -87.253.26.85 45934 -176.108.146.88 6881 -188.187.45.126 43757 -92.2.212.97 15078 -178.140.169.137 22922 -114.38.14.84 16958 -80.98.106.227 9773 -86.169.117.185 51938 -201.53.229.60 1041 -65.95.191.51 51413 -24.78.8.98 6884 -90.204.42.12 48402 -76.7.214.210 35875 -88.155.36.246 15856 -78.227.88.161 23191 -62.83.111.85 36398 -130.43.29.146 52526 -88.170.61.126 32761 -85.246.109.226 6890 -82.237.40.39 39052 -95.239.56.106 62200 -71.187.209.2 22274 -178.148.68.18 53318 -78.163.220.242 31758 -188.235.149.202 63083 -119.201.103.241 62715 -83.87.5.5 43317 -201.83.71.123 50579 -83.6.22.221 52512 -95.54.76.150 56930 -207.255.112.154 6881 -188.121.244.133 10980 -41.212.221.164 33050 -178.168.58.44 23476 -142.161.41.171 41788 -211.133.168.214 44631 -220.18.72.3 64774 -70.114.155.3 34892 -97.85.86.199 6890 -119.74.54.94 6881 -114.34.239.242 22647 -67.128.168.196 11524 -86.145.211.200 49330 -72.230.75.87 21095 -31.35.57.129 13924 -190.60.48.165 41301 -213.245.41.143 40018 -95.104.80.193 6881 -120.208.30.229 16001 -93.105.81.215 21000 -93.96.13.136 12181 -190.88.179.253 20701 -58.7.210.130 51413 -195.222.95.57 51413 -121.223.47.224 41563 -85.219.118.111 27483 -78.43.137.174 10409 -77.71.220.234 62357 -85.107.182.248 19486 -37.235.207.247 30166 -176.97.212.163 22523 -88.230.184.110 25432 -94.44.164.74 60966 -95.188.23.129 42927 -78.242.168.94 34153 -62.93.99.6 28010 -78.105.105.87 42127 -208.101.109.128 53329 -164.215.87.224 57073 -87.106.187.29 20277 -91.121.114.171 58846 -80.42.246.251 20502 -188.72.98.36 15503 -176.31.248.87 6338 -118.160.199.38 63400 -174.71.20.57 52193 -113.161.204.192 6881 -2.94.72.90 27587 -89.204.110.192 6881 -76.121.38.23 58982 -93.95.160.156 13118 -122.174.156.164 15004 -94.155.59.112 57833 -176.49.172.107 49001 -23.16.200.217 51413 -60.241.87.17 24478 -108.242.252.38 39304 -201.252.144.11 15506 -92.125.17.239 25548 -114.79.138.158 60635 -76.103.79.28 36151 -77.71.69.65 12087 -138.199.66.212 26174 -119.131.41.152 1231 -119.202.178.119 45249 -78.141.127.164 55618 -88.245.188.55 28097 -217.165.53.221 24579 -46.22.234.12 14916 -98.199.98.228 32970 -203.213.94.200 14161 -66.197.135.74 9870 -213.167.206.125 38106 -80.83.245.36 6993 -112.203.171.200 25932 -105.236.34.74 43961 -92.49.5.186 38678 -46.61.12.234 49001 -91.148.14.62 11206 -95.37.162.145 14476 -68.192.162.202 31159 -68.209.239.148 50375 -75.185.11.189 23993 -178.72.159.43 47954 -118.160.199.38 61182 -75.142.21.2 56117 -46.187.88.219 48529 -98.127.163.114 53062 -94.245.153.136 23040 -109.174.3.81 51413 -77.232.162.51 14257 -94.96.112.204 35187 -118.160.199.38 51651 -5.13.18.103 24121 -79.226.190.78 18189 -95.90.236.216 41463 -83.134.60.207 10267 -118.160.199.38 51532 -176.31.109.159 24586 -99.242.88.203 21704 -88.174.176.173 56969 -84.151.248.98 61500 -123.195.214.39 20846 -94.62.25.152 39020 -89.33.72.233 1398 -92.37.27.83 37375 -83.110.225.79 17257 -178.36.198.215 22849 -112.234.202.158 16001 -188.231.143.20 6881 -5.12.126.206 34538 -62.65.216.158 13414 -92.43.189.45 3140 -79.9.144.222 29037 -93.77.32.187 57408 -91.247.142.205 58199 -85.114.60.149 17582 -119.196.44.47 51763 -178.88.3.227 33031 -76.30.131.83 49366 -86.168.167.166 55451 -212.45.81.173 16427 -188.224.10.109 46059 -82.178.114.74 50836 -78.55.114.191 42839 -85.54.211.184 17283 -95.135.101.164 55829 -209.195.77.83 34603 -79.153.101.234 11154 -71.63.225.31 21053 -184.147.116.143 49025 -88.186.230.88 12048 -89.132.181.63 61498 -95.84.208.14 9372 -79.93.218.69 28681 -64.113.125.178 61127 -174.100.51.253 44460 -88.3.236.194 10926 -109.194.234.36 14342 -68.106.225.140 47417 -78.24.231.166 6881 -84.40.80.3 6890 -177.5.36.152 12588 -68.82.32.238 18307 -64.121.118.201 61270 -75.40.21.238 51413 -99.59.129.46 26141 -79.95.171.102 11092 -67.71.140.245 15582 -95.32.187.214 14778 -213.112.177.129 43304 -81.51.97.133 40039 -89.133.89.51 55846 -79.18.246.192 20356 -109.124.197.42 31559 -182.53.45.3 14895 -74.219.135.69 30239 -95.111.0.20 34295 -84.154.235.198 59678 -93.58.14.83 51413 -213.114.48.42 38511 -46.48.90.11 55025 -5.2.58.49 49001 -92.139.252.16 36535 -94.68.144.118 10009 -75.187.202.104 44822 -84.52.169.26 10838 -114.32.211.85 30116 -75.69.72.31 51413 -118.160.199.38 63151 -142.59.218.136 11300 -118.160.199.38 63619 -118.160.199.38 59277 -82.47.63.231 26035 -67.8.141.69 63990 -223.18.249.29 7221 -82.136.113.22 6881 -86.100.227.142 50497 -188.186.13.95 21313 -24.128.39.166 5223 -31.8.136.66 11996 -82.137.118.90 26474 -84.217.43.156 45620 -217.29.187.23 62523 -108.254.5.66 58192 -182.177.228.43 31532 -118.160.199.38 60134 -67.167.180.162 11451 -188.164.212.104 28566 -95.196.203.111 59402 -213.27.20.223 53410 -178.44.187.32 52209 -70.83.35.78 31982 -1.172.161.190 17526 -78.237.111.89 45254 -188.25.246.130 16313 -67.173.33.90 33134 -212.49.47.32 19949 -176.214.214.73 64892 -173.73.46.92 52828 -71.237.6.246 41304 -70.113.2.167 45645 -88.84.191.25 30536 -87.2.74.180 6783 -96.63.15.208 34651 -76.181.135.146 17016 -79.168.31.62 2622 -95.153.169.40 19697 -88.217.36.182 2924 -119.96.130.9 12038 -90.225.103.241 40066 -78.106.178.64 46183 -220.136.37.144 27075 -92.87.167.73 55624 -188.232.61.83 6881 -183.89.3.101 10618 -111.242.54.149 15979 -120.146.228.149 6881 -67.242.169.143 6886 -31.8.71.71 10170 -78.236.77.65 32026 -91.137.168.238 27616 -93.109.84.235 21443 -77.34.44.71 35691 -109.209.40.17 55542 -83.157.77.228 7812 -88.233.167.39 20620 -69.176.171.40 11254 -93.11.175.201 41027 -50.71.135.98 20332 -69.181.169.181 7313 -46.8.136.196 57085 -180.64.39.48 14708 -46.211.113.5 49001 -142.163.53.182 58144 -90.38.76.72 4699 -83.252.23.84 10699 -78.163.181.120 16519 -221.118.191.176 17563 -184.41.75.34 57537 -99.192.77.139 33333 -88.174.167.76 30032 -46.116.177.103 22754 -94.103.196.139 54378 -188.77.246.133 35496 -217.76.184.18 51413 -108.160.185.132 31530 -50.83.34.19 23846 -193.77.159.24 43611 -80.14.161.164 51789 -114.185.184.10 23151 -82.235.101.26 7816 -92.83.188.95 10477 -46.180.245.79 53580 -46.37.83.122 37389 -86.29.220.199 28527 -92.137.208.191 29253 -85.167.249.218 55649 -221.127.216.99 21461 -130.89.165.24 10110 -99.60.78.40 18894 -49.145.59.194 38935 -92.247.248.50 23666 -5.149.211.210 22277 -176.226.153.243 61967 -174.117.49.59 13052 -121.141.14.57 30323 -83.155.218.188 51413 -129.21.122.81 32785 -46.118.83.183 12324 -92.255.208.221 34798 -212.21.13.209 56909 -220.120.236.151 11393 -37.218.190.131 35691 -46.41.109.26 39584 -2.51.116.185 63433 -67.86.174.199 33605 -212.74.222.13 38345 -115.240.98.113 51413 -37.59.55.58 51413 -109.72.144.240 41290 -207.224.196.66 10731 -78.128.52.177 24574 -79.138.67.151 47942 -50.201.138.122 10228 -176.9.113.77 61059 -94.21.30.143 63448 -178.89.100.227 6881 -91.67.129.216 1210 -82.232.212.66 55826 -78.228.230.130 12577 -79.175.106.234 12684 -213.231.145.208 12306 -97.106.156.54 63552 -79.176.173.50 33043 -75.70.84.67 52856 -31.220.168.41 35190 -1.161.107.196 31811 -80.98.158.177 29436 -88.148.233.194 38081 -184.166.72.229 63472 -93.186.192.165 39020 -151.25.110.226 49289 -178.45.159.135 31825 -98.225.11.98 51769 -109.28.82.4 33620 -90.16.53.195 31338 -223.219.73.227 17107 -92.96.51.71 56237 -112.173.11.227 63314 -37.229.60.103 6881 -90.29.226.250 14329 -182.210.49.84 11993 -177.32.251.226 27655 -189.54.195.49 50555 diff --git a/libbitdht/src/example/bdhandler.cc b/libbitdht/src/example/bdhandler.cc deleted file mode 100644 index 0b8766a5a..000000000 --- a/libbitdht/src/example/bdhandler.cc +++ /dev/null @@ -1,349 +0,0 @@ -/* - * libretroshare/src/dht: bdhandler.h - * - * BitDht example interface - * - * Copyright 2009-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "bitdht@lunamutt.com". - * - */ - - -#include -#include -#include -#include - -#include - -#include "bdhandler.h" - - -/**** - * This example bitdht app is designed to perform a single shot DHT search. - * Ww want to minimise the dht work, and number of UDP packets sent. - * - * This means we need to add: - * - don't search for App network. (libbitdht option) - * - don't bother filling up Space. (libbitdht option) - * - Programmatically add bootstrap peers. (libbitdht option) - * - */ - - - -/* This is a conversion callback class - */ - -class BdCallback: public BitDhtCallback -{ - public: - - BdCallback(BitDhtHandler *parent) - :mParent(parent) { return; } - -virtual int dhtNodeCallback(const bdId *id, uint32_t peerflags) -{ - return mParent->NodeCallback(id, peerflags); -} - -virtual int dhtPeerCallback(const bdId *id, uint32_t status) -{ - return mParent->PeerCallback(id, status); -} - -virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status) -{ - return mParent->ValueCallback(id, key, status); -} - -virtual int dhtConnectCallback(const bdId*, const bdId*, const bdId*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) -{ - return 1; -} - -virtual int dhtInfoCallback(const bdId*, uint32_t, uint32_t, std::string) -{ - return 1; -} - - private: - - BitDhtHandler *mParent; -}; - - -BitDhtHandler::BitDhtHandler(bdNodeId *ownId, uint16_t port, std::string appId, std::string bootstrapfile) -{ - std::cerr << "BitDhtHandler::BitDhtHandler()" << std::endl; - std::cerr << "Using Id: "; - bdStdPrintNodeId(std::cerr, ownId); - std::cerr << std::endl; - - std::cerr << "Using Bootstrap File: " << bootstrapfile; - std::cerr << std::endl; - std::cerr << "Converting OwnId to bdNodeId...."; - std::cerr << std::endl; - - /* standard dht behaviour */ - bdDhtFunctions *stdfns = new bdStdDht(); - - std::cerr << "BitDhtHandler() startup ... creating UdpBitDht"; - std::cerr << std::endl; - - /* create dht */ - struct sockaddr_in local; - memset(&local, 0, sizeof(local)); - local.sin_family = AF_INET; - local.sin_addr.s_addr = 0; - local.sin_port = htons(port); - - mStack = new UdpStack(local); - - mUdpBitDht = new UdpBitDht(mStack, ownId, appId, bootstrapfile, stdfns); - mStack->addReceiver(mUdpBitDht); - - /* setup callback to here */ - BdCallback *bdcb = new BdCallback(this); - mUdpBitDht->addCallback(bdcb); - - std::cerr << "BitDhtHandler() starting threads and dht"; - std::cerr << std::endl; - - mUdpBitDht->start(); /* starts up the bitdht thread */ - - /* setup best mode for quick search */ - uint32_t dhtFlags = BITDHT_MODE_TRAFFIC_MED | BITDHT_MODE_RELAYSERVERS_IGNORED; - mUdpBitDht->setDhtMode(dhtFlags); - mUdpBitDht->setAttachMode(false); - - /* switch on the dht too */ - mUdpBitDht->startDht(); -} - - /* pqiNetAssist - external interface functions */ -void BitDhtHandler::enable(bool on) -{ - std::cerr << "p3BitDht::enable(" << on << ")"; - std::cerr << std::endl; - if (on) - { - mUdpBitDht->startDht(); - } - else - { - mUdpBitDht->stopDht(); - } -} - -void BitDhtHandler::shutdown() /* blocking call */ -{ - mUdpBitDht->stopDht(); -} - - -void BitDhtHandler::restart() -{ - mUdpBitDht->stopDht(); - mUdpBitDht->startDht(); -} - -bool BitDhtHandler::getEnabled() -{ - return (mUdpBitDht->stateDht() != 0); -} - -bool BitDhtHandler::getActive() -{ - return (mUdpBitDht->stateDht() >= BITDHT_MGR_STATE_ACTIVE); -} - - - - - /* pqiNetAssistConnect - external interface functions */ - /* add / remove peers */ -bool BitDhtHandler::FindNode(bdNodeId *peerId) -{ - std::cerr << "BitDhtHandler::FindNode("; - bdStdPrintNodeId(std::cerr, peerId); - std::cerr << ")" << std::endl; - - - BssResult res; - res.id.id = *peerId; - res.mode = BSS_SINGLE_SHOT; - res.status = 0; - - { - bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ - mSearchNodes[*peerId] = res; - } - - /* add in peer */ - mUdpBitDht->addFindNode(peerId, BITDHT_QFLAGS_DISGUISE); - - return true ; -} - -bool BitDhtHandler::DropNode(bdNodeId *peerId) -{ - std::cerr << "BitDhtHandler::DropNode("; - bdStdPrintNodeId(std::cerr, peerId); - std::cerr << ")" << std::endl; - std::cerr << std::endl; - - /* remove in peer */ - mUdpBitDht->removeFindNode(peerId); - - bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ - - /* find the node from our list */ - std::map::iterator it; - it = mSearchNodes.find(*peerId); - if (it != mSearchNodes.end()) - { - std::cerr << "BitDhtHandler::DropNode() Found NodeId, removing"; - std::cerr << std::endl; - - mSearchNodes.erase(it); - } - return true ; -} - - -bool BitDhtHandler::SearchResult(bdId *id, uint32_t &status) -{ - bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ - - /* find the node from our list */ - std::map::iterator it; - it = mSearchNodes.find(id->id); - if (it != mSearchNodes.end()) - { - if (it->second.status != 0) - { - std::cerr << "BitDhtHandler::SearchResults() Found Results"; - std::cerr << std::endl; - status = it->second.status; - *id = it->second.id; - return true; - } - - std::cerr << "BitDhtHandler::SearchResults() No Results Yet"; - std::cerr << std::endl; - return false; - } - - std::cerr << "BitDhtHandler::SearchResults() ERROR: No Search Entry"; - std::cerr << std::endl; - return false; -} - - -/********************** Callback Functions **************************/ - -int BitDhtHandler::NodeCallback(const bdId *id, uint32_t peerflags) -{ -#ifdef DEBUG_BITDHT - std::cerr << "BitDhtHandler::NodeCallback()"; - bdStdPrintNodeId(std::cerr, &(id->id)); - std::cerr << " flags: " << peerflags; - std::cerr << std::endl; -#endif - - return 0; -} - -int BitDhtHandler::PeerCallback(const bdId *id, uint32_t status) -{ - std::cerr << "BitDhtHandler::PeerCallback() NodeId: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; - - bdStackMutex stack(resultsMtx); /********** MUTEX LOCKED *************/ - - /* find the node from our list */ - std::map::iterator it; - it = mSearchNodes.find(id->id); - if (it == mSearchNodes.end()) - { - std::cerr << "BitDhtHandler::PeerCallback() Unknown NodeId !!! "; - std::cerr << std::endl; - - return 1; - } - it->second.status = status; - - bool connect = false; - switch(status) - { - case BITDHT_MGR_QUERY_FAILURE: - /* do nothing */ - std::cerr << "BitDhtHandler::PeerCallback() QUERY FAILURE ... do nothin "; - std::cerr << std::endl; - - - break; - - case BITDHT_MGR_QUERY_PEER_OFFLINE: - /* do nothing */ - - std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER OFFLINE ... do nothin "; - std::cerr << std::endl; - - break; - - case BITDHT_MGR_QUERY_PEER_UNREACHABLE: - /* do nothing */ - - std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER UNREACHABLE ... saving address "; - std::cerr << std::endl; - it->second.id = *id; - - break; - - case BITDHT_MGR_QUERY_PEER_ONLINE: - /* do something */ - - std::cerr << "BitDhtHandler::PeerCallback() QUERY PEER ONLINE ... saving address"; - std::cerr << std::endl; - - it->second.id = *id; - break; - } - return 1; -} - - - -int BitDhtHandler::ValueCallback(const bdNodeId *id, std::string key, uint32_t status) -{ - std::cerr << "BitDhtHandler::ValueCallback() NOOP for NOW"; - std::cerr << std::endl; - - std::cerr << "BitDhtHandler::ValueCallback()"; - bdStdPrintNodeId(std::cerr, id); - std::cerr << " key: " << key; - std::cerr << " status: " << status; - std::cerr << std::endl; - - /* ignore for now */ - return 0; -} - diff --git a/libbitdht/src/example/bdhandler.h b/libbitdht/src/example/bdhandler.h deleted file mode 100644 index c0c942db6..000000000 --- a/libbitdht/src/example/bdhandler.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * libbitdht/src/example/bdhandler.h - * - * BitDht interface example - * - * Copyright 2009-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "bitdht@lunamutt.com". - * - */ - - -#ifndef BITDHT_HANDLER_H -#define BITDHT_HANDLER_H - -#include -#include - -#include "udp/udpstack.h" -#include "udp/udpbitdht.h" -#include "bitdht/bdiface.h" - -/*** This class can be overloaded to use the XXXXCallback() Functions *****/ -class BitDhtIntCallback; - - -class BssResult -{ - public: - bdId id; - uint32_t mode; // single shot - uint32_t status; // SEARCHING, FAILURE, FOUND, MULTIPLE HITS. -}; - -#define BSS_SINGLE_SHOT 0x0001 - - -class BitDhtHandler -{ - - public: - - BitDhtHandler(bdNodeId *ownId, uint16_t port, std::string appId, std::string bootstrapfile); - -void enable(bool on); -void shutdown(); /* blocking call */ -void restart(); - -bool getEnabled(); -bool getActive(); - -bool FindNode(bdNodeId *peerId); -bool DropNode(bdNodeId *peerId); - -virtual int NodeCallback(const bdId *id, uint32_t peerflags); -virtual int PeerCallback(const bdId *id, uint32_t status); -virtual int ValueCallback(const bdNodeId *id, std::string key, uint32_t status); - -bool SearchResult(bdId *id, uint32_t &status); - - private: - - /* real DHT classes */ - UdpStack *mStack; - UdpBitDht *mUdpBitDht; - - bdMutex resultsMtx; /* for all class data (below) */ - - std::map mSearchNodes; -}; - - -#endif /* BITDHT_HANDLER_H */ - diff --git a/libbitdht/src/example/bootstrap_fn.cc b/libbitdht/src/example/bootstrap_fn.cc deleted file mode 100644 index 0288087f0..000000000 --- a/libbitdht/src/example/bootstrap_fn.cc +++ /dev/null @@ -1,84 +0,0 @@ - - -#include "bitdht/bdiface.h" -#include "bitdht/bdstddht.h" -#include "bdhandler.h" - -#include "bootstrap_fn.h" - -bool bdSingleShotFindPeer(const std::string bootstrapfile, const std::string peerId, std::string &peer_ip, uint16_t &peer_port) -{ - /* startup dht : with a random id! */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - - uint16_t port = 6775; - std::string appId = "bsId"; - BitDhtHandler dht(&ownId, port, appId, bootstrapfile); - - /* install search node */ - bdNodeId searchId; - if (!bdStdLoadNodeId(&searchId, peerId)) - { - std::cerr << "bdSingleShotFindPeer(): Invalid Input Id: " << peerId; - return false; - } - - std::cerr << "bssdht: searching for Id: "; - bdStdPrintNodeId(std::cerr, &searchId); - std::cerr << std::endl; - - dht.FindNode(&searchId); - - /* run your program */ - bdId resultId; - uint32_t status; - - resultId.id = searchId; - - while(false == dht.SearchResult(&resultId, status)) - { - sleep(10); - } - - std::cerr << "bdSingleShotFindPeer(): Found Result:" << std::endl; - - std::cerr << "\tId: "; - bdStdPrintId(std::cerr, &resultId); - std::cerr << std::endl; - - std::cerr << "\tstatus: " << status; - std::cerr << std::endl; - - dht.shutdown(); - - if ((status == BITDHT_QUERY_PEER_UNREACHABLE) || - (status == BITDHT_QUERY_SUCCESS)) - { - - peer_ip = bdnet_inet_ntoa(resultId.addr.sin_addr); - peer_port = ntohs(resultId.addr.sin_port); - - std::cerr << "Answer: "; - std::cerr << std::endl; - std::cerr << "\tPeer IpAddress: " << peer_ip; - std::cerr << std::endl; - std::cerr << "\tPeer Port: " << peer_port; - std::cerr << std::endl; - } - else - { - std::cerr << "Sorry, Cant be found!"; - std::cerr << std::endl; - } - - return true; -} - - - - - - - - diff --git a/libbitdht/src/example/bootstrap_fn.h b/libbitdht/src/example/bootstrap_fn.h deleted file mode 100644 index 19ff6d714..000000000 --- a/libbitdht/src/example/bootstrap_fn.h +++ /dev/null @@ -1,17 +0,0 @@ - -#include -#include - - -/* NOTE. At the moment only the bootstrapfile is actually used. - * peerId is ignored (a random peerId is searched for). ip & port are not filled in either. - * - * This is mainly to finish testing. - * - * Once the best form of the return functions is decided (ipv4 structure, or strings). - * this can be finished off. - * - */ - -bool bdSingleShotFindPeer(const std::string bootstrapfile, const std::string peerId, std::string &ip, uint16_t &port); - diff --git a/libbitdht/src/example/bssdht.cc b/libbitdht/src/example/bssdht.cc deleted file mode 100644 index 97f006260..000000000 --- a/libbitdht/src/example/bssdht.cc +++ /dev/null @@ -1,72 +0,0 @@ - -#include "bootstrap_fn.h" -#include -#include - -void args(char *name) -{ - std::cerr << std::endl; - std::cerr << "Dht Single Shot Searcher"; - std::cerr << std::endl; - std::cerr << "Usage:"; - std::cerr << std::endl; - std::cerr << "\t" << name << " -p "; - std::cerr << std::endl; - std::cerr << std::endl; - std::cerr << "NB: The PeerId is Required to Run"; - std::cerr << std::endl; - std::cerr << std::endl; -} - - -int main(int argc, char **argv) -{ - - std::string bootstrapfile = "bdboot.txt"; - std::string peerId; - std::string ip; - uint16_t port; - int c; - bool havePeerId = false; - - - while((c = getopt(argc, argv,"p:")) != -1) - { - switch (c) - { - case 'p': - peerId = optarg; - havePeerId = true; - break; - default: - args(argv[0]); - return 1; - break; - } - } - - if (!havePeerId) - { - args(argv[0]); - return 1; - } - - - std::cerr << "bssdht: starting up"; - std::cerr << std::endl; - - bdSingleShotFindPeer(bootstrapfile, peerId, ip, port); - - std::cerr << "bssdht: finished"; - std::cerr << std::endl; - - return 1; -} - - - - - - - - diff --git a/libbitdht/src/libbitdht.pro b/libbitdht/src/libbitdht.pro deleted file mode 100644 index ab53768a5..000000000 --- a/libbitdht/src/libbitdht.pro +++ /dev/null @@ -1,185 +0,0 @@ -# RetroShare main qmake build script -# -# Copyright (C) 2004-2019, Retroshare Team -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License along -# with this program. If not, see . -# -# SPDX-FileCopyrightText: Retroshare Team -# SPDX-License-Identifier: LGPL-3.0-or-later - -!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") - -TEMPLATE = lib -CONFIG += staticlib -CONFIG -= qt -TARGET = bitdht -DESTDIR = lib - -!include("use_libbitdht.pri"):error("Including") - -QMAKE_CXXFLAGS *= -Wall -DBE_DEBUG - -# treat warnings as error for better removing -#QMAKE_CFLAGS += -Werror -#QMAKE_CXXFLAGS += -Werror - -################################# Linux ########################################## -linux-* { - QMAKE_CC = $${QMAKE_CXX} -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -unix { - data_files.path = "$${DATA_DIR}" - data_files.files = bitdht/bdboot.txt - INSTALLS += data_files -} - -android-* { - # see https://community.kde.org/Necessitas/Assets - bdboot.files=bitdht/bdboot.txt - bdboot.path=/assets/values - INSTALLS += bdboot -} - -#################### Cross compilation for windows under Linux #################### - -win32-x-g++ { - OBJECTS_DIR = temp/win32xgcc/obj - # These have been replaced by _WIN32 && __MINGW32__ - # 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 - - INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ -} -################################# Windows ########################################## - -win32 { - QMAKE_CC = $${QMAKE_CXX} - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - DEFINES *= STATICLIB WIN32_LEAN_AND_MEAN - # These have been replaced by _WIN32 && __MINGW32__ - #DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW - - # 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 -} - -################################# MacOSX ########################################## - -mac { - QMAKE_CC = $${QMAKE_CXX} - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc -} - -################################# FreeBSD ########################################## - -freebsd-* { -} - -################################# OpenBSD ########################################## - -openbsd-* { -} - -################################# Haiku ########################################## - -haiku-* { - DESTDIR = lib -} - -################################### COMMON stuff ################################## -################################### COMMON stuff ################################## - -DEPENDPATH += . -INCLUDEPATH += . - -HEADERS += \ - bitdht/bdiface.h \ - bitdht/bencode.h \ - bitdht/bdobj.h \ - bitdht/bdmsgs.h \ - bitdht/bdpeer.h \ - bitdht/bdquery.h \ - bitdht/bdhash.h \ - bitdht/bdstore.h \ - bitdht/bdnode.h \ - bitdht/bdmanager.h \ - bitdht/bdstddht.h \ - bitdht/bdhistory.h \ - util/bdnet.h \ - util/bdthreads.h \ - util/bdrandom.h \ - util/bdfile.h \ - util/bdstring.h \ - udp/udplayer.h \ - udp/udpstack.h \ - udp/udpbitdht.h \ - bitdht/bdconnection.h \ - bitdht/bdfilter.h \ - bitdht/bdaccount.h \ - bitdht/bdquerymgr.h \ - util/bdbloom.h \ - bitdht/bdfriendlist.h \ - -SOURCES += \ - bitdht/bencode.c \ - bitdht/bdobj.cc \ - bitdht/bdmsgs.cc \ - bitdht/bdpeer.cc \ - bitdht/bdquery.cc \ - bitdht/bdhash.cc \ - bitdht/bdstore.cc \ - bitdht/bdnode.cc \ - bitdht/bdmanager.cc \ - bitdht/bdstddht.cc \ - bitdht/bdhistory.cc \ - util/bdnet.cc \ - util/bdthreads.cc \ - util/bdrandom.cc \ - util/bdfile.cc \ - util/bdstring.cc \ - udp/udplayer.cc \ - udp/udpstack.cc \ - udp/udpbitdht.cc \ - bitdht/bdconnection.cc \ - bitdht/bdfilter.cc \ - bitdht/bdaccount.cc \ - bitdht/bdquerymgr.cc \ - util/bdbloom.cc \ - bitdht/bdfriendlist.cc \ diff --git a/libbitdht/src/tests/bdbloom_makefilter.cc b/libbitdht/src/tests/bdbloom_makefilter.cc deleted file mode 100644 index ee3c6e4b8..000000000 --- a/libbitdht/src/tests/bdbloom_makefilter.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * bitdht/bdbloom_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - -#include -#include "util/bdbloom.h" -#include "bitdht/bdstddht.h" -#include - -#define N_TESTS 100 - -int main(int argc, char **argv) -{ - /* read from the file */ - if (argc < 2) - { - std::cerr << "Missing Hash File"; - std::cerr << std::endl; - } - - FILE *fd = fopen(argv[1], "r"); - if (!fd) - { - std::cerr << "Failed to Open File: " << argv[1]; - std::cerr << std::endl; - return 1; - } - - char line[1000]; - - bdBloom filter; - - int nHashes = 0; - while(fgets(line, 1000-1, fd)) - { - std::string hash = line; - std::cerr << "Read Hash: " << hash; - std::cerr << std::endl; - - filter.add(hash); - nHashes++; - } - fclose(fd); - - filter.printFilter(std::cerr); - - int bits = filter.countBits(); - int filterBits = filter.filterBits(); - std::cerr << "Filter Bits Set: " << bits; - std::cerr << std::endl; - - double possible = ((double) bits) * bits; - double max = ((double) filterBits) * filterBits; - std::cerr << "Therefore Possible Finds: " << possible << "/" << max << " = %" << 100 * possible / max; - std::cerr << std::endl; - std::cerr << "With Insertions: " << nHashes; - std::cerr << std::endl; - - std::cerr << std::endl; - std::cerr << std::endl; - - std::cerr << "Filter String: " << filter.getFilter() << std::endl; - std::cerr << std::endl; - std::cerr << std::endl; - - return 1; -} - - diff --git a/libbitdht/src/tests/bdbloom_test.cc b/libbitdht/src/tests/bdbloom_test.cc deleted file mode 100644 index d0aefb947..000000000 --- a/libbitdht/src/tests/bdbloom_test.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* - * bitdht/bdbloom_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - -#include -#include "util/bdbloom.h" -#include "bitdht/bdstddht.h" -#include - -#define N_TESTS 100 - -int main(int argc, char **argv) -{ - - /* Do this multiple times */ - int i; - - - bdBloom filter; - - std::list testIds; - std::list::iterator it; - - for(i = 0; i < N_TESTS; i++) - { - bdNodeId targetId; - bdStdRandomNodeId(&targetId); - testIds.push_back(targetId); - } - - std::cerr << "Test bdBloom Filter...." << std::endl; - for(it = testIds.begin(); it != testIds.end(); it++) - { - bdNodeId targetId = *it; - - std::cerr << "-------------------------------------------------" << std::endl; - std::cerr << "Inserting : "; - std::ostringstream str; - bdStdPrintNodeId(str, &targetId); - std::cerr << str.str(); - std::cerr << std::endl; - - filter.add(str.str()); - - filter.printFilter(std::cerr); - } - - std::string fs1 = filter.getFilter(); - /* now extract, and reinsert filter */ - bdBloom filter2; - filter2.setFilterBits(fs1); - - std::string fs2 = filter2.getFilter(); - filter2.printFilter(std::cerr); - - if (fs1 == fs2) - { - std::cerr << "SUCCESS: Filter Correctly Transferred!"; - std::cerr << std::endl; - } - else - { - std::cerr << "FAILURE: Filter Not Transferred!"; - std::cerr << std::endl; - } - - - for(it = testIds.begin(); it != testIds.end(); it++) - { - bdNodeId targetId = *it; - - std::cerr << "-------------------------------------------------" << std::endl; - std::cerr << "Testing : "; - std::cerr << std::endl; - - std::ostringstream str; - bdStdPrintNodeId(str, &targetId); - std::cerr << str.str() << std::endl; - - if (filter2.test(str.str())) - { - std::cerr << "SUCCESS: Filter Found Entry"; - std::cerr << std::endl; - } - else - { - std::cerr << "FAILURE: Filter Didn't Found Entry"; - std::cerr << std::endl; - } - } - - int bits = filter.countBits(); - int filterBits = filter.filterBits(); - std::cerr << "Filter Bits Set: " << bits; - std::cerr << std::endl; - - double possible = ((double) bits) * bits; - double max = ((double) filterBits) * filterBits; - std::cerr << "Therefore Possible Finds: " << possible << "/" << max << " = %" << 100 * possible / max; - std::cerr << std::endl; - std::cerr << "With Insertions: " << N_TESTS; - std::cerr << std::endl; - -#define FINAL_TESTS (1000000) - int found = 0; - int didnt = 0; - for(i = 0; i < FINAL_TESTS; i++) - { - if ((i != 0) && (i % 100000 == 0)) - { - std::cerr << "Run " << i << " Checks" << std::endl; - } - - bdNodeId targetId; - bdStdRandomNodeId(&targetId); - std::ostringstream str; - bdStdPrintNodeId(str, &targetId); - - if (filter2.test(str.str())) - { - found++; - } - else - { - didnt++; - } - } - - std::cerr << "Final Stats: " << FINAL_TESTS << " random checks done"; - std::cerr << std::endl; - std::cerr << "\t" << found << " " << 100.0 * ((double) found) / FINAL_TESTS << "% found"; - std::cerr << std::endl; - std::cerr << "\t" << didnt << " " << 100.0 * ((double) didnt) / FINAL_TESTS << "% didnt"; - std::cerr << std::endl; - - - - - - return 1; -} - - diff --git a/libbitdht/src/tests/bdboot.txt b/libbitdht/src/tests/bdboot.txt deleted file mode 100644 index 3a2f6b2b2..000000000 --- a/libbitdht/src/tests/bdboot.txt +++ /dev/null @@ -1,500 +0,0 @@ -50.193.28.158 36327 -88.181.96.123 11328 -99.37.188.41 29653 -88.72.55.221 12254 -76.103.79.28 36151 -78.219.65.122 18814 -50.80.44.10 60059 -82.66.32.246 39882 -89.88.138.23 50082 -93.9.151.183 41948 -60.35.23.158 12641 -93.181.45.102 62514 -41.249.53.96 52932 -82.227.12.97 46602 -89.156.177.7 29920 -178.236.129.166 56294 -46.173.64.63 44300 -86.73.179.122 59624 -209.195.101.75 44444 -76.114.41.44 13750 -188.103.108.41 1580 -74.192.244.156 23315 -91.217.90.22 58541 -27.32.169.219 57166 -175.196.134.95 6890 -99.229.202.165 36801 -119.14.195.27 60485 -112.206.13.117 41825 -87.89.253.70 52870 -203.186.173.169 22508 -122.168.241.122 16167 -113.250.99.211 3319 -87.106.249.208 4281 -97.90.151.69 54641 -81.249.29.121 7812 -24.122.0.38 5007 -79.119.57.255 48324 -84.237.250.67 60736 -72.208.178.104 46970 -93.7.211.121 35220 -82.126.138.5 31165 -98.21.67.18 56158 -174.101.153.252 38195 -70.184.208.133 1664 -173.12.200.5 5996 -5.39.78.183 7777 -212.178.8.49 61787 -81.38.140.98 37021 -189.4.28.74 28817 -90.55.204.2 38814 -183.89.101.187 63939 -175.208.45.169 32911 -124.86.6.169 14743 -58.168.9.105 36962 -89.178.158.14 54494 -86.23.51.76 44444 -111.119.227.15 26632 -68.82.46.243 31651 -91.20.211.178 57166 -89.85.171.145 32926 -75.126.109.30 15009 -88.170.61.126 32761 -82.237.40.39 39052 -80.101.24.220 17412 -95.84.208.14 9372 -109.212.31.106 4662 -80.98.106.227 9773 -67.197.115.77 33457 -212.43.36.251 20273 -129.21.122.81 32785 -109.187.235.96 49414 -93.66.62.37 59880 -81.169.151.138 42157 -67.252.30.196 41576 -77.176.247.93 7812 -178.65.138.159 52160 -178.17.18.206 8028 -96.53.93.210 56028 -80.236.120.181 14451 -37.24.108.103 2000 -95.171.138.138 42342 -88.72.55.221 37933 -89.133.71.20 14968 -96.250.108.15 45291 -86.74.221.169 36035 -111.50.223.158 16001 -46.33.251.143 11789 -159.224.9.168 57529 -74.4.200.21 45569 -77.224.214.10 7886 -91.237.165.36 55393 -71.65.115.24 60705 -180.245.74.54 10065 -89.229.5.2 1040 -178.129.19.231 53510 -76.23.105.94 47088 -76.121.226.114 47476 -108.77.112.69 51413 -24.246.67.233 55806 -95.25.123.108 17701 -142.161.104.76 16956 -90.56.162.201 53163 -62.99.25.102 22309 -116.14.209.177 59826 -213.87.123.121 20587 -83.165.11.132 9481 -122.150.77.71 6890 -77.236.180.89 24819 -84.24.96.215 6881 -98.176.147.218 62776 -79.82.130.49 20757 -78.43.137.174 10409 -74.136.3.207 43112 -95.133.243.200 7509 -71.232.162.47 10580 -209.195.104.126 6881 -178.82.162.111 36190 -175.173.87.138 16001 -72.218.218.39 6881 -84.252.26.117 10264 -46.166.104.222 50700 -86.52.88.196 52333 -188.186.142.97 22222 -63.227.112.135 40297 -110.171.80.30 50831 -62.16.187.208 60193 -41.221.124.3 12720 -122.86.88.153 5831 -46.29.209.84 6881 -83.165.111.199 63885 -80.98.162.185 51413 -176.73.16.252 34976 -24.188.113.226 42817 -88.207.42.112 51187 -85.230.147.123 58371 -50.92.78.248 41837 -94.212.214.204 52385 -86.52.180.140 6881 -94.23.198.174 51413 -212.198.182.174 18060 -78.234.129.171 33797 -125.186.188.58 6881 -94.210.26.194 16981 -109.64.246.237 23252 -86.201.102.163 51413 -75.82.14.204 37960 -172.1.72.173 31558 -86.71.169.12 32682 -37.110.130.32 61724 -61.64.143.4 59026 -202.79.36.129 58060 -88.254.55.5 53323 -84.39.4.247 6881 -31.151.104.160 51413 -201.87.14.68 50129 -24.246.26.61 51151 -101.103.182.123 36511 -95.111.64.209 10076 -89.224.149.142 25365 -46.21.211.0 18488 -49.49.27.110 13392 -60.185.230.42 64770 -188.27.125.50 51464 -212.21.6.250 64885 -114.243.240.207 53212 -89.40.161.33 29112 -14.145.16.208 18746 -186.204.50.237 17198 -124.115.12.153 2043 -47.54.129.97 47411 -109.200.116.239 17972 -213.16.182.12 25128 -217.20.73.188 35691 -182.177.193.44 10083 -80.222.111.127 35847 -79.94.175.146 41542 -74.141.87.159 55574 -95.37.172.1 11051 -77.100.104.142 54078 -80.184.19.34 35010 -94.180.203.42 6881 -37.201.168.34 48690 -95.28.111.83 11777 -84.208.143.35 50422 -188.186.45.35 17670 -90.146.80.87 26792 -122.121.191.214 47448 -31.181.0.236 6881 -99.242.88.203 21704 -176.31.109.159 32450 -62.93.99.6 28010 -95.90.236.216 41463 -95.132.145.53 17125 -222.216.168.211 50260 -182.96.166.223 4565 -111.92.19.48 46488 -88.170.61.126 7465 -216.49.152.239 59312 -108.46.182.176 23053 -59.19.172.14 58485 -159.224.26.228 13839 -184.147.15.149 64385 -41.98.81.187 10109 -90.5.180.162 18619 -81.198.134.16 6881 -66.229.51.242 51413 -82.11.60.187 55393 -62.194.99.138 18011 -178.151.1.128 20702 -84.98.19.169 36650 -84.224.105.232 13220 -68.115.149.90 49710 -37.205.70.166 35691 -85.232.130.42 62207 -83.158.230.144 55555 -83.246.216.234 49001 -92.233.249.147 55582 -41.108.95.129 12262 -83.152.236.89 58730 -115.220.147.35 7076 -78.106.26.128 26900 -84.101.22.120 55512 -89.142.253.198 10520 -151.64.241.149 51346 -95.168.12.60 63676 -213.46.147.163 38512 -85.130.52.88 25279 -90.193.28.149 22222 -79.132.25.126 59243 -111.250.206.117 25332 -99.230.144.57 34023 -112.192.66.172 1242 -58.170.183.148 16308 -110.76.72.49 13412 -80.9.174.99 58943 -84.98.243.248 13291 -91.148.138.106 17006 -173.193.242.231 25025 -173.193.242.231 37448 -84.244.2.193 27947 -78.45.13.229 19014 -173.193.242.231 22859 -119.154.190.187 43623 -213.65.128.142 55595 -78.234.140.58 8080 -92.142.60.155 6881 -189.59.195.217 64931 -122.169.6.171 35672 -178.47.227.162 33893 -46.246.67.243 64453 -46.119.144.241 49001 -174.36.55.75 18688 -94.243.89.164 57848 -209.140.255.87 20785 -62.77.128.245 51413 -91.211.177.3 20588 -81.84.65.143 12157 -68.228.230.85 20862 -108.90.48.119 51413 -24.212.131.70 48665 -85.23.70.134 53440 -217.55.204.253 12652 -31.180.94.141 35691 -109.152.61.125 57213 -92.136.246.118 13888 -178.34.229.72 30185 -94.24.202.64 30012 -123.202.103.167 33351 -109.71.206.215 6881 -89.70.19.188 26238 -59.180.22.196 20921 -189.73.206.149 55505 -46.130.66.188 60070 -183.10.152.135 47269 -41.233.124.184 13394 -112.139.59.213 12821 -89.2.143.130 18263 -217.210.76.120 30274 -178.149.61.10 19539 -96.233.255.79 50924 -124.121.88.187 63778 -119.204.207.162 30894 -103.14.61.48 53600 -46.63.62.162 10219 -77.41.141.187 6881 -83.110.90.167 42603 -61.78.82.158 29484 -85.0.20.26 6881 -94.236.128.96 50907 -99.230.119.14 1755 -108.13.168.252 62118 -84.125.19.21 42646 -74.141.87.159 55998 -86.125.209.88 62846 -37.43.117.187 40595 -95.104.110.103 47173 -76.78.36.229 36258 -97.94.141.117 63650 -49.49.90.217 14706 -94.6.23.192 39715 -46.232.228.161 5439 -186.133.30.205 15189 -46.186.48.179 61088 -31.134.17.73 32518 -98.229.16.76 13046 -89.211.153.176 63047 -95.16.10.140 12057 -46.149.41.106 49001 -178.204.78.171 28106 -94.51.214.102 6881 -178.127.223.150 23171 -203.141.138.201 42247 -95.53.43.124 19988 -66.11.189.123 16723 -178.46.157.54 54330 -85.87.178.219 23203 -83.114.210.35 51413 -178.78.33.173 49001 -95.191.57.183 28277 -111.241.72.105 63166 -190.213.94.37 13819 -114.34.93.16 6881 -80.201.144.250 16648 -217.148.57.194 52856 -46.180.187.212 20308 -59.143.213.135 36841 -115.241.104.112 54040 -58.182.18.125 11840 -202.160.16.7 58808 -78.230.94.4 63082 -188.254.157.48 40307 -78.162.174.165 24173 -88.196.203.160 47372 -182.164.124.199 48810 -121.102.203.62 20440 -219.246.57.153 16001 -2.61.38.78 25590 -99.98.96.67 13178 -125.114.50.210 1056 -90.193.128.203 61929 -94.14.5.83 58485 -37.193.160.216 57423 -58.115.35.67 11257 -182.235.129.91 16001 -186.36.145.147 42376 -128.68.147.228 6881 -200.119.228.231 17654 -88.89.110.64 26602 -115.79.234.94 36463 -80.193.158.59 49348 -78.73.114.77 11385 -90.54.174.104 20963 -218.151.52.146 16617 -46.161.143.220 49735 -188.18.80.97 6881 -37.212.44.31 10638 -89.223.99.150 49001 -65.4.130.12 50221 -186.74.22.89 45612 -95.58.93.119 28709 -209.6.69.225 56332 -85.103.248.197 27524 -174.45.1.123 6881 -118.171.185.18 19917 -87.90.247.194 39695 -213.222.142.58 28962 -69.253.233.190 44895 -88.172.121.96 30728 -222.226.45.246 26333 -82.245.33.128 25515 -178.44.235.211 19597 -121.168.129.77 60375 -121.45.206.235 23987 -217.162.186.254 39835 -83.222.112.119 58903 -178.74.53.50 22389 -61.70.254.221 62238 -119.56.48.165 16001 -93.148.114.59 12721 -88.251.154.23 17808 -188.79.87.245 15489 -46.119.165.133 58378 -76.94.95.223 25698 -88.188.193.27 26118 -123.211.1.4 27072 -101.68.107.193 25086 -95.147.47.122 26085 -123.243.64.132 35587 -186.89.157.161 15024 -174.106.96.168 56049 -109.148.234.144 60557 -89.178.224.73 28557 -85.104.92.129 10002 -99.228.252.24 37108 -61.62.254.10 32181 -2.50.255.118 36581 -176.49.163.194 23892 -90.23.214.138 63347 -119.36.38.104 62888 -109.122.3.81 6881 -86.99.199.68 25025 -84.120.63.7 11837 -188.60.197.229 16629 -89.110.207.136 13761 -213.57.37.242 44892 -75.90.96.145 31951 -99.247.185.46 36957 -76.227.224.238 24196 -217.27.215.96 6882 -213.33.236.230 65360 -77.5.35.67 43398 -83.108.63.210 61452 -24.12.46.116 23073 -173.193.242.231 36660 -71.94.186.218 10322 -109.228.185.71 6881 -175.205.72.185 59696 -200.120.153.187 57279 -1.64.32.1 11212 -89.233.243.128 33881 -89.3.35.16 8010 -219.99.6.250 54921 -79.95.171.102 11092 -126.13.14.150 17431 -58.208.74.237 6600 -114.245.149.20 9371 -78.233.157.35 40874 -84.226.253.50 6881 -69.14.60.243 61616 -50.33.142.137 52383 -188.242.78.174 33213 -71.237.6.246 41304 -41.107.85.131 10010 -89.222.164.45 39809 -88.186.107.212 42344 -195.132.158.234 22855 -82.122.102.50 25612 -76.255.133.138 31677 -24.130.61.50 28383 -98.165.83.165 3661 -99.55.140.166 50473 -75.109.50.114 25562 -87.106.187.29 20277 -24.247.183.167 2365 -82.228.100.167 42278 -109.214.57.82 1042 -77.196.18.56 22750 -66.177.205.21 8086 -82.231.237.146 9517 -176.31.248.87 6338 -2.6.66.21 45350 -79.153.101.234 11154 -24.247.179.164 8929 -71.63.225.31 21053 -83.157.77.228 7812 -108.59.72.193 2398 -88.127.44.139 15998 -64.121.118.201 61270 -90.38.76.72 4699 -67.173.33.90 33134 -88.217.36.182 2924 -2.236.14.214 55556 -109.194.233.11 6881 -178.187.47.44 53127 -126.29.214.91 42242 -41.178.247.176 24977 -37.59.34.186 41497 -82.225.11.196 38136 -195.132.158.49 61570 -78.105.105.87 42127 -94.23.204.135 30392 -178.63.84.76 51413 -78.237.111.89 45254 -76.189.121.236 31548 -24.85.183.150 9646 -88.181.149.119 5018 -126.130.125.117 24435 -65.15.247.19 51319 -176.31.109.159 24586 -176.31.127.140 44137 -89.93.149.195 57218 -88.165.34.61 51449 -188.242.97.188 35390 -107.15.22.183 10392 -24.211.20.89 62868 -74.108.4.175 17391 -80.185.95.18 18365 -146.247.80.210 38204 -27.4.216.128 57962 -88.238.170.69 26026 -74.215.38.97 50596 -87.89.75.85 42176 -115.188.217.116 62348 -98.250.89.141 13038 -93.11.175.201 41027 -174.109.14.220 51413 -114.79.170.114 27462 -84.22.157.13 28498 -180.183.210.31 21257 -42.113.246.104 10775 diff --git a/libbitdht/src/tests/bdmetric_test.cc b/libbitdht/src/tests/bdmetric_test.cc deleted file mode 100644 index d0865794e..000000000 --- a/libbitdht/src/tests/bdmetric_test.cc +++ /dev/null @@ -1,264 +0,0 @@ -/* - * bitdht/bdmetric_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" -#include -#include - - -#include "utest.h" - -bool test_metric_explicit(); -bool test_metric_random(); - -INITTEST(); - -int main(int argc, char **argv) -{ - std::cerr << "libbitdht: " << argv[0] << std::endl; - - test_metric_explicit(); - - FINALREPORT("libbitdht: Metric Tests"); - return TESTRESULT(); -} - -bool test_metric_explicit() -{ - std::cerr << "test_metric_explicit:" << std::endl; - -#define NUM_IDS 6 - - /* create some ids */ - bdId id[NUM_IDS]; - int i, j; - - /* create a set of known ids ... and - * check the metrics are what we expect. - */ - - for(i = 0; i < NUM_IDS; i++) - { - bdZeroNodeId(&(id[i].id)); - } - - /* test the zero node works */ - for(i = 0; i < NUM_IDS; i++) - { - for(j = 0; j < BITDHT_KEY_LEN; j++) - { - CHECK(id[i].id.data[j] == 0); - } - } - - for(i = 0; i < NUM_IDS; i++) - { - for(j = i; j < NUM_IDS; j++) - { - id[j].id.data[BITDHT_KEY_LEN - i - 1] = 1; - } - } - - for(i = 0; i < NUM_IDS; i++) - { - fprintf(stderr, "id[%d]:", i+1); - bdStdPrintId(std::cerr,&(id[i])); - fprintf(stderr, "\n"); - } - - /* now do the sums */ - bdMetric met; - bdMetric met2; - int bdist = 0; - - for(i = 0; i < 6; i++) - { - for(j = i+1; j < 6; j++) - { - bdStdDistance(&(id[i].id), &(id[j].id), &met); - - fprintf(stderr, "%d^%d:", i, j); - bdStdPrintNodeId(std::cerr,&met); - fprintf(stderr, "\n"); - - bdist = bdStdBucketDistance(&met); - fprintf(stderr, " bucket: %d\n", bdist); - } - } - -#if 0 - int c1 = met < met2; - int c2 = met2 < met; - - fprintf(stderr, "1^2<1^3? : %d 1^3<1^2?: %d\n", c1, c2); -#endif - - - REPORT("Test Byte Manipulation"); - //FAILED("Couldn't Bind to socket"); - - return 1; -} - - - -bool test_metric_random() -{ - std::cerr << "test_metric_random:" << std::endl; - - /* create some ids */ - bdId id1; - bdId id2; - bdId id3; - bdId id4; - bdId id5; - bdId id6; - - bdStdRandomId(&id1); - bdStdRandomId(&id2); - bdStdRandomId(&id3); - bdStdRandomId(&id4); - bdStdRandomId(&id5); - bdStdRandomId(&id6); - - fprintf(stderr, "id1:"); - bdStdPrintId(std::cerr,&id1); - fprintf(stderr, "\n"); - - fprintf(stderr, "id2:"); - bdStdPrintId(std::cerr,&id2); - fprintf(stderr, "\n"); - - fprintf(stderr, "id3:"); - bdStdPrintId(std::cerr,&id3); - fprintf(stderr, "\n"); - - fprintf(stderr, "id4:"); - bdStdPrintId(std::cerr,&id4); - fprintf(stderr, "\n"); - - fprintf(stderr, "id5:"); - bdStdPrintId(std::cerr,&id5); - fprintf(stderr, "\n"); - - fprintf(stderr, "id6:"); - bdStdPrintId(std::cerr,&id6); - fprintf(stderr, "\n"); - - /* now do the sums */ - bdMetric met; - bdMetric met2; - int bdist = 0; - bdStdDistance(&(id1.id), &(id2.id), &met); - - fprintf(stderr, "1^2:"); - bdStdPrintNodeId(std::cerr,&met); - fprintf(stderr, "\n"); - bdist = bdStdBucketDistance(&met); - fprintf(stderr, " bucket: %d\n", bdist); - - bdStdDistance(&(id1.id), &(id3.id), &met2); - bdist = bdStdBucketDistance(&met2); - - fprintf(stderr, "1^3:"); - bdStdPrintNodeId(std::cerr,&met2); - fprintf(stderr, "\n"); - fprintf(stderr, " bucket: %d\n", bdist); - - int c1 = met < met2; - int c2 = met2 < met; - - fprintf(stderr, "1^2<1^3? : %d 1^3<1^2?: %d\n", c1, c2); - - - bdStdDistance(&(id1.id), &(id4.id), &met2); - bdist = bdStdBucketDistance(&met2); - - fprintf(stderr, "1^4:"); - bdStdPrintNodeId(std::cerr,&met2); - fprintf(stderr, "\n"); - fprintf(stderr, " bucket: %d\n", bdist); - - c1 = met < met2; - c2 = met2 < met; - - fprintf(stderr, "1^2<1^4? : %d 1^4<1^2?: %d\n", c1, c2); - - bdStdDistance(&(id1.id), &(id5.id), &met); - bdist = bdStdBucketDistance(&met); - - fprintf(stderr, "1^5:"); - bdStdPrintNodeId(std::cerr,&met); - fprintf(stderr, "\n"); - fprintf(stderr, " bucket: %d\n", bdist); - - bdStdDistance(&(id1.id), &(id6.id), &met); - bdist = bdStdBucketDistance(&met); - - fprintf(stderr, "1^6:"); - bdStdPrintNodeId(std::cerr,&met); - fprintf(stderr, "\n"); - fprintf(stderr, " bucket: %d\n", bdist); - - bdStdDistance(&(id2.id), &(id3.id), &met); - bdist = bdStdBucketDistance(&met); - - fprintf(stderr, "2^3:"); - bdStdPrintNodeId(std::cerr,&met); - fprintf(stderr, "\n"); - fprintf(stderr, " bucket: %d\n", bdist); - - - fprintf(stderr, "id1:"); - bdStdPrintId(std::cerr,&id1); - fprintf(stderr, "\n"); - - fprintf(stderr, "id2:"); - bdStdPrintId(std::cerr,&id2); - fprintf(stderr, "\n"); - - fprintf(stderr, "id3:"); - bdStdPrintId(std::cerr,&id3); - fprintf(stderr, "\n"); - - fprintf(stderr, "id4:"); - bdStdPrintId(std::cerr,&id4); - fprintf(stderr, "\n"); - - fprintf(stderr, "id5:"); - bdStdPrintId(std::cerr,&id5); - fprintf(stderr, "\n"); - - fprintf(stderr, "id6:"); - bdStdPrintId(std::cerr,&id6); - fprintf(stderr, "\n"); - - - return 1; -} - - diff --git a/libbitdht/src/tests/bdmgr_multitest.cc b/libbitdht/src/tests/bdmgr_multitest.cc deleted file mode 100644 index cfed76862..000000000 --- a/libbitdht/src/tests/bdmgr_multitest.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * bitdht/bdmgr_multitest.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdmanager.h" -#include "bitdht/bdstddht.h" -#include "udp/udplayer.h" -#include "util/bdrandom.h" - -#include - -/********************************************************************************** - * tests of multi bdnodes all connected together. - * in these cases, the networking step is shortcut and the ip addresses ignored. - * instead the port number is used as an index to peers. - * - * test1() - * Small cross seeding, and static list of peers. - * Set it going - and see what happens. - */ - -std::map nodes; -std::map addrIdx; - -int main(int argc, char **argv) -{ - time_t sim_time = 600; - time_t starttime = time(NULL); - int n_nodes = 1000; - std::map::iterator it; - std::map::iterator nit; - std::map::iterator ait; - - int i, j; - - bdDhtFunctions *fns = new bdStdDht(); - - std::cerr << "bdmgr_multitest() Setting up Nodes" << std::endl; - /* setup nodes */ - for(i = 0; i < n_nodes; i++) - { - bdId id; - - bdStdRandomId(&id); - - //id.addr.sin_port = htons(i); - //((uint32_t *) (id.id.data))[0] = i * 16 * 16; /* force this so the sort order is maintained! */ - std::cerr << "bdmgr_multitest() Id: "; - fns->bdPrintId(std::cerr, &id); - std::cerr << std::endl; - - bdNodeManager *mgr = new bdNodeManager(&(id.id), "bdTEST", "", fns); - - /* Store in nodes */ - nodes[id] = mgr; - /* Store in indices */ - addrIdx[id.addr] = id; - - } - - std::cerr << "bdmgr_multitest() Cross Seeding" << std::endl; - /* do a little cross seeding */ - for(nit = nodes.begin(); nit != nodes.end(); nit++) - { - for(j = 0; j < 2; j++) - { - int peeridx = bdRandom::random_u32() % n_nodes; - for(i = 0, it = nodes.begin(); - (i < peeridx) && (it != nodes.end()); i++, it++) - { - /* empty */ - } - if (it != nodes.end()) - { - nit->second->addPotentialPeer((bdId *) &(it->first), NULL); - } - } - } - - /* ready to run */ - - std::cerr << "bdmgr_multitest() Simulation Time....." << std::endl; - i = 0; - while(time(NULL) < starttime + sim_time) - { - i++; - std::cerr << "bdmgr_multitest() Iteration: " << i << std::endl; - - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* extract messages to go -> and deliver */ -#define MAX_MSG_SIZE 10240 - struct sockaddr_in addr; - char data[MAX_MSG_SIZE]; - int len = MAX_MSG_SIZE; - - while(it->second->outgoingMsg(&addr, data, &len)) - { - std::cerr << "bdmgr_multitest() Msg from Peer: " << j; - - /* find the peer */ - ait = addrIdx.find(addr); - nit = nodes.end(); - if (ait != addrIdx.end()) - { - nit = nodes.find(ait->second); - std::cerr << " For: "; - fns->bdPrintId(std::cerr, &(nit->first)); - std::cerr << std::endl; - } - else - { - std::cerr << " For Unknown Destination"; - std::cerr << std::endl; - - } - - if (nit != nodes.end()) - { - /* set from address */ - nit->second->incomingMsg( (sockaddr_in *) &(it->first.addr), data, len); - } - /* reset message size */ - len = MAX_MSG_SIZE; - } - } - - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* tick */ - std::cerr << "bdmgr_multitest() Ticking peer: " << j << std::endl; - it->second->iteration(); - } - - - /* have a rest */ - sleep(1); - } - - std::cerr << "bdmgr_multitest() Displying States"<< std::endl; - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* tick */ - std::cerr << "bdmgr_multitest() Peer State: " << j << std::endl; - it->second->printState(); - } - -} - - - - - - - - - - - - - - - - diff --git a/libbitdht/src/tests/bdmidids_test.cc b/libbitdht/src/tests/bdmidids_test.cc deleted file mode 100644 index de52975cb..000000000 --- a/libbitdht/src/tests/bdmidids_test.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * bitdht/bdmidids_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" -#include - -int main(int argc, char **argv) -{ - - /* Do this multiple times */ - int i, j; - - std::cerr << "Test Mid Peer Intersection....." << std::endl; - for(i = 0; i < 10; i++) - { - bdNodeId targetId; - bdNodeId peerId; - - bdStdRandomNodeId(&targetId); - bdStdRandomNodeId(&peerId); - - std::cerr << "-------------------------------------------------" << std::endl; - - for(j = 0; j < 10; j++) - { - - bdNodeId midId; - - bdStdRandomMidId(&targetId, &peerId, &midId); - - bdMetric TPmetric; - bdMetric TMmetric; - bdMetric PMmetric; - - bdStdDistance(&targetId, &peerId, &TPmetric); - bdStdDistance(&targetId, &midId, &TMmetric); - bdStdDistance(&peerId, &midId, &PMmetric); - - int TPdist = bdStdBucketDistance(&TPmetric); - int TMdist = bdStdBucketDistance(&TMmetric); - int PMdist = bdStdBucketDistance(&PMmetric); - - std::cerr << "Target: "; - bdStdPrintNodeId(std::cerr,&targetId); - std::cerr << " Peer: "; - bdStdPrintNodeId(std::cerr,&peerId); - std::cerr << std::endl; - - std::cerr << "\tTarget ^ Peer: "; - bdStdPrintNodeId(std::cerr,&TPmetric); - std::cerr << " Bucket: " << TPdist; - std::cerr << std::endl; - - std::cerr << "\tTarget ^ Mid: "; - bdStdPrintNodeId(std::cerr,&TMmetric); - std::cerr << " Bucket: " << TMdist; - std::cerr << std::endl; - - std::cerr << "\tPeer ^ Mid: "; - bdStdPrintNodeId(std::cerr,&PMmetric); - std::cerr << " Bucket: " << PMdist; - std::cerr << std::endl; - - /* now save mid to peer... and repeat */ - peerId = midId; - } - } - - return 1; -} - - diff --git a/libbitdht/src/tests/bdmsgs_test.cc b/libbitdht/src/tests/bdmsgs_test.cc deleted file mode 100644 index cdfaed7d2..000000000 --- a/libbitdht/src/tests/bdmsgs_test.cc +++ /dev/null @@ -1,102 +0,0 @@ - -/* - * bitdht/bdmsgs_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdmsgs.h" -#include "bitdht/bdstddht.h" -#include - -/******************************************************************* - * Test of bencode message creation functions in bdmsgs.cc - * - * Create a couple of each type. - */ - -#define MAX_MESSAGE_LEN 10240 - -int main(int argc, char **argv) -{ - /***** create messages *****/ - char msg[MAX_MESSAGE_LEN]; - int avail = MAX_MESSAGE_LEN -1; - - bdToken tid; - bdToken vid; - bdToken token; - - - bdNodeId ownId; - bdNodeId peerId; - bdNodeId target; - bdNodeId info_hash; - - bdStdRandomNodeId(&ownId); - bdStdRandomNodeId(&peerId); - bdStdRandomNodeId(&target); - bdStdRandomNodeId(&info_hash); - - std::list nodes; - std::list values; - - /* setup tokens */ - strncpy((char*)tid.data, "tid", 4); - strncpy((char*)vid.data, "RS50", 5); - strncpy((char*)token.data, "ToKEn", 6); - - tid.len = 3; - vid.len = 4; - token.len = 5; - - /* setup lists */ - for(int i = 0; i < 8; i++) - { - bdId rndId; - bdStdRandomId(&rndId); - - nodes.push_back(rndId); - values.push_back("values"); - } - - uint32_t port = 1234; - - bitdht_create_ping_msg(&tid, &ownId, msg, avail); - bitdht_response_ping_msg(&tid, &ownId, &vid, msg, avail); - - bitdht_find_node_msg(&tid, &ownId, &target, msg, avail); - bitdht_resp_node_msg(&tid, &ownId, nodes, msg, avail); - - bitdht_get_peers_msg(&tid, &ownId, &info_hash, msg, avail); - bitdht_peers_reply_hash_msg(&tid, &ownId, &token, values, msg, avail); - bitdht_peers_reply_closest_msg(&tid, &ownId, &token, nodes, msg, avail); - - bitdht_announce_peers_msg(&tid, &ownId, &info_hash, port, &token, msg, avail); - bitdht_reply_announce_msg(&tid, &ownId, msg, avail); - - - return 1; -} - - diff --git a/libbitdht/src/tests/bdnode_multitest1.cc b/libbitdht/src/tests/bdnode_multitest1.cc deleted file mode 100644 index 5e1a6ebca..000000000 --- a/libbitdht/src/tests/bdnode_multitest1.cc +++ /dev/null @@ -1,185 +0,0 @@ -/* - * bitdht/bdnode_multitest1.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdnode.h" -#include "bitdht/bdstddht.h" -#include "util/bdrandom.h" - -#include - -/********************************************************************************** - * tests of multi bdnodes all connected together. - * in these cases, the networking step is shortcut and the ip addresses ignored. - * instead the port number is used as an index to peers. - * - * test1() - * Small cross seeding, and static list of peers. - * Set it going - and see what happens. - */ - -std::map nodes; -std::map portIdx; - -int main(int argc, char **argv) -{ - time_t sim_time = 60; - time_t starttime = time(NULL); - int n_nodes = 10; - std::map::iterator it; - std::map::iterator nit; - std::map::iterator pit; - - int i, j; - - bdDhtFunctions *fns = new bdStdDht(); - - std::cerr << "bdnode_multitest1() Setting up Nodes" << std::endl; - /* setup nodes */ - for(i = 0; i < n_nodes; i++) - { - bdId id; - - bdStdRandomId(&id); - - id.addr.sin_port = htons(i); - ((uint32_t *) (id.id.data))[0] = i * 16 * 16; /* force this so the sort order is maintained! */ - std::cerr << "bdnode_multitest1() Id: "; - fns->bdPrintId(std::cerr, &id); - std::cerr << std::endl; - - bdNode *node = new bdNode(&(id.id), "bdTEST", "", fns); - - /* Store in nodes */ - nodes[id] = node; - /* Store in indices */ - portIdx[i] = id; - - } - - std::cerr << "bdnode_multitest1() Cross Seeding" << std::endl; - /* do a little cross seeding */ - for(i = 0; i < n_nodes; i++) - { - bdId nid = portIdx[i]; - bdNode *node = nodes[nid]; - - for(j = 0; j < 5; j++) - { - int peeridx = bdRandom::random_u32() % n_nodes; - - bdId pid = portIdx[peeridx]; - node->addPotentialPeer(&pid, NULL); - } - } - - /* ready to run */ - - std::cerr << "bdnode_multitest1() Simulation Time....." << std::endl; - i = 0; - while(time(NULL) < starttime + sim_time) - { - i++; - std::cerr << "bdnode_multitest1() Iteration: " << i << std::endl; - - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* extract messages to go -> and deliver */ -#define MAX_MSG_SIZE 10240 - struct sockaddr_in addr; - char data[MAX_MSG_SIZE]; - int len = MAX_MSG_SIZE; - - while(it->second->outgoingMsg(&addr, data, &len)) - { - std::cerr << "bdnode_multitest1() Msg from Peer: " << j; - - /* find the peer */ - int peeridx = htons(addr.sin_port); - pit = portIdx.find(peeridx); - nit = nodes.end(); - if (pit != portIdx.end()) - { - nit = nodes.find(pit->second); - std::cerr << " For: "; - fns->bdPrintId(std::cerr, &(nit->first)); - std::cerr << std::endl; - } - else - { - std::cerr << " For Unknown Destination"; - std::cerr << std::endl; - - } - - if (nit != nodes.end()) - { - /* set from address */ - nit->second->incomingMsg( (sockaddr_in *) &(it->first.addr), data, len); - } - /* reset message size */ - len = MAX_MSG_SIZE; - } - } - - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* tick */ - std::cerr << "bdnode_multitest1() Ticking peer: " << j << std::endl; - it->second->iteration(); - } - - if (i % 5 == 0) - { - std::cerr << "bdnode_multitest1() Displying States"<< std::endl; - for(it = nodes.begin(), j = 0; it != nodes.end(); it++, j++) - { - /* tick */ - std::cerr << "bdnode_multitest1() Peer State: " << j << std::endl; - it->second->printState(); - } - } - - - /* have a rest */ - sleep(1); - } -} - - - - - - - - - - - - - - - - diff --git a/libbitdht/src/tests/bdnode_test.cc b/libbitdht/src/tests/bdnode_test.cc deleted file mode 100644 index 848a27e7c..000000000 --- a/libbitdht/src/tests/bdnode_test.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * bitdht/bdnode_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdquery.h" -#include "bitdht/bdnode.h" - -#define N_PEERS_TO_ADD_INIT 10 -#define N_PEERS_TO_ADD 11 -#define N_PEERS_TO_START 10 -#define N_PEERS_TO_PRINT 1 -#define N_QUERIES 2 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdDhtFunctions *fns = new bdStdDht(); - - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - - bdNode node(&ownId, "bdTEST","./dht.log", fns); - - int i = 0; - for (i = 0; i < N_PEERS_TO_ADD_INIT; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - - node.addPeer(&tmpId, 0); - } - - node.printState(); - -#if 0 - for(i = 0; i < N_QUERIES; i++) - { - /* create a query */ - bdNodeId queryId; - bdStdRandomNodeId(&queryId); - - node.addQuery(&queryId, 0); - } -#endif - - node.printState(); - - for (i = 0; i < N_PEERS_TO_ADD; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - - node.addPeer(&tmpId, 0); - - if (i % N_PEERS_TO_PRINT == 0) - { - node.printState(); - node.iteration(); - sleep(5); - } - } - - return 1; -} - - diff --git a/libbitdht/src/tests/bdnode_test2.cc b/libbitdht/src/tests/bdnode_test2.cc deleted file mode 100644 index 1e4b16b68..000000000 --- a/libbitdht/src/tests/bdnode_test2.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* - * bitdht/bdnode_test2.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdquery.h" -#include "bitdht/bdnode.h" - -#define N_PEERS_TO_ADD_INIT 10 -#define N_PEERS_TO_ADD 11 -#define N_PEERS_TO_START 10 -#define N_PEERS_TO_PRINT 1 -#define N_QUERIES 2 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - bdDhtFunctions *fns = new bdStdDht(); - - bdNode node(&ownId, "bdTEST", "./dht.log", fns); - - while(1) - { - node.iteration(); - sleep(1); - } - - return 1; -} - - diff --git a/libbitdht/src/tests/bdquery_test.cc b/libbitdht/src/tests/bdquery_test.cc deleted file mode 100644 index b4c8e980b..000000000 --- a/libbitdht/src/tests/bdquery_test.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * bitdht/bdquery_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdquery.h" - -#define N_PEERS_TO_ADD 10000 -#define N_PEERS_TO_PRINT 1000 -#define N_PEERS_TO_START 10 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - - bdDhtFunctions *fns = new bdStdDht(); - - bdSpace space(&ownId, fns); - int i = 0; - for (i = 0; i < N_PEERS_TO_ADD; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - - space.add_peer(&tmpId, 0); - } - - space.printDHT(); - - /* create a query */ - bdId queryId; - bdStdRandomId(&queryId); - - - - std::list startList; - std::multimap nearest; - std::multimap::iterator it; - - space.find_nearest_nodes(&(queryId.id), N_PEERS_TO_START, nearest); - - for(it = nearest.begin(); it != nearest.end(); it++) - { - startList.push_back(it->second); - } - - bdQuery query(&(queryId.id), startList, BITDHT_QFLAGS_DISGUISE, fns); - - /* */ - - query.printQuery(); - - - return 1; -} - - diff --git a/libbitdht/src/tests/bdspace_test.cc b/libbitdht/src/tests/bdspace_test.cc deleted file mode 100644 index ead78c683..000000000 --- a/libbitdht/src/tests/bdspace_test.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * bitdht/bdspace_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" - -#define N_PEERS_TO_ADD 10000 -#define N_PEERS_TO_PRINT 1000 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - bdDhtFunctions *fns = new bdStdDht(); - - bdSpace space(&ownId, fns); - int i = 0; - for (i = 0; i < N_PEERS_TO_ADD; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - - space.add_peer(&tmpId, 0); - - if (i % N_PEERS_TO_PRINT == 0) - { - space.printDHT(); - } - } - space.printDHT(); - - return 1; -} - - diff --git a/libbitdht/src/tests/bdspace_test2.cc b/libbitdht/src/tests/bdspace_test2.cc deleted file mode 100644 index ca9e7f024..000000000 --- a/libbitdht/src/tests/bdspace_test2.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * bitdht/bdspace_test2.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdstddht.h" - -#define N_PEERS_TO_ADD 10000 -#define N_PEERS_TO_TEST 100 -#define N_PEERS_TO_FIND 10 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdNodeId ownId; - bdStdRandomNodeId(&ownId); - bdDhtFunctions *fns = new bdStdDht(); - - bdSpace space(&ownId, fns); - int i = 0; - for (i = 0; i < N_PEERS_TO_ADD; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - space.add_peer(&tmpId, 0); - } - - space.printDHT(); - - - /* now generate random id's and test closeness */ - for(i = 0; i < N_PEERS_TO_TEST; i++) - { - bdId tmpId; - bdStdRandomId(&tmpId); - std::multimap list2; - - space.find_nearest_nodes(&(tmpId.id), N_PEERS_TO_FIND, list2); - } - - return 1; -} - - diff --git a/libbitdht/src/tests/bdstore_test.cc b/libbitdht/src/tests/bdstore_test.cc deleted file mode 100644 index c1207def5..000000000 --- a/libbitdht/src/tests/bdstore_test.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* - * bitdht/bdstore_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdstore.h" -#include "bitdht/bdstddht.h" - -#include -#include - -int main(int argc, char **argv) -{ - /* load store */ - if (argc < 2) - { - fprintf(stderr, "Missing Store File\n"); - exit(1); - } - - bdDhtFunctions *fns = new bdStdDht(); - bdStore store(argv[1], fns); - return 1; -} - - diff --git a/libbitdht/src/tests/bdudp_test.cc b/libbitdht/src/tests/bdudp_test.cc deleted file mode 100644 index 4b9d581bd..000000000 --- a/libbitdht/src/tests/bdudp_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -/* - * bitdht/bdudp_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bdpeer.h" -#include "bitdht/bdquery.h" -#include "udp/udpbitdht.h" - -#define N_PEERS_TO_ADD 10000 -#define N_PEERS_TO_PRINT 1000 -#define N_PEERS_TO_START 10 - -int main(int argc, char **argv) -{ - - /* create some ids */ - bdId ownId; - bdRandomId(&ownId); - - - struct sockaddr_in local; - local.sin_addr.s_addr = 0; - local.sin_port = htons(7812); - std::string bootstrapfile = "dht.log"; - - bdId bid; - - bid.addr = local; - bid.id = ownId.id; - - UdpBitDht ubd(local, 0, &bid, bootstrapfile); - - - - while(1) - { - ubd.tick(); - sleep(1); - } - - return 1; -} - - diff --git a/libbitdht/src/tests/bencode_test.cc b/libbitdht/src/tests/bencode_test.cc deleted file mode 100644 index 8d35c0678..000000000 --- a/libbitdht/src/tests/bencode_test.cc +++ /dev/null @@ -1,182 +0,0 @@ -/* - * bitdht/bencode_test.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "bitdht/bencode.h" -#include - -int main(int argc, char **argv) -{ - - char msg[100]; - - msg[0] = 'd'; - msg[1] = '1'; - msg[2] = ':'; - msg[3] = 't'; - msg[4] = 'L'; - msg[5] = 'b'; - msg[6] = 'U'; - msg[7] = 0xd9; - msg[8] = 0xfa; - msg[9] = 0xff; - msg[10] = 0xff; - msg[11] = 0xff; - msg[12] = 0xff; - msg[13] = '\n'; - msg[14] = 'H'; - msg[15] = '#'; - msg[16] = '#'; - msg[17] = '#'; - msg[18] = '#'; - msg[19] = '#'; - msg[20] = '#'; - msg[21] = '#'; - - be_node *n = be_decoden(msg, 16); - - if (n) - { - be_dump(n); - be_free(n); - } - else - { - fprintf(stderr, "didn't crash!\n"); - } - - msg[0] = 'd'; - msg[1] = '1'; - msg[2] = ':'; - msg[3] = 'a'; - msg[4] = 'L'; - msg[5] = 0x8d; - msg[6] = 0xd6; - msg[7] = '\r'; - msg[8] = 0x9d; - msg[9] = ';'; - msg[10] = 0xff; - msg[11] = 0xff; - msg[12] = 0xff; - msg[13] = 0xff; - msg[14] = 'H'; - msg[15] = '#'; - msg[16] = '#'; - msg[17] = '#'; - msg[18] = '#'; - msg[19] = '#'; - msg[20] = '#'; - msg[21] = '#'; - - n = be_decoden(msg, 14); - - if (n) - { - be_dump(n); - be_free(n); - } - else - { - fprintf(stderr, "didn't crash!\n"); - } - - msg[0] = 'd'; - msg[1] = '1'; - msg[2] = ':'; - msg[3] = 't'; - msg[4] = '4'; - msg[5] = ':'; - msg[6] = 'a'; - msg[7] = 'b'; - msg[8] = 'c'; - msg[9] = 'd'; - msg[10] = '1'; - msg[11] = ':'; - msg[12] = 'y'; - msg[13] = '1'; - msg[14] = ':'; - msg[15] = 'r'; - msg[16] = '1'; - msg[17] = ':'; - msg[18] = 'r'; - msg[19] = 'd'; - msg[20] = '2'; - msg[21] = ':'; - msg[22] = 'i'; - msg[23] = 'd'; - msg[24] = '2'; - msg[25] = '0'; - msg[26] = ':'; - msg[27] = '1'; - msg[28] = '2'; - msg[29] = '3'; - msg[30] = '4'; - msg[31] = '5'; - msg[32] = '6'; - msg[33] = '7'; - msg[34] = '8'; - msg[35] = '9'; - msg[36] = '0'; - msg[37] = 'a'; - msg[38] = 'b'; - msg[39] = 'c'; - msg[40] = 'd'; - msg[41] = 'e'; - msg[42] = 'f'; - msg[43] = 'g'; - msg[44] = 'h'; - msg[45] = 'i'; - msg[46] = '.'; - msg[47] = '5'; - msg[48] = ':'; - msg[49] = 'n'; - msg[50] = 'o'; - msg[51] = 'd'; - msg[52] = 'e'; - msg[53] = 's'; - msg[54] = '2'; - msg[55] = '0'; - msg[56] = '8'; - msg[57] = ':'; - msg[58] = '\0'; - msg[59] = '\0'; - msg[60] = '\0'; - - n = be_decoden(msg, 58); - - if (n) - { - be_dump(n); - be_free(n); - } - else - { - fprintf(stderr, "didn't crash!\n"); - } - - return 1; -} - - diff --git a/libbitdht/src/tests/scripts/checks.mk b/libbitdht/src/tests/scripts/checks.mk deleted file mode 100644 index dfccbdedf..000000000 --- a/libbitdht/src/tests/scripts/checks.mk +++ /dev/null @@ -1,19 +0,0 @@ -#Basic checks - -ifndef TEST_TOP_DIR -dummy: - echo "TEST_TOP_DIR is not defined in your makefile" -endif - -ifneq ($(OS),Linux) - ifneq ($(OS),MacOSX) - ifndef PTHREADS_DIR -dummy: - echo "you must define PTHREADS_DIR before you can compile" - - endif - endif -endif - - - diff --git a/libbitdht/src/tests/scripts/config-cygwin.mk b/libbitdht/src/tests/scripts/config-cygwin.mk deleted file mode 100644 index ec4518f68..000000000 --- a/libbitdht/src/tests/scripts/config-cygwin.mk +++ /dev/null @@ -1,118 +0,0 @@ -ifneq ($(OS),Cygwin) -dummy: - echo "ERROR Cygwin configuration file included, but (OS != Cygwin) - -endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -SRC_ROOT=../../../.. - -PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads/pthreads.2 - -################### - -#ALT_SRC_ROOT=/cygdrive/c/RetroShareBuild/src -#SRC_ROOT=/cygdrive/c/RetroShareBuild/src - -#PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads-w32-2-8-0-release - -################### - -ZLIB_DIR=$(ALT_SRC_ROOT)/zlib-1.2.3 - -SSL_DIR=$(SRC_ROOT)/openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -ifdef PQI_USE_XPGP - INCLUDE += -I $(SSL_DIR)/include -endif - -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -RSCFLAGS = -Wall -g $(INCLUDE) - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -WININC += -DPTW32_STATIC_LIB -WININC += -mno-cygwin -mwindows -fno-exceptions -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(PTHREADS_DIR) $(WININC) -CFLAGS += -I$(ZLIB_DIR) - -LIBS = -L$(LIBDIR) -lretroshare -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) -endif - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -RSCFLAGS += $(WININC) - - diff --git a/libbitdht/src/tests/scripts/config-linux.mk b/libbitdht/src/tests/scripts/config-linux.mk deleted file mode 100644 index 182f9c39a..000000000 --- a/libbitdht/src/tests/scripts/config-linux.mk +++ /dev/null @@ -1,41 +0,0 @@ - -ifneq ($(OS),Linux) -dummy: - echo "ERROR Linux configuration file included, but (OS != Linux) - -endif - -############ LINUX CONFIGURATION ######################## - -include $(TEST_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(LIB_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(LIB_TOP_DIR) -CFLAGS = -Wall -g $(INCLUDE) -CFLAGS += ${DEFINES} -D BE_DEBUG - -######################################################################### -# OS Compile Options -######################################################################### - -######################################################################### -# OS specific Linking. -######################################################################### - -LIBS = -L$(LIBDIR) -lbitdht -LIBS += -lpthread -#LIBS += $(XLIB) -ldl -lz -#LIBS += -lupnp -#LIBS += -lgpgme -# -#RSLIBS = $(LIBS) - - diff --git a/libbitdht/src/tests/scripts/config-macosx.mk b/libbitdht/src/tests/scripts/config-macosx.mk deleted file mode 100644 index ecf95733d..000000000 --- a/libbitdht/src/tests/scripts/config-macosx.mk +++ /dev/null @@ -1,81 +0,0 @@ - -ifneq ($(OS),MacOSX) -dummy: - echo "ERROR MacOSX configuration file included, but (OS != MacOSX) - -endif - -############ MACOSX CONFIGURATION ######################## - - -# FLAGS to decide if we want i386 Build or ppc Build -# -# - -# MAC_I386_BUILD = 1 -# MAC_PPC_BUILD = 1 - -MAC_I386_BUILD = 1 -#MAC_PPC_BUILD = 1 - -ifndef MAC_I386_BUILD - MAC_PPC_BUILD = 1 -endif - -include $(TEST_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm - -RANLIB = ranlib - -# Dummy ranlib -> can't do it until afterwards with universal binaries. -# RANLIB = ls -l - -LIBDIR = $(LIB_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -OPT_DIR = /opt/local -OPT_INCLUDE = $(OPT_DIR)/include -OPT_LIBS = $(OPT_DIR)/lib - -INCLUDE = -I $(LIB_TOP_DIR) -#-I $(OPT_INCLUDE) -#CFLAGS = -Wall -O3 -CFLAGS = -Wall -g - -# Flags for architecture builds. -ifdef MAC_I386_BUILD - CFLAGS += -arch i386 -endif - -ifdef MAC_PPC_BUILD - CFLAGS += -arch ppc -endif - -CFLAGS += $(INCLUDE) - -# This Line is for Universal BUILD for 10.4 + 10.5 -# (but unlikely to work unless Qt Libraries are build properly) -#CFLAGS += -isysroot /Developer/SDKs/MacOSX10.5.sdk - -######################################################################### -# OS Compile Options -######################################################################### - -######################################################################### -# OS specific Linking. -######################################################################### - -#LIBS = -Wl,-search_paths_first - -# for Univeral BUILD -# LIBS += -arch ppc -arch i386 -# LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 - -#LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk -LIBS += -L$(LIBDIR) -lbitdht - - diff --git a/libbitdht/src/tests/scripts/config-mingw.mk b/libbitdht/src/tests/scripts/config-mingw.mk deleted file mode 100644 index c0040ac4e..000000000 --- a/libbitdht/src/tests/scripts/config-mingw.mk +++ /dev/null @@ -1,138 +0,0 @@ -#ifneq ($(OS),"Win ") -#dummy: -# echo "ERROR OS = $(OS)" -# echo "ERROR MinGW configuration file included, but (OS != Win) -# -#endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -#PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -SRC_ROOT_PKG=/home/Mark/prog/retroshare/package/rs-win-v0.5.0/src -SRC_ROOT_GPG=/local - -#ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -#SRC_ROOT=../../../.. - -PTHREADS_DIR=$(SRC_ROOT_PKG)/pthreads-w32-2-8-0/Pre-built.2 -ZLIB_DIR=$(SRC_ROOT_PKG)/zlib-1.2.3 -SSL_DIR=$(SRC_ROOT_PKG)/openssl-tmp -UPNPC_DIR=$(SRC_ROOT_PKG)/miniupnpc-1.3 - -########################################################################### - -#### Enable this section for compiling with MSYS/MINGW compile -#SRC_ROOT=/home/linux - -#SSL_DIR=$(SRC_ROOT)/OpenSSL -#GPGME_DIR=$(SRC_ROOT)/gpgme-1.1.8 -#GPG_ERROR_DIR=$(SRC_ROOT)/libgpg-error-1.7 - -#ZLIB_DIR=$(SRC_ROOT)/zlib-1.2.3 -#UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 -#PTHREADS_DIR=$(SRC_ROOT)/pthreads-w32-2-8-0-release - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ####################################### - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -# These aren't used anymore.... really. -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -# SSL / pthreads / Zlib -# included by default for Windows compilation. -INCLUDE += -I $(SSL_DIR)/include -INCLUDE += -I$(PTHREADS_DIR) -INCLUDE += -I$(ZLIB_DIR) - - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -BIOCFLAGS += -DWINDOWS_SYS - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -#WININC += -DPTW32_STATIC_LIB -#WININC += -mno-cygwin -mwindows -fno-exceptions - -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(SSL_DIR)/include -CFLAGS += -I$(PTHREADS_DIR)/include -CFLAGS += -I$(ZLIB_DIR) -CFLAGS += -I$(SRC_ROOT_GPG)/include - -### Enable this for GPGME and GPG ERROR dirs -#CFLAGS += -I$(GPGME_DIR)/src -#CFLAGS += -I$(GPG_ERROR_DIR)/src - -CFLAGS += $(WININC) - - - -LIBS = -L$(LIBDIR) -lretroshare - -LIBS += -L$(SSL_DIR) - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -#RSCFLAGS = -Wall -g $(INCLUDE) -#RSCFLAGS += $(WININC) - - diff --git a/libbitdht/src/tests/scripts/config.mk b/libbitdht/src/tests/scripts/config.mk deleted file mode 100644 index 0859a4799..000000000 --- a/libbitdht/src/tests/scripts/config.mk +++ /dev/null @@ -1,27 +0,0 @@ - -# determine which operating system -# -########################################################################### -#Define OS. -# -OS = Linux -#OS = MacOSX -#OS = Cygwin -#OS = Win # MinGw. -########################################################################### - -ifeq ($(OS),Linux) - include $(TEST_TOP_DIR)/scripts/config-linux.mk -else - ifeq ($(OS),MacOSX) - include $(TEST_TOP_DIR)/scripts/config-macosx.mk - else - ifeq ($(OS),Cygwin) - include $(TEST_TOP_DIR)/scripts/config-cygwin.mk - else - include $(TEST_TOP_DIR)/scripts/config-mingw.mk - endif - endif -endif - -########################################################################### diff --git a/libbitdht/src/tests/scripts/regress.mk b/libbitdht/src/tests/scripts/regress.mk deleted file mode 100644 index f80b48451..000000000 --- a/libbitdht/src/tests/scripts/regress.mk +++ /dev/null @@ -1,25 +0,0 @@ - -testoutputfiles = $(foreach tt,$(1),$(tt).tstout) - -%.tstout : %.sh - -sh ./$< > $@ 2>&1 - -%.tstout : % - -./$< > $@ 2>&1 - -TESTOUT = $(call testoutputfiles,$(TESTS)) - -.phony : tests regress retest clobber - -tests: $(TESTS) - -regress: $(TESTOUT) - @-echo "--------------- SUCCESS (count):" - @-grep -c SUCCESS $(TESTOUT) - @-echo "--------------- FAILURE REPORTS:" - @-grep FAILURE $(TESTOUT) || echo no failures - @-echo "--------------- end" - -retest: - -/bin/rm $(TESTOUT) - diff --git a/libbitdht/src/tests/scripts/rules.mk b/libbitdht/src/tests/scripts/rules.mk deleted file mode 100644 index 9166e80a4..000000000 --- a/libbitdht/src/tests/scripts/rules.mk +++ /dev/null @@ -1,19 +0,0 @@ - -# defines required / used. -# -# CFLAGS -# -# - -.cc.o: - $(CC) $(CFLAGS) -c $< - -clean: - -/bin/rm $(EXECOBJ) $(TESTOBJ) - -clobber: clean retest - -/bin/rm $(EXEC) $(TESTS) - - -include $(TEST_TOP_DIR)/scripts/regress.mk - diff --git a/libbitdht/src/tests/udpbitdht_nettest.cc b/libbitdht/src/tests/udpbitdht_nettest.cc deleted file mode 100644 index 0dbb634b2..000000000 --- a/libbitdht/src/tests/udpbitdht_nettest.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* - * bitdht/udpbitdht_nettest.cc - * - * BitDHT: An Flexible DHT library. - * - * Copyright 2010 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 3 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 "bitdht@lunamutt.com". - * - */ - - -#include "udp/udpbitdht.h" -#include "udp/udpstack.h" -#include "bitdht/bdstddht.h" - -#include -#include - -/******************************************************************* - * DHT test program. - * - * - * Create a couple of each type. - */ - -#define MAX_MESSAGE_LEN 10240 - -int args(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " -p "; - std::cerr << " -b "; - std::cerr << " -u "; - std::cerr << " -q "; - std::cerr << " -r (do dht restarts) "; - std::cerr << " -j (do join test) "; - std::cerr << std::endl; - return 1; -} - -#define DEF_PORT 7500 - -#define MIN_DEF_PORT 1001 -#define MAX_DEF_PORT 16000 - -#define DEF_BOOTFILE "bdboot.txt" - -int main(int argc, char **argv) -{ - int c; - int port = DEF_PORT; - std::string bootfile = DEF_BOOTFILE; - std::string uid; - bool setUid = false; - bool doRandomQueries = false; - bool doRestart = false; - bool doThreadJoin = false; - int noQueries = 0; - - while((c = getopt(argc, argv,"rjp:b:u:q:")) != -1) - { - switch (c) - { - case 'r': - doRestart = true; - break; - case 'j': - doThreadJoin = true; - break; - case 'p': - { - int tmp_port = atoi(optarg); - if ((tmp_port > MIN_DEF_PORT) && (tmp_port < MAX_DEF_PORT)) - { - port = tmp_port; - std::cerr << "Port: " << port; - std::cerr << std::endl; - } - else - { - std::cerr << "Invalid Port"; - std::cerr << std::endl; - args(argv[0]); - return 1; - } - - } - break; - case 'b': - { - bootfile = optarg; - std::cerr << "Bootfile: " << bootfile; - std::cerr << std::endl; - } - break; - case 'u': - { - setUid = true; - uid = optarg; - std::cerr << "UID: " << uid; - std::cerr << std::endl; - } - break; - case 'q': - { - doRandomQueries = true; - noQueries = atoi(optarg); - std::cerr << "Doing Random Queries"; - std::cerr << std::endl; - } - break; - - default: - { - args(argv[0]); - return 1; - } - break; - } - } - - - bdDhtFunctions *fns = new bdStdDht(); - - bdNodeId id; - - /* start off with a random id! */ - bdStdRandomNodeId(&id); - - if (setUid) - { - int len = uid.size(); - if (len > 20) - { - len = 20; - } - - for(int i = 0; i < len; i++) - { - id.data[i] = uid[i]; - } - } - - std::cerr << "Using NodeId: "; - fns->bdPrintNodeId(std::cerr, &id); - std::cerr << std::endl; - - /* setup the udp port */ - struct sockaddr_in local; - memset(&local, 0, sizeof(local)); - local.sin_family = AF_INET; - local.sin_addr.s_addr = 0; - local.sin_port = htons(port); - UdpStack *udpstack = new UdpStack(local); - - /* create bitdht component */ - std::string dhtVersion = "dbTEST"; - UdpBitDht *bitdht = new UdpBitDht(udpstack, &id, dhtVersion, bootfile, fns); - - /* add in the stack */ - udpstack->addReceiver(bitdht); - - /* register callback display */ - bdDebugCallback *cb = new bdDebugCallback(); - bitdht->addCallback(cb); - - /* startup threads */ - //udpstack->start(); - bitdht->start(); - - - - - /* do a couple of random continuous searchs. */ - - uint32_t mode = BITDHT_QFLAGS_DO_IDLE; - - int count = 0; - int running = 1; - - std::cerr << "Starting Dht: "; - std::cerr << std::endl; - bitdht->startDht(); - - - if (doRandomQueries) - { - for(int i = 0; i < noQueries; i++) - { - bdNodeId rndId; - bdStdRandomNodeId(&rndId); - - std::cerr << "BitDht Launching Random Search: "; - bdStdPrintNodeId(std::cerr, &rndId); - std::cerr << std::endl; - - bitdht->addFindNode(&rndId, mode); - - } - } - - while(1) - { - sleep(60); - - std::cerr << "BitDht State: "; - std::cerr << bitdht->stateDht(); - std::cerr << std::endl; - - std::cerr << "Dht Network Size: "; - std::cerr << bitdht->statsNetworkSize(); - std::cerr << std::endl; - - std::cerr << "BitDht Network Size: "; - std::cerr << bitdht->statsBDVersionSize(); - std::cerr << std::endl; - - if (++count == 2) - { - /* switch to one-shot searchs */ - mode = 0; - } - - if (doThreadJoin) - { - /* change address */ - if (count % 2 == 0) - { - - std::cerr << "Resetting UdpStack: "; - std::cerr << std::endl; - - udpstack->resetAddress(local); - } - } - if (doRestart) - { - if (count % 2 == 1) - { - if (running) - { - - std::cerr << "Stopping Dht: "; - std::cerr << std::endl; - - bitdht->stopDht(); - running = 0; - } - else - { - std::cerr << "Starting Dht: "; - std::cerr << std::endl; - - bitdht->startDht(); - running = 1; - } - } - } - } - return 1; -} - - diff --git a/libbitdht/src/tests/utest.h b/libbitdht/src/tests/utest.h deleted file mode 100644 index 1ebd9875a..000000000 --- a/libbitdht/src/tests/utest.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _UNIT_TEST_MACROS_H__ -#define _UNIT_TEST_MACROS_H__ - -#include - -#define TFAILURE( s ) printf( "FAILURE: " __FILE__ ":%-4d %s\n", __LINE__, s ) -#define TSUCCESS( s ) printf( "SUCCESS: " __FILE__ ":%-4d %s\n", __LINE__, s ) - -/* careful with this line (no protection) */ -#define INITTEST() int ok = 1; int gok = 1; - -/* declare the variables */ -extern int ok; -extern int gok; - -#define CHECK( b ) do { if ( ! (b) ) { ok = 0; TFAILURE( #b ); } } while(0) -#define FAILED( s ) do { ok = 0; TFAILURE( s ); } while(0) -#define REPORT( s ) do { if ( ! (ok) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) -#define REPORT2( b, s ) do { if ( ! (b) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) -#define FINALREPORT( s ) do { gok &= ok; ok = 1; if ( ! (gok) ) { TFAILURE( s ); } else { TSUCCESS( s );} } while(0) -#define TESTRESULT() (!gok) - -#endif diff --git a/libbitdht/src/udp/udpbitdht.cc b/libbitdht/src/udp/udpbitdht.cc deleted file mode 100644 index 066faf54d..000000000 --- a/libbitdht/src/udp/udpbitdht.cc +++ /dev/null @@ -1,373 +0,0 @@ -/******************************************************************************* - * bitdht/udpbitdht.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "udp/udpbitdht.h" -#include "bitdht/bdpeer.h" -#include "bitdht/bdstore.h" -#include "bitdht/bdmsgs.h" -#include "bitdht/bencode.h" - -#include -#include /* for usleep() */ -#include -#include - -#include - -#include "util/bdnet.h" - -/* - * #define DEBUG_UDP_BITDHT 1 - * - * #define BITDHT_VERSION_ANONYMOUS 1 - */ - -//#define DEBUG_UDP_BITDHT 1 - -#define BITDHT_VERSION_IDENTIFER 1 - -// Original RS 0.5.0/0.5.1 version, is un-numbered. -//#define BITDHT_VERSION "00" // First Release of BitDHT with Connections (Proxy Support + Dht Stun) -//#define BITDHT_VERSION "01" // Testing Connections (Proxy Only) -#define BITDHT_VERSION "02" // Completed Relay Connections from svn 4766 -//#define BITDHT_VERSION "04" // Full DHT implementation.? - -/*************************************/ - -UdpBitDht::UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string appVersion, std::string bootstrapfile, std::string bootstrapfilebak, const std::string& filteredipfile, bdDhtFunctions *fns) - :UdpSubReceiver(pub), dhtMtx(true)//, mFns(fns) -{ - std::string usedVersion; - -#ifdef BITDHT_VERSION_IDENTIFER - usedVersion = "BD"; - usedVersion += BITDHT_VERSION; -#endif - usedVersion += appVersion; - -#ifdef BITDHT_VERSION_ANONYMOUS - usedVersion = ""; /* blank it */ -#endif - - clearDataTransferred(); - - /* setup nodeManager */ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - mBitDhtManager = new bdNodeManager(id, usedVersion, bootstrapfile, bootstrapfilebak, filteredipfile, fns); -} - - -UdpBitDht::~UdpBitDht() -{ - return; -} - - - /*********** External Interface to the World ************/ - - /***** Functions to Call down to bdNodeManager ****/ - /* Friend Tracking */ -void UdpBitDht::addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->addBadPeer(addr, source, reason, age); -} - - -void UdpBitDht::updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->updateKnownPeer(id, type, flags); -} - - /* Request DHT Peer Lookup */ - /* Request Keyword Lookup */ -void UdpBitDht::addFindNode(bdNodeId *id, uint32_t mode) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->addFindNode(id, mode); -} - -void UdpBitDht::removeFindNode(bdNodeId *id) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->removeFindNode(id); -} - -void UdpBitDht::findDhtValue(bdNodeId *id, std::string key, uint32_t mode) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->findDhtValue(id, key, mode); -} - - /***** Add / Remove Callback Clients *****/ -void UdpBitDht::addCallback(BitDhtCallback *cb) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->addCallback(cb); -} - -void UdpBitDht::removeCallback(BitDhtCallback *cb) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->removeCallback(cb); -} - -bool UdpBitDht::ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->ConnectionRequest(laddr, target, mode, delay, start); -} - - - -void UdpBitDht::ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, - uint32_t bandwidth, uint32_t delay, uint32_t answer) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->ConnectionAuth(srcId, proxyId, destId, mode, loc, bandwidth, delay, answer); -} - -void UdpBitDht::ConnectionOptions(uint32_t allowedModes, uint32_t flags) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mBitDhtManager->ConnectionOptions(allowedModes, flags); -} - -bool UdpBitDht::setAttachMode(bool on) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->setAttachMode(on); -} - - -int UdpBitDht::getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->getDhtPeerAddress(id, from); -} - -int UdpBitDht::getDhtValue(const bdNodeId *id, std::string key, std::string &value) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->getDhtValue(id, key, value); -} - -int UdpBitDht::getDhtBucket(const int idx, bdBucket &bucket) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->getDhtBucket(idx, bucket); -} - - - -int UdpBitDht::getDhtQueries(std::map &queries) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->getDhtQueries(queries); -} - -int UdpBitDht::getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->getDhtQueryStatus(id, query); -} - -bool UdpBitDht::isAddressBanned(const sockaddr_in &raddr) -{ - return mBitDhtManager->addressBanned(raddr) ; -} - -bool UdpBitDht::getListOfBannedIps(std::list& ipl) -{ - return mBitDhtManager->getFilteredPeers(ipl) ; -} - - - - /* stats and Dht state */ -int UdpBitDht:: startDht() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->startDht(); -} - -int UdpBitDht:: stopDht() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->stopDht(); -} - -int UdpBitDht::stateDht() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->stateDht(); -} - -uint32_t UdpBitDht::statsNetworkSize() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->statsNetworkSize(); -} - -uint32_t UdpBitDht::statsBDVersionSize() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->statsBDVersionSize(); -} - -uint32_t UdpBitDht::setDhtMode(uint32_t dhtFlags) -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - return mBitDhtManager->setDhtMode(dhtFlags); -} - - - /******************* Internals *************************/ - - /***** Iteration / Loop Management *****/ - - /*** Overloaded from UdpSubReceiver ***/ -int UdpBitDht::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* pass onto bitdht */ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - /* check packet suitability */ - if (mBitDhtManager->isBitDhtPacket((char *) data, size, from)) - { - - mReadBytes += size; - mBitDhtManager->incomingMsg(&from, (char *) data, size); - return 1; - } - return 0; -} - -int UdpBitDht::status(std::ostream &out) -{ - out << "UdpBitDht::status()" << std::endl; - - return 1; -} - -void UdpBitDht::clearDataTransferred() -{ - /* pass onto bitdht */ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - mReadBytes = 0; - mWriteBytes = 0; -} - - -void UdpBitDht::getDataTransferred(uint32_t &read, uint32_t &write) -{ - { - /* pass onto bitdht */ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - read = mReadBytes; - write = mWriteBytes; - } - clearDataTransferred(); -} - - - /*** Overloaded from iThread ***/ -#define MAX_MSG_PER_TICK 100 -#define TICK_PAUSE_USEC 20000 /* 20ms secs .. max messages = 50 x 100 = 5000 */ - -void UdpBitDht::run() -{ - while(1) - { - while(tick()) - { - usleep(TICK_PAUSE_USEC); - } - - { - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - mBitDhtManager->iteration(); - } - sleep(1); - } -} - - -int UdpBitDht::tick() -{ - bdStackMutex stack(dhtMtx); /********** MUTEX LOCKED *************/ - - /* pass on messages from the node */ - int i = 0; - char data[BITDHT_MAX_PKTSIZE]; - struct sockaddr_in toAddr; - int size = BITDHT_MAX_PKTSIZE; - - while((i < MAX_MSG_PER_TICK) && (mBitDhtManager->outgoingMsg(&toAddr, data, &size))) - { -#ifdef DEBUG_UDP_BITDHT - std::cerr << "UdpBitDht::tick() outgoing msg(" << size << ") to " << toAddr; - std::cerr << std::endl; -#endif - - mWriteBytes += size; - sendPkt(data, size, toAddr, BITDHT_TTL); - - // iterate - i++; - size = BITDHT_MAX_PKTSIZE; // reset msg size! - } - - if (i == MAX_MSG_PER_TICK) - { - return 1; /* keep on ticking */ - } - return 0; -} - - - diff --git a/libbitdht/src/udp/udpbitdht.h b/libbitdht/src/udp/udpbitdht.h deleted file mode 100644 index 38088edfb..000000000 --- a/libbitdht/src/udp/udpbitdht.h +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * udp/udpbitdht.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef UDP_BIT_DHT_CLASS_H -#define UDP_BIT_DHT_CLASS_H - -#include -#include -#include - -#include "udp/udpstack.h" -#include "bitdht/bdiface.h" -#include "bitdht/bdmanager.h" - -/* - * This implements a UdpSubReceiver class to allow the DHT to talk to the network. - * The parser is very strict - and will try to not pick up anyone else's messages. - * - * Mutexes are implemented at this level protecting the whole of the DHT code. - * This class is also a thread - enabling it to do callback etc. - */ - -// class BitDhtCallback defined in bdiface.h - - -class UdpBitDht: public UdpSubReceiver, public bdThread, public BitDhtInterface -{ - public: - - UdpBitDht(UdpPublisher *pub, bdNodeId *id, std::string dhtVersion, std::string bootstrapfile, std::string bootstrapfilebak, const std::string& filteredipfile,bdDhtFunctions *fns); -virtual ~UdpBitDht(); - - - /*********** External Interface to the World (BitDhtInterface) ************/ - - /***** Functions to Call down to bdNodeManager ****/ - - /* Friend Tracking */ -virtual void addBadPeer(const struct sockaddr_in &addr, uint32_t source, uint32_t reason, uint32_t age); -virtual void updateKnownPeer(const bdId *id, uint32_t type, uint32_t flags); - - /* Request DHT Peer Lookup */ - /* Request Keyword Lookup */ -virtual void addFindNode(bdNodeId *id, uint32_t mode); -virtual void removeFindNode(bdNodeId *id); -virtual void findDhtValue(bdNodeId *id, std::string key, uint32_t mode); - - /***** Add / Remove Callback Clients *****/ -virtual void addCallback(BitDhtCallback *cb); -virtual void removeCallback(BitDhtCallback *cb); - - /***** Connections Requests *****/ -virtual bool ConnectionRequest(struct sockaddr_in *laddr, bdNodeId *target, uint32_t mode, uint32_t delay, uint32_t start); -virtual void ConnectionAuth(bdId *srcId, bdId *proxyId, bdId *destId, uint32_t mode, uint32_t loc, - uint32_t bandwidth, uint32_t delay, uint32_t answer); -virtual void ConnectionOptions(uint32_t allowedModes, uint32_t flags); -virtual bool setAttachMode(bool on); - - /***** Get Results Details *****/ -virtual int getDhtPeerAddress(const bdNodeId *id, struct sockaddr_in &from); -virtual int getDhtValue(const bdNodeId *id, std::string key, std::string &value); -virtual int getDhtBucket(const int idx, bdBucket &bucket); - -virtual int getDhtQueries(std::map &queries); -virtual int getDhtQueryStatus(const bdNodeId *id, bdQuerySummary &query); - - virtual bool isAddressBanned(const sockaddr_in &raddr) ; - virtual bool getListOfBannedIps(std::list &ipl); - - /* stats and Dht state */ -virtual int startDht(); -virtual int stopDht(); -virtual int stateDht(); -virtual uint32_t statsNetworkSize(); -virtual uint32_t statsBDVersionSize(); -virtual uint32_t setDhtMode(uint32_t dhtFlags); - -void getDataTransferred(uint32_t &read, uint32_t &write); - - /******************* Internals *************************/ - /***** Iteration / Loop Management *****/ - - /*** Overloaded from UdpSubReceiver ***/ -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); -virtual int status(std::ostream &out); - - - /*** Overloaded from iThread ***/ -virtual void run(); - - /**** do whats to be done ***/ -int tick(); -private: - -void clearDataTransferred(); - - bdMutex dhtMtx; /* for all class data (below) */ - bdNodeManager *mBitDhtManager; - //bdDhtFunctions *mFns; - - - uint32_t mReadBytes; - uint32_t mWriteBytes; - - -}; - - -#endif diff --git a/libbitdht/src/udp/udplayer.cc b/libbitdht/src/udp/udplayer.cc deleted file mode 100644 index 1a82c3d81..000000000 --- a/libbitdht/src/udp/udplayer.cc +++ /dev/null @@ -1,772 +0,0 @@ -/******************************************************************************* - * udp/udplayer.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2004-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "udp/udplayer.h" -#include "util/bdrandom.h" -#include "util/bdstring.h" - -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif - -/*** - * #define UDP_ENABLE_BROADCAST 1 - * #define UDP_LOOPBACK_TESTING 1 - * #define DEBUG_UDP_LAYER 1 - ***/ - -//#define DEBUG_UDP_LAYER 1 - -static const int UDP_DEF_TTL = 64; - -/* NB: This #define makes the listener open 0.0.0.0:X port instead - * of a specific port - this helps library communicate on systems - * with multiple interfaces or unique network setups. - * - * - It should always be used! - * - * #define OPEN_UNIVERSAL_PORT 1 - * - */ - -#define OPEN_UNIVERSAL_PORT 1 - - -class udpPacket -{ - public: - udpPacket(struct sockaddr_in *addr, void *dta, int dlen) - :raddr(*addr), len(dlen) - { - data = malloc(len); - - if(data != NULL) - memcpy(data, dta, len); - else - std::cerr << "(EE) error in memory allocation in " << __PRETTY_FUNCTION__ << std::endl; - } - - ~udpPacket() - { - if (data) - { - free(data); - data = NULL; - len = 0; - } - } - - struct sockaddr_in raddr; - void *data; - int len; -}; - -//std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr) -std::ostream &operator<<(std::ostream &out, struct sockaddr_in &addr) -{ - out << "[" << bdnet_inet_ntoa(addr.sin_addr) << ":"; - out << htons(addr.sin_port) << "]"; - return out; -} - -bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2) -{ - if (addr.sin_family != addr2.sin_family) - return false; - if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr) - return false; - if (addr.sin_port != addr2.sin_port) - return false; - return true; -} - - -bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2) -{ - if (addr.sin_family != addr2.sin_family) - return (addr.sin_family < addr2.sin_family); - if (addr.sin_addr.s_addr != addr2.sin_addr.s_addr) - return (addr.sin_addr.s_addr < addr2.sin_addr.s_addr); - if (addr.sin_port != addr2.sin_port) - return (addr.sin_port < addr2.sin_port); - return false; -} - -std::string printPkt(void *d, int size) -{ - std::string out = "Packet:**********************"; - for(int i = 0; i < size; i++) - { - if (i % 16 == 0) - out += "\n"; - bd_sprintf_append(out, "%2x ", (unsigned int) ((unsigned char *) d)[i]); - } - out += "\n**********************\n"; - return out; -} - - -std::string printPktOffset(unsigned int offset, void *d, unsigned int size) -{ - std::string out = "Packet:**********************\n"; - bd_sprintf_append(out, "Offset: %x -> %x\n", offset, offset + size); - out += "Packet:**********************"; - - unsigned int j = offset % 16; - if (j != 0) - { - out += "\n"; - bd_sprintf_append(out, "%6x: ", (unsigned int) offset - j); - for(unsigned int i = 0; i < j; i++) - { - out += "xx "; - } - } - for(unsigned int i = offset; i < offset + size; i++) - { - if (i % 16 == 0) - { - out += "\n"; - bd_sprintf_append(out, "%6x: ", (unsigned int) i); - } - bd_sprintf(out, "%2x ", (unsigned int) ((unsigned char *) d)[i-offset]); - } - out += "\n**********************\n"; - return out; -} - - - -UdpLayer::UdpLayer(UdpReceiver *udpr, struct sockaddr_in &local) - :recv(udpr), laddr(local), errorState(0), ttl(UDP_DEF_TTL) -{ - openSocket(); - return; -} - -int UdpLayer::status(std::ostream &out) -{ - out << "UdpLayer::status()" << std::endl; - out << "localaddr: " << laddr << std::endl; - out << "sockfd: " << sockfd << std::endl; - out << std::endl; - return 1; -} - -int UdpLayer::reset(struct sockaddr_in &local) -{ -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset()" << std::endl; -#endif - - /* stop the old thread */ - { - bdStackMutex stack(sockMtx); /********** LOCK MUTEX *********/ -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset() setting stopThread flag" << std::endl; -#endif - stopThread = true; - } -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset() joining" << std::endl; -#endif - - join(); - -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset() closing socket" << std::endl; -#endif - closeSocket(); - -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset() resetting variables" << std::endl; -#endif - laddr = local; - errorState = 0; - ttl = UDP_DEF_TTL; - -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::reset() opening socket" << std::endl; -#endif - openSocket(); - - return 1 ; -} - - -int UdpLayer::closeSocket() -{ - /* close socket if open */ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - if (sockfd > 0) - { - bdnet_close(sockfd); - } - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 1; -} - -void UdpLayer::run() -{ - return recv_loop(); -} - -/* higher level interface */ -void UdpLayer::recv_loop() -{ - size_t maxsize = 16000; - void *inbuf = malloc(maxsize); - - if(inbuf == NULL) - { - std::cerr << "(EE) Error in memory allocation of size " << maxsize - << " in " << __PRETTY_FUNCTION__ << std::endl; - return; - } - - int status; - struct timeval timeout; - - while(1) - { - for(;;) - { - /* check if we need to stop */ - bool toStop = false; - { - bdStackMutex stack(sockMtx); (void) stack; - toStop = stopThread; - } - - if (toStop) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::recv_loop() stopping thread" << std::endl; -#endif - free(inbuf); - stop(); - return; // Avoid compiler warning about usage of inbuf after free - } - - fd_set rset; - FD_ZERO(&rset); - FD_SET(sockfd, &rset); - timeout.tv_sec = 0; - timeout.tv_usec = 500000; // 500 ms timeout - status = select(sockfd+1, &rset, NULL, NULL, &timeout); - if (status > 0) break; // data available, go read it -#ifdef DEBUG_UDP_LAYER - else if (status < 0) std::cerr << "UdpLayer::recv_loop() Error: " - << bdnet_errno() << std::endl; -#endif - }; - - int nsize = static_cast(maxsize); - struct sockaddr_in from; - if (0 < receiveUdpPacket(inbuf, &nsize, from)) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::readPkt() from : " << from << std::endl - << printPkt(inbuf, nsize); -#endif - recv->recvPkt(inbuf, nsize, from); // pass to reciever. - } -#ifdef DEBUG_UDP_LAYER - else std::cerr << "UdpLayer::readPkt() not ready" << from << std::endl; -#endif - } -} - - -int UdpLayer::sendPkt(const void *data, int size, const sockaddr_in &to, int ttl) -{ - /* if ttl is different -> set it */ - if (ttl != getTTL()) - { - setTTL(ttl); - } - - /* and send! */ -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::sendPkt() to: " << to << std::endl; - std::cerr << printPkt((void *) data, size); -#endif - sendUdpPacket(data, size, to); - return size; -} - -/* setup connections */ -int UdpLayer::openSocket() -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - /* make a socket */ - sockfd = bdnet_socket(PF_INET, SOCK_DGRAM, 0); -#ifdef DEBUG_UDP_LAYER - std::cerr << "UpdStreamer::openSocket()" << std::endl; -#endif - /* bind to address */ - - -#ifdef UDP_LOOPBACK_TESTING - bdnet_inet_aton("127.0.0.1", &(laddr.sin_addr)); -#endif - -#ifdef OPEN_UNIVERSAL_PORT - struct sockaddr_in tmpaddr = laddr; - tmpaddr.sin_addr.s_addr = 0; - if (0 != bdnet_bind(sockfd, (struct sockaddr *) (&tmpaddr), sizeof(tmpaddr))) -#else - if (0 != bdnet_bind(sockfd, (struct sockaddr *) (&laddr), sizeof(laddr))) -#endif - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "Socket Failed to Bind to : " << laddr << std::endl; - std::cerr << "Error: " << bdnet_errno() << std::endl; -#endif - errorState = EADDRINUSE; - //exit(1); - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; - } - - if (-1 == bdnet_fcntl(sockfd, F_SETFL, O_NONBLOCK)) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "Failed to Make Non-Blocking" << std::endl; -#endif - } - -#ifdef UDP_ENABLE_BROADCAST - /* Setup socket for broadcast. */ - int val = 1; - if (-1 == setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int))) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "Failed to Make Socket Broadcast" << std::endl; -#endif - } -#endif - - errorState = 0; - -#ifdef DEBUG_UDP_LAYER - std::cerr << "Socket Bound to : " << laddr << std::endl; -#endif - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - -#ifdef DEBUG_UDP_LAYER - std::cerr << "Setting TTL to " << UDP_DEF_TTL << std::endl; -#endif - setTTL(UDP_DEF_TTL); - clearDataTransferred(); // clear statistics. - - // start up our thread. - { - bdStackMutex stack(sockMtx); /********** LOCK MUTEX *********/ - stopThread = false; - } - start(); - - return 1; - -} - -int UdpLayer::setTTL(int t) -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - int err = bdnet_setsockopt(sockfd, IPPROTO_IP, IP_TTL, &t, sizeof(int)); - ttl = t; - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::setTTL(" << t << ") returned: " << err; - std::cerr << std::endl; -#endif - - return err; -} - -int UdpLayer::getTTL() -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - int t = ttl; - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return t; -} - -/* monitoring / updates */ -int UdpLayer::okay() -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - bool nonFatalError = ((errorState == 0) || - (errorState == EAGAIN) || - (errorState == EINPROGRESS)); - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - -#ifdef DEBUG_UDP_LAYER - if (!nonFatalError) - { - std::cerr << "UdpLayer::NOT okay(): Error: " << errorState << std::endl; - } - -#endif - - return nonFatalError; -} - -int UdpLayer::tick() -{ -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::tick()" << std::endl; -#endif - return 1; -} - -void UdpLayer::getDataTransferred(uint32_t &read, uint32_t &write) -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - read = readBytes; - write = writeBytes; - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - - clearDataTransferred(); -} - -void UdpLayer::clearDataTransferred() -{ - sockMtx.lock(); /********** LOCK MUTEX *********/ - - readBytes = 0; - writeBytes = 0; - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ -} - -/******************* Internals *************************************/ - -int UdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from) -{ - struct sockaddr_in fromaddr; - socklen_t fromsize = sizeof(fromaddr); - int insize = *size; - - sockMtx.lock(); /********** LOCK MUTEX *********/ - - insize = bdnet_recvfrom(sockfd,data,insize,0, - (struct sockaddr*)&fromaddr,&fromsize); - - if (0 < insize) - { - readBytes += insize; - } - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - - if (0 < insize) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "receiveUdpPacket() from: " << fromaddr; - std::cerr << " Size: " << insize; - std::cerr << std::endl; -#endif - *size = insize; - from = fromaddr; - return insize; - } - return -1; -} - -int UdpLayer::sendUdpPacket(const void *data, int size, const struct sockaddr_in &to) -{ - /* send out */ -#ifdef DEBUG_UDP_LAYER - std::cerr << "UdpLayer::sendUdpPacket(): size: " << size; - std::cerr << " To: " << to << std::endl; -#endif - struct sockaddr_in toaddr = to; - - sockMtx.lock(); /********** LOCK MUTEX *********/ - - bdnet_sendto(sockfd, data, size, 0, - (struct sockaddr *) &(toaddr), - sizeof(toaddr)); - - writeBytes += size; - - sockMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 1; -} - - -/**************************** LossyUdpLayer - for Testing **************/ - - -LossyUdpLayer::LossyUdpLayer(UdpReceiver *udpr, - struct sockaddr_in &local, double frac) - :UdpLayer(udpr, local), lossFraction(frac) -{ - return; -} -LossyUdpLayer::~LossyUdpLayer() { return; } - -int LossyUdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from) -{ - if (0 < UdpLayer::receiveUdpPacket(data, size, from)) - { - float prob = bdRandom::random_f32(); - if (prob < lossFraction) - { - /* discard */ - //std::cerr << "LossyUdpLayer::receiveUdpPacket() Dropping packet!"; - //std::cerr << std::endl; - //std::cerr << printPkt(data, *size); - //std::cerr << std::endl; - std::cerr << "LossyUdpLayer::receiveUdpPacket() Packet (" << *size << ") Dropped!"; - std::cerr << std::endl; - - *size = 0; - return -1; - } - - return *size; - } - return -1; -} - -int LossyUdpLayer::sendUdpPacket(const void *data, int size, const struct sockaddr_in &to) -{ - double prob = (1.0 * (rand() / (RAND_MAX + 1.0))); - - if (prob < lossFraction) - { - /* discard */ - - //std::cerr << "LossyUdpLayer::sendUdpPacket() Dropping packet!"; - //std::cerr << std::endl; - //std::cerr << printPkt((void *) data, size); - //std::cerr << std::endl; - std::cerr << "LossyUdpLayer::sendUdpPacket() Packet (" << size << ") Dropped!"; - std::cerr << std::endl; - - return size; - } - - // otherwise read normally; - return UdpLayer::sendUdpPacket(data, size, to); -} - -/**************************** LossyUdpLayer - for Testing **************/ - -PortRange::PortRange() :lport(0), uport(0) { return; } -PortRange::PortRange(uint16_t lp, uint16_t up) :lport(lp), uport(up) { return; } - -bool PortRange::inRange(uint16_t port) -{ - if (port < lport) - { - return false; - } - - if (port > uport) - { - return false; - } - return true; -} - - - -RestrictedUdpLayer::RestrictedUdpLayer(UdpReceiver *udpr, - struct sockaddr_in &local) - :UdpLayer(udpr, local) -{ - return; -} -RestrictedUdpLayer::~RestrictedUdpLayer() { return; } - -void RestrictedUdpLayer::addRestrictedPortRange(int lp, int up) -{ - PortRange pr(lp, up); - mLostPorts.push_back(pr); -} - -int RestrictedUdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from) -{ - if (0 < UdpLayer::receiveUdpPacket(data, size, from)) - { - /* check the port against list */ - uint16_t inPort = ntohs(from.sin_port); - - std::list::iterator it; - for(it = mLostPorts.begin(); it != mLostPorts.end(); it++) - { - if (it->inRange(inPort)) - { -#ifdef DEBUG_UDP_LAYER - std::cerr << "RestrictedUdpLayer::receiveUdpPacket() Dropping packet"; - std::cerr << ", Port(" << inPort << ") in restricted range!"; - std::cerr << std::endl; - //std::cerr << printPkt(data, *size); - //std::cerr << std::endl; -#endif - - *size = 0; - return -1; - - } - - } - -#ifdef DEBUG_UDP_LAYER - std::cerr << "RestrictedUdpLayer::receiveUdpPacket() Accepting packet"; - std::cerr << ", Port(" << inPort << ") in Okay range!"; - std::cerr << std::endl; -#endif - /* acceptable port */ - return *size; - } - return -1; -} - -int RestrictedUdpLayer::sendUdpPacket(const void *data, int size, const struct sockaddr_in &to) -{ - /* check the port against list */ - uint16_t outPort = ntohs(to.sin_port); - - std::list::iterator it; - for(it = mLostPorts.begin(); it != mLostPorts.end(); it++) - { - if (it->inRange(outPort)) - { - /* drop */ -#ifdef DEBUG_UDP_LAYER - std::cerr << "RestrictedUdpLayer::sendUdpPacket() Dropping packet"; - std::cerr << ", Port(" << outPort << ") in restricted range!"; - std::cerr << std::endl; - //std::cerr << printPkt(data, *size); - //std::cerr << std::endl; -#endif - - return size; - } - - - } - -#ifdef DEBUG_UDP_LAYER - std::cerr << "RestrictedUdpLayer::sendUdpPacket() Sending packet"; - std::cerr << ", Port(" << outPort << ") in Okay range!"; - std::cerr << std::endl; -#endif - - // otherwise read normally; - return UdpLayer::sendUdpPacket(data, size, to); -} - - -#define STARTUP_PERIOD 60 - -TimedUdpLayer::TimedUdpLayer(UdpReceiver *udpr, - struct sockaddr_in &local) - :UdpLayer(udpr, local) -{ - mStartTime = time(NULL) + STARTUP_PERIOD; - mActive = false; - return; -} - -TimedUdpLayer::~TimedUdpLayer() { return; } - -int TimedUdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &from) -{ - if (0 < UdpLayer::receiveUdpPacket(data, size, from)) - { - if (!mActive) - { - if (time(NULL) < mStartTime) - { -#ifdef DEBUG_UDP_LAYER -#endif - std::cerr << "TimedUdpLayer::receiveUdpPacket() Dropping packet (Too Early)"; - std::cerr << std::endl; - //std::cerr << printPkt(data, *size); - //std::cerr << std::endl; - - *size = 0; - return -1; - - } - - mActive = true; - - } - - /* acceptable port */ - return *size; - } - return -1; -} - -int TimedUdpLayer::sendUdpPacket(const void *data, int size, const struct sockaddr_in &to) -{ - if (!mActive) - { - if (time(NULL) < mStartTime) - { - /* drop */ -#ifdef DEBUG_UDP_LAYER -#endif - std::cerr << "TimedUdpLayer::sendUdpPacket() Dropping packet (Too Early)"; - std::cerr << std::endl; - return size; - } - - /* else activate */ - mActive = true; - } - - // otherwise read normally; - return UdpLayer::sendUdpPacket(data, size, to); -} - - - - diff --git a/libbitdht/src/udp/udplayer.h b/libbitdht/src/udp/udplayer.h deleted file mode 100644 index 06e76c647..000000000 --- a/libbitdht/src/udp/udplayer.h +++ /dev/null @@ -1,188 +0,0 @@ -/******************************************************************************* - * udp/udplayer.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2004-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_UDP_LAYER_H -#define BITDHT_UDP_LAYER_H - -#include "util/bdthreads.h" -#include "util/bdnet.h" - -#include -#include -#include - -/* careful - duplicate definitions */ -//std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr); -std::ostream &operator<<(std::ostream &out, struct sockaddr_in &addr); - -bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2); -bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2); - -std::string printPkt(void *d, int size); -std::string printPktOffset(unsigned int offset, void *d, unsigned int size); - - -/* UdpLayer ..... is the bottom layer which - * just sends and receives Udp packets. - */ - -class UdpReceiver -{ - public: -virtual ~UdpReceiver() {} -virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0; -virtual int status(std::ostream &out) = 0; -}; - -class UdpPublisher -{ - public: -virtual ~UdpPublisher() {} -virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl) = 0; -}; - - -class UdpLayer: public bdThread -{ - public: - - UdpLayer(UdpReceiver *recv, struct sockaddr_in &local); -virtual ~UdpLayer() { return; } - -int reset(struct sockaddr_in &local); /* calls join, close, openSocket */ -void getDataTransferred(uint32_t &read, uint32_t &write); - -int status(std::ostream &out); - - /* setup connections */ - int closeSocket(); - int openSocket(); - - /* RsThread functions */ -virtual void run(); /* called once the thread is started */ - -void recv_loop(); /* uses callback to UdpReceiver */ - - /* Higher Level Interface */ - //int readPkt(void *data, int *size, struct sockaddr_in &from); - int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl); - - /* monitoring / updates */ - int okay(); - int tick(); - - - /* data */ - /* internals */ - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - int setTTL(int t); - int getTTL(); - - /* low level */ - private: - -void clearDataTransferred(); - - UdpReceiver *recv; - - struct sockaddr_in laddr; /* local addr */ - - uint32_t readBytes; - uint32_t writeBytes; - - int errorState; - int sockfd; - int ttl; - bool stopThread; - - bdMutex sockMtx; -}; - - -/* For Testing - drops packets */ -class LossyUdpLayer: public UdpLayer -{ - public: - LossyUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local, double frac); -virtual ~LossyUdpLayer(); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - double lossFraction; -}; - -class PortRange -{ - public: - PortRange(); - PortRange(uint16_t lp, uint16_t up); - - bool inRange(uint16_t port); - - uint16_t lport; - uint16_t uport; -}; - - -/* For Testing - drops packets */ -class RestrictedUdpLayer: public UdpLayer -{ - public: - RestrictedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local); -virtual ~RestrictedUdpLayer(); - -void addRestrictedPortRange(int lp, int up); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - std::list mLostPorts; -}; - - -/* For Testing - drops packets all packets for initial minute (simulates TTL) */ -class TimedUdpLayer: public UdpLayer -{ - public: - TimedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local); -virtual ~TimedUdpLayer(); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - time_t mStartTime; - bool mActive; - -}; - - -#endif diff --git a/libbitdht/src/udp/udpproxylayer.h b/libbitdht/src/udp/udpproxylayer.h deleted file mode 100644 index 939bdabf8..000000000 --- a/libbitdht/src/udp/udpproxylayer.h +++ /dev/null @@ -1,181 +0,0 @@ -/******************************************************************************* - * libbitdht/src/udp/udpproxylayer.h * - * * - * Copyright 2004 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BITDHT_UDP_LAYER_H -#define BITDHT_UDP_LAYER_H - -#include "util/bdthreads.h" -#include "util/bdnet.h" - -#include -#include -#include - -/* careful - duplicate definitions */ -//std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr); -std::ostream &operator<<(std::ostream &out, struct sockaddr_in &addr); - -bool operator==(const struct sockaddr_in &addr, const struct sockaddr_in &addr2); -bool operator<(const struct sockaddr_in &addr, const struct sockaddr_in &addr2); - -std::string printPkt(void *d, int size); -std::string printPktOffset(unsigned int offset, void *d, unsigned int size); - - -/* UdpLayer ..... is the bottom layer which - * just sends and receives Udp packets. - */ - -class UdpReceiver -{ - public: -virtual ~UdpReceiver() {} -virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0; -virtual int status(std::ostream &out) = 0; -}; - -class UdpPublisher -{ - public: -virtual ~UdpPublisher() {} -virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl) = 0; -}; - - -class UdpLayer: public bdThread -{ - public: - - UdpLayer(UdpReceiver *recv, struct sockaddr_in &local); -virtual ~UdpLayer() { return; } - -int reset(struct sockaddr_in &local); /* calls join, close, openSocket */ - -int status(std::ostream &out); - - /* setup connections */ - int closeSocket(); - int openSocket(); - - /* RsThread functions */ -virtual void run(); /* called once the thread is started */ - -void recv_loop(); /* uses callback to UdpReceiver */ - - /* Higher Level Interface */ - //int readPkt(void *data, int *size, struct sockaddr_in &from); - int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl); - - /* monitoring / updates */ - int okay(); - int tick(); - - - /* data */ - /* internals */ - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - int setTTL(int t); - int getTTL(); - - /* low level */ - private: - - UdpReceiver *recv; - - struct sockaddr_in laddr; /* local addr */ - - int errorState; - int sockfd; - int ttl; - bool stopThread; - - bdMutex sockMtx; -}; - - -/* For Testing - drops packets */ -class LossyUdpLayer: public UdpLayer -{ - public: - LossyUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local, double frac); -virtual ~LossyUdpLayer(); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - double lossFraction; -}; - -class PortRange -{ - public: - PortRange(); - PortRange(uint16_t lp, uint16_t up); - - bool inRange(uint16_t port); - - uint16_t lport; - uint16_t uport; -}; - - -/* For Testing - drops packets */ -class RestrictedUdpLayer: public UdpLayer -{ - public: - RestrictedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local); -virtual ~RestrictedUdpLayer(); - -void addRestrictedPortRange(int lp, int up); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - std::list mLostPorts; -}; - - -/* For Testing - drops packets all packets for initial minute (simulates TTL) */ -class TimedUdpLayer: public UdpLayer -{ - public: - TimedUdpLayer(UdpReceiver *udpr, struct sockaddr_in &local); -virtual ~TimedUdpLayer(); - - protected: - -virtual int receiveUdpPacket(void *data, int *size, struct sockaddr_in &from); -virtual int sendUdpPacket(const void *data, int size, const struct sockaddr_in &to); - - time_t mStartTime; - bool mActive; - -}; - - -#endif diff --git a/libbitdht/src/udp/udpstack.cc b/libbitdht/src/udp/udpstack.cc deleted file mode 100644 index fdf8eb9cf..000000000 --- a/libbitdht/src/udp/udpstack.cc +++ /dev/null @@ -1,252 +0,0 @@ -/******************************************************************************* - * udp/udpstack.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "udp/udpstack.h" - -#include -#include -#include -#include - -#include - -/*** - * #define DEBUG_UDP_RECV 1 - ***/ - -//#define DEBUG_UDP_RECV 1 - - -UdpStack::UdpStack(struct sockaddr_in &local) - :udpLayer(NULL), laddr(local) -{ - openSocket(); - return; -} - -UdpStack::UdpStack(int testmode, struct sockaddr_in &local) - :udpLayer(NULL), laddr(local) -{ - std::cerr << "UdpStack::UdpStack() Evoked in TestMode" << std::endl; - if (testmode == UDP_TEST_LOSSY_LAYER) - { - std::cerr << "UdpStack::UdpStack() Installing LossyUdpLayer" << std::endl; - udpLayer = new LossyUdpLayer(this, laddr, UDP_TEST_LOSSY_FRAC); - } - else if (testmode == UDP_TEST_RESTRICTED_LAYER) - { - std::cerr << "UdpStack::UdpStack() Installing RestrictedUdpLayer" << std::endl; - udpLayer = new RestrictedUdpLayer(this, laddr); - } - else if (testmode == UDP_TEST_TIMED_LAYER) - { - std::cerr << "UdpStack::UdpStack() Installing TimedUdpLayer" << std::endl; - udpLayer = new TimedUdpLayer(this, laddr); - } - else - { - std::cerr << "UdpStack::UdpStack() Installing Standard UdpLayer" << std::endl; - // standard layer - openSocket(); - } - return; -} - -UdpLayer *UdpStack::getUdpLayer() /* for testing only */ -{ - return udpLayer; -} - -bool UdpStack::getLocalAddress(struct sockaddr_in &local) -{ - local = laddr; - return true; -} - -bool UdpStack::resetAddress(struct sockaddr_in &local) -{ -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::resetAddress(" << local << ")"; - std::cerr << std::endl; -#endif - laddr = local; - - return udpLayer->reset(local); -} - - - -/* higher level interface */ -int UdpStack::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* print packet information */ -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; -#endif - - bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/ - - std::list::iterator it; - for(it = mReceivers.begin(); it != mReceivers.end(); it++) - { - // See if they want the packet. - if ((*it)->recvPkt(data, size, from)) - { -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; -#endif - break; - } - } - return 1; -} - -int UdpStack::sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl) -{ - /* print packet information */ -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::sendPkt(" << size << ") ttl: " << ttl; - std::cerr << " to: " << to; - std::cerr << std::endl; -#endif - - /* send to udpLayer */ - return udpLayer->sendPkt(data, size, to, ttl); -} - -int UdpStack::status(std::ostream &out) -{ - { - bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/ - - out << "UdpStack::status()" << std::endl; - out << "localaddr: " << laddr << std::endl; - out << "UdpStack::SubReceivers:" << std::endl; - std::list::iterator it; - int i = 0; - for(it = mReceivers.begin(); it != mReceivers.end(); it++, i++) - { - out << "\tReceiver " << i << " --------------------" << std::endl; - (*it)->status(out); - } - out << "--------------------" << std::endl; - out << std::endl; - } - - udpLayer->status(out); - - return 1; -} - -/* setup connections */ -int UdpStack::openSocket() -{ - udpLayer = new UdpLayer(this, laddr); - return 1; -} - -/* monitoring / updates */ -int UdpStack::okay() -{ - return udpLayer->okay(); -} - -int UdpStack::close() -{ - /* TODO */ - return 1; -} - - - /* add a TCPonUDP stream */ -int UdpStack::addReceiver(UdpReceiver *recv) -{ - bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/ - - /* check for duplicate */ - std::list::iterator it; - it = std::find(mReceivers.begin(), mReceivers.end(), recv); - if (it == mReceivers.end()) - { - mReceivers.push_back(recv); - return 1; - } - - /* otherwise its already there! */ - -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::addReceiver() Recv already exists!" << std::endl; - std::cerr << "UdpStack::addReceiver() ERROR" << std::endl; -#endif - - return 0; -} - -int UdpStack::removeReceiver(UdpReceiver *recv) -{ - bdStackMutex stack(stackMtx); /********** LOCK MUTEX *********/ - - /* check for duplicate */ - std::list::iterator it; - it = std::find(mReceivers.begin(), mReceivers.end(), recv); - if (it != mReceivers.end()) - { - mReceivers.erase(it); - return 1; - } - - /* otherwise its not there! */ - -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpStack::removeReceiver() Recv dont exist!" << std::endl; - std::cerr << "UdpStack::removeReceiver() ERROR" << std::endl; -#endif - - return 0; -} - - - -/*****************************************************************************************/ - -UdpSubReceiver::UdpSubReceiver(UdpPublisher *pub) - :mPublisher(pub) -{ - return; -} - -int UdpSubReceiver::sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl) -{ - /* print packet information */ -#ifdef DEBUG_UDP_RECV - std::cerr << "UdpSubReceiver::sendPkt(" << size << ") ttl: " << ttl; - std::cerr << " to: " << to; - std::cerr << std::endl; -#endif - - /* send to udpLayer */ - return mPublisher->sendPkt(data, size, to, ttl); -} - - diff --git a/libbitdht/src/udp/udpstack.h b/libbitdht/src/udp/udpstack.h deleted file mode 100644 index 31b8ec324..000000000 --- a/libbitdht/src/udp/udpstack.h +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * udp/udpstack.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_UDP_STACK_RECEIVER_H -#define BITDHT_UDP_STACK_RECEIVER_H - -#include "util/bdthreads.h" -#include "util/bdnet.h" - -#include -#include -#include - -#include -#include - -#include "udp/udplayer.h" - -/* UdpStackReceiver is a Generic Receiver of info from a UdpLayer class. - * it provides a UdpReceiver class, and accepts a stack of UdpReceivers, - * which will be iterated through (in-order) until someone accepts the packet. - * - * It is important to order these Receivers correctly! - * - * This infact becomes the holder of the UdpLayer, and all controls - * go through the StackReceiver. - */ - -class UdpSubReceiver: public UdpReceiver -{ - public: - UdpSubReceiver(UdpPublisher *pub); - - /* calls mPublisher->sendPkt */ -virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl); - /* callback for recved data (overloaded from UdpReceiver) */ -//virtual int recvPkt(void *data, int size, struct sockaddr_in &from) = 0; - - UdpPublisher *mPublisher; -}; - - -#define UDP_TEST_LOSSY_LAYER 1 -#define UDP_TEST_RESTRICTED_LAYER 2 -#define UDP_TEST_TIMED_LAYER 3 - -#define UDP_TEST_LOSSY_FRAC (0.10) - -class UdpStack: public UdpReceiver, public UdpPublisher -{ - public: - - UdpStack(struct sockaddr_in &local); - UdpStack(int testmode, struct sockaddr_in &local); -virtual ~UdpStack() { return; } - -UdpLayer *getUdpLayer(); /* for testing only */ - -bool getLocalAddress(struct sockaddr_in &local); -bool resetAddress(struct sockaddr_in &local); - - - /* add in a receiver */ -int addReceiver(UdpReceiver *recv); -int removeReceiver(UdpReceiver *recv); - - /* Packet IO */ - /* pass-through send packets */ -virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl); - /* callback for recved data (overloaded from UdpReceiver) */ - -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); - -int status(std::ostream &out); - - /* setup connections */ - int openSocket(); - - /* monitoring / updates */ - int okay(); -// int tick(); - - int close(); - - private: - - UdpLayer *udpLayer; - - bdMutex stackMtx; /* for all class data (below) */ - - struct sockaddr_in laddr; /* local addr */ - - std::list mReceivers; -}; - -#endif diff --git a/libbitdht/src/use_libbitdht.pri b/libbitdht/src/use_libbitdht.pri deleted file mode 100644 index 5758393af..000000000 --- a/libbitdht/src/use_libbitdht.pri +++ /dev/null @@ -1,25 +0,0 @@ -# RetroShare main qmake build script -# -# Copyright (C) 2004-2019, Retroshare Team -# -# This program is free software: you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. -# See the GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License along -# with this program. If not, see . -# -# SPDX-FileCopyrightText: Retroshare Team -# SPDX-License-Identifier: LGPL-3.0-or-later - -DEPENDPATH *= $$system_path($$clean_path($${PWD}/../../libbitdht/src)) -INCLUDEPATH *= $$system_path($$clean_path($${PWD}/../../libbitdht/src)) -LIBS *= -L$$system_path($$clean_path($${OUT_PWD}/../../libbitdht/src/lib/)) -lbitdht - -!equals(TARGET, bitdht):PRE_TARGETDEPS *= $$system_path($$clean_path($${OUT_PWD}/../../libbitdht/src/lib/libbitdht.a)) diff --git a/libbitdht/src/util/bdbloom.cc b/libbitdht/src/util/bdbloom.cc deleted file mode 100644 index 739e2c793..000000000 --- a/libbitdht/src/util/bdbloom.cc +++ /dev/null @@ -1,402 +0,0 @@ -/******************************************************************************* - * util/bdbloom.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/bdbloom.h" -#include "util/bdstring.h" - -#include -#include - -#if defined(_WIN32) || defined(__MINGW32__) -#include -#endif - -/* Bloom Filter implementation */ - - -bloomFilter::bloomFilter(int m, int k) -{ - mBits.resize(m); - mHashFns.resize(k); - - mFilterBits = m; - mNoHashs = k; - mNoElements = 0; - - int i; - for(i = 0; i < m; i++) - { - mBits[i] = 0; - } - - for(i = 0; i < k; i++) - { - mHashFns[i] = NULL; - } - -} - -uint8_t convertCharToUint8(char ch1, char ch2) -{ - uint8_t value1 = 0; - uint8_t value2 = 0; - - /* do char1 */ - if (ch1 >= '0' && ch1 <= '9') - value1 = (ch1 - '0'); - else if (ch1 >= 'A' && ch1 <= 'F') - value1 = (ch1 - 'A' + 10); - else if (ch1 >= 'a' && ch1 <= 'f') - value1 = (ch1 - 'a' + 10); - - /* do char2 */ - if (ch2 >= '0' && ch2 <= '9') - value2 = (ch2 - '0'); - else if (ch2 >= 'A' && ch2 <= 'F') - value2 = (ch2 - 'A' + 10); - else if (ch2 >= 'a' && ch2 <= 'f') - value2 = (ch2 - 'a' + 10); - - uint8_t output = (value1 << 4) + value2; - return output; -} - -#define BITS_PER_BYTE (8) - -int bloomFilter::setFilterBits(const std::string &hex) -{ - uint32_t bytes = (mFilterBits / BITS_PER_BYTE); - if (mFilterBits % BITS_PER_BYTE) - { - bytes++; - } - - if (hex.size() < bytes * 2) - { - return 0; - } - - // convert to binary array. - uint8_t *tmparray = (uint8_t *) malloc(bytes); - - if(tmparray == NULL) - { - std::cerr << "(EE) Error. Cannot allocate memory for " << bytes << " bytes in " << __PRETTY_FUNCTION__ << std::endl; - return 0; - } - - uint32_t i = 0; - - for(i = 0; i < bytes; i++) - { - tmparray[i] = convertCharToUint8(hex[2 * i], hex[2 * i + 1]); - } - - - for(i = 0; i < mFilterBits; i++) - { - int byte = i / BITS_PER_BYTE; - int bit = i % BITS_PER_BYTE; - uint8_t value = (tmparray[byte] & (1 << bit)); - - if (value) - { - mBits[i] = 1; - } - else - { - mBits[i] = 0; - } - } - - free(tmparray); - return 1; -} - -std::string bloomFilter::getFilter() -{ - /* extract filter as a hex string */ - int bytes = (mFilterBits / BITS_PER_BYTE); - if (mFilterBits % BITS_PER_BYTE) - { - bytes++; - } - - if (bytes==0) - { - std::cerr << "(EE) Error. Cannot allocate memory for 0 byte in " << __PRETTY_FUNCTION__ << std::endl; - return std::string(); - } - // convert to binary array. - uint8_t *tmparray = (uint8_t *) malloc(bytes); - - if(tmparray == NULL) - { - std::cerr << "(EE) Error. Cannot allocate memory for " << bytes << " bytes in " << __PRETTY_FUNCTION__ << std::endl; - return std::string(); - } - - int i,j; - - for(i = 0; i < bytes; i++) - { - tmparray[i] = 0; - for(j = 0; j < BITS_PER_BYTE; j++) - { - int bit = i * BITS_PER_BYTE + j; - if (mBits[bit]) - { - tmparray[i] |= (1 << j); - } - } - } - - std::string out; - for(int i = 0; i < bytes; i++) - { - bd_sprintf_append(out, "%02lx", (uint32_t) (tmparray)[i]); - } - - free(tmparray); - - return out; -} - -void bloomFilter::setBit(int bit) -{ - mBits[bit] = 1; - -} - - -bool bloomFilter::isBitSet(int bit) -{ - return (mBits[bit] == 1); -} - -uint32_t bloomFilter::filterBits() -{ - return mFilterBits; -} - -uint32_t bloomFilter::countBits() -{ - int count = 0; - uint32_t i; - for(i = 0; i < mFilterBits; i++) - { - if (mBits[i]) - { - count++; - } - } - return count; -} - - -void bloomFilter::printFilter(std::ostream &out) -{ - out << "bloomFilter: m = " << mFilterBits; - out << " k = " << mNoHashs; - out << " n = " << mNoElements; - out << std::endl; - - out << "BITS: "; - uint32_t i; - for(i = 0; i < mFilterBits; i++) - { - if ((i > 0) && (i % 32 == 0)) - { - out << std::endl; - out << "BITS: "; - } - if (mBits[i]) - { - out << "1"; - } - else - { - out << "0"; - } - } - out << std::endl; - out << "STR: " << getFilter(); - out << std::endl; -} - -void bloomFilter::setHashFunction(int idx, uint32_t (*hashfn)(const std::string &)) -{ - mHashFns[idx] = hashfn; -} - -void bloomFilter::add(const std::string &hex) -{ - uint32_t (*hashfn)(const std::string &); - uint32_t i; - for(i = 0; i < mNoHashs; i++) - { - hashfn = mHashFns[i]; - - int bit = hashfn(hex); - - setBit(bit); - } - - mNoElements++; - -} - -bool bloomFilter::test(const std::string &hex) -{ - uint32_t (*hashfn)(const std::string &); - uint32_t i; - for(i = 0; i < mNoHashs; i++) - { - hashfn = mHashFns[i]; - - int bit = hashfn(hex); - - if (!isBitSet(bit)) - { - return false; - } - } - return true; -} - -uint32_t getFirst10BitsAsNumber(const std::string &input) -{ - if (input.size() < 8) - { - std::cerr << "getFirst10BitsAsNumber() ERROR Size too small!"; - std::cerr << std::endl; - return 0; - } - - uint8_t data[4]; - - data[0] = convertCharToUint8(input[0], input[1]); - data[1] = convertCharToUint8(input[2], input[3]); - data[2] = convertCharToUint8(input[4], input[5]); - data[3] = convertCharToUint8(input[6], input[7]); - - uint32_t val = ((data[0] & 0xff) << 2) + ((data[1] & 0xc0) >> 6); - -#ifdef DEBUG_BLOOM - std::cerr << "getFirst10BitsAsNumber() input: " << input; - std::cerr << std::endl; - std::cerr << "getFirst10BitsAsNumber() "; - std::cerr << " data[0]: " << std::hex << (uint32_t) data[0]; - std::cerr << " data[1]: " << (uint32_t) data[1]; - std::cerr << " data[2]: " << (uint32_t) data[2]; - std::cerr << " data[3]: " << (uint32_t) data[3]; - std::cerr << " val: " << std::dec << (uint32_t) val; - std::cerr << std::endl; -#endif - - return val; -} - -uint32_t getSecond10BitsAsNumber(const std::string &input) -{ - if (input.size() < 8) - { - std::cerr << "getSecond10BitsAsNumber() ERROR Size too small!"; - std::cerr << std::endl; - return 0; - } - - uint8_t data[4]; - - data[0] = convertCharToUint8(input[0], input[1]); - data[1] = convertCharToUint8(input[2], input[3]); - data[2] = convertCharToUint8(input[4], input[5]); - data[3] = convertCharToUint8(input[6], input[7]); - - uint32_t val = ((data[1] & 0x3f) << 4) + ((data[2] & 0xf0) >> 4); - -#ifdef DEBUG_BLOOM - std::cerr << "getSecond10BitsAsNumber() input: " << input; - std::cerr << std::endl; - std::cerr << "getSecond10BitsAsNumber() "; - std::cerr << " data[0]: " << std::hex << (uint32_t) data[0]; - std::cerr << " data[1]: " << (uint32_t) data[1]; - std::cerr << " data[2]: " << (uint32_t) data[2]; - std::cerr << " data[3]: " << (uint32_t) data[3]; - std::cerr << " val: " << std::dec << (uint32_t) val; - std::cerr << std::endl; -#endif - - return val; -} - - -uint32_t getMid10BitsAsNumber(const std::string &input) -{ - if (input.size() < 8) - { - std::cerr << "getMid10BitsAsNumber() ERROR Size too small!"; - std::cerr << std::endl; - return 0; - } - - uint8_t data[4]; - - data[0] = convertCharToUint8(input[0], input[1]); - data[1] = convertCharToUint8(input[2], input[3]); - data[2] = convertCharToUint8(input[4], input[5]); - data[3] = convertCharToUint8(input[6], input[7]); - - uint32_t val = ((data[0] & 0x07) << 7) + ((data[1] & 0x7f) >> 1); - -#ifdef DEBUG_BLOOM - std::cerr << "getMid10BitsAsNumber() input: " << input; - std::cerr << std::endl; - std::cerr << "getMid10BitsAsNumber() "; - std::cerr << " data[0]: " << std::hex << (uint32_t) data[0]; - std::cerr << " data[1]: " << (uint32_t) data[1]; - std::cerr << " data[2]: " << (uint32_t) data[2]; - std::cerr << " data[3]: " << (uint32_t) data[3]; - std::cerr << " val: " << std::dec << (uint32_t) val; - std::cerr << std::endl; -#endif - - return val; -} - - -#define BDFILTER_M 1024 -#define BDFILTER_K 3 - -bdBloom::bdBloom() - :bloomFilter(BDFILTER_M, BDFILTER_K) -{ - /* set the fns. */ - setHashFunction(0, getFirst10BitsAsNumber); - setHashFunction(1, getSecond10BitsAsNumber); - setHashFunction(2, getMid10BitsAsNumber); -} - - - - - diff --git a/libbitdht/src/util/bdbloom.h b/libbitdht/src/util/bdbloom.h deleted file mode 100644 index 8ffd13f1e..000000000 --- a/libbitdht/src/util/bdbloom.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * util/bdbloom.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_BLOOM_H -#define BITDHT_BLOOM_H - -#include -#include - -#include -#include - - -class bloomFilter -{ - public: - - bloomFilter(int m, int k); - -int setFilterBits(const std::string &hex); -std::string getFilter(); - -void printFilter(std::ostream &out); - -bool test(const std::string &hex); // takes first m bits. -void add(const std::string &hex); -uint32_t countBits(); -uint32_t filterBits(); - - protected: -void setHashFunction(int idx, uint32_t (*hashfn)(const std::string &)); - - private: -void setBit(int bit); -bool isBitSet(int bit); - - std::vector mBits; - std::vector mHashFns; - - uint32_t mFilterBits; - uint32_t mNoHashs; - uint32_t mNoElements; -}; - - -/* our specific implementation */ -class bdBloom: public bloomFilter -{ - public: - - bdBloom(); -}; - - -#endif - diff --git a/libbitdht/src/util/bdfile.cc b/libbitdht/src/util/bdfile.cc deleted file mode 100644 index bcd2eb64b..000000000 --- a/libbitdht/src/util/bdfile.cc +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * util/bdfile.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef WIN32 -#include -#endif - -#include -#include -#include -#include "bdfile.h" - -namespace librs { - namespace util { - bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest) ; - } -} - -bool bdFile::renameFile(const std::string& from, const std::string& to) -{ - int loops = 0; - -#ifdef WIN32 - std::wstring f; - librs::util::ConvertUtf8ToUtf16(from, f); - std::wstring t; - librs::util::ConvertUtf8ToUtf16(to, t); - - while (!MoveFileEx(f.c_str(), t.c_str(), MOVEFILE_REPLACE_EXISTING)) -#else - std::string f(from),t(to) ; - - while (rename(from.c_str(), to.c_str()) < 0) -#endif - { -#ifdef WIN32 - if (GetLastError() != ERROR_ACCESS_DENIED) -#else - if (errno != EACCES) -#endif - /* set errno? */ - return false ; -#ifdef WIN32 - Sleep(100000); /* us */ -#else - usleep(100000); /* us */ -#endif - - if (loops >= 30) - return false ; - - loops++; - } - - return true ; -} - diff --git a/libbitdht/src/util/bdnet.cc b/libbitdht/src/util/bdnet.cc deleted file mode 100644 index ba8c33553..000000000 --- a/libbitdht/src/util/bdnet.cc +++ /dev/null @@ -1,363 +0,0 @@ -/******************************************************************************* - * util/bdnet.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bdnet.h" -#include "bdstring.h" - -#include -#include -#include - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#if defined(_WIN32) || defined(__MINGW32__) - -//#define BDNET_DEBUG - -/* error handling */ -int bdnet_int_errno; - -int bdnet_errno() -{ - return bdnet_int_errno; -} - -int bdnet_init() -{ - std::cerr << "bdnet_init()" << std::endl; - bdnet_int_errno = 0; - - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - - return 0; -} - -/* check if we can modify the TTL on a UDP packet */ -int bdnet_checkTTL(int fd) -{ - std::cerr << "bdnet_checkTTL()" << std::endl; - int optlen = 4; - char optval[optlen]; - - int ret = getsockopt(fd, IPPROTO_IP, IP_TTL, optval, &optlen); - //int ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, optval, &optlen); - if (ret == SOCKET_ERROR) - { - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - std::cerr << "bdnet_checkTTL() Failed!"; - std::cerr << std::endl; - } - else - { - std::cerr << "bdnet_checkTTL() :"; - std::cerr << (int) optval[0] << ":"; - std::cerr << (int) optval[1] << ":"; - std::cerr << (int) optval[2] << ":"; - std::cerr << (int) optval[3] << ": RET: "; - std::cerr << ret << ":"; - std::cerr << std::endl; - } - return ret; -} - -int bdnet_close(int fd) -{ - std::cerr << "bdnet_close()" << std::endl; - return closesocket(fd); -} - -int bdnet_socket(int domain, int type, int protocol) -{ - int osock = socket(domain, type, protocol); - std::cerr << "bdnet_socket()" << std::endl; - - if ((unsigned) osock == INVALID_SOCKET) - { - // Invalidate socket Unix style. - osock = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - bdnet_checkTTL(osock); - return osock; -} - -int bdnet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) -{ - std::cerr << "bdnet_bind()" << std::endl; - int ret = bind(sockfd,my_addr,addrlen); - if (ret != 0) - { - /* store unix-style error - */ - - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - return ret; -} - -int bdnet_fcntl(int fd, int cmd, long arg) -{ - int ret; - - unsigned long int on = 1; - std::cerr << "bdnet_fcntl()" << std::endl; - - /* can only do NONBLOCK at the moment */ - if ((cmd != F_SETFL) || (arg != O_NONBLOCK)) - { - std::cerr << "bdnet_fcntl() limited to fcntl(fd, F_SETFL, O_NONBLOCK)"; - std::cerr << std::endl; - bdnet_int_errno = EOPNOTSUPP; - return -1; - } - - ret = ioctlsocket(fd, FIONBIO, &on); - - if (ret != 0) - { - /* store unix-style error - */ - - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - return ret; -} - -int bdnet_setsockopt(int s, int level, int optname, - const void *optval, socklen_t optlen) -{ - std::cerr << "bdnet_setsockopt() val:" << *((int *) optval) << std::endl; - std::cerr << "bdnet_setsockopt() len:" << optlen << std::endl; - if ((level != IPPROTO_IP) || (optname != IP_TTL)) - { - std::cerr << "bdnet_setsockopt() limited to "; - std::cerr << "setsockopt(fd, IPPROTO_IP, IP_TTL, ....)"; - std::cerr << std::endl; - bdnet_int_errno = EOPNOTSUPP; - return -1; - } - - int ret = setsockopt(s, level, optname, (const char *) optval, optlen); - //int ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) optval, optlen); - if (ret == SOCKET_ERROR) - { - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - bdnet_checkTTL(s); - return ret; -} - -ssize_t bdnet_recvfrom(int s, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ -#ifdef BDNET_DEBUG - std::cerr << "bdnet_recvfrom()" << std::endl; -#endif - int ret = recvfrom(s, (char *) buf, len, flags, from, fromlen); - if (ret == SOCKET_ERROR) - { - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - return ret; -} - -ssize_t bdnet_sendto(int s, const void *buf, size_t len, int flags, - const struct sockaddr *to, socklen_t tolen) -{ -#ifdef BDNET_DEBUG - std::cerr << "bdnet_sendto()" << std::endl; -#endif - int ret = sendto(s, (const char *) buf, len, flags, to, tolen); - if (ret == SOCKET_ERROR) - { - ret = -1; - bdnet_int_errno = bdnet_w2u_errno(WSAGetLastError()); - } - return ret; -} - -int bdnet_w2u_errno(int err) -{ - /* switch */ - std::cerr << "tou_net_w2u_errno(" << err << ")" << std::endl; - switch(err) - { - case WSAEINPROGRESS: - return EINPROGRESS; - break; - case WSAEWOULDBLOCK: - return EINPROGRESS; - break; - case WSAENETUNREACH: - return ENETUNREACH; - break; - case WSAETIMEDOUT: - return ETIMEDOUT; - break; - case WSAEHOSTDOWN: - return EHOSTDOWN; - break; - case WSAECONNREFUSED: - return ECONNREFUSED; - break; - case WSAEADDRINUSE: - return EADDRINUSE; - break; - case WSAEUSERS: - return EUSERS; - break; - /* This one is returned for UDP recvfrom, when nothing there - * but not a real error... translate into EINPROGRESS - */ - case WSAECONNRESET: - std::cerr << "tou_net_w2u_errno(" << err << ")"; - std::cerr << " = WSAECONNRESET ---> EINPROGRESS"; - std::cerr << std::endl; - return EINPROGRESS; - break; - /*** - * - case WSAECONNRESET: - return ECONNRESET; - break; - * - ***/ - - case WSANOTINITIALISED: - std::cerr << "tou_net_w2u_errno(" << err << ") WSANOTINITIALISED. Fix Your Code!"; - std::cerr << std::endl; - break; - default: - std::cerr << "tou_net_w2u_errno(" << err << ") Unknown"; - std::cerr << std::endl; - break; - } - - return ECONNREFUSED; /* sensible default? */ -} - -int bdnet_inet_aton(const char *name, struct in_addr *addr) -{ - return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE); -} - -#ifndef __MINGW64_VERSION_MAJOR -int sleep(unsigned int sec) -{ - Sleep(sec * 1000); - return 0; -} -#endif - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else // UNIX - -/* Unix Version is easy -> just call the unix fn - */ - -#include /* for close definition */ - -/* the universal interface */ -int bdnet_init() { return 0; } -int bdnet_errno() { return errno; } - - -/* check if we can modify the TTL on a UDP packet */ -int bdnet_checkTTL(int /*fd*/) { return 1;} - - -int bdnet_inet_aton(const char *name, struct in_addr *addr) -{ - return inet_aton(name, addr); -} - -int bdnet_close(int fd) { return close(fd); } - -int bdnet_socket(int domain, int type, int protocol) -{ - return socket(domain, type, protocol); -} - -int bdnet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) -{ - return bind(sockfd,my_addr,addrlen); -} - -int bdnet_fcntl(int fd, int cmd, long arg) -{ - return fcntl(fd, cmd, arg); -} - -int bdnet_setsockopt(int s, int level, int optname, - const void *optval, socklen_t optlen) -{ - return setsockopt(s, level, optname, optval, optlen); -} - -ssize_t bdnet_recvfrom(int s, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - return recvfrom(s, buf, len, flags, from, fromlen); -} - -ssize_t bdnet_sendto(int s, const void *buf, size_t len, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - return sendto(s, buf, len, flags, to, tolen); -} - - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - -void bdsockaddr_clear(struct sockaddr_in *addr) -{ - memset(addr, 0, sizeof(*addr)); -} - -/* thread-safe version of inet_ntoa */ - -std::string bdnet_inet_ntoa(struct in_addr in) -{ - std::string str; - uint8_t *bytes = (uint8_t *) &(in.s_addr); - bd_sprintf(str, "%u.%u.%u.%u", (int) bytes[0], (int) bytes[1], (int) bytes[2], (int) bytes[3]); - return str; -} diff --git a/libbitdht/src/util/bdnet.h b/libbitdht/src/util/bdnet.h deleted file mode 100644 index 89ecfa710..000000000 --- a/libbitdht/src/util/bdnet.h +++ /dev/null @@ -1,174 +0,0 @@ -/******************************************************************************* - * util/bdnet.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_UNIVERSAL_NETWORK_HEADER -#define BITDHT_UNIVERSAL_NETWORK_HEADER - -#include -#include - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#if defined(_WIN32) || defined(__MINGW32__) - -#include - -#include /* for ssize_t */ -typedef uint32_t in_addr_t; - -#else // UNIX - -#include -#include -#include -#include - -#include -#include - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - - -/* C Interface */ -#ifdef __cplusplus -extern "C" { -#endif - -/******* - * This defines a (unix-like) universal networking layer - * that should function on both windows and unix. (C - interface) - * - * This is of course only a subset of the full interface. - * functions required are: - * - * int bdnet_close(int fd); - * int bdnet_socket(int domain, int type, int protocol); - * int bdnet_bind(int sockfd, const struct sockaddr *my_addr, - * socklen_t addrlen); - * int bdnet_fcntl(int fd, int cmd, long arg); - * int bdnet_setsockopt(int s, int level, int optname, - * const void *optval, socklen_t optlen); - * ssize_t bdnet_recvfrom(int s, void *buf, size_t len, int flags, - * struct sockaddr *from, socklen_t *fromlen); - * ssize_t bdnet_sendto(int s, const void *buf, size_t len, int flags, - * const struct sockaddr *to, socklen_t tolen); - * - * There are some non-standard ones as well: - * int bdnet_errno(); for internal networking errors - * int bdnet_init(); required for windows - * int bdnet_checkTTL(); a check if we can modify the ttl - */ - - -/* the universal interface */ -int bdnet_errno(); /* for internal networking errors */ -int bdnet_init(); /* required for windows */ -int bdnet_close(int fd); -int bdnet_socket(int domain, int type, int protocol); -int bdnet_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); -int bdnet_fcntl(int fd, int cmd, long arg); -int bdnet_setsockopt(int s, int level, int optname, - const void *optval, socklen_t optlen); -ssize_t bdnet_recvfrom(int s, void *buf, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -ssize_t bdnet_sendto(int s, const void *buf, size_t len, int flags, - const struct sockaddr *to, socklen_t tolen); - -/* address filling */ -int bdnet_inet_aton(const char *name, struct in_addr *addr); -/* check if we can modify the TTL on a UDP packet */ -int bdnet_checkTTL(int fd); - -void bdsockaddr_clear(struct sockaddr_in *addr); - -/* Extra stuff to declare for windows error handling (mimics unix errno) - */ - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#if defined(_WIN32) || defined(__MINGW32__) - -// Some Network functions that are missing from windows. -//in_addr_t inet_netof(struct in_addr addr); -//in_addr_t inet_network(char *inet_name); -//int inet_aton(const char *name, struct in_addr *addr); - - -// definitions for fcntl (NON_BLOCK) (random?) -#define F_SETFL 0x1010 -#define O_NONBLOCK 0x0100 - -// definitions for setsockopt (TTL) (random?) -//#define IPPROTO_IP 0x0011 -//#define IP_TTL 0x0110 - -/* define the Unix Error Codes that we use... - * NB. we should make the same, but not necessary - */ - -#define EAGAIN 11 -#define EUSERS 87 - -#define EHOSTDOWN 112 - -#ifndef __MINGW64_VERSION_MAJOR -#define EWOULDBLOCK EAGAIN - -#define ENOTSOCK 88 - -#define EOPNOTSUPP 95 - -#define EADDRINUSE 98 -#define EADDRNOTAVAIL 99 -#define ENETDOWN 100 -#define ENETUNREACH 101 - -#define ECONNRESET 104 - -#define ETIMEDOUT 10060 // value from pthread.h -#define ECONNREFUSED 111 -#define EHOSTUNREACH 113 -#define EALREADY 114 -#define EINPROGRESS 115 -#endif - -int bdnet_w2u_errno(int error); - -/* also put the sleep commands in here (where else to go) - * ms uses millisecs. - * void Sleep(int ms); - */ -#ifndef __MINGW64_VERSION_MAJOR -int sleep(unsigned int sec); -#endif - -#endif // END of WINDOWS defines. -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - -#ifdef __cplusplus -} /* C Interface */ -#endif - -/* thread-safe version of inet_ntoa */ -std::string bdnet_inet_ntoa(struct in_addr in); - -#endif /* BITDHT_UNIVERSAL_NETWORK_HEADER */ diff --git a/libbitdht/src/util/bdrandom.cc b/libbitdht/src/util/bdrandom.cc deleted file mode 100644 index 93a0352dd..000000000 --- a/libbitdht/src/util/bdrandom.cc +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * util/bdrandom.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright (C) 2010 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include -#include "util/bdrandom.h" - -uint32_t bdRandom::index = 0 ; -std::vector bdRandom::MT(bdRandom::N,0u) ; -bdMutex bdRandom::rndMtx ; - -#if (defined(_WIN32) || defined(__MINGW32__)) && !defined(WIN_PTHREADS_H) -static bool auto_seed = bdRandom::seed( (time(NULL) + ((uint32_t) pthread_self().p)*0x1293fe)^0x18e34a12 ) ; -#else - #ifdef __APPLE__ - static bool auto_seed = bdRandom::seed( (time(NULL) + pthread_mach_thread_np(pthread_self())*0x1293fe + (getpid()^0x113ef76b))^0x18e34a12 ) ; - #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__) - static bool auto_seed = bdRandom::seed(arc4random()); - #else - static bool auto_seed = bdRandom::seed( (time(NULL) + pthread_self()*0x1293fe + (getpid()^0x113ef76b))^0x18e34a12 ) ; - #endif -#endif -bool bdRandom::seed(uint32_t s) -{ - bdStackMutex mtx(rndMtx) ; - - MT.resize(N,0) ; // because MT might not be already resized - - uint32_t j ; - MT[0]= s & 0xffffffffUL; - for (j=1; j> 30)) + j) & 0xffffffffUL ; - - return true ; -} - -void bdRandom::locked_next_state() -{ - for(uint32_t i=0;i> 1) ; - - if((y & 1) == 1) - MT[i] = MT[i] ^ 0x9908b0df ; - } - index = 0 ; -} - -uint32_t bdRandom::random_u32() -{ - uint32_t y; - - { - bdStackMutex mtx(rndMtx) ; - - y = MT[index++] ; - - if(index == N) - locked_next_state(); - } - - // Tempering - y ^= (y >> 11); - y ^= (y << 7 ) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); - - return y; -} - -uint64_t bdRandom::random_u64() -{ - return ((uint64_t)random_u32() << 32ul) + random_u32() ; -} - -float bdRandom::random_f32() -{ - return random_u32() / (float)(~(uint32_t)0) ; -} - -double bdRandom::random_f64() -{ - return random_u64() / (double)(~(uint64_t)0) ; -} - -std::string bdRandom::random_alphaNumericString(uint32_t len) -{ - std::string s = "" ; - - for(uint32_t i=0;i * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_UTILS_BDRANDOM_H -#define BITDHT_UTILS_BDRANDOM_H - -/* This Source Code is basically a direct copy of libretroshare's RsRandom. - * the function names have just been renamed. drbob - */ - -// bdRandom contains a random number generator that is -// - thread safe -// - system independant -// - fast -// - NOT CRYPTOGRAPHICALLY SAFE -// - DO NOT USE FOR ANYTHING REQUIRING STRONG UNPREDICTABLE RANDOMNESS -// -// The implementation is adapted from the Mersenne Twister page of Wikipedia. -// -// http://en.wikipedia.org/wiki/Mersenne_twister - -// FIXME(ben): MT is not cryptographically safe. - -#include -#include "util/bdthreads.h" - -class bdRandom -{ - public: - static uint32_t random_u32() ; - static uint64_t random_u64() ; - static float random_f32() ; - static double random_f64() ; - - static bool seed(uint32_t s) ; - - static std::string random_alphaNumericString(uint32_t length) ; - - private: - static bdMutex rndMtx ; - - static const uint32_t N = 624; - static const uint32_t M = 397; - - static const uint32_t MATRIX_A = 0x9908b0dfUL; - static const uint32_t UMASK = 0x80000000UL; - static const uint32_t LMASK = 0x7fffffffUL; - - static void locked_next_state() ; - static uint32_t index ; - static std::vector MT ; -}; - -#endif diff --git a/libbitdht/src/util/bdstring.cc b/libbitdht/src/util/bdstring.cc deleted file mode 100644 index 3808e0c68..000000000 --- a/libbitdht/src/util/bdstring.cc +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * util/bdstring.h * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright (C) 2010 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bdstring.h" - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#endif -#include - -#ifdef _WIN32 -// asprintf() and vasprintf() are missing in Win32 -static int vasprintf(char **sptr, const char *fmt, va_list argv) -{ - int wanted = __mingw_vsnprintf(*sptr = NULL, 0, fmt, argv); - if ((wanted > 0) && ((*sptr = (char*) malloc(wanted + 1)) != NULL)) { - return __mingw_vsprintf(*sptr, fmt, argv); - } - - return wanted; -} - -//static int asprintf(char **sptr, const char *fmt, ...) -//{ -// int retval; -// va_list argv; -// va_start( argv, fmt ); -// retval = vasprintf(sptr, fmt, argv); -// va_end(argv); -// return retval; -//} -#endif - -int bd_sprintf(std::string &str, const char *fmt, ...) -{ - char *buffer = NULL; - va_list ap; - - va_start(ap, fmt); - int retval = vasprintf(&buffer, fmt, ap); - va_end(ap); - - if (retval >= 0) { - if (buffer) { - str = buffer; - free(buffer); - } else { - str.clear(); - } - } else { - str.clear(); - } - - return retval; -} - -int bd_sprintf_append(std::string &str, const char *fmt, ...) -{ - va_list ap; - char *buffer = NULL; - - va_start(ap, fmt); - int retval = vasprintf(&buffer, fmt, ap); - va_end(ap); - - if (retval >= 0) { - if (buffer) { - str.append(buffer); - free(buffer); - } - } - - return retval; -} diff --git a/libbitdht/src/util/bdstring.h b/libbitdht/src/util/bdstring.h deleted file mode 100644 index e9160c663..000000000 --- a/libbitdht/src/util/bdstring.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * util/bdstring.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright (C) 2010 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_UTILS_BDSTRING_H -#define BITDHT_UTILS_BDSTRING_H - -#ifdef WIN32 -// for proper handling of %ll -#define bd_snprintf __mingw_snprintf -#define bd_fprintf __mingw_fprintf -#else -#define bd_snprintf snprintf -#define bd_fprintf fprintf -#endif - -#ifdef __cplusplus - // These definitions are only available for C++ Modules. - #include - - int bd_sprintf(std::string &str, const char *fmt, ...); - int bd_sprintf_append(std::string &str, const char *fmt, ...); -#endif - -#endif diff --git a/libbitdht/src/util/bdthreads.cc b/libbitdht/src/util/bdthreads.cc deleted file mode 100644 index 3fce7ff43..000000000 --- a/libbitdht/src/util/bdthreads.cc +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * util/bdthread.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright (C) 2004-2010 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "bdthreads.h" -#include /* for usleep() */ - -/******* - * #define DEBUG_THREADS 1 - *******/ - -//#define DEBUG_THREADS 1 - -#ifdef DEBUG_THREADS - #include -#endif - -extern "C" void* bdthread_init(void* p) -{ -#ifdef DEBUG_THREADS - std::cerr << "bdthread_init()"; - std::cerr << std::endl; -#endif - - bdThread *thread = (bdThread *) p; - if (!thread) - { -#ifdef DEBUG_THREADS - std::cerr << "bdthread_init() Error Invalid thread pointer."; - std::cerr << std::endl; -#endif - return 0; - } - thread -> run(); - return 0; -} - - -pthread_t createThread(bdThread &thread) -{ - pthread_t tid; - void *data = (void *) (&thread); - -#ifdef DEBUG_THREADS - std::cerr << "createThread() creating a bdThread"; - std::cerr << std::endl; -#endif - - thread.mMutex.lock(); - { - pthread_create(&tid, 0, &bdthread_init, data); - thread.mTid = tid; - } - -#ifdef DEBUG_THREADS - std::cerr << "createThread() created Thread.mTid: "; - -#if defined(_WIN32) || defined(__MINGW32__) - std::cerr << "WIN32: Cannot print mTid "; -#else - std::cerr << thread.mTid; -#endif - std::cerr << std::endl; - -#endif - - thread.mMutex.unlock(); - - - - return tid; - -} - -bdThread::bdThread() -{ - -#ifdef DEBUG_THREADS - std::cerr << "bdThread::bdThread()"; - std::cerr << std::endl; -#endif - -#if defined(_WIN32) || defined(__MINGW32__) - memset (&mTid, 0, sizeof(mTid)); -#else - mTid = 0; -#endif -} - -void bdThread::join() /* waits for the the mTid thread to stop */ -{ -#ifdef DEBUG_THREADS - std::cerr << "bdThread::join() Called! Waiting for Thread.mTid: "; - -#if defined(_WIN32) || defined(__MINGW32__) - std::cerr << "WIN32: Cannot print mTid "; -#else - std::cerr << mTid; -#endif - - std::cerr << std::endl; -#endif - - mMutex.lock(); - { -#if defined(_WIN32) || defined(__MINGW32__) || defined(__APPLE__) - /* Its a struct in Windows compile and the member .p ist checked in the pthreads library */ -#else - if(mTid > 0) -#endif - pthread_join(mTid, NULL); - -#ifdef DEBUG_THREADS - std::cerr << "bdThread::join() Joined Thread.mTid: "; - -#if defined(_WIN32) || defined(__MINGW32__) - std::cerr << "WIN32: Cannot print mTid "; -#else - std::cerr << mTid; -#endif - - std::cerr << std::endl; - std::cerr << "bdThread::join() Setting mTid = 0"; - std::cerr << std::endl; -#endif - -#if defined(_WIN32) || defined(__MINGW32__) - memset (&mTid, 0, sizeof(mTid)); -#else - mTid = 0; -#endif - - } - mMutex.unlock(); - -} - -void bdThread::stop() -{ -#ifdef DEBUG_THREADS - std::cerr << "bdThread::stop() Called!"; - std::cerr << std::endl; -#endif - - pthread_exit(NULL); -} - - - diff --git a/libbitdht/src/util/bdthreads.h b/libbitdht/src/util/bdthreads.h deleted file mode 100644 index 34c48b1bc..000000000 --- a/libbitdht/src/util/bdthreads.h +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * util/bdthread.cc * - * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright (C) 2004-2010 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef BITDHT_THREADS_H -#define BITDHT_THREADS_H - -#include -#include -#include - -/* Thread Wrappers */ - -class bdMutex -{ - public: - - bdMutex(bool recursive = false) - { - /* remove unused parameter warnings */ - (void) recursive; - -#if 0 // TESTING WITHOUT RECURSIVE - if(recursive) - { - pthread_mutexattr_t att ; - pthread_mutexattr_init(&att) ; - pthread_mutexattr_settype(&att,PTHREAD_MUTEX_RECURSIVE) ; - - if( pthread_mutex_init(&realMutex, &att)) - std::cerr << "ERROR: Could not initialize mutex !" << std::endl ; - } - else -#endif - if( pthread_mutex_init(&realMutex, NULL)) - std::cerr << "ERROR: Could not initialize mutex !" << std::endl ; - } - - ~bdMutex() { pthread_mutex_destroy(&realMutex); } - void lock() { pthread_mutex_lock(&realMutex); } - void unlock() { pthread_mutex_unlock(&realMutex); } - bool trylock() { return (0 == pthread_mutex_trylock(&realMutex)); } - - private: - pthread_mutex_t realMutex; -}; - -class bdStackMutex -{ - public: - - bdStackMutex(bdMutex &mtx): mMtx(mtx) { mMtx.lock(); } - ~bdStackMutex() { mMtx.unlock(); } - - private: - bdMutex &mMtx; -}; - -class bdThread; - -/* to create a thread! */ -pthread_t createThread(bdThread &thread); - -class bdThread -{ - public: - bdThread(); -virtual ~bdThread() { return; } - -virtual void start() { createThread(*this); } -virtual void run() = 0; /* called once the thread is started */ -virtual void join(); /* waits for the mTid thread to stop */ -virtual void stop(); /* calls pthread_exit() */ - - pthread_t mTid; - bdMutex mMutex; -}; - - -#endif diff --git a/libretroshare b/libretroshare new file mode 160000 index 000000000..8c02b54e4 --- /dev/null +++ b/libretroshare @@ -0,0 +1 @@ +Subproject commit 8c02b54e4d16e38b28e77263a0b1570c50df4c99 diff --git a/libretroshare/src/Doxyfile b/libretroshare/src/Doxyfile deleted file mode 100644 index 0f5cec54a..000000000 --- a/libretroshare/src/Doxyfile +++ /dev/null @@ -1,1633 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -# Doxyfile 1.7.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "RetroShare libretroshare" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = /var/www/notdefine/retroshare/libretroshare - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = YES - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = YES - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NONE - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvances is that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = YES - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/libretroshare/src/chat/distantchat.cc b/libretroshare/src/chat/distantchat.cc deleted file mode 100644 index 621e92229..000000000 --- a/libretroshare/src/chat/distantchat.cc +++ /dev/null @@ -1,389 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distantchat.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include - -#include "openssl/rand.h" -#include "openssl/dh.h" -#include "openssl/err.h" - -#include "crypto/rsaes.h" -#include "util/rsmemory.h" -#include "util/rsprint.h" - -#include "rsitems/rsmsgitems.h" - -#include "retroshare/rsmsgs.h" -#include "retroshare/rsidentity.h" -#include "retroshare/rsiface.h" - -#include "rsserver/p3face.h" -#include "services/p3idservice.h" -#include "gxs/gxssecurity.h" -#include "turtle/p3turtle.h" -#include "retroshare/rsids.h" -#include "distantchat.h" - -//#define DEBUG_DISTANT_CHAT - -#ifdef DEBUG_DISTANT_CHAT - -#include - -uint32_t msecs_of_day() -{ - timeval tv ; - gettimeofday(&tv,NULL) ; - return tv.tv_usec / 1000 ; -} -#define DISTANT_CHAT_DEBUG() std::cerr << time(NULL) << "." << std::setfill('0') << std::setw(3) << msecs_of_day() << " : DISTANT_CHAT : " << __FUNCTION__ << " : " -#endif - -//static const uint32_t DISTANT_CHAT_KEEP_ALIVE_TIMEOUT = 6 ; // send keep alive packet so as to avoid tunnel breaks. - -//static const uint32_t RS_DISTANT_CHAT_DH_STATUS_UNINITIALIZED = 0x0000 ; -//static const uint32_t RS_DISTANT_CHAT_DH_STATUS_HALF_KEY_DONE = 0x0001 ; -//static const uint32_t RS_DISTANT_CHAT_DH_STATUS_KEY_AVAILABLE = 0x0002 ; - -static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ; - -DistantChatService::DistantChatService() : - // default: accept everyone - mDistantChatPermissions(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE), - mGxsTunnels(nullptr), mDistantChatMtx("distant chat") {} - -void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr) -{ - mGxsTunnels = tr ; - tr->registerClientService(DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,this) ; -} - -bool DistantChatService::handleOutgoingItem(RsChatItem *item) -{ - RsGxsTunnelId tunnel_id ; - - { - RS_STACK_MUTEX(mDistantChatMtx) ; - - std::map::const_iterator it=mDistantChatContacts.find(DistantChatPeerId(item->PeerId())); - - if(it == mDistantChatContacts.end()) - return false ; - } - -#ifdef CHAT_DEBUG - DISTANT_CHAT_DEBUG() << "p3ChatService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl; -#endif - - uint32_t size = RsChatSerialiser().size(item) ; - RsTemporaryMemory mem(size) ; - - if(!RsChatSerialiser().serialise(item,mem,&size)) - { - std::cerr << "(EE) serialisation error. Something's really wrong!" << std::endl; - return false; - } -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << " sending: " << RsUtil::BinToHex(mem,size,100) << std::endl; - DISTANT_CHAT_DEBUG() << " size: " << std::dec << size << std::endl; - DISTANT_CHAT_DEBUG() << " hash: " << RsDirUtil::sha1sum(mem,size) << std::endl; -#endif - - mGxsTunnels->sendData( RsGxsTunnelId(item->PeerId()),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,mem,size); - return true; -} - -void DistantChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) -{ - if(cs->flags & RS_CHAT_FLAG_CONNEXION_REFUSED) - { -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "(II) Distant chat: received notification that peer refuses conversation." << std::endl; -#endif - RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(cs->PeerId())),"Connexion refused by distant peer!") ; - } - - if(cs->flags & RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION) - markDistantChatAsClosed(DistantChatPeerId(cs->PeerId())) ; - - // nothing more to do, because the decryption routing will update the last_contact time when decrypting. - - if(cs->flags & RS_CHAT_FLAG_KEEP_ALIVE) - std::cerr << "DistantChatService::handleRecvChatStatusItem(): received keep alive packet for inactive chat! peerId=" << cs->PeerId() << std::endl; -} - -bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool am_I_client_side) -{ - if(am_I_client_side) // always accept distant chat when we're the client side. - return true ; - - bool res = true ; - - if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS) - res = (rsIdentity!=NULL) && rsIdentity->isARegularContact(gxs_id) ; - - if(mDistantChatPermissions & RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY) - res = false ; - - if(!res) - { -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "(II) refusing distant chat from peer " << gxs_id << ". Sending a notification back to tunnel " << tunnel_id << std::endl; -#endif - RsChatStatusItem *item = new RsChatStatusItem ; - item->flags = RS_CHAT_FLAG_CONNEXION_REFUSED ; - item->status_string.clear() ; // is not used yet! But could be set in GUI to some message (??). - item->PeerId(RsPeerId(tunnel_id)) ; - - // we do not use handleOutGoingItem() because there's no distant chat contact, as the chat is refused. - - uint32_t size = RsChatSerialiser().size(item) ; - RsTemporaryMemory mem(size) ; - - if(!RsChatSerialiser().serialise(item,mem,&size)) - { - std::cerr << "(EE) serialisation error. Something's really wrong!" << std::endl; - return false; - } - -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << " sending: " << RsUtil::BinToHex(mem,size,100) << std::endl; - DISTANT_CHAT_DEBUG() << " size: " << std::dec << std::endl; - DISTANT_CHAT_DEBUG() << " hash: " << RsDirUtil::sha1sum(mem,size) << std::endl; -#endif - - mGxsTunnels->sendData( RsGxsTunnelId(item->PeerId()),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,mem,size); - } - - return res ; -} - -void DistantChatService::notifyTunnelStatus( const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status ) -{ -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl; -#endif - - switch(tunnel_status) - { - default: - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: std::cerr << "(EE) don't know how to handle RS_GXS_TUNNEL_STATUS_UNKNOWN !" << std::endl; - break ; - - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"Tunnel is secured. You can talk!") ; - RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_ONLINE) ; - break ; - - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"Tunnel is down...") ; - RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ; - break ; - - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(tunnel_id)),"Tunnel is down...") ; - RsServer::notify()->notifyPeerStatusChanged(tunnel_id.toStdString(),RS_STATUS_OFFLINE) ; - break ; - } -} - -void DistantChatService::receiveData( const RsGxsTunnelId& tunnel_id, unsigned char* data, uint32_t data_size) -{ -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "DistantChatService::receiveData(): got data of size " << std::dec << data_size << " for tunnel " << tunnel_id << std::endl; - DISTANT_CHAT_DEBUG() << " received: " << RsUtil::BinToHex(data,data_size,100) << std::endl; - DISTANT_CHAT_DEBUG() << " hash: " << RsDirUtil::sha1sum(data,data_size) << std::endl; - DISTANT_CHAT_DEBUG() << " deserialising..." << std::endl; -#endif - - // always make the contact up to date. This is useful for server side, which doesn't know about the chat until it - // receives the first item. - { - RS_STACK_MUTEX(mDistantChatMtx) ; - - RsGxsTunnelService::GxsTunnelInfo tinfo; - if(!mGxsTunnels->getTunnelInfo(tunnel_id,tinfo)) - return ; - - // Check if the data is accepted. We cannot prevent the creation of tunnels at the level of p3GxsTunnels, since tunnels are shared between services. - // however, - - DistantChatContact& contact(mDistantChatContacts[DistantChatPeerId(tunnel_id)]) ; - - contact.to_id = tinfo.destination_gxs_id ; - contact.from_id = tinfo.source_gxs_id ; - } - - RsItem *item = RsChatSerialiser().deserialise(data,&data_size) ; - - if(item != NULL) - { - item->PeerId(RsPeerId(tunnel_id)) ; // just in case, but normally this is already done. - - handleIncomingItem(item) ; - RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD); - } - else - std::cerr << " (EE) item could not be deserialised!" << std::endl; -} - -void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid) -{ - mGxsTunnels->closeExistingTunnel( - RsGxsTunnelId(dcpid), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID ); - - RS_STACK_MUTEX(mDistantChatMtx) ; - - std::map::iterator it = mDistantChatContacts.find(dcpid) ; - - if(it != mDistantChatContacts.end()) - mDistantChatContacts.erase(it) ; -} - -bool DistantChatService::initiateDistantChatConnexion( - const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, - DistantChatPeerId& dcpid, uint32_t& error_code, bool notify ) -{ - RsGxsTunnelId tunnel_id ; - - if(!mGxsTunnels->requestSecuredTunnel(to_gxs_id,from_gxs_id,tunnel_id,DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID,error_code)) - return false ; - - dcpid = DistantChatPeerId(tunnel_id) ; - - DistantChatContact& dc_contact(mDistantChatContacts[dcpid]) ; - - dc_contact.from_id = from_gxs_id ; - dc_contact.to_id = to_gxs_id ; - - error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ; - - if(notify) - { - // Make a self message to raise the chat window - RsChatMsgItem *item = new RsChatMsgItem; - item->message = "[Starting distant chat. Please wait for secure tunnel"; - item->message += " to be established]"; - item->chatFlags = RS_CHAT_FLAG_PRIVATE; - item->sendTime = time(NULL); - item->PeerId(RsPeerId(tunnel_id)); - handleRecvChatMsgItem(item); - delete item ; - } - - return true ; -} - -bool DistantChatService::getDistantChatStatus(const DistantChatPeerId& tunnel_id, DistantChatPeerInfo& cinfo) -{ - RS_STACK_MUTEX(mDistantChatMtx); - - RsGxsTunnelService::GxsTunnelInfo tinfo; - - if(!mGxsTunnels->getTunnelInfo(RsGxsTunnelId(tunnel_id),tinfo)) return false; - - cinfo.to_id = tinfo.destination_gxs_id; - cinfo.own_id = tinfo.source_gxs_id; - cinfo.pending_items = tinfo.pending_data_packets; - cinfo.peer_id = tunnel_id; - - switch(tinfo.tunnel_status) - { - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_CAN_TALK : cinfo.status = RS_DISTANT_CHAT_STATUS_CAN_TALK; break; - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_TUNNEL_DN: cinfo.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN; break; - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED: cinfo.status = RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED; break; - case RsGxsTunnelService::RS_GXS_TUNNEL_STATUS_UNKNOWN: - default: - cinfo.status = RS_DISTANT_CHAT_STATUS_UNKNOWN; break; - } - - return true; -} - -bool DistantChatService::closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) -{ - mGxsTunnels->closeExistingTunnel(RsGxsTunnelId(tunnel_id), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ; - - // also remove contact. Or do we wait for the notification? - - return true ; -} - -uint32_t DistantChatService::getDistantChatPermissionFlags() -{ - return mDistantChatPermissions ; -} -bool DistantChatService::setDistantChatPermissionFlags(uint32_t flags) -{ - if(mDistantChatPermissions != flags) - { - mDistantChatPermissions = flags ; -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "(II) Changing distant chat permissions to " << flags << ". Existing openned chats will however remain active until closed" << std::endl; -#endif - triggerConfigSave() ; - } - - return true ; -} - -void DistantChatService::addToSaveList(std::list& list) const -{ - /* Save permission flags */ - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "DISTANT_CHAT_PERMISSION_FLAGS" ; - kv.value = RsUtil::NumberToString(mDistantChatPermissions) ; - - vitem->tlvkvs.pairs.push_back(kv) ; - - list.push_back(vitem) ; -} -bool DistantChatService::processLoadListItem(const RsItem *item) -{ - const RsConfigKeyValueSet *vitem = NULL ; - - if(NULL != (vitem = dynamic_cast(item))) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - if(kit->key == "DISTANT_CHAT_PERMISSION_FLAGS") - { -#ifdef DEBUG_DISTANT_CHAT - DISTANT_CHAT_DEBUG() << "Loaded distant chat permission flags: " << kit->value << std::endl ; -#endif - if (!kit->value.empty()) - { - std::istringstream is(kit->value) ; - - uint32_t tmp ; - is >> tmp ; - - if(tmp < 3) - mDistantChatPermissions = tmp ; - else - std::cerr << "(EE) Invalid value read for DistantChatPermission flags in config: " << tmp << std::endl; - } - - return true; - } - - return false ; -} - diff --git a/libretroshare/src/chat/distantchat.h b/libretroshare/src/chat/distantchat.h deleted file mode 100644 index eda55da49..000000000 --- a/libretroshare/src/chat/distantchat.h +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distantchat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include -#include -#include - -class RsGixs ; - -static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ; - -/** - * Public interface only uses DistandChatPeerId, but internally, this is - * converted into a RsGxsTunnelId - */ -class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService -{ -public: - DistantChatService() ; - - virtual void triggerConfigSave()=0 ; - bool processLoadListItem(const RsItem *item) ; - void addToSaveList(std::list& list) const; - - /** - * Creates the invite if the public key of the distant peer is available. - * On success, stores the invite in the map above, so that we can respond - * to tunnel requests. */ - bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id, - const RsGxsId &from_gxs_id, - DistantChatPeerId& dcpid, - uint32_t &error_code, - bool notify = true ); - bool closeDistantChatConnexion(const DistantChatPeerId &tunnel_id) ; - - // Sets flags to only allow connexion from some people. - - uint32_t getDistantChatPermissionFlags() ; - bool setDistantChatPermissionFlags(uint32_t flags) ; - - // Returns the status of a distant chat contact. The contact is defined by the tunnel id (turned into a DistantChatPeerId) because - // each pair of talking GXS id needs to be treated separately - - virtual bool getDistantChatStatus(const DistantChatPeerId &tunnel_id, DistantChatPeerInfo& cinfo) ; - - // derived in p3ChatService, so as to pass down some info - virtual void handleIncomingItem(RsItem *) = 0; - virtual bool handleRecvChatMsgItem(RsChatMsgItem *& ci)=0 ; - - bool handleOutgoingItem(RsChatItem *) ; - bool handleRecvItem(RsChatItem *) ; - void handleRecvChatStatusItem(RsChatStatusItem *cs) ; - -private: - struct DistantChatContact - { - RsGxsId from_id ; - RsGxsId to_id ; - }; - // This maps contains the current peers to talk to with distant chat. - // - std::map mDistantChatContacts ; // current peers we can talk to - - // Permission handling - - uint32_t mDistantChatPermissions ; - - // Overloaded from RsGxsTunnelClientService - -public: - virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ; - -private: - virtual bool acceptDataFromPeer( - const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id, - bool am_I_client_side); - virtual void notifyTunnelStatus( - const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status); - virtual void receiveData( - const RsGxsTunnelId& id, unsigned char* data, uint32_t data_size ); - - // Utility functions. - - void markDistantChatAsClosed(const DistantChatPeerId& dcpid) ; - - RsGxsTunnelService *mGxsTunnels ; - RsMutex mDistantChatMtx ; -}; diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc deleted file mode 100644 index 4112afd31..000000000 --- a/libretroshare/src/chat/distributedchat.cc +++ /dev/null @@ -1,2205 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distributedchat.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include - -#include "util/rsprint.h" -#include "util/rsmemory.h" -#include "distributedchat.h" - -#include "pqi/p3historymgr.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsiface.h" -#include "retroshare/rsidentity.h" -#include "rsserver/p3face.h" -#include "gxs/rsgixs.h" -#include "services/p3idservice.h" - -//#define DEBUG_CHAT_LOBBIES 1 - -static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connection challenge every 20 messages -static const rstime_t CONNECTION_CHALLENGE_MAX_MSG_AGE = 30 ; // maximum age of a message to be used in a connection challenge -static const int CONNECTION_CHALLENGE_MIN_DELAY = 15 ; // sends a connection at most every 15 seconds -static const int LOBBY_CACHE_CLEANING_PERIOD = 10 ; // clean lobby caches every 10 secs (remove old messages) - -static const rstime_t MAX_KEEP_MSG_RECORD = 1200 ; // keep msg record for 1200 secs max. -static const rstime_t MAX_KEEP_INACTIVE_NICKNAME = 180 ; // keep inactive nicknames for 3 mn max. -static const rstime_t MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE = 120 ; // send keep alive packet every 2 minutes. -static const rstime_t MAX_KEEP_PUBLIC_LOBBY_RECORD = 60 ; // keep inactive lobbies records for 60 secs max. -static const rstime_t MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ = 20 ; // don't ask for lobby list more than once every 30 secs. -static const rstime_t LOBBY_LIST_AUTO_UPDATE_TIME = 121 ; // regularly ask for available lobbies every 5 minutes, to allow auto-subscribe to work - -static const uint32_t MAX_ALLOWED_LOBBIES_IN_LIST_WARNING = 50 ; -//static const uint32_t MAX_MESSAGES_PER_SECONDS_NUMBER = 5 ; // max number of messages from a given peer in a window for duration below -static const uint32_t MAX_MESSAGES_PER_SECONDS_PERIOD = 10 ; // duration window for max number of messages before messages get dropped. - -#define IS_PUBLIC_LOBBY(flags) (flags & RS_CHAT_LOBBY_FLAGS_PUBLIC ) -#define IS_PGP_SIGNED_LOBBY(flags) (flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) -#define IS_CONNEXION_CHALLENGE(flags) (flags & RS_CHAT_LOBBY_FLAGS_CHALLENGE ) - -#define EXTRACT_PRIVACY_FLAGS(flags) (ChatLobbyFlags(flags.toUInt32()) * (RS_CHAT_LOBBY_FLAGS_PUBLIC | RS_CHAT_LOBBY_FLAGS_PGP_SIGNED)) - -DistributedChatService::DistributedChatService(uint32_t serv_type,p3ServiceControl *sc,p3HistoryMgr *hm, RsGixs *is) - : mServType(serv_type),mDistributedChatMtx("Distributed Chat"), mServControl(sc), mHistMgr(hm),mGixs(is) -{ - _time_shift_average = 0.0f ; - _should_reset_lobby_counts = false ; - last_visible_lobby_info_request_time = 0 ; -} - -void DistributedChatService::flush() -{ - static rstime_t last_clean_time_lobby = 0 ; - static rstime_t last_req_chat_lobby_list = 0 ; - - rstime_t now = time(NULL) ; - - if(last_clean_time_lobby + LOBBY_CACHE_CLEANING_PERIOD < now) - { - cleanLobbyCaches() ; - last_clean_time_lobby = now ; - - // also make sure that the default identity is not null - - if(_default_identity.isNull()) - { - std::list ids ; - mGixs->getOwnIds(ids) ; - - if(!ids.empty()) - { - _default_identity = ids.front() ; - triggerConfigSave() ; - } - } - } - if(last_req_chat_lobby_list + LOBBY_LIST_AUTO_UPDATE_TIME < now) - { - std::vector visible_lobbies_tmp ; - getListOfNearbyChatLobbies(visible_lobbies_tmp) ; - - if (visible_lobbies_tmp.empty()){ - last_req_chat_lobby_list = now-LOBBY_LIST_AUTO_UPDATE_TIME+MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ; - } else { - last_req_chat_lobby_list = now ; - } - } -} - -bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci) -{ - // check if it's a lobby msg, in which case we replace the peer id by the lobby's virtual peer id. - // - RsChatLobbyMsgItem *cli = dynamic_cast(ci) ; - - if(cli == NULL) - return true ; // the item is handled correctly if it's not a lobby item ;-) - - rstime_t now = time(NULL) ; - - if(now+100 > (rstime_t) cli->sendTime + MAX_KEEP_MSG_RECORD) // the message is older than the max cache keep plus 100 seconds ! It's too old, and is going to make an echo! - { - std::cerr << "Received severely outdated lobby event item (" << now - (rstime_t)cli->sendTime << " in the past)! Dropping it!" << std::endl; - std::cerr << "Message item is:" << std::endl; - cli->print(std::cerr) ; - std::cerr << std::endl; - return false ; - } - if(now+600 < (rstime_t) cli->sendTime) // the message is from the future. Drop it. more than 10 minutes - { - std::cerr << "Received event item from the future (" << (rstime_t)cli->sendTime - now << " seconds in the future)! Dropping it!" << std::endl; - std::cerr << "Message item is:" << std::endl; - cli->print(std::cerr) ; - std::cerr << std::endl; - return false ; - } - - if( rsReputations->overallReputationLevel(cli->signature.keyId) == - RsReputationLevel::LOCALLY_NEGATIVE ) - { - std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl; - return false ; - } - if(!checkSignature(cli,cli->PeerId())) // check the object's signature and possibly request missing keys - { - std::cerr << "Signature mismatched for this lobby event item. Item will be dropped: " << std::endl; - cli->print(std::cerr) ; - std::cerr << std::endl; - return false; - } - - // add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous - - rsGRouter->addRoutingClue(GRouterKeyId(cli->signature.keyId),cli->PeerId()) ; - - ChatLobbyFlags fl ; - - // delete items that are not for us, as early as possible. - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - // send upward for display - - std::map::const_iterator it = _chat_lobbys.find(cli->lobby_id) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Chatlobby for id " << std::hex << cli->lobby_id << " has no record. Dropping the msg." << std::dec << std::endl; -#endif - return false; - } - fl = it->second.lobby_flags ; - } - if(IS_PGP_SIGNED_LOBBY(fl)) - { - RsIdentityDetails details; - - if(!rsIdentity->getIdDetails(cli->signature.keyId,details)) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "(WW) cannot get ID " << cli->signature.keyId << " for checking signature of lobby item." << std::endl; -#endif - return false; - } - - if(!(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) - { - std::cerr << "(WW) Received a lobby msg/item that is not PGP-authed (id=" << cli->signature.keyId << "), whereas the lobby flags require it. Rejecting!" << std::endl; - - return false ; - } - } - - if(!bounceLobbyObject(cli,cli->PeerId())) // forwards the message to friends, keeps track of subscribers, etc. - return false; - - // setup the peer id to the virtual peer id of the lobby. - // - RsPeerId virtual_peer_id ; - getVirtualPeerId(cli->lobby_id,virtual_peer_id) ; - cli->PeerId(virtual_peer_id) ; - - //name = cli->nick; - //popupChatFlag = RS_POPUP_CHATLOBBY; - - RsServer::notify()->AddPopupMessage(RS_POPUP_CHATLOBBY, ChatId(cli->lobby_id).toStdString(), cli->signature.keyId.toStdString(), cli->message); /* notify private chat message */ - - return true ; -} - -bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) -{ - // Always request the key. If not present, it will be asked to the peer id who sent this item. - - std::list peer_list ; - peer_list.push_back(peer_id) ; - - // network pre-request key to allow message authentication. - - mGixs->requestKey(obj->signature.keyId,peer_list,RsIdentityUsage(RsServiceType::CHAT, - RsIdentityUsage::CHAT_LOBBY_MSG_VALIDATION, - RsGxsGroupId(), - RsGxsMessageId(), - RsGxsMessageId(), - RsGxsMessageId(), - obj->lobby_id)); - - uint32_t size = RsChatSerialiser(RsSerializationFlags::SIGNATURE) - .size(dynamic_cast(obj)); - RsTemporaryMemory memory(size) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Checking object signature: " << std::endl; - std::cerr << " signature id: " << obj->signature.keyId << std::endl; -#endif - - if( !RsChatSerialiser(RsSerializationFlags::SIGNATURE) - .serialise(dynamic_cast(obj),memory,&size) ) - { - std::cerr << " (EE) Cannot serialise message item. " << std::endl; - return false ; - } - - uint32_t error_status ; - RsIdentityUsage use_info(RsServiceType::CHAT, - RsIdentityUsage::CHAT_LOBBY_MSG_VALIDATION, - RsGxsGroupId(), - RsGxsMessageId(), - RsGxsMessageId(), - RsGxsMessageId(), - obj->lobby_id) ; - - if(!mGixs->validateData(memory,size,obj->signature,false,use_info,error_status)) - { - bool res = false ; - - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "(WW) Key is not is cache. Cannot verify." << std::endl; -#endif - res =true ; - break ; - case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: std::cerr << "(EE) Signature mismatch. Spoofing/MITM?." << std::endl; - res =false ; - break ; - default: break ; - } - return res; - } - - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " signature: CHECKS" << std::endl; -#endif - - return true ; -} - -bool DistributedChatService::getVirtualPeerId(const ChatLobbyId& id,ChatLobbyVirtualPeerId& vpid) -{ - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Was asked for virtual peer name of " << std::hex << id << std::dec<< std::endl; -#endif - std::map::const_iterator it(_chat_lobbys.find(id)) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " not found!! " << std::endl; -#endif - return false ; - } - - vpid = it->second.virtual_peer_id ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " returning " << vpid << std::endl; -#endif - return true ; -} - -void DistributedChatService::locked_printDebugInfo() const -{ - std::cerr << "Recorded lobbies: " << std::endl; - rstime_t now = time(NULL) ; - - for( std::map::const_iterator it(_chat_lobbys.begin()) ;it!=_chat_lobbys.end();++it) - { - std::cerr << " Lobby id\t\t: " << std::hex << it->first << std::dec << std::endl; - std::cerr << " Lobby name\t\t: " << it->second.lobby_name << std::endl; - std::cerr << " Lobby topic\t\t: " << it->second.lobby_topic << std::endl; - std::cerr << " nick name\t\t: " << it->second.gxs_id << std::endl; - std::cerr << " Lobby type\t\t: " << ((IS_PUBLIC_LOBBY(it->second.lobby_flags))?"Public":"Private") << std::endl; - std::cerr << " Lobby security\t\t: " << ((IS_PGP_SIGNED_LOBBY(it->second.lobby_flags))?"PGP-signed IDs required":"Anon IDs accepted") << std::endl; - std::cerr << " Lobby peer id\t: " << it->second.virtual_peer_id << std::endl; - std::cerr << " Challenge count\t: " << it->second.connexion_challenge_count << std::endl; - std::cerr << " Last activity\t: " << now - it->second.last_activity << " seconds ago." << std::endl; - std::cerr << " Cached messages\t: " << it->second.msg_cache.size() << std::endl; - - for(std::map::const_iterator it2(it->second.msg_cache.begin());it2!=it->second.msg_cache.end();++it2) - std::cerr << " " << std::hex << it2->first << std::dec << " time=" << now - it2->second << " secs ago" << std::endl; - - std::cerr << " Participating friends: " << std::endl; - - for(std::set::const_iterator it2(it->second.participating_friends.begin());it2!=it->second.participating_friends.end();++it2) - std::cerr << " " << *it2 << std::endl; - - std::cerr << " Participating nick names: " << std::endl; - - for(std::map::const_iterator it2(it->second.gxs_ids.begin());it2!=it->second.gxs_ids.end();++it2) - std::cerr << " " << it2->first << ": " << now - it2->second << " secs ago" << std::endl; - - } - - std::cerr << "Visible public lobbies: " << std::endl; - - for( std::map::const_iterator it(_visible_lobbies.begin()) ;it!=_visible_lobbies.end();++it) - { - std::cerr << " " << std::hex << it->first << " name = " << std::dec << it->second.lobby_name << it->second.lobby_topic << std::endl; - for(std::set::const_iterator it2(it->second.participating_friends.begin());it2!=it->second.participating_friends.end();++it2) - std::cerr << " With friend: " << *it2 << std::endl; - } - - std::cerr << "Chat lobby flags: " << std::endl; - - for( std::map::const_iterator it(_known_lobbies_flags.begin()) ;it!=_known_lobbies_flags.end();++it) - std::cerr << " \"" << std::hex << it->first << "\" flags = " << it->second << std::dec << std::endl; -} - -bool DistributedChatService::locked_bouncingObjectCheck(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id,uint32_t lobby_count) -{ - static std::map > message_counts ; - - std::ostringstream os ; - os << obj->lobby_id ; - - std::string pid = peer_id.toStdString() + "_" + os.str() ; - - // Check for the number of peers in the lobby. First look into visible lobbies, because the number - // of peers there is more accurate. If non existant (because it's a private lobby), take the count from - // the current lobby list. - // - std::map::const_iterator it = _visible_lobbies.find(obj->lobby_id) ; - - if(it != _visible_lobbies.end()) - lobby_count = it->second.total_number_of_peers ; - else - { - std::map::const_iterator it = _chat_lobbys.find(obj->lobby_id) ; - - if(it != _chat_lobbys.end()) - lobby_count = it->second.gxs_ids.size() ; - else - { - std::cerr << "DistributedChatService::locked_bouncingObjectCheck(): weird situation: cannot find lobby in visible lobbies nor current lobbies. Dropping message. If you see this, contact the developers." << std::endl; - return false ; - } - } - - // max objects per second: lobby_count * 1/MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE objects per second. - // So in cache, there is in average that number times MAX_MESSAGES_PER_SECONDS_PERIOD - // - float max_cnt = std::max(10.0f, 10*lobby_count / (float)MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE * MAX_MESSAGES_PER_SECONDS_PERIOD) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "lobby_count=" << lobby_count << std::endl; - std::cerr << "Got msg for peer " << pid << std::dec << ". Limit is " << max_cnt << ". List is " ; - for(std::list::const_iterator it(message_counts[pid].begin());it!=message_counts[pid].end();++it) - std::cerr << *it << " " ; - std::cerr << std::endl; -#endif - - rstime_t now = time(NULL) ; - - std::list& lst = message_counts[pid] ; - - // Clean old messages time stamps from the list. - // - while(!lst.empty() && lst.front() + MAX_MESSAGES_PER_SECONDS_PERIOD < now) - lst.pop_front() ; - - if(lst.size() > max_cnt) - { - std::cerr << "(WW) more than " << max_cnt << " messages forwarded by peer " << pid << ". Message from \"" << obj->nick << "\" will not be forwarded." << std::endl; - return false; - } - else - lst.push_back(now) ; - - return true ; -} - -// This function should be used for all types of chat messages. But this requires a non backward compatible change in -// chat protocol. To be done for version 0.6 -// -void DistributedChatService::checkSizeAndSendLobbyMessage(RsChatItem *msg) -{ - // Multiple-parts messaging has been disabled in lobbies, because of the following issues: - // 1 - it breaks signatures because the subid of each sub-item is changed (can be fixed) - // 2 - it breaks (can be fixed as well) - // 3 - it is unreliable since items are not guarrantied to all arrive in the end (cannot be fixed) - // 4 - large objects can be used to corrupt end peers (cannot be fixed) - // - static const uint32_t MAX_ITEM_SIZE = 32000 ; - - if(RsChatSerialiser().size(msg) > MAX_ITEM_SIZE) - { - std::cerr << "(EE) Chat item exceeds maximum serial size. It will be dropped." << std::endl; - delete msg ; - return ; - } - sendChatItem(msg) ; -} - -bool DistributedChatService::handleRecvItem(RsChatItem *item) -{ - switch(item->PacketSubType()) - { - case RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT: handleRecvChatLobbyEventItem (dynamic_cast(item)) ; break ; - case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED: handleRecvLobbyInvite_Deprecated (dynamic_cast(item)) ; break ; // to be removed (deprecated since May 2017) - case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE: handleRecvLobbyInvite (dynamic_cast(item)) ; break ; - case RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE: handleConnectionChallenge (dynamic_cast(item)) ; break ; - case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: handleFriendUnsubscribeLobby (dynamic_cast(item)) ; break ; - case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: handleRecvChatLobbyListRequest (dynamic_cast(item)) ; break ; - case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: handleRecvChatLobbyList (dynamic_cast(item)) ; break ; - default: return false ; - } - return true ; -} - -void DistributedChatService::handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *clr) -{ - // make a lobby list item - // - RsChatLobbyListItem *item = new RsChatLobbyListItem; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Peer " << clr->PeerId() << " requested the list of public chat lobbies." << std::endl; -#endif - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::const_iterator it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it) - { - const ChatLobbyEntry& lobby(it->second) ; - - if(IS_PUBLIC_LOBBY(lobby.lobby_flags) || - (lobby.previously_known_peers.find(clr->PeerId()) != lobby.previously_known_peers.end() - ||lobby.participating_friends.find(clr->PeerId()) != lobby.participating_friends.end()) ) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Adding lobby " << std::hex << it->first << std::dec << " \"" - << it->second.lobby_name << it->second.lobby_topic << "\" count=" << it->second.gxs_ids.size() << std::endl; -#endif - - VisibleChatLobbyInfo info ; - - info.id = it->first ; - info.name = it->second.lobby_name ; - info.topic = it->second.lobby_topic ; - info.count = it->second.gxs_ids.size() ; - info.flags = ChatLobbyFlags(EXTRACT_PRIVACY_FLAGS(it->second.lobby_flags)) ; - - item->lobbies.push_back(info) ; - } -#ifdef DEBUG_CHAT_LOBBIES - else - std::cerr << " Not adding private lobby " << std::hex << it->first << std::dec << std::endl ; -#endif - } - } - - item->PeerId(clr->PeerId()) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Sending list to " << clr->PeerId() << std::endl; -#endif - sendChatItem(item); -} - -void DistributedChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item) -{ - if(item->lobbies.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING) - std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobbies.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl; - - std::list chatLobbyToSubscribe; - std::list invitationNeeded ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Received chat lobby list from friend " << item->PeerId() << ", " << item->lobbies.size() << " elements." << std::endl; -#endif - { - rstime_t now = time(NULL) ; - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - for(uint32_t i=0;ilobbies.size() && i < MAX_ALLOWED_LOBBIES_IN_LIST_WARNING;++i) - { - VisibleChatLobbyRecord& rec(_visible_lobbies[item->lobbies[i].id]) ; - - rec.lobby_id = item->lobbies[i].id ; - rec.lobby_name = item->lobbies[i].name ; - rec.lobby_topic = item->lobbies[i].topic ; - rec.participating_friends.insert(item->PeerId()) ; - - if(_should_reset_lobby_counts) - rec.total_number_of_peers = item->lobbies[i].count ; - else - rec.total_number_of_peers = std::max(rec.total_number_of_peers,item->lobbies[i].count) ; - - rec.last_report_time = now ; - rec.lobby_flags = EXTRACT_PRIVACY_FLAGS(item->lobbies[i].flags) ; - - std::map::const_iterator it(_known_lobbies_flags.find(item->lobbies[i].id)) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " lobby id " << std::hex << item->lobbies[i].id << std::dec << ", " << item->lobbies[i].name - << ", " << item->lobbies[i].count << " participants" << std::endl; -#endif - if(it != _known_lobbies_flags.end() && (it->second & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE)) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " lobby is flagged as autosubscribed. Adding it to subscribe list." << std::endl; -#endif - ChatLobbyId clid = item->lobbies[i].id; - if(_chat_lobbys.find(clid) == _chat_lobbys.end()) - chatLobbyToSubscribe.push_back(clid); - } - - // for subscribed lobbies, check that item->PeerId() is among the participating friends. If not, add him! - - std::map::iterator it2 = _chat_lobbys.find(item->lobbies[i].id) ; - - if(it2 != _chat_lobbys.end() && it2->second.participating_friends.find(item->PeerId()) == it2->second.participating_friends.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " lobby is currently subscribed but friend is not participating already -> adding to partipating friends and sending invite." << std::endl; -#endif - it2->second.participating_friends.insert(item->PeerId()) ; - invitationNeeded.push_back(item->lobbies[i].id) ; - } - } - } - - std::list::iterator it; - for (it = chatLobbyToSubscribe.begin(); it != chatLobbyToSubscribe.end(); ++it) - { - RsGxsId gxsId = _lobby_default_identity[*it]; - if (gxsId.isNull()) - gxsId = _default_identity; - - //Check if gxsId can connect to this lobby - ChatLobbyFlags flags(0); - std::map::const_iterator vlIt = _visible_lobbies.find(*it) ; - if(vlIt != _visible_lobbies.end()) - flags = vlIt->second.lobby_flags; - else - { - std::map::const_iterator clIt = _chat_lobbys.find(*it) ; - - if(clIt != _chat_lobbys.end()) - flags = clIt->second.lobby_flags; - } - - RsIdentityDetails idd ; - if(!rsIdentity->getIdDetails(gxsId,idd)) - std::cerr << "(EE) Lobby auto-subscribe: Can't get Id detail for:" << gxsId.toStdString().c_str() << std::endl; - else - { - if(IS_PGP_SIGNED_LOBBY(flags) - && !(idd.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ) - { - std::cerr << "(EE) Attempt to auto-subscribe to signed lobby with non signed Id. Remove it." << std::endl; - setLobbyAutoSubscribe(*it, false); - } else { - joinVisibleChatLobby(*it,gxsId); - } - } - } - - for(std::list::const_iterator it = invitationNeeded.begin();it!=invitationNeeded.end();++it) - invitePeerToLobby(*it,item->PeerId(),false) ; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - _should_reset_lobby_counts = false ; -} - -void DistributedChatService::addTimeShiftStatistics(int D) -{ - static const int S = 50 ; // accuracy up to 2^50 second. Quite conservative! - static int total = 0 ; - static std::vector log_delay_histogram(S,0) ; - - int delay = (D<0)?(-D):D ; - - if(delay < 0) - delay = -delay ; - - // compute log2. - int l = 0 ; - while(delay > 0) delay >>= 1, ++l ; - - int bin = std::min(S-1,l) ; - ++log_delay_histogram[bin] ; - ++total ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "New delay stat item. delay=" << D << ", log=" << bin << " total=" << total << ", histogram = " ; - - for(int i=0;i 30) - { - float t = 0.0f ; - int i=0 ; - for(;i0 so i is incremented - if(log_delay_histogram[i-1] == 0) return ; // cannot happen, either, but let's be cautious. - - float expected = ( i * (log_delay_histogram[i-1] - t + total*0.5) + (i-1) * (t - total*0.5) ) / (float)log_delay_histogram[i-1] - 1; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << ". Expected delay: " << expected << std::endl ; -#endif - - if(expected > 9) // if more than 20 samples - RsServer::notify()->notifyChatLobbyTimeShift( (int)pow(2.0f,expected)) ; - - total = 0.0f ; - log_delay_histogram.clear() ; - log_delay_histogram.resize(S,0) ; - } -#ifdef DEBUG_CHAT_LOBBIES - else - std::cerr << std::endl; -#endif -} - -void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item) -{ - ChatLobbyFlags fl ; - - // delete items that are not for us, as early as possible. - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - // send upward for display - - std::map::const_iterator it = _chat_lobbys.find(item->lobby_id) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Chatlobby for id " << std::hex << item->lobby_id << " has no record. Dropping the msg." << std::dec << std::endl; -#endif - return ; - } - fl = it->second.lobby_flags ; - } - - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Received ChatLobbyEvent item of type " << (int)(item->event_type) << ", and string=" << item->string1 << std::endl; -#endif - rstime_t now = time(nullptr); - - if( rsReputations->overallReputationLevel(item->signature.keyId) == - RsReputationLevel::LOCALLY_NEGATIVE ) - { - std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl; - return ; - } - if(!checkSignature(item,item->PeerId())) // check the object's signature and possibly request missing keys - { - std::cerr << "Signature mismatched for this lobby event item: " << std::endl; - item->print(std::cerr) ; - std::cerr << std::endl; - return ; - } - - if(IS_PGP_SIGNED_LOBBY(fl)) - { - RsIdentityDetails details; - - if(!rsIdentity->getIdDetails(item->signature.keyId,details)) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "(WW) cannot get ID " << item->signature.keyId << " for checking signature of lobby item." << std::endl; -#endif - return ; - } - - if(!(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) - { - std::cerr << "(WW) Received a lobby msg/item that is not PGP-authed (ID=" << item->signature.keyId << "), whereas the lobby flags require it. Rejecting!" << std::endl; - return ; - } - } - addTimeShiftStatistics((int)now - (int)item->sendTime) ; - - if(now+100 > (rstime_t) item->sendTime + MAX_KEEP_MSG_RECORD) // the message is older than the max cache keep minus 100 seconds ! It's too old, and is going to make an echo! - { - std::cerr << "Received severely outdated lobby event item (" << now - (rstime_t)item->sendTime << " in the past)! Dropping it!" << std::endl; - std::cerr << "Message item is:" << std::endl; - item->print(std::cerr) ; - std::cerr << std::endl; - return ; - } - if(now+600 < (rstime_t) item->sendTime) // the message is from the future more than 10 minutes - { - std::cerr << "Received event item from the future (" << (rstime_t)item->sendTime - now << " seconds in the future)! Dropping it!" << std::endl; - std::cerr << "Message item is:" << std::endl; - item->print(std::cerr) ; - std::cerr << std::endl; - return ; - } - // add a routing clue for this peer/GXSid combination. This is quite reliable since the lobby transport is almost instantaneous - rsGRouter->addRoutingClue(GRouterKeyId(item->signature.keyId),item->PeerId()) ; - - if(! bounceLobbyObject(item,item->PeerId())) - return ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " doing specific job for this status item." << std::endl; -#endif - - if(item->event_type == RS_CHAT_LOBBY_EVENT_PEER_LEFT) // if a peer left. Remove its nickname from the list. - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removing nickname " << item->nick << " from lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _chat_lobbys.find(item->lobby_id) ; - - if(it != _chat_lobbys.end()) - { - std::map::iterator it2(it->second.gxs_ids.find(item->signature.keyId)) ; - - if(it2 != it->second.gxs_ids.end()) - { - it->second.gxs_ids.erase(it2) ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removed id " << item->signature.keyId << " from lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - } -#ifdef DEBUG_CHAT_LOBBIES - else - std::cerr << " (EE) nickname " << item->nick << " not in participant nicknames list!" << std::endl; -#endif - } - } - else if(item->event_type == RS_CHAT_LOBBY_EVENT_PEER_JOINED) // if a joined left. Add its nickname to the list. - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " adding nickname " << item->nick << " to lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _chat_lobbys.find(item->lobby_id) ; - - if(it != _chat_lobbys.end()) - { - it->second.gxs_ids[item->signature.keyId] = time(NULL) ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " added nickname " << item->nick << " from lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - // trigger a keep alive packets so as to inform the new participant of our presence in the chatroom - it->second.last_keep_alive_packet_time = 0 ; - } - } - else if(item->event_type == RS_CHAT_LOBBY_EVENT_KEEP_ALIVE) // keep alive packet. - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " adding nickname " << item->nick << " to lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _chat_lobbys.find(item->lobby_id) ; - - if(it != _chat_lobbys.end()) - { - it->second.gxs_ids[item->signature.keyId] = time(NULL) ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " added nickname " << item->nick << " from lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - } - } - - RsServer::notify()->notifyChatLobbyEvent(item->lobby_id,item->event_type,item->signature.keyId,item->string1); -} - -void DistributedChatService::getListOfNearbyChatLobbies(std::vector& visible_lobbies) -{ - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - visible_lobbies.clear() ; - - for(std::map::const_iterator it(_visible_lobbies.begin());it!=_visible_lobbies.end();++it) - visible_lobbies.push_back(it->second) ; - } - - rstime_t now = time(NULL) ; - - if(now > MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ + last_visible_lobby_info_request_time) - { - std::set ids ; - mServControl->getPeersConnected(mServType, ids); - - for(std::set::const_iterator it(ids.begin());it!=ids.end();++it) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " asking list of public lobbies to " << *it << std::endl; -#endif - RsChatLobbyListRequestItem *item = new RsChatLobbyListRequestItem ; - item->PeerId(*it) ; - - sendChatItem(item); - } - last_visible_lobby_info_request_time = now ; - _should_reset_lobby_counts = true ; - } -} - -// returns: -// true: the object is not a duplicate and should be used -// false: the object is a duplicate or there is an error, and it should be destroyed. -// -bool DistributedChatService::bounceLobbyObject(RsChatLobbyBouncingObject *item,const RsPeerId& peer_id) -{ - rstime_t now = time(NULL) ; - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ -#ifdef DEBUG_CHAT_LOBBIES - locked_printDebugInfo() ; // debug - - std::cerr << "Handling ChatLobbyMsg " << std::hex << item->msg_id << ", lobby id " << item->lobby_id << ", from peer id " << peer_id << std::endl; -#endif - - // send upward for display - - std::map::iterator it(_chat_lobbys.find(item->lobby_id)) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Chatlobby for id " << std::hex << item->lobby_id << " has no record. Dropping the msg." << std::dec << std::endl; -#endif - return false ; - } - - ChatLobbyEntry& lobby(it->second) ; - - // Adds the peer id to the list of friend participants, even if it's not original msg source - - if(peer_id != mServControl->getOwnId()) - lobby.participating_friends.insert(peer_id) ; - - lobby.gxs_ids[item->signature.keyId] = now ; - - // Checks wether the msg is already recorded or not - - std::map::iterator it2(lobby.msg_cache.find(item->msg_id)) ; - - if(it2 != lobby.msg_cache.end()) // found! - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Msg already received at time " << it2->second << ". Dropping!" << std::endl ; -#endif - it2->second = now ; // update last msg seen time, to prevent echos. - return false ; - } -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Msg not received already. Adding in cache, and forwarding!" << std::endl ; -#endif - - lobby.msg_cache[item->msg_id] = now ; - lobby.last_activity = now ; - - // Check that if we have a lobby bouncing object, it's not flooding the lobby - if(!locked_bouncingObjectCheck(item,peer_id,lobby.participating_friends.size())) - return false; - - // Forward to allparticipating friends, except this peer. - - for(std::set::const_iterator it(lobby.participating_friends.begin());it!=lobby.participating_friends.end();++it) - if((*it)!=peer_id && mServControl->isPeerConnected(mServType, *it)) - { - RsChatLobbyBouncingObject *obj2 = item->duplicate() ; // makes a copy - RsChatItem *item2 = dynamic_cast(obj2) ; - - assert(item2 != NULL) ; - - item2->PeerId(*it) ; // replaces the virtual peer id with the actual destination. - - checkSizeAndSendLobbyMessage(item2) ; - } - - ++lobby.connexion_challenge_count ; - - return true ; -} - -void DistributedChatService::sendLobbyStatusString(const ChatLobbyId& lobby_id,const std::string& status_string) -{ - sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_PEER_STATUS,status_string) ; -} - -/** - * Inform other Clients of a nickname change - * - * as example for updating their ChatLobby Blocklist for muted peers - * */ -void DistributedChatService::sendLobbyStatusPeerChangedNickname(const ChatLobbyId& lobby_id, const std::string& newnick) -{ - sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME, newnick) ; -} - - -void DistributedChatService::sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) -{ - sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_PEER_LEFT,std::string()) ; -} - -void DistributedChatService::sendLobbyStatusNewPeer(const ChatLobbyId& lobby_id) -{ - sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_PEER_JOINED,std::string()) ; -} - -void DistributedChatService::sendLobbyStatusKeepAlive(const ChatLobbyId& lobby_id) -{ - sendLobbyStatusItem(lobby_id,RS_CHAT_LOBBY_EVENT_KEEP_ALIVE,std::string()) ; -} - -void DistributedChatService::sendLobbyStatusItem(const ChatLobbyId& lobby_id,int type,const std::string& status_string) -{ - RsChatLobbyEventItem item ; - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - item.event_type = type ; - item.string1 = status_string ; - item.sendTime = time(NULL) ; - - if(! locked_initLobbyBouncableObject(lobby_id,item)) - return ; - } - RsPeerId ownId = mServControl->getOwnId(); - bounceLobbyObject(&item,ownId) ; -} - -bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId& lobby_id,RsChatLobbyBouncingObject& item) -{ - // get a pointer to the info for that chat lobby. - // - std::map::iterator it(_chat_lobbys.find(lobby_id)) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Chatlobby for id " << std::hex << lobby_id << " has no record. This is a serious error!!" << std::dec << std::endl; -#endif - return false; - } - ChatLobbyEntry& lobby(it->second) ; - - // chat lobby stuff - // - do - { - item.msg_id = RSRandom::random_u64(); - } - while( lobby.msg_cache.find(item.msg_id) != lobby.msg_cache.end() ) ; - - RsIdentityDetails details ; - if(!rsIdentity || !rsIdentity->getIdDetails(lobby.gxs_id,details)) - { - std::cerr << "(EE) Cannot send chat lobby object. Signign identity " << lobby.gxs_id << " is unknown." << std::endl; - return false ; - } - - item.lobby_id = lobby_id ; - item.nick = details.mNickname ; - item.signature.TlvClear() ; - item.signature.keyId = lobby.gxs_id ; - - // now sign the object, if the lobby expects it - - uint32_t size = RsChatSerialiser(RsSerializationFlags::SIGNATURE) - .size(dynamic_cast(&item)); - RsTemporaryMemory memory(size) ; - - if( !RsChatSerialiser(RsSerializationFlags::SIGNATURE) - .serialise(dynamic_cast(&item),memory,&size) ) - { - std::cerr << "(EE) Cannot sign message item. " << std::endl; - return false ; - } - - uint32_t error_status ; - - if(!mGixs->signData(memory,size,lobby.gxs_id,item.signature,error_status)) - { - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Cannot sign item: key not available for ID " << lobby.gxs_id << std::endl; - break ; - default: std::cerr << "(EE) Cannot sign item: unknown error" << std::endl; - break ; - } - return false ; - } - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " signature done." << std::endl; - - // check signature - if(!mGixs->validateData(memory,item.signed_serial_size(),item.signature,true,error_status)) - { - std::cerr << "(EE) Cannot check message item. " << std::endl; - return false ; - } - std::cerr << " signature checks!" << std::endl; - std::cerr << " Item dump:" << std::endl; - item.print(std::cerr,2) ; -#endif - - return true ; -} - -bool DistributedChatService::sendLobbyChat(const ChatLobbyId& lobby_id, const std::string& msg) -{ -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl; - std::cerr << "msg:" << std::endl; - std::cerr << msg << std::endl; -#endif - - RsChatLobbyMsgItem item ; - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - // chat msg stuff - // - item.chatFlags = RS_CHAT_FLAG_LOBBY | RS_CHAT_FLAG_PRIVATE; - item.sendTime = time(NULL); - item.recvTime = item.sendTime; - item.message = msg; - item.parent_msg_id = 0; - - // gives a random msg id, setup the nickname, and signs the item. - - if(! locked_initLobbyBouncableObject(lobby_id,item)) - return false; - } - - RsPeerId ownId = rsPeers->getOwnId(); - - bounceLobbyObject(&item, ownId) ; - - ChatMessage message; - message.chatflags = 0; - message.chat_id = ChatId(lobby_id); - message.msg = msg; - message.lobby_peer_gxs_id = item.signature.keyId; - message.recvTime = item.recvTime; - message.sendTime = item.sendTime; - message.incoming = false; - message.online = true; - RsServer::notify()->notifyChatMessage(message); - mHistMgr->addMessage(message); - - return true ; -} - -void DistributedChatService::handleConnectionChallenge(RsChatLobbyConnectChallengeItem *item) -{ - // Look into message cache of all lobbys to handle the challenge. - // -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "DistributedChatService::handleConnectionChallenge(): received connection challenge:" << std::endl; - std::cerr << " Challenge code = 0x" << std::hex << item->challenge_code << std::dec << std::endl; - std::cerr << " Peer Id = " << item->PeerId() << std::endl; -#endif - - rstime_t now = time(NULL) ; - ChatLobbyId lobby_id ; - const RsPeerId& ownId = rsPeers->getOwnId(); - - bool found = false ; - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::iterator it(_chat_lobbys.begin());it!=_chat_lobbys.end() && !found;++it) - for(std::map::const_iterator it2(it->second.msg_cache.begin());it2!=it->second.msg_cache.end() && !found;++it2) - if(it2->second + CONNECTION_CHALLENGE_MAX_MSG_AGE + 5 > now) // any msg not older than 5 seconds plus max challenge count is fine. - { - uint64_t code = makeConnexionChallengeCode(ownId,it->first,it2->first) ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Lobby_id = 0x" << std::hex << it->first << ", msg_id = 0x" << it2->first << ": code = 0x" << code << std::dec << std::endl ; -#endif - if(code == item->challenge_code) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Challenge accepted for lobby " << std::hex << it->first << ", for chat msg " << it2->first << std::dec << std::endl ; - std::cerr << " Sending connection request to peer " << item->PeerId() << std::endl; -#endif - - lobby_id = it->first ; - found = true ; - - // also add the peer to the list of participating friends - it->second.participating_friends.insert(item->PeerId()) ; - } - } - } - - if(found) // send invitation. As the peer already has the lobby, the invitation will most likely be accepted. - invitePeerToLobby(lobby_id, item->PeerId(),true) ; -#ifdef DEBUG_CHAT_LOBBIES - else - std::cerr << " Challenge denied: no existing cached msg has matching Id." << std::endl; -#endif -} - -void DistributedChatService::sendConnectionChallenge(ChatLobbyId lobby_id) -{ - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Sending connection challenge to friends for lobby 0x" << std::hex << lobby_id << std::dec << std::endl ; -#endif - - // look for a msg in cache. Any recent msg is fine. - - std::map::const_iterator it = _chat_lobbys.find(lobby_id) ; - - if(it == _chat_lobbys.end()) - { - std::cerr << "ERROR: sendConnectionChallenge(): could not find lobby 0x" << std::hex << lobby_id << std::dec << std::endl; - return ; - } - - rstime_t now = time(NULL) ; - ChatLobbyMsgId msg_id = 0 ; - - for(std::map::const_iterator it2(it->second.msg_cache.begin());it2!=it->second.msg_cache.end();++it2) - if(it2->second + CONNECTION_CHALLENGE_MAX_MSG_AGE > now) // any msg not older than 20 seconds is fine. - { - msg_id = it2->first ; -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Using msg id 0x" << std::hex << it2->first << std::dec << std::endl; -#endif - break ; - } - - if(msg_id == 0) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " No suitable message found in cache. Probably not enough activity !!" << std::endl; -#endif - return ; - } - - // Broadcast to all direct friends - - std::set ids ; - mServControl->getPeersConnected(mServType, ids); - - for(std::set::const_iterator it(ids.begin());it!=ids.end();++it) - { - RsChatLobbyConnectChallengeItem *item = new RsChatLobbyConnectChallengeItem ; - - uint64_t code = makeConnexionChallengeCode(*it,lobby_id,msg_id) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Sending collexion challenge code 0x" << std::hex << code << std::dec << " to peer " << *it << std::endl; -#endif - item->PeerId(*it) ; - item->challenge_code = code ; - - sendChatItem(item); - } -} - -uint64_t DistributedChatService::makeConnexionChallengeCode(const RsPeerId& peer_id,ChatLobbyId lobby_id,ChatLobbyMsgId msg_id) -{ - uint64_t result = 0 ; - - for(uint32_t i=0;i> 35 ; - result += result << 6 ; - result ^= peer_id.toByteArray()[i] * lobby_id ; - result += result << 26 ; - result ^= result >> 13 ; - } - return result ; -} - -void DistributedChatService::getChatLobbyList(std::list& clids) -{ - // fill up a dummy list for now. - - clids.clear() ; - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::const_iterator it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it) - clids.push_back(it->first) ; -} - -bool DistributedChatService::getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) -{ - // fill up a dummy list for now. - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - - std::map::const_iterator it = _chat_lobbys.find(id) ; - - if(it != _chat_lobbys.end()) - { - info = it->second ; - return true ; - } - else - return false ; -} - -void DistributedChatService::invitePeerToLobby(const ChatLobbyId& lobby_id, const RsPeerId& peer_id,bool connexion_challenge) -{ -#ifdef DEBUG_CHAT_LOBBIES - if(connexion_challenge) - std::cerr << "Sending connection challenge accept to peer " << peer_id << " for lobby "<< std::hex << lobby_id << std::dec << std::endl; - else - std::cerr << "Sending invitation to peer " << peer_id << " to lobby "<< std::hex << lobby_id << std::dec << std::endl; -#endif - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _chat_lobbys.find(lobby_id) ; - - if(it == _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " invitation send: canceled. Lobby " << lobby_id << " not found!" << std::endl; -#endif - return ; - } - - RsChatLobbyInviteItem *item = new RsChatLobbyInviteItem ; - - item->lobby_id = lobby_id ; - item->lobby_name = it->second.lobby_name ; - item->lobby_topic = it->second.lobby_topic ; - item->lobby_flags = connexion_challenge?RS_CHAT_LOBBY_FLAGS_CHALLENGE:(it->second.lobby_flags) ; - item->PeerId(peer_id) ; - - sendChatItem(item) ; - - //FOR BACKWARD COMPATIBILITY - {// to be removed (deprecated since May 2017) - RsChatLobbyInviteItem_Deprecated *item = new RsChatLobbyInviteItem_Deprecated ; - - item->lobby_id = lobby_id ; - item->lobby_name = it->second.lobby_name ; - item->lobby_topic = it->second.lobby_topic ; - item->lobby_flags = connexion_challenge?RS_CHAT_LOBBY_FLAGS_CHALLENGE:(it->second.lobby_flags) ; - item->PeerId(peer_id) ; - - sendChatItem(item) ; - } -} - -// to be removed (deprecated since May 2017) -void DistributedChatService::handleRecvLobbyInvite_Deprecated(RsChatLobbyInviteItem_Deprecated *item) -{ -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Received deprecated invite to lobby from " << item->PeerId() << " to lobby " << std::hex << item->lobby_id << std::dec << ", named " << item->lobby_name << item->lobby_topic << std::endl; -#endif - RsChatLobbyInviteItem newItem ; - - newItem.lobby_id = item->lobby_id ; - newItem.lobby_name = item->lobby_name ; - newItem.lobby_topic = item->lobby_topic ; - newItem.lobby_flags = item->lobby_flags ; - newItem.PeerId( item->PeerId() ); - - handleRecvLobbyInvite(&newItem); // The item is not deleted inside this function. -} - -void DistributedChatService::handleRecvLobbyInvite(RsChatLobbyInviteItem *item) -{ -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Received invite to lobby from " << item->PeerId() << " to lobby " << std::hex << item->lobby_id << std::dec << ", named " << item->lobby_name << item->lobby_topic << std::endl; -#endif - - // 1 - store invite in a cache - // - // 1.1 - if the lobby is already setup, add the peer to the communicating peers. - // - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _chat_lobbys.find(item->lobby_id) ; - - if(it != _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Lobby already exists. " << std::endl; - std::cerr << " privacy levels: " << item->lobby_flags << " vs. " << it->second.lobby_flags ; -#endif - - if ((!IS_CONNEXION_CHALLENGE(item->lobby_flags)) && EXTRACT_PRIVACY_FLAGS(item->lobby_flags) != EXTRACT_PRIVACY_FLAGS(it->second.lobby_flags)) - { - std::cerr << " : Don't match. Cancelling." << std::endl; - return ; - } -#ifdef DEBUG_CHAT_LOBBIES - else - std::cerr << " : Match!" << std::endl; - - std::cerr << " Adding new friend " << item->PeerId() << " to lobby." << std::endl; -#endif - - // to be removed (deprecated since May 2017) - { //Update Topics if have received deprecated before (withou topic) - if(it->second.lobby_topic.empty() && !item->lobby_topic.empty()) - it->second.lobby_topic = item->lobby_topic; - } - - it->second.participating_friends.insert(item->PeerId()) ; - return ; - } - - // to be removed (deprecated since May 2017) - {//check if invitation is already received by deprecated version - std::map::const_iterator it(_lobby_invites_queue.find( item->lobby_id)) ; - if(it != _lobby_invites_queue.end()) - return ; - } - // Don't record the invitation if it's a challenge response item or a lobby we don't have. - // - if(IS_CONNEXION_CHALLENGE(item->lobby_flags)) - return ; - - // no, then create a new invitation entry in the cache. - - ChatLobbyInvite invite ; - invite.lobby_id = item->lobby_id ; - invite.peer_id = item->PeerId() ; - invite.lobby_name = item->lobby_name ; - invite.lobby_topic = item->lobby_topic ; - invite.lobby_flags = item->lobby_flags ; - - _lobby_invites_queue[item->lobby_id] = invite ; - } - // 2 - notify the gui to ask the user. - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_INVITATION, NOTIFY_TYPE_ADD); -} - -void DistributedChatService::getPendingChatLobbyInvites(std::list& invites) -{ - invites.clear() ; - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::const_iterator it(_lobby_invites_queue.begin());it!=_lobby_invites_queue.end();++it) - invites.push_back(it->second) ; -} - - -bool DistributedChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id,const RsGxsId& identity) -{ - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Accepting chat lobby "<< lobby_id << std::endl; -#endif - - std::map::iterator it = _lobby_invites_queue.find(lobby_id) ; - - if(it == _lobby_invites_queue.end()) - { - std::cerr << " (EE) lobby invite not in cache!!" << std::endl; - return false; - } - - //std::map::const_iterator vid = _visible_lobbies.find(lobby_id) ; - - //When invited to new Lobby, it is not visible. - //if(_visible_lobbies.end() == vid) - //{ - // std::cerr << " (EE) Cannot subscribe a non visible chat lobby!!" << std::endl; - // return false ; - //} - - RsIdentityDetails det ; - if( (!rsIdentity->getIdDetails(identity,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID)) - { - std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is not ours! Something's wrong here." << std::endl; - return false ; - } - - if( (it->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) - { - std::cerr << " (EE) Cannot subscribe with identity " << identity << " because it is unsigned and the lobby requires signed ids only." << std::endl; - return false ; - } - - if(_chat_lobbys.find(lobby_id) != _chat_lobbys.end()) - { - std::cerr << " (II) Lobby already exists. Weird." << std::endl; - return true ; - } - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Creating new Lobby entry." << std::endl; -#endif - rstime_t now = time(NULL) ; - - ChatLobbyEntry entry ; - entry.participating_friends.insert(it->second.peer_id) ; - entry.lobby_flags = it->second.lobby_flags ; - entry.gxs_id = identity ; - entry.lobby_id = lobby_id ; - entry.lobby_name = it->second.lobby_name ; - entry.lobby_topic = it->second.lobby_topic ; - entry.virtual_peer_id = makeVirtualPeerId(lobby_id) ; - entry.connexion_challenge_count = 0 ; - entry.last_activity = now ; - entry.last_connexion_challenge_time = now ; - entry.joined_lobby_packet_sent = false; - entry.last_keep_alive_packet_time = now ; - - _chat_lobbys[lobby_id] = entry ; - - _lobby_invites_queue.erase(it) ; // remove the invite from cache. - - // we should also send a message to the lobby to tell we're here. - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Pushing new msg item to incoming msgs." << std::endl; -#endif - RsChatLobbyMsgItem *item = new RsChatLobbyMsgItem; - item->lobby_id = entry.lobby_id ; - item->msg_id = 0 ; - item->parent_msg_id = 0 ; - item->nick = "Chat room management" ; - item->message = std::string("Welcome to chat lobby") ; - item->PeerId(entry.virtual_peer_id) ; - item->chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_LOBBY ; - - locked_storeIncomingMsg(item) ; - } -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Notifying of new recvd msg." << std::endl ; -#endif - - RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD); - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD); - - // send AKN item - sendLobbyStatusNewPeer(lobby_id) ; - - return true ; -} - -ChatLobbyVirtualPeerId DistributedChatService::makeVirtualPeerId(ChatLobbyId lobby_id) -{ - uint8_t bytes[RsPeerId::SIZE_IN_BYTES] ; - memset(bytes,0,RsPeerId::SIZE_IN_BYTES) ; - memcpy(bytes,&lobby_id,sizeof(lobby_id)) ; - - return ChatLobbyVirtualPeerId(bytes) ; -} - - -void DistributedChatService::denyLobbyInvite(const ChatLobbyId& lobby_id) -{ - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Denying chat lobby invite to "<< lobby_id << std::endl; -#endif - std::map::iterator it = _lobby_invites_queue.find(lobby_id) ; - - if(it == _lobby_invites_queue.end()) - { - std::cerr << " (EE) lobby invite not in cache!!" << std::endl; - return ; - } - - _lobby_invites_queue.erase(it) ; -} - -bool DistributedChatService::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& gxs_id) -{ - RsIdentityDetails det ; - if( (!rsIdentity->getIdDetails(gxs_id,det)) || !(det.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID)) - { - std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is not ours! Something's wrong here." << std::endl; - return false ; - } - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Joining public chat lobby " << std::hex << lobby_id << std::dec << std::endl; -#endif - std::list invited_friends ; - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - // create a unique id. - // - std::map::const_iterator it(_visible_lobbies.find(lobby_id)) ; - - if(it == _visible_lobbies.end()) - { - std::cerr << " lobby is not a known public chat lobby. Sorry!" << std::endl; - return false ; - } - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " lobby found. Initiating join sequence..." << std::endl; -#endif - - if(_chat_lobbys.find(lobby_id) != _chat_lobbys.end()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " lobby already in participating list. Returning!" << std::endl; -#endif - return true ; - } - - if( (it->second.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ) && !(det.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) - { - std::cerr << " (EE) Cannot subscribe with identity " << gxs_id << " because it is unsigned and the lobby requires signed ids only." << std::endl; - return false ; - } - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " Creating new lobby entry." << std::endl; -#endif - rstime_t now = time(NULL) ; - - ChatLobbyEntry entry ; - - entry.lobby_flags = it->second.lobby_flags ;//RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ; - entry.participating_friends.clear() ; - entry.gxs_id = gxs_id ; - entry.lobby_id = lobby_id ; - entry.lobby_name = it->second.lobby_name ; - entry.lobby_topic = it->second.lobby_topic ; - entry.virtual_peer_id = makeVirtualPeerId(lobby_id) ; - entry.connexion_challenge_count = 0 ; - entry.last_activity = now ; - entry.last_connexion_challenge_time = now ; - entry.joined_lobby_packet_sent = false; - entry.last_keep_alive_packet_time = now ; - - for(std::set::const_iterator it2(it->second.participating_friends.begin());it2!=it->second.participating_friends.end();++it2) - { - invited_friends.push_back(*it2) ; - entry.participating_friends.insert(*it2) ; - } - _chat_lobbys[lobby_id] = entry ; - } - - setLobbyAutoSubscribe(lobby_id,true); - - triggerConfigSave(); // so that we save the subscribed lobbies - - for(std::list::const_iterator it(invited_friends.begin());it!=invited_friends.end();++it) - invitePeerToLobby(lobby_id,*it) ; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - sendLobbyStatusNewPeer(lobby_id) ; - - return true ; -} - -ChatLobbyId DistributedChatService::createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set& invited_friends,ChatLobbyFlags lobby_flags) -{ -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Creating a new Chat lobby !!" << std::endl; -#endif - ChatLobbyId lobby_id ; - { - if (!rsIdentity->isOwnId(lobby_identity)) - { - RsErr() << __PRETTY_FUNCTION__ << " lobby_identity RsGxsId id must be own" << std::endl; - return 0; - } - - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - // create a unique id. - // - do { lobby_id = RSRandom::random_u64() ; } while(_chat_lobbys.find(lobby_id) != _chat_lobbys.end()) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " New (unique) ID: " << std::hex << lobby_id << std::dec << std::endl; -#endif - rstime_t now = time(NULL) ; - - ChatLobbyEntry entry ; - entry.lobby_flags = lobby_flags ; - entry.participating_friends.clear() ; - entry.gxs_id = lobby_identity ; // to be changed. For debug only!! - entry.lobby_id = lobby_id ; - entry.lobby_name = lobby_name ; - entry.lobby_topic = lobby_topic ; - entry.virtual_peer_id = makeVirtualPeerId(lobby_id) ; - entry.connexion_challenge_count = 0 ; - entry.last_activity = now ; - entry.last_connexion_challenge_time = now ; - entry.joined_lobby_packet_sent = false; - entry.last_keep_alive_packet_time = now ; - - _chat_lobbys[lobby_id] = entry ; - } - - for(std::set::const_iterator it(invited_friends.begin());it!=invited_friends.end();++it) - invitePeerToLobby(lobby_id,*it) ; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - - triggerConfigSave(); - - return lobby_id ; -} - -void DistributedChatService::handleFriendUnsubscribeLobby(RsChatLobbyUnsubscribeItem *item) -{ - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _chat_lobbys.find(item->lobby_id) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Received unsubscribed to lobby " << std::hex << item->lobby_id << std::dec << ", from friend " << item->PeerId() << std::endl; -#endif - - if(it == _chat_lobbys.end()) - { - std::cerr << "Chat lobby " << std::hex << item->lobby_id << std::dec << " does not exist ! Can't unsubscribe friend!" << std::endl; - return ; - } - - for(std::set::iterator it2(it->second.participating_friends.begin());it2!=it->second.participating_friends.end();++it2) - if(*it2 == item->PeerId()) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removing peer id " << item->PeerId() << " from participant list of lobby " << std::hex << item->lobby_id << std::dec << std::endl; -#endif - it->second.previously_known_peers.insert(*it2) ; - it->second.participating_friends.erase(it2) ; - break ; - } - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_MOD) ; -} - -void DistributedChatService::unsubscribeChatLobby(const ChatLobbyId& id) -{ - // send AKN item - sendLobbyStatusPeerLeaving(id) ; - setLobbyAutoSubscribe(id, false); - - { - RS_STACK_MUTEX(mDistributedChatMtx); - - std::map::iterator it = _chat_lobbys.find(id) ; - - if(it == _chat_lobbys.end()) - { - std::cerr << "Chat lobby " << id << " does not exist ! Can't unsubscribe!" << std::endl; - return ; - } - - // send a lobby leaving packet to all friends - - for(std::set::const_iterator it2(it->second.participating_friends.begin());it2!=it->second.participating_friends.end();++it2) - { - RsChatLobbyUnsubscribeItem *item = new RsChatLobbyUnsubscribeItem ; - - item->lobby_id = id ; - item->PeerId(*it2) ; - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Sending unsubscribe item to friend " << *it2 << std::endl; -#endif - - sendChatItem(item) ; - } - - // remove history - - //mHistoryMgr->clear(it->second.virtual_peer_id); - - // remove lobby information - - _chat_lobbys.erase(it) ; - } - - triggerConfigSave(); // so that we save the subscribed lobbies - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_DEL) ; - - // done! -} -bool DistributedChatService::setDefaultIdentityForChatLobby(const RsGxsId& nick) -{ - if (nick.isNull()) - { - std::cerr << "Ignore empty nickname for chat lobby " << std::endl; - return false; - } - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - _default_identity = nick; - } - - triggerConfigSave() ; - return true ; -} - -void DistributedChatService::getDefaultIdentityForChatLobby(RsGxsId& nick) -{ - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - nick = locked_getDefaultIdentity() ; -} - -RsGxsId DistributedChatService::locked_getDefaultIdentity() -{ - if(_default_identity.isNull() && rsIdentity!=NULL) - { - std::list own_ids ; - rsIdentity->getOwnIds(own_ids) ; - - if(!own_ids.empty()) - { - _default_identity = own_ids.front() ; - triggerConfigSave(); - } - } - return _default_identity ; -} - -bool DistributedChatService::getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) -{ - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "getting nickname for chat lobby "<< std::hex << lobby_id << std::dec << std::endl; -#endif - std::map::iterator it = _chat_lobbys.find(lobby_id) ; - - if(it == _chat_lobbys.end()) - { - std::cerr << " (EE) lobby does not exist!!" << std::endl; - return false ; - } - - nick = it->second.gxs_id ; - return true ; -} - -bool DistributedChatService::setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) -{ - if (nick.isNull()) - { - std::cerr << "(EE) Ignore empty nickname for chat lobby " << nick << std::endl; - return false; - } - - // first check for change and send status peer changed nick name - bool changed = false; - std::map::iterator it; - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Changing nickname for chat lobby " << std::hex << lobby_id << std::dec << " to " << nick << std::endl; -#endif - it = _chat_lobbys.find(lobby_id) ; - - if(it == _chat_lobbys.end()) - { - std::cerr << " (EE) lobby does not exist!!" << std::endl; - return false; - } - - if (!it->second.gxs_id.isNull() && it->second.gxs_id != nick) - changed = true; - } - - if (changed) - { - // Inform other peers of change the Nickname - { - RsIdentityDetails det1,det2 ; - - // Only send a nickname change event if the two Identities are not anonymous - - if(rsIdentity->getIdDetails(nick,det1) && rsIdentity->getIdDetails(it->second.gxs_id,det2) && (det1.mFlags & det2.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) - sendLobbyStatusPeerChangedNickname(lobby_id, nick.toStdString()) ; - } - - // set new nick name - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - it = _chat_lobbys.find(lobby_id) ; - - if(it == _chat_lobbys.end()) - { - std::cerr << " (EE) lobby does not exist!!" << std::endl; - return false; - } - - it->second.gxs_id = nick ; - } - - return true ; -} - -void DistributedChatService::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) -{ - - if(autoSubscribe) - { - { - RS_STACK_MUTEX(mDistributedChatMtx); - _known_lobbies_flags[lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; - } - RsGxsId gxsId; - - if (getIdentityForChatLobby(lobby_id, gxsId)) - { - RS_STACK_MUTEX(mDistributedChatMtx); - _lobby_default_identity[lobby_id] = gxsId; - } - } - else - { - RS_STACK_MUTEX(mDistributedChatMtx); - _known_lobbies_flags[lobby_id] &= ~RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ; - _lobby_default_identity.erase(lobby_id); - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - triggerConfigSave(); -} - -bool DistributedChatService::getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) -{ - if(_known_lobbies_flags.find(lobby_id) == _known_lobbies_flags.end()) // keep safe about default values form std::map - return false; - - return _known_lobbies_flags[lobby_id] & RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE ; -} - -void DistributedChatService::cleanLobbyCaches() -{ -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Cleaning chat lobby caches." << std::endl; -#endif - - std::list keep_alive_lobby_ids ; - std::list changed_lobbies ; - std::list send_challenge_lobbies ; - std::list joined_lobby_ids ; - - { - RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - for(std::map::iterator it = _chat_lobbys.begin();it!=_chat_lobbys.end();++it) - { - // 1 - remove old messages - // - for(std::map::iterator it2(it->second.msg_cache.begin());it2!=it->second.msg_cache.end();) - if(it2->second + MAX_KEEP_MSG_RECORD < now) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removing old msg 0x" << std::hex << it2->first << ", time=" << std::dec << now - it2->second << " secs ago" << std::endl; -#endif - - std::map::iterator tmp(it2) ; - ++tmp ; - it->second.msg_cache.erase(it2) ; - it2 = tmp ; - } - else - ++it2 ; - - bool changed = false ; - - // 2 - remove inactive nicknames - // - for(std::map::iterator it2(it->second.gxs_ids.begin());it2!=it->second.gxs_ids.end();) - if(it2->second + MAX_KEEP_INACTIVE_NICKNAME < now) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removing inactive nickname 0x" << std::hex << it2->first << ", time=" << std::dec << now - it2->second << " secs ago" << std::endl; -#endif - - std::map::iterator tmp(it2) ; - ++tmp ; - it->second.gxs_ids.erase(it2) ; - it2 = tmp ; - changed = true ; - } - else - ++it2 ; - - if(changed) - changed_lobbies.push_back(it->first) ; - - // 3 - send a joined_lobby packet if a participating friend is connected, we do that only once - // - if (!it->second.joined_lobby_packet_sent) - { - bool oneParticipatingFriendIsConnected = false; - for(std::set::const_iterator fit(it->second.participating_friends.begin());fit!=it->second.participating_friends.end();++fit) - { - if(mServControl->isPeerConnected(mServType, *fit)) - { - oneParticipatingFriendIsConnected = true; - break; - } - } - if (oneParticipatingFriendIsConnected) - { - joined_lobby_ids.push_back(it->first) ; - it->second.joined_lobby_packet_sent = true; - } - } - - // 4 - send lobby keep-alive packet - // - if(it->second.last_keep_alive_packet_time + MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE < now) - { - keep_alive_lobby_ids.push_back(it->first) ; - it->second.last_keep_alive_packet_time = now ; - } - - // 5 - look at lobby activity and possibly send connection challenge - // - if(++it->second.connexion_challenge_count > CONNECTION_CHALLENGE_MAX_COUNT && now > it->second.last_connexion_challenge_time + CONNECTION_CHALLENGE_MIN_DELAY) - { - it->second.connexion_challenge_count = 0 ; - it->second.last_connexion_challenge_time = now ; - send_challenge_lobbies.push_back(it->first); - } - } - - // 2 - clean deprecated public chat lobby records - // - - for(std::map::iterator it(_visible_lobbies.begin());it!=_visible_lobbies.end();) - { - if(it->second.last_report_time + MAX_KEEP_PUBLIC_LOBBY_RECORD < now && _chat_lobbys.find(it->first)==_chat_lobbys.end()) // this lobby record is too late. - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << " removing old public lobby record 0x" << std::hex << it->first << ", time=" << std::dec << now - it->second.last_report_time << " secs ago" << std::endl; -#endif - std::map::iterator tmp(it) ; - ++tmp ; - _visible_lobbies.erase(it) ; - it = tmp ; - } - else - ++it ; - } - } - - // send keep alive - for(std::list::const_iterator it(keep_alive_lobby_ids.begin());it!=keep_alive_lobby_ids.end();++it) - sendLobbyStatusKeepAlive(*it) ; - - // update the gui - for(std::list::const_iterator it(changed_lobbies.begin());it!=changed_lobbies.end();++it) - RsServer::notify()->notifyChatLobbyEvent(*it,RS_CHAT_LOBBY_EVENT_KEEP_ALIVE,RsGxsId(),"") ; - - // send peer joined - for(std::list::const_iterator it(joined_lobby_ids.begin());it!=joined_lobby_ids.end();++it) - sendLobbyStatusNewPeer(*it) ; - - // send connection challenges - for(std::list::const_iterator it(send_challenge_lobbies.begin());it!=send_challenge_lobbies.end();++it) - sendConnectionChallenge(*it) ; -} - -void DistributedChatService::addToSaveList(std::list& list) const -{ - /* Save Lobby Auto Subscribe */ - for(std::map::const_iterator it=_known_lobbies_flags.begin(); it!=_known_lobbies_flags.end(); ++it) - { - RsChatLobbyConfigItem *clci = new RsChatLobbyConfigItem ; - clci->lobby_Id=it->first; - clci->flags=it->second.toUInt32(); - - list.push_back(clci) ; - } - - for(auto it(_chat_lobbys.begin());it!=_chat_lobbys.end();++it) - { - RsSubscribedChatLobbyConfigItem *scli = new RsSubscribedChatLobbyConfigItem; - scli->info = it->second; // copies the ChatLobbyInfo part only - list.push_back(scli); - } - - /* Save Default Nick Name */ - { - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "DEFAULT_IDENTITY"; - kv.value = _default_identity.toStdString(); - vitem->tlvkvs.pairs.push_back(kv); - list.push_back(vitem); - } - - /* Save Default Nick Name by Lobby*/ - for(std::map::const_iterator it=_lobby_default_identity.begin(); it!=_lobby_default_identity.end(); ++it) - { - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - ChatLobbyId cli = it->first; - RsGxsId gxsId = it->second; - - std::stringstream stream; - stream << std::setfill ('0') << std::setw(sizeof(ChatLobbyId)*2) - << std::hex << cli; - std::string strCli( stream.str() ); - - RsTlvKeyValue kv; - kv.key = "LOBBY_DEFAULT_IDENTITY:"+strCli; - kv.value = gxsId.toStdString(); - vitem->tlvkvs.pairs.push_back(kv); - list.push_back(vitem); - } - -} - -bool DistributedChatService::processLoadListItem(const RsItem *item) -{ - const RsConfigKeyValueSet *vitem = NULL; - const std::string strldID = "LOBBY_DEFAULT_IDENTITY:"; - - if(NULL != (vitem = dynamic_cast(item))) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if( kit->key == "DEFAULT_IDENTITY" ) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Loaded config default nick name for distributed chat: " << kit->value << std::endl ; -#endif - if (!kit->value.empty()) - { - _default_identity = RsGxsId(kit->value) ; - if(_default_identity.isNull()) - std::cerr << "ERROR: default identity is malformed." << std::endl; - } - - return true; - } - - if( kit->key.compare(0, strldID.length(), strldID) == 0) - { -#ifdef DEBUG_CHAT_LOBBIES - std::cerr << "Loaded config lobby default nick name: " << kit->key << " " << kit->value << std::endl ; -#endif - - std::string strCli = kit->key.substr(strldID.length()); - std::stringstream stream; - stream << std::hex << strCli; - ChatLobbyId cli = 0; - stream >> cli; - - if (!kit->value.empty() && (cli != 0)) - { - RsGxsId gxsId(kit->value); - if (gxsId.isNull()) - std::cerr << "ERROR: lobby default identity is malformed." << std::endl; - else - _lobby_default_identity[cli] = gxsId ; - } - - return true; - } - } - - const RsChatLobbyConfigItem *clci = NULL ; - - if(NULL != (clci = dynamic_cast(item))) - { - _known_lobbies_flags[clci->lobby_Id] = ChatLobbyFlags(clci->flags) ; - return true ; - } - - if(_default_identity.isNull() && rsIdentity!=NULL) - { - std::list own_ids ; - rsIdentity->getOwnIds(own_ids) ; - - if(!own_ids.empty()) - _default_identity = own_ids.front() ; - } - - const RsSubscribedChatLobbyConfigItem *scli = dynamic_cast(item); - - if(scli != NULL) - { - if(_chat_lobbys.find(scli->info.lobby_id) != _chat_lobbys.end()) // do nothing if the lobby is already subscribed - return true; - - std::cerr << "Re-subscribing to chat lobby " << (void*)scli->info.lobby_id << ", flags = " << scli->info.lobby_flags << std::endl; - - rstime_t now = time(NULL); - - // Add the chat room into visible chat rooms - { - RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - - VisibleChatLobbyRecord& rec(_visible_lobbies[scli->info.lobby_id]) ; - - rec.lobby_id = scli->info.lobby_id ; - rec.lobby_name = scli->info.lobby_name ; - rec.lobby_topic = scli->info.lobby_topic ; - rec.participating_friends = scli->info.participating_friends; - rec.total_number_of_peers = 0; - rec.last_report_time = now ; - rec.lobby_flags = EXTRACT_PRIVACY_FLAGS(scli->info.lobby_flags) ; - - _known_lobbies_flags[scli->info.lobby_id] |= RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE; - } - - // Add the chat room into subscribed chat rooms - - ChatLobbyEntry entry ; - (ChatLobbyInfo&)entry = scli->info; - - entry.virtual_peer_id = makeVirtualPeerId(entry.lobby_id) ; // not random, so we keep the same id at restart - entry.connexion_challenge_count = 0 ; - entry.last_activity = now ; - entry.last_connexion_challenge_time = now ; - entry.joined_lobby_packet_sent = false ; - entry.last_keep_alive_packet_time = now ; - - { - RS_STACK_MUTEX(mDistributedChatMtx); /********** STACK LOCKED MTX ******/ - _chat_lobbys[entry.lobby_id] = entry ; - } - - // make the UI aware of the existing chat room - - RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ; - - return true; - } - - return false ; -} - diff --git a/libretroshare/src/chat/distributedchat.h b/libretroshare/src/chat/distributedchat.h deleted file mode 100644 index 96369511d..000000000 --- a/libretroshare/src/chat/distributedchat.h +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distributedchat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -typedef RsPeerId ChatLobbyVirtualPeerId ; - -struct RsItem; -class p3HistoryMgr ; -class p3IdService ; -class p3ServiceControl; -class RsChatLobbyItem ; -class RsChatLobbyListRequestItem ; -class RsChatLobbyListItem ; -class RsChatLobbyEventItem ; -class RsChatLobbyBouncingObject ; -class RsChatLobbyInviteItem_Deprecated ; // to be removed (deprecated since May 2017) -class RsChatLobbyInviteItem ; -class RsChatLobbyMsgItem ; -class RsChatLobbyConnectChallengeItem ; -class RsChatLobbyUnsubscribeItem ; - -class RsChatItem ; -class RsChatMsgItem ; -class RsGixs ; - -class DistributedChatService -{ - public: - DistributedChatService(uint32_t service_type,p3ServiceControl *sc,p3HistoryMgr *hm,RsGixs *is) ; - - virtual ~DistributedChatService() {} - - void flush() ; - - // Interface part to communicate with - // - bool getVirtualPeerId(const ChatLobbyId& lobby_id, RsPeerId& virtual_peer_id) ; - void getChatLobbyList(std::list& clids) ; - bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& clinfo) ; - bool acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& identity) ; - void denyLobbyInvite(const ChatLobbyId& id) ; - void getPendingChatLobbyInvites(std::list& invites) ; - void invitePeerToLobby(const ChatLobbyId&, const RsPeerId& peer_id,bool connexion_challenge = false) ; - void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; - bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) ; - bool getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick) ; - bool setDefaultIdentityForChatLobby(const RsGxsId& nick) ; - void getDefaultIdentityForChatLobby(RsGxsId& nick) ; - void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe); - bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id); - void sendLobbyStatusString(const ChatLobbyId& id,const std::string& status_string) ; - void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) ; - - ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic, const std::set& invited_friends,ChatLobbyFlags flags) ; - - void getListOfNearbyChatLobbies(std::vector& public_lobbies) ; - bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &gxs_id) ; - - protected: - bool handleRecvItem(RsChatItem *) ; - - virtual void sendChatItem(RsChatItem *) =0 ; - virtual void locked_storeIncomingMsg(RsChatMsgItem *) =0 ; - virtual void triggerConfigSave() =0; - - void addToSaveList(std::list& list) const ; - bool processLoadListItem(const RsItem *item) ; - - void checkSizeAndSendLobbyMessage(RsChatItem *) ; - - bool sendLobbyChat(const ChatLobbyId &lobby_id, const std::string&) ; - bool handleRecvChatLobbyMsgItem(RsChatMsgItem *item) ; - - bool checkSignature(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id) ; - - private: - /// make some statistics about time shifts, to prevent various issues. - void addTimeShiftStatistics(int shift) ; - - void handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *item) ; - void handleRecvChatLobbyList(RsChatLobbyListItem *item) ; - void handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item) ; - - - /// Checks that the lobby object is not flooding a lobby. - bool locked_bouncingObjectCheck(RsChatLobbyBouncingObject *obj,const RsPeerId& peer_id,uint32_t lobby_count) ; - - /// receive and handle chat lobby item - bool recvLobbyChat(RsChatLobbyMsgItem*,const RsPeerId& src_peer_id) ; - void handleRecvLobbyInvite_Deprecated(RsChatLobbyInviteItem_Deprecated*) ; // to be removed (deprecated since May 2017) - void handleRecvLobbyInvite(RsChatLobbyInviteItem*) ; - void checkAndRedirectMsgToLobby(RsChatMsgItem*) ; - void handleConnectionChallenge(RsChatLobbyConnectChallengeItem *item) ; - void sendConnectionChallenge(ChatLobbyId id) ; - void handleFriendUnsubscribeLobby(RsChatLobbyUnsubscribeItem*) ; - void cleanLobbyCaches() ; - bool bounceLobbyObject(RsChatLobbyBouncingObject *obj, const RsPeerId& peer_id) ; - - void sendLobbyStatusItem(const ChatLobbyId&, int type, const std::string& status_string) ; - void sendLobbyStatusPeerChangedNickname(const ChatLobbyId& lobby_id, const std::string& newnick) ; - - void sendLobbyStatusNewPeer(const ChatLobbyId& lobby_id) ; - void sendLobbyStatusKeepAlive(const ChatLobbyId&) ; - - bool locked_initLobbyBouncableObject(const ChatLobbyId& id,RsChatLobbyBouncingObject&) ; - void locked_printDebugInfo() const ; - RsGxsId locked_getDefaultIdentity(); - - static ChatLobbyVirtualPeerId makeVirtualPeerId(ChatLobbyId) ; - static uint64_t makeConnexionChallengeCode(const RsPeerId& peer_id,ChatLobbyId lobby_id,ChatLobbyMsgId msg_id) ; - - class ChatLobbyEntry: public ChatLobbyInfo - { - public: - std::map msg_cache ; - RsPeerId virtual_peer_id ; - int connexion_challenge_count ; - rstime_t last_connexion_challenge_time ; - bool joined_lobby_packet_sent; - rstime_t last_keep_alive_packet_time ; - std::set previously_known_peers ; - }; - - std::map _chat_lobbys ; - std::map _lobby_invites_queue ; - std::map _visible_lobbies ; - std::map _known_lobbies_flags ; // flags for all lobbies, including the ones that are not known. So we can't - std::map > _pendingPartialLobbyMessages ; // store them in _chat_lobbies (subscribed lobbies) nor _visible_lobbies. - // Known flags: - // RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE - - float _time_shift_average ; - rstime_t last_lobby_challenge_time ; // prevents bruteforce attack - rstime_t last_visible_lobby_info_request_time ; // allows to ask for updates - bool _should_reset_lobby_counts ; - RsGxsId _default_identity; - std::map _lobby_default_identity; - - uint32_t mServType ; - RsMutex mDistributedChatMtx ; - - p3ServiceControl *mServControl; - p3HistoryMgr *mHistMgr; - RsGixs *mGixs ; -}; diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc deleted file mode 100644 index 3fbbdaf75..000000000 --- a/libretroshare/src/chat/p3chatservice.cc +++ /dev/null @@ -1,1485 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: chatservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include - -#include "util/rsdir.h" -#include "util/radix64.h" -#include "crypto/rsaes.h" -#include "util/rsrandom.h" -#include "util/rsstring.h" -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsstatus.h" -#include "pqi/pqibin.h" -#include "pqi/pqistore.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3historymgr.h" -#include "rsserver/p3face.h" -#include "services/p3idservice.h" -#include "gxstrans/p3gxstrans.h" - -#include "chat/p3chatservice.h" -#include "rsitems/rsconfigitems.h" - -/**** - * #define CHAT_DEBUG 1 - ****/ - -static const uint32_t MAX_MESSAGE_SECURITY_SIZE = 31000 ; // Max message size to forward other friends -static const uint32_t MAX_AVATAR_JPEG_SIZE = 32767; // Maximum size in bytes for an avatar. Too large packets - // don't transfer correctly and can kill the system. - // Images are 96x96, which makes approx. 27000 bytes uncompressed. - -p3ChatService::p3ChatService( p3ServiceControl *sc, p3IdService *pids, - p3LinkMgr *lm, p3HistoryMgr *historyMgr, - p3GxsTrans& gxsTransService ) : - DistributedChatService(getServiceInfo().mServiceType, sc, historyMgr,pids), - mChatMtx("p3ChatService"), mServiceCtrl(sc), mLinkMgr(lm), - mHistoryMgr(historyMgr), _own_avatar(NULL), - _serializer(new RsChatSerialiser()), - mDGMutex("p3ChatService distant id - gxs id map mutex"), - mGxsTransport(gxsTransService) -{ - addSerialType(_serializer); - mGxsTransport.registerGxsTransClient( GxsTransSubServices::P3_CHAT_SERVICE, - this ); -} - -RsServiceInfo p3ChatService::getServiceInfo() -{ return RsServiceInfo(RS_SERVICE_TYPE_CHAT, "chat", 1, 0, 1, 0); } - -int p3ChatService::tick() -{ - if(receivedItems()) receiveChatQueue(); - - DistributedChatService::flush(); - - return 0; -} - -/***************** Chat Stuff **********************/ - -void p3ChatService::sendPublicChat(const std::string &msg) -{ - /* go through all the peers */ - - std::set ids; - std::set::iterator it; - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, ids); - - /* add in own id -> so get reflection */ - RsPeerId ownId = mServiceCtrl->getOwnId(); - ids.insert(ownId); - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat()"; - std::cerr << std::endl; -#endif - - for(it = ids.begin(); it != ids.end(); ++it) - { - RsChatMsgItem *ci = new RsChatMsgItem(); - - ci->PeerId(*it); - ci->chatFlags = RS_CHAT_FLAG_PUBLIC; - ci->sendTime = time(NULL); - ci->recvTime = ci->sendTime; - ci->message = msg; - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat() Item:"; - std::cerr << std::endl; - ci->print(std::cerr); - std::cerr << std::endl; -#endif - - if (*it == ownId) - { - //mHistoryMgr->addMessage(false, RsPeerId(), ownId, ci); - ChatMessage message; - initChatMessage(ci, message); - message.incoming = false; - message.online = true; - RsServer::notify()->notifyChatMessage(message); - mHistoryMgr->addMessage(message); - } - else - checkSizeAndSendMessage(ci); - } -} - - -class p3ChatService::AvatarInfo -{ - public: - AvatarInfo() - { - _image_size = 0 ; - _image_data = NULL ; - _peer_is_new = false ; // true when the peer has a new avatar - _own_is_new = false ; // true when I myself a new avatar to send to this peer. - } - - ~AvatarInfo() - { - free( _image_data ); - _image_data = NULL ; - _image_size = 0 ; - } - - AvatarInfo(const AvatarInfo& ai) - { - init(ai._image_data,ai._image_size) ; - } - - void init(const unsigned char *jpeg_data,int size) - { - if(size == 0) - { - _image_size = 0; - _image_data = nullptr; - } - else - { - _image_size = size ; - _image_data = (unsigned char*)rs_malloc(size) ; - memcpy(_image_data,jpeg_data,size) ; - } - } - AvatarInfo(const unsigned char *jpeg_data,int size) - { - init(jpeg_data,size) ; - } - - void toUnsignedChar(unsigned char *& data,uint32_t& size) const - { - if(_image_size == 0) - { - size = 0 ; - data = NULL ; - return ; - } - data = (unsigned char *)rs_malloc(_image_size) ; - size = _image_size ; - memcpy(data,_image_data,size*sizeof(unsigned char)) ; - } - - uint32_t _image_size ; - unsigned char *_image_data ; - int _peer_is_new ; // true when the peer has a new avatar - int _own_is_new ; // true when I myself a new avatar to send to this peer. -}; - -void p3ChatService::sendGroupChatStatusString(const std::string& status_string) -{ - std::set ids; - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, ids); - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat(): sending group chat status string: " << status_string << std::endl ; - std::cerr << std::endl; -#endif - - for(std::set::iterator it = ids.begin(); it != ids.end(); ++it) - { - RsChatStatusItem *cs = new RsChatStatusItem ; - - cs->status_string = status_string ; - cs->flags = RS_CHAT_FLAG_PUBLIC ; - - cs->PeerId(*it); - - sendItem(cs); - } -} - -void p3ChatService::sendStatusString( const ChatId& id, - const std::string& status_string ) -{ - if(id.isLobbyId()) sendLobbyStatusString(id.toLobbyId(),status_string); - else if(id.isBroadcast()) sendGroupChatStatusString(status_string); - else if(id.isPeerId() || id.isDistantChatId()) - { - RsPeerId vpid; - if(id.isDistantChatId()) vpid = RsPeerId(id.toDistantChatId()); - else vpid = id.toPeerId(); - - if(isOnline(vpid)) - { - RsChatStatusItem *cs = new RsChatStatusItem; - - cs->status_string = status_string; - cs->flags = RS_CHAT_FLAG_PRIVATE; - cs->PeerId(vpid); - -#ifdef CHAT_DEBUG - std::cerr << "sending chat status packet:" << std::endl; - cs->print(std::cerr); -#endif - sendChatItem(cs); - } - } - else - { - std::cerr << "p3ChatService::sendStatusString() Error: chat id of this " - << "type is not handled, is it empty?" << std::endl; - return; - } -} - -void p3ChatService::clearChatLobby(const ChatId& id) -{ - RsServer::notify()->notifyChatCleared(id); -} - -void p3ChatService::sendChatItem(RsChatItem *item) -{ - if(DistantChatService::handleOutgoingItem(item)) return; -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChatItem(): sending to " << item->PeerId() - << ": interpreted as friend peer id." << std::endl; -#endif - sendItem(item); -} - -void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg) -{ - // We check the message item, and possibly split it into multiple messages, if the message is too big. - - static const uint32_t MAX_STRING_SIZE = 15000 ; - -#ifdef CHAT_DEBUG - std::cerr << "Sending message: size=" << msg->message.size() << ", sha1sum=" << RsDirUtil::sha1sum((uint8_t*)msg->message.c_str(),msg->message.size()) << std::endl; -#endif - - while(msg->message.size() > MAX_STRING_SIZE) - { - // chop off the first 15000 wchars - - RsChatMsgItem *item = new RsChatMsgItem(*msg) ; - - item->message = item->message.substr(0,MAX_STRING_SIZE) ; - msg->message = msg->message.substr(MAX_STRING_SIZE,msg->message.size()-MAX_STRING_SIZE) ; - - // Clear out any one time flags that should not be copied into multiple objects. This is - // a precaution, in case the receivign peer does not yet handle split messages transparently. - // - item->chatFlags &= (RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_PUBLIC | RS_CHAT_FLAG_LOBBY) ; - -#ifdef CHAT_DEBUG - std::cerr << "Creating slice of size " << item->message.size() << std::endl; -#endif - // Indicate that the message is to be continued. - // - item->chatFlags |= RS_CHAT_FLAG_PARTIAL_MESSAGE ; - sendChatItem(item) ; - } -#ifdef CHAT_DEBUG - std::cerr << "Creating slice of size " << msg->message.size() << std::endl; -#endif - sendChatItem(msg) ; -} - - -bool p3ChatService::isOnline(const RsPeerId& pid) -{ - // check if the id is a tunnel id or a peer id. - DistantChatPeerInfo dcpinfo; - if(getDistantChatStatus(DistantChatPeerId(pid),dcpinfo)) - return dcpinfo.status == RS_DISTANT_CHAT_STATUS_CAN_TALK; - else return mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid); -} - -bool p3ChatService::sendChat(ChatId destination, std::string msg) -{ - if(destination.isLobbyId()) - return DistributedChatService::sendLobbyChat(destination.toLobbyId(), msg); - else if(destination.isBroadcast()) - { - sendPublicChat(msg); - return true; - } - else if(destination.isPeerId()==false && destination.isDistantChatId()==false) - { - std::cerr << "p3ChatService::sendChat() Error: chat id type not handled. Is it empty?" << std::endl; - return false; - } - // destination is peer or distant -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat()" << std::endl; -#endif - - RsPeerId vpid; - if(destination.isDistantChatId()) - vpid = RsPeerId(destination.toDistantChatId()); // convert to virtual peer id - else - vpid = destination.toPeerId(); - - RsChatMsgItem *ci = new RsChatMsgItem(); - ci->PeerId(vpid); - ci->chatFlags = RS_CHAT_FLAG_PRIVATE; - ci->sendTime = time(NULL); - ci->recvTime = ci->sendTime; - ci->message = msg; - - ChatMessage message; - initChatMessage(ci, message); - message.incoming = false; - message.online = true; - - if(!isOnline(vpid) && !destination.isDistantChatId()) - { - message.online = false; - RsServer::notify()->notifyChatMessage(message); - - // use the history to load pending messages to the gui - // this is not very nice, because the user may think the message was send, while it is still in the queue - mHistoryMgr->addMessage(message); - - RsGxsTransId tId = RSRandom::random_u64(); - -#ifdef SUSPENDED_CODE - // this part of the code was formerly used to send the traffic over GxsTransport. The problem is that - // gxstunnel takes care of reaching the peer already, so GxsTransport would only be needed when the - // current peer is offline. So we need to fin a way to quickly push the items to friends when quitting RS. - - if(destination.isDistantChatId()) - { - RS_STACK_MUTEX(mDGMutex); - DIDEMap::const_iterator it = mDistantGxsMap.find(destination.toDistantChatId()); - if(it != mDistantGxsMap.end()) - { - const DistantEndpoints& de(it->second); - uint32_t sz = _serializer->size(ci); - std::vector data; data.resize(sz); - _serializer->serialise(ci, &data[0], &sz); - mGxsTransport.sendData(tId, GxsTransSubServices::P3_CHAT_SERVICE, - de.from, de.to, &data[0], sz); - } - else - std::cout << "p3ChatService::sendChat(...) can't find distant" - << "chat id in mDistantGxsMap this is unxpected!" - << std::endl; - } -#endif - - // peer is offline, add to outgoing list - { - RS_STACK_MUTEX(mChatMtx); - privateOutgoingMap.insert(outMP::value_type(tId, ci)); - } - - IndicateConfigChanged(); - return false; - } - - { - RS_STACK_MUTEX(mChatMtx); - std::map::iterator it = _avatars.find(vpid); - - if(it == _avatars.end()) - { - _avatars[vpid] = new AvatarInfo ; - it = _avatars.find(vpid) ; - } - if(it->second->_own_is_new) - { -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sendChat: new avatar never sent to peer " << vpid << ". Setting flag to packet." << std::endl; -#endif - - ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ; - it->second->_own_is_new = false ; - } - } - -#ifdef CHAT_DEBUG - std::cerr << "Sending msg to (maybe virtual) peer " << vpid << ", flags = " << ci->chatFlags << std::endl ; - std::cerr << "p3ChatService::sendChat() Item:"; - std::cerr << std::endl; - ci->print(std::cerr); - std::cerr << std::endl; -#endif - - RsServer::notify()->notifyChatMessage(message); - - // cyril: history is temporarily disabled for distant chat, since we need to store the full tunnel ID, but then - // at loading time, the ID is not known so that chat window shows 00000000 as a peer. - - //if(!message.chat_id.isDistantChatId()) - mHistoryMgr->addMessage(message); - - checkSizeAndSendMessage(ci); - - // Check if custom state string has changed, in which case it should be sent to the peer. - bool should_send_state_string = false ; - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _state_strings.find(vpid) ; - - if(it == _state_strings.end()) - { - _state_strings[vpid] = StateStringInfo() ; - it = _state_strings.find(vpid) ; - it->second._own_is_new = true ; - } - if(it->second._own_is_new) - { - should_send_state_string = true ; - it->second._own_is_new = false ; - } - } - - if(should_send_state_string) - { -#ifdef CHAT_DEBUG - std::cerr << "own status string is new for peer " << vpid << ": sending it." << std::endl ; -#endif - RsChatStatusItem *cs = makeOwnCustomStateStringItem() ; - cs->PeerId(vpid) ; - sendChatItem(cs) ; - } - - return true; -} - -// This method might take control over the memory, or modify it, possibly adding missing parts. -// This function looks weird because it cannot duplicate the message since it does not know -// what type of object it is and the duplicate method of lobby messages is reserved for -// ChatLobby bouncing objects. -// -// Returns false if the item shouldn't be used (and replaced to NULL) - -bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatMsgItem *& ci) -{ - // Check is the item is ending an incomplete item. - // - std::map::iterator it = _pendingPartialMessages.find(ci->PeerId()) ; - - bool ci_is_incomplete = ci->chatFlags & RS_CHAT_FLAG_PARTIAL_MESSAGE ; - - if(it != _pendingPartialMessages.end()) - { -#ifdef CHAT_DEBUG - std::cerr << "Pending message found. Appending it." << std::endl; -#endif - // Yes, there is. Append the item to ci. - - ci->message = it->second->message + ci->message ; - ci->chatFlags |= it->second->chatFlags ; - - // always remove existing partial. The compound message is in ci now. - - delete it->second ; - _pendingPartialMessages.erase(it) ; - } - - // now decide what to do: if ci is incomplete, store it and replace the pointer with NULL - // if complete, return it. - - if(ci_is_incomplete) - { -#ifdef CHAT_DEBUG - std::cerr << "Message is partial, storing for later." << std::endl; -#endif - // The item is a partial message. Push it, and wait for the rest. - // - _pendingPartialMessages[ci->PeerId()] = ci ; // cannot use duplicate() here - ci = NULL ; // takes memory ownership over ci - return false ; - } - else - { -#ifdef CHAT_DEBUG - std::cerr << "Message is complete, using it now. Size = " << ci->message.size() << ", hash=" << RsDirUtil::sha1sum((uint8_t*)ci->message.c_str(),ci->message.size()) << std::endl; -#endif - return true ; - } -} - - -void p3ChatService::receiveChatQueue() -{ - RsItem *item ; - - while(NULL != (item=recvItem())) - handleIncomingItem(item) ; -} - -class MsgCounter -{ - public: - MsgCounter() {} - - void clean(rstime_t max_time) - { - while(!recv_times.empty() && recv_times.front() < max_time) - recv_times.pop_front() ; - } - std::list recv_times ; -}; - -void p3ChatService::handleIncomingItem(RsItem *item) -{ -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::receiveChatQueue() Item:" << (void*)item - << std::endl ; -#endif - - // RsChatMsgItems needs dynamic_cast, since they have derived siblings. - RsChatMsgItem* ci = dynamic_cast(item); - if(ci) - { - handleRecvChatMsgItem(ci); - - /* +ci+ deletion is handled by handleRecvChatMsgItem ONLY in some - * specific cases, in case +ci+ has not been handled deleted it here */ - delete ci ; - - return; - } - - if(DistributedChatService::handleRecvItem(dynamic_cast(item))) - { - delete item; - return; - } - - switch(item->PacketSubType()) - { - case RS_PKT_SUBTYPE_CHAT_STATUS: - handleRecvChatStatusItem(dynamic_cast(item)); - break; - case RS_PKT_SUBTYPE_CHAT_AVATAR: - handleRecvChatAvatarItem(dynamic_cast(item)); - break; - default: - { - static int already = false; - if(!already) - { - std::cerr << "Unhandled item subtype " - << static_cast(item->PacketSubType()) - << " in p3ChatService: " << std::endl; - already = true; - } - } - } - delete item; -} - -void p3ChatService::handleRecvChatAvatarItem(RsChatAvatarItem *ca) -{ - receiveAvatarJpegData(ca) ; - -#ifdef CHAT_DEBUG - std::cerr << "Received avatar data for peer " << ca->PeerId() << ". Notifying." << std::endl ; -#endif - RsServer::notify()->notifyPeerHasNewAvatar(ca->PeerId().toStdString()) ; -} - -uint32_t p3ChatService::getMaxMessageSecuritySize(int type) -{ - switch (type) - { - case RS_CHAT_TYPE_LOBBY: - return MAX_MESSAGE_SECURITY_SIZE; - - case RS_CHAT_TYPE_PUBLIC: - case RS_CHAT_TYPE_PRIVATE: - case RS_CHAT_TYPE_DISTANT: - return 0; // unlimited - } - - std::cerr << "p3ChatService::getMaxMessageSecuritySize: Unknown chat type " << type << std::endl; - - return MAX_MESSAGE_SECURITY_SIZE; -} - -bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci) -{ - // Remove too big messages - if (ci->chatFlags & RS_CHAT_FLAG_LOBBY) - { - uint32_t maxMessageSize = getMaxMessageSecuritySize(RS_CHAT_TYPE_LOBBY); - if (maxMessageSize > 0 && ci->message.length() > maxMessageSize) - { - std::ostringstream os; - os << getMaxMessageSecuritySize(RS_CHAT_TYPE_LOBBY); - - ci->message = "**** Security warning: Message bigger than "; - ci->message += os.str(); - ci->message += " characters, forwarded to you by "; - ci->message += rsPeers->getPeerName(ci->PeerId()); - ci->message += ", dropped. ****"; - return false; - } - } - - // The following code has been suggested, but is kept suspended since it is a bit too much restrictive. -#ifdef SUSPENDED - // Transform message to lowercase - std::wstring mes(ci->message); - std::transform( mes.begin(), mes.end(), mes.begin(), std::towlower); - - // Quick fix for svg attack and other nuisances (inline pictures) - if (mes.find(L"message = L"**** Security warning: Message contains an . ****"; - return false; - } - - // Remove messages with too many line breaks - size_t pos = 0; - int count_line_breaks = 0; - while ((pos = mes.find(L" 50) - { - ci->message = L"**** More than 50 line breaks, dropped. ****"; - return false; - } -#endif - - // https://en.wikipedia.org/wiki/Billion_laughs - // This should be done for all incoming HTML messages (also in forums - // etc.) so this should be a function in some other file. - - if (ci->message.find("message << std::endl; - std::cout << "**********" << std::endl; - std::cout << "********** entity attack by " << ci->PeerId().toStdString().c_str() << std::endl; - std::cout << "**********" << std::endl; - - ci->message = "**** This message (from peer id " + rsPeers->getPeerName(ci->PeerId()) + ") has been removed because it contains the string \" … - - // Also check flags. Lobby msgs should have proper flags, but they can be - // corrupted by a friend before sending them that can result in e.g. lobby - // messages ending up in the broadcast channel, etc. - - uint32_t fl = ci->chatFlags & (RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_PUBLIC | RS_CHAT_FLAG_LOBBY) ; - -#ifdef CHAT_DEBUG - std::cerr << "Checking msg flags: " << std::hex << fl << std::endl; -#endif - - if(dynamic_cast(ci) != NULL) - { - if(fl != (RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_LOBBY)) - std::cerr << "Warning: received chat lobby message with iconsistent flags " << std::hex << fl << std::dec << " from friend peer " << ci->PeerId() << std::endl; - - ci->chatFlags &= ~RS_CHAT_FLAG_PUBLIC ; - } - else if(fl!=0 && !(fl == RS_CHAT_FLAG_PRIVATE || fl == RS_CHAT_FLAG_PUBLIC)) // The !=0 is normally not needed, but we keep it for - { // a while, for backward compatibility. It's not harmful. - std::cerr << "Warning: received chat lobby message with iconsistent flags " << std::hex << fl << std::dec << " from friend peer " << ci->PeerId() << std::endl; - - std::cerr << "This message will be dropped."<< std::endl; - return false ; - } - - return true ; -} - -bool p3ChatService::initiateDistantChatConnexion( const RsGxsId& to_gxs_id, - const RsGxsId& from_gxs_id, - DistantChatPeerId& pid, - uint32_t& error_code, - bool notify ) -{ - - if(to_gxs_id.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " Destination RsGxsId is invalid" << std::endl; - return false; - } - if (from_gxs_id.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " Origin RsGxsId is invalid" << std::endl; - return false; - } - if (!rsIdentity->isOwnId(from_gxs_id)) - { - RsErr() << __PRETTY_FUNCTION__ << " Origin RsGxsId id must be own" << std::endl; - return false; - } - - if(DistantChatService::initiateDistantChatConnexion( to_gxs_id, - from_gxs_id, pid, - error_code, notify )) - { - RS_STACK_MUTEX(mDGMutex); - DistantEndpoints ep; ep.from = from_gxs_id; ep.to = to_gxs_id; - mDistantGxsMap.insert(DIDEMap::value_type(pid, ep)); - return true; - } - return false; -} - -bool p3ChatService::receiveGxsTransMail( const RsGxsId& authorId, - const RsGxsId& recipientId, - const uint8_t* data, - uint32_t dataSize ) -{ - DistantChatPeerId pid; - uint32_t error_code; - if(initiateDistantChatConnexion( - authorId, recipientId, pid, error_code, false )) - { - RsChatMsgItem* item = static_cast( - _serializer->deserialise( - const_cast(data), &dataSize )); - RsPeerId rd(p3GxsTunnelService::makeGxsTunnelId(authorId, recipientId)); - item->PeerId(rd); - handleRecvChatMsgItem(item); - delete item; - return true; - } - - std::cerr << __PRETTY_FUNCTION__ << " (EE) failed initiating" - << " distant chat connection error: "<< error_code - << std::endl; - return false; -} - -bool p3ChatService::notifyGxsTransSendStatus(RsGxsTransId mailId, - GxsTransSendStatus status ) -{ - if ( status != GxsTransSendStatus::RECEIPT_RECEIVED ) return true; - - bool changed = false; - - { - RS_STACK_MUTEX(mChatMtx); - auto it = privateOutgoingMap.find(mailId); - if( it != privateOutgoingMap.end() ) - { - privateOutgoingMap.erase(it); - changed = true; - } - } - - if(changed) - { - RsServer::notify()->notifyListChange( - NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL ); - - IndicateConfigChanged(); - } - - return true; -} - -bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci) -{ - std::string name; - uint32_t popupChatFlag = RS_POPUP_CHAT; - - { - RS_STACK_MUTEX(mChatMtx); - - // we make sure this call does not take control over the memory - if(!locked_checkAndRebuildPartialMessage(ci)) return true; - /* message is a subpart of an existing message. - * So everything ok, but we need to return. */ - } - - // Check for security. This avoids bombing messages, and so on. - if(!checkForMessageSecurity(ci)) return false; - - /* If it's a lobby item, we need to bounce it and possibly check for timings - * etc. */ - if(!DistributedChatService::handleRecvChatLobbyMsgItem(ci)) return false; - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::receiveChatQueue() Item:" << std::endl; - ci->print(std::cerr); - std::cerr << std::endl << "Got msg. Flags = " << ci->chatFlags << std::endl; -#endif - - // Now treat normal chat stuff such as avatar requests, except for chat lobbies. - - if( !(ci->chatFlags & RS_CHAT_FLAG_LOBBY)) - { - if(ci->chatFlags & RS_CHAT_FLAG_REQUESTS_AVATAR) // no msg here. Just an avatar request. - { - sendAvatarJpegData(ci->PeerId()) ; - return false ; - } - - // normal msg. Return it normally. - // Check if new avatar is available at peer's. If so, send a request to get the avatar. - - if((ci->chatFlags & RS_CHAT_FLAG_AVATAR_AVAILABLE) && !(ci->chatFlags & RS_CHAT_FLAG_LOBBY)) - { -#ifdef CHAT_DEBUG - std::cerr << "New avatar is available for peer " << ci->PeerId() << ", sending request" << std::endl ; -#endif - sendAvatarRequest(ci->PeerId()) ; - ci->chatFlags &= ~RS_CHAT_FLAG_AVATAR_AVAILABLE ; - } - - std::map::const_iterator it = _avatars.find(ci->PeerId()) ; - -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice:: avatar requested from above. " << std::endl ; -#endif - // has avatar. Return it strait away. - // - if(it!=_avatars.end() && it->second->_peer_is_new) - { -#ifdef CHAT_DEBUG - std::cerr << "Avatar is new for peer. ending info above" << std::endl ; -#endif - ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ; - } - } - - std::string message = ci->message; - - if(!(ci->chatFlags & RS_CHAT_FLAG_LOBBY)) - { - if(ci->chatFlags & RS_CHAT_FLAG_PRIVATE) - RsServer::notify()->AddPopupMessage(popupChatFlag, ci->PeerId().toStdString(), name, message); /* notify private chat message */ - else - { -#ifdef RS_DIRECT_CHAT - /* notify public chat message */ - RsServer::notify()->AddPopupMessage( RS_POPUP_GROUPCHAT, ci->PeerId().toStdString(), "", message ); - //RsServer::notify()->AddFeedItem( RS_FEED_ITEM_CHAT_NEW, ci->PeerId().toStdString(), message, "" ); -#else // def RS_DIRECT_CHAT - /* Ignore deprecated direct node broadcast chat messages */ - return false; -#endif - } - } - - ci->recvTime = time(NULL); - - ChatMessage cm; - initChatMessage(ci, cm); - cm.incoming = true; - cm.online = true; - RsServer::notify()->notifyChatMessage(cm); - - mHistoryMgr->addMessage(cm); - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mChatMessage = cm; - rsEvents->postEvent(ev); - } - - return true ; -} - -void p3ChatService::locked_storeIncomingMsg(RsChatMsgItem */*item*/) -{ -#ifdef REMOVE - privateIncomingList.push_back(item) ; -#endif -} - -void p3ChatService::handleRecvChatStatusItem(RsChatStatusItem *cs) -{ -#ifdef CHAT_DEBUG - std::cerr << "Received status string \"" << cs->status_string << "\"" << std::endl ; -#endif - - DistantChatPeerInfo dcpinfo; - - if(cs->flags & RS_CHAT_FLAG_REQUEST_CUSTOM_STATE) // no state here just a request. - sendCustomState(cs->PeerId()) ; - else if(cs->flags & RS_CHAT_FLAG_CUSTOM_STATE) // Check if new custom string is available at peer's. - { // If so, send a request to get the custom string. - receiveStateString(cs->PeerId(),cs->status_string) ; // store it - RsServer::notify()->notifyCustomState(cs->PeerId().toStdString(), cs->status_string) ; - } - else if(cs->flags & RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE) - { -#ifdef CHAT_DEBUG - std::cerr << "New custom state is available for peer " << cs->PeerId() << ", sending request" << std::endl ; -#endif - sendCustomStateRequest(cs->PeerId()) ; - } - else if(DistantChatService::getDistantChatStatus(DistantChatPeerId(cs->PeerId()), dcpinfo)) - { - RsServer::notify()->notifyChatStatus(ChatId(DistantChatPeerId(cs->PeerId())), cs->status_string) ; - } - else if(cs->flags & RS_CHAT_FLAG_PRIVATE) - { - RsServer::notify()->notifyChatStatus(ChatId(cs->PeerId()),cs->status_string) ; - } - else if(cs->flags & RS_CHAT_FLAG_PUBLIC) - { - ChatId id = ChatId::makeBroadcastId(); - id.broadcast_status_peer_id = cs->PeerId(); - RsServer::notify()->notifyChatStatus(id, cs->status_string) ; - } - - DistantChatService::handleRecvChatStatusItem(cs) ; -} - -void p3ChatService::initChatMessage(RsChatMsgItem *c, ChatMessage &m) -{ - m.chat_id = ChatId(c->PeerId()); - m.chatflags = 0; - m.sendTime = c->sendTime; - m.recvTime = c->recvTime; - m.msg = c->message; - - RsChatLobbyMsgItem *lobbyItem = dynamic_cast(c) ; - if(lobbyItem != NULL) - { - m.lobby_peer_gxs_id = lobbyItem->signature.keyId ; - m.chat_id = ChatId(lobbyItem->lobby_id); - return; - } - - DistantChatPeerInfo dcpinfo; - if(DistantChatService::getDistantChatStatus(DistantChatPeerId(c->PeerId()), dcpinfo)) - m.chat_id = ChatId(DistantChatPeerId(c->PeerId())); - - if (c -> chatFlags & RS_CHAT_FLAG_PRIVATE) - m.chatflags |= RS_CHAT_PRIVATE; - else - { - m.chat_id = ChatId::makeBroadcastId(); - m.broadcast_peer_id = c->PeerId(); - m.chatflags |= RS_CHAT_PUBLIC; - } -} - -void p3ChatService::setOwnCustomStateString(const std::string& s) -{ - std::set onlineList; - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice: Setting own state string to new value : " << s << std::endl ; -#endif - _custom_status_string = s ; - - for(std::map::iterator it(_state_strings.begin());it!=_state_strings.end();++it) - it->second._own_is_new = true ; - - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, onlineList); - } - - RsServer::notify()->notifyOwnStatusMessageChanged() ; - - // alert your online peers to your newly set status - std::set::iterator it(onlineList.begin()); - for(; it != onlineList.end(); ++it){ - - RsChatStatusItem *cs = new RsChatStatusItem(); - cs->flags = RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE; - cs->status_string = ""; - cs->PeerId(*it); - sendItem(cs); - } - - IndicateConfigChanged(); -} - -void p3ChatService::setOwnAvatarJpegData(const unsigned char *data,int size) -{ - { - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice: Setting own avatar to new image." << std::endl ; -#endif - - if((uint32_t)size > MAX_AVATAR_JPEG_SIZE) - { - std::cerr << "Supplied avatar image is too big. Maximum size is " << MAX_AVATAR_JPEG_SIZE << ", supplied image has size " << size << std::endl; - return ; - } - if(_own_avatar != NULL) - delete _own_avatar ; - - _own_avatar = new AvatarInfo(data,size) ; - - // set the info that our avatar is new, for all peers - for(std::map::iterator it(_avatars.begin());it!=_avatars.end();++it) - it->second->_own_is_new = true ; - } - IndicateConfigChanged(); - - RsServer::notify()->notifyOwnAvatarChanged() ; - -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice:setOwnAvatarJpegData() done." << std::endl ; -#endif - -} - -void p3ChatService::receiveStateString(const RsPeerId& id,const std::string& s) -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice: received custom state string for peer " << id << ". Storing it." << std::endl ; -#endif - - bool new_peer = (_state_strings.find(id) == _state_strings.end()) ; - - _state_strings[id]._custom_status_string = s ; - _state_strings[id]._peer_is_new = true ; - _state_strings[id]._own_is_new = new_peer ; -} - -void p3ChatService::receiveAvatarJpegData(RsChatAvatarItem *ci) -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice: received avatar jpeg data for peer " << ci->PeerId() << ". Storing it." << std::endl ; -#endif - - if(ci->image_size > MAX_AVATAR_JPEG_SIZE) - { - std::cerr << "Peer " << ci->PeerId()<< " is sending a jpeg image for avatar that exceeds the admitted size (size=" << ci->image_size << ", max=" << MAX_AVATAR_JPEG_SIZE << ")"<< std::endl; - return ; - } - bool new_peer = (_avatars.find(ci->PeerId()) == _avatars.end()) ; - - if (new_peer == false && _avatars[ci->PeerId()]) { - delete _avatars[ci->PeerId()]; - } - _avatars[ci->PeerId()] = new AvatarInfo(ci->image_data,ci->image_size) ; - _avatars[ci->PeerId()]->_peer_is_new = true ; - _avatars[ci->PeerId()]->_own_is_new = new_peer ; -} - -std::string p3ChatService::getOwnCustomStateString() -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - return _custom_status_string ; -} -void p3ChatService::getOwnAvatarJpegData(unsigned char *& data,int& size) -{ - // should be a Mutex here. - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - uint32_t s = 0 ; -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice:: own avatar requested from above. " << std::endl ; -#endif - // has avatar. Return it strait away. - // - if(_own_avatar != NULL) - { - _own_avatar->toUnsignedChar(data,s) ; - size = s ; - } - else - { - data=NULL ; - size=0 ; - } -} - -std::string p3ChatService::getCustomStateString(const RsPeerId& peer_id) -{ - { - // should be a Mutex here. - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _state_strings.find(peer_id) ; - - // has it. Return it strait away. - // - if(it!=_state_strings.end()) - { - it->second._peer_is_new = false ; - return it->second._custom_status_string ; - } - } - - sendCustomStateRequest(peer_id); - return std::string() ; -} - -void p3ChatService::getAvatarJpegData(const RsPeerId& peer_id,unsigned char *& data,int& size) -{ - { - // should be a Mutex here. - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it = _avatars.find(peer_id) ; - -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice:: avatar for peer " << peer_id << " requested from above. " << std::endl ; -#endif - // has avatar. Return it straight away. - // - if(it!=_avatars.end()) - { - uint32_t s=0 ; - it->second->toUnsignedChar(data,s) ; - size = s ; - it->second->_peer_is_new = false ; -#ifdef CHAT_DEBUG - std::cerr << "Already has avatar. Returning it" << std::endl ; -#endif - return ; - } else { -#ifdef CHAT_DEBUG - std::cerr << "No avatar for this peer. Requesting it by sending request packet." << std::endl ; -#endif - } - } - - sendAvatarRequest(peer_id); -} - -void p3ChatService::sendAvatarRequest(const RsPeerId& peer_id) -{ - if(!isOnline(peer_id)) - return ; - - // Doesn't have avatar. Request it. - // - RsChatMsgItem *ci = new RsChatMsgItem(); - - ci->PeerId(peer_id); - ci->chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_REQUESTS_AVATAR ; - ci->sendTime = time(NULL); - ci->message.erase(); - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sending request for avatar, to peer " << peer_id << std::endl ; - std::cerr << std::endl; -#endif - - sendChatItem(ci); -} - -void p3ChatService::sendCustomStateRequest(const RsPeerId& peer_id){ - - if(!isOnline(peer_id)) - return ; - - RsChatStatusItem* cs = new RsChatStatusItem; - - cs->PeerId(peer_id); - cs->flags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_REQUEST_CUSTOM_STATE ; - cs->status_string.erase(); - -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sending request for status, to peer " << peer_id << std::endl ; - std::cerr << std::endl; -#endif - - sendChatItem(cs); -} - -RsChatStatusItem *p3ChatService::makeOwnCustomStateStringItem() -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - RsChatStatusItem *ci = new RsChatStatusItem(); - - ci->flags = RS_CHAT_FLAG_CUSTOM_STATE ; - ci->status_string = _custom_status_string ; - - return ci ; -} - -RsChatAvatarItem *p3ChatService::makeOwnAvatarItem() -{ - RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ - RsChatAvatarItem *ci = new RsChatAvatarItem(); - - _own_avatar->toUnsignedChar(ci->image_data,ci->image_size) ; - - return ci ; -} - - -void p3ChatService::sendAvatarJpegData(const RsPeerId& peer_id) -{ -#ifdef CHAT_DEBUG - std::cerr << "p3chatservice: sending requested for peer " << peer_id << ", data=" << (void*)_own_avatar << std::endl ; -#endif - - if(_own_avatar != NULL) - { - RsChatAvatarItem *ci = makeOwnAvatarItem(); - ci->PeerId(peer_id); - - // take avatar, and embed it into a std::string. - // -#ifdef CHAT_DEBUG - std::cerr << "p3ChatService::sending avatar image to peer" << peer_id << ", image size = " << ci->image_size << std::endl ; - std::cerr << std::endl; -#endif - - sendChatItem(ci) ; - } - else { -#ifdef CHAT_DEBUG - std::cerr << "We have no avatar yet: Doing nothing" << std::endl ; -#endif - } -} - -void p3ChatService::sendCustomState(const RsPeerId& peer_id){ - -#ifdef CHAT_DEBUG -std::cerr << "p3chatservice: sending requested status string for peer " << peer_id << std::endl ; -#endif - - RsChatStatusItem *cs = makeOwnCustomStateStringItem(); - cs->PeerId(peer_id); - - sendChatItem(cs); -} - -bool p3ChatService::loadList(std::list& load) -{ - std::list ssl_peers; - mLinkMgr->getFriendList(ssl_peers); - - for(std::list::const_iterator it(load.begin());it!=load.end();++it) - { - if(PrivateOugoingMapItem* om=dynamic_cast(*it)) - { - RS_STACK_MUTEX(mChatMtx); - for( auto& pair : om->store ) - { - privateOutgoingMap.insert( - outMP::value_type(pair.first, - new RsChatMsgItem(pair.second)) ); - } - - delete om; continue; - } - - - RsChatAvatarItem *ai = NULL ; - - if(NULL != (ai = dynamic_cast(*it))) - { - RS_STACK_MUTEX(mChatMtx); - - if(ai->image_size <= MAX_AVATAR_JPEG_SIZE) - _own_avatar = new AvatarInfo(ai->image_data,ai->image_size) ; - else - std::cerr << "Dropping avatar image, because its size is " - << ai->image_size << ", and the maximum allowed size " - << "is " << MAX_AVATAR_JPEG_SIZE << std::endl; - - delete *it; - continue; - } - - RsChatStatusItem *mitem = NULL ; - - if(NULL != (mitem = dynamic_cast(*it))) - { - RS_STACK_MUTEX(mChatMtx); - - _custom_status_string = mitem->status_string ; - - delete *it; - continue; - } - - /* TODO: G10h4ck 2017/02/27 this block is kept for retrocompatibility, - * and will be used just first time, to load messages in the old format - * should be removed in the following RS version */ - if( RsPrivateChatMsgConfigItem *citem = - dynamic_cast(*it) ) - { - RS_STACK_MUTEX(mChatMtx); - - if ( citem->chatFlags & RS_CHAT_FLAG_PRIVATE ) - { - if ( std::find(ssl_peers.begin(), ssl_peers.end(), - citem->configPeerId) != ssl_peers.end() ) - { - RsChatMsgItem *ci = new RsChatMsgItem(); - citem->get(ci); - - if (citem->configFlags & RS_CHATMSG_CONFIGFLAG_INCOMING) - { - locked_storeIncomingMsg(ci); - } - else privateOutgoingMap.insert( - outMP::value_type(RSRandom::random_u64(), ci) ); - } - else { /* no friends */ } - } - else { /* ignore all other items */ } - - delete *it; - continue; - } - - DistributedChatService::processLoadListItem(*it) ; - DistantChatService::processLoadListItem(*it) ; - - // delete unknown items - delete *it; - } - - load.clear() ; - return true; -} - -bool p3ChatService::saveList(bool& cleanup, std::list& list) -{ - cleanup = true; - - /* now we create a pqistore, and stream all the msgs into it */ - - if(_own_avatar != NULL) - { - RsChatAvatarItem *ci = makeOwnAvatarItem() ; - ci->PeerId(mServiceCtrl->getOwnId()); - - list.push_back(ci) ; - } - - mChatMtx.lock(); /****** MUTEX LOCKED *******/ - - PrivateOugoingMapItem* om = new PrivateOugoingMapItem; - typedef std::map::value_type vT; - for( auto& pair : privateOutgoingMap ) - om->store.insert(vT(pair.first, *pair.second)); - list.push_back(om); - - - RsChatStatusItem *di = new RsChatStatusItem ; - di->status_string = _custom_status_string ; - di->flags = RS_CHAT_FLAG_CUSTOM_STATE ; - - list.push_back(di); - - DistributedChatService::addToSaveList(list) ; - DistantChatService::addToSaveList(list) ; - - return true; -} - -void p3ChatService::saveDone() -{ - /* unlock mutex */ - mChatMtx.unlock(); /****** MUTEX UNLOCKED *******/ -} - -RsSerialiser *p3ChatService::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsChatSerialiser) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss ; -} - -/*************** pqiMonitor callback ***********************/ - -void p3ChatService::statusChange(const std::list &plist) -{ - for (auto it = plist.cbegin(); it != plist.cend(); ++it) - { - if (it->actions & RS_SERVICE_PEER_CONNECTED) - { - /* send the saved outgoing messages */ - bool changed = false; - - std::vector to_send; - - { - RS_STACK_MUTEX(mChatMtx); - - for( auto cit = privateOutgoingMap.begin(); - cit != privateOutgoingMap.end(); ) - { - RsChatMsgItem *c = cit->second; - if (c->PeerId() == it->id) - { - //mHistoryMgr->addMessage(false, c->PeerId(), ownId, c); - - to_send.push_back(c) ; - changed = true; - cit = privateOutgoingMap.erase(cit); - continue; - } - - ++cit; - } - } - - for(auto toIt = to_send.begin(); toIt != to_send.end(); ++toIt) - { - ChatMessage message; - initChatMessage(*toIt, message); - message.incoming = false; - message.online = true; - RsServer::notify()->notifyChatMessage(message); - - checkSizeAndSendMessage(*toIt); // delete item - } - - if (changed) - { - RsServer::notify()->notifyListChange( - NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL); - - IndicateConfigChanged(); - } - } - else if (it->actions & RS_SERVICE_PEER_REMOVED) - { - /* now handle remove */ - mHistoryMgr->clear(ChatId(it->id)); - - RS_STACK_MUTEX(mChatMtx); - for ( auto cit = privateOutgoingMap.begin(); - cit != privateOutgoingMap.end(); ) - { - RsChatMsgItem *c = cit->second; - if (c->PeerId() == it->id) cit = privateOutgoingMap.erase(cit); - else ++cit; - } - IndicateConfigChanged(); - } - } -} diff --git a/libretroshare/src/chat/p3chatservice.h b/libretroshare/src/chat/p3chatservice.h deleted file mode 100644 index bc4dd56b9..000000000 --- a/libretroshare/src/chat/p3chatservice.h +++ /dev/null @@ -1,305 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: chatservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef SERVICE_CHAT_HEADER -#define SERVICE_CHAT_HEADER - -#include -#include -#include - -#include "rsitems/rsmsgitems.h" -#include "services/p3service.h" -#include "pqi/pqiservicemonitor.h" -#include "chat/distantchat.h" -#include "chat/distributedchat.h" -#include "retroshare/rsmsgs.h" -#include "gxstrans/p3gxstrans.h" -#include "util/rsdeprecate.h" - -class p3ServiceControl; -class p3LinkMgr; -class p3HistoryMgr; - -typedef RsPeerId ChatLobbyVirtualPeerId ; - -struct RsChatMessageEvent : RsEvent -{ - RsChatMessageEvent() : RsEvent(RsEventType::CHAT_MESSAGE) {} - ~RsChatMessageEvent() override = default; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mChatMessage); - } - - ChatMessage mChatMessage; -}; - -//!The basic Chat service. - /** - * - * Can be used to send and receive chats, immediate status (using notify), avatars, and custom status - * This service uses rsnotify (callbacks librs clients (e.g. rs-gui)) - * @see NotifyBase - */ -class p3ChatService : - public p3Service, public DistantChatService, public DistributedChatService, public p3Config, - public pqiServiceMonitor, GxsTransClient -{ -public: - p3ChatService(p3ServiceControl *cs, p3IdService *pids, p3LinkMgr *cm, - p3HistoryMgr *historyMgr, p3GxsTrans& gxsTransService ); - - virtual RsServiceInfo getServiceInfo(); - - /***** 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(); - - /*************** pqiMonitor callback ***********************/ - virtual void statusChange(const std::list &plist); - - /*! - * public chat sent to all peers - */ - void sendPublicChat(const std::string &msg); - - /********* RsMsgs ***********/ - /*! - * Send a chat message. - * @param destination where to send the chat message - * @param msg the message - * @see ChatId - */ - bool sendChat(ChatId destination, std::string msg); - - /*! - * chat is sent to specifc peer - * @param id peer to send chat msg to - */ - bool sendPrivateChat(const RsPeerId &id, const std::string &msg); - - /** - * can be used to send 'immediate' status msgs, these status updates are - * meant for immediate use by peer (not saved by rs) e.g currently used to - * update user when a peer 'is typing' during a chat */ - void sendStatusString( const ChatId& id, const std::string& status_str ); - - /** - * @brief clearChatLobby: Signal chat was cleared by GUI. - * @param id: Chat id cleared. - */ - virtual void clearChatLobby(const ChatId& id); - - /*! - * send to all peers online - *@see sendStatusString() - */ - void sendGroupChatStatusString(const std::string& status_str) ; - - /*! - * this retrieves custom status for a peers, generate a requests to the peer - * @param peer_id the id of the peer you want status string for - */ - std::string getCustomStateString(const RsPeerId& peer_id) ; - - /*! - * sets the client's custom status, generates 'status available' item sent to all online peers - */ - void setOwnCustomStateString(const std::string&) ; - - /*! - * @return client's custom string - */ - std::string getOwnCustomStateString() ; - - /*! gets the peer's avatar in jpeg format, if available. Null otherwise. Also asks the peer to send - * its avatar, if not already available. Creates a new unsigned char array. It's the caller's - * responsibility to delete this ones used. - */ - void getAvatarJpegData(const RsPeerId& peer_id,unsigned char *& data,int& size) ; - - /*! - * Sets the avatar data and size for client's account - * @param data is copied, so should be destroyed by the caller - */ - void setOwnAvatarJpegData(const unsigned char *data,int size) ; - - /*! - * Gets the avatar data for clients account - * data is in jpeg format - */ - void getOwnAvatarJpegData(unsigned char *& data,int& size) ; - - /*! - * Return the max message size for security forwarding - * @param type RS_CHAT_TYPE_... - * return 0 unlimited - */ - static uint32_t getMaxMessageSecuritySize(int type); - - /*! - * Checks message security, especially remove billion laughs attacks - */ - - static bool checkForMessageSecurity(RsChatMsgItem *) ; - - /*! - * @param clear private chat queue - */ - bool clearPrivateChatQueue(bool incoming, const RsPeerId &id); - - virtual bool initiateDistantChatConnexion( const RsGxsId& to_gxs_id, - const RsGxsId& from_gxs_id, - DistantChatPeerId &pid, - uint32_t& error_code, - bool notify = true ); - - /// @see GxsTransClient::receiveGxsTransMail(...) - virtual bool receiveGxsTransMail( const RsGxsId& authorId, - const RsGxsId& recipientId, - const uint8_t* data, uint32_t dataSize ); - - /// @see GxsTransClient::notifySendMailStatus(...) - virtual bool notifyGxsTransSendStatus( RsGxsTransId mailId, - GxsTransSendStatus status ); - - -protected: - /************* from p3Config *******************/ - virtual RsSerialiser *setupSerialiser() ; - - /*! - * chat msg items and custom status are saved - */ - virtual bool saveList(bool& cleanup, std::list&) ; - virtual void saveDone(); - virtual bool loadList(std::list& load) ; - - // accepts virtual peer id - bool isOnline(const RsPeerId &pid) ; - - /// This is to be used by subclasses/parents to call IndicateConfigChanged() - virtual void triggerConfigSave() { IndicateConfigChanged() ; } - - /// Same, for storing messages in incoming list - RS_DEPRECATED virtual void locked_storeIncomingMsg(RsChatMsgItem *) ; - -private: - RsMutex mChatMtx; - - class AvatarInfo ; - class StateStringInfo ; - - // Receive chat queue - void receiveChatQueue(); - void handleIncomingItem(RsItem *); // called by the former, and turtle handler for incoming encrypted items - - virtual void sendChatItem(RsChatItem *) ; - - void initChatMessage(RsChatMsgItem *c, ChatMessage& msg); - - /// Send avatar info to peer in jpeg format. - void sendAvatarJpegData(const RsPeerId& peer_id) ; - - /// Send custom state info to peer - void sendCustomState(const RsPeerId& peer_id); - - /// Receive the avatar in a chat item, with RS_CHAT_RECEIVE_AVATAR flag. - void receiveAvatarJpegData(RsChatAvatarItem *ci) ; // new method - void receiveStateString(const RsPeerId& id,const std::string& s) ; - - /// methods for handling various Chat items. - virtual bool handleRecvChatMsgItem(RsChatMsgItem *&item) ; // NULL-ifies the item if memory ownership is taken - - void handleRecvChatStatusItem(RsChatStatusItem *item) ; - void handleRecvChatAvatarItem(RsChatAvatarItem *item) ; - - /// Sends a request for an avatar to the peer of given id - void sendAvatarRequest(const RsPeerId& peer_id) ; - - /// Send a request for custom status string - void sendCustomStateRequest(const RsPeerId& peer_id); - - /// called as a proxy to sendItem(). Possibly splits item into multiple items of size lower than the maximum item size. - //void checkSizeAndSendMessage(RsChatLobbyMsgItem *item) ; - void checkSizeAndSendMessage(RsChatMsgItem *item) ; // keep for compatibility for a few weeks. - - /// Called when a RsChatMsgItem is received. The item may be collapsed with any waiting partial chat item from the same peer. - /// if so, the chat item will be turned to NULL - bool locked_checkAndRebuildPartialMessage(RsChatMsgItem *&) ; - - RsChatAvatarItem *makeOwnAvatarItem() ; - RsChatStatusItem *makeOwnCustomStateStringItem() ; - - p3ServiceControl *mServiceCtrl; - p3LinkMgr *mLinkMgr; - p3HistoryMgr *mHistoryMgr; - - /// messages waiting to be send when peer comes online - typedef std::map outMP; - outMP privateOutgoingMap; - - AvatarInfo *_own_avatar ; - std::map _avatars ; - std::map _pendingPartialMessages; - - std::string _custom_status_string ; - std::map _state_strings ; - - RsChatSerialiser *_serializer; - - struct DistantEndpoints { RsGxsId from; RsGxsId to; }; - typedef std::map DIDEMap; - DIDEMap mDistantGxsMap; - RsMutex mDGMutex; - - p3GxsTrans& mGxsTransport; -}; - -class p3ChatService::StateStringInfo -{ - public: - StateStringInfo() - { - _custom_status_string = "" ; // the custom status string of the peer - _peer_is_new = false ; // true when the peer has a new avatar - _own_is_new = false ; // true when I myself a new avatar to send to this peer. - } - - std::string _custom_status_string ; - int _peer_is_new ; // true when the peer has a new avatar - int _own_is_new ; // true when I myself a new avatar to send to this peer. -}; - -#endif // SERVICE_CHAT_HEADER - diff --git a/libretroshare/src/chat/rschatitems.cc b/libretroshare/src/chat/rschatitems.cc deleted file mode 100644 index 13d272c4e..000000000 --- a/libretroshare/src/chat/rschatitems.cc +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: rschatitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include "retroshare/rsmsgs.h" -#include "util/rstime.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" - -#include "serialiser/rstypeserializer.h" - -#include "chat/rschatitems.h" - -//#define CHAT_DEBUG 1 - -//static const uint32_t RS_CHAT_SERIALIZER_FLAGS_NO_SIGNATURE = 0x0001; - -RsItem *RsChatSerialiser::create_item(uint16_t service_id,uint8_t item_sub_id) const -{ - if(service_id != RS_SERVICE_TYPE_CHAT) return NULL; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(); - case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(); - case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(); - case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG: return new RsChatLobbyMsgItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE: return new RsChatLobbyInviteItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED: return new RsChatLobbyInviteItem_Deprecated(); // to be removed (deprecated since May 2017) - case RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE: return new RsChatLobbyConnectChallengeItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: return new RsChatLobbyUnsubscribeItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT: return new RsChatLobbyEventItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: return new RsChatLobbyListRequestItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: return new RsChatLobbyListItem(); - case RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG: return new RsChatLobbyConfigItem(); - case RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG: return new RsSubscribedChatLobbyConfigItem(); - case RS_PKT_SUBTYPE_OUTGOING_MAP: return new PrivateOugoingMapItem(); - default: - std::cerr << "Unknown packet type in chat!" << std::endl; - return NULL; - } -} - -void RsChatMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,chatFlags,"chatflags") ; - RsTypeSerializer::serial_process(j,ctx,sendTime,"sendTime") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,message,"message") ; -} - -/*************************************************************************/ - -void RsChatLobbyBouncingObject::serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,lobby_id,"lobby_id") ; - RsTypeSerializer::serial_process(j,ctx,msg_id ,"msg_id") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,nick,"nick") ; - - if(!(ctx.mFlags & RsSerializationFlags::SIGNATURE)) - RS_SERIAL_PROCESS(signature); -} - -void RsChatLobbyMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsChatMsgItem::serial_process(j,ctx) ; - RsTypeSerializer::serial_process(j,ctx,parent_msg_id,"parent_msg_id") ; - RsChatLobbyBouncingObject::serial_process(j,ctx) ; -} - -void RsChatLobbyListRequestItem::serial_process(RsGenericSerializer::SerializeJob /*j*/,RsGenericSerializer::SerializeContext& /*ctx*/) -{ - // nothing to do. This is an empty item. -} - -template<> void RsTypeSerializer::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,VisibleChatLobbyInfo& info,const std::string& /*name*/) -{ - RsTypeSerializer::serial_process(j,ctx,info.id,"info.id") ; - - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,info.name, "info.name") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,info.topic,"info.topic") ; - RsTypeSerializer::serial_process(j,ctx, info.count,"info.count") ; - RsTypeSerializer::serial_process (j,ctx, info.flags,"info.flags") ; -} - -void RsChatLobbyListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,lobbies,"lobbies") ; -} - -void RsChatLobbyEventItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,event_type,"event_type") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,string1,"string1") ; - RsTypeSerializer::serial_process(j,ctx,sendTime ,"sendTime") ; - - RsChatLobbyBouncingObject::serial_process(j,ctx) ; -} -void RsChatLobbyUnsubscribeItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,lobby_id,"lobby_id") ; -} - -void RsChatLobbyConnectChallengeItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,challenge_code,"challenge_code") ; -} - -// to be removed (deprecated since May 2017) -void RsChatLobbyInviteItem_Deprecated::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx, lobby_id, "lobby_id") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,lobby_name, "lobby_name") ; - RsTypeSerializer::serial_process (j,ctx, lobby_flags,"lobby_flags") ; -} - -void RsChatLobbyInviteItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx, lobby_id, "lobby_id") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,lobby_name, "lobby_name") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,lobby_topic,"lobby_topic") ; - RsTypeSerializer::serial_process (j,ctx, lobby_flags,"lobby_flags") ; -} - -void RsPrivateChatMsgConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - uint32_t x=0 ; - - RsTypeSerializer::serial_process(j,ctx, x, "place holder value") ; - RsTypeSerializer::serial_process (j,ctx, configPeerId,"configPeerId") ; - RsTypeSerializer::serial_process(j,ctx, chatFlags, "chatFlags") ; - RsTypeSerializer::serial_process(j,ctx, sendTime, "sendTime") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_MSG,message, "message") ; - RsTypeSerializer::serial_process(j,ctx, recvTime, "recvTime") ; -} - -void RsChatStatusItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,flags,"flags") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,status_string,"status_string") ; -} - -void RsChatAvatarItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::TlvMemBlock_proxy b(image_data,image_size) ; - RsTypeSerializer::serial_process(j,ctx,b,"image data") ; -} - -void RsSubscribedChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - info.serial_process(j,ctx); -} - -void RsChatLobbyConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,lobby_Id,"lobby_Id") ; - RsTypeSerializer::serial_process(j,ctx,flags,"flags") ; -} - -/* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */ -void RsPrivateChatMsgConfigItem::set(RsChatMsgItem *ci, const RsPeerId& /*peerId*/, uint32_t confFlags) -{ - PeerId(ci->PeerId()); - configPeerId = ci->PeerId(); - chatFlags = ci->chatFlags; - configFlags = confFlags; - sendTime = ci->sendTime; - message = ci->message; - recvTime = ci->recvTime; -} - -/* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */ -void RsPrivateChatMsgConfigItem::get(RsChatMsgItem *ci) -{ - ci->PeerId(configPeerId); - ci->chatFlags = chatFlags; - //configFlags not used - ci->sendTime = sendTime; - ci->message = message; - ci->recvTime = recvTime; -} - - -void PrivateOugoingMapItem::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ RS_SERIAL_PROCESS(store); } diff --git a/libretroshare/src/chat/rschatitems.h b/libretroshare/src/chat/rschatitems.h deleted file mode 100644 index aca3a411a..000000000 --- a/libretroshare/src/chat/rschatitems.h +++ /dev/null @@ -1,383 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: rschatitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include "openssl/bn.h" -#include "retroshare/rstypes.h" -#include "serialiser/rsserializer.h" -#include "serialiser/rstlvkeys.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "rsitems/rsitem.h" -#include "serialiser/rsserial.h" -#include "util/rsdeprecate.h" - -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvfileitem.h" -#include "retroshare/rsmsgs.h" - -/* chat Flags */ -const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001; -const uint32_t RS_CHAT_FLAG_REQUESTS_AVATAR = 0x0002; -const uint32_t RS_CHAT_FLAG_CONTAINS_AVATAR = 0x0004; -const uint32_t RS_CHAT_FLAG_AVATAR_AVAILABLE = 0x0008; -const uint32_t RS_CHAT_FLAG_CUSTOM_STATE = 0x0010; // used for transmitting peer status string -const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020; -const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040; -const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080; -const uint32_t RS_CHAT_FLAG_PARTIAL_MESSAGE = 0x0100; -const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200; -const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400; -const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800; -const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000; -const uint32_t RS_CHAT_FLAG_CONNEXION_REFUSED = 0x2000; - -const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001; - -const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ; -const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_ACCEPT = 0x08 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; // will be deprecated when only signed messages are accepted (02/2015) -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_deprecated = 0x0F ; // to be removed -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012) -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated3 = 0x12 ; -const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ; -const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG = 0x17 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT = 0x18 ; -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x19 ; - -RS_DEPRECATED_FOR(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE) \ -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED = 0x1A ; // to be removed (deprecated since May 2017) - -const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1B ; -const uint8_t RS_PKT_SUBTYPE_OUTGOING_MAP = 0x1C ; - -const uint8_t RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG = 0x1D ; - -typedef uint64_t ChatLobbyId ; -typedef uint64_t ChatLobbyMsgId ; -typedef std::string ChatLobbyNickName ; -typedef uint64_t DistantChatDHSessionId ; - -class RsChatItem: public RsItem -{ - public: - RsChatItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_CHAT,chat_subtype) - { - setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ; - } - - virtual ~RsChatItem() {} - virtual void clear() {} -}; - -/*! - * For sending chat msgs - * @see p3ChatService - */ -class RsChatMsgItem: public RsChatItem -{ -public: - RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {} - RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {} - - //RsChatMsgItem() {} - - virtual ~RsChatMsgItem() {} - - // derived from RsItem - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear() {} - - uint32_t chatFlags; - uint32_t sendTime; - std::string message; - - /* not serialised */ - uint32_t recvTime; -}; - -// This class contains the info to bounce an object throughout a lobby, while -// maintaining cache info to avoid duplicates. -// -class RsChatLobbyBouncingObject -{ -public: - ChatLobbyId lobby_id ; - ChatLobbyMsgId msg_id ; - ChatLobbyNickName nick ; // Nickname of sender - - RsTlvKeySignature signature ; - - virtual RsChatLobbyBouncingObject *duplicate() const = 0 ; - -protected: - // The functions below handle the serialisation of data that is specific to the bouncing object level. - // They are called by serial_size() and serialise() from children, but should not overload the serial_size() and - // serialise() methods, otherwise the wrong method will be called when serialising from this top level class. - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual uint32_t PacketId() const= 0; -}; - -class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject -{ -public: - RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG) {} - - virtual ~RsChatLobbyMsgItem() {} - virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; } - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - ChatLobbyMsgId parent_msg_id ; // Used for threaded chat. - -protected: - virtual uint32_t PacketId() const { return RsChatMsgItem::PacketId() ; } -}; - -class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject -{ -public: - RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {} - - virtual ~RsChatLobbyEventItem() {} - virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; } - // - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // members. - // - uint8_t event_type ; // used for defining the type of event. - std::string string1; // used for any string - uint32_t sendTime; // used to check for old looping messages - -protected: - virtual uint32_t PacketId() const { return RsChatItem::PacketId() ; } -}; - -class RsChatLobbyListRequestItem: public RsChatItem -{ - public: - RsChatLobbyListRequestItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST) {} - virtual ~RsChatLobbyListRequestItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -struct VisibleChatLobbyInfo -{ - ChatLobbyId id ; - std::string name ; - std::string topic ; - uint32_t count ; - ChatLobbyFlags flags ; -}; - -class RsChatLobbyListItem: public RsChatItem -{ - public: - RsChatLobbyListItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST) {} - virtual ~RsChatLobbyListItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - std::vector lobbies ; -}; - -class RsChatLobbyUnsubscribeItem: public RsChatItem -{ - public: - RsChatLobbyUnsubscribeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE) {} - - virtual ~RsChatLobbyUnsubscribeItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint64_t lobby_id ; -}; - -class RsChatLobbyConnectChallengeItem: public RsChatItem -{ - public: - RsChatLobbyConnectChallengeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE) {} - - virtual ~RsChatLobbyConnectChallengeItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint64_t challenge_code ; -}; - -/// @deprecated since May 2017, to be removed -class RsChatLobbyInviteItem_Deprecated : public RsChatItem -{ - public: - RsChatLobbyInviteItem_Deprecated() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPRECATED) {} - virtual ~RsChatLobbyInviteItem_Deprecated() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - ChatLobbyId lobby_id ; - std::string lobby_name ; - std::string lobby_topic ; - ChatLobbyFlags lobby_flags ; -}; - -class RsChatLobbyInviteItem: public RsChatItem -{ - public: - RsChatLobbyInviteItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE) {} - virtual ~RsChatLobbyInviteItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - ChatLobbyId lobby_id ; - std::string lobby_name ; - std::string lobby_topic ; - ChatLobbyFlags lobby_flags ; -}; - -/*! - * For saving incoming and outgoing chat msgs - * @see p3ChatService - */ -struct RsPrivateChatMsgConfigItem : RsChatItem -{ - RsPrivateChatMsgConfigItem() : - RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG) {} - - virtual ~RsPrivateChatMsgConfigItem() {} - virtual void clear() {} - - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - - /** set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */ - void set(RsChatMsgItem *ci, const RsPeerId &peerId, uint32_t confFlags); - /** get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */ - void get(RsChatMsgItem *ci); - - RsPeerId configPeerId; - uint32_t chatFlags; - uint32_t configFlags; - uint32_t sendTime; - std::string message; - uint32_t recvTime; -}; - -class RsSubscribedChatLobbyConfigItem: public RsChatItem -{ -public: - RsSubscribedChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_SUBSCRIBED_CHAT_LOBBY_CONFIG) {} - virtual ~RsSubscribedChatLobbyConfigItem() {} - - virtual void clear() { RsChatItem::clear(); info.clear(); } - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - ChatLobbyInfo info; -}; - -class RsChatLobbyConfigItem: public RsChatItem -{ -public: - RsChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG) { lobby_Id = 0; } - - virtual ~RsChatLobbyConfigItem() {} - - virtual void clear() { lobby_Id = 0; } - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint64_t lobby_Id; - uint32_t flags ; -}; - -// This class contains activity info for the sending peer: active, idle, typing, etc. -// -class RsChatStatusItem: public RsChatItem -{ - public: - RsChatStatusItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_STATUS) {} - - virtual ~RsChatStatusItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t flags ; - std::string status_string; -}; - -// This class contains avatar images in Qt format. -// -class RsChatAvatarItem: public RsChatItem -{ -public: - RsChatAvatarItem(): - RsChatItem(RS_PKT_SUBTYPE_CHAT_AVATAR), - image_size(0), image_data(nullptr) - { setPriorityLevel(QOS_PRIORITY_RS_CHAT_AVATAR_ITEM); } - - ~RsChatAvatarItem() override { free(image_data); } - - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override; - - uint32_t image_size; /// size of data in bytes - unsigned char* image_data ; /// image data -}; - - -struct PrivateOugoingMapItem : RsChatItem -{ - PrivateOugoingMapItem() : RsChatItem(RS_PKT_SUBTYPE_OUTGOING_MAP) {} - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - - std::map store; -}; - -struct RsChatSerialiser : RsServiceSerializer -{ - RsChatSerialiser(RsSerializationFlags flags = RsSerializationFlags::NONE): - RsServiceSerializer(RS_SERVICE_TYPE_CHAT, flags) {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const; -}; - diff --git a/libretroshare/src/crypto/chacha20.cpp b/libretroshare/src/crypto/chacha20.cpp deleted file mode 100644 index ebda0ee3c..000000000 --- a/libretroshare/src/crypto/chacha20.cpp +++ /dev/null @@ -1,1421 +0,0 @@ -/******************************************************************************* - * libretroshare/src/crypto: chacha20.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "crypto/chacha20.h" -#include "util/rsprint.h" -#include "util/rsrandom.h" -#include "util/rstime.h" - -#define rotl(x,n) { x = (x << n) | (x >> (-n & 31)) ;} - -//#define DEBUG_CHACHA20 - -#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) - #define AEAD_chacha20_poly1305_openssl AEAD_chacha20_poly1305 -#else - #define AEAD_chacha20_poly1305_rs AEAD_chacha20_poly1305 -#endif - -namespace librs { -namespace crypto { - -/*! - * \brief The uint256_32 struct - * This structure represents 256bits integers, to be used for computing poly1305 authentication tags. - */ -struct uint256_32 -{ - uint32_t b[8] ; - - uint256_32() { memset(&b[0],0,8*sizeof(uint32_t)) ; } - - uint256_32(uint32_t b7,uint32_t b6,uint32_t b5,uint32_t b4,uint32_t b3,uint32_t b2,uint32_t b1,uint32_t b0) - { - b[0]=b0; b[1]=b1; b[2]=b2; b[3]=b3; - b[4]=b4; b[5]=b5; b[6]=b6; b[7]=b7; - } - - static uint256_32 random() - { - uint256_32 r ; - for(uint32_t i=0;i<8;++i) - r.b[i] = RSRandom::random_u32(); - - return r; - } - - // constant cost == - bool operator==(const uint256_32& u) - { - bool res = true ; - - if(b[0] != u.b[0]) res = false ; - if(b[1] != u.b[1]) res = false ; - if(b[2] != u.b[2]) res = false ; - if(b[3] != u.b[3]) res = false ; - if(b[4] != u.b[4]) res = false ; - if(b[5] != u.b[5]) res = false ; - if(b[6] != u.b[6]) res = false ; - if(b[7] != u.b[7]) res = false ; - - return res ; - } - - // Constant cost sum. - // - void operator +=(const uint256_32& u) - { - uint64_t v(0) ; - - v += (uint64_t)b[0] + (uint64_t)u.b[0] ; b[0] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[1] + (uint64_t)u.b[1] ; b[1] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[2] + (uint64_t)u.b[2] ; b[2] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[3] + (uint64_t)u.b[3] ; b[3] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[4] + (uint64_t)u.b[4] ; b[4] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[5] + (uint64_t)u.b[5] ; b[5] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[6] + (uint64_t)u.b[6] ; b[6] = (uint32_t)v ; v >>= 32; - v += (uint64_t)b[7] + (uint64_t)u.b[7] ; b[7] = (uint32_t)v ; - } - void operator -=(const uint256_32& u) - { - *this += ~u ; - ++*this ; - } - void operator++() - { - for(int i=0;i<8;++i) - if( ++b[i] ) - break ; - } - - bool operator<(const uint256_32& u) const - { - for(int i=7;i>=0;--i) - if(b[i] < u.b[i]) - return true ; - else - if(b[i] > u.b[i]) - return false ; - - return false ; - } - uint256_32 operator~() const - { - uint256_32 r(*this) ; - - r.b[0] = ~b[0] ; - r.b[1] = ~b[1] ; - r.b[2] = ~b[2] ; - r.b[3] = ~b[3] ; - r.b[4] = ~b[4] ; - r.b[5] = ~b[5] ; - r.b[6] = ~b[6] ; - r.b[7] = ~b[7] ; - - return r ; - } - - void poly1305clamp() - { - b[0] &= 0x0fffffff; - b[1] &= 0x0ffffffc; - b[2] &= 0x0ffffffc; - b[3] &= 0x0ffffffc; - } - // Constant cost product. - // - void operator *=(const uint256_32& u) - { - uint256_32 r ; - - for(int i=0;i<8;++i) - for(int j=0;j<8;++j) - if(i+j < 8) - { - uint64_t s = (uint64_t)u.b[j]*(uint64_t)b[i] ; - - uint256_32 partial ; - partial.b[i+j] = (s & 0xffffffff) ; - - if(i+j+1 < 8) - partial.b[i+j+1] = (s >> 32) ; - - r += partial; - } - *this = r; - } - - static void print(const uint256_32& s) - { - fprintf(stdout,"%08x %08x %08x %08x %08x %08x %08x %08x",(uint32_t)s.b[7],(uint32_t)s.b[6],(uint32_t)s.b[5],(uint32_t)s.b[4], - (uint32_t)s.b[3],(uint32_t)s.b[2],(uint32_t)s.b[1],(uint32_t)s.b[0]) ; - } - static int max_non_zero_of_height_bits(uint8_t s) - { - for(int i=7;i>=0;--i) - if((s & (1<=0;--c) - if(b[c] != 0) - { - if( (b[c] & 0xff000000) != 0) return (c<<5) + 3*8 + max_non_zero_of_height_bits(b[c] >> 24) ; - if( (b[c] & 0x00ff0000) != 0) return (c<<5) + 2*8 + max_non_zero_of_height_bits(b[c] >> 16) ; - if( (b[c] & 0x0000ff00) != 0) return (c<<5) + 1*8 + max_non_zero_of_height_bits(b[c] >> 8) ; - - return c*32 + 0*8 + max_non_zero_of_height_bits(b[c]) ; - } - return -1; - } - void lshift(uint32_t n) - { - uint32_t p = n >> 5; // n/32 - uint32_t u = n & 0x1f ; // n%32 - - if(p > 0) - for(int i=7;i>=0;--i) - b[i] = (i>=(int)p)?b[i-p]:0 ; - - uint32_t r = 0 ; - - if(u>0) - for(int i=0;i<8;++i) - { - uint32_t r1 = (b[i] >> (31-u+1)) ; - b[i] = (b[i] << u) & 0xffffffff; - b[i] += r ; - r = r1 ; - } - } - void lshift() - { - uint32_t r ; - uint32_t r1 ; - - r1 = (b[0] >> 31) ; b[0] <<= 1; r = r1 ; - r1 = (b[1] >> 31) ; b[1] <<= 1; b[1] += r ; r = r1 ; - r1 = (b[2] >> 31) ; b[2] <<= 1; b[2] += r ; r = r1 ; - r1 = (b[3] >> 31) ; b[3] <<= 1; b[3] += r ; r = r1 ; - r1 = (b[4] >> 31) ; b[4] <<= 1; b[4] += r ; r = r1 ; - r1 = (b[5] >> 31) ; b[5] <<= 1; b[5] += r ; r = r1 ; - r1 = (b[6] >> 31) ; b[6] <<= 1; b[6] += r ; r = r1 ; - b[7] <<= 1; b[7] += r ; - } - void rshift() - { - uint32_t r ; - uint32_t r1 ; - - r1 = b[7] & 0x1; b[7] >>= 1 ; r = r1 ; - r1 = b[6] & 0x1; b[6] >>= 1 ; if(r) b[6] += 0x80000000 ; r = r1 ; - r1 = b[5] & 0x1; b[5] >>= 1 ; if(r) b[5] += 0x80000000 ; r = r1 ; - r1 = b[4] & 0x1; b[4] >>= 1 ; if(r) b[4] += 0x80000000 ; r = r1 ; - r1 = b[3] & 0x1; b[3] >>= 1 ; if(r) b[3] += 0x80000000 ; r = r1 ; - r1 = b[2] & 0x1; b[2] >>= 1 ; if(r) b[2] += 0x80000000 ; r = r1 ; - r1 = b[1] & 0x1; b[1] >>= 1 ; if(r) b[1] += 0x80000000 ; r = r1 ; - b[0] >>= 1 ; if(r) b[0] += 0x80000000 ; - } -}; - -// Compute quotient and modulo of n by p where both n and p are 256bits integers. -// -static void quotient(const uint256_32& n,const uint256_32& p,uint256_32& q,uint256_32& r) -{ - // simple algorithm: add up multiples of u while keeping below *this. Once done, substract. - - r = n ; - q = uint256_32(0,0,0,0,0,0,0,0) ; - - int bmax = n.max_non_zero_bit() - p.max_non_zero_bit(); - - uint256_32 m(0,0,0,0,0,0,0,0) ; - uint256_32 d = p ; - - m.b[bmax/32] = (1u << (bmax%32)) ; // set m to be 2^bmax - - d.lshift(bmax); - - for(int b=bmax;b>=0;--b,d.rshift(),m.rshift()) - if(! (r < d)) - { - r -= d ; - q += m ; - } -} - -static void remainder(const uint256_32& n,const uint256_32& p,uint256_32& r) -{ - // simple algorithm: add up multiples of u while keeping below *this. Once done, substract. - - r = n ; - int bmax = n.max_non_zero_bit() - p.max_non_zero_bit(); - - uint256_32 d = p ; - d.lshift(bmax); - - for(int b=bmax;b>=0;--b,d.rshift()) - if(! (r < d)) - r -= d ; -} - -class chacha20_state -{ -public: - uint32_t c[16] ; - - chacha20_state(uint8_t key[32],uint32_t block_counter,uint8_t nounce[12]) - { - c[0] = 0x61707865 ; - c[1] = 0x3320646e ; - c[2] = 0x79622d32 ; - c[3] = 0x6b206574 ; - - c[ 4] = (uint32_t)key[0 ] + (((uint32_t)key[1 ])<<8) + (((uint32_t)key[2 ])<<16) + (((uint32_t)key[3 ])<<24); - c[ 5] = (uint32_t)key[4 ] + (((uint32_t)key[5 ])<<8) + (((uint32_t)key[6 ])<<16) + (((uint32_t)key[7 ])<<24); - c[ 6] = (uint32_t)key[8 ] + (((uint32_t)key[9 ])<<8) + (((uint32_t)key[10])<<16) + (((uint32_t)key[11])<<24); - c[ 7] = (uint32_t)key[12] + (((uint32_t)key[13])<<8) + (((uint32_t)key[14])<<16) + (((uint32_t)key[15])<<24); - c[ 8] = (uint32_t)key[16] + (((uint32_t)key[17])<<8) + (((uint32_t)key[18])<<16) + (((uint32_t)key[19])<<24); - c[ 9] = (uint32_t)key[20] + (((uint32_t)key[21])<<8) + (((uint32_t)key[22])<<16) + (((uint32_t)key[23])<<24); - c[10] = (uint32_t)key[24] + (((uint32_t)key[25])<<8) + (((uint32_t)key[26])<<16) + (((uint32_t)key[27])<<24); - c[11] = (uint32_t)key[28] + (((uint32_t)key[29])<<8) + (((uint32_t)key[30])<<16) + (((uint32_t)key[31])<<24); - - c[12] = block_counter ; - - c[13] = (uint32_t)nounce[0 ] + (((uint32_t)nounce[1 ])<<8) + (((uint32_t)nounce[2 ])<<16) + (((uint32_t)nounce[3 ])<<24); - c[14] = (uint32_t)nounce[4 ] + (((uint32_t)nounce[5 ])<<8) + (((uint32_t)nounce[6 ])<<16) + (((uint32_t)nounce[7 ])<<24); - c[15] = (uint32_t)nounce[8 ] + (((uint32_t)nounce[9 ])<<8) + (((uint32_t)nounce[10])<<16) + (((uint32_t)nounce[11])<<24); - } -}; - -static void quarter_round(uint32_t& a,uint32_t& b,uint32_t& c,uint32_t& d) -{ - a += b ; d ^= a; rotl(d,16) ; //d <<<=16 ; - c += d ; b ^= c; rotl(b,12) ; //b <<<=12 ; - a += b ; d ^= a; rotl(d,8) ; //d <<<=8 ; - c += d ; b ^= c; rotl(b,7) ; //b <<<=7 ; -} - -static void add(chacha20_state& s,const chacha20_state& t) { for(uint32_t i=0;i<16;++i) s.c[i] += t.c[i] ; } - -static void apply_20_rounds(chacha20_state& s) -{ - chacha20_state t(s) ; - - for(uint32_t i=0;i<10;++i) - { - quarter_round(s.c[ 0],s.c[ 4],s.c[ 8],s.c[12]) ; - quarter_round(s.c[ 1],s.c[ 5],s.c[ 9],s.c[13]) ; - quarter_round(s.c[ 2],s.c[ 6],s.c[10],s.c[14]) ; - quarter_round(s.c[ 3],s.c[ 7],s.c[11],s.c[15]) ; - quarter_round(s.c[ 0],s.c[ 5],s.c[10],s.c[15]) ; - quarter_round(s.c[ 1],s.c[ 6],s.c[11],s.c[12]) ; - quarter_round(s.c[ 2],s.c[ 7],s.c[ 8],s.c[13]) ; - quarter_round(s.c[ 3],s.c[ 4],s.c[ 9],s.c[14]) ; - } - - add(s,t) ; -} - -#ifdef DEBUG_CHACHA20 -static void print(const chacha20_state& s) -{ - fprintf(stdout,"%08x %08x %08x %08x\n",s.c[0 ],s.c[1 ],s.c[2 ],s.c[3 ]) ; - fprintf(stdout,"%08x %08x %08x %08x\n",s.c[4 ],s.c[5 ],s.c[6 ],s.c[7 ]) ; - fprintf(stdout,"%08x %08x %08x %08x\n",s.c[8 ],s.c[9 ],s.c[10],s.c[11]) ; - fprintf(stdout,"%08x %08x %08x %08x\n",s.c[12],s.c[13],s.c[14],s.c[15]) ; -} -#endif - -void chacha20_encrypt_rs(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size) -{ - for(uint32_t i=0;i> (8*(k%4))) & 0xff) ; - } -} - -#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) -void chacha20_encrypt_openssl(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size) -{ - EVP_CIPHER_CTX *ctx; - - int len; - int tmp_len; - uint8_t tmp[size]; - uint8_t iv[16]; - - // create iv with nonce and block counter - memcpy(iv, &block_counter, 4); - memcpy(iv + 4, nonce, 12); - - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) return; - - /* Initialise the encryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits */ - if(1 != EVP_EncryptInit_ex(ctx, EVP_chacha20(), NULL, key, iv)) goto out; - - /* Provide the message to be encrypted, and obtain the encrypted output. - * EVP_EncryptUpdate can be called multiple times if necessary - */ - if(1 != EVP_EncryptUpdate(ctx, tmp, &len, data, size)) goto out; - tmp_len = len; - - /* Finalise the encryption. Further ciphertext bytes may be written at - * this stage. - */ - if(1 != EVP_EncryptFinal_ex(ctx, tmp + len, &len)) goto out; - tmp_len += len; - - memcpy(data, tmp, tmp_len); - -out: - /* Clean up */ - EVP_CIPHER_CTX_free(ctx); -} -#endif - -struct poly1305_state -{ - uint256_32 r ; - uint256_32 s ; - uint256_32 p ; - uint256_32 a ; -}; - -static void poly1305_init(poly1305_state& s,uint8_t key[32]) -{ - s.r = uint256_32( 0,0,0,0, - ((uint32_t)key[12] << 0) + ((uint32_t)key[13] << 8) + ((uint32_t)key[14] << 16) + ((uint32_t)key[15] << 24), - ((uint32_t)key[ 8] << 0) + ((uint32_t)key[ 9] << 8) + ((uint32_t)key[10] << 16) + ((uint32_t)key[11] << 24), - ((uint32_t)key[ 4] << 0) + ((uint32_t)key[ 5] << 8) + ((uint32_t)key[ 6] << 16) + ((uint32_t)key[ 7] << 24), - ((uint32_t)key[ 0] << 0) + ((uint32_t)key[ 1] << 8) + ((uint32_t)key[ 2] << 16) + ((uint32_t)key[ 3] << 24) - ); - - s.r.poly1305clamp(); - - s.s = uint256_32( 0,0,0,0, - ((uint32_t)key[28] << 0) + ((uint32_t)key[29] << 8) + ((uint32_t)key[30] << 16) + ((uint32_t)key[31] << 24), - ((uint32_t)key[24] << 0) + ((uint32_t)key[25] << 8) + ((uint32_t)key[26] << 16) + ((uint32_t)key[27] << 24), - ((uint32_t)key[20] << 0) + ((uint32_t)key[21] << 8) + ((uint32_t)key[22] << 16) + ((uint32_t)key[23] << 24), - ((uint32_t)key[16] << 0) + ((uint32_t)key[17] << 8) + ((uint32_t)key[18] << 16) + ((uint32_t)key[19] << 24) - ); - - s.p = uint256_32(0,0,0,0x3,0xffffffff,0xffffffff,0xffffffff,0xfffffffb) ; - s.a = uint256_32(0,0,0, 0, 0, 0, 0, 0) ; -} - -// Warning: each call will automatically *pad* the data to a multiple of 16 bytes. -// -static void poly1305_add(poly1305_state& s,uint8_t *message,uint32_t size,bool pad_to_16_bytes=false) -{ -#ifdef DEBUG_CHACHA20 - std::cerr << "Poly1305: digesting " << RsUtil::BinToHex(message,size) << std::endl; -#endif - - for(uint32_t i=0;i<(size+15)/16;++i) - { - uint256_32 block ; - uint32_t j; - - for(j=0;j<16 && i*16+j < size;++j) - block.b[j/4] += ((uint64_t)message[i*16+j]) << (8*(j & 0x3)) ; - - if(pad_to_16_bytes) - block.b[4] += 0x01 ; - else - block.b[j/4] += 0x01 << (8*(j& 0x3)); - - s.a += block ; - s.a *= s.r ; - - uint256_32 q,rst; - remainder(s.a,s.p,rst) ; - s.a = rst ; - } -} - -static void poly1305_finish(poly1305_state& s,uint8_t tag[16]) -{ - s.a += s.s ; - - tag[ 0] = (s.a.b[0] >> 0) & 0xff ; tag[ 1] = (s.a.b[0] >> 8) & 0xff ; tag[ 2] = (s.a.b[0] >>16) & 0xff ; tag[ 3] = (s.a.b[0] >>24) & 0xff ; - tag[ 4] = (s.a.b[1] >> 0) & 0xff ; tag[ 5] = (s.a.b[1] >> 8) & 0xff ; tag[ 6] = (s.a.b[1] >>16) & 0xff ; tag[ 7] = (s.a.b[1] >>24) & 0xff ; - tag[ 8] = (s.a.b[2] >> 0) & 0xff ; tag[ 9] = (s.a.b[2] >> 8) & 0xff ; tag[10] = (s.a.b[2] >>16) & 0xff ; tag[11] = (s.a.b[2] >>24) & 0xff ; - tag[12] = (s.a.b[3] >> 0) & 0xff ; tag[13] = (s.a.b[3] >> 8) & 0xff ; tag[14] = (s.a.b[3] >>16) & 0xff ; tag[15] = (s.a.b[3] >>24) & 0xff ; -} - -void poly1305_tag(uint8_t key[32],uint8_t *message,uint32_t size,uint8_t tag[16]) -{ - poly1305_state s; - - poly1305_init (s,key); - poly1305_add(s,message,size) ; - poly1305_finish(s,tag); -} - -static void poly1305_key_gen(uint8_t key[32], uint8_t nonce[12], uint8_t generated_key[32]) -{ - uint32_t counter = 0 ; - - chacha20_state s(key,counter,nonce); - apply_20_rounds(s) ; - - for(uint32_t k=0;k<8;++k) - for(uint32_t i=0;i<4;++i) - generated_key[k*4 + i] = (s.c[k] >> 8*i) & 0xff ; -} - -bool constant_time_memory_compare(const uint8_t *m1,const uint8_t *m2,uint32_t size) -{ - return !CRYPTO_memcmp(m1,m2,size) ; -} - -bool AEAD_chacha20_poly1305_rs(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt) -{ - // encrypt + tag. See RFC7539-2.8 - - uint8_t session_key[32]; - poly1305_key_gen(key,nonce,session_key); - - uint8_t lengths_vector[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } ; - - for(uint32_t i=0;i<4;++i) - { - lengths_vector[0+i] = ( aad_size >> (8*i)) & 0xff ; - lengths_vector[8+i] = (data_size >> (8*i)) & 0xff ; - } - - if(encrypt) - { - chacha20_encrypt_rs(key,1,nonce,data,data_size); - - poly1305_state pls ; - - poly1305_init(pls,session_key); - - poly1305_add(pls,aad,aad_size,true); // add and pad the aad - poly1305_add(pls,data,data_size,true); // add and pad the cipher text - poly1305_add(pls,lengths_vector,16,true); // add the lengths - - poly1305_finish(pls,tag); - return true ; - } - else - { - poly1305_state pls ; - uint8_t computed_tag[16]; - - poly1305_init(pls,session_key); - - poly1305_add(pls,aad,aad_size,true); // add and pad the aad - poly1305_add(pls,data,data_size,true); // add and pad the cipher text - poly1305_add(pls,lengths_vector,16,true); // add the lengths - - poly1305_finish(pls,computed_tag); - - // decrypt - - chacha20_encrypt_rs(key,1,nonce,data,data_size); - - return constant_time_memory_compare(tag,computed_tag,16) ; - } -} - -#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) -#define errorOut {ret = false; goto out;} - -bool AEAD_chacha20_poly1305_openssl(uint8_t key[32], uint8_t nonce[12], uint8_t *data, uint32_t data_size, uint8_t *aad, uint32_t aad_size, uint8_t tag[16], bool encrypt_or_decrypt) -{ - EVP_CIPHER_CTX *ctx; - - bool ret = true; - int len; - const uint8_t tag_len = 16; - int tmp_len; - uint8_t tmp[data_size]; - - /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) return false; - - if (encrypt_or_decrypt) { - /* Initialise the encryption operation. */ - if(1 != EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL)) errorOut - - /* Initialise key and IV */ - if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, nonce)) errorOut - - /* Provide any AAD data. This can be called zero or more times as - * required - */ - if(1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_size)) errorOut - - /* Provide the message to be encrypted, and obtain the encrypted output. - * EVP_EncryptUpdate can be called multiple times if necessary - */ - if(1 != EVP_EncryptUpdate(ctx, tmp, &len, data, data_size)) errorOut - tmp_len = len; - - /* Finalise the encryption. Normally ciphertext bytes may be written at - * this stage, but this does not occur in GCM mode - */ - if(1 != EVP_EncryptFinal_ex(ctx, data + len, &len)) errorOut - tmp_len += len; - - /* Get the tag */ - if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, tag)) errorOut - } else { - /* Initialise the decryption operation. */ - if(!EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce)) errorOut - - /* Provide any AAD data. This can be called zero or more times as - * required - */ - if(!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_size)) errorOut - - /* Provide the message to be decrypted, and obtain the plaintext output. - * EVP_DecryptUpdate can be called multiple times if necessary - */ - if(!EVP_DecryptUpdate(ctx, tmp, &len, data, data_size)) errorOut - tmp_len = len; - - /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ - if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag)) errorOut - - /* Finalise the decryption. A positive return value indicates success, - * anything else is a failure - the plaintext is not trustworthy. - */ - if(EVP_DecryptFinal_ex(ctx, tmp + len, &len) > 0) { - /* Success */ - tmp_len += len; - ret = true; - } else { - /* Verify failed */ - errorOut - } - } - - memcpy(data, tmp, tmp_len); - -out: - /* Clean up */ - EVP_CIPHER_CTX_free(ctx); - return !!ret; -} - -#undef errorOut -#endif - -bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt) -{ - // encrypt + tag. See RFC7539-2.8 - - if(encrypt) - { -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - chacha20_encrypt_rs(key,1,nonce,data,data_size); -#else - chacha20_encrypt_openssl(key, 1, nonce, data, data_size); -#endif - - uint8_t computed_tag[EVP_MAX_MD_SIZE]; - unsigned int md_size ; - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - HMAC_CTX hmac_ctx ; - HMAC_CTX_init(&hmac_ctx) ; - - HMAC_Init(&hmac_ctx,key,32,EVP_sha256()) ; - HMAC_Update(&hmac_ctx,aad,aad_size) ; - HMAC_Update(&hmac_ctx,data,data_size) ; - HMAC_Final(&hmac_ctx,computed_tag,&md_size) ; - - HMAC_CTX_cleanup(&hmac_ctx) ; -#else - HMAC_CTX *hmac_ctx = HMAC_CTX_new(); - - HMAC_Init_ex(hmac_ctx,key,32,EVP_sha256(),NULL) ; - HMAC_Update(hmac_ctx,aad,aad_size) ; - HMAC_Update(hmac_ctx,data,data_size) ; - HMAC_Final(hmac_ctx,computed_tag,&md_size) ; - - HMAC_CTX_free(hmac_ctx) ; - hmac_ctx=NULL; -#endif - - assert(md_size >= 16); - - memcpy(tag,computed_tag,16) ; - - return true ; - } - else - { - uint8_t computed_tag[EVP_MAX_MD_SIZE]; - unsigned int md_size ; - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - HMAC_CTX hmac_ctx ; - HMAC_CTX_init(&hmac_ctx) ; - - HMAC_Init(&hmac_ctx,key,32,EVP_sha256()) ; - HMAC_Update(&hmac_ctx,aad,aad_size) ; - HMAC_Update(&hmac_ctx,data,data_size) ; - HMAC_Final(&hmac_ctx,computed_tag,&md_size) ; - - HMAC_CTX_cleanup(&hmac_ctx) ; -#else - HMAC_CTX *hmac_ctx = HMAC_CTX_new(); - - HMAC_Init_ex(hmac_ctx,key,32,EVP_sha256(),NULL) ; - HMAC_Update(hmac_ctx,aad,aad_size) ; - HMAC_Update(hmac_ctx,data,data_size) ; - HMAC_Final(hmac_ctx,computed_tag,&md_size) ; - - HMAC_CTX_free(hmac_ctx) ; - hmac_ctx=NULL; -#endif - - // decrypt - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - chacha20_encrypt_rs(key,1,nonce,data,data_size); -#else - chacha20_encrypt_openssl(key, 1, nonce, data, data_size); -#endif - - return constant_time_memory_compare(tag,computed_tag,16) ; - } -} - - -bool perform_tests() -{ - // RFC7539 - 2.1.1 - - std::cerr << " quarter round " ; - - uint32_t a = 0x11111111 ; - uint32_t b = 0x01020304 ; - uint32_t c = 0x9b8d6f43 ; - uint32_t d = 0x01234567 ; - - quarter_round(a,b,c,d) ; - - if(!(a == 0xea2a92f4)) return false ; - if(!(b == 0xcb1cf8ce)) return false ; - if(!(c == 0x4581472e)) return false ; - if(!(d == 0x5881c4bb)) return false ; - - std::cerr << " OK" << std::endl; - - // RFC7539 - 2.3.2 - - std::cerr << " RFC7539 - 2.3.2 " ; - - uint8_t key[32] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b, \ - 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, \ - 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f } ; - uint8_t nounce[12] = { 0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00 } ; - - chacha20_state s(key,1,nounce) ; - -#ifdef DEBUG_CHACHA20 - print(s) ; -#endif - - apply_20_rounds(s) ; - -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"\n") ; - - print(s) ; -#endif - - uint32_t check_vals[16] = { - 0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3, - 0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3, - 0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9, - 0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 - }; - - for(uint32_t i=0;i<16;++i) - if(s.c[i] != check_vals[i]) - return false ; - - std::cerr << " OK" << std::endl; - - // RFC7539 - 2.4.2 - - std::cerr << " RFC7539 - 2.4.2 " ; - - uint8_t nounce2[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00 } ; - - uint8_t plaintext[7*16+2] = { - 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, - 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, - 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, - 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, - 0x74, 0x2e - }; - - chacha20_encrypt_rs(key,1,nounce2,plaintext,7*16+2) ; - -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"CipherText: \n") ; - - for(uint32_t k=0;k<7*16+2;++k) - { - fprintf(stdout,"%02x ",plaintext[k]) ; - - if( (k % 16) == 15) - fprintf(stdout,"\n") ; - } - fprintf(stdout,"\n") ; -#endif - - uint8_t check_cipher_text[7*16+2] = { - 0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81, - 0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b, - 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab, 0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57, - 0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab, 0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8, - 0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d, 0x6a, 0x61, 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e, - 0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06, 0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36, - 0x5a, 0xf9, 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6, 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42, - 0x87, 0x4d - }; - - for(uint32_t i=0;i<7*16+2;++i) - if(!(check_cipher_text[i] == plaintext[i] )) - return false; - - std::cerr << " OK" << std::endl; - - // operators - - { uint256_32 uu(0,0,0,0,0,0,0,0 ) ; ++uu ; if(!(uu == uint256_32(0,0,0,0,0,0,0,1))) return false ; } - { uint256_32 uu(0,0,0,0,0,0,0,0xffffffff) ; ++uu ; if(!(uu == uint256_32(0,0,0,0,0,0,1,0))) return false ; } - { uint256_32 uu(0,0,0,0,0,0,0,0) ; uu = ~uu;++uu ; if(!(uu == uint256_32(0,0,0,0,0,0,0,0))) return false ; } - - std::cerr << " operator++ on 256bits numbers OK" << std::endl; - - // sums/diffs of numbers - - for(uint32_t i=0;i<100;++i) - { - uint256_32 a = uint256_32::random() ; - uint256_32 b = uint256_32::random() ; -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"Adding ") ; - uint256_32::print(a) ; - fprintf(stdout,"\n to ") ; - uint256_32::print(b) ; -#endif - - uint256_32 c(a) ; - if(!(c == a) ) - return false; - - c += b ; - -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"\n found ") ; - uint256_32::print(c) ; -#endif - - c -= b ; - -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"\n subst ") ; - uint256_32::print(c) ; - fprintf(stdout,"\n") ; -#endif - - if(!(a == a)) return false ; - if(!(c == a)) return false ; - - uint256_32 vv(0,0,0,0,0,0,0,1) ; - vv -= a ; - vv += a ; - - if(!(vv == uint256_32(0,0,0,0,0,0,0,1))) return false ; - - } - uint256_32 vv(0,0,0,0,0,0,0,0) ; - uint256_32 ww(0,0,0,0,0,0,0,1) ; - vv -= ww ; - if(!(vv == ~uint256_32(0,0,0,0,0,0,0,0))) return false; - - std::cerr << " Sums / diffs of 256bits numbers OK" << std::endl; - - // check that (a-b)*(c-d) = ac - bc - ad + bd - - for(uint32_t i=0;i<100;++i) - { - uint256_32 a = uint256_32::random(); - uint256_32 b = uint256_32::random(); - uint256_32 c = uint256_32::random(); - uint256_32 d = uint256_32::random(); - - uint256_32 amb(a) ; - amb -= b; - uint256_32 cmd(c) ; - cmd -= d; - uint256_32 ambtcmd(amb); - ambtcmd *= cmd ; - - uint256_32 atc(a) ; atc *= c ; - uint256_32 btc(b) ; btc *= c ; - uint256_32 atd(a) ; atd *= d ; - uint256_32 btd(b) ; btd *= d ; - - uint256_32 atcmbtcmatdpbtd(atc) ; - atcmbtcmatdpbtd -= btc ; - atcmbtcmatdpbtd -= atd ; - atcmbtcmatdpbtd += btd ; - - if(!(atcmbtcmatdpbtd == ambtcmd)) return false ; - } - std::cerr << " (a-b)*(c-d) == ac-bc-ad+bd on random OK" << std::endl; - - // shifts - - for(uint32_t i=0;i<100;++i) - { - uint256_32 x = uint256_32::random(); - uint256_32 y(x) ; - - uint32_t r = x.b[0] & 0x1 ; - x.rshift() ; - x.lshift() ; - - x.b[0] += r ; - - if(!(x == y) ) return false ; - } - std::cerr << " left/right shifting OK" << std::endl; - - // test modulo by computing modulo and recomputing the product. - - for(uint32_t i=0;i<100;++i) - { - uint256_32 q1(0,0,0,0,0,0,0,0),r1(0,0,0,0,0,0,0,0) ; - - uint256_32 n1 = uint256_32::random(); - uint256_32 p1 = uint256_32::random(); - - if(RSRandom::random_f32() < 0.2) - { - p1.b[7] = 0 ; - - if(RSRandom::random_f32() < 0.1) - p1.b[6] = 0 ; - } - - quotient(n1,p1,q1,r1) ; -#ifdef DEBUG_CHACHA20 - fprintf(stdout,"result: q=") ; uint256_32::print(q1) ; fprintf(stdout," r=") ; uint256_32::print(r1) ; fprintf(stdout,"\n") ; -#endif - - //uint256_32 res(q1) ; - q1 *= p1 ; - q1 += r1 ; - - if(!(q1 == n1)) return false ; - } - std::cerr << " Quotient/modulo on random numbers OK" << std::endl; - - // RFC7539 - 2.5 - // - { - uint8_t key[32] = { 0x85,0xd6,0xbe,0x78,0x57,0x55,0x6d,0x33,0x7f,0x44,0x52,0xfe,0x42,0xd5,0x06,0xa8,0x01,0x03,0x80,0x8a,0xfb,0x0d,0xb2,0xfd,0x4a,0xbf,0xf6,0xaf,0x41,0x49,0xf5,0x1b } ; - uint8_t tag[16] ; - std::string msg("Cryptographic Forum Research Group") ; - - poly1305_tag(key,(uint8_t*)msg.c_str(),msg.length(),tag) ; - - uint8_t test_tag[16] = { 0xa8,0x06,0x1d,0xc1,0x30,0x51,0x36,0xc6,0xc2,0x2b,0x8b,0xaf,0x0c,0x01,0x27,0xa9 }; - - if(!(constant_time_memory_compare(tag,test_tag,16))) return false ; - } - std::cerr << " RFC7539 - 2.5 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #1 - // - { - uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - uint8_t tag[16] ; - uint8_t text[64] ; - memset(text,0,64) ; - - poly1305_tag(key,text,64,tag) ; - - uint8_t test_tag[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #001 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #2 - // - { - uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x36,0xe5,0xf6,0xb5,0xc5,0xe0,0x60,0x70,0xf0,0xef,0xca,0x96,0x22,0x7a,0x86,0x3e } ; - uint8_t tag[16] ; - - std::string msg("Any submission to the IETF intended by the Contributor for publication as all or part of an IETF Internet-Draft or RFC and any statement made within the context of an IETF activity is considered an \"IETF Contribution\". Such statements include oral statements in IETF sessions, as well as written and electronic communications made at any time or place, which are addressed to") ; - - poly1305_tag(key,(uint8_t*)msg.c_str(),msg.length(),tag) ; - - uint8_t test_tag[16] = { 0x36,0xe5,0xf6,0xb5,0xc5,0xe0,0x60,0x70,0xf0,0xef,0xca,0x96,0x22,0x7a,0x86,0x3e }; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #002 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #3 - // - { - uint8_t key[32] = { 0x36,0xe5,0xf6,0xb5,0xc5,0xe0,0x60,0x70,0xf0,0xef,0xca,0x96,0x22,0x7a,0x86,0x3e, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - uint8_t tag[16] ; - - std::string msg("Any submission to the IETF intended by the Contributor for publication as all or part of an IETF Internet-Draft or RFC and any statement made within the context of an IETF activity is considered an \"IETF Contribution\". Such statements include oral statements in IETF sessions, as well as written and electronic communications made at any time or place, which are addressed to") ; - - poly1305_tag(key,(uint8_t*)msg.c_str(),msg.length(),tag) ; - - uint8_t test_tag[16] = { 0xf3,0x47,0x7e,0x7c,0xd9,0x54,0x17,0xaf,0x89,0xa6,0xb8,0x79,0x4c,0x31,0x0c,0xf0 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #003 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #4 - // - { - uint8_t key[32] = { 0x1c ,0x92 ,0x40 ,0xa5 ,0xeb ,0x55 ,0xd3 ,0x8a ,0xf3 ,0x33 ,0x88 ,0x86 ,0x04 ,0xf6 ,0xb5 ,0xf0, - 0x47 ,0x39 ,0x17 ,0xc1 ,0x40 ,0x2b ,0x80 ,0x09 ,0x9d ,0xca ,0x5c ,0xbc ,0x20 ,0x70 ,0x75 ,0xc0 }; - uint8_t tag[16] ; - - std::string msg("'Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.") ; - - poly1305_tag(key,(uint8_t*)msg.c_str(),msg.length(),tag) ; - - uint8_t test_tag[16] = { 0x45,0x41,0x66,0x9a,0x7e,0xaa,0xee,0x61,0xe7,0x08,0xdc,0x7c,0xbc,0xc5,0xeb,0x62 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #004 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #5 - // - { - uint8_t key[32] = { 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; - - poly1305_tag(key,msg,16,tag) ; - - uint8_t test_tag[16] = { 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #005 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #6 - // - { - uint8_t key[32] = { 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; - uint8_t tag[16] ; - - uint8_t msg[16] = { 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - - poly1305_tag(key,msg,16,tag) ; - - uint8_t test_tag[16] = { 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #006 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #7 - // - { - uint8_t key[32] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[48] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - poly1305_tag(key,msg,48,tag) ; - - uint8_t test_tag[16] = { 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #007 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #8 - // - { - uint8_t key[32] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[48] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xfb,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe, - 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } ; - - poly1305_tag(key,msg,48,tag) ; - - uint8_t test_tag[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #008 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #9 - // - { - uint8_t key[32] = { 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[16] = { 0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } ; - - poly1305_tag(key,msg,16,tag) ; - - uint8_t test_tag[16] = { 0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #009 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #10 - // - { - uint8_t key[32] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[64] = { - 0xE3 ,0x35 ,0x94 ,0xD7 ,0x50 ,0x5E ,0x43 ,0xB9 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, - 0x33 ,0x94 ,0xD7 ,0x50 ,0x5E ,0x43 ,0x79 ,0xCD ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, - 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, - 0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 }; - - poly1305_tag(key,msg,64,tag) ; - - uint8_t test_tag[16] = { 0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!(constant_time_memory_compare(tag,test_tag,16)) ) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #010 OK" << std::endl; - - // RFC7539 - Poly1305 test vector #11 - // - { - uint8_t key[32] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t tag[16] ; - - uint8_t msg[48] = { - 0xE3 ,0x35 ,0x94 ,0xD7 ,0x50 ,0x5E ,0x43 ,0xB9 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, - 0x33 ,0x94 ,0xD7 ,0x50 ,0x5E ,0x43 ,0x79 ,0xCD ,0x01 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, - 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 } ; - - poly1305_tag(key,msg,48,tag) ; - - uint8_t test_tag[16] = { 0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 } ; - - if(!constant_time_memory_compare(tag,test_tag,16)) return false ; - } - std::cerr << " RFC7539 poly1305 test vector #011 OK" << std::endl; - - // RFC7539 - 2.6.2 - // - { - uint8_t key[32] = { 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f }; - - uint8_t session_key[32] ; - uint8_t test_session_key[32] = { 0x8a,0xd5,0xa0,0x8b,0x90,0x5f,0x81,0xcc,0x81,0x50,0x40,0x27,0x4a,0xb2,0x94,0x71, - 0xa8,0x33,0xb6,0x37,0xe3,0xfd,0x0d,0xa5,0x08,0xdb,0xb8,0xe2,0xfd,0xd1,0xa6,0x46 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }; - - poly1305_key_gen(key,nonce,session_key) ; - - if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ; - } - std::cerr << " RFC7539 - 2.6.2 OK" << std::endl; - - // RFC7539 - Poly1305 key generation. Test vector #1 - // - { - uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t session_key[32] ; - uint8_t test_session_key[32] = { 0x76,0xb8,0xe0,0xad,0xa0,0xf1,0x3d,0x90,0x40,0x5d,0x6a,0xe5,0x53,0x86,0xbd,0x28, - 0xbd,0xd2,0x19,0xb8,0xa0,0x8d,0xed,0x1a,0xa8,0x36,0xef,0xcc,0x8b,0x77,0x0d,0xc7 }; - - poly1305_key_gen(key,nonce,session_key) ; - - if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ; - } - std::cerr << " RFC7539 poly1305 key gen. TVec #1 OK" << std::endl; - - // RFC7539 - Poly1305 key generation. Test vector #2 - // - { - uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 }; - uint8_t session_key[32] ; - uint8_t test_session_key[32] = { 0xec,0xfa,0x25,0x4f,0x84,0x5f,0x64,0x74,0x73,0xd3,0xcb,0x14,0x0d,0xa9,0xe8,0x76, - 0x06,0xcb,0x33,0x06,0x6c,0x44,0x7b,0x87,0xbc,0x26,0x66,0xdd,0xe3,0xfb,0xb7,0x39 }; - - - - poly1305_key_gen(key,nonce,session_key) ; - - if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ; - } - std::cerr << " RFC7539 poly1305 key gen. TVec #2 OK" << std::endl; - - // RFC7539 - Poly1305 key generation. Test vector #3 - // - { - uint8_t key[32] = { 0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0, - 0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 }; - uint8_t session_key[32] ; - uint8_t test_session_key[32] = { 0x96,0x5e,0x3b,0xc6,0xf9,0xec,0x7e,0xd9,0x56,0x08,0x08,0xf4,0xd2,0x29,0xf9,0x4b, - 0x13,0x7f,0xf2,0x75,0xca,0x9b,0x3f,0xcb,0xdd,0x59,0xde,0xaa,0xd2,0x33,0x10,0xae }; - - poly1305_key_gen(key,nonce,session_key) ; - - if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ; - } - std::cerr << " RFC7539 poly1305 key gen. TVec #3 OK" << std::endl; - - // RFC7539 - 2.8.2 - // - { - uint8_t msg[7*16+2] = { - 0x4c,0x61,0x64,0x69,0x65,0x73,0x20,0x61,0x6e,0x64,0x20,0x47,0x65,0x6e,0x74,0x6c, - 0x65,0x6d,0x65,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x63,0x6c,0x61,0x73, - 0x73,0x20,0x6f,0x66,0x20,0x27,0x39,0x39,0x3a,0x20,0x49,0x66,0x20,0x49,0x20,0x63, - 0x6f,0x75,0x6c,0x64,0x20,0x6f,0x66,0x66,0x65,0x72,0x20,0x79,0x6f,0x75,0x20,0x6f, - 0x6e,0x6c,0x79,0x20,0x6f,0x6e,0x65,0x20,0x74,0x69,0x70,0x20,0x66,0x6f,0x72,0x20, - 0x74,0x68,0x65,0x20,0x66,0x75,0x74,0x75,0x72,0x65,0x2c,0x20,0x73,0x75,0x6e,0x73, - 0x63,0x72,0x65,0x65,0x6e,0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x62,0x65,0x20,0x69, - 0x74,0x2e } ; - - uint8_t test_msg[7*16+2] = { - 0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2, - 0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6, - 0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b, - 0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36, - 0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58, - 0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc, - 0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b, - 0x61,0x16 }; - - uint8_t aad[12] = { 0x50,0x51,0x52,0x53,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7 }; - uint8_t nonce[12] = { 0x07,0x00,0x00,0x00,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 }; - - uint8_t key[32] = { 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f }; - uint8_t tag[16] ; - uint8_t test_tag[16] = { 0x1a,0xe1,0x0b,0x59,0x4f,0x09,0xe2,0x6a,0x7e,0x90,0x2e,0xcb,0xd0,0x60,0x06,0x91 }; - - AEAD_chacha20_poly1305_rs(key,nonce,msg,7*16+2,aad,12,tag,true) ; - - if(!constant_time_memory_compare(msg,test_msg,7*16+2)) return false ; - if(!constant_time_memory_compare(tag,test_tag,16)) return false ; - - bool res = AEAD_chacha20_poly1305_rs(key,nonce,msg,7*16+2,aad,12,tag,false) ; - - if(!res) return false ; - } - std::cerr << " RFC7539 - 2.8.2 OK" << std::endl; - - - // RFC7539 - AEAD checking and decryption - // - { - uint8_t key[32] = { 0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0, - 0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 }; - - uint8_t ciphertext[16*16 + 9] = { - 0x64,0xa0,0x86,0x15,0x75,0x86,0x1a,0xf4,0x60,0xf0,0x62,0xc7,0x9b,0xe6,0x43,0xbd, - 0x5e,0x80,0x5c,0xfd,0x34,0x5c,0xf3,0x89,0xf1,0x08,0x67,0x0a,0xc7,0x6c,0x8c,0xb2, - 0x4c,0x6c,0xfc,0x18,0x75,0x5d,0x43,0xee,0xa0,0x9e,0xe9,0x4e,0x38,0x2d,0x26,0xb0, - 0xbd,0xb7,0xb7,0x3c,0x32,0x1b,0x01,0x00,0xd4,0xf0,0x3b,0x7f,0x35,0x58,0x94,0xcf, - 0x33,0x2f,0x83,0x0e,0x71,0x0b,0x97,0xce,0x98,0xc8,0xa8,0x4a,0xbd,0x0b,0x94,0x81, - 0x14,0xad,0x17,0x6e,0x00,0x8d,0x33,0xbd,0x60,0xf9,0x82,0xb1,0xff,0x37,0xc8,0x55, - 0x97,0x97,0xa0,0x6e,0xf4,0xf0,0xef,0x61,0xc1,0x86,0x32,0x4e,0x2b,0x35,0x06,0x38, - 0x36,0x06,0x90,0x7b,0x6a,0x7c,0x02,0xb0,0xf9,0xf6,0x15,0x7b,0x53,0xc8,0x67,0xe4, - 0xb9,0x16,0x6c,0x76,0x7b,0x80,0x4d,0x46,0xa5,0x9b,0x52,0x16,0xcd,0xe7,0xa4,0xe9, - 0x90,0x40,0xc5,0xa4,0x04,0x33,0x22,0x5e,0xe2,0x82,0xa1,0xb0,0xa0,0x6c,0x52,0x3e, - 0xaf,0x45,0x34,0xd7,0xf8,0x3f,0xa1,0x15,0x5b,0x00,0x47,0x71,0x8c,0xbc,0x54,0x6a, - 0x0d,0x07,0x2b,0x04,0xb3,0x56,0x4e,0xea,0x1b,0x42,0x22,0x73,0xf5,0x48,0x27,0x1a, - 0x0b,0xb2,0x31,0x60,0x53,0xfa,0x76,0x99,0x19,0x55,0xeb,0xd6,0x31,0x59,0x43,0x4e, - 0xce,0xbb,0x4e,0x46,0x6d,0xae,0x5a,0x10,0x73,0xa6,0x72,0x76,0x27,0x09,0x7a,0x10, - 0x49,0xe6,0x17,0xd9,0x1d,0x36,0x10,0x94,0xfa,0x68,0xf0,0xff,0x77,0x98,0x71,0x30, - 0x30,0x5b,0xea,0xba,0x2e,0xda,0x04,0xdf,0x99,0x7b,0x71,0x4d,0x6c,0x6f,0x2c,0x29, - 0xa6,0xad,0x5c,0xb4,0x02,0x2b,0x02,0x70,0x9b }; - - uint8_t aad[12] = { 0xf3,0x33,0x88,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x91 }; - - uint8_t received_tag[16] = { 0xee,0xad,0x9d,0x67,0x89,0x0c,0xbb,0x22,0x39,0x23,0x36,0xfe,0xa1,0x85,0x1f,0x38 }; - - if(!AEAD_chacha20_poly1305_rs(key,nonce,ciphertext,16*16+9,aad,12,received_tag,false)) - return false ; - - uint8_t cleartext[16*16+9] = { - 0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x2d,0x44,0x72,0x61,0x66,0x74,0x73,0x20, - 0x61,0x72,0x65,0x20,0x64,0x72,0x61,0x66,0x74,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65, - 0x6e,0x74,0x73,0x20,0x76,0x61,0x6c,0x69,0x64,0x20,0x66,0x6f,0x72,0x20,0x61,0x20, - 0x6d,0x61,0x78,0x69,0x6d,0x75,0x6d,0x20,0x6f,0x66,0x20,0x73,0x69,0x78,0x20,0x6d, - 0x6f,0x6e,0x74,0x68,0x73,0x20,0x61,0x6e,0x64,0x20,0x6d,0x61,0x79,0x20,0x62,0x65, - 0x20,0x75,0x70,0x64,0x61,0x74,0x65,0x64,0x2c,0x20,0x72,0x65,0x70,0x6c,0x61,0x63, - 0x65,0x64,0x2c,0x20,0x6f,0x72,0x20,0x6f,0x62,0x73,0x6f,0x6c,0x65,0x74,0x65,0x64, - 0x20,0x62,0x79,0x20,0x6f,0x74,0x68,0x65,0x72,0x20,0x64,0x6f,0x63,0x75,0x6d,0x65, - 0x6e,0x74,0x73,0x20,0x61,0x74,0x20,0x61,0x6e,0x79,0x20,0x74,0x69,0x6d,0x65,0x2e, - 0x20,0x49,0x74,0x20,0x69,0x73,0x20,0x69,0x6e,0x61,0x70,0x70,0x72,0x6f,0x70,0x72, - 0x69,0x61,0x74,0x65,0x20,0x74,0x6f,0x20,0x75,0x73,0x65,0x20,0x49,0x6e,0x74,0x65, - 0x72,0x6e,0x65,0x74,0x2d,0x44,0x72,0x61,0x66,0x74,0x73,0x20,0x61,0x73,0x20,0x72, - 0x65,0x66,0x65,0x72,0x65,0x6e,0x63,0x65,0x20,0x6d,0x61,0x74,0x65,0x72,0x69,0x61, - 0x6c,0x20,0x6f,0x72,0x20,0x74,0x6f,0x20,0x63,0x69,0x74,0x65,0x20,0x74,0x68,0x65, - 0x6d,0x20,0x6f,0x74,0x68,0x65,0x72,0x20,0x74,0x68,0x61,0x6e,0x20,0x61,0x73,0x20, - 0x2f,0xe2,0x80,0x9c,0x77,0x6f,0x72,0x6b,0x20,0x69,0x6e,0x20,0x70,0x72,0x6f,0x67, - 0x72,0x65,0x73,0x73,0x2e,0x2f,0xe2,0x80,0x9d } ; - - if(!constant_time_memory_compare(cleartext,ciphertext,16*16+9)) - return false ; - } - std::cerr << " RFC7539 AEAD test vector #1 OK" << std::endl; - - // bandwidth test - // - - { - uint32_t SIZE = 1*1024*1024 ; - uint8_t *ten_megabyte_data = (uint8_t*)malloc(SIZE) ; - - memset(ten_megabyte_data,0x37,SIZE) ; // put something. We dont really care here. - - uint8_t key[32] = { 0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0, - 0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0 }; - - uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 }; - uint8_t aad[12] = { 0xf3,0x33,0x88,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x91 }; - - uint8_t received_tag[16] ; - - { - rstime::RsScopeTimer s("AEAD1") ; - chacha20_encrypt_rs(key, 1, nonce, ten_megabyte_data,SIZE) ; - - std::cerr << " Chacha20 encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl; - } - { - rstime::RsScopeTimer s("AEAD2") ; - AEAD_chacha20_poly1305_rs(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ; - - std::cerr << " AEAD/poly1305 own encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl; - } -#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) - { - rstime::RsScopeTimer s("AEAD3") ; - AEAD_chacha20_poly1305_openssl(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ; - - std::cerr << " AEAD/poly1305 openssl encryption speed: " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl; - } -#endif - { - rstime::RsScopeTimer s("AEAD4") ; - AEAD_chacha20_sha256(key,nonce,ten_megabyte_data,SIZE,aad,12,received_tag,true) ; - - std::cerr << " AEAD/sha256 encryption speed : " << SIZE / (1024.0*1024.0) / s.duration() << " MB/s" << std::endl; - } - - free(ten_megabyte_data) ; - } - - return true; -} - -} -} - - diff --git a/libretroshare/src/crypto/chacha20.h b/libretroshare/src/crypto/chacha20.h deleted file mode 100644 index 1b19a1402..000000000 --- a/libretroshare/src/crypto/chacha20.h +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * libretroshare/src/crypto: chacha20.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -namespace librs -{ - namespace crypto - { - /*! - * \brief chacha20_encrypt - * Performs in place encryption/decryption of the supplied data, using chacha20, using the supplied key and nonce. - * - * \param key secret encryption key. *Should never* be re-used. - * \param block_counter any integer. 0 is fine. - * \param nonce acts as an initialzation vector. /!\ it is extremely important to make sure that this nounce *is* everytime different. Using a purely random value is fine. - * \param data data that gets encrypted/decrypted in place - * \param size size of the data. - */ - void chacha20_encrypt(uint8_t key[32], uint32_t block_counter, uint8_t nonce[12], uint8_t *data, uint32_t size) ; - - /*! - * \brief poly1305_tag - * Computes an authentication tag for the supplied data, using the given secret key. - * \param key secret key. *Should not* be used multiple times. - * \param message message to generate a tag for - * \param size size of the message - * \param tag place where the tag is stored. - */ - - void poly1305_tag(uint8_t key[32],uint8_t *message,uint32_t size,uint8_t tag[16]); - - /*! - * \brief AEAD_chacha20_poly1305 - * Provides in-place authenticated encryption using the AEAD construction as described in RFC7539. - * The data is first encrypted in place then 16-padded and concatenated to its size, than concatenated to the - * 16-padded AAD (additional authenticated data) and its size, authenticated using poly1305. - * - * \param key key that is used to derive a one time secret key for poly1305 and that is also used to encrypt the data - * \param nonce nonce. *Should be unique* in order to make the chacha20 stream cipher unique. - * \param data data that is encrypted/decrypted in place. - * \param size size of the data - * \param aad additional authenticated data. Can be used to authenticate the nonce. - * \param aad_size - * \param tag generated poly1305 tag. - * \param encrypt true to encrypt, false to decrypt and check the tag. - * \return - * always true for encryption. - * authentication result for decryption. data is *always* xored to the cipher stream whatever the authentication result is. - */ - bool AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt_or_decrypt) ; - - /*! - * \brief AEAD_chacha20_sha256 - * Provides authenticated encryption using a simple construction that associates chacha20 encryption with HMAC authentication using - * the same 32 bytes key. The authenticated tag is the 16 first bytes of the sha256 HMAC. - * - * \param key encryption/authentication key - * \param nonce nonce. *Should be unique* in order to make chacha20 stream cipher unique. - * \param data data that is encrypted/decrypted in place - * \param data_size size of data to encrypt/authenticate - * \param aad additional authenticated data. Can be used to authenticate the nonce. - * \param aad_size - * \param tag 16 bytes authentication tag result - * \param encrypt true to encrypt, false to decrypt and check the tag. - * \return - * always true for encryption. - * authentication result for decryption. data is *always* xored to the cipher stream whatever the authentication result is. - */ - bool AEAD_chacha20_sha256(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16],bool encrypt_or_decrypt) ; - - /*! - * \brief constant_time_memcmp - * Provides a constant time comparison of two memory chunks. Calls CRYPTO_memcmp. - * - * \param m1 memory block 1 - * \param m2 memory block 2 - * \param size common size of m1 and m2 - * \return - * false if the two chunks are different - * true if the two chunks are identical - */ - bool constant_time_memory_compare(const uint8_t *m1,const uint8_t *m2,uint32_t size) ; - - /*! - * \brief perform_tests - * Tests all methods in this class, using the tests supplied in RFC7539 - * \return - * true is all tests pass - */ - - bool perform_tests() ; - } -} diff --git a/libretroshare/src/crypto/hashstream.cc b/libretroshare/src/crypto/hashstream.cc deleted file mode 100644 index 1d3c46b75..000000000 --- a/libretroshare/src/crypto/hashstream.cc +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * libretroshare/src/crypto: hashstream.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "hashstream.h" - -#include -#include -#include -#include - -namespace librs -{ - namespace crypto - { - HashStream::HashStream(HashType t) - { - assert(t == SHA1) ; - - mdctx = EVP_MD_CTX_create(); - EVP_DigestInit_ex(mdctx,EVP_sha1(),NULL); - } - HashStream::~HashStream() - { - if(mdctx) - EVP_MD_CTX_destroy(mdctx) ; - } - - Sha1CheckSum HashStream::hash() - { - uint8_t h[EVP_MAX_MD_SIZE] ; - unsigned int len; - EVP_DigestFinal_ex(mdctx,h,&len) ; - - EVP_MD_CTX_destroy(mdctx) ; - mdctx=NULL ; - - return Sha1CheckSum(h); - } - - template<> - HashStream& operator<<(HashStream& u,const std::string& s) - { - EVP_DigestUpdate(u.mdctx,s.c_str(),s.length()) ; - return u; - } - template<> - HashStream& operator<<(HashStream& u,const uint64_t& n) - { - unsigned char mem[8] ; - uint64_t s(n); - for(int i=0;i<8;++i) - { - mem[i] = (uint8_t)s; - s <<= 8 ; - } - - EVP_DigestUpdate(u.mdctx,mem,8); - return u; - } - template<> - HashStream& operator<<(HashStream& u,const uint32_t& n) - { - unsigned char mem[4] ; - uint64_t s(n); - for(int i=0;i<4;++i) - { - mem[i] = (uint8_t)s; - s <<= 8 ; - } - - EVP_DigestUpdate(u.mdctx,mem,4); - return u; - } - template<> - HashStream& operator<<(HashStream& u,const uint8_t& n) - { - EVP_DigestUpdate(u.mdctx,&n,1); - return u; - } - - } -} diff --git a/libretroshare/src/crypto/hashstream.h b/libretroshare/src/crypto/hashstream.h deleted file mode 100644 index b303b6509..000000000 --- a/libretroshare/src/crypto/hashstream.h +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * libretroshare/src/crypto: hashstream.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -namespace librs -{ - namespace crypto - { - // Forward declare the class - class HashStream; - // Forward declare the template operator - template HashStream& operator<<(HashStream& u, const T&); - - class HashStream - { - public: - enum HashType { UNKNOWN = 0x00, - SHA1 = 0x01 - }; - - HashStream(HashType t); - ~HashStream(); - - Sha1CheckSum hash() ; - - template friend HashStream& operator<<(HashStream& u, const T&) ; - - template - friend HashStream& operator<<(HashStream& u, const t_RsGenericIdType& r) - { - EVP_DigestUpdate(u.mdctx, r.toByteArray(), ID_SIZE_IN_BYTES); - return u; - } - private: - EVP_MD_CTX *mdctx ; - }; - } -} diff --git a/libretroshare/src/crypto/rsaes.cc b/libretroshare/src/crypto/rsaes.cc deleted file mode 100644 index d5ad2c7a0..000000000 --- a/libretroshare/src/crypto/rsaes.cc +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsaes.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include - -#include "rsaes.h" - -uint32_t RsAES::get_buffer_size(uint32_t n) -{ - return n + AES_BLOCK_SIZE ; -} - -bool RsAES::aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key_data[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) -{ - int nrounds = 5; - uint8_t key[32], iv[32]; - - /* - * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material. - * nrounds is the number of times the we hash the material. More rounds are more secure but - * slower. - */ - int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, 16, nrounds, key, iv); - - if (i != 32) - { - printf("Key size is %d bits - should be 256 bits\n", i); - return false ; - } - - EVP_CIPHER_CTX *e_ctx = EVP_CIPHER_CTX_new(); - EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv); - - /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */ - int c_len = input_data_length + AES_BLOCK_SIZE ; - int f_len = 0; - - if(output_data_length < (uint32_t)c_len) - { - EVP_CIPHER_CTX_free(e_ctx) ; - return false ; - } - - /* update ciphertext, c_len is filled with the length of ciphertext generated, - *len is the size of plaintext in bytes */ - - 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_free(e_ctx) ; - return false ; - } - - /* update ciphertext with the final remaining bytes */ - 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_free(e_ctx) ; - return false ; - } - - output_data_length = c_len + f_len; - - EVP_CIPHER_CTX_free(e_ctx) ; - return true; -} - -bool RsAES::aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key_data[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) -{ - int nrounds = 5; - uint8_t key[32], iv[32]; - - /* - * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material. - * nrounds is the number of times the we hash the material. More rounds are more secure but - * slower. - */ - int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, 16, nrounds, key, iv); - - if (i != 32) - { - printf("Key size is %d bits - should be 256 bits\n", i); - return false ; - } - - EVP_CIPHER_CTX *e_ctx = EVP_CIPHER_CTX_new(); - EVP_DecryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv); - - /* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */ - int c_len = input_data_length + AES_BLOCK_SIZE ; - int f_len = 0; - - if(output_data_length < (uint32_t)c_len) - { - EVP_CIPHER_CTX_free(e_ctx) ; - return false ; - } - - output_data_length = c_len ; - - /* update ciphertext, c_len is filled with the length of ciphertext generated, - *len is the size of plaintext in bytes */ - - if(! EVP_DecryptUpdate(e_ctx, output_data, &c_len, input_data, input_data_length)) - { - std::cerr << "RsAES: decryption failed." << std::endl; - EVP_CIPHER_CTX_free(e_ctx) ; - return false ; - } - - /* update ciphertext with the final remaining bytes */ - 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_free(e_ctx) ; - return false ; - } - - output_data_length = c_len + f_len; - - EVP_CIPHER_CTX_free(e_ctx) ; - return true; -} - diff --git a/libretroshare/src/crypto/rsaes.h b/libretroshare/src/crypto/rsaes.h deleted file mode 100644 index d4592793d..000000000 --- a/libretroshare/src/crypto/rsaes.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsaes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -class RsAES -{ - public: - // Crypt/decrypt data using a 16 bytes key and a 8 bytes salt. - // - // output_data allocation is left to the client. The size should be at least RsAES::get_buffer_size(input_data_length) - // - // Return value: - // true: encryption/decryption ok - // - // false: encryption/decryption went bad. Check buffer size. - // - static bool aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) ; - static bool aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) ; - - // computes the safe buffer size to store encrypted/decrypted data for the given input stream size - // - static uint32_t get_buffer_size(uint32_t size) ; -}; - diff --git a/libretroshare/src/crypto/rscrypto.cpp b/libretroshare/src/crypto/rscrypto.cpp deleted file mode 100644 index 0a296673e..000000000 --- a/libretroshare/src/crypto/rscrypto.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/******************************************************************************* - * libretroshare/src/crypto: crypto.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include - -#include "rscrypto.h" -#include "util/rsrandom.h" - -//#define CRYPTO_DEBUG 1 - -namespace librs { -namespace crypto { - -#define RSCRYPTO_DEBUG() std::cerr << time(NULL) << " : RSCRYPTO : " << __FUNCTION__ << " : " -#define RSCRYPTO_ERROR() std::cerr << "(EE) RSCRYPTO ERROR : " - -static const uint32_t ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE = 12 ; -static const uint32_t ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE = 16 ; -static const uint32_t ENCRYPTED_MEMORY_HEADER_SIZE = 4 ; -static const uint32_t ENCRYPTED_MEMORY_EDATA_SIZE = 4 ; - -static const uint8_t ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_POLY1305 = 0x01 ; -static const uint8_t ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_SHA256 = 0x02 ; - -bool encryptAuthenticateData(const unsigned char *clear_data,uint32_t clear_data_size,uint8_t *encryption_master_key,unsigned char *& encrypted_data,uint32_t& encrypted_data_len) -{ - uint8_t initialization_vector[ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE] ; - - RSRandom::random_bytes(initialization_vector,ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE) ; - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << "ftServer::Encrypting ft item." << std::endl; - RSCRYPTO_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE) << std::endl; -#endif - - uint32_t item_serialized_size = clear_data_size;//RsGenericSerializer().size(clear_item) ; - uint32_t total_data_size = ENCRYPTED_MEMORY_HEADER_SIZE + ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_MEMORY_EDATA_SIZE + item_serialized_size + ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE ; - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << " clear part size : " << size(clear_item) << std::endl; - RSCRYPTO_DEBUG() << " total item size : " << total_data_size << std::endl; -#endif - - encrypted_data = (unsigned char*)rs_malloc( total_data_size ) ; - encrypted_data_len = total_data_size ; - - if(encrypted_data == NULL) - return false ; - - uint8_t *edata = (uint8_t*)encrypted_data; - uint32_t edata_size = item_serialized_size; - uint32_t offset = 0; - - edata[0] = 0xae ; - edata[1] = 0xad ; - edata[2] = ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_SHA256 ; // means AEAD_chacha20_sha256 - edata[3] = 0x01 ; - - offset += ENCRYPTED_MEMORY_HEADER_SIZE; - uint32_t aad_offset = offset ; - uint32_t aad_size = ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_MEMORY_EDATA_SIZE ; - - memcpy(&edata[offset], initialization_vector, ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE) ; - offset += ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE ; - - edata[offset+0] = (edata_size >> 0) & 0xff ; - edata[offset+1] = (edata_size >> 8) & 0xff ; - edata[offset+2] = (edata_size >> 16) & 0xff ; - edata[offset+3] = (edata_size >> 24) & 0xff ; - - offset += ENCRYPTED_MEMORY_EDATA_SIZE ; - - memcpy(&edata[offset],clear_data,clear_data_size); - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << " clear item : " << RsUtil::BinToHex(&edata[offset],std::min(50,(int)total_data_size-(int)offset)) << "(...)" << std::endl; -#endif - - uint32_t clear_item_offset = offset ; - offset += edata_size ; - - uint32_t authentication_tag_offset = offset ; - assert(ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE + offset == total_data_size) ; - - //uint8_t encryption_key[32] ; - //deriveEncryptionKey(hash,encryption_key) ; - - if(edata[2] == ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_POLY1305) - librs::crypto::AEAD_chacha20_poly1305(encryption_master_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ; - else if(edata[2] == ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_SHA256) - librs::crypto::AEAD_chacha20_sha256 (encryption_master_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ; - else - return false ; - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl; - RSCRYPTO_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE) << std::endl; - RSCRYPTO_DEBUG() << " final item : " << RsUtil::BinToHex(&edata[0],std::min(50u,total_data_size)) << "(...)" << std::endl; -#endif - - return true ; -} - -// Decrypts the given item using aead-chacha20-poly1305 -bool decryptAuthenticateData(const unsigned char *encrypted_data,uint32_t encrypted_data_len,uint8_t *encryption_master_key, unsigned char *& decrypted_data, uint32_t& decrypted_data_size) -{ - //uint8_t encryption_key[32] ; - //deriveEncryptionKey(hash,encryption_key) ; - - uint8_t *edata = (uint8_t*)encrypted_data; - uint32_t offset = 0; - - if(encrypted_data_len < ENCRYPTED_MEMORY_HEADER_SIZE + ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_MEMORY_EDATA_SIZE) return false ; - - if(edata[0] != 0xae) return false ; - if(edata[1] != 0xad) return false ; - if(edata[2] != ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_POLY1305 && edata[2] != ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_SHA256) return false ; - if(edata[3] != 0x01) return false ; - - offset += ENCRYPTED_MEMORY_HEADER_SIZE ; - uint32_t aad_offset = offset ; - uint32_t aad_size = ENCRYPTED_MEMORY_EDATA_SIZE + ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE ; - - uint8_t *initialization_vector = &edata[offset] ; - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << "ftServer::decrypting ft item." << std::endl; - RSCRYPTO_DEBUG() << " item data : " << RsUtil::BinToHex(edata,std::min(50u,encrypted_data_len) << "(...)" << std::endl; - RSCRYPTO_DEBUG() << " hash : " << hash << std::endl; - RSCRYPTO_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl; - RSCRYPTO_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE) << std::endl; -#endif - - offset += ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE ; - - uint32_t edata_size = 0 ; - edata_size += ((uint32_t)edata[offset+0]) << 0 ; - edata_size += ((uint32_t)edata[offset+1]) << 8 ; - edata_size += ((uint32_t)edata[offset+2]) << 16 ; - edata_size += ((uint32_t)edata[offset+3]) << 24 ; - - if(edata_size + ENCRYPTED_MEMORY_EDATA_SIZE + ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE + ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_MEMORY_HEADER_SIZE != encrypted_data_len) - { - RSCRYPTO_ERROR() << " ERROR: encrypted data size is " << edata_size << ", should be " << encrypted_data_len - (ENCRYPTED_MEMORY_EDATA_SIZE + ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE + ENCRYPTED_MEMORY_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_MEMORY_HEADER_SIZE ) << std::endl; - return false ; - } - - offset += ENCRYPTED_MEMORY_EDATA_SIZE ; - uint32_t clear_item_offset = offset ; - - uint32_t authentication_tag_offset = offset + edata_size ; -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_MEMORY_AUTHENTICATION_TAG_SIZE) << std::endl; -#endif - - bool result ; - - if(edata[2] == ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_POLY1305) - result = librs::crypto::AEAD_chacha20_poly1305(encryption_master_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ; - else if(edata[2] == ENCRYPTED_MEMORY_FORMAT_AEAD_CHACHA20_SHA256) - result = librs::crypto::AEAD_chacha20_sha256 (encryption_master_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ; - else - return false ; - -#ifdef CRYPTO_DEBUG - RSCRYPTO_DEBUG() << " authen. result : " << result << std::endl; - RSCRYPTO_DEBUG() << " decrypted daya : " << RsUtil::BinToHex(&edata[clear_item_offset],std::min(50u,edata_size)) << "(...)" << std::endl; -#endif - - if(!result) - { - RSCRYPTO_ERROR() << "(EE) decryption/authentication went wrong." << std::endl; - return false ; - } - - decrypted_data_size = edata_size ; - decrypted_data = (unsigned char*)rs_malloc(edata_size) ; - - if(decrypted_data == NULL) - { - std::cerr << "Failed to allocate memory for decrypted data chunk of size " << edata_size << std::endl; - return false ; - } - memcpy(decrypted_data,&edata[clear_item_offset],edata_size) ; - - return true ; -} - -} -} - diff --git a/libretroshare/src/crypto/rscrypto.h b/libretroshare/src/crypto/rscrypto.h deleted file mode 100644 index 9666aed28..000000000 --- a/libretroshare/src/crypto/rscrypto.h +++ /dev/null @@ -1,59 +0,0 @@ - -/******************************************************************************* - * libretroshare/src/crypto: crypto.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "crypto/chacha20.h" - -namespace librs -{ -namespace crypto -{ -/*! - * \brief encryptAuthenticateData - Encrypts/decrypts data, using a autenticated construction + chacha20, based on a given 32 bytes master key. The actual encryption using a randomized key - based on a 96 bits IV. Input values are not touched (memory is not released). Memory ownership of outputs is left to the client. - * \param clear_data input data to encrypt - * \param clear_data_size length of input data - * \param encryption_master_key encryption master key of length 32 bytes. - * \param encrypted_data encrypted data, allocated using malloc - * \param encrypted_data_len length of encrypted data - * \return - * true if everything went well. - */ -bool encryptAuthenticateData(const unsigned char *clear_data,uint32_t clear_data_size,uint8_t *encryption_master_key,unsigned char *& encrypted_data,uint32_t& encrypted_data_size); - -/*! - * \brief decryptAuthenticateData - Encrypts/decrypts data, using a autenticated construction + chacha20, based on a given 32 bytes master key. The actual encryption using a randomized key - based on a 96 bits IV. Input values are not touched (memory is not released). Memory ownership of outputs is left to the client. - * \param encrypted_data input encrypted data - * \param encrypted_data_size input encrypted data length - * \param encryption_master_key encryption master key of length 32 bytes. - * \param decrypted_data decrypted data, allocated using malloc. - * \param decrypted_data_size length of allocated decrypted data. - * \return - * true if decryption + authentication are ok. - */ -bool decryptAuthenticateData(const unsigned char *encrypted_data,uint32_t encrypted_data_size, uint8_t* encryption_master_key, unsigned char *& decrypted_data,uint32_t& decrypted_data_size); -} -} - diff --git a/libretroshare/src/deep_search/channelsindex.cpp b/libretroshare/src/deep_search/channelsindex.cpp deleted file mode 100644 index cd1c374fc..000000000 --- a/libretroshare/src/deep_search/channelsindex.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/channelsindex.hpp" -#include "deep_search/commonutils.hpp" - -uint32_t DeepChannelsIndex::search( - const std::string& queryStr, - std::vector& results, uint32_t maxResults ) -{ - results.clear(); - - std::unique_ptr dbPtr( - DeepSearch::openReadOnlyDatabase(dbPath()) ); - if(!dbPtr) return 0; - - Xapian::Database& db(*dbPtr); - - // Set up a QueryParser with a stemmer and suitable prefixes. - Xapian::QueryParser queryparser; - //queryparser.set_stemmer(Xapian::Stem("en")); - queryparser.set_stemming_strategy(queryparser.STEM_SOME); - // Start of prefix configuration. - //queryparser.add_prefix("title", "S"); - //queryparser.add_prefix("description", "XD"); - // End of prefix configuration. - - // And parse the query. - Xapian::Query query = queryparser.parse_query(queryStr); - - // Use an Enquire object on the database to run the query. - Xapian::Enquire enquire(db); - enquire.set_query(query); - - Xapian::MSet mset = enquire.get_mset( - 0, maxResults ? maxResults : db.get_doccount() ); - - for ( Xapian::MSetIterator m = mset.begin(); m != mset.end(); ++m ) - { - const Xapian::Document& doc = m.get_document(); - DeepChannelsSearchResult s; - s.mUrl = doc.get_value(URL_VALUENO); -#if XAPIAN_AT_LEAST(1,3,5) - s.mSnippet = mset.snippet(doc.get_data()); -#endif // XAPIAN_AT_LEAST(1,3,5) - results.push_back(s); - } - - return static_cast(results.size()); -} - -void DeepChannelsIndex::indexChannelGroup(const RsGxsChannelGroup& chan) -{ - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - - // Set up a TermGenerator that we'll use in indexing. - Xapian::TermGenerator termgenerator; - //termgenerator.set_stemmer(Xapian::Stem("en")); - - // We make a document and tell the term generator to use this. - Xapian::Document doc; - termgenerator.set_document(doc); - - // Index each field with a suitable prefix. - termgenerator.index_text(chan.mMeta.mGroupName, 1, "G"); - termgenerator.index_text( - DeepSearch::timetToXapianDate(chan.mMeta.mPublishTs), 1, "D" ); - termgenerator.index_text(chan.mDescription, 1, "XD"); - - // Index fields without prefixes for general search. - termgenerator.index_text(chan.mMeta.mGroupName); - termgenerator.increase_termpos(); - termgenerator.index_text(chan.mDescription); - - RsUrl chanUrl; chanUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", chan.mMeta.mGroupId.toStdString()); - const std::string idTerm("Q" + chanUrl.toString()); - - chanUrl.setQueryKV("publishTs", std::to_string(chan.mMeta.mPublishTs)); - chanUrl.setQueryKV("name", chan.mMeta.mGroupName); - if(!chan.mMeta.mAuthorId.isNull()) - chanUrl.setQueryKV("authorId", chan.mMeta.mAuthorId.toStdString()); - if(chan.mMeta.mSignFlags) - chanUrl.setQueryKV( "signFlags", - std::to_string(chan.mMeta.mSignFlags) ); - std::string rsLink(chanUrl.toString()); - - // store the RS link so we are able to retrive it on matching search - doc.add_value(URL_VALUENO, rsLink); - - // Store some fields for display purposes. - doc.set_data(chan.mMeta.mGroupName + "\n" + chan.mDescription); - - // We use the identifier to ensure each object ends up in the - // database only once no matter how many times we run the - // indexer. "Q" prefix is a Xapian convention for unique id term. - doc.add_boolean_term(idTerm); - db.replace_document(idTerm, doc); -} - -void DeepChannelsIndex::removeChannelFromIndex(RsGxsGroupId grpId) -{ - // "Q" prefix is a Xapian convention for unique id term. - RsUrl chanUrl; chanUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", grpId.toStdString()); - std::string idTerm("Q" + chanUrl.toString()); - - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - db.delete_document(idTerm); -} - -void DeepChannelsIndex::indexChannelPost(const RsGxsChannelPost& post) -{ - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - - // Set up a TermGenerator that we'll use in indexing. - Xapian::TermGenerator termgenerator; - //termgenerator.set_stemmer(Xapian::Stem("en")); - - // We make a document and tell the term generator to use this. - Xapian::Document doc; - termgenerator.set_document(doc); - - // Index each field with a suitable prefix. - termgenerator.index_text(post.mMeta.mMsgName, 1, "S"); - termgenerator.index_text( - DeepSearch::timetToXapianDate(post.mMeta.mPublishTs), 1, "D" ); - - // TODO: we should strip out HTML tags instead of skipping indexing - // Avoid indexing HTML - bool isPlainMsg = - post.mMsg[0] != '<' || post.mMsg[post.mMsg.size() - 1] != '>'; - - if(isPlainMsg) - termgenerator.index_text(post.mMsg, 1, "XD"); - - // Index fields without prefixes for general search. - termgenerator.index_text(post.mMeta.mMsgName); - if(isPlainMsg) - { - termgenerator.increase_termpos(); - termgenerator.index_text(post.mMsg); - } - - for(const RsGxsFile& attachment : post.mFiles) - { - termgenerator.index_text(attachment.mName, 1, "F"); - - termgenerator.increase_termpos(); - termgenerator.index_text(attachment.mName); - } - - // We use the identifier to ensure each object ends up in the - // database only once no matter how many times we run the - // indexer. - RsUrl postUrl; postUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", post.mMeta.mGroupId.toStdString()) - .setQueryKV("msgid", post.mMeta.mMsgId.toStdString()); - std::string idTerm("Q" + postUrl.toString()); - - postUrl.setQueryKV("publishTs", std::to_string(post.mMeta.mPublishTs)); - postUrl.setQueryKV("name", post.mMeta.mMsgName); - postUrl.setQueryKV("authorId", post.mMeta.mAuthorId.toStdString()); - std::string rsLink(postUrl.toString()); - - // store the RS link so we are able to retrive it on matching search - doc.add_value(URL_VALUENO, rsLink); - - // Store some fields for display purposes. - if(isPlainMsg) - doc.set_data(post.mMeta.mMsgName + "\n" + post.mMsg); - else doc.set_data(post.mMeta.mMsgName); - - doc.add_boolean_term(idTerm); - db.replace_document(idTerm, doc); -} - -void DeepChannelsIndex::removeChannelPostFromIndex( - RsGxsGroupId grpId, RsGxsMessageId msgId ) -{ - RsUrl postUrl; postUrl - .setScheme("retroshare").setPath("/channel") - .setQueryKV("id", grpId.toStdString()) - .setQueryKV("msgid", msgId.toStdString()); - // "Q" prefix is a Xapian convention for unique id term. - std::string idTerm("Q" + postUrl.toString()); - - std::unique_ptr dbPtr( - DeepSearch::openWritableDatabase( - dbPath(), Xapian::DB_CREATE_OR_OPEN ) ); - if(!dbPtr) return; - - Xapian::WritableDatabase& db(*dbPtr); - db.delete_document(idTerm); -} diff --git a/libretroshare/src/deep_search/channelsindex.hpp b/libretroshare/src/deep_search/channelsindex.hpp deleted file mode 100644 index 0a49629d9..000000000 --- a/libretroshare/src/deep_search/channelsindex.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "util/rstime.h" -#include "retroshare/rsgxschannels.h" -#include "retroshare/rsinit.h" -#include "util/rsurl.h" - -struct DeepChannelsSearchResult -{ - std::string mUrl; - double mWeight; - std::string mSnippet; -}; - -struct DeepChannelsIndex -{ - /** - * @brief Search indexed GXS groups and messages - * @param[in] maxResults maximum number of acceptable search results, 0 for - * no limits - * @return search results count - */ - static uint32_t search( const std::string& queryStr, - std::vector& results, - uint32_t maxResults = 100 ); - - static void indexChannelGroup(const RsGxsChannelGroup& chan); - - static void removeChannelFromIndex(RsGxsGroupId grpId); - - static void indexChannelPost(const RsGxsChannelPost& post); - - static void removeChannelPostFromIndex( - RsGxsGroupId grpId, RsGxsMessageId msgId ); - - static uint32_t indexFile(const std::string& path); - -private: - - enum : Xapian::valueno - { - /// Used to store retroshare url of indexed documents - URL_VALUENO, - - /// @see Xapian::BAD_VALUENO - BAD_VALUENO = Xapian::BAD_VALUENO - }; - - static const std::string& dbPath() - { - static const std::string dbDir = - RsAccounts::AccountDirectory() + "/deep_channels_xapian_db"; - return dbDir; - } -}; diff --git a/libretroshare/src/deep_search/commonutils.cpp b/libretroshare/src/deep_search/commonutils.cpp deleted file mode 100644 index eecbd4ec6..000000000 --- a/libretroshare/src/deep_search/commonutils.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/commonutils.hpp" -#include "util/stacktrace.h" -#include "util/rsdebug.h" - -namespace DeepSearch -{ - -std::unique_ptr openWritableDatabase( - const std::string& path, int flags, int blockSize ) -{ - try - { - std::unique_ptr dbPtr( - new Xapian::WritableDatabase(path, flags, blockSize) ); - return dbPtr; - } - catch(Xapian::DatabaseLockError) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed aquiring Xapian DB lock " - << path << std::endl; - print_stacktrace(); - } - catch(...) - { - RsErr() << __PRETTY_FUNCTION__ << " Xapian DB is apparently corrupted " - << "deleting it might help without causing any harm: " - << path << std::endl; - print_stacktrace(); - } - - return nullptr; -} - -std::unique_ptr openReadOnlyDatabase( - const std::string& path, int flags ) -{ - try - { - std::unique_ptr dbPtr( - new Xapian::Database(path, flags) ); - return dbPtr; - } - catch(Xapian::DatabaseOpeningError e) - { - RsWarn() << __PRETTY_FUNCTION__ << " " << e.get_msg() - << ", probably nothing has been indexed yet." << std::endl; - } - catch(Xapian::DatabaseLockError) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed aquiring Xapian DB lock " - << path << std::endl; - print_stacktrace(); - } - catch(...) - { - RsErr() << __PRETTY_FUNCTION__ << " Xapian DB is apparently corrupted " - << "deleting it might help without causing any harm: " - << path << std::endl; - print_stacktrace(); - } - - return nullptr; -} - -std::string timetToXapianDate(const rstime_t& time) -{ - char date[] = "YYYYMMDD\0"; - time_t tTime = static_cast(time); - std::strftime(date, 9, "%Y%m%d", std::gmtime(&tTime)); - return date; -} - -} diff --git a/libretroshare/src/deep_search/commonutils.hpp b/libretroshare/src/deep_search/commonutils.hpp deleted file mode 100644 index 28961bc09..000000000 --- a/libretroshare/src/deep_search/commonutils.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "util/rstime.h" - -#ifndef XAPIAN_AT_LEAST -#define XAPIAN_AT_LEAST(A,B,C) (XAPIAN_MAJOR_VERSION > (A) || \ - (XAPIAN_MAJOR_VERSION == (A) && \ - (XAPIAN_MINOR_VERSION > (B) || \ - (XAPIAN_MINOR_VERSION == (B) && XAPIAN_REVISION >= (C))))) -#endif // ndef XAPIAN_AT_LEAST - -namespace DeepSearch -{ - -std::unique_ptr openWritableDatabase( - const std::string& path, int flags = 0, int blockSize = 0 ); - -std::unique_ptr openReadOnlyDatabase( - const std::string& path, int flags = 0 ); - -std::string timetToXapianDate(const rstime_t& time); - -} diff --git a/libretroshare/src/deep_search/filesflacindexer.hpp b/libretroshare/src/deep_search/filesflacindexer.hpp deleted file mode 100644 index dbdc62b99..000000000 --- a/libretroshare/src/deep_search/filesflacindexer.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/filesindex.hpp" -#include "util/rsdebug.h" - -#include -#include -#include -#include -#include - -struct RsDeepFlacFileIndexer -{ - RsDeepFlacFileIndexer() - { - DeepFilesIndex::registerIndexer(31, indexFlacFile); - } - - static uint32_t indexFlacFile( - const std::string& path, const std::string& /*name*/, - Xapian::TermGenerator& xTG, Xapian::Document& xDoc ) - { - Dbg3() << __PRETTY_FUNCTION__ << " " << path << std::endl; - - using FlacChain = FLAC::Metadata::Chain; - std::unique_ptr flacChain(new FlacChain); - - if(!flacChain->is_valid()) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed creating FLAC Chain 1" - << std::endl; - return 1; - } - - if(!flacChain->read(path.c_str(), false)) - { - Dbg3() << __PRETTY_FUNCTION__ << " Failed to open the file as FLAC" - << std::endl; - - flacChain.reset(new FlacChain); - if(!flacChain->is_valid()) - { - RsErr() << __PRETTY_FUNCTION__ - << " Failed creating FLAC Chain 2" << std::endl; - return 1; - } - if(!flacChain->read(path.c_str(), true)) - { - Dbg3() << __PRETTY_FUNCTION__ - << " Failed to open the file as OggFLAC" - << std::endl; - return 0; - } - } - - unsigned validCommentsCnt = 0; - std::string docData = xDoc.get_data(); - - FLAC::Metadata::Iterator mdit; - mdit.init(*flacChain); - if(!mdit.is_valid()) return 1; - - do - { - ::FLAC__MetadataType mdt = mdit.get_block_type(); - if (mdt != FLAC__METADATA_TYPE_VORBIS_COMMENT) continue; - - Dbg2() << __PRETTY_FUNCTION__ << " Found Vorbis Comment Block" - << std::endl; - - std::unique_ptr proto(mdit.get_block()); - if(!proto) continue; - - const FLAC::Metadata::VorbisComment* vc = - dynamic_cast(proto.get()); - if(!vc || !vc->is_valid()) continue; - - unsigned numComments = vc->get_num_comments(); - for(unsigned i = 0; i < numComments; ++i) - { - FLAC::Metadata::VorbisComment::Entry entry = - vc->get_comment(i); - if(!entry.is_valid()) continue; - - std::string tagName( entry.get_field_name(), - entry.get_field_name_length() ); - - /* Vorbis tags should be uppercases but not all the softwares - * enforce it */ - for (auto& c: tagName) c = static_cast(toupper(c)); - - std::string tagValue( entry.get_field_value(), - entry.get_field_value_length() ); - - if(tagValue.empty()) continue; - - if(tagName == "ARTIST") - xTG.index_text(tagValue, 1, "A"); - else if (tagName == "DESCRIPTION") - xTG.index_text(tagValue, 1, "XD"); - else if (tagName == "TITLE") - xTG.index_text(tagValue, 1, "S"); - else if(tagName.find("COVERART") != tagName.npos) - continue; // Avoid polluting the index with binary data - else if (tagName.find("METADATA_BLOCK_PICTURE") != tagName.npos) - continue; // Avoid polluting the index with binary data - - // Index fields without prefixes for general search. - xTG.increase_termpos(); - std::string fullComment(tagName + "=" + tagValue); - xTG.index_text(fullComment); - docData += fullComment + "\n"; - - Dbg2() << __PRETTY_FUNCTION__ << " Indexed " << fullComment - << std::endl; - - ++validCommentsCnt; - } - } - while(mdit.next()); - - if(validCommentsCnt > 0) - { - Dbg1() << __PRETTY_FUNCTION__ << " Successfully indexed: " << path - << std::endl; - - xDoc.set_data(docData); - return 99; - } - - /* Altought the file appears to be a valid FLAC, no vorbis comment has - * been found so return less then 50 maybe it has tagged only with ID3 - * tags ? */ - return 30; - } - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; diff --git a/libretroshare/src/deep_search/filesindex.cpp b/libretroshare/src/deep_search/filesindex.cpp deleted file mode 100644 index 3edcf9a97..000000000 --- a/libretroshare/src/deep_search/filesindex.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/filesindex.hpp" -#include "deep_search/commonutils.hpp" -#include "util/rsdebug.h" -#include "retroshare/rsinit.h" -#include "retroshare/rsversion.h" - -#include - -/*static*/ std::multimap -DeepFilesIndex::indexersRegister = {}; - -bool DeepFilesIndex::indexFile( - const std::string& path, const std::string& name, - const RsFileHash& hash ) -{ - auto dbPtr = DeepSearch::openWritableDatabase( - mDbPath, Xapian::DB_CREATE_OR_OPEN ); - if(!dbPtr) return false; - Xapian::WritableDatabase& db(*dbPtr); - - const std::string hashString = hash.toStdString(); - const std::string idTerm("Q" + hashString); - - Xapian::Document oldDoc; - Xapian::PostingIterator pIt = db.postlist_begin(idTerm); - if( pIt != db.postlist_end(idTerm) ) - { - oldDoc = db.get_document(*pIt); - if( oldDoc.get_value(INDEXER_VERSION_VALUENO) == - RS_HUMAN_READABLE_VERSION && - std::stoull(oldDoc.get_value(INDEXERS_COUNT_VALUENO)) == - indexersRegister.size() ) - { - /* Looks like this file has already been indexed by this RetroShare - * exact version, so we can skip it. If the version was different it - * made sense to reindex it as better indexers might be available - * since last time it was indexed */ - Dbg3() << __PRETTY_FUNCTION__ << " skipping laready indexed file: " - << hash << " " << name << std::endl; - return true; - } - } - - Xapian::Document doc; - - // Set up a TermGenerator that we'll use in indexing. - Xapian::TermGenerator termgenerator; - //termgenerator.set_stemmer(Xapian::Stem("en")); - termgenerator.set_document(doc); - - for(auto& indexerPair : indexersRegister) - if(indexerPair.second(path, name, termgenerator, doc) > 50) - break; - - doc.add_boolean_term(idTerm); - termgenerator.index_text(name, 1, "N"); - termgenerator.index_text(name); - doc.add_value(FILE_HASH_VALUENO, hashString); - doc.add_value(INDEXER_VERSION_VALUENO, RS_HUMAN_READABLE_VERSION); - doc.add_value( - INDEXERS_COUNT_VALUENO, - std::to_string(indexersRegister.size()) ); - db.replace_document(idTerm, doc); - - return true; -} - -bool DeepFilesIndex::removeFileFromIndex(const RsFileHash& hash) -{ - Dbg3() << __PRETTY_FUNCTION__ << " removing file from index: " - << hash << std::endl; - - std::unique_ptr db = - DeepSearch::openWritableDatabase(mDbPath, Xapian::DB_CREATE_OR_OPEN); - if(!db) return false; - - db->delete_document("Q" + hash.toStdString()); - return true; -} - -/*static*/ std::string DeepFilesIndex::dbDefaultPath() -{ return RsAccounts::AccountDirectory() + "/deep_files_index_xapian_db"; } - -/*static*/ bool DeepFilesIndex::registerIndexer( - int order, const DeepFilesIndex::IndexerFunType& indexerFun ) -{ - Dbg1() << __PRETTY_FUNCTION__ << " " << order << std::endl; - - indexersRegister.insert(std::make_pair(order, indexerFun)); - return true; -} - -uint32_t DeepFilesIndex::search( - const std::string& queryStr, - std::vector& results, uint32_t maxResults ) -{ - results.clear(); - - auto dbPtr = DeepSearch::openReadOnlyDatabase(mDbPath); - if(!dbPtr) return 0; - Xapian::Database& db(*dbPtr); - - // Set up a QueryParser with a stemmer and suitable prefixes. - Xapian::QueryParser queryparser; - //queryparser.set_stemmer(Xapian::Stem("en")); - queryparser.set_stemming_strategy(queryparser.STEM_SOME); - // Start of prefix configuration. - //queryparser.add_prefix("title", "S"); - //queryparser.add_prefix("description", "XD"); - // End of prefix configuration. - - // And parse the query. - Xapian::Query query = queryparser.parse_query(queryStr); - - // Use an Enquire object on the database to run the query. - Xapian::Enquire enquire(db); - enquire.set_query(query); - - Xapian::MSet mset = enquire.get_mset( - 0, maxResults ? maxResults : db.get_doccount() ); - - for ( Xapian::MSetIterator m = mset.begin(); m != mset.end(); ++m ) - { - const Xapian::Document& doc = m.get_document(); - DeepFilesSearchResult s; - s.mFileHash = RsFileHash(doc.get_value(FILE_HASH_VALUENO)); - s.mWeight = m.get_weight(); -#if XAPIAN_AT_LEAST(1,3,5) - s.mSnippet = mset.snippet(doc.get_data()); -#endif // XAPIAN_AT_LEAST(1,3,5) - results.push_back(s); - } - - return static_cast(results.size()); -} - - -#ifdef RS_DEEP_FILES_INDEX_OGG -# include "deep_search/filesoggindexer.hpp" -static RsDeepOggFileIndexer oggFileIndexer; -#endif // def RS_DEEP_FILES_INDEX_OGG - -#ifdef RS_DEEP_FILES_INDEX_FLAC -# include "deep_search/filesflacindexer.hpp" -static RsDeepFlacFileIndexer flacFileIndexer; -#endif // def RS_DEEP_FILES_INDEX_FLAC - -#ifdef RS_DEEP_FILES_INDEX_TAGLIB -# include "deep_search/filestaglibindexer.hpp" -static RsDeepTaglibFileIndexer taglibFileIndexer; -#endif // def RS_DEEP_FILES_INDEX_TAGLIB diff --git a/libretroshare/src/deep_search/filesindex.hpp b/libretroshare/src/deep_search/filesindex.hpp deleted file mode 100644 index f811e5e9c..000000000 --- a/libretroshare/src/deep_search/filesindex.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rstypes.h" -#include "util/rsdebug.h" - -#include -#include -#include -#include -#include -#include - -struct DeepFilesSearchResult -{ - DeepFilesSearchResult() : mWeight(0) {} - - RsFileHash mFileHash; - double mWeight; - std::string mSnippet; -}; - -class DeepFilesIndex -{ -public: - DeepFilesIndex(const std::string& dbPath) : mDbPath(dbPath) {} - - /** - * @brief Search indexed files - * @param[in] maxResults maximum number of acceptable search results, 0 for - * no limits - * @return search results count - */ - uint32_t search( const std::string& queryStr, - std::vector& results, - uint32_t maxResults = 100 ); - - /** - * @return false if file could not be indexed because of error or - * unsupported type, true otherwise. - */ - bool indexFile( - const std::string& path, const std::string& name, - const RsFileHash& hash ); - - /** - * @brief Remove file entry from database - * @return false on error, true otherwise. - */ - bool removeFileFromIndex(const RsFileHash& hash); - - static std::string dbDefaultPath(); - - using IndexerFunType = std::function< - uint32_t( const std::string& path, const std::string& name, - Xapian::TermGenerator& xTG, Xapian::Document& xDoc ) >; - - static bool registerIndexer( - int order, const IndexerFunType& indexerFun ); - -private: - enum : Xapian::valueno - { - /// Used to store RsFileHash of indexed documents - FILE_HASH_VALUENO, - - /** Used to check if some file need reindex because was indexed with an - * older version of the indexer */ - INDEXER_VERSION_VALUENO, - - /** Used to check if some file need reindex because was indexed with an - * older version of the indexer */ - INDEXERS_COUNT_VALUENO, - - /// @see Xapian::BAD_VALUENO - BAD_VALUENO = Xapian::BAD_VALUENO - }; - - const std::string mDbPath; - - /** Storage for indexers function by order */ - static std::multimap indexersRegister; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; diff --git a/libretroshare/src/deep_search/filesoggindexer.hpp b/libretroshare/src/deep_search/filesoggindexer.hpp deleted file mode 100644 index 00c22ae66..000000000 --- a/libretroshare/src/deep_search/filesoggindexer.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/filesindex.hpp" -#include "util/rsdebug.h" - -#include -#include -#include -#include - -struct RsDeepOggFileIndexer -{ - RsDeepOggFileIndexer() - { - DeepFilesIndex::registerIndexer(30, indexOggFile); - } - - static uint32_t indexOggFile( - const std::string& path, const std::string& /*name*/, - Xapian::TermGenerator& xTG, Xapian::Document& xDoc ) - { - Dbg3() << __PRETTY_FUNCTION__ << " " << path << std::endl; - - OggVorbis_File vf; - int ret = ov_fopen(path.c_str(), &vf); - - if(ret == 0 && vf.vc) - { - vorbis_comment& vc = *vf.vc; - std::string docData = xDoc.get_data(); - for (int i = 0; i < vc.comments; ++i) - { - using szt = std::string::size_type; - std::string userComment( - vc.user_comments[i], - static_cast(vc.comment_lengths[i]) ); - - if(userComment.empty()) continue; - - szt equalPos = userComment.find('='); - if(equalPos == std::string::npos) continue; - - std::string tagName = userComment.substr(0, equalPos); - if(tagName.empty()) continue; - - std::string tagValue = userComment.substr(equalPos + 1); - if(tagValue.empty()) continue; - - /* Ogg tags should be uppercases but not all the softwares - * enforce it */ - for (auto& c: tagName) c = static_cast(toupper(c)); - - if(tagName == "ARTIST") - xTG.index_text(tagValue, 1, "A"); - else if (tagName == "DESCRIPTION") - xTG.index_text(tagValue, 1, "XD"); - else if (tagName == "TITLE") - xTG.index_text(tagValue, 1, "S"); - else if(tagName.find("COVERART") != tagName.npos) - continue; // Avoid polluting the index with binary data - else if (tagName.find("METADATA_BLOCK_PICTURE") != tagName.npos) - continue; // Avoid polluting the index with binary data - - // Index fields without prefixes for general search. - xTG.increase_termpos(); - xTG.index_text(userComment); - docData += userComment + "\n"; - } - xDoc.set_data(docData); - - ov_clear(&vf); - return 99; - } - - return 0; - } - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; diff --git a/libretroshare/src/deep_search/filestaglibindexer.hpp b/libretroshare/src/deep_search/filestaglibindexer.hpp deleted file mode 100644 index 341e9af38..000000000 --- a/libretroshare/src/deep_search/filestaglibindexer.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * RetroShare full text indexing and search implementation based on Xapian * - * * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * Copyright (C) 2019 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "deep_search/filesindex.hpp" -#include "util/rsdebug.h" - -#include -#include -#include -#include -#include -#include - -struct RsDeepTaglibFileIndexer -{ - RsDeepTaglibFileIndexer() - { - DeepFilesIndex::registerIndexer(40, indexFile); - } - - static uint32_t indexFile( - const std::string& path, const std::string& /*name*/, - Xapian::TermGenerator& xTG, Xapian::Document& xDoc ) - { - Dbg4() << __PRETTY_FUNCTION__ << " " << path << std::endl; - - TagLib::FileRef tFile(path.c_str()); - if(tFile.isNull()) return 0; - - const TagLib::Tag* tag = tFile.tag(); - if(!tag) return 0; - - TagLib::PropertyMap tMap = tag->properties(); - - unsigned validCommentsCnt = 0; - std::string docData = xDoc.get_data(); - for( TagLib::PropertyMap::ConstIterator mIt = tMap.begin(); - mIt != tMap.end(); ++mIt ) - { - if(mIt->first.isNull() || mIt->first.isEmpty()) continue; - std::string tagName(mIt->first.upper().to8Bit()); - - if(mIt->second.isEmpty()) continue; - std::string tagValue(mIt->second.toString(", ").to8Bit(true)); - if(tagValue.empty()) continue; - - if(tagName == "ARTIST") - xTG.index_text(tagValue, 1, "A"); - else if (tagName == "DESCRIPTION") - xTG.index_text(tagValue, 1, "XD"); - else if (tagName == "TITLE") - xTG.index_text(tagValue, 1, "S"); - else if(tagName.find("COVERART") != tagName.npos) - continue; // Avoid polluting the index with binary data - else if (tagName.find("METADATA_BLOCK_PICTURE") != tagName.npos) - continue; // Avoid polluting the index with binary data - - // Index fields without prefixes for general search. - xTG.increase_termpos(); - std::string fullComment(tagName + "=" + tagValue); - xTG.index_text(fullComment); - docData += fullComment + "\n"; - - Dbg2() << __PRETTY_FUNCTION__ << " Indexed " << tagName << "=\"" - << tagValue << '"' << std::endl; - - ++validCommentsCnt; - } - - if(validCommentsCnt > 0) - { - Dbg1() << __PRETTY_FUNCTION__ << " Successfully indexed: " << path - << std::endl; - - xDoc.set_data(docData); - return 99; - } - - /* Altought the file appears to be supported by taglib, no comments has - * been found so return less then 50 maybe another indexer is capable of - * extracting information */ - return 30; - } - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; diff --git a/libretroshare/src/dht/connectstatebox.cc b/libretroshare/src/dht/connectstatebox.cc deleted file mode 100644 index c1a0c4ff2..000000000 --- a/libretroshare/src/dht/connectstatebox.cc +++ /dev/null @@ -1,1049 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: connectstatebox.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "dht/connectstatebox.h" - -#include "util/rsrandom.h" -#include "util/rsstring.h" - -#include - -/** - * - * #define TESTING_PERIODS 1 - * #define DEBUG_CONNECTBOX 1 - * - **/ - - -/* Have made the PROXY Attempts + MAX_TIME much larger, - * have have potential for this to take a while. - */ - -#ifdef TESTING_PERIODS - #define FAILED_WAIT_TIME (1800) // 5 minutes. - #define TCP_WAIT_TIME (10) // 1/6 minutes. - #define DIRECT_MAX_WAIT_TIME (30) // 1/6 minutes. - #define PROXY_BASE_WAIT_TIME (10) // 30 // 1/6 minutes. - #define PROXY_MAX_WAIT_TIME (30) // 120 // 1/6 minutes. - #define RELAY_MAX_WAIT_TIME (30) // 1/6 minutes. - #define REVERSE_WAIT_TIME (30) // 1/2 minutes. - - #define MAX_DIRECT_ATTEMPTS (3) - #define MAX_PROXY_ATTEMPTS (3) - #define MAX_RELAY_ATTEMPTS (3) - - #define MAX_DIRECT_FAILED_ATTEMPTS (1) - #define MAX_PROXY_FAILED_ATTEMPTS (2) - #define MAX_RELAY_FAILED_ATTEMPTS (2) -#else - #define FAILED_WAIT_TIME (1800) // 30 minutes. - #define TCP_WAIT_TIME (60) // 1 minutes. - #define DIRECT_MAX_WAIT_TIME (60) // 1 minutes. - - #define PROXY_BASE_WAIT_TIME (30) // 1/2 minutes. - #define PROXY_MAX_WAIT_TIME (120) // 1 minutes. - - #define RELAY_MAX_WAIT_TIME (60) // 1 minutes. - #define REVERSE_WAIT_TIME (300) // 5 minutes. - - #define MAX_DIRECT_ATTEMPTS (5) - #define MAX_PROXY_ATTEMPTS (10) - #define MAX_RELAY_ATTEMPTS (5) - - #define MAX_DIRECT_FAILED_ATTEMPTS (3) - #define MAX_PROXY_FAILED_ATTEMPTS (3) - #define MAX_RELAY_FAILED_ATTEMPTS (3) - -#endif - -PeerConnectStateBox::PeerConnectStateBox() -{ - //mPeerId = id; - rstime_t now = time(NULL); - mState = CSB_START; - mNetState = CSB_NETSTATE_UNKNOWN; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - mNextAttemptTS = now; - mAttemptLength = 0; - mProxyPortFlags = 0; - mProxyPortChoice = false; - mProxyPortTS = 0; - - -} - - -std::string NetStateAsString(uint32_t netstate) -{ - std::string str; - switch(netstate) - { - case CSB_NETSTATE_FORWARD: - str = "Forwarded"; - break; - - case CSB_NETSTATE_STABLENAT: - str = "StableNat"; - break; - - case CSB_NETSTATE_EXCLUSIVENAT: - str = "ExclusiveNat"; - break; - - case CSB_NETSTATE_FIREWALLED: - str = "Firewalled"; - break; - default: - str = "Unknown NetState"; - break; - } - return str; -} - -std::string StateAsString(uint32_t state) -{ - std::string str; - switch(state) - { - case CSB_START: - str = "Start:"; - break; - - case CSB_TCP_WAIT: - str = "TCP Wait:"; - break; - - case CSB_DIRECT_ATTEMPT: - str = "Direct Attempt:"; - break; - - case CSB_DIRECT_WAIT: - str = "Direct Wait:"; - break; - - case CSB_PROXY_ATTEMPT: - str = "Proxy Attempt:"; - break; - - case CSB_PROXY_WAIT: - str = "Proxy Wait:"; - break; - - case CSB_RELAY_ATTEMPT: - str = "Relay Attempt:"; - break; - - case CSB_RELAY_WAIT: - str = "Relay Wait:"; - break; - - case CSB_REVERSE_WAIT: - str = "Reverse Wait:"; - break; - - case CSB_FAILED_WAIT: - str = "Failed Wait:"; - break; - - case CSB_CONNECTED: - str = "Connected:"; - break; - - default: - str = "Unknown State:"; - break; - } - - return str; -} - - -std::string UpdateAsString(uint32_t update) -{ - std::string str; - switch(update) - { - case CSB_UPDATE_NONE: - str = "none"; - break; - - case CSB_UPDATE_CONNECTED: - str = "Connected"; - break; - - case CSB_UPDATE_DISCONNECTED: - str = "Disconnected"; - break; - - case CSB_UPDATE_AUTH_DENIED: - str = "Auth Denied"; - break; - - case CSB_UPDATE_FAILED_ATTEMPT: - str = "Failed Attempt:"; - break; - - case CSB_UPDATE_MODE_UNAVAILABLE: - str = "Mode Unavailable:"; - break; - - default: - str = "Unknown Update"; - break; - } - return str; -} - -void PeerConnectStateBox::errorMsg(std::ostream &out, std::string msg, uint32_t updateParam) -{ - out << "PeerConnectStateBox::ERROR " << msg; - out << " NetState: " << NetStateAsString(mNetState); - out << " State: " << StateAsString(mState); - out << " Update: " << UpdateAsString(updateParam); - out << " for peer: " << mPeerId; - out << std::endl; -} - - -void PeerConnectStateBox::stateMsg(std::ostream &out, std::string msg, uint32_t updateParam) -{ - out << "PeerConnectStateBox::MSG " << msg; - out << " NetState: " << NetStateAsString(mNetState); - out << " State: " << StateAsString(mState); - out << " Update: " << UpdateAsString(updateParam); - out << " for peer: " << mPeerId; - out << std::endl; -} - -std::string PeerConnectStateBox::connectState() const -{ - std::string str = StateAsString(mState); - rstime_t now = time(NULL); - std::string out; - rs_sprintf(out, "%s(%lu/%lu) for %ld secs", str.c_str(), mNoAttempts, mNoFailedAttempts, now - mStateTS); - if ( (mState == CSB_CONNECTED) || (mState == CSB_DIRECT_ATTEMPT) || - (mState == CSB_PROXY_ATTEMPT) || (mState == CSB_RELAY_ATTEMPT) || - (mState == CSB_FAILED_WAIT) ) - { - rs_sprintf_append(out, " Last Attempt: %ld", mAttemptLength); - } - else - { - rs_sprintf_append(out, " LA: %ld", mAttemptLength); - rs_sprintf_append(out, " NextAttempt: %ld", mNextAttemptTS - now); - } - - return out; -} - - -uint32_t convertNetStateToInternal(RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype) -{ - uint32_t connNet = CSB_NETSTATE_UNKNOWN; - - if (netmode == RsNetworkMode::EXTERNALIP) - { - connNet = CSB_NETSTATE_FORWARD; - } - else if ((nathole != RsNatHoleMode::UNKNOWN) && (nathole != RsNatHoleMode::NONE)) - { - connNet = CSB_NETSTATE_FORWARD; - } - else if (netmode == RsNetworkMode::BEHINDNAT) - { - if ((nattype == RsNatTypeMode::RESTRICTED_CONE) || - (nattype == RsNatTypeMode::FULL_CONE)) - { - connNet = CSB_NETSTATE_STABLENAT; - } - else if (nattype == RsNatTypeMode::DETERM_SYM) - { - connNet = CSB_NETSTATE_EXCLUSIVENAT; - } - else - { - connNet = CSB_NETSTATE_FIREWALLED; - } - } - return connNet; -} - -bool shouldUseProxyPortInternal(uint32_t netstate) -{ - if (netstate == CSB_NETSTATE_FORWARD) - { - return false; - } - return true; -} - -bool PeerConnectStateBox::shouldUseProxyPort(RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype) -{ - uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype); - return shouldUseProxyPortInternal(netstate); -} - -uint32_t PeerConnectStateBox::calcNetState(RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype) -{ - uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype); - return netstate; -} - - -uint32_t PeerConnectStateBox::connectCb(uint32_t cbtype, RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype) -{ - uint32_t netstate = convertNetStateToInternal(netmode, nathole, nattype); - -#ifdef DEBUG_CONNECTBOX - std::cerr << "PeerConnectStateBox::connectCb("; - if (cbtype == CSB_CONNECT_DIRECT) - { - std::cerr << "DIRECT"; - } - else - { - std::cerr << "UNREACHABLE"; - } - std::cerr << "," << NetStateAsString(netstate) << ")"; - std::cerr << std::endl; -#endif - - if (netstate != mNetState) - { -#ifdef DEBUG_CONNECTBOX - std::cerr << "PeerConnectStateBox::connectCb() WARNING Changing NetState from: "; - std::cerr << " from: " << NetStateAsString(mNetState); - std::cerr << " to: " << NetStateAsString(netstate); - std::cerr << " for peer: " << mPeerId; - std::cerr << std::endl; -#endif - - mNetState = netstate; - } - - if (cbtype == CSB_CONNECT_DIRECT) - { - return connectCb_direct(); - } - else - { - return connectCb_unreachable(); - } -} - - -uint32_t PeerConnectStateBox::connectCb_direct() -{ - uint32_t retval = 0; - rstime_t now = time(NULL); - - switch(mState) - { - - case CSB_DIRECT_ATTEMPT: - { - errorMsg(std::cerr, "mState == DIRECT_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_PROXY_ATTEMPT: - { - errorMsg(std::cerr, "mState == PROXY_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_RELAY_ATTEMPT: - { - errorMsg(std::cerr, "mState == RELAY_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_FAILED_WAIT: - { - /* if too soon */ - //if (now - mStateTS < FAILED_WAIT_TIME) - if (mNextAttemptTS > now) - { - /* same state */ - retval = CSB_ACTION_WAIT; - break; - } - } /* FALLTHROUGH TO START CASE */ - /* fallthrough */ - default: - case CSB_REVERSE_WAIT: - case CSB_PROXY_WAIT: - case CSB_RELAY_WAIT: - { - if (mState != CSB_FAILED_WAIT) - { - /* ERROR */ - errorMsg(std::cerr, "mState != FAILED_WAIT", 0); - - } - - } /* FALLTHROUGH TO START CASE */ - /* fallthrough */ - case CSB_START: - { - /* starting up the connection */ - mState = CSB_TCP_WAIT; - retval = CSB_ACTION_TCP_CONN; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - mNextAttemptTS = now + TCP_WAIT_TIME; - - } - break; - case CSB_TCP_WAIT: - { - /* if too soon */ - //if (now - mStateTS < TCP_WAIT_TIME) - if (mNextAttemptTS > now) - { - /* same state */ - retval = CSB_ACTION_WAIT; - } - else - { - /* try again */ - mState = CSB_DIRECT_ATTEMPT; - retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - } - } - break; - - case CSB_DIRECT_WAIT: - { - /* if too soon */ - //if (now - mStateTS < DIRECT_WAIT_TIME) - if (mNextAttemptTS > now) - { - /* same state */ - retval = CSB_ACTION_WAIT; - } - else if ((mNoAttempts >= MAX_DIRECT_ATTEMPTS) || - (mNoFailedAttempts >= MAX_DIRECT_FAILED_ATTEMPTS)) - { - /* if too many attempts */ - /* no RELAY attempt => FAILED_WAIT */ - mState = CSB_FAILED_WAIT; - retval = CSB_ACTION_WAIT; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - mNextAttemptTS = now + FAILED_WAIT_TIME; - } - else - { - /* try again */ - mState = CSB_DIRECT_ATTEMPT; - retval = CSB_ACTION_DIRECT_CONN | CSB_ACTION_DHT_PORT; - mStateTS = now; - mNoAttempts++; - } - } - break; - - case CSB_CONNECTED: - { - retval = CSB_ACTION_WAIT; - } - break; - } - - return retval; - -} - - -uint32_t PeerConnectStateBox::connectCb_unreachable() -{ - uint32_t retval = 0; - - uint32_t proxyPortMode = CSB_ACTION_PROXY_PORT; - if (!shouldUseProxyPortInternal(mNetState)) - { - proxyPortMode = CSB_ACTION_DHT_PORT; - } - - rstime_t now = time(NULL); - - switch(mState) - { - case CSB_DIRECT_ATTEMPT: - { - errorMsg(std::cerr, "mState == DIRECT_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_PROXY_ATTEMPT: - { - errorMsg(std::cerr, "mState == PROXY_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_RELAY_ATTEMPT: - { - errorMsg(std::cerr, "mState == RELAY_ATTEMPT", 0); - retval = CSB_ACTION_WAIT; - } - break; - - case CSB_FAILED_WAIT: - { - /* if too soon */ - //if (now - mStateTS < FAILED_WAIT_TIME) - if (mNextAttemptTS > now) - { - /* same state */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too soon, no action", 0); -#endif - retval = CSB_ACTION_WAIT; - break; - } - } /* FALLTHROUGH TO START CASE */ - /* fallthrough */ - default: - case CSB_DIRECT_WAIT: - { - if (mState != CSB_FAILED_WAIT) - { - /* ERROR */ - errorMsg(std::cerr, "mState != FAILED_WAIT", 0); - - } - - } /* FALLTHROUGH TO START CASE */ - /* fallthrough */ - case CSB_START: - { - /* starting up the connection */ - mState = CSB_TCP_WAIT; - retval = CSB_ACTION_WAIT; /* NO POINT TRYING A TCP_CONN */ - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - mNextAttemptTS = now + TCP_WAIT_TIME; - - } - break; - case CSB_TCP_WAIT: - { - /* if too soon */ - if (mNextAttemptTS > now) - { - /* same state */ - retval = CSB_ACTION_WAIT; - } - else - { - /* starting up the connection */ - if (mState != CSB_NETSTATE_FIREWALLED) - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "not Firewalled => PROXY_ATTEMPT", 0); -#endif - mState = CSB_PROXY_ATTEMPT; - retval = CSB_ACTION_PROXY_CONN | proxyPortMode; - } - else - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "Firewalled => RELAY_ATTEMPT", 0); -#endif - mState = CSB_RELAY_ATTEMPT; - retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT; - - } - - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - } - - } - break; - case CSB_PROXY_WAIT: - { - /* if too soon */ - if (mNextAttemptTS > now) - { - /* same state */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too soon, no action", 0); -#endif - retval = CSB_ACTION_WAIT; - } - else if ((mNoAttempts >= MAX_PROXY_ATTEMPTS) || - (mNoFailedAttempts >= MAX_PROXY_FAILED_ATTEMPTS)) - { - /* if too many attempts */ - /* switch to RELAY attempt */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too many PROXY => RELAY_ATTEMPT", 0); -#endif - mState = CSB_RELAY_ATTEMPT; - retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - } - else - { - /* try again */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "PROXY_ATTEMPT try again", 0); -#endif - mState = CSB_PROXY_ATTEMPT; - retval = CSB_ACTION_PROXY_CONN | proxyPortMode; - mStateTS = now; - mNoAttempts++; - } - } - break; - - case CSB_REVERSE_WAIT: - { - /* if too soon */ - //if (now - mStateTS < REVERSE_WAIT_TIME) - if (mNextAttemptTS > now) - { - /* same state */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too soon, no action", 0); -#endif - retval = CSB_ACTION_WAIT; - } - else - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "timeout => RELAY_ATTEMPT", 0); -#endif - /* switch to RELAY attempt */ - mState = CSB_RELAY_ATTEMPT; - retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - } - } - break; - - case CSB_RELAY_WAIT: - { - /* if too soon */ - if (mNextAttemptTS > now) - { - /* same state */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too soon, no action", 0); -#endif - retval = CSB_ACTION_WAIT; - } - else if ((mNoAttempts >= MAX_RELAY_ATTEMPTS) || - (mNoFailedAttempts >= MAX_RELAY_FAILED_ATTEMPTS)) - { - /* if too many attempts */ - /* switch to RELAY attempt */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "too many RELAY => FAILED_WAIT", 0); -#endif - mState = CSB_FAILED_WAIT; - retval = CSB_ACTION_WAIT; - mStateTS = now; - mNoAttempts = 0; - mNoFailedAttempts = 0; - mNextAttemptTS = now + FAILED_WAIT_TIME; - } - else - { - /* try again */ -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "RELAY_ATTEMPT try again", 0); -#endif - mState = CSB_RELAY_ATTEMPT; - retval = CSB_ACTION_RELAY_CONN | CSB_ACTION_DHT_PORT; - mStateTS = now; - mNoAttempts++; - } - } - break; - - case CSB_CONNECTED: - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "connected => no action", 0); -#endif - retval = CSB_ACTION_WAIT; - } - break; - } - - return retval; -} - - - -uint32_t PeerConnectStateBox::updateCb(uint32_t update) -{ - /* The Error Callback doesn't trigger another connection. - * but can change the connection state - * - * Possible Errors: - * 1) AUTH DENIED. (fatal) - * 2) MODE UNAVILABLE - * 3) RETRY ATTEMPT - * 4) FAILED ATTEMPT - * 5) CONNECTION - * 6) DISCONNECTED. - * - * Fitting these into the states: - case CSB_START: - CONNECTION => CSB_CONNECTED - error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - case CSB_CONNECTED: - CONNECTION => CSB_CONNECTED - DISCONNECTED => CSB_START - error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT - - case CSB_FAILED_WAIT: - CONNECTION => CSB_CONNECTED - error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - case CSB_REVERSE_WAIT: - CONNECTION => CSB_CONNECTED - error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - case CSB_DIRECT_ATTEMPT: - CONNECTION => CSB_CONNECTED - AUTH DENIED => CSB_FAILED_WAIT - FAILED ATTEMPT => stay here. - RETRY ATTEMPT => stay here - MODE UNAVAILABLE - probably error => CSB_FAILED_WAIT - error if: MODE UNAVAILABLE, DISCONNECTED - - case CSB_PROXY_ATTEMPT: - CONNECTION => CSB_CONNECTED - AUTH DENIED => CSB_FAILED_WAIT - FAILED ATTEMPT => stay here. - RETRY ATTEMPT => stay here - MODE_UNAVAILABLE => CSB_REVERSE_WAIT | CSB_RELAY_ATTEMPT - error if: DISCONNECTED - - case CSB_RELAY_ATTEMPT: - CONNECTION => CSB_CONNECTED - AUTH DENIED => CSB_FAILED_WAIT - FAILED ATTEMPT => stay here. - RETRY ATTEMPT => stay here - MODE_UNAVAILABLE => CSB_FAILED_WAIT - error if: DISCONNECTED - - case CSB_DIRECT_WAIT: - CONNECTION => CSB_CONNECTED - error if: AUTH DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - case CSB_PROXY_WAIT: - CONNECTION => CSB_CONNECTED - error if: AUTH_DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - case CSB_RELAY_ATTEMPT: - CONNECTION => CSB_CONNECTED - error if: AUTH_DENIED, MODE UNAVAILABLE, FAILED ATTEMPT, RETRY ATTEMPT, DISCONNECTED - */ - - /* DO Connect / Disconnect Updates ... very specific! */ - rstime_t now = time(NULL); - switch(update) - { - case CSB_UPDATE_CONNECTED: - { - if ((mState == CSB_DIRECT_ATTEMPT) || (mState == CSB_PROXY_ATTEMPT) || (mState == CSB_RELAY_ATTEMPT)) - { - mAttemptLength = now - mStateTS; - } - else - { - mAttemptLength = 0; - } - -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "=> CONNECTED", update); -#endif - mState = CSB_CONNECTED; - mStateTS = now; - - return 0; - } - break; - case CSB_UPDATE_DISCONNECTED: - { - if (mState != CSB_CONNECTED) - { - /* ERROR, ignore (as already in disconnected state) */ - errorMsg(std::cerr, "mState != CSB_CONNECTED", update); - - } - else - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "=> START", update); -#endif - /* move to START state */ - mState = CSB_START; - mStateTS = now; - return 1; - } - - return 0; - } - break; - } - - - /* Now catch errors for feedback when we should be WAITING */ - switch(mState) - { - default: - case CSB_DIRECT_WAIT: - case CSB_PROXY_WAIT: - case CSB_RELAY_WAIT: - case CSB_REVERSE_WAIT: - case CSB_FAILED_WAIT: - case CSB_START: - case CSB_CONNECTED: /* impossible */ - { - /* ERROR */ - /* shouldn't receive anything here! */ - errorMsg(std::cerr, "shouldnt get anything", update); - - return 0; - } - break; - - case CSB_DIRECT_ATTEMPT: - case CSB_PROXY_ATTEMPT: - case CSB_RELAY_ATTEMPT: - { - /* OKAY */ - - } - break; - } - - - switch(update) - { - /* if AUTH_DENIED ... => FAILED_WAIT */ - case CSB_UPDATE_AUTH_DENIED: - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "=> FAILED WAIT", update); -#endif - mState = CSB_FAILED_WAIT; - mStateTS = now; - mAttemptLength = now - mStateTS; - mNextAttemptTS = now + FAILED_WAIT_TIME; - - return 1; - } - break; - /* if standard FAIL => stay where we are */ - case CSB_UPDATE_RETRY_ATTEMPT: - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "RETRY FAIL => switch to wait state", update); -#endif - mAttemptLength = now - mStateTS; - switch(mState) - { - case CSB_DIRECT_ATTEMPT: - mState = CSB_DIRECT_WAIT; - mStateTS = now; - mNextAttemptTS = now + RSRandom::random_u32() % DIRECT_MAX_WAIT_TIME; - break; - case CSB_PROXY_ATTEMPT: - mState = CSB_PROXY_WAIT; - mStateTS = now; - mNextAttemptTS = now + PROXY_BASE_WAIT_TIME + (RSRandom::random_u32() % (PROXY_MAX_WAIT_TIME - PROXY_BASE_WAIT_TIME)); - break; - case CSB_RELAY_ATTEMPT: - mState = CSB_RELAY_WAIT; - mStateTS = now; - mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME; - break; - default: -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "RETRY FAIL, but unusual state", update); -#endif - break; - } - - return 1; - } - /* if standard FAIL => stay where we are */ - case CSB_UPDATE_FAILED_ATTEMPT: - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "STANDARD FAIL => switch to wait state", update); -#endif - mNoFailedAttempts++; - mAttemptLength = now - mStateTS; - switch(mState) - { - case CSB_DIRECT_ATTEMPT: - mState = CSB_DIRECT_WAIT; - mStateTS = now; - mNextAttemptTS = now + RSRandom::random_u32() % DIRECT_MAX_WAIT_TIME; - break; - case CSB_PROXY_ATTEMPT: - mState = CSB_PROXY_WAIT; - mStateTS = now; - mNextAttemptTS = now + PROXY_BASE_WAIT_TIME + (RSRandom::random_u32() % (PROXY_MAX_WAIT_TIME - PROXY_BASE_WAIT_TIME)); - break; - case CSB_RELAY_ATTEMPT: - mState = CSB_RELAY_WAIT; - mStateTS = now; - mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME; - break; - default: -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "STANDARD FAIL, but unusual state", update); -#endif - break; - } - - return 1; - } - break; - - /* finally MODE_UNAVAILABLE */ - case CSB_UPDATE_MODE_UNAVAILABLE: - { - mAttemptLength = now - mStateTS; - if (mState == CSB_PROXY_ATTEMPT) - { - if (mNetState == CSB_NETSTATE_FORWARD) - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "as FORWARDED => REVERSE_WAIT", update); -#endif - mState = CSB_REVERSE_WAIT; - mStateTS = now; - mNextAttemptTS = now + REVERSE_WAIT_TIME; - } - else - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "as !FORWARDED => RELAY_ATTEMPT", update); -#endif - mState = CSB_RELAY_WAIT; - mNoAttempts = 0; - mStateTS = now; - mNextAttemptTS = now + RSRandom::random_u32() % RELAY_MAX_WAIT_TIME; - } - return 1; - } - else - { -#ifdef DEBUG_CONNECTBOX - stateMsg(std::cerr, "MODE UNAVAIL => FAILED_WAIT", update); -#endif - mState = CSB_FAILED_WAIT; - mStateTS = now; - mNextAttemptTS = now + FAILED_WAIT_TIME; - - if ((mState == CSB_DIRECT_ATTEMPT) - || (mState == CSB_PROXY_ATTEMPT)) - { - /* OKAY */ - return 1; - } - else - { - /* ERROR */ - errorMsg(std::cerr, "strange MODE", update); - - return 0; - } - } - } - break; - - default: - { - /* ERROR */ - errorMsg(std::cerr, "impossible default", update); - } - break; - } - - /* if we get here... ERROR */ - errorMsg(std::cerr, "if we get here => ERROR", update); - - - return 0; -} - - - - - - - - - - -bool PeerConnectStateBox::storeProxyPortChoice(uint32_t flags, bool useProxyPort) -{ - mProxyPortFlags = flags; - mProxyPortChoice = useProxyPort; - mProxyPortTS = time(NULL); - - return useProxyPort; -} - -bool PeerConnectStateBox::getProxyPortChoice() -{ -#ifdef DEBUG_CONNECTBOX - rstime_t now = time(NULL); - - std::cerr << "PeerConnectStateBox::getProxyPortChoice() Using ConnectLogic Info from: "; - std::cerr << now-mProxyPortTS << " ago. Flags: " << mProxyPortFlags; - std::cerr << " UseProxyPort? " << mProxyPortChoice; - std::cerr << std::endl; -#endif - - return mProxyPortChoice; -} - - - diff --git a/libretroshare/src/dht/connectstatebox.h b/libretroshare/src/dht/connectstatebox.h deleted file mode 100644 index 20c6fdb20..000000000 --- a/libretroshare/src/dht/connectstatebox.h +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: connectstatebox.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef CONNECT_STATUS_BOX_H -#define CONNECT_STATUS_BOX_H - -/* a connect state box */ - -#define CSB_START 1 -#define CSB_TCP_WAIT 2 -#define CSB_DIRECT_ATTEMPT 3 -#define CSB_DIRECT_WAIT 4 -#define CSB_PROXY_ATTEMPT 5 -#define CSB_PROXY_WAIT 6 -#define CSB_RELAY_ATTEMPT 7 -#define CSB_RELAY_WAIT 8 -#define CSB_REVERSE_WAIT 9 -#define CSB_FAILED_WAIT 10 -#define CSB_CONNECTED 11 - - -#define CSB_NETSTATE_UNKNOWN 0 -#define CSB_NETSTATE_FORWARD 1 -#define CSB_NETSTATE_STABLENAT 2 -#define CSB_NETSTATE_EXCLUSIVENAT 3 -#define CSB_NETSTATE_FIREWALLED 4 - -#define CSB_CONNECT_DIRECT 1 -#define CSB_CONNECT_UNREACHABLE 2 - -/* return values */ -#define CSB_ACTION_MASK_MODE 0x00ff -#define CSB_ACTION_MASK_PORT 0xff00 - -#define CSB_ACTION_WAIT 0x0001 -#define CSB_ACTION_TCP_CONN 0x0002 -#define CSB_ACTION_DIRECT_CONN 0x0004 -#define CSB_ACTION_PROXY_CONN 0x0008 -#define CSB_ACTION_RELAY_CONN 0x0010 - -#define CSB_ACTION_DHT_PORT 0x0100 -#define CSB_ACTION_PROXY_PORT 0x0200 - -/* update input */ -#define CSB_UPDATE_NONE 0x0000 -#define CSB_UPDATE_CONNECTED 0x0001 -#define CSB_UPDATE_DISCONNECTED 0x0002 -#define CSB_UPDATE_AUTH_DENIED 0x0003 -#define CSB_UPDATE_RETRY_ATTEMPT 0x0004 -#define CSB_UPDATE_FAILED_ATTEMPT 0x0005 -#define CSB_UPDATE_MODE_UNAVAILABLE 0x0006 - -#include -#include - -#include -#include "util/rstime.h" -#include - -#include - -class PeerConnectStateBox -{ - public: - PeerConnectStateBox(); - - uint32_t connectCb(uint32_t cbtype, RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype); - uint32_t updateCb(uint32_t updateType); - - bool shouldUseProxyPort(RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype); - - uint32_t calcNetState(RsNetworkMode netmode, RsNatHoleMode nathole, RsNatTypeMode nattype); - std::string connectState() const; - - std::string mPeerId; - - bool storeProxyPortChoice(uint32_t flags, bool useProxyPort); - bool getProxyPortChoice(); - - private: - - uint32_t connectCb_direct(); - uint32_t connectCb_unreachable(); - - void errorMsg(std::ostream &out, std::string msg, uint32_t updateParam); - void stateMsg(std::ostream &out, std::string msg, uint32_t updateParam); - - - uint32_t mState; - uint32_t mNetState; - rstime_t mStateTS; - uint32_t mNoAttempts; - uint32_t mNoFailedAttempts; - rstime_t mNextAttemptTS; - rstime_t mAttemptLength; - - // ProxyPort Storage. - uint32_t mProxyPortFlags; - bool mProxyPortChoice; - rstime_t mProxyPortTS; -}; - - -#endif diff --git a/libretroshare/src/dht/p3bitdht.cc b/libretroshare/src/dht/p3bitdht.cc deleted file mode 100644 index 9e4798066..000000000 --- a/libretroshare/src/dht/p3bitdht.cc +++ /dev/null @@ -1,460 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#include "dht/p3bitdht.h" - -#include "bitdht/bdstddht.h" - -#include "tcponudp/udprelay.h" -#ifdef RS_USE_DHT_STUNNER -#include "tcponudp/udpstunner.h" -#endif // RS_USE_DHT_STUNNER - -#include "retroshare/rsbanlist.h" - -#include - - -/* This is a conversion callback class between pqi interface - * and the BitDht Interface. - * - */ - -/**** EXTERNAL INTERFACE DHT POINTER *****/ -RsDht *rsDht = NULL; - -class p3BdCallback: public BitDhtCallback -{ - public: - - p3BdCallback(p3BitDht *parent) - :mParent(parent) { return; } - -virtual int dhtNodeCallback(const bdId *id, uint32_t peerflags) -{ - return mParent->NodeCallback(id, peerflags); -} - -virtual int dhtPeerCallback(const bdId *id, uint32_t status) -{ - return mParent->PeerCallback(id, status); -} - -virtual int dhtValueCallback(const bdNodeId *id, std::string key, uint32_t status) -{ - return mParent->ValueCallback(id, key, status); -} - -virtual int dhtConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) -{ - return mParent->ConnectCallback(srcId, proxyId, destId, mode, point, param, cbtype, errcode); -} - -virtual int dhtInfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info) -{ - return mParent->InfoCallback(id, type, flags, info); -} - - virtual int dhtIsBannedCallback(const sockaddr_in *addr, bool *isBanned) - { - if(!rsBanList) - { - *isBanned = true; // rsBanList is not enabled yet. For security, default to banned. - return 0; - } - - // check whether ip filtering is enabled - // if not return 0 to signal that no filter is available - if(!rsBanList->ipFilteringEnabled()) - return 0; - - // now check the filter - if(rsBanList->isAddressAccepted( - *reinterpret_cast(addr), - RSBANLIST_CHECKING_FLAGS_BLACKLIST )) - { - *isBanned = false; - } else { -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht dhtIsBannedCallback: peer is banned " << sockaddr_storage_tostring(*(const sockaddr_storage*)addr) << std::endl; -#endif - *isBanned = true; - } - - // return 1 to signal that a filter is available - return 1; - } - - private: - - p3BitDht *mParent; -}; - - -p3BitDht::p3BitDht(const RsPeerId& id, pqiConnectCb *cb, p3NetMgr *nm, - UdpStack *udpstack, std::string bootstrapfile, std::string bootstrapfilebak, const std::string& filteredipfile) - :p3Config(), pqiNetAssistConnect(id, cb), mNetMgr(nm), dhtMtx("p3BitDht") -{ -#ifdef RS_USE_DHT_STUNNER - mDhtStunner = NULL; - mProxyStunner = NULL; -#endif - mRelay = NULL; - - mPeerSharer = NULL; - - mRelayHandler = NULL; - - std::string dhtVersion = "RS51"; // should come from elsewhere! - mOwnRsId = id; - - mMinuteTS = 0; - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::p3BitDht()" << std::endl; - std::cerr << "Using Id: " << id; - std::cerr << std::endl; - std::cerr << "Using Bootstrap File: " << bootstrapfile; - std::cerr << std::endl; - std::cerr << "Converting OwnId to bdNodeId...."; - std::cerr << std::endl; -#endif - - /* setup ownId */ - storeTranslation_locked(id); - lookupNodeId_locked(id, &mOwnDhtId); - - -#ifdef DEBUG_BITDHT - std::cerr << "Own NodeId: "; - bdStdPrintNodeId(std::cerr, &mOwnDhtId); - std::cerr << std::endl; -#endif - - /* standard dht behaviour */ - //bdDhtFunctions *stdfns = new bdStdDht(); - mDhtFns = new bdModDht(); - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht() startup ... creating UdpBitDht"; - std::cerr << std::endl; -#endif - - /* create dht */ - mUdpBitDht = new UdpBitDht(udpstack, &mOwnDhtId, dhtVersion, bootstrapfile, bootstrapfilebak, filteredipfile,mDhtFns); - udpstack->addReceiver(mUdpBitDht); - - /* setup callback to here */ - p3BdCallback *bdcb = new p3BdCallback(this); - mUdpBitDht->addCallback(bdcb); - -#if 0 - /* enable all modes */ - /* Switched to only Proxy Mode - as Direct Connections can be unreliable - as they share the UDP with the DHT.... - * We'll get these working properly and then if necessary get Direct further tested. - */ - mUdpBitDht->ConnectionOptions( - // BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY | BITDHT_CONNECT_MODE_RELAY, - //BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY, - BITDHT_CONNECT_MODE_PROXY, - BITDHT_CONNECT_OPTION_AUTOPROXY); - -#endif - - setupRelayDefaults(); - - clearDataRates(); -} - -p3BitDht::~p3BitDht() -{ - //udpstack->removeReceiver(mUdpBitDht); - delete mUdpBitDht; -} - - -bool p3BitDht::getOwnDhtId(std::string &ownDhtId) -{ - bdStdPrintNodeId(ownDhtId, &(mOwnDhtId), false); - return true; -} - -#ifdef RS_USE_DHT_STUNNER -void p3BitDht::setupConnectBits(UdpStunner *dhtStunner, UdpStunner *proxyStunner, UdpRelayReceiver *relay) -{ - mDhtStunner = dhtStunner; - mProxyStunner = proxyStunner; - mRelay = relay; -} -#else // RS_USE_DHT_STUNNER -void p3BitDht::setupConnectBits(UdpRelayReceiver *relay) -{ - mRelay = relay; -} -#endif //RS_USE_DHT_STUNNER - -void p3BitDht::setupPeerSharer(pqiNetAssistPeerShare *sharer) -{ - mPeerSharer = sharer; -} - - /* Tweak the DHT Parameters */ -void p3BitDht::modifyNodesPerBucket(uint16_t count) -{ - bdModDht *modFns = (bdModDht *) mDhtFns; - modFns->setNodesPerBucket(count); -} - -/* Support for Outsourced Relay Handling */ - -void p3BitDht::installRelayHandler(p3BitDhtRelayHandler *handler) -{ - /* The Handler is mutex protected, as its installation can occur when the dht is already running */ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - mRelayHandler = handler; -} - -UdpRelayReceiver *p3BitDht::getRelayReceiver() -{ - return mRelay; -} - - -void p3BitDht::start() -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::start()"; - std::cerr << std::endl; -#endif - - mUdpBitDht->start(); /* starts up the bitdht thread */ - - /* dht switched on by config later. */ -} - - /* pqiNetAssist - external interface functions */ -void p3BitDht::enable(bool on) -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::enable(" << on << ")"; - std::cerr << std::endl; -#endif - - if (on) - { - mUdpBitDht->startDht(); - } - else - { - mUdpBitDht->stopDht(); - } -} - -void p3BitDht::shutdown() /* blocking call */ -{ - mUdpBitDht->stopDht(); -} - - -void p3BitDht::restart() -{ - mUdpBitDht->stopDht(); - mUdpBitDht->startDht(); -} - -bool p3BitDht::getEnabled() -{ - return (mUdpBitDht->stateDht() != 0); -} - -bool p3BitDht::getActive() -{ - return (mUdpBitDht->stateDht() >= BITDHT_MGR_STATE_ACTIVE); -} - -bool p3BitDht::getNetworkStats(uint32_t &netsize, uint32_t &localnetsize) -{ - netsize = mUdpBitDht->statsNetworkSize(); - localnetsize = mUdpBitDht->statsBDVersionSize(); - return true; -} - -#if 0 - /* pqiNetAssistConnect - external interface functions */ - /* add / remove peers */ -bool p3BitDht::findPeer(std::string pid) -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer(" << pid << ")"; - std::cerr << std::endl; -#endif - - /* convert id -> NodeId */ - if (!storeTranslation(pid)) - { - std::cerr << "p3BitDht::findPeer() Failed to storeTranslation"; - std::cerr << std::endl; - - /* error */ - return false; - } - - bdNodeId nid; - if (!lookupNodeId(pid, &nid)) - { - std::cerr << "p3BitDht::findPeer() Failed to lookupNodeId"; - std::cerr << std::endl; - - /* error */ - return false; - } - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() calling AddFindNode() with pid => NodeId: "; - bdStdPrintNodeId(std::cerr, &nid); - std::cerr << std::endl; -#endif - - /* add in peer */ - mUdpBitDht->addFindNode(&nid, BITDHT_QFLAGS_DO_IDLE); - - return true ; -} - -bool p3BitDht::dropPeer(std::string pid) -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::dropPeer(" << pid << ")"; - std::cerr << std::endl; -#endif - - /* convert id -> NodeId */ - bdNodeId nid; - if (!lookupNodeId(pid, &nid)) - { - std::cerr << "p3BitDht::dropPeer() Failed to lookup NodeId"; - std::cerr << std::endl; - - /* error */ - return false; - } - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::dropPeer() Translated to NodeId: "; - bdStdPrintNodeId(std::cerr, &nid); - std::cerr << std::endl; -#endif - - /* remove in peer */ - mUdpBitDht->removeFindNode(&nid); - - /* remove from translation */ - if (!removeTranslation(pid)) - { - std::cerr << "p3BitDht::dropPeer() Failed to removeTranslation"; - std::cerr << std::endl; - - /* error */ - return false; - } - - return true ; -} - -#endif - - - /* extract current peer status */ -bool p3BitDht::getPeerStatus(const RsPeerId& id, - struct sockaddr_storage &/*laddr*/, struct sockaddr_storage &/*raddr*/, - uint32_t &/*type*/, uint32_t &/*mode*/) -{ - /* remove unused parameter warnings */ - (void) id; - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::getPeerStatus(" << id << ")"; - std::cerr << std::endl; -#endif - - return false; -} - -bool p3BitDht::getExternalInterface(struct sockaddr_storage &/*raddr*/, - uint32_t &/*mode*/) -{ - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::getExternalInterface()"; - std::cerr << std::endl; -#endif - - - return false; -} - -bool p3BitDht::isAddressBanned(const sockaddr_storage &raddr) -{ - if(raddr.ss_family == AF_INET6) // the DHT does not handle INET6 addresses yet. - return false ; - - if(raddr.ss_family == AF_INET) - return mUdpBitDht->isAddressBanned((sockaddr_in&)raddr) ; - - return false ; -} - -void p3BitDht::getListOfBannedIps(std::list& ips) -{ - std::list lst ; - - mUdpBitDht->getListOfBannedIps(lst) ; - - for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) - { - RsDhtFilteredPeer fp ; - fp.mAddr = (*it).mAddr ; - fp.mFilterFlags = (*it).mFilterFlags ; - fp.mFilterTS = (*it).mFilterTS ; - fp.mLastSeen = (*it).mLastSeen ; - ips.push_back(fp) ; - } -} - -bool p3BitDht::setAttachMode(bool on) -{ - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::setAttachMode(" << on << ")"; - std::cerr << std::endl; -#endif - - return mUdpBitDht->setAttachMode(on); -} - - - - diff --git a/libretroshare/src/dht/p3bitdht.h b/libretroshare/src/dht/p3bitdht.h deleted file mode 100644 index 26cb43847..000000000 --- a/libretroshare/src/dht/p3bitdht.h +++ /dev/null @@ -1,398 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef MRK_P3_BITDHT_H -#define MRK_P3_BITDHT_H - -#include "pqi/pqiassist.h" -#include "pqi/p3cfgmgr.h" -#include "retroshare/rsdht.h" - -#include -#include -#include "pqi/pqinetwork.h" -#include "pqi/pqimonitor.h" -#include "util/rsthreads.h" - -#include "udp/udpstack.h" -#include "udp/udpbitdht.h" -#include "bitdht/bdiface.h" - -#include "dht/connectstatebox.h" - -class DhtPeerDetails -{ - public: - - DhtPeerDetails(); - - RsDhtPeerType mPeerType; - - bdId mDhtId; - RsPeerId mRsId; - - /* direct from the DHT! */ - RsDhtPeerDht mDhtState; - rstime_t mDhtUpdateTS; - - /* internal state */ - PeerConnectStateBox mConnectLogic; - - /* Actual Connection Status */ - RsDhtPeerConnectState mPeerConnectState; - std::string mPeerConnectMsg; - uint32_t mPeerConnectMode; - bdId mPeerConnectPeerId; - bdId mPeerConnectProxyId; - struct sockaddr_in mPeerConnectAddr; - uint32_t mPeerConnectPoint; - - rstime_t mPeerConnectUdpTS; - rstime_t mPeerConnectTS; - rstime_t mPeerConnectClosedTS; - - bool mExclusiveProxyLock; - - /* keeping the PeerCbMsg, as we will need it for debugging */ - /* don't think this data is ever used for decisions??? */ - - /* Connection Request Status */ - std::string mPeerReqStatusMsg; - RsDhtPeerRequest mPeerReqState; - uint32_t mPeerReqMode; - bdId mPeerReqProxyId; - rstime_t mPeerReqTS; - - /* Callback Info */ - std::string mPeerCbMsg; - uint32_t mPeerCbMode; - uint32_t mPeerCbPoint; - bdId mPeerCbProxyId; - bdId mPeerCbDestId; - rstime_t mPeerCbTS; - -}; - -#define PEERNET_ACTION_TYPE_CONNECT 1 -#define PEERNET_ACTION_TYPE_AUTHORISE 2 -#define PEERNET_ACTION_TYPE_START 3 -#define PEERNET_ACTION_TYPE_RESTARTREQ 4 -#define PEERNET_ACTION_TYPE_KILLREQ 5 -#define PEERNET_ACTION_TYPE_TCPATTEMPT 6 - -class PeerAction -{ - public: - - uint32_t mType; - bdId mSrcId; - bdId mProxyId; - bdId mDestId; - uint32_t mMode; - uint32_t mPoint; - uint32_t mAnswer; - uint32_t mDelayOrBandwidth; -}; - - - -/****** - * Adding the ability to install alternative Handler - * for monitoring/controlling Relay Connections outside of p3bitdht. - ***/ - -class p3BitDhtRelayHandler -{ - public: - - int (*mInstallRelay)(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t &bandwidth); - int (*mLogFailedConnection)(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode); -}; - - - - -class UdpRelayReceiver; -#ifdef RS_USE_DHT_STUNNER -class UdpStunner; -#endif // RS_USE_DHT_STUNNER -class p3NetMgr; - -class p3BitDht: public p3Config, public pqiNetAssistConnect, public RsDht -{ -public: - p3BitDht(const RsPeerId& id, pqiConnectCb *cb, p3NetMgr *nm, - UdpStack *udpstack, std::string bootstrapfile, std::string bootstrapfilebak, const std::string &filteredipfile); - - - virtual ~p3BitDht(); - - - /*********************************************************************************************** - ********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) ********* -************************************************************************************************/ - - virtual uint32_t getNetState(uint32_t type); - virtual int getDhtPeers(int lvl, std::list &peers); - virtual int getNetPeerList(std::list &peerIds); - virtual int getNetPeerStatus(const RsPeerId& peerId, RsDhtNetPeer &status); - - virtual int getRelayEnds(std::list &relayEnds); - virtual int getRelayProxies(std::list &relayProxies); - - //virtual int getNetFailedPeer(std::string peerId, PeerStatus &status); - - virtual std::string getUdpAddressString(); - - virtual void getDhtRates(float &read, float &write); - virtual void getRelayRates(float &read, float &write, float &relay); - - virtual bool getOwnDhtId(std::string &ownDhtId); - - /*********************************************************************************************** - ********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) ********* -************************************************************************************************/ - -#ifdef RS_USE_DHT_STUNNER - void setupConnectBits(UdpStunner *dhtStunner, UdpStunner *proxyStunner, UdpRelayReceiver *relay); -#else // RS_USE_DHT_STUNNER - void setupConnectBits(UdpRelayReceiver *relay); -#endif // RS_USE_DHT_STUNNER - void setupPeerSharer(pqiNetAssistPeerShare *sharer); - void modifyNodesPerBucket(uint16_t count); - - void start(); /* starts up the bitdht thread */ - - /* pqiNetAssist - external interface functions */ - virtual int tick(); - virtual void enable(bool on); - virtual void shutdown(); /* blocking call */ - virtual void restart(); - - virtual bool getEnabled(); - virtual bool getActive(); - virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize); - - /* pqiNetAssistConnect - external interface functions */ - - /* add / remove peers */ - virtual bool findPeer(const RsPeerId& id); - virtual bool dropPeer(const RsPeerId& id); - - virtual int addBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age); - virtual int addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &addr, uint32_t flags); - //virtual int addFriend(const std::string pid); - //virtual int addFriendOfFriend(const std::string pid); - //virtual int addOther(const std::string pid); - - /* feedback on success failure of Connections */ - virtual void ConnectionFeedback(const RsPeerId& pid, int state); - - /* extract current peer status */ - virtual bool getPeerStatus(const RsPeerId& id, - struct sockaddr_storage &laddr, struct sockaddr_storage &raddr, - uint32_t &type, uint32_t &mode); - - virtual bool getExternalInterface(struct sockaddr_storage &raddr, - uint32_t &mode); - - virtual bool isAddressBanned(const struct sockaddr_storage& raddr) ; - virtual void getListOfBannedIps(std::list &lst) ; - - virtual bool setAttachMode(bool on); - - - - /* notifyPeer/setExtInterface/Bootstrap/Stun - * hould all be removed from NetAssist? - */ - - - - /* pqiNetAssistConnect - external interface functions */ - - - /*********************************************************************************************** - ****************************** Connections (p3bitdht_peernet.cc) ****************************** -************************************************************************************************/ - /* Feedback from RS Upper Layers */ - //virtual void ConnectionFeedback(std::string pid, int state); - - /* Callback functions - from bitdht */ - int NodeCallback(const bdId *id, uint32_t peerflags); - int PeerCallback(const bdId *id, uint32_t status); - int ValueCallback(const bdNodeId *id, std::string key, uint32_t status); - int ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode); - int InfoCallback(const bdId *id, uint32_t type, uint32_t flags, std::string info); - - - int OnlinePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd); - int UnreachablePeerCallback_locked(const bdId *id, uint32_t status, DhtPeerDetails *dpd); - //int tick(); - int minuteTick(); - int doActions(); - int checkProxyAllowed(const bdId *srcId, const bdId *destId, int mode, uint32_t &bandwidth); - int checkConnectionAllowed(const bdId *peerId, int mode); - void initiateConnection(const bdId *srcId, const bdId *proxyId, const bdId *destId, uint32_t mode, uint32_t loc, uint32_t delayOrBandwidth); - int installRelayConnection(const bdId *srcId, const bdId *destId, uint32_t &bandwidth); - int removeRelayConnection(const bdId *srcId, const bdId *destId); - void monitorConnections(); - - void ConnectCallout(const RsPeerId &peerId, struct sockaddr_in addr, uint32_t connectMode); - - void ConnectCalloutTCPAttempt(const RsPeerId &peerId, struct sockaddr_in addr); - void ConnectCalloutDirectOrProxy(const RsPeerId &peerId, struct sockaddr_in raddr, uint32_t connectFlags, uint32_t delay); - void ConnectCalloutRelay(const RsPeerId &peerId, struct sockaddr_in srcaddr, - struct sockaddr_in proxyaddr, struct sockaddr_in destaddr, - uint32_t connectMode, uint32_t bandwidth); - - - void Feedback_Connected(const RsPeerId& pid); - void Feedback_ConnectionFailed(const RsPeerId& pid); - void Feedback_ConnectionClosed(const RsPeerId& pid); - - void UdpConnectionFailed_locked(DhtPeerDetails *dpd); - void ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely); - - - /*** RELAY HANDLER CODE ***/ - void installRelayHandler(p3BitDhtRelayHandler *); - UdpRelayReceiver *getRelayReceiver(); - - int RelayHandler_InstallRelayConnection(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t &bandwidth); - int RelayHandler_LogFailedProxyAttempt(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode); - - - - /*********************************************************************************************** - ******************** Relay Config Stuff (TEMP - MOSTLY, in p3bitdht_relay.cc) ***************** - ********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) ********* -************************************************************************************************/ - - // Interface for controlling Relays & DHT Relay Mode - virtual int getRelayServerList(std::list &ids); - virtual int addRelayServer(std::string ids); - virtual int removeRelayServer(std::string ids); - - virtual RsDhtRelayMode getRelayMode(); - virtual int setRelayMode(RsDhtRelayMode mode); - - virtual int getRelayAllowance(RsDhtRelayClass classIdx, uint32_t &count, uint32_t &bandwidth); - virtual int setRelayAllowance(RsDhtRelayClass classIdx, uint32_t count, uint32_t bandwidth); - -private: - - // Relay Handling Code / Variables (Mutex Protected). - int setupRelayDefaults(); - int pushRelayServers(); - - std::list mRelayServerList; - RsDhtRelayMode mRelayMode; - -protected: - /*****************************************************************/ - /*********************** p3config ******************************/ - /* Key Functions to be overloaded for Full Configuration */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual void saveDone(); - virtual bool loadList(std::list& load); - /*****************************************************************/ - - // DATA RATES: Variables (Mutex Protected). -private: - - void updateDataRates(); - void clearDataRates(); - - float mRelayReadRate; - float mRelayWriteRate; - float mRelayRelayRate; - float mDhtReadRate; - float mDhtWriteRate; - - rstime_t mLastDataRateUpdate; - - - /*********************************************************************************************** - ************************** Internal Accounting (p3bitdht_peers.cc) **************************** -************************************************************************************************/ - -public: - - int removePeer(const RsPeerId& pid); - - // Can be used externally too. - int calculateNodeId(const RsPeerId& pid, bdNodeId *id); - int addKnownNode(const bdId *id, uint32_t flags); - -private: - - DhtPeerDetails *addInternalPeer_locked(const RsPeerId& pid, RsDhtPeerType type); - int removeInternalPeer_locked(const RsPeerId& pid); - DhtPeerDetails *findInternalDhtPeer_locked(const bdNodeId *id, RsDhtPeerType type); - DhtPeerDetails *findInternalRsPeer_locked(const RsPeerId &pid); - - bool havePeerTranslation_locked(const RsPeerId &pid); - int lookupNodeId_locked(const RsPeerId& pid, bdNodeId *id); - int lookupRsId_locked(const bdNodeId *id, RsPeerId &pid); - int storeTranslation_locked(const RsPeerId& pid); - int removeTranslation_locked(const RsPeerId& pid); - - UdpBitDht *mUdpBitDht; /* has own mutex, is static except for creation/destruction */ -#ifdef RS_USE_DHT_STUNNER - UdpStunner *mDhtStunner; - UdpStunner *mProxyStunner; -#endif // RS_USE_DHT_STUNNER - UdpRelayReceiver *mRelay; - - p3NetMgr *mNetMgr; - - pqiNetAssistPeerShare *mPeerSharer; - - bdDhtFunctions *mDhtFns; - - RsMutex dhtMtx; - - - p3BitDhtRelayHandler *mRelayHandler; - - RsPeerId mOwnRsId; - bdNodeId mOwnDhtId; - - rstime_t mMinuteTS; - - /* translation maps */ - std::map mTransToNodeId; - std::map mTransToRsId; - - std::map mPeers; - std::map mFailedPeers; - - /* Connection Action Queue */ - std::list mActions; - -}; - -#endif /* MRK_P3_BITDHT_H */ - diff --git a/libretroshare/src/dht/p3bitdht_interface.cc b/libretroshare/src/dht/p3bitdht_interface.cc deleted file mode 100644 index b31bbd03c..000000000 --- a/libretroshare/src/dht/p3bitdht_interface.cc +++ /dev/null @@ -1,387 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht_interface.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsnet.h" -#include "dht/p3bitdht.h" - -#include "tcponudp/udprelay.h" -#include "tcponudp/udpstunner.h" -#include "bitdht/bdstddht.h" - - -void convertBdPeerToRsDhtPeer(RsDhtPeer &peer, const bdPeer &int_peer); -void convertDhtPeerDetailsToRsDhtNetPeer(RsDhtNetPeer &status, const DhtPeerDetails &details); -void convertUdpRelayEndtoRsDhtRelayEnd(RsDhtRelayEnd &end, const UdpRelayEnd &int_end); -void convertUdpRelayProxytoRsDhtRelayProxy(RsDhtRelayProxy &proxy, const UdpRelayProxy &int_proxy); - - -/*********************************************************************************************** - ********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) ********* -************************************************************************************************/ - -uint32_t p3BitDht::getNetState(uint32_t /*type*/) -{ - - return 1; -} - -int p3BitDht::getDhtPeers(int lvl, std::list &peers) -{ - /* this function we can actually implement! */ - bdBucket int_peers; - std::list::iterator it; - mUdpBitDht->getDhtBucket(lvl, int_peers); - - for(it = int_peers.entries.begin(); it != int_peers.entries.end(); ++it) - { - RsDhtPeer peer; - - convertBdPeerToRsDhtPeer(peer, *it); - peer.mBucket = lvl; - - peers.push_back(peer); - } - return (int_peers.entries.size() > 0); -} - -int p3BitDht::getNetPeerList(std::list &peerIds) -{ - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); ++it) - { - peerIds.push_back(it->second.mRsId); - } - - return 1; -} - -int p3BitDht::getNetPeerStatus(const RsPeerId& peerId, RsDhtNetPeer &status) -{ - - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - DhtPeerDetails *dpd = findInternalRsPeer_locked(peerId); - if (!dpd) - { - return 0; - } - - convertDhtPeerDetailsToRsDhtNetPeer(status, *dpd); - return 1; -} - - -int p3BitDht::getRelayEnds(std::list &relayEnds) -{ - /* no need for mutex as mRelayReceiver is protected */ - if (!mRelay) - { - return 0; - } - - std::list int_relayEnds; - std::list::iterator it; - mRelay->getRelayEnds(int_relayEnds); - - for(it = int_relayEnds.begin(); it != int_relayEnds.end(); ++it) - { - RsDhtRelayEnd end; - convertUdpRelayEndtoRsDhtRelayEnd(end, *it); - - relayEnds.push_back(end); - } - return 1; -} - - -int p3BitDht::getRelayProxies(std::list &relayProxies) -{ - /* no need for mutex as mRelayReceiver is protected */ - if (!mRelay) - { - return 0; - } - - std::list int_relayProxies; - std::list::iterator it; - mRelay->getRelayProxies(int_relayProxies); - - for(it = int_relayProxies.begin(); it != int_relayProxies.end(); ++it) - { - RsDhtRelayProxy proxy; - convertUdpRelayProxytoRsDhtRelayProxy(proxy, *it); - relayProxies.push_back(proxy); - } - return 1; -} - - -#if 0 -int p3BitDht::getNetFailedPeer(std::string peerId, PeerStatus &status) -{ - return 1; -} -#endif - -std::string p3BitDht::getUdpAddressString() -{ - std::string out; -#ifdef RS_USE_DHT_STUNNER - struct sockaddr_in extAddr; - uint8_t extStable; - - if (mDhtStunner->externalAddr(extAddr, extStable)) - { - rs_sprintf_append(out, " DhtExtAddr: %s:%u", rs_inet_ntoa(extAddr.sin_addr).c_str(), ntohs(extAddr.sin_port)); - - if (extStable) - { - out += " (Stable) "; - } - else - { - out += " (Unstable) "; - } - } - else - { - out += " DhtExtAddr: Unknown "; - } - if (mProxyStunner->externalAddr(extAddr, extStable)) - { - rs_sprintf_append(out, " ProxyExtAddr: %s:%u", rs_inet_ntoa(extAddr.sin_addr).c_str(), ntohs(extAddr.sin_port)); - - if (extStable) - { - out += " (Stable) "; - } - else - { - out += " (Unstable) "; - } - } - else - { - out += " ProxyExtAddr: Unknown "; - } -#else // RS_USE_DHT_STUNNER - // whitespaces taken from above - out = " DhtExtAddr: Unknown ProxyExtAddr: Unknown "; -#endif // RS_USE_DHT_STUNNER - return out; -} - -void p3BitDht::updateDataRates() -{ - uint32_t relayRead = 0; - uint32_t relayWrite = 0; - uint32_t relayRelay = 0; - uint32_t dhtRead = 0; - uint32_t dhtWrite = 0; - - mRelay->getDataTransferred(relayRead, relayWrite, relayRelay); - mUdpBitDht->getDataTransferred(dhtRead, dhtWrite); - - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - rstime_t now = time(NULL); - float period = now - mLastDataRateUpdate; - -#define RATE_FACTOR (0.75) - - mRelayReadRate *= RATE_FACTOR; - mRelayReadRate += (1.0 - RATE_FACTOR) * (relayRead / period); - - mRelayWriteRate *= RATE_FACTOR; - mRelayWriteRate += (1.0 - RATE_FACTOR) * (relayWrite / period); - - mRelayRelayRate *= RATE_FACTOR; - mRelayRelayRate += (1.0 - RATE_FACTOR) * (relayRelay / period); - - mDhtReadRate *= RATE_FACTOR; - mDhtReadRate += (1.0 - RATE_FACTOR) * (dhtRead / period); - - mDhtWriteRate *= RATE_FACTOR; - mDhtWriteRate += (1.0 - RATE_FACTOR) * (dhtWrite / period); - - mLastDataRateUpdate = now; - -} - -void p3BitDht::clearDataRates() -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - mRelayReadRate = 0; - mRelayWriteRate = 0; - mRelayRelayRate = 0; - mDhtReadRate = 0; - mDhtWriteRate = 0; - - mLastDataRateUpdate = time(NULL); -} - - -/* in kB/s */ -void p3BitDht::getDhtRates(float &read, float &write) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - read = mDhtReadRate / 1024.0; - write = mDhtWriteRate / 1024.0; -} - -void p3BitDht::getRelayRates(float &read, float &write, float &relay) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - read = mRelayReadRate / 1024.0; - write = mRelayWriteRate / 1024.0; - relay = mRelayRelayRate / 1024.0; -} - - - -/*********************************************************************************************** - ********** External RsDHT Interface (defined in libretroshare/src/retroshare/rsdht.h) ********* -************************************************************************************************/ - -void convertBdPeerToRsDhtPeer(RsDhtPeer &peer, const bdPeer &int_peer) -{ - bdStdPrintNodeId(peer.mDhtId, &(int_peer.mPeerId.id), false); - - rs_sprintf(peer.mAddr, "%s:%u", rs_inet_ntoa(int_peer.mPeerId.addr.sin_addr).c_str(), ntohs(int_peer.mPeerId.addr.sin_port)); - - peer.mLastSendTime = int_peer.mLastSendTime; - peer.mLastRecvTime = int_peer.mLastRecvTime; - peer.mFoundTime = int_peer.mFoundTime; - peer.mPeerFlags = int_peer.mPeerFlags; - peer.mExtraFlags = int_peer.mExtraFlags; -} - - - -void convertDhtPeerDetailsToRsDhtNetPeer(RsDhtNetPeer &status, const DhtPeerDetails &details) -{ - bdStdPrintId(status.mDhtId, &(details.mDhtId), false); - - status.mRsId = details.mRsId; - - status.mPeerType = details.mPeerType; - - status.mDhtState = details.mDhtState; - - status.mConnectState = details.mConnectLogic.connectState(); - - status.mPeerReqState = details.mPeerReqState; - - status.mExclusiveProxyLock = details.mExclusiveProxyLock; - - status.mPeerConnectState = details.mPeerConnectState; - - switch(details.mPeerConnectMode) - { - default: - status.mPeerConnectMode = RsDhtTouMode::NONE; - break; - case BITDHT_CONNECT_MODE_DIRECT: - status.mPeerConnectMode = RsDhtTouMode::DIRECT; - break; - case BITDHT_CONNECT_MODE_PROXY: - status.mPeerConnectMode = RsDhtTouMode::PROXY; - break; - case BITDHT_CONNECT_MODE_RELAY: - status.mPeerConnectMode = RsDhtTouMode::RELAY; - break; - } - - //status.mPeerConnectProxyId = details.mPeerConnectProxyId; - bdStdPrintId(status.mPeerConnectProxyId, &(details.mPeerConnectProxyId), false); - - status.mCbPeerMsg = details.mPeerCbMsg; - - return; -} - -void convertUdpRelayEndtoRsDhtRelayEnd(RsDhtRelayEnd &end, const UdpRelayEnd &int_end) -{ - rs_sprintf(end.mLocalAddr, "%s:%u", rs_inet_ntoa(int_end.mLocalAddr.sin_addr).c_str(), ntohs(int_end.mLocalAddr.sin_port)); - rs_sprintf(end.mProxyAddr, "%s:%u", rs_inet_ntoa(int_end.mProxyAddr.sin_addr).c_str(), ntohs(int_end.mProxyAddr.sin_port)); - rs_sprintf(end.mRemoteAddr, "%s:%u", rs_inet_ntoa(int_end.mRemoteAddr.sin_addr).c_str(), ntohs(int_end.mRemoteAddr.sin_port)); - - end.mCreateTS = 0; - return; -} - -void convertUdpRelayProxytoRsDhtRelayProxy(RsDhtRelayProxy &proxy, const UdpRelayProxy &int_proxy) -{ - rs_sprintf(proxy.mSrcAddr, "%s:%u", rs_inet_ntoa(int_proxy.mAddrs.mSrcAddr.sin_addr).c_str(), ntohs(int_proxy.mAddrs.mSrcAddr.sin_port)); - rs_sprintf(proxy.mDestAddr, "%s:%u", rs_inet_ntoa(int_proxy.mAddrs.mDestAddr.sin_addr).c_str(), ntohs(int_proxy.mAddrs.mDestAddr.sin_port)); - - proxy.mBandwidth = int_proxy.mBandwidth; - proxy.mRelayClass = int_proxy.mRelayClass; - proxy.mLastTS = int_proxy.mLastTS; - proxy.mCreateTS = 0; - - //proxy.mDataSize = int_proxy.mDataSize; - //proxy.mLastBandwidthTS = int_proxy.mLastBandwidthTS; -} - -RsDhtPeer::RsDhtPeer() -{ - mBucket = 0; - - //std::string mDhtId; - mLastSendTime = 0; - mLastRecvTime = 0; - mFoundTime = 0; - mPeerFlags = 0; - mExtraFlags = 0; -} - - -RsDhtNetPeer::RsDhtNetPeer() -{ - return; -} - - -RsDhtRelayEnd::RsDhtRelayEnd() -{ - mCreateTS = 0; -} - - -RsDhtRelayProxy::RsDhtRelayProxy() -{ - mBandwidth = 0; - mRelayClass = 0; - mLastTS = 0; - mCreateTS = 0; - - //uint32_t mDataSize; - //rstime_t mLastBandwidthTS; - -} - - diff --git a/libretroshare/src/dht/p3bitdht_peernet.cc b/libretroshare/src/dht/p3bitdht_peernet.cc deleted file mode 100644 index a37678728..000000000 --- a/libretroshare/src/dht/p3bitdht_peernet.cc +++ /dev/null @@ -1,2533 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht_peernet.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "dht/p3bitdht.h" - -#include -#include - - -#include "bitdht/bdiface.h" -#include "bitdht/bdstddht.h" -#include "bitdht/bdmanager.h" - -//#include "udp/udplayer.h" - -#include "util/rsnet.h" -#include "tcponudp/tou.h" -#include "tcponudp/udpstunner.h" -#include "tcponudp/udprelay.h" - -#include "pqi/p3netmgr.h" -#include "pqi/pqimonitor.h" - -#define PEERNET_CONNECT_TIMEOUT 180 // Should be BIGGER than Higher level (but okay if not!) - -#define MIN_DETERMINISTIC_SWITCH_PERIOD 60 - -/*** - * - * #define DEBUG_BITDHT_COMMON 1 // These are the things that are called regularly (annoying for debugging specifics) - * #define DEBUG_PEERNET 1 - * - **/ - - -/****************************************************************************************** - ************************************* Dht Callback *************************************** - ******************************************************************************************/ - -/**** dht NodeCallback **** - * - * - * In the old version, we used this to callback mConnCb->peerStatus() - * We might want to drop this, and concentrate on the connection stuff. - * - * -> if an new dht peer, then pass to Stunners. - * -> do we care if we know them? not really! - */ - -int p3BitDht::InfoCallback(const bdId *id, uint32_t /*type*/, uint32_t /*flags*/, std::string /*info*/) -{ - /* translate info */ - RsPeerId rsid; - struct sockaddr_in addr = id->addr; - int outtype = PNASS_TYPE_BADPEER; - int outreason = PNASS_REASON_UNKNOWN; - int outage = 0; - -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::InfoCallback() likely BAD_PEER: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(id->id), RsDhtPeerType::ANY); - - if (dpd) - { - rsid = dpd->mRsId; - } - } - - if (mPeerSharer) - { - struct sockaddr_storage tmpaddr; - struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr; - ap->sin_family = AF_INET; - ap->sin_addr = addr.sin_addr; - ap->sin_port = addr.sin_port; - - mPeerSharer->updatePeer(rsid, tmpaddr, outtype, outreason, outage); - } - -#ifdef RS_USE_DHT_STUNNER - /* call to the Stunners to drop the address as well */ - /* IDEALLY these addresses should all be filtered at UdpLayer level instead! */ - if (mDhtStunner) - { - mDhtStunner->dropStunPeer(addr); - } - if (mProxyStunner) - { - mProxyStunner->dropStunPeer(addr); - } -#endif // RS_USE_DHT_STUNNER - - return 1; -} - - - -/**** dht NodeCallback **** - * - * - * In the old version, we used this to callback mConnCb->peerStatus() - * We might want to drop this, and concentrate on the connection stuff. - * - * -> if an new dht peer, then pass to Stunners. - * -> do we care if we know them? not really! - */ - -int p3BitDht::NodeCallback(const bdId *id, uint32_t peerflags) -{ - // No need for Mutex, and Stunners are self protected. - - // These are the flags that will be returned by p3BitDht & RS peers with the new DHT. - // if (peerflags & BITDHT_PEER_STATUS_DHT_ENGINE_VERSION) // Change to this later... - if ((peerflags & BITDHT_PEER_STATUS_DHT_ENGINE) && - (peerflags & BITDHT_PEER_STATUS_DHT_APPL)) - { - - /* pass off to the Stunners - * but only if they need them. - * ideally don't pass to both peers... (XXX do later) - */ - - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - if (id->id == mOwnDhtId) - { -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::NodeCallback() Skipping own id"; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - return 1; - } - } - -#ifdef RS_USE_DHT_STUNNER - if ((mProxyStunner) && (mProxyStunner->needStunPeers())) - { -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::NodeCallback() Passing BitDHT Peer to DhtStunner: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - mProxyStunner->addStunPeer(id->addr, NULL); - } - /* else */ // removed else until we have lots of peers. - - if ((mDhtStunner) && (mDhtStunner->needStunPeers())) - { -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::NodeCallback() Passing BitDHT Peer to DhtStunner: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - mDhtStunner->addStunPeer(id->addr, NULL); - } -#endif // RS_USE_DHT_STUNNER - } - return 1; -} - -/**** dht PeerCallback **** - * - * - * In the old version, we used this to callback mConnCb->peerConnectRequest() - * we need to continue doing this, to maintain compatibility. - * - * -> update Dht Status, and trigger connect if ONLINE or UNREACHABLE - */ - - -int p3BitDht::PeerCallback(const bdId *id, uint32_t status) -{ - //std::string str; - //bdStdPrintNodeId(str, &(id->id)); - - //std::cerr << "p3BitDht::dhtPeerCallback()"; - //std::cerr << std::endl; - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(id->id), RsDhtPeerType::FRIEND); - - if (!dpd) - { - /* ERROR */ - std::cerr << "p3BitDht::PeerCallback() ERROR Unknown Peer: "; - bdStdPrintId(std::cerr, id); - std::cerr << " status: " << status; - std::cerr << std::endl; - - return 0; - } - - sockaddr_clear(&(dpd->mDhtId.addr)); - - switch(status) - { - default: - dpd->mDhtState = RsDhtPeerDht::NOT_ACTIVE; - break; - - case BITDHT_MGR_QUERY_FAILURE: - dpd->mDhtState = RsDhtPeerDht::FAILURE; - break; - - case BITDHT_MGR_QUERY_PEER_OFFLINE: - dpd->mDhtState = RsDhtPeerDht::OFFLINE; - break; - - case BITDHT_MGR_QUERY_PEER_UNREACHABLE: - dpd->mDhtState = RsDhtPeerDht::UNREACHABLE; - dpd->mDhtId = *id; // set the IP:Port of the unreachable peer. - UnreachablePeerCallback_locked(id, status, dpd); - - break; - - case BITDHT_MGR_QUERY_PEER_ONLINE: - dpd->mDhtState = RsDhtPeerDht::ONLINE; - dpd->mDhtId = *id; // set the IP:Port of the Online peer. - OnlinePeerCallback_locked(id, status, dpd); - - break; - - } - - rstime_t now = time(NULL); - dpd->mDhtUpdateTS = now; - - return 1; -} - - - -int p3BitDht::OnlinePeerCallback_locked(const bdId *id, uint32_t /*status*/, DhtPeerDetails *dpd) -{ - /* remove unused parameter warnings */ - (void) id; - - if ((dpd->mPeerConnectState != RsDhtPeerConnectState::DISCONNECTED) || - (dpd->mPeerReqState == RsDhtPeerRequest::RUNNING)) - { - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::OnlinePeerCallback_locked() WARNING Ignoring Callback: connection already underway: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - return 1; - } - - bool connectOk = true; - bool doTCPCallback = false; - - /* work out network state */ - uint32_t connectFlags = dpd->mConnectLogic.connectCb(CSB_CONNECT_DIRECT, - mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()); -// bool useProxyPort = (connectFlags & CSB_ACTION_PROXY_PORT); - - switch(connectFlags & CSB_ACTION_MASK_MODE) - { - default: - case CSB_ACTION_WAIT: - { - connectOk = false; - } - break; - case CSB_ACTION_TCP_CONN: - { - connectOk = false; - doTCPCallback = true; - } - break; - case CSB_ACTION_DIRECT_CONN: - { - - connectOk = true; - } - break; - case CSB_ACTION_PROXY_CONN: - { - /* ERROR */ - std::cerr << "dhtPeerCallback: ERROR ConnectLogic returned PROXY"; - std::cerr << std::endl; - connectOk = false; - } - break; - case CSB_ACTION_RELAY_CONN: - { - /* ERROR */ - std::cerr << "dhtPeerCallback: ERROR ConnectLogic returned RELAY"; - std::cerr << std::endl; - connectOk = false; - } - break; - } - - if (connectOk) - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Peer Online, triggering Direct Connection for: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_CONNECT; - ca.mMode = BITDHT_CONNECT_MODE_DIRECT; - ca.mDestId = *id; - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - - mActions.push_back(ca); - } - - /* might need to make this an ACTION - leave for now */ - if (doTCPCallback) - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Peer Online, triggering TCP Connection for: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_TCPATTEMPT; - ca.mMode = BITDHT_CONNECT_MODE_DIRECT; - ca.mDestId = *id; - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - - mActions.push_back(ca); - //ConnectCalloutTCPAttempt(dpd->mRsId, id->addr); - } - - return 1; -} - - - -int p3BitDht::UnreachablePeerCallback_locked(const bdId *id, uint32_t /*status*/, DhtPeerDetails *dpd) -{ - - if ((dpd->mPeerConnectState != RsDhtPeerConnectState::DISCONNECTED) || - (dpd->mPeerReqState == RsDhtPeerRequest::RUNNING)) - { - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::UnreachablePeerCallback_locked() WARNING Ignoring Callback: connection already underway: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - return 1; - } - -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Peer Unreachable, triggering Proxy | Relay Connection for: "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - - bool proxyOk = false; - bool connectOk = true; - - /* work out network state */ - uint32_t connectFlags = dpd->mConnectLogic.connectCb(CSB_CONNECT_UNREACHABLE, - mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()); - bool useProxyPort = (connectFlags & CSB_ACTION_PROXY_PORT); - - switch(connectFlags & CSB_ACTION_MASK_MODE) - { - default: - case CSB_ACTION_WAIT: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Request to Wait ... so no Connection Attempt for "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - connectOk = false; - } - break; - case CSB_ACTION_DIRECT_CONN: - { - /* ERROR */ - std::cerr << "dhtPeerCallback: ERROR ConnectLogic returned DIRECT"; - std::cerr << std::endl; - - connectOk = false; - } - break; - case CSB_ACTION_PROXY_CONN: - { - proxyOk = true; - connectOk = true; - } - break; - case CSB_ACTION_RELAY_CONN: - { - proxyOk = false; - connectOk = true; - } - break; - } - - if (connectOk) - { - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_CONNECT; - ca.mDestId = *id; - - dpd->mConnectLogic.storeProxyPortChoice(connectFlags, useProxyPort); - - if (proxyOk) - { - ca.mMode = BITDHT_CONNECT_MODE_PROXY; -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Trying Proxy Connection."; - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Trying Relay Connection."; - std::cerr << std::endl; -#endif - ca.mMode = BITDHT_CONNECT_MODE_RELAY; - } - - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - mActions.push_back(ca); - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtPeerCallback. Cancelled Connection Attempt for "; - bdStdPrintId(std::cerr, id); - std::cerr << std::endl; -#endif - } - - return 1; -} - - - -int p3BitDht::ValueCallback(const bdNodeId */*id*/, std::string /*key*/, uint32_t /*status*/) -{ - std::cerr << "p3BitDht::ValueCallback() ERROR Does nothing!"; - std::cerr << std::endl; - - return 1; -} - -int p3BitDht::ConnectCallback(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t point, uint32_t param, uint32_t cbtype, uint32_t errcode) -{ -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ConnectCallback()"; - std::cerr << std::endl; - std::cerr << "srcId: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << std::endl; - std::cerr << "proxyId: "; - bdStdPrintId(std::cerr, proxyId); - std::cerr << std::endl; - std::cerr << "destId: "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; - - std::cerr << " mode: " << mode; - std::cerr << " param: " << param; - std::cerr << " point: " << point; - std::cerr << " cbtype: " << cbtype; - std::cerr << std::endl; -#endif - - - /* we handle MID and START/END points differently... this is biggest difference. - * so handle first. - */ - - bdId peerId; - rstime_t now = time(NULL); - - switch(point) - { - default: - case BD_PROXY_CONNECTION_UNKNOWN_POINT: - { - std::cerr << "p3BitDht::dhtConnectCallback() ERROR UNKNOWN point, ignoring Callback"; - std::cerr << std::endl; - return 0; - } - case BD_PROXY_CONNECTION_START_POINT: - peerId = *destId; - break; - case BD_PROXY_CONNECTION_END_POINT: - peerId = *srcId; - break; - case BD_PROXY_CONNECTION_MID_POINT: - { - /* AS a mid point, we can receive.... AUTH,PENDING,PROXY,FAILED */ - - switch(cbtype) - { - case BITDHT_CONNECT_CB_AUTH: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection Requested Between:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; -#endif - /* if there is an error code - then it is just to inform us of a failed attempt */ - if (errcode) - { - RelayHandler_LogFailedProxyAttempt(srcId, destId, mode, errcode); - /* END MID FAILED ATTEMPT */ - return 1; - } - - uint32_t bandwidth = 0; - - int connectionAllowed = BITDHT_CONNECT_ERROR_GENERIC; - if (checkProxyAllowed(srcId, destId, mode, bandwidth)) - { - connectionAllowed = BITDHT_CONNECT_ANSWER_OKAY; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Allowed"; - std::cerr << std::endl; -#endif - } - else - { - connectionAllowed = BITDHT_CONNECT_ERROR_AUTH_DENIED; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Denied"; - std::cerr << std::endl; -#endif - } - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_AUTHORISE; - ca.mMode = mode; - ca.mProxyId = *proxyId; - ca.mSrcId = *srcId; - ca.mDestId = *destId; - ca.mPoint = point; - ca.mAnswer = connectionAllowed; - ca.mDelayOrBandwidth = bandwidth; - - mActions.push_back(ca); - } - break; - case BITDHT_CONNECT_CB_PENDING: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection Pending:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; -#endif - } - break; - case BITDHT_CONNECT_CB_PROXY: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection Starting:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; -#endif - } - break; - case BITDHT_CONNECT_CB_FAILED: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection Failed:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - - std::cerr << " ErrorCode: " << errcode; - int errsrc = errcode & BITDHT_CONNECT_ERROR_MASK_SOURCE; - int errtype = errcode & BITDHT_CONNECT_ERROR_MASK_TYPE; - - std::cerr << " ErrorSrc: " << errsrc; - std::cerr << " ErrorType: " << errtype; - - std::cerr << std::endl; -#endif - - if (mode == BITDHT_CONNECT_MODE_RELAY) - { - removeRelayConnection(srcId, destId); - } - } - break; - default: - case BITDHT_CONNECT_CB_START: - { - std::cerr << "dhtConnectionCallback() ERROR unexpected Proxy ConnectionCallback:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; - } - break; - } - /* End the MID Point stuff */ - return 1; - } - } - - /* if we get here, we are an endpoint (peer specified in peerId) */ - - /* translate id into string for exclusive mode */ - std::string pid; - bdStdPrintNodeId(pid, &(peerId.id), false); - - switch(cbtype) - { - case BITDHT_CONNECT_CB_AUTH: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Requested By: "; - bdStdPrintId(std::cerr, &(peerId)); - std::cerr << std::endl; -#endif - - int connectionAllowed = BITDHT_CONNECT_ERROR_GENERIC; - if (checkConnectionAllowed(&(peerId), mode)) - { - connectionAllowed = BITDHT_CONNECT_ANSWER_OKAY; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Allowed"; - std::cerr << std::endl; -#endif - } - else - { - connectionAllowed = BITDHT_CONNECT_ERROR_AUTH_DENIED; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Denied"; - std::cerr << std::endl; -#endif - } - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_AUTHORISE; - ca.mProxyId = *proxyId; - ca.mSrcId = *srcId; - ca.mDestId = *destId; - ca.mDelayOrBandwidth = 0; - - /* Check Proxy ExtAddress Status (but only if connection is Allowed) */ - if ((connectionAllowed == BITDHT_CONNECT_ANSWER_OKAY) && - (mode == BITDHT_CONNECT_MODE_PROXY)) - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Checking Address for Proxy"; - std::cerr << std::endl; -#endif - - struct sockaddr_in extaddr; - sockaddr_clear(&extaddr); - - bool connectOk = false; - bool proxyPort = false; - bool exclusivePort = false; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback(): Proxy... deciding which port to use."; - std::cerr << std::endl; -#endif - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - proxyPort = dpd->mConnectLogic.shouldUseProxyPort( - mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()); - - dpd->mConnectLogic.storeProxyPortChoice(0, proxyPort); - -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback: Setting ProxyPort: "; - std::cerr << " UseProxyPort? " << proxyPort; - std::cerr << std::endl; - - std::cerr << "dhtConnectionCallback: Checking ConnectLogic.NetState: "; - std::cerr << dpd->mConnectLogic.calcNetState(mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()); - std::cerr << std::endl; -#endif - - if (proxyPort) - { - exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.calcNetState( - mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode())); - } - -#ifdef DEBUG_PEERNET - if (exclusivePort) std::cerr << "dhtConnectionCallback: we Require Exclusive Proxy Port for connection" << std::endl; - else std::cerr << "dhtConnectionCallback: Dont need Exclusive Proxy Port for connection" << std::endl; -#endif - - connectOk = true; - } - else - { - std::cerr << "PeerAction: Connect Proxy: ERROR Cannot find PeerStatus"; - std::cerr << std::endl; - } - -#ifdef RS_USE_DHT_STUNNER - uint8_t extStable = 0; - - UdpStunner *stunner = mProxyStunner; - if (!proxyPort) - { - stunner = mDhtStunner; - } - - if ((connectOk) && (stunner) && (stunner->externalAddr(extaddr, extStable))) - { - if (extStable) - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection Attempt to: "; - bdStdPrintId(std::cerr, &(peerId)); - std::cerr << " is Ok as we have Stable Own External Proxy Address"; - std::cerr << std::endl; -#endif - - if (point == BD_PROXY_CONNECTION_END_POINT) - { - ca.mDestId.addr = extaddr; - } - else - { - ca.mSrcId.addr = extaddr; - std::cerr << "dhtConnectionCallback() ERROR Proxy Auth as SrcId"; - std::cerr << std::endl; - } - - /* check if we require exclusive use of the proxy port */ - if (exclusivePort) - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback: Attempting to Grab ExclusiveLock of UdpStunner"; - std::cerr << std::endl; -#endif - - int stun_age = mProxyStunner->grabExclusiveMode(pid); - if (stun_age > 0) - { - int delay = 0; - if (stun_age < MIN_DETERMINISTIC_SWITCH_PERIOD) - { - delay = MIN_DETERMINISTIC_SWITCH_PERIOD - stun_age; - } - - /* great we got it! */ - ca.mDelayOrBandwidth = delay; - -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback: GotExclusiveLock With Delay: " << delay; - std::cerr << " for stable port"; - std::cerr << std::endl; -#endif - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - dpd->mExclusiveProxyLock = true; - -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback: Success at grabbing ExclusiveLock of UdpStunner"; - std::cerr << std::endl; -#endif - - } - else - { - std::cerr << "PeerAction: Connect Proxy: ERROR Cannot find PeerStatus"; - std::cerr << std::endl; - connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; - mProxyStunner->releaseExclusiveMode(pid,false); - } - } - else - { - /* failed to get exclusive mode - must wait */ - connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; - -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback: Failed to Grab ExclusiveLock, Returning TEMPUNAVAIL"; - std::cerr << std::endl; -#endif - } - } - - - } - else - { - if (exclusivePort) - { - connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection"; - std::cerr << " is Discarded, as External Proxy Address is Not Stable! (EXCLUSIVE MODE)"; - std::cerr << std::endl; -#endif - } - else - { - connectionAllowed = BITDHT_CONNECT_ERROR_UNREACHABLE; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Proxy Connection"; - std::cerr << " is Discarded, as Own External Proxy Address is Not Stable!"; - std::cerr << std::endl; -#endif - } - } - } - else - { - connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() ERROR Proxy Connection "; - std::cerr << " is Discarded, as Failed to get Own External Proxy Address."; - std::cerr << std::endl; -#endif - } -#else // RS_USE_DHT_STUNNER - connectionAllowed = BITDHT_CONNECT_ERROR_TEMPUNAVAIL; - (void) connectOk; - (void) exclusivePort; -#endif // RS_USE_DHT_STUNNER - } - - ca.mMode = mode; - ca.mPoint = point; - ca.mAnswer = connectionAllowed; - - mActions.push_back(ca); - } - break; - - case BITDHT_CONNECT_CB_START: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Starting with: "; - bdStdPrintId(std::cerr, &(peerId)); - std::cerr << std::endl; -#endif - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_START; - ca.mMode = mode; - ca.mProxyId = *proxyId; - ca.mSrcId = *srcId; - ca.mDestId = *destId; - ca.mPoint = point; - ca.mDelayOrBandwidth = param; - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - - mActions.push_back(ca); - - } - break; - - case BITDHT_CONNECT_CB_FAILED: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Connection Attempt Failed with:"; - bdStdPrintId(std::cerr, &(peerId)); - std::cerr << std::endl; - - std::cerr << "dhtConnectionCallback() Proxy:"; - bdStdPrintId(std::cerr, proxyId); - std::cerr << std::endl; - - std::cerr << "dhtConnectionCallback() "; - std::cerr << " ErrorCode: " << errcode; - int errsrc = errcode & BITDHT_CONNECT_ERROR_MASK_SOURCE; - int errtype = errcode & BITDHT_CONNECT_ERROR_MASK_TYPE; - - std::cerr << " ErrorSrc: " << errsrc; - std::cerr << " ErrorType: " << errtype; - std::cerr << std::endl; -#endif - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - dpd->mPeerCbMsg = "ERROR : "; - dpd->mPeerCbMsg += decodeConnectionError(errcode); - dpd->mPeerCbMode = mode; - dpd->mPeerCbPoint = point; - dpd->mPeerCbProxyId = *proxyId; - dpd->mPeerCbDestId = peerId; - dpd->mPeerCbTS = now; - } - else - { - std::cerr << "dhtConnectionCallback() "; - std::cerr << "ERROR Unknown Peer"; - std::cerr << std::endl; - } - } - break; - - case BITDHT_CONNECT_CB_REQUEST: - { -#ifdef DEBUG_PEERNET - std::cerr << "dhtConnectionCallback() Local Connection Request Feedback:"; - bdStdPrintId(std::cerr, &(peerId)); - std::cerr << std::endl; - - std::cerr << "dhtConnectionCallback() Proxy:"; - bdStdPrintId(std::cerr, proxyId); - std::cerr << std::endl; -#endif - - if (point != BD_PROXY_CONNECTION_START_POINT) - { - std::cerr << "dhtConnectionCallback() ERROR not START_POINT"; - std::cerr << std::endl; - return 0; - } - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - if (errcode) - { - ReleaseProxyExclusiveMode_locked(dpd, false); - - dpd->mPeerReqStatusMsg = "STOPPED: "; - dpd->mPeerReqStatusMsg += decodeConnectionError(errcode); - dpd->mPeerReqState = RsDhtPeerRequest::STOPPED; - dpd->mPeerReqTS = now; - - int updatecode = CSB_UPDATE_FAILED_ATTEMPT; - int errtype = errcode & BITDHT_CONNECT_ERROR_MASK_TYPE; - switch(errtype) - { - /* fatal errors */ - case BITDHT_CONNECT_ERROR_AUTH_DENIED: - { - updatecode = CSB_UPDATE_AUTH_DENIED; - } - break; - - /* move on errors */ - case BITDHT_CONNECT_ERROR_UNREACHABLE: // sym NAT. - case BITDHT_CONNECT_ERROR_UNSUPPORTED: // mode unavailable. - { - updatecode = CSB_UPDATE_MODE_UNAVAILABLE; - } - break; - - - /* retry attempts */ - case BITDHT_CONNECT_ERROR_TEMPUNAVAIL: - case BITDHT_CONNECT_ERROR_DUPLICATE: - { - updatecode = CSB_UPDATE_RETRY_ATTEMPT; - } - break; - /* standard failed attempts */ - case BITDHT_CONNECT_ERROR_GENERIC: - case BITDHT_CONNECT_ERROR_PROTOCOL: - case BITDHT_CONNECT_ERROR_TIMEOUT: - case BITDHT_CONNECT_ERROR_NOADDRESS: - case BITDHT_CONNECT_ERROR_OVERLOADED: - /* CB_REQUEST errors */ - case BITDHT_CONNECT_ERROR_TOOMANYRETRY: - case BITDHT_CONNECT_ERROR_OUTOFPROXY: - { - updatecode = CSB_UPDATE_FAILED_ATTEMPT; - } - break; - - /* user cancelled ... no update */ - case BITDHT_CONNECT_ERROR_USER: - { - updatecode = CSB_UPDATE_NONE; - } - break; - } - if (updatecode) - { - dpd->mConnectLogic.updateCb(updatecode); - } - } - else // a new connection attempt. - { - dpd->mPeerReqStatusMsg = "Connect Attempt"; - dpd->mPeerReqState = RsDhtPeerRequest::RUNNING; - dpd->mPeerReqMode = mode; - dpd->mPeerReqProxyId = *proxyId; - dpd->mPeerReqTS = now; - - // This also is flagged into the instant Cb info. - dpd->mPeerCbMsg = "Local Connect Attempt"; - dpd->mPeerCbMode = mode; - dpd->mPeerCbPoint = point; - dpd->mPeerCbProxyId = *proxyId; - dpd->mPeerCbDestId = peerId; - dpd->mPeerCbTS = now; - } - } - else - { - std::cerr << "dhtConnectionCallback() ERROR Cannot find PeerStatus"; - std::cerr << std::endl; - } - } - break; - - default: - case BITDHT_CONNECT_CB_PENDING: - case BITDHT_CONNECT_CB_PROXY: - { - std::cerr << "dhtConnectionCallback() ERROR unexpected ConnectionCallback:"; - std::cerr << std::endl; - bdStdPrintId(std::cerr, srcId); - std::cerr << " and "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; - } - break; - } - return 1; -} - -/****************************************************************************************** - ******************************** Dht Actions / Monitoring ******************************** - ******************************************************************************************/ - - -/* tick stuff that isn't in its own thread */ - -int p3BitDht::tick() -{ - doActions(); - monitorConnections(); - - minuteTick(); - -#ifdef DEBUG_PEERNET_COMMON - time_t now = time(NULL); // Don't use rstime_t here or ctime break on windows - std::cerr << "p3BitDht::tick() TIME: " << ctime(&now) << std::endl; - std::cerr.flush(); -#endif - - return 1; -} - -#define MINUTE_IN_SECS 60 -#define TEN_IN_SECS 10 - -int p3BitDht::minuteTick() -{ - rstime_t now = time(NULL); - int deltaT = 0; - - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - deltaT = now-mMinuteTS; - } - - //if (deltaT > MINUTE_IN_SECS) - if (deltaT > TEN_IN_SECS) - { - mRelay->checkRelays(); - - updateDataRates(); - - /* temp - testing - print dht & relay traffic */ - float dhtRead, dhtWrite; - float relayRead, relayWrite, relayRelayed; - - getRelayRates(relayRead, relayWrite, relayRelayed); - getDhtRates(dhtRead, dhtWrite); - -#ifdef DEBUG_PEERNET_COMMON - double denom = deltaT; - - std::cerr << "p3BitDht::minuteTick() "; - std::cerr << "DhtRead: " << dhtRead / denom << " kB/s "; - std::cerr << "DhtWrite: " << dhtWrite / denom << " kB/s "; - std::cerr << std::endl; - - std::cerr << "p3BitDht::minuteTick() "; - std::cerr << "RelayRead: " << relayRead / denom << " kB/s "; - std::cerr << "RelayWrite: " << relayWrite / denom << " kB/s "; - std::cerr << "RelayRelayed: " << relayRelayed / denom << " kB/s "; - std::cerr << std::endl; -#endif - - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - mMinuteTS = now; - } - return 1; -} - -int p3BitDht::doActions() -{ -#ifdef DEBUG_PEERNET_COMMON - std::cerr << "p3BitDht::doActions()" << std::endl; -#endif - - rstime_t now = time(NULL); - - while(mActions.size() > 0) - { - PeerAction action; - - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - if (mActions.size() < 1) - { - break; - } - - action = mActions.front(); - mActions.pop_front(); - } - - switch(action.mType) - { - case PEERNET_ACTION_TYPE_CONNECT: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << std::endl; -#endif - - bool doConnectionRequest = false; - bool connectionReqFailed = false; - bool grabbedExclusivePort = false; - - /* translate id into string for exclusive mode */ - std::string pid; - bdStdPrintNodeId(pid, &(action.mDestId.id), false); - - - // Parameters that will be used for the Connect Request. - struct sockaddr_in connAddr; // We zero this address. (DHT Layer handles most cases) - sockaddr_clear(&connAddr); - uint32_t connStart = 1; /* > 0 indicates GO (number indicates required startup delay) */ - uint32_t connDelay = 0; - - uint32_t failReason = CSB_UPDATE_MODE_UNAVAILABLE; - - if ((action.mMode == BITDHT_CONNECT_MODE_DIRECT) || - (action.mMode == BITDHT_CONNECT_MODE_RELAY)) - { - doConnectionRequest = true; - } - else if (action.mMode == BITDHT_CONNECT_MODE_PROXY) - { - struct sockaddr_in extaddr; - sockaddr_clear(&extaddr); - bool proxyPort = true; - bool exclusivePort = false; - bool connectOk = false; - -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Proxy... deciding which port to use."; - std::cerr << std::endl; -#endif - - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(action.mDestId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - connectOk = true; - proxyPort = dpd->mConnectLogic.getProxyPortChoice(); - if (proxyPort) - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Using ProxyPort. Checking ConnectLogic.NetState: "; - std::cerr << dpd->mConnectLogic.calcNetState(mNetMgr->getNetworkMode(), - mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode()); - std::cerr << std::endl; -#endif - - exclusivePort = (CSB_NETSTATE_EXCLUSIVENAT == dpd->mConnectLogic.calcNetState( - mNetMgr->getNetworkMode(), mNetMgr->getNatHoleMode(), mNetMgr->getNatTypeMode())); - - if (exclusivePort) - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: NetState indicates Exclusive Mode"; - std::cerr << std::endl; -#endif - } - } - } - else - { - std::cerr << "PeerAction: Connect Proxy: ERROR Cannot find PeerStatus"; - std::cerr << std::endl; - } - } -#ifdef RS_USE_DHT_STUNNER - uint8_t extStable = 0; - - UdpStunner *stunner = mProxyStunner; - if (!proxyPort) - { - stunner = mDhtStunner; - } - - - - if ((connectOk) && (stunner) && (stunner->externalAddr(extaddr, extStable))) - { - if (extStable) - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Proxy Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " is OkGo as we have Stable Own External Proxy Address"; - std::cerr << std::endl; -#endif - - /* check if we require exclusive use of the proxy port */ - if (exclusivePort) - { - int stun_age = mProxyStunner->grabExclusiveMode(pid); - if (stun_age > 0) - { - int delay = 0; - if (stun_age < MIN_DETERMINISTIC_SWITCH_PERIOD) - { - delay = MIN_DETERMINISTIC_SWITCH_PERIOD - stun_age; - } - -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Stunner has indicated a Delay of " << delay; - std::cerr << " to ensure a stable Port!"; - std::cerr << std::endl; -#endif - - /* great we got it! */ - connAddr = extaddr; - connDelay = delay; - doConnectionRequest = true; - grabbedExclusivePort = true; - } - else - { - /* failed to get exclusive mode - must wait */ - connectionReqFailed = true; - failReason = CSB_UPDATE_RETRY_ATTEMPT; - } - } - else - { - /* stable and non-exclusive - go for it */ - connAddr = extaddr; - connStart = 1; - doConnectionRequest = true; - } - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: WARNING Proxy Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " is Discarded, as Own External Proxy Address is Not Stable!"; - std::cerr << std::endl; -#endif - - connectionReqFailed = true; - if (exclusivePort) - { - failReason = CSB_UPDATE_RETRY_ATTEMPT; -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: As Exclusive Mode, Port Will stabilise => RETRY"; - std::cerr << std::endl; -#endif - - } - else - { - failReason = CSB_UPDATE_MODE_UNAVAILABLE; -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Not Exclusive Mode, => MODE UNAVAILABLE"; - std::cerr << std::endl; -#endif - } - } - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: ERROR Proxy Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " is Discarded, as Failed to get Own External Proxy Address."; - std::cerr << std::endl; -#endif - - connectionReqFailed = true; - failReason = CSB_UPDATE_RETRY_ATTEMPT; - } -#else // RS_USE_DHT_STUNNER - connectionReqFailed = true; - failReason = CSB_UPDATE_RETRY_ATTEMPT; - (void) connectOk; -#endif //RS_USE_DHT_STUNNER - } - - if (doConnectionRequest) - { - if (mUdpBitDht->ConnectionRequest(&connAddr, &(action.mDestId.id), action.mMode, connDelay, connStart)) - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " has gone ahead"; - std::cerr << std::endl; -#endif - - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(action.mDestId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - dpd->mPeerReqStatusMsg = "Connect Request"; - dpd->mPeerReqState = RsDhtPeerRequest::RUNNING; - dpd->mPeerReqMode = action.mMode; - dpd->mPeerReqTS = now; - - if (grabbedExclusivePort) - { - dpd->mExclusiveProxyLock = true; - } - } - else - { - std::cerr << "PeerAction: Connect ERROR Cannot find PeerStatus"; - std::cerr << std::endl; - } - } - else - { - connectionReqFailed = true; - failReason = CSB_UPDATE_MODE_UNAVAILABLE; - } - } - - if (connectionReqFailed) - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction: Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " is Discarded, as Mode is Unavailable"; - std::cerr << std::endl; -#endif - - //if (grabbedExclusivePort) - //{ - // mProxyStunner->releaseExclusiveMode(pid,false); - //} - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(action.mDestId.id), RsDhtPeerType::FRIEND); - if (dpd) - { - dpd->mConnectLogic.updateCb(failReason); - - dpd->mPeerReqStatusMsg = "Req Mode Unavailable"; - dpd->mPeerReqState = RsDhtPeerRequest::STOPPED; - dpd->mPeerReqMode = action.mMode; - dpd->mPeerReqTS = now; - - if (grabbedExclusivePort) - { - ReleaseProxyExclusiveMode_locked(dpd, false); - } - } - else - { - std::cerr << "PeerAction: ERROR Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " has no Internal Dht Peer!"; - std::cerr << std::endl; - - if (grabbedExclusivePort) - { - std::cerr << "PeerAction: ERROR ERROR, we grabd Exclusive Port to do this, trying emergency release"; - std::cerr << std::endl; -#ifdef RS_USE_DHT_STUNNER - mProxyStunner->releaseExclusiveMode(pid,false); -#endif // RS_USE_DHT_STUNNER - } - } - } - - } - break; - - case PEERNET_ACTION_TYPE_AUTHORISE: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. Authorise Connection between: "; - bdStdPrintId(std::cerr, &(action.mSrcId)); - std::cerr << " and "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << " delay/bandwidth: " << action.mDelayOrBandwidth; - std::cerr << std::endl; -#endif - - int delay = 0; - int bandwidth = 0; - if (action.mMode == BITDHT_CONNECT_MODE_RELAY) - { - bandwidth = action.mDelayOrBandwidth; - } - else - { - delay = action.mDelayOrBandwidth; - } - - mUdpBitDht->ConnectionAuth(&(action.mSrcId), &(action.mProxyId), &(action.mDestId), - action.mMode, action.mPoint, bandwidth, delay, action.mAnswer); - - // Only feedback to the gui if we are at END. - if (action.mPoint == BD_PROXY_CONNECTION_END_POINT) - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(action.mSrcId.id), RsDhtPeerType::ANY); - if (dpd) - { - if (action.mAnswer) - { - dpd->mPeerCbMsg = "WE DENIED AUTH: ERROR : "; - dpd->mPeerCbMsg += decodeConnectionError(action.mAnswer); - } - else - { - dpd->mPeerCbMsg = "We AUTHED"; - } - dpd->mPeerCbMode = action.mMode; - dpd->mPeerCbPoint = action.mPoint; - dpd->mPeerCbProxyId = action.mProxyId; - dpd->mPeerCbDestId = action.mSrcId; - dpd->mPeerCbTS = now; - } - // Not an error if AUTH_DENIED - cos we don't know them! (so won't be in peerList). - else if (action.mAnswer | BITDHT_CONNECT_ERROR_AUTH_DENIED) - { -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction Authorise Connection "; - std::cerr << "Denied Unknown Peer"; - std::cerr << std::endl; -#endif - } - else - { - std::cerr << "PeerAction Authorise Connection "; - std::cerr << "ERROR Unknown Peer & !DENIED ???"; - std::cerr << std::endl; - } - } - } - break; - - case PEERNET_ACTION_TYPE_START: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. Start Connection between: "; - bdStdPrintId(std::cerr, &(action.mSrcId)); - std::cerr << " and "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << " delay/bandwidth: " << action.mDelayOrBandwidth; - std::cerr << std::endl; -#endif - - initiateConnection(&(action.mSrcId), &(action.mProxyId), &(action.mDestId), - action.mMode, action.mPoint, action.mDelayOrBandwidth); - } - break; - - case PEERNET_ACTION_TYPE_RESTARTREQ: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. Restart Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << std::endl; -#endif - - struct sockaddr_in laddr; - sockaddr_clear(&laddr); - uint32_t start = 1; - uint32_t delay = 0; - - mUdpBitDht->ConnectionRequest(&laddr, &(action.mDestId.id), action.mMode, delay, start); - } - break; - - case PEERNET_ACTION_TYPE_KILLREQ: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. Kill Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << std::endl; -#endif - - struct sockaddr_in laddr; - sockaddr_clear(&laddr); - uint32_t start = 0; - uint32_t delay = 0; - - mUdpBitDht->ConnectionRequest(&laddr, &(action.mDestId.id), action.mMode, delay, start); - } - break; - - case PEERNET_ACTION_TYPE_TCPATTEMPT: - { - /* connect attempt */ -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. TCP Connection Attempt to: "; - bdStdPrintId(std::cerr, &(action.mDestId)); - std::cerr << " mode: " << action.mMode; - std::cerr << std::endl; -#endif - - RsPeerId peerRsId; - bool foundPeerId = false; - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(action.mDestId.id), RsDhtPeerType::ANY); - if (dpd) - { - peerRsId = dpd->mRsId; - foundPeerId = true; -#ifdef DEBUG_PEERNET - std::cerr << "PeerAction. TCP Connection Attempt. DoingCallback for RsID: "; - std::cerr << peerRsId; - std::cerr << std::endl; -#endif - } - else - { - std::cerr << "PeerAction. TCP Connection Attempt. ERROR unknown peer"; - std::cerr << std::endl; - } - } - - if (foundPeerId) - { - ConnectCalloutTCPAttempt(peerRsId, action.mDestId.addr); - } - } - break; - } - } - return 1; -} - - - - - -/****************************** Connection Logic ***************************/ - -/* Proxies!. - * - * We can allow all PROXY connections, as it is just a couple of messages, - * however, we should be smart about how many RELAY connections are allowed. - * - * e.g. Allow 20 Relay connections. - * 15 for friends, 5 for randoms. - * - * Can also validate addresses with own secure connections. - */ - -int p3BitDht::checkProxyAllowed(const bdId *srcId, const bdId *destId, int mode, uint32_t &bandwidth) -{ -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkProxyAllowed()"; - std::cerr << std::endl; -#endif - - // Dont think that a mutex is required here! But might be so just lock to ensure that it is possible. - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - } - - if (mode == BITDHT_CONNECT_MODE_PROXY) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkProxyAllowed() Allowing all PROXY connections, OKAY"; - std::cerr << std::endl; -#endif - - bandwidth = 0; // unlimited as p2p. - return 1; - //return CONNECTION_OKAY; - } - - if (mode != BITDHT_CONNECT_MODE_RELAY) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkProxyAllowed() unknown Connect Mode DENIED"; - std::cerr << std::endl; -#endif - return 0; - } - - /* will install the Relay Here... so that we reserve the Relay Space for later. - * decide on relay bandwidth limitation as well - */ - if (RelayHandler_InstallRelayConnection(srcId, destId, mode, bandwidth)) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkProxyAllowed() Successfully added Relay, Connection OKAY"; - std::cerr << std::endl; -#endif - - return 1; - // CONNECT_OKAY. - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkProxyAllowed() Failed to install Relay, Connection DENIED"; - std::cerr << std::endl; -#endif - - return 0; - //return CONNECT_MODE_OVERLOADED; - } - - return 0; - //return CONNECT_MODE_NOTAVAILABLE; - //return CONNECT_MODE_OVERLOADED; -} - - -int p3BitDht::checkConnectionAllowed(const bdId *peerId, int mode) -{ - (void) mode; - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkConnectionAllowed() to: "; - bdStdPrintId(std::cerr,peerId); - std::cerr << " mode: " << mode; - std::cerr << std::endl; -#endif - - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - rstime_t now = time(NULL); - - /* check if they are in our friend list */ - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerId->id), RsDhtPeerType::FRIEND); - if (!dpd) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::checkConnectionAllowed() Peer Not Friend, DENIED"; - std::cerr << std::endl; -#endif - - /* store as failed connection attempt */ - std::map::iterator it; - it = mFailedPeers.find(peerId->id); - if (it == mFailedPeers.end()) - { - mFailedPeers[peerId->id] = DhtPeerDetails(); - it = mFailedPeers.find(peerId->id); - } - - /* flag as failed */ - it->second.mDhtId = *peerId; - it->second.mDhtState = RsDhtPeerDht::NOT_ACTIVE; - it->second.mDhtUpdateTS = now; - - it->second.mPeerType = RsDhtPeerType::OTHER; - it->second.mPeerCbMsg = "Denied Non-Friend"; - - it->second.mPeerReqStatusMsg = "Denied Non-Friend"; - it->second.mPeerReqState = RsDhtPeerRequest::STOPPED; - it->second.mPeerReqTS = now; - it->second.mPeerReqMode = 0; - //it->second.mPeerProxyId; - it->second.mPeerReqTS = now; - - it->second.mPeerCbMsg = "Denied Non-Friend"; - - it->second.mPeerConnectMsg = "Denied Non-Friend"; - it->second.mPeerConnectState = RsDhtPeerConnectState::DISCONNECTED; - - - return 0; - //return NOT_FRIEND; - } - - /* are a friend */ - - if (dpd->mPeerConnectState == RsDhtPeerConnectState::CONNECTED) - { - std::cerr << "p3BitDht::checkConnectionAllowed() ERROR Peer Already Connected, DENIED"; - std::cerr << std::endl; - - // STATUS UPDATE DONE IN ACTION. - //it->second.mPeerStatusMsg = "2nd Connection Attempt!"; - //it->second.mPeerUpdateTS = now; - return 0; - //return ALREADY_CONNECTED; - } - - return 1; - //return CONNECTION_OKAY; -} - - - - - -/* So initiateConnection has to call out to other bits of RS. - * critical information is: - * Peer RsId, Peer Address, Connect Mode (includes Proxy/OrNot). - - * - * What do we need: ACTIVE / PASSIVE / UNSPEC - * + Min Delay Time, - */ - - -void p3BitDht::ConnectCalloutTCPAttempt(const RsPeerId &peerId, struct sockaddr_in raddrv4) -{ - struct sockaddr_storage raddr; - struct sockaddr_storage proxyaddr; - struct sockaddr_storage srcaddr; - - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(srcaddr); - - struct sockaddr_in *rap = (struct sockaddr_in *) &raddr; - //struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr; - //struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr; - - // only one to translate - rap->sin_family = AF_INET; - rap->sin_addr = raddrv4.sin_addr; - rap->sin_port = raddrv4.sin_port; - - uint32_t source = RS_CB_DHT; - uint32_t connectFlags = RS_CB_FLAG_ORDER_UNSPEC | RS_CB_FLAG_MODE_TCP; - uint32_t delay = 0; - uint32_t bandwidth = 0; - - mConnCb->peerConnectRequest(peerId, raddr, proxyaddr, srcaddr, source, connectFlags, delay, bandwidth); -} - - -void p3BitDht::ConnectCalloutDirectOrProxy(const RsPeerId &peerId, struct sockaddr_in raddrv4, uint32_t connectFlags, uint32_t delay) -{ - struct sockaddr_storage raddr; - struct sockaddr_storage proxyaddr; - struct sockaddr_storage srcaddr; - - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(srcaddr); - - struct sockaddr_in *rap = (struct sockaddr_in *) &raddr; -// struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr; -// struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr; - - // only one to translate - rap->sin_family = AF_INET; - rap->sin_addr = raddrv4.sin_addr; - rap->sin_port = raddrv4.sin_port; - - uint32_t source = RS_CB_DHT; - uint32_t bandwidth = 0; - - mConnCb->peerConnectRequest(peerId, raddr, proxyaddr, srcaddr, source, connectFlags, delay, bandwidth); -} - -void p3BitDht::ConnectCalloutRelay(const RsPeerId &peerId, - struct sockaddr_in srcaddrv4, struct sockaddr_in proxyaddrv4, struct sockaddr_in destaddrv4, - uint32_t connectFlags, uint32_t bandwidth) -{ - struct sockaddr_storage destaddr; - struct sockaddr_storage proxyaddr; - struct sockaddr_storage srcaddr; - - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(srcaddr); - - struct sockaddr_in *dap = (struct sockaddr_in *) &destaddr; - struct sockaddr_in *pap = (struct sockaddr_in *) &proxyaddr; - struct sockaddr_in *sap = (struct sockaddr_in *) &srcaddr; - - dap->sin_family = AF_INET; - dap->sin_addr = destaddrv4.sin_addr; - dap->sin_port = destaddrv4.sin_port; - - pap->sin_family = AF_INET; - pap->sin_addr = proxyaddrv4.sin_addr; - pap->sin_port = proxyaddrv4.sin_port; - - sap->sin_family = AF_INET; - sap->sin_addr = srcaddrv4.sin_addr; - sap->sin_port = srcaddrv4.sin_port; - - uint32_t source = RS_CB_DHT; - uint32_t delay = 0; - - mConnCb->peerConnectRequest(peerId, destaddr, proxyaddr, srcaddr, source, connectFlags, delay, bandwidth); -} - - - - -//virtual void peerConnectRequest(std::string id, struct sockaddr_in raddr, -// struct sockaddr_in proxyaddr, struct sockaddr_in srcaddr, -// uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0; - - -void p3BitDht::initiateConnection(const bdId *srcId, const bdId *proxyId, const bdId *destId, - uint32_t mode, uint32_t loc, uint32_t delayOrBandwidth) -{ -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::initiateConnection()"; - std::cerr << std::endl; - std::cerr << "\t srcId: "; - bdStdPrintId(std::cerr, srcId); - std::cerr << std::endl; - - std::cerr << "\t proxyId: "; - bdStdPrintId(std::cerr, proxyId); - std::cerr << std::endl; - - std::cerr << "\t destId: "; - bdStdPrintId(std::cerr, destId); - std::cerr << std::endl; - - std::cerr << "\t Mode: " << mode << " loc: " << loc; - std::cerr << std::endl; - std::cerr << "\t DelayOrBandwidth: " << delayOrBandwidth; - std::cerr << std::endl; -#endif - - bdId peerConnectId; - - uint32_t connectFlags = 0; - - uint32_t delay = 0; - uint32_t bandwidth = 0; - - /* determine who the actual destination is. - * as we always specify the remote address, this is all we need. - */ - if (loc == BD_PROXY_CONNECTION_START_POINT) - { - peerConnectId = *destId; - /* lowest is active */ - if (srcId < destId) - { - connectFlags |= RS_CB_FLAG_ORDER_ACTIVE; - } - else - { - connectFlags |= RS_CB_FLAG_ORDER_PASSIVE; - } - } - else if (loc == BD_PROXY_CONNECTION_END_POINT) - { - peerConnectId = *srcId; - /* lowest is active (we are now dest - in this case) */ - if (destId < srcId) - { - connectFlags |= RS_CB_FLAG_ORDER_ACTIVE; - } - else - { - connectFlags |= RS_CB_FLAG_ORDER_PASSIVE; - } - } - else - { - std::cerr << "p3BitDht::initiateConnection() ERROR, NOT either START or END"; - std::cerr << std::endl; - /* ERROR */ - return; - } - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::initiateConnection() Connecting to "; - bdStdPrintId(std::cerr, &peerConnectId); - std::cerr << std::endl; -#endif - -// uint32_t touConnectMode = 0; - RsPeerId rsId; - - { - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&(peerConnectId.id), RsDhtPeerType::FRIEND); - /* grab a socket */ - if (!dpd) - { - std::cerr << "p3BitDht::initiateConnection() ERROR Peer not found"; - std::cerr << std::endl; - return; - } - - if (dpd->mPeerConnectState != RsDhtPeerConnectState::DISCONNECTED) - { - std::cerr << "p3BitDht::initiateConnection() ERROR Peer is not Disconnected"; - std::cerr << std::endl; - return; - } - - rsId = dpd->mRsId; - - /* start the connection */ - /* These Socket Modes must match the TOU Stack - or it breaks. */ - switch(mode) - { - default: - case BITDHT_CONNECT_MODE_DIRECT: -// touConnectMode = RsDhtTouMode::DIRECT; - connectFlags |= RS_CB_FLAG_MODE_UDP_DIRECT; - delay = delayOrBandwidth; - break; - - case BITDHT_CONNECT_MODE_PROXY: - { - bool useProxyPort = dpd->mConnectLogic.getProxyPortChoice(); - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::initiateConnection() Peer Mode Proxy... deciding which port to use."; - std::cerr << " UseProxyPort? " << useProxyPort; - std::cerr << std::endl; -#endif - - delay = delayOrBandwidth; - if (useProxyPort) - { -// touConnectMode = RsDhtTouMode::PROXY; - connectFlags |= RS_CB_FLAG_MODE_UDP_PROXY; - } - else - { -// touConnectMode = RsDhtTouMode::DIRECT; - connectFlags |= RS_CB_FLAG_MODE_UDP_DIRECT; - } - - } - break; - - case BITDHT_CONNECT_MODE_RELAY: -// touConnectMode = RsDhtTouMode::RELAY; - connectFlags |= RS_CB_FLAG_MODE_UDP_RELAY; - bandwidth = delayOrBandwidth; - break; - } - - - dpd->mPeerConnectProxyId = *proxyId; - dpd->mPeerConnectPeerId = peerConnectId; - - - /* store results in Status */ - dpd->mPeerConnectMsg = "UDP started"; - dpd->mPeerConnectState = RsDhtPeerConnectState::UDP_STARTED; - dpd->mPeerConnectUdpTS = time(NULL); - dpd->mPeerConnectMode = mode; - dpd->mPeerConnectPoint = loc; - } - - /* finally we call out to start the connection (Outside of Mutex) */ - - if ((mode == BITDHT_CONNECT_MODE_DIRECT) || (mode == BITDHT_CONNECT_MODE_PROXY)) - { - ConnectCalloutDirectOrProxy(rsId, peerConnectId.addr, connectFlags, delay); - } - else if (mode == BITDHT_CONNECT_MODE_RELAY) - { - if (loc == BD_PROXY_CONNECTION_START_POINT) - { - ConnectCalloutRelay(rsId, srcId->addr, proxyId->addr, destId->addr, connectFlags, bandwidth); - } - else // END_POINT - { - /* reverse order connection call */ - ConnectCalloutRelay(rsId, destId->addr, proxyId->addr, srcId->addr, connectFlags, bandwidth); - } - } - - -} - - -int p3BitDht::installRelayConnection(const bdId *srcId, const bdId *destId, uint32_t &bandwidth) -{ - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - /* work out if either srcId or DestId is a friend */ - int relayClass = UDP_RELAY_CLASS_GENERAL; - -#ifdef DEBUG_PEERNET - RsPeerId strId1; - bdStdPrintNodeId(strId1, &(srcId->id), false); - - RsPeerId strId2; - bdStdPrintNodeId(strId2, &(destId->id), false); -#endif - - /* grab a socket */ - DhtPeerDetails *dpd_src = findInternalDhtPeer_locked(&(srcId->id), RsDhtPeerType::ANY); - DhtPeerDetails *dpd_dest = findInternalDhtPeer_locked(&(destId->id), RsDhtPeerType::ANY); - - if ((dpd_src) && (dpd_src->mPeerType == RsDhtPeerType::FRIEND)) - { - relayClass = UDP_RELAY_CLASS_FRIENDS; - } - else if ((dpd_dest) && (dpd_dest->mPeerType == RsDhtPeerType::FRIEND)) - { - relayClass = UDP_RELAY_CLASS_FRIENDS; - } - else if ((dpd_src) && (dpd_src->mPeerType == RsDhtPeerType::FOF)) - { - relayClass = UDP_RELAY_CLASS_FOF; - } - else if ((dpd_dest) && (dpd_dest->mPeerType == RsDhtPeerType::FOF)) - { - relayClass = UDP_RELAY_CLASS_FOF; - } - else - { - relayClass = UDP_RELAY_CLASS_GENERAL; - } - - /* will install the Relay Here... so that we reserve the Relay Space for later. */ - UdpRelayAddrSet relayAddrs(&(srcId->addr), &(destId->addr)); - if (mRelay->addUdpRelay(&relayAddrs, relayClass, bandwidth)) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::installRelayConnection() Successfully added Relay, Connection OKAY"; - std::cerr << std::endl; -#endif - - return 1; - // CONNECT_OKAY. - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::installRelayConnection() Failed to install Relay, Connection DENIED"; - std::cerr << std::endl; -#endif - - return 0; - //return CONNECT_MODE_OVERLOADED; - } - return 0; -} - - -int p3BitDht::removeRelayConnection(const bdId *srcId, const bdId *destId) -{ - //RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - - UdpRelayAddrSet relayAddrs(&(srcId->addr), &(destId->addr)); - if (mRelay->removeUdpRelay(&relayAddrs)) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::removeRelayConnection() Successfully removed Relay"; - std::cerr << std::endl; -#endif - - return 1; - } - else - { - std::cerr << "p3BitDht::removeRelayConnection() ERROR Failed to remove Relay"; - std::cerr << std::endl; - - return 0; - } -} - -/***************************************************** UDP Connections *****************************/ - - -void p3BitDht::monitorConnections() -{ - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - rstime_t now = time(NULL); - - std::map::iterator it; - - for(it = mPeers.begin(); it != mPeers.end(); ++it) - { - /* ignore ones which aren't friends */ - if (it->second.mPeerType != RsDhtPeerType::FRIEND) - { - continue; - } - - if (it->second.mPeerConnectState == RsDhtPeerConnectState::UDP_STARTED) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::monitorConnections() Connection in progress to: "; - - bdStdPrintNodeId(std::cerr, &(it->second.mDhtId.id)); - std::cerr << std::endl; -#endif - - if (now - it->second.mPeerConnectUdpTS > PEERNET_CONNECT_TIMEOUT) - { - /* This CAN happen ;( */ -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::monitorConnections() WARNING InProgress Connection Failed: "; - bdStdPrintNodeId(std::cerr, &(it->second.mDhtId.id)); - std::cerr << std::endl; -#endif - - UdpConnectionFailed_locked(&(it->second)); - } - } - } -} - - - - -void p3BitDht::Feedback_Connected(const RsPeerId& pid) -{ - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - DhtPeerDetails *dpd = findInternalRsPeer_locked(pid); - - if (!dpd) - { - /* ERROR */ - std::cerr << "p3BitDht::Feedback_Connected() ERROR peer not found: " << pid; - std::cerr << std::endl; - - return; - } - - /* sanity checking */ - if (dpd->mPeerConnectState != RsDhtPeerConnectState::UDP_STARTED) - { - /* ERROR */ - std::cerr << "p3BitDht::Feedback_Connected() ERROR not in UDP_STARTED mode for: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; - - return; - } - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::monitorConnections() InProgress Connection Now Active: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - /* switch state! */ - dpd->mPeerConnectState = RsDhtPeerConnectState::CONNECTED; - dpd->mPeerConnectTS = time(NULL); - - dpd->mConnectLogic.updateCb(CSB_UPDATE_CONNECTED); - - rs_sprintf(dpd->mPeerConnectMsg, "Connected in %ld secs", dpd->mPeerConnectTS - dpd->mPeerConnectUdpTS); - - // Remove the Connection Request. - if (dpd->mPeerReqState == RsDhtPeerRequest::RUNNING) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::monitorConnections() Request Active, Stopping Request"; - std::cerr << std::endl; -#endif - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_KILLREQ; - ca.mMode = dpd->mPeerConnectMode; - //ca.mProxyId = *proxyId; - //ca.mSrcId = *srcId; - ca.mDestId = dpd->mPeerConnectPeerId; - //ca.mPoint = point; - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - - mActions.push_back(ca); - - // What the Action should do... - //struct sockaddr_in tmpaddr; - //bdsockaddr_clear(&tmpaddr); - //int start = 0; - //mUdpBitDht->ConnectionRequest(&tmpaddr, &(it->second.mPeerConnectPeerId.id), it->second.mPeerConnectMode, start); - } - // only an error if we initiated the connection. - else if (dpd->mPeerConnectPoint == BD_PROXY_CONNECTION_START_POINT) - { - std::cerr << "p3BitDht::monitorConnections() ERROR Request not active, can't stop"; - std::cerr << std::endl; - } - - ReleaseProxyExclusiveMode_locked(dpd, true); -} - -void p3BitDht::Feedback_ConnectionFailed(const RsPeerId& pid) -{ - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - DhtPeerDetails *dpd = findInternalRsPeer_locked(pid); - - if (!dpd) - { - /* ERROR */ - std::cerr << "p3BitDht::Feedback_Connected() ERROR peer not found: " << pid; - std::cerr << std::endl; - - return; - } - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::Feedback_ConnectionFailed() UDP Connection Failed: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - return UdpConnectionFailed_locked(dpd); -} - -void p3BitDht::Feedback_ConnectionClosed(const RsPeerId& pid) -{ - RsStackMutex stack(dhtMtx); /********** LOCKED MUTEX ***************/ - DhtPeerDetails *dpd = findInternalRsPeer_locked(pid); - - if (!dpd) - { - /* ERROR */ - std::cerr << "p3BitDht::Feedback_Connected() ERROR peer not found: " << pid; - std::cerr << std::endl; - - return; - } - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::Feedback_ConnectionClosed() Active Connection Closed: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - return UdpConnectionFailed_locked(dpd); -} - - -void p3BitDht::UdpConnectionFailed_locked(DhtPeerDetails *dpd) -{ - if (dpd->mPeerConnectState == RsDhtPeerConnectState::UDP_STARTED) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::UdpConnectionFailed_locked() UDP Connection Failed: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - /* shut it down */ - - /* ONLY need to update ConnectLogic - if it was our Attempt Running */ - if (dpd->mPeerReqState == RsDhtPeerRequest::RUNNING) - { - dpd->mConnectLogic.updateCb(CSB_UPDATE_FAILED_ATTEMPT); - } - dpd->mPeerConnectState = RsDhtPeerConnectState::DISCONNECTED; - dpd->mPeerConnectMsg = "UDP Failed"; - - } - else - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::UdpConnectionFailed_locked() Active Connection Closed: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - dpd->mConnectLogic.updateCb(CSB_UPDATE_DISCONNECTED); - - dpd->mPeerConnectState = RsDhtPeerConnectState::DISCONNECTED; - dpd->mPeerConnectClosedTS = time(NULL); - rs_sprintf(dpd->mPeerConnectMsg, "Closed, Alive for: %ld secs", dpd->mPeerConnectClosedTS - dpd->mPeerConnectTS); - } - - - - if (dpd->mPeerReqState == RsDhtPeerRequest::RUNNING) - { -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::UdpConnectionFailed_locked() "; - std::cerr << "Request Active (Paused)... Killing for next Attempt"; - std::cerr << std::endl; -#endif - - /* Push Back PeerAction */ - PeerAction ca; - ca.mType = PEERNET_ACTION_TYPE_KILLREQ; - ca.mMode = dpd->mPeerConnectMode; - //ca.mProxyId = *proxyId; - //ca.mSrcId = *srcId; - ca.mDestId = dpd->mPeerConnectPeerId; - //ca.mPoint = point; - ca.mAnswer = BITDHT_CONNECT_ERROR_NONE; - - mActions.push_back(ca); - } - // only an error if we initiated the connection. - else if (dpd->mPeerConnectPoint == BD_PROXY_CONNECTION_START_POINT) - { - std::cerr << "p3BitDht::UdpConnectionFailed_locked() "; - std::cerr << "ERROR Request not active, can't stop"; - std::cerr << std::endl; - } - - ReleaseProxyExclusiveMode_locked(dpd, true); -} - - - -void p3BitDht::ReleaseProxyExclusiveMode_locked(DhtPeerDetails *dpd, bool addrChgLikely) -{ -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked()"; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - /* translate id into string for exclusive mode */ - std::string pid; - bdStdPrintNodeId(pid, &(dpd->mDhtId.id), false); - - - if (dpd->mExclusiveProxyLock) - { -#ifdef RS_USE_DHT_STUNNER - if (mProxyStunner->releaseExclusiveMode(pid, addrChgLikely)) - { - dpd->mExclusiveProxyLock = false; - -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked() Lock released by Connection to peer: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - } - else -#else // RS_USE_DHT_STUNNER - (void)addrChgLikely; -#endif // RS_USE_DHT_STUNNER - { - dpd->mExclusiveProxyLock = false; - - std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked() ERROR ProxyStunner is not Locked"; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; - } - - } - else - { -#ifdef DEBUG_BITDHT_COMMON - std::cerr << "p3BitDht::ReleaseProxyExclusiveMode_locked() Don't Have a Lock"; - std::cerr << std::endl; -#endif - } - -} - - -void p3BitDht::ConnectionFeedback(const RsPeerId& pid, int mode) -{ -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ConnectionFeedback() peer: " << pid; - std::cerr << " mode: " << mode; - std::cerr << std::endl; -#endif - - switch(mode) - { - case NETMGR_DHT_FEEDBACK_CONNECTED: -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ConnectionFeedback() HAVE CONNECTED (tcp?/udp) to peer: " << pid; - std::cerr << std::endl; -#endif - - Feedback_Connected(pid); - break; - - case NETMGR_DHT_FEEDBACK_CONN_FAILED: -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ConnectionFeedback() UDP CONNECTION FAILED to peer: " << pid; - std::cerr << std::endl; -#endif - Feedback_ConnectionFailed(pid); - break; - - case NETMGR_DHT_FEEDBACK_CONN_CLOSED: -#ifdef DEBUG_PEERNET - std::cerr << "p3BitDht::ConnectionFeedback() CONNECTION (tcp?/udp) CLOSED to peer: " << pid; - std::cerr << std::endl; -#endif - Feedback_ConnectionClosed(pid); - break; - } -} - - -/***** Check for a RelayHandler... and call its functions preferentially */ - -int p3BitDht::RelayHandler_LogFailedProxyAttempt(const bdId *srcId, const bdId *destId, uint32_t mode, uint32_t errcode) -{ - - { - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - if ((mRelayHandler) && (mRelayHandler->mLogFailedConnection)) - { - return mRelayHandler->mLogFailedConnection(srcId, destId, mode, errcode); - } - } - - /* NO standard handler */ - return 0; -} - - -int p3BitDht::RelayHandler_InstallRelayConnection(const bdId *srcId, const bdId *destId, - uint32_t mode, uint32_t &bandwidth) -{ - - { - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - if ((mRelayHandler) && (mRelayHandler->mInstallRelay)) - { - return mRelayHandler->mInstallRelay(srcId, destId, mode, bandwidth); - } - } - - /* standard handler */ - return installRelayConnection(srcId, destId, bandwidth); -} - - - - - diff --git a/libretroshare/src/dht/p3bitdht_peers.cc b/libretroshare/src/dht/p3bitdht_peers.cc deleted file mode 100644 index 013a9b47c..000000000 --- a/libretroshare/src/dht/p3bitdht_peers.cc +++ /dev/null @@ -1,752 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht_peernet.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2010 by Robert Fernie. * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "dht/p3bitdht.h" - -#include "bitdht/bdstddht.h" - -#include "tcponudp/udprelay.h" -#include "tcponudp/udpstunner.h" - -#include - -/*** - * - * #define DEBUG_BITDHT 1 - * #define DEBUG_BITDHT_TRANSLATE 1 - * - **/ - -/****************************************************************************************** - ********************************* Existing Interface ************************************* - ******************************************************************************************/ - /* pqiNetAssistConnect - external interface functions */ - /* add / remove peers */ -/***** - * At the moment, findPeer, dropPeer are the only way that peer info enters the dht. - * This will obviously change, and we will have a list of Friends and FoF, - * but for now we need to expect that this function will add unknown pids. - * - */ -#define USE_OLD_DHT_INTERFACE 1 - - -bool p3BitDht::findPeer(const RsPeerId& pid) -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer(" << pid << ")"; - std::cerr << std::endl; -#endif - bdNodeId nid; - - { - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - DhtPeerDetails *dpd = findInternalRsPeer_locked(pid); - if (!dpd) - { - dpd = addInternalPeer_locked(pid, RsDhtPeerType::FRIEND); - if (!dpd) - { - /* ERROR */ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() ERROR installing InternalPeer"; - std::cerr << std::endl; -#endif - return false; - } - - /* new entry... what do we need to set? */ - dpd->mDhtState = RsDhtPeerDht::SEARCHING; - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() Installed new DhtPeer with pid => NodeId: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - } - else - { - /* old entry */ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() Reactivating DhtPeer with pid => NodeId: "; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - - if (dpd->mDhtState != RsDhtPeerDht::NOT_ACTIVE) - { -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() WARNING DhtState is Already Active!"; - bdStdPrintNodeId(std::cerr, &(dpd->mDhtId.id)); - std::cerr << std::endl; -#endif - } - else - { - /* flag as searching */ - dpd->mDhtState = RsDhtPeerDht::SEARCHING; -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() Marking Old Peer as SEARCHING"; - std::cerr << std::endl; -#endif - } - - } - - nid = dpd->mDhtId.id; - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::findPeer() calling AddFindNode() with pid => NodeId: "; - bdStdPrintNodeId(std::cerr, &nid); - std::cerr << std::endl; -#endif - - } - - /* add in peer */ - mUdpBitDht->addFindNode(&nid, BITDHT_QFLAGS_DO_IDLE | BITDHT_QFLAGS_UPDATES); - - return true ; -} - -bool p3BitDht::dropPeer(const RsPeerId& pid) -{ -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::dropPeer(" << pid << ")"; - std::cerr << std::endl; -#endif - - bdNodeId nid; - - { - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - DhtPeerDetails *dpd = findInternalRsPeer_locked(pid); - if (!dpd) - { -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::dropPeer(" << pid << ") HACK TO INCLUDE FRIEND AS NON-ACTIVE PEER"; - std::cerr << std::endl; -#endif - - //addFriend(pid); - dpd = addInternalPeer_locked(pid, RsDhtPeerType::FOF); - - return false; - } - - /* flag as searching */ - dpd->mDhtState = RsDhtPeerDht::NOT_ACTIVE; - - nid = dpd->mDhtId.id; - -#ifdef DEBUG_BITDHT - std::cerr << "p3BitDht::dropPeer() calling removeFindNode() with pid => NodeId: "; - bdStdPrintNodeId(std::cerr, &nid); - std::cerr << std::endl; -#endif - } - - /* remove in peer */ - mUdpBitDht->removeFindNode(&nid); - - /* not removing from translation */ - - return true ; -} - - -/****************************************************************************************** - ********************************* Basic Peer Details ************************************* - ******************************************************************************************/ - -int p3BitDht::addBadPeer( const sockaddr_storage &addr, uint32_t /*reason*/, - uint32_t /*flags*/, uint32_t /*age*/ ) -{ - //mUdpBitDht->updateKnownPeer(&id, 0, bdflags); - - sockaddr_in addrv4; - sockaddr_storage tmpaddr; - sockaddr_storage_copy(addr, tmpaddr); - if(!sockaddr_storage_ipv6_to_ipv4(tmpaddr)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!" - << std::endl; - sockaddr_storage_dump(addr); - print_stacktrace(); - return -EINVAL; - } - - struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr; - - // convert. - addrv4.sin_family = ap->sin_family; - addrv4.sin_addr = ap->sin_addr; - addrv4.sin_port = ap->sin_port; - -#ifdef RS_USE_DHT_STUNNER - if (mDhtStunner) - { - mDhtStunner->dropStunPeer(addrv4); - } - if (mProxyStunner) - { - mProxyStunner->dropStunPeer(addrv4); - } -#endif // RS_USE_DHT_STUNNER - return 1; -} - - -int p3BitDht::addKnownPeer( const RsPeerId &pid, - const sockaddr_storage &addr, uint32_t flags ) -{ - sockaddr_in addrv4; - sockaddr_clear(&addrv4); - - sockaddr_storage tmpaddr; - sockaddr_storage_copy(addr, tmpaddr); - if( !sockaddr_storage_isnull(addr) && - !sockaddr_storage_ipv6_to_ipv4(tmpaddr) ) - { - std::cerr << __PRETTY_FUNCTION__ << " Error: got non IPv4 address!" - << std::endl; - sockaddr_storage_dump(addr); - print_stacktrace(); - return -EINVAL; - } - - // convert. - struct sockaddr_in *ap = (struct sockaddr_in *) &tmpaddr; - addrv4.sin_family = ap->sin_family; - addrv4.sin_addr = ap->sin_addr; - addrv4.sin_port = ap->sin_port; - - RsDhtPeerType p3type = RsDhtPeerType::ANY; - int bdflags = 0; - bdId id; - bool isOwnId = false; - - switch(flags & NETASSIST_KNOWN_PEER_TYPE_MASK) - { - default: - return 0; - break; - case NETASSIST_KNOWN_PEER_WHITELIST: - p3type = RsDhtPeerType::OTHER; - bdflags = BITDHT_PEER_STATUS_DHT_WHITELIST; - - break; - case NETASSIST_KNOWN_PEER_FOF: - p3type = RsDhtPeerType::FOF; - bdflags = BITDHT_PEER_STATUS_DHT_FOF; - - break; - case NETASSIST_KNOWN_PEER_FRIEND: - p3type = RsDhtPeerType::FRIEND; - bdflags = BITDHT_PEER_STATUS_DHT_FRIEND; - - break; - case NETASSIST_KNOWN_PEER_RELAY: - p3type = RsDhtPeerType::OTHER; - bdflags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER; - - break; - case NETASSIST_KNOWN_PEER_SELF: - p3type = RsDhtPeerType::OTHER; - bdflags = BITDHT_PEER_STATUS_DHT_SELF; - isOwnId = true; - - - break; - } - - if (flags & NETASSIST_KNOWN_PEER_ONLINE) - { - bdflags |= BD_FRIEND_ENTRY_ONLINE; - } - - if (!isOwnId) - { - RS_STACK_MUTEX(dhtMtx); - DhtPeerDetails *dpd = addInternalPeer_locked(pid, p3type); - - - if (bdflags & BD_FRIEND_ENTRY_ONLINE) - { - /* can we update the address? */ - //dpd->mDhtId.addr = addr; - } - - - id.id = dpd->mDhtId.id; - id.addr = addrv4; - } - else - { - // shouldn't use own id without mutex - but it is static! - id.id = mOwnDhtId; - id.addr = addrv4; - } - - mUdpBitDht->updateKnownPeer(&id, 0, bdflags); - - return 1; -} - - -/* Total duplicate of above function - can't be helped, should merge somehow */ -int p3BitDht::addKnownNode(const bdId *id, uint32_t flags) -{ - int bdflags = 0; - - switch(flags & NETASSIST_KNOWN_PEER_TYPE_MASK) - { - default: - return 0; - break; - case NETASSIST_KNOWN_PEER_WHITELIST: - bdflags = BITDHT_PEER_STATUS_DHT_WHITELIST; - - break; - case NETASSIST_KNOWN_PEER_FOF: - bdflags = BITDHT_PEER_STATUS_DHT_FOF; - - break; - case NETASSIST_KNOWN_PEER_FRIEND: - bdflags = BITDHT_PEER_STATUS_DHT_FRIEND; - - break; - case NETASSIST_KNOWN_PEER_RELAY: - bdflags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER; - - break; - case NETASSIST_KNOWN_PEER_SELF: - bdflags = BITDHT_PEER_STATUS_DHT_SELF; - - break; - } - - if (flags & NETASSIST_KNOWN_PEER_ONLINE) - { - bdflags |= BD_FRIEND_ENTRY_ONLINE; - } - - mUdpBitDht->updateKnownPeer(id, 0, bdflags); - - return 1; -} - - - -#if 0 -int p3BitDht::addFriend(const std::string pid) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - return (NULL != addInternalPeer_locked(pid, RsDhtPeerType::FRIEND)); -} - - -int p3BitDht::addFriendOfFriend(const std::string pid) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - return (NULL != addInternalPeer_locked(pid, RsDhtPeerType::FOF)); -} - - -int p3BitDht::addOther(const std::string pid) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - return (NULL != addInternalPeer_locked(pid, RsDhtPeerType::OTHER)); -} -#endif - - -int p3BitDht::removePeer(const RsPeerId& pid) -{ - RsStackMutex stack(dhtMtx); /********* LOCKED *********/ - - return removeInternalPeer_locked(pid); -} - - -/****************************************************************************************** - ********************************* Basic Peer Details ************************************* - ******************************************************************************************/ - -DhtPeerDetails *p3BitDht::addInternalPeer_locked(const RsPeerId& pid, RsDhtPeerType type) -{ - /* create the data structure */ - if (!havePeerTranslation_locked(pid)) - { - storeTranslation_locked(pid); - } - - bdNodeId id; - if (!lookupNodeId_locked(pid, &id)) - { - return 0; - } - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&id, RsDhtPeerType::ANY); - if (!dpd) - { - DhtPeerDetails newdpd; - - newdpd.mDhtId.id = id; - newdpd.mRsId = pid; - newdpd.mDhtState = RsDhtPeerDht::NOT_ACTIVE; - newdpd.mPeerType = RsDhtPeerType::ANY; - - mPeers[id] = newdpd; - dpd = findInternalDhtPeer_locked(&id, RsDhtPeerType::ANY); - - if(dpd == NULL) - { - std::cerr << "(EE) inconsistency error in p3BitDht::addInternalPeer_locked() Cannot find peer that was just added." << std::endl; - return NULL; - } - } - - /* what do we need to reset? */ - dpd->mPeerType = type; - - return dpd; -} - - -int p3BitDht::removeInternalPeer_locked(const RsPeerId& pid) -{ - bdNodeId id; - if (!lookupNodeId_locked(pid, &id)) - { - return 0; - } - - std::map::iterator it = mPeers.find(id); - if (it == mPeers.end()) - { - return 0; - } - - mPeers.erase(it); - - // remove the translation? - removeTranslation_locked(pid); - - return 1; -} - - -/* indexed by bdNodeId, as this is the more used call interface */ -DhtPeerDetails *p3BitDht::findInternalDhtPeer_locked(const bdNodeId *id, RsDhtPeerType type) -{ - std::map::iterator it = mPeers.find(*id); - if (it == mPeers.end()) - { - return NULL; - } - if (type != RsDhtPeerType::ANY) - { - if (it->second.mPeerType != type) - { - return NULL; - } - } - return &(it->second); -} - - -/* interface to get with alt id */ -DhtPeerDetails *p3BitDht::findInternalRsPeer_locked(const RsPeerId &pid) -{ - /* create the data structure */ - if (!havePeerTranslation_locked(pid)) - { - return NULL; - } - - bdNodeId id; - if (!lookupNodeId_locked(pid, &id)) - { - return NULL; - } - - DhtPeerDetails *dpd = findInternalDhtPeer_locked(&id,RsDhtPeerType::ANY); - - return dpd; -} - - -/****************************************************************************************** - *************************** Fundamental Node Translation ********************************* - ******************************************************************************************/ - -bool p3BitDht::havePeerTranslation_locked(const RsPeerId &pid) -{ -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::havePeerTranslation_locked() for : " << pid; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mTransToNodeId.find(pid); - if (it == mTransToNodeId.end()) - { -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::havePeerTranslation_locked() failed Missing translation"; - std::cerr << std::endl; -#endif - - return false; - } - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::havePeerTranslation_locked() Found NodeId: "; - bdStdPrintNodeId(std::cerr, &(it->second)); - std::cerr << std::endl; -#endif - - return true; -} - - -int p3BitDht::lookupNodeId_locked(const RsPeerId& pid, bdNodeId *id) -{ -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupNodeId_locked() for : " << pid; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mTransToNodeId.find(pid); - if (it == mTransToNodeId.end()) - { -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupNodeId_locked() failed"; - std::cerr << std::endl; -#endif - - return 0; - } - *id = it->second; - - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupNodeId_locked() Found NodeId: "; - bdStdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - - return 1; -} - - -int p3BitDht::lookupRsId_locked(const bdNodeId *id, RsPeerId&pid) -{ -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupRsId_locked() for : "; - bdStdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - - std::map::iterator nit; - nit = mTransToRsId.find(*id); - if (nit == mTransToRsId.end()) - { -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupRsId_locked() failed"; - std::cerr << std::endl; -#endif - - return 0; - } - pid = nit->second; - - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::lookupRsId_locked() Found Matching RsId: " << pid; - std::cerr << std::endl; -#endif - - return 1; -} - -int p3BitDht::storeTranslation_locked(const RsPeerId& pid) -{ -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::storeTranslation_locked(" << pid << ")"; - std::cerr << std::endl; -#endif - - bdNodeId nid; - calculateNodeId(pid, &nid); - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::storeTranslation_locked() Converts to NodeId: "; - bdStdPrintNodeId(std::cerr, &(nid)); - std::cerr << std::endl; -#endif - - mTransToNodeId[pid] = nid; - mTransToRsId[nid] = pid; - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::storeTranslation_locked() Success"; - std::cerr << std::endl; -#endif - - return 1; -} - -int p3BitDht::removeTranslation_locked(const RsPeerId& pid) -{ - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::removeTranslation_locked(" << pid << ")"; - std::cerr << std::endl; -#endif - - std::map::iterator it = mTransToNodeId.find(pid); - it = mTransToNodeId.find(pid); - if (it == mTransToNodeId.end()) - { - std::cerr << "p3BitDht::removeTranslation_locked() ERROR MISSING TransToNodeId"; - std::cerr << std::endl; - /* missing */ - return 0; - } - - bdNodeId nid = it->second; - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::removeTranslation_locked() Found Translation: NodeId: "; - bdStdPrintNodeId(std::cerr, &(nid)); - std::cerr << std::endl; -#endif - - - std::map::iterator nit; - nit = mTransToRsId.find(nid); - if (nit == mTransToRsId.end()) - { - std::cerr << "p3BitDht::removeTranslation_locked() ERROR MISSING TransToRsId"; - std::cerr << std::endl; - /* inconsistent!!! */ - return 0; - } - - mTransToNodeId.erase(it); - mTransToRsId.erase(nit); - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::removeTranslation_locked() SUCCESS"; - std::cerr << std::endl; -#endif - - return 1; -} - - -/* Adding a little bit of fixed text... - * This allows us to ensure that only compatible peers will find each other - */ - -const uint8_t RS_DHT_VERSION_LEN = 17; -const uint8_t rs_dht_version_data[RS_DHT_VERSION_LEN] = "RS_VERSION_0.5.1"; - -/******************** Conversion Functions **************************/ -int p3BitDht::calculateNodeId(const RsPeerId& pid, bdNodeId *id) -{ - /* generate node id from pid */ -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << "p3BitDht::calculateNodeId() " << pid; -#endif - - /* use a hash to make it impossible to reverse */ - - uint8_t sha_hash[SHA_DIGEST_LENGTH]; - memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ; - SHA_CTX *sha_ctx = new SHA_CTX; - SHA1_Init(sha_ctx); - - SHA1_Update(sha_ctx, rs_dht_version_data, RS_DHT_VERSION_LEN); - SHA1_Update(sha_ctx, pid.toByteArray(), RsPeerId::SIZE_IN_BYTES); - SHA1_Final(sha_hash, sha_ctx); - - for(int i = 0; i < SHA_DIGEST_LENGTH && (i < BITDHT_KEY_LEN); i++) - { - id->data[i] = sha_hash[i]; - } - delete sha_ctx; - -#ifdef DEBUG_BITDHT_TRANSLATE - std::cerr << " => "; - bdStdPrintNodeId(std::cerr, id); - std::cerr << std::endl; -#endif - - return 1; -} - - -/******************** Conversion Functions **************************/ - -DhtPeerDetails::DhtPeerDetails() -{ - mDhtState = RsDhtPeerDht::NOT_ACTIVE; - - mDhtState = RsDhtPeerDht::SEARCHING; - mDhtUpdateTS = time(NULL); - - mPeerReqStatusMsg = "Just Added"; - mPeerReqState = RsDhtPeerRequest::STOPPED; - mPeerReqMode = 0; - //mPeerReqProxyId; - mPeerReqTS = time(NULL); - - mExclusiveProxyLock = false; - - mPeerCbMsg = "No CB Yet"; - mPeerCbMode = 0; - mPeerCbPoint = 0; - //mPeerCbProxyId = 0; - //mPeerCbDestId = 0; - mPeerCbTS = 0; - - mPeerConnectState = RsDhtPeerConnectState::DISCONNECTED; - mPeerConnectMsg = "Disconnected"; - mPeerConnectMode = 0; - //dpd->mPeerConnectProxyId; - mPeerConnectPoint = 0; - - mPeerConnectUdpTS = 0; - mPeerConnectTS = 0; - mPeerConnectClosedTS = 0; - - bdsockaddr_clear(&(mPeerConnectAddr)); -} - diff --git a/libretroshare/src/dht/p3bitdht_relay.cc b/libretroshare/src/dht/p3bitdht_relay.cc deleted file mode 100644 index 2d2845c83..000000000 --- a/libretroshare/src/dht/p3bitdht_relay.cc +++ /dev/null @@ -1,404 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: p3bitdht_relay.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2011 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -#include "util/rsnet.h" -#include "dht/p3bitdht.h" - -#include "tcponudp/udprelay.h" -#include "bitdht/bdstddht.h" - -#include "rsitems/rsconfigitems.h" - - -/*********************************************************************************************** - ********** External RsDHT Interface for Dht-Relay Control ************************************* -************************************************************************************************/ - -int p3BitDht::setupRelayDefaults() -{ - RsDhtRelayMode mode = RsDhtRelayMode::ENABLED | RsDhtRelayMode::OFF; - setRelayMode(mode); - - return 1; -} - - -/**** THIS IS A TEMPORARY HACK INTERFACE - UNTIL WE HAVE MORE SOFISTICATED SYSTEM - * NB: using bdNodeIds here, rather than SSL IDS. - *****/ - -int p3BitDht::getRelayServerList(std::list &ids) -{ - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - ids = mRelayServerList; - - return 1; -} - -int p3BitDht::addRelayServer(std::string id) -{ - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - std::list::iterator it; - it = std::find(mRelayServerList.begin(), mRelayServerList.end(), id); - if (it == mRelayServerList.end()) - { - mRelayServerList.push_back(id); - } - - IndicateConfigChanged(); - return 1; -} - -int p3BitDht::removeRelayServer(std::string id) -{ - - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - std::list::iterator it; - it = std::find(mRelayServerList.begin(), mRelayServerList.end(), id); - if (it != mRelayServerList.end()) - { - mRelayServerList.erase(it); - } - - IndicateConfigChanged(); - return 1; -} - -int p3BitDht::pushRelayServers() -{ - std::list servers; - - { - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - servers = mRelayServerList; - } - - std::list::iterator it; - for(it = servers.begin(); it != servers.end(); ++it) - { - /* push it to dht */ - uint32_t bdflags = BITDHT_PEER_STATUS_DHT_RELAY_SERVER; - bdId id; - bdStdLoadNodeId(&(id.id), *it); - - mUdpBitDht->updateKnownPeer(&id, 0, bdflags); - - } - return 1; -} - - -RsDhtRelayMode p3BitDht::getRelayMode() -{ - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - - return mRelayMode; -} - -int p3BitDht::setRelayMode(RsDhtRelayMode mode) -{ - std::cerr << "p3BitDht::setRelayMode(" << mode << ")"; - std::cerr << std::endl; - - if (!!(mode & RsDhtRelayMode::ENABLED)) - { - mUdpBitDht->ConnectionOptions( - BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY | BITDHT_CONNECT_MODE_RELAY, - BITDHT_CONNECT_OPTION_AUTOPROXY); - } - else - { - mUdpBitDht->ConnectionOptions( - BITDHT_CONNECT_MODE_DIRECT | BITDHT_CONNECT_MODE_PROXY, - BITDHT_CONNECT_OPTION_AUTOPROXY); - } - - RsDhtRelayMode relaymode = mode & RsDhtRelayMode::MASK; - - switch(relaymode) - { - case RsDhtRelayMode::OFF: - mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_IGNORED); - break; - case RsDhtRelayMode::ON: - pushRelayServers(); - mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_FLAGGED); - break; - case RsDhtRelayMode::SERVER: - pushRelayServers(); - mUdpBitDht->setDhtMode(BITDHT_MODE_RELAYSERVERS_SERVER); - break; - } - - { - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - mRelayMode = mode; - } - - IndicateConfigChanged(); - - return 1; -} - -int p3BitDht::getRelayAllowance(RsDhtRelayClass classIdx, uint32_t &count, uint32_t &bandwidth) -{ - std::cerr << "p3BitDht::getRelayAllowance(" << static_cast::type>(classIdx) << "): "; - if ((classIdx >= RsDhtRelayClass::ALL) && (classIdx < RsDhtRelayClass::NUM_CLASS)) - { - count = mRelay->getRelayClassMax(static_cast::type>(classIdx)); - bandwidth = mRelay->getRelayClassBandwidth(static_cast::type>(classIdx)); - - std::cerr << " count: " << count << " bandwidth: " << bandwidth; - std::cerr << std::endl; - return 1; - } - std::cerr << " Invalid classIdx"; - std::cerr << std::endl; - - return 0; -} - -int p3BitDht::setRelayAllowance(RsDhtRelayClass classIdx, uint32_t count, uint32_t bandwidth) -{ - std::cerr << "p3BitDht::getRelayAllowance(" << static_cast::type>(classIdx) << ", "; - std::cerr << ", " << count << ", " << bandwidth << ")"; - std::cerr << std::endl; - - int retval = mRelay->setRelayClassMax(static_cast::type>(classIdx), count, bandwidth); - IndicateConfigChanged(); - - return retval; -} - - -/*********************************************************************************************** - ********** External RsDHT Interface for Dht-Relay Control ************************************* -************************************************************************************************/ - -/*****************************************************************/ -/*********************** p3config ******************************/ - /* Key Functions to be overloaded for Full Configuration */ -RsSerialiser *p3BitDht::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - return rss ; -} - - -bool p3BitDht::saveList(bool &cleanup, std::list &saveList) -{ - cleanup = true; - - std::cerr << "p3BitDht::saveList()"; - std::cerr << std::endl; - - - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - RsConfigKeyValueSet *config = new RsConfigKeyValueSet(); - - RsTlvKeyValue kv; - - /* Push Relay Class Stuff */ - int i; - for(i = 0; i < static_cast::type>(RsDhtRelayClass::NUM_CLASS); ++i) - { - rs_sprintf(kv.key, "RELAY_CLASS%d_COUNT", i); - rs_sprintf(kv.value, "%d", mRelay->getRelayClassMax(i)); - config->tlvkvs.pairs.push_back(kv); - - rs_sprintf(kv.key, "RELAY_CLASS%d_BANDWIDTH", i); - rs_sprintf(kv.value, "%d", mRelay->getRelayClassBandwidth(i)); - config->tlvkvs.pairs.push_back(kv); - } - - /* add RelayMode */ - { - kv.key = "RELAY_MODE"; - rs_sprintf(kv.value, "%lu", mRelayMode); - config->tlvkvs.pairs.push_back(kv); - } - - /* add Servers */ - std::list::iterator it; - for(i = 0, it = mRelayServerList.begin(); it != mRelayServerList.end(); ++it, ++i) - { - rs_sprintf(kv.key, "RELAY_SERVER%d", i); - kv.value = *it; - config->tlvkvs.pairs.push_back(kv); - } - - std::cerr << "BITDHT Save Item:"; - std::cerr << std::endl; - - config->print(std::cerr, 0); - - saveList.push_back(config); - - return true; -} - -void p3BitDht::saveDone() -{ - return; -} - -bool p3BitDht::loadList(std::list& load) -{ - std::cerr << "p3BitDht::loadList()"; - std::cerr << std::endl; - - if (load.empty() || (load.size() > 1)) - { - /* error */ - std::cerr << "p3BitDht::loadList() Error only expecting 1 item"; - std::cerr << std::endl; - - for(std::list::iterator it=load.begin();it!=load.end();++it) - delete *it ; - - load.clear() ; - return false; - } - RsItem *item = load.front(); - - RsConfigKeyValueSet *config = dynamic_cast(item); - - if (!config) - { - /* error */ - std::cerr << "p3BitDht::loadList() Error expecting item = config"; - std::cerr << std::endl; - delete item ; - return false; - } - - //std::cerr << "BITDHT Load Item:"; - //std::cerr << std::endl; - - //config->print(std::cerr, 0); - - std::list servers; - int peers[static_cast::type>(RsDhtRelayClass::NUM_CLASS)] = {0}; - int bandwidth[static_cast::type>(RsDhtRelayClass::NUM_CLASS)] = {0}; - - bool haveMode = false; - RsDhtRelayMode mode = RsDhtRelayMode::DISABLED; - - std::list::iterator it; - for(it = config->tlvkvs.pairs.begin(); it != config->tlvkvs.pairs.end(); ++it) - { - std::string key = it->key; - std::string value = it->value; - if (0 == strncmp(key.c_str(), "RELAY_SERVER", 12)) - { - /* add to RELAY_SERVER List */ - servers.push_back(value); - //std::cerr << "p3BitDht::loadList() Found Server: " << value; - //std::cerr << std::endl; - } - else if (0 == strncmp(key.c_str(), "RELAY_MODE", 10)) - { - mode = static_cast(atoi(value.c_str())); - haveMode = true; - - //std::cerr << "p3BitDht::loadList() Found Mode: " << mode; - //std::cerr << std::endl; - } - else if (0 == strncmp(key.c_str(), "RELAY_CLASS", 11)) - { - /* len check */ - if (key.length() < 14) - continue; - - int idx = 0; - uint32_t val = atoi(value.c_str()); - switch(key[11]) - { - default: - case '0': - idx = 0; - break; - case '1': - idx = 1; - break; - case '2': - idx = 2; - break; - case '3': - idx = 3; - break; - } - - if (key[13] == 'C') - { - //std::cerr << "p3BitDht::loadList() Found Count(" << idx << "): "; - //std::cerr << val; - //std::cerr << std::endl; - peers[idx] = val; - } - else - { - //std::cerr << "p3BitDht::loadList() Found Bandwidth(" << idx << "): "; - //std::cerr << val; - //std::cerr << std::endl; - bandwidth[idx] = val; - } - } - else - { - //std::cerr << "p3BitDht::loadList() Unknown Key:value: " << key; - //std::cerr << ":" << value; - //std::cerr << std::endl; - } - } - - - // Cleanup config. - delete config; - - { - RsStackMutex stack(dhtMtx); /*********** LOCKED **********/ - mRelayServerList = servers; - } - - int i; - for(i = 0; i < static_cast::type>(RsDhtRelayClass::NUM_CLASS); ++i) - { - mRelay->setRelayClassMax(i, peers[i], bandwidth[i]); - } - - if (haveMode) - { - setRelayMode(mode); - } - - load.clear() ; - return true; -} - -/*****************************************************************/ - diff --git a/libretroshare/src/dht/stunaddrassist.h b/libretroshare/src/dht/stunaddrassist.h deleted file mode 100644 index 195337b1a..000000000 --- a/libretroshare/src/dht/stunaddrassist.h +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * libretroshare/src/dht: stunaddrassist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -#ifndef STUN_ADDR_ASSIST_H -#define STUN_ADDR_ASSIST_H - -#include "pqi/pqiassist.h" -#include "tcponudp/udpstunner.h" - -class stunAddrAssist: public pqiAddrAssist -{ - public: - - stunAddrAssist(UdpStunner *stunner) - { - mStunner = stunner; - } - -virtual bool getExternalAddr(struct sockaddr_storage &remote, uint8_t &stable) - { - // IPV4 ONLY. - struct sockaddr_in remotev4; - if (mStunner->externalAddr(remotev4, stable)) - { - sockaddr_storage_clear(remote); - struct sockaddr_in *addr = (struct sockaddr_in *) &remote; - addr->sin_family = AF_INET; - addr->sin_addr = remotev4.sin_addr; - addr->sin_port = remotev4.sin_port; - - return true; - } - return false; - } - -virtual int tick() - { - return mStunner->tick(); - } - -virtual void setRefreshPeriod(int32_t period) - { - return mStunner->setTargetStunPeriod(period); - } - - private: - - UdpStunner *mStunner; -}; - -#endif - diff --git a/libretroshare/src/file_sharing/README.txt b/libretroshare/src/file_sharing/README.txt deleted file mode 100644 index 947cf64be..000000000 --- a/libretroshare/src/file_sharing/README.txt +++ /dev/null @@ -1,215 +0,0 @@ -Design document for the new file list sharing system. -==================================================== - -Big picture ------------ - - p3SharesManager - Functionalities - * contains the list of shared files - - responds to search, requests for FileInfo - * responsible for sync-ing file lists between peers - - Level 3: interface with GUI - - regularly issue syncing requests in background - - automatically issue syncing requests as files are browsed - - Level 2: internal stuff - - examine syncing requests. Only get data - - Level 1: syncing system - - list of pending requests with priorities, sort them and handle response from friends - - Level 0: interface with friends - - serialisation/deserialisation of file list items - - FileIndex should support: - - O(log(n)) search for hash - - O(n) search for regular exp - - O(1) remove of file and directory - - Members - - list of file indexes - => map of - - - - Parent classes - - p3Service (sends and receives information about shared files) - - Notes: - - the same file should be able to be held by two different directories. Hash search will return a single hit. - - the previously existing PersonEntry had no field and was overloading DirEntry, with overwritten file names, hashes etc. Super bad! - -Directory storage file format ------------------------------ - * should be extensible (xml or binary format? Binary, because it's going to be encrypted anyway) - => works with binary fields - => - - [= version =] - [= peer id =] - [= num entries =] - [= some information =] - - [entry tag] [entry size] [Field ID 01] [field size v 01] [Field data 01] [Field ID 02] [field size v 02] [Field data 02] ... - [entry tag] [entry size] [Field ID 01] [field size v 01] [Field data 01] [Field ID 02] [field size v 02] [Field data 02] ... - [entry tag] [entry size] [Field ID 01] [field size v 01] [Field data 01] [Field ID 02] [field size v 02] [Field data 02] ... - ... - 2 1-5 v 2 1-5 v - * entry content - Tag | Content | Size - ----------------+--------------------------------------+------ - 01 | sha1 hash | 20 - 01 | sha1^2 hash | 20 - 02 | file name | < 512 - 03 | file size | 8 - 04 | dir name | < 512 - 05 | last modif time local | 4 - 06 | last modif time including sub-dirs | 4 - -Classes -------- - - p3ShareManager - - tick() - * handle pending syncing requests => sends items - * watch shared directories - => hash new files - => updates shared files - * - - - list of shared parent directories, with share flags - - FileIndex // should support hierarchical navigation, load/save - - - - LocalFileIndex: public FileIndex - - std::map // used for search - - FileInfo - - std::string name - - RsFileHash hash - - uint64_t size - - rstime_t Last modification time - - LocalFileInfo: public FileInfo - - rstime_t Last data access time - - uint64_t Total data uploaded - - uint32_t ShareFlags - - SharedDirectory - - parent groups - - group flags - -Best data structure for file index ----------------------------------- - - | Hash map map list - ----------------+-----------------+------------+-------------- - Adding | Constant | log(n) | O(n) - Hash search | Constant | log(n) | O(n) - Name/exp search | O(n) | O(n) | O(n) - Recursive browse| Constant | log(n) | O(n) - - Should we use the same struct for files and directories? - - Sol 1: - DirClass + PersonClass + FileEntry class - - each has pointers to elements list of the same type - - lists are handled for Files (all file entries), - - Directories are represented by the hash of the full path - - Sol 2: - Same class for all elements, in a single hash map. Each element is - defined by its type (Dir, Person, File) which all have a hash. - -Syncing between peers ---------------------- - -Generating sync events - * Client side - - for each directory, in breadth first order - - if directory has changed, or last update is old - => push a sync request - - store the peer's last up time. Compare with peer uptimes recursively. - - * Server side - - after a change, broadcast a "directory changed" packet to all connected friends - - * directoy updater - - crawl through directories - - compare TS of files, missing files, new files - - feed a queue of files to hash - - directory whatcher gets notified when files are hashed - - - a separate component hashes files (FileHashingProcess) - - DirectoryWatcher (watches a hierarchy) File List (stores a directory hierarchy) - | | - | | - | | - +-----------------------+------------------+ - | | - Shared File Service | - | | - | | - +----------- own file list -------+---------- Encrypted/compressed save to disk - | | | - +----------- friend file lists ---+ -Roadmap -------- - -[X] complete this file until a proper description of the whole thing is achieved. -[X] create a new directory and implement the .h for the basic functionality -[ ] look into existing code in ftServer for the integration, but don't change anything yet -[X] setup class hierarchy -[ ] merge hash cache into file lists. -[ ] new format for saving of FileIndex to make it locally encrypted, compact and extensible -[ ] create basic directory functionality with own files: re-hash, and store -[ ] display own files in GUI, with proper update and working sort - -TODO -==== - - [ ] directory handler - [ ] abstract functions to keep a directory and get updates to it. - [ ] hierarchical storage representation. - [ ] allow add/delete entries - [ ] auto-cleanup - - [ ] directory updater - [ ] abstract layer - [ ] crawls the directory and ask updates - - [ ] derive local directory updater - [ ] crawl local files, and asks updates to storage class - [ ] derive remote directory updater - [ ] crawl stored files, and request updates to storage class - - [ ] load/save of directory content. Should be extensible - [ ] p3FileLists with minimal functonality: no exchange. Only storage of own file lists - [ ] service (items) for p3FileLists - [ ] connect RemoteDirModel to new system - [ ] test GUI functions - [ ] test update between peers - - - - - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc deleted file mode 100644 index d93df1d1b..000000000 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ /dev/null @@ -1,1235 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: dir_hierarchy.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include -#include - -#include "util/rstime.h" -#include "util/rsdir.h" -#include "util/rsprint.h" -#include "retroshare/rsexpr.h" -#include "dir_hierarchy.h" -#include "filelist_io.h" -#include "file_sharing_defaults.h" - -#ifdef RS_DEEP_FILES_INDEX -# include "deep_search/filesindex.hpp" -#endif // def RS_DEEP_FILES_INDEX - -//#define DEBUG_DIRECTORY_STORAGE 1 - -typedef FileListIO::read_error read_error; - -/******************************************************************************************************************/ -/* Internal File Hierarchy Storage */ -/******************************************************************************************************************/ - -template typename std::set::iterator erase_from_set(typename std::set& s,const typename std::set::iterator& it) -{ - typename std::set::iterator tmp(it); - ++tmp; - s.erase(it) ; - return tmp; -} - -// This class handles the file hierarchy -// A Mutex is used to ensure total coherence at this level. So only abstracted operations are allowed, -// so that the hierarchy stays completely coherent between calls. - -InternalFileHierarchyStorage::InternalFileHierarchyStorage() : mRoot(0) -{ - DirEntry *de = new DirEntry("") ; - - de->row=0; - de->parent_index=0; - de->dir_modtime=0; - de->dir_hash=RsFileHash() ; // null hash is root by convention. - - mNodes.push_back(de) ; - mDirHashes[de->dir_hash] = 0 ; - - mTotalSize = 0 ; - mTotalFiles = 0 ; -} - -bool InternalFileHierarchyStorage::getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const -{ - if(!checkIndex(index,FileStorageNode::TYPE_DIR)) - return false ; - - hash = static_cast(mNodes[index])->dir_hash ; - - return true; -} -bool InternalFileHierarchyStorage::getIndexFromDirHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) -{ - std::map::iterator it = mDirHashes.find(hash) ; - - if(it == mDirHashes.end()) - return false; - - index = it->second; - - // make sure the hash actually points to some existing file. If not, remove it. This is a lazy update of dir hashes: when we need them, we check them. - if(!checkIndex(index, FileStorageNode::TYPE_DIR) || static_cast(mNodes[index])->dir_hash != hash) - { - std::cerr << "(II) removing non existing hash from dir hash list: " << hash << std::endl; - - mDirHashes.erase(it) ; - return false ; - } - return true; -} -bool InternalFileHierarchyStorage::getIndexFromFileHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) -{ - std::map::iterator it = mFileHashes.find(hash) ; - - if(it == mFileHashes.end()) - return false; - - index = it->second; - - // make sure the hash actually points to some existing file. If not, remove it. This is a lazy update of file hashes: when we need them, we check them. - if(!checkIndex(it->second, FileStorageNode::TYPE_FILE) || static_cast(mNodes[index])->file_hash != hash) - { - std::cerr << "(II) removing non existing hash from file hash list: " << hash << std::endl; - - mFileHashes.erase(it) ; - return false ; - } - - return true; -} - -bool InternalFileHierarchyStorage::getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const -{ - if(!checkIndex(e,FileStorageNode::TYPE_DIR)) - return false ; - - const DirEntry& d = *static_cast(mNodes[e]) ; - - if((uint32_t)row < d.subdirs.size()) - { - c = d.subdirs[row] ; - return true ; - } - - if((uint32_t)row < d.subdirs.size() + d.subfiles.size()) - { - c = d.subfiles[row - (int)d.subdirs.size()] ; - return true ; - } - return false; -} - -int InternalFileHierarchyStorage::parentRow(DirectoryStorage::EntryIndex e) -{ - if(!checkIndex(e,FileStorageNode::TYPE_DIR | FileStorageNode::TYPE_FILE) || e==0) - return -1 ; - - return mNodes[mNodes[e]->parent_index]->row; -} - -// high level modification routines - -bool InternalFileHierarchyStorage::isIndexValid(DirectoryStorage::EntryIndex e) const -{ - return e < mNodes.size() && mNodes[e] != NULL ; -} - -bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::set& subdirs, const RsFileHash& random_hash_seed) -{ - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return false; - - DirEntry& d(*static_cast(mNodes[indx])) ; - - std::set should_create(subdirs); - - for(uint32_t i=0;i(mNodes[d.subdirs[i]])->dir_name) == subdirs.end()) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] Removing subdirectory " << static_cast(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl; -#endif - - if( !removeDirectory(d.subdirs[i])) - i++ ; - } - else - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] Keeping existing subdirectory " << static_cast(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl; -#endif - - should_create.erase(static_cast(mNodes[d.subdirs[i]])->dir_name) ; - ++i; - } - - for(std::set::const_iterator it(should_create.begin());it!=should_create.end();++it) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] adding new subdirectory " << it->first << " at index " << mNodes.size() << std::endl; -#endif - - DirEntry *de = new DirEntry(*it) ; - - de->row = mNodes.size(); - de->parent_index = indx; - de->dir_modtime = 0;// forces parsing.it->second; - de->dir_parent_path = RsDirUtil::makePath(d.dir_parent_path, d.dir_name) ; - de->dir_hash = createDirHash(de->dir_name,d.dir_hash,random_hash_seed) ; - - mDirHashes[de->dir_hash] = mNodes.size() ; - - d.subdirs.push_back(mNodes.size()) ; - mNodes.push_back(de) ; - } - - return true; -} - -RsFileHash InternalFileHierarchyStorage::createDirHash(const std::string& dir_name, const RsFileHash& dir_parent_hash, const RsFileHash& random_hash_salt) -{ - // What we need here: a unique identifier - // - that cannot be bruteforced to find the real directory name and path - // - that is used by friends to refer to a specific directory. - - // Option 1: compute H(some_secret_salt + dir_name + dir_parent_path) - // and keep the same salt so that we can re-create the hash - // - // Option 2: compute H(virtual_path). That only works at the level of LocalDirectoryStorage - // - // Option 3: just compute something random, but then we need to store it so as to not - // confuse friends when restarting. - - RsTemporaryMemory mem(dir_name.size() + 2*RsFileHash::SIZE_IN_BYTES) ; - - memcpy( mem, random_hash_salt.toByteArray(),RsFileHash::SIZE_IN_BYTES) ; - memcpy(&mem[ RsFileHash::SIZE_IN_BYTES], dir_parent_hash.toByteArray(),RsFileHash::SIZE_IN_BYTES) ; - memcpy(&mem[2*RsFileHash::SIZE_IN_BYTES],dir_name.c_str(), dir_name.size()) ; - - RsFileHash res = RsDirUtil::sha1sum( mem,mem.size() ) ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "Creating new dir hash for dir " << dir_name << ", parent dir hash=" << dir_parent_hash << " seed=[hidden]" << " result is " << res << std::endl; -#endif - - return res ; -} - -bool InternalFileHierarchyStorage::removeDirectory(DirectoryStorage::EntryIndex indx) // no reference here! Very important. Otherwise, the messign we do inside can change the value of indx!! -{ - // check that it's a directory - - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return false; - - if(indx == 0) - return nodeAccessError("checkIndex(): Cannot remove top level directory") ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "(--) Removing directory " << indx << std::endl; - print(); -#endif - // remove from parent - - DirEntry& d(*static_cast(mNodes[indx])) ; - DirEntry& parent_dir(*static_cast(mNodes[d.parent_index])); - - for(uint32_t i=0;i= mNodes.size() || mNodes[indx] == NULL) - return nodeAccessError("checkIndex(): Node does not exist") ; - - if(! (mNodes[indx]->type() & type)) - return nodeAccessError("checkIndex(): Node is of wrong type") ; - - return true; -} - -bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map& subfiles,std::map& new_files) -{ - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return false; - - DirEntry& d(*static_cast(mNodes[indx])) ; - new_files = subfiles ; - - // remove from new_files the ones that already exist and have a modf time that is not older. - - for(uint32_t i=0;i(mNodes[d.subfiles[i]])) ; - std::map::const_iterator it = subfiles.find(f.file_name) ; - - if(it == subfiles.end()) // file does not exist anymore => delete - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] removing non existing file " << f.file_name << " at index " << d.subfiles[i] << std::endl; -#endif - - deleteFileNode(d.subfiles[i]) ; - - d.subfiles[i] = d.subfiles[d.subfiles.size()-1] ; - d.subfiles.pop_back(); - continue; - } - - if(it->second.modtime != f.file_modtime || it->second.size != f.file_size) // file is newer and/or has different size - { - f.file_hash.clear(); // hash needs recomputing - f.file_modtime = it->second.modtime; - f.file_size = it->second.size; - - mTotalSize -= f.file_size ; - mTotalSize += it->second.size ; - } - new_files.erase(f.file_name) ; - - ++i; - } - - for(std::map::const_iterator it(new_files.begin());it!=new_files.end();++it) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] adding new file " << it->first << " at index " << mNodes.size() << std::endl; -#endif - - d.subfiles.push_back(mNodes.size()) ; - mNodes.push_back(new FileEntry(it->first,it->second.size,it->second.modtime)); - mNodes.back()->row = mNodes.size()-1; - mNodes.back()->parent_index = indx; - - mTotalSize += it->second.size; - mTotalFiles += 1; - } - return true; -} -bool InternalFileHierarchyStorage::updateHash(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash) -{ - if(!checkIndex(file_index,FileStorageNode::TYPE_FILE)) - { - std::cerr << "[directory storage] (EE) cannot update file at index " << file_index << ". Not a valid index, or not a file." << std::endl; - return false; - } -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] updating hash at index " << file_index << ", hash=" << hash << std::endl; -#endif - - RsFileHash& old_hash (static_cast(mNodes[file_index])->file_hash) ; - mFileHashes[hash] = file_index ; - - old_hash = hash ; - - return true; -} -bool InternalFileHierarchyStorage::updateFile(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash, const std::string& fname,uint64_t size, const rstime_t modf_time) -{ - if(!checkIndex(file_index,FileStorageNode::TYPE_FILE)) - { - std::cerr << "[directory storage] (EE) cannot update file at index " << file_index << ". Not a valid index, or not a file." << std::endl; - return false; - } - - FileEntry& fe(*static_cast(mNodes[file_index])) ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "[directory storage] updating file entry at index " << file_index << ", name=" << fe.file_name << " size=" << fe.file_size << ", hash=" << fe.file_hash << std::endl; -#endif - if(mTotalSize >= fe.file_size) - mTotalSize -= fe.file_size; - - mTotalSize += size ; - - fe.file_hash = hash; - fe.file_size = size; - fe.file_modtime = modf_time; - fe.file_name = fname; - - if(!hash.isNull()) - mFileHashes[hash] = file_index ; - - return true; -} - -void InternalFileHierarchyStorage::deleteFileNode(uint32_t index) -{ - if(mNodes[index] != NULL) - { - FileEntry& fe(*static_cast(mNodes[index])) ; - -#ifdef RS_DEEP_FILES_INDEX - DeepFilesIndex tfi(DeepFilesIndex::dbDefaultPath()); - tfi.removeFileFromIndex(fe.file_hash); -#endif - - if(mTotalSize >= fe.file_size) - mTotalSize -= fe.file_size ; - - if(mTotalFiles > 0) - mTotalFiles -= 1; - - delete mNodes[index] ; - mFreeNodes.push_back(index) ; - mNodes[index] = NULL ; - } -} -void InternalFileHierarchyStorage::deleteNode(uint32_t index) -{ - if(mNodes[index] != NULL) - { - delete mNodes[index] ; - mFreeNodes.push_back(index) ; - mNodes[index] = NULL ; - } -} - -DirectoryStorage::EntryIndex InternalFileHierarchyStorage::allocateNewIndex() -{ - while(!mFreeNodes.empty()) - { - uint32_t index = mFreeNodes.front(); - mFreeNodes.pop_front(); - - if(mNodes[index] == NULL) - return DirectoryStorage::EntryIndex(index) ; - } - - mNodes.push_back(NULL) ; - return mNodes.size()-1 ; -} - -bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryIndex& indx,const std::string& dir_name,rstime_t most_recent_time,rstime_t dir_modtime,const std::vector& subdirs_hash,const std::vector& subfiles_array) -{ - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - { - std::cerr << "[directory storage] (EE) cannot update dir at index " << indx << ". Not a valid index, or not an existing dir." << std::endl; - return false; - } - DirEntry& d(*static_cast(mNodes[indx])) ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "Updating dir entry: name=\"" << dir_name << "\", most_recent_time=" << most_recent_time << ", modtime=" << dir_modtime << std::endl; -#endif - - d.dir_most_recent_time = most_recent_time; - d.dir_modtime = dir_modtime; - d.dir_update_time = time(NULL); - d.dir_name = dir_name; - - std::map existing_subdirs ; - - for(uint32_t i=0;i(mNodes[d.subdirs[i]])->dir_hash] = d.subdirs[i] ; - - d.subdirs.clear(); - - // check that all subdirs already exist. If not, create. - for(uint32_t i=0;i::iterator it = existing_subdirs.find(subdirs_hash[i]) ; - DirectoryStorage::EntryIndex dir_index = 0; - - if(it != existing_subdirs.end() && mNodes[it->second] != NULL && mNodes[it->second]->type() == FileStorageNode::TYPE_DIR) - { - dir_index = it->second ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " already exists, at index " << dir_index << std::endl; -#endif - - existing_subdirs.erase(it) ; - } - else - { - dir_index = allocateNewIndex() ; - - DirEntry *de = new DirEntry("") ; - - mNodes[dir_index] = de ; - - de->dir_parent_path = RsDirUtil::makePath(d.dir_parent_path, dir_name) ; - de->dir_hash = subdirs_hash[i]; - - mDirHashes[subdirs_hash[i]] = dir_index ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " created, at new index " << dir_index << std::endl; -#endif - } - - d.subdirs.push_back(dir_index) ; - mDirHashes[subdirs_hash[i]] = dir_index ; - } - // remove subdirs that do not exist anymore - - for(std::map::const_iterator it = existing_subdirs.begin();it!=existing_subdirs.end();++it) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl; -#endif - - if(!checkIndex(it->second,FileStorageNode::TYPE_DIR)) - { - std::cerr << "(EE) Cannot delete node of index " << it->second << " because it is not a file. Inconsistency error!" << std::endl; - continue ; - } - recursRemoveDirectory(it->second) ; - } - - // now update subfiles. This is more stricky because we need to not suppress hash duplicates - - std::map existing_subfiles ; - - for(uint32_t i=0;i(mNodes[d.subfiles[i]])->file_name] = d.subfiles[i] ; - - d.subfiles.clear(); - - for(uint32_t i=0;i::iterator it = existing_subfiles.find(subfiles_array[i].file_name) ; - const FileEntry& f(subfiles_array[i]) ; - DirectoryStorage::EntryIndex file_index ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " subfile name = " << subfiles_array[i].file_name << ": " ; -#endif - - if(it != existing_subfiles.end() && mNodes[it->second] != NULL && mNodes[it->second]->type() == FileStorageNode::TYPE_FILE) - { - file_index = it->second ; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " already exists, at index " << file_index << std::endl; -#endif - - if(!updateFile(file_index,f.file_hash,f.file_name,f.file_size,f.file_modtime)) - std::cerr << "(EE) Cannot update file with index " << it->second <<" and hash " << f.file_hash << ". This is very weird. Entry should have just been created and therefore should exist. Skipping." << std::endl; - - existing_subfiles.erase(it) ; - } - else - { - file_index = allocateNewIndex() ; - - mNodes[file_index] = new FileEntry(f.file_name,f.file_size,f.file_modtime,f.file_hash) ; - mFileHashes[f.file_hash] = file_index ; - mTotalSize += f.file_size ; - mTotalFiles++; - -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " created, at new index " << file_index << std::endl; -#endif - } - - d.subfiles.push_back(file_index) ; - } - // remove subfiles that do not exist anymore - - for(std::map::const_iterator it = existing_subfiles.begin();it!=existing_subfiles.end();++it) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl; -#endif - - if(!checkIndex(it->second,FileStorageNode::TYPE_FILE)) - { - std::cerr << "(EE) Cannot delete node of index " << it->second << " because it is not a file. Inconsistency error!" << std::endl; - continue ; - } - deleteFileNode(it->second) ; - } - - // now update row and parent index for all subnodes - - uint32_t n=0; - for(uint32_t i=0;i(mNodes[d.subdirs[i]])->dir_update_time = 0 ; // force the update of the subdir. - - mNodes[d.subdirs[i]]->parent_index = indx ; - mNodes[d.subdirs[i]]->row = n++ ; - } - for(uint32_t i=0;iparent_index = indx ; - mNodes[d.subfiles[i]]->row = n++ ; - } - - - return true; -} - -void InternalFileHierarchyStorage::getStatistics(SharedDirStats& stats) const -{ - stats.total_number_of_files = mTotalFiles ; - stats.total_shared_size = mTotalSize ; -} - -bool InternalFileHierarchyStorage::getTS(const DirectoryStorage::EntryIndex& index,rstime_t& TS,rstime_t DirEntry::* m) const -{ - if(!checkIndex(index,FileStorageNode::TYPE_DIR)) - { - std::cerr << "[directory storage] (EE) cannot get TS for index " << index << ". Not a valid index or not a directory." << std::endl; - return false; - } - - DirEntry& d(*static_cast(mNodes[index])) ; - - TS = d.*m ; - - return true; -} - -bool InternalFileHierarchyStorage::setTS(const DirectoryStorage::EntryIndex& index,rstime_t& TS,rstime_t DirEntry::* m) -{ - if(!checkIndex(index,FileStorageNode::TYPE_DIR)) - { - std::cerr << "[directory storage] (EE) cannot get TS for index " << index << ". Not a valid index or not a directory." << std::endl; - return false; - } - - DirEntry& d(*static_cast(mNodes[index])) ; - - d.*m = TS; - - return true; -} - -// Do a complete recursive sweep of directory hierarchy and update cumulative size of directories - -uint64_t InternalFileHierarchyStorage::recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index) -{ - DirEntry& d(*static_cast(mNodes[dir_index])) ; - - uint64_t local_cumulative_size = 0; - - for(uint32_t i=0;i(mNodes[d.subfiles[i]])->file_size; - - for(uint32_t i=0;i(mNodes[dir_index])) ; - - rstime_t largest_modf_time = d.dir_modtime ; - unfinished_files_present = false ; - - for(uint32_t i=0;i(mNodes[d.subfiles[i]]) ; - - if(!f->file_hash.isNull()) - largest_modf_time = std::max(largest_modf_time, f->file_modtime) ; // only account for hashed files, since we never send unhashed files to friends. - else - unfinished_files_present = true ; - } - - for(uint32_t i=0;i 0) - largest_modf_time-- ; - - d.dir_most_recent_time = largest_modf_time ; - - return largest_modf_time ; -} - -// Low level stuff. Should normally not be used externally. - -const InternalFileHierarchyStorage::FileStorageNode *InternalFileHierarchyStorage::getNode(DirectoryStorage::EntryIndex indx) const -{ - if(checkIndex(indx,FileStorageNode::TYPE_FILE | FileStorageNode::TYPE_DIR)) - return mNodes[indx] ; - else - return NULL ; -} - -const InternalFileHierarchyStorage::DirEntry *InternalFileHierarchyStorage::getDirEntry(DirectoryStorage::EntryIndex indx) const -{ - if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) - return NULL ; - - return static_cast(mNodes[indx]) ; -} -const InternalFileHierarchyStorage::FileEntry *InternalFileHierarchyStorage::getFileEntry(DirectoryStorage::EntryIndex indx) const -{ - if(!checkIndex(indx,FileStorageNode::TYPE_FILE)) - return NULL ; - - return static_cast(mNodes[indx]) ; -} -uint32_t InternalFileHierarchyStorage::getType(DirectoryStorage::EntryIndex indx) const -{ - if(checkIndex(indx,FileStorageNode::TYPE_FILE | FileStorageNode::TYPE_DIR)) - return mNodes[indx]->type() ; - else - return FileStorageNode::TYPE_UNKNOWN; -} - -DirectoryStorage::EntryIndex InternalFileHierarchyStorage::getSubFileIndex(DirectoryStorage::EntryIndex parent_index,uint32_t file_tab_index) -{ - if(!checkIndex(parent_index,FileStorageNode::TYPE_DIR)) - return DirectoryStorage::NO_INDEX; - - if(static_cast(mNodes[parent_index])->subfiles.size() <= file_tab_index) - return DirectoryStorage::NO_INDEX; - - return static_cast(mNodes[parent_index])->subfiles[file_tab_index]; -} -DirectoryStorage::EntryIndex InternalFileHierarchyStorage::getSubDirIndex(DirectoryStorage::EntryIndex parent_index,uint32_t dir_tab_index) -{ - if(!checkIndex(parent_index,FileStorageNode::TYPE_DIR)) - return DirectoryStorage::NO_INDEX; - - if(static_cast(mNodes[parent_index])->subdirs.size() <= dir_tab_index) - return DirectoryStorage::NO_INDEX; - - return static_cast(mNodes[parent_index])->subdirs[dir_tab_index]; -} - -bool InternalFileHierarchyStorage::searchHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& result) -{ - return getIndexFromFileHash(hash,result); -} - -class DirectoryStorageExprFileEntry: public RsRegularExpression::ExpFileEntry -{ -public: - DirectoryStorageExprFileEntry(const InternalFileHierarchyStorage::FileEntry& fe,const InternalFileHierarchyStorage::DirEntry& parent) : mFe(fe),mDe(parent) {} - - inline virtual const std::string& file_name() const { return mFe.file_name ; } - inline virtual uint64_t file_size() const { return mFe.file_size ; } - inline virtual const RsFileHash& file_hash() const { return mFe.file_hash ; } - inline virtual rstime_t file_modtime() const { return mFe.file_modtime ; } - inline virtual std::string file_parent_path()const { return RsDirUtil::makePath(mDe.dir_parent_path, mDe.dir_name) ; } - inline virtual uint32_t file_popularity() const { NOT_IMPLEMENTED() ; return 0; } - -private: - const InternalFileHierarchyStorage::FileEntry& mFe ; - const InternalFileHierarchyStorage::DirEntry& mDe ; -}; - -int InternalFileHierarchyStorage::searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const -{ - for(std::map::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) - if(mNodes[it->second] != NULL && exp->eval( - DirectoryStorageExprFileEntry(*static_cast(mNodes[it->second]), - *static_cast(mNodes[mNodes[it->second]->parent_index]) - ))) - results.push_back(it->second); - - return 0; -} - -int InternalFileHierarchyStorage::searchTerms( - const std::list& terms, - std::list& results ) const -{ - // most entries are likely to be files, so we could do a linear search over the entries tab. - // instead we go through the table of hashes. - - for(std::map::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) - if(mNodes[it->second] != NULL) - { - const std::string &str1 = static_cast(mNodes[it->second])->file_name; - - for(std::list::const_iterator iter(terms.begin()); iter != terms.end(); ++iter) - { - /* always ignore case */ - const std::string &str2 = (*iter); - - if(str1.end() != std::search( str1.begin(), str1.end(), str2.begin(), str2.end(), RsRegularExpression::CompareCharIC() )) - { - results.push_back(it->second); - break; - } - } - } - return 0 ; -} - -bool InternalFileHierarchyStorage::check(std::string& error_string) // checks consistency of storage. -{ - // recurs go through all entries, check that all - - error_string = ""; - bool bDirOut = false; - bool bDirDouble = false; - bool bFileOut = false; - bool bFileDouble = false; - bool bOrphean = false; - - std::vector hits(mNodes.size(),0) ; // count hits of children. Should be 1 for all in the end. Otherwise there's an error. - hits[0] = 1 ; // because 0 is never the child of anyone - - mFreeNodes.clear(); - - for(uint32_t i=0;itype() == FileStorageNode::TYPE_DIR) - { - // stamp the kids - DirEntry& de = *static_cast(mNodes[i]) ; - - for(uint32_t j=0;j= mNodes.size()) - { - if(!bDirOut){ error_string += " - Node child dir out of tab!"; bDirOut = true;} - de.subdirs[j] = de.subdirs.back() ; - de.subdirs.pop_back(); - } - else if(hits[de.subdirs[j]] != 0) - { - if(!bDirDouble){ error_string += " - Double hit on a single node dir."; bDirDouble = true;} - de.subdirs[j] = de.subdirs.back() ; - de.subdirs.pop_back(); - } - else - { - hits[de.subdirs[j]] = 1; - ++j ; - } - } - for(uint32_t j=0;j= mNodes.size()) - { - if(!bFileOut){ error_string += " - Node child file out of tab!"; bFileOut = true;} - de.subfiles[j] = de.subfiles.back() ; - de.subfiles.pop_back(); - } - else if(hits[de.subfiles[j]] != 0) - { - if(!bFileDouble){ error_string += " - Double hit on a single node file."; bFileDouble = true;} - de.subfiles[j] = de.subfiles.back() ; - de.subfiles.pop_back(); - } - else - { - hits[de.subfiles[j]] = 1; - ++j ; - } - } - } - else if( mNodes[i] == NULL ) - mFreeNodes.push_back(i) ; - - for(uint32_t i=0;itype() == FileStorageNode::TYPE_DIR) - { - std::cerr << " Node " << i << ": type=" << mNodes[i]->type() << std::endl; - ++ndirs; - } - else if(mNodes[i]->type() == FileStorageNode::TYPE_FILE) - { - std::cerr << " Node " << i << ": type=" << mNodes[i]->type() << std::endl; - ++nfiles; - } - else - { - ++nunknown; - std::cerr << "(EE) Error: unknown type node found!" << std::endl; - } - - std::cerr << "Total nodes: " << mNodes.size() << " (" << nfiles << " files, " << ndirs << " dirs, " << nempty << " empty slots"; - if (nunknown > 0) std::cerr << ", " << nunknown << " unknown"; - std::cerr << ")" << std::endl; - - - recursPrint(0,DirectoryStorage::EntryIndex(0)); - - std::cerr << "Known dir hashes: " << std::endl; - for(std::map::const_iterator it(mDirHashes.begin());it!=mDirHashes.end();++it) - std::cerr << " " << it->first << " at index " << it->second << std::endl; - - std::cerr << "Known file hashes: " << std::endl; - for(std::map::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) - std::cerr << " " << it->first << " at index " << it->second << std::endl; -} -void InternalFileHierarchyStorage::recursPrint(int depth,DirectoryStorage::EntryIndex node) const -{ - std::string indent(2*depth,' '); - - if(mNodes[node] == NULL) - { - std::cerr << "EMPTY NODE !!" << std::endl; - return ; - } - DirEntry& d(*static_cast(mNodes[node])); - - std::cerr << indent << "dir hash=" << d.dir_hash << ". name:" << d.dir_name << ", parent_path:" << d.dir_parent_path << ", modf time: " << d.dir_modtime << ", recurs_last_modf_time: " << d.dir_most_recent_time << ", parent: " << d.parent_index << ", row: " << d.row << ", subdirs: " ; - - for(uint32_t i=0;i(mNodes[d.subfiles[i]])); - std::cerr << indent << " hash:" << f.file_hash << " ts:" << (uint64_t)f.file_modtime << " " << f.file_size << " " << f.file_name << ", parent: " << f.parent_index << ", row: " << f.row << std::endl; - } -} - -bool InternalFileHierarchyStorage::nodeAccessError(const std::string& s) -{ - std::cerr << "(EE) InternalDirectoryStructure: ERROR: " << s << std::endl; - return false ; -} - -// Removes the given subdirectory from the parent node and all its pendign subdirs and files. - -bool InternalFileHierarchyStorage::recursRemoveDirectory(DirectoryStorage::EntryIndex dir) -{ - DirEntry& d(*static_cast(mNodes[dir])) ; - - RsFileHash hash = d.dir_hash ; - - for(uint32_t i=0;itype() == FileStorageNode::TYPE_FILE) - { - const FileEntry& fe(*static_cast(mNodes[i])) ; - - uint32_t file_section_offset = 0 ; - - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_PARENT_INDEX ,(uint32_t)fe.parent_index)) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_ROW ,(uint32_t)fe.row )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)i )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,fe.file_name )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,fe.file_size )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,fe.file_hash )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)fe.file_modtime)) throw std::runtime_error("Write error") ; - - if(!FileListIO::writeField(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_LOCAL_FILE_ENTRY,tmp_section_data,file_section_offset)) throw std::runtime_error("Write error") ; - } - else if(mNodes[i] != NULL && mNodes[i]->type() == FileStorageNode::TYPE_DIR) - { - const DirEntry& de(*static_cast(mNodes[i])) ; - - uint32_t dir_section_offset = 0 ; - - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_PARENT_INDEX ,(uint32_t)de.parent_index )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_ROW ,(uint32_t)de.row )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)i )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,de.dir_name )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_DIR_HASH ,de.dir_hash )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,de.dir_parent_path )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)de.dir_modtime )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,(uint32_t)de.dir_update_time )) throw std::runtime_error("Write error") ; - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)de.dir_most_recent_time )) throw std::runtime_error("Write error") ; - - if(!FileListIO::writeField(tmp_section_data,tmp_section_size,dir_section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)de.subdirs.size())) throw std::runtime_error("Write error") ; - - for(uint32_t j=0;j= mNodes.size()) - mNodes.resize(node_index+1,NULL) ; - - FileEntry *fe = new FileEntry(file_name,file_size,file_modtime,file_hash); - - fe->parent_index = parent_index ; - fe->row = row ; - - mNodes[node_index] = fe ; - mFileHashes[fe->file_hash] = node_index ; - - mTotalFiles++ ; - mTotalSize += file_size ; - } - else if(FileListIO::readField(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_LOCAL_DIR_ENTRY,node_section_data,node_section_size)) - { - uint32_t node_index ; - std::string dir_name ; - std::string dir_parent_path ; - RsFileHash dir_hash ; - uint32_t dir_modtime ; - uint32_t dir_update_time ; - uint32_t dir_most_recent_time ; - uint32_t row ; - uint32_t parent_index ; - - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_PARENT_INDEX ,parent_index )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_PARENT_INDEX ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_ROW ,row )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_ROW ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,node_index )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,dir_name )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_FILE_NAME ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_DIR_HASH ,dir_hash )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_DIR_HASH ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,dir_parent_path )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,dir_modtime )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_MODIF_TS ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,dir_update_time )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_UPDATE_TS ) ; - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,dir_most_recent_time )) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS) ; - - if(node_index >= mNodes.size()) - mNodes.resize(node_index+1,NULL) ; - - DirEntry *de = new DirEntry(dir_name) ; - de->dir_name = dir_name ; - de->dir_parent_path = dir_parent_path ; - de->dir_hash = dir_hash ; - de->dir_modtime = dir_modtime ; - de->dir_update_time = dir_update_time ; - de->dir_most_recent_time = dir_most_recent_time ; - - de->parent_index = parent_index ; - de->row = row ; - - uint32_t n_subdirs = 0 ; - uint32_t n_subfiles = 0 ; - - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_subdirs)) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RAW_NUMBER) ; - - for(uint32_t j=0;jsubdirs.push_back(di) ; - } - - if(!FileListIO::readField(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_subfiles)) throw read_error(node_section_data,node_section_size,node_section_offset,FILE_LIST_IO_TAG_RAW_NUMBER) ; - - for(uint32_t j=0;jsubfiles.push_back(fi) ; - } - mNodes[node_index] = de ; - mDirHashes[de->dir_hash] = node_index ; - } - else - throw read_error(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_LOCAL_FILE_ENTRY) ; - - free(node_section_data) ; - } - free(buffer) ; - - std::string err_str ; - - if(!check(err_str)) - std::cerr << "(EE) Error while loading file hierarchy " << fname << std::endl; - - recursUpdateCumulatedSize(mRoot); - - return true ; - } - catch(read_error& e) - { -#ifdef DEBUG_DIRECTORY_STORAGE - std::cerr << "Error while reading: " << e.what() << std::endl; -#endif - - if(buffer != NULL) - free(buffer) ; - return false; - } -} - diff --git a/libretroshare/src/file_sharing/dir_hierarchy.h b/libretroshare/src/file_sharing/dir_hierarchy.h deleted file mode 100644 index c6a28650b..000000000 --- a/libretroshare/src/file_sharing/dir_hierarchy.h +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: dir_hierarchy.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "directory_storage.h" - -class InternalFileHierarchyStorage -{ -public: - class FileStorageNode - { - public: - static const uint32_t TYPE_UNKNOWN = 0x0000 ; - static const uint32_t TYPE_FILE = 0x0001 ; - static const uint32_t TYPE_DIR = 0x0002 ; - - virtual ~FileStorageNode() {} - virtual uint32_t type() const =0; - - DirectoryStorage::EntryIndex parent_index; - uint32_t row ; - }; - class FileEntry: public FileStorageNode - { - public: - FileEntry() : file_size(0), file_modtime(0) {} - FileEntry(const std::string& name,uint64_t size,rstime_t modtime) : file_name(name),file_size(size),file_modtime(modtime) {} - FileEntry(const std::string& name,uint64_t size,rstime_t modtime,const RsFileHash& hash) : file_name(name),file_size(size),file_modtime(modtime),file_hash(hash) {} - - virtual uint32_t type() const { return FileStorageNode::TYPE_FILE ; } - virtual ~FileEntry() {} - - // local stuff - std::string file_name ; - uint64_t file_size ; - rstime_t file_modtime; - RsFileHash file_hash ; - }; - - class DirEntry: public FileStorageNode - { - public: - explicit DirEntry(const std::string& name) : dir_name(name), dir_cumulated_size(0), dir_modtime(0),dir_most_recent_time(0),dir_update_time(0) {} - virtual ~DirEntry() {} - - virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; } - - // local stuff - std::string dir_name ; - std::string dir_parent_path ; - RsFileHash dir_hash ; - uint64_t dir_cumulated_size; - - std::vector subdirs ; - std::vector subfiles ; - - rstime_t dir_modtime; - rstime_t dir_most_recent_time;// recursive most recent modification time, including files and subdirs in the entire hierarchy below. - rstime_t dir_update_time; // last time the information was updated for that directory. Includes subdirs indexes and subfile info. - }; - - // class stuff - InternalFileHierarchyStorage() ; - - bool load(const std::string& fname) ; - bool save(const std::string& fname) ; - - int parentRow(DirectoryStorage::EntryIndex e); - bool isIndexValid(DirectoryStorage::EntryIndex e) const; - bool getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const; - bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::set& subdirs, const RsFileHash &random_hash_seed); - bool removeDirectory(DirectoryStorage::EntryIndex indx) ; - bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const; - bool updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map& subfiles,std::map& new_files); - bool updateHash(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash); - bool updateFile(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash, const std::string& fname,uint64_t size, const rstime_t modf_time); - bool updateDirEntry(const DirectoryStorage::EntryIndex& indx, const std::string& dir_name, rstime_t most_recent_time, rstime_t dir_modtime, const std::vector &subdirs_hash, const std::vector &subfiles_array); - - // TS get/set functions. Take one of the class members as argument. - - bool getTS(const DirectoryStorage::EntryIndex& index,rstime_t& TS,rstime_t DirEntry::* ) const; - bool setTS(const DirectoryStorage::EntryIndex& index,rstime_t& TS,rstime_t DirEntry::* ) ; - - // Do a complete recursive sweep over sub-directories and files, and update the lst modf TS. This could be also performed by a cleanup method. - // Also keeps the high level statistics up to date. - - rstime_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index, bool &unfinished_files_present); - - // Do a complete recursive sweep over sub-directories and files, and update the cumulative size. - - uint64_t recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index); - - // hash stuff - - bool getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const ; - bool getIndexFromDirHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) ; - bool getIndexFromFileHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) ; - - // file/dir access and modification - bool findSubDirectory(DirectoryStorage::EntryIndex e,const std::string& s) const ; // returns true when s is the name of a sub-directory in the given entry e - - uint32_t mRoot ; - std::list mFreeNodes ; // keeps a list of free nodes in order to make insert effcieint - std::vector mNodes;// uses pointers to keep information about valid/invalid objects. - - void compress() ; // use empty space in the vector, mostly due to deleted entries. This is a complicated operation, mostly due to - // all the indirections used. Nodes need to be moved, renamed, etc. The operation discards all file entries that - // are not referenced. - - friend class DirectoryStorage ; // only class that can use this. - friend class LocalDirectoryStorage ; // only class that can use this. - - // Low level stuff. Should normally not be used externally. - - const FileStorageNode *getNode(DirectoryStorage::EntryIndex indx) const; - const DirEntry *getDirEntry(DirectoryStorage::EntryIndex indx) const; - const FileEntry *getFileEntry(DirectoryStorage::EntryIndex indx) const; - uint32_t getType(DirectoryStorage::EntryIndex indx) const; - DirectoryStorage::EntryIndex getSubFileIndex(DirectoryStorage::EntryIndex parent_index,uint32_t file_tab_index); - DirectoryStorage::EntryIndex getSubDirIndex(DirectoryStorage::EntryIndex parent_index,uint32_t dir_tab_index); - - // search. SearchHash is logarithmic. The other two are linear. - - bool searchHash(const RsFileHash& hash, DirectoryStorage::EntryIndex &result); - int searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const ; - int searchTerms(const std::list& terms, std::list &results) const ; // does a logical OR between items of the list of terms - - bool check(std::string& error_string) ;// checks consistency of storage. - - void print() const; - - // gets statistics about share files - - void getStatistics(SharedDirStats& stats) const ; - -private: - void recursPrint(int depth,DirectoryStorage::EntryIndex node) const; - static bool nodeAccessError(const std::string& s); - static RsFileHash createDirHash(const std::string& dir_name, const RsFileHash &dir_parent_hash, const RsFileHash &random_hash_salt) ; - - // Allocates a new entry in mNodes, possible re-using an empty slot and returns its index. - - DirectoryStorage::EntryIndex allocateNewIndex(); - - // Deletes an existing entry in mNodes, and keeps record of the indices that get freed. - - void deleteNode(DirectoryStorage::EntryIndex); - void deleteFileNode(DirectoryStorage::EntryIndex); - - // Removes the given subdirectory from the parent node and all its pendign subdirs. Files are kept, and will go during the cleaning - // phase. That allows to keep file information when moving them around. - - bool recursRemoveDirectory(DirectoryStorage::EntryIndex dir); - - // Map of the hash of all files. The file hashes are the sha1sum of the file data. - // is used for fast search access for FT. - // Note: We should try something faster than std::map. hash_map?? - // Unlike directories, multiple files may have the same hash. So this cannot be used for anything else than FT. - - std::map mFileHashes ; - - // The directory hashes are the sha1sum of the - // full public path to the directory. - // The later is used by synchronisation items in order - // to avoid sending explicit EntryIndex values. - // This is kept separate from mFileHashes because the two are used - // in very different ways. - // - std::map mDirHashes ; - - // high level statistics on the full hierarchy. Should be kept up to date. - - uint32_t mTotalFiles ; - uint64_t mTotalSize ; -}; - diff --git a/libretroshare/src/file_sharing/directory_list.h b/libretroshare/src/file_sharing/directory_list.h deleted file mode 100644 index c643b6153..000000000 --- a/libretroshare/src/file_sharing/directory_list.h +++ /dev/null @@ -1,13 +0,0 @@ -// This class keeps a shared directory. It's quite the equivalent of the old "FileIndex" class -// The main difference is that it is -// - extensible -// - fast to search (at least for hashes). Should provide possibly multiple search handles for -// the same file, e.g. if connexion is encrypted. -// - abstracts the browsing in a same manner. -// -class SharedDirectoryList -{ - public: - - DirEntry mRoot ; -}; diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc deleted file mode 100644 index c4a46f4fb..000000000 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ /dev/null @@ -1,961 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: directory_storage.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include - -#include "util/rstime.h" -#include "serialiser/rstlvbinary.h" -#include "retroshare/rspeers.h" -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "file_sharing_defaults.h" -#include "directory_storage.h" -#include "dir_hierarchy.h" -#include "filelist_io.h" - -#ifdef RS_DEEP_FILES_INDEX -# include "deep_search/filesindex.hpp" -#endif // def RS_DEEP_FILES_INDEX - -//#define DEBUG_REMOTE_DIRECTORY_STORAGE 1 - -/******************************************************************************************************************/ -/* Iterators */ -/******************************************************************************************************************/ - -DirectoryStorage::DirIterator::DirIterator(DirectoryStorage *s,DirectoryStorage::EntryIndex i) -{ - mStorage = s->mFileHierarchy ; - mParentIndex = i; - mDirTabIndex = 0; -} - -DirectoryStorage::FileIterator::FileIterator(DirectoryStorage *s,DirectoryStorage::EntryIndex i) -{ - mStorage = s->mFileHierarchy ; - mParentIndex = i; - mFileTabIndex = 0; -} - -DirectoryStorage::DirIterator& DirectoryStorage::DirIterator::operator++() -{ - ++mDirTabIndex ; - - return *this; -} -DirectoryStorage::FileIterator& DirectoryStorage::FileIterator::operator++() -{ - ++mFileTabIndex ; - - return *this; -} -DirectoryStorage::EntryIndex DirectoryStorage::FileIterator::operator*() const { return mStorage->getSubFileIndex(mParentIndex,mFileTabIndex) ; } -DirectoryStorage::EntryIndex DirectoryStorage::DirIterator ::operator*() const { return mStorage->getSubDirIndex(mParentIndex,mDirTabIndex) ; } - -DirectoryStorage::FileIterator::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } -DirectoryStorage::DirIterator ::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } - -RsFileHash DirectoryStorage::FileIterator::hash() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_hash):RsFileHash(); } -uint64_t DirectoryStorage::FileIterator::size() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_size):0; } -std::string DirectoryStorage::FileIterator::name() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_name):std::string(); } -rstime_t DirectoryStorage::FileIterator::modtime() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_modtime):0; } - -std::string DirectoryStorage::DirIterator::name() const { const InternalFileHierarchyStorage::DirEntry *d = mStorage->getDirEntry(**this) ; return d?(d->dir_name):std::string(); } - -/******************************************************************************************************************/ -/* Directory Storage */ -/******************************************************************************************************************/ - -DirectoryStorage::DirectoryStorage(const RsPeerId &pid,const std::string& fname) - : mPeerId(pid), mDirStorageMtx("Directory storage "+pid.toStdString()),mLastSavedTime(0),mChanged(false),mFileName(fname) -{ - { - RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy = new InternalFileHierarchyStorage(); - } - load(fname) ; -} - -DirectoryStorage::EntryIndex DirectoryStorage::root() const -{ - return EntryIndex(0) ; -} -int DirectoryStorage::parentRow(EntryIndex e) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - return mFileHierarchy->parentRow(e) ; -} -bool DirectoryStorage::getChildIndex(EntryIndex e,int row,EntryIndex& c) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - return mFileHierarchy->getChildIndex(e,row,c) ; -} - -uint32_t DirectoryStorage::getEntryType(const EntryIndex& indx) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - switch(mFileHierarchy->getType(indx)) - { - case InternalFileHierarchyStorage::FileStorageNode::TYPE_DIR: return DIR_TYPE_DIR ; - case InternalFileHierarchyStorage::FileStorageNode::TYPE_FILE: return DIR_TYPE_FILE ; - default: - return DIR_TYPE_UNKNOWN; - } -} - -bool DirectoryStorage::getDirectoryUpdateTime (EntryIndex index,rstime_t& update_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,update_TS,&InternalFileHierarchyStorage::DirEntry::dir_update_time ); } -bool DirectoryStorage::getDirectoryRecursModTime(EntryIndex index,rstime_t& rec_md_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,rec_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_most_recent_time); } -bool DirectoryStorage::getDirectoryLocalModTime (EntryIndex index,rstime_t& loc_md_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,loc_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_modtime ); } - -bool DirectoryStorage::setDirectoryUpdateTime (EntryIndex index,rstime_t update_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,update_TS,&InternalFileHierarchyStorage::DirEntry::dir_update_time ); } -bool DirectoryStorage::setDirectoryRecursModTime(EntryIndex index,rstime_t rec_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,rec_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_most_recent_time); } -bool DirectoryStorage::setDirectoryLocalModTime (EntryIndex index,rstime_t loc_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,loc_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_modtime ); } - -bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx, const std::set &subdirs, const RsFileHash& hash_salt) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - bool res = mFileHierarchy->updateSubDirectoryList(indx,subdirs,hash_salt) ; - mChanged = true ; - return res ; -} -bool DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::map& subfiles,std::map& new_files) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - bool res = mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ; - mChanged = true ; - return res ; -} -bool DirectoryStorage::removeDirectory(const EntryIndex& indx) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - bool res = mFileHierarchy->removeDirectory(indx); - mChanged = true ; - - return res ; -} - -void DirectoryStorage::locked_check() -{ - std::string error ; - if(!mFileHierarchy->check(error)) - std::cerr << "Check error: " << error << std::endl; -} - -void DirectoryStorage::getStatistics(SharedDirStats& stats) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->getStatistics(stats); -} - -bool DirectoryStorage::load(const std::string& local_file_name) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - mChanged = false ; - return mFileHierarchy->load(local_file_name); -} -void DirectoryStorage::save(const std::string& local_file_name) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->save(local_file_name); -} -void DirectoryStorage::print() -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->print(); -} - -int DirectoryStorage::searchTerms( - const std::list& terms, - std::list& results ) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - return mFileHierarchy->searchTerms(terms,results); -} -int DirectoryStorage::searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - return mFileHierarchy->searchBoolExp(exp,results); -} - -bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - d.children.clear() ; - uint32_t type = mFileHierarchy->getType(indx) ; - - d.ref = (void*)(intptr_t)indx ; - - if (type == InternalFileHierarchyStorage::FileStorageNode::TYPE_DIR) /* has children --- fill */ - { - const InternalFileHierarchyStorage::DirEntry *dir_entry = mFileHierarchy->getDirEntry(indx) ; - - /* extract all the entries */ - - for(DirectoryStorage::DirIterator it(this,indx);it;++it) - { - DirStub stub; - stub.type = DIR_TYPE_DIR; - stub.name = it.name(); - stub.ref = (void*)(intptr_t)*it; // this is updated by the caller, who knows which friend we're dealing with - - d.children.push_back(stub); - } - - for(DirectoryStorage::FileIterator it(this,indx);it;++it) - { - DirStub stub; - stub.type = DIR_TYPE_FILE; - stub.name = it.name(); - stub.ref = (void*)(intptr_t)*it; - - d.children.push_back(stub); - } - - d.type = DIR_TYPE_DIR; - d.hash.clear() ; - d.size = dir_entry->dir_cumulated_size;//dir_entry->subdirs.size() + dir_entry->subfiles.size(); - d.max_mtime = dir_entry->dir_most_recent_time ; - d.mtime = dir_entry->dir_modtime ; - d.name = dir_entry->dir_name; - d.path = RsDirUtil::makePath(dir_entry->dir_parent_path, dir_entry->dir_name) ; - d.parent = (void*)(intptr_t)dir_entry->parent_index ; - - if(indx == 0) - { - d.type = DIR_TYPE_PERSON ; - d.name = mPeerId.toStdString(); - } - } - else if(type == InternalFileHierarchyStorage::FileStorageNode::TYPE_FILE) - { - const InternalFileHierarchyStorage::FileEntry *file_entry = mFileHierarchy->getFileEntry(indx) ; - - d.type = DIR_TYPE_FILE; - d.size = file_entry->file_size; - d.max_mtime = file_entry->file_modtime ; - d.name = file_entry->file_name; - d.hash = file_entry->file_hash; - d.mtime = file_entry->file_modtime; - d.parent = (void*)(intptr_t)file_entry->parent_index ; - - const InternalFileHierarchyStorage::DirEntry *parent_dir_entry = mFileHierarchy->getDirEntry(file_entry->parent_index); - - if(parent_dir_entry != NULL) - d.path = RsDirUtil::makePath(parent_dir_entry->dir_parent_path, parent_dir_entry->dir_name) ; - else - d.path = "" ; - } - else - return false; - - d.flags.clear() ; - - return true; -} - -bool DirectoryStorage::getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - return mFileHierarchy->getDirHashFromIndex(index,hash) ; -} -bool DirectoryStorage::getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - return mFileHierarchy->getIndexFromDirHash(hash,index) ; -} - -void DirectoryStorage::checkSave() -{ - rstime_t now = time(NULL); - - if(mChanged && mLastSavedTime + MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE < now) - { - mFileHierarchy->recursUpdateCumulatedSize(mFileHierarchy->mRoot); - - { - RS_STACK_MUTEX(mDirStorageMtx) ; - locked_check(); - } - - save(mFileName); - - { - RS_STACK_MUTEX(mDirStorageMtx) ; - mLastSavedTime = now ; - mChanged = false ; - } - } -} -/******************************************************************************************************************/ -/* Local Directory Storage */ -/******************************************************************************************************************/ - -LocalDirectoryStorage::LocalDirectoryStorage(const std::string& fname,const RsPeerId& own_id) - : DirectoryStorage(own_id,fname) -{ - mTSChanged = false ; -} - -RsFileHash LocalDirectoryStorage::makeEncryptedHash(const RsFileHash& hash) -{ - return RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES); -} -bool LocalDirectoryStorage::locked_findRealHash(const RsFileHash& hash, RsFileHash& real_hash) const -{ - std::map::const_iterator it = mEncryptedHashes.find(hash) ; - - if(it == mEncryptedHashes.end()) - return false ; - - real_hash = it->second ; - return true ; -} - -int LocalDirectoryStorage::searchHash(const RsFileHash& hash, RsFileHash& real_hash, EntryIndex& result) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - if(locked_findRealHash(hash,real_hash) && mFileHierarchy->searchHash(real_hash,result)) - return true ; - - if(mFileHierarchy->searchHash(hash,result)) - { - real_hash.clear(); - return true ; - } - return false ; -} - -void LocalDirectoryStorage::setSharedDirectoryList(const std::list& lst) -{ - std::set dirs_with_new_virtualname ; - bool dirs_with_changed_flags = false ; - - { - RS_STACK_MUTEX(mDirStorageMtx) ; - - // Chose virtual name if not supplied, and remove duplicates. - - std::set virtual_names ; // maps virtual to real name - std::list processed_list ; - - for(std::list::const_iterator it(lst.begin());it!= lst.end();++it) - { - int i=0; - std::string candidate_virtual_name = it->virtualname ; - - if(candidate_virtual_name.empty()) - candidate_virtual_name = RsDirUtil::getTopDir(it->filename); - - while(virtual_names.find(candidate_virtual_name) != virtual_names.end()) - rs_sprintf_append(candidate_virtual_name, "-%d", ++i); - - SharedDirInfo d(*it); - d.virtualname = candidate_virtual_name ; - processed_list.push_back(d) ; - - virtual_names.insert(candidate_virtual_name) ; - } - - // now for each member of the processed list, check if it is an existing shared directory that has been changed. If so, we need to update the dir TS of that directory - - std::map new_dirs ; - - for(std::list::const_iterator it(processed_list.begin());it!=processed_list.end();++it) - { - std::map::iterator it2 = mLocalDirs.find(it->filename) ; - - if(it2 != mLocalDirs.end()) - { - if(it2->second.virtualname != it->virtualname) - dirs_with_new_virtualname.insert(it->filename) ; - - if(!SharedDirInfo::sameLists((*it).parent_groups,it2->second.parent_groups) || (*it).shareflags != it2->second.shareflags) - dirs_with_changed_flags = true ; - } - - new_dirs[it->filename] = *it; - } - - mLocalDirs = new_dirs ; - mTSChanged = true ; - } - - // now update the TS off-mutex. - - for(DirIterator dirit(this,root());dirit;++dirit) - if(dirs_with_new_virtualname.find(dirit.name()) != dirs_with_new_virtualname.end()) - { - std::cerr << "Updating TS of local dir \"" << dirit.name() << "\" with changed virtual name" << std::endl; - setDirectoryLocalModTime(*dirit,time(NULL)); - } - - if(dirs_with_changed_flags) - setDirectoryLocalModTime(0,time(NULL)) ; -} - -void LocalDirectoryStorage::getSharedDirectoryList(std::list& lst) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - lst.clear(); - - for(std::map::iterator it(mLocalDirs.begin());it!=mLocalDirs.end();++it) - lst.push_back(it->second) ; -} -void LocalDirectoryStorage::updateShareFlags(const SharedDirInfo& info) -{ - bool changed = false ; - - { - RS_STACK_MUTEX(mDirStorageMtx) ; - - std::map::iterator it = mLocalDirs.find(info.filename) ; - - if(it == mLocalDirs.end()) - { - std::cerr << "(EE) LocalDirectoryStorage::updateShareFlags: directory \"" << info.filename << "\" not found" << std::endl; - return ; - } - - // we compare the new info with the old one. If the two group lists have a different order, they will be seen as different. Not a big deal. We just - // want to make sure that if they are different, flags get updated. - - if(!SharedDirInfo::sameLists(it->second.parent_groups,info.parent_groups) || it->second.filename != info.filename || it->second.shareflags != info.shareflags || it->second.virtualname != info.virtualname) - { - it->second = info; - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "Updating dir mod time because flags at level 0 have changed." << std::endl; -#endif - changed = true ; - } - } - - if(changed) - { - setDirectoryLocalModTime(0,time(NULL)) ; - mTSChanged = true ; - } -} - -bool LocalDirectoryStorage::convertSharedFilePath(const std::string& path, std::string& fullpath) -{ - std::string shpath = RsDirUtil::removeRootDir(path); - std::string basedir = RsDirUtil::getRootDir(path); - std::string realroot ; - { - RS_STACK_MUTEX(mDirStorageMtx) ; - realroot = locked_findRealRootFromVirtualFilename(basedir); - } - - if (realroot.empty()) - return false; - - /* construct full name */ - fullpath = realroot + "/"; - fullpath += shpath; - - return true; -} - -void LocalDirectoryStorage::notifyTSChanged() -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - mTSChanged = true ; -} -void LocalDirectoryStorage::updateTimeStamps() -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - if(mTSChanged) - { -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "Updating recursive TS for local shared dirs..." << std::endl; -#endif - - bool unfinished_files_below ; - - rstime_t last_modf_time = mFileHierarchy->recursUpdateLastModfTime(EntryIndex(0),unfinished_files_below) ; - mTSChanged = false ; - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "LocalDirectoryStorage: global last modf time is " << last_modf_time << " (which is " << time(NULL) - last_modf_time << " secs ago), unfinished files below=" << unfinished_files_below << std::endl; -#else - // remove unused variable warning - // variable is only used for debugging - (void)last_modf_time; -#endif - } -} - -bool LocalDirectoryStorage::updateHash( - const EntryIndex& index, const RsFileHash& hash, - bool update_internal_hierarchy ) -{ - bool ret = false; - - { - RS_STACK_MUTEX(mDirStorageMtx); - - mEncryptedHashes[makeEncryptedHash(hash)] = hash ; - mChanged = true ; - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "Updating index of hash " << hash << " update_internal=" - << update_internal_hierarchy << std::endl; -#endif - - ret = (!update_internal_hierarchy) || - mFileHierarchy->updateHash(index,hash); - } // RS_STACK_MUTEX(mDirStorageMtx); - -#ifdef RS_DEEP_FILES_INDEX - FileInfo fInfo; - if( ret && getFileInfo(index, fInfo) && - fInfo.storage_permission_flags & DIR_FLAGS_ANONYMOUS_SEARCH ) - { - DeepFilesIndex dfi(DeepFilesIndex::dbDefaultPath()); - ret &= dfi.indexFile(fInfo.path, fInfo.fname, hash); - } -#endif // def RS_DEEP_FILES_INDEX - - return ret; -} -std::string LocalDirectoryStorage::locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const -{ - /**** MUST ALREADY BE LOCKED ****/ - - std::map::const_iterator cit = mLocalDirs.find(virtual_rootdir) ; - - if (cit == mLocalDirs.end()) - { - std::cerr << "(EE) locked_findRealRootFromVirtualFilename() Invalid RootDir: " << virtual_rootdir << std::endl; - return std::string(); - } - return cit->second.filename; -} - -bool LocalDirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) -{ - bool res = DirectoryStorage::extractData(indx,d) ; - - if(!res) - return false; - - // here we should update the file sharing flags - - return getFileSharingPermissions(indx,d.flags,d.parent_groups) ; -} - -bool LocalDirectoryStorage::getFileInfo(DirectoryStorage::EntryIndex i,FileInfo& info) -{ - DirDetails d; - extractData(i,d) ; - - if(d.type != DIR_TYPE_FILE) - { - std::cerr << "(EE) LocalDirectoryStorage: asked for file info for index " << i << " which is not a file." << std::endl; - return false; - } - - info.storage_permission_flags = d.flags; // Combination of the four RS_DIR_FLAGS_*. Updated when the file is a local stored file. - info.parent_groups = d.parent_groups; - info.transfer_info_flags = TransferRequestFlags(); // various flags from RS_FILE_HINTS_* - info.path = d.path + "/" + d.name; - info.fname = d.name; - info.hash = d.hash; - info.size = d.size; - - // all this stuff below is not useful in this case. - - info.mId = 0; /* (GUI) Model Id -> unique number */ - info.ext.clear(); - info.avail = 0; /* how much we have */ - info.rank = 0; - info.age = 0; - info.queue_position =0; - info.searchId = 0; /* 0 if none */ - - /* Transfer Stuff */ - info.transfered = 0; - info.tfRate = 0; /* in kbytes */ - info.downloadStatus = FT_STATE_COMPLETE ; - //std::list peers; - - info.priority = SPEED_NORMAL; - info.lastTS = 0; - - return true; -} - -bool LocalDirectoryStorage::getFileSharingPermissions(const EntryIndex& indx,FileStorageFlags& flags,std::list& parent_groups) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - return locked_getFileSharingPermissions(indx,flags,parent_groups) ; -} - -bool LocalDirectoryStorage::locked_getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags& flags, std::list &parent_groups) -{ - flags.clear() ; - parent_groups.clear(); - - std::string base_dir; - - const InternalFileHierarchyStorage::FileStorageNode *n = mFileHierarchy->getNode(indx) ; - - if(n == NULL) - return false ; - - for(DirectoryStorage::EntryIndex i=((n->type()==InternalFileHierarchyStorage::FileStorageNode::TYPE_FILE)?((intptr_t)n->parent_index):indx);;) - { - const InternalFileHierarchyStorage::DirEntry *e = mFileHierarchy->getDirEntry(i) ; - - if(e == NULL) - break ; - - if(e->parent_index == 0) - { - base_dir = e->dir_name ; - break ; - } - i = e->parent_index ; - } - - if(!base_dir.empty()) - { - std::map::const_iterator it = mLocalDirs.find(base_dir) ; - - if(it == mLocalDirs.end()) - { - std::cerr << "(II) base directory \"" << base_dir << "\" not found in shared dir list." << std::endl; - return false ; - } - - flags = it->second.shareflags; - parent_groups = it->second.parent_groups; - } - - return true; -} - -std::string LocalDirectoryStorage::locked_getVirtualDirName(EntryIndex indx) const -{ - if(indx == 0) - return std::string() ; - - const InternalFileHierarchyStorage::DirEntry *dir = mFileHierarchy->getDirEntry(indx); - - if(dir->parent_index != 0) - return dir->dir_name ; - - std::map::const_iterator it = mLocalDirs.find(dir->dir_name) ; - - if(it == mLocalDirs.end()) - { - std::cerr << "(EE) Cannot find real name " << dir->dir_name << " at level 1 among shared dirs. Bug?" << std::endl; - return std::string() ; - } - - return it->second.virtualname ; -} -std::string LocalDirectoryStorage::locked_getVirtualPath(EntryIndex indx) const -{ - if(indx == 0) - return std::string() ; - - std::string res ; - const InternalFileHierarchyStorage::DirEntry *dir = mFileHierarchy->getDirEntry(indx); - - while(dir->parent_index != 0) - { - dir = mFileHierarchy->getDirEntry(dir->parent_index) ; - res += dir->dir_name + "/"+ res ; - } - - std::map::const_iterator it = mLocalDirs.find(dir->dir_name) ; - - if(it == mLocalDirs.end()) - { - std::cerr << "(EE) Cannot find real name " << dir->dir_name << " at level 1 among shared dirs. Bug?" << std::endl; - return std::string() ; - } - return it->second.virtualname + "/" + res; -} - -bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinaryData& bindata,const RsPeerId& client_id) -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - const InternalFileHierarchyStorage::DirEntry *dir = mFileHierarchy->getDirEntry(indx); - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "Serialising Dir entry " << std::hex << indx << " for client id " << client_id << std::endl; -#endif - if(dir == NULL) - { - std::cerr << "(EE) serialiseDirEntry: ERROR. Cannot find entry " << (void*)(intptr_t)indx << std::endl; - return false; - } - - // compute list of allowed subdirs - std::vector allowed_subdirs ; - FileStorageFlags node_flags ; - std::list node_groups ; - - // for each subdir, compute the node flags and groups, then ask rsPeers to compute the mask that result from these flags for the particular peer supplied in parameter - - for(uint32_t i=0;isubdirs.size();++i) - if(indx != 0 || (locked_getFileSharingPermissions(dir->subdirs[i],node_flags,node_groups) && (rsPeers->computePeerPermissionFlags(client_id,node_flags,node_groups) & RS_FILE_HINTS_BROWSABLE))) - { - RsFileHash hash ; - if(!mFileHierarchy->getDirHashFromIndex(dir->subdirs[i],hash)) - { - std::cerr << "(EE) Cannot get hash from subdir index " << dir->subdirs[i] << ". Weird bug." << std::endl ; - return false; - } - allowed_subdirs.push_back(hash) ; -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << " pushing subdir " << hash << ", array position=" << i << " indx=" << dir->subdirs[i] << std::endl; -#endif - } -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - else - std::cerr << " not pushing subdir " << hash << ", array position=" << i << " indx=" << dir->subdirs[i] << ": permission denied for this peer." << std::endl; -#endif - - // now count the files that do not have a null hash (meaning the hash has indeed been computed) - - uint32_t allowed_subfiles = 0 ; - - for(uint32_t i=0;isubfiles.size();++i) - { - const InternalFileHierarchyStorage::FileEntry *file = mFileHierarchy->getFileEntry(dir->subfiles[i]) ; - if(file != NULL && !file->file_hash.isNull()) - allowed_subfiles++ ; - } - - unsigned char *section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; - - if(!section_data) - return false ; - - uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; - uint32_t section_offset = 0; - - // we need to send: - // - the name of the directory, its TS - // - the index entry for each subdir (the updte TS are exchanged at a higher level) - // - the file info for each subfile - // - std::string virtual_dir_name = locked_getVirtualDirName(indx) ; - - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,virtual_dir_name )) { free(section_data); return false ;} - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,(uint32_t)dir->dir_most_recent_time)) { free(section_data); return false ;} - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)dir->dir_modtime )) { free(section_data); return false ;} - - // serialise number of subdirs and number of subfiles - - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subdirs.size() )) { free(section_data); return false ;} - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,(uint32_t)allowed_subfiles )) { free(section_data); return false ;} - - // serialise subdirs entry indexes - - for(uint32_t i=0;isubfiles.size();++i) - { - uint32_t file_section_offset = 0 ; - - const InternalFileHierarchyStorage::FileEntry *file = mFileHierarchy->getFileEntry(dir->subfiles[i]) ; - - if(file == NULL || file->file_hash.isNull()) - { - std::cerr << "(II) skipping unhashed or Null file entry " << dir->subfiles[i] << " to get/send file info." << std::endl; - continue ; - } - - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) { free(section_data);free(file_section_data);return false ;} - if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,(uint32_t)file->file_modtime)) { free(section_data);free(file_section_data);return false ;} - - // now write the whole string into a single section in the file - - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_offset)) { free(section_data); free(file_section_data);return false ;} - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << " pushing subfile " << file->hash << ", array position=" << i << " indx=" << dir->subfiles[i] << std::endl; -#endif - } - free(file_section_data) ; - -#ifdef DEBUG_LOCAL_DIRECTORY_STORAGE - std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl; -#endif - - bindata.bin_data = realloc(section_data,section_offset) ; // This discards the possibly unused trailing bytes in the end of section_data - bindata.bin_len = section_offset ; - - return true ; -} - - -/******************************************************************************************************************/ -/* Remote Directory Storage */ -/******************************************************************************************************************/ - -RemoteDirectoryStorage::RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) - : DirectoryStorage(pid,fname) -{ - mLastSweepTime = time(NULL) - (RSRandom::random_u32() % DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP) ; - - std::cerr << "Loaded remote directory for peer " << pid << ", inited last sweep time to " << time(NULL) - mLastSweepTime << " secs ago." << std::endl; -#ifdef DEBUG_REMOTE_DIRECTORY_STORAGE - mFileHierarchy->print(); -#endif -} - -bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,const RsTlvBinaryData& bindata) -{ - const unsigned char *section_data = (unsigned char*)bindata.bin_data ; - uint32_t section_size = bindata.bin_len ; - uint32_t section_offset=0 ; - -#ifdef DEBUG_REMOTE_DIRECTORY_STORAGE - std::cerr << "RemoteDirectoryStorage::deserialiseDirEntry(): deserialising directory content for friend " << peerId() << ", and directory " << indx << std::endl; -#endif - - std::string dir_name ; - uint32_t most_recent_time ,dir_modtime ; - - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,dir_name )) return false ; - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,most_recent_time)) return false ; - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,dir_modtime )) return false ; - -#ifdef DEBUG_REMOTE_DIRECTORY_STORAGE - std::cerr << " dir name : \"" << dir_name << "\"" << std::endl; - std::cerr << " most recent time : " << most_recent_time << std::endl; - std::cerr << " modification time : " << dir_modtime << std::endl; -#endif - - // serialise number of subdirs and number of subfiles - - uint32_t n_subdirs,n_subfiles ; - - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_subdirs )) return false ; - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_subfiles )) return false ; - -#ifdef DEBUG_REMOTE_DIRECTORY_STORAGE - std::cerr << " number of subdirs : " << n_subdirs << std::endl; - std::cerr << " number of files : " << n_subfiles << std::endl; -#endif - - // serialise subdirs entry indexes - - std::vector subdirs_hashes ; - RsFileHash subdir_hash ; - - for(uint32_t i=0;i subfiles_array ; - - // Pre-allocate file_section_data, so that read_field does not need to do it many times. - - unsigned char *file_section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; - - if(!file_section_data) - return false ; - - uint32_t file_section_size = FL_BASE_TMP_SECTION_SIZE ; - - for(uint32_t i=0;iupdateDirEntry(indx,dir_name,most_recent_time,dir_modtime,subdirs_hashes,subfiles_array)) - { - std::cerr << "(EE) Cannot update dir entry with index " << indx << ": entry does not exist." << std::endl; - return false ; - } - - mChanged = true ; - - return true ; -} - -int RemoteDirectoryStorage::searchHash(const RsFileHash& hash, EntryIndex& result) const -{ - RS_STACK_MUTEX(mDirStorageMtx) ; - - return mFileHierarchy->searchHash(hash,result); -} - - - diff --git a/libretroshare/src/file_sharing/directory_storage.h b/libretroshare/src/file_sharing/directory_storage.h deleted file mode 100644 index 670682be3..000000000 --- a/libretroshare/src/file_sharing/directory_storage.h +++ /dev/null @@ -1,318 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: directory_storage.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "retroshare/rsids.h" -#include "retroshare/rsfiles.h" -#include "util/rstime.h" - -#define NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; } - -class RsTlvBinaryData ; -class InternalFileHierarchyStorage ; -class RsTlvBinaryData ; - -class DirectoryStorage -{ - public: - DirectoryStorage(const RsPeerId& pid, const std::string& fname) ; - virtual ~DirectoryStorage() {} - - typedef uint32_t EntryIndex ; - static const EntryIndex NO_INDEX = 0xffffffff; - - void save() const ; - - // These functions are to be used by file transfer and file search. - - virtual int searchTerms(const std::list& terms, std::list &results) const ; - virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list &results) const ; - - // gets/sets the various time stamps: - // - bool getDirectoryRecursModTime(EntryIndex index,rstime_t& recurs_max_modf_TS) const ; // last modification time, computed recursively over all subfiles and directories - bool getDirectoryLocalModTime (EntryIndex index,rstime_t& motime_TS) const ; // last modification time for that index only - bool getDirectoryUpdateTime (EntryIndex index,rstime_t& update_TS) const ; // last time the entry was updated. This is only used on the RemoteDirectoryStorage side. - - bool setDirectoryRecursModTime(EntryIndex index,rstime_t recurs_max_modf_TS) ; - bool setDirectoryLocalModTime (EntryIndex index,rstime_t modtime_TS) ; - bool setDirectoryUpdateTime (EntryIndex index,rstime_t update_TS) ; - - uint32_t getEntryType(const EntryIndex& indx) ; // WARNING: returns DIR_TYPE_*, not the internal directory storage stuff. - virtual bool extractData(const EntryIndex& indx,DirDetails& d); - - // This class allows to abstractly browse the stored directory hierarchy in a depth-first manner. - // It gives access to sub-files and sub-directories below. When using it, the client should make sure - // that the DirectoryStorage is properly locked, since the iterator cannot lock it. - // - class DirIterator - { - public: - DirIterator(const DirIterator& d) ; - DirIterator(DirectoryStorage *d,EntryIndex i) ; - - DirIterator& operator++() ; - EntryIndex operator*() const ; - - operator bool() const ; // used in for loops. Returns true when the iterator is valid. - - // info about the directory that is pointed by the iterator - - std::string name() const ; - rstime_t last_modif_time() const ; // last time a file in this directory or in the directories below has been modified. - rstime_t last_update_time() const ; // last time this directory was updated - private: - EntryIndex mParentIndex ; // index of the parent dir. - uint32_t mDirTabIndex ; // index in the vector of subdirs. - InternalFileHierarchyStorage *mStorage ; - - friend class DirectoryStorage ; - }; - class FileIterator - { - public: - explicit FileIterator(DirIterator& d); // crawls all files in specified directory - FileIterator(DirectoryStorage *d,EntryIndex e); // crawls all files in specified directory - - FileIterator& operator++() ; - EntryIndex operator*() const ; // current file entry - - operator bool() const ; // used in for loops. Returns true when the iterator is valid. - - // info about the file that is pointed by the iterator - - std::string name() const ; - uint64_t size() const ; - RsFileHash hash() const ; - rstime_t modtime() const ; - - private: - EntryIndex mParentIndex ; // index of the parent dir. - uint32_t mFileTabIndex ; // index in the vector of subdirs. - InternalFileHierarchyStorage *mStorage ; - }; - - struct FileTS - { - uint64_t size ; - rstime_t modtime; - }; - - EntryIndex root() const ; // returns the index of the root directory entry. This is generally 0. - const RsPeerId& peerId() const { return mPeerId ; } // peer ID of who owns that file list. - int parentRow(EntryIndex e) const ; // position of the current node, in the array of children at its parent node. Used by GUI for display. - bool getChildIndex(EntryIndex e,int row,EntryIndex& c) const; // returns the index of the children node at position "row" in the children nodes. Used by GUI for display. - - // Sets the subdirectory/subfiles list of entry indx the supplied one, possible adding and removing directories (resp.files). New directories are set empty with - // just a name and need to be updated later on. New files are returned in a list so that they can be sent to hash cache. - // - bool updateSubDirectoryList(const EntryIndex& indx, const std::set& subdirs, const RsFileHash &random_hash_salt) ; - bool updateSubFilesList(const EntryIndex& indx, const std::map &subfiles, std::map &new_files) ; - bool removeDirectory(const EntryIndex& indx) ; - - // Returns the hash of the directory at the given index and reverse. This hash is set as random the first time it is used (when updating directories). It will be - // used by the sync system to designate the directory without referring to index (index could be used to figure out the existance of hidden directories) - - bool getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const ; // constant cost - bool getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const ; // log cost. - - // gathers statistics from the internal directory structure - - void getStatistics(SharedDirStats& stats) ; - - void print(); - void cleanup(); - - /*! - * \brief checkSave - * Checks the time of last saving, last modification time, and saves if needed. - */ - void checkSave() ; - - const std::string& filename() const { return mFileName ; } - - protected: - bool load(const std::string& local_file_name) ; - void save(const std::string& local_file_name) ; - - private: - - // debug - void locked_check(); - - // storage of internal structure. Totally hidden from the outside. EntryIndex is simply the index of the entry in the vector. - - RsPeerId mPeerId; - - protected: - mutable RsMutex mDirStorageMtx ; - - InternalFileHierarchyStorage *mFileHierarchy ; - - rstime_t mLastSavedTime ; - bool mChanged ; - std::string mFileName; -}; - -class RemoteDirectoryStorage: public DirectoryStorage -{ -public: - RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) ; - virtual ~RemoteDirectoryStorage() {} - - /*! - * \brief deserialiseDirEntry - * Loads a serialised directory content coming from a friend. The directory entry needs to exist already, - * as it is created when updating the parent. - * - * \param indx index of the directory to update - * \param bindata binary data to deserialise from - * \return false when the directory cannot be found. - */ - bool deserialiseUpdateDirEntry(const EntryIndex& indx,const RsTlvBinaryData& data) ; - - /*! - * \brief lastSweepTime - * returns the last time a sweep has been done over the directory in order to check update TS. - * \return - */ - rstime_t& lastSweepTime() { return mLastSweepTime ; } - - /*! - * \brief searchHash - * Looks into local database of shared files for the given hash. - * \param hash hash to look for - * \param results Entry index of the file that is found - * \return - * true is a file is found - * false otherwise. - */ - virtual int searchHash(const RsFileHash& hash, EntryIndex& results) const ; - -private: - rstime_t mLastSweepTime ; -}; - -class LocalDirectoryStorage: public DirectoryStorage -{ -public: - LocalDirectoryStorage(const std::string& fname,const RsPeerId& own_id); - virtual ~LocalDirectoryStorage() {} - - /*! - * \brief [gs]etSharedDirectoryList - * Gets/sets the list of shared directories. Each directory is supplied with a virtual name (the name the friends will see), and sharing flags/groups. - * \param lst - */ - void setSharedDirectoryList(const std::list& lst) ; - void getSharedDirectoryList(std::list& lst) ; - - void updateShareFlags(const SharedDirInfo& info) ; - bool convertSharedFilePath(const std::string& path_with_virtual_name,std::string& fullpath) ; - - virtual bool updateHash(const EntryIndex& index, const RsFileHash& hash, bool update_internal_hierarchy); - /*! - * \brief searchHash - * Looks into local database of shared files for the given hash. Also looks for files such that the hash of the hash - * matches the given hash, and returns the real hash. - * \param hash hash to look for - * \param real_hash hash such that H(real_hash) = hash, or null hash if not found. - * \param results Entry index of the file that is found - * \return - * true is a file is found - * false otherwise. - */ - virtual int searchHash(const RsFileHash& hash, RsFileHash &real_hash, EntryIndex &results) const ; - - /*! - * \brief updateTimeStamps - * Checks recursive TS and update the if needed. - */ - void updateTimeStamps(); - - /*! - * \brief notifyTSChanged - * Use this to force an update of the recursive TS, when calling updateTimeStamps(); - */ - void notifyTSChanged(); - /*! - * \brief getFileInfo Converts an index info a full file info structure. - * \param i index in the directory structure - * \param info structure to be filled in - * \return false if the file does not exist, or is a directory,... - */ - bool getFileInfo(DirectoryStorage::EntryIndex i,FileInfo& info) ; - - /*! - * \brief getFileSharingPermissions - * Computes the flags and parent groups for any index. - * \param indx index of the entry to compute the flags for - * \param flags computed flags - * \param parent_groups computed parent groups - * \return - * false if the index is not valid - * false otherwise - */ - bool getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags &flags, std::list &parent_groups); - - virtual bool extractData(const EntryIndex& indx,DirDetails& d) ; - - /*! - * \brief serialiseDirEntry - * Produced a serialised directory content listing suitable for export to friends. - * - * \param indx index of the directory to serialise - * \param bindata binary data created by serialisation - * \param client_id Peer id to be serialised to. Depending on permissions, some subdirs can be removed. - * \return false when the directory cannot be found. - */ - bool serialiseDirEntry(const EntryIndex& indx, RsTlvBinaryData& bindata, const RsPeerId &client_id) ; - -private: - static RsFileHash makeEncryptedHash(const RsFileHash& hash); - bool locked_findRealHash(const RsFileHash& hash, RsFileHash& real_hash) const; - std::string locked_getVirtualPath(EntryIndex indx) const ; - std::string locked_getVirtualDirName(EntryIndex indx) const ; - - bool locked_getFileSharingPermissions(const EntryIndex& indx, FileStorageFlags &flags, std::list& parent_groups); - std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const; - - std::map mLocalDirs ; // map is better for search. it->first=it->second.filename - std::map mEncryptedHashes; // map such that hash(it->second) = it->first - - bool mTSChanged ; -}; - - - - - - - - - - - diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc deleted file mode 100644 index 828d1ee2c..000000000 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ /dev/null @@ -1,416 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: directory_updater.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include "util/folderiterator.h" -#include "util/rstime.h" -#include "rsserver/p3face.h" - -#include "directory_storage.h" -#include "directory_updater.h" -#include "file_sharing_defaults.h" - -//#define DEBUG_LOCAL_DIR_UPDATER 1 - -//=============================================================================================================// -// Local Directory Updater // -//=============================================================================================================// - -LocalDirectoryUpdater::LocalDirectoryUpdater(HashStorage *hc,LocalDirectoryStorage *lds) - : mHashCache(hc), mSharedDirectories(lds) - , mLastSweepTime(0), mLastTSUpdateTime(0) - , mDelayBetweenDirectoryUpdates(DELAY_BETWEEN_DIRECTORY_UPDATES) - , mIsEnabled(false), mFollowSymLinks(FOLLOW_SYMLINKS_DEFAULT) - , mIgnoreDuplicates(true) - /* Can be left to false, but setting it to true will force to re-hash any file that has been left unhashed in the last session.*/ - , mNeedsFullRecheck(true) - , mIsChecking(false), mForceUpdate(false), mIgnoreFlags (0), mMaxShareDepth(0) -{ -} - -bool LocalDirectoryUpdater::isEnabled() const -{ - return mIsEnabled ; -} -void LocalDirectoryUpdater::setEnabled(bool b) -{ - if(mIsEnabled == b) return; - if(!b) RsThread::askForStop(); - else if(!RsThread::isRunning()) start("fs dir updater"); - mIsEnabled = b ; -} - -void LocalDirectoryUpdater::threadTick() -{ - rstime_t now = time(NULL) ; - - if (mIsEnabled || mForceUpdate) - { - if(now > mDelayBetweenDirectoryUpdates + mLastSweepTime) - { - bool some_files_not_ready = false ; - - if(sweepSharedDirectories(some_files_not_ready)) - { - if(some_files_not_ready) - { - mNeedsFullRecheck = true ; - mLastSweepTime = now - mDelayBetweenDirectoryUpdates + 60 ; // retry 20 secs from now - - std::cerr << "(II) some files being modified. Will re-scan in 60 secs." << std::endl; - } - else - { - mNeedsFullRecheck = false ; - mLastSweepTime = now ; - } - - mSharedDirectories->notifyTSChanged(); - mForceUpdate = false ; - } - else - std::cerr << "(WW) sweepSharedDirectories() failed. Will do it again in a short time." << std::endl; - } - - if(now > DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE + mLastTSUpdateTime) - { - mSharedDirectories->updateTimeStamps() ; - mLastTSUpdateTime = now ; - } - } - - for(uint32_t i=0;i<10;++i) - { - rstime::rs_usleep(1*1000*1000); - - { - if(mForceUpdate) - break ; - } - } -} - -void LocalDirectoryUpdater::forceUpdate(bool add_safe_delay) -{ - mForceUpdate = true ; - mLastSweepTime = rstime_t(time(NULL)) - rstime_t(mDelayBetweenDirectoryUpdates) ; - - if(add_safe_delay) - mLastSweepTime += rstime_t(MIN_TIME_AFTER_LAST_MODIFICATION); - - if(mHashCache != NULL && mHashCache->hashingProcessPaused()) - mHashCache->togglePauseHashingProcess(); -} - -bool LocalDirectoryUpdater::sweepSharedDirectories(bool& some_files_not_ready) -{ - if(mHashSalt.isNull()) - { - std::cerr << "(EE) no salt value in LocalDirectoryUpdater. Is that a bug?" << std::endl; - return false; - } - - mIsChecking = true ; - - RsServer::notify()->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] LocalDirectoryUpdater::sweep()" << std::endl; -#endif - - // recursive update algorithm works that way: - // - the external loop starts on the shared directory list and goes through sub-directories - // - at the same time, it updates the local list of shared directories. A single sweep is performed over the whole directory structure. - // - the information that is costly to compute (the hash) is store externally into a separate structure. - // - doing so, changing directory names or moving files between directories does not cause a re-hash of the content. - // - std::list shared_directory_list ; - mSharedDirectories->getSharedDirectoryList(shared_directory_list); - - std::set sub_dir_list ; - - // We re-check that each dir actually exists. It might have been removed from the disk. - - for(std::list::const_iterator real_dir_it(shared_directory_list.begin());real_dir_it!=shared_directory_list.end();++real_dir_it) - if(RsDirUtil::checkDirectory( (*real_dir_it).filename ) ) - sub_dir_list.insert( (*real_dir_it).filename ) ; - - // make sure that entries in stored_dir_it are the same than paths in real_dir_it, and in the same order. - - mSharedDirectories->updateSubDirectoryList(mSharedDirectories->root(),sub_dir_list,mHashSalt) ; - - // now for each of them, go recursively and match both files and dirs - - std::set existing_dirs ; - - for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,mSharedDirectories->root()) ; stored_dir_it;++stored_dir_it) - { -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] recursing into " << stored_dir_it.name() << std::endl; -#endif - existing_dirs.insert(RsDirUtil::removeSymLinks(stored_dir_it.name())); - - recursUpdateSharedDir(stored_dir_it.name(), *stored_dir_it,existing_dirs,1,some_files_not_ready) ; // here we need to use the list that was stored, instead of the shared dir list, because the two - // are not necessarily in the same order. - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - mIsChecking = false ; - - return true ; -} - -void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx,std::set& existing_directories,uint32_t current_depth,bool& some_files_not_ready) -{ -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << "[directory storage] parsing directory " << cumulated_path << ", index=" << indx << std::endl; -#endif - - // make sure list of subdirs is the same - // make sure list of subfiles is the same - // request all hashes to the hashcache - - librs::util::FolderIterator dirIt(cumulated_path,mFollowSymLinks,false); // disallow symbolic links and files from the future. - - rstime_t dir_local_mod_time ; - if(!mSharedDirectories->getDirectoryLocalModTime(indx,dir_local_mod_time)) - { - std::cerr << "(EE) Cannot get local mod time for dir index " << indx << std::endl; - return; - } - - rstime_t now = time(NULL) ; - - if(mNeedsFullRecheck || dirIt.dir_modtime() > dir_local_mod_time) // the > is because we may have changed the virtual name, and therefore the TS wont match. - // we only want to detect when the directory has changed on the disk - { - // collect subdirs and subfiles - - std::map subfiles ; - std::set subdirs ; - - for(;dirIt.isValid();dirIt.next()) - if(filterFile(dirIt.file_name())) - { - switch(dirIt.file_type()) - { - case librs::util::FolderIterator::TYPE_FILE: - - if(dirIt.file_modtime() + MIN_TIME_AFTER_LAST_MODIFICATION < now) - { - subfiles[dirIt.file_name()].modtime = dirIt.file_modtime() ; - subfiles[dirIt.file_name()].size = dirIt.file_size(); -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " adding sub-file \"" << dirIt.file_name() << "\"" << std::endl; -#endif - } - else - { - some_files_not_ready = true ; - - std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being written to. Keeping it for later." << std::endl; - } - - break; - - case librs::util::FolderIterator::TYPE_DIR: - { - bool dir_is_accepted = true ; - - if( (mMaxShareDepth > 0u && current_depth > mMaxShareDepth) || (mMaxShareDepth==0 && current_depth >= 64)) // 64 is here as a safe limit, to make loops impossible. - dir_is_accepted = false ; - - if(dir_is_accepted && mFollowSymLinks && mIgnoreDuplicates) - { - std::string real_path = RsDirUtil::removeSymLinks(cumulated_path + "/" + dirIt.file_name()) ; - - if(existing_directories.end() != existing_directories.find(real_path)) - { - std::cerr << "(WW) Directory " << cumulated_path << " has real path " << real_path << " which already belongs to another shared directory. Ignoring" << std::endl; - dir_is_accepted = false ; - } - else - existing_directories.insert(real_path) ; - } - - if(dir_is_accepted) - subdirs.insert(dirIt.file_name()); - -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " adding sub-dir \"" << dirIt.file_name() << "\"" << std::endl; -#endif - } - break; - default: - std::cerr << "(EE) Dir entry of unknown type with path \"" << cumulated_path << "/" << dirIt.file_name() << "\"" << std::endl; - } - } - // update folder modificatoin time, which is the only way to detect e.g. removed or renamed files. - - mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()) ; - - // update file and dir lists for current directory. - - mSharedDirectories->updateSubDirectoryList(indx,subdirs,mHashSalt) ; - - std::map new_files ; - mSharedDirectories->updateSubFilesList(indx,subfiles,new_files) ; - - // now go through list of subfiles and request the hash to hashcache - - for(DirectoryStorage::FileIterator dit(mSharedDirectories,indx);dit;++dit) - { - // ask about the hash. If not present, ask HashCache. If not present, or different, the callback will update it. - - RsFileHash hash ; - - // mSharedDirectories does two things: store H(F), and compute H(H(F)), which is used in FT. The later is always needed. - - if(mHashCache->requestHash(cumulated_path + "/" + dit.name(),dit.size(),dit.modtime(),hash,this,*dit)) - mSharedDirectories->updateHash(*dit,hash,hash != dit.hash()); - } - } -#ifdef DEBUG_LOCAL_DIR_UPDATER - else - std::cerr << " directory is unchanged. Keeping existing files and subdirs list." << std::endl; -#endif - - // go through the list of sub-dirs and recursively update - - for(DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,indx) ; stored_dir_it; ++stored_dir_it) - { -#ifdef DEBUG_LOCAL_DIR_UPDATER - std::cerr << " recursing into " << stored_dir_it.name() << std::endl; -#endif - recursUpdateSharedDir(cumulated_path + "/" + stored_dir_it.name(), *stored_dir_it,existing_directories,current_depth+1,some_files_not_ready) ; - } -} - -bool LocalDirectoryUpdater::filterFile(const std::string& fname) const -{ - if(mIgnoreFlags & RS_FILE_SHARE_FLAGS_IGNORE_SUFFIXES) - for(auto it(mIgnoredSuffixes.begin());it!=mIgnoredSuffixes.end();++it) - if(fname.size() >= (*it).size() && fname.substr( fname.size() - (*it).size()) == *it) - { - std::cerr << "(II) ignoring file " << fname << ", because it matches suffix \"" << *it << "\"" << std::endl; - return false ; - } - - if(mIgnoreFlags & RS_FILE_SHARE_FLAGS_IGNORE_PREFIXES) - for(auto it(mIgnoredPrefixes.begin());it!=mIgnoredPrefixes.end();++it) - if(fname.size() >= (*it).size() && fname.substr( 0,(*it).size()) == *it) - { - std::cerr << "(II) ignoring file " << fname << ", because it matches prefix \"" << *it << "\"" << std::endl; - return false ; - } - - return true ; -} - -void LocalDirectoryUpdater::togglePauseHashingProcess() -{ - mHashCache->togglePauseHashingProcess() ; -} -bool LocalDirectoryUpdater::hashingProcessPaused() -{ - return mHashCache->hashingProcessPaused(); -} - -bool LocalDirectoryUpdater::inDirectoryCheck() const -{ - return mHashCache->isRunning(); -} - -void LocalDirectoryUpdater::hash_callback(uint32_t client_param, const std::string &/*name*/, const RsFileHash &hash, uint64_t /*size*/) -{ - if(!mSharedDirectories->updateHash(DirectoryStorage::EntryIndex(client_param),hash,true)) - std::cerr << "(EE) Cannot update file. Something's wrong." << std::endl; - - mSharedDirectories->notifyTSChanged() ; -} - -bool LocalDirectoryUpdater::hash_confirm(uint32_t client_param) -{ - return mSharedDirectories->getEntryType(DirectoryStorage::EntryIndex(client_param)) == DIR_TYPE_FILE ; -} - -void LocalDirectoryUpdater::setFileWatchPeriod(int seconds) -{ - mDelayBetweenDirectoryUpdates = seconds ; -} -uint32_t LocalDirectoryUpdater::fileWatchPeriod() const -{ - return mDelayBetweenDirectoryUpdates ; -} - -void LocalDirectoryUpdater::setFollowSymLinks(bool b) -{ - if(b != mFollowSymLinks) - mNeedsFullRecheck = true ; - - mFollowSymLinks = b ; - - forceUpdate(false); -} - -bool LocalDirectoryUpdater::followSymLinks() const -{ - return mFollowSymLinks ; -} - -void LocalDirectoryUpdater::setIgnoreLists(const std::list& ignored_prefixes,const std::list& ignored_suffixes,uint32_t ignore_flags) -{ - mIgnoredPrefixes = ignored_prefixes ; - mIgnoredSuffixes = ignored_suffixes ; - mIgnoreFlags = ignore_flags; -} -bool LocalDirectoryUpdater::getIgnoreLists(std::list& ignored_prefixes,std::list& ignored_suffixes,uint32_t& ignore_flags) const -{ - ignored_prefixes = mIgnoredPrefixes; - ignored_suffixes = mIgnoredSuffixes; - ignore_flags = mIgnoreFlags ; - - return true; -} - -int LocalDirectoryUpdater::maxShareDepth() const -{ - return mMaxShareDepth ; -} - -void LocalDirectoryUpdater::setMaxShareDepth(uint32_t d) -{ - if(d != mMaxShareDepth) - mNeedsFullRecheck = true ; - - mMaxShareDepth = d ; -} - -bool LocalDirectoryUpdater::ignoreDuplicates() const -{ - return mIgnoreDuplicates; -} - -void LocalDirectoryUpdater::setIgnoreDuplicates(bool b) -{ - if(b != mIgnoreDuplicates) - mNeedsFullRecheck = true ; - - mIgnoreDuplicates = b ; -} diff --git a/libretroshare/src/file_sharing/directory_updater.h b/libretroshare/src/file_sharing/directory_updater.h deleted file mode 100644 index b7d72b3a9..000000000 --- a/libretroshare/src/file_sharing/directory_updater.h +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: directory_updater.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -// This class crawls the given directry hierarchy and updates it. It does so by calling the -// shared file list source. This source may be of two types: -// - local: directories are crawled n disk and files are hashed / requested from a cache -// - remote: directories are requested remotely to a providing client -// -#include "file_sharing/hash_cache.h" -#include "file_sharing/directory_storage.h" -#include "util/rstime.h" - -class LocalDirectoryUpdater: public HashStorageClient, public RsTickingThread -{ -public: - LocalDirectoryUpdater(HashStorage *hash_cache,LocalDirectoryStorage *lds) ; - virtual ~LocalDirectoryUpdater() {} - - void forceUpdate(bool add_safe_delay); - bool inDirectoryCheck() const ; - void togglePauseHashingProcess(); - bool hashingProcessPaused(); - - void setHashSalt(const RsFileHash& hash) { mHashSalt = hash; } - const RsFileHash& hashSalt() const { return mHashSalt; } - - void setFileWatchPeriod(int seconds) ; - uint32_t fileWatchPeriod() const ; - - void setFollowSymLinks(bool b) ; - bool followSymLinks() const ; - - void setEnabled(bool b) ; - bool isEnabled() const ; - - void setIgnoreLists(const std::list& ignored_prefixes,const std::list& ignored_suffixes,uint32_t ignore_flags) ; - bool getIgnoreLists(std::list& ignored_prefixes,std::list& ignored_suffixes,uint32_t& ignore_flags) const ; - - void setMaxShareDepth(uint32_t i) ; - int maxShareDepth() const; - - void setIgnoreDuplicates(bool b) ; - bool ignoreDuplicates() const; - -protected: - void threadTick() override; /// @see RsTickingThread - - virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size); - virtual bool hash_confirm(uint32_t client_param) ; - - void recursUpdateSharedDir(const std::string& cumulated_path, DirectoryStorage::EntryIndex indx, std::set& existing_directories, uint32_t current_depth,bool& files_not_ready); - bool sweepSharedDirectories(bool &some_files_not_ready); - -private: - bool filterFile(const std::string& fname) const ; // reponds true if the file passes the ignore lists test. - - HashStorage *mHashCache ; - LocalDirectoryStorage *mSharedDirectories ; - - RsFileHash mHashSalt ; - - rstime_t mLastSweepTime; - rstime_t mLastTSUpdateTime; - - uint32_t mDelayBetweenDirectoryUpdates; - bool mIsEnabled ; - bool mFollowSymLinks; - bool mIgnoreDuplicates; - bool mNeedsFullRecheck ; - bool mIsChecking ; - bool mForceUpdate ; - - uint32_t mIgnoreFlags ; - uint32_t mMaxShareDepth ; - - std::list mIgnoredPrefixes ; - std::list mIgnoredSuffixes ; -}; - diff --git a/libretroshare/src/file_sharing/file_sharing_defaults.h b/libretroshare/src/file_sharing/file_sharing_defaults.h deleted file mode 100644 index 92ff43947..000000000 --- a/libretroshare/src/file_sharing/file_sharing_defaults.h +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: file_sharing_defaults.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#pragma once - -static const uint32_t DELAY_BETWEEN_DIRECTORY_UPDATES = 600 ; // 10 minutes -static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ = 120 ; // 2 minutes -static const uint32_t DELAY_BETWEEN_LOCAL_DIRECTORIES_TS_UPDATE = 20 ; // 20 sec. But we only update for real if something has changed. -static const uint32_t DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP = 60 ; // 60 sec. -static const uint32_t DELAY_BETWEEN_EXTRA_FILES_CACHE_UPDATES = 2 ; // 2 sec. - -static const uint32_t DELAY_BEFORE_DELETE_NON_EMPTY_REMOTE_DIR = 60*24*86400 ; // delete non empty remoe directories after 60 days of inactivity -static const uint32_t DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR = 5*24*86400 ; // delete empty remote directories after 5 days of inactivity - -static const std::string HASH_CACHE_DURATION_SS = "HASH_CACHE_DURATION" ; // key string to store hash remembering time -static const std::string WATCH_FILE_DURATION_SS = "WATCH_FILES_DELAY" ; // key to store delay before re-checking for new files -static const std::string WATCH_FILE_ENABLED_SS = "WATCH_FILES_ENABLED"; // key to store ON/OFF flags for file whatch -static const std::string TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS = "TRUST_FRIEND_NODES_FOR_BANNED_FILES"; // should we trust friends for banned files or not -static const std::string FOLLOW_SYMLINKS_SS = "FOLLOW_SYMLINKS"; // dereference symbolic links, or just ignore them. -static const std::string IGNORE_DUPLICATES = "IGNORE_DUPLICATES"; // do not index files that are referenced multiple times because of links -static const std::string WATCH_HASH_SALT_SS = "WATCH_HASH_SALT"; // Salt that is used to hash directory names -static const std::string IGNORED_PREFIXES_SS = "IGNORED_PREFIXES"; // ignore file prefixes -static const std::string IGNORED_SUFFIXES_SS = "IGNORED_SUFFIXES"; // ignore file suffixes -static const std::string IGNORE_LIST_FLAGS_SS = "IGNORED_FLAGS"; // ignore file flags -static const std::string MAX_SHARE_DEPTH = "MAX_SHARE_DEPTH"; // maximum depth of shared directories - -static const std::string FILE_SHARING_DIR_NAME = "file_sharing" ; // hard-coded directory name to store friend file lists, hash cache, etc. -static const std::string HASH_CACHE_FILE_NAME = "hash_cache.bin" ; // hard-coded directory name to store encrypted hash cache. -static const std::string LOCAL_SHARED_DIRS_FILE_NAME = "local_dir_hierarchy.bin" ; // hard-coded directory name to store encrypted local dir hierarchy. - -static const uint32_t MIN_INTERVAL_BETWEEN_HASH_CACHE_SAVE = 20 ; // never save hash cache more often than every 20 secs. -static const uint32_t MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE = 23 ; // never save remote directories more often than this -static const uint32_t MIN_TIME_AFTER_LAST_MODIFICATION = 10 ; // never hash a file that is just being modified, otherwise we end up with a corrupted hash - -static const uint32_t MAX_DIR_SYNC_RESPONSE_DATA_SIZE = 20000 ; // Maximum RsItem data size in bytes for serialised directory transmission -static const uint32_t DEFAULT_HASH_STORAGE_DURATION_DAYS = 30 ; // remember deleted/inaccessible files for 30 days - -static const uint32_t NB_FRIEND_INDEX_BITS_32BITS = 10 ; // Do not change this! -static const uint32_t NB_ENTRY_INDEX_BITS_32BITS = 22 ; // Do not change this! -static const uint32_t ENTRY_INDEX_BIT_MASK_32BITS = 0x003fffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change! - -static const uint64_t NB_FRIEND_INDEX_BITS_64BITS = 24 ; // Do not change this! -static const uint64_t NB_ENTRY_INDEX_BITS_64BITS = 40 ; // Do not change this! -static const uint64_t ENTRY_INDEX_BIT_MASK_64BITS = 0x0000000fffffffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. Depends on the two values just before. Dont change! - -static const uint32_t DELAY_BEFORE_DROP_REQUEST = 600; // every 10 min - -static const bool FOLLOW_SYMLINKS_DEFAULT = true; -static const bool TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT = true; - -static const uint32_t FL_BASE_TMP_SECTION_SIZE = 4096 ; diff --git a/libretroshare/src/file_sharing/file_tree.cc b/libretroshare/src/file_sharing/file_tree.cc deleted file mode 100644 index d34dc166b..000000000 --- a/libretroshare/src/file_sharing/file_tree.cc +++ /dev/null @@ -1,378 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: file_tree.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2018 Retroshare Team * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include - -#include "util/radix64.h" -#include "util/rsbase64.h" -#include "util/rsdir.h" -#include "retroshare/rsfiles.h" -#include "file_sharing_defaults.h" -#include "filelist_io.h" -#include "serialiser/rstypeserializer.h" - -void RsFileTree::DirData::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(subdirs); - RS_SERIAL_PROCESS(subfiles); -} - -void RsFileTree::FileData::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(hash); -} - -/*static*/ std::tuple, std::error_condition> -RsFileTree::fromBase64(const std::string& base64) -{ - const auto failure = [](std::error_condition ec) - { return std::make_tuple(nullptr, ec); }; - - if(base64.empty()) return failure(std::errc::invalid_argument); - - std::error_condition ec; - std::vector mem; - if( (ec = RsBase64::decode(base64, mem)) ) return failure(ec); - - RsGenericSerializer::SerializeContext ctx( - mem.data(), static_cast(mem.size()), - RsSerializationFlags::INTEGER_VLQ ); - std::unique_ptr ft(new RsFileTree); - ft->serial_process( - RsGenericSerializer::SerializeJob::DESERIALIZE, ctx); - if(ctx.mOk) return std::make_tuple(std::move(ft), std::error_condition()); - - return failure(std::errc::invalid_argument); -} - -std::string RsFileTree::toBase64() const -{ - RsGenericSerializer::SerializeContext ctx; - ctx.mFlags = RsSerializationFlags::INTEGER_VLQ; - RsFileTree* ncThis = const_cast(this); - ncThis->serial_process( - RsGenericSerializer::SerializeJob::SIZE_ESTIMATE, ctx ); - - std::vector buf(ctx.mOffset); - ctx.mSize = ctx.mOffset; ctx.mOffset = 0; ctx.mData = buf.data(); - - ncThis->serial_process( - RsGenericSerializer::SerializeJob::SERIALIZE, ctx ); - std::string result; - RsBase64::encode(ctx.mData, ctx.mSize, result, false, true); - return result; -} - -std::string RsFileTree::toRadix64() const -{ - unsigned char* buff = nullptr; - uint32_t size = 0; - serialise(buff, size); - std::string res; - Radix64::encode(buff,size,res); - free(buff); - return res; -} - -std::unique_ptr RsFileTree::fromRadix64( - const std::string& radix64_string ) -{ - std::unique_ptr ft(new RsFileTree); - std::vector mem = Radix64::decode(radix64_string); - if(ft->deserialise(mem.data(), static_cast(mem.size()))) - return ft; - return nullptr; -} - -void RsFileTree::recurs_buildFileTree( - RsFileTree& ft, uint32_t index, const DirDetails& dd, bool remote, - bool remove_top_dirs ) -{ - RsDbg() << __PRETTY_FUNCTION__ << " index: " << index << std::endl; - if(ft.mDirs.size() <= index) - ft.mDirs.resize(index+1) ; - - if(remove_top_dirs) - ft.mDirs[index].name = RsDirUtil::getTopDir(dd.name) ; - else - ft.mDirs[index].name = dd.name ; - - ft.mDirs[index].subfiles.clear(); - ft.mDirs[index].subdirs.clear(); - - DirDetails dd2 ; - - FileSearchFlags flags = remote ? RS_FILE_HINTS_REMOTE : RS_FILE_HINTS_LOCAL; - - for(uint32_t i=0;iRequestDirDetails(dd.children[i].ref,dd2,flags)) - { - if(dd.children[i].type == DIR_TYPE_FILE) - { - FileData f ; - f.name = dd2.name ; - f.size = dd2.size ; - f.hash = dd2.hash ; - - ft.mDirs[index].subfiles.push_back(ft.mFiles.size()) ; - ft.mFiles.push_back(f) ; - - ft.mTotalFiles++ ; - ft.mTotalSize += f.size ; - } - else if(dd.children[i].type == DIR_TYPE_DIR) - { - ft.mDirs[index].subdirs.push_back(ft.mDirs.size()); - recurs_buildFileTree(ft,ft.mDirs.size(),dd2,remote,remove_top_dirs) ; - } - else - std::cerr << "(EE) Unsupported DirDetails type." << std::endl; - } - else - std::cerr << "(EE) Cannot request dir details for pointer " << dd.children[i].ref << std::endl; -} - -bool RsFileTree::getDirectoryContent( - std::string& name, std::vector& subdirs, - std::vector& subfiles, uint64_t index_p ) const -{ - // Avoid warnings on Android armv7 - using sz_t = std::vector::size_type; - sz_t index = static_cast(index_p); - - if(index >= mDirs.size()) return false; - - name = mDirs[index].name; - subdirs = mDirs[index].subdirs ; - - subfiles.clear() ; - for(sz_t i=0; i < mDirs[index].subfiles.size(); ++i) - subfiles.push_back(mFiles[static_cast(mDirs[index].subfiles[i])]); - - return true; -} - -std::unique_ptr RsFileTree::fromDirDetails( - const DirDetails& dd, bool remote ,bool remove_top_dirs ) -{ - std::unique_ptrft(new RsFileTree); - if(dd.type == DIR_TYPE_FILE) - { - FileData fd; - fd.name = dd.name; fd.hash = dd.hash; fd.size = dd.size; - ft->mFiles.push_back(fd); - ft->mTotalFiles = 1; - ft->mTotalSize = fd.size; - - DirData dd; - dd.name = "/"; - dd.subfiles.push_back(0); - ft->mDirs.push_back(dd); - } - else recurs_buildFileTree(*ft, 0, dd, remote, remove_top_dirs ); - return ft; -} - -typedef FileListIO::read_error read_error ; - -bool RsFileTree::deserialise(unsigned char *buffer,uint32_t buffer_size) -{ - uint32_t buffer_offset = 0 ; - - mTotalFiles = 0; - mTotalSize = 0; - - try - { - // Read some header - - uint32_t version,n_dirs,n_files ; - - if(!FileListIO::readField(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_LOCAL_DIRECTORY_VERSION,version)) throw read_error(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_LOCAL_DIRECTORY_VERSION) ; - if(version != (uint32_t) FILE_LIST_IO_LOCAL_DIRECTORY_TREE_VERSION_0001) throw std::runtime_error("Wrong version number") ; - - if(!FileListIO::readField(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_files)) throw read_error(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_RAW_NUMBER) ; - if(!FileListIO::readField(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_RAW_NUMBER,n_dirs)) throw read_error(buffer,buffer_size,buffer_offset,FILE_LIST_IO_TAG_RAW_NUMBER) ; - - // Write all file/dir entries - - mFiles.resize(n_files) ; - mDirs.resize(n_dirs) ; - - unsigned char *node_section_data = NULL ; - uint32_t node_section_size = 0 ; - - for(uint32_t i=0;i * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include -#include "retroshare/rsids.h" -#include "pqi/authssl.h" -#include "util/rsdir.h" -#include "util/rsprint.h" -#include "serialiser/rsbaseserial.h" -#include "filelist_io.h" - -FileListIO::read_error::read_error(unsigned char *sec,uint32_t size,uint32_t offset,uint8_t expected_tag) -{ - std::ostringstream s ; - s << "At offset " << offset << "/" << size << ": expected section tag " << std::hex << (int)expected_tag << std::dec << " but got " << RsUtil::BinToHex(&sec[offset],std::min((int)size-(int)offset, 15)) << "..." << std::endl; - err_string = s.str(); -} - -template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const uint32_t & val) { return setRawUInt32(buff,size,&offset,val) ; } -template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const uint64_t & val) { return setRawUInt64(buff,size,&offset,val) ; } -template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const std::string & val) { return setRawString(buff,size,&offset,val) ; } -template<> bool FileListIO::serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const Sha1CheckSum & val) { return val.serialise(buff,size,offset) ; } - -template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,uint32_t & val) { return getRawUInt32(const_cast(buff),size,&offset,&val) ; } -template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,uint64_t & val) { return getRawUInt64(const_cast(buff),size,&offset,&val) ; } -template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,std::string & val) { return getRawString(const_cast(buff),size,&offset,val) ; } -template<> bool FileListIO::deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,Sha1CheckSum & val) { return val.deserialise(const_cast(buff),size,offset) ; } - -template<> uint32_t FileListIO::serial_size(const uint32_t & ) { return 4 ; } -template<> uint32_t FileListIO::serial_size(const uint64_t & ) { return 8 ; } -template<> uint32_t FileListIO::serial_size(const std::string & val) { return getRawStringSize(val) ; } -template<> uint32_t FileListIO::serial_size(const Sha1CheckSum & ) { return Sha1CheckSum::serial_size(); } - -bool FileListIO::writeField( unsigned char*&buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const unsigned char * val,uint32_t size) -{ - if(!checkSectionSize(buff,buff_size,offset,size)) - return false; - - if(!writeSectionHeader(buff,buff_size,offset,section_tag,size)) - return false; - - memcpy(&buff[offset],val,size) ; - offset += size ; - - return true; -} - -bool FileListIO::readField (const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag, unsigned char *& val,uint32_t& size) -{ - uint32_t local_size ; - - if(!readSectionHeader(buff,buff_size,offset,check_section_tag,local_size)) - return false; - - if(!checkSectionSize(val,size,0,local_size)) // allocate val if needed to handle local_size bytes. - return false; - - memcpy(val,&buff[offset],local_size); - offset += local_size ; - - return true ; -} - -bool FileListIO::write125Size(unsigned char *data,uint32_t data_size,uint32_t& offset,uint32_t S) -{ - if(S < 192) - { - if(offset+1 > data_size) - return false; - - data[offset++] = (uint8_t)S ; - return true; - } - else if(S < 8384) - { - if(offset+2 > data_size) - return false; - - data[offset+1] = (S - 192) & 0xff ; - data[offset ] = ((S - 192 - data[offset+1]) >> 8) + 192; - - offset += 2 ; - - return true; - } - else - { - if(offset+5 > data_size) - return false; - - data[offset++] = 0xff ; - data[offset++] = (uint8_t)((S >> 24) & 255) ; - data[offset++] = (uint8_t)((S >> 16) & 255) ; - data[offset++] = (uint8_t)((S >> 8) & 255) ; - data[offset++] = (uint8_t)((S ) & 255) ; - - return true ; - } -} - -bool FileListIO::read125Size(const unsigned char *data,uint32_t data_size,uint32_t& offset,uint32_t& S) -{ - if(offset + 1 >= data_size) return false; - - uint8_t b1 = data[offset++] ; - - if(b1 < 192) - { - S = b1; - return true ; - } - if(offset + 1 >= data_size) return false; - - uint8_t b2 = data[offset++] ; - - if(b1 < 224) - { - S = ((b1-192) << 8) + b2 + 192 ; - return true; - } - - if(b1 != 0xff) - return false; - - if(offset + 3 >= data_size) return false; - - uint8_t b3 = data[offset++]; - uint8_t b4 = data[offset++]; - uint8_t b5 = data[offset++]; - - S = (b2 << 24) | (b3 << 16) | (b4 << 8) | b5 ; - return true; -} - -bool FileListIO::saveEncryptedDataToFile(const std::string& fname,const unsigned char *data,uint32_t total_size) -{ - void *encryptedData = NULL ; - int encDataLen = 0 ; - - if(!AuthSSL::getAuthSSL()->encrypt( encryptedData, encDataLen, data,total_size, AuthSSL::getAuthSSL()->OwnId())) - { - std::cerr << "Cannot encrypt encrypted file. Something's wrong." << std::endl; - return false; - } - - FILE *F = fopen( (fname+".tmp").c_str(),"wb" ) ; - - if(!F) - { - std::cerr << "Cannot open encrypted file for writing: " << fname+".tmp" << std::endl; - - free(encryptedData); - return false; - } - if(fwrite(encryptedData,1,encDataLen,F) != (uint32_t)encDataLen) - { - std::cerr << "Could not write entire encrypted file. Out of disc space??" << std::endl; - fclose(F) ; - - free(encryptedData); - return false; - } - - fclose(F) ; - - RsDirUtil::renameFile(fname+".tmp",fname) ; -#ifdef FIM_DEBUG - std::cerr << "done." << std::endl ; -#endif - - free(encryptedData); - return true; -} - -bool FileListIO::loadEncryptedDataFromFile(const std::string& fname,unsigned char *& data,uint32_t& total_size) -{ - uint64_t file_size ; - - if(!RsDirUtil::checkFile( fname,file_size,true ) ) - { -#ifdef FIM_DEBUG - std::cerr << "Encrypted file " << fname << " not available or empty." << std::endl; -#endif - return false; - } - - // read the binary stream into memory. - // - RsTemporaryMemory buffer(file_size) ; - - if(buffer == NULL) - return false; - - FILE *F = fopen( fname.c_str(),"rb") ; - if (!F) - { - std::cerr << "Cannot open encrypted file, filename " << fname << std::endl; - return false; - } - if(fread(buffer,1,file_size,F) != file_size) - { - std::cerr << "Cannot read from file " + fname << ": something's wrong." << std::endl; - fclose(F) ; - return false; - } - fclose(F) ; - - // now decrypt - void *decrypted_data =NULL; - int decrypted_data_size =0; - - if(!AuthSSL::getAuthSSL()->decrypt(decrypted_data, decrypted_data_size, buffer, file_size)) - { - std::cerr << "Cannot decrypt encrypted file. Something's wrong." << std::endl; - return false; - } - - data = (unsigned char*)decrypted_data ; - total_size = decrypted_data_size ; - - return true; -} diff --git a/libretroshare/src/file_sharing/filelist_io.h b/libretroshare/src/file_sharing/filelist_io.h deleted file mode 100644 index 65863ffd0..000000000 --- a/libretroshare/src/file_sharing/filelist_io.h +++ /dev/null @@ -1,167 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: filelist_io.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "util/rsmemory.h" - -// This file implements load/save of various fields used for file lists and directory content. -// WARNING: the encoding is system-dependent, so this should *not* be used to exchange data between computers. - -static const uint32_t FILE_LIST_IO_LOCAL_DIRECTORY_STORAGE_VERSION_0001 = 0x00000001 ; -static const uint32_t FILE_LIST_IO_LOCAL_DIRECTORY_TREE_VERSION_0001 = 0x00010001 ; - -static const uint8_t FILE_LIST_IO_TAG_UNKNOWN = 0x00 ; -static const uint8_t FILE_LIST_IO_TAG_LOCAL_DIRECTORY_VERSION = 0x01 ; - -static const uint8_t FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY = 0x10 ; -static const uint8_t FILE_LIST_IO_TAG_LOCAL_FILE_ENTRY = 0x11 ; -static const uint8_t FILE_LIST_IO_TAG_LOCAL_DIR_ENTRY = 0x12 ; -static const uint8_t FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY = 0x13 ; - -static const uint8_t FILE_LIST_IO_TAG_FILE_SHA1_HASH = 0x20 ; -static const uint8_t FILE_LIST_IO_TAG_FILE_NAME = 0x21 ; -static const uint8_t FILE_LIST_IO_TAG_FILE_SIZE = 0x22 ; - -static const uint8_t FILE_LIST_IO_TAG_MODIF_TS = 0x30 ; -static const uint8_t FILE_LIST_IO_TAG_RECURS_MODIF_TS = 0x31 ; -static const uint8_t FILE_LIST_IO_TAG_UPDATE_TS = 0x32 ; - -static const uint8_t FILE_LIST_IO_TAG_ENTRY_INDEX = 0x40 ; -static const uint8_t FILE_LIST_IO_TAG_PARENT_INDEX = 0x41 ; - -static const uint8_t FILE_LIST_IO_TAG_DIR_HASH = 0x50 ; -static const uint8_t FILE_LIST_IO_TAG_DIR_NAME = 0x51 ; - -static const uint8_t FILE_LIST_IO_TAG_ROW = 0x60 ; -static const uint8_t FILE_LIST_IO_TAG_BINARY_DATA = 0x61 ; -static const uint8_t FILE_LIST_IO_TAG_RAW_NUMBER = 0x62 ; - -static const uint32_t SECTION_HEADER_MAX_SIZE = 6 ; // section tag (1 byte) + size (max = 5 bytes) - - -class FileListIO -{ -public: - template - static bool writeField(unsigned char *& buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const T& val) - { - uint32_t s = serial_size(val) ; - - if(!checkSectionSize(buff,buff_size,offset,s)) - return false; - - if(!writeSectionHeader(buff,buff_size,offset,section_tag,s)) - return false; - - return serialise(buff,buff_size,offset,val) ; - } - - template - static bool readField(const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag,T& val) - { - uint32_t section_size ; - - if(!readSectionHeader(buff,buff_size,offset,check_section_tag,section_size)) - return false; - - return deserialise(buff,buff_size,offset,val); - } - - class read_error - { - public: - read_error(unsigned char *sec,uint32_t size,uint32_t offset,uint8_t expected_tag); - read_error(const std::string& s) : err_string(s) {} - - const std::string& what() const { return err_string ; } - private: - std::string err_string ; - }; - - - static bool writeField( unsigned char*&buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,const unsigned char * val,uint32_t size) ; - static bool readField (const unsigned char *buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag, unsigned char *& val,uint32_t& size) ; - - template static bool serialise(unsigned char *buff,uint32_t size,uint32_t& offset,const T& val) ; - template static bool deserialise(const unsigned char *buff,uint32_t size,uint32_t& offset,T& val) ; - template static uint32_t serial_size(const T& val) ; - - static bool saveEncryptedDataToFile(const std::string& fname,const unsigned char *data,uint32_t total_size); - static bool loadEncryptedDataFromFile(const std::string& fname,unsigned char *& data,uint32_t& total_size); - -private: - static bool write125Size(unsigned char *data,uint32_t total_size,uint32_t& offset,uint32_t size) ; - static bool read125Size (const unsigned char *data,uint32_t total_size,uint32_t& offset,uint32_t& size) ; - - static bool checkSectionSize(unsigned char *& buff,uint32_t& buff_size,uint32_t offset,uint32_t S) - { - // This tests avoids an infinite loop when growing new size - - if(offset + S + SECTION_HEADER_MAX_SIZE > 0x8fffffff) - return false ; - - if(offset + S + SECTION_HEADER_MAX_SIZE > buff_size) - { - uint32_t new_size = (buff_size == 0)?512:buff_size ; - - while(new_size < offset + S + SECTION_HEADER_MAX_SIZE) - new_size <<= 1 ; - - buff = (unsigned char *)realloc(buff,new_size) ; - - if(!buff) - { - buff_size = 0 ; - return false ; - } - buff_size = new_size ; - } - return true ; - } - - static bool writeSectionHeader(unsigned char *& buff,uint32_t& buff_size,uint32_t& offset,uint8_t section_tag,uint32_t S) - { - buff[offset++] = section_tag ; - if(!write125Size(buff,buff_size,offset,S)) return false ; - - return true; - } - - static bool readSectionHeader(const unsigned char *& buff,uint32_t buff_size,uint32_t& offset,uint8_t check_section_tag,uint32_t& S) - { - if(offset + 1 > buff_size) - return false ; - - uint8_t section_tag = buff[offset] ; // we do the offset++ after, only if the header can be read. Doing so, we can make multiple read attempts. - - if(section_tag != check_section_tag) - return false; - - offset++ ; - - return read125Size(buff,buff_size,offset,S) ; - } -}; diff --git a/libretroshare/src/file_sharing/hash_cache.cc b/libretroshare/src/file_sharing/hash_cache.cc deleted file mode 100644 index 331f1a481..000000000 --- a/libretroshare/src/file_sharing/hash_cache.cc +++ /dev/null @@ -1,606 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: hash_cache.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include "util/rsdir.h" -#include "util/rsprint.h" -#include "util/rstime.h" -#include "rsserver/p3face.h" -#include "pqi/authssl.h" -#include "hash_cache.h" -#include "filelist_io.h" -#include "file_sharing_defaults.h" -#include "retroshare/rsinit.h" - -//#define HASHSTORAGE_DEBUG 1 - -static const uint32_t DEFAULT_INACTIVITY_SLEEP_TIME = 50*1000; -static const uint32_t MAX_INACTIVITY_SLEEP_TIME = 2*1000*1000; - -HashStorage::HashStorage(const std::string& save_file_name) - : mFilePath(save_file_name), mHashMtx("Hash Storage mutex") -{ - mInactivitySleepTime = DEFAULT_INACTIVITY_SLEEP_TIME; - mRunning = false ; - mLastSaveTime = 0 ; - mTotalSizeToHash = 0; - mTotalFilesToHash = 0; - mCurrentHashingSpeed = 0 ; - mMaxStorageDurationDays = DEFAULT_HASH_STORAGE_DURATION_DAYS ; - mHashingProcessPaused = false; - mHashedBytes = 0 ; - mHashingTime = 0 ; - - { - RS_STACK_MUTEX(mHashMtx) ; - - if(!locked_load()) - try_load_import_old_hash_cache(); - } -} - -void HashStorage::togglePauseHashingProcess() -{ - RS_STACK_MUTEX(mHashMtx) ; - mHashingProcessPaused = !mHashingProcessPaused ; -} -bool HashStorage::hashingProcessPaused() -{ - RS_STACK_MUTEX(mHashMtx) ; - return mHashingProcessPaused; -} - -static std::string friendlyUnit(uint64_t val) -{ - const std::string units[6] = {"B","KB","MB","GB","TB","PB"}; - char buf[50] ; - - double fact = 1.0 ; - - for(unsigned int i=0; i<6; ++i) - if(double(val)/fact < 1024.0) - { - sprintf(buf,"%2.2f",double(val)/fact) ; - return std::string(buf) + " " + units[i]; - } - else - fact *= 1024.0f ; - - sprintf(buf,"%2.2f",double(val)/fact*1024.0f) ; - return std::string(buf) + " TB"; -} - -void HashStorage::threadTick() -{ - FileHashJob job; - RsFileHash hash; - uint64_t size = 0; - - - { - bool empty ; - uint32_t st ; - - { - RS_STACK_MUTEX(mHashMtx) ; - - if(mChanged && mLastSaveTime + MIN_INTERVAL_BETWEEN_HASH_CACHE_SAVE < time(NULL)) - { - locked_save(); - mLastSaveTime = time(NULL) ; - mChanged = false ; - } - } - - { - RS_STACK_MUTEX(mHashMtx) ; - - empty = mFilesToHash.empty(); - st = mInactivitySleepTime ; - } - - // sleep off mutex! - if(empty) - { -#ifdef HASHSTORAGE_DEBUG - std::cerr << "nothing to hash. Sleeping for " << st << " us" << std::endl; -#endif - - rstime::rs_usleep(st); // when no files to hash, just wait for 2 secs. This avoids a dramatic loop. - - if(st > MAX_INACTIVITY_SLEEP_TIME) - { - RS_STACK_MUTEX(mHashMtx) ; - - mInactivitySleepTime = MAX_INACTIVITY_SLEEP_TIME; - - if(!mChanged) // otherwise it might prevent from saving the hash cache - { - stopHashThread(); - } - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::DIRECTORY_SWEEP_ENDED; - rsEvents->postEvent(ev); - } - //RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_FINISH, "") ; - } - else - { - RS_STACK_MUTEX(mHashMtx) ; - mInactivitySleepTime = 2*st ; - } - - return ; - } - mInactivitySleepTime = DEFAULT_INACTIVITY_SLEEP_TIME; - - bool paused = false ; - { - RS_STACK_MUTEX(mHashMtx) ; - paused = mHashingProcessPaused ; - } - - if(paused) // we need to wait off mutex!! - { - rstime::rs_usleep(MAX_INACTIVITY_SLEEP_TIME) ; - std::cerr << "Hashing process currently paused." << std::endl; - return; - } - else - { - RS_STACK_MUTEX(mHashMtx) ; - - job = mFilesToHash.begin()->second ; - mFilesToHash.erase(mFilesToHash.begin()) ; - } - - if(job.client->hash_confirm(job.client_param)) - { -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Hashing file " << job.full_path << "..." ; std::cerr.flush(); -#endif - - std::string tmpout; - - if(mCurrentHashingSpeed > 0) - rs_sprintf(tmpout, "%lu/%lu (%s - %d%%, %d MB/s) : %s", (unsigned long int)mHashCounter+1, (unsigned long int)mTotalFilesToHash, friendlyUnit(mTotalHashedSize).c_str(), int(mTotalHashedSize/double(mTotalSizeToHash)*100.0), mCurrentHashingSpeed,job.full_path.c_str()) ; - else - rs_sprintf(tmpout, "%lu/%lu (%s - %d%%) : %s", (unsigned long int)mHashCounter+1, (unsigned long int)mTotalFilesToHash, friendlyUnit(mTotalHashedSize).c_str(), int(mTotalHashedSize/double(mTotalSizeToHash)*100.0), job.full_path.c_str()) ; - - //RsServer::notify()->notifyHashingInfo(NOTIFY_HASHTYPE_HASH_FILE, tmpout) ; - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::HASHING_FILE; - ev->mMessage = tmpout; - rsEvents->postEvent(ev); - } - - double seconds_origin = rstime::RsScopeTimer::currentTime() ; - - if(RsDirUtil::getFileHash(job.full_path, hash,size, this)) - { - // store the result - -#ifdef HASHSTORAGE_DEBUG - std::cerr << "done."<< std::endl; -#endif - - RS_STACK_MUTEX(mHashMtx) ; - HashStorageInfo& info(mFiles[job.real_path]); - - info.filename = job.real_path ; - info.size = size ; - info.modf_stamp = job.ts ; - info.time_stamp = time(NULL); - info.hash = hash; - - mChanged = true ; - mTotalHashedSize += size ; - } - else - std::cerr << "ERROR: cannot hash file " << job.full_path << std::endl; - - mHashingTime += rstime::RsScopeTimer::currentTime() - seconds_origin ; - mHashedBytes += size ; - - if(mHashingTime > 3) - { - mCurrentHashingSpeed = (int)(mHashedBytes / mHashingTime ) / (1024*1024) ; - mHashingTime = 0 ; - mHashedBytes = 0 ; - } - - ++mHashCounter ; - } - } - // call the client - - if(!hash.isNull()) - job.client->hash_callback(job.client_param, job.full_path, hash, size); -} - -bool HashStorage::requestHash(const std::string& full_path,uint64_t size,rstime_t mod_time,RsFileHash& known_hash,HashStorageClient *c,uint32_t client_param) -{ - // check if the hash is up to date w.r.t. cache. - -#ifdef HASHSTORAGE_DEBUG - std::cerr << "HASH Requested for file " << full_path << ": mod_time: " << mod_time << ", size: " << size << " :" ; -#endif - RS_STACK_MUTEX(mHashMtx) ; - - std::string real_path = RsDirUtil::removeSymLinks(full_path) ; - - rstime_t now = time(NULL) ; - std::map::iterator it = mFiles.find(real_path) ; - - // On windows we compare the time up to +/- 3600 seconds. This avoids re-hashing files in case of daylight saving change. - // - // See: - // https://support.microsoft.com/en-us/kb/190315 - // - if(it != mFiles.end() -#ifdef WINDOWS_SYS - && ( (uint64_t)mod_time == it->second.modf_stamp || (uint64_t)mod_time+3600 == it->second.modf_stamp ||(uint64_t)mod_time == it->second.modf_stamp+3600) -#else - && (uint64_t)mod_time == it->second.modf_stamp -#endif - && size == it->second.size) - { - it->second.time_stamp = now ; - -#ifdef WINDOWS_SYS - if(it->second.modf_stamp != (uint64_t)mod_time) - { - std::cerr << "(WW) detected a 1 hour shift in file modification time. This normally happens to many files at once, when daylight saving time shifts (file=\"" << full_path << "\")." << std::endl; - it->second.modf_stamp = (uint64_t)mod_time; - mChanged = true; - startHashThread(); - } -#endif - - known_hash = it->second.hash; -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Found in cache." << std::endl ; -#endif - return true ; - } -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Not in cache. Scheduling for re-hash." << std::endl ; -#endif - - // we need to schedule a re-hashing - - if(mFilesToHash.find(real_path) != mFilesToHash.end()) - return false ; - - FileHashJob job ; - - job.client = c ; - job.size = size ; - job.client_param = client_param ; - job.full_path = full_path ; - job.real_path = real_path ; - job.ts = mod_time ; - - // We store the files indexed by their real path, so that we allow to not re-hash files that are pointed multiple times through the directory links - // The client will be notified with the full path instead of the real path. - - mFilesToHash[real_path] = job; - - mTotalSizeToHash += size ; - ++mTotalFilesToHash; - - startHashThread(); - - return false; -} - -void HashStorage::startHashThread() -{ - if(!mRunning) - { - mRunning = true ; - std::cerr << "Starting hashing thread." << std::endl; - mHashCounter = 0; - mTotalHashedSize = 0; - - start("fs hash cache") ; - } -} - -void HashStorage::stopHashThread() -{ - if(mRunning) - { - RsInfo() << __PRETTY_FUNCTION__ << "Stopping hashing thread." - << std::endl; - - RsThread::askForStop(); - mRunning = false ; - mTotalSizeToHash = 0; - mTotalFilesToHash = 0; - } -} - -void HashStorage::clean() -{ - RS_STACK_MUTEX(mHashMtx) ; - - rstime_t now = time(NULL) ; - rstime_t duration = mMaxStorageDurationDays * 24 * 3600 ; // seconds - -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Cleaning hash cache." << std::endl ; -#endif - - for(std::map::iterator it(mFiles.begin());it!=mFiles.end();) - if((uint64_t)(it->second.time_stamp + duration) < (uint64_t)now) - { -#ifdef HASHSTORAGE_DEBUG - std::cerr << " Entry too old: " << it->first << ", ts=" << it->second.time_stamp << std::endl ; -#endif - std::map::iterator tmp(it) ; - ++tmp ; - mFiles.erase(it) ; - it=tmp ; - mChanged = true ; - } - else - ++it ; - -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Done." << std::endl; -#endif -} - -bool HashStorage::locked_load() -{ - unsigned char *data = NULL ; - uint32_t data_size=0; - - if(!FileListIO::loadEncryptedDataFromFile(mFilePath,data,data_size)) - { - std::cerr << "(EE) Cannot read hash cache." << std::endl; - return false; - } - uint32_t offset = 0 ; - HashStorageInfo info ; -#ifdef HASHSTORAGE_DEBUG - uint32_t n=0; -#endif - - while(offset < data_size) - if(readHashStorageInfo(data,data_size,offset,info)) - { -#ifdef HASHSTORAGE_DEBUG - std::cerr << info << std::endl; - ++n ; -#endif - mFiles[info.filename] = info ; - } - - free(data) ; -#ifdef HASHSTORAGE_DEBUG - std::cerr << n << " entries loaded." << std::endl ; -#endif - return true ; -} - -void HashStorage::locked_save() -{ -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Saving Hash Cache to file " << mFilePath << "..." << std::endl ; -#endif - - unsigned char *data = NULL ; - uint32_t offset = 0 ; - uint32_t total_size = 0; - - for(std::map::const_iterator it(mFiles.begin());it!=mFiles.end();++it) - writeHashStorageInfo(data,total_size,offset,it->second) ; - - if(!FileListIO::saveEncryptedDataToFile(mFilePath,data,offset)) - { - std::cerr << "(EE) Cannot save hash cache data." << std::endl; - free(data) ; - return ; - } - - std::cerr << mFiles.size() << " entries saved in hash cache." << std::endl; - - free(data) ; -} - -bool HashStorage::readHashStorageInfo(const unsigned char *data,uint32_t total_size,uint32_t& offset,HashStorageInfo& info) const -{ - unsigned char *section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; - - if(!section_data) - return false ; - - uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; - uint32_t section_offset = 0; - - // This way, the entire section is either read or skipped. That avoids the risk of being stuck somewhere in the middle - // of a section because of some unknown field, etc. - - if(!FileListIO::readField(data,total_size,offset,FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY,section_data,section_size)) - { - free(section_data); - return false; - } - - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) { free(section_data); return false ; } - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) { free(section_data); return false ; } - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) { free(section_data); return false ; } - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) { free(section_data); return false ; } - if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) { free(section_data); return false ; } - - free(section_data); - return true; -} - -bool HashStorage::writeHashStorageInfo(unsigned char *& data,uint32_t& total_size,uint32_t& offset,const HashStorageInfo& info) const -{ - unsigned char *section_data = (unsigned char *)rs_malloc(FL_BASE_TMP_SECTION_SIZE) ; - - if(!section_data) - return false ; - - uint32_t section_offset = 0 ; - uint32_t section_size = FL_BASE_TMP_SECTION_SIZE; - - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_NAME ,info.filename )) { free(section_data); return false ; } - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,info.size )) { free(section_data); return false ; } - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_UPDATE_TS ,info.time_stamp)) { free(section_data); return false ; } - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,info.modf_stamp)) { free(section_data); return false ; } - if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,info.hash )) { free(section_data); return false ; } - - // now write the whole string into a single section in the file - - if(!FileListIO::writeField(data,total_size,offset,FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY,section_data,section_offset)) return false ; -#ifdef HASHSTORAGE_DEBUG - std::cerr << "Writing hash storage section " << RsUtil::BinToHex(section_data,section_offset) << std::endl; - std::cerr << "Info.filename = " << info.filename << std::endl; -#endif - free(section_data) ; - - return true; -} - -std::ostream& operator<<(std::ostream& o,const HashStorage::HashStorageInfo& info) -{ - return o << info.hash << " " << info.modf_stamp << " " << info.size << " " << info.filename ; -} - -/********************************************************************************************************************************/ -/* 09/26/2016 */ -/* This method should be removed in a few months. It only helps importing the old hash cache in order to */ -/* spare the re-hashing of everything. If successful, it also renames the old hash cache into a new name so that */ -/* the file is not found at the next attempt. */ -/********************************************************************************************************************************/ -// -#include "rsserver/rsaccounts.h" -#include - -bool HashStorage::try_load_import_old_hash_cache() -{ - // compute file name - - std::string base_dir = RsAccounts::AccountDirectory(); - std::string old_cache_filename = base_dir + "/" + "file_cache.bin" ; - - // check for unencrypted - - std::istream *f = NULL ; - uint64_t file_size ; - - if(RsDirUtil::checkFile( old_cache_filename,file_size,false ) ) - { - std::cerr << "Encrypted hash cache file present. Reading it." << std::endl; - - // read the binary stream into memory. - // - RsTemporaryMemory buffer(file_size) ; - - if(buffer == NULL) - return false; - - FILE *F = fopen( old_cache_filename.c_str(),"rb") ; - if (!F) - { - std::cerr << "Cannot open file for reading encrypted file cache, filename " << old_cache_filename << std::endl; - return false; - } - if(fread(buffer,1,file_size,F) != file_size) - { - std::cerr << "Cannot read from file " << old_cache_filename << ": something's wrong." << std::endl; - fclose(F) ; - return false; - } - fclose(F) ; - - void *decrypted_data =NULL; - int decrypted_data_size =0; - - if(!AuthSSL::getAuthSSL()->decrypt(decrypted_data, decrypted_data_size, buffer, file_size)) - { - std::cerr << "Cannot decrypt encrypted file cache. Something's wrong." << std::endl; - return false; - } - std::string s((char *)decrypted_data,decrypted_data_size) ; - f = new std::istringstream(s) ; - - free(decrypted_data) ; - } - else - return false; - - std::streamsize max_line_size = 2000 ; // should be enough. Anyway, if we - // miss one entry, we just lose some - // cache itemsn but this is not too - // much of a problem. - char *buff = new char[max_line_size] ; - - std::cerr << "Importing hashCache from file " << old_cache_filename << std::endl ; - int n=0 ; - - std::map tmp_files ; // stored as (full_path, hash_info) - - while(!f->eof()) - { - HashStorageInfo info ; - - f->getline(buff,max_line_size,'\n') ; - info.filename = std::string(buff) ; - - f->getline(buff,max_line_size,'\n') ; //if(sscanf(buff,"%llu",&info.size) != 1) break ; - - info.size = 0 ; - sscanf(buff, RsDirUtil::scanf_string_for_uint(sizeof(info.size)), &info.size); - - f->getline(buff,max_line_size,'\n') ; if(sscanf(buff,RsDirUtil::scanf_string_for_uint(sizeof(info.time_stamp)),&info.time_stamp) != 1) { std::cerr << "Could not read one entry! Giving up." << std::endl; break ; } - f->getline(buff,max_line_size,'\n') ; if(sscanf(buff,RsDirUtil::scanf_string_for_uint(sizeof(info.modf_stamp)),&info.modf_stamp) != 1) { std::cerr << "Could not read one entry! Giving up." << std::endl; break ; } - f->getline(buff,max_line_size,'\n') ; info.hash = RsFileHash(std::string(buff)) ; - - std::cerr << " (" << info.filename << ", " << info.size << ", " << info.time_stamp << ", " << info.modf_stamp << ", " << info.hash << std::endl ; - ++n ; - - tmp_files[info.filename] = info ; - } - - delete[] buff ; - delete f ; - - std::cerr << "(II) Successfully imported hash cache from file " << old_cache_filename << " for a total of " << n << " entries." << std::endl; - std::cerr << "(II) This file is now obsolete, and will be renamed " << old_cache_filename + ".bak" << " in case you needed it. But you can safely remove it." << std::endl; - - RsDirUtil::renameFile(old_cache_filename,old_cache_filename+".bak") ; - - mFiles = tmp_files ; - locked_save() ; // this is called explicitly here because the ticking thread is not active. - - return true; -} -/********************************************************************************************************************************/ diff --git a/libretroshare/src/file_sharing/hash_cache.h b/libretroshare/src/file_sharing/hash_cache.h deleted file mode 100644 index 6fbb9ae5c..000000000 --- a/libretroshare/src/file_sharing/hash_cache.h +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: hash_cache.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - - -#pragma once - -#include -#include "util/rsthreads.h" -#include "retroshare/rsfiles.h" -#include "util/rstime.h" - -/*! - * \brief The HashStorageClient class - * Used by clients of the hash cache for receiving hash results when done. This is asynchrone of course since hashing - * might be quite costly. - */ -class HashStorageClient -{ -public: - HashStorageClient() {} - virtual ~HashStorageClient() {} - - // the result of the hashing info is sent to this method - - virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size)=0; - - // this method is used to check that the client param is still valid just before hashing. This avoids hashing files - // that are still in queue while removed from shared lists. - - virtual bool hash_confirm(uint32_t client_param)=0 ; -}; - -class HashStorage: public RsTickingThread -{ -public: - explicit HashStorage(const std::string& save_file_name) ; - - /*! - * \brief requestHash Requests the hash for the given file, assuming size and mod_time are the same. - * - * \param full_path Full path to reach the file - * \param size Actual file size - * \param mod_time Actual file modification time - * \param known_hash Returned hash for the file. - * \param c Hash cache client to which the hash should be sent once calculated - * \param client_param Param to be passed to the client callback. Useful if the client needs a file ID. - * - * \return true if the supplied hash info is up to date. - */ - bool requestHash(const std::string& full_path, uint64_t size, rstime_t mod_time, RsFileHash& known_hash, HashStorageClient *c, uint32_t client_param) ; - - struct HashStorageInfo - { - std::string filename ; // full path of the file - uint64_t size ; - uint32_t time_stamp ; // last time the hash was tested/requested - uint32_t modf_stamp ; - RsFileHash hash ; - } ; - - // interaction with GUI, called from p3FileLists - void setRememberHashFilesDuration(uint32_t days) { mMaxStorageDurationDays = days ; } // duration for which the hash is kept even if the file is not shared anymore - uint32_t rememberHashFilesDuration() const { return mMaxStorageDurationDays ; } - void clear() { mFiles.clear(); mChanged=true; } // drop all known hashes. Not something to do, except if you want to rehash the entire database - bool empty() const { return mFiles.empty() ; } - void togglePauseHashingProcess() ; - bool hashingProcessPaused(); - - void threadTick() override; /// @see RsTickingThread - - friend std::ostream& operator<<(std::ostream& o,const HashStorageInfo& info) ; -private: - /*! - * \brief clean - * This function is responsible for removing old hashes, etc - */ - void clean() ; - - void startHashThread(); - void stopHashThread(); - - // loading/saving the entire hash database to a file - - void locked_save() ; - bool locked_load() ; - bool try_load_import_old_hash_cache(); - - bool readHashStorageInfo(const unsigned char *data,uint32_t total_size,uint32_t& offset,HashStorageInfo& info) const; - bool writeHashStorageInfo(unsigned char *& data,uint32_t& total_size,uint32_t& offset,const HashStorageInfo& info) const; - - // Local configuration and storage - - uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries - std::map mFiles ; // stored as (full_path, hash_info) - std::string mFilePath ; // file where the hash database is stored - bool mChanged ; - bool mHashingProcessPaused ; - - struct FileHashJob - { - std::string full_path; // canonicalized file name (means: symlinks removed, loops removed, etc) - std::string real_path; // path supplied by the client. - uint64_t size ; - HashStorageClient *client; - uint32_t client_param ; - rstime_t ts; - }; - - // current work - - std::map mFilesToHash ; - - // thread/mutex stuff - - RsMutex mHashMtx ; - bool mRunning; - uint64_t mHashCounter; - uint32_t mInactivitySleepTime ; - uint64_t mTotalSizeToHash ; - uint64_t mTotalHashedSize ; - uint64_t mTotalFilesToHash ; - rstime_t mLastSaveTime ; - - // The following is used to estimate hashing speed. - - double mHashingTime ; - uint64_t mHashedBytes ; - uint32_t mCurrentHashingSpeed ; // in MB/s -}; - diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc deleted file mode 100644 index 6eb3899e2..000000000 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ /dev/null @@ -1,2285 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: p3filelists.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include "rsitems/rsserviceids.h" - -#include "file_sharing/p3filelists.h" -#include "file_sharing/directory_storage.h" -#include "file_sharing/directory_updater.h" -#include "file_sharing/rsfilelistitems.h" -#include "file_sharing/file_sharing_defaults.h" - -#include "retroshare/rsids.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsinit.h" - -#include "rsserver/p3face.h" - -#define P3FILELISTS_DEBUG() std::cerr << time(NULL) << " : FILE_LISTS : " << __FUNCTION__ << " : " -#define P3FILELISTS_ERROR() std::cerr << "***ERROR***" << " : FILE_LISTS : " << __FUNCTION__ << " : " - -//#define DEBUG_P3FILELISTS 1 -//#define DEBUG_CONTENT_FILTERING 1 -//#define DEBUG_FILE_HIERARCHY 1 - -static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ; -static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ; -static const uint32_t P3FILELISTS_UPDATE_FLAG_LOCAL_DIRS_CHANGED = 0x0002 ; -static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_DIRS_CHANGED = 0x0004 ; - -p3FileDatabase::p3FileDatabase(p3ServiceControl *mpeers) - : mServCtrl(mpeers), mFLSMtx("p3FileLists") -{ - // make sure the base directory exists - - std::string base_dir = RsAccounts::AccountDirectory(); - - if(base_dir.empty()) - throw std::runtime_error("Cannot create base directory to store/access file sharing files.") ; - - mFileSharingDir = base_dir + "/" + FILE_SHARING_DIR_NAME ; - - if(!RsDirUtil::checkCreateDirectory(mFileSharingDir)) - throw std::runtime_error("Cannot create base directory to store/access file sharing files.") ; - - // loads existing indexes for friends. Some might be already present here. - // - mRemoteDirectories.clear() ; // we should load them! - mOwnId = mpeers->getOwnId() ; - - mBannedFileListNeedsUpdate = false; - mLocalSharedDirs = new LocalDirectoryStorage(mFileSharingDir + "/" + LOCAL_SHARED_DIRS_FILE_NAME,mOwnId); - mHashCache = new HashStorage(mFileSharingDir + "/" + HASH_CACHE_FILE_NAME) ; - - mLocalDirWatcher = new LocalDirectoryUpdater(mHashCache,mLocalSharedDirs) ; - - mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ; - mLastRemoteDirSweepTS = 0 ; - mLastExtraFilesCacheUpdate = 0; - mLastCleanupTime = 0 ; - mLastDataRecvTS = 0 ; - mTrustFriendNodesForBannedFiles = TRUST_FRIEND_NODES_FOR_BANNED_FILES_DEFAULT; - mLastPrimaryBanListChangeTimeStamp = 0; - - // This is for the transmission of data - - addSerialType(new RsFileListsSerialiser()) ; -} - -void p3FileDatabase::setIgnoreLists(const std::list& ignored_prefixes,const std::list& ignored_suffixes, uint32_t ignore_flags) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->setIgnoreLists(ignored_prefixes,ignored_suffixes,ignore_flags) ; - - IndicateConfigChanged(); -} -bool p3FileDatabase::getIgnoreLists(std::list& ignored_prefixes,std::list& ignored_suffixes, uint32_t& ignore_flags) -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->getIgnoreLists(ignored_prefixes,ignored_suffixes,ignore_flags) ; -} - -RsSerialiser *p3FileDatabase::setupSerialiser() -{ - // This one is for saveList/loadList - - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsFileListsSerialiser()) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - rss->addSerialType(new RsFileConfigSerialiser()); - - return rss ; -} -void p3FileDatabase::setSharedDirectories(const std::list& shared_dirs) -{ - { - RS_STACK_MUTEX(mFLSMtx) ; - - mLocalSharedDirs->setSharedDirectoryList(shared_dirs) ; - mLocalDirWatcher->forceUpdate(false); - - } - - IndicateConfigChanged(); -} -void p3FileDatabase::getSharedDirectories(std::list& shared_dirs) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalSharedDirs->getSharedDirectoryList(shared_dirs) ; -} -void p3FileDatabase::updateShareFlags(const SharedDirInfo& info) -{ - { - RS_STACK_MUTEX(mFLSMtx) ; - mLocalSharedDirs->updateShareFlags(info) ; - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - IndicateConfigChanged(); -} - -p3FileDatabase::~p3FileDatabase() -{ - RS_STACK_MUTEX(mFLSMtx) ; - - for(uint32_t i=0;iprint(); -#endif - last_print_time = now ; - } - -#warning mr-alice 2016-08-19: "This should be removed, but it's necessary atm for updating the GUI" - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - - checkSendBannedFilesInfo(); - } - - if(mUpdateFlags) - { - IndicateConfigChanged(); - - if(mUpdateFlags & P3FILELISTS_UPDATE_FLAG_LOCAL_DIRS_CHANGED) - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - - if(mUpdateFlags & P3FILELISTS_UPDATE_FLAG_REMOTE_DIRS_CHANGED) - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); - - mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ; - } - - if(mLastRemoteDirSweepTS + 5 < now) - { - RS_STACK_MUTEX(mFLSMtx) ; - - std::set online_peers ; - mServCtrl->getPeersConnected(getServiceInfo().mServiceType, online_peers) ; - - for(uint32_t i=0;ipeerId()) != online_peers.end() && mRemoteDirectories[i]->lastSweepTime() + DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP < now) - { -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "Launching recurs sweep of friend directory " << mRemoteDirectories[i]->peerId() << ". Content currently is:" << std::endl; - mRemoteDirectories[i]->print(); -#endif - - locked_recursSweepRemoteDirectory(mRemoteDirectories[i],mRemoteDirectories[i]->root(),0) ; - mRemoteDirectories[i]->lastSweepTime() = now ; - } - - mRemoteDirectories[i]->checkSave() ; - } - - mLastRemoteDirSweepTS = now; - mLocalSharedDirs->checkSave() ; - - // This is a hack to make loaded directories show up in the GUI, because the GUI generally isn't ready at the time they are actually loaded up, - // so the first notify is ignored, and no other notify will happen next. We only do it if no data was received in the last 5 secs, in order to - // avoid syncing the GUI at every dir sync which kills performance. - - if(mLastDataRecvTS + 5 < now && mLastDataRecvTS + 20 > now) - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); // notify the GUI if the hierarchy has changed - } - - return 0; -} - -void p3FileDatabase::startThreads() -{ - RS_STACK_MUTEX(mFLSMtx) ; -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Starting directory watcher thread..." ; -#endif - mLocalDirWatcher->start("fs dir watcher"); -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Done." << std::endl; -#endif -} -void p3FileDatabase::stopThreads() -{ - RS_STACK_MUTEX(mFLSMtx) ; -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Stopping hash cache thread..." ; std::cerr.flush() ; -#endif - mHashCache->fullstop(); -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Done." << std::endl; - P3FILELISTS_DEBUG() << "Stopping directory watcher thread..." ; std::cerr.flush() ; -#endif - mLocalDirWatcher->fullstop(); -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Done." << std::endl; -#endif -} - -bool p3FileDatabase::saveList(bool &cleanup, std::list& sList) -{ -cleanup = true; - -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "Save list" << std::endl; -#endif - - /* get list of directories */ - std::list dirList; - { - RS_STACK_MUTEX(mFLSMtx) ; - mLocalSharedDirs->getSharedDirectoryList(dirList); - } - - { - RS_STACK_MUTEX(mFLSMtx) ; - for(std::list::iterator it = dirList.begin(); it != dirList.end(); ++it) - { - RsFileConfigItem *fi = new RsFileConfigItem(); - - fi->file.path = (*it).filename ; - fi->file.name = (*it).virtualname ; - fi->flags = (*it).shareflags.toUInt32() ; - - for(std::list::const_iterator it2( (*it).parent_groups.begin());it2!=(*it).parent_groups.end();++it2) - fi->parent_groups.ids.insert(*it2) ; - - sList.push_back(fi); - } - } - - { - RS_STACK_MUTEX(mFLSMtx) ; - - RsFileListsBannedHashesConfigItem *item = new RsFileListsBannedHashesConfigItem ; - - item->primary_banned_files_list = mPrimaryBanList; - sList.push_back(item) ; - } - - RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet(); - - /* basic control parameters */ - { - RS_STACK_MUTEX(mFLSMtx) ; - std::string s ; - rs_sprintf(s, "%lu", mHashCache->rememberHashFilesDuration()) ; - - RsTlvKeyValue kv; - - kv.key = HASH_CACHE_DURATION_SS; - kv.value = s ; - - rskv->tlvkvs.pairs.push_back(kv); - } - - { - std::string s ; - rs_sprintf(s, "%d", watchPeriod()) ; - - RsTlvKeyValue kv; - - kv.key = WATCH_FILE_DURATION_SS; - kv.value = s ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - std::string s ; - rs_sprintf(s, "%d", maxShareDepth()) ; - - RsTlvKeyValue kv; - - kv.key = MAX_SHARE_DEPTH; - kv.value = s ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - RsTlvKeyValue kv; - - kv.key = FOLLOW_SYMLINKS_SS; - kv.value = followSymLinks()?"YES":"NO" ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - RsTlvKeyValue kv; - - kv.key = IGNORE_DUPLICATES; - kv.value = ignoreDuplicates()?"YES":"NO" ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - RsTlvKeyValue kv; - - kv.key = WATCH_FILE_ENABLED_SS; - kv.value = watchEnabled()?"YES":"NO" ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - RsTlvKeyValue kv; - - kv.key = TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS; - kv.value = trustFriendNodesForBannedFiles()?"YES":"NO" ; - - rskv->tlvkvs.pairs.push_back(kv); - } - { - RsTlvKeyValue kv; - - kv.key = WATCH_HASH_SALT_SS; - kv.value = mLocalDirWatcher->hashSalt().toStdString(); - - rskv->tlvkvs.pairs.push_back(kv); - } - { - std::list prefix_list,suffix_list; - uint32_t flags ; - - mLocalDirWatcher->getIgnoreLists(prefix_list,suffix_list,flags) ; - - std::string prefix_string, suffix_string ; - - for(auto it(prefix_list.begin());it!=prefix_list.end();++it) prefix_string += *it + ";" ; - for(auto it(suffix_list.begin());it!=suffix_list.end();++it) suffix_string += *it + ";" ; - - RsTlvKeyValue kv; - - kv.key = IGNORED_PREFIXES_SS; kv.value = prefix_string; rskv->tlvkvs.pairs.push_back(kv); - kv.key = IGNORED_SUFFIXES_SS; kv.value = suffix_string; rskv->tlvkvs.pairs.push_back(kv); - - std::string s ; - rs_sprintf(s, "%lu", flags) ; - - kv.key = IGNORE_LIST_FLAGS_SS; kv.value = s; rskv->tlvkvs.pairs.push_back(kv); - } - - /* Add KeyValue to saveList */ - sList.push_back(rskv); - - return true; -} - -bool p3FileDatabase::loadList(std::list& load) -{ - /* for each item, check it exists .... - * - remove any that are dead (or flag?) - */ - static const FileStorageFlags PERMISSION_MASK = DIR_FLAGS_PERMISSIONS_MASK; - -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "Load list" << std::endl; -#endif - - std::list dirList; - std::list ignored_prefixes,ignored_suffixes ; - uint32_t ignore_flags = RS_FILE_SHARE_FLAGS_IGNORE_PREFIXES | RS_FILE_SHARE_FLAGS_IGNORE_SUFFIXES ; - uint32_t max_share_depth = 0; - - // OS-dependent default ignore lists -#ifdef WINDOWS_SYS - ignored_suffixes.push_back( ".bak" ); -#else - ignored_prefixes.push_back( "." ); - ignored_suffixes.push_back( "~" ); - ignored_suffixes.push_back( ".part" ); -#endif - - for(std::list::iterator it = load.begin(); it != load.end(); ++it) - { - RsConfigKeyValueSet *rskv ; - - if (NULL != (rskv = dynamic_cast(*it))) - { - /* make into map */ - //std::map configMap; - //std::map::const_iterator mit ; - - for(std::list::const_iterator kit = rskv->tlvkvs.pairs.begin(); kit != rskv->tlvkvs.pairs.end(); ++kit) - if (kit->key == HASH_CACHE_DURATION_SS) - { - uint32_t t=0 ; - if(sscanf(kit->value.c_str(),"%u",&t) == 1) - mHashCache->setRememberHashFilesDuration(t); - } - else if(kit->key == WATCH_FILE_DURATION_SS) - { - int t=0 ; - if(sscanf(kit->value.c_str(),"%d",&t) == 1) - setWatchPeriod(t); - } - else if(kit->key == FOLLOW_SYMLINKS_SS) - { - setFollowSymLinks(kit->value == "YES") ; - } - else if(kit->key == IGNORE_DUPLICATES) - { - setIgnoreDuplicates(kit->value == "YES") ; - } - else if(kit->key == WATCH_FILE_ENABLED_SS) - { - setWatchEnabled(kit->value == "YES") ; - } - else if(kit->key == TRUST_FRIEND_NODES_FOR_BANNED_FILES_SS) - { - setTrustFriendNodesForBannedFiles(kit->value == "YES") ; - } - else if(kit->key == WATCH_HASH_SALT_SS) - { - std::cerr << "Initing directory watcher with saved secret salt..." << std::endl; - mLocalDirWatcher->setHashSalt(RsFileHash(kit->value)) ; - } - else if(kit->key == IGNORED_PREFIXES_SS) - { - ignored_prefixes.clear(); - - std::string b ; - for(uint32_t i=0;ivalue.size();++i) - if(kit->value[i] == ';') - { - if(!b.empty()) // security! - ignored_prefixes.push_back(b) ; - - b.clear(); - } - else - b.push_back(kit->value[i]) ; - } - else if(kit->key == IGNORED_SUFFIXES_SS) - { - ignored_suffixes.clear(); - - std::string b ; - for(uint32_t i=0;ivalue.size();++i) - if(kit->value[i] == ';') - { - if(!b.empty()) // security! - ignored_suffixes.push_back(b) ; - b.clear(); - } - else - b.push_back(kit->value[i]) ; - } - else if(kit->key == IGNORE_LIST_FLAGS_SS) - { - int t=0 ; - if(sscanf(kit->value.c_str(),"%d",&t) == 1) - ignore_flags = (uint32_t)t ; - } - else if(kit->key == MAX_SHARE_DEPTH) - { - int t=0 ; - if(sscanf(kit->value.c_str(),"%d",&t) == 1) - max_share_depth = (uint32_t)t ; - } - - delete *it ; - continue ; - } - - RsFileConfigItem *fi = dynamic_cast(*it); - - if (fi) - { - /* ensure that it exists? */ - - SharedDirInfo info ; - info.filename = RsDirUtil::convertPathToUnix(fi->file.path); - info.virtualname = fi->file.name; - info.shareflags = FileStorageFlags(fi->flags) ; - info.shareflags &= PERMISSION_MASK ; - - for(std::set::const_iterator itt(fi->parent_groups.ids.begin());itt!=fi->parent_groups.ids.end();++itt) - info.parent_groups.push_back(*itt) ; - - dirList.push_back(info) ; - } - - RsFileListsBannedHashesConfigItem *fb = dynamic_cast(*it) ; - - if(fb) - { - mPrimaryBanList = fb->primary_banned_files_list ; - mBannedFileListNeedsUpdate = true; - mLastPrimaryBanListChangeTimeStamp = time(NULL); - } - - delete *it ; - } - - /* set directories */ - mLocalSharedDirs->setSharedDirectoryList(dirList); - mLocalDirWatcher->setIgnoreLists(ignored_prefixes,ignored_suffixes,ignore_flags) ; - mLocalDirWatcher->setMaxShareDepth(max_share_depth); - - load.clear() ; - - return true; -} - -void p3FileDatabase::cleanup() -{ - { - RS_STACK_MUTEX(mFLSMtx) ; -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "p3FileDatabase::cleanup()" << std::endl; -#endif - - // look through the list of friend directories. Remove those who are not our friends anymore. - // - std::set friend_set ; - { - std::list friend_lst ; - - rsPeers->getFriendList(friend_lst); - - for(std::list::const_iterator it(friend_lst.begin());it!=friend_lst.end();++it) - friend_set.insert(*it) ; - } - rstime_t now = time(NULL); - - for(uint32_t i=0;igetDirectoryRecursModTime(0,recurs_mod_time) ; - - rstime_t last_contact = 0 ; - RsPeerDetails pd ; - if(rsPeers->getPeerDetails(mRemoteDirectories[i]->peerId(),pd)) - last_contact = pd.lastConnect ; - - // We remove directories in the following situations: - // - the peer is not a friend - // - the dir list is non empty but the peer is offline since more than 60 days - // - the dir list is empty and the peer is ffline since more than 5 days - - bool should_remove = friend_set.find(mRemoteDirectories[i]->peerId()) == friend_set.end() - || (recurs_mod_time == 0 && last_contact + DELAY_BEFORE_DELETE_EMPTY_REMOTE_DIR < now ) - || (recurs_mod_time != 0 && last_contact + DELAY_BEFORE_DELETE_NON_EMPTY_REMOTE_DIR < now ); - - if(!should_remove) - continue ; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " removing file list of non friend " << mRemoteDirectories[i]->peerId() << std::endl; -#endif - - mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; - - friend_set.erase(mRemoteDirectories[i]->peerId()); - - mFriendIndexMap.erase(mRemoteDirectories[i]->peerId()); - - // also remove the existing file - - remove(mRemoteDirectories[i]->filename().c_str()) ; - - delete mRemoteDirectories[i]; - mRemoteDirectories[i] = NULL ; - - // now, in order to avoid empty seats, just move the last one here, and update indexes - - while(i < mRemoteDirectories.size() && mRemoteDirectories[i] == NULL) - { - mRemoteDirectories[i] = mRemoteDirectories.back(); - mRemoteDirectories.pop_back(); - } - - if(i < mRemoteDirectories.size() && mRemoteDirectories[i] != NULL) // this test is needed in the case we have deleted the last element - mFriendIndexMap[mRemoteDirectories[i]->peerId()] = i; - - mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_DIRS_CHANGED ; - } - - // look through the remaining list of friends, which are the ones for which no remoteDirectoryStorage class has been allocated. - // - for(std::set::const_iterator it(friend_set.begin());it!=friend_set.end();++it) - { - // Check if a remote directory exists for that friend, possibly creating the index if the file does not but the friend is online. - - if(rsPeers->isOnline(*it) || RsDirUtil::fileExists(makeRemoteFileName(*it))) - locked_getFriendIndex(*it) ; - } - - // cancel existing requests for which the peer is offline - - std::set online_peers ; - mServCtrl->getPeersConnected(getServiceInfo().mServiceType, online_peers) ; - - for(std::map::iterator it = mPendingSyncRequests.begin();it!=mPendingSyncRequests.end();) - if(online_peers.find(it->second.peer_id) == online_peers.end() || it->second.request_TS + DELAY_BEFORE_DROP_REQUEST < now) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " removing pending request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << ", because peer is offline or request is too old." << std::endl; -#endif - std::map::iterator tmp(it); - ++tmp; - mPendingSyncRequests.erase(it) ; - it = tmp; - } - else - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " keeping request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << std::endl; -#endif - ++it ; - } - - // This is needed at least here, because loadList() might never have been called, if there is no config file present. - - if(mLocalDirWatcher->hashSalt().isNull()) - { - std::cerr << "(WW) Initialising directory watcher salt to some random value " << std::endl; - mLocalDirWatcher->setHashSalt(RsFileHash::random()) ; - - IndicateConfigChanged(); - } - } -} - -std::string p3FileDatabase::makeRemoteFileName(const RsPeerId& pid) const -{ - return mFileSharingDir + "/" + "dirlist_"+pid.toStdString()+".bin" ; -} - -uint32_t p3FileDatabase::locked_getFriendIndex(const RsPeerId& pid) -{ - std::map::const_iterator it = mFriendIndexMap.find(pid) ; - - if(it == mFriendIndexMap.end()) - { - // allocate a new index for that friend, and tell that we should save. - uint32_t found = 0 ; - for(uint32_t i=0;isecond << std::endl; -#endif - } - - if(sizeof(void*)==4 && mRemoteDirectories.size() >= (1u << NB_FRIEND_INDEX_BITS_32BITS) ) - { - std::cerr << "(EE) FriendIndexTab is full. This is weird. Do you really have more than " << (1<= (1ull << NB_FRIEND_INDEX_BITS_64BITS) ) - { - std::cerr << "(EE) FriendIndexTab is full. This is weird. Do you really have more than " << (1<second) - { - mRemoteDirectories.resize(it->second+1,NULL) ; - mRemoteDirectories[it->second] = new RemoteDirectoryStorage(pid,makeRemoteFileName(pid)); - - mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_DIRS_CHANGED ; - mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << pid << ", with index " << it->second << std::endl; -#endif - } - - return it->second; - } -} - -template<> bool p3FileDatabase::convertPointerToEntryIndex<4>(const void *p, EntryIndex& e, uint32_t& friend_index) -{ - // trust me, I can do this ;-) - -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // defined(__GNUC__) && !defined(__clang__) - e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_32BITS ) ; - friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_32BITS ; -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif // defined(__GNUC__) && !defined(__clang__) - - if(friend_index == 0) - { - std::cerr << "(EE) Cannot find friend index in pointer. Encoded value is zero!" << std::endl; - return false; - } - friend_index--; - - return true; -} -template<> bool p3FileDatabase::convertEntryIndexToPointer<4>(const EntryIndex& e, uint32_t fi, void *& p) -{ - // the pointer is formed the following way: - // - // [ 10 bits | 22 bits ] - // - // This means that the whoel software has the following build-in limitation: - // * 1023 friends - // * 4M shared files. - - uint32_t fe = (uint32_t)e ; - - if(fi+1 >= (1u<= (1u<< NB_ENTRY_INDEX_BITS_32BITS)) - { - P3FILELISTS_ERROR() << "(EE) cannot convert entry index " << e << " of friend with index " << fi << " to pointer." << std::endl; - return false ; - } - - p = reinterpret_cast( ( (1u+fi) << NB_ENTRY_INDEX_BITS_32BITS ) + (fe & ENTRY_INDEX_BIT_MASK_32BITS)) ; - - return true; -} -template<> bool p3FileDatabase::convertPointerToEntryIndex<8>(const void *p, EntryIndex& e, uint32_t& friend_index) -{ - // trust me, I can do this ;-) - -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // defined(__GNUC__) && !defined(__clang__) - e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_64BITS ) ; - friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_64BITS ; -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif // defined(__GNUC__) && !defined(__clang__) - - if(friend_index == 0) - { - std::cerr << "(EE) Cannot find friend index in pointer. Encoded value is zero!" << std::endl; - return false; - } - friend_index--; - -#ifdef DEBUG_P3FILELISTS - std::cerr << "Generated index " << e <<" friend " << friend_index << " from pointer " << p << std::endl; -#endif - return true; -} -template<> bool p3FileDatabase::convertEntryIndexToPointer<8>(const EntryIndex& e, uint32_t fi, void *& p) -{ - // the pointer is formed the following way: - // - // [ 24 bits | 40 bits ] - // - // This means that the whoel software has the following build-in limitation: - // * 1.6M friends - // * 1T shared files. - - uint64_t fe = (uint64_t)e ; - - if(fi+1 >= (1ull<= (1ull<< NB_ENTRY_INDEX_BITS_64BITS)) - { - P3FILELISTS_ERROR() << "(EE) cannot convert entry index " << e << " of friend with index " << fi << " to pointer." << std::endl; - return false ; - } - - p = reinterpret_cast( ( (1ull+fi) << NB_ENTRY_INDEX_BITS_64BITS ) + (fe & ENTRY_INDEX_BIT_MASK_64BITS)) ; - -#ifdef DEBUG_P3FILELISTS - std::cerr << "Generated pointer " << p << " from friend " << fi << " and index " << e << std::endl; -#endif - - return true; -} -void p3FileDatabase::requestDirUpdate(void *ref) -{ - uint32_t fi; - DirectoryStorage::EntryIndex e ; - - convertPointerToEntryIndex(ref,e,fi); - - if(fi == 0) - return ; // not updating current directory (should we?) - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Trying to force sync of entry ndex " << e << " to friend " << mRemoteDirectories[fi-1]->peerId() << std::endl; -#endif - - RS_STACK_MUTEX(mFLSMtx) ; - - if(locked_generateAndSendSyncRequest(mRemoteDirectories[fi-1],e)) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Succeed." << std::endl; -#endif - } -} - -// Finds the pointer to the sub-element #row under element ref. - -bool p3FileDatabase::findChildPointer( void *ref, int row, void *& result, - FileSearchFlags flags ) const -{ - if (ref == NULL) - { - if(flags & RS_FILE_HINTS_LOCAL) - { - if(row != 0 && row != 1) - return false ; - - convertEntryIndexToPointer(0,row,result); - - return true ; - } - else if((uint32_t)row < mRemoteDirectories.size()) - { - convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result); - return true; - } - else - return false; - } - - uint32_t fi; - DirectoryStorage::EntryIndex e ; - - convertPointerToEntryIndex(ref,e,fi); - - // check consistency - if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 1 && (flags & RS_FILE_HINTS_LOCAL))) - { - P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; - return false ; - } - - if(fi==1 && (flags & RS_FILE_HINTS_LOCAL)) // extra list - { - convertEntryIndexToPointer(row+1,1,result); - return true; - } - DirectoryStorage *storage = (flags & RS_FILE_HINTS_LOCAL)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]); - - // Case where the index is the top of a single person. Can be us, or a friend. - - EntryIndex c = 0; - bool res = storage->getChildIndex(e,row,c); - - convertEntryIndexToPointer(c,fi,result) ; - - return res; -} - -// This function returns statistics about the entire directory - -int p3FileDatabase::getSharedDirStatistics(const RsPeerId& pid,SharedDirStats& stats) -{ - RS_STACK_MUTEX(mFLSMtx) ; - - if(pid == mOwnId) - { - mLocalSharedDirs->getStatistics(stats) ; - return true ; - } - else - { - uint32_t fi = locked_getFriendIndex(pid); - mRemoteDirectories[fi]->getStatistics(stats) ; - - return true ; - } -} - -bool p3FileDatabase::removeExtraFile(const RsFileHash& hash) -{ - bool ret = false; - { - RS_STACK_MUTEX(mFLSMtx) ; - - ret = mExtraFiles->removeExtraFile(hash); - mLastExtraFilesCacheUpdate = 0 ; // forced cache reload - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0); - return ret; -} - -void p3FileDatabase::getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIndex e,DirDetails& d) const -{ - // update the cache of extra files if last requested too long ago - - rstime_t now = time(NULL); - - if(mLastExtraFilesCacheUpdate + DELAY_BETWEEN_EXTRA_FILES_CACHE_UPDATES <= now) - { - mExtraFiles->getExtraFileList(mExtraFilesCache); - mLastExtraFilesCacheUpdate = now; - } - - // - - if(e == 0) // "virtual extra files directory" => create a dir with as many child as they are extra files - { - d.parent = NULL ; - - d.prow = 0;//fi-1 ; - d.type = DIR_TYPE_PERSON; - d.hash.clear() ; - d.size = mExtraFilesCache.size(); - d.max_mtime = time(NULL); - d.mtime = time(NULL); - d.name = "[Extra List]"; - d.path = "/"; - d.ref = ref ; - - for(uint32_t i=0;i(i+1,1,stub.ref); // local shared files from extra list - - d.children.push_back(stub); - } - } - else // extra file. Just query the corresponding data from ftExtra - { - d.prow = 1;//fi-1 ; - d.type = DIR_TYPE_EXTRA_FILE; - - FileInfo& f(mExtraFilesCache[(int)e-1]) ; - - d.hash = f.hash; - d.size = f.size; - d.max_mtime = 0; // this is irrelevant - d.mtime = 0; // this is irrelevant - d.name = f.path; // so that the UI shows the complete path, since the parent directory is not really a directory. - d.path = f.path; - d.ref = ref ; - - convertEntryIndexToPointer(0,1,d.parent) ; - } - - d.flags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ; - d.id = RsPeerId(); -} - -// This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files. -int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const -{ - RS_STACK_MUTEX(mFLSMtx) ; - - d.children.clear(); - - // Case where the pointer is NULL, which means we're at the top of the list of shared directories for all friends (including us) - // or at the top of our own list of shared directories, depending on the flags. - - // Friend index is used as follows: - // 0 : own id - // 1...n : other friends - // - // entry_index: starts at 0. - // - // The point is: we cannot use (0,0) because it encodes to NULL. No existing combination should encode to NULL. - // So we need to properly convert the friend index into 0 or into a friend tab index in mRemoteDirectories. - // - // We should also check the consistency between flags and the content of ref. - - if (ref == NULL) - { - d.ref = NULL ; - d.type = DIR_TYPE_ROOT; - d.parent = NULL; - d.prow = -1; - d.name = "root"; - d.hash.clear() ; - d.path = ""; - d.mtime = 0; - d.flags.clear() ; - d.max_mtime = 0 ; - - if(flags & RS_FILE_HINTS_LOCAL) - { - void *p; - - { - convertEntryIndexToPointer(0,0,p); // root of own directories - DirStub stub; - stub.type = DIR_TYPE_PERSON; - stub.name = mServCtrl->getOwnId().toStdString(); - stub.ref = p; - d.children.push_back(stub); - } - - if(mExtraFiles->size() > 0) - { - convertEntryIndexToPointer(0,1,p); // local shared files from extra list - DirStub stub; - stub.type = DIR_TYPE_PERSON; // not totally exact, but used as a trick. - stub.name = "[Extra List]"; - stub.ref = p; - - d.children.push_back(stub); - } - - - } - else for(uint32_t i=0;i(mRemoteDirectories[i]->root(),i+1,p); - - DirStub stub; - stub.type = DIR_TYPE_PERSON; - stub.name = mRemoteDirectories[i]->peerId().toStdString(); - stub.ref = p; - d.children.push_back(stub); - } - - d.size = 0; // non documented - -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; - P3FILELISTS_DEBUG() << d << std::endl; -#endif - - return true ; - } - - uint32_t fi; - DirectoryStorage::EntryIndex e ; - - convertPointerToEntryIndex(ref,e,fi); - - // check consistency - if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 1 && (flags & RS_FILE_HINTS_LOCAL))) - { - P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; - return false ; - } - - if((flags & RS_FILE_HINTS_LOCAL) && fi == 1) // extra list - { - getExtraFilesDirDetails(ref,e,d); - -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; - P3FILELISTS_DEBUG() << d << std::endl; -#endif - return true; - } - - - DirectoryStorage *storage = (flags & RS_FILE_HINTS_LOCAL)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]); - - // Case where the index is the top of a single person. Can be us, or a friend. - - if(storage==NULL || !storage->extractData(e,d)) - { -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "(WW) request on index " << e << ", for directory ID=" << ((storage==NULL)?("[NULL]"):(storage->peerId().toStdString())) << " failed. This should not happen." << std::endl; -#endif - return false ; - } - - // update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert - // a pointer into an int. - - convertEntryIndexToPointer((intptr_t)d.ref,fi,d.ref) ; - - for(uint32_t i=0;i((intptr_t)d.children[i].ref,fi,d.children[i].ref); - - if(e == 0) // root - { - d.prow = 0;//fi-1 ; - d.parent = NULL ; - } - else - { - if(d.parent == 0) // child of root node - d.prow = (flags & RS_FILE_HINTS_LOCAL)?0:(fi-1); - else - d.prow = storage->parentRow(e) ; - - convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ; - } - - d.id = storage->peerId(); - -#ifdef DEBUG_FILE_HIERARCHY - P3FILELISTS_DEBUG() << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; - P3FILELISTS_DEBUG() << d << std::endl; -#endif - - return true; -} - -uint32_t p3FileDatabase::getType(void *ref,FileSearchFlags flags) const -{ - RS_STACK_MUTEX(mFLSMtx) ; - - EntryIndex e ; - uint32_t fi; - - if(ref == NULL) - return DIR_TYPE_ROOT ; - - convertPointerToEntryIndex(ref,e,fi); - - if(e == 0) - return DIR_TYPE_PERSON ; - - if(flags & RS_FILE_HINTS_LOCAL) - { - if(fi == 0 && mLocalSharedDirs != NULL) - return mLocalSharedDirs->getEntryType(e) ; - - if(fi == 1) - return DIR_TYPE_EXTRA_FILE; - - P3FILELISTS_ERROR() << " Cannot determine type of entry " << ref << std::endl; - return DIR_TYPE_ROOT ;// some failure case. Should not happen - } - else - { - if(fi-1 < mRemoteDirectories.size() && mRemoteDirectories[fi-1]!=NULL) - return mRemoteDirectories[fi-1]->getEntryType(e) ; - - P3FILELISTS_ERROR() << " Cannot determine type of entry " << ref << std::endl; - return DIR_TYPE_ROOT ;// some failure case. Should not happen - } -} - -void p3FileDatabase::forceDirectoryCheck(bool add_safe_delay) // Force re-sweep the directories and see what's changed -{ - mLocalDirWatcher->forceUpdate(add_safe_delay); -} -void p3FileDatabase::togglePauseHashingProcess() -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->togglePauseHashingProcess(); -} -bool p3FileDatabase::hashingProcessPaused() -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->hashingProcessPaused(); -} -bool p3FileDatabase::inDirectoryCheck() -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->inDirectoryCheck(); -} -void p3FileDatabase::setFollowSymLinks(bool b) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->setFollowSymLinks(b) ; - IndicateConfigChanged(); -} -bool p3FileDatabase::followSymLinks() const -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->followSymLinks() ; -} -void p3FileDatabase::setIgnoreDuplicates(bool i) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->setIgnoreDuplicates(i) ; - IndicateConfigChanged(); -} -bool p3FileDatabase::ignoreDuplicates() const -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->ignoreDuplicates() ; -} -void p3FileDatabase::setMaxShareDepth(int i) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->setMaxShareDepth(i) ; - IndicateConfigChanged(); -} -int p3FileDatabase::maxShareDepth() const -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->maxShareDepth() ; -} -void p3FileDatabase::setWatchEnabled(bool b) -{ - RS_STACK_MUTEX(mFLSMtx) ; - mLocalDirWatcher->setEnabled(b) ; - IndicateConfigChanged(); -} -bool p3FileDatabase::watchEnabled() -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->isEnabled() ; -} -void p3FileDatabase::setWatchPeriod(uint32_t seconds) -{ - RS_STACK_MUTEX(mFLSMtx) ; - - mLocalDirWatcher->setFileWatchPeriod(seconds); - IndicateConfigChanged(); -} -uint32_t p3FileDatabase::watchPeriod() -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalDirWatcher->fileWatchPeriod(); -} - -int p3FileDatabase::SearchKeywords(const std::list& keywords, std::list& results,FileSearchFlags flags,const RsPeerId& client_peer_id) -{ - if(flags & RS_FILE_HINTS_LOCAL) - { - std::list firesults; - std::list pointers; - - { - RS_STACK_MUTEX(mFLSMtx) ; - - mLocalSharedDirs->searchTerms(keywords,firesults) ; - - for(std::list::iterator it(firesults.begin());it!=firesults.end();++it) - { - void *p=NULL; - convertEntryIndexToPointer(*it,0,p); - pointers.push_back(p) ; - } - } - - filterResults(pointers,results,flags,client_peer_id) ; - } - - if(flags & RS_FILE_HINTS_REMOTE) - { - std::list pointers ; - - { - RS_STACK_MUTEX(mFLSMtx) ; - - for(uint32_t i=0;i local_results; - mRemoteDirectories[i]->searchTerms(keywords,local_results) ; - - for(std::list::iterator it(local_results.begin());it!=local_results.end();++it) - { - void *p=NULL; - convertEntryIndexToPointer(*it,i+1,p); - - pointers.push_back(p) ; - } - } - } - - for(auto it(pointers.begin());it!=pointers.end();++it) - { - DirDetails dd; - - if(!RequestDirDetails (*it,dd,RS_FILE_HINTS_REMOTE)) - continue ; - - results.push_back(dd); - } - } - - return !results.empty() ; -} - -int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::list& results,FileSearchFlags flags,const RsPeerId& client_peer_id) const -{ - if(flags & RS_FILE_HINTS_LOCAL) - { - std::list firesults; - std::list pointers; - { - RS_STACK_MUTEX(mFLSMtx) ; - - mLocalSharedDirs->searchBoolExp(exp,firesults) ; - - for(std::list::iterator it(firesults.begin());it!=firesults.end();++it) - { - void *p=NULL; - convertEntryIndexToPointer(*it,0,p); - pointers.push_back(p); - } - } - - filterResults(pointers,results,flags,client_peer_id) ; - } - - if(flags & RS_FILE_HINTS_REMOTE) - { - std::list pointers ; - { - RS_STACK_MUTEX(mFLSMtx) ; - - for(uint32_t i=0;i local_results; - mRemoteDirectories[i]->searchBoolExp(exp,local_results) ; - - for(std::list::iterator it(local_results.begin());it!=local_results.end();++it) - { - void *p=NULL; - convertEntryIndexToPointer(*it,i+1,p); - pointers.push_back(p) ; - } - } - } - - for(auto it(pointers.begin());it!=pointers.end();++it) - { - DirDetails dd; - - if(!RequestDirDetails (*it,dd,RS_FILE_HINTS_REMOTE)) - continue ; - - results.push_back(dd); - } - } - - return !results.empty() ; - -} - -bool p3FileDatabase::search( - const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const -{ - RS_STACK_MUTEX(mFLSMtx); - - if( (hintflags & RS_FILE_HINTS_EXTRA) && - mExtraFiles->search(hash, hintflags, info) ) - return true; - - if(hintflags & RS_FILE_HINTS_LOCAL) - { - RsFileHash real_hash ; - EntryIndex indx; - - if(mLocalSharedDirs->searchHash(hash,real_hash,indx)) - { - mLocalSharedDirs->getFileInfo(indx,info) ; - - if(!real_hash.isNull()) - { - info.hash = real_hash ; - info.transfer_info_flags |= RS_FILE_REQ_ENCRYPTED ; - } - - return true; - } - } - - if(hintflags & RS_FILE_HINTS_REMOTE) - { - EntryIndex indx; - bool found = false ; - - for(uint32_t i=0;isearchHash(hash,indx)) - { - TransferInfo ti ; - ti.peerId = mRemoteDirectories[i]->peerId(); - - info.hash = hash ; - info.peers.push_back(ti) ; - - found = true ; - } - - if(found) - return true; - } - return false; -} - -int p3FileDatabase::filterResults(const std::list& firesults,std::list& results,FileSearchFlags flags,const RsPeerId& peer_id) const -{ - results.clear(); - - flags &= RS_FILE_HINTS_PERMISSION_MASK; // remove other flags. - - /* translate/filter results */ - - for(std::list::const_iterator rit(firesults.begin()); rit != firesults.end(); ++rit) - { - DirDetails cdetails ; - - if(!RequestDirDetails (*rit,cdetails,RS_FILE_HINTS_LOCAL)) - { - P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << *rit << std::endl; - continue ; - } -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Filtering candidate " << *rit << ", flags=" << cdetails.flags << ", peer=" << peer_id ; -#endif - - if(!peer_id.isNull()) - { - FileSearchFlags permission_flags = rsPeers->computePeerPermissionFlags(peer_id,cdetails.flags,cdetails.parent_groups) ; - - if (cdetails.type == DIR_TYPE_FILE && ( permission_flags & flags )) - { - cdetails.id.clear() ; - results.push_back(cdetails); -#ifdef DEBUG_P3FILELISTS - std::cerr << ": kept" << std::endl ; -#endif - } -#ifdef DEBUG_P3FILELISTS - else - std::cerr << ": discarded" << std::endl ; -#endif - } - else - results.push_back(cdetails); - } - - return !results.empty() ; -} - -bool p3FileDatabase::convertSharedFilePath(const std::string& path,std::string& fullpath) -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mLocalSharedDirs->convertSharedFilePath(path,fullpath) ; -} - -//==============================================================================================================================// -// Update of remote directories // -//==============================================================================================================================// - -// Algorithm: -// -// Local dirs store the last modif time of the file, in local time -// - the max time is computed upward until the root of the hierarchy -// - because the hash is performed late, the last modf time upward is updated only when the hash is obtained. -// -// Remote dirs store -// 1 - recursive max modif time of the files/dir in the friend's time -// 2 - modif time of the files/dir in the friend's time -// 3 - update TS in the local time -// -// The update algorithm is the following: -// -// [Client side] -// - every 30 sec, send a sync packet for the root of the hierarchy containing the remote known max recurs TS. -// - crawl through all directories and if the update TS is 0, ask for sync too. -// - when a sync respnse is received: -// - if response is ACK, set the update time to now. Nothing changed. -// - if response is an update -// * locally update the subfiles -// * for all subdirs, set the local update time to 0 (so as to force a sync) -// -// [Server side] -// - when sync req is received, compare to local recurs TS, and send ACK or full update accordingly -// -// Directories are designated by their hash, instead of their index. This allows to hide the non shared directories -// behind a layer of abstraction, at the cost of a logarithmic search, which is acceptable as far as dir sync-ing between -// friends is concerned (We obviously could not do that for GUI display, which has a small and constant cost). - -void p3FileDatabase::tickRecv() -{ - RsItem *item ; - - while( NULL != (item = recvItem()) ) - { - switch(item->PacketSubType()) - { - case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast(item) ) ; break ; - case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM : handleBannedFilesInfo( dynamic_cast(item) ) ; break ; - case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: - { - RsFileListsSyncResponseItem *sitem = dynamic_cast(item); - handleDirSyncResponse(sitem) ; - item = sitem ; - } - break ; - default: - P3FILELISTS_ERROR() << "(EE) unhandled packet subtype " << item->PacketSubType() << " in " << __PRETTY_FUNCTION__ << std::endl; - } - - delete item ; - } -} - -void p3FileDatabase::tickSend() -{ - // go through the list of out requests and send them to the corresponding friends, if they are online. -} - -void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item) -{ - RsFileListsSyncResponseItem *ritem = new RsFileListsSyncResponseItem; - - // look at item TS. If local is newer, send the full directory content. - { - RS_STACK_MUTEX(mFLSMtx) ; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Received directory sync request from peer " << item->PeerId() << ". hash=" << item->entry_hash << ", flags=" << (void*)(intptr_t)item->flags << ", request id: " << std::hex << item->request_id << std::dec << ", last known TS: " << item->last_known_recurs_modf_TS << std::endl; -#endif - - EntryIndex entry_index = DirectoryStorage::NO_INDEX; - - if(!mLocalSharedDirs->getIndexFromDirHash(item->entry_hash,entry_index)) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl; -#endif - return; - } - - uint32_t entry_type = mLocalSharedDirs->getEntryType(entry_index) ; - ritem->PeerId(item->PeerId()) ; - ritem->request_id = item->request_id; - ritem->entry_hash = item->entry_hash ; - - std::list node_groups; - FileStorageFlags node_flags; - - if(entry_type != DIR_TYPE_DIR) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory does not exist anymore, or is not a directory, or permission denied. Answering with proper flags." << std::endl; -#endif - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED ; - } - else if(entry_index != 0 && (!mLocalSharedDirs->getFileSharingPermissions(entry_index,node_flags,node_groups) || !(rsPeers->computePeerPermissionFlags(item->PeerId(),node_flags,node_groups) & RS_FILE_HINTS_BROWSABLE))) - { - P3FILELISTS_ERROR() << "(EE) cannot get file permissions for entry index " << (void*)(intptr_t)entry_index << ", or permission denied." << std::endl; - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED ; - } - else - { - rstime_t local_recurs_max_time ; - mLocalSharedDirs->getDirectoryRecursModTime(entry_index,local_recurs_max_time) ; - - if(item->last_known_recurs_modf_TS != local_recurs_max_time) // normally, should be "<", but since we provided the TS it should be equal, so != is more robust. - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory is more recent than what the friend knows. Sending full dir content as response." << std::endl; -#endif - - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_SYNC_DIR_CONTENT; - ritem->last_known_recurs_modf_TS = local_recurs_max_time; - - // We supply the peer id, in order to possibly remove some subdirs, if entries are not allowed to be seen by this peer. - mLocalSharedDirs->serialiseDirEntry(entry_index,ritem->directory_content_data,item->PeerId()) ; - } - else - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Directory is up to date w.r.t. what the friend knows. Sending ACK." << std::endl; -#endif - - ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE ; - ritem->last_known_recurs_modf_TS = local_recurs_max_time ; - } - } - } - - // sends the response. - - splitAndSendItem(ritem) ; -} - -void p3FileDatabase::splitAndSendItem(RsFileListsSyncResponseItem *ritem) -{ - ritem->checksum = RsDirUtil::sha1sum((uint8_t*)ritem->directory_content_data.bin_data,ritem->directory_content_data.bin_len); - - while(ritem->directory_content_data.bin_len > MAX_DIR_SYNC_RESPONSE_DATA_SIZE) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Chopping off partial chunk of size " << MAX_DIR_SYNC_RESPONSE_DATA_SIZE << " from item data of size " << ritem->directory_content_data.bin_len << std::endl; -#endif - - ritem->flags |= RsFileListsItem::FLAGS_SYNC_PARTIAL ; - - RsFileListsSyncResponseItem *subitem = new RsFileListsSyncResponseItem() ; - - subitem->entry_hash = ritem->entry_hash; - subitem->flags = ritem->flags ; - subitem->last_known_recurs_modf_TS = ritem->last_known_recurs_modf_TS; - subitem->request_id = ritem->request_id; - subitem->checksum = ritem->checksum ; - - // copy a subpart of the data - subitem->directory_content_data.tlvtype = ritem->directory_content_data.tlvtype ; - subitem->directory_content_data.setBinData(ritem->directory_content_data.bin_data, MAX_DIR_SYNC_RESPONSE_DATA_SIZE) ; - - // update ritem to chop off the data that was sent. - memmove(ritem->directory_content_data.bin_data, &((unsigned char*)ritem->directory_content_data.bin_data)[MAX_DIR_SYNC_RESPONSE_DATA_SIZE], ritem->directory_content_data.bin_len - MAX_DIR_SYNC_RESPONSE_DATA_SIZE) ; - ritem->directory_content_data.bin_len -= MAX_DIR_SYNC_RESPONSE_DATA_SIZE ; - - // send - subitem->PeerId(ritem->PeerId()) ; - - sendItem(subitem) ; - - // fix up last chunk - if(ritem->directory_content_data.bin_len <= MAX_DIR_SYNC_RESPONSE_DATA_SIZE) - ritem->flags |= RsFileListsItem::FLAGS_SYNC_PARTIAL_END ; - } - - sendItem(ritem) ; -} - -// This function should not take memory ownership of ritem, so it makes copies. -// The item that is returned is either created (if different from ritem) or equal to ritem. - -RsFileListsSyncResponseItem *p3FileDatabase::recvAndRebuildItem(RsFileListsSyncResponseItem *ritem) -{ - if(!(ritem->flags & RsFileListsItem::FLAGS_SYNC_PARTIAL )) - return ritem ; - - // item is a partial item. Look first for a starting entry - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Item from peer " << ritem->PeerId() << " is partial. Size = " << ritem->directory_content_data.bin_len << std::endl; -#endif - - RS_STACK_MUTEX(mFLSMtx) ; - - bool is_ending = (ritem->flags & RsFileListsItem::FLAGS_SYNC_PARTIAL_END); - std::map::iterator it = mPartialResponseItems.find(ritem->request_id) ; - - if(it == mPartialResponseItems.end()) - { - if(is_ending) - { - P3FILELISTS_ERROR() << "Impossible situation: partial item ended right away. Dropping..." << std::endl; - return NULL; - } -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Creating new item buffer" << std::endl; -#endif - - mPartialResponseItems[ritem->request_id] = new RsFileListsSyncResponseItem(*ritem) ; - return NULL ; - } - else if(it->second->checksum != ritem->checksum) - { - P3FILELISTS_ERROR() << "Impossible situation: partial items with different checksums. Dropping..." << std::endl; - mPartialResponseItems.erase(it); - return NULL; - } - - // collapse the item at the end of the existing partial item. Dont delete ritem as it will be by the caller. - - uint32_t old_len = it->second->directory_content_data.bin_len ; - uint32_t added = ritem->directory_content_data.bin_len; - - it->second->directory_content_data.bin_data = realloc(it->second->directory_content_data.bin_data,old_len + added) ; - memcpy(&((unsigned char*)it->second->directory_content_data.bin_data)[old_len],ritem->directory_content_data.bin_data,added); - it->second->directory_content_data.bin_len = old_len + added ; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Added new chunk of length " << added << ". New size is " << old_len + added << std::endl; -#endif - - // if finished, return the item - - if(is_ending) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Item is complete. Returning it" << std::endl; -#endif - - RsFileListsSyncResponseItem *ret = it->second ; - mPartialResponseItems.erase(it) ; - - ret->flags &= ~RsFileListsItem::FLAGS_SYNC_PARTIAL_END ; - ret->flags &= ~RsFileListsItem::FLAGS_SYNC_PARTIAL ; - - return ret ; - } - else - return NULL ; -} - -// We employ a trick in this function: -// - if recvAndRebuildItem(item) returns the same item, it has not created memory, so the incoming item should be the one to -// delete, which is done by the caller in every case. -// - if it returns a different item, it means that the item has been created below when collapsing items, so we should delete both. -// to do so, we first delete the incoming item, and replace the pointer by the new created one. - -void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem*& sitem) -{ - RsFileListsSyncResponseItem *item = recvAndRebuildItem(sitem) ; - - if(!item) - return ; - - if(item != sitem) - { - delete sitem ; - sitem = item ; - } - - rstime_t now = time(NULL); - - // check the hash. If anything goes wrong (in the chunking for instance) the hash will not match - - if(RsDirUtil::sha1sum((uint8_t*)item->directory_content_data.bin_data,item->directory_content_data.bin_len) != item->checksum) - { - P3FILELISTS_ERROR() << "Checksum error in response item " << std::hex << item->request_id << std::dec << " . This is unexpected, and might be due to connection problems." << std::endl; - return ; - } - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Handling sync response for directory with hash " << item->entry_hash << std::endl; -#endif - - EntryIndex entry_index = DirectoryStorage::NO_INDEX; - - // find the correct friend entry - - uint32_t fi = 0 ; - - { - RS_STACK_MUTEX(mFLSMtx) ; - fi = locked_getFriendIndex(item->PeerId()); - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " friend index is " << fi ; -#endif - - // make sure we have a remote directory for that friend. - - if(!mRemoteDirectories[fi]->getIndexFromDirHash(item->entry_hash,entry_index)) - { - std::cerr << std::endl; - P3FILELISTS_ERROR() << " (EE) cannot find index from hash " << item->entry_hash << ". Dropping the response." << std::endl; - return ; - } -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " entry index is " << entry_index << " " ; -#endif - } - - if(item->flags & RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED) - { - RS_STACK_MUTEX(mFLSMtx) ; -#ifdef DEBUG_P3FILELISTS - std::cerr << " removing directory with index " << entry_index << " because it does not exist." << std::endl; -#endif - mRemoteDirectories[fi]->removeDirectory(entry_index); - - mRemoteDirectories[fi]->print(); - } - else if(item->flags & RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE) - { - RS_STACK_MUTEX(mFLSMtx) ; -#ifdef DEBUG_P3FILELISTS - std::cerr << " Directory is up to date. Setting local TS." << std::endl; -#endif - - mRemoteDirectories[fi]->setDirectoryUpdateTime(entry_index,now) ; - } - else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Item contains directory data. Deserialising/Updating." << std::endl; -#endif - RS_STACK_MUTEX(mFLSMtx) ; - - if(mLastDataRecvTS + 1 < now) // avoid notifying the GUI too often as it kills performance. - { - RsServer::notify()->notifyListPreChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); // notify the GUI if the hierarchy has changed - mLastDataRecvTS = now; - } -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "Performing update of directory index " << std::hex << entry_index << std::dec << " from friend " << item->PeerId() << std::endl; -#endif - - if(mRemoteDirectories[fi]->deserialiseUpdateDirEntry(entry_index,item->directory_content_data)) - mRemoteDirectories[fi]->lastSweepTime() = now - DELAY_BETWEEN_REMOTE_DIRECTORIES_SWEEP + 10 ; // force re-sweep in 10 secs, so as to fasten updated - else - P3FILELISTS_ERROR() << "(EE) Cannot deserialise dir entry. ERROR. "<< std::endl; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " new content after update: " << std::endl; - mRemoteDirectories[fi]->print(); -#endif - } - - // remove the original request from pending list in the end. doing this here avoids that a new request is added while the previous response is not treated. - - { - RS_STACK_MUTEX(mFLSMtx) ; - - std::map::iterator it = mPendingSyncRequests.find(item->request_id) ; - - if(it == mPendingSyncRequests.end()) - { - P3FILELISTS_ERROR() << " request " << std::hex << item->request_id << std::dec << " cannot be found. ERROR!" << std::endl; - return ; - } - mPendingSyncRequests.erase(it) ; - } - - -} - -void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *rds,DirectoryStorage::EntryIndex e,int depth) -{ - rstime_t now = time(NULL) ; - - //std::string indent(2*depth,' ') ; - - // if not up to date, request update, and return (content is not certified, so no need to recurs yet). - // if up to date, return, because TS is about the last modif TS below, so no need to recurs either. - - // get the info for this entry - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << "currently at entry index " << e << std::endl; -#endif - - rstime_t local_update_TS; - - if(!rds->getDirectoryUpdateTime(e,local_update_TS)) - { - P3FILELISTS_ERROR() << " (EE) lockec_recursSweepRemoteDirectory(): cannot get update TS for directory with index " << e << ". This is a consistency bug." << std::endl; - return; - } - - // compare TS - - if((e == 0 && now > local_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) || local_update_TS == 0) // we need to compare local times only. We cannot compare local (now) with remote time. - if(locked_generateAndSendSyncRequest(rds,e)) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Asking for sync of directory " << e << " to peer " << rds->peerId() << " because it's " << (now - local_update_TS) << " secs old since last check." << std::endl; -#endif - } - - for(DirectoryStorage::DirIterator it(rds,e);it;++it) - locked_recursSweepRemoteDirectory(rds,*it,depth+1); -} - -p3FileDatabase::DirSyncRequestId p3FileDatabase::makeDirSyncReqId(const RsPeerId& peer_id,const RsFileHash& hash) -{ - static uint64_t random_bias = RSRandom::random_u64(); - - uint8_t mem[RsPeerId::SIZE_IN_BYTES + RsFileHash::SIZE_IN_BYTES]; - memcpy(mem,peer_id.toByteArray(),RsPeerId::SIZE_IN_BYTES) ; - memcpy(&mem[RsPeerId::SIZE_IN_BYTES],hash.toByteArray(),RsFileHash::SIZE_IN_BYTES) ; - - RsFileHash tmp = RsDirUtil::sha1sum(mem,RsPeerId::SIZE_IN_BYTES + RsFileHash::SIZE_IN_BYTES) ; - - // This is kind of arbitrary. The important thing is that the same ID needs to be generated every time for a given (peer_id,entry index) pair, in a way - // that cannot be brute-forced or reverse-engineered, which explains the random bias and the usage of the hash, that is itself random. - - uint64_t tmp2 ; - memcpy(&tmp2,tmp.toByteArray(),sizeof(uint64_t)); - - uint64_t r = random_bias ^ tmp2; - -#ifdef DEBUG_P3FILELISTS - std::cerr << "Creating ID " << std::hex << r << std::dec << " from peer id " << peer_id << " and hash " << hash << std::endl; -#endif - - return r ; -} - -bool p3FileDatabase::locked_generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e) -{ - RsFileHash entry_hash ; - rstime_t now = time(NULL) ; - - rstime_t max_known_recurs_modf_time ; - - if(!rds->getDirectoryRecursModTime(e,max_known_recurs_modf_time)) - { - P3FILELISTS_ERROR() << " (EE) cannot find recurs mod time for entry index " << e << ". This is very unexpected." << std::endl; - return false; - } - if(!rds->getDirHashFromIndex(e,entry_hash) ) - { - P3FILELISTS_ERROR() << " (EE) cannot find hash for entry index " << e << ". This is very unexpected." << std::endl; - return false; - } - - // check if a request already exists and is not too old either: no need to re-ask. - - DirSyncRequestId sync_req_id = makeDirSyncReqId(rds->peerId(),entry_hash) ; - - std::map::iterator it = mPendingSyncRequests.find(sync_req_id) ; - - if(it != mPendingSyncRequests.end()) - { -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Not asking for sync of directory " << e << " to friend " << rds->peerId() << " because a recent pending request still exists." << std::endl; -#endif - return false ; - } - - RsFileListsSyncRequestItem *item = new RsFileListsSyncRequestItem ; - - item->entry_hash = entry_hash ; - item->flags = RsFileListsItem::FLAGS_SYNC_REQUEST ; - item->request_id = sync_req_id ; - item->last_known_recurs_modf_TS = max_known_recurs_modf_time ; - item->PeerId(rds->peerId()) ; - - DirSyncRequestData data ; - - data.request_TS = now ; - data.peer_id = item->PeerId(); - data.flags = item->flags; - -#ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " Pushing req " << std::hex << sync_req_id << std::dec << " in pending list with peer id " << data.peer_id << std::endl; -#endif - - mPendingSyncRequests[sync_req_id] = data ; - - sendItem(item) ; // at end! Because item is destroyed by the process. - - return true; -} - - -//=========================================================================================================================// -// Unwanted content filtering system // -//=========================================================================================================================// - -bool p3FileDatabase::banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) -{ -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " setting file \"" << filename << "\" size=" << file_size << " hash=" << real_file_hash << " as banned." << std::endl; -#endif - { - RS_STACK_MUTEX(mFLSMtx) ; - BannedFileEntry& entry(mPrimaryBanList[real_file_hash]) ; // primary list (user controlled) of files banned from FT search and forwarding. map - - if(entry.mBanTimeStamp == 0) - { - entry.mFilename = filename ; - entry.mSize = file_size ; - entry.mBanTimeStamp = time(NULL); - - RsFileHash hash_of_hash ; - ftServer::encryptHash(real_file_hash,hash_of_hash) ; - - mBannedFileList.insert(real_file_hash) ; - mBannedFileList.insert(hash_of_hash) ; - - mLastPrimaryBanListChangeTimeStamp = time(NULL); - mBannedFileListNeedsUpdate = true ; - } - } - - IndicateConfigChanged(); - return true; -} -bool p3FileDatabase::unbanFile(const RsFileHash& real_file_hash) -{ -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " unbanning file with hash " << real_file_hash << std::endl; -#endif - { - RS_STACK_MUTEX(mFLSMtx) ; - mPrimaryBanList.erase(real_file_hash) ; - mLastPrimaryBanListChangeTimeStamp = time(NULL); - mBannedFileListNeedsUpdate = true ; - } - - IndicateConfigChanged(); - return true; -} - -bool p3FileDatabase::isFileBanned(const RsFileHash& hash) -{ - RS_STACK_MUTEX(mFLSMtx) ; - - if(mBannedFileList.empty()) // quick exit - return false ; - - RsFileHash hash_of_hash ; - ftServer::encryptHash(hash,hash_of_hash) ; - - bool res = mBannedFileList.find(hash) != mBannedFileList.end() || mBannedFileList.find(hash_of_hash) != mBannedFileList.end() ; - -#ifdef DEBUG_CONTENT_FILTERING - if(res) - P3FILELISTS_DEBUG() << " is file banned(" << hash << "): " << (res?"YES":"NO") << std::endl; -#endif - return res ; -} - -bool p3FileDatabase::getPrimaryBannedFilesList(std::map& banned_files) -{ - RS_STACK_MUTEX(mFLSMtx) ; - banned_files = mPrimaryBanList; - - return true ; -} - -bool p3FileDatabase::trustFriendNodesForBannedFiles() const -{ - RS_STACK_MUTEX(mFLSMtx) ; - return mTrustFriendNodesForBannedFiles; -} - -void p3FileDatabase::setTrustFriendNodesForBannedFiles(bool b) -{ - if(b != mTrustFriendNodesForBannedFiles) - { - IndicateConfigChanged(); - mBannedFileListNeedsUpdate = true; - } - - RS_STACK_MUTEX(mFLSMtx) ; - mTrustFriendNodesForBannedFiles = b; -} - -void p3FileDatabase::checkSendBannedFilesInfo() -{ - RS_STACK_MUTEX(mFLSMtx) ; - - // 1 - compare records to list of online friends, send own info of not already - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Checking banned files information: " << std::endl; -#endif - - rstime_t now = time(NULL); - std::list online_friends ; - rsPeers->getOnlineList(online_friends); - - std::set peers ; - for(auto it(online_friends.begin());it!=online_friends.end();++it) // convert to std::set for efficient search - peers.insert(*it) ; - - for(auto it(mPeerBannedFiles.begin());it!=mPeerBannedFiles.end();) - { - if(peers.find(it->first) == peers.end()) // friend not online, remove his record - { - it = mPeerBannedFiles.erase(it) ; -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Peer " << it->first << " is offline: removign record." << std::endl; -#endif - continue; - } - - if(it->second.mLastSent < mLastPrimaryBanListChangeTimeStamp) // has ban info already been sent? If not do it. - { -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Peer " << it->first << " is online and hasn't been sent since last change: sending..." << std::endl; -#endif - locked_sendBanInfo(it->first); - it->second.mLastSent = now; - } - - peers.erase(it->first); // friend has been handled -> remove from list - ++it; - } - - // 2 - add a new record for friends not already in the record map - - for(auto it(peers.begin());it!=peers.end();++it) - { - locked_sendBanInfo(*it); - mPeerBannedFiles[*it].mLastSent = now; -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Peer " << *it << " is online and hasn't been sent info at all: sending..." << std::endl; -#endif - } - - // 3 - update list of banned hashes if it has changed somehow - - if(mBannedFileListNeedsUpdate) - { - mBannedFileList.clear(); - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Creating local banned file list: " << std::endl; -#endif - // Add all H(H(f)) from friends - - if(mTrustFriendNodesForBannedFiles) - for(auto it(mPeerBannedFiles.begin());it!=mPeerBannedFiles.end();++it) - for(auto it2(it->second.mBannedHashOfHash.begin());it2!=it->second.mBannedHashOfHash.end();++it2) - { - mBannedFileList.insert(*it2); - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " from " << it->first << ": H(H(f)) = " << *it2 << std::endl; -#endif - } - - // Add H(f) and H(H(f)) from our primary list - - for(auto it(mPrimaryBanList.begin());it!=mPrimaryBanList.end();++it) - { - mBannedFileList.insert(it->first) ; - - RsFileHash hash_of_hash ; - ftServer::encryptHash(it->first,hash_of_hash) ; - - mBannedFileList.insert(hash_of_hash) ; - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " primary: H(f) = " << it->first << ": H(H(f)) = " << hash_of_hash << std::endl; -#endif - } - - mBannedFileListNeedsUpdate = false ; - } - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " Final list of locally banned hashes contains: " << mBannedFileList.size() << " elements." << std::endl; -#endif -} - -void p3FileDatabase::locked_sendBanInfo(const RsPeerId& peer) -{ - RsFileListsBannedHashesItem *item = new RsFileListsBannedHashesItem ; - uint32_t session_id = RSRandom::random_u32(); - - item->session_id = session_id ; - item->PeerId(peer); - - for(auto it(mPrimaryBanList.begin());it!=mPrimaryBanList.end();++it) - { - RsFileHash hash_of_hash ; - - ftServer::encryptHash(it->first,hash_of_hash) ; - - if(!item) - { - item = new RsFileListsBannedHashesItem ; - - item->PeerId(peer); - item->session_id = session_id ; - } - - item->encrypted_hashes.insert(hash_of_hash) ; - - if(item->encrypted_hashes.size() >= 200) - { - sendItem(item); - item = NULL ; - } - } - - if(item) - sendItem(item); -} - -void p3FileDatabase::handleBannedFilesInfo(RsFileListsBannedHashesItem *item) -{ - RS_STACK_MUTEX(mFLSMtx) ; - -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " received banned files info from peer " << item->PeerId() << ", session id = " << std::hex << item->session_id << std::dec << ": " << item->encrypted_hashes.size() << " files:" << std::endl; -#endif - // 1 - localize the friend in the banned file map - - PeerBannedFilesEntry& pbfe(mPeerBannedFiles[item->PeerId()]) ; - - if(pbfe.mSessionId != item->session_id) - pbfe.mBannedHashOfHash.clear(); - - pbfe.mSessionId = item->session_id ; - - // 2 - replace/update the list, depending on the session_id - - for(auto it(item->encrypted_hashes.begin());it!=item->encrypted_hashes.end();++it) - { - pbfe.mBannedHashOfHash.insert(*it); -#ifdef DEBUG_CONTENT_FILTERING - P3FILELISTS_DEBUG() << " added H(H(f)) = " << *it << std::endl; -#endif - } - - // 3 - tell the updater that the banned file list has changed - - mBannedFileListNeedsUpdate = true ; -} - diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h deleted file mode 100644 index f9a97e47b..000000000 --- a/libretroshare/src/file_sharing/p3filelists.h +++ /dev/null @@ -1,301 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: p3filelists.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -// -// This class is responsible for -// - maintaining a list of shared file hierarchies for each known friends -// - talking to the GUI -// - providing handles for the directory tree listing GUI -// - providing search handles for FT -// - keeping these lists up to date -// - sending our own file list to friends depending on the defined access rights -// - serving file search requests from other services such as file transfer -// -// p3FileList does the following micro-tasks: -// - tick the watchers -// - get incoming info from the service layer, which can be: -// - directory content request => the directory content is shared to the friend -// - directory content => the directory watcher is notified -// - keep two queues of update requests: -// - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing. -// - slow queue that is handled slowly. Used in background update of shared directories. -// -// The list of local shared files is maintained by FileListWatcher. -// -// p3FileLists is organised as follows: -// -// p3FileDatabase -// | -// +---- HashStorage // Handles known hashes. Serves as a reference when new files are hashed. -// | -// +---- RemoteDirectoryStorage // Stores the list of shared files at friends -// | | -// | +---- InternalFileHierarchyStorage -// | -// +---- LocalDirectoryStorage // Stores the list of locally shared files -// | | -// | +---- InternalFileHierarchyStorage -// | -// +---- LocalDirectoryUpdater // Keeps the local lists up to date, by regularly crawling directories -// -#pragma once - -#include "ft/ftsearch.h" -#include "ft/ftextralist.h" -#include "retroshare/rsfiles.h" -#include "services/p3service.h" -#include "util/rstime.h" -#include "file_sharing/hash_cache.h" -#include "file_sharing/directory_storage.h" - -#include "pqi/p3cfgmgr.h" -#include "pqi/p3linkmgr.h" - -class RemoteDirectoryUpdater ; -class LocalDirectoryUpdater ; - -class RemoteDirectoryStorage ; -class LocalDirectoryStorage ; - -class RsFileListsSyncRequestItem ; -class RsFileListsSyncResponseItem ; -class RsFileListsBannedHashesItem ; - -class HashStorage ; - -struct PeerBannedFilesEntry -{ - std::set mBannedHashOfHash; - uint32_t mSessionId ; // used for when a friend sends multiple packets in separate items. - rstime_t mLastSent; -}; - -class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, public RsSharedFileService -{ - public: - typedef DirectoryStorage::EntryIndex EntryIndex; // this should probably be defined elsewhere - - virtual RsServiceInfo getServiceInfo(); - - struct RsFileListSyncRequest - { - RsPeerId peerId ; - EntryIndex index ; - // [...] more to add here - }; - - explicit p3FileDatabase(p3ServiceControl *mpeers); - ~p3FileDatabase(); - - void setExtraList(ftExtraList *f) { mExtraFiles = f ; } - /*! - * \brief forceSyncWithPeers - * - * Forces the synchronisation of the database with connected peers. This is triggered when e.g. a new group of friend is created, or when - * a friend was added/removed from a group. - */ - void forceSyncWithPeers() { NOT_IMPLEMENTED() ; } - - // derived from p3Service - // - virtual int tick() ; - - // ftSearch - virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; - virtual int SearchKeywords(const std::list& keywords, std::list& results,FileSearchFlags flags,const RsPeerId& peer_id) ; - virtual int SearchBoolExp(RsRegularExpression::Expression *exp, std::list& results,FileSearchFlags flags,const RsPeerId& peer_id) const ; - - // Extra file list - virtual bool removeExtraFile(const RsFileHash& hash); - - // Interface for browsing dir hierarchy - // - - void stopThreads() ; - void startThreads() ; - - bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) const; - - // void * here is the type expected by the abstract model index from Qt. It gets turned into a DirectoryStorage::EntryIndex internally. - - void requestDirUpdate(void *ref) ; // triggers an update. Used when browsing. - int RequestDirDetails(void *, DirDetails&, FileSearchFlags) const ; - uint32_t getType(void *, FileSearchFlags flags) const ; - - // proxy method used by the web UI. Dont't delete! - int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const; - - // set/update shared directories - - void setSharedDirectories(const std::list& dirs); - void getSharedDirectories(std::list& dirs); - void updateShareFlags(const SharedDirInfo& info) ; - bool convertSharedFilePath(const std::string& path,std::string& fullpath); - - void setIgnoreLists(const std::list& ignored_prefixes,const std::list& ignored_suffixes, uint32_t ignore_flags) ; - bool getIgnoreLists(std::list& ignored_prefixes,std::list& ignored_suffixes, uint32_t& ignore_flags) ; - - void setIgnoreDuplicates(bool i) ; - bool ignoreDuplicates() const ; - - void setMaxShareDepth(int i) ; - int maxShareDepth() const ; - - bool banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) ; - bool unbanFile(const RsFileHash& real_file_hash); - bool isFileBanned(const RsFileHash& hash) ; - bool getPrimaryBannedFilesList(std::map& banned_files) ; - bool trustFriendNodesForBannedFiles() const ; - void setTrustFriendNodesForBannedFiles(bool b) ; - - // computes/gathers statistics about shared directories - - int getSharedDirStatistics(const RsPeerId& pid,SharedDirStats& stats); - - // interface for hash caching - - void setWatchPeriod(uint32_t seconds); - uint32_t watchPeriod() ; - void setWatchEnabled(bool b) ; - bool watchEnabled() ; - - bool followSymLinks() const; - void setFollowSymLinks(bool b) ; - - // interfact for directory parsing - - void forceDirectoryCheck(bool add_safe_delay); // Force re-sweep the directories and see what's changed - bool inDirectoryCheck(); - void togglePauseHashingProcess(); - bool hashingProcessPaused(); - - protected: - void getExtraFilesDirDetails(void *ref,DirectoryStorage::EntryIndex e,DirDetails& d) const; - - int filterResults(const std::list& firesults,std::list& results,FileSearchFlags flags,const RsPeerId& peer_id) const; - std::string makeRemoteFileName(const RsPeerId& pid) const; - - // Derived from p3Config - // - virtual bool loadList(std::list& items); - virtual bool saveList(bool &cleanup, std::list&); - virtual RsSerialiser *setupSerialiser() ; - - void cleanup(); - void tickRecv(); - void tickSend(); - - void checkSendBannedFilesInfo(); - - private: - p3ServiceControl *mServCtrl ; - RsPeerId mOwnId ; - - typedef uint64_t DirSyncRequestId ; - - static DirSyncRequestId makeDirSyncReqId(const RsPeerId& peer_id, const RsFileHash &hash) ; - - // utility functions to send items with some maximum size. - - void splitAndSendItem(RsFileListsSyncResponseItem *ritem); - RsFileListsSyncResponseItem *recvAndRebuildItem(RsFileListsSyncResponseItem *ritem); - - /*! - * \brief generateAndSendSyncRequest - * \param rds Remote directory storage for the request - * \param e Entry index to update - * \return true if the request is correctly sent. - */ - bool locked_generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e); - - // File sync request queues. The fast one is used for online browsing when friends are connected. - // The slow one is used for background update of file lists. - // - std::map mFastRequestQueue ; - std::map mSlowRequestQueue ; - - // Directory storage hierarchies - // - // The remote one is the reference for the PeerId index below: - // RemoteDirectories[ getFriendIndex(pid) - 1] = RemoteDirectoryStorage(pid) - - std::vector mRemoteDirectories ; - LocalDirectoryStorage *mLocalSharedDirs ; - LocalDirectoryUpdater *mLocalDirWatcher ; - ftExtraList *mExtraFiles; - - // utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc - - template static bool convertEntryIndexToPointer(const EntryIndex &e, uint32_t friend_index, void *& p); - template static bool convertPointerToEntryIndex(const void *p, EntryIndex& e, uint32_t& friend_index) ; - - uint32_t locked_getFriendIndex(const RsPeerId& pid); - - void handleDirSyncRequest (RsFileListsSyncRequestItem *) ; - void handleDirSyncResponse (RsFileListsSyncResponseItem *&) ; - - std::map mFriendIndexMap ; - std::vector mFriendIndexTab; - - // Directory synchronization - // - struct DirSyncRequestData - { - RsPeerId peer_id ; - rstime_t request_TS ; - uint32_t flags ; - }; - - rstime_t mLastRemoteDirSweepTS ; // TS for friend list update - std::map mPendingSyncRequests ; // pending requests, waiting for an answer - std::map mPartialResponseItems; - - void locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *rds, DirectoryStorage::EntryIndex e, int depth); - - // We use a shared file cache as well, to avoid re-hashing files with known modification TS and equal name. - // - HashStorage *mHashCache ; - - // Local flags and mutexes - - mutable RsMutex mFLSMtx ; - uint32_t mUpdateFlags ; - std::string mFileSharingDir ; - rstime_t mLastCleanupTime; - rstime_t mLastDataRecvTS ; - - // File filtering. Not explicitly related to shared files, but has its place here - // - - std::map mPrimaryBanList ; // primary list (user controlled) of files banned from FT search and forwarding. map - std::map mPeerBannedFiles ; // records of which files other peers ban, stored as H(H(f)) - std::set mBannedFileList ; // list of banned hashes. This include original hashs and H(H(f)) when coming from friends. - mutable std::vector mExtraFilesCache; // cache for extra files, to avoid requesting them too often. - mutable rstime_t mLastExtraFilesCacheUpdate ; - bool mTrustFriendNodesForBannedFiles ; - bool mBannedFileListNeedsUpdate; - rstime_t mLastPrimaryBanListChangeTimeStamp; - - void locked_sendBanInfo(const RsPeerId& pid); - void handleBannedFilesInfo(RsFileListsBannedHashesItem *item); -}; - diff --git a/libretroshare/src/file_sharing/rsfilelistitems.cc b/libretroshare/src/file_sharing/rsfilelistitems.cc deleted file mode 100644 index 4ac90af10..000000000 --- a/libretroshare/src/file_sharing/rsfilelistitems.cc +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: rsfilelistsitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#include "serialiser/rsbaseserial.h" - -#include "serialiser/rstypeserializer.h" - -#include "file_sharing/rsfilelistitems.h" - -void RsFileListsSyncRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,entry_hash,"entry_hash") ; - RsTypeSerializer::serial_process(j,ctx,flags ,"flags") ; - RsTypeSerializer::serial_process(j,ctx,last_known_recurs_modf_TS,"last_known_recurs_modf_TS") ; - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; -} -void RsFileListsSyncResponseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,entry_hash, "entry_hash") ; - RsTypeSerializer::serial_process (j,ctx,checksum, "checksum") ; - RsTypeSerializer::serial_process (j,ctx,flags, "flags") ; - RsTypeSerializer::serial_process (j,ctx,last_known_recurs_modf_TS,"last_known_recurs_modf_TS") ; - RsTypeSerializer::serial_process (j,ctx,request_id, "request_id") ; - RsTypeSerializer::serial_process(j,ctx,directory_content_data, "directory_content_data") ; -} -void RsFileListsBannedHashesItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,session_id ,"session_id") ; - RsTypeSerializer::serial_process(j,ctx,encrypted_hashes,"encrypted_hashes") ; -} -void RsFileListsBannedHashesConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,primary_banned_files_list,"primary_banned_files_list") ; -} - -RsItem *RsFileListsSerialiser::create_item(uint16_t service,uint8_t type) const -{ - if(service != RS_SERVICE_TYPE_FILE_DATABASE) - return NULL ; - - switch(type) - { - case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return new RsFileListsSyncRequestItem(); - case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return new RsFileListsSyncResponseItem(); - case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM: return new RsFileListsBannedHashesItem(); - case RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM: return new RsFileListsBannedHashesConfigItem(); - default: - return NULL ; - } -} -void RsFileListsSyncResponseItem::clear() -{ - directory_content_data.TlvClear(); -} diff --git a/libretroshare/src/file_sharing/rsfilelistitems.h b/libretroshare/src/file_sharing/rsfilelistitems.h deleted file mode 100644 index a8c84e18b..000000000 --- a/libretroshare/src/file_sharing/rsfilelistitems.h +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * libretroshare/src/file_sharing: rsfilelistsitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Mr.Alice * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ -#pragma once - -#include -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvkeys.h" -#include "gxs/rsgxsdata.h" - -#include "serialiser/rsserializer.h" -#include "retroshare/rsfiles.h" - -const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM = 0x01; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM = 0x04; -const uint8_t RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM = 0x05; - -/*! - * Base class for filelist sync items - */ -class RsFileListsItem : public RsItem -{ -public: - explicit RsFileListsItem(uint8_t subtype) - : RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_FILE_DATABASE, subtype) - { - setPriorityLevel(QOS_PRIORITY_RS_SLOW_SYNC_REQUEST); // this is the default. Someitems may be faster, on demand. - return; - } - virtual ~RsFileListsItem(){} - - virtual void clear() = 0; - - static const uint32_t FLAGS_SYNC_REQUEST = 0x0001 ; - static const uint32_t FLAGS_SYNC_RESPONSE = 0x0002 ; - static const uint32_t FLAGS_SYNC_DIR_CONTENT = 0x0004 ; - static const uint32_t FLAGS_ENTRY_UP_TO_DATE = 0x0008 ; - static const uint32_t FLAGS_ENTRY_WAS_REMOVED = 0x0010 ; - static const uint32_t FLAGS_SYNC_PARTIAL = 0x0020 ; - static const uint32_t FLAGS_SYNC_PARTIAL_END = 0x0040 ; -}; - -/*! - * Use to request synchronization on a specific directory. Also used to respond that the directory is up to date. - */ -class RsFileListsSyncRequestItem : public RsFileListsItem -{ -public: - - RsFileListsSyncRequestItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM), flags(0), last_known_recurs_modf_TS(0), request_id(0) {} - - virtual void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsFileHash entry_hash ; // hash of the directory to sync - uint32_t flags; // used to say that it's a request or a response, say that the directory has been removed, ask for further update, etc. - uint32_t last_known_recurs_modf_TS; // time of last modification, computed over all files+directories below. - uint64_t request_id; // use to determine if changes that have occured since last hash -}; - -class RsFileListsSyncResponseItem : public RsFileListsItem -{ -public: - - RsFileListsSyncResponseItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM), flags(0), last_known_recurs_modf_TS(0), request_id(0) {} - - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsFileHash entry_hash ; // hash of the directory to sync - RsFileHash checksum ; // checksum of the bindary data, for checking - uint32_t flags; // is it a partial/final item (used for large items only) - uint32_t last_known_recurs_modf_TS; // time of last modification, computed over all files+directories below. - uint64_t request_id; // use to determine if changes that have occured since last hash - - RsTlvBinaryData directory_content_data ; // encoded binary data. This allows to vary the encoding format, in a way that is transparent to the serialiser. -}; - -class RsFileListsBannedHashesItem: public RsFileListsItem -{ -public: - RsFileListsBannedHashesItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_ITEM){} - - virtual void clear() { encrypted_hashes.clear(); } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t session_id ; // used to allow to send in multiple parts. - std::set encrypted_hashes ;// hash of hash for each banned file. -}; - -class RsFileListsBannedHashesConfigItem: public RsFileListsItem -{ -public: - RsFileListsBannedHashesConfigItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_BANNED_HASHES_CONFIG_ITEM){} - - virtual void clear() { primary_banned_files_list.clear(); } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - std::map primary_banned_files_list ; -}; - -class RsFileListsSerialiser : public RsServiceSerializer -{ -public: - - RsFileListsSerialiser() : RsServiceSerializer(RS_SERVICE_TYPE_FILE_DATABASE) {} - - virtual ~RsFileListsSerialiser() {} - - virtual RsItem *create_item(uint16_t service,uint8_t type) const ; -}; - - diff --git a/libretroshare/src/ft/ftchunkmap.cc b/libretroshare/src/ft/ftchunkmap.cc deleted file mode 100644 index 8b0c60007..000000000 --- a/libretroshare/src/ft/ftchunkmap.cc +++ /dev/null @@ -1,708 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftchunkmap.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -/******** - * #define DEBUG_FTCHUNK 1 - *********/ - -#ifdef DEBUG_FTCHUNK -#include -#endif -#include -#include -#include "retroshare/rspeers.h" -#include "ftchunkmap.h" -#include "util/rstime.h" - -static const uint32_t SOURCE_CHUNK_MAP_UPDATE_PERIOD = 60 ; //! TTL for chunkmap info -static const uint32_t INACTIVE_CHUNK_TIME_LAPSE = 3600 ; //! TTL for an inactive chunk -static const uint32_t FT_CHUNKMAP_MAX_CHUNK_JUMP = 50 ; //! Maximum chunk jump in progressive DL mode -static const uint32_t FT_CHUNKMAP_MAX_SLICE_REASK_DELAY = 10 ; //! Maximum time to re-ask a slice to another peer at end of transfer - -std::ostream& operator<<(std::ostream& o,const ftChunk& c) -{ - return o << "\tChunk [" << c.offset << "] size: " << c.size << " ChunkId: " << c.id << " Age: " << time(NULL) - c.ts << ", owner: " << c.peer_id ; -} - -// Chunk: very bold implementation for now. We should compress the bits to have -// 32 of them per uint32_t value, of course! -// -Chunk::Chunk(uint64_t start,uint32_t size) - : _start(start),_offset(start),_end( (uint64_t)size + start ) -{ -} - -void Chunk::getSlice(uint32_t size_hint,ftChunk& chunk) -{ - // Take the current offset - chunk.offset = _offset ; - chunk.size = std::min(size_hint,(uint32_t)(_end-_offset)) ; - chunk.id = _offset ; - chunk.ts = time(NULL) ; - - // push the slice marker into currently handled slices. - _offset += chunk.size ; -} - -ChunkMap::ChunkMap(uint64_t s,bool availability) - : _file_size(s), - _chunk_size(CHUNKMAP_FIXED_CHUNK_SIZE), // 1MB chunks - _assume_availability(availability) -{ - uint64_t n = s/(uint64_t)_chunk_size ; - if(s% (uint64_t)_chunk_size != 0) - ++n ; - - _map.resize(n,FileChunksInfo::CHUNK_OUTSTANDING) ; - _strategy = FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE ; - _total_downloaded = 0 ; - _file_is_complete = false ; -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::ChunkMap: starting new chunkmap:" << std::endl ; - std::cerr << " File size: " << s << std::endl ; - std::cerr << " Strategy: " << _strategy << std::endl ; - std::cerr << " ChunkSize: " << _chunk_size << std::endl ; - std::cerr << " Number of Chunks: " << n << std::endl ; - std::cerr << " Data: " ; - for(uint32_t i=0;i<_map.size();++i) - std::cerr << _map[i] ; - std::cerr << std::endl ; -#endif -} - -void ChunkMap::setAvailabilityMap(const CompressedChunkMap& map) -{ - // do some sanity check - // - - 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 ; - } - - // copy the map - // - _file_is_complete = true ; - _total_downloaded = 0 ; - - for(uint32_t i=0;i<_map.size();++i) - if(map[i] > 0) - { - _map[i] = FileChunksInfo::CHUNK_DONE ; - _total_downloaded += sizeOfChunk(i) ; - } - else - { - _map[i] = FileChunksInfo::CHUNK_OUTSTANDING ; - _file_is_complete = false ; - } -} - -void ChunkMap::dataReceived(const ftChunk::OffsetInFile& cid) -{ - // 1 - find which chunk contains the received data. - // - - // trick: cid is the chunk offset. So we use it to get the chunk number. - int n = (uint64_t)cid/_chunk_size ; - - std::map::iterator itc(_slices_to_download.find(n)) ; - - if(itc == _slices_to_download.end()) - { - std::cerr << "!!! ChunkMap::dataReceived: error: ChunkId " << cid << " corresponds to chunk number " << n << ", which is not being downloaded!" << std::endl ; -#ifdef DEBUG_FTCHUNK - assert(false) ; -#endif - return ; - } - - std::map::iterator it(itc->second._slices.find(cid)) ; - - if(it == itc->second._slices.end()) - { - std::cerr << "!!! ChunkMap::dataReceived: chunk " << cid << " is not found in slice lst of chunk number " << n << std::endl ; -#ifdef DEBUG_FTCHUNK - assert(false) ; -#endif - return ; - } - - _total_downloaded += it->second.size ; - itc->second._remains -= it->second.size ; - itc->second._slices.erase(it) ; - itc->second._last_data_received = time(NULL) ; // update time stamp - -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::dataReceived: received data chunk " << cid << " for chunk number " << n << ", local remains=" << itc->second._remains << ", total downloaded=" << _total_downloaded << ", remains=" << _file_size - _total_downloaded << std::endl ; -#endif - if(itc->second._remains == 0) // the chunk was completely downloaded - { -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::dataReceived: Chunk is complete. Removing it." << std::endl ; -#endif - - _map[n] = FileChunksInfo::CHUNK_CHECKING ; - - if(n > 0 || _file_size > CHUNKMAP_FIXED_CHUNK_SIZE) // dont' put <1MB files into checking mode. This is useless. - _chunks_checking_queue.push_back(n) ; - else - _map[n] = FileChunksInfo::CHUNK_DONE ; - - _slices_to_download.erase(itc) ; - - updateTotalDownloaded() ; - } -} - -void ChunkMap::updateTotalDownloaded() -{ - _total_downloaded = 0 ; - _file_is_complete = true ; - - // First, round over chunk map to get the raw info. - // - for(uint32_t i=0;i<_map.size();++i) - switch(_map[i]) - { - case FileChunksInfo::CHUNK_CHECKING: _file_is_complete = false ; - /* fallthrough */ - case FileChunksInfo::CHUNK_DONE: _total_downloaded += sizeOfChunk(i) ; - break ; - default: - _file_is_complete = false ; - } - - // Then go through active chunks. - // - for(std::map::const_iterator itc(_slices_to_download.begin());itc!=_slices_to_download.end();++itc) - { - if(_map[itc->first] == FileChunksInfo::CHUNK_CHECKING) - _total_downloaded -= sizeOfChunk(itc->first) ; - - _total_downloaded += sizeOfChunk(itc->first) - itc->second._remains ; - - if(_file_is_complete) - std::cerr << "ChunkMap::updateTotalDownloaded(): ERROR: file still has pending slices but all chunks are marked as DONE !!" << std::endl; - } -} - -void ChunkMap::getChunksToCheck(std::vector& chunks_crc_to_ask) -{ - chunks_crc_to_ask.clear() ; - - for(uint32_t i=0;i<_chunks_checking_queue.size();) - { - chunks_crc_to_ask.push_back(_chunks_checking_queue[i]) ; - - // remove that chunk from the queue - - _chunks_checking_queue[i] = _chunks_checking_queue.back() ; - _chunks_checking_queue.pop_back() ; - } -} - -void ChunkMap::setChunkCheckingResult(uint32_t chunk_number,bool check_succeeded) -{ - // Find the chunk is the waiting queue. Remove it, and mark it as done. - // - if(_map[chunk_number] != FileChunksInfo::CHUNK_CHECKING) - { - std::cerr << "(EE) ChunkMap: asked to set checking result of chunk " << chunk_number<< " that is not marked as being checked!!" << std::endl; - return ; - } - - if(check_succeeded) - { - _map[chunk_number] = FileChunksInfo::CHUNK_DONE ; - - // We also check whether the file is complete or not. - - _file_is_complete = true ; - - for(uint32_t i=0;i<_map.size();++i) - if(_map[i] != FileChunksInfo::CHUNK_DONE) - { - _file_is_complete = false ; - break ; - } - } - else - { - _total_downloaded -= sizeOfChunk(chunk_number) ; // restore completion. - _map[chunk_number] = FileChunksInfo::CHUNK_OUTSTANDING ; - } -} - -bool ChunkMap::reAskPendingChunk( const RsPeerId& peer_id, - uint32_t /*size_hint*/, - uint64_t& offset, uint32_t& size) -{ - // make sure that we're at the end of the file. No need to be too greedy in the middle of it. - - for(uint32_t i=0;i<_map.size();++i) - if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING) - return false ; - - rstime_t now = time(NULL); - - for(std::map::iterator it(_slices_to_download.begin());it!=_slices_to_download.end();++it) - for(std::map::iterator it2(it->second._slices.begin());it2!=it->second._slices.end();++it2) - if(it2->second.request_time + FT_CHUNKMAP_MAX_SLICE_REASK_DELAY < now && it2->second.peers.end()==it2->second.peers.find(peer_id)) - { - offset = it2->first; - size = it2->second.size ; - -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::reAskPendingChunk: re-asking slice (" << offset << ", " << size << ") to peer " << peer_id << std::endl; -#endif - - it2->second.request_time = now ; - it2->second.peers.insert(peer_id) ; - - return true ; - } - - return false ; -} - -// Warning: a chunk may be empty, but still being downloaded, so asking new slices from it -// will produce slices of size 0. This happens at the end of each chunk. -// --> I need to get slices from the next chunk, in such a case. -// --> solution: -// - have too chunks maps: -// 1 indexed by peer id to feed the getChunk method -// - chunks pushed when new chunks are needed -// - chunks removed when empty -// 1 indexed by chunk id to account for chunks being downloaded -// - chunks pushed when new chunks are needed -// - chunks removed when completely downloaded -// -bool ChunkMap::getDataChunk(const RsPeerId& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed) -{ -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::getDataChunk: size_hint = " << size_hint << std::endl ; -#endif - // 1 - find if this peer already has an active chunk. - // - std::map::iterator it = _active_chunks_feed.find(peer_id) ; - std::map::iterator falsafe_it = _active_chunks_feed.end() ; - - if(it == _active_chunks_feed.end()) - { - SourceChunksInfo *sci = getSourceChunksInfo(peer_id) ; - - // 0 - Look into other pending chunks and slice from here. We only consider chunks with size smaller than - // the requested size, - // - for(std::map::iterator pit(_active_chunks_feed.begin());pit!=_active_chunks_feed.end();++pit) - { - uint32_t c = pit->second._start / _chunk_size ; - - if(!(sci->is_full || sci->cmap[c])) // check that the chunk is available for requested peer. - continue ; - - ChunkDownloadInfo& cdi(_slices_to_download[c]) ; - falsafe_it = pit ; // let's keep this one just in case. - - if(cdi._slices.rbegin() != cdi._slices.rend() && cdi._slices.rbegin()->second.size*0.7 <= (float)size_hint) - { - it = pit ; -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::getDataChunk: Sharing slice " << pit->second._start << " of peer " << pit->first << " for peer " << peer_id << std::endl; -#endif - break ; - } -#ifdef DEBUG_FTCHUNK - else - std::cerr << "*** ChunkMap::getDataChunk: Not Sharing slice " << pit->second._start << " of peer " << pit->first << " for peer " << peer_id << ", because current peer is too slow" << std::endl; -#endif - } - - if(it == _active_chunks_feed.end()) // not found. Find a new chunk. - { - // 1 - select an available chunk id for this peer. - // - uint32_t c = getAvailableChunk(peer_id,source_chunk_map_needed) ; - - if(c >= _map.size()) - if(falsafe_it != _active_chunks_feed.end()) // no chunk available. Let's see if we can still take an active--faster--chunk. - { - it = falsafe_it ; -#ifdef DEBUG_FTCHUNK - std::cerr << "*** ChunkMap::getDataChunk: Using falsafe chunk " << it->second._start << " of peer " << it->first << " for peer " << peer_id << std::endl; -#endif - } - else - return false ; // no more availabel chunks, no falsafe case. - else - { - // 2 - add the chunk in the list of active chunks, and mark it as being downloaded - // - uint32_t soc = sizeOfChunk(c) ; - _active_chunks_feed[peer_id] = Chunk( c*(uint64_t)_chunk_size, soc ) ; - _map[c] = FileChunksInfo::CHUNK_ACTIVE ; - _slices_to_download[c]._remains = soc ; // init the list of slices to download - it = _active_chunks_feed.find(peer_id) ; -#ifdef DEBUG_FTCHUNK - std::cout << "*** ChunkMap::getDataChunk: Allocating new chunk " << c << " for peer " << peer_id << std::endl ; -#endif - } - } - } -#ifdef DEBUG_FTCHUNK - else - std::cout << "*** ChunkMap::getDataChunk: Re-using chunk " << it->second._start/_chunk_size << " for peer " << peer_id << std::endl ; -#endif - - // Get the first slice of the chunk, that is at most of length size - // - it->second.getSlice(size_hint,chunk) ; - _slices_to_download[chunk.offset/_chunk_size]._last_data_received = time(NULL) ; - - ChunkDownloadInfo::SliceRequestInfo& r(_slices_to_download[chunk.offset/_chunk_size]._slices[chunk.id]); - - r.size = chunk.size ; - r.request_time = time(NULL); - r.peers.insert(peer_id); - - chunk.peer_id = peer_id ; - -#ifdef DEBUG_FTCHUNK - std::cout << "*** ChunkMap::getDataChunk: returning slice " << chunk << " for peer " << it->first << std::endl ; -#endif - if(it->second.empty()) - _active_chunks_feed.erase(it) ; - - return true ; -} - -void ChunkMap::removeInactiveChunks(std::vector& to_remove) -{ - to_remove.clear() ; - rstime_t now = time(NULL) ; - - for(std::map::iterator it(_slices_to_download.begin());it!=_slices_to_download.end();) - if(now - it->second._last_data_received > (int)INACTIVE_CHUNK_TIME_LAPSE) - { -#ifdef DEBUG_FTCHUNK - std::cerr << "ChunkMap::removeInactiveChunks(): removing inactive chunk " << it->first << ", time lapse=" << now - it->second._last_data_received << std::endl ; -#endif - // First, remove all slices from this chunk - // - std::map::iterator tmp(it) ; - - for(std::map::const_iterator it2(it->second._slices.begin());it2!=it->second._slices.end();++it2) - to_remove.push_back(it2->first) ; - - _map[it->first] = FileChunksInfo::CHUNK_OUTSTANDING ; // reset the chunk - - _total_downloaded -= (sizeOfChunk(it->first) - it->second._remains) ; // restore completion. - - // Also remove the chunk from the chunk feed, to free the associated peer. - // - for(std::map::iterator it3=_active_chunks_feed.begin();it3!=_active_chunks_feed.end();) - if(it3->second._start == _chunk_size*uint64_t(it->first)) - { - std::map::iterator tmp3 = it3 ; - ++it3 ; - _active_chunks_feed.erase(tmp3) ; - } - else - ++it3 ; - - ++it ; - _slices_to_download.erase(tmp) ; - } - else - ++it ; -} - -bool ChunkMap::isChunkAvailable(uint64_t offset, uint32_t chunk_size) const -{ - return hasChunkState(offset, chunk_size, FileChunksInfo::CHUNK_DONE); -} - -bool ChunkMap::isChunkOutstanding(uint64_t offset, uint32_t chunk_size) const -{ - return hasChunkState(offset, chunk_size, FileChunksInfo::CHUNK_OUTSTANDING); -} - -bool ChunkMap::hasChunkState(uint64_t offset, uint32_t chunk_size, FileChunksInfo::ChunkState state) const -{ - uint32_t chunk_number_start = offset/(uint64_t)_chunk_size ; - uint32_t chunk_number_end = (offset+(uint64_t)chunk_size)/(uint64_t)_chunk_size ; - - if((offset+(uint64_t)chunk_size) % (uint64_t)_chunk_size != 0) - ++chunk_number_end ; - - // It's possible that chunk_number_start==chunk_number_end+1, but for this we need to have - // chunk_size=0, and offset%_chunk_size=0, so the response "true" is still valid. - // - for(uint32_t i=chunk_number_start;i::iterator it(_peers_chunks_availability.find(peer_id)) ; - - // Do we have a chunk map for this file source ? - // - if yes, we use it - // - if no, - // - if availability is assumed, let's build a plain chunkmap for it - // - otherwise, refuse the transfer, but still ask for the chunkmap - // - // We first test whether the source has a record of not. If not, we fill a new record. - // For availability sources we fill it plain, otherwise, we fill it blank. - // - if(it == _peers_chunks_availability.end()) - { - SourceChunksInfo& pchunks(_peers_chunks_availability[peer_id]) ; - - // Ok, we don't have the info, so two cases: - // - peer_id is a not a turtle peer, so he is considered having the full file source, so we init with a plain chunkmap - // - otherwise, a source map needs to be obtained, so we init with a blank chunkmap - // - if(_assume_availability) - { - pchunks.cmap._map.resize( CompressedChunkMap::getCompressedSize(_map.size()),~(uint32_t)0 ) ; - pchunks.TS = 0 ; - pchunks.is_full = true ; - } - else - { - pchunks.cmap._map.resize( CompressedChunkMap::getCompressedSize(_map.size()),0 ) ; - pchunks.TS = 0 ; - pchunks.is_full = false ; - } - - it = _peers_chunks_availability.find(peer_id) ; - } - return &(it->second) ; -} - -void ChunkMap::getSourcesList(uint32_t chunk_number,std::vector& sources) -{ - sources.clear() ; - - for(std::map::const_iterator it(_peers_chunks_availability.begin());it!=_peers_chunks_availability.end();++it) - if(it->second.cmap[chunk_number]) - sources.push_back(it->first) ; -} - -uint32_t ChunkMap::getAvailableChunk(const RsPeerId& peer_id,bool& map_is_too_old) -{ - // Quite simple strategy: Check for 1st availabe chunk for this peer starting from the given start location. - // - SourceChunksInfo *peer_chunks = getSourceChunksInfo(peer_id) ; - - // If the info is too old, we ask for a new one. When the map is full, we ask 10 times less, as it's probably not - // useful to get a new map that will also be full, but because we need to be careful not to mislead information, - // we still keep asking. - // - rstime_t now = time(NULL) ; - - if((!peer_chunks->is_full) && ((int)now - (int)peer_chunks->TS > (int)SOURCE_CHUNK_MAP_UPDATE_PERIOD)) - { - map_is_too_old = true ;// We will re-ask but not before some seconds. - peer_chunks->TS = now ; - } - else - map_is_too_old = false ;// the map is not too old - - uint32_t available_chunks = 0 ; - uint32_t available_chunks_before_max_dist = 0 ; - - for(unsigned int i=0;i<_map.size();++i) - if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING) - { - if(peer_chunks->is_full || peer_chunks->cmap[i]) - ++available_chunks ; - } - else - available_chunks_before_max_dist = available_chunks ; - - if(available_chunks > 0) - { - uint32_t chosen_chunk_number ; - - switch(_strategy) - { - case FileChunksInfo::CHUNK_STRATEGY_STREAMING: chosen_chunk_number = 0 ; - break ; - case FileChunksInfo::CHUNK_STRATEGY_RANDOM: chosen_chunk_number = rand() % available_chunks ; - break ; - case FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE: chosen_chunk_number = rand() % std::min(available_chunks, available_chunks_before_max_dist+FT_CHUNKMAP_MAX_CHUNK_JUMP) ; - break ; - default: - chosen_chunk_number = 0 ; - } - uint32_t j=0 ; - - for(uint32_t i=0;i<_map.size();++i) - if(_map[i] == FileChunksInfo::CHUNK_OUTSTANDING && (peer_chunks->is_full || peer_chunks->cmap[i])) - { - if(j == chosen_chunk_number) - { -#ifdef DEBUG_FTCHUNK - std::cerr << "ChunkMap::getAvailableChunk: returning chunk " << i << " for peer " << peer_id << std::endl; -#endif - return i ; - } - else - ++j ; - } - } - -#ifdef DEBUG_FTCHUNK - std::cout << "!!! ChunkMap::getAvailableChunk: No available chunk from peer " << peer_id << ": returning false" << std::endl ; -#endif - return _map.size() ; -} - -void ChunkMap::getChunksInfo(FileChunksInfo& info) const -{ - info.file_size = _file_size ; - info.chunk_size = _chunk_size ; - info.chunks = _map ; - info.strategy = _strategy ; - - info.active_chunks.clear() ; - - for(std::map::const_iterator it(_slices_to_download.begin());it!=_slices_to_download.end();++it) - info.active_chunks.push_back(std::pair(it->first,it->second._remains)) ; - - info.compressed_peer_availability_maps.clear() ; - - for(std::map::const_iterator it(_peers_chunks_availability.begin());it!=_peers_chunks_availability.end();++it) - info.compressed_peer_availability_maps[it->first] = it->second.cmap ; -} - -void ChunkMap::removeFileSource(const RsPeerId& peer_id) -{ - std::map::iterator it(_peers_chunks_availability.find(peer_id)) ; - - if(it == _peers_chunks_availability.end()) - return ; - - _peers_chunks_availability.erase(it) ; -} - -void ChunkMap::getAvailabilityMap(CompressedChunkMap& compressed_map) const -{ - compressed_map = CompressedChunkMap(_map) ; - -#ifdef DEBUG_FTCHUNK - std::cerr << "ChunkMap:: retrieved availability map of size " << _map.size() << ", chunk_size=" << _chunk_size << std::endl ; -#endif -} - -void ChunkMap::forceCheck() -{ - for(uint32_t i=0;i<_map.size();++i) - { - _map[i] = FileChunksInfo::CHUNK_CHECKING ; - _chunks_checking_queue.push_back(i) ; - } - - updateTotalDownloaded() ; -} - -uint32_t ChunkMap::getNumberOfChunks(uint64_t size) -{ - uint64_t n = size/(uint64_t)CHUNKMAP_FIXED_CHUNK_SIZE ; - - if(size % (uint64_t)CHUNKMAP_FIXED_CHUNK_SIZE != 0) - ++n ; - - uint32_t value = n & 0xffffffffull ; - - if((uint64_t)value != n) - { - std::cerr << "ERROR: number of chunks is a totally absurd value. File size is " << size << ", chunks are " << n << "!!" << std::endl ; - return 0 ; - } - return value ; -} - -void ChunkMap::buildPlainMap(uint64_t size, CompressedChunkMap& map) -{ - uint32_t n = getNumberOfChunks(size) ; - - map = CompressedChunkMap(n,~uint32_t(0)) ; -} - - diff --git a/libretroshare/src/ft/ftchunkmap.h b/libretroshare/src/ft/ftchunkmap.h deleted file mode 100644 index a9e7eb900..000000000 --- a/libretroshare/src/ft/ftchunkmap.h +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftchunkmap.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -#pragma once - -#include -#include "retroshare/rstypes.h" - -// ftChunkMap: -// - handles chunk map over a complete file -// - mark down which chunk is being downloaded by which peer -// - allocate data ranges of any requested size for a given peer -// - continuing an existing chunk -// - allocating a new chunk -// -// Download mecanism: -// - ftFileCreator handles a list of active slices, and periodically resends requests every 20 sec. -// Slices have arbitrary size (less than a chunk), depending on the transfer rate. -// When receiving data, ftFileCreator shrinks its slices until they get complete. When a slice is finished, it -// notifies ftChunkMap that this slice is done. -// -// - ftChunkMap maintains two levels: -// - the chunk level (Chunks a 1MB long) with a map of who has which chunk and what locally is the state of -// each chunk -// - the slice level: each active chunk is cut into slices (basically a list of intervalls) being downloaded, and -// a remaining slice to cut off new candidates. When notified for a complete slice, ftChunkMap removed the -// corresponding acive slice. When asked a slice, ftChunkMap cuts out a slice from the remaining part of the chunk -// to download, sends the slice's coordinates and gives a unique slice id (such as the slice offset). - - -// This class handles a slice of a chunk of arbitrary uint32_t size, at the level of ftFileCreator - -class ftController ; - -class ftChunk -{ - public: - typedef uint64_t OffsetInFile ; - - ftChunk():offset(0), size(0), id(0), ts(0),ref_cnt(NULL) {} - - friend std::ostream& operator<<(std::ostream& o,const ftChunk& f) ; - - uint64_t offset; // current offset of the slice - uint64_t size; // size remaining to download - OffsetInFile id ; // id of the chunk. Equal to the starting offset of the chunk - rstime_t ts; // time of last data received - int *ref_cnt; // shared counter of number of sub-blocks. Used when a slice gets split. - RsPeerId peer_id ; -}; - -// This class handles a single fixed-sized chunk. Although each chunk is requested at once, -// it may be sent back into sub-chunks because of file transfer rate constraints. -// So the dataReceived function should be called to progressively complete the chunk, -// and the getChunk method should ask for a sub-chunk of a given size. -// -class Chunk -{ - public: - Chunk(): _start(0),_offset(0),_end(0) {} // only used in default std::map fillers - - Chunk(uint64_t start,uint32_t size) ; - - void getSlice(uint32_t size_hint,ftChunk& chunk) ; - - // Returns true when the chunk is complete - bool empty() const { return _offset == _end ; } - - // Array of intervalls of bytes to download. - // - uint64_t _start ; // const - uint64_t _offset ; // not const: handles the current offset within the chunk. - uint64_t _end ; // const -}; - -struct ChunkDownloadInfo -{ - public: - struct SliceRequestInfo - { - uint32_t size ; // size of the slice - rstime_t request_time ; // last request time - std::set peers ; // peers the slice was requested to. Normally only one, except at the end of the file. - }; - - std::map _slices ; - uint32_t _remains ; - rstime_t _last_data_received ; -}; - -class SourceChunksInfo -{ - public: - CompressedChunkMap cmap ; //! map of what the peer has/doens't have - rstime_t TS ; //! last update time for this info - bool is_full ; //! is the map full ? In such a case, re-asking for it is unnecessary. - - // Returns true if the offset is starting in a mapped chunk. - // - bool hasData(uint64_t offset,uint32_t fixed_chunk_size) const - { - if(is_full) - return true ; - - return cmap[offset / (uint64_t)fixed_chunk_size ] ; - } -}; - -class ChunkMap -{ - public: - static const uint32_t CHUNKMAP_FIXED_CHUNK_SIZE = 1024*1024 ; // 1 MB chunk - typedef uint32_t ChunkNumber ; - - /// Constructor. Decides what will be the size of chunks and how many there will be. - - ChunkMap(uint64_t file_size,bool assume_availability) ; - - /// destructor - virtual ~ChunkMap() {} - - /// Returns an slice of data to be asked to the peer within a chunk. - /// If a chunk is already been downloaded by this peer, take a slice at - /// the beginning of this chunk, or at least where it starts. - /// If not, randomly/streamly select a new chunk depending on the strategy. - /// adds an entry in the chunk_ids map, and sets up 1 interval for it. - /// the chunk should be available from the designated peer. - /// On return: - /// - source_chunk_map_needed = true if the source map should be asked - - virtual bool getDataChunk(const RsPeerId& peer_id,uint32_t size_hint,ftChunk& chunk,bool& source_chunk_map_needed) ; - - /// Returns an already pending slice that was being downloaded but hasn't arrived yet. This is mostly used at the end of the file - /// in order to re-ask pendign slices to active peers while slow peers take a lot of time to send their remaining slices. - /// - bool reAskPendingChunk(const RsPeerId& peer_id,uint32_t size_hint,uint64_t& offset,uint32_t& size); - - /// Notify received a slice of data. This needs to - /// - carve in the map of chunks what is received, what is not. - /// - tell which chunks are finished. For this, each interval must know what chunk number it has been attributed - /// when the interval is split in the middle, the number of intervals for the chunk is increased. If the interval is - /// completely covered by the data, the interval number is decreased. - - virtual void dataReceived(const ftChunk::OffsetInFile& c_id) ; - - /// Decides how chunks are selected. - /// STREAMING: the 1st chunk is always returned - /// RANDOM: a uniformly random chunk is selected among available chunks for the current source. - /// - - void setStrategy(FileChunksInfo::ChunkStrategy s) { _strategy = s ; } - FileChunksInfo::ChunkStrategy getStrategy() const { return _strategy ; } - - /// Properly fills an vector of fixed size chunks with availability or download state. - /// chunks is given with the proper number of chunks and we have to adapt to it. This can be used - /// to display square chunks in the gui or display a blue bar of availability by collapsing info from all peers. - /// The set method is not virtual because it has no reason to exist in the parent ftFileProvider - - virtual void getAvailabilityMap(CompressedChunkMap& cmap) const ; - void setAvailabilityMap(const CompressedChunkMap& cmap) ; - - /// Removes the source availability map. The map - void removeFileSource(const RsPeerId& peer_id) ; - - /// This function fills in a plain map for a file of the given size. This - /// is used to ensure that the chunk size will be consistent with the rest - /// of the code. - // - static void buildPlainMap(uint64_t size,CompressedChunkMap& map) ; - - /// Computes the number of chunks for the given file size. - static uint32_t getNumberOfChunks(uint64_t size) ; - - /// This function is used by the parent ftFileProvider to know whether the chunk can be sent or not. - bool isChunkAvailable(uint64_t offset, uint32_t chunk_size) const ; - - bool isChunkOutstanding(uint64_t offset, uint32_t chunk_size) const ; - - /// Remove active chunks that have not received any data for the last 60 seconds, and return - /// the list of slice numbers that should be canceled. - void removeInactiveChunks(std::vector& to_remove) ; - - /// Updates the peer's availablility map - // - void setPeerAvailabilityMap(const RsPeerId& peer_id,const CompressedChunkMap& peer_map) ; - - /// Returns a pointer to the availability chunk map of the given source, and possibly - /// allocates it if necessary. - // - SourceChunksInfo *getSourceChunksInfo(const RsPeerId& peer_id) ; - - /// Returns the total size of downloaded data in the file. - uint64_t getTotalReceived() const { return _total_downloaded ; } - - /// returns true is the file is complete - bool isComplete() const { return _file_is_complete ; } - - /// returns info about currently downloaded chunks - void getChunksInfo(FileChunksInfo& info) const ; - - /// input the result of the chunk hash checking - void setChunkCheckingResult(uint32_t chunk_number, bool succeed) ; - - /// returns the current list of chunks to ask for a CRC, and a proposed source for each - void getChunksToCheck(std::vector& chunks_to_ask) ; - - /// Get all available sources for this chunk - void getSourcesList(uint32_t chunk_number,std::vector& sources) ; - - /// sets all chunks to checking state - void forceCheck() ; - - /// Goes through all structures and computes the actual file completion. The true completion - /// gets lost when force checking the file. - void updateTotalDownloaded() ; - - protected: - /// handles what size the last chunk has. - uint32_t sizeOfChunk(uint32_t chunk_number) const ; - - /// Returns a chunk available for this peer_id, depending on the chunk strategy. - // - uint32_t getAvailableChunk(const RsPeerId& peer_id,bool& chunk_map_too_old) ; - - private: - bool hasChunkState(uint64_t offset, uint32_t chunk_size, FileChunksInfo::ChunkState state) const; - - uint64_t _file_size ; //! total size of the file in bytes. - uint32_t _chunk_size ; //! Size of chunks. Common to all chunks. - FileChunksInfo::ChunkStrategy _strategy ; //! how do we allocate new chunks - std::map _active_chunks_feed ; //! vector of chunks being downloaded. Exactly 1 chunk per peer. - std::map _slices_to_download ; //! list of (slice offset,slice size) currently being downloaded - std::vector _map ; //! vector of chunk state over the whole file - std::map _peers_chunks_availability ; //! what does each source peer have - uint64_t _total_downloaded ; //! completion for the file - bool _file_is_complete ; //! set to true when the file is complete. - bool _assume_availability ; //! true if all sources always have the complete file. - std::vector _chunks_checking_queue ; //! Queue of downloaded chunks to be checked. -}; - - diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc deleted file mode 100644 index 29494f189..000000000 --- a/libretroshare/src/ft/ftcontroller.cc +++ /dev/null @@ -1,2273 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftcontroller.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* - * ftController - * - * Top level download controller. - * - * inherits configuration (save downloading files) - * inherits pqiMonitor (knows which peers are online). - * inherits CacheTransfer (transfers cache files too) - * inherits RsThread (to control transfers) - * - */ - -#ifdef WINDOWS_SYS -#include "util/rsstring.h" -#endif -#include "util/rsdiscspace.h" -#include "util/rsmemory.h" -#include "util/rstime.h" -#include "util/cxx17retrocompat.h" -#include "ft/ftcontroller.h" - -#include "ft/ftfilecreator.h" -#include "ft/fttransfermodule.h" -#include "ft/ftsearch.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftextralist.h" -#include "ft/ftserver.h" - -#include "turtle/p3turtle.h" - -#include "util/rsdir.h" -#include "rsserver/p3face.h" - -#include "pqi/p3linkmgr.h" - -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" - -#include "rsitems/rsconfigitems.h" -#include -#include /* for (u)sleep() */ -#include "util/rstime.h" - -/****** - * #define CONTROL_DEBUG 1 - * #define DEBUG_DWLQUEUE 1 - *****/ - -static const int32_t SAVE_TRANSFERS_DELAY = 301 ; // save transfer progress every 301 seconds. -static const int32_t INACTIVE_CHUNKS_CHECK_DELAY = 240 ; // time after which an inactive chunk is released -static const int32_t MAX_TIME_INACTIVE_REQUEUED = 120 ; // time after which an inactive ftFileControl is bt-queued - -static const int32_t FT_FILECONTROL_QUEUE_ADD_END = 0 ; -static const int32_t FT_FILECONTROL_MAX_UPLOAD_SLOTS_DEFAULT= 0 ; - -const uint32_t FT_CNTRL_STANDARD_RATE = 10 * 1024 * 1024; -const uint32_t FT_CNTRL_SLOW_RATE = 100 * 1024; - -ftFileControl::ftFileControl() - :mTransfer(NULL), mCreator(NULL), - mState(DOWNLOADING), mSize(0), mFlags(0), mCreateTime(0), mQueuePriority(0), mQueuePosition(0) -{ - return; -} - -ftFileControl::ftFileControl(const std::string& fname, const std::string& tmppath, const std::string& dest - , uint64_t size, const RsFileHash &hash, TransferRequestFlags flags - , ftFileCreator *fc, ftTransferModule *tm) - : mName(fname), mCurrentPath(tmppath), mDestination(dest) - , mTransfer(tm), mCreator(fc), mState(DOWNLOADING), mHash(hash) - , mSize(size), mFlags(flags), mCreateTime(0), mQueuePriority(0), mQueuePosition(0) -{} - -ftController::ftController(ftDataMultiplex *dm, p3ServiceControl *sc, uint32_t ftServiceId) - : p3Config(), - last_save_time(0), - last_clean_time(0), - mSearch(NULL), - mDataplex(dm), - mExtraList(NULL), - mTurtle(NULL), - mFtServer(NULL), - mServiceCtrl(sc), - mFtServiceType(ftServiceId), - mDefaultEncryptionPolicy(RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE), - mFilePermDirectDLPolicy(RS_FILE_PERM_DIRECT_DL_PER_USER), - cnt(0), - ctrlMutex("ftController"), - doneMutex("ftController"), - mFtActive(false), - mFtPendingDone(false), - mDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE), - _max_active_downloads(5), // default queue size - _max_uploads_per_friend(FT_FILECONTROL_MAX_UPLOAD_SLOTS_DEFAULT) -{ -} - -void ftController::setTurtleRouter(p3turtle *pt) { mTurtle = pt ; } -void ftController::setFtServer(ftServer *ft) { mFtServer = ft ; } - -void ftController::setFtSearchNExtra(ftSearch *search, ftExtraList *list) -{ - mSearch = search; - mExtraList = list; -} - -bool ftController::getFileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it = mDownloads.find(hash) ; - - if(it != mDownloads.end()) - { - it->second->mCreator->getChunkMap(info) ; - //info.flags = it->second->mFlags ; - - return true ; - } - - it = mCompleted.find(hash) ; - - if(it != mCompleted.end()) - { - // This should rather be done as a static method of ChunkMap. - // - // We do this manually, because the file creator has already been destroyed. - // - info.file_size = it->second->mSize ; - info.strategy = mDefaultChunkStrategy ; - info.chunk_size = ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE ; - //info.flags = it->second->mFlags ; - uint32_t nb_chunks = it->second->mSize/ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE ; - if(it->second->mSize % ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE != 0) - ++nb_chunks ; - info.chunks.resize(nb_chunks,FileChunksInfo::CHUNK_DONE) ; - - return true ; - } - - return false ; -} - -void ftController::addFileSource(const RsFileHash& hash,const RsPeerId& peer_id) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it = mDownloads.find(hash); - -#ifdef CONTROL_DEBUG - std::cerr << "ftController: Adding source " << peer_id << " to current download hash=" << hash ; -#endif - if(it != mDownloads.end()) - { - it->second->mTransfer->addFileSource(peer_id); - setPeerState(it->second->mTransfer, peer_id, FT_CNTRL_STANDARD_RATE, mServiceCtrl->isPeerConnected(mFtServiceType, peer_id )); - -#ifdef CONTROL_DEBUG - std::cerr << "... added." << std::endl ; -#endif - return ; - } -#ifdef CONTROL_DEBUG - std::cerr << "... not added: hash not found." << std::endl ; -#endif -} -void ftController::removeFileSource(const RsFileHash& hash,const RsPeerId& peer_id) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it = mDownloads.find(hash); - -#ifdef CONTROL_DEBUG - std::cerr << "ftController: Adding source " << peer_id << " to current download hash=" << hash ; -#endif - if(it != mDownloads.end()) - { - it->second->mTransfer->removeFileSource(peer_id); - it->second->mCreator->removeFileSource(peer_id); - -#ifdef CONTROL_DEBUG - std::cerr << "... added." << std::endl ; -#endif - return ; - } -#ifdef CONTROL_DEBUG - std::cerr << "... not added: hash not found." << std::endl ; -#endif -} -void ftController::threadTick() -{ - /* check the queues */ - - //Waiting 1 sec before start - rstime::rs_usleep(1*1000*1000); // 1 sec - -#ifdef CONTROL_DEBUG - //std::cerr << "ftController::run()"; - //std::cerr << std::endl; -#endif - bool doPending = false; - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - doPending = (mFtActive) && (!mFtPendingDone); - } - - rstime_t now = time(NULL) ; - if(now > last_save_time + SAVE_TRANSFERS_DELAY) - { - IndicateConfigChanged() ; - last_save_time = now ; - } - - if(now > last_clean_time + INACTIVE_CHUNKS_CHECK_DELAY) - { - searchForDirectSources() ; - - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - for(std::map::iterator it(mDownloads.begin());it!=mDownloads.end();++it) - it->second->mCreator->removeInactiveChunks() ; - - last_clean_time = now ; - } - - if (doPending) - { - if (!handleAPendingRequest()) - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - mFtPendingDone = true; - } - } - - tickTransfers() ; - - { - std::list files_to_complete ; - - { - RsStackMutex stack2(doneMutex); - files_to_complete = mDone ; - mDone.clear(); - } - - for(std::list::iterator it(files_to_complete.begin()); it != files_to_complete.end(); ++it) - completeFile(*it); - } - - if(cnt++ % 10 == 0) - checkDownloadQueue() ; -} - -void ftController::searchForDirectSources() -{ -#ifdef CONTROL_DEBUG - std::cerr << "ftController::searchForDirectSources()" << std::endl; -#endif - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - if (!mSearch) - { -#ifdef CONTROL_DEBUG - std::cerr << " search module not available!" << std::endl; -#endif - return; - } - - for(std::map::iterator it(mDownloads.begin()); it != mDownloads.end(); ++it ) - if(it->second->mState != ftFileControl::QUEUED && it->second->mState != ftFileControl::PAUSED ) - { -#ifdef CONTROL_DEBUG - std::cerr << " file " << it->first << ":" << std::endl; -#endif - FileInfo info ; // Info needs to be re-allocated each time, to start with a clear list of peers (it's not cleared down there) - - if( mSearch->search(it->first, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info) ) - for( std::vector::const_iterator pit = info.peers.begin(); pit != info.peers.end(); ++pit ) - { - bool bAllowDirectDL = false; - switch (mFilePermDirectDLPolicy) { - case RS_FILE_PERM_DIRECT_DL_YES: bAllowDirectDL = true; break; - case RS_FILE_PERM_DIRECT_DL_NO: bAllowDirectDL = false; break; - default:bAllowDirectDL = (rsPeers->servicePermissionFlags(pit->peerId) & RS_NODE_PERM_DIRECT_DL); break; - } - if( bAllowDirectDL ) - if( it->second->mTransfer->addFileSource(pit->peerId) ) /* if the sources don't exist already - add in */ - setPeerState( it->second->mTransfer, pit->peerId, FT_CNTRL_STANDARD_RATE, mServiceCtrl->isPeerConnected(mFtServiceType, pit->peerId) ); -#ifdef CONTROL_DEBUG - std::cerr << " found source " << pit->peerId << ", allowDirectDL=" << bAllowDirectDL << ". " << (bAllowDirectDL?"adding":"not adding") << std::endl; -#endif - } -#ifdef CONTROL_DEBUG - else - std::cerr << " search returned empty.: " << std::endl; -#endif - } -#ifdef CONTROL_DEBUG - else - std::cerr << " file " << it->first << ": state is " << it->second->mState << ": ignored." << std::endl; -#endif -} - -void ftController::tickTransfers() -{ - // 1 - sort modules into arrays according to priority - - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - -#ifdef CONTROL_DEBUG - // std::cerr << "ticking transfers." << std::endl ; -#endif - // Collect all non queued files. - // - for(std::map::iterator it(mDownloads.begin()); it != mDownloads.end(); ++it) - if(it->second->mState != ftFileControl::QUEUED && it->second->mState != ftFileControl::PAUSED) - it->second->mTransfer->tick() ; -} - -bool ftController::getPriority(const RsFileHash& hash,DwlSpeed& p) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it(mDownloads.find(hash)) ; - - if(it != mDownloads.end()) - { - p = it->second->mTransfer->downloadPriority() ; - return true ; - } - else - return false ; -} - -void ftController::setPriority(const RsFileHash& hash,DwlSpeed p) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it(mDownloads.find(hash)) ; - - if(it != mDownloads.end()) - it->second->mTransfer->setDownloadPriority(p) ; -} - -/* Called every 10 seconds or so */ -void ftController::checkDownloadQueue() -{ - // We do multiple things here: - // - // 0 - make sure all transfers have a consistent value for mDownloadQueue - // - // 1 - are there queued files ? - // - // YES - // 1.1 - check for inactive files (see below). - // - select one inactive file - // - close it temporarily - // - remove it from turtle handling - // - move the ftFileControl to queued list - // - set the queue priority to 1+largest in the queue. - // 1.2 - pop from the queue the 1st file to come (according to availability of sources, then priority) - // - enable turtle router handling for this hash - // - reset counters - // - set the file as waiting - // NO - // Do nothing, because no files are waiting. - // - // 2 - in FileRequest, if the max number of downloaded files is exceeded, put the - // file in the queue list, and don't enable the turtle router handling. - // - // Implementation: - // - locate a hash in the queue - // - move hashes in the queue up/down/top/bottom - // - now the place of each ftFileControl element in the queue to activate/desactive them - // - // So: - // - change mDownloads to be a std::map - // - sort the ftFileControl* into a std::vector - // - store the queue position of each ftFileControl* into its own structure (mQueuePosition member) - // - // We don't want the turtle router to keep openning tunnels for queued files, so we only base - // the notion of inactive on the fact that no traffic happens for the file within 5 mins. - // - // How do we detect inactive files? - // For a downld file: - no traffic for 5 min. - - RsStackMutex mtx(ctrlMutex) ; - -#ifdef DEBUG_DWLQUEUE - std::cerr << "Checking download queue." << std::endl ; -#endif - if(mDownloads.size() <= _max_active_downloads) - return ; - - std::vector inactive_transfers ; - std::vector transfers_with_online_sources ; - - std::set online_peers ; - mServiceCtrl->getPeersConnected(mFtServiceType,online_peers) ; - - // Check for inactive transfers, and queued transfers with online sources. - // - rstime_t now = time(NULL) ; - - for(std::map::const_iterator it(mDownloads.begin());it!=mDownloads.end() ;++it) - if( it->second->mState != ftFileControl::QUEUED && (it->second->mState == ftFileControl::PAUSED - || now > it->second->mTransfer->lastActvTimeStamp() + (rstime_t)MAX_TIME_INACTIVE_REQUEUED)) - { - inactive_transfers.push_back(it->second) ; - } - else if(it->second->mState == ftFileControl::QUEUED) - { - std::list srcs ; - it->second->mTransfer->getFileSources(srcs) ; - - for(std::list::const_iterator it2(srcs.begin());it2!=srcs.end();++it2) - if(online_peers.find(*it2) != online_peers.end()) - { - transfers_with_online_sources.push_back(it->second) ; - break ; - } - } - -#ifdef DEBUG_DWLQUEUE - std::cerr << "Identified " << inactive_transfers.size() << " inactive transfer, and " << transfers_with_online_sources.size() << " queued transfers with online sources." << std::endl; -#endif - - // first swap as many queued transfers with online sources with inactive transfers - uint32_t i=0; - - for(;imName << " at position " << inactive_transfers[i]->mQueuePosition << " with transfer at position " << transfers_with_online_sources[i]->mQueuePosition << " which has available sources." << std::endl; -#endif - inactive_transfers[i]->mTransfer->resetActvTimeStamp() ; // very important! - transfers_with_online_sources[i]->mTransfer->resetActvTimeStamp() ; // very important! - - locked_swapQueue(inactive_transfers[i]->mQueuePosition,transfers_with_online_sources[i]->mQueuePosition); - } - - // now if some inactive transfers remain, put them at the end of the queue. - - for(;imName << " at position " << inactive_transfers[i]->mQueuePosition << " moved to end of the queue. mState=" << inactive_transfers[i]->mState << ", time lapse=" << now - it->second->mCreator->lastActvTimeStamp() << std::endl ; -#endif - locked_bottomQueue(inactive_transfers[i]->mQueuePosition) ; -#ifdef DEBUG_DWLQUEUE - std::cerr << " new position: " << inactive_transfers[i]->mQueuePosition << std::endl ; - std::cerr << " new state: " << inactive_transfers[i]->mState << std::endl ; -#endif - inactive_transfers[i]->mTransfer->resetActvTimeStamp() ; // very important! - } - - // finally, do a full swab over the queue to make sure that the expected number of downloads is met. - - for(uint32_t i=0;i::iterator it(mDownloads.find(hash)) ; - - if(it == mDownloads.end()) - { - std::cerr << "ftController::moveInQueue: can't find hash " << hash << " in the download list." << std::endl ; - return ; - } - uint32_t pos = it->second->mQueuePosition ; - -#ifdef DEBUG_DWLQUEUE - std::cerr << "Moving file " << hash << ", pos=" << pos << " to new pos." << std::endl ; -#endif - switch(mv) - { - case QUEUE_TOP: locked_topQueue(pos) ; - break ; - - case QUEUE_BOTTOM: locked_bottomQueue(pos) ; - break ; - - case QUEUE_UP: if(pos > 0) - locked_swapQueue(pos,pos-1) ; - break ; - - case QUEUE_DOWN: if(pos < mDownloadQueue.size()-1) - locked_swapQueue(pos,pos+1) ; - break ; - default: - std::cerr << "ftController::moveInQueue: unknown move " << mv << std::endl ; - } -} - -void ftController::locked_topQueue(uint32_t pos) -{ - ftFileControl *tmp=mDownloadQueue[pos] ; - - for(int p=pos;p>0;--p) - { - mDownloadQueue[p]=mDownloadQueue[p-1] ; - locked_checkQueueElement(p) ; - } - mDownloadQueue[0]=tmp ; - - locked_checkQueueElement(0) ; -} -void ftController::locked_bottomQueue(uint32_t pos) -{ - ftFileControl *tmp=mDownloadQueue[pos] ; - - for(uint32_t p=pos;pmQueuePosition = pos ; - - if(pos < _max_active_downloads && mDownloadQueue[pos]->mState != ftFileControl::PAUSED) - { - if(mDownloadQueue[pos]->mState == ftFileControl::QUEUED) - mDownloadQueue[pos]->mTransfer->resetActvTimeStamp() ; - - mDownloadQueue[pos]->mState = ftFileControl::DOWNLOADING ; - - if(mDownloadQueue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) - mFtServer->activateTunnels(mDownloadQueue[pos]->mHash,mDefaultEncryptionPolicy,mDownloadQueue[pos]->mFlags,true); - } - - if(pos >= _max_active_downloads && mDownloadQueue[pos]->mState != ftFileControl::QUEUED && mDownloadQueue[pos]->mState != ftFileControl::PAUSED) - { - mDownloadQueue[pos]->mState = ftFileControl::QUEUED ; - mDownloadQueue[pos]->mCreator->closeFile() ; - - if(mDownloadQueue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) - mFtServer->activateTunnels(mDownloadQueue[pos]->mHash,mDefaultEncryptionPolicy,mDownloadQueue[pos]->mFlags,false); - } -} - -bool ftController::FlagFileComplete(const RsFileHash& hash) -{ - RsStackMutex stack2(doneMutex); - mDone.push_back(hash); - -#ifdef CONTROL_DEBUG - std::cerr << "ftController:FlagFileComplete(" << hash << ")"; - std::cerr << std::endl; -#endif - - return true; -} - -bool ftController::completeFile(const RsFileHash& hash) -{ - /* variables... so we can drop mutex later */ - std::string path; - std::string name; - uint64_t size = 0; - uint32_t period = 0; - TransferRequestFlags flags ; - TransferRequestFlags extraflags ; - uint32_t completeCount = 0; - - { - RS_STACK_MUTEX(ctrlMutex); - -#ifdef CONTROL_DEBUG - std::cerr << "ftController:completeFile(" << hash << ")"; - std::cerr << std::endl; -#endif - std::map::iterator it(mDownloads.find(hash)); - - if (it == mDownloads.end()) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController:completeFile(" << hash << ")"; - std::cerr << " Not Found!"; - std::cerr << std::endl; -#endif - return false; - } - - /* check if finished */ - if (!(it->second)->mCreator->finished()) - { - /* not done! */ -#ifdef CONTROL_DEBUG - std::cerr << "ftController:completeFile(" << hash << ")"; - std::cerr << " Transfer Not Done"; - std::cerr << std::endl; - - std::cerr << "FileSize: "; - std::cerr << (it->second)->mCreator->getFileSize(); - std::cerr << " and Recvd: "; - std::cerr << (it->second)->mCreator->getRecvd(); -#endif - return false; - } - - - ftFileControl *fc = it->second; - - // (csoler) I've postponed this to the end of the block because deleting the - // element from the map calls the destructor of fc->mTransfer, which - // makes fc to point to nothing and causes random behavior/crashes. - // - // mDataplex->removeTransferModule(fc->mTransfer->hash()); - // - /* done - cleanup */ - - // (csoler) I'm copying this because "delete fc->mTransfer" deletes the hash string! - RsFileHash hash_to_suppress(fc->mTransfer->hash()); - - // This should be done that early, because once the file creator is - // deleted, it should not be accessed by the data multiplex anymore! - // - mDataplex->removeTransferModule(hash_to_suppress) ; - - if (fc->mTransfer) - { - delete fc->mTransfer; - fc->mTransfer = NULL; - } - - if (fc->mCreator) - { - fc->mCreator->closeFile() ; - delete fc->mCreator; - fc->mCreator = NULL; - } - - fc->mState = ftFileControl::COMPLETED; - - std::string dst_dir,src_dir,src_file,dst_file ; - - RsDirUtil::splitDirFromFile(fc->mCurrentPath,src_dir,src_file) ; - RsDirUtil::splitDirFromFile(fc->mDestination,dst_dir,dst_file) ; - - // We use this intermediate file in case the destination directory is not available, so as to not keep the partial file name. - - std::string intermediate_file_name = src_dir+'/'+dst_file ; - - // I don't know how the size can be zero, but believe me, this happens, - // and it causes an error on linux because then the file may not even exist. - // - if( fc->mSize == 0) - fc->mState = ftFileControl::ERROR_COMPLETION; - else - { - std::cerr << "CompleteFile(): renaming " << fc->mCurrentPath << " into " << fc->mDestination << std::endl; - std::cerr << "CompleteFile(): 1 - renaming " << fc->mCurrentPath << " info " << intermediate_file_name << std::endl; - - if(RsDirUtil::moveFile(fc->mCurrentPath,intermediate_file_name) ) - { - fc->mCurrentPath = intermediate_file_name ; - - std::cerr << "CompleteFile(): 2 - renaming/copying " << intermediate_file_name << " into " << fc->mDestination << std::endl; - - if(RsDirUtil::moveFile(intermediate_file_name,fc->mDestination) ) - fc->mCurrentPath = fc->mDestination; - else - fc->mState = ftFileControl::ERROR_COMPLETION; - } - else - fc->mState = ftFileControl::ERROR_COMPLETION; - } - - /* for extralist additions */ - path = fc->mDestination; - name = fc->mName; - //hash = fc->mHash; - size = fc->mSize; - period = 30 * 24 * 3600; /* 30 days */ - extraflags.clear() ; - -#ifdef CONTROL_DEBUG - std::cerr << "CompleteFile(): size = " << size << std::endl ; -#endif - - flags = fc->mFlags ; - - locked_queueRemove(it->second->mQueuePosition) ; - - /* switch map */ - mCompleted[fc->mHash] = fc; - completeCount = mCompleted.size(); - - mDownloads.erase(it); - - if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) - mFtServer->activateTunnels(hash_to_suppress,mDefaultEncryptionPolicy,flags,false); - - } // UNLOCK: RS_STACK_MUTEX(ctrlMutex); - - - /******************** NO Mutex from Now ******************** - * cos Callback can end up back in this class. - ***********************************************************/ - - /* If it has a callback - do it now */ - - if(flags & RS_FILE_REQ_EXTRA)// | RS_FILE_HINTS_MEDIA)) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::completeFile() adding to ExtraList"; - std::cerr << std::endl; -#endif - - if(mExtraList) - mExtraList->addExtraFile(path, hash, size, period, extraflags); - } - else - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::completeFile() No callback"; - std::cerr << std::endl; -#endif - } - - /* Notify GUI */ - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mHash = hash; - ev->mFileTransferEventCode = RsFileTransferEventCode::DOWNLOAD_COMPLETE; - rsEvents->postEvent(ev); - } - - rsFiles->ForceDirectoryCheck(true) ; - - IndicateConfigChanged(); /* completed transfer -> save */ - return true; -} - - /***************************************************************/ - /********************** Controller Access **********************/ - /***************************************************************/ - -bool ftController::activate() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - mFtActive = true; - mFtPendingDone = false; - return true; -} - -bool ftController::isActiveAndNoPending() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - return (mFtActive && mFtPendingDone); -} - -bool ftController::handleAPendingRequest() -{ - uint32_t nb_requests_handled = 0 ; - static const uint32_t MAX_SIMULTANEOUS_PENDING_REQUESTS = 100 ; - - while(!mPendingRequests.empty() && nb_requests_handled++ < MAX_SIMULTANEOUS_PENDING_REQUESTS) - { - ftPendingRequest req; - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - req = mPendingRequests.front(); - mPendingRequests.pop_front(); - } -#ifdef CONTROL_DEBUG - std::cerr << "Requesting pending hash " << req.mHash << std::endl ; -#endif - - FileRequest(req.mName, req.mHash, req.mSize, req.mDest, TransferRequestFlags(req.mFlags), req.mSrcIds, req.mState); - - { - // See whether there is a pendign chunk map recorded for this hash. - // - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it(mPendingChunkMaps.find(req.mHash)) ; - - if(it != mPendingChunkMaps.end()) - { - RsFileTransfer *rsft = it->second ; - std::map::iterator fit = mDownloads.find(rsft->file.hash); - - if((fit==mDownloads.end() || (fit->second)->mCreator == NULL)) - { - // This should never happen, because the last call to FileRequest must have created the fileCreator!! - // - std::cerr << "ftController::loadList(): Error: could not find hash " << rsft->file.hash << " in mDownloads list !" << std::endl ; - } - else - { -#ifdef CONTROL_DEBUG - std::cerr << "Hash " << req.mHash << " is in downloads" << std::endl ; - std::cerr << " setting chunk strategy to " << rsft->chunk_strategy << std::endl; -#endif - (fit->second)->mCreator->setAvailabilityMap(rsft->compressed_chunk_map) ; - (fit->second)->mCreator->setChunkStrategy((FileChunksInfo::ChunkStrategy)(rsft->chunk_strategy)) ; - (fit->second)->mState=rsft->state; - } - - delete rsft ; - mPendingChunkMaps.erase(it) ; - } -#ifdef CONTROL_DEBUG - else - std::cerr << "No pending chunkmap for hash " << req.mHash << std::endl ; -#endif - } - } - return !mPendingRequests.empty(); -} - -bool ftController::alreadyHaveFile(const RsFileHash& hash, FileInfo &info) -{ - // check for downloads - if (FileDetails(hash, info) && (info.downloadStatus == FT_STATE_COMPLETE)) - return true ; - - // check for file lists - if (!mSearch) return false; - if (mSearch->search(hash, RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, info)) - return true ; - - return false ; -} - -bool ftController::FileRequest( - const std::string& fname, const RsFileHash& hash, uint64_t size, - const std::string& dest, TransferRequestFlags flags, - const std::list &_srcIds, uint16_t state ) -{ - /* TODO: To support collections faithfully we need to be able to save - * the same file to multiple locations, both if already downloaded or - * incomplete */ - - std::list srcIds(_srcIds) ; - - /* check if we have the file */ - - FileInfo info; - if(alreadyHaveFile(hash, info)) - return false ; - - // the strategy for requesting encryption is the following: - // - // if policy is STRICT - // - disable clear, enforce encryption - // else - // - if not specified, use both - // - if(mDefaultEncryptionPolicy == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT) - { - flags |= RS_FILE_REQ_ENCRYPTED ; - flags &= ~RS_FILE_REQ_UNENCRYPTED ; - } - else if(!(flags & ( RS_FILE_REQ_ENCRYPTED | RS_FILE_REQ_UNENCRYPTED ))) - { - flags |= RS_FILE_REQ_ENCRYPTED ; - flags |= RS_FILE_REQ_UNENCRYPTED ; - } - - if(size == 0) // we treat this special case because - { - /* if no destpath - send to download directory */ - std::string destination ; - - if (dest == "") - destination = mDownloadPath + "/" + fname; - else - destination = dest + "/" + fname; - - // create void file with the target name. - FILE *f = RsDirUtil::rs_fopen(destination.c_str(),"w") ; - if(!f) - RsErr() << __PRETTY_FUNCTION__ << " Could not write file " - << destination << std::endl; - else - fclose(f) ; - - return true ; - } - - // Bugs in the cache system can cause files with arbitrary size to be - // requested, causing a division by zero in ftChunkMap when size > 1MB * - // (2^32-1). I thus conservatively check for large size values. - // - if(size >= 1024ull*1024ull*((1ull << 32) - 1)) - { - RsErr() << __PRETTY_FUNCTION__ - << " unexpected size. This is probably a bug." - << " name = " << fname - << " flags = " << flags - << " dest = " << dest - << " size = " << size << std::endl; - return false; - } - - /* If file transfer is not enabled .... - * save request for later. This will also - * mean that we will have to copy local files, - * or have a callback which says: local file. - */ - - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - if (!mFtActive) - { - /* store in pending queue */ - ftPendingRequest req(fname, hash, size, dest, flags, srcIds,state); - mPendingRequests.push_back(req); - return true; - } - } - - /* remove the sources from the list, if they don't have clearance for direct - * transfer. This happens only for non cache files. */ - for(std::list::iterator it = srcIds.begin(); it != srcIds.end(); ) - { - bool bAllowDirectDL = false; - switch (mFilePermDirectDLPolicy) { - case RS_FILE_PERM_DIRECT_DL_YES: bAllowDirectDL = true; break; - case RS_FILE_PERM_DIRECT_DL_NO: bAllowDirectDL = false; break; - default:bAllowDirectDL = (rsPeers->servicePermissionFlags(*it) & RS_NODE_PERM_DIRECT_DL); break; - } - - if(!bAllowDirectDL) - { - std::list::iterator tmp(it); - ++tmp; - srcIds.erase(it); - it = tmp; - } - else - ++it; - } - - std::list::const_iterator it; - std::vector::const_iterator pit; - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest(" << fname << ","; - std::cerr << hash << "," << size << "," << dest << ","; - std::cerr << flags << ",<"; - - for(it = srcIds.begin(); it != srcIds.end(); ++it) - { - std::cerr << *it << ","; - } - std::cerr << ">)"; - std::cerr << std::endl; -#endif - - uint32_t rate = 0; - if (flags & RS_FILE_REQ_BACKGROUND) - rate = FT_CNTRL_SLOW_RATE; - else - rate = FT_CNTRL_STANDARD_RATE; - - /* First check if the file is already being downloaded.... - * This is important as some guis request duplicate files regularly. - */ - - { - RS_STACK_MUTEX(ctrlMutex); - - auto dit = std::as_const(mDownloads).find(hash); - if (dit != mDownloads.end()) - { - /* we already have it! */ - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() Already Downloading File"; - std::cerr << std::endl; - std::cerr << "\tNo need to download"; - std::cerr << std::endl; -#endif - /* but we should add this peer - if they don't exist! - * (needed for channels). - */ - - for(it = srcIds.begin(); it != srcIds.end(); ++it) - { - bool bAllowDirectDL = false; - switch (mFilePermDirectDLPolicy) { - case RS_FILE_PERM_DIRECT_DL_YES: bAllowDirectDL = true; break; - case RS_FILE_PERM_DIRECT_DL_NO: bAllowDirectDL = false; break; - default:bAllowDirectDL = (rsPeers->servicePermissionFlags(*it) & RS_NODE_PERM_DIRECT_DL); break; - } - if(bAllowDirectDL) - { - uint32_t i, j; - if ((dit->second)->mTransfer->getPeerState(*it, i, j)) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() Peer Existing"; - std::cerr << std::endl; -#endif - continue; /* already added peer */ - } - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() Adding Peer: " << *it; - std::cerr << std::endl; -#endif - (dit->second)->mTransfer->addFileSource(*it); - setPeerState(dit->second->mTransfer, *it, rate, mServiceCtrl->isPeerConnected(mFtServiceType, *it)); - } - } - - if (srcIds.empty()) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() WARNING: No Src Peers"; - std::cerr << std::endl; -#endif - } - - return true; - } - } // RS_STACK_MUTEX(ctrlMutex); unlocked - - - if(mSearch && !(flags & RS_FILE_REQ_NO_SEARCH)) - { - /* do a source search - for any extra sources */ - // add sources only in direct mode - // - if(/* (flags & RS_FILE_HINTS_BROWSABLE) && */ mSearch->search(hash, RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY, info)) - { - /* do something with results */ -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() Found Other Sources"; - std::cerr << std::endl; -#endif - - /* if the sources don't exist already - add in */ - for(pit = info.peers.begin(); pit != info.peers.end(); ++pit) - { -#ifdef CONTROL_DEBUG - std::cerr << "\tSource: " << pit->peerId; - std::cerr << std::endl; -#endif - // Because this is auto-add, we only add sources that we allow to DL from using direct transfers. - - bool bAllowDirectDL = false; - switch (mFilePermDirectDLPolicy) { - case RS_FILE_PERM_DIRECT_DL_YES: bAllowDirectDL = true; break; - case RS_FILE_PERM_DIRECT_DL_NO: bAllowDirectDL = false; break; - default:bAllowDirectDL = (rsPeers->servicePermissionFlags(pit->peerId) & RS_NODE_PERM_DIRECT_DL); break; - } - - if ((srcIds.end() == std::find( srcIds.begin(), srcIds.end(), pit->peerId)) && bAllowDirectDL) - { - srcIds.push_back(pit->peerId); - -#ifdef CONTROL_DEBUG - std::cerr << "\tAdding in: " << pit->peerId; - std::cerr << std::endl; -#endif - } - } - } - } - - /* add in new item for download */ - std::string savepath; - std::string destination; - - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - savepath = mPartialsPath + "/" + hash.toStdString(); - destination = dest + "/" + fname; - - /* if no destpath - send to download directory */ - if (dest == "") - destination = mDownloadPath + "/" + fname; - } /******* UNLOCKED ********/ - - // We check that flags are consistent. - - if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING) - mFtServer->activateTunnels(hash,mDefaultEncryptionPolicy,flags,true); - - bool assume_availability = false; - - ftFileCreator *fc = new ftFileCreator(savepath, size, hash,assume_availability); - ftTransferModule *tm = new ftTransferModule(fc, mDataplex,this); - -#ifdef CONTROL_DEBUG - std::cerr << "Note: setting chunk strategy to " << mDefaultChunkStrategy <setChunkStrategy(mDefaultChunkStrategy) ; - - /* add into maps */ - ftFileControl *ftfc = new ftFileControl(fname, savepath, destination, size, hash, flags, fc, tm); - ftfc->mCreateTime = time(NULL); - - /* now add source peers (and their current state) */ - tm->setFileSources(srcIds); - - /* get current state for transfer module */ - for(it = srcIds.begin(); it != srcIds.end(); ++it) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() adding peer: " << *it; - std::cerr << std::endl; -#endif - setPeerState(tm, *it, rate, mServiceCtrl->isPeerConnected(mFtServiceType, *it)); - } - - /* add structures into the accessible data. Needs to be locked */ - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - locked_addToQueue(ftfc, FT_FILECONTROL_QUEUE_ADD_END ) ; - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileRequest() Created ftFileCreator @: " << fc; - std::cerr << std::endl; - std::cerr << "ftController::FileRequest() Created ftTransModule @: " << tm; - std::cerr << std::endl; - std::cerr << "ftController::FileRequest() Created ftFileControl." ; - std::cerr << std::endl; -#endif - - /* add to ClientModule */ - mDataplex->addTransferModule(tm, fc); - mDownloads[hash] = ftfc; - } - - IndicateConfigChanged(); /* completed transfer -> save */ - return true; -} - -bool ftController::setPeerState(ftTransferModule *tm, const RsPeerId& id, uint32_t maxrate, bool online) -{ - if (id == mServiceCtrl->getOwnId()) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setPeerState() is Self"; - std::cerr << std::endl; -#endif - tm->setPeerState(id, PQIPEER_IDLE, maxrate); - } - else if (online || mTurtle->isOnline(id)) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setPeerState()"; - std::cerr << " Peer is Online"; - std::cerr << std::endl; -#endif - tm->setPeerState(id, PQIPEER_IDLE, maxrate); - } - else - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setPeerState()"; - std::cerr << " Peer is Offline"; - std::cerr << std::endl; -#endif - tm->setPeerState(id, PQIPEER_NOT_ONLINE, maxrate); - } - return true; -} - - -bool ftController::setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s) -{ - std::map::iterator mit=mDownloads.find(hash); - if (mit==mDownloads.end()) - { -#ifdef CONTROL_DEBUG - std::cerr<<"ftController::setChunkStrategy file is not found in mDownloads"<second->mCreator->setChunkStrategy(s) ; - return true ; -} - -bool ftController::FileCancel(const RsFileHash& hash) -{ - mFtServer->activateTunnels(hash,mDefaultEncryptionPolicy,TransferRequestFlags(0),false); - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileCancel" << std::endl; -#endif - /*check if the file in the download map*/ - - { - RsStackMutex mtx(ctrlMutex) ; - - std::map::iterator mit=mDownloads.find(hash); - if (mit==mDownloads.end()) - { -#ifdef CONTROL_DEBUG - std::cerr<<"ftController::FileCancel file is not found in mDownloads"<second)->mCreator->finished()) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController:FileCancel(" << hash << ")"; - std::cerr << " Transfer Already finished"; - std::cerr << std::endl; - - std::cerr << "FileSize: "; - std::cerr << (mit->second)->mCreator->getFileSize(); - std::cerr << " and Recvd: "; - std::cerr << (mit->second)->mCreator->getRecvd(); -#endif - return false; - } - - /*find the point to transfer module*/ - ftTransferModule* ft=(mit->second)->mTransfer; - ft->cancelTransfer(); - - ftFileControl *fc = mit->second; - mDataplex->removeTransferModule(fc->mTransfer->hash()); - - if (fc->mTransfer) - { - delete fc->mTransfer; - fc->mTransfer = NULL; - } - - if (fc->mCreator) - { - delete fc->mCreator; - fc->mCreator = NULL; - } - - /* delete the temporary file */ - if (0 == remove(fc->mCurrentPath.c_str())) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileCancel() remove temporary file "; - std::cerr << fc->mCurrentPath; - std::cerr << std::endl; -#endif - } - else - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileCancel() fail to remove file "; - std::cerr << fc->mCurrentPath; - std::cerr << std::endl; -#endif - } - - locked_queueRemove(fc->mQueuePosition) ; - delete fc ; - mDownloads.erase(mit); - } - - IndicateConfigChanged(); /* completed transfer -> save */ - return true; -} - -bool ftController::FileControl(const RsFileHash& hash, uint32_t flags) -{ -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileControl(" << hash << ","; - std::cerr << flags << ")"<::iterator mit=mDownloads.find(hash); - if (mit==mDownloads.end()) - { -#ifdef CONTROL_DEBUG - std::cerr<<"ftController::FileControl file is not found in mDownloads"<second->mState = ftFileControl::PAUSED ; - std::cerr << "setting state to " << ftFileControl::PAUSED << std::endl ; - break; - - case RS_FILE_CTRL_START: - mit->second->mState = ftFileControl::DOWNLOADING ; - std::cerr << "setting state to " << ftFileControl::DOWNLOADING << std::endl ; - break; - - case RS_FILE_CTRL_FORCE_CHECK: - mit->second->mTransfer->forceCheck(); - std::cerr << "setting state to " << ftFileControl::CHECKING_HASH << std::endl ; - break; - - default: - return false; - } - IndicateConfigChanged() ; - - return true; -} - -bool ftController::FileClearCompleted() -{ -#ifdef CONTROL_DEBUG - std::cerr << "ftController::FileClearCompleted()" <second; - - mCompleted.clear(); - - IndicateConfigChanged(); - } - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mFileTransferEventCode = RsFileTransferEventCode::COMPLETED_FILES_REMOVED; - rsEvents->postEvent(ev); - } - - return true; -} - - /* get Details of File Transfers */ -void ftController::FileDownloads(std::list &hashs) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator it; - for(it = mDownloads.begin(); it != mDownloads.end(); ++it) - { - hashs.push_back(it->second->mHash); - } - for(it = mCompleted.begin(); it != mCompleted.end(); ++it) - { - hashs.push_back(it->second->mHash); - } -} - - - /* Directory Handling */ -bool ftController::setDownloadDirectory(std::string path) -{ -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setDownloadDirectory(" << path << ")"; - std::cerr << std::endl; -#endif - /* check if it exists */ - if (RsDirUtil::checkCreateDirectory(path)) - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - mDownloadPath = RsDirUtil::convertPathToUnix(path); - - RsDiscSpace::setDownloadPath(mDownloadPath) ; -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setDownloadDirectory() Okay!"; - std::cerr << std::endl; -#endif - IndicateConfigChanged(); - return true; - } - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::setDownloadDirectory() Failed"; - std::cerr << std::endl; -#endif - return false; -} - -bool ftController::setPartialsDirectory(std::string path) -{ - - /* check it is not a subdir of download / shared directories (BAD) - TODO */ - { - RsStackMutex stack(ctrlMutex); - - path = RsDirUtil::convertPathToUnix(path); - - if (path.find(mDownloadPath) != std::string::npos) { - return false; - } - - if (rsFiles) { - std::list::iterator it; - std::list dirs; - rsFiles->getSharedDirectories(dirs); - for (it = dirs.begin(); it != dirs.end(); ++it) { - if (path.find((*it).filename) != std::string::npos) { - return false; - } - } - } - } - - /* check if it exists */ - - if (RsDirUtil::checkCreateDirectory(path)) - { - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - mPartialsPath = path; - - RsDiscSpace::setPartialsPath(path) ; - -#if 0 /*** FIX ME !!!**************/ - /* move all existing files! */ - std::map::iterator it; - for(it = mDownloads.begin(); it != mDownloads.end(); ++it) - { - (it->second).mCreator->changePartialDirectory(mPartialPath); - } -#endif - IndicateConfigChanged(); - return true; - } - - return false; -} - -std::string ftController::getDownloadDirectory() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - return mDownloadPath; -} - -std::string ftController::getPartialsDirectory() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - return mPartialsPath; -} - -bool ftController::setDestinationDirectory(const RsFileHash& hash,const std::string& dest_dir) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - std::map::iterator it = mDownloads.find(hash); - - if (it == mDownloads.end()) - return false; - - std::cerr << "(II) Changing destination of file " << it->second->mDestination << std::endl; - - it->second->mDestination = dest_dir + '/' + it->second->mName ; - - std::cerr << "(II) ...to " << it->second->mDestination << std::endl; - - return true ; -} -bool ftController::setDestinationName(const RsFileHash& hash,const std::string& dest_name) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - std::map::iterator it = mDownloads.find(hash); - - if (it == mDownloads.end()) - return false; - - std::cerr << "(II) Changing destination of file " << it->second->mDestination << std::endl; - - std::string dest_path ; - RsDirUtil::removeTopDir(it->second->mDestination, dest_path); /* remove fname */ - - it->second->mDestination = dest_path + '/' + dest_name ; - it->second->mName = dest_name ; - - std::cerr << "(II) ...to " << it->second->mDestination << std::endl; - - return true ; -} - -bool ftController::FileDetails(const RsFileHash &hash, FileInfo &info) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - bool completed = false; - std::map::iterator it = mDownloads.find(hash); - if (it == mDownloads.end()) - { - /* search completed files too */ - it = mCompleted.find(hash); - if (it == mCompleted.end()) - { - /* Note: mTransfer & mCreator - * are both NULL - */ - return false; - } - completed = true; - } - - /* extract details */ - info.hash = hash; - info.fname = it->second->mName; - info.storage_permission_flags.clear() ; - info.transfer_info_flags = it->second->mFlags ; - info.priority = SPEED_NORMAL ; - RsDirUtil::removeTopDir(it->second->mDestination, info.path); /* remove fname */ - info.queue_position = it->second->mQueuePosition ; - - if(it->second->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING) - info.storage_permission_flags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD ; // file being downloaded anonymously are always anonymously available. - - /* get list of sources from transferModule */ - std::list peerIds; - std::list::iterator pit; - - if (!completed) - { - it->second->mTransfer->getFileSources(peerIds); - info.priority = it->second->mTransfer->downloadPriority() ; - info.lastTS = it->second->mCreator->lastRecvTimeStamp(); // last time the file was actually written - } - else - info.lastTS = 0; - - double totalRate = 0; - uint32_t tfRate = 0; - uint32_t state = 0; - - bool isDownloading = false; - bool isSuspended = false; - - info.peers.clear(); - - for(pit = peerIds.begin(); pit != peerIds.end(); ++pit) - { - if (it->second->mTransfer->getPeerState(*pit, state, tfRate)) - { - TransferInfo ti; - switch(state) - { - case PQIPEER_INIT: - ti.status = FT_STATE_OKAY; - break; - case PQIPEER_NOT_ONLINE: - ti.status = FT_STATE_WAITING; - break; - case PQIPEER_DOWNLOADING: - isDownloading = true; - ti.status = FT_STATE_DOWNLOADING; - break; - case PQIPEER_IDLE: - ti.status = FT_STATE_OKAY; - break; - default: - case PQIPEER_SUSPEND: - isSuspended = true; - ti.status = FT_STATE_FAILED; - break; - } - - ti.tfRate = tfRate / 1024.0; - ti.peerId = *pit; - info.peers.push_back(ti); - totalRate += tfRate / 1024.0; - } - } - - if ((completed) || ((it->second)->mCreator->finished())) - { - info.downloadStatus = FT_STATE_COMPLETE; - } - else if (isDownloading) - { - info.downloadStatus = FT_STATE_DOWNLOADING; - } - else if (isSuspended) - { - info.downloadStatus = FT_STATE_FAILED; - } - else - { - info.downloadStatus = FT_STATE_WAITING; - } - - if(it->second->mState == ftFileControl::QUEUED) - info.downloadStatus = FT_STATE_QUEUED ; - - if(it->second->mState == ftFileControl::PAUSED) - info.downloadStatus = FT_STATE_PAUSED ; - - if((!completed) && it->second->mTransfer->isCheckingHash()) - info.downloadStatus = FT_STATE_CHECKING_HASH ; - - info.tfRate = totalRate; - info.size = (it->second)->mSize; - - if (completed) - { - info.transfered = info.size; - info.avail = info.transfered; - } - else - { - info.transfered = (it->second)->mCreator->getRecvd(); - info.avail = info.transfered; - } - - return true; - - - -} - - - /***************************************************************/ - /********************** Controller Access **********************/ - /***************************************************************/ - - /* pqiMonitor callback: - * Used to tell TransferModules new available peers - */ -void ftController::statusChange(const std::list &plist) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - uint32_t rate = FT_CNTRL_STANDARD_RATE; - - /* add online to all downloads */ - std::map::iterator it; - std::list::const_iterator pit; - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::statusChange()"; - std::cerr << std::endl; -#endif - - for(it = mDownloads.begin(); it != mDownloads.end(); ++it) - { -#ifdef CONTROL_DEBUG - std::cerr << "ftController::statusChange() Updating Hash:"; - std::cerr << it->first; - std::cerr << std::endl; -#endif - for(pit = plist.begin(); pit != plist.end(); ++pit) - { -#ifdef CONTROL_DEBUG - std::cerr << "Peer: " << pit->id; -#endif - if (pit->actions & RS_SERVICE_PEER_CONNECTED) - { -#ifdef CONTROL_DEBUG - std::cerr << " is Newly Connected!"; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, pit->id, rate, true); - } - else if (pit->actions & RS_SERVICE_PEER_DISCONNECTED) - { -#ifdef CONTROL_DEBUG - std::cerr << " is Just disconnected!"; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, pit->id, rate, false); - } - else // Added or Removed. - { -#ifdef CONTROL_DEBUG - std::cerr << " had something happen to it: "; - std::cerr << pit-> actions; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, pit->id, rate, false); - } - } - - // Now also look at turtle virtual peers, for ongoing downloads only. - // - if(it->second->mState != ftFileControl::DOWNLOADING) - continue ; - - std::list vlist ; - std::list::const_iterator vit; - mTurtle->getSourceVirtualPeersList(it->first,vlist) ; - -#ifdef CONTROL_DEBUG - std::cerr << "vlist.size() = " << vlist.size() << std::endl; -#endif - - for(vit = vlist.begin(); vit != vlist.end(); ++vit) - { -#ifdef CONTROL_DEBUG - std::cerr << "Peer: " << vit->id; -#endif - if (vit->actions & RS_PEER_CONNECTED) - { -#ifdef CONTROL_DEBUG - std::cerr << " is Newly Connected!"; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, vit->id, rate, true); - } - else if (vit->actions & RS_PEER_DISCONNECTED) - { -#ifdef CONTROL_DEBUG - std::cerr << " is Just disconnected!"; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, vit->id, rate, false); - } - else - { -#ifdef CONTROL_DEBUG - std::cerr << " had something happen to it: "; - std::cerr << vit-> actions; - std::cerr << std::endl; -#endif - setPeerState(it->second->mTransfer, vit->id, rate, false); - } - } - } -} - -const std::string active_downloads_size_ss("MAX_ACTIVE_DOWNLOADS"); -const std::string download_dir_ss("DOWN_DIR"); -const std::string partial_dir_ss("PART_DIR"); -const std::string max_uploads_per_friend_ss("MAX_UPLOADS_PER_FRIEND"); -const std::string default_chunk_strategy_ss("DEFAULT_CHUNK_STRATEGY"); -const std::string free_space_limit_ss("FREE_SPACE_LIMIT"); -const std::string default_encryption_policy_ss("DEFAULT_ENCRYPTION_POLICY"); -const std::string file_perm_direct_dl_ss("FILE_PERM_DIRECT_DL"); - - - /* p3Config Interface */ -RsSerialiser *ftController::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser(); - - /* add in the types we need! */ - rss->addSerialType(new RsFileConfigSerialiser()); - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss; -} - -bool ftController::saveList(bool &cleanup, std::list& saveData) -{ - - - /* it can delete them! */ - cleanup = true; - - /* create a key/value set for most of the parameters */ - std::map configMap; - std::map::iterator mit; - std::list::iterator it; - - /* basic control parameters */ - std::string s ; - rs_sprintf(s, "%lu", getQueueSize()) ; - configMap[active_downloads_size_ss] = s ; - configMap[download_dir_ss] = getDownloadDirectory(); - configMap[partial_dir_ss] = getPartialsDirectory(); - - switch(mDefaultChunkStrategy) - { - case FileChunksInfo::CHUNK_STRATEGY_STREAMING: configMap[default_chunk_strategy_ss] = "STREAMING" ; - break ; - case FileChunksInfo::CHUNK_STRATEGY_RANDOM: configMap[default_chunk_strategy_ss] = "RANDOM" ; - break ; - - default: - case FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE:configMap[default_chunk_strategy_ss] = "PROGRESSIVE" ; - break ; - } - - rs_sprintf(s,"%lu",_max_uploads_per_friend) ; - configMap[max_uploads_per_friend_ss] = s ; - - configMap[default_encryption_policy_ss] = (mDefaultEncryptionPolicy==RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE)?"PERMISSIVE":"STRICT" ; - - switch (mFilePermDirectDLPolicy) { - case RS_FILE_PERM_DIRECT_DL_YES: configMap[file_perm_direct_dl_ss] = "YES" ; - break; - case RS_FILE_PERM_DIRECT_DL_NO: configMap[file_perm_direct_dl_ss] = "NO" ; - break; - default: configMap[file_perm_direct_dl_ss] = "PER_USER" ; - break; - } - - rs_sprintf(s, "%lu", RsDiscSpace::freeSpaceLimit()); - configMap[free_space_limit_ss] = s ; - - RsConfigKeyValueSet *rskv = new RsConfigKeyValueSet(); - - /* Convert to TLV */ - for(mit = configMap.begin(); mit != configMap.end(); ++mit) - { - RsTlvKeyValue kv; - kv.key = mit->first; - kv.value = mit->second; - - rskv->tlvkvs.pairs.push_back(kv); - } - - /* Add KeyValue to saveList */ - saveData.push_back(rskv); - - /* get list of Downloads .... - * strip out Caches / ExtraList / Channels???? - * (anything with a callback?) - * - most systems will restart missing files. - */ - - - /* get Details of File Transfers */ - std::list hashs; - FileDownloads(hashs); - - for(it = hashs.begin(); it != hashs.end(); ++it) - { - /* stack mutex released each loop */ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::map::iterator fit = mDownloads.find(*it); - if (fit == mDownloads.end()) - continue; - - /* ignore cache files. As this is small files, better download them again from scratch at restart.*/ - - // Node: We still save finished transfers. This keeps transfers that are - // in checking mode. Finished or checked transfers will restart and - // immediately terminate/recheck at next startup. - // - // if ((fit->second)->mCreator->finished()) - // continue; - - /* make RsFileTransfer item for save list */ - RsFileTransfer *rft = new RsFileTransfer(); - - /* what data is important? */ - - rft->file.name = fit->second->mName; - rft->file.hash = fit->second->mHash; - rft->file.filesize = fit->second->mSize; - RsDirUtil::removeTopDir(fit->second->mDestination, rft->file.path); /* remove fname */ - rft->flags = fit->second->mFlags.toUInt32(); - rft->state = fit->second->mState; - - std::list lst ; - fit->second->mTransfer->getFileSources(lst); - - // Remove turtle peers from sources, as they are not supposed to survive a reboot of RS, since they are dynamic sources. - // Otherwize, such sources are unknown from the turtle router, at restart, and never get removed. - // - for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) - if(!mTurtle->isTurtlePeer(*it)) - rft->allPeerIds.ids.insert(*it) ; - - rft->transferred = fit->second->mCreator->getRecvd(); - fit->second->mCreator->getAvailabilityMap(rft->compressed_chunk_map) ; - rft->chunk_strategy = fit->second->mCreator->getChunkStrategy() ; - - saveData.push_back(rft); - } - - { - /* Save pending list of downloads */ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - - std::list::iterator pit; - for (pit = mPendingRequests.begin(); pit != mPendingRequests.end(); ++pit) - { - /* make RsFileTransfer item for save list */ - RsFileTransfer *rft = NULL; - - std::map::iterator rit = mPendingChunkMaps.find(pit->mHash); - if (rit != mPendingChunkMaps.end()) { - /* use item from the not loaded pending list */ - rft = new RsFileTransfer(*(rit->second)); - } else { - rft = new RsFileTransfer(); - - /* what data is important? */ - - rft->file.name = pit->mName; - rft->file.hash = pit->mHash; - rft->file.filesize = pit->mSize; - RsDirUtil::removeTopDir(pit->mDest, rft->file.path); /* remove fname */ - rft->flags = pit->mFlags.toUInt32(); - rft->state = pit->mState; - - rft->allPeerIds.ids.clear() ; - for(std::list::const_iterator it(pit->mSrcIds.begin());it!=pit->mSrcIds.end();++it) - rft->allPeerIds.ids.insert( *it ) ; - } - - // Remove turtle peers from sources, as they are not supposed to survive a reboot of RS, since they are dynamic sources. - // Otherwize, such sources are unknown from the turtle router, at restart, and never get removed. We do that in post - // process since the rft object may have been created from mPendingChunkMaps - // - for(std::set::iterator sit(rft->allPeerIds.ids.begin());sit!=rft->allPeerIds.ids.end();) - if(mTurtle->isTurtlePeer(RsPeerId(*sit))) - { - std::set::iterator sittmp(sit) ; - ++sittmp ; - rft->allPeerIds.ids.erase(sit) ; - sit = sittmp ; - } - else - ++sit ; - - saveData.push_back(rft); - } - } - - /* list completed! */ - return true; -} - - -bool ftController::loadList(std::list& load) -{ - std::list::iterator it; - std::list::iterator kit; - RsConfigKeyValueSet *rskv; - RsFileTransfer *rsft; - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::loadList() Item Count: " << load.size(); - std::cerr << std::endl; -#endif - - for(it = load.begin(); it != load.end(); ++it) - { - /* switch on type */ - if (NULL != (rskv = dynamic_cast(*it))) - { - /* make into map */ - std::map configMap; - for(kit = rskv->tlvkvs.pairs.begin(); - kit != rskv->tlvkvs.pairs.end(); ++kit) - { - configMap[kit->key] = kit->value; - } - - loadConfigMap(configMap); - - } - else if (NULL != (rsft = dynamic_cast(*it))) - { - /* This will get stored on a waiting list - until the - * config files are fully loaded - */ -#ifdef TO_REMOVE - (csoler) I removed this because RS_FILE_HINTS_NETWORK_WIDE is actually equal to RS_FILE_REQ_ENCRYPTED, so this test removed the encrypted flag when loading!! - // Compatibility with previous versions. - if(rsft->flags & RS_FILE_HINTS_NETWORK_WIDE.toUInt32()) - { - std::cerr << "Ensuring compatibility, replacing RS_FILE_HINTS_NETWORK_WIDE with RS_FILE_REQ_ANONYMOUS_ROUTING" << std::endl; - rsft->flags &= ~RS_FILE_HINTS_NETWORK_WIDE.toUInt32() ; - rsft->flags |= RS_FILE_REQ_ANONYMOUS_ROUTING.toUInt32() ; - } -#endif - -#ifdef CONTROL_DEBUG - std::cerr << "ftController::loadList(): requesting " << rsft->file.name << ", " << rsft->file.hash << ", " << rsft->file.filesize << std::endl ; -#endif - std::list src_lst ; - for(std::set::const_iterator it(rsft->allPeerIds.ids.begin());it!=rsft->allPeerIds.ids.end();++it) - src_lst.push_back(*it) ; - - FileRequest(rsft->file.name, rsft->file.hash, rsft->file.filesize, rsft->file.path, TransferRequestFlags(rsft->flags), src_lst, rsft->state); - - { - RsStackMutex mtx(ctrlMutex) ; - - std::map::iterator fit = mDownloads.find(rsft->file.hash); - - if((fit==mDownloads.end() || (fit->second)->mCreator == NULL)) - { - std::cerr << "ftController::loadList(): Error: could not find hash " << rsft->file.hash << " in mDownloads list !" << std::endl ; - std::cerr << "Storing the map in a wait list." << std::endl ; - - mPendingChunkMaps[rsft->file.hash] = rsft ; - - continue ; // i.e. don't delete the item! - } - else - { - (fit->second)->mCreator->setAvailabilityMap(rsft->compressed_chunk_map) ; - (fit->second)->mCreator->setChunkStrategy((FileChunksInfo::ChunkStrategy)(rsft->chunk_strategy)) ; - } - } - } - - /* cleanup */ - delete (*it); - } - load.clear() ; - return true; - -} - -bool ftController::loadConfigMap(std::map &configMap) -{ - std::map::iterator mit; - - //std::string str_true("true"); - //std::string empty(""); - //std::string dir = "notempty"; - - if (configMap.end() != (mit = configMap.find(download_dir_ss))) - setDownloadDirectory(mit->second); - - if (configMap.end() != (mit = configMap.find(active_downloads_size_ss))) - { - int n=5 ; - sscanf(mit->second.c_str(), "%d", &n); - std::cerr << "Note: loading active max downloads: " << n << std::endl; - setQueueSize(n); - } - if (configMap.end() != (mit = configMap.find(partial_dir_ss))) - { - setPartialsDirectory(mit->second); - } - - if (configMap.end() != (mit = configMap.find(default_encryption_policy_ss))) - { - if(mit->second == "STRICT") - { - mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT ; - std::cerr << "Note: loading default value for encryption policy: STRICT" << std::endl; - } - else if(mit->second == "PERMISSIVE") - { - mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ; - std::cerr << "Note: loading default value for encryption policy: PERMISSIVE" << std::endl; - } - else - { - std::cerr << "(EE) encryption policy not recognized: \"" << mit->second << "\"" << std::endl; - mDefaultEncryptionPolicy = RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE ; - } - } - - if (configMap.end() != (mit = configMap.find(default_chunk_strategy_ss))) - { - if(mit->second == "STREAMING") - { - setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_STREAMING) ; - std::cerr << "Note: loading default value for chunk strategy: streaming" << std::endl; - } - else if(mit->second == "RANDOM") - { - setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ; - std::cerr << "Note: loading default value for chunk strategy: random" << std::endl; - } - else if(mit->second == "PROGRESSIVE") - { - setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE) ; - std::cerr << "Note: loading default value for chunk strategy: progressive" << std::endl; - } - else - std::cerr << "**** ERROR ***: Unknown value for default chunk strategy in keymap." << std::endl ; - } - - if (configMap.end() != (mit = configMap.find(free_space_limit_ss))) - { - uint32_t size ; - if (sscanf(mit->second.c_str(), "%u", &size) == 1) { - std::cerr << "have read a size limit of " << size <<" MB" << std::endl ; - - RsDiscSpace::setFreeSpaceLimit(size) ; - } - } - if(configMap.end() != (mit = configMap.find(max_uploads_per_friend_ss))) - { - uint32_t n ; - if (sscanf(mit->second.c_str(), "%u", &n) == 1) { - std::cerr << "have read a max upload slots limit of " << n << std::endl ; - - _max_uploads_per_friend = n ; - } - } - - if(configMap.end() != (mit = configMap.find(file_perm_direct_dl_ss))) - { - if(mit->second == "YES") - { - mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_YES ; - std::cerr << "Note: loading default value for file permission direct download: YES" << std::endl; - } - else if(mit->second == "NO") - { - mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_NO ; - std::cerr << "Note: loading default value for file permission direct download: NO" << std::endl; - } - else if(mit->second == "PER_USER") - { - mFilePermDirectDLPolicy = RS_FILE_PERM_DIRECT_DL_PER_USER ; - std::cerr << "Note: loading default value for file permission direct download: PER_USER" << std::endl; - } - } - - return true; -} - -void ftController::setMaxUploadsPerFriend(uint32_t m) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - _max_uploads_per_friend = m ; - IndicateConfigChanged(); -} -uint32_t ftController::getMaxUploadsPerFriend() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - return _max_uploads_per_friend ; -} -void ftController::setDefaultEncryptionPolicy(uint32_t p) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - mDefaultEncryptionPolicy = p ; - IndicateConfigChanged(); -} -uint32_t ftController::defaultEncryptionPolicy() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - return mDefaultEncryptionPolicy ; -} - -void ftController::setFilePermDirectDL(uint32_t perm) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - if (mFilePermDirectDLPolicy != perm) - { - mFilePermDirectDLPolicy = perm; - IndicateConfigChanged(); - } -} -uint32_t ftController::filePermDirectDL() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - return mFilePermDirectDLPolicy; -} - -void ftController::setFreeDiskSpaceLimit(uint32_t size_in_mb) -{ - RsDiscSpace::setFreeSpaceLimit(size_in_mb) ; - - IndicateConfigChanged() ; -} - - -uint32_t ftController::freeDiskSpaceLimit() const -{ - return RsDiscSpace::freeSpaceLimit() ; -} - -FileChunksInfo::ChunkStrategy ftController::defaultChunkStrategy() -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ - return mDefaultChunkStrategy ; -} -void ftController::setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy S) -{ - RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ -#ifdef CONTROL_DEBUG - std::cerr << "Note: in frController: setting chunk strategy to " << S << std::endl ; -#endif - mDefaultChunkStrategy = S ; - IndicateConfigChanged() ; -} diff --git a/libretroshare/src/ft/ftcontroller.h b/libretroshare/src/ft/ftcontroller.h deleted file mode 100644 index e890a83d6..000000000 --- a/libretroshare/src/ft/ftcontroller.h +++ /dev/null @@ -1,273 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftcontroller.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_CONTROLLER_HEADER -#define FT_CONTROLLER_HEADER - -/* - * ftController - * - * Top level download controller. - * - * inherits configuration (save downloading files) - * inherits pqiMonitor (knows which peers are online). - * inherits CacheTransfer (transfers cache files too) - * inherits RsThread (to control transfers) - * - */ - -class ftFileCreator; -class ftTransferModule; -class ftFileProvider; -class ftSearch; -class ftServer; -class ftExtraList; -class ftDataMultiplex; -class p3turtle ; -class p3ServiceControl; - -#include "util/rsthreads.h" -#include "pqi/pqiservicemonitor.h" -#include "pqi/p3cfgmgr.h" - -#include "retroshare/rsfiles.h" -#include "rsitems/rsconfigitems.h" - -#include - - -const uint32_t FC_TRANSFER_COMPLETE = 0x0001; - -class ftFileControl -{ - public: - - enum { DOWNLOADING = 0, - COMPLETED = 1, - ERROR_COMPLETION = 2, - QUEUED = 3, - PAUSED = 4, - CHECKING_HASH = 5 - }; - - ftFileControl(); - ftFileControl( const std::string& fname, const std::string& tmppath, const std::string& dest - , uint64_t size, const RsFileHash& hash, TransferRequestFlags flags - , ftFileCreator *fc, ftTransferModule *tm); - - std::string mName; - std::string mCurrentPath; /* current full path (including name) */ - std::string mDestination; /* final full path (including name) */ - ftTransferModule * mTransfer; - ftFileCreator * mCreator; - uint32_t mState; - RsFileHash mHash; - uint64_t mSize; - TransferRequestFlags mFlags; - rstime_t mCreateTime; - uint32_t mQueuePriority ; - uint32_t mQueuePosition ; -}; - -class ftPendingRequest -{ - public: - ftPendingRequest(const std::string& fname, const RsFileHash& hash, - uint64_t size, const std::string& dest, TransferRequestFlags flags, - const std::list &srcIds, uint16_t state) - : mName(fname), mHash(hash), mSize(size), - mDest(dest), mFlags(flags), mSrcIds(srcIds), mState(state) { return; } - - ftPendingRequest() : mSize(0), mFlags(0), mState(0) { return; } - - std::string mName; - RsFileHash mHash; - uint64_t mSize; - std::string mDest; - TransferRequestFlags mFlags; - std::list mSrcIds; - uint16_t mState; -}; - - -class ftController: - public RsTickingThread, public pqiServiceMonitor, public p3Config -{ -public: - - /* Setup */ - ftController(ftDataMultiplex *dm, p3ServiceControl *sc, uint32_t ftServiceId); - - void setFtSearchNExtra(ftSearch *, ftExtraList *); - void setTurtleRouter(p3turtle *) ; - void setFtServer(ftServer *) ; - bool activate(); - bool isActiveAndNoPending(); - - void threadTick() override; /// @see RsTickingThread - - /***************************************************************/ - /********************** Controller Access **********************/ - /***************************************************************/ - - bool FileRequest(const std::string& fname, const RsFileHash& hash, - uint64_t size, const std::string& dest, TransferRequestFlags flags, - const std::list &sourceIds, uint16_t state = ftFileControl::DOWNLOADING); - - /// Do we already have this file, either in download or in file lists ? - bool alreadyHaveFile(const RsFileHash& hash, FileInfo &info); - - bool setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s); - void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy s); - void setDefaultEncryptionPolicy(uint32_t s); - FileChunksInfo::ChunkStrategy defaultChunkStrategy(); - uint32_t freeDiskSpaceLimit() const ; - void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; - uint32_t defaultEncryptionPolicy(); - - void setMaxUploadsPerFriend(uint32_t m) ; - uint32_t getMaxUploadsPerFriend() ; - - void setFilePermDirectDL(uint32_t perm) ; - uint32_t filePermDirectDL() ; - - bool FileCancel(const RsFileHash& hash); - bool FileControl(const RsFileHash& hash, uint32_t flags); - bool FileClearCompleted(); - bool FlagFileComplete(const RsFileHash& hash); - bool getFileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info); - bool setDestinationName(const RsFileHash& hash,const std::string& dest_name) ; - bool setDestinationDirectory(const RsFileHash& hash,const std::string& dest_name) ; - - // Download speed - bool getPriority(const RsFileHash& hash,DwlSpeed& p); - void setPriority(const RsFileHash& hash,DwlSpeed p); - - // Action on queue position - // - void moveInQueue(const RsFileHash& hash,QueueMove mv) ; - void clearQueue() ; - void setQueueSize(uint32_t size) ; - uint32_t getQueueSize() ; - - /* get Details of File Transfers */ - void FileDownloads(std::list &hashs); - - /* Directory Handling */ - bool setDownloadDirectory(std::string path); - bool setPartialsDirectory(std::string path); - std::string getDownloadDirectory(); - std::string getPartialsDirectory(); - bool FileDetails(const RsFileHash &hash, FileInfo &info); - - /***************************************************************/ - /********************** Cache Transfer *************************/ - /***************************************************************/ - - /// Returns true is full source availability can be assumed for this peer. - /// - bool assumeAvailability(const RsPeerId& peer_id) const ; - - /* pqiMonitor callback (also provided mConnMgr pointer!) */ - virtual void statusChange(const std::list &plist); - - void addFileSource(const RsFileHash& hash,const RsPeerId& peer_id) ; - void removeFileSource(const RsFileHash& hash,const RsPeerId& peer_id) ; - - protected: - - void searchForDirectSources() ; - void tickTransfers() ; - - /***************************************************************/ - /********************** Controller Access **********************/ - /***************************************************************/ - - - /* p3Config Interface */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual bool loadList(std::list& load); - bool loadConfigMap(std::map &configMap); - - private: - - /* RunTime Functions */ - void checkDownloadQueue(); // check the whole queue for inactive files - - void locked_addToQueue(ftFileControl*,int strategy) ;// insert this one into the queue - void locked_bottomQueue(uint32_t pos) ; // bottom queue file which is at this position - void locked_topQueue(uint32_t pos) ; // top queue file which is at this position - void locked_checkQueueElement(uint32_t pos) ; // check the state of this element in the queue - void locked_queueRemove(uint32_t pos) ; // delete this element from the queue - void locked_swapQueue(uint32_t pos1,uint32_t pos2) ; // swap position of the two elements - - bool completeFile(const RsFileHash& hash); - bool handleAPendingRequest(); - - bool setPeerState(ftTransferModule *tm, const RsPeerId& id, - uint32_t maxrate, bool online); - - rstime_t last_save_time ; - rstime_t last_clean_time ; - /* pointers to other components */ - - ftSearch *mSearch; - ftDataMultiplex *mDataplex; - ftExtraList *mExtraList; - p3turtle *mTurtle ; - ftServer *mFtServer ; - p3ServiceControl *mServiceCtrl; - uint32_t mFtServiceType; - uint32_t mDefaultEncryptionPolicy; - uint32_t mFilePermDirectDLPolicy; - - uint32_t cnt ; - RsMutex ctrlMutex; - - std::map mCompleted; - std::map mDownloads; - std::vector mDownloadQueue ; - - std::string mConfigPath; - std::string mDownloadPath; - std::string mPartialsPath; - - /**** SPEED QUEUES ****/ - - /* callback list (for File Completion) */ - RsMutex doneMutex; - std::list mDone; - - /* List to Pause File transfers until Caches are properly loaded */ - bool mFtActive; - bool mFtPendingDone; - std::list mPendingRequests; - std::map mPendingChunkMaps ; - - FileChunksInfo::ChunkStrategy mDefaultChunkStrategy ; - - uint32_t _max_active_downloads ; // maximum number of simultaneous downloads - uint32_t _max_uploads_per_friend ; // maximum number of uploads per friend. 0 means unlimited. -}; - -#endif diff --git a/libretroshare/src/ft/ftdata.h b/libretroshare/src/ft/ftdata.h deleted file mode 100644 index 349dae521..000000000 --- a/libretroshare/src/ft/ftdata.h +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftdata.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef FT_DATA_INTERFACE_HEADER -#define FT_DATA_INTERFACE_HEADER - -/* - * ftData. - * - * Internal Interfaces for sending and receiving data. - * Most likely to be implemented by ftServer. - * Provided as an independent interface for testing purposes. - * - */ - -#include -#include - -#include - - /*************** SEND INTERFACE *******************/ - -class CompressedChunkMap ; - -class ftDataSend -{ - public: - virtual ~ftDataSend() { return; } - - /* Client Send */ - virtual bool sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) = 0; - - /* Server Send */ - virtual bool sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data) = 0; - - /// Send a chunkmap[request]. Because requests/chunkmaps can go both - //directions, but for different usages, we have this "is_client" flags, - //that gives the ultimate goal of the data. "is_client==true" means that - //the message is for a client (download) instead of a server. - // - virtual bool sendChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) = 0; - virtual bool sendChunkMap(const RsPeerId& peer_id,const RsFileHash& hash,const CompressedChunkMap& cmap,bool is_client) = 0; - - /// Send a request for a chunk crc map - virtual bool sendSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number) = 0; - /// Send a chunk crc map - virtual bool sendSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) = 0; -}; - - - - /*************** RECV INTERFACE *******************/ - -class ftDataRecv -{ - public: - virtual ~ftDataRecv() { return; } - - /* Client Recv */ - virtual bool recvData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data) = 0; - - /* Server Recv */ - virtual bool recvDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) = 0; - - /// Send a request for a chunk map - virtual bool recvChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) = 0; - - /// Send a chunk map - virtual bool recvChunkMap(const RsPeerId& peer_id,const RsFileHash& hash,const CompressedChunkMap& cmap,bool is_client) = 0; - - virtual bool recvSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_id) = 0; - virtual bool recvSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_id,const Sha1CheckSum& sum) = 0; - -}; - -#endif diff --git a/libretroshare/src/ft/ftdatamultiplex.cc b/libretroshare/src/ft/ftdatamultiplex.cc deleted file mode 100644 index de8f1261c..000000000 --- a/libretroshare/src/ft/ftdatamultiplex.cc +++ /dev/null @@ -1,1164 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftdatamultiplex.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* - * ftDataMultiplexModule. - * - * This multiplexes the data from PQInterface to the ftTransferModules. - */ - -#include "ft/ftdatamultiplex.h" -#include "ft/fttransfermodule.h" -#include "ft/ftfilecreator.h" -#include "ft/ftfileprovider.h" -#include "ft/ftsearch.h" -#include "util/rsdir.h" -#include "util/rsmemory.h" -#include -#include "util/rstime.h" - -/* For Thread Behaviour */ -const uint32_t DMULTIPLEX_MIN = 10; /* 10 msec sleep */ -const uint32_t DMULTIPLEX_MAX = 1000; /* 1 sec sleep */ -const double DMULTIPLEX_RELAX = 0.5; /* relax factor to calculate sleep time if not working in /libretroshare/src/util/rsthreads.cc */ - -static const uint32_t MAX_CHECKING_CHUNK_WAIT_DELAY = 120 ; //! TTL for an inactive chunk -const uint32_t MAX_SIMULTANEOUS_CRC_REQUESTS = 20 ; - -/****** - * #define MPLEX_DEBUG 1 - *****/ - -ftClient::ftClient(ftTransferModule *module, ftFileCreator *creator) - :mModule(module), mCreator(creator) -{ - return; -} - -const uint32_t FT_DATA = 0x0001; // data cuhnk to be stored -const uint32_t FT_DATA_REQ = 0x0002; // data request to be treated -const uint32_t FT_CLIENT_CHUNK_MAP_REQ = 0x0003; // chunk map request to be treated by client -const uint32_t FT_SERVER_CHUNK_MAP_REQ = 0x0004; // chunk map request to be treated by server -//const uint32_t FT_CRC32MAP_REQ = 0x0005; // crc32 map request to be treated by server -const uint32_t FT_CLIENT_CHUNK_CRC_REQ = 0x0006; // chunk sha1 crc request to be treated - -ftRequest::ftRequest(uint32_t type, const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunk, void *data) - :mType(type), mPeerId(peerId), mHash(hash), mSize(size), - mOffset(offset), mChunk(chunk), mData(data) -{ - return; -} - -ftDataMultiplex::ftDataMultiplex(const RsPeerId& ownId, ftDataSend *server, ftSearch *search) - :RsQueueThread(DMULTIPLEX_MIN, DMULTIPLEX_MAX, DMULTIPLEX_RELAX), dataMtx("ftDataMultiplex"), - mDataSend(server), mSearch(search), mOwnId(ownId) -{ - return; -} - -bool ftDataMultiplex::getFileData(const RsFileHash& hash, uint64_t offset, uint32_t& requested_size, uint8_t *data) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - ftFileProvider* provider = 0; - - std::map::iterator cit; - std::map::iterator sit; - - // check if file is currently downloading - if (mClients.end() != (cit = mClients.find(hash))) - provider = (cit->second).mCreator; - - // else check if its already uploading - else if (mServers.end() != (sit = mServers.find(hash))) - provider = sit->second; - - // else create a new provider - else - { - FileInfo info; - FileSearchFlags hintflags = RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_NETWORK_WIDE; - if(mSearch->search(hash, hintflags, info)) - { - provider = new ftFileProvider(info.path, info.size, hash); - mServers[hash] = provider; - } - } - - if(!provider || ! provider->getFileData(mOwnId, offset, requested_size, data, true)) - { - requested_size = 0 ; - return false ; - } - return true ; -} - -bool ftDataMultiplex::addTransferModule(ftTransferModule *mod, ftFileCreator *f) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - std::map::iterator it; - if (mClients.end() != (it = mClients.find(mod->hash()))) - { - /* error */ - return false; - } - mClients[mod->hash()] = ftClient(mod, f); - - return true; -} - -bool ftDataMultiplex::removeTransferModule(const RsFileHash& hash) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - std::map::iterator it; - if (mClients.end() == (it = mClients.find(hash))) - { - /* error */ - return false; - } - mClients.erase(it); - - // This is very important to delete the hash from servers as well, because - // after removing the transfer module, ftController will delete the fileCreator. - // If the file creator is also a server in use, then it will cause a crash - // at the next server request. - // - // With the current action, the next server request will re-create the server as - // a ftFileProvider. - // - std::map::iterator sit = mServers.find(hash) ; - - if(sit != mServers.end()) - mServers.erase(sit); - - return true; -} - - -bool ftDataMultiplex::FileUploads(std::list &hashs) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - std::map::iterator sit; - for(sit = mServers.begin(); sit != mServers.end(); ++sit) - { - hashs.push_back(sit->first); - } - return true; -} - -bool ftDataMultiplex::FileDownloads(std::list &hashs) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - std::map::iterator cit; - for(cit = mClients.begin(); cit != mClients.end(); ++cit) - { - hashs.push_back(cit->first); - } - return true; -} - - -bool ftDataMultiplex::FileDetails(const RsFileHash &hash, FileSearchFlags hintsflag, FileInfo &info) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::FileDetails("; - std::cerr << hash << ", " << hintsflag << ")"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - if(hintsflag & RS_FILE_HINTS_DOWNLOAD) - { - std::map::iterator cit; - if (mClients.end() != (cit = mClients.find(hash))) - { - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::FileDetails()"; - std::cerr << " Found ftFileCreator!"; - std::cerr << std::endl; -#endif - - //(cit->second).mModule->FileDetails(info); - (cit->second).mCreator->FileDetails(info); - return true; - } - } - - if(hintsflag & RS_FILE_HINTS_UPLOAD) - { - std::map::iterator sit; - sit = mServers.find(hash); - if (sit != mServers.end()) - { - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::FileDetails()"; - std::cerr << " Found ftFileProvider!"; - std::cerr << std::endl; -#endif - - (sit->second)->FileDetails(info); - return true; - } - } - - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::FileDetails()"; - std::cerr << " Found nothing"; - std::cerr << std::endl; -#endif - - return false; -} - - /* data interface */ - - /*************** SEND INTERFACE (calls ftDataSend) *******************/ - - /* Client Send */ -bool ftDataMultiplex::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::sendDataRequest() Client Send"; - std::cerr << std::endl; -#endif - return mDataSend->sendDataRequest(peerId,hash,size,offset,chunksize); -} - - /* Server Send */ -bool ftDataMultiplex::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::sendData() Server Send"; - std::cerr << std::endl; -#endif - return mDataSend->sendData(peerId,hash,size,offset,chunksize,data); -} - - - /*************** RECV INTERFACE (provides ftDataRecv) ****************/ - - /* Client Recv */ -bool ftDataMultiplex::recvData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvData() Client Recv"; - std::cerr << std::endl; -#endif - /* Store in Queue */ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - mRequestQueue.push_back(ftRequest(FT_DATA,peerId,hash,size,offset,chunksize,data)); - - return true; -} - - - /* Server Recv */ -bool ftDataMultiplex::recvDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvDataRequest() Server Recv"; - std::cerr << std::endl; -#endif - /* Store in Queue */ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - mRequestQueue.push_back( - ftRequest(FT_DATA_REQ,peerId,hash,size,offset,chunksize,NULL)); - - return true; -} - -bool ftDataMultiplex::recvChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash,bool is_client) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvChunkMapRequest() Server Recv"; - std::cerr << std::endl; -#endif - /* Store in Queue */ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - if(is_client) - mRequestQueue.push_back(ftRequest(FT_CLIENT_CHUNK_MAP_REQ,peerId,hash,0,0,0,NULL)); - else - mRequestQueue.push_back(ftRequest(FT_SERVER_CHUNK_MAP_REQ,peerId,hash,0,0,0,NULL)); - - return true; -} - -bool ftDataMultiplex::recvSingleChunkCRCRequest(const RsPeerId& peerId, const RsFileHash& hash,uint32_t chunk_number) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvChunkMapRequest() Server Recv"; - std::cerr << std::endl; -#endif - /* Store in Queue */ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - mRequestQueue.push_back(ftRequest(FT_CLIENT_CHUNK_CRC_REQ,peerId,hash,0,0,chunk_number,NULL)); - - return true; -} - -/*********** BACKGROUND THREAD OPERATIONS ***********/ -bool ftDataMultiplex::workQueued() -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - if (mRequestQueue.size() > 0) - { - return true; - } - - if (mSearchQueue.size() > 0) - { - return true; - } - - return false; -} - -bool ftDataMultiplex::doWork() -{ - bool doRequests = true; - - /* Handle All the current Requests */ - while(doRequests) - { - ftRequest req; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - if (mRequestQueue.empty()) - { - doRequests = false; - continue; - } - - req = mRequestQueue.front(); - mRequestQueue.pop_front(); - } - - /* MUTEX FREE */ - - switch(req.mType) - { - case FT_DATA: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling FT_DATA"; - std::cerr << std::endl; -#endif - handleRecvData(req.mPeerId, req.mHash, req.mSize, req.mOffset, req.mChunk, req.mData); - break; - - case FT_DATA_REQ: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling FT_DATA_REQ"; - std::cerr << std::endl; -#endif - handleRecvDataRequest(req.mPeerId, req.mHash, req.mSize, req.mOffset, req.mChunk); - break; - - case FT_CLIENT_CHUNK_MAP_REQ: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling FT_CLIENT_CHUNK_MAP_REQ"; - std::cerr << std::endl; -#endif - handleRecvClientChunkMapRequest(req.mPeerId,req.mHash) ; - break ; - - case FT_SERVER_CHUNK_MAP_REQ: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling FT_CLIENT_CHUNK_MAP_REQ"; - std::cerr << std::endl; -#endif - handleRecvServerChunkMapRequest(req.mPeerId,req.mHash) ; - break ; - - case FT_CLIENT_CHUNK_CRC_REQ: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling FT_CLIENT_CHUNK_CRC_REQ"; - std::cerr << std::endl; -#endif - handleRecvChunkCrcRequest(req.mPeerId,req.mHash,req.mChunk) ; - break ; - - default: -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Ignoring UNKNOWN"; - std::cerr << std::endl; -#endif - break; - } - } - - /* Only Handle One Search Per Period.... - * Lower Priority - */ - ftRequest req; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - if (mSearchQueue.empty()) - { - /* Finished */ - return true; - } - - req = mSearchQueue.front(); - mSearchQueue.pop_front(); - } - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::doWork() Handling Search Request"; - std::cerr << std::endl; -#endif - if(handleSearchRequest(req.mPeerId, req.mHash)) - handleRecvDataRequest(req.mPeerId, req.mHash, req.mSize, req.mOffset, req.mChunk) ; - - - return true; -} - -bool ftDataMultiplex::recvSingleChunkCRC(const RsPeerId& peerId, const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvSingleChunkCrc() Received crc of file " << hash << ", from peer id " << peerId << ", chunk " << chunk_number << ", crc=" << crc.toStdString() << std::endl; -#else - (void) peerId; -#endif - // remove this chunk from the request list as well. - - Sha1CacheEntry& sha1cache(_cached_sha1maps[hash]) ; - std::map >::iterator it2(sha1cache._to_ask.find(chunk_number)) ; - - if(it2 != sha1cache._to_ask.end()) - sha1cache._to_ask.erase(it2) ; - - // update the cache: get size from the client. - - std::map::iterator it = mClients.find(hash); - - if(it == mClients.end()) - { - std::cerr << "ftDataMultiplex::recvSingleChunkCrc() ERROR: No matching Client for CRC. This is an error. " << hash << " !" << std::endl; - /* error */ - return false; - } - - // store in the cache as well - - if(sha1cache._map.size() == 0) - sha1cache._map = Sha1Map(it->second.mCreator->fileSize(),ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE) ; - - sha1cache._map.set(chunk_number,crc) ; - - sha1cache._received.push_back(chunk_number) ; - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvSingleChunkCrc() stored in cache. " << std::endl; -#endif - - return true ; -} - -bool ftDataMultiplex::dispatchReceivedChunkCheckSum() -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - uint32_t MAX_CHECKSUM_CHECK_PER_FILE = 25 ; - - for(std::map::iterator it(_cached_sha1maps.begin());it!=_cached_sha1maps.end();) - { - std::map::iterator itc = mClients.find(it->first); - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::dispatchReceivedChunkCheckSum(): treating hash " << it->first << std::endl; -#endif - - if(itc == mClients.end()) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::dispatchReceivedChunkCheckSum() ERROR: No matching Client for hash. This is probably a late answer. Dropping the hash. Hash=" << it->first << std::endl; -#endif - - std::map::iterator tmp(it) ; - ++tmp ; - _cached_sha1maps.erase(it) ; - it = tmp ; - /* error */ - continue ; - } - ftFileCreator *client = itc->second.mCreator ; - - for(uint32_t n=0;nsecond._received.empty();++n) - { - int chunk_number = it->second._received.back() ; - - if(!it->second._map.isSet(chunk_number)) - std::cerr << "ftDataMultiplex::dispatchReceivedChunkCheckSum() ERROR: chunk " << chunk_number << " is supposed to be initialized but it was not received !!" << std::endl; - else - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::dispatchReceivedChunkCheckSum(): checking chunk " << chunk_number << " with hash " << it->second._map[chunk_number].toStdString() << std::endl; -#endif - client->verifyChunk(chunk_number,it->second._map[chunk_number]) ; - } - it->second._received.pop_back() ; - } - ++it ; - } - return true ; -} - -// A chunk map has arrived. It can be two different situations: -// - an uploader has sent his chunk map, so we need to store it in the corresponding ftFileProvider -// - a source for a download has sent his chunk map, so we need to send it to the corresponding ftFileCreator. -// -bool ftDataMultiplex::recvChunkMap(const RsPeerId& peerId, const RsFileHash& hash,const CompressedChunkMap& compressed_map,bool client) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - if(client) // is the chunk map for a client, or for a server ? - { - std::map::iterator it = mClients.find(hash); - - if(it == mClients.end()) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvChunkMap() ERROR: No matching Client for hash " << hash << " !"; - std::cerr << std::endl; -#endif - /* error */ - return false; - } - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::recvChunkMap() Passing map of file " << hash << ", to FT Module"; - std::cerr << std::endl; -#endif - - (it->second).mCreator->setSourceMap(peerId, compressed_map); - return true ; - } - else - { - std::map::iterator it = mServers.find(hash) ; - - if(it == mServers.end()) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMap() ERROR: No matching file Provider for hash " << hash ; - std::cerr << std::endl; -#endif - return false; - } - - it->second->setClientMap(peerId, compressed_map); - return true ; - } - - return false; -} - -bool ftDataMultiplex::handleRecvClientChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash) -{ - CompressedChunkMap cmap ; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - std::map::iterator it = mClients.find(hash); - - if(it == mClients.end()) - { - // If we can't find the client, it's not a problem. Chunk maps from - // clients are not essential, as they are only used for display. -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvClientChunkMapRequest() ERROR: No matching Client for hash " << hash ; - std::cerr << ". Performing local search." << std::endl; -#endif - return false; - } - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvClientChunkMapRequest() Sending map of file " << hash << ", to peer " << peerId << std::endl; -#endif - - (it->second).mCreator->getAvailabilityMap(cmap); - } - - mDataSend->sendChunkMap(peerId,hash,cmap,false); - - return true ; -} - -bool ftDataMultiplex::handleRecvChunkCrcRequest(const RsPeerId& peerId, const RsFileHash& hash, uint32_t chunk_number) -{ - // look into the sha1sum cache - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() looking for chunk " << chunk_number << " for hash " << hash << std::endl; -#endif - - Sha1CheckSum crc ; - bool found = false ; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - Sha1CacheEntry& sha1cache(_cached_sha1maps[hash]) ; - sha1cache.last_activity = time(NULL) ; // update time_stamp - - if(sha1cache._map.size() > 0 && sha1cache._map.isSet(chunk_number)) - { - crc = sha1cache._map[chunk_number] ; - found = true ; - } - } - - if(found) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() found in cache ! Sending " << crc.toStdString() << std::endl; -#endif - mDataSend->sendSingleChunkCRC(peerId,hash,chunk_number,crc); - return true ; - } - - std::map::iterator it ; - std::string filename ; - uint64_t filesize =0; - found = true ; - - // 1 - look into the list of servers.Not clients ! Clients dont' have verified data. - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - it = mServers.find(hash) ; - - if(it == mServers.end()) - found = false ; - } - - // 2 - if not found, create a server. - // - if(!found) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() ERROR: No matching file Provider for hash " << hash ; - std::cerr << std::endl; -#endif - if(!handleSearchRequest(peerId,hash)) - return false ; - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() A new file Provider has been made up for hash " << hash ; - std::cerr << std::endl; -#endif - } - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - it = mServers.find(hash) ; - - if(it == mServers.end()) // handleSearchRequest should have filled mServers[hash], but we have been off-mutex since, - { - std::cerr << "Could definitely not find a provider for file " << hash << ". Maybe the file does not exist?" << std::endl; - return false ; // so it's safer to check again. - } - else - { - filesize = it->second->fileSize() ; - filename = it->second->fileName() ; - } - } - -#ifdef MPLEX_DEBUG - std::cerr << "Computing Sha1 for chunk " << chunk_number<< " of file " << filename << ", hash=" << hash << ", size=" << filesize << std::endl; -#endif - - unsigned char *buf = new unsigned char[ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE] ; - FILE *fd = RsDirUtil::rs_fopen(filename.c_str(),"rb") ; - - if(fd == NULL) - { - std::cerr << "Cannot read file " << filename << ". Something's wrong!" << std::endl; - delete[] buf ; - return false ; - } - uint32_t len ; - if(fseeko64(fd,(uint64_t)chunk_number * (uint64_t)ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE,SEEK_SET)!=0 || 0==(len = fread(buf,1,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE,fd))) - { - std::cerr << "Cannot fseek/read from file " << filename << " at position " << (uint64_t)chunk_number * (uint64_t)ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE << std::endl; - fclose(fd) ; - - delete[] buf ; - return false ; - } - fclose(fd) ; - - crc = RsDirUtil::sha1sum(buf,len) ; - delete[] buf ; - - // update cache - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - Sha1CacheEntry& sha1cache(_cached_sha1maps[hash]) ; - - if(sha1cache._map.size() == 0) - sha1cache._map = Sha1Map(filesize,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE) ; - - sha1cache._map.set(chunk_number,crc) ; - } -#ifdef MPLEX_DEBUG - std::cerr << "Sending CRC of chunk " << chunk_number<< " of file " << filename << ", hash=" << hash << ", size=" << filesize << ", crc=" << crc.toStdString() << std::endl; -#endif - - mDataSend->sendSingleChunkCRC(peerId,hash,chunk_number,crc); - return true ; -} - -bool ftDataMultiplex::handleRecvServerChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash) -{ - CompressedChunkMap cmap ; - std::map::iterator it ; - bool found = true ; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - it = mServers.find(hash) ; - - if(it == mServers.end()) - found = false ; - } - - if(!found) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() ERROR: No matching file Provider for hash " << hash ; - std::cerr << std::endl; -#endif - if(!handleSearchRequest(peerId,hash)) - return false ; - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() A new file Provider has been made up for hash " << hash ; - std::cerr << std::endl; -#endif - } - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - it = mServers.find(hash) ; - - if(it == mServers.end()) // handleSearchRequest should have filled mServers[hash], but we have been off-mutex since, - { - std::cerr << "ftDataMultiplex::handleRecvChunkMapReq() : weird state: search request succeeded, but no server available!" << std::endl; - return false ; // so it's safer to check again. - } - else - it->second->getAvailabilityMap(cmap); - } - - mDataSend->sendChunkMap(peerId,hash,cmap,true); - - return true; -} - -bool ftDataMultiplex::handleRecvData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t /*size*/, uint64_t offset, uint32_t chunksize, void *data) -{ - ftTransferModule *transfer_module = NULL ; - - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - std::map::iterator it; - if (mClients.end() == (it = mClients.find(hash))) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() ERROR: No matching Client!"; - std::cerr << std::endl; -#endif - /* error */ - return false; - } - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() Passing to Module"; - std::cerr << std::endl; -#endif - - transfer_module = (it->second).mModule ; - } - transfer_module->recvFileData(peerId, offset, chunksize, data); - - return true; -} - - - /* called by ftTransferModule */ -bool ftDataMultiplex::handleRecvDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) -{ - /**** Find Files *****/ - - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - std::map::iterator cit; - if (mOwnId == peerId) - { - /* own requests must be passed to Servers */ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() OwnId, so skip Clients..."; - std::cerr << std::endl; -#endif - } - else if (mClients.end() != (cit = mClients.find(hash))) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() Matched to a Client."; - std::cerr << std::endl; -#endif - locked_handleServerRequest((cit->second).mCreator, peerId, hash, size, offset, chunksize); - return true; - } - - std::map::iterator sit; - if (mServers.end() != (sit = mServers.find(hash))) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() Matched to a Provider."; - std::cerr << std::endl; -#endif - locked_handleServerRequest(sit->second, peerId, hash, size, offset, chunksize); - return true; - } - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleRecvData() No Match... adding to Search Queue."; - std::cerr << std::endl; -#endif - - /* Add to Search Queue */ - mSearchQueue.push_back( ftRequest(FT_DATA_REQ, peerId, hash, size, offset, chunksize, NULL)); - - return true; -} - -bool ftDataMultiplex::locked_handleServerRequest(ftFileProvider *provider, const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, - uint64_t offset, uint32_t chunksize) -{ - if(chunksize > uint32_t(10*1024*1024)) - { - std::cerr << "Warning: peer " << peerId << " is asking a large chunk (s=" << chunksize << ") for hash " << hash << ", filesize=" << size << ". This is unexpected." << std::endl ; - return false ; - } - void *data = rs_malloc(chunksize); - - if(data == NULL) - return false ; - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::locked_handleServerRequest()"; - std::cerr << "\t peer: " << peerId << " hash: " << hash; - std::cerr << " size: " << size; - std::cerr << std::endl; - std::cerr << "\t offset: " << offset; - std::cerr << " chunksize: " << chunksize << " data: " << data; - std::cerr << std::endl; -#endif - - if (provider->getFileData(peerId,offset, chunksize, data)) - { - /* send data out */ - sendData(peerId, hash, size, offset, chunksize, data); - return true; - } -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::locked_handleServerRequest()"; - std::cerr << " FAILED"; - std::cerr << std::endl; -#endif - free(data); - - return false; -} - -bool ftDataMultiplex::getClientChunkMap(const RsFileHash& upload_hash,const RsPeerId& peerId,CompressedChunkMap& cmap) -{ - bool too_old = false; - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - std::map::iterator sit = mServers.find(upload_hash); - - if(mServers.end() == sit) - return false ; - - sit->second->getClientMap(peerId,cmap,too_old) ; - } - - // If the map is too old then we should ask an other map to the peer. - // - if(too_old) - sendChunkMapRequest(peerId,upload_hash,true); - - return true ; -} - -bool ftDataMultiplex::sendChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) -{ - return mDataSend->sendChunkMapRequest(peer_id,hash,is_client); -} -bool ftDataMultiplex::sendSingleChunkCRCRequests(const RsFileHash& hash, const std::vector& to_ask) -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - // Put all requested chunks in the request queue. - - Sha1CacheEntry& ce(_cached_sha1maps[hash]) ; - - for(uint32_t i=0;i& list(ce._to_ask[to_ask[i]]) ; - list.first = 0 ; // set last request time to 0 - } - return true ; -} - -void ftDataMultiplex::handlePendingCrcRequests() -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - rstime_t now = time(NULL) ; - uint32_t n=0 ; - - // Go through the list of currently handled hashes. For each of them, - // look for pending chunk crc requests. - // - if the last request is too old, re-ask: - // - ask the file creator about the possible sources for this chunk => returns a list of active sources - // - among active sources, pick the one that has the smallest request time stamp, in the request list. - // - // With this, only active sources are querried. - // - - for(std::map::iterator it(_cached_sha1maps.begin());it!=_cached_sha1maps.end();++it) - for(std::map >::iterator it2(it->second._to_ask.begin());it2!=it->second._to_ask.end();++it2) - if(it2->second.first + MAX_CHECKING_CHUNK_WAIT_DELAY < now) // is the last request old enough? - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): Requesting sources for chunk " << it2->first << ", hash " << it->first << std::endl; -#endif - // 0 - ask which sources can be used for this chunk - // - std::map::const_iterator it4(mClients.find(it->first)) ; - - if(it4 == mClients.end()) - continue ; - - std::vector sources ; - it4->second.mCreator->getSourcesList(it2->first,sources) ; - - // 1 - go through all sources. Take the oldest one. - // - - RsPeerId best_source ; - rstime_t oldest_timestamp = now ; - - for(uint32_t i=0;i::const_iterator it3(it2->second.second.find(sources[i])) ; - - if(it3 == it2->second.second.end()) // source not found. So this one is surely the oldest one to have been requested. - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): not found! So using it directly." << std::endl; -#endif - best_source = sources[i] ; - break ; - } - else if(it3->second <= oldest_timestamp) // do nothing, otherwise, ask again - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): not found! So using it directly." << std::endl; -#endif - best_source = sources[i] ; - oldest_timestamp = it3->second ; - } -#ifdef MPLEX_DEBUG - else - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): Source too recently used! So using it directly." << std::endl; -#endif - } - if(!best_source.isNull()) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): Asking crc of chunk " << it2->first << " to peer " << best_source << " for hash " << it->first << std::endl; -#endif - // Use the source to ask the CRC. - // - // sendSingleChunkCRCRequest(peer_id, hash, chunk_id) - // - mDataSend->sendSingleChunkCRCRequest(best_source,it->first,it2->first); - it2->second.second[best_source] = now ; - it2->second.first = now ; - - if(++n > MAX_SIMULTANEOUS_CRC_REQUESTS) - return ; - } -#ifdef MPLEX_DEBUG - else - std::cerr << "ftDataMultiplex::handlePendingCrcRequests(): no source for chunk " << it2->first << std::endl; -#endif - } -} - -void ftDataMultiplex::deleteUnusedServers() -{ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - //scan the uploads list in ftdatamultiplex and delete the items which time out - rstime_t now = time(NULL); - - for(std::map::iterator sit(mServers.begin());sit != mServers.end();) - if(sit->second->purgeOldPeers(now,10)) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::deleteUnusedServers(): provider " << (void*)sit->second << " has no active peers. Removing. Now=" << now << std::endl ; -#endif - // We don't delete servers that are clients at the same time ! - if(dynamic_cast(sit->second) == NULL) - { -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::deleteUnusedServers(): deleting file provider " << (void*)sit->second << std::endl ; -#endif - delete sit->second; - } -#ifdef MPLEX_DEBUG - else - std::cerr << "ftDataMultiplex::deleteUnusedServers(): " << (void*)sit->second << " was not deleted because it's also a file creator." << std::endl ; -#endif - - std::map::iterator tmp(sit); - ++tmp ; - - mServers.erase(sit); - - sit = tmp ; - } - else - ++sit ; -} - -bool ftDataMultiplex::handleSearchRequest(const RsPeerId& peerId, const RsFileHash& hash) -{ -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleSearchRequest("; - std::cerr << peerId << ", " << hash << "...)"; - std::cerr << std::endl; -#endif - - /* - * Do Actual search - * Could be Cache File, Local or Extra - * (anywhere but remote really) - * - * the network wide and browsable flags are needed, otherwise results get filtered. - * For tunnel creation, the check of browsable/network wide flag is already done, so - * if we get a file download packet here, the source is already allowed to download it. - * That is why we don't call the search function with a peer id. - * - */ - - FileInfo info; - FileSearchFlags hintflags = RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SPEC_ONLY ; - - if(rsTurtle->isTurtlePeer(peerId)) - hintflags |= RS_FILE_HINTS_NETWORK_WIDE ; - - if(mSearch->search(hash, hintflags, info)) - { - - /* setup a new provider */ - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - // We might already have a file provider, if two requests have got stacked in the request queue. So let's - // check that before. - -#ifdef MPLEX_DEBUG - std::cerr << "ftDataMultiplex::handleSearchRequest("; - std::cerr << " Found Local File, sharing..."; -#endif - std::map::const_iterator it = mServers.find(hash) ; - ftFileProvider *provider ; - - if(it == mServers.end()) - { - provider = new ftFileProvider(info.path, info.size, hash); - mServers[hash] = provider; -#ifdef MPLEX_DEBUG - std::cerr << " created new file provider " << (void*)provider << std::endl; -#endif - } - else - { -#ifdef MPLEX_DEBUG - std::cerr << " re-using existing file provider " << (void*)it->second << std::endl; -#endif - } - - return true; - } - // Now check wether the required file is actually being downloaded. In such a case, - // setup the file provider to be the file creator itself. Warning: this server should not - // be deleted when not used anymore. We need to restrict this to client peers that are - // not ourself, since the file transfer also handles the local cache traffic (this - // is something to be changed soon!!) - // - - if(peerId != mOwnId) - { - RsStackMutex stack(dataMtx); /******* LOCK MUTEX ******/ - - std::map::const_iterator it(mClients.find(hash)) ; - - if(it != mClients.end()) - { - mServers[hash] = it->second.mCreator ; - return true; - } - } - - return false; -} - - - - - diff --git a/libretroshare/src/ft/ftdatamultiplex.h b/libretroshare/src/ft/ftdatamultiplex.h deleted file mode 100644 index 019940b63..000000000 --- a/libretroshare/src/ft/ftdatamultiplex.h +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftdatamultiplex.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_DATA_MULTIPLEX_HEADER -#define FT_DATA_MULTIPLEX_HEADER - -/* - * ftDataMultiplexModule. - * - * This multiplexes the data from PQInterface to the ftTransferModules. - */ - -class ftTransferModule; -class ftFileProvider; -class ftFileCreator; -class ftSearch; - -#include -#include -#include -#include - -#include "util/rsthreads.h" - -#include "ft/ftdata.h" -#include "retroshare/rsfiles.h" - - -class ftClient -{ - public: - - ftClient() :mModule(NULL), mCreator(NULL) { return; } - ftClient(ftTransferModule *module, ftFileCreator *creator); - - ftTransferModule *mModule; - ftFileCreator *mCreator; -}; - -class ftRequest -{ - public: - - ftRequest(uint32_t type, const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunk, void *data); - - ftRequest() - :mType(0), mSize(0), mOffset(0), mChunk(0), mData(NULL) { return; } - - uint32_t mType; - RsPeerId mPeerId; - RsFileHash mHash; - uint64_t mSize; - uint64_t mOffset; - uint32_t mChunk; - void *mData; -}; - -typedef std::map ChunkCheckSumSourceList ; - -class Sha1CacheEntry -{ - public: - Sha1Map _map ; // Map of available sha1 sums for every chunk. - rstime_t last_activity ; // This is used for removing unused entries. - std::vector _received ; // received chunk ids. To bedispatched. - std::map > _to_ask ; // Chunks to ask to sources. -}; - -class ftDataMultiplex: public ftDataRecv, public RsQueueThread -{ - - public: - - ftDataMultiplex(const RsPeerId& ownId, ftDataSend *server, ftSearch *search); - - /** - * @see RsFiles::getFileData - * - * data should be pre-allocated by the client with size sufficient gfor requested_size bytes. - * requested_size will be changed so as to contain the actual number of bytes copied from the file, - * in case where the full size wasn't available. - * False is returned if no data can be obtained from that file. - */ - bool getFileData(const RsFileHash& hash, uint64_t offset,uint32_t& requested_size, uint8_t *data); - - /* ftController Interface */ - bool addTransferModule(ftTransferModule *mod, ftFileCreator *f); - bool removeTransferModule(const RsFileHash& hash); - - /* data interface */ - /* get Details of File Transfers */ - bool FileUploads(std::list &hashs); - bool FileDownloads(std::list &hashs); - bool FileDetails(const RsFileHash &hash, FileSearchFlags hintsflag, FileInfo &info); - - void deleteUnusedServers() ; - void handlePendingCrcRequests() ; - - - /*************** SEND INTERFACE (calls ftDataSend) *******************/ - - /* Client Send */ - bool sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); - - /* Server Send */ - bool sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); - - /* Server/client Send */ - bool sendChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash,bool is_client) ; - - - /* called from a separate thread */ - bool sendSingleChunkCRCRequests(const RsFileHash& hash, const std::vector& to_ask) ; - - bool dispatchReceivedChunkCheckSum() ; - - /*************** RECV INTERFACE (provides ftDataRecv) ****************/ - - /* Client Recv */ - virtual bool recvData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); - /* Server Recv */ - virtual bool recvDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); - - /// Receive a request for a chunk map - virtual bool recvChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) ; - /// Receive a chunk map - virtual bool recvChunkMap(const RsPeerId& peer_id,const RsFileHash& hash,const CompressedChunkMap& cmap,bool is_client) ; - - virtual bool recvSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_id) ; - virtual bool recvSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_id,const Sha1CheckSum& sum) ; - - // Returns the chunk map from the file uploading client. Also initiates a chunk map request if this - // map is too old. This supposes that the caller will ask again in a few seconds. - // - bool getClientChunkMap(const RsFileHash& upload_hash,const RsPeerId& peer_id,CompressedChunkMap& map) ; - - protected: - - /* Overloaded from RsQueueThread */ - virtual bool workQueued(); - virtual bool doWork(); - - private: - - /* Handling Job Queues */ - bool handleRecvData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); - bool handleRecvDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); - bool handleSearchRequest(const RsPeerId& peerId, const RsFileHash& hash); - bool handleRecvClientChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash) ; - bool handleRecvServerChunkMapRequest(const RsPeerId& peerId, const RsFileHash& hash) ; - bool handleRecvChunkCrcRequest(const RsPeerId& peerId, const RsFileHash& hash,uint32_t chunk_id) ; - - /* We end up doing the actual server job here */ - bool locked_handleServerRequest(ftFileProvider *provider, const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); - - RsMutex dataMtx; - - std::map mClients; - std::map mServers; - - std::list mRequestQueue; - std::list mSearchQueue; - - std::map _cached_sha1maps ; // one cache entry per file hash. Handled dynamically. - - ftDataSend *mDataSend; - ftSearch *mSearch; - RsPeerId mOwnId; - - friend class ftServer; -}; - -#endif diff --git a/libretroshare/src/ft/ftextralist.cc b/libretroshare/src/ft/ftextralist.cc deleted file mode 100644 index 3912cc1b3..000000000 --- a/libretroshare/src/ft/ftextralist.cc +++ /dev/null @@ -1,538 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftextralist.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2008 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include - -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif - -#include -#include -#include "ft/ftextralist.h" -#include "rsitems/rsconfigitems.h" -#include "util/rsdir.h" -#include "util/rstime.h" -#include -#include /* for (u)sleep() */ -#include "util/rstime.h" - -/****** - * #define DEBUG_ELIST 1 - *****/ - -ftExtraList::ftExtraList() - :p3Config(), extMutex("p3Config") -{ - cleanup = 0; - return; -} - - -void ftExtraList::threadTick() -{ - bool todo = false; - rstime_t now = time(NULL); - - { - RsStackMutex stack(extMutex); - - todo = (mToHash.size() > 0); - } - - if (todo) - { - /* Hash a file */ - hashAFile(); - - /* microsleep */ - rstime::rs_usleep(10); - } - else - { - /* cleanup */ - if (cleanup < now) - { - cleanupOldFiles(); - cleanup = now + CLEANUP_PERIOD; - } - - /* sleep */ -#ifdef WIN32 - Sleep(1000); -#else - sleep(1); -#endif - } -} - - - -void ftExtraList::hashAFile() -{ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::hashAFile()"; - std::cerr << std::endl; -#endif - - /* extract entry from the queue */ - FileDetails details; - - { - RS_STACK_MUTEX(extMutex); - - if (mToHash.empty()) - return; - - details = mToHash.front(); - mToHash.pop_front(); - } - -#ifdef DEBUG_ELIST - std::cerr << "Hashing: " << details.info.path; - std::cerr << std::endl; -#endif - - /* hash it! */ - std::string name, hash; - //uint64_t size; - if (RsDirUtil::hashFile(details.info.path, details.info.fname, details.info.hash, details.info.size)) - { - RS_STACK_MUTEX(extMutex); - - /* stick it in the available queue */ - mFiles[details.info.hash] = details; - mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; - - /* add to the path->hash map */ - mHashedList[details.info.path] = details.info.hash; - - IndicateConfigChanged(); - - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_ADDED; - if(rsEvents) - rsEvents->postEvent(ev); - } -} - - /*** - * If the File is alreay Hashed, then just add it in. - **/ - -bool ftExtraList::addExtraFile(std::string path, const RsFileHash& hash, - uint64_t size, uint32_t period, TransferRequestFlags flags) -{ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::addExtraFile() path: " << path; - std::cerr << " hash: " << hash; - std::cerr << " size: " << size; - std::cerr << " period: " << period; - std::cerr << " flags: " << flags; - - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(extMutex); - - FileDetails details; - - details.info.path = path; - details.info.fname = RsDirUtil::getTopDir(path); - details.info.hash = hash; - details.info.size = size; - details.info.age = time(NULL) + period; /* if time > this... cleanup */ - details.info.transfer_info_flags = flags ; - - /* stick it in the available queue */ - mFiles[details.info.hash] = details; - mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; - - IndicateConfigChanged(); - - return true; -} - -bool ftExtraList::removeExtraFile(const RsFileHash& hash) -{ - /* remove unused parameter warnings */ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::removeExtraFile()"; - std::cerr << " hash: " << hash; - std::cerr << " flags: " << flags; - - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(extMutex); - - mHashOfHash.erase(makeEncryptedHash(hash)) ; - - std::map::iterator it; - it = mFiles.find(hash); - if (it == mFiles.end()) - { - return false; - } - - mFiles.erase(it); - - IndicateConfigChanged(); - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mEventCode = RsSharedDirectoriesEventCode::EXTRA_LIST_FILE_REMOVED; - rsEvents->postEvent(ev); - } - return true; -} - -bool ftExtraList::moveExtraFile(std::string fname, const RsFileHash &hash, uint64_t /*size*/, - std::string destpath) -{ - RsStackMutex stack(extMutex); - - std::map::iterator it; - it = mFiles.find(hash); - if (it == mFiles.end()) - { - return false; - } - - std::string path = destpath + '/' + fname; - if (RsDirUtil::renameFile(it->second.info.path, path)) - { - /* rename */ - it->second.info.path = path; - it->second.info.fname = fname; - IndicateConfigChanged(); - } - - return true; -} - - - -bool ftExtraList::cleanupOldFiles() -{ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::cleanupOldFiles()"; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(extMutex); - - rstime_t now = time(NULL); - - std::list toRemove; - - for( std::map::iterator it = mFiles.begin(); it != mFiles.end(); ++it) /* check timestamps */ - if ((rstime_t)it->second.info.age < now) - toRemove.push_back(it->first); - - if (toRemove.size() > 0) - { - std::map::iterator it; - - /* remove items */ - for(std::list::iterator rit = toRemove.begin(); rit != toRemove.end(); ++rit) - { - if (mFiles.end() != (it = mFiles.find(*rit))) mFiles.erase(it); - mHashOfHash.erase(makeEncryptedHash(*rit)); - } - - IndicateConfigChanged(); - } - return true; -} - -bool ftExtraList::hashExtraFile( - std::string path, uint32_t period, TransferRequestFlags flags ) -{ - constexpr rstime_t max_int = std::numeric_limits::max(); - const rstime_t now = time(nullptr); - const rstime_t timeOut = now + period; - - if(timeOut > max_int) - { - /* Under the hood period is stored as int FileInfo::age so we do this - * check here to detect 2038 year problem - * https://en.wikipedia.org/wiki/Year_2038_problem */ - RsErr() << __PRETTY_FUNCTION__ << " period: " << period << " > " - << max_int - now << std::errc::value_too_large << std::endl; - return false; - } - - if(!RsDirUtil::fileExists(path)) - { - RsErr() << __PRETTY_FUNCTION__ << " path: " << path - << std::errc::no_such_file_or_directory << std::endl; - return false; - } - - if(RsDirUtil::checkDirectory(path)) - { - RsErr() << __PRETTY_FUNCTION__ << " path: " << path - << std::errc::is_a_directory << std::endl; - return false; - } - - FileDetails details(path, period, flags); - details.info.age = static_cast(timeOut); - - { - RS_STACK_MUTEX(extMutex); - mToHash.push_back(details); /* add into queue */ - } - - return true; -} - -bool ftExtraList::hashExtraFileDone(std::string path, FileInfo &info) -{ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::hashExtraFileDone()"; - std::cerr << std::endl; -#endif - - RsFileHash hash; - { - /* Find in the path->hash map */ - RS_STACK_MUTEX(extMutex); - - std::map::iterator it; - if (mHashedList.end() == (it = mHashedList.find(path))) - { - return false; - } - hash = it->second; - } - return search(hash, FileSearchFlags(0), info); -} - - /*** - * Search Function - used by File Transfer - * - **/ -bool ftExtraList::search(const RsFileHash &hash, FileSearchFlags /*hintflags*/, FileInfo &info) const -{ -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::search() hash=" << hash ; -#endif - - /* find hash */ - std::map::const_iterator fit; - if (mFiles.end() == (fit = mFiles.find(hash))) - { -#ifdef DEBUG_ELIST - std::cerr << " not found in mFiles. Trying encrypted... " ; -#endif - // File not found. We try to look for encrypted hash. - - std::map::const_iterator hit = mHashOfHash.find(hash) ; - - if(hit == mHashOfHash.end()) - { -#ifdef DEBUG_ELIST - std::cerr << " not found." << std::endl; -#endif - return false; - } -#ifdef DEBUG_ELIST - std::cerr << " found! Reaching data..." ; -#endif - - fit = mFiles.find(hit->second) ; - - if(fit == mFiles.end()) // not found. This is an error. - { -#ifdef DEBUG_ELIST - std::cerr << " no data. Returning false." << std::endl; -#endif - return false ; - } - -#ifdef DEBUG_ELIST - std::cerr << " ok! Accepting encrypted transfer." << std::endl; -#endif - info = fit->second.info; - info.storage_permission_flags = FileStorageFlags(DIR_FLAGS_ANONYMOUS_DOWNLOAD) ; - info.transfer_info_flags |= RS_FILE_REQ_ENCRYPTED ; - } - else - { -#ifdef DEBUG_ELIST - std::cerr << " found! Accepting direct transfer" << std::endl; -#endif - info = fit->second.info; - - // Unencrypted file transfer: We only allow direct transfers. This is not exactly secure since another friend can - // swarm the file. But the hash being kept secret, there's no risk here. - // - info.storage_permission_flags = FileStorageFlags(DIR_FLAGS_BROWSABLE) ; - } - - if(info.transfer_info_flags & RS_FILE_REQ_ANONYMOUS_ROUTING) info.storage_permission_flags |= DIR_FLAGS_ANONYMOUS_DOWNLOAD ; - - return true; -} - -RsFileHash ftExtraList::makeEncryptedHash(const RsFileHash& hash) -{ - return RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES); -} - - /*** - * Configuration - store extra files. - * - **/ - -RsSerialiser *ftExtraList::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser(); - - /* add in the types we need! */ - rss->addSerialType(new RsFileConfigSerialiser()); - return rss; -} - -bool ftExtraList::saveList(bool &cleanup, std::list& sList) -{ - - - cleanup = true; - - /* called after each item is added */ - - /* create a list of fileitems with - * age used to specify its timeout. - */ - -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::saveList()"; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(extMutex); - - - std::map::const_iterator it; - for(it = mFiles.begin(); it != mFiles.end(); ++it) - { - RsFileConfigItem *fi = new RsFileConfigItem(); - - fi->file.path = (it->second).info.path; - fi->file.name = (it->second).info.fname; - fi->file.hash = (it->second).info.hash; - fi->file.filesize = (it->second).info.size; - fi->file.age = (it->second).info.age; - fi->flags = (it->second).info.transfer_info_flags.toUInt32(); - - sList.push_back(fi); - } - - return true; -} - - -bool ftExtraList::loadList(std::list& load) -{ - /* for each item, check it exists .... - * - remove any that are dead (or flag?) - */ - -#ifdef DEBUG_ELIST - std::cerr << "ftExtraList::loadList()"; - std::cerr << std::endl; -#endif - - rstime_t ts = time(NULL); - - - std::list::iterator it; - for(it = load.begin(); it != load.end(); ++it) - { - - RsFileConfigItem *fi = dynamic_cast(*it); - if (!fi) - { - delete (*it); - continue; - } - - /* open file */ - FILE *fd = RsDirUtil::rs_fopen(fi->file.path.c_str(), "rb"); - if (fd == NULL) - { - delete (*it); - continue; - } - - fclose(fd); - fd = NULL ; - - if (ts > (rstime_t)fi->file.age) - { - /* too old */ - delete (*it); - continue ; - } - - /* add into system */ - FileDetails file; - - RS_STACK_MUTEX(extMutex); - - FileDetails details; - - details.info.path = fi->file.path; - details.info.fname = fi->file.name; - details.info.hash = fi->file.hash; - details.info.size = fi->file.filesize; - details.info.age = fi->file.age; /* time that we remove it. */ - details.info.transfer_info_flags = TransferRequestFlags(fi->flags); - - /* stick it in the available queue */ - mFiles[details.info.hash] = details; - mHashOfHash[makeEncryptedHash(details.info.hash)] = details.info.hash ; - - delete (*it); - - /* short sleep */ - rstime::rs_usleep(1000) ; - } - load.clear() ; - return true; -} - -void ftExtraList::getExtraFileList(std::vector& files) const -{ - RS_STACK_MUTEX(extMutex); - - files.clear(); - - for(auto it(mFiles.begin());it!=mFiles.end();++it) - files.push_back(it->second.info); -} diff --git a/libretroshare/src/ft/ftextralist.h b/libretroshare/src/ft/ftextralist.h deleted file mode 100644 index 229c0fe3c..000000000 --- a/libretroshare/src/ft/ftextralist.h +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftextralist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_FILE_EXTRA_LIST_HEADER -#define FT_FILE_EXTRA_LIST_HEADER - -/* - * ftFileExtraList - * - * This maintains a list of 'Extra Files' to share with peers. - * - * Files are added via: - * 1) For Files which have been hashed already: - * addExtraFile(std::string path, std::string hash, uint64_t size, uint32_t period, uint32_t flags); - * - * 2) For Files to be hashed: - * hashExtraFile(std::string path, uint32_t period, uint32_t flags); - * - * Results of Hashing can be retrieved via: - * hashExtraFileDone(std::string path, std::string &hash, uint64_t &size); - * - * Files can be searched for via: - * searchExtraFiles(std::string hash, ftFileDetail file); - * - * This Class is Mutexed protected, and has a thread in it which checks the files periodically. - * If a file is found to have changed... It is discarded from the list - and not updated. - * - * this thread is also used to hash added files. - * - * The list of extra files is stored using the configuration system. - * - */ - -#include -#include -#include - -#include "ft/ftsearch.h" -#include "util/rsthreads.h" -#include "retroshare/rsfiles.h" -#include "pqi/p3cfgmgr.h" -#include "util/rstime.h" - -class RS_DEPRECATED_FOR(FileInfo) FileDetails -{ - public: - FileDetails() - { - return; - } - - FileDetails(std::string path, uint32_t /*p*/, TransferRequestFlags f) - { - info.path = path; -// period = p; - info.transfer_info_flags = f; - } - - FileDetails(FileInfo &i, uint32_t /*p*/, TransferRequestFlags f) - { - info = i; - // period = p; - info.transfer_info_flags = f; - } - - FileInfo info; - -#if 0 /*** WHAT IS NEEDED ***/ - std::list sources; - std::string path; - std::string fname; - RsFileHash hash; - uint64_t size; -#endif - - //uint32_t start; - //uint32_t period; - //TransferRequestFlags flags; -}; - -const uint32_t FT_DETAILS_CLEANUP = 0x0100; /* remove when it expires */ -const uint32_t FT_DETAILS_LOCAL = 0x0001; -const uint32_t FT_DETAILS_REMOTE = 0x0002; - -const uint32_t CLEANUP_PERIOD = 600; /* 10 minutes */ - - -class ftExtraList: public RsTickingThread, public p3Config, public ftSearch -{ - -public: - - ftExtraList(); - - /*** - * If the File is alreay Hashed, then just add it in. - **/ - - bool addExtraFile(std::string path, const RsFileHash &hash, - uint64_t size, uint32_t period, TransferRequestFlags flags); - - bool removeExtraFile(const RsFileHash& hash); - bool moveExtraFile(std::string fname, const RsFileHash& hash, uint64_t size, - std::string destpath); - - - uint32_t size() const { return mFiles.size() ; } - - /*** - * Hash file, and add to the files, - * file is removed after period. - **/ - - /** - * Hash file, and add to the files, file is removed after period. - */ - bool hashExtraFile( - std::string path, uint32_t period, TransferRequestFlags flags ); - bool hashExtraFileDone(std::string path, FileInfo &info); - - /*** - * Search Function - used by File Transfer - * implementation of ftSearch. - * - **/ - virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; - - /*! - * \brief getExtraFileList - * Retrieves the list for display purposes - */ - void getExtraFileList(std::vector& files) const ; - - void threadTick() override; /// @see RsTickingThread - - /*** - * Configuration - store extra files. - * - **/ - -protected: - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual bool loadList(std::list& load); - - static RsFileHash makeEncryptedHash(const RsFileHash& hash); - -private: - - /* Worker Functions */ - void hashAFile(); - bool cleanupOldFiles(); - - mutable RsMutex extMutex; - - std::list mToHash; - - std::map mHashedList; /* path -> hash ( not saved ) */ - std::map mFiles; - std::map mHashOfHash; /* sha1(hash) map so as to answer requests to encrypted transfers */ - - rstime_t cleanup ; -}; - - - - -#endif diff --git a/libretroshare/src/ft/ftfilecreator.cc b/libretroshare/src/ft/ftfilecreator.cc deleted file mode 100644 index a5c354092..000000000 --- a/libretroshare/src/ft/ftfilecreator.cc +++ /dev/null @@ -1,762 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfilecreator.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef WINDOWS_SYS -#include "util/rsstring.h" -#include "util/rswin.h" -#endif - -#include "ftfilecreator.h" -#include -#include -#include "util/rstime.h" -#include -#include -#include - -/******* - * #define FILE_DEBUG 1 - ******/ - -#define CHUNK_MAX_AGE 120 -#define MAX_FTCHUNKS_PER_PEER 20 - -/*********************************************************** -* -* ftFileCreator methods -* -***********************************************************/ - -ftFileCreator::ftFileCreator(const std::string& path, uint64_t size, const RsFileHash& hash,bool assume_availability) - : ftFileProvider(path,size,hash), chunkMap(size,assume_availability) -{ - /* - * FIXME any inits to do? - */ - -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator()"; - std::cerr << std::endl; - std::cerr << "\tpath: " << path; - std::cerr << std::endl; - std::cerr << "\tsize: " << size; - std::cerr << std::endl; - std::cerr << "\thash: " << hash; - std::cerr << std::endl; -#endif - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - rstime_t now = time(NULL) ; - _creation_time = now ; - - struct stat64 buf; - - // Initialise last recv time stamp to last modification time for the partial file. - // -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(file_name, wfullname); - if ( 0 == _wstati64(wfullname.c_str(), &buf)) -#else - if ( 0 == stat64(file_name.c_str(), &buf)) -#endif - _last_recv_time_t = buf.st_mtime ; - else - _last_recv_time_t = now ; - -#ifdef FILE_DEBUG - std::cerr << "Inited last modification time for hash " << hash << " to " << _last_recv_time_t << std::endl; -#endif -} - -bool ftFileCreator::getFileData(const RsPeerId& peer_id,uint64_t offset, uint32_t &chunk_size, void *data, bool allow_unverified) -{ - // Only send the data if we actually have it. - // -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::getFileData(). Asked for offset=" << offset << ", size=" << chunk_size << std::endl ; -#endif - bool have_it = false ; - { - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - have_it = chunkMap.isChunkAvailable(offset, chunk_size) ; - -#define ENABLE_SLICES -#ifdef ENABLE_SLICES - // try if we have data from an incomplete or not veryfied chunk - if(!have_it && allow_unverified) - { - //std::map::iterator it; - have_it = true; - // this map contains chunks which are currently being downloaded - for(std::map::iterator it=mChunks.begin(); it!=mChunks.end(); ++it) - { - ftChunk chunk = it->second; - // begin of slice is in requested range - if(chunk.offset >= offset && chunk.offset < (offset+chunk_size)) - { - // reduce the requested size - chunk_size = chunk.offset - offset; - } - // end of slice is in requested range - if((chunk.offset+chunk.size) >= offset && (chunk.offset+chunk.size) < (offset+chunk_size)) - { - // can do nothing about this - have_it = false; - } - } - // check if the chunk was already started to download - // if not, we don't have it - if(chunkMap.isChunkOutstanding(offset, chunk_size)) - have_it = false; - } -#endif - } -#ifdef FILE_DEBUG - if(have_it) - std::cerr << "ftFileCreator::getFileData(). Have it" << std::endl ; - else - std::cerr << "ftFileCreator::getFileData(). Don't have it" << std::endl ; -#endif - - if(have_it) - return ftFileProvider::getFileData(peer_id,offset, chunk_size, data); - else - return false ; -} - -rstime_t ftFileCreator::creationTimeStamp() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return _creation_time ; -} -rstime_t ftFileCreator::lastRecvTimeStamp() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return _last_recv_time_t ; -} - -void ftFileCreator::closeFile() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - if(fd != NULL) - { -#ifdef FILE_DEBUG - std::cerr << "CLOSED FILE " << (void*)fd << " (" << file_name << ")." << std::endl ; -#endif - fclose(fd) ; - } - - fd = NULL ; -} - -uint64_t ftFileCreator::getRecvd() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return chunkMap.getTotalReceived() ; -} - -bool ftFileCreator::addFileData(uint64_t offset, uint32_t chunk_size, void *data) -{ -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::addFileData("; - std::cerr << offset; - std::cerr << ", " << chunk_size; - std::cerr << ", " << data << ")"; - std::cerr << " this: " << this; - std::cerr << std::endl; -#endif - /* dodgey checking outside of mutex... much check again inside FileAttrs(). */ - /* Check File is open */ - - if(!RsDiscSpace::checkForDiscSpace(RS_PARTIALS_DIRECTORY)) - return false ; - - bool complete = false ; - { - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - if (fd == NULL) - if (!locked_initializeFileAttrs()) - return false; - - /* - * check its at the correct location - */ - if (offset + chunk_size > mSize) - { - chunk_size = mSize - offset; - std::cerr <<"Chunk Size greater than total file size, adjusting chunk size " << chunk_size << std::endl; - - } - - /* - * go to the offset of the file - */ - if (0 != fseeko64(this->fd, offset, SEEK_SET)) - { - std::cerr << "ftFileCreator::addFileData() Bad fseek at offset " << offset << ", fd=" << (void*)(this->fd) << ", size=" << mSize << ", errno=" << errno << std::endl; - return 0; - } - - if (1 != fwrite(data, chunk_size, 1, this->fd)) - { - std::cerr << "ftFileCreator::addFileData() Bad fwrite." << std::endl; - std::cerr << "ERRNO: " << errno << std::endl; - - return 0; - } - -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::addFileData() added Data..."; - std::cerr << std::endl; - std::cerr << " pos: " << offset; - std::cerr << std::endl; -#endif - /* - * Notify ftFileChunker about chunks received - */ - locked_notifyReceived(offset,chunk_size); - - complete = chunkMap.isComplete(); - } - if(complete) - { -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::addFileData() File is complete: closing" << std::endl ; -#endif - closeFile(); - } - - /* - * FIXME HANDLE COMPLETION HERE - Any better way? - */ - - return 1; -} - -void ftFileCreator::removeInactiveChunks() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::removeInactiveChunks(): looking for old chunks." << std::endl ; -#endif - std::vector to_remove ; - - chunkMap.removeInactiveChunks(to_remove) ; - -#ifdef FILE_DEBUG - if(!to_remove.empty()) - std::cerr << "ftFileCreator::removeInactiveChunks(): removing slice ids: " ; -#endif - // This double loop looks costly, but it's called on very few chunks, and not often, so it's ok. - // - for(uint32_t i=0;i::iterator it(mChunks.begin());it!=mChunks.end();) - if(it->second.id == to_remove[i]) - { - std::map::iterator tmp(it) ; - ++it ; - if(--*tmp->second.ref_cnt == 0) - delete tmp->second.ref_cnt; - --mChunksPerPeer[tmp->second.peer_id].cnt ; - mChunks.erase(tmp) ; - } - else - ++it ; - } -#ifdef FILE_DEBUG - if(!to_remove.empty()) - std::cerr << std::endl ; -#endif -} - -void ftFileCreator::removeFileSource(const RsPeerId& peer_id) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator:: removign file source " << peer_id << " from chunkmap." << std::endl ; -#endif - chunkMap.removeFileSource(peer_id) ; -} - -int ftFileCreator::locked_initializeFileAttrs() -{ -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::initializeFileAttrs() Filename: " << file_name << " this: " << this << std::endl; -#endif - - /* - * check if the file exists - * cant use FileProviders verion because that opens readonly. - */ - - if (fd) - return 1; - - /* - * check if the file exists - */ - - { -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::initializeFileAttrs() trying (r+b) " << file_name << " this: " << this << std::endl; -#endif - } - - /* - * attempt to open file - */ - - fd = RsDirUtil::rs_fopen(file_name.c_str(), "r+b"); - - if (!fd) - { -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::initializeFileAttrs() Failed to open (r+b): "; - std::cerr << file_name << ", errno = " << errno << std::endl; - - std::cerr << "ftFileCreator::initializeFileAttrs() opening w+b"; - std::cerr << std::endl; -#endif - - /* try opening for write */ - fd = RsDirUtil::rs_fopen(file_name.c_str(), "w+b"); - if (!fd) - { - std::cerr << "ftFileCreator::initializeFileAttrs()"; - std::cerr << " Failed to open (w+b): "<< file_name << ", errno = " << errno << std::endl; - return 0; - } - } -#ifdef FILE_DEBUG - std::cerr << "OPENNED FILE " << (void*)fd << " (" << file_name << "), for r/w." << std::endl ; -#endif - - return 1; -} -ftFileCreator::~ftFileCreator() -{ -#ifdef FILE_DEBUG - std::cerr << "Deleting file creator for " << file_name << std::endl; -#endif - - // Note: The file is actually closed in the parent, that is always a ftFileProvider. - // - /* - * FIXME Any cleanups specific to filecreator? - */ -} - - -int ftFileCreator::locked_notifyReceived(uint64_t offset, uint32_t chunk_size) -{ - /* ALREADY LOCKED */ -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::locked_notifyReceived( " << offset; - std::cerr << ", " << chunk_size << " )"; - std::cerr << " this: " << this; - std::cerr << std::endl; -#endif - - /* find the chunk */ - std::map::iterator it = mChunks.find(offset); - ftChunk chunk ; - - if(it == mChunks.end()) - { - // Chunk is not found. Maybe that is because the packet is in the middle - // of an existing chunk. This case occurs whenever a packet is lost due - // to temporarily interrupted connection. In such a case we split the - // chunk. Any pending block will be re-asked to the source after 40 secs. - // -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::locked_notifyReceived(): Failed to match to existing chunk. A packet was probably dropped. Strategy is:" << std::endl; - std::cerr << " - find corresponding chunk, split it in two pieces and ask again the first part." << std::endl; - - locked_printChunkMap(); -#endif - bool found = false ; - - for(std::map::iterator it2=mChunks.begin();it2!=mChunks.end();++it2) - if( it2->second.offset < offset && it2->second.size+it2->second.offset >= chunk_size+offset) // found it if it started strictly after the beginning of the chunk and ends before its end. - { - it = it2 ; -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::locked_notifyReceived(): Chunk found: " << it->second.offset << " to " << it->second.offset + it->second.size << std::endl; -#endif - - // 1 - split the chunk into two parts. Re-ask the first part, and keep the second part - // as ongoing. - - ftChunk part1( it->second ); - part1.size = offset - it->second.offset ; // always > 0 - - chunk = it->second ; // saves the data, as it will be erased by next line - mChunks[part1.offset] = part1; - - chunk.offset = offset ; - chunk.size -= part1.size ; - - // 2 - we need to be extra careful: - // - the chunks will have the same id. That's potentially a problem for completing the slice - // we should keep a list of pending chunkIds, so as to only call chunkMap.dataReceived() when - // all parts are obtained. - // - new parts arriving in the second part cannot interfere since they should come in order. - - ++(*chunk.ref_cnt) ; - -#ifdef FILE_DEBUG - std::cerr << "Created two sub chunks. Ref_cnt = " << *chunk.ref_cnt << std::endl; - std::cerr << " chunk1: " << part1 << std::endl; - std::cerr << " chunk2: " << chunk << std::endl; -#endif - - found = true ; - break ; - } - - if(!found) - { -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::locked_notifyReceived(): failed to find an active slice for " << offset << "+" << chunk_size << ", hash = " << hash << ": dropping data." << std::endl; -#endif - return 0; /* ignoring */ - } - } - else - { - chunk = it->second; - mChunks.erase(it); - } - - if (chunk.size != chunk_size) - { - /* partial : shrink chunk */ - chunk.size -= chunk_size; - chunk.offset += chunk_size; - mChunks[chunk.offset] = chunk; - } - else if( --*chunk.ref_cnt == 0) // notify the chunkmap that the slice is finished, and decrement the number of chunks for this peer. - { -#ifdef FILE_DEBUG - std::cerr << "Chunk finished and ref cnt = " << *chunk.ref_cnt << ": deleting." << std::endl; -#endif - chunkMap.dataReceived(chunk.id) ; - --mChunksPerPeer[chunk.peer_id].cnt ; - delete chunk.ref_cnt ; // delete the counter - } -#ifdef FILE_DEBUG - else - std::cerr << "Chunk finished but ref cnt = " << *chunk.ref_cnt << ": not deleting." << std::endl; -#endif - - _last_recv_time_t = time(NULL) ; - - /* otherwise there is another earlier block to go - */ - - return 1; -} - -FileChunksInfo::ChunkStrategy ftFileCreator::getChunkStrategy() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - return chunkMap.getStrategy() ; -} -void ftFileCreator::setChunkStrategy(FileChunksInfo::ChunkStrategy s) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - // Let's check, for safety. - if(s != FileChunksInfo::CHUNK_STRATEGY_STREAMING && s != FileChunksInfo::CHUNK_STRATEGY_RANDOM && s != FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE) - { - std::cerr << "ftFileCreator::ERROR: invalid chunk strategy " << s << "!" << " setting default value " << FileChunksInfo::CHUNK_STRATEGY_STREAMING << std::endl ; - s = FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE ; - } - -#ifdef FILE_DEBUG - std::cerr << "ftFileCtreator: setting chunk strategy to " << s << std::endl ; -#endif - chunkMap.setStrategy(s) ; -} - -/* Returns true if more to get - * But can return size = 0, if we are still waiting for the data. - */ - -bool ftFileCreator::getMissingChunk(const RsPeerId& peer_id,uint32_t size_hint,uint64_t &offset, uint32_t& size,bool& source_chunk_map_needed) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ -#ifdef FILE_DEBUG - std::cerr << "ffc::getMissingChunk(...,"<< size_hint << ")"; - std::cerr << " this: " << this; - std::cerr << std::endl; - locked_printChunkMap(); -#endif - source_chunk_map_needed = false ; - rstime_t now = time(NULL) ; - - // 0 - is there a faulting chunk that would need to be asked again ? - - for(std::map::iterator it(mChunks.begin());it!=mChunks.end();++it) - if(it->second.ts + CHUNK_MAX_AGE < now && chunkMap.getSourceChunksInfo(peer_id)->hasData(it->second.offset,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE)) - { - offset = it->second.offset ; - size = it->second.size ; - it->second.ts = now ; - -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::getMissingChunk(): re-asking for chunk that wasn't received: " << offset << " + " << size << std::endl; -#endif - return true ; - } - - // 1 - is there an ongoing 1MB chunk for which we need to take a new slice? - // - uint32_t& chunks_for_this_peer(mChunksPerPeer[peer_id].cnt) ; - - if(chunks_for_this_peer >= MAX_FTCHUNKS_PER_PEER) - { -#ifdef FILE_DEBUG - std::cerr << "ffc::getMissingChunk() too many chunks for peer " << peer_id << " for hash " << hash << ". Count = " << chunks_for_this_peer << std::endl ; -#endif - return false ; - } - - /* else allocate a new chunk */ - - ftChunk chunk ; - - if(!chunkMap.getDataChunk(peer_id,size_hint,chunk,source_chunk_map_needed)) - { - // No chunks are available. We brutally re-ask an ongoing chunk to another peer. - - if(chunkMap.reAskPendingChunk(peer_id,size_hint,offset,size)) - return true ; - - return false ; - } - -#ifdef FILE_DEBUG - std::cerr << "ffc::getMissingChunk() Retrieved new chunk: " << chunk << std::endl ; -#endif - - chunk.ref_cnt = new int ; - *chunk.ref_cnt = 1 ; - mChunks[chunk.offset] = chunk ; - - offset = chunk.offset ; - // cppcheck-suppress unreadVariable - size = chunk.size ; - - ++chunks_for_this_peer ; // increase number of chunks for this peer. - - return true; /* cos more data to get */ -} - -void ftFileCreator::getChunkMap(FileChunksInfo& info) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - chunkMap.getChunksInfo(info) ; - - // add info pending requests, handled by ftFileCreator - // - info.pending_slices.clear(); - - for(std::map::iterator it = mChunks.begin();it!=mChunks.end();++it) - { - int n = it->second.id / info.chunk_size ; - - FileChunksInfo::SliceInfo si ; - si.start = it->second.offset - n*info.chunk_size ; - si.size = it->second.size ; - si.peer_id = it->second.peer_id ; - - info.pending_slices[n].push_back(si) ; - } -} - -bool ftFileCreator::locked_printChunkMap() -{ -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator::locked_printChunkMap()"; - std::cerr << " this: " << this; - std::cerr << std::endl; -#endif - - /* check start point */ - std::cerr << "\tOutstanding Chunks:"; - std::cerr << std::endl; - - std::map::iterator it; - - for(it = mChunks.begin(); it != mChunks.end(); ++it) - std::cerr << " " << it->second << std::endl ; - - std::cerr << "Active chunks per peer:" << std::endl ; - for(std::map::const_iterator it(mChunksPerPeer.begin());it!=mChunksPerPeer.end();++it) - std::cerr << " " << it->first << "\t: " << it->second.cnt << std::endl; - - return true; -} - -void ftFileCreator::setAvailabilityMap(const CompressedChunkMap& cmap) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - chunkMap.setAvailabilityMap(cmap) ; -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator: setting chunkmap for hash " << hash << ": " ; - - for(uint32_t i=0;iis_full ; -} - -void ftFileCreator::setSourceMap(const RsPeerId& peer_id,const CompressedChunkMap& compressed_map) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - -#ifdef FILE_DEBUG - std::cerr << "ftFileCreator:: Received source map for hash " << hash << " for source peer " << peer_id << std::endl; -#endif - // At this point, we should cancel all file chunks that are asked to the - // peer and which this peer actually doesn't possesses. Otherwise, the transfer may get stuck. - // This should be done by: - // - first setting the peer availability map - // - then asking the chunkmap which chunks are being downloaded, but actually shouldn't - // - cancelling them in the ftFileCreator, so that they can be re-asked later to another peer. - // - chunkMap.setPeerAvailabilityMap(peer_id,compressed_map) ; -} - -bool ftFileCreator::finished() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - return chunkMap.isComplete() ; -} - -bool ftFileCreator::hashReceivedData(RsFileHash& hash) -{ -#ifdef FILE_DEBUG - std::cerr << "file creator asked for hashing received data " << file_name << std::endl; -#endif - - // csoler: No mutex here please ! - // - // This is a bit dangerous, but otherwise we might stuck the GUI for a - // long time. Therefore, we must pay attention not to call this function - // at a time file_name nor hash can be modified, which is easy. - // - if(!finished()) - { - std::cerr << "Transfer not finished !! This should not happen" << std::endl; - return false ; - } - - uint64_t tmpsize ; - return RsDirUtil::getFileHash(file_name,hash,tmpsize) ; -} - -void ftFileCreator::forceCheck() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - chunkMap.forceCheck(); -} - -void ftFileCreator::getSourcesList(uint32_t chunk_num,std::vector& sources) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - chunkMap.getSourcesList(chunk_num,sources) ; -} - -void ftFileCreator::getChunksToCheck(std::vector& chunks_to_ask) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - chunkMap.getChunksToCheck(chunks_to_ask) ; -} - -bool ftFileCreator::verifyChunk(uint32_t chunk_number,const Sha1CheckSum& sum) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - if(!locked_initializeFileAttrs() ) - return false ; - - static const uint32_t chunk_size = ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE ; - unsigned char *buff = new unsigned char[chunk_size] ; - uint32_t len ; - - if(fseeko64(fd,(uint64_t)chunk_number * (uint64_t)chunk_size,SEEK_SET)==0 && (len = fread(buff,1,chunk_size,fd)) > 0) - { - Sha1CheckSum comp = RsDirUtil::sha1sum(buff,len) ; - - if(sum == comp) - chunkMap.setChunkCheckingResult(chunk_number,true) ; - else - { - std::cerr << "Sum mismatch for chunk " << chunk_number << std::endl; - std::cerr << " Computed hash = " << comp.toStdString() << std::endl; - std::cerr << " Reference hash = " << sum.toStdString() << std::endl; - - chunkMap.setChunkCheckingResult(chunk_number,false) ; - } - } - else - { - printf("Chunk verification: cannot fseek!\n") ; - chunkMap.setChunkCheckingResult(chunk_number,false) ; - } - - delete[] buff ; - return true ; -} - - - diff --git a/libretroshare/src/ft/ftfilecreator.h b/libretroshare/src/ft/ftfilecreator.h deleted file mode 100644 index 01a990414..000000000 --- a/libretroshare/src/ft/ftfilecreator.h +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfilecreator.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_FILE_CREATOR_HEADER -#define FT_FILE_CREATOR_HEADER - -/* - * ftFileCreator - * - * TODO: Serialiser Load / Save. - * - */ -#include "ftfileprovider.h" -#include "ftchunkmap.h" -#include - -class ZeroInitCounter -{ - public: - ZeroInitCounter(): cnt(0) {} - uint32_t cnt ; -}; - -class ftFileCreator: public ftFileProvider -{ - public: - - ftFileCreator(const std::string& savepath, uint64_t size, const RsFileHash& hash,bool assume_availability); - - ~ftFileCreator(); - - /* overloaded from FileProvider */ - virtual bool getFileData(const RsPeerId& peer_id,uint64_t offset, uint32_t &chunk_size, void *data, bool allow_unverified = false); - bool finished() ; - uint64_t getRecvd(); - - /// (temporarily) close the file, to save file descriptors. - void closeFile() ; - - void getChunkMap(FileChunksInfo& info) ; - - void setChunkStrategy(FileChunksInfo::ChunkStrategy s) ; - FileChunksInfo::ChunkStrategy getChunkStrategy() ; - - // Computes a sha1sum of the partial file, to check that the data is overall consistent. - // This function is not mutexed. This is a bit dangerous, but otherwise we might stuck the GUI for a - // long time. Therefore, we must pay attention not to call this function - // at a time file_name nor hash can be modified, which is quite easy. - - bool hashReceivedData(RsFileHash& hash) ; - - // Sets all chunks to checking state - // - void forceCheck() ; - - bool verifyChunk(uint32_t, const Sha1CheckSum&) ; - - // Looks into the chunkmap for downloaded chunks that have not yet been certified. - // For each of them, returns the chunk number and a source peer to ask the CRC to. - // - void getChunksToCheck(std::vector& chunks_to_ask) ; - - /* - * creation functions for FileCreator - */ - - // Gets a new variable-sized chunk of size "size_hint" from the given peer id. The returned size, "size" is - // at most equal to size_hint. chunk_map_needed is set if - // - no chunkmap info is available. In such a case, the chunk info is irrelevant and false is returned. - // - the chunk info is too old. In tis case, true is returned, and the chunks info can be used. - // - bool getMissingChunk(const RsPeerId& peer_id,uint32_t size_hint,uint64_t& offset, uint32_t& size,bool& is_chunk_map_too_old); - - // Takes care of purging any inactive chunks. This should be called regularly, because some peers may disconnect - // and let inactive chunks not finished. - // - void removeInactiveChunks() ; - - // removes the designated file source from the chunkmap. - void removeFileSource(const RsPeerId& peer_id) ; - - // Get all available sources for this chunk - // - void getSourcesList(uint32_t chunk_number,std::vector& sources) ; - - // Returns resets the time stamp of the last data receive. - rstime_t lastRecvTimeStamp() ; - rstime_t creationTimeStamp() ; - - // actually store data in the file, and update chunks info - // - bool addFileData(uint64_t offset, uint32_t chunk_size, void *data); - - // Load/save the availability map for the file being downloaded, in a compact/compressed form. - // This is used for - // - loading and saving info about the current transfers - // - getting info about current chunks for the GUI - // - sending availability info to the peers for which we also are a source - // - virtual void getAvailabilityMap(CompressedChunkMap& cmap) ; - void setAvailabilityMap(const CompressedChunkMap& cmap) ; - - // This is called when receiving the availability map from a source peer, for the file being handled. - // - void setSourceMap(const RsPeerId& peer_id,const CompressedChunkMap& map) ; - - // Returns true id the given file source is complete. - // - bool sourceIsComplete(const RsPeerId& peer_id) ; - - protected: - - virtual int locked_initializeFileAttrs(); - - private: - - bool locked_printChunkMap(); - int locked_notifyReceived(uint64_t offset, uint32_t chunk_size); - /* - * structure to track missing chunks - */ - - std::map mChunks; - std::map mChunksPerPeer ; - - ChunkMap chunkMap ; - - rstime_t _last_recv_time_t ; /// last time stamp when data was received. Used for queue control. - rstime_t _creation_time ; /// time at which the file creator was created. Used to spot long-inactive transfers. -}; - -#endif // FT_FILE_CREATOR_HEADER diff --git a/libretroshare/src/ft/ftfileprovider.cc b/libretroshare/src/ft/ftfileprovider.cc deleted file mode 100644 index 0660a9bca..000000000 --- a/libretroshare/src/ft/ftfileprovider.cc +++ /dev/null @@ -1,357 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfileprovider.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif // WINDOWS_SYS - -#include "ftfileprovider.h" -#include "ftchunkmap.h" - -#include "util/rsdir.h" -#include -#include -#include "util/rstime.h" - -/******** -* #define DEBUG_FT_FILE_PROVIDER 1 -* #define DEBUG_TRANSFERS 1 // TO GET TIMESTAMPS of DATA READING -********/ - -#ifdef DEBUG_TRANSFERS - #include "util/rsprint.h" - #include -#endif - -static const rstime_t UPLOAD_CHUNK_MAPS_TIME = 20 ; // time to ask for a new chunkmap from uploaders in seconds. - -ftFileProvider::ftFileProvider(const std::string& path, uint64_t size, const RsFileHash& hash) - : mSize(size), hash(hash), file_name(path), fd(NULL), ftcMutex("ftFileProvider") -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_FT_FILE_PROVIDER - std::cout << "Creating file provider for " << hash << std::endl ; -#endif -} - -ftFileProvider::~ftFileProvider() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ -#ifdef DEBUG_FT_FILE_PROVIDER - std::cout << "ftFileProvider::~ftFileProvider(): Destroying file provider for " << hash << std::endl ; -#endif - if (fd!=NULL) { - fclose(fd); - fd = NULL ; -#ifdef DEBUG_FT_FILE_PROVIDER - std::cout << "ftFileProvider::~ftFileProvider(): closed file: " << hash << std::endl ; -#endif - } -} - -bool ftFileProvider::fileOk() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return (fd != NULL); -} - -RsFileHash ftFileProvider::getHash() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return hash; -} - -uint64_t ftFileProvider::getFileSize() -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - return mSize; -} - -bool ftFileProvider::FileDetails(FileInfo &info) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - info.hash = hash; - info.size = mSize; - info.path = file_name; - info.fname = RsDirUtil::getTopDir(file_name); - - info.transfered = 0 ; // unused - info.lastTS = 0; - info.downloadStatus = FT_STATE_DOWNLOADING ; - - info.peers.clear() ; - float total_transfer_rate = 0.0f ; - - for(std::map::const_iterator it(uploading_peers.begin());it!=uploading_peers.end();++it) - { - TransferInfo inf ; - inf.peerId = it->first ; - inf.status = FT_STATE_DOWNLOADING ; - inf.name = info.fname ; - inf.transfered = it->second.req_loc ; - - inf.tfRate = it->second.transfer_rate/1024.0 ; - total_transfer_rate += it->second.transfer_rate ; - info.lastTS = std::max(info.lastTS,it->second.lastTS); - - info.peers.push_back(inf) ; - } - info.tfRate = total_transfer_rate/1024.0 ; - - /* Use req_loc / req_size to estimate data rate */ - - return true; -} - -bool ftFileProvider::purgeOldPeers(rstime_t now,uint32_t max_duration) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::purgeOldPeers(): " << (void*)this << ": examining peers." << std::endl ; -#endif - bool ret = true ; - for(std::map::iterator it(uploading_peers.begin());it!=uploading_peers.end();) - if( (*it).second.lastTS+max_duration < (uint32_t)now) - { -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::purgeOldPeers(): " << (void*)this << ": peer " << it->first << " is too old. Removing." << std::endl ; -#endif - std::map::iterator tmp = it ; - ++tmp ; - uploading_peers.erase(it) ; - it=tmp ; - } - else - { -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::purgeOldPeers(): " << (void*)this << ": peer " << it->first << " will be kept." << std::endl ; -#endif - ret = false ; - ++it ; - } - return ret ; -} - -void ftFileProvider::getAvailabilityMap(CompressedChunkMap& cmap) -{ - // We are here because the file we deal with is complete. So we return a plain map. - // - ChunkMap::buildPlainMap(mSize,cmap) ; -} - - -bool ftFileProvider::getFileData(const RsPeerId& peer_id,uint64_t offset, uint32_t &chunk_size, void *data, bool /*allow_unverified*/) -{ - /* dodgey checking outside of mutex... - * much check again inside FileAttrs(). - */ - if (fd == NULL) - if (!initializeFileAttrs()) - return false; - - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - /* - * FIXME: Warning of comparison between unsigned and signed int? - */ - - if(offset >= mSize) - { - std::cerr << "ftFileProvider::getFileData(): request (" << offset << ") exceeds file size (" << mSize << "! " << std::endl; - return false ; - } - - uint32_t data_size = chunk_size; - uint64_t base_loc = offset; - - if (base_loc + data_size > mSize) - { - data_size = mSize - base_loc; - chunk_size = mSize - base_loc; - std::cerr <<"Chunk Size greater than total file size, adjusting chunk size " << data_size << std::endl; - } - - if(data_size > 0 && data != NULL) - { - /* - * seek for base_loc - */ - if(fseeko64(fd, base_loc, SEEK_SET) == -1) - { - #ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::getFileData() Failed to seek. Data_size=" << data_size << ", base_loc=" << base_loc << " !" << std::endl; - #endif - //free(data); No!! It's already freed upwards in ftDataMultiplex::locked_handleServerRequest() - return 0; - } - - // Data space allocated by caller. - //void *data = malloc(chunk_size); - - /* - * read the data - */ - - if (1 != fread(data, data_size, 1, fd)) - { - #ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::getFileData() Failed to get data. Data_size=" << data_size << ", base_loc=" << base_loc << " !" << std::endl; - #endif - //free(data); No!! It's already freed upwards in ftDataMultiplex::locked_handleServerRequest() - return 0; - } - - /* - * Update status of ftFileStatus to reflect last usage (for GUI display) - * We need to store. - * (a) Id, - * (b) Offset, - * (c) Size, - * (d) timestamp - */ - - // This creates the peer info, and updates it. - // - rstime_t now = time(NULL) ; - uploading_peers[peer_id].updateStatus(offset,data_size,now) ; - -#ifdef DEBUG_TRANSFERS - std::cerr << "ftFileProvider::getFileData() "; - std::cerr << " at " << RsUtil::AccurateTimeString(); - std::cerr << " hash: " << hash; - std::cerr << " for peerId: " << peer_id; - std::cerr << " offset: " << offset; - std::cerr << " chunkSize: " << chunk_size; - std::cerr << std::endl; -#endif - - } - else - { - std::cerr << "No data to read, or NULL buffer used" << std::endl; - return 0; - } - return 1; -} - -void ftFileProvider::PeerUploadInfo::updateStatus(uint64_t offset,uint32_t data_size,rstime_t now) -{ - lastTS = now ; - long int diff = (long int)now - (long int)lastTS_t ; // in bytes/s. Average over multiple samples - -#ifdef DEBUG_FT_FILE_PROVIDER - std::cout << "diff = " << diff << std::endl ; -#endif - - if(diff > 3) - { - transfer_rate = total_size / (float)diff ; -#ifdef DEBUG_FT_FILE_PROVIDER - std::cout << "updated TR = " << transfer_rate << ", total_size=" << total_size << std::endl ; -#endif - lastTS_t = now ; - total_size = 0 ; - } - - req_loc = offset; - req_size = data_size; - total_size += req_size ; -} - -void ftFileProvider::setClientMap(const RsPeerId& peer_id,const CompressedChunkMap& cmap) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - // Create by default. - uploading_peers[peer_id].client_chunk_map = cmap ; - uploading_peers[peer_id].client_chunk_map_stamp = time(NULL) ; -} - -void ftFileProvider::getClientMap(const RsPeerId& peer_id,CompressedChunkMap& cmap,bool& map_is_too_old) -{ - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - - PeerUploadInfo& pui(uploading_peers[peer_id]) ; - - rstime_t now = time(NULL) ; - - if(now - pui.client_chunk_map_stamp > UPLOAD_CHUNK_MAPS_TIME) - { - map_is_too_old = true ; - pui.client_chunk_map_stamp = now ; // to avoid re-asking before the TTL - } - else - map_is_too_old = false ; - - cmap = pui.client_chunk_map; -} - -int ftFileProvider::initializeFileAttrs() -{ -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::initializeFileAttrs() Filename: " << file_name << std::endl; -#endif - - RsStackMutex stack(ftcMutex); /********** STACK LOCKED MTX ******/ - if (fd) - return 1; - - /* - * check if the file exists - */ - - { -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider::initializeFileAttrs() trying (r+b) " << std::endl; -#endif - } - - /* - * attempt to open file - */ - - fd = RsDirUtil::rs_fopen(file_name.c_str(), "r+b"); - if (!fd) - { - std::cerr << "ftFileProvider::initializeFileAttrs() Failed to open (r+b): "; - std::cerr << file_name << std::endl; - - /* try opening read only */ - fd = RsDirUtil::rs_fopen(file_name.c_str(), "rb"); - if (!fd) - { - std::cerr << "ftFileProvider::initializeFileAttrs() Failed to open (rb): "; - std::cerr << file_name << std::endl; - - /* try opening read only */ - return 0; - } - } -#ifdef DEBUG_FT_FILE_PROVIDER - std::cerr << "ftFileProvider:: openned file " << file_name << std::endl ; -#endif - - return 1; -} - - diff --git a/libretroshare/src/ft/ftfileprovider.h b/libretroshare/src/ft/ftfileprovider.h deleted file mode 100644 index 4ed0dbec9..000000000 --- a/libretroshare/src/ft/ftfileprovider.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfileprovider.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_FILE_PROVIDER_HEADER -#define FT_FILE_PROVIDER_HEADER - -/* - * ftFileProvider. - * - */ -#include -#include -#include "util/rsthreads.h" -#include "retroshare/rsfiles.h" - -class ftFileProvider -{ - public: - ftFileProvider(const std::string& path, uint64_t size, const RsFileHash& hash); - virtual ~ftFileProvider(); - - /** - * read a block of data from the file - * @param peer_id for the uploading stats: to which peer the data will be send - * @param offset begin of the requested data range - * @param chunk_size how many bytes to read. Will be set to the number of valid bytes in data on return. - * @param data pointer to a buffer of size chunk_size. Contains the data on success. - * @param allow_unverified for ftFileCreator: set to true to return data from unverified chunks. Use it if you want data asap. - * @return true if data was read - */ - virtual bool getFileData(const RsPeerId& peer_id,uint64_t offset, uint32_t &chunk_size, void *data, bool allow_unverified = false); - virtual bool FileDetails(FileInfo &info); - RsFileHash getHash(); - uint64_t getFileSize(); - bool fileOk(); - - // Provides a client for the map of chunks actually present in the file. If the provider is also - // a file creator, because the file is actually being downloaded, then the map may be partially complete. - // Otherwize, a plain map is returned. - // - virtual void getAvailabilityMap(CompressedChunkMap& cmap) ; - - // a ftFileProvider feeds a distant peer. To display what the peers already has, we need to store/read this info. - void getClientMap(const RsPeerId& peer_id,CompressedChunkMap& cmap,bool& map_is_too_old) ; - void setClientMap(const RsPeerId& peer_id,const CompressedChunkMap& cmap) ; - - // Removes inactive peers from the client list. Returns true if all peers have been removed. - // - bool purgeOldPeers(rstime_t now,uint32_t max_duration) ; - - const RsFileHash& fileHash() const { return hash ; } - const std::string& fileName() const { return file_name ; } - uint64_t fileSize() const { return mSize ; } - protected: - virtual int initializeFileAttrs(); /* does for both */ - - uint64_t mSize; - RsFileHash hash; - std::string file_name; - FILE *fd; - - /* - * Structure to gather statistics FIXME: lastRequestor - figure out a - * way to get last requestor (peerID) - */ - class PeerUploadInfo - { - public: - PeerUploadInfo() - : req_loc(0),req_size(1), lastTS_t(0), lastTS(0),transfer_rate(0), total_size(0), client_chunk_map_stamp(0) {} - - void updateStatus(uint64_t offset,uint32_t data_size,rstime_t now) ; - - uint64_t req_loc; - uint32_t req_size; - rstime_t lastTS_t; // used for estimating transfer rate. - rstime_t lastTS; // last update time (for purging) - - // these two are used for speed estimation - float transfer_rate ; - uint32_t total_size ; - - // Info about what the downloading peer already has - CompressedChunkMap client_chunk_map ; - rstime_t client_chunk_map_stamp ; - }; - - // Contains statistics (speed, peer name, etc.) of all uploading peers for that file. - // - std::map uploading_peers ; - - /* - * Mutex Required for stuff below - */ - RsMutex ftcMutex; -}; - - -#endif // FT_FILE_PROVIDER_HEADER diff --git a/libretroshare/src/ft/ftfilesearch.cc b/libretroshare/src/ft/ftfilesearch.cc deleted file mode 100644 index c9571f9a8..000000000 --- a/libretroshare/src/ft/ftfilesearch.cc +++ /dev/null @@ -1,177 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfilesearch.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "ft/ftfilesearch.h" - -const uint32_t MAX_SEARCHS = 24; /* lower 24 bits of hint */ - -//#define DEBUG_SEARCH 1 - -ftFileSearch::ftFileSearch() - :mSearchs(MAX_SEARCHS) -{ - uint32_t i; - for(i = 0; i < MAX_SEARCHS; i++) - { - mSearchs[i] = NULL; - } -} - -bool ftFileSearch::addSearchMode(ftSearch *search, FileSearchFlags hintflags) -{ - hintflags &= FileSearchFlags(0x000000ff); - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::addSearchMode() : " << hintflags; - std::cerr << std::endl; -#endif - - uint32_t i; - for (i = 0; i < MAX_SEARCHS; i++) - { - uint32_t hints = hintflags.toUInt32() >> i; - if (hints & 0x0001) - { - /* has the flag */ - mSearchs[i] = search; - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::addSearchMode() to slot "; - std::cerr << i; - std::cerr << std::endl; -#endif - - return true; - } - } - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::addSearchMode() Failed"; - std::cerr << std::endl; -#endif - - return false; -} - -bool ftFileSearch::search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const -{ - uint32_t hints, i; - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search(" << hash ; - std::cerr << ", " << hintflags << ");"; - std::cerr << std::endl; -#endif - - for (i = 0; i < MAX_SEARCHS; i++) - { - hints = hintflags.toUInt32() >> i; - if (hints & 0x0001) - { - /* has the flag */ - ftSearch *search = mSearchs[i]; - if (search) - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: "; - std::cerr << i; - std::cerr << std::endl; -#endif - if (search->search(hash, hintflags, info)) - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: "; - std::cerr << i << " success!"; - std::cerr << std::endl; -#endif - return true; - } - else - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: "; - std::cerr << i << " no luck"; - std::cerr << std::endl; -#endif - } - } - } - } - - /* if we haven't found it by now! - check if SPEC_ONLY flag is set */ - if (hintflags & RS_FILE_HINTS_SPEC_ONLY) - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SPEC_ONLY: Failed"; - std::cerr << std::endl; -#endif - return false; - } - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() Searching Others (no SPEC ONLY):"; - std::cerr << std::endl; -#endif - - /* if we don't have the SPEC_ONLY flag, - * we check through all the others - */ - for (i = 0; i < MAX_SEARCHS; i++) - { - hints = hintflags.toUInt32() >> i; - if (hints & 0x0001) - { - continue; - } - - /* has the flag */ - ftSearch *search = mSearchs[i]; - if (search) - { - -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: " << i; - std::cerr << std::endl; -#endif - if (search->search(hash, hintflags, info)) - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: "; - std::cerr << i << " success!"; - std::cerr << std::endl; -#endif - return true; - } - else - { -#ifdef DEBUG_SEARCH - std::cerr << "ftFileSearch::search() SLOT: "; - std::cerr << i << " no luck"; - std::cerr << std::endl; -#endif - } - - } - } - /* found nothing */ - return false; -} - diff --git a/libretroshare/src/ft/ftfilesearch.h b/libretroshare/src/ft/ftfilesearch.h deleted file mode 100644 index 46c11d33c..000000000 --- a/libretroshare/src/ft/ftfilesearch.h +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftfilesearch.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_FILE_SEARCH_HEADER -#define FT_FILE_SEARCH_HEADER - -/* - * ftFileSearch - * - * This is implements an array of ftSearch Interfaces. - * - */ - -#include - -#include "ft/ftsearch.h" - -class ftFileSearch: public ftSearch -{ - - public: - - ftFileSearch(); - -bool addSearchMode(ftSearch *search, FileSearchFlags hintflags); -virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const; - - private: - - // should have a mutex to protect vector.... - // but not really necessary as it is const most of the time. - - std::vector mSearchs; -}; - - -#endif diff --git a/libretroshare/src/ft/ftsearch.h b/libretroshare/src/ft/ftsearch.h deleted file mode 100644 index 7906d275f..000000000 --- a/libretroshare/src/ft/ftsearch.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftsearch.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef FT_SEARCH_HEADER -#define FT_SEARCH_HEADER - -/* - * ftSearch - * - * This is a generic search interface - used by ft* to find files. - * The derived class will search for Caches/Local/ExtraList/Remote entries. - * - */ - -#include "retroshare/rsfiles.h" // includes retroshare/rstypes.h too! - -class ftSearch -{ - - public: - ftSearch() { return; } - virtual ~ftSearch() { return; } - virtual bool search(const RsFileHash & /*hash*/, FileSearchFlags /*hintflags*/,const RsPeerId& /*peer_id*/, FileInfo & /*info*/) const - { - std::cerr << "Non overloaded search method called!!!" << std::endl; - return false; - } - virtual bool search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const = 0; - -}; - -#endif diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc deleted file mode 100644 index 07a400acf..000000000 --- a/libretroshare/src/ft/ftserver.cc +++ /dev/null @@ -1,2360 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftserver.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include - -#include "crypto/chacha20.h" -//const int ftserverzone = 29539; - -#include "file_sharing/p3filelists.h" -#include "ft/ftcontroller.h" -#include "ft/ftdatamultiplex.h" -//#include "ft/ftdwlqueue.h" -#include "ft/ftextralist.h" -#include "ft/ftfileprovider.h" -#include "ft/ftfilesearch.h" -#include "ft/ftserver.h" -#include "ft/ftturtlefiletransferitem.h" - -#include "pqi/p3linkmgr.h" -#include "pqi/p3notify.h" -#include "pqi/pqi.h" - -#include "retroshare/rstypes.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsinit.h" -#include "util/cxx17retrocompat.h" -#include "rsitems/rsfiletransferitems.h" -#include "rsitems/rsserviceids.h" -#include "util/rsmemory.h" -#include "rsserver/p3face.h" -#include "turtle/p3turtle.h" -#include "util/rsurl.h" -#include "util/rsdebug.h" -#include "util/rsdir.h" -#include "util/rsprint.h" -#include "util/rstime.h" - -#ifdef RS_DEEP_FILES_INDEX -# include "deep_search/filesindex.hpp" -#endif // def RS_DEEP_FILES_INDEX - -/*** - * #define SERVER_DEBUG 1 - * #define SERVER_DEBUG_CACHE 1 - ***/ - -#define FTSERVER_DEBUG() std::cerr << time(NULL) << " : FILE_SERVER : " << __FUNCTION__ << " : " -#define FTSERVER_ERROR() std::cerr << "(EE) FILE_SERVER ERROR : " - -/*static*/ const RsFilesErrorCategory RsFilesErrorCategory::instance; - -/*static*/ const std::string RsFiles::DEFAULT_FILES_BASE_URL = - "retroshare:///files"; -/*static*/ const std::string RsFiles::FILES_URL_COUNT_FIELD = "filesCount"; -/*static*/ const std::string RsFiles::FILES_URL_DATA_FIELD = "filesData"; -// Use a 5 character word so there is no mistake it isn't base64 as 5%4=1 -/*static*/ const std::string RsFiles::FILES_URL_FAGMENT_FORWARD = "fragm"; -/*static*/ const std::string RsFiles::FILES_URL_NAME_FIELD = "filesName"; -/*static*/ const std::string RsFiles::FILES_URL_SIZE_FIELD = "filesSize"; - - -static const rstime_t FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD = 5 ; // low priority tasks handling every 5 seconds -static const rstime_t FILE_TRANSFER_MAX_DELAY_BEFORE_DROP_USAGE_RECORD = 10 ; // keep usage records for 10 secs at most. - -#ifdef RS_DEEP_FILES_INDEX -TurtleFileInfoV2::TurtleFileInfoV2(const DeepFilesSearchResult& dRes) : - fHash(dRes.mFileHash), fWeight(static_cast(dRes.mWeight)), - fSnippet(dRes.mSnippet) -{ - FileInfo fInfo; - rsFiles->FileDetails(fHash, RS_FILE_HINTS_LOCAL, fInfo); - - fSize = fInfo.size; - fName = fInfo.fname; -} -#endif // def RS_DEEP_FILES_INDEX - -TurtleFileInfoV2::~TurtleFileInfoV2() = default; - -/* Setup */ -ftServer::ftServer(p3PeerMgr *pm, p3ServiceControl *sc): - p3Service(), - // should be FT, but this is for backward compatibility - RsServiceSerializer(RS_SERVICE_TYPE_TURTLE), - mPeerMgr(pm), mServiceCtrl(sc), - mFileDatabase(NULL), - mFtController(NULL), mFtExtra(NULL), - mFtDataplex(NULL), mFtSearch(NULL), srvMutex("ftServer"), - mSearchCallbacksMapMutex("ftServer callbacks map") -{ - addSerialType(new RsFileTransferSerialiser()) ; -} - -const std::string FILE_TRANSFER_APP_NAME = "ft"; -const uint16_t FILE_TRANSFER_APP_MAJOR_VERSION = 1; -const uint16_t FILE_TRANSFER_APP_MINOR_VERSION = 0; -const uint16_t FILE_TRANSFER_MIN_MAJOR_VERSION = 1; -const uint16_t FILE_TRANSFER_MIN_MINOR_VERSION = 0; - -RsServiceInfo ftServer::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_FILE_TRANSFER, - FILE_TRANSFER_APP_NAME, - FILE_TRANSFER_APP_MAJOR_VERSION, - FILE_TRANSFER_APP_MINOR_VERSION, - FILE_TRANSFER_MIN_MAJOR_VERSION, - FILE_TRANSFER_MIN_MINOR_VERSION); -} - - -void ftServer::setConfigDirectory(std::string path) -{ - mConfigPath = path; - - /* Must update the sub classes ... if they exist - * TODO. - */ - - std::string basecachedir = mConfigPath + "/cache"; - std::string localcachedir = mConfigPath + "/cache/local"; - std::string remotecachedir = mConfigPath + "/cache/remote"; - - RsDirUtil::checkCreateDirectory(basecachedir) ; - RsDirUtil::checkCreateDirectory(localcachedir) ; - RsDirUtil::checkCreateDirectory(remotecachedir) ; -} - -/* Control Interface */ - -/* add Config Items (Extra, Controller) */ -void ftServer::addConfigComponents(p3ConfigMgr */*mgr*/) -{ - /* NOT SURE ABOUT THIS ONE */ -} - -const RsPeerId& ftServer::OwnId() -{ - static RsPeerId null_id ; - - if (mServiceCtrl) - return mServiceCtrl->getOwnId(); - else - return null_id ; -} - -/* Final Setup (once everything is assigned) */ -void ftServer::SetupFtServer() -{ - - /* setup FiStore/Monitor */ - //std::string localcachedir = mConfigPath + "/cache/local"; - //std::string remotecachedir = mConfigPath + "/cache/remote"; - RsPeerId ownId = mServiceCtrl->getOwnId(); - - /* search/extras List */ - mFtExtra = new ftExtraList(); - mFtSearch = new ftFileSearch(); - - /* Transport */ - mFtDataplex = new ftDataMultiplex(ownId, this, mFtSearch); - - /* make Controller */ - mFtController = new ftController(mFtDataplex, mServiceCtrl, getServiceInfo().mServiceType); - mFtController -> setFtSearchNExtra(mFtSearch, mFtExtra); - - std::string emergencySaveDir = RsAccounts::AccountDirectory(); - std::string emergencyPartialsDir = RsAccounts::AccountDirectory(); - - if (emergencySaveDir != "") - { - emergencySaveDir += "/"; - emergencyPartialsDir += "/"; - } - emergencySaveDir += "Downloads"; - emergencyPartialsDir += "Partials"; - - mFtController->setDownloadDirectory(emergencySaveDir); - mFtController->setPartialsDirectory(emergencyPartialsDir); - - /* complete search setup */ - mFtSearch->addSearchMode(mFtExtra, RS_FILE_HINTS_EXTRA); - - mServiceCtrl->registerServiceMonitor(mFtController, getServiceInfo().mServiceType); - - return; -} - -void ftServer::connectToFileDatabase(p3FileDatabase *fdb) -{ - mFileDatabase = fdb ; - - mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_LOCAL); // due to a bug in addSearchModule, modules can only be added one by one. Using | between flags wont work. - mFtSearch->addSearchMode(fdb, RS_FILE_HINTS_REMOTE); - - mFileDatabase->setExtraList(mFtExtra); -} -void ftServer::connectToTurtleRouter(p3turtle *fts) -{ - mTurtleRouter = fts ; - - mFtController->setTurtleRouter(fts) ; - mFtController->setFtServer(this) ; - - mTurtleRouter->registerTunnelService(this) ; -} - -void ftServer::StartupThreads() -{ - /* start up order - important for dependencies */ - - /* self contained threads */ - /* startup ExtraList Thread */ - mFtExtra->start("ft extra lst"); - - /* startup Monitor Thread */ - /* startup the FileMonitor (after cache load) */ - /* start it up */ - mFileDatabase->startThreads(); - - /* Controller thread */ - mFtController->start("ft ctrl"); - - /* Dataplex */ - mFtDataplex->start("ft dataplex"); -} - -void ftServer::StopThreads() -{ - /* stop Dataplex */ - mFtDataplex->fullstop(); - - /* stop Controller thread */ - mFtController->fullstop(); - - /* self contained threads */ - /* stop ExtraList Thread */ - mFtExtra->fullstop(); - - delete (mFtDataplex); - mFtDataplex = nullptr; - - delete (mFtController); - mFtController = nullptr; - - delete (mFtExtra); - mFtExtra = nullptr; - - /* stop Monitor Thread */ - mFileDatabase->stopThreads(); - delete mFileDatabase; - mFileDatabase = nullptr; -} - -/***************************************************************/ -/********************** RsFiles Interface **********************/ -/***************************************************************/ - -/***************************************************************/ -/********************** Controller Access **********************/ -/***************************************************************/ - -bool ftServer::ResumeTransfers() -{ - mFtController->activate(); - - return true; -} - -bool ftServer::getFileData(const RsFileHash& hash, uint64_t offset, uint32_t& requested_size,uint8_t *data) -{ - return mFtDataplex->getFileData(hash, offset, requested_size,data); -} - -bool ftServer::alreadyHaveFile(const RsFileHash& hash, FileInfo &info) -{ - return mFileDatabase->search( - hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, info ); -} - -bool ftServer::FileRequest( - const std::string& fname, const RsFileHash& hash, uint64_t size, - const std::string& dest, TransferRequestFlags flags, - const std::list& srcIds ) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "Requesting " << fname << std::endl ; -#endif - - if(!mFtController->FileRequest(fname, hash, size, dest, flags, srcIds)) - return false ; - - return true ; -} - -std::error_condition ftServer::requestFiles( - const RsFileTree& collection, const std::string& destPath, - const std::vector& srcIds, FileRequestFlags flags ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto dirsCount = collection.mDirs.size(); - const auto filesCount = collection.mFiles.size(); - - Dbg2() << fname << " dirsCount: " << dirsCount - << " filesCount: " << filesCount << std::endl; - - if(!dirsCount) - { - RsErr() << fname << " Directories list empty in collection " - << std::endl; - return std::errc::not_a_directory; - } - - if(!filesCount) - { - RsErr() << fname << " Files list empty in collection " << std::endl; - return std::errc::invalid_argument; - } - - if(filesCount != collection.mTotalFiles) - { - RsErr() << fname << " Files count mismatch" << std::endl; - return std::errc::invalid_argument; - } - - std::string basePath = destPath.empty() ? getDownloadDirectory() : destPath; - // Track how many time a directory have been explored - std::vector dirsSeenCnt(dirsCount, 0); - // - using StackEntry = std::tuple; - std::deque dStack = { std::make_tuple(0, basePath) }; - - const auto exploreDir = [&](const StackEntry& se)-> std::error_condition - { - uint64_t dirHandle; std::string parentPath; - std::tie(dirHandle, parentPath) = se; - - const auto& dirData = collection.mDirs[dirHandle]; - auto& seenTimes = dirsSeenCnt[dirHandle]; - std::string dirPath = RsDirUtil::makePath(parentPath, dirData.name); - - /* This check is not perfect but is cheap and interrupt loop exploration - * before it becomes pathological */ - if(seenTimes++ > dirsCount) - { - RsErr() << fname << " loop detected! dir: " - << dirHandle << " \"" << dirPath - << "\" explored too many times" << std::endl; - return std::errc::too_many_symbolic_link_levels; - } - - for(auto fHandle: dirData.subfiles) - { - if(fHandle >= filesCount) return std::errc::argument_out_of_domain; - - const RsFileTree::FileData& fData = collection.mFiles[fHandle]; - - bool fr = - FileRequest( fData.name, fData.hash, fData.size, - dirPath, - TransferRequestFlags::fromEFT(flags), - std::list(srcIds.begin(), srcIds.end()) ); - - Dbg2() << fname << " requested: " << fr << " " - << fData.hash << " -> " << dirPath << std::endl; - } - - for(auto dHandle: dirData.subdirs) - dStack.push_back(std::make_tuple(dHandle, dirPath)); - - return std::error_condition(); - }; - - while(!dStack.empty()) - { - if(std::error_condition ec = exploreDir(dStack.front())) return ec; - dStack.pop_front(); - } - - return std::error_condition(); -} - -bool ftServer::activateTunnels(const RsFileHash& hash,uint32_t encryption_policy,TransferRequestFlags flags,bool onoff) -{ - RsFileHash hash_of_hash ; - - encryptHash(hash,hash_of_hash) ; - mEncryptedHashes.insert(std::make_pair(hash_of_hash,hash)) ; - - if(onoff) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "Activating tunnels for hash " << hash << std::endl; -#endif - if(flags & RS_FILE_REQ_ENCRYPTED) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " flags require end-to-end encryption. Requesting hash of hash " << hash_of_hash << std::endl; -#endif - mTurtleRouter->monitorTunnels(hash_of_hash,this,true) ; - } - if((flags & RS_FILE_REQ_UNENCRYPTED) && (encryption_policy != RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT)) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " flags require no end-to-end encryption. Requesting hash " << hash << std::endl; -#endif - mTurtleRouter->monitorTunnels(hash,this,true) ; - } - } - else - { - mTurtleRouter->stopMonitoringTunnels(hash_of_hash); - mTurtleRouter->stopMonitoringTunnels(hash); - } - return true ; -} - -bool ftServer::setDestinationDirectory(const RsFileHash& hash,const std::string& directory) -{ - return mFtController->setDestinationDirectory(hash,directory); -} -bool ftServer::setDestinationName(const RsFileHash& hash,const std::string& name) -{ - return mFtController->setDestinationName(hash,name); -} - -bool ftServer::setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s) -{ - return mFtController->setChunkStrategy(hash,s); -} -void ftServer::setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy s) -{ - mFtController->setDefaultChunkStrategy(s) ; -} -FileChunksInfo::ChunkStrategy ftServer::defaultChunkStrategy() -{ - return mFtController->defaultChunkStrategy() ; -} - -uint32_t ftServer::freeDiskSpaceLimit()const -{ - return mFtController->freeDiskSpaceLimit() ; -} -void ftServer::setFreeDiskSpaceLimit(uint32_t s) -{ - mFtController->setFreeDiskSpaceLimit(s) ; -} - -void ftServer::setDefaultEncryptionPolicy(uint32_t s) -{ - mFtController->setDefaultEncryptionPolicy(s) ; -} -uint32_t ftServer::defaultEncryptionPolicy() -{ - return mFtController->defaultEncryptionPolicy() ; -} - -void ftServer::setMaxUploadSlotsPerFriend(uint32_t n) -{ - mFtController->setMaxUploadsPerFriend(n) ; -} -uint32_t ftServer::getMaxUploadSlotsPerFriend() -{ - return mFtController->getMaxUploadsPerFriend() ; -} - -void ftServer::setFilePermDirectDL(uint32_t perm) -{ - mFtController->setFilePermDirectDL(perm); -} -uint32_t ftServer::filePermDirectDL() -{ - return mFtController->filePermDirectDL() ; -} - -bool ftServer::FileCancel(const RsFileHash& hash) -{ - // Remove from both queue and ftController, by default. - // - mFtController->FileCancel(hash); - - return true ; -} - -bool ftServer::FileControl(const RsFileHash& hash, uint32_t flags) -{ - return mFtController->FileControl(hash, flags); -} - -bool ftServer::FileClearCompleted() -{ - return mFtController->FileClearCompleted(); -} -void ftServer::setQueueSize(uint32_t s) -{ - mFtController->setQueueSize(s) ; -} -uint32_t ftServer::getQueueSize() -{ - return mFtController->getQueueSize() ; -} -/* Control of Downloads Priority. */ -bool ftServer::changeQueuePosition(const RsFileHash& hash, QueueMove mv) -{ - mFtController->moveInQueue(hash,mv) ; - return true ; -} -bool ftServer::changeDownloadSpeed(const RsFileHash& hash, int speed) -{ - mFtController->setPriority(hash, (DwlSpeed)speed); - return true ; -} -bool ftServer::getDownloadSpeed(const RsFileHash& hash, int & speed) -{ - DwlSpeed _speed; - int ret = mFtController->getPriority(hash, _speed); - if (ret) - speed = _speed; - - return ret; -} -bool ftServer::clearDownload(const RsFileHash& /*hash*/) -{ - return true ; -} - -bool ftServer::FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) -{ - return mFtController->getFileDownloadChunksDetails(hash,info); -} - -void ftServer::requestDirUpdate(void *ref) -{ - mFileDatabase->requestDirUpdate(ref) ; -} - -/* Directory Handling */ -bool ftServer::setDownloadDirectory(const std::string& path) -{ - return mFtController->setDownloadDirectory(path); -} - -std::string ftServer::getDownloadDirectory() -{ - return mFtController->getDownloadDirectory(); -} - -bool ftServer::setPartialsDirectory(const std::string& path) -{ - return mFtController->setPartialsDirectory(path); -} - -std::string ftServer::getPartialsDirectory() -{ - return mFtController->getPartialsDirectory(); -} - -/***************************************************************/ -/************************* Other Access ************************/ -/***************************************************************/ - -bool ftServer::copyFile(const std::string& source, const std::string& dest) -{ - return RsDirUtil::copyFile(source, dest); -} - -void ftServer::FileDownloads(std::list &hashs) -{ - mFtController->FileDownloads(hashs); -} - -bool ftServer::FileUploadChunksDetails(const RsFileHash& hash,const RsPeerId& peer_id,CompressedChunkMap& cmap) -{ - return mFtDataplex->getClientChunkMap(hash,peer_id,cmap); -} - -bool ftServer::FileUploads(std::list &hashs) -{ - return mFtDataplex->FileUploads(hashs); -} - -bool ftServer::FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) -{ - if (hintflags & RS_FILE_HINTS_DOWNLOAD) - if(mFtController->FileDetails(hash, info)) - return true ; - - if(hintflags & RS_FILE_HINTS_UPLOAD) - if(mFtDataplex->FileDetails(hash, hintflags, info)) - { - // We also check if the file is a DL as well. In such a case we use - // the DL as the file name, to replace the hash. If the file is a cache - // file, we skip the call to fileDetails() for efficiency reasons. - // - FileInfo info2 ; - if(mFtController->FileDetails(hash, info2)) - info.fname = info2.fname ; - - return true ; - } - - if(hintflags & ~(RS_FILE_HINTS_UPLOAD | RS_FILE_HINTS_DOWNLOAD)) - if(mFtSearch->search(hash, hintflags, info)) - return true ; - - return false; -} - -RsItem *ftServer::create_item(uint16_t service, uint8_t item_type) const -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "p3turtle: deserialising packet: " << std::endl ; -#endif - - RsServiceType serviceType = static_cast(service); - switch (serviceType) - { - /* This one is here for retro-compatibility as turtle routing and file - * trasfer services were just one service before turle service was - * generalized */ - case RsServiceType::TURTLE: break; - case RsServiceType::FILE_TRANSFER: break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Wrong service type: " << service - << std::endl; - return nullptr; - } - - try - { - switch(item_type) - { - case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(); - case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(); - case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(); - case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(); - case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(); - case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(); - case static_cast(RsFileItemType::FILE_SEARCH_REQUEST): - return new RsFileSearchRequestItem(); - case static_cast(RsFileItemType::FILE_SEARCH_RESULT): - return new RsFileSearchResultItem(); - default: - return nullptr; - } - } - catch(std::exception& e) - { - FTSERVER_ERROR() << "(EE) deserialisation error in " << __PRETTY_FUNCTION__ << ": " << e.what() << std::endl; - - return nullptr; - } -} - -bool ftServer::isEncryptedSource(const RsPeerId& virtual_peer_id) -{ - RS_STACK_MUTEX(srvMutex) ; - - return mEncryptedPeerIds.find(virtual_peer_id) != mEncryptedPeerIds.end(); -} - -void ftServer::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "adding virtual peer. Direction=" << dir << ", hash=" << hash << ", vpid=" << virtual_peer_id << std::endl; -#endif - RsFileHash real_hash ; - - { - if(findRealHash(hash,real_hash)) - { - RS_STACK_MUTEX(srvMutex) ; - mEncryptedPeerIds[virtual_peer_id] = hash ; - } - else - real_hash = hash; - } - - if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " direction is SERVER. Adding file source for end-to-end encrypted tunnel for real hash " << real_hash << ", virtual peer id = " << virtual_peer_id << std::endl; -#endif - mFtController->addFileSource(real_hash,virtual_peer_id) ; - } -} - -void ftServer::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) -{ - RsFileHash real_hash ; - if(findRealHash(hash,real_hash)) - mFtController->removeFileSource(real_hash,virtual_peer_id) ; - else - mFtController->removeFileSource(hash,virtual_peer_id) ; - - RS_STACK_MUTEX(srvMutex) ; - mEncryptedPeerIds.erase(virtual_peer_id) ; -} - -bool ftServer::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_id) -{ - FileInfo info ; - RsFileHash real_hash ; - bool found = false ; - - if(FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY, info)) - { - if(info.transfer_info_flags & RS_FILE_REQ_ENCRYPTED) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "handleTunnelRequest: openning encrypted FT tunnel for H(H(F))=" << hash << " and H(F)=" << info.hash << std::endl; -#endif - - RS_STACK_MUTEX(srvMutex) ; - mEncryptedHashes[hash] = info.hash; - - real_hash = info.hash ; - } - else - real_hash = hash ; - - found = true ; - } - else // try to see if we're already swarming the file - { - { - RS_STACK_MUTEX(srvMutex) ; - std::map::const_iterator it = mEncryptedHashes.find(hash) ; - - if(it != mEncryptedHashes.end()) - real_hash = it->second ; - else - real_hash = hash ; - } - - if(FileDetails(real_hash,RS_FILE_HINTS_DOWNLOAD,info)) - { - // This file is currently being downloaded. Let's look if we already have a chunk or not. If not, no need to - // share the file! - - FileChunksInfo info2 ; - if(rsFiles->FileDownloadChunksDetails(real_hash, info2)) - for(uint32_t i=0;idefaultEncryptionPolicy() == RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT && hash == real_hash) - { -#ifdef SERVER_DEBUG - std::cerr << "(WW) rejecting file transfer for hash " << hash << " because the hash is not encrypted and encryption policy requires it." << std::endl; -#endif - return false ; - } - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer: performing local hash search for hash " << hash << std::endl; - - if(found) - { - FTSERVER_DEBUG() << "Found hash: " << std::endl; - FTSERVER_DEBUG() << " hash = " << real_hash << std::endl; - FTSERVER_DEBUG() << " peer = " << peer_id << std::endl; - FTSERVER_DEBUG() << " flags = " << info.storage_permission_flags << std::endl; - FTSERVER_DEBUG() << " groups= " ; - for(std::list::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it) - FTSERVER_DEBUG() << (*it) << ", " ; - FTSERVER_DEBUG() << std::endl; - FTSERVER_DEBUG() << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl; - } -#endif - - // The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE - // This is an additional computation cost, but the way it's written here, it's only called when res is true. - // - found = found && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ; - - return found ; -} - -/***************************************************************/ -/******************* ExtraFileList Access **********************/ -/***************************************************************/ - -bool ftServer::ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t size, uint32_t period, TransferRequestFlags flags) -{ - return mFtExtra->addExtraFile(fname, hash, size, period, flags); -} - -bool ftServer::ExtraFileRemove(const RsFileHash& hash) -{ return mFileDatabase->removeExtraFile(hash); } - -bool ftServer::ExtraFileHash( std::string localpath, rstime_t period, TransferRequestFlags flags ) -{ - constexpr rstime_t uintmax = std::numeric_limits::max(); - if(period > uintmax) - { - RsErr() << __PRETTY_FUNCTION__ << " period: " << period << " > " - << uintmax << std::errc::value_too_large << std::endl; - return false; - } - - return mFtExtra->hashExtraFile( - localpath, static_cast(period), flags ); -} - -bool ftServer::ExtraFileStatus(std::string localpath, FileInfo &info) -{ - return mFtExtra->hashExtraFileDone(localpath, info); -} - -bool ftServer::ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath) -{ - return mFtExtra->moveExtraFile(fname, hash, size, destpath); -} - -/***************************************************************/ -/******************** Directory Listing ************************/ -/***************************************************************/ - -bool ftServer::findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) -{ - return mFileDatabase->findChildPointer(ref,row,result,flags) ; -} - -bool ftServer::requestDirDetails( - DirDetails &details, uint64_t handle, FileSearchFlags flags ) -{ return RequestDirDetails(reinterpret_cast(handle), details, flags); } - -int ftServer::RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags) -{ - return mFileDatabase->RequestDirDetails(ref,details,flags) ; -} - -uint32_t ftServer::getType(void *ref, FileSearchFlags flags) -{ - return mFileDatabase->getType(ref,flags) ; -} -/***************************************************************/ -/******************** Search Interface *************************/ -/***************************************************************/ - -int ftServer::SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags) -{ - return mFileDatabase->SearchKeywords(keywords, results,flags,RsPeerId()); -} -int ftServer::SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) -{ - return mFileDatabase->SearchKeywords(keywords, results,flags,peer_id); -} - -int ftServer::SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags) -{ - return mFileDatabase->SearchBoolExp(exp, results,flags,RsPeerId()); -} -int ftServer::SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) -{ - return mFileDatabase->SearchBoolExp(exp,results,flags,peer_id) ; -} -int ftServer::getSharedDirStatistics(const RsPeerId& pid, SharedDirStats& stats) -{ - return mFileDatabase->getSharedDirStatistics(pid,stats) ; -} - -/***************************************************************/ -/*************** Local Shared Dir Interface ********************/ -/***************************************************************/ - -bool ftServer::ConvertSharedFilePath(std::string path, std::string &fullpath) -{ - return mFileDatabase->convertSharedFilePath(path, fullpath); -} - -void ftServer::updateSinceGroupPermissionsChanged() -{ - mFileDatabase->forceSyncWithPeers(); -} -void ftServer::ForceDirectoryCheck(bool add_safe_delay) -{ - mFileDatabase->forceDirectoryCheck(add_safe_delay); - return; -} - -bool ftServer::InDirectoryCheck() -{ - return mFileDatabase->inDirectoryCheck(); -} - -bool ftServer::getSharedDirectories(std::list &dirs) -{ - mFileDatabase->getSharedDirectories(dirs); - return true; -} - -bool ftServer::setSharedDirectories(const std::list& dirs) -{ - mFileDatabase->setSharedDirectories(dirs); - return true; -} - -bool ftServer::addSharedDirectory(const SharedDirInfo& dir) -{ - SharedDirInfo _dir = dir; - _dir.filename = RsDirUtil::convertPathToUnix(_dir.filename); - - std::list dirList; - mFileDatabase->getSharedDirectories(dirList); - - // check that the directory is not already in the list. - for(std::list::const_iterator it(dirList.begin());it!=dirList.end();++it) - if((*it).filename == _dir.filename) - return false ; - - // ok then, add the shared directory. - dirList.push_back(_dir); - - mFileDatabase->setSharedDirectories(dirList); - return true; -} - -bool ftServer::updateShareFlags(const SharedDirInfo& info) -{ - mFileDatabase->updateShareFlags(info); - - return true ; -} - -bool ftServer::removeSharedDirectory(std::string dir) -{ - dir = RsDirUtil::convertPathToUnix(dir); - - std::list dirList; - std::list::iterator it; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::removeSharedDirectory(" << dir << ")" << std::endl; -#endif - - mFileDatabase->getSharedDirectories(dirList); - -#ifdef SERVER_DEBUG - for(it = dirList.begin(); it != dirList.end(); ++it) - FTSERVER_DEBUG() << " existing: " << (*it).filename << std::endl; -#endif - - for(it = dirList.begin();it!=dirList.end() && (*it).filename != dir;++it) ; - - if(it == dirList.end()) - { - FTSERVER_ERROR() << "(EE) ftServer::removeSharedDirectory(): Cannot Find Directory... Fail" << std::endl; - return false; - } - - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " Updating Directories" << std::endl; -#endif - - dirList.erase(it); - mFileDatabase->setSharedDirectories(dirList); - - return true; -} - -bool ftServer::getIgnoreLists(std::list& ignored_prefixes, std::list& ignored_suffixes,uint32_t& ignore_flags) -{ - return mFileDatabase->getIgnoreLists(ignored_prefixes,ignored_suffixes,ignore_flags) ; -} -void ftServer::setIgnoreLists(const std::list& ignored_prefixes, const std::list& ignored_suffixes, uint32_t ignore_flags) -{ - mFileDatabase->setIgnoreLists(ignored_prefixes,ignored_suffixes,ignore_flags) ; -} - -bool ftServer::watchEnabled() { return mFileDatabase->watchEnabled() ; } -int ftServer::watchPeriod() const { return mFileDatabase->watchPeriod()/60 ; } -bool ftServer::followSymLinks() const { return mFileDatabase->followSymLinks() ; } -bool ftServer::ignoreDuplicates() { return mFileDatabase->ignoreDuplicates() ; } -int ftServer::maxShareDepth() const { return mFileDatabase->maxShareDepth() ; } - -void ftServer::setWatchEnabled(bool b) { mFileDatabase->setWatchEnabled(b) ; } -void ftServer::setWatchPeriod(int minutes) { mFileDatabase->setWatchPeriod(minutes*60) ; } -void ftServer::setFollowSymLinks(bool b) { mFileDatabase->setFollowSymLinks(b) ; } -void ftServer::setIgnoreDuplicates(bool ignore) { mFileDatabase->setIgnoreDuplicates(ignore); } -void ftServer::setMaxShareDepth(int depth) { mFileDatabase->setMaxShareDepth(depth) ; } - -void ftServer::togglePauseHashingProcess() { mFileDatabase->togglePauseHashingProcess() ; } -bool ftServer::hashingProcessPaused() { return mFileDatabase->hashingProcessPaused() ; } - -bool ftServer::getShareDownloadDirectory() -{ - std::list dirList; - mFileDatabase->getSharedDirectories(dirList); - - std::string dir = mFtController->getDownloadDirectory(); - - // check if the download directory is in the list. - for (std::list::const_iterator it(dirList.begin()); it != dirList.end(); ++it) - if ((*it).filename == dir) - return true; - - return false; -} - -bool ftServer::shareDownloadDirectory(bool share) -{ - if (share) - { - /* Share */ - SharedDirInfo inf ; - inf.filename = mFtController->getDownloadDirectory(); - inf.shareflags = DIR_FLAGS_ANONYMOUS_DOWNLOAD ; - - return addSharedDirectory(inf); - } - else - { - /* Unshare */ - std::string dir = mFtController->getDownloadDirectory(); - return removeSharedDirectory(dir); - } -} - -/***************************************************************/ -/****************** End of RsFiles Interface *******************/ -/***************************************************************/ - -//bool ftServer::loadConfigMap(std::map &/*configMap*/) -//{ -// return true; -//} - -/***************************************************************/ -/********************** Data Flow **********************/ -/***************************************************************/ - -bool ftServer::sendTurtleItem(const RsPeerId& peerId,const RsFileHash& hash,RsTurtleGenericTunnelItem *item) -{ - // we cannot look in the encrypted hash map, since the same hash--on this side of the FT--can be used with both - // encrypted and unencrypted peers ids. So the information comes from the virtual peer Id. - - RsFileHash encrypted_hash; - - if(findEncryptedHash(peerId,encrypted_hash)) - { - // we encrypt the item - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "Sending turtle item to peer ID " << peerId << " using encrypted tunnel." << std::endl; -#endif - - RsTurtleGenericDataItem *encrypted_item ; - - if(!encryptItem(item, hash, encrypted_item)) - return false ; - - encrypted_item->setPriorityLevel(item->priority_level()); - - delete item ; - - mTurtleRouter->sendTurtleData(peerId,encrypted_item) ; - } - else - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "Sending turtle item to peer ID " << peerId << " using non uncrypted tunnel." << std::endl; -#endif - mTurtleRouter->sendTurtleData(peerId,item) ; - } - - return true ; -} - -/* Client Send */ -bool ftServer::sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendDataRequest() to peer " << peerId << " for hash " << hash << ", offset=" << offset << ", chunk size="<< chunksize << std::endl; -#endif - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleFileRequestItem *item = new RsTurtleFileRequestItem ; - - item->chunk_offset = offset ; - item->chunk_size = chunksize ; - - sendTurtleItem(peerId,hash,item) ; - } - else - { - /* create a packet */ - /* push to networking part */ - RsFileTransferDataRequestItem *rfi = new RsFileTransferDataRequestItem(); - - /* id */ - rfi->PeerId(peerId); - - /* file info */ - rfi->file.filesize = size; - rfi->file.hash = hash; /* ftr->hash; */ - - /* offsets */ - rfi->fileoffset = offset; /* ftr->offset; */ - rfi->chunksize = chunksize; /* ftr->chunk; */ - - sendItem(rfi); - } - - return true; -} - -bool ftServer::sendChunkMapRequest(const RsPeerId& peerId,const RsFileHash& hash,bool is_client) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendChunkMapRequest() to peer " << peerId << " for hash " << hash << std::endl; -#endif - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ; - sendTurtleItem(peerId,hash,item) ; - } - else - { - /* create a packet */ - /* push to networking part */ - RsFileTransferChunkMapRequestItem *rfi = new RsFileTransferChunkMapRequestItem(); - - /* id */ - rfi->PeerId(peerId); - - /* file info */ - rfi->hash = hash; /* ftr->hash; */ - rfi->is_client = is_client ; - - sendItem(rfi); - } - - return true ; -} - -bool ftServer::sendChunkMap(const RsPeerId& peerId,const RsFileHash& hash,const CompressedChunkMap& map,bool is_client) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendChunkMap() to peer " << peerId << " for hash " << hash << std::endl; -#endif - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleFileMapItem *item = new RsTurtleFileMapItem ; - item->compressed_map = map ; - sendTurtleItem(peerId,hash,item) ; - } - else - { - /* create a packet */ - /* push to networking part */ - RsFileTransferChunkMapItem *rfi = new RsFileTransferChunkMapItem(); - - /* id */ - rfi->PeerId(peerId); - - /* file info */ - rfi->hash = hash; /* ftr->hash; */ - rfi->is_client = is_client; /* ftr->hash; */ - rfi->compressed_map = map; /* ftr->hash; */ - - sendItem(rfi); - } - - return true ; -} - -bool ftServer::sendSingleChunkCRCRequest(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendSingleCRCRequest() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl; -#endif - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem; - item->chunk_number = chunk_number ; - - sendTurtleItem(peerId,hash,item) ; - } - else - { - /* create a packet */ - /* push to networking part */ - RsFileTransferSingleChunkCrcRequestItem *rfi = new RsFileTransferSingleChunkCrcRequestItem(); - - /* id */ - rfi->PeerId(peerId); - - /* file info */ - rfi->hash = hash; /* ftr->hash; */ - rfi->chunk_number = chunk_number ; - - sendItem(rfi); - } - - return true ; -} - -bool ftServer::sendSingleChunkCRC(const RsPeerId& peerId,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) -{ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendSingleCRC() to peer " << peerId << " for hash " << hash << ", chunk number=" << chunk_number << std::endl; -#endif - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleChunkCrcItem *item = new RsTurtleChunkCrcItem; - item->chunk_number = chunk_number ; - item->check_sum = crc ; - - sendTurtleItem(peerId,hash,item) ; - } - else - { - /* create a packet */ - /* push to networking part */ - RsFileTransferSingleChunkCrcItem *rfi = new RsFileTransferSingleChunkCrcItem(); - - /* id */ - rfi->PeerId(peerId); - - /* file info */ - rfi->hash = hash; /* ftr->hash; */ - rfi->check_sum = crc; - rfi->chunk_number = chunk_number; - - sendItem(rfi); - } - - return true ; -} - -/* Server Send */ -bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data) -{ - /* create a packet */ - /* push to networking part */ - uint32_t tosend = chunksize; - uint64_t offset = 0; - uint32_t chunk; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendData() to " << peerId << ", hash: " << hash << " offset: " << baseoffset << " chunk: " << chunksize << " data: " << data << std::endl; -#endif - - while(tosend > 0) - { - //static const uint32_t MAX_FT_CHUNK = 32 * 1024; /* 32K */ - //static const uint32_t MAX_FT_CHUNK = 16 * 1024; /* 16K */ - // - static const uint32_t MAX_FT_CHUNK = 8 * 1024; /* 16K */ - - /* workout size */ - chunk = MAX_FT_CHUNK; - if (chunk > tosend) - { - chunk = tosend; - } - - /******** New Serialiser Type *******/ - - if(mTurtleRouter->isTurtlePeer(peerId)) - { - RsTurtleFileDataItem *item = new RsTurtleFileDataItem ; - - item->chunk_offset = offset+baseoffset ; - item->chunk_size = chunk; - item->chunk_data = rs_malloc(chunk) ; - - if(item->chunk_data == NULL) - { - delete item; - return false; - } - memcpy(item->chunk_data,&(((uint8_t *) data)[offset]),chunk) ; - - sendTurtleItem(peerId,hash,item) ; - } - else - { - RsFileTransferDataItem *rfd = new RsFileTransferDataItem(); - - /* set id */ - rfd->PeerId(peerId); - - /* file info */ - rfd->fd.file.filesize = size; - rfd->fd.file.hash = hash; - rfd->fd.file.name = ""; /* blank other data */ - rfd->fd.file.path = ""; - rfd->fd.file.pop = 0; - rfd->fd.file.age = 0; - - rfd->fd.file_offset = baseoffset + offset; - - /* file data */ - rfd->fd.binData.setBinData( &(((uint8_t *) data)[offset]), chunk); - - sendItem(rfd); - - /* print the data pointer */ -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::sendData() Packet: " << " offset: " << rfd->fd.file_offset << " chunk: " << chunk << " len: " << rfd->fd.binData.bin_len << " data: " << rfd->fd.binData.bin_data << std::endl; -#endif - } - - offset += chunk; - tosend -= chunk; - } - - /* clean up data */ - free(data); - - return true; -} - -// Encrypts the given item using aead-chacha20-poly1305 -// -// The format is the following -// -// [encryption format] [random initialization vector] [encrypted data size] [encrypted data] [authentication tag] -// 4 bytes 12 bytes 4 bytes variable 16 bytes -// -// +-------------------- authenticated data part ----------------------+ -// -// -// Encryption format: -// ae ad 01 01 : encryption using AEAD, format 01 (authed with Poly1305 ), version 01 -// ae ad 02 01 : encryption using AEAD, format 02 (authed with HMAC Sha256), version 01 -// -// - -void ftServer::deriveEncryptionKey(const RsFileHash& hash, uint8_t *key) -{ - // The encryption key is simply the 256 hash of the - SHA256_CTX sha_ctx ; - - if(SHA256_DIGEST_LENGTH != 32) - throw std::runtime_error("Warning: can't compute Sha1Sum with sum size != 32") ; - - SHA256_Init(&sha_ctx); - SHA256_Update(&sha_ctx, hash.toByteArray(), hash.SIZE_IN_BYTES); - SHA256_Final (key, &sha_ctx); -} - -#ifdef USE_NEW_METHOD -static const uint32_t ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE = 12 ; -static const uint32_t ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE = 16 ; -static const uint32_t ENCRYPTED_FT_HEADER_SIZE = 4 ; -static const uint32_t ENCRYPTED_FT_EDATA_SIZE = 4 ; - -static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 = 0x01 ; -static const uint8_t ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 = 0x02 ; -#endif //USE_NEW_METHOD - -bool ftServer::encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item) -{ -#ifndef USE_NEW_METHOD - uint32_t item_serialized_size = size(clear_item) ; - - RsTemporaryMemory data(item_serialized_size) ; - - if(data == NULL) - return false ; - - serialise(clear_item, data, &item_serialized_size); - - uint8_t encryption_key[32] ; - deriveEncryptionKey(hash,encryption_key) ; - - return p3turtle::encryptData(data,item_serialized_size,encryption_key,encrypted_item) ; -#else - uint8_t initialization_vector[ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE] ; - - RSRandom::random_bytes(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::Encrypting ft item." << std::endl; - FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl; -#endif - - uint32_t item_serialized_size = size(clear_item) ; - uint32_t total_data_size = ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE + item_serialized_size + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " clear part size : " << size(clear_item) << std::endl; - FTSERVER_DEBUG() << " total item size : " << total_data_size << std::endl; -#endif - - encrypted_item = new RsTurtleGenericDataItem ; - encrypted_item->data_bytes = rs_malloc( total_data_size ) ; - encrypted_item->data_size = total_data_size ; - - if(encrypted_item->data_bytes == NULL) - return false ; - - uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ; - uint32_t edata_size = item_serialized_size; - uint32_t offset = 0; - - edata[0] = 0xae ; - edata[1] = 0xad ; - edata[2] = ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256 ; // means AEAD_chacha20_sha256 - edata[3] = 0x01 ; - - offset += ENCRYPTED_FT_HEADER_SIZE; - uint32_t aad_offset = offset ; - uint32_t aad_size = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ; - - memcpy(&edata[offset], initialization_vector, ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ; - offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ; - - edata[offset+0] = (edata_size >> 0) & 0xff ; - edata[offset+1] = (edata_size >> 8) & 0xff ; - edata[offset+2] = (edata_size >> 16) & 0xff ; - edata[offset+3] = (edata_size >> 24) & 0xff ; - - offset += ENCRYPTED_FT_EDATA_SIZE ; - - uint32_t ser_size = (uint32_t)((int)total_data_size - (int)offset); - - serialise(clear_item,&edata[offset], &ser_size); - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " clear item : " << RsUtil::BinToHex(&edata[offset],std::min(50,(int)total_data_size-(int)offset)) << "(...)" << std::endl; -#endif - - uint32_t clear_item_offset = offset ; - offset += edata_size ; - - uint32_t authentication_tag_offset = offset ; - assert(ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + offset == total_data_size) ; - - uint8_t encryption_key[32] ; - deriveEncryptionKey(hash,encryption_key) ; - - if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305) - librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ; - else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256) - librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],true) ; - else - return false ; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl; - FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl; - FTSERVER_DEBUG() << " final item : " << RsUtil::BinToHex(&edata[0],std::min(50u,total_data_size)) << "(...)" << std::endl; -#endif - - return true ; -#endif -} - -// Decrypts the given item using aead-chacha20-poly1305 - -bool ftServer::decryptItem(const RsTurtleGenericDataItem *encrypted_item,const RsFileHash& hash,RsTurtleGenericTunnelItem *& decrypted_item) -{ -#ifndef USE_NEW_METHOD - unsigned char *data = NULL ; - uint32_t data_size = 0 ; - - uint8_t encryption_key[32] ; - deriveEncryptionKey(hash,encryption_key) ; - - if(!p3turtle::decryptItem(encrypted_item,encryption_key,data,data_size)) - { - FTSERVER_ERROR() << "Cannot decrypt data!" << std::endl; - - if(data) - free(data) ; - return false ; - } - decrypted_item = dynamic_cast(deserialise(data,&data_size)) ; - free(data); - - return (decrypted_item != NULL); - -#else - uint8_t encryption_key[32] ; - deriveEncryptionKey(hash,encryption_key) ; - - uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ; - uint32_t offset = 0; - - if(encrypted_item->data_size < ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE) return false ; - - if(edata[0] != 0xae) return false ; - if(edata[1] != 0xad) return false ; - if(edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305 && edata[2] != ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256) return false ; - if(edata[3] != 0x01) return false ; - - offset += ENCRYPTED_FT_HEADER_SIZE ; - uint32_t aad_offset = offset ; - uint32_t aad_size = ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ; - - uint8_t *initialization_vector = &edata[offset] ; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::decrypting ft item." << std::endl; - FTSERVER_DEBUG() << " item data : " << RsUtil::BinToHex(edata,std::min(50u,encrypted_item->data_size)) << "(...)" << std::endl; - FTSERVER_DEBUG() << " hash : " << hash << std::endl; - FTSERVER_DEBUG() << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl; - FTSERVER_DEBUG() << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl; -#endif - - offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ; - - uint32_t edata_size = 0 ; - edata_size += ((uint32_t)edata[offset+0]) << 0 ; - edata_size += ((uint32_t)edata[offset+1]) << 8 ; - edata_size += ((uint32_t)edata[offset+2]) << 16 ; - edata_size += ((uint32_t)edata[offset+3]) << 24 ; - - if(edata_size + ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE != encrypted_item->data_size) - { - FTSERVER_ERROR() << " ERROR: encrypted data size is " << edata_size << ", should be " << encrypted_item->data_size - (ENCRYPTED_FT_EDATA_SIZE + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_HEADER_SIZE ) << std::endl; - return false ; - } - - offset += ENCRYPTED_FT_EDATA_SIZE ; - uint32_t clear_item_offset = offset ; - - uint32_t authentication_tag_offset = offset + edata_size ; -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl; -#endif - - bool result ; - - if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_POLY1305) - result = librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ; - else if(edata[2] == ENCRYPTED_FT_FORMAT_AEAD_CHACHA20_SHA256) - result = librs::crypto::AEAD_chacha20_sha256 (encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset],false) ; - else - return false ; - -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << " authen. result : " << result << std::endl; - FTSERVER_DEBUG() << " decrypted daya : " << RsUtil::BinToHex(&edata[clear_item_offset],std::min(50u,edata_size)) << "(...)" << std::endl; -#endif - - if(!result) - { - FTSERVER_ERROR() << "(EE) decryption/authentication went wrong." << std::endl; - return false ; - } - - decrypted_item = dynamic_cast(deserialise(&edata[clear_item_offset],&edata_size)) ; - - if(decrypted_item == NULL) - return false ; - - return true ; -#endif -} - -bool ftServer::encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash) -{ - hash_of_hash = RsDirUtil::sha1sum(hash.toByteArray(),hash.SIZE_IN_BYTES); - return true ; -} - -bool ftServer::findEncryptedHash(const RsPeerId& virtual_peer_id, RsFileHash& encrypted_hash) -{ - RS_STACK_MUTEX(srvMutex); - - std::map::const_iterator it = mEncryptedPeerIds.find(virtual_peer_id) ; - - if(it != mEncryptedPeerIds.end()) - { - encrypted_hash = it->second ; - return true ; - } - else - return false ; -} - -bool ftServer::findRealHash(const RsFileHash& hash, RsFileHash& real_hash) -{ - RS_STACK_MUTEX(srvMutex); - std::map::const_iterator it = mEncryptedHashes.find(hash) ; - - if(it != mEncryptedHashes.end()) - { - real_hash = it->second ; - return true ; - } - else - return false ; -} - -TurtleSearchRequestId ftServer::turtleSearch(const std::string& string_to_match) -{ - return mTurtleRouter->turtleSearch(string_to_match) ; -} -TurtleSearchRequestId ftServer::turtleSearch(const RsRegularExpression::LinearizedExpression& expr) -{ - return mTurtleRouter->turtleSearch(expr) ; -} - -#warning we should do this here, but for now it is done by turtle router. -// // Dont delete the item. The client (p3turtle) is doing it after calling this. -// // -// void ftServer::receiveSearchResult(RsTurtleSearchResultItem *item) -// { -// RsTurtleFTSearchResultItem *ft_sr = dynamic_cast(item) ; -// -// if(ft_sr == NULL) -// { -// FTSERVER_ERROR() << "(EE) ftServer::receiveSearchResult(): item cannot be cast to a RsTurtleFTSearchResultItem" << std::endl; -// return ; -// } -// -// RsServer::notify()->notifyTurtleSearchResult(ft_sr->request_id,ft_sr->result) ; -// } - -// Dont delete the item. The client (p3turtle) is doing it after calling this. -// -void ftServer::receiveTurtleData(const RsTurtleGenericTunnelItem *i, - const RsFileHash& hash, - const RsPeerId& virtual_peer_id, - RsTurtleGenericTunnelItem::Direction direction) -{ - if(i->PacketSubType() == RS_TURTLE_SUBTYPE_GENERIC_DATA) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "Received encrypted data item. Trying to decrypt" << std::endl; -#endif - - RsFileHash real_hash ; - - if(!findRealHash(hash,real_hash)) - { - FTSERVER_ERROR() << "(EE) Cannot find real hash for encrypted data item with H(H(F))=" << hash << ". This is unexpected." << std::endl; - return ; - } - - RsTurtleGenericTunnelItem *decrypted_item ; - if(!decryptItem(dynamic_cast(i),real_hash,decrypted_item)) - { - FTSERVER_ERROR() << "(EE) decryption error." << std::endl; - return ; - } - - receiveTurtleData(decrypted_item, real_hash, virtual_peer_id,direction) ; - - delete decrypted_item ; - return ; - } - - switch(i->PacketSubType()) - { - case RS_TURTLE_SUBTYPE_FILE_REQUEST: - { - const RsTurtleFileRequestItem *item = dynamic_cast(i) ; - if (item) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received file data request for " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ; - } - } - break ; - - case RS_TURTLE_SUBTYPE_FILE_DATA : - { - const RsTurtleFileDataItem *item = dynamic_cast(i) ; - if (item) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received file data for " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ; - - const_cast(item)->chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted - // down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData - } - } - break ; - - case RS_TURTLE_SUBTYPE_FILE_MAP : - { - const RsTurtleFileMapItem *item = dynamic_cast(i) ; - if (item) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received chunk map for hash " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; - } - } - break ; - - case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST: - { - //RsTurtleFileMapRequestItem *item = dynamic_cast(i) ; -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received chunkmap request for hash " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; - } - break ; - - case RS_TURTLE_SUBTYPE_CHUNK_CRC : - { - const RsTurtleChunkCrcItem *item = dynamic_cast(i) ; - if (item) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received single chunk CRC for hash " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ; - } - } - break ; - - case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST: - { - const RsTurtleChunkCrcRequestItem *item = dynamic_cast(i) ; - if (item) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::receiveTurtleData(): received single chunk CRC request for hash " << hash << " from peer " << virtual_peer_id << std::endl; -#endif - getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ; - } - } - break ; - default: - FTSERVER_ERROR() << "WARNING: Unknown packet type received: sub_id=" << reinterpret_cast(i->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ; - } -} - -/* NB: The rsCore lock must be activated before calling this. - * This Lock should be moved lower into the system... - * most likely destination is in ftServer. - */ -int ftServer::tick() -{ - bool moreToTick = false ; - - if(handleIncoming()) - moreToTick = true; - - static rstime_t last_law_priority_tasks_handling_time = 0 ; - rstime_t now = time(NULL) ; - - if(last_law_priority_tasks_handling_time + FILE_TRANSFER_LOW_PRIORITY_TASKS_PERIOD < now) - { - last_law_priority_tasks_handling_time = now ; - - mFtDataplex->deleteUnusedServers() ; - mFtDataplex->handlePendingCrcRequests() ; - mFtDataplex->dispatchReceivedChunkCheckSum() ; - cleanTimedOutSearches(); - } - - return moreToTick; -} - -bool ftServer::checkUploadLimit(const RsPeerId& pid,const RsFileHash& hash) -{ - // No need for this extra cost if the value means "unlimited" - -#ifdef SERVER_DEBUG - std::cerr << "Checking upload limit for friend " << pid << " and hash " << hash << ": " ; -#endif - - uint32_t max_ups = mFtController->getMaxUploadsPerFriend() ; - - RS_STACK_MUTEX(srvMutex) ; - - if(max_ups == 0) - { -#ifdef SERVER_DEBUG - std::cerr << " no limit! returning true." << std::endl; -#endif - return true ; - } -#ifdef SERVER_DEBUG - std::cerr << " max=" << max_ups ; -#endif - - // Find the latest records for this pid. - - std::map& tmap(mUploadLimitMap[pid]) ; - std::map::iterator it ; - - rstime_t now = time(NULL) ; - - // If the limit has been decresed, we arbitrarily drop some ongoing slots. - - while(tmap.size() > max_ups) - tmap.erase(tmap.begin()) ; - - // Look in the upload record map. If it's not full, directly allocate a slot. If full, re-use an existing slot if a file is already cited. - - if(tmap.size() < max_ups || (tmap.size()==max_ups && tmap.end() != (it = tmap.find(hash)))) - { -#ifdef SERVER_DEBUG - std::cerr << " allocated slot for this hash => true" << std::endl; -#endif - - tmap[hash] = now ; - return true ; - } - - // There's no room in the used slots, but maybe some of them are not used anymore, in which case we remove them, which freeze a slot. - uint32_t cleaned = 0 ; - - for(it = tmap.begin();it!=tmap.end() && cleaned<2;) - if(it->second + FILE_TRANSFER_MAX_DELAY_BEFORE_DROP_USAGE_RECORD < now) - { - std::map::iterator tmp(it) ; - ++tmp; - tmap.erase(it) ; - it = tmp; - ++cleaned ; - } - else - ++it ; - - if(cleaned > 0) - { -#ifdef SERVER_DEBUG - std::cerr << " cleaned up " << cleaned << " old hashes => true" << std::endl; -#endif - tmap[hash] = now ; - return true ; - } - -#ifdef SERVER_DEBUG - std::cerr << " no slot for this hash => false" << std::endl; -#endif - return false ; -} - -int ftServer::handleIncoming() -{ - // now File Input. - int nhandled = 0 ; - - RsItem *item = NULL ; - - while(NULL != (item = recvItem())) - { - nhandled++ ; - - switch(item->PacketSubType()) - { - case RS_PKT_SUBTYPE_FT_DATA_REQUEST: - { - RsFileTransferDataRequestItem *f = dynamic_cast(item) ; - - if (f && checkUploadLimit(f->PeerId(),f->file.hash)) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received data request for hash " << f->file.hash << ", offset=" << f->fileoffset << ", chunk size=" << f->chunksize << std::endl; -#endif - mFtDataplex->recvDataRequest(f->PeerId(), f->file.hash, f->file.filesize, f->fileoffset, f->chunksize); - } - } - break ; - - case RS_PKT_SUBTYPE_FT_DATA: - { - RsFileTransferDataItem *f = dynamic_cast(item) ; - if (f) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received data for hash " << f->fd.file.hash << ", offset=" << f->fd.file_offset << ", chunk size=" << f->fd.binData.bin_len << std::endl; -#endif - mFtDataplex->recvData(f->PeerId(), f->fd.file.hash, f->fd.file.filesize, f->fd.file_offset, f->fd.binData.bin_len, f->fd.binData.bin_data); - - /* we've stolen the data part -> so blank before delete - */ - f->fd.binData.TlvShallowClear(); - } - } - break ; - - case RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST: - { - RsFileTransferChunkMapRequestItem *f = dynamic_cast(item) ; - if (f) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received chunkmap request for hash " << f->hash << ", client=" << f->is_client << std::endl; -#endif - mFtDataplex->recvChunkMapRequest(f->PeerId(), f->hash,f->is_client) ; - } - } - break ; - - case RS_PKT_SUBTYPE_FT_CHUNK_MAP: - { - RsFileTransferChunkMapItem *f = dynamic_cast(item) ; - if (f) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received chunkmap for hash " << f->hash << ", client=" << f->is_client << /*", map=" << f->compressed_map <<*/ std::endl; -#endif - mFtDataplex->recvChunkMap(f->PeerId(), f->hash,f->compressed_map,f->is_client) ; - } - } - break ; - - case RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST: - { - RsFileTransferSingleChunkCrcRequestItem *f = dynamic_cast(item) ; - if (f) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << std::endl; -#endif - mFtDataplex->recvSingleChunkCRCRequest(f->PeerId(), f->hash,f->chunk_number) ; - } - } - break ; - - case RS_PKT_SUBTYPE_FT_CHUNK_CRC: - { - RsFileTransferSingleChunkCrcItem *f = dynamic_cast(item) ; - if (f) - { -#ifdef SERVER_DEBUG - FTSERVER_DEBUG() << "ftServer::handleIncoming: received single chunk crc req for hash " << f->hash << ", chunk number=" << f->chunk_number << ", checksum = " << f->check_sum << std::endl; -#endif - mFtDataplex->recvSingleChunkCRC(f->PeerId(), f->hash,f->chunk_number,f->check_sum); - } - } - break ; - } - - delete item ; - } - - return nhandled; -} - -/********************************** - ********************************** - ********************************** - *********************************/ - -void ftServer::ftReceiveSearchResult(RsTurtleFTSearchResultItem *item) -{ - bool hasCallback = false; - - { - RS_STACK_MUTEX(mSearchCallbacksMapMutex); - auto cbpt = mSearchCallbacksMap.find(item->request_id); - if(cbpt != mSearchCallbacksMap.end()) - { - hasCallback = true; - - std::vector cRes; - for(auto& res: std::as_const(item->result)) - cRes.push_back(TurtleFileInfoV2(res)); - - cbpt->second.first(cRes); - } - } // end RS_STACK_MUTEX(mSearchCallbacksMapMutex); - - if(!hasCallback) - RsServer::notify()->notifyTurtleSearchResult( - item->PeerId(), item->request_id, item->result ); -} - -bool ftServer::receiveSearchRequest( - unsigned char* searchRequestData, uint32_t searchRequestDataLen, - unsigned char*& searchResultData, uint32_t& searchResultDataLen, - uint32_t& maxAllowsHits ) -{ -#ifdef RS_DEEP_FILES_INDEX - std::unique_ptr recvItem( - RsServiceSerializer::deserialise( - searchRequestData, &searchRequestDataLen ) ); - - if(!recvItem) - { - RsWarn() << __PRETTY_FUNCTION__ << " Search request deserialization " - << "failed" << std::endl; - return false; - } - - std::unique_ptr sReqItPtr( - dynamic_cast(recvItem.get()) ); - if(!sReqItPtr) - { - RsWarn() << __PRETTY_FUNCTION__ << " Received an invalid search request" - << " " << *recvItem << std::endl; - return false; - } - recvItem.release(); - - RsFileSearchRequestItem& searchReq(*sReqItPtr); - - std::vector dRes; - DeepFilesIndex dfi(DeepFilesIndex::dbDefaultPath()); - if(dfi.search(searchReq.queryString, dRes, maxAllowsHits) > 0) - { - RsFileSearchResultItem resIt; - - for(const auto& dMatch : dRes) - resIt.mResults.push_back(TurtleFileInfoV2(dMatch)); - - searchResultDataLen = RsServiceSerializer::size(&resIt); - searchResultData = static_cast(malloc(searchResultDataLen)); - return RsServiceSerializer::serialise( - &resIt, searchResultData, &searchResultDataLen ); - } -#endif // def RS_DEEP_FILES_INDEX - - searchResultData = nullptr; - searchResultDataLen = 0; - return false; -} - -void ftServer::receiveSearchResult( - TurtleSearchRequestId requestId, unsigned char* searchResultData, - uint32_t searchResultDataLen ) -{ - if(!searchResultData || !searchResultDataLen) - { - RsWarn() << __PRETTY_FUNCTION__ << " got null paramethers " - << "searchResultData: " << static_cast(searchResultData) - << " searchResultDataLen: " << searchResultDataLen - << " seems someone else in the network have a buggy RetroShare" - << " implementation" << std::endl; - return; - } - - RS_STACK_MUTEX(mSearchCallbacksMapMutex); - auto cbpt = mSearchCallbacksMap.find(requestId); - if(cbpt != mSearchCallbacksMap.end()) - { - RsItem* recvItem = RsServiceSerializer::deserialise( - searchResultData, &searchResultDataLen ); - - if(!recvItem) - { - RsWarn() << __PRETTY_FUNCTION__ << " Search result deserialization " - << "failed" << std::endl; - return; - } - - std::unique_ptr resItPtr( - dynamic_cast(recvItem) ); - - if(!resItPtr) - { - RsWarn() << __PRETTY_FUNCTION__ << " Received invalid search result" - << std::endl; - delete recvItem; - return; - } - - cbpt->second.first(resItPtr->mResults); - } -} - -/***************************** CONFIG ****************************/ - -bool ftServer::addConfiguration(p3ConfigMgr *cfgmgr) -{ - /* add all the subbits to config mgr */ - cfgmgr->addConfiguration("ft_database.cfg" , mFileDatabase); - cfgmgr->addConfiguration("ft_extra.cfg" , mFtExtra ); - cfgmgr->addConfiguration("ft_transfers.cfg", mFtController); - - return true; -} - -#ifdef RS_DEEP_FILES_INDEX -static std::vector xapianQueryKeywords = -{ - " AND ", " OR ", " NOT ", " XOR ", " +", " -", " ( ", " ) ", " NEAR ", - " ADJ ", " \"", "\" " -}; -#endif - -bool ftServer::turtleSearchRequest( - const std::string& matchString, - const std::function& results)>& multiCallback, - rstime_t maxWait ) -{ - if(matchString.empty()) - { - RsWarn() << __PRETTY_FUNCTION__ << " match string can't be empty!" - << std::endl; - return false; - } - -#ifdef RS_DEEP_FILES_INDEX - RsFileSearchRequestItem sItem; - sItem.queryString = matchString; - - uint32_t iSize = RsServiceSerializer::size(&sItem); - uint8_t* iBuf = static_cast(malloc(iSize)); - RsServiceSerializer::serialise(&sItem, iBuf, &iSize); - - Dbg3() << __PRETTY_FUNCTION__ << " sending search request:" << sItem - << std::endl; - - TurtleRequestId xsId = mTurtleRouter->turtleSearch(iBuf, iSize, this); - - { RS_STACK_MUTEX(mSearchCallbacksMapMutex); - mSearchCallbacksMap.emplace( - xsId, - std::make_pair( - multiCallback, - std::chrono::system_clock::now() + - std::chrono::seconds(maxWait) ) ); - } // RS_STACK_MUTEX(mSearchCallbacksMapMutex); - - /* Trick to keep receiving more or less usable results from old peers */ - std::string strippedQuery = matchString; - for(const std::string& xKeyword : xapianQueryKeywords) - { - std::string::size_type pos = std::string::npos; - while( (pos = strippedQuery.find(xKeyword)) != std::string::npos ) - strippedQuery.replace(pos, xKeyword.length(), " "); - } - - Dbg3() << __PRETTY_FUNCTION__ << " sending stripped query for " - << "retro-compatibility: " << strippedQuery << std::endl; - - TurtleRequestId sId = mTurtleRouter->turtleSearch(strippedQuery); -#else // def RS_DEEP_FILES_INDEX - TurtleRequestId sId = mTurtleRouter->turtleSearch(matchString); -#endif // def RS_DEEP_FILES_INDEX - - { - RS_STACK_MUTEX(mSearchCallbacksMapMutex); - mSearchCallbacksMap.emplace( - sId, - std::make_pair( - multiCallback, - std::chrono::system_clock::now() + - std::chrono::seconds(maxWait) ) ); - } - - return true; -} - -void ftServer::cleanTimedOutSearches() -{ - RS_STACK_MUTEX(mSearchCallbacksMapMutex); - auto now = std::chrono::system_clock::now(); - for( auto cbpt = mSearchCallbacksMap.begin(); - cbpt != mSearchCallbacksMap.end(); ) - if(cbpt->second.second <= now) - cbpt = mSearchCallbacksMap.erase(cbpt); - else ++cbpt; -} - -// Offensive content file filtering - -int ftServer::banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) -{ - return mFileDatabase->banFile(real_file_hash,filename,file_size) ; -} -int ftServer::unbanFile(const RsFileHash& real_file_hash) -{ - return mFileDatabase->unbanFile(real_file_hash) ; -} -bool ftServer::getPrimaryBannedFilesList(std::map& banned_files) -{ - return mFileDatabase->getPrimaryBannedFilesList(banned_files) ; -} - -bool ftServer::isHashBanned(const RsFileHash& hash) -{ - return mFileDatabase->isFileBanned(hash); -} - -RsFileItem::~RsFileItem() = default; - -RsFileItem::RsFileItem(RsFileItemType subtype) : - RsItem( RS_PKT_VERSION_SERVICE, - static_cast(RsServiceType::FILE_TRANSFER), - static_cast(subtype) ) {} - -void RsFileSearchRequestItem::clear() { queryString.clear(); } - -void RsFileSearchResultItem::clear() { mResults.clear(); } - - -std::error_condition RsFilesErrorCategory::default_error_condition(int ev) -const noexcept -{ - switch(static_cast(ev)) - { - case RsFilesErrorNum::FILES_HANDLE_NOT_FOUND: - return std::errc::invalid_argument; - default: - return std::error_condition(ev, *this); - } -} - -std::error_condition ftServer::dirDetailsToLink( - std::string& link, - const DirDetails& dirDetails, bool fragSneak, const std::string& baseUrl ) -{ - std::unique_ptr tFileTree = - RsFileTree::fromDirDetails(dirDetails, false); - if(!tFileTree) return std::errc::invalid_argument; - - link = tFileTree->toBase64(); - - if(!baseUrl.empty()) - { - RsUrl tUrl(baseUrl); - tUrl.setQueryKV(FILES_URL_COUNT_FIELD, - std::to_string(tFileTree->mTotalFiles) ) - .setQueryKV(FILES_URL_NAME_FIELD, dirDetails.name) - .setQueryKV( FILES_URL_SIZE_FIELD, - std::to_string(tFileTree->mTotalSize) ); - if(fragSneak) - tUrl.setQueryKV(FILES_URL_DATA_FIELD, FILES_URL_FAGMENT_FORWARD) - .setFragment(link); - else tUrl.setQueryKV(FILES_URL_DATA_FIELD, link); - link = tUrl.toString(); - } - - return std::error_condition(); -} - -std::error_condition ftServer::exportCollectionLink( - std::string& link, uint64_t handle, bool fragSneak, - const std::string& baseUrl ) -{ - DirDetails tDirDet; - if(!requestDirDetails(tDirDet, handle)) - return RsFilesErrorNum::FILES_HANDLE_NOT_FOUND; - - return dirDetailsToLink(link, tDirDet, fragSneak, baseUrl); -} - -/// @see RsFiles -std::error_condition ftServer::exportFileLink( - std::string& link, const RsFileHash& fileHash, uint64_t fileSize, - const std::string& fileName, bool fragSneak, const std::string& baseUrl ) -{ - if(fileHash.isNull() || !fileSize || fileName.empty()) - return std::errc::invalid_argument; - - DirDetails tDirDet; - tDirDet.type = DIR_TYPE_FILE; - tDirDet.name = fileName; - tDirDet.hash = fileHash; - tDirDet.size = fileSize; - - return dirDetailsToLink(link, tDirDet, fragSneak, baseUrl); -} - -std::error_condition ftServer::parseFilesLink( - const std::string& link, RsFileTree& collection ) -{ - RsUrl tUrl(link); - - { - /* Handle retrocompatibility with old stile single file links - * retroshare://file?name=$FILE_NAME&size=$FILE_SIZE&hash=$FILE_HASH - */ - if( tUrl.scheme() == "retroshare" && tUrl.host() == "file" - && tUrl.hasQueryK("name") && !tUrl.getQueryV("name")->empty() - && tUrl.hasQueryK("size") && !tUrl.getQueryV("size")->empty() - && tUrl.hasQueryK("hash") && !tUrl.getQueryV("hash")->empty() ) - { - DirDetails dt; - dt.type = DIR_TYPE_FILE; - dt.hash = RsFileHash(*tUrl.getQueryV("hash")); - dt.name = *tUrl.getQueryV("name"); - try - { - dt.size = std::stoull(*tUrl.getQueryV("size")); - std::unique_ptr ft; - if( !dt.hash.isNull() && - (ft = RsFileTree::fromDirDetails(dt, true)) ) - { - collection = *ft; - return std::error_condition(); - } - } - catch (...) {} - } - } - - { - /* Handle retrocompatibility with old stile collection links - * retroshare://collection?name=$NAME&size=$SIZE&radix=$RADIX&files=$COUNT - */ - if( tUrl.scheme() == "retroshare" && tUrl.host() == "collection" - && tUrl.hasQueryK("name") && !tUrl.getQueryV("name")->empty() - && tUrl.hasQueryK("size") && !tUrl.getQueryV("size")->empty() - && tUrl.hasQueryK("radix") && !tUrl.getQueryV("radix")->empty() - && tUrl.hasQueryK("files") && !tUrl.getQueryV("files")->empty() ) - { - try - { - // Don't need the values just check they are valid numbers - std::stoull(*tUrl.getQueryV("size")); - std::stoull(*tUrl.getQueryV("files")); - - auto ft = RsFileTree::fromRadix64(*tUrl.getQueryV("radix")); - if(ft) - { - collection = *ft; - return std::error_condition(); - } - } - catch (...) {} - } - } - - // Finaly handle the new files link format - rs_view_ptr radixPtr = - tUrl.getQueryV(FILES_URL_DATA_FIELD); - if(!radixPtr) radixPtr = &link; - else if(*radixPtr == FILES_URL_FAGMENT_FORWARD) radixPtr = &tUrl.fragment(); - - std::unique_ptr tft; std::error_condition ec; - std::tie(tft, ec) = RsFileTree::fromBase64(*radixPtr); - if(tft) collection = *tft; - return ec; -} diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h deleted file mode 100644 index f6cc4b44c..000000000 --- a/libretroshare/src/ft/ftserver.h +++ /dev/null @@ -1,439 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftserver.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef FT_SERVER_HEADER -#define FT_SERVER_HEADER - -/* - * ftServer. - * - * Top level File Transfer interface. - * (replaces old filedexserver) - * - * sets up the whole File Transfer class structure. - * sets up the File Indexing side of cache system too. - * - * provides rsFiles interface for external control. - * - */ - -#include -#include -#include -#include -#include - -#include "ft/ftdata.h" -#include "turtle/turtleclientservice.h" -#include "services/p3service.h" -#include "retroshare/rsfiles.h" -#include "rsitems/rsitem.h" -#include "serialiser/rsserial.h" -#include "pqi/pqi.h" -#include "pqi/p3cfgmgr.h" - -class p3ConnectMgr; -class p3FileDatabase; - -class ftFiStore; -class ftFiMonitor; - -class ftController; -class ftExtraList; -class ftFileSearch; - -class ftDataMultiplex; -class p3turtle; - -class p3PeerMgr; -class p3ServiceControl; -class p3FileDatabase; - -enum class RsFileItemType : uint8_t -{ - NONE = 0x00, /// Only to detect ununitialized - FILE_SEARCH_REQUEST = 0x57, - FILE_SEARCH_RESULT = 0x58 -}; - -struct RsFileItem : RsItem -{ - ~RsFileItem() override; - -protected: - RsFileItem(RsFileItemType subtype); -}; - -struct RsFileSearchRequestItem : RsFileItem -{ - RsFileSearchRequestItem() : RsFileItem(RsFileItemType::FILE_SEARCH_REQUEST) - { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST); } - - std::string queryString; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { RS_SERIAL_PROCESS(queryString); } - - void clear() override; -}; - -struct RsFileSearchResultItem : RsFileItem -{ - RsFileSearchResultItem() : RsFileItem(RsFileItemType::FILE_SEARCH_RESULT) - { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT); } - - std::vector mResults; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { RS_SERIAL_PROCESS(mResults); } - - void clear() override; -}; - - -class ftServer : - public p3Service, public RsFiles, public ftDataSend, - public RsTurtleClientService, public RsServiceSerializer -{ - -public: - - /***************************************************************/ - /******************** Setup ************************************/ - /***************************************************************/ - - ftServer(p3PeerMgr *peerMgr, p3ServiceControl *serviceCtrl); - virtual RsServiceInfo getServiceInfo(); - - /* Assign important variables */ - void setConfigDirectory(std::string path); - - /* add Config Items (Extra, Controller) */ - void addConfigComponents(p3ConfigMgr *mgr); - - const RsPeerId& OwnId(); - - /* Final Setup (once everything is assigned) */ - void SetupFtServer() ; - virtual void connectToTurtleRouter(p3turtle *p) ; - virtual void connectToFileDatabase(p3FileDatabase *b); - - // Implements RsTurtleClientService - // - - uint16_t serviceId() const { return RS_SERVICE_TYPE_FILE_TRANSFER ; } - virtual bool handleTunnelRequest(const RsFileHash& hash,const RsPeerId& peer_id) ; - virtual void receiveTurtleData(const RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ; - - /// We keep this for retro-compatibility @see RsTurtleClientService - virtual void ftReceiveSearchResult(RsTurtleFTSearchResultItem *item); - - /// @see RsTurtleClientService - bool receiveSearchRequest( - unsigned char* searchRequestData, uint32_t searchRequestDataLen, - unsigned char*& search_result_data, uint32_t& searchResultDataLen, - uint32_t& maxAllowsHits ) override; - - /// @see RsTurtleClientService - void receiveSearchResult( - TurtleSearchRequestId requestId, unsigned char* searchResultData, - uint32_t searchResultDataLen ) override; - - virtual RsItem *create_item(uint16_t service,uint8_t item_type) const ; - virtual RsServiceSerializer *serializer() { return this ; } - - void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ; - void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ; - - /***************************************************************/ - /*************** Control Interface *****************************/ - /************** (Implements RsFiles) ***************************/ - /***************************************************************/ - - void StartupThreads(); - void StopThreads(); - - // member access - - ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; } - ftController *getController() const { return mFtController ; } - - /** - * @see RsFiles::getFileData - */ - bool getFileData(const RsFileHash& hash, uint64_t offset, uint32_t& requested_size,uint8_t *data); - - /*** - * Control of Downloads - ***/ - virtual bool alreadyHaveFile(const RsFileHash& hash, FileInfo &info); - virtual bool FileRequest(const std::string& fname, const RsFileHash& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list& srcIds); - virtual bool FileCancel(const RsFileHash& hash); - virtual bool FileControl(const RsFileHash& hash, uint32_t flags); - virtual bool FileClearCompleted(); - virtual bool setDestinationDirectory(const RsFileHash& hash,const std::string& new_path) ; - virtual bool setDestinationName(const RsFileHash& hash,const std::string& new_name) ; - virtual bool setChunkStrategy(const RsFileHash& hash,FileChunksInfo::ChunkStrategy s) ; - virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ; - virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ; - virtual uint32_t freeDiskSpaceLimit() const ; - virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; - virtual void setDefaultEncryptionPolicy(uint32_t policy) ; // RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT/PERMISSIVE - virtual uint32_t defaultEncryptionPolicy() ; - virtual void setMaxUploadSlotsPerFriend(uint32_t n) ; - virtual uint32_t getMaxUploadSlotsPerFriend() ; - virtual void setFilePermDirectDL(uint32_t perm) ; - virtual uint32_t filePermDirectDL() ; - - /// @see RsFiles - std::error_condition requestFiles( - const RsFileTree& collection, - const std::string& destPath = "", - const std::vector& srcIds = std::vector(), - FileRequestFlags flags = FileRequestFlags::ANONYMOUS_ROUTING - ) override; - - /// @see RsFiles - bool turtleSearchRequest( - const std::string& matchString, - const std::function& results)>& multiCallback, - rstime_t maxWait = 300 ) override; - - virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ; - virtual TurtleSearchRequestId turtleSearch(const RsRegularExpression::LinearizedExpression& expr) ; - - /// @see RsFiles - std::error_condition exportCollectionLink( - std::string& link, uint64_t handle, bool fragSneak = false, - const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL - ) override; - - /// @see RsFiles - std::error_condition exportFileLink( - std::string& link, const RsFileHash& fileHash, uint64_t fileSize, - const std::string& fileName, bool fragSneak = false, - const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL - ) override; - - /// @see RsFiles - std::error_condition parseFilesLink( - const std::string& link, RsFileTree& collection ) override; - - /*** - * Control of Downloads Priority. - ***/ - virtual uint32_t getQueueSize() ; - virtual void setQueueSize(uint32_t s) ; - virtual bool changeQueuePosition(const RsFileHash& hash, QueueMove queue_mv); - virtual bool changeDownloadSpeed(const RsFileHash& hash, int speed); - virtual bool getDownloadSpeed(const RsFileHash& hash, int & speed); - virtual bool clearDownload(const RsFileHash& hash); - //virtual void getDwlDetails(std::list & details); - - /*** - * Download/Upload Details - ***/ - virtual void FileDownloads(std::list &hashs); - virtual bool FileUploads(std::list &hashs); - virtual bool FileDetails(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info); - virtual bool FileDownloadChunksDetails(const RsFileHash& hash,FileChunksInfo& info) ; - virtual bool FileUploadChunksDetails(const RsFileHash& hash,const RsPeerId& peer_id,CompressedChunkMap& map) ; - virtual bool isEncryptedSource(const RsPeerId& virtual_peer_id) ; - - - /*** - * Extra List Access - ***/ - virtual bool ExtraFileAdd(std::string fname, const RsFileHash& hash, uint64_t size, uint32_t period, TransferRequestFlags flags); - virtual bool ExtraFileRemove(const RsFileHash& hash); - virtual bool ExtraFileHash(std::string localpath, rstime_t period, TransferRequestFlags flags); - virtual bool ExtraFileStatus(std::string localpath, FileInfo &info); - virtual bool ExtraFileMove(std::string fname, const RsFileHash& hash, uint64_t size, std::string destpath); - - - /*** - * Directory Listing / Search Interface - ***/ - virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags); - - /// @see RsFiles::RequestDirDetails - virtual bool requestDirDetails( - DirDetails &details, uint64_t handle = 0, - FileSearchFlags flags = RS_FILE_HINTS_LOCAL ); - - virtual bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) ; - virtual uint32_t getType(void *ref,FileSearchFlags flags) ; - - virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags); - virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id); - virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags); - virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id); - virtual int getSharedDirStatistics(const RsPeerId& pid, SharedDirStats& stats) ; - - virtual int banFile(const RsFileHash& real_file_hash, const std::string& filename, uint64_t file_size) ; - virtual int unbanFile(const RsFileHash& real_file_hash); - virtual bool getPrimaryBannedFilesList(std::map& banned_files) ; - virtual bool isHashBanned(const RsFileHash& hash); - - /*** - * Utility Functions - ***/ - virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath); - virtual void ForceDirectoryCheck(bool add_safe_delay); - virtual void updateSinceGroupPermissionsChanged() ; - virtual bool InDirectoryCheck(); - virtual bool copyFile(const std::string& source, const std::string& dest); - - /*** - * Directory Handling - ***/ - virtual void requestDirUpdate(void *ref) ; // triggers the update of the given reference. Used when browsing. - virtual bool setDownloadDirectory(const std::string& path); - virtual bool setPartialsDirectory(const std::string& path); - virtual std::string getDownloadDirectory(); - virtual std::string getPartialsDirectory(); - - virtual bool getSharedDirectories(std::list &dirs); - virtual bool setSharedDirectories(const std::list &dirs); - virtual bool addSharedDirectory(const SharedDirInfo& dir); - virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist ! - virtual bool removeSharedDirectory(std::string dir); - - virtual bool getIgnoreLists(std::list& ignored_prefixes, std::list& ignored_suffixes, uint32_t& ignore_flags) ; - virtual void setIgnoreLists(const std::list& ignored_prefixes, const std::list& ignored_suffixes,uint32_t ignore_flags) ; - - virtual bool getShareDownloadDirectory(); - virtual bool shareDownloadDirectory(bool share); - - virtual void setWatchPeriod(int minutes) ; - virtual int watchPeriod() const ; - virtual void setWatchEnabled(bool b) ; - virtual bool watchEnabled() ; - virtual bool followSymLinks() const; - virtual void setFollowSymLinks(bool b); - virtual void togglePauseHashingProcess(); - virtual bool hashingProcessPaused(); - - virtual void setMaxShareDepth(int depth) ; - virtual int maxShareDepth() const; - - virtual bool ignoreDuplicates() ; - virtual void setIgnoreDuplicates(bool ignore) ; - - static bool encryptHash(const RsFileHash& hash, RsFileHash& hash_of_hash); - - /***************************************************************/ - /*************** Data Transfer Interface ***********************/ - /***************************************************************/ -public: - virtual bool activateTunnels(const RsFileHash& hash,uint32_t default_encryption_policy,TransferRequestFlags flags,bool onoff); - - virtual bool sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data); - virtual bool sendDataRequest(const RsPeerId& peerId, const RsFileHash& hash, uint64_t size, uint64_t offset, uint32_t chunksize); - virtual bool sendChunkMapRequest(const RsPeerId& peer_id,const RsFileHash& hash,bool is_client) ; - virtual bool sendChunkMap(const RsPeerId& peer_id,const RsFileHash& hash,const CompressedChunkMap& cmap,bool is_client) ; - virtual bool sendSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number) ; - virtual bool sendSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ; - - static void deriveEncryptionKey(const RsFileHash& hash, uint8_t *key); - - bool encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item); - bool decryptItem(const RsTurtleGenericDataItem *encrypted_item, const RsFileHash& hash, RsTurtleGenericTunnelItem *&decrypted_item); - - /*************** Internal Transfer Fns *************************/ - virtual int tick(); - - /* Configuration */ - bool addConfiguration(p3ConfigMgr *cfgmgr); - bool ResumeTransfers(); - - /*************************** p3 Config Overload ********************/ - -protected: - int handleIncoming() ; - bool handleCacheData() ; - - /*! - * \brief sendTurtleItem - * Sends the given item into a turtle tunnel, possibly encrypting it if the type of tunnel requires it, which is known from the hash itself. - * \param peerId Peer id to send to (this is a virtual peer id from turtle service) - * \param hash hash of the file. If the item needs to be encrypted - * \param item item to send. - * \return - * true if everything goes right - */ - bool sendTurtleItem(const RsPeerId& peerId,const RsFileHash& hash,RsTurtleGenericTunnelItem *item); - - // fnds out what is the real hash of encrypted hash hash - bool findRealHash(const RsFileHash& hash, RsFileHash& real_hash); - bool findEncryptedHash(const RsPeerId& virtual_peer_id, RsFileHash& encrypted_hash); - - bool checkUploadLimit(const RsPeerId& pid,const RsFileHash& hash); - - std::error_condition dirDetailsToLink( - std::string& link, - const DirDetails& dirDetails, bool fragSneak, - const std::string& baseUrl ); - -private: - - /* no need for Mutex protection - - * as each component is protected independently. - */ - p3PeerMgr *mPeerMgr; - p3ServiceControl *mServiceCtrl; - p3FileDatabase *mFileDatabase ; - ftController *mFtController; - ftExtraList *mFtExtra; - ftDataMultiplex *mFtDataplex; - p3turtle *mTurtleRouter ; - ftFileSearch *mFtSearch; - - RsMutex srvMutex; - std::string mConfigPath; - std::string mDownloadPath; - std::string mPartialsPath; - - std::map mEncryptedHashes ; // This map is such that sha1(it->second) = it->first - std::map mEncryptedPeerIds ; // This map holds the hash to be used with each peer id - std::map > mUploadLimitMap ; - - /** Store search callbacks with timeout*/ - std::map< - TurtleRequestId, - std::pair< - std::function& results)>, - std::chrono::system_clock::time_point > - > mSearchCallbacksMap; - RsMutex mSearchCallbacksMapMutex; - - /// Cleanup mSearchCallbacksMap - void cleanTimedOutSearches(); - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; - - - -#endif diff --git a/libretroshare/src/ft/fttransfermodule.cc b/libretroshare/src/ft/fttransfermodule.cc deleted file mode 100644 index 8c6ae1f08..000000000 --- a/libretroshare/src/ft/fttransfermodule.cc +++ /dev/null @@ -1,923 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: fttransfermodule.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -/****** - * #define FT_DEBUG 1 - *****/ - -#include "util/rstime.h" - -#include "retroshare/rsturtle.h" -#include "fttransfermodule.h" - -/************************************************************************* - * Notes on file transfer strategy. - * Care must be taken not to overload pipe. best way is to time requests. - * and according adjust data rate. - * - * each peer gets a 'max_rate' which is decided on the type of transfer. - * - trickle ... - * - stream ... - * - max ... - * - * Each peer is independently managed. - * - * via the functions: - * - */ - -const double FT_TM_MAX_PEER_RATE = 100 * 1024 * 1024; /* 100MB/s */ -const uint32_t FT_TM_MAX_RESETS = 5; -const uint32_t FT_TM_MINIMUM_CHUNK = 1024; /* ie 1Kb / sec */ -const uint32_t FT_TM_DEFAULT_TRANSFER_RATE = 20*1024; /* ie 20 Kb/sec */ -const uint32_t FT_TM_RESTART_DOWNLOAD = 20; /* 20 seconds */ -const uint32_t FT_TM_DOWNLOAD_TIMEOUT = 10; /* 10 seconds */ - -const double FT_TM_RATE_INCREASE_SLOWER = 0.05 ; -const double FT_TM_RATE_INCREASE_AVERAGE = 0.3 ; -const double FT_TM_RATE_INCREASE_FASTER = 1.0 ; - -#define FT_TM_FLAG_DOWNLOADING 0 -#define FT_TM_FLAG_CANCELED 1 -#define FT_TM_FLAG_COMPLETE 2 -#define FT_TM_FLAG_CHECKING 3 -#define FT_TM_FLAG_CHUNK_CRC 4 - -peerInfo::peerInfo(const RsPeerId& peerId_in) - :peerId(peerId_in),state(PQIPEER_NOT_ONLINE),desiredRate(FT_TM_DEFAULT_TRANSFER_RATE),actualRate(FT_TM_DEFAULT_TRANSFER_RATE), - lastTS(0), - recvTS(0), lastTransfers(0), nResets(0), - rtt(0), rttActive(false), rttStart(0), rttOffset(0), - mRateIncrease(1) - { - } -// peerInfo(const RsPeerId& peerId_in,uint32_t state_in,uint32_t maxRate_in): -// peerId(peerId_in),state(state_in),desiredRate(maxRate_in),actualRate(0), -// lastTS(0), -// recvTS(0), lastTransfers(0), nResets(0), -// rtt(0), rttActive(false), rttStart(0), rttOffset(0), -// mRateIncrease(1) -// { -// return; -// } -ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftController *c) - :mFileCreator(fc), mMultiplexor(dm), mFtController(c), tfMtx("ftTransferModule"), mFlag(FT_TM_FLAG_DOWNLOADING),mPriority(SPEED_NORMAL) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - - mHash = mFileCreator->getHash(); - mSize = mFileCreator->getFileSize(); - mFileStatus.hash = mHash; - - _hash_thread = NULL ; - - // Dummy for Testing (should be handled independantly for - // each peer. - //mChunkSize = 10000; - desiredRate = FT_TM_MAX_PEER_RATE; /* 1MB/s ??? */ - actualRate = 0; - - _last_activity_time_stamp = time(NULL) ; -} - -ftTransferModule::~ftTransferModule() -{ - // Prevents deletion while called from another thread. - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -} - - -bool ftTransferModule::setFileSources(const std::list& peerIds) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - - mFileSources.clear(); - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::setFileSources()"; - std::cerr << " List of peers: " ; -#endif - - std::list::const_iterator it; - for(it = peerIds.begin(); it != peerIds.end(); ++it) - { - -#ifdef FT_DEBUG - std::cerr << " \t" << *it; -#endif - - peerInfo pInfo(*it); - mFileSources.insert(std::pair(*it,pInfo)); - } - -#ifdef FT_DEBUG - std::cerr << std::endl; -#endif - - return true; -} - -bool ftTransferModule::getFileSources(std::list &peerIds) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - std::map::iterator it; - for(it = mFileSources.begin(); it != mFileSources.end(); ++it) - { - peerIds.push_back(it->first); - } - return true; -} - -bool ftTransferModule::addFileSource(const RsPeerId& peerId) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - std::map::iterator mit; - mit = mFileSources.find(peerId); - - if (mit == mFileSources.end()) - { - /* add in new source */ - peerInfo pInfo(peerId); - mFileSources.insert(std::pair(peerId,pInfo)); - //mit = mFileSources.find(peerId); - - mMultiplexor->sendChunkMapRequest(peerId, mHash,false) ; -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::addFileSource()"; - std::cerr << " adding peer: " << peerId << " to sourceList"; - std::cerr << std::endl; -#endif - return true ; - - } - else - { -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::addFileSource()"; - std::cerr << " peer: " << peerId << " already there"; - std::cerr << std::endl; -#endif - return false; - } -} - -bool ftTransferModule::removeFileSource(const RsPeerId& peerId) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - std::map::iterator mit; - mit = mFileSources.find(peerId); - - if (mit != mFileSources.end()) - { - /* add in new source */ - mFileSources.erase(mit) ; -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::addFileSource(): removing peer: " << peerId << " from sourceList" << std::endl; -#endif - } -#ifdef FT_DEBUG - else - std::cerr << "ftTransferModule::addFileSource(): Should remove peer: " << peerId << ", but it's not in the source list. " << std::endl; -#endif - - return true; -} - -bool ftTransferModule::setPeerState(const RsPeerId& peerId,uint32_t state,uint32_t maxRate) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::setPeerState()"; - std::cerr << " peerId: " << peerId; - std::cerr << " state: " << state; - std::cerr << " maxRate: " << maxRate << std::endl; -#endif - - std::map::iterator mit; - mit = mFileSources.find(peerId); - - if (mit == mFileSources.end()) - { - /* add in new source */ - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::setPeerState()"; - std::cerr << " adding new peer to sourceList"; - std::cerr << std::endl; -#endif - return false; - } - - (mit->second).state=state; - (mit->second).desiredRate=maxRate; - // Start it off at zero.... - // (mit->second).actualRate=maxRate; /* should give big kick in right direction */ - - std::list::iterator it; - it = std::find(mOnlinePeers.begin(), mOnlinePeers.end(), peerId); - - if (state!=PQIPEER_NOT_ONLINE) - { - //change to online, add peerId in online peer list - if (it==mOnlinePeers.end()) mOnlinePeers.push_back(peerId); - } - else - { - //change to offline, remove peerId in online peer list - if (it!=mOnlinePeers.end()) mOnlinePeers.erase(it); - } - - return true; -} - - -bool ftTransferModule::getPeerState(const RsPeerId& peerId,uint32_t &state,uint32_t &tfRate) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - std::map::iterator mit; - mit = mFileSources.find(peerId); - - if (mit == mFileSources.end()) return false; - - state = (mit->second).state; - tfRate = (uint32_t) (mit->second).actualRate; - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::getPeerState()"; - std::cerr << " peerId: " << peerId; - std::cerr << " state: " << state; - std::cerr << " tfRate: " << tfRate << std::endl; -#endif - return true; -} - -uint32_t ftTransferModule::getDataRate(const RsPeerId& peerId) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - std::map::iterator mit; - mit = mFileSources.find(peerId); - if (mit == mFileSources.end()) - { -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::getDataRate()"; - std::cerr << " peerId: " << peerId; - std::cerr << " peer not exist in file sources " << std::endl; -#endif - return 0; - } - else - return (uint32_t) (mit->second).actualRate; -} -void ftTransferModule::resetActvTimeStamp() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - _last_activity_time_stamp = time(NULL); -} -rstime_t ftTransferModule::lastActvTimeStamp() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - return _last_activity_time_stamp ; -} - - //interface to client module -bool ftTransferModule::recvFileData(const RsPeerId& peerId, uint64_t offset, uint32_t chunk_size, void *data) -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::recvFileData()"; - std::cerr << " peerId: " << peerId; - std::cerr << " offset: " << offset; - std::cerr << " chunksize: " << chunk_size; - std::cerr << " data: " << data; - std::cerr << std::endl; -#endif - - bool ok = false; - - std::map::iterator mit; - mit = mFileSources.find(peerId); - - if (mit == mFileSources.end()) - { -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::recvFileData()"; - std::cerr << " peer not found in sources"; - std::cerr << std::endl; -#endif - return false; - } - ok = locked_recvPeerData(mit->second, offset, chunk_size, data); - - locked_storeData(offset, chunk_size, data); - - _last_activity_time_stamp = time(NULL) ; - - free(data) ; - return ok; -} - -void ftTransferModule::locked_requestData(const RsPeerId& peerId, uint64_t offset, uint32_t chunk_size) -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::requestData()"; - std::cerr << " peerId: " << peerId; - std::cerr << " hash: " << mHash; - std::cerr << " size: " << mSize; - std::cerr << " offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; -#endif - - mMultiplexor->sendDataRequest(peerId, mHash, mSize, offset,chunk_size); -} - -bool ftTransferModule::locked_getChunk(const RsPeerId& peer_id,uint32_t size_hint,uint64_t &offset, uint32_t &chunk_size) -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::locked_getChunk()"; - std::cerr << " hash: " << mHash; - std::cerr << " size: " << mSize; - std::cerr << " offset: " << offset; - std::cerr << " size_hint: " << size_hint; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; -#endif - - bool source_peer_map_needed ; - - bool val = mFileCreator->getMissingChunk(peer_id,size_hint,offset, chunk_size,source_peer_map_needed); - - if(source_peer_map_needed) - mMultiplexor->sendChunkMapRequest(peer_id, mHash,false) ; - -#ifdef FT_DEBUG - if (val) - { - std::cerr << "ftTransferModule::locked_getChunk()"; - std::cerr << " Answer: Chunk Available"; - std::cerr << " hash: " << mHash; - std::cerr << " size: " << mSize; - std::cerr << " offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << " peer map needed = " << source_peer_map_needed << std::endl ; - std::cerr << std::endl; - } - else - { - std::cerr << "ftTransferModule::locked_getChunk()"; - std::cerr << " Answer: No Chunk Available"; - std::cerr << " peer map needed = " << source_peer_map_needed << std::endl ; - std::cerr << std::endl; - } -#endif - - return val; -} - -bool ftTransferModule::locked_storeData(uint64_t offset, uint32_t chunk_size,void *data) -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::storeData()"; - std::cerr << " hash: " << mHash; - std::cerr << " size: " << mSize; - std::cerr << " offset: " << offset; - std::cerr << " chunk_size: " << chunk_size; - std::cerr << std::endl; -#endif - - return mFileCreator -> addFileData(offset, chunk_size, data); -} - -bool ftTransferModule::queryInactive() -{ - /* NB: Not sure about this lock... might cause deadlock. - */ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::queryInactive()" << std::endl; -#endif - - if (mFileStatus.stat == ftFileStatus::PQIFILE_INIT) - mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING; - - if (mFileStatus.stat != ftFileStatus::PQIFILE_DOWNLOADING) - { - if (mFileStatus.stat == ftFileStatus::PQIFILE_FAIL_CANCEL) - mFlag = FT_TM_FLAG_COMPLETE; //file canceled by user - return false; - } - - if (mFileStatus.stat == ftFileStatus::PQIFILE_CHECKING) - return false ; - - std::map::iterator mit; - for(mit = mFileSources.begin(); mit != mFileSources.end(); ++mit) - { - locked_tickPeerTransfer(mit->second); - } - if(mFileCreator->finished()) // transfer is complete - { - mFileStatus.stat = ftFileStatus::PQIFILE_CHECKING ; - mFlag = FT_TM_FLAG_CHECKING; - } - else - { - // request for CRCs to ask - std::vector chunks_to_ask ; - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::queryInactive() : getting chunks to check." << std::endl; -#endif - - mFileCreator->getChunksToCheck(chunks_to_ask) ; -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::queryInactive() : got " << chunks_to_ask.size() << " chunks." << std::endl; -#endif - - mMultiplexor->sendSingleChunkCRCRequests(mHash,chunks_to_ask); - } - - return true; -} - -bool ftTransferModule::cancelTransfer() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - mFileStatus.stat=ftFileStatus::PQIFILE_FAIL_CANCEL; - - return 1; -} - -bool ftTransferModule::cancelFileTransferUpward() -{ - if (mFtController) - mFtController->FileCancel(mHash); - return true; -} -bool ftTransferModule::completeFileTransfer() -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::completeFileTransfer()"; - std::cerr << std::endl; -#endif - if (mFtController) - mFtController->FlagFileComplete(mHash); - return true; -} - -int ftTransferModule::tick() -{ - queryInactive(); -#ifdef FT_DEBUG - { - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - - std::cerr << "ftTransferModule::tick()"; - std::cerr << " mFlag: " << mFlag; - std::cerr << " mHash: " << mHash; - std::cerr << " mSize: " << mSize; - std::cerr << std::endl; - - std::cerr << "Peers: "; - std::map::iterator it; - for(it = mFileSources.begin(); it != mFileSources.end(); ++it) - { - std::cerr << " " << it->first; - } - std::cerr << std::endl; - - - } -#endif - - uint32_t flags = 0; - { - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - flags = mFlag; - } - - switch (flags) - { - case FT_TM_FLAG_DOWNLOADING: //file transfer not complete - adjustSpeed(); - break; - case FT_TM_FLAG_COMPLETE: //file transfer complete - completeFileTransfer(); - break; - case FT_TM_FLAG_CANCELED: //file transfer canceled - break; - case FT_TM_FLAG_CHECKING: // Check if file hash matches the hashed data - checkFile() ; - break ; - default: - break; - } - - return 0; -} - -bool ftTransferModule::isCheckingHash() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -#ifdef FT_DEBUG - std::cerr << "isCheckingHash(): mFlag=" << mFlag << std::endl; -#endif - return mFlag == FT_TM_FLAG_CHECKING || mFlag == FT_TM_FLAG_CHUNK_CRC; -} - -class HashThread: public RsThread -{ - public: - explicit HashThread(ftFileCreator *m) - : _hashThreadMtx("HashThread"), _m(m),_finished(false),_hash("") {} - - virtual void run() - { -#ifdef FT_DEBUG - std::cerr << "hash thread is running for file " << std::endl; -#endif - RsFileHash tmphash ; - _m->hashReceivedData(tmphash) ; - - RsStackMutex stack(_hashThreadMtx) ; - _hash = tmphash ; - _finished = true ; - } - RsFileHash hash() - { - RsStackMutex stack(_hashThreadMtx) ; - return _hash ; - } - bool finished() - { - RsStackMutex stack(_hashThreadMtx) ; - return _finished ; - } - private: - RsMutex _hashThreadMtx ; - ftFileCreator *_m ; - bool _finished ; - RsFileHash _hash ; -}; - -bool ftTransferModule::checkFile() -{ - { - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::checkFile(): checking File " << mHash << std::endl ; -#endif - - // if we don't have a hashing thread, create one. - - if(_hash_thread == NULL) - { - // Note: using new is really important to avoid copy and write errors in the thread. - // - _hash_thread = new HashThread(mFileCreator) ; - _hash_thread->start("ft hash") ; -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::checkFile(): launched hashing thread for file " << mHash << std::endl ; -#endif - return false ; - } - - if(!_hash_thread->finished()) - { -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::checkFile(): file " << mHash << " is being hashed.?" << std::endl ; -#endif - return false ; - } - - RsFileHash check_hash( _hash_thread->hash() ) ; - - delete _hash_thread ; - _hash_thread = NULL ; - - if(check_hash == mHash) - { - mFlag = FT_TM_FLAG_COMPLETE ; // Transfer is complete. -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::checkFile(): hash finished. File verification complete ! Setting mFlag to 1" << std::endl ; -#endif - return true ; - } - } - - - forceCheck() ; - return false ; -} - -void ftTransferModule::forceCheck() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::forceCheck(): setting flags to force check." << std::endl ; -#endif - - mFileCreator->forceCheck() ; - mFlag = FT_TM_FLAG_DOWNLOADING ; // Ask for CRC map. - mFileStatus.stat = ftFileStatus::PQIFILE_DOWNLOADING; -} - -void ftTransferModule::adjustSpeed() -{ - RsStackMutex stack(tfMtx); /******* STACK LOCKED ******/ - - std::map::iterator mit; - - - actualRate = 0; - for(mit = mFileSources.begin(); mit != mFileSources.end(); ++mit) - { -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::adjustSpeed()"; - std::cerr << "Peer: " << mit->first; - std::cerr << " Desired Rate: " << (mit->second).desiredRate; - std::cerr << " Actual Rate: " << (mit->second).actualRate; - std::cerr << std::endl; -#endif - actualRate += mit->second.actualRate; - } - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::adjustSpeed() Totals:"; - std::cerr << "Desired Rate: " << desiredRate << " Actual Rate: " << actualRate; - std::cerr << std::endl; -#endif - - return; -} - - -/******************************************************************************* - * Actual Peer Transfer Management Code. - * - * request very tick, at rate - * - * - **/ - - -/* NOTEs on this function... - * 1) This is the critical function for deciding the rate at which ft takes place. - * 2) Some of the peers might not have the file... care must be taken avoid deadlock. - * - * Eg. A edge case which fails badly. - * Small 1K file (one chunk), with 3 sources (A,B,C). A doesn't have file. - * (a) request data from A. B & C pause cos no more data needed. - * (b) all timeout, chunk reset... then back to request again (a) and repeat. - * (c) all timeout x 5 and are disabled.... no transfer, while B&C had it all the time. - * - * To solve this we might need random waiting periods, so each peer can - * be tried. - * - * - */ - -bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info) -{ - /* how long has it been? */ - rstime_t ts = time(NULL); - - int ageRecv = ts - info.recvTS; - int ageReq = ts - info.lastTS; - - /* if offline - ignore */ - if(info.state == PQIPEER_SUSPEND) - return false; - - if (ageReq > (int) (FT_TM_RESTART_DOWNLOAD * (info.nResets + 1))) - { - // The succession of ifs, makes the process continue every 6 * FT_TM_RESTART_DOWNLOAD * FT_TM_MAX_RESETS seconds - // on average, which is one attempt every 600 seconds in the least, which corresponds to once every 10 minutes in - // average. - // - if (info.nResets > 1) /* 3rd timeout */ - { - /* 90% chance of return false... - * will mean variations in which peer - * starts first. hopefully stop deadlocks. - */ - if (rand() % 12 != 0) - return false; - } - - info.state = PQIPEER_DOWNLOADING; - info.recvTS = ts; /* reset to activate */ - info.nResets = std::min(FT_TM_MAX_RESETS,info.nResets + 1); - ageRecv = 0; - } - - if (ageRecv > (int) FT_TM_DOWNLOAD_TIMEOUT) - { - info.state = PQIPEER_IDLE; - return false; - } -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() actual rate (before): " << info.actualRate << ", lastTransfers=" << info.lastTransfers << std::endl ; - std::cerr << mHash<< " - actual rate: " << info.actualRate << " lastTransfers=" << info.lastTransfers << ". AgeReq = " << ageReq << std::endl; -#endif - /* update rate */ - - if( (info.lastTransfers > 0 && ageReq > 0) || ageReq > 2) - { - info.actualRate = info.actualRate * 0.75 + 0.25 * info.lastTransfers / (float)ageReq; - info.lastTransfers = 0; - info.lastTS = ts; - } - - /**************** - * NOTE: If we continually increase the request rate thus: ... - * uint32_t next_req = info.actualRate * 1.25; - * - * then we will achieve max data rate, but we will fill up - * peers out queue and/or network buffers..... - * - * we must therefore monitor the RTT to tell us if this is happening. - */ - - /* emergency shutdown if we are stuck in x 1.25 mode - * probably not needed - */ - -// csoler: I commented this out because that tends to make some sources -// get stuck into minimal 128 B/s rate, when multiple sources are competiting into the -// same limited bandwidth. I don't think this emergency shutdown is necessary anyway. -// -// if ((info.rttActive) && (ts - info.rttStart > FT_TM_SLOW_RTT)) -// { -// if (info.mRateIncrease > 0) -// { -//#ifdef FT_DEBUG -// std::cerr << "!!! - Emergency shutdown because rttActive is true, and age is " << ts - info.rttStart << std::endl ; -//#endif -// info.mRateIncrease = 0; -// info.rttActive = false ; // I've added this to avoid being stuck when rttActive is true -// } -// } - - /* request at more than current rate */ - uint32_t next_req = info.actualRate * (1.0 + info.mRateIncrease); -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() actual rate (after): " << actualRate - << " info.desiredRate=" << info.desiredRate - << " info.actualRate=" << info.actualRate - << ", next_req=" << next_req ; - - std::cerr << std::endl; -#endif - - if (next_req > info.desiredRate * 1.1) - { - next_req = info.desiredRate * 1.1; -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() Reached MaxRate: next_req: " << next_req; - std::cerr << std::endl; -#endif - } - - - if (next_req > FT_TM_MAX_PEER_RATE) - { - next_req = FT_TM_MAX_PEER_RATE; -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() Reached AbsMaxRate: next_req: " << next_req; - std::cerr << std::endl; -#endif - } - - - if (next_req < FT_TM_MINIMUM_CHUNK) - { - next_req = FT_TM_MINIMUM_CHUNK; -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() small chunk: next_req: " << next_req; - std::cerr << std::endl; -#endif - } - -#ifdef FT_DEBUG - std::cerr << "locked_tickPeerTransfer() desired next_req: " << next_req; - std::cerr << std::endl; -#endif - - /* do request */ - uint64_t req_offset = 0; - uint32_t req_size =0 ; - - // Loop over multiple calls to the file creator: for some reasons the file creator might not be able to - // give a plain chunk of the requested size (size hint larger than the fixed chunk size, priority given to - // an old pending chunk, etc). - // - while(next_req > 0 && locked_getChunk(info.peerId,next_req,req_offset,req_size)) - if(req_size > 0) - { - info.state = PQIPEER_DOWNLOADING; - locked_requestData(info.peerId,req_offset,req_size); - - /* start next rtt measurement */ - if (!info.rttActive) - { - info.rttStart = ts; - info.rttActive = true; - info.rttOffset = req_offset + req_size; - } - next_req -= std::min(req_size,next_req) ; - } - else - { - std::cerr << "transfermodule::Waiting for available data"; - std::cerr << std::endl; - break ; - } - - return true; -} - - - - //interface to client module -bool ftTransferModule::locked_recvPeerData(peerInfo &info, uint64_t offset, uint32_t chunk_size, void *) -{ -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::locked_recvPeerData()"; - std::cerr << " peerId: " << info.peerId; - std::cerr << " rttOffset: " << info.rttOffset; - std::cerr << " lastTransfers: " << info.lastTransfers; - std::cerr << " offset: " << offset; - std::cerr << " chunksize: " << chunk_size; - std::cerr << std::endl; -#endif - - rstime_t ts = time(NULL); - info.recvTS = ts; - info.nResets = 0; - info.state = PQIPEER_DOWNLOADING; - info.lastTransfers += chunk_size; - - if ((info.rttActive) && (info.rttOffset == offset + chunk_size)) - { - /* update tip */ - int32_t rtt = time(NULL) - info.rttStart; - - /* - * FT_TM_FAST_RTT = 1 sec. mRateIncrease = 1.00 - * FT_TM_SLOW_RTT =20 sec. mRateIncrease = 0 - * 11 sec. mRateIncrease = -0.25 - * if it is slower than this allow fast data increase. - * initial guess - linear with rtt. - * change if this leads to wild oscillations - * - */ - -// info.mRateIncrease = (FT_TM_SLOW_RTT - rtt) * -// (FT_TM_MAX_INCREASE / (FT_TM_SLOW_RTT - FT_TM_FAST_RTT)); -// -// if (info.mRateIncrease > FT_TM_MAX_INCREASE) -// info.mRateIncrease = FT_TM_MAX_INCREASE; -// -// if (info.mRateIncrease < FT_TM_MIN_INCREASE) -// info.mRateIncrease = FT_TM_MIN_INCREASE; - - switch(mPriority) - { - case SPEED_LOW : info.mRateIncrease = FT_TM_RATE_INCREASE_SLOWER ; break ; - case SPEED_NORMAL : info.mRateIncrease = FT_TM_RATE_INCREASE_AVERAGE; break ; - case SPEED_HIGH : info.mRateIncrease = FT_TM_RATE_INCREASE_FASTER ; break ; - } - info.rtt = rtt; - info.rttActive = false; - -#ifdef FT_DEBUG - std::cerr << "ftTransferModule::locked_recvPeerData()"; - std::cerr << "Updated Rate based on RTT: " << rtt; - std::cerr << " Rate increase: " << 1.0+info.mRateIncrease; - std::cerr << std::endl; -#endif - - } - return true; -} - diff --git a/libretroshare/src/ft/fttransfermodule.h b/libretroshare/src/ft/fttransfermodule.h deleted file mode 100644 index 29766dbad..000000000 --- a/libretroshare/src/ft/fttransfermodule.h +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: fttransfermodule.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef FT_TRANSFER_MODULE_HEADER -#define FT_TRANSFER_MODULE_HEADER - -/* - * FUNCTION DESCRIPTION - * - * Each Transfer Module is paired up with a single File Creator, and responsible for the transfer of one file. - * The Transfer Module is responsible for sending requests to peers at the correct data rates, and storing the returned data - * in a FileCreator. - * There are multiple Transfer Modules in the File Transfer system. Their requests are multiplexed through the Client Module. * The Transfer Module contains all the algorithms for sensible Data Requests. - * It must be able to cope with varying data rates and dropped peers without flooding the system with too many requests. - * - */ - -#include -#include -#include - -#include "ft/ftfilecreator.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftcontroller.h" - -#include "util/rsthreads.h" - -const uint32_t PQIPEER_INIT = 0x0000; -const uint32_t PQIPEER_NOT_ONLINE = 0x0001; -const uint32_t PQIPEER_DOWNLOADING = 0x0002; -const uint32_t PQIPEER_IDLE = 0x0004; -const uint32_t PQIPEER_SUSPEND = 0x0010; - -class HashThread ; - -class peerInfo -{ -public: - explicit peerInfo(const RsPeerId& peerId_in); - -// peerInfo(const RsPeerId& peerId_in,uint32_t state_in,uint32_t maxRate_in): -// peerId(peerId_in),state(state_in),desiredRate(maxRate_in),actualRate(0), -// lastTS(0), -// recvTS(0), lastTransfers(0), nResets(0), -// rtt(0), rttActive(false), rttStart(0), rttOffset(0), -// mRateIncrease(1) -// { -// return; -// } - RsPeerId peerId; - uint32_t state; - double desiredRate; /* speed at which the data should be requested */ - double actualRate; /* actual speed at which the data is received */ - - rstime_t lastTS; /* last Request */ - rstime_t recvTS; /* last Recv */ - uint32_t lastTransfers; /* data recvd in last second */ - uint32_t nResets; /* count to disable non-existant files */ - - uint32_t rtt; /* last rtt */ - bool rttActive; /* have we initialised an rtt measurement */ - rstime_t rttStart; /* ts of request */ - uint64_t rttOffset; /* end of request */ - float mRateIncrease; /* current rate increase factor */ -}; - -class ftFileStatus -{ -public: - enum Status { - PQIFILE_INIT, - PQIFILE_NOT_ONLINE, - PQIFILE_DOWNLOADING, - PQIFILE_COMPLETE, - PQIFILE_CHECKING, - PQIFILE_FAIL, - PQIFILE_FAIL_CANCEL, - PQIFILE_FAIL_NOT_AVAIL, - PQIFILE_FAIL_NOT_OPEN, - PQIFILE_FAIL_NOT_SEEK, - PQIFILE_FAIL_NOT_WRITE, - PQIFILE_FAIL_NOT_READ, - PQIFILE_FAIL_BAD_PATH - }; - - ftFileStatus():hash(""),stat(PQIFILE_INIT) {} - explicit ftFileStatus(const RsFileHash& hash_in):hash(hash_in),stat(PQIFILE_INIT) {} - - RsFileHash hash; - Status stat; -}; - -class ftTransferModule -{ -public: - ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftController *c); - ~ftTransferModule(); - - //interface to download controller - bool setFileSources(const std::list& peerIds); - bool addFileSource(const RsPeerId& peerId); - bool removeFileSource(const RsPeerId& peerId); - bool setPeerState(const RsPeerId& peerId,uint32_t state,uint32_t maxRate); //state = ONLINE/OFFLINE - bool getFileSources(std::list &peerIds); - bool getPeerState(const RsPeerId& peerId,uint32_t &state,uint32_t &tfRate); - uint32_t getDataRate(const RsPeerId& peerId); - bool cancelTransfer(); - bool cancelFileTransferUpward(); - bool completeFileTransfer(); - bool isCheckingHash() ; - void forceCheck() ; - - //interface to multiplex module - bool recvFileData(const RsPeerId& peerId, uint64_t offset, uint32_t chunk_size, void *data); - void locked_requestData(const RsPeerId& peerId, uint64_t offset, uint32_t chunk_size); - - //interface to file creator - bool locked_getChunk(const RsPeerId& peer_id,uint32_t size_hint,uint64_t &offset, uint32_t &chunk_size); - bool locked_storeData(uint64_t offset, uint32_t chunk_size, void *data); - - int tick(); - - const RsFileHash& hash() const { return mHash; } - uint64_t size() const { return mSize; } - - //internal used functions - bool queryInactive(); - void adjustSpeed(); - - DwlSpeed downloadPriority() const { return mPriority ; } - void setDownloadPriority(DwlSpeed p) { mPriority =p ; } - - // read/reset the last time the transfer module was active (either wrote data, or was solicitaded by clients) - rstime_t lastActvTimeStamp() ; - void resetActvTimeStamp() ; - -private: - - bool locked_tickPeerTransfer(peerInfo &info); - bool locked_recvPeerData(peerInfo &info, uint64_t offset, - uint32_t chunk_size, void *data); - - bool checkFile() ; - bool checkCRC() ; - - /* These have independent Mutexes / are const locally (no Mutex protection)*/ - ftFileCreator *mFileCreator; - ftDataMultiplex *mMultiplexor; - ftController *mFtController; - - RsFileHash mHash; - uint64_t mSize; - - RsMutex tfMtx; /* below is mutex protected */ - - std::list mOnlinePeers; - std::map mFileSources; - - uint16_t mFlag; //2:file canceled, 1:transfer complete, 0: not complete, 3: checking hash, 4: checking chunks - double desiredRate; - double actualRate; - - rstime_t _last_activity_time_stamp ; - - ftFileStatus mFileStatus; //used for pause/resume file transfer - - HashThread *_hash_thread ; - DwlSpeed mPriority ; // transfer speed priority -}; - -#endif //FT_TRANSFER_MODULE_HEADER diff --git a/libretroshare/src/ft/ftturtlefiletransferitem.cc b/libretroshare/src/ft/ftturtlefiletransferitem.cc deleted file mode 100644 index 14150e42d..000000000 --- a/libretroshare/src/ft/ftturtlefiletransferitem.cc +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftturtlefiletransferitem.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -#include -#include -#include - -#include - -void RsTurtleFileMapRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,direction,"direction") ; -} - -void RsTurtleFileMapItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,direction,"direction") ; - RsTypeSerializer::serial_process (j,ctx,compressed_map._map,"map") ; -} -void RsTurtleChunkCrcRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,chunk_number,"chunk_number") ; -} -void RsTurtleChunkCrcItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,chunk_number,"chunk_number") ; - RsTypeSerializer::serial_process (j,ctx,check_sum,"check_sum") ; -} - -void RsTurtleFileRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,chunk_offset,"chunk_offset") ; - RsTypeSerializer::serial_process(j,ctx,chunk_size,"chunk_size") ; -} -void RsTurtleFileDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,chunk_offset,"chunk_offset") ; - - RsTypeSerializer::TlvMemBlock_proxy prox(chunk_data,chunk_size) ; - - RsTypeSerializer::serial_process(j,ctx,prox,"chunk_data") ; -} - diff --git a/libretroshare/src/ft/ftturtlefiletransferitem.h b/libretroshare/src/ft/ftturtlefiletransferitem.h deleted file mode 100644 index 6bbc24aef..000000000 --- a/libretroshare/src/ft/ftturtlefiletransferitem.h +++ /dev/null @@ -1,122 +0,0 @@ -/******************************************************************************* - * libretroshare/src/ft: ftturtlefiletransferitem.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -/***********************************************************************************/ -/* Turtle File Transfer item classes */ -/***********************************************************************************/ - -class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleFileRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST), chunk_offset(0), chunk_size(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);} - - virtual bool shouldStampTunnel() const { return false ; } - virtual Direction travelingDirection() const { return DIRECTION_SERVER ; } - - uint64_t chunk_offset ; - uint32_t chunk_size ; - - void clear() {} - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleFileDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA), chunk_offset(0), chunk_size(0), chunk_data(NULL) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;} - ~RsTurtleFileDataItem() { clear() ; } - - virtual bool shouldStampTunnel() const { return true ; } - virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; } - - void clear() - { - free(chunk_data); - chunk_data = NULL ; - chunk_size = 0 ; - chunk_offset = 0 ; - } - - uint64_t chunk_offset ; // offset in the file - uint32_t chunk_size ; // size of the file chunk - void *chunk_data ; // actual data. - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleFileMapRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;} - - virtual bool shouldStampTunnel() const { return false ; } - - void clear() {} - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleFileMapItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;} - - virtual bool shouldStampTunnel() const { return false ; } - - CompressedChunkMap compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have" - // by default, we suppose the peer has all the chunks. This info will thus be and-ed - // with the default file map for this source. - - void clear() { compressed_map._map.clear() ;} - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleChunkCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST), chunk_number(0) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST);} - - virtual bool shouldStampTunnel() const { return false ; } - virtual Direction travelingDirection() const { return DIRECTION_SERVER ; } - - uint32_t chunk_number ; // id of the chunk to CRC. - - void clear() {} - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleChunkCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC), chunk_number(0) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC);} - - virtual bool shouldStampTunnel() const { return true ; } - virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; } - - uint32_t chunk_number ; - Sha1CheckSum check_sum ; - - void clear() { check_sum.clear() ;} - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; diff --git a/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.cc b/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.cc deleted file mode 100644 index 6f66684c9..000000000 --- a/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.cc +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Gossip discovery service items * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "gossipdiscovery/gossipdiscoveryitems.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstypeserializer.h" -#include "serialiser/rsserializable.h" - -#include - -RsItem *RsDiscSerialiser::create_item( - uint16_t service, uint8_t item_subtype ) const -{ - if(service != RS_SERVICE_TYPE_DISC) return nullptr; - - switch(static_cast(item_subtype)) - { - case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem(); - case RsGossipDiscoveryItemType::PGP_CERT_BINARY: return new RsDiscPgpKeyItem(); - case RsGossipDiscoveryItemType::PGP_CERT: return new RsDiscPgpCertItem(); // deprecated, hanlde to suppress "unkown item" warning - case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem(); - case RsGossipDiscoveryItemType::IDENTITY_LIST: return new RsDiscIdentityListItem(); - default: - return nullptr; - } - - return nullptr; -} - -/*************************************************************************/ - -void RsDiscPgpListItem::clear() -{ - mode = RsGossipDiscoveryPgpListMode::NONE; - pgpIdSet.TlvClear(); -} - -void RsDiscPgpListItem::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(mode); - RS_SERIAL_PROCESS(pgpIdSet); -} - -void RsDiscPgpKeyItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,pgpKeyId,"pgpKeyId") ; - - RsTypeSerializer::TlvMemBlock_proxy prox(bin_data,bin_len) ; - RsTypeSerializer::serial_process(j,ctx,prox,"keyData") ; -} - -void RsDiscPgpKeyItem::clear() -{ - pgpKeyId.clear(); - free(bin_data); - bin_data = nullptr; - bin_len = 0; -} - -void RsDiscContactItem::clear() -{ - pgpId.clear(); - sslId.clear(); - - location.clear(); - version.clear(); - - netMode = 0; - vs_disc = 0; - vs_dht = 0; - lastContact = 0; - - isHidden = false; - hiddenAddr.clear(); - hiddenPort = 0; - - localAddrV4.TlvClear(); - extAddrV4.TlvClear(); - localAddrV6.TlvClear(); - extAddrV6.TlvClear(); - - - dyndns.clear(); - - localAddrList.TlvClear(); - extAddrList.TlvClear(); -} - -void RsDiscContactItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,pgpId,"pgpId"); - RsTypeSerializer::serial_process (j,ctx,sslId,"sslId"); - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_LOCATION,location,"location"); - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_VERSION,version,"version"); - RsTypeSerializer::serial_process(j,ctx,netMode,"netMode"); - RsTypeSerializer::serial_process(j,ctx,vs_disc,"vs_disc"); - RsTypeSerializer::serial_process(j,ctx,vs_dht,"vs_dht"); - RsTypeSerializer::serial_process(j,ctx,lastContact,"lastContact"); - - // This is a hack. Normally we should have to different item types, in order to avoid this nonesense. - - if(j == RsGenericSerializer::DESERIALIZE) - isHidden = ( GetTlvType( &(((uint8_t *) ctx.mData)[ctx.mOffset]) )==TLV_TYPE_STR_DOMADDR); - - if(isHidden) - { - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_DOMADDR,hiddenAddr,"hiddenAddr"); - RsTypeSerializer::serial_process(j,ctx,hiddenPort,"hiddenPort"); - } - else - { - RsTypeSerializer::serial_process(j,ctx,localAddrV4,"localAddrV4"); - RsTypeSerializer::serial_process(j,ctx, extAddrV4,"extAddrV4"); - RsTypeSerializer::serial_process(j,ctx,localAddrV6,"localAddrV6"); - RsTypeSerializer::serial_process(j,ctx, extAddrV6,"extAddrV6"); - RsTypeSerializer::serial_process(j,ctx,currentConnectAddress,"currentConnectAddress"); - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_DYNDNS,dyndns,"dyndns"); - RsTypeSerializer::serial_process (j,ctx,localAddrList,"localAddrList"); - RsTypeSerializer::serial_process (j,ctx, extAddrList,"extAddrList"); - } -} - -void RsDiscIdentityListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RS_SERIAL_PROCESS(ownIdentityList); -} - -RsDiscItem::RsDiscItem(RsGossipDiscoveryItemType subtype) - : RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC, static_cast(subtype) ) -{ -} - -RsDiscItem::~RsDiscItem() {} diff --git a/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.h b/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.h deleted file mode 100644 index b77074e37..000000000 --- a/libretroshare/src/gossipdiscovery/gossipdiscoveryitems.h +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * Gossip discovery service items * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "serialiser/rsserial.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvaddrs.h" -#include "serialiser/rstlvbinary.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rsserializer.h" - -enum class RsGossipDiscoveryItemType : uint8_t -{ - PGP_LIST = 0x1, - PGP_CERT = 0x2, // deprecated - CONTACT = 0x5, - IDENTITY_LIST = 0x6, - PGP_CERT_BINARY = 0x9, -}; - -class RsDiscItem: public RsItem -{ -protected: - RsDiscItem(RsGossipDiscoveryItemType subtype); - -public: - RsDiscItem() = delete; - virtual ~RsDiscItem(); -}; - -/** - * This enum is underlined by uint32_t for historical reasons. - * We are conscious that uint32_t is an overkill for so few possible values but, - * changing here it at this point would break binary serialized item - * retro-compatibility. - */ -enum class RsGossipDiscoveryPgpListMode : uint32_t -{ - NONE = 0x0, - FRIENDS = 0x1, - GETCERT = 0x2 -}; - -class RsDiscPgpListItem: public RsDiscItem -{ -public: - - RsDiscPgpListItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_LIST) - { setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_LIST); } - - void clear() override; - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - RsGossipDiscoveryPgpListMode mode; - RsTlvPgpIdSet pgpIdSet; -}; - -class RsDiscPgpKeyItem: public RsDiscItem -{ -public: - - RsDiscPgpKeyItem() : - RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT_BINARY), - bin_data(nullptr), bin_len(0) - { setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); } - - ~RsDiscPgpKeyItem() override { free(bin_data); } - void clear() override; - - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - /// duplicate information for practical reasons - RsPgpId pgpKeyId; - - unsigned char* bin_data; - uint32_t bin_len; -}; - -class RS_DEPRECATED_FOR(RsDiscPgpKeyItem) RsDiscPgpCertItem: public RsDiscItem -{ -public: - RsDiscPgpCertItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT) - { setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); } - - void clear() override - { - pgpId.clear(); - pgpCert.clear(); - } - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override - { - RsTypeSerializer::serial_process(j,ctx,pgpId,"pgpId") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ; - } - - RsPgpId pgpId; - std::string pgpCert; -}; - -class RsDiscContactItem: public RsDiscItem -{ -public: - - RsDiscContactItem() : RsDiscItem(RsGossipDiscoveryItemType::CONTACT) - { setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); } - - void clear() override; - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - RsPgpId pgpId; - RsPeerId sslId; - - // COMMON - std::string location; - std::string version; - - uint32_t netMode; /* Mandatory */ - uint16_t vs_disc; /* Mandatory */ - uint16_t vs_dht; /* Mandatory */ - uint32_t lastContact; - - bool isHidden; /* not serialised */ - - // HIDDEN. - std::string hiddenAddr; - uint16_t hiddenPort; - - // STANDARD. - - RsTlvIpAddress currentConnectAddress ; // used to check! - - RsTlvIpAddress localAddrV4; /* Mandatory */ - RsTlvIpAddress extAddrV4; /* Mandatory */ - - RsTlvIpAddress localAddrV6; /* Mandatory */ - RsTlvIpAddress extAddrV6; /* Mandatory */ - - std::string dyndns; - - RsTlvIpAddrSet localAddrList; - RsTlvIpAddrSet extAddrList; -}; - -class RsDiscIdentityListItem: public RsDiscItem -{ -public: - - RsDiscIdentityListItem() : - RsDiscItem(RsGossipDiscoveryItemType::IDENTITY_LIST) - { setPriorityLevel(QOS_PRIORITY_RS_DISC_CONTACT); } - - void clear() override { ownIdentityList.clear(); } - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override; - - std::list ownIdentityList; -}; - -class RsDiscSerialiser: public RsServiceSerializer -{ -public: - RsDiscSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_DISC) {} - virtual ~RsDiscSerialiser() {} - - RsItem* create_item(uint16_t service, uint8_t item_subtype) const; -}; diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc deleted file mode 100644 index 732967f44..000000000 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ /dev/null @@ -1,1366 +0,0 @@ -/******************************************************************************* - * RetroShare gossip discovery service implementation * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2013 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "gossipdiscovery/p3gossipdiscovery.h" -#include "pqi/p3peermgr.h" -#include "retroshare/rsversion.h" -#include "retroshare/rsiface.h" -#include "rsserver/p3face.h" -#include "util/rsdebug.h" -#include "retroshare/rspeers.h" - -/**** - * #define P3DISC_DEBUG 1 - ****/ - -/*extern*/ std::shared_ptr rsGossipDiscovery(nullptr); - -static bool populateContactInfo( const peerState &detail, - RsDiscContactItem *pkt, - bool include_ip_information ) -{ - pkt->clear(); - - pkt->pgpId = detail.gpg_id; - pkt->sslId = detail.id; - pkt->location = detail.location; - pkt->version = ""; - pkt->netMode = detail.netMode; - pkt->vs_disc = detail.vs_disc; - pkt->vs_dht = detail.vs_dht; - - pkt->lastContact = time(nullptr); - - if (detail.hiddenNode) - { - pkt->isHidden = true; - pkt->hiddenAddr = detail.hiddenDomain; - pkt->hiddenPort = detail.hiddenPort; - } - else - { - pkt->isHidden = false; - - if(include_ip_information) - { - pkt->localAddrV4.addr = detail.localaddr; - pkt->extAddrV4.addr = detail.serveraddr; - sockaddr_storage_clear(pkt->localAddrV6.addr); - sockaddr_storage_clear(pkt->extAddrV6.addr); - - pkt->dyndns = detail.dyndns; - detail.ipAddrs.mLocal.loadTlv(pkt->localAddrList); - detail.ipAddrs.mExt.loadTlv(pkt->extAddrList); - } - else - { - sockaddr_storage_clear(pkt->localAddrV6.addr); - sockaddr_storage_clear(pkt->extAddrV6.addr); - sockaddr_storage_clear(pkt->localAddrV4.addr); - sockaddr_storage_clear(pkt->extAddrV4.addr); - } - } - - return true; -} - -void DiscPgpInfo::mergeFriendList(const std::set &friends) -{ - std::set::const_iterator it; - for(it = friends.begin(); it != friends.end(); ++it) - { - mFriendSet.insert(*it); - } -} - - -p3discovery2::p3discovery2( - p3PeerMgr* peerMgr, p3LinkMgr* linkMgr, p3NetMgr* netMgr, - p3ServiceControl* sc, RsGixs* gixs ) : - p3Service(), mRsEventsHandle(0), mPeerMgr(peerMgr), mLinkMgr(linkMgr), - mNetMgr(netMgr), mServiceCtrl(sc), mGixs(gixs), mDiscMtx("p3discovery2"), - mLastPgpUpdate(0) -{ - Dbg3() << __PRETTY_FUNCTION__ << std::endl; - - RS_STACK_MUTEX(mDiscMtx); - addSerialType(new RsDiscSerialiser()); - - // Add self into PGP FriendList. - mFriendList[AuthGPG::getAuthGPG()->getGPGOwnId()] = DiscPgpInfo(); -} - - -const std::string DISCOVERY_APP_NAME = "disc"; -const uint16_t DISCOVERY_APP_MAJOR_VERSION = 1; -const uint16_t DISCOVERY_APP_MINOR_VERSION = 0; -const uint16_t DISCOVERY_MIN_MAJOR_VERSION = 1; -const uint16_t DISCOVERY_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3discovery2::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_DISC, - DISCOVERY_APP_NAME, - DISCOVERY_APP_MAJOR_VERSION, - DISCOVERY_APP_MINOR_VERSION, - DISCOVERY_MIN_MAJOR_VERSION, - DISCOVERY_MIN_MINOR_VERSION); -} - -p3discovery2::~p3discovery2() -{ rsEvents->unregisterEventsHandler(mRsEventsHandle); } - -void p3discovery2::addFriend(const RsPeerId &sslId) -{ - RsPgpId pgpId = getPGPId(sslId); - - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mFriendList.find(pgpId); - if (it == mFriendList.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() adding pgp entry: " << pgpId; - std::cerr << std::endl; -#endif - - mFriendList[pgpId] = DiscPgpInfo(); - - it = mFriendList.find(pgpId); - } - - - /* now add RsPeerId */ - - std::map::iterator sit; - sit = it->second.mSslIds.find(sslId); - if (sit == it->second.mSslIds.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() adding ssl entry: " << sslId; - std::cerr << std::endl; -#endif - - it->second.mSslIds[sslId] = DiscSslInfo(); - sit = it->second.mSslIds.find(sslId); - } - - /* update Settings from peerMgr */ - peerState detail; - if (mPeerMgr->getFriendNetStatus(sit->first, detail)) - { - sit->second.mDiscStatus = detail.vs_disc; - } - else - { - sit->second.mDiscStatus = RS_VS_DISC_OFF; - } -} - -void p3discovery2::removeFriend(const RsPeerId &sslId) -{ - RsPgpId pgpId = getPGPId(sslId); - - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mFriendList.find(pgpId); - if (it == mFriendList.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::removeFriend() missing pgp entry: " << pgpId; - std::cerr << std::endl; -#endif - return; - } - - std::map::iterator sit; - sit = it->second.mSslIds.find(sslId); - if (sit == it->second.mSslIds.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() missing ssl entry: " << sslId; - std::cerr << std::endl; -#endif - return; - } - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() removing ssl entry: " << sslId; - std::cerr << std::endl; -#endif - it->second.mSslIds.erase(sit); - - if (it->second.mSslIds.empty()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() pgpId now has no sslIds"; - std::cerr << std::endl; -#endif - /* pgp peer without any ssl entries -> check if they are still a real friend */ - if (!(AuthGPG::getAuthGPG()->isGPGAccepted(pgpId))) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::addFriend() pgpId is no longer a friend, removing"; - std::cerr << std::endl; -#endif - mFriendList.erase(it); - } - } -} - -RsPgpId p3discovery2::getPGPId(const RsPeerId &id) -{ - RsPgpId pgpId; - mPeerMgr->getGpgId(id, pgpId); - return pgpId; -} - -int p3discovery2::tick() -{ - return handleIncoming(); -} - -int p3discovery2::handleIncoming() -{ - RsItem* item = nullptr; - - int nhandled = 0; - // While messages read - while(nullptr != (item = recvItem())) - { - RsDiscPgpListItem* pgplist = nullptr; - RsDiscPgpKeyItem* pgpkey = nullptr; - RsDiscPgpCertItem* pgpcert = nullptr; // deprecated, hanlde for retro compability - RsDiscContactItem* contact = nullptr; - RsDiscIdentityListItem* gxsidlst = nullptr; - - ++nhandled; - - Dbg4() << __PRETTY_FUNCTION__ << " Received item: " << *item << std::endl; - - if((contact = dynamic_cast(item)) != nullptr) - { - if (item->PeerId() == contact->sslId) - recvOwnContactInfo(item->PeerId(), contact); - else - processContactInfo(item->PeerId(), contact); - } - else if( (gxsidlst = dynamic_cast(item)) != nullptr ) - recvIdentityList(item->PeerId(),gxsidlst->ownIdentityList); - else if((pgpkey = dynamic_cast(item)) != nullptr) - recvPGPCertificate(item->PeerId(), pgpkey); - else if((pgpcert = dynamic_cast(item)) != nullptr) - RsWarn() << "Received a deprecated RsDiscPgpCertItem. Will not be handled." << std::endl; // nothing to do. - else if((pgplist = dynamic_cast(item)) != nullptr) - { - if (pgplist->mode == RsGossipDiscoveryPgpListMode::FRIENDS) - processPGPList(pgplist->PeerId(), pgplist); - else if (pgplist->mode == RsGossipDiscoveryPgpListMode::GETCERT) - recvPGPCertificateRequest(pgplist->PeerId(), pgplist); - } - else - { - RsWarn() << __PRETTY_FUNCTION__ << " Received unknown item type " << (int)item->PacketSubType() << "! " << std::endl ; - RsWarn() << item << std::endl; - } - - delete item; - } - - return nhandled; -} - -void p3discovery2::sendOwnContactInfo(const RsPeerId &sslid) -{ - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendOwnContactInfo()"; - std::cerr << std::endl; -#endif - peerState detail; - if (mPeerMgr->getOwnNetStatus(detail)) - { - RsDiscContactItem *pkt = new RsDiscContactItem(); - - /* Cyril: we dont send our own IP to an hidden node. It will not use it - * anyway. Furthermore, a Tor node is not supposed to have any mean to send the IPs of his friend nodes - * to other nodes. This would be a very serious security risk. */ - - populateContactInfo(detail, pkt, !rsPeers->isHiddenNode(sslid)); - - /* G10h4ck: sending IP information also to hidden nodes has proven very - * helpful in the usecase of non hidden nodes, that share a common - * hidden trusted node, to discover each other IP. - * Advanced/corner case non hidden node users that want to hide their - * IP to a specific hidden ~trusted~ node can do it through the - * permission matrix. Disabling this instead will make life more - * difficult for average user, that moreover whould have no way to - * revert an hardcoded policy. */ - - pkt->version = RS_HUMAN_READABLE_VERSION; - pkt->PeerId(sslid); - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendOwnContactInfo() sending:" << std::endl; - pkt -> print(std::cerr); - std::cerr << std::endl; -#endif - sendItem(pkt); - - RsDiscIdentityListItem *pkt2 = new RsDiscIdentityListItem(); - - rsIdentity->getOwnIds(pkt2->ownIdentityList,true); - pkt2->PeerId(sslid) ; - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendOwnContactInfo() sending own signed identity list:" << std::endl; - for(auto it(pkt2->ownIdentityList.begin());it!=pkt2->ownIdentityList.end();++it) - std::cerr << " identity: " << (*it).toStdString() << std::endl; -#endif - sendItem(pkt2); - } -} - -void p3discovery2::recvOwnContactInfo(const RsPeerId &fromId, const RsDiscContactItem *item) -{ -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::recvOwnContactInfo()"; - std::cerr << std::endl; - - std::cerr << "Info sent by the peer itself -> updating self info:" << std::endl; - std::cerr << " -> vs_disc : " << item->vs_disc << std::endl; - std::cerr << " -> vs_dht : " << item->vs_dht << std::endl; - std::cerr << " -> network mode : " << item->netMode << std::endl; - std::cerr << " -> location : " << item->location << std::endl; - std::cerr << std::endl; -#endif - // Check that the "own" ID sent corresponds to the one we think it should be. - // Some of these checks may look superfluous but it's better to risk to check twice than not check at all. - - // was obtained using a short invite. , and that the friend is marked as "ignore PGP validation" because it - RsPeerDetails det ; - if(!rsPeers->getPeerDetails(fromId,det)) - { - RsErr() << "(EE) Cannot obtain details from " << fromId << " who is supposed to be a friend! Dropping the info." << std::endl; - return; - } - if(det.gpg_id != item->pgpId) - { - RsErr() << "(EE) peer " << fromId << " sent own details with PGP key ID " << item->pgpId << " which does not match the known key id " << det.gpg_id << ". Dropping the info." << std::endl; - return; - } - - // Peer Own Info replaces the existing info, because the - // peer is the primary source of his own IPs, except for hidden nodes - // that normally send nothing. We still ignore it as a double security. - - mPeerMgr->setNetworkMode(fromId, item->netMode); - mPeerMgr->setLocation(fromId, item->location); - mPeerMgr->setVisState(fromId, item->vs_disc, item->vs_dht); - - if(!mPeerMgr->isHiddenNode(fromId)) - { - if(!det.localAddr.empty()) - { - if(sockaddr_storage_isValidNet(item->localAddrV4.addr)) - mPeerMgr->setLocalAddress(fromId,item->localAddrV4.addr); - else if(sockaddr_storage_isValidNet(item->localAddrV6.addr)) - mPeerMgr->setLocalAddress(fromId,item->localAddrV6.addr); - } - - if(!det.extAddr.empty()) - { - if(sockaddr_storage_isValidNet(item->extAddrV4.addr)) - mPeerMgr->setExtAddress(fromId,item->extAddrV4.addr); - else if(sockaddr_storage_isValidNet(item->extAddrV6.addr)) - mPeerMgr->setExtAddress(fromId,item->extAddrV6.addr); - } - } - - setPeerVersion(fromId, item->version); - - // Hidden nodes do not need IP information. So that information is dropped. - // However, that doesn't mean hidden nodes do not know that information. Normally - // normal nodes should not send it, but old nodes still do. - - if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId())) - updatePeerAddresses(item); - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mGossipDiscoveryEventType = RsGossipDiscoveryEventType::FRIEND_PEER_INFO_RECEIVED; - ev->mFromId = fromId; - ev->mAboutId = item->sslId; - rsEvents->postEvent(ev); - } - - // if the peer is not validated, we stop the exchange here - - if(det.skip_pgp_signature_validation) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::recvOwnContactInfo() missing PGP key " << item->pgpId << " from short invite friend " << fromId << ". Requesting it." << std::endl; -#endif - requestPGPCertificate(det.gpg_id, fromId); - return; - } - - // This information will be sent out to online peers, at the receipt of their PGPList. - // It is important that PGPList is received after the OwnContactItem. - // This should happen, but is not enforced by the protocol. - - // Start peer list exchange, if discovery is enabled - - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - if(ps.vs_disc != RS_VS_DISC_OFF) - sendPGPList(fromId); - - // Update mDiscStatus. - RS_STACK_MUTEX(mDiscMtx); - - RsPgpId pgpId = getPGPId(fromId); - std::map::iterator it = mFriendList.find(pgpId); - if (it != mFriendList.end()) - { - std::map::iterator sit = it->second.mSslIds.find(fromId); - if (sit != it->second.mSslIds.end()) - { - sit->second.mDiscStatus = item->vs_disc; -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::recvOwnContactInfo()"; - std::cerr << "updating mDiscStatus to: " << sit->second.mDiscStatus; - std::cerr << std::endl; -#endif - } - else - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::recvOwnContactInfo()"; - std::cerr << " ERROR missing SSL Entry: " << fromId; - std::cerr << std::endl; -#endif - } - } -} - -void p3discovery2::recvIdentityList(const RsPeerId& pid,const std::list& ids) -{ - std::list peers; - peers.push_back(pid); - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::recvIdentityList(): from peer " << pid << ": " << ids.size() << " identities" << std::endl; -#endif - - RsIdentityUsage use_info(RsServiceType::GOSSIP_DISCOVERY,RsIdentityUsage::IDENTITY_NEW_FROM_DISCOVERY); - - for(auto it(ids.begin());it!=ids.end();++it) - { -#ifdef P3DISC_DEBUG - std::cerr << " identity: " << (*it).toStdString() << std::endl; -#endif - mGixs->requestKey(*it,peers,use_info) ; - } -} - -void p3discovery2::updatePeerAddresses(const RsDiscContactItem *item) -{ - if (item->isHidden) - mPeerMgr->setHiddenDomainPort(item->sslId, item->hiddenAddr, - item->hiddenPort); - else - { - mPeerMgr->setDynDNS(item->sslId, item->dyndns); - updatePeerAddressList(item); - } -} - -void p3discovery2::updatePeerAddressList(const RsDiscContactItem *item) -{ - if (item->isHidden) - { - } - else if(!mPeerMgr->isHiddenNode(rsPeers->getOwnId())) - { - /* Cyril: we don't store IP addresses if we're a hidden node. - * Normally they should not be sent to us, except for old peers. */ - /* G10h4ck: sending IP information also to hidden nodes has proven very - * helpful in the usecase of non hidden nodes, that share a common - * hidden trusted node, to discover each other IP. - * Advanced/corner case non hidden node users that want to hide their - * IP to a specific hidden ~trusted~ node can do it through the - * permission matrix. Disabling this instead will make life more - * difficult for average user, that moreover whould have no way to - * revert an hardcoded policy. */ - pqiIpAddrSet addrsFromPeer; - addrsFromPeer.mLocal.extractFromTlv(item->localAddrList); - addrsFromPeer.mExt.extractFromTlv(item->extAddrList); - -#ifdef P3DISC_DEBUG - std::cerr << "Setting address list to peer " << item->sslId - << ", to be:" << std::endl ; - - std::string addrstr; - addrsFromPeer.printAddrs(addrstr); - std::cerr << addrstr; - std::cerr << std::endl; -#endif - mPeerMgr->updateAddressList(item->sslId, addrsFromPeer); - } -} - -// Starts the Discovery process. -// should only be called it DISC2_STATUS_NOT_HIDDEN(OwnInfo.status). -void p3discovery2::sendPGPList(const RsPeerId &toId) -{ - updatePgpFriendList(); - - RS_STACK_MUTEX(mDiscMtx); - - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendPGPList() to " << toId << std::endl; -#endif - - RsDiscPgpListItem *pkt = new RsDiscPgpListItem(); - - pkt->mode = RsGossipDiscoveryPgpListMode::FRIENDS; - - for(auto it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - // Check every friend, and only send his PGP key if the friend tells that he wants discovery. Because this action over profiles depends on a node information, - // we check each node of a given progile and only send the profile key if at least one node allows it. - - for(auto it2(it->second.mSslIds.begin());it2!=it->second.mSslIds.end();++it2) - if(it2->second.mDiscStatus != RS_VS_DISC_OFF) - { - pkt->pgpIdSet.ids.insert(it->first); - break; - } - } - - pkt->PeerId(toId); - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendPGPList() sending:" << std::endl; - pkt->print(std::cerr); - std::cerr << std::endl; -#endif - - sendItem(pkt); -} - -void p3discovery2::updatePgpFriendList() -{ -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePgpFriendList()"; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(mDiscMtx); - -#define PGP_MAX_UPDATE_PERIOD 300 - - if (time(NULL) < mLastPgpUpdate + PGP_MAX_UPDATE_PERIOD ) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePgpFriendList() Already uptodate"; - std::cerr << std::endl; -#endif - return; - } - - mLastPgpUpdate = time(NULL); - - std::list pgpList; - std::set pgpSet; - - std::set::iterator sit; - std::list::iterator lit; - std::map::iterator it; - - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); - AuthGPG::getAuthGPG()->getGPGAcceptedList(pgpList); - pgpList.push_back(ownPgpId); - - // convert to set for ordering. - for(lit = pgpList.begin(); lit != pgpList.end(); ++lit) - { - pgpSet.insert(*lit); - } - - std::list pgpToAdd; - std::list pgpToRemove; - - - sit = pgpSet.begin(); - it = mFriendList.begin(); - while (sit != pgpSet.end() && it != mFriendList.end()) - { - if (*sit < it->first) - { - /* to add */ - pgpToAdd.push_back(*sit); - ++sit; - } - else if (it->first < *sit) - { - /* to remove */ - pgpToRemove.push_back(it->first); - ++it; - } - else - { - /* same - okay */ - ++sit; - ++it; - } - } - - /* more to add? */ - for(; sit != pgpSet.end(); ++sit) - { - pgpToAdd.push_back(*sit); - } - - for(; it != mFriendList.end(); ++it) - { - /* more to remove */ - pgpToRemove.push_back(it->first); - } - - for(lit = pgpToRemove.begin(); lit != pgpToRemove.end(); ++lit) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePgpFriendList() Removing pgpId: " << *lit; - std::cerr << std::endl; -#endif - - it = mFriendList.find(*lit); - mFriendList.erase(it); - } - - for(lit = pgpToAdd.begin(); lit != pgpToAdd.end(); ++lit) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePgpFriendList() Adding pgpId: " << *lit; - std::cerr << std::endl; -#endif - - mFriendList[*lit] = DiscPgpInfo(); - } - - /* finally install the pgpList on our own entry */ - DiscPgpInfo &ownInfo = mFriendList[ownPgpId]; - ownInfo.mergeFriendList(pgpSet); - -} - -void p3discovery2::processPGPList(const RsPeerId &fromId, const RsDiscPgpListItem *item) -{ - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::processPGPList() from " << fromId; - std::cerr << std::endl; -#endif - - RsPgpId fromPgpId = getPGPId(fromId); - auto it = mFriendList.find(fromPgpId); - if (it == mFriendList.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::processPGPList() is not friend: " << fromId; - std::cerr << std::endl; -#endif - - // cleanup. - return; - } - - bool requestUnknownPgpCerts = true; - peerState pstate; - mPeerMgr->getOwnNetStatus(pstate); - if (pstate.vs_disc != RS_VS_DISC_FULL) - requestUnknownPgpCerts = false; - - uint32_t linkType = mLinkMgr->getLinkType(fromId); - if ((linkType & RS_NET_CONN_SPEED_TRICKLE) || - (linkType & RS_NET_CONN_SPEED_LOW)) - { - std::cerr << "p3discovery2::processPGPList() Not requesting Certificates from: " << fromId; - std::cerr << " (low bandwidth)" << std::endl; - requestUnknownPgpCerts = false; - } - - if (requestUnknownPgpCerts) - { - std::set::const_iterator fit; - for(fit = item->pgpIdSet.ids.begin(); fit != item->pgpIdSet.ids.end(); ++fit) - { - if (!AuthGPG::getAuthGPG()->isGPGId(*fit)) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit; - std::cerr << " from SslId: " << fromId; - std::cerr << std::endl; -#endif - requestPGPCertificate(*fit, fromId); - } - } - } - - it->second.mergeFriendList(item->pgpIdSet.ids); - updatePeers_locked(fromId); -} - - -/* - * -> Update Other Peers about B. - * -> Update B about Other Peers. - */ -void p3discovery2::updatePeers_locked(const RsPeerId &aboutId) -{ - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeers_locked() about " << aboutId; - std::cerr << std::endl; -#endif - - RsPgpId aboutPgpId = getPGPId(aboutId); - - auto ait = mFriendList.find(aboutPgpId); - if (ait == mFriendList.end()) - { - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeers_locked() PgpId is not a friend: " << aboutPgpId; - std::cerr << std::endl; -#endif - return; - } - - std::set mutualFriends; - std::set onlineFriends; - - const std::set &friendSet = ait->second.mFriendSet; - - for(auto fit = friendSet.begin(); fit != friendSet.end(); ++fit) - { - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() checking their friend: " << *fit; - std::cerr << std::endl; -#endif - - auto ffit = mFriendList.find(*fit); - - if (ffit == mFriendList.end()) - { - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() Ignoring not our friend"; - std::cerr << std::endl; -#endif - // Not our friend, or we have no Locations (SSL) for this RsPgpId (same difference) - continue; - } - - if (ffit->second.mFriendSet.find(aboutPgpId) != ffit->second.mFriendSet.end()) - { - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() Adding as Mutual Friend"; - std::cerr << std::endl; -#endif - mutualFriends.insert(*fit); - - for(auto mit = ffit->second.mSslIds.begin(); mit != ffit->second.mSslIds.end(); ++mit) - { - RsPeerId sslid = mit->first; - if (mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, sslid)) - { - // TODO IGNORE if sslid == aboutId, or sslid == ownId. -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() Adding Online RsPeerId: " << sslid; - std::cerr << std::endl; -#endif - onlineFriends.insert(sslid); - } - } - } - } - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() Updating " << aboutId << " about Mutual Friends"; - std::cerr << std::endl; -#endif - // update aboutId about Other Peers. - for(auto fit = mutualFriends.begin(); fit != mutualFriends.end(); ++fit) - sendContactInfo_locked(*fit, aboutId); - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::updatePeer_locked() Updating Online Peers about " << aboutId; - std::cerr << std::endl; -#endif - // update Other Peers about aboutPgpId. - for(auto sit = onlineFriends.begin(); sit != onlineFriends.end(); ++sit) - { - // This could be more efficient, and only be specific about aboutId. - // but we'll leave it like this for the moment. - sendContactInfo_locked(aboutPgpId, *sit); - } -} - -void p3discovery2::sendContactInfo_locked(const RsPgpId &aboutId, const RsPeerId &toId) -{ -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() aboutPGPId: " << aboutId << " toId: " << toId; - std::cerr << std::endl; -#endif - std::map::const_iterator it; - it = mFriendList.find(aboutId); - if (it == mFriendList.end()) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() ERROR aboutId is not a friend"; - std::cerr << std::endl; -#endif - return; - } - - std::map::const_iterator sit; - for(sit = it->second.mSslIds.begin(); sit != it->second.mSslIds.end(); ++sit) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() related sslId: " << sit->first; - std::cerr << std::endl; -#endif - - if (sit->first == rsPeers->getOwnId()) - { - // sending info of toId to himself will be used by toId to check that the IP it is connected as is the same - // as its external IP. -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::processContactInfo() not sending info on self"; - std::cerr << std::endl; -#endif - continue; - } - - if (sit->second.mDiscStatus != RS_VS_DISC_OFF) - { - peerState detail; - peerConnectState detail2; - - if (mPeerMgr->getFriendNetStatus(sit->first, detail)) - { - RsDiscContactItem *pkt = new RsDiscContactItem(); - populateContactInfo(detail, pkt,!mPeerMgr->isHiddenNode(toId));// never send IPs to an hidden node. The node will not use them anyway. - pkt->PeerId(toId); - - // send to each peer its own connection address. - - if(sit->first == toId && mLinkMgr->getFriendNetStatus(sit->first,detail2)) - pkt->currentConnectAddress.addr = detail2.connectaddr; - else - sockaddr_storage_clear(pkt->currentConnectAddress.addr) ; - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() Sending"; - std::cerr << std::endl; - pkt->print(std::cerr); - std::cerr << std::endl; -#endif - sendItem(pkt); - } - else - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() No Net Status"; - std::cerr << std::endl; -#endif - } - } - else - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::sendContactInfo_locked() RsPeerId Hidden"; - std::cerr << std::endl; -#endif - } - } -} - -void p3discovery2::processContactInfo(const RsPeerId &fromId, const RsDiscContactItem *item) -{ - (void) fromId; // remove unused parameter warnings, debug only - - RS_STACK_MUTEX(mDiscMtx); - - // This case is the node fromId sending information about ourselves to us. There's one good use of this: - // read the IP information the friend knows about us, and use it to extimate our external address. - - if (item->sslId == rsPeers->getOwnId()) - { - if(sockaddr_storage_isExternalNet(item->currentConnectAddress.addr)) - mPeerMgr->addCandidateForOwnExternalAddress(item->PeerId(), item->currentConnectAddress.addr); - - return; - } - - auto it = mFriendList.find(item->pgpId); // is this the PGP id one of our friends? - - if (it == mFriendList.end()) // no it's not. - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::processContactInfo(" << fromId << ") RsPgpId: "; - std::cerr << item->pgpId << " Not Friend."; - std::cerr << std::endl; - std::cerr << "p3discovery2::processContactInfo(" << fromId << ") THIS SHOULD NEVER HAPPEN!"; - std::cerr << std::endl; -#endif - - /* THESE ARE OUR FRIEND OF FRIENDS ... pass this information along to - * NetMgr & DHT... - * as we can track FOF and use them as potential Proxies / Relays - */ - - if (!item->isHidden) - { - /* add into NetMgr and non-search, so we can detect connect attempts */ - mNetMgr->netAssistFriend(item->sslId,false); - - /* inform NetMgr that we know this peer */ - mNetMgr->netAssistKnownPeer(item->sslId, item->extAddrV4.addr, NETASSIST_KNOWN_PEER_FOF | NETASSIST_KNOWN_PEER_OFFLINE); - } - return; - } - - // The peer the discovery info is about is a friend. We gather the nodes for that profile into the local structure and notify p3peerMgr. - - if(!rsPeers->isGPGAccepted(item->pgpId)) // this is an additional check, because the friendship previously depends on the local cache. We need - return ; // fresh information here. - - bool should_notify_discovery = false; - - DiscSslInfo& sslInfo(it->second.mSslIds[item->sslId]); // This line inserts the entry while not removing already existing data - // do not remove it! - if (!mPeerMgr->isFriend(item->sslId)) - { - should_notify_discovery = true; - - // Add with no disc by default. If friend already exists, it will do nothing - // NO DISC is important - otherwise, we'll just enter a nasty loop, - // where every addition triggers requests, then they are cleaned up, and readded... - - // This way we get their addresses, but don't advertise them until we get a - // connection. -#ifdef P3DISC_DEBUG - std::cerr << "--> Adding to friends list " << item->sslId << " - " << item->pgpId << std::endl; -#endif - // We pass RS_NODE_PERM_ALL because the PGP id is already a friend, so we should keep the existing - // permission flags. Therefore the mask needs to be 0xffff. - - // set last seen to RS_PEER_OFFLINE_NO_DISC minus 1 so that it won't be shared with other friends - // until a first connection is established - - // This code is a bit dangerous: we add a friend without the insurance that the PGP key that will validate this friend actually has - // the supplied PGP id. Of course, because it comes from a friend, we should trust that friend. Anyway, it is important that - // when connecting the handshake is always doen w.r.t. the known PGP key, and not the one that is indicated in the certificate issuer field. - - mPeerMgr->addFriend( item->sslId, item->pgpId, item->netMode, - RS_VS_DISC_OFF, RS_VS_DHT_FULL, - time(NULL) - RS_PEER_OFFLINE_NO_DISC - 1, - RS_NODE_PERM_ALL ); - - updatePeerAddresses(item); - } - updatePeerAddressList(item); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_NEIGHBOURS, NOTIFY_TYPE_MOD); - - if(should_notify_discovery) - { - RsServer::notify()->notifyDiscInfoChanged(); - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mGossipDiscoveryEventType = RsGossipDiscoveryEventType::FRIEND_PEER_INFO_RECEIVED; - ev->mFromId = fromId; - ev->mAboutId = item->sslId; - rsEvents->postEvent(ev); - } - } -} - -/* we explictly request certificates, instead of getting them all the time - */ -void p3discovery2::requestPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId) -{ -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::requestPGPCertificate() aboutId: " << aboutId << " to: " << toId; - std::cerr << std::endl; -#endif - - RsDiscPgpListItem *pkt = new RsDiscPgpListItem(); - - pkt->mode = RsGossipDiscoveryPgpListMode::GETCERT; - pkt->pgpIdSet.ids.insert(aboutId); - pkt->PeerId(toId); - -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::requestPGPCertificate() sending:" << std::endl; - pkt->print(std::cerr); - std::cerr << std::endl; -#endif - - sendItem(pkt); -} - -void p3discovery2::recvPGPCertificateRequest( const RsPeerId& fromId, const RsDiscPgpListItem* item ) -{ -#ifdef P3DISC_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " from " << fromId << std::endl; -#endif - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - if(ps.vs_disc == RS_VS_DISC_OFF) - { - std::cerr << "(WW) refusing PGP certificate request from " << fromId << " because discovery is OFF" << std::endl; - return; - } - - RsPgpId ownPgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); - for(const RsPgpId& pgpId : item->pgpIdSet.ids) - if (pgpId == ownPgpId) - sendPGPCertificate(pgpId, fromId); - else if(ps.vs_disc != RS_VS_DISC_OFF && AuthGPG::getAuthGPG()->isGPGAccepted(pgpId)) - sendPGPCertificate(pgpId, fromId); - else - std::cerr << "(WW) not sending certificate " << pgpId << " asked by friend " << fromId << " because this either this cert is not a friend, or discovery is off" << std::endl; -} - - -void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId) -{ - RsDiscPgpKeyItem *pgp_key_item = new RsDiscPgpKeyItem; - - pgp_key_item->PeerId(toId); - pgp_key_item->pgpKeyId = aboutId; - unsigned char *bin_data; - size_t bin_len; - - if(!AuthGPG::getAuthGPG()->exportPublicKey(aboutId,bin_data,bin_len,false,true)) - { - std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl; - return ; - } - - pgp_key_item->bin_data = bin_data; - pgp_key_item->bin_len = bin_len; - - sendItem(pgp_key_item); -} - -void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* item ) -{ - // 1 - check that the cert structure is valid. - - RsPgpId cert_pgp_id; - std::string cert_name; - std::list cert_signers; - - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( (unsigned char*)item->bin_data,item->bin_len, cert_pgp_id, cert_name, cert_signers )) - { - std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl; - return; - } - - if(cert_pgp_id != item->pgpKeyId) - { - std::cerr << "(EE) received a PGP key from " << fromId << " which ID (" << cert_pgp_id << ") is different from the one anounced in the packet (" << item->pgpKeyId << ")!" << std::endl; - return; - } - - // 2 - check if the peer who is sending us a cert is already validated - - RsPeerDetails det; - if(!rsPeers->getPeerDetails(fromId,det)) - { - std::cerr << "(EE) cannot get peer details from friend " << fromId << ": this is very wrong!"<< std::endl; - return; - } - - // We treat own pgp keys right away when they are sent by a friend for which we dont have it. This way we can keep the skip_pgg_signature_validation consistent - - if(det.skip_pgp_signature_validation) - { -#ifdef P3DISC_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Received own full certificate from short-invite friend " << fromId << std::endl; -#endif - // do some extra checks. Dont remove them. They cost nothing as compared to what they could avoid. - - if(item->pgpKeyId != det.gpg_id) - { - std::cerr << "(EE) received a PGP key with ID " << item->pgpKeyId << " from non validated peer " << fromId << ", which should only be allowed to send his own key " << det.gpg_id << std::endl; - return; - } - } - RsPgpId tmp_pgp_id; - std::string error_string; - -#ifdef P3DISC_DEBUG - std::cerr << __PRETTY_FUNCTION__ << "Received PGP key " << cert_pgp_id << " from from friend " << fromId << ". Adding to keyring." << std::endl; -#endif - // now that will add the key *and* set the skip_signature_validation flag at once - rsPeers->loadPgpKeyFromBinaryData((unsigned char*)item->bin_data,item->bin_len, tmp_pgp_id,error_string); // no error should occur at this point because we called loadDetailsFromStringCert() already - - // Make sure we allow connections after the key is added. This is not the case otherwise. We only do that if the peer is non validated peer, since - // otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key. - - if(det.skip_pgp_signature_validation) - AuthGPG::getAuthGPG()->AllowConnection(det.gpg_id,true); -} - - /************* from pqiServiceMonitor *******************/ -void p3discovery2::statusChange(const std::list &plist) -{ -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::statusChange()" << std::endl; -#endif - - std::list::const_iterator pit; - for(pit = plist.begin(); pit != plist.end(); ++pit) - { - if (pit->actions & RS_SERVICE_PEER_CONNECTED) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::statusChange() Starting Disc with: " << pit->id << std::endl; -#endif - sendOwnContactInfo(pit->id); - } - else if (pit->actions & RS_SERVICE_PEER_DISCONNECTED) - { - std::cerr << "p3discovery2::statusChange() Disconnected: " << pit->id << std::endl; - } - - if (pit->actions & RS_SERVICE_PEER_NEW) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::statusChange() Adding Friend: " << pit->id << std::endl; -#endif - addFriend(pit->id); - } - else if (pit->actions & RS_SERVICE_PEER_REMOVED) - { -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::statusChange() Removing Friend: " << pit->id << std::endl; -#endif - removeFriend(pit->id); - } - } -#ifdef P3DISC_DEBUG - std::cerr << "p3discovery2::statusChange() finished." << std::endl; -#endif - return; -} - - - /*************************************************************************************/ - /* Extracting Network Graph Details */ - /*************************************************************************************/ -bool p3discovery2::getDiscFriends(const RsPeerId& id, std::list &proxyIds) -{ - // This is treated appart, because otherwise we don't receive any disc info about us - if(id == rsPeers->getOwnId()) // SSL id - return rsPeers->getFriendList(proxyIds) ; - - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it; - RsPgpId pgp_id = getPGPId(id); - - it = mFriendList.find(pgp_id); - if (it == mFriendList.end()) - { - // ERROR. - return false; - } - - // For each of their friends that we know, grab that set of RsPeerId. - const std::set &friendSet = it->second.mFriendSet; - std::set::const_iterator fit; - for(fit = friendSet.begin(); fit != friendSet.end(); ++fit) - { - it = mFriendList.find(*fit); - if (it == mFriendList.end()) - { - continue; - } - - std::map::const_iterator sit; - for(sit = it->second.mSslIds.begin(); - sit != it->second.mSslIds.end(); ++sit) - { - proxyIds.push_back(sit->first); - } - } - return true; - -} - -bool p3discovery2::getWaitingDiscCount(size_t &sendCount, size_t &recvCount) -{ - RS_STACK_MUTEX(mDiscMtx); - sendCount = 0;//mPendingDiscPgpCertOutList.size(); - recvCount = 0;//mPendingDiscPgpCertInList.size(); - - return true; -} - -bool p3discovery2::getDiscPgpFriends(const RsPgpId &pgp_id, std::list &proxyPgpIds) -{ - /* find id -> and extract the neighbour_of ids */ - - if(pgp_id == rsPeers->getGPGOwnId()) // SSL id // This is treated appart, because otherwise we don't receive any disc info about us - return rsPeers->getGPGAcceptedList(proxyPgpIds) ; - - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it; - it = mFriendList.find(pgp_id); - if (it == mFriendList.end()) - { - // ERROR. - return false; - } - - std::set::const_iterator fit; - for(fit = it->second.mFriendSet.begin(); fit != it->second.mFriendSet.end(); ++fit) - { - proxyPgpIds.push_back(*fit); - } - return true; -} - -bool p3discovery2::getPeerVersion(const RsPeerId &peerId, std::string &version) -{ - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it; - it = mLocationMap.find(peerId); - if (it == mLocationMap.end()) - { - // MISSING. - return false; - } - - version = it->second.mVersion; - return true; -} - -bool p3discovery2::setPeerVersion(const RsPeerId &peerId, const std::string &version) -{ - RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it; - it = mLocationMap.find(peerId); - if (it == mLocationMap.end()) - { - mLocationMap[peerId] = DiscPeerInfo(); - it = mLocationMap.find(peerId); - } - - it->second.mVersion = version; - return true; -} - - -/*************************************************************************************/ -/* AuthGPGService */ -/*************************************************************************************/ -// AuthGPGOperation *p3discovery2::getGPGOperation() -// { -// { -// RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/ -// -// /* process disc reply in list */ -// if (!mPendingDiscPgpCertInList.empty()) { -// RsDiscPgpCertItem *item = mPendingDiscPgpCertInList.front(); -// mPendingDiscPgpCertInList.pop_front(); -// -// return new AuthGPGOperationLoadOrSave(true, item->pgpId, item->pgpCert, item); -// } -// } -// -// return NULL; -// } - -// void p3discovery2::setGPGOperation(AuthGPGOperation *operation) -// { -// AuthGPGOperationLoadOrSave *loadOrSave = dynamic_cast(operation); -// if (loadOrSave) -// { -// RsDiscPgpCertItem *item = (RsDiscPgpCertItem *) loadOrSave->m_userdata; -// if (!item) -// { -// return; -// } -// -// if (loadOrSave->m_load) -// { -// -// #ifdef P3DISC_DEBUG -// std::cerr << "p3discovery2::setGPGOperation() Loaded Cert" << std::endl; -// item->print(std::cerr, 5); -// std::cerr << std::endl; -// #endif -// // It has already been processed by PGP. -// delete item; -// } -// else -// { -// // Attaching Certificate. -// item->pgpCert = loadOrSave->m_certGpg; -// -// #ifdef P3DISC_DEBUG -// std::cerr << "p3discovery2::setGPGOperation() Sending Message:" << std::endl; -// item->print(std::cerr, 5); -// #endif -// -// // Send off message -// sendItem(item); -// } -// return; -// } -// -// /* ignore other operations */ -// } diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.h b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.h deleted file mode 100644 index 95773df69..000000000 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.h +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* - * RetroShare gossip discovery service implementation * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2013 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -// -// p3GossipDiscovery is reponsible for facilitating the circulation of public keys between friend nodes. -// -// The service locally holds a cache that stores: -// * the list of friend profiles, in each of which the list of locations with their own discovery flag (which means whether they allow discovery or not) -// * the list of friend nodes, with their version number -// -// Data flow -// ========= -// -// statusChange(std::list&) // called by pqiMonitor when peers are added,removed, or recently connected -// | -// +---- sendOwnContactInfo(RsPeerId) // [On connection] sends own PgpId, discovery flag, list of own signed GxsIds -// | | -// | +---->[to friend] -// | -// +---- locally add/remove cache info // [New/Removed friend] updates the list of friends, along with their own discovery flag -// -// tick() -// | -// +------ handleIncoming() -// | -// +-- recvOwnContactInfo(RsPeerId) // update location, IP addresses of a peer. -// | | -// | +------(if the peer has short_invite flag) -// | | | -// | | +---------requestPGPKey()->[to friend] // requests the full PGP public key, so as to be -// | | // able to validate connections. -// | | -// | +------(if disc != RS_VS_DISC_OFF) -// | | -// | +---------sendPgpList()->[to friend] // sends own list of friend profiles for which at least one location -// | // accepts discovery -// +-- processContactInfo(item->PeerId(), contact); -// | | -// | +------ addFriend() // called on nodes signed by the PGP key mentionned in the disc info -// | | -// | +------ update local discovery info -// | -// +-- recvIdentityList(Gxs Identity List) -// | | -// | +------ mGixs->requestKey(*it,peers,use_info) ; // requestKey() takes care of requesting the GxsIds that are missing -// | -// +-- recvPGPCertificate(item->PeerId(), pgpkey); -// | | -// | +------(if peer has short invite flag) -// | | -// | +--------- add key to keyring, accept connections and notify peerMgr -// | -// +-- processPGPList(pgplist->PeerId(), pgplist); // list of PGP keys of a friend, received from himself -// | | -// | +------ requestPgpCertificate() // request missing keys only -// | | -// | +------ updatePeers_locked(fromId) -// | | -// | +--------- sendContactInfo_locked(from,to) // sends IP information about mutual friends to the origin of the info -// | | -// | +--------- sendContactInfo_locked(to,from) // sends IP information origin to online mutual friends -// | -// +-- recvPGPCertificateRequest(pgplist->PeerId(), pgplist); -// | -// +------ sendPGPCertificate() // only sends the ones we are friend with, and only send own cert -// // if discovery is off -// -// Notes: -// * Tor nodes never send their own IP, and normal nodes never send their IP to Tor nodes either. -// A Tor node may accidentally know the IP of a normal node when it adds its certificate. However, the IP is dropped and not saved in this case. -// Generally speaking, no IP information should leave or transit through a Tor node. -// -// * the decision to call recvOwnContactInfo() or processContactInfo() depends on whether the item's peer id is the one the info is about. This is -// a bit unsafe. We should probably have to different items here especially if the information is not exactly the same. -// -#include - -#include "retroshare/rsgossipdiscovery.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" -#include "pqi/pqiservicemonitor.h" -#include "gossipdiscovery/gossipdiscoveryitems.h" -#include "services/p3service.h" -#include "pqi/authgpg.h" -#include "gxs/rsgixs.h" - -class p3ServiceControl; - -struct DiscSslInfo -{ - DiscSslInfo() : mDiscStatus(RS_VS_DISC_OFF) {} // default is to not allow discovery, until the peer tells about it - uint16_t mDiscStatus; -}; - -struct DiscPeerInfo -{ - DiscPeerInfo() {} - - std::string mVersion; -}; - -struct DiscPgpInfo -{ - DiscPgpInfo() {} - - void mergeFriendList(const std::set &friends); - - std::set mFriendSet; - std::map mSslIds; -}; - - -class p3discovery2 : - public RsGossipDiscovery, public p3Service, public pqiServiceMonitor - //public AuthGPGService -{ -public: - - p3discovery2( p3PeerMgr* peerMgr, p3LinkMgr* linkMgr, p3NetMgr* netMgr, - p3ServiceControl* sc, RsGixs* gixs ); - virtual ~p3discovery2(); - -virtual RsServiceInfo getServiceInfo(); - - /************* from pqiServiceMonitor *******************/ - virtual void statusChange(const std::list &plist); - /************* from pqiServiceMonitor *******************/ - - int tick(); - - /* external interface */ - bool getDiscFriends(const RsPeerId &id, std::list &friends); - bool getDiscPgpFriends(const RsPgpId &pgpid, std::list &gpg_friends); - bool getPeerVersion(const RsPeerId &id, std::string &version); - bool getWaitingDiscCount(size_t &sendCount, size_t &recvCount); - - /************* from AuthGPService ****************/ - // virtual AuthGPGOperation *getGPGOperation(); - // virtual void setGPGOperation(AuthGPGOperation *operation); - - -private: - - RsPgpId getPGPId(const RsPeerId &id); - - int handleIncoming(); - void updatePgpFriendList(); - - void addFriend(const RsPeerId &sslId); - void removeFriend(const RsPeerId &sslId); - - void updatePeerAddresses(const RsDiscContactItem *item); - void updatePeerAddressList(const RsDiscContactItem *item); - - void sendOwnContactInfo(const RsPeerId &sslid); - void recvOwnContactInfo(const RsPeerId &fromId, const RsDiscContactItem *item); - - void sendPGPList(const RsPeerId &toId); - void processPGPList(const RsPeerId &fromId, const RsDiscPgpListItem *item); - - void processContactInfo(const RsPeerId &fromId, const RsDiscContactItem *info); - - // send/recv information - - void requestPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId); - void recvPGPCertificateRequest(const RsPeerId& fromId, const RsDiscPgpListItem* item ); - void sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId); - void recvPGPCertificate(const RsPeerId &fromId, RsDiscPgpKeyItem *item); - void recvIdentityList(const RsPeerId& pid,const std::list& ids); - - bool setPeerVersion(const RsPeerId &peerId, const std::string &version); - - void rsEventsHandler(const RsEvent& event); - RsEventsHandlerId_t mRsEventsHandle; - - p3PeerMgr *mPeerMgr; - p3LinkMgr *mLinkMgr; - p3NetMgr *mNetMgr; - p3ServiceControl *mServiceCtrl; - RsGixs* mGixs; - - /* data */ - RsMutex mDiscMtx; - - void updatePeers_locked(const RsPeerId &aboutId); - void sendContactInfo_locked(const RsPgpId &aboutId, const RsPeerId &toId); - - rstime_t mLastPgpUpdate; - - std::map mFriendList; - std::map mLocationMap; - -// This was used to async the receiving of PGP keys, mainly because PGPHandler cross-checks all signatures, so receiving these keys in large loads can be costly -// Because discovery is not running in the main thread, there's no reason to re-async this into another process (e.g. AuthGPG) -// -// std::list mPendingDiscPgpCertInList; - -protected: - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; diff --git a/libretroshare/src/grouter/groutercache.h b/libretroshare/src/grouter/groutercache.h deleted file mode 100644 index cfaa847b8..000000000 --- a/libretroshare/src/grouter/groutercache.h +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: groutercache.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsflags.h" -#include "rsgrouter.h" - -#define FLAGS_TAG_GROUTER_CACHE 0x22948eb1 - -typedef t_RsFlags32 GRouterCacheInfoFlags ; -typedef uint64_t GRouterMessageId ; - -const uint32_t GROUTER_CACHE_INFO_FLAGS_WAITING_ACK = 0x0001 ; - -class GRouterMessageDataItem -{ - public: - uint8_t *data_bytes ; // data to be sent - uint32_t data_size ; // size of the data - GRouterMessageId message_id ; - GRouterKeyId destination ; - - private: - // Make this class non copiable to avoid memory issues - // - GRouterMessageDataItem& operator=(const GRouterMessageDataItem&) ; - GRouterMessageDataItem(const GRouterMessageDataItem&) ; -}; - -class GRouterCacheInfo -{ - public: - GRouterCacheInfoFlags flags ; - rstime_t last_activity ; -}; - -class GRouterCache -{ - public: - // Stored transitting messages - // - std::list _pending_messages ; - - // Cache of which message is pending, waiting for an ACK, etc. - // - std::map _cache_info ; - - // debug stuff - // - void debugDump() ; -}; - diff --git a/libretroshare/src/grouter/grouterclientservice.h b/libretroshare/src/grouter/grouterclientservice.h deleted file mode 100644 index 394f8421a..000000000 --- a/libretroshare/src/grouter/grouterclientservice.h +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: grouterclientservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// This class is the parent class for any service that will use the global router to distribute its packets. -// Typical representative clients include: -// -// p3msgservice: sends distant messages and advertise messaging keys -// -#pragma once - -#include -#include -#include - -struct RsItem; - -static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_UNKNOWN = 0x0000 ; // unused. -static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED = 0x0001 ; // sent when data has been received and a receipt is available. -static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED = 0x0002 ; // sent if the global router cannot send after a while - -class GRouterClientService -{ -public: - // This method is called by the turtle router to send data that comes out of a turtle tunnel. - // The turtle router stays responsible for the memory management of data. Most of the time the - // data chunk is a serialized item to be de-serialized by the client service. - // - // Parameters: - // item : global router item. Handled by the client service. - // destination_key : key that is associated with this item. Can be useful for the client. - // - // GRouter stays owner of the item, so the client should not delete it! - // - virtual void receiveGRouterData(const RsGxsId& destination_key,const RsGxsId& /*signing_key*/, GRouterServiceId &/*client_id*/, uint8_t */*data*/, uint32_t /*data_size*/) - { - std::cerr << "!!!!!! Received Data from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ; - std::cerr << " destination key_id = " << destination_key.toStdString() << std::endl; - } - - // This method is called by the global router when a message has been received, or cannot be sent, etc. - // - virtual void notifyDataStatus(const GRouterMsgPropagationId& received_id,const RsGxsId& signer_id,uint32_t data_status) - { - std::cerr << "!!!!!! Received Data status from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ; - std::cerr << " message ID = " << received_id << std::endl; - std::cerr << " data status = " << data_status << std::endl; - std::cerr << " signer ID = " << signer_id << std::endl; - } - - // This function is mandatory. It should do two things: - // 1 - keep a pointer to the global router, so as to be able to send data (e.g. copy pt into a local variable) - // 2 - call pt->registerTunnelService(this), so that the TR knows that service and can send back information to it. - // - virtual void connectToGlobalRouter(p3GRouter *pt) = 0 ; - - // should be derived to determine wether the client accepts data from this peer or not. If not, the data is dropped. - - virtual bool acceptDataFromPeer(const RsGxsId& gxs_id) =0; -}; - - diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc deleted file mode 100644 index 10c91b222..000000000 --- a/libretroshare/src/grouter/grouteritems.cc +++ /dev/null @@ -1,269 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: grouteritems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsprint.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" -#include "grouteritems.h" - -#include "serialiser/rstypeserializer.h" - -/**********************************************************************************************/ -/* SERIALISER STUFF */ -/**********************************************************************************************/ - -RsItem *RsGRouterSerialiser::create_item(uint16_t service_id,uint8_t subtype) const -{ - if(RS_SERVICE_TYPE_GROUTER != service_id) - return NULL; /* wrong type */ - - switch(subtype) - { - case RS_PKT_SUBTYPE_GROUTER_DATA: return new RsGRouterGenericDataItem (); - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: return new RsGRouterTransactionChunkItem(); - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN: return new RsGRouterTransactionAcknItem (); - case RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT: return new RsGRouterSignedReceiptItem (); - case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES: return new RsGRouterMatrixCluesItem (); - case RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK: return new RsGRouterMatrixTrackItem (); - case RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST: return new RsGRouterMatrixFriendListItem(); - case RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO: return new RsGRouterRoutingInfoItem (); - - default: - return NULL; - } -} - -void RsGRouterTransactionChunkItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,propagation_id,"propagation_id") ; - RsTypeSerializer::serial_process(j,ctx,chunk_start ,"chunk_start") ; - RsTypeSerializer::serial_process(j,ctx,chunk_size ,"chunk_size") ; - RsTypeSerializer::serial_process(j,ctx,total_size ,"total_size") ; - - // Hack for backward compatibility (the chunk size is not directly next to the chunk data) - - if(j == RsGenericSerializer::DESERIALIZE) - { - if(chunk_size > ctx.mSize || ctx.mOffset > ctx.mSize - chunk_size) // better than if(chunk_size + offset > size) - { - std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; - ctx.mOk = false ; - return ; - } - if( NULL == (chunk_data = (uint8_t*)rs_malloc(chunk_size))) - { - ctx.mOk = false ; - return ; - } - - memcpy(chunk_data,&((uint8_t*)ctx.mData)[ctx.mOffset],chunk_size) ; - ctx.mOffset += chunk_size ; - } - else if(j== RsGenericSerializer::SERIALIZE) - { - memcpy(&((uint8_t*)ctx.mData)[ctx.mOffset],chunk_data,chunk_size) ; - ctx.mOffset += chunk_size ; - } - else if(j== RsGenericSerializer::SIZE_ESTIMATE) - ctx.mOffset += chunk_size ; - else - std::cerr << " [Binary data] " << ", length=" << chunk_size << " data=" << RsUtil::BinToHex((uint8_t*)chunk_data,std::min(50u,chunk_size)) << ((chunk_size>50)?"...":"") << std::endl; - -} -void RsGRouterTransactionAcknItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,propagation_id,"propagation_id") ; -} - -void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,routing_id,"routing_id") ; - RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ; - RsTypeSerializer::serial_process(j,ctx,service_id,"service_id") ; - - RsTypeSerializer::RawMemoryWrapper prox(data_bytes, data_size); - RsTypeSerializer::serial_process(j, ctx, prox, "data"); - - if(!!(ctx.mFlags & RsSerializationFlags::SIGNATURE)) return; - - RsTypeSerializer::serial_process(j,ctx,signature,"signature") ; - RsTypeSerializer::serial_process(j,ctx,duplication_factor,"duplication_factor") ; - RS_SERIAL_PROCESS(flags); - - if(j == RsGenericSerializer::DESERIALIZE) // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more. - { - if(duplication_factor < 1) - { - duplication_factor = 1 ; - std::cerr << "(II) correcting GRouter item duplication factor from 0 to 1, to ensure backward compat." << std::endl; - } - if(duplication_factor > GROUTER_MAX_DUPLICATION_FACTOR) - { - std::cerr << "(WW) correcting GRouter item duplication factor of " << duplication_factor << ". This is very unexpected." << std::endl; - duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ; - } - } -} - -void RsGRouterSignedReceiptItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,routing_id,"routing_id") ; - RS_SERIAL_PROCESS(flags); - RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ; - RsTypeSerializer::serial_process (j,ctx,service_id,"service_id") ; - RsTypeSerializer::serial_process (j,ctx,data_hash,"data_hash") ; - - if(!!(ctx.mFlags & RsSerializationFlags::SIGNATURE)) return; - - RsTypeSerializer::serial_process(j,ctx,signature,"signature") ; -} - -void RsGRouterRoutingInfoItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,peerId,"peerId") ; - RsTypeSerializer::serial_process(j,ctx,data_status,"data_status") ; - RsTypeSerializer::serial_process(j,ctx,tunnel_status,"tunnel_status") ; - RsTypeSerializer::serial_process (j,ctx,received_time_TS,"received_time_TS") ; - RsTypeSerializer::serial_process (j,ctx,last_sent_TS,"last_sent_TS") ; - - RsTypeSerializer::serial_process (j,ctx,last_tunnel_request_TS,"last_tunnel_request_TS") ; - RsTypeSerializer::serial_process(j,ctx,sending_attempts,"sending_attempts") ; - - RsTypeSerializer::serial_process(j,ctx,client_id,"client_id") ; - RsTypeSerializer::serial_process (j,ctx,item_hash,"item_hash") ; - RsTypeSerializer::serial_process (j,ctx,tunnel_hash,"tunnel_hash") ; - RsTypeSerializer::serial_process(j,ctx,routing_flags,"routing_flags") ; - - RsTypeSerializer::serial_process(j,ctx,incoming_routes,"incoming_routes") ; - - // Hack for backward compatibility. Normally we should need a single commandline to serialise/deserialise a single item here. - // But the full item is serialised, so we need the header. - - if(j == RsGenericSerializer::DESERIALIZE) - { - data_item = new RsGRouterGenericDataItem() ; - - ctx.mOffset += 8 ; - data_item->serial_process(j,ctx) ; - - if(ctx.mOffset < ctx.mSize) - { - receipt_item = new RsGRouterSignedReceiptItem(); - - ctx.mOffset += 8 ; - receipt_item->serial_process(j,ctx) ; - } - else - receipt_item = NULL ; - } - else if(j == RsGenericSerializer::SERIALIZE) - { - uint32_t remaining_size = ctx.mSize - ctx.mOffset; - ctx.mOk = ctx.mOk && RsGRouterSerialiser().serialise(data_item,ctx.mData,&remaining_size) ; - ctx.mOffset += RsGRouterSerialiser().size(data_item) ; - - if(receipt_item != NULL) - { - remaining_size = ctx.mSize - ctx.mOffset; - ctx.mOk = ctx.mOk && RsGRouterSerialiser().serialise(receipt_item,ctx.mData,&remaining_size); - ctx.mOffset += RsGRouterSerialiser().size(receipt_item) ; - } - } - else if(j == RsGenericSerializer::PRINT) - { - std::cerr << " [Serialized data] " << std::endl; - - if(receipt_item != NULL) - std::cerr << " [Receipt item ]" << std::endl; - } - else if(j == RsGenericSerializer::SIZE_ESTIMATE) - { - ctx.mOffset += RsGRouterSerialiser().size(data_item) ; - - if(receipt_item != NULL) - ctx.mOffset += RsGRouterSerialiser().size(receipt_item) ; - } -} - -void RsGRouterMatrixFriendListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,reverse_friend_indices,"reverse_friend_indices") ; -} - -void RsGRouterMatrixTrackItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,provider_id,"provider_id") ; - RsTypeSerializer::serial_process(j,ctx,message_id,"message_id") ; - RsTypeSerializer::serial_process(j,ctx,time_stamp,"time_stamp") ; -} - -void RsGRouterMatrixCluesItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,destination_key,"destination_key") ; - RsTypeSerializer::serial_process(j,ctx,clues,"clues") ; -} - -template<> void RsTypeSerializer::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx,RoutingMatrixHitEntry& s,const std::string& name) -{ - RsTypeSerializer::serial_process(j,ctx,s.friend_id,name+":friend_id") ; - RsTypeSerializer::serial_process (j,ctx,s.weight,name+":weight") ; - RsTypeSerializer::serial_process (j,ctx,s.time_stamp,name+":time_stamp") ; -} - -RsGRouterGenericDataItem *RsGRouterGenericDataItem::duplicate() const -{ - RsGRouterGenericDataItem *item = new RsGRouterGenericDataItem ; - - // copy all members - - *item = *this ; - - // then duplicate the memory chunk - - if(data_size > 0) - { - item->data_bytes = (uint8_t*)rs_malloc(data_size) ; - - if(item->data_bytes == NULL) - { - delete item ; - return NULL ; - } - memcpy(item->data_bytes,data_bytes,data_size) ; - } - else - item->data_bytes = NULL ; - - return item ; -} - -RsGRouterSignedReceiptItem *RsGRouterSignedReceiptItem::duplicate() const -{ - RsGRouterSignedReceiptItem *item = new RsGRouterSignedReceiptItem ; - - // copy all members - - *item = *this ; - - return item ; -} - -RsGRouterAbstractMsgItem::~RsGRouterAbstractMsgItem() = default; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h deleted file mode 100644 index 0a12cb3f0..000000000 --- a/libretroshare/src/grouter/grouteritems.h +++ /dev/null @@ -1,296 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: grouteritems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "util/rsmemory.h" - -#include "serialiser/rsserial.h" -#include "serialiser/rstlvkeys.h" -#include "rsitems/rsserviceids.h" -#include "retroshare/rstypes.h" -#include "retroshare/rsflags.h" -#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_MATRIX_TRACK = 0x94 ; // item to save matrix track info - -const uint8_t QOS_PRIORITY_RS_GROUTER = 4 ; // relevant for items that travel through friends - - -/***********************************************************************************/ -/* Basic GRouter Item Class */ -/***********************************************************************************/ - -class RsGRouterItem: public RsItem -{ - public: - explicit RsGRouterItem(uint8_t grouter_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GROUTER,grouter_subtype) {} - - virtual ~RsGRouterItem() {} - - virtual void clear() = 0 ; -}; - -/***********************************************************************************/ -/* Helper base classes */ -/***********************************************************************************/ - -class RsGRouterNonCopyableObject -{ - public: - RsGRouterNonCopyableObject() {} - protected: - RsGRouterNonCopyableObject(const RsGRouterNonCopyableObject&) {} - RsGRouterNonCopyableObject operator=(const RsGRouterNonCopyableObject&) { return *this ;} -}; - -/***********************************************************************************/ -/* Specific packets */ -/***********************************************************************************/ - -// This abstract item class encapsulates 2 types of signed items. All have signature, destination key -// and routing ID. Sub-items are responsible for providing the serialised data to be signed for -// both signing and checking. - -enum class RsGRouterItemFlags : uint32_t -{ - NONE = 0x0, - ENCRYPTED = 0x1, - SERVICE_UNKNOWN = 0x2 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RsGRouterItemFlags) - -struct RsGRouterAbstractMsgItem: RsGRouterItem -{ - explicit RsGRouterAbstractMsgItem(uint8_t pkt_subtype): - RsGRouterItem(pkt_subtype), flags(RsGRouterItemFlags::NONE) {} - - GRouterMsgPropagationId routing_id ; - GRouterKeyId destination_key ; - GRouterServiceId service_id ; - RsTlvKeySignature signature ; // signs mid+destination_key+state - - /// packet was delivered, not delivered, bounced, etc - RsGRouterItemFlags flags; - - ~RsGRouterAbstractMsgItem(); -}; - -class RsGRouterGenericDataItem: - public RsGRouterAbstractMsgItem, public RsGRouterNonCopyableObject -{ -public: - RsGRouterGenericDataItem(): - RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_DATA), - data_size(0), data_bytes(nullptr), duplication_factor(0) - { setPriorityLevel(QOS_PRIORITY_RS_GROUTER); } - - virtual ~RsGRouterGenericDataItem() { clear(); } - virtual void clear() - { - free(data_bytes); - data_bytes = nullptr; - } - - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - - RsGRouterGenericDataItem *duplicate() const; - - /// packet data - uint32_t data_size; - uint8_t* data_bytes; - - /** number of duplicates allowed. Should be capped at each de-serialise - * operation! */ - uint32_t duplication_factor; -}; - -class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem -{ - public: - RsGRouterSignedReceiptItem() : RsGRouterAbstractMsgItem(RS_PKT_SUBTYPE_GROUTER_SIGNED_RECEIPT) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER) ; } - virtual ~RsGRouterSignedReceiptItem() {} - - virtual void clear() {} - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGRouterSignedReceiptItem *duplicate() const ; - - // packet data - // - Sha1CheckSum data_hash ; // avoids an attacker to re-use a given signed receipt. This is the hash of the enceypted data. -}; - -// Low-level data items - -class RsGRouterTransactionItem: public RsGRouterItem -{ - public: - explicit RsGRouterTransactionItem(uint8_t pkt_subtype) : RsGRouterItem(pkt_subtype) {} - - virtual ~RsGRouterTransactionItem() {} - - virtual void clear() =0; - - virtual RsGRouterTransactionItem *duplicate() const = 0 ; -}; - -class RsGRouterTransactionChunkItem: public RsGRouterTransactionItem, public RsGRouterNonCopyableObject -{ -public: - RsGRouterTransactionChunkItem() : RsGRouterTransactionItem(RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK), chunk_start(0), chunk_size(0), total_size(0), chunk_data(NULL) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER) ; } - - virtual ~RsGRouterTransactionChunkItem() { free(chunk_data) ; } - - virtual void clear() {} - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual RsGRouterTransactionItem *duplicate() const - { - RsGRouterTransactionChunkItem *item = new RsGRouterTransactionChunkItem ; - *item = *this ; // copy all fields - item->chunk_data = (uint8_t*)rs_malloc(chunk_size) ; // deep copy memory chunk - - if(item->chunk_data == NULL) - return NULL ; - - memcpy(item->chunk_data,chunk_data,chunk_size) ; - return item ; - } - - GRouterMsgPropagationId propagation_id ; - uint32_t chunk_start ; - uint32_t chunk_size ; - uint32_t total_size ; - uint8_t *chunk_data ; -}; -class RsGRouterTransactionAcknItem: public RsGRouterTransactionItem -{ -public: - RsGRouterTransactionAcknItem() : RsGRouterTransactionItem(RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER) ; } - virtual ~RsGRouterTransactionAcknItem() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual void clear() {} - - virtual RsGRouterTransactionItem *duplicate() const { return new RsGRouterTransactionAcknItem(*this) ; } - - GRouterMsgPropagationId propagation_id ; -}; - -// Items for saving the routing matrix information. - -class RsGRouterMatrixCluesItem: public RsGRouterItem -{ - public: - RsGRouterMatrixCluesItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES) - { setPriorityLevel(0) ; } // this item is never sent through the network - - virtual void clear() {} - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // packet data - // - GRouterKeyId destination_key ; - std::list clues ; -}; - -class RsGRouterMatrixTrackItem: public RsGRouterItem -{ - public: - RsGRouterMatrixTrackItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_MATRIX_TRACK), time_stamp(0) - { setPriorityLevel(0) ; } // this item is never sent through the network - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual void clear() {} - - // packet data - // - RsGxsMessageId message_id ; - RsPeerId provider_id ; - rstime_t time_stamp ; -}; -class RsGRouterMatrixFriendListItem: public RsGRouterItem -{ - public: - RsGRouterMatrixFriendListItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST) - { setPriorityLevel(0) ; } // this item is never sent through the network - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear() {} - - // packet data - // - std::vector reverse_friend_indices ; -}; - -class RsGRouterRoutingInfoItem: public RsGRouterItem, public GRouterRoutingInfo, public RsGRouterNonCopyableObject -{ - public: - RsGRouterRoutingInfoItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO) - { setPriorityLevel(0) ; } // this item is never sent through the network - - virtual ~RsGRouterRoutingInfoItem() { clear() ; } - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual void clear() - { - if(data_item != NULL) delete data_item ; - if(receipt_item != NULL) delete receipt_item ; - - data_item = NULL ; - receipt_item = NULL ; - } -}; - -/***********************************************************************************/ -/* Serialisation */ -/***********************************************************************************/ - -class RsGRouterSerialiser: public RsServiceSerializer -{ -public: - explicit RsGRouterSerialiser( - RsSerializationFlags flags = RsSerializationFlags::NONE ): - RsServiceSerializer(RS_SERVICE_TYPE_GROUTER, flags) {} - - virtual RsItem *create_item(uint16_t service,uint8_t subtype) const ; -}; - - diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc deleted file mode 100644 index b210f619e..000000000 --- a/libretroshare/src/grouter/groutermatrix.cc +++ /dev/null @@ -1,379 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: groutermatrix.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "groutertypes.h" -#include "groutermatrix.h" -#include "grouteritems.h" - -//#define ROUTING_MATRIX_DEBUG - -GRouterMatrix::GRouterMatrix() -{ - _proba_need_updating = true ; -} - -bool GRouterMatrix::addTrackingInfo(const RsGxsMessageId& mid,const RsPeerId& source_friend) -{ - rstime_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 - rstime_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. - // - uint32_t fid = getFriendId(source_friend) ; - - // 2 - get the Key map, and add the routing clue. - // - rstime_t now = time(NULL) ; - - RoutingMatrixHitEntry rc ; - rc.weight = weight ; - rc.time_stamp = now ; - rc.friend_id = fid ; - - std::list& lst( _routing_clues[key_id] ) ; - - // Prevent flooding. Happens in two scenarii: - // 1 - a user restarts RS very often => keys get republished for some reason - // 2 - a user intentionnaly floods a key - // - // Solution is to look for all recorded events, and not add any new event if an event came from the same friend - // too close in the past. Going through the list is not costly since it is bounded to RS_GROUTER_MATRIX_MAX_HIT_ENTRIES elemts. - - for(std::list::const_iterator mit(lst.begin());mit!=lst.end();++mit) - if((*mit).friend_id == fid && (*mit).time_stamp + RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS > now) - { -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << "GRouterMatrix::addRoutingClue(): too many clues for key " << key_id.toStdString() << " from friend " << source_friend << " in a small interval of " << now - lst.front().time_stamp << " seconds. Flooding?" << std::endl; -#endif - return false ; - } - - lst.push_front(rc) ; // create it if necessary - - // Remove older elements - // - uint32_t sz = lst.size() ; // O(n)! - - for(uint32_t i=RS_GROUTER_MATRIX_MAX_HIT_ENTRIES;i::const_iterator it = _friend_indices.find(source_friend) ; - - if(it == _friend_indices.end()) - return _reverse_friend_indices.size() ; - else - return it->second ; -} -uint32_t GRouterMatrix::getFriendId(const RsPeerId& source_friend) -{ - std::map::const_iterator it = _friend_indices.find(source_friend) ; - - if(it == _friend_indices.end()) - { - // add a new friend - - uint32_t new_id = _reverse_friend_indices.size() ; - _reverse_friend_indices.push_back(source_friend) ; - _friend_indices[source_friend] = new_id ; - - return new_id ; - } - else - return it->second ; -} - -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) ; -} - -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 -{ - std::cerr << " Proba needs up: " << _proba_need_updating << std::endl; - std::cerr << " Known keys: " << _time_combined_hits.size() << std::endl; - std::cerr << " Routing events: " << std::endl; - rstime_t now = time(NULL) ; - - for(std::map >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) - { - std::cerr << " " << it->first.toStdString() << " : " ; - for(std::list::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) - std::cerr << now - (*it2).time_stamp << " (" << (*it2).friend_id << "," << (*it2).weight << ") " ; - - std::cerr << std::endl; - } - std::cerr << " Routing values: " << std::endl; - - for(std::map >::const_iterator it(_time_combined_hits.begin());it!=_time_combined_hits.end();++it) - { - std::cerr << " " << it->first.toStdString() << " : " ; - - for(uint32_t i=0;isecond.size();++i) - 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, float& maximum) const -{ - // Routing probabilities are computed according to routing clues - // - // For a given key, each friend has a known set of routing clues (rstime_t, weight) - // We combine these to compute a static weight for each friend/key pair. - // This is performed in updateRoutingProbabilities() - // - // Then for a given list of online friends, the weights are computed into probabilities, - // that always sum up to 1. - // -#ifdef ROUTING_MATRIX_DEBUG - if(_proba_need_updating) - std::cerr << "GRouterMatrix::computeRoutingProbabilities(): matrix is not up to date. Not a real problem, but still..." << std::endl; -#endif - - probas.resize(friends.size(),0.0f) ; - float total = 0.0f ; - - std::map >::const_iterator it2 = _time_combined_hits.find(key_id) ; - - if(it2 == _time_combined_hits.end()) - { - // The key is not known. In this case, we return a zero probability for all peers. - // - float p = 0.0f;//1.0f / friends.size() ; - - probas.clear() ; - probas.resize(friends.size(),p) ; - -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << "GRouterMatrix::computeRoutingProbabilities(): key id " << key_id.toStdString() << " does not exist! Returning uniform probabilities." << std::endl; -#endif - return false ; - } - const std::vector& w(it2->second) ; - maximum = 0.0f ; - - for(uint32_t i=0;i= w.size()) - probas[i] = 0.0f ; - else - { - probas[i] = w[findex] ; - total += w[findex] ; - - if(maximum < w[findex]) - maximum = w[findex] ; - } - } - - if(total > 0.0f) - for(uint32_t i=0;i >::const_iterator it(_routing_clues.begin());it!=_routing_clues.end();++it) - { -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << " " << it->first.toStdString() << " : " ; -#endif - - std::vector& v(_time_combined_hits[it->first]) ; - v.clear() ; - v.resize(_friend_indices.size(),0.0f) ; - - for(std::list::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) - { - // Half life period is 7 days. - - float time_difference_in_days = 1 + (now - (*it2).time_stamp ) / (7*86400.0f) ; - v[(*it2).friend_id] += (*it2).weight / (time_difference_in_days*time_difference_in_days) ; - } - } -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << " done." << std::endl; -#endif - - _proba_need_updating = false ; - return true ; -} - -bool GRouterMatrix::saveList(std::list& items) -{ -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << " GRoutingMatrix::saveList()" << std::endl; -#endif - - RsGRouterMatrixFriendListItem *item = new RsGRouterMatrixFriendListItem ; - - 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 ; - - item->destination_key = it->first ; - item->clues = it->second ; - - items.push_back(item) ; - } - - 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 ; - 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 != (itm3 = dynamic_cast(*it))) - { -#ifdef ROUTING_MATRIX_DEBUG - std::cerr << " initing tracking clues." << std::endl; -#endif - RoutingTrackEntry rte ; - rte.friend_id = itm3->provider_id ; - rte.time_stamp = itm3->time_stamp ; - - _tracking_clues[itm3->message_id] = rte; - } - if(NULL != (itm2 = dynamic_cast(*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() ; - - 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. - } - } - - return true ; -} - diff --git a/libretroshare/src/grouter/groutermatrix.h b/libretroshare/src/grouter/groutermatrix.h deleted file mode 100644 index 7630b798d..000000000 --- a/libretroshare/src/grouter/groutermatrix.h +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: groutermatrix.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include - -#include "pgp/rscertificate.h" -#include "retroshare/rsgrouter.h" -#include "groutertypes.h" - -struct RsItem; - -// The routing matrix records the event clues received from each friend -// -struct RoutingMatrixHitEntry -{ - uint32_t friend_id ; // not the full key. Gets too big otherwise! - float weight ; - rstime_t time_stamp ; -}; - -struct RoutingTrackEntry -{ - RsPeerId friend_id ; // not the full key. Gets too big otherwise! - rstime_t time_stamp ; -}; - -class GRouterMatrix -{ - public: - GRouterMatrix() ; - - // Computes the routing probabilities for this id for the given list of friends. - // the computation accounts for the time at which the info was received and the - // weight of each routing hit record. - // - bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector& friends, std::vector& probas, float &maximum) const ; - - // Update routing probabilities for each key, accounting for all received events, but without - // activity information - // - bool updateRoutingProbabilities() ; - - // 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. - // - uint32_t getFriendId(const RsPeerId& id) ; - - // returns the friend id. If not exist, returns _reverse_friend_indices.size() - // - uint32_t getFriendId_const(const RsPeerId& id) const; - - // 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 _tracking_clues ; // who provided the most recent messages - - // This is used to avoid re-computing probas when new events have been received. - // - bool _proba_need_updating ; - - // Routing weights. These are the result of a time convolution of the routing clues and weights - // recorded in _routing_clues. - // - 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 deleted file mode 100644 index 23efdbed6..000000000 --- a/libretroshare/src/grouter/groutertypes.h +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: groutertypes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include "util/rstime.h" -#include -#include "pgp/rscertificate.h" -#include "turtle/p3turtle.h" -#include "retroshare/rsgrouter.h" - -class RsGRouterGenericDataItem ; -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 = 61 ; // 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 -static const float RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING = 0.01f ; // routing probability under which the routage is performed randomly -static const float RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT = 0.5f ; // min ratio of forward proba with respect to best peer. - -static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response. -static const uint32_t MAX_TUNNEL_UNMANAGED_TIME = 600 ; // min time before retry tunnels for that msg. -static const uint32_t MAX_DELAY_FOR_RESEND = 2*86400+300 ; // re-send if held for more than 2 days (cache store period) plus security delay. -static const uint32_t MAX_DESTINATION_KEEP_TIME = 20*86400 ; // keep for 20 days in destination cache to avoid re- -static const uint32_t MAX_RECEIPT_KEEP_TIME = 20*86400 ; // keep for 20 days in destination cache to avoid re- -static const uint32_t TUNNEL_OK_WAIT_TIME = 2 ; // wait for 2 seconds after last tunnel ok, so that we have a complete set of tunnels. -static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2MB size limit. This is of course arbitrary. -static const uint32_t MAX_TRANSACTION_ACK_WAITING_TIME = 60 ; // wait for at most 60 secs for a ACK. If not restart the transaction. -static const uint32_t DIRECT_FRIEND_TRY_DELAY = 20 ; // wait for 20 secs if no friends available, then try tunnels. -static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // clean inactive data pipes for more than 5 mins -static const uint32_t GROUTER_MAX_DUPLICATION_FACTOR = 10 ; // max number of duplicates for a given message to keep in the network -static const uint32_t GROUTER_MAX_BRANCHING_FACTOR = 3 ; // max number of branches, for locally forwarding items - -static const rstime_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything -static const rstime_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation. -static const rstime_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. -static const uint32_t RS_GROUTER_DATA_STATUS_PENDING = 0x0001 ; // item is pending. Should be sent asap. -static const uint32_t RS_GROUTER_DATA_STATUS_SENT = 0x0002 ; // item is sent to tunnel or friend. No need to keep sending. -static const uint32_t RS_GROUTER_DATA_STATUS_RECEIPT_OK = 0x0003 ; // item is at destination. -static const uint32_t RS_GROUTER_DATA_STATUS_ONGOING = 0x0004 ; // transaction is ongoing. -static const uint32_t RS_GROUTER_DATA_STATUS_DONE = 0x0005 ; // receipt item has been forward to all routes. We can remove the item. - -static const uint32_t RS_GROUTER_SENDING_STATUS_TUNNEL = 0x0001 ; // item was sent in a tunnel -static const uint32_t RS_GROUTER_SENDING_STATUS_FRIEND = 0x0002 ; // item was sent to a friend - -static const uint32_t RS_GROUTER_TUNNEL_STATUS_UNMANAGED = 0x0000 ; // no tunnel requested atm -static const uint32_t RS_GROUTER_TUNNEL_STATUS_PENDING = 0x0001 ; // tunnel requested to turtle -static const uint32_t RS_GROUTER_TUNNEL_STATUS_READY = 0x0002 ; // tunnel is ready but we're still waiting for various confirmations - -class FriendTrialRecord -{ - public: - RsPeerId friend_id ; // id of the friend - rstime_t time_stamp ; // time of the last tried - float probability ; // probability at which the item was selected - uint32_t nb_friends ; // number of friends at the time of sending the item - - bool serialise(void *data,uint32_t& offset,uint32_t size) const ; - bool deserialise(void *data,uint32_t& offset,uint32_t size) ; -}; - -class GRouterRoutingInfo -{ - // There's no destructor to this class, because the memory is managed elsewhere, which - // ovoids lots of duplications if the class is copied. -public: - GRouterRoutingInfo() - : data_status(0) - , tunnel_status(0) - , received_time_TS(0) - , last_sent_TS(0) - , last_tunnel_request_TS(0) - , sending_attempts(0) - , routing_flags(0) - , data_item(NULL) - , receipt_item(NULL) - , data_transaction_TS(0) // this is not serialised. - {} - - uint32_t data_status ; // pending, waiting, etc. - uint32_t tunnel_status ; // status of tunnel handling. - - rstime_t received_time_TS ; // time at which the item was originally received - rstime_t last_sent_TS ; // last time the item was sent - rstime_t last_tunnel_request_TS ; // last time tunnels have been asked for this item. - uint32_t sending_attempts ; // number of times tunnels have been asked for this peer without success - - GRouterServiceId client_id ; // service ID of the client. Only valid when origin==OwnId - TurtleFileHash tunnel_hash ; // tunnel hash to be used for this item - uint32_t routing_flags ; - - RsGRouterGenericDataItem *data_item ; - RsGRouterSignedReceiptItem *receipt_item ; - - RsTlvPeerIdSet incoming_routes ; - Sha1CheckSum item_hash ; // used to check re-existance, consistency, etc. - - // non serialised data - - rstime_t data_transaction_TS ; - - static const uint32_t ROUTING_FLAGS_ALLOW_TUNNELS = 0x0001; - static const uint32_t ROUTING_FLAGS_ALLOW_FRIENDS = 0x0002; - static const uint32_t ROUTING_FLAGS_IS_ORIGIN = 0x0004; - static const uint32_t ROUTING_FLAGS_IS_DESTINATION = 0x0008; -}; - diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc deleted file mode 100644 index 16148d508..000000000 --- a/libretroshare/src/grouter/p3grouter.cc +++ /dev/null @@ -1,2519 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: p3grouter.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -//////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Decentralized routing -// ===================== -// -// Main idea: Each peer holds a local routing table, a matrix with probabilities that each friend -// is a correct path for a given key ID. -// -// The routing tables are updated as messages go back and forth. Successful -// interactions feed the routing table with information of where to route the -// packets. -// -// The routing is kept probabilistic, meaning that the optimal route is not -// always chosen, but the randomness helps updating the routing probabilities. -// -// Services that might use the router (All services really...) -// - Messenger -// - sends/receives messages to distant peers -// - Channels, forums, posted, etc. -// - send messages to the origin of the channel/forum/posted -// -// Decentralized routing algorithm: -// - message passing -// - upward: -// * Forward msg to friends according to probabilities. -// * If all equal, send to all friends (or a rando subset of them). -// * keep the local routing info in a cache that is saved (Which peer issued the msg) -// - which probability was used to chose this friend (will be useful -// to compute the routing contribution if the msg is ACK-ed) -// -// Two probabilities are computed: -// - routing probabilities among connected friends -// * this is computed by the routing matrix -// - branching factor N -// * depends on the depth of the items. Currently branching is 3 at origin and 1 elsewhere. -// * depends on the distribution of probabilities (min and max) -// -// Once computed, -// - the item is forwarded randomly to N peers drawn from the list of connected peers with the given probabilities. -// - the depth of the item is incremented randomly -// -// - downward: look into routing cache. If info not present, drop the item. -// Forward item into stored direction. -// -// - routing probability computation: count number of times a reliable info is obtained from -// which direction for which identity -// * the count is a floating point number, since weights can be assigned to each info -// (especially for importance sampling) -// * init: all friends have equal count of 0 (or 1, well, we'll have to make this right). -// * We use importance sampling, meaning that when peer relays a msg from ID: -// count[ID, peer] += 1.0 / importance -// -// ... where importance was the probability of chosing peer for the -// route upward. -// -// * probability of forward is proportional to count. -// -// - routing cache -// * this cache stores messages IDs (like turtle router) but is saved on disk -// * it is used to remember where to send back responses to messages, and -// with what probability the route was chosen. -// * cache items have a TTL and the cache is cleaned regularly. -// -// - routing matrix -// * the structure is fed by other services, when they receive key IDs. -// * stores for each identity the count of how many times each peer gave reliable info for that ID. -// That information should be enough to route packets in the correct direction. -// * saved to disk. -// * all contributions should have a time stamp. Regularly, the oldest contributions are removed. -// -// - Routed packets: we use a common packet type for all services: -// -// We need two abstract item types: -// -// * Data packet -// - packet unique ID (sha1, or uint64_t) -// - destination ID (for Dn packets, the destination is the source!) -// - packet type: Id request, Message, etc. -// - packet service ID (Can be messenging, channels, etc). -// - packet data (void* + size_t) -// - flags (such as ACK or response required, and packet direction) -// - routed directions and probabilities -// * ACK packet. -// - packet unique ID (the id of the corresponding data) -// - flags (reason for ACK. Could be data delivered, or error, too far, etc) -// -// - Data storage packets -// * We need storage packets for the matrix states. -// * General routing options info? -// -// - Main difficulties: -// * have a good re-try strategy if a msg does not arrive. -// * handle peer availability. In forward mode: easy. In backward mode: -// difficult. We should wait, and send back the packet if possible. -// * robustness -// * security: avoid flooding, and message alteration. -// -// Data pipeline -// ============= -// -// sendData() -// | -// +--> encrypt/sign ---> store in _pending_messages -// -// receiveTurtleData() -// | -// +-------------------------------------------------+ -// tick() | -// | | -// +--> HandleLowLevelServiceItems() | -// | | | -// | +--> handleLowLevelServiceItem(item) <------------+ -// | | -// | +--> handleIncomingTransactionAckItem() -// | | -// | +--> handleIncomingTransactionChunkItem() -// | | -// | +---> addDataChunk() -// | | -// | +---> push item to _incoming_items list -// | -// +--> handleIncoming() -// | | -// | +---> handleIncomingReceiptItem(GRouterSignedReceiptItem*) -// | | | -// | +---> handleIncomingDataItem(GRouterDataItem*) | -// | | | -// | +----------------------------+ -// | | -// | | -// | [for US?] --------------------+-----> verifySignedData() -// | | | -// | +-----> notifyClient() -// | | | -// | | +-----> send Receipt item ---+ -// | | | -// | +----> Store In _pending_messages | -// | | -// +--> routePendingObjects() | -// | | | -// | +--> locked_collectAvailablePeers()/locked_collectAvailableTunnels() | -// | | | -// | +--> sliceDataItem() | -// | | | -// | +--> locked_sendTransactionData() <-----------------------------------------------+ -// | | -// | +--> mTurtle->sendTurtleData(virtual_pid,turtle_item) / sendItem() -// | -// +--> handleTunnels() -// | | -// | +---> mTurtle->stopMonitoringTunnels(hash) ; -// | +---> mTurtle->monitoringTunnels(hash) ; -// | -// +--> autoWash() -// -//////////////////////////////////////////////////////////////////////////////////////////////////////////// - -#include -#include - -#include "util/rsrandom.h" -#include "util/rsprint.h" -#include "util/rsmemory.h" -#include "rsitems/rsconfigitems.h" -#include "services/p3idservice.h" -#include "turtle/p3turtle.h" -#include "gxs/rsgixs.h" -#include "retroshare/rspeers.h" -#include "util/cxx17retrocompat.h" -#include "p3grouter.h" -#include "grouteritems.h" -#include "groutertypes.h" -#include "grouterclientservice.h" - -/**********************/ -//#define GROUTER_DEBUG -/**********************/ - -const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ; - -p3GRouter::p3GRouter(p3ServiceControl *sc, RsGixs *is) : - p3Service(), p3Config(), mServiceControl(sc), mTurtle(nullptr), mGixs(is), - grMtx("GRouter"), _changed(false), _debug_enabled(true), - _last_autowash_time(0), _last_matrix_update_time(0), - _last_debug_output_time(0), _last_config_changed(0), - _random_salt(RsRandom::random_u64()), - mMissingKeyQueueMtx("GRouterMissingKeyQueue") -{ addSerialType(new RsGRouterSerialiser()); } - -int p3GRouter::tick() -{ - rstime_t now = time(nullptr); - - // Sort incoming service data - // - handleLowLevelServiceItems() ; - - // Handle high level global router data - // - handleIncoming() ; - - // Take each item in the list of pending messages and receipts. If the destination peer is available - // or if the tunnel is available, the item will be sent there. - // - routePendingObjects() ; - - // clean things up. Remove unused requests, old stuff etc. - - autoWash() ; - - // Go through the list of active tunnel requests and pending objects to ask for new tunnels - // or close existing tunnel requests. - // - handleTunnels() ; - - /* Handle items in mMissingKeyQueue */ - if(now > mMissingKeyQueueCheckLastCheck + mMissingKeyQueueCheckEvery) - { - mMissingKeyQueueCheckLastCheck = now; - - RS_STACK_MUTEX(mMissingKeyQueueMtx); - for(auto it = mMissingKeyQueue.begin(); it != mMissingKeyQueue.end();) - { - const RsGxsId& senderId = it->first->signature.keyId; - if(rsIdentity->isKnownId(senderId)) - { - Dbg2() << __PRETTY_FUNCTION__ << " got key: " << senderId - << " for item pending validation, calling item handler" - << std::endl; - - handleIncomingItem(it->first.get()); - it = mMissingKeyQueue.erase(it); - } - else - { - Dbg3() << __PRETTY_FUNCTION__ << " requesting missing key: " - << senderId << " to validate pending item" << std::endl; - - /* At this point the network status may have varied a lot since - * we received the item, so we don't even know if the peer who - * forwarded the item is still online, moreover the fact that - * after specific request we haven't got the key yet suggests it - * is not a good route toward the key, so request it to all - * available peers */ - rsIdentity->requestIdentity(senderId); - ++it; - } - } - } - - // Update routing matrix - // - if(now > _last_matrix_update_time + RS_GROUTER_MATRIX_UPDATE_PERIOD) - { - RsStackMutex mtx(grMtx) ; - - _last_matrix_update_time = now ; - _routing_matrix.updateRoutingProbabilities() ; // This should be locked. - _routing_matrix.cleanUp() ; // This should be locked. - } - -#ifdef GROUTER_DEBUG - // Debug dump everything - // - if(now > _last_debug_output_time + RS_GROUTER_DEBUG_OUTPUT_PERIOD) - { - _last_debug_output_time = now ; - if(_debug_enabled) - debugDump() ; - } -#endif - - // If content has changed, save config, at most every RS_GROUTER_MIN_CONFIG_SAVE_PERIOD seconds appart - // Otherwise, always save at least every RS_GROUTER_MAX_CONFIG_SAVE_PERIOD seconds - // - if(_changed && now > _last_config_changed + RS_GROUTER_MIN_CONFIG_SAVE_PERIOD) - { -#ifdef GROUTER_DEBUG - grouter_debug() << "p3GRouter::tick(): triggering config save." << std::endl; -#endif - - _changed = false ; - _last_config_changed = now ; - IndicateConfigChanged() ; - } - - return 0 ; -} - -RsSerialiser *p3GRouter::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - - rss->addSerialType(new RsGRouterSerialiser) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss ; -} - -bool p3GRouter::registerKey(const RsGxsId& authentication_key,const GRouterServiceId& client_id,const std::string& description) -{ - RS_STACK_MUTEX(grMtx) ; - - if(_registered_services.find(client_id) == _registered_services.end()) - { - std::cerr << __PRETTY_FUNCTION__ << ": unable to register key " << authentication_key << " for client id " << client_id << ": client id is not known." << std::endl; - return false ; - } - - GRouterPublishedKeyInfo info ; - info.service_id = client_id ; - info.authentication_key = authentication_key ; - info.description_string = description.substr(0,20); - - Sha1CheckSum hash = makeTunnelHash(authentication_key,client_id) ; - - _owned_key_ids[hash] = info ; -#ifdef GROUTER_DEBUG - grouter_debug() << "Registered the following key: " << std::endl; - grouter_debug() << " Auth GXS Id : " << authentication_key << std::endl; - grouter_debug() << " Client id : " << std::hex << client_id << std::dec << std::endl; - grouter_debug() << " Description : " << info.description_string << std::endl; - grouter_debug() << " Hash : " << hash << std::endl; -#endif - - return true ; -} -bool p3GRouter::unregisterKey(const RsGxsId& key_id,const GRouterServiceId& sid) -{ - RS_STACK_MUTEX(grMtx) ; - - Sha1CheckSum hash = makeTunnelHash(key_id,sid) ; - - const auto it = _owned_key_ids.find(hash); - if(it == _owned_key_ids.end()) - { - RsErr() << __PRETTY_FUNCTION__ << " key " << key_id << " not found." - << std::endl; - return false; - } - -#ifdef GROUTER_DEBUG - grouter_debug() << "p3GRouter::unregistered the following key: " << std::endl; - grouter_debug() << " Key id : " << key_id.toStdString() << std::endl; - grouter_debug() << " Client id : " << std::hex << it->second.service_id << std::dec << std::endl; - grouter_debug() << " Description : " << it->second.description_string << std::endl; -#endif - - _owned_key_ids.erase(it) ; - - return true ; -} -//===========================================================================================================================// -// Service data handling // -//===========================================================================================================================// - -void p3GRouter::handleLowLevelServiceItems() -{ - // While messages read - // - RsItem *item = NULL; - - while(NULL != (item = recvItem())) - { - RsGRouterTransactionItem *gtitem = dynamic_cast(item); - if (gtitem) - { - handleLowLevelServiceItem(gtitem) ; - } - else - { - delete(item); - } - } -} - -void p3GRouter::handleLowLevelServiceItem(RsGRouterTransactionItem *item) -{ - switch(item->PacketSubType()) - { - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_ACKN: - { - RsGRouterTransactionAcknItem *trans_ack_item = dynamic_cast(item); - if (trans_ack_item) - { - handleLowLevelTransactionAckItem(trans_ack_item) ; - } - break ; - } - case RS_PKT_SUBTYPE_GROUTER_TRANSACTION_CHUNK: - { - RsGRouterTransactionChunkItem *chunk_item = dynamic_cast(item); - if (chunk_item) - { - handleLowLevelTransactionChunkItem(chunk_item) ; - } - break ; - } - default: - std::cerr << "p3GRouter::handleIncoming: Unknown packet subtype " << item->PacketSubType() << std::endl ; - } - delete item; -} - -//===========================================================================================================================// -// Turtle management // -//===========================================================================================================================// - -bool p3GRouter::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/) -{ - // tunnel request is answered according to the following rules: - // - we are the destination => always accept - // - we know the destination and have RCPT items to send back => always accept - // - we know the destination and have a route (according to matrix) => accept with high probability - // - we don't know the destination => accept with very low probability - - if(_owned_key_ids.find(hash) == _owned_key_ids.end()) - return false ; - -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::handleTunnelRequest(). Got req for hash " << hash << ", responding OK" << std::endl; -#endif - return true ; -} - -void p3GRouter::handleLowLevelTransactionChunkItem(RsGRouterTransactionChunkItem *chunk_item) -{ -#ifdef GROUTER_DEBUG - std::cerr << " item is a transaction item." << std::endl; -#endif - - RsPeerId pid = chunk_item->PeerId() ; - - RsGRouterAbstractMsgItem *generic_item = NULL; - { - RS_STACK_MUTEX(grMtx) ; - - generic_item = _incoming_data_pipes[pid].addDataChunk(dynamic_cast(chunk_item->duplicate())) ;// addDataChunk takes ownership over chunk_item - } - - // send to client off-mutex - - if(generic_item == NULL) - return ; - - generic_item->PeerId(pid) ; - -#ifdef GROUTER_DEBUG - std::cerr << " transaction is finished. Passing newly created item to client." << std::endl; - std::cerr << " sending a ACK item" << std::endl; -#endif - - RsGRouterTransactionAcknItem ackn_item ; - ackn_item.propagation_id = generic_item->routing_id ; - locked_sendTransactionData(pid,ackn_item) ; - - { - RS_STACK_MUTEX(grMtx) ; - _incoming_items.push_back(generic_item) ; - } -} - -void p3GRouter::handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem *trans_ack_item) -{ -#ifdef GROUTER_DEBUG - std::cerr << " item is a transaction ACK." << std::endl; -#endif - RS_STACK_MUTEX(grMtx) ; - - std::map::iterator it=_pending_messages.find(trans_ack_item->propagation_id) ; - - if(it != _pending_messages.end() && it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING) - { - it->second.data_status = RS_GROUTER_DATA_STATUS_SENT; - it->second.last_sent_TS = time(NULL) ; -#ifdef GROUTER_DEBUG - std::cerr << " setting new status as sent/awaiting receipt." << std::endl; -#endif - } -#ifdef GROUTER_DEBUG - else - std::cerr << " Note: no routing ID corresponds to this ACK item. This probably corresponds to a signed receipt" << std::endl; -#endif -} - -void p3GRouter::receiveTurtleData(const RsTurtleGenericTunnelItem *gitem, const RsFileHash & hash, const RsPeerId &virtual_peer_id, RsTurtleGenericTunnelItem::Direction direction) -{ -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::receiveTurtleData() " << std::endl; - std::cerr << " Received data for hash : " << hash << std::endl; - std::cerr << " Virtual peer id : " << virtual_peer_id << std::endl; - std::cerr << " Direction : " << direction << std::endl; -#endif - - // turtle data is received. - // This function - // - possibly packs multi-item blocks back together - // - converts it into a grouter generic item (by deserialising it) - - const RsTurtleGenericDataItem *item = dynamic_cast(gitem) ; - - if(item == NULL) - { - std::cerr << " ERROR: item is not a data item. That is an error." << std::endl; - return ; - } -#ifdef GROUTER_DEBUG - std::cerr << " data size : " << item->data_size << std::endl; - std::cerr << " data bytes : " << RsDirUtil::sha1sum((unsigned char*)item->data_bytes,item->data_size) << std::endl; -#endif - - // Items come out of the pipe in order. We need to recover all chunks before we de-serialise the content and have it handled by handleIncoming() - - uint32_t size = item->data_size ; - RsItem *itm = RsGRouterSerialiser().deserialise(item->data_bytes,&size); - -if(itm == NULL) -{ - std::cerr << "(EE) p3GRouter::receiveTurtleData(): cannot de-serialise data. Somthing wrong in the format. Item data (size="<< item->data_size << "): " << RsUtil::BinToHex((char*)item->data_bytes,item->data_size) << std::endl; - return ; -} - - itm->PeerId(virtual_peer_id) ; - - // At this point we can have either a transaction chunk, or a transaction ACK. - // We handle them both here - - RsGRouterTransactionChunkItem *chunk_item = dynamic_cast(itm) ; - RsGRouterTransactionAcknItem *trans_ack_item = NULL; - - if(chunk_item != NULL) - handleLowLevelTransactionChunkItem(chunk_item) ; - else if(NULL != (trans_ack_item = dynamic_cast(itm))) - handleLowLevelTransactionAckItem(trans_ack_item) ; - else - { - std::cerr << " ERROR: cannot deserialise turtle item." << std::endl; - if(itm) - delete itm ; - } -} - -void GRouterTunnelInfo::removeVirtualPeer(const TurtleVirtualPeerId& vpid) -{ - std::set::iterator it = virtual_peers.find(vpid) ; - - if(it == virtual_peers.end()) - { - std::cerr << " ERROR: removing a virtual peer that does not exist. This is an error!" << std::endl; - return ; - } - - virtual_peers.erase(it) ; -} -void GRouterTunnelInfo::addVirtualPeer(const TurtleVirtualPeerId& vpid) -{ - if(virtual_peers.find(vpid) != virtual_peers.end()) - std::cerr << " ERROR: adding a virtual peer that already exist. This is an error!" << std::endl; - - virtual_peers.insert(vpid) ; - - rstime_t now = time(NULL) ; - - if(first_tunnel_ok_TS == 0) first_tunnel_ok_TS = now ; - last_tunnel_ok_TS = now ; -} - -RsGRouterAbstractMsgItem *GRouterDataInfo::addDataChunk(RsGRouterTransactionChunkItem *chunk) -{ - last_activity_TS = time(NULL) ; - - // perform some checking - - if(chunk->total_size > MAX_GROUTER_DATA_SIZE + 10000 || chunk->chunk_size > chunk->total_size || chunk->chunk_start >= chunk->total_size) - { - std::cerr << " ERROR: chunk size is unconsistent, or too large: size=" << chunk->chunk_size << ", start=" << chunk->chunk_start << ", total size=" << chunk->total_size << ". Chunk will be dropped. Data pipe will be reset." << std::endl; - clear() ; - delete chunk ; - return NULL ; - } - - // now add that chunk. - - if(incoming_data_buffer == NULL) - { - if(chunk->chunk_start != 0) - { - std::cerr << " ERROR: chunk numbering is wrong. First chunk is not starting at 0. Dropping." << std::endl; - delete chunk; - return NULL; - } - incoming_data_buffer = chunk ; - } - else - { - if(incoming_data_buffer->chunk_size != chunk->chunk_start || incoming_data_buffer->total_size != chunk->total_size) - { - std::cerr << " ERROR: chunk numbering is wrong. Dropping." << std::endl; - delete chunk ; - delete incoming_data_buffer ; - incoming_data_buffer = NULL ; - return NULL; - } - incoming_data_buffer->chunk_data = (uint8_t*)realloc((uint8_t*)incoming_data_buffer->chunk_data,incoming_data_buffer->chunk_size + chunk->chunk_size) ; - memcpy(&incoming_data_buffer->chunk_data[incoming_data_buffer->chunk_size],chunk->chunk_data,chunk->chunk_size) ; - incoming_data_buffer->chunk_size += chunk->chunk_size ; - - delete chunk ; - } - - // if finished, return it. - - if(incoming_data_buffer->total_size == incoming_data_buffer->chunk_size) - { - RsItem *data_item = RsGRouterSerialiser().deserialise(incoming_data_buffer->chunk_data,&incoming_data_buffer->chunk_size) ; - - delete incoming_data_buffer; - incoming_data_buffer = NULL ; - - return dynamic_cast(data_item) ; - } - else - return NULL ; -} - -void p3GRouter::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) -{ - RS_STACK_MUTEX(grMtx) ; - - // Server side tunnels. This is incoming data. Nothing to do. - -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::addVirtualPeer(). Received vpid " << virtual_peer_id << " for hash " << hash << ", direction=" << dir << std::endl; - std::cerr << " direction = " << dir << std::endl; -#endif - - // client side. We set the tunnel flags to READY. - - if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER) - { - bool found = false ; - - // linear search. Bad, but not really a problem. New virtual peers come quite rarely. - for(std::map::iterator it(_pending_messages.begin());it!=_pending_messages.end();++it) - if(it->second.tunnel_hash == hash) - { -#ifdef GROUTER_DEBUG - std::cerr << " setting tunnel state to READY." << std::endl; -#endif - it->second.tunnel_status = RS_GROUTER_TUNNEL_STATUS_READY ; - found = true ; - - // don't break here, because we might send multiple items though the same tunnel. - } - - if(!found) - { - std::cerr << " ERROR: cannot find corresponding pending message." << std::endl; - return ; - } - } - if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) - { - } - -#ifdef GROUTER_DEBUG - std::cerr << " adding VPID." << std::endl; -#endif - - _tunnels[hash].addVirtualPeer(virtual_peer_id) ; - -} - -void p3GRouter::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) -{ - RS_STACK_MUTEX(grMtx) ; - -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::removeVirtualPeer(). Removing vpid " << virtual_peer_id << " for hash " << hash << std::endl; - std::cerr << " removing VPID." << std::endl; -#endif - - // make sure the VPID exists. - - std::map::iterator it = _tunnels.find(hash) ; - - if(it == _tunnels.end()) - { - std::cerr << " no virtual peers at all for this hash: " << hash << "! This is a consistency error." << std::endl; - return ; - } - it->second.removeVirtualPeer(virtual_peer_id) ; - -#ifdef GROUTER_DEBUG - std::cerr << " setting tunnel status in pending message." << std::endl; -#endif - - for(std::map::iterator it2(_pending_messages.begin());it2!=_pending_messages.end();++it2) - if(it2->second.tunnel_hash == hash && it->second.virtual_peers.empty()) - it2->second.tunnel_status = RS_GROUTER_TUNNEL_STATUS_PENDING ; - - if(it->second.virtual_peers.empty()) - { -#ifdef GROUTER_DEBUG - std::cerr << " last virtual peer removed. Also deleting hash entry." << std::endl; -#endif - _tunnels.erase(it) ; - } - -} - -void p3GRouter::connectToTurtleRouter(p3turtle *pt) -{ - mTurtle = pt ; - pt->registerTunnelService(this) ; -} - -//===========================================================================================================================// -// Tunnel management // -//===========================================================================================================================// - -class item_comparator_001 -{ -public: - template - bool operator()(const std::pair& p1,const std::pair& p2) const - { - return p1.first < p2.first ; - } -}; - -void p3GRouter::handleTunnels() -{ - // This function is responsible for asking for tunnels, and removing requests from the turtle router. - // To remove the unnecessary TR activity generated by multiple peers trying to send the same message, - // only peers which haven't passed on any data to direct friends, or for which the best friends are not online - // will be allowed to monitor tunnels. - - // Go through the list of pending messages - // - if tunnels are pending for too long => remove from turtle - // - if item is waiting for too long => tunnels are waitin - - // We need a priority queue of items to handle, starting from the most ancient items, with a delay that varies with - // how much time they have been waiting. When a turtle slot it freed, we take the next item in the queue and - // activate tunnel handling for it. - - // possible pending message status: - // - RS_GROUTER_PENDING_MSG_STATUS_TUNNEL_READY : tunnel is ready. Waiting a few seconds to be used (this is to allow multiple tunnels to come). - // - RS_GROUTER_PENDING_MSG_STATUS_TUNNEL_PENDING : tunnel was asked. - // - RS_GROUTER_PENDING_MSG_STATUS_TUNNEL_UNMANAGED: not tunnel managed at the moment. - - // 1 - make a priority list of messages to ask tunnels for - - // Compute the priority of pending messages, according to the number of attempts and how far in the past they have been tried for the last time. - // Delay after which a message is re-sent, depending on the number of attempts already made. - - RS_STACK_MUTEX(grMtx) ; - -#ifdef GROUTER_DEBUG - if(!_pending_messages.empty()) - { - grouter_debug() << "p3GRouter::handleTunnels()" << std::endl; - grouter_debug() << " building priority list of items to send..." << std::endl; - } -#endif - - rstime_t now = time(NULL) ; - std::vector > priority_list ; - - for(std::map::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it) - { -#ifdef GROUTER_DEBUG - grouter_debug() << " " << std::hex << it->first << std::dec - << ", data_status=" << it->second.data_status << ", tunnel_status=" << it->second.tunnel_status - << ", last received: "<< now - it->second.received_time_TS << " (secs ago)" - << ", last TR: "<< now - it->second.last_tunnel_request_TS << " (secs ago)" - << ", last sent: " << now - it->second.last_sent_TS << " (secs ago) "<< std::endl; -#endif - - if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING && (it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS)) - { - if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_UNMANAGED && it->second.last_tunnel_request_TS + MAX_TUNNEL_UNMANAGED_TIME < now) - { - uint32_t item_delay = now - it->second.last_tunnel_request_TS ; - int item_priority = item_delay ; - -#ifdef GROUTER_DEBUG - grouter_debug() << " delay=" << item_delay << " attempts=" << it->second.sending_attempts << ", priority=" << item_priority << std::endl; -#endif - - if(item_priority > 0) - priority_list.push_back(std::make_pair(item_priority,&it->second)) ; - } - else if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_PENDING && it->second.last_tunnel_request_TS + MAX_TUNNEL_WAIT_TIME < now) - { - mTurtle->stopMonitoringTunnels(it->second.tunnel_hash) ; - - it->second.tunnel_status = RS_GROUTER_TUNNEL_STATUS_UNMANAGED ; - -#ifdef GROUTER_DEBUG - grouter_debug() << " stopping tunnels for this message." << std::endl; ; -#endif - } -#ifdef GROUTER_DEBUG - else if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_READY) - grouter_debug() << " tunnel is available. " << std::endl; - else - grouter_debug() << " doing nothing." << std::endl; - - grouter_debug() << std::endl; -#endif - } - else - { -#ifdef GROUTER_DEBUG - std::cerr << " closing pending tunnels." << std::endl; -#endif - mTurtle->stopMonitoringTunnels(it->second.tunnel_hash) ; - - it->second.tunnel_status = RS_GROUTER_TUNNEL_STATUS_UNMANAGED ; - } - - // also check that all tunnels are actually active, to remove any old dead tunnels - // - // if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_READY) - // { - // std::map::iterator it2 = _tunnels.find(it->second.tunnel_hash) ; - // - // if(it2 == _tunnels.end() || it2->second.virtual_peers.empty()) ; - // { - // std::cerr << " re-setting tunnel status to PENDING, as no tunnels are actually present." << std::endl; - // it->second.tunnel_status = RS_GROUTER_TUNNEL_STATUS_PENDING ; - // } - // } - } -#ifdef GROUTER_DEBUG - if(!priority_list.empty()) - grouter_debug() << " sorting..." << std::endl; -#endif - - - std::sort(priority_list.begin(),priority_list.end(),item_comparator_001()) ; - - // take tunnels from item priority list, and enable tunnel handling, while respecting max number of active tunnels limit - - for(uint32_t i=0;ifirst << " with duplication factor = " << itpid->second << std::endl; -#endif - // delete temporary items - - for(std::list::const_iterator cit=chunks.begin();cit!=chunks.end();++cit) - delete *cit; - } - - data_item->duplication_factor = saved_duplication_factor ; -} - -void p3GRouter::routePendingObjects() -{ - // Go throught he list of pending messages. For those with a peer ready, send the message to that peer. - // The peer might be: - // - a virtual peer id that actually is a tunnel - // - a real friend node - // Tunnels and friends will used whenever available. Of course this might cause a message to arrive multiple times, but we - // don't really care since the GR takes care of duplicates already. - // - // Which tunnels are available is handled by handleTunnels() - // - - rstime_t now = time(NULL) ; - - RS_STACK_MUTEX(grMtx) ; -#ifdef GROUTER_DEBUG - if(!_pending_messages.empty()) - std::cerr << "p3GRouter::routePendingObjects()" << std::endl; -#endif - bool pending_messages_changed = false ; - - for(std::map::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it) - { -#ifdef GROUTER_DEBUG - std::cerr << " message " << std::hex << it->first << std::dec << std::endl; -#endif - if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING) - { - // Look for tunnels and friends where to send the data. Send to both. - - std::map peers_and_duplication_factors ; - - if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS) - locked_collectAvailableTunnels(it->second.tunnel_hash,it->second.data_item->duplication_factor,peers_and_duplication_factors); - - if(!peers_and_duplication_factors.empty()) - { -#ifdef GROUTER_DEBUG - std::cerr << " tunnels available! sending!" << std::endl; -#endif - locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ; - - // change item state in waiting list - - it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ; - it->second.data_transaction_TS = now ; - - pending_messages_changed = true ; - continue ; // no need to seek for friend asynced routes since tunnels directly go to the final destination! - } - - if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS) - locked_collectAvailableFriends(it->second.data_item->destination_key,it->second.incoming_routes.ids,it->second.data_item->duplication_factor,peers_and_duplication_factors); - - if(!peers_and_duplication_factors.empty()) - { -#ifdef GROUTER_DEBUG - std::cerr << " friends available! sending!" << std::endl; -#endif - locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ; - - // change item state in waiting list - - it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ; - it->second.data_transaction_TS = now ; - - pending_messages_changed = true ; - } - else - { -#ifdef GROUTER_DEBUG - std::cerr << " no direct friends available" << std::endl; -#endif - - if(it->second.received_time_TS + DIRECT_FRIEND_TRY_DELAY < now && !(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS)) - { -#ifdef GROUTER_DEBUG - std::cerr << " enabling tunnels for this message." << std::endl; -#endif - it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; - } - } - - } - else if(it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING && now > MAX_TRANSACTION_ACK_WAITING_TIME + it->second.data_transaction_TS) - { -#ifdef GROUTER_DEBUG - std::cerr << " waited too long for this transation. Switching back to PENDING." << std::endl; -#endif - - it->second.data_status = RS_GROUTER_DATA_STATUS_PENDING ; - } - else if(it->second.data_status == RS_GROUTER_DATA_STATUS_SENT) - { - if( (it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN) && it->second.last_sent_TS + MAX_DELAY_FOR_RESEND < now) - { -#ifdef GROUTER_DEBUG - std::cerr << " item was not received. Re-setting status to PENDING" << std::endl; -#endif - it->second.data_status = RS_GROUTER_DATA_STATUS_PENDING ; - } - else - { -#ifdef GROUTER_DEBUG - std::cerr << " item was sent. Desactivating tunnels." << std::endl; -#endif - it->second.routing_flags &= ~GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; - } - } - - // We treat this case apart, so as to make sure that receipt items are always forwarded wen possible even if the data_status - // is not set correctly. - - if(it->second.receipt_item != NULL && !it->second.incoming_routes.ids.empty()) - { - // send the receipt through all incoming routes, as soon as it gets delivered. - -#ifdef GROUTER_DEBUG - std::cerr << " receipt should be sent back. Trying all incoming routes..." << std::endl; -#endif - - std::list chunks ; - - for(std::set::iterator it2=it->second.incoming_routes.ids.begin();it2!=it->second.incoming_routes.ids.end();) - if(mServiceControl->isPeerConnected(getServiceInfo().mServiceType,*it2) || mTurtle->isTurtlePeer(*it2)) - { -#ifdef GROUTER_DEBUG - std::cerr << " sending receipt back to " << *it2 << " which is online." << std::endl; -#endif - if(chunks.empty()) - sliceDataItem(it->second.receipt_item,chunks) ; - - for(std::list::const_iterator it3(chunks.begin());it3!=chunks.end();++it3) - locked_sendTransactionData(*it2,*(*it3) ) ; - - // then remove from the set. - std::set::iterator it2tmp = it2 ; - ++it2tmp ; - it->second.incoming_routes.ids.erase(it2) ; - it2 = it2tmp ; - - pending_messages_changed = true ; - } - else - ++it2 ; - - for(std::list::const_iterator cit=chunks.begin();cit!=chunks.end();++cit) - delete *cit; - - // Because signed receipts are small items, we take the bet that if the item could be sent, then it was received. - // otherwise, we should mark that incomng route as being handled, wait for the ACK and deal with it by updating - // it->second.data_status at that time. - - if(it->second.incoming_routes.ids.empty()) - it->second.data_status = RS_GROUTER_DATA_STATUS_DONE ; - } - } - - if(pending_messages_changed) - IndicateConfigChanged() ; -} - -void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const std::set& incoming_routes,uint32_t duplication_factor, std::map& friend_peers_and_duplication_factors) -{ - // Old strategy was the following: - // if origin - // send to multiple neighbors : best and random - // else - // send to a single "best" neighbor (determined by threshold over routing probability), - - // New strategy is: - // - // Characteristics of the distribution to look at: - // * who's online, who's not - // * all values quite equal - // * single value well above others - // * largest value is small - // Algorithm: - // - // 0 - encode duplicate factor in routed item and allow at most N duplicates - // - when forwarding to N peers, split the duplication factor into N bins, each being proportional to the forwarding probability. - // Example for N=3 and D=10: - // - // p Calculation Final bin - // - // +-0.21--> 0.21*10=2.1 --> 2 0.1 below - // | - // 10 ----+-0.45--> 0.45*10=4.5 --> 4.6-> 5 0.4 above - // | - // +-0.34--> 0.34*10=3.4 --> 3.0-> 3 0 - // - // - // 1 - get routing probabilities p_i for all peers as well as the maximum proba p before normalization. - // - // Set N = min(3,item->duplication_factor) // max number of friends to route to - // - // if p < threshold // That means the routage info is too old => Fallback to random routing. - // Select N random online friends and forward to them. - // else - // Let p_i be the probabilities of all peers - // Select all online peers for which p_i >= 0.5*p. - // if !empty - // Update duplication factors according to probabilities and number of peers - // Route to these peers - // else - // Keep the item - // - -#ifdef GROUTER_DEBUG - std::cerr << "locked_getAvailableFriends()" << std::endl; - std::cerr << " looking for friends for item to ID " << gxs_id << " duplication factor = " << duplication_factor << std::endl; - std::cerr << " retrieving online friends and all friends lists." << std::endl; -#endif - std::set online_ids ; - std::list all_ids ; - - rsPeers->getFriendList(all_ids) ; - mServiceControl->getPeersConnected(getServiceInfo().mServiceType,online_ids) ; - - std::vector tmp_peers; - - for(std::list::const_iterator it(all_ids.begin());it!=all_ids.end();++it) - tmp_peers.push_back(*it) ; - - std::vector probas; - float maximum = 1.0; - float max_probability = 0.0; - - _routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas, maximum) ; - -#ifdef GROUTER_DEBUG - std::cerr << " initial routing probabilities (maximum=" << maximum << ")" << std::endl; - for(uint32_t i=0;i using uniform random routing." << std::endl; -#endif - } - else - { - for(uint32_t i=0;i giving up." << std::endl; -#endif - return ; - } - - // now select the N best peers -#ifdef GROUTER_DEBUG - std::cerr << " Remaining peers and routing probabilities:" << std::endl; - for(uint32_t i=0;i > mypairs ; - - for(uint32_t i=0;i 0 && max_count > 0) - { - for(int i=mypairs.size()-1,n=0;i>=0 && n=0 && n=0 && nsecond.last_tunnel_ok_TS + TUNNEL_OK_WAIT_TIME > now) - { -#ifdef GROUTER_DEBUG - std::cerr << ". Still waiting delay (stabilisation)." << std::endl; -#endif - return ; - } - - // for now, just take one. But in the future, we will need some policy to temporarily store objects at proxy peers, etc. - -#ifdef GROUTER_DEBUG - std::cerr << " " << vpit->second.virtual_peers.size() << " virtual peers available. " << std::endl; -#endif - TurtleVirtualPeerId vpid = *(vpit->second.virtual_peers.begin()) ; - - tunnel_peers_and_duplication_factors[vpid] = total_duplication ; -} - -bool p3GRouter::locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& trans_item) -{ - if(mTurtle->isTurtlePeer(pid)) - { -#ifdef GROUTER_DEBUG - std::cerr << " sending to tunnel vpid " << pid << std::endl; -#endif - uint32_t turtle_data_size = RsGRouterSerialiser().size(const_cast(&trans_item)) ; - uint8_t *turtle_data = (uint8_t*)rs_malloc(turtle_data_size) ; - - if(turtle_data == NULL) - return false ; - - if(!RsGRouterSerialiser().serialise(const_cast(&trans_item),turtle_data,&turtle_data_size)) - { - std::cerr << " ERROR: cannot serialise RsGRouterTransactionChunkItem." << std::endl; - - free(turtle_data) ; - return false ; - } - - RsTurtleGenericDataItem *turtle_item = new RsTurtleGenericDataItem ; - - turtle_item->data_size = turtle_data_size ; - turtle_item->data_bytes = turtle_data ; - -#ifdef GROUTER_DEBUG - std::cerr << " sending to vpid " << pid << std::endl; -#endif - mTurtle->sendTurtleData(pid,turtle_item) ; - - return true ; - } - else - { -#ifdef GROUTER_DEBUG - std::cerr << " sending to pid " << pid << std::endl; -#endif - RsGRouterTransactionItem *item_copy = trans_item.duplicate() ; - item_copy->PeerId(pid) ; - - sendItem(item_copy) ; - - return true ; - } -} - -void p3GRouter::autoWash() -{ - bool items_deleted = false ; - rstime_t now = time(nullptr); - - std::map > failed_msgs ; - - { - RS_STACK_MUTEX(grMtx) ; - - for(std::map::iterator it=_pending_messages.begin();it!=_pending_messages.end();) - { - bool delete_entry = false ; - - if(it->second.data_status == RS_GROUTER_DATA_STATUS_DONE ) - { - if(!(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_DESTINATION) || it->second.received_time_TS + MAX_DESTINATION_KEEP_TIME < now) // is the item too old for cache - delete_entry = true ; - } - else if(it->second.data_status == RS_GROUTER_DATA_STATUS_RECEIPT_OK ) - { - if(it->second.received_time_TS + MAX_RECEIPT_KEEP_TIME < now) // is the item too old for cache - delete_entry = true ; - } - else - if(it->second.received_time_TS + GROUTER_ITEM_MAX_CACHE_KEEP_TIME < now) - delete_entry = true ; - - if(delete_entry) - { -#ifdef GROUTER_DEBUG - grouter_debug() << " Removing cached item " << std::hex << it->first << std::dec << std::endl; -#endif - //GRouterClientService *client = NULL ; - //GRouterServiceId service_id = 0; - - if( it->second.data_status != RS_GROUTER_DATA_STATUS_DONE ) - { - GRouterClientService *client = NULL; - - if(locked_getLocallyRegisteredClientFromServiceId(it->second.client_id,client)) - failed_msgs[it->first] = std::make_pair(client,it->second.data_item->signature.keyId) ; - else - std::cerr << " ERROR: client id " << it->second.client_id << " not registered. Consistency error." << std::endl; - } - - delete it->second.data_item ; - - if(it->second.receipt_item != NULL) - delete it->second.receipt_item ; - - std::map::iterator tmp(it) ; - ++tmp ; - _pending_messages.erase(it) ; - it = tmp ; - - items_deleted = true ; - } - else - ++it ; - } - - // also check all existing tunnels - - for(std::map::iterator it = _tunnels.begin();it!=_tunnels.end();++it) - { - std::list vpids_to_remove ; - for(std::set::iterator it2 = it->second.virtual_peers.begin();it2!=it->second.virtual_peers.end();++it2) - if(!mTurtle->isTurtlePeer(*it2)) - { - vpids_to_remove.push_back(*it2) ; -#ifdef GROUTER_DEBUG - std::cerr << " " << *it2 << " is not an active tunnel for hash " << it->first << ". Removing virtual peer id." << std::endl; -#endif - } - - for(std::list::const_iterator it2=vpids_to_remove.begin();it2!=vpids_to_remove.end();++it2) - it->second.removeVirtualPeer(*it2) ; - } - - - // Also clean incoming data pipes - - for(std::map::iterator it(_incoming_data_pipes.begin());it!=_incoming_data_pipes.end();) - if(it->second.last_activity_TS + MAX_INACTIVE_DATA_PIPE_DELAY < now) - { -#ifdef GROUTER_DEBUG - std::cerr << " removing data pipe for peer " << it->first << " which is too old." << std::endl; -#endif - std::map::iterator ittmp = it ; - ++ittmp ; - it->second.clear() ; - _incoming_data_pipes.erase(it) ; - it = ittmp ; - } - else - ++it ; - - /* Cleanup timed out items in mMissingKeyQueue */ - mMissingKeyQueueMtx.lock(); - while( mMissingKeyQueue.begin() != mMissingKeyQueue.end() && - mMissingKeyQueue.front().second <= now ) - { - RsWarn() << __PRETTY_FUNCTION__ << " Deleting timed out item from " - << "unknown RsGxsId: " - << mMissingKeyQueue.front().first->signature.keyId - << std::endl; - mMissingKeyQueue.pop_front(); - } - mMissingKeyQueueMtx.unlock(); - } - // Look into pending items. - - for(std::map >::const_iterator it(failed_msgs.begin());it!=failed_msgs.end();++it) - { -#ifdef GROUTER_DEBUG - std::cerr << " notifying client for message id " << std::hex << it->first << " state = FAILED" << std::endl; -#endif - it->second.first->notifyDataStatus(it->first,it->second.second ,GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED) ; - } - - if(items_deleted) - _changed = true ; -} - -bool p3GRouter::sliceDataItem(RsGRouterAbstractMsgItem *item,std::list& chunks) -{ - try - { - // Split the item into chunks. This function ensures that chunks in the list are valid. Memory ownership is left to the - // calling client. In case of error, all allocated memory is deleted. - -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::sliceDataItem()" << std::endl; - std::cerr << "item dump before send:" << std::endl; - item->print(std::cerr, 2) ; -#endif - - uint32_t size = RsGRouterSerialiser().size(item); - - RsTemporaryMemory data(size) ; // data will be freed on return, whatever the route taken. - - if(data == NULL) - { - std::cerr << " ERROR: cannot allocate memory. Size=" << size << std::endl; - throw ; - } - - if(!RsGRouterSerialiser().serialise(item,data,&size)) - { - std::cerr << " ERROR: cannot serialise." << std::endl; - throw ; - } - - uint32_t offset = 0 ; - static const uint32_t CHUNK_SIZE = 15000 ; - - while(offset < size) - { - uint32_t chunk_size = std::min(size - offset, CHUNK_SIZE) ; - - RsGRouterTransactionChunkItem *chunk_item = new RsGRouterTransactionChunkItem ; - - chunk_item->propagation_id = item->routing_id ; - chunk_item->total_size = size; - chunk_item->chunk_start= offset; - chunk_item->chunk_size = chunk_size ; - chunk_item->chunk_data = (uint8_t*)rs_malloc(chunk_size) ; -#ifdef GROUTER_DEBUG - std::cerr << " preparing to send a chunk [" << offset << " -> " << offset + chunk_size << " / " << size << "]" << std::endl; -#endif - - if(chunk_item->chunk_data == NULL) - { - delete chunk_item; - throw ; - } - memcpy(chunk_item->chunk_data,&data[offset],chunk_size) ; - - offset += chunk_size ; - - chunks.push_back(chunk_item) ; - } - - return true ; - } - catch(...) - { - for(std::list::const_iterator it(chunks.begin());it!=chunks.end();++it) - delete *it ; - - chunks.clear() ; - - return false ; - } -} - -void p3GRouter::handleIncoming() -{ - while(!_incoming_items.empty()) - { - RsGRouterAbstractMsgItem *item = _incoming_items.front() ; - _incoming_items.pop_front() ; - - handleIncomingItem(item); - delete item ; - } -} - -void p3GRouter::handleIncomingItem(const RsGRouterAbstractMsgItem *item) -{ - const RsGRouterGenericDataItem *generic_data_item ; - const RsGRouterSignedReceiptItem *receipt_item ; - - if(NULL != (generic_data_item = dynamic_cast(item))) - handleIncomingDataItem(generic_data_item) ; - else if(NULL != (receipt_item = dynamic_cast(item))) - handleIncomingReceiptItem(receipt_item) ; - else - std::cerr << "Item has unknown type (not data nor signed receipt). Dropping!" << std::endl; -} - -void p3GRouter::handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *receipt_item) -{ - bool changed = false ; -#ifdef GROUTER_DEBUG - std::cerr << "Handling incoming signed receipt item." << std::endl; - std::cerr << "Item content:" << std::endl; - const_cast(receipt_item)->print(std::cerr,2) ; -#endif - RsGxsId signer_id ; - - // Because we don't do proxy-transmission yet, the client needs to be notified. Otherwise, we will need to - // first check if we're a proxy or not. We also remove the message from the global router sending list. - // in the proxy case, we should only store the receipt. - - GRouterClientService *client_service = NULL; - GRouterMsgPropagationId mid = 0 ; - - { - RS_STACK_MUTEX (grMtx) ; - - std::map::iterator it=_pending_messages.find(receipt_item->routing_id) ; - if(it == _pending_messages.end()) - { - std::cerr << " ERROR: no routing ID corresponds to this message. Inconsistency!" << std::endl; - return ; - } - signer_id = it->second.data_item->signature.keyId ; - - // check hash. - - if(receipt_item->data_hash != it->second.item_hash) - { - std::cerr << " checking receipt hash : FAILED. Receipt is dropped." << std::endl; - return ; - } -#ifdef GROUTER_DEBUG - else - std::cerr << " checking receipt hash : OK" << std::endl; -#endif - // check signature. The policy if the following: - // if we're the destination: - // signature should check and signing key should be available // always ensures the receipt is valid - // else - // if key is available, signature should check // early protects against frodulent receipts that we can check - - uint32_t error_status ; - - if(! verifySignedDataItem(receipt_item,RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CHECK,error_status)) - if( (it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN) || (error_status != RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE)) - { - std::cerr << " checking receipt signature : FAILED. Receipt is dropped. Error status=" << error_status << std::endl; - return ; - } -#ifdef GROUTER_DEBUG - std::cerr << " checking receipt signature : OK. " << std::endl; - std::cerr << " removing messsage from cache." << std::endl; -#endif - - if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN) - { -#ifdef GROUTER_DEBUG - std::cerr << " message is at origin. Setting message transmission to DONE" << std::endl; -#endif - it->second.data_status = RS_GROUTER_DATA_STATUS_DONE; - - if(locked_getLocallyRegisteredClientFromServiceId(it->second.client_id,client_service)) - mid = it->first ; - else - { - mid = 0 ; - std::cerr << " ERROR: cannot retrieve service ID for message " << std::hex << it->first << std::dec << std::endl; - } - } - else - { -#ifdef GROUTER_DEBUG - std::cerr << " message is not at origin. Setting message transmission to RECEIPT_OK" << std::endl; -#endif - it->second.data_status = RS_GROUTER_DATA_STATUS_RECEIPT_OK; - it->second.receipt_item = receipt_item->duplicate() ; - } - - changed = true ; - } - - if(mid != 0) - { -#ifdef GROUTER_DEBUG - std::cerr << " notifying client " << (void*)client_service << " that msg " << std::hex << mid << std::dec << " was received." << std::endl; -#endif - client_service->notifyDataStatus(mid, signer_id, GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED) ; - } - - // also note the incoming route in the routing matrix - - if(!mTurtle->isTurtlePeer(receipt_item->PeerId())) - { -#ifdef GROUTER_DEBUG - std::cerr << " receipt item comes from a direct friend. Marking route in routing matrix." << std::endl; -#endif - addRoutingClue(receipt_item->signature.keyId,receipt_item->PeerId()) ; - } - - if(changed) - IndicateConfigChanged() ; -} - -Sha1CheckSum p3GRouter::computeDataItemHash(const RsGRouterGenericDataItem *data_item) -{ - RsGRouterSerialiser signature_serializer( - RsSerializationFlags::SIGNATURE | - RsSerializationFlags::SKIP_HEADER ); - - uint32_t signed_data_size = signature_serializer.size(const_cast(data_item)); - uint32_t total_size = signed_data_size + data_item->signature.TlvSize() ; - RsTemporaryMemory mem(total_size) ; - - uint32_t offset = 0 ; - uint32_t tmp_size = total_size ; - signature_serializer.serialise(const_cast(data_item),mem,&tmp_size) ; - if(tmp_size != signed_data_size) - std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl; - - offset += tmp_size ; - - data_item->signature.SetTlv(mem, total_size,&offset) ; - - if(offset != total_size) - std::cerr << "(EE) Some error occured in p3GRouter::computeDataItemHash(). Mismatched offset/data size" << std::endl; - - return RsDirUtil::sha1sum(mem,total_size) ; -} - -void p3GRouter::handleIncomingDataItem(const RsGRouterGenericDataItem *data_item) -{ -#ifdef GROUTER_DEBUG - std::cerr << "Handling incoming data item. " << std::endl; - std::cerr << "Item content:" << std::endl; - const_cast(data_item)->print(std::cerr,2) ; -#endif - - // we find 3 things: - // A - is the item for us ? - // B - signature and hash check ? - // C - item is already known ? - - // Store the item? if !C - // Send a receipt? if A && B - // Notify client? if A && !C - // - GRouterClientService *clientService = NULL ; - GRouterServiceId service_id = data_item->service_id ; - RsGRouterSignedReceiptItem *receipt_item = NULL ; - - Sha1CheckSum item_hash = computeDataItemHash(data_item) ; - - bool item_is_already_known = false ; - bool cache_has_changed = false ; - bool item_is_for_us = _owned_key_ids.find( makeTunnelHash(data_item->destination_key,service_id) ) != _owned_key_ids.end() ; - - // A - Find client and service ID from destination key. -#ifdef GROUTER_DEBUG - std::cerr << " step A: find if the item is for us or not, and whether it's aready in cache or not." << std::endl; -#endif - { - RS_STACK_MUTEX(grMtx) ; - - // also check wether this item is for us or not - -#ifdef GROUTER_DEBUG - std::cerr << " item is " << (item_is_for_us?"":"not") << " for us." << std::endl; -#endif - auto it = _pending_messages.find(data_item->routing_id) ; - - if(it != _pending_messages.end()) - { - if(it->second.item_hash != item_hash) - { -#ifdef GROUTER_DEBUG - std::cerr << " ERROR: item is already known but data hash does not match. Dropping that item." << std::endl; -#endif - return ; - } - item_is_already_known = true ; - receipt_item = it->second.receipt_item ; -#ifdef GROUTER_DEBUG - std::cerr << " item is already in cache." << std::endl; -#endif - } -#ifdef GROUTER_DEBUG - else - std::cerr << " item is new." << std::endl; -#endif - } - - if(!item_is_already_known) - { - uint32_t error_status ; - - if(!verifySignedDataItem(data_item,RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CHECK,error_status)) // we should get proper flags out of this - { - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: - { - RS_STACK_MUTEX(mMissingKeyQueueMtx); - - rstime_t timeout = time(nullptr) + mMissingKeyQueueEntryTimeout; - RsGxsId authorId = data_item->signature.keyId; - mMissingKeyQueue.push_back( std::make_pair(std::unique_ptr(data_item->duplicate()), timeout) ); - - /* Do not request the missing key here to the peer which forwarded the item as verifySignedDataItem(...) does it already */ - - RsInfo() << __PRETTY_FUNCTION__ << " Received a message from unknown RsGxsId: " << authorId <<". Cannot verify signature yet, storing in mMissingKeyQueue for later processing. Timeout: " << timeout << std::endl; - return; - } - default: - RsWarn() << __PRETTY_FUNCTION__ << " item signature verification FAILED with: " << error_status << ", Dropping!" << std::endl; - return; - } - } -#ifdef GROUTER_DEBUG - else - std::cerr << " verifying item signature: CHECKED!" ; -#endif - } - - // At this point, if item is already known, it is guarrantied to be identical to the stored item. - // If the item is for us, and not already known, check the signature and hash, and generate a signed receipt - - if(item_is_for_us && !item_is_already_known) - { - // Check that we actually have a registered service ready to accept this item. If not, drop it. - - { - RS_STACK_MUTEX(grMtx) ; - auto its = _registered_services.find(service_id) ; - - if(its != _registered_services.end()) - clientService = its->second ; - } - -#ifdef GROUTER_DEBUG - std::cerr << " step B: item is for us and is new, so make sure it's authentic and create a receipt" << std::endl; -#endif - // No we need to send a signed receipt to the sender. - - receipt_item = new RsGRouterSignedReceiptItem; - receipt_item->data_hash = item_hash ; - receipt_item->service_id = data_item->service_id ; - receipt_item->routing_id = data_item->routing_id ; - receipt_item->destination_key = data_item->signature.keyId ; - receipt_item->flags = RsGRouterItemFlags::NONE ; - - if(!clientService) - { - receipt_item->flags = RsGRouterItemFlags::SERVICE_UNKNOWN; - RsWarn() << __PRETTY_FUNCTION__ << " got a message from: " << data_item->signature.keyId << " for an unkown service: " << data_item->service_id << " is your RetroShare version updated?" << std::endl; - } - -#ifdef GROUTER_DEBUG - std::cerr << " preparing signed receipt." << std::endl; -#endif - - if(!signDataItem(receipt_item,data_item->destination_key)) - { - std::cerr << " signing: FAILED. Receipt dropped. ERROR. Packet dropped as well." << std::endl; - return ; - } -#ifdef GROUTER_DEBUG - std::cerr << " signing: OK." << std::endl; -#endif - } -#ifdef GROUTER_DEBUG - else - std::cerr << " step B: skipped, since item is not for us, or already known." << std::endl; -#endif - - // now store the item in _pending_messages whether it is for us or not (if the item is for us, this prevents receiving multiple - // copies of the message) -#ifdef GROUTER_DEBUG - std::cerr << " step C: store the item is cache." << std::endl; -#endif - { - RS_STACK_MUTEX(grMtx) ; - - GRouterRoutingInfo& info(_pending_messages[data_item->routing_id]) ; - - if(info.data_item == NULL) // item is not for us - { -#ifdef GROUTER_DEBUG - std::cerr << " item is new. Storing it." << std::endl; -#endif - - info.data_item = data_item->duplicate() ; - info.receipt_item = receipt_item ; // inited before, or NULL. - info.tunnel_status = RS_GROUTER_TUNNEL_STATUS_UNMANAGED ; - info.last_sent_TS = 0 ; - info.client_id = data_item->service_id ; - info.item_hash = item_hash ; - info.last_tunnel_request_TS = 0 ; - info.sending_attempts = 0 ; - info.received_time_TS = time(NULL) ; - info.tunnel_hash = makeTunnelHash(data_item->destination_key,data_item->service_id) ; - - if(item_is_for_us) - { - // don't store if item is for us. No need to take that much memory. - - free(info.data_item->data_bytes) ; - info.data_item->data_size = 0 ; - info.data_item->data_bytes = NULL ; - - info.routing_flags = GRouterRoutingInfo::ROUTING_FLAGS_IS_DESTINATION | GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS ; - info.data_status = RS_GROUTER_DATA_STATUS_RECEIPT_OK ; - } - else - { - info.routing_flags = GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS ; // don't allow tunnels just yet - info.data_status = RS_GROUTER_DATA_STATUS_PENDING ; - } - } -#ifdef GROUTER_DEBUG - else - std::cerr << " item is already in cache." << std::endl; - - std::cerr << " storing incoming route from " << data_item->PeerId() << std::endl; -#endif - info.incoming_routes.ids.insert(data_item->PeerId()) ; - cache_has_changed = true ; - } - - // if the item is for us and is not already known, notify the client. - - if(clientService && !item_is_already_known) - { - // compute the hash before decryption. - -#ifdef GROUTER_DEBUG - std::cerr << " step D: item is for us and is new: decrypting and notifying client." << std::endl; -#endif - RsGRouterGenericDataItem *decrypted_item = data_item->duplicate() ; - - if(!decryptDataItem(decrypted_item)) - { - std::cerr << " decrypting item : FAILED! Item cannot be passed to the client." << std::endl; - delete decrypted_item ; - - return ; - } -#ifdef GROUTER_DEBUG - else - std::cerr << " decrypting item : OK!" << std::endl; - - std::cerr << " notyfying client." << std::endl; -#endif - if(clientService->acceptDataFromPeer(decrypted_item->signature.keyId)) - { - clientService->receiveGRouterData(decrypted_item->destination_key,decrypted_item->signature.keyId,service_id,decrypted_item->data_bytes,decrypted_item->data_size); - - decrypted_item->data_bytes = NULL ; - decrypted_item->data_size = 0 ; - } - - delete decrypted_item ; - } -#ifdef GROUTER_DEBUG - else - std::cerr << " step D: item is not for us or not new: skipping this step." << std::endl; -#endif - - if(cache_has_changed) - IndicateConfigChanged() ; -} - -bool p3GRouter::locked_getLocallyRegisteredClientFromServiceId(const GRouterServiceId& service_id,GRouterClientService *& client) -{ - client = NULL ; - - std::map::const_iterator its = _registered_services.find(service_id) ; - - if(its == _registered_services.end()) - { - std::cerr << " ERROR: client id " << service_id << " not registered. Consistency error." << std::endl; - return false; - } - - client = its->second ; - - return true ; -} - -void p3GRouter::addRoutingClue(const RsGxsId& id, const RsPeerId& peer_id) -{ - RS_STACK_MUTEX(grMtx) ; -#ifdef GROUTER_DEBUG - 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) -{ - RS_STACK_MUTEX(grMtx) ; - _registered_services[id] = service ; - return true ; -} - -bool p3GRouter::encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) -{ - assert(!(item->flags & RsGRouterItemFlags::ENCRYPTED)); - -#ifdef GROUTER_DEBUG - std::cerr << " Encrypting data for key " << destination_key << std::endl; - std::cerr << " Decrypted size = " << item->data_size << std::endl; -#endif - - uint8_t *encrypted_data =NULL; - uint32_t encrypted_size =0; - uint32_t error_status ; - - if(!mGixs->encryptData( item->data_bytes, item->data_size, encrypted_data, - encrypted_size, destination_key, error_status, - true )) - { - std::cerr << "(EE) Cannot encrypt: " ; - if(error_status == RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE) std::cerr << " key not available for ID = " << destination_key << std::endl; - if(error_status == RsGixs::RS_GIXS_ERROR_UNKNOWN ) std::cerr << " unknown error for ID = " << destination_key << std::endl; - - return false ; - } - - free(item->data_bytes) ; - item->data_bytes = encrypted_data ; - item->data_size = encrypted_size ; - item->flags |= RsGRouterItemFlags::ENCRYPTED; - -#ifdef GROUTER_DEBUG - std::cerr << " Encrypted size = " << encrypted_size << std::endl; - std::cerr << " First bytes of encrypted data: " << RsUtil::BinToHex((const char *)encrypted_data,std::min(encrypted_size,30u)) << "..."<< std::endl; - std::cerr << " Encrypted data hash = " << RsDirUtil::sha1sum((const uint8_t *)encrypted_data,encrypted_size) << std::endl; -#endif -return true ; -} -bool p3GRouter::decryptDataItem(RsGRouterGenericDataItem *item) -{ - assert(!!(item->flags & RsGRouterItemFlags::ENCRYPTED)); - -#ifdef GROUTER_DEBUG - std::cerr << " decrypting data for key " << item->destination_key << std::endl; - std::cerr << " encrypted size = " << item->data_size << std::endl; -#endif - - uint8_t *decrypted_data =NULL; - uint32_t decrypted_size =0; - uint32_t error_status ; - - if(!mGixs->decryptData( item->data_bytes, item->data_size, decrypted_data, - decrypted_size, item->destination_key, error_status, - true )) - { - if(error_status == RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE) - std::cerr << "(EE) Cannot decrypt incoming message. Key " << item->destination_key << " unknown." << std::endl; - else - std::cerr << "(EE) Cannot decrypt incoming message. Unknown error. " << std::endl; - - return false ; - } - - free(item->data_bytes) ; - item->data_bytes = decrypted_data ; - item->data_size = decrypted_size ; - item->flags &= ~RsGRouterItemFlags::ENCRYPTED; - - return true ; -} - -bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signing_id) -{ - try - { -//#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::signDataItem()" << std::endl; - std::cerr << " Key ID = " << signing_id << std::endl; - std::cerr << " Getting key material..." << std::endl; -//#endif - RsGRouterSerialiser signature_serializer( - RsSerializationFlags::SIGNATURE | - RsSerializationFlags::SKIP_HEADER ); - uint32_t data_size = signature_serializer.size(item) ; - RsTemporaryMemory data(data_size) ; - - if(data == NULL) - throw std::runtime_error("Cannot allocate memory for signing data.") ; - - if(!signature_serializer.serialise(item,data,&data_size)) - throw std::runtime_error("Cannot serialise signed data.") ; - - uint32_t error_status ; - - std::cerr << "GRouter::signing data" << std::endl; - std::cerr << " size: " << data_size << std::endl; - std::cerr << " data: " << RsUtil::BinToHex(data,data_size) << std::endl; - - if(!mGixs->signData(data,data_size,signing_id,item->signature,error_status)) - throw std::runtime_error("Cannot sign for id " + signing_id.toStdString() + ". Signature call failed.") ; - -//#ifdef GROUTER_DEBUG - std::cerr << "Created signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key id=" << signing_id << std::endl; -//#endif - // Check signature - RsIdentityUsage::UsageCode info = RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CREATION; - uint32_t error; - - if(verifySignedDataItem(item,info,error)) - std::cerr << "Signature checks." << std::endl; - else - { - std::cerr << "(EE) Cannot verify own signed item. Something's wrong." << std::endl; - return false ; - } - - return true ; - } - catch(std::exception& e) - { - std::cerr << " signing failed. Error: " << e.what() << std::endl; - - item->signature.TlvClear() ; - return false ; - } -} -bool p3GRouter::verifySignedDataItem(const RsGRouterAbstractMsgItem *item,const RsIdentityUsage::UsageCode& info,uint32_t& error_status) -{ - try - { - if( rsReputations->overallReputationLevel(item->signature.keyId) == - RsReputationLevel::LOCALLY_NEGATIVE ) - { - RsWarn() << __PRETTY_FUNCTION__ << " received global router " - << "message from banned identity " << item->signature.keyId - << ". Rejecting the message." << std::endl; - return false; - } - - RsGRouterSerialiser signature_serializer( - RsSerializationFlags::SIGNATURE | - RsSerializationFlags::SKIP_HEADER ); - - uint32_t data_size = signature_serializer.size(const_cast(item)); // the const cast shouldn't be necessary if size() took a const. - RsTemporaryMemory data(data_size); - - if(data == NULL) - throw std::runtime_error("Cannot allocate data.") ; - - if(!signature_serializer.serialise(const_cast(item),data,&data_size)) - throw std::runtime_error("Cannot serialise signed data."); - - RsIdentityUsage use(RsServiceType::GROUTER,info); - - if(!mGixs->validateData( data, data_size, item->signature, true, use, error_status )) - { - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: - { - std::list peer_ids; - peer_ids.push_back(item->PeerId()); - - RsWarn() << __PRETTY_FUNCTION__ << " Key for GXS Id " << item->signature.keyId << " is not available. Cannot verify. Asking key to peer " << item->PeerId() << std::endl; - mGixs->requestKey(item->signature.keyId,peer_ids,use); - } - break; - case RsGixs::RS_GIXS_ERROR_SIGNATURE_MISMATCH: - RsWarn() << __PRETTY_FUNCTION__ << " Signature mismatch. " << "Spoofing/Corrupted/MITM?." << std::endl; - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Signature verification failed on GRouter message. Unknown error status: " << error_status << std::endl; - break; - } - return false; - } - - return true; - } - catch(std::exception& e) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed. Error: " << e.what() << std::endl; - return false ; - } -} - -bool p3GRouter::cancel(GRouterMsgPropagationId mid) -{ - { - RS_STACK_MUTEX(grMtx) ; - -#ifdef GROUTER_DEBUG - std::cerr << "p3GRouter::cancel(). Canceling message ID " << mid << std::endl; -#endif - - std::map::iterator it = _pending_messages.find(mid) ; - - if(it == _pending_messages.end()) - { - std::cerr << " ERROR: message ID is unknown." << std::endl; - return false ; - } - - delete it->second.data_item ; - if(it->second.receipt_item) - delete it->second.receipt_item; - - _pending_messages.erase(it) ; - } - - IndicateConfigChanged() ; - - return true ; -} - -bool p3GRouter::sendData( const RsGxsId& destination, const GRouterServiceId& client_id, const uint8_t* data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId&propagation_id ) -{ -// std::cerr << "GRouter currently disabled." << std::endl; -// return false; - - if(data_size > MAX_GROUTER_DATA_SIZE) - { - std::cerr << "GRouter max size limit exceeded (size=" << data_size << ", max=" << MAX_GROUTER_DATA_SIZE << "). Please send a smaller object!" << std::endl; - return false ; - } - - // Make sure we have a unique id (at least locally). There's little chances that an id of the same value is out there anyway. - // - { - RsStackMutex mtx(grMtx) ; - do { propagation_id = RSRandom::random_u64(); } while(_pending_messages.find(propagation_id) != _pending_messages.end()) ; - } - - // create the signed data item - - RsGRouterGenericDataItem *data_item = new RsGRouterGenericDataItem ; - - data_item->data_bytes = (uint8_t*)rs_malloc(data_size) ; - - if(data_item->data_bytes == NULL) - return false ; - - memcpy(data_item->data_bytes,data,data_size) ; - - data_item->data_size = data_size ; - data_item->routing_id = propagation_id ; - data_item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ; - data_item->service_id = client_id ; - data_item->destination_key = destination ; - data_item->flags = RsGRouterItemFlags::NONE ; // this is unused for now. - - // First, encrypt. - - if(!encryptDataItem(data_item,destination)) - { - std::cerr << "Cannot encrypt data item. Some error occured!" << std::endl; - delete data_item; - return false; - } - - // Then, sign the encrypted data, so that the signature can be checked by non priviledged users. - - if(!signDataItem(data_item,signing_id)) - { - std::cerr << "Cannot sign data item. Some error occured!" << std::endl; - delete data_item; - return false; - } - - // Verify the signature. If that fails, there's a bug somewhere!! - uint32_t error_status; - - if(!verifySignedDataItem(data_item,RsIdentityUsage::GLOBAL_ROUTER_SIGNATURE_CREATION,error_status)) - { - std::cerr << "Cannot verify data item that was just signed. Some error occured!" << std::endl; - delete data_item; - return false; - } - // push the item into pending messages. - // - GRouterRoutingInfo info ; - - rstime_t now = time(NULL) ; - - info.data_item = data_item ; - info.receipt_item = NULL ; - info.data_status = RS_GROUTER_DATA_STATUS_PENDING ; - info.tunnel_status = RS_GROUTER_TUNNEL_STATUS_UNMANAGED ; - info.last_sent_TS = 0 ; - info.client_id = client_id ; - info.last_tunnel_request_TS = 0 ; - info.item_hash = computeDataItemHash(data_item) ; - info.sending_attempts = 0 ; - info.routing_flags = GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN | GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS ;// don't allow tunnels just yet - info.received_time_TS = now ; - info.tunnel_hash = makeTunnelHash(destination,client_id) ; - -#ifdef GROUTER_DEBUG - grouter_debug() << "p3GRouter::sendGRouterData(): pushing the following item in the msg pending list:" << std::endl; - grouter_debug() << " routing id = " << std::hex << propagation_id << std::dec << std::endl; - grouter_debug() << " data_item.size = " << info.data_item->data_size << std::endl; - grouter_debug() << " data_item.byte = " << RsDirUtil::sha1sum(info.data_item->data_bytes,info.data_item->data_size) << std::endl; - grouter_debug() << " destination = " << data_item->destination_key << std::endl; - grouter_debug() << " signed by key = " << data_item->signature.keyId << std::endl; - grouter_debug() << " data status = " << info.data_status << std::endl; - grouter_debug() << " tunnel status = " << info.tunnel_status << std::endl; - grouter_debug() << " sending attempt= " << info.sending_attempts << std::endl; - grouter_debug() << " duplicate fact = " << info.data_item->duplication_factor << std::endl; - grouter_debug() << " recv time = " << info.received_time_TS << std::endl; - grouter_debug() << " client id = " << std::hex << data_item->service_id << std::dec << std::endl; - grouter_debug() << " tunnel hash = " << info.tunnel_hash << std::endl; - grouter_debug() << " item hash = " << info.item_hash << std::endl; - grouter_debug() << " routing flags = " << info.routing_flags << std::endl; -#endif - - { - RS_STACK_MUTEX(grMtx) ; - _pending_messages[propagation_id] = info ; - } - IndicateConfigChanged() ; - -return true ; -} - -Sha1CheckSum p3GRouter::makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client) -{ - static_assert( RsGxsId::SIZE_IN_BYTES == 16, - "This function breaks if RsGxsId size changes" ); - static_assert( Sha1CheckSum::SIZE_IN_BYTES == 20, - "This function breaks if Sha1CheckSum size changes" ); - static_assert( sizeof(client) == 4, - "This function breaks if client service id size changes" ); - - uint8_t bytes[20] ; - memcpy(bytes,destination.toByteArray(),16) ; - bytes[16] = 0 ; - bytes[17] = 0 ; - bytes[18] = (client >> 8) & 0xff ; - bytes[19] = client & 0xff ; - - return RsDirUtil::sha1sum(bytes,20) ; -} -bool p3GRouter::loadList(std::list& items) -{ - { - RS_STACK_MUTEX(grMtx) ; - -#ifdef GROUTER_DEBUG - grouter_debug() << "p3GRouter::loadList() : " << std::endl; -#endif - - _routing_matrix.loadList(items) ; - -#ifdef GROUTER_DEBUG - // remove all existing objects. - // - grouter_debug() << " removing all existing items (" << _pending_messages.size() << " items to delete)." << std::endl; -#endif - - if(!_pending_messages.empty()) - std::cerr << " WARNING: pending msg list is not empty. List will be cleared." << std::endl; - - // clear the existing list. - // - for(std::map::iterator it(_pending_messages.begin());it!=_pending_messages.end();++it) - delete it->second.data_item ; - - _pending_messages.clear() ; - - for(std::list::const_iterator it(items.begin());it!=items.end();++it) - { - RsGRouterRoutingInfoItem *itm1 = NULL ; - - if(NULL != (itm1 = dynamic_cast(*it))) - { - // clean data state - itm1->tunnel_status = RS_GROUTER_TUNNEL_STATUS_UNMANAGED ; - - _pending_messages[itm1->data_item->routing_id] = *itm1 ; - - itm1->data_item = NULL ; // prevents deletion. - itm1->receipt_item = NULL ; // prevents deletion. - } - - delete *it ; - } - } -#ifdef GROUTER_DEBUG - debugDump(); -#endif - items.clear() ; - return true ; -} -bool p3GRouter::saveList(bool& cleanup,std::list& items) -{ - // We save - // - the routing clues - // - the pending items - - cleanup = true ; // the client should delete the items. - -#ifdef GROUTER_DEBUG - grouter_debug() << "p3GRouter::saveList()..." << std::endl; - grouter_debug() << " saving routing clues." << std::endl; -#endif - - RS_STACK_MUTEX(grMtx) ; - - _routing_matrix.saveList(items) ; - -#ifdef GROUTER_DEBUG - grouter_debug() << " saving pending items." << std::endl; -#endif - - for(std::map::const_iterator it(_pending_messages.begin());it!=_pending_messages.end();++it) - { - RsGRouterRoutingInfoItem *item = new RsGRouterRoutingInfoItem ; - -#warning: Cppcheck(cstyleCast): C-style pointer casting - // cppcheck-suppress cstyleCast - *(GRouterRoutingInfo*)item = it->second ; // copy all members - - item->data_item = it->second.data_item->duplicate() ; // deep copy, because we call delete on the object, and the item might be removed before we handle it in the client. - if(it->second.receipt_item != NULL) - item->receipt_item = it->second.receipt_item->duplicate() ; - - items.push_back(item) ; - } - - return true ; -} - -bool p3GRouter::getRoutingMatrixInfo(RsGRouter::GRouterRoutingMatrixInfo& info) -{ - RS_STACK_MUTEX(grMtx) ; - - info.per_friend_probabilities.clear() ; - info.friend_ids.clear() ; - info.published_keys.clear() ; - - std::list ids ; - //mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ; - rsPeers->getFriendList(ids) ; - - info.published_keys = _owned_key_ids ; - - for(std::list::const_iterator it(ids.begin());it!=ids.end();++it) - info.friend_ids.push_back(*it) ; - - std::vector known_keys ; - std::vector probas ; - float maximum= 0.0f; - _routing_matrix.getListOfKnownKeys(known_keys) ; - - for(uint32_t i=0;i& infos) -{ - RS_STACK_MUTEX(grMtx) ; - - infos.clear() ; - - for(std::map::const_iterator it(_pending_messages.begin());it!=_pending_messages.end();++it) - { - GRouterRoutingCacheInfo cinfo ; - - cinfo.mid = it->first ; - cinfo.local_origin = it->second.incoming_routes.ids ; - cinfo.destination = it->second.data_item->destination_key ; - cinfo.duplication_factor = it->second.data_item->duplication_factor ; - cinfo.routing_time = it->second.received_time_TS ; - cinfo.last_tunnel_attempt_time = it->second.last_tunnel_request_TS ; - cinfo.last_sent_time = it->second.last_sent_TS ; - cinfo.receipt_available = (it->second.receipt_item != NULL); - cinfo.data_status = it->second.data_status ; - cinfo.tunnel_status = it->second.tunnel_status ; - cinfo.data_size = it->second.data_item->data_size ; - cinfo.item_hash = it->second.item_hash; - - infos.push_back(cinfo) ; - } - return true ; -} - -// Dump everything -// -void p3GRouter::debugDump() -{ - RS_STACK_MUTEX(grMtx) ; - - rstime_t now = time(NULL) ; - - grouter_debug() << "Full dump of Global Router state: " << std::endl; - grouter_debug() << " Owned keys : " << std::endl; - - for(std::map::const_iterator it(_owned_key_ids.begin());it!=_owned_key_ids.end();++it) - { - grouter_debug() << " Hash : " << it->first << std::endl; - grouter_debug() << " Key : " << it->second.authentication_key << std::endl; - grouter_debug() << " Service id : " << std::hex << it->second.service_id << std::dec << std::endl; - grouter_debug() << " Description : " << it->second.description_string << std::endl; - } - - grouter_debug() << " Registered services: " << std::endl; - - for(std::map::const_iterator it(_registered_services.begin() );it!=_registered_services.end();++it) - grouter_debug() << " " << std::hex << it->first << " " << std::dec << (void*)it->second << std::endl; - - grouter_debug() << " Data items: " << std::endl; - - static const std::string statusString[6] = { "Unkn","Pend","Sent","Receipt OK","Ongoing","Done" }; - - for(std::map::iterator it(_pending_messages.begin());it!=_pending_messages.end();++it) - { - grouter_debug() << " Msg id: " << std::hex << it->first << std::dec ; - grouter_debug() << " data hash: " << it->second.item_hash ; - grouter_debug() << " client: " << std::hex << it->second.client_id << std::dec; - grouter_debug() << " Flags: " << std::hex << it->second.routing_flags << std::dec; - grouter_debug() << " Dest: " << it->second.data_item->destination_key ; - grouter_debug() << " Recd: " << now - it->second.received_time_TS << " secs ago."; - grouter_debug() << " Sent: " << now - it->second.last_sent_TS << " secs ago."; - grouter_debug() << " Trans. TS: " << now - it->second.data_transaction_TS << " secs ago." ; - grouter_debug() << " Data Status: " << statusString[it->second.data_status] ; - grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] ; - grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) ; - grouter_debug() << " Dup: " << it->second.data_item->duplication_factor << std::endl; - } - - grouter_debug() << " Tunnels: " << std::endl; - - for(std::map::const_iterator it(_tunnels.begin());it!=_tunnels.end();++it) - { - grouter_debug() << " hash: " << it->first << ", first received: " << now - it->second.last_tunnel_ok_TS << " (secs ago), last received: " << now - it->second.last_tunnel_ok_TS << std::endl; - - for(std::set::const_iterator it2 = it->second.virtual_peers.begin();it2!=it->second.virtual_peers.end();++it2) - grouter_debug() << " " << (*it2) << std::endl; - } - - grouter_debug() << " Incoming data pipes: " << std::endl; - - for(std::map::const_iterator it(_incoming_data_pipes.begin());it!=_incoming_data_pipes.end();++it) - if(it->second.incoming_data_buffer != NULL) - grouter_debug() << " " << it->first << ": offset=" << it->second.incoming_data_buffer->chunk_start << " size=" << it->second.incoming_data_buffer->chunk_size << " over " << it->second.incoming_data_buffer->total_size << std::endl; - else - grouter_debug() << " " << it->first << " empty." << std::endl; - - grouter_debug() << " Routing matrix: " << std::endl; - - // if(_debug_enabled) - // _routing_matrix.debugDump() ; -} - - - - diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h deleted file mode 100644 index 236c8b7a5..000000000 --- a/libretroshare/src/grouter/p3grouter.h +++ /dev/null @@ -1,374 +0,0 @@ -/******************************************************************************* - * libretroshare/src/grouter: p3grouter.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "retroshare/rsgrouter.h" -#include "retroshare/rstypes.h" -#include "retroshare/rstypes.h" -#include "retroshare/rsidentity.h" - -#include "turtle/turtleclientservice.h" -#include "services/p3service.h" -#include "pqi/p3cfgmgr.h" -#include "util/rsdebug.h" -#include "groutertypes.h" -#include "groutermatrix.h" -#include "grouteritems.h" - -// To be put in pqi/p3cfgmgr.h -static const uint32_t CONFIG_TYPE_GROUTER = 0x0016 ; - -class p3LinkMgr ; -class p3turtle ; -class RsGixs ; -class RsGRouterItem ; -class RsGRouterGenericDataItem ; -class RsGRouterSignedReceiptItem ; -class RsGRouterAbstractMsgItem ; -class RsGRouterTransactionItem ; -class RsGRouterTransactionAcknItem ; - -// This class is responsible for accepting data chunks and merging them into a final object. When the object is -// complete, it is de-serialised and returned as a RsGRouterGenericDataItem*. - -class GRouterTunnelInfo -{ -public: - GRouterTunnelInfo() :first_tunnel_ok_TS(0), last_tunnel_ok_TS(0) {} - - // These two methods handle the memory management of buffers for each virtual peers. - - void addVirtualPeer(const TurtleVirtualPeerId& vpid) ; - void removeVirtualPeer(const TurtleVirtualPeerId& vpid) ; - - std::set virtual_peers ; - - rstime_t first_tunnel_ok_TS ; // timestamp when 1st tunnel was received. - rstime_t last_tunnel_ok_TS ; // timestamp when last tunnel was received. -}; -class GRouterDataInfo -{ - // ! This class does not have a copy constructor that duplicates the incoming data buffer. This is on purpose! -public: - GRouterDataInfo() : last_activity_TS(0) - { - incoming_data_buffer = NULL ; - } - - void clear() { if(incoming_data_buffer!=NULL) delete incoming_data_buffer ; incoming_data_buffer = NULL ;} - - // These two methods handle the memory management of buffers for each virtual peers. - - RsGRouterAbstractMsgItem *addDataChunk(RsGRouterTransactionChunkItem *chunk_item) ; - RsGRouterTransactionChunkItem *incoming_data_buffer ; - - rstime_t last_activity_TS ; -}; - -class p3GRouter: public RsGRouter, public RsTurtleClientService, public p3Service, public p3Config -{ -public: - p3GRouter(p3ServiceControl *sc,RsGixs *is) ; - - //===================================================// - // Router clients business // - //===================================================// - - // This method allows to associate client ids (that are saved to disk) to client objects deriving - // from GRouterClientService. The various services are responsible for regstering themselves to the - // global router, with consistent ids. The services are stored in a map, and arriving objects are - // passed on the correct service depending on the client id of the key they are reaching. - // - virtual bool registerClientService(const GRouterServiceId& id,GRouterClientService *service) ; - - // Use this method to register/unregister a key that the global router will - // forward in the network, so that is can be a possible destination for - // global messages. - // - // auth_id : The GXS key that will be used to sign the data Receipts. - // contact_key : The key that is used to open tunnels - // desc_str : Any fixed length string (< 20 characters) to descript the address in words. - // client_id : Id of the client service to send the traffic to. - // The client ID should match the ID that has been registered using the previous method. - // - // Unregistering a key might not have an instantaneous effect, so the client is responsible for - // discarding traffic that might later come for this key. - // - virtual bool registerKey(const RsGxsId& authentication_id, const GRouterServiceId& client_id,const std::string& description_string) ; - virtual bool unregisterKey(const RsGxsId &key_id, const GRouterServiceId &sid) ; - - //===================================================// - // Routing clue collection methods // - //===================================================// - - virtual void addRoutingClue( - const RsGxsId& id, const RsPeerId& peer_id) override; - - //===================================================// - // Client/server request services // - //===================================================// - - // Sends an item to the given destination. The router takes ownership of - // the memory. That means item_data will be erase on return. The returned id should be - // remembered by the client, so that he knows when the data has been received. - // The client id is supplied so that the client can be notified when the data has been received. - // Data is not modified by the global router. - // - virtual bool sendData(const RsGxsId& destination, const GRouterServiceId& client_id, const uint8_t *data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId& id) ; - - // Cancels a given sending order. If called too late, the message might already have left. But this will remove the item from the - // re-try list. - virtual bool cancel(GRouterMsgPropagationId mid) ; - - //===================================================// - // Interface with RsGRouter // - //===================================================// - - // debug info from routing matrix - // - list of known key ids - // - list of clues/time_stamp for each key. - // - real time routing probabilities - // - virtual bool getRoutingMatrixInfo(GRouterRoutingMatrixInfo& info) ; - - // debug info from routing cache - // - Cache Items - // * which message ids - // * directions - // * timestamp - // * message type - // - Cache state (memory size, etc) - // - virtual bool getRoutingCacheInfo(std::vector& info) ; - - //===================================================// - // Derived from p3Service // - //===================================================// - - virtual RsServiceInfo getServiceInfo() - { - return RsServiceInfo(RS_SERVICE_TYPE_GROUTER, - SERVICE_INFO_APP_NAME, - SERVICE_INFO_APP_MAJOR_VERSION, - SERVICE_INFO_APP_MINOR_VERSION, - SERVICE_INFO_MIN_MAJOR_VERSION, - SERVICE_INFO_MIN_MINOR_VERSION) ; - } - - virtual void setDebugEnabled(bool b) { _debug_enabled = b ; } - - virtual void connectToTurtleRouter(p3turtle *pt) ; - -protected: - //===================================================// - // Routing method handling // - //===================================================// - - // Calls - // - packet handling methods - // - matrix updates - // - virtual int tick() ; - - static const std::string SERVICE_INFO_APP_NAME ; - static const uint16_t SERVICE_INFO_APP_MAJOR_VERSION = 1; - static const uint16_t SERVICE_INFO_APP_MINOR_VERSION = 0; - static const uint16_t SERVICE_INFO_MIN_MAJOR_VERSION = 1; - static const uint16_t SERVICE_INFO_MIN_MINOR_VERSION = 0; - - //===================================================// - // Interaction with turtle router // - //===================================================// - - uint16_t serviceId() const { return RS_SERVICE_TYPE_GROUTER; } - virtual bool handleTunnelRequest(const RsFileHash& /*hash*/,const RsPeerId& /*peer_id*/) ; - virtual void receiveTurtleData(const RsTurtleGenericTunnelItem */*item*/,const RsFileHash& /*hash*/,const RsPeerId& /*virtual_peer_id*/,RsTurtleGenericTunnelItem::Direction /*direction*/); - virtual void addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) ; - virtual void removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) ; - -private: - //===================================================// - // Low level item sorting // - //===================================================// - - void handleLowLevelServiceItems() ; - void handleLowLevelServiceItem(RsGRouterTransactionItem*) ; - void handleLowLevelTransactionChunkItem(RsGRouterTransactionChunkItem *chunk_item); - void handleLowLevelTransactionAckItem(RsGRouterTransactionAcknItem*) ; - - static Sha1CheckSum computeDataItemHash(const RsGRouterGenericDataItem *data_item); - - std::ostream& grouter_debug() const - { - static std::ostream null(0); - return _debug_enabled?(std::cerr):null; - } - - void routePendingObjects() ; - void handleTunnels() ; - void autoWash() ; - - //===================================================// - // High level item sorting // - //===================================================// - - void handleIncoming() ; - - void handleIncomingItem(const RsGRouterAbstractMsgItem *item); - void handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *receipt_item) ; - void handleIncomingDataItem(const RsGRouterGenericDataItem *data_item) ; - - bool locked_getLocallyRegisteredClientFromServiceId(const GRouterServiceId& service_id,GRouterClientService *& client); - - // utility functions - // - static float computeMatrixContribution(float base,uint32_t time_shift,float probability) ; - static bool sliceDataItem(RsGRouterAbstractMsgItem *,std::list& chunks) ; - - uint32_t computeRandomDistanceIncrement(const RsPeerId& pid,const GRouterKeyId& destination_id) ; - - // signs an item with the given key. - bool signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& id) ; - bool verifySignedDataItem(const RsGRouterAbstractMsgItem *item, const RsIdentityUsage::UsageCode &info, uint32_t &error_status) ; - bool encryptDataItem(RsGRouterGenericDataItem *item,const RsGxsId& destination_key) ; - bool decryptDataItem(RsGRouterGenericDataItem *item) ; - - static Sha1CheckSum makeTunnelHash(const RsGxsId& destination,const GRouterServiceId& client); - - //bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id); - bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item); - - void locked_collectAvailableFriends(const GRouterKeyId &gxs_id, const std::set& incoming_routes,uint32_t duplication_factor, std::map &friend_peers_and_duplication_factors); - void locked_collectAvailableTunnels(const TurtleFileHash& hash, uint32_t total_duplication, std::map &tunnel_peers_and_duplication_factors); - void locked_sendToPeers(RsGRouterGenericDataItem *data_item, const std::map &peers_and_duplication_factors); - - //===================================================// - // p3Config methods // - //===================================================// - - // Load/save the routing info, the pending items in transit, and the config variables. - // - virtual bool loadList(std::list& items) ; - virtual bool saveList(bool& cleanup,std::list& items) ; - - virtual RsSerialiser *setupSerialiser() ; - - //===================================================// - // Debug methods // - //===================================================// - - // Prints the internal state of the router, for debug purpose. - // - void debugDump() ; - - //===================================================// - // Internal queues/variables // - //===================================================// - - // Stores the routing info - // - list of known key ids - // - list of clues/time_stamp for each key. - // - real time routing probabilities - // - GRouterMatrix _routing_matrix ; - - // Stores the keys which identify the router's node. For each key, a structure holds: - // - the client service - // - flags - // - usage time stamps - // - std::map _owned_key_ids ; - - // Registered services. These are known to the different peers with a common id, - // so it's important to keep consistency here. This map is volatile, and re-created at each startup of - // the software, when newly created services register themselves. - - std::map _registered_services ; - - // Stores the routing events. - // - ongoing requests, waiting for return ACK - // - pending items - // Both a stored in 2 different lists, to allow a more efficient handling. - // - std::map _pending_messages;// pending messages - - // Stores virtual peers that appear/disappear as the result of the turtle router client - // - std::map _tunnels ; - - // Stores incoming data from any peers (virtual and real) into chunks that get aggregated until finished. - // - std::map _incoming_data_pipes ; - - // Queue of incoming items. Might be receipts or data. Should always be empty (not a storage place) - std::list _incoming_items ; - - // Data handling methods - // - //void handleRecvDataItem(RsGRouterGenericDataItem *item); - //void handleRecvReceiptItem(RsGRouterReceiptItem *item); - - // Pointers to other RS objects - // - p3ServiceControl *mServiceControl ; - p3turtle *mTurtle ; - RsGixs *mGixs ; - //p3LinkMgr *mLinkMgr ; - - // Multi-thread protection mutex. - // - RsMutex grMtx ; - - // config update/save variables - bool _changed ; - bool _debug_enabled ; - - rstime_t _last_autowash_time ; - rstime_t _last_matrix_update_time ; - rstime_t _last_debug_output_time ; - rstime_t _last_config_changed ; - - uint64_t _random_salt ; - - /** Temporarly store items that could not have been verified yet due to - * missing author key, attempt to handle them once in a while. - * The items are discarded if after mMissingKeyQueueEntryTimeout the key - * hasn't been received yet, and are not saved on RetroShare stopping. */ - std::list< std::pair< - std::unique_ptr, rstime_t > > mMissingKeyQueue; - RsMutex mMissingKeyQueueMtx; /// protect mMissingKeyQueue - - /// @see mMissingKeyQueue - static constexpr rstime_t mMissingKeyQueueEntryTimeout = 600; - - /// @see mMissingKeyQueue - static constexpr rstime_t mMissingKeyQueueCheckEvery = 30; - - /// @see mMissingKeyQueue - rstime_t mMissingKeyQueueCheckLastCheck = 0; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/gxs/UseCases.txt b/libretroshare/src/gxs/UseCases.txt deleted file mode 100644 index 4ca721633..000000000 --- a/libretroshare/src/gxs/UseCases.txt +++ /dev/null @@ -1,341 +0,0 @@ - -These are some example usages of the GxsService... -All of these must be provided by the basic system. - -chris: -Please not all request* functions have a receive pair if not noted below - - -1) Forums ------------------------------------- -1.1) Display of subscribed forums. Service must provide: - 1.1.1) list of subscribed Groups. - ---------------- - int requestSubscribedGrps(); - - Component: - RsGnp::requestGroups() - - - ---------------- - 1.1.2) list of messages for each Group. - ---------------- - int requestGrpMsgs(std::list&); - ---------------- - - 1.1.3) details of group by group Id. - ---------------- - int requestGrp(std::list& grpIds); - ---------------- - - 1.1.4) details of messages by message Id. - ---------------- - int requestMsgs(std::list& msgs); - ---------------- - - 1.1.5) newest version of each message - - ---------------- - 1.1.4 : not intitialising RsGxsMsgId::version default to returning - newest version of message - ---------------- - - 1.1.6) status of message (read / unread). - - ---------------- - returned with msg data - int flagMsgRead(const RsGxsMsgId& msgId, bool read) - - ---------------- - - 1.1.7) access to Identity associated with Group and Messages - - ---------------- - returned with message - ---------------- - - 1.1.8) updates when new groups arrive. - - ---------------- - virtual void notifyGroupChanged(std::list grpId) = 0 - ---------------- - - 1.1.9) updates when new messages arrive. - ---------------- - virtual void notifyMsgChanged(std::list msgId) = 0 - ---------------- - - 1.1.10) updates when groups / messages change. - - ---------------- - 1.1.8 and 1.1.9 - ---------------- - - 1.1.11) Search forums for Keywords. - - ---------------- - int requestLocalSearch(RsGxsSearch* term); - ---------------- - - 1.1.12) Access new (time restricted) messages. - ---------------- - ? explain - ---------------- - -1.2) Creation of new material. - 1.2.1) ability to create Groups. - - ---------------- - int pushGrp(std::set& grp, std::string& profileName); - int pushGrp(std::set& grp, RsIdentityExchangeService::IdentityType type, const std::set& peers, - const std::string& pseudonymName = ""); - - ---------------- - - 1.2.2) ability to create Messages. - - void pushMsg(std::set& msg); - -1.3) Deletion of forums and posts. - 1.3.1) discard forum (can't do this currently). - ---------------- - done automatically by GDService based on cutoff - ---------------- - - 1.3.2) delete post. - ---------------- - // post is removed from system and note made in db not to syn it - // this is cleaned from db post expires - // very likely to also propagate to friends - int requestDeleteMsg(const RsGxsMsgId& msgId); - int requestDeleteGrp(const RsGxsGrpId& grpId); - ---------------- - - 1.3.3) discard old posts. - ---------------- - done automatically by GDService based on cutoff - ---------------- - -1.4) Control of Forums - - 1.4.1) Storage Period of subscribed forums - - ---------------- - void setSubscribedGroupDiscardAge(uint32_t length); - ---------------- - - 1.4.2) Storage Period of unsubscribed forums. - - ---------------- - void setUnsubscribedGrpDiscardAge(uint32_t length); - ---------------- - - 1.4.3) transfer unsubscribed forums and posts (yes/no) - - ---------------- - don't think I want this, definitely default false - int GXService::allUnsubscribedTransfer(bool) - ---------------- - - 1.4.4) modify forums we own. - - ---------------- - int GXService::updateGroup(multimap) - ---------------- - - ---------------- - int GXService::updateMsg(multimap) - ---------------- - - 1.4.5) modify read status. - - ---------------- - int flagMsgRead(const RsGxsMsgId& msgId, bool read) ; - ---------------- - 1.4.6) Subscribe to forums - - ---------------- - int requestSubscribeToGrp(const RsGxsGrpId& grpId, bool subscribe); - ---------------- - -1.5) Finding other forums. - 1.5.1) Listing of other forums. - int GXService::requestGroupList(); - void receiveGroupList(token, list); //call back - 1.5.2) ability to temporarily get forum messages. - ? Explain - 1.5.3) search remote forums for keywords. - ---------------- - // service will have to provide own search module (can RsGDService can - // service remote search requests concurrent with GXS) - // module return message and groups (msgs can be marked compile time as not // searchable - int requestRemoteSearch(RsGxsSearch* term, uint32_t hops); - - ---------------- - 1.5.4) optional download of friends forums. - ---------------- - int requestPeersGrps(const std::string& sslId); - ---------------- - - -2) Channels ------------------------------------- -2.1) Mostly like Forums, additional functionality. - 2.1.1) Download files associated with Post. - - ---------------- - ? Explain, This should not be part of interface, this is feature specific - ---------------- - -2.2) Comments - 2.2.1) Write a comment. - ---------------- - see 1.2.2. RsGxsMsg with required indirection data members - to associate with message the comment is being made on - ---------------- - - 2.2.2) Reject (downgrade) bad comment. - ---------------- - user needs to verify publisher sent downgrage message - bool RsGxis::bool verify(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature); - - ---------------- - - 2.2.3) Control Comments: Allow / Disallow, Pseudo / Authed Comments. - ---------------- - bool RsGxis::bool sign(const KeyRef& keyref, unsigned char* data, uint32_t dataLen, std::string& signature); - - ---------------- - - -3) Wiki ------------------------------------- -3.1) Editing functionality - 3.1.1) Access to Latest Version. - - ---------------- - Pls see 1.1.7 - ---------------- - - 3.1.2) Access to Version History. (including who edited). - - ---------------- - // need to include std::map as top level RsGxsMsg - ---------------- - - 3.2) Controlling Editing Rights. - - ---------------- - Pls see 1.1.7 - ---------------- - - - 3.2.1) Rejecting an Edit. - - ---------------- - using 1.2.2 publisher can send messages with private key signature that he does not accept edit 'x' - bool GXIService verify(Identity, data, dataLen, signature) - ---------------- - - 3.2.2) Changing Edit Rights. -using 1.2.2, publisher sends new publish key under old private key signature, and user uses - -3.3) Searching for Wikis. - 3.3.1) Search for keyword. - ---------------- - see 1.5.3 - ---------------- - - 3.3.2) Search for hashtag. - ---------------- - ? Explain, anything different from keyword - see 1.5.3 - ---------------- - - - 3.3.3) Search for pattern? - ---------------- - Bit more detail on search type - RsGxsSearch{ int searchType; const int PATTERN_TYPE, TERM_TYPE; ....} - - ---------------- - - -4) Wire (Twitter) ------------------------------------- -4.1) Following Friends. - 4.1.1) Adding Person. - - ---------------- - See 1.4.6 - ---------------- - - -4.2) Search The Wire. - 4.2.1) Search for friends. - 4.2.2) Search for hash tags. - 4.2.3) Search for keywords. - 4.2.4) Search for Retweets. - 4.2.5) Search for replies. - ---------------- - for 4.2.* see 3.3.1 - ---------------- - -5) PhotoShare. ------------------------------------- -5.1) Controlling Access. - 5.1.1) Friends Only. - - ---------------- - GXService::setShareGroup(grpId, group=RsGroups::GROUP_FRIENDS) - ---------------- - - 5.1.2) Groups Only. - - ---------------- - 5.1.1 - ---------------- - - 5.1.3) Everyone. - ---------------- - 5.1.1 GXService::setShareGroup(grpId, group=RsGroups::GROUP_ALL) - ---------------- - - 5.1.4) Deleting Photographs. - - ---------------- - 1.3.2 - ---------------- - - 5.1.4) Deleting Album. - ---------------- - 1.3.2 - ---------------- - -6) Acadeeb ------------------------------------- -6.1) Review Article. - 6.1.1) Write Review/Rate. - ---------------- - see 1.2.2 for sending message - ---------------- - - 6.1.2) Recommend Article. - ---------------- - see 1.2.2 for sending message - ---------------- - 6.1.3) Get Rating of Article. - ---------------- - See 3.2.1 and 2.2.2 - ---------------- - - -6.2) Submit Review of Article - 6.2.1) stuff. - 6.2.2) stuff. - - -7) Tracker. ------------------------------------- -7.1) Tracker Stuff. - diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc deleted file mode 100644 index 6798ee29c..000000000 --- a/libretroshare/src/gxs/gxssecurity.cc +++ /dev/null @@ -1,1191 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxssecurity.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2010 by Robert Fernie * - * 2011-2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "gxssecurity.h" -#include "pqi/authgpg.h" -#include "util/rsdir.h" -#include "util/rsmemory.h" -//#include "retroshare/rspeers.h" - -/**** - * #define GXS_SECURITY_DEBUG 1 - ***/ - -static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER = 0xFACE; -static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE = 2 ; -static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE = 2 ; -static const uint32_t MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE = 256 ; - -static RsGxsId getRsaKeyFingerprint_old_insecure_method(RSA *pubkey) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - int lenn = BN_num_bytes(pubkey -> n); - - RsTemporaryMemory tmp(lenn) ; - BN_bn2bin(pubkey -> n, tmp); -#else - const BIGNUM *nn=NULL,*ee=NULL ; - RSA_get0_key(pubkey,&nn,&ee,NULL) ; - - int lenn = BN_num_bytes(nn); - - RsTemporaryMemory tmp(lenn) ; - BN_bn2bin(nn, tmp); -#endif - - // Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent - // We should not be using strings here, but a real ID. To be done later. - - assert(lenn >= CERTSIGNLEN) ; - - return RsGxsId((unsigned char*)tmp) ; -} -static RsGxsId getRsaKeyFingerprint(RSA *pubkey) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - int lenn = BN_num_bytes(pubkey -> n); - int lene = BN_num_bytes(pubkey -> e); - - RsTemporaryMemory tmp(lenn+lene) ; - - BN_bn2bin(pubkey -> n, tmp); - BN_bn2bin(pubkey -> e, &tmp[lenn]); -#else - const BIGNUM *nn=NULL,*ee=NULL ; - RSA_get0_key(pubkey,&nn,&ee,NULL) ; - - int lenn = BN_num_bytes(nn); - int lene = BN_num_bytes(ee); - - RsTemporaryMemory tmp(lenn+lene) ; - - BN_bn2bin(nn, tmp); - BN_bn2bin(ee, &tmp[lenn]); -#endif - - Sha1CheckSum s = RsDirUtil::sha1sum(tmp,lenn+lene) ; - - // Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent - // We should not be using strings here, but a real ID. To be done later. - - assert(Sha1CheckSum::SIZE_IN_BYTES >= CERTSIGNLEN) ; - - return RsGxsId(s.toStdString().substr(0,2*CERTSIGNLEN)); -} - -static RSA *extractPrivateKey(const RsTlvPrivateRSAKey& key) -{ - assert(key.keyFlags & RSTLV_KEY_TYPE_FULL) ; - - const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; - long keylen = key.keyData.bin_len; - - /* extract admin key */ - RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen); - - return rsakey; -} - -static RSA *extractPublicKey(const RsTlvPublicRSAKey& key) -{ - assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - - const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; - long keylen = key.keyData.bin_len; - - /* extract admin key */ - RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); - - return rsakey; -} -static void setRSAPublicKeyData(RsTlvPublicRSAKey& key, RSA *rsa_pub) -{ - assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7 - int reqspace = i2d_RSAPublicKey(rsa_pub, &data); - - key.keyData.setBinData(data, reqspace); - key.keyId = getRsaKeyFingerprint(rsa_pub); - - free(data) ; -} - -static void setRSAPrivateKeyData(RsTlvPrivateRSAKey& key, RSA *rsa_priv) -{ - assert(key.keyFlags & RSTLV_KEY_TYPE_FULL) ; - - unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7 - int reqspace = i2d_RSAPrivateKey(rsa_priv, &data); - - key.keyData.setBinData(data, reqspace); - key.keyId = getRsaKeyFingerprint(rsa_priv); - - free(data) ; -} -bool GxsSecurity::checkFingerprint(const RsTlvPublicRSAKey& key) -{ - RSA *rsa_pub = ::extractPublicKey(key) ; - bool res = (key.keyId == getRsaKeyFingerprint(rsa_pub)) ; - RSA_free(rsa_pub) ; - return res ; -} - -bool GxsSecurity::checkPrivateKey(const RsTlvPrivateRSAKey& key) -{ -#ifdef GXS_SECURITY_DEBUG - std::cerr << "Checking private key " << key.keyId << " ..." << std::endl; -#endif - - if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_FULL) - { - std::cerr << "(WW) GxsSecurity::checkPrivateKey(): private key has wrong flags " << std::hex << (key.keyFlags & RSTLV_KEY_TYPE_MASK) << std::dec << ". This is unexpected." << std::endl; - return false ; - } - RSA *rsa_prv = ::extractPrivateKey(key) ; - - if(rsa_prv == NULL) - { - std::cerr << "(WW) GxsSecurity::checkPrivateKey(): no private key can be extracted from key ID " << key.keyId << ". Key is corrupted?" << std::endl; - return false ; - } - RSA *rsa_pub = RSAPublicKey_dup(rsa_prv); - RSA_free(rsa_prv) ; - - if(rsa_pub == NULL) - { - std::cerr << "(WW) GxsSecurity::checkPrivateKey(): no public key can be extracted from key ID " << key.keyId << ". Key is corrupted?" << std::endl; - return false ; - } - RsGxsId recomputed_key_id = getRsaKeyFingerprint(rsa_pub) ; - - if(recomputed_key_id != key.keyId) - { - if(key.keyId == getRsaKeyFingerprint_old_insecure_method(rsa_pub)) - { -#ifdef GXS_SECURITY_DEBUG - std::cerr << "(WW) fingerprint of key " << key.keyId << " was derived using old---insecure---format. It can be faked easily. You should get rid of this key!" << std::endl; -#endif - RSA_free(rsa_pub) ; - - // The policy is to *accept* these private keys, but the public key that corresponds will be rejected anyway, as it can easily be faked. - return true ; - } - else - { - std::cerr << "(WW) GxsSecurity::checkPrivateKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << std::endl; - - RSA_free(rsa_pub) ; - return false ; - } - } - - RSA_free(rsa_pub) ; - return true ; -} - -bool GxsSecurity::checkPublicKey(const RsTlvPublicRSAKey &key) -{ -#ifdef GXS_SECURITY_DEBUG - std::cerr << "Checking public key " << key.keyId << " ..." << std::endl; -#endif - - if( (key.keyFlags & RSTLV_KEY_TYPE_MASK) != RSTLV_KEY_TYPE_PUBLIC_ONLY) - { - std::cerr << "(WW) GxsSecurity::checkPublicKey(): public key has wrong flags " << std::hex << (key.keyFlags & RSTLV_KEY_TYPE_MASK) << std::dec << ". This is unexpected." << std::endl; - return false ; - } - - // try to extract private key - const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; - long keylen = key.keyData.bin_len; - RSA *rsa_prv = d2i_RSAPrivateKey(NULL, &(keyptr), keylen); - - if(rsa_prv != NULL) - { - std::cerr << "(SS) GxsSecurity::checkPublicKey(): public key with ID " << key.keyId << " actually is a Private key!!!" << std::endl; - RSA_free(rsa_prv) ; - return false ; - } - - RSA *rsa_pub = ::extractPublicKey(key) ; - - if(rsa_pub == NULL) - { - std::cerr << "(WW) GxsSecurity::checkPublicKey(): no public key can be extracted from key ID " << key.keyId << ". Key is corrupted?" << std::endl; - return false ; - } - RsGxsId recomputed_key_id = getRsaKeyFingerprint(rsa_pub) ; - - if(recomputed_key_id != key.keyId) - { - if(key.keyId == getRsaKeyFingerprint_old_insecure_method(rsa_pub)) - { -#ifdef GXS_SECURITY_DEBUG - std::cerr << "(WW) fingerprint was derived using old---insecure---format. It can be faked easily." << std::endl; -#endif - RSA_free(rsa_pub) ; - - // The policy is to accept these public keys, but warn the owner, since they might be fake keys. They will be soon rejected here, by replacing - // the return value by false. - return true ; - } - else - std::cerr << "(WW) GxsSecurity::checkPublicKey(): key " << key.keyId << " has wrong fingerprint " << recomputed_key_id << "! Key will be discarded." << std::endl; - - RSA_free(rsa_pub) ; - return false ; - } - - RSA_free(rsa_pub) ; - return true ; -} - -bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAKey& private_key) -{ - // admin keys - BIGNUM *ebn = BN_new(); - BN_set_word(ebn, 65537); - RSA *rsa = RSA_new(); - RSA_generate_key_ex(rsa, 2048, ebn, NULL); - RSA *rsa_pub = RSAPublicKey_dup(rsa); - - BN_clear_free(ebn) ; - - public_key.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY ; - private_key.keyFlags = RSTLV_KEY_TYPE_FULL ; - - setRSAPublicKeyData(public_key, rsa_pub); - setRSAPrivateKeyData(private_key, rsa); - - public_key.startTS = time(NULL); - public_key.endTS = public_key.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ - - private_key.startTS = public_key.startTS; - private_key.endTS = 0; /* no end */ - - // clean up - RSA_free(rsa); - RSA_free(rsa_pub); - - if(!(private_key.checkKey() && public_key.checkKey())) - { - std::cerr << "(EE) ERROR while generating keys. Something inconsistent in flags. This is probably a bad sign!" << std::endl; - return false ; - } - - return true ; -} - -bool GxsSecurity::extractPublicKey(const RsTlvPrivateRSAKey &private_key, RsTlvPublicRSAKey &public_key) -{ - public_key.TlvClear() ; - - if(!(private_key.keyFlags & RSTLV_KEY_TYPE_FULL)) - return false ; - - RSA *rsaPrivKey = extractPrivateKey(private_key); - - if(!rsaPrivKey) - return false ; - - RSA *rsaPubKey = RSAPublicKey_dup(rsaPrivKey); - RSA_free(rsaPrivKey); - - if(!rsaPubKey) - return false ; - - setRSAPublicKeyData(public_key, rsaPubKey); - RSA_free(rsaPubKey); - - public_key.keyFlags = private_key.keyFlags & (RSTLV_KEY_DISTRIB_MASK) ; // keep the distrib flags - public_key.keyFlags |= RSTLV_KEY_TYPE_PUBLIC_ONLY; - public_key.startTS = private_key.startTS ; - public_key.endTS = public_key.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ - - // This code fixes a problem of old RSA keys where the fingerprint wasn't computed using SHA1(n,e) but - // using the first bytes of n (ouuuuch!). Still, these keys are valid and should produce a correct - // fingerprint. So we replace the public key fingerprint (that is normally recomputed) with the FP of - // the private key. - - if(public_key.keyId != private_key.keyId) - { - std::cerr << std::endl; - std::cerr << "WARNING: GXS ID key pair " << private_key.keyId << " has inconsistent fingerprint. This is an old key " << std::endl; - std::cerr << " that is unsecure (can be faked easily). You should delete it!" << std::endl; - std::cerr << std::endl; - - public_key.keyId = private_key.keyId ; - } - - return true ; -} - -bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvPrivateRSAKey &privKey, RsTlvKeySignature& sign) -{ - RSA* rsa_priv = extractPrivateKey(privKey); - - if(!rsa_priv) - { - std::cerr << "GxsSecurity::getSignature(): Cannot create signature. Keydata is incomplete." << std::endl; - return false ; - } - EVP_PKEY *key_priv = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(key_priv, rsa_priv); - - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - bool ok = EVP_SignInit(mdctx, EVP_sha1()) == 1; - ok &= EVP_SignUpdate(mdctx, data, data_len) == 1; - - unsigned int siglen = EVP_PKEY_size(key_priv); - unsigned char sigbuf[siglen] ; - memset(sigbuf,0,siglen) ; - ok &= EVP_SignFinal(mdctx, sigbuf, &siglen, key_priv) == 1; - - // clean up - EVP_MD_CTX_destroy(mdctx); - EVP_PKEY_free(key_priv); - - sign.signData.setBinData(sigbuf, siglen); - sign.keyId = RsGxsId(privKey.keyId); - - return ok; -} - -bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const RsTlvPublicRSAKey &key, const RsTlvKeySignature& signature) -{ - assert(!(key.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - - RSA *rsakey = ::extractPublicKey(key) ; - - if(!rsakey) - { - std::cerr << "GxsSecurity::validateSignature(): Cannot validate signature. Keydata is incomplete." << std::endl; - key.print(std::cerr,0) ; - return false ; - } - EVP_PKEY *signKey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(signKey, rsakey); - - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - EVP_VerifyInit(mdctx, EVP_sha1()); - EVP_VerifyUpdate(mdctx, data, data_len); - - int signOk = EVP_VerifyFinal(mdctx, (unsigned char*)signature.signData.bin_data, signature.signData.bin_len, signKey); - - /* clean up */ - EVP_PKEY_free(signKey); - EVP_MD_CTX_destroy(mdctx); - - return signOk; -} - -bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey& key) -{ - #ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg()"; - std::cerr << std::endl; - std::cerr << "RsNxsMsg :"; - std::cerr << std::endl; - const_cast(&msg)->print(std::cerr, 10); - std::cerr << std::endl; - #endif - - RsGxsMsgMetaData& msgMeta = *(msg.metaData); - - // /********************* check signature *******************/ - - /* check signature timeperiod */ - if(msgMeta.mPublishTs < key.startTS) - { - RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId - << " The signed message has an inconsistent msg publish time of " << msgMeta.mPublishTs - << " whereas the signing key was created later at TS " << key.startTS - << ". Validation rejected for security. If you see this, something irregular is going on." << std::endl; - return false; - } - - if(key.endTS != 0 && msgMeta.mPublishTs > key.endTS) - { - RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId - << " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs - << " The validation still passes, but that key should be renewed." << std::endl; - - // no return here. We still proceed checking the signature. - } - - /* decode key */ - const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; - long keylen = key.keyData.bin_len; - unsigned int siglen = sign.signData.bin_len; - unsigned char *sigbuf = (unsigned char *) sign.signData.bin_data; - - #ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg() Decode Key"; - std::cerr << " keylen: " << keylen << " siglen: " << siglen; - std::cerr << std::endl; - #endif - - /* extract admin key */ - - RSA *rsakey = (key.keyFlags & RSTLV_KEY_TYPE_FULL)? (d2i_RSAPrivateKey(NULL, &(keyptr), keylen)) : (d2i_RSAPublicKey(NULL, &(keyptr), keylen)); - - if (!rsakey) - { - #ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg()"; - std::cerr << " Invalid RSA Key"; - std::cerr << std::endl; - - key.print(std::cerr, 10); - #endif - } - - - RsTlvKeySignatureSet signSet = msgMeta.signSet; - msgMeta.signSet.TlvClear(); - - RsGxsMessageId msgId = msgMeta.mMsgId, origMsgId = msgMeta.mOrigMsgId; - - if(msgMeta.mOrigMsgId == msgMeta.mMsgId) // message is not versionned, then the signature was made with mOrigMsgId==NULL - msgMeta.mOrigMsgId.clear(); - - msgMeta.mMsgId.clear(); - - int signOk = 0 ; - - { - EVP_PKEY *signKey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(signKey, rsakey); - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - uint32_t metaDataLen = msgMeta.serial_size(); - uint32_t allMsgDataLen = metaDataLen + msg.msg.bin_len; - - RsTemporaryMemory metaData(metaDataLen) ; - RsTemporaryMemory allMsgData(allMsgDataLen) ; - - if(!metaData || !allMsgData) - return false ; - - msgMeta.serialise(metaData, &metaDataLen); - - // copy msg data and meta in allmsgData buffer - memcpy(allMsgData, msg.msg.bin_data, msg.msg.bin_len); - memcpy(allMsgData+(msg.msg.bin_len), metaData, metaDataLen); - - /* calc and check signature */ - - EVP_VerifyInit(mdctx, EVP_sha1()); - EVP_VerifyUpdate(mdctx, allMsgData, allMsgDataLen); - - signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); - - /* clean up */ - EVP_PKEY_free(signKey); - EVP_MD_CTX_destroy(mdctx); - } - - msgMeta.mOrigMsgId = origMsgId; - msgMeta.mMsgId = msgId; - msgMeta.signSet = signSet; - - if (signOk == 1) - { - #ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg() Signature OK"; - std::cerr << std::endl; - #endif - return true; - } - - #ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg() Signature invalid"; - std::cerr << std::endl; - #endif - - return false; -} - -bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPublicRSAKey& key) -{ -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::encrypt() " << std::endl; -#endif - // Encrypts (in,inlen) into (out,outlen) using the given RSA public key. - // The format of the encrypted data is: - // - // [--- Encrypted session key length ---|--- Encrypted session key ---|--- IV ---|---- Encrypted data ---] - // - - out = NULL ; - - RSA *tmpkey = ::extractPublicKey(key) ; - RSA *rsa_publish_pub = RSAPublicKey_dup(tmpkey) ; - RSA_free(tmpkey) ; - - EVP_PKEY *public_key = NULL; - - //RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); - //rsa_publish_pub = RSAPublicKey_dup(rsa_publish); - - - if(rsa_publish_pub != NULL) - { - public_key = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(public_key, rsa_publish_pub); - } - else - { -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity(): Could not generate publish key " << grpId - << std::endl; -#endif - return false; - } - - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - int eklen, net_ekl; - unsigned char *ek; - unsigned char iv[EVP_MAX_IV_LENGTH]; - int out_currOffset = 0; - int out_offset = 0; - - int max_evp_key_size = EVP_PKEY_size(public_key); - ek = (unsigned char*)rs_malloc(max_evp_key_size); - - if(ek == NULL) - return false ; - - const EVP_CIPHER *cipher = EVP_aes_128_cbc(); - int cipher_block_size = EVP_CIPHER_block_size(cipher); - int size_net_ekl = sizeof(net_ekl); - - int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl; - - // intialize context and send store encrypted cipher in ek - if(!EVP_SealInit(ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) return false; - - EVP_PKEY_free(public_key) ; - - // now assign memory to out accounting for data, and cipher block size, key length, and key length val - out = (uint8_t*)rs_malloc(inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH) ; - - if (out == NULL) - return false; - - net_ekl = htonl(eklen); - memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl); - out_offset += size_net_ekl; - - memcpy((unsigned char*)out + out_offset, ek, eklen); - out_offset += eklen; - - memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); - out_offset += EVP_MAX_IV_LENGTH; - - // now encrypt actual data - if(!EVP_SealUpdate(ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) - { - free(out) ; - out = NULL ; - return false; - } - - // move along to partial block space - out_offset += out_currOffset; - - // add padding - if(!EVP_SealFinal(ctx, (unsigned char*) out + out_offset, &out_currOffset)) - { - free(out) ; - out = NULL ; - return false; - } - - // move to end - out_offset += out_currOffset; - - // make sure offset has not gone passed valid memory bounds - if(out_offset > max_outlen) - { - free(out) ; - out = NULL ; - return false; - } - - // free encrypted key data - free(ek); - - EVP_CIPHER_CTX_free(ctx); - - outlen = out_offset; - return true; -} - -bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector &keys) -{ -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::encrypt() " << std::endl; -#endif - // Encrypts (in,inlen) into (out,outlen) using the given RSA public key. - // The format of the encrypted data is: - // - // [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---] - // 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet - // - - out = NULL ; - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - std::vector public_keys(keys.size(),NULL); - - try - { - if(keys.empty()) - throw std::runtime_error("EVP_SealInit will not be called with 0 keys. GxsSecurity::encrypt() was called with an empty set of destination keys!") ; - - for(uint32_t i=0;i ek(keys.size(),NULL) ; - std::vector eklen(keys.size(),0) ; - - for(uint32_t i=0;i> 8) & 0xff ; - - // number of keys - - out[out_offset++] = keys.size() & 0xff ; - out[out_offset++] = (keys.size() >> 8) & 0xff ; - - // encrypted keys, each preceeded with its length - - for(uint32_t i=0;i max_outlen) - throw std::runtime_error("Memory used by encryption exceeds allocated memory block") ; - - // free encrypted key data - - for(uint32_t i=0;i 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); - return false; - } - - memcpy(ek, (unsigned char*)in + in_offset, eklen); - in_offset += eklen; - - memcpy(iv, (unsigned char*)in + in_offset, EVP_MAX_IV_LENGTH); - in_offset += EVP_MAX_IV_LENGTH; - - const EVP_CIPHER* cipher = EVP_aes_128_cbc(); - - if(!EVP_OpenInit(ctx, cipher, ek, eklen, iv, privateKey)) - { - std::cerr << "(EE) Cannot decrypt data. Most likely reason: private GXS key is missing." << std::endl; - return false; - } - EVP_PKEY_free(privateKey) ; - - if(inlen < (uint32_t)in_offset) - { - std::cerr << "Severe error in " << __PRETTY_FUNCTION__ << ": cannot encrypt. " << std::endl; - return false ; - } - out = (uint8_t*)rs_malloc(inlen - in_offset); - - if(out == NULL) - return false; - - if(!EVP_OpenUpdate(ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + in_offset, inlen - in_offset)) - { - free(out) ; - out = NULL ; - return false; - } - - outlen = out_currOffset; - - if(!EVP_OpenFinal(ctx, (unsigned char*)out + out_currOffset, &out_currOffset)) - { - free(out) ; - out = NULL ; - return false; - } - - outlen += out_currOffset; - free(ek); - - EVP_CIPHER_CTX_free(ctx); - return true; -} - -bool GxsSecurity::decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector &keys) -{ - // Decrypts (in,inlen) into (out,outlen) using one of the given RSA public keys, trying them all in a row. - // The format of the encrypted data is: - // - // [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---] - // 2 bytes 2 byte = n 256 bytes EVP_MAX_IV_LENGTH Rest of packet - // - // This method can be used to decrypt multi-encrypted data, if passing he correct encrypted key block (corresponding to the given key) - -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::decrypt() " << std::endl; -#endif - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - - try - { - out = NULL ; - - // check that the input block has a valid format. - - uint32_t offset = 0 ; - uint16_t format_id = in[offset] + (in[offset+1] << 8) ; - - if(format_id != MULTI_ENCRYPTION_FORMAT_v001_HEADER) - { - std::cerr << "Unrecognised format in encrypted block. Header id = " << std::hex << format_id << std::dec << std::endl; - throw std::runtime_error("Unrecognised format in encrypted block.") ; - } - offset += MULTI_ENCRYPTION_FORMAT_v001_HEADER_SIZE; - - // read number of encrypted keys - - uint32_t number_of_keys = in[offset] + (in[offset+1] << 8) ; - offset += MULTI_ENCRYPTION_FORMAT_v001_NUMBER_OF_KEYS_SIZE; - - // reach the actual data offset - - uint32_t encrypted_keys_offset = offset ; - uint32_t encrypted_block_size = 0 ; - - uint32_t IV_offset = offset + number_of_keys * MULTI_ENCRYPTION_FORMAT_v001_ENCRYPTED_KEY_SIZE ; - uint32_t encrypted_block_offset = IV_offset + EVP_MAX_IV_LENGTH ; - - // read IV offset - - if(encrypted_block_offset >= inlen) - throw std::runtime_error("Offset error") ; - - encrypted_block_size = inlen - encrypted_block_offset ; -#ifdef GXS_SECURITY_DEBUG - std::cerr << " number of keys in envelop: " << number_of_keys << std::endl; - std::cerr << " IV offset : " << IV_offset << std::endl; - std::cerr << " encrypted block offset : " << encrypted_block_offset << std::endl; - std::cerr << " encrypted block size : " << encrypted_block_size << std::endl; -#endif - - // decrypt - - bool succeed = false; - - for(uint32_t j=0;j(&grp)->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - RsGxsGrpMetaData& grpMeta = *(grp.metaData); - - /********************* check signature *******************/ - - /* check signature timeperiod */ - if (grpMeta.mPublishTs < key.startTS) - { - RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsGrp() TS out of range for admin/publish key of group " << grpMeta.mGroupId - << " The signed group has an inconsistent creation/modification time of " << grpMeta.mPublishTs - << " whereas the key was created later at TS " << key.startTS - << ". Validation rejected for security. If you see this, something irregular is going on." << std::endl; - return false; - } - if (key.endTS != 0 && grpMeta.mPublishTs > key.endTS) - { - RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for admin/publish key for group " << grpMeta.mGroupId - << " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << grpMeta.mPublishTs - << " The validation still passes, but that key should be renewed." << std::endl; - - // no return. Still proceed checking signature. - } - - /* decode key */ - const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; - long keylen = key.keyData.bin_len; - unsigned int siglen = sign.signData.bin_len; - unsigned char *sigbuf = (unsigned char *) sign.signData.bin_data; - -#ifdef DISTRIB_DEBUG - std::cerr << "GxsSecurity::validateNxsMsg() Decode Key"; - std::cerr << " keylen: " << keylen << " siglen: " << siglen; - std::cerr << std::endl; -#endif - - /* extract admin key */ - RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); - - if (!rsakey) - { -#ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsGrp()"; - std::cerr << " Invalid RSA Key"; - std::cerr << std::endl; - - key.print(std::cerr, 10); -#endif - } - - std::vector api_versions_to_check ; - api_versions_to_check.push_back(RS_GXS_GRP_META_DATA_VERSION_ID_0002) ; // put newest first, for debug info purpose - api_versions_to_check.push_back(RS_GXS_GRP_META_DATA_VERSION_ID_0001) ; - - RsTlvKeySignatureSet signSet = grpMeta.signSet; - grpMeta.signSet.TlvClear(); - - int signOk =0; - EVP_PKEY *signKey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(signKey, rsakey); - - - for(uint32_t i=0;i0) - std::cerr << "(WW) Checking group signature with old api version " << i+1 << " : tag " << std::hex << api_versions_to_check[i] << std::dec << " result: " << signOk << std::endl; -#endif - } - - /* clean up */ - EVP_PKEY_free(signKey); - - // restore data - - grpMeta.signSet = signSet; - - if (signOk == 1) - { -#ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsGrp() Signature OK"; - std::cerr << std::endl; -#endif - return true; - } - -#ifdef GXS_SECURITY_DEBUG - std::cerr << "GxsSecurity::validateNxsGrp() Signature invalid"; - std::cerr << std::endl; -#endif - - return false; -} - -void GxsSecurity::createPublicKeysFromPrivateKeys(RsTlvSecurityKeySet& keyset) -{ - for( std::map::const_iterator it = keyset.private_keys.begin(); it != keyset.private_keys.end() ; ++it) - if(keyset.public_keys.find(it->second.keyId) == keyset.public_keys.end()) - { - RsTlvPublicRSAKey pub_key ; - - if(!extractPublicKey(it->second,pub_key)) - { - std::cerr << "(EE) ERROR when trying to generate public key from private key for ID " << it->second.keyId << ". This is probably a bug with security implications." << std::endl; - continue ; - } - - keyset.public_keys[it->second.keyId] = pub_key ; - - std::cerr << "(II) Generated missing public key for ID " << it->second.keyId << " from private key." << std::endl; - } -} diff --git a/libretroshare/src/gxs/gxssecurity.h b/libretroshare/src/gxs/gxssecurity.h deleted file mode 100644 index 7b607c916..000000000 --- a/libretroshare/src/gxs/gxssecurity.h +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxssecurity.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2010 by Robert Fernie * - * 2011-2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef GXSSECURITY_H -#define GXSSECURITY_H - -#include "serialiser/rstlvkeys.h" - -#include "rsitems/rsnxsitems.h" - -#include -#include - - -/*! - * This contains functionality for performing basic security operations needed - * in RsGenExchange operations. - * Also has routine for creating security objects around msgs and groups - * TODO: Those functions doesn't do param checking! - */ -class GxsSecurity -{ - public: - /*! - * Extracts a public key from a private key. - */ - static bool extractPublicKey(const RsTlvPrivateRSAKey& private_key,RsTlvPublicRSAKey& public_key) ; - - /*! - * Generates a public/private RSA keypair. To be used for all GXS purposes. - * @param RsTlvSecurityKey public RSA key - * @param RsTlvSecurityKey private RSA key - * @return true if the generate was successful, false otherwise. - */ - static bool generateKeyPair(RsTlvPublicRSAKey &public_key, RsTlvPrivateRSAKey &private_key) ; - - /*! - * Encrypts data using envelope encryption (taken from open ssl's evp_sealinit ) - * only full publish key holders can encrypt data for given group - *@param out - *@param outlen - *@param in - *@param inlen - */ - static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPublicRSAKey& key) ; - static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector& keys) ; - - /** - * Decrypts data using evelope decryption (taken from open ssl's evp_sealinit ) - * only full publish key holders can decrypt data for a group - * @param out where decrypted data is written to - * @param outlen - * @param in - * @param inlen - * @return false if encryption failed - */ - static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvPrivateRSAKey& key) ; - static bool decrypt(uint8_t *& out, uint32_t & outlen, const uint8_t *in, uint32_t inlen, const std::vector& keys); - - /*! - * uses grp signature to check if group has been - * tampered with - * @param newGrp the Nxs group to be validated - * @param sign the signature to validdate against - * @param key the public key to use to check signature - * @return true if group valid false otherwise - */ - static bool validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey& key); - - /*! - * Validate a msg's signature using the given public key - * @param msg the Nxs message to be validated - * @param sign the signature to validdate against - * @param key the public key to use to check signature - * @return false if verfication of signature is not passed - */ - static bool validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& sign, const RsTlvPublicRSAKey &key); - - - /*! - * @param data data to be signed - * @param data_len length of data to be signed - * @param privKey private key to used to make signature - * @param sign the signature is stored here - * @return false if signature creation failed, true is signature created - */ - static bool getSignature(const char *data, uint32_t data_len, const RsTlvPrivateRSAKey& privKey, RsTlvKeySignature& sign); - - /*! - * @param data data that has been signed - * @param data_len length of signed data - * @param privKey public key to used to check signature - * @param sign Signature for the data - * @return true if signature checks - */ - static bool validateSignature(const char *data, uint32_t data_len, const RsTlvPublicRSAKey& pubKey, const RsTlvKeySignature& sign); - - /*! - * Checks that the public key has correct fingerprint and correct flags. - * @brief checkPublicKey - * @param key - * @return false if the key is invalid. - */ - - static bool checkPublicKey(const RsTlvPublicRSAKey &key); - static bool checkPrivateKey(const RsTlvPrivateRSAKey &key); - static bool checkFingerprint(const RsTlvPublicRSAKey& key); // helper function to only check the fingerprint - - /*! - * Adds possibly missing public keys when private keys are present. - * - * \brief createPublicKeysForPrivateKeys - * \param set set of keys to consider - * \return - */ - static void createPublicKeysFromPrivateKeys(RsTlvSecurityKeySet& set) ; -}; - -#endif // GXSSECURITY_H diff --git a/libretroshare/src/gxs/gxstokenqueue.cc b/libretroshare/src/gxs/gxstokenqueue.cc deleted file mode 100644 index 227ea33fc..000000000 --- a/libretroshare/src/gxs/gxstokenqueue.cc +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxstokenqueue.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "gxs/gxstokenqueue.h" - -/******* - * #define GXS_DEBUG 1 - ******/ - -bool GxsTokenQueue::queueRequest(uint32_t token, uint32_t req_type) -{ - RS_STACK_MUTEX(mQueueMtx); - mQueue.push_back(GxsTokenQueueItem(token, req_type)); - return true; -} - - -void GxsTokenQueue::checkRequests() -{ - { - RS_STACK_MUTEX(mQueueMtx); - if (mQueue.empty()) return; - } - - // Must check all, and move to a different list - for reentrant / good mutex behaviour. - std::list toload; - std::list::iterator it; - bool stuffToLoad = false; - - { - RS_STACK_MUTEX(mQueueMtx); - for(it = mQueue.begin(); it != mQueue.end();) - { - uint32_t token = it->mToken; - it->mStatus = mGenExchange->getTokenService()->requestStatus(token); - - if ( it->mStatus == RsTokenService::COMPLETE - || it->mStatus == RsTokenService::CANCELLED ) - { - toload.push_back(*it); - it = mQueue.erase(it); - stuffToLoad = true; - -#ifdef GXS_DEBUG - std::cerr << "GxsTokenQueue::checkRequests() token: " << token - << " Complete" << std::endl; -#endif - ++it; - } - else if (it->mStatus == RsTokenService::FAILED) - { - // maybe we should do alternative callback? - std::cerr << __PRETTY_FUNCTION__ << " ERROR Request Failed! " - << " token: " << token << std::endl; - - it = mQueue.erase(it); - } - else - { -#ifdef GXS_DEBUG - std::cerr << "GxsTokenQueue::checkRequests() token: " << token - << " is unfinished, status: " << status << std::endl; -#endif - ++it; - } - } - } // RS_STACK_MUTEX(mQueueMtx) END - - if (stuffToLoad) - { - for(it = toload.begin(); it != toload.end(); ++it) - { - handleResponse(it->mToken, it->mReqType, it->mStatus); - } - } -} - diff --git a/libretroshare/src/gxs/gxstokenqueue.h b/libretroshare/src/gxs/gxstokenqueue.h deleted file mode 100644 index e4445c44a..000000000 --- a/libretroshare/src/gxs/gxstokenqueue.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxstokenqueue.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef R_GXS_TOKEN_QUEUE_H -#define R_GXS_TOKEN_QUEUE_H - -#include "gxs/rsgenexchange.h" -#include "retroshare/rsservicecontrol.h" -#include "util/rsthreads.h" - - -struct GxsTokenQueueItem -{ -public: - - GxsTokenQueueItem(const uint32_t token, const uint32_t req_type) : - mToken(token), mReqType(req_type), mStatus(RsTokenService::PENDING) {} - - GxsTokenQueueItem(): mToken(0), mReqType(0), mStatus(RsTokenService::PENDING) {} - - uint32_t mToken; - uint32_t mReqType; - RsTokenService::GxsRequestStatus mStatus; -}; - - -/** - * A little helper class, to manage callbacks from requests - */ -class GxsTokenQueue -{ -public: - explicit GxsTokenQueue(RsGenExchange *gxs) : - mGenExchange(gxs), mQueueMtx("GxsTokenQueueMtx") {} - - bool queueRequest(uint32_t token, uint32_t req_type); - void checkRequests(); /// must be called by - -protected: - - /// This must be overloaded to complete the functionality. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) = 0; - -private: - RsGenExchange *mGenExchange; - RsMutex mQueueMtx; - std::list mQueue; -}; - - -#endif //R_GXS_TOKEN_QUEUE_H diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc deleted file mode 100644 index b0415a9f6..000000000 --- a/libretroshare/src/gxs/rsdataservice.cc +++ /dev/null @@ -1,1780 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxsdataservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/***** - * #define RS_DATA_SERVICE_DEBUG 1 - * #define RS_DATA_SERVICE_DEBUG_TIME 1 - * #define RS_DATA_SERVICE_DEBUG_CACHE 1 - ****/ - -#include -#include -#include - -#ifdef RS_DATA_SERVICE_DEBUG_TIME -#include -#endif - -#include "rsdataservice.h" -#include "retroshare/rsgxsflags.h" -#include "util/rsstring.h" - -#define MSG_TABLE_NAME std::string("MESSAGES") -#define GRP_TABLE_NAME std::string("GROUPS") -#define DATABASE_RELEASE_TABLE_NAME std::string("DATABASE_RELEASE") - -#define GRP_LAST_POST_UPDATE_TRIGGER std::string("LAST_POST_UPDATE") - -#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_SERV_STRING std::string("serv_str") -#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") -#define KEY_NXS_FILE_OFFSET_OLD std::string("fileOffset") -#define KEY_NXS_FILE_LEN_OLD std::string("nxsFileLen") - -// grp table columns -#define KEY_KEY_SET std::string("keySet") -#define KEY_GRP_NAME std::string("grpName") -#define KEY_GRP_SIGN_FLAGS std::string("signFlags") -#define KEY_GRP_CIRCLE_ID std::string("circleId") -#define KEY_GRP_CIRCLE_TYPE std::string("circleType") -#define KEY_GRP_INTERNAL_CIRCLE std::string("internalCircle") -#define KEY_GRP_ORIGINATOR std::string("originator") -#define KEY_GRP_AUTHEN_FLAGS std::string("authenFlags") - -// grp local -#define KEY_GRP_SUBCR_FLAG std::string("subscribeFlag") -#define KEY_GRP_POP std::string("popularity") -#define KEY_MSG_COUNT std::string("msgCount") -#define KEY_GRP_STATUS std::string("grpStatus") -#define KEY_GRP_LAST_POST std::string("lastPost") -#define KEY_GRP_REP_CUTOFF std::string("rep_cutoff") - -// msg table columns -#define KEY_MSG_ID std::string("msgId") -#define KEY_ORIG_MSG_ID std::string("origMsgId") -#define KEY_MSG_PARENT_ID std::string("parentId") -#define KEY_MSG_THREAD_ID std::string("threadId") -#define KEY_MSG_NAME std::string("msgName") - -// msg local -#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") -#define KEY_DATABASE_RELEASE_ID_VALUE 1 -#define KEY_DATABASE_RELEASE std::string("release") - -const std::string RsGeneralDataService::GRP_META_SERV_STRING = KEY_NXS_SERV_STRING; -const std::string RsGeneralDataService::GRP_META_STATUS = KEY_GRP_STATUS; -const std::string RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG = KEY_GRP_SUBCR_FLAG; -const std::string RsGeneralDataService::GRP_META_CUTOFF_LEVEL = KEY_GRP_REP_CUTOFF; - -const std::string RsGeneralDataService::MSG_META_SERV_STRING = KEY_NXS_SERV_STRING; -const std::string RsGeneralDataService::MSG_META_STATUS = KEY_MSG_STATUS; - -const uint32_t RsGeneralDataService::GXS_MAX_ITEM_SIZE = 1572864; // 1.5 Mbytes - -static int addColumn(std::list &list, const std::string &attribute) -{ - list.push_back(attribute); - return list.size() - 1; -} - -RsDataService::RsDataService(const std::string &serviceDir, const std::string &dbName, uint16_t serviceType, - RsGxsSearchModule * /* mod */, const std::string& key) - : RsGeneralDataService(), mDbMutex("RsDataService"), mServiceDir(serviceDir), mDbName(dbName), mDbPath(mServiceDir + "/" + dbName), mServType(serviceType), mDb(NULL) -{ - bool isNewDatabase = !RsDirUtil::fileExists(mDbPath); - - mDb = new RetroDb(mDbPath, RetroDb::OPEN_READWRITE_CREATE, key); - mUseCache = true; - - 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_NxsServString = addColumn(mMsgMetaColumns, KEY_NXS_SERV_STRING); - 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); - mColMsg_NxsData = addColumn(mMsgColumns, KEY_NXS_DATA); - 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_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_InternCircle = addColumn(mGrpMetaColumns, KEY_GRP_INTERNAL_CIRCLE); - 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); - - // 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); - - // Msg id columns - mColMsgId_MsgId = addColumn(mMsgIdColumn, KEY_MSG_ID); -} - -RsDataService::~RsDataService(){ - -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::~RsDataService()"; - std::cerr << std::endl; -#endif - - mDb->closeDb(); - delete mDb; -} - -static bool moveDataFromFileToDatabase(RetroDb *db, const std::string serviceDir, const std::string &tableName, const std::string &keyId, std::list &files) -{ - bool ok = true; - - // Move message data - std::list columns; - columns.push_back(keyId); - columns.push_back(KEY_NXS_FILE_OLD); - columns.push_back(KEY_NXS_FILE_OFFSET_OLD); - columns.push_back(KEY_NXS_FILE_LEN_OLD); - - RetroCursor* c = db->sqlQuery(tableName, columns, "", ""); - - if (c) - { - bool valid = c->moveToFirst(); - - while (ok && valid){ - std::string dataFile; - c->getString(1, dataFile); - - if (!dataFile.empty()) { - bool fileOk = true; - - // first try to find the file in the service dir - if (RsDirUtil::fileExists(serviceDir + "/" + dataFile)) { - dataFile.insert(0, serviceDir + "/"); - } else if (RsDirUtil::fileExists(dataFile)) { - // use old way for backward compatibility - //TODO: can be removed later - } else { - fileOk = false; - - std::cerr << "moveDataFromFileToDatabase() cannot find file " << dataFile; - std::cerr << std::endl; - } - - if (fileOk) { - std::string id; - c->getString(0, id); - - uint32_t offset = c->getInt32(2); - uint32_t data_len = c->getInt32(3); - - char* data = new char[data_len]; - std::ifstream istrm(dataFile.c_str(), std::ios::binary); - istrm.seekg(offset, std::ios::beg); - istrm.read(data, data_len); - istrm.close(); - - ContentValue cv; - // insert new columns - cv.put(KEY_NXS_DATA, data_len, data); - cv.put(KEY_NXS_DATA_LEN, (int32_t) data_len); - // clear old columns - cv.put(KEY_NXS_FILE_OLD, ""); - cv.put(KEY_NXS_FILE_OFFSET_OLD, 0); - cv.put(KEY_NXS_FILE_LEN_OLD, 0); - - ok = db->sqlUpdate(tableName, keyId + "='" + id + "'", cv); - delete[] data; - - if (std::find(files.begin(), files.end(), dataFile) == files.end()) { - files.push_back(dataFile); - } - } - } - - valid = c->moveToNext(); - } - - delete c; - } - - return ok; -} - -void RsDataService::initialise(bool isNewDatabase) -{ - const int databaseRelease = 1; - int currentDatabaseRelease = 0; - bool ok = true; - - RsStackMutex stack(mDbMutex); - - // initialise database - - if (isNewDatabase || !mDb->tableExists(DATABASE_RELEASE_TABLE_NAME)) { - // create table for database release - mDb->execSQL("CREATE TABLE " + DATABASE_RELEASE_TABLE_NAME + "(" + - KEY_DATABASE_RELEASE_ID + " INT PRIMARY KEY," + - KEY_DATABASE_RELEASE + " INT);"); - } - - if (isNewDatabase) { - // create table for msg data - mDb->execSQL("CREATE TABLE " + MSG_TABLE_NAME + "(" + - KEY_MSG_ID + " TEXT PRIMARY KEY," + - KEY_GRP_ID + " TEXT," + - KEY_NXS_FLAGS + " INT," + - KEY_ORIG_MSG_ID + " TEXT," + - KEY_TIME_STAMP + " INT," + - KEY_NXS_IDENTITY + " TEXT," + - KEY_SIGN_SET + " BLOB," + - KEY_NXS_DATA + " BLOB,"+ - KEY_NXS_DATA_LEN + " INT," + - KEY_MSG_STATUS + " INT," + - KEY_CHILD_TS + " INT," + - KEY_NXS_META + " BLOB," + - KEY_MSG_THREAD_ID + " TEXT," + - KEY_MSG_PARENT_ID + " TEXT,"+ - KEY_MSG_NAME + " TEXT," + - KEY_NXS_SERV_STRING + " TEXT," + - KEY_NXS_HASH + " TEXT," + - KEY_RECV_TS + " INT);"); - - // create table for grp data - mDb->execSQL("CREATE TABLE " + GRP_TABLE_NAME + "(" + - KEY_GRP_ID + " TEXT PRIMARY KEY," + - KEY_TIME_STAMP + " INT," + - KEY_NXS_DATA + " BLOB," + - KEY_NXS_DATA_LEN + " INT," + - KEY_KEY_SET + " BLOB," + - KEY_NXS_META + " BLOB," + - KEY_GRP_NAME + " TEXT," + - KEY_GRP_LAST_POST + " INT," + - KEY_GRP_POP + " INT," + - KEY_MSG_COUNT + " INT," + - KEY_GRP_SUBCR_FLAG + " INT," + - KEY_GRP_STATUS + " INT," + - KEY_NXS_IDENTITY + " TEXT," + - KEY_ORIG_GRP_ID + " TEXT," + - KEY_NXS_SERV_STRING + " TEXT," + - KEY_NXS_FLAGS + " INT," + - KEY_GRP_AUTHEN_FLAGS + " INT," + - KEY_GRP_SIGN_FLAGS + " INT," + - KEY_GRP_CIRCLE_ID + " TEXT," + - KEY_GRP_CIRCLE_TYPE + " INT," + - KEY_GRP_INTERNAL_CIRCLE + " TEXT," + - KEY_GRP_ORIGINATOR + " TEXT," + - KEY_NXS_HASH + " TEXT," + - KEY_RECV_TS + " INT," + - KEY_PARENT_GRP_ID + " TEXT," + - KEY_GRP_REP_CUTOFF + " INT," + - KEY_SIGN_SET + " BLOB);"); - - mDb->execSQL("CREATE TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER + - " INSERT ON " + MSG_TABLE_NAME + - std::string(" BEGIN ") + - " UPDATE " + GRP_TABLE_NAME + " SET " + KEY_GRP_LAST_POST + "= new." - + KEY_RECV_TS + " WHERE " + KEY_GRP_ID + "=new." + KEY_GRP_ID + ";" - + std::string("END;")); - - mDb->execSQL("CREATE INDEX " + MSG_INDEX_GRPID + " ON " + MSG_TABLE_NAME + "(" + KEY_GRP_ID + ");"); - - // Insert release, no need to upgrade - ContentValue cv; - cv.put(KEY_DATABASE_RELEASE_ID, KEY_DATABASE_RELEASE_ID_VALUE); - cv.put(KEY_DATABASE_RELEASE, databaseRelease); - mDb->sqlInsert(DATABASE_RELEASE_TABLE_NAME, "", cv); - - currentDatabaseRelease = databaseRelease; - } else { - // check release - - { - // try to select the release - std::list columns; - columns.push_back(KEY_DATABASE_RELEASE); - - std::string where; - rs_sprintf(where, "%s=%d", KEY_DATABASE_RELEASE_ID.c_str(), KEY_DATABASE_RELEASE_ID_VALUE); - - RetroCursor* c = mDb->sqlQuery(DATABASE_RELEASE_TABLE_NAME, columns, where, ""); - if (c) { - ok = c->moveToFirst(); - - if (ok) { - currentDatabaseRelease = c->getInt32(0); - } - delete c; - - if (!ok) { - // No record found ... insert the record - ContentValue cv; - cv.put(KEY_DATABASE_RELEASE_ID, KEY_DATABASE_RELEASE_ID_VALUE); - cv.put(KEY_DATABASE_RELEASE, currentDatabaseRelease); - ok = mDb->sqlInsert(DATABASE_RELEASE_TABLE_NAME, "", cv); - } - } else { - ok = false; - } - } - - // Release 1 - int newRelease = 1; - if (ok && currentDatabaseRelease < newRelease) { - // Update database - std::list files; - - ok = startReleaseUpdate(newRelease); - - // Move data in files into database - ok = ok && mDb->execSQL("ALTER TABLE " + GRP_TABLE_NAME + " ADD COLUMN " + KEY_NXS_DATA + " BLOB;"); - ok = ok && mDb->execSQL("ALTER TABLE " + GRP_TABLE_NAME + " ADD COLUMN " + KEY_NXS_DATA_LEN + " INT;"); - ok = ok && mDb->execSQL("ALTER TABLE " + MSG_TABLE_NAME + " ADD COLUMN " + KEY_NXS_DATA + " BLOB;"); - ok = ok && mDb->execSQL("ALTER TABLE " + MSG_TABLE_NAME + " ADD COLUMN " + KEY_NXS_DATA_LEN + " INT;"); - - ok = ok && moveDataFromFileToDatabase(mDb, mServiceDir, GRP_TABLE_NAME, KEY_GRP_ID, files); - ok = ok && moveDataFromFileToDatabase(mDb, mServiceDir, MSG_TABLE_NAME, KEY_MSG_ID, files); - -// SQLite doesn't support DROP COLUMN -// ok = ok && mDb->execSQL("ALTER TABLE " + GRP_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_OLD + ";"); -// ok = ok && mDb->execSQL("ALTER TABLE " + GRP_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_OFFSET_OLD + ";"); -// ok = ok && mDb->execSQL("ALTER TABLE " + GRP_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_LEN_OLD + ";"); -// ok = ok && mDb->execSQL("ALTER TABLE " + MSG_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_OLD + ";"); -// ok = ok && mDb->execSQL("ALTER TABLE " + MSG_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_OFFSET_OLD + ";"); -// ok = ok && mDb->execSQL("ALTER TABLE " + MSG_TABLE_NAME + " DROP COLUMN " + KEY_NXS_FILE_LEN_OLD + ";"); - - ok = finishReleaseUpdate(newRelease, ok); - if (ok) { - // Remove transfered files - std::list::const_iterator file; - for (file = files.begin(); file != files.end(); ++file) { - remove(file->c_str()); - } - currentDatabaseRelease = newRelease; - } - } - } - - if (ok) { - std::cerr << "Database " << mDbName << " release " << currentDatabaseRelease << " successfully initialised." << std::endl; - } else { - std::cerr << "Database " << mDbName << " initialisation failed." << std::endl; - } -} - -bool RsDataService::startReleaseUpdate(int release) -{ - // Update database - std::cerr << "Database " << mDbName << " update to release " << release << "." << std::endl; - - return mDb->beginTransaction(); -} - -bool RsDataService::finishReleaseUpdate(int release, bool result) -{ - if (result) { - std::string where; - rs_sprintf(where, "%s=%d", KEY_DATABASE_RELEASE_ID.c_str(), KEY_DATABASE_RELEASE_ID_VALUE); - - ContentValue cv; - cv.put(KEY_DATABASE_RELEASE, release); - result = mDb->sqlUpdate(DATABASE_RELEASE_TABLE_NAME, where, cv); - } - - if (result) { - result = mDb->commitTransaction(); - } else { - result = mDb->rollbackTransaction(); - } - - if (result) { - std::cerr << "Database " << mDbName << " successfully updated to release " << release << "." << std::endl; - } else { - std::cerr << "Database " << mDbName << " update to release " << release << "failed." << std::endl; - } - - return result; -} - -std::shared_ptr RsDataService::locked_getGrpMeta(RetroCursor& c, int colOffset) -{ -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::locked_getGrpMeta()" << std::endl; -#endif - - bool ok = true; - - // for extracting raw data - uint32_t offset = 0; - char* data = NULL; - uint32_t data_len = 0; - - // grpId - std::string tempId; - c.getString(mColGrpMeta_GrpId + colOffset, tempId); - - std::shared_ptr grpMeta ; - RsGxsGroupId grpId(tempId) ; - - if(grpId.isNull()) // not in the DB! - return nullptr; - - if(mUseCache) - grpMeta = mGrpMetaDataCache.getOrCreateMeta(grpId); - else - grpMeta = std::make_shared(); - - if(!grpMeta->mGroupId.isNull()) // the grpMeta is already initialized because it comes from the cache - return grpMeta; - - grpMeta->mGroupId = RsGxsGroupId(tempId); - c.getString(mColGrpMeta_NxsIdentity + colOffset, tempId); - grpMeta->mAuthorId = RsGxsId(tempId); - - c.getString(mColGrpMeta_Name + colOffset, grpMeta->mGroupName); - c.getString(mColGrpMeta_OrigGrpId + colOffset, tempId); - grpMeta->mOrigGrpId = RsGxsGroupId(tempId); - c.getString(mColGrpMeta_ServString + colOffset, grpMeta->mServiceString); - std::string temp; - c.getString(mColGrpMeta_NxsHash + colOffset, temp); - grpMeta->mHash = RsFileHash(temp); - grpMeta->mReputationCutOff = c.getInt32(mColGrpMeta_RepCutoff + colOffset); - grpMeta->mSignFlags = c.getInt32(mColGrpMeta_SignFlags + colOffset); - - 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 + colOffset, data_len); - - if(data) - ok &= grpMeta->keys.GetTlv(data, data_len, &offset); - else - grpMeta->keys.TlvClear() ; - - // local meta - 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 + colOffset, tempId); - grpMeta->mCircleId = RsGxsCircleId(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 + colOffset, s) ; - grpMeta->mOriginator = RsPeerId(s); - grpMeta->mAuthenFlags = c.getInt32(mColGrpMeta_AuthenFlags + colOffset); - grpMeta->mRecvTS = c.getInt32(mColGrpMeta_RecvTs + colOffset); - - - c.getString(mColGrpMeta_ParentGrpId, tempId); - grpMeta->mParentGrpId = RsGxsGroupId(tempId); - - // make sure that flags and keys are actually consistent - - bool have_private_admin_key = false ; - bool have_private_publish_key = false ; - - for(auto mit = grpMeta->keys.private_keys.begin(); mit != grpMeta->keys.private_keys.end();++mit) - { - if(mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_FULL)) have_private_publish_key = true ; - if(mit->second.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) have_private_admin_key = true ; - } - - if(have_private_admin_key && !(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) - { - std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group does not have flag ADMIN but an admin key was found. Updating the flags." << std::endl; - grpMeta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - } - if(!have_private_admin_key && (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) - { - std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group has flag ADMIN but no admin key found. Updating the flags." << std::endl; - grpMeta->mSubscribeFlags &= ~GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - } - if(have_private_publish_key && !(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)) - { - std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group does not have flag PUBLISH but an admin key was found. Updating the flags." << std::endl; - grpMeta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_PUBLISH; - } - if(!have_private_publish_key && (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)) - { - std::cerr << "(WW) inconsistency in group " << grpMeta->mGroupId << ": group has flag PUBLISH but no admin key found. Updating the flags." << std::endl; - grpMeta->mSubscribeFlags &= ~GXS_SERV::GROUP_SUBSCRIBE_PUBLISH; - } - - if(ok) - return grpMeta; - else - return NULL; -} - -RsNxsGrp* RsDataService::locked_getGroup(RetroCursor &c) -{ - /*! - * grpId, pub admin and pub publish key - * necessary for successful group - */ - RsNxsGrp* grp = new RsNxsGrp(mServType); - bool ok = true; - - // for manipulating raw data - uint32_t offset = 0; - char* data = NULL; - uint32_t data_len = 0; - - // grpId - c.getStringT(mColGrp_GrpId, grp->grpId); - ok &= !grp->grpId.isNull(); - - offset = 0; data_len = 0; - if(ok){ - - data = (char*)c.getData(mColGrp_MetaData, data_len); - if(data) - grp->meta.GetTlv(data, data_len, &offset); - } - - /* now retrieve grp data */ - offset = 0; data_len = 0; - if(ok){ - data = (char*)c.getData(mColGrp_NxsData, data_len); - if(data) - ok &= grp->grp.GetTlv(data, data_len, &offset); - } - - if(ok) - return grp; - else - delete grp; - - return NULL; -} - -std::shared_ptr RsDataService::locked_getMsgMeta(RetroCursor &c, int colOffset) -{ - bool ok = true; - uint32_t data_len = 0, - offset = 0; - char* data = NULL; - - RsGxsGroupId group_id; - RsGxsMessageId msg_id; - - std::string gId; - c.getString(mColMsgMeta_GrpId + colOffset, gId); - group_id = RsGxsGroupId(gId); - std::string temp; - c.getString(mColMsgMeta_MsgId + colOffset, temp); - msg_id = RsGxsMessageId(temp); - - // without these, a msg is meaningless - if(group_id.isNull() || msg_id.isNull()) - return nullptr; - - std::shared_ptr msgMeta; - - if(mUseCache) - msgMeta = mMsgMetaDataCache[group_id].getOrCreateMeta(msg_id); - else - msgMeta = std::make_shared(); - - if(!msgMeta->mGroupId.isNull()) // we cannot do that because the cursor needs to advance. Is there a method to skip some data in the db? - return msgMeta; - - msgMeta->mGroupId = group_id; - msgMeta->mMsgId = msg_id; - - c.getString(mColMsgMeta_OrigMsgId + colOffset, temp); - msgMeta->mOrigMsgId = RsGxsMessageId(temp); - c.getString(mColMsgMeta_NxsIdentity + colOffset, temp); - msgMeta->mAuthorId = RsGxsId(temp); - c.getString(mColMsgMeta_Name + colOffset, msgMeta->mMsgName); - c.getString(mColMsgMeta_NxsServString + colOffset, msgMeta->mServiceString); - - c.getString(mColMsgMeta_NxsHash + colOffset, temp); - msgMeta->mHash = RsFileHash(temp); - msgMeta->recvTS = c.getInt32(mColMsgMeta_RecvTs + colOffset); - offset = 0; - data = (char*)c.getData(mColMsgMeta_SignSet + colOffset, data_len); - msgMeta->signSet.GetTlv(data, data_len, &offset); - msgMeta->mMsgSize = c.getInt32(mColMsgMeta_NxsDataLen + colOffset); - - 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 + colOffset, temp); - msgMeta->mThreadId = RsGxsMessageId(temp); - c.getString(mColMsgMeta_MsgParentId + colOffset, temp); - msgMeta->mParentId = RsGxsMessageId(temp); - - // local meta - msgMeta->mMsgStatus = c.getInt32(mColMsgMeta_MsgStatus + colOffset); - msgMeta->mChildTs = c.getInt32(mColMsgMeta_ChildTs + colOffset); - - if(ok) - return msgMeta; - - return nullptr; -} - - - -RsNxsMsg* RsDataService::locked_getMessage(RetroCursor &c) -{ - - RsNxsMsg* msg = new RsNxsMsg(mServType); - - bool ok = true; - uint32_t data_len = 0, - offset = 0; - char* data = NULL; - c.getStringT(mColMsg_GrpId, msg->grpId); - std::string temp; - c.getString(mColMsg_MsgId, temp); - msg->msgId = RsGxsMessageId(temp); - - ok &= (!msg->grpId.isNull()) && (!msg->msgId.isNull()); - - offset = 0; data_len = 0; - if(ok){ - - data = (char*)c.getData(mColMsg_MetaData, data_len); - if(data) - msg->meta.GetTlv(data, data_len, &offset); - } - - /* now retrieve msg data */ - offset = 0; data_len = 0; - if(ok){ - data = (char*)c.getData(mColMsg_NxsData, data_len); - if(data) - ok &= msg->msg.GetTlv(data, data_len, &offset); - } - - if(ok) - return msg; - - delete msg; - return nullptr; -} - -int RsDataService::storeMessage(const std::list& msg) -{ - - RsStackMutex stack(mDbMutex); - - // start a transaction - mDb->beginTransaction(); - - for(std::list::const_iterator mit = msg.begin(); mit != msg.end(); ++mit) - { - RsNxsMsg* msgPtr = *mit; - RsGxsMsgMetaData* msgMetaPtr = msgPtr->metaData; - - assert(msgMetaPtr != NULL); - -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::storeMessage() "; - std::cerr << " GroupId: " << msgMetaPtr->mGroupId.toStdString(); - std::cerr << " MessageId: " << msgMetaPtr->mMsgId.toStdString(); - std::cerr << std::endl; -#endif - - // skip msg item if size if greater than - if(!validSize(msgPtr)) - { - std::cerr << "RsDataService::storeMessage() ERROR invalid size"; - std::cerr << std::endl; - continue; - } - - ContentValue cv; - - uint32_t dataLen = msgPtr->msg.TlvSize(); - char msgData[dataLen]; - uint32_t offset = 0; - msgPtr->msg.SetTlv(msgData, dataLen, &offset); - cv.put(KEY_NXS_DATA, dataLen, msgData); - - cv.put(KEY_NXS_DATA_LEN, (int32_t)dataLen); - cv.put(KEY_MSG_ID, msgMetaPtr->mMsgId.toStdString()); - cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId.toStdString()); - cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString); - cv.put(KEY_NXS_HASH, msgMetaPtr->mHash.toStdString()); - cv.put(KEY_RECV_TS, (int32_t)msgMetaPtr->recvTS); - - - char signSetData[msgMetaPtr->signSet.TlvSize()]; - offset = 0; - msgMetaPtr->signSet.SetTlv(signSetData, msgMetaPtr->signSet.TlvSize(), &offset); - cv.put(KEY_SIGN_SET, msgMetaPtr->signSet.TlvSize(), signSetData); - cv.put(KEY_NXS_IDENTITY, msgMetaPtr->mAuthorId.toStdString()); - - - cv.put(KEY_NXS_FLAGS, (int32_t) msgMetaPtr->mMsgFlags); - cv.put(KEY_TIME_STAMP, (int32_t) msgMetaPtr->mPublishTs); - - offset = 0; - char metaData[msgPtr->meta.TlvSize()]; - msgPtr->meta.SetTlv(metaData, msgPtr->meta.TlvSize(), &offset); - cv.put(KEY_NXS_META, msgPtr->meta.TlvSize(), metaData); - - cv.put(KEY_MSG_PARENT_ID, msgMetaPtr->mParentId.toStdString()); - cv.put(KEY_MSG_THREAD_ID, msgMetaPtr->mThreadId.toStdString()); - cv.put(KEY_ORIG_MSG_ID, msgMetaPtr->mOrigMsgId.toStdString()); - cv.put(KEY_MSG_NAME, msgMetaPtr->mMsgName); - - // now local meta - cv.put(KEY_MSG_STATUS, (int32_t)msgMetaPtr->mMsgStatus); - cv.put(KEY_CHILD_TS, (int32_t)msgMetaPtr->mChildTs); - - if (!mDb->sqlInsert(MSG_TABLE_NAME, "", cv)) - { - std::cerr << "RsDataService::storeMessage() sqlInsert Failed"; - std::cerr << std::endl; - std::cerr << "\t For GroupId: " << msgMetaPtr->mGroupId.toStdString(); - std::cerr << std::endl; - std::cerr << "\t & MessageId: " << msgMetaPtr->mMsgId.toStdString(); - std::cerr << std::endl; - } - - // This is needed so that mLastPost is correctly updated in the group meta when it is re-loaded. - - if(mUseCache) - mMsgMetaDataCache[msgMetaPtr->mGroupId].updateMeta(msgMetaPtr->mMsgId,*msgMetaPtr); - - delete *mit; - } - - // finish transaction - bool ret = mDb->commitTransaction(); - - return ret; -} - -bool RsDataService::validSize(RsNxsMsg* msg) const -{ - if((msg->msg.TlvSize() + msg->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true; - - return false; -} - - -int RsDataService::storeGroup(const std::list& grp) -{ - - RsStackMutex stack(mDbMutex); - - // begin transaction - mDb->beginTransaction(); - - for(std::list::const_iterator sit = grp.begin();sit != grp.end(); ++sit) - { - RsNxsGrp* grpPtr = *sit; - RsGxsGrpMetaData* grpMetaPtr = grpPtr->metaData; - - assert(grpMetaPtr != NULL); - - // if data is larger than max item size do not add - if(!validSize(grpPtr)) continue; - -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::storeGroup() GrpId: " << grpPtr->grpId.toStdString(); - std::cerr << " CircleType: " << (uint32_t) grpMetaPtr->mCircleType; - std::cerr << " CircleId: " << grpMetaPtr->mCircleId.toStdString(); - std::cerr << std::endl; -#endif - - /*! - * STORE data, data len, - * grpId, flags, publish time stamp, identity, - * id signature, admin signatue, key set, last posting ts - * and meta data - **/ - ContentValue cv; - - uint32_t dataLen = grpPtr->grp.TlvSize(); - char grpData[dataLen]; - uint32_t offset = 0; - grpPtr->grp.SetTlv(grpData, dataLen, &offset); - cv.put(KEY_NXS_DATA, dataLen, grpData); - - cv.put(KEY_NXS_DATA_LEN, (int32_t) dataLen); - cv.put(KEY_GRP_ID, grpPtr->grpId.toStdString()); - cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName); - cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId.toStdString()); - cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString); - cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); - cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs); - cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags); - cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId.toStdString()); - cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType); - cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle.toStdString()); - cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator.toStdString()); - cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags); - cv.put(KEY_PARENT_GRP_ID, grpMetaPtr->mParentGrpId.toStdString()); - cv.put(KEY_NXS_HASH, grpMetaPtr->mHash.toStdString()); - cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS); - cv.put(KEY_GRP_REP_CUTOFF, (int32_t)grpMetaPtr->mReputationCutOff); - cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId.toStdString()); - - offset = 0; - char keySetData[grpMetaPtr->keys.TlvSize()]; - grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset); - cv.put(KEY_KEY_SET, grpMetaPtr->keys.TlvSize(), keySetData); - - offset = 0; - char metaData[grpPtr->meta.TlvSize()]; - grpPtr->meta.SetTlv(metaData, grpPtr->meta.TlvSize(), &offset); - cv.put(KEY_NXS_META, grpPtr->meta.TlvSize(), metaData); - - // local meta data - cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags); - cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop); - cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mVisibleMsgCount); - cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus); - cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost); - - mGrpMetaDataCache.updateMeta(grpMetaPtr->mGroupId,*grpMetaPtr); - - if (!mDb->sqlInsert(GRP_TABLE_NAME, "", cv)) - { - std::cerr << "RsDataService::storeGroup() sqlInsert Failed"; - std::cerr << std::endl; - std::cerr << "\t For GroupId: " << grpMetaPtr->mGroupId.toStdString(); - std::cerr << std::endl; - } - - delete *sit; - } - // finish transaction - bool ret = mDb->commitTransaction(); - - return ret; -} - -int RsDataService::updateGroup(const std::list &grp) -{ - - RsStackMutex stack(mDbMutex); - - // begin transaction - mDb->beginTransaction(); - - for( std::list::const_iterator sit = grp.begin(); sit != grp.end(); ++sit) - { - - RsNxsGrp* grpPtr = *sit; - RsGxsGrpMetaData* grpMetaPtr = grpPtr->metaData; - - assert(grpMetaPtr != NULL); - - // if data is larger than max item size do not add - if(!validSize(grpPtr)) continue; - - /*! - * STORE data, data len, - * grpId, flags, publish time stamp, identity, - * id signature, admin signatue, key set, last posting ts - * and meta data - **/ - ContentValue cv; - uint32_t dataLen = grpPtr->grp.TlvSize(); - char grpData[dataLen]; - uint32_t offset = 0; - grpPtr->grp.SetTlv(grpData, dataLen, &offset); - cv.put(KEY_NXS_DATA, dataLen, grpData); - - cv.put(KEY_NXS_DATA_LEN, (int32_t) dataLen); - cv.put(KEY_GRP_ID, grpPtr->grpId.toStdString()); - cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName); - cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId.toStdString()); - cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString); - cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); - cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs); - cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags); - cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId.toStdString()); - cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType); - cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle.toStdString()); - cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator.toStdString()); - cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags); - cv.put(KEY_NXS_HASH, grpMetaPtr->mHash.toStdString()); - cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS); - cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId.toStdString()); - - offset = 0; - char keySetData[grpMetaPtr->keys.TlvSize()]; - grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset); - cv.put(KEY_KEY_SET, grpMetaPtr->keys.TlvSize(), keySetData); - - offset = 0; - char metaData[grpPtr->meta.TlvSize()]; - grpPtr->meta.SetTlv(metaData, grpPtr->meta.TlvSize(), &offset); - cv.put(KEY_NXS_META, grpPtr->meta.TlvSize(), metaData); - - // local meta data - cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags); - cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop); - cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mVisibleMsgCount); - cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus); - cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost); - - mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId.toStdString() + "'", cv); - - mGrpMetaDataCache.updateMeta(grpMetaPtr->mGroupId,*grpMetaPtr); - - delete *sit; - } - // finish transaction - bool ret = mDb->commitTransaction(); - - return ret; -} - -int RsDataService::updateGroupKeys(const RsGxsGroupId& grpId,const RsTlvSecurityKeySet& keys,uint32_t subscribe_flags) -{ - RsStackMutex stack(mDbMutex); - - // begin transaction - mDb->beginTransaction(); - - /*! - * STORE key set - **/ - - ContentValue cv; - //cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags); ? - - uint32_t offset = 0; - char keySetData[keys.TlvSize()]; - keys.SetTlv(keySetData, keys.TlvSize(), &offset); - cv.put(KEY_KEY_SET, keys.TlvSize(), keySetData); - cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)subscribe_flags); - - mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpId.toStdString() + "'", cv); - - // finish transaction - bool res = mDb->commitTransaction(); - - mGrpMetaDataCache.clear(grpId); - mGrpMetaDataCache.setCacheUpToDate(false); // this is needed because clear() doesn't do it (on purpose) - - return res; -} - -bool RsDataService::validSize(RsNxsGrp* grp) const -{ - if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true; - return false; -} - -int RsDataService::retrieveNxsGrps(std::map &grp, bool withMeta) -{ -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; - int requestedGroups = grp.size(); -#endif - - if(grp.empty()) - { - RsStackMutex stack(mDbMutex); - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, withMeta ? mGrpColumnsWithMeta : mGrpColumns, "", ""); - - if(c) - { - std::vector grps; - - locked_retrieveGroups(c, grps, withMeta ? mColGrp_WithMetaOffset : 0); - std::vector::iterator vit = grps.begin(); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - resultCount = grps.size(); -#endif - - for(; vit != grps.end(); ++vit) - { - grp[(*vit)->grpId] = *vit; - } - - delete c; - } - - } - else - { - RsStackMutex stack(mDbMutex); - std::map::iterator mit = grp.begin(); - - std::list toRemove; - - for(; mit != grp.end(); ++mit) - { - const RsGxsGroupId& grpId = mit->first; - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, withMeta ? mGrpColumnsWithMeta : mGrpColumns, "grpId='" + grpId.toStdString() + "'", ""); - - if(c) - { - std::vector grps; - locked_retrieveGroups(c, grps, withMeta ? mColGrp_WithMetaOffset : 0); - - if(!grps.empty()) - { - RsNxsGrp* ng = grps.front(); - grp[ng->grpId] = ng; - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - ++resultCount; -#endif - }else{ - toRemove.push_back(grpId); - } - - delete c; - } - } - - std::list::iterator grpIdIt; - for (grpIdIt = toRemove.begin(); grpIdIt != toRemove.end(); ++grpIdIt) - { - grp.erase(*grpIdIt); - } - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - std::cerr << "RsDataService::retrieveNxsGrps() " << mDbName << ", Requests: " << requestedGroups << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - return 1; -} - -void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector& grps, int metaOffset) -{ - if(c){ - bool valid = c->moveToFirst(); - - while(valid){ - RsNxsGrp* g = locked_getGroup(*c); - - // only add the latest grp info - if(g) - { - if (metaOffset) - g->metaData = new RsGxsGrpMetaData(*locked_getGrpMeta(*c, metaOffset)); - else - g->metaData = nullptr; - - grps.push_back(g); - } - valid = c->moveToNext(); - } - } -} - -int RsDataService::retrieveNxsMsgs(const GxsMsgReq &reqIds, GxsMsgResult &msg, bool withMeta) -{ -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; -#endif - - for(auto mit = reqIds.begin(); mit != reqIds.end(); ++mit) - { - - const RsGxsGroupId& grpId = mit->first; - - // if vector empty then request all messages - const std::set& msgIdV = mit->second; - std::vector msgSet; - - if(msgIdV.empty()) - { - RS_STACK_MUTEX(mDbMutex); - - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, withMeta ? mMsgColumnsWithMeta : mMsgColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", ""); - - if(c) - locked_retrieveMessages(c, msgSet, withMeta ? mColMsg_WithMetaOffset : 0); - - delete c; - } - else - { - RS_STACK_MUTEX(mDbMutex); - - // request each grp - for( std::set::const_iterator sit = msgIdV.begin(); - sit!=msgIdV.end();++sit ) - { - const RsGxsMessageId& msgId = *sit; - - 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, withMeta ? mColMsg_WithMetaOffset : 0); - } - - delete c; - } - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - resultCount += msgSet.size(); -#endif - - msg[grpId] = msgSet; - - msgSet.clear(); - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - std::cerr << "RsDataService::retrieveNxsMsgs() " << mDbName << ", Requests: " << reqIds.size() << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - return 1; -} - -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 = new RsGxsMsgMetaData(*locked_getMsgMeta(*c, metaOffset)); - else - m->metaData = nullptr; - - msgs.push_back(m); - } - - valid = c->moveToNext(); - } - return; -} - -int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaResult& msgMeta) -{ - RsStackMutex stack(mDbMutex); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; -#endif - - for(auto mit(reqIds.begin()); mit != reqIds.end(); ++mit) - { - - const RsGxsGroupId& grpId = mit->first; - const std::set& msgIdV = mit->second; - - // if vector empty then request all messages - - // The pointer here is a trick to not initialize a new cache entry when cache is disabled, while keeping the unique variable all along. - t_MetaDataCache *cache(mUseCache? (&mMsgMetaDataCache[grpId]) : nullptr); - - if(msgIdV.empty()) - { - if(mUseCache && cache->isCacheUpToDate()) - cache->getFullMetaList(msgMeta[grpId]); - else - { - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgMetaColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", ""); - - if (c) - { - locked_retrieveMsgMetaList(c, msgMeta[grpId]); - - if(mUseCache) - cache->setCacheUpToDate(true); - } - delete c; - } -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << mDbName << ": Retrieving (all) Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; -#endif - } - else - { - // request each msg meta - auto& metaSet(msgMeta[grpId]); - - for(auto sit(msgIdV.begin()); sit!=msgIdV.end(); ++sit) - { - const RsGxsMessageId& msgId = *sit; - - auto meta = mUseCache?cache->getMeta(msgId): (std::shared_ptr()); - - if(meta) - metaSet.push_back(meta); - else - { - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgMetaColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", ""); - - c->moveToFirst(); - auto meta = locked_getMsgMeta(*c, 0); - - if(meta) - { - metaSet.push_back(meta); - - if(mUseCache) - mMsgMetaDataCache[grpId].updateMeta(msgId,meta); - } - - delete c; - } - } -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << mDbName << ": Retrieving Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; -#endif - } - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - if(mDbName==std::string("gxsforums_db")) - std::cerr << "RsDataService::retrieveGxsMsgMetaData() " << mDbName << ", Requests: " << reqIds.size() << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - return 1; -} - -void RsDataService::locked_retrieveGrpMetaList(RetroCursor *c, std::map >& grpMeta) -{ - if(!c) - { - RsErr() << __PRETTY_FUNCTION__ << ": attempt to retrieve Group Meta data from the DB with null cursor!" << std::endl; - return; - } - - bool valid = c->moveToFirst(); - - while(valid) - { - auto m = locked_getGrpMeta(*c, 0); - - if(m != nullptr) - grpMeta[m->mGroupId] = m; - - valid = c->moveToNext(); - } -} - -void RsDataService::locked_retrieveMsgMetaList(RetroCursor *c, std::vector >& msgMeta) -{ - if(!c) - { - RsErr() << __PRETTY_FUNCTION__ << ": attempt to retrieve Msg Meta data from the DB with null cursor!" << std::endl; - return; - } - - bool valid = c->moveToFirst(); - while(valid) - { - auto m = locked_getMsgMeta(*c, 0); - - if(m != nullptr) - msgMeta.push_back(m); - - valid = c->moveToNext(); - } -} - -int RsDataService::retrieveGxsGrpMetaData(std::map >& grp) -{ -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::retrieveGxsGrpMetaData()"; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(mDbMutex); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; - int requestedGroups = grp.size(); -#endif - - if(grp.empty()) - { - if(mUseCache && mGrpMetaDataCache.isCacheUpToDate()) // grab all the stash from the cache, so as to avoid decryption costs. - { -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void*)this << ": RsDataService::retrieveGxsGrpMetaData() retrieving all from cache!" << std::endl; -#endif - - mGrpMetaDataCache.getFullMetaList(grp) ; - } - else - { -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "RsDataService::retrieveGxsGrpMetaData() retrieving all" << std::endl; -#endif - // clear the cache - - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "", ""); - - if(c) - { - locked_retrieveGrpMetaList(c,grp); - - if(mUseCache) - mGrpMetaDataCache.setCacheUpToDate(true); - } - delete c; -#ifdef RS_DATA_SERVICE_DEBUG_TIME - resultCount += grp.size(); -#endif - - } - } - else - { - for(auto mit(grp.begin()); mit != grp.end(); ++mit) - { - auto meta = mUseCache?mGrpMetaDataCache.getMeta(mit->first): (std::shared_ptr()) ; - - if(meta) - mit->second = meta; - else - { -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << mDbName << ": Retrieving Grp metadata grpId=" << mit->first ; -#endif - - const RsGxsGroupId& grpId = mit->first; - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", ""); - - c->moveToFirst(); - - auto meta = locked_getGrpMeta(*c, 0); - - if(meta) - { - mit->second = meta; - - if(mUseCache) - mGrpMetaDataCache.updateMeta(grpId,meta); - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - ++resultCount; -#endif - - delete c; - -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - else - std::cerr << ". not found!" << std::endl; -#endif - } - } - - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - std::cerr << "RsDataService::retrieveGxsGrpMetaData() " << mDbName << ", Requests: " << requestedGroups << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - /* Remove not found entries as stated in the documentation */ - for(auto i = grp.begin(); i != grp.end();) - if(!i->second) i = grp.erase(i); - else ++i; - - return 1; -} - -int RsDataService::resetDataStore() -{ - -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "resetDataStore() " << std::endl; -#endif - - { - RsStackMutex stack(mDbMutex); - - mDb->execSQL("DROP INDEX " + MSG_INDEX_GRPID); - mDb->execSQL("DROP TABLE " + DATABASE_RELEASE_TABLE_NAME); - mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME); - mDb->execSQL("DROP TABLE " + GRP_TABLE_NAME); - mDb->execSQL("DROP TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER); - } - - // recreate database - initialise(true); - - return 1; -} - -int RsDataService::updateGroupMetaData(const GrpLocMetaData& meta) -{ -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void*)this << ": Updating Grp Meta data: grpId = " << meta.grpId << std::endl; -#endif - - RsStackMutex stack(mDbMutex); - const RsGxsGroupId& grpId = meta.grpId; - -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void*)this << ": erasing old entry from cache." << std::endl; -#endif - - if( mDb->sqlUpdate(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", meta.val)) - { - // If we use the cache, update the meta data immediately. - - if(mUseCache) - { - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpMetaColumns, "grpId='" + grpId.toStdString() + "'", ""); - - c->moveToFirst(); - - // temporarily disable the cache so that we get the value from the DB itself. - mUseCache=false; - auto meta = locked_getGrpMeta(*c, 0); - mUseCache=true; - - if(meta) - mGrpMetaDataCache.updateMeta(grpId,meta); - - delete c; - } - - return 1; - } - return 0; -} - -int RsDataService::updateMessageMetaData(const MsgLocMetaData& metaData) -{ -#ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void*)this << ": Updating Msg Meta data: grpId = " << metaData.msgId.first << " msgId = " << metaData.msgId.second << std::endl; -#endif - - RsStackMutex stack(mDbMutex); - const RsGxsGroupId& grpId = metaData.msgId.first; - const RsGxsMessageId& msgId = metaData.msgId.second; - - if(mDb->sqlUpdate(MSG_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", metaData.val) ) - { - // If we use the cache, update the meta data immediately. - - if(mUseCache) - { - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgMetaColumns, KEY_GRP_ID+ "='" + grpId.toStdString() + "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", ""); - - c->moveToFirst(); - - // temporarily disable the cache so that we get the value from the DB itself. - mUseCache=false; - auto meta = locked_getMsgMeta(*c, 0); - mUseCache=true; - - if(meta) - mMsgMetaDataCache[grpId].updateMeta(msgId,meta); - - delete c; - } - - return 1; - } - return 0; -} - -int RsDataService::removeMsgs(const GxsMsgReq& msgIds) -{ - RsStackMutex stack(mDbMutex); - - GxsMsgReq::const_iterator mit = msgIds.begin(); - - for(; mit != msgIds.end(); ++mit) - { - const std::set& msgIdV = mit->second; - const RsGxsGroupId& grpId = mit->first; - - // delete messages - GxsMsgReq msgsToDelete; - msgsToDelete[grpId] = msgIdV; - locked_removeMessageEntries(msgsToDelete); - } - - return 1; -} - -int RsDataService::removeGroups(const std::vector &grpIds) -{ - - RsStackMutex stack(mDbMutex); - - locked_removeGroupEntries(grpIds); - - return 1; -} - -int RsDataService::retrieveGroupIds(std::vector &grpIds) -{ - RsStackMutex stack(mDbMutex); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; -#endif - - RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, mGrpIdColumn, "", ""); - - if(c) - { - bool valid = c->moveToFirst(); - - while(valid) - { - std::string grpId; - c->getString(mColGrpId_GrpId, grpId); - grpIds.push_back(RsGxsGroupId(grpId)); - valid = c->moveToNext(); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - ++resultCount; -#endif - } - delete c; - }else - { - return 0; - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - std::cerr << "RsDataService::retrieveGroupIds() " << mDbName << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - return 1; -} - -int RsDataService::retrieveMsgIds(const RsGxsGroupId& grpId, RsGxsMessageId::std_set& msgIds) -{ -#ifdef RS_DATA_SERVICE_DEBUG_TIME - rstime::RsScopeTimer timer(""); - int resultCount = 0; -#endif - - RetroCursor* c = mDb->sqlQuery(MSG_TABLE_NAME, mMsgIdColumn, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", ""); - - if(c) - { - bool valid = c->moveToFirst(); - - while(valid) - { - std::string msgId; - c->getString(mColMsgId_MsgId, msgId); - - if(c->columnCount() != 1) - std::cerr << "(EE) ********* not retrieving all columns!!" << std::endl; - - msgIds.insert(RsGxsMessageId(msgId)); - valid = c->moveToNext(); - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - ++resultCount; -#endif - } - delete c; - }else - { - return 0; - } - -#ifdef RS_DATA_SERVICE_DEBUG_TIME - std::cerr << "RsDataService::retrieveNxsGrps() " << mDbName << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl; -#endif - - return 1; - -} - -bool RsDataService::locked_removeMessageEntries(const GxsMsgReq& msgIds) -{ - // start a transaction - bool ret = mDb->beginTransaction(); - - GxsMsgReq::const_iterator mit = msgIds.begin(); - - for(; mit != msgIds.end(); ++mit) - { - const RsGxsGroupId& grpId = mit->first; - const std::set& msgsV = mit->second; - auto& cache(mMsgMetaDataCache[grpId]); - - for(auto& msgId:msgsV) - { - mDb->sqlDelete(MSG_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "' AND " + KEY_MSG_ID + "='" + msgId.toStdString() + "'", ""); - - cache.clear(msgId); - } - } - - ret &= mDb->commitTransaction(); - - return ret; -} - -bool RsDataService::locked_removeGroupEntries(const std::vector& grpIds) -{ - // start a transaction - bool ret = mDb->beginTransaction(); - - for(auto grpId:grpIds) - { - mDb->sqlDelete(GRP_TABLE_NAME, KEY_GRP_ID+ "='" + grpId.toStdString() + "'", ""); - - // also remove the group meta from cache. - mGrpMetaDataCache.clear(grpId) ; - } - - ret &= mDb->commitTransaction(); - return ret; -} - -uint32_t RsDataService::cacheSize() const { - return 0; -} - -int RsDataService::setCacheSize(uint32_t /* size */) -{ - return 0; -} - -void RsDataService::debug_printCacheSize() -{ - RS_STACK_MUTEX(mDbMutex); - - uint32_t nb_items; - uint64_t total_size; - - mGrpMetaDataCache.debug_computeSize(nb_items, total_size); - - RsDbg() << "[CACHE] Cache size: " << std::endl; - RsDbg() << "[CACHE] Groups: " << " total: " << nb_items << ", size: " << total_size << std::endl; - - nb_items = 0; - total_size = 0; - - for(auto& it:mMsgMetaDataCache) - { - uint32_t tmp_nb_items; - uint64_t tmp_total_size; - - it.second.debug_computeSize(tmp_nb_items, tmp_total_size); - - nb_items += tmp_nb_items; - total_size += tmp_total_size; - } - RsDbg() << "[CACHE] Msgs: " << " total: " << nb_items << ", size: " << total_size << std::endl; -} - - - - - - - - diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h deleted file mode 100644 index e9554f04f..000000000 --- a/libretroshare/src/gxs/rsdataservice.h +++ /dev/null @@ -1,459 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxsdataservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2012 by Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSDATASERVICE_H -#define RSDATASERVICE_H - -#include "gxs/rsgds.h" -#include "util/retrodb.h" - -class MsgUpdate -{ -public: - - //MsgUpdate(){} - //MsgUpdate(const MsgUpdate& ){}//hier müsste ein echter constructor sein - RsGxsMessageId msgId; - ContentValue cv; -}; - -template class t_MetaDataCache -{ -public: - t_MetaDataCache() - : mCache_ContainsAllMetas(false) - {} - virtual ~t_MetaDataCache() = default; - - bool isCacheUpToDate() const { return mCache_ContainsAllMetas ; } - void setCacheUpToDate(bool b) { mCache_ContainsAllMetas = b; } - - void getFullMetaList(std::map >& mp) const { mp = mMetas ; } - void getFullMetaList(std::vector >& mp) const { for(auto& m:mMetas) mp.push_back(m.second) ; } - - std::shared_ptr getMeta(const ID& id) - { - auto itt = mMetas.find(id); - - if(itt != mMetas.end()) - return itt->second ; - else - return nullptr; - } - - std::shared_ptr getOrCreateMeta(const ID& id) - { - auto it = mMetas.find(id) ; - - if(it != mMetas.end()) - { -#ifdef RS_DATA_SERVICE_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << ": getting group meta " << grpId << " from cache." << std::endl; -#endif - return it->second ; - } - else - { -#ifdef RS_DATA_SERVICE_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << ": group meta " << grpId << " not in cache. Loading it from DB..." << std::endl; -#endif - return (mMetas[id] = std::make_shared()); - } - } - - void updateMeta(const ID& id,const MetaDataClass& meta) - { - mMetas[id] = std::make_shared(meta); // create a new shared_ptr to possibly replace the previous one - } - - void updateMeta(const ID& id,const std::shared_ptr& meta) - { - mMetas[id] = meta; // create a new shared_ptr to possibly replace the previous one - } - - void clear(const ID& id) - { - auto it = mMetas.find(id) ; - - // We dont actually delete the item, because it might be used by a calling client. - // In this case, the memory will not be used for long, so we keep it into a list for a safe amount - // of time and delete it later. Using smart pointers here would be more elegant, but that would need - // to be implemented thread safe, which is difficult in this case. - - if(it != mMetas.end()) - { -#ifdef RS_DATA_SERVICE_DEBUG - std::cerr << "(II) moving database cache entry " << (void*)(*it).second << " to dead list." << std::endl; -#endif - - mMetas.erase(it) ; - - // No need to modify mCache_ContainsAllMetas since, assuming that the cache always contains - // all possible elements from the DB, clearing one from the cache means that it is also deleted from the db, so - // the property is preserved. - } - } - - void debug_computeSize(uint32_t& nb_items, uint64_t& total_size) const - { - nb_items = mMetas.size(); - total_size = 0; - - for(auto it:mMetas) total_size += it.second->serial_size(); - } -private: - std::map > mMetas; - - static const uint32_t CACHE_ENTRY_GRACE_PERIOD = 600 ; // Unused items are deleted 10 minutes after last usage. - - bool mCache_ContainsAllMetas ; -}; - -class RsDataService : public RsGeneralDataService -{ -public: - - RsDataService(const std::string& serviceDir, const std::string& dbName, uint16_t serviceType, - RsGxsSearchModule* mod = NULL, const std::string& key = ""); - virtual ~RsDataService(); - - /*! - * Retrieves all msgs - * @param reqIds requested msg ids (grpId,msgId), leave msg list empty to get all msgs for the grp - * @param msg result of msg retrieval - * @param withMeta true will also retrieve metadata - * @return error code - */ - int retrieveNxsMsgs(const GxsMsgReq& reqIds, GxsMsgResult& msg, bool withMeta = false) override; - - /*! - * Retrieves groups, if empty, retrieves all grps, if map is not empty - * only retrieve entries, if entry cannot be found, it is removed from map - * @param grp retrieved groups - * @param withMeta this initialise the metaData member of the nxsgroups retrieved - * @return error code - */ - int retrieveNxsGrps(std::map& grp, bool withMeta) override; - - /*! - * Retrieves meta data of all groups stored (most current versions only) - * @param grp output group meta data - * @return error code - */ - int retrieveGxsGrpMetaData(std::map > &grp) override; - - /*! - * Retrieves meta data of all groups stored (most current versions only) - * @param grpIds grpIds for which to retrieve meta data - * @param msgMeta meta data result as map of grpIds to array of metadata for that grpId - * @return error code - */ - int retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaResult& msgMeta) override; - - /*! - * remove msgs in data store - * @param grpId group Id of message to be removed - * @param msgIds ids of messages to be removed - * @return error code - */ - int removeMsgs(const GxsMsgReq& msgIds) override; - - /*! - * remove groups in data store listed in grpIds param - * @param grpIds ids of groups to be removed - * @return error code - */ - int removeGroups(const std::vector& grpIds) override; - - /*! - * Retrieves all group ids in store - * @param grpIds all grpids in store is inserted into this vector - * @return error code - */ - int retrieveGroupIds(std::vector &grpIds) override; - - /*! - * Retrives all msg ids in store - * @param grpId groupId of message ids to retrieve - * @param msgId msgsids retrieved - * @return error code - */ - int retrieveMsgIds(const RsGxsGroupId& grpId, RsGxsMessageId::std_set& msgId) override; - - /*! - * @return the cache size set for this RsGeneralDataService in bytes - */ - uint32_t cacheSize() const override; - - /*! - * \brief serviceType - * \return - * The service type for the current data service. - */ - virtual uint16_t serviceType() const override { return mServType; } - - /*! - * @param size size of cache to set in bytes - */ - int setCacheSize(uint32_t size) override; - - /*! - * Stores a list of signed messages into data store - * @param msg map of message and decoded meta data information - * @return error code - */ - int storeMessage(const std::list& msg) override; - - /*! - * Stores a list of groups in data store - * @param grp map of group and decoded meta data - * @return error code - */ - int storeGroup(const std::list& grp) override; - - /*! - * Updates group entries in Db - * @param grp map of group and decoded meta data - * @return error code - */ - int updateGroup(const std::list& grsp) override; - - /*! - * @param metaData The meta data item to update - * @return error code - */ - int updateMessageMetaData(const MsgLocMetaData& metaData) override; - - /*! - * @param metaData The meta data item to update - * @return error code - */ - int updateGroupMetaData(const GrpLocMetaData &meta) override; - - /*! - * Completely clear out data stored in - * and returns this to a state - * as it was when first constructed - * @return error code - */ - int resetDataStore() override; - - bool validSize(RsNxsMsg* msg) const override; - bool validSize(RsNxsGrp* grp) const override; - - /*! - * Convenience function used to only update group keys. This is used when sending - * publish keys between peers. - * @return SQL error code - */ - - int updateGroupKeys(const RsGxsGroupId& grpId,const RsTlvSecurityKeySet& keys, uint32_t subscribe_flags) override; - - void debug_printCacheSize() ; - -private: - - /*! - * Retrieves all the msg results from a cursor - * @param c cursor to result set - * @param msgs messages retrieved from cursor are stored here - */ - 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, int metaOffset); - - /*! - * Retrieves all the msg meta results from a cursor - * @param c cursor to result set - * @param msgMeta message metadata retrieved from cursor are stored here - */ - void locked_retrieveMsgMetaList(RetroCursor* c, std::vector > &msgMeta); - - /*! - * Retrieves all the grp meta results from a cursor - * @param c cursor to result set - * @param grpMeta group metadata retrieved from cursor are stored here - */ - void locked_retrieveGrpMetaList(RetroCursor *c, std::map > &grpMeta); - - /*! - * extracts a msg meta item from a cursor at its - * current position - */ - std::shared_ptr locked_getMsgMeta(RetroCursor& c, int colOffset); - - /*! - * extracts a grp meta item from a cursor at its - * current position - */ - std::shared_ptr locked_getGrpMeta(RetroCursor& c, int colOffset); - - /*! - * extracts a msg item from a cursor at its - * current position - */ - RsNxsMsg* locked_getMessage(RetroCursor& c); - - /*! - * extracts a grp item from a cursor at its - * current position - */ - RsNxsGrp* locked_getGroup(RetroCursor& c); - - /*! - * Creates an sql database and its associated file - * also creates the message and groups table - * @param isNewDatabase is new database - */ - void initialise(bool isNewDatabase); - - /*! - * Remove entries for data base - * @param msgIds - */ - bool locked_removeMessageEntries(const GxsMsgReq& msgIds); - bool locked_removeGroupEntries(const std::vector& grpIds); - -private: - /*! - * Start release update - * @param release - * @return true/false - */ - bool startReleaseUpdate(int release); - - /*! - * Finish release update - * @param release - * @param result - * @return true/false - */ - bool finishReleaseUpdate(int release, bool result); - -private: - - RsMutex mDbMutex; - - 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 - int mColMsgMeta_GrpId; - int mColMsgMeta_TimeStamp; - int mColMsgMeta_NxsFlags; - int mColMsgMeta_SignSet; - int mColMsgMeta_NxsIdentity; - int mColMsgMeta_NxsHash; - int mColMsgMeta_MsgId; - int mColMsgMeta_OrigMsgId; - int mColMsgMeta_MsgStatus; - int mColMsgMeta_ChildTs; - int mColMsgMeta_MsgParentId; - int mColMsgMeta_MsgThreadId; - int mColMsgMeta_Name; - int mColMsgMeta_NxsServString; - int mColMsgMeta_RecvTs; - int mColMsgMeta_NxsDataLen; - - // Message columns - int mColMsg_GrpId; - int mColMsg_NxsData; - int mColMsg_MetaData; - int mColMsg_MsgId; - - // Message columns with meta - int mColMsg_WithMetaOffset; - - // Group meta columns - int mColGrpMeta_GrpId; - int mColGrpMeta_TimeStamp; - int mColGrpMeta_NxsFlags; -// int mColGrpMeta_SignSet; - int mColGrpMeta_NxsIdentity; - int mColGrpMeta_NxsHash; - int mColGrpMeta_KeySet; - int mColGrpMeta_SubscrFlag; - int mColGrpMeta_Pop; - int mColGrpMeta_MsgCount; - int mColGrpMeta_Status; - int mColGrpMeta_Name; - int mColGrpMeta_LastPost; - int mColGrpMeta_OrigGrpId; - int mColGrpMeta_ServString; - int mColGrpMeta_SignFlags; - int mColGrpMeta_CircleId; - int mColGrpMeta_CircleType; - int mColGrpMeta_InternCircle; - int mColGrpMeta_Originator; - int mColGrpMeta_AuthenFlags; - int mColGrpMeta_ParentGrpId; - int mColGrpMeta_RecvTs; - int mColGrpMeta_RepCutoff; - int mColGrpMeta_NxsDataLen; - - // Group columns - int mColGrp_GrpId; - int mColGrp_NxsData; - int mColGrp_MetaData; - - // Group columns with meta - int mColGrp_WithMetaOffset; - - // Group id columns - int mColGrpId_GrpId; - - // Msg id columns - int mColMsgId_MsgId; - - std::string mServiceDir; - std::string mDbName; - std::string mDbPath; - uint16_t mServType; - - RetroDb* mDb; - - // used to store metadata instead of reading it from the database. - // The boolean variable below is also used to force re-reading when - // the entre list of grp metadata is requested (which happens quite often) - - void locked_clearGrpMetaCache(const RsGxsGroupId& gid); - void locked_updateGrpMetaCache(const RsGxsGrpMetaData& meta); - - t_MetaDataCache mGrpMetaDataCache; - std::map > mMsgMetaDataCache; - - bool mUseCache; -}; - -#endif // RSDATASERVICE_H diff --git a/libretroshare/src/gxs/rsgds.h b/libretroshare/src/gxs/rsgds.h deleted file mode 100644 index f4a3b0229..000000000 --- a/libretroshare/src/gxs/rsgds.h +++ /dev/null @@ -1,278 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgds.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie, Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include -#include -#include - -#include "inttypes.h" - -#include "rsitems/rsgxsitems.h" -#include "rsitems/rsnxsitems.h" -#include "gxs/rsgxsdata.h" -#include "rsgxs.h" -#include "rsgxsutil.h" -#include "util/contentvalue.h" - -class RsGxsSearchModule { - -public: - - virtual ~RsGxsSearchModule(); - - -}; - -/*! - * This allows modification of local - * meta data items of a message - */ -struct MsgLocMetaData { - MsgLocMetaData() = default; - MsgLocMetaData(const MsgLocMetaData& meta): msgId(meta.msgId), val(meta.val) {} - - RsGxsGrpMsgIdPair msgId; - ContentValue val; -}; - -/*! - * This allows modification of local - * meta data items of a group - */ -struct GrpLocMetaData { - GrpLocMetaData() = default; - GrpLocMetaData(const GrpLocMetaData& meta): grpId(meta.grpId), val(meta.val) {} - - RsGxsGroupId grpId; - ContentValue val; -}; - -/*! - * This is used to query network statistics for a given group. This is useful - * to e.g. show group popularity, or number of visible messages for unsubscribed - * group. - */ -struct RsGroupNetworkStats -{ - RsGroupNetworkStats() : - mSuppliers(0), mMaxVisibleCount(0), mGrpAutoSync(false), - mAllowMsgSync(false), mLastGroupModificationTS(0) {} - - uint32_t mSuppliers; - uint32_t mMaxVisibleCount; - bool mGrpAutoSync; - bool mAllowMsgSync; - rstime_t mLastGroupModificationTS; -}; - -typedef std::map > NxsMsgDataResult; -typedef std::map > NxsMsgRelatedDataResult; -typedef std::map > GxsMsgResult; // - -/*! - * The main role of GDS is the preparation and handing out of messages requested from - * RsGeneralExchangeService and RsGeneralExchangeService - * It is important to note that no actual messages are passed by this interface as its is expected - * architecturally to pass messages to the service via a call back - * - * It also acts as a layer between RsGeneralStorageService and its parent RsGeneralExchangeService - * thus allowing for non-blocking requests, etc. - * It also provides caching ability - * - * - * Caching feature: - * - A cache index should be maintained which is faster than normal message request - * - This should allow fast retrieval of message based on grp id or msg id - * - * Identity Exchange Service: - * - As this is the point where data is accessed by both the GNP and GXS the identities - * used to decrypt, encrypt and verify is handle here. - * - * Please note all function are blocking. - */ -class RsGeneralDataService -{ - -public: - - static const uint32_t GXS_MAX_ITEM_SIZE; - - static const std::string MSG_META_SERV_STRING; - static const std::string MSG_META_STATUS; - - static const std::string GRP_META_SUBSCRIBE_FLAG; - static const std::string GRP_META_STATUS; - static const std::string GRP_META_SERV_STRING; - static const std::string GRP_META_CUTOFF_LEVEL; - -public: - - typedef std::map GrpStoreMap; - typedef std::map MsgStoreMap; - - RsGeneralDataService(){} - virtual ~RsGeneralDataService(){} - - /*! - * Retrieves all msgs - * @param reqIds requested msg ids (grpId,msgId), leave msg list empty to get all msgs for the grp - * @param msg result of msg retrieval - * @param cache whether to store results of this retrieval in memory for faster later retrieval - * @param strictFilter if true do not request any message if reqIds is empty - * @return error code - */ - virtual int retrieveNxsMsgs( const GxsMsgReq& reqIds, GxsMsgResult& msg, bool withMeta = false ) = 0; - - /*! - * Retrieves all groups stored. Caller owns the memory and is supposed to delete the RsNxsGrp pointers after use. - * @param grp retrieved groups - * @param withMeta if true the meta handle of nxs grps is intitialised - * @param cache whether to store retrieval in mem for faster later retrieval - * @return error code - */ - virtual int retrieveNxsGrps(std::map& grp, bool withMeta) = 0; - - /*! - * Retrieves meta data of all groups stored (most current versions only) - * Memory is owned by the service, not the caller. Therefore the pointers in the temporary map - * shouldn't be destroyed. - * - * @param grp if null grpIds entries are made, only meta for those grpId are retrieved \n - * , if grpId is failed to be retrieved it will be erased from map - * @return error code - */ - virtual int retrieveGxsGrpMetaData(std::map >& grp) = 0; - - /*! - * Retrieves meta data of all groups stored (most current versions only) - * @param grpIds grpIds for which to retrieve meta data - * @param msgMeta meta data result as map of grpIds to array of metadata for that grpId - * @return error code - */ - virtual int retrieveGxsMsgMetaData(const GxsMsgReq& msgIds, GxsMsgMetaResult& msgMeta) = 0; - - /*! - * remove msgs in data store listed in msgIds param - * @param msgIds ids of messages to be removed - * @return error code - */ - virtual int removeMsgs(const GxsMsgReq& msgIds) = 0; - - /*! - * remove groups in data store listed in grpIds param - * @param grpIds ids of groups to be removed - * @return error code - */ - virtual int removeGroups(const std::vector& grpIds) = 0; - - /*! - * Retrieves all group ids in store - * @param grpIds all grpids in store is inserted into this vector - * @return error code - */ - virtual int retrieveGroupIds(std::vector& grpIds) = 0; - - /*! - * Retrives all msg ids in store - * @param grpId groupId of message ids to retrieve - * @param msgId msgsids retrieved - * @return error code - */ - virtual int retrieveMsgIds(const RsGxsGroupId& grpId, RsGxsMessageId::std_set& msgId) = 0; - - /*! - * @return the cache size set for this RsGeneralDataService in bytes - */ - virtual uint32_t cacheSize() const = 0; - - /*! - * \brief serviceType - * \return - * The service type for the current data service. - */ - virtual uint16_t serviceType() const = 0 ; - - /*! - * @param size size of cache to set in bytes - */ - virtual int setCacheSize(uint32_t size) = 0; - - /*! - * Stores a list of signed messages into data store - * @param msg map of message and decoded meta data information - * @return error code - */ - virtual int storeMessage(const std::list& msgs) = 0; - - /*! - * Stores a list of groups in data store - * @param grp map of group and decoded meta data - * @return error code - */ - virtual int storeGroup(const std::list& grsp) = 0; - - - /*! - * Updates group entries in Db - * @param grp map of group and decoded meta data - * @return error code - */ - virtual int updateGroup(const std::list& grsp) = 0; - - /*! - * @param metaData - */ - virtual int updateMessageMetaData(const MsgLocMetaData& metaData) = 0; - - /*! - * @param metaData - */ - virtual int updateGroupMetaData(const GrpLocMetaData& meta) = 0; - - virtual int updateGroupKeys(const RsGxsGroupId& grpId,const RsTlvSecurityKeySet& keys,uint32_t subscribed_flags) = 0 ; - - /*! - * Completely clear out data stored in - * and returns this to a state - * as it was when first constructed - */ - virtual int resetDataStore() = 0; - - /*! - * Use to determine if message isn't over the storage - * limit for a single message item - * @param msg the message to check size validity - * @return whether the size of of msg is valid - */ - virtual bool validSize(RsNxsMsg* msg) const = 0 ; - - /*! - * Use to determine if group isn't over the storage limit - * for a single group item - * @param grp the group to check size validity - * @return whether the size of grp is valid for storage - */ - virtual bool validSize(RsNxsGrp* grp) const = 0 ; - -}; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc deleted file mode 100644 index 5ddb0be26..000000000 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ /dev/null @@ -1,3739 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgenexchange.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Christopher Evi-Parker * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -#include "pqi/pqihash.h" -#include "rsgenexchange.h" -#include "gxssecurity.h" -#include "util/contentvalue.h" -#include "util/rsprint.h" -#include "util/rstime.h" -#include "retroshare/rsgxsflags.h" -#include "retroshare/rsgxscircles.h" -#include "retroshare/rsgrouter.h" -#include "retroshare/rsidentity.h" -#include "retroshare/rspeers.h" -#include "rsitems/rsnxsitems.h" -#include "rsgixs.h" -#include "rsgxsutil.h" -#include "rsserver/p3face.h" -#include "retroshare/rsevents.h" -#include "util/radix64.h" - -#define PUB_GRP_MASK 0x000f -#define RESTR_GRP_MASK 0x00f0 -#define PRIV_GRP_MASK 0x0f00 -#define GRP_OPTIONS_MASK 0xf000 - -#define PUB_GRP_OFFSET 0 -#define RESTR_GRP_OFFSET 8 -#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 - -static const uint32_t MSG_CLEANUP_PERIOD = 60*59; // 59 minutes -static const uint32_t INTEGRITY_CHECK_PERIOD = 60*31; // 31 minutes - -#define GXS_MASK "GXS_MASK_HACK" - -/* - * #define GEN_EXCH_DEBUG 1 - */ - -#if defined(GEN_EXCH_DEBUG) -static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_FORUMS;// use this to allow to this service id only, or 0 for all services - // warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums) -class nullstream: public std::ostream {}; - -// static std::string nice_time_stamp(rstime_t now,rstime_t TS) -// { -// if(TS == 0) -// return "Never" ; -// else -// { -// std::ostringstream s; -// s << now - TS << " secs ago" ; -// return s.str() ; -// } -// } - -static std::ostream& gxsgenexchangedebug(uint32_t service_type) -{ - static nullstream null ; - - if (service_to_print==0 || service_type == 0 || (service_type == service_to_print)) - return std::cerr << time(NULL) << ":RSGENEXCHANGE service " << std::hex << service_type << std::dec << ": " ; - else - return null ; -} - -#define GXSGENEXCHANGEDEBUG gxsgenexchangedebug(serviceType()) - -#endif - -// Data flow in RsGenExchange -// -// publishGroup() -// | -// +--- stores in mGrpsToPublish -// -// updateGroup() -// | -// +--- stores in mGroupUpdatePublish -// -// tick() -// | -// +--- processRecvdData(); -// | | -// | +-- processRecvdGroups(); -// | | | -// | | +---- mGroupPendingValidate -// | | | -// | | +---- acceptance => validateGrp() => check existance => store in mGroupUpdates -// | | | -// | | +--- validateNxsGrp() -// | | -// | +-- processRecvdMessages(); -// | | -// | +-- performUpdateValidation(); // validates group updates in mGroupUpdates received from friends -// | | -// | +---- mGroupUpdates => updateValid() => store new groups -// | | | -// | | +--- stamp keys, check admin keys are the same, validateNxsGrp() -// | | | -// | +---- stores RsGxsGroupChange in mNotifications +--- data signature check -// | -// +--- publishGrps(); // creates signatures and data for locally created groups -// | | -// | +-- reads mGrpsToPublish, creates the group, clears mGrpsToPublish -// | | -// | +--- generateGroupKeys() -// | | -// | +--- serviceCreateGroup() -// | | -// | +--- createGroup() -// | | -// | +--- createGroupSignatures() -// | -// +--- processGroupUpdatePublish(); // goes through list of group updates to perform locally -// | | -// | +-- reads/deletes mGroupUpdatePublish, stores in mGrpsToPublish -// | -// +--- processGrpMetaChanges(); -// | | -// | +-- updates mNotifications, calls mDataAccess -// | -// +--- processGroupDelete(); -// | -// +--- publishMsgs(); -// | -// +--- processMsgMetaChanges(); -// | | -// | +-- updates mNotifications, calls mDataAccess -// | -// +--- processMessageDelete(); -// | -// +--- mDataAccess->processRequests(); -// | -// +--- processRoutingClues() ; -// - -RsGenExchange::RsGenExchange( - RsGeneralDataService* gds, RsNetworkExchangeService* ns, - RsSerialType* serviceSerialiser, uint16_t servType, RsGixs* gixs, - uint32_t authenPolicy ) : - mGenMtx("GenExchange"), - mDataStore(gds), - mNetService(ns), - mSerialiser(serviceSerialiser), - mServType(servType), - mGixs(gixs), - mAuthenPolicy(authenPolicy), - mCleaning(false), - mLastClean((int)time(NULL) - (int)(RSRandom::random_u32() % MSG_CLEANUP_PERIOD)), // this helps unsynchronising the checks for the different services - mChecking(false), - mCheckStarted(false), - mLastCheck((int)time(NULL) - (int)(RSRandom::random_u32() % INTEGRITY_CHECK_PERIOD) + 120), // this helps unsynchronising the checks for the different services, with 2 min security to avoid checking right away before statistics come up. - mIntegrityCheck(NULL), - SIGN_MAX_WAITING_TIME(60), - SIGN_FAIL(0), - SIGN_SUCCESS(1), - SIGN_FAIL_TRY_LATER(2), - VALIDATE_FAIL(0), - VALIDATE_SUCCESS(1), - VALIDATE_FAIL_TRY_LATER(2), - VALIDATE_MAX_WAITING_TIME(60) -{ - mDataAccess = new RsGxsDataAccess(gds); - - // Perform an early checking/cleaning of the db. Will eliminate groups and messages that do not match their hash - -#ifdef RS_DEEP_CHANNEL_INDEX - // This code is only called because it of deep indexing in channels. But loading - // the entire set of messages in order to provide indexing is pretty bad (very costly and slowly - // eats memory, as many tests have shown. Not because of leaks, but because new threads are - // apparently attributed large stacks and pages of memory are not regained by the system maybe because it thinks - // that RS will use them again. - // - // * the deep check should be implemented differently, in an incremental way. For instance in notifyChanges() of each - // service (e.g. channels here) should update the index when a new message is received. The question to how old messages - // are processed is open. I believe that they shouldn't. New users will progressively process them. - // - // * integrity check (re-hashing of message data) is not needed. Message signature already ensures that all messages received are - // unalterated. The only problem (possibly very rare) is that a message is locally corrupted and not deleted (because of no check). - // It will therefore never be replaced by the correct one from friends. The cost of re-hashing the whole db data regularly - // doesn't counterbalance such a low risk. - // - if(mServType == RS_SERVICE_GXS_TYPE_CHANNELS) - { - std::vector grpsToDel; - GxsMsgReq msgsToDel; - - RsGxsSinglePassIntegrityCheck::check(mServType,mGixs,mDataStore, - this, *mSerialiser, - grpsToDel,msgsToDel); - - for(auto& grpId: grpsToDel) - { - uint32_t token2=0; - deleteGroup(token2,grpId); - } - - if(!msgsToDel.empty()) - { - uint32_t token1=0; - deleteMsgs(token1,msgsToDel); - } - } -#endif -} - -void RsGenExchange::setNetworkExchangeService(RsNetworkExchangeService *ns) -{ - if(mNetService != NULL) - std::cerr << "(EE) Cannot override existing network exchange service. Make sure it has been deleted otherwise." << std::endl; - else - mNetService = ns ; -} - -RsGenExchange::~RsGenExchange() -{ - // need to destruct in a certain order (bad thing, TODO: put down instance ownership rules!) - delete mNetService; - - delete mDataAccess; - mDataAccess = NULL; - - delete mDataStore; - mDataStore = NULL; - - for(uint32_t i=0;igetGroupServerUpdateTS(gid,grp_server_update_TS,msg_server_update_TS) ; -} - -void RsGenExchange::threadTick() -{ - static const double timeDelta = 0.1; // slow tick in sec - - tick(); - rstime::rs_usleep((int) (timeDelta * 1000 *1000)); // timeDelta sec -} - -void RsGenExchange::tick() -{ - // Meta Changes should happen first. - // This is important, as services want to change Meta, then get results. - // Services shouldn't rely on this ordering - but some do. - processGrpMetaChanges(); - processMsgMetaChanges(); - - mDataAccess->processRequests(); - - publishGrps(); - - publishMsgs(); - - processGroupUpdatePublish(); - - processGroupDelete(); - processMessageDelete(); - - processRecvdData(); - - processRoutingClues() ; - - { - std::vector mNotifications_copy; - - // make a non-deep copy of mNotifications so that it can be passed off-mutex to notifyChanged() - // that will delete it. The potential high cost of notifyChanges() makes it preferable to call off-mutex. - { - RS_STACK_MUTEX(mGenMtx); - if(!mNotifications.empty()) - { - mNotifications_copy = mNotifications; - mNotifications.clear(); - } - } - - // Calling notifyChanges() calls back RsGxsIfaceHelper::receiveChanges() that deletes the pointers in the array - // and the array itself. This is pretty bad and we should normally delete the changes here. - - if(!mNotifications_copy.empty()) - notifyChanges(mNotifications_copy); - } - - // implemented service tick function - service_tick(); - - rstime_t now = time(NULL); - - // Cleanup unused data. This is only needed when auto-synchronization is needed, which is not the case - // of identities. This is why idendities do their own cleaning. - now = time(NULL); - - if( (mNetService && (mNetService->msgAutoSync() || mNetService->grpAutoSync())) && (mLastClean + MSG_CLEANUP_PERIOD < now) ) - { - GxsMsgReq msgs_to_delete; - std::vector grps_to_delete; - - RsGxsCleanUp(mDataStore,this,1).clean(mNextGroupToCheck,grps_to_delete,msgs_to_delete); // no need to lock here, because all access below (RsGenExchange, RsDataStore) are properly mutexed - - uint32_t token1=0; - deleteMsgs(token1,msgs_to_delete); - - for(auto& grpId: grps_to_delete) - { - uint32_t token2=0; - deleteGroup(token2,grpId); - } - - RS_STACK_MUTEX(mGenMtx) ; - mLastClean = now; - } - - if(mChecking || (mLastCheck + INTEGRITY_CHECK_PERIOD < now)) - { - mLastCheck = time(NULL); - - { - RS_STACK_MUTEX(mGenMtx) ; - - if(!mIntegrityCheck) - { - mIntegrityCheck = new RsGxsIntegrityCheck( mDataStore, this, - *mSerialiser, mGixs); - mIntegrityCheck->start("gxs integrity"); - mChecking = true; - } - } - - if(mIntegrityCheck->isDone()) - { - std::vector grpIds; - GxsMsgReq msgIds; - - { - RS_STACK_MUTEX(mGenMtx) ; - mIntegrityCheck->getDeletedIds(grpIds, msgIds); - } - - if(!msgIds.empty()) - { - uint32_t token1=0; - deleteMsgs(token1,msgIds); - } - - if(!grpIds.empty()) - for(auto& grpId: grpIds) - { - uint32_t token2=0; - deleteGroup(token2,grpId); - } - - { - RS_STACK_MUTEX(mGenMtx) ; - delete mIntegrityCheck; - mIntegrityCheck = NULL; - mChecking = false; - } - } - } -} - -bool RsGenExchange::messagePublicationTest(const RsGxsMsgMetaData& meta) -{ - if(!mNetService) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "(EE) No network service in service " << std::hex << serviceType() << std::dec << ": cannot read message storage time." << std::endl; -#endif - return false ; - } - - uint32_t st = mNetService->getKeepAge(meta.mGroupId); - - rstime_t storageTimeLimit = meta.mPublishTs + st; - - return meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER || st == 0 || storageTimeLimit >= time(NULL); -} - -bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId) -{ - RS_STACK_MUTEX(mGenMtx) ; - -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "RsGenExchange::acknowledgeTokenMsg(). token=" << token << std::endl; -#endif - std::map::iterator mit = mMsgNotify.find(token); - - if(mit == mMsgNotify.end()) - { -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << " no notification found for this token." << std::endl; -#endif - return false; - } - - - msgId = mit->second; - - // no dump token as client has ackowledged its completion - mDataAccess->disposeOfPublicToken(token); - mMsgNotify.erase(mit); - -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << " found grpId=" << msgId.first <<", msgId=" << msgId.second << " disposing token from mDataAccess" << std::endl; -#endif - return true; -} - - - -bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mGenMtx) ; - -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "RsGenExchange::acknowledgeTokenGrp(). token=" << token << std::endl; -#endif - std::map::iterator mit = mGrpNotify.find(token); - - if(mit == mGrpNotify.end()) - { -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << " no notification found for this token." << std::endl; -#endif - return false; - } - - grpId = mit->second; - - // no dump token as client has ackowledged its completion - mDataAccess->disposeOfPublicToken(token); - mGrpNotify.erase(mit); - -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << " found grpId=" << grpId << ". Disposing token from mDataAccess" << std::endl; -#endif - return true; -} - -void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys) -{ - /* create Keys */ - RsTlvPublicRSAKey pubAdminKey ; - RsTlvPrivateRSAKey privAdminKey; - - GxsSecurity::generateKeyPair(pubAdminKey,privAdminKey) ; - - // for now all public - pubAdminKey.keyFlags |= RSTLV_KEY_DISTRIB_ADMIN ; - privAdminKey.keyFlags |= RSTLV_KEY_DISTRIB_ADMIN ; - - keySet.public_keys[pubAdminKey.keyId] = pubAdminKey; - keySet.private_keys[privAdminKey.keyId] = privAdminKey; - - if(genPublishKeys) - { - /* set publish keys */ - RsTlvPublicRSAKey pubPublishKey ; - RsTlvPrivateRSAKey privPublishKey; - - GxsSecurity::generateKeyPair(pubPublishKey,privPublishKey) ; - - // for now all public - pubPublishKey.keyFlags |= RSTLV_KEY_DISTRIB_PUBLISH ; - privPublishKey.keyFlags |= RSTLV_KEY_DISTRIB_PUBLISH ; - - keySet.public_keys[pubPublishKey.keyId] = pubPublishKey; - keySet.private_keys[privPublishKey.keyId] = privPublishKey; - } -} - -uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) -{ -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "RsGenExchange::createGroup()"<< std::endl; -#endif - - RsGxsGrpMetaData* meta = grp->metaData; - - /* add public admin and publish keys to grp */ - - // find private admin key - RsTlvPrivateRSAKey privAdminKey; - bool privKeyFound = false; // private admin key - - for( std::map::iterator mit = keySet.private_keys.begin(); mit != keySet.private_keys.end(); ++mit) - { - RsTlvPrivateRSAKey& key = mit->second; - - if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL)) - { - privAdminKey = key; - privKeyFound = true; - break ; - } - } - - if(!privKeyFound) - { - std::cerr << "RsGenExchange::createGroup() Missing private ADMIN Key" << std::endl; - - return false; - } - - // only public keys are included to be transported. The 2nd line below is very important. - - meta->keys = keySet; - meta->keys.private_keys.clear() ; - - // group is self signing - // for the creation of group signature - // only public admin and publish keys are present in meta - uint32_t metaDataLen = meta->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); - uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; - - char* metaData = new char[metaDataLen]; - char* allGrpData = new char[allGrpDataLen]; // msgData + metaData - - meta->serialise(metaData, metaDataLen,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); - - // copy msg data and meta in allMsgData buffer - memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len); - memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen); - - RsTlvKeySignature adminSign; - bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, privAdminKey, adminSign); - - // add admin sign to grpMeta - meta->signSet.keySignSet[INDEX_AUTHEN_ADMIN] = adminSign; - - RsTlvBinaryData grpData(mServType); - grpData.setBinData(allGrpData, allGrpDataLen); - - uint8_t ret = createGroupSignatures(meta->signSet, grpData, *(grp->metaData)); - - // clean up - delete[] allGrpData; - delete[] metaData; - - if (!ok) - { - std::cerr << "RsGenExchange::createGroup() ERROR !okay (getSignature error)" << std::endl; - return CREATE_FAIL; - } - - if(ret == SIGN_FAIL) - { - return CREATE_FAIL; - }else if(ret == SIGN_FAIL_TRY_LATER) - { - return CREATE_FAIL_TRY_LATER; - }else if(ret == SIGN_SUCCESS) - { - return CREATE_SUCCESS; - }else{ - return CREATE_FAIL; - } -} - -int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& grpData, - RsGxsGrpMetaData& grpMeta) -{ - bool needIdentitySign = false; - int id_ret; - - uint8_t author_flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; - - PrivacyBitPos pos = GRP_OPTION_BITS; - - // Check required permissions, and allow them to sign it - if they want too - as well! - if ((!grpMeta.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag)) - { - needIdentitySign = true; -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "Needs Identity sign! (Service Flags)"<< std::endl; -#endif - } - - if (needIdentitySign) - { - if(grpMeta.mAuthorId.isNull()) - { - std::cerr << "RsGenExchange::createGroupSignatures() "; - std::cerr << "Group signature is required by service, but the author id is null." << std::endl; - id_ret = SIGN_FAIL; - } - else if(mGixs) - { - bool haveKey = mGixs->havePrivateKey(grpMeta.mAuthorId); - - if(haveKey) - { - RsTlvPrivateRSAKey authorKey; - mGixs->getPrivateKey(grpMeta.mAuthorId, authorKey); - RsTlvKeySignature sign; - - if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len, authorKey, sign)) - { - id_ret = SIGN_SUCCESS; - mGixs->timeStampKey(grpMeta.mAuthorId,RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::GROUP_AUTHOR_SIGNATURE_CREATION,grpMeta.mGroupId)) ; - signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; - } - else - id_ret = SIGN_FAIL; - } - 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; - } - } - else - { - id_ret = SIGN_SUCCESS; - } - - return id_ret; -} - -int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, - const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta) -{ - bool needPublishSign = false, needIdentitySign = false; - uint32_t grpFlag = grpMeta.mGroupFlags; - - bool publishSignSuccess = false; - -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "RsGenExchange::createMsgSignatures() for Msg.mMsgName: " << msgMeta.mMsgName<< std::endl; -#endif - - - // publish signature is determined by whether group is public or not - // for private group signature is not needed as it needs decrypting with - // the private publish key anyways - - // restricted is a special case which heeds whether publish sign needs to be checked or not - // one may or may not want - - uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; - uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN; - - if(!msgMeta.mParentId.isNull()) - { - // Child Message. - author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - } - - PrivacyBitPos pos = PUBLIC_GRP_BITS; - if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) - { - pos = RESTRICTED_GRP_BITS; - } - else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) - { - pos = PRIVATE_GRP_BITS; - } - - needIdentitySign = false; - needPublishSign = false; - if (checkAuthenFlag(pos, publish_flag)) - { - needPublishSign = true; -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "Needs Publish sign! (Service Flags)"<< 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 - GXSGENEXCHANGEDEBUG << "Needs Identity sign! (Service Flags)"<< std::endl; -#endif - } - - if (!msgMeta.mAuthorId.isNull()) - { - needIdentitySign = true; -#ifdef GEN_EXCH_DEBUG - GXSGENEXCHANGEDEBUG << "Needs Identity sign! (AuthorId Exists)"<< std::endl; -#endif - } - - if(needPublishSign) - { - // public and shared is publish key - const RsTlvSecurityKeySet& keys = grpMeta.keys; - const RsTlvPrivateRSAKey *publishKey; - - std::map::const_iterator mit = keys.private_keys.begin(), mit_end = keys.private_keys.end(); - bool publish_key_found = false; - - for(; mit != mit_end; ++mit) - { - - publish_key_found = mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_FULL); - if(publish_key_found) - break; - } - - if (publish_key_found) - { - // private publish key - publishKey = &(mit->second); - - 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[INDEX_AUTHEN_PUBLISH] = publishSign; - }else - { - std::cerr << "RsGenExchange::createMsgSignatures()"; - std::cerr << " ERROR Cannot find PUBLISH KEY for Message Signing!"; - std::cerr << " ERROR Publish Sign failed!"; - std::cerr << std::endl; - } - - } - else // publish sign not needed so set as successful - { - publishSignSuccess = true; - } - - int id_ret; - - if (needIdentitySign) - { - if(mGixs) - { - bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId); - - if(haveKey) - { - RsTlvPrivateRSAKey authorKey; - mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey); - RsTlvKeySignature sign; - - if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, authorKey, sign)) - { - id_ret = SIGN_SUCCESS; - mGixs->timeStampKey(msgMeta.mAuthorId,RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::MESSAGE_AUTHOR_SIGNATURE_CREATION,msgMeta.mGroupId,msgMeta.mMsgId,msgMeta.mParentId,msgMeta.mThreadId)) ; - signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; - } - else - id_ret = SIGN_FAIL; - } - 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; - } - } - else - { - id_ret = SIGN_SUCCESS; - } - - if(publishSignSuccess) - { - return id_ret; - } - else - { - return SIGN_FAIL; - } -} - -int RsGenExchange::createMessage(RsNxsMsg* msg) -{ - const RsGxsGroupId& id = msg->grpId; - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::createMessage() " << std::endl; -#endif - RsGxsGrpMetaTemporaryMap metaMap ; - metaMap[id] = std::make_shared(); - mDataStore->retrieveGxsGrpMetaData(metaMap); - - RsGxsMsgMetaData &meta = *(msg->metaData); - - int ret_val; - - if(!metaMap[id]) - { - return CREATE_FAIL; - } - else - { - // get publish key - const auto& grpMeta = metaMap[id]; - - uint32_t metaDataLen = meta.serial_size(); - uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; - - RsTemporaryMemory metaData(metaDataLen); - RsTemporaryMemory allMsgData(allMsgDataLen); - - meta.serialise(metaData, &metaDataLen); - - // copy msg data and meta in allmsgData buffer - memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); - memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); - - RsTlvBinaryData msgData(0); - - msgData.setBinData(allMsgData, allMsgDataLen); - - // create signatures - ret_val = createMsgSignatures(meta.signSet, msgData, meta, *grpMeta); - - - // get hash of msg data to create msg id - pqihash hash; - hash.addData(allMsgData, allMsgDataLen); - RsFileHash hashId; - hash.Complete(hashId); - msg->msgId = RsGxsMessageId(hashId); - - // assign msg id to msg meta - msg->metaData->mMsgId = msg->msgId; - } - - if(ret_val == SIGN_FAIL) - return CREATE_FAIL; - else if(ret_val == SIGN_FAIL_TRY_LATER) - return CREATE_FAIL_TRY_LATER; - else if(ret_val == SIGN_SUCCESS) - return CREATE_SUCCESS; - else - { - std::cerr << "Unknown return value from signature attempt!"; - return CREATE_FAIL; - } -} - -int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uint32_t& /*signFlag*/, RsTlvSecurityKeySet& grpKeySet) -{ - bool needIdentitySign = false; - bool needPublishSign = false; - bool publishValidate = true, idValidate = true; - - uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; - uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN; - - if(!msg->metaData->mParentId.isNull()) - { - // Child Message. - author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - } - - PrivacyBitPos pos = PUBLIC_GRP_BITS; - if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) - { - pos = RESTRICTED_GRP_BITS; - } - else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) - { - pos = PRIVATE_GRP_BITS; - } - - if (checkAuthenFlag(pos, publish_flag)) - needPublishSign = true; - - // Check required permissions, if they have signed it anyway - we need to validate it. - 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[INDEX_AUTHEN_PUBLISH]; - - std::map& keys = grpKeySet.public_keys; - std::map::iterator mit = keys.begin(); - - RsGxsId keyId; - for(; mit != keys.end() ; ++mit) - { - RsTlvPublicRSAKey& key = mit->second; - - if(key.keyFlags & RSTLV_KEY_DISTRIB_PUBLIC_deprecated) - { - keyId = key.keyId; - std::cerr << "WARNING: old style publish key with flags " << key.keyFlags << std::endl; - std::cerr << " this cannot be fixed, but RS will deal with it." << std::endl; - break ; - } - if(key.keyFlags & RSTLV_KEY_DISTRIB_PUBLISH) // we might have the private key, but we still should be able to check the signature - { - keyId = key.keyId; - break; - } - } - - if(!keyId.isNull()) - { - RsTlvPublicRSAKey& key = keys[keyId]; - publishValidate &= GxsSecurity::validateNxsMsg(*msg, sign, key); - } - else - { - std::cerr << "(EE) public publish key not found in group that require publish key validation. This should not happen! msgId=" << metaData.mMsgId << ", grpId=" << metaData.mGroupId << std::endl; - std::cerr << "(EE) public keys available for this group are: " << std::endl; - - for(std::map::const_iterator it(grpKeySet.public_keys.begin());it!=grpKeySet.public_keys.end();++it) - std::cerr << "(EE) " << it->first << std::endl; - - std::cerr << "(EE) private keys available for this group are: " << std::endl; - - for(std::map::const_iterator it(grpKeySet.private_keys.begin());it!=grpKeySet.private_keys.end();++it) - std::cerr << "(EE) " << it->first << std::endl; - - publishValidate = false; - } - } - else - { - publishValidate = true; - } - - - - if(needIdentitySign) - { - if(mGixs) - { - bool haveKey = mGixs->haveKey(metaData.mAuthorId); - - if(haveKey) - { - - RsTlvPublicRSAKey authorKey; - bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; - - if (auth_key_fetched) - { - RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; - idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - mGixs->timeStampKey(metaData.mAuthorId,RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::MESSAGE_AUTHOR_SIGNATURE_VALIDATION, - metaData.mGroupId, - metaData.mMsgId, - metaData.mParentId, - metaData.mThreadId)) ; - } - 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. The reputation will need to be at least as high as this value for the msg to validate. - // At validation step, we accept all messages, except the ones signed by locally rejected identities. - - if( details.mReputation.mOverallReputationLevel == - RsReputationLevel::LOCALLY_NEGATIVE ) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl; -#endif - idValidate = false ; - } - } - - } - } - else - { - std::list peers; - peers.push_back(msg->PeerId()); - mGixs->requestKey(metaData.mAuthorId, peers, RsIdentityUsage((RsServiceType)serviceType(), - RsIdentityUsage::MESSAGE_AUTHOR_SIGNATURE_VALIDATION, - metaData.mGroupId, - metaData.mMsgId, - metaData.mParentId, - metaData.mThreadId)); - -#ifdef GEN_EXCH_DEBUG - std::cerr << ", Key missing. Retry later." << std::endl; -#endif - return VALIDATE_FAIL_TRY_LATER; - } - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; -#endif - idValidate = false; - } - } - else - { - 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 - return VALIDATE_FAIL; - -} - -int RsGenExchange::validateGrp(RsNxsGrp* grp) -{ - bool needIdentitySign = false, idValidate = false; - RsGxsGrpMetaData& metaData = *(grp->metaData); - - uint8_t author_flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; - - PrivacyBitPos pos = GRP_OPTION_BITS; - -#ifdef GEN_EXCH_DEBUG - std::cerr << "Validating group " << grp->grpId << ", authorId = " << metaData.mAuthorId << std::endl; -#endif - // Check required permissions, and allow them to sign it - if they want too - as well! - if ((!metaData.mAuthorId.isNull()) || checkAuthenFlag(pos, author_flag)) - { - needIdentitySign = true; -#ifdef GEN_EXCH_DEBUG - std::cerr << " Needs Identity sign! (Service Flags). Identity signing key is " << metaData.mAuthorId << std::endl; -#endif - } - - if(needIdentitySign) - { - if(mGixs) - { - bool haveKey = mGixs->haveKey(metaData.mAuthorId); - - if(haveKey) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " have ID key in cache: yes" << std::endl; -#endif - - RsTlvPublicRSAKey authorKey; - bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) ; - - if (auth_key_fetched) - { - - RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; - idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " key ID validation result: " << idValidate << std::endl; -#endif - mGixs->timeStampKey(metaData.mAuthorId,RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::GROUP_AUTHOR_SIGNATURE_VALIDATION,metaData.mGroupId)); - } - else - { - std::cerr << "RsGenExchange::validateGrp()"; - std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Group Sign Validation"; - std::cerr << std::endl; - idValidate = false; - } - - }else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " have key in cache: no. Return VALIDATE_LATER" << std::endl; - std::cerr << " requesting key " << metaData.mAuthorId << " to origin peer " << grp->PeerId() << std::endl; -#endif - std::list peers; - peers.push_back(grp->PeerId()); - mGixs->requestKey(metaData.mAuthorId, peers,RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::GROUP_AUTHOR_SIGNATURE_VALIDATION,metaData.mGroupId)); - return VALIDATE_FAIL_TRY_LATER; - } - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " (EE) Gixs not enabled while request identity signature validation!" << std::endl; -#endif - idValidate = false; - } - } - else - { - idValidate = true; - } - - if(idValidate) - return VALIDATE_SUCCESS; - else - return VALIDATE_FAIL; - -} - -bool RsGenExchange::checkAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const -{ -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::checkMsgAuthenFlag(pos: " << pos << " flag: "; - std::cerr << (int) flag << " mAuthenPolicy: " << mAuthenPolicy << ")"; - std::cerr << std::endl; -#endif - - switch(pos) - { - case PUBLIC_GRP_BITS: - return mAuthenPolicy & flag; - break; - case RESTRICTED_GRP_BITS: - return flag & (mAuthenPolicy >> RESTR_GRP_OFFSET); - break; - case PRIVATE_GRP_BITS: - return flag & (mAuthenPolicy >> PRIV_GRP_OFFSET); - break; - case GRP_OPTION_BITS: - return flag & (mAuthenPolicy >> GRP_OPTIONS_OFFSET); - break; - default: - std::cerr << "pos option not recognised"; - return false; - } -} - -static void addMessageChanged(std::map > &msgs, const std::map > &msgChanged) -{ - if (msgs.empty()) { - msgs = msgChanged; - } else { - for (auto mapIt = msgChanged.begin(); mapIt != msgChanged.end(); ++mapIt) - { - const RsGxsGroupId &grpId = mapIt->first; - const std::set &srcMsgIds = mapIt->second; - std::set &destMsgIds = msgs[grpId]; - - for (auto msgIt = srcMsgIds.begin(); msgIt != srcMsgIds.end(); ++msgIt) - destMsgIds.insert(*msgIt) ; - } - } -} - -#ifdef TO_REMOVE -void RsGenExchange::receiveChanges(std::vector& changes) -{ - std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl; -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::receiveChanges()" << std::endl; -#endif - std::unique_ptr evt(new RsGxsChanges); - evt->mServiceType = static_cast(mServType); - - RsGxsChanges& out = *evt; - out.mService = getTokenService(); - - // collect all changes in one GxsChanges object - std::vector::iterator vit = changes.begin(); - for(; vit != changes.end(); ++vit) - { - RsGxsNotify* n = *vit; - RsGxsGroupChange* gc; - RsGxsMsgChange* mc; - RsGxsDistantSearchResultChange *gt; - - if((mc = dynamic_cast(n)) != nullptr) - { - if (mc->metaChange()) - addMessageChanged(out.mMsgsMeta, mc->msgChangeMap); - else - addMessageChanged(out.mMsgs, mc->msgChangeMap); - } - else if((gc = dynamic_cast(n)) != nullptr) - { - if(gc->metaChange()) - out.mGrpsMeta.splice(out.mGrpsMeta.end(), gc->mGrpIdList); - else - out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList); - } - else if(( gt = dynamic_cast(n) ) != nullptr) - out.mDistantSearchReqs.push_back(gt->mRequestId); - else - RsErr() << __PRETTY_FUNCTION__ << " Unknown changes type!" << std::endl; - delete n; - } - changes.clear() ; - - if(rsEvents) rsEvents->postEvent(std::move(evt)); -} -#endif - -bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) -{ - if(subscribe) - setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, - (GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED)); - else - setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED, - (GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED)); - - if(mNetService) mNetService->subscribeStatusChanged(grpId,subscribe); -#ifdef GEN_EXCH_DEBUG - else - std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl; -#endif - - return true; -} - -bool RsGenExchange::getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) -{ - return mDataAccess->getGroupStatistic(token, stats); -} - -bool RsGenExchange::getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) -{ - return mDataAccess->getServiceStatistic(token, stats); -} - -bool RsGenExchange::getGroupList(const uint32_t &token, std::list &groupIds) -{ - return mDataAccess->getGroupList(token, groupIds); - -} - -bool RsGenExchange::getMsgList(const uint32_t &token, - GxsMsgIdResult &msgIds) -{ - return mDataAccess->getMsgIdList(token, msgIds); -} - -bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) -{ - return mDataAccess->getMsgRelatedList(token, msgIds); -} -bool RsGenExchange::getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta) -{ - auto it = mPublishedMsgs.find(token); - - if(it == mPublishedMsgs.end()) - return false ; - - meta = it->second; - return true; -} -bool RsGenExchange::getPublishedGroupMeta(const uint32_t& token,RsGroupMetaData& meta) -{ - auto it = mPublishedGrps.find(token); - - if(it == mPublishedGrps.end()) - return false ; - - meta = it->second; - return true; -} - -bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list &groupInfo) -{ - std::list > metaL; - bool ok = mDataAccess->getGroupSummary(token, metaL); - - for( auto lit = metaL.begin(); lit != metaL.end(); ++lit) - { - const RsGxsGrpMetaData& gMeta = *(*lit); - - RsGroupMetaData m(gMeta); - RsGroupNetworkStats sts ; - - if(mNetService != NULL && mNetService->getGroupNetworkStats(gMeta.mGroupId,sts)) - { - m.mPop = sts.mSuppliers ; - m.mVisibleMsgCount = sts.mMaxVisibleCount ; - - if((!(IS_GROUP_SUBSCRIBED(gMeta.mSubscribeFlags))) || gMeta.mLastPost == 0) - m.mLastPost = sts.mLastGroupModificationTS ; - } - else - { - m.mPop= 0 ; - m.mVisibleMsgCount = 0 ; - } - - // We could save this in the net service, but it's a bit more than that since some services have - // specific usage footprints for their groups. - - m.mLastSeen = (IS_GROUP_SUBSCRIBED(gMeta.mSubscribeFlags)) ? time(nullptr) : service_getLastGroupSeenTs(gMeta.mGroupId); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "Group: " << gMeta.mGroupId << " name \"" << gMeta.mGroupName << "\" last seen=" << m.mLastSeen << " now=" << time(nullptr) << std::endl; -#endif - - groupInfo.push_back(m); - } - - return ok; -} - -bool RsGenExchange::getMsgMeta(const uint32_t &token, - GxsMsgMetaMap &msgInfo) -{ -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::getMsgMeta(): retrieving meta data for token " << token << std::endl; -#endif - //std::list metaL; - GxsMsgMetaResult result; - bool ok = mDataAccess->getMsgSummary(token, result); - - for(auto mit=result.begin(); mit != result.end(); ++mit) - { - auto& metaV = mit->second; - - std::vector& msgInfoV = msgInfo[mit->first]; - - RsMsgMetaData meta; - for(auto vit=metaV.begin(); vit != metaV.end(); ++vit) - msgInfoV.push_back(RsMsgMetaData(*(*vit))); - } - - return ok; -} - -bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap &msgMeta) -{ - MsgRelatedMetaResult result; - bool ok = mDataAccess->getMsgRelatedSummary(token, result); - - MsgRelatedMetaResult::iterator mit = result.begin(); - - for(; mit != result.end(); ++mit) - { - auto& metaV = mit->second; - - std::vector& msgInfoV = msgMeta[mit->first]; - - for(auto vit=metaV.begin(); vit != metaV.end(); ++vit) - msgInfoV.push_back(RsMsgMetaData(*(*vit))); - } - - return ok; -} - -bool RsGenExchange::getSerializedGroupData(uint32_t token, RsGxsGroupId& id, - unsigned char *& data, - uint32_t& size) -{ - RS_STACK_MUTEX(mGenMtx) ; - - std::list nxsGrps; - - if(!mDataAccess->getGroupData(token, nxsGrps)) - return false ; - - if(nxsGrps.size() != 1) - { - std::cerr << "(EE) getSerializedGroupData() got multiple groups in single request. This is unexpected." << std::endl; - - for(std::list::const_iterator it(nxsGrps.begin());it!=nxsGrps.end();++it) - delete *it ; - - return false ; - } - RsNxsGrp *nxs_grp = *(nxsGrps.begin()); - - size = RsNxsSerialiser(mServType).size(nxs_grp); - id = nxs_grp->metaData->mGroupId ; - - if(size > 1024*1024 || NULL==(data = (unsigned char *)rs_malloc(size))) - { - std::cerr << "(EE) getSerializedGroupData() cannot allocate mem chunk of size " << size << ". Too big, or no room." << std::endl; - delete nxs_grp ; - return false ; - } - - return RsNxsSerialiser(mServType).serialise(nxs_grp,data,&size) ; -} - -bool RsGenExchange::retrieveNxsIdentity(const RsGxsGroupId& group_id,RsNxsGrp *& identity_grp) -{ - RS_STACK_MUTEX(mGenMtx) ; - - std::map grp; - grp[group_id]=nullptr; - std::map::const_iterator grp_it; - - if(! mDataStore->retrieveNxsGrps(grp, true) || grp.end()==(grp_it=grp.find(group_id)) || !grp_it->second) - { - std::cerr << "(EE) Cannot retrieve group data for group " << group_id << " in service " << mServType << std::endl; - return false; - } - - identity_grp = grp_it->second; - return true; -} - -bool RsGenExchange::deserializeGroupData(unsigned char *data, uint32_t size, - RsGxsGroupId* gId /*= nullptr*/) -{ - RS_STACK_MUTEX(mGenMtx) ; - - RsItem *item = RsNxsSerialiser(mServType).deserialise(data, &size); - - RsNxsGrp *nxs_grp = dynamic_cast(item); - - if(item == NULL) - { - std::cerr << "(EE) RsGenExchange::deserializeGroupData(): cannot " - << "deserialise this data. Something's wrong." << std::endl; - delete item; - return false; - } - - if(mGrpPendingValidate.find(nxs_grp->grpId) != mGrpPendingValidate.end()) - { - std::cerr << "(WW) Group " << nxs_grp->grpId << " is already pending validation. Not adding again." << std::endl; - return true; - } - - if(gId) - *gId = nxs_grp->grpId; - - mGrpPendingValidate.insert(std::make_pair(nxs_grp->grpId, GxsPendingItem(nxs_grp, nxs_grp->grpId,time(NULL)))); - - return true; -} - -bool RsGenExchange::getGroupData(const uint32_t &token, std::vector& grpItem) -{ - std::list nxsGrps; - bool ok = mDataAccess->getGroupData(token, nxsGrps); - - std::list::iterator lit = nxsGrps.begin(); -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::getGroupData() RsNxsGrp::len: " << nxsGrps.size(); - std::cerr << std::endl; -#endif - - if(ok) - { - for(; lit != nxsGrps.end(); ++lit) - { - RsTlvBinaryData& data = (*lit)->grp; - RsItem* item = NULL; - - if(data.bin_len != 0) - item = mSerialiser->deserialise(data.bin_data, &data.bin_len); - - if(item) - { - RsGxsGrpItem* gItem = dynamic_cast(item); - if (gItem) - { - gItem->meta = *((*lit)->metaData); - - RsGroupNetworkStats sts ; - if(mNetService && mNetService->getGroupNetworkStats(gItem->meta.mGroupId,sts)) - { - gItem->meta.mPop = sts.mSuppliers; - gItem->meta.mVisibleMsgCount = sts.mMaxVisibleCount; - - // When the group is not subscribed, the last post value is not updated, because there's no message stored. As a consequence, - // we rely on network statistics to give this value, but it is not as accurate as if it was locally computed, because of blocked - // posts, friends not available, sync delays, etc. Similarly if the group has just been subscribed, the last post info is probably - // uninitialised, so we will it too. - - if((!(IS_GROUP_SUBSCRIBED(gItem->meta.mSubscribeFlags))) || gItem->meta.mLastPost == 0) - gItem->meta.mLastPost = sts.mLastGroupModificationTS ; - - } - else - { - gItem->meta.mPop = 0; - gItem->meta.mVisibleMsgCount = 0; - } - - // We could save this in the net service, but it's a bit more than that since some services have - // specific usage footprints for their groups. - - gItem->meta.mLastSeen = (IS_GROUP_SUBSCRIBED(gItem->meta.mSubscribeFlags)) ? time(nullptr) : service_getLastGroupSeenTs(gItem->meta.mGroupId); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "Group: " << gItem->meta.mGroupId << " name \"" << gItem->meta.mGroupName << "\" last seen=" << gItem->meta.mLastSeen << " now=" << time(nullptr) << std::endl; -#endif - - // Also check the group privacy flags. A while ago, it as possible to publish a group without privacy flags. Now it is not possible anymore. - // As a consequence, it's important to supply a correct value in this flag before the data can be edited/updated. - - if((gItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_MASK) == 0) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "(WW) getGroupData(): mGroupFlags for group " << gItem->meta.mGroupId << " has incorrect value " << std::hex << gItem->meta.mGroupFlags << std::dec << ". Setting value to GXS_SERV::FLAG_PRIVACY_PUBLIC." << std::endl; -#endif - gItem->meta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; - } - - grpItem.push_back(gItem); - } - else - { - std::cerr << "RsGenExchange::getGroupData() deserialisation/dynamic_cast ERROR"; - std::cerr << std::endl; - delete item; - } - } - else if(data.bin_len > 0) - //std::cerr << "(EE) RsGenExchange::getGroupData() Item type is probably not handled. Data is: " << RsUtil::BinToHex((unsigned char*)data.bin_data,std::min(50u,data.bin_len)) << ((data.bin_len>50)?"...":"") << std::endl; - std::cerr << "(EE) RsGenExchange::getGroupData() Item type is probably not handled. Data is: " << RsUtil::BinToHex((unsigned char*)data.bin_data,data.bin_len) << std::endl; - - delete *lit; - } - } - return ok; -} - -bool RsGenExchange::getMsgData(uint32_t token, GxsMsgDataMap &msgItems) -{ - RS_STACK_MUTEX(mGenMtx) ; - NxsMsgDataResult msgResult; - bool ok = mDataAccess->getMsgData(token, msgResult); - - if(ok) - { - NxsMsgDataResult::iterator mit = msgResult.begin(); - for(; mit != msgResult.end(); ++mit) - { - 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) - { - RsNxsMsg*& msg = *vit; - RsItem* item = NULL; - - if(msg->msg.bin_len != 0) - item = mSerialiser->deserialise(msg->msg.bin_data, &msg->msg.bin_len); - - if (item) - { - RsGxsMsgItem* mItem = dynamic_cast(item); - if (mItem) - { - mItem->meta = *((*vit)->metaData); // get meta info from nxs msg - gxsMsgItems.push_back(mItem); - } - else - { - std::cerr << "RsGenExchange::getMsgData() deserialisation/dynamic_cast ERROR"; - std::cerr << std::endl; - delete item; - } - } - else - { - std::cerr << "RsGenExchange::getMsgData() deserialisation ERROR"; - std::cerr << std::endl; - } - delete msg; - } - } - } - return ok; -} - -bool RsGenExchange::getMsgRelatedData( uint32_t token, - GxsMsgRelatedDataMap &msgItems ) -{ - RS_STACK_MUTEX(mGenMtx) ; - NxsMsgRelatedDataResult msgResult; - bool ok = mDataAccess->getMsgRelatedData(token, msgResult); - - if(ok) - { - NxsMsgRelatedDataResult::iterator mit = msgResult.begin(); - for(; mit != msgResult.end(); ++mit) - { - const RsGxsGrpMsgIdPair& msgId = mit->first; - std::vector &gxsMsgItems = msgItems[msgId]; - std::vector& nxsMsgsV = mit->second; - - for(auto vit=nxsMsgsV.begin(); vit != nxsMsgsV.end(); ++vit) - { - RsNxsMsg*& msg = *vit; - RsItem* item = NULL; - - if(msg->msg.bin_len != 0) - item = mSerialiser->deserialise(msg->msg.bin_data, - &msg->msg.bin_len); - if (item) - { - RsGxsMsgItem* mItem = dynamic_cast(item); - - if (mItem) - { - mItem->meta = *((*vit)->metaData); // get meta info from nxs msg - gxsMsgItems.push_back(mItem); - } - else - { - std::cerr << "RsGenExchange::getMsgRelatedData() deserialisation/dynamic_cast ERROR"; - std::cerr << std::endl; - delete item; - } - } - else - { - std::cerr << "RsGenExchange::getMsgRelatedData() deserialisation ERROR"; - std::cerr << std::endl; - } - - delete msg; - } - } - } - return ok; -} - -RsTokenService* RsGenExchange::getTokenService() -{ - return mDataAccess; -} - - -bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authenFlag, const PrivacyBitPos &pos) -{ - uint32_t temp = 0; - temp = msgFlag; - - switch(pos) - { - case PUBLIC_GRP_BITS: - authenFlag &= ~PUB_GRP_MASK; - authenFlag |= temp; - break; - case RESTRICTED_GRP_BITS: - authenFlag &= ~RESTR_GRP_MASK; - authenFlag |= (temp << RESTR_GRP_OFFSET); - break; - case PRIVATE_GRP_BITS: - authenFlag &= ~PRIV_GRP_MASK; - authenFlag |= (temp << PRIV_GRP_OFFSET); - break; - case GRP_OPTION_BITS: - authenFlag &= ~GRP_OPTIONS_MASK; - authenFlag |= (temp << GRP_OPTIONS_OFFSET); - break; - default: - std::cerr << "pos option not recognised"; - return false; - } - return true; -} - -void RsGenExchange::receiveNewGroups(const std::vector &groups) -{ - RS_STACK_MUTEX(mGenMtx) ; - - auto vit = groups.begin(); - - // store these for tick() to pick them up - for(; vit != groups.end(); ++vit) - { - RsNxsGrp* grp = *vit; - NxsGrpPendValidVect::iterator received = mGrpPendingValidate.find(grp->grpId); - - // drop group if you already have them - // TODO: move this to nxs layer to save bandwidth - if(received == mGrpPendingValidate.end()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::notifyNewGroups() Received GrpId: " << grp->grpId; - std::cerr << std::endl; -#endif - - mGrpPendingValidate.insert(std::make_pair(grp->grpId, GxsPendingItem(grp, grp->grpId,time(NULL)))); - } - else - { - delete grp; - } - } - -} - - -void RsGenExchange::receiveNewMessages(const std::vector& messages) -{ - RS_STACK_MUTEX(mGenMtx) ; - - // store these for tick() to pick them up - - for(uint32_t i=0;imsgId) ; - - // if we have msg already just delete it - if(it == mMsgPendingValidate.end()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::notifyNewMessages() Received Msg: "; - std::cerr << " GrpId: " << msg->grpId; - std::cerr << " MsgId: " << msg->msgId; - std::cerr << std::endl; -#endif - RsGxsGrpMsgIdPair id; - id.first = msg->grpId; - id.second = msg->msgId; - - mMsgPendingValidate.insert(std::make_pair(msg->msgId,GxsPendingItem(msg, id,time(NULL)))); - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " message is already in pending validation list. dropping." << std::endl; -#endif - delete msg; - } - } -} - -void RsGenExchange::receiveDistantSearchResults(TurtleRequestId id,const RsGxsGroupId &grpId) -{ - std::cerr << __PRETTY_FUNCTION__ << " received result for request " << std::hex << id << std::dec << ": this method should be overloaded in the client service, but it is not. This is a bug!" << std::endl; -} - -void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId) -{ - RS_STACK_MUTEX(mGenMtx); - - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY,grpId, true); - mNotifications.push_back(gc); -} - -void RsGenExchange::notifyChangedGroupSyncParams(const RsGxsGroupId &grpId) -{ - RS_STACK_MUTEX(mGenMtx); - - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED,grpId, false); - - mNotifications.push_back(gc); -} -void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId) -{ - RS_STACK_MUTEX(mGenMtx); - - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED,grpId, false); - - mNotifications.push_back(gc); -} - -bool RsGenExchange::checkGroupMetaConsistency(const RsGroupMetaData& meta) -{ - std::cerr << "Checking group consistency:" << std::endl; - - if(meta.mGroupName.empty()) - { - std::cerr << "(EE) cannot create a group with no name." << std::endl; - return false; - } - - uint32_t gf = meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_MASK ; - - if(gf != GXS_SERV::FLAG_PRIVACY_PUBLIC && gf != GXS_SERV::FLAG_PRIVACY_RESTRICTED && gf != GXS_SERV::FLAG_PRIVACY_PRIVATE) - { - std::cerr << "(EE) mGroupFlags has incorrect value " << std::hex << meta.mGroupFlags << std::dec << ". A value among GXS_SERV::FLAG_PRIVACY_{PUBLIC,RESTRICTED,PRIVATE} is expected." << std::endl; - return false ; - } - - if(meta.mCircleType < GXS_CIRCLE_TYPE_PUBLIC || meta.mCircleType > GXS_CIRCLE_TYPE_YOUR_EYES_ONLY) - { - std::cerr << "(EE) mCircleType has incorrect value " << std::hex << meta.mCircleType << std::dec << ". A single value among GXS_CIRCLE_TYPE_{PUBLIC,EXTERNAL,YOUR_FRIENDS_ONLY,LOCAL,EXT_SELF,YOUR_EYES_ONLY} is expected." << std::endl; - return false ; - } - - if(meta.mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) - { - if(!meta.mInternalCircle.isNull()) - { - std::cerr << "(EE) Group circle type is EXTERNAL, but an internal circle ID " << meta.mInternalCircle << " was supplied. This is an error." << std::endl; - return false ; - } - if(meta.mCircleId.isNull()) - { - std::cerr << "(EE) Group circle type is EXTERNAL, but no external circle ID was supplied. meta.mCircleId is indeed empty. This is an error." << std::endl; - return false ; - } - } - - if(meta.mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) - { - if(!meta.mCircleId.isNull()) - { - std::cerr << "(EE) Group circle type is YOUR_FRIENDS_ONLY, but an external circle ID " << meta.mCircleId << " was supplied. This is an error." << std::endl; - return false ; - } - if(meta.mInternalCircle.isNull()) - { - std::cerr << "(EE) Group circle type is YOUR_FRIENDS_ONLY, but no internal circle ID was supplied. meta.mInternalCircle is indeed empty. This is an error." << std::endl; - return false ; - } - } - - if(meta.mCircleType == GXS_CIRCLE_TYPE_EXT_SELF) - { - if(!meta.mCircleId.isNull()) - { - std::cerr << "(EE) Group circle type is EXT_SELF, but an external circle ID " << meta.mCircleId << " was supplied. This is an error." << std::endl; - return false ; - } - if(!meta.mInternalCircle.isNull()) - { - std::cerr << "(EE) Group circle type is EXT_SELF, but an internal circle ID " << meta.mInternalCircle << " was supplied. This is an error." << std::endl; - return false ; - } - } - - std::cerr << "Group is clean." << std::endl; - return true ; -} - -void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem) -{ - if(!checkGroupMetaConsistency(grpItem->meta)) - { - std::cerr << "(EE) Cannot publish group. Some information was not supplied." << std::endl; - return ; - } - - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - GxsGrpPendingSign ggps(grpItem, token); - mGrpsToPublish.push_back(ggps); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGroup() token: " << token; - std::cerr << std::endl; -#endif - -} - - -void RsGenExchange::updateGroup(uint32_t& token, RsGxsGrpItem* grpItem) -{ - if(!checkGroupMetaConsistency(grpItem->meta)) - { - std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl; - delete grpItem; - return ; - } - - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token)); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::updateGroup() token: " << token; - std::cerr << std::endl; -#endif -} - -void RsGenExchange::deleteGroup(uint32_t& token, const RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - mGroupDeletePublish.push_back(GroupDeletePublish(grpId, token)); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::deleteGroup() token: " << token; - std::cerr << std::endl; -#endif -} -void RsGenExchange::deleteMsgs(uint32_t& token, const GxsMsgReq& msgs) -{ - RS_STACK_MUTEX(mGenMtx) ; - - token = mDataAccess->generatePublicToken(); - mMsgDeletePublish.push_back(MsgDeletePublish(msgs, token)); - - // This code below will suspend any requests of the deleted messages for 24 hrs. This of course only works - // if all friend nodes consistently delete the messages in the mean time. - - if(mNetService != NULL) - for(GxsMsgReq::const_iterator it(msgs.begin());it!=msgs.end();++it) - for(auto it2(it->second.begin());it2!=it->second.end();++it2) - mNetService->rejectMessage(*it2); -} - -void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) -{ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - mMsgsToPublish.insert(std::make_pair(token, msgItem)); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishMsg() token: " << token; - std::cerr << std::endl; -#endif - -} - -uint32_t RsGenExchange::getDefaultSyncPeriod() -{ - RS_STACK_MUTEX(mGenMtx) ; - - if(mNetService != NULL) - return mNetService->getDefaultSyncAge(); - else - { - std::cerr << "(EE) No network service available. Cannot get default sync period. " << std::endl; - return 0; - } -} - -RsReputationLevel RsGenExchange::minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_sign_flags ) -{ - return RsNetworkExchangeService::minReputationForForwardingMessages(group_sign_flags,identity_sign_flags); -} -uint32_t RsGenExchange::getSyncPeriod(const RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mGenMtx) ; - - if(mNetService != NULL) - return mNetService->getSyncAge(grpId); - else - return RS_GXS_DEFAULT_MSG_REQ_PERIOD; -} - -bool RsGenExchange::getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats) -{ - return (!mNetService) || mNetService->getGroupNetworkStats(grpId,stats) ; -} - -void RsGenExchange::setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) -{ - if(mNetService != NULL) - return mNetService->setSyncAge(grpId,age_in_secs) ; - else - std::cerr << "(EE) No network service available. Cannot set storage period. " << std::endl; -} - -uint32_t RsGenExchange::getStoragePeriod(const RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mGenMtx) ; - - if(!mNetService) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "(EE) No network service in service " << std::hex << serviceType() << std::dec << ": cannot read message storage time. Returning infinity." << std::endl; -#endif - return false ; - } - return mNetService->getKeepAge(grpId) ; -} -void RsGenExchange::setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) -{ - if(mNetService != NULL) - return mNetService->setKeepAge(grpId,age_in_secs) ; - else - std::cerr << "(EE) No network service available. Cannot set storage period. " << std::endl; -} - -void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask) -{ - /* TODO APPLY MASK TO FLAGS */ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - - GrpLocMetaData g; - g.grpId = grpId; - g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag); - g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location - mGrpLocMetaMap.insert(std::make_pair(token, g)); -} - -void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask) -{ - /* TODO APPLY MASK TO FLAGS */ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - - GrpLocMetaData g; - g.grpId = grpId; - g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status); - g.val.put(RsGeneralDataService::GRP_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location - mGrpLocMetaMap.insert(std::make_pair(token, g)); -} - - -void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString) -{ - RS_STACK_MUTEX(mGenMtx); - token = mDataAccess->generatePublicToken(); - - GrpLocMetaData g; - g.grpId = grpId; - g.val.put(RsGeneralDataService::GRP_META_SERV_STRING, servString); - mGrpLocMetaMap.insert(std::make_pair(token, g)); -} - -void RsGenExchange::setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask) -{ - /* TODO APPLY MASK TO FLAGS */ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - - MsgLocMetaData m; - m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status); - m.val.put(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location - m.msgId = msgId; - mMsgLocMetaMap.insert(std::make_pair(token, m)); -} - -void RsGenExchange::setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ) -{ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - - MsgLocMetaData m; - m.val.put(RsGeneralDataService::MSG_META_SERV_STRING, servString); - m.msgId = msgId; - mMsgLocMetaMap.insert(std::make_pair(token, m)); -} - -void RsGenExchange::processMsgMetaChanges() -{ - std::map metaMap; - - { - RS_STACK_MUTEX(mGenMtx); - if (mMsgLocMetaMap.empty()) - { - return; - } - metaMap = mMsgLocMetaMap; - mMsgLocMetaMap.clear(); - } - - GxsMsgReq msgIds; - - std::map::iterator mit; - for (mit = metaMap.begin(); mit != metaMap.end(); ++mit) - { - MsgLocMetaData& m = mit->second; - - int32_t value, mask; - bool ok = true; - bool changed = false; - - // for meta flag changes get flag to apply mask - if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS, value)) - { - ok = false; - if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, mask)) - { - GxsMsgReq req; - std::set msgIdV; - msgIdV.insert(m.msgId.second); - req.insert(std::make_pair(m.msgId.first, msgIdV)); - GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(req, result); - GxsMsgMetaResult::iterator mit = result.find(m.msgId.first); - - if(mit != result.end()) - { - const auto& msgMetaV = mit->second; - - if(!msgMetaV.empty()) - { - const auto& meta = *(msgMetaV.begin()); - value = (meta->mMsgStatus & ~mask) | (mask & value); - changed = (static_cast(meta->mMsgStatus) != value); - m.val.put(RsGeneralDataService::MSG_META_STATUS, value); - ok = true; - } - } - m.val.removeKeyValue(RsGeneralDataService::MSG_META_STATUS+GXS_MASK); - } - } - - ok &= mDataStore->updateMessageMetaData(m) == 1; - uint32_t token = mit->first; - - if(ok) - { - mDataAccess->updatePublicRequestStatus(token, RsTokenService::COMPLETE); - if (changed) - { - msgIds[m.msgId.first].insert(m.msgId.second); - } - } - else - { - mDataAccess->updatePublicRequestStatus(token, RsTokenService::FAILED); - } - - { - RS_STACK_MUTEX(mGenMtx); - mMsgNotify.insert(std::make_pair(token, m.msgId)); - } - } - - if (!msgIds.empty()) - { - RS_STACK_MUTEX(mGenMtx); - - for(auto it(msgIds.begin());it!=msgIds.end();++it) - for(auto& msg_id:it->second) - mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, it->first, msg_id, false)); - } -} - -void RsGenExchange::processGrpMetaChanges() -{ - std::map metaMap; - - { - RS_STACK_MUTEX(mGenMtx); - if (mGrpLocMetaMap.empty()) - { - return; - } - metaMap = mGrpLocMetaMap; - mGrpLocMetaMap.clear(); - } - - std::list grpChanged; - - std::map::iterator mit; - for (mit = metaMap.begin(); mit != metaMap.end(); ++mit) - { - GrpLocMetaData& g = mit->second; - uint32_t token = mit->first; - -#ifdef GEN_EXCH_DEBUG - RsDbg() << " Processing GrpMetaChange for token " << token << std::endl; -#endif - // process mask - bool ok = processGrpMask(g.grpId, g.val); - - ok = ok && (mDataStore->updateGroupMetaData(g) == 1); - - if(ok) - { - mDataAccess->updatePublicRequestStatus(token, RsTokenService::COMPLETE); - grpChanged.push_back(g.grpId); - } - else - { - mDataAccess->updatePublicRequestStatus(token, RsTokenService::FAILED); - } - - { - RS_STACK_MUTEX(mGenMtx); - mGrpNotify.insert(std::make_pair(token, g.grpId)); -#ifdef GEN_EXCH_DEBUG - RsDbg() << " Processing GrpMetaChange Adding token " << token << " to mGrpNotify" << std::endl; -#endif - } - } - - for(auto& groupId:grpChanged) - { - RS_STACK_MUTEX(mGenMtx); - - mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED,groupId, true)); - } -} - -bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpCv) -{ - // first find out which mask is involved - int32_t value, mask, currValue; - std::string key; - std::shared_ptr grpMeta; - bool ok = false; - - RsGxsGrpMetaTemporaryMap grpMetaMap; - grpMetaMap[grpId] = std::make_shared(); - - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - auto mit = grpMetaMap.find(grpId); - - if(mit != grpMetaMap.end()) - { - 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; - } - - if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_STATUS, value) && grpMeta) - { - key = RsGeneralDataService::GRP_META_STATUS; - currValue = grpMeta->mGroupStatus; - } - else if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, value) && grpMeta) - { - key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG; - currValue = grpMeta->mSubscribeFlags; - } - else - return !(grpCv.empty()); - - ok &= grpCv.getAsInt32(key+GXS_MASK, mask); - - // remove mask entry so it doesn't affect actual entry - grpCv.removeKeyValue(key+GXS_MASK); - - // apply mask to current value - value = (currValue & ~mask) | (value & mask); - - grpCv.put(key, value); - - return ok; -} - -void RsGenExchange::publishMsgs() -{ - - RS_STACK_MUTEX(mGenMtx) ; - - rstime_t now = time(NULL); - - // stick back msgs pending signature - typedef std::map > PendSignMap; - - PendSignMap::iterator sign_it = mMsgPendingSign.begin(); - - for(; sign_it != mMsgPendingSign.end(); ++sign_it) - { - GxsPendingItem& item = sign_it->second; - mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem)); - } - - std::map > msgChangeMap; - std::map::iterator mit = mMsgsToPublish.begin(); - - for(; mit != mMsgsToPublish.end(); ++mit) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishMsgs() Publishing a Message"; - std::cerr << std::endl; -#endif - - RsGxsMsgItem* msgItem = mit->second; - uint32_t token = mit->first; - - uint32_t size = mSerialiser->size(msgItem); - - if(size > RsSerialiser::MAX_SERIAL_SIZE) - { - std::cerr << "Trying to publish a GXS message larger than the accepted maximal size of " << RsSerialiser::MAX_SERIAL_SIZE << " bytes. This is a bug." << std::endl; - mDataAccess->updatePublicRequestStatus(token, RsTokenService::FAILED); - delete msgItem; - - continue; - } - RsTemporaryMemory mData(size); - - // for fatal sign creation - bool createOk = false; - - // if sign requests to try later - bool tryLater = false; - - bool serialOk = mSerialiser->serialise(msgItem, mData, &size); - - if(serialOk) - { - RsNxsMsg* msg = new RsNxsMsg(mServType); - msg->grpId = msgItem->meta.mGroupId; - - msg->msg.setBinData(mData, size); - - // now create meta - msg->metaData = new RsGxsMsgMetaData(); - *(msg->metaData) = msgItem->meta; - - // assign time stamp - msg->metaData->mPublishTs = time(NULL); - - // now intialise msg (sign it) - uint8_t createReturn = createMessage(msg); - - if(createReturn == CREATE_FAIL) - { - createOk = false; - } - else if(createReturn == CREATE_FAIL_TRY_LATER) - { - PendSignMap::iterator pit = mMsgPendingSign.find(token); - tryLater = true; - - // add to queue of messages waiting for a successful - // sign attempt - if(pit == mMsgPendingSign.end()) - { - GxsPendingItem gsi(msgItem, token,time(NULL)); - mMsgPendingSign.insert(std::make_pair(token, gsi)); - } - else - { - // remove from attempts queue if over sign - // attempts limit - if(pit->second.mFirstTryTS + SIGN_MAX_WAITING_TIME < now) - { - std::cerr << "Pending signature grp=" << pit->second.mItem->meta.mGroupId << ", msg=" << pit->second.mItem->meta.mMsgId << ", has exceeded validation time limit. The author's key can probably not be obtained. This is unexpected." << std::endl; - - mMsgPendingSign.erase(token); - tryLater = false; - } - } - - createOk = false; - } - else if(createReturn == CREATE_SUCCESS) - { - createOk = true; - - // erase from queue if it exists - mMsgPendingSign.erase(token); - } - else // unknown return, just fail - createOk = false; - - - - RsGxsMessageId msgId; - RsGxsGroupId grpId = msgItem->meta.mGroupId; - - bool validSize = false; - - // check message not over single msg storage limit - if(createOk) - validSize = mDataStore->validSize(msg); - - if(createOk && validSize) - { - // empty orig msg id means this is the original - // msg. - // (csoler) Why are we doing this??? - - if(msg->metaData->mOrigMsgId.isNull()) - { - msg->metaData->mOrigMsgId = msg->metaData->mMsgId; - } - - // now serialise meta data - size = msg->metaData->serial_size(); - - { - RsTemporaryMemory metaDataBuff(size); - - bool s = msg->metaData->serialise(metaDataBuff, &size); - s &= msg->meta.setBinData(metaDataBuff, size); - if (!s) - std::cerr << "(WW) Can't serialise or set bin data" << std::endl; - } - - msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - msgId = msg->msgId; - grpId = msg->grpId; - msg->metaData->recvTS = time(NULL); - - // FIXTESTS global variable rsPeers not available in unittests! - - if(rsPeers) - mRoutingClues[msg->metaData->mAuthorId].insert(rsPeers->getOwnId()) ; - - computeHash(msg->msg, msg->metaData->mHash); // (csoler) weird choice: hash should also depend on metadata. Fortunately, msg signature - // signs the holw thing (msg + meta) - - mPublishedMsgs[token] = *msg->metaData; - - RsGxsMsgItem *msg_item = dynamic_cast(mSerialiser->deserialise(msg->msg.bin_data,&msg->msg.bin_len)) ; - - if(!msg_item) - { - delete msg; - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::FAILED); - - std::cerr << "RsGenExchange::publishMsgs() failed to publish msg, probably because of data size limits. bin_len=" << msg->msg.bin_len << std::endl; - continue; // next mit - } - msg_item->meta = *msg->metaData; - - mDataAccess->addMsgData(msg); // msg is deleted by addMsgData() - - msgChangeMap[grpId].push_back(msg_item); - - if(mNetService != NULL) - mNetService->stampMsgServerUpdateTS(grpId) ; - - // add to published to allow acknowledgement - mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::COMPLETE); - } - else - { - // delete msg if create msg not ok - delete msg; - - if(!tryLater) - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::FAILED); - - std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl; - } - } - else - { - std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl; - } - - if(!tryLater) - delete msgItem; - } - - // clear msg item map as we're done publishing them and all - // entries are invalid - mMsgsToPublish.clear(); - - for(auto it(msgChangeMap.begin());it!=msgChangeMap.end();++it) - for(auto& msg_item: it->second) - { - RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED,msg_item->meta.mGroupId, msg_item->meta.mMsgId, false); - ch->mNewMsgItem = msg_item; - - mNotifications.push_back(ch); - } -} - -RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */, - RsTlvSecurityKeySet& /* keySet */) -{ -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::service_CreateGroup(): Does nothing" - << std::endl; -#endif - return SERVICE_CREATE_SUCCESS; -} - - -#define PENDING_SIGN_TIMEOUT 10 // 5 seconds - - -void RsGenExchange::processGroupUpdatePublish() -{ - RS_STACK_MUTEX(mGenMtx) ; - - // get keys for group update publish - - // first build meta request map for groups to be updated - RsGxsGrpMetaTemporaryMap grpMeta; - - for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit) - { - GroupUpdatePublish& gup = *vit; - const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId; - grpMeta.insert(std::make_pair(groupId, std::make_shared())); - } - - if(grpMeta.empty()) - return; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - // now - for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit) - { - GroupUpdatePublish& gup = *vit; - const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId; - auto mit = grpMeta.find(groupId); - - std::shared_ptr meta; - - if(mit == grpMeta.end() || mit->second == nullptr) - { - std::cerr << "Error! could not find meta of old group to update!" << std::endl; - mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED); - delete gup.grpItem; - continue; - } - else - meta = mit->second; - - //gup.grpItem->meta = *meta; - GxsGrpPendingSign ggps(gup.grpItem, gup.mToken); - - if(checkKeys(meta->keys)) - { - ggps.mKeys = meta->keys; - - GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ; - - ggps.mHaveKeys = true; - ggps.mStartTS = time(NULL); - ggps.mLastAttemptTS = 0; - ggps.mIsUpdate = true; - ggps.mToken = gup.mToken; - mGrpsToPublish.push_back(ggps); - } - else - { - std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl; - - delete gup.grpItem; - mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED); - } - } - - mGroupUpdatePublish.clear(); -} - - -void RsGenExchange::processRoutingClues() -{ - 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) ) ; - - mRoutingClues.clear() ; -} - -void RsGenExchange::processGroupDelete() -{ - RS_STACK_MUTEX(mGenMtx); - - // get keys for group delete publish - typedef std::pair GrpNote; - std::map toNotify; - - for( auto vit = mGroupDeletePublish.begin();vit != mGroupDeletePublish.end(); ++vit) - { - std::vector gprIds; - gprIds.push_back(vit->mGroupId); - mDataStore->removeGroups(gprIds); - toNotify.insert(std::make_pair( vit->mToken, GrpNote(true, vit->mGroupId))); - } - - std::list grpDeleted; - for(auto mit=toNotify.begin(); mit != toNotify.end(); ++mit) - { - GrpNote& note = mit->second; - RsTokenService::GxsRequestStatus status = - note.first ? RsTokenService::COMPLETE - : RsTokenService::FAILED; - - mDataAccess->updatePublicRequestStatus(mit->first, status); - mDataAccess->disposeOfPublicToken(mit->first); - - if(note.first) - grpDeleted.push_back(note.second); - } - - for(auto& groupId:grpDeleted) - { - RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, groupId,false); - mNotifications.push_back(gc); - } - - mGroupDeletePublish.clear(); -} - -void RsGenExchange::processMessageDelete() -{ - RS_STACK_MUTEX(mGenMtx) ; - - struct MsgNote { - MsgNote(bool s,const GxsMsgReq& mid) : state(s),msgIds(mid){} - - bool state; - GxsMsgReq msgIds; - }; - std::map toNotify; - - for( auto vit = mMsgDeletePublish.begin(); vit != mMsgDeletePublish.end(); ++vit) - { - uint32_t token = (*vit).mToken; - bool res = mDataStore->removeMsgs( (*vit).mMsgs ); - -#ifdef GEN_EXCH_DEBUG - for(auto mit: (*vit).mMsgs) - { - std::cerr << "Attempt to delete messages: token=" << token << std::endl; - for(const auto& msg:mit.second) - std::cerr << " grpId=" << mit.first << ", msgId=" << msg << std::endl; - std::cerr << " Result: " << res << std::endl; - } -#endif - toNotify.insert(std::make_pair(token, MsgNote(res,(*vit).mMsgs))); - } - - std::list msgDeleted; - - for(auto mit = toNotify.begin(); mit != toNotify.end(); ++mit) - { - MsgNote& note = mit->second; - RsTokenService::GxsRequestStatus status = - note.state ? RsTokenService::COMPLETE - : RsTokenService::FAILED; - - mDataAccess->updatePublicRequestStatus(mit->first, status); - mDataAccess->disposeOfPublicToken(mit->first); - - if(note.state) - msgDeleted.push_back(note.msgIds); - } - - for(const auto& msgreq:msgDeleted) - for(const auto& msgit:msgreq) - for(const auto& msg:msgit.second) - mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_MESSAGE_DELETED,msgit.first,msg, false)); - - mMsgDeletePublish.clear(); -} - -bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet) -{ - - typedef std::map keyMap; - const keyMap& allKeys = keySet.private_keys; - keyMap::const_iterator cit = allKeys.begin(); - - bool adminFound = false, publishFound = false; - for(; cit != allKeys.end(); ++cit) - { - const RsTlvPrivateRSAKey& key = cit->second; - if(key.keyFlags & RSTLV_KEY_TYPE_FULL) // this one is not useful. Just a security. - { - if(key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) - adminFound = true; - - if(key.keyFlags & RSTLV_KEY_DISTRIB_PUBLISH) - publishFound = true; - - } - else if(key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY) // this one is not useful. Just a security. - { - std::cerr << "(EE) found a public only key in the private key list" << std::endl; - return false ; - } - } - - // user must have both private and public parts of publish and admin keys - return adminFound && publishFound; -} - -void RsGenExchange::publishGrps() -{ - std::list groups_to_subscribe ; - - { - RS_STACK_MUTEX(mGenMtx) ; - NxsGrpSignPendVect::iterator vit = mGrpsToPublish.begin(); - - typedef struct _GrpNote { - - _GrpNote(bool success,bool is_update,const RsGxsGroupId& gid) : mSuccess(success),mIsUpdate(is_update),mGroupId(gid){} - - bool mSuccess; - bool mIsUpdate; - RsGxsGroupId mGroupId; - - } GrpNote; - - std::map toNotify; // used to notify about token processing if success or fails because of timeout - - while( vit != mGrpsToPublish.end() ) - { - GxsGrpPendingSign& ggps = *vit; - - /* do intial checks to see if this entry has expired */ - rstime_t now = time(NULL) ; - uint32_t token = ggps.mToken; - - - if(now > (ggps.mStartTS + PENDING_SIGN_TIMEOUT) ) - { - // timed out - toNotify.insert(std::make_pair( token, GrpNote(false,ggps.mIsUpdate, RsGxsGroupId()))); - delete ggps.mItem; - vit = mGrpsToPublish.erase(vit); - - continue; - } - - RsGxsGroupId grpId; - RsNxsGrp* grp = new RsNxsGrp(mServType); - RsGxsGrpItem* grpItem = ggps.mItem; - - RsTlvSecurityKeySet fullKeySet; - - if(!(ggps.mHaveKeys)) - { - generateGroupKeys(fullKeySet, true); - ggps.mHaveKeys = true; - ggps.mKeys = fullKeySet; - } - else - { - // We should just merge the keys instead of overwriting them, because the update may not contain private parts. - - fullKeySet = ggps.mKeys; - } - - // find private admin key - RsTlvPrivateRSAKey privAdminKey; - bool privKeyFound = false; - for(std::map::iterator mit_keys = fullKeySet.private_keys.begin(); mit_keys != fullKeySet.private_keys.end(); ++mit_keys) - { - RsTlvPrivateRSAKey& key = mit_keys->second; - - if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) - { - privAdminKey = key; - privKeyFound = true; - } - } - - uint8_t create = CREATE_FAIL; - - if(privKeyFound) - { - // get group id from private admin key id - grpItem->meta.mGroupId = grp->grpId = RsGxsGroupId(privAdminKey.keyId); - - ServiceCreate_Return ret = service_CreateGroup(grpItem, fullKeySet); - - bool serialOk = false, servCreateOk; - - if(ret == SERVICE_CREATE_SUCCESS) - { - uint32_t size = mSerialiser->size(grpItem); - char *gData = new char[size]; - serialOk = mSerialiser->serialise(grpItem, gData, &size); - grp->grp.setBinData(gData, size); - delete[] gData; - servCreateOk = true; - - }else - { - servCreateOk = false; - } - - if(serialOk && servCreateOk) - { - grp->metaData = new RsGxsGrpMetaData(); - grpItem->meta.mPublishTs = time(NULL); - *(grp->metaData) = grpItem->meta; - - // TODO: change when publish key optimisation added (public groups don't have publish key - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED - | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH; - - create = createGroup(grp, fullKeySet); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() "; - std::cerr << " GrpId: " << grp->grpId; - std::cerr << " CircleType: " << (uint32_t) grp->metaData->mCircleType; - std::cerr << " CircleId: " << grp->metaData->mCircleId.toStdString(); - std::cerr << std::endl; -#endif - - if(create == CREATE_SUCCESS) - { - // Here we need to make sure that no private keys are included. This is very important since private keys - // can be used to modify the group. Normally the private key set is whiped out by createGroup, but - - grp->metaData->keys.private_keys.clear() ; - - uint32_t mdSize = grp->metaData->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); - - { - RsTemporaryMemory metaData(mdSize); - serialOk = grp->metaData->serialise(metaData, mdSize,RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); -#warning csoler: TODO: grp->meta should be renamed grp->public_meta ! - grp->meta.setBinData(metaData, mdSize); - } - mPublishedGrps[ggps.mToken] = *grp->metaData ; // save the connexion between the token and the created metadata, without private keys - - // Place back private keys for publisher and database storage - grp->metaData->keys.private_keys = fullKeySet.private_keys; - - if(mDataStore->validSize(grp) && serialOk) - { - grpId = grp->grpId; - computeHash(grp->grp, grp->metaData->mHash); - grp->metaData->mRecvTS = time(NULL); - - // Also push in notifications. We do it here when we still have pointers on the old and new groups - - RsGxsGroupChange *c = new RsGxsGroupChange(ggps.mIsUpdate?RsGxsNotify::TYPE_UPDATED:RsGxsNotify::TYPE_PUBLISHED, grpId,false); - - c->mNewGroupItem = dynamic_cast(mSerialiser->deserialise(grp->grp.bin_data,&grp->grp.bin_len)); - c->mNewGroupItem->meta = *grp->metaData; // grp will be deleted because mDataStore will destroy it on update - - if(ggps.mIsUpdate) - { - RsNxsGrpDataTemporaryMap oldGrpDatas; - oldGrpDatas.insert(std::make_pair(grpId, (RsNxsGrp*)NULL)); - - if(mDataStore->retrieveNxsGrps(oldGrpDatas,true) && oldGrpDatas.size() == 1) - { - auto oldGrp = oldGrpDatas[grpId]; - c->mOldGroupItem = dynamic_cast(mSerialiser->deserialise(oldGrp->grp.bin_data,&oldGrp->grp.bin_len)); - c->mOldGroupItem->meta = *oldGrp->metaData; - } - } - - mNotifications.push_back(c); - - // now store (and incidently delete grp) - - if(ggps.mIsUpdate) - mDataAccess->updateGroupData(grp); - else - mDataAccess->addGroupData(grp); - - groups_to_subscribe.push_back(grpId) ; - } - else - { - create = CREATE_FAIL; - } - } - } - 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) - create = CREATE_FAIL; - } - else - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() Could not find private publish keys " << std::endl; -#endif - create = CREATE_FAIL; - } - - if(create == CREATE_FAIL) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; -#endif - delete grp; - delete grpItem; - vit = mGrpsToPublish.erase(vit); - toNotify.insert(std::make_pair(token, GrpNote(false, ggps.mIsUpdate,grpId))); - - } - else if(create == CREATE_FAIL_TRY_LATER) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() failed grp, trying again " << std::endl; -#endif - delete grp; - ggps.mLastAttemptTS = time(NULL); - ++vit; - } - else if(create == CREATE_SUCCESS) - { - delete grpItem; - vit = mGrpsToPublish.erase(vit); - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" - << std::endl; -#endif - - // add to published to allow acknowledgement - toNotify.insert(std::make_pair(token, GrpNote(true,ggps.mIsUpdate,grpId))); - } - } - - // toNotify contains the token and the group update/creation info. We parse it to - // - notify that group creation/update for a specific token was - - for(auto mit=toNotify.begin(); mit != toNotify.end(); ++mit) - { - GrpNote& note = mit->second; - RsTokenService::GxsRequestStatus status = note.mSuccess ? RsTokenService::COMPLETE : RsTokenService::FAILED; - - mGrpNotify.insert(std::make_pair(mit->first, note.mGroupId)); // always notify - mDataAccess->updatePublicRequestStatus(mit->first, status); // update the token request with the given status - } - } - - // This is done off-mutex to avoid possible cross deadlocks with the net service. - - if(mNetService!=NULL) - for(std::list::const_iterator it(groups_to_subscribe.begin());it!=groups_to_subscribe.end();++it) - mNetService->subscribeStatusChanged((*it),true) ; -} - -uint32_t RsGenExchange::generatePublicToken() -{ - uint32_t token = mDataAccess->generatePublicToken(); -#ifdef GEN_EXCH_DEBUG - std::cerr << "New token generated: " << token << " in RsGenExchange::generatePublicToken()" << std::endl; -#endif - return token; -} - -bool RsGenExchange::updatePublicRequestStatus( - uint32_t token, RsTokenService::GxsRequestStatus status ) -{ - return mDataAccess->updatePublicRequestStatus(token, status); -} - -bool RsGenExchange::disposeOfPublicToken(const uint32_t &token) -{ - return mDataAccess->disposeOfPublicToken(token); -} - -RsGeneralDataService* RsGenExchange::getDataStore() -{ - return mDataStore; -} - -bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet &keySet) -{ - if(grpId.isNull()) - return false; - - RS_STACK_MUTEX(mGenMtx) ; - - RsGxsGrpMetaTemporaryMap grpMeta; - grpMeta[grpId] = std::make_shared(); - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - if(grpMeta.empty()) - return false; - - const auto& meta = grpMeta[grpId]; - - if(meta == NULL) - return false; - - keySet = meta->keys; - GxsSecurity::createPublicKeysFromPrivateKeys(keySet) ; - - return true; -} - -void RsGenExchange::shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set& peers) -{ - if(grpId.isNull()) - return ; - - mNetService->sharePublishKey(grpId,peers) ; -} - -void RsGenExchange::processRecvdData() -{ - processRecvdGroups(); - - processRecvdMessages(); - - performUpdateValidation(); - -} - - -void RsGenExchange::computeHash(const RsTlvBinaryData& data, RsFileHash& hash) -{ - pqihash pHash; - pHash.addData(data.bin_data, data.bin_len); - pHash.Complete(hash); -} - -void RsGenExchange::processRecvdMessages() -{ - std::list messages_to_reject ; - - { - RS_STACK_MUTEX(mGenMtx) ; - - rstime_t now = time(NULL); - - if(mMsgPendingValidate.empty()) - return ; -#ifdef GEN_EXCH_DEBUG - else - std::cerr << "processing received messages" << std::endl; -#endif - // 1 - First, make sure items metadata is deserialised, clean old failed items, and collect the groups Ids we have to check - - RsGxsGrpMetaTemporaryMap grpMetas; - - for(NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin();pend_it != mMsgPendingValidate.end();) - { - GxsPendingItem& gpsi = pend_it->second; - RsNxsMsg *msg = gpsi.mItem ; - - if(msg->metaData == NULL) - { - RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); - - if(msg->meta.bin_len != 0 && meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len))) - msg->metaData = meta; - else - delete meta; - } - - bool accept_new_msg = msg->metaData != NULL && acceptNewMessage(msg->metaData,msg->msg.bin_len); - - if(!accept_new_msg) - messages_to_reject.push_back(msg->metaData->mMsgId); // This prevents reloading the message again at next sync. - - if(!accept_new_msg || gpsi.mFirstTryTS + VALIDATE_MAX_WAITING_TIME < now) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "Pending validation grp=" << gpsi.mId.first << ", msg=" << gpsi.mId.second << ", has exceeded validation time limit. The author's key can probably not be obtained. This is unexpected." << std::endl; -#endif - - delete gpsi.mItem; - pend_it = mMsgPendingValidate.erase(pend_it); - } - else - { - grpMetas.insert(std::make_pair(pend_it->second.mItem->grpId, std::make_shared())); - ++pend_it; - } - } - - // 2 - Retrieve the metadata for the associated groups. The test is here to avoid the default behavior to - // retrieve all groups when the list is empty - - if(!grpMetas.empty()) - mDataStore->retrieveGxsGrpMetaData(grpMetas); - - GxsMsgReq msgIds; - std::list msgs_to_store; - -#ifdef GEN_EXCH_DEBUG - std::cerr << " updating received messages:" << std::endl; -#endif - - // 3 - Validate each message - - for(NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin();pend_it != mMsgPendingValidate.end();) - { - RsNxsMsg* msg = pend_it->second.mItem; - - // (cyril) Normally we should discard posts that are older than the sync request. But that causes a problem because - // RsGxsNetService requests posts to sync by chunks of 20. So if the 20 are discarded, they will be re-synced next time, and the sync process - // will indefinitly loop on the same 20 posts. Since the posts are there already, keeping them is the least problematique way to fix this problem. - // - // uint32_t max_sync_age = ( mNetService != NULL)?( mNetService->getSyncAge(msg->metaData->mGroupId)):RS_GXS_DEFAULT_MSG_REQ_PERIOD; - // - // if(max_sync_age != 0 && msg->metaData->mPublishTs + max_sync_age < time(NULL)) - // { - // std::cerr << "(WW) not validating message " << msg->metaData->mMsgId << " in group " << msg->metaData->mGroupId << " because it is older than synchronisation limit. This message was probably sent by a friend node that does not accept sync limits already." << std::endl; - // ok = false ; - // } - -#ifdef GEN_EXCH_DEBUG - std::cerr << " deserialised info: grp id=" << msg->grpId << ", msg id=" << msg->msgId ; -#endif - auto mit = grpMetas.find(msg->grpId); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " msg info : grp id=" << msg->grpId << ", msg id=" << msg->msgId << std::endl; -#endif - // validate msg - - if(mit == grpMetas.end()) - { - std::cerr << "RsGenExchange::processRecvdMessages(): impossible situation: grp meta " << msg->grpId << " not available." << std::endl; - ++pend_it ; - continue ; - } - - const auto& grpMeta = mit->second; - RsTlvSecurityKeySet keys = grpMeta->keys ; - - GxsSecurity::createPublicKeysFromPrivateKeys(keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing. - - int validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->mSignFlags, keys); - -#ifdef GEN_EXCH_DEBUG - 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) - { - msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - msgs_to_store.push_back(msg); - - msgIds[msg->grpId].insert(msg->msgId); - // std::vector &msgv = msgIds[msg->grpId]; - // if (std::find(msgv.begin(), msgv.end(), msg->msgId) == msgv.end()) - // msgv.push_back(msg->msgId); - - computeHash(msg->msg, msg->metaData->mHash); - msg->metaData->recvTS = time(NULL); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " new status flags: " << msg->metaData->mMsgStatus << std::endl; - std::cerr << " computed hash: " << msg->metaData->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 if(validateReturn == VALIDATE_FAIL) - { - // In this case, we notify the network exchange service not to DL the message again, at least not yet. - -#ifdef GEN_EXCH_DEBUG - std::cerr << "Validation failed for message id " - << "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl; -#endif - messages_to_reject.push_back(msg->msgId) ; - delete msg ; - } - else if(validateReturn == VALIDATE_FAIL_TRY_LATER) - { - ++pend_it ; - continue; - } - - // Remove the entry from mMsgPendingValidate, but do not delete msg since it's either pushed into msg_to_store or deleted in the FAIL case! - - NxsMsgPendingVect::iterator tmp = pend_it ; - ++tmp ; - mMsgPendingValidate.erase(pend_it) ; - pend_it = tmp ; - } - - if(!msgIds.empty()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " removing existing and old messages from incoming list." << std::endl; -#endif - removeDeleteExistingMessages(msgs_to_store, msgIds); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " storing remaining messages" << std::endl; -#endif - - for(auto& nxs_msg: msgs_to_store) - { - RsGxsMsgItem *item = dynamic_cast(mSerialiser->deserialise(nxs_msg->msg.bin_data,&nxs_msg->msg.bin_len)); - - if(!item) - continue; - - item->meta = *nxs_msg->metaData; - - RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, item->meta.mGroupId, item->meta.mMsgId,false); - c->mNewMsgItem = item; - - mNotifications.push_back(c); - } - - mDataStore->storeMessage(msgs_to_store); // All items will be destroyed later on, since msgs_to_store is a temporary map - } - } - - // Done off-mutex to avoid cross deadlocks in the netservice that might call the RsGenExchange as an observer.. - - if(mNetService != NULL) - for(std::list::const_iterator it(messages_to_reject.begin());it!=messages_to_reject.end();++it) - mNetService->rejectMessage(*it) ; -} - -bool RsGenExchange::acceptNewGroup(const RsGxsGrpMetaData* /*grpMeta*/ ) { return true; } -bool RsGenExchange::acceptNewMessage(const RsGxsMsgMetaData* /*grpMeta*/,uint32_t /*size*/ ) { return true; } - -void RsGenExchange::processRecvdGroups() -{ - RS_STACK_MUTEX(mGenMtx) ; - - if(mGrpPendingValidate.empty()) - return; - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::Processing received groups" << std::endl; -#endif - std::list grpIds; - std::list grps_to_store; - - // 1 - retrieve the existing groups so as to check what's not new - std::vector existingGrpIds; - mDataStore->retrieveGroupIds(existingGrpIds); - - // 2 - go through each and every new group data and validate the signatures. - - for(NxsGrpPendValidVect::iterator vit = mGrpPendingValidate.begin(); vit != mGrpPendingValidate.end();) - { - GxsPendingItem& gpsi = vit->second; - RsNxsGrp* grp = gpsi.mItem; - - if(grp->metaData == NULL) - { - RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); - - if(grp->meta.bin_len != 0 && meta->deserialise(grp->meta.bin_data, grp->meta.bin_len)) - grp->metaData = meta ; - else - delete meta ; - } -#ifdef GEN_EXCH_DEBUG - std::cerr << " processing validation for group " << grp->metaData->mGroupId << ", original attempt time: " << time(NULL) - gpsi.mFirstTryTS << " seconds ago" << std::endl; -#endif - - // early deletion of group from the pending list if it's malformed, not accepted, or has been tried unsuccessfully for too long - - if(grp->metaData == NULL || !acceptNewGroup(grp->metaData) || gpsi.mFirstTryTS + VALIDATE_MAX_WAITING_TIME < time(NULL)) - { - NxsGrpPendValidVect::iterator tmp(vit) ; - ++tmp ; - delete grp ; - mGrpPendingValidate.erase(vit) ; - vit = tmp ; - continue; - } - - // group signature validation - - uint8_t ret = validateGrp(grp); - - if(ret == VALIDATE_SUCCESS) - { - grp->metaData->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD; - - computeHash(grp->grp, grp->metaData->mHash); - - // group has been validated. Let's notify the global router for the clue - - if(!grp->metaData->mAuthorId.isNull()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "Group routage info: Identity=" << grp->metaData->mAuthorId << " from " << grp->PeerId() << std::endl; -#endif - mRoutingClues[grp->metaData->mAuthorId].insert(grp->PeerId()) ; - } - - // This has been moved here (as opposed to inside part for new groups below) because it is used to update the server TS when updates - // of grp metadata arrive. - - grp->metaData->mRecvTS = time(NULL); - - // now check if group already exists - - if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end()) - { - grp->metaData->mOriginator = grp->PeerId(); - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED; - - grps_to_store.push_back(grp); - grpIds.push_back(grp->grpId); - } - else - { - GroupUpdate update; - update.newGrp = grp; - mGroupUpdates.push_back(update); - } - } - else if(ret == VALIDATE_FAIL) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " failed to validate incoming meta, grpId: " << grp->grpId << ": wrong signature" << std::endl; -#endif - delete grp; - } - else if(ret == VALIDATE_FAIL_TRY_LATER) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << " failed to validate incoming grp, trying again later. grpId: " << grp->grpId << std::endl; -#endif - ++vit ; - continue; - } - - // Erase entry from the list - - NxsGrpPendValidVect::iterator tmp(vit) ; - ++tmp ; - mGrpPendingValidate.erase(vit) ; - vit = tmp ; - } - - if(!grps_to_store.empty()) - { - for(auto Grp:grps_to_store) - { - RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, Grp->grpId, false); - - c->mNewGroupItem = dynamic_cast(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len)); - - mNotifications.push_back(c); - } - - mDataStore->storeGroup(grps_to_store); // deletes the data after storing it. -#ifdef GEN_EXCH_DEBUG - std::cerr << " adding the following grp ids to notification: " << std::endl; - for(std::list::const_iterator it(grpIds.begin());it!=grpIds.end();++it) - std::cerr << " " << *it << std::endl; -#endif - } -} - -void RsGenExchange::performUpdateValidation() -{ - RS_STACK_MUTEX(mGenMtx) ; - - if(mGroupUpdates.empty()) - return; - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl; -#endif - - RsNxsGrpDataTemporaryMap grpDatas; - - for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit) - grpDatas.insert(std::make_pair(vit->newGrp->grpId, (RsNxsGrp*)NULL)); - - if(grpDatas.empty() || !mDataStore->retrieveNxsGrps(grpDatas,true)) - { - if(grpDatas.empty()) - RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: no group in list!" << std::endl; - else - RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: cannot retrieve froup data for these groups!" << std::endl; - - return; - } - -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl; -#endif - std::list grps; // dont use RsNxsGrpDataTemporaryList because updateGrps will delete the groups - - for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit) - { - GroupUpdate& gu = *vit; - - auto mit = grpDatas.find(gu.newGrp->grpId); - - if(mit == grpDatas.end()) - { - RsErr() << __PRETTY_FUNCTION__ << " Validation of group update failed for group " << gu.newGrp->grpId << " because previous grp version cannot be found." << std::endl; - continue; - } - RsGxsGrpMetaData *oldGrpMeta(mit->second->metaData); - RsNxsGrp *oldGrp(mit->second); - - if(updateValid(*oldGrpMeta, *gu.newGrp)) - { - if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) - gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId(); - - // Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information - // is received. - - gu.newGrp->metaData->mSubscribeFlags = oldGrpMeta->mSubscribeFlags ; - - // Also keep private keys if present - - if(!gu.newGrp->metaData->keys.private_keys.empty()) - std::cerr << "(EE) performUpdateValidation() group " <metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl; - else - gu.newGrp->metaData->keys.private_keys = oldGrpMeta->keys.private_keys ; - - // Now prepare notification of the client - - RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,gu.newGrp->metaData->mGroupId,false); - - c->mNewGroupItem = dynamic_cast(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len)); - c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update - - c->mOldGroupItem = dynamic_cast(mSerialiser->deserialise(oldGrp->grp.bin_data,&oldGrp->grp.bin_len)); - c->mOldGroupItem->meta = *oldGrpMeta; // no need to delete mit->second, as it will be deleted automatically in the temporary map - - mNotifications.push_back(c); - - // finally, add the group to the list to send to mDataStore - - grps.push_back(gu.newGrp); - } - else - { - delete gu.newGrp; // delete here because mDataStore will not take care of this one. no need to delete mit->second, as it will be deleted automatically in the temporary map - gu.newGrp = NULL ; - } - } - - mDataStore->updateGroup(grps); - -#ifdef GEN_EXCH_DEBUG - std::cerr << " adding the following grp ids to notification: " << std::endl; -#endif - - // cleanup - - mGroupUpdates.clear(); -} - -bool RsGenExchange::updateValid(const RsGxsGrpMetaData& oldGrpMeta, const RsNxsGrp& newGrp) const -{ - std::map& signSet = newGrp.metaData->signSet.keySignSet; - std::map::iterator mit = signSet.find(INDEX_AUTHEN_ADMIN); - - if(mit == signSet.end()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::updateValid() new admin sign not found! " << std::endl; - std::cerr << "RsGenExchange::updateValid() grpId: " << oldGrpMeta.mGroupId << std::endl; -#endif - - return false; - } - - RsTlvKeySignature adminSign = mit->second; - RsTlvSecurityKeySet old_keys = oldGrpMeta.keys ; - - GxsSecurity::createPublicKeysFromPrivateKeys(old_keys); // make sure we have the public keys that correspond to the private ones, as it happens. Most of the time this call does nothing. - - std::map& keys = old_keys.public_keys; - std::map::iterator keyMit = keys.find(RsGxsId(oldGrpMeta.mGroupId)); - - if(keyMit == keys.end()) - { -#ifdef GEN_EXCH_DEBUG - std::cerr << "RsGenExchange::updateValid() admin key not found! " << std::endl; -#endif - return false; - } - - // also check this is the latest published group - bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs; - - mGixs->timeStampKey(newGrp.metaData->mAuthorId, RsIdentityUsage(RsServiceType(mServType),RsIdentityUsage::GROUP_ADMIN_SIGNATURE_CREATION, oldGrpMeta.mGroupId)) ; - - return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest; -} - -void RsGenExchange::setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) -{ - RS_STACK_MUTEX(mGenMtx) ; - token = mDataAccess->generatePublicToken(); - - GrpLocMetaData g; - g.grpId = grpId; - g.val.put(RsGeneralDataService::GRP_META_CUTOFF_LEVEL, (int32_t)CutOff); - mGrpLocMetaMap.insert(std::make_pair(token, g)); -} - -void RsGenExchange::removeDeleteExistingMessages( std::list& msgs, GxsMsgReq& msgIdsNotify) -{ - // first get grp ids of messages to be stored - - RsGxsGroupId::std_set mGrpIdsUnique; - - for(std::list::const_iterator cit = msgs.begin(); cit != msgs.end(); ++cit) - mGrpIdsUnique.insert((*cit)->metaData->mGroupId); - - //RsGxsGroupId::std_list grpIds(mGrpIdsUnique.begin(), mGrpIdsUnique.end()); - //RsGxsGroupId::std_list::const_iterator it = grpIds.begin(); - typedef std::map MsgIdReq; - MsgIdReq msgIdReq; - - // now get a list of all msgs ids for each group - for(RsGxsGroupId::std_set::const_iterator it(mGrpIdsUnique.begin()); it != mGrpIdsUnique.end(); ++it) - { - mDataStore->retrieveMsgIds(*it, msgIdReq[*it]); - -#ifdef GEN_EXCH_DEBUG - const std::set& vec(msgIdReq[*it]) ; - std::cerr << " retrieved " << vec.size() << " message ids for group " << *it << std::endl; - - for(auto it2(vec.begin());it2!=vec.end();++it2) - std::cerr << " " << *it2 << std::endl; -#endif - } - - // now for each msg to be stored that exist in the retrieved msg/grp "index" delete and erase from map - for(std::list::iterator cit2 = msgs.begin(); cit2 != msgs.end();) - { - const RsGxsMessageId::std_set& msgIds = msgIdReq[(*cit2)->metaData->mGroupId]; - -#ifdef GEN_EXCH_DEBUG - std::cerr << " grpid=" << (*cit2)->grpId << ", msgid=" << (*cit2)->msgId ; -#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) - // - if(msgIds.find((*cit2)->metaData->mMsgId) != msgIds.end() || !messagePublicationTest( *(*cit2)->metaData)) - { - // msg exist in retrieved index. We should use a std::set here instead of a vector. - - RsGxsMessageId::std_set& notifyIds = msgIdsNotify[ (*cit2)->metaData->mGroupId]; - RsGxsMessageId::std_set::iterator it2 = notifyIds.find((*cit2)->metaData->mMsgId); - - if(it2 != notifyIds.end()) - { - notifyIds.erase(it2); - if (notifyIds.empty()) - { - msgIdsNotify.erase( (*cit2)->metaData->mGroupId); - } - } -#ifdef GEN_EXCH_DEBUG - std::cerr << " discarding " << (*cit2)->msgId << std::endl; -#endif - - delete *cit2; - cit2 = msgs.erase(cit2); - } - else - ++cit2; - } -} - -DistantSearchGroupStatus RsGenExchange::getDistantSearchStatus(const RsGxsGroupId& group_id) -{ - return mNetService->getDistantSearchStatus(group_id) ; -} -void RsGenExchange::turtleGroupRequest(const RsGxsGroupId& group_id) -{ - mNetService->turtleGroupRequest(group_id) ; -} -void RsGenExchange::turtleSearchRequest(const std::string& match_string) -{ - mNetService->turtleSearchRequest(match_string) ; -} - -bool RsGenExchange::localSearch( const std::string& matchString, - std::list& results ) -{ - return mNetService->search(matchString, results); -} - -bool RsGenExchange::exportGroupBase64( - std::string& radix, const RsGxsGroupId& groupId, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(groupId.isNull()) return failure("groupId cannot be null"); - - // We have no blocking API here, so we need to make a blocking request manually. - const std::list groupIds({groupId}); - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - mDataAccess->requestGroupInfo( token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); - - // provide a sync response: actually wait for the token. - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); - - auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most - auto st = mDataAccess->requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = mDataAccess->requestStatus(token); - } - if(st != RsTokenService::COMPLETE) - return failure( "waitToken(...) failed with: " + std::to_string(st) ); - - uint8_t* buf = nullptr; - uint32_t size; - RsGxsGroupId grpId; - - if(!getSerializedGroupData(token, grpId, buf, size)) - return failure("failed retrieving GXS data"); - - Radix64::encode(buf, static_cast(size), radix); - free(buf); - - return true; -} - -bool RsGenExchange::importGroupBase64( - const std::string& radix, RsGxsGroupId& groupId, - std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(radix.empty()) return failure("radix is empty"); - - std::vector mem = Radix64::decode(radix); - if(mem.empty()) return failure("radix seems corrupted"); - - // On success this also import the group as pending validation - if(!deserializeGroupData( - mem.data(), static_cast(mem.size()), - reinterpret_cast(&groupId) )) - return failure("failed deserializing group"); - - return true; -} - -RsGxsChanges::RsGxsChanges() : - RsEvent(RsEventType::GXS_CHANGES), mServiceType(RsServiceType::NONE), - mService(nullptr) {} - -RsGxsIface::~RsGxsIface() = default; -RsGxsGroupSummary::~RsGxsGroupSummary() = default; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h deleted file mode 100644 index 1bb8bbde6..000000000 --- a/libretroshare/src/gxs/rsgenexchange.h +++ /dev/null @@ -1,1015 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgenexchange.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie, Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGENEXCHANGE_H -#define RSGENEXCHANGE_H - -#include -#include "util/rstime.h" - -#include "rsgxs.h" -#include "rsgds.h" -#include "rsnxs.h" -#include "retroshare/rsgxsiface.h" -#include "rsgxsdataaccess.h" -#include "rsnxsobserver.h" -#include "retroshare/rsgxsservice.h" -#include "rsitems/rsnxsitems.h" -#include "gxs/rsgxsnotify.h" -#include "rsgxsutil.h" - -template -class GxsPendingItem -{ -public: - GxsPendingItem(GxsItem item, Identity id,rstime_t ts) : - mItem(item), mId(id), mFirstTryTS(ts) - {} - - bool operator==(const Identity& id) - { - return this->mId == id; - } - - GxsItem mItem; - Identity mId; - rstime_t mFirstTryTS; -}; - -class GxsGrpPendingSign -{ -public: - - GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token), - mItem(item), mHaveKeys(false), mIsUpdate(false) - {} - - rstime_t mLastAttemptTS, mStartTS; - uint32_t mToken; - RsGxsGrpItem* mItem; - bool mHaveKeys; // mKeys->first == true if key present - bool mIsUpdate; - RsTlvSecurityKeySet mKeys; -}; - -typedef std::map > GxsMsgDataMap; -typedef std::map GxsGroupDataMap; -typedef std::map > GxsMsgRelatedDataMap; - -/*! - * This should form the parent class to \n - * all gxs services. This provides access to service's msg/grp data \n - * management/publishing/sync features - * - * Features: \n - * a. Data Access: \n - * Provided by handle to RsTokenService. This ensure consistency \n - * of requests and hiearchy of groups -> then messages which are \n - * sectioned by group ids. \n - * The one caveat is that redemption of tokens are done through \n - * the backend of this class \n - * b. Publishing: \n - * Methods are provided to publish msg and group items and also make \n - * changes to meta information of both item types \n - * c. Sync/Notification: \n - * Also notifications are made here on receipt of new data from \n - * connected peers - */ - -class RsGixs; - -class RsGenExchange : public RsNxsObserver, public RsTickingThread, - public RsGxsIface -{ -public: - - /// used by class derived for RsGenExchange to indicate if service create passed or not - enum ServiceCreate_Return { SERVICE_CREATE_SUCCESS, SERVICE_CREATE_FAIL, SERVICE_CREATE_FAIL_TRY_LATER } ; - - /*! - * Constructs a RsGenExchange object, the owner ship of gds, ns, and serviceserialiser passes \n - * onto the constructed object - * @param gds Data service needed to act as store of message - * @param ns Network service needed to synchronise data with rs peers - * @param serviceSerialiser The users service needs this \n - * in order for gen exchange to deal with its data types - * @param mServType This should be service type used by the serialiser - * @param gixs This is used for verification of msgs and groups received by Gen Exchange using identities. - * @param authenPolicy This determines the authentication used for verfying authorship of msgs and groups - */ - RsGenExchange( - RsGeneralDataService* gds, RsNetworkExchangeService* ns, - RsSerialType* serviceSerialiser, uint16_t mServType, RsGixs* gixs, - uint32_t authenPolicy ); - - virtual ~RsGenExchange(); - - // Convention that this is implemented here. - // and passes to network service. - virtual RsServiceInfo getServiceInfo() = 0; - - void setNetworkExchangeService(RsNetworkExchangeService *ns) ; - - /** S: Observer implementation **/ - - /*! - * @param messages messages are deleted after function returns - */ - virtual void receiveNewMessages(const std::vector &messages) override; - - /*! - * @param groups groups are deleted after function returns - */ - virtual void receiveNewGroups(const std::vector &groups) override; - - /*! - * @param grpId group id - */ - virtual void notifyReceivePublishKey(const RsGxsGroupId &grpId) override; - - virtual void notifyChangedGroupSyncParams(const RsGxsGroupId &grpId) override; - /*! - * \brief notifyReceiveDistantSearchResults - * Should be called when new search results arrive. - * \param grpId - */ - virtual void receiveDistantSearchResults(TurtleRequestId id,const RsGxsGroupId &grpId) override; - /*! - * @param grpId group id - */ - virtual void notifyChangedGroupStats(const RsGxsGroupId &grpId) override; - - /** E: Observer implementation **/ - - /*! - * This is called by Gxs service runner - * periodically, use to implement non - * blocking calls - */ - void tick(); - - /*! - * Any backgroup processing needed by - */ - virtual void service_tick() = 0; - - /*! - * - * @return handle to token service handle for making - * request to this gxs service - */ - RsTokenService* getTokenService(); - - void threadTick() override; /// @see RsTickingThread - - /*! - * Policy bit pattern portion - */ - enum PrivacyBitPos { PUBLIC_GRP_BITS, RESTRICTED_GRP_BITS, PRIVATE_GRP_BITS, GRP_OPTION_BITS } ; - - /*! - * Convenience function for setting bit patterns of the individual privacy level authentication - * policy and group options - * @param flag the bit pattern (and policy) set for the privacy policy - * @param authenFlag Only the policy portion chosen will be modified with 'flag', - * the origianl flags in the indicated bit position (pos) are over-written - * @param pos The policy bit portion to modify - * @see PrivacyBitPos - */ - static bool setAuthenPolicyFlag(const uint8_t& flag, uint32_t& authenFlag, const PrivacyBitPos& pos); - -public: - - /** data access functions **/ - - /*! - * Retrieve group list for a given token - * @param token - * @param groupIds - * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready - */ - bool getGroupList(const uint32_t &token, std::list &groupIds); - - /*! - * Retrieve msg list for a given token sectioned by group Ids - * @param token token to be redeemed - * @param msgIds a map of grpId -> msgList (vector) - * @return false if could not redeem token - */ - bool getMsgList(const uint32_t &token, GxsMsgIdResult &msgIds); - - /*! - * Retrieve msg list for a given token for message related info - * @param token token to be redeemed - * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) - * @return false if could not redeem token - */ - bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds)override; - - - /*! - * retrieve group meta data associated to a request token - * @param token - * @param groupInfo - * @return false if could not redeem token - */ - bool getGroupMeta(const uint32_t &token, std::list& groupInfo)override; - - /*! - * retrieves message meta data associated to a request token - * @param token token to be redeemed - * @param msgInfo the meta data to be retrieved for token store here - */ - bool getMsgMeta(const uint32_t &token, GxsMsgMetaMap &msgInfo)override; - - /*! - * Retrieve msg meta for a given token for message related info - * @param token token to be redeemed - * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) - * @return false if could not redeem token - */ - bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta)override; - - /*! - * Retrieves the meta data of a newly created group. The meta is kept in cache for the current session. - * \param token token that was used to create the group - * \param meta meta data for this group - * \return false if the group is not yet created. - */ - bool getPublishedGroupMeta(const uint32_t& token,RsGroupMetaData& meta); - - /*! - * Retrieves the meta data of a newly created post. The meta is kept in cache for the current session. - * \param token token that was used to create the post - * \param meta meta data for this post - * \return false if the group is not yet created. - */ - bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta); - -#ifdef TO_REMOVE - /*! - * Gxs services should call this for automatic handling of - * changes, send - * @param changes - */ - virtual void receiveChanges(std::vector& changes); -#endif - - /*! - * \brief acceptNewGroup - * Early checks if the group can be accepted. This is mainly used to check wether the group is banned for some reasons. - * Returns true unless derived in GXS services. - * - * \param grpMeta Group metadata to check - * \return - */ - virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) ; - - /*! - * \brief acceptNewMessage - * Early checks if the message can be accepted. This is mainly used to check wether the group is for instance overloaded and the service wants - * to put limitations to it. - * Returns true unless derived in GXS services. - * - * \param grpMeta Group metadata to check - * \return - */ - virtual bool acceptNewMessage(const RsGxsMsgMetaData *msgMeta, uint32_t size) ; - - bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) override; - - /*! - * Gets service statistic for a given services - * @param token value to to retrieve requested stats - * @param stats the status - * @return true if token exists false otherwise - */ - bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) override; - - /*! - * Get group statistic - * @param token to be redeemed - * @param stats the stats associated to token requ - * @return true if token is false otherwise - */ - bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) override; - - /*! - * \brief turtleGroupRequest - * Issues a browadcast group request using the turtle router generic search system. The request is obviously asynchroneous and will be - * handled in RsGenExchange when received. - * \param group_id - */ - void turtleGroupRequest(const RsGxsGroupId& group_id); - void turtleSearchRequest(const std::string& match_string); - - /*! - * \brief getDistantSearchStatus - * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, - * data request ongoing and data available - */ - DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) ; - - /** - * @brief Search local groups. Blocking API. - * @param matchString string to look for in the search - * @param results storage for results - * @return false on error, true otherwise - */ - bool localSearch( const std::string& matchString, - std::list& results ); - - /// @see RsGxsIface - bool exportGroupBase64( - std::string& radix, const RsGxsGroupId& groupId, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsIface - bool importGroupBase64( - const std::string& radix, - RsGxsGroupId& groupId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - -protected: - - bool messagePublicationTest(const RsGxsMsgMetaData&) ; - /*! - * retrieves group data associated to a request token - * @param token token to be redeemed for grpitem retrieval - * @param grpItem the items to be retrieved for token are stored here - */ - bool getGroupData(const uint32_t &token, std::vector& grpItem); - - /*! - * \brief getSerializedGroupData - * Retrieves the complete group data serialized into a chunk of memory. This can be useful to - * transfer a full group from one machine to another. - * - * \param token token previously obtained from cache request - * \param data memory chunk allocated (using malloc) - * \param size size of the memory chunk. - * \return - */ - - bool getSerializedGroupData(uint32_t token, RsGxsGroupId &id, - unsigned char *& data, uint32_t& size); - bool deserializeGroupData(unsigned char *data, uint32_t size, - RsGxsGroupId* gId = nullptr); - - /*! - * \brief retrieveNxsIdentity - * Sync version of the previous method. Might take some time, so should be used carefully. - */ - bool retrieveNxsIdentity(const RsGxsGroupId& group_id,RsNxsGrp *& identity_grp); - - template - bool getGroupDataT(const uint32_t &token, std::vector& grpItem) - { - std::vector items; - bool ok = getGroupData(token, items); - std::vector::iterator vit = items.begin(); - - for(; vit != items.end(); ++vit) - { - RsGxsGrpItem* gi = *vit; - - GrpType* item = dynamic_cast(gi); - - if(item) - { - grpItem.push_back(item); - } - else - { -#ifdef GXS_DEBUG - std::cerr << "\nRsGenExchange::getGroupDataT(): Wrong type!\n"; -#endif - delete gi; - } - } - - return ok; - } - -public: - - /*! - * retrieves message data associated to a request token - * @param token token to be redeemed for message item retrieval - * @param msgItems - */ - bool getMsgData(uint32_t token, GxsMsgDataMap& msgItems); - - template - bool getMsgDataT( uint32_t token, std::map >& msgItems) - { - GxsMsgDataMap msgData; - bool ok = getMsgData(token, msgData); - - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - const RsGxsGroupId& grpId = mit->first; - std::vector& mv = mit->second; - std::vector::iterator vit = mv.begin(); - for(; vit != mv.end(); ++vit) - { - RsGxsMsgItem* mi = *vit; - MsgType* mt = dynamic_cast(mi); - - if(mt != NULL) - { - msgItems[grpId].push_back(mt); - } - else - { - std::cerr << "RsGenExchange::getMsgDataT(): bad cast to msg type" << std::endl; - delete mi; - } - } - } - - return ok; - } - - /*! - * retrieves message related data associated to a request token - * @param token token to be redeemed for message item retrieval - * @param msgItems - */ - bool getMsgRelatedData(uint32_t token, GxsMsgRelatedDataMap& msgItems); - -protected: - - /*! - * Convenience template function for retrieve - * msg related data from - * @param GxsMsgType This represent derived msg class type of the service (i.e. msg type that derives from RsGxsMsgItem - * @param MsgType Represents the final type the core data is converted to - * @param token token to be redeemed - */ - template - bool getMsgRelatedDataT(const uint32_t &token, std::map > &msgItems) - { - - RsStackMutex stack(mGenMtx); - NxsMsgRelatedDataResult msgResult; - bool ok = mDataAccess->getMsgRelatedData(token, msgResult); - NxsMsgRelatedDataResult::iterator mit = msgResult.begin(); - - if(ok) - { - for(; mit != msgResult.end(); ++mit) - { - std::vector gxsMsgItems; - const RsGxsGrpMsgIdPair& msgId = mit->first; - std::vector& nxsMsgsV = mit->second; - std::vector::iterator vit - = nxsMsgsV.begin(); - for(; vit != nxsMsgsV.end(); ++vit) - { - RsNxsMsg*& msg = *vit; - RsItem* item = NULL; - - if(msg->msg.bin_len != 0) - item = mSerialiser->deserialise(msg->msg.bin_data, - &msg->msg.bin_len); - - GxsMsgType* mItem = NULL; - - if(item) - mItem = dynamic_cast(item); - - if(mItem == NULL) - { - delete msg; - continue; - } - - mItem->meta = *((*vit)->metaData); // get meta info from nxs msg - // GxsMsgType m = (*mItem); // doesn't work! don't know why, even with overloading done. - MsgType theServMsg = (MsgType)*mItem; - gxsMsgItems.push_back(theServMsg); - delete msg; - } - msgItems[msgId] = gxsMsgItems; - } - } - return ok; - } - -public: - /*! - * Generate a new token, the status of the token can be queried from request - * status feature. - * @attention the token space is shared with RsGenExchange backend. - * @return Generated token - */ - uint32_t generatePublicToken(); - - /*! - * Updates the status of associate token - * @warning the token space is shared with RsGenExchange backend, so do not - * modify tokens except does you have created by calling generatePublicToken() - * @param token - * @param status - * @return false if token could not be found, true if token disposed of - */ - bool updatePublicRequestStatus( - uint32_t token, RsTokenService::GxsRequestStatus status); - - /*! - * This gets rid of a publicly issued token - * @param token - * @return false if token could not found, true if token is disposed of - */ - bool disposeOfPublicToken(const uint32_t &token); - -protected: - /*! - * This gives access to the data store which hold msgs and groups - * for the service - * @return Data store for retrieving msgs and groups - */ - RsGeneralDataService* getDataStore(); - - /*! - * Retrieve keys for a given group, \n - * call is blocking retrieval from underlying db - * @warning under normal circumstance a service should not need this - * @param grpId the id of the group to retrieve keys for - * @param keys set to the retrieved keys - * @return false if group does not exist or grpId is empty - */ - bool getGroupKeys(const RsGxsGroupId& grpId, RsTlvSecurityKeySet& keySet); - -public: - - /*! - * This allows the client service to acknowledge that their msgs has \n - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeTokenMsg(const uint32_t& token, RsGxsGrpMsgIdPair& msgId); - - /*! - * This allows the client service to acknowledge that their grps has \n - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param grpId ids of created/modified group - * @return true if token exists false otherwise - */ - bool acknowledgeTokenGrp(const uint32_t& token, RsGxsGroupId& grpId); - -protected: - - /** Modifications **/ - - /*! - * Enables publication of a group item \n - * This will induce a related change message \n - * Ownership of item passes to this rsgenexchange \n - * @param token - * @param grpItem - */ - void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem); - - /*! - * Updates an existing group item \n - * This will induce a related change message \n - * Ownership of item passes to this rsgenexchange \n - * @param token - * @param grpItem - */ - void updateGroup(uint32_t& token, RsGxsGrpItem* grpItem); - - /*! - * Deletes an existing group item \n - * This will induce a related change message \n - * Ownership of item passes to this rsgenexchange \n - * @param token - * @param grpItem - */ - void deleteGroup(uint32_t& token, const RsGxsGroupId &grpId); - -public: - /*! - * Enables publication of a message item \n - * Setting mOrigMsgId meta member to blank \n - * leads to this msg being an original msg \n - * if mOrigMsgId is not blank the msgId then this msg is \n - * considered a versioned msg \n - * Ownership of item passes to this rsgenexchange - * @param token - * @param msgItem - */ - void publishMsg(uint32_t& token, RsGxsMsgItem* msgItem); - - /*! - * Deletes the messages \n - * This will induce a related change message \n - * @param token - * @param msgs - */ - void deleteMsgs(uint32_t& token, const GxsMsgReq& msgs); - -protected: - /*! - * This represents the group before its signature is calculated - * Reimplement this function if you need to access keys to further extend - * security of your group items using keyset properties - * Derived service should return one of three ServiceCreate_Return enum values below - * @warning do not modify keySet! - * @param grp The group which is stored by GXS prior - * service can make specific modifications need - * in particular access to its keys and meta - * @param keySet this is the key set used to define the group - * contains private and public admin and publish keys - * (use key flags to distinguish) - * @return SERVICE_CREATE_SUCCESS, SERVICE_CREATE_FAIL, SERVICE_FAIL_TRY_LATER - */ - virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); - - /*! - * \brief service_checkIfGroupIsStillUsed - * Re-implement this function to help GXS cleaning, by telling that some particular group - * is not used anymore. This usually depends on subscription, the fact that friend nodes send - * some info or not, and particular cleaning strategy of each service. - * Besides, groups in some services are used by other services (e.g. identities, circles, are used in - * forums and so on), so deciding on a group usage can only be left to the specific service it is used in. - * \return - * true if the group is still used, false otherwise, meaning that the group can be deleted. Default is - * that the group is always in use. - */ - virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& /* meta */) { return true; } // see RsGenExchange - - /*! - * \brief service_getLastGroupSeenTs - * \return - * returns the last time a friend sent information (statistics) about this group. That practically means when the - * group was still being subscribed by at least one friend. This is used by service_checkIfGroupIsStillUsed() to - * help getting rid of dead groups. - */ - virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) { return 0; } -public: - - /*! - * sets the group subscribe flag - * @param token this is set to token value associated to this request - * @param grpId Id of group whose subscribe file will be changed - * @param status - * @param mask - */ - void setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - - /*! - * sets the group subscribe flag - * @param token this is set to token value associated to this request - * @param grpId Id of group whose subscribe file will be changed - * @param status - * @param mask - */ - void setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - - /*! - * sets the group service string - * @param token this is set to token value associated to this request - * @param grpId Id of group whose subscribe file will be changed - * @param servString - */ - void setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); - - /*! - * - * @param token value set to be redeemed with acknowledgement - * @param grpId group id for cutoff value to be set - * @param CutOff The cut off value to set - */ - void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff); - - /*! - * - * @param token value set to be redeemed with acknowledgement - * @param grpId group id of the group to update - * @param CutOff The cut off value to set - */ - void updateGroupLastMsgTimeStamp(uint32_t& token, const RsGxsGroupId& grpId); - - /*! - * sets the msg status flag - * @param token this is set to token value associated to this request - * @param grpId Id of group whose subscribe file will be changed - * @param status - * @param mask Mask to apply to status flag - */ - void setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); - - /*! - * sets the message service string - * @param token this is set to token value associated to this request - * @param msgId Id of message whose service string will be changed - * @param servString The service string to set msg to - */ - void setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); - - /*! - * sets the message service string - */ - - void shareGroupPublishKey(const RsGxsGroupId& grpId,const std::set& peers) ; - - /*! - * Returns the local TS of the group as known by the network service. - * This is useful to allow various network services to sync their update TS - * when needed. Typical use case is forums and circles. - * @param gid GroupId the TS is which is requested - */ - bool getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) ; - - /*! - * \brief getDefaultStoragePeriod. All times in seconds. - * \return - */ - virtual uint32_t getDefaultStoragePeriod() override{ return mNetService->getDefaultKeepAge() ; } - - virtual uint32_t getStoragePeriod(const RsGxsGroupId& grpId) override; - virtual void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) override; - - virtual uint32_t getDefaultSyncPeriod()override; - virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) override; - virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) override; - virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats); - - uint16_t serviceType() const override { return mServType ; } - uint32_t serviceFullType() const { return RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(mServType); } - - virtual RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_flags )override; -protected: - - /** Notifications **/ - - /*! - * This confirms this class as an abstract one that \n - * should not be instantiated \n - * The deriving class should implement this function \n - * as it is called by the backend GXS system to \n - * update client of changes which should \n - * instigate client to retrieve new content from the system - * Note! For newly received message and groups, bit 0xf00 is set to - * GXS_SERV::GXS_MSG_STATUS_UNPROCESSED and GXS_SERV::GXS_MSG_STATUS_UNREAD - * @param changes the changes that have occured to data held by this service - */ - virtual void notifyChanges(std::vector& changes) = 0; - -private: - - void processRecvdData(); - - void processRecvdMessages(); - - void processRecvdGroups(); - - void publishGrps(); - - void processGroupUpdatePublish(); - - void processGroupDelete(); - void processMessageDelete(); - void processRoutingClues(); - - void publishMsgs(); - - bool checkGroupMetaConsistency(const RsGroupMetaData& meta); - - /*! - * processes msg local meta changes - */ - void processMsgMetaChanges(); - - /*! - * Processes group local meta changes - */ - void processGrpMetaChanges(); - - /*! - * Convenience function for properly applying masks for status and subscribe flag - * of a group. - * @warning mask entry is removed from grpCv - */ - bool processGrpMask(const RsGxsGroupId& grpId, ContentValue& grpCv); - - /*! - * This completes the creation of an instance on RsNxsGrp - * by assigning it a groupId and signature via SHA1 and EVP_sign respectively \n - * @param grp Nxs group to create - * @return CREATE_SUCCESS for success, CREATE_FAIL for fail, - * CREATE_FAIL_TRY_LATER for Id sign key not avail (but requested) - */ - uint8_t createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); - -protected: - /*! - * This completes the creation of an instance on RsNxsMsg - * by assigning it a groupId and signature via SHA1 and EVP_sign respectively - * What signatures are calculated are based on the authentication policy - * of the service - * @param msg the Nxs message to create - * @return CREATE_SUCCESS for success, CREATE_FAIL for fail, - * CREATE_FAIL_TRY_LATER for Id sign key not avail (but requested) - */ - int createMessage(RsNxsMsg* msg); - - RsNetworkExchangeService *netService() const { return mNetService ; } - -private: - /*! - * convenience function to create sign - * @param signSet signatures are stored here - * @param msgData message data to be signed - * @param grpMeta the meta data for group the message belongs to - * @return SIGN_SUCCESS for success, SIGN_FAIL for fail, - * SIGN_FAIL_TRY_LATER for Id sign key not avail (but requested), try later - */ - int createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, - const RsGxsMsgMetaData& msgMeta, const RsGxsGrpMetaData& grpMeta); - - /*! - * convenience function to create sign for groups - * @param signSet signatures are stored here - * @param grpData group data to be signed - * @param grpMeta the meta data for group to be signed - * @return SIGN_SUCCESS for success, SIGN_FAIL for fail, - * SIGN_FAIL_TRY_LATER for Id sign key not avail (but requested), try later - */ - int createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& grpData, - RsGxsGrpMetaData& grpMeta); - - /*! - * check meta change is legal - * @return false if meta change is not legal - */ - bool locked_validateGrpMetaChange(GrpLocMetaData&); - - /*! - * Generate a set of keys that can define a GXS group - * @param privatekeySet contains private generated keys - * @param publickeySet contains public generated keys (counterpart of private) - * @param genPublicKeys should publish key pair also be generated - */ - void generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys); - - /*! - * Attempts to validate msg signatures - * @param msg message to be validated - * @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, const uint32_t &signFlag, RsTlvSecurityKeySet& grpKeySet); - - /*! - * Attempts to validate group signatures - * @param grp group to be validated - * @return VALIDATE_SUCCESS for success, VALIDATE_FAIL for fail, - * VALIDATE_ID_SIGN_NOT_AVAIL for Id sign key not avail (but requested) - */ - int validateGrp(RsNxsGrp* grp); - - /*! - * Checks flag against a given privacy bit block - * @param pos Determines 8 bit wide privacy block to check - * @param flag the flag to and(&) against - * @param the result of the (bit-block & flag) - */ - bool checkAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const; - - void groupShareKeys(std::list peers); - - static void computeHash(const RsTlvBinaryData& data, RsFileHash& hash); - - /*! - * Checks validation of recently received groups to be - * updated (and updates them, a bit of a misnomer) - */ - void performUpdateValidation(); - - /*! - * Checks if the update is valid (i.e. the new admin signature is by the old admin key) - * @param oldGrp the old group to be updated (must have meta data member initialised) - * @param newGrp the new group that updates the old group (must have meta data member initialised) - * @return - */ - bool updateValid(const RsGxsGrpMetaData& oldGrp, const RsNxsGrp& newGrp) const; - - /*! - * convenience function for checking private publish and admin keys are present - * @param keySet The keys set to split into a private and public set - * @return false, if private admin and publish keys cannot be found, true otherwise - */ - bool checkKeys(const RsTlvSecurityKeySet& keySet); - - /*! - * Message and notification map passed to method - * are cleansed of msgs and ids that already exist in database - * @param msgs messages to be filtered - * @param msgIdsNotify message notification map to be filtered - */ - void removeDeleteExistingMessages(std::list& msgs, GxsMsgReq& msgIdsNotify); - - RsMutex mGenMtx; - RsGxsDataAccess* mDataAccess; - RsGeneralDataService* mDataStore; - RsNetworkExchangeService *mNetService; - RsSerialType *mSerialiser; - /// service type - uint16_t mServType; - RsGixs* mGixs; - - std::vector mReceivedMsgs; - - typedef std::map > NxsGrpPendValidVect; - NxsGrpPendValidVect mGrpPendingValidate; - - std::vector mGrpsToPublish; - typedef std::vector NxsGrpSignPendVect; - - std::map mPublishedGrps ; // keeps track of which group was created using which token - std::map mPublishedMsgs ; // keeps track of which message was created using which token - - std::map mMsgsToPublish; - - std::map mMsgNotify; - std::map mGrpNotify; - - // for loc meta changes - std::map mGrpLocMetaMap; - std::map mMsgLocMetaMap; - - std::vector mNotifications; - - - - /// authentication policy - uint32_t mAuthenPolicy; - - std::map > mMsgPendingSign; - - typedef std::map > NxsMsgPendingVect; - NxsMsgPendingVect mMsgPendingValidate; - - bool mCleaning; - rstime_t mLastClean; - - bool mChecking, mCheckStarted; - rstime_t mLastCheck; - RsGxsIntegrityCheck* mIntegrityCheck; - RsGxsGroupId mNextGroupToCheck ; - -protected: - enum CreateStatus { CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER }; - const uint8_t SIGN_MAX_WAITING_TIME; - // TODO: cleanup this should be an enum! - const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER; - const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_WAITING_TIME; - -private: - - std::vector mGroupUpdates, mPeersGroupUpdate; - - std::vector mGroupUpdatePublish; - std::vector mGroupDeletePublish; - std::vector mMsgDeletePublish; - - std::map > mRoutingClues ; - - friend class RsGxsCleanUp; -}; - -#endif // RSGENEXCHANGE_H diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h deleted file mode 100644 index 955aea673..000000000 --- a/libretroshare/src/gxs/rsgixs.h +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgixs.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie, Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGIXS_H -#define RSGIXS_H - -#include "gxs/rsgxs.h" -#include "gxs/rsgenexchange.h" - -#include "retroshare/rsgxscircles.h" - -#include "serialiser/rstlvkeys.h" -#include "retroshare/rsids.h" -/*! - * GIXP: General Identity Exchange Service. - * - * As we're always running into troubles with GPG signatures... we are going to - * create a layer of RSA Keys for the following properties: - * - * 1) RSA Keys can be Anonymous, Self-Signed with Pseudonym, Signed by GPG Key. - * To clarify: - * a. This forms a layer of keys stay between GPG and pub/priv publish key ? - * b. Difference between anonymous and pseudonym keys? - * - Anonymous cannot be signed? - * - - * c. To some extent this determines security model of RsGeneralExchangeService - - * - Anonymous & Pseudonym Keys will be shared network-wide (Hop by Hop). - - GPG signed Keys will only be shared if we can validate the signature - (providing similar behaviour to existing GPG Keys). - - GPG signed Keys can optionally be marked for Network-wide sharing. - * 2) These keys can be used anywhere, specifically in the protocols described below. - * 3) These keys can be used to sign, encrypt, verify & decrypt - * 4) Keys will never need to be directly accessed - stored in this class. - * a. I guess can work solely through Id - * b. Use Case: Receivve a message, has a key id, request - * 5) They will be cached locally and exchanged p2p, by pull request. - * 6) This class will use the generalised packet storage for efficient caching & loading. - * 7) Data will be stored encrypted. - */ - - -/****** - * More notes. The ideas above have been crystalised somewhat. - * - * The Identity service will now serve two roles: - * 1) validating msgs. - * 2) reputation of identity. - * - * The identity will be equivalent to a Group Definition. - * and the reputation contained in the group's messages. - * - * - * Group - * MetaData: - * Public Key - * Signatures. (Admin & optional GPG). - * RealData: - * Nickname. - * GPGHash - * - * The GPGHash will allow people to identify the real gpg user behind the identity. - * We must make sure that the Hash input has enough entropy that it cannot be brute-forced (e.g. like password hashes). - * - * The Identity service only has to provide hooks to access the Keys for each group. - * All the key definitions are exactly the same as for GroupMetaData. - * - * The Interface is split into three parts. - * 1) Internal interface used by GXS to verify signatures. - * 2) Internal interface used by GXS to help decide if we get a message or not. - * 3) External interface to access nicknames, generate new identities etc. - * - * The actual implementation will cache frequently used keys and nicknames, - * as these will be used very frequently. - *****/ - -/* Identity Interface for GXS Message Verification. - */ -class RsGixs -{ -public: - // TODO: cleanup this should be an enum! - static const uint32_t RS_GIXS_ERROR_NO_ERROR = 0x0000 ; - static const uint32_t RS_GIXS_ERROR_UNKNOWN = 0x0001 ; - static const uint32_t RS_GIXS_ERROR_KEY_NOT_AVAILABLE = 0x0002 ; - static const uint32_t RS_GIXS_ERROR_SIGNATURE_MISMATCH = 0x0003 ; - - /* Performs/validate a signature with the given key ID. The key must be available, otherwise the signature error - * will report it. Each time a key is used to validate a signature, its usage timestamp is updated. - * - * If force_load is true, the key will be forced loaded from the cache. If not, uncached keys will return - * with error_status=RS_GIXS_SIGNATURE_ERROR_KEY_NOT_AVAILABLE, but will likely be cached on the next call. - */ - - virtual bool signData(const uint8_t *data,uint32_t data_size,const RsGxsId& signer_id,RsTlvKeySignature& signature,uint32_t& signing_error) = 0 ; - virtual bool validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,const RsIdentityUsage& info,uint32_t& signing_error) = 0 ; - - virtual bool encryptData( const uint8_t *clear_data, - uint32_t clear_data_size, - uint8_t *& encrypted_data, - uint32_t& encrypted_data_size, - const RsGxsId& encryption_key_id, - uint32_t& encryption_error, bool force_load) = 0 ; - virtual bool decryptData( const uint8_t *encrypted_data, - uint32_t encrypted_data_size, - uint8_t *& clear_data, uint32_t& clear_data_size, - const RsGxsId& encryption_key_id, - uint32_t& encryption_error, bool force_load) = 0 ; - - virtual bool getOwnIds(std::list &ownIds, bool signed_only = false)=0; - virtual bool isOwnId(const RsGxsId& key_id) = 0 ; - - virtual void timeStampKey(const RsGxsId& key_id,const RsIdentityUsage& reason) = 0 ; - - // Key related interface - used for validating msgs and groups. - /*! - * Use to query a whether given key is available by its key reference - * @param keyref the keyref of key that is being checked for - * @return true if available, false otherwise - */ - virtual bool haveKey(const RsGxsId &id) = 0; - - /*! - * Use to query whether private key member of the given key reference is available - * @param keyref the KeyRef of the key being checked for - * @return true if private key is held here, false otherwise - */ - virtual bool havePrivateKey(const RsGxsId &id) = 0; - - // The fetchKey has an optional peerList.. this is people that had the msg with the signature. - // These same people should have the identity - so we ask them first. - /*! - * Use to request a given key reference - * @param keyref the KeyRef of the key being requested - * @return will - */ - virtual bool requestKey(const RsGxsId &id, const std::list &peers,const RsIdentityUsage& info) = 0; - virtual bool requestPrivateKey(const RsGxsId &id) = 0; - - /*! - * \brief receiveNewIdentity - * Receives a new identity. This is a facility offerred to RsGxsNetService when identities are sent/received by turtle tunnels - */ - virtual bool receiveNewIdentity(RsNxsGrp *identity_grp)=0; - virtual bool retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp)=0; - - /*! - * Retrieves a key identity - * @param keyref - * @return a pointer to a valid profile if successful, otherwise NULL - * - */ - virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey& key) = 0; - virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey& 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 - - virtual ~RsGixs(); -}; - -class GixsReputation -{ -public: - GixsReputation() :reputation_level(0) {} - - RsGxsId id; - uint32_t reputation_level ; -}; - -struct RsGixsReputation -{ - virtual RsReputationLevel overallReputationLevel( - const RsGxsId& id, uint32_t* identity_flags = nullptr ) = 0; - virtual ~RsGixsReputation(){} -}; - -/*** This Class pulls all the GXS Interfaces together ****/ - -struct RsGxsIdExchange : RsGenExchange, RsGixs -{ - RsGxsIdExchange( - RsGeneralDataService* gds, RsNetworkExchangeService* ns, - RsSerialType* serviceSerialiser, uint16_t mServType, - uint32_t authenPolicy ) - : RsGenExchange( - gds, ns, serviceSerialiser, mServType, this, authenPolicy ) {} -}; - - - - -/* For Circles Too */ - -class RsGcxs -{ - public: - virtual ~RsGcxs(){} - - /* GXS Interface - for working out who can receive */ - virtual bool isLoaded(const RsGxsCircleId &circleId) = 0; - virtual bool loadCircle(const RsGxsCircleId &circleId) = 0; - - virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id,bool& should_encrypt) = 0; - virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) = 0; - - virtual bool recipients(const RsGxsCircleId &circleId, std::list& friendlist) = 0; - virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, std::list& idlist) = 0; - - virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) = 0; - - virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) =0; -}; - - - -class RsGxsCircleExchange: public RsGenExchange, public RsGcxs -{ -public: - RsGxsCircleExchange(RsGeneralDataService* gds, RsNetworkExchangeService* ns, RsSerialType* serviceSerialiser, - uint16_t mServType, RsGixs* gixs, uint32_t authenPolicy) - :RsGenExchange(gds,ns,serviceSerialiser,mServType, gixs, authenPolicy) { return; } - virtual ~RsGxsCircleExchange() { return; } - - virtual bool getLocalCircleServerUpdateTS(const RsGxsCircleId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) - { - return RsGenExchange::getGroupServerUpdateTS(RsGxsGroupId(gid),grp_server_update_TS,msg_server_update_TS) ; - } -}; - - -#endif // RSGIXS_H diff --git a/libretroshare/src/gxs/rsgroups.h b/libretroshare/src/gxs/rsgroups.h deleted file mode 100644 index 5a24ac826..000000000 --- a/libretroshare/src/gxs/rsgroups.h +++ /dev/null @@ -1,151 +0,0 @@ -// -// This is a first attempt at managing groups and group permissions -// in libretroshare. -// -// Rules: -// 1 - Groups are handled GPG-wise, and not SSLId wise, but we need to provide functions -// for SSLIds since that's what peers are represented by. -// -// 2 - A peer can be in different groups. That will be useful for e.g. file sharing. -// -// 3 - Global permissions always prevail over permissions given at the group level. For -// instance for discovery between two peers that belong to groups G1 and G2: -// -// | Global discovery flag ON | Global disc flag OFF | -// --------------------+--------------------------+----------------------+ -// Group disc(G1,G2)=1 | Allow | Don't allow | -// Group disc(G1,G2)=0 | Don't allow | Don't allow | -// -// 4 - Binary group permissions are OR-ed between pairs of groups. If peers (A,B) can be matched to -// two different pairs of groups, the flags are combined with an OR. -// -// libretroshare side -// ================== -// We need a matrix for binary group flags, i.e. flags for pair of groups, for: -// -// Turtle traffic: -// * does the turtle traffic can go from peers of a group to another -// * default: yes -// -// Discovery: -// * does the turtle traffic can go from peers of a group to another -// * default: yes. Overriden by discovery status in config. -// -// Public chat lobby advertisement: -// * public lobby coming from peers of a group go to peers of another group -// * default: yes -// -// Relay connexions: -// * allow relay connexions between people of group A and group B. -// -// General Exchange Services: -// * Allow data exchanged from one peers of one group to peers of another group -// -// We need per-group permission flags for: -// -// File download permission: -// * each shared directory belongs to a list of groups -// * each shared directory has a set of DL flags (browsable B,network wide N) for groups and for global. -// * files are listed with unix-like permissions style: -// ---- : file can't be transfered at all. -// bn-- : file is browsable and turtle-able by friends of its groups only. -// b-b- : file is browsable by everybody -// --b- : file is browsable by everybody that does not belong to its groups (can be useful to isolate people in a group) -// -n-- : file is turtle-able by people that belong to its groups only. -// bnbn : file is always accessible in any ways. That's what file sharing is about. Should be the default ;-) -// -// We need to propose some pre-initialized settings to the user, so that he won't have to bother with flags, but we -// need to allow precisely tweaking them as well: -// Directory is -// - Accessible for this group only (allow select a group) -// - Fully shared anonymously -// - [...] -// -// If the shared directory has no groups, than the first two flags are meaningless. -// -// GUI side -// ======== -// - we need a tab in config to manage groups and group flag permission matrix -// - when sharing a directory, the user can act on permissions: setting which groups a -// directory belongs to. -// -// Classes for groups. To be displatched in rstypes.h ? -// - -#pragma once - -typedef RsPeerId SSLId ; -typedef RsPgpId GPGId ; -typedef uint64_t RsGroupId ; - -class RsPeerGroupInfo -{ - public: - RsGroupId group_id ; // Id of the group, should be random and unique in the RS session. - std::string group_name ; // user-defined name of the group ("parents", "friends", etc) - std::set elements ; // people in the group. GPG-wise. -}; - -class GroupFlagsMatrix -{ - public: - // flags - - static const uint32_t GROUP_MATRIX_FLAG_DISCOVERY = 0x1 ; - static const uint32_t GROUP_MATRIX_FLAG_TURTLE = 0x2 ; - static const uint32_t GROUP_MATRIX_FLAG_PUBLIC_LOBBY = 0x4 ; - static const uint32_t GROUP_MATRIX_FLAG_RELAY = 0x8 ; - - // returns/set all flags for a given pair of groups. Used by the - // GUI to draw/modify group flags. - // - uint32_t getGroupFlags(RsGroupId grp1,RsGroupId grp2) const ; - void setGroupFlags(uint32_t flags,RsGroupId grp1,RsGroupId grp2) const ; - - // Returns a given flag for two people in particular. Used by services to - // know what to do or not do. - // - bool groupPermission(uint32_t group_flag,GPGId peer_1,GPGId peer2) const ; - - private: - std::vector _flags ; // vector of size number_of_groups^2 - std::map _group_entries ; // index to read the flags vector. -}; - -// Interface class for Groups. Should go in libretroshare/stc/retroshare/rsgroups.h -// - -class RsGroupManagement -{ - public: - // Group handling - - // Returns false is the group does not exist. Otherwise, fills the GroupInfo struct. - // - virtual bool getGroupInfo(const RsGroupId& id,RsPeerGroupInfo& info) = 0 ; - - // Adds a friend to a group. - virtual bool getGroupInfo(const RsGroupId& id,RsPeerGroupInfo& info) = 0 ; - - // Group permission handling - // - virtual bool allow_TwoPeers_TurtleTraffic (const SSLId& p1,const SSLId& p2) = 0 ; - virtual bool allow_TwoPeers_Discovery (const SSLId& p1,const SSLId& p2) = 0 ; - virtual bool allow_TwoPeers_LobbyAdvertisement(const SSLId& p1,const SSLId& p2) = 0 ; - virtual bool allow_TwoPeers_GeneralExchangeService(const SSLId& p1,const SSLId& p2) = 0 ; - // [...] -}; - -class p3GroupManagement: public RsGroupManagement, public p3Config -{ - public: - // [...] - - private: - std::map _groups ; -}; - -// This is the entry point for external interface. -// -extern RsGroupManagement *rsGroups ; - diff --git a/libretroshare/src/gxs/rsgxs.h b/libretroshare/src/gxs/rsgxs.h deleted file mode 100644 index 696f317ae..000000000 --- a/libretroshare/src/gxs/rsgxs.h +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxs.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXS_H -#define RSGXS_H - -#include "gxs/rsgxsdata.h" - -#include -#include - -/* data types used throughout Gxs from netservice to genexchange */ - -typedef std::map > > GxsMsgMetaResult; -typedef std::map > > MsgRelatedMetaResult; - -// Default values that are used throughout GXS code - -static const uint32_t RS_GXS_DEFAULT_MSG_STORE_PERIOD = 86400 * 372 ; // 1 year. Default time for which messages are keps in the database. -static const uint32_t RS_GXS_DEFAULT_MSG_SEND_PERIOD = 86400 * 30 * 1 ; // one month. Default delay after which we don't send messages -static const uint32_t RS_GXS_DEFAULT_MSG_REQ_PERIOD = 86400 * 30 * 1 ; // one month. Default Delay after which we don't request messages - -#endif // RSGXS_H diff --git a/libretroshare/src/gxs/rsgxsdata.cc b/libretroshare/src/gxs/rsgxsdata.cc deleted file mode 100644 index b83096575..000000000 --- a/libretroshare/src/gxs/rsgxsdata.cc +++ /dev/null @@ -1,360 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsdata.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsgxsdata.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" - -RsGxsGrpMetaData::RsGxsGrpMetaData() -{ - clear(); -} - -uint32_t RsGxsGrpMetaData::serial_size(uint32_t api_version) const -{ - uint32_t s = 8; // header size - - s += mGroupId.serial_size(); - s += mOrigGrpId.serial_size(); - s += mParentGrpId.serial_size(); - s += GetTlvStringSize(mGroupName); - s += 4; // mGroupFlags - s += 4; // mPublishTs - s += 4; // mCircleType - s += 4; // mAuthenFlag - s += mAuthorId.serial_size(); - s += GetTlvStringSize(mServiceString); - s += mCircleId.serial_size(); - s += signSet.TlvSize(); - s += keys.TlvSize(); - - if(api_version == RS_GXS_GRP_META_DATA_VERSION_ID_0002) - s += 4; // mSignFlag - else if(api_version != RS_GXS_GRP_META_DATA_VERSION_ID_0001) - std::cerr << "(EE) wrong/unknown API version " << api_version << " requested in RsGxsGrpMetaData::serial_size()" << std::endl; - - return s; -} - -void RsGxsGrpMetaData::clear(){ - - mGroupId.clear(); - mOrigGrpId.clear(); - mGroupName.clear(); - mGroupFlags = 0; - mPublishTs = 0; - mSignFlags = 0; - mAuthorId.clear(); - - mCircleId.clear(); - mCircleType = 0; - - signSet.TlvClear(); - keys.TlvClear(); - - mServiceString.clear(); - mAuthenFlags = 0; - mParentGrpId.clear(); - - mSubscribeFlags = 0; - - mPop = 0; - mVisibleMsgCount = 0; - mGroupStatus = 0; - mLastPost = 0; - mReputationCutOff = 0; - mGrpSize = 0 ; - - mGroupStatus = 0 ; - mRecvTS = 0; - - mOriginator.clear(); - mInternalCircle.clear(); - mHash.clear() ; -} - -bool RsGxsGrpMetaData::serialise(void *data, uint32_t &pktsize,uint32_t api_version) -{ - uint32_t tlvsize = serial_size(api_version) ; - uint32_t offset = 0; - - if (pktsize < tlvsize) - return false; /* not enough space */ - - pktsize = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, api_version, tlvsize); - -#ifdef GXS_DEBUG - std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; - std::cerr << "RsGxsGrpMetaData serialise(): Header: " << ok << std::endl; - std::cerr << "RsGxsGrpMetaData serialise(): Size: " << tlvsize << std::endl; -#endif - - /* skip header */ - offset += 8; - - ok &= mGroupId.serialise(data, tlvsize, offset); - ok &= mOrigGrpId.serialise(data, tlvsize, offset); - ok &= mParentGrpId.serialise(data, tlvsize, offset); - ok &= SetTlvString(data, tlvsize, &offset, 0, mGroupName); - ok &= setRawUInt32(data, tlvsize, &offset, mGroupFlags); - ok &= setRawUInt32(data, tlvsize, &offset, mPublishTs); - ok &= setRawUInt32(data, tlvsize, &offset, mCircleType); - ok &= setRawUInt32(data, tlvsize, &offset, mAuthenFlags); - ok &= mAuthorId.serialise(data, tlvsize, offset); - ok &= SetTlvString(data, tlvsize, &offset, 0, mServiceString); - ok &= mCircleId.serialise(data, tlvsize, offset); - - ok &= signSet.SetTlv(data, tlvsize, &offset); - ok &= keys.SetTlv(data, tlvsize, &offset); - - if(api_version == RS_GXS_GRP_META_DATA_VERSION_ID_0002) - ok &= setRawUInt32(data, tlvsize, &offset, mSignFlags); // new in API v2. Was previously missing. Kept in the end for backward compatibility - - return ok; -} - -bool RsGxsGrpMetaData::deserialise(void *data, uint32_t &pktsize) -{ - - uint32_t offset = 8; // skip the header - uint32_t rssize = getRsItemSize(data); - - bool ok = true ; - - ok &= rssize == pktsize; - - if(!ok) return false; - - ok &= mGroupId.deserialise(data, pktsize, offset); - ok &= mOrigGrpId.deserialise(data, pktsize, offset); - ok &= mParentGrpId.deserialise(data, pktsize, offset); - ok &= GetTlvString(data, pktsize, &offset, 0, mGroupName); - ok &= getRawUInt32(data, pktsize, &offset, &mGroupFlags); - 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) - { - std::cerr << "WARNING: Deserialised group with mGroupName.length() = " << mGroupName.length() << ". This is not allowed. This item will be dropped." << std::endl; - return false ; - } - if(mServiceString.length() > RsGxsGrpMetaData::MAX_ALLOWED_STRING_SIZE) - { - std::cerr << "WARNING: Deserialised group with mServiceString.length() = " << mGroupName.length() << ". This is not allowed. This item will be dropped." << std::endl; - return false ; - } -#endif - - return ok; -} - -RsGxsMsgMetaData::RsGxsMsgMetaData(){ - clear(); - //std::cout << "\nrefcount++ : " << ++refcount << std::endl; - return; -} - -RsGxsMsgMetaData::~RsGxsMsgMetaData(){ - //std::cout << "\nrefcount-- : " << --refcount << std::endl; - return; -} - -uint32_t RsGxsMsgMetaData::serial_size() const -{ - - uint32_t s = 8; // header size - - s += mGroupId.serial_size(); - s += mMsgId.serial_size(); - s += mThreadId.serial_size(); - s += mParentId.serial_size(); - s += mOrigMsgId.serial_size(); - s += mAuthorId.serial_size(); - - s += signSet.TlvSize(); - s += GetTlvStringSize(mMsgName); - s += 4; // mPublishTS - s += 4; // mMsgFlags - - return s; -} - -void RsGxsMsgMetaData::clear() -{ - mGroupId.clear(); - mMsgId.clear(); - mThreadId.clear(); - mParentId.clear(); - mOrigMsgId.clear(); - mAuthorId.clear(); - - signSet.TlvClear(); - mMsgName.clear(); - mPublishTs = 0; - mMsgFlags = 0; - - mServiceString.clear(); - mMsgStatus = 0; - mMsgSize = 0; - mChildTs = 0; - recvTS = 0; - mHash.clear(); - validated = false; -} - -bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size) -{ - uint32_t tlvsize = serial_size() ; - uint32_t offset = 0; - - if (*size < tlvsize) - return false; /* not enough space */ - - *size = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, RS_GXS_MSG_META_DATA_VERSION_ID_0002, tlvsize); - -#ifdef GXS_DEBUG - std::cerr << "RsGxsGrpMetaData serialise()" << std::endl; - std::cerr << "RsGxsGrpMetaData serialise(): Header: " << ok << std::endl; - std::cerr << "RsGxsGrpMetaData serialise(): Size: " << tlvsize << std::endl; -#endif - - /* skip header */ - offset += 8; - - ok &= mGroupId.serialise(data, *size, offset); - ok &= mMsgId.serialise(data, *size, offset); - ok &= mThreadId.serialise(data, *size, offset); - ok &= mParentId.serialise(data, *size, offset); - ok &= mOrigMsgId.serialise(data, *size, offset); - ok &= mAuthorId.serialise(data, *size, offset); - - ok &= signSet.SetTlv(data, *size, &offset); - ok &= SetTlvString(data, *size, &offset, 0, mMsgName); - ok &= setRawUInt32(data, *size, &offset, mPublishTs); - ok &= setRawUInt32(data, *size, &offset, mMsgFlags); - - return ok; -} - - -bool RsGxsMsgMetaData::deserialise(void *data, uint32_t *size) -{ - uint32_t offset = 8; // skip the header - uint32_t rssize = getRsItemSize(data); - - bool ok = true ; - - ok &= rssize == *size; - - if(!ok) return false; - - ok &= mGroupId.deserialise(data, *size, offset); - ok &= mMsgId.deserialise(data, *size, offset); - ok &= mThreadId.deserialise(data, *size, offset); - ok &= mParentId.deserialise(data, *size, offset); - ok &= mOrigMsgId.deserialise(data, *size, offset); - ok &= mAuthorId.deserialise(data, *size, offset); - - ok &= signSet.GetTlv(data, *size, &offset); - ok &= GetTlvString(data, *size, &offset, 0, mMsgName); - uint32_t t=0; - ok &= getRawUInt32(data, *size, &offset, &t); - mPublishTs = t; - ok &= getRawUInt32(data, *size, &offset, &mMsgFlags); - - return ok; -} - -void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta) -{ - this->mAuthorId = rMeta.mAuthorId; - this->mGroupFlags = rMeta.mGroupFlags; - this->mGroupId = rMeta.mGroupId; - this->mGroupStatus = rMeta.mGroupStatus ; - this->mLastPost = rMeta.mLastPost; - this->mVisibleMsgCount = rMeta.mVisibleMsgCount ; - this->mPop = rMeta.mPop; - this->mPublishTs = rMeta.mPublishTs; - this->mSubscribeFlags = rMeta.mSubscribeFlags; - this->mGroupName = rMeta.mGroupName; - this->mServiceString = rMeta.mServiceString; - this->mSignFlags = rMeta.mSignFlags; - this->mCircleId = rMeta.mCircleId; - this->mCircleType = rMeta.mCircleType; - this->mInternalCircle = rMeta.mInternalCircle; - this->mOriginator = rMeta.mOriginator; - this->mAuthenFlags = rMeta.mAuthenFlags; - //std::cout << "rMeta.mParentGrpId= " <mParentGrpId = rMeta.mParentGrpId; -} - -void RsGxsMsgMetaData::operator =(const RsMsgMetaData& rMeta) -{ - this->mAuthorId = rMeta.mAuthorId; - this->mChildTs = rMeta.mChildTs ; - this->mGroupId = rMeta.mGroupId; - this->mMsgFlags = rMeta.mMsgFlags ; - this->mMsgId = rMeta.mMsgId ; - this->mMsgName = rMeta.mMsgName; - this->mMsgStatus = rMeta.mMsgStatus; - this->mOrigMsgId = rMeta.mOrigMsgId; - this->mParentId = rMeta.mParentId ; - this->mPublishTs = rMeta.mPublishTs ; - this->mThreadId = rMeta.mThreadId; - this->mServiceString = rMeta.mServiceString; -} - - diff --git a/libretroshare/src/gxs/rsgxsdata.h b/libretroshare/src/gxs/rsgxsdata.h deleted file mode 100644 index acc0c71d8..000000000 --- a/libretroshare/src/gxs/rsgxsdata.h +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsdata.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSMETA_H -#define RSGXSMETA_H - -#include - -#include "retroshare/rstypes.h" -#include "serialiser/rstlvkeys.h" -#include "util/rstime.h" -#include "rsitems/rsgxsitems.h" - -struct RsGroupMetaData; -struct RsMsgMetaData; - -static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0001 = 0x0000 ; // change this, and keep old values if the content changes -static const uint32_t RS_GXS_GRP_META_DATA_VERSION_ID_0002 = 0xaf01 ; // current API - -static const uint32_t RS_GXS_MSG_META_DATA_VERSION_ID_0002 = 0x0000 ; // current API - -static const uint32_t RS_GXS_GRP_META_DATA_CURRENT_API_VERSION = RS_GXS_GRP_META_DATA_VERSION_ID_0002; - -class RsGxsGrpMetaData -{ -public: - static const int MAX_ALLOWED_STRING_SIZE = 50 ; - - RsGxsGrpMetaData(); - bool deserialise(void *data, uint32_t &pktsize); - bool serialise(void* data, uint32_t &pktsize, uint32_t api_version); - uint32_t serial_size(uint32_t api_version) const; - uint32_t serial_size() const { return serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); } - void clear(); - void operator =(const RsGroupMetaData& rMeta); - - //Sort data in same order than serialiser and deserializer - RsGxsGroupId mGroupId; - RsGxsGroupId mOrigGrpId; - RsGxsGroupId mParentGrpId; - std::string mGroupName; - uint32_t mGroupFlags; // GXS_SERV::FLAG_PRIVACY_RESTRICTED | GXS_SERV::FLAG_PRIVACY_PRIVATE | GXS_SERV::FLAG_PRIVACY_PUBLIC - uint32_t mPublishTs; - uint32_t mCircleType; - uint32_t mAuthenFlags; - RsGxsId mAuthorId; - std::string mServiceString; - RsGxsCircleId mCircleId; - RsTlvKeySignatureSet signSet; - RsTlvSecurityKeySet keys; - - uint32_t mSignFlags; - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - - uint32_t mSubscribeFlags; - - uint32_t mPop; // Number of friends who subscribed - uint32_t mVisibleMsgCount; // Max number of messages reported by a single friend (used for unsubscribed groups) - uint32_t mLastPost; // Time stamp of last post (not yet filled) - uint32_t mReputationCutOff; - uint32_t mGrpSize; - - uint32_t mGroupStatus; - uint32_t mRecvTS; - RsPeerId mOriginator; - RsGxsCircleId mInternalCircle; - RsFileHash mHash; -}; - - -class RsGxsMsgMetaData -{ -public: - - explicit RsGxsMsgMetaData(); - ~RsGxsMsgMetaData(); - bool deserialise(void *data, uint32_t *size); - bool serialise(void* data, uint32_t *size); - uint32_t serial_size() const; - void clear(); - void operator =(const RsMsgMetaData& rMeta); - - //Sort data in same order than serialiser and deserializer - RsGxsGroupId mGroupId; - RsGxsMessageId mMsgId; - RsGxsMessageId mThreadId; - RsGxsMessageId mParentId; - RsGxsMessageId mOrigMsgId; - RsGxsId mAuthorId; - - RsTlvKeySignatureSet signSet; - std::string mMsgName; - rstime_t mPublishTs; - uint32_t mMsgFlags; // used by some services (e.g. by forums to store message moderation flags) - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - // normally READ / UNREAD flags. LOCAL Data. - - std::string mServiceString; - uint32_t mMsgStatus; - uint32_t mMsgSize; - rstime_t mChildTs; - uint32_t recvTS; - RsFileHash mHash; - bool validated; -}; - - - - -#endif // RSGXSMETA_H diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc deleted file mode 100644 index a14248d4f..000000000 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ /dev/null @@ -1,1973 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsdataaccess.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 by Christopher Evi-Parker, Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rstime.h" - -#include "rsgxsutil.h" -#include "rsgxsdataaccess.h" -#include "retroshare/rsgxsflags.h" - -/*********** - * #define DATA_DEBUG 1 - **********/ - -// Debug system to allow to print only for some services (group, Peer, etc) - -#if defined(DATA_DEBUG) -static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_FORUMS;// use this to allow to this service id only, or 0 for all services - // warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums) - -class nullstream: public std::ostream {}; - -static std::string nice_time_stamp(rstime_t now,rstime_t TS) -{ - if(TS == 0) - return "Never" ; - else - { - std::ostringstream s; - s << now - TS << " secs ago" ; - return s.str() ; - } -} - -static std::ostream& gxsdatadebug(uint32_t service_type) -{ - static nullstream null ; - - if (service_to_print==0 || service_type == 0 || (service_type == service_to_print)) - return std::cerr << time(NULL) << ":GXSDATASERVICE: " ; - else - return null ; -} - -#define GXSDATADEBUG gxsdatadebug(mDataStore->serviceType()) - -static const std::vector tokenStatusString( { - std::string("FAILED"), - std::string("PENDING"), - std::string("PARTIAL"), - std::string("COMPLETE"), - std::string("DONE"), - std::string("CANCELLED"), - }); - -#endif - -bool operator<(const std::pair& p1,const std::pair& p2) -{ - return p1.second->Options.mPriority <= p2.second->Options.mPriority ; // <= so that new elements with same priority are inserted before -} - -RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : - mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {} - - -RsGxsDataAccess::~RsGxsDataAccess() -{ - for(auto& it:mRequestQueue) - delete it.second; -} -bool RsGxsDataAccess::requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds ) -{ - if(groupIds.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << " (WW) Group Id list is empty!" << std::endl; - return false; - } - - GxsRequest* req = nullptr; - uint32_t reqType = opts.mReqType; - - if(reqType & GXS_REQUEST_TYPE_GROUP_META) - { - GroupMetaReq* gmr = new GroupMetaReq(); - gmr->mGroupIds = groupIds; - req = gmr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - { - GroupDataReq* gdr = new GroupDataReq(); - gdr->mGroupIds = groupIds; - req = gdr; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - { - GroupIdReq* gir = new GroupIdReq(); - gir->mGroupIds = groupIds; - req = gir; - } - else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) - { - GroupSerializedDataReq* gir = new GroupSerializedDataReq(); - gir->mGroupIds = groupIds; - req = gir; - } - - if(!req) - { - RsErr() << __PRETTY_FUNCTION__ << " request type not recognised, " << "reqType: " << reqType << std::endl; - return false; - } - - generateToken(token); - -#ifdef DATA_DEBUG - GXSDATADEBUG << "RsGxsDataAccess::requestGroupInfo() gets token: " << token << std::endl; -#endif - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - -bool RsGxsDataAccess::requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) -{ - - GxsRequest* req = nullptr; - uint32_t reqType = opts.mReqType; - - if(reqType & GXS_REQUEST_TYPE_GROUP_META) - req = new GroupMetaReq(); - else if(reqType & GXS_REQUEST_TYPE_GROUP_DATA) - req = new GroupDataReq(); - else if(reqType & GXS_REQUEST_TYPE_GROUP_IDS) - req = new GroupIdReq(); - else if(reqType & GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA) - req = new GroupSerializedDataReq(); - else - { - RsErr() << "RsGxsDataAccess::requestGroupInfo() request type not recognised, type " << reqType << std::endl; - return false; - } - - generateToken(token); -#ifdef DATA_DEBUG - GXSDATADEBUG << "RsGxsDataAccess::requestGroupInfo() gets Token: " << token << std::endl; -#endif - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - -void RsGxsDataAccess::generateToken(uint32_t &token) -{ - RS_STACK_MUTEX(mDataMutex); - token = mNextToken++; -} - - -bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq &msgIds) -{ - - GxsRequest* req = nullptr; - uint32_t reqType = opts.mReqType; - - // remove all empty grpId entries - GxsMsgReq::const_iterator mit = msgIds.begin(); - std::vector toRemove; - - for(; mit != msgIds.end(); ++mit) - { - if(mit->second.empty()) - toRemove.push_back(mit->first); - } - - std::vector::const_iterator vit = toRemove.begin(); - - GxsMsgReq filteredMsgIds = msgIds; - - for(; vit != toRemove.end(); ++vit) - filteredMsgIds.erase(*vit); - - if(reqType & GXS_REQUEST_TYPE_MSG_META) - { - MsgMetaReq* mmr = new MsgMetaReq(); - mmr->mMsgIds = filteredMsgIds; - req = mmr; - - }else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) - { - MsgDataReq* mdr = new MsgDataReq(); - mdr->mMsgIds = filteredMsgIds; - req = mdr; - - }else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) - { - MsgIdReq* mir = new MsgIdReq(); - mir->mMsgIds = filteredMsgIds; - req = mir; - - } - - if(req == nullptr) - { - RsErr() << "RsGxsDataAccess::requestMsgInfo() request type not recognised, type " << reqType << std::endl; - return false; - }else - { - generateToken(token); -#ifdef DATA_DEBUG - GXSDATADEBUG << "RsGxsDataAccess::requestMsgInfo() gets Token: " << token << std::endl; -#endif - } - - setReq(req, token, ansType, opts); - storeRequest(req); - return true; -} - -bool RsGxsDataAccess::requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list& grpIds) -{ - GxsRequest* req = nullptr; - uint32_t reqType = opts.mReqType; - - std::list::const_iterator lit = grpIds.begin(); - - if(reqType & GXS_REQUEST_TYPE_MSG_META) - { - MsgMetaReq* mmr = new MsgMetaReq(); - - for(; lit != grpIds.end(); ++lit) - mmr->mMsgIds[*lit] = std::set(); - - req = mmr; - } - else if(reqType & GXS_REQUEST_TYPE_MSG_DATA) - { - MsgDataReq* mdr = new MsgDataReq(); - - for(; lit != grpIds.end(); ++lit) - mdr->mMsgIds[*lit] = std::set(); - - req = mdr; - } - else if(reqType & GXS_REQUEST_TYPE_MSG_IDS) - { - MsgIdReq* mir = new MsgIdReq(); - - for(; lit != grpIds.end(); ++lit) - mir->mMsgIds[*lit] = std::set(); - - req = mir; - } - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " request type not recognised, type " << reqType << std::endl; - return false; - }else - { - generateToken(token); -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ << " gets Token: " << token << std::endl; -#endif - } - - setReq(req, token, ansType, opts); - storeRequest(req); - return true; -} - - -void RsGxsDataAccess::requestServiceStatistic(uint32_t& token,const RsTokReqOptions& opts) -{ - ServiceStatisticRequest* req = new ServiceStatisticRequest(); - - generateToken(token); - - if(opts.mReqType != GXS_REQUEST_TYPE_SERVICE_STATS) - { - RsErr() << "Expected opts.mReqType to be GXS_REQUEST_TYPE_SERVICE_STATS requestServiceStatistic()" << std::endl; - return; - } - - setReq(req, token, 0, opts); - storeRequest(req); -} - -void RsGxsDataAccess::requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId,const RsTokReqOptions& opts) -{ - GroupStatisticRequest* req = new GroupStatisticRequest(); - req->mGrpId = grpId; - - if(opts.mReqType != GXS_REQUEST_TYPE_GROUP_STATS) - { - RsErr() << "Expected opts.mReqType to be GXS_REQUEST_TYPE_SERVICE_STATS requestServiceStatistic()" << std::endl; - return; - } - - generateToken(token); - - setReq(req, token,0, opts); - storeRequest(req); -} - -bool RsGxsDataAccess::requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector &msgIds) -{ - - MsgRelatedInfoReq* req = new MsgRelatedInfoReq(); - req->mMsgIds = msgIds; - - generateToken(token); - - setReq(req, token, ansType, opts); - storeRequest(req); - - return true; -} - - -void RsGxsDataAccess::setReq(GxsRequest* req, uint32_t token, uint32_t ansType, const RsTokReqOptions& opts) const -{ - req->token = token; - req->clientAnswerType = ansType; - req->Options = opts; - return; -} -void RsGxsDataAccess::storeRequest(GxsRequest* req) -{ - RS_STACK_MUTEX(mDataMutex); - req->status = PENDING; - req->reqTime = time(nullptr); - - mRequestQueue.insert(std::make_pair(req->token,req)); - mPublicToken[req->token] = PENDING; - -#ifdef DATA_DEBUG - GXSDATADEBUG << "Stored request token=" << req->token << " priority = " << static_cast(req->Options.mPriority) << " Current request Queue is:" ; - for(auto it(mRequestQueue.begin());it!=mRequestQueue.end();++it) - GXSDATADEBUG << it->first << " (p=" << static_cast(req->Options.mPriority) << ") "; - GXSDATADEBUG << std::endl; - GXSDATADEBUG << "PublicToken size: " << mPublicToken.size() << " Completed requests waiting for client: " << mCompletedRequests.size() << std::endl; -#endif -} - -RsTokenService::GxsRequestStatus RsGxsDataAccess::requestStatus(uint32_t token) -{ - RsTokenService::GxsRequestStatus status; - uint32_t reqtype; - uint32_t anstype; - rstime_t ts; - - if (!checkRequestStatus(token, status, reqtype, anstype, ts)) - return RsTokenService::FAILED; - - return status; -} - -bool RsGxsDataAccess::cancelRequest(const uint32_t& token) -{ - RsStackMutex stack(mDataMutex); /****** LOCKED *****/ - - GxsRequest* req = locked_retrieveCompletedRequest(token); - if (!req) - { - return false; - } - - req->status = CANCELLED; - - return true; -} - -bool RsGxsDataAccess::clearRequest(const uint32_t& token) -{ - RS_STACK_MUTEX(mDataMutex); - return locked_clearRequest(token); -} - -bool RsGxsDataAccess::locked_clearRequest(const uint32_t& token) -{ - auto it = mCompletedRequests.find(token); - - if(it == mCompletedRequests.end()) - return false; - - delete it->second; - mCompletedRequests.erase(it); - - auto it2 = mPublicToken.find(token); - if(it2 != mPublicToken.end()) - mPublicToken.erase(it2); - -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": Removing public token " << token << ". Completed tokens: " << mCompletedRequests.size() << " Size of mPublicToken: " << mPublicToken.size() << std::endl; -#endif - return true; -} - -bool RsGxsDataAccess::getGroupSummary(const uint32_t& token, std::list >& groupInfo) -{ - RS_STACK_MUTEX(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve group summary" << std::endl; - return false; - } - - GroupMetaReq* gmreq = dynamic_cast(req); - - if(gmreq) - { - groupInfo = gmreq->mGroupMetaData; - gmreq->mGroupMetaData.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed cast" << std::endl; - return false; - } - locked_clearRequest(token); - - return true; -} - -bool RsGxsDataAccess::getGroupData(const uint32_t& token, std::list& grpData) -{ - RS_STACK_MUTEX(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << "RsGxsDataAccess::getGroupData() Unable to retrieve group data" << std::endl; - return false; - } - - GroupDataReq* gmreq = dynamic_cast(req); - GroupSerializedDataReq* gsreq = dynamic_cast(req); - - if(gsreq) - { - grpData.swap(gsreq->mGroupData); - gsreq->mGroupData.clear(); - } - else if(gmreq) - { - grpData.swap(gmreq->mGroupData); - gmreq->mGroupData.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed cast req->reqType: " << req->reqType << std::endl; - return false; - } - locked_clearRequest(token); - - return true; -} - -bool RsGxsDataAccess::getMsgData(const uint32_t& token, NxsMsgDataResult& msgData) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve group data" << std::endl; - return false; - } - - MsgDataReq* mdreq = dynamic_cast(req); - - if(mdreq) - { - msgData.swap(mdreq->mMsgData); - mdreq->mMsgData.clear(); - } - else - { - RsErr() << "RsGxsDataAccess::getMsgData() Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - - return true; -} - -bool RsGxsDataAccess::getMsgRelatedData(const uint32_t& token, NxsMsgRelatedDataResult& msgData) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve group data" << std::endl; - return false; - } - MsgRelatedInfoReq* mrireq = dynamic_cast(req); - - if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_DATA) - return false; - - if(mrireq) - { - msgData.swap(mrireq->mMsgDataResult); - mrireq->mMsgDataResult.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - - locked_clearRequest(token); - - return true; -} - -bool RsGxsDataAccess::getMsgSummary(const uint32_t& token, GxsMsgMetaResult& msgInfo) -{ - - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve group data" << std::endl; - return false; - } - MsgMetaReq* mmreq = dynamic_cast(req); - - if(mmreq) - { - msgInfo.swap(mmreq->mMsgMetaData); - mmreq->mMsgMetaData.clear(); - } - else - { - RsErr() << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - -bool RsGxsDataAccess::getMsgRelatedSummary(const uint32_t &token, MsgRelatedMetaResult &msgMeta) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve message summary" << std::endl; - return false; - } - if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_META) - return false; - - MsgRelatedInfoReq* mrireq = dynamic_cast(req); - - if(mrireq) - { - msgMeta.swap(mrireq->mMsgMetaResult); - mrireq->mMsgMetaResult.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - - -bool RsGxsDataAccess::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve message data" << std::endl; - return false; - } - if(req->Options.mReqType != GXS_REQUEST_TYPE_MSG_RELATED_IDS) - return false; - - MsgRelatedInfoReq* mrireq = dynamic_cast(req); - - if(mrireq) - { - msgIds.swap(mrireq->mMsgIdResult); - mrireq->mMsgIdResult.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - -bool RsGxsDataAccess::getMsgIdList(const uint32_t& token, GxsMsgIdResult& msgIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve msg Ids" << std::endl; - return false; - } - MsgIdReq* mireq = dynamic_cast(req); - - if(mireq) - { - msgIds.swap(mireq->mMsgIdResult); - mireq->mMsgIdResult.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed cast" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - -bool RsGxsDataAccess::getGroupList(const uint32_t& token, std::list& groupIds) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve group Ids, Request does not exist" << std::endl; - return false; - } - GroupIdReq* gireq = dynamic_cast(req); - - if(gireq) - { - groupIds.swap(gireq->mGroupIdResult); - gireq->mGroupIdResult.clear(); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - -bool RsGxsDataAccess::getGroupStatistic(const uint32_t &token, GxsGroupStatistic &grpStatistic) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << "RsGxsDataAccess::getGroupStatistic() Unable to retrieve grp stats" << std::endl; - return false; - } - GroupStatisticRequest* gsreq = dynamic_cast(req); - - if(gsreq) - grpStatistic = gsreq->mGroupStatistic; - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} - -bool RsGxsDataAccess::getServiceStatistic(const uint32_t &token, GxsServiceStatistic &servStatistic) -{ - RsStackMutex stack(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " Unable to retrieve service stats" << std::endl; - return false; - } - ServiceStatisticRequest* ssreq = dynamic_cast(req); - - if(ssreq) - servStatistic = ssreq->mServiceStatistic; - else - { - RsErr() << __PRETTY_FUNCTION__ << " Req found, failed caste" << std::endl; - return false; - } - locked_clearRequest(token); - return true; -} -GxsRequest* RsGxsDataAccess::locked_retrieveCompletedRequest(const uint32_t& token) -{ - auto it = mCompletedRequests.find(token) ; - - if(it == mCompletedRequests.end()) - return nullptr; - - return it->second; -} - -#define MAX_REQUEST_AGE 120 // 2 minutes - -void RsGxsDataAccess::processRequests() -{ - // process requests - - while (!mRequestQueue.empty()) - { -#ifdef DATA_DEBUG - dumpTokenQueues(); -#endif - // Extract the first elements from the request queue. cleanup all other elements marked at terminated. - - GxsRequest* req = nullptr; - { - RsStackMutex stack(mDataMutex); /******* LOCKED *******/ - rstime_t now = time(nullptr); // this is ok while in the loop below - - while(!mRequestQueue.empty() && req == nullptr) - { - if(now > mRequestQueue.begin()->second->reqTime + MAX_REQUEST_AGE) - { - mPublicToken[mRequestQueue.begin()->second->token] = CANCELLED; - delete mRequestQueue.begin()->second; - mRequestQueue.erase(mRequestQueue.begin()); - continue; - } - - switch( mRequestQueue.begin()->second->status ) - { - case PARTIAL: - RsErr() << "Found partial request in mRequestQueue. This is a bug." << std::endl; // fallthrough - case COMPLETE: - case DONE: - case FAILED: - case CANCELLED: -#ifdef DATA_DEBUG - GXSDATADEBUG << " Service " << std::hex << mDataStore->serviceType() << std::dec << ": request " << mRequestQueue.begin()->second->token << ": status = " << mRequestQueue.begin()->second->status << ": removing from the RequestQueue" << std::endl; -#endif - delete mRequestQueue.begin()->second; - mRequestQueue.erase(mRequestQueue.begin()); - continue; - break; - case PENDING: - req = mRequestQueue.begin()->second; - req->status = PARTIAL; - mRequestQueue.erase(mRequestQueue.begin()); // remove it right away from the waiting queue. - break; - } - - } - } // END OF MUTEX. - - if (!req) - break; - - GroupMetaReq* gmr; - GroupDataReq* gdr; - GroupIdReq* gir; - - MsgMetaReq* mmr; - MsgDataReq* mdr; - MsgIdReq* mir; - MsgRelatedInfoReq* mri; - GroupStatisticRequest* gsr; - GroupSerializedDataReq* grr; - ServiceStatisticRequest* ssr; - -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": Processing request: " << req->token << " Status: " << req->status << " ReqType: " << req->reqType << " Age: " << time(nullptr) - req->reqTime << std::endl; -#endif - - /* PROCESS REQUEST! */ - bool ok = false; - - if((gmr = dynamic_cast(req)) != nullptr) - { - ok = getGroupSummary(gmr); - } - else if((gdr = dynamic_cast(req)) != nullptr) - { - ok = getGroupData(gdr); - } - else if((gir = dynamic_cast(req)) != nullptr) - { - ok = getGroupList(gir); - } - else if((mmr = dynamic_cast(req)) != nullptr) - { - ok = getMsgSummary(mmr); - } - else if((mdr = dynamic_cast(req)) != nullptr) - { - ok = getMsgData(mdr); - } - else if((mir = dynamic_cast(req)) != nullptr) - { - ok = getMsgIdList(mir); - } - else if((mri = dynamic_cast(req)) != nullptr) - { - ok = getMsgRelatedInfo(mri); - } - else if((gsr = dynamic_cast(req)) != nullptr) - { - ok = getGroupStatistic(gsr); - } - else if((ssr = dynamic_cast(req)) != nullptr) - { - ok = getServiceStatistic(ssr); - } - else if((grr = dynamic_cast(req)) != nullptr) - { - ok = getGroupSerializedData(grr); - } - else - RsErr() << __PRETTY_FUNCTION__ << " Failed to process request, token: " << req->token << std::endl; - - // We cannot easily remove the request here because the queue may have more elements now and mRequestQueue.begin() is not necessarily the same element. - // but we mark it as COMPLETE/FAILED so that it will be removed in the next loop. - { - RsStackMutex stack(mDataMutex); /******* LOCKED *******/ - - if(ok) - { - // When the request is complete, we move it to the complete list, so that the caller can easily retrieve the request data - -#ifdef DATA_DEBUG - GXSDATADEBUG << " Service " << std::hex << mDataStore->serviceType() << std::dec << ": Request completed successfully. Marking as COMPLETE." << std::endl; -#endif - req->status = COMPLETE ; - mCompletedRequests[req->token] = req; - mPublicToken[req->token] = COMPLETE; - } - else - { - mPublicToken[req->token] = FAILED; - delete req;//req belongs to no one now -#ifdef DATA_DEBUG - GXSDATADEBUG << " Service " << std::hex << mDataStore->serviceType() << std::dec << ": Request failed. Marking as FAILED." << std::endl; -#endif - } - } // END OF MUTEX. - - } -} - - - -bool RsGxsDataAccess::getGroupSerializedData(GroupSerializedDataReq* req) -{ - std::map grpData; - std::list grpIdsOut; - - getGroupList(req->mGroupIds, req->Options, grpIdsOut); - - if(grpIdsOut.empty()) - return true; - - - for(std::list::iterator lit = grpIdsOut.begin();lit != grpIdsOut.end();++lit) - grpData[*lit] = nullptr; - - bool ok = mDataStore->retrieveNxsGrps(grpData, true); - req->mGroupData.clear(); - - std::map::iterator mit = grpData.begin(); - - for(; mit != grpData.end(); ++mit) - req->mGroupData.push_back(mit->second) ; - - return ok; -} -bool RsGxsDataAccess::getGroupData(GroupDataReq* req) -{ - std::map grpData; - std::list grpIdsOut; - - getGroupList(req->mGroupIds, req->Options, grpIdsOut); - - if(grpIdsOut.empty()) - return true; - - std::list::iterator lit = grpIdsOut.begin(), - lit_end = grpIdsOut.end(); - - for(; lit != lit_end; ++lit) - { - grpData[*lit] = nullptr; - } - - bool ok = mDataStore->retrieveNxsGrps(grpData, true); - - std::map::iterator mit = grpData.begin(); - for(; mit != grpData.end(); ++mit) - req->mGroupData.push_back(mit->second); - - return ok; -} - -bool RsGxsDataAccess::getGroupSummary(GroupMetaReq* req) -{ - - RsGxsGrpMetaTemporaryMap grpMeta; - std::list grpIdsOut; - - getGroupList(req->mGroupIds, req->Options, grpIdsOut); - - if(grpIdsOut.empty()) - return true; - - for(auto lit = grpIdsOut.begin();lit != grpIdsOut.end(); ++lit) - grpMeta[*lit] = nullptr; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - for(auto mit = grpMeta.begin(); mit != grpMeta.end(); ++mit) - req->mGroupMetaData.push_back(mit->second); - - return true; -} - -bool RsGxsDataAccess::getGroupList(GroupIdReq* req) -{ - return getGroupList(req->mGroupIds, req->Options, req->mGroupIdResult); -} - -bool RsGxsDataAccess::getGroupList(const std::list& grpIdsIn, const RsTokReqOptions& opts, std::list& grpIdsOut) -{ - RsGxsGrpMetaTemporaryMap grpMeta; - - for(auto lit = grpIdsIn.begin(); lit != grpIdsIn.end(); ++lit) - grpMeta[*lit] = nullptr; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - for(auto mit = grpMeta.begin() ; mit != grpMeta.end(); ++mit) - grpIdsOut.push_back(mit->first); - - filterGrpList(grpIdsOut, opts, grpMeta); - - return true; -} - -bool RsGxsDataAccess::getMsgData(MsgDataReq* req) -{ - GxsMsgReq msgIdOut; - - const RsTokReqOptions& opts(req->Options); - - // filter based on options - getMsgIdList(req->mMsgIds, opts, msgIdOut); - - // If the list is empty because of filtering do not retrieve from DB - if((opts.mMsgFlagMask || opts.mStatusMask) && msgIdOut.empty()) - return true; - - mDataStore->retrieveNxsMsgs(msgIdOut, req->mMsgData, true); - return true; -} - - -bool RsGxsDataAccess::getMsgSummary(MsgMetaReq* req) -{ - GxsMsgReq msgIdOut; - - const RsTokReqOptions& opts(req->Options); - - // filter based on options - getMsgMetaDataList(req->mMsgIds, opts, req->mMsgMetaData); - -// // If the list is empty because of filtering do not retrieve from DB -// if((opts.mMsgFlagMask || opts.mStatusMask) && msgIdOut.empty()) -// return true; -// -// mDataStore->retrieveGxsMsgMetaData(msgIdOut, req->mMsgMetaData); - - return true; -} - -bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgMetaResult& result ) -{ - // First get all message metas, then filter out the ones we want to keep. - result.clear(); - mDataStore->retrieveGxsMsgMetaData(msgIds, result); - - /* CASEs this handles. - * Input is groupList + Flags. - * 1) No Flags => All Messages in those Groups. - * - */ -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgList()" << std::endl; -#endif - - bool onlyOrigMsgs = false; - bool onlyLatestMsgs = false; - bool onlyThreadHeadMsgs = false; - - // Can only choose one of these two. - if (opts.mOptions & RS_TOKREQOPT_MSG_ORIGMSG) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgList() MSG_ORIGMSG" << std::endl; -#endif - onlyOrigMsgs = true; - } - else if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgList() MSG_LATEST" << std::endl; -#endif - onlyLatestMsgs = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgList() MSG_THREAD" << std::endl; -#endif - onlyThreadHeadMsgs = true; - } - - GxsMsgMetaResult::iterator meta_it; - - for(meta_it = result.begin(); meta_it != result.end(); ++meta_it) - { - //const RsGxsGroupId& grpId = meta_it->first; - - //auto& filter( metaFilter[grpId] ); // does the initialization of metaFilter[grpId] and avoids further O(log(n)) calls - - auto& metaV = meta_it->second; - - if (onlyLatestMsgs) // if we only consider latest messages, we need to first filter out messages with "children" - { - // The strategy is the following: for each msg we only know its direct ancestor. So we build a map to be able to find for a given message - // which messages derive from it. - // Then when this map is fuly build, we follow this map and every message that has no direct follow up will be kept. - // Because msgs are stored in a std::vector we build a map to convert each vector to its position in metaV. - - std::vector keep(metaV.size(),true); // this vector will tell wether we keep or not a given Meta - std::map index_in_metaV; // holds the index of each group Id in metaV - - for(uint32_t i=0;imMsgId] = i; - - // Now loop once over message Metas and see if they have a parent. If yes, then mark the parent to be discarded. - - for(uint32_t i=0;imOrigMsgId.isNull() && metaV[i]->mOrigMsgId != metaV[i]->mMsgId) // this one is a follow up - { - auto it = index_in_metaV.find(metaV[i]->mOrigMsgId); - - if(it != index_in_metaV.end()) - keep[it->second] = false; - else - std::cerr << "Found a msg that has a parent that is not locally known. Not an error anyway." << std::endl; - - } - - // Finally we just discard the messages for which the keep flag has been set to false. - - for(uint32_t i=0;i TS. - std::map > origMsgTs; - - for(uint32_t i=0;imParentId.isNull())) - { - delete msgMeta; - metaV[i] = nullptr; - continue; - } - - auto oit = origMsgTs.find(msgMeta->mOrigMsgId); - - bool addMsg = false; - if (oit != origMsgTs.end()) - { - if(oit->second.second > msgMeta->mPublishTs) - { -#ifdef DATA_DEBUG - std::cerr << "RsGxsDataAccess::getMsgList() Found New OrigMsgId: "; - std::cerr << msgMeta->mOrigMsgId; - std::cerr << " MsgId: " << msgMeta->mMsgId; - std::cerr << " TS: " << msgMeta->mPublishTs; - std::cerr << std::endl; -#endif - origMsgTs[msgMeta->mOrigMsgId] = std::make_pair(msgMeta->mMsgId, msgMeta->mPublishTs); // add as latest. (overwriting if necessary) - } - } - else - { - delete msgMeta; - metaV[i] = nullptr; - continue; - } - - - } - - // Add the discovered Latest Msgs. - for(auto oit = origMsgTs.begin(); oit != origMsgTs.end(); ++oit) - { - msgIdsOut[grpId].insert(oit->second.first); - } -#endif - - for(uint32_t i=0;imParentId.isNull()) - { - //delete msgMeta; - metaV[i] = nullptr; - continue; - } - - if (onlyOrigMsgs && !msgMeta->mOrigMsgId.isNull() && msgMeta->mMsgId != msgMeta->mOrigMsgId) - { - //delete msgMeta; - metaV[i] = nullptr; - continue; - } - } - } - - // collapse results while keeping the order, eliminating empty slots - - for(auto it(result.begin());it!=result.end();++it) - { - uint32_t j=0; // j is the end of the cleaned-up tab, at the first available place - - for(uint32_t i=0;isecond.size();++i) // i is the index in the tab possibly containing nullptr's - if(it->second[i] != nullptr) - { - it->second[j] = it->second[i]; // move the pointer to the first available place - ++j; - } - - it->second.resize(j); // normally all pointers have been moved forward so there is nothing to delete here. - } - - // filterMsgIdList(msgIdsOut, opts, metaFilter); // this call is absurd: we already have in metaFilter the content we want. - - //metaFilter.clear(); - - // delete meta data - //cleanseMsgMetaMap(result); - - return true; -} - -bool RsGxsDataAccess::getMsgIdList( const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut ) -{ - GxsMsgMetaResult result; - - getMsgMetaDataList( msgIds, opts, result ); - - // extract MessageIds - - msgIdsOut.clear(); - - for(auto it(result.begin());it!=result.end();++it) - { - auto& id_set(msgIdsOut[it->first]); - - for(uint32_t i=0;isecond.size();++i) - id_set.insert(it->second[i]->mMsgId); - } - - // delete meta data - //cleanseMsgMetaMap(result); - - return true; -} - -bool RsGxsDataAccess::getMsgRelatedInfo(MsgRelatedInfoReq *req) -{ - /* CASEs this handles. - * Input is msgList + Flags. - * 1) No Flags => return nothing - */ -#ifdef DATA_DEBUG - GXSDATADEBUG << "RsGxsDataAccess::getMsgRelatedList()" << std::endl; -#endif - - const RsTokReqOptions& opts = req->Options; - - bool onlyLatestMsgs = false; - bool onlyAllVersions = false; - bool onlyChildMsgs = false; - bool onlyThreadMsgs = false; - - if (opts.mOptions & RS_TOKREQOPT_MSG_LATEST) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgRelatedList() MSG_LATEST" << std::endl; -#endif - onlyLatestMsgs = true; - } - else if (opts.mOptions & RS_TOKREQOPT_MSG_VERSIONS) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgRelatedList() MSG_VERSIONS" << std::endl; -#endif - onlyAllVersions = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_PARENT) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgRelatedList() MSG_PARENTS" << std::endl; -#endif - onlyChildMsgs = true; - } - - if (opts.mOptions & RS_TOKREQOPT_MSG_THREAD) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgRelatedList() MSG_THREAD" << std::endl; -#endif - onlyThreadMsgs = true; - } - - if(onlyAllVersions && onlyChildMsgs) - { - RS_ERR("Incompatible FLAGS (VERSIONS & PARENT)"); - return false; - } - - if(onlyAllVersions && onlyThreadMsgs) - { - RS_ERR("Incompatible FLAGS (VERSIONS & THREAD)"); - return false; - } - - if((!onlyLatestMsgs) && onlyChildMsgs) - { - RS_ERR("Incompatible FLAGS (!LATEST & PARENT)"); - return false; - } - - if((!onlyLatestMsgs) && onlyThreadMsgs) - { - RS_ERR("Incompatible FLAGS (!LATEST & THREAD)"); - return false; - } - - if(onlyChildMsgs && onlyThreadMsgs) - { - RS_ERR("Incompatible FLAGS (PARENT & THREAD)"); - return false; - } - - if( (!onlyLatestMsgs) && (!onlyAllVersions) && (!onlyChildMsgs) && - (!onlyThreadMsgs) ) - { - RS_WARN("NO FLAGS -> SIMPLY RETURN nothing"); - return true; - } - - for(auto vit_msgIds(req->mMsgIds.begin()); vit_msgIds != req->mMsgIds.end(); ++vit_msgIds) - { - MsgMetaFilter filterMap; - - - const RsGxsGrpMsgIdPair& grpMsgIdPair = *vit_msgIds; - - // get meta data for all in group - GxsMsgMetaResult result; - GxsMsgReq msgIds; - msgIds.insert(std::make_pair(grpMsgIdPair.first, std::set())); - mDataStore->retrieveGxsMsgMetaData(msgIds, result); - auto& metaV = result[grpMsgIdPair.first]; - - // msg id to relate to - const RsGxsMessageId& msgId = grpMsgIdPair.second; - const RsGxsGroupId& grpId = grpMsgIdPair.first; - - std::set outMsgIds; - - std::shared_ptr origMeta; - - for(auto vit_meta = metaV.begin(); vit_meta != metaV.end(); ++vit_meta) - if(msgId == (*vit_meta)->mMsgId) - { - origMeta = *vit_meta; - break; - } - - if(!origMeta) - { - RS_ERR("Cannot find meta of msgId: ", msgId, " to relate to"); - return false; - } - - const RsGxsMessageId& origMsgId = origMeta->mOrigMsgId; - auto& metaMap = filterMap[grpId]; - - if (onlyLatestMsgs) - { - if (onlyChildMsgs || onlyThreadMsgs) - { - // RUN THROUGH ALL MSGS... in map origId -> TS. - std::map > origMsgTs; - std::map >::iterator oit; - - for(auto vit_meta = metaV.begin(); vit_meta != metaV.end(); ++vit_meta) - { - auto meta = *vit_meta; - - // skip msgs that aren't children. - if (onlyChildMsgs) - { - if (meta->mParentId != origMsgId) - { - continue; - } - } - else /* onlyThreadMsgs */ - { - if (meta->mThreadId != msgId) - { - continue; - } - } - - - oit = origMsgTs.find(meta->mOrigMsgId); - - bool addMsg = false; - if (oit == origMsgTs.end()) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "RsGxsDataAccess::getMsgRelatedList() Found New OrigMsgId: " - << meta->mOrigMsgId - << " MsgId: " << meta->mMsgId - << " TS: " << meta->mPublishTs - << std::endl; -#endif - - addMsg = true; - } - // check timestamps. - else if (oit->second.second < meta->mPublishTs) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": RsGxsDataAccess::getMsgRelatedList() Found Later Msg. OrigMsgId: " - << meta->mOrigMsgId - << " MsgId: " << meta->mMsgId - << " TS: " << meta->mPublishTs - << std::endl; -#endif - - addMsg = true; - } - - if (addMsg) - { - // add as latest. (overwriting if necessary) - origMsgTs[meta->mOrigMsgId] = std::make_pair(meta->mMsgId, meta->mPublishTs); - metaMap.insert(std::make_pair(meta->mMsgId, meta)); - } - } - - // Add the discovered Latest Msgs. - for(oit = origMsgTs.begin(); oit != origMsgTs.end(); ++oit) - { - outMsgIds.insert(oit->second.first); - } - } - else - { - - /* first guess is potentially better than Orig (can't be worse!) */ - rstime_t latestTs = 0; - RsGxsMessageId latestMsgId; - std::shared_ptr latestMeta; - - for(auto vit_meta = metaV.begin(); vit_meta != metaV.end(); ++vit_meta) - if ((*vit_meta)->mOrigMsgId == origMsgId) - { - if ((*vit_meta)->mPublishTs > latestTs) - { - latestTs = (*vit_meta)->mPublishTs; - latestMsgId = (*vit_meta)->mMsgId; - latestMeta = (*vit_meta); - } - } - - outMsgIds.insert(latestMsgId); - metaMap.insert(std::make_pair(latestMsgId, latestMeta)); - } - } - else if (onlyAllVersions) - { - for(auto vit_meta = metaV.begin(); vit_meta != metaV.end(); ++vit_meta) - if ((*vit_meta)->mOrigMsgId == origMsgId) - { - outMsgIds.insert((*vit_meta)->mMsgId); - metaMap.insert(std::make_pair((*vit_meta)->mMsgId, (*vit_meta))); - } - } - - GxsMsgIdResult filteredOutMsgIds; - filteredOutMsgIds[grpId] = outMsgIds; - filterMsgIdList(filteredOutMsgIds, opts, filterMap); - - if(!filteredOutMsgIds[grpId].empty()) - { - if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_IDS) - { - req->mMsgIdResult[grpMsgIdPair] = filteredOutMsgIds[grpId]; - } - else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_META) - { - GxsMsgMetaResult metaResult; - mDataStore->retrieveGxsMsgMetaData(filteredOutMsgIds, metaResult); - req->mMsgMetaResult[grpMsgIdPair] = metaResult[grpId]; - } - else if(req->Options.mReqType == GXS_REQUEST_TYPE_MSG_RELATED_DATA) - { - GxsMsgResult msgResult; - mDataStore->retrieveNxsMsgs(filteredOutMsgIds, msgResult, true); - req->mMsgDataResult[grpMsgIdPair] = msgResult[grpId]; - } - } - - outMsgIds.clear(); - filteredOutMsgIds.clear(); - } - return true; -} - -bool RsGxsDataAccess::getGroupStatistic(GroupStatisticRequest *req) -{ - // filter based on options - GxsMsgIdResult metaReq; - metaReq[req->mGrpId] = std::set(); - GxsMsgMetaResult metaResult; - mDataStore->retrieveGxsMsgMetaData(metaReq, metaResult); - - const auto& msgMetaV_it = metaResult.find(req->mGrpId); - - if(msgMetaV_it == metaResult.end()) - return false; - - const auto& msgMetaV(msgMetaV_it->second); - - req->mGroupStatistic.mGrpId = req->mGrpId; - req->mGroupStatistic.mNumMsgs = msgMetaV.size(); - req->mGroupStatistic.mTotalSizeOfMsgs = 0; - req->mGroupStatistic.mNumThreadMsgsNew = 0; - req->mGroupStatistic.mNumThreadMsgsUnread = 0; - req->mGroupStatistic.mNumChildMsgsNew = 0; - req->mGroupStatistic.mNumChildMsgsUnread = 0; - - std::set obsolete_msgs ; // stored message ids that are referred to as older versions of an existing message - - for(uint32_t i = 0; i < msgMetaV.size(); ++i) - if(!msgMetaV[i]->mOrigMsgId.isNull() && msgMetaV[i]->mOrigMsgId!=msgMetaV[i]->mMsgId) - obsolete_msgs.insert(msgMetaV[i]->mOrigMsgId); - - for(uint32_t i = 0; i < msgMetaV.size(); ++i) - { - const auto& m = msgMetaV[i]; - req->mGroupStatistic.mTotalSizeOfMsgs += m->mMsgSize + m->serial_size(); - - if(obsolete_msgs.find(m->mMsgId) != obsolete_msgs.end()) // skip obsolete messages. - continue; - - if (IS_MSG_NEW(m->mMsgStatus)) - { - if (m->mParentId.isNull()) - ++req->mGroupStatistic.mNumThreadMsgsNew; - else - ++req->mGroupStatistic.mNumChildMsgsNew; - } - if (IS_MSG_UNREAD(m->mMsgStatus)) - { - if (m->mParentId.isNull()) - ++req->mGroupStatistic.mNumThreadMsgsUnread; - else - ++req->mGroupStatistic.mNumChildMsgsUnread; - } - } - - return true; -} - -// potentially very expensive! -bool RsGxsDataAccess::getServiceStatistic(ServiceStatisticRequest *req) -{ - RsGxsGrpMetaTemporaryMap grpMeta ; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - req->mServiceStatistic.mNumGrps = grpMeta.size(); - req->mServiceStatistic.mNumMsgs = 0; - req->mServiceStatistic.mSizeOfGrps = 0; - req->mServiceStatistic.mSizeOfMsgs = 0; - req->mServiceStatistic.mNumGrpsSubscribed = 0; - req->mServiceStatistic.mNumThreadMsgsNew = 0; - req->mServiceStatistic.mNumThreadMsgsUnread = 0; - req->mServiceStatistic.mNumChildMsgsNew = 0; - req->mServiceStatistic.mNumChildMsgsUnread = 0; - - for(auto mit = grpMeta.begin(); mit != grpMeta.end(); ++mit) - { - const auto& m = mit->second; - req->mServiceStatistic.mSizeOfGrps += m->mGrpSize + m->serial_size(RS_GXS_GRP_META_DATA_CURRENT_API_VERSION); - - if (IS_GROUP_SUBSCRIBED(m->mSubscribeFlags)) - { - ++req->mServiceStatistic.mNumGrpsSubscribed; - - GroupStatisticRequest gr; - gr.mGrpId = m->mGroupId; - getGroupStatistic(&gr); - - req->mServiceStatistic.mNumMsgs += gr.mGroupStatistic.mNumMsgs; - req->mServiceStatistic.mSizeOfMsgs += gr.mGroupStatistic.mTotalSizeOfMsgs; - req->mServiceStatistic.mNumThreadMsgsNew += gr.mGroupStatistic.mNumThreadMsgsNew; - req->mServiceStatistic.mNumThreadMsgsUnread += gr.mGroupStatistic.mNumThreadMsgsUnread; - req->mServiceStatistic.mNumChildMsgsNew += gr.mGroupStatistic.mNumChildMsgsNew; - req->mServiceStatistic.mNumChildMsgsUnread += gr.mGroupStatistic.mNumChildMsgsUnread; - } - } - - req->mServiceStatistic.mSizeStore = req->mServiceStatistic.mSizeOfGrps + req->mServiceStatistic.mSizeOfMsgs; - - return true; -} - -bool RsGxsDataAccess::getMsgIdList(MsgIdReq* req) -{ - - GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(req->mMsgIds, result); - - for(auto mit = result.begin(); mit != result.end(); ++mit) - { - const RsGxsGroupId grpId = mit->first; - auto& metaV = mit->second; - - for(auto vit=metaV.begin(); vit != metaV.end(); ++vit) - req->mMsgIdResult[grpId].insert((*vit)->mMsgId); - } - - GxsMsgReq msgIdOut; - - // filter based on options - getMsgIdList(req->mMsgIdResult, req->Options, msgIdOut); - req->mMsgIdResult = msgIdOut; - - return true; -} - -void RsGxsDataAccess::filterMsgIdList( GxsMsgIdResult& resultsMap, const RsTokReqOptions& opts, const MsgMetaFilter& msgMetas ) const -{ - for( GxsMsgIdResult::iterator grpIt = resultsMap.begin(); grpIt != resultsMap.end(); ++grpIt ) - { - const RsGxsGroupId& groupId(grpIt->first); - std::set& msgsIdSet(grpIt->second); - - MsgMetaFilter::const_iterator cit = msgMetas.find(groupId); - if(cit == msgMetas.end()) continue; -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ << " " << msgsIdSet.size() - << " for group: " << groupId << " before filtering" - << std::endl; -#endif - - for( std::set::iterator msgIdIt = msgsIdSet.begin(); msgIdIt != msgsIdSet.end(); ) - { - const RsGxsMessageId& msgId(*msgIdIt); - const auto& msgsMetaMap = cit->second; - - bool keep = false; - auto msgsMetaMapIt = msgsMetaMap.find(msgId); - - if( msgsMetaMapIt != msgsMetaMap.end() ) - keep = checkMsgFilter(opts, msgsMetaMapIt->second); - - if(keep) - ++msgIdIt; - else - msgIdIt = msgsIdSet.erase(msgIdIt); - } - -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ << " " << msgsIdSet.size() - << " for group: " << groupId << " after filtering" - << std::endl; -#endif - } -} - -void RsGxsDataAccess::filterGrpList(std::list &grpIds, const RsTokReqOptions &opts, const GrpMetaFilter& meta) const -{ - for(auto lit = grpIds.begin(); lit != grpIds.end(); ) - { - auto cit = meta.find(*lit); - - bool keep = false; - - if(cit != meta.end()) - keep = checkGrpFilter(opts, cit->second); - - if(keep) - ++lit; - else - lit = grpIds.erase(lit); - } -} - - -bool RsGxsDataAccess::checkRequestStatus( uint32_t token, GxsRequestStatus& status, uint32_t& reqtype, uint32_t& anstype, rstime_t& ts ) -{ - RS_STACK_MUTEX(mDataMutex); - - GxsRequest* req = locked_retrieveCompletedRequest(token); - -#ifdef DATA_DEBUG - GXSDATADEBUG << "CheckRequestStatus: token=" << token << std::endl ; -#endif - - if(req != nullptr) - { - anstype = req->clientAnswerType; - reqtype = req->reqType; - status = COMPLETE; - ts = req->reqTime; -#ifdef DATA_DEBUG - GXSDATADEBUG << " Returning status = COMPLETE" << std::endl; -#endif - return true; - } - - auto it = mPublicToken.find(token); - - if(it != mPublicToken.end()) - { - status = it->second; -#ifdef DATA_DEBUG - GXSDATADEBUG << " Returning status = " << status << std::endl; -#endif - return true; - } - - status = FAILED; -#ifdef DATA_DEBUG - GXSDATADEBUG << " Token not found. Returning FAILED" << std::endl; -#endif - return false; -} - -bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) { - - RsStackMutex stack(mDataMutex); - - std::list grpM; - grpM.push_back(grp); - return mDataStore->storeGroup(grpM); -} - -bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) { - - RsStackMutex stack(mDataMutex); - - std::list grpM; - grpM.push_back(grp); - return mDataStore->updateGroup(grpM); -} - -bool RsGxsDataAccess::getGroupData(const RsGxsGroupId& grpId, RsNxsGrp *& grp_data) -{ - RsStackMutex stack(mDataMutex); - - std::map grps ; - - grps[grpId] = nullptr ; - - if(mDataStore->retrieveNxsGrps(grps, false)) // the false here is very important: it removes the private key parts. - { - grp_data = grps.begin()->second; - return true; - } - else - return false ; -} - -bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) { - - RsStackMutex stack(mDataMutex); - - std::list msgM; - msgM.push_back(msg); - return mDataStore->storeMessage(msgM); -} - - - -void RsGxsDataAccess::tokenList(std::list& tokens) -{ - - RsStackMutex stack(mDataMutex); - - for(auto& it:mRequestQueue) - tokens.push_back(it.second->token); - - for(auto& it:mCompletedRequests) - tokens.push_back(it.first); -} - -bool RsGxsDataAccess::locked_updateRequestStatus( uint32_t token, RsTokenService::GxsRequestStatus status ) -{ - GxsRequest* req = locked_retrieveCompletedRequest(token); - - if(req) req->status = status; - else return false; - - return true; -} - -uint32_t RsGxsDataAccess::generatePublicToken() -{ - uint32_t token; - generateToken(token); - - { - RS_STACK_MUTEX(mDataMutex); - mPublicToken[token] = PENDING ; -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": Adding new public token " << token << " in PENDING state. Completed tokens: " << mCompletedRequests.size() << " Size of mPublicToken: " << mPublicToken.size() << std::endl; - if(mDataStore->serviceType() == 0x218 && token==19) - print_stacktrace(); -#endif - } - - return token; -} - - - -bool RsGxsDataAccess::updatePublicRequestStatus( uint32_t token, RsTokenService::GxsRequestStatus status ) -{ - RS_STACK_MUTEX(mDataMutex); - - auto mit = mPublicToken.find(token); - - if(mit != mPublicToken.end()) - { - mit->second = status; -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": updating public token " << token << " to state " << tokenStatusString[status] << std::endl; -#endif - return true; - } - else - return false; -} - - - -bool RsGxsDataAccess::disposeOfPublicToken(uint32_t token) -{ - RS_STACK_MUTEX(mDataMutex); - auto mit = mPublicToken.find(token); - if(mit != mPublicToken.end()) - { - mPublicToken.erase(mit); -#ifdef DATA_DEBUG - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": Deleting public token " << token << ". Completed tokens: " << mCompletedRequests.size() << " Size of mPublicToken: " << mPublicToken.size() << std::endl; -#endif - return true; - } - else - return false; -} - -#ifdef DATA_DEBUG -void RsGxsDataAccess::dumpTokenQueues() -{ - RS_STACK_MUTEX(mDataMutex); - - GXSDATADEBUG << "Service " << std::hex << mDataStore->serviceType() << std::dec << ": dumping token list."<< std::endl; - - for(auto tokenpair:mPublicToken) - GXSDATADEBUG << " Public Token " << tokenpair.first << " : " << tokenStatusString[tokenpair.second] << std::endl; - - for(auto tokenpair:mCompletedRequests) - GXSDATADEBUG << " Completed Tokens: " << tokenpair.first << std::endl; - - for(auto tokenpair:mRequestQueue) - GXSDATADEBUG << " RequestQueue: " << tokenpair.first << " status " << tokenStatusString[tokenpair.second->status] << std::endl; - - GXSDATADEBUG << std::endl; -} -#endif - -bool RsGxsDataAccess::checkGrpFilter(const RsTokReqOptions &opts, const std::shared_ptr& meta) const -{ - - bool subscribeMatch = false; - - if(opts.mSubscribeMask) - { - // Exact Flags match required. - if ((opts.mSubscribeMask & opts.mSubscribeFilter) == (opts.mSubscribeMask & meta->mSubscribeFlags)) - { - subscribeMatch = true; - } - } - else - { - subscribeMatch = true; - } - - return subscribeMatch; -} -bool RsGxsDataAccess::checkMsgFilter(const RsTokReqOptions& opts, const std::shared_ptr &meta ) const -{ - if (opts.mStatusMask) - { - // Exact Flags match required. - if ( (opts.mStatusMask & opts.mStatusFilter) == - (opts.mStatusMask & meta->mMsgStatus) ) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Continue checking Msg as StatusMatches: " - << " Mask: " << opts.mStatusMask - << " StatusFilter: " << opts.mStatusFilter - << " MsgStatus: " << meta->mMsgStatus - << " MsgId: " << meta->mMsgId << std::endl; -#endif - } - else - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Dropping Msg due to !StatusMatch " - << " Mask: " << opts.mStatusMask - << " StatusFilter: " << opts.mStatusFilter - << " MsgStatus: " << meta->mMsgStatus - << " MsgId: " << meta->mMsgId << std::endl; -#endif - - return false; - } - } - else - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Status check not requested" - << " mStatusMask: " << opts.mStatusMask - << " MsgId: " << meta->mMsgId << std::endl; -#endif - } - - if(opts.mMsgFlagMask) - { - // Exact Flags match required. - if ( (opts.mMsgFlagMask & opts.mMsgFlagFilter) == - (opts.mMsgFlagMask & meta->mMsgFlags) ) - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Accepting Msg as FlagMatches: " - << " Mask: " << opts.mMsgFlagMask - << " FlagFilter: " << opts.mMsgFlagFilter - << " MsgFlag: " << meta->mMsgFlags - << " MsgId: " << meta->mMsgId << std::endl; -#endif - } - else - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Dropping Msg due to !FlagMatch " - << " Mask: " << opts.mMsgFlagMask - << " FlagFilter: " << opts.mMsgFlagFilter - << " MsgFlag: " << meta->mMsgFlags - << " MsgId: " << meta->mMsgId << std::endl; -#endif - - return false; - } - } - else - { -#ifdef DATA_DEBUG - GXSDATADEBUG << __PRETTY_FUNCTION__ - << " Flags check not requested" - << " mMsgFlagMask: " << opts.mMsgFlagMask - << " MsgId: " << meta->mMsgId << std::endl; -#endif - } - - return true; -} - -GxsGroupStatistic::~GxsGroupStatistic() = default; -GxsServiceStatistic::~GxsServiceStatistic() = default; diff --git a/libretroshare/src/gxs/rsgxsdataaccess.h b/libretroshare/src/gxs/rsgxsdataaccess.h deleted file mode 100644 index cf5c729bd..000000000 --- a/libretroshare/src/gxs/rsgxsdataaccess.h +++ /dev/null @@ -1,519 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsdataaccess.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSDATAACCESS_H -#define RSGXSDATAACCESS_H - -#include -#include "retroshare/rstokenservice.h" -#include "rsgxsrequesttypes.h" -#include "rsgds.h" - - -typedef std::map< RsGxsGroupId, std::map > > MsgMetaFilter; -typedef std::map< RsGxsGroupId, std::shared_ptr > GrpMetaFilter; - -bool operator<(const std::pair& p1,const std::pair& p2); - -class RsGxsDataAccess : public RsTokenService -{ -public: - explicit RsGxsDataAccess(RsGeneralDataService* ds); - virtual ~RsGxsDataAccess() ; - -public: - - /** S: RsTokenService - * TODO: cleanup - * In the following methods @param uint32_t ansType is of no use, it is - * deprecated and should be removed as soon as possible as it is cause of - * many confusions, instead use const RsTokReqOptions::mReqType &opts to - * specify the kind of data you are interested in. - * Most of the methods use const uint32_t &token as param type change it to - * uint32_t - */ - - /*! - * Use this to request group related information - * @param token The token returned for the request, store this value to pool for request completion - * @param ansType @deprecated unused @see S: RsTokenService notice - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds group id to request info for - * @return - */ - bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) override; - - /*! - * Use this to request all group related info - * @param token The token returned for the request, store this value to pool for request completion - * @param ansType @deprecated unused @see S: RsTokenService notice - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @return - */ - bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) override; - - /*! - * Use this to get msg information (id, meta, or data), store token value to poll for request completion - * @param token The token returned for the request - * @param ansType @deprecated unused @see S: RsTokenService notice - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) override; - - /*! - * Use this to get message information (id, meta, or data), store token value to poll for request completion - * @param token The token returned for the request - * @param ansType @deprecated unused @see S: RsTokenService notice - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, this retrieve all the msgs info for each grpId in list, if group Id list is empty \n - * all messages for all groups are retrieved - * @return true if request successful false otherwise - */ - bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list& grpIds) override; - - /*! - * For requesting msgs related to a given msg id within a group - * @param token The token returned for the request - * @param ansType @deprecated unused @see S: RsTokenService notice - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector &msgIds) override; - - /*! - * This request statistics on amount of data held - * number of groups - * number of groups subscribed - * number of messages - * size of db store - * total size of messages - * total size of groups - * @param token - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - */ - void requestServiceStatistic(uint32_t& token, const RsTokReqOptions &opts) override; - - /*! - * To request statistic on a group - * @param token set to value to be redeemed to get statistic - * @param grpId the id of the group - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - */ - void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId, const RsTokReqOptions &opts) override; - - /* Poll */ - GxsRequestStatus requestStatus(uint32_t token); - - /* Cancel Request */ - bool cancelRequest(const uint32_t &token); - - - /** E: RsTokenService **/ - -public: - - /*! - * This adds a groups to the gxs data base, this is a blocking call \n - * If function returns successfully DataAccess can be queried for grp - * @param grp the group to add, responsibility grp passed lies with callee - * @return false if group cound not be added - */ - bool addGroupData(RsNxsGrp* grp); - - /*! - * This updates a groups in the gxs data base, this is a blocking call \n - * If function returns successfully DataAccess can be queried for grp - * @param grp the group to add, responsibility grp passed lies with callee - * @return false if group cound not be added - */ - bool updateGroupData(RsNxsGrp* grp); - - /*! - * This adds a group to the gxs data base, this is a blocking call \n - * Responsibility for msg still lies with callee \n - * If function returns successfully DataAccess can be queried for msg - * @param msg the msg to add - * @return false if msg could not be added, true otherwise - */ - bool addMsgData(RsNxsMsg* msg); - - /*! - * This retrieves a group from the gxs data base, this is a blocking call \n - * @param grp the group to add, memory ownership passed to the callee - * @return false if group cound not be retrieved - */ - bool getGroupData(const RsGxsGroupId& grpId,RsNxsGrp *& grp_data); - - -public: - - - - /*! - * This must be called periodically to progress requests - */ - void processRequests(); - - /*! - * @param token - * @param grpStatistic - * @return false if token cannot be redeemed - */ - bool getGroupStatistic(const uint32_t &token, GxsGroupStatistic& grpStatistic); - - /*! - * @param token - * @param servStatistic - * @return false if token cannot be redeemed - */ - bool getServiceStatistic(const uint32_t &token, GxsServiceStatistic& servStatistic); - - - /*! - * Retrieve group list for a given token - * @param token request token to be redeemed - * @param groupIds - * @param msgIds - * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready - */ - bool getGroupList(const uint32_t &token, std::list &groupIds); - - /*! - * - * @param token request token to be redeemed - * @param msgIds - */ - bool getMsgIdList(const uint32_t &token, GxsMsgIdResult &msgIds); - - - /*! - * Retrieve msg list for a given token for message related info - * @param token token to be redeemed - * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) - * @return false if could not redeem token - */ - bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds); - - - /*! - * @param token request token to be redeemed - * @param groupInfo - */ - bool getGroupSummary(const uint32_t &token, std::list > &groupInfo); - - /*! - * - * @param token request token to be redeemed - * @param msgInfo - */ - bool getMsgSummary(const uint32_t &token, GxsMsgMetaResult &msgInfo); - - - /*! - * Retrieve msg meta for a given token for message related info - * @param token token to be redeemed - * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) - * @return false if could not redeem token - */ - bool getMsgRelatedSummary(const uint32_t &token, MsgRelatedMetaResult& msgMeta); - - /*! - * - * @param token request token to be redeemed - * @param grpData - */ - bool getGroupData(const uint32_t &token, std::list& grpData); - - /*! - * - * @param token request token to be redeemed - * @param msgData - * @return false if data cannot be found for token - */ - bool getMsgData(const uint32_t &token, NxsMsgDataResult& msgData); - - /*! - * - * @param token request token to be redeemed - * @param msgData - * @return false if data cannot be found for token - */ - bool getMsgRelatedData(const uint32_t &token, NxsMsgRelatedDataResult& msgData); - -private: - - /** helper functions to implement token service **/ - - /*! - * Assigns a token value to passed integer - * @param token is assigned a unique token value - */ - void generateToken(uint32_t &token); - - /*! - * - * @param token the value of the token for the request object handle wanted - * @return the request associated to this token - */ - GxsRequest* locked_retrieveCompletedRequest(const uint32_t& token); - - /*! - * Add a gxs request to queue - * @param req gxs request to add - */ - void storeRequest(GxsRequest* req); - - /*! - * convenience function to setting members of request - * @param req - * @param token - * @param ansType - * @param opts - */ - void setReq(GxsRequest* req, uint32_t token, uint32_t ansType, const RsTokReqOptions& opts) const; - - /*! - * Remove request for request queue - * Request is deleted - * @param token the token associated to the request - * @return true if token successfully cleared, false if token does not exist - */ - bool clearRequest(const uint32_t &token); - - /*! - * Updates the status flag of a request - * @param token the token value of the request to set - * @param status the status to set - * @return - */ - bool locked_updateRequestStatus(uint32_t token, GxsRequestStatus status); - - /*! - * Use to query the status and other values of a given token - * @param token the toke of the request to check for - * @param status set to current status of request - * @param reqtype set to request type of request - * @param anstype set to to anstype of request - * @param ts time stamp - * @return false if token does not exist, true otherwise - */ - bool checkRequestStatus( uint32_t token, GxsRequestStatus &status, - uint32_t &reqtype, uint32_t &anstype, rstime_t &ts); - - // special ones for testing (not in final design) - /*! - * Get list of active tokens of this token service - * @param tokens sets to list of token contained in this tokenservice - */ - void tokenList(std::list &tokens); - - // /*! - // * Convenience function to delete the ids - // * @param filter the meta filter to clean - // */ - // void cleanseMsgMetaMap(GxsMsgMetaResult& result); - -public: - - /*! - * Assigns a token value to passed integer - * The status of the token can still be queried from request status feature - * @param token is assigned a unique token value - */ - uint32_t generatePublicToken(); - - /*! - * Updates the status of associate token - * @param token - * @param status - * @return false if token could not be found, true if token disposed of - */ - bool updatePublicRequestStatus(uint32_t token, GxsRequestStatus status); - - /*! - * This gets rid of a publicly issued token - * @param token - * @return false if token could not found, true if token disposed of - */ - bool disposeOfPublicToken(uint32_t token); - -private: - - /* These perform the actual blocking retrieval of data */ - - /*! - * Attempts to retrieve group id list from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getGroupList(GroupIdReq* req); - - /*! - * convenience function for filtering grpIds - * @param grpIdsIn The ids to filter with opts - * @param opts the filter options - * @param grpIdsOut grpIdsIn filtered with opts - */ - bool getGroupList(const std::list& grpIdsIn, const RsTokReqOptions& opts, std::list& grpIdsOut); - - /*! - * Attempts to retrieve msg id list from data store - * Computationally/CPU-Bandwidth expensive - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getMsgIdList(MsgIdReq* req); - - /*! - * Attempts to retrieve msg Meta list from data store - * Computationally/CPU-Bandwidth expensive - * - * @param msgIds List of message Ids for the Message Metas to retrieve - * @param opts GxsRequest options - * @param result Map of Meta information for messages - * - */ - bool getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgMetaResult& result ); - - /*! - * Attempts to retrieve group meta data from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getGroupSummary(GroupMetaReq* req); - - /*! - * Attempts to retrieve msg meta data from data store - * @param req - * @return false if unsuccessful, true otherwise - */ - bool getMsgSummary(MsgMetaReq* req); - - /*! - * Attempts to retrieve group data from data store - * @param req The request specifying data to retrieve - * @return false if unsuccessful, true otherwise - */ - bool getGroupData(GroupDataReq* req); - - /*! - * Attempts to retrieve message data from data store - * @param req The request specifying data to retrieve - * @return false if unsuccessful, true otherwise - */ - bool getMsgData(MsgDataReq* req); - - - /*! - * Attempts to retrieve messages related to msgIds of associated equest - * @param req Request object to satisfy - * @return false if data cannot be found for token - */ - bool getMsgRelatedInfo(MsgRelatedInfoReq* req); - - - /*! - * - * Attempts to retrieve group statistic - * @param req Request object to satisfy - */ - bool getGroupStatistic(GroupStatisticRequest* req); - - /*! - * - * Attempts to retrieve group data in serialized format - * @param req Request object to satisfy - */ - bool getGroupSerializedData(GroupSerializedDataReq* req); - - /*! - * - * Attempts to service statistic - * @param req request object to satisfy - */ - bool getServiceStatistic(ServiceStatisticRequest* req); - - /*! - * This filter msgs based of options supplied (at the moment just status masks) - * @param msgIds The msgsIds to filter - * @param opts the request options set by user - * @param meta The accompanying meta information for msg, ids - */ - void filterMsgIdList(GxsMsgIdResult& msgIds, const RsTokReqOptions& opts, const MsgMetaFilter& meta) const; - - /*! - * This filter msgs based of options supplied (at the moment just status masks) - * @param grpIds The group ids to filter - * @param opts the request options containing mask set by user - * @param meta The accompanying meta information for group ids - */ - void filterGrpList(std::list& msgIds, const RsTokReqOptions& opts, const GrpMetaFilter& meta) const; - - - /*! - * This applies the options to the meta to find out if the given message satisfies - * them - * @param opts options containing filters to check - * @param meta meta containing currently defined options for msg - * @return true if msg meta passes all options - */ - bool checkMsgFilter(const RsTokReqOptions& opts, const std::shared_ptr& meta) const; - - /*! - * This applies the options to the meta to find out if the given group satisfies - * them - * @param opts options containing filters to check - * @param meta meta containing currently defined options for group - * @return true if group meta passes all options - */ - bool checkGrpFilter(const RsTokReqOptions& opts, const std::shared_ptr &meta) const; - - - /*! - * This is a filter method which applies the request options to the list of ids - * requested - * @param msgIds the msg ids for filter to be applied to - * @param opts the options used to parameterise the id filter - * @param msgIdsOut the left overs ids after filter is applied to msgIds - */ - bool getMsgIdList(const GxsMsgReq& msgIds, const RsTokReqOptions& opts, GxsMsgReq& msgIdsOut); - - void dumpTokenQueues(); -private: - bool locked_clearRequest(const uint32_t &token); - - RsGeneralDataService* mDataStore; - - RsMutex mDataMutex; /* protecting below */ - - uint32_t mNextToken; - std::map mPublicToken; - - std::set > mRequestQueue; - std::map mCompletedRequests; - - bool mUseMetaCache; -}; - -#endif // RSGXSDATAACCESS_H diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc deleted file mode 100644 index 888a54aa2..000000000 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ /dev/null @@ -1,5617 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsnetservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// -// RsNxsItem -// | -// +-- RsNxsSyncGrp send req for group list, with time stamp of what we have -// +-- RsNxsSyncMsg -// +-- RsNxsGroupPublishKeyItem -// +-- RsNxsSyncGrpItem send individual grp info with time stamps, authors, etc. -// -// -// tick() -// | -// +----------- sharePublishKeys() -// | -// +----------- syncWithPeers() -// | | -// | +--if AutoSync--- send global UpdateTS of each peer to itself => the peer knows the last -// | | time current peer has received an updated from himself -// | | type=RsNxsSyncGrp -// | | role: advise to request grp list for mServType -// | | -// | +--Retrive all grp Id + meta -// | -// | For each peer -// | For each grp to request -// | send RsNxsSyncMsg(ServiceType, grpId, updateTS) -// | | -// | (Only send if rand() < sendingProb()) +---comes from mClientMsgUpdateMap -// | -// +----------- recvNxsItemQueue() -// | -// +------ handleRecvPublishKeys(auto*) -// | -// | -// | -// +------ handleRecvSyncGroup( RsNxsSyncGrp*) -// | - parse all subscribed groups. For each, send a RsNxsSyncGrpItem with publish TS -// | - pack into a single RsNxsTransac item -// | | -// | +---- canSendGrpId(peer, grpMeta, toVet) // determines if put in vetting list -// | | | // or sent right away -// | | +--CIRCLES_TYPE_LOCAL------- false -// | | +--CIRCLES_TYPE_PUBLIC------ true -// | | +--CIRCLES_TYPE_EXTERNAL---- mCircles->canSend(circleId, getPgpId(peerId)) -// | | +--CIRCLES_TYPE_YOUR_EYES--- internal circle stuff -// | | -// | +---- store in mPendingCircleVet ou directement locked_pushGrpRespFromList() -// | -// +------ handleRecvSyncMessage( RsNxsSyncMsg*) -// - parse msgs from group -// - send all msg IDs for this group -// | -// +---- canSendMsgIds(msgMeta, grpMeta, peer) -// | | -// | +--CIRCLES_TYPE_LOCAL------- false -// | +--CIRCLES_TYPE_PUBLIC------ true -// | +--CIRCLES_TYPE_EXTERNAL---- mCircles->canSend(circleId, getPgpId(peerId)) -// | +--CIRCLES_TYPE_YOUR_EYES--- internal circle stuff -// | -// +---- store in mPendingCircleVet ou directement locked_pushGrpRespFromList() -// data_tick() -// | -// +----------- updateServerSyncTS() -// | - retrieve all group meta data -// | - updates mServerMsgUpdateMap[grpId]=grp->mLastPostTS for all grps -// | - updates mGrpServerUpdateItem to max of all received TS -// | -// +----------- processTransactions() -// | -// +----------- processCompletedTransactions() -// | | -// | +------ locked_processCompletedIncomingTrans() -// | | | -// | | +-------- locked_genReqMsgTransaction() // request messages based on list -// | | | -// | | +-------- locked_genReqGrpTransaction() // request groups based on list -// | | | -// | | +-------- locked_genSendMsgsTransaction() // send msg list -// | | | -// | | +-------- locked_genSendGrpsTransaction() // send group list -// | | -// | +------ locked_processCompletedOutgoingTrans() -// | -// +----------- processExplicitGroupRequests() -// | - parse mExplicitRequest and for each element (containing a grpId list), -// | send the group ID (?!?!) -// | -// +----------- runVetting() -// | -// +--------- sort items from mPendingResp -// | | -// | +------ locked_createTransactionFromPending(GrpRespPending / MsgRespPending) -// | | // takes accepted transaction and adds them to the list of active trans -// | -// +--------- sort items from mPendingCircleVetting -// | -// +------ locked_createTransactionFromPending(GrpCircleIdsRequestVetting / MsgCircleIdsRequestVetting) -// // takes accepted transaction and adds them to the list of active trans -// -// Objects for time stamps -// ======================= -// -// mClientGrpUpdateMap: map< RsPeerId, TimeStamp > Time stamp of last modification of group data for that peer (in peer's clock time!) -// (Set at server side to be mGrpServerUpdateItem->grpUpdateTS) -// -// Only updated in processCompletedIncomingTransaction() from Grp list transaction. -// Used in syncWithPeers() sending in RsNxsSyncGrp once to all peers: peer will send data if -// has something new. All time comparisons are in the friends' clock time. -// -// mClientMsgUpdateMap: map< RsPeerId, map > -// -// Last msg list modification time sent by that peer Id -// Updated in processCompletedIncomingTransaction() from Grp list trans. -// Used in syncWithPeers() sending in RsNxsSyncGrp once to all peers. -// Set at server to be mServerMsgUpdateMap[grpId]->msgUpdateTS -// -// mGrpServerUpdateItem: TimeStamp Last group local modification timestamp over all groups -// -// mServerMsgUpdateMap: map< GrpId, TimeStamp > Timestamp local modification for each group (i.e. time of most recent msg / metadata update) -// -// -// Group update algorithm -// ====================== -// -// CLient Server -// ====== ====== -// -// tick() tick() -// | | -// +---- SyncWithPeers +-- recvNxsItemQueue() -// | | -// +---------------- Send global UpdateTS of each peer to itself => the peer knows +---------> +------ handleRecvSyncGroup( RsNxsSyncGrp*) -// | the last msg sent (stored in mClientGrpUpdateMap[peer_id]), | | - parse all subscribed groups. For each, send a RsNxsSyncGrpItem with publish TS -// | type=RsNxsSyncGrp | | - pack into a single RsNxsTransac item -// | role: advise to request grp list for mServType -------------------+ | -// | +--> +------ handleRecvSyncMessage( RsNxsSyncMsg*) -// +---------------- Retrieve all grp Id + meta | - parse msgs from group -// | | - send all msg IDs for this group -// +-- For each peer | -// For each grp to request | -// send RsNxsSyncMsg(ServiceType, grpId, updateTS) | -// | | -// (Only send if rand() < sendingProb()) +---comes from mClientMsgUpdateMap -----+ -// -// Suggestions -// =========== -// * handleRecvSyncGroup should use mit->second.mLastPost to limit the sending of already known data -// X * apparently mServerMsgUpdateMap is initially empty -> by default clients will always want to receive the data. -// => new peers will always send data for each group until they get an update for that group. -// X * check that there is a timestamp for unsubscribed items, otherwise we always send TS=0 and we always get them!! (in 346) -// -// -> there is not. mClientMsgUpdateMap is updated when msgs are received. -// -> 1842: leaves before asking for msg content. -// -// Proposed changes: -// - for unsubsribed groups, mClientMsgUpdateMap[peerid][grpId]=now when the group list is received => wont be asked again -// - when we subscribe, we reset the time stamp. -// -// Better change: -// - each peer sends last -// -// * the last TS method is not perfect: do new peers always receive old messages? -// -// * there's double information between mServerMsgUpdateMap first element (groupId) and second->grpId -// * processExplicitGroupRequests() seems to send the group list that it was asked for without further information. How is that useful??? -// -// * grps without messages will never be stamped because stamp happens in genReqMsgTransaction, after checking msgListL.empty() -// Problem: without msg, we cannot know the grpId!! -// -// * mClientMsgUpdateMap[peerid][grpId] is only updated when new msgs are received. Up to date groups will keep asking for lists! -// -// Distant sync -// ============ -// -// Distant sync uses tunnels to sync subscribed GXS groups that are not supplied by friends. Peers can subscribe to a GXS group using a RS link -// which GXS uses to request updates through tunnels. -// * The whole exchange should be kept private and anonymous between the two distant peers, so we use the same trick than for FT: encrypt the data using the group ID. -// * The same node shouldn't be known as a common server for different GXS groups -// -// GXS net service: -// * talks to virtual peers, treated like normal peers -// * virtual peers only depend on the server ID, not on tunnel ID, and be kept constant accross time so that ClientGroupUpdateMap is kept consistent -// * does not use tunnels if friends can already supply the data (??) This causes issues with "islands". -// -// Tunnels: -// * a specific service named GxsSyncTunnelService handles the creation/management of sync tunnels: -// * tunnel data need to be encrypted. -// -// bool manageTunnels(const RsGxsGroupId&) ; // start managing tunnels for this group -// bool releaseTunnels(const RsGxsGroupId&) ; // stop managing tunnels for this group -// bool sendData(const unsigned char *data,uint32_t size,const RsPeerId& virtual_peer) ; // send data to this virtual peer -// bool getVirtualPeers(const RsGxsGroupId&, std::list& peers) ; // returns the virtual peers for this group -// -// Proposed protocol: -// * request tunnels based on H(GroupId) -// * encrypt tunnel data using chacha20+HMAC-SHA256 using AEAD( GroupId, 96bits IV, tunnel ID ) (similar to what FT does) -// * when tunnel is established, exchange virtual peer names: vpid = H( GroupID | Random bias ) -// * when vpid is known, notify the client (GXS net service) which can use the virtual peer to sync -// -// * only use a single tunnel per virtual peer ID -// -// Client ------------------ TR(H(GroupId)) --------------> Server -// -// Client <-------------------- T OK ---------------------- Server -// -// [Encrypted traffic using H(GroupId, 96bits IV, tunnel ID)] -// -// Client <--------- VPID = H( Random IV | GroupId ) ------ Server -// | | -// +--------------> Mark the virtual peer active <-----------+ -// -// Unsolved problems: -// * if we want to preserve anonymity, we cannot prevent GXS from duplicating the data from virtual/real peers that actually are the same peers. -// * ultimately we should only use tunnels to sync GXS. The mix between tunnels and real peers is not a problem but will cause unnecessary traffic. -// -// Notes: -// * given that GXS only talks to peers once every 2 mins, it's likely that keep-alive packets will be needed - - -#include -#include -#include -#include -#include - -#include "rsgxsnetservice.h" -#include "gxssecurity.h" -#include "retroshare/rsconfig.h" -#include "retroshare/rsgxsflags.h" -#include "retroshare/rsgxscircles.h" -#include "retroshare/rspeers.h" -#include "pgp/pgpauxutils.h" -#include "crypto/rscrypto.h" -#include "util/rsdir.h" -#include "util/rstime.h" -#include "util/rsmemory.h" -#include "util/stacktrace.h" - -#ifdef RS_DEEP_CHANNEL_INDEX -# include "deep_search/channelsindex.hpp" -#endif - -/*** - * Use the following defines to debug: - NXS_NET_DEBUG_0 shows group update high level information - NXS_NET_DEBUG_1 shows group update low level info (including transaction details) - NXS_NET_DEBUG_2 bandwidth information - NXS_NET_DEBUG_3 publish key exchange - NXS_NET_DEBUG_4 vetting - NXS_NET_DEBUG_5 summary of transactions (useful to just know what comes in/out) - NXS_NET_DEBUG_6 group sync statistics (e.g. number of posts at nighbour nodes, etc) - NXS_NET_DEBUG_7 encryption/decryption of transactions - NXS_NET_DEBUG_8 gxs distant sync - NXS_NET_DEBUG_9 gxs distant search - - ***/ -//#define NXS_NET_DEBUG_0 1 -//#define NXS_NET_DEBUG_1 1 -//#define NXS_NET_DEBUG_2 1 -//#define NXS_NET_DEBUG_3 1 -//#define NXS_NET_DEBUG_4 1 -//#define NXS_NET_DEBUG_5 1 -//#define NXS_NET_DEBUG_6 1 -//#define NXS_NET_DEBUG_7 1 -//#define NXS_NET_DEBUG_8 1 -//#define NXS_NET_DEBUG_9 1 - -//#define NXS_FRAG - -// The constant below have a direct influence on how fast forums/channels/posted/identity groups propagate and on the overloading of queues: -// -// Channels/forums will update at a rate of SYNC_PERIOD*MAX_REQLIST_SIZE/60 messages per minute. -// A large TRANSAC_TIMEOUT helps large transactions to finish before anything happens (e.g. disconnexion) or when the server has low upload bandwidth, -// but also uses more memory. -// A small value for MAX_REQLIST_SIZE is likely to help messages to propagate in a chaotic network, but will also slow them down. -// A small SYNC_PERIOD fasten message propagation, but is likely to overload the server side of transactions (e.g. overload outqueues). -// -//static const uint32_t GIXS_CUT_OFF = 0; -static const uint32_t SYNC_PERIOD = 60; -static const uint32_t MAX_REQLIST_SIZE = 20; // No more than 20 items per msg request list => creates smaller transactions that are less likely to be cancelled. -static const uint32_t TRANSAC_TIMEOUT = 2000; // In seconds. Has been increased to avoid epidemic transaction cancelling due to overloaded outqueues. -#ifdef TO_REMOVE -static const uint32_t SECURITY_DELAY_TO_FORCE_CLIENT_REUPDATE = 3600; // force re-update if there happens to be a large delay between our server side TS and the client side TS of friends -#endif -static const uint32_t REJECTED_MESSAGE_RETRY_DELAY = 24*3600; // re-try rejected messages every 24hrs. Most of the time this is because the peer's reputation has changed. -static const uint32_t GROUP_STATS_UPDATE_DELAY = 240; // update unsubscribed group statistics every 3 mins -static const uint32_t GROUP_STATS_UPDATE_NB_PEERS = 2; // number of peers to which the group stats are asked -static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; // 200,000 bytes including signature and headers -static const uint32_t MIN_DELAY_BETWEEN_GROUP_SEARCH = 40; // dont search same group more than every 40 secs. -static const uint32_t SAFETY_DELAY_FOR_UNSUCCESSFUL_UPDATE = 0; // avoid re-sending the same msg list to a peer who asks twice for the same update in less than this time - -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN = 0x00 ; -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_NO_ERROR = 0x01 ; -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR = 0x02 ; -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_ENCRYPTION_ERROR = 0x03 ; -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_SERIALISATION_ERROR = 0x04 ; -static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ; - -// Debug system to allow to print only for some IDs (group, Peer, etc) - -#if defined(NXS_NET_DEBUG_0) || defined(NXS_NET_DEBUG_1) || defined(NXS_NET_DEBUG_2) || defined(NXS_NET_DEBUG_3) \ - || defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \ - || defined(NXS_NET_DEBUG_8) || defined(NXS_NET_DEBUG_9) - -static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ; -static const RsGxsGroupId group_id_to_print = RsGxsGroupId();//std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs -static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS; // use this to allow to this service id only, or 0 for all services - // warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums) - -class nullstream: public std::ostream {}; - -static std::string nice_time_stamp(rstime_t now,rstime_t TS) -{ - if(TS == 0) - return "Never" ; - else - { - std::ostringstream s; - s << now - TS << " secs ago" ; - return s.str() ; - } -} - -static std::ostream& gxsnetdebug(const RsPeerId& peer_id,const RsGxsGroupId& grp_id,uint32_t service_type) -{ - static nullstream null ; - - if((peer_to_print.isNull() || peer_id.isNull() || peer_id == peer_to_print) - && (group_id_to_print.isNull() || grp_id.isNull() || grp_id == group_id_to_print) - && (service_to_print==0 || service_type == 0 || ((service_type >> 8)&0xffff) == service_to_print)) - return std::cerr << time(NULL) << ":GXSNETSERVICE: " ; - else - return null ; -} - -#define GXSNETDEBUG___ gxsnetdebug(RsPeerId(),RsGxsGroupId(),mServiceInfo.mServiceType) -#define GXSNETDEBUG_P_(peer_id ) gxsnetdebug(peer_id ,RsGxsGroupId(),mServiceInfo.mServiceType) -#define GXSNETDEBUG__G( group_id) gxsnetdebug(RsPeerId(),group_id ,mServiceInfo.mServiceType) -#define GXSNETDEBUG_PG(peer_id,group_id) gxsnetdebug(peer_id ,group_id ,mServiceInfo.mServiceType) - -#endif - -const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000; - -RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, - RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, - const RsServiceInfo serviceInfo, - RsGixsReputation* reputations, RsGcxs* circles, RsGixs *gixs, - PgpAuxUtils *pgpUtils, RsGxsNetTunnelService *mGxsNT, - bool grpAutoSync, bool msgAutoSync, bool distSync, uint32_t default_store_period, uint32_t default_sync_period) - : p3ThreadedService(), p3Config(), mTransactionN(0), - mObserver(nxsObs), mDataStore(gds), - mServType(servType), mTransactionTimeOut(TRANSAC_TIMEOUT), - mNetMgr(netMgr), mNxsMutex("RsGxsNetService"), - mSyncTs(0), mLastKeyPublishTs(0), - mLastCleanRejectedMessages(0), mSYNC_PERIOD(SYNC_PERIOD), - mCircles(circles), mGixs(gixs), - mReputations(reputations), mPgpUtils(pgpUtils), mGxsNetTunnel(mGxsNT), - mGrpAutoSync(grpAutoSync), mAllowMsgSync(msgAutoSync),mAllowDistSync(distSync), - mServiceInfo(serviceInfo), mDefaultMsgStorePeriod(default_store_period), - mDefaultMsgSyncPeriod(default_sync_period) -{ - addSerialType(new RsNxsSerialiser(mServType)); - mOwnId = mNetMgr->getOwnId(); - mUpdateCounter = 0; - - mLastCacheReloadTS = 0; - - // check the consistency - - if(mDefaultMsgStorePeriod > 0 && mDefaultMsgSyncPeriod > mDefaultMsgStorePeriod) - { - std::cerr << "(WW) in GXS service \"" << getServiceInfo().mServiceName << "\": too large message sync period will be set to message store period." << std::endl; - mDefaultMsgSyncPeriod = mDefaultMsgStorePeriod ; - } -} - -void RsGxsNetService::getItemNames(std::map& names) const -{ - names.clear(); - - names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM ] = "Group Sync Request" ; - names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM ] = "Group Sync" ; - names[RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM ] = "Group Stats" ; - names[RS_PKT_SUBTYPE_NXS_GRP_ITEM ] = "Group Data" ; - names[RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM ] = "Encrypted data" ; - names[RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM ] = "Session Key" ; - names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM ] = "Message Sync" ; - names[RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM ] = "Message Sync Request" ; - names[RS_PKT_SUBTYPE_NXS_MSG_ITEM ] = "Message Data" ; - names[RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM ] = "Transaction" ; - names[RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM ] = "Publish key" ; -} - -RsGxsNetService::~RsGxsNetService() -{ - RS_STACK_MUTEX(mNxsMutex) ; - - for(TransactionsPeerMap::iterator it = mTransactions.begin();it!=mTransactions.end();++it) - { - for(TransactionIdMap::iterator it2 = it->second.begin();it2!=it->second.end();++it2) - delete it2->second ; - - it->second.clear() ; - } - mTransactions.clear() ; - - mClientGrpUpdateMap.clear() ; - mServerMsgUpdateMap.clear() ; -} - - -int RsGxsNetService::tick() -{ - // always check for new items arriving - // from peers - recvNxsItemQueue(); - - bool should_notify = false; - - { - RS_STACK_MUTEX(mNxsMutex) ; - - should_notify = should_notify || !mNewGroupsToNotify.empty() ; - should_notify = should_notify || !mNewMessagesToNotify.empty() ; - should_notify = should_notify || !mNewPublishKeysToNotify.empty() ; - should_notify = should_notify || !mNewStatsToNotify.empty() ; - should_notify = should_notify || !mNewGrpSyncParamsToNotify.empty() ; - } - - if(should_notify) - processObserverNotifications() ; - - rstime_t now = time(NULL); - rstime_t elapsed = mSYNC_PERIOD + mSyncTs; - - if((elapsed) < now) - { - syncWithPeers(); - syncGrpStatistics(); - checkDistantSyncState(); - - mSyncTs = now; - } - - if(now > 10 + mLastKeyPublishTs) - { - sharePublishKeysPending() ; - - mLastKeyPublishTs = now ; - } - - if(now > 3600 + mLastCleanRejectedMessages) - { - mLastCleanRejectedMessages = now ; - cleanRejectedMessages() ; - } - return 1; -} - -void RsGxsNetService::processObserverNotifications() -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "Processing observer notification." << std::endl; -#endif - - // Observer notifycation should never be done explicitly within a Mutex-protected region, because of the risk - // of causing a cross-deadlock between the observer (RsGxsGenExchange) and the network layer (RsGxsNetService). - - std::vector grps_copy ; - std::vector msgs_copy ; - std::set stat_copy ; - std::set keys_copy,grpss_copy ; - - { - RS_STACK_MUTEX(mNxsMutex) ; - - grps_copy = mNewGroupsToNotify ; - msgs_copy = mNewMessagesToNotify ; - stat_copy = mNewStatsToNotify ; - keys_copy = mNewPublishKeysToNotify ; - grpss_copy = mNewGrpSyncParamsToNotify ; - - mNewGroupsToNotify.clear() ; - mNewMessagesToNotify.clear() ; - mNewStatsToNotify.clear() ; - mNewPublishKeysToNotify.clear() ; - mNewGrpSyncParamsToNotify.clear() ; - } - - if(!grps_copy.empty()) mObserver->receiveNewGroups (grps_copy); - if(!msgs_copy.empty()) mObserver->receiveNewMessages(msgs_copy); - - for(std::set::const_iterator it(keys_copy.begin());it!=keys_copy.end();++it) - mObserver->notifyReceivePublishKey(*it); - - for(std::set::const_iterator it(stat_copy.begin());it!=stat_copy.end();++it) - mObserver->notifyChangedGroupStats(*it); - - for(std::set::const_iterator it(grpss_copy.begin());it!=grpss_copy.end();++it) - mObserver->notifyChangedGroupSyncParams(*it); -} - -void RsGxsNetService::rejectMessage(const RsGxsMessageId& msg_id) -{ - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "adding message " << msg_id << " to rejection list for 24hrs." << std::endl; -#endif - mRejectedMessages[msg_id] = time(NULL) ; -} -void RsGxsNetService::cleanRejectedMessages() -{ - RS_STACK_MUTEX(mNxsMutex) ; - rstime_t now = time(NULL) ; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "Cleaning rejected messages." << std::endl; -#endif - - for(std::map::iterator it(mRejectedMessages.begin());it!=mRejectedMessages.end();) - if(it->second + REJECTED_MESSAGE_RETRY_DELAY < now) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << " message id " << it->first << " should be re-tried. removing from list..." << std::endl; -#endif - - std::map::iterator tmp = it ; - ++tmp ; - mRejectedMessages.erase(it) ; - it=tmp ; - } - else - ++it ; -} - -RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) -{ - static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ; - unsigned char tmpmem[SIZE]; - uint32_t offset = 0 ; - - pid.serialise(tmpmem,SIZE,offset) ; - gid.serialise(tmpmem,SIZE,offset) ; - - assert(RsGxsGroupId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ; - - return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() ); -} - -void RsGxsNetService::syncWithPeers() -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "RsGxsNetService::syncWithPeers() this=" << (void*)this << ". serviceInfo=" << mServiceInfo << std::endl; -#endif - - static RsNxsSerialiser ser(mServType) ; // this is used to estimate bandwidth. - - RS_STACK_MUTEX(mNxsMutex) ; - - std::set peers; - mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers); - - if(mAllowDistSync && mGxsNetTunnel != NULL) - { - // Grab all online virtual peers of distant tunnels for the current service. - - std::list vpids ; - mGxsNetTunnel->getVirtualPeers(vpids); - - for(auto it(vpids.begin());it!=vpids.end();++it) - peers.insert(RsPeerId(*it)) ; - } - - if (peers.empty()) { - // nothing to do - return; - } - - // for now just grps - for(auto sit = peers.begin(); sit != peers.end(); ++sit) - { - - const RsPeerId peerId = *sit; - - ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId); - uint32_t updateTS = 0; - - if(cit != mClientGrpUpdateMap.end()) - { - const RsGxsGrpUpdate *gui = &cit->second; - updateTS = gui->grpUpdateTS; - } - RsNxsSyncGrpReqItem *grp = new RsNxsSyncGrpReqItem(mServType); - grp->clear(); - grp->PeerId(*sit); - grp->updateTS = updateTS; - -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_(*sit) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global group TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) to himself" << std::endl; -#endif - generic_sendItem(grp); - } - - if(!mAllowMsgSync) - return ; - -#ifndef GXS_DISABLE_SYNC_MSGS - - RsGxsGrpMetaTemporaryMap grpMeta; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - RsGxsGrpMetaTemporaryMap toRequest; - - for(RsGxsGrpMetaTemporaryMap::iterator mit = grpMeta.begin(); mit != grpMeta.end(); ++mit) - { - const auto& meta = mit->second; - - // This was commented out because we want to know how many messages are available for unsubscribed groups. - - if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) - { - toRequest.insert(std::make_pair(mit->first, meta)); - mit->second = NULL ; // avoids destruction ;-) - } - } - - // Synchronise group msg for groups which we're subscribed to - // For each peer and each group, we send to the peer the time stamp of the most - // recent modification the peer has sent. If the peer has more recent messages he will send them, because its latest - // modifications will be more recent. This ensures that we always compare timestamps all taken in the same - // computer (the peer's computer in this case) - - for(auto sit = peers.begin(); sit != peers.end(); ++sit) - { - const RsPeerId& peerId = *sit; - - // now see if you have an updateTS so optimise whether you need - // to get a new list of peer data - const RsGxsMsgUpdate *mui = NULL; - - ClientMsgMap::const_iterator cit = mClientMsgUpdateMap.find(peerId); - - if(cit != mClientMsgUpdateMap.end()) - mui = &cit->second; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peerId) << " syncing messages with peer " << peerId << std::endl; -#endif - - RsGxsGrpMetaTemporaryMap::const_iterator mmit = toRequest.begin(); - for(; mmit != toRequest.end(); ++mmit) - { - const auto& meta = mmit->second; - const RsGxsGroupId& grpId = mmit->first; - RsGxsCircleId encrypt_to_this_circle_id ; - - if(!checkCanRecvMsgFromPeer(peerId, *meta,encrypt_to_this_circle_id)) - continue; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(peerId,grpId) << " peer can send messages for group " << grpId ; - if(!encrypt_to_this_circle_id.isNull()) - GXSNETDEBUG_PG(peerId,grpId) << " request should be encrypted for circle ID " << encrypt_to_this_circle_id << std::endl; - else - GXSNETDEBUG_PG(peerId,grpId) << " request should be sent in clear." << std::endl; - -#endif - // On default, the info has never been received so the TS is 0, meaning the peer has sent that it had no information. - - uint32_t updateTS = 0; - - if(mui) - { - std::map::const_iterator cit2 = mui->msgUpdateInfos.find(grpId); - - if(cit2 != mui->msgUpdateInfos.end()) - updateTS = cit2->second.time_stamp; - } - - // get sync params for this group - - RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType); - - msg->clear(); - msg->PeerId(peerId); - msg->updateTS = updateTS; - - int req_delay = (int)locked_getGrpConfig(grpId).msg_req_delay ; - int keep_delay = (int)locked_getGrpConfig(grpId).msg_keep_delay ; - - // If we store for less than we request, we request less, otherwise the posts will be deleted after being obtained. - - if(keep_delay > 0 && req_delay > 0 && keep_delay < req_delay) - req_delay = keep_delay ; - - // The last post will be set to TS 0 if the req delay is 0, which means "Indefinitly" - - if(req_delay > 0) - msg->createdSinceTS = std::max(0,(int)time(NULL) - req_delay); - else - msg->createdSinceTS = 0 ; - - if(encrypt_to_this_circle_id.isNull()) - msg->grpId = grpId; - else - { - msg->grpId = hashGrpId(grpId,mNetMgr->getOwnId()) ; - msg->flag |= RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID ; - } - -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl; -#endif - generic_sendItem(msg); - -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl; -#endif - } - } - -#endif -} - -void RsGxsNetService::generic_sendItem(RsNxsItem *si) -{ - // check if the item is to be sent to a distant peer or not - - RsGxsGroupId tmp_grpId; - - if(mAllowDistSync && mGxsNetTunnel != NULL && mGxsNetTunnel->isDistantPeer( static_cast(si->PeerId()),tmp_grpId)) - { - RsNxsSerialiser ser(mServType); - - uint32_t size = ser.size(si); - unsigned char *mem = (unsigned char *)rs_malloc(size) ; - - if(!mem) - return ; - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG_P_(si->PeerId()) << "Sending RsGxsNetTunnelService Item:" << (void*)si << " of type: " << std::hex << si->PacketId() << std::dec - << " transaction " << si->transactionNumber << " to virtual peer " << si->PeerId() << std::endl ; -#endif - ser.serialise(si,mem,&size) ; - - mGxsNetTunnel->sendTunnelData(mServType,mem,size,static_cast(si->PeerId())); - delete si; - } - else - sendItem(si) ; -} - -void RsGxsNetService::checkDistantSyncState() -{ - if(!mAllowDistSync || mGxsNetTunnel==NULL || !mGrpAutoSync) - return ; - - RsGxsGrpMetaTemporaryMap grpMeta; - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - // Go through group statistics and groups without information are re-requested to random peers selected - // among the ones who provided the group info. - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___<< "Checking distant sync for all groups." << std::endl; -#endif - // get the list of online peers - - std::set online_peers; - mNetMgr->getOnlineList(mServiceInfo.mServiceType , online_peers); - - RS_STACK_MUTEX(mNxsMutex) ; - - for(auto it(grpMeta.begin());it!=grpMeta.end();++it) - if(it->second->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) // we only consider subscribed groups here. - { -#warning (cyril) We might need to also remove peers for recently unsubscribed groups - const RsGxsGroupId& grpId(it->first); - const RsGxsGrpConfig& rec = locked_getGrpConfig(grpId) ; - -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG__G(it->first) << " group " << grpId; -#endif - bool at_least_one_friend_is_supplier = false ; - - for(auto it2(rec.suppliers.ids.begin());it2!=rec.suppliers.ids.end() && !at_least_one_friend_is_supplier;++it2) - if(online_peers.find(*it2) != online_peers.end()) // check that the peer is online - at_least_one_friend_is_supplier = true ; - - // That strategy is likely to create islands of friends connected to each other. There's no real way - // to decide what to do here, except maybe checking the last message TS remotely vs. locally. - - if(at_least_one_friend_is_supplier) - { - mGxsNetTunnel->releaseDistantPeers(mServType,grpId); -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___<< " Group " << grpId << ": suppliers among friends. Releasing peers." << std::endl; -#endif - } - else - { - mGxsNetTunnel->requestDistantPeers(mServType,grpId); -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___<< " Group " << grpId << ": no suppliers among friends. Requesting peers." << std::endl; -#endif - } - } -} - -void RsGxsNetService::syncGrpStatistics() -{ - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG___<< "Sync-ing group statistics." << std::endl; -#endif - RsGxsGrpMetaTemporaryMap grpMeta; - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - - std::set online_peers; - mNetMgr->getOnlineList(mServiceInfo.mServiceType, online_peers); - - if(mAllowDistSync && mGxsNetTunnel != NULL) - { - // Grab all online virtual peers of distant tunnels for the current service. - - std::list vpids ; - mGxsNetTunnel->getVirtualPeers(vpids); - - for(auto it(vpids.begin());it!=vpids.end();++it) - online_peers.insert(RsPeerId(*it)) ; - } - - // Go through group statistics and groups without information are re-requested to random peers selected - // among the ones who provided the group info. - - rstime_t now = time(NULL) ; - - for(auto it(grpMeta.begin());it!=grpMeta.end();++it) - { - const RsGxsGrpConfig& rec = locked_getGrpConfig(it->first) ; - -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG__G(it->first) << " group " << it->first ; -#endif - - if(rec.statistics_update_TS + GROUP_STATS_UPDATE_DELAY < now && rec.suppliers.ids.size() > 0) - { -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG__G(it->first) << " needs update. Randomly asking to some friends" << std::endl; -#endif - // randomly select GROUP_STATS_UPDATE_NB_PEERS friends among the suppliers of this group - - uint32_t n = RSRandom::random_u32() % rec.suppliers.ids.size() ; - - std::set::const_iterator rit = rec.suppliers.ids.begin(); - for(uint32_t i=0;ifirst) << " asking friend " << peer_id << " for an update of stats for group " << it->first << std::endl; -#endif - - RsNxsSyncGrpStatsItem *grs = new RsNxsSyncGrpStatsItem(mServType) ; - - grs->request_type = RsNxsSyncGrpStatsItem::GROUP_INFO_TYPE_REQUEST ; - - grs->grpId = it->first ; - grs->PeerId(peer_id) ; - - generic_sendItem(grs) ; - } - } - } -#ifdef NXS_NET_DEBUG_6 - else - GXSNETDEBUG__G(it->first) << " up to date." << std::endl; -#endif - } -} - -void RsGxsNetService::handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs) -{ - if(grs->request_type == RsNxsSyncGrpStatsItem::GROUP_INFO_TYPE_REQUEST) - { -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << "Received Grp update stats Request for group " << grs->grpId << " from friend " << grs->PeerId() << std::endl; -#endif - RsGxsGrpMetaTemporaryMap grpMetas; - grpMetas[grs->grpId] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMetas); - - const auto& grpMeta = grpMetas[grs->grpId]; - - if(grpMeta == NULL) - { -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << " Group is unknown. Not reponding." << std::endl; -#endif - return ; - } - - // check if we're subscribed or not - - if(! (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )) - { -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << " Group is not subscribed. Not reponding." << std::endl; -#endif - return ; - } - - // now count available messages - - GxsMsgReq reqIds; - reqIds[grs->grpId] = std::set(); - GxsMsgMetaResult result; - -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << " retrieving message information." << std::endl; -#endif - mDataStore->retrieveGxsMsgMetaData(reqIds, result); - - const auto& vec(result[grs->grpId]) ; - - if(vec.empty()) // that means we don't have any, or there isn't any, but since the default is always 0, no need to send. - return ; - - RsNxsSyncGrpStatsItem *grs_resp = new RsNxsSyncGrpStatsItem(mServType) ; - grs_resp->request_type = RsNxsSyncGrpStatsItem::GROUP_INFO_TYPE_RESPONSE ; - grs_resp->number_of_posts = vec.size(); - grs_resp->grpId = grs->grpId; - grs_resp->PeerId(grs->PeerId()) ; - - grs_resp->last_post_TS = grpMeta->mPublishTs ; // This is not zero, and necessarily older than any message in the group up to clock precision. - // This allows us to use 0 as "uninitialized" proof. If the group meta has been changed, this time - // will be more recent than some messages. This shouldn't be a problem, since this value can only - // be used to discard groups that are not used. - - for(uint32_t i=0;ilast_post_TS < vec[i]->mPublishTs) - grs_resp->last_post_TS = vec[i]->mPublishTs; - -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << " sending back statistics item with " << vec.size() << " elements." << std::endl; -#endif - - generic_sendItem(grs_resp) ; - } - else if(grs->request_type == RsNxsSyncGrpStatsItem::GROUP_INFO_TYPE_RESPONSE) - { -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(grs->PeerId(),grs->grpId) << "Received Grp update stats item from peer " << grs->PeerId() << " for group " << grs->grpId << ", reporting " << grs->number_of_posts << " posts." << std::endl; -#endif - RS_STACK_MUTEX(mNxsMutex) ; - - RsGxsGrpConfig& rec(locked_getGrpConfig(grs->grpId)) ; - - uint32_t old_count = rec.max_visible_count ; - uint32_t old_suppliers_count = rec.suppliers.ids.size() ; - - rec.suppliers.ids.insert(grs->PeerId()) ; - rec.max_visible_count = std::max(rec.max_visible_count,grs->number_of_posts) ; - rec.statistics_update_TS = time(NULL) ; - rec.last_group_modification_TS = grs->last_post_TS; - - if (old_count != rec.max_visible_count || old_suppliers_count != rec.suppliers.ids.size()) - mNewStatsToNotify.insert(grs->grpId) ; - } - else - std::cerr << "(EE) RsGxsNetService::handleRecvSyncGrpStatistics(): unknown item type " << grs->request_type << " found. This is a bug." << std::endl; -} - -// This function is useful when we need to force a new sync of messages from all friends when e.g. the delay for sync gets changed. -// Normally, when subscribing to a group (not needed when unsubscribing), we should also call this method. - -void RsGxsNetService::locked_resetClientTS(const RsGxsGroupId& grpId) -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(grpId) << "Resetting client TS for grp " << grpId << std::endl; -#endif - - for(ClientMsgMap::iterator it(mClientMsgUpdateMap.begin());it!=mClientMsgUpdateMap.end();++it) - it->second.msgUpdateInfos.erase(grpId) ; -} - -void RsGxsNetService::subscribeStatusChanged(const RsGxsGroupId& grpId,bool subscribed) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - if(!subscribed) - return ; - - // When we subscribe, we reset the time stamps, so that the entire group list - // gets requested once again, for a proper update. - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(grpId) << "Changing subscribe status for grp " << grpId << " to " << subscribed << ": reseting all server msg time stamps for this group, and server global TS." << std::endl; - std::map::iterator it = mServerMsgUpdateMap.find(grpId) ; -#endif - - RsGxsServerMsgUpdate& item(mServerMsgUpdateMap[grpId]) ; - - item.msgUpdateTS = time(NULL) ; - - // We also update mGrpServerUpdateItem so as to trigger a new grp list exchange with friends (friends will send their known ClientTS which - // will be lower than our own grpUpdateTS, triggering our sending of the new subscribed grp list. - - mGrpServerUpdate.grpUpdateTS = time(NULL) ; - - if(subscribed) - locked_resetClientTS(grpId) ; -} - -bool RsGxsNetService::fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const -{ - // first determine how many fragments - uint32_t msgSize = msg.msg.TlvSize(); - uint32_t dataLeft = msgSize; - uint8_t nFragments = ceil(float(msgSize)/FRAGMENT_SIZE); - - RsTemporaryMemory buffer(FRAGMENT_SIZE); - int currPos = 0; - - - for(uint8_t i=0; i < nFragments; ++i) - { - RsNxsMsg* msgFrag = new RsNxsMsg(mServType); - msgFrag->grpId = msg.grpId; - msgFrag->msgId = msg.msgId; - msgFrag->meta = msg.meta; - msgFrag->transactionNumber = msg.transactionNumber; - msgFrag->pos = i; - msgFrag->PeerId(msg.PeerId()); - msgFrag->count = nFragments; - uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE); - - memcpy(buffer, ((char*)msg.msg.bin_data) + currPos, fragSize); - msgFrag->msg.setBinData(buffer, fragSize); - - currPos += fragSize; - dataLeft -= fragSize; - msgFragments.push_back(msgFrag); - } - - return true; -} - -bool RsGxsNetService::fragmentGrp(RsNxsGrp& grp, GrpFragments& grpFragments) const -{ - // first determine how many fragments - uint32_t grpSize = grp.grp.TlvSize(); - uint32_t dataLeft = grpSize; - uint8_t nFragments = ceil(float(grpSize)/FRAGMENT_SIZE); - char buffer[FRAGMENT_SIZE]; - int currPos = 0; - - - for(uint8_t i=0; i < nFragments; ++i) - { - RsNxsGrp* grpFrag = new RsNxsGrp(mServType); - grpFrag->grpId = grp.grpId; - grpFrag->meta = grp.meta; - grpFrag->pos = i; - grpFrag->count = nFragments; - uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE); - - memcpy(buffer, ((char*)grp.grp.bin_data) + currPos, fragSize); - grpFrag->grp.setBinData(buffer, fragSize); - - currPos += fragSize; - dataLeft -= fragSize; - grpFragments.push_back(grpFrag); - } - - return true; -} - -RsNxsMsg* RsGxsNetService::deFragmentMsg(MsgFragments& msgFragments) const -{ - if(msgFragments.empty()) return NULL; - - // if there is only one fragment with a count 1 or less then - // the fragment is the msg - if(msgFragments.size() == 1) - { - RsNxsMsg* m = msgFragments.front(); - - if(m->count > 1) // normally mcount should be exactly 1, but if not initialised (old versions) it's going to be 0 - { - // delete everything - std::cerr << "(WW) Cannot deFragment message set. m->count=" << m->count << ", but msgFragments.size()=" << msgFragments.size() << ". Incomplete? Dropping all." << std::endl; - - for(uint32_t i=0;imsg.bin_len; - - RsTemporaryMemory data(datSize) ; - - if(!data) - { - for(uint32_t i=0;imsg.bin_data, msg->msg.bin_len); - currPos += msg->msg.bin_len; - } - - RsNxsMsg* msg = new RsNxsMsg(mServType); - const RsNxsMsg& m = *(*(msgFragments.begin())); - msg->msg.setBinData(data, datSize); - msg->msgId = m.msgId; - msg->grpId = m.grpId; - msg->transactionNumber = m.transactionNumber; - msg->meta = m.meta; - - // now clean! - for(uint32_t i=0;igrp.bin_len; - - char* data = new char[datSize]; - uint32_t currPos = 0; - - for(mit = grpFragments.begin(); mit != grpFragments.end(); ++mit) - { - RsNxsGrp* grp = *mit; - memcpy(data + (currPos), grp->grp.bin_data, grp->grp.bin_len); - currPos += grp->grp.bin_len; - } - - RsNxsGrp* grp = new RsNxsGrp(mServType); - const RsNxsGrp& g = *(*(grpFragments.begin())); - grp->grp.setBinData(data, datSize); - grp->grpId = g.grpId; - grp->transactionNumber = g.transactionNumber; - grp->meta = g.meta; - - delete[] data; - - return grp; -} - -struct GrpFragCollate -{ - RsGxsGroupId mGrpId; - GrpFragCollate(const RsGxsGroupId& grpId) : mGrpId(grpId){ } - bool operator()(RsNxsGrp* grp) { return grp->grpId == mGrpId;} -}; - -void RsGxsNetService::locked_createTransactionFromPending( MsgRespPending* msgPend) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(msgPend->mPeerId) << "locked_createTransactionFromPending()" << std::endl; -#endif - MsgAuthorV::const_iterator cit = msgPend->mMsgAuthV.begin(); - std::list reqList; - uint32_t transN = locked_getTransactionId(); - for(; cit != msgPend->mMsgAuthV.end(); ++cit) - { - const MsgAuthEntry& entry = *cit; - - if(entry.mPassedVetting) - { - RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType); - msgItem->grpId = entry.mGrpId; - msgItem->msgId = entry.mMsgId; - msgItem->authorId = entry.mAuthorId; - msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; - msgItem->transactionNumber = transN; - msgItem->PeerId(msgPend->mPeerId); - reqList.push_back(msgItem); - } -#ifdef NXS_NET_DEBUG_1 - else - GXSNETDEBUG_PG(msgPend->mPeerId,entry.mGrpId) << " entry failed vetting: grpId=" << entry.mGrpId << ", msgId=" << entry.mMsgId << ", peerId=" << msgPend->mPeerId << std::endl; -#endif - } - - if(!reqList.empty()) - locked_pushMsgTransactionFromList(reqList, msgPend->mPeerId, transN) ; -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(msgPend->mPeerId) << " added " << reqList.size() << " items to transaction." << std::endl; -#endif -} - -void RsGxsNetService::locked_createTransactionFromPending(GrpRespPending* grpPend) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(grpPend->mPeerId) << "locked_createTransactionFromPending() from peer " << grpPend->mPeerId << std::endl; -#endif - GrpAuthorV::const_iterator cit = grpPend->mGrpAuthV.begin(); - std::list reqList; - uint32_t transN = locked_getTransactionId(); - for(; cit != grpPend->mGrpAuthV.end(); ++cit) - { - const GrpAuthEntry& entry = *cit; - - if(entry.mPassedVetting) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGrpId) << " entry Group Id: " << entry.mGrpId << " PASSED" << std::endl; -#endif - RsNxsSyncGrpItem* msgItem = new RsNxsSyncGrpItem(mServType); - msgItem->grpId = entry.mGrpId; - msgItem->authorId = entry.mAuthorId; - msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; - msgItem->transactionNumber = transN; - msgItem->PeerId(grpPend->mPeerId); - reqList.push_back(msgItem); - } -#ifdef NXS_NET_DEBUG_1 - else - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGrpId) << " entry failed vetting: grpId=" << entry.mGrpId << ", peerId=" << grpPend->mPeerId << std::endl; -#endif - } - - if(!reqList.empty()) - locked_pushGrpTransactionFromList(reqList, grpPend->mPeerId, transN); -} - - -bool RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(grpPend->mPeerId) << "locked_createTransactionFromPending(GrpCircleIdReq)" << std::endl; -#endif - std::vector::iterator cit = grpPend->mGrpCircleV.begin(); - uint32_t transN = locked_getTransactionId(); - std::list itemL; - for(; cit != grpPend->mGrpCircleV.end(); ++cit) - { - const GrpIdCircleVet& entry = *cit; - - if(entry.mCleared) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " Group Id: " << entry.mGroupId << " PASSED" << std::endl; -#endif - RsNxsSyncGrpItem* gItem = new RsNxsSyncGrpItem(mServType); - gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - gItem->grpId = entry.mGroupId; - gItem->publishTs = 0; - gItem->PeerId(grpPend->mPeerId); - gItem->transactionNumber = transN; - gItem->authorId = entry.mAuthorId; - // why it authorId not set here??? - - if(entry.mShouldEncrypt) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " item for this grpId should be encrypted." << std::endl; -#endif - RsNxsItem *encrypted_item = NULL ; - uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; - - if(encryptSingleNxsItem(gItem, entry.mCircleId, entry.mGroupId,encrypted_item,status)) - { - itemL.push_back(encrypted_item) ; - delete gItem ; - } -#ifdef NXS_NET_DEBUG_7 - else - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " Could not encrypt item for grpId " << entry.mGroupId << " for circle " << entry.mCircleId << ". Will try later. Adding to vetting list." << std::endl; -#endif - } - else - itemL.push_back(gItem); - } -#ifdef NXS_NET_DEBUG_1 - else - GXSNETDEBUG_PG(grpPend->mPeerId,entry.mGroupId) << " Group Id: " << entry.mGroupId << " FAILED" << std::endl; -#endif - } - - if(!itemL.empty()) - locked_pushGrpRespFromList(itemL, grpPend->mPeerId, transN); - - return true ; -} - -bool RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVetting* msgPend) -{ - std::vector::iterator vit = msgPend->mMsgs.begin(); - std::list itemL; - - uint32_t transN = locked_getTransactionId(); - RsGxsGroupId grp_id ; - - for(; vit != msgPend->mMsgs.end(); ++vit) - { - MsgIdCircleVet& mic = *vit; - RsNxsSyncMsgItem* mItem = new RsNxsSyncMsgItem(mServType); - mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - mItem->grpId = msgPend->mGrpId; - mItem->msgId = mic.mMsgId; - mItem->authorId = mic.mAuthorId; - mItem->PeerId(msgPend->mPeerId); - mItem->transactionNumber = transN; - - grp_id = msgPend->mGrpId ; - - if(msgPend->mShouldEncrypt) - { - RsNxsItem *encrypted_item = NULL ; - uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; - - if(encryptSingleNxsItem(mItem,msgPend->mCircleId,msgPend->mGrpId,encrypted_item,status)) - { - itemL.push_back(encrypted_item) ; - delete mItem ; - } - else - { - std::cerr << "(EE) cannot encrypt Msg ids in circle-restriced response to grp " << msgPend->mGrpId << " for circle " << msgPend->mCircleId << std::endl; - return false ; - } - } - else - itemL.push_back(mItem); - } - - if(!itemL.empty()) - locked_pushMsgRespFromList(itemL, msgPend->mPeerId,grp_id, transN); - - return true ; -} - -/*bool RsGxsNetService::locked_canReceive(const RsGxsGrpMetaData * const grpMeta - , const RsPeerId& peerId ) -{ - - double timeDelta = 0.2; - - if(grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) { - int i=0; - mCircles->loadCircle(grpMeta->mCircleId); - - // check 5 times at most - // spin for 1 second at most - while(i < 5) { - - if(mCircles->isLoaded(grpMeta->mCircleId)) { - const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); - return mCircles->canSend(grpMeta->mCircleId, pgpId); - }//if(mCircles->isLoaded(grpMeta->mCircleId)) - - usleep((int) (timeDelta * 1000 * 1000));// timeDelta sec - i++; - }//while(i < 5) - - } else {//if(grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) - return true; - }//else (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) - - return false; -}*/ - -void RsGxsNetService::collateGrpFragments(GrpFragments fragments, - std::map& partFragments) const -{ - // get all unique grpIds; - GrpFragments::iterator vit = fragments.begin(); - std::set grpIds; - - for(; vit != fragments.end(); ++vit) - grpIds.insert( (*vit)->grpId ); - - std::set::iterator sit = grpIds.begin(); - - for(; sit != grpIds.end(); ++sit) - { - const RsGxsGroupId& grpId = *sit; - GrpFragments::iterator bound = std::partition( - fragments.begin(), fragments.end(), - GrpFragCollate(grpId)); - - // something will always be found for a group id - for(vit = fragments.begin(); vit != bound; ) - { - partFragments[grpId].push_back(*vit); - vit = fragments.erase(vit); - } - - GrpFragments& f = partFragments[grpId]; - RsNxsGrp* grp = *(f.begin()); - - // if counts of fragments is incorrect remove - // from coalescion - if(grp->count != f.size()) - { - GrpFragments::iterator vit2 = f.begin(); - - for(; vit2 != f.end(); ++vit2) - delete *vit2; - - partFragments.erase(grpId); - } - } - - fragments.clear(); -} - -struct MsgFragCollate -{ - RsGxsMessageId mMsgId; - MsgFragCollate(const RsGxsMessageId& msgId) : mMsgId(msgId){ } - bool operator()(RsNxsMsg* msg) { return msg->msgId == mMsgId;} -}; - -void RsGxsNetService::collateMsgFragments(MsgFragments& fragments, std::map& partFragments) const -{ - // get all unique message Ids; - MsgFragments::iterator vit = fragments.begin(); - std::set msgIds; - - for(; vit != fragments.end(); ++vit) - msgIds.insert( (*vit)->msgId ); - - - std::set::iterator sit = msgIds.begin(); - - for(; sit != msgIds.end(); ++sit) - { - const RsGxsMessageId& msgId = *sit; - MsgFragments::iterator bound = std::partition( - fragments.begin(), fragments.end(), - MsgFragCollate(msgId)); - - // something will always be found for a group id - for(vit = fragments.begin(); vit != bound; ++vit ) - { - partFragments[msgId].push_back(*vit); - } - - fragments.erase(fragments.begin(), bound); - MsgFragments& f = partFragments[msgId]; - RsNxsMsg* msg = *(f.begin()); - - // if counts of fragments is incorrect remove - // from coalescion - if(msg->count != f.size()) - { - MsgFragments::iterator vit2 = f.begin(); - - for(; vit2 != f.end(); ++vit2) - delete *vit2; - - partFragments.erase(msgId); - } - } - - fragments.clear(); -} - -class StoreHere -{ -public: - - StoreHere(RsGxsNetService::ClientGrpMap& cgm, RsGxsNetService::ClientMsgMap& cmm, RsGxsNetService::ServerMsgMap& smm,RsGxsNetService::GrpConfigMap& gcm, RsGxsServerGrpUpdate& sgm) - : mClientGrpMap(cgm), mClientMsgMap(cmm), mServerMsgMap(smm), mGrpConfigMap(gcm), mServerGrpUpdate(sgm) - {} - - template void check_store(ID_type id,UpdateMap& map,ItemClass& item) - { - if(!id.isNull()) - map.insert(std::make_pair(id,item)) ; - else - std::cerr << "(EE) loaded a null ID for class type " << typeid(map).name() << std::endl; - } - - void operator() (RsItem* item) - { - RsGxsMsgUpdateItem *mui; - RsGxsGrpUpdateItem *gui; - RsGxsServerGrpUpdateItem *gsui; - RsGxsServerMsgUpdateItem *msui; - RsGxsGrpConfigItem *mgci; - - if((mui = dynamic_cast(item)) != NULL) - check_store(mui->peerID,mClientMsgMap,*mui); - else if((mgci = dynamic_cast(item)) != NULL) - check_store(mgci->grpId,mGrpConfigMap, *mgci); - else if((gui = dynamic_cast(item)) != NULL) - check_store(gui->peerID,mClientGrpMap, *gui); - else if((msui = dynamic_cast(item)) != NULL) - check_store(msui->grpId,mServerMsgMap, *msui); - else if((gsui = dynamic_cast(item)) != NULL) - mServerGrpUpdate = *gsui; - else - std::cerr << "Type not expected!" << std::endl; - - delete item ; - } - -private: - - RsGxsNetService::ClientGrpMap& mClientGrpMap; - RsGxsNetService::ClientMsgMap& mClientMsgMap; - RsGxsNetService::ServerMsgMap& mServerMsgMap; - RsGxsNetService::GrpConfigMap& mGrpConfigMap; - - RsGxsServerGrpUpdate& mServerGrpUpdate; -}; - -bool RsGxsNetService::loadList(std::list &load) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - // The delete is done in StoreHere, if necessary - - std::for_each(load.begin(), load.end(), StoreHere(mClientGrpUpdateMap, mClientMsgUpdateMap, mServerMsgUpdateMap, mServerGrpConfigMap, mGrpServerUpdate)); - rstime_t now = time(NULL); - - // We reset group statistics here. This is the best place since we know at this point which are all unsubscribed groups. - - for(GrpConfigMap::iterator it(mServerGrpConfigMap.begin());it!=mServerGrpConfigMap.end();++it) - { - // At each reload, we reset the count of visible messages. It will be rapidely restored to its real value from friends. - - it->second.max_visible_count = 0; // std::max(it2->second.message_count,gnsr.max_visible_count) ; - - // the update time stamp is randomised so as not to ask all friends at once about group statistics. - - it->second.statistics_update_TS = now - GROUP_STATS_UPDATE_DELAY + (RSRandom::random_u32()%(GROUP_STATS_UPDATE_DELAY/10)) ; - - // Similarly, we remove all suppliers. - // Actual suppliers will come back automatically. - - it->second.suppliers.ids.clear() ; - - // also make sure that values stored for keep and req delays correspond to the canonical values - - locked_checkDelay(it->second.msg_req_delay); - locked_checkDelay(it->second.msg_keep_delay); - } - - return true; -} - -void RsGxsNetService::locked_checkDelay(uint32_t& time_in_secs) -{ - if(time_in_secs < 1 * 86400) { time_in_secs = 0 ; return ; } - if(time_in_secs <= 10 * 86400) { time_in_secs = 5 * 86400; return ; } - if(time_in_secs <= 20 * 86400) { time_in_secs = 15 * 86400; return ; } - if(time_in_secs <= 60 * 86400) { time_in_secs = 30 * 86400; return ; } - if(time_in_secs <= 120 * 86400) { time_in_secs = 90 * 86400; return ; } - if(time_in_secs <= 250 * 86400) { time_in_secs = 180 * 86400; return ; } - time_in_secs = 365 * 86400; -} - -#include - -template -struct get_second : public std::unary_function -{ - get_second(uint16_t serv_type,typename UpdateMap::key_type ItemClass::*member): mServType(serv_type),ID_member(member) {} - - RsItem* operator()(const typename UpdateMap::value_type& value) const - { - ItemClass *item = new ItemClass(value.second,mServType); - (*item).*ID_member = value.first ; - return item ; - } - - uint16_t mServType ; - typename UpdateMap::key_type ItemClass::*ID_member ; -}; - - -bool RsGxsNetService::saveList(bool& cleanup, std::list& save) -{ - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_0 - std::cerr << "RsGxsNetService::saveList()..." << std::endl; -#endif - - // hardcore templates - std::transform(mClientGrpUpdateMap.begin(), mClientGrpUpdateMap.end(), std::back_inserter(save), get_second(mServType,&RsGxsGrpUpdateItem::peerID)); - std::transform(mClientMsgUpdateMap.begin(), mClientMsgUpdateMap.end(), std::back_inserter(save), get_second(mServType,&RsGxsMsgUpdateItem::peerID)); - std::transform(mServerMsgUpdateMap.begin(), mServerMsgUpdateMap.end(), std::back_inserter(save), get_second(mServType,&RsGxsServerMsgUpdateItem::grpId)); - std::transform(mServerGrpConfigMap.begin(), mServerGrpConfigMap.end(), std::back_inserter(save), get_second(mServType,&RsGxsGrpConfigItem::grpId)); - - RsGxsServerGrpUpdateItem *it = new RsGxsServerGrpUpdateItem(mGrpServerUpdate,mServType) ; - - save.push_back(it); - - cleanup = true; - return true; -} - -RsSerialiser *RsGxsNetService::setupSerialiser() -{ - - RsSerialiser *rss = new RsSerialiser; - rss->addSerialType(new RsGxsUpdateSerialiser(mServType)); - - return rss; -} - -RsItem *RsGxsNetService::generic_recvItem() -{ - { - RsItem *item ; - - if(NULL != (item=recvItem())) - return item ; - } - - unsigned char *data = NULL ; - uint32_t size = 0 ; - RsGxsNetTunnelVirtualPeerId virtual_peer_id ; - - while(mAllowDistSync && mGxsNetTunnel!=NULL && mGxsNetTunnel->receiveTunnelData(mServType,data,size,virtual_peer_id)) - { - RsNxsItem *item = dynamic_cast(RsNxsSerialiser(mServType).deserialise(data,&size)) ; - item->PeerId(virtual_peer_id) ; - - free(data) ; - - if(!item) - continue ; - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG_P_(item->PeerId()) << "Received RsGxsNetTunnelService Item:" << (void*)item << " of type: " << std::hex << item->PacketId() << std::dec - << " transaction " << item->transactionNumber << " from virtual peer " << item->PeerId() << std::endl ; -#endif - return item ; - } - - return NULL ; -} - -void RsGxsNetService::recvNxsItemQueue() -{ - RsItem *item ; - - while(NULL != (item=generic_recvItem())) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << "Received RsGxsNetService Item:" << (void*)item << " type=" << std::hex << item->PacketId() << std::dec << std::endl ; -#endif - // RsNxsItem needs dynamic_cast, since they have derived siblings. - // - RsNxsItem *ni = dynamic_cast(item) ; - if(ni != NULL) - { - // a live transaction has a non zero value - if(ni->transactionNumber != 0) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << " recvNxsItemQueue() handlingTransaction, transN " << ni->transactionNumber << std::endl; -#endif - - if(!handleTransaction(ni)) - delete ni; - - continue; - } - - // Check whether the item is encrypted. If so, try to decrypt it, and replace ni with the decrypted item.. - - bool item_was_encrypted = false ; - - if(ni->PacketSubType() == RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM) - { - RsNxsItem *decrypted_item ; - - if(decryptSingleNxsItem(dynamic_cast(ni),decrypted_item)) - { - item = ni = decrypted_item ; - item_was_encrypted = true ; -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(item->PeerId()) << " decrypted item " << std::endl; -#endif - } -#ifdef NXS_NET_DEBUG_7 - else - GXSNETDEBUG_P_(item->PeerId()) << " (EE) Could not decrypt incoming encrypted NXS item. Probably a friend subscribed to a circle-restricted group." << std::endl; -#endif - } - - switch(ni->PacketSubType()) - { - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM: handleRecvSyncGrpStatistics (dynamic_cast(ni)) ; break ; - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM: handleRecvSyncGroup (dynamic_cast(ni)) ; break ; - case RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM: handleRecvSyncMessage (dynamic_cast(ni),item_was_encrypted) ; break ; - case RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM:handleRecvPublishKeys (dynamic_cast(ni)) ; break ; - - default: - if(ni->PacketSubType() != RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM) - { - std::cerr << "Unhandled item subtype " << (uint32_t) ni->PacketSubType() << " in RsGxsNetService: " << std::endl ; break ; - } - } - delete item ; - } - else - { - std::cerr << "Not a RsNxsItem, deleting!" << std::endl; - delete(item); - } - } -} - - -bool RsGxsNetService::handleTransaction(RsNxsItem* item) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << "handleTransaction(RsNxsItem) number=" << item->transactionNumber << std::endl; -#endif - - /*! - * This attempts to handle a transaction - * It first checks if this transaction id already exists - * If it does then check this not a initiating transactions - */ - - RS_STACK_MUTEX(mNxsMutex) ; - - const RsPeerId& peer = item->PeerId(); - - RsNxsTransacItem* transItem = dynamic_cast(item); - - // if this is a RsNxsTransac item process - if(transItem) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << " this is a RsNxsTransac item. callign process." << std::endl; -#endif - return locked_processTransac(transItem); - } - - - // then this must be transaction content to be consumed - // first check peer exist for transaction - bool peerTransExists = mTransactions.find(peer) != mTransactions.end(); - - // then check transaction exists - - NxsTransaction* tr = NULL; - uint32_t transN = item->transactionNumber; - - if(peerTransExists) - { - TransactionIdMap& transMap = mTransactions[peer]; - - if(transMap.find(transN) != transMap.end()) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << " Consuming Transaction content, transN: " << item->transactionNumber << std::endl; - GXSNETDEBUG_P_(item->PeerId()) << " Consuming Transaction content, from Peer: " << item->PeerId() << std::endl; -#endif - - tr = transMap[transN]; - tr->mItems.push_back(item); - - return true; - } - } - - return false; -} - -bool RsGxsNetService::locked_processTransac(RsNxsTransacItem *item) -{ - - /*! - * To process the transaction item - * It can either be initiating a transaction - * or ending one that already exists - * - * For initiating an incoming transaction the peer - * and transaction item need not exists - * as the peer will be added and transaction number - * added thereafter - * - * For commencing/starting an outgoing transaction - * the transaction must exist already - * - * For ending a transaction the - */ - - RsPeerId peer; - - // for outgoing transaction use own id - if(item->transactFlag & (RsNxsTransacItem::FLAG_BEGIN_P2 | RsNxsTransacItem::FLAG_END_SUCCESS)) - peer = mOwnId; - else - peer = item->PeerId(); - - uint32_t transN = item->transactionNumber; - item->timestamp = time(NULL); // register time received - NxsTransaction* tr = NULL; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << "locked_processTransac() " << std::endl; - GXSNETDEBUG_P_(peer) << " Received transaction item: " << transN << std::endl; - GXSNETDEBUG_P_(peer) << " With peer: " << item->PeerId() << std::endl; - GXSNETDEBUG_P_(peer) << " trans type: " << item->transactFlag << std::endl; -#endif - - bool peerTrExists = mTransactions.find(peer) != mTransactions.end(); - bool transExists = false; - - if(peerTrExists) - { - TransactionIdMap& transMap = mTransactions[peer]; - // record whether transaction exists already - transExists = transMap.find(transN) != transMap.end(); - } - - // initiating an incoming transaction - if(item->transactFlag & RsNxsTransacItem::FLAG_BEGIN_P1) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " initiating Incoming transaction." << std::endl; -#endif - - if(transExists) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " transaction already exist! ERROR" << std::endl; -#endif - return false; // should not happen! - } - - // create a transaction if the peer does not exist - if(!peerTrExists) - mTransactions[peer] = TransactionIdMap(); - - TransactionIdMap& transMap = mTransactions[peer]; - - - // create new transaction - tr = new NxsTransaction(); - transMap[transN] = tr; - tr->mTransaction = item; - tr->mTimeOut = item->timestamp + mTransactionTimeOut; -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " Setting timeout of " << mTransactionTimeOut << " secs, which is " << tr->mTimeOut - time(NULL) << " secs from now." << std::endl; -#endif - - // note state as receiving, commencement item - // is sent on next run() loop - tr->mFlag = NxsTransaction::FLAG_STATE_STARTING; - return true; - // commencement item for outgoing transaction - } - else if(item->transactFlag & RsNxsTransacItem::FLAG_BEGIN_P2) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " initiating outgoign transaction." << std::endl; -#endif - // transaction must exist - if(!peerTrExists || !transExists) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " transaction does not exist. Cancelling!" << std::endl; -#endif - - return false; - } - - - // alter state so transaction content is sent on - // next run() loop - TransactionIdMap& transMap = mTransactions[mOwnId]; - NxsTransaction* tr = transMap[transN]; - tr->mFlag = NxsTransaction::FLAG_STATE_SENDING; - delete item; - return true; - // end transac item for outgoing transaction - } - else if(item->transactFlag & RsNxsTransacItem::FLAG_END_SUCCESS) - { - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " marking this transaction succeed" << std::endl; -#endif - // transaction does not exist - if(!peerTrExists || !transExists) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " transaction does not exist. Cancelling!" << std::endl; -#endif - return false; - } - - // alter state so that transaction is removed - // on next run() loop - TransactionIdMap& transMap = mTransactions[mOwnId]; - NxsTransaction* tr = transMap[transN]; - tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED; - delete item; - return true; - } - else - return false; -} - -void RsGxsNetService::threadTick() -{ - static const double timeDelta = 0.5; - - //Start waiting as nothing to do in runup - rstime::rs_usleep((int) (timeDelta * 1000 * 1000)); // timeDelta sec - - if(mUpdateCounter >= 120) // 60 seconds - { - updateServerSyncTS(); -#ifdef TO_REMOVE - updateClientSyncTS(); -#endif - mUpdateCounter = 1; - } - else - mUpdateCounter++; - - if(mUpdateCounter % 20 == 0) // dump the full shit every 20 secs - debugDump() ; - - // process active transactions - processTransactions(); - - // process completed transactions - processCompletedTransactions(); - - // vetting of id and circle info - runVetting(); - - processExplicitGroupRequests(); -} - -void RsGxsNetService::debugDump() -{ -#ifdef NXS_NET_DEBUG_0 - RS_STACK_MUTEX(mNxsMutex) ; - //rstime_t now = time(NULL) ; - - GXSNETDEBUG___<< "RsGxsNetService::debugDump():" << std::endl; - - RsGxsGrpMetaTemporaryMap grpMetas; - - if(!group_id_to_print.isNull()) - grpMetas[group_id_to_print] = NULL ; - - mDataStore->retrieveGxsGrpMetaData(grpMetas); - - GXSNETDEBUG___<< " mGrpServerUpdateItem time stamp: " << nice_time_stamp(time(NULL) , mGrpServerUpdate.grpUpdateTS) << " (is the last local modification time over all groups of this service)" << std::endl; - - GXSNETDEBUG___<< " mServerMsgUpdateMap: (is for each subscribed group, the last local modification time)" << std::endl; - - for(ServerMsgMap::const_iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it) - { - RsGxsGrpMetaTemporaryMap::const_iterator it2 = grpMetas.find(it->first) ; - auto grpMeta = (it2 != grpMetas.end())? it2->second : (std::shared_ptr()) ; - std::string subscribe_string = (grpMeta==NULL)?"Unknown" : ((grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)?" Subscribed":" NOT Subscribed") ; - - GXSNETDEBUG__G(it->first) << " Grp:" << it->first << " last local modification (secs ago): " << nice_time_stamp(time(NULL),it->second.msgUpdateTS) << ", " << subscribe_string << std::endl; - } - - GXSNETDEBUG___<< " mClientGrpUpdateMap: (is for each friend, last modif time of group meta data at that friend, all groups included, sent by the friend himself)" << std::endl; - - for(std::map::const_iterator it(mClientGrpUpdateMap.begin());it!=mClientGrpUpdateMap.end();++it) - GXSNETDEBUG_P_(it->first) << " From peer: " << it->first << " - last updated at peer (secs ago): " << nice_time_stamp(time(NULL),it->second.grpUpdateTS) << std::endl; - - GXSNETDEBUG___<< " mClientMsgUpdateMap: (is for each friend, the modif time for each group (e.g. last message received), sent by the friend himself)" << std::endl; - - for(std::map::const_iterator it(mClientMsgUpdateMap.begin());it!=mClientMsgUpdateMap.end();++it) - { - GXSNETDEBUG_P_(it->first) << " From peer: " << it->first << std::endl; - - for(std::map::const_iterator it2(it->second.msgUpdateInfos.begin());it2!=it->second.msgUpdateInfos.end();++it2) - GXSNETDEBUG_PG(it->first,it2->first) << " group " << it2->first << " - last updated at peer (secs ago): " << nice_time_stamp(time(NULL),it2->second.time_stamp) << ". Message count=" << it2->second.message_count << std::endl; - } - - GXSNETDEBUG___<< " List of rejected message ids: " << std::dec << mRejectedMessages.size() << std::endl; -#endif -} - -#ifdef TO_REMOVE -// This method is normally not needed, but we use it to correct possible inconsistencies in the updte time stamps -// on the client side. - -void RsGxsNetService::updateClientSyncTS() -{ - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___<< "updateClientSyncTS(): checking last modification time stamps of local data w.r.t. client's modification times" << std::endl; -#endif - - if(mGrpServerUpdateItem == NULL) - mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType); - - for(ClientGrpMap::iterator it = mClientGrpUpdateMap.begin();it!=mClientGrpUpdateMap.end();++it) - if(it->second->grpUpdateTS > SECURITY_DELAY_TO_FORCE_CLIENT_REUPDATE + mGrpServerUpdateItem->grpUpdateTS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(it->first) << " last global client GRP modification time known for peer (" << nice_time_stamp(time(NULL),it->second->grpUpdateTS) << " is quite more recent than our own server modification time (" << nice_time_stamp(time(NULL),mGrpServerUpdateItem->grpUpdateTS) << ". Forcing update! " << std::endl; -#endif - it->second->grpUpdateTS = 0 ; - } - - for(ClientMsgMap::iterator it = mClientMsgUpdateMap.begin();it!=mClientMsgUpdateMap.end();++it) - for(std::map::iterator it2 = it->second->msgUpdateInfos.begin();it2!=it->second->msgUpdateInfos.end();++it2) - { - std::map::const_iterator mmit = mServerMsgUpdateMap.find(it2->first) ; - - if(mmit != mServerMsgUpdateMap.end() && it2->second.time_stamp > SECURITY_DELAY_TO_FORCE_CLIENT_REUPDATE + mmit->second->msgUpdateTS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(it->first,it2->first) << " last group msg modification time known for peer (" << nice_time_stamp(time(NULL),it2->second.time_stamp) << " and group " << it2->first << " is quite more recent than our own server modification time (" << nice_time_stamp(time(NULL),mmit->second->msgUpdateTS) << ". Forcing update! " << std::endl; -#endif - it2->second.time_stamp = 0 ; - } - } -} -#endif - -void RsGxsNetService::updateServerSyncTS() -{ - RsGxsGrpMetaTemporaryMap gxsMap; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___<< "updateServerSyncTS(): updating last modification time stamp of local data." << std::endl; -#endif - - { - RS_STACK_MUTEX(mNxsMutex) ; - // retrieve all grps and update TS - mDataStore->retrieveGxsGrpMetaData(gxsMap); - - // (cyril) This code was previously removed because it sounded inconsistent: the list of grps normally does not need to be updated when - // new posts arrive. The two (grp list and msg list) are handled independently. Still, when group meta data updates are received, - // the server TS needs to be updated, because it is the only way to propagate the changes. So we update it to the publish time stamp, - // if needed. - - // as a grp list server also note this is the latest item you have - // then remove from mServerMsgUpdateMap, all items that are not in the group list! - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << " cleaning server map of groups with no data:" << std::endl; -#endif - - for(ServerMsgMap::iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();) - if(gxsMap.find(it->first) == gxsMap.end()) - { - // not found! Removing server update info for this group - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(it->first) << " removing server update info for group " << it->first << std::endl; -#endif - ServerMsgMap::iterator tmp(it) ; - ++tmp ; - mServerMsgUpdateMap.erase(it) ; - it = tmp ; - } - else - ++it; - } - -#ifdef NXS_NET_DEBUG_0 - if(gxsMap.empty()) - GXSNETDEBUG___<< " database seems to be empty. The modification timestamp will be reset." << std::endl; -#endif - // finally, update timestamps. - bool change = false; - - for(auto mit = gxsMap.begin();mit != gxsMap.end(); ++mit) - { - // Check if the group is subscribed and restricted to a circle. If the circle has changed, update the - // global TS to reflect that change to clients who may be able to see/subscribe to that particular group. - - if( (mit->second->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) && !mit->second->mCircleId.isNull()) - { - // ask to the GxsNetService of circles what the server TS is for that circle. If more recent, we update the serverTS of the - // local group - - rstime_t circle_group_server_ts ; - rstime_t circle_msg_server_ts ; - - // This call needs to be off-mutex, because of self-restricted circles. - // Normally we should update as a function of MsgServerUpdateTS and the mRecvTS of the circle, not the global grpServerTS. - // But grpServerTS is easier to get since it does not require a db access. So we trade the real call for this cheap and conservative call. - - if(mCircles->getLocalCircleServerUpdateTS(mit->second->mCircleId,circle_group_server_ts,circle_msg_server_ts)) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(mit->first) << " Group " << mit->first << " is conditionned to circle " << mit->second->mCircleId << ". local Grp TS=" << time(NULL) - mGrpServerUpdate.grpUpdateTS << " secs ago, circle grp server update TS=" << time(NULL) - circle_group_server_ts << " secs ago"; -#endif - // We use a max here between grp and msg TS because membership is driven by invite list (grp data) crossed with - // membership requests messages (msg data). - - auto circle_membership_ts = std::max(circle_group_server_ts,circle_msg_server_ts); - - if(circle_membership_ts > mGrpServerUpdate.grpUpdateTS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(mit->first) << " - Updating local Grp Server update TS to follow changes in circles." << std::endl; -#endif - - RS_STACK_MUTEX(mNxsMutex) ; - mGrpServerUpdate.grpUpdateTS = circle_membership_ts ; - } -#ifdef NXS_NET_DEBUG_0 - else - GXSNETDEBUG__G(mit->first) << " - Nothing to do." << std::endl; -#endif - } - else - std::cerr << "(EE) Cannot retrieve attached circle TS" << std::endl; - } - - RS_STACK_MUTEX(mNxsMutex) ; - - const auto& grpMeta = mit->second; -#ifdef TO_REMOVE - // That accounts for modification of the meta data. - - if(mGrpServerUpdateItem->grpUpdateTS < grpMeta->mPublishTs) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(grpId) << " publish time stamp of group " << grpId << " has changed to " << time(NULL)-grpMeta->mPublishTs << " secs ago. updating!" << std::endl; -#endif - mGrpServerUpdateItem->grpUpdateTS = grpMeta->mPublishTs; - } -#endif - - // I keep the creation, but the data is not used yet. -#warning csoler 2016-12-12: Disabled this, but do we need it? - // RsGxsServerMsgUpdate& msui(mServerMsgUpdateMap[grpId]) ; - - // (cyril) I'm removing this, because the msgUpdateTS is updated when new messages are received by calling locked_stampMsgServerUpdateTS(). - // mLastPost is actually updated somewhere when loading group meta data. It's not clear yet whether it is set to the latest publish time (wrong) - // or the latest receive time (right). The former would cause problems because it would need to compare times coming from different (potentially async-ed) - // machines. - // - // if(grpMeta->mLastPost > msui->msgUpdateTS ) - // { - // change = true; - // msui->msgUpdateTS = grpMeta->mLastPost; -#ifdef NXS_NET_DEBUG_0 - // GXSNETDEBUG__G(grpId) << " updated msgUpdateTS to last post = " << time(NULL) - grpMeta->mLastPost << " secs ago for group "<< grpId << std::endl; -#endif - // } - - // This is needed for group metadata updates to actually propagate: only a new grpUpdateTS will trigger the exchange of groups mPublishTs which - // will then be compared and pssibly trigger a MetaData transmission. mRecvTS is upated when creating, receiving for the first time, or receiving - // an update, all in rsgenexchange.cc, after group/update validation. It is therefore a local TS, that can be compared to grpUpdateTS (same machine). - - if(mGrpServerUpdate.grpUpdateTS < grpMeta->mRecvTS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(grpMeta->mGroupId) << " updated msgUpdateTS to last RecvTS = " << time(NULL) - grpMeta->mRecvTS << " secs ago for group "<< grpMeta->mGroupId << ". This is probably because an update has been received." << std::endl; -#endif - mGrpServerUpdate.grpUpdateTS = grpMeta->mRecvTS; - change = true; - } - } - - // actual change in config settings, then save configuration - if(change) - IndicateConfigChanged(); -} - -bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) -{ - return tr->mTimeOut < ((uint32_t) time(NULL)); -} - -void RsGxsNetService::processTransactions() -{ - RS_STACK_MUTEX(mNxsMutex) ; - - for(TransactionsPeerMap::iterator mit = mTransactions.begin();mit != mTransactions.end(); ++mit) - { -#ifdef NXS_NET_DEBUG_1 - if(!mit->second.empty()) - GXSNETDEBUG_P_(mit->first) << "processTransactions from/to peer " << mit->first << std::endl; -#endif - - TransactionIdMap& transMap = mit->second; - TransactionIdMap::iterator mmit = transMap.begin(), mmit_end = transMap.end(); - - if(mmit == mmit_end) // no waiting transactions for this peer - continue ; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " peerId=" << mit->first << std::endl; -#endif - // transaction to be removed - std::list toRemove; - - /*! - * Transactions owned by peer - */ - if(mit->first == mOwnId) - { - for(; mmit != mmit_end; ++mmit) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " type: outgoing " << std::endl; - GXSNETDEBUG_P_(mit->first) << " transN = " << mmit->second->mTransaction->transactionNumber << std::endl; -#endif - NxsTransaction* tr = mmit->second; - uint16_t flag = tr->mFlag; - std::list::iterator lit, lit_end; - uint32_t transN = tr->mTransaction->transactionNumber; - - // first check transaction has not expired - if(locked_checkTransacTimedOut(tr)) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " timeout! " << std::endl; - GXSNETDEBUG_P_(mit->first) << std::dec ; - int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ; - GXSNETDEBUG_P_(mit->first) << " Outgoing Transaction has failed, tranN: " << transN << ", Peer: " << mit->first ; - GXSNETDEBUG_P_(mit->first) << ", age: " << total_transaction_time << ", nItems=" << tr->mTransaction->nItems << ". tr->mTimeOut = " << tr->mTimeOut << ", now = " << (uint32_t) time(NULL) << std::endl; -#endif - - tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; - toRemove.push_back(transN); - mComplTransactions.push_back(tr); - continue; - } -#ifdef NXS_NET_DEBUG_1 - else - GXSNETDEBUG_P_(mit->first) << " still on time." << std::endl; -#endif - - // send items requested - if(flag & NxsTransaction::FLAG_STATE_SENDING) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first)<< " Sending Transaction content, transN: " << transN << " with peer: " << tr->mTransaction->PeerId() << std::endl; -#endif - lit = tr->mItems.begin(); - lit_end = tr->mItems.end(); - - for(; lit != lit_end; ++lit){ - generic_sendItem(*lit); - } - - tr->mItems.clear(); // clear so they don't get deleted in trans cleaning - tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - - } - else if(flag & NxsTransaction::FLAG_STATE_WAITING_CONFIRM) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first)<< " Waiting confirm! returning." << std::endl; -#endif - continue; - - } - else if(flag & NxsTransaction::FLAG_STATE_COMPLETED) - { - -#ifdef NXS_NET_DEBUG_1 - int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ; - - GXSNETDEBUG_P_(mit->first)<< " Outgoing completed " << tr->mTransaction->nItems << " items transaction in " << total_transaction_time << " seconds." << std::endl; -#endif - // move to completed transactions - toRemove.push_back(transN); - mComplTransactions.push_back(tr); - }else{ - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first)<< " Unknown flag for active transaction, transN: " << transN << ", Peer: " << mit->first<< std::endl; -#endif - - toRemove.push_back(transN); - tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; - mComplTransactions.push_back(tr); - } - } - - }else{ - - /*! - * Essentially these are incoming transactions - * Several states are dealth with - * Receiving: waiting to receive items from peer's transaction - * and checking if all have been received - * Completed: remove transaction from active and tell peer - * involved in transaction - * Starting: this is a new transaction and need to teell peer - * involved in transaction - */ - - for(; mmit != mmit_end; ++mmit){ - - NxsTransaction* tr = mmit->second; - uint16_t flag = tr->mFlag; - uint32_t transN = tr->mTransaction->transactionNumber; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " type: incoming " << std::endl; - GXSNETDEBUG_P_(mit->first) << " transN = " << mmit->second->mTransaction->transactionNumber << std::endl; -#endif - // first check transaction has not expired - if(locked_checkTransacTimedOut(tr)) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " timeout!" << std::endl; - GXSNETDEBUG_P_(mit->first) << std::dec ; - int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ; - GXSNETDEBUG_P_(mit->first) << " Incoming Transaction has failed, tranN: " << transN << ", Peer: " << mit->first ; - GXSNETDEBUG_P_(mit->first) << ", age: " << total_transaction_time << ", nItems=" << tr->mTransaction->nItems << ". tr->mTimeOut = " << tr->mTimeOut << ", now = " << (uint32_t) time(NULL) << std::endl; -#endif - - tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; - toRemove.push_back(transN); - mComplTransactions.push_back(tr); - continue; - } - - if(flag & NxsTransaction::FLAG_STATE_RECEIVING) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " received " << tr->mItems.size() << " item over a total of " << tr->mTransaction->nItems << std::endl; -#endif - - // if the number it item received equal that indicated - // then transaction is marked as completed - // to be moved to complete transations - // check if done - if(tr->mItems.size() == tr->mTransaction->nItems) - { - tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED; -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " completed!" << std::endl; -#endif - } - - }else if(flag & NxsTransaction::FLAG_STATE_COMPLETED) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " transaction is completed!" << std::endl; - GXSNETDEBUG_P_(mit->first) << " sending success!" << std::endl; -#endif - - // send completion msg - RsNxsTransacItem* trans = new RsNxsTransacItem(mServType); - trans->clear(); - trans->transactFlag = RsNxsTransacItem::FLAG_END_SUCCESS; - trans->transactionNumber = transN; - trans->PeerId(tr->mTransaction->PeerId()); - generic_sendItem(trans); - - // move to completed transactions - - // Try to decrypt the items that need to be decrypted. This function returns true if the transaction is not encrypted. - - if(processTransactionForDecryption(tr)) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " successfully decrypted/processed transaction " << transN << ". Adding to completed list." << std::endl; -#endif - mComplTransactions.push_back(tr); - - // transaction processing done - // for this id, add to removal list - toRemove.push_back(mmit->first); -#ifdef NXS_NET_DEBUG_1 - int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ; - GXSNETDEBUG_P_(mit->first) << " incoming completed " << tr->mTransaction->nItems << " items transaction in " << total_transaction_time << " seconds." << std::endl; -#endif - } - else - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " no decryption occurred because of unloaded keys. Will retry later. TransN=" << transN << std::endl; -#endif - } - - - } - else if(flag & NxsTransaction::FLAG_STATE_STARTING) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " transaction is starting!" << std::endl; - GXSNETDEBUG_P_(mit->first) << " setting state to Receiving" << std::endl; -#endif - // send item to tell peer your are ready to start - RsNxsTransacItem* trans = new RsNxsTransacItem(mServType); - trans->clear(); - trans->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P2 | - (tr->mTransaction->transactFlag & RsNxsTransacItem::FLAG_TYPE_MASK); - trans->transactionNumber = transN; - trans->PeerId(tr->mTransaction->PeerId()); - generic_sendItem(trans); - tr->mFlag = NxsTransaction::FLAG_STATE_RECEIVING; - - } - else{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(mit->first) << " transaction is in unknown state. ERROR!" << std::endl; - GXSNETDEBUG_P_(mit->first) << " transaction FAILS!" << std::endl; -#endif - - std::cerr << " Unknown flag for active transaction, transN: " << transN << ", Peer: " << mit->first << std::endl; - toRemove.push_back(mmit->first); - mComplTransactions.push_back(tr); - tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; // flag as a failed transaction - } - } - } - - std::list::iterator lit = toRemove.begin(); - - for(; lit != toRemove.end(); ++lit) - { - transMap.erase(*lit); - } - - } -} - -bool RsGxsNetService::getGroupNetworkStats(const RsGxsGroupId& gid,RsGroupNetworkStats& stats) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - GrpConfigMap::const_iterator it ( mServerGrpConfigMap.find(gid) ); - - if(it == mServerGrpConfigMap.end()) - return false ; - - stats.mSuppliers = it->second.suppliers.ids.size(); - stats.mMaxVisibleCount = it->second.max_visible_count ; - stats.mAllowMsgSync = mAllowMsgSync ; - stats.mGrpAutoSync = mGrpAutoSync ; - stats.mLastGroupModificationTS = it->second.last_group_modification_TS ; - - return true ; -} - -void RsGxsNetService::processCompletedTransactions() -{ - RS_STACK_MUTEX(mNxsMutex) ; - /*! - * Depending on transaction we may have to respond to peer - * responsible for transaction - */ - while(mComplTransactions.size()>0) - { - - NxsTransaction* tr = mComplTransactions.front(); - - bool outgoing = tr->mTransaction->PeerId() == mOwnId; - - if(outgoing){ - locked_processCompletedOutgoingTrans(tr); - }else{ - locked_processCompletedIncomingTrans(tr); - } - - - delete tr; - mComplTransactions.pop_front(); - } -} - -void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr) -{ - uint16_t flag = tr->mTransaction->transactFlag; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "Processing complete Incoming transaction with " << tr->mTransaction->nItems << " items." << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " flags = " << flag << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " peerId= " << tr->mTransaction->PeerId() << std::endl; -#endif - if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " transaction has completed." << std::endl; -#endif - // for a completed list response transaction - // one needs generate requests from this - if(flag & RsNxsTransacItem::FLAG_TYPE_MSG_LIST_RESP) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = msg list response." << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " => generate msg request based on it." << std::endl; -#endif - // generate request based on a peers response - locked_genReqMsgTransaction(tr); - - }else if(flag & RsNxsTransacItem::FLAG_TYPE_GRP_LIST_RESP) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = grp list response." << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " => generate group transaction request based on it." << std::endl; -#endif - locked_genReqGrpTransaction(tr); - } - // you've finished receiving request information now gen - else if(flag & RsNxsTransacItem::FLAG_TYPE_MSG_LIST_REQ) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = msg list request." << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " => generate msg list based on it." << std::endl; -#endif - locked_genSendMsgsTransaction(tr); - } - else if(flag & RsNxsTransacItem::FLAG_TYPE_GRP_LIST_REQ) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = grp list request." << std::endl; - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " => generate grp list based on it." << std::endl; -#endif - locked_genSendGrpsTransaction(tr); - } - else if(flag & RsNxsTransacItem::FLAG_TYPE_GRPS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = groups." << std::endl; -#endif - std::vector grps; - - while(tr->mItems.size() != 0) - { - RsNxsGrp* grp = dynamic_cast(tr->mItems.front()); - - if(grp) - { - tr->mItems.pop_front(); - grps.push_back(grp); -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grp->grpId) << " adding new group " << grp->grpId << " to incoming list!" << std::endl; -#endif - } - else - std::cerr << " /!\\ item did not caste to grp" << std::endl; - } - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " ...and notifying observer " << std::endl; -#endif -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (tr->mTransaction->PeerId()) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - Received new groups meta data from peer " << tr->mTransaction->PeerId() << std::endl; - for(uint32_t i=0;imTransaction->PeerId(),grps[i]->grpId) ; -#endif - // notify listener of grps - for(uint32_t i=0;imTransaction->PeerId(); - uint32_t updateTS = tr->mTransaction->updateTS; - -#ifdef NXS_NET_DEBUG_0 - ClientGrpMap::iterator it = mClientGrpUpdateMap.find(peerFrom); -#endif - - RsGxsGrpUpdate& item(mClientGrpUpdateMap[peerFrom]) ; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " and updating mClientGrpUpdateMap for peer " << peerFrom << " of new time stamp " << nice_time_stamp(time(NULL),updateTS) << std::endl; -#endif - - item.grpUpdateTS = updateTS; - - IndicateConfigChanged(); - } - else if(flag & RsNxsTransacItem::FLAG_TYPE_MSGS) - { - - std::vector msgs; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " type = msgs." << std::endl; -#endif - RsGxsGroupId grpId; - //rstime_t now = time(NULL) ; - - while(tr->mItems.size() > 0) - { - RsNxsMsg* msg = dynamic_cast(tr->mItems.front()); - if(msg) - { - if(grpId.isNull()) - grpId = msg->grpId; - - tr->mItems.pop_front(); - - msgs.push_back(msg); -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " pushing grpId="<< msg->grpId << ", msgsId=" << msg->msgId << " to list of incoming messages" << std::endl; -#endif - } - else - std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg" << std::endl; - } - -//#warning We need here to queue all incoming items into a list where the vetting will be checked -//#warning in order to avoid someone without the proper rights to post in a group protected with an external circle - -#ifdef NXS_FRAG - // (cyril) This code does not work. Since we do not really need message fragmenting, I won't fix it. - - std::map collatedMsgs; - collateMsgFragments(msgs, collatedMsgs); // this destroys msgs whatsoever and recovers memory when needed - - msgs.clear(); - - std::map::iterator mit = collatedMsgs.begin(); - for(; mit != collatedMsgs.end(); ++mit) - { - MsgFragments& f = mit->second; - RsNxsMsg* msg = deFragmentMsg(f); - - if(msg) - msgs.push_back(msg); - } - collatedMsgs.clear(); -#endif -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " ...and notifying observer of " << msgs.size() << " new messages." << std::endl; -#endif -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_PG (tr->mTransaction->PeerId(),grpId) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - Received new messages from peer " << tr->mTransaction->PeerId() << " for group " << grpId << std::endl; - for(uint32_t i=0;imTransaction->PeerId(),grpId) << " " << msgs[i]->msgId << std::endl ; -#endif - // notify listener of msgs - for(uint32_t i=0;imTransaction, grpId); - - // also update server sync TS, since we need to send the new message list to friends for comparison - locked_stampMsgServerUpdateTS(grpId); - } - } - else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " transaction has failed. Wasting it." << std::endl; -#endif - // don't do anything transaction will simply be cleaned - } - return; -} - -void RsGxsNetService::locked_doMsgUpdateWork(const RsNxsTransacItem *nxsTrans, const RsGxsGroupId &grpId) -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(nxsTrans->PeerId(),grpId) << "updating MsgUpdate time stamps for peerId=" << nxsTrans->PeerId() << ", grpId=" << grpId << std::endl; -#endif - // firts check if peer exists - const RsPeerId& peerFrom = nxsTrans->PeerId(); - - if(peerFrom.isNull()) - { - std::cerr << "(EE) update from null peer!" << std::endl; - print_stacktrace() ; - } - - RsGxsMsgUpdate& mui(mClientMsgUpdateMap[peerFrom]) ; - - // now update the peer's entry for this grp id - - if(mPartialMsgUpdates[peerFrom].find(grpId) != mPartialMsgUpdates[peerFrom].end()) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(nxsTrans->PeerId(),grpId) << " this is a partial update. Not using new time stamp." << std::endl; -#endif - } - else - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(nxsTrans->PeerId(),grpId) << " this is a full update. Updating time stamp." << std::endl; -#endif - mui.msgUpdateInfos[grpId].time_stamp = nxsTrans->updateTS; - IndicateConfigChanged(); - } -} - -void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr) -{ - uint16_t flag = tr->mTransaction->transactFlag; - -#ifdef NXS_NET_DEBUG_0 - RsNxsTransacItem *nxsTrans = tr->mTransaction; - GXSNETDEBUG_P_(nxsTrans->PeerId()) << "locked_processCompletedOutgoingTrans(): tr->flags = " << flag << std::endl; -#endif - - if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED) - { - // for a completed list response transaction - // one needs generate requests from this - if(flag & RsNxsTransacItem::FLAG_TYPE_MSG_LIST_RESP) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " complete Sending Msg List Response, transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - }else if(flag & RsNxsTransacItem::FLAG_TYPE_GRP_LIST_RESP) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " complete Sending Grp Response, transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - } - // you've finished sending a request so don't do anything - else if( (flag & RsNxsTransacItem::FLAG_TYPE_MSG_LIST_REQ) || - (flag & RsNxsTransacItem::FLAG_TYPE_GRP_LIST_REQ) ) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " complete Sending Msg/Grp Request, transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - - }else if(flag & RsNxsTransacItem::FLAG_TYPE_GRPS) - { - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " complete Sending Grp Data, transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - - }else if(flag & RsNxsTransacItem::FLAG_TYPE_MSGS) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " complete Sending Msg Data, transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - } - }else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " Failed transaction! transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - }else{ - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(nxsTrans->PeerId())<< " Serious error unrecognised trans Flag! transN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - } -} - - -void RsGxsNetService::locked_pushMsgTransactionFromList(std::list& reqList, const RsPeerId& peerId, const uint32_t& transN) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peerId) << "locked_pushMsgTransactionFromList()" << std::endl; - GXSNETDEBUG_P_(peerId) << " nelems = " << reqList.size() << std::endl; - GXSNETDEBUG_P_(peerId) << " peerId = " << peerId << std::endl; - GXSNETDEBUG_P_(peerId) << " transN = " << transN << std::endl; -#endif -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (peerId) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending message request to peer " - << peerId << " for " << reqList.size() << " messages" << std::endl; -#endif - RsNxsTransacItem* transac = new RsNxsTransacItem(mServType); - transac->transactFlag = RsNxsTransacItem::FLAG_TYPE_MSG_LIST_REQ - | RsNxsTransacItem::FLAG_BEGIN_P1; - transac->timestamp = 0; - transac->nItems = reqList.size(); - transac->PeerId(peerId); - transac->transactionNumber = transN; - NxsTransaction* newTrans = new NxsTransaction(); - newTrans->mItems = reqList; - newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; - // create transaction copy with your id to indicate - // its an outgoing transaction - newTrans->mTransaction = new RsNxsTransacItem(*transac); - newTrans->mTransaction->PeerId(mOwnId); - - if (locked_addTransaction(newTrans)) - generic_sendItem(transac); - else - { - delete newTrans; - delete transac; - } - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peerId) << " Requested new transaction for " << reqList.size() << " items." << std::endl; -#endif -} - -void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) -{ - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG___ << "RsGxsNetService::genReqMsgTransaction()" << std::endl; -#endif - - // to create a transaction you need to know who you are transacting with - // then what msgs to request - // then add an active Transaction for request - - std::list msgItemL; - std::list::iterator lit = tr->mItems.begin(); - - // first get item list sent from transaction - for(; lit != tr->mItems.end(); ++lit) - { - RsNxsSyncMsgItem* item = dynamic_cast(*lit); - if(item) - { - msgItemL.push_back(item); - }else - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(item->PeerId()) << "RsGxsNetService::genReqMsgTransaction(): item failed cast to RsNxsSyncMsgItem* " << std::endl; -#endif - } - } -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " found " << msgItemL.size()<< " messages in this transaction." << std::endl; -#endif - - if(msgItemL.empty()) - return; - - // get grp id for this transaction - RsNxsSyncMsgItem* item = msgItemL.front(); - const RsGxsGroupId& grpId = item->grpId; - - // store the count for the peer who sent the message list - uint32_t mcount = msgItemL.size() ; - RsPeerId pid = msgItemL.front()->PeerId() ; - - RsGxsGrpConfig& gnsr(locked_getGrpConfig(grpId)); - - std::set::size_type oldSuppliersCount = gnsr.suppliers.ids.size(); - uint32_t oldVisibleCount = gnsr.max_visible_count; - - gnsr.suppliers.ids.insert(pid) ; - gnsr.max_visible_count = std::max(gnsr.max_visible_count, mcount) ; - - if (oldVisibleCount != gnsr.max_visible_count || oldSuppliersCount != gnsr.suppliers.ids.size()) - mNewStatsToNotify.insert(grpId) ; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " grpId = " << grpId << std::endl; - GXSNETDEBUG_PG(item->PeerId(),grpId) << " retrieving grp mesta data..." << std::endl; -#endif - RsGxsGrpMetaTemporaryMap grpMetaMap; - grpMetaMap[grpId] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - const auto& grpMeta = grpMetaMap[grpId]; - - if(grpMeta == NULL) // this should not happen, but just in case... - { - std::cerr << "(EE) grpMeta is NULL in " << __PRETTY_FUNCTION__ << " line " << __LINE__ << ". This is very unexpected." << std::endl; - return ; - } - - if(! (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )) - { - // For unsubscribed groups, we update the timestamp something more recent, so that the group content will not be asked to the same - // peer again, unless the peer has new info about it. It's important to use the same clock (this is peer's clock) so that - // we never compare times from different (and potentially badly sync-ed clocks) - - std::cerr << "(EE) stepping in part of the code (" << __PRETTY_FUNCTION__ << ") where we shouldn't. This is a bug." << std::endl; - -#ifdef TO_REMOVE - locked_stampPeerGroupUpdateTime(pid,grpId,tr->mTransaction->updateTS,msgItemL.size()) ; -#endif - return ; - } - -#ifdef TO_REMOVE - int cutoff = 0; - if(grpMeta != NULL) - cutoff = grpMeta->mReputationCutOff; -#endif - - GxsMsgReq reqIds; - reqIds[grpId] = std::set(); - GxsMsgMetaResult result; - mDataStore->retrieveGxsMsgMetaData(reqIds, result); - auto& msgMetaV = result[grpId]; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " retrieving grp message list..." << std::endl; - GXSNETDEBUG_PG(item->PeerId(),grpId) << " grp locally contains " << msgMetaV.size() << " messsages." << std::endl; -#endif - std::set msgIdSet; - - // put ids in set for each searching - for(auto vit=msgMetaV.begin(); vit != msgMetaV.end(); ++vit) - msgIdSet.insert((*vit)->mMsgId); - - msgMetaV.clear(); - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " grp locally contains " << msgIdSet.size() << " unique messsages." << std::endl; -#endif - // get unique id for this transaction - uint32_t transN = locked_getTransactionId(); - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " new transaction ID: " << transN << std::endl; -#endif - // add msgs that you don't have to request list - std::list::iterator llit = msgItemL.begin(); - std::list reqList; - int reqListSize = 0 ; - - const RsPeerId peerFrom = tr->mTransaction->PeerId(); - - std::list peers; - peers.push_back(tr->mTransaction->PeerId()); - bool reqListSizeExceeded = false ; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " sorting items..." << std::endl; -#endif - for(; llit != msgItemL.end(); ++llit) - { - RsNxsSyncMsgItem*& syncItem = *llit; - const RsGxsMessageId& msgId = syncItem->msgId; - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " msg ID = " << msgId ; -#endif - if(reqListSize >= (int)MAX_REQLIST_SIZE) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ". reqlist too big. Pruning out this item for now." << std::endl; -#endif - reqListSizeExceeded = true ; - continue ; // we should actually break, but we need to print some debug info. - } - - if(reqListSize < (int)MAX_REQLIST_SIZE && msgIdSet.find(msgId) == msgIdSet.end()) - { - - bool noAuthor = syncItem->authorId.isNull(); - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ", reqlist size=" << reqListSize << ", message not present." ; -#endif - // grp meta must be present if author present - - if(!noAuthor && grpMeta == NULL) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ", no group meta found. Givign up." << std::endl; -#endif - continue; - } - - // The algorithm on request of message is: - // - // - always re-check for author ban level - // - if author is locally banned, do not download. - // - if author is not locally banned, download, whatever friends' opinion might be. - - if( mReputations->overallReputationLevel(syncItem->authorId) == - RsReputationLevel::LOCALLY_NEGATIVE ) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl; -#endif - continue ; - } - - if(mRejectedMessages.find(msgId) != mRejectedMessages.end()) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ", message has been recently rejected. Not requesting message!" << std::endl; -#endif - continue ; - } - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl; -#endif - RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType); - msgItem->grpId = grpId; - msgItem->msgId = msgId; - msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; - msgItem->transactionNumber = transN; - msgItem->PeerId(peerFrom); - reqList.push_back(msgItem); - ++reqListSize ; - } -#ifdef NXS_NET_DEBUG_1 - else - GXSNETDEBUG_PG(item->PeerId(),grpId) << ". already here." << std::endl; -#endif - } - - if(!reqList.empty()) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " Request list: " << reqList.size() << " elements." << std::endl; -#endif - locked_pushMsgTransactionFromList(reqList, tr->mTransaction->PeerId(), transN); - - if(reqListSizeExceeded) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " Marking update operation as unfinished." << std::endl; -#endif - mPartialMsgUpdates[tr->mTransaction->PeerId()].insert(item->grpId) ; - } - else - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " Marking update operation as terminal." << std::endl; -#endif - mPartialMsgUpdates[tr->mTransaction->PeerId()].erase(item->grpId) ; - } - } - else - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(item->PeerId(),grpId) << " Request list is empty. Not doing anything. " << std::endl; -#endif - // The list to req is empty. That means we already have all messages that this peer can - // provide. So we can stamp the group from this peer to be up to date. - - // Part of this is already achieved in two other places: - // - the GroupStats exchange system, which counts the messages at each peer. It could also supply TS for the messages, but it does not for the time being - // - client TS are updated when receiving messages - - locked_stampPeerGroupUpdateTime(pid,grpId,tr->mTransaction->updateTS,msgItemL.size()) ; - } -} - -void RsGxsNetService::locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,rstime_t tm,uint32_t n_messages) -{ - RsGxsMsgUpdate& up(mClientMsgUpdateMap[pid]); - - up.msgUpdateInfos[grpId].time_stamp = tm; - up.msgUpdateInfos[grpId].message_count = std::max(n_messages, up.msgUpdateInfos[grpId].message_count) ; - - IndicateConfigChanged(); -} - -void RsGxsNetService::locked_pushGrpTransactionFromList( std::list& reqList, const RsPeerId& peerId, const uint32_t& transN) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peerId) << "locked_pushGrpTransactionFromList()" << std::endl; - GXSNETDEBUG_P_(peerId) << " nelems = " << reqList.size() << std::endl; - GXSNETDEBUG_P_(peerId) << " peerId = " << peerId << std::endl; - GXSNETDEBUG_P_(peerId) << " transN = " << transN << std::endl; -#endif -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (peerId) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending group request to peer " - << peerId << " for " << reqList.size() << " groups" << std::endl; -#endif - RsNxsTransacItem* transac = new RsNxsTransacItem(mServType); - transac->transactFlag = RsNxsTransacItem::FLAG_TYPE_GRP_LIST_REQ - | RsNxsTransacItem::FLAG_BEGIN_P1; - transac->timestamp = 0; - transac->nItems = reqList.size(); - transac->PeerId(peerId); - transac->transactionNumber = transN; - NxsTransaction* newTrans = new NxsTransaction(); - newTrans->mItems = reqList; - newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - newTrans->mTimeOut = time(NULL) + mTransactionTimeOut; - newTrans->mTransaction = new RsNxsTransacItem(*transac); - newTrans->mTransaction->PeerId(mOwnId); - - if (locked_addTransaction(newTrans)) - generic_sendItem(transac); - else - { - delete newTrans; - delete transac; - } -} -void RsGxsNetService::addGroupItemToList(NxsTransaction*& tr, const RsGxsGroupId& grpId, uint32_t& transN, std::list& reqList) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << "RsGxsNetService::addGroupItemToList() Added GroupID: << grpId" << std::endl; -#endif - - RsNxsSyncGrpItem* grpItem = new RsNxsSyncGrpItem(mServType); - grpItem->PeerId(tr->mTransaction->PeerId()); - grpItem->grpId = grpId; - grpItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST; - grpItem->transactionNumber = transN; - reqList.push_back(grpItem); -} - -void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) -{ - // to create a transaction you need to know who you are transacting with - // then what grps to request - // then add an active Transaction for request - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "locked_genReqGrpTransaction(): " << std::endl; -#endif - - std::list grpItemL; - RsGxsGrpMetaTemporaryMap grpMetaMap; - - for(std::list::iterator lit = tr->mItems.begin(); lit != tr->mItems.end(); ++lit) - { - RsNxsSyncGrpItem* item = dynamic_cast(*lit); - if(item) - { - grpItemL.push_back(item); - grpMetaMap[item->grpId] = NULL; - } - else - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),item->grpId) << "RsGxsNetService::genReqGrpTransaction(): item failed to caste to RsNxsSyncMsgItem* " << std::endl; -#endif - } - } - - if (grpItemL.empty()) - { - // Normally the client grp updateTS is set after the transaction, but if no transaction is to happen, we have to set it here. - // Possible change: always do the update of the grpClientTS here. Needs to be tested... - - RsGxsGrpUpdate& item (mClientGrpUpdateMap[tr->mTransaction->PeerId()]); - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " reqList is empty, updating anyway ClientGrpUpdate TS for peer " << tr->mTransaction->PeerId() << " to: " << tr->mTransaction->updateTS << std::endl; -#endif - - if(item.grpUpdateTS != tr->mTransaction->updateTS) - { - item.grpUpdateTS = tr->mTransaction->updateTS; - IndicateConfigChanged(); - } - return; - } - - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - - // now do compare and add loop - std::list::iterator llit = grpItemL.begin(); - std::list reqList; - - uint32_t transN = locked_getTransactionId(); - - std::list peers; - peers.push_back(tr->mTransaction->PeerId()); - - for(; llit != grpItemL.end(); ++llit) - { - RsNxsSyncGrpItem*& grpSyncItem = *llit; - const RsGxsGroupId& grpId = grpSyncItem->grpId; - - auto metaIter = grpMetaMap.find(grpId); - bool haveItem = false; - bool latestVersion = false; - - if (metaIter != grpMetaMap.end() && metaIter->second) - { - haveItem = true; - latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs; - } - // FIXTESTS global variable rsReputations not available in unittests! - - if( mReputations->overallReputationLevel(RsGxsId(grpSyncItem->grpId)) == RsReputationLevel::LOCALLY_NEGATIVE ) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpSyncItem->grpId << " is banned. Not GXS-syncing group." << std::endl; -#endif - continue ; - } - - if( (mGrpAutoSync && !haveItem) || latestVersion) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Identity " << grpId << " will be sync-ed using GXS. mGrpAutoSync:" << mGrpAutoSync << " haveItem:" << haveItem << " latest_version: " << latestVersion << std::endl; -#endif - addGroupItemToList(tr, grpId, transN, reqList); - } - } - - if(!reqList.empty()) - locked_pushGrpTransactionFromList(reqList, tr->mTransaction->PeerId(), transN); - else - { - // Normally the client grp updateTS is set after the transaction, but if no transaction is to happen, we have to set it here. - // Possible change: always do the update of the grpClientTS here. Needs to be tested... - - RsGxsGrpUpdate& item (mClientGrpUpdateMap[tr->mTransaction->PeerId()]); - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " reqList is empty, updating anyway ClientGrpUpdate TS for peer " << tr->mTransaction->PeerId() << " to: " << tr->mTransaction->updateTS << std::endl; -#endif - - if(item.grpUpdateTS != tr->mTransaction->updateTS) - { - item.grpUpdateTS = tr->mTransaction->updateTS; - IndicateConfigChanged(); - } - } - -} - -void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr) -{ - -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "locked_genSendGrpsTransaction() Generating Grp data send from TransN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - - // go groups requested in transaction tr - - std::list::iterator lit = tr->mItems.begin(); - - t_RsGxsGenericDataTemporaryMap grps ; - - for(;lit != tr->mItems.end(); ++lit) - { - RsNxsSyncGrpItem* item = dynamic_cast(*lit); - if (item) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),item->grpId) << "locked_genSendGrpsTransaction() retrieving data for group \"" << item->grpId << "\"" << std::endl; -#endif - grps[item->grpId] = NULL; - } - else - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),item->grpId) << "RsGxsNetService::locked_genSendGrpsTransaction(): item failed to caste to RsNxsSyncGrpItem* " << std::endl; -#endif - } - } - - if(!grps.empty()) - mDataStore->retrieveNxsGrps(grps, false); - else - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "RsGxsNetService::locked_genSendGrpsTransaction(): no group to request! This is unexpected" << std::endl; -#endif - return; - } - - NxsTransaction* newTr = new NxsTransaction(); - newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - - uint32_t transN = locked_getTransactionId(); - - // store grp items to send in transaction - std::map::iterator mit = grps.begin(); - RsPeerId peerId = tr->mTransaction->PeerId(); - for(;mit != grps.end(); ++mit) - { -#warning csoler: Should make sure that no private key information is sneaked in here for the grp - mit->second->PeerId(peerId); // set so it gets sent to right peer - mit->second->transactionNumber = transN; - newTr->mItems.push_back(mit->second); - mit->second = NULL ; // avoids deletion -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),mit->first) << "RsGxsNetService::locked_genSendGrpsTransaction(): adding grp data of group \"" << mit->first << "\" to transaction" << std::endl; -#endif - } - - if(newTr->mItems.empty()){ - delete newTr; - return; - } - - uint32_t updateTS = 0; - updateTS = mGrpServerUpdate.grpUpdateTS; - -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (tr->mTransaction->PeerId()) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending global group TS " - << updateTS << " to peer " << tr->mTransaction->PeerId() << std::endl; -#endif - RsNxsTransacItem* ntr = new RsNxsTransacItem(mServType); - ntr->transactionNumber = transN; - ntr->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 | RsNxsTransacItem::FLAG_TYPE_GRPS; - ntr->updateTS = updateTS; - ntr->nItems = grps.size(); - ntr->PeerId(tr->mTransaction->PeerId()); - - newTr->mTransaction = new RsNxsTransacItem(*ntr); - newTr->mTransaction->PeerId(mOwnId); - newTr->mTimeOut = time(NULL) + mTransactionTimeOut; - - ntr->PeerId(tr->mTransaction->PeerId()); - - if(locked_addTransaction(newTr)) - generic_sendItem(ntr); - else - { - delete ntr ; - delete newTr; - } - - return; -} - -void RsGxsNetService::runVetting() -{ - // The vetting operation consists in transforming pending group/msg Id requests and grp/msg content requests - // into real transactions, based on the authorisations of the Peer Id these transactions are targeted to using the - // reputation system. - // - - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef TO_BE_REMOVED - // Author response vetting is disabled since not used, as the reputations are currently not async-ed anymore. - - std::vector::iterator vit = mPendingResp.begin(); - - for(; vit != mPendingResp.end(); ) - { - AuthorPending* ap = *vit; - - if(ap->accepted() || ap->expired()) - { - // add to transactions - if(AuthorPending::MSG_PEND == ap->getType()) - { - MsgRespPending* mrp = static_cast(ap); - locked_createTransactionFromPending(mrp); - } - else if(AuthorPending::GRP_PEND == ap->getType()) - { - GrpRespPending* grp = static_cast(ap); - locked_createTransactionFromPending(grp); - }else - std::cerr << "RsGxsNetService::runVetting(): Unknown pending type! Type: " << ap->getType() << std::endl; - - delete ap; - vit = mPendingResp.erase(vit); - } - else - { - ++vit; - } - - } -#endif - - - // now lets do circle vetting - std::vector::iterator vit2 = mPendingCircleVets.begin(); - for(; vit2 != mPendingCircleVets.end(); ) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG___ << " Examining/clearing pending vetting of type " << (*vit2)->getType() << std::endl; -#endif - GrpCircleVetting*& gcv = *vit2; - if(gcv->cleared() || gcv->expired()) - { - if(gcv->getType() == GrpCircleVetting::GRP_ID_PEND) - { - GrpCircleIdRequestVetting* gcirv = static_cast(gcv); -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_P_(gcirv->mPeerId) << " vetting is a GRP ID PENDING Response" << std::endl; -#endif - - if(!locked_createTransactionFromPending(gcirv)) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_P_(gcirv->mPeerId) << " Response sent!" << std::endl; -#endif - ++vit2 ; - continue ; - } - } - else if(gcv->getType() == GrpCircleVetting::MSG_ID_SEND_PEND) - { - MsgCircleIdsRequestVetting* mcirv = static_cast(gcv); - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_P_(mcirv->mPeerId) << " vetting is a MSG ID PENDING Response" << std::endl; -#endif - if(mcirv->cleared()) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_P_(mcirv->mPeerId) << " vetting cleared! Sending..." << std::endl; -#endif - if(!locked_createTransactionFromPending(mcirv)) - continue ; // keep it in the list for retry - } - } - else - { -#ifdef NXS_NET_DEBUG_4 - std::cerr << "RsGxsNetService::runVetting(): Unknown Circle pending type! Type: " << gcv->getType() << std::endl; -#endif - } - - delete gcv; - vit2 = mPendingCircleVets.erase(vit2); - } - else - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG___ << " ... not cleared yet." << std::endl; -#endif - ++vit2; - } - } -} - -void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr) -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << "locked_genSendMsgsTransaction() Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber << std::endl; -#endif - - // go groups requested in transaction tr - - std::list::iterator lit = tr->mItems.begin(); - - GxsMsgReq msgIds; - GxsMsgResult msgs; - - if(tr->mItems.empty()){ - return; - } - - // hacky assumes a transaction only consist of a single grpId - RsGxsGroupId grpId; - - for(;lit != tr->mItems.end(); ++lit) - { - RsNxsSyncMsgItem* item = dynamic_cast(*lit); - if (item) - { - msgIds[item->grpId].insert(item->msgId); - - if(grpId.isNull()) - grpId = item->grpId; - else if(grpId != item->grpId) - { - std::cerr << "RsGxsNetService::locked_genSendMsgsTransaction(): transaction on two different groups! ERROR!" << std::endl; - return ; - } - } - else - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << "RsGxsNetService::locked_genSendMsgsTransaction(): item failed to caste to RsNxsSyncMsgItem* " << std::endl; -#endif - } - } - -#ifdef CODE_TO_ENCRYPT_MESSAGE_DATA - // now if transaction is limited to an external group, encrypt it for members of the group. - - RsGxsCircleId encryption_circle ; - std::map grp; - grp[grpId] = NULL ; - - mDataStore->retrieveGxsGrpMetaData(grp); - - RsGxsGrpMetaData *grpMeta = grp[grpId] ; - - if(grpMeta == NULL) - { - std::cerr << "(EE) cannot retrieve group meta data for message transaction " << tr->mTransaction->transactionNumber << std::endl; - return ; - } - - encryption_circle = grpMeta->mCircleId ; - delete grpMeta ; - grp.clear() ; -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId) << " Msg transaction items will be encrypted for circle " << std::endl; -#endif -#endif - - mDataStore->retrieveNxsMsgs(msgIds, msgs, false); - - NxsTransaction* newTr = new NxsTransaction(); - newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - - uint32_t transN = locked_getTransactionId(); - - // store msg items to send in transaction - GxsMsgResult::iterator mit = msgs.begin(); - RsPeerId peerId = tr->mTransaction->PeerId(); - uint32_t msgSize = 0; - - for(;mit != msgs.end(); ++mit) - { - std::vector& msgV = mit->second; - std::vector::iterator vit = msgV.begin(); - - for(; vit != msgV.end(); ++vit) - { - RsNxsMsg* msg = *vit; - msg->PeerId(peerId); - msg->transactionNumber = transN; - - // Quick trick to clamp messages with an exceptionnally large size. Signature will fail on client side, and the message - // will be rejected. - - if(msg->msg.bin_len > MAX_ALLOWED_GXS_MESSAGE_SIZE) - { - std::cerr << "(WW) message with ID " << msg->msgId << " in group " << msg->grpId << " exceeds size limit of " << MAX_ALLOWED_GXS_MESSAGE_SIZE << " bytes. Actual size is " << msg->msg.bin_len << " bytes. Message will be truncated and rejected at client." << std::endl; - msg->msg.bin_len = 1 ; // arbitrary small size, but not 0. No need to send the data since it's going to be rejected. - } - -#ifdef NXS_FRAG - MsgFragments fragments; - fragmentMsg(*msg, fragments); - - delete msg ; - - MsgFragments::iterator mit = fragments.begin(); - - for(; mit != fragments.end(); ++mit) - { - newTr->mItems.push_back(*mit); - msgSize++; - } -#else - - msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future. - msg->pos = 0; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl; -#endif - - newTr->mItems.push_back(msg); - msgSize++; -#endif - -#ifdef CODE_TO_ENCRYPT_MESSAGE_DATA - // encrypt - - if(!encryption_circle.isNull()) - { - uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; - - RsNxsEncryptedDataItem encrypted_msg_item = NULL ; - - if(encryptSingleNxsItem(msg,encryption_circle,encrypted_msg_item,status)) - { - newTr->mItems.push_back(msg); - delete msg ; - } - else - { - } - } - else - { - newTr->mItems.push_back(msg); - - msgSize++; - } -#endif - } - } - - if(newTr->mItems.empty()){ - delete newTr; - return; - } - - // now send a transaction item and store the transaction data - - uint32_t updateTS = mServerMsgUpdateMap[grpId].msgUpdateTS; - - RsNxsTransacItem* ntr = new RsNxsTransacItem(mServType); - ntr->transactionNumber = transN; - ntr->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 | - RsNxsTransacItem::FLAG_TYPE_MSGS; - ntr->updateTS = updateTS; - ntr->nItems = msgSize; - ntr->PeerId(peerId); - - newTr->mTransaction = new RsNxsTransacItem(*ntr); - newTr->mTransaction->PeerId(mOwnId); - newTr->mTimeOut = time(NULL) + mTransactionTimeOut; - -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_PG (peerId,grpId) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending message update to peer " << peerId << " for group " << grpId << " with TS=" << nice_time_stamp(time(NULL),updateTS) <<" (secs ago)" << std::endl; - -#endif - ntr->PeerId(tr->mTransaction->PeerId()); - - if(locked_addTransaction(newTr)) - generic_sendItem(ntr); - else - { - delete ntr ; - delete newTr; - } - - return; -} -uint32_t RsGxsNetService::locked_getTransactionId() -{ - return ++mTransactionN; -} -bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr) -{ - const RsPeerId& peer = tr->mTransaction->PeerId(); -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << "locked_addTransaction() " << std::endl; -#endif - uint32_t transN = tr->mTransaction->transactionNumber; - TransactionIdMap& transMap = mTransactions[peer]; - bool transNumExist = transMap.find(transN) != transMap.end(); - - if(transNumExist) - { -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_P_(peer) << " Transaction number exist already, transN: " << transN << std::endl; -#endif - return false; - } - - transMap[transN] = tr; - - return true; -} - -// Turns a single RsNxsItem into an encrypted one, suitable for the supplied destination circle. -// Returns false when the keys are not loaded. Question to solve: what do we do if we miss some keys?? -// We should probably send anyway. - -bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, const RsGxsGroupId& destination_group, RsNxsItem *&encrypted_item, uint32_t& status) -{ - encrypted_item = NULL ; - status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_ (item->PeerId()) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - Encrypting single item for peer " << item->PeerId() << ", for circle ID " << destination_circle << std::endl; -#endif - // 1 - Find out the list of GXS ids to encrypt for - // We could do smarter things (like see if the peer_id owns one of the circle's identities - // but for now we aim at the simplest solution: encrypt for all identities in the circle. - - std::list recipients ; - - if(!mCircles->recipients(destination_circle,destination_group,recipients)) - { - std::cerr << " (EE) Cannot encrypt transaction: recipients list not available. Should re-try later." << std::endl; - status = RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR ; - return false ; - } - - if(recipients.empty()) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(item->PeerId()) << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl; -#endif - return false ; - } - -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_ (item->PeerId()) << " Dest Ids: " << std::endl; -#endif - std::vector recipient_keys ; - - for(std::list::const_iterator it(recipients.begin());it!=recipients.end();++it) - { - RsTlvPublicRSAKey pkey ; - - if(!mGixs->getKey(*it,pkey)) - { - std::cerr << " (EE) Cannot retrieve public key " << *it << " for circle encryption. Should retry later?" << std::endl; - - // we should probably request the key? - status = RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING ; - continue ; - } -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_ (item->PeerId()) << " added key " << *it << std::endl; -#endif - recipient_keys.push_back(pkey) ; - } - - // 2 - call GXSSecurity to make a header item that encrypts for the given list of peers. - -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_ (item->PeerId()) << " Encrypting..." << std::endl; -#endif - uint32_t size = RsNxsSerialiser(mServType).size(item) ; - RsTemporaryMemory tempmem( size ) ; - - if(!RsNxsSerialiser(mServType).serialise(item,tempmem,&size)) - { - std::cerr << " (EE) Cannot serialise item. Something went wrong." << std::endl; - status = RS_NXS_ITEM_ENCRYPTION_STATUS_SERIALISATION_ERROR ; - return false ; - } - - unsigned char *encrypted_data = NULL ; - uint32_t encrypted_len = 0 ; - - if(!GxsSecurity::encrypt(encrypted_data, encrypted_len,tempmem,size,recipient_keys)) - { - std::cerr << " (EE) Cannot multi-encrypt item. Something went wrong." << std::endl; - status = RS_NXS_ITEM_ENCRYPTION_STATUS_ENCRYPTION_ERROR ; - return false ; - } - - RsNxsEncryptedDataItem *enc_item = new RsNxsEncryptedDataItem(mServType) ; - - enc_item->encrypted_data.bin_len = encrypted_len ; - enc_item->encrypted_data.bin_data = encrypted_data ; - - // also copy all the important data. - - enc_item->transactionNumber = item->transactionNumber ; - enc_item->PeerId(item->PeerId()) ; - - encrypted_item = enc_item ; -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(item->PeerId()) << " encrypted item of size " << encrypted_len << std::endl; -#endif - status = RS_NXS_ITEM_ENCRYPTION_STATUS_NO_ERROR ; - - return true ; -} - -// Tries to decrypt the transaction. First load the keys and process all items. -// If keys are loaded, encrypted items that cannot be decrypted are discarded. -// Otherwise the transaction is untouched for retry later. - -bool RsGxsNetService::processTransactionForDecryption(NxsTransaction *tr) -{ -#ifdef NXS_NET_DEBUG_7 - RsPeerId peerId = tr->mTransaction->PeerId() ; - GXSNETDEBUG_P_(peerId) << "RsGxsNetService::decryptTransaction()" << std::endl; -#endif - - std::list decrypted_items ; - std::vector private_keys ; - - // get all private keys. Normally we should look into the circle name and only supply the keys that we have - - for(std::list::iterator it(tr->mItems.begin());it!=tr->mItems.end();) - { - RsNxsEncryptedDataItem *encrypted_item = dynamic_cast(*it) ; - - if(encrypted_item == NULL) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(peerId) << " skipping unencrypted item..." << std::endl; -#endif - ++it ; - continue ; - } - - // remove the encrypted item. After that it points to the next item to handle - it = tr->mItems.erase(it) ; - - RsNxsItem *nxsitem = NULL ; - - if(decryptSingleNxsItem(encrypted_item,nxsitem,&private_keys)) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(peerId) << " Replacing the encrypted item with the clear one." << std::endl; -#endif - tr->mItems.insert(it,nxsitem) ; // inserts before it, so no need to ++it - } - - delete encrypted_item ; - } - - return true ; -} - -bool RsGxsNetService::decryptSingleNxsItem(const RsNxsEncryptedDataItem *encrypted_item, RsNxsItem *& nxsitem,std::vector *pprivate_keys) -{ - // if private_keys storage is supplied use/update them, otherwise, find which key should be used, and store them in a local std::vector. - - nxsitem = NULL ; - std::vector local_keys ; - std::vector& private_keys = pprivate_keys?(*pprivate_keys):local_keys ; - - // we need the private keys to decrypt the item. First load them in! - bool key_loading_failed = false ; - - if(private_keys.empty()) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId()) << " need to retrieve private keys..." << std::endl; -#endif - - std::list own_keys ; - mGixs->getOwnIds(own_keys) ; - - for(std::list::const_iterator it(own_keys.begin());it!=own_keys.end();++it) - { - RsTlvPrivateRSAKey private_key ; - - if(mGixs->getPrivateKey(*it,private_key)) - { - private_keys.push_back(private_key) ; -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId())<< " retrieved private key " << *it << std::endl; -#endif - } - else - { - std::cerr << " (EE) Cannot retrieve private key for ID " << *it << std::endl; - key_loading_failed = true ; - break ; - } - } - } - if(key_loading_failed) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId()) << " Some keys not loaded.Returning false to retry later." << std::endl; -#endif - return false ; - } - - // we do this only when something actually needs to be decrypted. - - unsigned char *decrypted_mem = NULL; - uint32_t decrypted_len =0; - -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId())<< " Trying to decrypt item..." ; -#endif - - if(!GxsSecurity::decrypt(decrypted_mem,decrypted_len, (uint8_t*)encrypted_item->encrypted_data.bin_data,encrypted_item->encrypted_data.bin_len,private_keys)) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId()) << " Failed! Cannot decrypt this item." << std::endl; -#endif - decrypted_mem = NULL ; // for safety - return false ; - } -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_P_(encrypted_item->PeerId())<< " Succeeded! deserialising..." << std::endl; -#endif - - // deserialise the item - - RsItem *ditem = NULL ; - - if(decrypted_mem!=NULL) - { - ditem = RsNxsSerialiser(mServType).deserialise(decrypted_mem,&decrypted_len) ; - free(decrypted_mem) ; - - if(ditem != NULL) - { - ditem->PeerId(encrypted_item->PeerId()) ; // This is needed because the deserialised item has no peer id - nxsitem = dynamic_cast(ditem) ; - } - else - std::cerr << " Cannot deserialise. Item encoding error!" << std::endl; - - return (nxsitem != NULL) ; - } - return false ; -} - -void RsGxsNetService::cleanTransactionItems(NxsTransaction* tr) const -{ - std::list::iterator lit = tr->mItems.begin(); - - for(; lit != tr->mItems.end(); ++lit) - { - delete *lit; - } - - tr->mItems.clear(); -} - -void RsGxsNetService::locked_pushGrpRespFromList(std::list& respList, const RsPeerId& peer, const uint32_t& transN) -{ -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << "locked_pushGrpResponseFromList()" << std::endl; - GXSNETDEBUG_P_(peer) << " nelems = " << respList.size() << std::endl; - GXSNETDEBUG_P_(peer) << " peerId = " << peer << std::endl; - GXSNETDEBUG_P_(peer) << " transN = " << transN << std::endl; -#endif - NxsTransaction* tr = new NxsTransaction(); - tr->mItems = respList; - - tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - RsNxsTransacItem* trItem = new RsNxsTransacItem(mServType); - trItem->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 - | RsNxsTransacItem::FLAG_TYPE_GRP_LIST_RESP; - trItem->nItems = respList.size(); - trItem->timestamp = 0; - trItem->PeerId(peer); - trItem->transactionNumber = transN; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_ (peer) << "Setting tr->mTransaction->updateTS to " << mGrpServerUpdate.grpUpdateTS << std::endl; -#endif - trItem->updateTS = mGrpServerUpdate.grpUpdateTS; - - // also make a copy for the resident transaction - tr->mTransaction = new RsNxsTransacItem(*trItem); - tr->mTransaction->PeerId(mOwnId); - tr->mTimeOut = time(NULL) + mTransactionTimeOut; - // signal peer to prepare for transaction -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (peer) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending group response to peer " - << peer << " with " << respList.size() << " groups " << std::endl; -#endif - if(locked_addTransaction(tr)) - generic_sendItem(trItem); - else - { - delete tr ; - delete trItem ; - } -} - -bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item) -{ - // Do we have new updates for this peer? - // The received TS is in our own clock, but send to us by the friend. - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(item->PeerId()) << " local modification time stamp: " << std::dec<< time(NULL) - mGrpServerUpdate.grpUpdateTS << " secs ago. Update sent: " << - ((item->updateTS < mGrpServerUpdate.grpUpdateTS)?"YES":"NO") << std::endl; -#endif - return item->updateTS < mGrpServerUpdate.grpUpdateTS && locked_checkResendingOfUpdates(item->PeerId(),RsGxsGroupId(),item->updateTS,mGrpServerUpdate.grpUpdateTsRecords[item->PeerId()]) ; -} - -void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrpReqItem *item) -{ - if (!item) - return; - - RS_STACK_MUTEX(mNxsMutex) ; - - RsPeerId peer = item->PeerId(); -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << "HandleRecvSyncGroup(): Service: " << mServType << " from " << peer << ", Last update TS (from myself) sent from peer is T = " << std::dec<< time(NULL) - item->updateTS << " secs ago" << std::endl; -#endif - - if(!locked_CanReceiveUpdate(item)) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << " RsGxsNetService::handleRecvSyncGroup() update will not be sent." << std::endl; -#endif - return; - } - - RsGxsGrpMetaTemporaryMap grp; - mDataStore->retrieveGxsGrpMetaData(grp); - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << " RsGxsNetService::handleRecvSyncGroup() retrieving local list of groups..." << std::endl; -#endif - if(grp.empty()) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << " RsGxsNetService::handleRecvSyncGroup() Grp Empty" << std::endl; -#endif - return; - } - - std::list itemL; - - uint32_t transN = locked_getTransactionId(); - - std::vector toVet; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << " Group list beings being sent: " << std::endl; -#endif - - for(auto mit = grp.begin(); mit != grp.end(); ++mit) - { - const auto& grpMeta = mit->second; - - // Only send info about subscribed groups. - - if(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - { - - // check if you can send this id to peer - // or if you need to add to the holding - // pen for peer to be vetted - - bool should_encrypt = false ; - - if(canSendGrpId(peer, *grpMeta, toVet,should_encrypt)) - { - RsNxsSyncGrpItem* gItem = new RsNxsSyncGrpItem(mServType); - gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - gItem->grpId = mit->first; - gItem->publishTs = mit->second->mPublishTs; - gItem->authorId = grpMeta->mAuthorId; - gItem->PeerId(peer); - gItem->transactionNumber = transN; - - if(should_encrypt) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(peer,mit->first) << " item for this grpId should be encrypted." << std::endl; -#endif - RsNxsItem *encrypted_item = NULL ; - uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; - - if(encryptSingleNxsItem(gItem, grpMeta->mCircleId,mit->first, encrypted_item,status)) - itemL.push_back(encrypted_item) ; - else - { - switch(status) - { - case RS_NXS_ITEM_ENCRYPTION_STATUS_CIRCLE_ERROR: - case RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING: toVet.push_back(GrpIdCircleVet(grpMeta->mGroupId, grpMeta->mCircleId, grpMeta->mAuthorId)); -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(peer,mit->first) << " Could not encrypt item for grpId " << grpMeta->mGroupId << " for circle " << grpMeta->mCircleId << ". Will try later. Adding to vetting list." << std::endl; -#endif - break ; - default: - std::cerr << " Could not encrypt item for grpId " << grpMeta->mGroupId << " for circle " << grpMeta->mCircleId << ". Not sending it." << std::endl; - } - } - delete gItem ; - } - else - itemL.push_back(gItem); - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(peer,mit->first) << " sending item for Grp " << mit->first << " name=" << grpMeta->mGroupName << ", publishTS=" << std::dec<< time(NULL) - mit->second->mPublishTs << " secs ago to peer ID " << peer << std::endl; -#endif - } - } - } - - if(!toVet.empty()) - mPendingCircleVets.push_back(new GrpCircleIdRequestVetting(mCircles, mPgpUtils, toVet, peer)); - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peer) << " final list sent (after vetting): " << itemL.size() << " elements." << std::endl; -#endif - locked_pushGrpRespFromList(itemL, peer, transN); - - return; -} - - - -bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector& /* toVet */, bool& should_encrypt) -{ -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendGrpId()"<< std::endl; -#endif - // check if that peer is a virtual peer id, in which case we only send/recv data to/from it items for the group it's requested for - - RsGxsGroupId peer_grp ; - if(mAllowDistSync && mGxsNetTunnel != NULL && mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId) - { -#warning (cyril) make sure that this is not a problem for cross-service sending of items -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Distant peer designed for group " << peer_grp << ": cannot request sync for different group." << std::endl; -#endif - return false ; - } - - // first do the simple checks - uint8_t circleType = grpMeta.mCircleType; - - if(circleType == GXS_CIRCLE_TYPE_LOCAL) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " LOCAL_CIRCLE, cannot send"<< std::endl; -#endif - return false; - } - else if(circleType == GXS_CIRCLE_TYPE_PUBLIC || circleType == GXS_CIRCLE_TYPE_UNKNOWN) // this complies with the fact that p3IdService does not initialise the circle type. - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " PUBLIC_CIRCLE, can send"<< std::endl; -#endif - return true; - } - else if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " EXTERNAL_CIRCLE, will be sent encrypted."<< std::endl; -#endif - should_encrypt = true ; - return true ; - } - else if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl; -#endif - bool res = checkPermissionsForFriendGroup(sslId,grpMeta) ; -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer: " << res << std::endl; -#endif - return res ; -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId)<< " YOUREYESONLY, checking further"<< std::endl; -#endif - } - else - { - std::cerr << "(EE) unknown value found in circle type for group " << grpMeta.mGroupId << ": " << (int)circleType << ": this is probably a bug in the design of the group creation." << std::endl; - return false; - } -} - -bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, RsGxsCircleId& should_encrypt_id) -{ - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::checkCanRecvMsgFromPeer()"; - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " peer Id = " << sslId << ", grpId=" << grpMeta.mGroupId <isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Distant peer designed for group " << peer_grp << ": cannot request sync for different group." << std::endl; -#endif - return false ; - } - - // first do the simple checks - uint8_t circleType = grpMeta.mCircleType; - should_encrypt_id.clear() ; - - if(circleType == GXS_CIRCLE_TYPE_LOCAL) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " LOCAL_CIRCLE, cannot request sync from peer" << std::endl; -#endif - return false; - } - - if(circleType == GXS_CIRCLE_TYPE_PUBLIC) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " PUBLIC_CIRCLE, can request msg sync" << std::endl; -#endif - return true; - } - - if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs will be encrypted." << std::endl; -#endif - should_encrypt_id = grpMeta.mCircleId ; - return true ; - } - - if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) // do not attempt to sync msg unless to originator or those permitted - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl; -#endif - bool res = checkPermissionsForFriendGroup(sslId,grpMeta) ; -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer: " << res << std::endl; -#endif - return res ; - } - - return true; -} - -bool RsGxsNetService::locked_checkResendingOfUpdates(const RsPeerId& pid,const RsGxsGroupId& grpId,rstime_t incoming_ts,RsPeerUpdateTsRecord& rec) -{ - rstime_t now = time(NULL); - - // Now we check if the peer is sending the same outdated TS for the same time in a short while. This would mean the peer - // hasn't finished processing the updates we're sending and we shouldn't send new data anymore. Of course the peer might - // have disconnected or so, which means that we need to be careful about not sending. As a compromise we still send, but - // after waiting for a while (See - - if(rec.mLastTsReceived == incoming_ts && rec.mTs + SAFETY_DELAY_FOR_UNSUCCESSFUL_UPDATE > now) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(pid,grpId) << "(II) peer " << pid << " already sent the same TS " << (long int)now-(long int)rec.mTs << " secs ago for that group ID. Will not send msg list again for a while to prevent clogging..." << std::endl; -#endif - return false; - } - - rec.mLastTsReceived = incoming_ts; - rec.mTs = now; - - return true; -} - -bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known) -{ - // Do we have new updates for this peer? - // Here we compare times in the same clock: our own clock, so it should be fine. - - grp_is_known = false ; - - if(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID) - { - // Item contains the hashed group ID in order to protect is from friends who don't know it. So we de-hash it using bruteforce over known group IDs for this peer. - // We could save the de-hash result. But the cost is quite light, since the number of encrypted groups per service is usually low. - - for(ServerMsgMap::iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it) - if(item->grpId == hashGrpId(it->first,item->PeerId())) - { - item->grpId = it->first ; - item->flag &= ~RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "(II) de-hashed group ID " << it->first << " from hash " << item->grpId << " and peer id " << item->PeerId() << std::endl; -#endif - grp_is_known = true ; - - // The order of tests below is important because we want to only modify the map of requests records if the request actually is a valid requests instead of - // a simple check that nothing's changed. - - return item->updateTS < it->second.msgUpdateTS && locked_checkResendingOfUpdates(item->PeerId(),item->grpId,item->updateTS,it->second.msgUpdateTsRecords[item->PeerId()]) ; - } - - return false ; - } - - ServerMsgMap::iterator cit = mServerMsgUpdateMap.find(item->grpId); - - if(cit != mServerMsgUpdateMap.end()) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - cit->second.msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < cit->second.msgUpdateTS) << std::endl; -#endif - grp_is_known = true ; - - return item->updateTS < cit->second.msgUpdateTS && locked_checkResendingOfUpdates(item->PeerId(),item->grpId,item->updateTS,cit->second.msgUpdateTsRecords[item->PeerId()]) ; - } - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl; -#endif - - return false; -} - -void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted) -{ - if (!item) - return; - - RS_STACK_MUTEX(mNxsMutex) ; - - const RsPeerId& peer = item->PeerId(); - bool grp_is_known = false; - bool was_circle_protected = item_was_encrypted || bool(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID); - - // This call determines if the peer can receive updates from us, meaning that our last TS is larger than what the peer sent. - // It also changes the items' group id into the un-hashed group ID if the group is a distant group. - - bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known); - - if(item_was_encrypted) - std::cerr << "(WW) got an encrypted msg sync req. from " << item->PeerId() << ". This will not send messages updates for group " << item->grpId << std::endl; - - // Insert the PeerId in suppliers list for this grpId -#ifdef NXS_NET_DEBUG_6 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl; -#endif -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ; -#endif - - // We update suppliers in two cases: - // Case 1: the grp is known because it is the hash of an existing group, but it's not yet in the server config map - // Case 2: the grp is not known, possibly because it was deleted, but there's an entry in mServerGrpConfigMap due to statistics gathering. Still, statistics are only - // gathered from known suppliers. So statistics never add new suppliers. These are only added here. - - if(grp_is_known || mServerGrpConfigMap.find(item->grpId)!=mServerGrpConfigMap.end()) - { - RsGxsGrpConfig& rec(locked_getGrpConfig(item->grpId)); // this creates it if needed. When the grp is unknown (and hashed) this will would create a unused entry - rec.suppliers.ids.insert(peer) ; - } - if(!peer_can_receive_update) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl; -#endif - return; - } - - RsGxsGrpMetaTemporaryMap grpMetas; - grpMetas[item->grpId] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMetas); - const auto& grpMeta = grpMetas[item->grpId]; - - if(grpMeta == NULL) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " Grp is unknown." << std::endl; -#endif - return; - } - if(!(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " Grp is not subscribed." << std::endl; -#endif - return ; - } - - if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != was_circle_protected ) - { - std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ; - if(!was_circle_protected) - std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl; - else - std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl; - - return ; - } - - GxsMsgReq req; - req[item->grpId] = std::set(); - - GxsMsgMetaResult metaResult; - mDataStore->retrieveGxsMsgMetaData(req, metaResult); - auto& msgMetas = metaResult[item->grpId]; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " retrieving message meta data." << std::endl; -#endif - if(req.empty()) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " No msg meta data.." << std::endl; -#endif - } -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " Sending MSG meta data created since TS=" << item->createdSinceTS << std::endl; -#endif - - std::list itemL; - - uint32_t transN = locked_getTransactionId(); - RsGxsCircleId should_encrypt_to_this_circle_id ; - - rstime_t now = time(NULL) ; - -#ifndef RS_GXS_SEND_ALL - uint32_t max_send_delay = locked_getGrpConfig(item->grpId).msg_req_delay; // we should use "sync" but there's only one variable used in the GUI: the req one. -#endif - - if(canSendMsgIds(msgMetas, *grpMeta, peer, should_encrypt_to_this_circle_id)) - { - for(auto vit = msgMetas.begin();vit != msgMetas.end(); ++vit) - { - const auto& m = *vit; - - // Check reputation - - if(!m->mAuthorId.isNull()) - { - RsIdentityDetails details ; - - if(!rsIdentity->getIdDetails(m->mAuthorId,details)) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending grp message ID " << (*vit)->mMsgId << ", because the identity of the author (" << m->mAuthorId << ") is not accessible (unknown/not cached)" << std::endl; -#endif - continue ; - } - - if(details.mReputation.mOverallReputationLevel < minReputationForForwardingMessages(grpMeta->mSignFlags, details.mFlags)) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because the author is flags " << std::hex << details.mFlags << std::dec << " and reputation level " << (int) details.mReputation.mOverallReputationLevel << std::endl; -#endif - continue ; - } - } - // Check publish TS -#ifndef RS_GXS_SEND_ALL - if(item->createdSinceTS > (*vit)->mPublishTs || ((max_send_delay > 0) && (*vit)->mPublishTs + max_send_delay < now)) -#else - if(item->createdSinceTS > (*vit)->mPublishTs) -#endif - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " not sending item ID " << (*vit)->mMsgId << ", because it is too old (publishTS = " << (time(NULL)-(*vit)->mPublishTs)/86400 << " days ago" << std::endl; -#endif - continue ; - } - - RsNxsSyncMsgItem* mItem = new RsNxsSyncMsgItem(mServType); - mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - mItem->grpId = m->mGroupId; - mItem->msgId = m->mMsgId; - mItem->authorId = m->mAuthorId; - mItem->PeerId(peer); - mItem->transactionNumber = transN; - - if(!should_encrypt_to_this_circle_id.isNull()) - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << ". Transaction will be encrypted for group " << should_encrypt_to_this_circle_id << std::endl; -#endif - RsNxsItem *encrypted_item = NULL ; - uint32_t status = RS_NXS_ITEM_ENCRYPTION_STATUS_UNKNOWN ; - - if(encryptSingleNxsItem(mItem, grpMeta->mCircleId,m->mGroupId, encrypted_item,status)) - { - itemL.push_back(encrypted_item) ; - delete mItem ; - } - else - { - // Something's not ready (probably the circle content. We could put on a vetting list, but actually the client will re-ask the list asap. - - std::cerr << " (EE) Cannot encrypt msg meta data. MsgId=" << mItem->msgId << ", grpId=" << mItem->grpId << ", circleId=" << should_encrypt_to_this_circle_id << ". Dropping the whole list." << std::endl; - - for(std::list::const_iterator it(itemL.begin());it!=itemL.end();++it) - delete *it ; - - itemL.clear() ; - delete mItem ; - break ; - } - } - else - { -#ifdef NXS_NET_DEBUG_7 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending info item for msg id " << mItem->msgId << " in clear." << std::endl; -#endif - itemL.push_back(mItem); - } - } - } -#ifdef NXS_NET_DEBUG_0 - else - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " vetting forbids sending. Nothing will be sent." << itemL.size() << " items." << std::endl; -#endif - - if(!itemL.empty()) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " sending final msg info list of " << itemL.size() << " items." << std::endl; -#endif - locked_pushMsgRespFromList(itemL, peer, item->grpId,transN); - } -#ifdef NXS_NET_DEBUG_0 - else - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " list is empty! Not sending anything." << std::endl; -#endif - - - // release meta resource - // for(std::vector::iterator vit = msgMetas.begin(); vit != msgMetas.end(); ++vit) - // delete *vit; -} - -void RsGxsNetService::locked_pushMsgRespFromList(std::list& itemL, const RsPeerId& sslId, const RsGxsGroupId& grp_id,const uint32_t& transN) -{ -#ifdef NXS_NET_DEBUG_1 - GXSNETDEBUG_PG(sslId,grp_id) << "locked_pushMsgResponseFromList()" << std::endl; - GXSNETDEBUG_PG(sslId,grp_id) << " nelems = " << itemL.size() << std::endl; - GXSNETDEBUG_PG(sslId,grp_id) << " peerId = " << sslId << std::endl; - GXSNETDEBUG_PG(sslId,grp_id) << " transN = " << transN << std::endl; -#endif - NxsTransaction* tr = new NxsTransaction(); - tr->mItems = itemL; - tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM; - - RsNxsTransacItem* trItem = new RsNxsTransacItem(mServType); - trItem->transactFlag = RsNxsTransacItem::FLAG_BEGIN_P1 | RsNxsTransacItem::FLAG_TYPE_MSG_LIST_RESP; - trItem->nItems = itemL.size(); - trItem->timestamp = 0; - trItem->PeerId(sslId); - trItem->transactionNumber = transN; - - // also make a copy for the resident transaction - tr->mTransaction = new RsNxsTransacItem(*trItem); - tr->mTransaction->PeerId(mOwnId); - tr->mTimeOut = time(NULL) + mTransactionTimeOut; - - // This time stamp is not supposed to be used on the other side. We just set it to avoid sending an uninitialiszed value. - trItem->updateTS = mServerMsgUpdateMap[grp_id].msgUpdateTS; - -#ifdef NXS_NET_DEBUG_5 - GXSNETDEBUG_P_ (sslId) << "Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " - sending messages response to peer " - << sslId << " with " << itemL.size() << " messages " << std::endl; -#endif - // signal peer to prepare for transaction - if(locked_addTransaction(tr)) - generic_sendItem(trItem); - else - { - delete tr ; - delete trItem ; - } -} - -bool RsGxsNetService::canSendMsgIds(std::vector >& msgMetas, const RsGxsGrpMetaData& grpMeta, const RsPeerId& sslId,RsGxsCircleId& should_encrypt_id) -{ -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << "RsGxsNetService::canSendMsgIds() CIRCLE VETTING" << std::endl; -#endif - // check if that peer is a virtual peer id, in which case we only send/recv data to/from it items for the group it's requested for - - RsGxsGroupId peer_grp ; - if(mAllowDistSync && mGxsNetTunnel != NULL && mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Distant peer designed for group " << peer_grp << ": cannot request sync for different group." << std::endl; -#endif - return false ; - } - - // first do the simple checks - uint8_t circleType = grpMeta.mCircleType; - - if(circleType == GXS_CIRCLE_TYPE_LOCAL) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: LOCAL => returning false" << std::endl; -#endif - return false; - } - else if(circleType == GXS_CIRCLE_TYPE_PUBLIC || circleType == GXS_CIRCLE_TYPE_UNKNOWN) // this complies with the fact that p3IdService does not initialise the circle type. - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: PUBLIC => returning true" << std::endl; -#endif - return true; - } - else if(circleType == GXS_CIRCLE_TYPE_EXTERNAL) - { - const RsGxsCircleId& circleId = grpMeta.mCircleId; -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs ids list will be encrypted." << std::endl; -#endif - should_encrypt_id = circleId ; - - // For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list. - // Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post - // is allowed at this point is anyway already vetted by the RsGxsGenExchange service. - - // Messages that stay in the list will be sent. As a consequence true is always returned. - // Messages put in vetting list will be dealt with later - - std::vector toVet; - - for(uint32_t i=0;imAuthorId.isNull() ) // keep the message in this case - ++i ; - else - { - if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, grpMeta.mGroupId, msgMetas[i]->mAuthorId)) - { - ++i ; - continue ; - } - - MsgIdCircleVet mic(msgMetas[i]->mMsgId, msgMetas[i]->mAuthorId); - toVet.push_back(mic); -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl; -#endif - - //delete msgMetas[i] ; - msgMetas[i] = msgMetas[msgMetas.size()-1] ; - msgMetas.pop_back() ; - } - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle info not loaded. Putting in vetting list and returning false." << std::endl; -#endif - if(!toVet.empty()) - mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId, sslId, grpMeta.mCircleId)); - - return true ; - } - else if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY) - { -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl; -#endif - bool res = checkPermissionsForFriendGroup(sslId,grpMeta) ; -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer: " << res << std::endl; -#endif - return res ; - } - else - { - std::cerr << "(EE) unknown value found in circle type for group " << grpMeta.mGroupId << ": " << (int)circleType << ": this is probably a bug in the design of the group creation." << std::endl; - return false; - } -} - -/** inherited methods **/ - -bool RsGxsNetService::checkPermissionsForFriendGroup(const RsPeerId& sslId,const RsGxsGrpMetaData& grpMeta) -{ -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: YOUR EYES ONLY - ID = " << grpMeta.mInternalCircle << std::endl; -#endif - // a non empty internal circle id means this - // is the personal circle owner - if(!grpMeta.mInternalCircle.isNull()) - { - RsGroupInfo ginfo ; - RsPgpId pgpId = mPgpUtils->getPGPId(sslId) ; - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Group internal circle: " << grpMeta.mInternalCircle << ", We're owner. Sending to everyone in the group." << std::endl; - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Current destination is PGP Id: " << pgpId << std::endl; -#endif - if(!rsPeers->getGroupInfo(RsNodeGroupId(grpMeta.mInternalCircle),ginfo)) - { - std::cerr << "(EE) Cannot get information for internal circle (group node) ID " << grpMeta.mInternalCircle << " which conditions dissemination of GXS group " << grpMeta.mGroupId << std::endl; - return false ; - } - - bool res = (ginfo.peerIds.find(pgpId) != ginfo.peerIds.end()); - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final Answer is: " << res << std::endl; -#endif - return res ; - } - else - { - // An empty internal circle id means this peer can only - // send circle related info from peer he received it from. - // Normally this should be a pgp-based decision, but if we do that, - // A ---> B ----> A' ---...--->B' , then A' will also send to B' since B is the - // originator for A'. So A will lose control of who can see the data. This should - // be discussed further... - -#ifdef NXS_NET_DEBUG_4 - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Empty internal circle: cannot only send/recv info to/from Peer we received it from (grpMeta.mOriginator=" << grpMeta.mOriginator << ")" << std::endl; - GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer is: " << (grpMeta.mOriginator == sslId) << std::endl; -#endif - if(grpMeta.mOriginator == sslId) - return true; - else - return false; - } -} - -void RsGxsNetService::pauseSynchronisation(bool /* enabled */) -{ - std::cerr << "(EE) RsGxsNetService::pauseSynchronisation() called, but not implemented." << std::endl; -} - -void RsGxsNetService::setSyncAge(const RsGxsGroupId &grpId, uint32_t age_in_secs) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - locked_checkDelay(age_in_secs) ; - - RsGxsGrpConfig& conf(locked_getGrpConfig(grpId)); - - if(conf.msg_req_delay != age_in_secs) - { - conf.msg_req_delay = age_in_secs; - - // we also need to zero the client TS, in order to trigger a new sync - locked_resetClientTS(grpId); - - IndicateConfigChanged(); - - // also send an event so that UI is updated - - mNewGrpSyncParamsToNotify.insert(grpId); - } -} -void RsGxsNetService::setKeepAge(const RsGxsGroupId &grpId, uint32_t age_in_secs) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - locked_checkDelay(age_in_secs) ; - - RsGxsGrpConfig& conf(locked_getGrpConfig(grpId)); - - if(conf.msg_keep_delay != age_in_secs) - { - conf.msg_keep_delay = age_in_secs; - IndicateConfigChanged(); - } -} - -RsGxsGrpConfig& RsGxsNetService::locked_getGrpConfig(const RsGxsGroupId& grp_id) -{ - GrpConfigMap::iterator it = mServerGrpConfigMap.find(grp_id); - - if(it == mServerGrpConfigMap.end()) - { - RsGxsGrpConfig& conf(mServerGrpConfigMap[grp_id]) ; - - conf.msg_keep_delay = mDefaultMsgStorePeriod; - conf.msg_send_delay = mDefaultMsgSyncPeriod; - conf.msg_req_delay = mDefaultMsgSyncPeriod; - - conf.max_visible_count = 0 ; - conf.statistics_update_TS = 0 ; - conf.last_group_modification_TS = 0 ; - - return conf ; - } - else - return it->second; -} - -uint32_t RsGxsNetService::getSyncAge(const RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - return locked_getGrpConfig(grpId).msg_req_delay ; -} -uint32_t RsGxsNetService::getKeepAge(const RsGxsGroupId& grpId) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - return locked_getGrpConfig(grpId).msg_keep_delay ; -} - -int RsGxsNetService::requestGrp(const std::list& grpId, const RsPeerId& peerId) -{ - RS_STACK_MUTEX(mNxsMutex) ; -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peerId) << "RsGxsNetService::requestGrp(): adding explicit group requests to peer " << peerId << std::endl; - - for(std::list::const_iterator it(grpId.begin());it!=grpId.end();++it) - GXSNETDEBUG_PG(peerId,*it) << " Group ID: " << *it << std::endl; -#endif - mExplicitRequest[peerId].assign(grpId.begin(), grpId.end()); - return 1; -} - -void RsGxsNetService::processExplicitGroupRequests() -{ - RS_STACK_MUTEX(mNxsMutex) ; - - std::map >::const_iterator cit = mExplicitRequest.begin(); - - for(; cit != mExplicitRequest.end(); ++cit) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(cit->first) << "RsGxsNetService::sending pending explicit group requests to peer " << cit->first << std::endl; -#endif - const RsPeerId& peerId = cit->first; - const std::list& groupIdList = cit->second; - - std::list grpSyncItems; - std::list::const_iterator git = groupIdList.begin(); - uint32_t transN = locked_getTransactionId(); - for(; git != groupIdList.end(); ++git) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG_P_(peerId) << " group request for grp ID " << *git << " to peer " << peerId << std::endl; -#endif - RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType); - item->grpId = *git; - item->PeerId(peerId); - item->flag = RsNxsSyncGrpItem::FLAG_REQUEST; - item->transactionNumber = transN; - grpSyncItems.push_back(item); - } - - if(!grpSyncItems.empty()) - locked_pushGrpTransactionFromList(grpSyncItems, peerId, transN); - } - - mExplicitRequest.clear(); -} - -int RsGxsNetService::sharePublishKey(const RsGxsGroupId& grpId,const std::set& peers) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - mPendingPublishKeyRecipients[grpId] = peers ; -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG__G(grpId) << "RsGxsNetService::sharePublishKeys() " << (void*)this << " adding publish keys for grp " << grpId << " to sending list" << std::endl; -#endif - - return true ; -} - -void RsGxsNetService::sharePublishKeysPending() -{ - RS_STACK_MUTEX(mNxsMutex) ; - - if(mPendingPublishKeyRecipients.empty()) - return ; - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG___ << "RsGxsNetService::sharePublishKeys() " << (void*)this << std::endl; -#endif - // get list of peers that are online - - std::set peersOnline; - std::list toDelete; - std::map >::iterator mit ; - - mNetMgr->getOnlineList(mServiceInfo.mServiceType, peersOnline); - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG___ << " " << peersOnline.size() << " peers online." << std::endl; -#endif - /* send public key to peers online */ - - for(mit = mPendingPublishKeyRecipients.begin(); mit != mPendingPublishKeyRecipients.end(); ++mit) - { - // Compute the set of peers to send to. We start with this, to avoid retrieving the data for nothing. - - std::list recipients ; - std::set offline_recipients ; - - for(std::set::const_iterator it(mit->second.begin());it!=mit->second.end();++it) - if(peersOnline.find(*it) != peersOnline.end()) - { -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_P_(*it) << " " << *it << ": online. Adding." << std::endl; -#endif - recipients.push_back(*it) ; - } - else - { -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_P_(*it) << " " << *it << ": offline. Keeping for next try." << std::endl; -#endif - offline_recipients.insert(*it) ; - } - - // If empty, skip - - if(recipients.empty()) - { -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG___ << " No recipients online. Skipping." << std::endl; -#endif - continue ; - } - - // Get the meta data for this group Id - // - RsGxsGrpMetaTemporaryMap grpMetaMap; - grpMetaMap[mit->first] = NULL; - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - - // Find the publish keys in the retrieved info - - const auto& grpMeta = grpMetaMap[mit->first] ; - - if(grpMeta == NULL) - { - std::cerr << "(EE) RsGxsNetService::sharePublishKeys() Publish keys cannot be found for group " << mit->first << std::endl; - continue ; - } - - const RsTlvSecurityKeySet& keys = grpMeta->keys; - - std::map::const_iterator kit = keys.private_keys.begin(), kit_end = keys.private_keys.end(); - bool publish_key_found = false; - RsTlvPrivateRSAKey publishKey ; - - for(; kit != kit_end && !publish_key_found; ++kit) - { - publish_key_found = (kit->second.keyFlags == (RSTLV_KEY_DISTRIB_PUBLISH | RSTLV_KEY_TYPE_FULL)); - publishKey = kit->second ; - } - - if(!publish_key_found) - { - std::cerr << "(EE) no publish key in group " << mit->first << ". Cannot share!" << std::endl; - continue ; - } - - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG__G(grpMeta->mGroupId) << " using publish key ID=" << publishKey.keyId << ", flags=" << publishKey.keyFlags << std::endl; -#endif - for(std::list::const_iterator it(recipients.begin());it!=recipients.end();++it) - { - /* Create publish key sharing item */ - RsNxsGroupPublishKeyItem *publishKeyItem = new RsNxsGroupPublishKeyItem(mServType); - - publishKeyItem->clear(); - publishKeyItem->grpId = mit->first; - - publishKeyItem->private_key = publishKey ; - publishKeyItem->PeerId(*it); - - generic_sendItem(publishKeyItem); -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(*it,grpMeta->mGroupId) << " sent key item to " << *it << std::endl; -#endif - } - - mit->second = offline_recipients ; - - // If given peers have all received key(s) then stop sending for group - if(offline_recipients.empty()) - toDelete.push_back(mit->first); - } - - // delete pending peer list which are done with - for(std::list::const_iterator lit = toDelete.begin(); lit != toDelete.end(); ++lit) - mPendingPublishKeyRecipients.erase(*lit); -} - -void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item) -{ -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::sharePublishKeys() " << std::endl; -#endif - - if (!item) - return; - - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " PeerId : " << item->PeerId() << std::endl; - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " GrpId: " << item->grpId << std::endl; - GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " Got key Item: " << item->private_key.keyId << std::endl; -#endif - - // Get the meta data for this group Id - // - RsGxsGrpMetaTemporaryMap grpMetaMap; - grpMetaMap[item->grpId] = NULL; - - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - - // update the publish keys in this group meta info - - const auto& grpMeta = grpMetaMap[item->grpId] ; - if (!grpMeta) { - std::cerr << "(EE) RsGxsNetService::handleRecvPublishKeys() grpMeta not found." << std::endl; - return ; - } - - // Check that the keys correspond, and that FULL keys are supplied, etc. - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId)<< " Key received: " << std::endl; -#endif - - bool admin = (item->private_key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (item->private_key.keyFlags & RSTLV_KEY_TYPE_FULL) ; - bool publi = (item->private_key.keyFlags & RSTLV_KEY_DISTRIB_PUBLISH) && (item->private_key.keyFlags & RSTLV_KEY_TYPE_FULL) ; - -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId)<< " Key id = " << item->private_key.keyId << " admin=" << admin << ", publish=" << publi << " ts=" << item->private_key.endTS << std::endl; -#endif - - if(!(!admin && publi)) - { - std::cerr << " Key is not a publish private key. Discarding!" << std::endl; - return ; - } - // Also check that we don't already have full keys for that group. - - if(grpMeta->keys.public_keys.find(item->private_key.keyId) == grpMeta->keys.public_keys.end()) - { - std::cerr << " (EE) Key not found in known group keys. This is an inconsistency." << std::endl; - return ; - } - - if(grpMeta->keys.private_keys.find(item->private_key.keyId) != grpMeta->keys.private_keys.end()) - { -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId)<< " (EE) Publish key already present in database. Discarding message." << std::endl; -#endif - mNewPublishKeysToNotify.insert(item->grpId) ; - return ; - } - - // Store/update the info. - - RsTlvSecurityKeySet keys = grpMeta->keys ; - keys.private_keys[item->private_key.keyId] = item->private_key ; - - bool ret = mDataStore->updateGroupKeys(item->grpId,keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ; - - if(ret) - { -#ifdef NXS_NET_DEBUG_3 - GXSNETDEBUG_PG(item->PeerId(),item->grpId)<< " updated database with new publish keys." << std::endl; -#endif - mNewPublishKeysToNotify.insert(item->grpId) ; - } - else - { - std::cerr << "(EE) could not update database. Something went wrong." << std::endl; - } -} - -bool RsGxsNetService::getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& group_server_update_TS, rstime_t& msg_server_update_TS) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - group_server_update_TS = mGrpServerUpdate.grpUpdateTS ; - - ServerMsgMap::iterator it = mServerMsgUpdateMap.find(gid) ; - - if(mServerMsgUpdateMap.end() == it) - msg_server_update_TS = 0 ; - else - msg_server_update_TS = it->second.msgUpdateTS ; - - return true ; -} - -bool RsGxsNetService::removeGroups(const std::list& groups) -{ - RS_STACK_MUTEX(mNxsMutex) ; - -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG___ << "Removing group information from deleted groups:" << std::endl; -#endif - - for(std::list::const_iterator git(groups.begin());git!=groups.end();++git) - { -#ifdef NXS_NET_DEBUG_0 - GXSNETDEBUG__G(*git) << " deleting info for group " << *git << std::endl; -#endif - - // Here we do not use locked_getGrpConfig() because we dont want the entry to be created if it doesnot already exist. - - GrpConfigMap::iterator it = mServerGrpConfigMap.find(*git) ; - - if(it != mServerGrpConfigMap.end()) - { - it->second.suppliers.TlvClear(); // we dont erase the entry, because we want to keep the user-defined sync parameters. - it->second.max_visible_count = 0; - } - - mServerMsgUpdateMap.erase(*git) ; - - for(ClientMsgMap::iterator it(mClientMsgUpdateMap.begin());it!=mClientMsgUpdateMap.end();++it) - it->second.msgUpdateInfos.erase(*git) ; - - // This last step is very important: it makes RS re-sync all groups after deleting, with every new peer. If may happen indeed that groups - // are deleted because there's no suppliers since the actual supplier friend is offline for too long. In this case, the group needs - // to re-appear when the friend who is a subscriber comes online again. - - mClientGrpUpdateMap.clear(); - } - - IndicateConfigChanged(); - return true ; -} - -bool RsGxsNetService::isDistantPeer(const RsPeerId& pid) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - if(!mAllowDistSync || mGxsNetTunnel == NULL) - return false ; - - RsGxsGroupId group_id ; - - return mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(pid),group_id); -} - -bool RsGxsNetService::stampMsgServerUpdateTS(const RsGxsGroupId& gid) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - return locked_stampMsgServerUpdateTS(gid) ; -} - -bool RsGxsNetService::locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid) -{ - RsGxsServerMsgUpdate& m(mServerMsgUpdateMap[gid]); - - m.msgUpdateTS = time(NULL) ; - - return true; -} - -DistantSearchGroupStatus RsGxsNetService::getDistantSearchStatus(const RsGxsGroupId& group_id) -{ - auto it = mSearchedGroups.find(group_id); - - if(it != mSearchedGroups.end()) - return it->second.status; - - for(auto it2:mDistantSearchResults) - if(it2.second.find(group_id) != it2.second.end()) - return DistantSearchGroupStatus::CAN_BE_REQUESTED; - - return DistantSearchGroupStatus::UNKNOWN; -} - -TurtleRequestId RsGxsNetService::turtleGroupRequest(const RsGxsGroupId& group_id) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - rstime_t now = time(NULL); - auto it = mSearchedGroups.find(group_id) ; - - if(mSearchedGroups.end() != it && (it->second.ts + MIN_DELAY_BETWEEN_GROUP_SEARCH > now)) - { - std::cerr << "(WW) Last turtle request was " << now - it->second.ts << " secs ago. Not searching again." << std::endl; - return it->second.request_id; - } - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG__G(group_id) << " requesting group id " << group_id << " using turtle" << std::endl; -#endif - TurtleRequestId req = mGxsNetTunnel->turtleGroupRequest(group_id,this) ; - - GroupRequestRecord& rec(mSearchedGroups[group_id]) ; - - rec.request_id = req; - rec.ts = now; - rec.status = DistantSearchGroupStatus::ONGOING_REQUEST; - - mSearchRequests[req] = group_id; - - return req; -} -TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_string) -{ - return mGxsNetTunnel->turtleSearchRequest(match_string,this) ; -} - -#ifndef RS_DEEP_CHANNEL_INDEX -static bool termSearch(const std::string& src, const std::string& substring) -{ - /* always ignore case */ - return src.end() != std::search( src.begin(), src.end(), substring.begin(), substring.end(), RsRegularExpression::CompareCharIC() ); -} -#endif // ndef RS_DEEP_CHANNEL_INDEX - -bool RsGxsNetService::retrieveDistantSearchResults(TurtleRequestId req,std::map& group_infos) -{ - RS_STACK_MUTEX(mNxsMutex) ; - - auto it = mDistantSearchResults.find(req) ; - - if(it == mDistantSearchResults.end()) - return false ; - - group_infos = it->second; - return true ; -} -bool RsGxsNetService::retrieveDistantGroupSummary(const RsGxsGroupId& group_id,RsGxsGroupSearchResults& gs) -{ - RS_STACK_MUTEX(mNxsMutex) ; - for(auto it(mDistantSearchResults.begin());it!=mDistantSearchResults.end();++it) - { - auto it2 = it->second.find(group_id) ; - - if(it2 != it->second.end()) - { - gs = it2->second; - return true ; - } - } - return false ; -} -bool RsGxsNetService::clearDistantSearchResults(const TurtleRequestId& id) -{ - RS_STACK_MUTEX(mNxsMutex) ; - mDistantSearchResults.erase(id); - return true ; -} - -void RsGxsNetService::receiveTurtleSearchResults( TurtleRequestId req, const std::list& group_infos ) -{ - std::set groupsToNotifyResults; - - { - RS_STACK_MUTEX(mNxsMutex); - - RsGxsGrpMetaTemporaryMap grpMeta; - std::map& search_results_map(mDistantSearchResults[req]); - -#ifdef NXS_NET_DEBUG_9 - std::cerr << "Received group summary through turtle search for the following groups:" << std::endl; -#endif - - for(const RsGxsGroupSummary& gps : group_infos) - { - std::cerr <<" " << gps.mGroupId << " \"" << gps.mGroupName << "\"" << std::endl; - grpMeta[gps.mGroupId] = nullptr; - } - - mDataStore->retrieveGxsGrpMetaData(grpMeta); - -#ifdef NXS_NET_DEBUG_9 - std::cerr << "Retrieved data store group data for the following groups:" <mGroupName << std::endl; -#endif - - for (const RsGxsGroupSummary& gps : group_infos) - { -#ifndef RS_DEEP_CHANNEL_INDEX - /* Only keep groups that are not locally known, and groups that are - * not already in the mDistantSearchResults structure. - * mDataStore may in some situations allocate an empty group meta data, so it's important - * to test that the group meta is both non null and actually corresponds to the group id we seek. */ - - auto& meta(grpMeta[gps.mGroupId]); - - if(meta != nullptr && meta->mGroupId == gps.mGroupId) - continue; - -#ifdef NXS_NET_DEBUG_9 - std::cerr << " group " << gps.mGroupId << " is not known. Adding it to search results..." << std::endl; -#endif - -#else // ndef RS_DEEP_CHANNEL_INDEX - /* When deep search is enabled search results may bring more info - * then we already have also about post that are indexed by xapian, - * so we don't apply this filter in this case. */ -#endif - const RsGxsGroupId& grpId(gps.mGroupId); - - groupsToNotifyResults.insert(grpId); - - // Find search results place for this particular group - -#ifdef NXS_NET_DEBUG_9 - std::cerr << " Adding gps=" << gps.mGroupId << " name=\"" << gps.mGroupName << "\" gps.mSearchContext=\"" << gps.mSearchContext << "\"" << std::endl; -#endif - RsGxsGroupSearchResults& eGpS(search_results_map[grpId]); - - if(eGpS.mGroupId != grpId) // not initialized yet. So we do it now. - { - eGpS.mGroupId = gps.mGroupId; - eGpS.mGroupName = gps.mGroupName; - eGpS.mAuthorId = gps.mAuthorId; - eGpS.mPublishTs = gps.mPublishTs; - eGpS.mSignFlags = gps.mSignFlags; - } - // We should check that the above values are always the same for all info that is received. In the end, we'll - // request the group meta and check the signature, but it may be misleading to receive a forged information - // that is not the real one. - - ++eGpS.mPopularity; // increase popularity. This is not a real counting, but therefore some heuristic estimate. - eGpS.mNumberOfMessages = std::max( eGpS.mNumberOfMessages, gps.mNumberOfMessages ); - eGpS.mLastMessageTs = std::max( eGpS.mLastMessageTs, gps.mLastMessageTs ); - - if(gps.mSearchContext != gps.mGroupName) // this is a bit of a hack. We should have flags to tell where the search hit happens - eGpS.mSearchContexts.insert(gps.mSearchContext); - } - } // end RS_STACK_MUTEX(mNxsMutex); - - for(const RsGxsGroupId& grpId : groupsToNotifyResults) - mObserver->receiveDistantSearchResults(req, grpId); -} - -void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len) -{ -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " received encrypted group data for turtle search request " << std::hex << req << std::dec << ": " << RsUtil::BinToHex(encrypted_group_data,encrypted_group_data_len,50) << std::endl; -#endif - auto it = mSearchRequests.find(req); - - if(mSearchRequests.end() == it) - { - std::cerr << "(EE) received search results for unknown request " << std::hex << req << std::dec ; - return; - } - RsGxsGroupId grpId = it->second; - - uint8_t encryption_master_key[32]; - Sha256CheckSum s = RsDirUtil::sha256sum(grpId.toByteArray(),grpId.SIZE_IN_BYTES); - memcpy(encryption_master_key,s.toByteArray(),32); - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " attempting data decryption with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl; -#endif - unsigned char *clear_group_data = NULL; - uint32_t clear_group_data_len ; - - if(!librs::crypto::decryptAuthenticateData(encrypted_group_data,encrypted_group_data_len,encryption_master_key,clear_group_data,clear_group_data_len)) - { - std::cerr << "(EE) Could not decrypt data. Something went wrong. Wrong key??" << std::endl; - return ; - } - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " successfuly decrypted data : " << RsUtil::BinToHex(clear_group_data,clear_group_data_len,50) << std::endl; -#endif - uint32_t used_size = clear_group_data_len; - RsItem *item = RsNxsSerialiser(mServType).deserialise(clear_group_data,&used_size) ; - RsNxsGrp *nxs_identity_grp=nullptr; - - if(used_size < clear_group_data_len) - { - uint32_t remaining_size = clear_group_data_len-used_size ; - RsItem *item2 = RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).deserialise(clear_group_data+used_size,&remaining_size) ; - - nxs_identity_grp = dynamic_cast(item2); - - if(!nxs_identity_grp) - std::cerr << "(EE) decrypted item contains more data that cannot be deserialized as a GxsId. Unexpected!" << std::endl; - - // We should probably check that the identity that is sent corresponds to the group author and don't add - // it otherwise. But in any case, this won't harm to add a new public identity. If that identity is banned, - // the group will be discarded in RsGenExchange anyway. - - if(nxs_identity_grp) - mGixs->receiveNewIdentity(nxs_identity_grp); - } - - free(clear_group_data); - clear_group_data = NULL ; - - RsNxsGrp *nxs_grp = dynamic_cast(item) ; - - if(nxs_grp == NULL) - { - std::cerr << "(EE) decrypted item is not a RsNxsGrp. Weird!" << std::endl; - return ; - } - -#ifdef NXS_NET_DEBUG_8 - if(nxs_identity_grp) - GXSNETDEBUG___ << " Serialized clear data contains a group " << nxs_grp->grpId << " in service " << std::hex << mServType << std::dec << " and a second identity item for an identity." << nxs_identity_grp->grpId << std::endl; - else - GXSNETDEBUG___ << " Serialized clear data contains a single GXS group for Grp Id " << nxs_grp->grpId << " in service " << std::hex << mServType << std::dec << std::endl; -#endif - - std::vector new_grps(1,nxs_grp); - - GroupRequestRecord& rec(mSearchedGroups[nxs_grp->grpId]) ; - rec.status = DistantSearchGroupStatus::HAVE_GROUP_DATA; - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " passing the grp data to observer." << std::endl; -#endif - mObserver->receiveNewGroups(new_grps); - mObserver->receiveDistantSearchResults(req, grpId); -} - -bool RsGxsNetService::search( const std::string& substring, - std::list& group_infos ) -{ - group_infos.clear(); - -#ifdef RS_DEEP_CHANNEL_INDEX - -#warning TODO: filter deep index search result to non circle-restricted groups. -// /!\ -// /!\ These results should be filtered to only return results coming from a non restricted group! -// /!\ - - std::vector results; - DeepChannelsIndex::search(substring, results); - - for(auto dsr : results) - { - RsUrl rUrl(dsr.mUrl); - const auto& uQ(rUrl.query()); - auto rit = uQ.find("id"); - if(rit != rUrl.query().end()) - { - RsGroupNetworkStats stats; - RsGxsGroupId grpId(rit->second); - if( !grpId.isNull() && getGroupNetworkStats(grpId, stats) ) - { - RsGxsGroupSummary s; - - s.mGroupId = grpId; - - if((rit = uQ.find("name")) != uQ.end()) - s.mGroupName = rit->second; - if((rit = uQ.find("signFlags")) != uQ.end()) - s.mSignFlags = static_cast(std::stoul(rit->second)); - if((rit = uQ.find("publishTs")) != uQ.end()) - s.mPublishTs = static_cast(std::stoll(rit->second)); - if((rit = uQ.find("authorId")) != uQ.end()) - s.mAuthorId = RsGxsId(rit->second); - - s.mSearchContext = dsr.mSnippet; - - s.mNumberOfMessages = stats.mMaxVisibleCount; - s.mLastMessageTs = stats.mLastGroupModificationTS; - s.mPopularity = stats.mSuppliers; - - group_infos.push_back(s); - } - } - } -#else // RS_DEEP_CHANNEL_INDEX - RsGxsGrpMetaTemporaryMap grpMetaMap; - { - RS_STACK_MUTEX(mNxsMutex) ; - mDataStore->retrieveGxsGrpMetaData(grpMetaMap); - } - - RsGroupNetworkStats stats; - for(auto it(grpMetaMap.begin());it!=grpMetaMap.end();++it) - if(it->second->mCircleType==GXS_CIRCLE_TYPE_PUBLIC && termSearch(it->second->mGroupName,substring)) - { - getGroupNetworkStats(it->first,stats); - - RsGxsGroupSummary s; - s.mGroupId = it->first; - s.mGroupName = it->second->mGroupName; - s.mSearchContext = it->second->mGroupName; - s.mSignFlags = it->second->mSignFlags; - s.mPublishTs = it->second->mPublishTs; - s.mAuthorId = it->second->mAuthorId; - s.mNumberOfMessages = stats.mMaxVisibleCount; - s.mLastMessageTs = stats.mLastGroupModificationTS; - s.mPopularity = it->second->mPop; - - group_infos.push_back(s); - } -#endif // RS_DEEP_CHANNEL_INDEX - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " performing local substring search in response to distant request. Found " << group_infos.size() << " responses." << std::endl; -#endif - return !group_infos.empty(); -} - -bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len) -{ - // First look into the grp hash cache - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " Received group data request for hash " << hashed_group_id << std::endl; -#endif - auto it = mGroupHashCache.find(hashed_group_id) ; - RsNxsGrp *grp_data = NULL ; - - if(mGroupHashCache.end() != it) - { - grp_data = it->second; - } - else - { - // Now check if the last request was too close in time, in which case, we dont retrieve data. - - if(mLastCacheReloadTS + 60 > time(NULL)) - { - std::cerr << "(WW) Not found in cache, and last cache reload less than 60 secs ago. Returning false. " << std::endl; - return false ; - } - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " reloading group cache information" << std::endl; -#endif - RsNxsGrpDataTemporaryMap grpDataMap; - { - RS_STACK_MUTEX(mNxsMutex) ; - mDataStore->retrieveNxsGrps(grpDataMap, true); - mLastCacheReloadTS = time(NULL); - } - - for(auto it(grpDataMap.begin());it!=grpDataMap.end();++it) - if(it->second->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) // only cache subscribed groups - { - RsNxsGrp *grp = it->second ; - grp->metaData->keys.TlvClear() ;// clean private keys. This technically not needed, since metaData is not serialized, but I still prefer. - - Sha1CheckSum hash(RsDirUtil::sha1sum(it->first.toByteArray(),it->first.SIZE_IN_BYTES)); - - mGroupHashCache[hash] = grp ; - it->second = NULL ; // prevents deletion - - if(hash == hashed_group_id) - grp_data = grp ; - } - } - - if(!grp_data) - { -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " no group found for hash " << hashed_group_id << ": returning false." << std::endl; -#endif - return false ; - } - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " found corresponding group data group id in cache group_id=" << grp_data->grpId << std::endl; -#endif - // Finally, serialize and encrypt the grp data - - uint32_t size = RsNxsSerialiser(mServType).size(grp_data); - RsNxsGrp *author_group=nullptr; - - if(!grp_data->metaData->mAuthorId.isNull()) - { -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " this group has an author identity " << grp_data->metaData->mAuthorId << " that we need to send at the same time." << std::endl; -#endif - mGixs->retrieveNxsIdentity(grp_data->metaData->mAuthorId,author_group); // whatever gets the data - - if(!author_group) - { - std::cerr << "(EE) Cannot retrieve author group data " << grp_data->metaData->mAuthorId << " for GXS group " << grp_data->grpId << std::endl; - return false; - } - - delete author_group->metaData; // delete private information, just in case, but normally it is not serialized. - author_group->metaData = NULL ; - - size += RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).size(author_group); - } - - RsTemporaryMemory mem(size) ; - uint32_t used_size=size; - - RsNxsSerialiser(mServType).serialise(grp_data,mem,&used_size) ; - - uint32_t remaining_size=size-used_size; - - if(author_group) - { -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " Serializing author group data..." << std::endl; -#endif - RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).serialise(author_group,mem+used_size,&remaining_size); - } - - uint8_t encryption_master_key[32]; - Sha256CheckSum s = RsDirUtil::sha256sum(grp_data->grpId.toByteArray(),grp_data->grpId.SIZE_IN_BYTES); - memcpy(encryption_master_key,s.toByteArray(),32); - -#ifdef NXS_NET_DEBUG_8 - GXSNETDEBUG___ << " sending data encrypted with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl; -#endif - return librs::crypto::encryptAuthenticateData(mem,size,encryption_master_key,encrypted_group_data,encrypted_group_data_len); -} - diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h deleted file mode 100644 index b619896b1..000000000 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ /dev/null @@ -1,633 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsnetservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSNETSERVICE_H -#define RSGXSNETSERVICE_H - -#include -#include - -#include "rsnxs.h" -#include "rsgds.h" -#include "rsnxsobserver.h" -#include "pqi/p3linkmgr.h" -#include "rsitems/rsnxsitems.h" -#include "rsitems/rsgxsupdateitems.h" -#include "rsgxsnettunnel.h" -#include "rsgxsnetutils.h" -#include "pqi/p3cfgmgr.h" -#include "rsgixs.h" -#include "util/rssharedptr.h" - -/// keep track of transaction number -typedef std::map TransactionIdMap; - -/// to keep track of peers active transactions -typedef std::map TransactionsPeerMap; - -class PgpAuxUtils; - -class RsGroupNetworkStatsRecord -{ - public: - RsGroupNetworkStatsRecord() { max_visible_count= 0 ; update_TS=0; } - - std::set suppliers ; - uint32_t max_visible_count ; - rstime_t update_TS ; -}; - -struct GroupRequestRecord -{ - GroupRequestRecord(): ts(0),request_id(0),status(DistantSearchGroupStatus::UNKNOWN) {} - - rstime_t ts ; - TurtleRequestId request_id; - DistantSearchGroupStatus status; -}; - -/*! - * This class implements the RsNetWorkExchangeService - * using transactions to handle synchrnisation of Nxs items between - * peers in a network - * Transactions requires the maintenance of several states between peers - * - * Thus a data structure maintains: peers, and their active transactions - * Then for each transaction it needs to be noted if this is an outgoing or incoming transaction - * Outgoing transaction are in 3 different states: - * 1. START 2. INITIATED 3. SENDING 4. END - * Incoming transaction are in 3 different states - * 1. START 2. RECEIVING 3. END - */ -class RsGxsNetService : - public RsNetworkExchangeService, public p3ThreadedService, public p3Config -{ -public: - - static const uint32_t FRAGMENT_SIZE; - /*! - * only one observer is allowed - * @param servType service type - * @param gds The data service which allows read access to a service/store - * @param nxsObs observer will be notified whenever new messages/grps - * @param nxsObs observer will be notified whenever new messages/grps - * arrive - */ - RsGxsNetService(uint16_t servType, RsGeneralDataService *gds, - RsNxsNetMgr *netMgr, - RsNxsObserver *nxsObs, // used to be = NULL. - const RsServiceInfo serviceInfo, - RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL, - PgpAuxUtils *pgpUtils = NULL, RsGxsNetTunnelService *mGxsNT = NULL, - bool grpAutoSync = true, bool msgAutoSync = true,bool distSync=false, - uint32_t default_store_period = RS_GXS_DEFAULT_MSG_STORE_PERIOD, - uint32_t default_sync_period = RS_GXS_DEFAULT_MSG_REQ_PERIOD); - - virtual ~RsGxsNetService(); - - virtual RsServiceInfo getServiceInfo() override { return mServiceInfo; } - - virtual void getItemNames(std::map& names) const override ; - -public: - - - virtual uint16_t serviceType() const override { return mServType ; } - - /*! - * Use this to set how far back synchronisation and storage of messages should take place - * @param age the max age a sync/storage item can to be allowed in a synchronisation - */ - virtual void setSyncAge(const RsGxsGroupId& grpId,uint32_t age_in_secs)override ; - virtual void setKeepAge(const RsGxsGroupId& grpId,uint32_t age_in_secs)override ; - - virtual uint32_t getSyncAge(const RsGxsGroupId& id)override ; - virtual uint32_t getKeepAge(const RsGxsGroupId& id)override ; - - virtual uint32_t getDefaultSyncAge() override { return mDefaultMsgSyncPeriod ; } - virtual uint32_t getDefaultKeepAge() override { return mDefaultMsgStorePeriod ; } - - virtual void setDefaultKeepAge(uint32_t t) override { mDefaultMsgStorePeriod = t ; } - virtual void setDefaultSyncAge(uint32_t t) override { mDefaultMsgSyncPeriod = t ; } - - virtual bool msgAutoSync() const override { return mAllowMsgSync; } - virtual bool grpAutoSync() const override { return mGrpAutoSync; } - /*! - * \brief Search methods. - * These four methods are used to request distant search and receive the results. - * \param group_id - */ - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id)override ; - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string)override ; - - virtual bool search(const std::string& substring,std::list& group_infos) override ; - virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)override ; - virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos)override ; - virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)override ; - - virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &group_infos)override ; - virtual bool clearDistantSearchResults(const TurtleRequestId& id)override ; - virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&, RsGxsGroupSearchResults &)override ; - virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId&) override ; - - /*! - * pauses synchronisation of subscribed groups and request for group id - * from peers - * @param enabled set to false to disable pause, and true otherwise - */ - // NOT IMPLEMENTED - virtual void pauseSynchronisation(bool enabled)override ; - - - /*! - * Request for this message is sent through to peers on your network - * and how many hops from them you've indicated - * @param msgId the messages to retrieve - * @return request token to be redeemed - */ - virtual int requestMsg(const RsGxsGrpMsgIdPair& /* msgId */)override { return 0;} - - /*! - * Request for this group is sent through to peers on your network - * and how many hops from them you've indicated - * @param enabled set to false to disable pause, and true otherwise - * @return request token to be redeemed - */ - virtual int requestGrp(const std::list& grpId, const RsPeerId& peerId)override ; - - /*! - * share publish keys for the specified group with the peers in the specified list. - */ - - virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::set& peers) override ; - - /*! - * Returns statistics for the group networking activity: popularity (number of friends subscribers) and max_visible_msg_count, - * that is the max nnumber of messages reported by a friend. - */ - virtual bool getGroupNetworkStats(const RsGxsGroupId& id,RsGroupNetworkStats& stats) override ; - - /*! - * Used to inform the net service that we changed subscription status. That helps - * optimising data transfer when e.g. unsubsribed groups are updated less often, etc - */ - virtual void subscribeStatusChanged(const RsGxsGroupId& id,bool subscribed) override ; - - virtual void rejectMessage(const RsGxsMessageId& msg_id) override ; - - virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) override ; - virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) override ; - virtual bool removeGroups(const std::list& groups)override ; - virtual bool isDistantPeer(const RsPeerId& pid)override ; - - /* p3Config methods */ -public: - - bool loadList(std::list& load)override ; - bool saveList(bool &cleanup, std::list&)override ; - RsSerialiser *setupSerialiser()override ; - -public: - - /*! - * initiates synchronisation - */ - int tick()override ; - - void threadTick() override; /// @see RsTickingThread - -private: - - /*! - * called when - * items are deemed to be waiting in p3Service item queue - */ - void recvNxsItemQueue(); - - - /** S: Transaction processing **/ - - /*! - * These process transactions which are in a wait state - * Also moves transaction which have been completed to - * the completed transactions list - */ - void processTransactions(); - - /*! - * Process completed transaction, which either simply - * retires a transaction or additionally generates a response - * to the completed transaction - */ - void processCompletedTransactions(); - - /*! - * Process transaction owned/started by user - * @param tr transaction to process, ownership stays with callee - */ - void locked_processCompletedOutgoingTrans(NxsTransaction* tr); - - /*! - * Process transactions started/owned by other peers - * @param tr transaction to process, ownership stays with callee - */ - void locked_processCompletedIncomingTrans(NxsTransaction* tr); - - - /*! - * Process a transaction item, assumes a general lock - * @param item the transaction item to process - * @return false ownership of item left with callee - */ - bool locked_processTransac(RsNxsTransacItem* item); - - /*! - * This adds a transaction - * completeted transaction list - * If this is an outgoing transaction, transaction id is - * decrement - * @param trans transaction to add - */ - void locked_completeTransaction(NxsTransaction* trans); - - /*! - * \brief locked_stampMsgServerUpdateTS - * updates the server msg time stamp. This function is the locked method for the one above with similar name - * \param gid group id to stamp. - * \return - */ - bool locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid); - /*! - * This retrieves a unique transaction id that - * can be used in an outgoing transaction - */ - uint32_t locked_getTransactionId(); - - /*! - * This attempts to push the transaction id counter back if you have - * active outgoing transactions in play - */ - bool attemptRecoverIds(); - - /*! - * The cb listener is the owner of the grps - * @param grps - */ - //void notifyListenerGrps(std::list& grps); - - /*! - * The cb listener is the owner of the msgs - * @param msgs - */ - //void notifyListenerMsgs(std::list& msgs); - - /*! - * Generates new transaction to send msg requests based on list - * of msgs received from peer stored in passed transaction - * @param tr transaction responsible for generating msg request - */ - void locked_genReqMsgTransaction(NxsTransaction* tr); - - /*! - * Generates new transaction to send grp requests based on list - * of grps received from peer stored in passed transaction - * @param tr transaction responsible for generating grp request - */ - void locked_genReqGrpTransaction(NxsTransaction* tr); - - /*! - * This first checks if one can send a grpId based circles - * If it can send, then it call locked_genSendMsgsTransaction - * @param tr transaction responsible for generating grp request - * @see locked_genSendMsgsTransaction - */ - void locked_checkSendMsgsTransaction(NxsTransaction* tr); - - /*! - * Generates new transaction to send msg data based on list - * of grpids received from peer stored in passed transaction - * @param tr transaction responsible for generating grp request - */ - void locked_genSendMsgsTransaction(NxsTransaction* tr); - - /*! - * Generates new transaction to send grp data based on list - * of grps received from peer stored in passed transaction - * @param tr transaction responsible for generating grp request - */ - void locked_genSendGrpsTransaction(NxsTransaction* tr); - - /*! - * convenience function to add a transaction to list - * @param tr transaction to add - */ - bool locked_addTransaction(NxsTransaction* tr); - - void cleanTransactionItems(NxsTransaction* tr) const; - - /*! - * @param tr the transaction to check for timeout - * @return false if transaction has timed out, true otherwise - */ - bool locked_checkTransacTimedOut(NxsTransaction* tr); - - /** E: Transaction processing **/ - - /** S: item handlers **/ - - /*! - * This attempts handles transaction items - * ownership of item is left with callee if this method returns false - * @param item transaction item to handle - * @return false if transaction could not be handled, ownership of item is left with callee - */ - bool handleTransaction(RsNxsItem* item); - - /*! - * Handles an nxs item for group synchronisation - * by startin a transaction and sending a list - * of groups held by user - * @param item contains grp sync info - */ - void handleRecvSyncGroup(RsNxsSyncGrpReqItem* item); - - /*! - * Handles an nxs item for group statistics - * @param item contaims update time stamp and number of messages - */ - void handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs); - - /*! - * Handles an nxs item for msgs synchronisation - * @param item contaims msg sync info - */ - void handleRecvSyncMessage(RsNxsSyncMsgReqItem* item,bool item_was_encrypted); - - /*! - * Handles an nxs item for group publish key - * @param item contaims keys/grp info - */ - void handleRecvPublishKeys(RsNxsGroupPublishKeyItem*) ; - - /** E: item handlers **/ - - - void runVetting(); - - /*! - * @param peerId The peer to vet to see if they can receive this groupid - * @param grpMeta this is the meta item to determine if it can be sent to given peer - * @param toVet groupid/peer to vet are stored here if their circle id is not cached - * @return false, if you cannot send to this peer, true otherwise - */ - bool canSendGrpId(const RsPeerId& sslId, const RsGxsGrpMetaData& grpMeta, std::vector& toVet, bool &should_encrypt); - bool canSendMsgIds(std::vector > &msgMetas, const RsGxsGrpMetaData&, const RsPeerId& sslId, RsGxsCircleId &should_encrypt_id); - - /*! - * \brief checkPermissionsForFriendGroup - * Checks that we can send/recv from that node, given that the grpMeta has a distribution limited to a local circle. - * \param sslId Candidate peer to send to or to receive from. - * \param grpMeta Contains info about the group id, internal circle id, etc. - * \return true only when the internal exists and validates as a friend node group, and contains the owner of sslId. - */ - bool checkPermissionsForFriendGroup(const RsPeerId& sslId,const RsGxsGrpMetaData& grpMeta) ; - - bool checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxsGrpMetaData& meta, RsGxsCircleId& should_encrypt_id); - - void locked_createTransactionFromPending(MsgRespPending* grpPend); - void locked_createTransactionFromPending(GrpRespPending* msgPend); - bool locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend) ; - bool locked_createTransactionFromPending(MsgCircleIdsRequestVetting* grpPend) ; - - void locked_pushGrpTransactionFromList(std::list& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a grp list request - void locked_pushMsgTransactionFromList(std::list& reqList, const RsPeerId& peerId, const uint32_t& transN); // forms a msg list request - void locked_pushGrpRespFromList(std::list& respList, const RsPeerId& peer, const uint32_t& transN); - void locked_pushMsgRespFromList(std::list& itemL, const RsPeerId& sslId, const RsGxsGroupId &grp_id, const uint32_t& transN); - - void checkDistantSyncState(); - void syncWithPeers(); - void syncGrpStatistics(); - void addGroupItemToList(NxsTransaction*& tr, - const RsGxsGroupId& grpId, uint32_t& transN, - std::list& reqList); - - //bool locked_canReceive(const RsGxsGrpMetaData * const grpMeta, const RsPeerId& peerId); - - void processExplicitGroupRequests(); - - void locked_doMsgUpdateWork(const RsNxsTransacItem* nxsTrans, const RsGxsGroupId& grpId); - - void updateServerSyncTS(); -#ifdef TO_REMOVE - void updateClientSyncTS(); -#endif - - bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item); - bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known); - void locked_resetClientTS(const RsGxsGroupId& grpId); - bool locked_checkResendingOfUpdates(const RsPeerId& pid, const RsGxsGroupId &grpId, rstime_t incoming_ts, RsPeerUpdateTsRecord& rec); - - static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ; - - RsGxsGrpConfig& locked_getGrpConfig(const RsGxsGroupId& grp_id); -private: - - typedef std::vector GrpFragments; - typedef std::vector MsgFragments; - - /*! - * Loops over pending publish key orders. - */ - void sharePublishKeysPending() ; - - /*! - * Fragment a message into individual fragments which are at most 150kb - * @param msg message to fragment - * @param msgFragments fragmented message - * @return false if fragmentation fails true otherwise - */ - bool fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const; - - /*! - * Fragment a group into individual fragments which are at most 150kb - * @param grp group to fragment - * @param grpFragments fragmented group - * @return false if fragmentation fails true other wise - */ - bool fragmentGrp(RsNxsGrp& grp, GrpFragments& grpFragments) const; - - /*! - * Fragment a message into individual fragments which are at most 150kb - * @param msg message to fragment - * @param msgFragments fragmented message - * @return NULL if not possible to reconstruct message from fragment, - * pointer to defragments nxs message is possible - */ - RsNxsMsg* deFragmentMsg(MsgFragments& msgFragments) const; - - /*! - * Fragment a group into individual fragments which are at most 150kb - * @param grp group to fragment - * @param grpFragments fragmented group - * @return NULL if not possible to reconstruct group from fragment, - * pointer to defragments nxs group is possible - */ - RsNxsGrp* deFragmentGrp(GrpFragments& grpFragments) const; - - - /*! - * Note that if all fragments for a message are not found then its fragments are dropped - * @param fragments message fragments which are not necessarily from the same message - * @param partFragments the partitioned fragments (into message ids) - */ - void collateMsgFragments(MsgFragments &fragments, std::map& partFragments) const; - - /*! - * Note that if all fragments for a group are not found then its fragments are dropped - * @param fragments group fragments which are not necessarily from the same group - * @param partFragments the partitioned fragments (into message ids) - */ - void collateGrpFragments(GrpFragments fragments, std::map& partFragments) const; - - /*! - * stamp the group info from that particular peer at the given time. - */ - - void locked_stampPeerGroupUpdateTime(const RsPeerId& pid,const RsGxsGroupId& grpId,rstime_t tm,uint32_t n_messages) ; - - /*! - * encrypts/decrypts the transaction for the destination circle id. - */ - bool encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId& destination_circle, const RsGxsGroupId &destination_group, RsNxsItem *& encrypted_item, uint32_t &status) ; - bool decryptSingleNxsItem(const RsNxsEncryptedDataItem *encrypted_item, RsNxsItem *&nxsitem, std::vector *private_keys=NULL); - bool processTransactionForDecryption(NxsTransaction *tr); // return false when the keys are not loaded => need retry later - - void cleanRejectedMessages(); - void processObserverNotifications(); - - void generic_sendItem(RsNxsItem *si); - RsItem *generic_recvItem(); - -private: - - static void locked_checkDelay(uint32_t& time_in_secs); - - /*** transactions ***/ - - /// active transactions - TransactionsPeerMap mTransactions; - - /// completed transactions - std::list mComplTransactions; - - /// transaction id counter - uint32_t mTransactionN; - - /*** transactions ***/ - - /*** synchronisation ***/ - std::list mSyncGrp; - std::list mSyncMsg; - /*** synchronisation ***/ - - RsNxsObserver* mObserver; - RsGeneralDataService* mDataStore; - uint16_t mServType; - - // how much time must elapse before a timeout failure - // for an active transaction - uint32_t mTransactionTimeOut; - - RsPeerId mOwnId; - - RsNxsNetMgr* mNetMgr; - - /// for other members save transactions - RsMutex mNxsMutex; - - uint32_t mSyncTs; - uint32_t mLastKeyPublishTs; - uint32_t mLastCleanRejectedMessages; - - const uint32_t mSYNC_PERIOD; - int mUpdateCounter ; - - RsGcxs* mCircles; - RsGixs *mGixs; - RsGixsReputation* mReputations; - PgpAuxUtils *mPgpUtils; - RsGxsNetTunnelService *mGxsNetTunnel; - - bool mGrpAutoSync; - bool mAllowMsgSync; - bool mAllowDistSync; - - // need to be verfied - std::vector mPendingResp; - std::vector mPendingCircleVets; - std::map > mPendingPublishKeyRecipients ; - std::map > mExplicitRequest; - std::map > mPartialMsgUpdates ; - - // nxs sync optimisation - // can pull dynamically the latest timestamp for each message - -public: - - typedef std::map ClientMsgMap; - typedef std::map ServerMsgMap; - typedef std::map ClientGrpMap; - typedef std::map GrpConfigMap; -private: - - ClientMsgMap mClientMsgUpdateMap; - ServerMsgMap mServerMsgUpdateMap; - ClientGrpMap mClientGrpUpdateMap; - GrpConfigMap mServerGrpConfigMap; - - RsGxsServerGrpUpdate mGrpServerUpdate; - RsServiceInfo mServiceInfo; - - std::map mRejectedMessages; - - std::vector mNewGroupsToNotify ; - std::vector mNewMessagesToNotify ; - std::set mNewStatsToNotify ; - std::set mNewPublishKeysToNotify ; - std::set mNewGrpSyncParamsToNotify ; - - // Distant search result map - std::map > mDistantSearchResults ; - - void debugDump(); - - uint32_t mDefaultMsgStorePeriod ; - uint32_t mDefaultMsgSyncPeriod ; - - std::map mGroupHashCache; - std::map mSearchRequests; - std::map mSearchedGroups ; - rstime_t mLastCacheReloadTS ; - - bool mUseMetaCache; -}; - -#endif // RSGXSNETSERVICE_H diff --git a/libretroshare/src/gxs/rsgxsnettunnel.cc b/libretroshare/src/gxs/rsgxsnettunnel.cc deleted file mode 100644 index 380491c5d..000000000 --- a/libretroshare/src/gxs/rsgxsnettunnel.cc +++ /dev/null @@ -1,1180 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxsnettunnel.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsdir.h" -#include "util/rstime.h" -#include "retroshare/rspeers.h" -#include "serialiser/rstypeserializer.h" -#include "gxs/rsnxs.h" -#include "rsgxsnettunnel.h" - -//#define DEBUG_RSGXSNETTUNNEL 1 - -#define GXS_NET_TUNNEL_NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; } -#define GXS_NET_TUNNEL_DEBUG() std::cerr << time(NULL) << " : GXS_NET_TUNNEL: " << __FUNCTION__ << " : " -#define GXS_NET_TUNNEL_ERROR() std::cerr << "(EE) GXS_NET_TUNNEL ERROR : " - -static const uint32_t RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_DATA = 1; -static const uint32_t RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH = 100; - -RsGxsDistSync *rsGxsDistSync = NULL; - -RsGxsNetTunnelService::RsGxsNetTunnelService(): mGxsNetTunnelMtx("GxsNetTunnel") -{ - mRandomBias.clear(); - - mLastKeepAlive = time(NULL) + (RSRandom::random_u32()%20); // adds some variance in order to avoid doing all this tasks at once across services - mLastAutoWash = time(NULL) + (RSRandom::random_u32()%20); - mLastDump = time(NULL) + (RSRandom::random_u32()%20); -} - -//===========================================================================================================================================// -// Transport Items // -//===========================================================================================================================================// - -const uint16_t RS_SERVICE_TYPE_GXS_NET_TUNNEL = 0x2233 ; - -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER = 0x01 ; -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE = 0x02 ; -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_RANDOM_BIAS = 0x03 ; -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING = 0x04 ; -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST = 0x05 ; -// const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY = 0x06; // DEPRECATED -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA = 0x07 ; -const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY = 0x08; - -class RsGxsNetTunnelItem: public RsItem -{ -public: - explicit RsGxsNetTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_NET_TUNNEL,item_subtype) - { - // no priority. All items are encapsulated into generic Turtle items anyway. - } - - virtual ~RsGxsNetTunnelItem() {} - virtual void clear() {} -}; - -class RsGxsNetTunnelVirtualPeerItem: public RsGxsNetTunnelItem -{ -public: - RsGxsNetTunnelVirtualPeerItem() :RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER) {} - - virtual ~RsGxsNetTunnelVirtualPeerItem() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,virtual_peer_id,"virtual_peer_id") ; - } - - RsPeerId virtual_peer_id ; -}; - -class RsGxsNetTunnelKeepAliveItem: public RsGxsNetTunnelItem -{ -public: - RsGxsNetTunnelKeepAliveItem() :RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE) {} - - virtual ~RsGxsNetTunnelKeepAliveItem() {} - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) {} -}; - -class RsGxsNetTunnelRandomBiasItem: public RsGxsNetTunnelItem -{ -public: - explicit RsGxsNetTunnelRandomBiasItem() : RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_RANDOM_BIAS) { clear();} - virtual ~RsGxsNetTunnelRandomBiasItem() {} - - virtual void clear() { mRandomBias.clear() ; } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,mRandomBias,"random bias") ; - } - - Bias20Bytes mRandomBias; // Cannot be a simple char[] because of serialization. -}; - -class RsGxsNetTunnelTurtleSearchSubstringItem: public RsGxsNetTunnelItem -{ -public: - explicit RsGxsNetTunnelTurtleSearchSubstringItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING) {} - virtual ~RsGxsNetTunnelTurtleSearchSubstringItem() {} - - uint16_t service ; - std::string substring_match ; - - virtual void clear() { substring_match.clear() ; } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,service,"service") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_KEY,substring_match,"substring_match") ; - } -}; - -class RsGxsNetTunnelTurtleSearchGroupRequestItem: public RsGxsNetTunnelItem -{ -public: - explicit RsGxsNetTunnelTurtleSearchGroupRequestItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST) {} - virtual ~RsGxsNetTunnelTurtleSearchGroupRequestItem() {} - - uint16_t service ; - Sha1CheckSum hashed_group_id ; - - virtual void clear() { hashed_group_id.clear() ; } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,service,"service") ; - RsTypeSerializer::serial_process(j,ctx,hashed_group_id,"hashed_group_id") ; - } -}; - -class RsGxsNetTunnelTurtleSearchGroupSummaryItem: public RsGxsNetTunnelItem -{ -public: - explicit RsGxsNetTunnelTurtleSearchGroupSummaryItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY) {} - virtual ~RsGxsNetTunnelTurtleSearchGroupSummaryItem() {} - - uint16_t service ; - std::list group_infos; - - virtual void clear() { group_infos.clear() ; } - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,service,"service") ; - RsTypeSerializer::serial_process(j,ctx,group_infos,"group_infos") ; - } -}; -class RsGxsNetTunnelTurtleSearchGroupDataItem: public RsGxsNetTunnelItem -{ -public: - explicit RsGxsNetTunnelTurtleSearchGroupDataItem() - : RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA), - encrypted_group_data(NULL), - encrypted_group_data_len(0) - {} - - virtual ~RsGxsNetTunnelTurtleSearchGroupDataItem() {} - - uint16_t service ; - unsigned char *encrypted_group_data ; - uint32_t encrypted_group_data_len ; - - virtual void clear() { free(encrypted_group_data);encrypted_group_data=NULL;encrypted_group_data_len=0; } - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,service,"service") ; - - RsTypeSerializer::TlvMemBlock_proxy prox(encrypted_group_data,encrypted_group_data_len) ; - RsTypeSerializer::serial_process(j,ctx,prox,"encrypted_group_data") ; - } -}; - -class RsGxsNetTunnelSerializer: public RsServiceSerializer -{ -public: - RsGxsNetTunnelSerializer() :RsServiceSerializer(RS_SERVICE_TYPE_GXS_NET_TUNNEL) {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const - { - if(service != RS_SERVICE_TYPE_GXS_NET_TUNNEL) - { - GXS_NET_TUNNEL_ERROR() << "received item with wrong service ID " << std::hex << service << std::dec << std::endl; - return NULL ; - } - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER : return new RsGxsNetTunnelVirtualPeerItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE : return new RsGxsNetTunnelKeepAliveItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_RANDOM_BIAS : return new RsGxsNetTunnelRandomBiasItem ; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING : return new RsGxsNetTunnelTurtleSearchSubstringItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST : return new RsGxsNetTunnelTurtleSearchGroupRequestItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY : return new RsGxsNetTunnelTurtleSearchGroupSummaryItem; - case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem; - default: - GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << (int)item_subtype << std::dec << " is not handled!" << std::endl; - return NULL ; - } - } -}; - -//===========================================================================================================================================// -// Interface with rest of the software // -//===========================================================================================================================================// - -uint16_t RsGxsNetTunnelService::serviceId() const -{ - return RS_SERVICE_TYPE_GXS_NET_TUNNEL; -} - -bool RsGxsNetTunnelService::registerSearchableService(RsNetworkExchangeService *gxs_service) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - mSearchableServices[gxs_service->serviceType()] = gxs_service ; - - return true; -} - -class DataAutoDelete -{ -public: - DataAutoDelete(unsigned char *& data) : mData(data) {} - ~DataAutoDelete() { free(mData); mData=NULL ; } - unsigned char *& mData; -}; - -RsGxsNetTunnelService::~RsGxsNetTunnelService() -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - // This is needed because we need to clear these structure in a mutex protected environment - // Also this calls the destructor of the objects which calls the freeing of memory e.g. allocated in the incoming data list. - - mGroups.clear(); - mHandledHashes.clear(); - mVirtualPeers.clear(); - - for(auto it(mIncomingData.begin());it!=mIncomingData.end();++it) - for(auto it2(it->second.begin());it2!=it->second.end();++it2) - delete it2->second; - - mIncomingData.clear(); -} - -bool RsGxsNetTunnelService::isDistantPeer(const RsGxsNetTunnelVirtualPeerId& virtual_peer, RsGxsGroupId& group_id) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - auto it = mVirtualPeers.find(virtual_peer) ; - - if(it != mVirtualPeers.end()) - { - group_id = it->second.group_id ; - return true ; - } - else - return false ; -} - -bool RsGxsNetTunnelService::receiveTunnelData(uint16_t service_id, unsigned char *& data, uint32_t& data_len, RsGxsNetTunnelVirtualPeerId& virtual_peer) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - std::list >& lst(mIncomingData[service_id]); - - if(lst.empty()) - { - data = NULL; - data_len = 0; - return false ; - } - - data = (unsigned char*)lst.front().second->bin_data ; - data_len = lst.front().second->bin_len ; - virtual_peer = lst.front().first; - - lst.front().second->bin_data = NULL ; // avoids deletion - lst.front().second->bin_len = 0 ; // avoids deletion - - delete lst.front().second; - lst.pop_front(); - - return true; -} - -bool RsGxsNetTunnelService::sendTunnelData(uint16_t /* service_id */,unsigned char *& data,uint32_t data_len,const RsGxsNetTunnelVirtualPeerId& virtual_peer) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - // The item is serialized and encrypted using chacha20+SHA256, using the generic turtle encryption, and then sent to the turtle router. - - DataAutoDelete iad(data) ; // This ensures the item is deleted whatsoever when leaving - - // 1 - find the virtual peer and the proper master key to encrypt with, and check that all the info is known - - auto it = mVirtualPeers.find(virtual_peer) ; - - if(it == mVirtualPeers.end()) - { - GXS_NET_TUNNEL_ERROR() << "cannot find virtual peer " << virtual_peer << ". Data is dropped." << std::endl; - return false ; - } - - if(it->second.vpid_status != RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE) - { - GXS_NET_TUNNEL_ERROR() << "virtual peer " << virtual_peer << " is not active. Data is dropped." << std::endl; - return false ; - } - - // 2 - encrypt and send the item. - - RsTurtleGenericDataItem *encrypted_turtle_item = NULL ; - - if(!p3turtle::encryptData(data,data_len,it->second.encryption_master_key,encrypted_turtle_item)) - { - GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl; - return false ; - } - - mTurtle->sendTurtleData(it->second.turtle_virtual_peer_id,encrypted_turtle_item) ; - - return true ; -} - -bool RsGxsNetTunnelService::getVirtualPeers(std::list& peers) -{ - // This function has two effects: - // - return the virtual peers for this group - // - passively set the group as "managed", so that it we answer tunnel requests. - - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - // update the hash entry if needed - - for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it) - peers.push_back(it->first) ; - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " returning " << peers.size() << " peers." << std::endl; -#endif - - return true ; -} - -bool RsGxsNetTunnelService::requestDistantPeers(uint16_t service_id, const RsGxsGroupId& group_id) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - // Now ask the turtle router to manage a tunnel for that hash. - - RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ; - - if(ginfo.group_policy < RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE) - ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE; - - ginfo.hash = calculateGroupHash(group_id) ; - ginfo.service_id = service_id; - - mHandledHashes[ginfo.hash] = group_id ; - - // we dont set the group policy here. It will only be set if no peers, or too few peers are available. -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " requesting peers for group " << group_id << std::endl; -#endif - - return true; -} - -bool RsGxsNetTunnelService::releaseDistantPeers(uint16_t /* service_id */,const RsGxsGroupId& group_id) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - // Ask turtle router to stop requesting tunnels for that hash. - - RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ; - - ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE; - ginfo.hash = calculateGroupHash(group_id) ; - - mHandledHashes[ginfo.hash] = group_id ; // yes, we do not remove, because we're supposed to answer tunnel requests from other peers. - - mTurtle->stopMonitoringTunnels(ginfo.hash) ; - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " releasing peers for group " << group_id << std::endl; -#endif - return true; -} - -void RsGxsNetTunnelService::dump() const -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - static std::string group_status_str[4] = { - std::string("[UNKNOWN ]"), - std::string("[IDLE ]"), - std::string("[TUNNELS_REQUESTED]"), - std::string("[VPIDS_AVAILABLE ]") - }; - - static std::string group_policy_str[4] = { - std::string("[UNKNOWN ]"), - std::string("[PASSIVE ]"), - std::string("[ACTIVE ]"), - std::string("[REQUESTING]"), - }; - static std::string vpid_status_str[3] = { - std::string("[UNKNOWN ]"), - std::string("[TUNNEL_OK]"), - std::string("[ACTIVE ]") - }; - - std::cerr << "GxsNetTunnelService dump (this=" << (void*)this << ": " << std::endl; - std::cerr << " Managed GXS groups: " << std::endl; - - for(auto it(mGroups.begin());it!=mGroups.end();++it) - { - std::cerr << " " << it->first << " hash: " << it->second.hash << " policy: " << group_policy_str[it->second.group_policy] << " status: " << group_status_str[it->second.group_status] << " Last contact: " << time(NULL) - it->second.last_contact << " secs ago" << std::endl; - - if(!it->second.virtual_peers.empty()) - std::cerr << " virtual peers:" << std::endl; - for(auto it2(it->second.virtual_peers.begin());it2!=it->second.virtual_peers.end();++it2) - std::cerr << " " << *it2 << std::endl; - } - - std::cerr << " Virtual peers: " << std::endl; - for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it) - std::cerr << " GXS Peer:" << it->first << " Turtle:" << it->second.turtle_virtual_peer_id - << " status: " << vpid_status_str[it->second.vpid_status] - << " group_id: " << it->second.group_id - << " direction: " << (int)it->second.side - << " last seen " << time(NULL)-it->second.last_contact << " secs ago" - << " ekey: " << RsUtil::BinToHex(it->second.encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE,10) << std::endl; - - std::cerr << " Virtual peer turtle => GXS conversion table: " << std::endl; - for(auto it(mTurtle2GxsPeer.begin());it!=mTurtle2GxsPeer.end();++it) - std::cerr << " " << it->first << " => " << it->second << std::endl; - - std::cerr << " Hashes: " << std::endl; - for(auto it(mHandledHashes.begin());it!=mHandledHashes.end();++it) - std::cerr << " hash: " << it->first << " GroupId: " << it->second << std::endl; - - std::cerr << " Incoming data: " << std::endl; - for(auto it(mIncomingData.begin());it!=mIncomingData.end();++it) - { - std::cerr << " service " << std::hex << it->first << std::dec << std::endl; - - for(auto it2(it->second.begin());it2!=it->second.end();++it2) - std::cerr << " peer id " << it2->first << " " << (void*)it2->second << std::endl; - } -} - -//===========================================================================================================================================// -// Interaction with Turtle Router // -//===========================================================================================================================================// - -void RsGxsNetTunnelService::connectToTurtleRouter(p3turtle *tr) -{ - mTurtle = tr ; - mTurtle->registerTunnelService(this) ; -} - -bool RsGxsNetTunnelService::handleTunnelRequest(const RsFileHash &hash,const RsPeerId& /* peer_id */) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - // We simply check for wether a managed group has a hash that corresponds to the given hash. - - return mHandledHashes.find(hash) != mHandledHashes.end(); -} - -void RsGxsNetTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *item, const RsFileHash& hash, const RsPeerId& turtle_virtual_peer_id, RsTurtleGenericTunnelItem::Direction direction) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " received turtle data for vpid " << turtle_virtual_peer_id << " for hash " << hash << " in direction " << (int)direction << std::endl; -#endif - - if(item->PacketSubType() != RS_TURTLE_SUBTYPE_GENERIC_DATA) - { - GXS_NET_TUNNEL_ERROR() << "item with type " << std::hex << item->PacketSubType() << std::dec << " received by GxsNetTunnel, but is not handled!" << std::endl; - return; - } - // find the group id - - auto it4 = mHandledHashes.find(hash) ; - - if(it4 == mHandledHashes.end()) - { - GXS_NET_TUNNEL_ERROR() << "Cannot find hash " << hash << " to be handled by GxsNetTunnel" << std::endl; - return; - } - RsGxsGroupId group_id = it4->second; - - // Now check if we got an item to advertise a virtual peer - - unsigned char *data = NULL ; - uint32_t data_size = 0 ; - - // generate the decryption key based on virtual peer id and group id - - uint8_t encryption_master_key[RS_GXS_TUNNEL_CONST_EKEY_SIZE] ; - - generateEncryptionKey(group_id,turtle_virtual_peer_id,encryption_master_key); - - if(!p3turtle::decryptItem(static_cast(item),encryption_master_key,data,data_size)) - { - GXS_NET_TUNNEL_ERROR() << "Cannot decrypt data!" << std::endl; - - if(data) - free(data) ; - - return ; - } - - uint16_t service_id = getRsItemService(getRsItemId(data)); - - if(service_id == RS_SERVICE_TYPE_GXS_NET_TUNNEL) - { - RsItem *decrypted_item = RsGxsNetTunnelSerializer().deserialise(data,&data_size); - RsGxsNetTunnelVirtualPeerItem *pid_item = dynamic_cast(decrypted_item) ; - - if(!pid_item) // this handles the case of a KeepAlive packet. - { - delete decrypted_item ; - free(data); - return ; - } - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " item is a virtual peer id item with vpid = "<< pid_item->virtual_peer_id - << " for group " << group_id << ". Setting virtual peer." << std::endl; -#endif - // we receive a virtual peer id, so we need to update the local information for this peer id - - mTurtle2GxsPeer[turtle_virtual_peer_id] = pid_item->virtual_peer_id ; - - RsGxsNetTunnelVirtualPeerInfo& vp_info(mVirtualPeers[pid_item->virtual_peer_id]) ; - delete pid_item; - - vp_info.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ; // status of the peer - vp_info.side = direction; // client/server - vp_info.last_contact = time(NULL); // last time some data was sent/recvd - vp_info.group_id = group_id; - vp_info.service_id = mGroups[group_id].service_id ; - - memcpy(vp_info.encryption_master_key,encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE); - - vp_info.turtle_virtual_peer_id = turtle_virtual_peer_id; // turtle peer to use when sending data to this vpid. - - free(data); - - return ; - } - - - // item is a generic data item for the client. Let's store the data in the appropriate incoming data queue. - - auto it = mTurtle2GxsPeer.find(turtle_virtual_peer_id) ; - - if(it == mTurtle2GxsPeer.end()) - { - GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for vpid " << turtle_virtual_peer_id << " but this vpid is unknown! Removing this vpid from group " << group_id << std::endl; - - // this situation is inconsistent: the first item that should go through the tunnel is a virtual peer info, so if we don't have one, it means that - // this virtual peer is dead. We should therefore remove it from the list of vpids for this group. - - mGroups[group_id].virtual_peers.erase(turtle_virtual_peer_id) ; - - free(data); - return; - } - - RsGxsNetTunnelVirtualPeerId gxs_vpid = it->second ; - - auto it2 = mVirtualPeers.find(gxs_vpid) ; - - if(it2 == mVirtualPeers.end()) - { - GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for GXS vpid " << gxs_vpid << " but the virtual peer id is missing!" << std::endl; - free(data); - return; - } - - if(service_id != it2->second.service_id && service_id != RS_SERVICE_GXS_TYPE_GXSID) - { - GXS_NET_TUNNEL_ERROR() << " received an item for VPID " << gxs_vpid << " openned for service " << it2->second.service_id << " that is not for that service nor for GXS Id service (service=" << std::hex << service_id << std::dec << ". Rejecting!" << std::endl; - free(data); - return ; - } - it2->second.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ; // status of the peer - it2->second.last_contact = time(NULL); // last time some data was sent/recvd from this peer - - mGroups[group_id].last_contact = time(NULL); // last time some data as received for this group - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << "item contains generic data for VPID " << gxs_vpid << ". service_id = " << std::hex << service_id << std::dec << ". Storing in incoming list" << std::endl; -#endif - - // push the data into the incoming data list - - RsTlvBinaryData *bind = new RsTlvBinaryData; - bind->tlvtype = 0; - bind->bin_len = data_size; - bind->bin_data = data; - - mIncomingData[service_id].push_back(std::make_pair(gxs_vpid,bind)) ; -} - -void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid,RsTurtleGenericTunnelItem::Direction dir) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - auto it = mHandledHashes.find(hash) ; - - if(it == mHandledHashes.end()) - { - std::cerr << "RsGxsNetTunnelService::addVirtualPeer(): error! hash " << hash << " is not handled. Cannot add vpid " << vpid << " in direction " << dir << std::endl; - return ; - } - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " adding virtual peer " << vpid << " for hash " << hash << " in direction " << dir << std::endl; -#endif - const RsGxsGroupId group_id(it->second) ; - - RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ; - ginfo.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE ; - ginfo.virtual_peers.insert(vpid); - - uint8_t encryption_master_key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]; - - generateEncryptionKey(group_id,vpid,encryption_master_key ); - - // We need to send our own virtual peer id to the other end of the tunnel - - RsGxsNetTunnelVirtualPeerId net_service_virtual_peer = locked_makeVirtualPeerId(group_id); - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " sending back virtual peer name " << net_service_virtual_peer << " to end of tunnel" << std::endl; -#endif - RsGxsNetTunnelVirtualPeerItem pitem ; - pitem.virtual_peer_id = net_service_virtual_peer ; - - RsTemporaryMemory tmpmem( RsGxsNetTunnelSerializer().size(&pitem) ) ; - uint32_t len = tmpmem.size(); - - RsGxsNetTunnelSerializer().serialise(&pitem,tmpmem,&len); - - RsTurtleGenericDataItem *encrypted_turtle_item = NULL ; - - if(p3turtle::encryptData(tmpmem,len,encryption_master_key,encrypted_turtle_item)) - mPendingTurtleItems.push_back(std::make_pair(vpid,encrypted_turtle_item)) ; // we cannot send directly because of turtle mutex locked before calling addVirtualPeer. - else - GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl; -} - -void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid) -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " removing virtual peer " << vpid << " for hash " << hash << std::endl; -#endif - mTurtle2GxsPeer.erase(vpid); - - auto it = mHandledHashes.find(hash) ; - - if(it == mHandledHashes.end()) - { - std::cerr << "RsGxsNetTunnelService::removeVirtualPeer(): error! hash " << hash << " is not handled. Cannot remove vpid " << vpid << std::endl; - return ; - } - - const RsGxsGroupId group_id(it->second) ; - - RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ; - - ginfo.virtual_peers.erase(vpid); - - if(ginfo.virtual_peers.empty()) - { - ginfo.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE ; - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " no more virtual peers for group " << group_id << ": setting status to TUNNELS_REQUESTED" << std::endl; -#endif - } -} - -RsFileHash RsGxsNetTunnelService::calculateGroupHash(const RsGxsGroupId& group_id) const -{ - return RsDirUtil::sha1sum(group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ; -} - -void RsGxsNetTunnelService::generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) -{ - // The key is generated as H(group_id | vpid) - // Because group_id is not known it shouldn't be possible to recover the key by observing the traffic. - - assert(Sha256CheckSum::SIZE_IN_BYTES == 32) ; - - unsigned char mem[RsGxsGroupId::SIZE_IN_BYTES + TurtleVirtualPeerId::SIZE_IN_BYTES] ; - - memcpy(mem ,group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ; - memcpy(mem+RsGxsGroupId::SIZE_IN_BYTES,vpid.toByteArray() ,TurtleVirtualPeerId::SIZE_IN_BYTES) ; - - memcpy( key, RsDirUtil::sha256sum(mem,RsGxsGroupId::SIZE_IN_BYTES+TurtleVirtualPeerId::SIZE_IN_BYTES).toByteArray(), RS_GXS_TUNNEL_CONST_EKEY_SIZE ) ; -} - -//===========================================================================================================================================// -// Service parts // -//===========================================================================================================================================// - -void RsGxsNetTunnelService::threadTick() -{ - while(!mPendingTurtleItems.empty()) - { - auto& it(mPendingTurtleItems.front()); - - mTurtle->sendTurtleData(it.first,it.second) ; - mPendingTurtleItems.pop_front(); - } - - rstime_t now = time(NULL); - - // cleanup - - if(mLastAutoWash + 5 < now) - { - autowash(); - mLastAutoWash = now; - } - - if(mLastKeepAlive + 20 < now) - { - mLastKeepAlive = now ; - sendKeepAlivePackets() ; - } - -#ifdef DEBUG_RSGXSNETTUNNEL - if(mLastDump + 10 < now) - { - mLastDump = now; - dump(); - } -#endif - - for(uint32_t i=0;i<2;++i) - { - if(shouldStop()) - return; - rstime::rs_usleep(500*1000) ; // 1 sec - } -} - -const Bias20Bytes& RsGxsNetTunnelService::locked_randomBias() -{ - if(mRandomBias.isNull()) - { - mRandomBias = Bias20Bytes::random(); - IndicateConfigChanged(); - - std::cerr << "Initialized RsGxsNetTunnel random bias to " << RsUtil::BinToHex(mRandomBias.toByteArray(),mRandomBias.SIZE_IN_BYTES) << std::endl; - } - - return mRandomBias ; -} - -RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::locked_makeVirtualPeerId(const RsGxsGroupId& group_id) -{ - assert(RsPeerId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;// so that we can build the virtual PeerId from a SHA1 sum. - - // We compute sha1( GroupId | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId - - Bias20Bytes rb(locked_randomBias()); - - unsigned char mem[group_id.SIZE_IN_BYTES + rb.SIZE_IN_BYTES]; - - memcpy(mem ,group_id.toByteArray(),group_id.SIZE_IN_BYTES) ; - memcpy(mem+group_id.SIZE_IN_BYTES,rb.toByteArray(),rb.SIZE_IN_BYTES) ; - - return RsGxsNetTunnelVirtualPeerId(RsDirUtil::sha1sum(mem,group_id.SIZE_IN_BYTES+rb.SIZE_IN_BYTES).toByteArray()); -} - - -void RsGxsNetTunnelService::sendKeepAlivePackets() -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " sending keep-alive packets. " << std::endl; -#endif - - // We send KA packets for each GXS virtual peer. The advantage is that unused tunnels will automatically die which eliminates duplicate tunnels - // automatically. We only send from the client side. - - for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it) - { - RsGxsNetTunnelVirtualPeerId own_gxs_vpid = locked_makeVirtualPeerId(it->second.group_id) ; - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " virtual peer " << it->first << " through tunnel " << it->second.turtle_virtual_peer_id << " for group " << it->second.group_id ; -#endif - - if(own_gxs_vpid < it->first) - { -#ifdef DEBUG_RSGXSNETTUNNEL - std::cerr << ": sent!" << std::endl; -#endif - RsGxsNetTunnelKeepAliveItem pitem ; - RsTemporaryMemory tmpmem( RsGxsNetTunnelSerializer().size(&pitem) ) ; - uint32_t len = tmpmem.size(); - - RsGxsNetTunnelSerializer().serialise(&pitem,tmpmem,&len); - - RsTurtleGenericDataItem *encrypted_turtle_item = NULL ; - - if(p3turtle::encryptData(tmpmem,len,it->second.encryption_master_key,encrypted_turtle_item)) - mPendingTurtleItems.push_back(std::make_pair(it->second.turtle_virtual_peer_id,encrypted_turtle_item)) ; - - it->second.last_contact = time(NULL) ; - } -#ifdef DEBUG_RSGXSNETTUNNEL - else - std::cerr << ": ignored!" << std::endl; -#endif - } -} - -void RsGxsNetTunnelService::autowash() -{ - RS_STACK_MUTEX(mGxsNetTunnelMtx); - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " performing per-group consistency test." << std::endl; -#endif - for(auto it(mGroups.begin());it!=mGroups.end();++it) - { - RsGxsNetTunnelVirtualPeerId own_gxs_vpid = locked_makeVirtualPeerId(it->first) ; - RsGxsNetTunnelGroupInfo& ginfo(it->second) ; - bool should_monitor_tunnels = false ; - -#ifdef DEBUG_RSGXSNETTUNNEL - GXS_NET_TUNNEL_DEBUG() << " group " << it->first << ": " ; -#endif - // check whether the group already has GXS virtual peers with suppliers. If so, we can set the GRP policy as passive. - - if(ginfo.group_policy >= RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE) - { - bool found = false ; - - // check wether one virtual peer provided by GXS has ID > own ID. In this case we leave the priority to it. - - for(auto it2(ginfo.virtual_peers.begin());!found && it2!=ginfo.virtual_peers.end();++it2) - { - auto it3 = mTurtle2GxsPeer.find(*it2) ; - - if( it3 != mTurtle2GxsPeer.end() && it3->second < own_gxs_vpid) - found = true ; - } - - if(found) - { -#ifdef DEBUG_RSGXSNETTUNNEL - std::cerr << " active, with client-side peers : "; -#endif - should_monitor_tunnels = false ; - ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE ; - } - else - { - should_monitor_tunnels = true ; - ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING ; -#ifdef DEBUG_RSGXSNETTUNNEL - std::cerr << " active, and no client-side peers available : " ; -#endif - } - } -#ifdef DEBUG_RSGXSNETTUNNEL - else - std::cerr << " passive : "; -#endif - - // We should also check whether the group is supplied using another tunnel. If so, no need to request tunnels. - // Otherwise the engine will keep requesting tunnels for all groups. -#warning CODE MISSING HERE - - if(should_monitor_tunnels) - { -#ifdef DEBUG_RSGXSNETTUNNEL - std::cerr << " requesting tunnels" << std::endl; -#endif - mTurtle->monitorTunnels(ginfo.hash,this,false) ; - } - else - { -#ifdef DEBUG_RSGXSNETTUNNEL - std::cerr << " dropping tunnels" << std::endl; -#endif - mTurtle->stopMonitoringTunnels(ginfo.hash); - } - } -} - -bool RsGxsNetTunnelService::saveList(bool& cleanup, std::list& save) -{ - RsGxsNetTunnelRandomBiasItem *it2 = new RsGxsNetTunnelRandomBiasItem() ; - - { - RS_STACK_MUTEX(mGxsNetTunnelMtx); - it2->mRandomBias = mRandomBias; - std::cerr << "Saving RsGxsNetTunnel random bias to disc" << std::endl; - } - - save.push_back(it2) ; - cleanup = true ; - - return true; -} - -bool RsGxsNetTunnelService::loadList(std::list &load) -{ - RsGxsNetTunnelRandomBiasItem *rbsi ; - - for(auto it(load.begin());it!=load.end();++it) - { - if((rbsi = dynamic_cast(*it))!=NULL) - { - RS_STACK_MUTEX(mGxsNetTunnelMtx); - mRandomBias = rbsi->mRandomBias; - - std::cerr << "Loaded RsGxsNetTunnel random bias from disc: " << RsUtil::BinToHex(mRandomBias.toByteArray(),mRandomBias.SIZE_IN_BYTES) << std::endl; - } - else - GXS_NET_TUNNEL_ERROR() << " unknown item in config file: type=" << std::hex << (*it)->PacketId() << std::dec << std::endl; - - delete *it; - } - - return true; -} - -RsSerialiser *RsGxsNetTunnelService::setupSerialiser() -{ - RsSerialiser *ser = new RsSerialiser ; - ser->addSerialType(new RsGxsNetTunnelSerializer) ; - - return ser ; -} - -//===========================================================================================================================================// -// Turtle Search system // -//===========================================================================================================================================// - -TurtleRequestId RsGxsNetTunnelService::turtleGroupRequest(const RsGxsGroupId& group_id,RsNetworkExchangeService *client_service) -{ - Sha1CheckSum hashed_group_id = RsDirUtil::sha1sum(group_id.toByteArray(),group_id.SIZE_IN_BYTES) ; - - GXS_NET_TUNNEL_DEBUG() << ": starting a turtle group request for grp \"" << group_id << "\" hashed to \"" << hashed_group_id << "\"" << std::endl; - - RsGxsNetTunnelTurtleSearchGroupRequestItem search_item ; - search_item.hashed_group_id = hashed_group_id ; - search_item.service = client_service->serviceType() ; - - uint32_t size = RsGxsNetTunnelSerializer().size(&search_item) ; - unsigned char *mem = (unsigned char*)rs_malloc(size) ; - - if(mem == NULL) - return 0 ; - - RsGxsNetTunnelSerializer().serialise(&search_item,mem,&size); - - return mTurtle->turtleSearch(mem,size,this) ; -} - -TurtleRequestId RsGxsNetTunnelService::turtleSearchRequest(const std::string& match_string,RsNetworkExchangeService *client_service) -{ - GXS_NET_TUNNEL_DEBUG() << ": starting a turtle search request for string \"" << match_string << "\"" << std::endl; - - RsGxsNetTunnelTurtleSearchSubstringItem search_item ; - search_item.substring_match = match_string ; - search_item.service = client_service->serviceType() ; - - uint32_t size = RsGxsNetTunnelSerializer().size(&search_item) ; - unsigned char *mem = (unsigned char*)rs_malloc(size) ; - - if(mem == NULL) - return 0 ; - - RsGxsNetTunnelSerializer().serialise(&search_item,mem,&size); - - RS_STACK_MUTEX(mGxsNetTunnelMtx); - return mTurtle->turtleSearch(mem,size,this) ; -} - -bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_data,uint32_t search_request_data_len,unsigned char *& search_result_data,uint32_t& search_result_data_size,uint32_t& max_allowed_hits) -{ - GXS_NET_TUNNEL_DEBUG() << ": received a request." << std::endl; - - RsItem *item = RsGxsNetTunnelSerializer().deserialise(search_request_data,&search_request_data_len) ; - - RsGxsNetTunnelTurtleSearchSubstringItem *substring_sr = dynamic_cast(item) ; - - if(substring_sr != NULL) - { - GXS_NET_TUNNEL_DEBUG() << " : type is substring for service " << std::hex << (int)substring_sr->service << std::dec << std::endl; - - max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_SEARCH ; - - std::list results ; - - RS_STACK_MUTEX(mGxsNetTunnelMtx); - - auto it = mSearchableServices.find(substring_sr->service) ; - - if(it != mSearchableServices.end() && it->second->search(substring_sr->substring_match,results)) - { - RsGxsNetTunnelTurtleSearchGroupSummaryItem search_result_item ; - - GXS_NET_TUNNEL_DEBUG() << " : " << results.size() << " result found. Sending back." << std::endl; - - search_result_item.service = substring_sr->service ; - search_result_item.group_infos = results ; - - search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ; - search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ; - - delete item; - - if(search_result_data == NULL) - return false ; - - RsGxsNetTunnelSerializer().serialise(&search_result_item,search_result_data,&search_result_data_size); - - return true ; - } - } - - RsGxsNetTunnelTurtleSearchGroupRequestItem *substring_gr = dynamic_cast(item) ; - - if(substring_gr != NULL) - { - RS_STACK_MUTEX(mGxsNetTunnelMtx); - auto it = mSearchableServices.find(substring_gr->service) ; - - max_allowed_hits = RS_GXS_NET_TUNNEL_MAX_ALLOWED_HITS_GROUP_DATA ; - - unsigned char *encrypted_group_data = NULL ; - uint32_t encrypted_group_data_len = 0 ; - - if(it != mSearchableServices.end() && it->second->search(substring_gr->hashed_group_id,encrypted_group_data,encrypted_group_data_len)) - { - RsGxsNetTunnelTurtleSearchGroupDataItem search_result_item ; - - search_result_item.service = substring_gr->service ; - search_result_item.encrypted_group_data = encrypted_group_data ; - search_result_item.encrypted_group_data_len = encrypted_group_data_len; - - search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ; - search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ; - - if(search_result_data == NULL) - return false ; - - RsGxsNetTunnelSerializer().serialise(&search_result_item,search_result_data,&search_result_data_size); - - delete item; - return true ; - } - } - - delete item; - return false ; -} - -void RsGxsNetTunnelService::receiveSearchResult(TurtleSearchRequestId request_id,unsigned char *search_result_data,uint32_t search_result_data_len) -{ - RsItem *item = RsGxsNetTunnelSerializer().deserialise(search_result_data,&search_result_data_len); - - GXS_NET_TUNNEL_DEBUG() << " : received search result for search request " << std::hex << request_id << "" << std::endl; - - RsGxsNetTunnelTurtleSearchGroupSummaryItem *result_gs = dynamic_cast(item) ; - - if(result_gs != NULL) - { - GXS_NET_TUNNEL_DEBUG() << " : result is of type group summary result for service " << result_gs->service << std::dec << ": " << std::endl; - -#ifdef DEBUG_RSGXSNETTUNNEL - for(auto it(result_gs->group_infos.begin());it!=result_gs->group_infos.end();++it) - std::cerr << " group " << (*it).mGroupId << ": " << (*it).mGroupName << ", " << (*it).mNumberOfMessages << " messages, last is " << time(NULL)-(*it).mLastMessageTs << " secs ago." << std::endl; -#endif - - auto it = mSearchableServices.find(result_gs->service) ; - - if(it == mSearchableServices.end()) - { - GXS_NET_TUNNEL_ERROR() << ": deserialized item is for service " << std::hex << result_gs->service << std::dec << " that is not in the searchable services list." << std::endl; - delete item; - return ; - } - - it->second->receiveTurtleSearchResults(request_id,result_gs->group_infos) ; - - delete item; - return ; - } - - RsGxsNetTunnelTurtleSearchGroupDataItem *result_gd = dynamic_cast(item) ; - - if(result_gd != NULL) - { - GXS_NET_TUNNEL_DEBUG() << " : result is of type group data for service " << result_gd->service << std::dec << ": " << std::endl; - - auto it = mSearchableServices.find(result_gd->service) ; - - if(it == mSearchableServices.end()) - { - GXS_NET_TUNNEL_ERROR() << ": deserialized item is for service " << std::hex << result_gd->service << std::dec << " that is not in the searchable services list." << std::endl; - delete item; - return ; - } - - it->second->receiveTurtleSearchResults(request_id,result_gd->encrypted_group_data,result_gd->encrypted_group_data_len) ; - - result_gd->encrypted_group_data = NULL ; // prevents deletion - delete item; - - return ; - } - - GXS_NET_TUNNEL_ERROR() << ": deserialized item is of unknown type. Dropping!" << std::endl; -} - -void RsGxsNetTunnelService::getStatistics(std::map& groups, std::map& virtual_peers, std::map &turtle_vpid_to_net_tunnel_vpid, Bias20Bytes& bias ) const -{ - groups = mGroups ; - virtual_peers = mVirtualPeers ; - turtle_vpid_to_net_tunnel_vpid = mTurtle2GxsPeer; - bias = mRandomBias ; -} - - - - - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/gxs/rsgxsnettunnel.h b/libretroshare/src/gxs/rsgxsnettunnel.h deleted file mode 100644 index 7c18ab54c..000000000 --- a/libretroshare/src/gxs/rsgxsnettunnel.h +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: gxsnettunnel.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include - -#include "turtle/p3turtle.h" -#include "retroshare/rsgxsdistsync.h" - -/*! - * \brief The RsGxsNetTunnelService class takes care of requesting tunnels to the turtle router, through which it is possible to sync - * a particular GXS group. For each group, a set of virtual peers, corresponding to active tunnels will be made available - * to RsGxsNetService. - * - * It is the responsibility of RsGxsNetService to activate/desactivate tunnels for each particular group, depending on wether the group - * is already available at regular friends or not. - * - * Tunnel management is done at the level of groups rather than services, because we would like to keep the possibility to not - * request tunnels for some groups which do not need it, and only request tunnels for specific groups that cannot be provided - * by direct connections. - */ - -// Protocol: -// * request tunnels based on H(GroupId) -// * encrypt tunnel data using chacha20+HMAC-SHA256 using AEAD( GroupId, 96bits IV, tunnel ID ) (similar to what FT does) -// * when tunnel is established, exchange virtual peer names: vpid = H( GroupID | Random bias ) -// * when vpid is known, notify the client (GXS net service) which can use the virtual peer to sync -// * only use a single tunnel per virtual peer ID -// - -// Client ------------------ TR(H(GroupId)) --------------> Server | -// | Turtle -// Client <-------------------- T OK ---------------------- Server | -// - -// Here, a turtle vpid is known | [ addVirtualPeer() called by turtle ] -// - -// [Encrypted traffic using H(GroupId | Tunnel ID, 96bits IV)] | -// | -// Client <--------- VPID = H( Random IV | GroupId ) ------ Server | -// | | | -// +--------------> Mark the virtual peer active <-----------+ | Encrypted traffic decoded locally and sorted -// | -// Here, a consistent virtual peer ID is known | -// | -// Client <------------------- GXS Data ------------------> Server | -// - -// Notes: -// * tunnels are established symmetrically. If a distant peers wants to sync the same group, they'll have to open a single tunnel, with a different ID. -// Groups therefore have two states: -// - managed : the group can be used to answer tunnel requests. If server tunnels are established, the group will be synced with these peers -// - tunneled: the group will actively request tunnels. If tunnels are established both ways, the same virtual peers will be used so the tunnels are "merged". -// * In practice, that means one of the two tunnels will not be used and therefore die. -// * If a tunneled group already has enough virtual peers, it will not request for tunnels itself. -// -// Group policy | Request tunnels | SyncWithPeers | Item receipt -// --------------------+-------------------+-----------------------+---------------- -// Passive | no | If peers present | If peers present -// Active | yes, if no peers | If peers present | If peers present -// | | | -// -// * when a service has the DistSync flag set, groups to sync are communicated passively to the GxsNetTunnel service when requesting distant peers. -// However, a call should be made to set a particular group policy to "ACTIVE" for group that do not have peers and need some. -// -// * services also need to retrieve GXS data items that come out of tunnels. These will be available as (data,len) type, since they are not de-serialized. -// -// * GxsNetService stores data information (such as update maps) per peerId, so it makes sense to use the same PeerId for all groups of a given service -// Therefore, virtual peers are stored separately from groups, because each one can sync multiple groups. -// -// * virtual peers are also shared among services. This reduces the required amount of tunnels and tunnel requests to send. -// -// * tunnels for a given service may also be used by the net service of p3IdService in order to explicitely request missing GxsIds. -// So GxsNetTunnel somehow allows different services to use the same tunnel. However we make sure that this traffic is limited to only p3IdService. -// -// How do we know that a group needs distant sync? -// * look into GrpConfigMap for suppliers. Suppliers is cleared at load. -// * last_update_TS in GrpConfigMap is randomised so it cannot be used -// * we need a way to know that there's no suppliers for good reasons (not that we just started) -// -// Security -// * the question of sync-ing with distant anonymous peers is a bit tricky because these peers can try to generate fake requests or change which messages are available -// and there is no way to prevent it. We therefore rely on GXS data integrity system to prevent this to happen. -// - -class RsGxsNetTunnelItem ; -class RsNetworkExchangeService ; - -class RsGxsNetTunnelService: - public RsTurtleClientService, public RsTickingThread, public p3Config, - public RsGxsDistSync -{ -public: - RsGxsNetTunnelService() ; - virtual ~RsGxsNetTunnelService() ; - - /*! - * \brief registerSearchableService - * Adds the network exchange service as a possible search source. This is used to allow distant search on the corresponding - * GXS service. - * \return - * always returns true. - */ - bool registerSearchableService(RsNetworkExchangeService *) ; - - /*! - * \brief Manage tunnels for this group - * @param group_id group for which tunnels should be released - */ - bool requestDistantPeers(uint16_t service_id,const RsGxsGroupId&group_id) ; - - /*! - * \brief Stop managing tunnels for this group - * @param group_id group for which tunnels should be released - */ - bool releaseDistantPeers(uint16_t service_id, const RsGxsGroupId&group_id) ; - - /*! - * \brief Get the list of active virtual peers for a given group. This implies that a tunnel is up and - * alive. This function also "registers" the group which allows to handle tunnel requests in the server side. - */ - bool getVirtualPeers(std::list& peers) ; // returns the virtual peers for this service - - /*! - * \brief serviceId - * Overloads the method in RsTurtleClientService. - * \return - * The service id for RsGxsNetTunnel. - */ - uint16_t serviceId() const ; - - /*! - * \brief sendData - * send data to this virtual peer, and takes memory ownership (deletes the item) - * \param item item to send - * \param virtual_peer destination virtual peer - * \return - * true if succeeded. - */ - bool sendTunnelData(uint16_t service_id,unsigned char *& data, uint32_t data_len, const RsGxsNetTunnelVirtualPeerId& virtual_peer) ; - - /*! - * \brief receiveData - * returns the next piece of data received, and the virtual GXS peer that sended it. - * \param data memory check containing the data. Memory ownership belongs to the client. - * \param data_len length of memory chunk - * \param virtual_peer peer who sent the data - * \return - * true if something is returned. If not, data is set to NULL, data_len to 0. - */ - bool receiveTunnelData(uint16_t service_id, unsigned char *& data, uint32_t& data_len, RsGxsNetTunnelVirtualPeerId& virtual_peer) ; - - /*! - * \brief isDistantPeer - * returns wether the peer is in the list of available distant peers or not - * \param group_id returned by the service to indicate which group this peer id is designed for. - * \return true if the peer is a distant GXS peer. - */ - - bool isDistantPeer(const RsGxsNetTunnelVirtualPeerId& virtual_peer,RsGxsGroupId& group_id) ; - - /*! - * \brief dumps all information about monitored groups. - */ - void dump() const; - - /*! - * \brief connectToTurtleRouter - * Should be called after allocating a RsGxsNetTunnelService - * \param tr turtle router object - */ - virtual void connectToTurtleRouter(p3turtle *tr) ; - - TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id, RsNetworkExchangeService *client_service) ; - TurtleRequestId turtleSearchRequest(const std::string& match_string,RsNetworkExchangeService *client_service) ; - - /*! - * \brief receiveSearchRequest - * See RsTurtleClientService::@ - */ - virtual bool receiveSearchRequest(unsigned char *search_request_data, uint32_t search_request_data_len, unsigned char *& search_result_data, uint32_t& search_result_data_len, uint32_t &max_allowed_hits); - virtual void receiveSearchResult(TurtleSearchRequestId request_id,unsigned char *search_result_data,uint32_t search_result_data_len); - - void threadTick() override; /// @see RsTickingThread - - // Overloads p3Config - - RsSerialiser *setupSerialiser(); - bool saveList(bool& cleanup, std::list& save); - bool loadList(std::list &load); - - // Overloads RsGxsDistSync - - void getStatistics(std::map& groups, // groups on the client and server side - std::map& virtual_peers, // current virtual peers, which group they provide, and how to talk to them through turtle - std::map& turtle_vpid_to_net_tunnel_vpid, - Bias20Bytes& bias) const; - -protected: - // interaction with turtle router - - virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ; - virtual void receiveTurtleData(const RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ; - void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ; - void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ; - const Bias20Bytes& locked_randomBias() ; - - p3turtle *mTurtle ; - - static const uint32_t RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE = 20 ; - static const uint32_t RS_GXS_TUNNEL_CONST_EKEY_SIZE = 32 ; - - mutable Bias20Bytes mRandomBias ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time. -private: - void autowash() ; - void sendKeepAlivePackets() ; - void handleIncoming(RsGxsNetTunnelItem *item) ; - void flush_pending_items(); - - std::map mGroups ; // groups on the client and server side - - std::map mVirtualPeers ; // current virtual peers, which group they provide, and how to talk to them through turtle - std::map mHandledHashes ; // hashes asked to turtle. Used to answer tunnel requests - std::map mTurtle2GxsPeer ; // convertion table to find GXS peer id from turtle - - std::list > mPendingTurtleItems ; // items that need to be sent off-turtle Mutex. - - std::map > > mIncomingData; // list of incoming data items - - std::map mSearchableServices ; - - /*! - * \brief Generates the hash to request tunnels for this group. This hash is only used by turtle, and is used to - * hide the real group id. - */ - - RsFileHash calculateGroupHash(const RsGxsGroupId&group_id) const ; - - /*! - * \brief makeVirtualPeerIdForGroup creates a virtual peer id that can be used and that will be constant accross time, whatever the - * tunnel ID and turtle virtual peer id. This allows RsGxsNetService to keep sync-ing the data consistently. - */ - - RsGxsNetTunnelVirtualPeerId locked_makeVirtualPeerId(const RsGxsGroupId& group_id) ; - - static void generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) ; - - mutable RsMutex mGxsNetTunnelMtx; - - friend class RsGxsTunnelRandomBiasItem ; - friend class StoreHere ; - - rstime_t mLastKeepAlive ; - rstime_t mLastAutoWash ; - rstime_t mLastDump ; -}; - diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc deleted file mode 100644 index b74abcb0f..000000000 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsnetutils.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsgxsnetutils.h" -#include "pqi/p3servicecontrol.h" -#include "pgp/pgpauxutils.h" - - const rstime_t AuthorPending::EXPIRY_PERIOD_OFFSET = 30; // 30 seconds - const int AuthorPending::MSG_PEND = 1; - const int AuthorPending::GRP_PEND = 2; - -AuthorPending::AuthorPending(RsGixsReputation* rep, rstime_t timeStamp) : mRep(rep), mTimeStamp(timeStamp) {} - -AuthorPending::~AuthorPending() {} - -bool AuthorPending::expired() const -{ - return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET); -} - -bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, const RsPeerId& /*peerId*/) -{ - rep.id = authorId ; - rep.reputation_level = - static_cast(mRep->overallReputationLevel(authorId)); - -#warning csoler 2017-01-10: Can it happen that reputations do not have the info yet? - return true ; -#ifdef TO_BE_REMOVED - { - return mRep->getReputation(authorId, rep); - } - - std::list peers; - peers.push_back(peerId); - mRep->loadReputation(authorId, peers); - return false; -#endif -} - -MsgAuthEntry::MsgAuthEntry() - : mPassedVetting(false) {} - - -GrpAuthEntry::GrpAuthEntry() - : mPassedVetting(false) {} - - - -MsgRespPending::MsgRespPending(RsGixsReputation* rep, const RsPeerId& peerId, const MsgAuthorV& msgAuthV, int cutOff) - : AuthorPending(rep, time(NULL)), mPeerId(peerId), mMsgAuthV(msgAuthV), mCutOff(cutOff) -{ -} - -GrpRespPending::GrpRespPending(RsGixsReputation* rep, const RsPeerId& peerId, const GrpAuthorV& grpAuthV, int cutOff) - : AuthorPending(rep, time(NULL)), mPeerId(peerId), mGrpAuthV(grpAuthV), mCutOff(cutOff) -{ -} - -int MsgRespPending::getType() const -{ - return MSG_PEND; -} - -bool MsgRespPending::accepted() -{ - MsgAuthorV::iterator cit = mMsgAuthV.begin(); - MsgAuthorV::size_type count = 0; - for(; cit != mMsgAuthV.end(); ++cit) - { - MsgAuthEntry& entry = *cit; - - if(!entry.mPassedVetting) - { - GixsReputation rep; - if(getAuthorRep(rep, entry.mAuthorId, mPeerId)) - { - if(rep.reputation_level >= (uint32_t)mCutOff) - { - entry.mPassedVetting = true; - count++; - } - } - - }else - { - count++; - } - } - - return count == mMsgAuthV.size(); -} - -int GrpRespPending::getType() const -{ - return GRP_PEND; -} - -bool GrpRespPending::accepted() -{ - GrpAuthorV::iterator cit = mGrpAuthV.begin(); - GrpAuthorV::size_type count = 0; - for(; cit != mGrpAuthV.end(); ++cit) - { - GrpAuthEntry& entry = *cit; - - if(!entry.mPassedVetting) - { - GixsReputation rep; - - if(getAuthorRep(rep, entry.mAuthorId, mPeerId)) - { - if(rep.reputation_level >= (uint32_t)mCutOff) - { - entry.mPassedVetting = true; - count++; - } - } - - }else - { - count++; - } - } - - return count == mGrpAuthV.size(); -} - - - -/** NxsTransaction definition **/ - -const uint8_t NxsTransaction::FLAG_STATE_STARTING = 0x0001; // when -const uint8_t NxsTransaction::FLAG_STATE_RECEIVING = 0x0002; // begin receiving items for incoming trans -const uint8_t NxsTransaction::FLAG_STATE_SENDING = 0x0004; // begin sending items for outgoing trans -const uint8_t NxsTransaction::FLAG_STATE_FAILED = 0x0010; -const uint8_t NxsTransaction::FLAG_STATE_WAITING_CONFIRM = 0x0020; -const uint8_t NxsTransaction::FLAG_STATE_COMPLETED = 0x0080; // originaly 0x008, but probably a typo, but we cannot change it since it would break backward compatibility. - - -NxsTransaction::NxsTransaction() - : mFlag(0), mTimeOut(0), mTransaction(NULL) { - -} - -NxsTransaction::~NxsTransaction(){ - - std::list::iterator lit = mItems.begin(); - - for(; lit != mItems.end(); ++lit) - { - delete *lit; - *lit = NULL; - } - - if(mTransaction) - delete mTransaction; - - mTransaction = NULL; -} - - -/* Net Manager */ - -RsNxsNetMgrImpl::RsNxsNetMgrImpl(p3ServiceControl *sc) - : mServiceCtrl(sc) -{ - -} - - -const RsPeerId& RsNxsNetMgrImpl::getOwnId() -{ - return mServiceCtrl->getOwnId(); -} - -void RsNxsNetMgrImpl::getOnlineList(const uint32_t serviceId, std::set &ssl_peers) -{ - mServiceCtrl->getPeersConnected(serviceId, ssl_peers); -} - -const rstime_t GrpCircleVetting::EXPIRY_PERIOD_OFFSET = 5; // 10 seconds -const int GrpCircleVetting::GRP_ID_PEND = 1; -const int GrpCircleVetting::GRP_ITEM_PEND = 2; -const int GrpCircleVetting::MSG_ID_SEND_PEND = 3; -const int GrpCircleVetting::MSG_ID_RECV_PEND = 3; - - -GrpIdCircleVet::GrpIdCircleVet(const RsGxsGroupId& grpId, const RsGxsCircleId& circleId, const RsGxsId& authId) - : mGroupId(grpId), mCircleId(circleId), mAuthorId(authId), mCleared(false) {} - -GrpCircleVetting::GrpCircleVetting(RsGcxs* const circles, PgpAuxUtils *pgpUtils) - : mCircles(circles), mPgpUtils(pgpUtils), mTimeStamp(time(NULL)) {} - -GrpCircleVetting::~GrpCircleVetting() {} - -bool GrpCircleVetting::expired() -{ - return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET); -} -bool GrpCircleVetting::canSend( - const RsPeerId& peerId, const RsGxsCircleId& circleId, - bool& should_encrypt ) -{ - if(mCircles->isLoaded(circleId)) - { - const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId); - return mCircles->canSend(circleId, pgpId,should_encrypt); - } - - mCircles->loadCircle(circleId); - - return false; -} - -GrpCircleIdRequestVetting::GrpCircleIdRequestVetting( - RsGcxs* const circles, - PgpAuxUtils *pgpUtils, - std::vector grpCircleV, const RsPeerId& peerId) - : GrpCircleVetting(circles, pgpUtils), mGrpCircleV(grpCircleV), mPeerId(peerId) {} - -bool GrpCircleIdRequestVetting::cleared() -{ - std::vector::size_type i, count=0; - for(i = 0; i < mGrpCircleV.size(); ++i) - { - GrpIdCircleVet& gic = mGrpCircleV[i]; - - if(!gic.mCleared) - { - if(canSend(mPeerId, gic.mCircleId,gic.mShouldEncrypt)) - { - gic.mCleared = true; - count++; - } - } - else - { - count++; - } - - } - - return count == mGrpCircleV.size(); -} - -int GrpCircleIdRequestVetting::getType() const -{ - return GRP_ID_PEND; -} - -MsgIdCircleVet::MsgIdCircleVet(const RsGxsMessageId& msgId, - const RsGxsId& authorId) - : mMsgId(msgId), mAuthorId(authorId) { -} - -MsgCircleIdsRequestVetting::MsgCircleIdsRequestVetting(RsGcxs* const circles, - PgpAuxUtils *pgpUtils, - std::vector msgs, const RsGxsGroupId& grpId, - const RsPeerId& peerId, const RsGxsCircleId& circleId) -: GrpCircleVetting(circles, pgpUtils), mMsgs(msgs), mGrpId(grpId), mPeerId(peerId), mCircleId(circleId) {} - -bool MsgCircleIdsRequestVetting::cleared() -{ - if(!mCircles->isLoaded(mCircleId)) - { - mCircles->loadCircle(mCircleId); - return false ; - } - - uint32_t filtered_out_msgs=0; - - for(uint32_t i=0;iisRecipient(mCircleId,mGrpId,mMsgs[i].mAuthorId)) - { - ++filtered_out_msgs; - mMsgs[i] = mMsgs[mMsgs.size()-1] ; - mMsgs.pop_back(); - } - else - ++i ; - - if(filtered_out_msgs>0) - std::cerr << "(WW) " << filtered_out_msgs << " messages not sent because they are signed by author(s) not member of that circle " << mCircleId << std::endl; - - RsPgpId pgpId = mPgpUtils->getPGPId(mPeerId); - bool can_send_res = mCircles->canSend(mCircleId, pgpId,mShouldEncrypt); - - if(mShouldEncrypt) // that means the circle is external - return true ; - else - return can_send_res ; -} - -int MsgCircleIdsRequestVetting::getType() const -{ - return MSG_ID_SEND_PEND; -} - - diff --git a/libretroshare/src/gxs/rsgxsnetutils.h b/libretroshare/src/gxs/rsgxsnetutils.h deleted file mode 100644 index 2ed229de0..000000000 --- a/libretroshare/src/gxs/rsgxsnetutils.h +++ /dev/null @@ -1,290 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsnetutils.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RSGXSNETUTILS_H_ -#define RSGXSNETUTILS_H_ - -#include -#include "retroshare/rsgxsifacetypes.h" -#include "rsitems/rsnxsitems.h" -#include "rsgixs.h" - -class p3ServiceControl; -class PgpAuxUtils; - -/*! - * This represents a transaction made - * with the NxsNetService in all states - * of operation until completion - * - */ -class NxsTransaction -{ - -public: - - static const uint8_t FLAG_STATE_STARTING; // when - static const uint8_t FLAG_STATE_RECEIVING; // begin receiving items for incoming trans - static const uint8_t FLAG_STATE_SENDING; // begin sending items for outgoing trans - static const uint8_t FLAG_STATE_COMPLETED; - static const uint8_t FLAG_STATE_FAILED; - static const uint8_t FLAG_STATE_WAITING_CONFIRM; - - NxsTransaction(); - ~NxsTransaction(); - - uint32_t mFlag; // current state of transaction - uint32_t mTimeOut; - - /*! - * this contains who we - * c what peer this transaction involves. - * c The type of transaction - * c transaction id - * c timeout set for this transaction - * c and itemCount - */ - RsNxsTransacItem* mTransaction; - std::list mItems; // items received or sent -}; - -/*! - * An abstraction of the net manager - * for retrieving Rs peers whom you will be synchronising - * and also you own Id - * Useful for testing also (abstracts away Rs's p3NetMgr) - */ -class RsNxsNetMgr -{ - -public: - - virtual ~RsNxsNetMgr(){}; - virtual const RsPeerId& getOwnId() = 0; - virtual void getOnlineList(const uint32_t serviceId, std::set& ssl_peers) = 0; - -}; - -class RsNxsNetMgrImpl : public RsNxsNetMgr -{ - -public: - - RsNxsNetMgrImpl(p3ServiceControl* sc); - virtual ~RsNxsNetMgrImpl(){}; - - virtual const RsPeerId& getOwnId(); - virtual void getOnlineList(const uint32_t serviceId, std::set& ssl_peers); - -private: - - // No need for mutex as this is constant in the class. - p3ServiceControl* mServiceCtrl; - -}; - -/*! - * Partial abstract class - * which represents - * items waiting to be vetted - * on account of their author Id - */ -class AuthorPending -{ -public: - - static const int MSG_PEND; - static const int GRP_PEND; - static const rstime_t EXPIRY_PERIOD_OFFSET; - - AuthorPending(RsGixsReputation* rep, rstime_t timeStamp); - virtual ~AuthorPending(); - virtual int getType() const = 0 ; - - /*! - * @return true if all authors pass vetting and their messages - * should be requested - */ - virtual bool accepted() = 0; - - /*! - * @return true if message is past set expiry date - */ - bool expired() const; - -protected: - - /*! - * Convenience function to get author reputation - * @param rep reputation of author - * @param authorId reputation to get - * @return true if successfully retrieve repution - */ - bool getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, const RsPeerId& peerId); - -private: - - RsGixsReputation* mRep; - rstime_t mTimeStamp; -}; - -class MsgAuthEntry -{ - -public: - - MsgAuthEntry(); - - RsGxsMessageId mMsgId; - RsGxsGroupId mGrpId; - RsGxsId mAuthorId; - bool mPassedVetting; - -}; - -class GrpAuthEntry -{ - -public: - - GrpAuthEntry(); - - RsGxsGroupId mGrpId; - RsGxsId mAuthorId; - bool mPassedVetting; -}; - -typedef std::vector MsgAuthorV; -typedef std::vector GrpAuthorV; - -class MsgRespPending : public AuthorPending -{ -public: - - MsgRespPending(RsGixsReputation* rep, const RsPeerId& peerId, const MsgAuthorV& msgAuthV, int cutOff = 0); - - int getType() const; - bool accepted(); - RsPeerId mPeerId; - MsgAuthorV mMsgAuthV; - int mCutOff; -}; - -class GrpRespPending : public AuthorPending -{ -public: - - GrpRespPending(RsGixsReputation* rep, const RsPeerId& peerId, const GrpAuthorV& grpAuthV, int cutOff = 0); - int getType() const; - bool accepted(); - RsPeerId mPeerId; - GrpAuthorV mGrpAuthV; - int mCutOff; -}; - - -/////////////// - -class GrpIdCircleVet -{ -public: - GrpIdCircleVet(const RsGxsGroupId& grpId, const RsGxsCircleId& circleId, const RsGxsId& authId); - RsGxsGroupId mGroupId; - RsGxsCircleId mCircleId; - RsGxsId mAuthorId; - - bool mCleared; - bool mShouldEncrypt; -}; - -class MsgIdCircleVet -{ -public: - MsgIdCircleVet(const RsGxsMessageId& grpId, const RsGxsId& authorId); - - RsGxsMessageId mMsgId; - RsGxsId mAuthorId; -}; - -class GrpItemCircleVet -{ -public: - RsNxsGrp* grpItem; - RsGxsCircleId mCircleId; - bool mCleared; -}; - -class GrpCircleVetting -{ -public: - - static const rstime_t EXPIRY_PERIOD_OFFSET; - static const int GRP_ID_PEND; - static const int GRP_ITEM_PEND; - static const int MSG_ID_SEND_PEND; - static const int MSG_ID_RECV_PEND; - - - GrpCircleVetting(RsGcxs* const circles, PgpAuxUtils *pgpUtils); - virtual ~GrpCircleVetting(); - bool expired(); - virtual int getType() const = 0; - virtual bool cleared() = 0; - -protected: - bool canSend(const RsPeerId& peerId, const RsGxsCircleId& circleId, bool& should_encrypt); - - RsGcxs* const mCircles; - PgpAuxUtils *mPgpUtils; - rstime_t mTimeStamp; -}; - -class GrpCircleIdRequestVetting : public GrpCircleVetting -{ -public: - GrpCircleIdRequestVetting(RsGcxs* const circles, - PgpAuxUtils *pgpUtils, - std::vector mGrpCircleV, const RsPeerId& peerId); - bool cleared(); - int getType() const; - std::vector mGrpCircleV; - RsPeerId mPeerId; -}; - -class MsgCircleIdsRequestVetting : public GrpCircleVetting -{ -public: - MsgCircleIdsRequestVetting(RsGcxs* const circles, - PgpAuxUtils *auxUtils, - std::vector msgs, const RsGxsGroupId& grpId, - const RsPeerId& peerId, const RsGxsCircleId& circleId); - bool cleared(); - int getType() const; - std::vector mMsgs; - RsGxsGroupId mGrpId; - RsPeerId mPeerId; - RsGxsCircleId mCircleId; - bool mShouldEncrypt; -}; - - -#endif /* RSGXSNETUTILS_H_ */ diff --git a/libretroshare/src/gxs/rsgxsnotify.h b/libretroshare/src/gxs/rsgxsnotify.h deleted file mode 100644 index 990acfe84..000000000 --- a/libretroshare/src/gxs/rsgxsnotify.h +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs/: rsgxsnotify.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -/*! - * The aim of this class is to implement notifications internally to GXS, which are - * mostly used by RsGenExchange to send information to specific services. These services - * then interpret these changes and turn them into human-readable/processed service-specific changes. - */ - -#include "retroshare/rsids.h" - -class RsGxsNotify -{ -public: - RsGxsNotify(const RsGxsGroupId& gid): mGroupId(gid){} - virtual ~RsGxsNotify()=default; - - enum NotifyType - { - TYPE_UNKNOWN = 0x00, - TYPE_PUBLISHED = 0x01, - TYPE_RECEIVED_NEW = 0x02, - TYPE_PROCESSED = 0x03, - TYPE_RECEIVED_PUBLISHKEY = 0x04, - TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05, - TYPE_STATISTICS_CHANGED = 0x06, - TYPE_UPDATED = 0x07, - TYPE_MESSAGE_DELETED = 0x08, - TYPE_GROUP_DELETED = 0x09, - TYPE_GROUP_SYNC_PARAMETERS_UPDATED = 0x0a, - }; - - virtual NotifyType getType() = 0; - - RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group - // that was although there is no pointers to the actual group data anymore. -}; - -/*! - * Relevant to group changes - */ -class RsGxsGroupChange : public RsGxsNotify -{ -public: - RsGxsGroupChange(NotifyType type, const RsGxsGroupId& gid,bool metaChange) : RsGxsNotify(gid),mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {} - virtual ~RsGxsGroupChange() override { delete mOldGroupItem; delete mNewGroupItem ; } - - NotifyType getType() override { return mNotifyType;} - bool metaChange() { return mMetaChange; } - - RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received. - RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED - -protected: - NotifyType mNotifyType; - bool mMetaChange; -}; - -/*! - * Relevant to message changes - */ -class RsGxsMsgChange : public RsGxsNotify -{ -public: - RsGxsMsgChange(NotifyType type, const RsGxsGroupId& gid, const RsGxsMessageId& msg_id,bool metaChange) - : RsGxsNotify(gid), mMsgId(msg_id), mNewMsgItem(nullptr),NOTIFY_TYPE(type), mMetaChange(metaChange) {} - virtual ~RsGxsMsgChange() override { delete mNewMsgItem ; } - - RsGxsMessageId mMsgId; - RsGxsMsgItem *mNewMsgItem; - - NotifyType getType(){ return NOTIFY_TYPE;} - bool metaChange() { return mMetaChange; } -private: - const NotifyType NOTIFY_TYPE; - bool mMetaChange; -}; - diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.cc b/libretroshare/src/gxs/rsgxsrequesttypes.cc deleted file mode 100644 index e10a4efc3..000000000 --- a/libretroshare/src/gxs/rsgxsrequesttypes.cc +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsrequesttypes.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsgxsrequesttypes.h" -#include "util/rsstd.h" - -std::ostream& operator<<(std::ostream& o,const GxsRequest& g) -{ - return g.print(o); -} - - -std::ostream& GroupMetaReq::print(std::ostream& o) const -{ - o << "[Request type=GroupMeta groupIds (size=" << mGroupIds.size() << "): " ; - - if(!mGroupIds.empty()) - { - o << *mGroupIds.begin() ; - - if(mGroupIds.size() > 1) - o << " ..." ; - } - - o << "]" ; - - return o; -} -std::ostream& GroupIdReq::print(std::ostream& o) const -{ - return o << "[Request type=GroupIdReq" << "]" ; -} - -std::ostream& GroupSerializedDataReq::print(std::ostream& o) const -{ - return o << "[Request type=GroupSerializedData" << "]" ; -} - -std::ostream& GroupDataReq::print(std::ostream& o) const -{ - o << "[Request type=GroupDataReq groupIds (size=" << mGroupIds.size() << "): " ; - - if(!mGroupIds.empty()) - { - o << *mGroupIds.begin() ; - - if(mGroupIds.size() > 1) - o << " ..." ; - } - - o << "]" ; - - return o; -} - -std::ostream& MsgIdReq::print(std::ostream& o) const -{ - return o << "[Request type=MsgId" << "]" ; -} - -std::ostream& MsgMetaReq::print(std::ostream& o) const -{ - o << "[Request type=MsgMetaReq groups (size=" << mMsgIds.size() << "): " ; - - if(!mMsgIds.empty()) - { - o << mMsgIds.begin()->first << " (" << mMsgIds.begin()->second.size() << " messages)"; - - if(mMsgIds.size() > 1) - o << " ..." ; - } - - o << "]" ; - - return o; -} - -std::ostream& MsgDataReq::print(std::ostream& o) const -{ - o << "[Request type=MsgDataReq groups (size=" << mMsgIds.size() << "): " ; - - if(!mMsgIds.empty()) - { - o << mMsgIds.begin()->first << " (" << mMsgIds.begin()->second.size() << " messages)"; - - if(mMsgIds.size() > 1) - o << " ..." ; - } - - o << "]" ; - - return o; -} - -std::ostream& MsgRelatedInfoReq::print(std::ostream& o) const -{ - o << "[Request type=MsgRelatedInfo msgIds (size=" << mMsgIds.size() << "): " ; - - if(!mMsgIds.empty()) - { - o << mMsgIds.begin()->first ; - - if(mMsgIds.size() > 1) - o << " ..." ; - } - - o << "]" ; - - return o; -} - -std::ostream& GroupSetFlagReq::print(std::ostream& o) const -{ - return o << "[Request type=GroupFlagSet grpId=" << grpId << "]" ; -} - - - -std::ostream& ServiceStatisticRequest::print(std::ostream& o) const -{ - return o << "[Request type=ServiceStatistics" << "]" ; -} - -std::ostream& GroupStatisticRequest::print(std::ostream& o) const -{ - return o << "[Request type=GroupStatistics grpId=" << mGrpId << "]" ; -} - -GroupMetaReq::~GroupMetaReq() -{ - //rsstd::delete_all(mGroupMetaData.begin(), mGroupMetaData.end()); // now memory ownership is kept by the cache. - mGroupMetaData.clear(); -} - -GroupDataReq::~GroupDataReq() -{ - rsstd::delete_all(mGroupData.begin(), mGroupData.end()); -} - -MsgDataReq::~MsgDataReq() -{ - for (NxsMsgDataResult::iterator it = mMsgData.begin(); it != mMsgData.end(); ++it) { - rsstd::delete_all(it->second.begin(), it->second.end()); - } -} - -MsgRelatedInfoReq::~MsgRelatedInfoReq() -{ - for (NxsMsgRelatedDataResult::iterator dataIt = mMsgDataResult.begin(); dataIt != mMsgDataResult.end(); ++dataIt) - rsstd::delete_all(dataIt->second.begin(), dataIt->second.end()); -} -std::ostream& MessageSetFlagReq::print(std::ostream& o) const -{ - return o << "[Request type=MsgFlagSet" << "]" ; -} - diff --git a/libretroshare/src/gxs/rsgxsrequesttypes.h b/libretroshare/src/gxs/rsgxsrequesttypes.h deleted file mode 100644 index dd9ddb7cd..000000000 --- a/libretroshare/src/gxs/rsgxsrequesttypes.h +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsrequesttypes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSREQUESTTYPES_H_ -#define RSGXSREQUESTTYPES_H_ - -#include "retroshare/rstokenservice.h" -#include "gxs/rsgds.h" -#include "util/rsdeprecate.h" - -struct GxsRequest -{ - GxsRequest() : - token(0), reqTime(0), clientAnswerType(0), reqType(0), - status(RsTokenService::FAILED) {} - virtual ~GxsRequest() {} - - uint32_t token; - uint32_t reqTime; - - uint32_t clientAnswerType; /// This is made available to the clients in order to keep track of why specific requests where sent.. - uint32_t reqType; - RsTokReqOptions Options; - - RsTokenService::GxsRequestStatus status; - - virtual std::ostream& print(std::ostream& o) const = 0; -}; - -std::ostream& operator<<(std::ostream& o,const GxsRequest& g); - -class GroupMetaReq : public GxsRequest -{ -public: - virtual ~GroupMetaReq(); - - virtual std::ostream& print(std::ostream& o) const override; -public: - std::list mGroupIds; - std::list > mGroupMetaData; -}; - -class GroupIdReq : public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - - std::list mGroupIds; - std::list mGroupIdResult; -}; -class GroupSerializedDataReq : public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - - std::list mGroupIds; - std::list mGroupData; -}; - -class GroupDataReq : public GxsRequest -{ -public: - virtual ~GroupDataReq(); - - virtual std::ostream& print(std::ostream& o) const override; -public: - std::list mGroupIds; - std::list mGroupData; -}; - -class MsgIdReq : public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - - GxsMsgReq mMsgIds; - GxsMsgIdResult mMsgIdResult; -}; - -class MsgMetaReq : public GxsRequest -{ -public: - virtual ~MsgMetaReq() = default; - - virtual std::ostream& print(std::ostream& o) const override; - -public: - GxsMsgReq mMsgIds; - GxsMsgMetaResult mMsgMetaData; -}; - -class MsgDataReq : public GxsRequest -{ -public: - virtual ~MsgDataReq(); - - virtual std::ostream& print(std::ostream& o) const override; -public: - GxsMsgReq mMsgIds; - NxsMsgDataResult mMsgData; -}; - -class ServiceStatisticRequest: public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - GxsServiceStatistic mServiceStatistic; -}; - -struct GroupStatisticRequest: public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - - RsGxsGroupId mGrpId; - GxsGroupStatistic mGroupStatistic; -}; - -class MsgRelatedInfoReq : public GxsRequest -{ -public: - virtual ~MsgRelatedInfoReq(); - - std::ostream& print(std::ostream& o) const override; -public: - std::vector mMsgIds; - MsgRelatedIdResult mMsgIdResult; - MsgRelatedMetaResult mMsgMetaResult; - NxsMsgRelatedDataResult mMsgDataResult; -}; - -class GroupSetFlagReq : public GxsRequest -{ -public: - virtual std::ostream& print(std::ostream& o) const override ; - - const static uint32_t FLAG_SUBSCRIBE; - const static uint32_t FLAG_STATUS; - - uint8_t type; - uint32_t flag; - uint32_t flagMask; - RsGxsGroupId grpId; -}; - -class MessageSetFlagReq : public GxsRequest -{ -public: - const static uint32_t FLAG_STATUS; - - virtual std::ostream& print(std::ostream& o) const override ; - uint8_t type; - uint32_t flag; - uint32_t flagMask; - RsGxsGrpMsgIdPair msgId; -}; - -#endif /* RSGXSREQUESTTYPES_H_ */ diff --git a/libretroshare/src/gxs/rsgxsutil.cc b/libretroshare/src/gxs/rsgxsutil.cc deleted file mode 100644 index f64fd236f..000000000 --- a/libretroshare/src/gxs/rsgxsutil.cc +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsutil.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Christopher Evi-Parker * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rstime.h" - -#include "rsgxsutil.h" -#include "retroshare/rsgxsflags.h" -#include "retroshare/rspeers.h" -#include "pqi/pqihash.h" -#include "gxs/rsgixs.h" - -#ifdef RS_DEEP_CHANNEL_INDEX -# include "deep_search/channelsindex.hpp" -# include "services/p3gxschannels.h" -# include "rsitems/rsgxschannelitems.h" -#endif - -// The goals of this set of methods is to check GXS messages and groups for consistency, mostly -// re-ferifying signatures and hashes, to make sure that the data hasn't been tempered. This shouldn't -// happen anyway, but we still conduct these test as an extra safety measure. - -static const uint32_t MAX_GXS_IDS_REQUESTS_NET = 10 ; // max number of requests from cache/net (avoids killing the system!) - -// #define DEBUG_GXSUTIL 1 - -#ifdef DEBUG_GXSUTIL -#define GXSUTIL_DEBUG() std::cerr << "[" << time(NULL) << "] : GXS_UTIL : " << __FUNCTION__ << " : " -#endif - -RsGxsCleanUp::RsGxsCleanUp(RsGeneralDataService* const dataService, RsGenExchange *genex, uint32_t chunkSize) -: mDs(dataService), mGenExchangeClient(genex), CHUNK_SIZE(chunkSize) -{ -} - -bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector& grps_to_delete,GxsMsgReq& messages_to_delete) -{ - RsGxsGrpMetaTemporaryMap grpMetaMap; - mDs->retrieveGxsGrpMetaData(grpMetaMap); - - rstime_t now = time(NULL); - -#ifdef DEBUG_GXSUTIL - uint16_t service_type = mGenExchangeClient->serviceType() ; - GXSUTIL_DEBUG() << " Cleaning up groups in service " << std::hex << service_type << std::dec << " starting at group " << next_group_to_check << std::endl; -#endif - // This method stores/takes the next group to check. This allows to limit group checking to a small part of the total groups - // in the situation where it takes too much time. So when arriving here, we must start again from where we left last time. - - if(grpMetaMap.empty()) // nothing to do. - { - next_group_to_check.clear(); - return true; - } - - auto it = next_group_to_check.isNull()?grpMetaMap.begin() : grpMetaMap.find(next_group_to_check); - - if(it == grpMetaMap.end()) // group wasn't found - it = grpMetaMap.begin(); - - bool full_round = false; // did we have the time to test all groups? - next_group_to_check = it->first; // covers the case where next_group_to_check is null or not found - - while(true) // check all groups, starting from the one indicated as parameter - { - const RsGxsGrpMetaData& grpMeta = *(it->second); - - // first check if we keep the group or not - - if(!mGenExchangeClient->service_checkIfGroupIsStillUsed(grpMeta)) - { -#ifdef DEBUG_GXSUTIL - std::cerr << " Scheduling group " << grpMeta.mGroupId << " for removal." << std::endl; -#endif - grps_to_delete.push_back(grpMeta.mGroupId); - } - else - { - const RsGxsGroupId& grpId = grpMeta.mGroupId; - GxsMsgReq req; - GxsMsgMetaResult result; - - req[grpId] = std::set(); - mDs->retrieveGxsMsgMetaData(req, result); - - GxsMsgMetaResult::iterator mit = result.begin(); - -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " Cleaning up group message for group ID " << grpId << std::endl; -#endif - uint32_t store_period = mGenExchangeClient->getStoragePeriod(grpId) ; - - for(; mit != result.end(); ++mit) - { - auto& metaV = mit->second; - - // First, make a map of which message have a child message. This allows to only delete messages that dont have child messages. - // A more accurate way to go would be to compute the time of the oldest message and possibly delete all the branch, but in the - // end the message tree will be deleted slice after slice, which should still be reasonnably fast. - // - std::set messages_with_kids ; - - for( uint32_t i=0;imParentId.isNull()) - messages_with_kids.insert(metaV[i]->mParentId) ; - - for( uint32_t i=0;imMsgId)!=messages_with_kids.end()); - - // check if expired - bool remove = store_period > 0 && ((meta->mPublishTs + store_period) < now) && !have_kids; - - // check client does not want the message kept regardless of age - remove &= !(meta->mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER); - - // if not subscribed remove messages (can optimise this really) - remove = remove || (grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED); - remove = remove || !(grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " msg id " << meta->mMsgId << " in grp " << grpId << ": keep_flag=" << bool(meta->mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER) - << " subscribed: " << bool(grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) << " store_period: " << store_period - << " kids: " << have_kids << " now - meta->mPublishTs: " << now - meta->mPublishTs ; -#endif - - if( remove ) - { - messages_to_delete[grpId].insert(meta->mMsgId); -#ifdef DEBUG_GXSUTIL - std::cerr << " Scheduling for removal." << std::endl; -#endif - } -#ifdef DEBUG_GXSUTIL - else - std::cerr << std::endl; -#endif - //delete meta; - } - } - } - - ++it; - - if(it == grpMetaMap.end()) - it = grpMetaMap.begin(); - - // check if we looped already - - if(it->first == next_group_to_check) - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "Had the time to test all groups. Will start again at " << it->first << std::endl; -#endif - full_round = true; - break; - } - - // now check if we spent too much time on this already - - rstime_t tm = time(nullptr); - - //if(tm > now + 1) // we spent more than 1 sec on the job already - if(tm > now) // we spent more than 1 sec on the job already - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "Aborting cleanup because it took too much time already. Next group left to be " << it->first << std::endl; -#endif - next_group_to_check = it->first; - full_round = false; - break; - } - } - - return full_round; -} - -RsGxsIntegrityCheck::RsGxsIntegrityCheck( - RsGeneralDataService* const dataService, RsGenExchange* genex, - RsSerialType& - , RsGixs* gixs ) - : mDs(dataService), mGenExchangeClient(genex), - mDone(false), mIntegrityMutex("integrity"), mGixs(gixs) {} - -void RsGxsIntegrityCheck::run() -{ - std::vector grps_to_delete; - GxsMsgReq msgs_to_delete; - - check(mGenExchangeClient->serviceType(), mGixs, mDs); - - RS_STACK_MUTEX(mIntegrityMutex); - mDone = true; -} - -bool RsGxsIntegrityCheck::check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds) -{ -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "Parsing all groups and messages MetaData in service " << std::hex << mds->serviceType() << std::endl; -#endif - // first take out all the groups - std::map > grp; - - mds->retrieveGxsGrpMetaData(grp); - - GxsMsgReq msgIds; - - std::map used_gxs_ids ; - std::set subscribed_groups ; - - // Check that message ids... - - for( auto git = grp.begin(); git != grp.end(); ++git ) - { - const auto& grpMeta = git->second; - - if (mds->retrieveMsgIds(grpMeta->mGroupId, msgIds[grpMeta->mGroupId]) == 1) - { - if(grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - { - subscribed_groups.insert(git->first); - - if(!grpMeta->mAuthorId.isNull()) - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "TimeStamping group authors' key ID " << grpMeta->mAuthorId << " in group ID " << grpMeta->mGroupId << std::endl; -#endif - if( rsReputations && rsReputations->overallReputationLevel( grpMeta->mAuthorId ) > RsReputationLevel::LOCALLY_NEGATIVE ) - used_gxs_ids.insert(std::make_pair(grpMeta->mAuthorId, RsIdentityUsage(RsServiceType(service_type), RsIdentityUsage::GROUP_AUTHOR_KEEP_ALIVE,grpMeta->mGroupId))); - } - } - } - else - msgIds.erase(msgIds.find(grpMeta->mGroupId)); // could not get them, so group is removed from list. - } - - // now messages - GxsMsgMetaResult msgMetas; - - mds->retrieveGxsMsgMetaData(msgIds, msgMetas); - - for(auto mit=msgMetas.begin(); mit != msgMetas.end(); ++mit) - { - const auto& msgM = mit->second; - - for(auto vit=msgM.begin(); vit != msgM.end(); ++vit) - { - const auto& meta = *vit; - - if (subscribed_groups.count(meta->mGroupId)) - if(!meta->mAuthorId.isNull()) - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << meta->mAuthorId << " in message " << meta->mMsgId << ", group ID " << meta->mGroupId<< std::endl; -#endif - if( rsReputations && rsReputations->overallReputationLevel( meta->mAuthorId ) > RsReputationLevel::LOCALLY_NEGATIVE ) - used_gxs_ids.insert(std::make_pair(meta->mAuthorId,RsIdentityUsage(RsServiceType(service_type), - RsIdentityUsage::MESSAGE_AUTHOR_KEEP_ALIVE, - meta->mGroupId, - meta->mMsgId, - meta->mParentId, - meta->mThreadId))) ; - } - } - } - - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "At end of pass, this is the list used GXS ids: " << std::endl; - GXSUTIL_DEBUG() << " requesting them to GXS identity service to enforce loading." << std::endl; -#endif - - std::list connected_friends ; - rsPeers->getOnlineList(connected_friends) ; - - std::vector > gxs_ids ; - - for(std::map::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it) - { - gxs_ids.push_back(*it) ; -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " " << it->first << std::endl; -#endif - } - uint32_t nb_requested_not_in_cache = 0; - -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " issuing random get on friends for non existing IDs" << std::endl; -#endif - - // now request a cache update for them, which triggers downloading from friends, if missing. - - for(;nb_requested_not_in_cachehaveKey(gxs_ids[n].first)) // checks if we have it already in the cache (conservative way to ensure that we atually have it) - { - mgixs->requestKey(gxs_ids[n].first,connected_friends,gxs_ids[n].second); - - ++nb_requested_not_in_cache ; -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " ... from cache/net" << std::endl; -#endif - } - else - { -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " ... already in cache" << std::endl; -#endif - } - mgixs->timeStampKey(gxs_ids[n].first,gxs_ids[n].second); - - gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ; - gxs_ids.pop_back() ; - } -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << " total actual cache requests: "<< nb_requested_not_in_cache << std::endl; -#endif - } - - return true; -} - -bool RsGxsSinglePassIntegrityCheck::check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds -#ifdef RS_DEEP_CHANNEL_INDEX - , RsGenExchange* mGenExchangeClient, RsSerialType& mSerializer -#endif - , std::vector& grpsToDel, GxsMsgReq& msgsToDel) -{ -#ifdef DEBUG_GXSUTIL - GXSUTIL_DEBUG() << "Parsing all groups and messages data in service " << std::hex << mds->serviceType() << " for integrity check. Could take a while..." << std::endl; -#endif -#ifdef RS_DEEP_CHANNEL_INDEX - bool isGxsChannels = mGenExchangeClient->serviceType() == RS_SERVICE_GXS_TYPE_CHANNELS; - std::set indexedGroups; -#endif - - // first take out all the groups - std::map grp; - mds->retrieveNxsGrps(grp, true); - GxsMsgReq msgIds; - GxsMsgReq grps; - - std::map used_gxs_ids ; - std::set subscribed_groups ; - - // compute hash and compare to stored value, if it fails then simply add it - // to list - for( std::map::iterator git = grp.begin(); git != grp.end(); ++git ) - { - RsNxsGrp* grp = git->second; - RsFileHash currHash; - pqihash pHash; - pHash.addData(grp->grp.bin_data, grp->grp.bin_len); - pHash.Complete(currHash); - - if(currHash == grp->metaData->mHash) - { - // Get all message ids of group, store them in msgIds, creating the grp entry at the same time. - - if (mds->retrieveMsgIds(grp->grpId, msgIds[grp->grpId]) == 1) - { - // store the group for retrieveNxsMsgs - grps[grp->grpId]; - - if(grp->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - subscribed_groups.insert(git->first); - } - else - msgIds.erase(msgIds.find(grp->grpId)); // could not get them, so group is removed from list. - -#ifdef RS_DEEP_CHANNEL_INDEX - // This should be moved to p3gxschannels. It is really not the place for this here! - - if( isGxsChannels - && grp->metaData->mCircleType == GXS_CIRCLE_TYPE_PUBLIC - && grp->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) - { - RsGxsGrpMetaData meta; - meta.deserialise(grp->meta.bin_data, grp->meta.bin_len); - - uint32_t blz = grp->grp.bin_len; - RsItem* rIt = mSerializer.deserialise(grp->grp.bin_data, - &blz); - - if( RsGxsChannelGroupItem* cgIt = - dynamic_cast(rIt) ) - { - RsGxsChannelGroup cg; - cgIt->toChannelGroup(cg, false); - cg.mMeta = meta; - - indexedGroups.insert(grp->grpId); - DeepChannelsIndex::indexChannelGroup(cg); - } - else - { - std::cerr << __PRETTY_FUNCTION__ << " Group: " - << meta.mGroupId.toStdString() << " " - << meta.mGroupName - << " doesn't seems a channel, please " - << "report to developers" - << std::endl; - print_stacktrace(); - } - - delete rIt; - } -#endif // def RS_DEEP_CHANNEL_INDEX - } - else - { - std::cerr << __PRETTY_FUNCTION__ <<" (EE) deleting group " << grp->grpId << " with wrong hash or null/corrupted meta data. meta=" << grp->metaData << std::endl; - grpsToDel.push_back(grp->grpId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelFromIndex(grp->grpId); -#endif // def RS_DEEP_CHANNEL_INDEX - } - - delete grp; - } - - // now messages - GxsMsgResult msgs; - - mds->retrieveNxsMsgs(grps, msgs, true); - - // Check msg ids and messages. Go through all message IDs referred to by the db call - // and verify that the message belongs to the nxs msg data that was just retrieved. - - for(auto& msgIdsIt:msgIds) - { - const RsGxsGroupId& grpId = msgIdsIt.first; - std::set& msgIdV = msgIdsIt.second; - - std::set nxsMsgS; - std::vector& nxsMsgV = msgs[grpId]; - - // To make the search efficient, we first build a set of msgIds to search in. - // Set build and search are both O(n log(n)). - - for(auto& nxsMsg:nxsMsgV) - if(nxsMsg) - nxsMsgS.insert(nxsMsg->msgId); - - for (auto& msgId:msgIdV) - if(nxsMsgS.find(msgId) == nxsMsgS.end()) - { - msgsToDel[grpId].insert(msgId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelPostFromIndex(grpId, msgId); -#endif // def RS_DEEP_CHANNEL_INDEX - } - } - - for(auto mit = msgs.begin(); mit != msgs.end(); ++mit) - { - std::vector& msgV = mit->second; - std::vector::iterator vit = msgV.begin(); - - for(; vit != msgV.end(); ++vit) - { - RsNxsMsg* msg = *vit; - RsFileHash currHash; - pqihash pHash; - pHash.addData(msg->msg.bin_data, msg->msg.bin_len); - pHash.Complete(currHash); - - if(msg->metaData == NULL || currHash != msg->metaData->mHash) - { - std::cerr << __PRETTY_FUNCTION__ <<" (EE) deleting message " << msg->msgId << " in group " << msg->grpId << " with wrong hash or null/corrupted meta data. meta=" << (void*)msg->metaData << std::endl; - msgsToDel[msg->grpId].insert(msg->msgId); -#ifdef RS_DEEP_CHANNEL_INDEX - if(isGxsChannels) - DeepChannelsIndex::removeChannelPostFromIndex( - msg->grpId, msg->msgId ); -#endif // def RS_DEEP_CHANNEL_INDEX - } - else if (subscribed_groups.count(msg->metaData->mGroupId)) - { -#ifdef RS_DEEP_CHANNEL_INDEX - // This should be moved to p3gxschannels. It is really not the place for this here! - - if( isGxsChannels && indexedGroups.count(msg->metaData->mGroupId) ) - { - RsGxsMsgMetaData meta; - meta.deserialise(msg->meta.bin_data, &msg->meta.bin_len); - - uint32_t blz = msg->msg.bin_len; - RsItem* rIt = mSerializer.deserialise(msg->msg.bin_data, - &blz); - - if( RsGxsChannelPostItem* cgIt = - dynamic_cast(rIt) ) - { - RsGxsChannelPost cg; - cgIt->toChannelPost(cg, false); - cg.mMeta = meta; - - DeepChannelsIndex::indexChannelPost(cg); - } - else if(dynamic_cast(rIt)) {} - else if(dynamic_cast(rIt)) {} - else - { - std::cerr << __PRETTY_FUNCTION__ << " Message: " - << meta.mMsgId.toStdString() - << " in group: " - << meta.mGroupId.toStdString() << " " - << " doesn't seems a channel post, please " - << "report to developers" - << std::endl; - print_stacktrace(); - } - - delete rIt; - } -#endif // def RS_DEEP_CHANNEL_INDEX - } - - delete msg; - } - } - - return true; -} -bool RsGxsIntegrityCheck::isDone() -{ - RS_STACK_MUTEX(mIntegrityMutex); - return mDone; -} - -void RsGxsIntegrityCheck::getDeletedIds(std::vector& grpIds, GxsMsgReq& msgIds) -{ - RS_STACK_MUTEX(mIntegrityMutex); - grpIds = mDeletedGrps; - msgIds = mDeletedMsgs; -} - diff --git a/libretroshare/src/gxs/rsgxsutil.h b/libretroshare/src/gxs/rsgxsutil.h deleted file mode 100644 index 34f1b2baa..000000000 --- a/libretroshare/src/gxs/rsgxsutil.h +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsutil.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Christopher Evi-Parker * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include -#include "rsitems/rsnxsitems.h" -#include "rsgds.h" - -class RsGixs ; -class RsGenExchange ; -class RsGeneralDataService ; - -// temporary holds a map of pointers to class T, and destroys all pointers on delete. - -class non_copiable -{ -public: - non_copiable() {} -private: - non_copiable& operator=(const non_copiable&) { return *this ;} - non_copiable(const non_copiable&) {} -}; - -template -class t_RsGxsGenericDataTemporaryMap: public std::map, public non_copiable -{ -public: - virtual ~t_RsGxsGenericDataTemporaryMap() - { - clear() ; - } - - virtual void clear() - { - for(typename t_RsGxsGenericDataTemporaryMap::iterator it = this->begin();it!=this->end();++it) - if(it->second != NULL) - delete it->second ; - - std::map::clear() ; - } -}; - -template -class t_RsGxsGenericDataTemporaryMapVector: public std::map >, public non_copiable -{ -public: - virtual ~t_RsGxsGenericDataTemporaryMapVector() - { - clear() ; - } - - virtual void clear() - { - for(typename t_RsGxsGenericDataTemporaryMapVector::iterator it = this->begin();it!=this->end();++it) - { - for(uint32_t i=0;isecond.size();++i) - delete it->second[i] ; - - it->second.clear(); - } - - std::map >::clear() ; - } -}; - -template -class t_RsGxsGenericDataTemporaryList: public std::list, public non_copiable -{ -public: - virtual ~t_RsGxsGenericDataTemporaryList() - { - clear() ; - } - - virtual void clear() - { - for(typename t_RsGxsGenericDataTemporaryList::iterator it = this->begin();it!=this->end();++it) - delete *it; - - std::list::clear() ; - } -}; - -typedef std::map > RsGxsGrpMetaTemporaryMap; // This map doesn't need to delete elements since it holds -typedef std::map > > RsGxsMsgMetaTemporaryMap; // shared_ptr's. - -typedef t_RsGxsGenericDataTemporaryMap RsNxsGrpDataTemporaryMap; -typedef t_RsGxsGenericDataTemporaryMapVector RsNxsMsgDataTemporaryMap ; - -typedef t_RsGxsGenericDataTemporaryList RsNxsGrpDataTemporaryList ; -typedef t_RsGxsGenericDataTemporaryList RsNxsMsgDataTemporaryList ; - -inline RsGxsGrpMsgIdPair getMsgIdPair(RsNxsMsg& msg) -{ - return RsGxsGrpMsgIdPair(std::make_pair(msg.grpId, msg.msgId)); -} - -inline RsGxsGrpMsgIdPair getMsgIdPair(RsGxsMsgItem& msg) -{ - return RsGxsGrpMsgIdPair(std::make_pair(msg.meta.mGroupId, msg.meta.mMsgId)); -} - -/*! - * Does message clean up based on individual group expirations first - * if avialable. If not then deletion s - */ -class RsGxsCleanUp -{ -public: - - /*! - * - * @param dataService - * @param mGroupTS - * @param chunkSize - * @param sleepPeriod - */ - RsGxsCleanUp(RsGeneralDataService* const dataService, RsGenExchange *genex, uint32_t chunkSize); - - /*! - * On construction this should be called to progress deletions - * Deletion will process by chunk size - * @return true if no more messages to delete, false otherwise - */ - bool clean(RsGxsGroupId& next_group_to_check,std::vector& grps_to_delete,GxsMsgReq& messages_to_delete); - -private: - - RsGeneralDataService* const mDs; - RsGenExchange *mGenExchangeClient; - uint32_t CHUNK_SIZE; -}; - -/*! - * Checks the integrity message and groups - * in rsDataService using computed hash - */ -class RsGxsIntegrityCheck : public RsThread -{ - - enum CheckState { CheckStart, CheckChecking }; - -public: - - - /*! - * - * @param dataService - * @param mGroupTS - * @param chunkSize - * @param sleepPeriod - */ - RsGxsIntegrityCheck(RsGeneralDataService* const dataService, - RsGenExchange *genex, RsSerialType&, - RsGixs *gixs); - - static bool check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds); - bool isDone(); - - void run(); - - void getDeletedIds(std::vector &grpIds, GxsMsgReq &msgIds); - -private: - - RsGeneralDataService* const mDs; - RsGenExchange *mGenExchangeClient; - bool mDone; - RsMutex mIntegrityMutex; - std::vector mDeletedGrps; - GxsMsgReq mDeletedMsgs; - - RsGixs* mGixs; -}; - -/*! - * Checks the integrity message and groups - * in rsDataService using computed hash - */ -class RsGxsSinglePassIntegrityCheck -{ -public: - - /*! - * - * @param dataService - * @param mGroupTS - * @param chunkSize - * @param sleepPeriod - */ - static bool check(uint16_t service_type, RsGixs *mgixs, RsGeneralDataService *mds -#ifdef RS_DEEP_CHANNEL_INDEX - , RsGenExchange* mGenExchangeClient, RsSerialType& mSerializer -#endif - , std::vector& grpsToDel, GxsMsgReq& msgsToDel); -}; - -class GroupUpdate -{ -public: - GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false) - {} - const RsGxsGrpMetaData* oldGrpMeta; - RsNxsGrp* newGrp; - bool validUpdate; -}; - -class GroupUpdatePublish -{ -public: - GroupUpdatePublish(RsGxsGrpItem* item, uint32_t token) - : grpItem(item), mToken(token) {} - RsGxsGrpItem* grpItem; - uint32_t mToken; -}; - -class GroupDeletePublish -{ -public: - GroupDeletePublish(const RsGxsGroupId& grpId, uint32_t token) - : mGroupId(grpId), mToken(token) {} - RsGxsGroupId mGroupId; - uint32_t mToken; -}; - - -class MsgDeletePublish -{ -public: - MsgDeletePublish(const GxsMsgReq& msgs, uint32_t token) - : mMsgs(msgs), mToken(token) {} - - GxsMsgReq mMsgs ; - uint32_t mToken; -}; diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h deleted file mode 100644 index fb6238f92..000000000 --- a/libretroshare/src/gxs/rsnxs.h +++ /dev/null @@ -1,310 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsnxs.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * Copyright 2011-2011 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RSGNP_H -#define RSGNP_H - -#include -#include -#include "util/rstime.h" -#include -#include -#include - -#include "services/p3service.h" -#include "retroshare/rsreputations.h" -#include "retroshare/rsidentity.h" -#include "retroshare/rsturtle.h" -#include "rsgds.h" - -/*! - * Retroshare General Network Exchange Service: \n - * Interface: - * - This provides a module to service peer's requests for GXS messages \n - * and also request GXS messages from other peers. \n - * - The general mode of operation is to sychronise all messages/grps between - * peers - * - * The interface is sparse as this service is mostly making the requests to other GXS components - * - * Groups: - * - As this is where exchanges occur between peers, this is also where group's relationships - * should get resolved as far as - * - Per implemented GXS there are a set of rules which will determine whether data is transferred - * between any set of groups - * - * 1 allow transfers to any group - * 2 transfers only between group - * - the also group matrix settings which is by default everyone can transfer to each other - */ - -class RsNetworkExchangeService -{ -public: - - RsNetworkExchangeService(){ return;} - virtual ~RsNetworkExchangeService() {} - - virtual uint16_t serviceType() const =0; - /*! - * Use this to set how far back synchronisation of messages should take place - * @param age in seconds the max age a sync/store item can to be allowed in a synchronisation - */ - virtual void setSyncAge(const RsGxsGroupId& id,uint32_t age_in_secs) =0; - virtual void setKeepAge(const RsGxsGroupId& id,uint32_t age_in_secs) =0; - - virtual uint32_t getSyncAge(const RsGxsGroupId& id) =0; - virtual uint32_t getKeepAge(const RsGxsGroupId& id) =0; - - virtual void setDefaultKeepAge(uint32_t t) =0; - virtual void setDefaultSyncAge(uint32_t t) =0; - - virtual uint32_t getDefaultSyncAge() =0; - virtual uint32_t getDefaultKeepAge() =0; - - virtual bool msgAutoSync() const =0; - virtual bool grpAutoSync() const =0; - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// DISTANT SEARCH FUNCTIONS /// - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*! - * \brief turtleGroupRequest - * Requests a particular group meta data. The request protects the group ID. - * \param group_id - * \return - * returns the turtle request ID that might be associated to some results. - */ - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id)=0; - - /*! - * \brief turtleSearchRequest - * Uses distant search to match the substring to the group meta data. - * \param match_string - * \return - * returns the turtle request ID that might be associated to some results. - */ - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string)=0; - - /*! - * \brief receiveTurtleSearchResults - * Called by turtle (through RsGxsNetTunnel) when new results are received - * \param req Turtle search request ID associated with this result - * \param group_infos Group summary information for the groups returned by the search - */ - virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos)=0; - - /*! - * \brief receiveTurtleSearchResults - * Called by turtle (through RsGxsNetTunnel) when new data is received - * \param req Turtle search request ID associated with this result - * \param encrypted_group_data Group data - */ - virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)=0; - - /*! - * \brief retrieveTurtleSearchResults - * To be used to retrieve the search results that have been notified (or not) - * \param req request that match the results to retrieve - * \param group_infos results to retrieve. - * \return - * false when the request is unknown. - */ - virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &group_infos)=0; - /*! - * \brief getDistantSearchResults - * \param id - * \param group_infos - * \return - */ - virtual bool clearDistantSearchResults(const TurtleRequestId& id)=0; - virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSearchResults&)=0; - - virtual bool search(const std::string& substring,std::list& group_infos) =0; - virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)=0; - - /*! - * \brief getDistantSearchStatus - * Request status of a possibly ongoing/finished search. If UNKNOWN is returned, it means that no - * such group is under request - * \return - */ - virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId&) =0; - - /*! - * Initiates a search through the network - * This returns messages which contains the search terms set in RsGxsSearch - * @param search contains search terms of requested from service - * @param hops how far into friend tree for search - * @return search token that can be redeemed later, implementation should indicate how this should be used - */ - //virtual int searchMsgs(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0; - - /*! - * Initiates a search of groups through the network which goes - * a given number of hops deep into your friend network - * @param search contains search term requested from service - * @param hops number of hops deep into peer network - * @return search token that can be redeemed later - */ - //virtual int searchGrps(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0; - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// DATA ACCESS FUNCTIONS /// - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - /*! - * pauses synchronisation of subscribed groups and request for group id - * from peers - * @param enabled set to false to disable pause, and true otherwise - */ - virtual void pauseSynchronisation(bool enabled) = 0; - - - /*! - * Request for this message is sent through to peers on your network - * and how many hops from them you've indicated - * @param msgId the messages to retrieve - * @return request token to be redeemed - */ - virtual int requestMsg(const RsGxsGrpMsgIdPair& msgId) = 0; - - /*! - * Request for this group is sent through to peers on your network - * and how many hops from them you've indicated - * @param enabled set to false to disable pause, and true otherwise - * @return request token to be redeemed - */ - virtual int requestGrp(const std::list& grpId, const RsPeerId& peerId) = 0; - - /*! - * returns some stats about this group related to the network visibility. - * For now, only one statistics: - * max_known_messages: max number of messages reported by a friend. This is used to display unsubscribed group content. - */ - virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats)=0; - - virtual void subscribeStatusChanged(const RsGxsGroupId& id,bool subscribed) =0; - - /*! - * Request for this group is sent through to peers on your network - * and how many hops from them you've indicated - */ - virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::set& peers)=0 ; - - /*! - * \brief rejectMessage - * Tells the network exchange service to not download this message again, at least for some time (maybe 24h or more) - * in order to avoid cluttering the network pipe with copied of this rejected message. - * \param msgId - */ - virtual void rejectMessage(const RsGxsMessageId& msgId) =0; - - /*! - * \brief getGroupServerUpdateTS - * Returns the server update time stamp for that group. This is used for synchronisation of TS between - * various network exchange services, suhc as channels/circles or forums/circles - * \param gid group for that request - * \param tm time stamp computed - * \return false if the group is not found, true otherwise - */ - virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) =0; - - /*! - * \brief stampMsgServerUpdateTS - * Updates the msgServerUpdateMap structure to time(NULL), so as to trigger sending msg lists to friends. - * This is needed when e.g. posting a new message to a group. - * \param gid the group to stamp in msgServerUpdateMap - * \return - */ - virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) =0; - - /*! - * \brief isDistantPeer - * \param pid peer that is a virtual peer provided by GxsNetTunnel - * \return - * true if the peer exists (adn therefore is online) - */ - virtual bool isDistantPeer(const RsPeerId& pid)=0; - - /*! - * \brief removeGroups - * Removes time stamp information from the list of groups. This allows to re-sync them if suppliers are present. - * \param groups list of groups to remove from the update maps - * \return true if nothing bad happens. - */ - virtual bool removeGroups(const std::list& groups)=0; - - /*! - * \brief minReputationForForwardingMessages - * Encodes the policy for sending/requesting messages depending on anti-spam settings. - * - * \param group_sign_flags Sign flags from the group meta data - * \param identity_flags Flags of the identity - * \return - */ - static RsReputationLevel minReputationForRequestingMessages( - uint32_t /* group_sign_flags */, uint32_t /* identity_flags */ ) - { - // We always request messages, except if the author identity is locally banned. - return RsReputationLevel::REMOTELY_NEGATIVE; - } - static RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_flags ) - { - // If anti-spam is enabled, do not send messages from authors with bad reputation. The policy is to only forward messages if the reputation of the author is at least - // equal to the minimal reputation in the table below (R=remotely, L=locally, P=positive, N=negative, O=neutral) : - // - // - // +----------------------------------------------------+ - // | Identity flags | - // +----------------------------------------------------+ - // | Anonymous Signed Signed+Known | - // +-------------+-----------+----------------------------------------------------+ - // | |NONE | O O O | - // | Forum flags |GPG_AUTHED | RP O O | - // | |GPG_KNOWN | RP RP O | - // +-------------+-----------+----------------------------------------------------+ - // - - if(identity_flags & RS_IDENTITY_FLAGS_PGP_KNOWN) - return RsReputationLevel::NEUTRAL; - else if(identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED) - { - if(group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) - return RsReputationLevel::REMOTELY_POSITIVE; - else - return RsReputationLevel::NEUTRAL; - } - else - { - if( (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) || (group_sign_flags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) - return RsReputationLevel::REMOTELY_POSITIVE; - else - return RsReputationLevel::NEUTRAL; - } - } -}; - -#endif // RSGNP_H diff --git a/libretroshare/src/gxs/rsnxsobserver.h b/libretroshare/src/gxs/rsnxsobserver.h deleted file mode 100644 index 2da5067a4..000000000 --- a/libretroshare/src/gxs/rsnxsobserver.h +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxs: rsgxsobserver.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2012 by Robert Fernie, Evi-Parker Christopher * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSNXSOBSERVER_H -#define RSNXSOBSERVER_H - -#include -#include "rsitems/rsnxsitems.h" - -typedef uint32_t TurtleRequestId ; - -class RsNxsObserver -{ -public: - - RsNxsObserver() {} - - -public: - - /*! - * @param messages messages are deleted after function returns - */ - virtual void receiveNewMessages(const std::vector& messages) = 0; - - /*! - * @param groups groups are deleted after function returns - */ - virtual void receiveNewGroups(const std::vector& groups) = 0; - - /*! - * \brief receiveDistantSearchResults - * Called when new distant search result arrive. - * \param grpId - */ - virtual void receiveDistantSearchResults(TurtleRequestId /*id*/,const RsGxsGroupId& /*grpId*/) - { - std::cerr << __PRETTY_FUNCTION__ << ": not overloaded but still called. Nothing will happen." << std::endl; - } - - /*! - * @param grpId group id - */ - virtual void notifyReceivePublishKey(const RsGxsGroupId &grpId) = 0; - - /*! - * \brief notifyChangedGroupSyncParams - * \param caled when a group sync parameter is updated - */ - virtual void notifyChangedGroupSyncParams(const RsGxsGroupId &grpId) = 0; - /*! - * @param grpId group id - */ - virtual void notifyChangedGroupStats(const RsGxsGroupId &grpId) = 0; -}; - -#endif // RSNXSOBSERVER_H diff --git a/libretroshare/src/gxstrans/p3gxstrans.cc b/libretroshare/src/gxstrans/p3gxstrans.cc deleted file mode 100644 index 354cf812f..000000000 --- a/libretroshare/src/gxstrans/p3gxstrans.cc +++ /dev/null @@ -1,1405 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxstrans: p3gxstrans.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsdir.h" -#include "gxstrans/p3gxstrans.h" -#include "util/stacktrace.h" -#include "util/rsdebug.h" - -//#define DEBUG_GXSTRANS 1 - -typedef unsigned int uint; - -/*extern*/ RsGxsTrans* rsGxsTrans = nullptr; - -const uint32_t p3GxsTrans::MAX_DELAY_BETWEEN_CLEANUPS = 900; // every 15 mins. Could be less. - -p3GxsTrans::~p3GxsTrans() -{ - // (cyril) this cannot be called here! There's chances the thread that saves configs will be dead already! - //p3Config::saveConfiguration(); - - { - RS_STACK_MUTEX(mIngoingMutex); - for ( auto& kv : mIncomingQueue) delete kv.second; - } -} - -bool p3GxsTrans::getDataStatistics(GxsTransStatistics& stats) -{ - { - RS_STACK_MUTEX(mDataMutex); - stats.prefered_group_id = mPreferredGroupId; - } - stats.outgoing_records.clear(); - - { - RS_STACK_MUTEX(mOutgoingMutex); - - for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); ++it) - { - const OutgoingRecord& pr(it->second); - - RsGxsTransOutgoingRecord rec ; - rec.status = pr.status ; - rec.send_TS = pr.sent_ts ; - rec.group_id = pr.group_id ; - rec.trans_id = pr.mailItem.mailId ; - rec.recipient = pr.recipient ; - rec.data_size = pr.mailData.size(); - rec.data_hash = RsDirUtil::sha1sum(pr.mailData.data(),pr.mailData.size()); - rec.client_service = pr.clientService ; - - stats.outgoing_records.push_back(rec) ; - } - } - - return true; -} - -bool p3GxsTrans::sendData( RsGxsTransId& mailId, - GxsTransSubServices service, - const RsGxsId& own_gxsid, const RsGxsId& recipient, - const uint8_t* data, uint32_t size, - RsGxsTransEncryptionMode cm ) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::sendEmail(...)" << std::endl; -#endif - - if(!mIdService.isOwnId(own_gxsid)) - { - std::cerr << "p3GxsTrans::sendEmail(...) isOwnId(own_gxsid) false!" - << std::endl; - return false; - } - - if(recipient.isNull()) - { - std::cerr << "p3GxsTrans::sendEmail(...) got invalid recipient" - << std::endl; - print_stacktrace(); - return false; - } - - OutgoingRecord pr( recipient, service, data, size ); - - pr.mailItem.clear(); - pr.author = own_gxsid; //pr.mailItem.meta.mAuthorId = own_gxsid; - pr.mailItem.cryptoType = cm; - pr.mailItem.mailId = RSRandom::random_u64(); - - { - RS_STACK_MUTEX(mOutgoingMutex); - mOutgoingQueue.insert(prMap::value_type(pr.mailItem.mailId, pr)); - } - - mailId = pr.mailItem.mailId; - - IndicateConfigChanged(); // This causes the saving of the message after all data has been filled in. - return true; -} - -bool p3GxsTrans::querySendStatus(RsGxsTransId mailId, GxsTransSendStatus& st) -{ - RS_STACK_MUTEX(mOutgoingMutex); - auto it = mOutgoingQueue.find(mailId); - if( it != mOutgoingQueue.end() ) - { - st = it->second.status; - return true; - } - return false; -} - -void p3GxsTrans::registerGxsTransClient( - GxsTransSubServices serviceType, GxsTransClient* service) -{ - RS_STACK_MUTEX(mServClientsMutex); - mServClients[serviceType] = service; -} - -void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::handleResponse(" << token << ", " << req_type << ", " << status << ")" << std::endl; -#endif - if (status != RsTokenService::COMPLETE) - return; //For now, only manage Complete request - - bool changed = false ; - - switch (req_type) - { - case GROUPS_LIST: - { -#ifdef DEBUG_GXSTRANS - std::cerr << " Reviewing available groups. " << std::endl; -#endif - std::vector groups; - getGroupData(token, groups); - - // First recompute the prefered group Id. - - { - RS_STACK_MUTEX(mDataMutex); - - for( auto grp : groups ) - { - locked_supersedePreferredGroup(grp->meta.mGroupId); - - if(RsGenExchange::getStoragePeriod(grp->meta.mGroupId) != GXS_STORAGE_PERIOD) - { - std::cerr << "(WW) forcing storage period in GxsTrans group " << grp->meta.mGroupId << " to " << GXS_STORAGE_PERIOD << " seconds. Value was " << RsGenExchange::getStoragePeriod(grp->meta.mGroupId) << std::endl; - - RsGenExchange::setStoragePeriod(grp->meta.mGroupId,GXS_STORAGE_PERIOD) ; - } - } - } - -#ifdef DEBUG_GXSTRANS - std::cerr << " computed preferred group id: " << mPreferredGroupId << std::endl; -#endif - for( auto grp : groups ) - { - /* For each group check if it is better candidate then - * preferredGroupId, if it is supplant it and subscribe if it is not - * subscribed yet. - * Otherwise if it has recent messages subscribe. - * If the group was already subscribed has no recent messages - * unsubscribe. - */ - - const RsGroupMetaData& meta = grp->meta; - bool subscribed = IS_GROUP_SUBSCRIBED(meta.mSubscribeFlags); - - // if mLastPost is 0, then the group is not subscribed, so it only has impact on shouldSubscribe. In any case, a group - // with no information shouldn't be subscribed, so the olderThen() test is still valid in the case mLastPost=0. - - bool old = olderThen( meta.mLastPost, UNUSED_GROUP_UNSUBSCRIBE_INTERVAL ); - uint32_t token; - - bool shouldSubscribe = false ; - bool shouldUnSubscribe = false ; - { - RS_STACK_MUTEX(mDataMutex); - - shouldSubscribe = (!subscribed) && ((!old)|| meta.mGroupId == mPreferredGroupId ); - shouldUnSubscribe = ( subscribed) && old && meta.mGroupId != mPreferredGroupId; - } - -#ifdef DEBUG_GXSTRANS - std::cout << " group " << grp->meta.mGroupId << ", subscribed: " << subscribed << " last post: " << meta.mLastPost << " should subscribe: "<< shouldSubscribe - << ", should unsubscribe: " << shouldUnSubscribe << std::endl; -#endif - if(shouldSubscribe) - RsGenExchange::subscribeToGroup(token, meta.mGroupId, true); - else if(shouldUnSubscribe) - RsGenExchange::subscribeToGroup(token, meta.mGroupId, false); - -#ifdef GXS_MAIL_GRP_DEBUG - char buff[30]; - struct tm* timeinfo; - timeinfo = localtime(&meta.mLastPost); - strftime(buff, sizeof(buff), "%Y %b %d %H:%M", timeinfo); - - std::cout << "p3GxsTrans::handleResponse(...) GROUPS_LIST " - << "meta.mGroupId: " << meta.mGroupId - << " meta.mLastPost: " << buff - << " subscribed: " << subscribed - << " old: " << old - << " shoudlSubscribe: " << shoudlSubscribe - << " shoudlUnSubscribe: " << shoudlUnSubscribe - << std::endl; -#endif // GXS_MAIL_GRP_DEBUG - - delete grp; - } - - bool have_preferred_group = false ; - - { - RS_STACK_MUTEX(mDataMutex); - have_preferred_group = !mPreferredGroupId.isNull(); - } - - if(!have_preferred_group) - { - /* This is true only at first run when we haven't received mail - * distribuition groups from friends */ - -#ifdef DEBUG_GXSTRANS - std::cerr << "p3GxsTrans::handleResponse(...) preferredGroupId.isNu" - << "ll() let's create a new group." << std::endl; -#endif - uint32_t token; - publishGroup(token, new RsGxsTransGroupItem()); - queueRequest(token, GROUP_CREATE); - } - - break; - } - case GROUP_CREATE: - { -#ifdef DEBUG_GXSTRANS - std::cerr << "p3GxsTrans::handleResponse(...) GROUP_CREATE" << std::endl; -#endif - RsGxsGroupId grpId; - acknowledgeTokenGrp(token, grpId); - - RS_STACK_MUTEX(mDataMutex); - locked_supersedePreferredGroup(grpId); - break; - } - case MAILS_UPDATE: - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::handleResponse(...) MAILS_UPDATE" << std::endl; -#endif - typedef std::map > GxsMsgDataMap; - GxsMsgDataMap gpMsgMap; - getMsgData(token, gpMsgMap); - for ( GxsMsgDataMap::iterator gIt = gpMsgMap.begin(); - gIt != gpMsgMap.end(); ++gIt ) - { - typedef std::vector vT; - vT& mv(gIt->second); - for( vT::const_iterator mIt = mv.begin(); mIt != mv.end(); ++mIt ) - { - RsGxsMsgItem* gIt = *mIt; - switch(static_cast(gIt->PacketSubType())) - { - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL: - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT: - { - RsGxsTransBaseMsgItem* mb = dynamic_cast(*mIt); - - if(mb) - { - RS_STACK_MUTEX(mIngoingMutex); - mIncomingQueue.insert(inMap::value_type(mb->mailId,mb)); - - changed = true ; - } - else - std::cerr << "p3GxsTrans::handleResponse(...) " - << "GXS_MAIL_SUBTYPE_MAIL cast error, " - << "something really wrong is happening" - << std::endl; - break; - } - default: - std::cerr << "p3GxsTrans::handleResponse(...) MAILS_UPDATE " - << "Unknown mail subtype : " - << static_cast(gIt->PacketSubType()) - << std::endl; - delete gIt; - break; - } - } - } - break; - } - default: - std::cerr << "p3GxsTrans::handleResponse(...) Unknown req_type: " - << req_type << std::endl; - break; - } - - if(changed) - IndicateConfigChanged(); -} -void p3GxsTrans::GxsTransIntegrityCleanupThread::getPerUserStatistics(std::map& m) -{ - RS_STACK_MUTEX(mMtx) ; - - m = total_message_size_and_count ; -} - -void p3GxsTrans::GxsTransIntegrityCleanupThread::getMessagesToDelete(GxsMsgReq& m) -{ - RS_STACK_MUTEX(mMtx) ; - - m = mMsgToDel ; - mMsgToDel.clear(); -} - -// This method does two things: -// 1 - cleaning up old messages and messages for which an ACK has been received. -// 2 - building per user statistics across groups. This is important because it allows to mitigate the excess of -// messages, which might be due to spam. -// -// Note: the anti-spam system is disabled the level of GXS, because we want to allow to send anonymous messages -// between identities that might not have a reputation yet. Still, messages from identities with a bad reputation -// are still deleted by GXS. -// -// The group limits are enforced according to the following rules: -// * a temporal sliding window is computed for each identity and the number of messages signed by this identity is counted -// * -// -// -// Deleted messages are notified to the RsGxsNetService part which keeps a list of delete messages so as not to request them again -// during the same session. This allows to safely delete messages while avoiding re-synchronisation from friend nodes. - -void p3GxsTrans::GxsTransIntegrityCleanupThread::run() -{ - // first take out all the groups - - std::map grp; - mDs->retrieveNxsGrps(grp, true); - -#ifdef DEBUG_GXSTRANS - std::cerr << "GxsTransIntegrityCleanupThread::run()" << std::endl; -#endif - - // compute hash and compare to stored value, if it fails then simply add it - // to list - - GxsMsgReq grps; - for(std::map::iterator git = grp.begin(); git != grp.end(); ++git) - { - RsNxsGrp* grp = git->second; - - // store the group for retrieveNxsMsgs - grps[grp->grpId]; - - delete grp; - } - - // now messages - - std::map totalMessageSizeAndCount; - - std::map > stored_msgs ; - std::list received_msgs ; - - GxsMsgResult msgs; - mDs->retrieveNxsMsgs(grps, msgs, true); - - for(GxsMsgResult::iterator mit = msgs.begin();mit != msgs.end(); ++mit) - { - std::vector& msgV = mit->second; - std::vector::iterator vit = msgV.begin(); -#ifdef DEBUG_GXSTRANS - std::cerr << "Group " << mit->first << ": " << std::endl; -#endif - - for(; vit != msgV.end(); ++vit) - { - RsNxsMsg* msg = *vit; - - RsGxsTransSerializer s ; - uint32_t size = msg->msg.bin_len; - RsItem *item = s.deserialise(msg->msg.bin_data,&size); - RsGxsTransMailItem *mitem ; - RsGxsTransPresignedReceipt *pitem ; - - if(item == NULL) - std::cerr << " Unrecocognised item type!" << std::endl; - else if(NULL != (mitem = dynamic_cast(item))) - { -#ifdef DEBUG_GXSTRANS - std::cerr << " " << msg->metaData->mMsgId << ": Mail data with ID " << std::hex << std::setfill('0') << std::setw(16) << mitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl; -#endif - - stored_msgs[mitem->mailId] = std::make_pair(msg->metaData->mGroupId,msg->metaData->mMsgId) ; - } - else if(NULL != (pitem = dynamic_cast(item))) - { -#ifdef DEBUG_GXSTRANS - std::cerr << " " << msg->metaData->mMsgId << ": Signed rcpt of ID " << std::hex << pitem->mailId << std::dec << " from " << msg->metaData->mAuthorId << " size: " << msg->msg.bin_len << std::endl; -#endif - - received_msgs.push_back(pitem->mailId) ; - } - else - std::cerr << " Unknown item type!" << std::endl; - - totalMessageSizeAndCount[msg->metaData->mAuthorId].size += msg->msg.bin_len ; - totalMessageSizeAndCount[msg->metaData->mAuthorId].count++; - delete msg; - - delete item; - } - } - - // From the collected information, build a list of group messages to delete. - - GxsMsgReq msgsToDel ; - -#ifdef DEBUG_GXSTRANS - std::cerr << "Msg removal report:" << std::endl; - - std::cerr << " Per user size and count: " << std::endl; - for(std::map::const_iterator it(totalMessageSizeAndCount.begin());it!=totalMessageSizeAndCount.end();++it) - std::cerr << " " << it->first << ": " << it->second.count << " messages, for a total size of " << it->second.size << " bytes." << std::endl; -#endif - - for(std::list::const_iterator it(received_msgs.begin());it!=received_msgs.end();++it) - { - std::map >::const_iterator it2 = stored_msgs.find(*it) ; - - if(stored_msgs.end() != it2) - { - msgsToDel[it2->second.first].insert(it2->second.second); - -#ifdef DEBUG_GXSTRANS - std::cerr << " scheduling msg " << std::hex << it2->second.first << "," << it2->second.second << " for deletion." << std::endl; -#endif - } - } - - RS_STACK_MUTEX(mMtx) ; - mMsgToDel = msgsToDel ; - total_message_size_and_count = totalMessageSizeAndCount; - mDone = true; -} - -bool p3GxsTrans::GxsTransIntegrityCleanupThread::isDone() -{ - RS_STACK_MUTEX(mMtx) ; - return mDone ; -} -void p3GxsTrans::service_tick() -{ - GxsTokenQueue::checkRequests(); - - rstime_t now = time(NULL); - bool changed = false ; - - if(mLastMsgCleanup + MAX_DELAY_BETWEEN_CLEANUPS < now) - { - RS_STACK_MUTEX(mPerUserStatsMutex); - if(!mCleanupThread) - mCleanupThread = new GxsTransIntegrityCleanupThread(getDataStore()); - - if(mCleanupThread->isRunning()) - std::cerr << "Cleanup thread is already running. Not running it again!" << std::endl; - else - { -#ifdef DEBUG_GXSTRANS - std::cerr << "Starting GxsIntegrity cleanup thread." << std::endl; -#endif - - mCleanupThread->start() ; - mLastMsgCleanup = now ; - } - - // This forces to review all groups, and decide to subscribe or not to each of them. - - requestGroupsData(); - } - - // now grab collected messages to delete - - if(mCleanupThread != NULL && mCleanupThread->isDone()) - { - RS_STACK_MUTEX(mPerUserStatsMutex); - GxsMsgReq msgToDel ; - - mCleanupThread->getMessagesToDelete(msgToDel) ; - - if(!msgToDel.empty()) - { -#ifdef DEBUG_GXSTRANS - std::cerr << "p3GxsTrans::service_tick(): deleting messages." << std::endl; -#endif - uint32_t token ; - deleteMsgs(token,msgToDel); - } - - mCleanupThread->getPerUserStatistics(per_user_statistics) ; - -#ifdef DEBUG_GXSTRANS - std::cerr << "p3GxsTrans: Got new set of per user statistics:"<< std::endl; - for(std::map::const_iterator it(per_user_statistics.begin());it!=per_user_statistics.end();++it) - std::cerr << " " << it->first << ": " << it->second.count << " " << it->second.size << std::endl; -#endif - // Waiting here is very important because the thread may still be updating its semaphores after setting isDone() to true - // If we delete it during this operation it will corrupt the stack and cause unpredictable errors. - - while(mCleanupThread->isRunning()) - { - std::cerr << "Waiting for mCleanupThread to terminate..." << std::endl; - rstime::rs_usleep(500*1000); - } - - delete mCleanupThread; - mCleanupThread=NULL ; - } - - { - RS_STACK_MUTEX(mOutgoingMutex); - for ( auto it = mOutgoingQueue.begin(); it != mOutgoingQueue.end(); ) - { - OutgoingRecord& pr(it->second); - GxsTransSendStatus oldStatus = pr.status; - - locked_processOutgoingRecord(pr); - - if (oldStatus != pr.status) notifyClientService(pr); - if( pr.status >= GxsTransSendStatus::RECEIPT_RECEIVED ) - { - it = mOutgoingQueue.erase(it); - changed = true ; - } - else ++it; - } - } - - - { - RS_STACK_MUTEX(mIngoingMutex); - for( auto it = mIncomingQueue.begin(); it != mIncomingQueue.end(); ) - { - switch(static_cast( it->second->PacketSubType())) - { - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL: - { - RsGxsTransMailItem* msg = dynamic_cast(it->second); - - if(!msg) - { - std::cerr << "p3GxsTrans::service_tick() (EE) " - << "GXS_MAIL_SUBTYPE_MAIL dynamic_cast failed, " - << "something really wrong is happening!" - << std::endl; - } - else - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::service_tick() " - << "GXS_MAIL_SUBTYPE_MAIL handling: " - << msg->meta.mMsgId - << " with cryptoType: " - << static_cast(msg->cryptoType) - << " recipientHint: " << msg->recipientHint - << " mailId: "<< msg->mailId - << " payload.size(): " << msg->payload.size() - << std::endl; -#endif - handleEncryptedMail(msg); - } - break; - } - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT: - { - RsGxsTransPresignedReceipt* rcpt = dynamic_cast(it->second); - - if(!rcpt) - { - std::cerr << "p3GxsTrans::service_tick() (EE) " - << "GXS_MAIL_SUBTYPE_RECEIPT dynamic_cast failed," - << " something really wrong is happening!" - << std::endl; - } - else if(mIdService.isOwnId(rcpt->meta.mAuthorId)) - { - /* It is a receipt for a mail sent by this node live it in - * ingoingQueue so processOutgoingRecord(...) will take care - * of it at next tick */ - ++it; - continue; - } - else - { - /* It is a receipt for a message sent by someone else - * we can delete original mail from our GXS DB without - * waiting for GXS_STORAGE_PERIOD, this has been implemented - * already by Cyril into GxsTransIntegrityCleanupThread */ - } - break; - } - default: - std::cerr << "p3GxsTrans::service_tick() (EE) got something " - << "really unknown into ingoingQueue!!" << std::endl; - break; - } - - delete it->second ; - it = mIncomingQueue.erase(it); - changed = true ; - } - } - - if(changed) - IndicateConfigChanged(); -} - -RsGenExchange::ServiceCreate_Return p3GxsTrans::service_CreateGroup( - RsGxsGrpItem* /*grpItem*/, RsTlvSecurityKeySet& /*keySet*/ ) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::service_CreateGroup(...) " - << grpItem->meta.mGroupId << std::endl; -#endif - return SERVICE_CREATE_SUCCESS; -} - -void p3GxsTrans::notifyChanges(std::vector& changes) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl; -#endif - std::list grps_to_request; - GxsMsgReq msgs_to_request; - - for( auto it = changes.begin(); it != changes.end(); ++it ) - { - RsGxsGroupChange* grpChange = dynamic_cast(*it); - RsGxsMsgChange* msgChange = dynamic_cast(*it); - - if (grpChange) - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl; -#endif - grps_to_request.push_back(grpChange->mGroupId); - } - else if(msgChange) - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl; -#endif - - msgs_to_request[msgChange->mGroupId].insert(msgChange->mMsgId); - -#ifdef DEBUG_GXSTRANS - for( GxsMsgReq::const_iterator it = msgChange->msgChangeMap.begin(); - it != msgChange->msgChangeMap.end(); ++it ) - { - const RsGxsGroupId& grpId = it->first; - const std::vector& msgsIds = it->second; - typedef std::vector::const_iterator itT; - for(itT vit = msgsIds.begin(); vit != msgsIds.end(); ++vit) - { - const RsGxsMessageId& msgId = *vit; - std::cout << "p3GxsTrans::notifyChanges(...) got " - << "notification for message " << msgId - << " in group " << grpId << std::endl; - } - } -#endif - } - delete *it; - } - - if(!msgs_to_request.empty()) - { - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca, opts, msgs_to_request); - - GxsTokenQueue::queueRequest(token, MAILS_UPDATE); - } - - - if(!grps_to_request.empty()) - requestGroupsData(&grps_to_request); -} - -uint32_t p3GxsTrans::AuthenPolicy() -{ - uint32_t policy = 0; - uint32_t flag = 0; - - // This ensure propagated message have valid author signature - flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | - GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag( flag, policy, - RsGenExchange::PUBLIC_GRP_BITS ); - - /* This ensure that in for restricted and private groups only authorized - * authors get the messages. Really not used ATM but don't hurts. */ - flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | - GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag( flag, policy, - RsGenExchange::RESTRICTED_GRP_BITS ); - RsGenExchange::setAuthenPolicyFlag( flag, policy, - RsGenExchange::PRIVATE_GRP_BITS ); - - /* This seems never used RetroShare wide but we should investigate it - * more before considering this conclusive */ - flag = 0; - RsGenExchange::setAuthenPolicyFlag( flag, policy, - RsGenExchange::GRP_OPTION_BITS ); - - return policy; -} - -bool p3GxsTrans::requestGroupsData(const std::list* groupIds) -{ - // std::cout << "p3GxsTrans::requestGroupsList()" << std::endl; - uint32_t token=0; - RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - if(!groupIds) - RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts); - else - RsGenExchange::getTokenService()->requestGroupInfo(token, 0xcaca, opts, *groupIds); - - GxsTokenQueue::queueRequest(token, GROUPS_LIST); - return true; -} - -bool p3GxsTrans::handleEncryptedMail(const RsGxsTransMailItem* mail) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::handleEcryptedMail(...)" << std::endl; -#endif - - std::set decryptIds; - std::list ownIds; - mIdService.getOwnIds(ownIds); - for(auto it = ownIds.begin(); it != ownIds.end(); ++it) - if(mail->maybeRecipient(*it)) decryptIds.insert(*it); - - // Hint match none of our own ids - if(decryptIds.empty()) - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::handleEcryptedMail(...) hint doesn't match" << std::endl; -#endif - return true; - } - - switch (mail->cryptoType) - { - case RsGxsTransEncryptionMode::CLEAR_TEXT: - { - uint16_t csri = 0; - uint32_t off = 0; - getRawUInt16(&mail->payload[0], mail->payload.size(), &off, &csri); - -#ifdef DEBUG_GXSTRANS - std::cerr << "service: " << csri << " got CLEAR_TEXT mail!" - << std::endl; -#endif - /* As we cannot verify recipient without encryption, just pass the hint - * as recipient */ - return dispatchDecryptedMail( mail->meta.mAuthorId, mail->recipientHint, - &mail->payload[0], mail->payload.size() ); - } - case RsGxsTransEncryptionMode::RSA: - { - bool ok = true; - for( std::set::const_iterator it = decryptIds.begin(); - it != decryptIds.end(); ++it ) - { - const RsGxsId& decryptId(*it); - uint8_t* decrypted_data = NULL; - uint32_t decrypted_data_size = 0; - uint32_t decryption_error; - if( mIdService.decryptData( &mail->payload[0], - mail->payload.size(), decrypted_data, - decrypted_data_size, decryptId, - decryption_error ) ) - ok = ok && dispatchDecryptedMail( mail->meta.mAuthorId, - decryptId, decrypted_data, - decrypted_data_size ); - free(decrypted_data); - } - return ok; - } - default: - std::cout << "Unknown encryption type:" - << static_cast(mail->cryptoType) << std::endl; - return false; - } -} - -bool p3GxsTrans::dispatchDecryptedMail( const RsGxsId& authorId, - const RsGxsId& decryptId, - const uint8_t* decrypted_data, - uint32_t decrypted_data_size ) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::dispatchDecryptedMail(, , " << decrypted_data_size - << ")" << std::endl; -#endif - - uint16_t csri = 0; - uint32_t offset = 0; - if(!getRawUInt16( decrypted_data, decrypted_data_size, &offset, &csri)) - { - std::cerr << "p3GxsTrans::dispatchDecryptedMail(...) (EE) fatal error " - << "deserializing service type, something really wrong is " - << "happening!" << std::endl; - return false; - } - GxsTransSubServices rsrvc = static_cast(csri); - - uint32_t rcptsize = decrypted_data_size - offset; - RsNxsTransPresignedReceipt* receipt = - static_cast( - RsNxsSerialiser(RS_SERVICE_TYPE_GXS_TRANS).deserialise( - const_cast(&decrypted_data[offset]), &rcptsize )); - offset += rcptsize; - if(!receipt) - { - std::cerr << "p3GxsTrans::dispatchDecryptedMail(...) (EE) fatal error " - << "deserializing presigned return receipt , something really" - << " wrong is happening!" << std::endl; - return false; - } -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::dispatchDecryptedMail(...) dispatching receipt " - << "with: msgId: " << receipt->msgId << std::endl; -#endif - - std::vector rcct; rcct.push_back(receipt); - RsGenExchange::receiveNewMessages(rcct); - - GxsTransClient* recipientService = NULL; - { - RS_STACK_MUTEX(mServClientsMutex); - recipientService = mServClients[rsrvc]; - } - - if(recipientService) - return recipientService->receiveGxsTransMail( - authorId, decryptId, &decrypted_data[offset], - decrypted_data_size-offset ); - else - { - std::cerr << "p3GxsTrans::dispatchReceivedMail(...) " - << "got message for unknown service: " - << csri << std::endl; - return false; - } -} - -void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr) -{ - //std::cout << "p3GxsTrans::processRecord(...)" << std::endl; - - switch (pr.status) - { - case GxsTransSendStatus::PENDING_PROCESSING: - { - pr.mailItem.saltRecipientHint(pr.recipient); - pr.mailItem.saltRecipientHint(RsGxsId::random()); - pr.sent_ts = time(NULL) ; //pr.mailItem.meta.mPublishTs = time(NULL); - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_PREFERRED_GROUP: - { - RS_STACK_MUTEX(mDataMutex); - - if(mPreferredGroupId.isNull()) - { - requestGroupsData(); - pr.status = GxsTransSendStatus::PENDING_PREFERRED_GROUP; - break; - } - - pr.group_id = mPreferredGroupId ; //pr.mailItem.meta.mGroupId = mPreferredGroupId; - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_RECEIPT_CREATE: - { - RsGxsTransPresignedReceipt grcpt; - grcpt.meta.mAuthorId = pr.author ; //grcpt.meta = pr.mailItem.meta; - grcpt.meta.mGroupId = pr.group_id ; //grcpt.meta = pr.mailItem.meta; - grcpt.meta.mMsgId.clear() ; - grcpt.meta.mParentId.clear() ; - grcpt.meta.mOrigMsgId.clear() ; - grcpt.meta.mPublishTs = time(NULL); - grcpt.mailId = pr.mailItem.mailId; - uint32_t grsz = RsGxsTransSerializer().size(&grcpt); - std::vector grsrz; - grsrz.resize(grsz); - RsGxsTransSerializer().serialise(&grcpt, &grsrz[0], &grsz); - - { - RS_STACK_MUTEX(mDataMutex); - pr.presignedReceipt.grpId = mPreferredGroupId; - } - pr.presignedReceipt.metaData = new RsGxsMsgMetaData(); - *pr.presignedReceipt.metaData = grcpt.meta; - pr.presignedReceipt.msg.setBinData(&grsrz[0], grsz); - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_RECEIPT_SIGNATURE: // (cyril) This step is never actually used. - { - switch (RsGenExchange::createMessage(&pr.presignedReceipt)) - { - case CREATE_SUCCESS: break; - case CREATE_FAIL_TRY_LATER: - pr.status = GxsTransSendStatus::PENDING_RECEIPT_CREATE; - return; - default: - pr.status = GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE; - goto processingFailed; - } - - uint32_t metaSize = pr.presignedReceipt.metaData->serial_size(); - std::vector srx; srx.resize(metaSize); - pr.presignedReceipt.metaData->serialise(&srx[0], &metaSize); - pr.presignedReceipt.meta.setBinData(&srx[0], metaSize); - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_PAYLOAD_CREATE: - { - uint16_t serv = static_cast(pr.clientService); - uint32_t rcptsize = RsGxsTransSerializer().size(&pr.presignedReceipt); - uint32_t datasize = pr.mailData.size(); - pr.mailItem.payload.resize(2 + rcptsize + datasize); - uint32_t offset = 0; - setRawUInt16(&pr.mailItem.payload[0], 2, &offset, serv); - RsGxsTransSerializer().serialise(&pr.presignedReceipt, - &pr.mailItem.payload[offset], - &rcptsize); - offset += rcptsize; - memcpy(&pr.mailItem.payload[offset], &pr.mailData[0], datasize); - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_PAYLOAD_ENCRYPT: - { - switch (pr.mailItem.cryptoType) - { - case RsGxsTransEncryptionMode::CLEAR_TEXT: - { - RsWarn() << __PRETTY_FUNCTION__ << " you are sending a mail " - << "without encryption, everyone can read it!" - << std::endl; - break; - } - case RsGxsTransEncryptionMode::RSA: - { - uint8_t* encryptedData = NULL; - uint32_t encryptedSize = 0; - uint32_t encryptError = 0; - if( mIdService.encryptData( &pr.mailItem.payload[0], - pr.mailItem.payload.size(), - encryptedData, encryptedSize, - pr.recipient, encryptError, true ) ) - { - pr.mailItem.payload.resize(encryptedSize); - memcpy( &pr.mailItem.payload[0], encryptedData, encryptedSize ); - free(encryptedData); - break; - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " RSA encryption failed! " - << "error_status: " << encryptError << std::endl; - pr.status = GxsTransSendStatus::FAILED_ENCRYPTION; - goto processingFailed; - } - } - case RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION: - default: - RsErr() << __PRETTY_FUNCTION__ << " attempt to send mail with " - << "wrong EncryptionMode: " - << static_cast(pr.mailItem.cryptoType) - << " dropping mail!" << std::endl; - pr.status = GxsTransSendStatus::FAILED_ENCRYPTION; - goto processingFailed; - } - } - /* fallthrough */ - case GxsTransSendStatus::PENDING_PUBLISH: - { -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::sendEmail(...) sending mail to: " - << pr.recipient - << " with cryptoType: " - << static_cast(pr.mailItem.cryptoType) - << " recipientHint: " << pr.mailItem.recipientHint - << " receiptId: " << pr.mailItem.mailId - << " payload size: " << pr.mailItem.payload.size() - << std::endl; -#endif - - RsGxsTransMailItem *mail_item = new RsGxsTransMailItem(pr.mailItem); - - // pr.mailItem.meta is *not* serialised. So it is important to not rely on what's in it! - - mail_item->meta.mGroupId = pr.group_id ; - mail_item->meta.mAuthorId = pr.author ; - - mail_item->meta.mMsgId.clear(); - mail_item->meta.mParentId.clear(); - mail_item->meta.mOrigMsgId.clear(); - - uint32_t token; - publishMsg(token, mail_item) ; - - pr.status = GxsTransSendStatus::PENDING_RECEIPT_RECEIVE; - - IndicateConfigChanged(); // This causes the saving of the message after pr.status has changed. - break; - } - //case GxsTransSendStatus::PENDING_TRANSFER: - case GxsTransSendStatus::PENDING_RECEIPT_RECEIVE: - { - RS_STACK_MUTEX(mIngoingMutex); - auto range = mIncomingQueue.equal_range(pr.mailItem.mailId); - bool changed = false; - bool received = false; - - for( auto it = range.first; it != range.second; ++it) - { - RsGxsTransPresignedReceipt* rt = dynamic_cast(it->second); - - if(rt && mIdService.isOwnId(rt->meta.mAuthorId)) - { - mIncomingQueue.erase(it); delete rt; - pr.status = GxsTransSendStatus::RECEIPT_RECEIVED; - - changed = true; - received = true; - break; - } - } - - if(!received && time(nullptr) - pr.sent_ts > GXS_STORAGE_PERIOD) - { - changed = true; - pr.status = GxsTransSendStatus::FAILED_TIMED_OUT; - } - - if(changed) - IndicateConfigChanged(); - - break; - } - case GxsTransSendStatus::RECEIPT_RECEIVED: - break; - -processingFailed: - case GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE: - case GxsTransSendStatus::FAILED_ENCRYPTION: - case GxsTransSendStatus::FAILED_TIMED_OUT: - default: - RsErr() << __PRETTY_FUNCTION__ << " processing:" << pr.mailItem.mailId - << " failed with: " << static_cast(pr.status) - << std::endl; - break; - } -} - -void p3GxsTrans::notifyClientService(const OutgoingRecord& pr) -{ - RS_STACK_MUTEX(mServClientsMutex); - auto it = mServClients.find(pr.clientService); - if( it != mServClients.end()) - { - GxsTransClient* serv(it->second); - if(serv) - { - serv->notifyGxsTransSendStatus(pr.mailItem.mailId, pr.status); - return; - } - } - - std::cerr << "p3GxsTrans::processRecord(...) (EE) processed" - << " mail for unkown service: " - << static_cast(pr.clientService) - << " fatally failed with: " - << static_cast(pr.status) << std::endl; - print_stacktrace(); -} - -RsSerialiser* p3GxsTrans::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new RsGxsTransSerializer); - return rss; -} - -bool p3GxsTrans::saveList(bool &cleanup, std::list& saveList) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::saveList(...)" << saveList.size() << " " << mIncomingQueue.size() << " " << mOutgoingQueue.size() << std::endl; -#endif - - mOutgoingMutex.lock(); - mIngoingMutex.lock(); - - for ( auto& kv : mOutgoingQueue ) - { -#ifdef DEBUG_GXSTRANS - std::cerr << "Saving outgoing item, ID " << std::hex << std::setfill('0') << std::setw(16) << kv.first << std::dec << "Group id: " << kv.second.group_id << ", TS=" << kv.second.sent_ts << std::endl; -#endif - saveList.push_back(&kv.second); - } - for ( auto& kv : mIncomingQueue ) - { -#ifdef DEBUG_GXSTRANS - std::cerr << "Saving incoming item, ID " << std::hex << std::setfill('0') << std::setw(16) << kv.first << std::endl; -#endif - saveList.push_back(kv.second); - } - -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::saveList(...)" << saveList.size() << " " << mIncomingQueue.size() << " " << mOutgoingQueue.size() << std::endl; -#endif - - cleanup = false; - return true; -} - -void p3GxsTrans::saveDone() -{ - mOutgoingMutex.unlock(); - mIngoingMutex.unlock(); -} - -bool p3GxsTrans::loadList(std::list&loadList) -{ -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::loadList(...) " << loadList.size() << " " - << mIncomingQueue.size() << " " << mOutgoingQueue.size() - << std::endl; -#endif - - for(auto& v : loadList) - switch(static_cast(v->PacketSubType())) - { - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL: - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT: - { - RsGxsTransBaseMsgItem* mi = dynamic_cast(v); - if(mi) - { - RS_STACK_MUTEX(mIngoingMutex); - mIncomingQueue.insert(inMap::value_type(mi->mailId, mi)); - } - break; - } - case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM_deprecated: - { - OutgoingRecord_deprecated* dot = dynamic_cast(v); - - if(dot) - { - std::cerr << "(EE) Read a deprecated GxsTrans outgoing item. Converting to new format..." << std::endl; - - OutgoingRecord ot(dot->recipient,dot->clientService,&dot->mailData[0],dot->mailData.size()) ; - - ot.status = dot->status ; - - ot.author.clear(); // These 3 fields cannot be stored in mailItem.meta, which is not serialised, so they are lost. - ot.group_id.clear() ; - ot.sent_ts = 0; - - ot.mailItem = dot->mailItem ; - ot.presignedReceipt = dot->presignedReceipt; - - RS_STACK_MUTEX(mOutgoingMutex); - mOutgoingQueue.insert(prMap::value_type(ot.mailItem.mailId, ot)); - -#ifdef DEBUG_GXSTRANS - std::cerr << "Loaded outgoing item (converted), ID " << std::hex << std::setfill('0') << std::setw(16) << ot.mailItem.mailId<< std::dec << ", Group id: " << ot.group_id << ", TS=" << ot.sent_ts << std::endl; -#endif - } - delete v; - break; - } - - case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM: - { - OutgoingRecord* ot = dynamic_cast(v); - if(ot) - { - RS_STACK_MUTEX(mOutgoingMutex); - mOutgoingQueue.insert( - prMap::value_type(ot->mailItem.mailId, *ot)); - -#ifdef DEBUG_GXSTRANS - std::cerr << "Loading outgoing item, ID " << std::hex << std::setfill('0') << std::setw(16) << ot->mailItem.mailId<< std::dec << "Group id: " << ot->group_id << ", TS=" << ot->sent_ts << std::endl; -#endif - } - delete v; - break; - } - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP: - default: - std::cerr << "p3GxsTrans::loadList(...) (EE) got item with " - << "unhandled type: " - << static_cast(v->PacketSubType()) - << std::endl; - delete v; - break; - } - -#ifdef DEBUG_GXSTRANS - std::cout << "p3GxsTrans::loadList(...) " << loadList.size() << " " - << mIncomingQueue.size() << " " << mOutgoingQueue.size() - << std::endl; -#endif - - return true; -} - -bool p3GxsTrans::acceptNewMessage(const RsGxsMsgMetaData *msgMeta,uint32_t msg_size) -{ - // 1 - check the total size of the msgs for the author of this particular msg. - - // 2 - Reject depending on embedded limits. - - // Depending on reputation, the messages will be rejected: - // - // Reputation | Maximum msg count | Maximum msg size - // ------------+----------------------+------------------ - // Negative | 0 | 0 // This is already handled by the anti-spam - // R-Negative | 10 | 10k - // Neutral | 100 | 20k - // R-Positive | 400 | 1M - // Positive | 1000 | 2M - - // Ideally these values should be left as user-defined parameters, with the - // default values below used as backup. - - static const uint32_t GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT = 10 ; - static const uint32_t GXSTRANS_MAX_COUNT_NEUTRAL_DEFAULT = 40 ; - static const uint32_t GXSTRANS_MAX_COUNT_REMOTELY_POSITIVE_DEFAULT = 400 ; - static const uint32_t GXSTRANS_MAX_COUNT_LOCALLY_POSITIVE_DEFAULT = 1000 ; - - static const uint32_t GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT = 10 * 1024 ; - static const uint32_t GXSTRANS_MAX_SIZE_NEUTRAL_DEFAULT = 200 * 1024 ; - static const uint32_t GXSTRANS_MAX_SIZE_REMOTELY_POSITIVE_DEFAULT = 1024 * 1024 ; - static const uint32_t GXSTRANS_MAX_SIZE_LOCALLY_POSITIVE_DEFAULT = 2 * 1024 * 1024 ; - - uint32_t max_count = 0 ; - uint32_t max_size = 0 ; - uint32_t identity_flags = 0 ; - - RsReputationLevel rep_lev = - rsReputations->overallReputationLevel( - msgMeta->mAuthorId, &identity_flags ); - - switch(rep_lev) - { - case RsReputationLevel::REMOTELY_NEGATIVE: - max_count = GXSTRANS_MAX_COUNT_REMOTELY_NEGATIVE_DEFAULT; - max_size = GXSTRANS_MAX_SIZE_REMOTELY_NEGATIVE_DEFAULT; - break ; - case RsReputationLevel::NEUTRAL: - max_count = GXSTRANS_MAX_COUNT_NEUTRAL_DEFAULT; - max_size = GXSTRANS_MAX_SIZE_NEUTRAL_DEFAULT; - break; - case RsReputationLevel::REMOTELY_POSITIVE: - max_count = GXSTRANS_MAX_COUNT_REMOTELY_POSITIVE_DEFAULT; - max_size = GXSTRANS_MAX_SIZE_REMOTELY_POSITIVE_DEFAULT; - break; - case RsReputationLevel::LOCALLY_POSITIVE: - max_count = GXSTRANS_MAX_COUNT_LOCALLY_POSITIVE_DEFAULT; - max_size = GXSTRANS_MAX_SIZE_LOCALLY_POSITIVE_DEFAULT; - break; - case RsReputationLevel::LOCALLY_NEGATIVE: // fallthrough - default: - max_count = 0; - max_size = 0; - break; - } - - bool pgp_linked = identity_flags & RS_IDENTITY_FLAGS_PGP_LINKED; - - if(rep_lev <= RsReputationLevel::NEUTRAL && !pgp_linked) - { - max_count /= 10 ; - max_size /= 10 ; - } - - RS_STACK_MUTEX(mPerUserStatsMutex); - - MsgSizeCount& s(per_user_statistics[msgMeta->mAuthorId]); - -#ifdef DEBUG_GXSTRANS - std::cerr << "GxsTrans::acceptMessage(): size=" << msg_size << ", grp=" << msgMeta->mGroupId << ", gxs_id=" << msgMeta->mAuthorId << ", pgp_linked=" << pgp_linked << ", current (size,cnt)=(" - << s.size << "," << s.count << ") reputation=" << rep_lev << ", limits=(" << max_size << "," << max_count << ") " ; -#endif - - if(s.size + msg_size > max_size || 1+s.count > max_count) - { -#ifdef DEBUG_GXSTRANS - std::cerr << "=> rejected." << std::endl; -#endif - return false ; - } - else - { -#ifdef DEBUG_GXSTRANS - std::cerr << "=> accepted." << std::endl; -#endif - - s.count++ ; - s.size += msg_size ; // update the statistics, so that it's not possible to pass a bunch of msgs at once below the limits. - - return true ; - } -} - - -bool p3GxsTrans::getGroupStatistics(std::map& stats) -{ - uint32_t token1; - - RsTokReqOptions opts1; - opts1.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token1, opts1) || waitToken(token1) != RsTokenService::COMPLETE ) - return false; - - std::list group_metas; - getGroupSummary(token1,group_metas); - - for(auto& group_meta:group_metas) - { - RsGxsTransGroupStatistics& stat(stats[group_meta.mGroupId]); - - uint32_t token2; - if(!RsGxsIfaceHelper::requestGroupStatistic(token2,group_meta.mGroupId) || waitToken(token2) != RsTokenService::COMPLETE) - continue; - - RsGenExchange::getGroupStatistic(token2,stat); - - stat.popularity = group_meta.mPop ; - stat.subscribed = IS_GROUP_SUBSCRIBED(group_meta.mSubscribeFlags) ; - stat.mGrpId = group_meta.mGroupId ; - - std::vector metas; - - uint32_t token3; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_META; - - std::list groupIds; - groupIds.push_back(group_meta.mGroupId); - - if( !requestMsgInfo(token3, opts, groupIds) || waitToken(token3, std::chrono::seconds(5)) != RsTokenService::COMPLETE ) - continue; - - GxsMsgMetaMap metaMap; - if(!RsGenExchange::getMsgMeta(token3, metaMap) || metaMap.size() != 1) - continue; - - for(auto& meta: metaMap.begin()->second) - stat.addMessageMeta(group_meta.mGroupId,meta) ; - } - - return true; -} - - diff --git a/libretroshare/src/gxstrans/p3gxstrans.h b/libretroshare/src/gxstrans/p3gxstrans.h deleted file mode 100644 index 688a9cd22..000000000 --- a/libretroshare/src/gxstrans/p3gxstrans.h +++ /dev/null @@ -1,343 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxstrans: p3gxstrans.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "retroshare/rsgxsifacetypes.h" // For RsGxsId, RsGxsCircleId -#include "gxs/gxstokenqueue.h" // For GxsTokenQueue -#include "gxstrans/p3gxstransitems.h" -#include "services/p3idservice.h" // For p3IdService -#include "util/rsthreads.h" -#include "retroshare/rsgxstrans.h" - -class p3GxsTrans; - -/// Services who want to make use of p3GxsTrans should inherit this struct -struct GxsTransClient -{ - /** - * This will be called by p3GxsTrans to dispatch mails to the subservice - * @param authorId message sender - * @param decryptId recipient id - * @param data buffer containing the decrypted data - * @param dataSize size of the buffer - * @return true if dispatching goes fine, false otherwise - */ - virtual bool receiveGxsTransMail( const RsGxsId& authorId, - const RsGxsId& recipientId, - const uint8_t* data, uint32_t dataSize - ) = 0; - - /** - * This will be called by p3GxsTrans to notify the subservice about the - * status of a sent email. - * @param originalMessage message for with the notification is made - * @param status the new status of the message - * @return true if notification goes fine, false otherwise (ignored ATM) - */ - virtual bool notifyGxsTransSendStatus( RsGxsTransId mailId, - GxsTransSendStatus status ) = 0; -}; - -struct MsgSizeCount -{ - MsgSizeCount() : size(0),count(0) {} - - uint32_t size ; - uint32_t count ; -}; - -/** - * @brief p3GxsTrans asyncronous redundant small mail trasport on top of GXS. - * p3GxsTrans is capable of asynchronous mail delivery and acknowledgement. - * p3GxsTrans is meant to be capable of multiple encryption options, - * @see RsGxsTransEncryptionMode at moment messages are encrypted using RSA - * unless the user ask for them being sent in clear text ( this is not supposed - * to happen in non testing environment so warnings and stack traces are printed - * in the log if an attempt to send something in clear text is made ). - * p3GxsTrans try to hide metadata so the travelling message signed by the author - * but the recipient is not disclosed, instead to avoid everyone trying to - * decrypt every message a hint has been introduced, the hint is calculated in a - * way that one can easily prove that a message is not destined to someone, but - * cannot prove the message is destined to someone - * @see RsGxsTransMailItem::recipientHint for more details. - * p3GxsTrans expose a simple API to send and receive mails, the API also - * provide notification for the sending mail status @see sendMail(...), - * @see querySendStatus(...), @see registerGxsTransClient(...), - * @see GxsTransClient::receiveGxsTransMail(...), - * @see GxsTransClient::notifyGxsTransSendStatus(...). - */ -class p3GxsTrans : public RsGenExchange, public GxsTokenQueue, public p3Config, public RsGxsTrans -{ -public: - p3GxsTrans( RsGeneralDataService* gds, RsNetworkExchangeService* nes, - p3IdService& identities ) : - RsGenExchange( gds, nes, new RsGxsTransSerializer(), - RS_SERVICE_TYPE_GXS_TRANS, &identities, - AuthenPolicy()), - GxsTokenQueue(this), - RsGxsTrans(static_cast(*this)), - // always check 30 secs after start) - mLastMsgCleanup(time(NULL) - MAX_DELAY_BETWEEN_CLEANUPS + 30), - mIdService(identities), - mServClientsMutex("p3GxsTrans client services map mutex"), - mOutgoingMutex("p3GxsTrans outgoing queue map mutex"), - mIngoingMutex("p3GxsTrans ingoing queue map mutex"), - mCleanupThread(nullptr), - mPerUserStatsMutex("p3GxsTrans user stats mutex"), - mDataMutex("p3GxsTrans data mutex") {} - - virtual ~p3GxsTrans(); - - /*! - * \brief getStatistics - * Gathers all sorts of statistics about the data transported by p3GxsTrans, in order to display info about the running status, - * message transport, etc. This is a blocking call. Use it in a thread. - * \param stats This structure contains all statistics information. - * \return true is the call succeeds. - */ - - virtual bool getDataStatistics(GxsTransStatistics& stats) override; - - /*! - * \brief getGroupStatistics - * Gathers statistics about GXS groups and messages used by GxsTrans to transport data. This is a blocking call. Use it in a thread. - * \param stats - * \return true if the data collection succeeds. - */ - virtual bool getGroupStatistics(std::map& stats) override; - - /** - * Send an email to recipient, in the process author of the email is - * disclosed to the network (because the sent GXS item is signed), while - * recipient is not @see RsGxsTransMailItem::recipientHint for details on - * recipient protection. - * This method is part of the public interface of this service. - * @return true if the mail will be sent, false if not - */ - bool sendData( RsGxsTransId& mailId, - GxsTransSubServices service, - const RsGxsId& own_gxsid, const RsGxsId& recipient, - const uint8_t* data, uint32_t size, - RsGxsTransEncryptionMode cm = RsGxsTransEncryptionMode::RSA - ); - - /** - * This method is part of the public interface of this service. - * @return false if mail is not found in outgoing queue, true otherwise - */ - bool querySendStatus( RsGxsTransId mailId, GxsTransSendStatus& st ); - - /** - * Register a client service to p3GxsTrans to receive mails via - * GxsTransClient::receiveGxsTransMail(...) callback - * This method is part of the public interface of this service. - */ - void registerGxsTransClient( GxsTransSubServices serviceType, - GxsTransClient* service ); - - /// @see RsGenExchange::getServiceInfo() - virtual RsServiceInfo getServiceInfo() override { return RsServiceInfo( RS_SERVICE_TYPE_GXS_TRANS, "GXS Mails", 0, 1, 0, 1 ); } - - static const uint32_t GXS_STORAGE_PERIOD = 15*86400; // 15 days. - static const uint32_t GXS_SYNC_PERIOD = 15*86400; -private: - /** Time interval of inactivity before a distribution group is unsubscribed. - * Approximatively 3 months seems ok ATM. */ - const static int32_t UNUSED_GROUP_UNSUBSCRIBE_INTERVAL = 16*86400; // 16 days - - /** - * This should be as little as possible as the size of the database can grow - * very fast taking in account we are handling mails for the whole network. - * We do prefer to resend a not acknowledged yet mail after - * GXS_STORAGE_PERIOD has passed and keep it little. - * Tought it can't be too little as this may cause signed receipts to - * get lost thus causing resend and fastly grow perceived async latency, in - * case two sporadically connected users sends mails each other. - * While it is ok for signed acknowledged to stays in the DB for a - * full GXS_STORAGE_PERIOD, mails should be removed as soon as a valid - * signed acknowledged is received for each of them. - * Two weeks seems fair ATM. - */ - static const uint32_t MAX_DELAY_BETWEEN_CLEANUPS ; // every 20 mins. Could be less. - - rstime_t mLastMsgCleanup ; - - /// Define how the backend should handle authentication based on signatures - static uint32_t AuthenPolicy(); - - /// Types to mark queries in tokens queue - enum GxsReqResTypes - { - GROUPS_LIST = 1, - GROUP_CREATE = 2, - MAILS_UPDATE = 3 - }; - - /// Store the id of the preferred GXS group to send emails - RsGxsGroupId mPreferredGroupId; - - /// Used for items {de,en}cryption - p3IdService& mIdService; - - /// Stores pointers to client services to notify them about new mails - std::map mServClients; - RsMutex mServClientsMutex; - - /** - * @brief Keep track of outgoing mails. - * Records enter the queue when a mail is sent, and are removed when a - * receipt has been received or sending is considered definetly failed. - * Items are saved in config for consistence accross RetroShare shutdowns. - */ - typedef std::map prMap; - prMap mOutgoingQueue; - RsMutex mOutgoingMutex; - void locked_processOutgoingRecord(OutgoingRecord& r); - - /** - * @brief Ingoing mail and receipt processing queue. - * At shutdown remaining items are saved in config and then deleted in - * destructor for consistence accross RetroShare instances. - * In order to avoid malicious messages ( non malicious collision has 1/2^64 - * probablity ) to smash items in the queue thus causing previous incoming - * item to not being processed and memleaked multimap is used instead of map - * for incoming queue. - */ - typedef std::unordered_multimap inMap; - inMap mIncomingQueue; - RsMutex mIngoingMutex; - - /// @see GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type - /// , RsTokenService::GxsRequestStatus status) - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - /// @see RsGenExchange::service_tick() - virtual void service_tick() override; - - /// @see RsGenExchange::service_CreateGroup(...) - RsGenExchange::ServiceCreate_Return service_CreateGroup( - RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& ) override; - - /// @see RsGenExchange::notifyChanges(std::vector &changes) - void notifyChanges(std::vector &changes) override; - - /// @see p3Config::setupSerialiser() - virtual RsSerialiser* setupSerialiser() override; - - /// @see p3Config::saveList(bool &cleanup, std::list&) - virtual bool saveList(bool &cleanup, std::list&saveList) override; - - /// @see p3Config::saveDone() - void saveDone() override; - - /// @see p3Config::loadList(std::list&) - virtual bool loadList(std::list& loadList) override; - - /// Request groups list to GXS backend. Async method. - bool requestGroupsData(const std::list* groupIds = NULL); - - /** - * Check if current preferredGroupId is the best against potentialGrId, if - * the passed one is better update it. - * Useful when GXS backend notifies groups changes, or when a reponse to an - * async grop request (@see GXS_REQUEST_TYPE_GROUP_*) is received. - * @return true if preferredGroupId has been supeseded by potentialGrId - * false otherwise. - */ - bool inline locked_supersedePreferredGroup(const RsGxsGroupId& potentialGrId) - { - if(mPreferredGroupId < potentialGrId) - { - std::cerr << "supersedePreferredGroup(...) " << potentialGrId - << " supersed " << mPreferredGroupId << std::endl; - mPreferredGroupId = potentialGrId; - return true; - } - return false; - } - - /** @return true if has passed more then interval seconds between timeStamp - * and ref. @param ref by default now is taked as reference. */ - bool static inline olderThen(rstime_t timeStamp, int32_t interval, - rstime_t ref = time(NULL)) - { return (timeStamp + interval) < ref; } - - - /// Decrypt email content and pass it to dispatchDecryptedMail(...) - bool handleEncryptedMail(const RsGxsTransMailItem* mail); - - /// Dispatch the message to the recipient service - bool dispatchDecryptedMail( const RsGxsId& authorId, - const RsGxsId& decryptId, - const uint8_t* decrypted_data, - uint32_t decrypted_data_size ); - - void notifyClientService(const OutgoingRecord& pr); - - /// Checks the integrity message and groups - class GxsTransIntegrityCleanupThread : public RsThread - { - enum CheckState { CheckStart, CheckChecking }; - - public: - explicit GxsTransIntegrityCleanupThread( - RsGeneralDataService* const dataService ): - mDs(dataService), mMtx("GxsTransIntegrityCheck"), mDone(false) {} - - bool isDone(); - void run(); - - void getDeletedIds(std::list& grpIds, std::map >& msgIds); - - void getMessagesToDelete(GxsMsgReq& req) ; - void getPerUserStatistics(std::map& m) ; - - private: - RsGeneralDataService* const mDs; - RsMutex mMtx ; - - GxsMsgReq mMsgToDel ; - std::map total_message_size_and_count; - bool mDone; - }; - - // Overloaded from RsGenExchange. - - bool acceptNewMessage(const RsGxsMsgMetaData *msgMeta, uint32_t size) override; - - GxsTransIntegrityCleanupThread *mCleanupThread ; - - // statistics of the load across all groups, per user. - - RsMutex mPerUserStatsMutex; - std::map per_user_statistics ; - - // Mutex to protect local data - - RsMutex mDataMutex; -}; - diff --git a/libretroshare/src/gxstrans/p3gxstransitems.cc b/libretroshare/src/gxstrans/p3gxstransitems.cc deleted file mode 100644 index 733d40bec..000000000 --- a/libretroshare/src/gxstrans/p3gxstransitems.cc +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxstrans: p3gxstrans.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "gxstrans/p3gxstransitems.h" -#include "serialiser/rstypeserializer.h" - -const RsGxsId RsGxsTransMailItem::allRecipientsHint("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); - -OutgoingRecord_deprecated::OutgoingRecord_deprecated() - : RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TRANS, static_cast(GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM_deprecated) ) { clear();} - -OutgoingRecord::OutgoingRecord() - : RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TRANS, static_cast(GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM) ) { clear();} - -OutgoingRecord::OutgoingRecord( RsGxsId rec, GxsTransSubServices cs, - const uint8_t* data, uint32_t size ) : - RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TRANS, - static_cast(GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM) ), - status(GxsTransSendStatus::PENDING_PROCESSING), recipient(rec), - clientService(cs) -{ - mailData.resize(size); - memcpy(&mailData[0], data, size); -} - -void OutgoingRecord_deprecated::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(status); - RS_SERIAL_PROCESS(recipient); - RS_SERIAL_PROCESS(mailItem); - RS_SERIAL_PROCESS(mailData); - RS_SERIAL_PROCESS(clientService); - RS_SERIAL_PROCESS(presignedReceipt); -} - -void OutgoingRecord::serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) -{ - RS_SERIAL_PROCESS(status); - RS_SERIAL_PROCESS(recipient); - RS_SERIAL_PROCESS(author); - RS_SERIAL_PROCESS(group_id); - RS_SERIAL_PROCESS(sent_ts); - RS_SERIAL_PROCESS(mailItem); - RS_SERIAL_PROCESS(mailData); - RS_SERIAL_PROCESS(clientService); - RS_SERIAL_PROCESS(presignedReceipt); -} diff --git a/libretroshare/src/gxstrans/p3gxstransitems.h b/libretroshare/src/gxstrans/p3gxstransitems.h deleted file mode 100644 index f2cab3cfe..000000000 --- a/libretroshare/src/gxstrans/p3gxstransitems.h +++ /dev/null @@ -1,270 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxstrans: p3gxstrans.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2017 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include "rsitems/rsgxsitems.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvidset.h" -#include "retroshare/rsgxsflags.h" -#include "retroshare/rsgxstrans.h" -#include "retroshare/rsgxscircles.h" // For: GXS_CIRCLE_TYPE_PUBLIC -#include "services/p3idservice.h" -#include "serialiser/rstypeserializer.h" - -class RsNxsTransPresignedReceipt : public RsNxsMsg -{ -public: - RsNxsTransPresignedReceipt() : RsNxsMsg(RS_SERVICE_TYPE_GXS_TRANS) {} - - virtual ~RsNxsTransPresignedReceipt() {} -}; - -class RsGxsTransBaseMsgItem : public RsGxsMsgItem -{ -public: - explicit RsGxsTransBaseMsgItem(GxsTransItemsSubtypes subtype) : - RsGxsMsgItem( RS_SERVICE_TYPE_GXS_TRANS, - static_cast(subtype) ), mailId(0) {} - - virtual ~RsGxsTransBaseMsgItem() {} - - RsGxsTransId mailId; - - void inline clear() - { - mailId = 0; - meta = RsMsgMetaData(); - } - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { RS_SERIAL_PROCESS(mailId); } -}; - -class RsGxsTransPresignedReceipt : public RsGxsTransBaseMsgItem -{ -public: - RsGxsTransPresignedReceipt() : RsGxsTransBaseMsgItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT) {} - virtual ~RsGxsTransPresignedReceipt() {} -}; - -enum class RsGxsTransEncryptionMode : uint8_t -{ - CLEAR_TEXT = 1, - RSA = 2, - UNDEFINED_ENCRYPTION = 250 -}; - -class RsGxsTransMailItem : public RsGxsTransBaseMsgItem -{ -public: - RsGxsTransMailItem() : - RsGxsTransBaseMsgItem(GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL), - cryptoType(RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION) {} - - virtual ~RsGxsTransMailItem() {} - - RsGxsTransEncryptionMode cryptoType; - - /** - * @brief recipientHint used instead of plain recipient id, so sender can - * decide the equilibrium between exposing the recipient and the cost of - * completely anonymize it. So a bunch of luky non recipient can conclude - * rapidly that they are not the recipient without trying to decrypt the - * message. - * - * To be able to decide how much metadata we disclose sending a message we - * send an hint instead of the recipient id in clear, the hint cannot be - * false (the recipient would discard the mail) but may be arbitrarly - * obscure like 0xFF...FF so potentially everyone could be the recipient, or - * may expose the complete recipient id or be a middle ground. - * To calculate arbitrary precise hint one do a bitwise OR of the recipients - * keys and an arbitrary salt, the more recipients has the mail and the more - * 1 bits has the salt the less accurate is the hint. - * This way the sender is able to adjust the metadata privacy needed for the - * message, in the more private case (recipientHint == 0xFFF...FFF) no one - * has a clue about who is the actual recipient, while this imply the cost - * that every potencial recipient has to try to decrypt it to know if it is - * for herself. This way a bunch of non recipients can rapidly discover that - * the message is not directed to them without attempting it's decryption. - * - * To check if one id may be the recipient of the mail or not one need to - * bitwise compare the hint with the id, if at least one bit of the hint is - * 0 while the corresponding bit in the id is 1 then the id cannot be the - * recipient of the mail. - * - * Note that by design one can prove that an id is not recipient of the mail - * but cannot prove it is. - * Also in the extreme case of using 0x00...00 as salt that is equivalent - * to not salting at all (aka the plain recipient id is used as hint) a - * malicious observer could not demostrate in a conclusive manner that the - * mail is directed to the actual recipient as the "apparently" - * corresponding hint may be fruit of a "luky" salting of another id. - */ - RsGxsId recipientHint; - void inline saltRecipientHint(const RsGxsId& salt) - { recipientHint = recipientHint | salt; } - - /** - * @brief maybeRecipient given an id and an hint check if they match - * @see recipientHint - * @return true if the id may be recipient of the hint, false otherwise - */ - bool inline maybeRecipient(const RsGxsId& id) const - { return (~id|recipientHint) == allRecipientsHint; } - - const static RsGxsId allRecipientsHint; - - /** This should travel encrypted, unless EncryptionMode::CLEAR_TEXT - * is specified */ - std::vector payload; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RsGxsTransBaseMsgItem::serial_process(j, ctx); - RS_SERIAL_PROCESS(cryptoType); - RS_SERIAL_PROCESS(recipientHint); - RS_SERIAL_PROCESS(payload); - } - - void clear() - { - RsGxsTransBaseMsgItem::clear(); - cryptoType = RsGxsTransEncryptionMode::UNDEFINED_ENCRYPTION; - recipientHint.clear(); - payload.clear(); - } - - /// Maximum mail size in bytes 10 MiB is more than anything sane can need - const static uint32_t MAX_SIZE = 10*8*1024*1024; -}; - -class RsGxsTransGroupItem : public RsGxsGrpItem -{ -public: - RsGxsTransGroupItem() : - RsGxsGrpItem( RS_SERVICE_TYPE_GXS_TRANS, - static_cast( - GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP) ) - { - meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - meta.mGroupName = "Mail"; - meta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC; - } - virtual ~RsGxsTransGroupItem() {} - - // TODO: Talk with Cyril why there is no RsGxsGrpItem::serial_process - virtual void serial_process(RsGenericSerializer::SerializeJob /*j*/, - RsGenericSerializer::SerializeContext& /*ctx*/) - {} - - void clear() {} -}; - -class RsGxsTransSerializer; - -class OutgoingRecord_deprecated : public RsItem -{ -public: - OutgoingRecord_deprecated( RsGxsId rec, GxsTransSubServices cs, const uint8_t* data, uint32_t size ); - - virtual ~OutgoingRecord_deprecated() {} - - GxsTransSendStatus status; - RsGxsId recipient; - /// Don't use a pointer would be invalid after publish - RsGxsTransMailItem mailItem; - - std::vector mailData; - GxsTransSubServices clientService; - - RsNxsTransPresignedReceipt presignedReceipt; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - - void clear() {} - -private: - friend class RsGxsTransSerializer; - OutgoingRecord_deprecated(); -}; - -class OutgoingRecord : public RsItem -{ -public: - OutgoingRecord( RsGxsId rec, GxsTransSubServices cs, - const uint8_t* data, uint32_t size ); - - virtual ~OutgoingRecord() {} - - GxsTransSendStatus status; - RsGxsId recipient; - - RsGxsId author; // These 3 fields cannot be stored in mailItem.meta, which is not serialised. - RsGxsGroupId group_id ; - uint32_t sent_ts ; - - /// Don't use a pointer would be invalid after publish - RsGxsTransMailItem mailItem; - - std::vector mailData; - GxsTransSubServices clientService; - - RsNxsTransPresignedReceipt presignedReceipt; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - - void clear() {} - -private: - friend class RsGxsTransSerializer; - OutgoingRecord(); -}; - - -class RsGxsTransSerializer : public RsServiceSerializer -{ -public: - RsGxsTransSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_GXS_TRANS) {} - virtual ~RsGxsTransSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_TYPE_GXS_TRANS) return NULL; - - switch(static_cast(item_sub_id)) - { - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_MAIL: return new RsGxsTransMailItem(); - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_RECEIPT: return new RsGxsTransPresignedReceipt(); - case GxsTransItemsSubtypes::GXS_TRANS_SUBTYPE_GROUP: return new RsGxsTransGroupItem(); - case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM_deprecated: return new OutgoingRecord_deprecated(); - case GxsTransItemsSubtypes::OUTGOING_RECORD_ITEM: return new OutgoingRecord(); - default: return NULL; - } - } -}; - diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc deleted file mode 100644 index e500f82b0..000000000 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ /dev/null @@ -1,1774 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distantchat.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "openssl/rand.h" -#include "openssl/dh.h" -#include "openssl/err.h" - -#include "crypto/rsaes.h" -#include "util/rsprint.h" -#include "util/rsmemory.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "p3gxstunnel.h" - -//#define DEBUG_GXS_TUNNEL - -static const uint32_t GXS_TUNNEL_KEEP_ALIVE_TIMEOUT = 6 ; // send keep alive packet so as to avoid tunnel breaks. - -static const uint32_t RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED = 0x0000 ; -static const uint32_t RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE = 0x0001 ; -static const uint32_t RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE = 0x0002 ; - -static const uint32_t RS_GXS_TUNNEL_DELAY_BETWEEN_RESEND = 10 ; // re-send every 10 secs. -static const uint32_t RS_GXS_TUNNEL_DATA_PRINT_STORAGE_DELAY = 600 ; // store old message ids for 10 minutes. - -static const uint32_t GXS_TUNNEL_ENCRYPTION_HMAC_SIZE = SHA_DIGEST_LENGTH ; -static const uint32_t GXS_TUNNEL_ENCRYPTION_IV_SIZE = 8 ; - -#ifdef DEBUG_GXS_TUNNEL -static const uint32_t INTERVAL_BETWEEN_DEBUG_DUMP = 10 ; -#endif - -static std::string GXS_TUNNEL_APP_NAME = "GxsTunnels" ; - -static const uint8_t GXS_TUNNEL_APP_MAJOR_VERSION = 0x01 ; -static const uint8_t GXS_TUNNEL_APP_MINOR_VERSION = 0x00 ; -static const uint8_t GXS_TUNNEL_MIN_MAJOR_VERSION = 0x01 ; -static const uint8_t GXS_TUNNEL_MIN_MINOR_VERSION = 0x00 ; - -RsGxsTunnelService *rsGxsTunnel = NULL ; - -p3GxsTunnelService::p3GxsTunnelService(RsGixs *pids) - : mGixs(pids), mGxsTunnelMtx("GXS tunnel") -{ - mTurtle = NULL ; - mCurrentPacketCounter = 0 ; -} - -void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr) -{ - mTurtle = tr ; - tr->registerTunnelService(this) ; -} - -bool p3GxsTunnelService::registerClientService(uint32_t service_id,RsGxsTunnelService::RsGxsTunnelClientService *service) -{ - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - if(mRegisteredServices.find(service_id) != mRegisteredServices.end()) - { - std::cerr << "(EE) p3GxsTunnelService::registerClientService(): trying to register client " << std::hex << service_id << std::dec << ", which is already registered!" << std::endl; - return false; - } -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::registerClientService(): registering client service " << std::hex << service_id << std::dec << std::endl; -#endif - - mRegisteredServices[service_id] = service ; - return true ; -} - -int p3GxsTunnelService::tick() -{ - -#ifdef DEBUG_GXS_TUNNEL - rstime_t now = time(NULL); - static rstime_t last_dump = 0; - - if(now > last_dump + INTERVAL_BETWEEN_DEBUG_DUMP ) - { - last_dump = now ; - debug_dump() ; - } -#endif - - flush() ; - - return 0 ; -} - -RsServiceInfo p3GxsTunnelService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_GXS_TUNNEL, - GXS_TUNNEL_APP_NAME, - GXS_TUNNEL_APP_MAJOR_VERSION, - GXS_TUNNEL_APP_MINOR_VERSION, - GXS_TUNNEL_MIN_MAJOR_VERSION, - GXS_TUNNEL_MIN_MINOR_VERSION); -} - -void p3GxsTunnelService::flush() -{ - // Flush pending DH items. This is a higher priority, so we deal with them first. - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::flush() flushing pending items." << std::endl; -#endif - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - for(std::list::iterator it=pendingDHItems.begin();it!=pendingDHItems.end();) - if(locked_sendClearTunnelData(*it) ) - { - delete *it ; - it = pendingDHItems.erase(it) ; - } - else - ++it ; - } - - // Flush items that could not be sent, probably because of a Mutex protected zone. - // - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - for(std::list::iterator it=pendingGxsTunnelItems.begin();it!=pendingGxsTunnelItems.end();) - if(locked_sendEncryptedTunnelData(*it) ) - { - delete *it ; - it = pendingGxsTunnelItems.erase(it) ; - } - else - { - ++it ; -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "Cannot send encrypted data item to tunnel " << (*it)->PeerId() << std::endl; -#endif - } - } - - // Look at pending data item, and re-send them if necessary. - - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - for(std::map::iterator it = pendingGxsTunnelDataItems.begin();it != pendingGxsTunnelDataItems.end();++it) - if(now > RS_GXS_TUNNEL_DELAY_BETWEEN_RESEND + it->second.last_sending_attempt) - { - if(locked_sendEncryptedTunnelData(it->second.data_item)) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " sending data item #" << std::hex << it->first << std::dec << std::endl; -#endif - it->second.last_sending_attempt = now ; - } -#ifdef DEBUG_GXS_TUNNEL - else - std::cerr << " Cannot send item " << std::hex << it->first << std::dec << std::endl; -#endif - } - } - - // TODO: also sweep GXS id map and disable any ID with no virtual peer id in the list. - - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - for(std::map::iterator it(_gxs_tunnel_contacts.begin());it!=_gxs_tunnel_contacts.end();) - { - // All sorts of cleaning. We start with the ones that may remove stuff, for efficiency reasons. - - // 1 - Remove any tunnel that was remotely closed, since we cannot use it anymore. - - if(it->second.status == RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED && it->second.last_contact + 20 < now) - { - std::map::iterator tmp = it ; - ++tmp ; - _gxs_tunnel_contacts.erase(it) ; - it=tmp ; - continue ; - } - - // 2 - re-digg tunnels that have died out of inaction - - if(it->second.last_contact+20+GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) GxsTunnelService:: connection interrupted with peer." << std::endl; -#endif - - it->second.status = RS_GXS_TUNNEL_STATUS_TUNNEL_DN ; - it->second.virtual_peer_id.clear() ; - - // Also reset turtle router monitoring so as to make the tunnel handling more responsive. If we don't do that, - // the TR will wait 60 secs for the tunnel to die, which causes a significant waiting time in the chat window. - - if(it->second.direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) GxsTunnelService:: forcing new tunnel campain." << std::endl; -#endif - - mTurtle->forceReDiggTunnels( randomHashFromDestinationGxsId(it->second.to_gxs_id) ); - } - } - - // send keep alive packets to active tunnels. - - if(it->second.last_keep_alive_sent + GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) - { - RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; - - cs->status = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE; - cs->PeerId(RsPeerId(it->first)) ; - - // we send off-mutex to avoid deadlock. - - pendingGxsTunnelItems.push_back(cs) ; - - it->second.last_keep_alive_sent = now ; -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) GxsTunnelService:: Sending keep alive packet to gxs id " << it->first << std::endl; -#endif - } - - // clean old received data prints. - - for(std::map::iterator it2=it->second.received_data_prints.begin();it2!=it->second.received_data_prints.end();) - if(now > it2->second + RS_GXS_TUNNEL_DATA_PRINT_STORAGE_DELAY) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) erasing old data print for message #" << it2->first << " in tunnel " << it->first << std::endl; -#endif - std::map::iterator tmp(it2) ; - ++tmp ; - it->second.received_data_prints.erase(it2) ; - it2 = tmp ; - } - else - ++it2 ; - - ++it ; - } -} - -// In this function the PeerId is the GXS tunnel ID. - -void p3GxsTunnelService::handleIncomingItem(const RsGxsTunnelId& tunnel_id,RsGxsTunnelItem *item) -{ - if(item == NULL) - return ; - - // We have 3 things to do: - // - // 1 - if it's a data item, send an ACK - // 2 - if it's an ack item, mark the item as properly received, and remove it from the queue - // 3 - if it's a status item, act accordingly. - - switch(item->PacketSubType()) - { - - case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: handleRecvTunnelDataItem(tunnel_id,dynamic_cast(item)) ; - break ; - - case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: handleRecvTunnelDataAckItem(tunnel_id,dynamic_cast(item)) ; - break ; - - case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(tunnel_id,dynamic_cast(item)) ; - break ; - - default: - std::cerr << "(EE) impossible situation. DH items should be handled at the service level" << std::endl; - } - - delete item ; -} - -void p3GxsTunnelService::handleRecvTunnelDataAckItem(const RsGxsTunnelId &/*id*/,RsGxsTunnelDataAckItem *item) -{ - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::handling RecvTunnelDataAckItem()" << std::endl; - std::cerr << " item counter = " << std::hex << item->unique_item_counter << std::dec << std::endl; -#endif - - // remove it from the queue. - - std::map::iterator it = pendingGxsTunnelDataItems.find(item->unique_item_counter) ; - - if(it == pendingGxsTunnelDataItems.end()) - { - std::cerr << " (EE) item number " << std::hex << item->unique_item_counter << std::dec << " is unknown. This is unexpected." << std::endl; - return ; - } - - delete it->second.data_item ; - pendingGxsTunnelDataItems.erase(it) ; -} - -void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id,RsGxsTunnelDataItem *item) -{ - // imediately send an ACK for this item - - RsGxsTunnelDataAckItem *ackitem = new RsGxsTunnelDataAckItem ; - - ackitem->unique_item_counter = item->unique_item_counter ; - ackitem->PeerId(RsPeerId(tunnel_id)) ; - - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - pendingGxsTunnelItems.push_back(ackitem) ; // we use the queue that does not need an ACK, in order to avoid an infinite loop ;-) - } - - // notify the client for the received data - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::handleRecvTunnelDataItem()" << std::endl; - std::cerr << " data size = " << item->data_size << std::endl; - std::cerr << " service id = " << std::hex << item->service_id << std::dec << std::endl; - std::cerr << " counter id = " << std::hex << item->unique_item_counter << std::dec << std::endl; -#endif - - RsGxsTunnelClientService *service = NULL ; - RsGxsId peer_from ; - bool is_client_side = false ; - - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - std::map::const_iterator it = mRegisteredServices.find(item->service_id) ; - - if(it == mRegisteredServices.end()) - { - std::cerr << " (EE) no registered service with ID " << std::hex << item->service_id << std::dec << ". Rejecting item." << std::endl; - return ; - } - service = it->second ; - - std::map::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it2 != _gxs_tunnel_contacts.end()) - { - it2->second.client_services.insert(item->service_id) ; - peer_from = it2->second.to_gxs_id ; - is_client_side = (it2->second.direction == RsTurtleGenericDataItem::DIRECTION_SERVER); - } - - // Check if the item has already been received. This is necessary because we actually re-send items until an ACK is received. If the ACK gets lost (connection interrupted) the - // item may be received twice. This is conservative and ensure that no item is lost nor received twice. - - if(it2->second.received_data_prints.find(item->unique_item_counter) != it2->second.received_data_prints.end()) - { - std::cerr << "(WW) received the same data item #" << std::hex << item->unique_item_counter << std::dec << " twice in last 20 mins. Tunnel id=" << tunnel_id << ". Probably a replay. Item will be dropped." << std::endl; - return ; - } - it2->second.received_data_prints[item->unique_item_counter] = time(NULL) ; - } - - if(service->acceptDataFromPeer(peer_from,tunnel_id,is_client_side)) - service->receiveData(tunnel_id,item->data,item->data_size) ; - - item->data = NULL ; // avoids deletion, since the client has the memory now - item->data_size = 0 ; -} - -void p3GxsTunnelService::handleRecvStatusItem(const RsGxsTunnelId& tunnel_id, RsGxsTunnelStatusItem *cs) -{ - std::vector notifications ; - std::set clients ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::handleRecvStatusItem(): tunnel_id=" << tunnel_id << " status=" << cs->status << std::endl; -#endif - - switch(cs->status) - { - case RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION: - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) Cannot mark tunnel connection as closed. No connection openned for tunnel id " << tunnel_id << ". Unexpected situation." << std::endl; - return ; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Marking distant chat as remotely closed for tunnel id " << tunnel_id << std::endl; -#endif - if(it->second.direction == RsTurtleGenericDataItem::DIRECTION_CLIENT) - { - it->second.status = RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED ; -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " This is server side. The tunnel cannot be re-openned, so we give it up." << std::endl; -#endif - } - else - { - it->second.status = RS_GXS_TUNNEL_STATUS_TUNNEL_DN ; -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " This is client side. The tunnel will be re-openned automatically." << std::endl; -#endif - } - - notifications.push_back(RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED) ; - } // nothing more to do, because the decryption routing will update the last_contact time when decrypting. - break ; - - case RS_GXS_TUNNEL_FLAG_KEEP_ALIVE: -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl; -#endif - break ; - - case RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION: - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "Received ACK item from the distant peer!" << std::endl; -#endif - - // in this case we notify the clients using this tunnel. - - notifications.push_back(RS_GXS_TUNNEL_STATUS_CAN_TALK) ; - } - break ; - - default: - std::cerr << "(EE) unhandled tunnel status " << std::hex << cs->status << std::dec << std::endl; - break ; - } - - // notify all clients - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " notifying clients. Prending notifications: " << notifications.size() << std::endl; -#endif - - if(notifications.size() > 0) - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " " << it->second.client_services.size() << " client services for tunnel id " << tunnel_id << std::endl; -#endif - - for(std::set::const_iterator it2(it->second.client_services.begin());it2!=it->second.client_services.end();++it2) - { - std::map::const_iterator it3=mRegisteredServices.find(*it2) ; - - if(it3 != mRegisteredServices.end()) - clients.insert(it3->second) ; - } - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " notifying " << clients.size() << " clients." << std::endl; -#endif - - for(std::set::const_iterator it(clients.begin());it!=clients.end();++it) - for(uint32_t i=0;inotifyTunnelStatus(tunnel_id,notifications[i]) ; -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " notifying client " << (void*)(*it) << " of status " << notifications[i] << std::endl; -#endif - } -} - -bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/) -{ - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - // look into owned GXS ids, and see if the hash corresponds to the expected hash - // - std::list own_id_list ; - rsIdentity->getOwnIds(own_id_list) ; - - // extract the GXS id from the hash - - RsGxsId destination_id = destinationGxsIdFromHash(hash) ; - - // linear search. Not costly because we have typically a low number of IDs. Otherwise, this really should be avoided! - - for(std::list::const_iterator it(own_id_list.begin());it!=own_id_list.end();++it) - if(*it == destination_id) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::handleTunnelRequest: received tunnel request for hash " << hash << std::endl; - std::cerr << " answering true!" << std::endl; -#endif - return true ; - } - - return false ; -} - -void p3GxsTunnelService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) -{ -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService:: received new virtual peer " << virtual_peer_id << " for hash " << hash << ", dir=" << dir << std::endl; -#endif - RsGxsId own_gxs_id ; - - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - GxsTunnelDHInfo& dhinfo( _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ) ; - dhinfo.gxs_id.clear() ; - - if(dhinfo.dh != NULL) - DH_free(dhinfo.dh) ; - - dhinfo.dh = NULL ; - dhinfo.direction = dir ; - dhinfo.hash = hash ; - dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ; - dhinfo.tunnel_id.clear(); - - if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) // server side - { - // check that a tunnel is not already working for this hash. If so, give up. - - own_gxs_id = destinationGxsIdFromHash(hash) ; - } - else // client side - { - std::map::const_iterator it = _gxs_tunnel_contacts.begin(); - - while(it != _gxs_tunnel_contacts.end() && it->second.hash != hash) ++it ; - - if(it == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) no pre-registered peer for hash " << hash << " on client side. This is a bug." << std::endl; - return ; - } - - if(it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " virtual peer is for a distant chat session that is already openned and alive. Giving it up." << std::endl; -#endif - return ; - } - - own_gxs_id = it->second.own_gxs_id ; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Creating new virtual peer ID entry and empty DH session key." << std::endl; -#endif - - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl; -#endif - - // Start a new DH session for this tunnel - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - locked_restartDHSession(virtual_peer_id,own_gxs_id) ; -} - -void p3GxsTunnelService::locked_restartDHSession(const RsPeerId& virtual_peer_id,const RsGxsId& own_gxs_id) -{ -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "Starting new DH session." << std::endl; -#endif - GxsTunnelDHInfo& dhinfo = _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ; // creates it, if necessary - - dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ; - dhinfo.own_gxs_id = own_gxs_id ; - - if(!locked_initDHSessionKey(dhinfo.dh)) - { - std::cerr << " (EE) Cannot start DH session. Something went wrong." << std::endl; - return ; - } - dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE ; - - if(!locked_sendDHPublicKey(dhinfo.dh,own_gxs_id,virtual_peer_id)) - std::cerr << " (EE) Cannot send DH public key. Something went wrong." << std::endl; -} - -void p3GxsTunnelService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) -{ - bool tunnel_dn = false ; - std::set client_services ; - RsGxsTunnelId tunnel_id ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService: Removing virtual peer " << virtual_peer_id << " for hash " << hash << std::endl; -#else - /* remove unused parameter warnings */ - (void) hash; -#endif - { - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - RsGxsId gxs_id ; - std::map::iterator it = _gxs_tunnel_virtual_peer_ids.find(virtual_peer_id) ; - - if(it == _gxs_tunnel_virtual_peer_ids.end()) - { - std::cerr << "(EE) Cannot remove virtual peer " << virtual_peer_id << ": not found in tunnel list!!" << std::endl; - return ; - } - - tunnel_id = it->second.tunnel_id ; - - if(it->second.dh != NULL) - DH_free(it->second.dh) ; - - _gxs_tunnel_virtual_peer_ids.erase(it) ; - - std::map::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it2 == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) Cannot find tunnel id " << tunnel_id << " in contact list. Weird." << std::endl; - return ; - } - if(it2->second.virtual_peer_id == virtual_peer_id) - { - it2->second.status = RS_GXS_TUNNEL_STATUS_TUNNEL_DN ; - it2->second.virtual_peer_id.clear() ; - tunnel_dn = true ; - } - - for(std::set::const_iterator it(it2->second.client_services.begin());it!=it2->second.client_services.end();++it) - { - std::map::const_iterator it2 = mRegisteredServices.find(*it) ; - - if(it2 != mRegisteredServices.end()) - client_services.insert(it2->second) ; - } - } - - if(tunnel_dn) - { - // notify all client services that this tunnel is down - - for(std::set::const_iterator it(client_services.begin());it!=client_services.end();++it) - (*it)->notifyTunnelStatus(tunnel_id,RS_GXS_TUNNEL_STATUS_TUNNEL_DN) ; - } -} - -void p3GxsTunnelService::receiveTurtleData(const RsTurtleGenericTunnelItem *gitem, const RsFileHash& hash, const RsPeerId& virtual_peer_id, RsTurtleGenericTunnelItem::Direction direction) -{ -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::receiveTurtleData(): Received turtle data. " << std::endl; - std::cerr << " hash = " << hash << std::endl; - std::cerr << " vpid = " << virtual_peer_id << std::endl; - std::cerr << " acting as = " << direction << std::endl; -#else - /* remove unused parameter warnings */ - (void) direction; -#endif - - void *data_bytes; - uint32_t data_size ; - bool accept_fast_items = false; - - const RsTurtleGenericFastDataItem *fitem = dynamic_cast(gitem) ; - - if(fitem != NULL) - { - data_bytes = fitem->data_bytes ; - data_size = fitem->data_size ; - accept_fast_items = true; - } - else - { - const RsTurtleGenericDataItem *item = dynamic_cast(gitem) ; - - if(item == NULL) - { - std::cerr << "(EE) item is not a data item. That is an error." << std::endl; - return ; - } - data_bytes = item->data_bytes ; - data_size = item->data_size ; - } - - // Call the AES crypto module - // - the IV is the first 8 bytes of item->data_bytes - - if(data_size < 8) - { - std::cerr << "(EE) item encrypted data stream is too small: size = " << data_size << std::endl; - return ; - } - if(*((uint64_t*)data_bytes) != 0) // WTF?? we should use flags - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Item is encrypted." << std::endl; -#endif - - // if cannot decrypt, it means the key is wrong. We need to re-negociate a new key. - - handleEncryptedData((uint8_t*)data_bytes,data_size,hash,virtual_peer_id,accept_fast_items) ; - } - else - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Item is not encrypted." << std::endl; -#endif - - // Now try deserialise the decrypted data to make an RsItem out of it. - // - uint32_t pktsize = data_size-8; - RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)data_bytes)[8],&pktsize) ; - - if(citem == NULL) - { - std::cerr << "(EE) item could not be de-serialized. That is an error." << std::endl; - return ; - } - - // DH key items are sent even before we know who we speak to, so the virtual peer id is used in this - // case only. - RsGxsTunnelDHPublicKeyItem *dhitem = dynamic_cast(citem) ; - - if(dhitem != NULL) - { - dhitem->PeerId(virtual_peer_id) ; - handleRecvDHPublicKey(dhitem) ; - } - else - std::cerr << "(EE) Deserialiased item has unexpected type." << std::endl; - - delete citem ; - } -} - -// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel. - -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 -bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id,bool accepts_fast_items) -#else -bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) -#endif -{ -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::handleEncryptedDataItem()" << std::endl; - std::cerr << " size = " << data_size << std::endl; - std::cerr << " data = " << (void*)data_bytes << std::endl; - std::cerr << " IV = " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; - std::cerr << " data = " << RsUtil::BinToHex((unsigned char*)data_bytes,data_size,100) ; - std::cerr << std::endl; -#endif - - RsGxsTunnelItem *citem = NULL; - RsGxsTunnelId tunnel_id; - - { - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - uint32_t encrypted_size = data_size - GXS_TUNNEL_ENCRYPTION_IV_SIZE - GXS_TUNNEL_ENCRYPTION_HMAC_SIZE; - uint32_t decrypted_size = RsAES::get_buffer_size(encrypted_size); - uint8_t *encrypted_data = (uint8_t*)data_bytes+GXS_TUNNEL_ENCRYPTION_IV_SIZE+GXS_TUNNEL_ENCRYPTION_HMAC_SIZE; - - RsTemporaryMemory decrypted_data(decrypted_size); - uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; - - if(!decrypted_data) - return false ; - - std::map::iterator it = _gxs_tunnel_virtual_peer_ids.find(virtual_peer_id) ; - - if(it == _gxs_tunnel_virtual_peer_ids.end()) - { - std::cerr << "(EE) item is not coming out of a registered tunnel. Weird. hash=" << hash << ", peer id = " << virtual_peer_id << std::endl; - return false ; - } - - tunnel_id = it->second.tunnel_id ; - std::map::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it2 == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) no tunnel data for tunnel ID=" << tunnel_id << ". This is a bug." << std::endl; - return false ; - } -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 - if(accepts_fast_items) - { - if(!it2->second.accepts_fast_turtle_items) - std::cerr << "(II) received probe for Fast track turtle items for tunnel VPID " << it2->second.virtual_peer_id << ": switching to Fast items mode." << std::endl; - - it2->second.accepts_fast_turtle_items = true; - } -#endif - - memcpy(aes_key,it2->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Using IV: " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; - std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl; - std::cerr << " key : " << RsUtil::BinToHex((unsigned char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) << std::endl; - std::cerr << " hmac : " << RsUtil::BinToHex((unsigned char*)data_bytes+GXS_TUNNEL_ENCRYPTION_IV_SIZE,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl; - std::cerr << " data : " << RsUtil::BinToHex((unsigned char*)data_bytes,data_size,100) << std::endl; -#endif - // first, check the HMAC - - unsigned char *hm = HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,NULL,NULL) ; - - if(memcmp(hm,&data_bytes[GXS_TUNNEL_ENCRYPTION_IV_SIZE],GXS_TUNNEL_ENCRYPTION_HMAC_SIZE)) - { - std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << RsUtil::BinToHex((char*)hm,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl; - std::cerr << "(EE) resetting new DH session." << std::endl; - - locked_restartDHSession(virtual_peer_id,it2->second.own_gxs_id) ; - - return false ; - } - - if(!RsAES::aes_decrypt_8_16(encrypted_data,encrypted_size, aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size)) - { - std::cerr << "(EE) packet decryption failed." << std::endl; - std::cerr << "(EE) resetting new DH session." << std::endl; - - locked_restartDHSession(virtual_peer_id,it2->second.own_gxs_id) ; - - return false ; - } - it2->second.status = RS_GXS_TUNNEL_STATUS_CAN_TALK ; - it2->second.last_contact = time(NULL) ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) Decrypted data: size=" << decrypted_size << std::endl; -#endif - - // Now try deserialise the decrypted data to make an RsItem out of it. - // - citem = dynamic_cast(RsGxsTunnelSerialiser().deserialise(decrypted_data,&decrypted_size)) ; - - if(citem == NULL) - { - std::cerr << "(EE) item could not be de-serialized. That is an error." << std::endl; - return true; - } - - it2->second.total_received += decrypted_size ; - - // DH key items are sent even before we know who we speak to, so the virtual peer id is used in this - // case only. - - citem->PeerId(virtual_peer_id) ; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(II) Setting peer id to " << citem->PeerId() << std::endl; -#endif - handleIncomingItem(tunnel_id,citem) ; // Treats the item, and deletes it - - return true ; -} - -void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) -{ - if (!item) - { - std::cerr << "p3GxsTunnelService: Received null DH public key item. This should not happen." << std::endl; - return; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService: Received DH public key." << std::endl; - item->print(std::cerr, 0) ; -#endif - - // Look for the current state of the key agreement. - - TurtleVirtualPeerId vpid = item->PeerId() ; - - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _gxs_tunnel_virtual_peer_ids.find(vpid) ; - - if(it == _gxs_tunnel_virtual_peer_ids.end()) - { - std::cerr << " (EE) Cannot find hash in gxs_tunnel peer list!!" << std::endl; - return ; - } - - // Now check the signature of the DH public key item. - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Checking signature. " << std::endl; -#endif - - uint32_t pubkey_size = BN_num_bytes(item->public_key) ; - RsTemporaryMemory data(pubkey_size) ; - BN_bn2bin(item->public_key, data) ; - - RsTlvPublicRSAKey signature_key ; - - // We need to get the key of the sender, but if the key is not cached, we - // need to get it first. So we let the system work for 2-3 seconds before - // giving up. Normally this would only cause a delay for uncached keys, - // which is rare. To force the system to cache the key, we first call for - // getIdDetails(). - // - RsIdentityDetails details ; - RsGxsId senders_id( item->signature.keyId ) ; - - for(int i=0;i<6;++i) - if(!mGixs->getKey(senders_id,signature_key) || signature_key.keyData.bin_data == NULL) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl; -#endif - usleep(500 * 1000) ; // sleep for 500 msec. - } - else - break ; - - if(signature_key.keyData.bin_data == NULL) - { - std::cerr << " (EE) Key unknown for checking signature from " << senders_id << ", can't verify signature. Using key provided in DH packet (without adding to the keyring)." << std::endl; - - // check GXS key for defects. - - if(!GxsSecurity::checkPublicKey(item->gxs_key)) - { - std::cerr << "(SS) Security error in distant chat DH handshake: supplied key " << item->gxs_key.keyId << " is inconsistent. Refusing chat!" << std::endl; - return ; - } - if(item->gxs_key.keyId != item->signature.keyId) - { - std::cerr << "(SS) Security error in distant chat DH handshake: supplied key " << item->gxs_key.keyId << " is not the same than the item's signature key " << item->signature.keyId << ". Refusing chat!" << std::endl; - return ; - } - - signature_key = item->gxs_key ; - } - - if(!GxsSecurity::validateSignature((char*)(unsigned char*)data,pubkey_size,signature_key,item->signature)) - { - std::cerr << "(SS) Signature was verified and it doesn't check! This is a security issue!" << std::endl; - return ; - } - mGixs->timeStampKey(item->signature.keyId,RsIdentityUsage(RsServiceType::GXS_TUNNEL,RsIdentityUsage::GXS_TUNNEL_DH_SIGNATURE_CHECK)); - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Signature checks! Sender's ID = " << senders_id << std::endl; - std::cerr << " Computing AES key" << std::endl; -#endif - - if(it->second.dh == NULL) - { - std::cerr << " (EE) no DH information for that peer. This is an error." << std::endl; - return ; - } - if(it->second.status == RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " DH Session already set for this tunnel. Re-initing a new session!" << std::endl; -#endif - - locked_restartDHSession(vpid,it->second.own_gxs_id) ; - } - - // gets current key params. By default, should contain all null pointers. - // - RsGxsId own_id = it->second.own_gxs_id ; - - RsGxsTunnelId tunnel_id = makeGxsTunnelId(own_id,senders_id) ; - - it->second.tunnel_id = tunnel_id ; - it->second.gxs_id = senders_id ; - - // Looks for the DH params. If not there yet, create them. - // - int size = DH_size(it->second.dh) ; - RsTemporaryMemory key_buff(size) ; - - if(size != DH_compute_key(key_buff,item->public_key,it->second.dh)) - { - std::cerr << " (EE) DH computation failed. Probably a bug. Error code=" << ERR_get_error() << std::endl; - return ; - } - it->second.status = RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " DH key computation successed. New key in place." << std::endl; -#endif - // make a hash of destination and source GXS ids in order to create the tunnel name - - GxsTunnelPeerInfo& pinfo(_gxs_tunnel_contacts[tunnel_id]) ; - - // Now hash the key buffer into a 16 bytes key. - - assert(GXS_TUNNEL_AES_KEY_SIZE <= Sha1CheckSum::SIZE_IN_BYTES) ; - memcpy(pinfo.aes_key, RsDirUtil::sha1sum(key_buff,size).toByteArray(),GXS_TUNNEL_AES_KEY_SIZE) ; - - pinfo.last_contact = time(NULL) ; - pinfo.last_keep_alive_sent = time(NULL) ; - pinfo.status = RS_GXS_TUNNEL_STATUS_CAN_TALK ; - pinfo.virtual_peer_id = vpid ; - pinfo.direction = it->second.direction ; - pinfo.own_gxs_id = own_id ; - pinfo.to_gxs_id = item->signature.keyId; // this is already set for client side but not for server side. - - // note: the hash might still be nn initialised on server side. - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " DH key computed. Tunnel is now secured!" << std::endl; - std::cerr << " Key computed: " << RsUtil::BinToHex((char*)pinfo.aes_key,16) << std::endl; - std::cerr << " Sending a ACK packet." << std::endl; -#endif - - // then we send an ACK packet to notify that the tunnel works. That's useful - // because it makes the peer at the other end of the tunnel know that all - // intermediate peer in the tunnel are able to transmit the data. - // However, it is not possible here to call sendTurtleData(), without dead-locking - // the turtle router, so we store the item is a list of items to be sent. - - RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; - - cs->status = RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION; - cs->PeerId(RsPeerId(tunnel_id)) ; - - pendingGxsTunnelItems.push_back(cs) ; -} - -// Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type. - -/*static*/ RsGxsTunnelId p3GxsTunnelService::makeGxsTunnelId( - const RsGxsId &own_id, const RsGxsId &distant_id ) -{ - unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ; - - // Always sort the ids, as a matter to avoid confusion between the two. Also that generates the same tunnel ID on both sides - // which helps debugging. If the code is right this is not needed anyway. - - if(own_id < distant_id) - { - memcpy(mem, own_id.toByteArray(), RsGxsId::SIZE_IN_BYTES) ; - memcpy(mem+RsGxsId::SIZE_IN_BYTES, distant_id.toByteArray(), RsGxsId::SIZE_IN_BYTES) ; - } - else - { - memcpy(mem, distant_id.toByteArray(), RsGxsId::SIZE_IN_BYTES) ; - memcpy(mem+RsGxsId::SIZE_IN_BYTES, own_id.toByteArray(), RsGxsId::SIZE_IN_BYTES) ; - } - - assert( RsGxsTunnelId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES ) ; - - return RsGxsTunnelId( RsDirUtil::sha1sum(mem, 2*RsGxsId::SIZE_IN_BYTES).toByteArray() ) ; -} - -bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_gxs_id,const RsPeerId& virtual_peer_id) -{ - if(dh == NULL) - { - std::cerr << " (EE) DH struct is not initialised! Error." << std::endl; - return false ; - } - - RsGxsTunnelDHPublicKeyItem *dhitem = new RsGxsTunnelDHPublicKeyItem ; -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - dhitem->public_key = BN_dup(dh->pub_key) ; -#else - const BIGNUM *pub_key=NULL ; - DH_get0_key(dh,&pub_key,NULL) ; - dhitem->public_key = BN_dup(pub_key) ; -#endif - - // we should also sign the data and check the signature on the other end. - // - RsTlvKeySignature signature ; - RsTlvPrivateRSAKey signature_key ; - RsTlvPublicRSAKey signature_key_public ; - - uint32_t error_status ; - - uint32_t size = BN_num_bytes(dhitem->public_key) ; - - RsTemporaryMemory data(size) ; - - if(data == NULL) - { - delete(dhitem); - return false ; - } - - BN_bn2bin(dhitem->public_key, data) ; - - if(!mGixs->signData((unsigned char*)data,size,own_gxs_id,signature,error_status)) - { - switch(error_status) - { - case RsGixs::RS_GIXS_ERROR_KEY_NOT_AVAILABLE: std::cerr << "(EE) Key is not available. Cannot sign." << std::endl; - break ; - default: std::cerr << "(EE) Unknown error when signing" << std::endl; - break ; - } - delete(dhitem); - return false; - } - - if(!mGixs->getKey(own_gxs_id,signature_key_public)) - { - std::cerr << " (EE) Could not retrieve own public key for ID = " << own_gxs_id << ". Giging up sending DH session params." << std::endl; - return false ; - } - - - assert(!(signature_key_public.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - - dhitem->signature = signature ; - dhitem->gxs_key = signature_key_public ; - dhitem->PeerId(virtual_peer_id) ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Pushing DH session key item to pending distant messages..." << std::endl; - dhitem->print(std::cerr, 2) ; - std::cerr << std::endl; -#endif - pendingDHItems.push_back(dhitem) ; // sent off-mutex to avoid deadlocking. - - return true ; -} - -bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh) -{ - // We use our own DH group prime. This has been generated with command-line openssl and checked. - - static const std::string dh_prime_2048_hex = "B3B86A844550486C7EA459FA468D3A8EFD71139593FE1C658BBEFA9B2FC0AD2628242C2CDC2F91F5B220ED29AAC271192A7374DFA28CDDCA70252F342D0821273940344A7A6A3CB70C7897A39864309F6CAC5C7EA18020EF882693CA2C12BB211B7BA8367D5A7C7252A5B5E840C9E8F081469EBA0B98BCC3F593A4D9C4D5DF539362084F1B9581316C1F80FDAD452FD56DBC6B8ED0775F596F7BB22A3FE2B4753764221528D33DB4140DE58083DB660E3E105123FC963BFF108AC3A268B7380FFA72005A1515C371287C5706FFA6062C9AC73A9B1A6AC842C2764CDACFC85556607E86611FDF486C222E4896CDF6908F239E177ACC641FCBFF72A758D1C10CBB" ; - - if(dh != NULL) - { - DH_free(dh) ; - dh = NULL ; - } - - dh = DH_new() ; - - if(!dh) - { - std::cerr << " (EE) DH_new() failed." << std::endl; - return false ; - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - BN_hex2bn(&dh->p,dh_prime_2048_hex.c_str()) ; - BN_hex2bn(&dh->g,"5") ; -#else - BIGNUM *pp=NULL ; - BIGNUM *gg=NULL ; - - BN_hex2bn(&pp,dh_prime_2048_hex.c_str()) ; - BN_hex2bn(&gg,"5") ; - - DH_set0_pqg(dh,pp,NULL,gg) ; -#endif - - int codes = 0 ; - - if(!DH_check(dh, &codes) || codes != 0) - { - std::cerr << " (EE) DH check failed!" << std::endl; - return false ; - } - - if(!DH_generate_key(dh)) - { - std::cerr << " (EE) DH generate_key() failed! Error code = " << ERR_get_error() << std::endl; - return false ; - } -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " (II) DH Session key inited." << std::endl; -#endif - return true ; -} - -// Sends the item in clear. This is only used for DH key exchange. -// in this case only, the item's PeerId is equal to the virtual peer Id for the tunnel, -// since we ight not now the tunnel id yet. - -bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item) -{ -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::sendClearTunnelData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl; -#endif - - // make a RsTurtleGenericData item out of it, and send it in clear. - // this is compatible with nodes older than 0.6.6 - RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ; - // force item priority to QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA to make the DH exchange faster on 0.6.6+ nodes - // this will not affect old nodes - gitem->setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA); - - RsGxsTunnelSerialiser ser ; - - uint32_t rssize = ser.size(item); - - gitem->data_size = rssize + 8 ; - gitem->data_bytes = rs_malloc(rssize+8) ; - - if(gitem->data_bytes == NULL) - { - delete gitem ; - return false ; - } - // by convention, we use a IV of 0 for unencrypted data. - memset(gitem->data_bytes,0,8) ; - - if(!ser.serialise(item,&((uint8_t*)gitem->data_bytes)[8],&rssize)) - { - std::cerr << "(EE) Could not serialise item!!!" << std::endl; - delete gitem ; - return false; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " GxsTunnelService::sendClearTunnelData(): Sending clear data to virtual peer: " << item->PeerId() << std::endl; - std::cerr << " gitem->data_size = " << gitem->data_size << std::endl; - std::cerr << " data = " << RsUtil::BinToHex((unsigned char*)gitem->data_bytes,gitem->data_size,100) ; - std::cerr << std::endl; -#endif - mTurtle->sendTurtleData(item->PeerId(),gitem) ; - - return true ; -} - -// Sends this item using secured/authenticated method, thx to the establshed cryptographic channel. - -bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) -{ - RsGxsTunnelSerialiser ser; - - uint32_t rssize = ser.size(item); - RsTemporaryMemory buff(rssize) ; - - if(!ser.serialise(item,buff,&rssize)) - { - std::cerr << "(EE) GxsTunnelService::sendEncryptedTunnelData(): Could not serialise item!" << std::endl; - return false; - } - - uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; - uint64_t IV = 0; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "Sending encrypted data to tunnel with vpid " << item->PeerId() << std::endl; -#endif - - RsGxsTunnelId tunnel_id ( item->PeerId() ); - - std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Cannot find contact key info for tunnel id " - << tunnel_id << ". Cannot send message!" << std::endl; -#endif - return false; - } - if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id << ". Tunnel status is: " << it->second.status << std::endl; -#endif - return false; - } - - it->second.total_sent += rssize ; // counts the size of clear data that is sent - - memcpy(aes_key,it->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; - RsPeerId virtual_peer_id = it->second.virtual_peer_id ; - - while(IV == 0) IV = RSRandom::random_u64() ; // make a random 8 bytes IV, that is not 0 - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): tunnel found. Encrypting data." << std::endl; -#endif - - // Now encrypt this data using AES. - // - uint32_t encrypted_size = RsAES::get_buffer_size(rssize); - RsTemporaryMemory encrypted_data(encrypted_size) ; - - if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size)) - { - std::cerr << "(EE) packet encryption failed." << std::endl; - return false; - } - - // make a TurtleGenericData item out of it: - // - - uint32_t data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ; - void *data_bytes = rs_malloc(data_size) ; - - if(data_bytes == NULL) - return false ; - - memcpy(& ((uint8_t*)data_bytes)[0] ,&IV,8) ; - - unsigned int md_len = GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ; - HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ; - - memcpy(& (((uint8_t*)data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ; - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl; - std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl; - std::cerr << " hmac: " << RsUtil::BinToHex((char*)data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl; -#endif -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl; - std::cerr << " data_size = " << data_size << std::endl; - std::cerr << " serialised data = " << RsUtil::BinToHex((unsigned char*)data_bytes,data_size,100) ; - std::cerr << std::endl; -#endif - - // We send the item through the turtle tunnel. We do that using the new 'fast' item type if the tunnel accepts it, and using the old slow one otherwise. - // Still if the tunnel hasn't been probed, we duplicate the packet using the new fast item format. The packet being received twice on the other side will - // be discarded with a warning. - // Note that because the data is deleted by sendTurtleData(), we need to send all packets at the end, and properly duplicate the data when needed. - -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 - RsTurtleGenericFastDataItem *gitem = new RsTurtleGenericFastDataItem; - gitem->data_bytes = data_bytes; - gitem->data_size = data_size ; -#else - RsTurtleGenericDataItem *gitem = NULL; - RsTurtleGenericFastDataItem *gitem2 = NULL; - - if(!it->second.accepts_fast_turtle_items) - { - std::cerr << "Sending old format (slow) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl; - gitem = new RsTurtleGenericDataItem ; - - gitem->data_bytes = data_bytes; - gitem->data_size = data_size ; - } - - if(it->second.accepts_fast_turtle_items || !it->second.already_probed_for_fast_items) - { - std::cerr << "Sending new format (fast) item for packet IV=" << std::hex << IV << std::dec << " in tunnel VPID=" << it->second.virtual_peer_id << std::endl; - gitem2 = new RsTurtleGenericFastDataItem ; - - if(gitem != NULL) // duplicate the data because it was already sent in gitem. - { - gitem2->data_bytes = rs_malloc(data_size); - gitem2->data_size = data_size ; - memcpy(gitem2->data_bytes,data_bytes,data_size); - } - else - { - gitem2->data_bytes = data_bytes; - gitem2->data_size = data_size ; - } - - it->second.already_probed_for_fast_items = true; - - } - if(gitem2) mTurtle->sendTurtleData(virtual_peer_id,gitem2) ; -#endif - if(gitem) mTurtle->sendTurtleData(virtual_peer_id,gitem) ; - - return true ; -} - -bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t service_id, uint32_t& error_code) -{ - // should be a parameter. - - std::list lst ; - mGixs->getOwnIds(lst) ; - - bool found = false ; - for(std::list::const_iterator it = lst.begin();it!=lst.end();++it) - if(*it == from_gxs_id) - { - found=true; - break ; - } - - if(!found) - { - std::cerr << " (EE) Cannot start distant chat, since GXS id " << from_gxs_id << " is not available." << std::endl; - error_code = RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID ; - return false ; - } - RsGxsId own_gxs_id = from_gxs_id ; - - startClientGxsTunnelConnection(to_gxs_id,own_gxs_id,service_id,tunnel_id) ; - - error_code = RS_GXS_TUNNEL_ERROR_NO_ERROR ; - - return true ; -} - -// This method generates an ID that should be unique for each packet sent to a same peer. Rather than a random value, -// we use this counter because outgoing items are sorted in a map by their counter value. Using an increasing value -// ensures that the packets are sent in the same order than received from the service. This can be useful in some cases, -// for instance when services split their items while expecting them to arrive in the same order. - -uint64_t p3GxsTunnelService::locked_getPacketCounter() -{ - return mCurrentPacketCounter++ ; -} - -bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t service_id, const uint8_t *data, uint32_t size) -{ - // make sure that the tunnel ID is registered. - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "p3GxsTunnelService::sendData()" << std::endl; - std::cerr << " tunnel id : " << tunnel_id << std::endl; - std::cerr << " data size : " << size << std::endl; - std::cerr << " service id: " << std::hex << service_id << std::dec << std::endl; -#endif - - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) - { - std::cerr << " (EE) no tunnel known with this ID. Sorry!" << std::endl; - return false ; - } - - // make sure the service is registered. - - if(mRegisteredServices.find(service_id) == mRegisteredServices.end()) - { - std::cerr << " (EE) no service registered with this ID. Please call rsGxsTunnel->registerClientService() at some point." << std::endl; - return false ; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " verifications fine! Storing in out queue with:" << std::endl; -#endif - - RsGxsTunnelDataItem *item = new RsGxsTunnelDataItem ; - - item->unique_item_counter = locked_getPacketCounter() ;// this allows to make the item unique, while respecting the packet order! - item->flags = 0; // not used yet. - item->service_id = service_id; - item->data_size = size; // encrypted data size - item->data = (uint8_t*)rs_malloc(size); // encrypted data - - if(item->data == NULL) - delete item ; - - item->PeerId(RsPeerId(tunnel_id)) ; - memcpy(item->data,data,size) ; - - GxsTunnelData& tdata( pendingGxsTunnelDataItems[item->unique_item_counter] ) ; - - tdata.data_item = item ; - tdata.last_sending_attempt = 0 ; // never sent until now - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " counter id : " << std::hex << item->unique_item_counter << std::dec << std::endl; -#endif - - return true ; -} - - -void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t service_id,RsGxsTunnelId& tunnel_id) -{ - // compute a random hash for that pair, and init the DH session for it so that we can recognise it when we get the virtual peer for it. - - RsFileHash hash = randomHashFromDestinationGxsId(to_gxs_id) ; - - tunnel_id = makeGxsTunnelId(from_gxs_id,to_gxs_id) ; - - { - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - if(_gxs_tunnel_contacts.find(tunnel_id) != _gxs_tunnel_contacts.end()) - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "GxsTunnelService:: asking GXS tunnel for a configuration that already exits.Ignoring." << std::endl; -#endif - return ; - } - } - - GxsTunnelPeerInfo info ; - - rstime_t now = time(NULL) ; - - info.last_contact = now ; - info.last_keep_alive_sent = now ; - info.status = RS_GXS_TUNNEL_STATUS_TUNNEL_DN ; - info.own_gxs_id = from_gxs_id ; - info.to_gxs_id = to_gxs_id ; - info.hash = hash ; - info.direction = RsTurtleGenericTunnelItem::DIRECTION_SERVER ; - info.virtual_peer_id.clear(); - info.client_services.insert(service_id) ; - - memset(info.aes_key,0,GXS_TUNNEL_AES_KEY_SIZE) ; - - { - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - _gxs_tunnel_contacts[tunnel_id] = info ; - } - -#ifdef DEBUG_GXS_TUNNEL - std::cerr << "Starting distant chat to " << to_gxs_id << ", hash = " << hash << ", from " << from_gxs_id << std::endl; - std::cerr << "Asking turtle router to monitor tunnels for hash " << hash << std::endl; -#endif - - // Now ask the turtle router to manage a tunnel for that hash. - - mTurtle->monitorTunnels(hash,this,false) ; -} - -TurtleFileHash p3GxsTunnelService::randomHashFromDestinationGxsId(const RsGxsId& destination) -{ - // This is in prevision for the "secured GXS tunnel" service, which will need a service ID to register, - // just like GRouter does. - - assert( destination.SIZE_IN_BYTES == 16) ; - assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ; - - uint8_t bytes[20] ; - memcpy(&bytes[4],destination.toByteArray(),16) ; - - RAND_bytes(&bytes[0],4) ; // fill the 4 first bytes with random crap. Very important to allow tunnels from different sources and statistically avoid collisions. - - // We could rehash this, with a secret key to get a HMAC. That would allow to publish secret distant chat - // passphrases. I'll do this later if needed. - - return Sha1CheckSum(bytes) ; // this does not compute a hash, and that is on purpose. -} - -RsGxsId p3GxsTunnelService::destinationGxsIdFromHash(const TurtleFileHash& sum) -{ - assert( RsGxsId::SIZE_IN_BYTES == 16) ; - assert(Sha1CheckSum::SIZE_IN_BYTES == 20) ; - - return RsGxsId(&sum.toByteArray()[4]);// takes the last 16 bytes -} - -bool p3GxsTunnelService::getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) -{ - RS_STACK_MUTEX(mGxsTunnelMtx); - - std::map::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) - return false ; - - info.destination_gxs_id = it->second.to_gxs_id; - info.source_gxs_id = it->second.own_gxs_id; - info.tunnel_status = it->second.status; - info.total_size_sent = it->second.total_sent; - info.total_size_received= it->second.total_received; - info.is_client_side = (it->second.direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT); - - // Data packets - - info.pending_data_packets = 0; - RsPeerId p(tunnel_id); - - for(auto it(pendingGxsTunnelDataItems.begin());it!=pendingGxsTunnelDataItems.end();++it) - if(it->second.data_item->PeerId() == p) - ++info.pending_data_packets ; - - info.total_data_packets_sent=0 ; - info.total_data_packets_received=0 ; - - return true ; -} - -bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id, uint32_t service_id) -{ - // two cases: - // - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files - // - server needs to only close the window and let the tunnel die. But the window should only open - // if a message arrives. - - TurtleFileHash hash ; - TurtleVirtualPeerId vpid ; - bool close_tunnel = false ; - int direction ; - { - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) - { - std::cerr << "(EE) Cannot close distant tunnel connection. No connection openned for tunnel id " << tunnel_id << std::endl; - - // We cannot stop tunnels, since their peer id is lost. Anyway, they'll die of starving. - - return false ; - } - vpid = it->second.virtual_peer_id ; - - std::map::const_iterator it2 = _gxs_tunnel_virtual_peer_ids.find(vpid) ; - - if(it2 != _gxs_tunnel_virtual_peer_ids.end()) - hash = it2->second.hash ; - else - hash = it->second.hash ; - - // check how many clients are used. If empty, close the tunnel - - std::set::iterator it3 = it->second.client_services.find(service_id) ; - - if(it3 == it->second.client_services.end()) - { - std::cerr << "(EE) service id not currently using that tunnel. This is an error." << std::endl; - return false; - } - - it->second.client_services.erase(it3) ; - direction = it->second.direction ; - - if(it->second.client_services.empty()) - close_tunnel = true ; - } - - if(close_tunnel) - { - // send a status item saying that we're closing the connection -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " Sending a ACK to close the tunnel since we're managing it and it's not used by any service. tunnel id=." << tunnel_id << std::endl; -#endif - - RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; - - cs->status = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION; - cs->PeerId(RsPeerId(tunnel_id)) ; - - locked_sendEncryptedTunnelData(cs) ; // that needs to be done off-mutex and before we close the tunnel also ignoring failure. - - if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER) // nothing more to do for server side. - { -#ifdef DEBUG_GXS_TUNNEL - std::cerr << " This is client side. Stopping tunnel manageement for tunnel_id " << tunnel_id << std::endl; -#endif - mTurtle->stopMonitoringTunnels( hash ) ; // still valid if the hash is null - } - - RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it = _gxs_tunnel_contacts.find(tunnel_id) ; - - if(it == _gxs_tunnel_contacts.end()) // server side. Nothing to do. - { - std::cerr << "(EE) Cannot close chat associated to tunnel id " << tunnel_id << ": not found." << std::endl; - return false ; - } - - _gxs_tunnel_contacts.erase(it) ; - - // GxsTunnelService::removeVirtualPeerId() will be called by the turtle service. - } - return true ; -} - -bool p3GxsTunnelService::getTunnelsInfo(std::vector &infos) -{ - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::const_iterator it(_gxs_tunnel_contacts.begin());it!=_gxs_tunnel_contacts.end();++it) - { - GxsTunnelInfo ti ; - - ti.tunnel_id = it->first ; - ti.destination_gxs_id = it->second.to_gxs_id ; - ti.source_gxs_id = it->second.own_gxs_id ; - ti.tunnel_status = it->second.status ; - ti.total_size_sent = it->second.total_sent ; - ti.total_size_received = it->second.total_received ; - - ti.pending_data_packets = 0; - RsPeerId p(it->first); - for(auto it(pendingGxsTunnelDataItems.begin());it!=pendingGxsTunnelDataItems.end();++it) - if(it->second.data_item->PeerId() == p) - ++ti.pending_data_packets ; - - ti.total_data_packets_sent =0; // not accounted for yet. - ti.total_data_packets_received=0 ; // not accounted for yet. - - infos.push_back(ti) ; - } - - return true ; -} - -void p3GxsTunnelService::debug_dump() -{ - RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - std::cerr << "p3GxsTunnelService::debug_dump()" << std::endl; - std::cerr << " Registered client services: " << std::endl; - - for(std::map::const_iterator it=mRegisteredServices.begin();it!=mRegisteredServices.end();++it) - std::cerr << std::hex << " " << it->first << " - " << (void*)it->second << std::dec << std::endl; - - std::cerr << " Active tunnels" << std::endl; - - for(std::map::const_iterator it=_gxs_tunnel_contacts.begin();it!=_gxs_tunnel_contacts.end();++it) - std::cerr << " tunnel_id=" << it->first << " vpid=" << it->second.virtual_peer_id << " status=" << it->second.status << " direction=" << it->second.direction << " last_contact=" << (now-it->second.last_contact) <<" secs ago. Last_keep_alive_sent:" << (now - it->second.last_keep_alive_sent) << " secs ago." << std::endl; - - std::cerr << " Virtual peers:" << std::endl; - - for(std::map::const_iterator it=_gxs_tunnel_virtual_peer_ids.begin();it!=_gxs_tunnel_virtual_peer_ids.end();++it) - std::cerr << " vpid=" << it->first << " to=" << it->second.gxs_id << " from=" << it->second.own_gxs_id << " tunnel_id=" << it->second.tunnel_id << " status=" << it->second.status << " direction=" << it->second.direction << " hash=" << it->second.hash << std::endl; - - std::cerr << " Pending items: " << std::endl; - std::cerr << " DH : " << pendingDHItems.size() << std::endl; - std::cerr << " Tunnel Management: " << pendingGxsTunnelItems.size() << std::endl; - std::cerr << " Data (client) : " << pendingGxsTunnelDataItems.size() << std::endl; -} - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.h b/libretroshare/src/gxstunnel/p3gxstunnel.h deleted file mode 100644 index d6e200678..000000000 --- a/libretroshare/src/gxstunnel/p3gxstunnel.h +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: distantchat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -// Generic tunnel service -// -// Preconditions: -// * the secured tunnel service takes care of: -// - tunnel health: tunnels are kept alive using special items, re-openned when necessary, etc. -// - transport: items are ACK-ed and re-sent if never received -// - encryption: items are all encrypted and authenticated using PFS(DH)+HMAC(sha1)+AES(128) -// * each tunnel is associated to a specific GXS id on both sides. Consequently, services that request tunnels from different IDs to a -// server for the same GXS id need to be handled correctly. -// * client services must register to the secured tunnel service if they want to use it. -// * multiple services can use the same tunnel. Items contain a service Id that is obtained when registering to the secured tunnel service. -// -// GUI -// * the GUI should show for each tunnel: -// - starting and ending GXS ids -// - tunnel status (DH ok, closed from distant peer, locally closed, etc) -// - amount of data that is transferred in the tunnel -// - number of pending items (and total size) -// - number ACKed items both ways. -// -// We can use an additional tab "Authenticated tunnels" in the statistics->turtle window for that purpose. -// -// Interaction with services: -// -// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (type = RsGxsTunnelId) -// -// Services send data in the tunnel using the virtual peer id -// -// Data is send to a service ID (could be any existing service ID). The endpoint of the tunnel must register each service, in order to -// allow the data to be transmitted/sent from/to that service. Otherwise an error is issued. -// -// Encryption -// * the whole tunnel traffic is encrypted using AES-128 with random IV -// * a random key is established using DH key exchange for each connection (establishment of a new virtual peer) -// * encrypted items are authenticated with HMAC(sha1). -// * DH public keys are the only chunks of data that travel un-encrypted along the tunnel. They are -// signed to avoid any MITM interactions. No time-stamp is used in DH exchange since a replay attack would not work. -// -// Algorithms -// -// * we need two layers: the turtle layer, and the GXS id layer. -// - for each pair of GXS ids talking, a single turtle tunnel is used -// - that tunnel can be shared by multiple services using it. -// - services are responsoble for asking tunnels and also droppping them when unused. -// - at the turtle layer, the tunnel will be effectively closed only when no service uses it. -// * IDs -// TurtleVirtualPeerId: -// - Used by tunnel service for each turtle tunnel -// - one virtual peer ID per GXS tunnel -// -// GxsTunnelId: -// - one GxsTunnelId per couple of GXS ids. But we also need to allow multiple services to use the tunnel. -// -// * at the turtle layer: -// - accept virtual peers from turtle tunnel service. The hash for that VP only depends on the server GXS id at server side, which is our -// own ID at server side, and destination ID at client side. What happens if two different clients request to talk to the same GXS id? (same hash) -// They should use different virtual peers, so it should be ok. -// -// Turtle hash: [ 0 ---------------15 16---19 ] -// Destination Random -// -// We Use 16 bytes to target the exact destination of the hash. The source part is just 4 arbitrary bytes that need to be different for all source -// IDs that come from the same peer, which is quite likely to be sufficient. The real source of the tunnel will make itself known when sending the -// DH key. -// -// * at the GXS layer -// - we should be able to have as many tunnels as they are different couples of GXS ids to interact. That means the tunnel should be determined -// by a mix between our own GXS id and the GXS id we're talking to. That is what the TunnelVirtualPeer is. -// -// -// RequestTunnel(source_own_id,destination_id) - -// | | -// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) | -// | | -// [Turtle async work] -------------------+ | Turtle layer: one virtual peer id -// | | | -// handleTunnelRequest() <-----------------------------------------------+ | | -// | | | -// +---------------- keep record in _gxs_tunnel_virtual_peer_id, initiate DH exchange | - -// | | -// handleDHPublicKey() <-----------------------------------------------------------------------------+ | -// | | -// +---------------- update _gxs_tunnel_contacts[ tunnel_hash = hash(own_id, destination_id) ] | GxsTunnelId level -// | | -// +---------------- notify client service that Peer(destination_id, tunnel_hash) is ready to talk to | -// - - -#include -#include -#include -#include - -class RsGixs ; - -static const uint32_t GXS_TUNNEL_AES_KEY_SIZE = 16 ; - -class p3GxsTunnelService: public RsGxsTunnelService, public RsTurtleClientService, public p3Service -{ -public: - explicit p3GxsTunnelService(RsGixs *pids) ; - virtual void connectToTurtleRouter(p3turtle *) override; - - uint16_t serviceId() const override { return RS_SERVICE_TYPE_GXS_TUNNEL ; } - - // Creates the invite if the public key of the distant peer is available. - // Om success, stores the invite in the map above, so that we can respond to tunnel requests. - // - virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) override ; - virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id,uint32_t service_id) override ; - virtual bool getTunnelsInfo(std::vector& infos) override ; - virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) override ; - virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) override ; - virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) override ; - - // derived from p3service - - virtual int tick() override; - virtual RsServiceInfo getServiceInfo() override; - -private: - void flush() ; - virtual void handleIncomingItem(const RsGxsTunnelId &tunnel_id, RsGxsTunnelItem *) ; - - class GxsTunnelPeerInfo - { - public: - GxsTunnelPeerInfo() - : last_contact(0), last_keep_alive_sent(0), status(0), direction(0) - , total_sent(0), total_received(0) - #ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 - , accepts_fast_turtle_items(false) - , already_probed_for_fast_items(false) - #endif - { - memset(aes_key, 0, GXS_TUNNEL_AES_KEY_SIZE); - } - - rstime_t last_contact ; // used to keep track of working connexion - rstime_t last_keep_alive_sent ; // last time we sent a keep alive packet. - - unsigned char aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; - - uint32_t status ; // info: do we have a tunnel ? - RsPeerId virtual_peer_id; // given by the turtle router. Identifies the tunnel. - RsGxsId to_gxs_id; // gxs id we're talking to - RsGxsId own_gxs_id ; // gxs id we're using to talk. - RsTurtleGenericTunnelItem::Direction direction ; // specifiec wether we are client(managing the tunnel) or server. - TurtleFileHash hash ; // hash that is last used. This is necessary for handling tunnel establishment - std::set client_services ; // services that used this tunnel - std::map received_data_prints ; // list of recently received messages, to avoid duplicates. Kept for 20 mins at most. - uint32_t total_sent ; // total data sent to this peer - uint32_t total_received ; // total data received by this peer -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 - bool accepts_fast_turtle_items; // does the tunnel accept RsTurtleGenericFastDataItem type? - bool already_probed_for_fast_items; // has the tunnel been probed already? If not, a fast item will be sent -#endif - }; - - class GxsTunnelDHInfo - { - public: - GxsTunnelDHInfo() : dh(0), direction(0), status(0) {} - - DH *dh ; - RsGxsId gxs_id ; - RsGxsId own_gxs_id ; - RsGxsTunnelId tunnel_id ; // this is a proxy, since we cna always recompute that from the two previous values. - RsTurtleGenericTunnelItem::Direction direction ; - uint32_t status ; - TurtleFileHash hash ; - }; - - struct GxsTunnelData - { - RsGxsTunnelDataItem *data_item ; - rstime_t last_sending_attempt ; - }; - - // This maps contains the current peers to talk to with distant chat. - // - std::map _gxs_tunnel_contacts ; // current peers we can talk to - std::map _gxs_tunnel_virtual_peer_ids ; // current virtual peers. Used to figure out tunnels, etc. - - // List of items to be sent asap. Used to store items that we cannot pass directly to - // sendTurtleData(), because of Mutex protection. - - std::map pendingGxsTunnelDataItems ; // items that need provable transport and encryption - std::list pendingGxsTunnelItems ; // items that do not need provable transport, yet need encryption - std::list pendingDHItems ; - - // Overloaded from RsTurtleClientService - - virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) override; - virtual void receiveTurtleData(const RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) override; - void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) override; - void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) override; - - // session handling handles - - void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id, uint32_t service_id, RsGxsTunnelId &tunnel_id) ; - void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ; - - // utility functions - - static TurtleFileHash randomHashFromDestinationGxsId(const RsGxsId& destination) ; - static RsGxsId destinationGxsIdFromHash(const TurtleFileHash& sum) ; - - // Cryptography management - - void handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) ; - bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ; - bool locked_initDHSessionKey(DH *&dh); - uint64_t locked_getPacketCounter(); - - TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle - - // item handling - - void handleRecvStatusItem(const RsGxsTunnelId& id,RsGxsTunnelStatusItem *item) ; - void handleRecvTunnelDataItem(const RsGxsTunnelId& id,RsGxsTunnelDataItem *item) ; - void handleRecvTunnelDataAckItem(const RsGxsTunnelId &id, RsGxsTunnelDataAckItem *item); - - // Comunication with Turtle service - - bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ; - bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted! - -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_004 - bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id, bool accepts_fast_items) ; -#else - bool handleEncryptedData(const uint8_t *data_bytes, uint32_t data_size, const TurtleFileHash& hash, const RsPeerId& virtual_peer_id) ; -#endif - - // local data - - p3turtle *mTurtle ; - RsGixs *mGixs ; - RsMutex mGxsTunnelMtx ; - - uint64_t mCurrentPacketCounter ; - - std::map mRegisteredServices ; - - void debug_dump(); - -public: - /// creates a unique tunnel ID from two GXS ids. - static RsGxsTunnelId makeGxsTunnelId( const RsGxsId &own_id, - const RsGxsId &distant_id ); -}; - diff --git a/libretroshare/src/gxstunnel/rsgxstunnelitems.cc b/libretroshare/src/gxstunnel/rsgxstunnelitems.cc deleted file mode 100644 index f86529c3b..000000000 --- a/libretroshare/src/gxstunnel/rsgxstunnelitems.cc +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * libretroshare/src/gxstunnel: rsgxstunnelitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include "util/rstime.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstypeserializer.h" -#include "util/rsprint.h" -#include "util/rsmemory.h" - -#include "gxstunnel/rsgxstunnelitems.h" - -//#define GXS_TUNNEL_ITEM_DEBUG 1 - -RsItem *RsGxsTunnelSerialiser::create_item(uint16_t service,uint8_t item_subtype) const -{ - if(service != RS_SERVICE_TYPE_GXS_TUNNEL) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: return new RsGxsTunnelDataItem(); - case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: return new RsGxsTunnelDataAckItem(); - case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: return new RsGxsTunnelDHPublicKeyItem(); - case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: return new RsGxsTunnelStatusItem(); - default: - return NULL ; - } -} - -RsGxsTunnelDHPublicKeyItem::~RsGxsTunnelDHPublicKeyItem() -{ - BN_free(public_key) ; -} - -void RsGxsTunnelDHPublicKeyItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,public_key,"public_key") ; - RsTypeSerializer::serial_process(j,ctx,signature,"signature") ; - RsTypeSerializer::serial_process(j,ctx,gxs_key,"gxs_key") ; -} - -template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM * const & member) -{ - uint32_t s = BN_num_bytes(member) ; - - if(size < offset + 4 + s) - return false ; - - bool ok = true ; - ok &= setRawUInt32(data, size, &offset, s); - - BN_bn2bin(member,&((unsigned char *)data)[offset]) ; - offset += s ; - - return ok; -} -template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM *& member) -{ - uint32_t s=0 ; - bool ok = true ; - ok &= getRawUInt32(data, size, &offset, &s); - - if(s > size || size - s < offset) - return false ; - - member = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ; - offset += s ; - - return ok; -} -template<> uint32_t RsTypeSerializer::serial_size(BIGNUM * const & member) -{ - return 4 + BN_num_bytes(member) ; -} -template<> void RsTypeSerializer::print_data(const std::string& name,BIGNUM * const & /* member */) -{ - std::cerr << "[BIGNUM] : " << name << std::endl; -} - -RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(BIGNUM*) -RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(BIGNUM*) - -void RsGxsTunnelStatusItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,status,"status") ; -} - -void RsGxsTunnelDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,unique_item_counter,"unique_item_counter") ; - RsTypeSerializer::serial_process(j,ctx,flags ,"flags") ; - RsTypeSerializer::serial_process(j,ctx,service_id ,"service_id") ; - - RsTypeSerializer::TlvMemBlock_proxy mem(data,data_size) ; - RsTypeSerializer::serial_process(j,ctx,mem,"data") ; -} -void RsGxsTunnelDataAckItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,unique_item_counter,"unique_item_counter") ; -} - - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/gxstunnel/rsgxstunnelitems.h b/libretroshare/src/gxstunnel/rsgxstunnelitems.h deleted file mode 100644 index a098c8c05..000000000 --- a/libretroshare/src/gxstunnel/rsgxstunnelitems.h +++ /dev/null @@ -1,151 +0,0 @@ -/******************************************************************************* - * libretroshare/src/chat: rsgxstunnelitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "rsitems/rsitem.h" - -#include "retroshare/rstypes.h" -#include "serialiser/rstlvkeys.h" -#include "serialiser/rsserial.h" - -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvfileitem.h" - -/* chat Flags */ -const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400; -const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800; -const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000; - -const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ; -const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ; -const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ; -const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ; - -typedef uint64_t GxsTunnelDHSessionId ; - -class RsGxsTunnelItem: public RsItem -{ - public: - explicit RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype) - { - setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ; - } - - virtual ~RsGxsTunnelItem() {} - virtual void clear() {} -}; - -/*! - * For sending distant communication data. The item is not encrypted after being serialised, but the data it. - * The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and - * sent as data in a RsGxsTunnelDataItem. - * - * @see p3GxsTunnelService - */ -class RsGxsTunnelDataItem: public RsGxsTunnelItem -{ -public: - RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA), unique_item_counter(0), flags(0), service_id(0), data_size(0), data(NULL) {} - explicit RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) , unique_item_counter(0), flags(0), service_id(0), data_size(0), data(NULL) {} - - virtual ~RsGxsTunnelDataItem() {} - virtual void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint64_t unique_item_counter; // this allows to make the item unique - uint32_t flags; // mainly NEEDS_HACK? - uint32_t service_id ; - uint32_t data_size ; // encrypted data size - unsigned char *data ; // encrypted data -}; - -// Used to send status of connection. This can be closing orders, flushing orders, etc. -// These items are always sent encrypted. - -class RsGxsTunnelStatusItem: public RsGxsTunnelItem -{ - public: - RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) , status(0) {} - RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsGxsTunnelStatusItem() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t status ; -}; - -// Used to confirm reception of an encrypted item. - -class RsGxsTunnelDataAckItem: public RsGxsTunnelItem -{ - public: - RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK), unique_item_counter(0) {} - RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsGxsTunnelDataAckItem() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint64_t unique_item_counter ; // unique identifier for that item -}; - - -// This class contains the public Diffie-Hellman parameters to be sent -// when performing a DH agreement over a distant chat tunnel. -// -class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem -{ - public: - RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY), public_key(NULL) {} - RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization - - virtual ~RsGxsTunnelDHPublicKeyItem() ; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // Private data to DH public key item - // - BIGNUM *public_key ; - - RsTlvKeySignature signature ; // signs the public key in a row. - RsTlvPublicRSAKey gxs_key ; // public key of the signer - - private: - // make the object non copy-able - RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY), public_key(NULL) {} - const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { public_key = NULL; return *this ;} -}; - -class RsGxsTunnelSerialiser: public RsServiceSerializer -{ -public: - RsGxsTunnelSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_GXS_TUNNEL) {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const ; -}; - diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp deleted file mode 100644 index 3fc54f6b0..000000000 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ /dev/null @@ -1,835 +0,0 @@ -/* - * RetroShare JSON API - * - * Copyright (C) 2018-2020 Gioacchino Mazzurco - * Copyright (C) 2019-2020 Asociación Civil Altermundi - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. - * See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2020 RetroShare Team - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#include -#include -#include -#include -#include -#include - - -#include "jsonapi.h" - -#include "util/rsjson.h" -#include "retroshare/rsfiles.h" -#include "util/radix64.h" -#include "retroshare/rsinit.h" -#include "util/rsnet.h" -#include "retroshare/rsiface.h" -#include "retroshare/rsinit.h" -#include "util/rsurl.h" -#include "util/rstime.h" -#include "retroshare/rsevents.h" -#include "retroshare/rsversion.h" - -// Generated at compile time -#include "jsonapi-includes.inl" - -/*extern*/ RsJsonApi* rsJsonApi = nullptr; - -const std::string RsJsonApi::DEFAULT_BINDING_ADDRESS = "127.0.0.1"; - -/*static*/ const std::multimap -JsonApiServer::corsHeaders = -{ - { "Access-Control-Allow-Origin", "*" }, - { "Access-Control-Allow-Methods", "GET, POST, OPTIONS"}, - { "Access-Control-Allow-Headers", "Authorization,DNT,User-Agent," - "X-Requested-With,If-Modified-Since," - "Cache-Control,Content-Type,Range" }, - { "Access-Control-Expose-Headers", "Content-Length,Content-Range" } -}; - -/*static*/ const std::multimap -JsonApiServer::corsOptionsHeaders = -{ - { "Access-Control-Allow-Origin", "*" }, - { "Access-Control-Allow-Methods", "GET, POST, OPTIONS"}, - { "Access-Control-Allow-Headers", "Authorization,DNT,User-Agent," - "X-Requested-With,If-Modified-Since," - "Cache-Control,Content-Type,Range" }, - { "Access-Control-Max-Age", "1728000" }, // 20 days - { "Content-Type", "text/plain; charset=utf-8" }, - { "Content-Length", "0" } -}; - -/* static */ const RsJsonApiErrorCategory RsJsonApiErrorCategory::instance; - -#define INITIALIZE_API_CALL_JSON_CONTEXT \ - RsGenericSerializer::SerializeContext cReq( \ - nullptr, 0, \ - RsSerializationFlags::YIELDING ); \ - RsJson& jReq(cReq.mJson); \ - if(session->get_request()->get_method() == "GET") \ - { \ - const std::string jrqp(session->get_request()->get_query_parameter("jsonData")); \ - jReq.Parse(jrqp.c_str(), jrqp.size()); \ - } \ - else \ - jReq.Parse(reinterpret_cast(body.data()), body.size()); \ -\ - RsGenericSerializer::SerializeContext cAns; \ - RsJson& jAns(cAns.mJson); \ -\ - /* if caller specified caller_data put it back in the answhere */ \ - const char kcd[] = "caller_data"; \ - if(jReq.HasMember(kcd)) \ - jAns.AddMember(kcd, jReq[kcd], jAns.GetAllocator()) - -#define DEFAULT_API_CALL_JSON_RETURN(RET_CODE) \ - std::stringstream ss; \ - ss << jAns; \ - std::string&& ans(ss.str()); \ - auto headers = corsHeaders; \ - headers.insert({ "Content-Type", "application/json" }); \ - headers.insert({ "Content-Length", std::to_string(ans.length()) }); \ - session->close(RET_CODE, ans, headers) - - -/*static*/ bool JsonApiServer::checkRsServicePtrReady( - const void* serviceInstance, const std::string& serviceName, - RsGenericSerializer::SerializeContext& ctx, - const std::shared_ptr session ) -{ - if(serviceInstance) return true; - - std::string jsonApiError = __PRETTY_FUNCTION__; - jsonApiError += "Service: "; - jsonApiError += serviceName; - jsonApiError += " not initialized!"; - - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(jsonApiError); - - RsJson& jAns(ctx.mJson); - DEFAULT_API_CALL_JSON_RETURN(rb::CONFLICT); - return false; -} - -void JsonApiServer::unProtectedRestart() -{ - /* Extremely sensitive stuff! - * Make sure you read documentation in header before changing or use!! */ - - fullstop(); - RsThread::start("JSON API Server"); -} - -bool RsJsonApi::parseToken( - const std::string& clear_token, std::string& user,std::string& passwd ) -{ - auto colonIndex = std::string::npos; - const auto tkLen = clear_token.length(); - - for(uint32_t i=0; i < tkLen; ++i) - if(clear_token[i] == ':') { colonIndex = i; break; } - - user = clear_token.substr(0, colonIndex); - - if(colonIndex < tkLen) - passwd = clear_token.substr(colonIndex + 1); - - return true; -} - -JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), - mService(nullptr), - mListeningPort(RsJsonApi::DEFAULT_PORT), - mBindingAddress(RsJsonApi::DEFAULT_BINDING_ADDRESS), - mRestartReqTS(0) -{ -#if defined(RS_THREAD_FORCE_STOP) && defined(RS_JSONAPI_DEBUG_SERVICE_STOP) - /* When called in bursts it seems that Restbed::Service::stop() doesn't - * always does the job, to debug those cases it has been useful to ask - * RsThread to force it to stop for us. */ - RsThread::setStopTimeout(10); -#endif - -#if !RS_VERSION_AT_LEAST(0,6,6) - registerHandler("/rsLoginHelper/createLocation", - [this](const std::shared_ptr session) - { - auto reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( static_cast(reqSize), [this]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - RsLoginHelper::Location location; - std::string password; - std::string errorMessage; - bool makeHidden = false; - bool makeAutoTor = false; - std::string createToken; - - // deserialize input parameters from JSON - { - RsGenericSerializer::SerializeContext& ctx(cReq); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON); - RS_SERIAL_PROCESS(location); - RS_SERIAL_PROCESS(password); - RS_SERIAL_PROCESS(makeHidden); - RS_SERIAL_PROCESS(makeAutoTor); - RS_SERIAL_PROCESS(createToken); - } - - // call retroshare C++ API - bool retval = rsLoginHelper->createLocation( - location, password, errorMessage, makeHidden, - makeAutoTor ); - - std::string tokenUser, tokenPw; - if(retval && parseToken(createToken, tokenUser, tokenPw)) - authorizeUser(tokenUser,tokenPw); - - // serialize out parameters and return value to JSON - { - RsGenericSerializer::SerializeContext& ctx(cAns); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(location); - RS_SERIAL_PROCESS(errorMessage); - RS_SERIAL_PROCESS(retval); - } - - // return them to the API caller - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - } ); - }, false); -#endif // !RS_VERSION_AT_LEAST(0,6,6) - - registerHandler("/rsLoginHelper/createLocationV2", - [this](const std::shared_ptr session) - { - auto reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( static_cast(reqSize), [this]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - RsPeerId locationId; - RsPgpId pgpId; - std::string locationName; - std::string pgpName; - std::string password; - - // JSON API only - std::string apiUser; - std::string apiPass; - - // deserialize input parameters from JSON - { - RsGenericSerializer::SerializeContext& ctx(cReq); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON); - RS_SERIAL_PROCESS(locationId); - RS_SERIAL_PROCESS(pgpId); - RS_SERIAL_PROCESS(locationName); - RS_SERIAL_PROCESS(pgpName); - RS_SERIAL_PROCESS(password); - - // JSON API only - RS_SERIAL_PROCESS(apiUser); - RS_SERIAL_PROCESS(apiPass); - } - - std::error_condition retval; - - if(apiUser.empty()) - retval = RsJsonApiErrorNum::TOKEN_FORMAT_INVALID; - - if(!retval) - retval = badApiCredientalsFormat(apiUser, apiPass); - - if(!retval) // call retroshare C++ API - retval = rsLoginHelper->createLocationV2( - locationId, pgpId, locationName, pgpName, password ); - - if(!retval) retval = authorizeUser(apiUser, apiPass); - - // serialize out parameters and return value to JSON - { - RsGenericSerializer::SerializeContext& ctx(cAns); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(locationId); - RS_SERIAL_PROCESS(pgpId); - RS_SERIAL_PROCESS(retval); - } - - // return them to the API caller - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - } ); - }, false); - - registerHandler("/rsControl/rsGlobalShutDown", - [](const std::shared_ptr session) - { - auto reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( static_cast(reqSize), []( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - - /* Wrap inside RsThread::async because this call - * RsThread::fullstop() also on JSON API server thread. - * Calling RsThread::fullstop() from it's own thread should never - * happen and if it happens an error message is printed - * accordingly by RsThread::fullstop() */ - RsThread::async([](){ rsControl->rsGlobalShutDown(); }); - } ); - }, true); - - registerHandler("/rsFiles/getFileData", - [](const std::shared_ptr session) - { - auto reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( static_cast(reqSize), []( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if(!checkRsServicePtrReady(rsFiles, "rsFiles", cAns, session)) - return; - - RsFileHash hash; - uint64_t offset; - uint32_t requested_size; - bool retval = false; - std::string errorMessage; - std::string base64data; - - // deserialize input parameters from JSON - { - RsGenericSerializer::SerializeContext& ctx(cReq); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON); - RS_SERIAL_PROCESS(hash); - RS_SERIAL_PROCESS(offset); - RS_SERIAL_PROCESS(requested_size); - } - - if(requested_size > 10485760) - errorMessage = "requested_size is too big! Better less then 1M"; - else - { - std::vector buffer(requested_size); - - // call retroshare C++ API - retval = rsFiles->getFileData( - hash, offset, requested_size, buffer.data()); - - Radix64::encode(buffer.data(), requested_size, base64data); - } - - // serialize out parameters and return value to JSON - { - RsGenericSerializer::SerializeContext& ctx(cAns); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(retval); - RS_SERIAL_PROCESS(requested_size); - RS_SERIAL_PROCESS(base64data); - if(!errorMessage.empty()) RS_SERIAL_PROCESS(errorMessage); - } - - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - } ); - }, true); - - registerHandler("/rsEvents/registerEventsHandler", - [this](const std::shared_ptr session) - { - const std::weak_ptr weakService(mService); - const std::multimap headers - { - { "Connection", "keep-alive" }, - { "Content-Type", "text/event-stream" } - }; - session->yield(rb::OK, headers); - - size_t reqSize = static_cast( - session->get_request()->get_header("Content-Length", 0) ); - session->fetch( reqSize, [weakService]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - if( !checkRsServicePtrReady( - rsEvents, "rsEvents", cAns, session ) ) - return; - - RsEventType eventType = RsEventType::__NONE; - - // deserialize input parameters from JSON - { - RsGenericSerializer::SerializeContext& ctx(cReq); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON); - RS_SERIAL_PROCESS(eventType); - } - - const std::weak_ptr weakSession(session); - RsEventsHandlerId_t hId = rsEvents->generateUniqueHandlerId(); - std::function)> multiCallback = - [weakSession, weakService, hId]( - std::shared_ptr event ) - { - auto lService = weakService.lock(); - if(!lService || lService->is_down()) - { - if(rsEvents) rsEvents->unregisterEventsHandler(hId); - return; - } - - lService->schedule( [weakSession, hId, event]() - { - auto session = weakSession.lock(); - if(!session || session->is_closed()) - { - if(rsEvents) rsEvents->unregisterEventsHandler(hId); - return; - } - - RsGenericSerializer::SerializeContext ctx; - RsTypeSerializer::serial_process( - RsGenericSerializer::TO_JSON, ctx, - *const_cast(event.get()), "event" ); - - std::stringstream message; - message << "data: " << compactJSON << ctx.mJson << "\n\n"; - - session->yield(message.str()); - } ); - }; - - std::error_condition retval = rsEvents->registerEventsHandler( - multiCallback, hId, eventType ); - - { - RsGenericSerializer::SerializeContext& ctx(cAns); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(retval); - } - - // return them to the API caller - std::stringstream message; - message << "data: " << compactJSON << cAns.mJson << "\n\n"; - session->yield(message.str()); - } ); - }, true); - - registerHandler("/rsJsonApi/restart", - [this](const std::shared_ptr session) - { - auto reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( static_cast(reqSize), [this]( - const std::shared_ptr session, - const rb::Bytes& body ) - { - INITIALIZE_API_CALL_JSON_CONTEXT; - - std::error_condition retval; - - const auto now = time(nullptr); - if(mRestartReqTS.exchange(now) + RESTART_BURST_PROTECTION > now) - retval = RsJsonApiErrorNum::NOT_A_MACHINE_GUN; - - // serialize out parameters and return value to JSON - { - RsGenericSerializer::SerializeContext& ctx(cAns); - RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON); - RS_SERIAL_PROCESS(retval); - } - - DEFAULT_API_CALL_JSON_RETURN(rb::OK); - - /* Wrap inside RsThread::async because this call fullstop() on - * JSON API server thread. - * Calling RsThread::fullstop() from it's own thread should never - * happen and if it happens an error message is printed - * accordingly by RsThread::fullstop() */ - if(!retval) RsThread::async([this](){ unProtectedRestart(); }); - } ); - }, true); - -// Generated at compile time -#include "jsonapi-wrappers.inl" -} - -void JsonApiServer::registerHandler( - const std::string& path, - const std::function)>& handler, - bool requiresAutentication ) -{ - std::shared_ptr resource(new rb::Resource); - resource->set_path(path); - resource->set_method_handler("GET", handler); - resource->set_method_handler("POST", handler); - resource->set_method_handler("OPTIONS", handleCorsOptions); - - if(requiresAutentication) - resource->set_authentication_handler( - [this, path]( - const std::shared_ptr session, - const std::function)>& callback ) - { - /* Declare outside the lambda to avoid returning a dangling - * reference */ - RsWarn tWarn; - const auto authFail = - [&](int status) -> std::ostream& - { - /* Capture session by reference as it is cheaper then copying - * shared_ptr by value which is not needed in this case */ - - session->close(status, corsOptionsHeaders); - return tWarn << "JsonApiServer authentication handler " - "blocked an attempt to call JSON API " - "authenticated method: " << path; - }; - - if(session->get_request()->get_method() == "OPTIONS") - { - callback(session); - return; - } - - if(!rsLoginHelper->isLoggedIn()) - { - authFail(rb::CONFLICT) << " before RetroShare login" - << std::endl; - return; - } - - std::istringstream authHeader; - authHeader.str(session->get_request()->get_header("Authorization")); - - std::string authToken; - std::getline(authHeader, authToken, ' '); - - if(authToken != "Basic") - { - authFail(rb::UNAUTHORIZED) - << " with wrong Authorization header: " - << authHeader.str() << std::endl; - return; - } - - std::getline(authHeader, authToken, ' '); - authToken = decodeToken(authToken); - - std::error_condition ec; - if(isAuthTokenValid(authToken, ec)) callback(session); - else - { - std::string tUser; - parseToken(authToken, tUser, RS_DEFAULT_STORAGE_PARAM(std::string)); - authFail(rb::UNAUTHORIZED) - << " user: " << tUser << ec << std::endl; - } - } ); - - mResources.push_back(resource); -} - -void JsonApiServer::setNewAccessRequestCallback( - const std::function& callback ) -{ mNewAccessRequestCallback = callback; } - -/*static*/ std::error_condition JsonApiServer::badApiCredientalsFormat( - const std::string& user, const std::string& passwd ) -{ - if(user.find(':') < std::string::npos) - return RsJsonApiErrorNum::API_USER_CONTAIN_COLON; - - if(user.empty()) - RsWarn() << __PRETTY_FUNCTION__ << " User is empty, are you sure " - << "this what you wanted?" << std::endl; - - if(passwd.empty()) - RsWarn() << __PRETTY_FUNCTION__ << " Password is empty, are you sure " - << "this what you wanted?" << std::endl; - - return std::error_condition(); -} - -std::error_condition JsonApiServer::requestNewTokenAutorization( - const std::string& user, const std::string& passwd ) -{ - auto ec = badApiCredientalsFormat(user, passwd); - if(ec) return ec; - - if(!rsLoginHelper->isLoggedIn()) - return RsJsonApiErrorNum::CANNOT_EXECUTE_BEFORE_RS_LOGIN; - - if(mNewAccessRequestCallback(user, passwd)) - return authorizeUser(user, passwd); - - return RsJsonApiErrorNum::AUTHORIZATION_REQUEST_DENIED; -} - -bool JsonApiServer::isAuthTokenValid( - const std::string& token, std::error_condition& error ) -{ - RS_STACK_MUTEX(configMutex); - - const auto failure = [&error](RsJsonApiErrorNum e) -> bool - { - error = e; - return false; - }; - - const auto success = [&error]() - { - error.clear(); - return true; - }; - - std::string user,passwd; - if(!parseToken(token, user, passwd)) - return failure(RsJsonApiErrorNum::TOKEN_FORMAT_INVALID); - - auto it = mAuthTokenStorage.mAuthorizedTokens.find(user); - if(it == mAuthTokenStorage.mAuthorizedTokens.end()) - return failure(RsJsonApiErrorNum::UNKNOWN_API_USER); - - // attempt avoiding +else CRYPTO_memcmp+ being optimized away - int noOptimiz = 1; - - /* Do not use mAuthTokenStorage.mAuthorizedTokens.count(token), because - * std::string comparison is usually not constant time on content to be - * faster, so an attacker may use timings to guess authorized tokens */ - - if( passwd.size() == it->second.size() && - ( noOptimiz = CRYPTO_memcmp( - passwd.data(), it->second.data(), it->second.size() ) ) == 0 ) - return success(); - // Make token size guessing harder - else noOptimiz = CRYPTO_memcmp(passwd.data(), passwd.data(), passwd.size()); - - /* At this point we are sure password is wrong, and one could think to - * plainly `return false` still this ugly and apparently unuseful extra - * calculation is here to avoid `else CRYPTO_memcmp` being optimized away, - * so a pontential attacker cannot guess password size based on timing */ - return static_cast(noOptimiz) + 1 == 0 ? - success() : failure(RsJsonApiErrorNum::WRONG_API_PASSWORD); -} - -std::map JsonApiServer::getAuthorizedTokens() -{ - RS_STACK_MUTEX(configMutex); - return mAuthTokenStorage.mAuthorizedTokens; -} - -bool JsonApiServer::revokeAuthToken(const std::string& token) -{ - RS_STACK_MUTEX(configMutex); - if(mAuthTokenStorage.mAuthorizedTokens.erase(token)) - { - IndicateConfigChanged(); - return true; - } - return false; -} - -void JsonApiServer::connectToConfigManager(p3ConfigMgr& cfgmgr) -{ - cfgmgr.addConfiguration("jsonapi.cfg",this); - - RsFileHash hash; - loadConfiguration(hash); -} - -std::error_condition JsonApiServer::authorizeUser( - const std::string& user, const std::string& passwd ) -{ - auto ec = badApiCredientalsFormat(user, passwd); - if(ec) return ec; - - RS_STACK_MUTEX(configMutex); - - std::string& p(mAuthTokenStorage.mAuthorizedTokens[user]); - if(p != passwd) - { - p = passwd; - IndicateConfigChanged(); - } - return ec; -} - -/*static*/ std::string JsonApiServer::decodeToken(const std::string& radix64_token) -{ - std::vector decodedVect(Radix64::decode(radix64_token)); - std::string decodedToken( - reinterpret_cast(&decodedVect[0]), - decodedVect.size() ); - return decodedToken; -} - -RsSerialiser* JsonApiServer::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new JsonApiConfigSerializer); - return rss; -} - -bool JsonApiServer::saveList(bool& cleanup, std::list& saveItems) -{ - cleanup = false; - configMutex.lock(); - saveItems.push_back(&mAuthTokenStorage); - return true; -} - -bool JsonApiServer::loadList(std::list& loadList) -{ - for(RsItem* it : loadList) - switch (static_cast(it->PacketSubType())) - { - case JsonApiItemsType::AuthTokenItem: - mAuthTokenStorage = *static_cast(it); - delete it; - break; - default: - delete it; - break; - } - return true; -} - -void JsonApiServer::saveDone() { configMutex.unlock(); } - -void JsonApiServer::handleCorsOptions( - const std::shared_ptr session ) -{ session->close(rb::NO_CONTENT, corsOptionsHeaders); } - -void JsonApiServer::registerResourceProvider(const JsonApiResourceProvider& rp) -{ mResourceProviders.insert(rp); } -void JsonApiServer::unregisterResourceProvider(const JsonApiResourceProvider& rp) -{ mResourceProviders.erase(rp); } -bool JsonApiServer::hasResourceProvider(const JsonApiResourceProvider& rp) -{ return mResourceProviders.find(rp) != mResourceProviders.end(); } - -std::vector > JsonApiServer::getResources() const -{ - auto tab = mResources; - - for(auto& rp: mResourceProviders) - for(auto r: rp.get().getResources()) tab.push_back(r); - - return tab; -} - -std::error_condition JsonApiServer::restart() -{ - const auto now = time(nullptr); - if(mRestartReqTS.exchange(now) + RESTART_BURST_PROTECTION > now) - return RsJsonApiErrorNum::NOT_A_MACHINE_GUN; - - unProtectedRestart(); - return std::error_condition(); -} - -void JsonApiServer::onStopRequested() -{ - auto tService = std::atomic_exchange( - &mService, std::shared_ptr(nullptr) ); - if(tService) tService->stop(); -} - -uint16_t JsonApiServer::listeningPort() const { return mListeningPort; } -void JsonApiServer::setListeningPort(uint16_t p) { mListeningPort = p; } -void JsonApiServer::setBindingAddress(const std::string& bindAddress) -{ mBindingAddress = bindAddress; } -std::string JsonApiServer::getBindingAddress() const { return mBindingAddress; } - -void JsonApiServer::run() -{ - auto settings = std::make_shared(); - settings->set_port(mListeningPort); - settings->set_bind_address(mBindingAddress); - settings->set_default_header("Connection", "close"); - - auto tService = std::make_shared(); - - for(auto& r: getResources()) tService->publish(r); - - try - { - RsUrl apiUrl; apiUrl.setScheme("http").setHost(mBindingAddress) - .setPort(mListeningPort); - RsInfo() << __PRETTY_FUNCTION__ << " JSON API server listening on " - << apiUrl.toString() << std::endl; - - /* re-allocating mService is important because it deletes the existing - * service and therefore leaves the listening port open */ - auto tExpected = std::shared_ptr(nullptr); - if(atomic_compare_exchange_strong(&mService, &tExpected, tService)) - tService->start(settings); - else - { - RsErr() << __PRETTY_FUNCTION__ << " mService was expected to be " - << " null, instead we got: " << tExpected - << " something wrong happened JsonApiServer won't start" - << std::endl; - print_stacktrace(); - } - } - catch(std::exception& e) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure starting JSON API server: " - << e.what() << std::endl; - print_stacktrace(); - return; - } - - RsDbg() << __PRETTY_FUNCTION__ << " finished!" << std::endl; -} - -/*static*/ void RsJsonApi::version( - uint32_t& major, uint32_t& minor, uint32_t& mini, std::string& extra, - std::string& human ) -{ - major = RS_MAJOR_VERSION; - minor = RS_MINOR_VERSION; - mini = RS_MINI_VERSION; - extra = RS_EXTRA_VERSION; - human = RS_HUMAN_READABLE_VERSION; -} - -std::error_condition RsJsonApiErrorCategory::default_error_condition(int ev) const noexcept -{ - switch(static_cast(ev)) - { - case RsJsonApiErrorNum::TOKEN_FORMAT_INVALID: // fallthrough - case RsJsonApiErrorNum::UNKNOWN_API_USER: // fallthrough - case RsJsonApiErrorNum::WRONG_API_PASSWORD: // fallthrough - case RsJsonApiErrorNum::AUTHORIZATION_REQUEST_DENIED: - return std::errc::permission_denied; - case RsJsonApiErrorNum::API_USER_CONTAIN_COLON: - return std::errc::invalid_argument; - default: - return std::error_condition(ev, *this); - } -} diff --git a/libretroshare/src/jsonapi/jsonapi.h b/libretroshare/src/jsonapi/jsonapi.h deleted file mode 100644 index 317d4066f..000000000 --- a/libretroshare/src/jsonapi/jsonapi.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * RetroShare JSON API - * - * Copyright (C) 2018-2020 Gioacchino Mazzurco - * Copyright (C) 2019-2020 Asociación Civil Altermundi - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. - * See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util/rsthreads.h" -#include "pqi/p3cfgmgr.h" -#include "rsitems/rsitem.h" -#include "jsonapi/jsonapiitems.h" -#include "retroshare/rsjsonapi.h" -#include "util/rsthreads.h" - -namespace rb = restbed; - -/** Interface to provide addotional resources to JsonApiServer */ -class JsonApiResourceProvider -{ -public: - virtual ~JsonApiResourceProvider() = default; - - virtual std::vector> getResources() const = 0; - - inline bool operator< (const JsonApiResourceProvider& rp) const - { return this < &rp; } -}; - -/** - * Uses p3Config to securely store persistent JSON API authorization tokens - */ -class JsonApiServer : public p3Config, public RsThread, public RsJsonApi -{ -public: - JsonApiServer(); - ~JsonApiServer() override = default; - - std::vector> getResources() const; - - /// @see RsJsonApi - void fullstop() override { RsThread::fullstop(); } - - /// @see RsJsonApi - std::error_condition restart() override; - - /// @see RsJsonApi - void askForStop() override { RsThread::askForStop(); } - - /// @see RsJsonApi - inline bool isRunning() override { return RsThread::isRunning(); } - - /// @see RsJsonApi - void setListeningPort(uint16_t port) override; - - /// @see RsJsonApi - void setBindingAddress(const std::string& bindAddress) override; - - /// @see RsJsonApi - std::string getBindingAddress() const override; - - /// @see RsJsonApi - uint16_t listeningPort() const override; - - /// @see RsJsonApi - void connectToConfigManager(p3ConfigMgr& cfgmgr) override; - - /// @see RsJsonApi - virtual std::error_condition authorizeUser( - const std::string& user, const std::string& passwd ) override; - - /// @see RsJsonApi - std::map getAuthorizedTokens() override; - - /// @see RsJsonApi - bool revokeAuthToken(const std::string& user) override; - - /// @see RsJsonApi - bool isAuthTokenValid( - const std::string& token, - std::error_condition& error = RS_DEFAULT_STORAGE_PARAM(std::error_condition) - ) override; - - /// @see RsJsonAPI - std::error_condition requestNewTokenAutorization( - const std::string& user, const std::string& password ) override; - - /// @see RsJsonApi - void registerResourceProvider(const JsonApiResourceProvider&) override; - - /// @see RsJsonApi - void unregisterResourceProvider(const JsonApiResourceProvider&) override; - - /// @see RsJsonApi - bool hasResourceProvider(const JsonApiResourceProvider&) override; - - /** - * @brief Get decoded version of the given encoded token - * @param[in] radix64_token encoded - * @return token decoded - */ - static std::string decodeToken(const std::string& radix64_token); - - /** - * Register an unique handler for a resource path - * @param[in] path Path into which publish the API call - * @param[in] handler function which will be called to handle the requested - * @param[in] requiresAutentication specify if the API call must be - * autenticated or not. - */ - void registerHandler( - const std::string& path, - const std::function)>& handler, - bool requiresAutentication = true ); - - /** - * @brief Set new access request callback - * @param callback function to call when a new JSON API access is requested - */ - void setNewAccessRequestCallback( - const std::function& - callback ); - -protected: - /// @see RsThread - void onStopRequested() override; - - static std::error_condition badApiCredientalsFormat( - const std::string& user, const std::string& passwd ); - -private: - /// @see RsThread - void run() override; - - /// @see p3Config::setupSerialiser - RsSerialiser* setupSerialiser() override; - - /// @see p3Config::saveList - bool saveList(bool &cleanup, std::list& saveItems) override; - - /// @see p3Config::loadList - bool loadList(std::list& loadList) override; - - /// @see p3Config::saveDone - void saveDone() override; - - /// Called when new JSON API auth token is requested to be authorized - std::function - mNewAccessRequestCallback; - - /// Encrypted persistent storage for authorized JSON API tokens - JsonApiServerAuthTokenStorage mAuthTokenStorage; - RsMutex configMutex; - - static const std::multimap corsHeaders; - static const std::multimap corsOptionsHeaders; - static void handleCorsOptions(const std::shared_ptr session); - - static bool checkRsServicePtrReady( - const void* serviceInstance, const std::string& serviceName, - RsGenericSerializer::SerializeContext& ctx, - const std::shared_ptr session ); - - static inline bool checkRsServicePtrReady( - const std::shared_ptr serviceInstance, - const std::string& serviceName, - RsGenericSerializer::SerializeContext& ctx, - const std::shared_ptr session ) - { - return checkRsServicePtrReady( - serviceInstance.get(), serviceName, ctx, session ); - } - - std::vector> mResources; - std::set< - std::reference_wrapper, - std::less > mResourceProviders; - - /** - * This pointer should be accessed via std::atomic_* operations, up until - * now only very critical operations like reallocation, are done that way, - * but this is not still 100% thread safe, but seems to handle all of the - * test cases (no crash, no deadlock), once we switch to C++20 we shoud - * change this into std::atomic> which - * will automatically handle atomic access properly all the times - */ - std::shared_ptr mService; - - uint16_t mListeningPort; - std::string mBindingAddress; - - /// @see unProtectedRestart() - std::atomic mRestartReqTS; - - /// @see unProtectedRestart() - constexpr static rstime_t RESTART_BURST_PROTECTION = 7; - - /** It is very important to protect this method from being called in bursts, - * because Restbed::Service::stop() together with - * Restbed::Service::start(...), which are called internally, silently fails - * if combined in bursts, probably because they have to deal with - * listening/releasing TCP port. - * @see JsonApiServer::restart() and @see JsonApiServer::JsonApiServer() - * implementation to understand how correctly use this. - */ - void unProtectedRestart(); -}; - diff --git a/libretroshare/src/jsonapi/jsonapiitems.h b/libretroshare/src/jsonapi/jsonapiitems.h deleted file mode 100644 index eba871e98..000000000 --- a/libretroshare/src/jsonapi/jsonapiitems.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * RetroShare JSON API - * - * Copyright (C) 2018-2019 Gioacchino Mazzurco - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. - * See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#pragma once - -#include -#include "util/rstime.h" -#include -#include - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserializer.h" -#include "serialiser/rsserializable.h" - -enum class JsonApiItemsType : uint8_t { AuthTokenItem_deprecated = 0, AuthTokenItem = 1 }; - -struct JsonApiServerAuthTokenStorage : RsItem -{ - JsonApiServerAuthTokenStorage() : - RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_JSONAPI, - static_cast(JsonApiItemsType::AuthTokenItem) ) {} - - /// @see RsSerializable - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(mAuthorizedTokens); - } - - /// @see RsItem - virtual void clear() { mAuthorizedTokens.clear(); } - - std::map mAuthorizedTokens; -}; - - -struct JsonApiConfigSerializer : RsServiceSerializer -{ - JsonApiConfigSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_JSONAPI) {} - virtual ~JsonApiConfigSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_TYPE_JSONAPI) return nullptr; - - switch(static_cast(item_sub_id)) - { - case JsonApiItemsType::AuthTokenItem: return new JsonApiServerAuthTokenStorage(); - default: return nullptr; - } - } -}; - - diff --git a/libretroshare/src/jsonapi/p3webui.cc b/libretroshare/src/jsonapi/p3webui.cc deleted file mode 100644 index 60fc63ea9..000000000 --- a/libretroshare/src/jsonapi/p3webui.cc +++ /dev/null @@ -1,196 +0,0 @@ -/* - * RetroShare Web User Interface - * - * Copyright (C) 2019 Cyril Soler - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. - * See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#include "p3webui.h" - -#include -#include -#include -#include -#include -#include - -#include "util/rsthreads.h" -#include "util/rsdebug.h" -#include "retroshare/rswebui.h" -#include "rsserver/rsaccounts.h" -#include "retroshare/rsjsonapi.h" - -#define DEBUG_RS_WEBUI 1 - -/*extern*/ RsWebUi* rsWebUi = new p3WebUI; - -enum MimeTypeIndex -{ - TEXT_HTML, - TEXT_CSS, - TEXT_SVG, - TEXT_TTF, - TEXT_WOFF, - APPLICATION_OCTET_STREAM, -}; - -static const constexpr char* const mime_types[] = -{ - "text/html", - "text/css", - "image/svg+xml", - "font/ttf", - "font/woff", - "application/octet-stream", -}; - -const std::string RsWebUi::DEFAULT_BASE_DIRECTORY = - RsAccountsDetail::PathDataDirectory(false) + "/webui/"; - -static std::string _base_directory = RsWebUi::DEFAULT_BASE_DIRECTORY; - -template class handler -{ -public: - static void get_handler( const std::shared_ptr< restbed::Session > session ) - { - const auto request = session->get_request( ); - const std::string filename = request->get_path_parameter( "filename" ); - std::string directory = request->get_path_parameter( "dir" ); - - if(!directory.empty()) directory += "/"; - - std::string resource_filename = _base_directory + "/" + directory + filename; - RsDbg() << "Reading file: \"" << resource_filename << "\"" << std::endl; - std::ifstream stream( resource_filename, std::ifstream::in ); - - if(stream.is_open()) - { - const std::string body = std::string( - std::istreambuf_iterator(stream), - std::istreambuf_iterator() ); - - RsDbg() << __PRETTY_FUNCTION__ - << " body length=" << body.length() << std::endl; - - const std::multimap headers - { - { "Content-Type", mime_types[MIME_TYPE_INDEX] }, - { "Content-Length", std::to_string(body.length()) } - }; - - session->close(restbed::OK, body, headers); - } - else - { - RsErr() << __PRETTY_FUNCTION__ << "Could not open file: " - << resource_filename << std::endl; - session->close(restbed::NOT_FOUND); - } - } -}; - -std::vector< std::shared_ptr > p3WebUI::getResources() const -{ - static std::vector< std::shared_ptr > rtab; - - if(rtab.empty()) - { - auto resource1 = std::make_shared< restbed::Resource >(); - resource1->set_paths( { - "/{filename: index.html}", - "/{filename: app.js}", - } - ); - resource1->set_method_handler( "GET", handler::get_handler ); - - auto resource2 = std::make_shared< restbed::Resource >(); - resource2->set_paths( { - "/{dir: css}/{filename: fontawesome.css}", - "/{dir: css}/{filename: solid.css}", - "/{filename: app.css}", - } ); - resource2->set_method_handler( "GET", handler::get_handler ); - - auto resource3 = std::make_shared< restbed::Resource >(); - resource3->set_paths( { - "/{dir: data}/{filename: retroshare.svg}", - "/{dir: webfonts}/{filename: fa-solid-900.svg}", - } ); - resource3->set_method_handler( "GET", handler::get_handler ); - - auto resource4 = std::make_shared< restbed::Resource >(); - resource4->set_paths( { - "/{dir: webfonts}/{filename: fa-solid-900.ttf}", - } ); - resource4->set_method_handler( "GET", handler::get_handler ); - - auto resource5 = std::make_shared< restbed::Resource >(); - resource5->set_paths( { - "/{dir: webfonts}/{filename: fa-solid-900.woff}", - "/{dir: webfonts}/{filename: fa-solid-900.woff2}", - } ); - resource5->set_method_handler( "GET", handler::get_handler ); - - auto resource6 = std::make_shared< restbed::Resource >(); - resource6->set_paths( { - "/{dir: webfonts}/{filename: fa-solid-900.eot}", - } ); - resource6->set_method_handler( "GET", handler::get_handler ); - - rtab.push_back(resource1); - rtab.push_back(resource2); - rtab.push_back(resource3); - rtab.push_back(resource4); - rtab.push_back(resource5); - rtab.push_back(resource6); - } - - return rtab; -} - - -void p3WebUI::setHtmlFilesDirectory(const std::string& html_dir) -{ - _base_directory = html_dir; -} - -bool p3WebUI::isRunning() const -{ return rsJsonApi->isRunning() && rsJsonApi->hasResourceProvider(*this); } - -void p3WebUI::setUserPassword(const std::string& passwd) -{ - RsDbg() << __PRETTY_FUNCTION__ << " Updating webui token with new passwd \"" - << passwd << "\"" << std::endl; - - if(!rsJsonApi->authorizeUser("webui",passwd)) - std::cerr << "(EE) Cannot register webui token. Some error occurred when calling authorizeUser()" << std::endl; -} - -bool p3WebUI::restart() -{ - rsJsonApi->registerResourceProvider(*this); - rsJsonApi->restart(); - return true; -} - -bool p3WebUI::stop() -{ - rsJsonApi->unregisterResourceProvider(*this); - rsJsonApi->restart(); - return true; -} diff --git a/libretroshare/src/jsonapi/p3webui.h b/libretroshare/src/jsonapi/p3webui.h deleted file mode 100644 index b67927ab7..000000000 --- a/libretroshare/src/jsonapi/p3webui.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * RetroShare Web User Interface - * - * Copyright (C) 2019 Cyril Soler - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the - * Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. - * See the GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: AGPL-3.0-only - */ - -#pragma once - -#include -#include -#include - -#include "retroshare/rswebui.h" -#include "jsonapi/jsonapi.h" - -class p3WebUI: public RsWebUi, public JsonApiResourceProvider -{ -public: - ~p3WebUI() override = default; - - // implements RsWebUI - - virtual void setHtmlFilesDirectory(const std::string& html_dir) override; - virtual void setUserPassword(const std::string& passwd) override; - - virtual bool restart() override ; - virtual bool stop() override ; - bool isRunning() const override; - // implements JsonApiResourceProvider - - virtual std::vector > getResources() const override; -}; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro deleted file mode 100644 index 84d18944e..000000000 --- a/libretroshare/src/libretroshare.pro +++ /dev/null @@ -1,1069 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") - -TEMPLATE = lib -libretroshare_shared { - CONFIG += shared -} else { - CONFIG += staticlib -} -CONFIG -= qt -TARGET = retroshare -TARGET_PRL = libretroshare -DESTDIR = lib - -!include("use_libretroshare.pri"):error("Including") - -# treat warnings as error for better removing -#QMAKE_CFLAGS += -Werror -#QMAKE_CXXFLAGS += -Werror - -## Uncomment to enable Unfinished Services. -#CONFIG += wikipoos -#CONFIG += gxsthewire -#CONFIG += gxsphotoshare - -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 -} - -CONFIG += file_lists - -file_lists { - HEADERS *= file_sharing/p3filelists.h \ - file_sharing/hash_cache.h \ - file_sharing/filelist_io.h \ - file_sharing/directory_storage.h \ - file_sharing/directory_updater.h \ - file_sharing/rsfilelistitems.h \ - file_sharing/dir_hierarchy.h \ - file_sharing/file_sharing_defaults.h - - SOURCES *= file_sharing/p3filelists.cc \ - file_sharing/hash_cache.cc \ - file_sharing/filelist_io.cc \ - file_sharing/directory_storage.cc \ - file_sharing/directory_updater.cc \ - file_sharing/dir_hierarchy.cc \ - file_sharing/file_tree.cc \ - file_sharing/rsfilelistitems.cc -} - - -dsdv { -DEFINES *= SERVICES_DSDV -HEADERS += unused/p3dsdv.h \ - unused/rstlvdsdv.h \ - unused/rsdsdvitems.h \ - unused/rsdsdv.h - -SOURCES *= unused/rstlvdsdv.cc \ - unused/rsdsdvitems.cc \ - unused/p3dsdv.cc -} -bitdht { - -HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.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/udprelay.h \ - tcponudp/rsudpstack.h \ - pqi/pqissludp.h \ - -SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.cc \ - tcponudp/udprelay.cc \ - pqi/pqissludp.cc \ - - useDhtStunner { - HEADERS += dht/stunaddrassist.h \ - tcponudp/udpstunner.h - - SOURCES += tcponudp/udpstunner.cc - - DEFINES += RS_USE_DHT_STUNNER - } - - 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/rsgossipdiscovery \ - retroshare/rsevents.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 \ - retroshare/rsgxsdistsync.h - -rs_webui { - PUBLIC_HEADERS += retroshare/rswebui.h - SOURCES += jsonapi/p3webui.cc - HEADERS += jsonapi/p3webui.h -} - -HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - rsitems/rspluginitems.h \ - util/i2pcommon.h \ - util/rsinitedptr.h - -HEADERS += $$PUBLIC_HEADERS - -################################# Linux ########################################## -linux-* { - CONFIG += link_pkgconfig - - QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 - QMAKE_CC = $${QMAKE_CXX} - - 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 - } - } - - contains(RS_UPNP_LIB, threadutil) { # ensure we don't break libpnp-1.8.x - # Check if the systems libupnp-1.6.x has been Debian-patched - !system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) { - # Patched libupnp or new unreleased version - DEFINES *= PATCHED_LIBUPNP - } - } - - PKGCONFIG *= libssl - equals(RS_UPNP_LIB, "upnp ixml threadutil"):PKGCONFIG *= libupnp - PKGCONFIG *= libcrypto zlib - no_sqlcipher:PKGCONFIG *= sqlite3 - LIBS *= -ldl - - DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -version_detail_bash_script { - warning("Version detail script is deprecated.") - warning("Remove references to version_detail_bash_script from all of your build scripts!") -} - -#################### 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 - - 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-g++|win32-clang-g++ { - QMAKE_CC = $${QMAKE_CXX} - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - !libretroshare_shared:DEFINES *= STATICLIB - - # 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 - - wLibs = ws2_32 gdi32 uuid iphlpapi crypt32 ole32 winmm - LIBS += $$linkDynamicLibs(wLibs) -} - -################################# MacOSX ########################################## - -mac { - QMAKE_CC = $${QMAKE_CXX} - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - - # Beautiful Hack to fix 64bit file access. - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs - - for(lib, LIB_DIR):LIBS += -L"$$lib" - for(bin, BIN_DIR):LIBS += -L"$$bin" - - DEPENDPATH += . $$INC_DIR - INCLUDEPATH += . $$INC_DIR - INCLUDEPATH += ../../../. - - # 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 - - DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" -} - -################################# 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 -} - -################################# 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 -} - -################################# 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 - 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 & SOURCES ############################# - -HEADERS += ft/ftchunkmap.h \ - ft/ftcontroller.h \ - ft/ftdata.h \ - ft/ftdatamultiplex.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 += crypto/chacha20.h \ - crypto/rsaes.h \ - crypto/hashstream.h \ - crypto/rscrypto.h - -HEADERS += directory_updater.h \ - directory_list.h \ - p3filelists.h - -HEADERS += chat/distantchat.h \ - chat/p3chatservice.h \ - chat/distributedchat.h \ - chat/rschatitems.h - -HEADERS += pqi/authssl.h \ - pqi/authgpg.h \ - pgp/pgphandler.h \ - pgp/pgpkeyutil.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/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/pqiservicemonitor.h \ - pqi/pqissl.h \ - pqi/pqissllistener.h \ - pqi/pqisslpersongrp.h \ - pqi/pqissli2pbob.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 - -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 \ - retroshare/rsgrouter.h \ - grouter/grouteritems.h \ - grouter/p3grouter.h \ - grouter/rsgroutermatrix.h \ - grouter/groutertypes.h \ - grouter/grouterclientservice.h - -HEADERS += rsitems/rsitem.h \ - rsitems/itempriorities.h \ - serialiser/rsbaseserial.h \ - rsitems/rsfiletransferitems.h \ - rsitems/rsconfigitems.h \ - rsitems/rshistoryitems.h \ - rsitems/rsmsgitems.h \ - serialiser/rsserial.h \ - rsitems/rsserviceids.h \ - serialiser/rsserviceitems.h \ - rsitems/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 \ - rsitems/rsbanlistitems.h \ - rsitems/rsbwctrlitems.h \ - gossipdiscovery/gossipdiscoveryitems.h \ - rsitems/rsheartbeatitems.h \ - rsitems/rsrttitems.h \ - rsitems/rsgxsrecognitems.h \ - rsitems/rsgxsupdateitems.h \ - rsitems/rsserviceinfoitems.h \ - -HEADERS += services/autoproxy/p3i2pbob.h \ - services/rseventsservice.h \ - services/autoproxy/rsautoproxymonitor.h \ - services/p3msgservice.h \ - services/p3service.h \ - services/p3statusservice.h \ - services/p3banlist.h \ - services/p3bwctrl.h \ - gossipdiscovery/p3gossipdiscovery.h \ - services/p3heartbeat.h \ - services/p3rtt.h \ - services/p3serviceinfo.h \ - -HEADERS += turtle/p3turtle.h \ - turtle/rsturtleitem.h \ - turtle/turtletypes.h \ - turtle/turtleclientservice.h - -HEADERS += util/folderiterator.h \ - util/rsdebug.h \ - util/rsdebuglevel0.h \ - util/rsdebuglevel1.h \ - util/rsdebuglevel2.h \ - util/rsdebuglevel3.h \ - util/rsdebuglevel4.h \ - util/rskbdinput.h \ - util/rsmemory.h \ - util/smallobject.h \ - util/rsdir.h \ - util/argstream.h \ - util/rsdiscspace.h \ - util/rsnet.h \ - util/extaddrfinder.h \ - util/dnsresolver.h \ - util/radix32.h \ - util/radix64.h \ - util/rsbase64.h \ - util/rsendian.h \ - util/rsinitedptr.h \ - util/rsprint.h \ - util/rsstring.h \ - util/rsstd.h \ - util/rsthreads.h \ - util/rswin.h \ - util/rsrandom.h \ - util/rsmemcache.h \ - util/rstickevent.h \ - util/rsrecogn.h \ - util/rstime.h \ - util/stacktrace.h \ - util/rsdeprecate.h \ - util/cxx11retrocompat.h \ - util/cxx14retrocompat.h \ - util/cxx17retrocompat.h \ - util/rsurl.h \ - util/rserrno.h - -SOURCES += ft/ftchunkmap.cc \ - ft/ftcontroller.cc \ - ft/ftdatamultiplex.cc \ - ft/ftextralist.cc \ - ft/ftfilecreator.cc \ - ft/ftfileprovider.cc \ - ft/ftfilesearch.cc \ - ft/ftserver.cc \ - ft/fttransfermodule.cc \ - ft/ftturtlefiletransferitem.cc \ - util/i2pcommon.cpp - -SOURCES += crypto/chacha20.cpp \ - crypto/hashstream.cc\ - crypto/rsaes.cc \ - crypto/rscrypto.cpp - -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/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/pqissli2pbob.cpp \ - pqi/pqisslproxy.cc \ - pqi/pqistore.cc \ - pqi/pqistreamer.cc \ - pqi/pqithreadstreamer.cc \ - pqi/pqiqosstreamer.cc \ - pqi/sslfns.cc \ - pqi/pqinetstatebox.cc \ - pqi/p3servicecontrol.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/p3serverconfig.cc - -SOURCES += grouter/p3grouter.cc \ - grouter/grouteritems.cc \ - grouter/groutermatrix.cc - -SOURCES += plugins/pluginmanager.cc \ - plugins/dlfcn_win32.cc - -SOURCES += serialiser/rsbaseserial.cc \ - rsitems/rsfiletransferitems.cc \ - rsitems/rsconfigitems.cc \ - rsitems/rshistoryitems.cc \ - rsitems/rsmsgitems.cc \ - serialiser/rsserial.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 \ - rsitems/rsbanlistitems.cc \ - rsitems/rsbwctrlitems.cc \ - gossipdiscovery/gossipdiscoveryitems.cc \ - rsitems/rsrttitems.cc \ - rsitems/rsgxsrecognitems.cc \ - rsitems/rsgxsupdateitems.cc \ - rsitems/rsserviceinfoitems.cc \ - - -SOURCES += services/autoproxy/rsautoproxymonitor.cc \ - services/rseventsservice.cc \ - services/autoproxy/p3i2pbob.cc \ - services/p3msgservice.cc \ - services/p3service.cc \ - services/p3statusservice.cc \ - services/p3banlist.cc \ - services/p3bwctrl.cc \ - gossipdiscovery/p3gossipdiscovery.cc \ - services/p3heartbeat.cc \ - services/p3rtt.cc \ - services/p3serviceinfo.cc \ - -SOURCES += turtle/p3turtle.cc \ - turtle/rsturtleitem.cc - -SOURCES += util/folderiterator.cc \ - util/rsdebug.cc \ - util/rskbdinput.cc \ - util/rsexpr.cc \ - util/smallobject.cc \ - util/rsdir.cc \ - util/rsmemory.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/rsrandom.cc \ - util/rstickevent.cc \ - util/rsrecogn.cc \ - util/rstime.cc \ - util/rsurl.cc \ - util/rsbase64.cc \ - util/rserrno.cc - -equals(RS_UPNP_LIB, miniupnpc) { - HEADERS += rs_upnp/upnputil.h rs_upnp/upnphandler_miniupnp.h - SOURCES += rs_upnp/upnputil.cc rs_upnp/upnphandler_miniupnp.cc -} - -contains(RS_UPNP_LIB, upnp) { - HEADERS += rs_upnp/upnp18_retrocompat.h - HEADERS += rs_upnp/UPnPBase.h rs_upnp/upnphandler_libupnp.h - SOURCES += rs_upnp/UPnPBase.cpp rs_upnp/upnphandler_libupnp.cc -} - -# new gxs cache system -# this should be disabled for releases until further notice. - -DEFINES *= SQLITE_HAS_CODEC -DEFINES *= GXS_ENABLE_SYNC_MSGS - -HEADERS += rsitems/rsnxsitems.h \ - rsitems/rsgxsitems.h \ - retroshare/rstokenservice.h \ - retroshare/rsgxsservice.h \ - retroshare/rsgxsflags.h \ - retroshare/rsgxsifacetypes.h \ - retroshare/rsgxsiface.h \ - retroshare/rsgxscommon.h \ - retroshare/rsgxsifacehelper.h \ - util/retrodb.h \ - util/rsdbbind.h \ - util/contentvalue.h \ - gxs/rsgxsutil.h \ - gxs/rsgxsnotify.h \ - gxs/gxssecurity.h \ - gxs/rsgds.h \ - gxs/rsgxs.h \ - gxs/rsdataservice.h \ - gxs/rsgxsnetservice.h \ - gxs/rsgxsnettunnel.h \ - gxs/rsgenexchange.h \ - gxs/rsnxs.h \ - gxs/rsnxsobserver.h \ - gxs/rsgxsdata.h \ - gxs/rsgxsdataaccess.h \ - gxs/gxstokenqueue.h \ - gxs/rsgxsnetutils.h \ - gxs/rsgxsrequesttypes.h - - -SOURCES += rsitems/rsnxsitems.cc \ - rsitems/rsgxsitems.cc \ - util/retrodb.cc \ - util/contentvalue.cc \ - util/rsdbbind.cc \ - gxs/gxssecurity.cc \ - gxs/rsgxsdataaccess.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ - gxs/rsgxsnetservice.cc \ - gxs/rsgxsnettunnel.cc \ - gxs/rsgxsdata.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 - -# new serialization code -HEADERS += serialiser/rsserializable.h \ - serialiser/rsserializer.h \ - serialiser/rstypeserializer.h \ - util/rsjson.h - -SOURCES += serialiser/rsserializable.cc \ - serialiser/rsserializer.cc \ - serialiser/rstypeserializer.cc \ - util/rsjson.cc - -# Identity Service -HEADERS += retroshare/rsidentity.h \ - retroshare/rsreputations.h \ - gxs/rsgixs.h \ - services/p3idservice.h \ - rsitems/rsgxsiditems.h \ - services/p3gxsreputation.h \ - rsitems/rsgxsreputationitems.h \ - -SOURCES += services/p3idservice.cc \ - rsitems/rsgxsiditems.cc \ - services/p3gxsreputation.cc \ - rsitems/rsgxsreputationitems.cc \ - -# GxsCircles Service -HEADERS += services/p3gxscircles.h \ - rsitems/rsgxscircleitems.h \ - retroshare/rsgxscircles.h \ - -SOURCES += services/p3gxscircles.cc \ - rsitems/rsgxscircleitems.cc \ - -# GxsForums Service -HEADERS += retroshare/rsgxsforums.h \ - services/p3gxsforums.h \ - rsitems/rsgxsforumitems.h - -SOURCES += services/p3gxsforums.cc \ - rsitems/rsgxsforumitems.cc \ - -# GxsChannels Service -HEADERS += retroshare/rsgxschannels.h \ - services/p3gxschannels.h \ - services/p3gxscommon.h \ - rsitems/rsgxscommentitems.h \ - rsitems/rsgxschannelitems.h \ - -SOURCES += services/p3gxschannels.cc \ - services/p3gxscommon.cc \ - rsitems/rsgxscommentitems.cc \ - rsitems/rsgxschannelitems.cc \ - -wikipoos { - DEFINES *= RS_USE_WIKI - - # Wiki Service - HEADERS += retroshare/rswiki.h \ - services/p3wiki.h \ - rsitems/rswikiitems.h - - SOURCES += services/p3wiki.cc \ - rsitems/rswikiitems.cc \ -} - -gxsthewire { - DEFINES *= RS_USE_WIRE - - # Wire Service - HEADERS += retroshare/rswire.h \ - services/p3wire.h \ - rsitems/rswireitems.h - - SOURCES += services/p3wire.cc \ - rsitems/rswireitems.cc \ -} - -# Posted Service -HEADERS += services/p3postbase.h \ - services/p3posted.h \ - retroshare/rsposted.h \ - rsitems/rsposteditems.h - -SOURCES += services/p3postbase.cc \ - services/p3posted.cc \ - rsitems/rsposteditems.cc - -gxsphotoshare { - DEFINES *= RS_USE_PHOTO - - #Photo Service - HEADERS += services/p3photoservice.h \ - retroshare/rsphoto.h \ - rsitems/rsphotoitems.h \ - - SOURCES += services/p3photoservice.cc \ - rsitems/rsphotoitems.cc \ -} - -rs_gxs_trans { - HEADERS += gxstrans/p3gxstransitems.h gxstrans/p3gxstrans.h - SOURCES += gxstrans/p3gxstransitems.cc gxstrans/p3gxstrans.cc -} - -rs_jsonapi { - JSONAPI_GENERATOR_SRC=$$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/) - JSONAPI_GENERATOR_OUT=$$clean_path($${RS_BUILD_PATH}/jsonapi-generator/src/) - isEmpty(JSONAPI_GENERATOR_EXE) { - win32 { - CONFIG(release, debug|release) { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/release/jsonapi-generator.exe) - } - CONFIG(debug, debug|release) { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/debug/jsonapi-generator.exe) - } - } else { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator) - } - } - - DOXIGEN_INPUT_DIRECTORY=$$clean_path($${PWD}) - DOXIGEN_CONFIG_SRC=$$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/jsonapi-generator-doxygen.conf) - DOXIGEN_CONFIG_OUT=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator-doxygen-final.conf) - WRAPPERS_INCL_FILE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-includes.inl) - WRAPPERS_REG_FILE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-wrappers.inl) - - no_rs_cross_compiling { - DUMMYRESTBEDINPUT = FORCE - CMAKE_GENERATOR_OVERRIDE="" - win32-g++|win32-clang-g++ { - isEmpty(QMAKE_SH) { - CMAKE_GENERATOR_OVERRIDE="-G \"MinGW Makefiles\"" - } else { - CMAKE_GENERATOR_OVERRIDE="-G \"MSYS Makefiles\"" - } - } - genrestbedlib.name = Generating librestbed. - genrestbedlib.input = DUMMYRESTBEDINPUT - genrestbedlib.output = $$clean_path($${RESTBED_BUILD_PATH}/librestbed.a) - genrestbedlib.CONFIG += target_predeps combine - genrestbedlib.variable_out = PRE_TARGETDEPS - win32-g++:isEmpty(QMAKE_SH) { - genrestbedlib.commands = \ - cd /D $$shell_path($${RS_SRC_PATH}) && git submodule update --init supportlibs/restbed || cd . $$escape_expand(\\n\\t) \ - cd /D $$shell_path($${RESTBED_SRC_PATH}) && git submodule update --init dependency/asio || cd . $$escape_expand(\\n\\t) \ - cd /D $$shell_path($${RESTBED_SRC_PATH}) && git submodule update --init dependency/catch || cd . $$escape_expand(\\n\\t )\ - cd /D $$shell_path($${RESTBED_SRC_PATH}) && git submodule update --init dependency/kashmir || cd . $$escape_expand(\\n\\t) \ - $(CHK_DIR_EXISTS) $$shell_path($$UDP_DISCOVERY_BUILD_PATH) $(MKDIR) $$shell_path($${UDP_DISCOVERY_BUILD_PATH}) $$escape_expand(\\n\\t) - } else { - genrestbedlib.commands = \ - cd $${RS_SRC_PATH} && ( \ - git submodule update --init supportlibs/restbed ; \ - cd $${RESTBED_SRC_PATH} ; \ - git submodule update --init dependency/asio ; \ - git submodule update --init dependency/catch ; \ - git submodule update --init dependency/kashmir ; \ - true ) && \ - mkdir -p $${RESTBED_BUILD_PATH} && - } - genrestbedlib.commands += \ - cd $$shell_path($${RESTBED_BUILD_PATH}) && \ - cmake \ - -DCMAKE_CXX_COMPILER=$$QMAKE_CXX \ - \"-DCMAKE_CXX_FLAGS=$${QMAKE_CXXFLAGS}\" \ - $${CMAKE_GENERATOR_OVERRIDE} -DBUILD_SSL=OFF \ - -DCMAKE_INSTALL_PREFIX=. -B. \ - -H$$shell_path($${RESTBED_SRC_PATH}) && \ - $(MAKE) - QMAKE_EXTRA_COMPILERS += genrestbedlib - - RESTBED_HEADER_FILE=$$clean_path($${RESTBED_BUILD_PATH}/include/restbed) - genrestbedheader.name = Generating restbed header. - genrestbedheader.input = genrestbedlib.output - genrestbedheader.output = $${RESTBED_HEADER_FILE} - genrestbedheader.CONFIG += target_predeps no_link - genrestbedheader.variable_out = HEADERS - genrestbedheader.commands = cd $$shell_path($${RESTBED_BUILD_PATH}) && $(MAKE) install - QMAKE_EXTRA_COMPILERS += genrestbedheader - } - - INCLUDEPATH *= $${JSONAPI_GENERATOR_OUT} - DEPENDPATH *= $${JSONAPI_GENERATOR_OUT} - APIHEADERS = $$files($${RS_SRC_PATH}/libretroshare/src/retroshare/*.h) - #Make sure that the jsonapigenerator executable are ready - APIHEADERS += $${JSONAPI_GENERATOR_EXE} - - genjsonapi.name = Generating jsonapi headers. - genjsonapi.input = APIHEADERS - genjsonapi.output = $${WRAPPERS_INCL_FILE} $${WRAPPERS_REG_FILE} - genjsonapi.clean = $${WRAPPERS_INCL_FILE} $${WRAPPERS_REG_FILE} - genjsonapi.CONFIG += target_predeps combine no_link - genjsonapi.variable_out = HEADERS - win32-g++:isEmpty(QMAKE_SH) { - genjsonapi.commands = \ - $(CHK_DIR_EXISTS) $$shell_path($$JSONAPI_GENERATOR_OUT) $(MKDIR) $$shell_path($${JSONAPI_GENERATOR_OUT}) $$escape_expand(\\n\\t) - } else { - genjsonapi.commands = \ - mkdir -p $${JSONAPI_GENERATOR_OUT} && \ - cp $${DOXIGEN_CONFIG_SRC} $${DOXIGEN_CONFIG_OUT} && \ - echo OUTPUT_DIRECTORY=$${JSONAPI_GENERATOR_OUT} >> $${DOXIGEN_CONFIG_OUT} && \ - echo INPUT=$${DOXIGEN_INPUT_DIRECTORY} >> $${DOXIGEN_CONFIG_OUT} && \ - doxygen $${DOXIGEN_CONFIG_OUT} && - } - genjsonapi.commands += \ - $${JSONAPI_GENERATOR_EXE} $${JSONAPI_GENERATOR_SRC} $${JSONAPI_GENERATOR_OUT} - QMAKE_EXTRA_COMPILERS += genjsonapi - - # Force recalculation of libretroshare dependencies see https://stackoverflow.com/a/47884045 - QMAKE_EXTRA_TARGETS += libretroshare - - HEADERS += jsonapi/jsonapi.h jsonapi/jsonapiitems.h retroshare/rsjsonapi.h - SOURCES += jsonapi/jsonapi.cpp -} - -rs_deep_channels_index { - HEADERS *= deep_search/commonutils.hpp - SOURCES *= deep_search/commonutils.cpp - - HEADERS += deep_search/channelsindex.hpp - SOURCES += deep_search/channelsindex.cpp -} - -rs_deep_files_index { - HEADERS *= deep_search/commonutils.hpp - SOURCES *= deep_search/commonutils.cpp - - HEADERS += deep_search/filesindex.hpp - SOURCES += deep_search/filesindex.cpp -} - -rs_deep_files_index_ogg { - HEADERS += deep_search/filesoggindexer.hpp -} - -rs_deep_files_index_flac { - HEADERS += deep_search/filesflacindexer.hpp -} - -rs_deep_files_index_taglib { - HEADERS += deep_search/filestaglibindexer.hpp -} - -rs_broadcast_discovery { - HEADERS += retroshare/rsbroadcastdiscovery.h \ - services/broadcastdiscoveryservice.h - SOURCES += services/broadcastdiscoveryservice.cc - - no_rs_cross_compiling { - DUMMYQMAKECOMPILERINPUT = FORCE - CMAKE_GENERATOR_OVERRIDE="" - win32-g++|win32-clang-g++ { - isEmpty(QMAKE_SH) { - CMAKE_GENERATOR_OVERRIDE="-G \"MinGW Makefiles\"" - } else { - CMAKE_GENERATOR_OVERRIDE="-G \"MSYS Makefiles\"" - } - } - udpdiscoverycpplib.name = Generating libudp-discovery.a. - udpdiscoverycpplib.input = DUMMYQMAKECOMPILERINPUT - udpdiscoverycpplib.output = $$clean_path($${UDP_DISCOVERY_BUILD_PATH}/libudp-discovery.a) - udpdiscoverycpplib.CONFIG += target_predeps combine - udpdiscoverycpplib.variable_out = PRE_TARGETDEPS - win32-g++:isEmpty(QMAKE_SH) { - udpdiscoverycpplib.commands = \ - cd /D $$shell_path($${RS_SRC_PATH}) && git submodule update --init supportlibs/udp-discovery-cpp || cd . $$escape_expand(\\n\\t) \ - $(CHK_DIR_EXISTS) $$shell_path($$UDP_DISCOVERY_BUILD_PATH) $(MKDIR) $$shell_path($${UDP_DISCOVERY_BUILD_PATH}) $$escape_expand(\\n\\t) - } else { - udpdiscoverycpplib.commands = \ - cd $${RS_SRC_PATH} && ( \ - git submodule update --init supportlibs/udp-discovery-cpp || \ - true ) && \ - mkdir -p $${UDP_DISCOVERY_BUILD_PATH} && - } - udpdiscoverycpplib.commands += \ - cd $$shell_path($${UDP_DISCOVERY_BUILD_PATH}) && \ - cmake -DCMAKE_C_COMPILER=$$fixQmakeCC($$QMAKE_CC) \ - -DCMAKE_CXX_COMPILER=$$QMAKE_CXX \ - \"-DCMAKE_CXX_FLAGS=$${QMAKE_CXXFLAGS}\" \ - $${CMAKE_GENERATOR_OVERRIDE} \ - -DBUILD_EXAMPLE=OFF -DBUILD_TOOL=OFF \ - -DCMAKE_INSTALL_PREFIX=. -B. \ - -H$$shell_path($${UDP_DISCOVERY_SRC_PATH}) && \ - $(MAKE) - QMAKE_EXTRA_COMPILERS += udpdiscoverycpplib - } -} - -########################################################################################################### -# 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. -} - -################################# Android ##################################### - -android-* { -## TODO: This probably disable largefile support and maybe is not necessary with -## __ANDROID_API__ >= 24 hence should be made conditional or moved to a -## compatibility header - DEFINES *= "fopen64=fopen" - DEFINES *= "fseeko64=fseeko" - DEFINES *= "ftello64=ftello" - -## Static library are very susceptible to order in command line - sLibs = bz2 $$RS_UPNP_LIB $$RS_SQL_LIB ssl crypto - - LIBS += $$linkStaticLibs(sLibs) - PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) - - HEADERS += util/androiddebug.h -} - diff --git a/libretroshare/src/pgp/pgpauxutils.cc b/libretroshare/src/pgp/pgpauxutils.cc deleted file mode 100644 index d7229e848..000000000 --- a/libretroshare/src/pgp/pgpauxutils.cc +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: pgpauxutils.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pgp/pgpauxutils.h" - -#include "pqi/authgpg.h" -#include "rsserver/p3face.h" -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" - -PgpAuxUtilsImpl::PgpAuxUtilsImpl() -{ - return; -} - - -const RsPgpId& PgpAuxUtilsImpl::getPGPOwnId() -{ - return AuthGPG::getAuthGPG()->getGPGOwnId(); -} - -RsPgpId PgpAuxUtilsImpl::getPGPId(const RsPeerId& sslid) -{ - return rsPeers->getGPGId(sslid); -} - -bool PgpAuxUtilsImpl::getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const -{ - return AuthGPG::getAuthGPG()->getKeyFingerprint(id, fp); -} - -bool PgpAuxUtilsImpl::VerifySignBin(const void *data, - uint32_t len, - unsigned char *sign, - unsigned int signlen, - const PGPFingerprintType& withfingerprint) - -{ - return AuthGPG::getAuthGPG()->VerifySignBin(data, len, sign, signlen, withfingerprint); -} - -bool PgpAuxUtilsImpl::getGPGAllList(std::list &ids) -{ - return AuthGPG::getAuthGPG()->getGPGAllList(ids); -} - -bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const -{ - return AuthGPG::getAuthGPG()->parseSignature(sign,signlen,issuer); -} - - - - diff --git a/libretroshare/src/pgp/pgpauxutils.h b/libretroshare/src/pgp/pgpauxutils.h deleted file mode 100644 index 4b188e3ae..000000000 --- a/libretroshare/src/pgp/pgpauxutils.h +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: pgpauxutils.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsids.h" -#include "retroshare/rstypes.h" -#include "util/rsdeprecate.h" - -/* This is a small collection of PGP functions that are widely used in libretroshare. - * This interface class allows these functions to be easily mocked for testing. - */ - -class PgpAuxUtils -{ - public: - virtual ~PgpAuxUtils(){} - - virtual const RsPgpId &getPGPOwnId() = 0; - virtual RsPgpId getPGPId(const RsPeerId& sslid) = 0; - virtual bool getGPGAllList(std::list &ids) = 0; - virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const = 0; - - virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0; - virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) = 0; -}; - -class PgpAuxUtilsImpl: public PgpAuxUtils -{ -public: - PgpAuxUtilsImpl(); - - virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); - - virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const ; - virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; - virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint); - virtual bool getGPGAllList(std::list &ids); -}; - - diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc deleted file mode 100644 index b1e96b00b..000000000 --- a/libretroshare/src/pgp/pgphandler.cc +++ /dev/null @@ -1,2133 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: pgphandler.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#ifdef WINDOWS_SYS -#include -#include "util/rsstring.h" -#include "util/rswin.h" -#endif - -extern "C" { -#include -#include -#include -#include -#include -#include -#include -} -#include "pgphandler.h" -#include "retroshare/rsiface.h" // For rsicontrol. -#include "retroshare/rspeers.h" // For rsicontrol. -#include "util/rsdir.h" -#include "util/rsdiscspace.h" -#include "util/rsmemory.h" -#include "pgp/pgpkeyutil.h" - -static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE = 64 ; -static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE = 64 ; -static const uint32_t PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE = 1024 ; - -//#define DEBUG_PGPHANDLER 1 -//#define PGPHANDLER_DSA_SUPPORT - -PassphraseCallback PGPHandler::_passphrase_callback = NULL ; - -ops_keyring_t *PGPHandler::allocateOPSKeyring() -{ - ops_keyring_t *kr = (ops_keyring_t*)rs_malloc(sizeof(ops_keyring_t)) ; - - if(kr == NULL) - return NULL ; - - kr->nkeys = 0 ; - kr->nkeys_allocated = 0 ; - kr->keys = 0 ; - - return kr ; -} - -ops_parse_cb_return_t cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)// __attribute__((unused))) -{ - const ops_parser_content_union_t *content=&content_->content; - bool prev_was_bad = false ; - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: prev_was_bad = true ; - /* fallthrough */ - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - { - std::string passwd; - std::string uid_hint ; - - if(cbinfo->cryptinfo.keydata->nuids > 0) - uid_hint = std::string((const char *)cbinfo->cryptinfo.keydata->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(cbinfo->cryptinfo.keydata->key_id).toStdString()+")" ; - - bool cancelled = false ; - passwd = PGPHandler::passphraseCallback()(NULL,"",uid_hint.c_str(),NULL,prev_was_bad,&cancelled) ; - - if(cancelled) - *(unsigned char *)cbinfo->arg = 1; - - *(content->secret_key_passphrase.passphrase)= (char *)ops_mallocz(passwd.length()+1) ; - memcpy(*(content->secret_key_passphrase.passphrase),passwd.c_str(),passwd.length()) ; - return OPS_KEEP_MEMORY; - } - break; - - default: - break; - } - - return OPS_RELEASE_MEMORY; -} -void PGPHandler::setPassphraseCallback(PassphraseCallback cb) -{ - _passphrase_callback = cb ; -} - -PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) - : pgphandlerMtx(std::string("PGPHandler")), _pubring_path(pubring),_secring_path(secring),_trustdb_path(trustdb),_pgp_lock_filename(pgp_lock_filename) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - _pubring_changed = false ; - _trustdb_changed = false ; - - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - if(_passphrase_callback == NULL) - std::cerr << "WARNING: before created a PGPHandler, you need to init the passphrase callback using PGPHandler::setPassphraseCallback()" << std::endl; - - // Allocate public and secret keyrings. - // - _pubring = allocateOPSKeyring() ; - _secring = allocateOPSKeyring() ; - - // Check that the file exists. If not, create a void keyring. - - FILE *ftest ; - ftest = RsDirUtil::rs_fopen(pubring.c_str(),"rb") ; - bool pubring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - ftest = RsDirUtil::rs_fopen(secring.c_str(),"rb") ; - bool secring_exist = (ftest != NULL) ; - if(ftest != NULL) - fclose(ftest) ; - - // Read public and secret keyrings from supplied files. - // - if(pubring_exist) - { - if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring. File corrupted.") ; - } - else - std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl; - - const ops_keydata_t *keydata ; - int i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - - // Init all certificates. - - initCertificateInfo(cert,keydata,i) ; - - // Validate signatures. - - validateAndUpdateSignatures(cert,keydata) ; - - ++i ; - } - _pubring_last_update_time = time(NULL) ; - std::cerr << "Pubring read successfully." << std::endl; - - if(secring_exist) - { - if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) - throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring. File corrupted.") ; - } - else - std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl; - - i=0 ; - while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) - { - initCertificateInfo(_secret_keyring_map[ RsPgpId(keydata->key_id) ],keydata,i) ; - ++i ; - } - _secring_last_update_time = time(NULL) ; - - std::cerr << "Secring read successfully." << std::endl; - - locked_readPrivateTrustDatabase() ; - _trustdb_last_update_time = time(NULL) ; -} - -void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) -{ - // Parse certificate name - // - - if(keydata->uids != NULL) - { - std::string namestring( (char *)keydata->uids[0].user_id ) ; - - cert._name = "" ; - uint32_t i=0; - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} - - // trim right spaces - std::string::size_type found = cert._name.find_last_not_of(' '); - if (found != std::string::npos) - cert._name.erase(found + 1); - else - cert._name.clear(); // all whitespace - - std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next += namestring[i] ; ++i ;} - - while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { next += namestring[i] ; ++i ;} - - if(i< namestring.length()) - { - std::string& next2 = (namestring[i] == '(')?cert._comment:cert._email ; - ++i ; - next2 = "" ; - while(i < namestring.length() && namestring[i] != ')' && namestring[i] != '>') { next2 += namestring[i] ; ++i ;} - } - } - - cert._trustLvl = 1 ; // to be setup accordingly - cert._validLvl = 1 ; // to be setup accordingly - cert._key_index = index ; - cert._flags = 0 ; - cert._time_stamp = 0 ;// "never" by default. Will be updated by trust database, and effective key usage. - - switch(keydata->key.pkey.algorithm) - { - case OPS_PKA_RSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA ; - break ; - case OPS_PKA_DSA: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - default: cert._type = PGPCertificateInfo::PGP_CERTIFICATE_TYPE_UNKNOWN ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ; - break ; - } - - ops_fingerprint_t f ; - ops_fingerprint(&f,&keydata->key.pkey) ; - - cert._fpr = PGPFingerprintType(f.fingerprint) ; -} - -bool PGPHandler::validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) -{ - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res = ops_validate_key_signatures(result,keydata,_pubring,cb_get_passphrase) ; - - if(res == ops_false) - { - static ops_boolean_t already = 0 ; - if(!already) - { - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - already = 1 ; - } - } - - bool ret = false ; - - // Parse signers. - // - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - { - RsPgpId signer_id(result->valid_sigs[i].signer_id); - - if(cert.signers.find(signer_id) == cert.signers.end()) - { - cert.signers.insert(signer_id) ; - ret = true ; - } - } - - ops_validate_result_free(result) ; - - return ret ; -} - -PGPHandler::~PGPHandler() -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Freeing PGPHandler. Deleting keyrings." << std::endl; -#endif - - // no need to free the the _map_ elements. They will be freed by the following calls: - // - ops_keyring_free(_pubring) ; - ops_keyring_free(_secring) ; - - free(_pubring) ; - free(_secring) ; -} - -bool PGPHandler::printKeys() const -{ -#ifdef DEBUG_PGPHANDLER - std::cerr << "Printing details of all " << std::dec << _public_keyring_map.size() << " keys: " << std::endl; -#endif - - for(std::map::const_iterator it(_public_keyring_map.begin()); it != _public_keyring_map.end(); ++it) - { - std::cerr << "PGP Key: " << it->first.toStdString() << std::endl; - - std::cerr << "\tName : " << it->second._name << std::endl; - std::cerr << "\tEmail : " << it->second._email << std::endl; - std::cerr << "\tOwnSign : " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) << std::endl; - std::cerr << "\tAccept Connect: " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) << std::endl; - std::cerr << "\ttrustLvl : " << it->second._trustLvl << std::endl; - std::cerr << "\tvalidLvl : " << it->second._validLvl << std::endl; - std::cerr << "\tUse time stamp: " << it->second._time_stamp << std::endl; - std::cerr << "\tfingerprint : " << it->second._fpr.toStdString() << std::endl; - std::cerr << "\tSigners : " << it->second.signers.size() << std::endl; - - std::set::const_iterator sit; - for(sit = it->second.signers.begin(); sit != it->second.signers.end(); ++sit) - { - std::cerr << "\t\tSigner ID:" << (*sit).toStdString() << ", Name: " ; - const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(*sit) ; - - if(info != NULL) - std::cerr << info->_name ; - - std::cerr << std::endl ; - } - } - std::cerr << "Public keyring list from OPS:" << std::endl; - ops_keyring_list(_pubring) ; - - return true ; -} - -bool PGPHandler::haveSecretKey(const RsPgpId& id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - return locked_getSecretKey(id) != NULL ; -} - -const PGPCertificateInfo *PGPHandler::getCertificateInfo(const RsPgpId& id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - std::map::const_iterator it( _public_keyring_map.find(id) ) ; - - if(it != _public_keyring_map.end()) - return &it->second; - else - return NULL ; -} - -bool PGPHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // go through secret keyring, and check that we have the pubkey as well. - // - - const ops_keydata_t *keydata = NULL ; - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(_secring,i++)) != NULL ) - if(ops_keyring_find_key_by_id(_pubring,keydata->key_id) != NULL) // check that the key is in the pubring as well - { -#ifdef PGPHANDLER_DSA_SUPPORT - if(keydata->key.pkey.algorithm == OPS_PKA_RSA || keydata->key.pkey.algorithm == OPS_PKA_DSA) -#else - if(keydata->key.pkey.algorithm == OPS_PKA_RSA) -#endif - ids.push_back(RsPgpId(keydata->key_id)) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << "Skipping keypair " << RsPgpId(keydata->key_id).toStdString() << ", unsupported algorithm: " << keydata->key.pkey.algorithm << std::endl; -#endif - } - - return true ; -} - -bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passphrase, RsPgpId& pgpId, const int keynumbits, std::string& errString) -{ - // Some basic checks - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - errString = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - if(name.length() > PGP_CERTIFICATE_LIMIT_MAX_NAME_SIZE) - { - errString = std::string("(EE) name in certificate exceeds the maximum allowed name size") ; - return false ; - } - if(email.length() > PGP_CERTIFICATE_LIMIT_MAX_EMAIL_SIZE) - { - errString = std::string("(EE) email in certificate exceeds the maximum allowed email size") ; - return false ; - } - if(passphrase.length() > PGP_CERTIFICATE_LIMIT_MAX_PASSWD_SIZE) - { - errString = std::string("(EE) passphrase in certificate exceeds the maximum allowed passphrase size") ; - return false ; - } - if(keynumbits % 1024 != 0) - { - errString = std::string("(EE) RSA key length is not a multiple of 1024") ; - return false ; - } - - // Now the real thing - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - // 1 - generate keypair - RSA-2048 - // - ops_user_id_t uid ; - char *s = strdup((name + " (Generated by RetroShare) <" + email + ">" ).c_str()) ; - uid.user_id = (unsigned char *)s ; - unsigned long int e = 65537 ; // some prime number - - ops_keydata_t *key = ops_rsa_create_selfsigned_keypair(keynumbits, e, &uid) ; - - free(s) ; - - if(!key) - return false ; - - // 2 - save the private key encrypted to a temporary memory buffer, so as to read an encrypted key to memory - - ops_create_info_t *cinfo = NULL ; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString = std::string("(EE) Cannot encode secret key to memory!!") ; - return false ; - } - - // 3 - read the memory chunk into an encrypted keyring - - ops_keyring_t *tmp_secring = allocateOPSKeyring() ; - - if(! ops_keyring_read_from_mem(tmp_secring, ops_false, buf)) - { - errString = std::string("(EE) Cannot re-read key from memory!!") ; - return false ; - } - ops_teardown_memory_write(cinfo,buf); // cleanup memory - - // 4 - copy the encrypted private key to the private keyring - - pgpId = RsPgpId(tmp_secring->keys[0].key_id) ; - addNewKeyToOPSKeyring(_secring,tmp_secring->keys[0]) ; - initCertificateInfo(_secret_keyring_map[ pgpId ],&tmp_secring->keys[0],_secring->nkeys-1) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; -#endif - ops_keyring_free(tmp_secring) ; - free(tmp_secring) ; - - // 5 - add key to secret keyring on disk. - - cinfo = NULL ; - std::string secring_path_tmp = _secring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - errString= std::string("Cannot copy secret keyring !! Disk full? Out of disk quota?") ; - return false ; - } - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key(key,(unsigned char *)passphrase.c_str(),passphrase.length(),ops_false,cinfo)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - errString= std::string("Cannot rename tmp secret key file ") + secring_path_tmp + " into " + _secring_path +". Disk error?" ; - return false ; - } - - // 6 - copy the public key to the public keyring on disk - - cinfo = NULL ; - std::string pubring_path_tmp = _pubring_path + ".tmp" ; - - if(RsDirUtil::fileExists(_pubring_path) && !RsDirUtil::copyFile(_pubring_path,pubring_path_tmp)) - { - errString= std::string("Cannot encode secret key to disk!! Disk full? Out of disk quota?") ; - return false ; - } - fd=ops_setup_file_append(&cinfo, pubring_path_tmp.c_str()); - - if(!ops_write_transferable_public_key(key, ops_false, cinfo)) - { - errString=std::string("Cannot encode secret key to memory!!") ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - if(!RsDirUtil::renameFile(pubring_path_tmp,_pubring_path)) - { - errString= std::string("Cannot rename tmp public key file ") + pubring_path_tmp + " into " + _pubring_path +". Disk error?" ; - return false ; - } - // 7 - clean - ops_keydata_free(key) ; - - // 8 - re-read the key from the public keyring, and add it to memory. - - _pubring_last_update_time = 0 ; // force update pubring from disk. - locked_syncPublicKeyring() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; -#endif - - // 9 - Update some flags. - - privateTrustCertificate(pgpId,PGPCertificateInfo::PGP_CERTIFICATE_TRUST_ULTIMATE) ; - - return true ; -} - -std::string PGPHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) -{ - ops_create_info_t* cinfo; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&cinfo, &buf, 0); - ops_boolean_t armoured = ops_true ; - - if(key->type == OPS_PTAG_CT_PUBLIC_KEY) - { - if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else if(key->type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - { - if(ops_write_transferable_secret_key_from_packet_data(key,armoured,cinfo) != ops_true) - return "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." ; - } - else - { - ops_create_info_delete(cinfo); - std::cerr << "Unhandled key type " << key->type << std::endl; - return "ERROR: Cannot write key. Unhandled key type. " ; - } - - ops_writer_close(cinfo) ; - - std::string res((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ; - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - std::string tmp ; - if(PGPKeyManagement::createMinimalKey(res,tmp) ) - res = tmp ; - } - - return res ; -} - -const ops_keydata_t *PGPHandler::locked_getSecretKey(const RsPgpId& id) const -{ - std::map::const_iterator res = _secret_keyring_map.find(id) ; - - if(res == _secret_keyring_map.end()) - return NULL ; - else - return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; -} -const ops_keydata_t *PGPHandler::locked_getPublicKey(const RsPgpId& id,bool stamp_the_key) const -{ - std::map::const_iterator res = _public_keyring_map.find(id) ; - - if(res == _public_keyring_map.end()) - return NULL ; - else - { - if(stamp_the_key) // Should we stamp the key as used? - { - static rstime_t last_update_db_because_of_stamp = 0 ; - rstime_t now = time(NULL) ; - - res->second._time_stamp = now ; - - if(now > last_update_db_because_of_stamp + 3600) // only update database once every hour. No need to do it more often. - { - _trustdb_changed = true ; - last_update_db_because_of_stamp = now ; - } - } - return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; - } -} - -std::string PGPHandler::SaveCertificateToString(const RsPgpId& id,bool include_signatures) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(key == NULL) - { - std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl; - return "" ; - } - - return makeRadixEncodedPGPKey(key,include_signatures) ; -} - -bool PGPHandler::exportPublicKey( - const RsPgpId& id, - unsigned char*& mem_block, size_t& mem_size, - bool armoured, bool include_signatures ) const -{ - mem_block = nullptr; mem_size = 0; // clear just in case - - if(armoured) - { - RsErr() << __PRETTY_FUNCTION__ << " should not be used with " - << "armoured=true, because there's a bug in the armoured export" - << " of OPS" << std::endl; - print_stacktrace(); - return false; - } - - RS_STACK_MUTEX(pgphandlerMtx); - const ops_keydata_t* key = locked_getPublicKey(id,false); - - if(!key) - { - RsErr() << __PRETTY_FUNCTION__ << " key id: " << id - << " not found in keyring." << std::endl; - return false; - } - - ops_create_info_t* cinfo; - ops_memory_t *buf = nullptr; - ops_setup_memory_write(&cinfo, &buf, 0); - - if(ops_write_transferable_public_key_from_packet_data( - key, armoured, cinfo ) != ops_true) - { - RsErr() << __PRETTY_FUNCTION__ << " This key id " << id - << " cannot be processed by RetroShare because DSA certificates" - << " support is not implemented yet." << std::endl; - return false; - } - - ops_writer_close(cinfo); - - mem_size = ops_memory_get_length(buf); - mem_block = reinterpret_cast(malloc(mem_size)); - memcpy(mem_block,ops_memory_get_data(buf),mem_size); - - ops_teardown_memory_write(cinfo,buf); - - if(!include_signatures) - { - size_t new_size; - PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size); - mem_size = new_size; - } - - return true; -} - -bool PGPHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *pubkey = locked_getPublicKey(exported_key_id,false) ; - - if(pubkey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in public keyring." << std::endl; - return false ; - } - const ops_keydata_t *seckey = locked_getSecretKey(exported_key_id) ; - - if(seckey == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": not found in secret keyring." << std::endl; - return false ; - } - - FILE *f = RsDirUtil::rs_fopen(filename.c_str(),"w") ; - if(f == NULL) - { - std::cerr << "Cannot output key " << exported_key_id.toStdString() << ": file " << filename << " cannot be written. Please check for permissions, quotas, disk space." << std::endl; - return false ; - } - - fprintf(f,"%s\n", makeRadixEncodedPGPKey(pubkey,true).c_str()) ; - fprintf(f,"%s\n", makeRadixEncodedPGPKey(seckey,true).c_str()) ; - - fclose(f) ; - return true ; -} - -bool PGPHandler::exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *pubkey = locked_getPublicKey(exportedKeyId,false); - - if(!pubkey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in public keyring."; - return false; - } - const ops_keydata_t *seckey = locked_getSecretKey(exportedKeyId); - - if(!seckey) - { - errorMsg = "Cannot output key " + exportedKeyId.toStdString() + - ": not found in secret keyring."; - return false; - } - - data = makeRadixEncodedPGPKey(pubkey, includeSignatures); - data += "\n"; - data += makeRadixEncodedPGPKey(seckey, includeSignatures); - data += "\n"; - return true; -} - -bool PGPHandler::getGPGDetailsFromBinaryBlock(const unsigned char *mem_block,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const -{ - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,mem_block,mem_size); - - if(!ops_keyring_read_from_mem(tmp_keyring,ops_false,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - //error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - //error_string.clear() ; - - if(tmp_keyring->nkeys != 1) - { - std::cerr << "No or incomplete/invalid key in supplied pgp block." << std::endl; - return false ; - } - if(tmp_keyring->keys[0].uids == NULL) - { - std::cerr << "No uid in supplied key." << std::endl; - return false ; - } - - key_id = RsPgpId(tmp_keyring->keys[0].key_id) ; - name = std::string((char *)tmp_keyring->keys[0].uids[0].user_id) ; - - // now parse signatures. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - ops_boolean_t res ; - - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],_pubring,cb_get_passphrase) ; - } - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // also add self-signature if any (there should be!). - // - res = ops_validate_key_signatures(result,&tmp_keyring->keys[0],tmp_keyring,cb_get_passphrase) ; - - if(res == ops_false) - std::cerr << "(WW) Error in PGPHandler::validateAndUpdateSignatures(). Validation failed for at least some signatures." << std::endl; - - // Parse signers. - // - - std::set signers_set ; // Use a set to remove duplicates. - - if(result != NULL) - for(size_t i=0;ivalid_count;++i) - signers_set.insert(RsPgpId(result->valid_sigs[i].signer_id)) ; - - ops_validate_result_free(result) ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - // write to the output variable - - signers.clear() ; - - for(std::set::const_iterator it(signers_set.begin());it!=signers_set.end();++it) - signers.push_back(*it) ; - - return true ; -} - -bool PGPHandler::importGPGKeyPair(const std::string& filename,RsPgpId& imported_key_id,std::string& import_error) -{ - import_error = "" ; - - // 1 - Test for file existance - // - FILE *ftest = RsDirUtil::rs_fopen(filename.c_str(),"r") ; - - if(ftest == NULL) - { - import_error = "Cannot open file " + filename + " for read. Please check access permissions." ; - return false ; - } - - fclose(ftest) ; - - // 2 - Read keyring from supplied file. - // - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_file(tmp_keyring, ops_true, filename.c_str())) - { - import_error = "PGPHandler::readKeyRing(): cannot read key file. File corrupted?" ; - free(tmp_keyring); - return false ; - } - - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::importGPGKeyPairFromString(const std::string &data, RsPgpId &imported_key_id, std::string &import_error) -{ - import_error = "" ; - - ops_memory_t* mem = ops_memory_new(); - ops_memory_add(mem, (unsigned char*)data.data(), data.length()); - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - - if(ops_false == ops_keyring_read_from_mem(tmp_keyring, ops_true, mem)) - { - import_error = "PGPHandler::importGPGKeyPairFromString(): cannot parse key data" ; - free(tmp_keyring); - return false ; - } - return checkAndImportKeyPair(tmp_keyring, imported_key_id, import_error); -} - -bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &imported_key_id, std::string &import_error) -{ - if(tmp_keyring == 0) - { - import_error = "PGPHandler::checkAndImportKey(): keyring is null" ; - return false; - } - - if(tmp_keyring->nkeys != 2) - { - import_error = "PGPHandler::importKeyPair(): file does not contain a valid keypair." ; - if(tmp_keyring->nkeys > 2) - import_error += "\nMake sure that your key is a RSA key (DSA is not yet supported) and does not contain subkeys (not supported yet)."; - return false ; - } - - // 3 - Test that keyring contains a valid keypair. - // - const ops_keydata_t *pubkey = NULL ; - const ops_keydata_t *seckey = NULL ; - - if(tmp_keyring->keys[0].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[0] ; - else if(tmp_keyring->keys[0].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[0] ; - else - { - import_error = "Unrecognised key type in key file for key #0. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[0].type << " in key file for key #0. Giving up." << std::endl; - return false ; - } - if(tmp_keyring->keys[1].type == OPS_PTAG_CT_PUBLIC_KEY) - pubkey = &tmp_keyring->keys[1] ; - else if(tmp_keyring->keys[1].type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - seckey = &tmp_keyring->keys[1] ; - else - { - import_error = "Unrecognised key type in key file for key #1. Giving up." ; - std::cerr << "Unrecognised key type " << tmp_keyring->keys[1].type << " in key file for key #1. Giving up." << std::endl; - return false ; - } - - if(pubkey == nullptr || seckey == nullptr || pubkey == seckey) - { - import_error = "File does not contain a public and a private key. Sorry." ; - return false ; - } - if(memcmp( pubkey->fingerprint.fingerprint, - seckey->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES ) != 0) - { - import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; - return false ; - } - if(pubkey->key.pkey.version != 4) - { - import_error = "Public key is not version 4. Rejected!" ; - return false ; - } - - // 4 - now check self-signature for this keypair. For this we build a dummy keyring containing only the key. - // - ops_validate_result_t *result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_keyring_t dummy_keyring ; - dummy_keyring.nkeys=1 ; - dummy_keyring.nkeys_allocated=1 ; - dummy_keyring.keys=const_cast(pubkey) ; - - ops_validate_key_signatures(result, const_cast(pubkey), &dummy_keyring, cb_get_passphrase) ; - - // Check that signatures contain at least one certification from the user id. - // - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - pubkey->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - import_error = "Cannot validate self signature for the imported key. Sorry." ; - return false ; - } - ops_validate_result_free(result); - - if(!RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - import_error = std::string("(EE) low disc space in pgp directory. Can't write safely to keyring.") ; - return false ; - } - // 5 - All test passed. Adding key to keyring. - // - { - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - imported_key_id = RsPgpId(pubkey->key_id) ; - - if(locked_getSecretKey(imported_key_id) == NULL) - { - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - ops_create_info_t *cinfo = NULL ; - - // Make a copy of the secret keyring - // - std::string secring_path_tmp = _secring_path + ".tmp" ; - if(RsDirUtil::fileExists(_secring_path) && !RsDirUtil::copyFile(_secring_path,secring_path_tmp)) - { - import_error = "(EE) Cannot write secret key to disk!! Disk full? Out of disk quota. Keyring will be left untouched." ; - return false ; - } - - // Append the new key - - int fd=ops_setup_file_append(&cinfo, secring_path_tmp.c_str()); - - if(!ops_write_transferable_secret_key_from_packet_data(seckey,ops_false,cinfo)) - { - import_error = "(EE) Cannot encode secret key to disk!! Disk full? Out of disk quota?" ; - return false ; - } - ops_teardown_file_write(cinfo,fd) ; - - // Rename the new keyring to overwrite the old one. - // - if(!RsDirUtil::renameFile(secring_path_tmp,_secring_path)) - { - import_error = " (EE) Cannot move temp file " + secring_path_tmp + ". Bad write permissions?" ; - return false ; - } - - addNewKeyToOPSKeyring(_secring,*seckey) ; - initCertificateInfo(_secret_keyring_map[ imported_key_id ],seckey,_secring->nkeys-1) ; - } - else - import_error = "Private key already exists! Not importing it again." ; - - if(locked_addOrMergeKey(_pubring,_public_keyring_map,pubkey)) - _pubring_changed = true ; - } - - // 6 - clean - // - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring); - - // write public key to disk - syncDatabase(); - - return true ; -} - -void PGPHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& key) -{ - if(kr->nkeys >= kr->nkeys_allocated) - { - kr->keys = (ops_keydata_t *)realloc(kr->keys,(kr->nkeys+1)*sizeof(ops_keydata_t)) ; - kr->nkeys_allocated = kr->nkeys+1; - } - memset(&kr->keys[kr->nkeys],0,sizeof(ops_keydata_t)) ; - ops_keydata_copy(&kr->keys[kr->nkeys],&key) ; - kr->nkeys++ ; -} - -bool PGPHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate(data,data_len,ops_false,id,error_string); -} - -bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string) -{ - return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string); -} - -bool PGPHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. -#ifdef DEBUG_PGPHANDLER - std::cerr << "Reading new key from string: " << std::endl; -#endif - - ops_keyring_t *tmp_keyring = allocateOPSKeyring(); - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,data,data_len) ; - - if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem)) - { - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - ops_memory_release(mem) ; - free(mem) ; - - std::cerr << "Could not read key. Format error?" << std::endl; - error_string = std::string("Could not read key. Format error?") ; - return false ; - } - ops_memory_release(mem) ; - free(mem) ; - error_string.clear() ; - - // Check that there is exactly one key in this data packet. - // - if(tmp_keyring->nkeys != 1) - { - std::cerr << "Loaded certificate contains more than one PGP key. This is not allowed." << std::endl; - error_string = "Loaded certificate contains more than one PGP key. This is not allowed." ; - return false ; - } - - const ops_keydata_t *keydata = ops_keyring_get_key_by_index(tmp_keyring,0); - - // Check that the key is a version 4 key - // - if(keydata->key.pkey.version != 4) - { - error_string = "Public key is not version 4. Rejected!" ; - std::cerr << "Received a key with unhandled version number (" << keydata->key.pkey.version << ")" << std::endl; - return false ; - } - - // Check that the key is correctly self-signed. - // - ops_validate_result_t* result=(ops_validate_result_t*)ops_mallocz(sizeof *result); - - ops_validate_key_signatures(result,keydata,tmp_keyring,cb_get_passphrase) ; - - bool found = false ; - - for(uint32_t i=0;ivalid_count;++i) - if(!memcmp( - static_cast(result->valid_sigs[i].signer_id), - keydata->key_id, - RsPgpId::SIZE_IN_BYTES )) - { - found = true ; - break ; - } - - if(!found) - { - error_string = "This key is not self-signed. This is required by Retroshare." ; - std::cerr << "This key is not self-signed. This is required by Retroshare." << std::endl; - ops_validate_result_free(result); - return false ; - } - ops_validate_result_free(result); - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key read correctly: " << std::endl; - ops_keyring_list(tmp_keyring) ; -#endif - - int i=0 ; - - while( (keydata = ops_keyring_get_key_by_index(tmp_keyring,i++)) != NULL ) - if(locked_addOrMergeKey(_pubring,_public_keyring_map,keydata)) - { - _pubring_changed = true ; -#ifdef DEBUG_PGPHANDLER - std::cerr << " Added the key in the main public keyring." << std::endl; -#endif - } - else - std::cerr << "Key already in public keyring." << std::endl; - - if(tmp_keyring->nkeys > 0) - id = RsPgpId(tmp_keyring->keys[0].key_id) ; - else - return false ; - - ops_keyring_free(tmp_keyring) ; - free(tmp_keyring) ; - - _pubring_changed = true ; - - return true ; -} - -bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) -{ - bool ret = false ; - RsPgpId id(keydata->key_id) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "AddOrMergeKey():" << std::endl; - std::cerr << " id: " << id.toStdString() << std::endl; -#endif - - // See if the key is already in the keyring - const ops_keydata_t *existing_key = NULL; - std::map::const_iterator res = kmap.find(id) ; - - // Checks that - // - the key is referenced by keyid - // - the map is initialized - // - the fingerprint matches! - // - if(res == kmap.end() || (existing_key = ops_keyring_get_key_by_index(keyring,res->second._key_index)) == NULL) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key is new. Adding it to keyring" << std::endl; -#endif - addNewKeyToOPSKeyring(keyring,*keydata) ; // the key is new. - initCertificateInfo(kmap[id],keydata,keyring->nkeys-1) ; - existing_key = &(keyring->keys[keyring->nkeys-1]) ; - ret = true ; - } - else - { - if(memcmp( existing_key->fingerprint.fingerprint, - keydata->fingerprint.fingerprint, - RsPgpFingerprint::SIZE_IN_BYTES )) - { - std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << " Key exists. Merging signatures." << std::endl; -#endif - ret = mergeKeySignatures(const_cast(existing_key),keydata) ; - - if(ret) - initCertificateInfo(kmap[id],existing_key,res->second._key_index) ; - } - - if(ret) - { - validateAndUpdateSignatures(kmap[id],existing_key) ; - kmap[id]._time_stamp = time(NULL) ; - } - - return ret ; -} - -bool PGPHandler::encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - - std::string outfile_tmp = outfile + ".tmp" ; - - ops_create_info_t *info; - int fd = ops_setup_file_write(&info, outfile_tmp.c_str(), ops_true); - - if (fd < 0) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot write to " << outfile_tmp << std::endl; - return false ; - } - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: encryption failed." << std::endl; - return false ; - } - - ops_write(text.c_str(), text.length(), info); - ops_teardown_file_write(info, fd); - - if(!RsDirUtil::renameFile(outfile_tmp,outfile)) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: Cannot rename " + outfile_tmp + " to " + outfile + ". Disk error?" << std::endl; - return false ; - } - - return true ; -} - -bool PGPHandler::encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ; - - if(public_key == NULL) - { - std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl; - return false ; - } - - if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl; - return false ; - } - if(public_key->key.pkey.algorithm != OPS_PKA_RSA) - { - std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied key id " << key_id.toStdString() << " is not an RSA key (DSA for instance, is not supported)!" << std::endl; - return false ; - } - ops_create_info_t *info; - ops_memory_t *buf = NULL ; - ops_setup_memory_write(&info, &buf, 0); - bool res = true; - - if(!ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false)) - { - std::cerr << "Encryption failed." << std::endl; - res = false ; - } - - ops_write(data,len,info); - ops_writer_close(info); - ops_create_info_delete(info); - - int tlen = ops_memory_get_length(buf) ; - - if( (int)*encrypted_data_len >= tlen) - { - if(res) - { - memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ; - *encrypted_data_len = tlen ; - res = true ; - } - } - else - { - std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl; - res = false ; - } - - ops_memory_release(buf) ; - free(buf) ; - - return res ; -} - -bool PGPHandler::decryptDataBin(const RsPgpId& /*key_id*/,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len) -{ - int out_length ; - unsigned char *out ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ; - - if(*data_len < (unsigned int)out_length) - { - std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl; - return false ; - } - - *data_len = (unsigned int)out_length ; - memcpy(data,out,out_length) ; - free(out) ; - - return (bool)res ; -} - -bool PGPHandler::decryptTextFromFile(const RsPgpId&,std::string& text,const std::string& inputfile) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - unsigned char *out_buf = NULL ; - std::string buf ; - - FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"rb") ; - - if (f == NULL) - { - std::cerr << "Cannot open file " << inputfile << " for read." << std::endl; - return false; - } - - int c ; - while( (c = fgetc(f))!= EOF) - buf += (unsigned char)c; - - fclose(f) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler::decryptTextFromFile: read a file of length " << std::dec << buf.length() << std::endl; - std::cerr << "buf=\"" << buf << "\"" << std::endl; -#endif - - int out_length ; - ops_boolean_t res = ops_decrypt_memory((const unsigned char *)buf.c_str(),buf.length(),&out_buf,&out_length,_secring,ops_true,cb_get_passphrase) ; - - text = std::string((char *)out_buf,out_length) ; - free (out_buf); - return (bool)res ; -} - -bool PGPHandler::SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool use_raw_signature, std::string reason /* = "" */) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - // need to find the key and to decrypt it. - - const ops_keydata_t *key = locked_getSecretKey(id) ; - - if(!key) - { - std::cerr << "Cannot sign: no secret key with id " << id.toStdString() << std::endl; - return false ; - } - - std::string uid_hint ; - if(key->nuids > 0) - uid_hint = std::string((const char *)key->uids[0].user_id) ; - uid_hint += "(" + RsPgpId(key->key_id).toStdString()+")" ; - -#ifdef DEBUG_PGPHANDLER - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - PGPFingerprintType fp(f.fingerprint) ; -#endif - - bool last_passwd_was_wrong = false ; -ops_secret_key_t *secret_key = NULL ; - - for(int i=0;i<3;++i) - { - bool cancelled =false; - std::string passphrase = _passphrase_callback(NULL,reason.c_str(),uid_hint.c_str(),"Please enter passwd for encrypting your key : ",last_passwd_was_wrong,&cancelled) ;//TODO reason - - secret_key = ops_decrypt_secret_key_from_data(key,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key entering cancelled" << std::endl; - return false ; - } - if(secret_key) - break ; - - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - last_passwd_was_wrong = true ; - } - if(!secret_key) - { - std::cerr << "Could not obtain secret key. Signature cancelled." << std::endl; - return false ; - } - - // then do the signature. - - ops_boolean_t not_raw = !use_raw_signature ; -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA256,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#else - ops_memory_t *memres = ops_sign_buf(data,len,OPS_SIG_BINARY,OPS_HASH_SHA1,secret_key,ops_false,ops_false,not_raw,not_raw) ; -#endif - - if(!memres) - return false ; - - bool res ; - uint32_t slen = (uint32_t)ops_memory_get_length(memres); - - if(*signlen >= slen) - { - *signlen = slen ; - - memcpy(sign,ops_memory_get_data(memres),*signlen) ; - res = true ; - } - else - { - std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl; - res = false ; - } - - ops_memory_release(memres) ; - free(memres) ; - ops_secret_key_free(secret_key) ; - free(secret_key) ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Signed with fingerprint " << fp.toStdString() << ", length " << std::dec << *signlen << ", literal data length = " << len << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)data, len) ; - std::cerr << std::endl; - std::cerr << "Data: " << std::endl; - hexdump( (unsigned char *)sign,*signlen) ; - std::cerr << std::endl; -#endif - return res ; -} - -bool PGPHandler::privateSignCertificate(const RsPgpId& ownId,const RsPgpId& id_of_key_to_sign) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - ops_keydata_t *key_to_sign = const_cast(locked_getPublicKey(id_of_key_to_sign,true)) ; - - if(key_to_sign == NULL) - { - std::cerr << "Cannot sign: no public key with id " << id_of_key_to_sign.toStdString() << std::endl; - return false ; - } - - // 1 - get decrypted secret key - // - const ops_keydata_t *skey = locked_getSecretKey(ownId) ; - - if(!skey) - { - std::cerr << "Cannot sign: no secret key with id " << ownId.toStdString() << std::endl; - return false ; - } - const ops_keydata_t *pkey = locked_getPublicKey(ownId,true) ; - - if(!pkey) - { - std::cerr << "Cannot sign: no public key with id " << ownId.toStdString() << std::endl; - return false ; - } - - bool cancelled = false; - std::string passphrase = _passphrase_callback(NULL,"",RsPgpId(skey->key_id).toStdString().c_str(),"Please enter passwd for encrypting your key : ",false,&cancelled) ; - - ops_secret_key_t *secret_key = ops_decrypt_secret_key_from_data(skey,passphrase.c_str()) ; - - if(cancelled) - { - std::cerr << "Key cancelled by used." << std::endl; - return false ; - } - if(!secret_key) - { - std::cerr << "Key decryption went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 2 - then do the signature. - - if(!ops_sign_key(key_to_sign,pkey->key_id,secret_key)) - { - std::cerr << "Key signature went wrong. Wrong passwd?" << std::endl; - return false ; - } - - // 3 - free memory - // - ops_secret_key_free(secret_key) ; - free(secret_key) ; - - _pubring_changed = true ; - - // 4 - update signatures. - // - PGPCertificateInfo& cert(_public_keyring_map[ id_of_key_to_sign ]) ; - validateAndUpdateSignatures(cert,key_to_sign) ; - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; - - return true ; -} - -void PGPHandler::updateOwnSignatureFlag(const RsPgpId& own_id) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - if(_public_keyring_map.find(own_id)==_public_keyring_map.end()) - { - std::cerr << __func__ << ": key with id=" << own_id.toStdString() << " not in keyring." << std::endl; - // return now, because the following operation would add an entry to _public_keyring_map - return; - } - - PGPCertificateInfo& own_cert(_public_keyring_map[ own_id ]) ; - - for(std::map::iterator it=_public_keyring_map.begin();it!=_public_keyring_map.end();++it) - locked_updateOwnSignatureFlag(it->second,it->first,own_cert,own_id) ; -} -void PGPHandler::updateOwnSignatureFlag(const RsPgpId& cert_id,const RsPgpId& own_id) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - std::map::iterator it( _public_keyring_map.find(cert_id) ) ; - - if(it == _public_keyring_map.end()) - { - std::cerr << "updateOwnSignatureFlag: Cannot get certificate for string " << cert_id.toStdString() << ". This is probably a bug." << std::endl; - return ; - } - - PGPCertificateInfo& cert( it->second ); - - PGPCertificateInfo& own_cert(_public_keyring_map[ own_id ]) ; - - locked_updateOwnSignatureFlag(cert,cert_id,own_cert,own_id) ; -} -void PGPHandler::locked_updateOwnSignatureFlag(PGPCertificateInfo& cert,const RsPgpId& cert_id,PGPCertificateInfo& own_cert,const RsPgpId& own_id_str) -{ - if(cert.signers.find(own_id_str) != cert.signers.end()) - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; - else - cert._flags &= ~PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; - - if(own_cert.signers.find( cert_id ) != own_cert.signers.end()) - cert._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME ; - else - cert._flags &= ~PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME ; -} - -/*static*/ RsPgpId PGPHandler::pgpIdFromFingerprint(const RsPgpFingerprint& f) -{ - return RsPgpId::fromBufferUnsafe( - f.toByteArray() + - RsPgpFingerprint::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES ); -} - -bool PGPHandler::getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const -{ - RS_STACK_MUTEX(pgphandlerMtx); - - const ops_keydata_t *key = locked_getPublicKey(id,false) ; - - if(!key) return false; - - ops_fingerprint_t f ; - ops_fingerprint(&f,&key->key.pkey) ; - - fp = RsPgpFingerprint::fromBufferUnsafe(f.fingerprint); - - return true ; -} - -bool PGPHandler::VerifySignBin(const void *literal_data, uint32_t literal_data_length, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& key_fingerprint) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - RsPgpId id = RsPgpId(key_fingerprint.toByteArray() + PGPFingerprintType::SIZE_IN_BYTES - RsPgpId::SIZE_IN_BYTES) ; - const ops_keydata_t *key = locked_getPublicKey(id,true) ; - - if(key == NULL) - { - std::cerr << "No key returned by fingerprint " << key_fingerprint.toStdString() << ", and ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - - // Check that fingerprint is the same. - const ops_public_key_t *pkey = &key->key.pkey ; - ops_fingerprint_t fp ; - ops_fingerprint(&fp,pkey) ; - - if(key_fingerprint != PGPFingerprintType(fp.fingerprint)) - { - std::cerr << "Key fingerprint does not match " << key_fingerprint.toStdString() << ", for ID " << id.toStdString() << ", signature verification failed!" << std::endl; - return false ; - } - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Verifying signature from fingerprint " << key_fingerprint.toStdString() << ", length " << std::dec << sign_len << ", literal data length = " << literal_data_length << std::endl; - std::cerr << "Signature body: " << std::endl; - hexdump( (unsigned char *)sign,sign_len) ; - std::cerr << std::endl; - std::cerr << "Signed data: " << std::endl; - hexdump( (unsigned char *)literal_data, literal_data_length) ; - std::cerr << std::endl; -#endif - - return ops_validate_detached_signature(literal_data,literal_data_length,sign,sign_len,key) ; -} - -void PGPHandler::setAcceptConnexion(const RsPgpId& id,bool b) -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - - std::map::iterator res = _public_keyring_map.find(id) ; - - if(res != _public_keyring_map.end()) - { - if(b) - res->second._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; - else - res->second._flags &= ~PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; - } -} - -bool PGPHandler::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) const -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP directory. - list.clear() ; - - for(std::map::const_iterator it(_public_keyring_map.begin());it!=_public_keyring_map.end();++it) - if( filter == NULL || (*filter)(it->second) ) - list.push_back(RsPgpId(it->first)) ; - - return true ; -} - -bool PGPHandler::isPgpPubKeyAvailable(const RsPgpId &id) -{ return _public_keyring_map.find(id) != _public_keyring_map.end(); } - -bool PGPHandler::isGPGId(const RsPgpId &id) -{ - return _public_keyring_map.find(id) != _public_keyring_map.end() ; -} - -bool PGPHandler::isGPGSigned(const RsPgpId &id) -{ - std::map::const_iterator res = _public_keyring_map.find(id) ; - return res != _public_keyring_map.end() && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) ; -} - -bool PGPHandler::isGPGAccepted(const RsPgpId &id) -{ - std::map::const_iterator res = _public_keyring_map.find(id) ; - return (res != _public_keyring_map.end()) && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION) ; -} - -// Lexicographic order on signature packets -// -bool operator<(const ops_packet_t& p1,const ops_packet_t& p2) -{ - if(p1.length < p2.length) - return true ; - if(p1.length > p2.length) - return false ; - - for(uint32_t i=0;i p2.raw[i]) - return false ; - } - return false ; -} - -bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) -{ - // First sort all signatures into lists to see which is new, which is not new - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging signatures for key " << RsPgpId(dst->key_id).toStdString() << std::endl; -#endif - std::set dst_packets ; - - for(uint32_t i=0;inpackets;++i) dst_packets.insert(dst->packets[i]) ; - - std::set to_add ; - - for(uint32_t i=0;inpackets;++i) - if(dst_packets.find(src->packets[i]) == dst_packets.end()) - { - uint8_t tag ; - uint32_t length ; - unsigned char *tmp_data = src->packets[i].raw ; // put it in a tmp variable because read_packetHeader() will modify it!! - - PGPKeyParser::read_packetHeader(tmp_data,tag,length) ; - - if(tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) - to_add.insert(src->packets[i]) ; -#ifdef DEBUG_PGPHANDLER - else - std::cerr << " Packet with tag 0x" << std::hex << (int)(src->packets[i].raw[0]) << std::dec << " not merged, because it is not a signature." << std::endl; -#endif - } - - for(std::set::const_iterator it(to_add.begin());it!=to_add.end();++it) - { -#ifdef DEBUG_PGPHANDLER - std::cerr << " Adding packet with tag 0x" << std::hex << (int)(*it).raw[0] << std::dec << std::endl; -#endif - ops_add_packet_to_keydata(dst,&*it) ; - } - return to_add.size() > 0 ; -} - -bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) -{ - PGPSignatureInfo info ; - - if(!PGPKeyManagement::parseSignature(sign,signlen,info)) - return false ; - - unsigned char bytes[8] ; - for(int i=0;i<8;++i) - { - bytes[7-i] = info.issuer & 0xff ; - info.issuer >>= 8 ; - } - issuer_id = RsPgpId(bytes) ; - - return true ; -} - -bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl) -{ - if(trustlvl < 0 || trustlvl >= 6 || trustlvl == 1) - { - std::cerr << "Invalid trust level " << trustlvl << " passed to privateTrustCertificate." << std::endl; - return false ; - } - - std::map::iterator it = _public_keyring_map.find(id); - - if(it == _public_keyring_map.end()) - { - std::cerr << "(EE) Key id " << id.toStdString() << " not in the keyring. Can't setup trust level." << std::endl; - return false ; - } - - if( (int)it->second._trustLvl != trustlvl ) - _trustdb_changed = true ; - - it->second._trustLvl = trustlvl ; - - return true ; -} - -struct PrivateTrustPacket -{ - /// pgp id in unsigned char format. - unsigned char user_id[RsPgpId::SIZE_IN_BYTES]; - uint8_t trust_level ; // trust level. From 0 to 6. - uint32_t time_stamp ; // last time the cert was ever used, in seconds since the epoch. 0 means not initialized. -}; - -void PGPHandler::locked_readPrivateTrustDatabase() -{ - FILE *fdb = RsDirUtil::rs_fopen(_trustdb_path.c_str(),"rb") ; -#ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler: Reading private trust database." << std::endl; -#endif - - if(fdb == NULL) - { - std::cerr << " private trust database not found. No trust info loaded." << std::endl ; - return ; - } - std::map::iterator it ; - PrivateTrustPacket trustpacket; - int n_packets = 0 ; - - while(fread((void*)&trustpacket,sizeof(PrivateTrustPacket),1,fdb) == 1) - { - it = _public_keyring_map.find(RsPgpId(trustpacket.user_id)) ; - - if(it == _public_keyring_map.end()) - { - std::cerr << " (WW) Trust packet found for unknown key id " << RsPgpId(trustpacket.user_id).toStdString() << std::endl; - continue ; - } - if(trustpacket.trust_level > 6) - { - std::cerr << " (WW) Trust packet found with unexpected trust level " << trustpacket.trust_level << std::endl; - continue ; - } - - ++n_packets ; - it->second._trustLvl = trustpacket.trust_level ; - - if(trustpacket.time_stamp > it->second._time_stamp) // only update time stamp if the loaded time stamp is newer - it->second._time_stamp = trustpacket.time_stamp ; - } - - fclose(fdb) ; - - std::cerr << "PGPHandler: Successfully read " << std::hex << n_packets << std::dec << " trust packets." << std::endl; -} - -bool PGPHandler::locked_writePrivateTrustDatabase() -{ - FILE *fdb = RsDirUtil::rs_fopen((_trustdb_path+".tmp").c_str(),"wb") ; -#ifdef DEBUG_PGPHANDLER - std::cerr << "PGPHandler: Reading private trust database." << std::endl; -#endif - - if(fdb == NULL) - { - std::cerr << " (EE) Can't open private trust database file " << _trustdb_path << " for write. Giving up!" << std::endl ; - return false; - } - PrivateTrustPacket trustpacket ; - /* Clear PrivateTrustPacket struct to suppress valgrind warnings due to the compiler extra padding*/ - memset(&trustpacket, 0, sizeof(PrivateTrustPacket)); - - for( std::map::iterator it = - _public_keyring_map.begin(); it!=_public_keyring_map.end(); ++it ) - { - memcpy( trustpacket.user_id, - it->first.toByteArray(), - RsPgpId::SIZE_IN_BYTES ); - trustpacket.trust_level = it->second._trustLvl ; - trustpacket.time_stamp = it->second._time_stamp ; - - if(fwrite((void*)&trustpacket,sizeof(PrivateTrustPacket),1,fdb) != 1) - { - std::cerr << " (EE) Cannot write to trust database " << _trustdb_path << ". Disc full, or quota exceeded ? Leaving database untouched." << std::endl; - fclose(fdb) ; - return false; - } - } - - fclose(fdb) ; - - if(!RsDirUtil::renameFile(_trustdb_path+".tmp",_trustdb_path)) - { - std::cerr << " (EE) Cannot move temp file " << _trustdb_path+".tmp" << ". Bad write permissions?" << std::endl; - return false ; - } - else - return true ; -} - -bool PGPHandler::syncDatabase() -{ - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Sync-ing keyrings." << std::endl; -#endif - locked_syncPublicKeyring() ; - //locked_syncSecretKeyring() ; - - // Now sync the trust database as well. - // - locked_syncTrustDatabase() ; - -#ifdef DEBUG_PGPHANDLER - std::cerr << "Done. " << std::endl; -#endif - return true ; -} - -bool PGPHandler::locked_syncPublicKeyring() -{ - struct stat64 buf ; -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(_pubring_path, wfullname); - if(-1 == _wstati64(wfullname.c_str(), &buf)) -#else - if(-1 == stat64(_pubring_path.c_str(), &buf)) -#endif - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _pubring_path << ". Can't sync public keyring." << std::endl; - - if(_pubring_last_update_time < buf.st_mtime) - { - std::cerr << "Detected change on disk of public keyring. Merging!" << std::endl ; - - locked_mergeKeyringFromDisk(_pubring,_public_keyring_map,_pubring_path) ; - _pubring_last_update_time = buf.st_mtime ; - } - - // Now check if the pubring was locally modified, which needs saving it again - if(_pubring_changed && RsDiscSpace::checkForDiscSpace(RS_PGP_DIRECTORY)) - { - std::string tmp_keyring_file = _pubring_path + ".tmp" ; - - std::cerr << "Local changes in public keyring. Writing to disk..." << std::endl; - if(!ops_write_keyring_to_file(_pubring,ops_false,tmp_keyring_file.c_str(),ops_true)) - { - std::cerr << "Cannot write public keyring tmp file. Disk full? Disk quota exceeded?" << std::endl; - return false ; - } - if(!RsDirUtil::renameFile(tmp_keyring_file,_pubring_path)) - { - std::cerr << "Cannot rename tmp pubring file " << tmp_keyring_file << " into actual pubring file " << _pubring_path << ". Check writing permissions?!?" << std::endl; - return false ; - } - - std::cerr << "Done." << std::endl; - _pubring_last_update_time = time(NULL) ; // should we get this value from the disk instead?? - _pubring_changed = false ; - } - return true ; -} - -bool PGPHandler::locked_syncTrustDatabase() -{ - struct stat64 buf ; -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(_trustdb_path, wfullname); - if(-1 == _wstati64(wfullname.c_str(), &buf)) -#else - if(-1 == stat64(_trustdb_path.c_str(), &buf)) -#endif - { - std::cerr << "PGPHandler::syncDatabase(): can't stat file " << _trustdb_path << ". Will force write it." << std::endl; - _trustdb_changed = true ; // we force write of trust database if it does not exist. - } - - if(_trustdb_last_update_time < buf.st_mtime) - { - std::cerr << "Detected change on disk of trust database. " << std::endl ; - - locked_readPrivateTrustDatabase(); - _trustdb_last_update_time = time(NULL) ; - } - - if(_trustdb_changed) - { - std::cerr << "Local changes in trust database. Writing to disk..." << std::endl; - if(!locked_writePrivateTrustDatabase()) - std::cerr << "Cannot write trust database. Disk full? Disk quota exceeded?" << std::endl; - else - { - std::cerr << "Done." << std::endl; - _trustdb_last_update_time = time(NULL) ; - _trustdb_changed = false ; - } - } - return true ; -} -void PGPHandler::locked_mergeKeyringFromDisk( ops_keyring_t *keyring, - std::map& kmap, - const std::string& keyring_file) -{ -#ifdef DEBUG_PGPHANDLER - std::cerr << "Merging keyring " << keyring_file << " from disk to memory." << std::endl; -#endif - - // 1 - load keyring into a temporary keyring list. - ops_keyring_t *tmp_keyring = PGPHandler::allocateOPSKeyring() ; - - if(ops_false == ops_keyring_read_from_file(tmp_keyring, false, keyring_file.c_str())) - { - std::cerr << "PGPHandler::locked_mergeKeyringFromDisk(): cannot read keyring. File corrupted?" ; - ops_keyring_free(tmp_keyring) ; - return ; - } - - // 2 - load new keys and merge existing key signatures - - for(int i=0;inkeys;++i) - locked_addOrMergeKey(keyring,kmap,&tmp_keyring->keys[i]) ;// we dont' account for the return value. This is disk merging, not local changes. - - // 4 - clean - ops_keyring_free(tmp_keyring) ; -} - -bool PGPHandler::removeKeysFromPGPKeyring(const std::set& keys_to_remove,std::string& backup_file,uint32_t& error_code) -{ - // 1 - lock everything. - // - RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures. - RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. - - error_code = PGP_KEYRING_REMOVAL_ERROR_NO_ERROR ; - - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key! Operation cancelled." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS ; - return false ; - } - - // 2 - sync everything. - // - locked_syncPublicKeyring() ; - - // 3 - make a backup of the public keyring - // - char template_name[_pubring_path.length()+8] ; - sprintf(template_name,"%s.XXXXXX",_pubring_path.c_str()) ; - -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - int fd_keyring_backup(mkstemp(template_name)); - if (fd_keyring_backup == -1) -#else - if(mktemp(template_name) == NULL) -#endif - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot create keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP ; - return false ; - } -#if defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8 - close(fd_keyring_backup); // TODO: keep the file open and use the fd -#endif - - if(!ops_write_keyring_to_file(_pubring,ops_false,template_name,ops_true)) - { - std::cerr << "PGPHandler::removeKeysFromPGPKeyring(): cannot write keyring backup file. Giving up." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP ; - return false ; - } - backup_file = std::string(template_name,_pubring_path.length()+7) ; - - std::cerr << "Keyring was backed up to file " << backup_file << std::endl; - - // Remove keys from the keyring, and update the keyring map. - // - for(std::set::const_iterator it(keys_to_remove.begin());it!=keys_to_remove.end();++it) - { - if(locked_getSecretKey(*it) != NULL) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " since its shared by a secret key!" << std::endl; - continue ; - } - - std::map::iterator res = _public_keyring_map.find(*it) ; - - if(res == _public_keyring_map.end()) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << " from keyring: key not found." << std::endl; - continue ; - } - - if(res->second._key_index >= (unsigned int)_pubring->nkeys || RsPgpId(_pubring->keys[res->second._key_index].key_id) != *it) - { - std::cerr << "(EE) PGPHandler:: can't remove key " << (*it).toStdString() << ". Inconsistency found." << std::endl; - error_code = PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY ; - return false ; - } - - // Move the last key to the freed place. This deletes the key in place. - // - ops_keyring_remove_key(_pubring,res->second._key_index) ; - - // Erase the info from the keyring map. - // - _public_keyring_map.erase(res) ; - - // now update all indices back. This internal look is very costly, but it avoids deleting the wrong keys, since the keyring structure is - // changed by ops_keyring_remove_key and therefore indices don't point to the correct location anymore. - - int i=0 ; - const ops_keydata_t *keydata ; - while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) - { - PGPCertificateInfo& cert(_public_keyring_map[ RsPgpId(keydata->key_id) ]) ; - cert._key_index = i ; - ++i ; - } - } - - // Everything went well, sync back the keyring on disk - - _pubring_changed = true ; - _trustdb_changed = true ; - - locked_syncPublicKeyring() ; - locked_syncTrustDatabase() ; - - return true ; -} diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h deleted file mode 100644 index 5d7eb82f8..000000000 --- a/libretroshare/src/pgp/pgphandler.h +++ /dev/null @@ -1,259 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: pgphandler.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include -#include -#include -} - -typedef std::string (*PassphraseCallback)(void *data, const char *uid_title, const char *uid_hint, const char *passphrase_info, int prev_was_bad,bool *cancelled) ; - -class PGPCertificateInfo -{ - public: - PGPCertificateInfo() : _trustLvl(0), _validLvl(0), _flags(0), _type(0), _time_stamp(0), _key_index(0) {} - - std::string _name; - std::string _email; - std::string _comment; - - std::set signers; - - uint32_t _trustLvl; - uint32_t _validLvl; - uint32_t _flags ; - uint32_t _type ; - - mutable rstime_t _time_stamp ; // last time the key was used (received, used for signature verification, etc) - - PGPFingerprintType _fpr; /* fingerprint */ - // RsPgpId _key_id ; - - uint32_t _key_index ; // index to array of keys in the public keyring - - static const uint32_t PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION = 0x0001 ; - static const uint32_t PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE = 0x0002 ; - static const uint32_t PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME = 0x0004 ; - static const uint32_t PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM = 0x0008 ; // set when the key is not RSA, so that RS avoids to use it. - - static const uint8_t PGP_CERTIFICATE_TRUST_UNDEFINED = 0x00 ; - static const uint8_t PGP_CERTIFICATE_TRUST_NEVER = 0x02 ; - static const uint8_t PGP_CERTIFICATE_TRUST_MARGINALLY = 0x03 ; - static const uint8_t PGP_CERTIFICATE_TRUST_FULLY = 0x04 ; - static const uint8_t PGP_CERTIFICATE_TRUST_ULTIMATE = 0x05 ; - - static const uint8_t PGP_CERTIFICATE_TYPE_UNKNOWN = 0x00 ; - static const uint8_t PGP_CERTIFICATE_TYPE_DSA = 0x01 ; - static const uint8_t PGP_CERTIFICATE_TYPE_RSA = 0x02 ; -}; - -/// This class offer an abstract pgp handler to be used in RetroShare. -class PGPHandler -{ -public: - PGPHandler( const std::string& path_to_public_keyring, - const std::string& path_to_secret_keyring, - const std::string& path_to_trust_database, - const std::string& pgp_lock_file) ; - - virtual ~PGPHandler() ; - - /** - * @param ids list of gpg certificate ids (note, not the actual certificates) - */ - bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) const ; - bool haveSecretKey(const RsPgpId& id) const ; - - bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) ; - bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ; - bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_id) const ; - bool exportGPGKeyPairToString( - std::string& data, const RsPgpId& exportedKeyId, - bool includeSignatures, std::string& errorMsg ) const; - - bool availableGPGCertificatesWithPrivateKeys(std::list& ids); - bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ; - - bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string); - bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string); - - std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ; - - /** The caller is in charge of freeing `mem` once finished */ - bool exportPublicKey( const RsPgpId& id, - unsigned char*& mem, size_t& mem_size, - bool armoured, bool include_signatures) const; - - bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ; - bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") ; - bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ; - bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) ; - - // The client should supply a memory chunk to store the data. The length will be updated to the real length of the data. - // - bool encryptDataBin(const RsPgpId& key_id,const void *data, const uint32_t len - , unsigned char *encrypted_data, unsigned int *encrypted_data_len) ; - bool decryptDataBin(const RsPgpId& key_id,const void *encrypted_data, const uint32_t encrypted_len - , unsigned char *data, unsigned int *data_len) ; - - bool encryptTextToFile(const RsPgpId& key_id,const std::string& text,const std::string& outfile) ; - bool decryptTextFromFile(const RsPgpId& key_id,std::string& text,const std::string& encrypted_inputfile) ; - - void setAcceptConnexion(const RsPgpId&,bool) ; - - void updateOwnSignatureFlag(const RsPgpId& ownId) ; - void updateOwnSignatureFlag(const RsPgpId& pgp_id,const RsPgpId& ownId) ; - - void locked_updateOwnSignatureFlag(PGPCertificateInfo&, const RsPgpId&, PGPCertificateInfo&, const RsPgpId&) ; - - // Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated - // and given pack for proper display. - // - bool removeKeysFromPGPKeyring(const std::set& key_ids,std::string& backup_file,uint32_t& error_code) ; - - //bool isKeySupported(const RsPgpId& id) const ; - - bool privateTrustCertificate(const RsPgpId& id,int valid_level) ; - - // Write keyring - - //bool writeSecretKeyring() ; - //bool writePublicKeyring() ; - - const PGPCertificateInfo *getCertificateInfo(const RsPgpId& id) const ; - - RS_DEPRECATED_FOR(isPgpPubKeyAvailable) - bool isGPGId(const RsPgpId &id); - bool isGPGSigned(const RsPgpId &id); - bool isGPGAccepted(const RsPgpId &id); - - static void setPassphraseCallback(PassphraseCallback cb) ; - static PassphraseCallback passphraseCallback() { return _passphrase_callback ; } - - /** - * @brief Check if a PGP publick key is available - * @param id id of the key to check - * @return true if the public key for the given id is available, - * false otherwise - */ - bool isPgpPubKeyAvailable(const RsPgpId& id); - - /** - * @brief Convert PGP fingerprint to PGP 64bit id - * @param f PGP fingerprint to convert - * @return PGP 64bit id extracted from fingerprint - */ - static RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& f); - - /** - * @brief Get PGP fingerprint for the given key - * @param id PGP 64bit key id - * @param fp storage for the retrived key fingerpring, the contained value - * is meaningfull only if true is returned - * @return true if the key was found, false if not - */ - bool getKeyFingerprint(const RsPgpId& id, RsPgpFingerprint& fp) const; - - // Gets info about the key. Who are the signers, what's the owner's name, etc. - // - bool getGPGDetailsFromBinaryBlock(const unsigned char *mem,size_t mem_size,RsPgpId& key_id, std::string& name, std::list& signers) const ; - - // Debug stuff. - virtual bool printKeys() const ; - - // Syncs the keyrings and trust database between memory and disk. The algorithm is: - // 1 - lock the keyrings - // 2 - compare file modification dates with last writing date - // - if file is modified, load it, and merge with memory - // 3 - look into memory modification flags - // - if flag says keyring has changed, write to disk - // - bool syncDatabase() ; - - private: - bool LoadCertificate(const unsigned char *bin_data,uint32_t bin_data_len, bool armoured, RsPgpId& gpg_id, std::string& error_string); - void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; - - // Returns true if the signatures have been updated - // - bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ; - - /** Check public/private key and import them into the keyring - * @param keyring keyring with the new public/private key pair. Will be freed by the function. - * @param imported_key_id PGP id of the imported key - * @param import_error human readbale error message - * @returns true on success - * */ - bool checkAndImportKeyPair(ops_keyring_t *keyring, RsPgpId& imported_key_id,std::string& import_error); - - const ops_keydata_t *locked_getPublicKey(const RsPgpId&,bool stamp_the_key) const; - const ops_keydata_t *locked_getSecretKey(const RsPgpId&) const ; - - void locked_readPrivateTrustDatabase() ; - bool locked_writePrivateTrustDatabase() ; - - bool locked_syncPublicKeyring() ; - bool locked_syncTrustDatabase() ; - - void locked_mergeKeyringFromDisk(ops_keyring_t *keyring, std::map& kmap, const std::string& keyring_file) ; - bool locked_addOrMergeKey(ops_keyring_t *keyring,std::map& kmap,const ops_keydata_t *keydata) ; - - // Members. - // - mutable RsMutex pgphandlerMtx ; - - ops_keyring_t *_pubring ; - ops_keyring_t *_secring ; - - std::map _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring. - std::map _secret_keyring_map ; - - const std::string _pubring_path ; - const std::string _secring_path ; - const std::string _trustdb_path ; - const std::string _pgp_lock_filename ; - - bool _pubring_changed ; - mutable bool _trustdb_changed ; - - rstime_t _pubring_last_update_time ; - rstime_t _secring_last_update_time ; - rstime_t _trustdb_last_update_time ; - - // Helper functions. - // - static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key,bool include_signatures) ; - static ops_keyring_t *allocateOPSKeyring() ; - static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; - static PassphraseCallback _passphrase_callback ; - static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different -}; diff --git a/libretroshare/src/pgp/pgpkeyutil.cc b/libretroshare/src/pgp/pgpkeyutil.cc deleted file mode 100644 index 76b332edf..000000000 --- a/libretroshare/src/pgp/pgpkeyutil.cc +++ /dev/null @@ -1,373 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: pgpkeyutil.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include "pgpkeyutil.h" - -#include -#include - -/****************************/ -/* #define DEBUG_PGPUTIL 1 */ -/****************************/ - -#define PGP_CRC24_INIT 0xB704CEL -#define PGP_CRC24_POLY 0x1864CFBL - -#define PGP_CERTIFICATE_START_STRING "-----BEGIN PGP PUBLIC KEY BLOCK-----" -#define PGP_CERTIFICATE_END_STRING "-----END PGP PUBLIC KEY BLOCK-----" -// -// All size are big endian -// MPI: 2 bytes size (length in bits) + string of octets -// -bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std::string& cleaned_certificate) -{ - try - { - // 0 - Extract Radix64 portion of the certificate - // - std::string version_string ; - std::string radix_cert = PGPKeyParser::extractRadixPartFromArmouredKey(pgp_certificate,version_string) ; - - // 1 - Convert armored key into binary key - // - std::vector keydata = Radix64::decode(radix_cert) ; - - size_t new_len ; - findLengthOfMinimalKey(keydata.data(), keydata.size(), new_len) ; - - cleaned_certificate = makeArmouredKey(keydata.data(), new_len, version_string) ; - return true ; - } - catch(std::exception& e) - { - cleaned_certificate = "" ; - std::cerr << "Certificate cleaning failed: " << e.what() << std::endl; - return false ; - } -} - -void PGPKeyManagement::findLengthOfMinimalKey(const unsigned char *keydata,size_t len,size_t& new_len) -{ - unsigned char *data = (unsigned char *)keydata ; - -#ifdef DEBUG_PGPUTIL - std::cerr << "Total size: " << len << std::endl; -#endif - - uint8_t packet_tag; - uint32_t packet_length ; - - // 2 - parse key data, only keep public key data, user id and self-signature. - - bool public_key=false ; - bool own_signature=false ; - bool user_id=false ; - - while(true) - { - PGPKeyParser::read_packetHeader(data,packet_tag,packet_length) ; -#ifdef DEBUG_PGPUTIL - std::cerr << "Header:" << std::endl; - std::cerr << " Packet tag: " << (int)packet_tag << std::endl; - std::cerr << " Packet length: " << packet_length << std::endl; -#endif - - data += packet_length ; - - if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_PUBLIC_KEY) - public_key = true ; - if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_USER_ID) - user_id = true ; - if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE) - own_signature = true ; - - if(public_key && own_signature && user_id) - break ; - - if( (uint64_t)data - (uint64_t)keydata >= len ) - break ; - } - - new_len = (uint64_t)data - (uint64_t)keydata ; -} - -std::string PGPKeyParser::extractRadixPartFromArmouredKey(const std::string& pgp_certificate,std::string& version_string) -{ - int n = pgp_certificate.length() ; - int i=0 ; - version_string = "" ; - - while(i < n && pgp_certificate[i] != '\n') ++i ; // remove first part -----BEGIN PGP CERTIFICATE----- - ++i ; - while(i < n && pgp_certificate[i] != '\n') version_string += pgp_certificate[i++] ; // remove first part Version: [fdfdfdf] - ++i ; - while(i < n && pgp_certificate[i] != '\n') ++i ; // remove blank line - - ++i ; - - int j=n-1 ; - - while(j>0 && pgp_certificate[j] != '=' && j>=i) --j ; - - std::string radix_cert = pgp_certificate.substr(i,j-i) ; - -#ifdef DEBUG_PGPUTIL - std::cerr << "extracted radix cert: " << std::endl; - std::cerr << radix_cert ; -#endif - return radix_cert ; -} - - -std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string) -{ - std::string outstring ; - Radix64::encode(keydata,key_size,outstring) ; - - uint32_t crc = compute24bitsCRC((unsigned char *)keydata,key_size) ; - - unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ; - std::string crc_string ; - Radix64::encode(tmp,3,crc_string) ; - -#ifdef DEBUG_PGPUTIL - std::cerr << "After signature pruning: " << std::endl; - std::cerr << outstring << std::endl; -#endif - - std::string certificate = std::string(PGP_CERTIFICATE_START_STRING) + "\n" + version_string + "\n\n" ; - - for(uint32_t i=0;i= hashed_size ) - break ; - } - // non hashed sub-packets are ignored for now. - - return issuer_found ; -} - -uint64_t PGPKeyParser::read_KeyID(unsigned char *& data) -{ - uint64_t val = 0 ; - - val |= uint64_t( *data ) << 56 ; ++data ; - val |= uint64_t( *data ) << 48 ; ++data ; - val |= uint64_t( *data ) << 40 ; ++data ; - val |= uint64_t( *data ) << 32 ; ++data ; - val |= uint64_t( *data ) << 24 ; ++data ; - val |= uint64_t( *data ) << 16 ; ++data ; - val |= uint64_t( *data ) << 8 ; ++data ; - val |= uint64_t( *data ) << 0 ; ++data ; - - return val ; -} - -uint32_t PGPKeyParser::write_125Size(unsigned char *data,uint32_t size) -{ - if(size < 192)//192 To know if size is coded with One Char < 0xC0 - { - data[0] = size ; - return 1; - } - - if(size < 8384)//8384 To know if size is coded with Two Chars < 0xE0. See RFC4880 - { - data[1] = (size - 192) & 0xFF ;//Warning data[1] could be "negative", recode it using 8bits type - data[0] = ((size - 192 - data[1]) >> 8) + 192 ; - - return 2 ; - } - - data[0] = 0xFF ; //Else size is coded with 4 Chars + 1 at 0xFF - data[1] = (size >> 24) & 0xFF ; - data[2] = (size >> 16) & 0xFF ; - data[3] = (size >> 8) & 0xFF ; - data[4] = (size ) & 0xFF ; - - return 5 ; -} - -uint32_t PGPKeyParser::read_125Size(unsigned char *& data) -{ - uint8_t b1 = *data ; - ++data ; - - if (b1 < 192) //192 Size is coded with One Char. See RFC4880 https://tools.ietf.org/html/rfc4880#section-4.2.2.1 - return b1 ; - - uint8_t b2 = *data ; - ++data ; - - if (b1 < 224)//224 = 0xC0+0x20 Size is coded with Two Chars - return ( (b1-192) << 8 ) + b2 + 192 ; // see RFC4880 - - if(b1 != 0xFF)// Else Coded with 4 Chars but first == 0xFF - throw std::runtime_error("GPG parsing error") ; - - uint8_t b3 = *data ; ++data ; - uint8_t b4 = *data ; ++data ; - uint8_t b5 = *data ; ++data ; - - return (b2 << 24) | (b3 << 16) | (b4 << 8) | b5 ; -} - -uint32_t PGPKeyParser::read_partialBodyLength(unsigned char *& data) -{ - uint8_t b1 =*data ; - ++data ; - - return 1 << (b1 & 0x1F) ; -} - - -void PGPKeyParser::read_packetHeader(unsigned char *& data,uint8_t& packet_tag,uint32_t& packet_length) -{ - uint8_t b1 = *data ; - ++data ; - - bool new_format = b1 & 0x40 ; - - if(new_format) - { -#ifdef DEBUG_PGPUTIL - std::cerr << "Packet is in new format" << std::endl; -#endif - packet_tag = b1 & 0x3f ; - packet_length = read_125Size(data) ; - } - else - { -#ifdef DEBUG_PGPUTIL - std::cerr << "Packet is in old format" << std::endl; -#endif - uint8_t length_type = b1 & 0x03 ; - packet_tag = (b1 & 0x3c) >> 2 ; - - int length_size ; - switch(length_type) - { - case 0: length_size = 1 ; - break ; - case 1: length_size = 2 ; - break ; - case 2: length_size = 4 ; - break ; - default: - throw std::runtime_error("Unhandled length type!") ; - } - - packet_length = 0 ; - for(int k=0;k * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -// refer to RFC4880 specif document for loading GPG public keys: -// -// 11.1: transferable public keys -// Global structure of transferable public keys -// -// - one public key packet (see 12.2) -// - zero or more revocation signatures (See signature type 5.2.1 for key signature types) -// -// - user certification signatures (0x10 or 0x13) -// -// - 5.2.2: Signature format packet -// - 5.2.3.1: signature subpacket specification -// -// - 4.3: packet tags (1 byte) - -#pragma once - -#include -#include - -static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN = 0 ; -static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_MD5 = 1 ; -static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA1 = 2 ; -static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA256 = 8 ; -static const uint8_t PGP_PACKET_TAG_HASH_ALGORITHM_SHA512 = 10 ; - -static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN = 0 ; -static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES = 1 ; -static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E = 2 ; -static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S = 3 ; -static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA = 17 ; - -static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN = 0 ; -static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V3 = 3 ; -static const uint8_t PGP_PACKET_TAG_SIGNATURE_VERSION_V4 = 4 ; - -static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN = 0xff ; -static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT = 0x00 ; -static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT = 0x01 ; -static const uint8_t PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG = 0x02 ; -// All other consts for signature types not used, so not defines. - -class PGPSignatureInfo -{ -public: - PGPSignatureInfo() : - signature_version (PGP_PACKET_TAG_SIGNATURE_VERSION_UNKNOWN), - signature_type (PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN), - issuer (0), - public_key_algorithm(PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN), - hash_algorithm (PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN) - {} - - uint8_t signature_version ; - uint8_t signature_type ; - uint64_t issuer ; - uint8_t public_key_algorithm ; - uint8_t hash_algorithm ; -}; - -// This class handles GPG keys. For now we only clean them from signatures, but -// in the future, we might cache them to avoid unnecessary calls to gpgme. -// -class PGPKeyManagement -{ - public: - // Create a minimal key, removing all signatures and third party info. - // Input: a clean PGP certificate (starts with "----BEGIN", - // ends with "-----END PGP PUBLIC KEY BLOCK-----" - // Output: the same certificate without signatures. - // - // Returns: - // - // true if the certificate cleaning succeeded - // false otherwise. - // - static bool createMinimalKey(const std::string& pgp_certificate,std::string& cleaned_certificate) ; - - static void findLengthOfMinimalKey(const unsigned char *keydata,size_t key_len,size_t& minimal_key_len) ; - static std::string makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string) ; - - // Computes the 24 bits CRC checksum necessary to all PGP data. - // - static uint32_t compute24bitsCRC(unsigned char *data,size_t len) ; - - static bool parseSignature(const unsigned char *signature, size_t sign_len, PGPSignatureInfo& info) ; -}; - -// This class handles the parsing of PGP packet headers under various (old and new) formats. -// -class PGPKeyParser -{ - public: - // These constants correspond to packet tags from RFC4880 - - static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY = 6 ; - static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ; - static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ; - static const uint8_t PGP_PACKET_TAG_ISSUER = 16 ; - - // These functions read and move the data pointer to the next byte after the read section. - // - static uint64_t read_KeyID(unsigned char *& data) ; - static uint32_t read_125Size(unsigned char *& data) ; - static uint32_t read_partialBodyLength(unsigned char *& data) ; - static void read_packetHeader(unsigned char *& data,uint8_t& packet_tag,uint32_t& packet_length) ; - - // These functions write, and indicate how many bytes where written. - // - static uint32_t write_125Size(unsigned char *data,uint32_t size) ; - - // Helper functions - // - static std::string extractRadixPartFromArmouredKey(const std::string& pgp_cert,std::string& version_string); -}; - - diff --git a/libretroshare/src/pgp/rscertificate.cc b/libretroshare/src/pgp/rscertificate.cc deleted file mode 100644 index f3007bb01..000000000 --- a/libretroshare/src/pgp/rscertificate.cc +++ /dev/null @@ -1,628 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pgp: rscertificate.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016 Cyril Soler * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include - -#include -#include -#include -#include "rscertificate.h" -#include "util/rsstring.h" -#include "util/stacktrace.h" -#include "util/rsdebug.h" - -//#define DEBUG_RSCERTIFICATE - -static const uint8_t CERTIFICATE_VERSION_06 = 0x06; - -enum CertificatePtag : uint8_t -{ - CERTIFICATE_PTAG_PGP_SECTION = 0x01, - CERTIFICATE_PTAG_EXTIPANDPORT_SECTION = 0x02, - CERTIFICATE_PTAG_LOCIPANDPORT_SECTION = 0x03, - CERTIFICATE_PTAG_DNS_SECTION = 0x04, - CERTIFICATE_PTAG_SSLID_SECTION = 0x05, - CERTIFICATE_PTAG_NAME_SECTION = 0x06, - CERTIFICATE_PTAG_CHECKSUM_SECTION = 0x07, - CERTIFICATE_PTAG_HIDDENNODE_SECTION = 0x08, - CERTIFICATE_PTAG_VERSION_SECTION = 0x09, - CERTIFICATE_PTAG_EXTRA_LOCATOR = 10 -}; - -static bool is_acceptable_radix64Char(char c) -{ - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=' ; -} - - -RsCertificate::~RsCertificate() -{ - delete[] binary_pgp_key ; -} - -void RsCertificate::addPacket(uint8_t ptag, const unsigned char *mem, size_t size, unsigned char *& buf, size_t& offset, size_t& buf_size) -{ - // Check that the buffer has sufficient size. If not, increase it. - - while(offset + size + 6 >= buf_size) - { - unsigned char *newbuf = new unsigned char[2*buf_size] ; - - memcpy(newbuf, buf, buf_size) ; - buf_size *= 2 ; - - delete[] buf ; - - buf = newbuf ; - } - - // Write ptag and size - - buf[offset] = ptag ; - offset += 1 ; - - offset += PGPKeyParser::write_125Size(&buf[offset],size) ; - - // Copy the data - - memcpy(&buf[offset], mem, size) ; - offset += size ; -} - -const RsCertificate&RsCertificate::operator=(const RsCertificate&) -{ - memset(ipv4_external_ip_and_port,0,6); - memset(ipv4_internal_ip_and_port,0,6); - binary_pgp_key = nullptr; - binary_pgp_key_size = 0; - only_pgp = false; - hidden_node = false; - return *this; -} - -std::string RsCertificate::toStdString() const -{ - //std::string res ; - size_t BS = 1000 ; - size_t p = 0 ; - unsigned char *buf = new unsigned char[BS] ; - - addPacket( CERTIFICATE_PTAG_VERSION_SECTION, &CERTIFICATE_VERSION_06 , 1 , buf, p, BS ) ; - addPacket( CERTIFICATE_PTAG_PGP_SECTION , binary_pgp_key , binary_pgp_key_size , buf, p, BS ) ; - - if(!only_pgp) - { - if (hidden_node) - { - addPacket( CERTIFICATE_PTAG_HIDDENNODE_SECTION, (unsigned char *)hidden_node_address.c_str(), hidden_node_address.length() , buf, p, BS ) ; - } - else - { - addPacket( CERTIFICATE_PTAG_EXTIPANDPORT_SECTION, ipv4_external_ip_and_port , 6 , buf, p, BS ) ; - addPacket( CERTIFICATE_PTAG_LOCIPANDPORT_SECTION, ipv4_internal_ip_and_port , 6 , buf, p, BS ) ; - addPacket( CERTIFICATE_PTAG_DNS_SECTION , (unsigned char *)dns_name.c_str() , dns_name.length() , buf, p, BS ) ; - } - - addPacket( CERTIFICATE_PTAG_NAME_SECTION , (unsigned char *)location_name.c_str() ,location_name.length() , buf, p, BS ) ; - addPacket( CERTIFICATE_PTAG_SSLID_SECTION , location_id.toByteArray() ,location_id.SIZE_IN_BYTES, buf, p, BS ) ; - - for (const RsUrl& locator : mLocators) - { - std::string urlStr(locator.toString()); - addPacket( CERTIFICATE_PTAG_EXTRA_LOCATOR, - (unsigned char *) urlStr.c_str(), urlStr.size(), - buf, p, BS ); - } - } - - uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(buf,p) ; - - // handle endian issues. - unsigned char mem[3] ; - mem[0] = computed_crc & 0xff ; - mem[1] = (computed_crc >> 8 ) & 0xff ; - mem[2] = (computed_crc >> 16) & 0xff ; - - addPacket( CERTIFICATE_PTAG_CHECKSUM_SECTION,mem,3,buf,p,BS) ; - - std::string out_string ; - - Radix64::encode(buf, p, out_string) ; - - // Now slice up to 64 chars. - // - std::string out2 ; - static const int LINE_LENGTH = 64 ; - - for(int i=0;i<(int)out_string.length();++i) - { - out2 += out_string[i] ; - - if(i % LINE_LENGTH == LINE_LENGTH-1) - out2 += '\n' ; - } - - delete[] buf ; - return out2 ; -} - -RsCertificate::RsCertificate(const RsPeerDetails& Detail, const unsigned char *binary_pgp_block,size_t binary_pgp_block_size) - :pgp_version("Version: OpenPGP:SDK v0.9") -{ - if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " is deprecated because it can " - << "miserably fail like this! " << std::endl; - print_stacktrace(); - throw std::runtime_error("Cannot init a certificate with a void key block."); - } - - binary_pgp_key = new unsigned char[binary_pgp_block_size] ; - memcpy(binary_pgp_key,binary_pgp_block,binary_pgp_block_size) ; - binary_pgp_key_size = binary_pgp_block_size ; - - if(!Detail.isOnlyGPGdetail) - { - only_pgp = false ; - location_id = RsPeerId( Detail.id ) ; - location_name = Detail.location ; - - if (Detail.isHiddenNode) - { - hidden_node = true; - hidden_node_address = Detail.hiddenNodeAddress; - rs_sprintf_append(hidden_node_address, ":%u", Detail.hiddenNodePort); - - memset(ipv4_internal_ip_and_port,0,6) ; - memset(ipv4_external_ip_and_port,0,6) ; - dns_name = "" ; - } - else - { - hidden_node = false; - hidden_node_address = ""; - - try - { - scan_ip(Detail.localAddr,Detail.localPort,ipv4_internal_ip_and_port); - } - catch(...) - { - std::cerr << "RsCertificate::Invalid LocalAddress: " - << Detail.localAddr << std::endl; - memset(ipv4_internal_ip_and_port,0,6); - } - - - try - { - scan_ip(Detail.extAddr,Detail.extPort,ipv4_external_ip_and_port); - } - catch(...) - { - std::cerr << "RsCertificate::Invalid ExternalAddress: " - << Detail.extAddr << std::endl; - memset(ipv4_external_ip_and_port,0,6) ; - } - - dns_name = Detail.dyndns; - - for(auto&& ipr : Detail.ipAddressList) - mLocators.insert(RsUrl(ipr.substr(0, ipr.find(' ')))); - } - } - else - { - only_pgp = true ; - hidden_node = false; - hidden_node_address = ""; - location_id = RsPeerId() ; - location_name = "" ; - memset(ipv4_internal_ip_and_port,0,6) ; - memset(ipv4_external_ip_and_port,0,6) ; - dns_name = "" ; - } -} - - -/*static*/ std::unique_ptr RsCertificate::fromMemoryBlock( - const RsPeerDetails& details, const uint8_t* binary_pgp_block, - size_t binary_pgp_block_size ) -{ - if(binary_pgp_block_size == 0 || binary_pgp_block == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " invalid parameters! " << std::endl; - print_stacktrace(); - return nullptr; - } - - std::unique_ptr crt(new RsCertificate); - - crt->binary_pgp_key = new uint8_t[binary_pgp_block_size]; - memcpy(crt->binary_pgp_key, binary_pgp_block, binary_pgp_block_size); - crt->binary_pgp_key_size = binary_pgp_block_size; - - if(!details.isOnlyGPGdetail) - { - crt->only_pgp = false; - crt->location_id = RsPeerId(details.id); - crt->location_name = details.location; - - if (details.isHiddenNode) - { - crt->hidden_node = true; - crt->hidden_node_address = details.hiddenNodeAddress; - rs_sprintf_append( - crt->hidden_node_address, ":%u", details.hiddenNodePort); - - memset(crt->ipv4_internal_ip_and_port, 0, 6); - memset(crt->ipv4_external_ip_and_port, 0, 6); - crt->dns_name = ""; - } - else - { - crt->hidden_node = false; - crt->hidden_node_address = ""; - - try - { - scan_ip( details.localAddr, details.localPort, - crt->ipv4_internal_ip_and_port ); - } - catch(...) - { - RsErr() << __PRETTY_FUNCTION__ << " Invalid LocalAddress: " - << details.localAddr << std::endl; - memset(crt->ipv4_internal_ip_and_port, 0, 6); - } - - try - { - scan_ip( details.extAddr, details.extPort, - crt->ipv4_external_ip_and_port ); - } - catch(...) - { - RsErr() << __PRETTY_FUNCTION__ << " Invalid ExternalAddress: " - << details.extAddr << std::endl; - memset(crt->ipv4_external_ip_and_port, 0, 6); - } - - crt->dns_name = details.dyndns; - - for(auto&& ipr : details.ipAddressList) - crt->mLocators.insert(RsUrl(ipr.substr(0, ipr.find(' ')))); - } - } - else - { - crt->only_pgp = true; - crt->hidden_node = false; - crt->hidden_node_address = ""; - crt->location_id = RsPeerId(); - crt->location_name = ""; - memset(crt->ipv4_internal_ip_and_port, 0, 6); - memset(crt->ipv4_external_ip_and_port, 0, 6); - crt->dns_name = ""; - } - - return crt; // Implicit move semantic -} - -void RsCertificate::scan_ip(const std::string& ip_string, unsigned short port,unsigned char *ip_and_port) -{ - int d0,d1,d2,d3 ; - - if(4 != sscanf(ip_string.c_str(),"%d.%d.%d.%d",&d0,&d1,&d2,&d3)) - throw std::runtime_error( "Cannot parse ip from given string." ); - - ip_and_port[0] = d0 ; - ip_and_port[1] = d1 ; - ip_and_port[2] = d2 ; - ip_and_port[3] = d3 ; - - ip_and_port[4] = (port >> 8 ) & 0xff ; - ip_and_port[5] = port & 0xff ; -} - -/*static*/ std::unique_ptr RsCertificate::fromString( - const std::string& instr, uint32_t& err_code ) -{ - Dbg3() << __PRETTY_FUNCTION__ << std::endl; - - std::unique_ptr crt(new RsCertificate); - - std::string str; - err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR; - - // 0 - clean the string and check that it is pure radix64 - for(uint32_t i=0;i bf = Radix64::decode(str); - size_t size = bf.size(); - - bool checksum_check_passed = false; - unsigned char* buf = bf.data(); - size_t total_s = 0; - crt->only_pgp = true; - uint8_t certificate_version = 0x00; - - while(total_s < size) - { - uint8_t ptag = buf[0]; - buf = &buf[1]; - - unsigned char *buf2 = buf; - uint32_t s = 0; - - try { s = PGPKeyParser::read_125Size(buf); } - catch (...) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return nullptr; - } - - total_s += 1 + ( - reinterpret_cast(buf) - - reinterpret_cast(buf2) ); - - if(total_s > size) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return nullptr; - } - - Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: " - << static_cast(ptag) - << ", size " << s << ", total_s = " << total_s - << ", expected total = " << size << std::endl; - - switch(ptag) - { - case CERTIFICATE_PTAG_VERSION_SECTION: - certificate_version = buf[0]; - break; - case CERTIFICATE_PTAG_PGP_SECTION: - crt->binary_pgp_key = new unsigned char[s]; - memcpy(crt->binary_pgp_key, buf, s); - crt->binary_pgp_key_size = s; - break; - case CERTIFICATE_PTAG_NAME_SECTION: - crt->location_name = - std::string(reinterpret_cast(buf), s); - break; - case CERTIFICATE_PTAG_SSLID_SECTION: - if(s != crt->location_id.SIZE_IN_BYTES) - { - err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID; - return nullptr; - } - // We just checked buffer size so next line is not unsafe - crt->location_id = RsPeerId::fromBufferUnsafe(buf); - crt->only_pgp = false; - break; - case CERTIFICATE_PTAG_DNS_SECTION: - crt->dns_name = std::string(reinterpret_cast(buf), s); - break; - case CERTIFICATE_PTAG_HIDDENNODE_SECTION: - crt->hidden_node_address = - std::string(reinterpret_cast(buf),s); - crt->hidden_node = true; - break; - case CERTIFICATE_PTAG_LOCIPANDPORT_SECTION: - if(s != 6) - { - err_code = CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP; - return nullptr; - } - memcpy(crt->ipv4_internal_ip_and_port, buf, s); - break; - case CERTIFICATE_PTAG_EXTIPANDPORT_SECTION: - if(s != 6) - { - err_code = CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP; - return nullptr; - } - memcpy(crt->ipv4_external_ip_and_port, buf, s); - break; - case CERTIFICATE_PTAG_CHECKSUM_SECTION: - { - if(s != 3 || total_s+3 != size) - { - err_code = - CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION; - return nullptr; - } - uint32_t computed_crc = - PGPKeyManagement::compute24bitsCRC(bf.data(),size-5); - uint32_t certificate_crc = static_cast( - buf[0] + (buf[1] << 8) + (buf[2] << 16) ); - if(computed_crc != certificate_crc) - { - err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; - return nullptr; - } - else checksum_check_passed = true; - break; - } - case CERTIFICATE_PTAG_EXTRA_LOCATOR: - crt->mLocators.insert( - RsUrl(std::string(reinterpret_cast(buf), s))); - break; - default: - RsWarn() << __PRETTY_FUNCTION__ << " unknwown ptag: " - << static_cast(ptag) - << " in certificate! Ignoring it." << std::endl; - break; - } - - buf = &buf[s]; - total_s += s; - } - - if(!checksum_check_passed) - { - err_code = CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM; - return nullptr; - } - - if(certificate_version != CERTIFICATE_VERSION_06) - { - err_code = CERTIFICATE_PARSING_ERROR_WRONG_VERSION; - return nullptr; - } - - Dbg3() << __PRETTY_FUNCTION__ << " Certificate version: " - << static_cast(certificate_version) << std::endl; - - if(total_s != size) - RsWarn() << __PRETTY_FUNCTION__ << " Certificate contains trailing " - << "characters. Weird." << std::endl; - - return crt; // Implicit move semantic -} - -std::string RsCertificate::hidden_node_string() const -{ - if ((!only_pgp) && (hidden_node)) - { - return hidden_node_address; - } - - std::string empty; - return empty; -} - -std::string RsCertificate::ext_ip_string() const -{ - std::ostringstream os ; - os << (int)ipv4_external_ip_and_port[0] << "." << (int)ipv4_external_ip_and_port[1] << "." << (int)ipv4_external_ip_and_port[2] << "." << (int)ipv4_external_ip_and_port[3] ; - return os.str() ; -} - -std::string RsCertificate::loc_ip_string() const -{ - std::ostringstream os ; - os << (int)ipv4_internal_ip_and_port[0] << "." << (int)ipv4_internal_ip_and_port[1] << "." << (int)ipv4_internal_ip_and_port[2] << "." << (int)ipv4_internal_ip_and_port[3] ; - return os.str() ; -} - -unsigned short RsCertificate::ext_port_us() const -{ - return (int)ipv4_external_ip_and_port[4]*256 + (int)ipv4_external_ip_and_port[5] ; -} - -unsigned short RsCertificate::loc_port_us() const -{ - return (int)ipv4_internal_ip_and_port[4]*256 + (int)ipv4_internal_ip_and_port[5] ; -} - -bool RsCertificate::cleanCertificate( const std::string& input, std::string& output, Format& format, uint32_t& error_code, bool check_content ) -{ - if(cleanRadix64(input,output,error_code)) - { - RsPeerDetails details; - - if(rsPeers->parseShortInvite(output,details,error_code)) - { - format = RS_CERTIFICATE_SHORT_RADIX; - return true; - } - - format = RS_CERTIFICATE_RADIX; - - if(!check_content) return true; - - uint32_t errCode; - auto crt = RsCertificate::fromString(input, errCode); - error_code = static_cast(errCode); - return crt != nullptr; - } - - return false; -} - -std::string RsCertificate::armouredPGPKey() const -{ - return PGPKeyManagement::makeArmouredKey(binary_pgp_key,binary_pgp_key_size,pgp_version) ; -} - -// Yeah, this is simple, and that is what's good about the radix format. Can't be broken ;-) -// -bool RsCertificate::cleanRadix64(const std::string& instr,std::string& str,uint32_t& error_code) -{ - error_code = RS_PEER_CERT_CLEANING_CODE_NO_ERROR ; - - // 0 - clean the string and check that it is pure radix64 - // - for(uint32_t i=0;i * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rstypes.h" -#include "util/rsurl.h" -#include "util/rsmemory.h" -#include "util/rsdebug.h" - -#include -#include -#include - -struct RsPeerDetails; - -class RsCertificate -{ -public: - typedef enum { RS_CERTIFICATE_OLD_FORMAT, RS_CERTIFICATE_RADIX, RS_CERTIFICATE_SHORT_RADIX } Format; - - /** - * @brief Create certificate object from certificate string - * @param[in] str radix format certificate string - * @param[out] errorCode Optional storage for eventual error code, - * meaningful only on failure - * @return nullptr on failure, pointer to the generated certificate - * otherwise - */ - static std::unique_ptr fromString( - const std::string& str, - uint32_t& errorCode = RS_DEFAULT_STORAGE_PARAM(uint32_t) ); - - /** - * @brief Create certificate object from peer details and PGP memory block - * @param[in] details peer details - * @param[in] binary_pgp_block pointer to PGP memory block - * @param[in] binary_pgp_block_size size of PGP memory block - * @return nullptr on failure, pointer to the generated certificate - * otherwise - */ - static std::unique_ptr fromMemoryBlock( - const RsPeerDetails& details, const uint8_t* binary_pgp_block, - size_t binary_pgp_block_size ); - - ~RsCertificate(); - - /// Convert to certificate radix string - std::string toStdString() const; - - std::string ext_ip_string() const; - std::string loc_ip_string() const; - std::string location_name_string() const { return location_name; } - std::string dns_string() const { return dns_name ; } - RsPeerId sslid() const { return location_id ; } - std::string hidden_node_string() const; - - std::string armouredPGPKey() const; - - unsigned short ext_port_us() const; - unsigned short loc_port_us() const; - - const unsigned char *pgp_key() const { return binary_pgp_key ; } - size_t pgp_key_size() const { return binary_pgp_key_size ; } - - static bool cleanCertificate( - const std::string& input, std::string& output, - RsCertificate::Format& format, uint32_t& error_code, bool check_content); - - const std::set& locators() const { return mLocators; } - - /** - * @deprecated using this costructor may raise exception that cause - * crash if not handled. - */ - RS_DEPRECATED_FOR("RsCertificate::fromMemoryBlock(...)") - RsCertificate( const RsPeerDetails& details, - const unsigned char *gpg_mem_block, - size_t gpg_mem_block_size ); - -private: - // new radix format - static bool cleanRadix64(const std::string& input, std::string& output, uint32_t &); - - static void scan_ip( const std::string& ip_string, unsigned short port, - unsigned char *destination_memory ); - - static void addPacket(uint8_t ptag, const unsigned char *mem, size_t size, - unsigned char*& buf, size_t& offset, size_t& buf_size); - - RsCertificate(const RsCertificate&) {} /// non copy-able - const RsCertificate& operator=(const RsCertificate&); /// non copy-able - - /// @brief Costruct an empty certificate - RsCertificate() : - ipv4_external_ip_and_port{0,0,0,0,0,0}, - ipv4_internal_ip_and_port{0,0,0,0,0,0}, - binary_pgp_key(nullptr), binary_pgp_key_size(0), - pgp_version("Version: OpenPGP:SDK v0.9"), only_pgp(true), - hidden_node(false) {} - - unsigned char ipv4_external_ip_and_port[6]; - unsigned char ipv4_internal_ip_and_port[6]; - - unsigned char *binary_pgp_key; - size_t binary_pgp_key_size; - - std::string location_name; - RsPeerId location_id; - std::string pgp_version; - std::string dns_name; - std::string hidden_node_address; - std::set mLocators; - - bool only_pgp ; /// does the cert contain only pgp info? - bool hidden_node; /// IP or hidden Node Address. - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; - diff --git a/libretroshare/src/plugins/dlfcn_win32.cc b/libretroshare/src/plugins/dlfcn_win32.cc deleted file mode 100644 index b669cfa54..000000000 --- a/libretroshare/src/plugins/dlfcn_win32.cc +++ /dev/null @@ -1,322 +0,0 @@ -/******************************************************************************* - * libretroshare/src/plugins: dlfcn_win32.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007 Ramiro Polla * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifdef WINDOWS_SYS - -#include -#include -#include - -#include "dlfcn_win32.h" - -/* Note: - * MSDN says these functions are not thread-safe. We make no efforts to have - * any kind of thread safety. - */ - -typedef struct global_object { - HMODULE hModule; - struct global_object *previous; - struct global_object *next; -} global_object; - -static global_object first_object; - -/* These functions implement a double linked list for the global objects. */ -static global_object *global_search( HMODULE hModule ) -{ - global_object *pobject; - - if( hModule == NULL ) - return NULL; - - for( pobject = &first_object; pobject ; pobject = pobject->next ) - if( pobject->hModule == hModule ) - return pobject; - - return NULL; -} - -static void global_add( HMODULE hModule ) -{ - global_object *pobject; - global_object *nobject; - - if( hModule == NULL ) - return; - - pobject = global_search( hModule ); - - /* Do not add object again if it's already on the list */ - if( pobject ) - return; - - for( pobject = &first_object; pobject->next ; pobject = pobject->next ); - - nobject = (global_object*) malloc( sizeof(global_object) ); - - /* Should this be enough to fail global_add, and therefore also fail - * dlopen? - */ - if( !nobject ) - return; - - pobject->next = nobject; - nobject->next = NULL; - nobject->previous = pobject; - nobject->hModule = hModule; -} - -static void global_rem( HMODULE hModule ) -{ - global_object *pobject; - - if( hModule == NULL ) - return; - - pobject = global_search( hModule ); - - if( !pobject ) - return; - - if( pobject->next ) - pobject->next->previous = pobject->previous; - if( pobject->previous ) - pobject->previous->next = pobject->next; - - free( pobject ); -} - -/* POSIX says dlerror( ) doesn't have to be thread-safe, so we use one - * static buffer. - * MSDN says the buffer cannot be larger than 64K bytes, so we set it to - * the limit. - */ -static char error_buffer[65535]; -static char *current_error; - -static int copy_string( char *dest, int dest_size, const char *src ) -{ - int i = 0; - - /* gcc should optimize this out */ - if( !src && !dest ) - return 0; - - for( i = 0 ; i < dest_size-1 ; i++ ) - { - if( !src[i] ) - break; - else - dest[i] = src[i]; - } - dest[i] = '\0'; - - return i; -} - -static void save_err_str( const char *str ) -{ - DWORD dwMessageId; - DWORD pos; - - dwMessageId = GetLastError( ); - - if( dwMessageId == 0 ) - return; - - /* Format error message to: - * "": - */ - pos = copy_string( error_buffer, sizeof(error_buffer), "\"" ); - pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, str ); - pos += copy_string( error_buffer+pos, sizeof(error_buffer)-pos, "\": " ); - pos += FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, - MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), - error_buffer+pos, sizeof(error_buffer)-pos, NULL ); - - if( pos > 1 ) - { - /* POSIX says the string must not have trailing */ - if( error_buffer[pos-2] == '\r' && error_buffer[pos-1] == '\n' ) - error_buffer[pos-2] = '\0'; - } - - current_error = error_buffer; -} - -static void save_err_ptr_str( const void *ptr ) -{ - char ptr_buf[19]; /* 0x up to 64 bits. */ - - sprintf( ptr_buf, "0x%p", ptr ); - - save_err_str( ptr_buf ); -} - -void *dlopen( const char *file, int mode ) -{ - HMODULE hModule; - UINT uMode; - - current_error = NULL; - - /* Do not let Windows display the critical-error-handler message box */ - uMode = SetErrorMode( SEM_FAILCRITICALERRORS ); - - if( file == 0 ) - { - /* POSIX says that if the value of file is 0, a handle on a global - * symbol object must be provided. That object must be able to access - * all symbols from the original program file, and any objects loaded - * with the RTLD_GLOBAL flag. - * The return value from GetModuleHandle( ) allows us to retrieve - * symbols only from the original program file. For objects loaded with - * the RTLD_GLOBAL flag, we create our own list later on. - */ - hModule = GetModuleHandle( NULL ); - - if( !hModule ) - save_err_ptr_str( file ); - } - else - { - char lpFileName[MAX_PATH]; - unsigned int i; - - /* MSDN says backslashes *must* be used instead of forward slashes. */ - for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ ) - { - if( !file[i] ) - break; - else if( file[i] == '/' ) - lpFileName[i] = '\\'; - else - lpFileName[i] = file[i]; - } - lpFileName[i] = '\0'; - - /* POSIX says the search path is implementation-defined. - * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely - * to UNIX's search paths (start with system folders instead of current - * folder). - */ - hModule = LoadLibraryExA( (LPSTR) lpFileName, NULL, - LOAD_WITH_ALTERED_SEARCH_PATH ); - - /* If the object was loaded with RTLD_GLOBAL, add it to list of global - * objects, so that its symbols may be retrieved even if the handle for - * the original program file is passed. POSIX says that if the same - * file is specified in multiple invocations, and any of them are - * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the - * symbols will remain global. - */ - if( !hModule ) - save_err_str( lpFileName ); - else if( (mode & RTLD_GLOBAL) ) - global_add( hModule ); - } - - /* Return to previous state of the error-mode bit flags. */ - SetErrorMode( uMode ); - - return (void *) hModule; -} - -int dlclose( void *handle ) -{ - HMODULE hModule = (HMODULE) handle; - BOOL ret; - - current_error = NULL; - - ret = FreeLibrary( hModule ); - - /* If the object was loaded with RTLD_GLOBAL, remove it from list of global - * objects. - */ - if( ret ) - global_rem( hModule ); - else - save_err_ptr_str( handle ); - - /* dlclose's return value in inverted in relation to FreeLibrary's. */ - ret = !ret; - - return (int) ret; -} - -void *dlsym( void *handle, const char *name ) -{ - FARPROC symbol; - - current_error = NULL; - - symbol = GetProcAddress( (HINSTANCE) handle, name ); - - if( symbol == NULL ) - { - HMODULE hModule; - - /* If the handle for the original program file is passed, also search - * in all globally loaded objects. - */ - - hModule = GetModuleHandle( NULL ); - - if( hModule == handle ) - { - global_object *pobject; - - for( pobject = &first_object; pobject ; pobject = pobject->next ) - { - if( pobject->hModule ) - { - symbol = GetProcAddress( pobject->hModule, name ); - if( symbol != NULL ) - break; - } - } - } - - // Do not close the handle of the calling process -// CloseHandle( hModule ); - } - - if( symbol == NULL ) - save_err_str( name ); - - return (void*) symbol; -} - -char *dlerror( void ) -{ - char *error_pointer = current_error; - - /* POSIX says that invoking dlerror( ) a second time, immediately following - * a prior invocation, shall result in NULL being returned. - */ - current_error = NULL; - - return error_pointer; -} -#endif diff --git a/libretroshare/src/plugins/dlfcn_win32.h b/libretroshare/src/plugins/dlfcn_win32.h deleted file mode 100644 index 3298777dd..000000000 --- a/libretroshare/src/plugins/dlfcn_win32.h +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * libretroshare/src/plugins: dlfcn_win32.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007 Ramiro Polla * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#ifdef WINDOWS_SYS -#ifndef DLFCN_H -#define DLFCN_H - -/* POSIX says these are implementation-defined. - * To simplify use with Windows API, we treat them the same way. - */ - -#define RTLD_LAZY 0 -#define RTLD_NOW 0 - -#define RTLD_GLOBAL (1 << 1) -#define RTLD_LOCAL (1 << 2) - -/* These two were added in The Open Group Base Specifications Issue 6. - * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant. - */ - -#define RTLD_DEFAULT 0 -#define RTLD_NEXT 0 - -void *dlopen ( const char *file, int mode ); -int dlclose( void *handle ); -void *dlsym ( void *handle, const char *name ); -char *dlerror( void ); - -#endif /* DLFCN_H */ -#endif /* WINDOWS_SYS */ diff --git a/libretroshare/src/plugins/pluginmanager.cc b/libretroshare/src/plugins/pluginmanager.cc deleted file mode 100644 index dcd474f8f..000000000 --- a/libretroshare/src/plugins/pluginmanager.cc +++ /dev/null @@ -1,586 +0,0 @@ -/******************************************************************************* - * libretroshare/src/plugins: pluginmanager.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "pluginmanager.h" -#include - -#if 0 -#include -#include -#include -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// lets disable the plugin system for now, as it's unfinished. -#ifdef WINDOWS_SYS -#include "dlfcn_win32.h" -#else -#include -#endif - -// #define DEBUG_PLUGIN_MANAGER 1 - -std::string RsPluginManager::_plugin_entry_symbol = "RETROSHARE_PLUGIN_provide" ; -std::string RsPluginManager::_plugin_revision_symbol = "RETROSHARE_PLUGIN_revision" ; -std::string RsPluginManager::_plugin_API_symbol = "RETROSHARE_PLUGIN_api" ; - -std::string RsPluginManager::_local_cache_dir ; -std::string RsPluginManager::_remote_cache_dir ; -std::vector RsPluginManager::_plugin_directories ; - -RsServiceControl *RsPluginManager::_service_control = NULL ; - -typedef RsPlugin *(*RetroSharePluginEntry)(void) ; -RsPluginHandler *rsPlugins ; - -RsPluginManager::RsPluginManager(const RsFileHash &hash) - : p3Config(),_current_executable_hash(hash) -{ - _allow_all_plugins = false ; -} - -bool RsPluginManager::loadConfiguration(RsFileHash &loadHash) -{ - return p3Config::loadConfiguration(loadHash); -} - -void RsPluginManager::loadConfiguration() -{ - RsFileHash dummyHash; - p3Config::loadConfiguration(dummyHash); -} - -void RsPluginManager::setInterfaces(RsPlugInInterfaces &interfaces) -{ - std::cerr << "RsPluginManager::setInterfaces() " << std::endl; - - for(uint32_t i=0;i<_plugins.size();++i) - if(_plugins[i].plugin != NULL) - { - std::cerr << " setting iterface for plugin " << _plugins[i].plugin->getPluginName() << ", with RS_ID " << _plugins[i].plugin->rs_service_id() << std::endl ; - _plugins[i].plugin->setInterfaces(interfaces); - } -} - -void RsPluginManager::setCacheDirectories(const std::string& local_cache, const std::string& remote_cache) -{ - _local_cache_dir = local_cache ; - _remote_cache_dir = remote_cache ; -} - -bool RsPluginManager::acceptablePluginName(const std::string& name) -{ - // Needs some windows specific code here - // -#ifdef WINDOWS_SYS - return name.size() > 4 && name.substr(name.size() - 4) == ".dll"; -#elif defined(__MACH__) - return name.size() > 6 && !strcmp(name.c_str()+name.size()-6,".dylib") ; -#else - return name.size() > 3 && !strcmp(name.c_str()+name.size()-3,".so") ; -#endif -} - -void RsPluginManager::disablePlugin(const RsFileHash& hash) -{ - std::set::iterator it = _accepted_hashes.find(hash) ; - - if(it != _accepted_hashes.end()) - { - std::cerr << "RsPluginManager::disablePlugin(): removing hash " << hash << " from white list" << std::endl; - - _accepted_hashes.erase(it) ; - IndicateConfigChanged() ; - } - if(_rejected_hashes.find(hash) == _rejected_hashes.end()) - { - std::cerr << "RsPluginManager::enablePlugin(): inserting hash " << hash << " in black list" << std::endl; - - _rejected_hashes.insert(hash) ; - IndicateConfigChanged() ; - } -} - -void RsPluginManager::enablePlugin(const RsFileHash& hash) -{ - if(_accepted_hashes.find(hash) == _accepted_hashes.end()) - { - std::cerr << "RsPluginManager::enablePlugin(): inserting hash " << hash << " in white list" << std::endl; - - _accepted_hashes.insert(hash) ; - IndicateConfigChanged() ; - } - std::set::const_iterator it(_rejected_hashes.find(hash)) ; - - if(it != _rejected_hashes.end()) - { - std::cerr << "RsPluginManager::enablePlugin(): removing hash " << hash << " from black list" << std::endl; - - _rejected_hashes.erase(it) ; - IndicateConfigChanged() ; - } -} - -void RsPluginManager::loadPlugins(const std::vector& plugin_directories) -{ - _plugin_directories = plugin_directories ; - _plugin_entry_symbol = "RETROSHARE_PLUGIN_provide" ; - _plugin_revision_symbol = "RETROSHARE_PLUGIN_revision" ; - - // 0 - get the list of files to read - - bool first_time = (_accepted_hashes.empty()) && _rejected_hashes.empty() ; - - for(uint32_t i=0;ip3_service(); - if (service) - { - pqih->removeService(service); - } - - _plugins[i].plugin->stop(); - delete _plugins[i].plugin; - _plugins[i].plugin = NULL; - } - if (_plugins[i].handle) - { - dlclose(_plugins[i].handle); - _plugins[i].handle = NULL; - } - } -} - -void RsPluginManager::getPluginStatus(int i,uint32_t& status,std::string& file_name,RsFileHash &hash,uint32_t& svn_revision,std::string& error_string) const -{ - if((uint32_t)i >= _plugins.size()) - return ; - - status = _plugins[i].status ; - error_string = _plugins[i].info_string ; - hash = _plugins[i].file_hash ; - file_name = _plugins[i].file_name ; - svn_revision = _plugins[i].svn_revision ; -} - -bool RsPluginManager::getAllowAllPlugins() const -{ - return _allow_all_plugins ; -} -void RsPluginManager::allowAllPlugins(bool b) -{ - _allow_all_plugins = b ; - IndicateConfigChanged() ; -} -RsSerialiser *RsPluginManager::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsPluginSerialiser()) ; - rss->addSerialType(new RsGeneralConfigSerialiser()) ; - - return rss ; -} - -void RsPluginManager::loadPlugins(const std::vector& plugins) -{ - for(uint32_t i=0;isetPlugInHandler(this); // WIN fix, cannot share global space with shared libraries - - // The following choice is conservative by forcing RS to resolve all dependencies at - // the time of loading the plugin. - - pinfo.status = PLUGIN_STATUS_LOADED ; - - _plugins.push_back(pinfo) ; - return true; -} - -bool RsPluginManager::loadPlugin(const std::string& plugin_name,bool first_time) -{ - std::cerr << " Loading plugin " << plugin_name << std::endl; - - PluginInfo pf ; - pf.plugin = NULL ; - pf.file_name = plugin_name ; - pf.info_string = "" ; - std::cerr << " -> hashing." << std::endl; - uint64_t size ; - - // Stage 1 - get information related to file (hash, name, ...) - // - if(!RsDirUtil::getFileHash(plugin_name,pf.file_hash,size)) - { - std::cerr << " -> cannot hash file. Plugin read canceled." << std::endl; - return false; - } - - _plugins.push_back(pf) ; - PluginInfo& pinfo(_plugins.back()) ; - - std::cerr << " -> hash = " << pinfo.file_hash << std::endl; - - if(!_allow_all_plugins) - { - if(_accepted_hashes.find(pinfo.file_hash) == _accepted_hashes.end() && _rejected_hashes.find(pinfo.file_hash) == _rejected_hashes.end() ) - if(!RsServer::notify()->askForPluginConfirmation(pinfo.file_name,pinfo.file_hash.toStdString(),first_time)) - _rejected_hashes.insert(pinfo.file_hash) ; // accepted hashes are treated at the end, for security. - - if(_rejected_hashes.find(pinfo.file_hash) != _rejected_hashes.end() ) - { - pinfo.status = PLUGIN_STATUS_REJECTED_HASH ; - std::cerr << " -> hash rejected. Giving up plugin. " << std::endl; - return false ; - } - } - else - std::cerr << " -> ALLOW_ALL_PLUGINS Enabled => plugin loaded by default." << std::endl; - - std::cerr << " -> hash authorized. Loading plugin. " << std::endl; - - // Stage 2 - open with dlopen, and get some basic info. - // - - // The following choice is conservative by forcing RS to resolve all dependencies at - // the time of loading the plugin. - - int link_mode = RTLD_NOW | RTLD_GLOBAL ; - - void *handle = dlopen(plugin_name.c_str(),link_mode) ; - - if(handle == NULL) - { - const char *val = dlerror() ; - std::cerr << " Cannot open plugin: " << val << std::endl ; - pinfo.status = PLUGIN_STATUS_DLOPEN_ERROR ; - pinfo.info_string = val ; - return false ; - } - - void *prev = dlsym(handle,_plugin_revision_symbol.c_str()) ; pinfo.svn_revision = (prev == NULL) ? 0 : (*(uint32_t *)prev) ; - void *papi = dlsym(handle,_plugin_API_symbol.c_str()) ; pinfo.API_version = (papi == NULL) ? 0 : (*(uint32_t *)papi) ; - - std::cerr << " -> plugin revision number: " << pinfo.svn_revision << std::endl; - std::cerr << " plugin API number : " << std::hex << pinfo.API_version << std::dec << std::endl; - - // Check that the plugin provides a svn revision number and a API number - // - if(pinfo.API_version == 0) - { - std::cerr << " -> No API version number." << std::endl; - pinfo.status = PLUGIN_STATUS_MISSING_API ; - pinfo.info_string = "" ; - dlclose(handle); - return false ; - } -#ifdef TO_REMOVE - if(pinfo.svn_revision == 0) - { - std::cerr << " -> No svn revision number." << std::endl; - pinfo.status = PLUGIN_STATUS_MISSING_SVN ; - pinfo.info_string = "" ; - dlclose(handle); - return false ; - } -#endif - - // Now look for the plugin class symbol. - // - void *pfe = dlsym(handle,_plugin_entry_symbol.c_str()) ; - - if(pfe == NULL) - { - std::cerr << dlerror() << std::endl ; - pinfo.status = PLUGIN_STATUS_MISSING_SYMBOL ; - pinfo.info_string = _plugin_entry_symbol ; - dlclose(handle); - return false ; - } - std::cerr << " -> Added function entry for symbol " << _plugin_entry_symbol << std::endl ; - - RsPlugin *p = ( (*(RetroSharePluginEntry)pfe)() ) ; - - if(p == NULL) - { - std::cerr << " Plugin entry function " << _plugin_entry_symbol << " returns NULL ! It should return an object of type RsPlugin* " << std::endl; - pinfo.status = PLUGIN_STATUS_NULL_PLUGIN ; - pinfo.info_string = "Plugin entry " + _plugin_entry_symbol + "() return NULL" ; - dlclose(handle); - return false ; - } - - pinfo.status = PLUGIN_STATUS_LOADED ; - pinfo.plugin = p ; - pinfo.handle = handle; - p->setPlugInHandler(this); // WIN fix, cannot share global space with shared libraries - pinfo.info_string = "" ; - - _accepted_hashes.insert(pinfo.file_hash) ; // do it now, to avoid putting in list a plugin that might have crashed during the load. - return true; -} - -const std::string& RsPluginManager::getLocalCacheDir() const -{ - assert(!_local_cache_dir.empty()) ; - return _local_cache_dir ; -} -const std::string& RsPluginManager::getRemoteCacheDir() const -{ - assert(!_remote_cache_dir.empty()) ; - return _remote_cache_dir ; -} -RsServiceControl *RsPluginManager::getServiceControl() const -{ - assert(_service_control); - return _service_control ; -} -void RsPluginManager::slowTickPlugins(rstime_t seconds) -{ - for(uint32_t i=0;i<_plugins.size();++i) - if(_plugins[i].plugin != NULL && _plugins[i].plugin->rs_cache_service() != NULL && (seconds % _plugins[i].plugin->rs_cache_service()->tickDelay() )) - { -#ifdef DEBUG_PLUGIN_MANAGER - std::cerr << " ticking plugin " << _plugins[i].plugin->getPluginName() << std::endl; -#endif - _plugins[i].plugin->rs_cache_service()->tick() ; - } -} - -void RsPluginManager::registerCacheServices() -{ - // this is removed since the old cache syste is gone, but we need to make it register new GXS group services instead. -#ifdef REMOVED - std::cerr << " Registering cache services." << std::endl; - - for(uint32_t i=0;i<_plugins.size();++i) - if(_plugins[i].plugin != NULL && _plugins[i].plugin->rs_cache_service() != NULL) - { - //rsFiles->getCacheStrapper()->addCachePair(CachePair(_plugins[i].plugin->rs_cache_service(),_plugins[i].plugin->rs_cache_service(),CacheId(_plugins[i].plugin->rs_service_id(), 0))) ; - std::cerr << " adding new cache pair for plugin " << _plugins[i].plugin->getPluginName() << ", with RS_ID " << _plugins[i].plugin->rs_service_id() << std::endl ; - } -#endif -} - -void RsPluginManager::registerClientServices(p3ServiceServer *pqih) -{ - std::cerr << " Registering pqi services." << std::endl; - - for(uint32_t i=0;i<_plugins.size();++i) - //if(_plugins[i].plugin != NULL && _plugins[i].plugin->rs_pqi_service() != NULL) - if(_plugins[i].plugin != NULL && _plugins[i].plugin->p3_service() != NULL) - { - //pqih->addService(_plugins[i].plugin->rs_pqi_service(), true) ; - pqih->addService(_plugins[i].plugin->p3_service(), true) ; - std::cerr << " Added pqi service for plugin " << _plugins[i].plugin->getPluginName() << std::endl; - } -} - -void RsPluginManager::addConfigurations(p3ConfigMgr *ConfigMgr) -{ - std::cerr << " Registering configuration files." << std::endl; - - for(uint32_t i=0;i<_plugins.size();++i) - if(_plugins[i].plugin != NULL && _plugins[i].plugin->configurationFileName().length() > 0) - { - if( _plugins[i].plugin->rs_cache_service() != NULL) - ConfigMgr->addConfiguration(_plugins[i].plugin->configurationFileName(), _plugins[i].plugin->rs_cache_service()); - //else if(_plugins[i].plugin->rs_pqi_service() != NULL) - // ConfigMgr->addConfiguration(_plugins[i].plugin->configurationFileName(), _plugins[i].plugin->rs_pqi_service()); - else if(_plugins[i].plugin->p3_config() != NULL) - ConfigMgr->addConfiguration(_plugins[i].plugin->configurationFileName(), _plugins[i].plugin->p3_config()); - else - continue ; - - std::cerr << " Added configuration for plugin " << _plugins[i].plugin->getPluginName() << ", with file " << _plugins[i].plugin->configurationFileName() << std::endl; - } -} - -bool RsPluginManager::loadList(std::list& list) -{ - std::set accepted_hash_candidates ; - std::set rejected_hash_candidates ; - - std::cerr << "RsPluginManager::loadList(): " << std::endl; - RsFileHash reference_executable_hash ; - - std::list::iterator it; - for(it = list.begin(); it != list.end(); ++it) - { - RsConfigKeyValueSet *witem = dynamic_cast(*it) ; - - if(witem) - for(std::list::const_iterator kit = witem->tlvkvs.pairs.begin(); kit != witem->tlvkvs.pairs.end(); ++kit) - { - if((*kit).key == "ALLOW_ALL_PLUGINS") - { - _allow_all_plugins = (kit->value == "YES"); - - if(_allow_all_plugins) - std::cerr << "WARNING: Allowing all plugins. No hash will be checked. Be careful! " << std::endl ; - } - else if((*kit).key == "REFERENCE_EXECUTABLE_HASH") - { - reference_executable_hash = RsFileHash(kit->value) ; - std::cerr << " Reference executable hash: " << kit->value << std::endl; - } - else if((*kit).key == "ACCEPTED") - { - accepted_hash_candidates.insert(RsFileHash((*kit).value)) ; - std::cerr << " Accepted hash: " << (*kit).value << std::endl; - } - else if((*kit).key == "REJECTED") - { - rejected_hash_candidates.insert(RsFileHash((*kit).value)) ; - std::cerr << " Rejected hash: " << (*kit).value << std::endl; - } - } - - delete (*it); - } - - // Rejected hashes are always kept, so that RS wont ask again if the executable hash has changed. - // - _rejected_hashes = rejected_hash_candidates ; - - if(reference_executable_hash == _current_executable_hash) - { - std::cerr << "(II) Executable hash matches. Updating the list of accepted/rejected plugins." << std::endl; - - _accepted_hashes = accepted_hash_candidates ; - } - else - std::cerr << "(WW) Executable hashes do not match. Executable hash has changed. Discarding the list of accepted/rejected plugins." << std::endl; - - return true; -} - -bool RsPluginManager::saveList(bool& cleanup, std::list& list) -{ - std::cerr << "PluginManager: saving list." << std::endl; - cleanup = true ; - - RsConfigKeyValueSet *witem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "ALLOW_ALL_PLUGINS" ; - kv.value = _allow_all_plugins?"YES":"NO" ; - witem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "REFERENCE_EXECUTABLE_HASH" ; - kv.value = _current_executable_hash.toStdString() ; - witem->tlvkvs.pairs.push_back(kv) ; - - std::cerr << " Saving current executable hash: " << kv.value << std::endl; - - // now push accepted and rejected hashes. - - for(std::set::const_iterator it(_accepted_hashes.begin());it!=_accepted_hashes.end();++it) - { - witem->tlvkvs.pairs.push_back( RsTlvKeyValue( "ACCEPTED", (*it).toStdString() ) ) ; - std::cerr << " " << *it << " : " << "ACCEPTED" << std::endl; - } - - for(std::set::const_iterator it(_rejected_hashes.begin());it!=_rejected_hashes.end();++it) - { - witem->tlvkvs.pairs.push_back( RsTlvKeyValue( "REJECTED", (*it).toStdString() ) ) ; - std::cerr << " " << *it << " : " << "REJECTED" << std::endl; - } - - list.push_back(witem) ; - - return true; -} - -RsPQIService::RsPQIService(uint16_t /*service_type*/, uint32_t /*tick_delay_in_seconds*/, RsPluginHandler* /*pgHandler*/) - : p3Service(),p3Config() -{ -} - diff --git a/libretroshare/src/plugins/pluginmanager.h b/libretroshare/src/plugins/pluginmanager.h deleted file mode 100644 index 965706bf1..000000000 --- a/libretroshare/src/plugins/pluginmanager.h +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************* - * libretroshare/src/plugins: pluginmanager.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -class p3ConfigMgr ; -class p3ServiceServer ; -class p3LinkMgr ; - -class PluginInfo -{ -public: - PluginInfo() : handle(NULL), plugin(NULL), API_version(0), svn_revision(0), status(0) {} - - public: - // Handle of the loaded plugin. - // - void *handle; - - // Main object provided by the plugin. NULL is the plugin could not be loaded. - // - RsPlugin *plugin ; - - // Information related to the file. Do not require the plugin to be loaded nor the DSO to be openned. - // - RsFileHash file_hash ; - std::string file_name ; - - // Information coming from directly loaded symbols. The plugin is responsible for providing them. - // - std::string creator ; // creator of the plugin - std::string name ; // name of the plugin - uint32_t API_version ; // API version. - uint32_t svn_revision ; // Coming from scripts. Same svn version but changing hash could be a security issue. - - // This info is filled when accessing the .so, and loading the plugin. - // - uint32_t status ; // See the flags in retroshare/rsplugin.h - std::string info_string ; -}; - -class RsPluginManager: public RsPluginHandler, public p3Config -{ - public: - explicit RsPluginManager(const RsFileHash& current_executable_sha1_hash) ; - virtual ~RsPluginManager() {} - - // ------------ Derived from RsPluginHandler ----------------// - // - virtual int nbPlugins() const { return _plugins.size() ; } - virtual RsPlugin *plugin(int i) { return _plugins[i].plugin ; } - virtual const std::vector& getPluginDirectories() const { return _plugin_directories ; } - virtual void getPluginStatus(int i, uint32_t& status,std::string& file_name, RsFileHash& hash,uint32_t& svn_revision,std::string& error_string) const ; - virtual void enablePlugin(const RsFileHash& hash) ; - virtual void disablePlugin(const RsFileHash &hash) ; - - virtual void slowTickPlugins(rstime_t sec) ; - virtual const std::string& getLocalCacheDir() const ; - virtual const std::string& getRemoteCacheDir() const ; - virtual RsServiceControl *getServiceControl() const ; - - virtual void allowAllPlugins(bool b) ; - virtual bool getAllowAllPlugins() const ; - - // ---------------- Derived from p3Config -------------------// - // - bool saveList(bool& cleanup, std::list& list) ; - bool loadList(std::list& list) ; - virtual RsSerialiser* setupSerialiser() ; - - // -------------------- Own members -------------------------// - // - virtual void addConfigurations(p3ConfigMgr *cfgMgr) ; - virtual bool loadConfiguration(RsFileHash &loadHash) ; - virtual void loadConfiguration() ; - - /*! - * sets interfaces for all loaded plugins - * @param interfaces - */ - void setInterfaces(RsPlugInInterfaces& interfaces); - - static bool acceptablePluginName(const std::string& s) ; - static void setCacheDirectories(const std::string& local,const std::string& remote) ; - static void setServiceControl(RsServiceControl *cm) { _service_control = cm ; } - - // Normal plugin loading system. Parses through the plugin directories and loads - // dso libraries, checks for the hash, and loads/rejects plugins according to - // the user's choice. - // - void loadPlugins(const std::vector& plugin_directories) ; - - // Explicit function to load a plugin programatically. - // No hash-checking is performed (there's no DSO file to hash!) - // Mostly convenient for insering plugins in development. - // - void loadPlugins(const std::vector& explicit_plugin_entries) ; - - void stopPlugins(p3ServiceServer *pqih); - - void registerCacheServices() ; - void registerClientServices(p3ServiceServer *pqih) ; - - private: - bool loadPlugin(RsPlugin *) ; - bool loadPlugin(const std::string& shared_library_name, bool first_time) ; - RsFileHash hashPlugin(const std::string& shared_library_name) ; - - std::vector _plugins ; - - // Should allow - // - searching - // - saving all hash - // - // At start - // * load reference executable hash. Compare with current executable. - // - if different => flush all plugin hashes from cache - // - if equal, - // - std::set _accepted_hashes ; // accepted hash values for reference executable hash. - std::set _rejected_hashes ; // rejected hash values for reference executable hash. - RsFileHash _current_executable_hash ; // At all times, the list of accepted plugins should be related to the current hash of the executable. - bool _allow_all_plugins ; - - static std::string _plugin_entry_symbol ; - static std::string _plugin_revision_symbol ; - static std::string _plugin_API_symbol ; - static std::string _remote_cache_dir ; - static std::string _local_cache_dir ; - - static RsServiceControl *_service_control ; - - static std::vector _plugin_directories ; -}; - diff --git a/libretroshare/src/plugins/rscacheservice.h b/libretroshare/src/plugins/rscacheservice.h deleted file mode 100644 index 82f43e0de..000000000 --- a/libretroshare/src/plugins/rscacheservice.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "plugins/pluginmanager.h" - -// This code needs to be re-written to work with GXS. For now it is obsolete. -// - -// The following class abstracts the construction of a cache service. The user only has to -// supply RS with a type ID. If the ID is already in use, RS will complain. -// -class RsCacheService: /* public CacheSource, public CacheStore, */ public p3Config -{ - public: - RsCacheService(uint16_t type,uint32_t tick_delay_in_seconds, RsPluginHandler* pgHandler) ; - - uint32_t tickDelay() const { return _tick_delay_in_seconds ; } - virtual void tick() {} - - // Functions from p3config - // - virtual RsSerialiser *setupSerialiser() { return NULL ; } - virtual bool saveList(bool&, std::list&) =0; - virtual bool loadList(std::list&) =0; - - private: - uint32_t _tick_delay_in_seconds ; -}; diff --git a/libretroshare/src/plugins/rspqiservice.h b/libretroshare/src/plugins/rspqiservice.h deleted file mode 100644 index f4ee6f313..000000000 --- a/libretroshare/src/plugins/rspqiservice.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "services/p3service.h" -#include "plugins/pluginmanager.h" - -// The following class abstracts the construction of a peer-to-peer service. The user only has to -// supply RS with a type ID. If the ID is already in use, RS will complain. -// -class RsPQIService: public p3Service, public p3Config -{ - public: - RsPQIService(uint16_t type,uint32_t tick_delay_in_seconds, RsPluginHandler* pgHandler) ; - - uint32_t tickDelay() const { return _tick_delay_in_seconds ; } - virtual int tick() = 0 ; - - // Functions from p3config - // - virtual RsSerialiser *setupSerialiser() { return NULL ; } - virtual bool saveList(bool&, std::list&) =0 ; - virtual bool loadList(std::list&) =0 ; - - private: - uint32_t _tick_delay_in_seconds ; -}; - diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc deleted file mode 100644 index b41084cf0..000000000 --- a/libretroshare/src/pqi/authgpg.cc +++ /dev/null @@ -1,769 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: authgpg.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2009 by Robert Fernie, Retroshare Team. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "authgpg.h" -#include "retroshare/rsiface.h" // For rsicontrol. -#include "retroshare/rspeers.h" // For RsPeerDetails. -#ifdef WINDOWS_SYS -#include "retroshare/rsinit.h" -#endif -#include "rsserver/p3face.h" -#include "pqi/p3notify.h" -#include "pgp/pgphandler.h" - -#include -#include -#include -#include /* for (u)sleep() */ -#include -#include -#include -#include -#include "rsitems/rsconfigitems.h" - -#define LIMIT_CERTIFICATE_SIZE 1 -#define MAX_CERTIFICATE_SIZE 10000 - -//#define DEBUG_AUTHGPG 1 - -//const rstime_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour - -AuthGPG *AuthGPG::_instance = NULL ; - -void cleanupZombies(int numkill); // function to cleanup zombies under OSX. - -//#define GPG_DEBUG 1 - -/* Function to sign X509_REQ via GPGme. */ - -bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) -{ - return PGPHandler::decryptTextFromFile(mOwnGpgId,text,inputfile) ; -} - -bool AuthGPG::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) -{ -// std::list pids ; -// -// for(std::list::const_iterator it(pgp_ids.begin());it!=pgp_ids.end();++it) -// pids.push_back(RsPgpId(*it)) ; - - return PGPHandler::removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; -} - -// bool AuthGPG::decryptTextFromString(std::string& encrypted_text,std::string& output) -// { -// return PGPHandler::decryptTextFromString(mOwnGpgId,encrypted_text,output) ; -// } - -bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) -{ - return PGPHandler::encryptTextToFile(mOwnGpgId,text,outfile) ; -} - -// bool AuthGPG::encryptTextToString(const std::string& pgp_id,const std::string& text,std::string& outstr) -// { -// return PGPHandler::encryptTextToString(RsPgpId(pgp_id),text,outstr) ; -// } - -std::string pgp_pwd_callback(void * /*hook*/, const char *uid_title, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad,bool *cancelled) -{ -#ifdef GPG_DEBUG2 - fprintf(stderr, "pgp_pwd_callback() called.\n"); -#endif - std::string password; - RsServer::notify()->askForPassword(uid_title, uid_hint, prev_was_bad, password,cancelled) ; - - return password ; -} - -void AuthGPG::init( - const std::string& path_to_public_keyring, - const std::string& path_to_secret_keyring, - const std::string& path_to_trustdb, - const std::string& pgp_lock_file) -{ - if(_instance != NULL) - { - exit(); - std::cerr << "AuthGPG::init() called twice!" << std::endl ; - } - -// if(cb) PGPHandler::setPassphraseCallback(cb);else - PGPHandler::setPassphraseCallback(pgp_pwd_callback); - _instance = new AuthGPG( path_to_public_keyring, - path_to_secret_keyring, - path_to_trustdb, pgp_lock_file ); -} - -void AuthGPG::exit() -{ - if(_instance) - { - _instance->fullstop(); - delete _instance; - _instance = nullptr; - } -} - -AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) - :p3Config(), - PGPHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), - gpgMtxService("AuthGPG-service"), - gpgMtxEngine("AuthGPG-engine"), - gpgMtxData("AuthGPG-data"), - mStoreKeyTime(0), - gpgKeySelected(false), - _force_sync_database(false), - mCount(0) -{ - start("AuthGPG"); -} - -/* This function is called when retroshare is first started - * to get the list of available GPG certificates. - * This function should only return certs for which - * the private(secret) keys are available. - * - * returns false if GnuPG is not available. - */ -//bool AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list &ids) -//{ -// std::list pids ; -// -// PGPHandler::availableGPGCertificatesWithPrivateKeys(pids) ; -// -// for(std::list::const_iterator it(pids.begin());it!=pids.end();++it) -// ids.push_back( (*it).toStdString() ) ; -// -// /* return false if there are no private keys */ -// return !ids.empty(); -//} - -/* You can initialise Retroshare with - * (a) load existing certificate. - * (b) a new certificate. - * - * This function must be called successfully (return == 1) - * before anything else can be done. (except above fn). - */ -int AuthGPG::GPGInit(const RsPgpId &ownId) -{ -#ifdef DEBUG_AUTHGPG - std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId.toStdString() << std::endl; -#endif - - mOwnGpgId = RsPgpId(ownId); - - //force the validity of the private key. When set to unknown, it caused signature and text encryptions bugs - privateTrustCertificate(ownId, 5); - updateOwnSignatureFlag(mOwnGpgId) ; - -#ifdef DEBUG_AUTHGPG - std::cerr << "AuthGPG::GPGInit finished." << std::endl; -#endif - - return 1; -} - - AuthGPG::~AuthGPG() -{ -} - -void AuthGPG::threadTick() -{ - rstime::rs_usleep(100 * 1000); //100 msec - - /// every 100 milliseconds - processServices(); - - /// every ten seconds - if (++mCount >= 100 || _force_sync_database) { - RsStackMutex stack(gpgMtxService); ///******* LOCKED ****** - - /// The call does multiple things at once: - /// - checks whether the keyring has changed in memory - /// - checks whether the keyring has changed on disk. - /// - merges/updates according to status. - /// - PGPHandler::syncDatabase() ; - mCount = 0; - _force_sync_database = false ; - }//if (++count >= 100 || _force_sync_database) -} - -void AuthGPG::processServices() -{ - AuthGPGOperation *operation = NULL; - AuthGPGService *service = NULL; - - { - RsStackMutex stack(gpgMtxService); /******* LOCKED ******/ - - std::list::iterator serviceIt; - for (serviceIt = services.begin(); serviceIt != services.end(); ++serviceIt) { - operation = (*serviceIt)->getGPGOperation(); - if (operation) { - service = *serviceIt; - break; - } - } - } /******* UNLOCKED ******/ - - if (operation == NULL) { - /* nothing to do */ - return; - } - - if (service == NULL) { - /* huh ? */ - delete operation; - return; - } - - AuthGPGOperationLoadOrSave *loadOrSave = dynamic_cast(operation); - if (loadOrSave) - { - if (loadOrSave->m_load) - { - /* process load operation */ - - - /* load the certificate */ - - - /* don't bother loading - if we already have the certificate */ - if (isGPGId(loadOrSave->m_certGpgId)) - { -#ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Skipping load - already have it" << std::endl; -#endif - } - else - { -#ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Process load operation" << std::endl; -#endif - std::string error_string ; - RsPgpId pgp_id ; - LoadCertificateFromString(loadOrSave->m_certGpg, pgp_id,error_string); - loadOrSave->m_certGpgId = pgp_id; - } - - - - } else { - /* process save operation */ - -#ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Process save operation" << std::endl; -#endif - - /* save the certificate to string */ - /***** - * #define DISABLE_CERTIFICATE_SEND 1 - ****/ - - loadOrSave->m_certGpg = SaveCertificateToString(loadOrSave->m_certGpgId,true); - -#ifdef GPG_DEBUG - std::cerr << "Certificate for: " << loadOrSave->m_certGpgId << " is: "; - std::cerr << std::endl; - std::cerr << loadOrSave->m_certGpg; - std::cerr << std::endl; -#endif - - } - - service->setGPGOperation(loadOrSave); - } - else - { -#ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Unknown operation" << std::endl; -#endif - } - - delete operation; -} - -bool AuthGPG::DoOwnSignature(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl, std::string reason /* = "" */) -{ - return PGPHandler::SignDataBin(mOwnGpgId,data,datalen,(unsigned char *)buf_sigout,outl,false,reason) ; -} - - -/* import to GnuPG and other Certificates */ -bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint) -{ - return PGPHandler::VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ; -} - -bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id) -{ - return PGPHandler::parseSignature((unsigned char*)sig,siglen,issuer_id) ; -} - -bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id) -{ - return PGPHandler::exportGPGKeyPair(fname,exported_id) ; -} - -bool AuthGPG::exportIdentityToString( - std::string& data, const RsPgpId& pgpId, bool includeSignatures, - std::string& errorMsg ) -{ - return PGPHandler::exportGPGKeyPairToString( - data, pgpId, includeSignatures, errorMsg); -} - -bool AuthGPG::importProfile(const std::string& fname,RsPgpId& imported_id,std::string& import_error) -{ - return PGPHandler::importGPGKeyPair(fname,imported_id,import_error) ; -} - -bool AuthGPG::importProfileFromString(const std::string &data, RsPgpId &gpg_id, std::string &import_error) -{ - return PGPHandler::importGPGKeyPairFromString(data, gpg_id, import_error); -} - -bool AuthGPG::active() -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - return gpgKeySelected; -} - -bool AuthGPG::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) -{ - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ - - return PGPHandler::GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString) ; -} - -/**** These Two are common */ -std::string AuthGPG::getGPGName(const RsPgpId& id,bool *success) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - const PGPCertificateInfo *info = getCertificateInfo(id) ; - - if(info != NULL) - { - if(success != NULL) *success = true ; - return info->_name ; - } - else - { - if(success != NULL) *success = false ; - return "[Unknown PGP Cert name]" ; - } -} - -/**** These Two are common */ -std::string AuthGPG::getGPGEmail(const RsPgpId& id,bool *success) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - const PGPCertificateInfo *info = getCertificateInfo(id) ; - - if(info != NULL) - { - if(success != NULL) *success = true ; - return info->_email ; - } - else - { - if(success != NULL) *success = false ; - return "[Unknown PGP Cert email]" ; - } -} - -/**** GPG versions ***/ - -const RsPgpId& AuthGPG::getGPGOwnId() -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - return mOwnGpgId ; -} - -std::string AuthGPG::getGPGOwnName() -{ - return getGPGName(mOwnGpgId) ; -} - -bool AuthGPG::getGPGAllList(std::list &ids) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - PGPHandler::getGPGFilteredList(ids) ; - - return true; -} -const PGPCertificateInfo *AuthGPG::getCertInfoFromStdString(const std::string& pgp_id) const -{ - try - { - return PGPHandler::getCertificateInfo(RsPgpId(pgp_id)) ; - } - catch(std::exception& e) - { - std::cerr << "(EE) exception raised while constructing a PGP certificate from id \"" << pgp_id << "\": " << e.what() << std::endl; - return NULL ; - } -} -bool AuthGPG::haveSecretKey(const RsPgpId& id) const -{ - return PGPHandler::haveSecretKey(id) ; -} -bool AuthGPG::isKeySupported(const RsPgpId& id) const -{ - const PGPCertificateInfo *pc = getCertificateInfo(id) ; - - if(pc == NULL) - return false ; - - return !(pc->_flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM) ; -} - -bool AuthGPG::getGPGDetails(const RsPgpId& pgp_id, RsPeerDetails &d) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - const PGPCertificateInfo *pc = PGPHandler::getCertificateInfo(pgp_id) ; - - if(pc == NULL) - return false ; - - const PGPCertificateInfo& cert(*pc) ; - - d.id.clear() ; - d.gpg_id = pgp_id ; - d.name = cert._name; - d.lastUsed = cert._time_stamp; - d.email = cert._email; - d.trustLvl = cert._trustLvl; - d.validLvl = cert._trustLvl; - d.ownsign = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE; - d.gpgSigners.clear() ; - - for(std::set::const_iterator it(cert.signers.begin());it!=cert.signers.end();++it) - d.gpgSigners.push_back( *it ) ; - - d.fpr = cert._fpr ; - d.accept_connection = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION; - d.hasSignedMe = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME; - - return true; -} - -bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - return PGPHandler::getGPGFilteredList(list,filter) ; -} - -static bool filter_Validity(const PGPCertificateInfo& /*info*/) { return true ; } //{ return info._validLvl >= PGPCertificateInfo::GPGME_VALIDITY_MARGINAL ; } -static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } -static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } - -bool AuthGPG::getGPGValidList(std::list &ids) -{ - return getGPGFilteredList(ids,&filter_Validity); -} - -bool AuthGPG::getGPGAcceptedList(std::list &ids) -{ - return getGPGFilteredList(ids,&filter_Accepted); -} - -bool AuthGPG::getGPGSignedList(std::list &ids) -{ - return getGPGFilteredList(ids,&filter_OwnSigned); -} - -// bool AuthGPG::getCachedGPGCertificate(const RsPgpId &id, std::string &certificate) -// { -// RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ -// #ifdef LIMIT_CERTIFICATE_SIZE -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),false) ; -// #else -// certificate = PGPHandler::SaveCertificateToString(RsPgpId(id),true) ; -// #endif -// -// // #ifdef LIMIT_CERTIFICATE_SIZE -// // std::string cleaned_key ; -// // if(PGPKeyManagement::createMinimalKey(certificate,cleaned_key)) -// // certificate = cleaned_key ; -// // #endif -// -// return certificate.length() > 0 ; -// } - -/***************************************************************** - * Loading and Saving Certificates - this has to - * be able to handle both openpgp and X509 certificates. - * - * X509 are passed onto AuthSSL, OpenPGP are passed to gpgme. - * - */ - - -/* SKTAN : do not know how to use std::string id */ - std::string AuthGPG::SaveCertificateToString(const RsPgpId &id,bool include_signatures) - { - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ - - return PGPHandler::SaveCertificateToString(id,include_signatures) ; - } -/* import to GnuPG and other Certificates */ -bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string) -{ - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ - - if(PGPHandler::LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string)) - { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; - return true ; - } - - return false ; -} - -/* import to GnuPG and other Certificates */ -bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string) -{ - RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/ - - if(PGPHandler::LoadCertificateFromString(str,gpg_id,error_string)) - { - updateOwnSignatureFlag(gpg_id,mOwnGpgId) ; - return true ; - } - - return false ; -} - -/***************************************************************** - * Auth...? Signing, Revoke, Trust are all done at - * the PGP level.... - * - * Only Signing of SSL is done at setup. - * Auth should be done... ?? not sure - * maybe - * - */ - - -/*************************************/ - -/* These take PGP Ids */ -bool AuthGPG::AllowConnection(const RsPgpId& gpg_id, bool accept) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::AllowConnection(" << gpg_id << ")" << std::endl; -#endif - - /* Was a "Reload Certificates" here -> be shouldn't be needed -> and very expensive, try without. */ - { - RsStackMutex stack(gpgMtxData); - PGPHandler::setAcceptConnexion(gpg_id,accept) ; - } - - IndicateConfigChanged(); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, accept ? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); - - return true; -} - -/* These take PGP Ids */ -bool AuthGPG::SignCertificateLevel0(const RsPgpId &id) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl; -#endif - - return privateSignCertificate(id) ; -} - -bool AuthGPG::RevokeCertificate(const RsPgpId &id) -{ - /* remove unused parameter warnings */ - (void) id; - -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::RevokeCertificate(" << id << ") not implemented yet" << std::endl; -#endif - - return false; -} - -bool AuthGPG::TrustCertificate(const RsPgpId& id, int trustlvl) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl; -#endif - return privateTrustCertificate(id, trustlvl) ; -} - -bool AuthGPG::encryptDataBin(const RsPgpId& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) -{ - return PGPHandler::encryptDataBin(RsPgpId(pgp_id),data,datalen,sign,signlen) ; -} - -bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) -{ - return PGPHandler::decryptDataBin(mOwnGpgId,data,datalen,sign,signlen) ; -} -bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen, std::string reason /*= ""*/) -{ - return DoOwnSignature(data, datalen, sign, signlen, reason); -} - -bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) -{ - return VerifySignature(data, datalen, sign, signlen, withfingerprint); -} - -/* Sign/Trust stuff */ - -int AuthGPG::privateSignCertificate(const RsPgpId &id) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - int ret = PGPHandler::privateSignCertificate(mOwnGpgId,id) ; - _force_sync_database = true ; - return ret ; -} - -/* revoke the signature on Certificate */ -int AuthGPG::privateRevokeCertificate(const RsPgpId &/*id*/) -{ - //RsStackMutex stack(gpgMtx); /******* LOCKED ******/ - std::cerr << __PRETTY_FUNCTION__ << ": not implemented!" << std::endl; - - return 0; -} - -int AuthGPG::privateTrustCertificate(const RsPgpId& id, int trustlvl) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - // csoler: Why are we not allowing this when the peer is not in the accepted peers list?? - // The trust level is only a user-defined property that has nothing to - // do with the fact that we allow connections or not. - - if(!isGPGAccepted(id)) - return 0; - - int res = PGPHandler::privateTrustCertificate(id,trustlvl) ; - _force_sync_database = true ; - return res ; -} - -// -----------------------------------------------------------------------------------// -// -------------------------------- Config functions ------------------------------ // -// -----------------------------------------------------------------------------------// -// -RsSerialiser *AuthGPG::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - return rss ; -} - -bool AuthGPG::saveList(bool& cleanup, std::list& lst) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::saveList() called" << std::endl ; -#endif - std::list ids ; - getGPGAcceptedList(ids) ; // needs to be done before the lock - - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - cleanup = true ; - - // Now save config for network digging strategies - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - - for (std::list::const_iterator it(ids.begin()); it != ids.end(); ++it) - if((*it) != mOwnGpgId) // skip our own id. - { - RsTlvKeyValue kv; - kv.key = (*it).toStdString() ; -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::saveList() called (it->second) : " << (it->second) << std::endl ; -#endif - kv.value = "TRUE"; - vitem->tlvkvs.pairs.push_back(kv) ; - } - lst.push_back(vitem); - - return true; -} - -bool AuthGPG::loadList(std::list& load) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl; -#endif - - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - /* load the list of accepted gpg keys */ - std::list::iterator it; - for(it = load.begin(); it != load.end(); ++it) - { - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - if(vitem) - { -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::loadList() General Variable Config Item:" << std::endl; - vitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - std::list::iterator kit; - for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - if (kit->key != mOwnGpgId.toStdString()) - PGPHandler::setAcceptConnexion(RsPgpId(kit->key), (kit->value == "TRUE")); - } - delete (*it); - } - load.clear() ; - return true; -} - -bool AuthGPG::addService(AuthGPGService *service) -{ - RsStackMutex stack(gpgMtxService); /********* LOCKED *********/ - - if (std::find(services.begin(), services.end(), service) != services.end()) { - /* it exists already! */ - return false; - } - - services.push_back(service); - return true; -} - - diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h deleted file mode 100644 index 4fe76194c..000000000 --- a/libretroshare/src/pqi/authgpg.h +++ /dev/null @@ -1,303 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: authgpg.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2009 by Raghu Dev R. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/**** - * Here's GPG policy : - * By default, all pgpg keys imported via a RS user (make friend and accept friend action) are signed at level 0. - * All signed keys by RS are set to be trusted marginally. You can change it to full or no trust in the friend profile - * For a key to be marginaly valid, it has to be signed by one fully trusted key, or at least by 3 marginally trusted keys. - * All keys that have at least marginal validity are designed as valid in RS. They are shown in the RS gui in order to be signed. - * If there is no validity then the key is not shown. - */ - -#ifndef RS_GPG_AUTH_HEADER -#define RS_GPG_AUTH_HEADER - -#include "util/rsthreads.h" -#include "pqi/p3cfgmgr.h" -#include "pgp/pgphandler.h" - -#define MAX_GPG_SIGNATURE_SIZE 4096 - -struct RsPeerDetails; - -/*! - * gpgcert is the identifier for a person. - * It is a wrapper class for a OpenPGP certificate. - */ - -class AuthGPGOperation -{ -public: - explicit AuthGPGOperation(void *userdata) - { - m_userdata = userdata; - } - virtual ~AuthGPGOperation() {} - -public: - void *m_userdata; -}; - -class AuthGPGOperationLoadOrSave : public AuthGPGOperation -{ -public: - AuthGPGOperationLoadOrSave(bool load, const RsPgpId &gpgId, const std::string &gpgCert, void *userdata) - : AuthGPGOperation(userdata) - { - m_load = load; - if (m_load) { - m_certGpg = gpgCert; - m_certGpgId = gpgId; - } else { - m_certGpgId = gpgId; - } - } - -public: - bool m_load; - RsPgpId m_certGpgId; // set for save & load. - std::string m_certGpg; // set for load -}; - -class AuthGPGService -{ -public: - AuthGPGService() {} - ~AuthGPGService() {} - - virtual AuthGPGOperation *getGPGOperation() = 0; - virtual void setGPGOperation(AuthGPGOperation *operation) = 0; -}; - -class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler -{ -public: - static void init(const std::string& path_to_pubring, - const std::string& path_to_secring, - const std::string& path_to_trustdb, - const std::string& pgp_lock_file); - - static void exit(); - static AuthGPG *getAuthGPG() { return _instance ; } - - /** - * @param ids list of gpg certificate ids (note, not the actual certificates) - */ - //virtual bool availableGPGCertificatesWithPrivateKeys(std::list &ids); - - /*********************************************************************************/ - /************************* STAGE 1 ***********************************************/ - /*********************************************************************************/ - /***** - * STAGE 1: Initialisation.... As we are switching to OpenPGP the init functions - * will be different. Just move the initialisation functions over.... - * - * As GPGMe requires external calls to the GPG executable, which could potentially - * be expensive, We'll want to cache the GPG keys in this class. - * This should be done at initialisation, and saved in a map. - * (see storage at the end of the class) - * - ****/ - virtual bool active(); - - // /* Initialize */ - // virtual bool InitAuth (); - // virtual bool CloseAuth(); - - /* Init by generating new Own PGP Cert, or selecting existing PGP Cert */ - - virtual int GPGInit(const RsPgpId &ownId); - virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - - /*********************************************************************************/ - /************************* STAGE 3 ***********************************************/ - /*********************************************************************************/ - /***** - * STAGE 3: These are some of the most commonly used functions in Retroshare. - * - * More commonly used functions. - * - * provide access to details in cache list. - * - ****/ - virtual std::string getGPGName(const RsPgpId &pgp_id,bool *success = NULL); - virtual std::string getGPGEmail(const RsPgpId &pgp_id,bool *success = NULL); - - /* PGP web of trust management */ - virtual const RsPgpId& getGPGOwnId(); - virtual std::string getGPGOwnName(); - - //virtual std::string getGPGOwnEmail(); - virtual bool isKeySupported(const RsPgpId &id) const ; - virtual bool haveSecretKey(const RsPgpId &id) const ; - virtual bool getGPGDetails(const RsPgpId& id, RsPeerDetails &d); - virtual bool getGPGAllList(std::list &ids); - virtual bool getGPGValidList(std::list &ids); - virtual bool getGPGAcceptedList(std::list &ids); - virtual bool getGPGSignedList(std::list &ids); - virtual bool importProfile(const std::string& filename,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool importProfileFromString(const std::string& data,RsPgpId& gpg_id,std::string& import_error) ; - virtual bool exportProfile(const std::string& filename,const RsPgpId& gpg_id) ; - virtual bool exportIdentityToString( - std::string& data, const RsPgpId& pgpId, bool includeSignatures, - std::string& errorMsg ); - - virtual bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) ; - - /*********************************************************************************/ - /************************* STAGE 4 ***********************************************/ - /*********************************************************************************/ - /***** - * STAGE 4: Loading and Saving Certificates. (Strings and Files) - * - ****/ - virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string); - virtual bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string); - virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ; - - // Cached certificates. - //bool getCachedGPGCertificate(const RsPgpId &id, std::string &certificate); - - /*********************************************************************************/ - /************************* STAGE 6 ***********************************************/ - /*********************************************************************************/ - /***** - * STAGE 6: Authentication, Trust and Signing. - * - * This is some of the harder functions, but they should have been - * done in gpgroot already. - * - ****/ - virtual bool AllowConnection(const RsPgpId &gpg_id, bool accept); - - virtual bool SignCertificateLevel0(const RsPgpId &id); - virtual bool RevokeCertificate(const RsPgpId &id); /* Particularly hard - leave for later */ - - virtual bool TrustCertificate(const RsPgpId& id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust - - /*********************************************************************************/ - /************************* STAGE 7 ***********************************************/ - /*********************************************************************************/ - /***** - * STAGE 7: Signing Data. - * - * There should also be Encryption Functions... (do later). - * - ****/ - virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = ""); - virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const PGPFingerprintType& withfingerprint); - virtual bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id); - - virtual bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen); - virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen); - - virtual bool decryptTextFromFile( std::string& text,const std::string& filename); - virtual bool encryptTextToFile (const std::string& text,const std::string& filename); - -// virtual bool decryptTextFromString( std::string& encrypted_text,std::string& clear_string); -// virtual bool encryptTextToString (const std::string& pgp_id,const std::string& clear_text,std::string& encrypted_string); - - bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; - - //END of PGP public functions - - /* GPG service */ - virtual bool addService(AuthGPGService *service) ; - - // This is for debug purpose only. Don't use it !! - static void setAuthGPG_debug(AuthGPG *auth_gpg) { _instance = auth_gpg ; } - - protected: - AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); - virtual ~AuthGPG(); - - /*****************************************************************/ - /*********************** p3config ******************************/ - /* Key Functions to be overloaded for Full Configuration */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual bool loadList(std::list& load); - /*****************************************************************/ - -private: - // Gets the certificate pointer and returns NULL if the string is invalid, or the - // cert was not found. - // - const PGPCertificateInfo *getCertInfoFromStdString(const std::string& ) const; - - /* SKTAN */ - //void showData(gpgme_data_t dh); - //void createDummyFriends(void); //NYI - - /* Internal functions */ - bool DoOwnSignature(const void *, unsigned int, void *, unsigned int *, std::string reason); - bool VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const PGPFingerprintType& withfingerprint); - - /* Sign/Trust stuff */ - int privateSignCertificate(const RsPgpId &id); - int privateRevokeCertificate(const RsPgpId &id); /* revoke the signature on Certificate */ - int privateTrustCertificate(const RsPgpId& id, int trustlvl); - - // store all keys in map mKeyList to avoid calling gpgme exe repeatedly - //bool storeAllKeys(); - //bool storeAllKeys_tick(); - - // Not used anymore - // bool updateTrustAllKeys_locked(); - - /* GPG service */ - void processServices(); - - bool printAllKeys_locked(); - bool printOwnKeys_locked(); - - void threadTick() override; /// @see RsTickingThread - -private: - - static AuthGPG *instance_gpg; // pointeur vers le singleton - - RsMutex gpgMtxService; - RsMutex gpgMtxEngine; - - /* Below is protected via the mutex */ - - // gpgme_engine_info_t INFO; - // gpgme_ctx_t CTX; - - RsMutex gpgMtxData; - /* Below is protected via the mutex */ - - rstime_t mStoreKeyTime; - - RsPgpId mOwnGpgId; - bool gpgKeySelected; - bool _force_sync_database ; - uint32_t mCount ; - - std::list services ; - - static AuthGPG *_instance ; -}; - -#endif diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc deleted file mode 100644 index eb89a1ed5..000000000 --- a/libretroshare/src/pqi/authssl.cc +++ /dev/null @@ -1,1851 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: authssl.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif // WINDOWS_SYS - -#include "authssl.h" -#include "sslfns.h" - -#include "pqinetwork.h" -#include "authgpg.h" -#include "rsitems/rsconfigitems.h" -#include "util/rsdebug.h" -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "pgp/pgpkeyutil.h" - -#include "retroshare/rspeers.h" // for RsPeerDetails structure -#include "retroshare/rsids.h" // for RsPeerDetails structure -#include "rsserver/p3face.h" - -/******************** notify of new Cert **************************/ - -#include -#include - -#include - -/* SSL connection diagnostic */ - -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_UNKNOWN = 0x00 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_OK = 0x01 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_NOT_VALID = 0x02 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN = 0x03 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR = 0x04 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE = 0x05 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_CERTIFICATE_MISSING = 0x06 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED = 0x07 ; -//const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_KEY_ALGORITHM_NOT_ACCEPTED = 0x08 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE = 0x09 ; -const uint32_t RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION = 0x0a ; - -/**** - * #define AUTHSSL_DEBUG 1 - ***/ - -static pthread_mutex_t* mutex_buf = nullptr; - -struct CRYPTO_dynlock_value -{ - pthread_mutex_t mutex; -}; - -# if OPENSSL_VERSION_NUMBER < 0x10100000L -/** - * OpenSSL locking function. - * - * @param mode lock mode - * @param n lock number - * @param file source file name - * @param line source file line number - * @return none - */ -static void locking_function(int mode, int n, const char */*file*/, int /*line*/) -{ - if (mode & CRYPTO_LOCK) { - pthread_mutex_lock(&mutex_buf[n]); - } else { - pthread_mutex_unlock(&mutex_buf[n]); - } -} -#endif - -# if OPENSSL_VERSION_NUMBER < 0x10100000L -/** - * OpenSSL uniq id function. - * - * @return thread id - */ -static unsigned long id_function(void) -{ -#if defined( WINDOWS_SYS) && !defined(WIN_PTHREADS_H) - return (unsigned long) pthread_self().p; -#else - return (unsigned long) pthread_self(); -#endif -} -#endif - -# if OPENSSL_VERSION_NUMBER < 0x10100000L -/** - * OpenSSL allocate and initialize dynamic crypto lock. - * - * @param file source file name - * @param line source file line number - */ -static struct CRYPTO_dynlock_value *dyn_create_function(const char */*file*/, int /*line*/) -{ - struct CRYPTO_dynlock_value *value; - - value = (struct CRYPTO_dynlock_value*) rs_malloc(sizeof(struct CRYPTO_dynlock_value)); - if (!value) - return NULL; - - pthread_mutex_init(&value->mutex, NULL); - - return value; -} -#endif - -# if OPENSSL_VERSION_NUMBER < 0x10100000L -/** - * OpenSSL dynamic locking function. - * - * @param mode lock mode - * @param l lock structure pointer - * @param file source file name - * @param line source file line number - * @return none - */ -static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char */*file*/, int /*line*/) -{ - if (mode & CRYPTO_LOCK) { - pthread_mutex_lock(&l->mutex); - } else { - pthread_mutex_unlock(&l->mutex); - } -} -#endif - -# if OPENSSL_VERSION_NUMBER < 0x10100000L -/** - * OpenSSL destroy dynamic crypto lock. - * - * @param l lock structure pointer - * @param file source file name - * @param line source file line number - * @return none - */ -static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char */*file*/, int /*line*/) -{ - pthread_mutex_destroy(&l->mutex); - free(l); -} -#endif - -/** - * Initialize TLS library. - * - * @return true on success, false on error - */ -bool tls_init() -{ - /* static locks area */ - mutex_buf = (pthread_mutex_t*) rs_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); - if (mutex_buf == NULL) - return false; - - for (int i = 0; i < CRYPTO_num_locks(); i++) { - pthread_mutex_init(&mutex_buf[i], NULL); - } -# if OPENSSL_VERSION_NUMBER < 0x10100000L - /* static locks callbacks */ - CRYPTO_set_locking_callback(locking_function); - CRYPTO_set_id_callback(id_function); - /* dynamic locks callbacks */ - CRYPTO_set_dynlock_create_callback(dyn_create_function); - CRYPTO_set_dynlock_lock_callback(dyn_lock_function); - CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); -#endif - return true; -} - -/** - * Cleanup TLS library. - * - * @return 0 - */ -void tls_cleanup() -{ - CRYPTO_set_dynlock_create_callback(NULL); - CRYPTO_set_dynlock_lock_callback(NULL); - CRYPTO_set_dynlock_destroy_callback(NULL); - - CRYPTO_set_locking_callback(NULL); - CRYPTO_set_id_callback(NULL); - - if (mutex_buf != NULL) { - for (int i = 0; i < CRYPTO_num_locks(); i++) { - pthread_mutex_destroy(&mutex_buf[i]); - } - free(mutex_buf); - mutex_buf = NULL; - } -} - -/*static*/ AuthSSL& AuthSSL::instance() -{ - static AuthSSLimpl mInstance; - return mInstance; -} - -AuthSSL* AuthSSL::getAuthSSL() { return &instance(); } - -AuthSSL::~AuthSSL() = default; - - -/********************************************************************************/ -/********************************************************************************/ -/********************* Cert Search / Add / Remove **************************/ -/********************************************************************************/ -/********************************************************************************/ - -static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx); - -std::string RsX509Cert::getCertName(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return getX509CNString(x509.cert_info->subject); -#else - return getX509CNString(X509_get_subject_name(&x509)); -#endif -} - -std::string RsX509Cert::getCertLocation(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return getX509LocString(x509.cert_info->subject); -#else - return getX509LocString(X509_get_subject_name(&x509)); -#endif -} - -std::string RsX509Cert::getCertOrg(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return getX509OrgString(x509.cert_info->subject); -#else - return getX509OrgString(X509_get_subject_name(&x509)); -#endif -} - -/*static*/ RsPgpId RsX509Cert::getCertIssuer(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return RsPgpId(getX509CNString(x509.cert_info->issuer)); -#else - return RsPgpId(getX509CNString(X509_get_issuer_name(&x509))); -#endif -} - -/*static*/ std::string RsX509Cert::getCertIssuerString(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return getX509CNString(x509.cert_info->issuer); -#else - return getX509CNString(X509_get_issuer_name(&x509)); -#endif -} - -/*static*/ RsPeerId RsX509Cert::getCertSslId(const X509& x509) -{ - RsPeerId sslid; - return getX509id(const_cast(&x509), sslid) ? sslid : RsPeerId(); -} - -/************************************************************************ - * - * - * CODE IS DIVIDED INTO - * - * 1) SSL Setup. - * 3) Cert Access. - * 4) Cert Sign / Verify. - * 5) Cert Authentication - * 2) Cert Add / Remove - * 6) Cert Storage - */ - -/********************************************************************************/ -/********************************************************************************/ -/********************* Cert Search / Add / Remove **************************/ -/********************************************************************************/ -/********************************************************************************/ - - -AuthSSLimpl::AuthSSLimpl() : - p3Config(), sslctx(nullptr), mOwnCert(nullptr), sslMtx("AuthSSL"), - mOwnPrivateKey(nullptr), mOwnPublicKey(nullptr), init(0) {} - -AuthSSLimpl::~AuthSSLimpl() -{ - RS_STACK_MUTEX(sslMtx); - - SSL_CTX_free(sslctx); - X509_free(mOwnCert); - - EVP_PKEY_free(mOwnPrivateKey); - EVP_PKEY_free(mOwnPublicKey); - - for(auto pcert: mCerts) - X509_free(pcert.second); -} - -bool AuthSSLimpl::active() { return init; } - -int AuthSSLimpl::InitAuth( - const char* cert_file, const char* priv_key_file, const char* passwd, - std::string locationName ) -{ - /* single call here si don't need to invoke mutex yet */ - static int initLib = 0; - if (!initLib) - { - initLib = 1; - - if (!tls_init()) { - return 0; - } - - SSL_load_error_strings(); - SSL_library_init(); - } - - - if (init == 1) - { - std::cerr << "AuthSSLimpl::InitAuth already initialized." << std::endl; - return 1; - } - - if ((cert_file == NULL) || - (priv_key_file == NULL) || - (passwd == NULL)) - { - //fprintf(stderr, "sslroot::initssl() missing parameters!\n"); - return 0; - } - - - // actions_to_seed_PRNG(); - RAND_seed(passwd, strlen(passwd)); - - std::cerr << "SSL Library Init!" << std::endl; - - // setup connection method - sslctx = SSL_CTX_new(SSLv23_method()); - SSL_CTX_set_options(sslctx,SSL_OP_NO_SSLv3) ; - - //SSL_OP_SINGLE_DH_USE CVE-2016-0701 - //https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_set_options.html - //If "strong" primes were used, it is not strictly necessary to generate a new DH key during each handshake but it is also recommended. SSL_OP_SINGLE_DH_USE should therefore be enabled whenever temporary/ephemeral DH parameters are used. - //SSL_CTX_set_options() adds the options set via bitmask in options to ctx. Options already set before are not cleared! - SSL_CTX_set_options(sslctx,SSL_OP_SINGLE_DH_USE) ; - - - // Setup cipher lists: - // - // std::string cipherString = "HIGH:!DSS:!aNULL:!3DES"; - // std::string cipherString = "DEFAULT"; - // - // The current cipher list asks in priority for EDH which provides PFS. However EDH needs proper - // parameters to be set on the server side, so if we're a client for a RS instance that has no DH params, - // the connection will be refused. So we happend the HIGH cipher suite just after. In oder to force - // PFS, at the risk of not always connecting, one should use: - // - // std::string cipherString = "kEDH:HIGH:!DSS:!aNULL:!3DES"; - // - // The following safe primes are 2048/4096 bits long. Should be enough. - // - // std::string dh_prime_2048_dec = "30651576830996935311378276950670996791883170963804289256203421500259588715033040934547350194073369837229137842804826417332761673984632102152477971341551955103053338169949165519208562998954887445690136488713010579430413255432398961330773637820158790237012997356731669148258317860643591694814197514454546928317578771868379525705082166818553884557266645700906836702542808787791878865135741211056957383668479369231868698451684633965462539374994559481908068730787128654626819903401038534403722014687647173327537458614224702967073490136394698912372792187651228785689025073104374674728645661275001416541267543884923191810923"; - // - //Not used (should be here: /libretroshare/src/gxstunnel/p3gxstunnel.cc:1131 - //std::string dh_prime_2048_hex = "B3B86A844550486C7EA459FA468D3A8EFD71139593FE1C658BBEFA9B2FC0AD2628242C2CDC2F91F5B220ED29AAC271192A7374DFA28CDDCA70252F342D0821273940344A7A6A3CB70C7897A39864309F6CAC5C7EA18020EF882693CA2C12BB211B7BA8367D5A7C7252A5B5E840C9E8F081469EBA0B98BCC3F593A4D9C4D5DF539362084F1B9581316C1F80FDAD452FD56DBC6B8ED0775F596F7BB22A3FE2B4753764221528D33DB4140DE58083DB660E3E105123FC963BFF108AC3A268B7380FFA72005A1515C371287C5706FFA6062C9AC73A9B1A6AC842C2764CDACFC85556607E86611FDF486C222E4896CDF6908F239E177ACC641FCBFF72A758D1C10CBB" ; - - std::string dh_prime_4096_hex = "A6F5777292D9E6BB95559C9124B9119E6771F11F2048C8FE74F4E8140494520972A087EF1D60B73894F1C5D509DD15D96CF379E9DDD46CE51B748085BACB440D915565782C73AF3A9580CE788441D1DA4D114E3D302CAB45A061ABCFC1F7E9200AE019CB923B77E096FA9377454A16FFE91D86535FF23E075B3E714F785CD7606E9CBD9D06F01CAFA2271883D649F13ABE170D714F6B6EC064C5BF35C4F4BDA5EF5ED5E70D5DC78F1AC1CDC04EEDAE8ADD65C4A9E27368E0B2C8595DD7626D763BFFB15364B3CCA9FCE814B9226B35FE652F4B041F0FF6694D6A482B0EF48CA41163D083AD2DE7B7A068BB05C0453E9D008551C7F67993A3EF2C4874F0244F78C4E0997BD31AB3BD88446916B499B2513DD5BA002063BD38D2CE55D29D071399D5CEE99458AF6FDC104A61CA3FACDAC803CBDE62B4C0EAC946D0E12F05CE9E94497110D64E611D957423B8AA412D84EC83E6E70E0977A31D6EE056D0527D4667D7242A77C9B679D191562E4026DA9C35FF85666296D872ED548E0FFE1A677FCC373C1F490CAB4F53DFD8735C0F1DF02FEAD824A217FDF4E3404D38A5BBC719C6622630FCD34F6F1968AF1B66A4AB1A9FCF653DA96EB3A42AF6FCFEA0547B8F314A527C519949007D7FA1726FF3D33EC46393B0207AA029E5EA574BDAC94D78894B22A2E3303E65A3F820DF57DB44951DE4E973C016C57F7A242D0BC53BC563AF" ; - - std::string cipherString = "kEDH+HIGH:!DSS:!aNULL:!3DES:!EXP"; - - SSL_CTX_set_cipher_list(sslctx, cipherString.c_str()); - - DH* dh = DH_new(); - int codes = 0; - bool pfs_enabled = true ; - - if (dh) - { -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - BN_hex2bn(&dh->p,dh_prime_4096_hex.c_str()) ; - BN_hex2bn(&dh->g,"5") ; -#else - BIGNUM *pp=NULL,*gg=NULL ; - - BN_hex2bn(&pp,dh_prime_4096_hex.c_str()) ; - BN_hex2bn(&gg,"5"); - - DH_set0_pqg(dh,pp,NULL,gg) ; -#endif - - std::cout.flush() ; - -#ifndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK - if(DH_check(dh, &codes) && codes == 0) - SSL_CTX_set_tmp_dh(sslctx, dh); - else - pfs_enabled = false; -#else // ndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK - /* DH_check(...) is not strictly necessary and on Android devices it - * takes at least one minute which is untolerable there */ - SSL_CTX_set_tmp_dh(sslctx, dh); -#endif // ndef RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK - } - else - pfs_enabled = false ; - - // certificates (Set Local Server Certificate). - FILE *ownfp = RsDirUtil::rs_fopen(cert_file, "r"); - if (ownfp == NULL) - { - std::cerr << "Couldn't open Own Certificate!" << std::endl; - return -1; - } - - // get xPGP certificate. - X509 *x509 = PEM_read_X509(ownfp, NULL, NULL, NULL); - - fclose(ownfp); - - if (x509 == NULL) - { - std::cerr << "AuthSSLimpl::InitAuth() PEM_read_X509() Failed"; - std::cerr << std::endl; - return -1; - } - - int result = SSL_CTX_use_certificate(sslctx, x509); - -#if OPENSSL_VERSION_NUMBER >= 0x10101000L - if(result != 1) - { - // In debian Buster, openssl security level is set to 2 which preclude the use of SHA1, originally used to sign RS certificates. - // As a consequence, on these systems, locations created with RS previously to Jan.2020 will not start unless we revert the - // security level to a value of 1. - - int save_sec = SSL_CTX_get_security_level(sslctx); - SSL_CTX_set_security_level(sslctx,1); - result = SSL_CTX_use_certificate(sslctx, x509); - - if(result == 1) - { - std::cerr << std::endl; - std::cerr << " Your Retroshare certificate uses low security settings that are incompatible " << std::endl; - std::cerr << "(WW) with current security level " << save_sec << " of the OpenSSL library. Retroshare will still start " << std::endl; - std::cerr << " (with security level set to 1), but you should probably create a new location." << std::endl; - std::cerr << std::endl; - } - } -#endif - - if(result != 1) - { - std::cerr << "(EE) Cannot use your Retroshare certificate. Some error occured in SSL_CTX_use_certificate()" << std::endl; - return -1; - } - - mOwnPublicKey = X509_get_pubkey(x509); - - // get private key - FILE *pkfp = RsDirUtil::rs_fopen(priv_key_file, "rb"); - if (pkfp == NULL) - { - std::cerr << "Couldn't Open PrivKey File!" << std::endl; - CloseAuth(); - return -1; - } - - mOwnPrivateKey = PEM_read_PrivateKey(pkfp, NULL, NULL, (void *) passwd); - fclose(pkfp); - - if (mOwnPrivateKey == NULL) - { - std::cerr << "AuthSSLimpl::InitAuth() PEM_read_PrivateKey() Failed"; - std::cerr << std::endl; - return -1; - } - SSL_CTX_use_PrivateKey(sslctx, mOwnPrivateKey); - - if (1 != SSL_CTX_check_private_key(sslctx)) - { - std::cerr << "Issues With Private Key! - Doesn't match your Cert" << std::endl; - std::cerr << "Check your input key/certificate:" << std::endl; - std::cerr << priv_key_file << " & " << cert_file; - std::cerr << std::endl; - CloseAuth(); - return -1; - } - - RsPeerId mownidstr ; - - if (!getX509id(x509, mownidstr)) - { - std::cerr << "AuthSSLimpl::InitAuth() getX509id() Failed"; - std::cerr << std::endl; - - /* bad certificate */ - CloseAuth(); - return -1; - } - mOwnId = mownidstr ; - - assert(!mOwnId.isNull()) ; - - /* Check that Certificate is Ok ( virtual function ) - * for gpg/pgp or CA verification - */ - - if (!validateOwnCertificate(x509, mOwnPrivateKey)) - { - std::cerr << "AuthSSLimpl::InitAuth() validateOwnCertificate() Failed"; - std::cerr << std::endl; - - /* bad certificate */ - CloseAuth(); - exit(1); - return -1; - } - - - // enable verification of certificates (PEER) - // and install verify callback. - SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER | - SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - verify_x509_callback); - - std::cerr << "SSL Verification Set" << std::endl; - - mOwnCert = x509; - - std::cerr << "Inited SSL context: " << std::endl; - std::cerr << " Certificate: " << mOwnId << std::endl; - std::cerr << " cipher list: " << cipherString << std::endl; - std::cerr << " PFS enabled: " << (pfs_enabled?"YES":"NO") ; - if(codes > 0) - { - std::cerr << " (reason: " ; - if(codes & DH_CHECK_P_NOT_PRIME ) std::cerr << "Not a prime number, " ; - if(codes & DH_CHECK_P_NOT_SAFE_PRIME) std::cerr << "Not a safe prime number, " ; - if(codes & DH_UNABLE_TO_CHECK_GENERATOR) std::cerr << "unable to check generator, " ; - if(codes & DH_NOT_SUITABLE_GENERATOR) std::cerr << "not a suitable generator" ; - std::cerr << ")" << std::endl; - } - else - std::cerr << std::endl; - - mOwnLocationName = locationName; - - init = 1; - return 1; -} - -/* Dummy function to be overloaded by real implementation */ -bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) -{ - (void) pkey; /* remove unused parameter warning */ - - uint32_t diagnostic ; - - /* standard authentication */ - if (!AuthX509WithGPG(x509,true,diagnostic)) - { - std::cerr << "Validate Own certificate ERROR: diagnostic = " << diagnostic << std::endl; - return false; - } - return true; -} - -bool AuthSSLimpl::CloseAuth() -{ - tls_cleanup(); - -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::CloseAuth()"; - std::cerr << std::endl; -#endif - SSL_CTX_free(sslctx); - - // clean up private key.... - // remove certificates etc -> opposite of initssl. - init = 0; - return 1; -} - -/* Context handling */ -SSL_CTX *AuthSSLimpl::getCTX() -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::getCTX()"; - std::cerr << std::endl; -#endif - return sslctx; -} - -const RsPeerId& AuthSSLimpl::OwnId() -{ -#ifdef AUTHSSL_DEBUG -// std::cerr << "AuthSSLimpl::OwnId()" << std::endl; -#endif - return mOwnId; -} - -std::string AuthSSLimpl::getOwnLocation() -{ return mOwnLocationName; } - -std::string AuthSSLimpl::SaveOwnCertificateToString() -{ return saveX509ToPEM(mOwnCert); } - -/********************************************************************************/ -/********************************************************************************/ -/********************* Cert Search / Add / Remove **************************/ -/********************************************************************************/ -/********************************************************************************/ - -bool AuthSSLimpl::SignData(std::string input, std::string &sign) -{ - return SignData(input.c_str(), input.length(), sign); -} - -bool AuthSSLimpl::SignData(const void *data, const uint32_t len, std::string &sign) -{ - - RsStackMutex stack(sslMtx); /***** STACK LOCK MUTEX *****/ - - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - unsigned int signlen = EVP_PKEY_size(mOwnPrivateKey); - unsigned char signature[signlen] ; - memset(signature,0,signlen) ; - - if (0 == EVP_SignInit(mdctx, EVP_sha1())) - { - std::cerr << "EVP_SignInit Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if (0 == EVP_SignUpdate(mdctx, data, len)) - { - std::cerr << "EVP_SignUpdate Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if (0 == EVP_SignFinal(mdctx, signature, &signlen, mOwnPrivateKey)) - { - std::cerr << "EVP_SignFinal Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - EVP_MD_CTX_destroy(mdctx); - - sign.clear(); - for(uint32_t i = 0; i < signlen; i++) - { - rs_sprintf_append(sign, "%02x", (uint32_t) (signature[i])); - } - - return true; -} - -bool AuthSSLimpl::SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen) -{ - return SignDataBin(input.c_str(), input.length(), sign, signlen); -} - -bool AuthSSLimpl::SignDataBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int *signlen) -{ - RsStackMutex stack(sslMtx); /***** STACK LOCK MUTEX *****/ - return SSL_SignDataBin(data, len, sign, signlen, mOwnPrivateKey); -} - - -bool AuthSSLimpl::VerifySignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen, const RsPeerId& sslId) -{ - /* find certificate. - * if we don't have - fail. - */ - - RsStackMutex stack(sslMtx); /***** STACK LOCK MUTEX *****/ - - /* find the peer */ - X509* peercert; - if (sslId == mOwnId) peercert = mOwnCert; - else if (!locked_FindCert(sslId, &peercert)) - { - std::cerr << "VerifySignBin() no peer" << std::endl; - return false; - } - - return SSL_VerifySignBin(data, len, sign, signlen, peercert); -} - -bool AuthSSLimpl::VerifyOwnSignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen) -{ return SSL_VerifySignBin(data, len, sign, signlen, mOwnCert); } - - -/********************************************************************************/ -/********************************************************************************/ -/********************* Sign and Auth with GPG **************************/ -/********************************************************************************/ -/********************************************************************************/ - -/* Note these functions don't need Mutexes - - * only using GPG functions - which lock themselves - */ - -X509 *AuthSSLimpl::SignX509ReqWithGPG(X509_REQ *req, long /*days*/) -{ - /* Transform the X509_REQ into a suitable format to - * generate DIGEST hash. (for SSL to do grunt work) - */ - -#define SERIAL_RAND_BITS 64 - - //const EVP_MD *digest = EVP_sha1(); - EVP_PKEY *tmppkey; - X509 *x509 = X509_new(); - if (x509 == NULL) - { - std::cerr << "AuthSSLimpl::SignX509Req() FAIL" << std::endl; - return NULL; - } - - //long version = 0x00; - unsigned long chtype = MBSTRING_UTF8; - X509_NAME *issuer_name = X509_NAME_new(); - X509_NAME_add_entry_by_txt(issuer_name, "CN", chtype, - (unsigned char *) AuthGPG::getAuthGPG()->getGPGOwnId().toStdString().c_str(), -1, -1, 0); -/**** - X509_NAME_add_entry_by_NID(issuer_name, 48, 0, - (unsigned char *) "email@email.com", -1, -1, 0); - X509_NAME_add_entry_by_txt(issuer_name, "O", chtype, - (unsigned char *) "org", -1, -1, 0); - X509_NAME_add_entry_by_txt(x509_name, "L", chtype, - (unsigned char *) "loc", -1, -1, 0); -****/ - - std::cerr << "AuthSSLimpl::SignX509Req() Issuer name: " << AuthGPG::getAuthGPG()->getGPGOwnId().toStdString() << std::endl; - -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 - static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; -#else -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_001 - static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0001 ; -#else - static const uint64_t CERTIFICATE_SERIAL_NUMBER = RS_CERTIFICATE_VERSION_NUMBER_06_0000 ; -#endif -#endif - - BIGNUM *btmp = BN_new(); - BN_set_word(btmp,CERTIFICATE_SERIAL_NUMBER) ; - -#ifdef OLD_CODE - if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) - { - std::cerr << "AuthSSLimpl::SignX509Req() rand FAIL" << std::endl; - return NULL; - } -#endif - ASN1_INTEGER *serial = ASN1_INTEGER_new(); - - if (!BN_to_ASN1_INTEGER(btmp, serial)) - { - std::cerr << "AuthSSLimpl::SignX509Req() asn1 FAIL" << std::endl; - return NULL; - } - BN_free(btmp); - - if (!X509_set_serialNumber(x509, serial)) - { - std::cerr << "AuthSSLimpl::SignX509Req() serial FAIL" << std::endl; - return NULL; - } - ASN1_INTEGER_free(serial); - - /* Generate SUITABLE issuer name. - * Must reference OpenPGP key, that is used to verify it - */ - - if (!X509_set_issuer_name(x509, issuer_name)) - { - std::cerr << "AuthSSLimpl::SignX509Req() issue FAIL" << std::endl; - return NULL; - } - X509_NAME_free(issuer_name); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - // (does not leak the key creation date to the outside anymore. for more privacy) - ASN1_TIME_set(X509_get_notBefore(x509), 0); - ASN1_TIME_set(X509_get_notAfter(x509), 0); -#else - // NEW code, set validity time between 2010 and 2110 (remember to change it when, if OpenSSL check it by default. ;) ) - // (does not leak the key creation date to the outside anymore. for more privacy) - if (!ASN1_TIME_set_string(X509_getm_notBefore(x509), "20100101000000Z")) - { - RsErr() << __PRETTY_FUNCTION__ << " Set notBefore FAIL" << std::endl; - return NULL; - } - if (!ASN1_TIME_set_string(X509_getm_notAfter(x509), "21100101000000Z")) - { - RsErr() << __PRETTY_FUNCTION__ << " Set notAfter FAIL" << std::endl; - return NULL; - } -#endif - - if (!X509_set_subject_name(x509, X509_REQ_get_subject_name(req))) - { - std::cerr << "AuthSSLimpl::SignX509Req() sub FAIL" << std::endl; - return NULL; - } - - tmppkey = X509_REQ_get_pubkey(req); - if (!tmppkey || !X509_set_pubkey(x509,tmppkey)) - { - std::cerr << "AuthSSLimpl::SignX509Req() pub FAIL" << std::endl; - return NULL; - } - - std::cerr << "X509 Cert, prepared for signing" << std::endl; - - /*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/ - // - // The code has been copied in order to use the PGP signing instead of supplying the - // private EVP_KEY to ASN1_sign(), which would be another alternative. - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF; - X509_ALGOR *algor1 = x509->cert_info->signature; - X509_ALGOR *algor2 = x509->sig_alg; - ASN1_BIT_STRING *signature = x509->signature; - X509_CINF *data = x509->cert_info; -#else - const X509_ALGOR *algor1 = X509_get0_tbs_sigalg(x509) ; - const X509_ALGOR *algor2 = NULL ; - - const ASN1_BIT_STRING *tmp_signature = NULL ; - - X509_get0_signature(&tmp_signature,&algor2,x509); - - ASN1_BIT_STRING *signature = const_cast(tmp_signature); -#endif - //EVP_PKEY *pkey = NULL; -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_002 - const EVP_MD *type = EVP_sha256(); -#else - const EVP_MD *type = EVP_sha1(); -#endif - - EVP_MD_CTX *ctx = EVP_MD_CTX_create(); - int inl=0; - X509_ALGOR *a; - - /* FIX ALGORITHMS */ - - a = const_cast(algor1); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - ASN1_TYPE_free(a->parameter); - a->parameter=ASN1_TYPE_new(); - a->parameter->type=V_ASN1_NULL; - - ASN1_OBJECT_free(a->algorithm); - a->algorithm=OBJ_nid2obj(type->pkey_type); -#else - X509_ALGOR_set0(a,OBJ_nid2obj(EVP_MD_pkey_type(type)),V_ASN1_NULL,NULL); -#endif - - a = const_cast(algor2); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - ASN1_TYPE_free(a->parameter); - a->parameter=ASN1_TYPE_new(); - a->parameter->type=V_ASN1_NULL; - - ASN1_OBJECT_free(a->algorithm); - a->algorithm=OBJ_nid2obj(type->pkey_type); -#else - X509_ALGOR_set0(a,OBJ_nid2obj(EVP_MD_pkey_type(type)),V_ASN1_NULL,NULL); -#endif - - - std::cerr << "Algorithms Fixed" << std::endl; - - unsigned int sigoutl=2048; // hashoutl; //EVP_PKEY_size(pkey); - unsigned char *buf_sigout=(unsigned char *)OPENSSL_malloc((unsigned int)sigoutl); - - /* input buffer */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - inl=i2d(data,NULL); - unsigned char *buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl); - - if(buf_in == NULL) - { - sigoutl=0; - fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n"); - return NULL ; - } - unsigned char *p=buf_in; // This because i2d modifies the pointer after writing to it. - i2d(data,&p); -#else - unsigned char *buf_in=NULL; - inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info -#endif - -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003 - if((buf_in == NULL) || (buf_sigout == NULL)) - { - sigoutl=0; - fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n"); - goto err; - } - std::cerr << "Buffers Allocated" << std::endl; - - /* NOW Sign via GPG Functions */ - if (!AuthGPG::getAuthGPG()->SignDataBin(buf_in, inl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) - { - sigoutl = 0; - goto err; - } -#else - unsigned int hashoutl=EVP_MD_size(type); - unsigned char *buf_hashout=(unsigned char *)OPENSSL_malloc((unsigned int)hashoutl); - - if((buf_hashout == NULL) || (buf_sigout == NULL)) - { - hashoutl=0; - sigoutl=0; - fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)\n"); - goto err; - } - std::cerr << "Buffers Allocated" << std::endl; - - /* data in buf_in, ready to be hashed */ - EVP_DigestInit_ex(ctx,type, NULL); - EVP_DigestUpdate(ctx,(unsigned char *)buf_in,inl); - if (!EVP_DigestFinal(ctx,(unsigned char *)buf_hashout, (unsigned int *)&hashoutl)) - { - hashoutl=0; - fprintf(stderr, "AuthSSLimpl::SignX509Req: ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB)\n"); - goto err; - } - - std::cerr << "Digest Applied: len: " << hashoutl << std::endl; - - /* NOW Sign via GPG Functions */ - if (!AuthGPG::getAuthGPG()->SignDataBin(buf_hashout, hashoutl, buf_sigout, (unsigned int *) &sigoutl,"AuthSSLimpl::SignX509ReqWithGPG()")) - { - sigoutl = 0; - goto err; - } -#endif - - std::cerr << "Buffer Sizes: in: " << inl; -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003 - std::cerr << " HashOut: " << hashoutl; -#endif - std::cerr << " SigOut: " << sigoutl; - std::cerr << std::endl; - - //passphrase = "NULL"; - - std::cerr << "Signature done: len:" << sigoutl << std::endl; - - /* ADD Signature back into Cert... Signed!. */ - - if (signature->data != NULL) OPENSSL_free(signature->data); - signature->data=buf_sigout; - buf_sigout=NULL; - signature->length=sigoutl; - /* In the interests of compatibility, I'll make sure that - * the bit string has a 'not-used bits' value of 0 - */ - signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); - signature->flags|=ASN1_STRING_FLAG_BITS_LEFT; - - std::cerr << "Certificate Complete" << std::endl; - - EVP_MD_CTX_destroy(ctx) ; - - // debug - // { - // int pkey_nid = OBJ_obj2nid(x509->sig_alg->algorithm); - // const char* sslbuf = OBJ_nid2ln(pkey_nid); - // std::cerr << "Signature hash algorithm: " << sslbuf << std::endl; - // } - - return x509; - - /* XXX CLEANUP */ - err: - /* cleanup */ - if(buf_in != NULL) - OPENSSL_free(buf_in) ; -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_003 - if(buf_hashout != NULL) - OPENSSL_free(buf_hashout) ; -#endif - if(buf_sigout != NULL) - OPENSSL_free(buf_sigout) ; - std::cerr << "GPGAuthMgr::SignX509Req() err: FAIL" << std::endl; - - return NULL; -} - - -bool AuthSSLimpl::AuthX509WithGPG(X509 *x509,bool verbose, uint32_t& diagnostic) -{ - RsPgpId issuer = RsX509Cert::getCertIssuer(*x509); - RsPeerDetails pd; - if (!AuthGPG::getAuthGPG()->getGPGDetails(issuer, pd)) - { - RsInfo() << __PRETTY_FUNCTION__ << " X509 NOT authenticated : " - << "AuthGPG::getAuthGPG()->getGPGDetails(" << issuer - << ",...) returned false." << std::endl; - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN; - return false; - } - else - Dbg3() << __PRETTY_FUNCTION__ << " issuer: " << issuer << " found" - << std::endl; - - /* verify GPG signature */ - /*** NOW The Manual signing bit (HACKED FROM asn1/a_sign.c) ***/ - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - int (*i2d)(X509_CINF*, unsigned char**) = i2d_X509_CINF; - ASN1_BIT_STRING* signature = x509->signature; - X509_CINF* data = x509->cert_info; -#else - const ASN1_BIT_STRING* signature = nullptr; - const X509_ALGOR* algor2 = nullptr; - X509_get0_signature(&signature,&algor2,x509); -#endif - - uint32_t certificate_version = getX509RetroshareCertificateVersion(x509); - - EVP_MD_CTX* ctx = EVP_MD_CTX_create(); - int inl = 0; - - const unsigned char* signed_data = nullptr; - uint32_t signed_data_length = 0; - - /* input buffer */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - inl = i2d(data, nullptr); - unsigned char* buf_in = static_cast( - OPENSSL_malloc(static_cast(inl)) ); - unsigned char* p = nullptr; -#else - unsigned char* buf_in = nullptr; - inl=i2d_re_X509_tbs(x509,&buf_in) ; // this does the i2d over x509->cert_info -#endif - - if(buf_in == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ - << " ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE)" << std::endl; - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_MALLOC_ERROR ; - return false; - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - p = buf_in; - i2d(data,&p); -#endif - - { // this scope is to avoid cross-initialization jumps to err. - - const Sha1CheckSum sha1 = RsDirUtil::sha1sum( - buf_in, static_cast(inl) ); - - if(certificate_version < RS_CERTIFICATE_VERSION_NUMBER_07_0001) - { - /* If the certificate belongs to 0.6 version, we hash it here, and - * then re-hash the hash it in the PGP signature */ - signed_data = sha1.toByteArray(); - signed_data_length = sha1.SIZE_IN_BYTES; - } - else - { - signed_data = buf_in ; - signed_data_length = static_cast(inl); - } - - /* NOW check sign via GPG Functions */ - - Dbg2() << __PRETTY_FUNCTION__ - << " verifying the PGP Key signature with finger print: " - << pd.fpr << std::endl; - - /* Take a early look at signature parameters. In particular we dont - * accept signatures with unsecure hash algorithms */ - - PGPSignatureInfo signature_info ; - PGPKeyManagement::parseSignature( - signature->data, static_cast(signature->length), - signature_info ); - - if(signature_info.signature_version != PGP_PACKET_TAG_SIGNATURE_VERSION_V4) - { - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_VERSION; - goto err; - } - - std::string sigtypestring; - - switch(signature_info.signature_type) - { - case PGP_PACKET_TAG_SIGNATURE_TYPE_BINARY_DOCUMENT: break; - case PGP_PACKET_TAG_SIGNATURE_TYPE_STANDALONE_SIG: /*fallthrough*/ - case PGP_PACKET_TAG_SIGNATURE_TYPE_CANONICAL_TEXT: /*fallthrough*/ - case PGP_PACKET_TAG_SIGNATURE_TYPE_UNKNOWN: /*fallthrough*/ - default: - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE_TYPE; - goto err; - } - - switch(signature_info.public_key_algorithm) - { - case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_ES: /*fallthrough*/ - case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_S: - sigtypestring = "RSA"; - break ; - case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_DSA: - sigtypestring = "DSA"; - break ; - case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_RSA_E: /*fallthrough*/ - case PGP_PACKET_TAG_PUBLIC_KEY_ALGORITHM_UNKNOWN: /*fallthrough*/ - default: - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED ; - goto err ; - } - - switch(signature_info.hash_algorithm) - { - case PGP_PACKET_TAG_HASH_ALGORITHM_SHA1: - sigtypestring += "+SHA1"; - break; - case PGP_PACKET_TAG_HASH_ALGORITHM_SHA256: - sigtypestring += "+SHA256"; - break; - case PGP_PACKET_TAG_HASH_ALGORITHM_SHA512: - sigtypestring += "+SHA512"; - break; - // We dont accept signatures with unknown or weak hash algorithms. - case PGP_PACKET_TAG_HASH_ALGORITHM_MD5: /*fallthrough*/ - case PGP_PACKET_TAG_HASH_ALGORITHM_UNKNOWN: /*fallthrough*/ - default: - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_HASH_ALGORITHM_NOT_ACCEPTED; - goto err; - } - - // passed, verify the signature itself - - if (!AuthGPG::getAuthGPG()->VerifySignBin( - signed_data, signed_data_length, signature->data, - static_cast(signature->length), pd.fpr )) - { - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE; - goto err; - } - - if(verbose) - RsInfo() << " Verified: " << sigtypestring - << " signature of certificate sslId: " - << RsX509Cert::getCertSslId(*x509) - << ", Version " << std::hex << certificate_version << std::dec - << " using PGP key " << pd.fpr << " " << pd.name << std::endl; - } - - EVP_MD_CTX_destroy(ctx); - - OPENSSL_free(buf_in); - - diagnostic = RS_SSL_HANDSHAKE_DIAGNOSTIC_OK; - - return true; - -err: // TODO: this label is very short and might collide every easly - RsInfo() << __PRETTY_FUNCTION__ << " X509 PGP authentication failed with " - << "diagnostic: " << diagnostic << std::endl; - - if(buf_in) OPENSSL_free(buf_in); - - return false; -} - -/********************************************************************************/ -/********************************************************************************/ -/**************************** encrypt / decrypt fns ****************************/ -/********************************************************************************/ -/********************************************************************************/ - -static int verify_x509_callback(int preverify_ok, X509_STORE_CTX *ctx) -{ return AuthSSL::instance().VerifyX509Callback(preverify_ok, ctx); } - -int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) -{ - /* According to OpenSSL documentation must return 0 if verification failed - * and 1 if succeded (aka can continue connection). - * About preverify_ok OpenSSL documentation doesn't tell which value is - * passed to the first callback in the authentication chain, it just says - * that the result of previous step is passed down, so I have tested it - * and we get passed 0 always so in our case as there is no other - * verifications step vefore we ignore it completely */ - - constexpr int verificationFailed = 0; - constexpr int verificationSuccess = 1; - - using Evt_t = RsAuthSslConnectionAutenticationEvent; - std::unique_ptr ev = std::unique_ptr(new Evt_t); - - X509* x509Cert = X509_STORE_CTX_get_current_cert(ctx); - if(!x509Cert) - { - std::string errMsg = "Cannot get certificate! OpenSSL error: " + - std::to_string(X509_STORE_CTX_get_error(ctx)) + " depth: " + - std::to_string(X509_STORE_CTX_get_error_depth(ctx)); - - RsErr() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - - return verificationFailed; - } - - RsPeerId sslId = RsX509Cert::getCertSslId(*x509Cert); - std::string sslCn = RsX509Cert::getCertIssuerString(*x509Cert); - - RsPgpId pgpId(sslCn); - - if(sslCn.length() == RsPgpFingerprint::SIZE_IN_BYTES*2) - { - RsPgpFingerprint pgpFpr(sslCn); // we also accept fingerprint format, so that in the future we can switch to fingerprints without backward compatibility issues - - if(!pgpFpr.isNull()) - pgpId = PGPHandler::pgpIdFromFingerprint(pgpFpr); // in the future, we drop PGP ids and keep the fingerprint all along - } - - if(sslId.isNull()) - { - std::string errMsg = "x509Cert has invalid sslId!"; - - RsInfo() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - - if(rsEvents) - { - ev->mSslCn = sslCn; - ev->mSslId = sslId; - ev->mPgpId = pgpId; - ev->mErrorMsg = errMsg; - ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; - - rsEvents->postEvent(std::move(ev)); - } - - return verificationFailed; - } - - if(pgpId.isNull()) - { - std::string errMsg = "x509Cert has invalid pgpId! sslCn >>>" + sslCn + - "<<<"; - - RsInfo() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - - if(rsEvents) - { - ev->mSslId = sslId; - ev->mSslCn = sslCn; - ev->mErrorMsg = errMsg; - ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; - - rsEvents->postEvent(std::move(ev)); - } - - return verificationFailed; - } - - bool isSslOnlyFriend = false; - - // For SSL only friends (ones added through short invites) we check that the fingerprint - // in the key (det.gpg_id) matches the one of the handshake. - { - RsPeerDetails det; - - if(rsPeers->getPeerDetails(sslId,det)) - isSslOnlyFriend = det.skip_pgp_signature_validation; - - if(det.skip_pgp_signature_validation && det.gpg_id != pgpId)// in the future, we should compare fingerprints instead - { - std::string errorMsg = "Peer " + sslId.toStdString() + " trying to connect with issuer ID " + pgpId.toStdString() - + " whereas key ID " + det.gpg_id.toStdString() + " was expected! Refusing connection." ; - - RsErr() << __PRETTY_FUNCTION__ << errorMsg << std::endl; - - if(rsEvents) - { - ev->mSslId = sslId; - ev->mSslCn = sslCn; - ev->mPgpId = pgpId; - ev->mErrorMsg = errorMsg; - ev->mErrorCode = RsAuthSslError::MISMATCHED_PGP_ID; - rsEvents->postEvent(std::move(ev)); - } - - return verificationFailed; - } - } - - uint32_t auth_diagnostic; - if(!isSslOnlyFriend && !AuthX509WithGPG(x509Cert,true, auth_diagnostic)) - { - std::string errMsg = "Certificate was rejected because PGP " - "signature verification failed with diagnostic: " - + std::to_string(auth_diagnostic) + " certName: " + - RsX509Cert::getCertName(*x509Cert) + " sslId: " + - RsX509Cert::getCertSslId(*x509Cert).toStdString() + - " issuerString: " + RsX509Cert::getCertIssuerString(*x509Cert); - - RsInfo() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - - if(rsEvents) - { - ev->mSslId = sslId; - ev->mSslCn = sslCn; - ev->mPgpId = pgpId; - - switch(auth_diagnostic) - { - case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: - ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND; - break; - case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: - ev->mErrorCode = RsAuthSslError::PGP_SIGNATURE_VALIDATION_FAILED; - break; - default: - ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; - break; - } - - ev->mErrorMsg = errMsg; - rsEvents->postEvent(std::move(ev)); - } - - if (auth_diagnostic == RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN) - RsServer::notify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, pgpId.toStdString(), sslCn, sslId.toStdString()); /* notify Connect Attempt */ - - return verificationFailed; - } -#ifdef AUTHSSL_DEBUG - std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <getGPGOwnId() && !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) - { - std::string errMsg = "Connection attempt signed by PGP key id: " + - pgpId.toStdString() + " not accepted because it is not" - " a friend."; - - Dbg1() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - - if(rsEvents) - { - ev->mSslId = sslId; - ev->mSslCn = sslCn; - ev->mPgpId = pgpId; - ev->mErrorMsg = errMsg; - ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND; - rsEvents->postEvent(std::move(ev)); - } - - RsServer::notify()->AddPopupMessage(RS_POPUP_CONNECT_ATTEMPT, pgpId.toStdString(), sslCn, sslId.toStdString()); /* notify Connect Attempt */ - - return verificationFailed; - } - - LocalStoreCert(x509Cert); - - RsInfo() << __PRETTY_FUNCTION__ << " authentication successfull for " - << "sslId: " << sslId << " isSslOnlyFriend: " << isSslOnlyFriend - << std::endl; - - return verificationSuccess; -} - -bool AuthSSLimpl::parseX509DetailsFromFile( const std::string& certFilePath, RsPeerId& certId, RsPgpId& issuer, std::string& location ) -{ - FILE* tmpfp = RsDirUtil::rs_fopen(certFilePath.c_str(), "r"); - if(!tmpfp) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed to open Certificate File: " - << certFilePath << std::endl; - return false; - } - - // get xPGP certificate. - X509* x509 = PEM_read_X509(tmpfp, nullptr, nullptr, nullptr); - fclose(tmpfp); - - if(!x509) - { - RsErr() << __PRETTY_FUNCTION__ << " PEM_read_X509 failed!" << std::endl; - return false; - } - - uint32_t diagnostic = 0; - - if(!AuthX509WithGPG(x509,false, diagnostic)) - { - RsErr() << __PRETTY_FUNCTION__ << " AuthX509WithGPG failed with " - << "diagnostic: " << diagnostic << std::endl; - - X509_free(x509); - return false; - } - - certId = RsX509Cert::getCertSslId(*x509); - issuer = RsX509Cert::getCertIssuer(*x509); - location = RsX509Cert::getCertLocation(*x509); - - X509_free(x509); - - if(certId.isNull() || issuer.isNull()) return false; - - return true; -} - - -/********************************************************************************/ -/********************************************************************************/ -/**************************** encrypt / decrypt fns ****************************/ -/********************************************************************************/ -/********************************************************************************/ - - -bool AuthSSLimpl::encrypt(void *&out, int &outlen, const void *in, int inlen, const RsPeerId& peerId) -{ - RS_STACK_MUTEX(sslMtx); - - /*const*/ EVP_PKEY* public_key = nullptr; - if (peerId == mOwnId) { public_key = mOwnPublicKey; } - else - { - auto it = mCerts.find(peerId); - - if (it == mCerts.end()) - { - RsErr() << __PRETTY_FUNCTION__ << " public key not found." << std::endl; - return false; - } - else public_key = const_cast( RsX509Cert::getPubKey(*it->second) ); - } - - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - int eklen, net_ekl; - unsigned char *ek; - unsigned char iv[EVP_MAX_IV_LENGTH]; - int out_currOffset = 0; - int out_offset = 0; - - int max_evp_key_size = EVP_PKEY_size(public_key); - ek = (unsigned char*)rs_malloc(max_evp_key_size); - - if(ek == NULL) - return false ; - - const EVP_CIPHER *cipher = EVP_aes_128_cbc(); - int cipher_block_size = EVP_CIPHER_block_size(cipher); - int size_net_ekl = sizeof(net_ekl); - - int max_outlen = inlen + cipher_block_size + EVP_MAX_IV_LENGTH + max_evp_key_size + size_net_ekl; - - // intialize context and send store encrypted cipher in ek - if(!EVP_SealInit(ctx, EVP_aes_128_cbc(), &ek, &eklen, iv, &public_key, 1)) { - free(ek); - return false; - } - - // now assign memory to out accounting for data, and cipher block size, key length, and key length val - out = (unsigned char*)rs_malloc(inlen + cipher_block_size + size_net_ekl + eklen + EVP_MAX_IV_LENGTH); - - if(out == NULL) - { - free(ek) ; - return false ; - } - net_ekl = htonl(eklen); - memcpy((unsigned char*)out + out_offset, &net_ekl, size_net_ekl); - out_offset += size_net_ekl; - - memcpy((unsigned char*)out + out_offset, ek, eklen); - out_offset += eklen; - - memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); - out_offset += EVP_MAX_IV_LENGTH; - - // now encrypt actual data - if(!EVP_SealUpdate(ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) { - free(ek); - free(out); - out = NULL; - return false; - } - - // move along to partial block space - out_offset += out_currOffset; - - // add padding - if(!EVP_SealFinal(ctx, (unsigned char*) out + out_offset, &out_currOffset)) { - free(ek); - free(out) ; - out = NULL; - return false; - } - - // move to end - out_offset += out_currOffset; - - // make sure offset has not gone passed valid memory bounds - if(out_offset > max_outlen) return false; - - // free encrypted key data - free(ek); - - EVP_CIPHER_CTX_free(ctx); - - outlen = out_offset; - - #ifdef DISTRIB_DEBUG - std::cerr << "Authssl::encrypt() finished with outlen : " << outlen << std::endl; - #endif - - return true; -} - -bool AuthSSLimpl::decrypt(void *&out, int &outlen, const void *in, int inlen) -{ - RsStackMutex stack(sslMtx); /******* LOCKED ******/ - - - -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::decrypt() called with inlen : " << inlen << std::endl; -#endif - //TODO : use ssl to decrypt the binary input buffer -// out = malloc(inlen); -// memcpy(out, in, inlen); -// outlen = inlen; - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - int eklen = 0, net_ekl = 0; - unsigned char iv[EVP_MAX_IV_LENGTH]; - int ek_mkl = EVP_PKEY_size(mOwnPrivateKey); - unsigned char *ek = (unsigned char*)malloc(ek_mkl); - - if(ek == NULL) - { - std::cerr << "(EE) Cannot allocate memory for " << ek_mkl << " bytes in " << __PRETTY_FUNCTION__ << std::endl; - return false ; - } - - int in_offset = 0, out_currOffset = 0; - int size_net_ekl = sizeof(net_ekl); - - if(size_net_ekl > inlen) { - free(ek); - return false; - } - - memcpy(&net_ekl, (unsigned char*)in, size_net_ekl); - eklen = ntohl(net_ekl); - in_offset += size_net_ekl; - - if(eklen > (inlen-in_offset)) { - free(ek); - return false; - } - - memcpy(ek, (unsigned char*)in + in_offset, eklen); - in_offset += eklen; - - if(EVP_MAX_IV_LENGTH > (inlen-in_offset)) { - free(ek); - return false; - } - - memcpy(iv, (unsigned char*)in + in_offset, EVP_MAX_IV_LENGTH); - in_offset += EVP_MAX_IV_LENGTH; - - const EVP_CIPHER* cipher = EVP_aes_128_cbc(); - - if(0 == EVP_OpenInit(ctx, cipher, ek, eklen, iv, mOwnPrivateKey)) { - free(ek); - return false; - } - - out = (unsigned char*)rs_malloc(inlen - in_offset); - - if(out == NULL) - { - free(ek) ; - return false ; - } - if(!EVP_OpenUpdate(ctx, (unsigned char*) out, &out_currOffset, (unsigned char*)in + in_offset, inlen - in_offset)) { - free(ek); - free(out) ; - out = NULL; - return false; - } - - //in_offset += out_currOffset; - outlen += out_currOffset; - - if(!EVP_OpenFinal(ctx, (unsigned char*)out + out_currOffset, &out_currOffset)) { - free(ek); - free(out) ; - out = NULL; - return false; - } - - outlen += out_currOffset; - - if(ek != NULL) - free(ek); - - EVP_CIPHER_CTX_free(ctx); - -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::decrypt() finished with outlen : " << outlen << std::endl; -#endif - - return true; -} - -/* Locked search -> internal help function */ -bool AuthSSLimpl::locked_FindCert(const RsPeerId& id, X509** cert) -{ - std::map::iterator it; - - if (mCerts.end() != (it = mCerts.find(id))) - { - *cert = it->second; - return true; - } - return false; -} - - -/* Remove Certificate */ - -bool AuthSSLimpl::RemoveX509(RsPeerId id) -{ - std::map::iterator it; - - RsStackMutex stack(sslMtx); /******* LOCKED ******/ - - if (mCerts.end() != (it = mCerts.find(id))) - { - X509* cert = it->second; - X509_free(cert); - mCerts.erase(it); - return true; - } - return false; -} - - -bool AuthSSLimpl::LocalStoreCert(X509* x509) -{ - //store the certificate in the local cert list - RsPeerId peerId ; - if(!getX509id(x509, peerId)) - { - std::cerr << "AuthSSLimpl::LocalStoreCert() Cannot retrieve peer id from certificate." << std::endl; -#ifdef AUTHSSL_DEBUG -#endif - return false; - } - - if(peerId.isNull()) - { - std::cerr << "AuthSSLimpl::LocalStoreCert(): invalid peer id \"" << peerId << "\"" << std::endl; - return false ; - } - - - RsStackMutex stack(sslMtx); /******* LOCKED ******/ - - if (peerId == mOwnId) - { -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::LocalStoreCert() not storing own certificate" << std::endl; -#endif - return false; - } - - /* do a search */ - std::map::iterator it; - - if (mCerts.end() != (it = mCerts.find(peerId))) - { - X509* cert = it->second; - - /* found something */ - /* check that they are exact */ - if (0 != X509_cmp(cert, x509)) - { - /* MAJOR ERROR */ - std::cerr << "ERROR : AuthSSLimpl::LocalStoreCert() got two ssl certificates with identical ids -> dropping second"; - std::cerr << std::endl; - return false; - } - /* otherwise - we have it already */ - return false; - } - -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::LocalStoreCert() storing certificate for " << peerId << std::endl; -#endif - mCerts[peerId] = X509_dup(x509); - - /* flag for saving config */ - IndicateConfigChanged(); - return true ; -} - - -/********************************************************************************/ -/********************************************************************************/ -/************************ Config Functions **********************************/ -/********************************************************************************/ -/********************************************************************************/ - - -RsSerialiser *AuthSSLimpl::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsGeneralConfigSerialiser()); - return rss ; -} - -bool AuthSSLimpl::saveList(bool& cleanup, std::list& lst) -{ - #ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::saveList() called" << std::endl ; - #endif - - RsStackMutex stack(sslMtx); /******* LOCKED ******/ - - cleanup = true ; - - // Now save config for network digging strategies - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - std::map::iterator mapIt; - for (mapIt = mCerts.begin(); mapIt != mCerts.end(); ++mapIt) { - if (mapIt->first == mOwnId) { - continue; - } - RsTlvKeyValue kv; - kv.key = mapIt->first.toStdString(); - #ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::saveList() called (mapIt->first) : " << (mapIt->first) << std::endl ; - #endif - kv.value = saveX509ToPEM(mapIt->second); - vitem->tlvkvs.pairs.push_back(kv) ; - } - lst.push_back(vitem); - - return true ; -} - -bool AuthSSLimpl::loadList(std::list& load) -{ - #ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::loadList() Item Count: " << load.size() << std::endl; - #endif - - /* load the list of accepted gpg keys */ - std::list::iterator it; - for(it = load.begin(); it != load.end(); ++it) { - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - - if(vitem) - { -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSLimpl::loadList() General Variable Config Item:" << std::endl; - vitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - std::list::iterator kit; - for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if (RsPeerId(kit->key) == mOwnId) { - continue; - } - - X509 *peer = loadX509FromPEM(kit->value); - /* authenticate it */ - uint32_t diagnos ; - if (peer && AuthX509WithGPG(peer,false,diagnos)) - LocalStoreCert(peer); - - X509_free(peer); - } - } - delete (*it); - } - load.clear() ; - return true; -} - -const EVP_PKEY*RsX509Cert::getPubKey(const X509& x509) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return x509.cert_info->key->pkey; -#else - return X509_get0_pubkey(&x509); -#endif -} diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h deleted file mode 100644 index ddd5dc86d..000000000 --- a/libretroshare/src/pqi/authssl.h +++ /dev/null @@ -1,261 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: authssl.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - - -#include -#include - -#include -#include - -#include "util/rsthreads.h" -#include "pqi/pqi_base.h" -#include "pqi/pqinetwork.h" -#include "pqi/p3cfgmgr.h" -#include "util/rsmemory.h" -#include "retroshare/rsevents.h" - -/** - * Functions to interact elegantly with X509 certificates, using this functions - * you can avoid annoying #ifdef *SSL_VERSION_NUMBER all around the code. - * Function names should be self descriptive. - */ -namespace RsX509Cert -{ -std::string getCertName(const X509& x509); -std::string getCertLocation(const X509& x509); -std::string getCertOrg(const X509& x509); -RsPgpId getCertIssuer(const X509& x509); -std::string getCertIssuerString(const X509& x509); -RsPeerId getCertSslId(const X509& x509); -const EVP_PKEY* getPubKey(const X509& x509); -}; - -/** - * This is an implementation of SSL certificate authentication with PGP - * signatures, instead of centralized certification authority. - */ -class AuthSSL -{ -public: - static AuthSSL& instance(); - - RS_DEPRECATED_FOR(AuthSSL::instance()) - static AuthSSL* getAuthSSL(); - - /* Initialisation Functions (Unique) */ - virtual bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) = 0; - - virtual bool active() = 0; - virtual int InitAuth( - const char* srvr_cert, const char* priv_key, const char* passwd, - std::string locationName ) = 0; - virtual bool CloseAuth() = 0; - - /*********** Overloaded Functions from p3AuthMgr **********/ - - /* get Certificate Id */ - virtual const RsPeerId& OwnId() = 0; - virtual std::string getOwnLocation() = 0; - - /* Load/Save certificates */ - virtual std::string SaveOwnCertificateToString() = 0; - - /* Sign / Encrypt / Verify Data */ - virtual bool SignData(std::string input, std::string &sign) = 0; - virtual bool SignData( - const void* data, const uint32_t len, std::string& sign ) = 0; - - virtual bool SignDataBin(std::string, unsigned char*, unsigned int*) = 0; - virtual bool SignDataBin( - const void*, uint32_t, unsigned char*, unsigned int* ) = 0; - virtual bool VerifyOwnSignBin( - const void*, uint32_t, unsigned char*, unsigned int ) = 0; - virtual bool VerifySignBin( - const void* data, const uint32_t len, unsigned char* sign, - unsigned int signlen, const RsPeerId& sslId ) = 0; - - /// return false if failed - virtual bool encrypt( - void*& out, int& outlen, const void* in, int inlen, - const RsPeerId& peerId ) = 0; - /// return false if failed - virtual bool decrypt(void*& out, int& outlen, const void* in, int inlen) = 0; - - virtual X509* SignX509ReqWithGPG(X509_REQ* req, long days) = 0; - - /** - * @brief Verify PGP signature correcteness on given X509 certificate - * Beware this doesn't check if the PGP signer is friend or not, just if the - * signature is valid! - * @param[in] x509 pointer ti the X509 certificate to check - * @param[out] diagnostic one of RS_SSL_HANDSHAKE_DIAGNOSTIC_* diagnostic - * codes - * @param[in] verbose if true, prints the authentication result to screen. - * @return true if correctly signed, false otherwise - */ - virtual bool AuthX509WithGPG( - X509* x509, - bool verbose, - uint32_t& diagnostic = RS_DEFAULT_STORAGE_PARAM(uint32_t) - ) = 0; - - /** - * @brief Callback provided to OpenSSL to authenticate connections - * This is the ultimate place where connection attempts get accepted - * if authenticated or refused if not authenticated. - * Emits @see RsAuthSslConnectionAutenticationEvent. - * @param preverify_ok passed by OpenSSL ignored as this call is the first - * in the authentication callback chain - * @param ctx OpenSSL connection context - * @return 0 if authentication failed, 1 if success see OpenSSL - * documentation - */ - virtual int VerifyX509Callback(int preverify_ok, X509_STORE_CTX* ctx) = 0; - - /// SSL specific functions used in pqissl/pqissllistener - virtual SSL_CTX* getCTX() = 0; - - /** - * This function parse X509 certificate from the file and return some - * verified informations, like ID and signer - * @return false on error, true otherwise - */ - virtual bool parseX509DetailsFromFile( - const std::string& certFilePath, RsPeerId& certId, RsPgpId& issuer, - std::string& location ) = 0; - - virtual ~AuthSSL(); - -protected: - AuthSSL() {} - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; - - -class AuthSSLimpl : public AuthSSL, public p3Config -{ -public: - - /** Initialisation Functions (Unique) */ - AuthSSLimpl(); - virtual ~AuthSSLimpl(); - - bool validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) override; - - bool active() override; - int InitAuth( const char *srvr_cert, const char *priv_key, - const char *passwd, std::string locationName ) - override; - - bool CloseAuth() override; - - /*********** Overloaded Functions from p3AuthMgr **********/ - - const RsPeerId& OwnId() override; - virtual std::string getOwnLocation() override; - - /* Load/Save certificates */ - virtual std::string SaveOwnCertificateToString() override; - - /* Sign / Encrypt / Verify Data */ - bool SignData(std::string input, std::string &sign) override; - bool SignData( - const void *data, const uint32_t len, std::string &sign) override; - - bool SignDataBin(std::string, unsigned char*, unsigned int*) override; - virtual bool SignDataBin( - const void*, uint32_t, unsigned char*, unsigned int*) override; - bool VerifyOwnSignBin( - const void*, uint32_t, unsigned char*, unsigned int) override; - virtual bool VerifySignBin( - const void *data, const uint32_t len, unsigned char *sign, - unsigned int signlen, const RsPeerId& sslId) override; - - bool encrypt( - void*& out, int& outlen, const void* in, int inlen, - const RsPeerId& peerId ) override; - bool decrypt(void *&out, int &outlen, const void *in, int inlen) override; - - virtual X509* SignX509ReqWithGPG(X509_REQ *req, long days) override; - - /// @see AuthSSL - bool AuthX509WithGPG(X509 *x509, bool verbose, uint32_t& auth_diagnostic) override; - - /// @see AuthSSL - int VerifyX509Callback(int preverify_ok, X509_STORE_CTX *ctx) override; - - /// @see AuthSSL - bool parseX509DetailsFromFile( - const std::string& certFilePath, RsPeerId& certId, - RsPgpId& issuer, std::string& location ) override; - - -/*****************************************************************/ -/*********************** p3config ******************************/ - /* Key Functions to be overloaded for Full Configuration */ - RsSerialiser* setupSerialiser() override; - bool saveList(bool &cleanup, std::list& ) override; - bool loadList(std::list& load) override; -/*****************************************************************/ - -public: - /* SSL specific functions used in pqissl/pqissllistener */ - SSL_CTX* getCTX() override; - -private: - - bool LocalStoreCert(X509* x509); - bool RemoveX509(const RsPeerId id); - - /*********** LOCKED Functions ******/ - bool locked_FindCert(const RsPeerId& id, X509** cert); - - /* Data */ - /* these variables are constants -> don't need to protect */ - SSL_CTX *sslctx; - RsPeerId mOwnId; - X509* mOwnCert; - - /** - * If the location name is included in SSL certificate it becomes a public - * information, because anyone able to open an SSL connection to the host is - * able to read it. To avoid that location name is now stored separately and - * and not included in the SSL certificate. - */ - std::string mOwnLocationName; - - RsMutex sslMtx; /* protects all below */ - - EVP_PKEY* mOwnPrivateKey; - EVP_PKEY* mOwnPublicKey; - - int init; - std::map mCerts; - - RsPgpId _last_gpgid_to_connect; - std::string _last_sslcn_to_connect; - RsPeerId _last_sslid_to_connect; -}; diff --git a/libretroshare/src/pqi/p3cfgmgr.cc b/libretroshare/src/pqi/p3cfgmgr.cc deleted file mode 100644 index e51f9fe52..000000000 --- a/libretroshare/src/pqi/p3cfgmgr.cc +++ /dev/null @@ -1,615 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3cfgmgr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie, Retroshare Team. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsdir.h" -//#include "retroshare/rspeers.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/authssl.h" -#include "pqi/pqibin.h" -#include "pqi/pqistore.h" -#include -#include -#include -#include "util/rsstring.h" - -#include "rsitems/rsconfigitems.h" - -/* -#define CONFIG_DEBUG 1 -*/ -#define BACKEDUP_SAVE - - -p3ConfigMgr::p3ConfigMgr(std::string dir) - :basedir(dir), cfgMtx("p3ConfigMgr"), - mConfigSaveActive(true) -{ -} - -void p3ConfigMgr::tick() -{ - bool toSave = false; - - { - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - /* iterate through and check if any have changed */ - std::list::iterator it; - for(it = mConfigs.begin(); it != mConfigs.end(); ++it) - { - if ((*it)->HasConfigChanged(0)) - { - -#ifdef CONFIG_DEBUG - std::cerr << "p3ConfigMgr::tick() Config Changed - Element: "; - std::cerr << *it; - std::cerr << std::endl; -#endif - - toSave = true; - } - } - - /* disable saving before exit */ - if (!mConfigSaveActive) - { - toSave = false; - } - } - - if (toSave) - { - saveConfiguration(); - } -} - - -void p3ConfigMgr::saveConfiguration() -{ - if(!RsDiscSpace::checkForDiscSpace(RS_CONFIG_DIRECTORY)) - return ; - - saveConfig(); - - -} - -void p3ConfigMgr::saveConfig() -{ - - bool ok= true; - - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - std::list::iterator it; - for(it = mConfigs.begin(); it != mConfigs.end(); ++it) - { - if ((*it)->HasConfigChanged(1)) - { -#ifdef CONFIG_DEBUG - std::cerr << "p3ConfigMgr::globalSaveConfig() Saving Element: "; - std::cerr << *it; - std::cerr << std::endl; -#endif - ok &= (*it)->saveConfiguration(); - } - /* save metaconfig */ - } - return; -} - - -void p3ConfigMgr::loadConfiguration() -{ - loadConfig(); - - return; -} - -void p3ConfigMgr::loadConfig() -{ - std::list::iterator cit; - RsFileHash dummyHash ; - for (cit = mConfigs.begin(); cit != mConfigs.end(); ++cit) - { -#ifdef CONFIG_DEBUG - std::cerr << "p3ConfigMgr::loadConfig() Element: "; - std::cerr << *cit <<" Dummy Hash: " << dummyHash; - std::cerr << std::endl; -#endif - - (*cit)->loadConfiguration(dummyHash); - - /* force config to NOT CHANGED */ - (*cit)->HasConfigChanged(0); - (*cit)->HasConfigChanged(1); - } - - return; -} - - -void p3ConfigMgr::addConfiguration(std::string file, pqiConfig *conf) -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - /* construct filename */ - std::string filename = basedir; - if (basedir != "") - { - filename += "/"; - } - filename += "config/"; - filename += file; - - std::list::iterator cit = std::find(mConfigs.begin(),mConfigs.end(),conf); - if (cit != mConfigs.end()) - { - std::cerr << "p3Config::addConfiguration() Config already added"; - std::cerr << std::endl; - std::cerr << "\tOriginal filename " << (*cit)->Filename(); - std::cerr << std::endl; - std::cerr << "\tIgnoring new filename " << filename; - std::cerr << std::endl; - return; - } - // Also check that the filename is not already registered for another config - - for(std::list::iterator it = mConfigs.begin(); it!= mConfigs.end();) - if((*it)->filename == filename) - { - std::cerr << "(WW) Registering a config for file \"" << filename << "\" that is already registered. Replacing previous component." << std::endl; - it = mConfigs.erase(it); - } - else - ++it; - - conf->setFilename(filename);// (cyril) this is quite terrible. The constructor of pqiConfig should take the filename as parameter and hold the information. - mConfigs.push_back(conf); -} - - -void p3ConfigMgr::completeConfiguration() -{ - saveConfiguration(); - - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - mConfigSaveActive = false; -} - - - -p3Config::p3Config() - :pqiConfig() -{ - return; -} - - -bool p3Config::loadConfiguration(RsFileHash& /* loadHash */) -{ - return loadConfig(); -} - -bool p3Config::loadConfig() -{ - -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::loadConfig() loading Configuration\n File: " << Filename() << std::endl; -#endif - - bool pass = true; - std::string cfgFname = Filename(); - std::string cfgFnameBackup = cfgFname + ".tmp"; - - std::string signFname = Filename() +".sgn"; - std::string signFnameBackup = signFname + ".tmp"; - - std::list load; - std::list::iterator it; - - // try 1st attempt - if(!loadAttempt(cfgFname, signFname, load)) - { - -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::loadConfig() Failed to Load" << std::endl; -#endif - - /* bad load */ - for(it = load.begin(); it != load.end(); ++it) - { - delete (*it); - } - pass = false; - - load.clear(); - } - - // try 2nd attempt with backup files if first failed - if(!pass) - { - if(!loadAttempt(cfgFnameBackup, signFnameBackup, load)) - { - -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::loadConfig() Failed on 2nd Pass" << std::endl; -#endif - - /* bad load */ - for(it = load.begin(); it != load.end(); ++it) - { - delete (*it); - } - pass = false; - } - else - pass = true; - } - - - - if(pass) - loadList(load); - else - return false; - - return pass; -} - -bool p3Config::loadAttempt(const std::string& cfgFname,const std::string& signFname, std::list& load) -{ - -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::loadAttempt() \nFilename: " << cfgFname << std::endl; -#endif - - - uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_READABLE; - uint32_t stream_flags = BIN_FLAGS_READABLE; - - BinEncryptedFileInterface *bio = new BinEncryptedFileInterface(cfgFname.c_str(), bioflags); - pqiSSLstore stream(setupSerialiser(), RsPeerId(), bio, stream_flags); - - if(!stream.getEncryptedItems(load)) - { -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::loadAttempt() Error occurred trying to load Item" << std::endl; -#endif - return false; - } - - /* set hash */ - setHash(bio->gethash()); - - // In order to check the signature that is stored on disk, we compute the hash of the current data (which should match the hash of the data on disc because we just read it), - // and validate the signature from the disk on this data. The config file data is therefore hashed twice. Not a security issue, but - // this is a bit inelegant. - - std::string signatureRead; - RsFileHash strHash(Hash()); - - BinFileInterface bfi(signFname.c_str(), BIN_FLAGS_READABLE); - - if(bfi.getFileSize() == 0) - return false ; - - RsTemporaryMemory mem(bfi.getFileSize()) ; - - if(!bfi.readdata(mem,mem.size())) - return false; - - // signature is stored as ascii so we need to convert it back to binary - - RsTemporaryMemory mem2(bfi.getFileSize()/2) ; - - if(!RsUtil::HexToBin(std::string((char*)(unsigned char*)mem,mem.size()),mem2,mem2.size())) - { - std::cerr << "Input string is not a Hex string!!"<< std::endl; - return false ; - } - - bool signature_checks = AuthSSL::getAuthSSL()->VerifyOwnSignBin(strHash.toByteArray(), RsFileHash::SIZE_IN_BYTES,mem2,mem2.size()); - - std::cerr << "(II) checked signature of config file " << cfgFname << ": " << (signature_checks?"OK":"Wrong!") << std::endl; - - return signature_checks; -} - -bool p3Config::saveConfiguration() -{ - return saveConfig(); -} - -bool p3Config::saveConfig() -{ - bool cleanup = true; - std::list toSave; - saveList(cleanup, toSave); - - // temporarily append new to files as these will replace current configuration - std::string newCfgFname = Filename() + "_new"; - std::string newSignFname = Filename() + ".sgn" + "_new"; - - std::string tmpCfgFname = Filename() + ".tmp"; - std::string tmpSignFname = Filename() + ".sgn" + ".tmp"; - - std::string cfgFname = Filename(); - std::string signFname = Filename() + ".sgn"; - - std::cerr << "(II) Saving configuration file " << cfgFname << std::endl; - - uint32_t bioflags = BIN_FLAGS_HASH_DATA | BIN_FLAGS_WRITEABLE; - uint32_t stream_flags = BIN_FLAGS_WRITEABLE; - bool written = true; - - if (!cleanup) - stream_flags |= BIN_FLAGS_NO_DELETE; - - BinEncryptedFileInterface *cfg_bio = new BinEncryptedFileInterface(newCfgFname.c_str(), bioflags); - pqiSSLstore *stream = new pqiSSLstore(setupSerialiser(), RsPeerId(), cfg_bio, stream_flags); - - written = written && stream->encryptedSendItems(toSave); - - if(!written) - std::cerr << "(EE) Error while writing config file " << Filename() << ": file dropped!!" << std::endl; - - /* store the hash */ - setHash(cfg_bio->gethash()); - - // bio is taken care of in stream's destructor, also forces file to close - delete stream; - - /* sign data */ - std::string signature; - RsFileHash strHash(Hash()); - AuthSSL::getAuthSSL()->SignData(strHash.toByteArray(),strHash.SIZE_IN_BYTES, signature); - - /* write signature to configuration */ - BinMemInterface *signbio = new BinMemInterface(signature.c_str(), - signature.length(), BIN_FLAGS_READABLE); - - signbio->writetofile(newSignFname.c_str()); - - delete signbio; - - // now rewrite current files to temp files - // rename back-up to current file - if(!RsDirUtil::renameFile(cfgFname, tmpCfgFname) || !RsDirUtil::renameFile(signFname, tmpSignFname)){ -#ifdef CONFIG_DEBUG - std::cerr << "p3Config::backedUpFileSave() Failed to rename backup meta files: " << std::endl - << cfgFname << " to " << tmpCfgFname << std::endl - << signFname << " to " << tmpSignFname << std::endl; -#endif - written = false; - } - - - - // now rewrite current files to temp files - // rename back-up to current file - if(!RsDirUtil::renameFile(newCfgFname, cfgFname) || !RsDirUtil::renameFile(newSignFname, signFname)){ - #ifdef CONFIG_DEBUG - std::cerr << "p3Config::() Failed to rename meta files: " << std::endl - << newCfgFname << " to " << cfgFname << std::endl - << newSignFname << " to " << signFname << std::endl; - #endif - - written = false; - } - - - - saveDone(); // callback to inherited class to unlock any Mutexes protecting saveList() data - - return written; - -} - - -/**************************** CONFIGURATION CLASSES ********************/ - -p3GeneralConfig::p3GeneralConfig() - :p3Config() -{ - return; -} - - // General Configuration System -std::string p3GeneralConfig::getSetting(const std::string &opt) -{ -#ifdef CONFIG_DEBUG - std::cerr << "p3GeneralConfig::getSetting(" << opt << ")"; - std::cerr << std::endl; -#endif - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - /* extract from config */ - std::map::iterator it; - if (settings.end() == (it = settings.find(opt))) - { - std::string nullstring; - return nullstring; - } - return it->second; -} - -void p3GeneralConfig::setSetting(const std::string &opt, const std::string &val) -{ -#ifdef CONFIG_DEBUG - std::cerr << "p3GeneralConfig::setSetting(" << opt << " = " << val << ")"; - std::cerr << std::endl; -#endif - { - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - /* extract from config */ - std::map::iterator it; - if (settings.end() != (it = settings.find(opt))) - { - if (it->second == val) - { - /* no change */ - return; - } - } - - settings[opt] = val; - } - /* outside mutex */ - IndicateConfigChanged(); - - return; -} - -RsSerialiser *p3GeneralConfig::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsGeneralConfigSerialiser()); - return rss; -} - -bool p3GeneralConfig::saveList(bool &cleanup, std::list& savelist) -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef CONFIG_DEBUG - std::cerr << "p3GeneralConfig::saveList() KV sets: " << settings.size(); - std::cerr << std::endl; -#endif - - cleanup = true; - - - RsConfigKeyValueSet *item = new RsConfigKeyValueSet(); - std::map::iterator it; - for(it = settings.begin(); it != settings.end(); ++it) - { - RsTlvKeyValue kv; - kv.key = it->first; - kv.value = it->second; - item->tlvkvs.pairs.push_back(kv); - - /* make sure we don't overload it */ - if (item->tlvkvs.TlvSize() > 4000) - { - savelist.push_back(item); - item = new RsConfigKeyValueSet(); - } - } - - if (item->tlvkvs.pairs.size() > 0) - { - savelist.push_back(item); - } else - delete item; - - return true; -} - - -bool p3GeneralConfig::loadList(std::list& load) -{ -#ifdef CONFIG_DEBUG - std::cerr << "p3GeneralConfig::loadList() count: " << load.size(); - std::cerr << std::endl; -#endif - - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - - /* add into settings */ - RsConfigKeyValueSet *item = NULL; - std::list::iterator it; - std::list::iterator kit; - - for(it = load.begin(); it != load.end();) - { - item = dynamic_cast(*it); - if (item) - { - for(kit = item->tlvkvs.pairs.begin(); - kit != item->tlvkvs.pairs.end(); ++kit) - { - settings[kit->key] = kit->value; - } - } - - /* cleanup */ - delete (*it); - it = load.erase(it); - } - - return true; -} - - -/**** MUTEX NOTE: - * have protected all, but think that - * only the Indication and hash really need it - */ - -pqiConfig::pqiConfig() - : cfgMtx("pqiConfig"), ConfInd(2) -{ - return; -} - -pqiConfig::~pqiConfig() -{ - return; -} - -const std::string& pqiConfig::Filename() -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - return filename; -} - -const RsFileHash& pqiConfig::Hash() -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - return hash; -} - -void pqiConfig::IndicateConfigChanged() -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - ConfInd.IndicateChanged(); -} - -bool pqiConfig::HasConfigChanged(uint16_t idx) -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - return ConfInd.Changed(idx); -} - -void pqiConfig::setFilename(const std::string& name) -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - filename = name; -} - -void pqiConfig::setHash(const RsFileHash& h) -{ - RsStackMutex stack(cfgMtx); /***** LOCK STACK MUTEX ****/ - hash = h; -} - diff --git a/libretroshare/src/pqi/p3cfgmgr.h b/libretroshare/src/pqi/p3cfgmgr.h deleted file mode 100644 index 768855d38..000000000 --- a/libretroshare/src/pqi/p3cfgmgr.h +++ /dev/null @@ -1,284 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3cfgmgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_CONFIG_MGR_HEADER -#define P3_CONFIG_MGR_HEADER - -#include -#include -#include - -#include "pqi/pqi_base.h" -#include "pqi/pqiindic.h" -#include "pqi/pqinetwork.h" -#include "util/rsthreads.h" -#include "pqi/pqibin.h" - -/***** Configuration Management ***** - * - * we need to store: - * (1) Certificates. - * (2) List of Friends / Net Configuration - * (3) Stun List. / DHT peers. - * (4) general config. - * - * - * At top level we need: - * - * - type / filename / size / hash - - * and the file signed... - * - * - */ - -/**** THESE are STORED in CONFIGURATION FILES.... - * Cannot be changed - * - *********************/ - -/* CACHE ID Must be at the END so that other configurations - * are loaded First (Cache Config --> Cache Loading) - */ - -class p3ConfigMgr; - - - -//! abstract class for configuration saving -/*! - * Aim is that active objects in retroshare can dervie from this class - * and implement their method of saving and loading their configuration - */ -class pqiConfig -{ - public: - pqiConfig(); -virtual ~pqiConfig(); - -/** - * loads configuration of object - * @param loadHash This is the hash that will be compared to confirm saved configuration has not - * been tampered with - */ -virtual bool loadConfiguration(RsFileHash &loadHash) = 0; - -/** - * save configuration of object - */ -virtual bool saveConfiguration() = 0; - -/** - * The name of the configuration file - */ -const std::string& Filename(); - -/** - * The hash computed for this configuration, can use this to compare to externally stored hash - * for validation checking - */ -const RsFileHash& Hash(); - - protected: - -/** - * Checks if configuration has changed - */ -virtual void IndicateConfigChanged(); -void setHash(const RsFileHash& h); - - RsMutex cfgMtx; - - /** - * This sets the name of the pqi configuation file - */ - void setFilename(const std::string& name); - -private: - /** - * @param an index for the Confind which contains list of configuarations that can be tracked - */ - bool HasConfigChanged(uint16_t idx); - - Indicator ConfInd; - - std::string filename; - RsFileHash hash; - - friend class p3ConfigMgr; - /* so it can access: - * setFilename() and HasConfigChanged() - */ -}; - - - -/***********************************************************************************************/ - -/*! - * MUTEX NOTE - * Class data is protected by mutex's so that anyone can call these - * functions, at any time. - */ -class p3ConfigMgr -{ - public: - - /** - * @param bdir base directory: where config files will be saved - */ - explicit p3ConfigMgr(std::string bdir); - - /** - * checks and update all added configurations - * @see rsserver - */ - void tick(); - - /** - * save all added configuation including configuration files - * creates global signature file - */ - void saveConfiguration(); - - /** - * loads all configurations - */ - void loadConfiguration(); - - /** - * @param file The name for new configuration - * @param conf to the configuration to use - */ - void addConfiguration(std::string file, pqiConfig *conf); - - /** saves config, and disables further saving - * used for exiting the system - */ - void completeConfiguration(); - - - - private: - - /** - * saves configuration of pqiconfigs in object configs - */ - void saveConfig(); - - /** - * - */ - void loadConfig(); - - const std::string basedir; - - RsMutex cfgMtx; /* below is protected */ - - bool mConfigSaveActive; - std::list mConfigs; -}; - - - -/***************************************************************************************************/ - - -/** - * @brief Abstract class for configuration saving. - * Aimed at rs services that uses RsItem config data, provide a way for RS - * services to save and load particular configurations as items. - */ -class p3Config : public pqiConfig -{ -public: - p3Config(); - - virtual bool loadConfiguration(RsFileHash &loadHash); - virtual bool saveConfiguration(); - -protected: - - /// Key Functions to be overloaded for Full Configuration - virtual RsSerialiser *setupSerialiser() = 0; - - /** - * saves list of derived object - * @param cleanup this inform you if you need to call saveDone() to - * unlock/allow access to resources pointed to by handles (list) - * returned by function: thus false, call saveDone after returned list - * finished with and vice versa - * @return list of config items derived object wants to saves - */ - virtual bool saveList(bool &cleanup, std::list&) = 0; - - /** - * loads up list of configs items for derived object - * @param load list of config items to load up - */ - virtual bool loadList(std::list& load) = 0; - - /** - * callback for mutex unlocking - * in derived classes (should only be needed if cleanup = false) - */ - virtual void saveDone() {} - -private: - - bool loadConfig(); - bool saveConfig(); - - bool loadAttempt( const std::string&, const std::string&, - std::list& load ); -}; // end of p3Config - - -class p3GeneralConfig: public p3Config -{ - public: - p3GeneralConfig(); - -// General Configuration System -std::string getSetting(const std::string &opt); -void setSetting(const std::string &opt, const std::string &val); - - protected: - - /* Key Functions to be overloaded for Full Configuration */ -virtual RsSerialiser *setupSerialiser(); -virtual bool saveList(bool &cleanup, std::list&); -virtual bool loadList(std::list& ); - - private: - - /* protected by pqiConfig mutex as well! */ -std::map settings; - - -}; - - - - - - - -#endif // P3_CONFIG_MGR_HEADER diff --git a/libretroshare/src/pqi/p3historymgr.cc b/libretroshare/src/pqi/p3historymgr.cc deleted file mode 100644 index a15d18075..000000000 --- a/libretroshare/src/pqi/p3historymgr.cc +++ /dev/null @@ -1,697 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3historymgr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstime.h" - -#include "p3historymgr.h" -#include "rsitems/rshistoryitems.h" -#include "rsitems/rsconfigitems.h" -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" -#include "rsitems/rsmsgitems.h" -#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 - -RsHistory *rsHistory = NULL; - -p3HistoryMgr::p3HistoryMgr() - : p3Config() - , nextMsgId(1) - , mPublicEnable(false), mLobbyEnable(true), mPrivateEnable(true), mDistantEnable(true) - , mPublicSaveCount(0), mLobbySaveCount(0), mPrivateSaveCount(0), mDistantSaveCount(0) - , mMaxStorageDurationSeconds(10*86400) // store for 10 days at most. - , mLastCleanTime(0) - , mHistoryMtx("p3HistoryMgr") -{ -} - -p3HistoryMgr::~p3HistoryMgr() -{ -} - -/***** p3HistoryMgr *****/ - -void p3HistoryMgr::addMessage(const ChatMessage& cm) -{ - uint32_t addMsgId = 0; - - rstime_t now = time(NULL) ; - - if(mLastCleanTime + MSG_HISTORY_CLEANING_PERIOD < now) - { - cleanOldMessages() ; - mLastCleanTime = now ; - } - - { - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - - RsPeerId msgPeerId; // id of sending peer - RsPeerId chatPeerId; // id of chat endpoint - std::string peerName; //name of sending peer - - if (cm.chat_id.isBroadcast() && mPublicEnable == true) { - peerName = rsPeers->getPeerName(cm.broadcast_peer_id); - } - else if (cm.chat_id.isPeerId() && mPrivateEnable == true) { - msgPeerId = cm.incoming ? cm.chat_id.toPeerId() : rsPeers->getOwnId(); - peerName = rsPeers->getPeerName(msgPeerId); - } - else if (cm.chat_id.isLobbyId() && mLobbyEnable == true) { - msgPeerId = RsPeerId(cm.lobby_peer_gxs_id); - RsIdentityDetails details; - if (rsIdentity->getIdDetails(cm.lobby_peer_gxs_id, details)) - peerName = details.mNickname; - else - peerName = cm.lobby_peer_gxs_id.toStdString(); - } - else if(cm.chat_id.isDistantChatId()&& mDistantEnable == true) - { - DistantChatPeerInfo dcpinfo; - if (rsMsgs->getDistantChatStatus(cm.chat_id.toDistantChatId(), dcpinfo)) - { - RsIdentityDetails det; - RsGxsId writer_id = cm.incoming?(dcpinfo.to_id):(dcpinfo.own_id); - - if(rsIdentity->getIdDetails(writer_id,det)) - peerName = det.mNickname; - else - peerName = writer_id.toStdString(); - - msgPeerId = cm.incoming?RsPeerId(dcpinfo.own_id):RsPeerId(dcpinfo.to_id); - } - else - { - RS_ERR( "Cannot retrieve friend name for distant chat ", cm.chat_id.toDistantChatId() ); - peerName = ""; - } - - } - else - return; - - if(!chatIdToVirtualPeerId(cm.chat_id, chatPeerId)) - return; - - RsHistoryMsgItem* item = new RsHistoryMsgItem; - item->chatPeerId = chatPeerId; - item->incoming = cm.incoming; - item->msgPeerId = msgPeerId; - item->peerName = peerName; - item->sendTime = cm.sendTime; - item->recvTime = cm.recvTime; - - item->message = cm.msg ; - //librs::util::ConvertUtf16ToUtf8(chatItem->message, item->message); - - std::map >::iterator mit = mMessages.find(item->chatPeerId); - if (mit != mMessages.end()) { - item->msgId = nextMsgId++; - mit->second.insert(std::make_pair(item->msgId, item)); - addMsgId = item->msgId; - - // check the limit - uint32_t limit; - if (chatPeerId.isNull()) - limit = mPublicSaveCount; - else if (cm.chat_id.isLobbyId()) - limit = mLobbySaveCount; - else - limit = mPrivateSaveCount; - - if (limit) { - while (mit->second.size() > limit) { - delete(mit->second.begin()->second); - mit->second.erase(mit->second.begin()); - } - } - } else { - std::map msgs; - item->msgId = nextMsgId++; - msgs.insert(std::make_pair(item->msgId, item)); - mMessages.insert(std::make_pair(item->chatPeerId, msgs)); - addMsgId = item->msgId; - - // no need to check the limit - } - - IndicateConfigChanged(); - } - - if (addMsgId) { - RsServer::notify()->notifyHistoryChanged(addMsgId, NOTIFY_TYPE_ADD); - } -} - -void p3HistoryMgr::cleanOldMessages() -{ - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - -#ifdef HISTMGR_DEBUG - std::cerr << "****** cleaning old messages." << std::endl; -#endif - rstime_t now = time(NULL) ; - bool changed = false ; - - for(std::map >::iterator mit = mMessages.begin(); mit != mMessages.end();) - { - if (mMaxStorageDurationSeconds > 0) - { - for(std::map::iterator lit = mit->second.begin();lit!=mit->second.end();) - if(lit->second->recvTime + mMaxStorageDurationSeconds < now) - { - 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) ; - lit = lit2 ; - - changed = true ; - } - else - ++lit ; - } - - if(mit->second.empty()) - { - std::map >::iterator mit2 = mit ; - ++mit2 ; -#ifdef HISTMGR_DEBUG - std::cerr << " removing peer id " << mit->first << ", since it has no messages" << std::endl; -#endif - mMessages.erase(mit) ; - mit = mit2 ; - - changed = true ; - } - else - ++mit ; - } - - if(changed) - IndicateConfigChanged() ; -} - -/***** p3Config *****/ - -RsSerialiser* p3HistoryMgr::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser; - rss->addSerialType(new RsHistorySerialiser); - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss; -} - -bool p3HistoryMgr::saveList(bool& cleanup, std::list& saveData) -{ - cleanup = false; - - mHistoryMtx.lock(); /********** STACK LOCKED MTX ******/ - - std::map >::iterator mit; - std::map::iterator lit; - for (mit = mMessages.begin(); mit != mMessages.end(); ++mit) { - for (lit = mit->second.begin(); lit != mit->second.end(); ++lit) { - if (lit->second->saveToDisc) { - saveData.push_back(lit->second); - } - } - } - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet; - - RsTlvKeyValue kv; - kv.key = "PUBLIC_ENABLE"; - kv.value = mPublicEnable ? "TRUE" : "FALSE"; - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "PRIVATE_ENABLE"; - kv.value = mPrivateEnable ? "TRUE" : "FALSE"; - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "LOBBY_ENABLE"; - kv.value = mLobbyEnable ? "TRUE" : "FALSE"; - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "DISTANT_ENABLE"; - kv.value = mDistantEnable ? "TRUE" : "FALSE"; - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "MAX_STORAGE_TIME"; - rs_sprintf(kv.value,"%d",mMaxStorageDurationSeconds) ; - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "LOBBY_SAVECOUNT"; - rs_sprintf(kv.value, "%lu", mLobbySaveCount); - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "PUBLIC_SAVECOUNT"; - rs_sprintf(kv.value, "%lu", mPublicSaveCount); - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "PRIVATE_SAVECOUNT"; - rs_sprintf(kv.value, "%lu", mPrivateSaveCount); - vitem->tlvkvs.pairs.push_back(kv); - - kv.key = "DISTANT_SAVECOUNT"; - rs_sprintf(kv.value, "%lu", mDistantSaveCount); - vitem->tlvkvs.pairs.push_back(kv); - - saveData.push_back(vitem); - saveCleanupList.push_back(vitem); - - return true; -} - -void p3HistoryMgr::saveDone() -{ - /* clean up the save List */ - std::list::iterator it; - for (it = saveCleanupList.begin(); it != saveCleanupList.end(); ++it) { - delete (*it); - } - - saveCleanupList.clear(); - - /* unlock mutex */ - mHistoryMtx.unlock(); /****** MUTEX UNLOCKED *******/ -} - -bool p3HistoryMgr::loadList(std::list& load) -{ - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - - RsHistoryMsgItem *msgItem; - std::list::iterator it; - - for (it = load.begin(); it != load.end(); ++it) - { - if (NULL != (msgItem = dynamic_cast(*it))) { - - 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)); - } else { - std::map msgs; - msgs.insert(std::make_pair(msgItem->msgId, msgItem)); - mMessages.insert(std::make_pair(msgItem->chatPeerId, msgs)); - } - - // don't delete the item !! - - continue; - } - - RsConfigKeyValueSet *rskv ; - if (NULL != (rskv = dynamic_cast(*it))) { - for (std::list::const_iterator kit = rskv->tlvkvs.pairs.begin(); kit != rskv->tlvkvs.pairs.end(); ++kit) { - if (kit->key == "PUBLIC_ENABLE") { - mPublicEnable = (kit->value == "TRUE") ? true : false; - continue; - } - - if (kit->key == "PRIVATE_ENABLE") { - mPrivateEnable = (kit->value == "TRUE") ? true : false; - continue; - } - - if (kit->key == "LOBBY_ENABLE") { - mLobbyEnable = (kit->value == "TRUE") ? true : false; - continue; - } - - if (kit->key == "DISTANT_ENABLE") { - mDistantEnable = (kit->value == "TRUE") ? true : false; - continue; - } - - if (kit->key == "MAX_STORAGE_TIME") { - uint32_t val ; - if (sscanf(kit->value.c_str(), "%u", &val) == 1) - mMaxStorageDurationSeconds = val ; - -#ifdef HISTMGR_DEBUG - std::cerr << "Loaded max storage time for history = " << val << " seconds" << std::endl; -#endif - continue; - } - - if (kit->key == "PUBLIC_SAVECOUNT") { - mPublicSaveCount = atoi(kit->value.c_str()); - continue; - } - if (kit->key == "PRIVATE_SAVECOUNT") { - mPrivateSaveCount = atoi(kit->value.c_str()); - continue; - } - if (kit->key == "LOBBY_SAVECOUNT") { - mLobbySaveCount = atoi(kit->value.c_str()); - continue; - } - if (kit->key == "DISTANT_SAVECOUNT") { - mDistantSaveCount = atoi(kit->value.c_str()); - continue; - } - } - - delete (*it); - continue; - } - - // delete unknown items - delete (*it); - } - - load.clear() ; - return true; -} - -// have to convert to virtual peer id, to be able to use existing serialiser and file format -bool p3HistoryMgr::chatIdToVirtualPeerId(const ChatId& chat_id, RsPeerId &peer_id) -{ - if (chat_id.isBroadcast()) { - peer_id = RsPeerId(); - return true; - } - if (chat_id.isPeerId()) { - peer_id = chat_id.toPeerId(); - return true; - } - if (chat_id.isLobbyId()) { - if(sizeof(ChatLobbyId) > RsPeerId::SIZE_IN_BYTES){ - std::cerr << "p3HistoryMgr::chatIdToVirtualPeerId() ERROR: ChatLobbyId does not fit into virtual peer id. Please report this error." << std::endl; - return false; - } - uint8_t bytes[RsPeerId::SIZE_IN_BYTES] ; - memset(bytes,0,RsPeerId::SIZE_IN_BYTES) ; - ChatLobbyId lobby_id = chat_id.toLobbyId(); - memcpy(bytes,&lobby_id,sizeof(ChatLobbyId)); - peer_id = RsPeerId(bytes); - return true; - } - - if (chat_id.isDistantChatId()) { - peer_id = RsPeerId(chat_id.toDistantChatId()); - return true; - } - - return false; -} - -/***** p3History *****/ - -static void convertMsg(const RsHistoryMsgItem* item, HistoryMsg &msg) -{ - msg.msgId = item->msgId; - msg.chatPeerId = item->chatPeerId; - msg.incoming = item->incoming; - msg.peerId = item->msgPeerId; - msg.peerName = item->peerName; - msg.sendTime = item->sendTime; - msg.recvTime = item->recvTime; - msg.message = item->message; -} - -bool p3HistoryMgr::getMessages(const ChatId &chatId, std::list &msgs, uint32_t loadCount) -{ - msgs.clear(); - - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - - RsPeerId chatPeerId; - bool enabled = false; - if (chatId.isBroadcast() && mPublicEnable == true) { - enabled = true; - } - if (chatId.isPeerId() && mPrivateEnable == true) { - enabled = true; - } - if (chatId.isLobbyId() && mLobbyEnable == true) { - enabled = true; - } - if (chatId.isDistantChatId() && mDistantEnable == true) { - enabled = true; - } - - if(enabled == false) - return false; - - if(!chatIdToVirtualPeerId(chatId, chatPeerId)) - return false; - -#ifdef HISTMGR_DEBUG - std::cerr << "Getting history for virtual peer " << chatPeerId << std::endl; -#endif - - uint32_t foundCount = 0; - - std::map >::iterator mit = mMessages.find(chatPeerId); - - if (mit != mMessages.end()) - { - std::map::reverse_iterator lit; - - for (lit = mit->second.rbegin(); lit != mit->second.rend(); ++lit) - { - HistoryMsg msg; - convertMsg(lit->second, msg); - msgs.insert(msgs.begin(), msg); - foundCount++; - if (loadCount && foundCount >= loadCount) { - break; - } - } - } -#ifdef HISTMGR_DEBUG - std::cerr << msgs.size() << " messages added." << std::endl; -#endif - - return true; -} - -bool p3HistoryMgr::getMessage(uint32_t msgId, HistoryMsg &msg) -{ - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - - std::map >::iterator mit; - for (mit = mMessages.begin(); mit != mMessages.end(); ++mit) { - std::map::iterator lit = mit->second.find(msgId); - if (lit != mit->second.end()) { - convertMsg(lit->second, msg); - return true; - } - } - - return false; -} - -void p3HistoryMgr::clear(const ChatId &chatId) -{ - { - RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/ - - RsPeerId chatPeerId; - 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()) { - return; - } - - std::map::iterator lit; - for (lit = mit->second.begin(); lit != mit->second.end(); ++lit) { - delete(lit->second); - } - mit->second.clear(); - mMessages.erase(mit); - - IndicateConfigChanged(); - } - - RsServer::notify()->notifyHistoryChanged(0, NOTIFY_TYPE_MOD); -} - -void p3HistoryMgr::removeMessages(const std::list &msgIds) -{ - std::list ids = 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 ******/ - - std::map >::iterator mit; - for (mit = mMessages.begin(); mit != mMessages.end(); ++mit) - { - iit = ids.begin(); - while ( !ids.empty() || (iit != ids.end()) ) - { - 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); - - removedIds.push_back(*iit); - iit = ids.erase(iit); - - continue; - } - - ++iit; - } - } - } - - if (!removedIds.empty()) - { - IndicateConfigChanged(); - - for (iit = removedIds.begin(); iit != removedIds.end(); ++iit) - RsServer::notify()->notifyHistoryChanged(*iit, NOTIFY_TYPE_DEL); - } -} - -bool p3HistoryMgr::getEnable(uint32_t chat_type) -{ - switch(chat_type) - { - case RS_HISTORY_TYPE_PUBLIC : return mPublicEnable ; - case RS_HISTORY_TYPE_LOBBY : return mLobbyEnable ; - case RS_HISTORY_TYPE_PRIVATE: return mPrivateEnable ; - case RS_HISTORY_TYPE_DISTANT: return mDistantEnable ; - default: - std::cerr << "Unexpected value " << chat_type<< " in p3HistoryMgr::getEnable(): this is a bug." << std::endl; - return 0 ; - } -} - -uint32_t p3HistoryMgr::getMaxStorageDuration() -{ - return mMaxStorageDurationSeconds ; -} - - -void p3HistoryMgr::setMaxStorageDuration(uint32_t seconds) -{ - if(mMaxStorageDurationSeconds != seconds) - IndicateConfigChanged() ; - - mMaxStorageDurationSeconds = seconds ; -} - -void p3HistoryMgr::setEnable(uint32_t chat_type, bool enable) -{ - bool oldValue; - - switch(chat_type) - { - case RS_HISTORY_TYPE_PUBLIC : oldValue = mPublicEnable ; - mPublicEnable = enable ; - break ; - - case RS_HISTORY_TYPE_LOBBY : oldValue = mLobbyEnable ; - mLobbyEnable = enable; - break ; - - case RS_HISTORY_TYPE_PRIVATE: oldValue = mPrivateEnable ; - mPrivateEnable = enable ; - break ; - case RS_HISTORY_TYPE_DISTANT: oldValue = mDistantEnable ; - mDistantEnable = enable ; - break ; - default: - return; - } - - if (oldValue != enable) - IndicateConfigChanged(); -} - -uint32_t p3HistoryMgr::getSaveCount(uint32_t chat_type) -{ - switch(chat_type) - { - case RS_HISTORY_TYPE_PUBLIC : return mPublicSaveCount ; - case RS_HISTORY_TYPE_LOBBY : return mLobbySaveCount ; - case RS_HISTORY_TYPE_PRIVATE: return mPrivateSaveCount ; - default: - std::cerr << "Unexpected value " << chat_type<< " in p3HistoryMgr::getSaveCount(): this is a bug." << std::endl; - return 0 ; - } -} - -void p3HistoryMgr::setSaveCount(uint32_t chat_type, uint32_t count) -{ - uint32_t oldValue; - - switch(chat_type) - { - case RS_HISTORY_TYPE_PUBLIC : oldValue = mPublicSaveCount ; - mPublicSaveCount = count ; - break ; - - case RS_HISTORY_TYPE_LOBBY : oldValue = mLobbySaveCount ; - mLobbySaveCount = count; - break ; - - case RS_HISTORY_TYPE_PRIVATE: oldValue = mPrivateSaveCount ; - mPrivateSaveCount = count ; - break ; - default: - return; - } - - if (oldValue != count) - IndicateConfigChanged(); -} diff --git a/libretroshare/src/pqi/p3historymgr.h b/libretroshare/src/pqi/p3historymgr.h deleted file mode 100644 index a74eff67e..000000000 --- a/libretroshare/src/pqi/p3historymgr.h +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3historymgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_P3_HISTORY_MGR_H -#define RS_P3_HISTORY_MGR_H - -#include -#include - -#include "rsitems/rshistoryitems.h" -#include "retroshare/rshistory.h" -#include "pqi/p3cfgmgr.h" - -class RsChatMsgItem; -class ChatMessage; - -//! handles history -/*! - * The is a retroshare service which allows peers - * to store the history of the chat messages - */ -class p3HistoryMgr: public p3Config -{ -public: - p3HistoryMgr(); - virtual ~p3HistoryMgr(); - - /******** p3HistoryMgr *********/ - - void addMessage(const ChatMessage &cm); - - /********* RsHistory ***********/ - - bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount); - bool getMessage(uint32_t msgId, HistoryMsg &msg); - void clear(const ChatId &chatPeerId); - void removeMessages(const std::list &msgIds); - - virtual bool getEnable(uint32_t chat_type); - virtual void setEnable(uint32_t chat_type, bool enable); - virtual uint32_t getSaveCount(uint32_t chat_type); - virtual void setSaveCount(uint32_t chat_type, uint32_t count); - virtual void setMaxStorageDuration(uint32_t seconds) ; - virtual uint32_t getMaxStorageDuration() ; - - /********* p3config ************/ - - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool& cleanup, std::list& saveData); - virtual void saveDone(); - virtual bool loadList(std::list& load); - - static bool chatIdToVirtualPeerId(const ChatId& chat_id, RsPeerId& peer_id); - -private: - uint32_t nextMsgId; - std::map > mMessages; - - // Removes messages stored for more than mMaxMsgStorageDurationSeconds seconds. - // This avoids the stored list to grow crazy with time. - // - void cleanOldMessages() ; - - bool mPublicEnable; - bool mLobbyEnable; - bool mPrivateEnable; - bool mDistantEnable; - - uint32_t mPublicSaveCount; - uint32_t mLobbySaveCount; - uint32_t mPrivateSaveCount; - uint32_t mDistantSaveCount; - - uint32_t mMaxStorageDurationSeconds ; - rstime_t mLastCleanTime ; - - std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ - - RsMutex mHistoryMtx; -}; - -#endif diff --git a/libretroshare/src/pqi/p3linkmgr.cc b/libretroshare/src/pqi/p3linkmgr.cc deleted file mode 100644 index 97a889b79..000000000 --- a/libretroshare/src/pqi/p3linkmgr.cc +++ /dev/null @@ -1,2209 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3linkmgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2011 by Robert Fernie. * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "pqi/p3linkmgr.h" - -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - -#include "rsserver/p3face.h" -#include "pqi/authssl.h" -#include "tcponudp/tou.h" -#include "util/extaddrfinder.h" -#include "util/dnsresolver.h" -#include "util/rsnet.h" -#include "pqi/authgpg.h" - - -#include "util/rsprint.h" -#include "util/rsdebug.h" -#include "util/rsstring.h" - -#include "rsitems/rsconfigitems.h" - -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsdht.h" -#include "retroshare/rsbanlist.h" - -/* Network setup States */ - -static struct RsLog::logInfo p3connectzoneInfo = {RsLog::Default, "p3connect"}; -#define p3connectzone &p3connectzoneInfo - -/**** - * #define LINKMGR_DEBUG 1 - * #define LINKMGR_DEBUG_LOG 1 - * #define LINKMGR_DEBUG_CONNFAIL 1 - * #define LINKMGR_DEBUG_ACTIONS 1 - * #define LINKMGR_DEBUG_LINKTYPE 1 - ***/ - -/**** - * #define DISABLE_UDP_CONNECTIONS 1 - ***/ - -/**** - * #define P3CONNMGR_NO_TCP_CONNECTIONS 1 - ***/ -/**** - * #define P3CONNMGR_NO_AUTO_CONNECTION 1 - ***/ - -//#define P3CONNMGR_NO_TCP_CONNECTIONS 1 - -const uint32_t P3CONNMGR_TCP_DEFAULT_DELAY = 3; /* 2 Seconds? is it be enough! */ -//const uint32_t P3CONNMGR_UDP_DEFAULT_DELAY = 3; /* 2 Seconds? is it be enough! */ - -const uint32_t P3CONNMGR_TCP_DEFAULT_PERIOD = 10; -const uint32_t P3CONNMGR_UDP_DEFAULT_PERIOD = 30; // this represents how long it stays at the default TTL (4), before rising. - -#define MAX_AVAIL_PERIOD 230 //times a peer stay in available state when not connected -#define MIN_RETRY_PERIOD 140 - -#define MAX_RANDOM_ATTEMPT_OFFSET 6 // seconds. - -void printConnectState(std::ostream &out, peerConnectState &peer); - -peerConnectAddress::peerConnectAddress() - :delay(0), period(0), type(0), flags(0), ts(0), bandwidth(0), domain_port(0) -{ - sockaddr_storage_clear(addr); - sockaddr_storage_clear(proxyaddr); - sockaddr_storage_clear(srcaddr); -} - - -peerAddrInfo::peerAddrInfo() - :found(false), type(0), ts(0) -{ -} - -peerConnectState::peerConnectState() - : dhtVisible(false), - connecttype(0), - actAsServer(false), - lastavailable(0), - lastattempt(0), - name(""), - state(0), - actions(0), - linkType(0), - source(0), - inConnAttempt(false), - wasDeniedConnection(false), - deniedTS(0), - deniedInConnAttempt(false) -{ -} - -std::string textPeerConnectState(peerConnectState &state) -{ - return "Id: " + state.id.toStdString() + "\n"; -} - -/********* - * NOTES: - * - * p3LinkMgr doesn't store anything. All configuration is handled by p3PeerMgr. - * - * p3LinkMgr recvs the Discovery / Dht / Status updates.... tries the address. - * at success the address is pushed to p3PeerMgr for storage. - * - */ - - -p3LinkMgrIMPL::p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr) - :mPeerMgr(peerMgr), mNetMgr(netMgr), mLinkMtx("p3LinkMgr"),mStatusChanged(false) -{ - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - mDNSResolver = new DNSResolver(); - mRetryPeriod = MIN_RETRY_PERIOD; - - /* setup Banned Ip Address - static for now - */ - - struct sockaddr_storage bip; - sockaddr_storage_clear(bip); - struct sockaddr_in *addr = (struct sockaddr_in *) &bip; - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = 1; - addr->sin_port = htons(0); - - mBannedIpList.push_back(bip); - } - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgr() Startup" << std::endl; -#endif - - return; -} - -p3LinkMgrIMPL::~p3LinkMgrIMPL() -{ - delete(mDNSResolver); -} - -bool p3LinkMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - mLocalAddress = addr; - - return true ; -} - -bool p3LinkMgrIMPL::getLocalAddress(struct sockaddr_storage &addr) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - addr = mLocalAddress; - return true; -} - - -bool p3LinkMgrIMPL::isOnline(const RsPeerId &ssl_id) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { - return false; - } - - if (it->second.state & RS_PEER_S_CONNECTED) - { - return true; - } - return false; -} - - - -uint32_t p3LinkMgrIMPL::getLinkType(const RsPeerId &ssl_id) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { - return 0; - } - - if (it->second.state & RS_PEER_S_CONNECTED) - { - return it->second.linkType; - } - return 0; -} - - - -void p3LinkMgrIMPL::getOnlineList(std::list &ssl_peers) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.state & RS_PEER_S_CONNECTED) - { - ssl_peers.push_back(it->first); - } - } - return; -} - -void p3LinkMgrIMPL::getFriendList(std::list &ssl_peers) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - ssl_peers.push_back(it->first); - } - return; -} - -bool p3LinkMgrIMPL::getPeerName(const RsPeerId &ssl_id, std::string &name) -{ - return mPeerMgr->getPeerName(ssl_id, name); -} - - -bool p3LinkMgrIMPL::getFriendNetStatus(const RsPeerId &id, peerConnectState &state) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) - { - return false; - } - - state = it->second; - - return true; -} - - - -void p3LinkMgrIMPL::setFriendVisibility(const RsPeerId &id, bool isVisible) -{ - /* set visibility */ - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) - { - /* */ - std::cerr << "p3LinkMgrIMPL::setFriendVisibility() ERROR peer unknown: " << id; - std::cerr << std::endl; - return; - } - - if (it->second.dhtVisible == isVisible) - { - /* no change in state */ - return; - } - - it->second.dhtVisible = isVisible; - - if (it->second.state & RS_PEER_S_CONNECTED) - { - /* dont worry about it */ - return; - } - } - - /* switch the NetAssistOn/Off */ - mNetMgr->netAssistFriend(id, isVisible); -} - - -void p3LinkMgrIMPL::tick() -{ - statusTick(); - tickMonitors(); -} - - -void p3LinkMgrIMPL::statusTick() -{ - /* iterate through peers ... - * if been available for long time ... remove flag - * if last attempt a while - retryConnect. - * etc. - */ - -#ifdef LINKMGR_DEBUG_TICK - std::cerr << "p3LinkMgrIMPL::statusTick()" << std::endl; -#endif - std::list retryIds; - //std::list dummyToRemove; - - { - rstime_t now = time(NULL); - rstime_t oldavail = now - MAX_AVAIL_PERIOD; - rstime_t retry = now - mRetryPeriod; - - RsStackMutex stack(mLinkMtx); /****** LOCK MUTEX ******/ - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.state & RS_PEER_S_CONNECTED) - { - continue; - } - - if ((it->second.state & RS_PEER_S_ONLINE) && - (it->second.lastavailable < oldavail)) - { -#ifdef LINKMGR_DEBUG_TICK - std::cerr << "p3LinkMgrIMPL::statusTick() ONLINE TIMEOUT for: "; - std::cerr << it->first; - std::cerr << std::endl; -#endif - it->second.state &= (~RS_PEER_S_ONLINE); - } - - if (it->second.lastattempt < retry) - { - retryIds.push_back(it->first); - } - } - } - -#ifndef P3CONNMGR_NO_AUTO_CONNECTION - std::list::iterator it2; - for(it2 = retryIds.begin(); it2 != retryIds.end(); ++it2) - { -#ifdef LINKMGR_DEBUG_TICK - std::cerr << "p3LinkMgrIMPL::statusTick() RETRY TIMEOUT for: "; - std::cerr << *it2; - std::cerr << std::endl; -#endif - /* retry it! */ - retryConnect(*it2); - } - -#endif - -} - - -/******************************** Network Status ********************************* - * Configuration Loading / Saving. - */ - -void p3LinkMgrIMPL::addMonitor(pqiMonitor *mon) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::list::iterator it; - it = std::find(clients.begin(), clients.end(), mon); - if (it != clients.end()) - { - return; - } - - mon->setLinkMgr(this); - clients.push_back(mon); - return; -} - -void p3LinkMgrIMPL::removeMonitor(pqiMonitor *mon) -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::list::iterator it; - it = std::find(clients.begin(), clients.end(), mon); - if (it == clients.end()) - { - return; - } - (*it)->setLinkMgr(NULL); - clients.erase(it); - - return; -} - -void p3LinkMgrIMPL::tickMonitors() -{ - bool doStatusChange = false; - std::list actionList; - std::map::iterator it; - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - if (mStatusChanged) - { -#ifdef LINKMGR_DEBUG_ACTIONS - std::cerr << "p3LinkMgrIMPL::tickMonitors() StatusChanged! List:" << std::endl; -#endif - /* assemble list */ - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.actions) - { - /* add in */ - pqipeer peer; - peer.id = it->second.id; - peer.name = it->second.name; - peer.state = it->second.state; - peer.actions = it->second.actions; - - /* reset action */ - it->second.actions = 0; - - actionList.push_back(peer); - -#ifdef LINKMGR_DEBUG_ACTIONS - std::cerr << "Friend: " << peer.name << " Id: " << peer.id.toStdString() << " State: " << peer.state; - if (peer.state & RS_PEER_S_FRIEND) - std::cerr << " S:RS_PEER_S_FRIEND"; - if (peer.state & RS_PEER_S_ONLINE) - std::cerr << " S:RS_PEER_S_ONLINE"; - if (peer.state & RS_PEER_S_CONNECTED) - std::cerr << " S:RS_PEER_S_CONNECTED"; - std::cerr << " Actions: " << peer.actions; - if (peer.actions & RS_PEER_NEW) - std::cerr << " A:RS_PEER_NEW"; - if (peer.actions & RS_PEER_MOVED) - std::cerr << " A:RS_PEER_MOVED"; - if (peer.actions & RS_PEER_CONNECTED) - std::cerr << " A:RS_PEER_CONNECTED"; - if (peer.actions & RS_PEER_DISCONNECTED) - std::cerr << " A:RS_PEER_DISCONNECTED"; - if (peer.actions & RS_PEER_CONNECT_REQ) - std::cerr << " A:RS_PEER_CONNECT_REQ"; - - std::cerr << std::endl; -#endif - -// if(peer.actions & RS_PEER_CONNECTED) -// { -// pqiIpAddress ip; -// ip.mAddr = it->second.currentConnAddrAttempt.addr; -// ip.mSeenTime = time(NULL); -// ip.mSrc = time(NULL); -// -// mPeerMgr->updateCurrentAddress(it->second.id,) -// std::cerr << "Peer " << it->second.id << " connected with IP " << sockaddr_storage_tostring(it->second.currentConnAddrAttempt.addr) << std::endl; -// } - - /* notify GUI */ - if (rsEvents && (peer.actions & RS_PEER_CONNECTED)) - { - auto e = std::make_shared(); - e->mConnectionInfoCode = RsConnectionEventCode::PEER_CONNECTED; - e->mSslId = peer.id; - rsEvents->postEvent(e); - } - if (rsEvents && (peer.actions & RS_PEER_DISCONNECTED)) - { - auto e = std::make_shared(); - e->mConnectionInfoCode = RsConnectionEventCode::PEER_DISCONNECTED; - e->mSslId = peer.id; - rsEvents->postEvent(e); - } - } - } - - /* do the Others as well! */ - for(it = mOthersList.begin(); it != mOthersList.end(); ++it) - { - if (it->second.actions) - { - /* add in */ - pqipeer peer; - peer.id = it->second.id; - peer.name = it->second.name; - peer.state = it->second.state; - peer.actions = it->second.actions; - - /* reset action */ - it->second.actions = 0; - -#ifdef LINKMGR_DEBUG_ACTIONS - std::cerr << "Other: " << peer.name << " Id: " << peer.id.toStdString() << " State: " << peer.state; - if (peer.state & RS_PEER_S_FRIEND) - std::cerr << " S:RS_PEER_S_FRIEND"; - if (peer.state & RS_PEER_S_ONLINE) - std::cerr << " S:RS_PEER_S_ONLINE"; - if (peer.state & RS_PEER_S_CONNECTED) - std::cerr << " S:RS_PEER_S_CONNECTED"; - std::cerr << " Actions: " << peer.actions; - if (peer.actions & RS_PEER_NEW) - std::cerr << " A:RS_PEER_NEW"; - if (peer.actions & RS_PEER_MOVED) - std::cerr << " A:RS_PEER_MOVED"; - if (peer.actions & RS_PEER_CONNECTED) - std::cerr << " A:RS_PEER_CONNECTED"; - if (peer.actions & RS_PEER_DISCONNECTED) - std::cerr << " A:RS_PEER_DISCONNECTED"; - if (peer.actions & RS_PEER_CONNECT_REQ) - std::cerr << " A:RS_PEER_CONNECT_REQ"; - - std::cerr << std::endl; -#endif - - actionList.push_back(peer); - } - } - mStatusChanged = false; - doStatusChange = true; - - } - } /****** UNLOCK STACK MUTEX ******/ - - - - - /* NOTE - clients is accessed without mutex protection!!!! - * At the moment this is okay - as they are only added at the start. - * IF this changes ---- must fix with second Mutex. - */ - - if (doStatusChange) - { -#ifdef LINKMGR_DEBUG_ACTIONS - std::cerr << "Sending to " << clients.size() << " monitorClients" << std::endl; -#endif - - /* send to all monitors */ - std::list::iterator mit; - for(mit = clients.begin(); mit != clients.end(); ++mit) - { - (*mit)->statusChange(actionList); - } - } - -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections - - /* notify all monitors */ - std::list::iterator mit; - for(mit = clients.begin(); mit != clients.end(); ++mit) { - (*mit)->statusChanged(); - } - -/////////////////////////////////////////////////////////// -#endif - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - /* Now Cleanup OthersList (served its purpose (MOVE Action)) */ - mOthersList.clear(); - } - -} - - -const RsPeerId& p3LinkMgrIMPL::getOwnId() -{ - return AuthSSL::getAuthSSL()->OwnId(); -} - - -bool p3LinkMgrIMPL::connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr, - struct sockaddr_storage &proxyaddr, - struct sockaddr_storage &srcaddr, - uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth, - std::string &domain_addr, uint16_t &domain_port) - -{ - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectAttempt() FAILED Not in FriendList! id: " << id << std::endl; -#endif - - return false; - } - - if (it->second.connAddrs.size() < 1) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectAttempt() FAILED No ConnectAddresses id: " << id << std::endl; -#endif - return false; - } - - - if (it->second.state & RS_PEER_S_CONNECTED) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectAttempt() Already FLAGGED as connected!!!!" << std::endl; - std::cerr << "p3LinkMgrIMPL::connectAttempt() But allowing anyway!!!" << std::endl; -#endif - - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::connectAttempt() ERROR ALREADY CONNECTED"); - - } - -#ifdef LINKMGR_DEBUG_LOG - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::connectAttempt() called id: " + id.toStdString()); -#endif - - it->second.lastattempt = time(NULL); - it->second.inConnAttempt = true; - it->second.currentConnAddrAttempt = it->second.connAddrs.front(); - it->second.connAddrs.pop_front(); - - raddr = it->second.currentConnAddrAttempt.addr; - delay = it->second.currentConnAddrAttempt.delay; - period = it->second.currentConnAddrAttempt.period; - type = it->second.currentConnAddrAttempt.type; - flags = it->second.currentConnAddrAttempt.flags; - - proxyaddr = it->second.currentConnAddrAttempt.proxyaddr; - srcaddr = it->second.currentConnAddrAttempt.srcaddr; - bandwidth = it->second.currentConnAddrAttempt.bandwidth; - - domain_addr = it->second.currentConnAddrAttempt.domain_addr; - domain_port = it->second.currentConnAddrAttempt.domain_port; - - /********* Setup LinkType parameters **********/ - -#define TRICKLE_LIMIT 2001 // 2kb -#define LOW_BANDWIDTH_LIMIT 5001 // 5kb - -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() Setting up LinkType" << std::endl; - std::cerr << "p3LinkMgrIMPL::connectAttempt() type = " << type << std::endl; -#endif - - it->second.linkType = 0; - if (type & RS_NET_CONN_TCP_ALL) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() type & TCP_ALL => TCP_UNKNOWN" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_TCP_UNKNOWN; - } - else if (type & RS_NET_CONN_UDP_ALL) - { - if (flags & RS_CB_FLAG_MODE_UDP_DIRECT) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() type & UDP_ALL && flags & DIRECT => UDP_DIRECT" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_UDP_DIRECT; - } - else if (flags & RS_CB_FLAG_MODE_UDP_PROXY) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() type & UDP_ALL && flags & PROXY => UDP_PROXY" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_UDP_PROXY; - } - else if (flags & RS_CB_FLAG_MODE_UDP_RELAY) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() type & UDP_ALL && flags & RELAY => UDP_RELAY" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_UDP_RELAY; - } - else - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() type & UDP_ALL && else => UDP_UNKNOWN" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_UDP_UNKNOWN; - } - } - else - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() else => TRANS_UNKNOWN" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_TRANS_UNKNOWN; - } - - if ((type & RS_NET_CONN_UDP_ALL) && (flags & RS_CB_FLAG_MODE_UDP_RELAY)) - { - if (bandwidth < TRICKLE_LIMIT) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() flags & RELAY && band < TRICKLE => SPEED_TRICKLE" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_SPEED_TRICKLE; - } - else if (bandwidth < LOW_BANDWIDTH_LIMIT) - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() flags & RELAY && band < LOW => SPEED_LOW" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_SPEED_LOW; - } - else - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() flags & RELAY && else => SPEED_NORMAL" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_SPEED_NORMAL; - } - } - else - { -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() else => SPEED_NORMAL" << std::endl; -#endif - it->second.linkType |= RS_NET_CONN_SPEED_NORMAL; - } - - uint32_t connType = mPeerMgr->getConnectionType(id); - it->second.linkType |= connType; - -#ifdef LINKMGR_DEBUG_LINKTYPE - std::cerr << "p3LinkMgrIMPL::connectAttempt() connType: " << connType << std::endl; - std::cerr << "p3LinkMgrIMPL::connectAttempt() final LinkType: " << it->second.linkType << std::endl; - - - std::cerr << "p3LinkMgrIMPL::connectAttempt() found an address: id: " << id << std::endl; - std::cerr << " laddr: " << sockaddr_storage_tostring(raddr) << " delay: " << delay << " period: " << period; - std::cerr << " type: " << type << std::endl; - std::cerr << "p3LinkMgrIMPL::connectAttempt() set LinkType to: " << it->second.linkType << std::endl; -#endif - - - /********* Setup LinkType parameters **********/ - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectAttempt() found an address: id: " << id << std::endl; - std::cerr << " laddr: " << sockaddr_storage_tostring(raddr) << " delay: " << delay << " period: " << period; - std::cerr << " type: " << type << std::endl; - std::cerr << "p3LinkMgrIMPL::connectAttempt() set LinkType to: " << it->second.linkType << std::endl; -#endif - if (sockaddr_storage_isnull(raddr)) { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectAttempt() WARNING: address or port is null" << std::endl; - std::cerr << " type: " << type << std::endl; -#endif - } - - return true; -} - - -/**************************** - * Update state, - * trigger retry if necessary, - * - * remove from DHT? - * - */ - -bool p3LinkMgrIMPL::connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address) -{ - bool doDhtAssist = false ; - bool updatePeerAddr = false; - bool updateLastContact = false; - -#ifdef LINKMGR_DEBUG - std::cerr << "Connection result with peer " << id << ": " << success << ". Is incoming: " << isIncomingConnection << ", remote addr: " << sockaddr_storage_tostring(remote_peer_address) << std::endl; -#endif - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - - if (id == getOwnId()) - { - rslog(RSL_ALERT, p3connectzone, "p3LinkMgrIMPL::connectResult() ERROR Trying to Connect to OwnId: " + id.toStdString()); - - return false; - } - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) - { - rslog(RSL_ALERT, p3connectzone, "p3LinkMgrIMPL::connectResult() ERROR Missing Friend: " + id.toStdString()); - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() ERROR, missing Friend " << " id: " << id << std::endl; -#endif - return false; - } - - /* now we can tell if we think we were connected - proper point to log */ - - { - std::string out = "p3LinkMgrIMPL::connectResult() id: " + id.toStdString(); - if (success) - { - out += " SUCCESS "; - if (it->second.state & RS_PEER_S_CONNECTED) - { - out += " WARNING: State says: Already Connected"; - } - } - else - { - if (it->second.state & RS_PEER_S_CONNECTED) - { - out += " FAILURE OF THE CONNECTION (Was Connected)"; - } - else - { - out += " FAILED ATTEMPT (Not Connected)"; - } - } -#ifdef LINKMGR_DEBUG_LOG - rslog(RSL_WARNING, p3connectzone, out); -#endif - } - - - - if (success) - { - /* update address (should also come through from DISC) */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Connect!: id: " << id << std::endl; - std::cerr << " Success: " << success << " flags: " << flags << ", remote IP = " << sockaddr_storage_iptostring(remote_peer_address) << std::endl; -#endif - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Connect!: id: " << id << std::endl; - std::cerr << " Success: " << success << " flags: " << flags << std::endl; - - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::connectResult() Success"); -#endif - - /* change state */ - it->second.state |= RS_PEER_S_CONNECTED; - it->second.actions |= RS_PEER_CONNECTED; - it->second.connecttype = flags; - it->second.connectaddr = remote_peer_address; - - it->second.actAsServer = isIncomingConnection; - - updateLastContact = true; /* time of connect */ - - /* only update the peer's address if we were in a connect attempt. - * Otherwise, they connected to us, and the address will be a - * random port of their outgoing TCP socket - * - * NB even if we received the connection, the IP address is likely to okay. - */ - - //used to send back to the peer it's own ext address - //it->second.currentserveraddr = remote_peer_address; - - // THIS TEST IS A Bit BAD XXX, we should update their address anyway... - // This means we only update connections that we've made.. so maybe not too bad? - - if ((it->second.inConnAttempt) && - (sockaddr_storage_same(it->second.currentConnAddrAttempt.addr, remote_peer_address))) - { - updatePeerAddr = true; -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() adding current peer address in list." << std::endl; -#endif - } - - /* remove other attempts */ - it->second.inConnAttempt = false; - it->second.connAddrs.clear(); - mStatusChanged = true; - } - else - { -#ifdef LINKMGR_DEBUG_CONNFAIL - std::cerr << "p3LinkMgrIMPL::connectResult() Disconnect/Fail: flags: " << flags << " id: " << id; - std::cerr << std::endl; - - if (it->second.inConnAttempt) - { - std::cerr << "p3LinkMgrIMPL::connectResult() Likely Connect Fail, as inConnAttempt Flag is set"; - std::cerr << std::endl; - } - if (it->second.state & RS_PEER_S_CONNECTED) - { - std::cerr << "p3LinkMgrIMPL::connectResult() Likely DISCONNECT, as state set to Connected"; - std::cerr << std::endl; - } -#endif - - it->second.inConnAttempt = false; - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Disconnect/Fail: id: " << id << std::endl; - std::cerr << " Success: " << success << " flags: " << flags << std::endl; -#endif - - /* if currently connected -> flag as failed */ - if (it->second.state & RS_PEER_S_CONNECTED) - { - it->second.state &= (~RS_PEER_S_CONNECTED); - it->second.actions |= RS_PEER_DISCONNECTED; - mStatusChanged = true; - - updateLastContact = true; /* time of disconnect */ - } - - if (it->second.connAddrs.size() >= 1) - { - it->second.actions |= RS_PEER_CONNECT_REQ; - mStatusChanged = true; - } - - if (it->second.dhtVisible) - { - doDhtAssist = true; - } - } - } - - if (updatePeerAddr) - { - pqiIpAddress raddr; - raddr.mAddr = remote_peer_address; - raddr.mSeenTime = time(NULL); - raddr.mSrc = 0; - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Success and we initiated connection... Updating Address"; - std::cerr << std::endl; -#endif - mPeerMgr->updateCurrentAddress(id, raddr); - } - - if (updateLastContact) - { - mPeerMgr->updateLastContact(id); - } - - - /* inform NetAssist of result. This is slightly duplicating below, as we switch it on/off - * in a second anyway. However, the FAILURE of UDP connection, must be informed. - * - * actually the way the DHT works at the moment, both forms of feedback are required. - * this handles connection requests, the other searches. As they are independent... do both. - */ - - if (flags == RS_NET_CONN_UDP_ALL) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Sending Feedback for UDP connection"; - std::cerr << std::endl; -#endif - if (success) - { -#ifdef LINKMGR_DEBUG - 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 - - 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); - } - } - - - if (success) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Success switching off DhtAssist for friend: " << id; - std::cerr << std::endl; -#endif - /* always switch it off now */ - mNetMgr->netAssistFriend(id,false); - - /* inform NetMgr that we know this peers address: but only if external address */ - if (sockaddr_storage_isExternalNet(remote_peer_address)) - { - mNetMgr->netAssistKnownPeer(id,remote_peer_address, - NETASSIST_KNOWN_PEER_FRIEND | NETASSIST_KNOWN_PEER_ONLINE); - } - } - else - { - if (doDhtAssist) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Fail, Enabling DhtAssist for: " << id; - std::cerr << std::endl; -#endif - mNetMgr->netAssistFriend(id,true) ; - } - else - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::connectResult() Fail, No DhtAssist, as No DHT visibility for: " << id; - std::cerr << std::endl; -#endif - } - - /* inform NetMgr that this peer is offline */ - mNetMgr->netAssistKnownPeer(id,remote_peer_address, NETASSIST_KNOWN_PEER_FRIEND | NETASSIST_KNOWN_PEER_OFFLINE); - } - - return success; -} - -/******************************** Feedback ...... ********************************* - * From various sources - */ - -void p3LinkMgrIMPL::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, - uint32_t type, uint32_t flags, uint32_t source) -{ - /* HACKED UP FIX ****/ - - std::map::iterator it; - bool isFriend = true; - - rstime_t now = time(NULL); - - peerAddrInfo details; - details.type = type; - details.found = true; - details.addrs = addrs; - details.ts = now; - - bool updateNetConfig = (source == RS_CB_PERSON); - uint32_t peer_vs_disc = 0; - uint32_t peer_vs_dht = 0; - uint32_t peerNetMode = 0; - - int ownNetMode; - { - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - ownNetMode = ps.netMode; - } - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - { - /* Log */ - std::string out = "p3LinkMgrIMPL::peerStatus() id: " + id.toStdString(); - rs_sprintf_append(out, " type: %lu flags: %lu source: %lu\n", type, flags, source); - addrs.printAddrs(out); - - rslog(RSL_WARNING, p3connectzone, out); -#ifdef LINKMGR_DEBUG - std::cerr << out << std::endl; -#endif - } - - /* look up the id */ - it = mFriendList.find(id); - if (it == mFriendList.end()) - { - /* check Others list */ - isFriend = false; - it = mOthersList.find(id); - if (it == mOthersList.end()) - { - /* not found - ignore */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Peer Not Found - Ignore" << std::endl; -#endif - return; - } -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Peer is in mOthersList" << std::endl; -#endif - } - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Current Peer State:" << std::endl; - printConnectState(std::cerr, it->second); - std::cerr << std::endl; -#endif - - /* update the status */ - - /* if source is DHT */ - if (source == RS_CB_DHT) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Update From DHT:"; - std::cerr << std::endl; -#endif - /* DHT can tell us about - * 1) connect type (UDP/TCP/etc) - * 2) local/external address - */ - it->second.source = RS_CB_DHT; - it->second.dht = details; - - /* If we get a info -> then they are online */ - it->second.state |= RS_PEER_S_ONLINE; - it->second.lastavailable = now; - - } - else if (source == RS_CB_DISC) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Update From DISC:"; - std::cerr << std::endl; -#endif - /* DISC can tell us about - * 1) connect type (UDP/TCP/etc) - * 2) local/external addresses - */ - it->second.source = RS_CB_DISC; - it->second.disc = details; - - - if (flags & RS_NET_FLAGS_ONLINE) - { - it->second.actions |= RS_PEER_ONLINE; - it->second.state |= RS_PEER_S_ONLINE; - it->second.lastavailable = now; - mStatusChanged = true; - } - - } - else if (source == RS_CB_PERSON) - { - /* PERSON can tell us about - * 1) online / offline - * 2) connect address - * -> update all! - */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Update From PERSON:"; - std::cerr << std::endl; -#endif - - it->second.source = RS_CB_PERSON; - it->second.peer = details; - - it->second.state |= RS_PEER_S_ONLINE; - it->second.lastavailable = now; - - /* must be online to recv info (should be connected too!) - * but no need for action as should be connected already - * - * One problem with these states... is that we will never find them via DHT - * if these flags are switched off here... If we get a connection attempt via DHT - * we should switch the DHT search back on. - */ - - peerNetMode = 0; //it->second.netMode &= (~RS_NET_MODE_ACTUAL); /* clear actual flags */ - if (flags & RS_NET_FLAGS_EXTERNAL_ADDR) - { - peerNetMode = RS_NET_MODE_EXT; - } - else if (flags & RS_NET_FLAGS_STABLE_UDP) - { - peerNetMode = RS_NET_MODE_UDP; - } - else - { - peerNetMode = RS_NET_MODE_UNREACHABLE; - } - - - /* always update VIS status */ - if (flags & RS_NET_FLAGS_USE_DISC) - { - peer_vs_disc = RS_VS_DISC_FULL; - } - else - { - peer_vs_disc = RS_VS_DISC_OFF; - } - - if (flags & RS_NET_FLAGS_USE_DHT) - { - peer_vs_dht = RS_VS_DHT_FULL; - } - else - { - peer_vs_dht = RS_VS_DHT_OFF; - } - - - } - - /* Determine Reachability (only advisory) */ - if (ownNetMode & RS_NET_MODE_UDP) - { - if ((details.type & RS_NET_CONN_UDP_DHT_SYNC) || - (details.type & RS_NET_CONN_TCP_EXTERNAL)) - { - /* reachable! */ - it->second.state &= (~RS_PEER_S_UNREACHABLE); - } - else - { - /* unreachable */ - it->second.state |= RS_PEER_S_UNREACHABLE; - } - } - else if (ownNetMode & RS_NET_MODE_UNREACHABLE) - { - if (details.type & RS_NET_CONN_TCP_EXTERNAL) - { - /* reachable! */ - it->second.state &= (~RS_PEER_S_UNREACHABLE); - } - else - { - /* unreachable */ - it->second.state |= RS_PEER_S_UNREACHABLE; - } - } - else - { - it->second.state &= (~RS_PEER_S_UNREACHABLE); - } - - if (!isFriend) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() NOT FRIEND " << " id: " << id << std::endl; -#endif - - { - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::peerStatus() NO CONNECT (not friend)"); - } - return; - } - - /* if already connected -> done */ - if (it->second.state & RS_PEER_S_CONNECTED) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() PEER ONLINE ALREADY " << " id: " << id << std::endl; -#endif - { - /* Log */ - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::peerStatus() NO CONNECT (already connected!)"); - } - - return; - } - - - } /****** STACK UNLOCK MUTEX *******/ - - bool newAddrs = mPeerMgr->updateAddressList(id, addrs); - if (updateNetConfig) - { - mPeerMgr -> setVisState(id, peer_vs_disc, peer_vs_dht); - mPeerMgr -> setNetworkMode(id, peerNetMode); - } - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus()" << " id: " << id; - std::cerr << " type: " << type << " flags: " << flags; - std::cerr << " source: " << source << std::endl; - std::cerr << " addrs: " << std::endl; - std::string out; - addrs.printAddrs(out); - std::cerr << out << std::endl; - -#endif - -#ifndef P3CONNMGR_NO_AUTO_CONNECTION - -#ifndef P3CONNMGR_NO_TCP_CONNECTIONS - if (newAddrs) - { - retryConnectTCP(id); - } - -#endif // P3CONNMGR_NO_TCP_CONNECTIONS - - -#else -#endif // P3CONNMGR_NO_AUTO_CONNECTION - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerStatus() Resulting Peer State:" << std::endl; - printConnectState(std::cerr, it->second); - std::cerr << std::endl; -#endif - -} - -/* This has become very unwieldy - as extra arguments are required for UDP connections */ -void p3LinkMgrIMPL::peerConnectRequest( - const RsPeerId& id, const sockaddr_storage &raddr, - const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr, - uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth ) -{ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() id: " << id; - std::cerr << " raddr: " << sockaddr_storage_tostring(raddr); - std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr); - std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr); - std::cerr << " source: " << source; - std::cerr << " flags: " << flags; - std::cerr << " delay: " << delay; - std::cerr << " bandwidth: " << bandwidth; - std::cerr << std::endl; -#endif - { - /* Log */ - std::string out = "p3LinkMgrIMPL::peerConnectRequest() id: " + id.toStdString(); - out += " raddr: "; - out += sockaddr_storage_tostring(raddr); - out += " proxyaddr: "; - out += sockaddr_storage_tostring(proxyaddr); - out += " srcaddr: "; - out += sockaddr_storage_tostring(srcaddr); - - rs_sprintf_append(out, " source: %lu", source); - rs_sprintf_append(out, " flags: %lu", flags); - rs_sprintf_append(out, " delay: %lu", delay); - rs_sprintf_append(out, " bandwidth: %lu", bandwidth); - - rslog(RSL_WARNING, p3connectzone, out); - } - - /******************** TCP PART *****************************/ - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() (From DHT Only)" << std::endl; -#endif - - if (source == RS_CB_DHT) - { - - if (flags & RS_CB_FLAG_MODE_TCP) - { - -#ifndef P3CONNMGR_NO_TCP_CONNECTIONS - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() DHT says Online ==> so try TCP"; - std::cerr << std::endl; -#endif - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() ERROR Peer is not Friend" << std::endl; -#endif - return; - } - - /* if already connected -> done */ - if (it->second.state & RS_PEER_S_CONNECTED) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() ERROR Peer Already Connected" << std::endl; -#endif - return; - } - /* setup specific attempt for DHT found address. */ - locked_ConnectAttempt_SpecificAddress(&(it->second), raddr); - } - - retryConnect(id); - -#endif - - } - else - { - /* UDP Attempt! */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() DHT says CONNECT ==> tryConnectUDP()"; - std::cerr << std::endl; -#endif - tryConnectUDP(id, raddr, proxyaddr, srcaddr, flags, delay, bandwidth); - - } - return; - - } - else - { // IS THIS USED??? - std::cerr << "p3LinkMgrIMPL::peerConnectRequest() ERROR source OTHER ==> NOOP" << std::endl; - std::cerr << std::endl; - - return; - } -} - - -/*******************************************************************/ -/*******************************************************************/ - /*************** External Control ****************/ -bool p3LinkMgrIMPL::retryConnect(const RsPeerId &id) -{ - /* push all available addresses onto the connect addr stack */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::retryConnect() id: " << id << std::endl; -#endif - -#ifndef P3CONNMGR_NO_TCP_CONNECTIONS - - retryConnectTCP(id); - -#endif // P3CONNMGR_NO_TCP_CONNECTIONS - - return true; -} - - - -bool p3LinkMgrIMPL::tryConnectUDP(const RsPeerId &id, const struct sockaddr_storage &rUdpAddr, - const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, - uint32_t flags, uint32_t delay, uint32_t bandwidth) - -{ - -#ifdef DISABLE_UDP_CONNECTIONS - - std::cerr << "p3LinkMgrIMPL::tryConnectUDP() CONNECTIONS DISABLED FOR NOW... id: " << id << std::endl; - - std::cerr << "p3LinkMgrIMPL::tryConnectUDP() PARAMS id: " << id; - std::cerr << " raddr: " << rs_inet_ntoa(rUdpAddr.sin_addr) << ":" << ntohs(rUdpAddr.sin_port); - std::cerr << " proxyaddr: " << rs_inet_ntoa(proxyaddr.sin_addr) << ":" << ntohs(proxyaddr.sin_port); - std::cerr << " srcaddr: " << rs_inet_ntoa(srcaddr.sin_addr) << ":" << ntohs(srcaddr.sin_port); - std::cerr << " flags: " << flags; - std::cerr << " delay: " << delay; - std::cerr << " bandwidth: " << bandwidth; - std::cerr << std::endl; - - mNetMgr->netAssistStatusUpdate(id, NETMGR_DHT_FEEDBACK_CONN_FAILED); - - return false; -#endif - - if (mPeerMgr->isHidden()) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::tryConnectUDP() isHidden(): no connection attempts for : " << id; - std::cerr << std::endl; -#endif - return false; - } - - - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - /* push all available addresses onto the connect addr stack */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::tryConnectUDP() id: " << id << std::endl; -#endif - - if (id == getOwnId()) { - #ifdef LINKMGR_DEBUG - rslog(RSL_WARNING, p3connectzone, "p3LinkMgrIMPL::retryConnectUDP() Failed, connecting to own id: "); - #endif - return false; - } - - /* look up the id */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::retryConnectUDP() Peer is not Friend" << std::endl; -#endif - return false; - } - - /* if already connected -> done */ - if (it->second.state & RS_PEER_S_CONNECTED) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::retryConnectUDP() Peer Already Connected" << std::endl; -#endif - return false; - } - - /* Explicit Request to start the UDP connection */ - if (sockaddr_storage_isValidNet(rUdpAddr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "Adding udp connection attempt: "; - std::cerr << "Addr: " << sockaddr_storage_tostring(rUdpAddr); - std::cerr << std::endl; -#endif - peerConnectAddress pca; - pca.addr = rUdpAddr; - pca.type = RS_NET_CONN_UDP_PEER_SYNC; - pca.delay = delay; - pca.ts = time(NULL); - pca.period = P3CONNMGR_UDP_DEFAULT_PERIOD; - pca.flags = flags; - - pca.proxyaddr = proxyaddr; - pca.srcaddr = srcaddr; - pca.bandwidth = bandwidth; - - // Push address to the front... so it happens quickly (before any timings are lost). - addAddressIfUnique(it->second.connAddrs, pca, true); - } - - /* finish it off */ - return locked_ConnectAttempt_Complete(&(it->second)); -} - - - - -/* push all available addresses onto the connect addr stack... - * with the following exceptions: - * - id is our own - * - id is not our friend - * - id is already connected - * - id is hidden but of an unkown type - * - we are hidden but id is not - */ -bool p3LinkMgrIMPL::retryConnectTCP(const RsPeerId &id) -{ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::retryConnectTCP() id: " << id << std::endl; -#endif - - if (id == getOwnId()) return false; - - { - RS_STACK_MUTEX(mLinkMtx); - std::map::iterator it = mFriendList.find(id); - if ( it == mFriendList.end() ) return false; - if ( it->second.state & RS_PEER_S_CONNECTED ) return false; - } - - // Extract the required info from p3PeerMgr - - // first possibility - is it a hidden peer - if (mPeerMgr->isHiddenPeer(id)) - { - /* check for valid hidden type */ - uint32_t type = mPeerMgr->getHiddenType(id); - if ( type & (~RS_HIDDEN_TYPE_MASK) ) return false; - - /* then we just have one connect attempt via the Proxy */ - struct sockaddr_storage proxy_addr; - std::string domain_addr; - uint16_t domain_port; - if ( mPeerMgr->getProxyAddress(id, proxy_addr, domain_addr, domain_port) ) - { - RS_STACK_MUTEX(mLinkMtx); - std::map::iterator it = mFriendList.find(id); - if (it != mFriendList.end()) - { - locked_ConnectAttempt_ProxyAddress(&(it->second), type, proxy_addr, domain_addr, domain_port); - return locked_ConnectAttempt_Complete(&(it->second)); - } - } - - return false; - } - - if (mPeerMgr->isHidden()) return false; - - struct sockaddr_storage lAddr; - struct sockaddr_storage eAddr; - pqiIpAddrSet histAddrs; - std::string dyndns; - if (mPeerMgr->getConnectAddresses(id, lAddr, eAddr, histAddrs, dyndns)) - { - RS_STACK_MUTEX(mLinkMtx); - - std::map::iterator it = mFriendList.find(id); - if ( it != mFriendList.end() ) - { - locked_ConnectAttempt_CurrentAddresses(&(it->second), lAddr, eAddr); - - uint16_t dynPort = 0; - if (!sockaddr_storage_isnull(eAddr)) dynPort = sockaddr_storage_port(eAddr); - if (!dynPort && !sockaddr_storage_isnull(lAddr)) - dynPort = sockaddr_storage_port(lAddr); - if (dynPort) - locked_ConnectAttempt_AddDynDNS(&(it->second), dyndns, dynPort); - - locked_ConnectAttempt_HistoricalAddresses(&(it->second), histAddrs); - - // finish it off - return locked_ConnectAttempt_Complete(&(it->second)); - } - else - std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to find friend data : " << id << std::endl; - } - else - std::cerr << "p3LinkMgrIMPL::retryConnectTCP() ERROR failed to get addresses from PeerMgr for: " << id << std::endl; - - return false; -} - -bool p3LinkMgrIMPL::locked_CheckPotentialAddr(const sockaddr_storage& addr) -{ - /* if invalid - quick rejection */ - if ( ! sockaddr_storage_isValidNet(addr) ) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - INVALID"; - std::cerr << std::endl; -#endif - return false; - } - - std::list::const_iterator it; - for(it = mBannedIpList.begin(); it != mBannedIpList.end(); ++it) - { -#ifdef LINKMGR_DEBUG - std::cerr << "Checking IP w.r.t. banned IP " << sockaddr_storage_iptostring(*it) << std::endl; -#endif - - if (sockaddr_storage_sameip(*it, addr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() REJECTING - ON BANNED IPLIST"; - std::cerr << std::endl; -#endif - return false; - } - } - - if(rsBanList != NULL && !rsBanList->isAddressAccepted(addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_CheckPotentialAddr() adding to local Banned IPList"; - std::cerr << std::endl; -#endif - return false ; - } - - return true; -} - - -void p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, const struct sockaddr_storage &remoteAddr) -{ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses()"; - std::cerr << std::endl; -#endif - if(locked_CheckPotentialAddr(remoteAddr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_SpecificAddresses() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "Addr: " << sockaddr_storage_tostring(remoteAddr); - std::cerr << std::endl; -#endif - peerConnectAddress pca; - pca.addr = remoteAddr; - pca.type = RS_NET_CONN_TCP_EXTERNAL; - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - addAddressIfUnique(peer->connAddrs, pca, false); - } -} - - -void p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, const struct sockaddr_storage &localAddr, const struct sockaddr_storage &serverAddr) -{ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses()"; - std::cerr << std::endl; -#endif - // Just push all the addresses onto the stack. - /* try "current addresses" first */ - if (locked_CheckPotentialAddr(localAddr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "Current Local Addr: " << sockaddr_storage_tostring(localAddr); - std::cerr << std::endl; -#endif - peerConnectAddress pca; - pca.addr = localAddr; - pca.type = RS_NET_CONN_TCP_LOCAL; - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - addAddressIfUnique(peer->connAddrs, pca, false); - } - - if (locked_CheckPotentialAddr(serverAddr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_CurrentAddresses() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "Current Ext Addr: " << sockaddr_storage_tostring(serverAddr); - std::cerr << std::endl; -#endif - peerConnectAddress pca; - pca.addr = serverAddr; - pca.type = RS_NET_CONN_TCP_EXTERNAL; - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - addAddressIfUnique(peer->connAddrs, pca, false); - } -} - - -void p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses(peerConnectState *peer, const pqiIpAddrSet &ipAddrs) -{ - /* now try historical addresses */ - /* try local addresses first */ - std::list::const_iterator ait; - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses()"; - std::cerr << std::endl; -#endif - for(ait = ipAddrs.mLocal.mAddrs.begin(); ait != ipAddrs.mLocal.mAddrs.end(); ++ait) - { - if (locked_CheckPotentialAddr(ait->mAddr)) - { - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "Local Addr: " << sockaddr_storage_tostring(ait->mAddr); - std::cerr << std::endl; -#endif - - peerConnectAddress pca; - pca.addr = ait->mAddr; - pca.type = RS_NET_CONN_TCP_LOCAL; - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - addAddressIfUnique(peer->connAddrs, pca, false); - } - } - - for(ait = ipAddrs.mExt.mAddrs.begin(); - ait != ipAddrs.mExt.mAddrs.end(); ++ait) - { - if (locked_CheckPotentialAddr(ait->mAddr)) - { - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_HistoricalAddresses() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "Ext Addr: " << sockaddr_storage_tostring(ait->mAddr); - std::cerr << std::endl; -#endif - peerConnectAddress pca; - pca.addr = ait->mAddr; - pca.type = RS_NET_CONN_TCP_EXTERNAL; - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - addAddressIfUnique(peer->connAddrs, pca, false); - } - } -} - - -void p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS(peerConnectState *peer, std::string dyndns, uint16_t port) -{ - /* try dyndns address too */ - struct sockaddr_storage addr; - if (!dyndns.empty() && port) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS() Looking up DynDNS address: " << dyndns << std::endl; -#endif - if(mDNSResolver->getIPAddressFromString(dyndns, addr)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS() "; - std::cerr << "Adding tcp connection attempt: "; - std::cerr << "DynDNS Addr: " << sockaddr_storage_iptostring(addr); - std::cerr << ":" << port; - std::cerr << std::endl; -#endif - peerConnectAddress pca; - sockaddr_storage_copyip(pca.addr, addr); - sockaddr_storage_setport(pca.addr, port); - pca.type = RS_NET_CONN_TCP_EXTERNAL; - //for the delay, we add a random time and some more time when the friend list is big - pca.delay = P3CONNMGR_TCP_DEFAULT_DELAY; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - /* check address validity */ - if (locked_CheckPotentialAddr(pca.addr)) - { - addAddressIfUnique(peer->connAddrs, pca, true); - } - } - else - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS() DNSResolver hasn't found addr yet"; - std::cerr << std::endl; -#endif - } - } - else - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_AddDynDNS() Address(" << dyndns << ") or Port(" << port << ") NULL ignoring"; - std::cerr << std::endl; -#endif - } -} - - -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; -#endif - peerConnectAddress pca; - pca.addr = proxy_addr; - - 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; - pca.ts = time(NULL); - pca.period = P3CONNMGR_TCP_DEFAULT_PERIOD; - - sockaddr_storage_clear(pca.proxyaddr); - sockaddr_storage_clear(pca.srcaddr); - pca.bandwidth = 0; - - pca.domain_addr = domain_addr; - pca.domain_port = domain_port; - - /* check address validity */ - if (locked_CheckPotentialAddr(pca.addr)) - { - addAddressIfUnique(peer->connAddrs, pca, true); - } -} - - -bool p3LinkMgrIMPL::addAddressIfUnique(std::list &addrList, peerConnectAddress &pca, bool pushFront) -{ - /* iterate through the list, and make sure it isn't already - * in the list - */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::addAddressIfUnique() Checking Address: " << sockaddr_storage_iptostring(pca.addr); - std::cerr << std::endl; -#endif - - std::list::iterator it; - for(it = addrList.begin(); it != addrList.end(); ++it) - { - if (sockaddr_storage_same(pca.addr, it->addr) && - (pca.type == it->type)) - { -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::addAddressIfUnique() Discarding Duplicate Address"; - std::cerr << std::endl; -#endif - /* already */ - return false; - } - } - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::addAddressIfUnique() Adding New Address"; - std::cerr << std::endl; -#endif - - if (pushFront) - { - addrList.push_front(pca); - } - else - { - addrList.push_back(pca); - } - - return true; -} - - - -bool p3LinkMgrIMPL::locked_ConnectAttempt_Complete(peerConnectState *peer) -{ - - /* flag as last attempt to prevent loop */ - //add a random perturbation between 0 and 2 sec. - peer->lastattempt = time(NULL) + rand() % MAX_RANDOM_ATTEMPT_OFFSET; - - if (peer->inConnAttempt) - { - /* -> it'll automatically use the addresses we added */ -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_Complete() Already in CONNECT ATTEMPT"; - std::cerr << std::endl; - std::cerr << "p3LinkMgrIMPL::locked_ConnectAttempt_Complete() Remaining ConnAddr Count: " << peer->connAddrs.size(); - std::cerr << std::endl; -#endif - return true; - } - - /* start a connection attempt */ - if (peer->connAddrs.size() > 0) - { -#ifdef LINKMGR_DEBUG - std::string out = "p3LinkMgrIMPL::locked_ConnectAttempt_Complete() Started CONNECT ATTEMPT!\n" ; - rs_sprintf_append(out, "p3LinkMgrIMPL::locked_ConnectAttempt_Complete() ConnAddr Count: %u", peer->connAddrs.size()); - rslog(RSL_DEBUG_ALERT, p3connectzone, out); - std::cerr << out << std::endl; -#endif - - peer->actions |= RS_PEER_CONNECT_REQ; - mStatusChanged = true; - return true; - } - else - { -#ifdef LINKMGR_DEBUG - std::string out = "p3LinkMgrIMPL::locked_ConnectAttempt_Complete() No addr in the connect attempt list. Not suitable for CONNECT ATTEMPT!"; - rslog(RSL_DEBUG_ALERT, p3connectzone, out); - std::cerr << out << std::endl; -#endif - return false; - } - return false; -} - - -/*********************************************************************************************************** - ************************************* Handling of Friends ************************************************* - ***********************************************************************************************************/ - -int p3LinkMgrIMPL::addFriend(const RsPeerId &id, bool isVisible) -{ -#ifdef LINKMGR_DEBUG_LOG - rslog(RSL_WARNING, p3connectzone, "p3LinkMgr::addFriend() id: " + id.toStdString()); -#endif - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::addFriend(" << id << "," << isVisible << ")"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mFriendList.find(id); - - if (it != mFriendList.end()) - { - std::cerr << "p3LinkMgrIMPL::addFriend() ERROR, friend already exists : " << id; - std::cerr << std::endl; - return 0; - } - - peerConnectState pcs; - pcs.dhtVisible = isVisible; - pcs.id = id; - pcs.name = "NoName"; - pcs.state = RS_PEER_S_FRIEND; - pcs.actions = RS_PEER_NEW; - pcs.linkType = RS_NET_CONN_SPEED_UNKNOWN ; - - mFriendList[id] = pcs; - - mStatusChanged = true; - } - - mNetMgr->netAssistFriend(id, isVisible); - - return 1; -} - - -int p3LinkMgrIMPL::removeFriend(const RsPeerId &id) -{ - rslog(RSL_WARNING, p3connectzone, "p3LinkMgr::removeFriend() id: " + id.toStdString()); - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - #ifdef LINKMGR_DEBUG - std::cerr << "p3LinkMgrIMPL::removeFriend(" << id << ")"; - std::cerr << std::endl; - #endif - - std::map::iterator it; - it = mFriendList.find(id); - - if (it == mFriendList.end()) - { - std::cerr << "p3LinkMgrIMPL::removeFriend() ERROR, friend not there : " << id; - std::cerr << std::endl; - return 0; - } - - /* Move to OthersList (so remove can be handled via the action) */ - peerConnectState peer = it->second; - - peer.state &= (~RS_PEER_S_FRIEND); - peer.state &= (~RS_PEER_S_CONNECTED); - peer.state &= (~RS_PEER_S_ONLINE); - peer.actions = RS_PEER_MOVED; - peer.inConnAttempt = false; - mOthersList[id] = peer; - - mStatusChanged = true; - - mFriendList.erase(it); - } - - mNetMgr->netAssistFriend(id, false); - - return 1; -} - -void p3LinkMgrIMPL::disconnectFriend(const RsPeerId& id) -{ - std::list disconnect_clients ; - - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - disconnect_clients = clients ; - - std::cerr << "Disconnecting friend " << id << std::endl; - - std::map::iterator it; - it = mFriendList.find(id); - - if (it == mFriendList.end()) - { - std::cerr << "p3LinkMgrIMPL::removeFriend() ERROR, friend not there : " << id; - std::cerr << std::endl; - return ; - } - - /* Move to OthersList (so remove can be handled via the action) */ - peerConnectState peer = it->second; - - peer.state &= (~RS_PEER_S_CONNECTED); - peer.state &= (~RS_PEER_S_ONLINE); - peer.actions = RS_PEER_DISCONNECTED; - peer.inConnAttempt = false; - } - - for(std::list::const_iterator it(disconnect_clients.begin());it!=disconnect_clients.end();++it) - (*it)->disconnectPeer(id) ; -} - -void p3LinkMgrIMPL::printPeerLists(std::ostream &out) -{ - { - RsStackMutex stack(mLinkMtx); /****** STACK LOCK MUTEX *******/ - - out << "p3LinkMgrIMPL::printPeerLists() Friend List"; - out << std::endl; - - - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - out << "\t SSL ID: " << it->second.id.toStdString(); - out << "\t State: " << it->second.state; - out << std::endl; - } - - out << "p3LinkMgrIMPL::printPeerLists() Others List"; - out << std::endl; - for(it = mOthersList.begin(); it != mOthersList.end(); ++it) - { - out << "\t SSL ID: " << it->second.id.toStdString(); - out << "\t State: " << it->second.state; - } - } - - return; -} - -bool p3LinkMgrIMPL::checkPotentialAddr(const sockaddr_storage& addr) -{ - RS_STACK_MUTEX(mLinkMtx); - return locked_CheckPotentialAddr(addr); -} - - -void printConnectState(std::ostream &out, peerConnectState &peer) -{ - - out << "Friend: " << peer.name << " Id: " << peer.id.toStdString() << " State: " << peer.state; - if (peer.state & RS_PEER_S_FRIEND) - out << " S:RS_PEER_S_FRIEND"; - if (peer.state & RS_PEER_S_ONLINE) - out << " S:RS_PEER_S_ONLINE"; - if (peer.state & RS_PEER_S_CONNECTED) - out << " S:RS_PEER_S_CONNECTED"; - out << " Actions: " << peer.actions; - if (peer.actions & RS_PEER_NEW) - out << " A:RS_PEER_NEW"; - if (peer.actions & RS_PEER_MOVED) - out << " A:RS_PEER_MOVED"; - if (peer.actions & RS_PEER_CONNECTED) - out << " A:RS_PEER_CONNECTED"; - if (peer.actions & RS_PEER_DISCONNECTED) - out << " A:RS_PEER_DISCONNECTED"; - if (peer.actions & RS_PEER_CONNECT_REQ) - out << " A:RS_PEER_CONNECT_REQ"; - - out << std::endl; - return; -} - - - diff --git a/libretroshare/src/pqi/p3linkmgr.h b/libretroshare/src/pqi/p3linkmgr.h deleted file mode 100644 index 3b2c5c638..000000000 --- a/libretroshare/src/pqi/p3linkmgr.h +++ /dev/null @@ -1,340 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3linkmgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_LINK_MANAGER_HEADER -#define MRK_PQI_LINK_MANAGER_HEADER - -#include "pqi/pqimonitor.h" -#include "pqi/pqiipset.h" -#include "util/rstime.h" -#include "pqi/pqiassist.h" - -#include "pqi/p3cfgmgr.h" - -#include "util/rsthreads.h" - -class ExtAddrFinder ; -class DNSResolver ; - - -/* order of attempts ... */ -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_TOR = 0x0008; -const uint32_t RS_NET_CONN_TCP_HIDDEN_I2P = 0x0010; - -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! */ -const uint32_t RS_TCP_HIDDEN_TIMEOUT_PERIOD = 30; /* 30 seconds! */ -const uint32_t RS_UDP_STD_TIMEOUT_PERIOD = 80; /* 80 secs, allows UDP TTL to get to 40! - Plenty of time (30+80) = 110 secs */ - -class peerAddrInfo -{ - public: - peerAddrInfo(); /* init */ - - bool found; - uint32_t type; - pqiIpAddrSet addrs; - rstime_t ts; -}; - -class peerConnectAddress -{ - public: - peerConnectAddress(); /* init */ - - struct sockaddr_storage addr; - uint32_t delay; /* to stop simultaneous connects */ - uint32_t period; /* UDP only */ - uint32_t type; - uint32_t flags; /* CB FLAGS defined in pqimonitor.h */ - rstime_t ts; - - // Extra Parameters for Relay connections. - struct sockaddr_storage proxyaddr; - struct sockaddr_storage srcaddr; - uint32_t bandwidth; - - // Extra Parameters for Proxy/Hidden connection. - std::string domain_addr; - uint16_t domain_port; -}; - -class peerConnectState -{ - public: - peerConnectState(); /* init */ - - RsPeerId id; - - /***** Below here not stored permanently *****/ - - bool dhtVisible; - - uint32_t connecttype; // RS_NET_CONN_TCP_ALL / RS_NET_CONN_UDP_ALL - bool actAsServer; - rstime_t lastavailable; - rstime_t lastattempt; - - std::string name; - - uint32_t state; - uint32_t actions; - uint32_t linkType; - - uint32_t source; /* most current source */ - peerAddrInfo dht; - peerAddrInfo disc; - peerAddrInfo peer; - - struct sockaddr_storage connectaddr; // current connection address. Can be local or external. - - /* a list of connect attempts to make (in order) */ - bool inConnAttempt; - peerConnectAddress currentConnAddrAttempt; - std::list connAddrs; - - /* information about denial */ - bool wasDeniedConnection; - rstime_t deniedTS; - bool deniedInConnAttempt; /* is below valid */ - peerConnectAddress deniedConnectionAttempt; -}; - -class p3tunnel; -class RsPeerGroupItem_deprecated; -struct RsGroupInfo; - -class p3PeerMgr; -class p3NetMgr; - -class p3PeerMgrIMPL; -class p3NetMgrIMPL; - -std::string textPeerConnectState(peerConnectState &state); - -/******* - * Virtual Interface to allow testing - * - */ - -class p3LinkMgr: public pqiConnectCb -{ - public: - - p3LinkMgr() { return; } -virtual ~p3LinkMgr() { return; } - - -virtual const RsPeerId& getOwnId() = 0; -virtual bool isOnline(const RsPeerId &ssl_id) = 0; -virtual void getOnlineList(std::list &ssl_peers) = 0; -virtual bool getPeerName(const RsPeerId &ssl_id, std::string &name) = 0; -virtual uint32_t getLinkType(const RsPeerId &ssl_id) = 0; - - /**************** handle monitors *****************/ -virtual void addMonitor(pqiMonitor *mon) = 0; -virtual void removeMonitor(pqiMonitor *mon) = 0; - - /****************** Connections *******************/ -virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr, - struct sockaddr_storage &proxyaddr, struct sockaddr_storage &srcaddr, - uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth, - std::string &domain_addr, uint16_t &domain_port) = 0; - -virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address) = 0; -virtual bool retryConnect(const RsPeerId &id) = 0; - - /* Network Addresses */ -virtual bool setLocalAddress(const struct sockaddr_storage &addr) = 0; -virtual bool getLocalAddress(struct sockaddr_storage &addr) = 0; - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - -virtual void getFriendList(std::list &ssl_peers) = 0; // ONLY used by p3peers.cc USE p3PeerMgr instead. -virtual bool getFriendNetStatus(const RsPeerId &id, peerConnectState &state) = 0; // ONLY used by p3peers.cc - - virtual bool checkPotentialAddr(const sockaddr_storage& addr) = 0; - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ -virtual int addFriend(const RsPeerId &ssl_id, bool isVisible) = 0; - /******* overloaded from pqiConnectCb *************/ -// THESE MUSTn't BE specfied HERE - as overloaded from pqiConnectCb. -//virtual void peerStatus(std::string id, const pqiIpAddrSet &addrs, -// uint32_t type, uint32_t flags, uint32_t source) = 0; -//virtual void peerConnectRequest(std::string id, const struct sockaddr_storage &raddr, -// const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, -// uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0; - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - -}; - - - -class p3LinkMgrIMPL: public p3LinkMgr -{ - public: - -/************************************************************************************************/ -/* EXTERNAL INTERFACE */ -/************************************************************************************************/ - -virtual const RsPeerId& getOwnId(); -virtual bool isOnline(const RsPeerId &ssl_id); -virtual void getOnlineList(std::list &ssl_peers); -virtual bool getPeerName(const RsPeerId &ssl_id, std::string &name); -virtual uint32_t getLinkType(const RsPeerId &ssl_id); - - - /**************** handle monitors *****************/ -virtual void addMonitor(pqiMonitor *mon); -virtual void removeMonitor(pqiMonitor *mon); - - /****************** Connections *******************/ -virtual bool connectAttempt(const RsPeerId &id, struct sockaddr_storage &raddr, - struct sockaddr_storage &proxyaddr, struct sockaddr_storage &srcaddr, - uint32_t &delay, uint32_t &period, uint32_t &type, uint32_t &flags, uint32_t &bandwidth, - std::string &domain_addr, uint16_t &domain_port); - -virtual bool connectResult(const RsPeerId &id, bool success, bool isIncomingConnection, uint32_t flags, const struct sockaddr_storage &remote_peer_address); -virtual bool retryConnect(const RsPeerId &id); - - /* Network Addresses */ -virtual bool setLocalAddress(const struct sockaddr_storage &addr); -virtual bool getLocalAddress(struct sockaddr_storage &addr); - - /******* overloaded from pqiConnectCb *************/ -virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, - uint32_t type, uint32_t flags, uint32_t source); -virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, - const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, - uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth); - - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - -virtual void getFriendList(std::list &ssl_peers); // ONLY used by p3peers.cc USE p3PeerMgr instead. -virtual bool getFriendNetStatus(const RsPeerId &id, peerConnectState &state); // ONLY used by p3peers.cc - -/************************************************************************************************/ -/* Extra IMPL Functions (used by p3PeerMgr, p3NetMgr + Setup) */ -/************************************************************************************************/ - - p3LinkMgrIMPL(p3PeerMgrIMPL *peerMgr, p3NetMgrIMPL *netMgr); - virtual ~p3LinkMgrIMPL(); - -void tick(); - - /* THIS COULD BE ADDED TO INTERFACE */ -void setFriendVisibility(const RsPeerId &id, bool isVisible); - - void disconnectFriend(const RsPeerId& id) ; - - /* add/remove friends */ -virtual int addFriend(const RsPeerId &ssl_id, bool isVisible); -int removeFriend(const RsPeerId &ssl_id); - -void printPeerLists(std::ostream &out); - - virtual bool checkPotentialAddr(const sockaddr_storage& addr); - -protected: - /* THESE CAN PROBABLY BE REMOVED */ -//bool shutdown(); /* blocking shutdown call */ -//bool getOwnNetStatus(peerConnectState &state); - - -protected: - /****************** Internal Interface *******************/ - - /* Internal Functions */ -void statusTick(); - - /* monitor control */ -void tickMonitors(); - - /* connect attempts UDP */ -bool tryConnectUDP(const RsPeerId &id, const struct sockaddr_storage &rUdpAddr, - const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, - uint32_t flags, uint32_t delay, uint32_t bandwidth); - - /* connect attempts TCP */ -bool retryConnectTCP(const RsPeerId &id); - -void locked_ConnectAttempt_SpecificAddress(peerConnectState *peer, const struct sockaddr_storage &remoteAddr); -void locked_ConnectAttempt_CurrentAddresses(peerConnectState *peer, const struct sockaddr_storage &localAddr, const struct sockaddr_storage &serverAddr); -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 uint32_t type, const struct sockaddr_storage &proxy_addr, const std::string &domain_addr, uint16_t domain_port); - -bool locked_ConnectAttempt_Complete(peerConnectState *peer); - - bool locked_CheckPotentialAddr(const sockaddr_storage& addr); - -bool addAddressIfUnique(std::list &addrList, peerConnectAddress &pca, bool pushFront); - - -private: - // These should have their own Mutex Protection, - //p3tunnel *mP3tunnel; - DNSResolver *mDNSResolver ; - - p3PeerMgrIMPL *mPeerMgr; - p3NetMgrIMPL *mNetMgr; - - RsMutex mLinkMtx; /* protects below */ - - uint32_t mRetryPeriod; - - bool mStatusChanged; - - struct sockaddr_storage mLocalAddress; - - std::list clients; - - bool mAllowTunnelConnection; - - /* external Address determination */ - //bool mUpnpAddrValid, mStunAddrValid; - //struct sockaddr_in mUpnpExtAddr; - - //peerConnectState mOwnState; - - std::map mFriendList; - std::map mOthersList; - - /* relatively static list of banned ip addresses */ - std::list mBannedIpList; -}; - -#endif // MRK_PQI_LINK_MANAGER_HEADER diff --git a/libretroshare/src/pqi/p3netmgr.cc b/libretroshare/src/pqi/p3netmgr.cc deleted file mode 100644 index 32b413e7b..000000000 --- a/libretroshare/src/pqi/p3netmgr.cc +++ /dev/null @@ -1,2036 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3netmgr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2011 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstime.h" -#include - -#include "pqi/p3netmgr.h" - -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" - -#include "util/rsnet.h" -#include "util/rsrandom.h" -#include "util/rsdebug.h" - -#include "util/extaddrfinder.h" -#include "util/dnsresolver.h" - - -struct RsLog::logInfo p3netmgrzoneInfo = {RsLog::Default, "p3netmgr"}; -#define p3netmgrzone &p3netmgrzoneInfo - -#include "rsitems/rsconfigitems.h" - -#include "retroshare/rsiface.h" -#include "retroshare/rsconfig.h" -#include "retroshare/rsbanlist.h" - -/* Network setup States */ - -const uint32_t RS_NET_NEEDS_RESET = 0x0000; -const uint32_t RS_NET_UNKNOWN = 0x0001; -const uint32_t RS_NET_UPNP_INIT = 0x0002; -const uint32_t RS_NET_UPNP_SETUP = 0x0003; -const uint32_t RS_NET_EXT_SETUP = 0x0004; -const uint32_t RS_NET_DONE = 0x0005; -const uint32_t RS_NET_LOOPBACK = 0x0006; -//const uint32_t RS_NET_DOWN = 0x0007; - -/* Stun modes (TODO) */ -//const uint32_t RS_STUN_DHT = 0x0001; -//const uint32_t RS_STUN_DONE = 0x0002; -//const uint32_t RS_STUN_LIST_MIN = 100; -//const uint32_t RS_STUN_FOUND_MIN = 10; - -const uint32_t MAX_UPNP_INIT = 60; /* seconds UPnP timeout */ -const uint32_t MAX_UPNP_COMPLETE = 600; /* 10 min... seems to take a while */ -//const uint32_t MAX_NETWORK_INIT = 70; /* timeout before network reset */ - -//const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5; - -/**** - * #define NETMGR_DEBUG 1 - * #define NETMGR_DEBUG_RESET 1 - * #define NETMGR_DEBUG_TICK 1 - * #define NETMGR_DEBUG_STATEBOX 1 - ***/ -// #define NETMGR_DEBUG 1 -// #define NETMGR_DEBUG_RESET 1 -// #define NETMGR_DEBUG_TICK 1 -// #define NETMGR_DEBUG_STATEBOX 1 - -pqiNetStatus::pqiNetStatus() : - mExtAddrOk(false), mExtAddrStableOk(false), mUpnpOk(false), mDhtOk(false), - mDhtNetworkSize(0), mDhtRsNetworkSize(0), mResetReq(false) -{ - sockaddr_storage_clear(mLocalAddr); - sockaddr_storage_clear(mExtAddr); -} - - - -void pqiNetStatus::print(std::ostream &out) -{ - out << "pqiNetStatus: "; - out << " mExtAddrOk: " << mExtAddrOk; - out << " mExtAddrStableOk: " << mExtAddrStableOk; - out << std::endl; - out << " mUpnpOk: " << mUpnpOk; - out << " mDhtOk: " << mDhtOk; - out << " mResetReq: " << mResetReq; - out << std::endl; - out << "mDhtNetworkSize: " << mDhtNetworkSize << " mDhtRsNetworkSize: " << mDhtRsNetworkSize; - out << std::endl; - out << "mLocalAddr: " << sockaddr_storage_tostring(mLocalAddr) << " "; - out << "mExtAddr: " << sockaddr_storage_tostring(mExtAddr) << " "; - out << std::endl; -} - - -p3NetMgrIMPL::p3NetMgrIMPL() : mPeerMgr(nullptr), mLinkMgr(nullptr), - mNetMtx("p3NetMgr"), mNetStatus(RS_NET_UNKNOWN), mStatusChanged(false), - mDoNotNetCheckUntilTs(0) -{ - - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - mNetMode = RS_NET_MODE_UDP; - - mUseExtAddrFinder = true; - mExtAddrFinder = new ExtAddrFinder(); - mNetInitTS = 0; - - mNetFlags = pqiNetStatus(); - mOldNetFlags = pqiNetStatus(); - - mOldNatType = RsNatTypeMode::UNKNOWN; - mOldNatHole = RsNatHoleMode::UNKNOWN; - sockaddr_storage_clear(mLocalAddr); - sockaddr_storage_clear(mExtAddr); - - // force to IPv4 for the moment. - mLocalAddr.ss_family = AF_INET; - mExtAddr.ss_family = AF_INET; - - // default to full. - mVsDisc = RS_VS_DISC_FULL; - mVsDht = RS_VS_DHT_FULL; - - } - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgr() Startup" << std::endl; -#endif - - rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr() Startup, resetting network"); - netReset(); - - return; -} - -void p3NetMgrIMPL::setManagers(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr) -{ - mPeerMgr = peerMgr; - mLinkMgr = linkMgr; -} - -#ifdef RS_USE_DHT_STUNNER -void p3NetMgrIMPL::setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun) -{ - mDhtStunner = dhtStun; - mProxyStunner = proxyStun; -} -#endif // RS_USE_DHT_STUNNER - - -/***** Framework / initial implementation for a connection manager. - * - * This needs a state machine for Initialisation. - * - * Network state: - * RS_NET_UNKNOWN - * RS_NET_EXT_UNKNOWN * forwarded port (but Unknown Ext IP) * - * RS_NET_EXT_KNOWN * forwarded port with known IP/Port. * - * - * RS_NET_UPNP_CHECK * checking for UPnP * - * RS_NET_UPNP_KNOWN * confirmed UPnP ext Ip/port * - * - * RS_NET_UDP_UNKNOWN * not Ext/UPnP - to determine Ext IP/Port * - * RS_NET_UDP_KNOWN * have Stunned for Ext Addr * - * - * Transitions: - * - * RS_NET_UNKNOWN -(config)-> RS_NET_EXT_UNKNOWN - * RS_NET_UNKNOWN -(config)-> RS_NET_UPNP_UNKNOWN - * RS_NET_UNKNOWN -(config)-> RS_NET_UDP_UNKNOWN - * - * RS_NET_EXT_UNKNOWN -(DHT(ip)/Stun)-> RS_NET_EXT_KNOWN - * - * RS_NET_UPNP_UNKNOWN -(Upnp)-> RS_NET_UPNP_KNOWN - * RS_NET_UPNP_UNKNOWN -(timout/Upnp)-> RS_NET_UDP_UNKNOWN - * - * RS_NET_UDP_UNKNOWN -(stun)-> RS_NET_UDP_KNOWN - * - * - * STUN state: - * RS_STUN_INIT * done nothing * - * RS_STUN_DHT * looking up peers * - * RS_STUN_DONE * found active peer and stunned * - * - * - * Steps. - ******************************************************************* - * (1) Startup. - * - UDP port setup. - * - DHT setup. - * - Get Stun Keys -> add to DHT. - * - Feedback from DHT -> ask UDP to stun. - * - * (1) determine Network mode. - * If external Port.... Done: - * (2) - ******************************************************************* - * Stable operation: - * (1) tick and check peers. - * (2) handle callback. - * (3) notify of new/failed connections. - * - * - */ - -/* Called to reseet the whole network stack. this call is - * triggered by udp stun address tracking. - * - * must: - * - reset UPnP and DHT. - * - - */ - -void p3NetMgrIMPL::netReset() -{ -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() Called" << std::endl; -#endif - rslog(RSL_ALERT, p3netmgrzone, "p3NetMgr::netReset() Called"); - - shutdown(); /* blocking shutdown call */ - - // Will initiate a new call for determining the external ip. - if (mUseExtAddrFinder) - { -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() restarting AddrFinder" << std::endl; -#endif - mExtAddrFinder->reset() ; - } - else - { -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() ExtAddrFinder Disabled" << std::endl; -#endif - } - -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() resetting NetStatus" << std::endl; -#endif - - /* reset tcp network - if necessary */ - { - /* NOTE: nNetListeners should be protected via the Mutex. - * HOWEVER, as we NEVER change this list - once its setup - * we can get away without it - and assume its constant. - * - * NB: (*it)->reset_listener must be out of the mutex, - * as it calls back to p3ConnMgr. - */ - - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - struct sockaddr_storage iaddr = mLocalAddr; - -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() resetting listeners" << std::endl; -#endif - std::list::const_iterator it; - for(it = mNetListeners.begin(); it != mNetListeners.end(); ++it) - { - (*it)->resetListener(iaddr); -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() reset listener" << std::endl; -#endif - } - } - - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetStatus = RS_NET_UNKNOWN; - netStatusReset_locked(); - } - - updateNetStateBox_reset(); - -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netReset() done" << std::endl; -#endif -} - - -void p3NetMgrIMPL::netStatusReset_locked() -{ - //std::cerr << "p3NetMgrIMPL::netStatusReset()" << std::endl;; - - mNetFlags = pqiNetStatus(); -} - - -bool p3NetMgrIMPL::shutdown() /* blocking shutdown call */ -{ -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::shutdown()"; - std::cerr << std::endl; -#endif - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetStatus = RS_NET_UNKNOWN; - mNetInitTS = time(NULL); - netStatusReset_locked(); - } - netAssistFirewallShutdown(); - netAssistConnectShutdown(); - - return true; -} - - - - - - - - - -void p3NetMgrIMPL::netStartup() -{ - /* startup stuff */ - - /* StunInit gets a list of peers, and asks the DHT to find them... - * This is needed for all systems so startup straight away - */ -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup()" << std::endl; -#endif - - netDhtInit(); - - /* decide which net setup mode we're going into - */ - - - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - mNetInitTS = time(NULL); - netStatusReset_locked(); - -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() resetting mNetInitTS / Status" << std::endl; -#endif - mNetMode &= ~(RS_NET_MODE_ACTUAL); - - switch(mNetMode & RS_NET_MODE_TRYMODE) - { - - case RS_NET_MODE_TRY_EXT: /* v similar to UDP */ -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() TRY_EXT mode"; - std::cerr << std::endl; -#endif - mNetMode |= RS_NET_MODE_EXT; - mNetStatus = RS_NET_EXT_SETUP; - break; - - case RS_NET_MODE_TRY_UDP: -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() TRY_UDP mode"; - std::cerr << std::endl; -#endif - mNetMode |= RS_NET_MODE_UDP; - mNetStatus = RS_NET_EXT_SETUP; - break; - - case RS_NET_MODE_TRY_LOOPBACK: -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() TRY_LOOPBACK mode"; - std::cerr << std::endl; -#endif - mNetMode |= RS_NET_MODE_HIDDEN; - mNetStatus = RS_NET_LOOPBACK; - break; - - default: // Fall through. - -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() UNKNOWN mode"; - std::cerr << std::endl; -#endif - - case RS_NET_MODE_TRY_UPNP: -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::netStartup() TRY_UPNP mode"; - std::cerr << std::endl; -#endif - /* Force it here (could be default!) */ - mNetMode |= RS_NET_MODE_TRY_UPNP; - mNetMode |= RS_NET_MODE_UDP; /* set to UDP, upgraded is UPnP is Okay */ - mNetStatus = RS_NET_UPNP_INIT; - break; - } -} - - -void p3NetMgrIMPL::tick() -{ - rstime_t now = time(nullptr); - rstime_t dontCheckNetUntil; - { RS_STACK_MUTEX(mNetMtx); dontCheckNetUntil = mDoNotNetCheckUntilTs; } - - if(now >= dontCheckNetUntil) netStatusTick(); - - uint32_t netStatus; { RS_STACK_MUTEX(mNetMtx); netStatus = mNetStatus; } - switch (netStatus) - { - case RS_NET_LOOPBACK: - if(dontCheckNetUntil <= now) - { - RS_STACK_MUTEX(mNetMtx); - mDoNotNetCheckUntilTs = now + 30; - } - break; - default: - netAssistTick(); - updateNetStateBox_temporal(); -#ifdef RS_USE_DHT_STUNNER - if (mDhtStunner) mDhtStunner->tick(); - if (mProxyStunner) mProxyStunner->tick(); -#endif // RS_USE_DHT_STUNNER - break; - } -} - -#define STARTUP_DELAY 5 - - -void p3NetMgrIMPL::netStatusTick() -{ - -#ifdef NETMGR_DEBUG_TICK - std::cerr << "p3NetMgrIMPL::netTick()" << std::endl; - - std::cerr << "p3NetMgrIMPL::netTick() mNetMode: " << std::hex << mNetMode; - std::cerr << " ACTUALMODE: " << (mNetMode & RS_NET_MODE_ACTUAL); - std::cerr << " TRYMODE: " << (mNetMode & RS_NET_MODE_TRYMODE); - std::cerr << std::endl; -#endif - - // Check whether we are stuck on loopback. This happens if RS starts when - // the computer is not yet connected to the internet. In such a case we - // periodically check for a local net address. - // - checkNetAddress() ; - - uint32_t netStatus = 0; - rstime_t age = 0; - { - RsStackMutex stack(mNetMtx); /************** LOCK MUTEX ***************/ - - netStatus = mNetStatus; - age = time(NULL) - mNetInitTS; - - } - - if(netStatus <= RS_NET_UPNP_SETUP && mUseExtAddrFinder) - { - sockaddr_storage tmpip = mLocalAddr; // copies local port and correctly inits the IP family -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "Asking ExtAddrFinder for IP. Initializing port with " << sockaddr_storage_port(tmpip) << std::endl; -#endif - - if(mExtAddrFinder->hasValidIP(tmpip) && sockaddr_storage_ipv6_to_ipv4(tmpip) && !sockaddr_storage_same(tmpip,mExtAddr)) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl; -#endif - -#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 - setExtAddress(tmpip); - } - } - - switch(netStatus) - { - case RS_NET_NEEDS_RESET: - -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: NEEDS_RESET" << std::endl; -#endif - rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::netTick() RS_NET_NEEDS_RESET, resetting network"); - - netReset(); - break; - - case RS_NET_UNKNOWN: -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: UNKNOWN" << std::endl; -#endif - - /* add a small delay to stop restarting straight after a RESET - * This is so can we shutdown cleanly - */ - if (age < STARTUP_DELAY) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() Delaying Startup" << std::endl; -#endif - } - else - { - netStartup(); - } - - break; - - case RS_NET_UPNP_INIT: -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: UPNP_INIT" << std::endl; -#endif - netUpnpInit(); - break; - - case RS_NET_UPNP_SETUP: -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: UPNP_SETUP" << std::endl; -#endif - netUpnpCheck(); - break; - - - case RS_NET_EXT_SETUP: -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: EXT_SETUP" << std::endl; -#endif - // This could take a lot of time on some systems to get there: - // (e.g. 10 mins to get passed upnp on windows), so it would be better to call it right away, so other external address finding - // systems still have a chance to run early. - - netExtCheck(); - break; - - case RS_NET_DONE: -#ifdef NETMGR_DEBUG_TICK - std::cerr << "p3NetMgrIMPL::netTick() STATUS: DONE" << std::endl; -#endif - - break; - - case RS_NET_LOOPBACK: - //don't do a shutdown because a client in a computer without local network might be usefull for debug. - //shutdown(); -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netTick() STATUS: RS_NET_LOOPBACK" << std::endl; -#endif - default: - break; - } - - return; -} - - -void p3NetMgrIMPL::netDhtInit() -{ -#if defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netDhtInit()" << std::endl; -#endif - - uint32_t vs = 0; - { - RsStackMutex stack(mNetMtx); /*********** LOCKED MUTEX ************/ - vs = mVsDht; - } - - enableNetAssistConnect(vs != RS_VS_DHT_OFF); -} - - -void p3NetMgrIMPL::netUpnpInit() -{ -#if defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpInit()" << std::endl; -#endif - uint16_t eport, iport; - - mNetMtx.lock(); /* LOCK MUTEX */ - - /* get the ports from the configuration */ - - mNetStatus = RS_NET_UPNP_SETUP; - iport = sockaddr_storage_port(mLocalAddr); - eport = sockaddr_storage_port(mExtAddr); - if ((eport < 1000) || (eport > 30000)) - { - eport = iport; - } - - mNetMtx.unlock(); /* UNLOCK MUTEX */ - - netAssistFirewallPorts(iport, eport); - enableNetAssistFirewall(true); -} - -void p3NetMgrIMPL::netUpnpCheck() -{ - /* grab timestamp */ - mNetMtx.lock(); /* LOCK MUTEX */ - - rstime_t delta = time(NULL) - mNetInitTS; - -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpCheck() age: " << delta << std::endl; -#endif - - mNetMtx.unlock(); /* UNLOCK MUTEX */ - - struct sockaddr_storage extAddr; - int upnpState = netAssistFirewallActive(); - - if (((upnpState == 0) && (delta > (rstime_t)MAX_UPNP_INIT)) || - ((upnpState > 0) && (delta > (rstime_t)MAX_UPNP_COMPLETE))) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpCheck() "; - std::cerr << "Upnp Check failed." << std::endl; -#endif - /* fallback to UDP startup */ - mNetMtx.lock(); /* LOCK MUTEX */ - - /* UPnP Failed us! */ - mNetStatus = RS_NET_EXT_SETUP; - mNetFlags.mUpnpOk = false; - - mNetMtx.unlock(); /* UNLOCK MUTEX */ - } - else if ((upnpState > 0) && netAssistExtAddress(extAddr)) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpCheck() "; - std::cerr << "Upnp Check success state: " << upnpState << std::endl; -#endif - /* switch to UDP startup */ - mNetMtx.lock(); /* LOCK MUTEX */ - - /* Set Net Status flags .... - * we now have external upnp address. Golden! - * don't set netOk flag until have seen some traffic. - */ - if (sockaddr_storage_isValidNet(extAddr)) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpCheck() "; - std::cerr << "UpnpAddr: " << sockaddr_storage_tostring(extAddr); - std::cerr << std::endl; -#endif - mNetFlags.mUpnpOk = true; - mNetFlags.mExtAddr = extAddr; - mNetFlags.mExtAddrOk = true; - mNetFlags.mExtAddrStableOk = true; - - mNetStatus = RS_NET_EXT_SETUP; - /* Fix netMode & Clear others! */ - mNetMode = RS_NET_MODE_TRY_UPNP | RS_NET_MODE_UPNP; - } - mNetMtx.unlock(); /* UNLOCK MUTEX */ - } - else - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netUpnpCheck() "; - std::cerr << "Upnp Check Continues: status: " << upnpState << std::endl; -#endif - } - -} - -class ZeroInt -{ - public: - ZeroInt() { n=0; } - uint32_t n ; -}; - -void p3NetMgrIMPL::netExtCheck() -{ -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck()" << std::endl; -#endif - bool netSetupDone = false; - - { - RS_STACK_MUTEX(mNetMtx); - - bool isStable = false; - sockaddr_storage tmpip; - - std::map address_votes; - - /* check for External Address */ - /* in order of importance */ - /* (1) UPnP -> which handles itself */ - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok" << std::endl; -#endif - /* net Assist */ - if ( netAssistExtAddress(tmpip) && - sockaddr_storage_isValidNet(tmpip) && - sockaddr_storage_ipv6_to_ipv4(tmpip) ) - { - if( !rsBanList || - rsBanList->isAddressAccepted( - tmpip, RSBANLIST_CHECKING_FLAGS_BLACKLIST ) ) - { - // must be stable??? - isStable = true; - mNetFlags.mExtAddrOk = true; - mNetFlags.mExtAddrStableOk = isStable; - address_votes[tmpip].n++ ; - std::cerr << __PRETTY_FUNCTION__ << " 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; - } - } - - /* ask ExtAddrFinder */ - { - /* ExtAddrFinder */ - if (mUseExtAddrFinder) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() checking ExtAddrFinder" << std::endl; -#endif - sockaddr_storage tmpip = mLocalAddr; // copies local port and correctly inits the IP family - - bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip); - - if (extFinderOk && sockaddr_storage_ipv6_to_ipv4(tmpip)) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by ExtAddrFinder" << std::endl; -#endif - sockaddr_storage_setport(tmpip, guessNewExtPort()); - -#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.mExtAddrOk = true; - - address_votes[tmpip].n++ ; - - /* XXX HACK TO FIX drbob: ALLOWING - * ExtAddrFinder -> ExtAddrStableOk = true - * (which it is not normally) */ - mNetFlags.mExtAddrStableOk = true; - - std::cerr << __PRETTY_FUNCTION__ << " ExtAddrFinder " - << " reported external address " - << sockaddr_storage_iptostring(tmpip) - << std::endl; - } - } - } - - /* also ask peer mgr. */ - if (mPeerMgr) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() checking mPeerMgr" << std::endl; -#endif - uint8_t isstable; // unused - sockaddr_storage tmpaddr; - - if ( mPeerMgr->getExtAddressReportedByFriends(tmpaddr, isstable) && sockaddr_storage_ipv6_to_ipv4(tmpaddr) ) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext supplied by friends" << std::endl; -#endif - sockaddr_storage_setport(tmpaddr, guessNewExtPort()); - -#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.mExtAddrOk = true; - mNetFlags.mExtAddrStableOk = isstable; - - address_votes[tmpaddr].n++; - - std::cerr << __PRETTY_FUNCTION__ << " 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 - } - -#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. - // (sehraf) For the record: The udp stunner uses multiple (as for now: two) peers to ensure that the IP recieved is the correct one, see UdpStunner::locked_checkExternalAddress() - // Nevertheless this stays a more risky method to determine the external ip address. - - /* lastly ask the DhtStunner as fallback */ - if (address_votes.empty()) { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Not Ok, Checking DhtStunner" << std::endl; -#endif - uint8_t isstable = 0; - struct sockaddr_storage tmpaddr; - sockaddr_storage_clear(tmpaddr); - - if (mDhtStunner) - { - /* input network bits */ - if (mDhtStunner->getExternalAddr(tmpaddr, isstable)) - { - if((rsBanList == NULL) || 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++ ; -#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; -#endif - } - else - std::cerr << "(SS) DHTStunner returned wrong own IP " << sockaddr_storage_iptostring(tmpaddr) << " (banned). Rejecting." << std::endl; - } - } - } -#endif - - /* any other sources ??? */ - - /* finalise address */ - if (mNetFlags.mExtAddrOk) - { - // look at votes. - - 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." ; - - if(it->second.n > admax) - { - mNetFlags.mExtAddr = it->first ; - admax = it->second.n ; - - 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; -#endif - //update ip address list - mExtAddr = mNetFlags.mExtAddr; - - 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; -#endif - - - - 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; -#endif - - // 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; - - /* 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"; - - //notify->AddSysMessage(0, RS_SYS_WARNING, title, msg); - - std::cerr << msg << std::endl; - } - - } - - } - - if (mNetFlags.mExtAddrOk) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() setting netAssistSetAddress()" << std::endl; -#endif - netAssistSetAddress(mNetFlags.mLocalAddr, mNetFlags.mExtAddr, mNetMode); - } - - /* flag unreachables! */ - if ((mNetFlags.mExtAddrOk) && (!mNetFlags.mExtAddrStableOk)) - { -#if defined(NETMGR_DEBUG_TICK) || defined(NETMGR_DEBUG_RESET) - std::cerr << "p3NetMgrIMPL::netExtCheck() Ext Unstable - Unreachable Check" << std::endl; -#endif - } - } - - if (netSetupDone) - { - std::cerr << "p3NetMgrIMPL::netExtCheck() netSetupDone" << std::endl; - - /* Setup NetStateBox with this info */ - updateNetStateBox_startup(); - - /* update PeerMgr with correct info */ - if (mPeerMgr) - { - mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr); - } - - /* inform DHT about our external address */ - RsPeerId fakeId; - netAssistKnownPeer(fakeId, mExtAddr, NETASSIST_KNOWN_PEER_SELF | NETASSIST_KNOWN_PEER_ONLINE); - - std::cerr << __PRETTY_FUNCTION__ << " Network Setup Complete" - << std::endl; - } -} - -/********************************************************************************************** - ************************************** Interfaces ***************************************** - **********************************************************************************************/ - -bool p3NetMgrIMPL::checkNetAddress() -{ - bool addrChanged = false; - bool validAddr = false; - - sockaddr_storage prefAddr; - sockaddr_storage oldAddr; - - if (mNetMode & RS_NET_MODE_TRY_LOOPBACK) - { - RsInfo() << __PRETTY_FUNCTION__ <<" network mode set to LOOPBACK," - << " forcing address to 127.0.0.1" << std::endl; - - sockaddr_storage_ipv4_aton(prefAddr, "127.0.0.1"); - validAddr = true; - } - else - { - /* TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just one local - * address is a flawed assumption, this should be redesigned as soon as - * possible. It will require complete reenginering of the network layer - * code. */ - - /* For retro-compatibility strictly accept only IPv4 addresses here, - * IPv6 addresses are handled in a retro-compatible manner in - * p3PeerMgrIMPL::UpdateOwnAddress */ - std::vector addrs; - if (getLocalAddresses(addrs)) - { - for (auto it = addrs.begin(); it != addrs.end(); ++it) - { - sockaddr_storage& addr(*it); - if( sockaddr_storage_isValidNet(addr) && - !sockaddr_storage_isLoopbackNet(addr) && - !sockaddr_storage_isLinkLocalNet(addr) && - sockaddr_storage_ipv6_to_ipv4(addr) ) - { - prefAddr = addr; - validAddr = true; - break; - } - } - - /* If no satisfactory local address has been found yet relax and - * accept also link local addresses */ - if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it) - { - sockaddr_storage& addr(*it); - if( sockaddr_storage_isValidNet(addr) && - !sockaddr_storage_isLoopbackNet(addr) && - sockaddr_storage_ipv6_to_ipv4(addr) ) - { - prefAddr = addr; - validAddr = true; - break; - } - } - - /* If no satisfactory local address has been found yet relax and - * accept also loopback addresses */ - if(!validAddr) for (auto it = addrs.begin(); it!=addrs.end(); ++it) - { - sockaddr_storage& addr(*it); - if( sockaddr_storage_isValidNet(addr) && - sockaddr_storage_ipv6_to_ipv4(addr) ) - { - prefAddr = addr; - validAddr = true; - break; - } - } - } - } - - if (!validAddr) - { - RsErr() << __PRETTY_FUNCTION__ << " no valid local network address " - <<" found. Report to developers." << std::endl; - print_stacktrace(); - - return false; - } - - /* check addresses */ - { RS_STACK_MUTEX(mNetMtx); - - sockaddr_storage_copy(mLocalAddr, oldAddr); - addrChanged = !sockaddr_storage_sameip(prefAddr, mLocalAddr); - - // update address. - sockaddr_storage_copyip(mLocalAddr, prefAddr); - sockaddr_storage_copy(mLocalAddr, mNetFlags.mLocalAddr); - - if(sockaddr_storage_isLoopbackNet(mLocalAddr)) - mNetStatus = RS_NET_LOOPBACK; - - // Check if local port is valid, reset it if not - if (!sockaddr_storage_port(mLocalAddr)) - { - /* Using same port as external may make some NAT happier */ - uint16_t port = sockaddr_storage_port(mExtAddr); - - /* Avoid to automatically set a local port to a reserved one < 1024 - * that needs special permissions or root access. - * This do not impede the user to set a reserved port manually, - * which make sense in some cases. */ - - std::cerr << __PRETTY_FUNCTION__ << " local port is 0. Ext port is " << port ; - - while (port < 1025) - port = static_cast(RsRandom::random_u32()); - - std::cerr << " new ext port is " << port << ": using these for local/ext ports" << std::endl; - - sockaddr_storage_setport(mLocalAddr, port); - sockaddr_storage_setport(mExtAddr, port); // this accounts for when the port was updated - addrChanged = true; - } - } // RS_STACK_MUTEX(mNetMtx); - - if (addrChanged) - { - RsInfo() << __PRETTY_FUNCTION__ << " local address changed, resetting network." << std::endl; - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mNetworkEventCode = RsNetworkEventCode::LOCAL_IP_UPDATED; - ev->mIPAddress = sockaddr_storage_iptostring(mLocalAddr); - rsEvents->postEvent(ev); - } - - if (mPeerMgr) mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr); - - netReset(); - } - - return true; -} - - -/********************************************************************************************** - ************************************** Interfaces ***************************************** - **********************************************************************************************/ - -/* to allow resets of network stuff */ -void p3NetMgrIMPL::addNetListener(pqiNetListener *listener) -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetListeners.push_back(listener); -} - - - -bool p3NetMgrIMPL::setLocalAddress(const struct sockaddr_storage &addr) -{ - bool changed = false; - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - if (!sockaddr_storage_same(mLocalAddr, addr)) - { - changed = true; - } - - mLocalAddr = addr; - mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr); - } - - if (changed) - { -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::setLocalAddress() Calling NetReset" << std::endl; -#endif - rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::setLocalAddress() local address changed, resetting network"); - netReset(); - } - return true; -} -bool p3NetMgrIMPL::getExtAddress(struct sockaddr_storage& addr) -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - if(mNetFlags.mExtAddrOk) - { - addr = mNetFlags.mExtAddr ; - return true ; - } - else - return false ; -} - -bool p3NetMgrIMPL::setExtAddress(const struct sockaddr_storage &addr) -{ - bool changed = false; - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - if (!sockaddr_storage_same(mExtAddr, addr)) - { - changed = true; - } - - mExtAddr = addr; - mPeerMgr->UpdateOwnAddress(mLocalAddr, mExtAddr); - } - - if (changed) - { -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::setExtAddress() Calling NetReset" << std::endl; -#endif - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mNetworkEventCode = RsNetworkEventCode::EXTERNAL_IP_UPDATED; - ev->mIPAddress = sockaddr_storage_iptostring(addr); - rsEvents->postEvent(ev); - } - - rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::setExtAddress() ext address changed, resetting network"); - netReset(); - } - return true; -} - -bool p3NetMgrIMPL::setNetworkMode(uint32_t netMode) -{ - uint32_t oldNetMode; - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - /* only change TRY flags */ - - oldNetMode = mNetMode; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::setNetworkMode()"; - std::cerr << " Existing netMode: " << mNetMode; - std::cerr << " Input netMode: " << netMode; - std::cerr << std::endl; -#endif - mNetMode &= ~(RS_NET_MODE_TRYMODE); - - switch(netMode & RS_NET_MODE_ACTUAL) - { - case RS_NET_MODE_EXT: - mNetMode |= RS_NET_MODE_TRY_EXT; - break; - case RS_NET_MODE_UPNP: - mNetMode |= RS_NET_MODE_TRY_UPNP; - break; - case RS_NET_MODE_HIDDEN: - mNetMode |= RS_NET_MODE_TRY_LOOPBACK; - break; - default: - case RS_NET_MODE_UDP: - mNetMode |= RS_NET_MODE_TRY_UDP; - break; - } - } - - - if ((netMode & RS_NET_MODE_ACTUAL) != (oldNetMode & RS_NET_MODE_ACTUAL)) - { -#ifdef NETMGR_DEBUG_RESET - std::cerr << "p3NetMgrIMPL::setNetworkMode() Calling NetReset" << std::endl; -#endif - rslog(RSL_WARNING, p3netmgrzone, "p3NetMgr::setNetworkMode() Net Mode changed, resetting network"); - netReset(); - } - return true; -} - - -bool p3NetMgrIMPL::setVisState(uint16_t vs_disc, uint16_t vs_dht) -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mVsDisc = vs_disc; - mVsDht = vs_dht; - - /* if we've started up - then tweak Dht On/Off */ - if (mNetStatus != RS_NET_UNKNOWN) - { - enableNetAssistConnect(mVsDht != RS_VS_DHT_OFF); - } - - return true; -} - - -/********************************************************************************************** - ************************************** Interfaces ***************************************** - **********************************************************************************************/ - -void p3NetMgrIMPL::addNetAssistFirewall(uint32_t id, pqiNetAssistFirewall *fwAgent) -{ - mFwAgents[id] = fwAgent; -} - - -bool p3NetMgrIMPL::enableNetAssistFirewall(bool on) -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - (it->second)->enable(on); - } - return true; -} - - -bool p3NetMgrIMPL::netAssistFirewallEnabled() -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - if ((it->second)->getEnabled()) - { - return true; - } - } - return false; -} - -bool p3NetMgrIMPL::netAssistFirewallActive() -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - if ((it->second)->getActive()) - { - return true; - } - } - return false; -} - -bool p3NetMgrIMPL::netAssistFirewallShutdown() -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - (it->second)->shutdown(); - } - return true; -} - -bool p3NetMgrIMPL::netAssistFirewallPorts(uint16_t iport, uint16_t eport) -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - (it->second)->setInternalPort(iport); - (it->second)->setExternalPort(eport); - } - return true; -} - - -bool p3NetMgrIMPL::netAssistExtAddress(struct sockaddr_storage &extAddr) -{ - std::map::iterator it; - for(it = mFwAgents.begin(); it != mFwAgents.end(); ++it) - { - if ((it->second)->getActive()) - { - if ((it->second)->getExternalAddress(extAddr)) - { - return true; - } - } - } - return false; -} - - -void p3NetMgrIMPL::addNetAssistConnect(uint32_t id, pqiNetAssistConnect *dht) -{ - mDhts[id] = dht; -} - -bool p3NetMgrIMPL::enableNetAssistConnect(bool on) -{ - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::enableNetAssistConnect(" << on << ")"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->enable(on); - } - return true; -} - -bool p3NetMgrIMPL::netAssistConnectEnabled() -{ - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - if ((it->second)->getEnabled()) - { -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectEnabled() YES"; - std::cerr << std::endl; -#endif - - return true; - } - } - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectEnabled() NO"; - std::cerr << std::endl; -#endif - - return false; -} - -bool p3NetMgrIMPL::netAssistConnectActive() -{ - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - if ((it->second)->getActive()) - - { -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectActive() ACTIVE"; - std::cerr << std::endl; -#endif - - return true; - } - } - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectActive() INACTIVE"; - std::cerr << std::endl; -#endif - - return false; -} - -bool p3NetMgrIMPL::netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize) -{ - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - if (((it->second)->getActive()) && ((it->second)->getNetworkStats(netsize, localnetsize))) - - { -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectStats("; - std::cerr << netsize << ", " << localnetsize << ")"; - std::cerr << std::endl; -#endif - - return true; - } - } - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectStats() INACTIVE"; - std::cerr << std::endl; -#endif - - return false; -} - -bool p3NetMgrIMPL::netAssistConnectShutdown() -{ -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistConnectShutdown()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->shutdown(); - } - return true; -} - -bool p3NetMgrIMPL::netAssistFriend(const RsPeerId &id, bool on) -{ - std::map::iterator it; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistFriend(" << id << ", " << on << ")"; - std::cerr << std::endl; -#endif - - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - if (on) - (it->second)->findPeer(id); - else - (it->second)->dropPeer(id); - } - return true; -} - - -bool p3NetMgrIMPL::netAssistKnownPeer(const RsPeerId &id, const struct sockaddr_storage &addr, uint32_t flags) -{ - std::map::iterator it; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistKnownPeer(" << id << ")"; - std::cerr << std::endl; -#endif - - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->addKnownPeer(id, addr, flags); - } - return true; -} - -bool p3NetMgrIMPL::netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age) -{ - std::map::iterator it; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistBadPeer(" << sockaddr_storage_iptostring(addr) << ")"; - std::cerr << std::endl; -#endif - - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->addBadPeer(addr, reason, flags, age); - } - return true; -} - - -bool p3NetMgrIMPL::netAssistAttach(bool on) -{ - std::map::iterator it; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistAttach(" << on << ")"; - std::cerr << std::endl; -#endif - - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->setAttachMode(on); - } - return true; -} - - - -bool p3NetMgrIMPL::netAssistStatusUpdate(const RsPeerId &id, int state) -{ - std::map::iterator it; - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgrIMPL::netAssistStatusUpdate(" << id << ", " << state << ")"; - std::cerr << std::endl; -#endif - - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->ConnectionFeedback(id, state); - } - return true; -} - - -bool p3NetMgrIMPL::netAssistSetAddress( const struct sockaddr_storage & /*laddr*/, - const struct sockaddr_storage & /*eaddr*/, - uint32_t /*mode*/) -{ -#if 0 - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->setExternalInterface(laddr, eaddr, mode); - } -#endif - return true; -} - -void p3NetMgrIMPL::netAssistTick() -{ - std::map::iterator it; - for(it = mDhts.begin(); it != mDhts.end(); ++it) - { - (it->second)->tick(); - } - - std::map::iterator fit; - for(fit = mFwAgents.begin(); fit != mFwAgents.end(); ++fit) - { - (fit->second)->tick(); - } - return; -} - - - -/********************************************************************** - ********************************************************************** - ******************** Network State *********************************** - ********************************************************************** - **********************************************************************/ - -bool p3NetMgrIMPL::getUPnPState() -{ - return netAssistFirewallActive(); -} - -bool p3NetMgrIMPL::getUPnPEnabled() -{ - return netAssistFirewallEnabled(); -} - -bool p3NetMgrIMPL::getDHTEnabled() -{ - return netAssistConnectEnabled(); -} - - -void p3NetMgrIMPL::getNetStatus(pqiNetStatus &status) -{ - /* cannot lock local stack, then call DHT... as this can cause lock up */ - /* must extract data... then update mNetFlags */ - - bool dhtOk = netAssistConnectActive(); - uint32_t netsize = 0, rsnetsize = 0; - netAssistConnectStats(netsize, rsnetsize); - - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - /* quick update of the stuff that can change! */ - mNetFlags.mDhtOk = dhtOk; - mNetFlags.mDhtNetworkSize = netsize; - mNetFlags.mDhtRsNetworkSize = rsnetsize; - - status = mNetFlags; -} - - - - - - - - - -/********************************************************************************************** - ************************************** ExtAddrFinder ***************************************** - **********************************************************************************************/ - -bool p3NetMgrIMPL::getIPServersEnabled() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mUseExtAddrFinder; -} - -void p3NetMgrIMPL::getIPServersList(std::list& ip_servers) -{ - mExtAddrFinder->getIPServersList(ip_servers); -} - -void p3NetMgrIMPL::setIPServersEnabled(bool b) -{ - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mUseExtAddrFinder = b; - } - -#ifdef NETMGR_DEBUG - std::cerr << "p3NetMgr: setIPServers to " << b << std::endl ; -#endif - -} - - - -/********************************************************************************************** - ************************************** NetStateBox ****************************************** - **********************************************************************************************/ - -RsNetState p3NetMgrIMPL::getNetStateMode() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mNetStateBox.getNetStateMode(); -} - -RsNetworkMode p3NetMgrIMPL::getNetworkMode() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mNetStateBox.getNetworkMode(); -} - -RsNatTypeMode p3NetMgrIMPL::getNatTypeMode() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mNetStateBox.getNatTypeMode(); -} - -RsNatHoleMode p3NetMgrIMPL::getNatHoleMode() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mNetStateBox.getNatHoleMode(); -} - -RsConnectModes p3NetMgrIMPL::getConnectModes() -{ - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - return mNetStateBox.getConnectModes(); -} - - -/* These are the regular updates from Dht / Stunners */ -void p3NetMgrIMPL::updateNetStateBox_temporal() -{ -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() "; - std::cerr << std::endl; -#endif - struct sockaddr_storage tmpaddr; - sockaddr_storage_clear(tmpaddr); - -#ifdef RS_USE_DHT_STUNNER - uint8_t isstable = 0; - - if (mDhtStunner) - { - - /* input network bits */ - if (mDhtStunner->getExternalAddr(tmpaddr, isstable)) - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetStateBox.setAddressStunDht(tmpaddr, isstable); - -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() DhtStunner: "; - std::cerr << sockaddr_storage_tostring(tmpaddr); - std::cerr << " Stable: " << (uint32_t) isstable; - std::cerr << std::endl; -#endif - - } - } - - if (mProxyStunner) - { - - /* input network bits */ - if (mProxyStunner->getExternalAddr(tmpaddr, isstable)) - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetStateBox.setAddressStunProxy(tmpaddr, isstable); - -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() ProxyStunner: "; - std::cerr << sockaddr_storage_tostring(tmpaddr); - std::cerr << " Stable: " << (uint32_t) isstable; - std::cerr << std::endl; -#endif - - } - } -#endif // RS_USE_DHT_STUNNER - - - { - bool dhtOn = netAssistConnectEnabled(); - bool dhtActive = netAssistConnectActive(); - - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - mNetStateBox.setDhtState(dhtOn, dhtActive); - } - - - /* now we check if a WebIP address is required? */ - -#ifdef NETMGR_DEBUG_STATEBOX - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - auto netstate = mNetStateBox.getNetStateMode(); - auto netMode = mNetStateBox.getNetworkMode(); - auto natType = mNetStateBox.getNatTypeMode(); - auto natHole = mNetStateBox.getNatHoleMode(); - auto connect = mNetStateBox.getConnectModes(); -#ifdef SUSPENDED - auto netstatestr = NetStateNetStateString(netstate); - auto connectstr = NetStateConnectModesString(connect); - auto natholestr = NetStateNatHoleString(natHole); - auto nattypestr = NetStateNatTypeString(natType); - auto netmodestr = NetStateNetworkModeString(netMode); - - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() NetStateBox Thinking"; - std::cerr << std::endl; - std::cerr << "\tNetState: " << netstatestr; - std::cerr << std::endl; - std::cerr << "\tConnectModes: " << connectstr; - std::cerr << std::endl; - std::cerr << "\tNetworkMode: " << netmodestr; - std::cerr << std::endl; - std::cerr << "\tNatHole: " << natholestr; - std::cerr << std::endl; - std::cerr << "\tNatType: " << nattypestr; - std::cerr << std::endl; -#endif - - } -#endif - - updateNatSetting(); - -} - -#define NET_STUNNER_PERIOD_FAST (-1) // default of Stunner. -#define NET_STUNNER_PERIOD_SLOW (120) // This needs to be as small Routers will allow... try 2 minutes. -// FOR TESTING ONLY. -//#define NET_STUNNER_PERIOD_SLOW (60) // 3 minutes. - -void p3NetMgrIMPL::updateNatSetting() -{ - bool updateRefreshRate = false; - RsNatTypeMode natType = RsNatTypeMode::UNKNOWN; - RsNatHoleMode natHole = RsNatHoleMode::UNKNOWN; - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - natType = mNetStateBox.getNatTypeMode(); - natHole = mNetStateBox.getNatHoleMode(); - if ((natType != mOldNatType) || (natHole != mOldNatHole)) - { - mOldNatType = natType; - mOldNatHole = natHole; - updateRefreshRate = true; - -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() NatType Change!"; -// std::cerr << "\tNatType: " << NetStateNatTypeString(natType); -// std::cerr << "\tNatHole: "k << NetStateNatHoleString(natHole); - - std::cerr << std::endl; -#endif - - - } - } - - - // MUST also use this chance to set ATTACH flag for DHT. - if (updateRefreshRate) - { -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_temporal() Updating Refresh Rate, based on changed NatType"; - std::cerr << std::endl; -#endif - -#ifdef RS_USE_DHT_STUNNER - if (mProxyStunner) { - switch(natType) - { - case RsNatTypeMode::RESTRICTED_CONE: - { - if ((natHole == RsNatHoleMode::NONE) || (natHole == RsNatHoleMode::UNKNOWN)) - { - mProxyStunner->setRefreshPeriod(NET_STUNNER_PERIOD_FAST); - } - else - { - mProxyStunner->setRefreshPeriod(NET_STUNNER_PERIOD_SLOW); - } - break; - } - case RsNatTypeMode::NONE: - case RsNatTypeMode::UNKNOWN: - case RsNatTypeMode::SYMMETRIC: - case RsNatTypeMode::DETERM_SYM: - case RsNatTypeMode::FULL_CONE: - case RsNatTypeMode::OTHER: - - mProxyStunner->setRefreshPeriod(NET_STUNNER_PERIOD_SLOW); - break; - } - } -#endif // RS_USE_DHT_STUNNER - - /* This controls the Attach mode of the DHT... - * which effectively makes the DHT "attach" to Open Nodes. - * So that messages can get through. - * We only want to be attached - if we don't have a stable DHT port. - */ - if ((natHole == RsNatHoleMode::NONE) || (natHole == RsNatHoleMode::UNKNOWN)) - { - switch(natType) - { - /* switch to attach mode if we have a bad firewall */ - case RsNatTypeMode::UNKNOWN: - case RsNatTypeMode::SYMMETRIC: - case RsNatTypeMode::RESTRICTED_CONE: - case RsNatTypeMode::DETERM_SYM: - case RsNatTypeMode::OTHER: - netAssistAttach(true); - - break; - /* switch off attach mode if we have a nice firewall */ - case RsNatTypeMode::NONE: - case RsNatTypeMode::FULL_CONE: - netAssistAttach(false); - break; - } - } - else - { - // Switch off Firewall Mode (Attach) - netAssistAttach(false); - } - } -} - - - -void p3NetMgrIMPL::updateNetStateBox_startup() -{ -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << std::endl; -#endif - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - /* fill in the data */ - struct sockaddr_storage tmpip; - - /* net Assist */ - if (netAssistExtAddress(tmpip)) - { - -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << "Ext supplied from netAssistExternalAddress()"; - std::cerr << std::endl; -#endif - - if (sockaddr_storage_isValidNet(tmpip)) - { -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << "netAssist Returned: " << sockaddr_storage_tostring(tmpip); - std::cerr << std::endl; -#endif - mNetStateBox.setAddressUPnP(true, tmpip); - } - else - { - mNetStateBox.setAddressUPnP(false, tmpip); -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << "ERROR Bad Address supplied from netAssistExternalAddress()"; - std::cerr << std::endl; -#endif - } - } - else - { -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << " netAssistExtAddress() is not active"; - std::cerr << std::endl; -#endif - mNetStateBox.setAddressUPnP(false, tmpip); - } - - - /* ExtAddrFinder */ - if (mUseExtAddrFinder) - { - tmpip = mLocalAddr; - bool extFinderOk = mExtAddrFinder->hasValidIP(tmpip); - - if (extFinderOk) - { - sockaddr_storage_setport(tmpip, guessNewExtPort()); - -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << "ExtAddrFinder Returned: " << sockaddr_storage_iptostring(tmpip); - std::cerr << std::endl; -#endif - - mNetStateBox.setAddressWebIP(true, tmpip); - } - else - { - mNetStateBox.setAddressWebIP(false, tmpip); -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << " ExtAddrFinder hasn't found an address yet"; - std::cerr << std::endl; -#endif - } - } - else - { -#ifdef NETMGR_DEBUG_STATEBOX - std::cerr << "p3NetMgrIMPL::updateNetStateBox_startup() "; - std::cerr << " ExtAddrFinder is not active"; - std::cerr << std::endl; -#endif - mNetStateBox.setAddressWebIP(false, tmpip); - } - - - /* finally - if the user has set Forwarded, pass it on */ - if (mNetMode & RS_NET_MODE_TRY_EXT) - { - mNetStateBox.setPortForwarded(true, 0); // Port unknown for now. - } - } -} - -void p3NetMgrIMPL::updateNetStateBox_reset() -{ - { - RsStackMutex stack(mNetMtx); /****** STACK LOCK MUTEX *******/ - - mNetStateBox.reset(); - - mOldNatHole = RsNatHoleMode::UNKNOWN; - mOldNatType = RsNatTypeMode::UNKNOWN; - - } -} - -p3NetMgr::~p3NetMgr() = default; -pqiNetAssist::~pqiNetAssist() = default; -pqiNetAssistPeerShare::~pqiNetAssistPeerShare() = default; -pqiNetAssistConnect::~pqiNetAssistConnect() = default; diff --git a/libretroshare/src/pqi/p3netmgr.h b/libretroshare/src/pqi/p3netmgr.h deleted file mode 100644 index a847c07b1..000000000 --- a/libretroshare/src/pqi/p3netmgr.h +++ /dev/null @@ -1,330 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3netmgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "pqi/pqimonitor.h" -#include "pqi/pqiipset.h" -#include "pqi/pqiassist.h" -#include "pqi/pqinetstatebox.h" -#include "pqi/p3cfgmgr.h" -#include "util/rsthreads.h" -#include "util/rsdebug.h" - -class ExtAddrFinder ; -class DNSResolver ; - - /* RS_VIS_STATE_XXXX - * determines how public this peer wants to be... - * - * STD = advertise to Peers / DHT checking etc - * GRAY = share with friends / but not DHT - * DARK = hidden from all - * BROWN? = hidden from friends / but on DHT - */ - - - -struct pqiNetStatus -{ - pqiNetStatus(); - - bool mExtAddrOk; // have external address. - bool mExtAddrStableOk; // stable external address. - bool mUpnpOk; // upnp is ok. - bool mDhtOk; // dht is ok. - - uint32_t mDhtNetworkSize; - uint32_t mDhtRsNetworkSize; - - struct sockaddr_storage mLocalAddr; // percieved ext addr. - struct sockaddr_storage mExtAddr; // percieved ext addr. - - bool mResetReq; // Not Used yet!. - - void print(std::ostream &out); -}; - -class p3PeerMgr; -class p3LinkMgr; - -class p3PeerMgrIMPL; -class p3LinkMgrIMPL; - -class rsUdpStack; -class UdpStunner; -class p3BitDht; -class UdpRelayReceiver; - - -#define NETMGR_DHT_FEEDBACK_CONNECTED 0x0001 -#define NETMGR_DHT_FEEDBACK_CONN_FAILED 0x0002 -#define NETMGR_DHT_FEEDBACK_CONN_CLOSED 0x0003 - - -/********** - * p3NetMgr Interface.... - * This allows a drop-in replacement for testing. - */ - -class p3NetMgr -{ -public: - - /*************** External Control ****************/ - - // Setup Network State. -virtual bool setNetworkMode(uint32_t netMode) = 0; -virtual bool setVisState(uint16_t vs_disc, uint16_t vs_dht) = 0; - - // Switch DHT On/Off. -virtual bool netAssistFriend(const RsPeerId &id, bool on) = 0; -virtual bool netAssistKnownPeer(const RsPeerId &id, const struct sockaddr_storage &addr, uint32_t flags) = 0; -virtual bool netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0; -virtual bool netAssistStatusUpdate(const RsPeerId &id, int mode) = 0; - - /* Get Network State */ -virtual RsNetState getNetStateMode() = 0; -virtual RsNetworkMode getNetworkMode() = 0; -virtual RsNatTypeMode getNatTypeMode() = 0; -virtual RsNatHoleMode getNatHoleMode() = 0; -virtual RsConnectModes getConnectModes() = 0; - - /* Shut It Down! */ -virtual bool shutdown() = 0; /* blocking shutdown call */ - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - - // THESE SHOULD BE MOVED TO p3PeerMgr (as it controls the config). - // The functional object should be transformed into a NetAssistFirewall object. - // ONLY USED by p3peers.cc & p3peermgr.cc -virtual bool getIPServersEnabled() = 0; -virtual void setIPServersEnabled(bool b) = 0; -virtual void getIPServersList(std::list& ip_servers) = 0; - - // ONLY USED by p3face-config.cc WHICH WILL BE REMOVED. -virtual void getNetStatus(pqiNetStatus &status) = 0; -virtual bool getUPnPState() = 0; -virtual bool getUPnPEnabled() = 0; -virtual bool getDHTEnabled() = 0; - - virtual ~p3NetMgr(); -}; - - -class p3NetMgrIMPL: public p3NetMgr -{ -public: - - p3NetMgrIMPL(); - -/************************************************************************************************/ -/* EXTERNAL INTERFACE */ -/************************************************************************************************/ - - /*************** External Control ****************/ - - // Setup Network State. -virtual bool setNetworkMode(uint32_t netMode); -virtual bool setVisState(uint16_t vs_disc, uint16_t vs_dht); - - // Switch DHT On/Off. -virtual bool netAssistFriend(const RsPeerId &id, bool on); -virtual bool netAssistKnownPeer(const RsPeerId &id, const struct sockaddr_storage &addr, uint32_t flags); -virtual bool netAssistBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age); -virtual bool netAssistStatusUpdate(const RsPeerId &id, int mode); - - /* Get Network State */ -virtual RsNetState getNetStateMode(); -virtual RsNetworkMode getNetworkMode(); -virtual RsNatTypeMode getNatTypeMode(); -virtual RsNatHoleMode getNatHoleMode(); -virtual RsConnectModes getConnectModes(); - - /* Shut It Down! */ -virtual bool shutdown(); /* blocking shutdown call */ - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - - // THESE SHOULD BE MOVED TO p3PeerMgr (as it controls the config). - // The functional object should be transformed into a NetAssistFirewall object. - // ONLY USED by p3peers.cc & p3peermgr.cc -virtual bool getIPServersEnabled(); -virtual void setIPServersEnabled(bool b); -virtual void getIPServersList(std::list& ip_servers); - - // ONLY USED by p3face-config.cc WHICH WILL BE REMOVED. -virtual void getNetStatus(pqiNetStatus &status); -virtual bool getUPnPState(); -virtual bool getUPnPEnabled(); -virtual bool getDHTEnabled(); - -/************************************************************************************************/ -/* Extra IMPL Functions (used by p3PeerMgr, p3NetMgr + Setup) */ -/************************************************************************************************/ - -void setManagers(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr); -#ifdef RS_USE_DHT_STUNNER -void setAddrAssist(pqiAddrAssist *dhtStun, pqiAddrAssist *proxyStun); -#endif // RS_USE_DHT_STUNNER - -void tick(); - - // THESE MIGHT BE ADDED TO INTERFACE. -bool setLocalAddress(const struct sockaddr_storage &addr); -bool setExtAddress(const struct sockaddr_storage &addr); -bool getExtAddress(sockaddr_storage &addr); - - /*************** Setup ***************************/ -void addNetAssistConnect(uint32_t type, pqiNetAssistConnect *); -void addNetAssistFirewall(uint32_t type, pqiNetAssistFirewall *); - -void addNetListener(pqiNetListener *listener); - - // SHOULD MAKE THIS PROTECTED. -bool checkNetAddress(); /* check our address is sensible */ - -protected: - /****************** Internal Interface *******************/ -bool enableNetAssistFirewall(bool on); -bool netAssistFirewallEnabled(); -bool netAssistFirewallActive(); -bool netAssistFirewallShutdown(); - -bool enableNetAssistConnect(bool on); -bool netAssistConnectEnabled(); -bool netAssistConnectActive(); -bool netAssistConnectShutdown(); -bool netAssistConnectStats(uint32_t &netsize, uint32_t &localnetsize); - -void netAssistTick(); - -/* Assist Firewall */ -bool netAssistExtAddress(struct sockaddr_storage &extAddr); -bool netAssistFirewallPorts(uint16_t iport, uint16_t eport); - - /* Assist Connect */ -//virtual bool netAssistFriend(std::string id, bool on); (PUBLIC) -bool netAssistSetAddress(const struct sockaddr_storage &laddr, - const struct sockaddr_storage &eaddr, - uint32_t mode); - -bool netAssistAttach(bool on); - - - /* Internal Functions */ -void netReset(); - -void statusTick(); -void netStatusTick(); -void netStartup(); - - /* startup the bits */ -void netDhtInit(); -void netUdpInit(); -void netStunInit(); - - - -void netInit(); - -void netExtInit(); -void netExtCheck(); - -void netUpnpInit(); -void netUpnpCheck(); - -void netUnreachableCheck(); - - - /* net state via NetStateBox */ -void updateNetStateBox_temporal(); -void updateNetStateBox_startup(); -void updateNetStateBox_reset(); - void updateNatSetting(); - - /** Conservatively guess new external port, previous approach (aka always - * reset it to local port) break setups where external manually - * forwarded port is different then local port. A common case is having - * SSLH listening on port 80 on the router with public IP forwanding - * plain HTTP connections to a web server and --anyprot connections to - * retroshare to make censor/BOFH/bad firewall life a little more - * difficult */ - uint16_t guessNewExtPort() - { - uint16_t newExtPort = sockaddr_storage_port(mExtAddr); - if(!newExtPort) newExtPort = sockaddr_storage_port(mLocalAddr); - return newExtPort; - } - -private: - // These should have there own Mutex Protection, - ExtAddrFinder *mExtAddrFinder ; - - /* These are considered static from a MUTEX perspective */ - std::map mFwAgents; - std::map mDhts; - - std::list mNetListeners; - - p3PeerMgr *mPeerMgr; - p3LinkMgr *mLinkMgr; - - //p3BitDht *mBitDht; -#ifdef RS_USE_DHT_STUNNER - pqiAddrAssist *mDhtStunner = nullptr; - pqiAddrAssist *mProxyStunner = nullptr; -#endif // RS_USE_DHT_STUNNER - - RsMutex mNetMtx; /* protects below */ - -void netStatusReset_locked(); - - // TODO: Sat Oct 24 15:51:24 CEST 2015 The fact of having just two possible address is a flawed assumption, this should be redesigned soon. - struct sockaddr_storage mLocalAddr; - struct sockaddr_storage mExtAddr; - - uint32_t mNetMode; - uint16_t mVsDisc; - uint16_t mVsDht; - - rstime_t mNetInitTS; - uint32_t mNetStatus; - - bool mStatusChanged; - - bool mUseExtAddrFinder; - - /* network status flags (read by rsiface) */ - pqiNetStatus mNetFlags; - pqiNetStatus mOldNetFlags; - - - // Improved NetStatusBox, which uses the Stunners! - pqiNetStateBox mNetStateBox; - - rstime_t mDoNotNetCheckUntilTs; - RsNatTypeMode mOldNatType; - RsNatHoleMode mOldNatHole; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc deleted file mode 100644 index 772a7e9bb..000000000 --- a/libretroshare/src/pqi/p3notify.cc +++ /dev/null @@ -1,314 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3notify.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/p3notify.h" -#include -#include - -RsNotify *rsNotify = NULL ; - -/* Output for retroshare-gui */ -bool p3Notify::NotifySysMessage(uint32_t &sysid, uint32_t &type, - std::string &title, std::string &msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - if (pendingSysMsgs.size() > 0) - { - p3NotifySysMsg smsg = pendingSysMsgs.front(); - pendingSysMsgs.pop_front(); - - sysid = smsg.sysid; - type = smsg.type; - title = smsg.title; - msg = smsg.msg; - - return true; - } - - return false; -} - - /* Output for retroshare-gui */ -bool p3Notify::NotifyLogMessage(uint32_t &sysid, uint32_t &type, - std::string &title, std::string &msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - if (pendingLogMsgs.size() > 0) - { - p3NotifyLogMsg smsg = pendingLogMsgs.front(); - pendingLogMsgs.pop_front(); - - sysid = smsg.sysid; - type = smsg.type; - title = smsg.title; - msg = smsg.msg; - - return true; - } - - return false; -} - - -bool p3Notify::NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &title, std::string &msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - if (pendingPopupMsgs.size() > 0) - { - p3NotifyPopupMsg pmsg = pendingPopupMsgs.front(); - pendingPopupMsgs.pop_front(); - - ptype = pmsg.type; - name = pmsg.name; - title = pmsg.title; - msg = pmsg.msg; - - return true; - } - - return false; -} - - - /* Control over Messages */ -bool p3Notify::GetSysMessageList(std::map &list) -{ - (void) list; /* suppress unused parameter warning */ - return false; -} - -bool p3Notify::GetPopupMessageList(std::map &list) -{ - (void) list; /* suppress unused parameter warning */ - return false; -} - - -bool p3Notify::SetSysMessageMode(uint32_t sysid, uint32_t mode) -{ - (void) sysid; /* suppress unused parameter warning */ - (void) mode; /* suppress unused parameter warning */ - return false; -} - -bool p3Notify::SetPopupMessageMode(uint32_t ptype, uint32_t mode) -{ - (void) ptype; /* suppress unused parameter warning */ - (void) mode; /* suppress unused parameter warning */ - return false; -} - - - /* Input from libretroshare */ -bool p3Notify::AddPopupMessage(uint32_t ptype, const std::string& name, const std::string& title, const std::string& msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - - p3NotifyPopupMsg pmsg; - - pmsg.type = ptype; - pmsg.name = name; - pmsg.title = title; - pmsg.msg = msg; - - pendingPopupMsgs.push_back(pmsg); - - return true; -} - - -bool p3Notify::AddSysMessage(uint32_t sysid, uint32_t type, const std::string& title, const std::string& msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - - p3NotifySysMsg smsg; - - smsg.sysid = sysid; - smsg.type = type; - smsg.title = title; - smsg.msg = msg; - - pendingSysMsgs.push_back(smsg); - - return true; -} - -bool p3Notify::AddLogMessage(uint32_t sysid, uint32_t type, const std::string& title, const std::string& msg) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - - p3NotifyLogMsg smsg; - - smsg.sysid = sysid; - smsg.type = type; - smsg.title = title; - smsg.msg = msg; - - pendingLogMsgs.push_back(smsg); - - return true; -} - - -bool p3Notify::GetFeedItem(RsFeedItem &item) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - if (pendingNewsFeed.size() > 0) - { - item = pendingNewsFeed.front(); - pendingNewsFeed.pop_front(); - - return true; - } - - return false; -} - - -bool p3Notify::AddFeedItem(uint32_t type, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, uint32_t result1) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - pendingNewsFeed.push_back(RsFeedItem(type, id1, id2, id3, id4, result1)); - - return true; -} - -bool p3Notify::ClearFeedItems(uint32_t type) -{ - RsStackMutex stack(noteMtx); /************* LOCK MUTEX ************/ - - std::list::iterator it; - for(it = pendingNewsFeed.begin(); it != pendingNewsFeed.end(); ) - { - if (it->mType == type) - { - it = pendingNewsFeed.erase(it); - } - else - { - ++it; - } - } - return true; -} - -#define FOR_ALL_NOTIFY_CLIENTS for(std::list::const_iterator it(notifyClients.begin());it!=notifyClients.end();++it) - -void p3Notify::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,const RsGxsId& nickname,const std::string& any_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatLobbyEvent(lobby_id,event_type,nickname,any_string) ; } - -void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListPreChange(list,type) ; } -void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; } - -void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; } -void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; } -void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; } -void p3Notify::notifyChatCleared (const ChatId& chat_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatCleared(chat_id) ; } - -void p3Notify::notifyChatLobbyTimeShift (int time_shift) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatLobbyTimeShift(time_shift) ; } -void p3Notify::notifyCustomState (const std::string& peer_id , const std::string& status_string ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyCustomState (peer_id,status_string) ; } -void p3Notify::notifyHashingInfo (uint32_t type , const std::string& fileinfo ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyHashingInfo (type,fileinfo) ; } -void p3Notify::notifyTurtleSearchResult (const RsPeerId& pid , uint32_t search_id , const std::list& files ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyTurtleSearchResult(pid,search_id,files) ; } -#warning MISSING CODE HERE -//void p3Notify::notifyTurtleSearchResult (uint32_t search_id , const std::list& groups ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyTurtleSearchResult(search_id,groups) ; } -void p3Notify::notifyPeerHasNewAvatar (std::string peer_id ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerHasNewAvatar(peer_id) ; } -void p3Notify::notifyOwnAvatarChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyOwnAvatarChanged() ; } -void p3Notify::notifyOwnStatusMessageChanged() { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyOwnStatusMessageChanged() ; } -void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; } -void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; } - -void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; } -void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; } - -void p3Notify::notifyDownloadComplete (const std::string& fileHash ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDownloadComplete (fileHash) ; } -void p3Notify::notifyDownloadCompleteCount (uint32_t count ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDownloadCompleteCount (count) ; } -void p3Notify::notifyHistoryChanged (uint32_t msgId , int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyHistoryChanged (msgId,type) ; } - -bool p3Notify::cachePgpPassphrase(const std::string& s) -{ - clearPgpPassphrase() ; - cached_pgp_passphrase = s ; - - std::cerr << "(WW) Caching PGP passphrase." << std::endl; - return true ; -} -bool p3Notify::clearPgpPassphrase() -{ - std::cerr << "(WW) Clearing PGP passphrase." << std::endl; - - // Just whipe out the memory instead of just releasing it. - - for(uint32_t i=0;iaskForPassword(title,key_details,prev_is_bad,password,*cancelled) ) - return true; - - return false ; -} -bool p3Notify::askForPluginConfirmation (const std::string& plugin_filename, const std::string& plugin_file_hash,bool first_time) -{ - FOR_ALL_NOTIFY_CLIENTS - if( (*it)->askForPluginConfirmation(plugin_filename,plugin_file_hash,first_time)) - return true ; - - return false ; -} - -void p3Notify::registerNotifyClient(NotifyClient *cl) -{ - notifyClients.push_back(cl) ; -} - -bool p3Notify::unregisterNotifyClient(NotifyClient *nc) -{ - std::list::iterator it = std::find(notifyClients.begin(), notifyClients.end(), nc); - if(it != notifyClients.end()) - { - notifyClients.erase(it); - return true; - } - else - { - return false; - } -} diff --git a/libretroshare/src/pqi/p3notify.h b/libretroshare/src/pqi/p3notify.h deleted file mode 100644 index 3d78cdf8c..000000000 --- a/libretroshare/src/pqi/p3notify.h +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3notify.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_P3_NOTIFY_INTERFACE_H -#define RS_P3_NOTIFY_INTERFACE_H - -#include "retroshare/rsnotify.h" -#include "retroshare/rsturtle.h" - -#include "util/rsthreads.h" - -class p3NotifySysMsg -{ - public: - - uint32_t sysid; - uint32_t type; - std::string title; - std::string msg; -}; - -class p3NotifyLogMsg -{ - public: - - uint32_t sysid; - uint32_t type; - std::string title; - std::string msg; -}; - -class p3NotifyPopupMsg -{ - public: - - uint32_t type; - std::string name; - std::string title; - std::string msg; -}; - - -class p3Notify: public RsNotify -{ - public: - - p3Notify() : noteMtx("p3Notify"), _disableAskPassword(false) { return; } - virtual ~p3Notify() { return; } - - virtual void registerNotifyClient(NotifyClient *nc) ; - virtual bool unregisterNotifyClient(NotifyClient *nc) ; - - /* Pull output methods for retroshare-gui */ - virtual bool NotifySysMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg); - virtual bool NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &title, std::string &msg); - virtual bool NotifyLogMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg); - - virtual bool GetFeedItem(RsFeedItem &item); - - /* Control over Messages */ - bool GetSysMessageList(std::map &list); - bool GetPopupMessageList(std::map &list); - - bool SetSysMessageMode(uint32_t sysid, uint32_t mode); - bool SetPopupMessageMode(uint32_t ptype, uint32_t mode); - - /* Notify messages */ - bool AddPopupMessage(uint32_t ptype, const std::string& name, const std::string& title, const std::string& msg); - bool AddSysMessage(uint32_t sysid, uint32_t type, const std::string& title, const std::string& msg); - bool AddLogMessage(uint32_t sysid, uint32_t type, const std::string& title, const std::string& msg); - bool AddFeedItem(uint32_t type, const std::string& id1, const std::string& id2 = "", const std::string& id3 = "", const std::string& id4 = "", uint32_t result1 = 0); - bool ClearFeedItems(uint32_t type); - - // Notifications of clients. Can be called from anywhere inside libretroshare. - // - void notifyListPreChange (int /* list */, int /* type */) ; - void notifyListChange (int /* list */, int /* type */) ; - void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ; - void notifyChatMessage (const ChatMessage& /* msg */) ; - void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) ; - void notifyChatCleared (const ChatId& /* chat_id */) ; - void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ , const RsGxsId & /* nickname */, const std::string& /* any string */) ; - void notifyChatLobbyTimeShift (int /* time_shift*/) ; - void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) ; - void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) ; - void notifyTurtleSearchResult (const RsPeerId &pid, uint32_t /* search_id */, const std::list& /* files */) ; -#warning MISSING CODE HERE -// void notifyTurtleSearchResult (uint32_t /* search_id */, const std::list& /* groups */) ; - void notifyPeerHasNewAvatar (std::string /* peer_id */) ; - void notifyOwnAvatarChanged () ; - void notifyOwnStatusMessageChanged () ; - void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ; - void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ; - void notifyConnectionWithoutCert (); - - void notifyPeerStatusChangedSummary () ; - void notifyDiscInfoChanged () ; - - void notifyDownloadComplete (const std::string& /* fileHash */) ; - void notifyDownloadCompleteCount (uint32_t /* count */) ; - void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) ; - - bool askForPassword (const std::string& title, const std::string& /* key_details */, bool /* prev_is_bad */, std::string&, bool *cancelled /* password */ ) ; - bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool first_time) ; - - virtual bool cachePgpPassphrase (const std::string& /* pgp_passphrase */) ; - virtual bool clearPgpPassphrase () ; - - virtual bool setDisableAskPassword (const bool /*bValue*/) ; - - private: - - RsMutex noteMtx; - - std::list pendingSysMsgs; - std::list pendingLogMsgs; - std::list pendingPopupMsgs; - std::list pendingNewsFeed; - - std::list notifyClients ; - - std::string cached_pgp_passphrase; - bool _disableAskPassword; -}; - - -#endif diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc deleted file mode 100644 index 83c4d9366..000000000 --- a/libretroshare/src/pqi/p3peermgr.cc +++ /dev/null @@ -1,3183 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3peermgr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2011 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include // for std::vector -#include // for std::random_shuffle - -#include "rsserver/p3face.h" -#include "util/rsnet.h" -#include "pqi/authgpg.h" -#include "pqi/authssl.h" - -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" -#include "pqi/p3historymgr.h" -#include "pqi/pqinetwork.h" // for getLocalAddresses - -#include "util/rsprint.h" -#include "util/rsstring.h" -#include "util/rsdebug.h" - -#include "rsitems/rsconfigitems.h" - -#include "retroshare/rsiface.h" // Needed for rsicontrol (should remove this dependancy) -#include "retroshare/rspeers.h" // Needed for Group Parameters. -#include "retroshare/rsbanlist.h" // Needed for banned IPs - -/* Network setup States */ - -//Defined and used in /libretroshare/src/pqi/p3netmgr.cc -//const uint32_t RS_NET_NEEDS_RESET = 0x0000; -//const uint32_t RS_NET_UNKNOWN = 0x0001; -//const uint32_t RS_NET_UPNP_INIT = 0x0002; -//const uint32_t RS_NET_UPNP_SETUP = 0x0003; -//const uint32_t RS_NET_EXT_SETUP = 0x0004; -//const uint32_t RS_NET_DONE = 0x0005; -//const uint32_t RS_NET_LOOPBACK = 0x0006; -//const uint32_t RS_NET_DOWN = 0x0007; - -//const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5; - -//const uint32_t PEER_IP_CONNECT_STATE_MAX_LIST_SIZE = 4; - -static struct RsLog::logInfo p3peermgrzoneInfo = {RsLog::Default, "p3peermgr"}; -#define p3peermgrzone &p3peermgrzoneInfo - -/**** - * #define PEER_DEBUG 1 - * #define PEER_DEBUG_LOG 1 - ***/ - -#define MAX_AVAIL_PERIOD 230 //times a peer stay in available state when not connected -#define MIN_RETRY_PERIOD 140 - -static const std::string kConfigDefaultProxyServerIpAddr = "127.0.0.1"; -static const uint16_t kConfigDefaultProxyServerPortTor = 9050; // standard port. -static const uint16_t kConfigDefaultProxyServerPortI2P = 4447; // I2Pd's standard port - -static const std::string kConfigKeyExtIpFinder = "USE_EXTR_IP_FINDER"; -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() - :skip_pgp_signature_validation(false),netMode(RS_NET_MODE_UNKNOWN), vs_disc(RS_VS_DISC_FULL), vs_dht(RS_VS_DHT_FULL), lastcontact(0), - hiddenNode(false), hiddenPort(0), hiddenType(RS_HIDDEN_TYPE_NONE) -{ - sockaddr_storage_clear(localaddr); - sockaddr_storage_clear(serveraddr); - - return; -} - -std::string textPeerConnectState(peerState &state) -{ - std::string out = "Id: " + state.id.toStdString() + "\n"; - rs_sprintf_append(out, "NetMode: %lu\n", state.netMode); - rs_sprintf_append(out, "VisState: Disc: %u Dht: %u\n", state.vs_disc, state.vs_dht); - - out += "laddr: "; - out += sockaddr_storage_tostring(state.localaddr); - out += "\neaddr: "; - out += sockaddr_storage_tostring(state.serveraddr); - out += "\n"; - - return out; -} - - -p3PeerMgrIMPL::p3PeerMgrIMPL(const RsPeerId& ssl_own_id, const RsPgpId& gpg_own_id, const std::string& gpg_own_name, const std::string& ssl_own_location) - :p3Config(), mPeerMtx("p3PeerMgr"), mStatusChanged(false) -{ - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - mLinkMgr = NULL; - mNetMgr = NULL; - - /* setup basics of own state */ - mOwnState.id = ssl_own_id ; - mOwnState.gpg_id = gpg_own_id ; - mOwnState.name = gpg_own_name ; - mOwnState.location = ssl_own_location ; - mOwnState.netMode = RS_NET_MODE_UPNP; // Default to UPNP. - mOwnState.vs_disc = RS_VS_DISC_FULL; - mOwnState.vs_dht = RS_VS_DHT_FULL; - - // setup default ProxyServerAddress. - // Tor - sockaddr_storage_clear(mProxyServerAddressTor); - sockaddr_storage_ipv4_aton(mProxyServerAddressTor, - kConfigDefaultProxyServerIpAddr.c_str()); - 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); - - mProxyServerStatusTor = RS_NET_PROXY_STATUS_UNKNOWN ; - mProxyServerStatusI2P = RS_NET_PROXY_STATUS_UNKNOWN; - } - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgr() Startup" << std::endl; -#endif - - - return; -} - -void p3PeerMgrIMPL::setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr) -{ - mLinkMgr = linkMgr; - mNetMgr = netMgr; -} - - -bool p3PeerMgrIMPL::setupHiddenNode(const std::string &hiddenAddress, const uint16_t hiddenPort) -{ - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setupHiddenNode()"; - std::cerr << " Address: " << hiddenAddress; - std::cerr << " Port: " << hiddenPort; - std::cerr << std::endl; -#endif - - mOwnState.hiddenNode = true; - mOwnState.hiddenPort = hiddenPort; - mOwnState.hiddenDomain = hiddenAddress; - mOwnState.hiddenType = hiddenDomainToHiddenType(hiddenAddress); - } - - forceHiddenNode(); - return true; -} - - -bool p3PeerMgrIMPL::forceHiddenNode() -{ - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - if (RS_NET_MODE_HIDDEN != mOwnState.netMode) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::forceHiddenNode() Required!"; - std::cerr << std::endl; -#endif - } - mOwnState.hiddenNode = true; - mOwnState.hiddenType = hiddenDomainToHiddenType(mOwnState.hiddenDomain); - - // force external address - otherwise its invalid. - sockaddr_storage_clear(mOwnState.serveraddr); - sockaddr_storage_ipv4_aton(mOwnState.serveraddr, "0.0.0.0"); - sockaddr_storage_ipv4_setport(mOwnState.serveraddr, 0); - } - - setOwnNetworkMode(RS_NET_MODE_HIDDEN); - - // switch off DHT too. - setOwnVisState(mOwnState.vs_disc, RS_VS_DHT_OFF); - - // Force the Port. - struct sockaddr_storage loopback; - sockaddr_storage_clear(loopback); - sockaddr_storage_ipv4_aton(loopback, "127.0.0.1"); - uint16_t port = sockaddr_storage_port(mOwnState.localaddr); - sockaddr_storage_ipv4_setport(loopback, port); - - setLocalAddress(AuthSSL::getAuthSSL()->OwnId(), loopback); - - mNetMgr->setIPServersEnabled(false); - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - return true; -} - - -bool p3PeerMgrIMPL::setOwnNetworkMode(uint32_t netMode) -{ - bool changed = false; - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setOwnNetworkMode() :"; - std::cerr << " Existing netMode: " << mOwnState.netMode; - std::cerr << " Input netMode: " << netMode; - std::cerr << std::endl; -#endif - - if (mOwnState.netMode != (netMode & RS_NET_MODE_ACTUAL)) - { - mOwnState.netMode = (netMode & RS_NET_MODE_ACTUAL); - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - changed = true; - } - } - - // Pass on Flags to NetMgr. - mNetMgr->setNetworkMode((netMode & RS_NET_MODE_ACTUAL)); - return changed; -} - -bool p3PeerMgrIMPL::setOwnVisState(uint16_t vs_disc, uint16_t vs_dht) -{ - bool changed = false; - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::string out; - rs_sprintf(out, "p3PeerMgr::setOwnVisState() Existing vis: %u/%u Input vis: %u/%u", - mOwnState.vs_disc, mOwnState.vs_dht, vs_disc, vs_dht); - rslog(RSL_WARNING, p3peermgrzone, out); - -#ifdef PEER_DEBUG - std::cerr << out.c_str() << std::endl; -#endif - - if (mOwnState.vs_disc != vs_disc || mOwnState.vs_dht != vs_dht) - { - mOwnState.vs_disc = vs_disc; - mOwnState.vs_dht = vs_dht; - changed = true; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - } - - // Pass on Flags to NetMgr. - mNetMgr->setVisState(vs_disc, vs_dht); - - return changed; -} - - -void p3PeerMgrIMPL::tick() -{ - static const rstime_t INTERVAL_BETWEEN_LOCATION_CLEANING = 300 ; // Remove unused locations and clean IPs every 10 minutes. - - static rstime_t last_friends_check = time(NULL) ; // first cleaning after 1 hour. - - rstime_t now = time(NULL) ; - - if(now > INTERVAL_BETWEEN_LOCATION_CLEANING + last_friends_check ) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::tick(): cleaning unused locations." << std::endl ; -#endif - - rslog(RSL_WARNING, p3peermgrzone, "p3PeerMgr::tick() removeUnusedLocations()"); - - removeUnusedLocations() ; - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::tick(): cleaning banned/old IPs." << std::endl ; -#endif - removeBannedIps() ; - - last_friends_check = now ; - } -} - - -/******************************** Network Status ********************************* - * Configuration Loading / Saving. - */ - - -const RsPeerId& p3PeerMgrIMPL::getOwnId() -{ - return AuthSSL::getAuthSSL()->OwnId(); -} - - -bool p3PeerMgrIMPL::getOwnNetStatus(peerState &state) -{ - RS_STACK_MUTEX(mPeerMtx); - state = mOwnState; - return true; -} - -bool p3PeerMgrIMPL::isFriend(const RsPeerId& id) -{ -#ifdef PEER_DEBUG_COMMON - std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") called" << std::endl; -#endif - RS_STACK_MUTEX(mPeerMtx); - bool ret = (mFriendList.end() != mFriendList.find(id)); -#ifdef PEER_DEBUG_COMMON - std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") returning : " << ret << std::endl; -#endif - return ret; -} -bool p3PeerMgrIMPL::isSslOnlyFriend(const RsPeerId& id) -{ -#ifdef PEER_DEBUG_COMMON - std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") called" << std::endl; -#endif - RS_STACK_MUTEX(mPeerMtx); - auto it = mFriendList.find(id); - bool ret = it != mFriendList.end() && it->second.skip_pgp_signature_validation ; - -#ifdef PEER_DEBUG_COMMON - std::cerr << "p3PeerMgrIMPL::isFriend(" << id << ") returning : " << ret << std::endl; -#endif - return ret; -} - -bool p3PeerMgrIMPL::getPeerName(const RsPeerId &ssl_id, std::string &name) -{ - RS_STACK_MUTEX(mPeerMtx); - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { - return false; - } - - name = it->second.name + " (" + it->second.location + ")"; - return true; -} - -bool p3PeerMgrIMPL::getGpgId(const RsPeerId &ssl_id, RsPgpId &gpgId) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { - return false; - } - - gpgId = it->second.gpg_id; - return true; -} - -/**** HIDDEN STUFF ****/ - -bool p3PeerMgrIMPL::isHidden() -{ - RS_STACK_MUTEX(mPeerMtx); - return mOwnState.hiddenNode; -} - -/** - * @brief checks the hidden type of the own peer. - * @param type type to check - * @return true when the peer has the same hidden type than type - */ -bool p3PeerMgrIMPL::isHidden(const uint32_t type) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - switch (type) { - case RS_HIDDEN_TYPE_TOR: - return mOwnState.hiddenType == RS_HIDDEN_TYPE_TOR; - break; - case RS_HIDDEN_TYPE_I2P: - return mOwnState.hiddenType == RS_HIDDEN_TYPE_I2P; - break; - default: -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::isHidden(" << type << ") unkown type -> false"; - std::cerr << std::endl; -#endif - return false; - break; - } -} - -bool p3PeerMgrIMPL::isHiddenPeer(const RsPeerId &ssl_id) -{ - return isHiddenPeer(ssl_id, RS_HIDDEN_TYPE_NONE); -} - -/** - * @brief checks the hidden type of a given ssl id. When type RS_HIDDEN_TYPE_NONE is choosen it returns the 'hiddenNode' value instead - * @param ssl_id to check - * @param type type to check. Use RS_HIDDEN_TYPE_NONE to check 'hiddenNode' value - * @return true when the peer has the same hidden type than type - */ -bool p3PeerMgrIMPL::isHiddenPeer(const RsPeerId &ssl_id, const uint32_t type) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::isHiddenPeer(" << ssl_id << ") Missing Peer => false"; - std::cerr << std::endl; -#endif - - return false; - } - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::isHiddenPeer(" << ssl_id << ") = " << (it->second).hiddenNode; - std::cerr << std::endl; -#endif - switch (type) { - case RS_HIDDEN_TYPE_TOR: - return (it->second).hiddenType == RS_HIDDEN_TYPE_TOR; - break; - case RS_HIDDEN_TYPE_I2P: - return (it->second).hiddenType == RS_HIDDEN_TYPE_I2P; - break; - default: - return (it->second).hiddenNode; - break; - } -} - -bool hasEnding (std::string const &fullString, std::string const &ending) { - if (fullString.length() < ending.length()) - return false; - - return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); -} - -/** - * @brief resolves the hidden type (tor or i2p) from a domain - * @param domain to check - * @return RS_HIDDEN_TYPE_TOR, RS_HIDDEN_TYPE_I2P or RS_HIDDEN_TYPE_NONE - * - * Tor: ^[a-z2-7]{16}\.onion$ - * - * I2P: There is more than one address: - * - pub. key in base64 - * - hash in base32 ( ^[a-z2-7]{52}\.b32\.i2p$ ) - * - "normal" .i2p domains - */ -uint32_t p3PeerMgrIMPL::hiddenDomainToHiddenType(const std::string &domain) -{ - if(hasEnding(domain, ".onion")) - return RS_HIDDEN_TYPE_TOR; - if(hasEnding(domain, ".i2p")) - return RS_HIDDEN_TYPE_I2P; - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::hiddenDomainToHiddenType() unknown hidden type: " << domain; - std::cerr << std::endl; -#endif - return RS_HIDDEN_TYPE_UNKNOWN; -} - -/** - * @brief returns the hidden type of a peer - * @param ssl_id peer id - * @return hidden type - */ -uint32_t p3PeerMgrIMPL::getHiddenType(const RsPeerId &ssl_id) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - if (ssl_id == AuthSSL::getAuthSSL()->OwnId()) - return mOwnState.hiddenType; - - /* check for existing */ - std::map::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; -} - -bool p3PeerMgrIMPL::isHiddenNode(const RsPeerId& id) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - if (id == AuthSSL::getAuthSSL()->OwnId()) - return mOwnState.hiddenNode ; - else - { - std::map::const_iterator it = mFriendList.find(id); - - if (it == mFriendList.end()) - { - std::cerr << "p3PeerMgrIMPL::isHiddenNode() Peer Not Found" << std::endl; - return false; - } - return it->second.hiddenNode ; - } -} - -/** - * @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 *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort()"; - std::cerr << std::endl; -#endif - - std::string domain = domain_addr; - // trim whitespace! - size_t pos = domain.find_last_not_of(" \t\n"); - if (std::string::npos != pos) - { - domain = domain.substr(0, pos + 1); - } - pos = domain.find_first_not_of(" \t\n"); - if (std::string::npos != pos) - { - domain = domain.substr(pos); - } - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - if (ssl_id == AuthSSL::getAuthSSL()->OwnId()) - { - 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; -#endif - return true; - } - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setHiddenDomainPort() Peer Not Found"; - std::cerr << std::endl; -#endif - return false; - } - - 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; -#endif - - return true; -} - -/** - * @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 *******/ - - 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; -} - -bool p3PeerMgrIMPL::resetOwnExternalAddressList() -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - mOwnState.ipAddrs.mLocal.mAddrs.clear() ; - mOwnState.ipAddrs.mExt.mAddrs.clear() ; - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - return true ; -} - -/** - * @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 *******/ - - 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 *******/ - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(ssl_id); - if (it == mFriendList.end()) - { - return false; - } - - if (!it->second.hiddenNode) - { - return false; - } - - domain_addr = it->second.hiddenDomain; - domain_port = it->second.hiddenPort; - - 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; -} - -// Placeholder until we implement this functionality. -uint32_t p3PeerMgrIMPL::getConnectionType(const RsPeerId &/*sslId*/) -{ - return RS_NET_CONN_TYPE_FRIEND; -} - -int p3PeerMgrIMPL::getFriendCount(bool ssl, bool online) -{ - if (online) { - // count only online id's - std::list onlineIds; - mLinkMgr->getOnlineList(onlineIds); - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::set gpgIds; - int count = 0; - - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) { - if (online && std::find(onlineIds.begin(), onlineIds.end(), it->first) == onlineIds.end()) { - continue; - } - if (ssl) { - // count ssl id's only - count++; - } else { - // count unique gpg id's - gpgIds.insert(it->second.gpg_id); - } - } - - return ssl ? count : gpgIds.size(); - } - - if (ssl) { - // count all ssl id's - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - return mFriendList.size(); - } - - // count all gpg id's - std::list gpgIds; - AuthGPG::getAuthGPG()->getGPGAcceptedList(gpgIds); - - // add own gpg id, if we have more than one location - std::list ownSslIds; - getAssociatedPeers(AuthGPG::getAuthGPG()->getGPGOwnId(), ownSslIds); - - return gpgIds.size() + ((ownSslIds.size() > 0) ? 1 : 0); -} - -bool p3PeerMgrIMPL::getFriendNetStatus(const RsPeerId &id, peerState &state) -{ - RS_STACK_MUTEX(mPeerMtx); - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) return false; - - state = it->second; - return true; -} - - -int p3PeerMgrIMPL::getConnectAddresses( - const RsPeerId &id, sockaddr_storage &lAddr, sockaddr_storage &eAddr, - pqiIpAddrSet &histAddrs, std::string &dyndns ) -{ - - RS_STACK_MUTEX(mPeerMtx); - - /* check for existing */ - std::map::iterator it; - it = mFriendList.find(id); - if (it == mFriendList.end()) - { - /* ERROR */ - std::cerr << "p3PeerMgrIMPL::getConnectAddresses() ERROR unknown Peer"; - std::cerr << std::endl; - return 0; - } - - lAddr = it->second.localaddr; - eAddr = it->second.serveraddr; - histAddrs = it->second.ipAddrs; - dyndns = it->second.dyndns; - - return 1; -} - - - -bool p3PeerMgrIMPL::haveOnceConnected() -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* check for existing */ - for(auto it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.lastcontact > 0) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::haveOnceConnected() lastcontact: "; - std::cerr << time(NULL) - it->second.lastcontact << " for id: " << it->first; - std::cerr << std::endl; -#endif - - return true; - } - } - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::haveOnceConnected() all Last Contacts = 0"; - std::cerr << std::endl; -#endif - - return false; -} - - -bool p3PeerMgrIMPL::notifyPgpKeyReceived(const RsPgpId& pgp_id) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - bool changed = false; - - for(auto it(mFriendList.begin());it!=mFriendList.end();++it) - { - if(it->second.gpg_id == pgp_id) - { - std::cerr << "(WW) notification that full key " << pgp_id << " is available. Reseting short invite flag for peer " << it->first << std::endl; - it->second.skip_pgp_signature_validation = false; - - changed = true; - } - } - - if(changed) - IndicateConfigChanged(); - - return true; -} - -/*******************************************************************/ -/*******************************************************************/ - -bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg_id, uint32_t netMode, uint16_t vs_disc, uint16_t vs_dht, rstime_t lastContact,ServicePermissionFlags service_flags) -{ - bool notifyLinkMgr = false; - RsPeerId id = input_id ; - RsPgpId gpg_id = input_gpg_id ; - -#ifdef PEER_DEBUG_LOG - rslog(RSL_WARNING, p3peermgrzone, "p3PeerMgr::addFriend() id: " + id.toStdString()); -#endif - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - RsErr() << "p3PeerMgrIMPL::addFriend() cannot add own id as a friend. That's a bug!" << std::endl; - /* (1) already exists */ - return false; - } - /* so four possibilities - * (1) already exists as friend -> do nothing. - * (2) is in others list -> move over. - * (3) is non-existant -> create new one. - */ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::addFriend() " << id << "; gpg_id : " << gpg_id << std::endl; -#endif - - std::map::iterator it; - if (mFriendList.end() != (it=mFriendList.find(id))) - { - // The friend may already be here, including with a short invite (meaning the PGP key is unknown). - - if(it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!! - { - RsErr() << "Trying to add SSL id (" << id << ") that is already a friend with existing PGP key (" << it->second.gpg_id << ") but using a different PGP key (" << input_gpg_id << "). This is a bug!" << std::endl; - return false; - } - else - return true; /* (1) already exists */ - } - - // check that the PGP key is known - - if(!AuthGPG::getAuthGPG()->isGPGId(gpg_id)) - { - RsErr() << "Trying to add SSL id (" << id << ") to be validated with unknown PGP key (" << gpg_id << ". This is a bug!" << std::endl; - return false; - } - - //Authentication is now tested at connection time, we don't store the ssl cert anymore - // - if (!AuthGPG::getAuthGPG()->isGPGAccepted(gpg_id) && gpg_id != AuthGPG::getAuthGPG()->getGPGOwnId()) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::addFriend() gpg is not accepted" << std::endl; -#endif - /* no auth */ - return false; - } - - // after that, we know that we have the key, because AuthGPG wouldn't answer yes for a key it doesn't know. - - /* check if it is in others */ -// if (mOthersList.end() != (it = mOthersList.find(id))) -// { -// /* (2) in mOthersList -> move over */ -//#ifdef PEER_DEBUG -// std::cerr << "p3PeerMgrIMPL::addFriend() Move from Others" << std::endl; -//#endif -// if(!it->second.gpg_id.isNull() && it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!! -// RsErr() << "Trying to add SSL id (" << id << ") that is already known (but not friend) with existing PGP key (" << it->second.gpg_id -// << ") but using a different PGP key (" << input_gpg_id << "). This looks like a bug! The friend will be added again with the new PGP key ID." << std::endl; -// -// mFriendList[id] = it->second; -// mOthersList.erase(it); -// -// it = mFriendList.find(id); -// -// /* setup connectivity parameters */ -// it->second.vs_disc = vs_disc; -// it->second.vs_dht = vs_dht; -// -// it->second.netMode = netMode; -// it->second.lastcontact = lastContact; -// -// it->second.gpg_id = input_gpg_id; -// it->second.skip_pgp_signature_validation = false; -// -// mStatusChanged = true; -// -// notifyLinkMgr = true; -// -// IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ -// } -// else - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::addFriend() Creating New Entry" << std::endl; -#endif - - /* create a new entry */ - peerState pstate; - - pstate.id = id; - pstate.gpg_id = gpg_id; - pstate.name = AuthGPG::getAuthGPG()->getGPGName(gpg_id); - - pstate.vs_disc = vs_disc; - pstate.vs_dht = vs_dht; - pstate.netMode = netMode; - pstate.lastcontact = lastContact; - - pstate.gpg_id = input_gpg_id; - pstate.skip_pgp_signature_validation = false; - - /* addr & timestamps -> auto cleared */ - - mFriendList[id] = pstate; - - mStatusChanged = true; - - notifyLinkMgr = true; - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - - if (notifyLinkMgr) - { - mLinkMgr->addFriend(id, vs_dht != RS_VS_DHT_OFF); - } - - service_flags &= servicePermissionFlags(gpg_id) ; // Always reduce the permissions. -#ifdef RS_CHATSERVER //Defined by chatserver - setServicePermissionFlags(gpg_id,RS_NODE_PERM_NONE) ; -#else - setServicePermissionFlags(gpg_id,service_flags) ; -#endif - -#ifdef PEER_DEBUG - printPeerLists(std::cerr); - mLinkMgr->printPeerLists(std::cerr); -#endif - - return true; -} - - -bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id, const RsPeerDetails& dt ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(sslId.isNull()) - return failure("Cannot add a null ID as SSL-only friend"); - - if(pgp_id.isNull()) - return failure( " Cannot add as SSL-only friend a peer with null PGP"); - - if(sslId == getOwnId()) - return failure( "Cannot add yourself as SSL-only friend id:" + - sslId.toStdString() ); - - bool alreadySslFriend = false; - peerState pstate; - - { RS_STACK_MUTEX(mPeerMtx); - auto it = mFriendList.find(sslId); - if( it != mFriendList.end() ) - { - alreadySslFriend = true; - - /* If it is already friend override pstate so we don't loose already - * known information about the peer, in particular overriding - * pstate.skip_pgp_signature_validation is important for security. - */ - pstate = it->second; - } - } // RS_STACK_MUTEX(mPeerMtx); - - /* If it is already friend check if PGP id of the invite matches with the - * PGP id we already know, to avoid nasty tricks with malevolently forged - * short invites.*/ - if(alreadySslFriend && pstate.gpg_id != pgp_id) - return failure( "Cannot SSL-only friend for a pre-existing friend with " - "mismatching PGP-id known: " + - pstate.gpg_id.toStdString() + " new: " + - pgp_id.toStdString() ); - - /* It is very important to be expecially carefull setting - * pstate.skip_pgp_signature_validation to true because this effectively - * disables PGP signature verification on connection attempt. - * This check in particular avoid someone attempting to trick the user into - * accepting as SSL-only friend a malevolently forged short invite, with the - * PGP id of an already known friend but the SSL-id of a location generated - * by the attacker which doesn't have access to the legitimate PGP - * certificate. - * In that case being pstate.skip_pgp_signature_validation false on - * connection attempt the PGP signaure verification would fail and the - * connection closed. - * Instead if pstate.skip_pgp_signature_validation would have been - * superficially set to true the PGP signature verification would have been - * skipped and the attacker connection would be accepted. - * If the PGP key is available add it as full friend. */ - if(AuthGPG::getAuthGPG()->isPgpPubKeyAvailable(pgp_id)) - AuthGPG::getAuthGPG()->AllowConnection(pgp_id, true); - else - pstate.skip_pgp_signature_validation = true; - - pstate.gpg_id = pgp_id; - pstate.id = sslId; - - /* At this point if we got info about the peer just update with the new - * values. */ - if(!dt.name.empty()) pstate.name = dt.name; - if(!dt.dyndns.empty()) - { - pstate.dyndns = dt.dyndns; - if(dt.extPort) - { - /* If there is no IPv4 address available yet add a placeholder to - * not loose the port, because the address is invalid. */ - if(!sockaddr_storage_isValidNet(pstate.serveraddr)) - sockaddr_storage_inet_pton(pstate.serveraddr, "192.0.2.0"); - sockaddr_storage_setport(pstate.serveraddr, dt.extPort); - } - } - pstate.hiddenNode = dt.isHiddenNode; - if(!dt.hiddenNodeAddress.empty()) - pstate.hiddenDomain = dt.hiddenNodeAddress; - if(dt.hiddenNodePort) pstate.hiddenPort = dt.hiddenNodePort; - if(dt.hiddenType) pstate.hiddenType = dt.hiddenType; - if(!dt.location.empty()) pstate.location = dt.location; - - { RS_STACK_MUTEX(mPeerMtx); - mFriendList[sslId] = pstate; - mStatusChanged = true; - } // RS_STACK_MUTEX(mPeerMtx); - - IndicateConfigChanged(); - mLinkMgr->addFriend(sslId, dt.vs_dht != RS_VS_DHT_OFF); - - /* To update IP addresses is much more confortable to use locators, beside - * of the easy to use another benefit is that this way we don't loose - * previously known IP addresses */ - if(!dt.isHiddenNode) - { - for(const std::string& ipStr : dt.ipAddressList) - addPeerLocator(sslId, RsUrl(ipStr)); - - if(dt.extPort && !dt.extAddr.empty()) - { - RsUrl locator; - locator.setScheme("ipv4").setHost(dt.extAddr) - .setPort(dt.extPort); - addPeerLocator(sslId, locator); - } - - if(dt.localPort && !dt.localAddr.empty()) - { - RsUrl locator; - locator.setScheme("ipv4").setHost(dt.localAddr) - .setPort(dt.localPort); - addPeerLocator(sslId, locator); - } - } - - return true; -} - -bool p3PeerMgrIMPL::removeFriend(const RsPgpId &id) -{ -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() for id : " << id << std::endl; - std::cerr << "p3PeerMgrIMPL::removeFriend() mFriendList.size() : " << mFriendList.size() << std::endl; -#endif - - rslog(RSL_WARNING, p3peermgrzone, "p3PeerMgr::removeFriend() id: " + id.toStdString()); - - std::list sslid_toRemove; // This is a list of SSLIds. - rsPeers->getAssociatedSSLIds(id,sslid_toRemove) ; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* move to othersList */ - //bool success = false; - std::map::iterator it; - //remove ssl and gpg_ids - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (find(sslid_toRemove.begin(),sslid_toRemove.end(),it->second.id) != sslid_toRemove.end()) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() friend found in the list." << id << std::endl; -#endif - peerState peer = it->second; - - sslid_toRemove.push_back(it->second.id); - - //mOthersList[it->second.id] = peer; - mStatusChanged = true; - - //success = true; - } - } - - for(std::list::iterator rit = sslid_toRemove.begin(); rit != sslid_toRemove.end(); ++rit) - if (mFriendList.end() != (it = mFriendList.find(*rit))) - mFriendList.erase(it); - - std::map::iterator it2 = mFriendsPermissionFlags.find(id) ; - - if(it2 != mFriendsPermissionFlags.end()) - mFriendsPermissionFlags.erase(it2); - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() new mFriendList.size() : " << mFriendList.size() << std::endl; -#endif - } - - std::list::iterator rit; - for(rit = sslid_toRemove.begin(); rit != sslid_toRemove.end(); ++rit) - { - mLinkMgr->removeFriend(*rit); - } - - /* remove id from all groups */ - - std::list ids ; - ids.push_back(id) ; - assignPeersToGroup(RsNodeGroupId(), ids, false); - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - -#ifdef PEER_DEBUG - printPeerLists(std::cerr); - mLinkMgr->printPeerLists(std::cerr); -#endif - - return !sslid_toRemove.empty(); -} -bool p3PeerMgrIMPL::removeFriend(const RsPeerId &id, bool removePgpId) -{ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() for id : " << id << std::endl; - std::cerr << "p3PeerMgrIMPL::removeFriend() mFriendList.size() : " << mFriendList.size() << std::endl; -#endif - - rslog(RSL_WARNING, p3peermgrzone, "p3PeerMgr::removeFriend() id: " + id.toStdString()); - - std::list sslid_toRemove; // This is a list of SSLIds. - std::list pgpid_toRemove; // This is a list of SSLIds. - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* move to othersList */ - //bool success = false; - std::map::iterator it; - //remove ssl and gpg_ids - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.id == id) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() friend found in the list." << id << std::endl; -#endif - peerState peer = it->second; - - sslid_toRemove.push_back(it->second.id); - if(removePgpId) - pgpid_toRemove.push_back(it->second.gpg_id); - - //mOthersList[id] = peer; - mStatusChanged = true; - - //success = true; - } - } - - for(std::list::iterator rit = sslid_toRemove.begin(); rit != sslid_toRemove.end(); ++rit) - if (mFriendList.end() != (it = mFriendList.find(*rit))) - mFriendList.erase(it); - - std::map::iterator it2 ; - - for(std::list::iterator rit = pgpid_toRemove.begin(); rit != pgpid_toRemove.end(); ++rit) - if (mFriendsPermissionFlags.end() != (it2 = mFriendsPermissionFlags.find(*rit))) - mFriendsPermissionFlags.erase(it2); - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::removeFriend() new mFriendList.size() : " << mFriendList.size() << std::endl; -#endif - } - - std::list::iterator rit; - for(rit = sslid_toRemove.begin(); rit != sslid_toRemove.end(); ++rit) - { - mLinkMgr->removeFriend(*rit); - } - - /* remove id from all groups */ - - assignPeersToGroup(RsNodeGroupId(), pgpid_toRemove, false); - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - -#ifdef PEER_DEBUG - printPeerLists(std::cerr); - mLinkMgr->printPeerLists(std::cerr); -#endif - - return !sslid_toRemove.empty(); -} - - -void p3PeerMgrIMPL::printPeerLists(std::ostream &out) -{ - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - out << "p3PeerMgrIMPL::printPeerLists() Friend List"; - out << std::endl; - - - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - out << "\t SSL ID: " << it->second.id; - out << "\t GPG ID: " << it->second.gpg_id; - out << std::endl; - } - -// out << "p3PeerMgrIMPL::printPeerLists() Others List"; -// out << std::endl; -// for(it = mOthersList.begin(); it != mOthersList.end(); ++it) -// { -// out << "\t SSL ID: " << it->second.id; -// out << "\t GPG ID: " << it->second.gpg_id; -// out << std::endl; -// } - } - - return; -} - - - -/*******************************************************************/ -/*******************************************************************/ - - -/********************************************************************** - ********************************************************************** - ******************** External Setup ********************************** - ********************************************************************** - **********************************************************************/ - - -/* This function should only be called from NetMgr, - * as it doesn't call back to there. - */ - -bool p3PeerMgrIMPL::UpdateOwnAddress( const sockaddr_storage& pLocalAddr, - const sockaddr_storage& pExtAddr ) -{ - sockaddr_storage localAddr; - sockaddr_storage_copy(pLocalAddr, localAddr); - sockaddr_storage_ipv6_to_ipv4(localAddr); - - sockaddr_storage extAddr; - sockaddr_storage_copy(pExtAddr, extAddr); - sockaddr_storage_ipv6_to_ipv4(extAddr); - -//#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress(" - << sockaddr_storage_tostring(localAddr) << ", " - << sockaddr_storage_tostring(extAddr) << ")" << std::endl; -//#endif - - if( rsBanList && - !rsBanList->isAddressAccepted(localAddr, - RSBANLIST_CHECKING_FLAGS_BLACKLIST) ) - { - std::cerr << "(SS) Trying to set own IP to a banned IP " - << sockaddr_storage_iptostring(localAddr) << ". This probably" - << "means that a friend in under traffic re-routing attack." - << std::endl; - return false; - } - - { - RS_STACK_MUTEX(mPeerMtx); - - //update ip address list - pqiIpAddress ipAddressTimed; - sockaddr_storage_copy(localAddr, ipAddressTimed.mAddr); - ipAddressTimed.mSeenTime = time(NULL); - ipAddressTimed.mSrc = 0; - mOwnState.ipAddrs.updateLocalAddrs(ipAddressTimed); - - if(!mOwnState.hiddenNode) - { - /* Workaround to spread multiple local ip addresses when presents. - * This is needed because RS wrongly assumes that there is just one - * active local ip address at time. */ - std::vector addrs; - if(getLocalAddresses(addrs)) - { - /* To work around MAX_ADDRESS_LIST_SIZE addresses limitation, - * let's shuffle the list of local addresses in the hope that - * with enough time every local address is advertised to - * trusted nodes so they may try to connect to all of them - * including the most convenient if a local connection exists. - */ - std::random_shuffle(addrs.begin(), addrs.end()); - - for (auto it = addrs.begin(); it!=addrs.end(); ++it) - { - sockaddr_storage& addr(*it); - if( sockaddr_storage_isValidNet(addr) && - !sockaddr_storage_isLoopbackNet(addr) && - /* Avoid IPv6 link local addresses as we don't have - * implemented the logic needed to handle sin6_scope_id. - * To properly handle sin6_scope_id it would probably - * require deep reenginering of the RetroShare - * networking stack */ - !sockaddr_storage_ipv6_isLinkLocalNet(addr) ) - { - sockaddr_storage_ipv6_to_ipv4(addr); - pqiIpAddress pqiIp; - sockaddr_storage_clear(pqiIp.mAddr); - pqiIp.mAddr.ss_family = addr.ss_family; - sockaddr_storage_copyip(pqiIp.mAddr, addr); - sockaddr_storage_setport( - pqiIp.mAddr, - sockaddr_storage_port(localAddr) ); - pqiIp.mSeenTime = time(nullptr); - pqiIp.mSrc = 0; - mOwnState.ipAddrs.updateLocalAddrs(pqiIp); - } - } - } - } - - sockaddr_storage_copy(localAddr, mOwnState.localaddr); - } - - - { - RS_STACK_MUTEX(mPeerMtx); - - //update ip address list - pqiIpAddress ipAddressTimed; - sockaddr_storage_copy(extAddr, ipAddressTimed.mAddr); - ipAddressTimed.mSeenTime = time(NULL); - ipAddressTimed.mSrc = 0; - mOwnState.ipAddrs.updateExtAddrs(ipAddressTimed); - - /* Attempted Fix to MANUAL FORWARD Mode.... - * don't update the server address - if we are in this mode - * - * It is okay - if they get it wrong, as we put the address in the address list anyway. - * This should keep people happy, and allow for misconfiguration! - */ - - if (mOwnState.netMode & RS_NET_MODE_TRY_EXT) - { - /**** THIS CASE SHOULD NOT BE TRIGGERED ****/ - std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port "; - std::cerr << " as MANUAL FORWARD Mode (ERROR - SHOULD NOT BE TRIGGERED: TRY_EXT_MODE)"; - std::cerr << std::endl; - std::cerr << "Address is Now: "; - std::cerr << sockaddr_storage_tostring(mOwnState.serveraddr); - std::cerr << std::endl; - } - else if (mOwnState.netMode & RS_NET_MODE_EXT) - { - sockaddr_storage_copyip(mOwnState.serveraddr, extAddr); - - std::cerr << "p3PeerMgrIMPL::UpdateOwnAddress() Disabling Update of Server Port "; - std::cerr << " as MANUAL FORWARD Mode"; - std::cerr << std::endl; - std::cerr << "Address is Now: "; - std::cerr << sockaddr_storage_tostring(mOwnState.serveraddr); - std::cerr << std::endl; - } - else - { - sockaddr_storage_copy(extAddr, mOwnState.serveraddr); - } - } - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - mLinkMgr->setLocalAddress(localAddr); - - return true; -} - - -bool p3PeerMgrIMPL::addPeerLocator(const RsPeerId &sslId, const RsUrl& locator) -{ - std::string host(locator.host()); - pqiIpAddress ip; - if(!locator.hasPort() || host.empty() || - !sockaddr_storage_inet_pton(ip.mAddr, host) || - !sockaddr_storage_setport(ip.mAddr, locator.port())) return false; - ip.mSeenTime = time(NULL); - - bool changed = false; - - if (sslId == AuthSSL::getAuthSSL()->OwnId()) - { - RS_STACK_MUTEX(mPeerMtx); - changed = mOwnState.ipAddrs.updateLocalAddrs(ip); - } - else - { - RS_STACK_MUTEX(mPeerMtx); - auto it = mFriendList.find(sslId); - if (it == mFriendList.end()) - { -#ifdef PEER_DEBUG - std::cerr << __PRETTY_FUNCTION__ << "cannot add address " << "info, peer id: " << sslId << " not found in list" << std::endl; -#endif - return false; - } - - changed = it->second.ipAddrs.updateLocalAddrs(ip); - } - - if (changed) - { -#ifdef PEER_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Added locator: " - << locator.toString() << std::endl; -#endif - IndicateConfigChanged(); - } - return changed; -} - -bool p3PeerMgrIMPL::setLocalAddress( const RsPeerId &id, - const sockaddr_storage &addr ) -{ - bool changed = false; - - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - { - RS_STACK_MUTEX(mPeerMtx); - if (!sockaddr_storage_same(mOwnState.localaddr, addr)) - { - mOwnState.localaddr = addr; - changed = true; - } - } - - if (changed) - { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - mNetMgr->setLocalAddress(addr); - mLinkMgr->setLocalAddress(addr); - } - return changed; - } - - RS_STACK_MUTEX(mPeerMtx); - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - std::cerr << "(EE) p3PeerMgrIMPL::setLocalAddress() cannot add addres " << "info : peer id not found in friend list id: " << id << std::endl; - return false; - } - - /* "it" points to peer */ - if (!sockaddr_storage_same(it->second.localaddr, addr)) - { - it->second.localaddr = addr; - changed = true; - } - -#if 0 - //update ip address list - IpAddressTimed ipAddressTimed; - ipAddressTimed.ipAddr = addr; - ipAddressTimed.seenTime = time(NULL); - it->second.updateIpAddressList(ipAddressTimed); -#endif - - if (changed) IndicateConfigChanged(); - return changed; -} - -bool p3PeerMgrIMPL::setExtAddress( const RsPeerId &id, - const sockaddr_storage &addr ) -{ - bool changed = false; - uint32_t check_res = 0; - - if(rsBanList && !rsBanList->isAddressAccepted( - addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST, check_res )) - { - RsErr() << __PRETTY_FUNCTION__ << " trying to set external contact " - << "address for peer: " << id << " to a banned address " << addr - << std::endl; - return false; - } - - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - { - RS_STACK_MUTEX(mPeerMtx); - if (!sockaddr_storage_same(mOwnState.serveraddr, addr)) - { - mOwnState.serveraddr = addr; - changed = true; - } - } - - mNetMgr->setExtAddress(addr); - - return changed; - } - - RS_STACK_MUTEX(mPeerMtx); - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - std::cerr << "(EE) p3PeerMgrIMPL::setExtAddress() cannot add addres " << "info : peer id not found in friend list id: " << id << std::endl; - return false; - } - - /* "it" points to peer */ - if (!sockaddr_storage_same(it->second.serveraddr, addr)) - { - it->second.serveraddr = addr; - changed = true; - } - -#if 0 - //update ip address list - IpAddressTimed ipAddressTimed; - ipAddressTimed.ipAddr = addr; - ipAddressTimed.seenTime = time(NULL); - it->second.updateIpAddressList(ipAddressTimed); -#endif - - if (changed) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - - return changed; -} - - -bool p3PeerMgrIMPL::setDynDNS(const RsPeerId &id, const std::string &dyndns) -{ - bool changed = false; - - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - if (mOwnState.dyndns.compare(dyndns) != 0) { - mOwnState.dyndns = dyndns; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - changed = true; - } - return changed; - } - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setDynDNS() cannot add dyn dns info : peer id not found in friend list id: " << id << std::endl; -#endif - return false; - } - - /* "it" points to peer */ - if (it->second.dyndns.compare(dyndns) != 0) { - it->second.dyndns = dyndns; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - changed = true; - } - - return changed; -} - -namespace pqi { - -struct ZeroedInt -{ - ZeroedInt() { n=0 ;} - int n ; -}; - -} - -bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, const sockaddr_storage &addr) -{ - // The algorithm is the following: - // - collect for each friend the last external connection address that is reported - // - everytime the list is changed, parse it entirely and - // * 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_clear(addr_filtered) ; - sockaddr_storage_copyip(addr_filtered,addr) ; - -#ifndef PEER_DEBUG - 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)) - { -#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 - - { - 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 ; - - if(!mNetMgr->getExtAddress(own_addr)) - { -#ifdef PEER_DEBUG - std::cerr << " cannot get current external address. Returning false" << std::endl; -#endif - return false ; - } -#ifdef PEER_DEBUG - std::cerr << " current external address is known to be " << sockaddr_storage_iptostring(own_addr) << std::endl; -#endif - - // Notify for every friend that has reported a wrong external address, except if that address is in the IP whitelist. - - if((rsBanList && !rsBanList->isAddressAccepted(addr_filtered, RSBANLIST_CHECKING_FLAGS_WHITELIST)) - && !sockaddr_storage_sameip(own_addr, addr_filtered) ) - { - RsInfo() << __PRETTY_FUNCTION__ << " Peer " << from - << " reports a connection address (" << addr_filtered - <<") that is not your current external address (" - << own_addr << "). This is weird." << std::endl; - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mSslId = from; - ev->mOwnLocator = RsUrl(own_addr); - ev->mReportedLocator = RsUrl(addr); - ev->mConnectionInfoCode = RsConnectionEventCode::PEER_REPORTS_WRONG_IP; - rsEvents->postEvent(ev); - } - } - - // 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) -{ - sockaddr_storage_clear(addr); - 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 count > 0 ; -} - -bool p3PeerMgrIMPL::getExtAddressReportedByFriends(sockaddr_storage &addr, uint8_t& /*isstable*/) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - uint32_t count =0; - - 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 ; -#ifdef PEER_DEBUG - rstime_t now = time(NULL) ; -#endif - - for(std::list::iterator it2(lst.begin());it2 != lst.end();) - { -#ifdef PEER_DEBUG - std::cerr << "Checking IP address " << sockaddr_storage_iptostring( (*it2).mAddr) << " for peer " << pid << ", age = " << now - (*it2).mSeenTime << std::endl; -#else - /* remove unused parameter warnings */ - (void) pid; -#endif - if(!link_mgr->checkPotentialAddr((*it2).mAddr)) - { -#ifdef PEER_DEBUG - std::cerr << " (SS) Removing Banned/old IP address " << sockaddr_storage_iptostring( (*it2).mAddr) << " from peer " << pid << ", age = " << now - (*it2).mSeenTime << std::endl; -#endif - - std::list::iterator ittmp = it2 ; - ++ittmp ; - lst.erase(it2) ; - it2 = ittmp ; - - changed = true ; - } - else - ++it2 ; - } - - return changed ; -} - -bool p3PeerMgrIMPL::updateAddressList(const RsPeerId& id, const pqiIpAddrSet &addrs) -{ -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setAddressList() called for id : " << id << std::endl; -#endif - // first clean the list from potentially banned IPs. - - pqiIpAddrSet clean_set = addrs ; - - cleanIpList(clean_set.mExt.mAddrs,id,mLinkMgr) ; - cleanIpList(clean_set.mLocal.mAddrs,id,mLinkMgr) ; - - bool am_I_a_hidden_node = isHiddenNode(getOwnId()) ; - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* check if it is our own ip */ - if (id == getOwnId()) - { - mOwnState.ipAddrs.updateAddrs(clean_set); - return true; - } - - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setLocalAddress() cannot add addres info : peer id not found in friend list. id: " << id << std::endl; -#endif - return false; - } - - /* "it" points to peer */ - - if(!am_I_a_hidden_node) - it->second.ipAddrs.updateAddrs(clean_set); - else - it->second.ipAddrs.clear(); - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setLocalAddress() Updated Address for: " << id; - std::cerr << std::endl; - std::string addrstr; - it->second.ipAddrs.printAddrs(addrstr); - std::cerr << addrstr; - std::cerr << std::endl; -#endif - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - return true; -} - - -bool p3PeerMgrIMPL::updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) -{ -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::updateCurrentAddress() called for id : " << id << std::endl; -#endif - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* cannot be own id */ - - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - std::cerr << "p3PeerMgrIMPL::updateCurrentAddress() ERROR peer id not found: " << id << std::endl; - return false; - } - - if (sockaddr_storage_isPrivateNet(addr.mAddr)) - { - it->second.ipAddrs.updateLocalAddrs(addr); - it->second.localaddr = addr.mAddr; - } - else - { - it->second.ipAddrs.updateExtAddrs(addr); - it->second.serveraddr = addr.mAddr; - } - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::updatedCurrentAddress() Updated Address for: " << id; - std::cerr << std::endl; - std::string addrstr; - it->second.ipAddrs.printAddrs(addrstr); - std::cerr << addrstr; - std::cerr << std::endl; -#endif - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - return true; -} - - -bool p3PeerMgrIMPL::updateLastContact(const RsPeerId& id) -{ -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::updateLastContact() called for id : " << id << std::endl; -#endif - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* cannot be own id */ - - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - std::cerr << "p3PeerMgrIMPL::updateLastContact() ERROR peer id not found: " << id << std::endl; - return false; - } - - it->second.lastcontact = time(NULL); - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - return true; -} - -bool p3PeerMgrIMPL::setNetworkMode(const RsPeerId &id, uint32_t netMode) -{ - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - return setOwnNetworkMode(netMode); - } - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - return false; - } - - bool changed = false; - - /* "it" points to peer */ - if (it->second.netMode != netMode) - { - it->second.netMode = netMode; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - changed = true; - } - - return changed; -} - -bool p3PeerMgrIMPL::setLocation(const RsPeerId &id, const std::string &location) -{ - bool changed = false; - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setLocation() called for id : " << id << "; with location " << location << std::endl; -#endif - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - if (mOwnState.location.compare(location) != 0) { - mOwnState.location = location; - changed = true; - } - return changed; - } - - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() != (it = mFriendList.find(id))) { - if (it->second.location.compare(location) != 0) { - it->second.location = location; - changed = true; - } - } - return changed; -} - -bool p3PeerMgrIMPL::setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht) -{ - { - std::string out; - rs_sprintf(out, "p3PeerMgr::setVisState(%s, %u, %u)", id.toStdString().c_str(), vs_disc, vs_dht); - rslog(RSL_WARNING, p3peermgrzone, out); - } - - if (id == AuthSSL::getAuthSSL()->OwnId()) - { - return setOwnVisState(vs_disc, vs_dht); - } - - bool isFriend = false; - bool changed = false; - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* check if it is a friend */ - std::map::iterator it; - if (mFriendList.end() == (it = mFriendList.find(id))) - { - return false; - } - else - { - isFriend = true; - } - - /* "it" points to peer */ - if ((it->second.vs_disc != vs_disc) || (it->second.vs_dht = vs_dht)) - { - it->second.vs_disc = vs_disc; - it->second.vs_dht = vs_dht; - changed = true; - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::setVisState(" << id << ", DISC: " << vs_disc << " DHT: " << vs_dht << ") "; - std::cerr << " NAME: " << it->second.name; - - switch(it->second.vs_disc) - { - default: - case RS_VS_DISC_OFF: - std::cerr << " NO-DISC "; - break; - case RS_VS_DISC_MINIMAL: - std::cerr << " MIN-DISC "; - break; - case RS_VS_DISC_FULL: - std::cerr << " FULL-DISC "; - break; - } - switch(it->second.vs_dht) - { - default: - case RS_VS_DHT_OFF: - std::cerr << " NO-DHT "; - break; - case RS_VS_DHT_PASSIVE: - std::cerr << " PASSIVE-DHT "; - break; - case RS_VS_DHT_FULL: - std::cerr << " FULL-DHT "; - break; - } - std::cerr << std::endl; -#endif - } - } - if(isFriend && changed) - { - mLinkMgr->setFriendVisibility(id, vs_dht != RS_VS_DHT_OFF); - } - - if (changed) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - - return changed; -} - - - - -/*******************************************************************/ - - -/********************************************************************** - ********************************************************************** - ******************** p3Config functions ****************************** - ********************************************************************** - **********************************************************************/ - - /* Key Functions to be overloaded for Full Configuration */ - -RsSerialiser *p3PeerMgrIMPL::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsPeerConfigSerialiser()); - rss->addSerialType(new RsGeneralConfigSerialiser()) ; - - return rss; -} - - -bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list& saveData) -{ - /* create a list of current peers */ - cleanup = true; - bool useExtAddrFinder = mNetMgr->getIPServersEnabled(); - - /* 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 *******/ - - RsPeerNetItem *item = new RsPeerNetItem(); - item->clear(); - - item->nodePeerId = getOwnId(); - item->pgpId = mOwnState.gpg_id; - item->location = mOwnState.location; - -#if 0 - if (mOwnState.netMode & RS_NET_MODE_TRY_EXT) - { - item->netMode = RS_NET_MODE_EXT; - } - else if (mOwnState.netMode & RS_NET_MODE_TRY_UPNP) - { - item->netMode = RS_NET_MODE_UPNP; - } - else - { - item->netMode = RS_NET_MODE_UDP; - } -#endif - item->netMode = mOwnState.netMode; - - item->vs_disc = mOwnState.vs_disc; - item->vs_dht = mOwnState.vs_dht; - - item->lastContact = mOwnState.lastcontact; - - item->localAddrV4.addr = mOwnState.localaddr; - item->extAddrV4.addr = mOwnState.serveraddr; - sockaddr_storage_clear(item->localAddrV6.addr); - sockaddr_storage_clear(item->extAddrV6.addr); - - item->dyndns = mOwnState.dyndns; - mOwnState.ipAddrs.mLocal.loadTlv(item->localAddrList); - mOwnState.ipAddrs.mExt.loadTlv(item->extAddrList); - item->domain_addr = mOwnState.hiddenDomain; - item->domain_port = mOwnState.hiddenPort; - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::saveList() Own Config Item:" << std::endl; - item->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - saveData.push_back(item); - - /* iterate through all friends and save */ - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - item = new RsPeerNetItem(); - item->clear(); - - item->nodePeerId = it->first; - item->pgpId = (it->second).gpg_id; - item->location = (it->second).location; - item->netMode = (it->second).netMode; - item->vs_disc = (it->second).vs_disc; - item->vs_dht = (it->second).vs_dht; - - item->lastContact = (it->second).lastcontact; - - item->localAddrV4.addr = (it->second).localaddr; - item->extAddrV4.addr = (it->second).serveraddr; - sockaddr_storage_clear(item->localAddrV6.addr); - sockaddr_storage_clear(item->extAddrV6.addr); - - - item->dyndns = (it->second).dyndns; - (it->second).ipAddrs.mLocal.loadTlv(item->localAddrList); - (it->second).ipAddrs.mExt.loadTlv(item->extAddrList); - - item->domain_addr = (it->second).hiddenDomain; - item->domain_port = (it->second).hiddenPort; - - saveData.push_back(item); -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::saveList() Peer Config Item:" << std::endl; - item->print(std::cerr, 10); - std::cerr << std::endl; -#endif - } - - RsPeerBandwidthLimitsItem *pblitem = new RsPeerBandwidthLimitsItem ; - pblitem->peers = mPeerBandwidthLimits ; - saveData.push_back(pblitem) ; - - RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ; - - for(std::map::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it) - { - sitem->pgp_ids.push_back(it->first) ; - sitem->service_flags.push_back(it->second) ; - } - - saveData.push_back(sitem) ; - - // Now save config for network digging strategies - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - - RsTlvKeyValue kv; - kv.key = kConfigKeyExtIpFinder; - kv.value = (useExtAddrFinder)?"TRUE":"FALSE" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - - // Store Proxy Server. - // Tor -#ifdef PEER_DEBUG - std::cerr << "Saving proxyServerAddress for Tor: " << sockaddr_storage_tostring(proxy_addr_tor); - std::cerr << std::endl; -#endif - - kv.key = kConfigKeyProxyServerIpAddrTor; - kv.value = sockaddr_storage_iptostring(proxy_addr_tor); - vitem->tlvkvs.pairs.push_back(kv) ; - - 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); - - /* save groups */ - - for ( std::map::iterator groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) - { - RsNodeGroupItem *itm = new RsNodeGroupItem(groupIt->second); - saveData.push_back(itm) ; - } - - return true; -} - -bool p3PeerMgrIMPL::getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn) -{ - RsPgpId pgp_id ; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::const_iterator it = mFriendList.find(pid) ; - - if(it == mFriendList.end()) - { - maxUp = 0; - maxDn = 0; - return false ; - } - - pgp_id = it->second.gpg_id ; - } - - return getMaxRates(pgp_id,maxUp,maxDn) ; -} - -bool p3PeerMgrIMPL::getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::const_iterator it2 = mPeerBandwidthLimits.find(pid) ; - - if(it2 != mPeerBandwidthLimits.end()) - { - maxUp = it2->second.max_up_rate_kbs ; - maxDn = it2->second.max_dl_rate_kbs ; - return true ; - } - else - { - maxUp = 0; - maxDn = 0; - return false ; - } -} -bool p3PeerMgrIMPL::setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - PeerBandwidthLimits& p(mPeerBandwidthLimits[pid]) ; - - if(maxUp == p.max_up_rate_kbs && maxDn == p.max_dl_rate_kbs) - return true ; - - std::cerr << "Updating max rates for peer " << pid << " to " << maxUp << " kB/s (up), " << maxDn << " kB/s (dn)" << std::endl; - - p.max_up_rate_kbs = maxUp ; - p.max_dl_rate_kbs = maxDn ; - - IndicateConfigChanged(); - - return true ; -} - -void p3PeerMgrIMPL::saveDone() -{ - /* clean up the save List */ - std::list::iterator it; - for(it = saveCleanupList.begin(); it != saveCleanupList.end(); ++it) - { - delete (*it); - } - - saveCleanupList.clear(); - - /* unlock mutex */ - mPeerMtx.unlock(); /****** MUTEX UNLOCKED *******/ -} - -bool p3PeerMgrIMPL::loadList(std::list& load) -{ - // DEFAULTS. - bool useExtAddrFinder = true; - std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr; - uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor; - std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr; - uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P; - - if (load.empty()) { - std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl; - return false; - } - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl; -#endif - - RsPeerId ownId = getOwnId(); - bool am_I_a_hidden_node = isHiddenNode(ownId) ; - - /* load the list of peers */ - std::list::iterator it; - for(it = load.begin(); it != load.end(); ++it) - { - RsPeerNetItem *pitem = dynamic_cast(*it); - if (pitem) - { - RsPeerId peer_id = pitem->nodePeerId ; - RsPgpId peer_pgp_id = pitem->pgpId ; - - if (peer_id == ownId) - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl; - pitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - /* add ownConfig */ - setOwnNetworkMode(pitem->netMode); - setOwnVisState(pitem->vs_disc, pitem->vs_dht); - - mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); - mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); - } - else - { -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl; - pitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - /* ************* */ - // permission flags is used as a mask for the existing perms, so we set it to 0xffff - - RsPeerDetails det ; - if(!rsPeers->getGPGDetails(peer_pgp_id,det)) - { - // would be better to add flags into RsPeerNetItem so that we already have this information. However, it's possible that the PGP key - // has been added in the meantime, so the peer would be loaded with the right pGP key attached. - - RsInfo() << __PRETTY_FUNCTION__ << " loading SSL-only " << "friend: " << peer_id << " " << pitem->location << std::endl; - addSslOnlyFriend(peer_id,peer_pgp_id); - } - else if(!addFriend( peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL )) - { - RsInfo() << __PRETTY_FUNCTION__ << " cannot add friend friend: " << peer_id << " " << pitem->location << ". Somthing's wrong." << std::endl; - } - setLocation(pitem->nodePeerId, pitem->location); - } - - if (pitem->netMode == RS_NET_MODE_HIDDEN) - { - /* set only the hidden stuff & localAddress */ - setLocalAddress(peer_id, pitem->localAddrV4.addr); - setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port); - - } - else - { - pqiIpAddrSet addrs; - - if(!am_I_a_hidden_node) // clear IPs if w're a hidden node. Friend's clear node IPs where previously sent. - { - setLocalAddress(peer_id, pitem->localAddrV4.addr); - setExtAddress(peer_id, pitem->extAddrV4.addr); - setDynDNS (peer_id, pitem->dyndns); - - /* convert addresses */ - addrs.mLocal.extractFromTlv(pitem->localAddrList); - addrs.mExt.extractFromTlv(pitem->extAddrList); - } - - updateAddressList(peer_id, addrs); - } - - delete(*it); - - continue; - } - - RsConfigKeyValueSet *vitem = dynamic_cast(*it) ; - if (vitem) - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl; - vitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - std::list::iterator kit; - for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if (kit->key == kConfigKeyExtIpFinder) - { - useExtAddrFinder = (kit->value == "TRUE"); -#ifdef PEER_DEBUG - std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ; -#endif - } - // Tor - else if (kit->key == kConfigKeyProxyServerIpAddrTor) - { - proxyIpAddressTor = kit->value; -#ifdef PEER_DEBUG - std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor; - std::cerr << std::endl ; -#endif - - } - else if (kit->key == kConfigKeyProxyServerPortTor) - { - uint16_t p = atoi(kit->value.c_str()); - - if(p >= 1024) - proxyPortTor = p; -#ifdef PEER_DEBUG - std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor; - std::cerr << std::endl ; -#endif - } - // I2p - else if (kit->key == kConfigKeyProxyServerIpAddrI2P) - { - proxyIpAddressI2P = kit->value; -#ifdef PEER_DEBUG - std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P; - std::cerr << std::endl ; -#endif - } - else if (kit->key == kConfigKeyProxyServerPortI2P) - { - uint16_t p = atoi(kit->value.c_str()); - - if(p >= 1024) - proxyPortI2P = p; -#ifdef PEER_DEBUG - std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P; - std::cerr << std::endl ; -#endif - } - } - - delete(*it); - - continue; - } - - RsNodeGroupItem *gitem2 = dynamic_cast(*it) ; - - if (gitem2) - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl; - gitem->print(std::cerr, 10); - std::cerr << std::endl; -#endif - RsGroupInfo info ; - info.peerIds = gitem2->pgpList.ids ; - info.id = gitem2->id ; - info.name = gitem2->name ; - info.flag = gitem2->flag ; - - std::cerr << "(II) Loaded group in new format. ID = " << info.id << std::endl; - groupList[info.id] = info ; - - delete *it ; - continue; - } - RsPeerBandwidthLimitsItem *pblitem = dynamic_cast(*it) ; - - if(pblitem) - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "Loaded service permission item: " << std::endl; -#endif - mPeerBandwidthLimits = pblitem->peers ; - } - RsPeerServicePermissionItem *sitem = dynamic_cast(*it) ; - - if(sitem) - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "Loaded service permission item: " << std::endl; -#endif - - for(uint32_t i=0;ipgp_ids.size();++i) - if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId()) - { - mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ; -#ifdef PEER_DEBUG - std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl; -#endif - } -#ifdef PEER_DEBUG - else - std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl; -#endif - } - - delete (*it); - } - - { - /* set missing groupIds */ - - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - /* Standard groups */ - const int standardGroupCount = 5; - const RsNodeGroupId standardGroupIds [standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES }; - const char *standardGroupNames[standardGroupCount] = { RS_GROUP_DEFAULT_NAME_FRIENDS, RS_GROUP_DEFAULT_NAME_FAMILY, RS_GROUP_DEFAULT_NAME_COWORKERS, RS_GROUP_DEFAULT_NAME_OTHERS, RS_GROUP_DEFAULT_NAME_FAVORITES }; - - for(uint32_t k=0;kisGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getAuthGPG()->getGPGOwnId()) - ++profileIdIt; - else - { - std::cerr << "(WW) filtering out profile " << profileIdIt->toStdString() << " from group " << group_pair.first.toStdString() << " because it is not a friend anymore" << std::endl; - - auto tmp = profileIdIt; - ++tmp; - group_pair.second.peerIds.erase(profileIdIt); - profileIdIt=tmp; - - IndicateConfigChanged(); - } - } - } - - // If we are hidden - don't want ExtAddrFinder - ever! - if (isHidden()) - useExtAddrFinder = false; - - mNetMgr->setIPServersEnabled(useExtAddrFinder); - - // Configure Proxy Server. - struct sockaddr_storage proxy_addr; - // Tor - sockaddr_storage_clear(proxy_addr); - sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str()); - sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor); - - if (sockaddr_storage_isValidNet(proxy_addr)) - { - setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr); - } - - // I2P - sockaddr_storage_clear(proxy_addr); - sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str()); - sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P); - - if (sockaddr_storage_isValidNet(proxy_addr)) - { - setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr); - } - - load.clear() ; - return true; -} - - -#if 0 - -void printConnectState(std::ostream &out, peerState &peer) -{ - - out << "Friend: " << peer.name << " Id: " << peer.id << " State: " << peer.state; - if (peer.state & RS_PEER_S_FRIEND) - out << " S:RS_PEER_S_FRIEND"; - if (peer.state & RS_PEER_S_ONLINE) - out << " S:RS_PEER_S_ONLINE"; - if (peer.state & RS_PEER_S_CONNECTED) - out << " S:RS_PEER_S_CONNECTED"; - out << " Actions: " << peer.actions; - if (peer.actions & RS_PEER_NEW) - out << " A:RS_PEER_NEW"; - if (peer.actions & RS_PEER_MOVED) - out << " A:RS_PEER_MOVED"; - if (peer.actions & RS_PEER_CONNECTED) - out << " A:RS_PEER_CONNECTED"; - if (peer.actions & RS_PEER_DISCONNECTED) - out << " A:RS_PEER_DISCONNECTED"; - if (peer.actions & RS_PEER_CONNECT_REQ) - out << " A:RS_PEER_CONNECT_REQ"; - - out << std::endl; - return; -} - -#endif - - -/********************************************************************** - ********************************************************************** - ************************** Groups ************************************ - ********************************************************************** - **********************************************************************/ - -bool p3PeerMgrIMPL::addGroup(RsGroupInfo &groupInfo) -{ - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - do { groupInfo.id = RsNodeGroupId::random(); } while(groupList.find(groupInfo.id) != groupList.end()) ; - - RsGroupInfo groupItem(groupInfo) ; - - // remove standard flag - - groupItem.flag &= ~RS_GROUP_FLAG_STANDARD; - groupList[groupInfo.id] = groupItem; - - std::cerr << "(II) Added new group with ID " << groupInfo.id << ", name=\"" << groupInfo.name << "\"" << std::endl; - } - - RsServer::notify()->notifyListChange(NOTIFY_LIST_GROUPLIST, NOTIFY_TYPE_ADD); - - IndicateConfigChanged(); - - return true; -} - -bool p3PeerMgrIMPL::editGroup(const RsNodeGroupId& groupId, RsGroupInfo &groupInfo) -{ - if (groupId.isNull()) - return false; - - bool changed = false; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it = groupList.find(groupId) ; - - if(it == groupList.end()) - { - std::cerr << "(EE) cannot find local node group with ID " << groupId << std::endl; - return false ; - } - - if (it->second.flag & RS_GROUP_FLAG_STANDARD) - { - // can't edit standard groups - std::cerr << "(EE) cannot edit standard group with ID " << groupId << std::endl; - return false ; - } - else - { - changed = true; - it->second = groupInfo; - } - } - - if (changed) - { - RsServer::notify()->notifyListChange(NOTIFY_LIST_GROUPLIST, NOTIFY_TYPE_MOD); - - IndicateConfigChanged(); - } - - return changed; -} - -bool p3PeerMgrIMPL::removeGroup(const RsNodeGroupId& groupId) -{ - bool changed = false; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it = groupList.find(groupId) ; - - if (it != groupList.end()) { - if (it->second.flag & RS_GROUP_FLAG_STANDARD) - { - // can't remove standard groups - std::cerr << "(EE) cannot remove standard group with ID " << groupId << std::endl; - return false ; - } -#warning csoler: we need to check that the local group is not used. Otherwise deleting it is going to cause problems! -// else if(!it->second.used_gxs_groups.empty()) -// { -// std::cerr << "(EE) cannot remove standard group with ID " << groupId << " because it is used in the following groups: " << std::endl; -// for(std::set::const_iterator it2(it->second.used_gxs_groups.begin());it2!=it->second.used_gxs_groups.end();++it2) -// std::cerr << " " << *it2 << std::endl; -// -// return false ; -// } - else - { - changed = true; - groupList.erase(it); - } - } - } - - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_GROUPLIST, NOTIFY_TYPE_DEL); - - IndicateConfigChanged(); - } - - return changed; -} - -bool p3PeerMgrIMPL::getGroupInfoByName(const std::string& groupName, RsGroupInfo &groupInfo) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - for(std::map::iterator it = groupList.begin();it!=groupList.end();++it) - if(it->second.name == groupName) - { - groupInfo = it->second ; - return true ; - } - - std::cerr << "(EE) getGroupInfoByName: no known group for name " << groupName << std::endl; - return false ; -} -bool p3PeerMgrIMPL::getGroupInfo(const RsNodeGroupId& groupId, RsGroupInfo &groupInfo) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::iterator it = groupList.find(groupId) ; - - if(it == groupList.end()) - return false ; - - groupInfo = it->second; - - return true; -} - -bool p3PeerMgrIMPL::getGroupInfoList(std::list& groupInfoList) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - for(std::map ::const_iterator groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) - groupInfoList.push_back(groupIt->second) ; - - return true; -} - -// groupId.isNull() && assign == false -> remove from all groups - -bool p3PeerMgrIMPL::assignPeersToGroup(const RsNodeGroupId &groupId, const std::list &peerIds, bool assign) -{ - if (groupId.isNull() && assign == true) - return false; - - if (peerIds.empty()) - return false; - - bool changed = false; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - for (std::map::iterator groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) - if (groupId.isNull() || groupIt->first == groupId) - { - RsGroupInfo& groupItem = groupIt->second; - - for (std::list::const_iterator peerIt = peerIds.begin(); peerIt != peerIds.end(); ++peerIt) - { - //std::set::iterator peerIt1 = groupItem.peerIds.find(*peerIt); - - if (assign) - { - groupItem.peerIds.insert(*peerIt); - changed = true; - } - else - { - groupItem.peerIds.erase(*peerIt); - changed = true; - } - } - - if (!groupId.isNull()) - break; - } - } - - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_GROUPLIST, NOTIFY_TYPE_MOD); - - IndicateConfigChanged(); - } - - return changed; -} - - -/********************************************************************** - ********************************************************************** - ******************** Service permission stuff ************************ - ********************************************************************** - **********************************************************************/ - -ServicePermissionFlags p3PeerMgrIMPL::servicePermissionFlags(const RsPeerId& ssl_id) -{ - RsPgpId gpg_id ; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::const_iterator it = mFriendList.find(ssl_id); - - if(it == mFriendList.end()) - return RS_NODE_PERM_DEFAULT ; - - gpg_id = it->second.gpg_id ; - } - - return servicePermissionFlags(gpg_id) ; -} - - -ServicePermissionFlags p3PeerMgrIMPL::servicePermissionFlags(const RsPgpId& pgp_id) -{ - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - std::map::const_iterator it = mFriendsPermissionFlags.find( pgp_id ) ; - - if(it == mFriendsPermissionFlags.end()) - return RS_NODE_PERM_DEFAULT ; - else - return it->second ; - } -} -void p3PeerMgrIMPL::setServicePermissionFlags(const RsPgpId& pgp_id, const ServicePermissionFlags& flags) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - // Check that we have a PGP id. This should not be necessary, but because - // we use std::string, anything can get passed down here. - // - - mFriendsPermissionFlags[pgp_id] = flags ; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ -} - -/********************************************************************** - ********************************************************************** - ******************** Stuff moved from p3peers ************************ - ********************************************************************** - **********************************************************************/ - -bool p3PeerMgrIMPL::removeAllFriendLocations(const RsPgpId &gpgid) -{ - std::list sslIds; - if (!getAssociatedPeers(gpgid, sslIds)) - { - return false; - } - - std::list::iterator it; - for(it = sslIds.begin(); it != sslIds.end(); ++it) - { - removeFriend(*it, true); - } - - return true; -} - - -bool p3PeerMgrIMPL::getAssociatedPeers(const RsPgpId &gpg_id, std::list &ids) -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgr::getAssociatedPeers() for id : " << gpg_id << std::endl; -#endif - - int count = 0; - std::map::iterator it; - for(it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (it->second.gpg_id == gpg_id) - { - count++; - ids.push_back(it->first); - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgr::getAssociatedPeers() found ssl id : " << it->first << std::endl; -#endif - - } - } - - return (count > 0); -} - -// goes through the list of known friend IPs and remove the ones that are banned by p3LinkMgr. - - -bool p3PeerMgrIMPL::removeBannedIps() -{ - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - -#ifdef PEER_DEBUG - std::cerr << "Cleaning known IPs for all peers." << std::endl; -#endif - - bool changed = false ; - for( std::map::iterator it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if(cleanIpList(it->second.ipAddrs.mExt.mAddrs,it->first,mLinkMgr)) changed = true ; - if(cleanIpList(it->second.ipAddrs.mLocal.mAddrs,it->first,mLinkMgr)) changed = true ; - - if(rsBanList!=NULL && !rsBanList->isAddressAccepted(it->second.serveraddr,RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { - sockaddr_storage_clear(it->second.serveraddr) ; - std::cerr << "(SS) Peer " << it->first << " has a banned server address. Wiping it out." << std::endl; - } - } - - if(cleanIpList(mOwnState.ipAddrs.mExt.mAddrs,mOwnState.id,mLinkMgr) ) changed = true ; - if(cleanIpList(mOwnState.ipAddrs.mLocal.mAddrs,mOwnState.id,mLinkMgr) ) changed = true ; - - if(changed) - IndicateConfigChanged(); - - return true ; -} - -// /* This only removes SSL certs, that are old... Can end up with no Certs per GPG Id -// * We are removing the concept of a "DummyId" - There is no need for it. -// */ -// -// bool isDummyFriend(RsPeerId id) -// { -// bool ret = (id.substr(0,5) == "dummy"); -// return ret; -// } - -/** - * @brief p3PeerMgrIMPL::removeUnusedLocations Removes all location offline for RS_PEER_OFFLINE_DELETE seconds or more. Keeps the most recent location per PGP id. - * @return true on success - * - * This function removes all location that are offline for too long defined by RS_PEER_OFFLINE_DELETE. - * It also makes sure that at least one location (the most recent) is kept. - * - * The idea of the function is the following: - * - keep track if there is at least one location per PGP id that is not offline for too long - * -> hasRecentLocation - * - keep track of most recent location per PGP id that is offline for too long (and its time stamp) - * -> mostRecentLocation - * -> mostRecentTime - * - * When a location is found that is offline for too long the following points are checked from the top to the bottom: - * 1) remove it when the PGP id has a location that is not offline for too long - * 2) remove it when the PGP id has a more recent location - * 3) keep it when it is the most recent location - * This location will possibly be removed when a more recent (but still offline for too long) is found - */ -bool p3PeerMgrIMPL::removeUnusedLocations() -{ - std::list toRemove; - std::map mostRecentTime; - - const rstime_t now = time(NULL); - - std::list pgpList ; - - if (!rsPeers->getGPGAcceptedList(pgpList)) - return false ; - - { - RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ - - // First put a sensible number in all PGP ids - - for(std::list::const_iterator it = pgpList.begin(); it != pgpList.end(); ++it) - mostRecentTime[*it] = (rstime_t)0; - -#ifdef PEER_DEBUG - std::cerr << "p3PeerMgr::removeUnusedLocations()" << std::endl; -#endif - // Then compute the most recently used location for all PGP ids - - for( std::map::iterator it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - rstime_t& bst(mostRecentTime[it->second.gpg_id]) ; - bst = std::max(bst,it->second.lastcontact) ; - } - - // And remove all locations that are too old and also older than the most recent location. Doing this we're sure to always keep at least one location per PGP id. - - for( std::map::iterator it = mFriendList.begin(); it != mFriendList.end(); ++it) - { - if (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE && it->second.lastcontact < mostRecentTime[it->second.gpg_id]) - toRemove.push_back(it->first); -#ifdef PEER_DEBUG - std::cerr << "Location " << it->first << " PGP id " << it->second.gpg_id << " last contact " << it->second.lastcontact << " remove: " << (now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE) << " most recent: " << mostRecentTime[it->second.gpg_id] - << ". Final result remove: " << (it->second.lastcontact < mostRecentTime[it->second.gpg_id] && now > it->second.lastcontact + RS_PEER_OFFLINE_DELETE )<< std::endl; -#endif - } - } - - for (std::list::iterator it = toRemove.begin(); it != toRemove.end(); ++it) - removeFriend(*it, false) ; - - return true; -} - -p3PeerMgr::~p3PeerMgr() = default; diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h deleted file mode 100644 index 2cc9e4888..000000000 --- a/libretroshare/src/pqi/p3peermgr.h +++ /dev/null @@ -1,431 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3peermgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2011 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_PEER_MANAGER_HEADER -#define MRK_PQI_PEER_MANAGER_HEADER - -#include -#include "pqi/pqimonitor.h" -#include "pqi/pqiipset.h" -#include "pqi/pqiassist.h" - -#include "pqi/p3cfgmgr.h" - -#include "util/rsthreads.h" - -/* RS_VIS_STATE -> specified in rspeers.h - */ - - /* Startup Modes (confirmed later) */ -const uint32_t RS_NET_MODE_TRYMODE = 0xff00; - -const uint32_t RS_NET_MODE_TRY_EXT = 0x0100; -const uint32_t RS_NET_MODE_TRY_UPNP = 0x0200; -const uint32_t RS_NET_MODE_TRY_UDP = 0x0400; -const uint32_t RS_NET_MODE_TRY_LOOPBACK = 0x0800; - - /* Actual State */ -const uint32_t RS_NET_MODE_ACTUAL = 0x00ff; - -const uint32_t RS_NET_MODE_UNKNOWN = 0x0000; -const uint32_t RS_NET_MODE_EXT = 0x0001; -const uint32_t RS_NET_MODE_UPNP = 0x0002; -const uint32_t RS_NET_MODE_UDP = 0x0004; -const uint32_t RS_NET_MODE_HIDDEN = 0x0008; -const uint32_t RS_NET_MODE_UNREACHABLE = 0x0010; - - -/* flags of peerStatus */ -const uint32_t RS_NET_FLAGS_USE_DISC = 0x0001; -const uint32_t RS_NET_FLAGS_USE_DHT = 0x0002; -const uint32_t RS_NET_FLAGS_ONLINE = 0x0004; -const uint32_t RS_NET_FLAGS_EXTERNAL_ADDR = 0x0008; -const uint32_t RS_NET_FLAGS_STABLE_UDP = 0x0010; -const uint32_t RS_NET_FLAGS_TRUSTS_ME = 0x0020; - -/* - * remove locations offline since 90 days - * stopt sending locations via discovery when offline for +30 days - */ -const rstime_t RS_PEER_OFFLINE_DELETE = (90 * 24 * 3600); -const rstime_t RS_PEER_OFFLINE_NO_DISC = (30 * 24 * 3600); - -class peerState -{ - public: - peerState(); /* init */ - - RsPeerId id; - RsPgpId gpg_id; - - // This flag is used when adding a single SSL cert as friend without adding its PGP key in the friend list. This allows to - // have short invites. However, because this represent a significant security risk, we perform multiple consistency checks - // whenever we use this flag, in particular: - // flat is true <==> friend SSL cert is in the friend list, but PGP id is not in the friend list - - bool skip_pgp_signature_validation; - - uint32_t netMode; /* EXT / UPNP / UDP / HIDDEN / INVALID */ - /* visState */ - uint16_t vs_disc; - uint16_t vs_dht; - - struct sockaddr_storage localaddr; - struct sockaddr_storage serveraddr; - std::string dyndns; - - rstime_t lastcontact; - - /* list of addresses from various sources */ - pqiIpAddrSet ipAddrs; - - bool hiddenNode; /* all IP addresses / dyndns must be blank */ - std::string hiddenDomain; - uint16_t hiddenPort; - uint32_t hiddenType; - - std::string location; - std::string name; - - uint32_t maxUpRate ; - uint32_t maxDnRate ; -}; - -class RsNodeGroupItem; -struct RsGroupInfo; - -class p3LinkMgr; -class p3NetMgr; - -class p3LinkMgrIMPL; -class p3NetMgrIMPL; - -class p3PeerMgr -{ -public: - virtual bool addFriend( const RsPeerId &ssl_id, const RsPgpId &gpg_id, - uint32_t netMode = RS_NET_MODE_UDP, - uint16_t vsDisc = RS_VS_DISC_FULL, - uint16_t vsDht = RS_VS_DHT_FULL, - rstime_t lastContact = 0, - ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT) ) = 0; - - virtual bool addSslOnlyFriend( - const RsPeerId& sslId, - const RsPgpId& pgpId, - const RsPeerDetails& details = RsPeerDetails() ) = 0; - - // Calling this removed the skip_pgp_signature_validation flag on all peers which PGP key is the one supplied. - virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) = 0; - - virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0; - virtual bool isFriend(const RsPeerId& ssl_id) = 0; - virtual bool isSslOnlyFriend(const RsPeerId &ssl_id)=0; - -virtual bool getAssociatedPeers(const RsPgpId &gpg_id, std::list &ids) = 0; -virtual bool removeAllFriendLocations(const RsPgpId &gpgid) = 0; - - - /******************** Groups **********************/ - /* This is solely used by p3peers - makes sense */ - -virtual bool addGroup(RsGroupInfo &groupInfo) = 0; -virtual bool editGroup(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) = 0; -virtual bool removeGroup(const RsNodeGroupId &groupId) = 0; -virtual bool getGroupInfo(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) = 0; -virtual bool getGroupInfoByName(const std::string& groupName, RsGroupInfo &groupInfo) = 0; -virtual bool getGroupInfoList(std::list &groupInfoList) = 0; -virtual bool assignPeersToGroup(const RsNodeGroupId &groupId, const std::list &peerIds, bool assign) = 0; - - virtual bool resetOwnExternalAddressList() = 0 ; - - virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) =0; - virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) =0; - virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) =0; - - /**************** Set Net Info ****************/ - /* - * These functions are used by: - * 1) p3linkmgr - * 2) p3peers - reasonable - * 3) p3disc - reasonable - */ - - virtual bool addPeerLocator(const RsPeerId &ssl_id, const RsUrl& locator) = 0; -virtual bool setLocalAddress(const RsPeerId &id, const struct sockaddr_storage &addr) = 0; -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; - -virtual bool setLocation(const RsPeerId &pid, const std::string &location) = 0; -virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port) = 0; -virtual bool isHiddenNode(const RsPeerId& id) = 0 ; - -virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr) = 0; -virtual bool updateLastContact(const RsPeerId& id) = 0; -virtual bool updateAddressList(const RsPeerId& id, const pqiIpAddrSet &addrs) = 0; - - - // THIS MUST ONLY BE CALLED BY NETMGR!!!! -virtual bool UpdateOwnAddress(const struct sockaddr_storage &local_addr, const struct sockaddr_storage &ext_addr) = 0; - - /**************** Net Status Info ****************/ - /* - * MUST RATIONALISE THE DATA FROM THESE FUNCTIONS - * These functions are used by: - * 1) p3face-config ... to remove! - * 2) p3peers - reasonable - * 3) p3disc - reasonable - */ - -virtual bool getOwnNetStatus(peerState &state) = 0; -virtual bool getFriendNetStatus(const RsPeerId &id, peerState &state) = 0; - -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 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; -virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)=0; -virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)=0; -virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)=0; - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - - // 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; - -/*************************************************************************************************/ -/*************************************************************************************************/ -/*************************************************************************************************/ -/*************************************************************************************************/ - - virtual ~p3PeerMgr(); -}; - - -class p3PeerMgrIMPL: public p3PeerMgr, public p3Config -{ -public: - - /************************************************************************************************/ - /* EXTERNAL INTERFACE */ - /************************************************************************************************/ - - virtual bool addFriend(const RsPeerId&ssl_id, const RsPgpId&gpg_id, uint32_t netMode = RS_NET_MODE_UDP, - uint16_t vsDisc = RS_VS_DISC_FULL, uint16_t vsDht = RS_VS_DHT_FULL, - rstime_t lastContact = 0,ServicePermissionFlags = ServicePermissionFlags(RS_NODE_PERM_DEFAULT)); - - bool addSslOnlyFriend(const RsPeerId& sslId, const RsPgpId &pgp_id, const RsPeerDetails& details = RsPeerDetails() ) override; - - virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) override; - - virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId); - virtual bool removeFriend(const RsPgpId &pgp_id); - - virtual bool isFriend(const RsPeerId &ssl_id); - virtual bool isSslOnlyFriend(const RsPeerId &ssl_id); - - virtual bool getAssociatedPeers(const RsPgpId &gpg_id, std::list &ids); - virtual bool removeAllFriendLocations(const RsPgpId &gpgid); - - - /******************** Groups **********************/ - /* This is solely used by p3peers - makes sense */ - - virtual bool addGroup(RsGroupInfo &groupInfo); - virtual bool editGroup(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo); - virtual bool removeGroup(const RsNodeGroupId &groupId); - virtual bool getGroupInfo(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo); - virtual bool getGroupInfoByName(const std::string& groupName, RsGroupInfo &groupInfo) ; - virtual bool getGroupInfoList(std::list &groupInfoList); - virtual bool assignPeersToGroup(const RsNodeGroupId &groupId, const std::list &peerIds, bool assign); - - virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) ; - virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) ; - virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) ; - - /**************** Set Net Info ****************/ - /* - * These functions are used by: - * 1) p3linkmgr - * 2) p3peers - reasonable - * 3) p3disc - reasonable - */ - - virtual bool addPeerLocator(const RsPeerId &ssl_id, const RsUrl& locator); - virtual bool setLocalAddress(const RsPeerId &id, const struct sockaddr_storage &addr); - 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); - - virtual bool setLocation(const RsPeerId &pid, const std::string &location); - virtual bool setHiddenDomainPort(const RsPeerId &id, const std::string &domain_addr, const uint16_t domain_port); - virtual bool isHiddenNode(const RsPeerId& id); - - virtual bool updateCurrentAddress(const RsPeerId& id, const pqiIpAddress &addr); - virtual bool updateLastContact(const RsPeerId& id); - virtual bool updateAddressList(const RsPeerId& id, const pqiIpAddrSet &addrs); - - virtual bool resetOwnExternalAddressList() ; - - // THIS MUST ONLY BE CALLED BY NETMGR!!!! - virtual bool UpdateOwnAddress(const struct sockaddr_storage &local_addr, const struct sockaddr_storage &ext_addr); - /**************** Net Status Info ****************/ - /* - * MUST RATIONALISE THE DATA FROM THESE FUNCTIONS - * These functions are used by: - * 1) p3face-config ... to remove! - * 2) p3peers - reasonable - * 3) p3disc - reasonable - */ - - virtual bool getOwnNetStatus(peerState &state); - virtual bool getFriendNetStatus(const RsPeerId &id, peerState &state); - - 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 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 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); - - /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ - - // Single Use Function... shouldn't be here. used by p3serverconfig.cc - virtual bool haveOnceConnected(); - - virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn); - virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn); - virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn); - - /************************************************************************************************/ - /* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */ - /************************************************************************************************/ - - p3PeerMgrIMPL( const RsPeerId& ssl_own_id, - const RsPgpId& gpg_own_id, - const std::string& gpg_own_name, - const std::string& ssl_own_location) ; - - void setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr); - - bool forceHiddenNode(); - bool setupHiddenNode(const std::string &hiddenAddress, const uint16_t hiddenPort); - - void tick(); - - const RsPeerId& getOwnId(); - bool setOwnNetworkMode(uint32_t netMode); - bool setOwnVisState(uint16_t vs_disc, uint16_t vs_dht); - - int getConnectAddresses( const RsPeerId &id, sockaddr_storage &lAddr, - sockaddr_storage &eAddr, pqiIpAddrSet &histAddrs, - std::string &dyndns ); - - -protected: - /* Internal Functions */ - - bool removeUnusedLocations(); - bool removeBannedIps(); - - void printPeerLists(std::ostream &out); - - virtual bool locked_computeCurrentBestOwnExtAddressCandidate(sockaddr_storage &addr, uint32_t &count); - -protected: - /*****************************************************************/ - /*********************** p3config ******************************/ - /* Key Functions to be overloaded for Full Configuration */ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list&); - virtual void saveDone(); - virtual bool loadList(std::list& load); - /*****************************************************************/ - - /* other important managers */ - - p3LinkMgrIMPL *mLinkMgr; - p3NetMgrIMPL *mNetMgr; - -private: - RsMutex mPeerMtx; /* protects below */ - - bool mStatusChanged; - - std::list clients; - - peerState mOwnState; - - std::map mFriendList; // - - std::map mReportedOwnAddresses ; - - std::map groupList; - //uint32_t lastGroupId; - - std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ - - std::map mFriendsPermissionFlags ; // permission flags for each gpg key - std::map mPeerBandwidthLimits ; // bandwidth limits for each gpg key - - struct sockaddr_storage mProxyServerAddressTor; - struct sockaddr_storage mProxyServerAddressI2P; - uint32_t mProxyServerStatusTor ; - uint32_t mProxyServerStatusI2P ; - -}; - -#endif // MRK_PQI_PEER_MANAGER_HEADER diff --git a/libretroshare/src/pqi/p3servicecontrol.cc b/libretroshare/src/pqi/p3servicecontrol.cc deleted file mode 100644 index 9bf3b3c62..000000000 --- a/libretroshare/src/pqi/p3servicecontrol.cc +++ /dev/null @@ -1,1416 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3servicecontrol.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2014-2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "p3servicecontrol.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "serialiser/rstypeserializer.h" -#include "rsitems/rsnxsitems.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/pqiservice.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsevents.h" - -/*******************************/ -// #define SERVICECONTROL_DEBUG 1 -/*******************************/ - -static const uint8_t RS_PKT_SUBTYPE_SERVICE_CONTROL_SERVICE_PERMISSIONS = 0x01 ; - -class RsServiceControlItem: public RsItem -{ -public: - explicit RsServiceControlItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_SERVICE_CONTROL,item_subtype) {} -}; - -class RsServicePermissionItem: public RsServiceControlItem, public RsServicePermissions -{ -public: - RsServicePermissionItem(): RsServiceControlItem(RS_PKT_SUBTYPE_SERVICE_CONTROL_SERVICE_PERMISSIONS) {} - explicit RsServicePermissionItem(const RsServicePermissions& perms) : RsServiceControlItem(RS_PKT_SUBTYPE_SERVICE_CONTROL_SERVICE_PERMISSIONS), RsServicePermissions(perms) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,mServiceId,"mServiceId") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,mServiceName,"mServiceName") ; - RsTypeSerializer::serial_process (j,ctx,mDefaultAllowed,"mDefaultAllowed") ; - - RsTypeSerializer::serial_process (j,ctx,mPeersAllowed,"mPeersAllowed"); - RsTypeSerializer::serial_process (j,ctx,mPeersDenied ,"mPeersDenied"); - } - - virtual void clear() {} -}; - -class ServiceControlSerialiser: public RsServiceSerializer -{ -public: - ServiceControlSerialiser() : RsServiceSerializer(RS_SERVICE_TYPE_SERVICE_CONTROL) {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const - { - if(RS_SERVICE_TYPE_SERVICE_CONTROL != service) - return NULL; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_SERVICE_CONTROL_SERVICE_PERMISSIONS: return new RsServicePermissionItem(); - default: - return NULL ; - } - } -}; - -RsServiceControl *rsServiceControl = NULL; - -p3ServiceControl::p3ServiceControl(p3LinkMgr *linkMgr) - : RsServiceControl(), p3Config(), - mLinkMgr(linkMgr), mOwnPeerId(linkMgr->getOwnId()), - mCtrlMtx("p3ServiceControl"), mMonitorMtx("P3ServiceControl::Monitor"), - mServiceServer(NULL) -{ - mSerialiser = new ServiceControlSerialiser ; -} - -RsSerialiser *p3ServiceControl::setupSerialiser() -{ - RsSerialiser *serial = new RsSerialiser; - serial->addSerialType(new ServiceControlSerialiser) ; - - return serial ; -} - -const RsPeerId& p3ServiceControl::getOwnId() -{ - return mOwnPeerId; -} - -bool p3ServiceControl::getServiceItemNames(uint32_t serviceId,std::map& names) -{ - if(mServiceServer != NULL) - return mServiceServer->getServiceItemNames(serviceId,names) ; - - return false ; -} - -/* Interface for Services */ -bool p3ServiceControl::registerService(const RsServiceInfo &info, bool defaultOn) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - std::map::iterator it; - it = mOwnServices.find(info.mServiceType); - if (it != mOwnServices.end()) - { - std::cerr << "p3ServiceControl::registerService() ERROR Duplicate Service ID"; - std::cerr << std::endl; - return false; - } - - /* sanity check ServiceInfo */ - mOwnServices[info.mServiceType] = info; - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::registerService() Registered ServiceID: " << info.mServiceType; - std::cerr << std::endl; - std::cerr << "p3ServiceControl::registerService() ServiceName: " << info.mServiceName; - std::cerr << std::endl; -#endif - - - /* create default permissions for this service - * this will be overwritten by configuration (if it exists). - */ - - createDefaultPermissions_locked(info.mServiceType, info.mServiceName, defaultOn); - return true; -} - -bool p3ServiceControl::deregisterService(uint32_t serviceId) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - std::map::iterator it; - it = mOwnServices.find(serviceId); - if (it == mOwnServices.end()) - { - std::cerr << "p3ServiceControl::deregisterService() ERROR No matching Service ID"; - std::cerr << std::endl; - return false; - } - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::deregisterService() Removed ServiceID: " << serviceId; - std::cerr << std::endl; -#endif - mOwnServices.erase(it); - return true; -} - - -/* Interface for Services */ -bool p3ServiceControl::registerServiceMonitor(pqiServiceMonitor *monitor, uint32_t serviceId) -{ - RsStackMutex stack(mMonitorMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::registerServiceMonitor() for ServiceId: "; - std::cerr << serviceId; - std::cerr << std::endl; -#endif - - mMonitors.insert(std::make_pair(serviceId, monitor)); - return true; -} - - -bool p3ServiceControl::deregisterServiceMonitor(pqiServiceMonitor *monitor) -{ - RsStackMutex stack(mMonitorMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::deregisterServiceMonitor()"; - std::cerr << std::endl; -#endif - - std::multimap::iterator it; - for(it = mMonitors.begin(); it != mMonitors.end(); ) - { - if (it->second == monitor) - { - mMonitors.erase(it++); - } - else - { - ++it; - } - } - return true; -} - -/* Interface to p3ServiceInfo */ -void p3ServiceControl::getServiceChanges(std::set &updateSet) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::getServiceChanges()"; - std::cerr << std::endl; -#endif - - std::set::iterator it; - for (it = mUpdatedSet.begin(); it != mUpdatedSet.end(); ++it) - { - updateSet.insert(*it); - } - - mUpdatedSet.clear(); -} - -std::string p3ServiceControl::getServiceName(uint32_t service_id) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - std::map::const_iterator it = mOwnServices.find(service_id) ; - - if(it == mOwnServices.end()) - { - std::cerr << "(EE) Cannot find own service for ID = " << std::hex << service_id << std::dec << std::endl; - return std::string(); - } - - return it->second.mServiceName; -} - -bool p3ServiceControl::getOwnServices(RsPeerServiceInfo &info) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::getOwnServices()"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - info.mPeerId.clear() ; - info.mServiceList = mOwnServices; - return true; -} - - -bool p3ServiceControl::getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::getServicesAllowed(" << peerId.toStdString() << ")"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - info.mPeerId = peerId; - - // For each registered Service.. check if peer has permissions. - std::map::iterator it; - for(it = mOwnServices.begin(); it != mOwnServices.end(); ++it) - { - if (peerHasPermissionForService_locked(peerId, it->first)) - { - info.mServiceList[it->first] = it->second; - } - } - return true; -} - -bool p3ServiceControl::peerHasPermissionForService_locked(const RsPeerId &peerId, uint32_t serviceId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::peerHasPermissionForService_locked()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mServicePermissionMap.find(serviceId); - if (it == mServicePermissionMap.end()) - { - return false; - } - return it->second.peerHasPermission(peerId); -} - -// This is used by both RsServiceControl and p3ServiceInfo. -bool p3ServiceControl::getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::getServicesProvided()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mServicesProvided.find(peerId); - if (it == mServicesProvided.end()) - { - return false; - } - - info = it->second; - return true; -} - -bool p3ServiceControl::updateServicesProvided(const RsPeerId &peerId, const RsPeerServiceInfo &info) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateServicesProvided() from: " << peerId.toStdString(); - std::cerr << std::endl; - std::cerr << info; - std::cerr << std::endl; -#endif - - mServicesProvided[peerId] = info; - updateFilterByPeer_locked(peerId); - - IndicateConfigChanged() ; - return true; -} - -/* External Interface to RsServiceControl */ -bool p3ServiceControl::getServicePermissions(uint32_t serviceId, RsServicePermissions &permissions) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::getServicePermissions()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - - it = mServicePermissionMap.find(serviceId); - if (it == mServicePermissionMap.end()) - { - return false; - } - permissions = it->second; - return true; -} - -bool p3ServiceControl::createDefaultPermissions_locked(uint32_t serviceId, const std::string& serviceName, bool defaultOn) -{ - std::map::iterator it; - it = mServicePermissionMap.find(serviceId); - if (it == mServicePermissionMap.end()) - { - RsServicePermissions perms; - perms.mServiceId = serviceId; - perms.mServiceName = serviceName; - perms.mDefaultAllowed = defaultOn; - - mServicePermissionMap[serviceId] = perms; - IndicateConfigChanged() ; - return true; - } - return false; -} - - -bool p3ServiceControl::updateServicePermissions(uint32_t serviceId, const RsServicePermissions &permissions) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateServicePermissions()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - it = mServicePermissionMap.find(serviceId); - if (it == mServicePermissionMap.end()) - { - std::cerr << "p3ServiceControl::updateServicePermissions()"; - std::cerr << " ERROR missing previous permissions"; - std::cerr << std::endl; - // ERROR. - return false; - } - - std::list onlinePeers; - mLinkMgr->getOnlineList(onlinePeers); - std::list::const_iterator pit; - if (it != mServicePermissionMap.end()) - { - for(pit = onlinePeers.begin(); pit != onlinePeers.end(); ++pit) - { - if (it->second.peerHasPermission(*pit) != - permissions.peerHasPermission(*pit)) - { - mUpdatedSet.insert(*pit); - } - } - } - - it->second = permissions; - it->second.mServiceId = serviceId; // just to make sure! - - // This is overkill - but will update everything. - updateAllFilters_locked(); - IndicateConfigChanged() ; - return true; -} - - -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ -/****************************************************************************/ - -// This is the basic system... -// which will be a little slow (2x maps). -// -// Potential improvement is to push the RsPeerFilter -// to the pqiStreamer, (when items have been sorted by peers already!). -// but we will do this later. - -bool p3ServiceControl::checkFilter(uint32_t serviceId, const RsPeerId &peerId) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() "; - std::cerr << " ServiceId: " << serviceId; -#endif - - std::map::iterator it; - it = mOwnServices.find(serviceId); - if (it != mOwnServices.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << " ServiceName: " << it->second.mServiceName; -#endif - } - else - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << " ServiceName: Unknown! "; -#endif - } - -#ifdef SERVICECONTROL_DEBUG - std::cerr << " PeerId: " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - // must allow ServiceInfo through, or we have nothing! - if (serviceId == RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(RS_SERVICE_TYPE_SERVICEINFO)) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Allowed SERVICEINFO"; - std::cerr << std::endl; -#endif - return true; - } - - - std::map::const_iterator pit; - pit = mPeerFilterMap.find(peerId); - if (pit == mPeerFilterMap.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Denied No PeerId"; - std::cerr << std::endl; -#endif - return false; - } - - if (pit->second.mDenyAll) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Denied Peer.DenyAll"; - std::cerr << std::endl; -#endif - return false; - } - - if (pit->second.mAllowAll) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Allowed Peer.AllowAll"; - std::cerr << std::endl; -#endif - return true; - } - - std::set::const_iterator sit; - sit = pit->second.mAllowedServices.find(serviceId); - if (sit == pit->second.mAllowedServices.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Denied !Peer.find(serviceId)"; - std::cerr << std::endl; -#endif - return false; - } -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::checkFilter() Allowed Peer.find(serviceId)"; - std::cerr << std::endl; -#endif - return true; -} - -bool versionOkay(uint16_t version_major, uint16_t version_minor, - uint16_t min_version_major, uint16_t min_version_minor) -{ - if (version_major > min_version_major) - { - return true; - } - if (version_major == min_version_major) - { - return (version_minor >= min_version_minor); - } - return false; -} - - -bool ServiceInfoCompatible(const RsServiceInfo &info1, const RsServiceInfo &info2) -{ - // Id, or Name mismatch. - if ((info1.mServiceType != info2.mServiceType) || - (info1.mServiceName != info2.mServiceName)) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "servicesCompatible: Type/Name mismatch"; - std::cerr << std::endl; - std::cerr << "Info1 ID: " << info1.mServiceType; - std::cerr << " " << info1.mServiceName; - std::cerr << std::endl; - std::cerr << "Info2 ID: " << info2.mServiceType; - std::cerr << " " << info2.mServiceName; - std::cerr << std::endl; -#endif - return false; - } - - // ensure that info1 meets minimum requirements for info2 - if (!versionOkay(info1.mVersionMajor, info1.mVersionMinor, - info2.mMinVersionMajor, info2.mMinVersionMinor)) - { - return false; - } - - // ensure that info2 meets minimum requirements for info1 - if (!versionOkay(info2.mVersionMajor, info2.mVersionMinor, - info1.mMinVersionMajor, info1.mMinVersionMinor)) - { - return false; - } - return true; -} - - -bool p3ServiceControl::updateFilterByPeer(const RsPeerId &peerId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer()"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - return updateFilterByPeer_locked(peerId); -} - - -bool p3ServiceControl::updateAllFilters() -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateAllFilters()"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - return updateAllFilters_locked(); -} - - -bool p3ServiceControl::updateAllFilters_locked() -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateAllFilters_locked()"; - std::cerr << std::endl; -#endif - - // Create a peerSet from ServicesProvided + PeerFilters. - // This will completely refresh the Filters. - std::set peerSet; - std::set::const_iterator pit; - - std::map::const_iterator it; - for(it = mServicesProvided.begin(); it != mServicesProvided.end(); ++it) - { - peerSet.insert(it->first); - } - - std::map::const_iterator fit; - for(fit = mPeerFilterMap.begin(); fit != mPeerFilterMap.end(); ++fit) - { - peerSet.insert(fit->first); - } - - for(pit = peerSet.begin(); pit != peerSet.end(); ++pit) - { - updateFilterByPeer_locked(*pit); - } - return true; -} - - -// create filter. (the easy way). -bool p3ServiceControl::updateFilterByPeer_locked(const RsPeerId &peerId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer_locked() : " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - ServicePeerFilter originalFilter; - ServicePeerFilter peerFilter; - - std::map::iterator fit; - fit = mPeerFilterMap.find(peerId); - if (fit != mPeerFilterMap.end()) - { - originalFilter = fit->second; - } - - std::map::iterator it; - it = mServicesProvided.find(peerId); - if (it == mServicesProvided.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty ... Clearing"; - std::cerr << std::endl; -#endif - - // empty, remove... - recordFilterChanges_locked(peerId, originalFilter, peerFilter); - if (fit != mPeerFilterMap.end()) - { - std::cerr << std::endl; - mPeerFilterMap.erase(fit); - } - return true; - } - - // For each registered Service.. check if services compatible. - // then check for permissions. - - // similar maps, can iterate through in parallel. - std::map::const_iterator oit = mOwnServices.begin(); - std::map::const_iterator eoit = mOwnServices.end(); - std::map::const_iterator tit = it->second.mServiceList.begin(); - std::map::const_iterator etit = it->second.mServiceList.end(); - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Comparing lists"; - std::cerr << std::endl; -#endif - - - while((oit != eoit) && (tit != etit)) - { - if (oit->first == tit->first) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "\tChecking Matching Service ID: " << oit->first; - std::cerr << std::endl; -#endif - /* match of service IDs */ - /* check if compatible */ - if (ServiceInfoCompatible(oit->second, tit->second)) - { - if (peerHasPermissionForService_locked(peerId, oit->first)) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "\t\tMatched Service ID: " << oit->first; - std::cerr << std::endl; -#endif - peerFilter.mAllowedServices.insert(oit->first); - } - } - ++oit; - ++tit; - } - else - { - if (oit->first < tit->first) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "\tSkipping Only Own Service ID: " << oit->first; - std::cerr << std::endl; -#endif - ++oit; - } - else - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "\tSkipping Only Peer Service ID: " << tit->first; - std::cerr << std::endl; -#endif - ++tit; - } - } - } - - // small optimisations. - if (peerFilter.mAllowedServices.empty()) - { - peerFilter.mDenyAll = true; - } - else - { - peerFilter.mDenyAll = false; - if (peerFilter.mAllowedServices.size() == mOwnServices.size()) - { - peerFilter.mAllowAll = true; - } - } - - // update or remove. - if (peerFilter.mDenyAll) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Empty(2) ... Clearing"; - std::cerr << std::endl; -#endif - - if (fit != mPeerFilterMap.end()) - { - mPeerFilterMap.erase(fit); - } - } - else - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updateFilterByPeer_locked() Installing PeerFilter"; - std::cerr << std::endl; -#endif - mPeerFilterMap[peerId] = peerFilter; - } - recordFilterChanges_locked(peerId, originalFilter, peerFilter); - - using Evt_t = RsPeerStateChangedEvent; - if(rsEvents) - rsEvents->postEvent(std::unique_ptr(new Evt_t(peerId))); - - return true; -} - -void p3ServiceControl::recordFilterChanges_locked(const RsPeerId &peerId, - ServicePeerFilter &originalFilter, ServicePeerFilter &updatedFilter) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::recordFilterChanges_locked()"; - std::cerr << std::endl; - std::cerr << "PeerId: " << peerId.toStdString(); - std::cerr << std::endl; - std::cerr << "OriginalFilter: " << originalFilter; - std::cerr << std::endl; - std::cerr << "UpdatedFilter: " << updatedFilter; - std::cerr << std::endl; -#endif - - /* find differences */ - //std::map changes; - std::set::const_iterator it1, it2, eit1, eit2; - it1 = originalFilter.mAllowedServices.begin(); - eit1 = originalFilter.mAllowedServices.end(); - it2 = updatedFilter.mAllowedServices.begin(); - eit2 = updatedFilter.mAllowedServices.end(); - - while((it1 != eit1) && (it2 != eit2)) - { - if (*it1 < *it2) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "Removed Service: " << *it1; - std::cerr << std::endl; -#endif - // removal - //changes[*it1] = false; - filterChangeRemoved_locked(peerId, *it1); - ++it1; - } - else if (*it2 < *it1) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "Added Service: " << *it2; - std::cerr << std::endl; -#endif - // addition. - filterChangeAdded_locked(peerId, *it2); - //changes[*it2] = true; - ++it2; - } - else - { - ++it1; - ++it2; - } - } - - // Handle the unfinished Set. - for(; it1 != eit1; ++it1) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "Removed Service: " << *it1; - std::cerr << std::endl; -#endif - // removal - //changes[*it1] = false; - filterChangeRemoved_locked(peerId, *it1); - } - - for(; it2 != eit2; ++it2) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "Added Service: " << *it2; - std::cerr << std::endl; -#endif - // addition. - //changes[*it2] = true; - filterChangeAdded_locked(peerId, *it2); - } - - // Can remove changes map... as only used below. -#if 0 - // now we to store for later notifications. - std::map::const_iterator cit; - for(cit = changes.begin(); cit != changes.end(); ++cit) - { - ServiceNotifications ¬es = mNotifications[cit->first]; - if (cit->second) - { - notes.mAdded.insert(peerId); - } - else - { - notes.mRemoved.insert(peerId); - } - } -#endif - -} - - -// when they go offline, etc. -void p3ServiceControl::removePeer(const RsPeerId &peerId) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::removePeer() : " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - ServicePeerFilter originalFilter; - bool hadFilter = false; - { - std::map::iterator fit; - fit = mPeerFilterMap.find(peerId); - if (fit != mPeerFilterMap.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::removePeer() clearing mPeerFilterMap"; - std::cerr << std::endl; -#endif - - hadFilter = true; - originalFilter = fit->second; - mPeerFilterMap.erase(fit); - } - else - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::removePeer() Nothing in mPeerFilterMap"; - std::cerr << std::endl; -#endif - } - } - - { - std::map::iterator sit; - sit = mServicesProvided.find(peerId); - if (sit != mServicesProvided.end()) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::removePeer() clearing mServicesProvided"; - std::cerr << std::endl; -#endif - - mServicesProvided.erase(sit); - } - else - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::removePeer() Nothing in mServicesProvided"; - std::cerr << std::endl; -#endif - } - } - - if (hadFilter) - { - ServicePeerFilter emptyFilter; - recordFilterChanges_locked(peerId, originalFilter, emptyFilter); - } -} - -/****************************************************************************/ -/****************************************************************************/ -// need to provide list of connected peers per service. -// these are collected here. - -void p3ServiceControl::filterChangeRemoved_locked(const RsPeerId &peerId, uint32_t serviceId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::filterChangeRemoved_locked(" << peerId.toStdString(); - std::cerr << ", " << serviceId << ")"; - std::cerr << std::endl; -#endif - - //std::map >::iterator mit; - - std::set &peerSet = mServicePeerMap[serviceId]; - std::set::iterator sit; - - sit = peerSet.find(peerId); - if (sit != peerSet.end()) - { - peerSet.erase(sit); - } - else - { - // ERROR - std::cerr << "p3ServiceControl::filterChangeRemoved_locked() ERROR NOT FOUND"; - std::cerr << std::endl; - } - - // Add to Notifications too. - ServiceNotifications ¬es = mNotifications[serviceId]; - notes.mRemoved.insert(peerId); -} - - -void p3ServiceControl::filterChangeAdded_locked(const RsPeerId &peerId, uint32_t serviceId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::filterChangeAdded_locked(" << peerId.toStdString(); - std::cerr << ", " << serviceId << ")"; - std::cerr << std::endl; -#endif - - //std::map >::iterator mit; - - std::set &peerSet = mServicePeerMap[serviceId]; - - // This bit is only for error checking. - std::set::iterator sit = peerSet.find(peerId); - if (sit != peerSet.end()) - { - // ERROR. - std::cerr << "p3ServiceControl::filterChangeAdded_locked() ERROR NOT FOUND"; - std::cerr << std::endl; - } - peerSet.insert(peerId); - - // Add to Notifications too. - ServiceNotifications ¬es = mNotifications[serviceId]; - notes.mAdded.insert(peerId); -} - - - -void p3ServiceControl::getPeersConnected(uint32_t serviceId, std::set &peerSet) -{ - RS_STACK_MUTEX(mCtrlMtx); - - std::map >::iterator mit; - mit = mServicePeerMap.find(serviceId); - if (mit != mServicePeerMap.end()) - { - peerSet = mit->second; - } - else - { - peerSet.clear(); - } -} - - -bool p3ServiceControl::isPeerConnected(uint32_t serviceId, const RsPeerId &peerId) -{ - RS_STACK_MUTEX(mCtrlMtx); - - std::map >::iterator mit; - mit = mServicePeerMap.find(serviceId); - if (mit != mServicePeerMap.end()) - { - std::set::iterator sit; - sit = mit->second.find(peerId); - return (sit != mit->second.end()); - } - - return false; -} - - -/****************************************************************************/ -/****************************************************************************/ - -void p3ServiceControl::tick() -{ - notifyAboutFriends(); - notifyServices(); - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::tick()"; - std::cerr << std::endl; -#endif -} - -// configuration. -bool p3ServiceControl::saveList(bool &cleanup, std::list &saveList) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::saveList()"; - std::cerr << std::endl; -#endif - cleanup = true ; - - for(std::map::iterator it(mServicePermissionMap.begin());it!=mServicePermissionMap.end();++it) - { - RsServicePermissionItem *item = new RsServicePermissionItem(it->second) ; - saveList.push_back(item) ; - } - return true; -} - -bool p3ServiceControl::loadList(std::list& loadList) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::loadList()"; - std::cerr << std::endl; -#endif - for(std::list::const_iterator it(loadList.begin());it!=loadList.end();++it) - { - RsServicePermissionItem *item = dynamic_cast(*it) ; - - if(item != NULL) - mServicePermissionMap[item->mServiceId] = *item ; - - delete *it ; - } - - loadList.clear() ; - return true; -} - - -/****************************************************************************/ -/****************************************************************************/ - - // pqiMonitor. -void p3ServiceControl::statusChange(const std::list &plist) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::statusChange()"; - std::cerr << std::endl; -#endif - - std::list::const_iterator pit; - for(pit = plist.begin(); pit != plist.end(); ++pit) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::statusChange() for peer: "; - std::cerr << " peer: " << (pit->id).toStdString(); - std::cerr << " state: " << pit->state; - std::cerr << " actions: " << pit->actions; - std::cerr << std::endl; -#endif - if (pit->state & RS_PEER_S_FRIEND) - { - // Connected / Disconnected. (interal actions). - if (pit->actions & RS_PEER_CONNECTED) - { - updatePeerConnect(pit->id); - } - else if (pit->actions & RS_PEER_DISCONNECTED) - { - updatePeerDisconnect(pit->id); - } - - // Added / Removed. (pass on notifications). - if (pit->actions & RS_PEER_NEW) - { - updatePeerNew(pit->id); - } - } - else - { - if (pit->actions & RS_PEER_MOVED) - { - updatePeerRemoved(pit->id); - } - } - } - return; -} - -// Update Peer status. -void p3ServiceControl::updatePeerConnect(const RsPeerId &peerId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updatePeerConnect(): " << peerId.toStdString(); - std::cerr << std::endl; -#else - (void)peerId; -#endif - return; -} - -void p3ServiceControl::updatePeerDisconnect(const RsPeerId &peerId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updatePeerDisconnect(): " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - removePeer(peerId); - return; -} - - -// Update Peer status. -void p3ServiceControl::updatePeerNew(const RsPeerId &peerId) -{ - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updatePeerNew(): " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - pqiServicePeer peer; - peer.id = peerId; - peer.actions = RS_SERVICE_PEER_NEW; - mFriendNotifications.push_back(peer); - - return; -} - -void p3ServiceControl::updatePeerRemoved(const RsPeerId &peerId) -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::updatePeerRemoved(): " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - removePeer(peerId); - - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - pqiServicePeer peer; - peer.id = peerId; - peer.actions = RS_SERVICE_PEER_REMOVED; - mFriendNotifications.push_back(peer); - - return; -} - -/****************************************************************************/ -/****************************************************************************/ - - -void p3ServiceControl::notifyAboutFriends() -{ - std::list friendNotifications; - { - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - if (mFriendNotifications.empty()) - { - return; - } -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyAboutFriends(): Something has changed!"; - std::cerr << std::endl; -#endif - - mFriendNotifications.swap(friendNotifications); - } - - { - RsStackMutex stack(mMonitorMtx); /***** LOCK STACK MUTEX ****/ - - std::multimap::const_iterator sit; - for(sit = mMonitors.begin(); sit != mMonitors.end(); ++sit) - { - sit->second->statusChange(friendNotifications); - } - } -} - - -void p3ServiceControl::notifyServices() -{ - std::map notifications; - { - RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ - - if (mNotifications.empty()) - { - return; - } - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices()"; - std::cerr << std::endl; -#endif - - mNotifications.swap(notifications); - } - - { - RsStackMutex stack(mMonitorMtx); /***** LOCK STACK MUTEX ****/ - - std::map::const_iterator it; - std::multimap::const_iterator sit, eit; - for(it = notifications.begin(); it != notifications.end(); ++it) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices(): Notifications for Service: " << it->first; - std::cerr << std::endl; -#endif - - sit = mMonitors.lower_bound(it->first); - eit = mMonitors.upper_bound(it->first); - if (sit == eit) - { - /* nothing to notify - skip */ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices(): Noone Monitoring ... skipping"; - std::cerr << std::endl; -#endif - - continue; - } - - std::list peers; - std::set::const_iterator pit; - for(pit = it->second.mAdded.begin(); - pit != it->second.mAdded.end(); ++pit) - { - pqiServicePeer peer; - peer.id = *pit; - peer.actions = RS_SERVICE_PEER_CONNECTED; - - peers.push_back(peer); - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " CONNECTED"; - std::cerr << std::endl; -#endif - } - - for(pit = it->second.mRemoved.begin(); - pit != it->second.mRemoved.end(); ++pit) - { - pqiServicePeer peer; - peer.id = *pit; - peer.actions = RS_SERVICE_PEER_DISCONNECTED; - - peers.push_back(peer); - -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices(): Peer: " << *pit << " DISCONNECTED"; - std::cerr << std::endl; -#endif - } - - for(; sit != eit; ++sit) - { -#ifdef SERVICECONTROL_DEBUG - std::cerr << "p3ServiceControl::notifyServices(): Sending to Monitoring Service"; - std::cerr << std::endl; -#endif - - sit->second->statusChange(peers); - } - } - } -} - - -/****************************************************************************/ -/****************************************************************************/ - - -RsServicePermissions::RsServicePermissions() -:mServiceId(0), mServiceName(), mDefaultAllowed(false) -{ - return; -} - -bool RsServicePermissions::peerHasPermission(const RsPeerId &peerId) const -{ -#ifdef SERVICECONTROL_DEBUG - std::cerr << "RsServicePermissions::peerHasPermission()"; - std::cerr << std::endl; -#endif - - std::set::const_iterator it; - if (mDefaultAllowed) - { - it = mPeersDenied.find(peerId); - return (it == mPeersDenied.end()); - } - else - { - it = mPeersAllowed.find(peerId); - return (it != mPeersAllowed.end()); - } -} - -void RsServicePermissions::setPermission(const RsPeerId& peerId) -{ - std::set::const_iterator it; - if (mDefaultAllowed) - { - it = mPeersDenied.find(peerId); - mPeersDenied.erase(it) ; - } - else - mPeersAllowed.insert(peerId); -} -void RsServicePermissions::resetPermission(const RsPeerId& peerId) -{ - std::set::const_iterator it; - if (!mDefaultAllowed) - { - it = mPeersAllowed.find(peerId); - mPeersAllowed.erase(it) ; - } - else - mPeersDenied.insert(peerId); -} - -RsServiceInfo::RsServiceInfo( - const uint16_t service_type, - const std::string& service_name, - const uint16_t version_major, - const uint16_t version_minor, - const uint16_t min_version_major, - const uint16_t min_version_minor) - :mServiceName(service_name), - mServiceType(RsServiceInfoUIn16ToFullServiceId(service_type)), - mVersionMajor(version_major), - mVersionMinor(version_minor), - mMinVersionMajor(min_version_major), - mMinVersionMinor(min_version_minor) -{ - return; -} - -unsigned int RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(uint16_t serviceType) -{ - return (((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) serviceType) << 8); -} - - -RsServiceInfo::RsServiceInfo() - :mServiceName("unknown"), - mServiceType(0), - mVersionMajor(0), - mVersionMinor(0), - mMinVersionMajor(0), - mMinVersionMinor(0) -{ - return; -} - -std::ostream &operator<<(std::ostream &out, const ServicePeerFilter &filter) -{ - out << "ServicePeerFilter DenyAll: " << filter.mDenyAll; - out << " AllowAll: " << filter.mAllowAll; - out << " Matched Services: "; - std::set::const_iterator it; - for(it = filter.mAllowedServices.begin(); it != filter.mAllowedServices.end(); ++it) - { - out << *it << " "; - } - out << std::endl; - return out; -} - - diff --git a/libretroshare/src/pqi/p3servicecontrol.h b/libretroshare/src/pqi/p3servicecontrol.h deleted file mode 100644 index fa4e4f37e..000000000 --- a/libretroshare/src/pqi/p3servicecontrol.h +++ /dev/null @@ -1,205 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3servicecontrol.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014-2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_SERVICE_CONTROL_HEADER -#define P3_SERVICE_CONTROL_HEADER - -#include -#include - -#include "retroshare/rsservicecontrol.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/pqimonitor.h" -#include "pqi/pqiservicemonitor.h" -#include "pqi/p3linkmgr.h" - -class p3ServiceServer ; - -class ServiceNotifications -{ - public: - std::set mAdded; - std::set mRemoved; -}; - -class ServicePeerFilter -{ - public: - ServicePeerFilter() - :mDenyAll(true), mAllowAll(false) {} - - bool mDenyAll; - bool mAllowAll; - std::set mAllowedServices; -}; - -std::ostream &operator<<(std::ostream &out, const ServicePeerFilter &filter); - -class ServiceControlSerialiser ; - -class p3ServiceControl: public RsServiceControl, public pqiMonitor, public p3Config -{ -public: - - /** - */ - explicit p3ServiceControl(p3LinkMgr *linkMgr); - - /** - * checks and update all added configurations - * @see rsserver - */ - void tick(); - - /** - * provided so that services don't need linkMgr, and can get all info - * from ServiceControl. - * @see rsserver - */ - -virtual const RsPeerId& getOwnId(); - - /** - * External Interface (RsServiceControl). - */ - -virtual bool getOwnServices(RsPeerServiceInfo &info); -virtual std::string getServiceName(uint32_t service_id) ; - - // This is what is passed to peers, can be displayed by GUI too. -virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info); - - // Information provided by peer. -virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info); - - // Main Permission Interface. -virtual bool getServicePermissions(uint32_t serviceId, RsServicePermissions &permissions); -virtual bool updateServicePermissions(uint32_t serviceId, const RsServicePermissions &permissions); - - // Get List of Peers using this Service. -virtual void getPeersConnected(uint32_t serviceId, std::set &peerSet); -virtual bool isPeerConnected(uint32_t serviceId, const RsPeerId &peerId); - - // Gets the list of items used by that service -virtual bool getServiceItemNames(uint32_t serviceId,std::map& names) ; - - /** - * Registration for all Services. - */ - -virtual bool registerService(const RsServiceInfo &info, bool defaultOn); -virtual bool deregisterService(uint32_t serviceId); - -virtual bool registerServiceMonitor(pqiServiceMonitor *monitor, uint32_t serviceId); -virtual bool deregisterServiceMonitor(pqiServiceMonitor *monitor); - - /** - * - */ - - - // Filter for services. -virtual bool checkFilter(uint32_t serviceId, const RsPeerId &peerId); - - /** - * Interface for ServiceInfo service. - */ - - // ServicesAllowed have changed for these peers. -virtual void getServiceChanges(std::set &updateSet); - - // Input from peers. -virtual bool updateServicesProvided(const RsPeerId &peerId, const RsPeerServiceInfo &info); - - // pqiMonitor. -virtual void statusChange(const std::list &plist); - - virtual void setServiceServer(p3ServiceServer *p) { mServiceServer = p ; } - -protected: - // configuration. -virtual bool saveList(bool &cleanup, std::list&); -virtual bool loadList(std::list& load); -virtual RsSerialiser *setupSerialiser() ; - -private: - -void notifyServices(); -void notifyAboutFriends(); - -void updatePeerConnect(const RsPeerId &peerId); -void updatePeerDisconnect(const RsPeerId &peerId); -void updatePeerNew(const RsPeerId &peerId); -void updatePeerRemoved(const RsPeerId &peerId); - -void removePeer(const RsPeerId &peerId); - - -bool updateAllFilters(); -bool updateAllFilters_locked(); -bool updateFilterByPeer(const RsPeerId &peerId); -bool updateFilterByPeer_locked(const RsPeerId &peerId); - - - void recordFilterChanges_locked(const RsPeerId &peerId, - ServicePeerFilter &originalFilter, ServicePeerFilter &updatedFilter); - - // Called from recordFilterChanges. - void filterChangeAdded_locked(const RsPeerId &peerId, uint32_t serviceId); - void filterChangeRemoved_locked(const RsPeerId &peerId, uint32_t serviceId); - -bool createDefaultPermissions_locked(uint32_t serviceId, const std::string& serviceName, bool defaultOn); -bool peerHasPermissionForService_locked(const RsPeerId &peerId, uint32_t serviceId); - - p3LinkMgr *mLinkMgr; - const RsPeerId mOwnPeerId; // const from constructor - - RsMutex mCtrlMtx; /* below is protected */ - - std::set mUpdatedSet; - - // From registration / deregistration. - std::map mOwnServices; - // From peers. - std::map mServicesProvided; - // derived from all the others. - std::map mPeerFilterMap; - - std::map mNotifications; - std::list mFriendNotifications; - - // Map of Connected Peers per Service. - std::map > mServicePeerMap; - - // Separate mutex here - must not hold both at the same time! - RsMutex mMonitorMtx; /* below is protected */ - std::multimap mMonitors; - - ServiceControlSerialiser *mSerialiser ; - - // Below here is saved in Configuration. - std::map mServicePermissionMap; - - p3ServiceServer *mServiceServer ; -}; - - -#endif // P3_SERVICE_CONTROL_HEADER diff --git a/libretroshare/src/pqi/p3upnpmgr.h b/libretroshare/src/pqi/p3upnpmgr.h deleted file mode 100644 index 6f58aa8ae..000000000 --- a/libretroshare/src/pqi/p3upnpmgr.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: p3upnpmgr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2007 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_P3_UPNP_MANAGER_H -#define MRK_P3_UPNP_MANAGER_H - -/* platform independent networking... */ -#include "util/rsthreads.h" -#include "pqi/pqinetwork.h" - -class p3UpnpMgr: public pqiNetAssistFirewall -{ - public: - -virtual ~p3UpnpMgr() { return; } - - /* External Interface */ -virtual void enable(bool on) = 0; /* launches thread to start it up */ -virtual void shutdown() = 0; /* blocking shutdown call */ -virtual void restart() = 0; /* must be called if ports change */ - -virtual bool getEnabled() = 0; -virtual bool getActive() = 0; - - /* the address that the listening port is on */ -virtual void setInternalPort(unsigned short iport_in) = 0; -virtual void setExternalPort(unsigned short eport_in) = 0; - - /* as determined by uPnP */ -virtual bool getInternalAddress(struct sockaddr_storage &addr) = 0; -virtual bool getExternalAddress(struct sockaddr_storage &addr) = 0; - -}; - -#endif /* MRK_P3_UPNP_MANAGER_H */ - diff --git a/libretroshare/src/pqi/pqi.h b/libretroshare/src/pqi/pqi.h deleted file mode 100644 index 1bf581ff1..000000000 --- a/libretroshare/src/pqi/pqi.h +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqi.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_TOP_HEADER -#define PQI_TOP_HEADER - -#include "rsitems/rsitem.h" - -class P3Interface -{ -public: - P3Interface() {return; } -virtual ~P3Interface() {return; } - -virtual int tick() { return 1; } -virtual int status() { return 1; } - -virtual int SendRsRawItem(RsRawItem *) = 0; -}; - - -/** - * @brief Interface to allow outgoing messages to be sent directly through to - * the pqiperson, rather than being queued - */ -class pqiPublisher -{ - public: -virtual ~pqiPublisher() { return; } -virtual bool sendItem(RsRawItem *item) = 0; - -}; - - -#endif // PQI_TOP_HEADER diff --git a/libretroshare/src/pqi/pqi_base.h b/libretroshare/src/pqi/pqi_base.h deleted file mode 100644 index 51980b501..000000000 --- a/libretroshare/src/pqi/pqi_base.h +++ /dev/null @@ -1,417 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqi_base.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_BASE_ITEM_HEADER -#define PQI_BASE_ITEM_HEADER - -#include -#include -#include -#include -#include -#include - -#include "pqi/pqinetwork.h" - -struct RSTrafficClue; - -/*** Base DataTypes: ****/ -#include "serialiser/rsserial.h" -#include "retroshare/rstypes.h" - -int getPQIsearchId(); -int fixme(char *str, int n); - -struct RsPeerCryptoParams; - -//! controlling data rates -/*! - * For controlling data rates. - * #define DEBUG_RATECAP 1 - */ - -class RsBwRates -{ - public: - RsBwRates() - :mRateIn(0), mRateOut(0), mMaxRateIn(0), mMaxRateOut(0), mQueueIn(0), mQueueOut(0) {return;} - float mRateIn; - float mRateOut; - float mMaxRateIn; - float mMaxRateOut; - int mQueueIn; - int mQueueOut; -}; - - -class RateInterface -{ - -public: - - RateInterface() - :bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0), - bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; } - - virtual ~RateInterface() { return; } - - virtual void getRates(RsBwRates &rates) - { - rates.mRateIn = bw_in; - rates.mRateOut = bw_out; - rates.mMaxRateIn = bwMax_in; - rates.mMaxRateOut = bwMax_out; - return; - } - - virtual int gatherStatistics(std::list& /* outqueue_lst */,std::list& /* inqueue_lst */) { return 0;} - - virtual int getQueueSize(bool /* in */) { return 0;} - virtual float getRate(bool in) - { - if (in) - return bw_in; - return bw_out; - } - - virtual float getMaxRate(bool in) - { - if (in) - return bwMax_in; - return bwMax_out; - } - - virtual void setMaxRate(bool in, float val) - { - if (in) - { - bwMax_in = val; - if (bwCapEnabled) - { - if (bwMax_in > bwCap_in) - { - bwMax_in = bwCap_in; - } - } - } - else - { - bwMax_out = val; - if (bwCapEnabled) - { - if (bwMax_out > bwCap_out) - { - bwMax_out = bwCap_out; - } - } - } - - return; - } - - - virtual void setRateCap(float val_in, float val_out) - { - if ((val_in == 0) && (val_out == 0)) - { -#ifdef DEBUG_RATECAP - std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl; -#endif - bwCapEnabled = false; - } - else - { -#ifdef DEBUG_RATECAP - std::cerr << "RateInterface::setRateCap() Enabled "; - std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl; -#endif - bwCapEnabled = true; - bwCap_in = val_in; - bwCap_out = val_out; - } - return; - } - -protected: - - virtual void setRate(bool in, float val) - { - if (in) - bw_in = val; - else - bw_out = val; - return; - } - -private: - float bw_in, bw_out, bwMax_in, bwMax_out; - bool bwCapEnabled; - float bwCap_in, bwCap_out; - -}; - - -class NetInterface; - -//! The basic exchange interface. -/*! - * - * This inherits the RateInterface, as Bandwidth control - * is critical to a networked application. - **/ -class PQInterface: public RateInterface -{ -public: - explicit PQInterface(const RsPeerId &id) : - traf_in(0), traf_out(0), peerId(id) {} - virtual ~PQInterface() {} - - /*! - * allows user to send RsItems to a particular facility (file, network) - */ - virtual int SendItem(RsItem *) = 0; - - // this function is overloaded in classes that need the serilized size to be returned. - virtual int SendItem(RsItem *item,uint32_t& size) - { - size = 0 ; - - static bool already=false ; - if(!already) - { - std::cerr << "Warning: PQInterface::SendItem(RsItem*,uint32_t&) calledbut not overloaded! Serialized size will not be returned." << std::endl; - already=true ; - } - return SendItem(item) ; - } - - virtual bool getCryptoParams(RsPeerCryptoParams&) { return false ;} - - /*! - * Retrieve RsItem from a facility - */ - virtual RsItem *GetItem() = 0; - virtual bool RecvItem(RsItem * /*item*/ ) { return false; } /* alternative for for GetItem(), when we want to push */ - - /** - * also there are tick + person id functions. - */ - virtual int tick() { return 0; } - virtual int status() { return 0; } - virtual const RsPeerId& PeerId() { return peerId; } - - // the callback from NetInterface Connection Events. - virtual int notifyEvent(NetInterface * /*ni*/, int /*event*/, - const sockaddr_storage & /*remote_peer_address*/) - { return 0; } - - virtual uint64_t getTraffic(bool in) - { - uint64_t ret = 0; - if (in) - { - ret = traf_in; - traf_in = 0; - return ret; - } - ret = traf_out; - traf_out = 0; - return ret; - } - uint64_t traf_in; - uint64_t traf_out; - - private: - - RsPeerId peerId; -}; - - - -/**** Consts for pqiperson -> placed here for NetBinDummy usage() */ - -const uint32_t PQI_CONNECT_TCP = 0x0001; -const uint32_t PQI_CONNECT_UDP = 0x0002; -const uint32_t PQI_CONNECT_HIDDEN_TOR_TCP = 0x0004; -const uint32_t PQI_CONNECT_HIDDEN_I2P_TCP = 0x0008; - - -#define BIN_FLAGS_NO_CLOSE 0x0001 -#define BIN_FLAGS_READABLE 0x0002 -#define BIN_FLAGS_WRITEABLE 0x0004 -#define BIN_FLAGS_NO_DELETE 0x0008 -#define BIN_FLAGS_HASH_DATA 0x0010 - -/*! - * This defines the binary interface used by Network/loopback/file - * interfaces - * e.g. sending binary data to file or to memory or even through a socket - */ -class BinInterface -{ -public: - BinInterface() {} - virtual ~BinInterface() {} - - /** - * To be called loop, for updating state - */ - virtual int tick() = 0; - - /** - * Sends data to a prescribed location (implementation dependent) - *@param data what will be sent - *@param len the size of data pointed to in memory - */ - virtual int senddata(void *data, int len) = 0; - - /** - * reads data from a prescribed location (implementation dependent) - *@param data what will be sent - *@param len the size of data pointed to in memory - */ - virtual int readdata(void *data, int len) = 0; - - /** - * Is more particular the case of the sending data through a socket (internet) - * moretoread and candsend, take a microsec timeout argument. - * - */ - virtual int netstatus() = 0; - virtual int isactive() = 0; - virtual bool moretoread(uint32_t usec) = 0; - virtual bool cansend(uint32_t usec) = 0; - - /** - * method for streamer to shutdown bininterface - **/ - virtual int close() = 0; - - /** - * If hashing data - **/ - virtual RsFileHash gethash() = 0; - - /** - * Number of bytes read/sent - */ - virtual uint64_t bytecount() { return 0; } - - /** - * used by pqistreamer to limit transfers - **/ - virtual bool bandwidthLimited() { return true; } -}; - - - -static const int NET_CONNECT_RECEIVED = 1; -static const int NET_CONNECT_SUCCESS = 2; -static const int NET_CONNECT_UNREACHABLE = 3; -static const int NET_CONNECT_FIREWALLED = 4; -static const int NET_CONNECT_FAILED = 5; - -static const uint32_t NET_PARAM_CONNECT_DELAY = 1; -static const uint32_t NET_PARAM_CONNECT_PERIOD = 2; -static const uint32_t NET_PARAM_CONNECT_TIMEOUT = 3; -static const uint32_t NET_PARAM_CONNECT_FLAGS = 4; -static const uint32_t NET_PARAM_CONNECT_BANDWIDTH = 5; - -static const uint32_t NET_PARAM_CONNECT_PROXY = 6; -static const uint32_t NET_PARAM_CONNECT_SOURCE = 7; - -static const uint32_t NET_PARAM_CONNECT_DOMAIN_ADDRESS = 8; -static const uint32_t NET_PARAM_CONNECT_REMOTE_PORT = 9; - - -/*! - * ******************** Network INTERFACE *************************** - * This defines the Network interface used by sockets/SSL/XPGP - * interfaces - * - * NetInterface: very pure interface, so no tick.... - * - * It is passed a pointer to a PQInterface *parent, - * this is used to notify the system of Connect/Disconnect Events. - * - * Below are the Events for callback. - **/ -class NetInterface -{ -public: - - /** - * @param p_in used to notify system of connect/disconnect events - */ - NetInterface(PQInterface *p_in, const RsPeerId& id) : p(p_in), peerId(id) {} - - virtual ~NetInterface() {} - - /* TODO - * The data entrypoint is connect(const struct sockaddr_storage &raddr) - * To generalize NetInterface we should have a more general type for raddr - * As an example a string containing an url or encoded like a domain name - */ - virtual int connect(const struct sockaddr_storage &raddr) = 0; - - virtual int listen() = 0; - virtual int stoplistening() = 0; - virtual int disconnect() = 0; - virtual int reset() = 0; - virtual const RsPeerId& PeerId() { return peerId; } - virtual int getConnectAddress(struct sockaddr_storage &raddr) = 0; - - virtual bool connect_parameter(uint32_t type, uint32_t value) = 0; - virtual bool connect_parameter(uint32_t /* type */ , const std::string & /* value */ ) { return false; } // not generally used. - virtual bool connect_additional_address(uint32_t /*type*/, const struct sockaddr_storage & /*addr*/) { return false; } // only needed by udp. - -protected: - PQInterface *parent() { return p; } - -private: - PQInterface *p; - RsPeerId peerId; -}; - -//! network binary interface (abstract) -/** - * Should be used for networking and connecting to addresses - * - * @see pqissl - * @see NetInterface - * @see BinInterface - **/ -class NetBinInterface: public NetInterface, public BinInterface -{ -public: - NetBinInterface(PQInterface *parent, const RsPeerId& id) : - NetInterface(parent, id) {} - virtual ~NetBinInterface() {} -}; - -#define CHAN_SIGN_SIZE 16 -#define CERTSIGNLEN 16 /* actual byte length of signature */ -#define PQI_PEERID_LENGTH 32 /* When expanded into a string */ - - - -#endif // PQI_BASE_ITEM_HEADER - diff --git a/libretroshare/src/pqi/pqiassist.h b/libretroshare/src/pqi/pqiassist.h deleted file mode 100644 index e7b508a3e..000000000 --- a/libretroshare/src/pqi/pqiassist.h +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiassist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2007 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include "retroshare/rstypes.h" -#include "pqi/pqinetwork.h" -#include "pqi/pqimonitor.h" - -/** - * @file - * This header file provides interfaces for assisting the connections to - * friends. - */ - -class pqiNetAssist -{ -public: - - /* External Interface */ -virtual void enable(bool on) = 0; -virtual void shutdown() = 0; /* blocking call */ -virtual void restart() = 0; - -virtual bool getEnabled() = 0; -virtual bool getActive() = 0; - -virtual int tick() { return 0; } /* for internal accounting */ - - virtual ~pqiNetAssist(); -}; - -struct PortForwardParams -{ - uint32_t fwdId; - uint32_t status; - uint32_t typeFlags; - sockaddr_storage intAddr; - sockaddr_storage extaddr; -}; - -/** - * Provides interfaces to functionality like upnp and apple's equivalent. - */ -class pqiNetAssistFirewall: public pqiNetAssist -{ -public: - /* the address that the listening port is on */ -virtual void setInternalPort(unsigned short iport_in) = 0; -virtual void setExternalPort(unsigned short eport_in) = 0; - - /* as determined by uPnP */ -virtual bool getInternalAddress(struct sockaddr_storage &addr) = 0; -virtual bool getExternalAddress(struct sockaddr_storage &addr) = 0; - - - /* New Port Forward interface to support as many ports as necessary */ -virtual bool requestPortForward(const PortForwardParams ¶ms) = 0; -virtual bool statusPortForward(const uint32_t fwdId, PortForwardParams ¶ms) = 0; - - -}; - - -#define PNASS_TYPE_BADPEER 0x0001 -#define PNASS_REASON_UNKNOWN 0x0001 - -class pqiNetAssistPeerShare -{ -public: - /** share Addresses for various reasons (bad peers, etc) */ - virtual void updatePeer( - const RsPeerId& id, const struct sockaddr_storage &addr, - int type, int reason, int age ) = 0; - - virtual ~pqiNetAssistPeerShare(); -}; - - -#ifdef RS_USE_DHT_STUNNER -/* this is for the Stunners - * - * - */ - -class pqiAddrAssist -{ - public: - - pqiAddrAssist() { return; } -virtual ~pqiAddrAssist() { return; } - -virtual bool getExternalAddr(struct sockaddr_storage &remote, uint8_t &stable) = 0; -virtual void setRefreshPeriod(int32_t period) = 0; -virtual int tick() = 0; /* for internal accounting */ - -}; -#endif // RS_USE_DHT_STUNNER - -#define NETASSIST_KNOWN_PEER_OFFLINE 0x0001 -#define NETASSIST_KNOWN_PEER_ONLINE 0x0002 - -#define NETASSIST_KNOWN_PEER_WHITELIST 0x0100 -#define NETASSIST_KNOWN_PEER_FRIEND 0x0200 -#define NETASSIST_KNOWN_PEER_FOF 0x0400 -#define NETASSIST_KNOWN_PEER_RELAY 0x0800 -#define NETASSIST_KNOWN_PEER_SELF 0x1000 - -#define NETASSIST_KNOWN_PEER_TYPE_MASK 0xff00 - -/** - * Provides interfaces to other networks like DHT that can provide information. - * These classes would be expected to use the pqiMonitor callback system to - * notify the connectionMgr. - */ -class pqiNetAssistConnect: public pqiNetAssist -{ -public: - pqiNetAssistConnect(const RsPeerId& id, pqiConnectCb *cb) : - mPeerId(id), mConnCb(cb) {} - - /********** External DHT Interface ************************ - * These Functions are the external interface - * for the DHT, and must be non-blocking and return quickly - */ - - /* add / remove peers */ -virtual bool findPeer(const RsPeerId& id) = 0; -virtual bool dropPeer(const RsPeerId& id) = 0; - - /* add non-active peers (can still toggle active/non-active via above) */ -virtual int addBadPeer(const struct sockaddr_storage &addr, uint32_t reason, uint32_t flags, uint32_t age) = 0; -virtual int addKnownPeer(const RsPeerId &pid, const struct sockaddr_storage &addr, uint32_t flags) = 0; - -virtual void ConnectionFeedback(const RsPeerId& pid, int mode) = 0; - - /* extract current peer status */ -virtual bool getPeerStatus(const RsPeerId& id, - struct sockaddr_storage &laddr, struct sockaddr_storage &raddr, - uint32_t &type, uint32_t &mode) = 0; // DEPRECIATE. - -virtual bool setAttachMode(bool on) = 0; // FIXUP. - - /***** Stats for Network / DHT *****/ -virtual bool getNetworkStats(uint32_t &netsize, uint32_t &localnetsize) = 0; // DEPRECIATE. - - ~pqiNetAssistConnect() override; - -protected: - RsPeerId mPeerId; - pqiConnectCb *mConnCb; -}; diff --git a/libretroshare/src/pqi/pqibin.cc b/libretroshare/src/pqi/pqibin.cc deleted file mode 100644 index 75e0b4b39..000000000 --- a/libretroshare/src/pqi/pqibin.cc +++ /dev/null @@ -1,746 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqibin.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqibin.h" -#include "pqi/authssl.h" -#include "util/rsnet.h" -#include "util/rsdir.h" -#include "util/rsmemory.h" - -// #define DEBUG_PQIBIN - -BinFileInterface::BinFileInterface(const char *fname, int flags) - :bin_flags(flags), buf(NULL), hash(NULL), bcount(0) -{ - /* if read + write - open r+ */ - if ((bin_flags & BIN_FLAGS_READABLE) && - (bin_flags & BIN_FLAGS_WRITEABLE)) - { - buf = RsDirUtil::rs_fopen(fname, "rb+"); - /* if the file don't exist */ - if (!buf) - { - buf = RsDirUtil::rs_fopen(fname, "wb+"); - } - - } - else if (bin_flags & BIN_FLAGS_READABLE) - { - buf = RsDirUtil::rs_fopen(fname, "rb"); - } - else if (bin_flags & BIN_FLAGS_WRITEABLE) - { - // This is enough to remove old file in Linux... - // but not in windows.... (what to do) - buf = RsDirUtil::rs_fopen(fname, "wb"); - fflush(buf); /* this might help windows! */ - } - else - { - /* not read or write! */ - } - - if (buf) - { -#ifdef DEBUG_PQIBIN - std::cerr << "BinFileInterface: " << (void*)this << ": openned file " << fname << std::endl; -#endif - /* no problem */ - - /* go to the end */ - fseek(buf, 0L, SEEK_END); - /* get size */ - size = ftell(buf); - /* back to the start */ - fseek(buf, 0L, SEEK_SET); - } - else - { - size = 0; - } - - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash = new pqihash(); - } -} - - -BinFileInterface::~BinFileInterface() -{ - if (buf) - { - fclose(buf); -#ifdef DEBUG_PQIBIN - std::cerr << "BinFileInterface: " << (void*)this << ": closed file " << std::endl; -#endif - } - - if (hash) - { - delete hash; - } -} - -int BinFileInterface::close() -{ - if (buf) - { - fclose(buf); -#ifdef DISTRIB_DEBUG - std::cerr << "BinFileInterface: " << (void*)this << ": closed file " << std::endl; -#endif - buf = NULL; - } - return 1; -} - -int BinFileInterface::senddata(void *data, int len) -{ - if (!buf) - return -1; - - if (1 != fwrite(data, len, 1, buf)) - { - return -1; - } - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->addData(data, len); - bcount += len; - } - return len; -} - -int BinFileInterface::readdata(void *data, int len) -{ - if (!buf) - return -1; - - if (1 != fread(data, len, 1, buf)) - { - return -1; - } - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->addData(data, len); - bcount += len; - } - return len; -} - -RsFileHash BinFileInterface::gethash() -{ - RsFileHash hashstr; - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->Complete(hashstr); - } - return hashstr; -} - -uint64_t BinFileInterface::bytecount() -{ - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - return bcount; - } - return 0; -} - -uint64_t BinFileInterface::getFileSize() -{ - return size; -} - - - -BinEncryptedFileInterface::BinEncryptedFileInterface(const char* fname, int flags) - : BinFileInterface(fname, flags), data(NULL), haveData(false), sizeData(0), cpyCount(0) -{ -} - -BinEncryptedFileInterface::~BinEncryptedFileInterface() -{ - if((sizeData > 0) && data != NULL) - { - free(data); - } - -} - -int BinEncryptedFileInterface::senddata(void* data, int len) -{ - - void* encrytedData = NULL; - int encDataLen = 0; - - // encrypt using own ssl public key - if(len > 0) - AuthSSL::getAuthSSL()->encrypt((void*&)encrytedData, encDataLen, data, len, AuthSSL::getAuthSSL()->OwnId()); - else - return -1; - - - if((encDataLen > 0) && (encrytedData != NULL)) - { - BinFileInterface::senddata((unsigned char *)encrytedData, encDataLen); - free(encrytedData); - } - else - { - return -1; - } - - return len; -} - - -int BinEncryptedFileInterface::readdata(void* data, int len) -{ - // to respect the inherited behavior of BinInterface - // the whole file is read and decryped and store to be read by subsequent calls - char* encryptedData = NULL; - int encrypDataLen = 0; - - - if(!haveData) // read whole data for first call, or first call after close() - { - - uint64_t encrypDataLen64 = BinFileInterface::getFileSize(); - - if(encrypDataLen64 > uint64_t(~(int)0)) - { - std::cerr << __PRETTY_FUNCTION__ << ": cannot decrypt files of size > " << ~(int)0 << std::endl; - return -1 ; - } - encrypDataLen = (int)encrypDataLen64 ; - encryptedData = new char[encrypDataLen]; - - // make sure assign was successful - if(encryptedData == NULL) - return -1; - - - if(-1 == BinFileInterface::readdata(encryptedData, encrypDataLen)) - { - delete[] encryptedData; - return -1; - } - - if((encrypDataLen > 0) && (encryptedData != NULL)) - { - int sizeDataInt = 0 ; - - if(!AuthSSL::getAuthSSL()->decrypt((void*&)(this->data), sizeDataInt, encryptedData, encrypDataLen)) - { - delete[] encryptedData; - return -1; - } - - sizeData = sizeDataInt ; - haveData = true; - delete[] encryptedData; - } - - - if((uint64_t)len <= sizeData) - { - memcpy(data, this->data, len); - cpyCount += len; - } - else - { - std::cerr << "BinEncryptedFileInterface::readData(): Error, Asking for more data than present" << std::endl; - return -1; - } - } - else - { - - if((cpyCount + len) <= (uint64_t)sizeData) - { - memcpy(data, (void *) ((this->data) + cpyCount), len); - cpyCount += len; - } - else - { - std::cerr << "BinEncryptedFileInterface::readData(): Error, Asking for more data than present" << std::endl; - return -1; - } - } - - return len; -} - -int BinEncryptedFileInterface::close() -{ - if(data != NULL) - { - free(data); - sizeData = 0; - haveData = false; - cpyCount = 0; - } - - return BinFileInterface::close(); -} - -uint64_t BinEncryptedFileInterface::bytecount() -{ - return cpyCount; -} - -bool BinEncryptedFileInterface::moretoread(uint32_t /* usec */) -{ - if(haveData) - return (cpyCount < (uint64_t)sizeData); - else - return cpyCount < (uint64_t)getFileSize(); -} - -BinMemInterface::BinMemInterface(int defsize, int flags) - :bin_flags(flags), buf(NULL), size(defsize), - recvsize(0), readloc(0), hash(NULL), bcount(0) - { - buf = rs_malloc(defsize); - - if(buf == NULL) - { - close() ; - return ; - } - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash = new pqihash(); - } - } - - -BinMemInterface::BinMemInterface(const void *data, const int defsize, int flags) - :bin_flags(flags), buf(NULL), size(defsize), - recvsize(0), readloc(0), hash(NULL), bcount(0) - { - buf = rs_malloc(defsize); - - if(buf == NULL) - { - close() ; - return ; - } - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash = new pqihash(); - } - - /* just remove the const - * *BAD* but senddata don't change it anyway - */ - senddata((void *) data, defsize); - } - -BinMemInterface::~BinMemInterface() -{ - if (buf) - free(buf); - - if (hash) - delete hash; - return; -} - -int BinMemInterface::close() -{ - if (buf) - { - free(buf); - buf = NULL; - } - size = 0; - recvsize = 0; - readloc = 0; - return 1; -} - - /* some fns to mess with the memory */ -int BinMemInterface::fseek(int loc) - { - if (loc <= recvsize) - { - readloc = loc; - return 1; - } - return 0; - } - - -int BinMemInterface::senddata(void *data, const int len) - { - if(recvsize + len > size) - { - /* resize? */ - return -1; - } - memcpy((char *) buf + recvsize, data, len); - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->addData(data, len); - bcount += len; - } - recvsize += len; - return len; - } - - -int BinMemInterface::readdata(void *data, int len) - { - if(readloc + len > recvsize) - { - /* no more stuff? */ - return -1; - } - memcpy(data, (char *) buf + readloc, len); - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->addData(data, len); - bcount += len; - } - readloc += len; - return len; - } - - - -RsFileHash BinMemInterface::gethash() - { - RsFileHash hashstr; - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - hash->Complete(hashstr); - } - return hashstr; - } - - -uint64_t BinMemInterface::bytecount() -{ - if (bin_flags & BIN_FLAGS_HASH_DATA) - { - return bcount; - } - return 0; -} - -bool BinMemInterface::writetofile(const char *fname) -{ - FILE *fd = RsDirUtil::rs_fopen(fname, "wb"); - if (!fd) - { - return false; - } - - if (1 != fwrite(buf, recvsize, 1, fd)) - { - fclose(fd); - return false; - } - - fclose(fd); - - return true; -} - -bool BinMemInterface::readfromfile(const char *fname) -{ - FILE *fd = RsDirUtil::rs_fopen(fname, "rb"); - if (!fd) - { - return false; - } - - /* get size */ - ::fseek(fd, 0L, SEEK_END); - int fsize = ftell(fd); - - if (fsize > size) - { - /* not enough room */ - std::cerr << "BinMemInterface::readfromfile() not enough room"; - std::cerr << std::endl; - - fclose(fd); - return false; - } - - ::fseek(fd, 0L, SEEK_SET); - if (1 != fread(buf, fsize, 1, fd)) - { - /* not enough room */ - std::cerr << "BinMemInterface::readfromfile() failed fread"; - std::cerr << std::endl; - - fclose(fd); - return false; - } - - recvsize = fsize; - readloc = 0; - fclose(fd); - - return true; -} - - -/**************************************************************************/ - - -void printNetBinID(std::ostream &out, const RsPeerId& id, uint32_t t) -{ - out << "NetBinId(" << id << ","; - if (t == PQI_CONNECT_TCP) - { - out << "TCP)"; - } - else if (t & (PQI_CONNECT_HIDDEN_TOR_TCP | PQI_CONNECT_HIDDEN_I2P_TCP)) - { - out << "HTCP"; - } - else - { - out << "UDP)"; - } -} - - -/************************** NetBinDummy ****************************** - * A test framework, - * - */ - -#include "pqi/pqiperson.h" - -const uint32_t DEFAULT_DUMMY_DELTA = 5; - -NetBinDummy::NetBinDummy(PQInterface *parent, const RsPeerId& id, uint32_t t) - :NetBinInterface(parent, id), type(t), dummyConnected(false), toConnect(false), connectDelta(DEFAULT_DUMMY_DELTA) -{ - return; -} - - // Net Interface -int NetBinDummy::connect(const struct sockaddr_storage &raddr) -{ - std::cerr << "NetBinDummy::connect("; - std::cerr << sockaddr_storage_tostring(raddr); - std::cerr << ") "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - std::cerr << "NetBinDummy::dummyConnect = true!"; - std::cerr << std::endl; - - if (type == PQI_CONNECT_TCP) - { - std::cerr << "NetBinDummy:: Not connecting TCP"; - std::cerr << std::endl; - if (parent()) - { - //struct sockaddr_storage addr = raddr; - parent()->notifyEvent(this, CONNECT_FAILED, raddr); - } - } - else if (!dummyConnected) - { - toConnect = true; - connectTS = time(NULL) + connectDelta; - std::cerr << "NetBinDummy::toConnect = true, connect in: "; - std::cerr << connectDelta << " secs"; - std::cerr << std::endl; - } - else - { - std::cerr << "NetBinDummy:: Already Connected!"; - std::cerr << std::endl; - } - - return 1; -} - -int NetBinDummy::listen() -{ - std::cerr << "NetBinDummy::connect() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return 1; -} - -int NetBinDummy::stoplistening() -{ - std::cerr << "NetBinDummy::stoplistening() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return 1; -} - -int NetBinDummy::disconnect() -{ - std::cerr << "NetBinDummy::disconnect() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - std::cerr << "NetBinDummy::dummyConnect = false!"; - std::cerr << std::endl; - dummyConnected = false; - - if (parent()) - { - struct sockaddr_storage addr; - sockaddr_storage_clear(addr); - - parent()->notifyEvent(this, CONNECT_FAILED, addr); - } - - return 1; -} - -int NetBinDummy::reset() -{ - std::cerr << "NetBinDummy::reset() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - disconnect(); - - return 1; -} - - - // Bin Interface. -int NetBinDummy::tick() -{ - - if (toConnect) - { - if (connectTS < time(NULL)) - { - std::cerr << "NetBinDummy::tick() dummyConnected = true "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - dummyConnected = true; - toConnect = false; - if (parent()) - { - struct sockaddr_storage addr; - sockaddr_storage_clear(addr); - - parent()->notifyEvent(this, CONNECT_SUCCESS, addr); - } - } - else - { - std::cerr << "NetBinDummy::tick() toConnect "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - } - } - return 0; -} - -int NetBinDummy::senddata(void */*data*/, int len) -{ - std::cerr << "NetBinDummy::senddata() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - if (dummyConnected) - return len; - return 0; -} - -int NetBinDummy::readdata(void */*data*/, int /*len*/) -{ - std::cerr << "NetBinDummy::readdata() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return 0; -} - -int NetBinDummy::netstatus() -{ - std::cerr << "NetBinDummy::netstatus() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return 1; -} - -int NetBinDummy::isactive() -{ - std::cerr << "NetBinDummy::isactive() "; - printNetBinID(std::cerr, PeerId(), type); - if (dummyConnected) - std::cerr << " true "; - else - std::cerr << " false "; - std::cerr << std::endl; - - return dummyConnected; -} - -bool NetBinDummy::moretoread(uint32_t /* usec */) -{ - std::cerr << "NetBinDummy::moretoread() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return false; -} - -bool NetBinDummy::cansend(uint32_t /* usec */) -{ - std::cerr << "NetBinDummy::cansend() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return dummyConnected; -} - -int NetBinDummy::close() -{ - std::cerr << "NetBinDummy::close() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return 1; -} - -RsFileHash NetBinDummy::gethash() -{ - std::cerr << "NetBinDummy::gethash() "; - printNetBinID(std::cerr, PeerId(), type); - std::cerr << std::endl; - - return RsFileHash(); -} - diff --git a/libretroshare/src/pqi/pqibin.h b/libretroshare/src/pqi/pqibin.h deleted file mode 100644 index 59a79622d..000000000 --- a/libretroshare/src/pqi/pqibin.h +++ /dev/null @@ -1,236 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqibin.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_BIN_INTERFACE_HEADER -#define PQI_BIN_INTERFACE_HEADER - - -#include "pqi/pqi_base.h" -#include "pqi/pqihash.h" -#include "util/rstime.h" - -#include - - -//! handles writing to binary files -/*! - * This allows for handling of binary file within Rs, In particular writing - * binary data to file declared in constructor - */ -class BinFileInterface: public BinInterface -{ -public: - BinFileInterface(const char *fname, int flags); -virtual ~BinFileInterface(); - -virtual int tick() { return 1; } - -virtual int senddata(void *data, int len); -virtual int readdata(void *data, int len); -virtual int netstatus() { return 1;} -virtual int isactive() { return (buf != NULL);} -virtual bool moretoread(uint32_t /* usec */ ) - { - if ((buf) && (bin_flags & BIN_FLAGS_READABLE)) - { - if ((size - ftell(buf)) > 0) - { - return true; - } - } - return false; - } - -virtual int close(); -virtual bool cansend(uint32_t /* usec */) - { - return (bin_flags & BIN_FLAGS_WRITEABLE); - } -virtual bool bandwidthLimited() { return false; } - -//! if HASHing is switched on -virtual RsFileHash gethash(); -virtual uint64_t bytecount(); - - virtual uint64_t getFileSize(); - -private: - int bin_flags; - FILE *buf; - uint64_t size; - pqihash *hash; - uint64_t bcount; -}; - -/*! - * use this for writing encrypted data to file using user's (ownid) ssl key - * hash for encrypted data is calculated, not the unencrypted data - */ -class BinEncryptedFileInterface : public BinFileInterface -{ -public: - - BinEncryptedFileInterface(const char *fname, int flags); - virtual ~BinEncryptedFileInterface(); - - /*! - * pls note if hashing is on, it is the hash of the encrypted data that is calculated - * also note, sif data is sent more than once, in a single instance of this object, then you will need to store the - * encrypted file size for each send externally as they are encrypted with different random keys. - * @param data data to be sent - * @param len length of data in bytes - * @return -1 if failed to write data, if not number bytes sent to file is returned - */ - int senddata(void *data, int len); - - /*! - * uses the hash of the encrypted data - * @param location to place data - * @param the length of data to be read - * @return -1 if failed to write data, if not number of bytes read is returned - */ - int readdata(void *data, int len); - - /*! - * this releases resources held by an instance - */ - int close(); - - uint64_t bytecount(); - bool moretoread(uint32_t usec); - -private: - - char* data; - bool haveData; - uint64_t sizeData; - uint64_t cpyCount; - -}; - -//! handles writing to reading/writing to memory -/*! - * This provide a memory interface for storing/retrieving information in memory - * to be read/sent elsewhere - */ -class BinMemInterface: public BinInterface -{ -public: - BinMemInterface(int defsize, int flags); - BinMemInterface(const void *data, const int size, int flags); -virtual ~BinMemInterface(); - - /* Extra Interfaces */ -int fseek(int loc); -int memsize() { return recvsize; } -void *memptr() { return buf; } - - /* file interface */ -bool writetofile(const char *fname); -bool readfromfile(const char *fname); - -virtual int tick() { return 1; } - -virtual int senddata(void *data, int len); -virtual int readdata(void *data, int len); -virtual int netstatus() { return 1; } -virtual int isactive() { return 1; } -virtual bool moretoread(uint32_t /* usec */) - { - if ((buf) && (bin_flags & BIN_FLAGS_READABLE )) - { - if (readloc < recvsize) - { - return true; - } - } - return false; - } - -virtual int close(); -virtual bool cansend(uint32_t /* usec */) - { - return (bin_flags & BIN_FLAGS_WRITEABLE); - } -virtual bool bandwidthLimited() { return false; } - -virtual RsFileHash gethash(); -virtual uint64_t bytecount(); - - private: - int bin_flags; - void *buf; - int size; - int recvsize; - int readloc; - pqihash *hash; - uint64_t bcount; -}; - - -class NetBinDummy: public NetBinInterface -{ -public: - NetBinDummy(PQInterface *parent, const RsPeerId& id, uint32_t t); -virtual ~NetBinDummy() { return; } - - // Net Interface -virtual int connect(const struct sockaddr_storage &raddr); -virtual int listen(); -virtual int stoplistening(); -virtual int disconnect(); -virtual int reset(); -virtual bool connect_parameter(uint32_t type, uint32_t value) - { - (void) type; /* suppress unused parameter warning */ - (void) value; /* suppress unused parameter warning */ - return false; - } -virtual int getConnectAddress(struct sockaddr_storage &raddr) - { - (void) raddr; /* suppress unused parameter warning */ - return 0; - } - - // Bin Interface. -virtual int tick(); - -virtual int senddata(void *data, int len); -virtual int readdata(void *data, int len); -virtual int netstatus(); -virtual int isactive(); -virtual bool moretoread(uint32_t usec); -virtual bool cansend(uint32_t usec); -virtual int close(); - -virtual RsFileHash gethash(); - - private: - uint32_t type; - bool dummyConnected; - bool toConnect; - uint32_t connectDelta; - rstime_t connectTS; -}; - - -#endif // PQI_BINARY_INTERFACES_HEADER - diff --git a/libretroshare/src/pqi/pqihandler.cc b/libretroshare/src/pqi/pqihandler.cc deleted file mode 100644 index 1864354a0..000000000 --- a/libretroshare/src/pqi/pqihandler.cc +++ /dev/null @@ -1,510 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqihandler.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqihandler.h" - -#include // for NULL -#include "util/rstime.h" // for time, rstime_t -#include // for sort -#include // for dec -#include // for string, char_traits, operator+, bas... -#include // for pair - -#include "pqi/pqi_base.h" // for PQInterface, RsBwRates -#include "retroshare/rsconfig.h" // for RSTrafficClue -#include "retroshare/rsids.h" // for t_RsGenericIdType -#include "retroshare/rspeers.h" // for RsPeers, rsPeers -#include "serialiser/rsserial.h" // for RsItem, RsRawItem -#include "util/rsdebug.h" // for pqioutput, PQL_DEBUG_BASIC, PQL_ALERT -#include "util/rsstring.h" // for rs_sprintf_append - -using std::dec; - -#ifdef WINDOWS_SYS -#include -#endif - -struct RsLog::logInfo pqihandlerzoneInfo = {RsLog::Default, "pqihandler"}; -#define pqihandlerzone &pqihandlerzoneInfo - -//static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ; -//static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ; - -//#define UPDATE_RATES_DEBUG 1 -// #define DEBUG_TICK 1 -// #define RSITEM_DEBUG 1 - -pqihandler::pqihandler() : coreMtx("pqihandler") -{ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - // setup minimal total+individual rates. - rateIndiv_out = 0.01; - rateIndiv_in = 0.01; - rateMax_out = 0.01; - rateMax_in = 0.01; - rateTotal_in = 0.0 ; - rateTotal_out = 0.0 ; - traffInSum = 0; - traffOutSum = 0; - last_m = time(NULL) ; - nb_ticks = 0 ; - mLastRateCapUpdate = 0 ; - ticks_per_sec = 5 ; // initial guess - return; -} - -int pqihandler::tick() -{ - int moreToTick = 0; - - { - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - // tick all interfaces... - std::map::iterator it; - for(it = mods.begin(); it != mods.end(); ++it) - { - if (0 < ((it -> second) -> pqi) -> tick()) - { -#ifdef DEBUG_TICK - std::cerr << "pqihandler::tick() moreToTick from mod()" << std::endl; -#endif - moreToTick = 1; - } - } -#ifdef TO_BE_REMOVED - // get the items, and queue them correctly - if (0 < locked_GetItems()) - { -#ifdef DEBUG_TICK - std::cerr << "pqihandler::tick() moreToTick from GetItems()" << std::endl; -#endif - moreToTick = 1; - } -#endif - } - - rstime_t now = time(NULL) ; - - if(now > mLastRateCapUpdate + 5) - { - std::map rateMap; - std::map::iterator it; - - - // every 5 secs, update the max rates for all modules - - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - for(std::map::iterator it = mods.begin(); it != mods.end(); ++it) - { - // This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates - // need to be updated from inside. - uint32_t maxUp = 0,maxDn =0 ; - if (rsPeers->getPeerMaximumRates(it->first,maxUp,maxDn) ) - it->second->pqi->setRateCap(maxDn,maxUp);// mind the order! Dn first, than Up. - } - - mLastRateCapUpdate = now ; - } - - UpdateRates(); - return moreToTick; -} - - -bool pqihandler::queueOutRsItem(RsItem *item) -{ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - uint32_t size ; - locked_HandleRsItem(item, size); - -#ifdef DEBUG_QOS - if(item->priority_level() == QOS_PRIORITY_UNKNOWN) - std::cerr << "Caught an unprioritized item !" << std::endl; - - print() ; -#endif - return true ; -} - -int pqihandler::status() -{ - std::map::iterator it; - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - { // for output - std::string out = "pqihandler::status() Active Modules:\n"; - - // display all interfaces... - for(it = mods.begin(); it != mods.end(); ++it) - { - rs_sprintf_append(out, "\tModule [%s] Pointer <%p>", it -> first.toStdString().c_str(), (void *) ((it -> second) -> pqi)); - } - - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out); - - } // end of output. - - - // status all interfaces... - for(it = mods.begin(); it != mods.end(); ++it) - { - ((it -> second) -> pqi) -> status(); - } - return 1; -} - -bool pqihandler::AddSearchModule(SearchModule *mod) -{ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - // if peerid used -> error. - //std::map::iterator it; - if (mod->peerid != mod->pqi->PeerId()) - { - // ERROR! - pqioutput(PQL_ALERT, pqihandlerzone, "ERROR peerid != PeerId!"); - return false; - } - - if (mod->peerid.isNull()) - { - // ERROR! - pqioutput(PQL_ALERT, pqihandlerzone, "ERROR peerid == NULL"); - return false; - } - - if (mods.find(mod->peerid) != mods.end()) - { - // ERROR! - pqioutput(PQL_ALERT, pqihandlerzone, "ERROR PeerId Module already exists!"); - return false; - } - - // store. - mods[mod->peerid] = mod; - return true; -} - -bool pqihandler::RemoveSearchModule(SearchModule *mod) -{ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - std::map::iterator it; - for(it = mods.begin(); it != mods.end(); ++it) - { - if (mod == it -> second) - { - mods.erase(it); - return true; - } - } - return false; -} - -// generalised output -int pqihandler::locked_HandleRsItem(RsItem *item, uint32_t& computed_size) -{ - computed_size = 0 ; - std::map::iterator it; - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, - "pqihandler::HandleRsItem()"); - - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, - "pqihandler::HandleRsItem() Sending to One Channel"); -#ifdef DEBUG_TICK - std::cerr << "pqihandler::HandleRsItem() Sending to One Channel" << std::endl; -#endif - - - // find module. - if ((it = mods.find(item->PeerId())) == mods.end()) - { - std::string out = "pqihandler::HandleRsItem() Invalid chan!"; - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out); -#ifdef DEBUG_TICK - std::cerr << out << std::endl; -#endif - - delete item; - return -1; - } - - std::string out = "pqihandler::HandleRsItem() sending to chan: " + it -> first.toStdString(); - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out); -#ifdef DEBUG_TICK - std::cerr << out << std::endl; -#endif - - // if yes send on item. - ((it -> second) -> pqi) -> SendItem(item,computed_size); - return 1; -} - -int pqihandler::SendRsRawItem(RsRawItem *ns) -{ - pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "pqihandler::SendRsRawItem()"); - - // directly send item to streamers - - return queueOutRsItem(ns) ; -} - -int pqihandler::ExtractTrafficInfo(std::list& out_lst,std::list& in_lst) -{ - in_lst.clear() ; - out_lst.clear() ; - - for( std::map::iterator it = mods.begin(); it != mods.end(); ++it) - { - std::list ilst,olst ; - - (it -> second)->pqi->gatherStatistics(olst,ilst) ; - - for(std::list::const_iterator it(ilst.begin());it!=ilst.end();++it) in_lst.push_back(*it) ; - for(std::list::const_iterator it(olst.begin());it!=olst.end();++it) out_lst.push_back(*it) ; - } - - return 1 ; -} - -// NEW extern fn to extract rates. -int pqihandler::ExtractRates(std::map &ratemap, RsBwRates &total) -{ - total.mMaxRateIn = getMaxRate(true); - total.mMaxRateOut = getMaxRate(false); - total.mRateIn = 0; - total.mRateOut = 0; - total.mQueueIn = 0; - total.mQueueOut = 0; - - /* Lock once rates have been retrieved */ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - std::map::iterator it; - for(it = mods.begin(); it != mods.end(); ++it) - { - SearchModule *mod = (it -> second); - - RsBwRates peerRates; - mod -> pqi -> getRates(peerRates); - - total.mRateIn += peerRates.mRateIn; - total.mRateOut += peerRates.mRateOut; - total.mQueueIn += peerRates.mQueueIn; - total.mQueueOut += peerRates.mQueueOut; - - ratemap[it->first] = peerRates; - - } - - return 1; -} - - - -// internal fn to send updates -int pqihandler::UpdateRates() -{ - std::map::iterator it; - - float avail_in = getMaxRate(true); - float avail_out = getMaxRate(false); - - float used_bw_in = 0; - float used_bw_out = 0; - - /* Lock once rates have been retrieved */ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - int num_sm = mods.size(); - float used_bw_in_table[num_sm]; /* table of in bandwidth currently used by each module */ - float used_bw_out_table[num_sm]; /* table of out bandwidth currently used by each module */ - - // loop through modules to get the used bandwidth -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates Looping through modules" << std::endl; -#endif - - int index = 0; - - for(it = mods.begin(); it != mods.end(); ++it) - { - SearchModule *mod = (it -> second); - - traffInSum += mod -> pqi -> getTraffic(true); - traffOutSum += mod -> pqi -> getTraffic(false); - - float crate_in = mod -> pqi -> getRate(true); - float crate_out = mod -> pqi -> getRate(false); - - used_bw_in += crate_in; - used_bw_out += crate_out; - - /* fill the table of used bandwidths */ - used_bw_in_table[index] = crate_in; - used_bw_out_table[index] = crate_out; - - ++index; - } - -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates Sorting used_bw_out_table: " << num_sm << " entries" << std::endl; -#endif - - /* Sort the used bw in/out table in ascending order */ - std::sort(used_bw_in_table, used_bw_in_table + num_sm); - std::sort(used_bw_out_table, used_bw_out_table + num_sm); - -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates used_bw_out " << used_bw_out << std::endl; -#endif - - /* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */ - - float out_remaining_bw = avail_out; - float out_max_bw = 0; - bool keep_going = true; - int mod_index = 0; - - while (keep_going && (mod_index < num_sm)) { - float result = (num_sm - mod_index) * (used_bw_out_table[mod_index] - out_max_bw); - if (result > out_remaining_bw) { - /* There is not enough remaining out bw to satisfy all modules, - distribute the remaining out bw among modules, then exit */ - out_max_bw += out_remaining_bw / (num_sm - mod_index); - out_remaining_bw = 0; - keep_going = false; - } else { - /* Grant the requested out bandwidth to all modules, - then recalculate the remaining out bandwidth */ - out_remaining_bw -= result; - out_max_bw = used_bw_out_table[mod_index]; - ++mod_index; - } - } - -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates mod_index " << mod_index << " out_max_bw " << out_max_bw << " remaining out bw " << out_remaining_bw << std::endl; -#endif - - /* Allocate only 50 pct the remaining out bw, if any, to make the transition more smooth */ - out_max_bw = out_max_bw + 0.5 * out_remaining_bw; - - /* Calculate the optimal in_max value, taking into account avail_in and the in bw requested by modules */ - - float in_remaining_bw = avail_in; - float in_max_bw = 0; - keep_going = true; - mod_index = 0; - - while (keep_going && mod_index < num_sm) { - float result = (num_sm - mod_index) * (used_bw_in_table[mod_index] - in_max_bw); - if (result > in_remaining_bw) { - /* There is not enough remaining in bw to satisfy all modules, - distribute the remaining in bw among modules, then exit */ - in_max_bw += in_remaining_bw / (num_sm - mod_index); - in_remaining_bw = 0; - keep_going = false; - } else { - /* Grant the requested in bandwidth to all modules, - then recalculate the remaining in bandwidth */ - in_remaining_bw -= result; - in_max_bw = used_bw_in_table[mod_index]; - ++mod_index; - } - } - -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates mod_index " << mod_index << " in_max_bw " << in_max_bw << " remaining in bw " << in_remaining_bw << std::endl; -#endif - - // allocate only 75 pct of the remaining in bw, to make the transition more smooth - in_max_bw = in_max_bw + 0.75 * in_remaining_bw; - - // store current total in and out used bw - locked_StoreCurrentRates(used_bw_in, used_bw_out); - -#ifdef UPDATE_RATES_DEBUG - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates setting new out_max " << out_max_bw << " in_max " << in_max_bw << std::endl; -#endif - - // retrieve the bandwidth limits provided by peers via BwCtrl - std::map rateMap; - rsConfig->getAllBandwidthRates(rateMap); - std::map::iterator rateMap_it; - -#ifdef UPDATE_RATES_DEBUG - // dump RsConfigurationDataRates - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates RsConfigDataRates dump" << std::endl; - for (rateMap_it = rateMap.begin(); rateMap_it != rateMap.end(); rateMap_it++) - RsDbg () << "UPDATE_RATES pqihandler::UpdateRates PeerId " << rateMap_it->first.toStdString() << " mAllowedOut " << rateMap_it->second.mAllowedOut << std::endl; -#endif - - // update max rates - for(it = mods.begin(); it != mods.end(); ++it) - { - SearchModule *mod = (it -> second); - - // for our down bandwidth we use the calculated value without taking into account the max up provided by peers via BwCtrl - // this is harmless as they will control their up bw on their side - mod -> pqi -> setMaxRate(true, in_max_bw); - - // for our up bandwidth we take into account the max down provided by peers via BwCtrl - // because we don't want to clog our outqueues, the TCP buffers, and the peers inbound queues - mod -> pqi -> setMaxRate(false, out_max_bw); - if ((rateMap_it = rateMap.find(mod->pqi->PeerId())) != rateMap.end()) - if (rateMap_it->second.mAllowedOut > 0) - if (out_max_bw > rateMap_it->second.mAllowedOut) - mod -> pqi -> setMaxRate(false, rateMap_it->second.mAllowedOut); - } - -#ifdef UPDATE_RATES_DEBUG - // dump maxRates - for(it = mods.begin(); it != mods.end(); ++it) - { - SearchModule *mod = (it -> second); - RsDbg() << "UPDATE_RATES pqihandler::UpdateRates PeerID " << (mod ->pqi -> PeerId()).toStdString() << " new bandwidth limits up " << mod -> pqi -> getMaxRate(false) << " down " << mod -> pqi -> getMaxRate(true) << std::endl; - } -#endif - - return 1; -} - -void pqihandler::getCurrentRates(float &in, float &out) -{ - RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/ - - in = rateTotal_in; - out = rateTotal_out; -} - -void pqihandler::locked_StoreCurrentRates(float in, float out) -{ - rateTotal_in = in; - rateTotal_out = out; -} - -void pqihandler::GetTraffic(uint64_t &in, uint64_t &out) -{ - in = traffInSum; - out = traffOutSum; -} diff --git a/libretroshare/src/pqi/pqihandler.h b/libretroshare/src/pqi/pqihandler.h deleted file mode 100644 index 4bfd4f828..000000000 --- a/libretroshare/src/pqi/pqihandler.h +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqihandler.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_HANDLER_HEADER -#define MRK_PQI_HANDLER_HEADER - -#include // for uint32_t -#include "util/rstime.h" // for rstime_t, NULL -#include // for list -#include // for map - -#include "pqi/pqi.h" // for P3Interface, pqiPublisher -#include "retroshare/rstypes.h" // for RsPeerId -#include "util/rsthreads.h" // for RsStackMutex, RsMutex - -class PQInterface; -struct RSTrafficClue; -class RsBwRates; -struct RsItem; -class RsRawItem; - -class SearchModule -{ - public: - SearchModule() : pqi(NULL) {} - - RsPeerId peerid ; - PQInterface *pqi; -}; - -// Presents a P3 Face to the world! -// and funnels data through to a PQInterface. -// -class pqihandler: public P3Interface, public pqiPublisher -{ - public: - pqihandler(); - - /**** Overloaded from pqiPublisher ****/ - virtual bool sendItem(RsRawItem *item) - { - return SendRsRawItem(item); - } - - bool AddSearchModule(SearchModule *mod); - bool RemoveSearchModule(SearchModule *mod); - - // Rest of P3Interface - virtual int tick(); - virtual int status(); - - // Service Data Interface - virtual int SendRsRawItem(RsRawItem *); -#ifdef TO_BE_REMOVED - virtual RsRawItem *GetRsRawItem(); -#endif - - // rate control. - //void setMaxRate(const RsPeerId& pid,bool in, uint32_t val_kBs); - void setMaxRate(bool in, float val); - float getMaxRate(bool in); - - void setMaxRates(const RsPeerId& pid,bool in,float val) ; - float getMaxRates(const RsPeerId& pid,bool in) ; - - void getCurrentRates(float &in, float &out); - - // TESTING INTERFACE. - int ExtractRates(std::map &ratemap, RsBwRates &totals); - int ExtractTrafficInfo(std::list &out_lst, std::list &in_lst); - - uint64_t traffInSum; - uint64_t traffOutSum; - void GetTraffic(uint64_t &in, uint64_t &out); - -protected: - /* check to be overloaded by those that can - * generates warnings otherwise - */ - - int locked_HandleRsItem(RsItem *ns, uint32_t& size); - bool queueOutRsItem(RsItem *) ; - -#ifdef TO_BE_REMOVED - int locked_GetItems(); - void locked_SortnStoreItem(RsItem *item); -#endif - - RsMutex coreMtx; /* MUTEX */ - - std::map mods; - - std::list in_service; - - private: - - // rate control. - int UpdateRates(); - void locked_StoreCurrentRates(float in, float out); - - float rateIndiv_in; - float rateIndiv_out; - float rateMax_in; - float rateMax_out; - - float rateTotal_in; - float rateTotal_out; - - uint32_t nb_ticks ; - rstime_t last_m ; - rstime_t mLastRateCapUpdate ; - float ticks_per_sec ; -}; - -inline void pqihandler::setMaxRate(bool in, float val) -{ - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - if (in) - rateMax_in = val; - else - rateMax_out = val; - return; -} - -inline float pqihandler::getMaxRate(bool in) -{ - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - if (in) - return rateMax_in; - else - return rateMax_out; -} - -#endif // MRK_PQI_HANDLER_HEADER diff --git a/libretroshare/src/pqi/pqihash.h b/libretroshare/src/pqi/pqihash.h deleted file mode 100644 index 9a36cb89c..000000000 --- a/libretroshare/src/pqi/pqihash.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqihash.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_HASH_ -#define PQI_HASH_ - -#include -#include -#include -#include -#include -#include "util/rsstring.h" -#include "retroshare/rstypes.h" -#include - -class pqihash -{ - public: - pqihash() -{ - - sha_hash = new uint8_t[SHA_DIGEST_LENGTH]; - memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ; - sha_ctx = new SHA_CTX; - SHA1_Init(sha_ctx); - doHash = true; -} - - ~pqihash() -{ - delete[] sha_hash; - delete sha_ctx; -} - - -void addData(const void *data, uint32_t len) -{ - if (doHash) - { - SHA1_Update(sha_ctx, data, len); - } -} - -void Complete(RsFileHash &hash) -{ - if (!doHash) - { - hash = endHash; - return; - } - - SHA1_Final(sha_hash, sha_ctx); - - endHash.clear(); - endHash = hash = Sha1CheckSum(sha_hash); - -// for(int i = 0; i < SHA_DIGEST_LENGTH; i++) -// { -// rs_sprintf_append(endHash, "%02x", (unsigned int) (sha_hash[i])); -// } -// hash = endHash; - doHash = false; - - return; -} - - private: - - bool doHash; - RsFileHash endHash; - uint8_t *sha_hash; - SHA_CTX *sha_ctx; -}; - -#endif diff --git a/libretroshare/src/pqi/pqiindic.h b/libretroshare/src/pqi/pqiindic.h deleted file mode 100644 index 28f619b16..000000000 --- a/libretroshare/src/pqi/pqiindic.h +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiindic.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_INDICATOR_HEADER -#define MRK_PQI_INDICATOR_HEADER - -#include - -// This will indicate to num different sources -// when the event has occured. - -class Indicator -{ - public: - explicit Indicator(uint16_t n = 1) - :num(n), changeFlags(n) {IndicateChanged();} -void IndicateChanged() - { - for(uint16_t i = 0; i < num; i++) - changeFlags[i]=true; - } - -bool Changed(uint16_t idx = 0) - { - /* catch overflow */ - if (idx > num - 1) - return false; - - bool ans = changeFlags[idx]; - changeFlags[idx] = false; - return ans; - } - - private: - uint16_t num; - std::vector changeFlags; -}; - - - -#endif diff --git a/libretroshare/src/pqi/pqiipset.cc b/libretroshare/src/pqi/pqiipset.cc deleted file mode 100644 index 6c273b47c..000000000 --- a/libretroshare/src/pqi/pqiipset.cc +++ /dev/null @@ -1,264 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiipset.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstime.h" -#include "pqi/pqiipset.h" -#include "util/rsstring.h" - -bool pqiIpAddress::sameAddress(const pqiIpAddress &a) const -{ - return sockaddr_storage_same(mAddr, a.mAddr); -} - - -bool pqiIpAddress::validAddress() const -{ - /* filter for unlikely addresses */ - if(sockaddr_storage_isLoopbackNet(mAddr)) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddress::validAddress() ip parameter is loopback: disgarding." << std::endl ; -#endif - return false; - } - - if(sockaddr_storage_isnull(mAddr)) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddress::validAddress() ip parameter is 0.0.0.0/1, or port is 0, ignoring." << std::endl; -#endif - return false; - } - - return true; - -} - - -bool pqiIpAddrList::updateIpAddressList(const pqiIpAddress &addr) -{ - std::list::iterator it; - bool add = false; - bool newAddr = true; - -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList()"; - std::cerr << std::endl; -#endif - - if (mAddrs.size() < MAX_ADDRESS_LIST_SIZE) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() small list: Add"; - std::cerr << std::endl; -#endif - add = true; - } - else if (mAddrs.back().mSeenTime < addr.mSeenTime) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() oldAddr: Add"; - std::cerr << std::endl; -#endif - add = true; - } - - if ((!add) || (!addr.validAddress())) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() not Add or !valid.. fail"; - std::cerr << std::endl; -#endif - return false; - } - - for(it = mAddrs.begin(); it != mAddrs.end(); ++it) - { - if (it->sameAddress(addr)) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() found duplicate"; - std::cerr << std::endl; -#endif - if (it->mSeenTime > addr.mSeenTime) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() orig better, returning"; - std::cerr << std::endl; -#endif - /* already better -> quit */ - return false; - } - -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() deleting orig"; - std::cerr << std::endl; -#endif - it = mAddrs.erase(it); - newAddr = false; - break; - } - } - - // ordered by decreaseing time. (newest at front) - bool added = false; - for(it = mAddrs.begin(); it != mAddrs.end(); ++it) - { - if (it->mSeenTime < addr.mSeenTime) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() added orig SeenTime: " << it->mSeenTime << " new SeenTime: " << addr.mSeenTime; - std::cerr << std::endl; -#endif - - added = true; - mAddrs.insert(it, addr); - break; - } - } - if (!added) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() pushing to back"; - std::cerr << std::endl; -#endif - mAddrs.push_back(addr); - } - - /* pop if necessary */ - while (mAddrs.size() > MAX_ADDRESS_LIST_SIZE) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrList::updateIpAddressList() popping back"; - std::cerr << std::endl; -#endif - mAddrs.pop_back(); - } - - return newAddr; -} - -void pqiIpAddrList::extractFromTlv(const RsTlvIpAddrSet &tlvAddrs) -{ - std::list::const_iterator it; - - //for(it = tlvAddrs.addrs.begin(); it != tlvAddrs.addrs.end() ; ++it) - for(it = tlvAddrs.mList.begin(); it != tlvAddrs.mList.end() ; ++it) - { - pqiIpAddress addr; - addr.mAddr = it->addr.addr; - addr.mSeenTime = it->seenTime; - addr.mSrc = it->source; - - mAddrs.push_back(addr); - } -} - -void pqiIpAddrList::loadTlv(RsTlvIpAddrSet &tlvAddrs) const -{ - std::list::const_iterator it; - - for(it = mAddrs.begin(); it != mAddrs.end() ; ++it) - { - RsTlvIpAddressInfo addr; - addr.addr.addr = it->mAddr; - addr.seenTime = it->mSeenTime; - addr.source = it->mSrc; - - //tlvAddrs.addrs.push_back(addr); - tlvAddrs.mList.push_back(addr); - } -} - - - -void pqiIpAddrList::printIpAddressList(std::string &out) const -{ - std::list::const_iterator it; - rstime_t now = time(NULL); - for(it = mAddrs.begin(); it != mAddrs.end(); ++it) - { - out += sockaddr_storage_tostring(it->mAddr); - rs_sprintf_append(out, "( %ld old)\n", now - it->mSeenTime); - } - return; -} - - -bool pqiIpAddrSet::updateLocalAddrs(const pqiIpAddress &addr) -{ - return mLocal.updateIpAddressList(addr); -} - -bool pqiIpAddrSet::updateExtAddrs(const pqiIpAddress &addr) -{ - return mExt.updateIpAddressList(addr); -} - -bool pqiIpAddrSet::updateAddrs(const pqiIpAddrSet &addrs) -{ -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrSet::updateAddrs()"; - std::cerr << std::endl; -#endif - - bool newAddrs = false; - std::list::const_iterator it; - for(it = addrs.mLocal.mAddrs.begin(); it != addrs.mLocal.mAddrs.end(); ++it) - { - if (mLocal.updateIpAddressList(*it)) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrSet::updateAddrs() Updated Local Addr"; - std::cerr << std::endl; -#endif - newAddrs = true; - } - } - - for(it = addrs.mExt.mAddrs.begin(); it != addrs.mExt.mAddrs.end(); ++it) - { - if (mExt.updateIpAddressList(*it)) - { -#ifdef IPADDR_DEBUG - std::cerr << "pqiIpAddrSet::updateAddrs() Updated Ext Addr"; - std::cerr << std::endl; -#endif - newAddrs = true; - } - } - return newAddrs; -} - - - -void pqiIpAddrSet::printAddrs(std::string &out) const -{ - out += "Local Addresses: "; - mLocal.printIpAddressList(out); - out += "\nExt Addresses: "; - mExt.printIpAddressList(out); - out += "\n"; -} - - - - diff --git a/libretroshare/src/pqi/pqiipset.h b/libretroshare/src/pqi/pqiipset.h deleted file mode 100644 index 9f6c31b17..000000000 --- a/libretroshare/src/pqi/pqiipset.h +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiipset.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_IP_SET_H -#define PQI_IP_SET_H - -#include "util/rsnet.h" -#include "serialiser/rstlvaddrs.h" -#include "util/rstime.h" - -#define MAX_ADDRESS_LIST_SIZE 10 - -class pqiIpAddress -{ - public: - bool sameAddress(const pqiIpAddress &a) const; - bool validAddress() const; - - struct sockaddr_storage mAddr; - rstime_t mSeenTime; - uint32_t mSrc; -}; - - -class pqiIpAddrList -{ - public: - - // returns true if new address added. - bool updateIpAddressList(const pqiIpAddress &addr); - void printIpAddressList(std::string &out) const; - void extractFromTlv(const RsTlvIpAddrSet &tlvAddrs); - void loadTlv(RsTlvIpAddrSet &tlvAddrs) const; - - // sorted list... based on seen time. - std::list mAddrs; -}; - - -class pqiIpAddrSet -{ - public: - - bool updateLocalAddrs(const pqiIpAddress &addr); - bool updateExtAddrs(const pqiIpAddress &addr); - bool updateAddrs(const pqiIpAddrSet &addrs); - void printAddrs(std::string &out) const; - pqiIpAddrList mLocal; - pqiIpAddrList mExt; - - void clear() - { - mLocal.mAddrs.clear(); - mExt.mAddrs.clear(); - } -}; - - -#endif diff --git a/libretroshare/src/pqi/pqilistener.h b/libretroshare/src/pqi/pqilistener.h deleted file mode 100644 index 5f748dc8f..000000000 --- a/libretroshare/src/pqi/pqilistener.h +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqilistener.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_GENERIC_LISTEN_HEADER -#define MRK_PQI_GENERIC_LISTEN_HEADER - -// operating system specific network header. -#include "pqi/pqinetwork.h" - -class pqilistener -{ -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; } -}; - - -#endif // MRK_PQI_GENERIC_LISTEN_HEADER diff --git a/libretroshare/src/pqi/pqiloopback.cc b/libretroshare/src/pqi/pqiloopback.cc deleted file mode 100644 index 69e70488b..000000000 --- a/libretroshare/src/pqi/pqiloopback.cc +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiloopback.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqiloopback.h" - -#include // for NULL - -struct RsItem; - -/*** -#define LOOPBACK_DEBUG 1 -***/ - -pqiloopback::pqiloopback(const RsPeerId& id) - :PQInterface(id) -{ - setMaxRate(true, 0); - setMaxRate(false, 0); - setRate(true, 0); - setRate(false, 0); - - return; -} - -pqiloopback::~pqiloopback() -{ - return; -} - -int pqiloopback::SendItem(RsItem *i) -{ - -#ifdef LOOPBACK_DEBUG - std::cerr << "pqiloopback::SendItem()"; - std::cerr << std::endl; - i->print(std::cerr); - std::cerr << std::endl; -#endif - objs.push_back(i); - return 1; -} - -RsItem * pqiloopback::GetItem() -{ - if (objs.size() > 0) - { - RsItem *pqi = objs.front(); - objs.pop_front(); -#ifdef LOOPBACK_DEBUG - std::cerr << "pqiloopback::GetItem()"; - std::cerr << std::endl; - pqi->print(std::cerr); - std::cerr << std::endl; -#endif - return pqi; - } - return NULL; -} - -// PQI interface. -int pqiloopback::tick() -{ - return 0; -} - -int pqiloopback::status() -{ - return 0; -} - - diff --git a/libretroshare/src/pqi/pqiloopback.h b/libretroshare/src/pqi/pqiloopback.h deleted file mode 100644 index f8d40e667..000000000 --- a/libretroshare/src/pqi/pqiloopback.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiloopback.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_LOOPBACK_HEADER -#define MRK_PQI_LOOPBACK_HEADER - -#include // for list - -#include "pqi/pqi_base.h" // for NetInterface (ptr only), PQInterface -#include "retroshare/rstypes.h" // for RsPeerId - -struct RsItem; - -class pqiloopback: public PQInterface -{ -public: - pqiloopback(const RsPeerId& id); -virtual ~pqiloopback(); - -// search Interface. -virtual int SendItem(RsItem *item); -virtual RsItem *GetItem(); - -// PQI interface. -virtual int tick(); -virtual int status(); - -private: - std::list objs; -}; - -#endif //MRK_PQI_LOOPBACK_HEADER diff --git a/libretroshare/src/pqi/pqimonitor.cc b/libretroshare/src/pqi/pqimonitor.cc deleted file mode 100644 index 550cd7b5a..000000000 --- a/libretroshare/src/pqi/pqimonitor.cc +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqimonitor.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqimonitor.h" -#include "pqi/pqinetwork.h" -#include "pqi/pqiipset.h" -#include "util/rsprint.h" - -/***** DUMMY Connect CB for testing *****/ - -#include - - -pqiConnectCbDummy::pqiConnectCbDummy() -{ - std::cerr << "pqiConnectCbDummy()" << std::endl; - return; -} - -pqiConnectCbDummy::~pqiConnectCbDummy() -{ - return; -} - -void pqiConnectCbDummy::peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, - uint32_t type, uint32_t mode, uint32_t source) -{ - std::cerr << "pqiConnectCbDummy::peerStatus()"; - std::cerr << " id: " << id; - std::cerr << " type: " << type; - std::cerr << " mode: " << mode; - std::cerr << " source: " << source; - std::cerr << std::endl; - - std::cerr << " addrs: "; - std::cerr << std::endl; - std::string out; - addrs.printAddrs(out); - std::cerr << out << std::endl; -} - -void pqiConnectCbDummy::peerConnectRequest(const RsPeerId &id, const sockaddr_storage &raddr - , const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr - , uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) -{ - std::cerr << "pqiConnectCbDummy::peerConnectRequest()"; - std::cerr << " id: " << id; - std::cerr << " raddr: " << sockaddr_storage_tostring(raddr); - std::cerr << " proxyaddr: " << sockaddr_storage_tostring(proxyaddr); - std::cerr << " srcaddr: " << sockaddr_storage_tostring(srcaddr); - std::cerr << " source: " << source; - std::cerr << " flags: " << flags; - std::cerr << " delay: " << delay; - std::cerr << " bandwidth: " << bandwidth; - std::cerr << std::endl; -} - -void pqiMonitor::disconnectPeer(const RsPeerId &/*peer*/) -{ - std::cerr << "(EE) pqiMonitor::disconnectPeer() shouldn't be called!!!"<< std::endl; -} - -#if 0 -void pqiConnectCbDummy::stunStatus(std::string id, const struct sockaddr_storage *raddr, - uint32_t type, uint32_t flags) -{ - std::cerr << "pqiConnectCbDummy::stunStatus()"; - std::cerr << " idhash: " << RsUtil::BinToHex(id) << " raddr: " << sockaddr_storage_tostring(raddr); - std::cerr << " type: " << type; - std::cerr << " flags: " << flags; - std::cerr << std::endl; -} -#endif - - diff --git a/libretroshare/src/pqi/pqimonitor.h b/libretroshare/src/pqi/pqimonitor.h deleted file mode 100644 index 34a858e66..000000000 --- a/libretroshare/src/pqi/pqimonitor.h +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqimonitor.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef PQI_MONITOR_H -#define PQI_MONITOR_H - -/**** Rough sketch of a Monitor class - * expect it to change significantly - * - */ - -#include -#include -#include -#include "pqi/pqiipset.h" -#include "retroshare/rstypes.h" - -/************** Define Type/Mode/Source ***************/ - - -/* STATE MASK */ -const uint32_t RS_PEER_STATE_MASK = 0x00ff; -const uint32_t RS_PEER_ACTION_MASK = 0xff00; - -/* STATE */ -const uint32_t RS_PEER_S_FRIEND = 0x0001; -const uint32_t RS_PEER_S_ONLINE = 0x0002; /* heard from recently..*/ -const uint32_t RS_PEER_S_CONNECTED = 0x0004; -const uint32_t RS_PEER_S_UNREACHABLE = 0x0008; - -/* ACTIONS */ -const uint32_t RS_PEER_NEW = 0x0001; /* new Peer */ -const uint32_t RS_PEER_ONLINE = 0x0002; -const uint32_t RS_PEER_CONNECTED = 0x0004; -const uint32_t RS_PEER_MOVED = 0x0008; /* moved from F->O or O->F */ -const uint32_t RS_PEER_DISCONNECTED = 0x0010; -const uint32_t RS_PEER_CONNECT_REQ = 0x0020; - -/* Stun Status Flags */ -//const uint32_t RS_STUN_SRC_DHT = 0x0001; -//const uint32_t RS_STUN_SRC_PEER = 0x0002; -const uint32_t RS_STUN_ONLINE = 0x0010; -const uint32_t RS_STUN_FRIEND = 0x0020; -const uint32_t RS_STUN_FRIEND_OF_FRIEND = 0x0040; - - -#define RS_CB_DHT 0x0001 /* from dht */ -#define RS_CB_DISC 0x0002 /* from peers */ -#define RS_CB_PERSON 0x0003 /* from connection */ -#define RS_CB_PROXY 0x0004 /* via proxy */ - - -#define RS_CB_FLAG_MASK_MODE 0x00ff -#define RS_CB_FLAG_MASK_ORDER 0xff00 - -#define RS_CB_FLAG_MODE_TCP 0x0001 -#define RS_CB_FLAG_MODE_UDP_DIRECT 0x0002 -#define RS_CB_FLAG_MODE_UDP_PROXY 0x0004 -#define RS_CB_FLAG_MODE_UDP_RELAY 0x0008 - -#define RS_CB_FLAG_ORDER_UNSPEC 0x0100 -#define RS_CB_FLAG_ORDER_PASSIVE 0x0200 -#define RS_CB_FLAG_ORDER_ACTIVE 0x0400 - -#define RSUDP_NUM_TOU_RECVERS 3 - -#define RSUDP_TOU_RECVER_DIRECT_IDX 0 -#define RSUDP_TOU_RECVER_PROXY_IDX 1 -#define RSUDP_TOU_RECVER_RELAY_IDX 2 - - -class pqipeer -{ - public: - RsPeerId id; - std::string name; - uint32_t state; - uint32_t actions; -}; - -class p3LinkMgr; - -/*! - * This class should be implemented - * to use the information that is passed to it via - * from the p3ConnectMngr - * Useful information is sent via ticks such as a peer's - * state and a peer's action - */ -class pqiMonitor -{ - public: - pqiMonitor() :mLinkMgr(NULL) { return; } -virtual ~pqiMonitor() { return; } - - /*! - * passes a handle the retroshare connection manager - */ - void setLinkMgr(p3LinkMgr *lm) { mLinkMgr = lm; } - - /*! - * this serves as a call back function for server which has - * a handle on the subclass and updates this subclass on the - * action of peer's of the client (state and action information) - * - *@param plist contains list of states and actions of the client's peers - */ -virtual void statusChange(const std::list &plist) = 0; - - // This is used to force disconnection of a peer, if e.g. something suspicious happenned. - - virtual void disconnectPeer(const RsPeerId& peer) ; - -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections -virtual void statusChanged() {}; -/////////////////////////////////////////////////////////// -#endif - -//virtual void ownStatusChange(pqipeer &) { return; } // SIGNAL reset or similar. -//virtual void peerStatus(std::string id, uint32_t mode) = 0; - - protected: - p3LinkMgr *mLinkMgr; -}; - - - - -class pqiConnectCb -{ - public: -virtual ~pqiConnectCb() { return; } -virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, - uint32_t type, uint32_t flags, uint32_t source) = 0; - -virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, - const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, - uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth) = 0; - - -//virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags) = 0; -}; - - -/**** DUMMY CB FOR TESTING (just prints) ****/ -class pqiConnectCbDummy: public pqiConnectCb -{ - public: - pqiConnectCbDummy(); -virtual ~pqiConnectCbDummy(); -virtual void peerStatus(const RsPeerId& id, const pqiIpAddrSet &addrs, - uint32_t type, uint32_t mode, uint32_t source); - - virtual void peerConnectRequest(const RsPeerId& id, const struct sockaddr_storage &raddr, - const struct sockaddr_storage &proxyaddr, const struct sockaddr_storage &srcaddr, - uint32_t source, uint32_t flags, uint32_t delay, uint32_t bandwidth); - -//virtual void stunStatus(std::string id, const struct sockaddr_storage &raddr, uint32_t type, uint32_t flags); -}; - - -/* network listener interface - used to reset network addresses */ -class pqiNetListener -{ - public: -virtual bool resetListener(const struct sockaddr_storage &local) = 0; - -}; - - -#endif // PQI_MONITOR_H - diff --git a/libretroshare/src/pqi/pqinetstatebox.cc b/libretroshare/src/pqi/pqinetstatebox.cc deleted file mode 100644 index 67d1fcef1..000000000 --- a/libretroshare/src/pqi/pqinetstatebox.cc +++ /dev/null @@ -1,616 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqinetstatebox.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsnet.h" -#include "pqi/pqinetstatebox.h" -#include "util/rstime.h" - -#ifdef RS_USE_BITDHT -#include "bitdht/bdiface.h" -#endif - -// External Interface. - -void pqiNetStateBox::setAddressStunDht(const struct sockaddr_storage &addr, bool stable) -{ - if ((!mStunDhtSet) || (mStunDhtStable != stable) || - (!sockaddr_storage_same(addr, mStunDhtAddr))) - { - mStunDhtSet = true; - mStunDhtStable = stable; - mStunDhtAddr = addr; - - mStatusOkay = false; - } - mStunDhtTS = time(NULL); -} - - -void pqiNetStateBox::setAddressStunProxy(const struct sockaddr_storage &addr, bool stable) -{ - if ((!mStunProxySet) || (mStunProxyStable != stable) || - (!sockaddr_storage_same(addr, mStunProxyAddr))) - { - - if (sockaddr_storage_sameip(addr,mStunProxyAddr)) - { - if (mStunProxyStable != stable) - { - mStunProxySemiStable = true; - } - } - else - { - mStunProxySemiStable = false; // change of address - must trigger this again! - } - - mStunProxySet = true; - mStunProxyStable = stable; - mStunProxyAddr = addr; - mStatusOkay = false; - } - mStunProxyTS = time(NULL); -} - - -void pqiNetStateBox::setAddressUPnP(bool active, const struct sockaddr_storage &addr) -{ - if ((!mUPnPSet) || (mUPnPActive != active) || - (!sockaddr_storage_same(addr, mUPnPAddr))) - { - mUPnPSet = true; - mUPnPAddr = addr; - mUPnPActive = active; - - mStatusOkay = false; - } - mUPnPTS = time(NULL); -} - - -void pqiNetStateBox::setAddressNatPMP(bool active, const struct sockaddr_storage &addr) -{ - if ((!mNatPMPSet) || (mNatPMPActive != active) || - (!sockaddr_storage_same(addr, mNatPMPAddr))) - { - mNatPMPSet = true; - mNatPMPAddr = addr; - mNatPMPActive = active; - - mStatusOkay = false; - } - mNatPMPTS = time(NULL); -} - - - -void pqiNetStateBox::setAddressWebIP(bool active, const struct sockaddr_storage &addr) -{ - if ((!mWebIPSet) || (mWebIPActive != active) || - (!sockaddr_storage_same(addr, mWebIPAddr))) - { - mWebIPSet = true; - mWebIPAddr = addr; - mWebIPActive = active; - - mStatusOkay = false; - } - mWebIPTS = time(NULL); -} - - -void pqiNetStateBox::setPortForwarded(bool /*active*/, uint16_t port) -{ - if ((!mPortForwardSet) || (mPortForwarded != port)) - - { - mPortForwardSet = true; - mPortForwarded = port; - - mStatusOkay = false; - } -} - - -void pqiNetStateBox::setDhtState(bool on, bool active) -{ - if ((!mDhtSet) || (mDhtActive != active) || (mDhtOn != on)) - { - mDhtSet = true; - mDhtActive = active; - mDhtOn = on; - - mStatusOkay = false; - } - mDhtTS = time(NULL); -} - - -/* Extract Net State */ -RsNetworkMode pqiNetStateBox::getNetworkMode() -{ - updateNetState(); - return mNetworkMode; -} - -RsNatTypeMode pqiNetStateBox::getNatTypeMode() -{ - updateNetState(); - return mNatTypeMode; -} - -RsNatHoleMode pqiNetStateBox::getNatHoleMode() -{ - updateNetState(); - return mNatHoleMode; -} - -RsConnectModes pqiNetStateBox::getConnectModes() -{ - updateNetState(); - return mConnectModes; -} - - -RsNetState pqiNetStateBox::getNetStateMode() -{ - updateNetState(); - return mNetStateMode; -} - - - -/******************************** Internal Workings *******************************/ -pqiNetStateBox::pqiNetStateBox() -{ - reset(); -} - - -void pqiNetStateBox::reset() -{ - - mStatusOkay = false; - //rstime_t mStatusTS; - - mNetworkMode = RsNetworkMode::UNKNOWN; - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::UNKNOWN; - mConnectModes = RsConnectModes::NONE; - mNetStateMode = RsNetState::BAD_UNKNOWN; - - /* Parameters set externally */ - - mStunDhtSet = false; - mStunDhtTS = 0; - mStunDhtStable = false; - sockaddr_storage_clear(mStunDhtAddr); - - mStunProxySet = false; - mStunProxySemiStable = false; - mStunProxyTS = 0; - mStunProxyStable = false; - sockaddr_storage_clear(mStunProxyAddr); - - mUPnPSet = false; - mUPnPActive = false; - sockaddr_storage_clear(mUPnPAddr); - - mNatPMPSet = false; - mNatPMPActive = false; - sockaddr_storage_clear(mNatPMPAddr); - - mWebIPSet = false; - mWebIPActive = false; - sockaddr_storage_clear(mWebIPAddr); - - mPortForwardSet = false; - mPortForwarded = false; - - mDhtSet = false; - mDhtActive = false; - mDhtOn = false; - -} - -//#define NETSTATE_PARAM_TIMEOUT 600 -#define NETSTATE_PARAM_TIMEOUT 900 // Change to 15 minutes -> see if it has effect on reconnect time -#define NETSTATE_TIMEOUT 60 - - /* check/update Net State */ -int pqiNetStateBox::statusOkay() -{ - if (!mStatusOkay) - { - return 0; - } - rstime_t now = time(NULL); - if (now - mStatusTS > NETSTATE_TIMEOUT) - { - return 0; - } - return 1; -} - -int pqiNetStateBox::updateNetState() -{ - if (!statusOkay()) - { - determineNetworkState(); - } - return 1; -} - - - - -void pqiNetStateBox::clearOldNetworkData() -{ -#ifdef RS_USE_DHT_STUNNER - /* check if any measurements are too old to consider */ - rstime_t now = time(NULL); - if (now - mStunProxyTS > NETSTATE_PARAM_TIMEOUT) - { - mStunProxySet = false; - } - - if (now - mStunDhtTS > NETSTATE_PARAM_TIMEOUT) - { - mStunDhtSet = false; - } -#else - //Set values, as they are not updated. - mStunProxySet = true; - mStunDhtSet = true; - mStunProxyStable = true; - mStunDhtStable = true; -#endif - -} - - -void pqiNetStateBox::determineNetworkState() -{ - clearOldNetworkData(); - rstime_t now = time(NULL); - - /* now we use the remaining valid input to determine network state */ - - /* Most important Factor is whether we have DHT(STUN) info to ID connection */ - if (mDhtActive) - { - /* firstly lets try to identify OFFLINE / UNKNOWN */ - if ((!mStunProxySet) || (!mStunDhtSet)) - { - mNetworkMode = RsNetworkMode::UNKNOWN; - // Assume these. - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::BAD_UNKNOWN; - - //mExtAddress = .... unknown; - //mExtAddrStable = false; - } - else // Both Are Set! - { - if (!mStunDhtStable) - { - //mExtAddress = mStunDhtExtAddress; - //mExtAddrStable = false; - - if (mStunProxySemiStable) - { - /* I'm guessing this will be a common mode for modern NAT/Firewalls. - * a DETERMINISTIC SYMMETRIC NAT.... This is likely to be the - * next iteration on the RESTRICTED CONE firewall described below. - * If you Stun fast, it looks like a SYMMETRIC NAT, but if you let - * the NAT timeout, you get back your original port so it looks like - * a RESTRICTED CONE nat... - * - * This kind of NAT is passable, if you only attempt one connection at - * a time, and are careful about it! - * - * NB: The StunDht port will never get this mode. - * It has unsolicited traffic which triggers SYM mode - * - */ - - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::DETERM_SYM; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::WARNING_NATTED; - - } - else if (!mStunProxyStable) - { - /* both unstable, Symmetric NAT, Firewalled, No UDP Hole */ - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::SYMMETRIC; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::BAD_NATSYM; - } - else - { - /* if DhtStun Unstable, but ProxyStable, then we have - * an interesting case. This is close to a Debian Firewall - * I tested in the past.... - * - * The big difference between DhtStun and ProxyStun is - * that Dht Port receives unsolicated packets, - * while Proxy Port always sends an outgoing one first. - * - * In the case of the debian firewall, the unsolicated pkts - * caused the outgoing port to change. - * - * We will label this difference RESTRICTED vs FULL CONE, - * but that label is really fully accurate. (gray area). - */ - - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::RESTRICTED_CONE; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::WARNING_NATTED; - } - } - else // Dht Stable. - { - /* DHT Stable port can be caused by: - * 1) Forwarded Port (UPNP, NATPMP, FORWARDED) - * 2) FULL CONE NAT. - * 3) EXT Port. - * Must look at Proxy Stability. - * - if Proxy Unstable, then must be forwarded port. - * - if Proxy Stable, then we cannot tell. - * -> Must use User Info (Upnp, PMP, Forwarded Flag). - * -> Also possible to be EXT Port (Check against iface) - */ - - //mExtAddress = mStunDhtExtAddress; - //mExtAddrStable = true; - - // Initial Fallback Guess at firewall state. - if (mStunProxySemiStable) - { - /* must be a forwarded port/ext or something similar */ - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::DETERM_SYM; - mNatHoleMode = RsNatHoleMode::FORWARDED; - mNetStateMode = RsNetState::GOOD; - } - else if (!mStunProxyStable) - { - /* must be a forwarded port/ext or something similar */ - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::SYMMETRIC; - mNatHoleMode = RsNatHoleMode::FORWARDED; - mNetStateMode = RsNetState::GOOD; - } - else - { - /* fallback is FULL CONE NAT */ - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::FULL_CONE; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::WARNING_NATTED; - } - - if (mUPnPActive) - { - // This Mode is OKAY. - mNetworkMode = RsNetworkMode::BEHINDNAT; - // Use Fallback Guess. - //mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::UPNP; - mNetStateMode = RsNetState::GOOD; - //mExtAddress = ... from UPnP, should match StunDht. - //mExtAddrStable = true; - } - else if (mNatPMPActive) - { - // This Mode is OKAY. - mNetworkMode = RsNetworkMode::BEHINDNAT; - // Use Fallback Guess. - //mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::NATPMP; - mNetStateMode = RsNetState::GOOD; - //mExtAddress = ... from NatPMP, should match NatPMP - //mExtAddrStable = true; - } - else - { - bool isExtAddress = false; - - if (isExtAddress) - { - mNetworkMode = RsNetworkMode::EXTERNALIP; - mNatTypeMode = RsNatTypeMode::NONE; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::GOOD; - - //mExtAddrStable = true; - } - else if (mPortForwardSet) - { - mNetworkMode = RsNetworkMode::BEHINDNAT; - // Use Fallback Guess. - //mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::FORWARDED; - mNetStateMode = RsNetState::ADV_FORWARD; - - //mExtAddrStable = true; // Probably, makin assumption. - } - else - { - /* At this point, we go with the fallback guesses */ - } - } - - } - } - } - else // DHT Inactive, must use other means... - { - /* If we get here we are dealing with a silly peer in "DarkMode". - * We have to primarily rely on the feedback from UPnP, PMP or WebSite "WhatsMyIp". - * This is in the "Advanced" Settings and liable to be set wrong. - * but thats the users fault! - */ - - if (mUPnPActive) - { - // This Mode is OKAY. - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::UPNP; - //mExtAddress = ... from UPnP. - //mExtAddrStable = true; - mNetStateMode = RsNetState::WARNING_NODHT; - } - else if (mNatPMPActive) - { - // This Mode is OKAY. - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::NATPMP; - //mExtAddress = ... from NatPMP. - //mExtAddrStable = true; - mNetStateMode = RsNetState::WARNING_NODHT; - } - else - { - /* if we reach this point, we really need a Web "WhatsMyIp" Check of our Ext Ip Address. */ - /* Check for the possibility of an EXT address ... */ - bool isExtAddress = false; - - //mExtAddress = ... from WhatsMyIp. - - if (isExtAddress) - { - mNetworkMode = RsNetworkMode::EXTERNALIP; - mNatTypeMode = RsNatTypeMode::NONE; - mNatHoleMode = RsNatHoleMode::NONE; - - //mExtAddrStable = true; - mNetStateMode = RsNetState::WARNING_NODHT; - } - else if (mPortForwardSet) - { - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::FORWARDED; - - //mExtAddrStable = true; // Probably, makin assumption. - mNetStateMode = RsNetState::WARNING_NODHT; - } - else - { - /* At this point we must assume firewalled. - * These people have destroyed the possibility of making connections ;( - * Should WARN about this. - */ - mNetworkMode = RsNetworkMode::BEHINDNAT; - mNatTypeMode = RsNatTypeMode::UNKNOWN; - mNatHoleMode = RsNatHoleMode::NONE; - mNetStateMode = RsNetState::BAD_NODHT_NAT; - - //mExtAddrStable = false; // Unlikely to be stable. - } - } - } - - workoutNetworkMode(); - - /* say that things are okay */ - mStatusOkay = true; - mStatusTS = now; -} - - - -/* based on calculated settings, what is the network mode - */ - -void pqiNetStateBox::workoutNetworkMode() -{ - /* connectModes are dependent on the other modes */ - mConnectModes = RsConnectModes::NONE; - switch(mNetworkMode) - { - case RsNetworkMode::UNKNOWN: - case RsNetworkMode::OFFLINE: - case RsNetworkMode::LOCALNET: - case RsNetworkMode::RESTARTING: - /* nothing here */ - break; - case RsNetworkMode::EXTERNALIP: - mConnectModes = RsConnectModes::OUTGOING_TCP; - mConnectModes |= RsConnectModes::ACCEPT_TCP; - - if (mDhtActive) - { - mConnectModes |= RsConnectModes::DIRECT_UDP; - /* if open port. don't want PROXY or RELAY connect - * because we should be able to do direct with EVERYONE. - * Ability to do Proxy is dependent on FIREWALL status. - * Technically could do RELAY, but disable both. - */ - //mConnectModes |= RsConnectModes::PROXY_UDP; - //mConnectModes |= RsConnectModes::RELAY_UDP; - } - break; - case RsNetworkMode::BEHINDNAT: - mConnectModes = RsConnectModes::OUTGOING_TCP; - - /* we're okay if there's a NAT HOLE */ - if ((mNatHoleMode == RsNatHoleMode::UPNP) || - (mNatHoleMode == RsNatHoleMode::NATPMP) || - (mNatHoleMode == RsNatHoleMode::FORWARDED)) - { - mConnectModes |= RsConnectModes::ACCEPT_TCP; - if (mDhtActive) - { - mConnectModes |= RsConnectModes::DIRECT_UDP; - /* dont want PROXY | RELAY with open ports */ - } - } - else - { - /* If behind NAT without NATHOLE, this is where RELAY | PROXY - * are useful. We Flag DIRECT connections, cos we can do these - * with peers with Open Ports. (but not with other NATted peers). - */ - if (mDhtActive) - { - mConnectModes |= RsConnectModes::DIRECT_UDP; - mConnectModes |= RsConnectModes::RELAY_UDP; - - if ((mNatTypeMode == RsNatTypeMode::RESTRICTED_CONE) || - (mNatTypeMode == RsNatTypeMode::FULL_CONE) || - (mNatTypeMode == RsNatTypeMode::DETERM_SYM)) - { - mConnectModes |= RsConnectModes::PROXY_UDP; - } - } - } - break; - } -} diff --git a/libretroshare/src/pqi/pqinetstatebox.h b/libretroshare/src/pqi/pqinetstatebox.h deleted file mode 100644 index 26b85345a..000000000 --- a/libretroshare/src/pqi/pqinetstatebox.h +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqinetstatebox.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_NET_STATUS_BOX_H -#define PQI_NET_STATUS_BOX_H - -/* a little state box to determine network status */ - -#include -#include - -#include -#include - -/*** Network state - * Want this to be all encompassing. - * - */ - -class pqiNetStateBox -{ - public: - pqiNetStateBox(); - - void reset(); - - /* input network bits */ - void setAddressStunDht(const struct sockaddr_storage &addr, bool stable); - void setAddressStunProxy(const struct sockaddr_storage &addr, bool stable); - - void setAddressUPnP(bool active, const struct sockaddr_storage &addr); - void setAddressNatPMP(bool active, const struct sockaddr_storage &addr); - void setAddressWebIP(bool active, const struct sockaddr_storage &addr); - - void setPortForwarded(bool active, uint16_t port); - - void setDhtState(bool dhtOn, bool dhtActive); - - RsNetState getNetStateMode(); - RsNetworkMode getNetworkMode(); - RsNatTypeMode getNatTypeMode(); - RsNatHoleMode getNatHoleMode(); - RsConnectModes getConnectModes(); - - private: - - /* calculate network state */ - void clearOldNetworkData(); - void determineNetworkState(); - int statusOkay(); - int updateNetState(); - - /* more internal fns */ - void workoutNetworkMode(); - - bool mStatusOkay; - rstime_t mStatusTS; - - RsNetworkMode mNetworkMode; - RsNatTypeMode mNatTypeMode; - RsNatHoleMode mNatHoleMode; - RsConnectModes mConnectModes; - RsNetState mNetStateMode; - - /* Parameters set externally */ - - bool mStunDhtSet; - rstime_t mStunDhtTS; - bool mStunDhtStable; - struct sockaddr_storage mStunDhtAddr; - - bool mStunProxySet; - rstime_t mStunProxyTS; - bool mStunProxyStable; - bool mStunProxySemiStable; - struct sockaddr_storage mStunProxyAddr; - - bool mDhtSet; - rstime_t mDhtTS; - bool mDhtOn; - bool mDhtActive; - - bool mUPnPSet; - struct sockaddr_storage mUPnPAddr; - bool mUPnPActive; - rstime_t mUPnPTS; - - bool mNatPMPSet; - struct sockaddr_storage mNatPMPAddr; - bool mNatPMPActive; - rstime_t mNatPMPTS; - - bool mWebIPSet; - struct sockaddr_storage mWebIPAddr; - bool mWebIPActive; - rstime_t mWebIPTS; - - bool mPortForwardSet; - uint16_t mPortForwarded; -}; - -#endif diff --git a/libretroshare/src/pqi/pqinetwork.cc b/libretroshare/src/pqi/pqinetwork.cc deleted file mode 100644 index 18fe71fc0..000000000 --- a/libretroshare/src/pqi/pqinetwork.cc +++ /dev/null @@ -1,533 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqinetwork.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef WINDOWS_SYS -# include "util/rswin.h" -# include "util/rsmemory.h" -# include -#endif // WINDOWS_SYS - -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ - -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" - -#include -#include -#include -#include - -#include "util/rsdebug.h" -#include "util/rsstring.h" -#include "util/rsnet.h" -#include "util/stacktrace.h" - -static struct RsLog::logInfo pqinetzoneInfo = {RsLog::Default, "pqinet"}; -#define pqinetzone &pqinetzoneInfo - -/***** - * #define NET_DEBUG 1 - ****/ - -#ifdef WINDOWS_SYS /* Windows - define errno */ - -int errno; - -#else /* Windows - define errno */ - -#include - -#endif - -#ifdef __HAIKU__ - #include - #define IFF_RUNNING 0x0001 -#endif - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - -void showSocketError(std::string &out) -{ - int err = errno; - rs_sprintf_append(out, "\tSocket Error(%d) : %s\n", err, socket_errorType(err).c_str()); -} - -std::string socket_errorType(int err) -{ - if (err == EBADF) - { - return std::string("EBADF"); - } - else if (err == EINVAL) - { - return std::string("EINVAL"); - } - else if (err == EFAULT) - { - return std::string("EFAULT"); - } - else if (err == ENOTSOCK) - { - return std::string("ENOTSOCK"); - } - else if (err == EISCONN) - { - return std::string("EISCONN"); - } - else if (err == ECONNREFUSED) - { - return std::string("ECONNREFUSED"); - } - else if (err == ETIMEDOUT) - { - return std::string("ETIMEDOUT"); - } - else if (err == ENETUNREACH) - { - return std::string("ENETUNREACH"); - } - else if (err == EADDRINUSE) - { - return std::string("EADDRINUSE"); - } - else if (err == EINPROGRESS) - { - return std::string("EINPROGRESS"); - } - else if (err == EALREADY) - { - return std::string("EALREADY"); - } - else if (err == EAGAIN) - { - return std::string("EAGAIN"); - } - else if (err == EISCONN) - { - return std::string("EISCONN"); - } - else if (err == ENOTCONN) - { - return std::string("ENOTCONN"); - } - // These ones have been turning up in SSL CONNECTION FAILURES. - else if (err == EPIPE) - { - return std::string("EPIPE"); - } - else if (err == ECONNRESET) - { - return std::string("ECONNRESET"); - } - else if (err == EHOSTUNREACH) - { - return std::string("EHOSTUNREACH"); - } - else if (err == EADDRNOTAVAIL) - { - return std::string("EADDRNOTAVAIL"); - } - // - - return std::string("UNKNOWN ERROR CODE - ASK RS-DEVS TO ADD IT!"); -} - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else - -void showSocketError(std::string &out) -{ - int err = WSAGetLastError(); - rs_sprintf_append(out, "\tSocket Error(%d) : %s\n", err, socket_errorType(err).c_str()); -} - - -std::string socket_errorType(int err) -{ - if (err == WSAEBADF) - { - return std::string("WSABADF"); - } - - - else if (err == WSAEINTR) - { - return std::string("WSAEINTR"); - } - else if (err == WSAEACCES) - { - return std::string("WSAEACCES"); - } - else if (err == WSAEFAULT) - { - return std::string("WSAEFAULT"); - } - else if (err == WSAEINVAL) - { - return std::string("WSAEINVAL"); - } - else if (err == WSAEMFILE) - { - return std::string("WSAEMFILE"); - } - else if (err == WSAEWOULDBLOCK) - { - return std::string("WSAEWOULDBLOCK"); - } - else if (err == WSAEINPROGRESS) - { - return std::string("WSAEINPROGRESS"); - } - else if (err == WSAEALREADY) - { - return std::string("WSAEALREADY"); - } - else if (err == WSAENOTSOCK) - { - return std::string("WSAENOTSOCK"); - } - else if (err == WSAEDESTADDRREQ) - { - return std::string("WSAEDESTADDRREQ"); - } - else if (err == WSAEMSGSIZE) - { - return std::string("WSAEMSGSIZE"); - } - else if (err == WSAEPROTOTYPE) - { - return std::string("WSAEPROTOTYPE"); - } - else if (err == WSAENOPROTOOPT) - { - return std::string("WSAENOPROTOOPT"); - } - else if (err == WSAENOTSOCK) - { - return std::string("WSAENOTSOCK"); - } - else if (err == WSAEISCONN) - { - return std::string("WSAISCONN"); - } - else if (err == WSAECONNREFUSED) - { - return std::string("WSACONNREFUSED"); - } - else if (err == WSAECONNRESET) - { - return std::string("WSACONNRESET"); - } - else if (err == WSAETIMEDOUT) - { - return std::string("WSATIMEDOUT"); - } - else if (err == WSAENETUNREACH) - { - return std::string("WSANETUNREACH"); - } - else if (err == WSAEADDRINUSE) - { - return std::string("WSAADDRINUSE"); - } - else if (err == WSAEAFNOSUPPORT) - { - return std::string("WSAEAFNOSUPPORT (normally UDP related!)"); - } - - return std::string("----WINDOWS OPERATING SYSTEM FAILURE----"); -} - -// implement the improved unix inet address fn. -// using old one. -int inet_aton(const char *name, struct in_addr *addr) -{ - return (((*addr).s_addr = inet_addr(name)) != INADDR_NONE); -} - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - -#include -#ifdef WINDOWS_SYS -# include -# include -# pragma comment(lib, "IPHLPAPI.lib") -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 -# include -# include -# include -# include -#else // not __ANDROID__ nor WINDOWS => Linux and other unixes -# include -# include -#endif // WINDOWS_SYS - -bool getLocalAddresses(std::vector& addrs) -{ - addrs.clear(); - -#ifdef WINDOWS_SYS - // Seems strange to me but M$ documentation suggests to allocate this way... - DWORD bf_size = 16000; - IP_ADAPTER_ADDRESSES* adapter_addresses = (IP_ADAPTER_ADDRESSES*) rs_malloc(bf_size); - - if(adapter_addresses == NULL) - return false ; - - DWORD error = GetAdaptersAddresses(AF_UNSPEC, - GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | - GAA_FLAG_SKIP_FRIENDLY_NAME, - NULL, - adapter_addresses, - &bf_size); - if (error != ERROR_SUCCESS) - { - std::cerr << "FATAL ERROR: getLocalAddresses failed!" << std::endl; - return false ; - } - - IP_ADAPTER_ADDRESSES* adapter(NULL); - for(adapter = adapter_addresses; NULL != adapter; adapter = adapter->Next) - { - IP_ADAPTER_UNICAST_ADDRESS* address; - for ( address = adapter->FirstUnicastAddress; address; address = address->Next) - { - sockaddr_storage tmp; - sockaddr_storage_clear(tmp); - if (sockaddr_storage_copyip(tmp, * reinterpret_cast(address->Address.lpSockaddr))) - addrs.push_back(tmp); - } - } - free(adapter_addresses); -#elif defined(__ANDROID__) && __ANDROID_API__ < 24 - foreach(QHostAddress qAddr, QNetworkInterface::allAddresses()) - { - sockaddr_storage tmpAddr; - sockaddr_storage_clear(tmpAddr); - if(sockaddr_storage_ipv4_aton(tmpAddr, qAddr.toString().toStdString().c_str())) - addrs.push_back(tmpAddr); - } -#else // not WINDOWS_SYS not ANDROID => Linux and other unixes - struct ifaddrs *ifsaddrs, *ifa; - if(getifaddrs(&ifsaddrs) != 0) - { - std::cerr << __PRETTY_FUNCTION__ << " FATAL ERROR: " << errno << " " - << strerror(errno) << std::endl; - print_stacktrace(); - return false; - } - for ( ifa = ifsaddrs; ifa; ifa = ifa->ifa_next ) - if ( ifa->ifa_addr && (ifa->ifa_flags & IFF_UP) ) - { - sockaddr_storage tmp; - sockaddr_storage_clear(tmp); - if (sockaddr_storage_copyip(tmp, *reinterpret_cast(ifa->ifa_addr))) - addrs.push_back(tmp); - } - freeifaddrs(ifsaddrs); -#endif // WINDOWS_SYS - -#ifdef NET_DEBUG - std::list::iterator it; - std::cout << "getLocalAddresses(...) returning: <" ; - for(it = addrs.begin(); it != addrs.end(); ++it) - std::cout << sockaddr_storage_iptostring(*it) << ", "; - std::cout << ">" << std::endl; -#endif - - return !addrs.empty(); -} - - -/************************************************************* - * Socket Library Wrapper Functions - * to get over the crapness of the windows. - * - */ - -int unix_close(int fd) -{ - int ret; -/******************* WINDOWS SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - ret = close(fd); -#else - -#ifdef NET_DEBUG - std::cerr << "unix_close()" << std::endl; -#endif - ret = closesocket(fd); - /* translate error */ -#endif -/******************* WINDOWS SPECIFIC PART ******************/ - return ret; -} - -int unix_socket(int domain, int type, int protocol) -{ - int osock = socket(domain, type, protocol); - -#ifdef WINDOWS_SYS -#ifdef NET_DEBUG - std::cerr << "unix_socket()" << std::endl; -#endif // NET_DEBUG - - if ((unsigned) osock == INVALID_SOCKET) - { - // Invalidate socket Unix style. - osock = -1; - errno = WinToUnixError(WSAGetLastError()); - } -#endif // WINDOWS_SYS - - return osock; -} - - -int unix_fcntl_nonblock(int fd) -{ - int ret; - -/******************* OS SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - int flags = fcntl(fd, F_GETFL); - ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - -#ifdef NET_DEBUG - std::cerr << "unix_fcntl_nonblock():" << ret << " errno:" << errno << std::endl; -#endif - -#else - unsigned long int on = 1; - ret = ioctlsocket(fd, FIONBIO, &on); - -#ifdef NET_DEBUG - std::cerr << "unix_fcntl_nonblock()" << std::endl; -#endif - if (ret != 0) - { - /* store unix-style error - */ - ret = -1; - errno = WinToUnixError(WSAGetLastError()); - } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ - return ret; -} - - -int unix_connect(int fd, const sockaddr_storage &serv_addr) -{ -#ifdef NET_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - int ret = connect( fd, (const struct sockaddr *) &serv_addr, - sizeof(struct sockaddr_in6) ); - -/******************* WINDOWS SPECIFIC PART ******************/ -#ifdef WINDOWS_SYS // WINDOWS - if (ret != 0) - { - errno = WinToUnixError(WSAGetLastError()); - ret = -1; - } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ - return ret; -} - - -int unix_getsockopt_error(int sockfd, int *err) -{ - int ret; - *err = 1; -/******************* WINDOWS SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - socklen_t optlen = 4; - ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, err, &optlen); -#else // WINDOWS_SYS - int optlen = 4; - ret=getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *) err, &optlen); - /* translate */ -#ifdef NET_DEBUG - std::cerr << "unix_getsockopt_error() returned: " << (int) err << std::endl; -#endif - if (*err != 0) - { - *err = WinToUnixError(*err); - } -#endif -/******************* WINDOWS SPECIFIC PART ******************/ - return ret; -} - -/******************* WINDOWS SPECIFIC PART ******************/ -#ifdef WINDOWS_SYS // ie WINDOWS. - -int WinToUnixError(int error) -{ -#ifdef NET_DEBUG - std::cerr << "WinToUnixError(" << error << ")" << std::endl; -#endif - switch(error) - { - case WSAEINPROGRESS: - return EINPROGRESS; - break; - case WSAEWOULDBLOCK: - return EINPROGRESS; - break; - case WSAENETUNREACH: - return ENETUNREACH; - break; - case WSAETIMEDOUT: - return ETIMEDOUT; - break; - case WSAEHOSTDOWN: - return EHOSTDOWN; - break; - case WSAECONNREFUSED: - return ECONNREFUSED; - break; - case WSAECONNRESET: - return ECONNRESET; - break; - default: -#ifdef NET_DEBUG - std::cerr << "WinToUnixError(" << error << ") Code Unknown!"; - std::cerr << std::endl; -#endif - break; - } - return ECONNREFUSED; /* sensible default? */ -} - -#endif -/******************* WINDOWS SPECIFIC PART ******************/ diff --git a/libretroshare/src/pqi/pqinetwork.h b/libretroshare/src/pqi/pqinetwork.h deleted file mode 100644 index e4238ee5e..000000000 --- a/libretroshare/src/pqi/pqinetwork.h +++ /dev/null @@ -1,112 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqinetwork.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_NETWORKING_HEADER -#define MRK_PQI_NETWORKING_HEADER - -#include - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - -#include -#include -#include -#include - -#include -#include - -//socket blocking/options. -#include -#include - -#else - -#include "util/rsnet.h" /* more generic networking header */ - -// Some Network functions that are missing from windows. -int inet_aton(const char *name, struct in_addr *addr); - -extern int errno; /* Define extern errno, to duplicate unix behaviour */ - -/* define the Unix Error Codes that we use... - * NB. we should make the same, but not necessary - */ -#define EAGAIN 11 - -#define EUSERS 87 - -#define EHOSTDOWN 112 - -#ifndef __MINGW64_VERSION_MAJOR -#define EWOULDBLOCK EAGAIN - -#define ENOTSOCK 88 - -#define EOPNOTSUPP 95 - -#define EADDRINUSE 98 -#define EADDRNOTAVAIL 99 -#define ENETDOWN 100 -#define ENETUNREACH 101 - -#define ECONNRESET 104 - -#define ETIMEDOUT 10060 // value from pthread.h -#define ECONNREFUSED 111 -#define EHOSTUNREACH 113 -#define EALREADY 114 -#define EINPROGRESS 115 -#endif - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - -#include -#include -#include - -// Same def - different functions... -void showSocketError(std::string &out); - -std::string socket_errorType(int err); - -bool getLocalAddresses(std::vector & addrs); - -/* 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 sockaddr_storage& serv_addr); -int unix_getsockopt_error(int sockfd, int *err); - -#ifdef WINDOWS_SYS // WINDOWS -/******************* WINDOWS SPECIFIC PART ******************/ -int WinToUnixError(int error); -#endif - - - -#endif - diff --git a/libretroshare/src/pqi/pqiperson.cc b/libretroshare/src/pqi/pqiperson.cc deleted file mode 100644 index 62d5e5412..000000000 --- a/libretroshare/src/pqi/pqiperson.cc +++ /dev/null @@ -1,697 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiperson.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqi.h" -#include "pqi/pqiperson.h" -#include "pqi/pqipersongrp.h" -#include "pqi/pqissl.h" -#include "util/rsdebug.h" -#include "util/rsstring.h" -#include "retroshare/rspeers.h" - -static struct RsLog::logInfo pqipersonzoneInfo = {RsLog::Default, "pqiperson"}; -#define pqipersonzone &pqipersonzoneInfo - -/**** - * #define PERSON_DEBUG 1 - ****/ - -pqiperson::pqiperson(const RsPeerId& id, pqipersongrp *pg) : - PQInterface(id), mNotifyMtx("pqiperson-notify"), mPersonMtx("pqiperson"), - active(false), activepqi(NULL), inConnectAttempt(false),// waittimes(0), - pqipg(pg) {} // TODO: must check id! - -pqiperson::~pqiperson() -{ - RS_STACK_MUTEX(mPersonMtx); - - // clean up the childrens - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - { - pqiconnect *pc = (it->second); - delete pc; - } - kids.clear(); -} - -int pqiperson::SendItem(RsItem *i,uint32_t& serialized_size) -{ - RS_STACK_MUTEX(mPersonMtx); - - if(active) - { - // every outgoing item goes through this function, so try to not waste cpu cycles - // check if debug output is wanted, to avoid unecessary work - // getZoneLevel() locks a global mutex and does a lookup in a map or returns a default value - // (not sure if this is a performance problem) - if (PQL_DEBUG_BASIC <= pqipersonzoneInfo.lvl) - { - std::string out = "pqiperson::SendItem() Active: Sending On\n"; - i->print_string(out, 5); // this can be very expensive -#ifdef PERSON_DEBUG - std::cerr << out << std::endl; -#endif - pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out); - } - return activepqi -> SendItem(i,serialized_size); - } - else - { - if (PQL_DEBUG_BASIC <= pqipersonzoneInfo.lvl) - { - std::string out = "pqiperson::SendItem()"; - out += " Not Active: Used to put in ToGo Store\n"; - out += " Now deleting..."; - pqioutput(PQL_DEBUG_BASIC, pqipersonzone, out); - } - delete i; - } - return 0; // queued. -} - -RsItem *pqiperson::GetItem() -{ - RS_STACK_MUTEX(mPersonMtx); - - if (active) - return activepqi->GetItem(); - // else not possible. - return NULL; -} - -bool pqiperson::RecvItem(RsItem *item) -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::RecvItem()" << std::endl; -#endif - - return pqipg->recvItem((RsRawItem *) item); -} - - -int pqiperson::status() -{ - RS_STACK_MUTEX(mPersonMtx); - - if (active) - return activepqi -> status(); - return -1; -} - -int pqiperson::receiveHeartbeat() -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::receiveHeartbeat() from peer : " - << PeerId().toStdString() << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - lastHeartbeatReceived = time(NULL); - - return 1; -} - -int pqiperson::tick() -{ - int activeTick = 0; - - { - RS_STACK_MUTEX(mPersonMtx); - -#ifdef PERSON_DEBUG - if(active) - { - std::cerr << "pqiperson: peer=" << (activepqi? (activepqi->PeerId()): (RsPeerId())) <<", active=" << active << ", last HB=" << time(NULL) - lastHeartbeatReceived << " secs ago." ; - if(lastHeartbeatReceived==0) - std::cerr << "!!!!!!!" << std::endl; - else - std::cerr << std::endl; - } -#endif - - //if lastHeartbeatReceived is 0, it might be not activated so don't do a net reset. - if ( active && time(NULL) > lastHeartbeatReceived + HEARTBEAT_REPEAT_TIME * 20) - { - int ageLastIncoming = time(NULL) - activepqi->getLastIncomingTS(); - -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::tick() WARNING No heartbeat from: " - << PeerId().toStdString() << " LastHeartbeat was: " - << time(NULL) - lastHeartbeatReceived - << "secs ago LastIncoming was: " << ageLastIncoming - << "secs ago" << std::endl; -#endif - - if (ageLastIncoming > 60) // Check timeout - { - std::cerr << "pqiperson::tick() " << PeerId().toStdString() << " No Heartbeat & No Packets for 60 secs -> assume dead." << std::endl; - this->reset_locked(); - } - - } - - - { -#ifdef PERSON_DEBUG - std::string statusStr = " inactive "; - if (active) - statusStr = " active "; - - std::string connectStr = " Not Connecting "; - if (inConnectAttempt) - connectStr = " In Connection Attempt "; - - std::cerr << "pqiperson::tick() Id: " << PeerId().toStdString() - << "activepqi: " << activepqi << " inConnectAttempt:" - << connectStr << std::endl; -#endif - - // tick the children. - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - { - if (0 < (it->second)->tick()) - activeTick = 1; -#ifdef PERSON_DEBUG - std::cerr << "\tTicking Child: "<< it->first << std::endl; -#endif - } - } - } - - // handle Notify Events that were generated. - processNotifyEvents(); - - return activeTick; -} - -// callback function for the child - notify of a change. -// This is only used for out-of-band info.... -// otherwise could get dangerous loops. -// - Actually, now we have - must store and process later. -int pqiperson::notifyEvent(NetInterface *ni, int newState, - const sockaddr_storage &remote_peer_address) -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::notifyEvent() adding event to Queue. newState=" - << newState << " from IP = " - << sockaddr_storage_tostring(remote_peer_address) << std::endl; -#endif - - if (mPersonMtx.trylock()) - { - handleNotifyEvent_locked(ni, newState, remote_peer_address); - mPersonMtx.unlock(); - return 1; - } - - RS_STACK_MUTEX(mNotifyMtx); - mNotifyQueue.push_back(NotifyData(ni, newState, remote_peer_address)); - return 1; -} - -void pqiperson::processNotifyEvents() -{ - NetInterface *ni; - int state; - sockaddr_storage addr; - - while(1) // While there is notification to handle - { - { - RS_STACK_MUTEX(mNotifyMtx); - - if(mNotifyQueue.empty()) - return; - - NotifyData &data = mNotifyQueue.front(); - ni = data.mNi; - state = data.mState; - addr = data.mAddr; - - mNotifyQueue.pop_front(); - } - - RS_STACK_MUTEX(mPersonMtx); - handleNotifyEvent_locked(ni, state, addr); - } -} - - -int pqiperson::handleNotifyEvent_locked(NetInterface *ni, int newState, - const sockaddr_storage &remote_peer_address) -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::handleNotifyEvent_locked() Id: " - << PeerId().toStdString() << " Message: " << newState - << " from: " << ni << std::endl; - int i = 0; -#endif - - /* find the pqi, */ - pqiconnect *pqi = NULL; - uint32_t type = 0; - std::map::iterator it; - - /* start again */ - for(it = kids.begin(); it != kids.end(); ++it) - { -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::handleNotifyEvent_locked() Kid# " << i - << " of " << kids.size() << " type: " << it->first - << " in_ni: " << ni << std::endl; - ++i; -#endif - - if ((it->second)->thisNetInterface(ni)) - { - pqi = (it->second); - type = (it->first); - } - } - - if (!pqi) - { - std::cerr << "pqiperson::handleNotifyEvent_locked Unknown Event Source!" - << std::endl; - return -1; - } - - - switch(newState) - { - case CONNECT_RECEIVED: - case CONNECT_SUCCESS: - { - - /* notify */ - if (pqipg) - { - pqissl *ssl = dynamic_cast(ni); - if(ssl) - pqipg->notifyConnect(PeerId(), type, true, ssl->actAsServer(), remote_peer_address); - else - pqipg->notifyConnect(PeerId(), type, true, false, remote_peer_address); - } - - if ((active) && (activepqi != pqi)) // already connected - trouble - { - // TODO: 2015/12/19 Is this block dead code? - - std::cerr << "pqiperson::handleNotifyEvent_locked Id: " - << PeerId().toStdString() << " CONNECT_SUCCESS+active->" - << "activing new connection, shutting others" - << std::endl; - - // This is the RESET that's killing the connections..... - //activepqi -> reset(); - // this causes a recursive call back into this fn. - // which cleans up state. - // we only do this if its not going to mess with new conn. - } - - /* now install a new one. */ - { -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::handleNotifyEvent_locked Id: " - << PeerId().toStdString() << " CONNECT_SUCCESS->marking " - << "so! (resetting others)" << std::endl; -#endif - - // mark as active. - active = true; - lastHeartbeatReceived = time(NULL) ; - activepqi = pqi; - inConnectAttempt = false; - - // STARTUP THREAD - activepqi->start("pqi " + PeerId().toStdString().substr(0, 11)); - - // reset all other children (clear up long UDP attempt) - for(it = kids.begin(); it != kids.end(); ++it) - if (!(it->second)->thisNetInterface(ni)) - it->second->reset(); - return 1; - } - break; - } - case CONNECT_UNREACHABLE: - case CONNECT_FIREWALLED: - case CONNECT_FAILED: - { - if (active && (activepqi == pqi)) - { -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::handleNotifyEvent_locked Id: " - << PeerId().toStdString() - << " CONNECT_FAILED->marking so!" << std::endl; -#endif - - activepqi->askForStop(); // STOP THREAD. - active = false; - activepqi = nullptr; - } -#ifdef PERSON_DEBUG - else - std::cerr << "pqiperson::handleNotifyEvent_locked Id: " - << PeerId().toStdString() + " CONNECT_FAILED-> from " - << "an unactive connection, don't flag the peer as " - << "not connected, just try next attempt !" << std::endl; -#endif - /* notify up */ - if (pqipg) - pqipg->notifyConnect(PeerId(), type, false, false, remote_peer_address); - - return 1; - } - default: - return -1; - } -} - -/***************** Not PQInterface Fns ***********************/ - -int pqiperson::reset() -{ - RS_STACK_MUTEX(mPersonMtx); - return reset_locked(); -} - -int pqiperson::reset_locked() -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::reset_locked() resetting all pqiconnect for Id: " - << PeerId().toStdString() << std::endl; -#endif - - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - { - it->second->askForStop(); // STOP THREAD. - (it->second) -> reset(); - } - - activepqi = NULL; - active = false; - lastHeartbeatReceived = 0; - - return 1; -} - -int pqiperson::fullstopthreads() -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::fullstopthreads() for Id: " - << PeerId().toStdString() << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - (it->second)->fullstop(); // WAIT FOR THREAD TO STOP. - - activepqi = NULL; - active = false; - lastHeartbeatReceived = 0; - - return 1; -} - -int pqiperson::addChildInterface(uint32_t type, pqiconnect *pqi) -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::addChildInterface() : Id " - << PeerId().toStdString() << " " << type << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - - kids[type] = pqi; - return 1; -} - -/***************** PRIVATE FUNCTIONS ***********************/ -// functions to iterate over the connects and change state. - - -int pqiperson::listen() -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::listen() Id: " + PeerId().toStdString() << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - - if (!active) - { - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - (it->second)->listen(); - } - return 1; -} - - -int pqiperson::stoplistening() -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::stoplistening() Id: " + PeerId().toStdString() - << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - (it->second)->stoplistening(); - - return 1; -} - -int pqiperson::connect(uint32_t type, const sockaddr_storage &raddr, - const sockaddr_storage &proxyaddr, - const sockaddr_storage &srcaddr, - uint32_t delay, uint32_t period, uint32_t timeout, - uint32_t flags, uint32_t bandwidth, - const std::string &domain_addr, uint16_t domain_port) -{ -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::connect() Id: " << PeerId().toStdString() - << " type: " << type << " addr: " - << sockaddr_storage_tostring(raddr) << " proxyaddr: " - << sockaddr_storage_tostring(proxyaddr) << " srcaddr: " - << sockaddr_storage_tostring(srcaddr) << " delay: " << delay - << " period: " << period << " timeout: " << timeout << " flags: " - << flags << " bandwidth: " << bandwidth << std::endl; -#endif - - RS_STACK_MUTEX(mPersonMtx); - - std::map::iterator it; - - it = kids.find(type); - if (it == kids.end()) - { - /* notify of fail! */ - pqipg->notifyConnect(PeerId(), type, false, false, raddr); - return 0; - } - - pqiconnect *pqi = it->second; - -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::connect() resetting for new connection attempt" << std::endl; -#endif - - /* set the parameters */ - pqi->reset(); - -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::connect() clearing rate cap" << std::endl; -#endif - setRateCap_locked(0,0); - -#ifdef PERSON_DEBUG - std::cerr << "pqiperson::connect() setting connect_parameters" << std::endl; -#endif - - // These two are universal. - pqi->connect_parameter(NET_PARAM_CONNECT_DELAY, delay); - pqi->connect_parameter(NET_PARAM_CONNECT_TIMEOUT, timeout); - - // these 5 are only used by UDP connections. - pqi->connect_parameter(NET_PARAM_CONNECT_PERIOD, period); - pqi->connect_parameter(NET_PARAM_CONNECT_FLAGS, flags); - pqi->connect_parameter(NET_PARAM_CONNECT_BANDWIDTH, bandwidth); - - pqi->connect_additional_address(NET_PARAM_CONNECT_PROXY, proxyaddr); - pqi->connect_additional_address(NET_PARAM_CONNECT_SOURCE, srcaddr); - - // These are used by Proxy/Hidden - pqi->connect_parameter(NET_PARAM_CONNECT_DOMAIN_ADDRESS, domain_addr); - pqi->connect_parameter(NET_PARAM_CONNECT_REMOTE_PORT, domain_port); - - pqi->connect(raddr); - - // flag if we started a new connectionAttempt. - inConnectAttempt = true; - - return 1; -} - - -void pqiperson::getRates(RsBwRates &rates) -{ - RS_STACK_MUTEX(mPersonMtx); - - // get the rate from the active one. - if ((!active) || (activepqi == NULL)) - return; - - activepqi->getRates(rates); -} - -int pqiperson::gatherStatistics(std::list& out_lst, - std::list& in_lst) -{ - RS_STACK_MUTEX(mPersonMtx); - - // Get the rate from the active one. - if( (!active) || (activepqi == NULL) ) - return 0 ; - - return activepqi->gatherStatistics(out_lst, in_lst); -} - -int pqiperson::getQueueSize(bool in) -{ - RS_STACK_MUTEX(mPersonMtx); - - // get the rate from the active one. - if ((!active) || (activepqi == NULL)) - return 0; - - return activepqi->getQueueSize(in); -} - -bool pqiperson::getCryptoParams(RsPeerCryptoParams & params) -{ - RS_STACK_MUTEX(mPersonMtx); - - if(active && activepqi != NULL) - return activepqi->getCryptoParams(params); - else - { - params.connexion_state = 0; - params.cipher_name.clear(); - - return false ; - } -} - -bool pqiconnect::getCryptoParams(RsPeerCryptoParams & params) -{ - pqissl *ssl = dynamic_cast(ni); - - if(ssl != NULL) - { - ssl->getCryptoParams(params); - return true; - } - else - { - params.connexion_state = 0 ; - params.cipher_name.clear() ; - return false ; - } -} - -float pqiperson::getRate(bool in) -{ - RS_STACK_MUTEX(mPersonMtx); - - // get the rate from the active one. - if ((!active) || (activepqi == NULL)) - return 0; - - return activepqi -> getRate(in); -} - -uint64_t pqiperson::getTraffic(bool in) -{ - if ((!active) || (activepqi == NULL)) - return 0; - return activepqi -> getTraffic(in); -} - -void pqiperson::setMaxRate(bool in, float val) -{ - RS_STACK_MUTEX(mPersonMtx); - - // set to all of them. (and us) - PQInterface::setMaxRate(in, val); - // clean up the children. - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - (it->second) -> setMaxRate(in, val); -} - -void pqiperson::setRateCap(float val_in, float val_out) -{ - // This methods might be called all the way down from pqiperson::tick() down - // to pqissludp while completing a UDP connexion, causing a deadlock. - // - // We need to make sure the mutex is not already locked by current thread. If so, we call the - // locked version directly if not, we lock, call, and unlock, possibly waiting if the - // lock is already acquired by another thread. - // - // The lock cannot be locked by the same thread between the first test and - // the "else" statement, so there is no possibility for this code to fail. - // - // We could actually put that code in RsMutex::lock()? - // TODO: 2015/12/19 This code is already in RsMutex::lock() but is guarded - // by RSTHREAD_SELF_LOCKING_GUARD which is specifically unset in the header - // Why is that code guarded? Do it have an impact on performance? - // Or we should not get in the situation of trying to relock the mutex on - // the same thread NEVER? - - if(pthread_equal(mPersonMtx.owner(), pthread_self())) - // Unlocked, or already locked by same thread - setRateCap_locked(val_in, val_out); - else - { - // Lock was free or locked by different thread => wait. - RS_STACK_MUTEX(mPersonMtx); - setRateCap_locked(val_in, val_out); - } -} - -void pqiperson::setRateCap_locked(float val_in, float val_out) -{ - // set to all of them. (and us) - PQInterface::setRateCap(val_in, val_out); - // clean up the children. - std::map::iterator it; - for(it = kids.begin(); it != kids.end(); ++it) - (it->second)->setRateCap(val_in, val_out); -} diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h deleted file mode 100644 index 59bae7834..000000000 --- a/libretroshare/src/pqi/pqiperson.h +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiperson.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_PERSON_HEADER -#define MRK_PQI_PERSON_HEADER - - -#include -#include "pqi/pqi.h" -#include "util/rsnet.h" - -#include - -class pqiperson; -struct RsPeerCryptoParams; - -static const int CONNECT_RECEIVED = 1; -static const int CONNECT_SUCCESS = 2; -static const int CONNECT_UNREACHABLE = 3; -static const int CONNECT_FIREWALLED = 4; -static const int CONNECT_FAILED = 5; - -static const rstime_t HEARTBEAT_REPEAT_TIME = 5; - -#include "pqi/pqiqosstreamer.h" -#include "pqi/pqithreadstreamer.h" - -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) {} - - 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() { pqistreamer::reset(); return ni->reset(); } - virtual int disconnect() { return reset() ; } - virtual bool connect_parameter(uint32_t type, uint32_t value) { return ni->connect_parameter(type, value);} - virtual bool connect_parameter(uint32_t type, const 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() { return ni->PeerId(); } - - // to check if our interface. - virtual bool thisNetInterface(NetInterface *ni_in) { return (ni_in == ni); } - -protected: - NetBinInterface *ni; -}; - - -class pqipersongrp; - -class NotifyData -{ -public: - NotifyData() : mNi(NULL), mState(0) - { - sockaddr_storage_clear(mAddr); - } - - NotifyData(NetInterface *ni, int state, const sockaddr_storage &addr) : - mNi(ni), mState(state), mAddr(addr) {} - - NetInterface *mNi; - int mState; - sockaddr_storage mAddr; -}; - - -class pqiperson: public PQInterface -{ -public: - pqiperson(const RsPeerId& id, pqipersongrp *ppg); - virtual ~pqiperson(); // must clean up children. - - // control of the connection. - int reset(); - int listen(); - int stoplistening(); - - int connect(uint32_t type, const sockaddr_storage &raddr, - const sockaddr_storage &proxyaddr, const sockaddr_storage &srcaddr, - uint32_t delay, uint32_t period, uint32_t timeout, uint32_t flags, - uint32_t bandwidth, const std::string &domain_addr, uint16_t domain_port); - - int fullstopthreads(); - int receiveHeartbeat(); - - // add in connection method. - int addChildInterface(uint32_t type, pqiconnect *pqi); - - virtual bool getCryptoParams(RsPeerCryptoParams&); - - // The PQInterface interface. - virtual int SendItem(RsItem *,uint32_t& serialized_size); - virtual int SendItem(RsItem *item) - { - std::cerr << "Warning pqiperson::sendItem(RsItem*) should not be called." - << "Plz call SendItem(RsItem *,uint32_t& serialized_size) instead." - << std::endl; - uint32_t serialized_size; - return SendItem(item, serialized_size); - } - - virtual RsItem *GetItem(); - virtual bool RecvItem(RsItem *item); - - virtual int status(); - virtual int tick(); - - // overloaded callback function for the child - notify of a change. - virtual int notifyEvent(NetInterface *ni, int event, const struct sockaddr_storage &addr); - - // PQInterface for rate control overloaded.... - virtual int getQueueSize(bool in); - virtual void getRates(RsBwRates &rates); - virtual float getRate(bool in); - virtual uint64_t getTraffic(bool in); - virtual void setMaxRate(bool in, float val); - virtual void setRateCap(float val_in, float val_out); - virtual int gatherStatistics(std::list& outqueue_lst, - std::list& inqueue_lst); - -private: - void processNotifyEvents(); - int handleNotifyEvent_locked(NetInterface *ni, int event, - const sockaddr_storage &addr); - - RsMutex mNotifyMtx; // LOCKS Notify Queue - std::list mNotifyQueue; - - RsMutex mPersonMtx; // LOCKS below - - int reset_locked(); - - void setRateCap_locked(float val_in, float val_out); - - std::map kids; - bool active; - pqiconnect *activepqi; - bool inConnectAttempt; - //int waittimes; - rstime_t lastHeartbeatReceived; // use to track connection failure - pqipersongrp *pqipg; /* parent for callback */ -}; - -#endif diff --git a/libretroshare/src/pqi/pqipersongrp.cc b/libretroshare/src/pqi/pqipersongrp.cc deleted file mode 100644 index 7146be7de..000000000 --- a/libretroshare/src/pqi/pqipersongrp.cc +++ /dev/null @@ -1,721 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqipersongrp.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqipersongrp.h" -#include "pqi/p3linkmgr.h" -#include "util/rsdebug.h" -#include "util/rsprint.h" -#include "serialiser/rsserializer.h" - -#include - -static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersongrp"}; -#define pqipersongrpzone &pqipersongrpzoneInfo - -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections -#include "retroshare/rsinit.h" -static std::list waitingIds; -#define MAX_CONNECT_COUNT 3 -/////////////////////////////////////////////////////////// -#endif - -/**** - *#define PGRP_DEBUG 1 - *#define PGRP_DEBUG_LOG 1 - ****/ - -#define DEFAULT_DOWNLOAD_KB_RATE (200.0) -#define DEFAULT_UPLOAD_KB_RATE (50.0) - -/* MUTEX NOTES: - * Functions like GetRsRawItem() lock itself (pqihandler) and - * likewise ServiceServer and ConfigMgr mutex themselves. - * This means the only things we need to worry about are: - * pqilistener and when accessing pqihandlers data. - */ - - - // New speedy recv. -bool pqipersongrp::RecvRsRawItem(RsRawItem *item) -{ - std::cerr << "pqipersongrp::RecvRsRawItem()"; - std::cerr << std::endl; - - p3ServiceServer::recvItem(item); - - return true; -} - - - -#ifdef TO_BE_REMOVED -// handle the tunnel services. -int pqipersongrp::tickServiceRecv() -{ - RsRawItem *pqi = NULL; - int i = 0; - - pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, "pqipersongrp::tickServiceRecv()"); - - //p3ServiceServer::tick(); - - while(NULL != (pqi = GetRsRawItem())) - { - static int ntimes=0 ; - if(++ntimes < 20) - { - std::cerr << "pqipersongrp::tickServiceRecv() GetRsRawItem()"; - std::cerr << " should never happen anymore! item data=" << RsUtil::BinToHex((char*)pqi->getRawData(),pqi->getRawLength()) ; - std::cerr << std::endl; - } - - ++i; - pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, - "pqipersongrp::tickServiceRecv() Incoming TunnelItem"); - recvItem(pqi); - } - - if (0 < i) - { - return 1; - } - return 0; -} -#endif - -// handle the tunnel services. - -// Improvements: -// This function is no longer necessary, and data is pushed directly to pqihandler. - -#ifdef TO_BE_REMOVED -int pqipersongrp::tickServiceSend() -{ - RsRawItem *pqi = NULL; - int i = 0; - - pqioutput(PQL_DEBUG_ALL, pqipersongrpzone, "pqipersongrp::tickServiceSend()"); - - p3ServiceServer::tick(); - - while(NULL != (pqi = outgoing())) /* outgoing has own locking */ - { - ++i; - pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, - "pqipersongrp::tickTunnelServer() OutGoing RsItem"); - - SendRsRawItem(pqi); /* Locked by pqihandler */ - } - if (0 < i) - { - return 1; - } - return 0; -} - -#endif - - - // init -pqipersongrp::pqipersongrp(p3ServiceControl *ctrl, unsigned long flags) - :pqihandler(), p3ServiceServer(this, ctrl), pqil(NULL), pqilMtx("pqipersongrp"), initFlags(flags) -{ -} - - -int pqipersongrp::tick() -{ - /* could limit the ticking of listener / tunnels to 1/sec... - * but not to important. - */ - - { - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - if (pqil) - { - pqil -> tick(); - } - } /* UNLOCKED */ - - int i = 0; - -#ifdef TO_BE_REMOVED - if (tickServiceSend()) - { - i = 1; -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::tick() moreToTick from tickServiceSend()" << std::endl; -#endif - } - if (pqihandler::tick()) /* does Send/Recv */ - { - i = 1; -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::tick() moreToTick from pqihandler::tick()" << std::endl; -#endif - } - if (tickServiceRecv()) - { - i = 1; -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::tick() moreToTick from tickServiceRecv()" << std::endl; -#endif - } -#endif - - if(pqihandler::tick()) - i=1; - - p3ServiceServer::tick(); - - return i; -} - -int pqipersongrp::status() -{ - { - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - if (pqil) - { - pqil -> status(); - } - } /* UNLOCKED */ - - return pqihandler::status(); -} - - -/* Initialise pqilistener */ -int pqipersongrp::init_listener() -{ - /* extract our information from the p3ConnectMgr */ - if (initFlags & PQIPERSON_NO_LISTENER) - { - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - pqil = NULL; - } - else - { - /* extract details from - */ - struct sockaddr_storage laddr; - mLinkMgr->getLocalAddress(laddr); - - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - pqil = locked_createListener(laddr); - } - return 1; -} - -bool pqipersongrp::resetListener(const struct sockaddr_storage &local) -{ - #ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::resetListener()" << std::endl; - #endif - - // stop it, - // change the address. - // restart. - - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - - if (pqil != NULL) - { - #ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::resetListener() haveListener" << std::endl; - #endif - - pqil -> resetlisten(); - pqil -> setListenAddr(local); - pqil -> setuplisten(); - - #ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::resetListener() done!" << std::endl; - #endif - - } - return 1; -} - -void pqipersongrp::statusChange(const std::list &plist) -{ - - /* iterate through, only worry about the friends */ - std::list::const_iterator it; - for(it = plist.begin(); it != plist.end(); ++it) - { - if (it->state & RS_PEER_S_FRIEND) - { - /* now handle add/remove */ - if ((it->actions & RS_PEER_NEW) - || (it->actions & RS_PEER_MOVED)) - { - addPeer(it->id); - } - - if (it->actions & RS_PEER_CONNECT_REQ) - { - connectPeer(it->id); - } - } - else /* Not Friend */ - { - if (it->actions & RS_PEER_MOVED) - { - removePeer(it->id); - } - } - } -} - -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections -void pqipersongrp::statusChanged() -{ -#warning "Windows connection limited hacked together - please fix" - - if (RsInit::isWindowsXP() == false) { - /* the problem only exist in Windows XP */ - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - waitingIds.clear(); - return; - } - - { - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - if (waitingIds.empty()) - { - /* nothing to do */ - return; - } - } - - /* check for active connections and start waiting id's */ - long connect_count = 0; - std::list toConnect; - - { - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - - /* get address from p3connmgr */ - if (!mLinkMgr) { - return; - } - - /* check for active connections and start waiting id's */ - std::list peers; - mLinkMgr->getFriendList(peers); - - /* count connection attempts */ - std::list::iterator peer; - for (peer = peers.begin(); peer != peers.end(); ++peer) { - peerConnectState state; - if (mLinkMgr->getFriendNetStatus(*peer, state) == false) { - continue; - } - - if (state.inConnAttempt) { - connect_count++; - if (connect_count >= MAX_CONNECT_COUNT) { -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::statusChanged() Too many connections due to windows limitations. There are " << waitingIds.size() << " waiting connections." << std::endl; -#endif - return; - } - } - } - -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::statusChanged() There are "; - std::cerr << connect_count << " connection attempts and " << waitingIds.size(); - std::cerr << " waiting connections. Can start "; - std::cerr << (MAX_CONNECT_COUNT - connect_count) << " connection attempts."; - std::cerr << std::endl; -#endif - - /* start some waiting id's */ - for (int i = connect_count; i < MAX_CONNECT_COUNT; i++) - { - if (waitingIds.empty()) { - break; - } - RsPeerId waitingId = waitingIds.front(); - waitingIds.pop_front(); - -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::statusChanged() id: " << waitingId << " connect peer"; - std::cerr << std::endl; -#endif - - toConnect.push_back(waitingId); - } - } /* UNLOCKED */ - - std::list::iterator cit; - for(cit = toConnect.begin(); cit != toConnect.end(); ++cit) - { - connectPeer(*cit, true); - } -} -/////////////////////////////////////////////////////////// -#endif - -bool pqipersongrp::getCryptoParams(const RsPeerId& id,RsPeerCryptoParams& params) -{ - RsStackMutex stack(coreMtx); /******* LOCKED MUTEX **********/ - - std::map::iterator it = mods.find(id) ; - - if(it == mods.end()) - return false ; - - return it->second->pqi->getCryptoParams(params) ; - - //return locked_getCryptoParams(id,params) ; -} - -int pqipersongrp::addPeer(const RsPeerId& id) -{ - pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, "pqipersongrp::addPeer() PeerId: " + id.toStdString()); - - std::cerr << "pqipersongrp::addPeer() id: " << id; - std::cerr << std::endl; -#ifdef PGRP_DEBUG -#endif - - SearchModule *sm = NULL; - - { - // The Mutex is required here as pqiListener is not thread-safe. - RsStackMutex stack(pqilMtx); /******* LOCKED MUTEX **********/ - pqiperson *pqip = locked_createPerson(id, pqil); - - // attach to pqihandler - sm = new SearchModule(); - sm -> peerid = id; - sm -> pqi = pqip; - - // reset it to start it working. -#ifdef PGRP_DEBUG_LOG - pqioutput(PQL_WARNING, pqipersongrpzone, "pqipersongrp::addPeer() => reset() called to initialise new person"); -#endif - pqip -> reset(); - pqip -> listen(); - - } /* UNLOCKED */ - - return AddSearchModule(sm); -} - - -int pqipersongrp::removePeer(const RsPeerId& id) -{ - std::map::iterator it; - -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::removePeer() id: " << id; - std::cerr << std::endl; -#endif - - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - - it = mods.find(id); - if (it != mods.end()) - { - SearchModule *mod = it->second; - pqiperson *p = (pqiperson *) mod -> pqi; - p -> stoplistening(); - pqioutput(PQL_WARNING, pqipersongrpzone, "pqipersongrp::removePeer() => reset() called before deleting person"); - p -> reset(); - p -> fullstopthreads(); - delete p; - mods.erase(it); - } - else - { - std::cerr << " pqipersongrp::removePeer() ERROR doesn't exist! id: " << id; - std::cerr << std::endl; - } - return 1; -} - -int pqipersongrp::tagHeartbeatRecvd(const RsPeerId& id) -{ - std::map::iterator it; - -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::tagHeartbeatRecvd() id: " << id; - std::cerr << std::endl; -#endif - - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - - it = mods.find(id); - if (it != mods.end()) - { - SearchModule *mod = it->second; - pqiperson *p = (pqiperson *) mod -> pqi; - p->receiveHeartbeat(); - return 1; - } - return 0; -} - - - - - - -int pqipersongrp::connectPeer(const RsPeerId& id -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections - , bool bConnect /*= false*/ -/////////////////////////////////////////////////////////// -#endif - ) -{ - RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ - - if (!mLinkMgr) - return 0; - - if (id == mLinkMgr->getOwnId()) - { -#ifdef PGRP_DEBUG - std::cerr << "pqipersongrp::connectPeer() ERROR Failed, connecting to own id." << std::endl; -#endif - return 0; - } - std::map::iterator it; - it = mods.find(id); - if (it == mods.end()) - { - return 0; - } - /* get the connect attempt details from the p3connmgr... */ - SearchModule *mod = it->second; - pqiperson *p = (pqiperson *) mod -> pqi; - -#ifdef WINDOWS_SYS - /////////////////////////////////////////////////////////// - // hack for too many connections - - if (RsInit::isWindowsXP()) { - /* the problem only exist in Windows XP */ - if (bConnect == false) { - /* check for id is waiting */ - if (std::find(waitingIds.begin(), waitingIds.end(), id) != waitingIds.end()) { - /* id is waiting for a connection */ -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() id: " << id << " is already waiting "; - std::cerr << std::endl; -#endif - return 0; - } - - /* check for connection type of the next connect attempt */ - peerConnectState state; - if (mLinkMgr->getFriendNetStatus(id, state) == false) { -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() id: " << id << " No friend net status"; - std::cerr << std::endl; -#endif - return 0; - } - if (state.connAddrs.size() < 1) { -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() id: " << id << " No existing connect addresses"; - std::cerr << std::endl; -#endif - return 0; - } - const peerConnectAddress ¤tConnAddrAttempt = state.connAddrs.front(); - if (currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) { -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() id: " << id << " added to the waiting list"; - std::cerr << std::endl; -#endif - /* TCP connect, add id to waiting */ - waitingIds.push_back(id); - - /* wait for call to connectPeer with empty id */ - return 0; - } - - /* try all other types of connect directly */ - -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() id: " << id << " connect directly without wait"; - std::cerr << std::endl; -#endif - } - - /* remove id from waiting */ - waitingIds.remove(id); - } - - /////////////////////////////////////////////////////////// -#endif - - struct sockaddr_storage addr; - uint32_t delay; - uint32_t period; - uint32_t timeout; - uint32_t type; - uint32_t flags = 0 ; - - struct sockaddr_storage proxyaddr; - struct sockaddr_storage srcaddr; - uint32_t bandwidth; - std::string domain_addr; - uint16_t domain_port; - - if (!mLinkMgr->connectAttempt(id, addr, proxyaddr, srcaddr, delay, period, type, flags, bandwidth, domain_addr, domain_port)) - { -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() No Net Address"; - std::cerr << std::endl; -#endif - return 0; - } - -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() connectAttempt data id: " << id; - std::cerr << " addr: " << sockaddr_storage_tostring(addr); - std::cerr << " delay: " << delay; - std::cerr << " period: " << period; - std::cerr << " type: " << type; - std::cerr << " flags: " << flags; - std::cerr << " domain_addr: " << domain_addr; - std::cerr << " domain_port: " << domain_port; - std::cerr << std::endl; -#endif - - - uint32_t ptype; - if (type & RS_NET_CONN_TCP_ALL) - { - 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; - break; - } -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() connecting with TCP: Timeout :" << timeout; - std::cerr << std::endl; -#endif - } - else if (type & RS_NET_CONN_UDP_ALL) - { - ptype = PQI_CONNECT_UDP; - timeout = period + RS_UDP_STD_TIMEOUT_PERIOD; // Split of UNCERTAINTY + TIME FOR TTL to RISE to Connection. -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() connecting with UDP: Timeout :" << timeout; - std::cerr << std::endl; -#endif - } - else - { -#ifdef PGRP_DEBUG - std::cerr << " pqipersongrp::connectPeer() Ignoring Unknown Type:" << type; - std::cerr << std::endl; -#endif - return 0; - } - - p->connect(ptype, addr, proxyaddr, srcaddr, delay, period, timeout, flags, bandwidth, domain_addr, domain_port); - - return 1; -} - -bool pqipersongrp::notifyConnect(const RsPeerId& id, uint32_t ptype, bool success, bool isIncomingConnection, const struct sockaddr_storage &raddr) -{ - uint32_t type = 0; - if (ptype == PQI_CONNECT_TCP) - { - type = RS_NET_CONN_TCP_ALL; - } - else if (ptype == PQI_CONNECT_UDP) - { - type = RS_NET_CONN_UDP_ALL; - } - - if (mLinkMgr) - mLinkMgr->connectResult(id, success, isIncomingConnection, type, raddr); - - return (NULL != mLinkMgr); -} - -/******************************** DUMMY Specific features ***************************/ - -#include "pqi/pqibin.h" - -pqilistener * pqipersongrpDummy::locked_createListener(const struct sockaddr_storage & /*laddr*/) -{ - pqilistener *listener = new pqilistener(); - return listener; -} - - -pqiperson * pqipersongrpDummy::locked_createPerson(const RsPeerId& id, pqilistener * /*listener*/) -{ - pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, "pqipersongrpDummy::createPerson() PeerId: " + id.toStdString()); - - pqiperson *pqip = new pqiperson(id, this); - - // TCP - NetBinDummy *d1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP); - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsRawSerialiser()); - - pqiconnect *pqic = new pqiconnect(pqip, rss, d1); - - pqip -> addChildInterface(PQI_CONNECT_TCP, pqic); - - // UDP. - NetBinDummy *d2 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP); - - RsSerialiser *rss2 = new RsSerialiser(); - rss2->addSerialType(new RsRawSerialiser()); - - pqiconnect *pqic2 = new pqiconnect(pqip, rss2, d2); - - pqip -> addChildInterface(PQI_CONNECT_UDP, pqic2); - - return pqip; -} - -/******************************** DUMMY Specific features ***************************/ - diff --git a/libretroshare/src/pqi/pqipersongrp.h b/libretroshare/src/pqi/pqipersongrp.h deleted file mode 100644 index 5b57aebb1..000000000 --- a/libretroshare/src/pqi/pqipersongrp.h +++ /dev/null @@ -1,141 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqipersongrp.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_PERSON_HANDLER_HEADER -#define MRK_PQI_PERSON_HANDLER_HEADER - -#include "pqi/pqihandler.h" -#include "pqi/pqiperson.h" -#include "pqi/pqilistener.h" -#include "pqi/pqiservice.h" -#include "pqi/pqimonitor.h" -#include "pqi/p3cfgmgr.h" - - -// So this is a specific implementation -// -// it is designed to have one pqilistensocket + a series of pqisockets -// -// as an added bonus, we are going to -// make this a pqitunnelserver, to which services can be attached. - -const unsigned long PQIPERSON_NO_LISTENER = 0x0001; - -const unsigned long PQIPERSON_ALL_BW_LIMITED = 0x0010; -struct RsPeerCryptoParams; - -class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer, public pqiNetListener -{ - public: - pqipersongrp(p3ServiceControl *ctrl, unsigned long flags); - - /*************************** Setup *************************/ - /* pqilistener */ - -virtual bool resetListener(const struct sockaddr_storage &local); // overloaded from pqiNetListener -int init_listener(); - - /*************** pqiMonitor callback ***********************/ -virtual void statusChange(const std::list &plist); - -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections -virtual void statusChanged(); -/////////////////////////////////////////////////////////// -#endif - - /******************* Peer Control **************************/ -virtual int addPeer(const RsPeerId& id); /* can be overloaded for testing */ -int removePeer(const RsPeerId& id); -int connectPeer(const RsPeerId& id -#ifdef WINDOWS_SYS -/////////////////////////////////////////////////////////// -// hack for too many connections - , bool bConnect = false -/////////////////////////////////////////////////////////// -#endif - ); - - // New speedy recv. -virtual bool RecvRsRawItem(RsRawItem *item); - - - /* Work-around to dodgy pointer stuff */ -int tagHeartbeatRecvd(const RsPeerId& id); - - /*** callback from children ****/ -bool notifyConnect(const RsPeerId& id, uint32_t type, bool success, bool isIncomingConnection, const struct sockaddr_storage &remote_peer_address); -//bool notifyConnect(std::string id, uint32_t type, bool success); - - // tick interfaces. -virtual int tick(); -virtual int status(); - -virtual bool getCryptoParams(const RsPeerId&,RsPeerCryptoParams&) ; - protected: - -virtual bool locked_getCryptoParams(const RsPeerId&, RsPeerCryptoParams&) { return false ;} - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ - // THESE NEED TO BE LOCKED UNTIL PQILISTENER IS THREAD-SAFE. -virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr) = 0; -virtual pqiperson *locked_createPerson(const RsPeerId& id, pqilistener *listener) = 0; - /********* FUNCTIONS to OVERLOAD for specialisation ********/ - - /* Overloaded RsItem Check - * checks item->cid vs Person - */ -virtual int checkOutgoingRsItem(RsItem *item, int global) - { - (void) item; /* suppress unused parameter warning */ - (void) global; /* suppress unused parameter warning */ - return 1; - } - - private: - - // The serviceserver operation. - //int tickServiceRecv(); - //int tickServiceSend(); - - pqilistener *pqil; - RsMutex pqilMtx; /* MUTEX */ - unsigned long initFlags; -}; - -class pqipersongrpDummy: public pqipersongrp -{ - public: - pqipersongrpDummy(p3ServiceControl *ctrl, unsigned long flags) - :pqipersongrp(ctrl, flags) { return; } - - protected: - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr); -virtual pqiperson *locked_createPerson(const RsPeerId& id, pqilistener *listener); - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -}; - - - -#endif // MRK_PQI_PERSON_HANDLER_HEADER diff --git a/libretroshare/src/pqi/pqiqos.cc b/libretroshare/src/pqi/pqiqos.cc deleted file mode 100644 index 0b2b484fa..000000000 --- a/libretroshare/src/pqi/pqiqos.cc +++ /dev/null @@ -1,156 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiqos.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include -#include - -#include "pqiqos.h" - -const uint32_t pqiQoS::MAX_PACKET_COUNTER_VALUE = (1 << 24) ; - -pqiQoS::pqiQoS(uint32_t nb_levels,float alpha) - : _item_queues(nb_levels),_alpha(alpha) -{ -#ifdef DEBUG - assert(pow(alpha,nb_levels) < 1e+20) ; -#endif - - float c = 1.0f ; - float inc = alpha ; - _nb_items = 0 ; - _id_counter = 0 ; - -for(int i=((int)nb_levels)-1;i>=0;--i,c *= alpha) - { - _item_queues[i]._threshold = c ; - _item_queues[i]._counter = 0 ; - _item_queues[i]._inc = inc ; - } -} - -void pqiQoS::clear() -{ - void *item ; - - for(uint32_t i=0;i<_item_queues.size();++i) - while( (item = _item_queues[i].pop()) != NULL) - free(item) ; - - _nb_items = 0 ; -} - -void pqiQoS::print() const -{ - std::cerr << "pqiQoS: " << _item_queues.size() << " levels, alpha=" << _alpha ; - std::cerr << " Size = " << _nb_items ; - std::cerr << " Queues: " ; - for(uint32_t i=0;i<_item_queues.size();++i) - std::cerr << _item_queues[i]._items.size() << " " ; - std::cerr << std::endl; -} - -void pqiQoS::in_rsItem(void *ptr,int size,int priority) -{ - 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 ; - } - - _item_queues[priority].push(ptr,size,_id_counter++) ; - ++_nb_items ; - - if(_id_counter >= MAX_PACKET_COUNTER_VALUE) - _id_counter = 0 ; -} - -// int pqiQoS::gatherStatistics(std::vector& per_service_count,std::vector& per_priority_count) const -// { -// assert(per_priority_count.size() == 10) ; -// assert(per_service_count.size() == 65536) ; -// -// for(uint32_t i=0;i<_item_queues.size();++i) -// { -// per_priority_count[i] += _item_queues[i].size() ; -// -// for(std::list::const_iterator it(_item_queues[i]._items.begin());it!=_item_queues[i]._items.end();++it) -// { -// uint32_t type = 0; -// uint32_t offset = 0; -// getRawUInt32((uint8_t*)(*it), 4, &offset, &type); -// -// uint16_t service_id = (type >> 8) & 0xffff ; -// -// ++per_service_count[service_id] ; -// } -// } -// return 1 ; -// } - - -void *pqiQoS::out_rsItem(uint32_t max_slice_size, uint32_t& size, bool& starts, bool& ends, uint32_t& packet_id) -{ - // Go through the queues. Increment counters. - - if(_nb_items == 0) - return NULL ; - - float inc = 1.0f ; - int i = _item_queues.size()-1 ; - - while(i > 0 && _item_queues[i]._items.empty()) - --i, inc = _item_queues[i]._inc ; - - int last = i ; - - for(int j=i;j>=0;--j) - if( (!_item_queues[j]._items.empty()) && ((_item_queues[j]._counter += inc) >= _item_queues[j]._threshold )) - { - last = j ; - _item_queues[j]._counter -= _item_queues[j]._threshold ; - } - - if(last >= 0) - { -#ifdef DEBUG - assert(_nb_items > 0) ; -#endif - - // now chop a slice of this item - - void *res = _item_queues[last].slice(max_slice_size,size,starts,ends,packet_id) ; - - if(ends) - --_nb_items ; - - return res ; - } - else - return NULL ; -} - - - - - diff --git a/libretroshare/src/pqi/pqiqos.h b/libretroshare/src/pqi/pqiqos.h deleted file mode 100644 index 74ff8ba77..000000000 --- a/libretroshare/src/pqi/pqiqos.h +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiqos.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// This class handles the prioritisation of RsItem, based on the -// priority level. The QoS algorithm must ensure that: -// -// - lower priority items get out with lower rate than high priority items -// - items of equal priority get out of the queue in the same order than they got in -// - items of level n+1 are output \alpha times more often than items of level n. -// \alpha is a constant that is not necessarily an integer, but strictly > 1. -// - the set of possible priority levels is finite, and pre-determined. -// -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -class pqiQoS -{ -public: - pqiQoS(uint32_t max_levels,float alpha) ; - - struct ItemRecord - { - void *data ; - uint32_t current_offset ; - uint32_t size ; - uint32_t id ; - }; - - class ItemQueue - { - public: - ItemQueue() - : _threshold(0.0) - , _counter(0.0) - , _inc(0.0) - {} - void *pop() - { - if(_items.empty()) - return NULL ; - - void *item = _items.front().data ; - _items.pop_front() ; - - return item ; - } - - void *slice(uint32_t max_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id) - { - if(_items.empty()) - return NULL ; - - ItemRecord& rec(_items.front()) ; - packet_id = rec.id ; - - // readily get rid of the item if it can be sent as a whole - - if(rec.current_offset == 0 && rec.size < max_size) - { - starts = true ; - ends = true ; - size = rec.size ; - - return pop() ; - } - starts = (rec.current_offset == 0) ; - ends = (rec.current_offset + max_size >= rec.size) ; - - if(rec.size <= rec.current_offset) - { - std::cerr << "(EE) severe error in slicing in QoS." << std::endl; - pop() ; - return NULL ; - } - - size = std::min(max_size, uint32_t((int)rec.size - (int)rec.current_offset)) ; - void *mem = rs_malloc(size) ; - - if(!mem) - { - std::cerr << "(EE) memory allocation error in QoS." << std::endl; - pop() ; - return NULL ; - } - - memcpy(mem,&((unsigned char*)rec.data)[rec.current_offset],size) ; - - if(ends) // we're taking the whole stuff. So we can delete the entry. - { - free(rec.data) ; - _items.pop_front() ; - } - else - rec.current_offset += size ; // by construction, !ends implies rec.current_offset < rec.size - - return mem ; - } - - void push(void *item,uint32_t size,uint32_t id) - { - ItemRecord rec ; - - rec.data = item ; - rec.current_offset = 0 ; - rec.size = size ; - rec.id = id ; - - _items.push_back(rec) ; - } - - uint32_t size() const { return _items.size() ; } - - float _threshold ; - float _counter ; - float _inc ; - - std::list _items ; - }; - - // This function pops items from the queue, y order of priority - // - void *out_rsItem(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id) ; - - // This function is used to queue items. - // - void in_rsItem(void *item, int size, int priority) ; - - void print() const ; - uint64_t qos_queue_size() const { return _nb_items ; } - - // kills all waiting items. - void clear() ; - - // get some stats about what's going on. service_packets will contain the number of - // packets per service, and queue_sizes will contain the size of the different priority queues. - - //int gatherStatistics(std::vector& per_service_count,std::vector& per_priority_count) const ; - - void computeTotalItemSize() const ; - int debug_computeTotalItemSize() const ; -private: - // This vector stores the lists of items with equal priorities. - // - std::vector _item_queues ; - float _alpha ; - uint64_t _nb_items ; - uint32_t _id_counter ; - - static const uint32_t MAX_PACKET_COUNTER_VALUE ; -}; - - diff --git a/libretroshare/src/pqi/pqiqosstreamer.cc b/libretroshare/src/pqi/pqiqosstreamer.cc deleted file mode 100644 index 2818b3ee7..000000000 --- a/libretroshare/src/pqi/pqiqosstreamer.cc +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiqosstreamer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2012 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqiqosstreamer.h" - -//#define DEBUG_PQIQOSSTREAMER 1 - -const float pqiQoSstreamer::PQI_QOS_STREAMER_ALPHA = 2.0f ; - -pqiQoSstreamer::pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin) - : pqithreadstreamer(parent,rss,peerid,bio_in,bio_flagsin), pqiQoS(PQI_QOS_STREAMER_MAX_LEVELS, PQI_QOS_STREAMER_ALPHA) -{ - _total_item_size = 0 ; - _total_item_count = 0 ; -} - -int pqiQoSstreamer::getQueueSize(bool in) -{ - if(in) - return pqistreamer::getQueueSize(in) ; - else - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - return qos_queue_size() ; - } -} - -//int pqiQoSstreamer::locked_gatherStatistics(std::vector& per_service_count,std::vector& per_priority_count) const // extracting data. -//{ -// return pqiQoS::gatherStatistics(per_service_count,per_priority_count) ; -//} - -void pqiQoSstreamer::locked_storeInOutputQueue(void *ptr,int size,int priority) -{ - _total_item_size += size ; - ++_total_item_count ; - - pqiQoS::in_rsItem(ptr,size,priority) ; -} - -void pqiQoSstreamer::locked_clear_out_queue() -{ -#ifdef DEBUG_PQIQOSSTREAMER - if(qos_queue_size() > 0) - std::cerr << " pqiQoSstreamer::locked_clear_out_queue(): clearing " << qos_queue_size() << " pending outqueue elements." << std::endl; -#endif - - pqiQoS::clear() ; - _total_item_size = 0 ; - _total_item_count = 0 ; -} - -void *pqiQoSstreamer::locked_pop_out_data(uint32_t max_slice_size, uint32_t& size, bool& starts, bool& ends, uint32_t& packet_id) -{ - void *out = pqiQoS::out_rsItem(max_slice_size,size,starts,ends,packet_id) ; - - if(out != NULL) - { - _total_item_size -= size ; - - if(ends) - --_total_item_count ; - } - - return out ; -} - diff --git a/libretroshare/src/pqi/pqiqosstreamer.h b/libretroshare/src/pqi/pqiqosstreamer.h deleted file mode 100644 index 5964b6cbe..000000000 --- a/libretroshare/src/pqi/pqiqosstreamer.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiqosstreamer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2012 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "pqiqos.h" -#include "pqithreadstreamer.h" - -class pqiQoSstreamer: public pqithreadstreamer, public pqiQoS -{ - public: - pqiQoSstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin); - - static const uint32_t PQI_QOS_STREAMER_MAX_LEVELS = 10 ; - static const float PQI_QOS_STREAMER_ALPHA ; - - virtual void locked_storeInOutputQueue(void *ptr, int size, int priority) ; - virtual int locked_out_queue_size() const { return _total_item_count ; } - virtual void locked_clear_out_queue() ; - virtual int locked_compute_out_pkt_size() const { return _total_item_size ; } - virtual void *locked_pop_out_data(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id); - //virtual int locked_gatherStatistics(std::vector& per_service_count,std::vector& per_priority_count) const; // extracting data. - - - virtual int getQueueSize(bool in) ; - - private: - uint32_t _total_item_size ; - uint32_t _total_item_count ; -}; - diff --git a/libretroshare/src/pqi/pqiservice.cc b/libretroshare/src/pqi/pqiservice.cc deleted file mode 100644 index 86336631a..000000000 --- a/libretroshare/src/pqi/pqiservice.cc +++ /dev/null @@ -1,219 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqiservice.h" -#include "util/rsdebug.h" -#include "util/rsstring.h" - -#include -#include -static double getCurrentTS() -{ -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} - -#ifdef SERVICE_DEBUG -const int pqiservicezone = 60478; -#endif - -/**** - * #define SERVICE_DEBUG 1 - ****/ - -void pqiService::setServiceServer(p3ServiceServerIface *server) -{ - mServiceServer = server; -} - -bool pqiService::send(RsRawItem *item) -{ - return mServiceServer->sendItem(item); -} - - -p3ServiceServer::p3ServiceServer(pqiPublisher *pub, p3ServiceControl *ctrl) : mPublisher(pub), mServiceControl(ctrl), srvMtx("p3ServiceServer") -{ - RS_STACK_MUTEX(srvMtx); /********* LOCKED *********/ - -#ifdef SERVICE_DEBUG - pqioutput(PQL_DEBUG_BASIC, pqiservicezone, - "p3ServiceServer::p3ServiceServer()"); -#endif - - return; -} - -int p3ServiceServer::addService(pqiService *ts, bool defaultOn) -{ - RS_STACK_MUTEX(srvMtx); /********* LOCKED *********/ - -#ifdef SERVICE_DEBUG - pqioutput(PQL_DEBUG_BASIC, pqiservicezone, - "p3ServiceServer::addService()"); -#endif - - RsServiceInfo info = ts->getServiceInfo(); - std::map::iterator it; - it = services.find(info.mServiceType); - if (it != services.end()) - { - std::cerr << "p3ServiceServer::addService(): Service already added with id " << info.mServiceType << "!" << std::endl; - // it exists already! - return -1; - } - - ts->setServiceServer(this); - services[info.mServiceType] = ts; - - // This doesn't need to be in Mutex. - mServiceControl->registerService(info,defaultOn); - - return 1; -} - -bool p3ServiceServer::getServiceItemNames(uint32_t service_type,std::map& names) -{ - RS_STACK_MUTEX(srvMtx); /********* LOCKED *********/ - - std::map::iterator it=services.find(service_type) ; - - if(it != services.end()) - { - it->second->getItemNames(names) ; - return true ; - } - else - return false ; -} - -int p3ServiceServer::removeService(pqiService *ts) -{ - RS_STACK_MUTEX(srvMtx); /********* LOCKED *********/ - -#ifdef SERVICE_DEBUG - pqioutput(PQL_DEBUG_BASIC, pqiservicezone, "p3ServiceServer::removeService()"); -#endif - - RsServiceInfo info = ts->getServiceInfo(); - - // This doesn't need to be in Mutex. - mServiceControl->deregisterService(info.mServiceType); - - std::map::iterator it = services.find(info.mServiceType); - if (it == services.end()) - { - std::cerr << "p3ServiceServer::removeService(): Service not found with id " << info.mServiceType << "!" << std::endl; - return -1; - } - - services.erase(it); - - return 1; -} - -bool p3ServiceServer::recvItem(RsRawItem *item) -{ - // Packet Filtering. - // This doesn't need to be in Mutex. - if (!mServiceControl->checkFilter(item->PacketId() & 0xffffff00, item->PeerId())) - { - delete item; - return false; - } - - pqiService *s = NULL; - - // access the service map under mutex lock - { - RS_STACK_MUTEX(srvMtx); - auto it = services.find(item -> PacketId() & 0xffffff00); - if (it == services.end()) - { - delete item; - return false; - } - s = it->second; - } - - // then call recv off mutex - bool result = s->recv(item); - return result; -} - -bool p3ServiceServer::sendItem(RsRawItem *item) -{ -#ifdef SERVICE_DEBUG - std::cerr << "p3ServiceServer::sendItem()"; - std::cerr << std::endl; - item -> print(std::cerr); - std::cerr << std::endl; -#endif - if (!item) - { - std::cerr << "p3ServiceServer::sendItem() Caught Null item"; - std::cerr << std::endl; - return false; - } - - // Packet Filtering. - if (!mServiceControl->checkFilter(item->PacketId() & 0xffffff00, item->PeerId())) - { -#ifdef SERVICE_DEBUG - std::cerr << "p3ServiceServer::sendItem() Fails Filtering for packet id=" << std::hex << item->PacketId() << std::dec << ", and peer " << item->PeerId() << std::endl; -#endif - delete item; - return false; - } - - mPublisher->sendItem(item); - - return true; -} - -int p3ServiceServer::tick() -{ - mServiceControl->tick(); - - // make a copy of the service map - std::map local_map; - { - RS_STACK_MUTEX(srvMtx); - local_map=services; - } - - // tick all services off mutex - for(auto it(local_map.begin());it!=local_map.end();++it) - { - (it->second)->tick(); - } - - return 1; - -} diff --git a/libretroshare/src/pqi/pqiservice.h b/libretroshare/src/pqi/pqiservice.h deleted file mode 100644 index ad983266e..000000000 --- a/libretroshare/src/pqi/pqiservice.h +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQI_SERVICE_HEADER -#define PQI_SERVICE_HEADER - -#include "pqi/pqi.h" -#include "pqi/pqi_base.h" -#include "util/rsthreads.h" - -#include "retroshare/rsservicecontrol.h" -#include "pqi/p3servicecontrol.h" - -// PQI Service, is a generic lower layer on which services can run on. -// -// these packets get passed through the -// server, to a service that is registered. -// -// example services: -// proxytunnel. -> p3proxy. -// sockettunnel -// -> either broadcast (attach to -// open socket instead -// of broadcast address) -// -> or requested/signon. -// -// games, -// voice -// video -// -// -// DataType is defined in the serialiser directory. - -class RsRawItem; -class p3ServiceServerIface; - - -class pqiService -{ -protected: - - pqiService() // our type of packets. - :mServiceServer(NULL) { return; } - - virtual ~pqiService() { return; } - -public: - void setServiceServer(p3ServiceServerIface *server); - // - virtual bool recv(RsRawItem *) = 0; - virtual bool send(RsRawItem *item); - - virtual RsServiceInfo getServiceInfo() = 0; - - virtual int tick() { return 0; } - - virtual void getItemNames(std::map& /*names*/) const {} // This does nothing by default. Service should derive it in order to give info for the UI - -private: - p3ServiceServerIface *mServiceServer; // const, no need for mutex. -}; - -#include - -/* We are pushing the packets back through p3ServiceServer, - * so that we can filter services at this level later... - * if we decide not to do this, pqiService can call through - * to the base level pqiPublisher instead. - */ - -// use interface to allow DI -class p3ServiceServerIface -{ -public: - - virtual ~p3ServiceServerIface() {} - - - virtual bool recvItem(RsRawItem *) = 0; - virtual bool sendItem(RsRawItem *) = 0; - - virtual bool getServiceItemNames(uint32_t service_type,std::map& names) =0; -}; - -class p3ServiceServer : public p3ServiceServerIface -{ -public: - p3ServiceServer(pqiPublisher *pub, p3ServiceControl *ctrl); - - int addService(pqiService *, bool defaultOn); - int removeService(pqiService *); - - bool recvItem(RsRawItem *); - bool sendItem(RsRawItem *); - - bool getServiceItemNames(uint32_t service_type, std::map& names) ; - - int tick(); -public: - -private: - - pqiPublisher *mPublisher; // constant no need for mutex. - p3ServiceControl *mServiceControl; - - RsMutex srvMtx; - std::map services; - -}; - - -#endif // PQI_SERVICE_HEADER diff --git a/libretroshare/src/pqi/pqiservicemonitor.h b/libretroshare/src/pqi/pqiservicemonitor.h deleted file mode 100644 index c101feac4..000000000 --- a/libretroshare/src/pqi/pqiservicemonitor.h +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiservicemonitor.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef PQI_SERVICE_MONITOR_H -#define PQI_SERVICE_MONITOR_H - -#include -#include -#include -#include - -/* ACTIONS */ -const uint32_t RS_SERVICE_PEER_NEW = 0x0001; /* new Peer */ -const uint32_t RS_SERVICE_PEER_CONNECTED = 0x0002; /* service connected */ -const uint32_t RS_SERVICE_PEER_DISCONNECTED = 0x0010; -const uint32_t RS_SERVICE_PEER_REMOVED = 0x0020; - -class pqiServicePeer -{ - public: - RsPeerId id; - uint32_t actions; -}; - - -class pqiServiceMonitor -{ - public: - pqiServiceMonitor() { return; } -virtual ~pqiServiceMonitor() { return; } - - /*! - * this serves as a call back function for server which has - * a handle on the subclass and updates this subclass on the - * action of peer's of the client (state and action information) - * - *@param plist contains list of states and actions of the client's peers - */ -virtual void statusChange(const std::list &plist) = 0; -}; - -#endif // PQI_SERVICE_MONITOR_H diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc deleted file mode 100644 index 76d447cc8..000000000 --- a/libretroshare/src/pqi/pqissl.cc +++ /dev/null @@ -1,1878 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissl.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqissl.h" -#include "pqi/pqinetwork.h" -#include "pqi/sslfns.h" - -#include "util/rsnet.h" -#include "util/rsdebug.h" -#include "util/rsstring.h" - -#include -#include -#include - -#include "pqi/pqissllistener.h" - -#include "pqi/p3linkmgr.h" -#include "retroshare/rspeers.h" -#include -#include - -#include "rsserver/p3face.h" - -static struct RsLog::logInfo pqisslzoneInfo = {RsLog::Default, "pqisslzone"}; -#define pqisslzone &pqisslzoneInfo - -/********* -#define WAITING_NOT 0 -#define WAITING_LOCAL_ADDR 1 -#define WAITING_REMOTE_ADDR 2 -#define WAITING_SOCK_CONNECT 3 -#define WAITING_SSL_CONNECTION 4 -#define WAITING_SSL_AUTHORISE 5 -#define WAITING_FAIL_INTERFACE 6 - -#define PQISSL_PASSIVE 0x00 -#define PQISSL_ACTIVE 0x01 - -const int PQISSL_LOCAL_FLAG = 0x01; -const int PQISSL_REMOTE_FLAG = 0x02; -const int PQISSL_UDP_FLAG = 0x02; -***********/ - -//#define PQISSL_DEBUG 1 -//#define PQISSL_LOG_DEBUG 1 -//#define PQISSL_LOG_DEBUG2 1 - -static const int PQISSL_MAX_READ_ZERO_COUNT = 20; -static const rstime_t PQISSL_MAX_READ_ZERO_TIME = 15; // 15 seconds of no data => reset. (atm HeartBeat pkt sent 5 secs) - -static const int PQISSL_SSL_CONNECT_TIMEOUT = 30; - -/********** PQI SSL STUFF ****************************************** - * - * A little note on the notifyEvent(FAILED).... - * - * this is called from - * (1) reset if needed! - * (2) Determine_Remote_Address (when all options have failed). - * - * reset() is only called when a TCP/SSL connection has been - * established, and there is an error. If there is a failed TCP - * connection, then an alternative address can be attempted. - * - * reset() is called from - * (1) destruction. - * (2) disconnect() - * (3) bad waiting state. - * - * // TCP/or SSL connection already established.... - * (5) pqissl::SSL_Connection_Complete() <- okay -> cos we made a TCP connection already. - * (6) pqissl::accept() <- okay cos something went wrong. - * (7) moretoread()/cansend() <- okay cos - * - */ - -pqissl::pqissl(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) : - NetBinInterface(parent, parent->PeerId()), - mLinkMgr(lm), pqil(l), mSslMtx("pqissl"), active(false), certvalid(false), - waiting(WAITING_NOT), sslmode(PQISSL_ACTIVE), ssl_connection(NULL), - sockfd(-1), readpkt(NULL), pktlen(0), total_len(0), attempt_ts(0), - n_read_zero(0), mReadZeroTS(0), ssl_connect_timeout(0), mConnectDelay(0), - mConnectTS(0), mConnectTimeout(0), mTimeoutTS(0) -{ sockaddr_storage_clear(remote_addr); } - - pqissl::~pqissl() -{ - rslog(RSL_ALERT, pqisslzone, - "pqissl::~pqissl -> destroying pqissl"); - stoplistening(); /* remove from pqissllistener only */ - - rslog(RSL_ALERT, pqisslzone, "pqissl::~pqissl() -> calling reset()"); - reset(); - return; -} - - -/********** Implementation of NetInterface *************************/ - -int pqissl::connect(const struct sockaddr_storage &raddr) -{ - RS_STACK_MUTEX(mSslMtx); - - remote_addr = raddr; - return ConnectAttempt(); -} - -// tells pqilistener to listen for us. -int pqissl::listen() -{ - if (pqil) - { - return pqil -> addlistenaddr(PeerId(), this); - } - return 0; -} - -int pqissl::stoplistening() -{ - if (pqil) - { - pqil -> removeListenPort(PeerId()); - } - return 1; -} - -int pqissl::disconnect() -{ - rslog(RSL_ALERT, pqisslzone, "pqissl::disconnect() -> calling reset()"); - return reset(); -} - -int pqissl::getConnectAddress(struct sockaddr_storage &raddr) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - raddr = remote_addr; - // TODO. - return (!sockaddr_storage_isnull(remote_addr)); -} - -/* BinInterface version of reset() for pqistreamer */ -int pqissl::close() -{ - rslog(RSL_ALERT, pqisslzone, "pqissl::close() -> calling reset()"); - return reset(); -} - -// put back on the listening queue. -int pqissl::reset() -{ - RS_STACK_MUTEX(mSslMtx); - return reset_locked(); -} - -int pqissl::reset_locked() -{ - std::string outLog; - bool neededReset = false; - - - /* a reset shouldn't cause us to stop listening - * only reasons for stoplistening() are; - * - * (1) destruction. - * (2) connection. - * (3) WillListen state change - * - */ - - outLog += "pqissl::reset():" + PeerId().toStdString(); - rs_sprintf_append(outLog, " (A: %d", (int) active); - rs_sprintf_append(outLog, " FD: %d", sockfd); - rs_sprintf_append(outLog, " W: %d", waiting); - rs_sprintf_append(outLog, " SSL: %p) ", ssl_connection); -#ifdef PQISSL_LOG_DEBUG - outLog += "\n"; -#endif - - - if (ssl_connection != NULL) - { - //outLog << "pqissl::reset() Shutting down SSL Connection"; - //outLog << std::endl; - SSL_shutdown(ssl_connection); - SSL_free (ssl_connection); - - neededReset = true; - } - - if (sockfd > 0) - { -#ifdef PQISSL_LOG_DEBUG - outLog += "pqissl::reset() Shutting down (active) socket\n"; -#endif - net_internal_close(sockfd); - sockfd = -1; - neededReset = true; - } - active = false; - sockfd = -1; - waiting = WAITING_NOT; - ssl_connection = NULL; - n_read_zero = 0; - mReadZeroTS = 0; - total_len = 0 ; - mTimeoutTS = 0; - - if (neededReset) - { -#ifdef PQISSL_LOG_DEBUG - outLog += "pqissl::reset() Reset Required!\n"; - outLog += "pqissl::reset() Will Attempt notifyEvent(FAILED)\n"; -#endif - } - -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_ALERT, pqisslzone, outLog); -#endif - - // notify people of problem! - // but only if we really shut something down. - if (neededReset) - { - // clean up the streamer - if (parent()) - { - struct sockaddr_storage addr; - sockaddr_storage_clear(addr); - parent() -> notifyEvent(this, NET_CONNECT_FAILED, addr); - } - } - return 1; -} - -bool pqissl::connect_parameter(uint32_t type, uint32_t value) -{ -#ifdef PQISSL_LOG_DEBUG - std::cerr << "pqissl::connect_parameter() Peer: " << PeerId(); -#endif - - switch(type) - { - case NET_PARAM_CONNECT_DELAY: - { -#ifdef PQISSL_LOG_DEBUG - std::cerr << " DELAY: " << value << std::endl; -#endif - RS_STACK_MUTEX(mSslMtx); - mConnectDelay = value; - return true; - } - case NET_PARAM_CONNECT_TIMEOUT: - { -#ifdef PQISSL_LOG_DEBUG - std::cerr << " TIMEOUT: " << value << std::endl; -#endif - RS_STACK_MUTEX(mSslMtx); - mConnectTimeout = value; - return true; - } - default: - { -#ifdef PQISSL_LOG_DEBUG - std::cerr << " type: " << type << " value: " << value << std::endl; -#endif - return false; - } - } -} - - -/********** End of Implementation of NetInterface ******************/ -/********** Implementation of BinInterface ************************** - * Only status() + tick() are here ... as they are really related - * to the NetInterface, and not the BinInterface, - * - */ - -void pqissl::getCryptoParams(RsPeerCryptoParams& params) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - if(active) - { - params.connexion_state = 1 ; - - char *desc = SSL_CIPHER_description(SSL_get_current_cipher(ssl_connection), NULL, 0); - params.cipher_name = std::string(desc); - OPENSSL_free(desc); - } - else - { - params.connexion_state = 0 ; - params.cipher_name.clear() ; - } -} - -bool pqissl::actAsServer() -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - return (bool)ssl_connection->server; -#else - return (bool)SSL_is_server(ssl_connection); -#endif -} - -/* returns ... - * -1 if inactive. - * 0 if connecting. - * 1 if connected. - */ - -int pqissl::status() -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - -#ifdef PQISSL_LOG_DEBUG - std::string out = "pqissl::status()"; - - if (active) - { - int alg; - - out += " active: \n"; - // print out connection. - out += "Connected TO : " + PeerId().toStdString() + "\n"; - // print out cipher. - rs_sprintf_append(out, "\t\tSSL Cipher:%s", SSL_get_cipher(ssl_connection)); - rs_sprintf_append(out, " (%d:%d)", SSL_get_cipher_bits(ssl_connection, &alg), alg); - rs_sprintf_append(out, "Vers:%s\n\n", SSL_get_cipher_version(ssl_connection)); - } - else - { - out += " Waiting for connection!\n"; - } - - rslog(RSL_DEBUG_BASIC, pqisslzone, out); -#endif - - if (active) - { - return 1; - } - else if (waiting > 0) - { - return 0; - } - return -1; -} - - // tick...... -int pqissl::tick() -{ - // there is no reason to lock pqissl mutex now - // we will lock the mutex later if we actually need to call to ConnectAttempt - // RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - // pqistreamer::tick(); - - // continue existing connection attempt. - if (!active) - { - // if we are waiting.. continue the connection (only) - if (waiting > 0) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, "pqissl::tick() Continuing Connection Attempt!"); -#endif - // now lock pqissl mutex, that will take up to 10 ms - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - ConnectAttempt(); - return 1; - } - } - return 1; -} - -/********** End of Implementation of BinInterface ******************/ -/********** Internals of SSL Connection ****************************/ - - -int pqissl::ConnectAttempt() -{ - switch(waiting) - { - case WAITING_NOT: - - sslmode = PQISSL_ACTIVE; /* we're starting this one */ - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() STATE = Not Waiting, starting connection"); -#endif - /* fallthrough */ - case WAITING_DELAY: - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() STATE = Waiting Delay, starting connection"); -#endif - - return Delay_Connection(); - //return Initiate_Connection(); /* now called by Delay_Connection() */ - - break; - - case WAITING_SOCK_CONNECT: - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() STATE = Waiting Sock Connect"); -#endif - - return Initiate_SSL_Connection(); - break; - - case WAITING_SSL_CONNECTION: - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() STATE = Waiting SSL Connection"); -#endif - - return Authorise_SSL_Connection(); - break; - - case WAITING_SSL_AUTHORISE: - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() STATE = Waiting SSL Authorise"); -#endif - - return Authorise_SSL_Connection(); - break; - case WAITING_FAIL_INTERFACE: - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() Failed - Retrying"); -#endif - - return Failed_Connection(); - break; - - - default: - rslog(RSL_ALERT, pqisslzone, - "pqissl::ConnectAttempt() STATE = Unknown - calling reset()"); - - reset_locked(); - break; - } - rslog(RSL_ALERT, pqisslzone, "pqissl::ConnectAttempt() Unknown"); - - return -1; -} - - -/****************************** FAILED ATTEMPT ****************************** - * Determine the Remote Address. - * - * Specifics: - * TCP / UDP - * TCP - check for which interface to use. - * UDP - check for request proxies.... - * - * X509 / XPGP - Same. - * - */ - -int pqissl::Failed_Connection() -{ -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::ConnectAttempt() Failed - Notifying"); -#endif - - if (parent()) - { - struct sockaddr_storage addr; - sockaddr_storage_clear(addr); - parent() -> notifyEvent(this, NET_CONNECT_UNREACHABLE, addr); - } - - waiting = WAITING_NOT; - - return 1; -} - -/****************************** MAKE CONNECTION ***************************** - * Open Socket and Initiate Connection. - * - * Specifics: - * TCP / UDP - * TCP - socket()/connect() - * UDP - tou_socket()/tou_connect() - * - * X509 / XPGP - Same. - * - */ - -int pqissl::Delay_Connection() -{ -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Delay_Connection() Attempting Outgoing Connection...."); -#endif - - if (waiting == WAITING_NOT) - { - waiting = WAITING_DELAY; - - /* we cannot just jump to Initiate_Connection, - * but must switch to WAITING_DELAY for at least one cycle. - * to avoid deadlock between threads.... - * ie. so the connection stuff is called from tick(), rather than connect() - */ - - /* set Connection TS. - */ -#ifdef PQISSL_LOG_DEBUG - { - std::string out; - rs_sprintf(out, "pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds", PeerId().toStdString(), mConnectDelay); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); - } -#endif - - mConnectTS = time(NULL) + mConnectDelay; - return 0; - } - else if (waiting == WAITING_DELAY) - { -#ifdef PQISSL_LOG_DEBUG - { - std::string out; - rs_sprintf(out, "pqissl::Delay_Connection() Connection to %s starting in %ld seconds", PeerId().toStdString(), mConnectTS - time(NULL)); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); - } -#endif - if (time(NULL) >= mConnectTS) - { - return Initiate_Connection(); - } - return 0; - } - - rslog(RSL_WARNING, pqisslzone, - "pqissl::Delay_Connection() Already Attempt in Progress!"); - return -1; -} - - -int pqissl::Initiate_Connection() -{ -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " " - << sockaddr_storage_tostring(remote_addr) << std::endl; -#endif - - int err; - sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr); - - if(waiting != WAITING_DELAY) - { - std::cerr << __PRETTY_FUNCTION__ << " Already Attempt in Progress!" - << std::endl; - return -1; - } - - // open socket connection to addr. - int osock = unix_socket(PF_INET6, SOCK_STREAM, 0); - -#ifdef PQISSL_LOG_DEBUG - { - std::string out; - rs_sprintf(out, "pqissl::Initiate_Connection() osock = %d", osock); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); - } -#endif - - if (osock < 0) - { - std::string out = "pqissl::Initiate_Connection() Failed to open socket!\n"; - out += "Socket Error:" + socket_errorType(errno); - rslog(RSL_WARNING, pqisslzone, out); - - net_internal_close(osock); - waiting = WAITING_FAIL_INTERFACE; - return -1; - } - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_Connection() Making Non-Blocking"); -#endif - - err = unix_fcntl_nonblock(osock); - if (err < 0) - { - std::string out; - rs_sprintf(out, "pqissl::Initiate_Connection() Error: Cannot make socket NON-Blocking: %d", err); - rslog(RSL_WARNING, pqisslzone, out); - - waiting = WAITING_FAIL_INTERFACE; - net_internal_close(osock); - return -1; - } - - if (sockaddr_storage_isnull(addr)) - { - rslog(RSL_WARNING, pqisslzone, "pqissl::Initiate_Connection() Invalid (0.0.0.0) Remote Address, Aborting Connect."); - waiting = WAITING_FAIL_INTERFACE; - net_internal_close(osock); - return -1; - } - -#ifdef WINDOWS_SYS - /* Set TCP buffer size for Windows systems */ - - int sockbufsize = 0; - int size = sizeof(int); - - err = getsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &size); -#ifdef PQISSL_DEBUG - if (err == 0) { - std::cerr << "pqissl::Initiate_Connection: Current TCP receive buffer size " << sockbufsize << std::endl; - } else { - std::cerr << "pqissl::Initiate_Connection: Error getting TCP receive buffer size. Error " << err << std::endl; - } -#endif - - sockbufsize = 0; - - err = getsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, &size); -#ifdef PQISSL_DEBUG - if (err == 0) { - std::cerr << "pqissl::Initiate_Connection: Current TCP send buffer size " << sockbufsize << std::endl; - } else { - std::cerr << "pqissl::Initiate_Connection: Error getting TCP send buffer size. Error " << err << std::endl; - } -#endif - - sockbufsize = WINDOWS_TCP_BUFFER_SIZE; - - err = setsockopt(osock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, sizeof(sockbufsize)); -#ifdef PQISSL_DEBUG - if (err == 0) { - std::cerr << "pqissl::Initiate_Connection: TCP receive buffer size set to " << sockbufsize << std::endl; - } else { - std::cerr << "pqissl::Initiate_Connection: Error setting TCP receive buffer size. Error " << err << std::endl; - } -#endif - - err = setsockopt(osock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, sizeof(sockbufsize)); -#ifdef PQISSL_DEBUG - if (err == 0) { - std::cerr << "pqissl::Initiate_Connection: TCP send buffer size set to " << sockbufsize << std::endl; - } else { - std::cerr << "pqissl::Initiate_Connection: Error setting TCP send buffer size. Error " << err << std::endl; - } -#endif -#endif // WINDOWS_SYS - - /* Systems that supports dual stack sockets defines IPV6_V6ONLY and some set - * it to 1 by default. This enable dual stack socket on such systems. - * Systems which don't support dual stack (only Windows older then XP SP3) - * will support IPv6 only and not IPv4 */ -#ifdef IPV6_V6ONLY - int no = 0; - err = rs_setsockopt( osock, IPPROTO_IPV6, IPV6_V6ONLY, - reinterpret_cast(&no), sizeof(no) ); -#ifdef PQISSL_DEBUG - if (err) std::cerr << __PRETTY_FUNCTION__ - << " Error setting IPv6 socket dual stack: " - << errno << " " << strerror(errno) << std::endl; - else std::cerr << __PRETTY_FUNCTION__ - << " Setting IPv6 socket dual stack" << std::endl; -#endif // PQISSL_DEBUG -#endif // IPV6_V6ONLY - - mTimeoutTS = time(NULL) + mConnectTimeout; - //std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl; - - sockaddr_storage_ipv4_to_ipv6(addr); -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Connecting To: " - << PeerId().toStdString() <<" via: " - << sockaddr_storage_tostring(addr) << std::endl; -#endif - - if (0 != (err = unix_connect(osock, addr))) - { - switch (errno) - { - case EINPROGRESS: - waiting = WAITING_SOCK_CONNECT; - sockfd = osock; - return 0; - default: -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Failure connect " - << sockaddr_storage_tostring(addr) - << " returns: " - << err << " -> errno: " << errno << " " - << socket_errorType(errno) << std::endl; -#endif - - net_internal_close(osock); - osock = -1; - waiting = WAITING_FAIL_INTERFACE; - return -1; - } - } - - waiting = WAITING_SOCK_CONNECT; - sockfd = osock; - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_Connection() Waiting for Socket Connect"); -#endif - - return 1; -} - - -/****************************** CHECK SOCKET ***************************** - * Check the Socket. - * - * select() and getsockopt(). - * - * Specifics: - * TCP / UDP - * TCP - select()/getsockopt() - * UDP - tou_error() - * - * X509 / XPGP - Same. - * - */ - -bool pqissl::CheckConnectionTimeout() -{ - /* new TimeOut code. */ - if (time(NULL) > mTimeoutTS) - { - std::string out; - rs_sprintf(out, "pqissl::Basic_Connection_Complete() Connection Timed Out. Peer: %s Period: %lu", PeerId().toStdString().c_str(), mConnectTimeout); - -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_WARNING, pqisslzone, out); -#endif - /* as sockfd is valid, this should close it all up */ - -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_ALERT, pqisslzone, "pqissl::Basic_Connection_Complete() -> calling reset()"); -#endif - reset_locked(); - return true; - } - return false; -} - - - -int pqissl::Basic_Connection_Complete() -{ -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete()..."); -#endif - - if (CheckConnectionTimeout()) - { - // calls reset. - return -1; - } - - if (waiting != WAITING_SOCK_CONNECT) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::Basic_Connection_Complete() Wrong Mode"); - return -1; - } - - if (sockfd == -1) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::Basic_Connection_Complete() problem with the socket descriptor. Aborting"); - rslog(RSL_ALERT, pqisslzone, "pqissl::Basic_Connection_Complete() -> calling reset()"); - reset_locked(); - return -1; - } - - // use select on the opened socket. - // Interestingly - This code might be portable.... - - fd_set ReadFDs, WriteFDs, ExceptFDs; - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); - FD_ZERO(&ExceptFDs); - - FD_SET(sockfd, &ReadFDs); - FD_SET(sockfd, &WriteFDs); - FD_SET(sockfd, &ExceptFDs); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete() Selecting ...."); -#endif - - int sr = 0; - if (0 > (sr = select(sockfd + 1, - &ReadFDs, &WriteFDs, &ExceptFDs, &timeout))) - { - // select error. - rslog(RSL_WARNING, pqisslzone, - "pqissl::Basic_Connection_Complete() Select ERROR(1)"); - - net_internal_close(sockfd); - sockfd=-1; - //reset(); - waiting = WAITING_FAIL_INTERFACE; - return -1; - } - -#ifdef PQISSL_LOG_DEBUG - { - std::string out; - rs_sprintf(out, "pqissl::Basic_Connection_Complete() Select returned %d", sr); - rslog(RSL_DEBUG_BASIC, pqisslzone, out); - } -#endif - - - if (FD_ISSET(sockfd, &ExceptFDs)) - { - // error - reset socket. - // this is a definite bad socket!. -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_WARNING, pqisslzone, - "pqissl::Basic_Connection_Complete() Select ERROR(2)"); -#endif - net_internal_close(sockfd); - sockfd=-1; - //reset(); - waiting = WAITING_FAIL_INTERFACE; - return -1; - } - - if (FD_ISSET(sockfd, &WriteFDs)) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete() Can Write!"); -#endif - } - else - { -#ifdef PQISSL_LOG_DEBUG - // happens frequently so switched to debug msg. - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete() Not Yet Ready!"); -#endif - return 0; - } - - if (FD_ISSET(sockfd, &ReadFDs)) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete() Can Read!"); -#endif - } - else - { -#ifdef PQISSL_LOG_DEBUG - // not ready return -1; - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Basic_Connection_Complete() Cannot Read!"); -#endif - } - - int err = 1; - if (0==unix_getsockopt_error(sockfd, &err)) - { - if (err == 0) - { - { - std::string out; - rs_sprintf(out, "pqissl::Basic_Connection_Complete() TCP Connection Complete: cert: %s on osock: ", PeerId().toStdString().c_str(), sockfd); -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_WARNING, pqisslzone, out); -#endif - } - return 1; - } - else if (err == EINPROGRESS) - { - rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() EINPROGRESS: cert: " + PeerId().toStdString()); - - return 0; - } - else if ((err == ENETUNREACH) || (err == ETIMEDOUT)) - { - rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() ENETUNREACH/ETIMEDOUT: cert: " + PeerId().toStdString()); - - // Then send unreachable message. - net_internal_close(sockfd); - sockfd=-1; - //reset(); - - waiting = WAITING_FAIL_INTERFACE; - - return -1; - } - else if ((err == EHOSTUNREACH) || (err == EHOSTDOWN)) - { -#ifdef PQISSL_DEBUG - rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() EHOSTUNREACH/EHOSTDOWN: cert: " + PeerId().toStdString()); -#endif - // Then send unreachable message. - net_internal_close(sockfd); - sockfd=-1; - //reset(); - waiting = WAITING_FAIL_INTERFACE; - - return -1; - } - else if (err == ECONNREFUSED) - { -#ifdef PQISSL_DEBUG - rslog(RSL_WARNING, pqisslzone, "pqissl::Basic_Connection_Complete() ECONNREFUSED: cert: " + PeerId().toStdString()); -#endif - - // Then send unreachable message. - net_internal_close(sockfd); - sockfd=-1; - //reset(); - waiting = WAITING_FAIL_INTERFACE; - - return -1; - } - - std::string out; - rs_sprintf(out, "Error: Connection Failed UNKNOWN ERROR: %d - %s", err, socket_errorType(err).c_str()); - rslog(RSL_WARNING, pqisslzone, out); - - net_internal_close(sockfd); - sockfd=-1; - //reset(); // which will send Connect Failed, - return -1; - } - - rslog(RSL_ALERT, pqisslzone, - "pqissl::Basic_Connection_Complete() BAD GETSOCKOPT!"); - waiting = WAITING_FAIL_INTERFACE; - - return -1; -} - - -int pqissl::Initiate_SSL_Connection() -{ - int err; - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_SSL_Connection() Checking Basic Connection"); -#endif - - if (0 >= (err = Basic_Connection_Complete())) - { - return err; - } - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_SSL_Connection() Basic Connection Okay"); -#endif - - // setup timeout value. - ssl_connect_timeout = time(NULL) + PQISSL_SSL_CONNECT_TIMEOUT; - - // Perform SSL magic. - // library already inited by sslroot(). - SSL *ssl = SSL_new(AuthSSL::getAuthSSL()->getCTX()); - if (ssl == NULL) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::Initiate_SSL_Connection() SSL_new failed!"); - - exit(1); - return -1; - } - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_SSL_Connection() SSL Connection Okay"); -#endif - - if(ssl_connection != NULL) - { - SSL_shutdown(ssl_connection); - SSL_free(ssl_connection) ; - } - - ssl_connection = ssl; - - net_internal_SSL_set_fd(ssl, sockfd); - if (err < 1) - { - std::string out = "pqissl::Initiate_SSL_Connection() SSL_set_fd failed!\n"; - printSSLError(ssl, err, SSL_get_error(ssl, err), ERR_get_error(), out); - - rslog(RSL_ALERT, pqisslzone, out); - } - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::Initiate_SSL_Connection() Waiting for SSL Connection"); -#endif - - waiting = WAITING_SSL_CONNECTION; - return 1; -} - -int pqissl::SSL_Connection_Complete() -{ -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::SSL_Connection_Complete()??? ... Checking"); -#endif - - if (waiting == WAITING_SSL_AUTHORISE) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::SSL_Connection_Complete() Waiting = W_SSL_AUTH"); - - return 1; - } - if (waiting != WAITING_SSL_CONNECTION) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::SSL_Connection_Complete() Still Waiting.."); - - return -1; - } - -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::SSL_Connection_Complete() Attempting SSL_connect"); -#endif - - /* if we are passive - then accept! */ - int err; - - if (sslmode == PQISSL_ACTIVE) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, "--------> Active Connect! Client side."); -#endif - err = SSL_connect(ssl_connection); - } - else - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, "--------> Passive Accept! Server side."); -#endif - err = SSL_accept(ssl_connection); - } - - if (err != 1) - { - int serr = SSL_get_error(ssl_connection, err); - if ((serr == SSL_ERROR_WANT_READ) || (serr == SSL_ERROR_WANT_WRITE)) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "Waiting for SSL handshake!"); -#endif - - waiting = WAITING_SSL_CONNECTION; - return 0; - } - - if(rsEvents) - { - X509 *x509 = SSL_get_peer_certificate(ssl_connection); - - if(x509) - { - auto ev = std::make_shared(); - ev->mSslId = RsX509Cert::getCertSslId(*x509); - ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION; - - if(!ev->mSslId.isNull()) - rsEvents->postEvent(ev); - } - } - - std::string out; - rs_sprintf(out, "pqissl::SSL_Connection_Complete()\nIssues with SSL Connect(%d)!\n", err); - printSSLError(ssl_connection, err, serr, ERR_get_error(), out); - - rslog(RSL_WARNING, pqisslzone, out); - - rslog(RSL_ALERT, pqisslzone, "pqissl::SSL_Connection_Complete() -> calling reset()"); - reset_locked(); - waiting = WAITING_FAIL_INTERFACE; - - return -1; - } - // if we get here... success v quickly. - - rslog(RSL_WARNING, pqisslzone, "pqissl::SSL_Connection_Complete() Success!: Peer: " + PeerId().toStdString()); - - waiting = WAITING_SSL_AUTHORISE; - return 1; -} - -int pqissl::Authorise_SSL_Connection() -{ - Dbg3() << __PRETTY_FUNCTION__ << std::endl; - - constexpr int failure = -1; - - if (time(nullptr) > ssl_connect_timeout) - { - RsInfo() << __PRETTY_FUNCTION__ << " Connection timed out reset!" - << std::endl; - reset_locked(); - } - - int err; - if (0 >= (err = SSL_Connection_Complete())) return err; - - Dbg3() << __PRETTY_FUNCTION__ << "SSL_Connection_Complete success." - << std::endl; - - // reset switch. - waiting = WAITING_NOT; - -#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK - X509* peercert = SSL_get_peer_certificate(ssl_connection); - if (!peercert) - { - RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer " - << "certificate at this point this should never happen!" - << std::endl; - print_stacktrace(); - exit(failure); - } - - RsPeerId certPeerId = RsX509Cert::getCertSslId(*peercert); - if (RsPeerId(certPeerId) != PeerId()) - { - RsErr() << __PRETTY_FUNCTION__ << " the cert Id doesn't match the peer " - << "id we're trying to connect to." << std::endl; - - /* TODO: Considering how difficult is managing to get a connection to a - * friend nowadays on the Internet because of evil NAT everywhere. - * If the cert is from a friend anyway we should find a way to make good - * use of this connection instead of throwing it away... */ - - X509_free(peercert); - reset_locked(); - return failure; - } - - /* At this point the actual connection authentication has already been - * performed in AuthSSL::VerifyX509Callback, any furter authentication check - * like the followings are redundant. */ - - bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(certPeerId); - - uint32_t authErrCode = 0; - if( !isSslOnlyFriend && !AuthSSL::instance().AuthX509WithGPG(peercert,false, authErrCode) ) - { - RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer " - << "certificate signature. This should never happen at this " - << "point!" << std::endl; - print_stacktrace(); - - X509_free(peercert); // not needed but just in case we change to return - exit(failure); - } - - RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) - { - RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId - << " is not friend. It is very unlikely to happen at this " - << "point! Either the user must have been so fast to deny " - << "friendship just after VerifyX509Callback have returned " - << "success and just before this code being executed, or " - << "something really fishy is happening! Share the full log " - << "with developers." << std::endl; - print_stacktrace(); - - X509_free(peercert); // not needed but just in case we change to return - exit(failure); - } -#endif // def RS_PQISSL_AUTH_REDUNDANT_CHECK - - Dbg2() << __PRETTY_FUNCTION__ << " Accepting connection to peer: " - << PeerId() << " with address: " << remote_addr << std::endl; - - return accept_locked(ssl_connection, sockfd, remote_addr); -} - - -/* This function is public, and callable from pqilistener - so must be mutex protected */ -int pqissl::accept( SSL *ssl, int fd, - const sockaddr_storage &foreign_addr) -{ -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - RS_STACK_MUTEX(mSslMtx); - return accept_locked(ssl, fd, foreign_addr); -} - -int pqissl::accept_locked( SSL *ssl, int fd, - const sockaddr_storage &foreign_addr ) -{ - Dbg3() << __PRETTY_FUNCTION__ << std::endl; - - constexpr int failure = -1; - constexpr int success = 1; - -#ifdef RS_PQISSL_BANLIST_DOUBLE_CHECK - /* At this point, as we are actively attempting the connection, we decide - * the address to which to connect to, banned addresses should never get - * here as the filtering for banned addresses happens much before, this - * check is therefore redundant, and if it trigger something really fishy - * must be happening (a bug somewhere else in the code). */ - uint32_t check_result; - uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST; - - if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL) - checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST; - - if( RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) != PeerId()) - std::cerr << "(EE) pqissl::accept_locked(): PeerId() is " << PeerId() << " but certificate ID is " << RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) << std::endl; - - if(rsBanList && !rsBanList->isAddressAccepted( foreign_addr, checking_flags, check_result )) - { - RsInfo() << __PRETTY_FUNCTION__ - << " Refusing incoming SSL connection from blacklisted " - << "foreign address " << foreign_addr - << ". Reason: " << check_result << ". This should never happen " - << "at this point! Please report full log to developers!" - << std::endl; - print_stacktrace(); - - if(rsEvents) - { - X509 *x509 = SSL_get_peer_certificate(ssl); - auto ev = std::make_shared(); - ev->mSslId = RsX509Cert::getCertSslId(*x509); - ev->mLocator = RsUrl(foreign_addr); - ev->mErrorCode = RsAuthSslError::IP_IS_BLACKLISTED; - rsEvents->postEvent(ev); - } - - reset_locked(); - return failure; - } -#endif //def RS_BANLIST_REDUNDANT_CHECK - - if (waiting != WAITING_NOT) - { - RsInfo() << __PRETTY_FUNCTION__ << " Peer: " << PeerId() - << " - Two connections in progress - Shut 1 down!" - << std::endl; - - // outgoing connection in progress. - // shut this baby down. - // - // Thought I should shut down one in progress, and continue existing one! - // But the existing one might be broke.... take second. - // all we need is to never stop listening. - - switch(waiting) - { - case WAITING_SOCK_CONNECT: -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting Sock Connect " - << "- close the socket" << std::endl; -#endif - break; - case WAITING_SSL_CONNECTION: -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL " - << "Connection - close sockfd + ssl_conn" << std::endl; -#endif - break; - case WAITING_SSL_AUTHORISE: -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " STATE = Waiting SSL Authorise" - << " - close sockfd + ssl_conn" << std::endl; -#endif - break; - case WAITING_FAIL_INTERFACE: -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " STATE = Failed, ignore?" - << std::endl; -#endif - break; - default: - std::cerr << __PRETTY_FUNCTION__ << " STATE = Unknown - resetting!" - << std::endl; - reset_locked(); - break; - } - } - - /* shutdown existing - in all cases use the new one */ - if ((ssl_connection) && (ssl_connection != ssl)) - { - RsInfo() << __PRETTY_FUNCTION__ - << " closing Previous/Existing ssl_connection" << std::endl; - SSL_shutdown(ssl_connection); - SSL_free (ssl_connection); - } - - if ((sockfd > -1) && (sockfd != fd)) - { - RsInfo() << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd" - << std::endl; - net_internal_close(sockfd); - } - - - // save ssl + sock. - - ssl_connection = ssl; - sockfd = fd; - - /* if we connected - then just writing the same over, - * but if from ssllistener then we need to save the address. - */ - sockaddr_storage_copy(foreign_addr, remote_addr); - - RsInfo() << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: " - << PeerId().toStdString() << " remoteaddr: " - << sockaddr_storage_iptostring(remote_addr) << std::endl; - -#ifdef PQISSL_DEBUG - { - int alg; - std::cerr << __PRETTY_FUNCTION__ << "SSL Cipher: " - << SSL_get_cipher(ssl) << std::endl << "SSL Cipher Bits: " - << SSL_get_cipher_bits(ssl, &alg) << " - " << alg - << std::endl; - } -#endif - - // make non-blocking / or check..... - int err; - if ((err = net_internal_fcntl_nonblock(sockfd)) < 0) - { - std::cerr << __PRETTY_FUNCTION__ << "Cannot make socket NON-Blocking " - << "reset!" << std::endl; - - active = false; - waiting = WAITING_FAIL_INTERFACE; // failed completely. - - reset_locked(); - return failure; - } -#ifdef PQISSL_DEBUG - else std::cerr << __PRETTY_FUNCTION__ << " Socket made non-nlocking!" - << std::endl; -#endif - - // we want to continue listening - incase this socket is crap, and they try again. - //stoplistening(); - - active = true; - waiting = WAITING_NOT; - -#ifdef PQISSL_DEBUG - std::cerr << __PRETTY_FUNCTION__ << "connection complete - notifying parent" - << std::endl; -#endif - - // Notify the pqiperson.... (Both Connect/Receive) - if (parent()) - { - // Is the copy necessary? - sockaddr_storage addr; sockaddr_storage_copy(remote_addr, addr); - parent()->notifyEvent(this, NET_CONNECT_SUCCESS, addr); - } - return success; -} - -/********** Implementation of BinInterface ************************** - * All the rest of the BinInterface. - * This functions much be Mutex protected. - * - */ - -int pqissl::senddata(void *data, int len) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - int tmppktlen ; - - // safety check. Apparently this avoids some SIGSEGV. - // - if(ssl_connection == NULL) - return -1; - -#ifdef PQISSL_DEBUG - std::cout << "Sending data thread=" << pthread_self() << ", ssl=" << (void*)this << ", size=" << len << std::endl ; -#endif - ERR_clear_error(); - tmppktlen = SSL_write(ssl_connection, data, len) ; - - if (len != tmppktlen) - { - std::string out = "pqissl::senddata() " + PeerId().toStdString(); - rs_sprintf_append(out, " Partial Send: len: %d sent: %d ", len, tmppktlen); - - int err = SSL_get_error(ssl_connection, tmppktlen); - // incomplete operations - to repeat.... - // handled by the pqistreamer... - if (err == SSL_ERROR_SYSCALL) - { - rs_sprintf_append(out, "SSL_write() SSL_ERROR_SYSCALL SOCKET_DEAD -> calling reset() errno: %d ", errno); - out += socket_errorType(errno); - std::cerr << out << std::endl; - rslog(RSL_ALERT, pqisslzone, out); - - /* extra debugging - based on SSL_get_error() man page */ - { - int errsys = errno; - int sslerr = 0; - std::string out2; - rs_sprintf(out2, "SSL_ERROR_SYSCALL, ret == %d errno: %d %s\n", tmppktlen, errsys, socket_errorType(errsys).c_str()); - - while(0 != (sslerr = ERR_get_error())) - { - rs_sprintf_append(out2, "SSLERR:%d:", sslerr); - - char sslbuf[256] = {0}; - out2 += ERR_error_string(sslerr, sslbuf); - out2 += "\n"; - } - rslog(RSL_ALERT, pqisslzone, out2); - } - - rslog(RSL_ALERT, pqisslzone, "pqissl::senddata() -> calling reset()"); - reset_locked(); - return -1; - } - else if (err == SSL_ERROR_WANT_WRITE) - { - out += "SSL_write() SSL_ERROR_WANT_WRITE"; - rslog(RSL_WARNING, pqisslzone, out); - return -1; - } - else if (err == SSL_ERROR_WANT_READ) - { - out += "SSL_write() SSL_ERROR_WANT_READ"; - rslog(RSL_WARNING, pqisslzone, out); - //std::cerr << out << std::endl; - return -1; - } - else - { - rs_sprintf_append(out, "SSL_write() UNKNOWN ERROR: %d\n", err); - printSSLError(ssl_connection, tmppktlen, err, ERR_get_error(), out); - out += "\n\tResetting!"; - std::cerr << out << std::endl; - rslog(RSL_ALERT, pqisslzone, out); - - rslog(RSL_ALERT, pqisslzone, "pqissl::senddata() -> calling reset()"); - reset_locked(); - return -1; - } - } - return tmppktlen; -} - -int pqissl::readdata(void *data, int len) -{ - RS_STACK_MUTEX(mSslMtx); - -#ifdef PQISSL_DEBUG - std::cout << "Reading data thread=" << pthread_self() << ", ssl=" - << (void*)this << std::endl; -#endif - - // Safety check. Apparently this avoids some SIGSEGV. - if (ssl_connection == NULL) return -1; - - // There is a do, because packets can be splitted into multiple ssl buffers - // when they are larger than 16384 bytes. Such packets have to be read in - // multiple slices. - do - { - int tmppktlen; - -#ifdef PQISSL_DEBUG - std::cerr << "calling SSL_read. len=" << len << ", total_len=" - << total_len << std::endl; -#endif - ERR_clear_error(); - - tmppktlen = SSL_read(ssl_connection, - (void*)( &(((uint8_t*)data)[total_len])), - len-total_len); - -#ifdef PQISSL_DEBUG - std::cerr << "have read " << tmppktlen << " bytes" << std::endl ; - std::cerr << "data[0] = " - << (int)((uint8_t*)data)[total_len+0] << " " - << (int)((uint8_t*)data)[total_len+1] << " " - << (int)((uint8_t*)data)[total_len+2] << " " - << (int)((uint8_t*)data)[total_len+3] << " " - << (int)((uint8_t*)data)[total_len+4] << " " - << (int)((uint8_t*)data)[total_len+5] << " " - << (int)((uint8_t*)data)[total_len+6] << " " - << (int)((uint8_t*)data)[total_len+7] << std::endl ; -#endif - - // Need to catch errors..... - if (tmppktlen <= 0) // probably needs a reset. - { - std::string out; - - int error = SSL_get_error(ssl_connection, tmppktlen); - unsigned long err2 = ERR_get_error(); - - if ((error == SSL_ERROR_ZERO_RETURN) && (err2 == 0)) - { - /* this code will be called when - * (1) moretoread -> returns true. + - * (2) SSL_read fails. - * - * There are two ways this can happen: - * (1) there is a little data on the socket, but not enough - * for a full SSL record, so there legimitately is no error, and the moretoread() - * was correct, but the read fails. - * - * (2) the socket has been closed correctly. this leads to moretoread() -> true, - * and ZERO error.... we catch this case by counting how many times - * it occurs in a row (cos the other one will not). - */ - if (n_read_zero == 0) - { - /* first read_zero */ - mReadZeroTS = time(NULL); - } - - ++n_read_zero; - out += "pqissl::readdata() " + PeerId().toStdString(); - rs_sprintf_append(out, " SSL_read() SSL_ERROR_ZERO_RETURN : nReadZero: %d", n_read_zero); - - if ((PQISSL_MAX_READ_ZERO_COUNT < n_read_zero) - && (time(NULL) - mReadZeroTS > PQISSL_MAX_READ_ZERO_TIME)) - { - out += " Count passed Limit, shutting down!"; - rs_sprintf_append(out, " ReadZero Age: %ld", time(NULL) - mReadZeroTS); - - rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()"); - reset_locked(); - } - -#ifdef PQISSL_LOG_DEBUG2 - rslog(RSL_ALERT, pqisslzone, out); -#endif - //std::cerr << out << std::endl ; - return -1; - } - - /* the only real error we expect */ - if (error == SSL_ERROR_SYSCALL) - { - out += "pqissl::readdata() " + PeerId().toStdString(); - out += " SSL_read() SSL_ERROR_SYSCALL"; - out += " SOCKET_DEAD -> calling reset()"; - rs_sprintf_append(out, " errno: %d", errno); - out += " " + socket_errorType(errno); - rslog(RSL_ALERT, pqisslzone, out); - - /* extra debugging - based on SSL_get_error() man page */ - { - int syserr = errno; - int sslerr = 0; - std::string out2; - rs_sprintf(out2, "SSL_ERROR_SYSCALL, ret == %d errno: %d %s\n", tmppktlen, syserr, socket_errorType(syserr).c_str()); - - while(0 != (sslerr = ERR_get_error())) - { - rs_sprintf_append(out2, "SSLERR:%d : ", sslerr); - - char sslbuf[256] = {0}; - out2 += ERR_error_string(sslerr, sslbuf); - out2 += "\n"; - } - rslog(RSL_ALERT, pqisslzone, out2); - } - - rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()"); - reset_locked(); - std::cerr << out << std::endl ; - return -1; - } - else if (error == SSL_ERROR_WANT_WRITE) - { - out += "SSL_read() SSL_ERROR_WANT_WRITE"; - rslog(RSL_WARNING, pqisslzone, out); - std::cerr << out << std::endl ; - return -1; - } - else if (error == SSL_ERROR_WANT_READ) - { - // SSL_WANT_READ is not a crittical error. It's just a sign that - // the internal SSL buffer is not ready to accept more data. So -1 - // is returned, and the connection will be retried as is on next - // call of readdata(). - -#ifdef PQISSL_DEBUG - out += "SSL_read() SSL_ERROR_WANT_READ"; - rslog(RSL_DEBUG_BASIC, pqisslzone, out); -#endif - return -1; - } - else - { - rs_sprintf_append(out, "SSL_read() UNKNOWN ERROR: %d Resetting!", error); - rslog(RSL_ALERT, pqisslzone, out); - std::cerr << out << std::endl ; - std::cerr << ", SSL_read() output is " << tmppktlen << std::endl ; - - printSSLError(ssl_connection, tmppktlen, error, err2, out); - - rslog(RSL_ALERT, pqisslzone, "pqissl::readdata() -> calling reset()"); - reset_locked(); - return -1; - } - - rslog(RSL_ALERT, pqisslzone, out); - //exit(1); - } - else - total_len+=tmppktlen ; - } while(total_len < len) ; - -#ifdef PQISSL_DEBUG - std::cerr << "pqissl: have read data of length " << total_len << ", expected is " << len << std::endl ; -#endif - - if (len != total_len) - { - std::string out; - rs_sprintf(out, "pqissl::readdata() Full Packet Not read!\n -> Expected len(%d) actually read(%d)", len, total_len); - std::cerr << out << std::endl; - rslog(RSL_WARNING, pqisslzone, out); - } - total_len = 0 ; // reset the packet pointer as we have finished a packet. - n_read_zero = 0; - return len;//tmppktlen; -} - - -// dummy function currently. -int pqissl::netstatus() -{ - return 1; -} - -int pqissl::isactive() -{ - return active; // no need to mutex this. It's atomic. -} - -bool pqissl::moretoread(uint32_t usec) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - -#ifdef PQISSL_DEBUG - { - std::string out; - rs_sprintf(out, "pqissl::moretoread() polling socket (%d)", sockfd); - rslog(RSL_DEBUG_ALL, pqisslzone, out); - } -#endif - - if(sockfd == -1) - { - std::cerr << "pqissl::moretoread(): socket is invalid or closed." << std::endl; - return 0 ; - } - - fd_set ReadFDs, WriteFDs, ExceptFDs; - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); - FD_ZERO(&ExceptFDs); - - FD_SET(sockfd, &ReadFDs); - // Dont set WriteFDs. - FD_SET(sockfd, &ExceptFDs); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = usec; - - if (select(sockfd + 1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout) < 0) - { - rslog(RSL_ALERT, pqisslzone, - "pqissl::moretoread() Select ERROR!"); - return 0; - } - - if (FD_ISSET(sockfd, &ExceptFDs)) - { - // error - reset socket. - rslog(RSL_ALERT, pqisslzone, - "pqissl::moretoread() Select Exception ERROR!"); - - // this is a definite bad socket!. - // reset. - rslog(RSL_ALERT, pqisslzone, "pqissl::moretoread() -> calling reset()"); - reset_locked(); - return 0; - } - - - if (FD_ISSET(sockfd, &ReadFDs)) - { -#ifdef PQISSL_LOG_DEBUG - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::moretoread() Data to Read!"); -#endif - return 1; - } - else if(SSL_pending(ssl_connection) > 0) - { - return 1 ; - } - else - { -#ifdef PQISSL_DEBUG - rslog(RSL_DEBUG_ALL, pqisslzone, - "pqissl::moretoread() No Data to Read!"); -#endif - return 0; - } - -} - -bool pqissl::cansend(uint32_t usec) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - -#ifdef PQISSL_DEBUG - rslog(RSL_DEBUG_ALL, pqisslzone, - "pqissl::cansend() polling socket!"); -#endif - - if(sockfd == -1) - { - std::cerr << "pqissl::cansend(): socket is invalid or closed." << std::endl; - return 0 ; - } - - // Interestingly - This code might be portable.... - - fd_set ReadFDs, WriteFDs, ExceptFDs; - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); - FD_ZERO(&ExceptFDs); - - // Dont Set ReadFDs. - FD_SET(sockfd, &WriteFDs); - FD_SET(sockfd, &ExceptFDs); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = usec; - - - if (select(sockfd + 1, &ReadFDs, &WriteFDs, &ExceptFDs, &timeout) < 0) - { - // select error. - rslog(RSL_ALERT, pqisslzone, - "pqissl::cansend() Select Error!"); - - return 0; - } - - if (FD_ISSET(sockfd, &ExceptFDs)) - { - // error - reset socket. - rslog(RSL_ALERT, pqisslzone, - "pqissl::cansend() Select Exception!"); - - // this is a definite bad socket!. - // reset. - rslog(RSL_ALERT, pqisslzone, "pqissl::cansend() -> calling reset()"); - reset_locked(); - return 0; - } - - if (FD_ISSET(sockfd, &WriteFDs)) - { -#ifdef PQISSL_DEBUG - // write can work. - rslog(RSL_DEBUG_ALL, pqisslzone, - "pqissl::cansend() Can Write!"); -#endif - return 1; - } - else - { -#ifdef PQISSL_DEBUG - // write can work. - rslog(RSL_DEBUG_BASIC, pqisslzone, - "pqissl::cansend() Can *NOT* Write!"); -#endif - - return 0; - } - -} - -RsFileHash pqissl::gethash() { return RsFileHash(); } - -/********** End of Implementation of BinInterface ******************/ - - -int pqissl::net_internal_close(int fd) -{ - return unix_close(fd); -} - -int pqissl::net_internal_SSL_set_fd(SSL *ssl, int fd) -{ - return SSL_set_fd(ssl, fd); -} - -int pqissl::net_internal_fcntl_nonblock(int fd) -{ - return unix_fcntl_nonblock(fd); -} diff --git a/libretroshare/src/pqi/pqissl.h b/libretroshare/src/pqi/pqissl.h deleted file mode 100644 index 30905be5e..000000000 --- a/libretroshare/src/pqi/pqissl.h +++ /dev/null @@ -1,274 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissl.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -// operating system specific network header. -#include "pqi/pqinetwork.h" - -#include -#include - -#include "pqi/pqi_base.h" -#include "pqi/authssl.h" - -#define RS_PQISSL_AUTH_DOUBLE_CHECK 1 - -#define RS_PQISSL_BANLIST_DOUBLE_CHECK 1 - - -#define WAITING_NOT 0 -#define WAITING_DELAY 1 -#define WAITING_SOCK_CONNECT 2 -#define WAITING_SSL_CONNECTION 3 -#define WAITING_SSL_AUTHORISE 4 -#define WAITING_FAIL_INTERFACE 5 - -#define PQISSL_PASSIVE 0x00 -#define PQISSL_ACTIVE 0x01 - -const int PQISSL_LOCAL_FLAG = 0x01; -const int PQISSL_REMOTE_FLAG = 0x02; -const int PQISSL_DNS_FLAG = 0x04; - -/* not sure about the value? */ -const int PQISSL_UDP_FLAG = 0x02; - -/* TCP buffer size for Windows systems */ -const int WINDOWS_TCP_BUFFER_SIZE = 512 * 1024; // 512 KB - - -// This is a (very) simple overview of the different state machnines. The tree includes high level funtions only. -// -// connect_parameter() is used to pass down settings, like address or timeout values -// -// tick() or connect() -// | -// +----- ConnectAttempt() -// | -// +--WAITING_NOT or WAITING_DELAY -// | | -// | +----- Delay_Connection() -// | | -// | +--WAITING_NOT -// | | - set 'waiting' to WAITING_DELAY and set delay for next connection attempt -// | | -// | +--WAITING_DELAY -// | | -// | +----- Initiate_Connection() -// | | -// | +----- setup socket -// | +----- connect -// | - on success: set "waiting" to WAITING_SOCK_CONNECT and "sockfd" to newly created socket -// | - on failure: set "waiting" to WAITING_FAIL_INTERFACE -// | -// +--WAITING_SOCK_CONNECT -// | | -// | +----- Initiate_SSL_Connection() -// | | -// | +----- Basic_Connection_Complete() -// | | | -// | | +----- CheckConnectionTimeout() -// | | | -// | | +----- ready up socket. -// | | - SOCKS, udp tou, i2p BOB intercept here -// | | - on failure: set "waiting" to WAITING_FAIL_INTERFACE and "sockfd" to -1 -// | | -// | +----- create SSL context and attach file descriptors -// | - on success:_set "waiting" to WAITING_SSL_CONNECTION -// | -// +--WAITING_SSL_CONNECTION or WAITING_SSL_AUTHORISE -// | | -// | +----- Authorise_SSL_Connection() -// | | -// | +----- SSL_Connection_Complete() -// | | | -// | | +----- performes TSL handshake -// | | - on success: set "waiting" to WAITING_SSL_AUTHORISE -// | | - on failure: set "waiting" to WAITING_FAIL_INTERFACE -// | | -// | +----- set "waiting" to WAITING_NOT -// | | -// | +----- accept_locked() -// | - add peer to the rest of RS and start pqi thread -// | -// | -// +--WAITING_FAIL_INTERFACE -// | -// +----- Failed_Connection() -// - set "waiting" to WAITING_NOT -// - - -/***************************** pqi Net SSL Interface ********************************* - * This provides the base SSL interface class, - * and handles most of the required functionality. - * - * there are a series of small fn's that can be overloaded - * to provide alternative behaviour.... - * - * Classes expected to inherit from this are: - * - * pqissllistener -> pqissllistener (tcp only) - * -> pqixpgplistener (tcp only) - * - * pqissl -> pqissltcp - * -> pqissludp - * -> pqixpgptcp - * -> pqixpgpudp - * - */ - -class pqissllistener; -class p3LinkMgr; -struct RsPeerCryptoParams; - -class pqissl: public NetBinInterface -{ -public: - pqissl(pqissllistener *l, PQInterface *parent, - p3LinkMgr *lm); -virtual ~pqissl(); - - // NetInterface -virtual int connect(const struct sockaddr_storage &raddr); -virtual int listen(); -virtual int stoplistening(); -virtual int reset(); -virtual int disconnect(); -virtual int getConnectAddress(struct sockaddr_storage &raddr); - -virtual bool connect_parameter(uint32_t /*type*/, const std::string & /*value*/) { return false; } -virtual bool connect_parameter(uint32_t type, uint32_t value); - - // BinInterface -virtual int tick(); -virtual int status(); - -virtual int senddata(void*, int); -virtual int readdata(void*, int); -virtual int netstatus(); -virtual int isactive(); -virtual bool moretoread(uint32_t usec); -virtual bool cansend(uint32_t usec); - -virtual int close(); /* BinInterface version of reset() */ -virtual RsFileHash gethash(); /* not used here */ -virtual bool bandwidthLimited() { return true ; } - -public: - -/// initiate incoming connection. -int accept(SSL *ssl, int fd, const struct sockaddr_storage &foreign_addr); - -void getCryptoParams(RsPeerCryptoParams& params) ; -bool actAsServer(); - - -protected: - - - /* no mutex protection for these ones */ - - p3LinkMgr *mLinkMgr; - pqissllistener *pqil; - - RsMutex mSslMtx; /**** MUTEX protects data and fn below ****/ - -virtual int reset_locked(); - - /// initiate incoming connection. - int accept_locked( SSL *ssl, int fd, - const sockaddr_storage& foreign_addr ); - - // A little bit of information to describe - // the SSL state, this is needed - // to allow full Non-Blocking Connect behaviour. - // This fn loops through the following fns. - // to complete an SSL. - -int ConnectAttempt(); - -virtual int Failed_Connection(); - - // Start up connection with delay... -virtual int Delay_Connection(); - - // These two fns are overloaded for udp/etc connections. -virtual int Initiate_Connection(); -virtual int Basic_Connection_Complete(); - - // These should be identical for all cases, - // differences are achieved via the net_internal_* fns. -int Initiate_SSL_Connection(); -int SSL_Connection_Complete(); -int Authorise_SSL_Connection(); - - // check connection timeout. -bool CheckConnectionTimeout(); - - - /* 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 */ - bool active; - bool certvalid; - - int waiting; - - // addition for udp (tcp version == ACTIVE). - int sslmode; - - SSL *ssl_connection; - int sockfd; - - struct sockaddr_storage remote_addr; - - void *readpkt; - int pktlen; - int total_len ; // saves the reading state accross successive calls. - - int attempt_ts; - - int n_read_zero; /* a counter to determine if the connection is really dead */ - rstime_t mReadZeroTS; /* timestamp of first READ_ZERO occurance */ - - int ssl_connect_timeout; /* timeout to ensure that we don't get stuck (can happen on udp!) */ - - uint32_t mConnectDelay; - rstime_t mConnectTS; - uint32_t mConnectTimeout; - rstime_t mTimeoutTS; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) - -private: - // ssl only fns. - int connectInterface(const struct sockaddr_storage &addr); -}; diff --git a/libretroshare/src/pqi/pqissli2pbob.cpp b/libretroshare/src/pqi/pqissli2pbob.cpp deleted file mode 100644 index 5551ce788..000000000 --- a/libretroshare/src/pqi/pqissli2pbob.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissli2pbob.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqissli2pbob.h" - -bool pqissli2pbob::connect_parameter(uint32_t type, const std::string &value) -{ - if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS) - { - RS_STACK_MUTEX(mSslMtx); - // a new line must be appended! - mI2pAddr = value + '\n'; - return true; - } - - return pqissl::connect_parameter(type, value); -} - -int pqissli2pbob::Basic_Connection_Complete() -{ - int ret; - - if ((ret = pqissl::Basic_Connection_Complete()) != 1) - { - // basic connection not complete. - return ret; - } - - // send addr. (new line is already appended) - ret = send(sockfd, mI2pAddr.c_str(), mI2pAddr.length(), 0); - if (ret != (int)mI2pAddr.length()) - return -1; - return 1; -} diff --git a/libretroshare/src/pqi/pqissli2pbob.h b/libretroshare/src/pqi/pqissli2pbob.h deleted file mode 100644 index b1a643a75..000000000 --- a/libretroshare/src/pqi/pqissli2pbob.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissli2pbob.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef PQISSLI2PBOB_H -#define PQISSLI2PBOB_H - -#include "pqi/pqissl.h" - -/* - * This class is a minimal varied version of pqissl to work with I2P BOB tunnels. - * The only difference is that the [.b32].i2p addresses must be sent first. - * - * Everything else is untouched. - */ - -class pqissli2pbob : public pqissl -{ -public: - pqissli2pbob(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) - : pqissl(l, parent, lm) {} - - // NetInterface interface -public: - bool connect_parameter(uint32_t type, const std::string &value); - - // pqissl interface -protected: - int Basic_Connection_Complete(); - -private: - std::string mI2pAddr; -}; - -#endif // PQISSLI2PBOB_H diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc deleted file mode 100644 index fa25bfe0b..000000000 --- a/libretroshare/src/pqi/pqissllistener.cc +++ /dev/null @@ -1,883 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissllistener.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * Copyright (C) 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "pqi/pqissl.h" -#include "pqi/pqissllistener.h" -#include "pqi/pqinetwork.h" -#include "pqi/sslfns.h" -#include "pqi/p3peermgr.h" -#include "util/rsdebug.h" -#include "util/rsstring.h" -#include "retroshare/rsbanlist.h" -#include "pqi/authgpg.h" - -#include -#include -#include - -static struct RsLog::logInfo pqissllistenzoneInfo = {RsLog::Default, "p3peermgr"}; -#define pqissllistenzone &pqissllistenzoneInfo - -/* NB: This #define makes the listener open 0.0.0.0:X port instead - * of a specific port - this might help retroshare work on PCs with - * multiple interfaces or unique network setups. - * #define OPEN_UNIVERSAL_PORT 1 - */ - -//#define DEBUG_LISTENNER -#define OPEN_UNIVERSAL_PORT 1 - -/************************ PQI SSL LISTEN BASE **************************** - * - * This provides all of the basic connection stuff, - * and calls completeConnection afterwards... - * - */ - - -pqissllistenbase::pqissllistenbase(const sockaddr_storage &addr, p3PeerMgr *pm) - : mPeerMgr(pm), active(false) -{ - sockaddr_storage_copy(addr, laddr); - - if (!(AuthSSL::getAuthSSL()-> active())) - { - pqioutput(PQL_ALERT, pqissllistenzone, - "SSL-CTX-CERT-ROOT not initialised!"); - exit(1); - } - - setuplisten(); -} - -pqissllistenbase::~pqissllistenbase() -{ - if(lsock != -1) - { -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - shutdown(lsock, SHUT_RDWR); - close(lsock); -#else //WINDOWS_SYS - closesocket(lsock); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - } -} - -int pqissllistenbase::tick() -{ - status(); - // check listen port. - acceptconnection(); - continueaccepts(); - return finaliseAccepts(); -} - -int pqissllistenbase::status() -{ - std::string out; - rs_sprintf(out, "pqissllistenbase::status(): Listening on port: %u", sockaddr_storage_port(laddr)); - pqioutput(PQL_DEBUG_ALL, pqissllistenzone, out); - return 1; -} - -int pqissllistenbase::setuplisten() -{ - int err; - if (active) return -1; - - lsock = socket(PF_INET6, SOCK_STREAM, 0); - -#ifdef IPV6_V6ONLY - int no = 0; - err = rs_setsockopt(lsock, IPPROTO_IPV6, IPV6_V6ONLY, - reinterpret_cast(&no), sizeof(no)); - if (err) std::cerr << __PRETTY_FUNCTION__ - << ": Error setting IPv6 socket dual stack" << std::endl; -#ifdef DEBUG_LISTENNER - else std::cerr << __PRETTY_FUNCTION__ - << ": Success setting IPv6 socket dual stack" << std::endl; -#endif -#endif // IPV6_V6ONLY - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - if (lsock < 0) - { - pqioutput(PQL_ALERT, pqissllistenzone, - "pqissllistenbase::setuplisten() Cannot Open Socket!"); - - return -1; - } - - 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); - - return -1; - } - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else //WINDOWS_SYS - if ((unsigned) lsock == INVALID_SOCKET) - { - std::string out = "pqissllistenbase::setuplisten() Cannot Open Socket!\n"; - out += "Socket Error: "+ socket_errorType(WSAGetLastError()); - pqioutput(PQL_ALERT, pqissllistenzone, out); - - return -1; - } - - // Make nonblocking. - 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()); - pqioutput(PQL_ALERT, pqissllistenzone, out); - - return -1; - } -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - // setup listening address. - - { - std::string out = "pqissllistenbase::setuplisten()\n"; - out += "\t FAMILY: " + sockaddr_storage_familytostring(laddr); - out += "\t ADDRESS: " + sockaddr_storage_tostring(laddr); - - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - //std::cerr << out.str() << std::endl; - } - - /* added a call to REUSEADDR, so that we can re-open an existing socket - * when we restart_listener. - */ - - { - int on = 1; - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) -#else //WINDOWS_SYS - if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on)) < 0) -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - { - std::string out = "pqissllistenbase::setuplisten() Cannot setsockopt SO_REUSEADDR!\n"; - showSocketError(out); - pqioutput(PQL_ALERT, pqissllistenzone, out); - std::cerr << out << std::endl; - - exit(1); - } - } - - struct sockaddr_storage tmpaddr; - sockaddr_storage_copy(laddr, tmpaddr); - sockaddr_storage_ipv4_to_ipv6(tmpaddr); - if (!mPeerMgr->isHidden()) sockaddr_storage_zeroip(tmpaddr); - - if (0 != (err = rs_bind(lsock, tmpaddr))) - { - std::string out = "pqissllistenbase::setuplisten() Cannot Bind to Local Address!\n"; - showSocketError(out); - pqioutput(PQL_ALERT, pqissllistenzone, out); - std::cerr << out << std::endl - << "tmpaddr: " << sockaddr_storage_tostring(tmpaddr) - << std::endl; - print_stacktrace(); - - return -1; - } - else - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::setuplisten() Bound to Address."); - } - -#ifdef WINDOWS_SYS - /* Set TCP buffer size for Windows systems */ - - int sockbufsize = 0; - int size = sizeof(int); - - err = getsockopt(lsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, &size); - if (err == 0) { - std::cerr << "pqissllistenbase::setuplisten: Current TCP receive buffer size " << sockbufsize << std::endl; - } else { - std::cerr << "pqissllistenbase::setuplisten: Error getting TCP receive buffer size. Error " << err << std::endl; - } - - sockbufsize = 0; - - err = getsockopt(lsock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, &size); - - if (err == 0) { - std::cerr << "pqissllistenbase::setuplisten: Current TCP send buffer size " << sockbufsize << std::endl; - } else { - std::cerr << "pqissllistenbase::setuplisten: Error getting TCP send buffer size. Error " << err << std::endl; - } - - sockbufsize = WINDOWS_TCP_BUFFER_SIZE; - - err = setsockopt(lsock, SOL_SOCKET, SO_RCVBUF, (char *)&sockbufsize, sizeof(sockbufsize)); - - if (err == 0) { - std::cerr << "pqissllistenbase::setuplisten: TCP receive buffer size set to " << sockbufsize << std::endl; - } else { - std::cerr << "pqissllistenbase::setuplisten: Error setting TCP receive buffer size. Error " << err << std::endl; - } - - err = setsockopt(lsock, SOL_SOCKET, SO_SNDBUF, (char *)&sockbufsize, sizeof(sockbufsize)); - - if (err == 0) { - std::cerr << "pqissllistenbase::setuplisten: TCP send buffer size set to " << sockbufsize << std::endl; - } else { - std::cerr << "pqissllistenbase::setuplisten: Error setting TCP send buffer size. Error " << err << std::endl; - } -#endif - - if (0 != (err = listen(lsock, 100))) - { - std::string out; - rs_sprintf(out, "pqissllistenbase::setuplisten() Error: Cannot Listen to Socket: %d\n", err); - showSocketError(out); - pqioutput(PQL_ALERT, pqissllistenzone, out); - std::cerr << out << std::endl; - - exit(1); - return -1; - } - else - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::setuplisten() Listening to Socket"); - } - active = true; - return 1; -} - -int pqissllistenbase::setListenAddr(const struct sockaddr_storage &addr) -{ - laddr = addr; - return 1; -} - -int pqissllistenbase::resetlisten() -{ - if (active) - { - // close ports etc. -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - shutdown(lsock, SHUT_RDWR); - close(lsock); -#else //WINDOWS_SYS - closesocket(lsock); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - lsock = -1; - active = false; - return 1; - } - - return 0; -} - - -int pqissllistenbase::acceptconnection() -{ - if (!active) - return 0; - // check port for any socets... - pqioutput(PQL_DEBUG_ALL, pqissllistenzone, "pqissllistenbase::accepting()"); - - // These are local but temp variables... - // can't be arsed making them all the time. - struct sockaddr_storage remote_addr; - socklen_t addrlen = sizeof(remote_addr); - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - int fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen); - int err = 0; - - if (fd < 0) - { - pqioutput(PQL_DEBUG_ALL, pqissllistenzone, - "pqissllistenbase::acceptconnnection() Nothing to Accept!"); - return 0; - } - - err = fcntl(fd, F_SETFL, O_NONBLOCK); - if (err < 0) - { - std::string out; - rs_sprintf(out, "pqissllistenbase::acceptconnection() Error: Cannot make socket NON-Blocking: %d", err); - pqioutput(PQL_ERROR, pqissllistenzone, out); - - close(fd); - return -1; - } - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else //WINDOWS_SYS - SOCKET fd = accept(lsock, (struct sockaddr *) &remote_addr, &addrlen); - int err = 0; - - if (fd == INVALID_SOCKET) - { - pqioutput(PQL_DEBUG_ALL, pqissllistenzone, - "pqissllistenbase::acceptconnnection() Nothing to Accept!"); - return 0; - } - - // Make nonblocking. - unsigned long int on = 1; - if (0 != (err = ioctlsocket(fd, FIONBIO, &on))) - { - std::string out; - rs_sprintf(out, "pqissllistenbase::acceptconnection() Error: Cannot make socket NON-Blocking: %d\n", err); - out += "Socket Error:" + socket_errorType(WSAGetLastError()); - pqioutput(PQL_ALERT, pqissllistenzone, out); - - closesocket(fd); - return 0; - } -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - std::cerr << "(II) Checking incoming connection address: " << sockaddr_storage_iptostring(remote_addr) ; - if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { - std::cerr << " => early rejected at this point, because of blacklist." << std::endl; -#ifndef WINDOWS_SYS - close(fd); -#else - closesocket(fd); -#endif - return false ; - } - else - std::cerr << " => Accepted (i.e. whitelisted, or not blacklisted)." << std::endl; - - { - std::string out; - out += "Accepted Connection from "; - out += sockaddr_storage_tostring(remote_addr); - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - } - - // Negotiate certificates. SSL stylee. - // Allow negotiations for secure transaction. - - IncomingSSLInfo incoming_connexion_info ; - - incoming_connexion_info.ssl = SSL_new(AuthSSL::getAuthSSL() -> getCTX()); - incoming_connexion_info.addr = remote_addr ; - incoming_connexion_info.gpgid.clear() ; - incoming_connexion_info.sslid.clear() ; - incoming_connexion_info.sslcn = "" ; - - SSL_set_fd(incoming_connexion_info.ssl, fd); - - return continueSSL(incoming_connexion_info, true); // continue and save if incomplete. -} - -int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool addin) -{ - // attempt the accept again. - int fd = SSL_get_fd(incoming_connexion_info.ssl); - int err = SSL_accept(incoming_connexion_info.ssl); - - if (err <= 0) - { - int ssl_err = SSL_get_error(incoming_connexion_info.ssl, err); - int err_err = ERR_get_error(); - - { - std::string out; - rs_sprintf(out, "pqissllistenbase::continueSSL() Issues with SSL Accept(%d)!\n", err); - printSSLError(incoming_connexion_info.ssl, err, ssl_err, err_err, out); - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - } - - switch (ssl_err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - { - std::string out = "pqissllistenbase::continueSSL() Connection Not Complete!\n"; - - if (addin) - { - out += "pqissllistenbase::continueSSL() Adding SSL to incoming!"; - - // add to incomingqueue. - incoming_ssl.push_back(incoming_connexion_info) ; - } - - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - - // zero means still continuing.... - return 0; - } - break; - case SSL_ERROR_SYSCALL: - { - std::string out = "pqissllistenbase::continueSSL() Connection failed!\n"; - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - - closeConnection(fd, incoming_connexion_info.ssl); - - // basic-error while connecting, no security message needed - return -1; - } - break; - } - - pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!"); - - // We use SSL_get_verify_result() in order to differentiate two cases: - // case 1: the incoming connection is closed because the peer is not a friend. This is already handled in authssl. - // case 2: the incoming connection is closed because no authentication info is available, in which case it returns X509_V_OK - auto vres = SSL_get_verify_result(incoming_connexion_info.ssl); - - if(vres == X509_V_OK && nullptr != rsEvents) - { - auto ev = std::make_shared(); - ev->mLocator = RsUrl(incoming_connexion_info.addr); - ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; - rsEvents->postEvent(ev); - } - closeConnection(fd, incoming_connexion_info.ssl); - - // failure -1, pending 0, sucess 1. - return -1; - } - - // Now grab the connection info from the SSL itself, because the callback info might be - // tempered due to multiple connection attempts at once. - // - X509 *x509 = SSL_get_peer_certificate(incoming_connexion_info.ssl) ; - - if(x509) - { - incoming_connexion_info.gpgid = RsX509Cert::getCertIssuer(*x509); - incoming_connexion_info.sslcn = RsX509Cert::getCertName(*x509); - incoming_connexion_info.sslid = RsX509Cert::getCertSslId(*x509); - -#ifndef DEBUG_LISTENNER - std::cerr << "ContinueSSL:" << std::endl; - std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl; - std::cerr << " Got SSL Id = " << incoming_connexion_info.sslid << std::endl; - std::cerr << " Got SSL CN = " << incoming_connexion_info.sslcn << std::endl; -#endif - } - -#ifdef DEBUG_LISTENNER - else - std::cerr << " no info." << std::endl; -#endif - - // if it succeeds - if (0 < completeConnection(fd, incoming_connexion_info)) - return 1; - - /* else we shut it down! */ - pqioutput(PQL_WARNING, pqissllistenzone, - "pqissllistenbase::completeConnection() Failed!"); - - closeConnection(fd, incoming_connexion_info.ssl) ; - - pqioutput(PQL_WARNING, pqissllistenzone, "Shutting it down!"); - - // failure -1, pending 0, sucess 1. - return -1; -} - - -int pqissllistenbase::closeConnection(int fd, SSL *ssl) -{ - /* else we shut it down! */ - pqioutput(PQL_WARNING, pqissllistenzone, "pqissllistenbase::closeConnection() Shutting it Down!"); - - // delete ssl connection. - SSL_shutdown(ssl); - - // close socket??? -/************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - shutdown(fd, SHUT_RDWR); - close(fd); -#else //WINDOWS_SYS - closesocket(fd); -#endif -/************************** WINDOWS/UNIX SPECIFIC PART ******************/ - // free connection. - SSL_free(ssl); - - return 1; -} - -int pqissllistenbase::continueaccepts() -{ - - // for each of the incoming sockets.... call continue. - - for(std::list::iterator it = incoming_ssl.begin(); it != incoming_ssl.end();) - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::continueaccepts() Continuing SSL"); - - if (0 != continueSSL( *it, false)) - { - pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, - "pqissllistenbase::continueaccepts() SSL Complete/Dead!"); - - /* save and increment -> so we can delete */ - std::list::iterator itd = it++; - incoming_ssl.erase(itd); - } - else - ++it; - } - return 1; -} - -#define ACCEPT_WAIT_TIME 30 - -int pqissllistenbase::finaliseAccepts() -{ - - // for each of the incoming sockets.... call continue. - std::list::iterator it; - - rstime_t now = time(NULL); - for(it = accepted_ssl.begin(); it != accepted_ssl.end();) - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::finalisedAccepts() Continuing SSL Accept"); - - /* check that the socket is still active - how? */ - int active = isSSLActive(it->mFd, it->mSSL); - if (active > 0) - { - pqioutput(PQL_WARNING, pqissllistenzone, - "pqissllistenbase::finaliseAccepts() SSL Connection Ok => finaliseConnection"); - - if (0 > finaliseConnection(it->mFd, it->mSSL, it->mPeerId, it->mAddr)) - { - closeConnection(it->mFd, it->mSSL); - } - it = accepted_ssl.erase(it); - } - else if (active < 0) - { - pqioutput(PQL_WARNING, pqissllistenzone, - "pqissllistenbase::finaliseAccepts() SSL Connection Dead => closeConnection"); - - closeConnection(it->mFd, it->mSSL); - it = accepted_ssl.erase(it); - } - else if (now - it->mAcceptTS > ACCEPT_WAIT_TIME) - { - pqioutput(PQL_WARNING, pqissllistenzone, - "pqissllistenbase::finaliseAccepts() SSL Connection Timed Out => closeConnection"); - closeConnection(it->mFd, it->mSSL); - it = accepted_ssl.erase(it); - } - else - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllistenbase::finaliseAccepts() SSL Connection Status Unknown"); - ++it; - } - } - return 1; -} - -int pqissllistenbase::isSSLActive(int /*fd*/, SSL *ssl) -{ - - /* can we just get error? */ - int bufsize = 8; /* just a little look */ - uint8_t buf[bufsize]; - int err = SSL_peek(ssl, buf, bufsize); - if (err <= 0) - { - int ssl_err = SSL_get_error(ssl, err); - int err_err = ERR_get_error(); - - { - std::string out; - rs_sprintf(out, "pqissllistenbase::isSSLActive() Issues with SSL_Accept(%d)!\n", err); - printSSLError(ssl, err, ssl_err, err_err, out); - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - } - - if (ssl_err == SSL_ERROR_ZERO_RETURN) - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::isSSLActive() SSL_ERROR_ZERO_RETURN Connection state unknown"); - - // zero means still continuing.... - return 0; - } - if ((ssl_err == SSL_ERROR_WANT_READ) || - (ssl_err == SSL_ERROR_WANT_WRITE)) - { - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, "pqissllistenbase::isSSLActive() SSL_ERROR_WANT_READ || SSL_ERROR_WANT_WRITE Connection state unknown"); - - // zero means still continuing.... - return 0; - } - else - { - std::string out; - rs_sprintf(out, "pqissllistenbase::isSSLActive() Issues with SSL Peek(%d) Likely the Connection was killed by Peer\n", err); - printSSLError(ssl, err, ssl_err, err_err, out); - pqioutput(PQL_ALERT, pqissllistenzone, out); - - return -1; - } - } - - pqioutput(PQL_WARNING, pqissllistenzone, "pqissllistenbase::isSSLActive() Successful Peer -> Connection Okay"); - - return 1; -} - -/************************ PQI SSL LISTENER **************************** - * - * This is the standard pqissl listener interface.... - * - * this class only allows connections from - * specific certificates, which are pre specified. - * - */ - -int pqissllistener::addlistenaddr(const RsPeerId& id, pqissl *acc) -{ - std::map::iterator it; - - std::string out = "Adding to Cert Listening Addresses Id: " + id.toStdString() + "\nCurrent Certs:\n"; - for(it = listenaddr.begin(); it != listenaddr.end(); ++it) - { - out += id.toStdString() + "\n"; - if (it -> first == id) - { - out += "pqissllistener::addlistenaddr() Already listening for Certificate!\n"; - - pqioutput(PQL_DEBUG_ALERT, pqissllistenzone, out); - return -1; - } - } - - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, out); - - // not there can accept it! - listenaddr[id] = acc; - return 1; -} - -int pqissllistener::removeListenPort(const RsPeerId& id) -{ - // check where the connection is coming from. - // if in list of acceptable addresses, - // - // check if in list. - std::map::iterator it; - for(it = listenaddr.begin();it!=listenaddr.end(); ++it) - { - if (it->first == id) - { - listenaddr.erase(it); - - pqioutput(PQL_DEBUG_BASIC, pqissllistenzone, - "pqissllisten::removeListenPort() Success!"); - return 1; - } - } - - pqioutput(PQL_WARNING, pqissllistenzone, - "pqissllistener::removeListenPort() Failed to Find a Match"); - - return -1; -} - - -int pqissllistener::status() -{ - pqissllistenbase::status(); - // print certificates we are listening for. - std::map::iterator it; - - std::string out = "pqissllistener::status(): Listening ("; - out += sockaddr_storage_tostring(laddr); - out += ") for Certs:"; - for(it = listenaddr.begin(); it != listenaddr.end(); ++it) - { - out += "\n" + it -> first.toStdString() ; - } - pqioutput(PQL_DEBUG_ALL, pqissllistenzone, out); - - return 1; -} - -int pqissllistener::completeConnection(int fd, IncomingSSLInfo& info) -{ - constexpr int failure = -1; - constexpr int success = 1; - - // Get the Peer Certificate.... - X509* peercert = SSL_get_peer_certificate(info.ssl); - if(!peercert) - { - RsFatal() << __PRETTY_FUNCTION__ << " failed to retrieve peer " - << "certificate at this point this should never happen!" - << std::endl; - print_stacktrace(); - exit(failure); - } - - RsPgpId pgpId = RsX509Cert::getCertIssuer(*peercert); - RsPeerId newPeerId = RsX509Cert::getCertSslId(*peercert); - -#ifdef RS_PQISSL_AUTH_DOUBLE_CHECK - /* At this point the actual connection authentication has already been - * performed in AuthSSL::VerifyX509Callback, any furter authentication check - * like the followings are redundant. */ - - bool isSslOnlyFriend = rsPeers->isSslOnlyFriend(newPeerId); - - uint32_t authErrCode = 0; - if( !isSslOnlyFriend && - !AuthSSL::instance().AuthX509WithGPG(peercert,false, authErrCode) ) - { - RsFatal() << __PRETTY_FUNCTION__ << " failure verifying peer " - << "certificate signature. This should never happen at this " - << "point!" << std::endl; - print_stacktrace(); - - X509_free(peercert); // not needed but just in case we change to return - exit(failure); - } - - if( !isSslOnlyFriend && pgpId != AuthGPG::getAuthGPG()->getGPGOwnId() && - !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) - { - RsFatal() << __PRETTY_FUNCTION__ << " pgpId: " << pgpId - << " is not friend. It is very unlikely to happen at this " - << "point! Either the user must have been so fast to deny " - << "friendship just after VerifyX509Callback have returned " - << "success and just before this code being executed, or " - << "something really fishy is happening! Share the full log " - << "with developers." << std::endl; - print_stacktrace(); - - X509_free(peercert); // not needed but just in case we change to return - exit(failure); - } -#endif //def RS_PQISSL_AUTH_REDUNDANT_CHECK - - bool found = false; - for(auto it = listenaddr.begin(); !found && it != listenaddr.end(); ) - { - if (it -> first == newPeerId) found = true; - else ++it; - } - - if (!found) - { - Dbg1() << __PRETTY_FUNCTION__ << " got secure connection from address: " - << info.addr << " with previously unknown SSL certificate: " - << newPeerId << " signed by PGP friend: " << pgpId - << ". Adding the new location as SSL friend." << std::endl; - - mPeerMgr->addFriend(newPeerId, pgpId); - } - - // Cleanup cert. - X509_free(peercert); - - // Pushback into Accepted List. - AcceptedSSL as; - as.mFd = fd; - as.mSSL = info.ssl; - as.mPeerId = newPeerId; - as.mAddr = info.addr; - as.mAcceptTS = time(nullptr); - - accepted_ssl.push_back(as); - - Dbg1() << __PRETTY_FUNCTION__ << "Successful Connection with: " - << newPeerId << " with address: " << info.addr << std::endl; - - return success; -} - -int pqissllistener::finaliseConnection(int fd, SSL *ssl, const RsPeerId& peerId, const struct sockaddr_storage &remote_addr) -{ - std::map::iterator it; - - std::string out = "pqissllistener::finaliseConnection()\n"; - out += "checking: " + peerId.toStdString() + "\n"; - // check if cert is in the list..... - - it = listenaddr.find(peerId); - if (it == listenaddr.end()) - { - out += "No Matching Peer for Connection:"; - out += sockaddr_storage_tostring(remote_addr); - out += "\npqissllistener => Shutting Down!"; - pqioutput(PQL_WARNING, pqissllistenzone, out); - return -1; - } - - out += "Found Matching Peer for Connection:"; - out += sockaddr_storage_tostring(remote_addr); - out += "\npqissllistener => Passing to pqissl module!"; - pqioutput(PQL_WARNING, pqissllistenzone, out); - - std::cerr << "pqissllistenner::finaliseConnection() connected to " << sockaddr_storage_tostring(remote_addr) << std::endl; - - // hand off ssl conection. - pqissl *pqis = it -> second; - pqis -> accept(ssl, fd, remote_addr); - - return 1; -} diff --git a/libretroshare/src/pqi/pqissllistener.h b/libretroshare/src/pqi/pqissllistener.h deleted file mode 100644 index 85af2d869..000000000 --- a/libretroshare/src/pqi/pqissllistener.h +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissllistener.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include -#include - -#include "pqi/pqi_base.h" -#include "pqi/pqilistener.h" -#include "pqi/authssl.h" -#include "util/rsdebug.h" -#include "pqi/pqinetwork.h" - -#define RS_PQISSL_AUTH_DOUBLE_CHECK 1 - - -// This is a simple overview of how the listener is setup, ticked (calling accept) and peers added to it. -// On the highest level (RsServer) the listener lives inside the pqisslpersongrp class (variable: "pqih"). -// Inside pqisslpersongrp the listener is stored in "pqil". -// -// The listener has an internal list with incoming connections that are handled in a similar fashion to pqissl. -// (Mainly setting up the socket (non-blocking) and establisching the ssl handshake.) -// When everything went fine the connection is passed to pqissl in finaliseConnection() -// -// This is how the listener is initialized during start up: -// -// RsServer::StartupRetroShare() -// | -// +----- pqih = new pqisslpersongrp(serviceCtrl, flags, mPeerMgr); -// +----- pqih->init_listener(); -// | -// +----- pqil = locked_createListener(laddr); -// | -// +----- return new pqissllistener(laddr, mPeerMgr); -// -// -// This is how the listener is ticked to call accept: -// -// RsServer::StartupRetroShare() -// | -// +----- pqih->tick(); -// | -// +----- pqil->tick(); -// | -// +----- acceptconnection(); -// | | -// | +----- accecpt() -// | -// +----- continueaccepts(); -// +----- finaliseAccepts(); -// | -// +----- finaliseConnection() -// | -// +----- pqis->accept() -// -// -// This is how peers (their id) are registered to the listener: -// (This is only used to tell if a connection peer is known or a new one (which is then added)) -// -// pqipersongrp::addPeer() -// | -// +----- pqiperson *pqip = locked_createPerson(id, pqil); -// | | -// | +----- pqiperson *pqip = new pqiperson(id, this); -// | +----- pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr); -// | +----- pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis); -// | +----- pqip->addChildInterface(PQI_CONNECT_TCP, pqisc); -// | | -// | +-- sets kids[type] = pqisc; -// | -// +----- pqip->reset(); -// +----- pqip->listen(); -// | -// +-- for all kids[] -// | -// +----- listen() ( of class pqiconnect ) -// | -// +----- listen() ( of class pqissl ) -// | -// +----- pqil->addlistenaddr(PeerId(), this); - - -/***************************** pqi Net SSL Interface ********************************* - */ - -class pqissl; -class p3PeerMgr; - -class AcceptedSSL -{ -public: - int mFd; - SSL *mSSL; - RsPeerId mPeerId; - - sockaddr_storage mAddr; - rstime_t mAcceptTS; -}; - - - - -class pqissllistenbase: public pqilistener -{ -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(); - /*************************************/ - - int acceptconnection(); - int continueaccepts(); - int finaliseAccepts(); - - struct IncomingSSLInfo - { - SSL *ssl ; - sockaddr_storage addr ; - RsPgpId gpgid ; - RsPeerId sslid ; - std::string sslcn ; - }; - - // fn to get cert, anyway - 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 sockaddr_storage &raddr) = 0; - -protected: - struct sockaddr_storage laddr; - std::list accepted_ssl; - p3PeerMgr *mPeerMgr; - -private: - - bool active; - int lsock; - std::list incoming_ssl ; -}; - - -class pqissllistener: public pqissllistenbase -{ -public: - pqissllistener(const struct sockaddr_storage &addr, p3PeerMgr *pm) : - pqissllistenbase(addr, pm) {} - virtual ~pqissllistener() {} - - 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); - -private: - std::map listenaddr; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/pqi/pqisslpersongrp.cc b/libretroshare/src/pqi/pqisslpersongrp.cc deleted file mode 100644 index 7016a2fa6..000000000 --- a/libretroshare/src/pqi/pqisslpersongrp.cc +++ /dev/null @@ -1,184 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqisslpersongrp.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsserializer.h" -#include "services/autoproxy/rsautoproxymonitor.h" -#include "util/rsdebug.h" - -#include "pqi/pqisslpersongrp.h" -#include "pqi/authssl.h" - -static struct RsLog::logInfo pqipersongrpzoneInfo = {RsLog::Default, "pqipersongrp"}; -#define pqipersongrpzone &pqipersongrpzoneInfo - -/**** - * #define PQI_DISABLE_UDP 1 - ***/ - -/********************************** SSL Specific features ***************************/ - -#include "pqi/pqissl.h" -#include "pqi/pqissllistener.h" -#include "pqi/p3peermgr.h" - -//#define PQISSLPERSON_DEBUG - -#ifndef PQI_DISABLE_UDP - #include "pqi/pqissludp.h" -#endif - -#include "pqi/pqisslproxy.h" -#include "pqi/pqissli2pbob.h" - -pqilistener * pqisslpersongrp::locked_createListener(const struct sockaddr_storage &laddr) -{ - pqilistener *listener = new pqissllistener(laddr, mPeerMgr); - return listener; -} - -pqiperson * pqisslpersongrp::locked_createPerson(const RsPeerId& id, pqilistener *listener) -{ -#ifdef PQISSLPERSON_DEBUG - std::cerr << "pqisslpersongrp::locked_createPerson() PeerId: " << id; - std::cerr << std::endl; -#endif - - pqioutput(PQL_DEBUG_BASIC, pqipersongrpzone, "pqipersongrp::createPerson() PeerId: " + id.toStdString()); - - pqiperson *pqip = new pqiperson(id, this); - - // If using proxy, then only create a proxy item, otherwise can use any. - // If we are a hidden node - then all connections should be via proxy. - if (mPeerMgr->isHiddenPeer(id) || mPeerMgr->isHidden()) - { -#ifdef PQISTREAMER_DEBUG - std::cerr << "pqisslpersongrp::locked_createPerson() Is Hidden Peer!"; - std::cerr << std::endl; -#endif - - // Use pqicI2PBOB for I2P - pqiconnect *pqicSOCKSProxy, *pqicI2PBOB; - { - pqisslproxy *pqis = new pqisslproxy((pqissllistener *) listener, pqip, mLinkMgr); - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsRawSerialiser()); - pqicSOCKSProxy = new pqiconnect(pqip, rss, pqis); - } - if (rsAutoProxyMonitor::instance()->isEnabled(autoProxyType::I2PBOB)) - { - pqissli2pbob *pqis = new pqissli2pbob((pqissllistener *) listener, pqip, mLinkMgr); - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsRawSerialiser()); - - pqicI2PBOB = new pqiconnect(pqip, rss, pqis); - } else { - pqicI2PBOB = pqicSOCKSProxy; - } - - - /* 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, pqicSOCKSProxy); - break; - case RS_HIDDEN_TYPE_I2P: - pqip -> addChildInterface(PQI_CONNECT_HIDDEN_I2P_TCP, pqicI2PBOB); - 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, pqicI2PBOB); - 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; - /* fallthrough */ - case RS_HIDDEN_TYPE_TOR: - pqip -> addChildInterface(PQI_CONNECT_HIDDEN_TOR_TCP, pqicSOCKSProxy); - break; - } - } - } - else - { -#ifdef PQISTREAMER_DEBUG - std::cerr << "pqisslpersongrp::locked_createPerson() Is Normal Peer!"; - std::cerr << std::endl; -#endif - - pqissl *pqis = new pqissl((pqissllistener *) listener, pqip, mLinkMgr); - - /* construct the serialiser .... - * Needs: - * * FileItem - * * FileData - * * ServiceGeneric - */ - - ssl_tunnels[id] = pqis ; // keeps for getting crypt info per peer. - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsRawSerialiser()); - - pqiconnect *pqisc = new pqiconnect(pqip, rss, pqis); - - pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc); - -#ifndef PQI_DISABLE_UDP - pqissludp *pqius = new pqissludp(pqip, mLinkMgr); - - RsSerialiser *rss2 = new RsSerialiser(); - rss2->addSerialType(new RsRawSerialiser()); - - pqiconnect *pqiusc = new pqiconnect(pqip, rss2, pqius); - - // add a ssl + proxy interface. - // Add Proxy First. - pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc); -#endif - } - - return pqip; -} - -void pqisslpersongrp::disconnectPeer(const RsPeerId &peer) -{ - std::map::iterator it = ssl_tunnels.find(peer) ; - - if(it != ssl_tunnels.end()) - it->second->disconnect() ; - else - std::cerr << "pqisslpersongrp::cannot find peer " << peer << ". cannot disconnect!" << std::endl; -} - - -/********************************** SSL Specific features ***************************/ - - diff --git a/libretroshare/src/pqi/pqisslpersongrp.h b/libretroshare/src/pqi/pqisslpersongrp.h deleted file mode 100644 index ea94e616a..000000000 --- a/libretroshare/src/pqi/pqisslpersongrp.h +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqisslpersongrp.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_SSL_PERSON_HANDLER_HEADER -#define MRK_PQI_SSL_PERSON_HANDLER_HEADER - -#include "pqi/pqipersongrp.h" - -class p3PeerMgr; -struct RsPeerCryptoParams; -class pqissl ; - -class pqisslpersongrp: public pqipersongrp -{ - public: - pqisslpersongrp(p3ServiceControl *ctrl, unsigned long flags, p3PeerMgr *pm) - :pqipersongrp(ctrl, flags), mPeerMgr(pm) { return; } - - protected: - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -virtual pqilistener *locked_createListener(const struct sockaddr_storage &laddr); -virtual pqiperson *locked_createPerson(const RsPeerId& id, pqilistener *listener); - /********* FUNCTIONS to OVERLOAD for specialisation ********/ - - virtual void disconnectPeer(const RsPeerId& peer) ; - - private: - - p3PeerMgr *mPeerMgr; - std::map ssl_tunnels ; -}; - - -#endif // MRK_PQI_SSL_PERSON_HANDLER_HEADER diff --git a/libretroshare/src/pqi/pqisslproxy.cc b/libretroshare/src/pqi/pqisslproxy.cc deleted file mode 100644 index 1c61bef78..000000000 --- a/libretroshare/src/pqi/pqisslproxy.cc +++ /dev/null @@ -1,629 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqisslproxy.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqisslproxy.h" -#include "pqi/pqinetwork.h" - -#include -#include - -#include - -#include "util/rsdebug.h" -#include "util/rsnet.h" - -#include "pqi/p3linkmgr.h" - -static struct RsLog::logInfo pqisslproxyzoneInfo = {RsLog::Default, "pqisslproxy"}; -#define pqisslproxyzone &pqisslproxyzoneInfo - -// #define PROXY_DEBUG 1 -// #define PROXY_DEBUG_LOG 1 - -#define PROXY_STATE_FAILED 0 -#define PROXY_STATE_INIT 1 -#define PROXY_STATE_WAITING_METHOD_RESPONSE 2 -#define PROXY_STATE_WAITING_SOCKS_RESPONSE 3 -#define PROXY_STATE_CONNECTION_COMPLETE 4 - -pqisslproxy::pqisslproxy(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm) - :pqissl(l, parent, lm) -{ - sockaddr_storage_clear(remote_addr); - return; -} - - -pqisslproxy::~pqisslproxy() -{ - rslog(RSL_ALERT, pqisslproxyzone, - "pqisslproxy::~pqisslproxy -> destroying pqisslproxy"); - - stoplistening(); - reset(); - - return; -} - -int pqisslproxy::Initiate_Connection() -{ - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Initiate_Connection()"; - std::cerr << std::endl; -#endif - - rslog(RSL_DEBUG_BASIC, pqisslproxyzone, - "pqisslproxy::Initiate_Connection() Connection to Proxy"); - /* init proxy state */ - mProxyState = PROXY_STATE_INIT; - - /* call standard Init_Conn() */ - return pqissl::Initiate_Connection(); -} - - -/********* VERY DIFFERENT **********/ -int pqisslproxy::Basic_Connection_Complete() -{ - rslog(RSL_DEBUG_BASIC, pqisslproxyzone, - "pqisslproxy::Basic_Connection_Complete()..."); - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Basic_Connection_Complete() STATE: " << mProxyState; - std::cerr << std::endl; -#endif - - if (CheckConnectionTimeout()) - { - // calls reset. - return -1; - } - - int ret = 0; - switch(mProxyState) - { - case PROXY_STATE_INIT: - ret = Proxy_Send_Method(); // checks basic conn, sends Method when able. - break; - - case PROXY_STATE_WAITING_METHOD_RESPONSE: - ret = Proxy_Send_Address(); // waits for Method Response, send Address when able. - break; - - case PROXY_STATE_WAITING_SOCKS_RESPONSE: - ret = Proxy_Connection_Complete(); // wait for ACK. - break; - - case PROXY_STATE_CONNECTION_COMPLETE: - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Basic_Connection_Complete() COMPLETED"; - std::cerr << std::endl; -#endif - - return 1; - - case PROXY_STATE_FAILED: - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Basic_Connection_Complete() FAILED"; - std::cerr << std::endl; -#endif - - reset_locked(); - return -1; - } - - if (ret < 0) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Basic_Connection_Complete() FAILED(2)"; - std::cerr << std::endl; -#endif - reset_locked(); - return -1; // FAILURE. - } - - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Basic_Connection_Complete() IN PROGRESS"; - std::cerr << std::endl; -#endif - - // In Progress. - return 0; -} - - -int pqisslproxy::Proxy_Send_Method() -{ - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Method() Checking pqissl::Basic_Connection_Complete()"; - std::cerr << std::endl; -#endif - - int ret = pqissl::Basic_Connection_Complete(); - if (ret != 1) - { - return ret; // basic connection not complete. - } - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Method() Basic complete, sending Method"; - std::cerr << std::endl; -#endif - - /* send hello to proxy server */ - char method_hello_data[3] = { 0x05, 0x01, 0x00 }; // [ Ver | nMethods (1) | No Auth Method ] - - int sent = send(sockfd, method_hello_data, 3, 0); - if (sent != 3) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Method() Send Failure"; - std::cerr << std::endl; -#endif - return -1; - } - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Method() Send Method Okay"; - std::cerr << std::endl; -#endif - - mProxyState = PROXY_STATE_WAITING_METHOD_RESPONSE; - - return 1; -} - -int pqisslproxy::Proxy_Method_Response() -{ - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response()"; - std::cerr << std::endl; -#endif - - /* get response from proxy server */ - - char method_response[2]; - - /* - first it was: - - int recvd = recv(sockfd, method_response, 2, MSG_WAITALL); - - this does not work on windows, because the socket is in nonblocking mode - the winsock reference says about the recv function and MSG_WAITALL: - - "Note that if the underlying transport does not support MSG_WAITALL, - or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP." - - now it is a two step process: - - int recvd = recv(sockfd, method_response, 2, MSG_PEEK); // test how many bytes are in the input queue - if (enaugh bytes available){ - recvd = recv(sockfd, method_response, 2, 0); - } - - this does not work on windows: - if ((recvd == -1) && (errno == EAGAIN)) return TRY_AGAIN_LATER; - - instead have to do: - if ((recvd == -1) && (WSAGetLastError() == WSAEWOULDBLOCK)) return TRY_AGAIN_LATER; - */ - - // test how many bytes can be read from the queue - int recvd = recv(sockfd, method_response, 2, MSG_PEEK); - if (recvd != 2) - { -#ifdef WINDOWS_SYS - if ((recvd == -1) && (WSAGetLastError() == WSAEWOULDBLOCK)) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() waiting for more data (windows)"; - std::cerr << std::endl; -#endif - return 0; - } -#endif - if ((recvd == -1) && (errno == EAGAIN)) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() EAGAIN"; - std::cerr << std::endl; -#endif - - return 0; - } - else if (recvd == -1) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() recv error peek"; - std::cerr << std::endl; -#endif - return -1; - } - else - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() waiting for more data"; - std::cerr << std::endl; -#endif - return 0; - } - } - - // read the bytes - recvd = recv(sockfd, method_response, 2, 0); - if (recvd != 2) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() recv error"; - std::cerr << std::endl; -#endif - return -1; - } - - // does it make sense? - if (method_response[0] != 0x05) - { - - // Error. -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() Error response[0] != 0x05. Is: "; - std::cerr << (uint32_t) method_response[0]; - std::cerr << std::endl; -#endif - return -1; - } - - if (method_response[1] != 0x00) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() Error response[0] != 0x00. Is: "; - std::cerr << (uint32_t) method_response[1]; - std::cerr << std::endl; -#endif - // Error. - return -1; - } - - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Method_Response() Response Okay"; - std::cerr << std::endl; -#endif - - return 1; -} - -#define MAX_SOCKS_REQUEST_LEN 262 // 4 + 1 + 255 + 2. - -int pqisslproxy::Proxy_Send_Address() -{ - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Address() Checking Method Response"; - std::cerr << std::endl; -#endif - - // Check Method Response. - int ret = Proxy_Method_Response(); - if (ret != 1) - { - return ret; // Method Response not complete. - } - - char socks_request[MAX_SOCKS_REQUEST_LEN] = - { 0x05, // SOCKS VERSION. - 0x01, // CONNECT (Tor doesn't support BIND or UDP). - 0x00, // RESERVED. - 0x03, // ADDRESS TYPE (Domain Name) - 0x00, // Length of Domain name... the rest is variable so can't hard code it! - }; - - /* get the length of the domain name, pack so we can't overflow uint8_t */ - uint8_t len = mDomainAddress.length(); - socks_request[4] = len; - for(int i = 0; i < len; i++) - { - socks_request[5 + i] = mDomainAddress[i]; - } - - /* now add the port, being careful with packing */ - uint16_t net_port = htons(mRemotePort); - socks_request[5 + len] = ((uint8_t *) &net_port)[0]; - socks_request[5 + len + 1] = ((uint8_t *) &net_port)[1]; - - int pkt_len = 5 + len + 2; - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Address() Sending String: "; - for(int i = 0; i < pkt_len; i++) - std::cerr << (uint32_t) socks_request[i]; - std::cerr << std::endl; -#endif - int sent = send(sockfd, socks_request, pkt_len, 0); - if (sent != pkt_len) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Address() Send Error"; - std::cerr << std::endl; -#endif - - return -1; - } - - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Send_Address() Sent Okay"; - std::cerr << std::endl; -#endif - - mProxyState = PROXY_STATE_WAITING_SOCKS_RESPONSE; - return 1; -} - -int pqisslproxy::Proxy_Connection_Complete() -{ - /* get response from proxy server */ - /* response is similar format to request - with variable length data */ - - char socks_response[MAX_SOCKS_REQUEST_LEN]; - - // test how many bytes can be read - int recvd = recv(sockfd, socks_response, 5, MSG_PEEK); - if (recvd != 5) - { -#ifdef WINDOWS_SYS - if ((recvd == -1) && (WSAGetLastError() == WSAEWOULDBLOCK)) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() waiting for more data (windows)"; - std::cerr << std::endl; -#endif - return 0; - } -#endif - if ((recvd == -1) && (errno == EAGAIN)) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() EAGAIN"; - std::cerr << std::endl; -#endif - return 0; - } - else if (recvd == -1) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() recv error peek"; - std::cerr << std::endl; -#endif - return -1; - } - else - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() waiting for more data"; - std::cerr << std::endl; -#endif - return 0; - } - } - - // read the bytes - recvd = recv(sockfd, socks_response, 5, 0); - if (recvd != 5) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() recv error"; - std::cerr << std::endl; -#endif - return -1; - } - - // error checking. - if (socks_response[0] != 0x05) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR socks_response[0] != 0x05. is: "; - std::cerr << (uint32_t) socks_response[0]; - std::cerr << std::endl; -#endif - - // error. - return -1; - } - - if (socks_response[1] != 0x00) - { - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR socks_response[1] != 0x00. is: "; - std::cerr << (uint32_t) socks_response[1]; - std::cerr << std::endl; -#endif - - // connection failed. - return -1; - } - - int address_bytes = 0; - switch(socks_response[3]) // Address Type. - { - case 0x01: - // IPv4 4 address bytes. - address_bytes = 4; -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() IPv4 Address Type"; - std::cerr << std::endl; -#endif - break; - case 0x04: - // IPv6 16 address bytes. - address_bytes = 16; -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() IPv6 Address Type"; - std::cerr << std::endl; -#endif - break; - case 0x03: - // Variable address bytes - specified in next byte. - address_bytes = 1 + socks_response[4]; -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() Domain Address Type. len: " << address_bytes; - std::cerr << std::endl; -#endif - break; - default: - // unknown error. -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR Unknown Address Type"; - std::cerr << std::endl; -#endif - return -1; - break; - } - - - // test how many bytes can be read - recvd = recv(sockfd, &(socks_response[5]), address_bytes + 1, MSG_PEEK); // address_bytes - 1 + 2... - if (recvd != address_bytes + 1) - { -#ifdef WINDOWS_SYS - if((recvd == -1) && (WSAGetLastError() == WSAEWOULDBLOCK)) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() waiting for more data(2) (windows)"; - std::cerr << std::endl; -#endif - return 0; - } -#endif - if ((recvd == -1) && (errno == EAGAIN)) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR EAGAIN at end."; - std::cerr << std::endl; -#endif - // Waiting - shouldn't happen. - return 0; - } - else if (recvd == -1) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() ERROR recving(2)"; - std::cerr << std::endl; -#endif - return -1; - } - else - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() waiting for more data(2)"; - std::cerr << std::endl; -#endif - return 0; - } - } - - // read the bytes - recvd = recv(sockfd, &(socks_response[5]), address_bytes + 1, 0); // address_bytes - 1 + 2... - if (recvd != address_bytes + 1) - { -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() recv error (2)"; - std::cerr << std::endl; -#endif - return -1; - } - -#ifdef PROXY_DEBUG - std::cerr << "pqisslproxy::Proxy_Connection_Complete() Received String: "; - for(int i = 0; i < 4 + address_bytes + 2; i++) - std::cerr << (uint32_t) socks_response[i]; - std::cerr << std::endl; -#endif - - // should print address. - // if we get here - connection is good!. - mProxyState = PROXY_STATE_CONNECTION_COMPLETE; - return 1; - -} - -bool pqisslproxy::connect_parameter(uint32_t type, const std::string &value) -{ - { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - if (type == NET_PARAM_CONNECT_DOMAIN_ADDRESS) - { - std::string out; - rs_sprintf(out, "pqisslproxy::connect_parameter() Peer: %s DOMAIN_ADDRESS: %s", PeerId().toStdString().c_str(), value.c_str()); -#ifdef PROXY_DEBUG_LOG - rslog(RSL_WARNING, pqisslproxyzone, out); -#endif - mDomainAddress = value; -#ifdef PROXY_DEBUG - std::cerr << out << std::endl; -#endif - return true; - } - } - - return pqissl::connect_parameter(type, value); -} - -bool pqisslproxy::connect_parameter(uint32_t type, uint32_t value) -{ - { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - if (type == NET_PARAM_CONNECT_REMOTE_PORT) - { - std::string out; - rs_sprintf(out, "pqisslproxy::connect_parameter() Peer: %s REMOTE_PORT: %lu", PeerId().toStdString().c_str(), value); -#ifdef PROXY_DEBUG_LOG - rslog(RSL_WARNING, pqisslproxyzone, out); -#endif - mRemotePort = value; -#ifdef PROXY_DEBUG - std::cerr << out << std::endl; -#endif - return true; - } - } - return pqissl::connect_parameter(type, value); -} - - - - diff --git a/libretroshare/src/pqi/pqisslproxy.h b/libretroshare/src/pqi/pqisslproxy.h deleted file mode 100644 index dc34295ad..000000000 --- a/libretroshare/src/pqi/pqisslproxy.h +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqisslproxy.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_SSL_PROXY_HEADER -#define MRK_PQI_SSL_PROXY_HEADER - -// operating system specific network header. -#include "pqi/pqinetwork.h" - -#include -#include - -#include "pqi/pqissl.h" - - /* pqisslproxy uses SOCKS5 proxy to hidden your own address and connect to peers. - * It uses the Domain Name interface of SOCKS5, as opposed to an IP address. - */ - -/* This provides a NetBinInterface, which is - * primarily inherited from pqissl. - * fns declared here are different -> all others are identical. - */ - -class pqisslproxy: public pqissl -{ -public: - pqisslproxy(pqissllistener *l, PQInterface *parent, p3LinkMgr *lm); -virtual ~pqisslproxy(); - - // NetInterface. Is the same. - // BinInterface. Is the same. - -virtual bool connect_parameter(uint32_t type, const std::string &value); -virtual bool connect_parameter(uint32_t type, uint32_t value); - -protected: - -//Initiate is the same - except it uses the Proxy Address rather than the Peer Address. -// minor tweaks to setup data state. -virtual int Initiate_Connection(); - -// The real overloading is done in Basic Connection Complete. -// Instead of just checking for an open socket, we need to communicate with the SOCKS5 proxy. -virtual int Basic_Connection_Complete(); - -// These are the internal steps in setting up the Proxy Connection. -virtual int Proxy_Send_Method(); -virtual int Proxy_Method_Response(); -virtual int Proxy_Send_Address(); -virtual int Proxy_Connection_Complete(); - -private: - - uint32_t mProxyState; - - std::string mDomainAddress; - uint16_t mRemotePort; -}; - -#endif // MRK_PQI_SSL_PROXY_HEADER diff --git a/libretroshare/src/pqi/pqissludp.cc b/libretroshare/src/pqi/pqissludp.cc deleted file mode 100644 index 9700f7cdc..000000000 --- a/libretroshare/src/pqi/pqissludp.cc +++ /dev/null @@ -1,622 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissludp.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqissludp.h" -#include "pqi/pqinetwork.h" - -#include "tcponudp/tou.h" -#include "tcponudp/bio_tou.h" - -#include -#include - - -#include "util/rsdebug.h" -#include "util/rsnet.h" -#include "util/rstime.h" -#include "util/rsstring.h" - -#include "pqi/p3linkmgr.h" -#include - -static struct RsLog::logInfo pqissludpzoneInfo = {RsLog::Default, "pqissludp"}; -#define pqissludpzone &pqissludpzoneInfo - - /* a final timeout, to ensure this never blocks completely - * 300 secs to complete udp/tcp/ssl connection. - * This is long as the udp connect can take some time. - */ - -static const uint32_t PQI_SSLUDP_DEF_CONN_PERIOD = 300; /* 5 minutes? */ - -/********** PQI SSL UDP STUFF **************************************/ - -pqissludp::pqissludp(PQInterface *parent, p3LinkMgr *lm) : - pqissl(nullptr, parent, lm), tou_bio(nullptr), - mConnectPeriod(PQI_SSLUDP_DEF_CONN_PERIOD), mConnectFlags(0), - mConnectBandwidth(0), mConnectProxyAddr(), mConnectSrcAddr() {} - -/* - * No need to call reset() here as it will be called in the upper class, - * pqissludp::reset_locked() just reset a few members to 0 that (that will be - * deleted anyway when this destructor ends), so pqissl::reset_locked() that is - * called by in parent class destructor will do just fine. - * - * DISCLAIMER: do not double free tou_bio here, as it is implicitely freed - * by SSL_free(...) in pqissl::reset() - */ -pqissludp::~pqissludp() = default; - - -int pqissludp::reset_locked() -{ - /* reset for next time.*/ - mConnectFlags = 0; - mConnectPeriod = PQI_SSLUDP_DEF_CONN_PERIOD; - - return pqissl::reset_locked(); -} - - - /* <===================== UDP Difference *******************/ - // The Proxy Version takes a few more step - // - // connectInterface is sent via message from the proxy. - // and is set here. - /* <===================== UDP Difference *******************/ - -int pqissludp::attach() -{ - // IN THE IMPROVED TOU LIBRARY, we need to be careful with the tou_socket PARAMETERS. - // For now, this should do! - sockfd = -1; - - if (mConnectFlags & RS_CB_FLAG_MODE_UDP_DIRECT) - { - std::cerr << "pqissludp::attach() Opening DIRECT Socket"; - std::cerr << std::endl; - sockfd = tou_socket(RSUDP_TOU_RECVER_DIRECT_IDX,TOU_RECEIVER_TYPE_UDPPEER,0); - } - else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_PROXY) - { - std::cerr << "pqissludp::attach() Opening PROXY Socket"; - std::cerr << std::endl; - sockfd = tou_socket(RSUDP_TOU_RECVER_PROXY_IDX,TOU_RECEIVER_TYPE_UDPPEER,0); - } - else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_RELAY) - { - std::cerr << "pqissludp::attach() Opening RELAY Socket"; - std::cerr << std::endl; - sockfd = tou_socket(RSUDP_TOU_RECVER_RELAY_IDX,TOU_RECEIVER_TYPE_UDPRELAY,0); - } - else - { - std::cerr << "pqissludp::attach() ERROR unknown Connect Mode" << std::endl; - std::cerr << "pqissludp::attach() mConnectFlags: " << std::hex << mConnectFlags << std::dec; - std::cerr << std::endl; - sockfd = -1; - } - - if (0 > sockfd) - { - rslog(RSL_WARNING, pqissludpzone, - "pqissludp::attach() failed to create a socket"); - return -1; - } - - // setup remote address - rslog(RSL_WARNING, pqissludpzone, - "pqissludp::attach() Opened Local Udp Socket"); - - return 1; -} - - -// The Address determination is done centrally -int pqissludp::Initiate_Connection() -{ - int err=0; - - attach(); /* open socket */ - //remote_addr.sin_family = AF_INET; - - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Initiate_Connection() Attempting Outgoing Connection...."); - - /* decide if we're active or passive */ - if (mConnectFlags & RS_CB_FLAG_ORDER_ACTIVE) - { - sslmode = PQISSL_ACTIVE; - } - else if (mConnectFlags & RS_CB_FLAG_ORDER_PASSIVE) - { - sslmode = PQISSL_PASSIVE; - } - else // likely UNSPEC - use old method to decide. - { - if (PeerId() < mLinkMgr->getOwnId()) - { - sslmode = PQISSL_ACTIVE; - } - else - { - sslmode = PQISSL_PASSIVE; - } - } - - if (waiting != WAITING_DELAY) - { - rslog(RSL_WARNING, pqissludpzone, - "pqissludp::Initiate_Connection() Already Attempt in Progress!"); - return -1; - } - - if (sockfd < 0) - { - rslog(RSL_ALERT, pqissludpzone, - "pqissludp::Initiate_Connection() Socket Creation Failed!"); - waiting = WAITING_FAIL_INTERFACE; - return -1; - } - - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Initiate_Connection() Opening Socket"); - - { - std::string out = "pqissludp::Initiate_Connection() Connecting To: " + PeerId().toStdString(); - out += " via: "; - out += sockaddr_storage_tostring(remote_addr); - out += " "; - - if (sslmode == PQISSL_ACTIVE) - { - out += "ACTIVE Connect (SSL_Connect)"; - } - else - { - out += "PASSIVE Connect (SSL_Accept)"; - } - rslog(RSL_WARNING, pqissludpzone, out); - } - - if (sockaddr_storage_isnull(remote_addr)) - { - rslog(RSL_WARNING, pqissludpzone, "pqissludp::Initiate_Connection() Invalid (0.0.0.0) Remote Address, Aborting Connect."); - waiting = WAITING_FAIL_INTERFACE; - - reset_locked(); - return -1; - } - - if(!sockaddr_storage_ipv6_to_ipv4(remote_addr)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error: remote_addr is not " - << "valid IPv4!" << std::endl; - sockaddr_storage_dump(remote_addr); - print_stacktrace(); - return -EINVAL; - } - - mTimeoutTS = time(NULL) + mConnectTimeout; - //std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl; - //std::cerr << " Connect Period is:" << mConnectPeriod << std::endl; - - /* <===================== UDP Difference *******************/ - - if (mConnectFlags & RS_CB_FLAG_MODE_UDP_DIRECT) - { - err = tou_connect(sockfd, (struct sockaddr *) &remote_addr, sizeof(remote_addr), mConnectPeriod); - } - else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_PROXY) - { - err = tou_connect(sockfd, (struct sockaddr *) &remote_addr, sizeof(remote_addr), mConnectPeriod); - } - else if (mConnectFlags & RS_CB_FLAG_MODE_UDP_RELAY) - { - std::cerr << __PRETTY_FUNCTION__ << " Calling tou_connect_via_relay(" - << sockaddr_storage_tostring(mConnectSrcAddr) << "," - << sockaddr_storage_tostring(mConnectProxyAddr) << "," - << sockaddr_storage_tostring(remote_addr) << ")" << std::endl; - - if(!sockaddr_storage_ipv6_to_ipv4(mConnectSrcAddr)) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR mConnectSrcAddr is " - << "not a valid IPv4!" << std::endl; - sockaddr_storage_dump(mConnectSrcAddr); - print_stacktrace(); - return -EINVAL; - } - if(!sockaddr_storage_ipv6_to_ipv4(mConnectProxyAddr)) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR mConnectProxyAddr " - << "is not a valid IPv4!" << std::endl; - sockaddr_storage_dump(mConnectProxyAddr); - print_stacktrace(); - return -EINVAL; - - } - - err = tou_connect_via_relay( - sockfd, - reinterpret_cast(mConnectSrcAddr), - reinterpret_cast(mConnectProxyAddr), - reinterpret_cast(remote_addr) ); - -/*** It seems that the UDP Layer sees x 1.2 the traffic of the SSL layer. - * We need to compensate somewhere... we drop the maximum traffic to 75% of limit - * to allow for extra lost packets etc. - * NB: If we have a lossy UDP transmission - re-transmission could cause excessive data to - * exceed the limit... This is difficult to account for without hacking the TcpOnUdp layer. - * If it is noticed as a problem - we'll deal with it then - */ -#define UDP_RELAY_TRANSPORT_OVERHEAD_FACTOR (0.7) - - parent()->setRateCap( UDP_RELAY_TRANSPORT_OVERHEAD_FACTOR * mConnectBandwidth / 1000.0, - UDP_RELAY_TRANSPORT_OVERHEAD_FACTOR * mConnectBandwidth / 1000.0); // Set RateCap. - } - - if (0 != err) - /* <===================== UDP Difference *******************/ - { - int tou_err = tou_errno(sockfd); - - std::string out = "pqissludp::Initiate_Connection()"; - - if ((tou_err == EINPROGRESS) || (tou_err == EAGAIN)) - { - // set state to waiting..... - waiting = WAITING_SOCK_CONNECT; - - out += " EINPROGRESS Waiting for Socket Connection"; - rslog(RSL_WARNING, pqissludpzone, out); - - return 0; - } - else if ((tou_err == ENETUNREACH) || (tou_err == ETIMEDOUT)) - { - out += "ENETUNREACHABLE: cert: " + PeerId().toStdString() + "\n"; - - // Then send unreachable message. - waiting = WAITING_FAIL_INTERFACE; - } - - rs_sprintf_append(out, "Error: Connection Failed: %d - %s", tou_err, socket_errorType(tou_err).c_str()); - - rslog(RSL_WARNING, pqissludpzone, out); - - reset_locked(); - - return -1; - } - else - { - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Init_Connection() connect returned 0"); - } - - waiting = WAITING_SOCK_CONNECT; - - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Initiate_Connection() Waiting for Socket Connect"); - - return 1; -} - -/********* VERY DIFFERENT **********/ -int pqissludp::Basic_Connection_Complete() -{ - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Basic_Connection_Complete()..."); - - if (CheckConnectionTimeout()) - { - return -1; - } - - if (waiting != WAITING_SOCK_CONNECT) - { - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Basic_Connection_Complete() Wrong Mode"); - return -1; - } - - - /* new approach is to check for an error */ - /* check for an error */ - int err; - if (0 != (err = tou_errno(sockfd))) - { - if (err == EINPROGRESS) - { - rslog(RSL_DEBUG_BASIC, pqissludpzone, "pqissludp::Basic_Connection_Complete() EINPROGRESS: cert: " + PeerId().toStdString()); - } - else if ((err == ENETUNREACH) || (err == ETIMEDOUT)) - { - rslog(RSL_WARNING, pqissludpzone, "pqissludp::Basic_Connection_Complete() ENETUNREACH/ETIMEDOUT: cert: " + PeerId().toStdString()); - - /* is the second one needed? */ - std::string out = "pqissludp::Basic_Connection_Complete() "; - rs_sprintf_append(out, "Error: Connection Failed: %d - %s", err, socket_errorType(err).c_str()); - rslog(RSL_DEBUG_BASIC, pqissludpzone, out); - - reset_locked(); - - // Then send unreachable message. - waiting = WAITING_FAIL_INTERFACE; - - return -1; - } - } - - /* <===================== UDP Difference *******************/ - if (tou_connected(sockfd)) - /* <===================== UDP Difference *******************/ - { - rslog(RSL_WARNING, pqissludpzone, "pqissludp::Basic_Connection_Complete() Connection Complete: cert: " + PeerId().toStdString()); - - return 1; - } - else - { - // not ready return -1; - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::Basic_Connection_Complete() Not Yet Ready!"); - return 0; - } - - return -1; -} - - -/* New Internal Functions required to generalise tcp/udp version - * of the programs - */ - -// used everywhere -int pqissludp::net_internal_close(int fd) -{ - rslog(RSL_ALERT, pqissludpzone, - "pqissludp::net_internal_close() -> tou_close()"); - return tou_close(fd); -} - -// install udp BIO. -int pqissludp::net_internal_SSL_set_fd(SSL *ssl, int fd) -{ - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::net_internal_SSL_set_fd()"); - - /* create the bio's */ - tou_bio =BIO_new(BIO_s_tou_socket()); - - /* attach the fd's to the BIO's */ - BIO_set_fd(tou_bio, fd, BIO_NOCLOSE); - SSL_set_bio(ssl, tou_bio, tou_bio); - return 1; -} - -bool pqissludp::connect_parameter(uint32_t type, uint32_t value) -{ - { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - //std::cerr << "pqissludp::connect_parameter() type: " << type << "value: " << value << std::endl; - if (type == NET_PARAM_CONNECT_PERIOD) - { - std::string out; - rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s PERIOD: %lu", PeerId().toStdString().c_str(), value); - rslog(RSL_WARNING, pqissludpzone, out); - - mConnectPeriod = value; - std::cerr << out << std::endl; - return true; - } - else if (type == NET_PARAM_CONNECT_FLAGS) - { - std::string out; - rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s FLAGS: %lu", PeerId().toStdString().c_str(), value); - rslog(RSL_WARNING, pqissludpzone, out); - - mConnectFlags = value; - std::cerr << out<< std::endl; - return true; - } - else if (type == NET_PARAM_CONNECT_BANDWIDTH) - { - std::string out; - rs_sprintf(out, "pqissludp::connect_parameter() Peer: %s BANDWIDTH: %lu", PeerId().toStdString().c_str(), value); - rslog(RSL_WARNING, pqissludpzone, out); - - mConnectBandwidth = value; - std::cerr << out << std::endl; - return true; - } - } - - return pqissl::connect_parameter(type, value); -} - -bool pqissludp::connect_additional_address(uint32_t type, const struct sockaddr_storage &addr) -{ - { - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - if (type == NET_PARAM_CONNECT_PROXY) - { - std::string out; - rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s PROXYADDR: ", PeerId().toStdString().c_str()); - out += sockaddr_storage_tostring(addr); - rslog(RSL_WARNING, pqissludpzone, out); - - mConnectProxyAddr = addr; - - std::cerr << out << std::endl; - return true; - } - else if (type == NET_PARAM_CONNECT_SOURCE) - { - std::string out; - rs_sprintf(out, "pqissludp::connect_additional_address() Peer: %s SRCADDR: ", PeerId().toStdString().c_str()); - out += sockaddr_storage_tostring(addr); - rslog(RSL_WARNING, pqissludpzone, out); - - mConnectSrcAddr = addr; - - std::cerr << out << std::endl; - return true; - } - } - return pqissl::connect_additional_address(type, addr); -} - -/********** PQI STREAMER OVERLOADING *********************************/ - -bool pqissludp::moretoread(uint32_t usec) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - // Extra Checks to avoid crashes in v0.6 ... pqithreadstreamer calls this function - // when sockfd = -1 during the shutdown of the thread. - // NB: it should never reach here if bio->isActive() returns false. - // Some mismatch to chase down when we have a chance. - // SAME test is at cansend. - if (sockfd < 0) - { - std::cerr << "pqissludp::moretoread() INVALID sockfd PARAMETER ... bad shutdown?"; - std::cerr << std::endl; - return false; - } - - - { - std::string out = "pqissludp::moretoread()"; - rs_sprintf_append(out, " polling socket (%d)", sockfd); - rslog(RSL_DEBUG_ALL, pqissludpzone, out); - } - - if (usec) - { - //std::cerr << "pqissludp::moretoread() usec parameter: " << usec; - //std::cerr << std::endl; - - if (0 < tou_maxread(sockfd)) - { - return true; - } - rstime::rs_usleep(usec); - } - - /* check for more to read first ... if nothing... check error - */ - /* <===================== UDP Difference *******************/ - if (tou_maxread(sockfd)) - /* <===================== UDP Difference *******************/ - { - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::moretoread() Data to Read!"); - return 1; - } - - /* else check the error */ - rslog(RSL_DEBUG_ALL, pqissludpzone, - "pqissludp::moretoread() No Data to Read!"); - - int err; - if (0 != (err = tou_errno(sockfd))) - { - if ((err == EAGAIN) || (err == EINPROGRESS)) - { - rslog(RSL_DEBUG_BASIC, pqissludpzone, "pqissludp::moretoread() EAGAIN/EINPROGRESS: cert " + PeerId().toStdString()); - return 0; - - } - else if ((err == ENETUNREACH) || (err == ETIMEDOUT)) - { - rslog(RSL_WARNING, pqissludpzone, "pqissludp::moretoread() ENETUNREACH/ETIMEDOUT: cert " + PeerId().toStdString()); - } - else if (err == EBADF) - { - rslog(RSL_WARNING, pqissludpzone, "pqissludp::moretoread() EBADF: cert " + PeerId().toStdString()); - } - else - { - std::string out = "pqissludp::moretoread() "; - rs_sprintf_append(out, " Unknown ERROR: %d: cert ", err, PeerId().toStdString().c_str()); - rslog(RSL_WARNING, pqissludpzone, out); - } - - reset_locked(); - return 0; - } - - if(SSL_pending(ssl_connection) > 0) - return 1 ; - - /* otherwise - not error - strange! */ - rslog(RSL_DEBUG_BASIC, pqissludpzone, - "pqissludp::moretoread() No Data + No Error (really nothing)"); - - return 0; - - -} - -bool pqissludp::cansend(uint32_t usec) -{ - RsStackMutex stack(mSslMtx); /**** LOCKED MUTEX ****/ - - // Extra Checks to avoid crashes in v0.6 ... pqithreadstreamer calls this function - // when sockfd = -1 during the shutdown of the thread. - // NB: it should never reach here if bio->isActive() returns false. - // Some mismatch to chase down when we have a chance. - // SAME test is at can moretoread. - if (sockfd < 0) - { - std::cerr << "pqissludp::cansend() INVALID sockfd PARAMETER ... bad shutdown?"; - std::cerr << std::endl; - return false; - } - - if (usec) - { - std::cerr << "pqissludp::cansend() usec parameter: " << usec; - std::cerr << std::endl; - - if (0 < tou_maxwrite(sockfd)) - { - return true; - } - - rstime::rs_usleep(usec); - } - - rslog(RSL_DEBUG_ALL, pqissludpzone, - "pqissludp::cansend() polling socket!"); - - /* <===================== UDP Difference *******************/ - return (0 < tou_maxwrite(sockfd)); - /* <===================== UDP Difference *******************/ - -} - - - diff --git a/libretroshare/src/pqi/pqissludp.h b/libretroshare/src/pqi/pqissludp.h deleted file mode 100644 index b716efb1e..000000000 --- a/libretroshare/src/pqi/pqissludp.h +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqissludp.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2015-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "pqi/pqissl.h" -#include "pqi/pqinetwork.h" -#include "util/rsdebug.h" - - -/** - * @brief pqissludp is the special NAT traversal protocol. - * This class will implement the basics of streaming ssl over udp using a - * tcponudp library. - * It provides a NetBinInterface, which is primarily inherited from pqissl. - * Some methods are override all others are identical. - */ -class pqissludp: public pqissl -{ -public: - pqissludp(PQInterface *parent, p3LinkMgr *lm); - ~pqissludp() override; - - int listen() override { return 1; } - int stoplistening() override { return 1; } - - 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); - /* UDP always through firewalls -> always bandwidth Limited */ - virtual bool bandwidthLimited() { return true; } - -protected: - - // pqissludp specific. - // called to initiate a connection; - int attach(); - - virtual int reset_locked(); - - virtual int Initiate_Connection(); - virtual int Basic_Connection_Complete(); - - /* 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*/) { return 0; } - -private: - - BIO *tou_bio; // specific to ssludp. - - uint32_t mConnectPeriod; - uint32_t mConnectFlags; - uint32_t mConnectBandwidth; - - struct sockaddr_storage mConnectProxyAddr; - struct sockaddr_storage mConnectSrcAddr; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/pqi/pqistore.cc b/libretroshare/src/pqi/pqistore.cc deleted file mode 100644 index 090a6a794..000000000 --- a/libretroshare/src/pqi/pqistore.cc +++ /dev/null @@ -1,575 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqistore.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* This is dependent on the sslroot at the moment. - * -> as we need to create/restore references to the Person. - * -> and store the signatures to do this. - */ - -/******************************************************************* - * pqistore provides an store stream. - * This stores RsItem + Person Reference + Timestamp, - * - * and allows Objects to be replayed or restored, - * independently of the rest of the pqi system. - * - */ - -#include "rsitems/rsitem.h" -#include "pqi/pqistore.h" -#include "serialiser/rsserial.h" -#include -#include - -#include "util/rsdebug.h" -#include "util/rsmemory.h" -#include "util/rsstring.h" - -// -// #define PQISTORE_DEBUG -// - -static struct RsLog::logInfo pqistorezoneInfo = {RsLog::Default, "pqistore"}; -#define pqistorezone &pqistorezoneInfo - -pqistore::pqistore(RsSerialiser *rss, const RsPeerId& srcId, BinInterface *bio_in, int bio_flags_in) - :PQInterface(RsPeerId()), rsSerialiser(rss), bio_flags(bio_flags_in), - nextPkt(NULL), mSrcId(srcId), bio(bio_in) -{ - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::pqistore() Initialisation!"); - - if (!bio_in) - { - pqioutput(PQL_ALERT, pqistorezone, "pqistore::pqistore() NULL bio, FATAL ERROR!"); - exit(1); - } - - bStopReading=false; - return; -} - -pqistore::~pqistore() -{ - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::~pqistore() Destruction!"); - - if (bio_flags & BIN_FLAGS_NO_CLOSE) - { - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::~pqistore() Not Closing BinInterface!;"); - } - else if (bio) - { - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::~pqistore() Deleting BinInterface!"); - - delete bio; - } - - if (rsSerialiser) - delete rsSerialiser; - - if (nextPkt) - { - delete nextPkt; - } - return; -} - - -// Get/Send Items. -int pqistore::SendItem(RsItem *si) -{ -#ifdef PQISTORE_DEBUG - { - std::string out = "pqistore::SendItem()\n"; - si -> print(out); - pqioutput(PQL_DEBUG_BASIC, pqistorezone, out); - } -#endif - - // check if this is a writing bio. - - if (!(bio_flags & BIN_FLAGS_WRITEABLE)) - { - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete si; - return -1; - } - -// std::cerr << "SendItem: si->PeerId()=" << si->PeerId() << std::endl ; - - int ret = writePkt(si); - return ret; /* 0 - failure, 1 - success*/ -} - -RsItem *pqistore::GetItem() -{ -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::GetItem()"); -#endif - - bStopReading=false; - // check if this is a reading bio. - if (!(bio_flags & BIN_FLAGS_READABLE)) - { - pqioutput(PQL_DEBUG_BASIC, pqistorezone, "pqistore::GetItem() Error Not Readable"); - bStopReading=true; - return NULL; - } - - // load if we dont have a packet. - if (!nextPkt) - { - if (!readPkt(&nextPkt)) - { - pqioutput(PQL_DEBUG_BASIC, pqistorezone, "pqistore::GetItem() Failed to ReadPkt"); - return NULL; - } - } - - if (!nextPkt) return NULL; - - RsItem *outPkt = nextPkt; - nextPkt = NULL; - -#ifdef PQISTORE_DEBUG - if (outPkt != NULL) - { - std::string out = "pqistore::GetItem() Returning:\n"; - outPkt -> print(out); - pqioutput(PQL_DEBUG_BASIC, pqistorezone, out); - } -#endif - return outPkt; -} - - - - -// // PQInterface -int pqistore::tick() -{ -#ifdef PQISTORE_DEBUG - std::cerr << "pqistore::tick()" << std::endl; -#endif - return 0; -} - -int pqistore::status() -{ -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::status()"); -#endif - return 0; -} - -// -/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/ - -int pqistore::writePkt(RsItem *pqi) -{ -// std::cerr << "writePkt, pqi->peerId()=" << pqi->PeerId() << std::endl ; -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::writePkt()"); -#endif - - uint32_t pktsize = rsSerialiser->size(pqi); - - RsTemporaryMemory ptr(pktsize) ; - - if(ptr == NULL) - return 0 ; - - if (!(rsSerialiser->serialise(pqi, ptr, &pktsize))) - { -#ifdef PQISTORE_DEBUG - std::string out = "pqistore::writePkt() Null Pkt generated!\nCaused By:\n"; - pqi -> print(out); - pqioutput(PQL_ALERT, pqistorezone, out); -#endif - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - return 0; - } - - /* extract the extra details */ - uint32_t len = getRsItemSize(ptr); - if (len != pktsize) - { - std::string out; - rs_sprintf(out, "pqistore::writePkt() Length MisMatch: len: %u!= pktsize: %u\nCaused By:\n", len, pktsize); - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqistorezone, out); - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - return 0; - } - - - if (!(bio->cansend(0))) - { - std::string out; - rs_sprintf(out, "pqistore::writePkt() BIO cannot write!\niscarding:\n"); - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqistorezone, out); - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 0; - } - -#ifdef PQISTORE_DEBUG - std::string out = "Writing Pkt Body"; -#endif - // write packet. - if (len != (uint32_t) bio->senddata(ptr, len)) - { -#ifdef PQISTORE_DEBUG - out += " Problems with Send Data!"; - pqioutput(PQL_ALERT, pqistorezone, out); -#endif - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 0; - } - -#ifdef PQISTORE_DEBUG - out += " Success!"; - pqioutput(PQL_DEBUG_BASIC, pqistorezone, out); -#endif - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 1; -} - -/* Reads a single packet from the input stream - * gets the timestamp as well. - */ - -int pqistore::readPkt(RsItem **item_out) -{ -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::readPkt()"); -#endif - bStopReading = false ; - - if ((!(bio->isactive())) || (!(bio->moretoread(0)))) - { - bStopReading = true ; - return 0; - } - - // initial read size: basic packet. - int blen = getRsPktBaseSize(); - void *block = rs_malloc(blen); - - if(block == NULL) - return false ; - - int tmplen; - /* we have the header */ - - // read the basic block (minimum packet size) - if (blen != (tmplen = bio->readdata(block, blen))) - { - pqioutput(PQL_WARNING, pqistorezone, "pqistore::readPkt() bad read(2)"); - - free(block); - bStopReading=true; - return 0; - } - - // workout how much more to read. - int blocklength = getRsItemSize(block); - - // make sure that blocklength is not a crazy number. If so, we drop the entire stream that might be corrupted. - - if(blocklength < blen || blocklength > 1024*1024*10) - { - std::cerr << "pqistore: ERROR: trying to realloc memory for packet of length" << blocklength <<", which is either too small, or exceeds the safety limit (10 MB)" << std::endl ; - free(block) ; - bStopReading=true; - return 0 ; - } - int extralen = blocklength - blen; - - void *tmp = realloc(block, blocklength); - - if (tmp == NULL) - { - free(block); - std::cerr << "pqistore: ERROR: trying to realloc memory for packet of length" << blocklength << std::endl ; - std::cerr << "Have you got enought memory?" << std::endl ; - bStopReading=true; - return 0 ; - } - else - block = tmp; - - if (extralen > 0) - { - void *extradata = (void *) (((char *) block) + blen); - - if (extralen != (tmplen = bio->readdata(extradata, extralen))) - { - std::string out; - rs_sprintf(out, "pqistore::readPkt() Error Completing Read (read %d/%d)", tmplen, extralen); - pqioutput(PQL_ALERT, pqistorezone, out); - bStopReading=true; - - free(block); - return 0; - } - } - - // create packet, based on header. - uint32_t readbytes = extralen + blen; - - RsItem *item = rsSerialiser->deserialise(block, &readbytes); - free(block); - - if (item == NULL) - { - pqioutput(PQL_ALERT, pqistorezone, "pqistore::readPkt() Failed to create Item from store!"); - return 0; - } - - item->PeerId(mSrcId); - *item_out = item; - return 1; -} - -/**** Hashing Functions ****/ -RsFileHash pqistore::gethash() -{ - return bio->gethash(); -} - -pqiSSLstore::pqiSSLstore(RsSerialiser *rss, const RsPeerId& srcId, BinEncryptedFileInterface* bio_in, int bio_flagsin) -: pqistore(rss, srcId, bio_in, bio_flagsin), enc_bio(bio_in) -{ - bStopReading=false; - return; -} - -pqiSSLstore::~pqiSSLstore() -{ - // no need to delete member enc_bio, as it is deleted by the parent class. - return; -} - -bool pqiSSLstore::encryptedSendItems(const std::list& rsItemList) -{ - - std::list::const_iterator it; - uint32_t sizeItems = 0, sizeItem = 0; - uint32_t offset = 0; - - for(it = rsItemList.begin(); it != rsItemList.end(); ++it) - if(*it != NULL) sizeItems += rsSerialiser->size(*it); - - RsTemporaryMemory data( sizeItems ? sizeItems : 1 ); - - for(it = rsItemList.begin(); it != rsItemList.end(); ++it) - if(*it != NULL) - { - sizeItem = rsSerialiser->size(*it); - - if(rsSerialiser->serialise(*it, &data[offset],&sizeItem)) - offset += sizeItem; - else - { - std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl; - std::cerr << "Item content: " << std::endl; - (*it)->print(std::cerr) ; - } - - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete *it; - } - - bool result = true; - - if(sizeItems == offset) - enc_bio->senddata(data, sizeItems); - else - result = false; - - return result; -} - -bool pqiSSLstore::getEncryptedItems(std::list& rsItemList) -{ - RsItem* item; - bStopReading=false; - - do - { - if (NULL != (item = GetItem())) - rsItemList.push_back(item); - - } while (enc_bio->isactive() && enc_bio->moretoread(0) && !bStopReading); - - return true; -} - - -RsItem *pqiSSLstore::GetItem() -{ -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqiSSLstore::GetItem()"); -#endif - - bStopReading=false; - // check if this is a reading bio. - if (!(bio_flags & BIN_FLAGS_READABLE)) - { - pqioutput(PQL_DEBUG_BASIC, pqistorezone, "pqiSSLstore::GetItem() Error Not Readable"); - bStopReading=true; - return NULL; - } - - // load if we dont have a packet. - if (!nextPkt) - { - if (!readPkt(&nextPkt)) - { - pqioutput(PQL_DEBUG_BASIC, pqistorezone, "pqiSSLstore::GetItem() Failed to ReadPkt"); - return NULL; - } - } - - if (!nextPkt) return NULL; - - RsItem *outPkt = nextPkt; - nextPkt = NULL; - -#ifdef PQISTORE_DEBUG - if (outPkt != NULL) - { - std::string out; - rs_sprintf(out, "pqiSSLstore::GetItem() Returning:\n"); - outPkt -> print(out); - pqioutput(PQL_DEBUG_BASIC, pqistorezone, out); - } -#endif - return outPkt; -} - - -int pqiSSLstore::readPkt(RsItem **item_out) -{ - *item_out = NULL ; -#ifdef PQISTORE_DEBUG - pqioutput(PQL_DEBUG_ALL, pqistorezone, "pqistore::readPkt()"); -#endif - - bStopReading=false ; - if ((!(enc_bio->isactive())) || (!(enc_bio->moretoread(0)))) - { - bStopReading=true ; - return 0; - } - - // initial read size: basic packet. - int blen = getRsPktBaseSize(); - void *block = rs_malloc(blen); - - if(block == NULL) - return false ; - - int tmplen; - /* we have the header */ - - // read the basic block (minimum packet size) - if (blen != (tmplen = enc_bio->readdata(block, blen))) - { - pqioutput(PQL_WARNING, pqistorezone, "pqiSSLstore::readPkt() bad read(2)"); - - free(block); - bStopReading=true; - return 0; - } - - // workout how much more to read. - int blocklength = getRsItemSize(block); - - if(blocklength < blen || blocklength > 1024*1024*10) - { - free(block); - std::cerr << "pqiSSLstore: ERROR: block length has invalid value " << blocklength << " (either too small, or exceeds the safety limit of 10 MB)" << std::endl ; - bStopReading=true; - return 0 ; - } - int extralen = blocklength - blen; - - void *tmp = realloc(block, blocklength); - - if (tmp == NULL) - { - free(block); - std::cerr << "pqiSSLstore: ERROR: trying to realloc memory for packet of length" << extralen+blen << std::endl ; - std::cerr << "Have you got enought memory?" << std::endl ; - bStopReading=true; - return 0 ; - } - else - block = tmp; - - if (extralen > 0) - { - void *extradata = (void *) (((char *) block) + blen); - - if (extralen != (tmplen = enc_bio->readdata(extradata, extralen))) - { - std::string out; - rs_sprintf(out, "pqiSSLstore::readPkt() Error Completing Read (read %d/%d)", tmplen, extralen); - pqioutput(PQL_ALERT, pqistorezone, out); - - free(block); - bStopReading=true; - return 0; - } - } - - // create packet, based on header. - uint32_t readbytes = extralen + blen; - - RsItem *item = rsSerialiser->deserialise(block, &readbytes); - free(block); - - if (item == NULL) - { - pqioutput(PQL_ALERT, pqistorezone, "pqiSSLstore::readPkt() Failed to create Item from store!"); - return 0; - } - - item->PeerId(mSrcId); - *item_out = item; - return 1; -} - diff --git a/libretroshare/src/pqi/pqistore.h b/libretroshare/src/pqi/pqistore.h deleted file mode 100644 index f8a586c67..000000000 --- a/libretroshare/src/pqi/pqistore.h +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqistore.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_STORE_STREAMER_HEADER -#define MRK_PQI_STORE_STREAMER_HEADER - -#include "pqi/pqibin.h" - -#include - -/******************************************************************* - * pqistore provides a stream to file. - * objects only - like pqistreamer as opposed to pqiarchive. - * - */ - -class pqistore: public PQInterface -{ -public: - pqistore(RsSerialiser *rss, const RsPeerId&srcId, BinInterface *bio_in, int bio_flagsin); -virtual ~pqistore(); - -// PQInterface -virtual int SendItem(RsItem *); -virtual RsItem *GetItem(); - -virtual int tick(); -virtual int status(); - -RsFileHash gethash(); - -bool bStopReading; - -protected: - -// Serialiser -RsSerialiser *rsSerialiser; -unsigned int bio_flags; // only BIN_NO_CLOSE at the moment. - -// Temp Storage for transient data..... -RsItem *nextPkt; -RsPeerId mSrcId; - -private: - - int writePkt(RsItem *item); - int readPkt(RsItem **item_out); - - - - // Binary Interface for IO, initialisated at startup. - BinInterface *bio; - -}; - - -/*! - * provdes an ssl encrypted stream to file storage - */ -class pqiSSLstore: public pqistore -{ - -public: - - pqiSSLstore(RsSerialiser *rss, const RsPeerId& srcId, BinEncryptedFileInterface *bio_in, int bio_flagsin); - - virtual ~pqiSSLstore(); - - /*! - * send items encrypted to file using client's ssl key - */ - bool encryptedSendItems(const std::list&); - - /*! - * retrieve encrypted file using client's ssl key - */ - bool getEncryptedItems(std::list&); - -private: - - RsItem *GetItem(); - int readPkt(RsItem **item_out); - - BinEncryptedFileInterface* enc_bio; - - //bool bStopReading; - -}; - - -#endif //MRK_PQI_STORE_STREAMER_HEADER diff --git a/libretroshare/src/pqi/pqistreamer.cc b/libretroshare/src/pqi/pqistreamer.cc deleted file mode 100644 index f5d61ab9f..000000000 --- a/libretroshare/src/pqi/pqistreamer.cc +++ /dev/null @@ -1,1442 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqistreamer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqistreamer.h" - -#include // for gettimeofday -#include // for free, realloc, exit -#include // for memcpy, memset, memcmp -#include "util/rstime.h" // for NULL, time, rstime_t -#include // for min -#include // for operator<<, ostream, basic_ostream -#include // for string, allocator, operator<<, oper... -#include // for pair - -#include "pqi/p3notify.h" // for p3Notify -#include "retroshare/rsids.h" // for operator<< -#include "retroshare/rsnotify.h" // for RS_SYS_WARNING -#include "rsserver/p3face.h" // for RsServer -#include "serialiser/rsserial.h" // for RsItem, RsSerialiser, getRsItemSize -#include "util/rsdebug.h" // for pqioutput, PQL_ALERT, PQL_DEBUG_ALL -#include "util/rsmemory.h" // for rs_malloc -#include "util/rsprint.h" // for BinToHex -#include "util/rsstring.h" // for rs_sprintf_append, rs_sprintf - -static struct RsLog::logInfo pqistreamerzoneInfo = {RsLog::Default, "pqistreamer"}; -#define pqistreamerzone &pqistreamerzoneInfo - -static const int PQISTREAM_ABS_MAX = 100000000; /* 100 MB/sec (actually per loop) */ -static const int PQISTREAM_AVG_PERIOD = 1; // update speed estimate every second -static const float PQISTREAM_AVG_FRAC = 0.8; // for bandpass filter over speed estimate. -static const float PQISTREAM_AVG_DT_FRAC = 0.99; // for low pass filter over elapsed time - -static const int PQISTREAM_OPTIMAL_PACKET_SIZE = 512; // It is believed that this value should be lower than TCP slices and large enough as compare to encryption padding. - // most importantly, it should be constant, so as to allow correct QoS. -static const int PQISTREAM_SLICE_FLAG_STARTS = 0x01; // -static const int PQISTREAM_SLICE_FLAG_ENDS = 0x02; // these flags should be kept in the range 0x01-0x08 -static const int PQISTREAM_SLICE_PROTOCOL_VERSION_ID_01 = 0x10; // Protocol version ID. Should hold on the 4 lower bits. -static const int PQISTREAM_PARTIAL_PACKET_HEADER_SIZE = 8; // Same size than normal header, to make the code simpler. -static const int PQISTREAM_PACKET_SLICING_PROBE_DELAY = 60; // send every 60 secs. - -// This is a probe packet, that won't deserialise (it's empty) but will not cause problems to old peers either, since they will ignore -// it. This packet however will be understood by new peers as a signal to enable packet slicing. This should go when all peers use the -// same protocol. - -static uint8_t PACKET_SLICING_PROBE_BYTES[8] = { 0x02, 0xaa, 0xbb, 0xcc, 0x00, 0x00, 0x00, 0x08 } ; - -/* Change to true to disable packet slicing and/or packet grouping, if needed */ -#define DISABLE_PACKET_SLICING false -#define DISABLE_PACKET_GROUPING false - -/* This removes the print statements (which hammer pqidebug) */ -/*** -#define RSITEM_DEBUG 1 -#define DEBUG_TRANSFERS 1 -#define DEBUG_PQISTREAMER 1 -#define DEBUG_PACKET_SLICING 1 - ***/ - -#ifdef DEBUG_TRANSFERS - #include "util/rsprint.h" -#endif - -static double getCurrentTS() -{ -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} - -pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in) - :PQInterface(id), mStreamerMtx("pqistreamer"), - mBio(bio_in), mBio_flags(bio_flags_in), mRsSerialiser(rss), - mPkt_wpending(NULL), mPkt_wpending_size(0), - mTotalRead(0), mTotalSent(0), - mCurrRead(0), mCurrSent(0), - mAvgReadCount(0), mAvgSentCount(0), - mAvgDtOut(0), mAvgDtIn(0) -{ - - // 100 B/s (minimal) - setMaxRate(true, 0.1); - setMaxRate(false, 0.1); - setRate(true, 0); // needs to be off-mutex - setRate(false, 0); - - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - - mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready. - mLastSentPacketSlicingProbe = 0 ; - - mAvgLastUpdate = mCurrSentTS = mCurrReadTS = getCurrentTS(); - - mIncomingSize = 0 ; - mIncomingSize_bytes = 0; - - mStatisticsTimeStamp = 0 ; - /* allocated once */ - mPkt_rpend_size = 0; - mPkt_rpending = 0; - mReading_state = reading_state_initial ; - - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!"); - - if (!bio_in) - { - pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!"); - exit(1); - } - - mFailed_read_attempts = 0; // reset failed read, as no packet is still read. - - return; -} - -pqistreamer::~pqistreamer() -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ -#ifdef DEBUG_PQISTREAMER - std::cerr << "Closing pqistreamer." << std::endl; -#endif - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Destruction!"); - - if (mBio_flags & BIN_FLAGS_NO_CLOSE) - { - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Not Closing BinInterface!"); - } - else if (mBio) - { - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::~pqistreamer() Deleting BinInterface!"); - - delete mBio; - } - - /* clean up serialiser */ - if (mRsSerialiser) - delete mRsSerialiser; - - free_pend() ; - - // clean up incoming. - while (!mIncoming.empty()) - { - RsItem *i = mIncoming.front(); - mIncoming.pop_front() ; - --mIncomingSize; - delete i; - } - - if (mIncomingSize != 0) - std::cerr << "(EE) inconsistency after deleting pqistreamer queue. Remaining items: " << mIncomingSize << std::endl ; - return; -} - - -// Get/Send Items. -// This is the entry poing for methods willing to send items through our out queue -int pqistreamer::SendItem(RsItem *si,uint32_t& out_size) -{ -#ifdef RSITEM_DEBUG - { - std::string out = "pqistreamer::SendItem():\n"; - si -> print_string(out); - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out); - std::cerr << out; - } -#endif - - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - - return queue_outpqi_locked(si,out_size); -} - -RsItem *pqistreamer::GetItem() -{ -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::GetItem()"); -#endif - - if(mIncoming.empty()) - return NULL; - - RsItem *osr = mIncoming.front() ; - mIncoming.pop_front() ; - --mIncomingSize; -// for future use -// mIncomingSize_bytes -= - - return osr; -} - - -float pqistreamer::getMaxRate(bool b) -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - return getMaxRate_locked(b); -} - -float pqistreamer::getMaxRate_locked(bool b) -{ - return RateInterface::getMaxRate(b) ; -} - -float pqistreamer::getRate(bool b) -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - return RateInterface::getRate(b) ; -} - -void pqistreamer::setMaxRate(bool b,float f) -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - setMaxRate_locked(b,f); -} - -void pqistreamer::setMaxRate_locked(bool b,float f) -{ - RateInterface::setMaxRate(b,f) ; -} - -void pqistreamer::setRate(bool b,float f) -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - RateInterface::setRate(b,f) ; -} - - -void pqistreamer::updateRates() -{ - // update actual rates both ways. - - double t = getCurrentTS(); // get current timestamp. - double diff = t - mAvgLastUpdate; - - if (diff > PQISTREAM_AVG_PERIOD) - { - float avgReadpSec = PQISTREAM_AVG_FRAC * getRate(true ) + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1024.0 * diff); - float avgSentpSec = PQISTREAM_AVG_FRAC * getRate(false) + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1024.0 * diff); - -#ifdef DEBUG_PQISTREAMER - uint64_t t_now = 1000 * getCurrentTS(); - std::cerr << std::dec << t_now << " DEBUG_PQISTREAMER pqistreamer::updateRates PeerId " << this->PeerId().toStdString() << " Current speed estimates: down " << std::dec << (int)(1024 * avgReadpSec) << " B/s / up " << (int)(1024 * avgSentpSec) << " B/s" << std::endl; -#endif - - // now store the new rates, zero meaning that we are not bandwidthLimited() - - if (mBio->bandwidthLimited()) - { - setRate(true, avgReadpSec); - setRate(false, avgSentpSec); - } - else - { - setRate(true, 0); - setRate(false, 0); - } - - mAvgLastUpdate = t; - mAvgReadCount = 0; - - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - mAvgSentCount = 0; - } - } -} - -int pqistreamer::tick_bio() -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - mBio->tick(); - - /* short circuit everything if bio isn't active */ - if (!(mBio->isactive())) - { - return 0; - } - return 1; -} - -int pqistreamer::tick_recv(uint32_t timeout) -{ -// Apart from a few exceptions that are atomic (mLastIncomingTs, mIncomingSize), only this pqi thread reads/writes mIncoming queue and related counters. -// The lock of pqistreamer mutex is thus not needed here. -// The mutex lock is still needed before calling locked_addTrafficClue because this method is also used by the thread pushing packets in mOutPkts. -// Locks around rates are provided internally. - - if (mBio->moretoread(timeout)) - { - handleincoming(); - } - if(!(mBio->isactive())) - { - free_pend(); - } - return 1; -} - -int pqistreamer::tick_send(uint32_t timeout) -{ - /* short circuit everything if bio isn't active */ - if (!(mBio->isactive())) - { - free_pend(); - return 0; - } - - if (mBio->cansend(timeout)) - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - handleoutgoing_locked(); - } - - return 1; -} - -int pqistreamer::status() -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - - -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::status()"); - - if (mBio->isactive()) - { - std::string out; - rs_sprintf(out, "Data in:%d out:%d", mTotalRead, mTotalSent); - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out); - } -#endif - - return 0; -} - -// this method is overloaded by pqiqosstreamer -void pqistreamer::locked_storeInOutputQueue(void *ptr,int,int) -{ - mOutPkts.push_back(ptr); -} - -int pqistreamer::queue_outpqi_locked(RsItem *pqi,uint32_t& pktsize) -{ - pktsize = 0 ; -#ifdef DEBUG_PQISTREAMER - std::cerr << "pqistreamer::queue_outpqi() called." << std::endl; -#endif - - /* decide which type of packet it is */ - - pktsize = mRsSerialiser->size(pqi); - void *ptr = rs_malloc(pktsize); - - if(ptr == NULL) - return 0 ; - -#ifdef DEBUG_PQISTREAMER - std::cerr << "pqistreamer::queue_outpqi() serializing packet with packet size : " << pktsize << std::endl; -#endif - - /*******************************************************************************************/ - // keep info for stats for a while. Only keep the items for the last two seconds. sec n is ongoing and second n-1 - // is a full statistics chunk that can be used in the GUI - - locked_addTrafficClue(pqi,pktsize,mCurrentStatsChunk_Out) ; - - /*******************************************************************************************/ - - if (mRsSerialiser->serialise(pqi, ptr, &pktsize)) - { - locked_storeInOutputQueue(ptr,pktsize,pqi->priority_level()) ; - - if (!(mBio_flags & BIN_FLAGS_NO_DELETE)) - { - delete pqi; - } - return 1; - } - else - { - /* cleanup serialiser */ - free(ptr); - } - - std::string out = "pqistreamer::queue_outpqi() Null Pkt generated!\nCaused By:\n"; - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqistreamerzone, out); - - if (!(mBio_flags & BIN_FLAGS_NO_DELETE)) - { - delete pqi; - } - return 1; // keep error internal. -} - -int pqistreamer::handleincomingitem(RsItem *pqi,int len) -{ - -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincomingitem()"); -#endif - // timestamp last received packet. - mLastIncomingTs = time(NULL); - - // Use overloaded Contact function - pqi -> PeerId(PeerId()); - - mIncoming.push_back(pqi); - ++mIncomingSize; - // for future use - // mIncomingSize_bytes += len; - - /*******************************************************************************************/ - // keep info for stats for a while. Only keep the items for the last two seconds. sec n is ongoing and second n-1 - // is a full statistics chunk that can be used in the GUI - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - locked_addTrafficClue(pqi,len,mCurrentStatsChunk_In) ; - } - /*******************************************************************************************/ - - return 1; -} - -void pqistreamer::locked_addTrafficClue(const RsItem *pqi,uint32_t pktsize,std::list& lst) -{ - rstime_t now = time(NULL) ; - - if(now > mStatisticsTimeStamp) // new chunk => get rid of oldest, replace old list by current list, clear current list. - { - mPreviousStatsChunk_Out = mCurrentStatsChunk_Out ; - mPreviousStatsChunk_In = mCurrentStatsChunk_In ; - mCurrentStatsChunk_Out.clear() ; - mCurrentStatsChunk_In.clear() ; - - mStatisticsTimeStamp = now ; - } - - RSTrafficClue tc ; - tc.TS = now ; - tc.size = pktsize ; - tc.priority = pqi->priority_level() ; - tc.peer_id = pqi->PeerId() ; - tc.count = 1 ; - tc.service_id = pqi->PacketService() ; - tc.service_sub_id = pqi->PacketSubType() ; - - lst.push_back(tc) ; -} - -rstime_t pqistreamer::getLastIncomingTS() -{ - // This is the only case where another thread (rs main for pqiperson) will access our data - // Still a mutex lock is not needed because the operation is atomic - return mLastIncomingTs; -} - -// Packet slicing: -// -// Old : 02 0014 03 00000026 [data, 26 bytes] => [version 1B] [service 2B][subpacket 1B] [size 4B] -// New2: pp ff xxxxxxxx ssss [data, sss bytes] => [protocol version 1B] [flags 1B] [2^32 packet count] [2^16 size] -// -// Encode protocol on 1.0 Bytes ( 8 bits) -// Encode flags on 1.0 Bytes ( 8 bits) -// 0x01 => incomplete packet continued after -// 0x02 => packet ending a previously incomplete packet -// -// Encode packet ID on 4.0 Bytes (32 bits) => packet counter = [0...2^32] -// Encode size on 2.0 Bytes (16 bits) => 65536 // max slice size = 65536 -// -// Backward compatibility: -// * send one packet with service + subpacket = aabbcc. Old peers will silently ignore such packets. Full packet header is: 02aabbcc 00000008 -// * if received, mark the peer as able to decode the new packet type -// In pqiQoS: -// - limit packet grouping to max size 512. -// - new peers need to read flux, and properly extract partial sizes, and combine packets based on packet counter. -// - on sending, RS grabs slices of max size 1024 from pqiQoS. If smaller, possibly pack them together. -// pqiQoS keeps track of sliced packets and makes sure the output is consistent: -// * when a large packet needs to be send, only takes a slice and return it, and update the remaining part -// * always consider priority when taking new slices => a newly arrived fast packet will always get through. -// -// Max slice size should be customisable, depending on bandwidth. To be tested... -// - -int pqistreamer::handleoutgoing_locked() -{ -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleoutgoing_locked()"); -#endif - - int maxbytes = outAllowedBytes_locked(); - int sentbytes = 0; - - // std::cerr << "pqistreamer: maxbytes=" << maxbytes<< std::endl ; - - std::list::iterator it; - - // if not connection, or cannot send anything... pause. - if (!(mBio->isactive())) - { - /* if we are not active - clear anything in the queues. */ - locked_clear_out_queue() ; -#ifdef DEBUG_PACKET_SLICING - std::cerr << "(II) Switching off packet slicing." << std::endl; -#endif - mAcceptsPacketSlicing = false ; - - /* also remove the pending packets */ - if (mPkt_wpending) - { - free(mPkt_wpending); - mPkt_wpending = NULL; - mPkt_wpending_size = 0 ; - } - - return 0; - } - - // a very simple round robin - - bool sent = true; - int nsent = 0 ; - while(sent) // catch if all items sent. - { - sent = false; - - if ((!(mBio->cansend(0))) || (maxbytes < sentbytes)) - { -#ifdef DEBUG_PQISTREAMER - if (sentbytes > maxbytes) - RsDbg() << "PQISTREAMER pqistreamer::handleoutgoing_locked() stopped sending max reached, sentbytes " << std::dec << sentbytes << " maxbytes " << maxbytes; - else - RsDbg() << "PQISTREAMER pqistreamer::handleoutgoing_locked() stopped sending bio not ready, sentbytes " << std::dec << sentbytes << " maxbytes " << maxbytes; -#endif - return 0; - } - // send a out_pkt., else send out_data. unless there is a pending packet. The strategy is to - // - grab as many packets as possible while below the optimal packet size, so as to allow some packing and decrease encryption padding overhead (suposeddly) - // - limit packets size to OPTIMAL_PACKET_SIZE when sending big packets so as to keep as much QoS as possible. - - if (!mPkt_wpending) - { - void *dta; - mPkt_wpending_size = 0 ; - int k=0; - - // Checks for inserting a packet slicing probe. We do that to send the other peer the information that packet slicing can be used. - // if so, we enable it for the session. This should be removed (because it's unnecessary) when all users have switched to the new version. - rstime_t now = time(NULL) ; - - if(now > mLastSentPacketSlicingProbe + PQISTREAM_PACKET_SLICING_PROBE_DELAY) - { -#ifdef DEBUG_PACKET_SLICING - std::cerr << "(II) Inserting packet slicing probe in traffic" << std::endl; -#endif - - mPkt_wpending_size = 8 ; - mPkt_wpending = rs_malloc(8) ; - memcpy(mPkt_wpending,PACKET_SLICING_PROBE_BYTES,8) ; - - mLastSentPacketSlicingProbe = now ; - } - - uint32_t slice_size=0; - bool slice_starts=true ; - bool slice_ends=true ; - uint32_t slice_packet_id=0 ; - - do - { - int desired_packet_size = mAcceptsPacketSlicing?PQISTREAM_OPTIMAL_PACKET_SIZE:(getRsPktMaxSize()); - - dta = locked_pop_out_data(desired_packet_size,slice_size,slice_starts,slice_ends,slice_packet_id) ; - - if(!dta) - break ; - - if(slice_starts && slice_ends) // good old method. Send the packet as is, since it's a full packet. - { -#ifdef DEBUG_PACKET_SLICING - std::cerr << "sending full slice, old style. Size=" << slice_size << std::endl; -#endif - mPkt_wpending = realloc(mPkt_wpending,slice_size+mPkt_wpending_size) ; - memcpy( &((char*)mPkt_wpending)[mPkt_wpending_size],dta,slice_size) ; - free(dta); - mPkt_wpending_size += slice_size ; - ++k ; - } - else // partial packet. We make a special header for it and insert it in the stream - { - if(slice_size > 0xffff || !mAcceptsPacketSlicing) - { - std::cerr << "(EE) protocol error in pqitreamer: slice size is too large and cannot be encoded." ; - free(mPkt_wpending) ; - mPkt_wpending_size = 0; - return -1 ; - } -#ifdef DEBUG_PACKET_SLICING - std::cerr << "sending partial slice, packet ID=" << std::hex << slice_packet_id << std::dec << ", size=" << slice_size << std::endl; -#endif - - mPkt_wpending = realloc(mPkt_wpending,slice_size+mPkt_wpending_size+PQISTREAM_PARTIAL_PACKET_HEADER_SIZE) ; - memcpy( &((char*)mPkt_wpending)[mPkt_wpending_size+PQISTREAM_PARTIAL_PACKET_HEADER_SIZE],dta,slice_size) ; - free(dta); - - // New2: pp ff xxxxxxxx ssss [data, sss bytes] => [flags 1B] [protocol version 1B] [2^32 packet count] [2^16 size] - - uint8_t partial_flags = 0 ; - if(slice_starts) partial_flags |= PQISTREAM_SLICE_FLAG_STARTS ; - if(slice_ends ) partial_flags |= PQISTREAM_SLICE_FLAG_ENDS ; - - ((char*)mPkt_wpending)[mPkt_wpending_size+0x00] = PQISTREAM_SLICE_PROTOCOL_VERSION_ID_01 ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x01] = partial_flags ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x02] = uint8_t(slice_packet_id >> 24) & 0xff ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x03] = uint8_t(slice_packet_id >> 16) & 0xff ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x04] = uint8_t(slice_packet_id >> 8) & 0xff ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x05] = uint8_t(slice_packet_id >> 0) & 0xff ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x06] = uint8_t(slice_size >> 8) & 0xff ; - ((char*)mPkt_wpending)[mPkt_wpending_size+0x07] = uint8_t(slice_size >> 0) & 0xff ; - - mPkt_wpending_size += slice_size + PQISTREAM_PARTIAL_PACKET_HEADER_SIZE; - ++k ; - } - } - while(mPkt_wpending_size < (uint32_t)maxbytes && mPkt_wpending_size < PQISTREAM_OPTIMAL_PACKET_SIZE && !DISABLE_PACKET_GROUPING) ; - -#ifdef DEBUG_PQISTREAMER - if(k > 1) - std::cerr << "Packed " << k << " packets into " << mPkt_wpending_size << " bytes." << std::endl; -#endif - } - - if (mPkt_wpending) - { - // write packet. -#ifdef DEBUG_PQISTREAMER - std::cout << "Sending Out Pkt of size " << mPkt_wpending_size << " !" << std::endl; -#endif - int ss=0; - - if (mPkt_wpending_size != (uint32_t)(ss = mBio->senddata(mPkt_wpending, mPkt_wpending_size))) - { -#ifdef DEBUG_PQISTREAMER - std::string out; - rs_sprintf(out, "Problems with Send Data! (only %d bytes sent, total pkt size=%d)", ss, mPkt_wpending_size); - // std::cerr << out << std::endl ; - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out); -#endif - std::cerr << PeerId() << ": sending failed. Only " << ss << " bytes sent over " << mPkt_wpending_size << std::endl; - - // pkt_wpending will kept til next time. - // ensuring exactly the same data is written (openSSL requirement). - return -1; - } -#ifdef DEBUG_PQISTREAMER - else - std::cerr << PeerId() << ": sent " << ss << " bytes " << std::endl; -#endif - - ++nsent; - - outSentBytes_locked(mPkt_wpending_size); // this is the only time where we know exactly what was sent. - -#ifdef DEBUG_TRANSFERS - std::cerr << "pqistreamer::handleoutgoing_locked() Sent Packet len: " << mPkt_wpending_size << " @ " << RsUtil::AccurateTimeString(); - std::cerr << std::endl; -#endif - - sentbytes += mPkt_wpending_size; - - free(mPkt_wpending); - mPkt_wpending = NULL; - mPkt_wpending_size = 0 ; - - sent = true; - } - } -#ifdef DEBUG_PQISTREAMER - if(nsent > 0) - std::cerr << "nsent = " << nsent << ", total bytes=" << sentbytes << std::endl; -#endif - return 1; -} - - -/* Handles reading from input stream. - */ -int pqistreamer::handleincoming() -{ - int readbytes = 0; - static const int max_failed_read_attempts = 2000 ; - -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::handleincoming()"); -#endif - - if(!(mBio->isactive())) - { - mReading_state = reading_state_initial ; - free_pend(); - return 0; - } - else - allocate_rpend(); - - // enough space to read any packet. - uint32_t maxlen = mPkt_rpend_size; - void *block = mPkt_rpending; - - // initial read size: basic packet. - int blen = getRsPktBaseSize(); // this is valid for both packet slices and normal un-sliced packets (same header size) - - int maxin = inAllowedBytes(); - -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << "reading state = " << mReading_state << std::endl ; -#endif - switch(mReading_state) - { - case reading_state_initial: /*std::cerr << "jumping to start" << std::endl; */ goto start_packet_read ; - case reading_state_packet_started: /*std::cerr << "jumping to middle" << std::endl;*/ goto continue_packet ; - } - -start_packet_read: - { // scope to ensure variable visibility - // read the basic block (minimum packet size) - int tmplen; -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << "starting packet" << std::endl ; -#endif - memset(block,0,blen) ; // reset the block, to avoid uninitialized memory reads. - - if (blen != (tmplen = mBio->readdata(block, blen))) - { - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() Didn't read BasePkt!"); - - // error.... (either blocked or failure) - if (tmplen == 0) - { -#ifdef DEBUG_PQISTREAMER - // most likely blocked! - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "pqistreamer::handleincoming() read blocked"); - std::cerr << "[" << (void*)pthread_self() << "] " << "given up 1" << std::endl ; -#endif - return 0; - } - else if (tmplen < 0) - { - // Most likely it is that the packet is pending but could not be read by pqissl because of stream flow. - // So we return without an error, and leave the machine state in 'start_read'. - // - //pqioutput(PQL_WARNING, pqistreamerzone, "pqistreamer::handleincoming() Error in bio read"); -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << "given up 2, state = " << mReading_state << std::endl ; -#endif - return 0; - } - else // tmplen > 0 - { - // strange case....This should never happen as partial reads are handled by pqissl below. -#ifdef DEBUG_PQISTREAMER - std::string out = "pqistreamer::handleincoming() Incomplete "; - rs_sprintf_append(out, "(Strange) read of %d bytes", tmplen); - pqioutput(PQL_ALERT, pqistreamerzone, out); - - std::cerr << "[" << (void*)pthread_self() << "] " << "given up 3" << std::endl ; -#endif - return -1; - } - } -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << "block 0 : " << RsUtil::BinToHex((unsigned char*)block,8) << std::endl; -#endif - - readbytes += blen; - mReading_state = reading_state_packet_started ; - mFailed_read_attempts = 0 ; // reset failed read, as the packet has been totally read. - - // Check for packet slicing probe (04/26/2016). To be removed when everyone uses it. - - if(!memcmp(block,PACKET_SLICING_PROBE_BYTES,8)) - { - mAcceptsPacketSlicing = !DISABLE_PACKET_SLICING; -#ifdef DEBUG_PACKET_SLICING - std::cerr << "(II) Enabling packet slicing!" << std::endl; -#endif - } - } -continue_packet: - { - // workout how much more to read. - - bool is_partial_packet = false ; - bool is_packet_starting = (((char*)block)[1] == PQISTREAM_SLICE_FLAG_STARTS) ; // STARTS and ENDS flags are actually never combined. - bool is_packet_ending = (((char*)block)[1] == PQISTREAM_SLICE_FLAG_ENDS) ; - bool is_packet_middle = (((char*)block)[1] == 0x00) ; - - uint32_t extralen =0; - uint32_t slice_packet_id =0; - - if( ((char*)block)[0] == PQISTREAM_SLICE_PROTOCOL_VERSION_ID_01 && ( is_packet_starting || is_packet_middle || is_packet_ending)) - { - extralen = (uint32_t(((uint8_t*)block)[6]) << 8 ) + (uint32_t(((uint8_t*)block)[7])); - slice_packet_id = (uint32_t(((uint8_t*)block)[2]) << 24) + (uint32_t(((uint8_t*)block)[3]) << 16) + (uint32_t(((uint8_t*)block)[4]) << 8) + (uint32_t(((uint8_t*)block)[5]) << 0); - -#ifdef DEBUG_PACKET_SLICING - std::cerr << "Reading partial packet from mem block " << RsUtil::BinToHex((char*)block,8) << ": packet_id=" << std::hex << slice_packet_id << std::dec << ", len=" << extralen << std::endl; -#endif - is_partial_packet = true ; - - mAcceptsPacketSlicing = !DISABLE_PACKET_SLICING; // this is needed - } - else - extralen = getRsItemSize(block) - blen; // old style packet type - -#ifdef DEBUG_PACKET_SLICING - std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet getRsItemSize(block) = " << getRsItemSize(block) << std::endl ; - std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet extralen = " << extralen << std::endl ; - - std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << mReading_state << std::endl ; - std::cerr << "[" << (void*)pthread_self() << "] " << "block 1 : " << RsUtil::BinToHex((unsigned char*)block,8) << std::endl; -#endif - if (extralen + (uint32_t)blen > maxlen) - { - pqioutput(PQL_ALERT, pqistreamerzone, "ERROR: Read Packet too Big!"); - - p3Notify *notify = RsServer::notify(); - if (notify) - { - std::string title = - "Warning: Bad Packet Read"; - - std::string msg; - msg = " **** WARNING **** \n"; - msg += "Retroshare has caught a BAD Packet Read"; - msg += "\n"; - msg += "This is normally caused by connecting to an"; - msg += " OLD version of Retroshare"; - msg += "\n"; - rs_sprintf_append(msg, "(M:%d B:%d E:%d)\n", maxlen, blen, extralen); - msg += "\n"; - msg += "block = " ; - msg += RsUtil::BinToHex((char*)block,8); - - msg += "\n"; - msg += "Please get your friends to upgrade to the latest version"; - msg += "\n"; - msg += "\n"; - msg += "If you are sure the error was not caused by an old version"; - msg += "\n"; - msg += "Please report the problem to Retroshare's developers"; - msg += "\n"; - - notify->AddLogMessage(0, RS_SYS_WARNING, title, msg); - - std::cerr << "pqistreamer::handle_incoming() ERROR: Read Packet too Big" << std::endl; - std::cerr << msg; - std::cerr << std::endl; - - } - mBio->close(); - mReading_state = reading_state_initial ; // restart at state 1. - mFailed_read_attempts = 0 ; - return -1; - - // Used to exit now! exit(1); - } - - if (extralen > 0) - { - void *extradata = (void *) (((char *) block) + blen); - int tmplen ; - - // Don't reset the block now! If pqissl is in the middle of a multiple-chunk - // packet (larger than 16384 bytes), and pqistreamer jumped directly yo - // continue_packet:, then readdata is going to write after the beginning of - // extradata, yet not exactly at start -> the start of the packet would be wiped out. - // - // so, don't do that: - // memset( extradata,0,extralen ) ; - - if (extralen != (uint32_t)(tmplen = mBio->readdata(extradata, extralen))) - { -#ifdef DEBUG_PACKET_SLICING - if(tmplen > 0) - std::cerr << "[" << (void*)pthread_self() << "] " << "Incomplete packet read ! This is a real problem ;-)" << std::endl ; -#endif - - if(++mFailed_read_attempts > max_failed_read_attempts) - { - std::string out; - rs_sprintf(out, "Error Completing Read (read %d/%d)", tmplen, extralen); - std::cerr << out << std::endl ; - pqioutput(PQL_ALERT, pqistreamerzone, out); - - p3Notify *notify = RsServer::notify(); - if (notify) - { - std::string title = "Warning: Error Completing Read"; - - std::string msgout; - msgout = " **** WARNING **** \n"; - msgout += "Retroshare has experienced an unexpected Read ERROR"; - msgout += "\n"; - rs_sprintf_append(msgout, "(M:%d B:%d E:%d R:%d)\n", maxlen, blen, extralen, tmplen); - msgout += "\n"; - msgout += "Note: this error might as well happen (rarely) when a peer disconnects in between a transmission of a large packet.\n"; - msgout += "If it happens manny time, please contact the developers, and send them these numbers:"; - msgout += "\n"; - - msgout += "block = " ; - msgout += RsUtil::BinToHex((char*)block,8) + "\n" ; - - std::cerr << msgout << std::endl; - } - - mBio->close(); - mReading_state = reading_state_initial ; // restart at state 1. - mFailed_read_attempts = 0 ; - return -1; - } - else - { -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << "given up 5, state = " << mReading_state << std::endl ; -#endif - return 0 ; // this is just a SSL_WANT_READ error. Don't panic, we'll re-try the read soon. - // we assume readdata() returned either -1 or the complete read size. - } - } -#ifdef DEBUG_PACKET_SLICING - std::cerr << "[" << (void*)pthread_self() << "] " << "continuing packet state=" << mReading_state << std::endl ; - std::cerr << "[" << (void*)pthread_self() << "] " << "block 2 : " << RsUtil::BinToHex((unsigned char*)extradata,8) << std::endl; -#endif - - mFailed_read_attempts = 0 ; - readbytes += extralen; - } - - // create packet, based on header. -#ifdef DEBUG_PQISTREAMER - { - std::string out; - rs_sprintf(out, "Read Data Block -> Incoming Pkt(%d)", blen + extralen); - //std::cerr << out ; - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out); - } -#endif - - uint32_t pktlen = blen+extralen ; -#ifdef DEBUG_PQISTREAMER - std::cerr << "[" << (void*)pthread_self() << "] " << RsUtil::BinToHex((char*)block,8) << "...: deserializing. Size=" << pktlen << std::endl ; -#endif - RsItem *pkt ; - - if(is_partial_packet) - { -#ifdef DEBUG_PACKET_SLICING - std::cerr << "Inputing partial packet " << RsUtil::BinToHex((char*)block,8) << std::endl; -#endif - uint32_t packet_length = 0 ; - pkt = addPartialPacket(block,pktlen,slice_packet_id,is_packet_starting,is_packet_ending,packet_length) ; - - pktlen = packet_length ; - } - else - pkt = mRsSerialiser->deserialise(block, &pktlen); - - if ((pkt != NULL) && (0 < handleincomingitem(pkt,pktlen))) - { -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, "Successfully Read a Packet!"); -#endif - inReadBytes(pktlen); // only count deserialised packets, because that's what is actually been transfered. - } - else if (!is_partial_packet) - { -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_ALERT, pqistreamerzone, "Failed to handle Packet!"); -#endif - std::cerr << "Incoming Packet could not be deserialised:" << std::endl; - std::cerr << " Incoming peer id: " << PeerId() << std::endl; - if(pktlen >= 8) - std::cerr << " Packet header : " << RsUtil::BinToHex((unsigned char*)block,8) << std::endl; - if(pktlen > 8) - std::cerr << " Packet data : " << RsUtil::BinToHex((unsigned char*)block+8,std::min(50u,pktlen-8)) << ((pktlen>58)?"...":"") << std::endl; - } - - mReading_state = reading_state_initial ; // restart at state 1. - mFailed_read_attempts = 0 ; // reset failed read, as the packet has been totally read. - } - - if(maxin > readbytes && mBio->moretoread(0)) - goto start_packet_read ; - -#ifdef DEBUG_PQISTREAMER - if (readbytes > maxin) - RsDbg() << "PQISTREAMER pqistreamer::handleincoming() stopped reading max reached, readbytes " << std::dec << readbytes << " maxin " << maxin; - else - RsDbg() << "PQISTREAMER pqistreamer::handleincoming() stopped reading no more to read, readbytes " << std::dec << readbytes << " maxin " << maxin; -#endif - - return 0; -} - -RsItem *pqistreamer::addPartialPacket(const void *block, uint32_t len, uint32_t slice_packet_id, bool is_packet_starting, bool is_packet_ending, uint32_t &total_len) -{ -#ifdef DEBUG_PACKET_SLICING - std::cerr << "Receiving partial packet. size=" << len << ", ID=" << std::hex << slice_packet_id << std::dec << ", starting:" << is_packet_starting << ", ending:" << is_packet_ending ; -#endif - - if(is_packet_starting && is_packet_ending) - { - std::cerr << " (EE) unexpected situation: both starting and ending" << std::endl; - return NULL ; - } - - uint32_t slice_length = len - PQISTREAM_PARTIAL_PACKET_HEADER_SIZE ; - unsigned char *slice_data = &((unsigned char*)block)[PQISTREAM_PARTIAL_PACKET_HEADER_SIZE] ; - - std::map::iterator it = mPartialPackets.find(slice_packet_id) ; - - if(it == mPartialPackets.end()) - { - // make sure we really have a starting packet. Otherwise this is an error. - - if(!is_packet_starting) - { - std::cerr << " (EE) non starting packet has no record. Dropping" << std::endl; - return NULL ; - } - PartialPacketRecord& rec = mPartialPackets[slice_packet_id] ; - - rec.mem = rs_malloc(slice_length) ; - - if(!rec.mem) - { - std::cerr << " (EE) Cannot allocate memory for slice of size " << slice_length << std::endl; - return NULL ; - } - - memcpy(rec.mem, slice_data, slice_length) ; ; - rec.size = slice_length ; - -#ifdef DEBUG_PACKET_SLICING - std::cerr << " => stored in new record (size=" << rec.size << std::endl; -#endif - - return NULL ; // no need to check for ending - } - else - { - PartialPacketRecord& rec = it->second ; - - if(is_packet_starting) - { - std::cerr << "(WW) dropping unfinished existing packet that gets to be replaced by new starting packet." << std::endl; - free(rec.mem); - rec.mem = NULL ; - rec.size = 0 ; - } - // make sure this is a continuing packet, otherwise this is an error. - - rec.mem = realloc(rec.mem, rec.size + slice_length) ; - memcpy( &((char*)rec.mem)[rec.size],slice_data,slice_length) ; - rec.size += slice_length ; - -#ifdef DEBUG_PACKET_SLICING - std::cerr << " => added to existing record size=" << rec.size ; -#endif - - if(is_packet_ending) - { -#ifdef DEBUG_PACKET_SLICING - std::cerr << " => deserialising: mem=" << RsUtil::BinToHex((char*)rec.mem,std::min(8u,rec.size)) << std::endl; -#endif - RsItem *item = mRsSerialiser->deserialise(rec.mem, &rec.size); - - total_len = rec.size ; - free(rec.mem) ; - mPartialPackets.erase(it) ; - return item ; - } - else - { -#ifdef DEBUG_PACKET_SLICING - std::cerr << std::endl; -#endif - return NULL ; - } - } -} - -/* BandWidth Management Assistance */ - -float pqistreamer::outTimeSlice_locked() -{ -#ifdef DEBUG_PQISTREAMER - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::outTimeSlice()"); -#endif - - //fixme("pqistreamer::outTimeSlice()", 1); - return 1; -} - -int pqistreamer::outAllowedBytes_locked() -{ - double t = getCurrentTS() ; // in sec, with high accuracy - - // allow a lot if not bandwidthLimited() - if (!mBio->bandwidthLimited()) - { - mCurrSent = 0; - mCurrSentTS = t; - return PQISTREAM_ABS_MAX; - } - - // dt is the time elapsed since the last round of sending data - double dt = t - mCurrSentTS; - - // ignore cases where dt > 1s - if (dt > 1) - dt = 1; - - // low pass filter on mAvgDtOut - mAvgDtOut = PQISTREAM_AVG_DT_FRAC * mAvgDtOut + (1 - PQISTREAM_AVG_DT_FRAC) * dt; - - double maxout = getMaxRate_locked(false) * 1024.0; - - // this is used to take into account a possible excess of data sent during the previous round - mCurrSent -= int(dt * maxout); - - // we dont allow negative value, any quota not used during the previous round is therefore lost - if (mCurrSent < 0) - mCurrSent = 0; - - mCurrSentTS = t; - - // now calculate the amount of data allowed to be sent during the next round - // we take into account the possible excess (but not deficit) of the previous round - // (this is handled differently when reading data, see below) - double quota = mAvgDtOut * maxout - mCurrSent; - -#ifdef DEBUG_PQISTREAMER - RsDbg() << "PQISTREAMER pqistreamer::outAllowedBytes_locked() dt " << std::dec << (int)(1000 * dt) << "ms, mAvgDtOut " << (int)(1000 * mAvgDtOut) << "ms, maxout " << (int)(maxout) << " bytes/s, mCurrSent " << mCurrSent << " bytes, quota " << (int)(quota) << " bytes"; -#endif - - return quota; -} - -int pqistreamer::inAllowedBytes() -{ - double t = getCurrentTS(); // in sec, with high accuracy - - // allow a lot if not bandwidthLimited() - if (!mBio->bandwidthLimited()) - { - mCurrRead = 0; - mCurrReadTS = t; - return PQISTREAM_ABS_MAX; - } - - // dt is the time elapsed since the last round of receiving data - double dt = t - mCurrReadTS; - - // limit dt to 1s - if (dt > 1) - dt = 1; - - // low pass filter on mAvgDtIn - mAvgDtIn = PQISTREAM_AVG_DT_FRAC * mAvgDtIn + (1 - PQISTREAM_AVG_DT_FRAC) * dt; - - double maxin = getMaxRate(true) * 1024.0; - - // this is used to take into account a possible excess/deficit of data received during the previous round - mCurrRead -= int(dt * maxin); - - // we allow negative value up to the average amount of data received during one round - // in that case we will use this credit during the next around - if (mCurrRead < - mAvgDtIn * maxin) - mCurrRead = - mAvgDtIn * maxin; - - mCurrReadTS = t; - - // we now calculate the max amount of data allowed to be received during the next round - // we take into account the excess/deficit of the previous round - double quota = mAvgDtIn * maxin - mCurrRead; - -#ifdef DEBUG_PQISTREAMER - RsDbg() << "PQISTREAMER pqistreamer::inAllowedBytes() dt " << std::dec << (int)(1000 * dt) << "ms, mAvgDtIn " << (int)(1000 * mAvgDtIn) << "ms, maxin " << (int)(maxin) << " bytes/s, mCurrRead " << mCurrRead << " bytes, quota " << (int)(quota) << " bytes"; -#endif - - return quota; -} - -void pqistreamer::outSentBytes_locked(uint32_t outb) -{ -#ifdef DEBUG_PQISTREAMER - { - std::string out; - rs_sprintf(out, "pqistreamer::outSentBytes(): %d@%gkB/s", outb, RateInterface::getRate(false)); - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out); - } -#endif - - /*** One theory for the massive delays - is that the queue here is filling up ****/ -//#define DEBUG_LAG 1 -#ifdef DEBUG_LAG - -#define MIN_PKTS_FOR_MSG 100 - if (out_queue_size() > MIN_PKTS_FOR_MSG) - { - std::cerr << "pqistreamer::outSentBytes() for: " << PeerId(); - std::cerr << " End of Write and still " << out_queue_size() << " pkts left"; - std::cerr << std::endl; - } - -#endif - mTotalSent += outb; - mCurrSent += outb; - mAvgSentCount += outb; - PQInterface::traf_out += outb; - return; -} - -void pqistreamer::inReadBytes(uint32_t inb) -{ -#ifdef DEBUG_PQISTREAMER - { - std::string out; - rs_sprintf(out, "pqistreamer::inReadBytes(): %d@%gkB/s", inb, RateInterface::getRate(true)); - pqioutput(PQL_DEBUG_ALL, pqistreamerzone, out); - } -#endif - - mTotalRead += inb; - mCurrRead += inb; - mAvgReadCount += inb; - PQInterface::traf_in += inb; - return; -} - -void pqistreamer::allocate_rpend() -{ - if(mPkt_rpending) - return; - - mPkt_rpend_size = getRsPktMaxSize(); - mPkt_rpending = rs_malloc(mPkt_rpend_size); - - if(mPkt_rpending == NULL) - return ; - - // avoid uninitialized (and random) memory read. - memset(mPkt_rpending,0,mPkt_rpend_size) ; -} - -// clean everything that is half-finished, to avoid causing issues when re-connecting later on. - -int pqistreamer::reset() -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ -#ifdef DEBUG_PQISTREAMER - std::cerr << "pqistreamer::reset()" << std::endl; -#endif - free_pend(); - - return 1 ; -} - -void pqistreamer::free_pend() -{ - if(mPkt_rpending) - { -#ifdef DEBUG_PQISTREAMER - std::cerr << "pqistreamer::free_pend(): pending input packet buffer" << std::endl; -#endif - free(mPkt_rpending); - mPkt_rpending = 0; - } - mPkt_rpend_size = 0; - - if (mPkt_wpending) - { -#ifdef DEBUG_PQISTREAMER - std::cerr << "pqistreamer::free_pend(): pending output packet buffer" << std::endl; -#endif - free(mPkt_wpending); - mPkt_wpending = NULL; - } - mPkt_wpending_size = 0 ; - -#ifdef DEBUG_PQISTREAMER - if(!mPartialPackets.empty()) - std::cerr << "pqistreamer::free_pend(): " << mPartialPackets.size() << " pending input partial packets" << std::endl; -#endif - // also delete any incoming partial packet - for(std::map::iterator it(mPartialPackets.begin());it!=mPartialPackets.end();++it) - free(it->second.mem) ; - - mPartialPackets.clear() ; - - // clean up outgoing. (cntrl packets) - locked_clear_out_queue() ; -} - -int pqistreamer::gatherStatistics(std::list& outqueue_lst,std::list& inqueue_lst) -{ - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - - return locked_gatherStatistics(outqueue_lst,inqueue_lst); -} - -// this method is overloaded by pqiqosstreamer -int pqistreamer::getQueueSize(bool in) -{ - if (in) -// no mutex is needed here because this is atomic - return mIncomingSize; - else - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - return locked_out_queue_size(); - } -} - -int pqistreamer::getQueueSize_bytes(bool in) -{ - if (in) -// no mutex is needed here because this is atomic -// for future use, mIncomingSize_bytes is not updated yet - return mIncomingSize_bytes; - else - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - return locked_compute_out_pkt_size(); - } -} - -void pqistreamer::getRates(RsBwRates &rates) -{ - RateInterface::getRates(rates); - -// no mutex is needed here because this is atomic - rates.mQueueIn = mIncomingSize; - - { - RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/ - rates.mQueueOut = locked_out_queue_size(); - } -} - -// this method is overloaded by pqiqosstreamer -int pqistreamer::locked_out_queue_size() const -{ - // Warning: because out_pkt is a list, calling size - // is O(n) ! Makign algorithms pretty inefficient. We should record how many - // items get stored and discarded to have a proper size value at any time - // - return mOutPkts.size() ; -} - -// this method is overloaded by pqiqosstreamer -void pqistreamer::locked_clear_out_queue() -{ - for(std::list::iterator it = mOutPkts.begin(); it != mOutPkts.end(); ) - { - free(*it); - it = mOutPkts.erase(it); -#ifdef DEBUG_PQISTREAMER - std::string out = "pqistreamer::locked_clear_out_queue() Not active -> Clearing Pkt!"; - std::cerr << out << std::endl; - pqioutput(PQL_DEBUG_BASIC, pqistreamerzone, out); -#endif - } -} - -// this method is overloaded by pqiqosstreamer -int pqistreamer::locked_compute_out_pkt_size() const -{ - int total = 0 ; - - for(std::list::const_iterator it = mOutPkts.begin(); it != mOutPkts.end(); ++it) - total += getRsItemSize(*it); - - return total ; -} - -int pqistreamer::locked_gatherStatistics(std::list& out_lst,std::list& in_lst) -{ - out_lst = mPreviousStatsChunk_Out ; - in_lst = mPreviousStatsChunk_In ; - - return 1 ; -} - -// this method is overloaded by pqiqosstreamer -void *pqistreamer::locked_pop_out_data(uint32_t /*max_slice_size*/, uint32_t &size, bool &starts, bool &ends, uint32_t &packet_id) -{ - size = 0 ; - starts = true ; - ends = true ; - packet_id = 0 ; - - void *res = NULL ; - - if (!mOutPkts.empty()) - { - res = *(mOutPkts.begin()); - mOutPkts.pop_front(); -#ifdef DEBUG_TRANSFERS - std::cerr << "pqistreamer::locked_pop_out_data() getting next pkt from mOutPkts queue"; - std::cerr << std::endl; -#endif - } - return res ; -} - diff --git a/libretroshare/src/pqi/pqistreamer.h b/libretroshare/src/pqi/pqistreamer.h deleted file mode 100644 index 0e7f6b815..000000000 --- a/libretroshare/src/pqi/pqistreamer.h +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqistreamer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_STREAMER_HEADER -#define MRK_PQI_STREAMER_HEADER - -#include // for uint32_t -#include "util/rstime.h" // for rstime_t -#include // for operator<<, basic_ostream, cerr, endl -#include // for list -#include // for map - -#include "pqi/pqi_base.h" // for BinInterface (ptr only), PQInterface -#include "retroshare/rsconfig.h" // for RSTrafficClue -#include "retroshare/rstypes.h" // for RsPeerId -#include "util/rsthreads.h" // for RsMutex - -struct RsItem; -class RsSerialiser; - -struct PartialPacketRecord -{ - void *mem ; - uint32_t size ; -}; - -/** - * @brief Fully implements the PQInterface and communicates with peer etc via - * the BinInterface. - * The interface does not handle connection, just communication. - * Possible BIN_FLAGS: BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE - */ -class pqistreamer: public PQInterface -{ - public: - pqistreamer(RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin); - virtual ~pqistreamer(); - - // PQInterface - virtual int SendItem(RsItem *item) - { - std::cerr << "Warning pqistreamer::sendItem(RsItem*) should not be called. Plz call SendItem(RsItem *,uint32_t& serialized_size) instead." << std::endl; - uint32_t serialized_size ; - return SendItem(item,serialized_size) ; - } - virtual int SendItem(RsItem *,uint32_t& serialized_size); - virtual RsItem *GetItem(); - virtual int status(); - - rstime_t getLastIncomingTS(); // Time of last data packet, for checking a connection is alive. - virtual void getRates(RsBwRates &rates); - virtual int getQueueSize(bool in); // extracting data. - virtual int getQueueSize_bytes(bool in); // size of incoming queue in bytes - virtual int gatherStatistics(std::list& outqueue_stats,std::list& inqueue_stats); // extracting data. - - // mutex protected versions of RateInterface calls. - virtual void setRate(bool b,float f) ; - virtual void setMaxRate(bool b,float f) ; - virtual void setMaxRate_locked(bool b,float f) ; - - virtual float getRate(bool b) ; - virtual float getMaxRate(bool b) ; - virtual float getMaxRate_locked(bool b); - - protected: - virtual int reset() ; - - int tick_bio(); - int tick_send(uint32_t timeout); - int tick_recv(uint32_t timeout); - - /* Implementation */ - - // These methods are redefined in pqiQoSstreamer - // - virtual void locked_storeInOutputQueue(void *ptr, int size, int priority) ; - virtual int locked_out_queue_size() const ; - virtual void locked_clear_out_queue() ; - virtual int locked_compute_out_pkt_size() const ; - virtual void *locked_pop_out_data(uint32_t max_slice_size,uint32_t& size,bool& starts,bool& ends,uint32_t& packet_id); - virtual int locked_gatherStatistics(std::list& outqueue_stats,std::list& inqueue_stats); // extracting data. - - void updateRates() ; - - protected: - RsMutex mStreamerMtx ; // Protects data, fns below, protected so pqiqos can use it too. - - // Binary Interface for IO, initialisated at startup. - BinInterface *mBio; - unsigned int mBio_flags; // BIN_FLAGS_NO_CLOSE | BIN_FLAGS_NO_DELETE - - private: - int queue_outpqi_locked(RsItem *i,uint32_t& serialized_size); - int handleincomingitem(RsItem *i, int len); - - // ticked regularly (manages out queues and sending - // via above interfaces. - virtual int handleoutgoing_locked(); - virtual int handleincoming(); - - // Bandwidth/Streaming Management. - float outTimeSlice_locked(); - - int outAllowedBytes_locked(); - void outSentBytes_locked(uint32_t ); - - int inAllowedBytes(); - void inReadBytes(uint32_t ); - - // cleans up everything that's pending / half finished. - void free_pend(); - - // RsSerialiser - determines which packets can be serialised. - RsSerialiser *mRsSerialiser; - - void *mPkt_wpending; // storage for pending packet to write. - uint32_t mPkt_wpending_size; // ... and its size. - - void allocate_rpend(); // use these two functions to allocate/free the buffer below - - int mPkt_rpend_size; // size of pkt_rpending. - void *mPkt_rpending; // storage for read in pending packets. - - enum {reading_state_packet_started=1, reading_state_initial=0 } ; - - int mReading_state ; - int mFailed_read_attempts ; - - // Temp Storage for transient data..... - std::list mOutPkts; // Cntrl / Search / Results queue - std::list mIncoming; - - uint32_t mIncomingSize; // size of mIncoming. To avoid calling linear cost std::list::size() - uint32_t mIncomingSize_bytes; // size of Incoming in btyes - - // data for network stats. - int mTotalRead; - int mTotalSent; - - // these are representative (but not exact) - int mCurrRead; - int mCurrSent; - - double mCurrReadTS; // TS from which these are measured. - double mCurrSentTS; - - double mAvgLastUpdate; // TS from which these are measured. - uint32_t mAvgReadCount; - uint32_t mAvgSentCount; - - double mAvgDtOut; // average time diff between 2 rounds of sending data - double mAvgDtIn; // average time diff between 2 rounds of receiving data - - rstime_t mLastIncomingTs; - - // traffic statistics - - std::list mPreviousStatsChunk_In ; - std::list mPreviousStatsChunk_Out ; - std::list mCurrentStatsChunk_In ; - std::list mCurrentStatsChunk_Out ; - rstime_t mStatisticsTimeStamp ; - - bool mAcceptsPacketSlicing ; - rstime_t mLastSentPacketSlicingProbe ; - void locked_addTrafficClue(const RsItem *pqi, uint32_t pktsize, std::list &lst); - RsItem *addPartialPacket(const void *block, uint32_t len, uint32_t slice_packet_id,bool packet_starting,bool packet_ending,uint32_t& total_len); - - std::map mPartialPackets ; -}; - -#endif //MRK_PQI_STREAMER_HEADER diff --git a/libretroshare/src/pqi/pqithreadstreamer.cc b/libretroshare/src/pqi/pqithreadstreamer.cc deleted file mode 100644 index 6745dc864..000000000 --- a/libretroshare/src/pqi/pqithreadstreamer.cc +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqithreadstreamer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstime.h" -#include "pqi/pqithreadstreamer.h" -#include - -#define DEFAULT_STREAMER_TIMEOUT 10000 // 10 ms -#define DEFAULT_STREAMER_SLEEP 30000 // 30 ms -#define DEFAULT_STREAMER_IDLE_SLEEP 1000000 // 1 sec - -// #define PQISTREAMER_DEBUG - -pqithreadstreamer::pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& id, BinInterface *bio_in, int bio_flags_in) -:pqistreamer(rss, id, bio_in, bio_flags_in), mParent(parent), mTimeout(0), mThreadMutex("pqithreadstreamer") -{ - mTimeout = DEFAULT_STREAMER_TIMEOUT; - mSleepPeriod = DEFAULT_STREAMER_SLEEP; -} - -bool pqithreadstreamer::RecvItem(RsItem *item) -{ - return mParent->RecvItem(item); -} - -int pqithreadstreamer::tick() -{ - // pqithreadstreamer mutex lock is not needed here - // we will only check if the connection is active, and if not we will try to establish it - tick_bio(); - - return 0; -} - -void pqithreadstreamer::threadTick() -{ - uint32_t recv_timeout = 0; - uint32_t sleep_period = 0; - bool isactive = false; - - { - RsStackMutex stack(mStreamerMtx); - recv_timeout = mTimeout; - sleep_period = mSleepPeriod; - isactive = mBio->isactive(); - } - - // update the connection rates - updateRates() ; - - // if the connection est not active, long sleep then return - if (!isactive) - { - rstime::rs_usleep(DEFAULT_STREAMER_IDLE_SLEEP); - return ; - } - - // fill incoming queue with items from SSL - { - RsStackMutex stack(mThreadMutex); - tick_recv(recv_timeout); - } - - // move items to appropriate service queue or shortcut to fast service - RsItem *incoming = NULL; - while((incoming = GetItem())) - { - RecvItem(incoming); - } - - // parse the outgoing queue and send items to SSL - { - RsStackMutex stack(mThreadMutex); - tick_send(0); - } - - // sleep - if (sleep_period) - { - rstime::rs_usleep(sleep_period); - } -} - diff --git a/libretroshare/src/pqi/pqithreadstreamer.h b/libretroshare/src/pqi/pqithreadstreamer.h deleted file mode 100644 index 7ba1690c8..000000000 --- a/libretroshare/src/pqi/pqithreadstreamer.h +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqithreadstreamer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_PQI_THREAD_STREAMER_HEADER -#define MRK_PQI_THREAD_STREAMER_HEADER - -#include "pqi/pqistreamer.h" -#include "util/rsthreads.h" - -class pqithreadstreamer: public pqistreamer, public RsTickingThread -{ -public: - pqithreadstreamer(PQInterface *parent, RsSerialiser *rss, const RsPeerId& peerid, BinInterface *bio_in, int bio_flagsin); - - // from pqistreamer - virtual bool RecvItem(RsItem *item); - virtual int tick(); - -protected: - void threadTick() override; /// @see RsTickingThread - - PQInterface *mParent; - uint32_t mTimeout; - uint32_t mSleepPeriod; - -private: - /* thread variables */ - RsMutex mThreadMutex; -}; - -#endif //MRK_PQI_THREAD_STREAMER_HEADER diff --git a/libretroshare/src/pqi/sslfns.cc b/libretroshare/src/pqi/sslfns.cc deleted file mode 100644 index cb799ed86..000000000 --- a/libretroshare/src/pqi/sslfns.cc +++ /dev/null @@ -1,886 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: sslfns.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* Functions in this file are SSL only, - * and have no dependence on SSLRoot() etc. - * might need SSL_Init() to be called - thats it! - */ - -/******************** notify of new Cert **************************/ - -#include "pqi/sslfns.h" -#include "pqi/pqi_base.h" -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "pqi/authssl.h" - -#include -#include -#include -#include - -#include -#include -#include - -/**** - * #define AUTHSSL_DEBUG 1 - ***/ - -/********************************************************************************/ - -#if defined(SSLFNS_ADD_CIPHER_CTX_RAND_KEY) - -int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) -{ - //if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) - // return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); - if (RAND_bytes(key, ctx->key_len) <= 0) - return 0; - return 1; -} - -#endif - -/********************************************************************************/ -/********************************************************************************/ - -X509_REQ *GenerateX509Req( - std::string pkey_file, std::string passwd, - std::string name, std::string email, std::string org, - std::string loc, std::string state, std::string country, - int nbits_in, std::string &errString) -{ - /* generate request */ - X509_REQ *req=X509_REQ_new(); - - // setup output. - BIO *bio_out = BIO_new(BIO_s_file()); - BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); - - EVP_PKEY *pkey = NULL; - X509_NAME *x509_name = NULL ; - RSA *rsa = NULL ; - - 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; - - 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_new(); - if ((rsa == NULL) || !EVP_PKEY_assign_RSA(pkey, rsa)) - throw std::runtime_error("Couldn't generate RSA Key"); - - BIGNUM *ebn = BN_new(); - BN_set_word(ebn, e); - RSA_generate_key_ex(rsa, nbits, ebn, NULL); - - // 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 + "\""); - - const EVP_CIPHER *cipher = EVP_des_ede3_cbc(); - - 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+"\""); - } - - fclose(out); - - // We have now created a private key.... - std::cerr << "GenerateX509Req() Saved Private Key to file \"" << pkey_file << "\"" << std::endl; - - /********** 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"))) - throw std::runtime_error("GenerateX509Req() Couldn't Open Private Key file \""+pkey_file+"\"") ; - - 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+"\"") ; - } - - fclose(tst_in); - EVP_PKEY_free(tst_pkey); - - /* Fill in details: fields. - req->req_info; - req->req_info->enc; - req->req_info->version; - req->req_info->subject; - req->req_info->pubkey; - ****************************/ - - long version = 0x00; - unsigned long chtype = MBSTRING_UTF8; - x509_name = X509_NAME_new(); - - // fill in the request. - - /**** X509_REQ -> Version ********************************/ - if(!X509_REQ_set_version(req,version)) /* version 1 */ - throw std::runtime_error("GenerateX509Req(): Couldn't Set SSL certificate Version!"); - - /**** X509_REQ -> Version ********************************/ - /**** X509_REQ -> Key ********************************/ - - if (!X509_REQ_set_pubkey(req,pkey)) - throw std::runtime_error("GenerateX509Req(): Couldn't Set SSL certificate PUBKEY!"); - - /**** SUBJECT ********************************/ - // create the name. - - // 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.") ; - - 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_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(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(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)) - throw std::runtime_error("GenerateX509Req() Couldn't Set Name to Request!"); - - X509_NAME_free(x509_name); - - /**** SUBJECT ********************************/ - - if (!X509_REQ_sign(req,pkey,EVP_sha1())) - throw std::runtime_error("GenerateX509Req() Failed to sign REQ"); - - errString = "No Error"; - - 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 - -#ifdef UNUSED_CODE -X509 *SignX509Certificate(X509_NAME *issuer, EVP_PKEY *privkey, X509_REQ *req, long days) -{ - const EVP_MD *digest = EVP_sha1(); - ASN1_INTEGER *serial = ASN1_INTEGER_new(); - EVP_PKEY *tmppkey; - X509 *x509 = X509_new(); - if (x509 == NULL) - return NULL; - - BIGNUM *btmp = BN_new(); - if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," pseudo_rand\n"); - - return NULL; - } - if (!BN_to_ASN1_INTEGER(btmp, serial)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," int\n"); - - return NULL; - } - BN_free(btmp); - - if (!X509_set_serialNumber(x509, serial)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," serialNumber\n"); - - return NULL; - } - ASN1_INTEGER_free(serial); - - if (!X509_set_issuer_name(x509, issuer)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," issuer\n"); - - return NULL; - } - - if (!X509_gmtime_adj(x509->cert_info->validity->notBefore, 0)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," notBefore\n"); - - return NULL; - } - - //x509->cert_info->validity->notAfter - //if (!X509_gmtime_adj(X509_get_notAfter(x509), (long)60*60*24*days)) - if (!X509_gmtime_adj(x509->cert_info->validity->notAfter, (long)60*60*24*days)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," notAfter\n"); - - return NULL; - } - - if (!X509_set_subject_name(x509, X509_REQ_get_subject_name(req))) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," subject_name\n"); - - return NULL; - } - - - tmppkey = X509_REQ_get_pubkey(req); - if (!tmppkey || !X509_set_pubkey(x509,tmppkey)) - { - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," pubkey\n"); - - return NULL; - } - - - /* Cleanup Algorithm part */ - - X509_ALGOR *algor1 = x509->cert_info->signature; - X509_ALGOR *algor2 = x509->sig_alg; - - X509_ALGOR *a; - - a = algor1; - ASN1_TYPE_free(a->parameter); - a->parameter=ASN1_TYPE_new(); - a->parameter->type=V_ASN1_NULL; - - ASN1_OBJECT_free(a->algorithm); - a->algorithm=OBJ_nid2obj(digest->pkey_type); - - a = algor2; - ASN1_TYPE_free(a->parameter); - a->parameter=ASN1_TYPE_new(); - a->parameter->type=V_ASN1_NULL; - - ASN1_OBJECT_free(a->algorithm); - a->algorithm=OBJ_nid2obj(digest->pkey_type); - - - if (!X509_sign(x509,privkey,digest)) - { - long e = ERR_get_error(); - - fprintf(stderr,"SignX509Certificate() Failed: "); - fprintf(stderr," signing Error: %ld\n", e); - - fprintf(stderr,"ERR: %s, %s, %s\n", - ERR_lib_error_string(e), - ERR_func_error_string(e), - ERR_reason_error_string(e)); - - int inl=i2d_X509(x509,NULL); - int outl=EVP_PKEY_size(privkey); - fprintf(stderr,"Size Check: inl: %d, outl: %d\n", inl, outl); - - return NULL; - } - - fprintf(stderr,"SignX509Certificate() Success\n"); - - return x509; -} -#endif - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - /* Sign / Encrypt / Verify Data */ -bool SSL_SignDataBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int *signlen, EVP_PKEY *pkey) -{ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - unsigned int req_signlen = EVP_PKEY_size(pkey); - if (req_signlen > *signlen) - { - /* not enough space */ - std::cerr << "SignDataBin() Not Enough Sign SpacegnInit Failure!" << std::endl; - return false; - } - - if (0 == EVP_SignInit(mdctx, EVP_sha1())) - { - std::cerr << "EVP_SignInit Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if (0 == EVP_SignUpdate(mdctx, data, len)) - { - std::cerr << "EVP_SignUpdate Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if (0 == EVP_SignFinal(mdctx, sign, signlen, pkey)) - { - std::cerr << "EVP_SignFinal Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - EVP_MD_CTX_destroy(mdctx); - return true; -} - -bool SSL_VerifySignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen, X509 *cert) -{ - - /* cert->cert_info->key->pkey is NULL.... - * but is instantiated when we call X509_get_pubkey() - */ - - EVP_PKEY *peerkey = X509_get_pubkey(cert); - - /* must free this key afterwards */ - bool ret = SSL_VerifySignBin(data, len, sign, signlen, peerkey); - - EVP_PKEY_free(peerkey); - - return ret; -} - -/* Correct form of this function ... Internal for AuthSSL's usage - */ - -bool SSL_VerifySignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen, EVP_PKEY *peerkey) -{ - if(peerkey == NULL) - { - std::cerr << "VerifySignBin: no public key available !!" << std::endl ; - return false ; - } - - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - if (0 == EVP_VerifyInit(mdctx, EVP_sha1())) - { - std::cerr << "EVP_VerifyInit Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if (0 == EVP_VerifyUpdate(mdctx, data, len)) - { - std::cerr << "EVP_VerifyUpdate Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - if(signlen == 0 || sign == NULL) - { - std::cerr << "AuthSSL::VerifySignBin: signlen=" << signlen << ", sign=" << (void*)sign << "!!" << std::endl ; - EVP_MD_CTX_destroy(mdctx); - return false ; - } - - if (0 == EVP_VerifyFinal(mdctx, sign, signlen, peerkey)) - { - std::cerr << "EVP_VerifyFinal Failure!" << std::endl; - - EVP_MD_CTX_destroy(mdctx); - return false; - } - - EVP_MD_CTX_destroy(mdctx); - return true; -} - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -X509 *loadX509FromPEM(std::string pem) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "loadX509FromPEM()"; - std::cerr << std::endl; -#endif - - /* Put the data into a mem BIO */ - char *certstr = strdup(pem.c_str()); - - BIO *bp = BIO_new_mem_buf(certstr, -1); - - X509 *pc = PEM_read_bio_X509(bp, NULL, NULL, NULL); - - BIO_free(bp); - free(certstr); - - return pc; -} - -std::string saveX509ToPEM(X509* x509) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "saveX509ToPEM() " << std::endl; -#endif - - /* get the cert first */ - std::string certstr; - BIO *bp = BIO_new(BIO_s_mem()); - - PEM_write_bio_X509(bp, x509); - - /* translate the bp data to a string */ - char *data; - int len = BIO_get_mem_data(bp, &data); - for(int i = 0; i < len; i++) - { - certstr += data[i]; - } - - BIO_free(bp); - - return certstr; -} - - -X509 *loadX509FromDER(const uint8_t *ptr, uint32_t len) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL::LoadX509FromDER()"; - std::cerr << std::endl; -#endif - - X509 *tmp = NULL; -#ifdef __APPLE__ - // This depends on which version you are compiling for... OSX10.5 doesn't have consts (old OpenSSL!) - // With the Advent of Openpgpsdk, we are forced to move to OSX10.6 for a newer OpenSSL (probably a good thing). - // So we can change this around. - //unsigned char **certptr = (unsigned char **) &ptr; - const unsigned char **certptr = (const unsigned char **) &ptr; -#else - const unsigned char **certptr = (const unsigned char **) &ptr; -#endif - - X509 *x509 = d2i_X509(&tmp, certptr, len); - - return x509; -} - -bool saveX509ToDER(X509 *x509, uint8_t **ptr, uint32_t *len) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL::saveX509ToDER()"; - std::cerr << std::endl; -#endif - - int certlen = i2d_X509(x509, (unsigned char **) ptr); - if (certlen > 0) - { - *len = certlen; - return true; - } - else - { - *len = 0; - return false; - } - return false; -} - - -bool getX509id(X509 *x509, RsPeerId& xid) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL::getX509id()"; - std::cerr << std::endl; -#endif - - xid.clear() ; - if (x509 == NULL) - { -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL::getX509id() NULL pointer"; - std::cerr << std::endl; -#endif - return false; - } - - // get the signature from the cert, and copy to the array. -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - ASN1_BIT_STRING *signature = x509->signature; -#else - const ASN1_BIT_STRING *signature = NULL ; - const X509_ALGOR *algor ; - - X509_get0_signature(&signature,&algor,x509); -#endif - - uint32_t version_number = getX509RetroshareCertificateVersion(x509) ; - - if(version_number >= RS_CERTIFICATE_VERSION_NUMBER_06_0001) - { - // What: Computes the node id by performing a sha256 hash of the certificate's PGP signature, instead of simply picking up the last 20 bytes of it. - // - // Why: There is no real risk in forging a certificate with the same ID as the authentication is performed over the PGP signature of the certificate - // which hashes the full SSL certificate (i.e. the full serialized CERT_INFO structure). However the possibility to - // create two certificates with the same IDs is a problem, as it can be used to cause disturbance in the software. - // - // Backward compat: makes connexions impossible with non patched peers, probably because the SSL id that is computed is not the same on both side, - // and in particular unpatched peers see a cerficate with ID different (because computed with the old method) than the ID that was - // submitted when making friends. - // - // Note: the advantage of basing the ID on the signature rather than the public key is not very clear, given that the signature is based on a hash - // of the public key (and the rest of the certificate info). - // - - if(RsPeerId::SIZE_IN_BYTES > Sha256CheckSum::SIZE_IN_BYTES) - return false ; - - xid = RsPeerId(RsDirUtil::sha256sum(ASN1_STRING_data(const_cast(signature)),ASN1_STRING_length(signature)).toByteArray()) ; - } - else - { - int signlen = ASN1_STRING_length(signature); - if (signlen < CERTSIGNLEN) - { -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL::getX509id() ERROR: Short Signature"; - std::cerr << std::endl; -#endif - return false; - } - - // else copy in the first CERTSIGNLEN. - unsigned char *signdata = ASN1_STRING_data(const_cast(signature)); - - /* switched to the other end of the signature. for - * more randomness - */ - -#warning csoler 2017-02-19: This is cryptographically horrible. We should hash the entire signature here! - - xid = RsPeerId(&signdata[signlen - CERTSIGNLEN]) ; - } - - return true; -} - - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -int pem_passwd_cb(char *buf, int size, int rwflag, void *password) -{ - /* remove unused parameter warnings */ - (void) rwflag; - - strncpy(buf, (char *)(password), size); - buf[size - 1] = '\0'; - return(strlen(buf)); -} - -uint64_t getX509SerialNumber(X509 *cert) -{ - ASN1_INTEGER *serial = X509_get_serialNumber(cert); - - BIGNUM *btmp = ASN1_INTEGER_to_BN(serial, NULL); - - uint64_t res = BN_get_word(btmp) ; - BN_free(btmp); - - return res ; -} - -uint32_t getX509RetroshareCertificateVersion(X509 *cert) -{ - // Because the serial number was totally random before being used to identity the handshake protocol, we check if we see known version strings. If not, - // we assume v0.6-0000 - // - // We compare the uint32_t into a uint64_t on purpose,to make sure that the highest bits are 0 and not random. - - switch(getX509SerialNumber(cert)) - { - case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_06_0000): return RS_CERTIFICATE_VERSION_NUMBER_06_0000 ; - case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_06_0001): return RS_CERTIFICATE_VERSION_NUMBER_06_0001 ; - case uint64_t(RS_CERTIFICATE_VERSION_NUMBER_07_0001): return RS_CERTIFICATE_VERSION_NUMBER_07_0001 ; - default: - return RS_CERTIFICATE_VERSION_NUMBER_06_0000; - } -} - -std::string getX509NameString(X509_NAME *name) -{ - std::string namestr; - for(int i = 0; i < X509_NAME_entry_count(name); i++) - { - X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); - ASN1_STRING *entry_data = X509_NAME_ENTRY_get_data(entry); - ASN1_OBJECT *entry_obj = X509_NAME_ENTRY_get_object(entry); - - namestr += "\t"; - namestr += OBJ_nid2ln(OBJ_obj2nid(entry_obj)); - namestr += " : "; - - //namestr += entry_obj -> flags; - //namestr += entry_data -> length; - //namestr += entry_data -> type; - - //namestr += entry_data -> flags; - //entry -> set; - - if (entry_data -> data != NULL) - { - namestr += (char *) entry_data -> data; - } - else - { - namestr += "NULL"; - } - - if (i + 1 < X509_NAME_entry_count(name)) - { - namestr += "\n"; - } - } - return namestr; -} - -std::string getX509CNString(X509_NAME *name) -{ - std::string namestr; - for(int i = 0; i < X509_NAME_entry_count(name); i++) - { - X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); - ASN1_STRING *entry_data = X509_NAME_ENTRY_get_data(entry); - ASN1_OBJECT *entry_obj = X509_NAME_ENTRY_get_object(entry); - - if (0 == strncmp("CN", OBJ_nid2sn(OBJ_obj2nid(entry_obj)), 2)) - { - if (entry_data -> data != NULL) - { - // do we need to convert ASN1_STRING to utf8 (ASN1_STRING_to_UTF8)? - namestr = (char *) entry_data->data; - } - else - { - namestr = "Unknown"; - } - break; - } - } - return namestr; -} - -std::string getX509TypeString(X509_NAME *name, const char *type, int len) -{ - std::string namestr; - for(int i = 0; i < X509_NAME_entry_count(name); i++) - { - X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); - ASN1_STRING *entry_data = X509_NAME_ENTRY_get_data(entry); - ASN1_OBJECT *entry_obj = X509_NAME_ENTRY_get_object(entry); - - if (0 == strncmp(type, OBJ_nid2sn(OBJ_obj2nid(entry_obj)), len)) - { - if (entry_data -> data != NULL) - { - // do we need to convert ASN1_STRING to utf8 (ASN1_STRING_to_UTF8)? - namestr = (char *) entry_data -> data; - } - else - { - namestr = "Unknown"; - } - break; - } - } - return namestr; -} - -std::string getX509LocString(X509_NAME *name) -{ - return getX509TypeString(name, "L", 2); -} - -std::string getX509OrgString(X509_NAME *name) -{ - return getX509TypeString(name, "O", 2); -} - -std::string getX509CountryString(X509_NAME *name) -{ - return getX509TypeString(name, "C", 2); -} - - -#ifdef AUTHSSL_DEBUG -std::string getX509Info(X509 *cert) -{ - std::string out = "X509 Certificate:\n"; - - long l; - l=X509_get_version(cert); - rs_sprintf_append(out, " Version: %ld(0x%ld)\n", l+1, l); - out += " Subject: \n"; - out += " " + getX509NameString(cert->cert_info->subject) + "\n\n"; - out += " Signatures:\n"; - return out; -} -#endif - -/********** SSL ERROR STUFF ******************************************/ - -int printSSLError( - SSL*, int retval, int err, unsigned long err2, std::string& out ) -{ - std::string reason; - - std::string mainreason = std::string("UNKNOWN ERROR CODE"); - if (err == SSL_ERROR_NONE) - { - mainreason = std::string("SSL_ERROR_NONE"); - } - else if (err == SSL_ERROR_ZERO_RETURN) - { - mainreason = std::string("SSL_ERROR_ZERO_RETURN"); - } - else if (err == SSL_ERROR_WANT_READ) - { - mainreason = std::string("SSL_ERROR_WANT_READ"); - } - else if (err == SSL_ERROR_WANT_WRITE) - { - mainreason = std::string("SSL_ERROR_WANT_WRITE"); - } - else if (err == SSL_ERROR_WANT_CONNECT) - { - mainreason = std::string("SSL_ERROR_WANT_CONNECT"); - } - else if (err == SSL_ERROR_WANT_ACCEPT) - { - mainreason = std::string("SSL_ERROR_WANT_ACCEPT"); - } - else if (err == SSL_ERROR_WANT_X509_LOOKUP) - { - mainreason = std::string("SSL_ERROR_WANT_X509_LOOKUP"); - } - else if (err == SSL_ERROR_SYSCALL) - { - mainreason = std::string("SSL_ERROR_SYSCALL"); - } - else if (err == SSL_ERROR_SSL) - { - mainreason = std::string("SSL_ERROR_SSL"); - } - rs_sprintf_append( out, - "RetVal(%d) -> SSL Error: %s\n\t + ERR Error: %s\n", - retval, mainreason.c_str(), - ERR_error_string(err2, nullptr) ); - return 1; -} - - -std::string sslErrorToString(int retval, int err, unsigned long err2) -{ - std::string ret; - // When printSSLError will be removed it's code will be moved here - printSSLError(nullptr, retval, err, err2, ret); - return ret; -} diff --git a/libretroshare/src/pqi/sslfns.h b/libretroshare/src/pqi/sslfns.h deleted file mode 100644 index c22076c51..000000000 --- a/libretroshare/src/pqi/sslfns.h +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: sslfns.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/* Functions in this file are SSL only, - * and have no dependence on SSLRoot() etc. - * might need SSL_Init() to be called - thats it! - */ - -/******************** notify of new Cert **************************/ - -#include -#include - -#include -#include - -#include "util/rsdeprecate.h" -#include "retroshare/rstypes.h" - - -/**** - * #define AUTHSSL_DEBUG 1 - ***/ - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - -// IF we are compiling against ssl0.9.7 - these functions don't exist. - -#if (OPENSSL_VERSION_NUMBER & 0xfffff000) < 0x00908000 - #define SSLFNS_ADD_CIPHER_CTX_RAND_KEY 1 -#endif - -#if defined(SSLFNS_ADD_CIPHER_CTX_RAND_KEY) - -int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); - -#endif - -// Certificates serial number is used to store the protocol version for the handshake. (*) means current version. -// -// 06_0000: < Nov.2017. -// * 06_0001: > Nov 2017. SSL id is computed by hashing the entire signature of the cert instead of simply picking up the last bytes. -// 07_0001: Signatures are performed using SHA256+RSA instead of SHA1+RSA - -static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_06_0000 = 0x00060000 ; // means version RS-0.6, certificate version 0. Default version before patch. -static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_06_0001 = 0x00060001 ; // means version RS-0.6, certificate version 1. -static const uint32_t RS_CERTIFICATE_VERSION_NUMBER_07_0001 = 0x00070001 ; // means version RS-0.7, certificate version 1. - -X509_REQ *GenerateX509Req( - std::string pkey_file, std::string passwd, - std::string name, std::string email, std::string org, - std::string loc, std::string state, std::string country, - int nbits_in, std::string &errString); - -X509 *SignX509Certificate(X509_NAME *issuer, EVP_PKEY *privkey, X509_REQ *req, long days); - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - - - /* Sign / Encrypt / Verify Data */ -bool SSL_SignDataBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int *signlen, EVP_PKEY *pkey); - -bool SSL_VerifySignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen, X509 *cert); - -bool SSL_VerifySignBin(const void *data, const uint32_t len, - unsigned char *sign, unsigned int signlen, EVP_PKEY *peerkey); - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -X509 *loadX509FromPEM(std::string pem); -std::string saveX509ToPEM(X509* x509); -X509 *loadX509FromDER(const uint8_t *ptr, uint32_t len); -bool saveX509ToDER(X509 *x509, uint8_t **ptr, uint32_t *len); - -bool getX509id(X509 *x509, RsPeerId &xid); - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -int pem_passwd_cb(char *buf, int size, int rwflag, void *password); - -std::string getX509NameString(X509_NAME *name); -std::string getX509CNString(X509_NAME *name); -std::string getX509TypeString(X509_NAME *name, const char *type, int len); -std::string getX509LocString(X509_NAME *name); -std::string getX509OrgString(X509_NAME *name); -std::string getX509CountryString(X509_NAME *name); -std::string getX509Info(X509 *cert); - -uint64_t getX509SerialNumber(X509 *cert); -uint32_t getX509RetroshareCertificateVersion(X509 *cert) ; - -/********** SSL ERROR STUFF ******************************************/ - -RS_DEPRECATED_FOR(sslErrorToString) -int printSSLError( - SSL* unused, int retval, int err, unsigned long err2, std::string& out); - -std::string sslErrorToString(int retval, int err, unsigned long err2); diff --git a/libretroshare/src/retroshare/rsbanlist.h b/libretroshare/src/retroshare/rsbanlist.h deleted file mode 100644 index c46ea0203..000000000 --- a/libretroshare/src/retroshare/rsbanlist.h +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * IPv4 address filtering interface * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include "util/rsnet.h" -#include "util/rstime.h" -#include "util/rsmemory.h" - -class RsBanList; - -/** - * Pointer to global instance of RsBanList service implementation - * @jsonapi{development} - */ -extern RsBanList* rsBanList; - -// TODO: use enum class instead of defines -#define RSBANLIST_ORIGIN_UNKNOWN 0 -#define RSBANLIST_ORIGIN_SELF 1 -#define RSBANLIST_ORIGIN_FRIEND 2 -#define RSBANLIST_ORIGIN_FOF 3 - -#define RSBANLIST_REASON_UNKNOWN 0 -#define RSBANLIST_REASON_USER 1 -#define RSBANLIST_REASON_DHT 2 -#define RSBANLIST_REASON_AUTO_RANGE 3 - -// These are flags. Can be combined. - -#define RSBANLIST_CHECKING_FLAGS_NONE 0x00 -#define RSBANLIST_CHECKING_FLAGS_BLACKLIST 0x01 -#define RSBANLIST_CHECKING_FLAGS_WHITELIST 0x02 - -// These are not flags. Cannot be combined. Used to give the reson for acceptance/denial of connections. - -#define RSBANLIST_CHECK_RESULT_UNKNOWN 0x00 -#define RSBANLIST_CHECK_RESULT_NOCHECK 0x01 -#define RSBANLIST_CHECK_RESULT_BLACKLISTED 0x02 -#define RSBANLIST_CHECK_RESULT_NOT_WHITELISTED 0x03 -#define RSBANLIST_CHECK_RESULT_ACCEPTED 0x04 - -#define RSBANLIST_TYPE_PEERLIST 1 -#define RSBANLIST_TYPE_BLACKLIST 2 -#define RSBANLIST_TYPE_WHITELIST 3 - -class RsTlvBanListEntry; - -class BanListPeer -{ -public: - BanListPeer() ; - - void toRsTlvBanListEntry(RsTlvBanListEntry& e) const ; - void fromRsTlvBanListEntry(const RsTlvBanListEntry& e) ; - - struct sockaddr_storage addr; - uint8_t masked_bytes ; // 0 = []/32. 1=[]/24, 2=[]/16 - uint32_t reason; // User, DHT - uint32_t level; // LOCAL, FRIEND, FoF. - bool state ; // true=>active, false=>just stored but inactive - int connect_attempts ; // recorded by the BanList service - rstime_t mTs; - std::string comment ; // -}; - -class RsBanList -{ -public: - /** - * @brief Enable or disable IP filtering service - * @jsonapi{development} - * @param[in] enable pass true to enable, false to disable - */ - virtual void enableIPFiltering(bool enable) = 0; - - /** - * @brief Get ip filtering service status - * @jsonapi{development} - * @return true if enabled, false if disabled - */ - virtual bool ipFilteringEnabled() = 0; - - /** - * @brief addIpRange - * @param addr full IPv4 address. Port is ignored. - * @param masked_bytes 0=full IP, 1="/24", 2="/16" - * @param list_type RSBANLIST_TYPE_WHITELIST or RSBANLIST_TYPE_BLACKLIST - * @param comment anything, user-based - * @return - */ - virtual bool addIpRange( - const sockaddr_storage& addr, int masked_bytes, uint32_t list_type, - const std::string& comment ) = 0; - - /** - * @brief removeIpRange - * @param addr full IPv4 address. Port is ignored. - * @param masked_bytes 0=full IP, 1="/24", 2="/16" - * @param list_type RSBANLIST_TYPE_WHITELIST or RSBANLIST_TYPE_BLACKLIST - * @return - */ - virtual bool removeIpRange( - const sockaddr_storage& addr, int masked_bytes, uint32_t list_type - ) = 0; - - /** - * @brief isAddressAccepted - * @param addr full IPv4 address. Port is ignored. - * @param checking_flags any combination of - * RSBANLIST_CHECKING_FLAGS_BLACKLIST and - * RSBANLIST_CHECKING_FLAGS_WHITELIST - * @param check_result returned result of the check in - * RSBANLIST_CHECK_RESULT_* - * @return true if address is accepted, false false if address is rejected. - */ - virtual bool isAddressAccepted( - const sockaddr_storage& addr, uint32_t checking_flags, - uint32_t& check_result = RS_DEFAULT_STORAGE_PARAM(uint32_t) ) = 0; - - virtual void getBannedIps(std::list& list) = 0; - virtual void getWhiteListedIps(std::list& list) = 0; - - virtual bool autoRangeEnabled() = 0; - virtual void enableAutoRange(bool b) = 0; - - virtual int autoRangeLimit() = 0; - virtual void setAutoRangeLimit(int n) = 0; - - virtual void enableIPsFromFriends(bool b) = 0; - virtual bool IPsFromFriendsEnabled() = 0; - - virtual void enableIPsFromDHT(bool b) = 0; - virtual bool iPsFromDHTEnabled() = 0; - - virtual ~RsBanList(); -}; diff --git a/libretroshare/src/retroshare/rsbroadcastdiscovery.h b/libretroshare/src/retroshare/rsbroadcastdiscovery.h deleted file mode 100644 index 92b0e5b0e..000000000 --- a/libretroshare/src/retroshare/rsbroadcastdiscovery.h +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * RetroShare Broadcast Domain Discovery * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rsids.h" -#include "retroshare/rstypes.h" -#include "serialiser/rsserializable.h" -#include "util/rstime.h" -#include "util/rsurl.h" -#include "util/rsmemory.h" -#include "retroshare/rsevents.h" - -class RsBroadcastDiscovery; - -/** - * Pointer to global instance of RsBroadcastDiscovery service implementation - * @jsonapi{development} - * - * TODO: this should become std::weak_ptr once we have a reasonable services - * management. - */ -extern RsBroadcastDiscovery* rsBroadcastDiscovery; - - -struct RsBroadcastDiscoveryResult : RsSerializable -{ - RsPgpFingerprint mPgpFingerprint; - RsPeerId mSslId; - std::string mProfileName; - RsUrl mLocator; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(mPgpFingerprint); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mProfileName); - RS_SERIAL_PROCESS(mLocator); - } - - RsBroadcastDiscoveryResult() = default; - RsBroadcastDiscoveryResult (const RsBroadcastDiscoveryResult&) = default; - ~RsBroadcastDiscoveryResult() override; -}; - - -/** - * @brief Event emitted when a non friend new peer is found in the local network - * @see RsEvents - */ -enum class RsBroadcastDiscoveryEventType: uint32_t { - UNKNOWN = 0x00, - PEER_FOUND = 0x01 -}; - -struct RsBroadcastDiscoveryEvent : RsEvent -{ - RsBroadcastDiscoveryEvent() - : RsEvent(RsEventType::BROADCAST_DISCOVERY), - mDiscoveryEventType(RsBroadcastDiscoveryEventType::UNKNOWN) - {} - - virtual ~RsBroadcastDiscoveryEvent() override = default; - - RsBroadcastDiscoveryEventType mDiscoveryEventType; - RsBroadcastDiscoveryResult mData; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mDiscoveryEventType); - RS_SERIAL_PROCESS(mData); - } -}; - - -/** - * Announce own RetroShare instace and look friends and peers in own broadcast - * domain (aka LAN). - * Emit event @see RsBroadcastDiscoveryPeerFoundEvent when a new peer (not - * friend yet) is found. - */ -class RsBroadcastDiscovery -{ -public: - /** - * @brief Get potential peers that have been discovered up until now - * @jsonapi{development} - * @return vector containing discovered peers, may be empty. - */ - virtual std::vector getDiscoveredPeers() = 0; - - /** - * @brief Check if multicast listening is enabled - * @jsonapi{development} - * On some platforms such as Android multicast listening, which is needed - * for broadcast discovery, is not enabled by default at WiFi driver level - * @see enableMulticastListening, so this method check if it is enabled. - * On platforms that are not expected to have such a limitation this method - * always return true. - * @return true if enabled, false otherwise. - */ - virtual bool isMulticastListeningEnabled() = 0; - - /** - * @brief On platforms that need it enable low level multicast listening - * @jsonapi{development} - * On Android and potencially other mobile platforms, WiFi drivers are - * configured by default to discard any packet that is not directed to the - * unicast mac address of the interface, this way they could save some - * battery but breaks anything that is not unicast, such as broadcast - * discovery. On such platforms this method enable low level multicast - * listening so we can receive advertisement from same broadcast domain - * nodes. - * On platforms without such limitation does nothing and always return - * false. - * It is exposed as a public API so the UI can decide the right equilibrium - * between discoverability and battery saving. - * @return true if multicast listening has been enabled due to this call, - * false otherwise. - */ - virtual bool enableMulticastListening() = 0; - - /** - * @brief Disable multicast listening - * @jsonapi{development} - * The opposite of @see enableMulticastListening. - * @return true if multicast listening has been disabled due to this call, - * false otherwise. - */ - virtual bool disableMulticastListening() = 0; - - virtual ~RsBroadcastDiscovery(); -}; diff --git a/libretroshare/src/retroshare/rsconfig.h b/libretroshare/src/retroshare/rsconfig.h deleted file mode 100644 index 918372b79..000000000 --- a/libretroshare/src/retroshare/rsconfig.h +++ /dev/null @@ -1,424 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsconfig.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_CONFIG_GUI_INTERFACE_H -#define RETROSHARE_CONFIG_GUI_INTERFACE_H - -#include -#include -#include -#include -#include - -/* The New Config Interface Class */ -class RsServerConfig; - -/** - * Pointer to global instance of RsServerConfig service implementation - * @jsonapi{development} - */ -extern RsServerConfig *rsConfig; - -enum class RsNetworkMode : uint8_t -{ - UNKNOWN = 1, - RESTARTING = 2, - OFFLINE = 3, - LOCALNET = 4, - BEHINDNAT = 5, - EXTERNALIP = 6 -}; - -enum class RsNatTypeMode : uint8_t -{ - NONE = 1, - UNKNOWN = 2, - SYMMETRIC = 3, - DETERM_SYM = 4, - RESTRICTED_CONE = 5, - FULL_CONE = 6, - OTHER = 7 -}; - -enum class RsNatHoleMode : uint8_t -{ - UNKNOWN = 0, - NONE = 1, - UPNP = 2, - NATPMP = 3, - FORWARDED = 4 -}; - -enum class RsConnectModes : uint16_t -{ - NONE = 0x0000, - ACCEPT_TCP = 0x0001, - OUTGOING_TCP= 0x0002, - DIRECT_UDP = 0x0100, - PROXY_UDP = 0x0200, - RELAY_UDP = 0x0400 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RsConnectModes) - -enum class RsNetState : uint8_t -{ - // BAD. (RED) - BAD_UNKNOWN = 1, - BAD_OFFLINE = 2, - BAD_NATSYM = 3, - BAD_NODHT_NAT = 4, - - // CAUTION. (ORANGE) - WARNING_RESTART = 5, - WARNING_NATTED = 6, - WARNING_NODHT = 7, - - // GOOD (GREEN) - // NAT with forwarded port, or EXT port. - GOOD = 8, - - // ADVANCED MODE (BLUE) - // If the user knows what they are doing... we cannot confirm this. - ADV_FORWARD = 9, - ADV_DARK_FORWARD= 10 -}; - - - -/************************** Indicate How experienced the RsUser is... based on Friends / Firewall status ******/ - -enum class RsConfigUserLvl : uint8_t -{ - NEW = 1, /* no friends */ - BASIC = 2, /* no connections */ - CASUAL = 3, /* firewalled */ - POWER = 4, /* good! */ - OVERRIDE= 5 /* forced to POWER level */ -}; - - - -// Must Match up with strings internal to Retroshare. -#define RS_CONFIG_ADVANCED 0x0101 - - -enum class RsOpMode : uint8_t -{ - FULL = 1, - NOTURTLE= 2, - GAMING = 3, - MINIMAL = 4 -}; - - -class RsConfigStartup -{ - public: - RsConfigStartup() - { - promptAtBoot = 1; - } - - -int promptAtBoot; /* popup the password prompt */ -}; - - -struct RsConfigDataRates : RsSerializable -{ - RsConfigDataRates() : - mRateIn(0), mRateMaxIn(0), mAllocIn(0), - mAllocTs(0), - mRateOut(0), mRateMaxOut(0), mAllowedOut(0), - mAllowedTs(0), - mQueueIn(0), mQueueOut(0) - {} - - /* all in kB/s */ - float mRateIn; - float mRateMaxIn; - float mAllocIn; - - rstime_t mAllocTs; - - float mRateOut; - float mRateMaxOut; - float mAllowedOut; - - rstime_t mAllowedTs; - - int mQueueIn; - int mQueueOut; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(mRateIn); - RS_SERIAL_PROCESS(mRateMaxIn); - RS_SERIAL_PROCESS(mAllocIn); - - RS_SERIAL_PROCESS(mAllocTs); - - RS_SERIAL_PROCESS(mRateOut); - RS_SERIAL_PROCESS(mRateMaxOut); - RS_SERIAL_PROCESS(mAllowedOut); - - RS_SERIAL_PROCESS(mAllowedTs); - - RS_SERIAL_PROCESS(mQueueIn); - RS_SERIAL_PROCESS(mQueueOut); - } -}; - -struct RSTrafficClue : RsSerializable -{ - rstime_t TS ; - uint32_t size ; - uint8_t priority ; - uint16_t service_id ; - uint8_t service_sub_id ; - RsPeerId peer_id ; - uint32_t count ; - - RSTrafficClue() { TS=0;size=0;service_id=0;service_sub_id=0; count=0; } - RSTrafficClue& operator+=(const RSTrafficClue& tc) { size += tc.size; count += tc.count ; return *this ;} - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(TS); - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(priority); - RS_SERIAL_PROCESS(service_id); - RS_SERIAL_PROCESS(service_sub_id); - RS_SERIAL_PROCESS(peer_id); - RS_SERIAL_PROCESS(count); - } -}; - -struct RsConfigNetStatus : RsSerializable -{ - RsConfigNetStatus() : netLocalOk(true) - { - localPort = extPort = 0 ; - firewalled = forwardPort = false ; - DHTActive = uPnPActive = netUpnpOk = netDhtOk = netStunOk = netExtAddressOk = false ; - uPnPState = 0 ; - //DHTPeers = 0 ; - netDhtNetSize = netDhtRsNetSize = 0; - } - - RsPeerId ownId; - std::string ownName; - - std::string localAddr; - int localPort; - std::string extAddr; - int extPort; - std::string extDynDns; - - bool firewalled; - bool forwardPort; - - /* older data types */ - bool DHTActive; - bool uPnPActive; - - int uPnPState; - - /* Flags for Network Status */ - RS_DEPRECATED - bool netLocalOk; /// As of today it's meaningless - bool netUpnpOk; /* upnp is enabled and active */ - bool netDhtOk; /* response from dht */ - bool netStunOk; /* recvd stun / udp packets */ - bool netExtAddressOk;/* from Dht/Stun or External IP Finder */ - - uint32_t netDhtNetSize; /* response from dht */ - uint32_t netDhtRsNetSize;/* response from dht */ - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(ownId); - RS_SERIAL_PROCESS(ownName); - - RS_SERIAL_PROCESS(localAddr); - RS_SERIAL_PROCESS(localPort); - RS_SERIAL_PROCESS(extAddr); - RS_SERIAL_PROCESS(extPort); - RS_SERIAL_PROCESS(extDynDns); - - RS_SERIAL_PROCESS(firewalled); - RS_SERIAL_PROCESS(forwardPort); - - RS_SERIAL_PROCESS(DHTActive); - RS_SERIAL_PROCESS(uPnPActive); - - RS_SERIAL_PROCESS(uPnPState); - - RS_SERIAL_PROCESS(netLocalOk); - RS_SERIAL_PROCESS(netUpnpOk); - RS_SERIAL_PROCESS(netDhtOk); - RS_SERIAL_PROCESS(netStunOk); - RS_SERIAL_PROCESS(netExtAddressOk); - - RS_SERIAL_PROCESS(netDhtNetSize); - RS_SERIAL_PROCESS(netDhtRsNetSize); - } -}; - - -/********* - * This is a new style RsConfig Interface. - * It should contain much of the information for the Options/Config Window. - * - * To start with, I'm going to move the stuff from RsIface::RsConfig into here. - * - */ - - -class RsServerConfig -{ -public: - - RsServerConfig() {} - virtual ~RsServerConfig() {} - - /* From RsIface::RsConfig */ - // Implemented Only this one! - /** - * @brief getConfigNetStatus return the net status - * @jsonapi{development} - * @param[out] status network status - * @return returns 1 on succes and 0 otherwise - */ - virtual int getConfigNetStatus(RsConfigNetStatus &status) = 0; - - // NOT IMPLEMENTED YET! - //virtual int getConfigStartup(RsConfigStartup ¶ms) = 0; - - /** - * @brief getTotalBandwidthRates returns the current bandwidths rates - * @jsonapi{development} - * @param[out] rates - * @return returns 1 on succes and 0 otherwise - */ - virtual int getTotalBandwidthRates(RsConfigDataRates &rates) = 0; - - /** - * @brief getAllBandwidthRates get the bandwidth rates for all peers - * @jsonapi{development} - * @param[out] ratemap map with peers->rates - * @return returns 1 on succes and 0 otherwise - */ - virtual int getAllBandwidthRates(std::map &ratemap) = 0; - - /** - * @brief getTrafficInfo returns a list of all tracked traffic clues - * @jsonapi{development} - * @param[out] out_lst outgoing traffic clues - * @param[out] in_lst incomming traffic clues - * @return returns 1 on succes and 0 otherwise - */ - virtual int getTrafficInfo(std::list& out_lst,std::list& in_lst) = 0 ; - - /* From RsInit */ - - // NOT IMPLEMENTED YET! - //virtual std::string RsConfigDirectory() = 0; - //virtual std::string RsConfigKeysDirectory() = 0; - - //virtual std::string RsProfileConfigDirectory() = 0; - //virtual bool getStartMinimised() = 0; - //virtual std::string getRetroShareLink() = 0; - - //virtual bool getAutoLogin() = 0; - //virtual void setAutoLogin(bool autoLogin) = 0; - //virtual bool RsClearAutoLogin() = 0; - - //virtual std::string getRetroshareDataDirectory() = 0; - - /* New Stuff */ - - virtual RsConfigUserLvl getUserLevel() = 0; - - virtual RsNetState getNetState() = 0; - virtual RsNetworkMode getNetworkMode() = 0; - virtual RsNatTypeMode getNatTypeMode() = 0; - virtual RsNatHoleMode getNatHoleMode() = 0; - virtual RsConnectModes getConnectModes() = 0; - - virtual bool getConfigurationOption(uint32_t key, std::string &opt) = 0; - virtual bool setConfigurationOption(uint32_t key, const std::string &opt) = 0; - - - /* Operating Mode */ - /** - * @brief getOperatingMode get current operating mode - * @jsonapi{development} - * @return return the current operating mode - */ - virtual RsOpMode getOperatingMode() = 0; - - /** - * @brief setOperatingMode set the current oprating mode - * @jsonapi{development} - * @param[in] opMode new opearting mode - * @return - */ - virtual bool setOperatingMode(RsOpMode opMode) = 0; - - /** - * @brief setOperatingMode set the current operating mode from string - * @param[in] opModeStr new operating mode as string - * @return - */ - virtual bool setOperatingMode(const std::string &opModeStr) = 0; - - /* Data Rate Control - to be moved here */ - /** - * @brief SetMaxDataRates set maximum upload and download rates - * @jsonapi{development} - * @param[in] downKb download rate in kB - * @param[in] upKb upload rate in kB - * @return returns 1 on succes and 0 otherwise - */ - virtual int SetMaxDataRates( int downKb, int upKb ) = 0; - - /** - * @brief GetMaxDataRates get maximum upload and download rates - * @jsonapi{development} - * @param[out] inKb download rate in kB - * @param[out] outKb upload rate in kB - * @return returns 1 on succes and 0 otherwise - */ - virtual int GetMaxDataRates( int &inKb, int &outKb ) = 0; - - /** - * @brief GetCurrentDataRates get current upload and download rates - * @jsonapi{development} - * @param[out] inKb download rate in kB - * @param[out] outKb upload rate in kB - * @return returns 1 on succes and 0 otherwise - */ - virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0; - virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb ) = 0; -}; - -#endif diff --git a/libretroshare/src/retroshare/rsdht.h b/libretroshare/src/retroshare/rsdht.h deleted file mode 100644 index f62d029eb..000000000 --- a/libretroshare/src/retroshare/rsdht.h +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsdht.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_DHT_GUI_INTERFACE_H -#define RETROSHARE_DHT_GUI_INTERFACE_H - -#include -#include -#include -#include -#include "util/rsnet.h" -#include "retroshare/rsflags.h" - -/* The Main Interface Class - for information about your Peers */ -class RsDht; -extern RsDht *rsDht; - -//std::ostream &operator<<(std::ostream &out, const RsPhotoShowDetails &detail); -//std::ostream &operator<<(std::ostream &out, const RsPhotoDetails &detail); - -enum class RsDhtPeerType : uint8_t -{ - ANY = 0, - OTHER = 1, - FOF = 2, - FRIEND = 3 -}; - -enum class RsDhtPeerDht : uint8_t -{ - NOT_ACTIVE = 0, - SEARCHING = 1, - FAILURE = 2, - OFFLINE = 3, - UNREACHABLE = 4, - ONLINE = 5 -}; - -enum class RsDhtPeerConnectState : uint8_t -{ - DISCONNECTED = 1, - UDP_STARTED = 2, - CONNECTED = 3 -}; - -enum class RsDhtPeerRequest : uint8_t -{ - STOPPED = 1, - RUNNING = 2 -}; - -enum class RsDhtTouMode : uint8_t -{ - NONE = 0, - DIRECT = 1, - PROXY = 2, - RELAY = 3 -}; - -enum class RsDhtRelayClass : uint8_t -{ - ALL = 0, - GENERAL = 1, - FOF = 2, - FRIENDS = 3, - - NUM_CLASS = 4 -}; - -enum class RsDhtRelayMode : uint16_t -{ - DISABLED= 0x0000, - ENABLED = 0x0001, - - MASK = 0x00f0, - OFF = 0x0010, - ON = 0x0020, - SERVER = 0x0040 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RsDhtRelayMode) - -class RsDhtPeer -{ - public: - RsDhtPeer(); - - int mBucket; - std::string mDhtId; - std::string mAddr; - rstime_t mLastSendTime; - rstime_t mLastRecvTime; - rstime_t mFoundTime; - uint32_t mPeerFlags; - uint32_t mExtraFlags; -}; - -class RsDhtNetPeer -{ - public: - RsDhtNetPeer(); - - std::string mDhtId; - RsPeerId mRsId; - - RsDhtPeerType mPeerType; - RsDhtPeerDht mDhtState; - - std::string mConnectState; // connectLogic. - - RsDhtPeerConnectState mPeerConnectState; - RsDhtTouMode mPeerConnectMode; - bool mExclusiveProxyLock; - - std::string mPeerConnectProxyId; - - RsDhtPeerRequest mPeerReqState; - std::string mCbPeerMsg; // Peer Cb Mgs. - -}; - -class RsDhtRelayEnd -{ - public: - - RsDhtRelayEnd(); - std::string mLocalAddr; - std::string mProxyAddr; - std::string mRemoteAddr; - rstime_t mCreateTS; -}; - -class RsDhtRelayProxy -{ - public: - RsDhtRelayProxy(); - - std::string mSrcAddr; - std::string mDestAddr; - - double mBandwidth; - int mRelayClass; - rstime_t mLastTS; - rstime_t mCreateTS; - - //uint32_t mDataSize; - //rstime_t mLastBandwidthTS; - -}; -class RsDhtFilteredPeer -{ -public: - struct sockaddr_in mAddr; - uint32_t mFilterFlags; /* reasons why we are filtering */ - rstime_t mFilterTS; - rstime_t mLastSeen; -}; - -class RsDht -{ - public: - - RsDht() { return; } -virtual ~RsDht() { return; } - -virtual uint32_t getNetState(uint32_t type) = 0; -virtual int getDhtPeers(int lvl, std::list &peers) = 0; -virtual int getNetPeerList(std::list &peerIds) = 0; -virtual int getNetPeerStatus(const RsPeerId& peerId, RsDhtNetPeer &status) = 0; - -virtual int getRelayEnds(std::list &relayEnds) = 0; -virtual int getRelayProxies(std::list &relayProxies) = 0; - -//virtual int getNetFailedPeer(std::string peerId, PeerStatus &status); - -virtual std::string getUdpAddressString() = 0; - -virtual void getDhtRates(float &read, float &write) = 0; -virtual void getRelayRates(float &read, float &write, float &relay) = 0; - - // Interface for controlling Relays & DHT Relay Mode -virtual int getRelayServerList(std::list &ids) = 0; -virtual int addRelayServer(std::string ids) = 0; -virtual int removeRelayServer(std::string ids) = 0; - -virtual RsDhtRelayMode getRelayMode() = 0; -virtual int setRelayMode(RsDhtRelayMode mode) = 0; - -virtual int getRelayAllowance(RsDhtRelayClass classIdx, uint32_t &count, uint32_t &bandwidth) = 0; -virtual int setRelayAllowance(RsDhtRelayClass classIdx, uint32_t count, uint32_t bandwidth) = 0; - - // So we can provide to clients. -virtual bool getOwnDhtId(std::string &ownDhtId) = 0; - -virtual bool isAddressBanned(const struct sockaddr_storage& raddr) =0; -virtual void getListOfBannedIps(std::list& lst) =0; - -#if 0 -virtual std::string getPeerStatusString(); -virtual std::string getDhtStatusString(); - -virtual int get_dht_queries(std::map &queries); -virtual int get_query_status(std::string id, bdQuerySummary &query); - -virtual int get_peer_status(std::string peerId, PeerStatus &status); - -virtual int get_net_failedpeers(std::list &peerIds); -virtual int get_failedpeer_status(std::string peerId, PeerStatus &status); -#endif - -}; - -#endif diff --git a/libretroshare/src/retroshare/rsdisc.h b/libretroshare/src/retroshare/rsdisc.h deleted file mode 100644 index 06311be6c..000000000 --- a/libretroshare/src/retroshare/rsdisc.h +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * RetroShare gossip discovery - discovery2 retro-compatibility include * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsgossipdiscovery.h" -#include "util/rsdeprecate.h" - -#warning "Including retroshare/rsdisc.h is deprecated, \ -use retroshare/rsgossipdiscovery.h instead" - -using RsDisc RS_DEPRECATED_FOR("RsGossipDiscovery") = RsGossipDiscovery; - -#define rsDisc rsGossipDiscovery.get() diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h deleted file mode 100644 index ec2e7b97f..000000000 --- a/libretroshare/src/retroshare/rsevents.h +++ /dev/null @@ -1,254 +0,0 @@ -/******************************************************************************* - * Retroshare events service * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019-2020 Retroshare Team * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "util/rsmemory.h" -#include "util/rsurl.h" -#include "serialiser/rsserializable.h" -#include "serialiser/rstypeserializer.h" -#include "util/rstime.h" -#include "util/rsdebug.h" - -class RsEvents; - -/** - * Pointer to global instance of RsEvents service implementation - * @jsonapi{development} - * - * TODO: this should become std::weak_ptr once we have a reasonable services - * management. - */ -extern RsEvents* rsEvents; - -/** - * @brief Events types. - * When creating a new type of event, add a new type here and use that to - * initialize mType in the constructor of your derivative of @see RsEvent - */ -enum class RsEventType : uint32_t -{ - __NONE = 0, /// Used internally to detect invalid event type passed - - /// @see RsBroadcastDiscovery - BROADCAST_DISCOVERY = 1, - - /// @see RsDiscPendingPgpReceivedEvent - GOSSIP_DISCOVERY = 2, - - /// @see AuthSSL - AUTHSSL_CONNECTION_AUTENTICATION = 3, - - /// @see pqissl - PEER_CONNECTION = 4, - - /// @see RsGxsChanges, used also in @see RsGxsBroadcast - GXS_CHANGES = 5, - - /// Emitted when a peer state changes, @see RsPeers - PEER_STATE_CHANGED = 6, - - /// @see RsMailStatusEvent - MAIL_STATUS = 7, - - /// @see RsGxsCircleEvent - GXS_CIRCLES = 8, - - /// @see RsGxsChannelEvent - GXS_CHANNELS = 9, - - /// @see RsGxsForumEvent - GXS_FORUMS = 10, - - /// @see RsGxsPostedEvent - GXS_POSTED = 11, - - /// @see RsGxsPostedEvent - GXS_IDENTITY = 12, - - /// @see RsFiles - SHARED_DIRECTORIES = 13, - - /// @see RsFiles - FILE_TRANSFER = 14, - - /// @see RsMsgs - CHAT_MESSAGE = 15, - - /// @see rspeers.h - NETWORK = 16, - - __MAX /// Used internally, keep last -}; - -enum class RsEventsErrorNum : int32_t -{ - EVENT_TYPE_UNDEFINED = 3004, - EVENT_TYPE_OUT_OF_RANGE = 3005, - INVALID_HANDLER_ID = 3006, - NULL_EVENT_POINTER = 3007 -}; - -struct RsEventsErrorCategory: std::error_category -{ - const char* name() const noexcept override - { return "RetroShare Events"; } - - std::string message(int ev) const override - { - switch (static_cast(ev)) - { - case RsEventsErrorNum::EVENT_TYPE_UNDEFINED: - return "Undefined event type"; - case RsEventsErrorNum::EVENT_TYPE_OUT_OF_RANGE: - return "Event type out of range"; - case RsEventsErrorNum::INVALID_HANDLER_ID: - return "Invalid handler id"; - default: - return rsErrorNotInCategory(ev, name()); - } - } - - std::error_condition default_error_condition(int ev) const noexcept override; - - const static RsEventsErrorCategory instance; -}; - - -namespace std -{ -/** Register RsJsonApiErrorNum as an error condition enum, must be in std - * namespace */ -template<> struct is_error_condition_enum : true_type {}; -} - -/** Provide RsEventsErrorNum conversion to std::error_condition, must be in - * same namespace of RsJsonApiErrorNum */ -inline std::error_condition make_error_condition(RsEventsErrorNum e) noexcept -{ - return std::error_condition( - static_cast(e), RsEventsErrorCategory::instance ); -}; - - -/** - * This struct is not meant to be used directly, you should create events type - * deriving from it. - */ -struct RsEvent : RsSerializable -{ -protected: - explicit RsEvent(RsEventType type) : - mType(type), mTimePoint(std::chrono::system_clock::now()) {} - - RsEvent() = delete; - -public: - RsEventType mType; - std::chrono::system_clock::time_point mTimePoint; - - /** - * Derived types must call this method at beginning of their implementation - * of serial_process - * @see RsSerializable - */ - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(mType); - - rstime_t mTime = std::chrono::system_clock::to_time_t(mTimePoint); - RS_SERIAL_PROCESS(mTime); - mTimePoint = std::chrono::system_clock::from_time_t(mTime); - } - - ~RsEvent() override; -}; - -typedef uint32_t RsEventsHandlerId_t; - -class RsEvents -{ -public: - /** - * @brief Post event to the event queue. - * @param[in] event - * @return Success or error details. - */ - virtual std::error_condition postEvent( - std::shared_ptr event ) = 0; - - /** - * @brief Send event directly to handlers. Blocking API - * The handlers get exectuded on the caller thread. - * @param[in] event - * @return Success or error details. - */ - virtual std::error_condition sendEvent( - std::shared_ptr event ) = 0; - - /** - * @brief Generate unique handler identifier - * @return generate Id - */ - virtual RsEventsHandlerId_t generateUniqueHandlerId() = 0; - - /** - * @brief Register events handler - * Every time an event is dispatced the registered events handlers will get - * their method handleEvent called with the event passed as paramether. - * @attention Callbacks must not fiddle internally with methods of this - * class otherwise a deadlock will happen. - * @jsonapi{development,manualwrapper} - * @param multiCallback Function that will be called each time an event - * is dispatched. - * @param[inout] hId Optional storage for handler id, useful to - * eventually unregister the handler later. The - * value may be provided to the function call but - * must habe been generated with - * @see generateUniqueHandlerId() - * @param[in] eventType Optional type of event for which the callback is - * called, if __NONE is passed multiCallback is - * called for every events without filtering. - * @return Success or error details. - */ - virtual std::error_condition registerEventsHandler( - std::function)> multiCallback, - RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0), - RsEventType eventType = RsEventType::__NONE ) = 0; - - /** - * @brief Unregister event handler - * @param[in] hId Id of the event handler to unregister - * @return Success or error details. - */ - virtual std::error_condition unregisterEventsHandler( - RsEventsHandlerId_t hId ) = 0; - - virtual ~RsEvents(); -}; diff --git a/libretroshare/src/retroshare/rsexpr.h b/libretroshare/src/retroshare/rsexpr.h deleted file mode 100644 index 562d6e342..000000000 --- a/libretroshare/src/retroshare/rsexpr.h +++ /dev/null @@ -1,407 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsexpr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Kashif Kaleem * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "util/rsprint.h" -#include "retroshare/rstypes.h" -#include "util/rstime.h" - -/****************************************************************************************** -Enumerations defining the Operators usable in the Boolean search expressions -******************************************************************************************/ - -namespace RsRegularExpression -{ -enum LogicalOperator{ - AndOp=0, /* exp AND exp */ - OrOp=1, /* exp OR exp */ - XorOp=2 /* exp XOR exp */ -}; - - -/* Operators for String Queries */ -enum StringOperator{ - ContainsAnyStrings = 0, /* e.g. name contains any of 'conference' 'meeting' 'presentation' */ - ContainsAllStrings = 1, /* same as above except that it contains ALL of the strings */ - EqualsString = 2 /* exactly equal*/ -}; - -/* Comparison operators ( >, <, >=, <=, == and InRange ) */ -enum RelOperator{ - Equals = 0, - GreaterEquals = 1, - Greater = 2, - SmallerEquals = 3, - Smaller = 4, - InRange = 5 /* lower limit <= value <= upper limit*/ -}; - -/******************************************************************************************** - * Helper class for further serialisation - ********************************************************************************************/ - -class StringExpression ; -class Expression ; - -class LinearizedExpression -{ -public: - std::vector _tokens ; - std::vector _ints ; - std::vector _strings ; - - typedef enum { EXPR_DATE = 0, - EXPR_POP = 1, - EXPR_SIZE = 2, - EXPR_HASH = 3, - EXPR_NAME = 4, - EXPR_PATH = 5, - EXPR_EXT = 6, - EXPR_COMP = 7, - EXPR_SIZE_MB = 8 } token ; - - static Expression *toExpr(const LinearizedExpression& e) ; - - std::string GetStrings(); - -private: - static Expression *toExpr(const LinearizedExpression& e,int&,int&,int&) ; - static void readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list& strings,bool& b,StringOperator& op) ; -}; - - -/****************************************************************************************** -Boolean Search Expression -classes: - - Expression: The base class of all expression typest - CompoundExpression: The expression which uses a logical operator to combine - the results of two expressions - StringExpression: An expression which uses some sort of string comparison. - RelExpression: A Relational Expression where > < >= <= == make sense. - e.g. size date etc - -******************************************************************************************/ - -/*! - * \brief The ExpFileEntry class - * This is the base class the regular expressions can operate on. Derive it to fit your own needs! - */ -class ExpFileEntry -{ -public: - virtual const std::string& file_name() const =0; - virtual uint64_t file_size() const =0; - virtual rstime_t file_modtime() const =0; - virtual uint32_t file_popularity() const =0; - virtual std::string file_parent_path() const =0; - virtual const RsFileHash& file_hash() const =0; -}; - -class Expression -{ -public: - virtual bool eval (const ExpFileEntry& file) = 0; - virtual ~Expression() {}; - - virtual void linearize(LinearizedExpression& e) const = 0 ; - virtual std::string toStdString() const = 0 ; -}; - -class CompoundExpression : public Expression -{ -public: - CompoundExpression( enum LogicalOperator op, Expression * exp1, Expression *exp2) - : Lexp(exp1), Rexp(exp2), Op(op){ } - - bool eval (const ExpFileEntry& file) { - if (Lexp == NULL or Rexp == NULL) { - return false; - } - switch (Op){ - case AndOp: - return Lexp->eval(file) && Rexp->eval(file); - case OrOp: - return Lexp->eval(file) || Rexp->eval(file); - case XorOp: - return Lexp->eval(file) ^ Rexp->eval(file); - default: - return false; - } - } - virtual ~CompoundExpression(){ - delete Lexp; - delete Rexp; - } - - virtual std::string toStdString() const - { - switch(Op) - { - case AndOp: return "(" + Lexp->toStdString() + ") AND (" + Rexp->toStdString() +")" ; - case OrOp: return "(" + Lexp->toStdString() + ") OR (" + Rexp->toStdString() +")" ; - case XorOp: return "(" + Lexp->toStdString() + ") XOR (" + Rexp->toStdString() +")" ; - default: - return "" ; - } - } - - virtual void linearize(LinearizedExpression& e) const ; -private: - Expression *Lexp; - Expression *Rexp; - enum LogicalOperator Op; - -}; - -class StringExpression: public Expression -{ -public: - StringExpression(enum StringOperator op, const std::list &t, bool ic): Op(op),terms(t), IgnoreCase(ic){} - - virtual void linearize(LinearizedExpression& e) const ; - virtual std::string toStdStringWithParam(const std::string& varstr) const; -protected: - bool evalStr(const std::string &str); - - enum StringOperator Op; - std::list terms; - bool IgnoreCase; -}; - -template -class RelExpression: public Expression -{ -public: - RelExpression(enum RelOperator op, T lv, T hv): Op(op), LowerValue(lv), HigherValue(hv) {} - - virtual void linearize(LinearizedExpression& e) const ; - virtual std::string toStdStringWithParam(const std::string& typestr) const; -protected: - bool evalRel(T val); - - enum RelOperator Op; - T LowerValue; - T HigherValue; -}; - -template<> void RelExpression::linearize(LinearizedExpression& e) const ; - -template -bool RelExpression::evalRel(T val) { - switch (Op) { - case Equals: - return LowerValue == val; - case GreaterEquals: - return LowerValue >= val; - case Greater: - return LowerValue > val; - case SmallerEquals: - return LowerValue <= val; - case Smaller: - return LowerValue < val; - case InRange: - return (LowerValue <= val) && (val <= HigherValue); - default: - return false; - } -} - -template -std::string RelExpression::toStdStringWithParam(const std::string& typestr) const -{ - std::string LowerValueStr = RsUtil::NumberToString(LowerValue) ; - - switch (Op) { - case Equals: return typestr + " = " + LowerValueStr ; - case GreaterEquals: return typestr + " <= "+ LowerValueStr ; - case Greater: return typestr + " < " + LowerValueStr ; - case SmallerEquals: return typestr + " >= "+ LowerValueStr ; - case Smaller: return typestr + " > " + LowerValueStr ; - case InRange: return LowerValueStr + " <= " + typestr + " <= " + RsUtil::NumberToString(HigherValue) ; - default: - return ""; - } -} - -/****************************************************************************************** -Binary Predicate for Case Insensitive search - -******************************************************************************************/ -/*Binary predicate for case insensitive character comparison.*/ -/*TODOS: - *Factor locales in the comparison - */ -struct CompareCharIC : - public std::binary_function< char , char , bool> { - - bool operator () ( char ch1 , char ch2 ) const { - return tolower( static_cast < unsigned char > (ch1) ) - == tolower( static_cast < unsigned char > (ch2) ); - } - -}; - -/****************************************************************************************** -Some implementations of StringExpressions. - -******************************************************************************************/ - -class NameExpression: public StringExpression -{ -public: - NameExpression(enum StringOperator op, const std::list &t, bool ic): - StringExpression(op,t,ic) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return StringExpression::toStdStringWithParam("NAME"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_NAME) ; - StringExpression::linearize(e) ; - } -}; - -class PathExpression: public StringExpression { -public: - PathExpression(enum StringOperator op, const std::list &t, bool ic): - StringExpression(op,t,ic) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString()const { return StringExpression::toStdStringWithParam("PATH"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_PATH) ; - StringExpression::linearize(e) ; - } -}; - -class ExtExpression: public StringExpression { -public: - ExtExpression(enum StringOperator op, const std::list &t, bool ic): - StringExpression(op,t,ic) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString()const { return StringExpression::toStdStringWithParam("EXTENSION"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_EXT) ; - StringExpression::linearize(e) ; - } -}; - -class HashExpression: public StringExpression { -public: - HashExpression(enum StringOperator op, const std::list &t): - StringExpression(op,t, true) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return StringExpression::toStdStringWithParam("HASH"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_HASH) ; - StringExpression::linearize(e) ; - } -}; - -/****************************************************************************************** -Some implementations of Relational Expressions. - -******************************************************************************************/ - -class DateExpression: public RelExpression -{ -public: - DateExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - DateExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return RelExpression::toStdStringWithParam("DATE"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_DATE) ; - RelExpression::linearize(e) ; - } -}; - -class SizeExpression: public RelExpression -{ -public: - SizeExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - SizeExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return RelExpression::toStdStringWithParam("SIZE"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ; - RelExpression::linearize(e) ; - } -}; - -class SizeExpressionMB: public RelExpression -{ -public: - SizeExpressionMB(enum RelOperator op, int v): RelExpression(op,v,v){} - SizeExpressionMB(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return RelExpression::toStdStringWithParam("SIZE"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_SIZE_MB) ; - RelExpression::linearize(e) ; - } -}; -class PopExpression: public RelExpression -{ -public: - PopExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - PopExpression(enum RelOperator op, int lv, int hv): RelExpression(op,lv,hv) {} - PopExpression(const LinearizedExpression& e) ; - bool eval(const ExpFileEntry& file); - - virtual std::string toStdString() const { return RelExpression::toStdStringWithParam("POPULARITY"); } - - virtual void linearize(LinearizedExpression& e) const - { - e._tokens.push_back(LinearizedExpression::EXPR_POP) ; - RelExpression::linearize(e) ; - } -}; -} - - diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h deleted file mode 100644 index f25d90957..000000000 --- a/libretroshare/src/retroshare/rsfiles.h +++ /dev/null @@ -1,996 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsfiles.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2008 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "rstypes.h" -#include "serialiser/rsserializable.h" -#include "rsturtle.h" -#include "util/rstime.h" -#include "retroshare/rsevents.h" -#include "util/rsmemory.h" -#include "util/rsdebug.h" - -class RsFiles; - -/** - * Pointer to global instance of RsFiles service implementation - * @jsonapi{development} - */ -extern RsFiles* rsFiles; - -enum class RsFilesErrorNum : int32_t -{ - FILES_HANDLE_NOT_FOUND = 2004, -}; - -struct RsFilesErrorCategory: std::error_category -{ - const char* name() const noexcept override - { return "RetroShare Files"; } - - std::string message(int ev) const override - { - switch (static_cast(ev)) - { - case RsFilesErrorNum::FILES_HANDLE_NOT_FOUND: - return "Files handle not found"; - default: - return rsErrorNotInCategory(ev, name()); - } - } - - std::error_condition default_error_condition(int ev) const noexcept override; - - const static RsFilesErrorCategory instance; -}; - - -namespace std -{ -/** Register RsFilesErrorNum as an error condition enum, must be in std - * namespace */ -template<> struct is_error_condition_enum : true_type {}; -} - -/** Provide RsJsonApiErrorNum conversion to std::error_condition, must be in - * same namespace of RsJsonApiErrorNum */ -inline std::error_condition make_error_condition(RsFilesErrorNum e) noexcept -{ - return std::error_condition( - static_cast(e), RsFilesErrorCategory::instance ); -}; - - -namespace RsRegularExpression { class Expression; } - -/* These are used mainly by ftController at the moment */ -const uint32_t RS_FILE_CTRL_PAUSE = 0x00000100; -const uint32_t RS_FILE_CTRL_START = 0x00000200; -const uint32_t RS_FILE_CTRL_FORCE_CHECK = 0x00000400; - -const uint32_t RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT = 0x00000001 ; -const uint32_t RS_FILE_CTRL_ENCRYPTION_POLICY_PERMISSIVE = 0x00000002 ; - -const uint32_t RS_FILE_PERM_DIRECT_DL_YES = 0x00000001 ; -const uint32_t RS_FILE_PERM_DIRECT_DL_NO = 0x00000002 ; -const uint32_t RS_FILE_PERM_DIRECT_DL_PER_USER = 0x00000003 ; - -const uint32_t RS_FILE_RATE_TRICKLE = 0x00000001; -const uint32_t RS_FILE_RATE_SLOW = 0x00000002; -const uint32_t RS_FILE_RATE_STANDARD = 0x00000003; -const uint32_t RS_FILE_RATE_FAST = 0x00000004; -const uint32_t RS_FILE_RATE_STREAM_AUDIO = 0x00000005; -const uint32_t RS_FILE_RATE_STREAM_VIDEO = 0x00000006; - -const uint32_t RS_FILE_PEER_ONLINE = 0x00001000; -const uint32_t RS_FILE_PEER_OFFLINE = 0x00002000; - -const uint32_t RS_FILE_SHARE_FLAGS_IGNORE_PREFIXES = 0x0001 ; -const uint32_t RS_FILE_SHARE_FLAGS_IGNORE_SUFFIXES = 0x0002 ; -const uint32_t RS_FILE_SHARE_FLAGS_IGNORE_DUPLICATES = 0x0004 ; - -const uint32_t RS_FILE_SHARE_PARAMETER_DEFAULT_MAXIMUM_DEPTH = 8; - -/************************************ - * Used To indicate where to search. - * - * The Order of these is very important, - * it specifies the search order too. - * - */ - -// Flags used when requesting info about transfers, mostly to filter out the result. -// -const FileSearchFlags RS_FILE_HINTS_CACHE_deprecated ( 0x00000001 ); -const FileSearchFlags RS_FILE_HINTS_EXTRA ( 0x00000002 ); -const FileSearchFlags RS_FILE_HINTS_LOCAL ( 0x00000004 ); -const FileSearchFlags RS_FILE_HINTS_REMOTE ( 0x00000008 ); -const FileSearchFlags RS_FILE_HINTS_DOWNLOAD ( 0x00000010 ); -const FileSearchFlags RS_FILE_HINTS_UPLOAD ( 0x00000020 ); -const FileSearchFlags RS_FILE_HINTS_SPEC_ONLY ( 0x01000000 ); - -const FileSearchFlags RS_FILE_HINTS_NETWORK_WIDE ( 0x00000080 );// can be downloaded anonymously -const FileSearchFlags RS_FILE_HINTS_BROWSABLE ( 0x00000100 );// browsable by friends -const FileSearchFlags RS_FILE_HINTS_SEARCHABLE ( 0x00000200 );// can be searched anonymously -const FileSearchFlags RS_FILE_HINTS_PERMISSION_MASK ( 0x00000380 );// OR of the last tree flags. Used to filter out. - -/** Flags used when requesting a new file transfer */ -enum class FileRequestFlags: uint32_t -{ - /// Enable requesting file via turtle routing. - ANONYMOUS_ROUTING = 0x00000040, - - /// Asks (TODO: or enforce?) for end-to-end encryption of file trasfer - ENCRYPTED = 0x00000080, - - /// Asks (TODO: or enforce?) no end-to-end encryption of file trasfer - UNENCRYPTED = 0x00000100, - - /// Start trasfer very slow - SLOW = 0x00002000, - - /// Disable searching for potential direct sources - NO_DIRECT_SEARCH = 0x02000000 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(FileRequestFlags) - -/// @deprecated Flags used when requesting a transfer -/// @see FileRequestFlags instead -const TransferRequestFlags RS_FILE_REQ_ANONYMOUS_ROUTING ( 0x00000040 ); // Use to ask turtle router to download the file. -const TransferRequestFlags RS_FILE_REQ_ENCRYPTED ( 0x00000080 ); // Asks for end-to-end encryption of file at the level of ftServer -const TransferRequestFlags RS_FILE_REQ_UNENCRYPTED ( 0x00000100 ); // Asks for no end-to-end encryption of file at the level of ftServer -const TransferRequestFlags RS_FILE_REQ_ASSUME_AVAILABILITY ( 0x00000200 ); // Assume full source availability. Used for cache files. -const TransferRequestFlags RS_FILE_REQ_CACHE_deprecated ( 0x00000400 ); // Old stuff used for cache files. Not used anymore. -const TransferRequestFlags RS_FILE_REQ_EXTRA ( 0x00000800 ); -const TransferRequestFlags RS_FILE_REQ_MEDIA ( 0x00001000 ); -const TransferRequestFlags RS_FILE_REQ_BACKGROUND ( 0x00002000 ); // To download slowly. -const TransferRequestFlags RS_FILE_REQ_NO_SEARCH ( 0x02000000 ); // disable searching for potential direct sources. - -// const uint32_t RS_FILE_HINTS_SHARE_FLAGS_MASK = RS_FILE_HINTS_NETWORK_WIDE_OTHERS | RS_FILE_HINTS_BROWSABLE_OTHERS -// | RS_FILE_HINTS_NETWORK_WIDE_GROUPS | RS_FILE_HINTS_BROWSABLE_GROUPS ; - -enum class RsSharedDirectoriesEventCode: uint8_t { - UNKNOWN = 0x00, - STARTING_DIRECTORY_SWEEP = 0x01, // (void) - HASHING_FILE = 0x02, // mMessage: full path and hashing speed of the file being hashed - DIRECTORY_SWEEP_ENDED = 0x03, // (void) - SAVING_FILE_INDEX = 0x04, // (void) - EXTRA_LIST_FILE_ADDED = 0x05, // (void) - EXTRA_LIST_FILE_REMOVED = 0x06, // (void) -}; - -enum class RsFileTransferEventCode: uint8_t { - UNKNOWN = 0x00, - DOWNLOAD_COMPLETE = 0x01, // mHash: hash of the complete file - COMPLETED_FILES_REMOVED = 0x02, // -}; - -struct RsSharedDirectoriesEvent: RsEvent -{ - RsSharedDirectoriesEvent() : RsEvent(RsEventType::SHARED_DIRECTORIES), mEventCode(RsSharedDirectoriesEventCode::UNKNOWN) {} - ~RsSharedDirectoriesEvent() override = default; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mEventCode); - RS_SERIAL_PROCESS(mMessage); - } - - RsSharedDirectoriesEventCode mEventCode; - std::string mMessage; -}; - -struct RsFileTransferEvent: RsEvent -{ - RsFileTransferEvent() : RsEvent(RsEventType::FILE_TRANSFER), mFileTransferEventCode(RsFileTransferEventCode::UNKNOWN) {} - ~RsFileTransferEvent() override = default; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mFileTransferEventCode); - RS_SERIAL_PROCESS(mHash); - } - - RsFileTransferEventCode mFileTransferEventCode; - RsFileHash mHash; -}; -struct SharedDirInfo : RsSerializable -{ - static bool sameLists(const std::list& l1,const std::list& l2) - { - std::list::const_iterator it1(l1.begin()) ; - std::list::const_iterator it2(l2.begin()) ; - - for(; (it1!=l1.end() && it2!=l2.end());++it1,++it2) - if(*it1 != *it2) - return false ; - - return it1 == l1.end() && it2 == l2.end() ; - } - - std::string filename; - std::string virtualname; - - /// combnation of DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_BROWSABLE | ... - FileStorageFlags shareflags; - std::list parent_groups; - - /// @see RsSerializable::serial_process - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(filename); - RS_SERIAL_PROCESS(virtualname); - RS_SERIAL_PROCESS(shareflags); - RS_SERIAL_PROCESS(parent_groups); - } -}; - -struct SharedDirStats -{ - uint32_t total_number_of_files ; - uint64_t total_shared_size ; -}; - -/** This class represents a tree of directories and files, only with their names - * size and hash. It is used to create collection links in the GUI and to - * transmit directory information between services. This class is independent - * from the existing FileHierarchy classes used in storage because we need a - * very copact serialization and storage size since we create links with it. - * Besides, we cannot afford to risk the leak of other local information - * by using the orignal classes. - */ -struct RsFileTree : RsSerializable -{ -public: - RsFileTree() : mTotalFiles(0), mTotalSize(0) {} - - /** - * @brief Create a RsFileTree from directory details - * @param dd directory or file details - * @param remote - * @param remove_top_dirs - * @return pointer to the created file-tree - */ - static std::unique_ptr fromDirDetails( - const DirDetails& dd, bool remote, bool remove_top_dirs = true ); - - /** - * @brief Create a RsFileTree from Base64 representation - * @param base64 base64 or base64url string representation of the file-tree - * @return pointer to the parsed file-tree on success, nullptr plus error - * details on failure - */ - static std::tuple, std::error_condition> - fromBase64(const std::string& base64); - - /** @brief Convert to base64 representetion */ - std::string toBase64() const; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mFiles); - RS_SERIAL_PROCESS(mDirs); - RS_SERIAL_PROCESS(mTotalFiles); - RS_SERIAL_PROCESS(mTotalSize); - } - - struct FileData: RsSerializable - { - std::string name; - uint64_t size; - RsFileHash hash; - - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - }; - - /// Allow browsing the hierarchy - bool getDirectoryContent( - std::string& name, std::vector& subdirs, - std::vector& subfiles, uint64_t handle = 0 ) const; - - struct DirData: RsSerializable - { - std::string name; - std::vector subdirs; - std::vector subfiles; - - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - }; - - static void recurs_buildFileTree( - RsFileTree& ft, uint32_t index, const DirDetails& dd, bool remote, - bool remove_top_dirs ); - - std::vector mFiles; - std::vector mDirs; - - uint32_t mTotalFiles; - uint64_t mTotalSize; - - virtual ~RsFileTree(); - - /** - * @brief Create a RsFileTree from Radix64 representation - * @deprecated kept for retrocompatibility with RetroShare-gui - * The format is not compatible with the new methods - * @param radix64_string - * @return nullptr if on failure, pointer to the created FileTree on success - */ - RS_DEPRECATED_FOR(fromBase64) - static std::unique_ptr fromRadix64( - const std::string& radix64_string ); - - /** @brief Convert to radix64 representetion - * @deprecated kept for retrocompatibility with RetroShare-gui - * The format is not compatible with the new methods - */ - RS_DEPRECATED_FOR(toBase64) - std::string toRadix64() const; - -private: - /** @deprecated kept for retrocompatibility with RetroShare-gui */ - RS_DEPRECATED_FOR(serial_process) - bool serialise(unsigned char *& data,uint32_t& data_size) const; - - /** @deprecated kept for retrocompatibility with RetroShare-gui */ - RS_DEPRECATED_FOR(serial_process) - bool deserialise(unsigned char* data, uint32_t data_size); -}; - -struct BannedFileEntry : RsSerializable -{ - BannedFileEntry() : mFilename(""), mSize(0), mBanTimeStamp(0) {} - - std::string mFilename; - uint64_t mSize; - rstime_t mBanTimeStamp; - - /// @see RsSerializable::serial_process - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(mFilename); - RS_SERIAL_PROCESS(mSize); - RS_SERIAL_PROCESS(mBanTimeStamp); - } -}; - -struct DeepFilesSearchResult; - -struct TurtleFileInfoV2 : RsSerializable -{ - TurtleFileInfoV2() : fSize(0), fWeight(0) {} - - explicit TurtleFileInfoV2(const TurtleFileInfo& oldInfo) : - fSize(oldInfo.size), fHash(oldInfo.hash), fName(oldInfo.name), - fWeight(0) {} - -#ifdef RS_DEEP_FILES_INDEX - explicit TurtleFileInfoV2(const DeepFilesSearchResult& dRes); -#endif // def RS_DEEP_FILES_INDEX - - uint64_t fSize; /// File size - RsFileHash fHash; /// File hash - std::string fName; /// File name - - /** @brief Xapian weight of the file which matched the search criteria - * This field is optional (its value is 0 when not specified). - * Given that Xapian weight for the same file is usually different on - * different nodes, it should not be used as an absolute refence, but just - * as an hint of how much the given file match the search criteria. - */ - float fWeight; - - /** @brief Xapian snippet of the file which matched the search criteria - * This field is optional (its value is an empty string when not specified). - */ - std::string fSnippet; - - - /// @see RsSerializable::serial_process - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(fSize); - RS_SERIAL_PROCESS(fHash); - RS_SERIAL_PROCESS(fName); - RS_SERIAL_PROCESS(fWeight); - RS_SERIAL_PROCESS(fSnippet); - } - - ~TurtleFileInfoV2() override; -}; - -class RsFiles -{ -public: - /** - * @brief Provides file data for the GUI, media streaming or API clients. - * It may return unverified chunks. This allows streaming without having to - * wait for hashes or completion of the file. - * This function returns an unspecified amount of bytes. Either as much data - * as available or a sensible maximum. Expect a block size of around 1MiB. - * To get more data, call this function repeatedly with different offsets. - * - * @jsonapi{development,manualwrapper} - * note the wrapper for this is written manually not autogenerated - * @see JsonApiServer. - * - * @param[in] hash hash of the file. The file has to be available on this node - * or it has to be in downloading state. - * @param[in] offset where the desired block starts - * @param[inout] requested_size size of pre-allocated data. Will be updated - * by the function. - * @param[out] data pre-allocated memory chunk of size 'requested_size' by the - * client - * @return Returns false in case - * - the files is not available on the local node - * - not downloading - * - the requested data was not downloaded yet - * - end of file was reached - */ - virtual bool getFileData( const RsFileHash& hash, uint64_t offset, - uint32_t& requested_size, uint8_t* data ) = 0; - - /** - * @brief Check if we already have a file - * @jsonapi{development} - * @param[in] hash file identifier - * @param[out] info storage for the possibly found file information - * @return true if the file is already present, false otherwise - */ - virtual bool alreadyHaveFile(const RsFileHash& hash, FileInfo &info) = 0; - - /** - * @brief Initiate downloading of a file - * @jsonapi{development} - * @param[in] fileName file name - * @param[in] hash file hash - * @param[in] size file size - * @param[in] destPath optional specify the destination directory - * @param[in] flags you usually want RS_FILE_REQ_ANONYMOUS_ROUTING - * @param[in] srcIds eventually specify known sources - * @return false if we already have the file, true otherwhise - */ - virtual bool FileRequest( - const std::string& fileName, const RsFileHash& hash, uint64_t size, - const std::string& destPath, TransferRequestFlags flags, - const std::list& srcIds ) = 0; - - /** - * @brief Initiate download of a files collection - * @jsonapi{development} - * An usually useful companion method of this is @see parseFilesLink() - * @param[in] collection collection of files to download - * @param[in] destPath optional base path on which to download the - * collection, if left empty the default download directory will be used - * @param[in] srcIds optional peers id known as direct source of the - * collection - * @param[in] flags optional flags to fine tune search and download - * algorithm - * @return success or error details. - */ - virtual std::error_condition requestFiles( - const RsFileTree& collection, - const std::string& destPath = "", - const std::vector& srcIds = std::vector(), - FileRequestFlags flags = FileRequestFlags::ANONYMOUS_ROUTING ) = 0; - - /** - * @brief Cancel file downloading - * @jsonapi{development} - * @param[in] hash - * @return false if the file is not in the download queue, true otherwhise - */ - virtual bool FileCancel(const RsFileHash& hash) = 0; - - /** - * @brief Set destination directory for given file - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] newPath - * @return false if some error occurred, true otherwise - */ - virtual bool setDestinationDirectory( - const RsFileHash& hash, const std::string& newPath ) = 0; - - /** - * @brief Set name for dowloaded file - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] newName - * @return false if some error occurred, true otherwise - */ - virtual bool setDestinationName( - const RsFileHash& hash, const std::string& newName ) = 0; - - /** - * @brief Set chunk strategy for file, useful to set streaming mode to be - * able of see video or other media preview while it is still downloading - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] newStrategy - * @return false if some error occurred, true otherwise - */ - virtual bool setChunkStrategy( - const RsFileHash& hash, - FileChunksInfo::ChunkStrategy newStrategy ) = 0; - - /** - * @brief Set default chunk strategy - * @jsonapi{development} - * @param[in] strategy - */ - virtual void setDefaultChunkStrategy( - FileChunksInfo::ChunkStrategy strategy ) = 0; - - /** - * @brief Get default chunk strategy - * @jsonapi{development} - * @return current default chunck strategy - */ - virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() = 0; - - /** - * @brief Get free disk space limit - * @jsonapi{development} - * @return current minimum free space on disk in MB - */ - virtual uint32_t freeDiskSpaceLimit() const = 0; - - /** - * @brief Set minimum free disk space limit - * @jsonapi{development} - * @param[in] minimumFreeMB minimum free space in MB - */ - virtual void setFreeDiskSpaceLimit(uint32_t minimumFreeMB) = 0; - - /** - * @brief Controls file transfer - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] flags action to perform. Pict into { RS_FILE_CTRL_PAUSE, RS_FILE_CTRL_START, RS_FILE_CTRL_FORCE_CHECK } } - * @return false if error occured such as unknown hash. - */ - virtual bool FileControl(const RsFileHash& hash, uint32_t flags) = 0; - - /** - * @brief Clear completed downloaded files list - * @jsonapi{development} - * @return false on error, true otherwise - */ - virtual bool FileClearCompleted() = 0; - - virtual void setDefaultEncryptionPolicy(uint32_t policy)=0; // RS_FILE_CTRL_ENCRYPTION_POLICY_STRICT/PERMISSIVE - virtual uint32_t defaultEncryptionPolicy()=0; - virtual void setMaxUploadSlotsPerFriend(uint32_t n)=0; - virtual uint32_t getMaxUploadSlotsPerFriend()=0; - virtual void setFilePermDirectDL(uint32_t perm)=0; - virtual uint32_t filePermDirectDL()=0; - - /** - * @brief Request remote files search - * @jsonapi{development} - * @param[in] matchString string to look for in the search. If files deep - * indexing is enabled at compile time support advanced features described - * at https://xapian.org/docs/queryparser.html - * @param multiCallback function that will be called each time a search - * result is received - * @param[in] maxWait maximum wait time in seconds for search results - * @return false on error, true otherwise - */ - virtual bool turtleSearchRequest( - const std::string& matchString, - const std::function& results)>& multiCallback, - rstime_t maxWait = 300 ) = 0; - - virtual TurtleRequestId turtleSearch(const std::string& string_to_match) = 0; - virtual TurtleRequestId turtleSearch( - const RsRegularExpression::LinearizedExpression& expr) = 0; - - /*** - * Control of Downloads Priority. - ***/ - virtual uint32_t getQueueSize() = 0 ; - virtual void setQueueSize(uint32_t s) = 0 ; - virtual bool changeQueuePosition(const RsFileHash& hash, QueueMove mv) = 0; - virtual bool changeDownloadSpeed(const RsFileHash& hash, int speed) = 0; - virtual bool getDownloadSpeed(const RsFileHash& hash, int & speed) = 0; - virtual bool clearDownload(const RsFileHash& hash) = 0; - - /** - * @brief Get incoming files list - * @jsonapi{development} - * @param[out] hashs storage for files identifiers list - */ - virtual void FileDownloads(std::list& hashs) = 0; - - /** - * @brief Get outgoing files list - * @jsonapi{development} - * @param[out] hashs storage for files identifiers list - * @return false if some error occurred, true otherwise - */ - virtual bool FileUploads(std::list& hashs) = 0; - - /** - * @brief Get file details - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] hintflags filtering hint ( RS_FILE_HINTS_UPLOAD|...| - * RS_FILE_HINTS_EXTRA|RS_FILE_HINTS_LOCAL ) - * @param[out] info storage for file information - * @return true if file found, false otherwise - */ - virtual bool FileDetails( - const RsFileHash& hash, FileSearchFlags hintflags, FileInfo& info ) = 0; - - virtual bool isEncryptedSource(const RsPeerId& virtual_peer_id) =0; - - /** - * @brief Get chunk details about the downloaded file with given hash. - * @jsonapi{development} - * @param[in] hash file identifier - * @param[out] info storage for file information - * @return true if file found, false otherwise - */ - virtual bool FileDownloadChunksDetails( - const RsFileHash& hash, FileChunksInfo& info) = 0; - - /** - * @brief Get details about the upload with given hash - * @jsonapi{development} - * @param[in] hash file identifier - * @param[in] peerId peer identifier - * @param[out] map storage for chunk info - * @return true if file found, false otherwise - */ - virtual bool FileUploadChunksDetails( - const RsFileHash& hash, const RsPeerId& peerId, - CompressedChunkMap& map ) = 0; - - /** - * @brief Remove file from extra fila shared list - * @jsonapi{development} - * @param[in] hash hash of the file to remove - * @return return false on error, true otherwise - */ - virtual bool ExtraFileRemove(const RsFileHash& hash) = 0; - - /** - * @brief Add file to extra shared file list - * @jsonapi{development} - * @param[in] localpath path of the file - * @param[in] period how much time the file will be kept in extra list in - * seconds - * @param[in] flags sharing policy flags ex: RS_FILE_REQ_ANONYMOUS_ROUTING - * @return false on error, true otherwise - */ - virtual bool ExtraFileHash( - std::string localpath, rstime_t period, TransferRequestFlags flags - ) = 0; - - /** - * @brief Get extra file information - * @jsonapi{development} - * @param[in] localpath path of the file - * @param[out] info storage for the file information - * @return false on error, true otherwise - */ - virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0; - - virtual bool ExtraFileMove( - std::string fname, const RsFileHash& hash, uint64_t size, - std::string destpath ) = 0; - - /** - * @brief Request directory details, subsequent multiple call may be used to - * explore a whole directory tree. - * @jsonapi{development} - * @param[out] details Storage for directory details - * @param[in] handle element handle 0 for root, pass the content of - * DirDetails::child[x].ref after first call to explore deeper, be aware - * that is not a real pointer but an index used internally by RetroShare. - * @param[in] flags file search flags RS_FILE_HINTS_* - * @return false if error occurred, true otherwise - */ - virtual bool requestDirDetails( - DirDetails &details, uint64_t handle = 0, - FileSearchFlags flags = RS_FILE_HINTS_LOCAL ) = 0; - - /*** - * Directory Listing / Search Interface - */ - /** - * Kept for retrocompatibility, it was originally written for easier - * interaction with Qt. As soon as you can, you should prefer to use the - * version of this method which take `uint64_t handle` as paramether. - */ - RS_DEPRECATED_FOR(requestDirDetails) - virtual int RequestDirDetails( - void* handle, DirDetails& details, FileSearchFlags flags ) = 0; - - virtual bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) =0; - virtual uint32_t getType(void *ref,FileSearchFlags flags) = 0; - - virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags) = 0; - virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) = 0; - virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags) = 0; - virtual int SearchBoolExp(RsRegularExpression::Expression * exp, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) = 0; - virtual int getSharedDirStatistics(const RsPeerId& pid, SharedDirStats& stats) =0; - - /** - * @brief Ban unwanted file from being, searched and forwarded by this node - * @jsonapi{development} - * @param[in] realFileHash this is what will really enforce banning - * @param[in] filename expected name of the file, for the user to read - * @param[in] fileSize expected file size, for the user to read - * @return meaningless value - */ - virtual int banFile( const RsFileHash& realFileHash, - const std::string& filename, uint64_t fileSize ) = 0; - - /** - * @brief Remove file from unwanted list - * @jsonapi{development} - * @param[in] realFileHash hash of the file - * @return meaningless value - */ - virtual int unbanFile(const RsFileHash& realFileHash) = 0; - - /** - * @brief Get list of banned files - * @jsonapi{development} - * @param[out] bannedFiles storage for banned files information - * @return meaningless value - */ - virtual bool getPrimaryBannedFilesList( - std::map& bannedFiles ) = 0; - - /** - * @brief Check if a file is on banned list - * @jsonapi{development} - * @param[in] hash hash of the file - * @return true if the hash is on the list, false otherwise - */ - virtual bool isHashBanned(const RsFileHash& hash) = 0; - - /*** - * Utility Functions. - ***/ - virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0; - - /** - * @brief Force shared directories check - * @param[in] add_safe_delay Schedule the check 20 seconds from now, to ensure to capture files written just now. - * @jsonapi{development} - */ - virtual void ForceDirectoryCheck(bool add_safe_delay=false) = 0; - - virtual void updateSinceGroupPermissionsChanged() = 0; - virtual bool InDirectoryCheck() = 0; - virtual bool copyFile(const std::string& source,const std::string& dest) = 0; - - /*** - * Directory Control - ***/ - virtual void requestDirUpdate(void *ref) =0 ; // triggers the update of the given reference. Used when browsing. - - /** - * @brief Set default complete downloads directory - * @jsonapi{development} - * @param[in] path directory path - * @return false if something failed, true otherwhise - */ - virtual bool setDownloadDirectory(const std::string& path) = 0; - - /** - * @brief Set partial downloads directory - * @jsonapi{development} - * @param[in] path directory path - * @return false if something failed, true otherwhise - */ - virtual bool setPartialsDirectory(const std::string& path) = 0; - - /** - * @brief Get default complete downloads directory - * @jsonapi{development} - * @return default completed downloads directory path - */ - virtual std::string getDownloadDirectory() = 0; - - /** - * @brief Get partial downloads directory - * @jsonapi{development} - * @return partials downloads directory path - */ - virtual std::string getPartialsDirectory() = 0; - - /** - * @brief Get list of current shared directories - * @jsonapi{development} - * @param[out] dirs storage for the list of share directories - * @return false if something failed, true otherwhise - */ - virtual bool getSharedDirectories(std::list& dirs) = 0; - - /** - * @brief Set shared directories - * @jsonapi{development} - * @param[in] dirs list of shared directories with share options - * @return false if something failed, true otherwhise - */ - virtual bool setSharedDirectories(const std::list& dirs) = 0; - - /** - * @brief Add shared directory - * @jsonapi{development} - * @param[in] dir directory to share with sharing options - * @return false if something failed, true otherwhise - */ - virtual bool addSharedDirectory(const SharedDirInfo& dir) = 0; - - /** - * @brief Updates shared directory sharing flags. - * The directory should be already shared! - * @jsonapi{development} - * @param[in] dir Shared directory with updated sharing options - * @return false if something failed, true otherwhise - */ - virtual bool updateShareFlags(const SharedDirInfo& dir) = 0; - - /** - * @brief Remove directory from shared list - * @jsonapi{development} - * @param[in] dir Path of the directory to remove from shared list - * @return false if something failed, true otherwhise - */ - virtual bool removeSharedDirectory(std::string dir) = 0; - - /// Default base URL used for files links @see exportFilesLink - static const std::string DEFAULT_FILES_BASE_URL; - - /** Link query field used to store collection files count - * @see exportFilesLink */ - static const std::string FILES_URL_COUNT_FIELD; - - /// Link query field used to store collection data @see exportFilesLink - static const std::string FILES_URL_DATA_FIELD; - - /** Link query FILES_URL_DATA_FIELD field value used to instruct the parser - * to look for the data into the link fragment - * @see exportFilesLink and parseFilesLink */ - static const std::string FILES_URL_FAGMENT_FORWARD; - - /// Link query field used to store collection name @see exportFilesLink - static const std::string FILES_URL_NAME_FIELD; - - /// Link query field used to store collection size @see exportFilesLink - static const std::string FILES_URL_SIZE_FIELD; - - /** - * @brief Export link to a collection of files - * @jsonapi{development} - * @param[out] link storage for the generated link - * @param[in] handle directory RetroShare handle - * @param[in] fragSneak when true the file data is sneaked into fragment - * instead of FILES_URL_DATA_FIELD query field, this way if using an - * http[s] link to pass around a disguised file link a misconfigured host - * attempting to visit that link with a web browser will not send the file - * data to the server thus protecting at least some of the privacy of the - * user even in a misconfiguration scenario. - * @param[in] baseUrl URL into which to sneak in the RetroShare file link - * base64, this is primarly useful to induce applications into making the - * link clickable, or to disguise the RetroShare link into a "normal" - * looking web link. If empty the collection data link will be outputted in - * plain base64 format. - * @return error information if some error occurred, 0/SUCCESS otherwise - */ - virtual std::error_condition exportCollectionLink( - std::string& link, uint64_t handle, bool fragSneak = false, - const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL ) = 0; - - /** - * @brief Export link to a file - * @jsonapi{development} - * @param[out] link @see exportCollectionLink - * @param[in] fileHash hash of the file - * @param[in] fileSize size of the file - * @param[in] fileName name of the file - * @param[in] fragSneak @see exportCollectionLink - * @param[in] baseUrl @see exportCollectionLink - * @return error @see exportCollectionLink - */ - virtual std::error_condition exportFileLink( - std::string& link, const RsFileHash& fileHash, uint64_t fileSize, - const std::string& fileName, bool fragSneak = false, - const std::string& baseUrl = RsFiles::DEFAULT_FILES_BASE_URL ) = 0; - - /** - * @brief Parse RetroShare files link - * @jsonapi{development} - * Support also old RetroShare-gui file and collections links format. - * @param[in] link files link either in base64 or URL format - * @param[out] collection storage for parsed files link - * @return error information if some error occurred, 0/SUCCESS otherwise - */ - virtual std::error_condition parseFilesLink( - const std::string& link, RsFileTree& collection ) = 0; - - /** - * @brief Get list of ignored file name prefixes and suffixes - * @param[out] ignoredPrefixes storage for ingored prefixes - * @param[out] ignoredSuffixes storage for ingored suffixes - * @param flags RS_FILE_SHARE_FLAGS_IGNORE_* - * @return false if something failed, true otherwhise - */ - virtual bool getIgnoreLists( - std::list& ignoredPrefixes, - std::list& ignoredSuffixes, - uint32_t& flags ) = 0; - - virtual void setIgnoreLists(const std::list& ignored_prefixes, const std::list& ignored_suffixes,uint32_t flags) =0; - - virtual void setWatchPeriod(int minutes) =0; - virtual void setWatchEnabled(bool b) =0; - virtual int watchPeriod() const =0; - virtual bool watchEnabled() =0; - virtual bool followSymLinks() const=0; - virtual void setFollowSymLinks(bool b)=0 ; - virtual void togglePauseHashingProcess() =0; // pauses/resumes the hashing process. - virtual bool hashingProcessPaused() =0; - - virtual bool getShareDownloadDirectory() = 0; - virtual bool shareDownloadDirectory(bool share) = 0; - - virtual void setMaxShareDepth(int depth) =0; - virtual int maxShareDepth() const=0; - - virtual bool ignoreDuplicates() = 0; - virtual void setIgnoreDuplicates(bool ignore) = 0; - - virtual ~RsFiles() = default; -}; diff --git a/libretroshare/src/retroshare/rsflags.h b/libretroshare/src/retroshare/rsflags.h deleted file mode 100644 index 8775f1dfb..000000000 --- a/libretroshare/src/retroshare/rsflags.h +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsflags.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2019 by Retroshare Team * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -/** Check if given type is a scoped enum */ -template -using rs_is_scoped_enum = std::integral_constant< bool, - std::is_enum::value && !std::is_convertible::value >; - -/** - * @brief Register enum class as flags type - * To use this macro define a scoped enum with your flag values, then register - * it as flags type passing it as parameter of this macro. - * The result will be type safe flags, that cannot be mixed up with flag of a - * different type, but that are very comfortable to operate like plain old - * integers. All commom operation like &, | or ! can be used. To convert - * the result of such operation to boolean use !!: -@code{.cpp} -RsConnectModes connect = rsConfig->getConnectModes(); -if (!!(connect & RsConnectModes::OUTGOING_TCP)) -@endcode - * - * This macro support flag fields of different lenght depending on what - * underlining type (usually from uint8_t up to uint64_t) has been declared for - * the enum class. - * If you plan to serialize those flags it is important to specify the - * underlining type of the enum otherwise different compilers may serialize a - * flag variable with different lenght, potentially causing interoperability - * issues between differents builds. - * - * Usage example: -@code{.cpp} -enum class RsGrouterItemFlags : uint32_t -{ - NONE = 0x0, - ENCRYPTED = 0x1, - SERVICE_UNKNOWN = 0x2 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RsGrouterItemFlags) -@endcode - */ -#define RS_REGISTER_ENUM_FLAGS_TYPE(eft) \ -template<> struct Rs__BitFlagsOps \ -{ \ - static_assert( std::is_enum::value, \ - "Are you trying to register a non-enum type as flags?" ); \ - static_assert( rs_is_scoped_enum::value, \ - "Are you trying to register an unscoped enum as flags?" ); \ - static constexpr bool enabled = true; \ -}; - -// By defaults types are not valid flags, so bit flags operators are disabled -template struct Rs__BitFlagsOps -{ static constexpr bool enabled = false; }; - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator &(EFT lhs, EFT rhs) -{ - using u_t = typename std::underlying_type::type; - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator &=(EFT& lhs, EFT rhs) { lhs = lhs & rhs; return lhs; } - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator |(EFT lhs, EFT rhs) -{ - using u_t = typename std::underlying_type::type; - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator |=(EFT& lhs, EFT rhs) { lhs = lhs | rhs; return lhs; } - - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator ^(EFT lhs, EFT rhs) -{ - using u_t = typename std::underlying_type::type; - return static_cast(static_cast(lhs) ^ static_cast(rhs)); -} - -template -typename std::enable_if::enabled, EFT>::type -/*EFT*/ operator ^=(EFT& lhs, EFT rhs) { lhs = lhs ^ rhs; return lhs; } - -template -typename std::enable_if::enabled, EFT>::type -operator ~(EFT val) -{ - using u_t = typename std::underlying_type::type; - return static_cast(~static_cast(val)); -} - -template -typename std::enable_if::enabled, bool>::type -operator !(EFT val) -{ - using u_t = typename std::underlying_type::type; - return static_cast(val) == 0; -} - -/// Nicely print flags bits as 1 and 0 -template -typename std::enable_if::enabled, std::ostream>::type& -operator <<(std::ostream& stream, EFT flags) -{ - using u_t = typename std::underlying_type::type; - return stream << std::bitset(static_cast(flags)); -} - -#include -#include "util/rsdeprecate.h" - - -/** - * @deprecated t_RsFlags32 has been deprecated because the newer - * @see RS_REGISTER_ENUM_FLAGS_TYPE provide more convenient flags facilities. - * -// This class provides a representation for flags that can be combined with bitwise -// operations. However, because the class is templated with an id, it's not possible to -// mixup flags belonging to different classes. This avoids many bugs due to confusion of flags types -// that occur when all flags are uint32_t values. -// -// To use this class, define an ID that is different than other flags classes, and do a typedef: -// -// #define TRANSFER_INFO_FLAGS_TAG 0x8133ea -// typedef t_RsFlags32 TransferInfoFlags ; -// -// Implementation details: -// - we cannot have at the same time a implicit contructor from uint32_t and a bool operator, otherwise c++ -// mixes up operators and transforms flags into booleans before combining them further. -// -// So I decided to have: -// - an explicit constructor from uint32_t -// - an implicit bool operator, that allows test like if(flags & FLAGS_VALUE) -// -*/ -template class RS_DEPRECATED_FOR(RS_REGISTER_ENUM_FLAGS_TYPE) t_RsFlags32 -{ - public: - inline t_RsFlags32() : _bits(0) {} - inline explicit t_RsFlags32(uint32_t N) : _bits(N) {} // allows initialization from a set of uint32_t - - - inline t_RsFlags32 operator| (const t_RsFlags32& f) const { return t_RsFlags32(_bits | f._bits) ; } - inline t_RsFlags32 operator^ (const t_RsFlags32& f) const { return t_RsFlags32(_bits ^ f._bits) ; } - inline t_RsFlags32 operator* (const t_RsFlags32& f) const { return t_RsFlags32(_bits & f._bits) ; } - - inline bool operator!=(const t_RsFlags32& f) const { return _bits != f._bits ; } - inline bool operator==(const t_RsFlags32& f) const { return _bits == f._bits ; } - inline bool operator& (const t_RsFlags32& f) const { return (_bits & f._bits)>0 ; } - - inline t_RsFlags32 operator|=(const t_RsFlags32& f) { _bits |= f._bits ; return *this ;} - inline t_RsFlags32 operator^=(const t_RsFlags32& f) { _bits ^= f._bits ; return *this ;} - inline t_RsFlags32 operator&=(const t_RsFlags32& f) { _bits &= f._bits ; return *this ;} - - inline t_RsFlags32 operator~() const { return t_RsFlags32(~_bits) ; } - - //inline explicit operator bool() const { return _bits>0; } - inline uint32_t toUInt32() const { return _bits ; } - - /// Easier porting to new flag system - template inline - typename std::enable_if<(Rs__BitFlagsOps::enabled && - sizeof(EFT) >= sizeof(uint32_t) ), EFT>::type - toEFT() { return static_cast(_bits); } - - /// Easier porting to new flag system - template - static inline typename std::enable_if< - Rs__BitFlagsOps::enabled && - sizeof(EFT) <= sizeof(uint32_t), t_RsFlags32>::type - fromEFT(EFT e) { return t_RsFlags32(static_cast(e)); } - - void clear() { _bits = 0 ; } - - friend std::ostream& operator<<(std::ostream& o,const t_RsFlags32& f) // friendly print with 0 and I - { - for(int i=31;i>=0;--i) { - std::string res = f._bits&(1< TransferRequestFlags; - -// Flags for file storage. Mainly permissions like BROWSABLE/NETWORK_WIDE for groups and peers. -// -typedef t_RsFlags32 FileStorageFlags ; - -// Flags for searching in files that could be local, downloads, remote, etc. -// -typedef t_RsFlags32 FileSearchFlags ; - -// Service permissions. Will allow each user to use or not use each service. -// -typedef t_RsFlags32 ServicePermissionFlags ; - -// Flags for chat lobbies -// -typedef t_RsFlags32 ChatLobbyFlags ; - diff --git a/libretroshare/src/retroshare/rsgossipdiscovery.h b/libretroshare/src/retroshare/rsgossipdiscovery.h deleted file mode 100644 index 9a6e2a792..000000000 --- a/libretroshare/src/retroshare/rsgossipdiscovery.h +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * RetroShare remote peers gossip discovery * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rsevents.h" -#include "util/rsmemory.h" - -class RsGossipDiscovery; - -/** - * Pointer to global instance of RsGossipDiscovery service implementation - * @jsonapi{development} - * - * TODO: this should become std::weak_ptr once we have a reasonable services - * management. - */ -extern std::shared_ptr rsGossipDiscovery; - -/** - * @brief Emitted when a pending PGP certificate is received - */ - -enum class RsGossipDiscoveryEventType: uint32_t { - UNKNOWN = 0x00, - FRIEND_PEER_INFO_RECEIVED = 0x01, -}; - -struct RsGossipDiscoveryEvent : RsEvent -{ - RsGossipDiscoveryEvent(): RsEvent(RsEventType::GOSSIP_DISCOVERY) {} - virtual ~RsGossipDiscoveryEvent() override {} - - RsGossipDiscoveryEventType mGossipDiscoveryEventType; - RsPeerId mFromId; - RsPeerId mAboutId; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RsEvent::serial_process(j,ctx); - RS_SERIAL_PROCESS(mGossipDiscoveryEventType); - RS_SERIAL_PROCESS(mFromId); - RS_SERIAL_PROCESS(mAboutId); - } -}; - -class RsGossipDiscovery -{ -public: - virtual ~RsGossipDiscovery() = default; - - /** - * @brief getDiscFriends get a list of all friends of a given friend - * @jsonapi{development} - * @param[in] id peer to get the friends of - * @param[out] friends list of friends (ssl id) - * @return true on success false otherwise - */ - virtual bool getDiscFriends( const RsPeerId& id, - std::list& friends ) = 0; - - /** - * @brief getDiscPgpFriends get a list of all friends of a given friend - * @jsonapi{development} - * @param[in] pgpid peer to get the friends of - * @param[out] gpg_friends list of friends (gpg id) - * @return true on success false otherwise - */ - virtual bool getDiscPgpFriends( - const RsPgpId& pgpid, std::list& gpg_friends ) = 0; - - /** - * @brief getPeerVersion get the version string of a peer. - * @jsonapi{development} - * @param[in] id peer to get the version string of - * @param[out] version version string sent by the peer - * @return true on success false otherwise - */ - virtual bool getPeerVersion(const RsPeerId& id, std::string& version) = 0; - - /** - * @brief getWaitingDiscCount get the number of queued discovery packets. - * @jsonapi{development} - * @param[out] sendCount number of queued outgoing packets - * @param[out] recvCount number of queued incoming packets - * @return true on success false otherwise - */ - virtual bool getWaitingDiscCount(size_t& sendCount, size_t& recvCount) = 0; -}; diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h deleted file mode 100644 index 84349f75e..000000000 --- a/libretroshare/src/retroshare/rsgrouter.h +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgrouter.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "util/rsdir.h" -#include "util/rsdeprecate.h" -#include "retroshare/rsids.h" -#include "retroshare/rsgxsifacetypes.h" -#include "rsitems/rsserviceids.h" - -typedef RsGxsId GRouterKeyId ; // we use SSLIds, so that it's easier in the GUI to mix up peer ids with grouter ids. -typedef uint32_t GRouterServiceId ; -typedef uint64_t GRouterMsgPropagationId ; - -class GRouterClientService ; -class RsGRouterGenericDataItem ; - -class RsGRouter -{ -public: - // This is the interface file for the global router service. - // - struct GRouterRoutingCacheInfo - { - GRouterMsgPropagationId mid ; - std::set local_origin; - GRouterKeyId destination ; - rstime_t routing_time; - rstime_t last_tunnel_attempt_time; - rstime_t last_sent_time; - bool receipt_available ; - uint32_t duplication_factor ; - uint32_t data_status ; - uint32_t tunnel_status ; - uint32_t data_size ; - Sha1CheckSum item_hash ; - }; - - struct GRouterPublishedKeyInfo - { - std::string description_string ; - RsGxsId authentication_key ; - uint32_t service_id ; - }; - - struct GRouterRoutingMatrixInfo - { - // Probabilities of reaching a given key for each friend. - // This concerns all known keys. - // - std::map > per_friend_probabilities ; - - // List of friend ids in the same order. Should roughly correspond to the friends that are currently online. - // - std::vector friend_ids ; - - // List of own published keys, with associated service ID - // - std::map published_keys ; - }; - - //===================================================// - // Debugging info // - //===================================================// - - virtual bool getRoutingCacheInfo(std::vector& infos) =0; - virtual bool getRoutingMatrixInfo(GRouterRoutingMatrixInfo& info) =0; - - // retrieve the routing probabilities - - //===================================================// - // Communication to other services. // - //===================================================// - - virtual bool sendData(const RsGxsId& destination, const GRouterServiceId& client_id, const uint8_t *data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId& id) =0; - virtual bool cancel(GRouterMsgPropagationId mid) =0; - - virtual bool registerKey(const RsGxsId& authentication_id, const GRouterServiceId& client_id,const std::string& description_string)=0 ; - - //===================================================// - // Routage feedback from other services // - //===================================================// - - virtual void addRoutingClue(const GRouterKeyId& destination, const RsPeerId& source) =0; -}; - -// To access the GRouter from anywhere -// -extern RsGRouter *rsGRouter ; diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h deleted file mode 100644 index 421417bdc..000000000 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ /dev/null @@ -1,741 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxschannels.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsgxscommon.h" -#include "serialiser/rsserializable.h" -#include "retroshare/rsturtle.h" -#include "util/rsdeprecate.h" -#include "retroshare/rsgxscircles.h" -#include "util/rsmemory.h" - -class RsGxsChannels; - -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsGxsChannels* rsGxsChannels; - - -struct RsGxsChannelGroup : RsSerializable, RsGxsGenericGroupData -{ - RsGxsChannelGroup() : mAutoDownload(false) {} - - std::string mDescription; - RsGxsImage mImage; - - bool mAutoDownload; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mDescription); - RS_SERIAL_PROCESS(mImage); - RS_SERIAL_PROCESS(mAutoDownload); - } - - ~RsGxsChannelGroup() override; -}; - -struct RsGxsChannelPost : RsSerializable, RsGxsGenericMsgData -{ - RsGxsChannelPost() : mAttachmentCount(0), mCommentCount(0), mUnreadCommentCount(0), mSize(0) {} - - std::set mOlderVersions; - std::string mMsg; // UTF8 encoded. - - std::list mFiles; - uint32_t mAttachmentCount; // auto calced. - uint32_t mCommentCount; // auto calced. - uint32_t mUnreadCommentCount; // auto calced. - uint64_t mSize; // auto calced. - - RsGxsImage mThumbnail; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mOlderVersions); - - RS_SERIAL_PROCESS(mMsg); - RS_SERIAL_PROCESS(mFiles); - RS_SERIAL_PROCESS(mAttachmentCount); - RS_SERIAL_PROCESS(mCommentCount); - RS_SERIAL_PROCESS(mUnreadCommentCount); - RS_SERIAL_PROCESS(mSize); - RS_SERIAL_PROCESS(mThumbnail); - } - - ~RsGxsChannelPost() override; -}; - - -enum class RsChannelEventCode: uint8_t -{ - UNKNOWN = 0x00, - NEW_CHANNEL = 0x01, // emitted when new channel is received - UPDATED_CHANNEL = 0x02, // emitted when existing channel is updated - NEW_MESSAGE = 0x03, // new message reeived in a particular channel (group and msg id) - UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular channel - RECEIVED_PUBLISH_KEY = 0x05, // publish key for this channel has been received - SUBSCRIBE_STATUS_CHANGED = 0x06, // subscription for channel mChannelGroupId changed. - READ_STATUS_CHANGED = 0x07, // existing message has been read or set to unread - RECEIVED_DISTANT_SEARCH_RESULT = 0x08, // result for the given group id available for the given turtle request id - STATISTICS_CHANGED = 0x09, // stats (nb of supplier friends, how many msgs they have etc) has changed - SYNC_PARAMETERS_UPDATED = 0x0a, // sync and storage times have changed - NEW_COMMENT = 0x0b, // new comment arrived/published. mChannelThreadId gives the ID of the commented message - NEW_VOTE = 0x0c, // new vote arrived/published. mChannelThreadId gives the ID of the votes message comment - DELETED_CHANNEL = 0x0d, // channel was deleted by auto-cleaning system -}; - -struct RsGxsChannelEvent: RsEvent -{ - RsGxsChannelEvent(): RsEvent(RsEventType::GXS_CHANNELS), mChannelEventCode(RsChannelEventCode::UNKNOWN) {} - - RsChannelEventCode mChannelEventCode; - RsGxsGroupId mChannelGroupId; - RsGxsMessageId mChannelMsgId; - RsGxsMessageId mChannelThreadId; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mChannelEventCode); - RS_SERIAL_PROCESS(mChannelGroupId); - RS_SERIAL_PROCESS(mChannelMsgId); - } -}; - -// This event is used to factor multiple search results notifications in a single event. - -struct RsGxsChannelSearchResultEvent: RsEvent -{ - RsGxsChannelSearchResultEvent(): - RsEvent(RsEventType::GXS_CHANNELS), - mChannelEventCode(RsChannelEventCode::RECEIVED_DISTANT_SEARCH_RESULT) {} - - RsChannelEventCode mChannelEventCode; - std::map > mSearchResultsMap; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - - RS_SERIAL_PROCESS(mChannelEventCode); - RS_SERIAL_PROCESS(mSearchResultsMap); - } -}; - -class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService -{ -public: - explicit RsGxsChannels(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - - /** - * @brief Create channel. Blocking API. - * @jsonapi{development} - * @param[in] name Name of the channel - * @param[in] description Description of the channel - * @param[in] thumbnail Optional image to show as channel thumbnail. - * @param[in] authorId Optional id of the author. Leave empty for an - * anonymous channel. - * @param[in] circleType Optional visibility rule, default public. - * @param[in] circleId If the channel is not public specify the id of - * the circle who can see the channel. Depending on - * the value you pass for - * circleType this should be be an external circle - * if EXTERNAL is passed, a local friend group id - * if NODES_GROUP is passed, empty otherwise. - * @param[out] channelId Optional storage for the id of the created - * channel, meaningful only if creations succeeds. - * @param[out] errorMessage Optional storage for error messsage, meaningful - * only if creation fail. - * @return False on error, true otherwise. - */ - virtual bool createChannelV2( - const std::string& name, - const std::string& description, - const RsGxsImage& thumbnail = RsGxsImage(), - const RsGxsId& authorId = RsGxsId(), - RsGxsCircleType circleType = RsGxsCircleType::PUBLIC, - const RsGxsCircleId& circleId = RsGxsCircleId(), - RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) = 0; - - /** - * @brief Add a comment on a post or on another comment. Blocking API. - * @jsonapi{development} - * @param[in] channelId Id of the channel in which the comment is to be - * posted - * @param[in] threadId Id of the post (that is a thread) in the channel - * where the comment is placed - * @param[in] comment UTF-8 string containing the comment itself - * @param[in] authorId Id of the author of the comment - * @param[in] parentId Id of the parent of the comment that is either a - * channel post Id or the Id of another comment. - * @param[in] origCommentId If this is supposed to replace an already - * existent comment, the id of the old post. - * If left blank a new post will be created. - * @param[out] commentMessageId Optional storage for the id of the comment - * that was created, meaningful only on success. - * @param[out] errorMessage Optional storage for error message, meaningful - * only on failure. - * @return false on error, true otherwise - */ - virtual bool createCommentV2( - const RsGxsGroupId& channelId, - const RsGxsMessageId& threadId, - const std::string& comment, - const RsGxsId& authorId, - const RsGxsMessageId& parentId = RsGxsMessageId(), - const RsGxsMessageId& origCommentId = RsGxsMessageId(), - RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) = 0; - - /** - * @brief Create channel post. Blocking API. - * @jsonapi{development} - * @param[in] channelId Id of the channel where to put the post. Beware - * you need publish rights on that channel to post. - * @param[in] title Title of the post - * @param[in] mBody Text content of the post - * @param[in] files Optional list of attached files. These are - * supposed to be already shared, - * @see ExtraFileHash() below otherwise. - * @param[in] thumbnail Optional thumbnail image for the post. - * @param[in] origPostId If this is supposed to replace an already - * existent post, the id of the old post. If left - * blank a new post will be created. - * @param[out] postId Optional storage for the id of the created post, - * meaningful only on success. - * @param[out] errorMessage Optional storage for the error message, - * meaningful only on failure. - * @return false on error, true otherwise - */ - virtual bool createPostV2( - const RsGxsGroupId& channelId, const std::string& title, - const std::string& mBody, - const std::list& files = std::list(), - const RsGxsImage& thumbnail = RsGxsImage(), - const RsGxsMessageId& origPostId = RsGxsMessageId(), - RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Create a vote - * @jsonapi{development} - * @param[in] channelId Id of the channel where to vote - * @param[in] postId Id of the channel post of which a comment is - * voted. - * @param[in] commentId Id of the comment that is voted - * @param[in] authorId Id of the author. Needs to be of an owned - * identity. - * @param[in] vote Vote value, either RsGxsVoteType::DOWN or - * RsGxsVoteType::UP - * @param[out] voteId Optional storage for the id of the created vote, - * meaningful only on success. - * @param[out] errorMessage Optional storage for error message, meaningful - * only on failure. - * @return false on error, true otherwise - */ - virtual bool createVoteV2( - const RsGxsGroupId& channelId, const RsGxsMessageId& postId, - const RsGxsMessageId& commentId, const RsGxsId& authorId, - RsGxsVoteType vote, - RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Edit channel details. - * @jsonapi{development} - * @param[in] channel Channel data (name, description...) with modifications - * @return false on error, true otherwise - */ - virtual bool editChannel(RsGxsChannelGroup& channel) = 0; - - /** - * @brief Share extra file - * Can be used to share extra file attached to a channel post - * @jsonapi{development} - * @param[in] path file path - * @return false on error, true otherwise - */ - virtual bool ExtraFileHash(const std::string& path) = 0; - - /** - * @brief Remove extra file from shared files - * @jsonapi{development} - * @param[in] hash hash of the file to remove - * @return false on error, true otherwise - */ - virtual bool ExtraFileRemove(const RsFileHash& hash) = 0; - - /** - * @brief Get channels summaries list. Blocking API. - * @jsonapi{development} - * @param[out] channels list where to store the channels - * @return false if something failed, true otherwhise - */ - virtual bool getChannelsSummaries(std::list& channels) = 0; - - /** - * @brief Get channels information (description, thumbnail...). - * Blocking API. - * @jsonapi{development} - * @param[in] chanIds ids of the channels of which to get the informations - * @param[out] channelsInfo storage for the channels informations - * @return false if something failed, true otherwhise - */ - virtual bool getChannelsInfo( - const std::list& chanIds, - std::vector& channelsInfo ) = 0; - - /** - * @brief Get all channel messages, comments and votes in a given channel - * @note It's the client's responsibility to figure out which message (resp. comment) - * a comment (resp. vote) refers to. - * - * @jsonapi{development} - * @param[in] channelId id of the channel of which the content is requested - * @param[out] posts storage for posts - * @param[out] comments storage for the comments - * @param[out] votes storage for votes - * @return false if something failed, true otherwhise - */ - virtual bool getChannelAllContent( const RsGxsGroupId& channelId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) = 0; - - /** - * @brief Get channel messages, comments and votes corresponding to the given IDs. - * @note Since comments are internally themselves messages, this function actually - * returns the data for messages, comments or votes that have the given ID. - * It *does not* automatically retrieve the comments or votes for a given message - * which Id you supplied. - * - * @jsonapi{development} - * @param[in] channelId id of the channel of which the content is requested - * @param[in] contentsIds ids of requested contents - * @param[out] posts storage for posts - * @param[out] comments storage for the comments - * @param[out] votes storage for the votes - * @return false if something failed, true otherwhise - */ - virtual bool getChannelContent( const RsGxsGroupId& channelId, - const std::set& contentsIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) = 0; - - /** - * @brief Get channel comments corresponding to the given message IDs. - * If the set is empty, nothing is returned. - * - * @jsonapi{development} - * @param[in] channelId id of the channel of which the content is requested - * @param[in] contentIds ids of requested contents - * @param[out] comments storage for the comments - * @return false if something failed, true otherwhise - */ - virtual bool getChannelComments(const RsGxsGroupId &channelId, - const std::set &contentIds, - std::vector &comments) = 0; - - /** - * @brief Get channel content summaries - * @jsonapi{development} - * @param[in] channelId id of the channel of which the content is requested - * @param[out] summaries storage for summaries - * @return false if something failed, true otherwhise - */ - virtual bool getContentSummaries( const RsGxsGroupId& channelId, - std::vector& summaries ) = 0; - - /** - * @brief Toggle post read status. Blocking API. - * @jsonapi{development} - * @param[in] postId post identifier - * @param[in] read true to mark as read, false to mark as unread - * @return false on error, true otherwise - */ - virtual bool markRead(const RsGxsGrpMsgIdPair& postId, bool read) = 0; - - /** - * @brief Share channel publishing key - * This can be used to authorize other peers to post on the channel - * @jsonapi{development} - * @param[in] channelId id of the channel - * @param[in] peers peers to share the key with - * @return false on error, true otherwise - */ - virtual bool shareChannelKeys( - const RsGxsGroupId& channelId, const std::set& peers ) = 0; - - /** - * @brief Subscrbe to a channel. Blocking API - * @jsonapi{development} - * @param[in] channelId Channel id - * @param[in] subscribe true to subscribe, false to unsubscribe - * @return false on error, true otherwise - */ - virtual bool subscribeToChannel( const RsGxsGroupId& channelId, - bool subscribe ) = 0; - - /** - * \brief Retrieve statistics about the channel service - * @jsonapi{development} - * \param[out] stat Statistics structure - * \return - */ - virtual bool getChannelServiceStatistics(GxsServiceStatistic& stat) =0; - - /** - * \brief Retrieve statistics about the given channel - * @jsonapi{development} - * \param[in] channelId Id of the channel group - * \param[out] stat Statistics structure - * \return - */ - virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0; - - /// default base URL used for channels links @see exportChannelLink - static const std::string DEFAULT_CHANNEL_BASE_URL; - - /// Link query field used to store channel name @see exportChannelLink - static const std::string CHANNEL_URL_NAME_FIELD; - - /// Link query field used to store channel id @see exportChannelLink - static const std::string CHANNEL_URL_ID_FIELD; - - /// Link query field used to store channel data @see exportChannelLink - static const std::string CHANNEL_URL_DATA_FIELD; - - /** Link query field used to store channel message title - * @see exportChannelLink */ - static const std::string CHANNEL_URL_MSG_TITLE_FIELD; - - /// Link query field used to store channel message id @see exportChannelLink - static const std::string CHANNEL_URL_MSG_ID_FIELD; - - /** - * @brief Get link to a channel - * @jsonapi{development} - * @param[out] link storage for the generated link - * @param[in] chanId Id of the channel of which we want to generate a link - * @param[in] includeGxsData if true include the channel GXS group data so - * the receiver can subscribe to the channel even if she hasn't received it - * through GXS yet - * @param[in] baseUrl URL into which to sneak in the RetroShare link - * radix, this is primarly useful to induce applications into making the - * link clickable, or to disguise the RetroShare link into a - * "normal" looking web link. If empty the GXS data link will be outputted - * in plain base64 format. - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if something failed, true otherwhise - */ - virtual bool exportChannelLink( - std::string& link, const RsGxsGroupId& chanId, - bool includeGxsData = true, - const std::string& baseUrl = RsGxsChannels::DEFAULT_CHANNEL_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Import channel from full link - * @jsonapi{development} - * @param[in] link channel link either in radix or link format - * @param[out] chanId optional storage for parsed channel id - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if some error occurred, true otherwise - */ - virtual bool importChannelLink( - const std::string& link, - RsGxsGroupId& chanId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Search the turtle reachable network for matching channels - * @jsonapi{development} - * An @see RsGxsChannelSearchResultEvent is emitted when matching channels - * arrives from the network - * @param[in] matchString string to search into the channels - * @return search id - */ - virtual TurtleRequestId turtleSearchRequest(const std::string& matchString)=0; - - /** - * @brief Retrieve available search results - * @jsonapi{development} - * @param[in] searchId search id - * @param[out] results storage for search results - * @return false on error, true otherwise - */ - virtual bool retrieveDistantSearchResults( - TurtleRequestId searchId, - std::map& results ) = 0; - - /** - * @brief Request distant channel details - * @jsonapi{development} - * An @see RsGxsChannelSearchResultEvent is emitted once details are - * retrieved from the network - * @param[in] groupId if of the group to request to the network - * @return search id - */ - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& groupId) = 0; - - /** - * @brief Retrieve previously requested distant group - * @jsonapi{development} - * @param[in] groupId if of teh group - * @param[out] distantGroup storage for group data - * @return false on error, true otherwise - */ - virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; - - /** - * @brief getDistantSearchStatus - * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, - * data request ongoing and data available - */ - virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) =0; - - /** - * @brief Clear accumulated search results - * @jsonapi{development} - * @param[in] reqId search id - * @return false on error, true otherwise - */ - virtual bool clearDistantSearchResults(TurtleRequestId reqId) = 0; - - ~RsGxsChannels() override; - - //////////////////////////////////////////////////////////////////////////// - /* Following functions are deprecated and should not be considered a safe to - * use API */ - - /** - * @brief Get auto-download option value for given channel - * @jsonapi{development} - * @deprecated This feature rely on very buggy code, the returned value is - * not reliable @see setChannelAutoDownload(). - * @param[in] channelId channel id - * @param[out] enabled storage for the auto-download option value - * @return false if something failed, true otherwhise - */ - RS_DEPRECATED - virtual bool getChannelAutoDownload( - const RsGxsGroupId& channelId, bool& enabled ) = 0; - - /** - * @brief Enable or disable auto-download for given channel. Blocking API - * @jsonapi{development} - * @deprecated This feature rely on very buggy code, when enabled the - * channel service start flooding erratically log with error messages, - * apparently without more dangerous consequences. Still those messages - * hints that something out of control is happening under the hood, use at - * your own risk. A safe alternative to this method can easly implemented - * at API client level instead. - * @param[in] channelId channel id - * @param[in] enable true to enable, false to disable - * @return false if something failed, true otherwhise - */ - RS_DEPRECATED - virtual bool setChannelAutoDownload( - const RsGxsGroupId& channelId, bool enable ) = 0; - - /** - * @brief Get download directory for the given channel - * @jsonapi{development} - * @deprecated @see setChannelAutoDownload() - * @param[in] channelId id of the channel - * @param[out] directory reference to string where to store the path - * @return false on error, true otherwise - */ - RS_DEPRECATED - virtual bool getChannelDownloadDirectory( const RsGxsGroupId& channelId, - std::string& directory ) = 0; - - /** - * @brief Set download directory for the given channel. Blocking API. - * @jsonapi{development} - * @deprecated @see setChannelAutoDownload() - * @param[in] channelId id of the channel - * @param[in] directory path - * @return false on error, true otherwise - */ - RS_DEPRECATED - virtual bool setChannelDownloadDirectory( - const RsGxsGroupId& channelId, const std::string& directory) = 0; - - /** - * @brief Create channel. Blocking API. - * @jsonapi{development} - * @deprecated { substituted by createChannelV2 } - * @param[inout] channel Channel data (name, description...) - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createChannelV2) - virtual bool createChannel(RsGxsChannelGroup& channel) = 0; - - RS_DEPRECATED_FOR(getChannelsInfo) - virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; - - RS_DEPRECATED_FOR(getChannelContent) - virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts, std::vector &votes) = 0; - - RS_DEPRECATED_FOR(getChannelContent) - virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts) = 0; - - RS_DEPRECATED_FOR(getChannelContent) - virtual bool getPostData(const uint32_t &token, std::vector &posts) = 0; - - /** - * @brief toggle message read status - * @deprecated - * @param[out] token GXS token queue token - * @param[in] msgId - * @param[in] read - */ - RS_DEPRECATED_FOR(markRead) - virtual void setMessageReadStatus( - uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; - - /** - * @brief Share channel publishing key - * This can be used to authorize other peers to post on the channel - * @deprecated - * @param[in] groupId Channel id - * @param[in] peers peers to which share the key - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(shareChannelKeys) - virtual bool groupShareKeys( - const RsGxsGroupId& groupId, const std::set& peers ) = 0; - - /** - * @brief Request subscription to a group. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @deprecated - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] groupId Channel id - * @param[in] subscribe - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(subscribeToChannel) - virtual bool subscribeToGroup( uint32_t& token, const RsGxsGroupId &groupId, - bool subscribe ) = 0; - - /** - * @brief Request channel creation. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @deprecated - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] group Channel data (name, description...) - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createChannelV2) - virtual bool createGroup(uint32_t& token, RsGxsChannelGroup& group) = 0; - - /** - * @brief Add a comment on a post or on another comment - * @jsonapi{development} - * @deprecated - * @param[inout] comment - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createCommentV2) - virtual bool createComment(RsGxsComment& comment) = 0; - - /** - * @brief Create channel post. Blocking API. - * @jsonapi{development} - * @deprecated - * @param[inout] post - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createPostV2) - virtual bool createPost(RsGxsChannelPost& post) = 0; - - /** - * @brief Request post creation. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @deprecated - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] post - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createPostV2) - virtual bool createPost(uint32_t& token, RsGxsChannelPost& post) = 0; - - /** - * @brief createVote - * @jsonapi{development} - * @deprecated - * @param[inout] vote - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(createVoteV2) - virtual bool createVote(RsGxsVote& vote) = 0; - - /** - * @brief Request channel change. - * The action is performed asyncronously, so it could fail in a subsequent - * phase even after returning true. - * @deprecated - * @param[out] token Storage for RsTokenService token to track request - * status. - * @param[in] group Channel data (name, description...) with modifications - * @return false on error, true otherwise - */ - RS_DEPRECATED_FOR(editChannel) - virtual bool updateGroup(uint32_t& token, RsGxsChannelGroup& group) = 0; -}; diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h deleted file mode 100644 index 6ff854360..000000000 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ /dev/null @@ -1,504 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxscircles.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsidentity.h" -#include "serialiser/rsserializable.h" -#include "util/rsmemory.h" - - -class RsGxsCircles; - -/** - * Pointer to global instance of RsGxsCircles service implementation - * @jsonapi{development} - */ -extern RsGxsCircles* rsGxsCircles; - -enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat -{ - UNKNOWN = 0, /// Used to detect uninizialized values. - PUBLIC = 1, /// Public distribution, based on GxsIds - EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds - - NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them - /// Based on PGP nodes ids. - - LOCAL = 4, /// not distributed at all - - /** Self-restricted. Used only at creation time of self-restricted circles - * when the circle id isn't known yet. Once the circle id is known the type - * is set to EXTERNAL, and the external circle id is set to the id of the - * circle itself. Based on GxsIds. - */ - EXT_SELF = 5, - - YOUR_EYES_ONLY = 6 /// distributed to nodes signed by your own PGP key only. -}; - -// TODO: convert to enum class -static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin -static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group -static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE = 0x0004 ;// key is available, so we can encrypt for this circle -static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0007 ;// user is allowed. Combines all flags above. - - -struct RsGxsCircleGroup : RsSerializable -{ - RsGroupMetaData mMeta; - - std::set mLocalFriends; - std::set mInvitedMembers; - std::set mSubCircles; -#ifdef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED -# error "Add description, and multiple owners/administrators to circles" - // or better in general to GXS groups -#endif - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mLocalFriends); - RS_SERIAL_PROCESS(mInvitedMembers); - RS_SERIAL_PROCESS(mSubCircles); - } - - ~RsGxsCircleGroup() override; -}; - -enum class RsGxsCircleSubscriptionType:uint8_t { - UNKNOWN = 0x00, - SUBSCRIBE = 0x01, - UNSUBSCRIBE = 0x02 -}; - -struct RsGxsCircleMsg : RsSerializable -{ - RsMsgMetaData mMeta; - -#ifdef TO_REMOVE - // This item is actually totally unused, so we can change it no problem -#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED - /* This is horrible and should be changed into yet to be defined something - * reasonable in next non-retrocompatible version */ - std::string stuff; -#endif -#endif - RsGxsCircleSubscriptionType mSubscriptionType; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mSubscriptionType); - } - - ~RsGxsCircleMsg() override; -}; - -struct RsGxsCircleDetails : RsSerializable -{ - RsGxsCircleDetails() : mCircleType(RsGxsCircleType::EXTERNAL), mAmIAllowed(false),mAmIAdmin(false) {} - ~RsGxsCircleDetails() override; - - // helper functions. - bool isIdInCircle(const RsGxsId& id) const { return mAllowedGxsIds.find(id) != mAllowedGxsIds.end(); } - bool isIdInInviteeList(const RsGxsId& id) const - { - auto it = mSubscriptionFlags.find(id); - return (it != mSubscriptionFlags.end()) && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ); - } - bool isIdRequestingMembership(const RsGxsId& id) const - { - auto it = mSubscriptionFlags.find(id); - return it != mSubscriptionFlags.end() && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED ); - } - bool isGxsIdBased() const { return mCircleType==RsGxsCircleType::PUBLIC || mCircleType==RsGxsCircleType::EXTERNAL || mCircleType==RsGxsCircleType::EXT_SELF; } - - // Members - - RsGxsCircleId mCircleId; - std::string mCircleName; - - RsGxsCircleType mCircleType; - RsGxsCircleId mRestrictedCircleId; - - /** true when one of load GXS ids belong to the circle allowed list (admin - * list & subscribed list). */ - bool mAmIAllowed; - - /// true when we're an administrator of the circle group, meaning that we can add/remove members from the invitee list. - bool mAmIAdmin; - - /// This crosses admin list and subscribed list - std::set mAllowedGxsIds; - std::set mAllowedNodes; - - /// subscription flags for all ids - std::map mSubscriptionFlags; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(mCircleId); - RS_SERIAL_PROCESS(mCircleName); - RS_SERIAL_PROCESS(mCircleType); - RS_SERIAL_PROCESS(mRestrictedCircleId); - RS_SERIAL_PROCESS(mAmIAllowed); - RS_SERIAL_PROCESS(mAmIAdmin); - RS_SERIAL_PROCESS(mAllowedGxsIds); - RS_SERIAL_PROCESS(mAllowedNodes); - RS_SERIAL_PROCESS(mSubscriptionFlags); - } -}; - - -enum class RsGxsCircleEventCode: uint8_t -{ - // Notifications be only have 4 different possibilities: - // - // invitee list join/leave and - // membership request / leave request - // - // From there, depending on what the client displays, it is possible to interpret these - // as "some user joined the circle", or "membership pending for that Id", etc, depending - // on whether the current node owns the circle, or the admin is or is not yours. - // - // These should be decided in the UI based on what the circle cache is displaying. - // - UNKNOWN = 0x00, - - /** - * Sent when we receive a membership request msg for a particular circle. - * - * mCircleId contains the circle id and mGxsId is the id requesting membership */ - CIRCLE_MEMBERSHIP_REQUEST = 0x01, - - /** - * Sent when the ID has been added to the circle invitee list. - * - * mCircleId is the circle that invites me, and mGxsId is my own Id that is invited */ - CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST = 0x02, - - /** - * Sent when a GxsId annouces its will to not be in the circle. - * - * mCircleId contains the circle id and mGxsId is the id dropping membership */ - CIRCLE_MEMBERSHIP_LEAVE = 0x03, - - /** - * Sent when the Id has been removed from the invitee list. - * - * mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */ - CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST = 0x04, - - /** - * Means a new circle has been received. - * - * mCircleId contains the circle id */ - NEW_CIRCLE = 0x05, - - /** - * Means that the circle cache has updated, and membership status that is displayed should probably be updated to. - * - * no additional information. Simply means that the info previously from the cache has changed. */ - CACHE_DATA_UPDATED = 0x06, - - /** - * The circle has been deleted by auto-cleaning. - * */ - CIRCLE_DELETED = 0x07, - - /** - * Circle has been updated (name, parent circle, type, etc) - * */ - CIRCLE_UPDATED = 0x08, -}; - -struct RsGxsCircleEvent: RsEvent -{ - RsGxsCircleEvent() - : RsEvent(RsEventType::GXS_CIRCLES), - mCircleEventType(RsGxsCircleEventCode::UNKNOWN) {} - - - RsGxsCircleEventCode mCircleEventType; - RsGxsCircleId mCircleId; - RsGxsId mGxsId; - - ///* @see RsEvent @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mCircleEventType); - RS_SERIAL_PROCESS(mCircleId); - RS_SERIAL_PROCESS(mGxsId); - } - - ~RsGxsCircleEvent() override; -}; - -class RsGxsCircles: public RsGxsIfaceHelper -{ -public: - - RsGxsCircles(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - virtual ~RsGxsCircles(); - - /** - * @brief Create new circle - * @jsonapi{development} - * @param[in] circleName String containing cirlce name - * @param[in] circleType Circle type - * @param[out] circleId Optional storage to output created circle id - * @param[in] restrictedId Optional id of a pre-existent circle that see the - * created circle. Meaningful only if circleType == EXTERNAL, must be null - * in all other cases. - * @param[in] authorId Optional author of the circle. - * @param[in] gxsIdMembers GXS ids of the members of the circle. - * @param[in] localMembers PGP ids of the members if the circle. - * @return false if something failed, true otherwhise - */ - virtual bool createCircle( - const std::string& circleName, RsGxsCircleType circleType, - RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId), - const RsGxsCircleId& restrictedId = RsGxsCircleId(), - const RsGxsId& authorId = RsGxsId(), - const std::set& gxsIdMembers = std::set(), - const std::set& localMembers = std::set() ) = 0; - - /** - * @brief Edit own existing circle - * @jsonapi{development} - * @param[inout] cData Circle data with modifications, storage for data - * updatedad during the operation. - * @return false if something failed, true otherwhise - */ - virtual bool editCircle(RsGxsCircleGroup& cData) = 0; - - /** - * @brief Get circle details. Memory cached - * @jsonapi{development} - * @param[in] id Id of the circle - * @param[out] details Storage for the circle details - * @return false if something failed, true otherwhise - */ - virtual bool getCircleDetails(const RsGxsCircleId& id, RsGxsCircleDetails& details ) = 0; - - /** - * @brief Get list of known external circles ids. Memory cached - * @jsonapi{development} - * @param[in] circleIds Storage for circles id list - * @return false if something failed, true otherwhise - */ - virtual bool getCircleExternalIdList(std::set& circleIds ) = 0; - - /** - * @brief Get circles summaries list. - * @jsonapi{development} - * @param[out] circles list where to store the circles summaries - * @return false if something failed, true otherwhise - */ - virtual bool getCirclesSummaries(std::list& circles) = 0; - - /** - * @brief Get circles information - * @jsonapi{development} - * @param[in] circlesIds ids of the circles of which to get the informations - * @param[out] circlesInfo storage for the circles informations - * @return false if something failed, true otherwhise - */ - virtual bool getCirclesInfo( - const std::list& circlesIds, - std::vector& circlesInfo ) = 0; - - /** - * @brief Get circle requests - * @jsonapi{development} - * @param[in] circleId id of the circle of which the requests are requested - * @param[out] requests storage for the circle requests - * @return false if something failed, true otherwhise - */ - virtual bool getCircleRequests( const RsGxsGroupId& circleId, - std::vector& requests ) = 0; - /** - * @brief Get specific circle request - * @jsonapi{development} - * @param[in] circleId id of the circle of which the requests are requested - * @param[in] msgId id of the request - * @param[out] msg storage for the circle request - * @return false if something failed, true otherwhise - */ - virtual bool getCircleRequest(const RsGxsGroupId& circleId, - const RsGxsMessageId& msgId, - RsGxsCircleMsg& msg) =0; - - /** - * @brief Invite identities to circle (admin key is required) - * @jsonapi{development} - * @param[in] identities ids of the identities to invite - * @param[in] circleId Id of the circle you own and want to invite ids in - * @return false if something failed, true otherwhise - */ - virtual bool inviteIdsToCircle( const std::set& identities, - const RsGxsCircleId& circleId ) = 0; - - /** - * @brief Remove identities from circle (admin key is required) - * @jsonapi{development} - * @param[in] identities ids of the identities to remove from the invite list - * @param[in] circleId Id of the circle you own and want to invite ids in - * @return false if something failed, true otherwhise - */ - virtual bool revokeIdsFromCircle( const std::set& identities, - const RsGxsCircleId& circleId ) = 0; - - /** - * @brief Request circle membership, or accept circle invitation - * @jsonapi{development} - * @param[in] ownGxsId Id of own identity to introduce to the circle - * @param[in] circleId Id of the circle to which ask for inclusion - * @return false if something failed, true otherwhise - */ - virtual bool requestCircleMembership( - const RsGxsId& ownGxsId, const RsGxsCircleId& circleId ) = 0; - - /** - * @brief Leave given circle - * @jsonapi{development} - * @param[in] ownGxsId Own id to remove from the circle - * @param[in] circleId Id of the circle to leave - * @return false if something failed, true otherwhise - */ - virtual bool cancelCircleMembership( - const RsGxsId& ownGxsId, const RsGxsCircleId& circleId ) = 0; - - /// default base URL used for circle links @see exportCircleLink - static const std::string DEFAULT_CIRCLE_BASE_URL; - - /// Circle link query field used to store circle name @see exportCircleLink - static const std::string CIRCLE_URL_NAME_FIELD; - - /// Circle link query field used to store circle id @see exportCircleLink - static const std::string CIRCLE_URL_ID_FIELD; - - /// Circle link query field used to store circle data @see exportCircleLink - static const std::string CIRCLE_URL_DATA_FIELD; - - /** - * @brief Get link to a circle - * @jsonapi{development} - * @param[out] link storage for the generated link - * @param[in] circleId Id of the circle of which we want to generate a link - * @param[in] includeGxsData if true include the circle GXS group data so - * the receiver can request circle membership even if the circle hasn't - * propagated through GXS to her yet - * @param[in] baseUrl URL into which to sneak in the RetroShare circle link - * radix, this is primarly useful to induce applications into making the - * link clickable, or to disguise the RetroShare circle link into a - * "normal" looking web link. If empty the circle data link will be - * outputted in plain base64 format. - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if something failed, true otherwhise - */ - virtual bool exportCircleLink( - std::string& link, const RsGxsCircleId& circleId, - bool includeGxsData = true, - const std::string& baseUrl = RsGxsCircles::DEFAULT_CIRCLE_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Import circle from full link - * @param[in] link circle link either in radix or link format - * @param[out] circleId optional storage for parsed circle id - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if some error occurred, true otherwise - */ - virtual bool importCircleLink( - const std::string& link, - RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - RS_DEPRECATED_FOR("getCirclesSummaries getCirclesInfo") - virtual bool getGroupData( - const uint32_t& token, std::vector& groups ) = 0; - - RS_DEPRECATED_FOR(getCirclesRequests) - virtual bool getMsgData( - const uint32_t& token, std::vector& msgs ) = 0; - - /// make new group - RS_DEPRECATED_FOR(createCircle) - virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0; - - /// update an existing group - RS_DEPRECATED_FOR("editCircle, inviteIdsToCircle") - virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0; -}; - - -/// @deprecated Used to detect uninizialized values. -RS_DEPRECATED_FOR("RsGxsCircleType::UNKNOWN") -static const uint32_t GXS_CIRCLE_TYPE_UNKNOWN = 0x0000; - -/// @deprecated not restricted to a circle -RS_DEPRECATED_FOR("RsGxsCircleType::PUBLIC") -static const uint32_t GXS_CIRCLE_TYPE_PUBLIC = 0x0001; - -/// @deprecated restricted to an external circle, made of RsGxsId -RS_DEPRECATED_FOR("RsGxsCircleType::EXTERNAL") -static const uint32_t GXS_CIRCLE_TYPE_EXTERNAL = 0x0002; - -/// @deprecated restricted to a subset of friend nodes of a given RS node given -/// by a RsPgpId list -RS_DEPRECATED_FOR("RsGxsCircleType::NODES_GROUP") -static const uint32_t GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY = 0x0003; - -/// @deprecated not distributed at all -RS_DEPRECATED_FOR("RsGxsCircleType::LOCAL") -static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004; - -/// @deprecated self-restricted. Not used, except at creation time when the -/// circle ID isn't known yet. Set to EXTERNAL afterwards. -RS_DEPRECATED_FOR("RsGxsCircleType::EXT_SELF") -static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005; - -/// @deprecated distributed to nodes signed by your own PGP key only. -RS_DEPRECATED_FOR("RsGxsCircleType::YOUR_EYES_ONLY") -static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006; diff --git a/libretroshare/src/retroshare/rsgxscommon.h b/libretroshare/src/retroshare/rsgxscommon.h deleted file mode 100644 index c820e1999..000000000 --- a/libretroshare/src/retroshare/rsgxscommon.h +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxscommon.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "rsgxsifacetypes.h" -#include "serialiser/rsserializable.h" - -struct RsGxsFile : RsSerializable -{ - RsGxsFile(); - std::string mName; - RsFileHash mHash; - uint64_t mSize; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mName); - RS_SERIAL_PROCESS(mHash); - RS_SERIAL_PROCESS(mSize); - } - - void clear() - { - mName.clear(); - mHash.clear(); - mSize = 0; - } -}; - -struct RsGxsImage : RsSerializable -{ - RsGxsImage(); - ~RsGxsImage(); - - /// Use copy constructor and duplicate memory. - RsGxsImage(const RsGxsImage& a); - - RsGxsImage &operator=(const RsGxsImage &a); // Need this as well? - - /** NB: Must make sure that we always use methods - to be consistent about - * malloc/free for this data. */ - static uint8_t *allocate(uint32_t size); - static void release(void *data); - - void take(uint8_t *data, uint32_t size); // Copies Pointer. - void copy(uint8_t *data, uint32_t size); // Allocates and Copies. - void clear(); // Frees. - void shallowClear(); // Clears Pointer. - bool empty() const; - - uint32_t mSize; - uint8_t* mData; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RsTypeSerializer::TlvMemBlock_proxy b(mData, mSize); - RsTypeSerializer::serial_process(j, ctx, b, "mData"); - } -}; - -enum class RsGxsVoteType : uint32_t -{ - NONE = 0, /// Used to detect unset vote? - DOWN = 1, /// Negative vote - UP = 2 /// Positive vote -}; - - -// Status Flags to indicate Voting.... -// All Services that use the Comment service must not Use This space. -namespace GXS_SERV { - /* Msg Vote Status */ - static const uint32_t GXS_MSG_STATUS_GXSCOMMENT_MASK = 0x000f0000; - static const uint32_t GXS_MSG_STATUS_VOTE_MASK = 0x00030000; - - static const uint32_t GXS_MSG_STATUS_VOTE_UP = 0x00010000; - static const uint32_t GXS_MSG_STATUS_VOTE_DOWN = 0x00020000; -} - - - - -struct RsGxsVote : RsSerializable -{ - RsGxsVote(); - RsMsgMetaData mMeta; - uint32_t mVoteType; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mVoteType); - } -}; - -struct RsGxsComment : RsSerializable -{ - RsGxsComment(); - RsMsgMetaData mMeta; - std::string mComment; - - // below is calculated. - uint32_t mUpVotes; - uint32_t mDownVotes; - double mScore; - - uint32_t mOwnVote; - - // This is filled in if detailed Comment Data is called. - std::list mVotes; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mComment); - RS_SERIAL_PROCESS(mUpVotes); - RS_SERIAL_PROCESS(mDownVotes); - RS_SERIAL_PROCESS(mScore); - RS_SERIAL_PROCESS(mOwnVote); - RS_SERIAL_PROCESS(mVotes); - } -}; - - -struct RsGxsCommentService -{ - RsGxsCommentService() {} - virtual ~RsGxsCommentService() {} - - /** Get previously requested comment data with token */ - virtual bool getCommentData( uint32_t token, - std::vector &comments ) = 0; - virtual bool getRelatedComments( uint32_t token, - std::vector &comments ) = 0; - - virtual bool createNewComment(uint32_t &token, const RsGxsComment &comment) = 0; // async API - virtual bool createComment(RsGxsComment& comment) = 0; // blocking API. Updates comment with new metadata. - - virtual bool createNewVote(uint32_t &token, RsGxsVote &vote) = 0; - - virtual bool acknowledgeComment( - uint32_t token, - std::pair& msgId ) = 0; - - virtual bool acknowledgeVote( - uint32_t token, - std::pair& msgId ) = 0; - - virtual bool setCommentAsRead(uint32_t& token,const RsGxsGroupId& gid,const RsGxsMessageId& comment_msg_id) = 0; -}; - -/// @deprecated use RsGxsVoteType::NONE instead @see RsGxsVoteType -#define GXS_VOTE_NONE 0x0000 - -/// @deprecated use RsGxsVoteType::DOWN instead @see RsGxsVoteType -#define GXS_VOTE_DOWN 0x0001 - -/// @deprecated use RsGxsVoteType::UP instead @see RsGxsVoteType -#define GXS_VOTE_UP 0x0002 diff --git a/libretroshare/src/retroshare/rsgxsdistsync.h b/libretroshare/src/retroshare/rsgxsdistsync.h deleted file mode 100644 index d65027d58..000000000 --- a/libretroshare/src/retroshare/rsgxsdistsync.h +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsdistsync.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include "retroshare/rsfiles.h" -#include "retroshare/rsturtle.h" - -typedef RsPeerId RsGxsNetTunnelVirtualPeerId ; - -struct RsGxsNetTunnelVirtualPeerInfo -{ - enum { RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN = 0x00, // unknown status. - RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK = 0x01, // tunnel has been established and we're waiting for virtual peer id - RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE = 0x02 // virtual peer id is known. Data can transfer. - }; - - RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN), last_contact(0),side(0) { memset(encryption_master_key,0,32) ; } - virtual ~RsGxsNetTunnelVirtualPeerInfo(){} - - uint8_t vpid_status ; // status of the peer - rstime_t last_contact ; // last time some data was sent/recvd - uint8_t side ; // client/server - uint8_t encryption_master_key[32]; - - TurtleVirtualPeerId turtle_virtual_peer_id ; // turtle peer to use when sending data to this vpid. - - RsGxsGroupId group_id ; // group that virtual peer is providing - uint16_t service_id ; // this is used for checkng consistency of the incoming data -}; - -struct RsGxsNetTunnelGroupInfo -{ - enum GroupStatus { - RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status - RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE = 0x01, // no virtual peers requested, just waiting - RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available. Data can be read/written - }; - - enum GroupPolicy { - RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN = 0x00, // nothing has been set - RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE = 0x01, // group is available for server side tunnels, but does not explicitely request tunnels - RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE = 0x02, // group will only explicitely request tunnels if none available - RS_GXS_NET_TUNNEL_GRP_POLICY_REQUESTING = 0x03, // group explicitely requests tunnels - }; - - RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0) {} - - GroupPolicy group_policy ; - GroupStatus group_status ; - rstime_t last_contact ; - RsFileHash hash ; - uint16_t service_id ; - - std::set virtual_peers ; // list of which virtual peers provide this group. Can me more than 1. -}; - -// This class is here to provide statistics about GXS dist sync internals. It -// -class RsGxsDistSync -{ - public: - virtual void getStatistics( - std::map& groups, // groups on the client and server side - std::map& virtual_peers, // current virtual peers, which group they provide, and how to talk to them through turtle - std::map& turtle_vpid_to_net_tunnel_vpid, - Bias20Bytes& bias - ) const =0; -}; - -extern RsGxsDistSync *rsGxsDistSync ; - diff --git a/libretroshare/src/retroshare/rsgxsflags.h b/libretroshare/src/retroshare/rsgxsflags.h deleted file mode 100644 index 7ef6d2c49..000000000 --- a/libretroshare/src/retroshare/rsgxsflags.h +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsflags.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2018 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSFLAGS_H -#define RSGXSFLAGS_H - -#include "inttypes.h" - -/** - * The GXS_SERV namespace serves a single point of reference for definining grp and msg flags - * Declared and defined here are: - * - privacy flags which define the level of privacy that can be given \n - * to a group - * - authentication types which defined types of authentication needed for a given message to - * confirm its authenticity - * - subscription flags: This used only locally by the peer to subscription status to a \n - * a group - * - - */ -namespace GXS_SERV { - - /** START privacy **/ - - static const uint32_t FLAG_PRIVACY_MASK = 0x0000000f; - static const uint32_t FLAG_PRIVACY_PRIVATE = 0x00000001; // pub key encrypted. No-one can read unless he has the key to decrypt the publish key. - static const uint32_t FLAG_PRIVACY_RESTRICTED = 0x00000002; // publish private key needed to publish. Typical usage: channels. - static const uint32_t FLAG_PRIVACY_PUBLIC = 0x00000004; // anyone can publish, publish key pair not needed. Typical usage: forums. - - /** END privacy **/ - - /** 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; // Anti-spam feature. Allows to ask higher reputation to anonymous IDs - 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; // not used anymore - static const uint32_t FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN = 0x00001000; // Anti-spam feature. Allows to ask higher reputation to unknown IDs and anonymous IDs - - 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; // unused - 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; // means: new threads need to be signed by the publish signature of the group. Typical use: posts in channels. - static const uint8_t MSG_AUTHEN_CHILD_PUBLISH_SIGN = 0x02; // means: all messages need to be signed by the publish signature of the group. Typical use: channels were comments are restricted to the publisher. - static const uint8_t MSG_AUTHEN_ROOT_AUTHOR_SIGN = 0x04; // means: new threads need to be signed by the author of the message. Typical use: forums, since posts are signed. - static const uint8_t MSG_AUTHEN_CHILD_AUTHOR_SIGN = 0x08; // means: all messages need to be signed by the author of the message. Typical use: forums since response to posts are signed, and signed comments in channels. - - /** END msg authentication flags **/ - - /** START group options flag **/ - - static const uint8_t GRP_OPTION_AUTHEN_AUTHOR_SIGN = 0x01; // means: the group options (serialised grp data) needs to be signed by a specific author stored in GroupMeta.mAuthorId - // note that it is always signed by the *admin* (means the creator) of the group. This author signature is just an option here. - - /** END group options flag **/ - - /** START Subscription Flags. (LOCAL) **/ - - static const uint32_t GROUP_SUBSCRIBE_ADMIN = 0x01;// means: you have the admin key for this group - static const uint32_t GROUP_SUBSCRIBE_PUBLISH = 0x02;// means: you have the publish key for thiss group. Typical use: publish key in channels are shared with specific friends. - static const uint32_t GROUP_SUBSCRIBE_SUBSCRIBED = 0x04;// means: you are subscribed to a group, which makes you a source for this group to your friend nodes. - static const uint32_t GROUP_SUBSCRIBE_NOT_SUBSCRIBED = 0x08; - - /*! - * Simply defines the range of bits that deriving services - * should not use - */ - static const uint32_t GROUP_SUBSCRIBE_MASK = 0x0000000f; - - /** END Subscription Flags. (LOCAL) **/ - - /** START GXS Msg status flags **/ - - /*! - * Two lower bytes are reserved for Generic STATUS Flags listed here. - * Services are free to use the two upper bytes. (16 flags). - * - * NOTE: RsGxsCommentService uses 0x000f0000. - */ - static const uint32_t GXS_MSG_STATUS_GEN_MASK = 0x0000ffff; - static const uint32_t GXS_MSG_STATUS_UNPROCESSED = 0x00000001; // Flags to store the read/process status of group messages. - static const uint32_t GXS_MSG_STATUS_GUI_UNREAD = 0x00000002; // The actual meaning may depend on the type of service. - static const uint32_t GXS_MSG_STATUS_GUI_NEW = 0x00000004; // - static const uint32_t GXS_MSG_STATUS_KEEP_FOREVER = 0x00000008; // Do not delete message even if older then group maximum storage time - static const uint32_t GXS_MSG_STATUS_DELETE = 0x00000020; // - - /** END GXS Msg status flags **/ - - /** START GXS Grp status flags **/ - - static const uint32_t GXS_GRP_STATUS_UNPROCESSED = 0x000000100; - static const uint32_t GXS_GRP_STATUS_UNREAD = 0x000000200; - - /** END GXS Grp status flags **/ -} - - -// GENERIC GXS MACROS -#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_MSG_UNPROCESSED(status) (status & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED) - -#define IS_GROUP_PGP_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) -#define IS_GROUP_PGP_KNOWN_AUTHED(signFlags) (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) -#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_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) -#define IS_GROUP_NOT_SUBSCRIBED(subscribeFlags) (subscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED) - -#endif // RSGXSFLAGS_H diff --git a/libretroshare/src/retroshare/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h deleted file mode 100644 index 83a961fc3..000000000 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ /dev/null @@ -1,421 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsforums.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rsserializable.h" -#include "retroshare/rsgxscircles.h" - - -class RsGxsForums; - -/** - * Pointer to global instance of RsGxsForums service implementation - * @jsonapi{development} - */ -extern RsGxsForums* rsGxsForums; - - -/** Forum Service message flags, to be used in RsMsgMetaData::mMsgFlags - * Gxs imposes to use the first two bytes (lower bytes) of mMsgFlags for - * private forum flags, the upper bytes being used for internal GXS stuff. - * @todo mixing service level flags and GXS level flag into the same member is - * prone to confusion, use separated members for those things - */ -static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MASK = 0x0000000f; -static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001; - -#define IS_FORUM_MSG_MODERATION(flags) (flags & RS_GXS_FORUM_MSG_FLAGS_MODERATED) - - -struct RsGxsForumGroup : RsSerializable, RsGxsGenericGroupData -{ - /** @brief Forum desciption */ - std::string mDescription; - - /** @brief List of forum moderators ids - * @todo run away from TLV old serializables as those types are opaque to - * JSON API! */ - RsTlvGxsIdSet mAdminList; - - /** @brief List of forum pinned posts, those are usually displayed on top - * @todo run away from TLV old serializables as those types are opaque to - * JSON API! */ - RsTlvGxsMsgIdSet mPinnedPosts; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - ~RsGxsForumGroup() override; - - /* G10h4ck: We should avoid actual methods in this contexts as they are - * invisible to JSON API */ - bool canEditPosts(const RsGxsId& id) const; -}; - -struct RsGxsForumMsg : RsSerializable -{ - /** @brief Forum post GXS metadata */ - RsMsgMetaData mMeta; - - /** @brief Forum post content */ - std::string mMsg; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mMsg); - } - - ~RsGxsForumMsg() override; -}; - - -enum class RsForumEventCode: uint8_t -{ - UNKNOWN = 0x00, - NEW_FORUM = 0x01, /// emitted when new forum is received - UPDATED_FORUM = 0x02, /// emitted when existing forum is updated - NEW_MESSAGE = 0x03, /// new message reeived in a particular forum - UPDATED_MESSAGE = 0x04, /// existing message has been updated in a particular forum - SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed - READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread - STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed - MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed. - SYNC_PARAMETERS_UPDATED = 0x0a, /// sync and storage times have changed - PINNED_POSTS_CHANGED = 0x0b, /// some posts where pinned or un-pinned - DELETED_FORUM = 0x0c, /// forum was deleted by cleaning -}; - -struct RsGxsForumEvent: RsEvent -{ - RsGxsForumEvent() - : RsEvent(RsEventType::GXS_FORUMS), - mForumEventCode(RsForumEventCode::UNKNOWN) {} - - RsForumEventCode mForumEventCode; - RsGxsGroupId mForumGroupId; - RsGxsMessageId mForumMsgId; - std::list mModeratorsAdded; - std::list mModeratorsRemoved; - - ///* @see RsEvent @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mForumEventCode); - RS_SERIAL_PROCESS(mForumGroupId); - RS_SERIAL_PROCESS(mForumMsgId); - RS_SERIAL_PROCESS(mForumMsgId); - RS_SERIAL_PROCESS(mModeratorsAdded); - RS_SERIAL_PROCESS(mModeratorsRemoved); - } - - ~RsGxsForumEvent() override; -}; - -class RsGxsForums: public RsGxsIfaceHelper -{ -public: - explicit RsGxsForums(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - virtual ~RsGxsForums(); - - /** - * @brief Create forum. - * @jsonapi{development} - * @param[in] name Name of the forum - * @param[in] description Optional description of the forum - * @param[in] authorId Optional id of the froum owner author - * @param[in] moderatorsIds Optional list of forum moderators - * @param[in] circleType Optional visibility rule, default public. - * @param[in] circleId If the forum is not public specify the id of - * the circle who can see the forum. Depending on - * the value you pass for circleType this should - * be a circle if EXTERNAL is passed, a local - * friends group id if NODES_GROUP is passed, - * empty otherwise. - * @param[out] forumId Optional storage for the id of the created - * forum, meaningful only if creations succeeds. - * @param[out] errorMessage Optional storage for error messsage, meaningful - * only if creation fail. - * @return False on error, true otherwise. - */ - virtual bool createForumV2( - const std::string& name, const std::string& description, - const RsGxsId& authorId = RsGxsId(), - const std::set& moderatorsIds = std::set(), - RsGxsCircleType circleType = RsGxsCircleType::PUBLIC, - const RsGxsCircleId& circleId = RsGxsCircleId(), - RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) = 0; - - /** - * @brief Create a post on the given forum. - * @jsonapi{development} - * @param[in] forumId Id of the forum in which the post is to be - * submitted - * @param[in] title UTF-8 string containing the title of the post - * @param[in] mBody UTF-8 string containing the text of the post - * @param[in] authorId Id of the author of the comment - * @param[in] parentId Optional Id of the parent post if this post is a - * reply to another post, empty otherwise. - * @param[in] origPostId If this is supposed to replace an already - * existent post, the id of the old post. - * If left blank a new post will be created. - * @param[out] postMsgId Optional storage for the id of the created, - * meaningful only on success. - * @param[out] errorMessage Optional storage for error message, meaningful - * only on failure. - * @return false on error, true otherwise - */ - virtual bool createPost( - const RsGxsGroupId& forumId, - const std::string& title, - const std::string& mBody, - const RsGxsId& authorId, - const RsGxsMessageId& parentId = RsGxsMessageId(), - const RsGxsMessageId& origPostId = RsGxsMessageId(), - RsGxsMessageId& postMsgId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) = 0; - - /** - * @brief Edit forum details. - * @jsonapi{development} - * @param[in] forum Forum data (name, description...) with modifications - * @return false on error, true otherwise - */ - virtual bool editForum(RsGxsForumGroup& forum) = 0; - - /** - * @brief Get forums summaries list. Blocking API. - * @jsonapi{development} - * @param[out] forums list where to store the forums summaries - * @return false if something failed, true otherwhise - */ - virtual bool getForumsSummaries(std::list& forums) = 0; - - /** - * @brief returns statistics for the forum service - * @jsonapi{development} - * @param[out] stat statistics struct - * @return false if the call fails - */ - virtual bool getForumServiceStatistics(GxsServiceStatistic& stat) =0; - - /** - * @brief returns statistics about a particular forum - * @jsonapi{development} - * @param[in] forumId Id of the forum - * @param[out] stat statistics struct - * @return false when the object doesn't exist or when the timeout is reached requesting the data - */ - virtual bool getForumStatistics(const RsGxsGroupId& forumId,GxsGroupStatistic& stat)=0; - - - /** - * @brief Get forums information (description, thumbnail...). - * Blocking API. - * @jsonapi{development} - * @param[in] forumIds ids of the forums of which to get the informations - * @param[out] forumsInfo storage for the forums informations - * @return false if something failed, true otherwhise - */ - virtual bool getForumsInfo( - const std::list& forumIds, - std::vector& forumsInfo ) = 0; - - /** - * @brief Get message metadatas for a specific forum. Blocking API - * @jsonapi{development} - * @param[in] forumId id of the forum of which the content is requested - * @param[out] msgMetas storage for the forum messages meta data - * @return false if something failed, true otherwhise - */ - virtual bool getForumMsgMetaData( const RsGxsGroupId& forumId, - std::vector& msgMetas) = 0; - - /** - * @brief Get specific list of messages from a single forum. Blocking API - * @jsonapi{development} - * @param[in] forumId id of the forum of which the content is requested - * @param[in] msgsIds list of message ids to request - * @param[out] msgs storage for the forum messages - * @return false if something failed, true otherwhise - */ - virtual bool getForumContent( - const RsGxsGroupId& forumId, - const std::set& msgsIds, - std::vector& msgs) = 0; - - /** - * @brief Toggle message read status. Blocking API. - * @jsonapi{development} - * @param[in] messageId post identifier - * @param[in] read true to mark as read, false to mark as unread - * @return false on error, true otherwise - */ - virtual bool markRead(const RsGxsGrpMsgIdPair& messageId, bool read) = 0; - - /** - * @brief Subscrbe to a forum. Blocking API - * @jsonapi{development} - * @param[in] forumId Forum id - * @param[in] subscribe true to subscribe, false to unsubscribe - * @return false on error, true otherwise - */ - virtual bool subscribeToForum( const RsGxsGroupId& forumId, - bool subscribe ) = 0; - - /// default base URL used for forums links @see exportForumLink - static const std::string DEFAULT_FORUM_BASE_URL; - - /// Link query field used to store forum name @see exportForumLink - static const std::string FORUM_URL_NAME_FIELD; - - /// Link query field used to store forum id @see exportForumLink - static const std::string FORUM_URL_ID_FIELD; - - /// Link query field used to store forum data @see exportForumLink - static const std::string FORUM_URL_DATA_FIELD; - - /** Link query field used to store forum message title - * @see exportForumLink */ - static const std::string FORUM_URL_MSG_TITLE_FIELD; - - /// Link query field used to store forum message id @see exportForumLink - static const std::string FORUM_URL_MSG_ID_FIELD; - - /** - * @brief Get link to a forum - * @jsonapi{development} - * @param[out] link storage for the generated link - * @param[in] forumId Id of the forum of which we want to generate a link - * @param[in] includeGxsData if true include the forum GXS group data so - * the receiver can subscribe to the forum even if she hasn't received it - * through GXS yet - * @param[in] baseUrl URL into which to sneak in the RetroShare link - * radix, this is primarly useful to induce applications into making the - * link clickable, or to disguise the RetroShare link into a - * "normal" looking web link. If empty the GXS data link will be outputted - * in plain base64 format. - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if something failed, true otherwhise - */ - virtual bool exportForumLink( - std::string& link, const RsGxsGroupId& forumId, - bool includeGxsData = true, - const std::string& baseUrl = RsGxsForums::DEFAULT_FORUM_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Import forum from full link - * @param[in] link forum link either in radix or URL format - * @param[out] forumId optional storage for parsed forum id - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if some error occurred, true otherwise - */ - virtual bool importForumLink( - const std::string& link, - RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Get posts related to the given post. - * If the set is empty, nothing is returned. - * @jsonapi{development} - * @param[in] forumId id of the forum of which the content is requested - * @param[in] parentId id of the post of which child posts (aka replies) - * are requested. - * @param[out] childPosts storage for the child posts - * @return Success or error details - */ - virtual std::error_condition getChildPosts( - const RsGxsGroupId& forumId, const RsGxsMessageId& parentId, - std::vector& childPosts ) = 0; - - /** - * @brief Set keep forever flag on a post so it is not deleted even if older - * then group maximum storage time - * @jsonapi{development} - * @param[in] forumId id of the forum of which the post pertain - * @param[in] postId id of the post on which to set the flag - * @param[in] keepForever true to set the flag, false to unset it - * @return Success or error details - */ - virtual std::error_condition setPostKeepForever( - const RsGxsGroupId& forumId, const RsGxsMessageId& postId, - bool keepForever ) = 0; - - /** - * @brief Create forum. Blocking API. - * @jsonapi{development} - * @param[inout] forum Forum data (name, description...) - * @return false on error, true otherwise - * @deprecated @see createForumV2 - */ - RS_DEPRECATED_FOR(createForumV2) - virtual bool createForum(RsGxsForumGroup& forum) = 0; - - /** - * @brief Create forum message. Blocking API. - * @jsonapi{development} - * @param[inout] message - * @return false on error, true otherwise - * @deprecated @see createPost - */ - RS_DEPRECATED_FOR(createPost) - virtual bool createMessage(RsGxsForumMsg& message) = 0; - - /* Specific Service Data */ - RS_DEPRECATED_FOR("getForumsSummaries, getForumsInfo") - virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; - RS_DEPRECATED_FOR(getForumContent) - virtual bool getMsgData(const uint32_t &token, std::vector &msgs) = 0; - RS_DEPRECATED_FOR(markRead) - virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; - RS_DEPRECATED_FOR(createForum) - virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; - RS_DEPRECATED_FOR(createMessage) - virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; - RS_DEPRECATED_FOR(editForum) - virtual bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) = 0; -}; diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h deleted file mode 100644 index ce64bf4ed..000000000 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ /dev/null @@ -1,325 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsiface.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Christopher Evi-Parker * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsreputations.h" -#include "retroshare/rsgxsservice.h" -#include "gxs/rsgxsdata.h" -#include "retroshare/rsgxsifacetypes.h" -#include "util/rsdeprecate.h" -#include "serialiser/rsserializable.h" -#include "rsitems/rsserviceids.h" -#include "retroshare/rsevents.h" - -/*! - * This structure is used to transport group summary information when a GXS - * service is searched. It contains the group information as well as a context - * string to tell where the information was found. It is more compact than a - * GroupMeta object, so as to make search responses as light as possible. - */ -struct RsGxsGroupSummary : RsSerializable -{ - RsGxsGroupSummary() : - mPublishTs(0), mNumberOfMessages(0),mLastMessageTs(0), - mSignFlags(0),mPopularity(0) {} - - RsGxsGroupId mGroupId; - std::string mGroupName; - RsGxsId mAuthorId; - rstime_t mPublishTs; - uint32_t mNumberOfMessages; - rstime_t mLastMessageTs; - uint32_t mSignFlags; - uint32_t mPopularity; - - std::string mSearchContext; - - /// @see RsSerializable::serial_process - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mGroupId); - RS_SERIAL_PROCESS(mGroupName); - RS_SERIAL_PROCESS(mAuthorId); - RS_SERIAL_PROCESS(mPublishTs); - RS_SERIAL_PROCESS(mNumberOfMessages); - RS_SERIAL_PROCESS(mLastMessageTs); - RS_SERIAL_PROCESS(mSignFlags); - RS_SERIAL_PROCESS(mPopularity); - RS_SERIAL_PROCESS(mSearchContext); - } - - ~RsGxsGroupSummary(); -}; - -/*! - * This structure is used to locally store group search results for a given service. - * It contains the group information as well as a context - * strings to tell where the information was found. It is more compact than a - * GroupMeta object, so as to make search responses as light as possible. - */ -struct RsGxsGroupSearchResults : RsSerializable -{ - RsGxsGroupSearchResults() - : mPublishTs(0), mNumberOfMessages(0),mLastMessageTs(0), mSignFlags(0),mPopularity(0) - {} - - RsGxsGroupId mGroupId; - std::string mGroupName; - RsGxsId mAuthorId; - rstime_t mPublishTs; - uint32_t mNumberOfMessages; - rstime_t mLastMessageTs; - uint32_t mSignFlags; - uint32_t mPopularity; - - std::set mSearchContexts; - - /// @see RsSerializable::serial_process - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mGroupId); - RS_SERIAL_PROCESS(mGroupName); - RS_SERIAL_PROCESS(mAuthorId); - RS_SERIAL_PROCESS(mPublishTs); - RS_SERIAL_PROCESS(mNumberOfMessages); - RS_SERIAL_PROCESS(mLastMessageTs); - RS_SERIAL_PROCESS(mSignFlags); - RS_SERIAL_PROCESS(mPopularity); - RS_SERIAL_PROCESS(mSearchContexts); - } - - virtual ~RsGxsGroupSearchResults() = default; -}; - -/*! - * Stores ids of changed gxs groups and messages. - * It is used to notify about GXS changes. - */ -struct RsGxsChanges : RsEvent -{ - RsGxsChanges(); - - /// Type of the service - RsServiceType mServiceType; - std::map > mMsgs; - std::map > mMsgsMeta; - std::list mGrps; - std::list mGrpsMeta; - std::list mDistantSearchReqs; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j,ctx); - RS_SERIAL_PROCESS(mServiceType); - RS_SERIAL_PROCESS(mMsgs); - RS_SERIAL_PROCESS(mMsgsMeta); - RS_SERIAL_PROCESS(mGrps); - RS_SERIAL_PROCESS(mGrpsMeta); - RS_SERIAL_PROCESS(mDistantSearchReqs); - } - - RsTokenService* mService; /// Weak pointer, not serialized -}; - -enum class DistantSearchGroupStatus:uint8_t -{ - UNKNOWN = 0x00, // no search ongoing for this group - CAN_BE_REQUESTED = 0x01, // a search result mentions this group, so the group data can be requested - ONGOING_REQUEST = 0x02, // the group data has been requested and the request is pending - HAVE_GROUP_DATA = 0x03, // group data has been received. Group can be subscribed. -}; - -/*! - * All implementations must offer thread safety - */ -struct RsGxsIface -{ - /*! - * \brief serviceType - * \return The 16-bits service type. See @serialiser/rsserviceids.h - */ - virtual uint16_t serviceType() const =0; - -#ifdef TO_REMOVE - /*! - * Gxs services should call this for automatic handling of - * changes, send - * @param changes - */ - virtual void receiveChanges(std::vector& changes) = 0; -#endif - - /*! - * @return handle to token service for this GXS service - */ - virtual RsTokenService* getTokenService() = 0; - - /* Generic Lists */ - - /*! - * Retrieve list of group ids associated to a request token - * @param token token to be redeemed for this request - * @param groupIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupList(const uint32_t &token, - std::list &groupIds) = 0; - - /*! - * Retrieves list of msg ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgList(const uint32_t &token, - GxsMsgIdResult& msgIds) = 0; - - /*! - * Retrieves list of msg related ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgRelatedList(const uint32_t &token, - MsgRelatedIdResult& msgIds) = 0; - - /*! - * @param token token to be redeemed for group summary request - * @param groupInfo the ids returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupMeta(const uint32_t &token, - std::list &groupInfo) = 0; - - /*! - * @param token token to be redeemed for message summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgMeta(const uint32_t &token, - GxsMsgMetaMap &msgInfo) = 0; - - /*! - * @param token token to be redeemed for message related summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgRelatedMeta(const uint32_t &token, - GxsMsgRelatedMetaMap &msgInfo) = 0; - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - virtual bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) = 0; - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeTokenMsg(const uint32_t& token, std::pair& msgId) = 0; - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeTokenGrp(const uint32_t& token, RsGxsGroupId& grpId) = 0; - - /*! - * Gets service statistic for a given services - * @param token value to to retrieve requested stats - * @param stats the status - * @return true if token exists false otherwise - */ - virtual bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) = 0; - - /*! - * - * @param token to be redeemed - * @param stats the stats associated to token request - * @return true if token is false otherwise - */ - virtual bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) = 0; - - /*! - * - * @param token value set to be redeemed with acknowledgement - * @param grpId group id for cutoff value to be set - * @param CutOff The cut off value to set - */ - virtual void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) = 0; - - /*! - * @return storage/sync time of messages in secs - */ - virtual uint32_t getDefaultStoragePeriod() = 0; - virtual uint32_t getStoragePeriod(const RsGxsGroupId& grpId) = 0; - virtual void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0; - - virtual uint32_t getDefaultSyncPeriod() = 0; - virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0; - virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0; - - virtual RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags,uint32_t identity_flags ) = 0; - - /** - * @brief Export group public data in base64 format - * @jsonapi{development} - * @param[out] radix storage for the generated base64 data - * @param[in] groupId Id of the group of which to output the data - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if something failed, true otherwhise - */ - virtual bool exportGroupBase64( - std::string& radix, const RsGxsGroupId& groupId, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Import group public data from base64 string - * @param[in] radix group invite in radix format - * @param[out] groupId optional storage for imported group id - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if some error occurred, true otherwise - */ - virtual bool importGroupBase64( - const std::string& radix, - RsGxsGroupId& groupId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - virtual ~RsGxsIface(); -}; diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h deleted file mode 100644 index 4339f95f0..000000000 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ /dev/null @@ -1,536 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsifacehelper.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2011 Christopher Evi-Parker * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "retroshare/rsgxsiface.h" -#include "retroshare/rsservicecontrol.h" -#include "retroshare/rsreputations.h" -#include "rsgxsflags.h" -#include "util/rsdeprecate.h" -#include "util/rsdebug.h" - -/*! - * This class only make method of internal members visible tu upper level to - * offer a more friendly API. - * This is just a workaround to awkward GXS API design, do not take it as an - * example for your coding. - * To properly fix the API design many changes with the implied chain reactions - * are necessary, so at this point this workaround seems acceptable. - */ - -//================================== -// #define DEBUG_GXSIFACEHELPER 1 -//================================== - -enum class TokenRequestType: uint8_t -{ - __NONE = 0x00, /// Used to detect uninitialized - GROUP_DATA = 0x01, - GROUP_META = 0x02, - GROUP_IDS = 0x03, - POSTS = 0x04, - ALL_POSTS = 0x05, - MSG_RELATED_INFO = 0x06, - GROUP_STATISTICS = 0x07, - SERVICE_STATISTICS = 0x08, - NO_KILL_TYPE = 0x09, - __MAX /// Used to detect out of range -}; - -class RsGxsIfaceHelper -{ -public: - /*! - * @param gxs handle to RsGenExchange instance of service (Usually the - * service class itself) - */ - explicit RsGxsIfaceHelper(RsGxsIface& gxs) : - mGxs(gxs), mTokenService(*gxs.getTokenService()), mMtx("GxsIfaceHelper") - {} - - ~RsGxsIfaceHelper() = default; - -#ifdef TO_REMOVE - /*! - * Gxs services should call this for automatic handling of - * changes, send - * @param changes - */ - void receiveChanges(std::vector &changes) - { - mGxs.receiveChanges(changes); - } -#endif - - /* Generic Lists */ - - /*! - * Retrieve list of group ids associated to a request token - * @param token token to be redeemed for this request - * @param groupIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getGroupList(const uint32_t &token, std::list &groupIds) - { - return mGxs.getGroupList(token, groupIds); - } - - /*! - * Retrieves list of msg ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgList(const uint32_t &token, - GxsMsgIdResult& msgIds) - { - return mGxs.getMsgList(token, msgIds); - } - - /*! - * Retrieves list of msg related ids associated to a request token - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds) - { - return mGxs.getMsgRelatedList(token, msgIds); - } - - /*! - * @param token token to be redeemed for group summary request - * @param groupInfo the ids returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getGroupSummary(const uint32_t &token, std::list &groupInfo) - { - return mGxs.getGroupMeta(token, groupInfo); - } - - /*! - * @param token token to be redeemed for message summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgSummary(const uint32_t &token, GxsMsgMetaMap &msgInfo) - { - return mGxs.getMsgMeta(token, msgInfo); - } - - /*! - * @param token token to be redeemed for message related summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - bool getMsgRelatedSummary(const uint32_t &token, GxsMsgRelatedMetaMap &msgInfo) - { - return mGxs.getMsgRelatedMeta(token, msgInfo); - } - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) - { - return mGxs.subscribeToGroup(token, grpId, subscribe); - } - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) - { - return mGxs.acknowledgeTokenMsg(token, msgId); - } - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) - { - return mGxs.acknowledgeTokenGrp(token, grpId); - } - - /*! - * Gets service statistic for a given services - * @param token value to to retrieve requested stats - * @param stats the status - * @return true if token exists false otherwise - */ - bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) - { - return mGxs.getServiceStatistic(token, stats); - } - - /*! - * - * @param token to be redeemed - * @param stats the stats associated to token request - * @return true if token is false otherwise - */ - bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) - { - return mGxs.getGroupStatistic(token, stats); - } - - /*! - * This determines the reputation threshold messages need to surpass in order - * for it to be accepted by local user from remote source - * NOTE: threshold only enforced if service require author signature - * @param token value set to be redeemed with acknowledgement - * @param grpId group id for cutoff value to be set - * @param CutOff The cut off value to set - */ - void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff) - { - return mGxs.setGroupReputationCutOff(token, grpId, CutOff); - } - - /*! - * @return storage/sync time of messages in secs - */ - uint32_t getDefaultStoragePeriod() - { - return mGxs.getDefaultStoragePeriod(); - } - uint32_t getStoragePeriod(const RsGxsGroupId& grpId) - { - return mGxs.getStoragePeriod(grpId); - } - void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) - { - mGxs.setStoragePeriod(grpId,age_in_secs); - } - uint32_t getDefaultSyncPeriod() - { - return mGxs.getDefaultSyncPeriod(); - } - uint32_t getSyncPeriod(const RsGxsGroupId& grpId) - { - return mGxs.getSyncPeriod(grpId); - } - void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) - { - mGxs.setSyncPeriod(grpId,age_in_secs); - } - - RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_flags ) - { - return mGxs.minReputationForForwardingMessages(group_sign_flags,identity_flags); - } - - /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list &groupIds, bool high_priority_request = false ) - { - TokenRequestType token_request_type; - - switch(opts.mReqType) - { - case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; - case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; - case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; - default: - RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; - return false; - } - - cancelActiveRequestTokens(token_request_type); - - if( mTokenService.requestGroupInfo(token, 0, opts, groupIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestGroupInfo - bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts, bool high_priority_request = false) - { - TokenRequestType token_request_type; - - switch(opts.mReqType) - { - case GXS_REQUEST_TYPE_GROUP_DATA: token_request_type = TokenRequestType::GROUP_DATA; break; - case GXS_REQUEST_TYPE_GROUP_META: token_request_type = TokenRequestType::GROUP_META; break; - case GXS_REQUEST_TYPE_GROUP_IDS: token_request_type = TokenRequestType::GROUP_IDS; break; - default: - RsErr() << __PRETTY_FUNCTION__ << "(EE) Unexpected request type " << opts.mReqType << "!!" << std::endl; - return false; - } - - cancelActiveRequestTokens(token_request_type); - - - if( mTokenService.requestGroupInfo(token, 0, opts)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : token_request_type; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgInfo - bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const GxsMsgReq& msgIds ) - { - if(mTokenService.requestMsgInfo(token, 0, opts, msgIds)) - { - RS_STACK_MUTEX(mMtx); - - mActiveTokens[token]= (msgIds.size()==1 && msgIds.begin()->second.size()==0) ?(TokenRequestType::ALL_POSTS):(TokenRequestType::POSTS); -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgInfo - bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list& grpIds ) - { - if(mTokenService.requestMsgInfo(token, 0, opts, grpIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::ALL_POSTS; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /// @see RsTokenService::requestMsgRelatedInfo - bool requestMsgRelatedInfo( - uint32_t& token, const RsTokReqOptions& opts, - const std::vector& msgIds ) - { - if( mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds)) - { - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::MSG_RELATED_INFO; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - else - return false; - } - - /** - * @jsonapi{development} - * @param[in] token - */ - RsTokenService::GxsRequestStatus requestStatus(uint32_t token) - { return mTokenService.requestStatus(token); } - - /// @see RsTokenService::requestServiceStatistic - bool requestServiceStatistic(uint32_t& token) - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_SERVICE_STATS; - - mTokenService.requestServiceStatistic(token,opts); - - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS; - -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - - /// @see RsTokenService::requestGroupStatistic - bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId) - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_STATS; - - mTokenService.requestGroupStatistic(token, grpId,opts); - - RS_STACK_MUTEX(mMtx); - mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS; -#ifdef DEBUG_GXSIFACEHELPER - locked_dumpTokens(); -#endif - return true; - } - - bool cancelActiveRequestTokens(TokenRequestType type) - { - RS_STACK_MUTEX(mMtx); - for(auto it = mActiveTokens.begin();it!=mActiveTokens.end();) - if(it->second == type) - { - mTokenService.cancelRequest(it->first); - it = mActiveTokens.erase(it); - } - else - ++it; - - return true; - } - - /// @see RsTokenService::cancelRequest - bool cancelRequest(uint32_t token) - { - { - RS_STACK_MUTEX(mMtx); - mActiveTokens.erase(token); - } - return mTokenService.cancelRequest(token); - } - - /** - * @deprecated - * Token service methods are already exposed by this helper, so you should - * not need to get token service pointer directly anymore. - */ - RS_DEPRECATED RsTokenService* getTokenService() { return &mTokenService; } - -protected: - /** - * Block caller while request is being processed. - * Useful for blocking API implementation. - * @param[in] token token associated to the request caller is waiting for - * @param[in] maxWait maximum waiting time in milliseconds - * @param[in] checkEvery time in millisecond between status checks - * @param[in] auto_delete_if_unsuccessful delete the request when it fails. This avoid leaving useless pending requests in the queue that would slow down additional calls. - */ - RsTokenService::GxsRequestStatus waitToken( - uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100), - bool auto_delete_if_unsuccessful=true) - { -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - auto wkStartime = std::chrono::steady_clock::now(); - int maxWorkAroundCnt = 10; -LLwaitTokenBeginLabel: -#endif - auto timeout = std::chrono::steady_clock::now() + maxWait; - auto st = requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) - && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) - cancelRequest(token); - -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - /* Work around for very slow/old android devices, we don't expect this - * to be necessary on newer devices. If it take unreasonably long - * something worser is already happening elsewere and we return anyway. - */ - if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE - && maxWorkAroundCnt-- > 0 ) - { - maxWait *= 10; - checkEvery *= 3; - Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " - << " workaround st: " << st - << " maxWorkAroundCnt: " << maxWorkAroundCnt - << " maxWait: " << maxWait.count() - << " checkEvery: " << checkEvery.count() << std::endl; - goto LLwaitTokenBeginLabel; - } - Dbg3() << __PRETTY_FUNCTION__ << " lasted: " - << std::chrono::duration_cast( - std::chrono::steady_clock::now() - wkStartime ).count() - << "ms" << std::endl; - -#endif - - { - RS_STACK_MUTEX(mMtx); - mActiveTokens.erase(token); - } - - return st; - } - -private: - RsGxsIface& mGxs; - RsTokenService& mTokenService; - RsMutex mMtx; - - std::map mActiveTokens; - -#ifdef DEBUG_GXSIFACEHELPER - void locked_dumpTokens() - { - const uint16_t service_id = mGxs.serviceType(); - const auto countSize = static_cast(TokenRequestType::__MAX); - uint32_t count[countSize] = {0}; - - RsDbg rsdbg; - rsdbg << __PRETTY_FUNCTION__ << " Service 0x" << std::hex << service_id - << " (" << rsServiceControl->getServiceName( - RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id) ) - << ") this=0x" << static_cast(this) - << ") Active tokens (per type): "; - - // let's count how many token of each type we've got. - for(auto& it: mActiveTokens) ++count[static_cast(it.second)]; - - for(uint32_t i=0; i < countSize; ++i) - rsdbg /* << i << ":" */ << count[i] << " "; - } -#endif // def DEBUG_GXSIFACEHELPER - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; diff --git a/libretroshare/src/retroshare/rsgxsifacetypes.h b/libretroshare/src/retroshare/rsgxsifacetypes.h deleted file mode 100644 index 0f78b3738..000000000 --- a/libretroshare/src/retroshare/rsgxsifacetypes.h +++ /dev/null @@ -1,309 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsifacetypes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2013 crispy * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSIFACETYPES_H_ -#define RSGXSIFACETYPES_H_ - -#include -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rsids.h" -#include "serialiser/rsserializable.h" -#include "serialiser/rstypeserializer.h" -#include "util/rstime.h" - -typedef std::map > GxsMsgIdResult; -typedef std::pair RsGxsGrpMsgIdPair; -typedef std::map > MsgRelatedIdResult; -typedef std::map > GxsMsgReq; - -struct RsMsgMetaData; - -typedef std::map > MsgMetaResult; - -enum class GxsRequestPriority { - VERY_HIGH = 0x00, - HIGH = 0x01, - NORMAL = 0x02, - LOW = 0x03, - VERY_LOW = 0x04, -}; - -class RsGxsGrpMetaData; -class RsGxsMsgMetaData; - -struct RsGroupMetaData : RsSerializable -{ - // (csoler) The correct default value to be used in mCircleType is GXS_CIRCLE_TYPE_PUBLIC, which is defined in rsgxscircles.h, - // but because of a loop in the includes, I cannot include it here. So I replaced with its current value 0x0001. - - RsGroupMetaData() : mGroupFlags(0), mSignFlags(0), mPublishTs(0), - mCircleType(0x0001), mAuthenFlags(0), mSubscribeFlags(0), mPop(0), - mVisibleMsgCount(0), mLastPost(0), mGroupStatus(0) {} - - virtual ~RsGroupMetaData() {} - - void operator =(const RsGxsGrpMetaData& rGxsMeta); - RsGroupMetaData(const RsGxsGrpMetaData& rGxsMeta) { operator=(rGxsMeta); } - - RsGxsGroupId mGroupId; - std::string mGroupName; - uint32_t mGroupFlags; // Combination of FLAG_PRIVACY_PRIVATE | FLAG_PRIVACY_RESTRICTED | FLAG_PRIVACY_PUBLIC: diffusion - uint32_t mSignFlags; // Combination of RSGXS_GROUP_SIGN_PUBLISH_MASK & RSGXS_GROUP_SIGN_AUTHOR_MASK, i.e. what signatures are required for parent and child msgs - - rstime_t mPublishTs; // Mandatory. - RsGxsId mAuthorId; // Author of the group. Left to "000....0" if anonymous - - // for circles - RsGxsCircleId mCircleId; // Id of the circle to which the group is restricted - uint32_t mCircleType; // combination of CIRCLE_TYPE_{ PUBLIC,EXTERNAL,YOUR_FRIENDS_ONLY,LOCAL,EXT_SELF,YOUR_EYES_ONLY } - - // other stuff. - uint32_t mAuthenFlags; // Actually not used yet. - RsGxsGroupId mParentGrpId; - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - - uint32_t mSubscribeFlags; - - uint32_t mPop; // Popularity = number of friend subscribers - uint32_t mVisibleMsgCount; // Max messages reported by friends - rstime_t mLastPost; // Timestamp for last message. Not used yet. - rstime_t mLastSeen; // Last time the group was advertised by friends. - - uint32_t mGroupStatus; - - /// Service Specific Free-Form local (non-synced) extra storage. - std::string mServiceString; - RsPeerId mOriginator; - RsGxsCircleId mInternalCircle; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mGroupId); - RS_SERIAL_PROCESS(mGroupName); - RS_SERIAL_PROCESS(mGroupFlags); - RS_SERIAL_PROCESS(mSignFlags); - RS_SERIAL_PROCESS(mPublishTs); - RS_SERIAL_PROCESS(mAuthorId); - RS_SERIAL_PROCESS(mCircleId); - RS_SERIAL_PROCESS(mCircleType); - RS_SERIAL_PROCESS(mAuthenFlags); - RS_SERIAL_PROCESS(mParentGrpId); - RS_SERIAL_PROCESS(mSubscribeFlags); - RS_SERIAL_PROCESS(mPop); - RS_SERIAL_PROCESS(mVisibleMsgCount); - RS_SERIAL_PROCESS(mLastPost); - RS_SERIAL_PROCESS(mGroupStatus); - RS_SERIAL_PROCESS(mServiceString); - RS_SERIAL_PROCESS(mOriginator); - RS_SERIAL_PROCESS(mInternalCircle); - } -}; - -// This is the parent class of all interface-level GXS group data. Derived classes -// will include service-specific information, such as icon, description, etc - -struct RsGxsGenericGroupData -{ - virtual ~RsGxsGenericGroupData() = default; // making the type polymorphic - - RsGroupMetaData mMeta; -}; - -struct RsMsgMetaData : RsSerializable -{ - RsMsgMetaData() : mPublishTs(0), mMsgFlags(0), mMsgStatus(0), mChildTs(0) {} - - virtual ~RsMsgMetaData() {} - - void operator =(const RsGxsMsgMetaData& rGxsMeta); - RsMsgMetaData(const RsGxsMsgMetaData& rGxsMeta) { operator=(rGxsMeta); } - - RsGxsGroupId mGroupId; - RsGxsMessageId mMsgId; - - RsGxsMessageId mThreadId; - RsGxsMessageId mParentId; - RsGxsMessageId mOrigMsgId; - - RsGxsId mAuthorId; - - std::string mMsgName; - rstime_t mPublishTs; - - /** the lower 16 bits for service, upper 16 bits for GXS - * @todo mixing service level flags and GXS level flag into the same member - * is prone to confusion, use separated members for those things, this could - * be done without breaking network retro-compatibility */ - uint32_t mMsgFlags; - - // BELOW HERE IS LOCAL DATA, THAT IS NOT FROM MSG. - // normally READ / UNREAD flags. LOCAL Data. - - /** the first 16 bits for service, last 16 for GXS - * @todo mixing service level flags and GXS level flag into the same member - * is prone to confusion, use separated members for those things, this could - * be done without breaking network retro-compatibility */ - uint32_t mMsgStatus; - - rstime_t mChildTs; - std::string mServiceString; // Service Specific Free-Form extra storage. - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mGroupId); - RS_SERIAL_PROCESS(mMsgId); - RS_SERIAL_PROCESS(mThreadId); - RS_SERIAL_PROCESS(mParentId); - RS_SERIAL_PROCESS(mOrigMsgId); - RS_SERIAL_PROCESS(mAuthorId); - RS_SERIAL_PROCESS(mMsgName); - RS_SERIAL_PROCESS(mPublishTs); - RS_SERIAL_PROCESS(mMsgFlags); - RS_SERIAL_PROCESS(mMsgStatus); - RS_SERIAL_PROCESS(mChildTs); - RS_SERIAL_PROCESS(mServiceString); - } -}; - -struct RsGxsGenericMsgData -{ - virtual ~RsGxsGenericMsgData() = default; // making the type polymorphic - - RsMsgMetaData mMeta; -}; - - -struct GxsGroupStatistic : RsSerializable -{ - GxsGroupStatistic() : - mNumMsgs(0), mTotalSizeOfMsgs(0), mNumThreadMsgsNew(0), - mNumThreadMsgsUnread(0), mNumChildMsgsNew(0), mNumChildMsgsUnread(0) {} - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mGrpId); - RS_SERIAL_PROCESS(mNumMsgs); - RS_SERIAL_PROCESS(mTotalSizeOfMsgs); - RS_SERIAL_PROCESS(mNumThreadMsgsNew); - RS_SERIAL_PROCESS(mNumThreadMsgsUnread); - RS_SERIAL_PROCESS(mNumChildMsgsNew); - RS_SERIAL_PROCESS(mNumChildMsgsUnread); - - } - - RsGxsGroupId mGrpId; - uint32_t mNumMsgs; /// number of message, from the database - uint32_t mTotalSizeOfMsgs; - uint32_t mNumThreadMsgsNew; - uint32_t mNumThreadMsgsUnread; - uint32_t mNumChildMsgsNew; - uint32_t mNumChildMsgsUnread; - - ~GxsGroupStatistic() override; -}; - -struct GxsServiceStatistic : RsSerializable -{ - GxsServiceStatistic() : - mNumMsgs(0), mNumGrps(0), mSizeOfMsgs(0), mSizeOfGrps(0), - mNumGrpsSubscribed(0), mNumThreadMsgsNew(0), mNumThreadMsgsUnread(0), - mNumChildMsgsNew(0), mNumChildMsgsUnread(0), mSizeStore(0) {} - - uint32_t mNumMsgs; - uint32_t mNumGrps; - uint32_t mSizeOfMsgs; - uint32_t mSizeOfGrps; - uint32_t mNumGrpsSubscribed; - uint32_t mNumThreadMsgsNew; - uint32_t mNumThreadMsgsUnread; - uint32_t mNumChildMsgsNew; - uint32_t mNumChildMsgsUnread; - uint32_t mSizeStore; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mNumMsgs); - RS_SERIAL_PROCESS(mNumGrps); - RS_SERIAL_PROCESS(mSizeOfMsgs); - RS_SERIAL_PROCESS(mSizeOfGrps); - RS_SERIAL_PROCESS(mNumGrpsSubscribed); - RS_SERIAL_PROCESS(mNumThreadMsgsNew); - RS_SERIAL_PROCESS(mNumThreadMsgsUnread); - RS_SERIAL_PROCESS(mNumChildMsgsNew); - RS_SERIAL_PROCESS(mNumChildMsgsUnread); - RS_SERIAL_PROCESS(mSizeStore); - } - - ~GxsServiceStatistic() override; -}; - -class RS_DEPRECATED RsGxsGroupUpdateMeta -{ -public: - - // expand as support is added for other utypes - enum UpdateType { DESCRIPTION, NAME }; - - explicit RsGxsGroupUpdateMeta(const RsGxsGroupId& groupId): - mGroupId(groupId) {} - - typedef std::map GxsMetaUpdate; - - /*! - * Only one item of a utype can exist - * @param utype the type of meta update - * @param item update item containing the change value - */ - void setMetaUpdate(UpdateType utype, const std::string& update) - { - mUpdates[utype] = update; - } - - /*! - * @param utype update type to remove - * @return false if update did not exist, true if update successfully removed - */ - bool removeUpdateType(UpdateType utype){ return mUpdates.erase(utype) == 1; } - - const GxsMetaUpdate* getUpdates() const { return &mUpdates; } - const RsGxsGroupId& getGroupId() const { return mGroupId; } - -private: - - GxsMetaUpdate mUpdates; - RsGxsGroupId mGroupId; -}; - -#endif /* RSGXSIFACETYPES_H_ */ diff --git a/libretroshare/src/retroshare/rsgxsservice.h b/libretroshare/src/retroshare/rsgxsservice.h deleted file mode 100644 index 152b018c9..000000000 --- a/libretroshare/src/retroshare/rsgxsservice.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxsservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSSERVICE_H -#define RSGXSSERVICE_H - - -#include "retroshare/rsgxsifacetypes.h" -#include "retroshare/rstokenservice.h" - -struct RsMsgMetaData ; -typedef uint32_t TurtleRequestId; - -typedef std::map > GxsMsgMetaMap; -typedef std::map > GxsMsgRelatedMetaMap; - - - -#endif // RSGXSSERVICE_H diff --git a/libretroshare/src/retroshare/rsgxstrans.h b/libretroshare/src/retroshare/rsgxstrans.h deleted file mode 100644 index 8cbb514a6..000000000 --- a/libretroshare/src/retroshare/rsgxstrans.h +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxstrans.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License version 3 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsgxscommon.h" -#include "rsitems/rsserviceids.h" - -/** Subservices identifiers (like port for TCP) - * @deprecated pay special attention fixing this as it may break - * retro-compatibility */ -enum class RS_DEPRECATED_FOR(RsServiceType) GxsTransSubServices : uint16_t -{ - UNKNOWN = 0x00, - TEST_SERVICE = 0x01, - P3_MSG_SERVICE = 0x02, - P3_CHAT_SERVICE = 0x03 -}; - -/// Values must fit into uint8_t -enum class GxsTransItemsSubtypes : uint8_t -{ - GXS_TRANS_SUBTYPE_MAIL = 0x01, - GXS_TRANS_SUBTYPE_RECEIPT = 0x02, - GXS_TRANS_SUBTYPE_GROUP = 0x03, - OUTGOING_RECORD_ITEM_deprecated = 0x04, - OUTGOING_RECORD_ITEM = 0x05 -}; - -enum class GxsTransSendStatus : uint8_t -{ - UNKNOWN = 0x00, - PENDING_PROCESSING = 0x01, - PENDING_PREFERRED_GROUP = 0x02, - PENDING_RECEIPT_CREATE = 0x03, - PENDING_RECEIPT_SIGNATURE = 0x04, - PENDING_SERIALIZATION = 0x05, - PENDING_PAYLOAD_CREATE = 0x06, - PENDING_PAYLOAD_ENCRYPT = 0x07, - PENDING_PUBLISH = 0x08, - /** This will be useful so the user can know if the mail reached at least - * some friend node, in case of internet connection interruption */ - //PENDING_TRANSFER, - PENDING_RECEIPT_RECEIVE = 0x09, - /// Records with status >= RECEIPT_RECEIVED get deleted - RECEIPT_RECEIVED = 0x0a, - FAILED_RECEIPT_SIGNATURE = 0xf0, - FAILED_ENCRYPTION = 0xf1, - FAILED_TIMED_OUT = 0xf2 -}; - -typedef uint64_t RsGxsTransId; - -class RsGxsTransGroup: public RsGxsGenericGroupData -{ -}; - -class RsGxsTransMsg -{ -public: - RsGxsTransMsg() : size(0),data(NULL) {} - virtual ~RsGxsTransMsg() { free(data) ; } - -public: - RsMsgMetaData mMeta; - - uint32_t size ; - uint8_t *data ; -}; - -struct RsGxsTransOutgoingRecord -{ - GxsTransSendStatus status; - RsGxsId recipient; - RsGxsTransId trans_id; - - GxsTransSubServices client_service; - - uint32_t data_size ; - Sha1CheckSum data_hash ; - uint32_t send_TS ; - RsGxsGroupId group_id ; -}; - -class RsGxsTransGroupStatistics: public GxsGroupStatistic -{ -public: - RsGxsTransGroupStatistics() - { - last_publish_TS = 0; - popularity = 0; - subscribed = false; - } - - void addMessageMeta(const RsGxsGroupId& grp,const RsMsgMetaData& meta) - { - messages_metas[meta.mMsgId] = meta ; - last_publish_TS = std::max(last_publish_TS,meta.mPublishTs) ; - mGrpId = grp ; - } - - bool subscribed ; - int popularity ; - - rstime_t last_publish_TS; - - std::map messages_metas ; -}; - - -/// RetroShare GxsTrans asyncronous redundant small mail trasport on top of GXS -/// -class RsGxsTrans: public RsGxsIfaceHelper -{ -public: - class GxsTransStatistics - { - public: - GxsTransStatistics() {} - - RsGxsGroupId prefered_group_id ; - std::vector outgoing_records; - }; - - RsGxsTrans(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - - virtual ~RsGxsTrans() {} - - virtual bool getDataStatistics(GxsTransStatistics& stats)=0; - virtual bool getGroupStatistics(std::map& stats) =0; -}; - -extern RsGxsTrans *rsGxsTrans ; diff --git a/libretroshare/src/retroshare/rsgxstunnel.h b/libretroshare/src/retroshare/rsgxstunnel.h deleted file mode 100644 index 125a7c9a9..000000000 --- a/libretroshare/src/retroshare/rsgxstunnel.h +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsgxstunnel.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "util/rsdir.h" -#include "retroshare/rsids.h" -#include "retroshare/rsturtle.h" -#include "retroshare/rsgxsifacetypes.h" - -class RsGxsTunnelService -{ -public: - enum { - RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000, - RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001 - }; - - enum { - RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00, - RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x01, - RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x02, - RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03 - }; - - class RsGxsTunnelClientService - { - public: - // The client should derive this in order to handle notifications from the tunnel service. - // This cannot be ignored because the client needs to know when the tunnel is active. - - virtual void notifyTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) =0; - - // Data obtained from the corresponding GXS id. The memory ownership is transferred to the client, which - // is responsible to free it using free() once used. - - virtual void receiveData(const RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) =0; - - // Used by the creator of the service to supply a pointer to the GXS tunnel service for it to be able to send data etc. - - virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) =0; - - // Gives feedback about type of data that is allowed in. For security reasons, this always needs to be re-derived (Clients can return true on default) - - virtual bool acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTunnelId& tunnel_id,bool am_I_client_side) = 0 ; - }; - - class GxsTunnelInfo - { - public: - // Tunnel information - - RsGxsTunnelId tunnel_id ; - RsGxsId destination_gxs_id ; // GXS Id we're talking to - RsGxsId source_gxs_id ; // GXS Id we're using to talk - uint32_t tunnel_status ; // active, requested, DH pending, etc. - uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management). - uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management). - bool is_client_side ; // specifiec wether we are client(managing the tunnel) or server. - - // Data packets - - uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. Should be 0 unless something bad happens. - uint32_t total_data_packets_sent ; // total number of data packets sent (does not include tunnel management) - uint32_t total_data_packets_received ; // total number of data packets received (does not include tunnel management) - }; - - // This is the interface file for the secured tunnel service - // - //===================================================// - // Debugging info // - //===================================================// - - virtual bool getTunnelsInfo(std::vector& infos) =0; - virtual bool getTunnelInfo(const RsGxsTunnelId& tunnel_id,GxsTunnelInfo& info) =0; - - // retrieve the routing probabilities - - //===================================================// - // Communication to other services. // - //===================================================// - - // Register a new client service. The service ID needs to be unique, and it's the coder's resonsibility to use an ID that is not used elsewhere - // for the same purpose. - - virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) =0; - - // Asks for a tunnel. The service will request it to turtle router, and exchange a AES key using DH. - // When the tunnel is secured, the client---here supplied as argument---will be notified. He can - // then send data into the tunnel. The same tunnel may be used by different clients. - // The service id is passed on so that the client is notified when the tunnel is up. - - virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t service_id,uint32_t& error_code) =0 ; - - // Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged. If the tunnel does not exist, the item is rejected and - // an error is issued. In any case, the memory ownership of the data is *not* transferred to the tunnel service, so the client should delete it afterwards, if needed. - - virtual bool sendData(const RsGxsTunnelId& tunnel_id, uint32_t client_service_id, const uint8_t *data, uint32_t data_size) =0; - - // Removes any established tunnel to this GXS id. This makes the tunnel refuse further data, but the tunnel will be however kept alive - // until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed. - - virtual bool closeExistingTunnel(const RsGxsTunnelId& to_id,uint32_t service_id) =0; - - //===================================================// - // Routage feedback from other services // - //===================================================// - -}; - -// To access the GRouter from anywhere -// -extern RsGxsTunnelService *rsGxsTunnel ; diff --git a/libretroshare/src/retroshare/rshistory.h b/libretroshare/src/retroshare/rshistory.h deleted file mode 100644 index f8eb7ecaa..000000000 --- a/libretroshare/src/retroshare/rshistory.h +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rshistory.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Thunder * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_HISTORY_INTERFACE_H -#define RS_HISTORY_INTERFACE_H - -class RsHistory; -class ChatId; - -extern RsHistory *rsHistory; - -#include -#include -#include -#include "retroshare/rstypes.h" - -//! data object for message history -/*! - * data object used for message history - */ -static const uint32_t RS_HISTORY_TYPE_PUBLIC = 0 ; -static const uint32_t RS_HISTORY_TYPE_PRIVATE = 1 ; -static const uint32_t RS_HISTORY_TYPE_LOBBY = 2 ; -static const uint32_t RS_HISTORY_TYPE_DISTANT = 3 ; - -class HistoryMsg -{ -public: - HistoryMsg() - { - msgId = 0; - incoming = false; - sendTime = 0; - recvTime = 0; - } - -public: - uint32_t msgId; - RsPeerId chatPeerId; - bool incoming; - RsPeerId peerId; - std::string peerName; - uint32_t sendTime; - uint32_t recvTime; - std::string message; -}; - -//! Interface to retroshare for message history -/*! - * Provides an interface for retroshare's message history functionality - */ -class RsHistory -{ -public: - virtual bool chatIdToVirtualPeerId(const ChatId &chat_id, RsPeerId &peer_id) = 0; - virtual bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount) = 0; - virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0; - virtual void removeMessages(const std::list &msgIds) = 0; - virtual void clear(const ChatId &chatPeerId) = 0; - - virtual bool getEnable(uint32_t chat_type) = 0; - virtual void setEnable(uint32_t chat_type, bool enable) = 0; - - virtual uint32_t getMaxStorageDuration() = 0; - virtual void setMaxStorageDuration(uint32_t seconds) = 0; - - // 0 = no limit, >0 count of saved messages - virtual uint32_t getSaveCount(uint32_t chat_type) = 0; - virtual void setSaveCount(uint32_t chat_type, uint32_t count) = 0; -}; - -#endif diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h deleted file mode 100644 index 0c8c364e3..000000000 --- a/libretroshare/src/retroshare/rsidentity.h +++ /dev/null @@ -1,653 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsidentity.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsreputations.h" -#include "retroshare/rsids.h" -#include "serialiser/rstlvimage.h" -#include "retroshare/rsgxscommon.h" -#include "serialiser/rsserializable.h" -#include "serialiser/rstypeserializer.h" -#include "util/rsdeprecate.h" - -class RsIdentity; - -/** - * Pointer to global instance of RsIdentity service implementation - * @jsonapi{development} - */ -extern RsIdentity* rsIdentity; - - -// GroupFlags: Only one so far: - -// The deprecated flag overlaps the privacy flags for mGroupFlags. This is an error that should be fixed. For the sake of keeping some -// backward compatibility, we need to make the change step by step. - -#define RSGXSID_GROUPFLAG_REALID_kept_for_compatibility 0x0001 -#define RSGXSID_GROUPFLAG_REALID 0x0100 - -// THESE ARE FLAGS FOR INTERFACE. -#define RSID_TYPE_MASK 0xff00 -#define RSID_RELATION_MASK 0x00ff - -#define RSID_TYPE_REALID 0x0100 -#define RSID_TYPE_PSEUDONYM 0x0200 - -#define RSID_RELATION_YOURSELF 0x0001 -#define RSID_RELATION_FRIEND 0x0002 -#define RSID_RELATION_FOF 0x0004 -#define RSID_RELATION_OTHER 0x0008 -#define RSID_RELATION_UNKNOWN 0x0010 - -/// @deprecated remove toghether with RsGxsIdGroup::mRecognTags -#define RSRECOGN_MAX_TAGINFO 5 - -// Unicode symbols. NOT utf-8 bytes, because of multi byte characters -#define RSID_MAXIMUM_NICKNAME_SIZE 30 -#define RSID_MINIMUM_NICKNAME_SIZE 2 - -std::string rsIdTypeToString(uint32_t idtype); - -static const uint32_t RS_IDENTITY_FLAGS_IS_A_CONTACT = 0x0001; -static const uint32_t RS_IDENTITY_FLAGS_PGP_LINKED = 0x0002; -static const uint32_t RS_IDENTITY_FLAGS_PGP_KNOWN = 0x0004; -static const uint32_t RS_IDENTITY_FLAGS_IS_OWN_ID = 0x0008; -static const uint32_t RS_IDENTITY_FLAGS_IS_DEPRECATED= 0x0010; // used to denote keys with deprecated fingerprint format. - -struct GxsReputation : RsSerializable -{ - GxsReputation(); - - bool updateIdScore(bool pgpLinked, bool pgpKnown); - bool update(); /// checks ranges and calculates overall score. - - int32_t mOverallScore; - int32_t mIdScore; /// PGP, Known, etc. - int32_t mOwnOpinion; - int32_t mPeerOpinion; - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mOverallScore); - RS_SERIAL_PROCESS(mIdScore); - RS_SERIAL_PROCESS(mOwnOpinion); - RS_SERIAL_PROCESS(mPeerOpinion); - } - - ~GxsReputation() override; -}; - - -struct RsGxsIdGroup : RsSerializable -{ - RsGxsIdGroup() : - mLastUsageTS(0), mPgpKnown(false), mIsAContact(false) {} - - RsGroupMetaData mMeta; - - // In GroupMetaData. - //std::string mNickname; (mGroupName) - //std::string mKeyId; (mGroupId) - //uint32_t mIdType; (mGroupFlags) - - // SHA(KeyId + Gpg Fingerprint) -> can only be IDed if GPG known. - // The length of the input must be long enough to make brute force search implausible. - - // Easy to do 1e9 SHA-1 hash computations per second on a GPU. - // We will need a minimum of 256 bits, ideally 1024 bits or 2048 bits. - - // Actually PgpIdHash is SHA1(.mMeta.mGroupId + PGPHandler->GpgFingerprint(ownId)) - // ??? 160 bits. - - Sha1CheckSum mPgpIdHash; - // Need a signature as proof - otherwise anyone could add others Hashes. - // This is a string, as the length is variable. - std::string mPgpIdSign; - - // Recognition Strings. MAX# defined above. - RS_DEPRECATED std::list mRecognTags; - - // Avatar - RsGxsImage mImage ; - rstime_t mLastUsageTS ; - - // Not Serialised - for GUI's benefit. - bool mPgpLinked; - bool mPgpKnown; - bool mIsAContact; // change that into flags one day - RsPgpId mPgpId; - GxsReputation mReputation; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - ~RsGxsIdGroup() override; -}; - -// DATA TYPE FOR EXTERNAL INTERFACE. - -struct RS_DEPRECATED RsRecognTag -{ - RsRecognTag(uint16_t tc, uint16_t tt, bool v) : - tag_class(tc), tag_type(tt), valid(v) {} - - uint16_t tag_class; - uint16_t tag_type; - bool valid; -}; - - -struct RS_DEPRECATED RsRecognTagDetails -{ - RsRecognTagDetails() : - valid_from(0), valid_to(0), tag_class(0), tag_type(0), is_valid(false), - is_pending(false) {} - - rstime_t valid_from; - rstime_t valid_to; - uint16_t tag_class; - uint16_t tag_type; - - std::string signer; - - bool is_valid; - bool is_pending; -}; - - -struct RsIdentityParameters -{ - RsIdentityParameters() : - isPgpLinked(false) {} - - bool isPgpLinked; - std::string nickname; - RsGxsImage mImage; -}; - -struct RsIdentityUsage : RsSerializable -{ - enum UsageCode : uint8_t - { - UNKNOWN_USAGE = 0x00, - - /** These 2 are normally not normal GXS identities, but nothing prevents - * it to happen either. */ - GROUP_ADMIN_SIGNATURE_CREATION = 0x01, - GROUP_ADMIN_SIGNATURE_VALIDATION = 0x02, - - /** Not typically used, since most services do not require group author - * signatures */ - GROUP_AUTHOR_SIGNATURE_CREATION = 0x03, - GROUP_AUTHOR_SIGNATURE_VALIDATION = 0x04, - - /// most common use case. Messages are signed by authors in e.g. forums. - MESSAGE_AUTHOR_SIGNATURE_CREATION = 0x05, - MESSAGE_AUTHOR_SIGNATURE_VALIDATION = 0x06, - - /** Identities are stamped regularly by crawlign the set of messages for - * all groups. That helps keepign the useful identities in hand. */ - GROUP_AUTHOR_KEEP_ALIVE = 0x07, - MESSAGE_AUTHOR_KEEP_ALIVE = 0x08, - - /** Chat lobby msgs are signed, so each time one comes, or a chat lobby - * event comes, a signature verificaiton happens. */ - CHAT_LOBBY_MSG_VALIDATION = 0x09, - - /// Global router message validation - GLOBAL_ROUTER_SIGNATURE_CHECK = 0x0a, - - /// Global router message signature - GLOBAL_ROUTER_SIGNATURE_CREATION = 0x0b, - - GXS_TUNNEL_DH_SIGNATURE_CHECK = 0x0c, - GXS_TUNNEL_DH_SIGNATURE_CREATION = 0x0d, - - /// Identity received through GXS sync - IDENTITY_NEW_FROM_GXS_SYNC = 0x0e, - /// Group update on that identity data. Can be avatar, name, etc. - IDENTITY_NEW_FROM_DISCOVERY = 0x0f, - /// Explicit request to friend - IDENTITY_NEW_FROM_EXPLICIT_REQUEST = 0x10, - - /// Any signature verified for that identity - IDENTITY_GENERIC_SIGNATURE_CHECK = 0x11, - - /// Any signature made by that identity - IDENTITY_GENERIC_SIGNATURE_CREATION = 0x12, - - IDENTITY_GENERIC_ENCRYPTION = 0x13, - IDENTITY_GENERIC_DECRYPTION = 0x14, - CIRCLE_MEMBERSHIP_CHECK = 0x15 - } ; - - RsIdentityUsage( RsServiceType service, - RsIdentityUsage::UsageCode code, - const RsGxsGroupId& gid = RsGxsGroupId(), - const RsGxsMessageId& message_id = RsGxsMessageId(), - const RsGxsMessageId& parent_id = RsGxsMessageId(), - const RsGxsMessageId& thread_id = RsGxsMessageId(), - uint64_t additional_id=0, - const std::string& comment = std::string() ); - - /// Id of the service using that identity, as understood by rsServiceControl - RsServiceType mServiceId; - - /** Specific code to use. Will allow forming the correct translated message - * in the GUI if necessary. */ - UsageCode mUsageCode; - - /// Group ID using the identity - RsGxsGroupId mGrpId; - - /// Message ID using the identity - RsGxsMessageId mMsgId; - - /// Reference message ID. Useful for votes/comments - RsGxsMessageId mParentId; - - /// Reference message ID. Useful for votes/comments - RsGxsMessageId mThreadId; - - /// Some additional ID. Can be used for e.g. chat lobbies. - uint64_t mAdditionalId; - - /// additional comment to be used mainly for debugging, but not GUI display - std::string mComment; - - bool operator<(const RsIdentityUsage& u) const { return mHash < u.mHash; } - RsFileHash mHash; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mServiceId); - RS_SERIAL_PROCESS(mUsageCode); - RS_SERIAL_PROCESS(mGrpId); - RS_SERIAL_PROCESS(mMsgId); - RS_SERIAL_PROCESS(mAdditionalId); - RS_SERIAL_PROCESS(mComment); - RS_SERIAL_PROCESS(mHash); - } - - friend struct RsTypeSerializer; -private: - /** Accessible only to friend class RsTypeSerializer needed for - * deserialization */ - RsIdentityUsage(); -}; - -enum class RsGxsIdentityEventCode: uint8_t -{ - UNKNOWN = 0x00, - NEW_IDENTITY = 0x01, - DELETED_IDENTITY = 0x02, - UPDATED_IDENTITY = 0x03, -}; - -struct RsGxsIdentityEvent: public RsEvent -{ - RsGxsIdentityEvent() - : RsEvent(RsEventType::GXS_IDENTITY), - mIdentityEventCode(RsGxsIdentityEventCode::UNKNOWN) {} - - RsGxsIdentityEventCode mIdentityEventCode; - RsGxsGroupId mIdentityId; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mIdentityEventCode); - RS_SERIAL_PROCESS(mIdentityId); - } - - ~RsGxsIdentityEvent() override = default; -}; - -struct RsIdentityDetails : RsSerializable -{ - RsIdentityDetails() : mFlags(0), mLastUsageTS(0) {} - - RsGxsId mId; - - std::string mNickname; - - uint32_t mFlags; - - RsPgpId mPgpId; - - /// @deprecated Recogn details. - RS_DEPRECATED std::list mRecognTags; - - /** 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. - */ - RsReputationInfo mReputation; - - RsGxsImage mAvatar; - - rstime_t mPublishTS; - rstime_t mLastUsageTS; - - std::map mUseCases; - - /// @see RsSerializable - virtual void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mId); - RS_SERIAL_PROCESS(mNickname); - RS_SERIAL_PROCESS(mFlags); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mReputation); - RS_SERIAL_PROCESS(mAvatar); - RS_SERIAL_PROCESS(mPublishTS); - RS_SERIAL_PROCESS(mLastUsageTS); - RS_SERIAL_PROCESS(mUseCases); - } - - ~RsIdentityDetails() override; -}; - - - -/** The Main Interface Class for GXS people identities */ -class RsIdentity: public RsGxsIfaceHelper -{ -public: - explicit RsIdentity(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - - /** - * @brief Create a new identity - * @jsonapi{development} - * @param[out] id storage for the created identity Id - * @param[in] name Name of the identity - * @param[in] avatar Image associated to the identity - * @param[in] pseudonimous true for unsigned identity, false otherwise - * @param[in] pgpPassword password to unlock PGP to sign identity, - * not implemented yet - * @return false on error, true otherwise - */ - virtual bool createIdentity( - RsGxsId& id, - const std::string& name, const RsGxsImage& avatar = RsGxsImage(), - bool pseudonimous = true, const std::string& pgpPassword = "" ) = 0; - - /** - * @brief Locally delete given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @return false on error, true otherwise - */ - virtual bool deleteIdentity(RsGxsId& id) = 0; - - /** - * @brief Update identity data (name, avatar...) - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[in] name New name of the identity - * @param[in] avatar New avatar for the identity - * @param[in] pseudonimous Set to true to make the identity anonymous. If set to false, updating will require the profile passphrase. - * @param[in] pgpPassword Profile passphrase, if non pseudonymous. - * @return false on error, true otherwise - */ - virtual bool updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) =0; - - /** - * @brief Get identity details, from the cache - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[out] details Storage for the identity details - * @return false on error, true otherwise - */ - virtual bool getIdDetails(const RsGxsId& id, RsIdentityDetails& details) = 0; - - /** - * @brief Get last seen usage time of given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @return timestamp of last seen usage - */ - virtual rstime_t getLastUsageTS(const RsGxsId& id) = 0; - - /** - * @brief Get own signed ids - * @jsonapi{development} - * @param[out] ids storage for the ids - * @return false on error, true otherwise - */ - virtual bool getOwnSignedIds(std::vector& ids) = 0; - - /** - * @brief Get own pseudonimous (unsigned) ids - * @jsonapi{development} - * @param[out] ids storage for the ids - * @return false on error, true otherwise - */ - virtual bool getOwnPseudonimousIds(std::vector& ids) = 0; - - /** - * @brief Check if an id is known - * @jsonapi{development} - * @param[in] id Id to check - * @return true if the id is known, false otherwise - */ - virtual bool isKnownId(const RsGxsId& id) = 0; - - /** - * @brief Check if an id is own - * @jsonapi{development} - * @param[in] id Id to check - * @return true if the id is own, false otherwise - */ - virtual bool isOwnId(const RsGxsId& id) = 0; - - /** - * @brief Get identities summaries list. - * @jsonapi{development} - * @param[out] ids list where to store the identities - * @return false if something failed, true otherwhise - */ - virtual bool getIdentitiesSummaries(std::list& ids) = 0; - - /** - * @brief Get identities information (name, avatar...). - * Blocking API. - * @jsonapi{development} - * @param[in] ids ids of the channels of which to get the informations - * @param[out] idsInfo storage for the identities informations - * @return false if something failed, true otherwhise - */ - virtual bool getIdentitiesInfo( - const std::set& ids, - std::vector& idsInfo ) = 0; - - /** - * @brief Check if an identity is contact - * @jsonapi{development} - * @param[in] id Id of the identity - * @return true if it is a conctact, false otherwise - */ - virtual bool isARegularContact(const RsGxsId& id) = 0; - - /** - * @brief Set/unset identity as contact - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[in] isContact true to set, false to unset - * @return false on error, true otherwise - */ - virtual bool setAsRegularContact(const RsGxsId& id, bool isContact) = 0; - - /** - * @brief Toggle automatic flagging signed by friends identity as contact - * @jsonapi{development} - * @param[in] enabled true to enable, false to disable - */ - virtual void setAutoAddFriendIdsAsContact(bool enabled) = 0; - - /** - * @brief Check if automatic signed by friend identity contact flagging is - * enabled - * @jsonapi{development} - * @return true if enabled, false otherwise - */ - virtual bool autoAddFriendIdsAsContact() = 0; - - /** - * @brief Get number of days after which delete a banned identities - * @jsonapi{development} - * @return number of days - */ - virtual uint32_t deleteBannedNodesThreshold() = 0; - - /** - * @brief Set number of days after which delete a banned identities - * @jsonapi{development} - * @param[in] days number of days - */ - virtual void setDeleteBannedNodesThreshold(uint32_t days) = 0; - - /** - * @brief request details of a not yet known identity to the network - * @jsonapi{development} - * @param[in] id id of the identity to request - * @param[in] peers optional list of the peers to ask for the key, if empty - * all online peers are asked. - * @return false on error, true otherwise - */ - virtual bool requestIdentity( - const RsGxsId& id, - const std::vector& peers = std::vector() ) = 0; - - /// default base URL used for indentity links @see exportIdentityLink - static const std::string DEFAULT_IDENTITY_BASE_URL; - - /// Link query field used to store indentity name @see exportIdentityLink - static const std::string IDENTITY_URL_NAME_FIELD; - - /// Link query field used to store indentity id @see exportIdentityLink - static const std::string IDENTITY_URL_ID_FIELD; - - /// Link query field used to store indentity data @see exportIdentityLink - static const std::string IDENTITY_URL_DATA_FIELD; - - /** - * @brief Get link to a identity - * @jsonapi{development} - * @param[out] link storage for the generated link - * @param[in] id Id of the identity of which you want to generate a link - * @param[in] includeGxsData if true include the identity GXS group data so - * the receiver can make use of the identity even if she hasn't received it - * through GXS yet - * @param[in] baseUrl URL into which to sneak in the RetroShare link - * radix, this is primarly useful to induce applications into making the - * link clickable, or to disguise the RetroShare link into a - * "normal" looking web link. If empty the GXS data link will be outputted - * in plain base64 format. - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if something failed, true otherwhise - */ - virtual bool exportIdentityLink( - std::string& link, const RsGxsId& id, - bool includeGxsData = true, - const std::string& baseUrl = RsIdentity::DEFAULT_IDENTITY_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief Import identity from full link - * @param[in] link identity link either in radix or link format - * @param[out] id optional storage for parsed identity - * @param[out] errMsg optional storage for error message, meaningful only in - * case of failure - * @return false if some error occurred, true otherwise - */ - virtual bool importIdentityLink( - const std::string& link, - RsGxsId& id = RS_DEFAULT_STORAGE_PARAM(RsGxsId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - RS_DEPRECATED_FOR(exportIdentityLink) - virtual bool getGroupSerializedData( - const uint32_t& token, - std::map& serialized_groups ) = 0; - - RS_DEPRECATED - virtual bool parseRecognTag( - const RsGxsId &id, const std::string& nickname, - const std::string& tag, RsRecognTagDetails& details) = 0; - - RS_DEPRECATED - virtual bool getRecognTagRequest( - const RsGxsId& id, const std::string& comment, uint16_t tag_class, - uint16_t tag_type, std::string& tag) = 0; - - RS_DEPRECATED - virtual uint32_t nbRegularContacts() =0; - - RS_DEPRECATED_FOR(exportIdentityLink) - virtual bool serialiseIdentityToMemory( const RsGxsId& id, - std::string& radix_string ) = 0; - RS_DEPRECATED_FOR(importIdentityLink) - virtual bool deserialiseIdentityFromMemory( const std::string& radix_string, - RsGxsId* id = nullptr ) = 0; - - /// Fills up list of all own ids. Returns false if ids are not yet loaded. - RS_DEPRECATED_FOR("getOwnSignedIds getOwnPseudonimousIds") - virtual bool getOwnIds( std::list &ownIds, - bool only_signed_ids = false ) = 0; - - RS_DEPRECATED - virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) = 0; - - RS_DEPRECATED_FOR(RsReputations) - virtual bool submitOpinion(uint32_t& token, const RsGxsId &id, - bool absOpinion, int score) = 0; - - RS_DEPRECATED - virtual bool deleteIdentity(uint32_t& token, RsGxsIdGroup &group) = 0; - - RS_DEPRECATED_FOR("getIdentitiesSummaries getIdentitiesInfo") - virtual bool getGroupData( const uint32_t& token, - std::vector& groups) = 0; - - virtual ~RsIdentity(); -}; diff --git a/libretroshare/src/retroshare/rsids.h b/libretroshare/src/retroshare/rsids.h deleted file mode 100644 index d38ee4518..000000000 --- a/libretroshare/src/retroshare/rsids.h +++ /dev/null @@ -1,339 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsids.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2013 Cyril Soler * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util/rsdebug.h" -#include "util/rsrandom.h" -#include "util/stacktrace.h" - -/** - * RsGenericIdType values might be random, but must be different, in order to - * make the various IDs incompatible with each other. - */ -enum class RsGenericIdType -{ - SSL, - PGP_ID, - SHA1, - PGP_FINGERPRINT, - GXS_GROUP, - GXS_ID, - GXS_MSG, - GXS_CIRCLE, - GROUTER, - GXS_TUNNEL, - DISTANT_CHAT, - NODE_GROUP, - SHA256, - BIAS_20_BYTES -}; - -/** - * This class aims at defining a generic ID type that is a list of bytes. It - * can be converted into a hexadecial string for printing, mainly) or for - * compatibility with old methods. - * - * To use this class, derive your own ID type from it. - * @see RsPpgFingerprint as an example. - * - * Take care to define and use a different @see RsGenericIdType for each ne type - * of ID you create, to avoid implicit conversion between subtypes, and - * therefore accidental ID mixup is impossible. - * - * ID Types with different lengths are not convertible even using explicit - * constructor and compilation would fail if that is attempted. - * - * Warning: never store references to a t_RsGenericIdType accross threads, since - * the cached string convertion is not thread safe. - */ -template -struct t_RsGenericIdType -{ - using Id_t = t_RsGenericIdType; - using std_list = std::list; - using std_vector = std::vector; - using std_set = std::set; - - /// by default, ids are set to null() - t_RsGenericIdType() { memset(bytes, 0, ID_SIZE_IN_BYTES); } - - /// Explicit constructor from a hexadecimal string - explicit t_RsGenericIdType(const std::string& hex_string); - - /** - * @brief Construct from a buffer of at least the size of SIZE_IN_BYTES - * This is dangerous if used without being absolutely sure of buffer size, - * nothing prevent a buffer of wrong size being passed at runtime! - * @param[in] buff pointer to the buffer - * @return empty id on failure, an id initialized from the bytes in the - * buffer - */ - static Id_t fromBufferUnsafe(const uint8_t* buff) - { - Id_t ret; - - if(!buff) - { - RsErr() << __PRETTY_FUNCTION__ << " invalid paramethers buff: " - << buff << std::endl; - print_stacktrace(); - return ret; - } - - memmove(ret.bytes, buff, SIZE_IN_BYTES); - return ret; - } - - /** - * Explicit constructor from a different type but with same size. - * - * This is used for conversions such as - * GroupId -> CircleId - * GroupId -> GxsId - */ - template - explicit t_RsGenericIdType( - const t_RsGenericIdType& - id ) - { memmove(bytes, id.toByteArray(), ID_SIZE_IN_BYTES); } - - /// Random initialization. Can be useful for testing and to generate new ids. - static Id_t random() - { - Id_t id; - RsRandom::random_bytes(id.bytes, ID_SIZE_IN_BYTES); - return id; - } - - inline void clear() { memset(bytes, 0, SIZE_IN_BYTES); } - - /// Converts to a std::string using cached value. - const uint8_t* toByteArray() const { return &bytes[0]; } - - static constexpr uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES; - - inline bool operator==(const Id_t& fp) const - { return !memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); } - - inline bool operator!=(const Id_t& fp) const - { return !!memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); } - - inline bool operator< (const Id_t& fp) const - { return (memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES) < 0); } - - inline Id_t operator~ () const - { - Id_t ret; - for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i) - ret.bytes[i] = ~bytes[i]; - return ret; - } - - inline Id_t operator| (const Id_t& fp) const - { - Id_t ret; - for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i) - ret.bytes[i] = bytes[i] | fp.bytes[i]; - return ret; - } - - inline bool isNull() const - { - for(uint32_t i=0; i < SIZE_IN_BYTES; ++i) - if(bytes[i] != 0) return false; - return true; - } - - friend std::ostream& operator<<(std::ostream& out, const Id_t& id) - { - switch (UNIQUE_IDENTIFIER) - { - case RsGenericIdType::PGP_FINGERPRINT: - { - uint8_t index = 0; - for(char c : id.toStdString()) - { - out << c; - if(++index % 4 == 0 && index < id.SIZE_IN_BYTES*2) out << ' '; - } - } - break; - default: out << id.toStdString(UPPER_CASE); break; - } - - return out; - } - - inline std::string toStdString() const { return toStdString(UPPER_CASE); } - - inline static uint32_t serial_size() { return SIZE_IN_BYTES; } - - bool serialise(void* data,uint32_t pktsize,uint32_t& offset) const - { - if(offset + SIZE_IN_BYTES > pktsize) return false; - memmove( &(reinterpret_cast(data))[offset], - bytes, SIZE_IN_BYTES ); - offset += SIZE_IN_BYTES; - return true; - } - - bool deserialise(const void* data, uint32_t pktsize, uint32_t& offset) - { - if(offset + SIZE_IN_BYTES > pktsize) return false; - memmove( bytes, - &(reinterpret_cast(data))[offset], - SIZE_IN_BYTES ); - offset += SIZE_IN_BYTES; - return true; - } - - /** Explicit constructor from a byte array. The array must have size at - * least ID_SIZE_IN_BYTES - * @deprecated This is too dangerous! - * Nothing prevent a buffer of wrong size being passed at runtime! - */ - RS_DEPRECATED_FOR("fromBufferUnsafe(const uint8_t* buff)") - explicit t_RsGenericIdType(const uint8_t bytes[]); - -private: - std::string toStdString(bool upper_case) const; - uint8_t bytes[ID_SIZE_IN_BYTES]; -}; - -template -std::string t_RsGenericIdType -::toStdString(bool upper_case) const -{ - static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ; - static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ; - - std::string res(ID_SIZE_IN_BYTES*2,' ') ; - - for(uint32_t j = 0; j < ID_SIZE_IN_BYTES; j++) - if(upper_case) - { - res[2*j ] = outh[ (bytes[j]>>4) ] ; - res[2*j+1] = outh[ bytes[j] & 0xf ] ; - } - else - { - res[2*j ] = outl[ (bytes[j]>>4) ] ; - res[2*j+1] = outl[ bytes[j] & 0xf ] ; - } - - return res ; -} - -template -t_RsGenericIdType -::t_RsGenericIdType(const std::string& s) -{ - std::string::size_type n = 0; - if(s.length() != ID_SIZE_IN_BYTES*2) - { - if(!s.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " supplied string in constructor " - << "has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2 - << " String=\"" << s << "\" = " << s.length() << std::endl; - print_stacktrace(); - } - clear(); - return; - } - - for(uint32_t i = 0; i < ID_SIZE_IN_BYTES; ++i) - { - bytes[i] = 0 ; - - for(int k=0;k<2;++k) - { - char b = s[n++] ; - - if(b >= 'A' && b <= 'F') - bytes[i] += (b-'A'+10) << 4*(1-k) ; - else if(b >= 'a' && b <= 'f') - bytes[i] += (b-'a'+10) << 4*(1-k) ; - else if(b >= '0' && b <= '9') - bytes[i] += (b-'0') << 4*(1-k) ; - else - { - RsErr() << __PRETTY_FUNCTION__ << "supplied string is not " - << "purely hexadecimal: s=\"" << s << "\"" << std::endl; - clear(); - return; - } - } - } -} - -template -RS_DEPRECATED_FOR("t_RsGenericIdType::fromBuffer(...)") -t_RsGenericIdType:: -t_RsGenericIdType(const uint8_t mem[]) /// @deprecated Too dangerous! -{ - if(mem == nullptr) memset(bytes, 0, ID_SIZE_IN_BYTES); - else memcpy(bytes, mem, ID_SIZE_IN_BYTES); -} - -/** - * This constants are meant to be used only inside this file. - * Use @see t_RsGenericIdType::SIZE_IN_BYTES in other places. - */ -namespace _RsIdSize -{ -constexpr uint32_t SSL_ID = 16; // = CERT_SIGN -constexpr uint32_t CERT_SIGN = 16; // = SSL_ID -constexpr uint32_t PGP_ID = 8; -constexpr uint32_t PGP_FINGERPRINT = 20; -constexpr uint32_t SHA1 = 20; -constexpr uint32_t SHA256 = 32; -} - -using RsPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::SSL >; -using RsPgpId = t_RsGenericIdType<_RsIdSize::PGP_ID , true, RsGenericIdType::PGP_ID >; -using Sha1CheckSum = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::SHA1 >; -using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, RsGenericIdType::SHA256 >; -using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>; -using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >; -using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >; -using RsGxsMessageId = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::GXS_MSG >; -using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >; -using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >; -using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >; -using DistantChatPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::DISTANT_CHAT >; -using RsNodeGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::NODE_GROUP >; - -/// @deprecated Ugly name kept temporarly only because it is used in many places -using PGPFingerprintType RS_DEPRECATED_FOR(RsPpgFingerprint) = RsPgpFingerprint; diff --git a/libretroshare/src/retroshare/rsiface.h b/libretroshare/src/retroshare/rsiface.h deleted file mode 100644 index 1f9041d3e..000000000 --- a/libretroshare/src/retroshare/rsiface.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsiface.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsnotify.h" -#include "rstypes.h" - -#include -#include - -class RsServer; -class RsInit; -struct RsPeerCryptoParams; -class RsControl; - -/// RsInit -> Configuration Parameters for RetroShare Startup -RsInit* InitRsConfig(); - -/* extract various options for GUI */ -const char *RsConfigDirectory(RsInit *config); -bool RsConfigStartMinimised(RsInit *config); -void CleanupRsConfig(RsInit *); - - -// Called First... (handles comandline options) -int InitRetroShare(int argc, char **argv, RsInit *config); - -/** - * Pointer to global instance of RsControl needed to expose JSON API - * @jsonapi{development} - */ -extern RsControl* rsControl; - -/** The Main Interface Class - for controlling the server */ -class RsControl -{ -public: - /// TODO: This should return a reference instead of a pointer! - static RsControl* instance(); - static void earlyInitNotificationSystem() { rsControl = instance(); } - - /* Real Startup Fn */ - virtual int StartupRetroShare() = 0; - - /** - * @brief Check if core is fully ready, true only after StartupRetroShare() - * finish and before rsGlobalShutDown() begin - * @jsonapi{development} - */ - virtual bool isReady() = 0; - - virtual void ConfigFinalSave() = 0; - - /** - * @brief Turn off RetroShare - * @jsonapi{development,manualwrapper} - */ - virtual void rsGlobalShutDown() = 0; - - virtual bool getPeerCryptoDetails( - const RsPeerId& ssl_id,RsPeerCryptoParams& params ) = 0; - virtual void getLibraries(std::list &libraries) = 0; - - /** - * @brief Set shutdown callback, useful if main runlop is controlled by - * another entity such as QCoreApplication - * @param callback function to call when shutdown is almost complete - */ - virtual void setShutdownCallback(const std::function& callback) = 0; - -protected: - RsControl() {} // should not be used, hence it's private. -}; - diff --git a/libretroshare/src/retroshare/rsinit.h b/libretroshare/src/retroshare/rsinit.h deleted file mode 100644 index 73fea2684..000000000 --- a/libretroshare/src/retroshare/rsinit.h +++ /dev/null @@ -1,480 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsinit.h * - * * - * Copyright (C) 2004-2014 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/// @file RetroShare initialization and login API - -// Initialize ok, result >= 0 -#define RS_INIT_OK 0 // Initialize ok -#define RS_INIT_HAVE_ACCOUNT 1 // Initialize ok, have account -// Initialize failed, result < 0 -#define RS_INIT_AUTH_FAILED -1 // AuthGPG::InitAuth failed -#define RS_INIT_BASE_DIR_ERROR -2 // AuthGPG::InitAuth failed -#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it. -#define RS_INIT_NO_EXECUTABLE -4 // executable path hasn't been set in config options - -#include -#include -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rsversion.h" - - -class RsLoginHelper; - -/** - * Pointer to global instance of RsLoginHelper - * @jsonapi{development} - */ -extern RsLoginHelper* rsLoginHelper; - - -enum class RsInitErrorNum : int32_t -{ - ALREADY_LOGGED_IN = 6000, - CANT_ACQUIRE_LOCK = 6001, - INVALID_LOCATION_NAME = 6002, - PGP_NAME_OR_ID_NEEDED = 6003, - PGP_KEY_CREATION_FAILED = 6004, - SSL_KEY_CREATION_FAILED = 6005, - INVALID_SSL_ID = 6006, - LOGIN_FAILED = 6007 -}; - -struct RsInitErrorCategory: std::error_category -{ - const char* name() const noexcept override - { return "RetroShare init"; } - - std::string message(int ev) const override - { - switch (static_cast(ev)) - { - case RsInitErrorNum::ALREADY_LOGGED_IN: - return "Already logged in"; - case RsInitErrorNum::CANT_ACQUIRE_LOCK: - return "Cannot aquire lock on location data. Another instance is " - "already running with this profile?"; - case RsInitErrorNum::INVALID_LOCATION_NAME: - return "Invalid location name"; - case RsInitErrorNum::PGP_NAME_OR_ID_NEEDED: - return "Either PGP name or PGP id is needed"; - case RsInitErrorNum::PGP_KEY_CREATION_FAILED: - return "Failure creating PGP key"; - case RsInitErrorNum::SSL_KEY_CREATION_FAILED: - return "Failure creating SSL key"; - case RsInitErrorNum::INVALID_SSL_ID: - return "Invalid SSL id"; - case RsInitErrorNum::LOGIN_FAILED: - return "Generic login failure"; - default: - return rsErrorNotInCategory(ev, name()); - } - } - - const static RsInitErrorCategory instance; -}; - - -namespace std -{ -/** Register RsJsonApiErrorNum as an error condition enum, must be in std - * namespace */ -template<> struct is_error_condition_enum : true_type {}; -} - -/** Provide RsInitErrorNum conversion to std::error_condition, must be in - * same namespace of RsInitErrorNum */ -inline std::error_condition make_error_condition(RsInitErrorNum e) noexcept -{ - return std::error_condition( - static_cast(e), RsInitErrorCategory::instance ); -}; - - - -/** - * @brief The RsInitConfig struct - * This class contains common configuration options, that executables using libretroshare may want to - * set using e.g. commandline options. To be passed to RsInit::InitRetroShare(). - */ -struct RsConfigOptions -{ - RsConfigOptions(); - - // required - - std::string main_executable_path;/* this should be set to argv[0] */ - - // Optional. Only change if needed. - - bool autoLogin; /* try auto-login */ - - bool udpListenerOnly; /* only listen to udp */ - std::string forcedInetAddress; /* inet address to use.*/ - uint16_t forcedPort; /* port to listen to */ - - bool outStderr; - int debugLevel; - std::string logfname; /* output filename for log */ - - std::string opModeStr; /* operating mode. Acceptable values: "Full", "NoTurtle", "Gaming", "Minimal" */ - std::string optBaseDir; /* base directory where to find profiles, etc */ - - uint16_t jsonApiPort; /* port to use fo Json API */ - std::string jsonApiBindAddress; /* bind address for Json API */ -}; - - -/*! - * Initialisation Class (not publicly disclosed to RsIFace) - */ -class RsInit -{ -public: - enum RS_DEPRECATED_FOR(RsInitErrorNum) LoadCertificateStatus : uint8_t - { - OK, /// Everything go as expected, no error occurred - ERR_ALREADY_RUNNING, /// Another istance is running already - ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running? - ERR_NO_AVAILABLE_ACCOUNT, /// Used in retroshare-service -U list when no account is available - ERR_UNKNOWN /// Unkown error, maybe password is wrong? - }; - - /* reorganised RsInit system */ - - /*! - * PreLogin - * Call before init retroshare, initialises rsinitconfig's public attributes - */ - static void InitRsConfig(); - - /*! - * Should be called to load up ssl cert and private key, and intialises gpg - * this must be called before accessing rsserver (e.g. ::startupretroshare) - * @param argc passed from executable - * @param argv commandline arguments passed to executable - * @param strictCheck set to true if you want rs to continue executing if - * invalid argument passed and vice versa - * @return RS_INIT_... - */ - static int InitRetroShare(const RsConfigOptions&); - - static bool isPortable(); - static bool isWindowsXP(); - static bool collectEntropy(uint32_t bytes) ; - - /*! - * \brief lockFilePath - * \return - * full path for the lock file. Can be used to warn the user about a non deleted lock that would prevent to start. - */ - static std::string lockFilePath(); - - /* - * Setup Hidden Location; - */ - static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob); - - static bool LoadPassword(const std::string& passwd) ; - - /* - * Final Certificate load. This can be called if: - * a) InitRetroshare() returns RS_INIT_HAVE_ACCOUNT -> autoLoad/password Set. - * b) or LoadPassword() - * - * This uses the preferredId from RsAccounts. - * This wrapper also locks the profile before finalising the login - */ - static LoadCertificateStatus LockAndLoadCertificates( - bool autoLoginNT, std::string& lockFilePath ); - - // Post Login Options - static bool getStartMinimised(); - - static int getSslPwdLen(); - static bool getAutoLogin(); - static void setAutoLogin(bool autoLogin); - static bool RsClearAutoLogin() ; - -private: - /** @brief Lock profile directory - * param[in] accountDir account directory to lock - * param[out] lockFilePath path of the created lock-file - */ - static LoadCertificateStatus LockConfigDirectory( - const std::string& accountDir, std::string& lockFilePath); - - /// @brief Unlock profile directory - static void UnlockConfigDirectory(); - - static int LoadCertificates(bool autoLoginNT); -}; - - - -/* Seperate static Class for dealing with Accounts */ - -class RsAccountsDetail; - -class RsAccounts -{ -public: - /// Should be called once before everything else. - static bool init(const std::string &opt_base_dir, int& error_code); - - /** - * @brief ConfigDirectory (usually ~/.retroshare) you can call this method - * even before initialisation (you can't with some other methods) - * @see RsAccountsDetail::PathBaseDirectory() - */ - static std::string ConfigDirectory(); - - /** - * @brief Get current account id. Beware that an account may be selected - * without actually logging in. - * @jsonapi{development,unauthenticated} - * @param[out] id storage for current account id - * @return false if account hasn't been selected yet, true otherwise - */ - static bool getCurrentAccountId(RsPeerId &id); - - /** - * @brief DataDirectory - * you can call this method even before initialisation (you can't with some other methods) - * @param check if set to true and directory does not exist, return empty string - * @return path where global platform independent files are stored, like bdboot.txt or webinterface files - */ - static std::string systemDataDirectory(bool check = true); - static std::string PGPDirectory(); - - /** - * @brief Get available PGP identities id list - * @jsonapi{development,unauthenticated} - * @param[out] pgpIds storage for PGP id list - * @return true on success, false otherwise - */ - static int GetPGPLogins(std::list &pgpIds); - static int GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email); - static bool GeneratePGPCertificate(const std::string&, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - - /** - * @brief Export full encrypted PGP identity to file - * @jsonapi{development} - * @param[in] filePath path of certificate file - * @param[in] pgpId PGP id to export - * @return true on success, false otherwise - */ - static bool ExportIdentity( const std::string& filePath, - const RsPgpId& pgpId ); - - /** - * @brief Import full encrypted PGP identity from file - * @jsonapi{development,unauthenticated} - * @param[in] filePath path of certificate file - * @param[out] pgpId storage for the PGP fingerprint of the imported key - * @param[out] errorMsg storage for eventual human readable error message - * @return true on success, false otherwise - */ - static bool ImportIdentity( - const std::string& filePath, RsPgpId& pgpId, std::string& errorMsg ); - - /** - * @brief Import full encrypted PGP identity from string - * @jsonapi{development,unauthenticated} - * @param[in] data certificate string - * @param[out] pgpId storage for the PGP fingerprint of the imported key - * @param[out] errorMsg storage for eventual human readable error message - * @return true on success, false otherwise - */ - static bool importIdentityFromString( - const std::string& data, RsPgpId& pgpId, - std::string& errorMsg ); - - /** - * @brief Export full encrypted PGP identity to string - * @jsonapi{development} - * @param[out] data storage for certificate string - * @param[in] pgpId PGP id to export - * @param[in] includeSignatures true to include signatures - * @param[out] errorMsg storage for eventual human readable error message - * @return true on success, false otherwise - */ - static bool exportIdentityToString( - std::string& data, const RsPgpId& pgpId, std::string& errorMsg, - bool includeSignatures = true ); - - static void GetUnsupportedKeys(std::map > &unsupported_keys); - static bool CopyGnuPGKeyrings() ; - - // Rs Accounts - static bool SelectAccount(const RsPeerId& id); - static bool GetPreferredAccountId(RsPeerId &id); - static bool GetAccountIds(std::list &ids); - - static bool GetAccountDetails(const RsPeerId &id, RsPgpId &gpgId, std::string &gpgName, std::string &gpgEmail, std::string &location); - - static bool createNewAccount( - const RsPgpId& pgp_id, const std::string& org, - const std::string& loc, const std::string& country, - bool ishiddenloc, bool is_auto_tor, const std::string& passwd, - RsPeerId &sslId, std::string &errString ); - - static void storeSelectedAccount() ; - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // All methods bellow can only be called ones SelectAccount() as been called. // - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - static bool getCurrentAccountOptions(bool& is_hidden,bool& is_tor_auto,bool& is_first_time) ; - - static bool checkCreateAccountDirectory(); // Generate the hierarchy of directories below ~/.retroshare/[SSL dir]/ - static bool isHiddenNode() ; // true if the running node is a hidden node. Used to choose which services to start. - static bool isTorAuto() ; // true if the running node is a hidden node using automated Tor management - - static std::string AccountDirectory(); // linux: ~/.retroshare/[SSL dir]/ - static std::string AccountKeysDirectory(); // linux: ~/.retroshare/[SSL dir]/keys/ - static std::string AccountPathCertFile(); // linux: ~/.retroshare/[SSL dir]/keys/user_cert.pem - static std::string AccountPathKeyFile(); // linux: ~/.retroshare/[SSL dir]/keys/user_pk.pem - static std::string AccountLocationName(); - - static bool lockPreferredAccount() ; // are these methods any useful?? - static void unlockPreferredAccount() ; - -private: - static RsAccountsDetail* rsAccountsDetails; -}; - -/** - * Pointer to global instance of RsAccounts needed to expose JSON API, as all - * the members of this class are static you should call them directly without - * using this pointer in the other parts of the code - * @jsonapi{development} - */ -extern RsAccounts* rsAccounts; - - -/** - * This helper class have been implemented because there was not reasonable way - * to login in the API that could be exposed via JSON API - */ -class RsLoginHelper -{ -public: - RsLoginHelper() = default; - - /** - * @brief Normal way to attempt login - * @jsonapi{development,unauthenticated} - * @param[in] account Id of the account to which attempt login - * @param[in] password Password for the given account - * @return RsInit::OK if login attempt success, error code otherwhise - */ - RsInit::LoadCertificateStatus attemptLogin( - const RsPeerId& account, const std::string& password ); - - /** - * @brief Feed extra entropy to the crypto libraries - * @jsonapi{development,unauthenticated} - * @param[in] bytes number to feed to the entropy pool - * @return false if error occurred, true otherwise - */ - static bool collectEntropy(uint32_t bytes); - - struct Location : RsSerializable - { - RsPeerId mLocationId; - RsPgpId mPgpId; - std::string mLocationName; - std::string mPgpName; - - /// @see RsSerializable::serial_process - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ); - }; - - /** - * @brief Get locations and associated information - * @jsonapi{development,unauthenticated} - * @param[out] locations storage for the retrived locations - */ - void getLocations(std::vector& locations); - - /** - * @brief Creates a new RetroShare location, and log in once is created - * @jsonapi{development,manualwrapper} - * @param[out] locationId storage for generated location SSL id - * @param[inout] pgpId specify PGP id to use to sign the location, if a null - * id is passed the PGP key is created too and this param is used as - * storage for its id. - * @param[in] password to protect and unlock the associated PGP key - * param[in] apiUser (JSON API only) string containing username for JSON API - * so it can be later used to authenticate JSON API calls. It is passed - * down to @see RsJsonApi::authorizeUser under the hood. - * param[in] apiPass (JSON API only) string containing password for JSON API - * so it can be later used to authenticate JSON API calls. It is passed - * down to @see RsJsonApi::authorizeUser under the hood. - * To improve security we strongly advise to not use the same as the - * password used for the PGP key. - * @return Success or error information - */ - std::error_condition createLocationV2( - RsPeerId& locationId, - RsPgpId& pgpId, - const std::string& locationName, - const std::string& pgpName, - const std::string& password - /* JSON API only - * const std::string& apiUser - * const std::string& apiPass */ ); - - /** - * @brief Check if RetroShare is already logged in, this usually return true - * after a successfull attemptLogin() and before closeSession() - * @jsonapi{development,unauthenticated} - * @return true if already logged in, false otherwise - */ - bool isLoggedIn(); - -#if !RS_VERSION_AT_LEAST(0,6,6) - /** - * @deprecated Use @see createLocationV2 instead - * @brief Creates a new RetroShare location, and log in once is created - * @jsonapi{development,manualwrapper} - * @param[inout] location provide input information to generate the location - * and storage to output the data of the generated location - * @param[in] password to protect and unlock the associated PGP key - * @param[out] errorMessage if some error occurred human readable error - * message - * @param[in] makeHidden pass true to create an hidden location. UNTESTED! - * @param[in] makeAutoTor pass true to create an automatically configured - * Tor hidden location. UNTESTED! - * @return true if success, false otherwise - */ - RS_DEPRECATED_FOR(createLocationV2) - bool createLocation( RsLoginHelper::Location& location, - const std::string& password, std::string& errorMessage, - bool makeHidden = false, bool makeAutoTor = false ); -#endif // !RS_VERSION_AT_LEAST(0,6,6) -}; diff --git a/libretroshare/src/retroshare/rsjsonapi.h b/libretroshare/src/retroshare/rsjsonapi.h deleted file mode 100644 index 38e33490e..000000000 --- a/libretroshare/src/retroshare/rsjsonapi.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * RetroShare JSON API public header - * - * Copyright (C) 2018-2020 Gioacchino Mazzurco - * Copyright (C) 2019 Cyril Soler - * Copyright (C) 2020 Asociación Civil Altermundi - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: LGPL-3.0-or-later - */ - -#pragma once - -#include -#include -#include -#include - -#include "util/rsdebug.h" -#include "util/rsmemory.h" - -class RsJsonApi; - -/** - * Pointer to global instance of RsJsonApi service implementation - * @jsonapi{development} - */ -extern RsJsonApi* rsJsonApi; - -enum class RsJsonApiErrorNum : int32_t -{ - TOKEN_FORMAT_INVALID = 2004, - UNKNOWN_API_USER = 2005, - WRONG_API_PASSWORD = 2006, - API_USER_CONTAIN_COLON = 2007, - AUTHORIZATION_REQUEST_DENIED = 2008, - CANNOT_EXECUTE_BEFORE_RS_LOGIN = 2009, - NOT_A_MACHINE_GUN = 2010 -}; - -struct RsJsonApiErrorCategory: std::error_category -{ - const char* name() const noexcept override - { return "RetroShare JSON API"; } - - std::string message(int ev) const override - { - switch (static_cast(ev)) - { - case RsJsonApiErrorNum::TOKEN_FORMAT_INVALID: - return "Invalid token format, must be alphanumeric_user:password"; - case RsJsonApiErrorNum::UNKNOWN_API_USER: - return "Unknown API user"; - case RsJsonApiErrorNum::WRONG_API_PASSWORD: - return "Wrong API password"; - case RsJsonApiErrorNum::API_USER_CONTAIN_COLON: - return "API user cannot contain colon character"; - case RsJsonApiErrorNum::AUTHORIZATION_REQUEST_DENIED: - return "User denied new token autorization"; - case RsJsonApiErrorNum::CANNOT_EXECUTE_BEFORE_RS_LOGIN: - return "This operation cannot be executed bedore RetroShare login"; - case RsJsonApiErrorNum::NOT_A_MACHINE_GUN: - return "Method must not be called in burst"; - default: - return rsErrorNotInCategory(ev, name()); - } - } - - std::error_condition default_error_condition(int ev) const noexcept override; - - const static RsJsonApiErrorCategory instance; -}; - - -namespace std -{ -/** Register RsJsonApiErrorNum as an error condition enum, must be in std - * namespace */ -template<> struct is_error_condition_enum : true_type {}; -} - -/** Provide RsJsonApiErrorNum conversion to std::error_condition, must be in - * same namespace of RsJsonApiErrorNum */ -inline std::error_condition make_error_condition(RsJsonApiErrorNum e) noexcept -{ - return std::error_condition( - static_cast(e), RsJsonApiErrorCategory::instance ); -}; - - -class p3ConfigMgr; -class JsonApiResourceProvider; - -class RsJsonApi -{ -public: - static const uint16_t DEFAULT_PORT = 9092; - static const std::string DEFAULT_BINDING_ADDRESS; // 127.0.0.1 - - /** - * @brief Restart RsJsonApi server. - * This method is asyncronous when called from JSON API. - * @jsonapi{development,manualwrapper} - * @return Success or error details - */ - virtual std::error_condition restart() = 0; - - /** @brief Request RsJsonApi to stop and wait until it has stopped. - * Do not expose this method to JSON API as fullstop must not be called from - * the same thread of service execution. - */ - virtual void fullstop() = 0; - - /** - * @brief Request RsJsonApi to stop asynchronously. - * @jsonapi{development} - * Be expecially carefull to call this from JSON API because you will loose - * access to the API. - * If you need to wait until stopping has completed @see isRunning(). - */ - virtual void askForStop() = 0; - - /** - * @brief Get status of the json api server - * @return Returns true if the server is running - */ - virtual bool isRunning() = 0; - - /** - * Sets the binding address of the JSON API server. Will only take effect - * after the server is restarted. - * @jsonapi{development} - * @param[in] address Binding address in IPv4 or IPv6 format. - */ - virtual void setBindingAddress(const std::string& address) = 0; - - /** - * Get the binding address of the JSON API server. - * @jsonapi{development} - * @return string representing binding address - */ - virtual std::string getBindingAddress() const = 0; - - /*! - * Set port on which JSON API server will listen. Will only take effect - * after the server is restarted. - * @jsonapi{development} - * @param[in] port Must be available otherwise the binding will fail - */ - virtual void setListeningPort(uint16_t port) = 0; - - /*! - * Get port on which JSON API server will listen. - * @jsonapi{development} - */ - virtual uint16_t listeningPort() const = 0; - - /*! - * Should be called after creating the JsonAPI object so that it publishes - * itself with the proper config file. - * Since JsonAPI is created *before* login, the config manager does not - * exist at that time. - * @param cfgmgr - */ - virtual void connectToConfigManager(p3ConfigMgr& cfgmgr) = 0; - - /** - * This is used to add/remove new web services to JsonAPI. The client - * should take care of not using a path range already used by the jsonAPI - * server - */ - virtual void registerResourceProvider(const JsonApiResourceProvider&) = 0; - virtual void unregisterResourceProvider(const JsonApiResourceProvider&) = 0; - virtual bool hasResourceProvider(const JsonApiResourceProvider&) = 0; - - /** - * @brief This function should be used by JSON API clients that aren't - * authenticated yet, to ask their token to be authorized, the success or - * failure will depend on mNewAccessRequestCallback return value, and it - * will likely need human user interaction in the process. - * @jsonapi{development,unauthenticated} - * @param[in] user user name to authorize - * @param[in] password password for the new user - * @return if an error occurred details about it. - */ - virtual std::error_condition requestNewTokenAutorization( - const std::string& user, const std::string& password) = 0; - - /** Split a token in USER:PASSWORD format into user and password */ - static bool parseToken( - const std::string& clear_token, - std::string& user, std::string& passwd ); - - /** - * Add new API auth user, passwd to the authorized set. - * @jsonapi{development} - * @param[in] user user name to autorize, must not contain ':' - * @param[in] password password for the user - * @return if some error occurred return details about it - */ - virtual std::error_condition authorizeUser( - const std::string& user, const std::string& password ) = 0; - - /** - * @brief Revoke given auth token - * @jsonapi{development} - * @param[in] user user name of which to revoke authorization - * @return true if the token has been revoked, false otherwise - */ - virtual bool revokeAuthToken(const std::string& user)=0; - - /** - * @brief Get authorized tokens - * @jsonapi{development} - * @return the set of authorized encoded tokens - */ - virtual std::map getAuthorizedTokens() = 0; - - /** - * @brief Check if given JSON API auth token is authorized - * @jsonapi{development,unauthenticated} - * @param[in] token decoded - * @param[out] error optional storage for error details - * @return true if authorized, false otherwise - */ - virtual bool isAuthTokenValid( - const std::string& token, - std::error_condition& error = RS_DEFAULT_STORAGE_PARAM(std::error_condition) - ) = 0; - - /** - * @brief Write version information to given paramethers - * @jsonapi{development,unauthenticated} - * @param[out] major storage - * @param[out] minor storage - * @param[out] mini storage - * @param[out] extra storage - * @param[out] human storage - */ - static void version( uint32_t& major, uint32_t& minor, uint32_t& mini, - std::string& extra, std::string& human ); - - virtual ~RsJsonApi() = default; -}; - diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h deleted file mode 100644 index 614a99707..000000000 --- a/libretroshare/src/retroshare/rsmsgs.h +++ /dev/null @@ -1,1043 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsmsgs.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rsgxsifacetypes.h" -#include "retroshare/rsevents.h" -#include "util/rsdeprecate.h" -#include "util/rsmemory.h" - -/********************** For Messages and Channels *****************/ - -#define RS_MSG_BOXMASK 0x000f /* Mask for determining Box */ - -#define RS_MSG_OUTGOING 0x0001 /* !Inbox */ -#define RS_MSG_PENDING 0x0002 /* OutBox */ -#define RS_MSG_DRAFT 0x0004 /* Draft */ - -/* ORs of above */ -#define RS_MSG_INBOX 0x00 /* Inbox */ -#define RS_MSG_SENTBOX 0x01 /* Sentbox */ -#define RS_MSG_OUTBOX 0x03 /* Outbox */ -#define RS_MSG_DRAFTBOX 0x05 /* Draftbox */ - -#define RS_MSG_NEW 0x000010 /* New */ -#define RS_MSG_TRASH 0x000020 /* Trash */ -#define RS_MSG_UNREAD_BY_USER 0x000040 /* Unread by user */ -#define RS_MSG_REPLIED 0x000080 /* Message is replied */ -#define RS_MSG_FORWARDED 0x000100 /* Message is forwarded */ -#define RS_MSG_STAR 0x000200 /* Message is marked with a star */ -// system message -#define RS_MSG_USER_REQUEST 0x000400 /* user request */ -#define RS_MSG_FRIEND_RECOMMENDATION 0x000800 /* friend recommendation */ -#define RS_MSG_DISTANT 0x001000 /* message is distant */ -#define RS_MSG_SIGNATURE_CHECKS 0x002000 /* message was signed, and signature checked */ -#define RS_MSG_SIGNED 0x004000 /* message was signed and signature didn't check */ -#define RS_MSG_LOAD_EMBEDDED_IMAGES 0x008000 /* load embedded images */ -#define RS_MSG_PUBLISH_KEY 0x020000 /* publish key */ -#define RS_MSG_SPAM 0x040000 /* Message is marked as spam */ - -#define RS_MSG_SYSTEM (RS_MSG_USER_REQUEST | RS_MSG_FRIEND_RECOMMENDATION | RS_MSG_PUBLISH_KEY) - -#define RS_CHAT_LOBBY_EVENT_PEER_LEFT 0x01 -#define RS_CHAT_LOBBY_EVENT_PEER_STATUS 0x02 -#define RS_CHAT_LOBBY_EVENT_PEER_JOINED 0x03 -#define RS_CHAT_LOBBY_EVENT_PEER_CHANGE_NICKNAME 0x04 -#define RS_CHAT_LOBBY_EVENT_KEEP_ALIVE 0x05 - -#define RS_MSGTAGTYPE_IMPORTANT 1 -#define RS_MSGTAGTYPE_WORK 2 -#define RS_MSGTAGTYPE_PERSONAL 3 -#define RS_MSGTAGTYPE_TODO 4 -#define RS_MSGTAGTYPE_LATER 5 -#define RS_MSGTAGTYPE_USER 100 - -//#define RS_CHAT_LOBBY_PRIVACY_LEVEL_CHALLENGE 0 /* Used to accept connection challenges only. */ -//#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC 1 /* lobby is visible by friends. Friends can connect.*/ -//#define RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE 2 /* lobby invisible by friends. Peers on invitation only .*/ - -#define RS_CHAT_TYPE_PUBLIC 1 -#define RS_CHAT_TYPE_PRIVATE 2 -#define RS_CHAT_TYPE_LOBBY 3 -#define RS_CHAT_TYPE_DISTANT 4 - -const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_AUTO_SUBSCRIBE( 0x00000001 ) ; -const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_deprecated ( 0x00000002 ) ; -const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_PUBLIC ( 0x00000004 ) ; -const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_CHALLENGE ( 0x00000008 ) ; -const ChatLobbyFlags RS_CHAT_LOBBY_FLAGS_PGP_SIGNED ( 0x00000010 ) ; // requires the signing ID to be PGP-linked. Avoids anonymous crap. - -typedef uint64_t ChatLobbyId ; -typedef uint64_t ChatLobbyMsgId ; -typedef std::string ChatLobbyNickName ; -typedef std::string RsMailMessageId; // TODO: rebase on t_RsGenericIdType - -/** - * Used to return a tracker id so the API user can keep track of sent mail - * status, it contains mail id, and recipient id - */ -struct RsMailIdRecipientIdPair : RsSerializable -{ - RsMailIdRecipientIdPair(RsMailMessageId mailId, RsGxsId recipientId): - mMailId(mailId), mRecipientId(recipientId) {} - - RsMailMessageId mMailId; - RsGxsId mRecipientId; - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext &ctx ) override; - - bool operator<(const RsMailIdRecipientIdPair& other) const; - bool operator==(const RsMailIdRecipientIdPair& other) const; - - RsMailIdRecipientIdPair() = default; - ~RsMailIdRecipientIdPair() override = default; -}; - -namespace Rs -{ -namespace Msgs -{ - -class MsgAddress -{ - public: - typedef enum { MSG_ADDRESS_TYPE_UNKNOWN = 0x00, - MSG_ADDRESS_TYPE_RSPEERID = 0x01, - MSG_ADDRESS_TYPE_RSGXSID = 0x02, - MSG_ADDRESS_TYPE_EMAIL = 0x03 } AddressType; - - typedef enum { MSG_ADDRESS_MODE_UNKNOWN = 0x00, - MSG_ADDRESS_MODE_TO = 0x01, - MSG_ADDRESS_MODE_CC = 0x02, - MSG_ADDRESS_MODE_BCC = 0x03 } AddressMode; - - explicit MsgAddress(const RsGxsId& gid, MsgAddress::AddressMode mmode) - : _type(MSG_ADDRESS_TYPE_RSGXSID), _mode(mmode), _addr_string(gid.toStdString()){} - - explicit MsgAddress(const RsPeerId& pid, MsgAddress::AddressMode mmode) - : _type(MSG_ADDRESS_TYPE_RSPEERID), _mode(mmode), _addr_string(pid.toStdString()){} - - explicit MsgAddress(const std::string& email, MsgAddress::AddressMode mmode) - : _type(MSG_ADDRESS_TYPE_EMAIL), _mode(mmode), _addr_string(email){} - - MsgAddress::AddressType type() { return _type ;} - MsgAddress::AddressMode mode() { return _mode ;} - - RsGxsId toGxsId() const { assert(_type==MSG_ADDRESS_TYPE_RSGXSID );return RsGxsId (_addr_string);} - RsPeerId toRsPeerId() const { assert(_type==MSG_ADDRESS_TYPE_RSPEERID);return RsPeerId(_addr_string);} - std::string toEmail() const { assert(_type==MSG_ADDRESS_TYPE_EMAIL );return _addr_string ;} - - private: - AddressType _type ; - AddressMode _mode ; - std::string _addr_string ; -}; - -struct MessageInfo : RsSerializable -{ - MessageInfo(): msgflags(0), size(0), count(0), ts(0) {} - - std::string msgId; - - RsPeerId rspeerid_srcId; - RsGxsId rsgxsid_srcId; - - unsigned int msgflags; - - // friend destinations - // - std::set rspeerid_msgto; // RsPeerId is used here for various purposes: - std::set rspeerid_msgcc; // - real peer ids which are actual friend locations - std::set rspeerid_msgbcc; // - - - // distant peers - // - std::set rsgxsid_msgto; // RsPeerId is used here for various purposes: - std::set rsgxsid_msgcc; // - real peer ids which are actual friend locations - std::set rsgxsid_msgbcc; // - - - std::string title; - std::string msg; - - std::string attach_title; - std::string attach_comment; - std::list files; - - int size; /* total of files */ - int count; /* file count */ - - int ts; - - // RsSerializable interface - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext &ctx ) override - { - RS_SERIAL_PROCESS(msgId); - - RS_SERIAL_PROCESS(rspeerid_srcId); - RS_SERIAL_PROCESS(rsgxsid_srcId); - - RS_SERIAL_PROCESS(msgflags); - - RS_SERIAL_PROCESS(rspeerid_msgto); - RS_SERIAL_PROCESS(rspeerid_msgcc); - RS_SERIAL_PROCESS(rspeerid_msgbcc); - - RS_SERIAL_PROCESS(rsgxsid_msgto); - RS_SERIAL_PROCESS(rsgxsid_msgcc); - RS_SERIAL_PROCESS(rsgxsid_msgcc); - - RS_SERIAL_PROCESS(title); - RS_SERIAL_PROCESS(msg); - - RS_SERIAL_PROCESS(attach_title); - RS_SERIAL_PROCESS(attach_comment); - RS_SERIAL_PROCESS(files); - - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(count); - - RS_SERIAL_PROCESS(ts); - } - - ~MessageInfo() override; -}; - -struct MsgInfoSummary : RsSerializable -{ - MsgInfoSummary() : msgflags(0), count(0), ts(0) {} - - RsMailMessageId msgId; - RsPeerId srcId; - - uint32_t msgflags; - std::list msgtags; /// that leaves 25 bits for user-defined tags. - - std::string title; - int count; /** file count */ - rstime_t ts; - - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext &ctx) override - { - RS_SERIAL_PROCESS(msgId); - RS_SERIAL_PROCESS(srcId); - - RS_SERIAL_PROCESS(msgflags); - RS_SERIAL_PROCESS(msgtags); - - RS_SERIAL_PROCESS(title); - RS_SERIAL_PROCESS(count); - RS_SERIAL_PROCESS(ts); - } - - ~MsgInfoSummary() override; -}; - -struct MsgTagInfo : RsSerializable -{ - virtual ~MsgTagInfo() = default; - - std::string msgId; - std::list tagIds; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(msgId); - RS_SERIAL_PROCESS(tagIds); - } -}; - -struct MsgTagType : RsSerializable -{ - virtual ~MsgTagType() = default; - /* map containing tagId -> pair (text, rgb color) */ - std::map > types; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(types); - } -}; - -} //namespace Rs -} //namespace Msgs - -enum class RsMailStatusEventCode: uint8_t -{ - NEW_MESSAGE = 0x00, - MESSAGE_REMOVED = 0x01, - MESSAGE_SENT = 0x02, - - /// means the peer received the message - MESSAGE_RECEIVED_ACK = 0x03, - - /// An error occurred attempting to sign the message - SIGNATURE_FAILED = 0x04, -}; - -struct RsMailStatusEvent : RsEvent -{ - RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS) {} - - RsMailStatusEventCode mMailStatusEventCode; - std::set mChangedMsgIds; - - /// @see RsEvent - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mChangedMsgIds); - RS_SERIAL_PROCESS(mMailStatusEventCode); - } - - ~RsMailStatusEvent() override = default; -}; - -#define RS_CHAT_PUBLIC 0x0001 -#define RS_CHAT_PRIVATE 0x0002 -#define RS_CHAT_AVATAR_AVAILABLE 0x0004 - -#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000 -#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001 -#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0002 -#define RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED 0x0003 - -#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000 -#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001 -#define RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH 0x0002 -#define RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY 0x0003 -#define RS_DISTANT_CHAT_ERROR_UNKNOWN_HASH 0x0004 - -#define RS_DISTANT_CHAT_FLAG_SIGNED 0x0001 -#define RS_DISTANT_CHAT_FLAG_SIGNATURE_OK 0x0002 - -// flags to define who we accept to talk to. Each flag *removes* some people. - -#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NONE 0x0000 -#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS 0x0001 -#define RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY 0x0002 - -#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE 0x0000 -#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS 0x0001 -#define RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY 0x0002 - -struct DistantChatPeerInfo : RsSerializable -{ - DistantChatPeerInfo() : status(0),pending_items(0) {} - - RsGxsId to_id ; - RsGxsId own_id ; - DistantChatPeerId peer_id ; // this is the tunnel id actually - uint32_t status ; // see the values in rsmsgs.h - uint32_t pending_items; // items not sent, waiting for a tunnel - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(to_id); - RS_SERIAL_PROCESS(own_id); - RS_SERIAL_PROCESS(peer_id); - RS_SERIAL_PROCESS(status); - RS_SERIAL_PROCESS(pending_items); - } -}; - -// Identifier for an chat endpoint like -// neighbour peer, distant peer, chatlobby, broadcast -class ChatId : RsSerializable -{ -public: - ChatId(); - virtual ~ChatId() = default; - - explicit ChatId(RsPeerId id); - explicit ChatId(ChatLobbyId id); - explicit ChatId(DistantChatPeerId id); - explicit ChatId(std::string str); - static ChatId makeBroadcastId(); - - std::string toStdString() const; - bool operator<(const ChatId& other) const; - bool isSameEndpoint(const ChatId& other) const; - - bool operator==(const ChatId& other) const { return isSameEndpoint(other) ; } - - bool isNotSet() const; - bool isPeerId() const; - bool isDistantChatId() const; - bool isLobbyId() const; - bool isBroadcast() const; - - RsPeerId toPeerId() const; - ChatLobbyId toLobbyId() const; - DistantChatPeerId toDistantChatId() const; - - // for the very specific case of transfering a status string - // from the chatservice to the gui, - // this defines from which peer the status string came from - RsPeerId broadcast_status_peer_id; -private: - enum Type : uint8_t - { TYPE_NOT_SET, - TYPE_PRIVATE, // private chat with directly connected friend, peer_id is valid - TYPE_PRIVATE_DISTANT, // private chat with distant peer, gxs_id is valid - TYPE_LOBBY, // chat lobby id, lobby_id is valid - TYPE_BROADCAST // message to/from all connected peers - }; - - Type type; - RsPeerId peer_id; - DistantChatPeerId distant_chat_id; - ChatLobbyId lobby_id; - - // RsSerializable interface -public: - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(broadcast_status_peer_id); - RS_SERIAL_PROCESS(type); - RS_SERIAL_PROCESS(peer_id); - RS_SERIAL_PROCESS(distant_chat_id); - RS_SERIAL_PROCESS(lobby_id); - } -}; - -struct ChatMessage : RsSerializable -{ - ChatId chat_id; // id of chat endpoint - RsPeerId broadcast_peer_id; // only used for broadcast chat: source peer id - RsGxsId lobby_peer_gxs_id; // only used for lobbys: nickname of message author - std::string peer_alternate_nickname; // only used when key is unknown. - - unsigned int chatflags; - uint32_t sendTime; - uint32_t recvTime; - std::string msg; - bool incoming; - bool online; // for outgoing messages: was this message send? - //bool system_message; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(chat_id); - RS_SERIAL_PROCESS(broadcast_peer_id); - RS_SERIAL_PROCESS(lobby_peer_gxs_id); - RS_SERIAL_PROCESS(peer_alternate_nickname); - - RS_SERIAL_PROCESS(chatflags); - RS_SERIAL_PROCESS(sendTime); - RS_SERIAL_PROCESS(recvTime); - RS_SERIAL_PROCESS(msg); - RS_SERIAL_PROCESS(incoming); - RS_SERIAL_PROCESS(online); - } -}; - -class ChatLobbyInvite : RsSerializable -{ -public: - virtual ~ChatLobbyInvite() = default; - - ChatLobbyId lobby_id ; - RsPeerId peer_id ; - std::string lobby_name ; - std::string lobby_topic ; - ChatLobbyFlags lobby_flags ; - - // RsSerializable interface -public: - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(lobby_id); - RS_SERIAL_PROCESS(peer_id); - RS_SERIAL_PROCESS(lobby_name); - RS_SERIAL_PROCESS(lobby_topic); - RS_SERIAL_PROCESS(lobby_flags); - } -}; - -struct VisibleChatLobbyRecord : RsSerializable -{ - VisibleChatLobbyRecord(): - lobby_id(0), total_number_of_peers(0), last_report_time(0) {} - - ChatLobbyId lobby_id ; // unique id of the lobby - std::string lobby_name ; // name to use for this lobby - std::string lobby_topic ; // topic to use for this lobby - std::set participating_friends ; // list of direct friend who participate. - - uint32_t total_number_of_peers ; // total number of particpating peers. Might not be - rstime_t last_report_time ; // last time the lobby was reported. - ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext &ctx) override - { - RS_SERIAL_PROCESS(lobby_id); - RS_SERIAL_PROCESS(lobby_name); - RS_SERIAL_PROCESS(lobby_topic); - RS_SERIAL_PROCESS(participating_friends); - - RS_SERIAL_PROCESS(total_number_of_peers); - RS_SERIAL_PROCESS(last_report_time); - RS_SERIAL_PROCESS(lobby_flags); - } - - ~VisibleChatLobbyRecord() override; -}; - -class ChatLobbyInfo : RsSerializable -{ -public: - virtual ~ChatLobbyInfo() = default; - - ChatLobbyId lobby_id ; // unique id of the lobby - std::string lobby_name ; // name to use for this lobby - std::string lobby_topic ; // topic to use for this lobby - std::set participating_friends ; // list of direct friend who participate. Used to broadcast sent messages. - RsGxsId gxs_id ; // ID to sign messages - - ChatLobbyFlags lobby_flags ; // see RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC / RS_CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE - std::map gxs_ids ; // list of non direct friend who participate. Used to display only. - rstime_t last_activity ; // last recorded activity. Useful for removing dead lobbies. - - virtual void clear() { gxs_ids.clear(); lobby_id = 0; lobby_name.clear(); lobby_topic.clear(); participating_friends.clear(); } - - // RsSerializable interface -public: - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(lobby_id); - RS_SERIAL_PROCESS(lobby_name); - RS_SERIAL_PROCESS(lobby_topic); - RS_SERIAL_PROCESS(participating_friends); - RS_SERIAL_PROCESS(gxs_id); - - RS_SERIAL_PROCESS(lobby_flags); - RS_SERIAL_PROCESS(gxs_ids); - RS_SERIAL_PROCESS(last_activity); - } -}; - - -class RsMsgs; -/** - * @brief Pointer to retroshare's message service - * @jsonapi{development} - */ -extern RsMsgs* rsMsgs; - -class RsMsgs -{ -public: - - /** - * @brief getMessageSummaries - * @jsonapi{development} - * @param[out] msgList - * @return always true - */ - virtual bool getMessageSummaries(std::list &msgList) = 0; - - /** - * @brief getMessage - * @jsonapi{development} - * @param[in] msgId message ID to lookup - * @param[out] msg - * @return true on success - */ - virtual bool getMessage(const std::string &msgId, Rs::Msgs::MessageInfo &msg) = 0; - - /** - * @brief sendMail - * @jsonapi{development} - * @param[in] from GXS id of the author - * @param[in] subject Mail subject - * @param[in] mailBody Mail body - * @param[in] to list of To: recipients - * @param[in] cc list of CC: recipients - * @param[in] bcc list of BCC: recipients - * @param[in] attachments list of suggested files - * @param[out] trackingIds storage for tracking ids for each sent mail - * @param[out] errorMsg error message if errors occurred, empty otherwise - * @return number of successfully sent mails - */ - virtual uint32_t sendMail( - const RsGxsId from, - const std::string& subject, - const std::string& mailBody, - const std::set& to = std::set(), - const std::set& cc = std::set(), - const std::set& bcc = std::set(), - const std::vector& attachments = std::vector(), - std::set& trackingIds = - RS_DEFAULT_STORAGE_PARAM(std::set), - std::string& errorMsg = - RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0; - - /** - * @brief getMessageCount - * @jsonapi{development} - * @param[out] nInbox - * @param[out] nInboxNew - * @param[out] nOutbox - * @param[out] nDraftbox - * @param[out] nSentbox - * @param[out] nTrashbox - */ - virtual void getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox) = 0; - - /** - * @brief SystemMessage - * @jsonapi{development} - * @param[in] title - * @param[in] message - * @param[in] systemFlag - * @return true on success - */ - virtual bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag) = 0; - - /** - * @brief MessageToDraft - * @jsonapi{development} - * @param[in] info - * @param[in] msgParentId - * @return true on success - */ - virtual bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId) = 0; - - /** - * @brief MessageToTrash - * @jsonapi{development} - * @param[in] msgId Id of the message to mode to trash box - * @param[in] bTrash Move to trash if true, otherwise remove from trash - * @return true on success - */ - virtual bool MessageToTrash(const std::string &msgId, bool bTrash) = 0; - - /** - * @brief getMsgParentId - * @jsonapi{development} - * @param[in] msgId - * @param[out] msgParentId - * @return true on success - */ - virtual bool getMsgParentId(const std::string &msgId, std::string &msgParentId) = 0; - - /** - * @brief MessageDelete - * @jsonapi{development} - * @param[in] msgId - * @return true on success - */ - virtual bool MessageDelete(const std::string &msgId) = 0; - - /** - * @brief MessageRead - * @jsonapi{development} - * @param[in] msgId - * @param[in] unreadByUser - * @return true on success - */ - virtual bool MessageRead(const std::string &msgId, bool unreadByUser) = 0; - - /** - * @brief MessageReplied - * @jsonapi{development} - * @param[in] msgId - * @param[in] replied - * @return true on success - */ - virtual bool MessageReplied(const std::string &msgId, bool replied) = 0; - - /** - * @brief MessageForwarded - * @jsonapi{development} - * @param[in] msgId - * @param[in] forwarded - * @return true on success - */ - virtual bool MessageForwarded(const std::string &msgId, bool forwarded) = 0; - - /** - * @brief MessageStar - * @jsonapi{development} - * @param[in] msgId - * @param[in] mark - * @return true on success - */ - virtual bool MessageStar(const std::string &msgId, bool mark) = 0; - - /** - * @brief MessageJunk - * @jsonapi{development} - * @param[in] msgId - * @param[in] mark - * @return true on success - */ - virtual bool MessageJunk(const std::string &msgId, bool mark) = 0; - - /** - * @brief MessageLoadEmbeddedImages - * @jsonapi{development} - * @param[in] msgId - * @param[in] load - * @return true on success - */ - virtual bool MessageLoadEmbeddedImages(const std::string &msgId, bool load) = 0; - - /* message tagging */ - /** - * @brief getMessageTagTypes - * @jsonapi{development} - * @param[out] tags - * @return always true - */ - virtual bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags) = 0; - - /** - * @brief setMessageTagType - * @jsonapi{development} - * @param[in] tagId - * @param[in] text - * @param[in] rgb_color - * @return true on success - */ - virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) = 0; - - /** - * @brief removeMessageTagType - * @jsonapi{development} - * @param[in] tagId - * @return true on success - */ - virtual bool removeMessageTagType(uint32_t tagId) = 0; - - /** - * @brief getMessageTag - * @jsonapi{development} - * @param[in] msgId - * @param[out] info - * @return true on success - */ - virtual bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info) = 0; - - /** - * @brief setMessageTag - * set == false && tagId == 0 --> remove all - * @jsonapi{development} - * @param[in] msgId - * @param[in] tagId - * @param[in] set - * @return true on success - */ - virtual bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set) = 0; - - /** - * @brief resetMessageStandardTagTypes - * @jsonapi{development} - * @param[out] tags - * @return always true - */ - virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags) = 0; - - /****************************************/ - /* Private distant messages */ - /****************************************/ - - virtual uint32_t getDistantMessagingPermissionFlags()=0 ; - virtual void setDistantMessagingPermissionFlags(uint32_t flags)=0 ; - - /****************************************/ - /* Chat */ - /****************************************/ - // sendChat for broadcast, private, lobby and private distant chat - // note: for lobby chat, you first have to subscribe to a lobby - // for private distant chat, it is reqired to have an active distant chat session - - /** - * @brief sendChat send a chat message to a given id - * @jsonapi{development} - * @param[in] id id to send the message - * @param[in] msg message to send - * @return true on success - */ - virtual bool sendChat(ChatId id, std::string msg) = 0; - - /** - * @brief getMaxMessageSecuritySize get the maximum size of a chta message - * @jsonapi{development} - * @param[in] type chat type - * @return maximum size or zero for infinite - */ - virtual uint32_t getMaxMessageSecuritySize(int type) = 0; - - /** - * @brief sendStatusString send a status string - * @jsonapi{development} - * @param[in] id chat id to send the status string to - * @param[in] status_string status string - */ - virtual void sendStatusString(const ChatId &id, const std::string &status_string) = 0; - - /** - * @brief clearChatLobby clear a chat lobby - * @jsonapi{development} - * @param[in] id chat lobby id to clear - */ - virtual void clearChatLobby(const ChatId &id) = 0; - - /** - * @brief setCustomStateString set your custom status message - * @jsonapi{development} - * @param[in] status_string status message - */ - virtual void setCustomStateString(const std::string &status_string) = 0; - - /** - * @brief getCustomStateString get your custom status message - * @return status message - */ - virtual std::string getCustomStateString() = 0; - - /** - * @brief getCustomStateString get the custom status message from a peer - * @jsonapi{development} - * @param[in] peer_id peer id to the peer you want to get the status message from - * @return status message - */ - virtual std::string getCustomStateString(const RsPeerId &peer_id) = 0; - -// get avatar data for peer pid -virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size) = 0 ; -// set own avatar data -virtual void setOwnAvatarData(const unsigned char *data,int size) = 0 ; -virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ; - - /****************************************/ - /* Chat lobbies */ - /****************************************/ - /** - * @brief joinVisibleChatLobby join a lobby that is visible - * @jsonapi{development} - * @param[in] lobby_id lobby to join to - * @param[in] own_id chat id to use - * @return true on success - */ - virtual bool joinVisibleChatLobby(const ChatLobbyId &lobby_id, const RsGxsId &own_id) = 0 ; - - /** - * @brief getChatLobbyList get ids of subscribed lobbies - * @jsonapi{development} - * @param[out] cl_list lobby list - */ - virtual void getChatLobbyList(std::list &cl_list) = 0; - - /** - * @brief getChatLobbyInfo get lobby info of a subscribed chat lobby. Returns true if lobby id is valid. - * @jsonapi{development} - * @param[in] id id to get infos from - * @param[out] info lobby infos - * @return true on success - */ - virtual bool getChatLobbyInfo(const ChatLobbyId &id, ChatLobbyInfo &info) = 0 ; - - /** - * @brief getListOfNearbyChatLobbies get info about all lobbies, subscribed and unsubscribed - * @jsonapi{development} - * @param[out] public_lobbies list of all visible lobbies - */ - virtual void getListOfNearbyChatLobbies(std::vector &public_lobbies) = 0 ; - - /** - * @brief invitePeerToLobby invite a peer to join a lobby - * @jsonapi{development} - * @param[in] lobby_id lobby it to invite into - * @param[in] peer_id peer to invite - */ - virtual void invitePeerToLobby(const ChatLobbyId &lobby_id, const RsPeerId &peer_id) = 0; - - /** - * @brief acceptLobbyInvite accept a chat invite - * @jsonapi{development} - * @param[in] id chat lobby id you were invited into and you want to join - * @param[in] identity chat identity to use - * @return true on success - */ - virtual bool acceptLobbyInvite(const ChatLobbyId &id, const RsGxsId &identity) = 0 ; - - /** - * @brief denyLobbyInvite deny a chat lobby invite - * @jsonapi{development} - * @param[in] id chat lobby id you were invited into - */ - virtual void denyLobbyInvite(const ChatLobbyId &id) = 0 ; - - /** - * @brief getPendingChatLobbyInvites get a list of all pending chat lobby invites - * @jsonapi{development} - * @param[out] invites list of all pending chat lobby invites - */ - virtual void getPendingChatLobbyInvites(std::list &invites) = 0; - - /** - * @brief unsubscribeChatLobby leave a chat lobby - * @jsonapi{development} - * @param[in] lobby_id lobby to leave - */ - virtual void unsubscribeChatLobby(const ChatLobbyId &lobby_id) = 0; - - /** - * @brief sendLobbyStatusPeerLeaving notify friend nodes that we're leaving a subscribed lobby - * @jsonapi{development} - * @param[in] lobby_id lobby to leave - */ - virtual void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) = 0; - - /** - * @brief setIdentityForChatLobby set the chat identit - * @jsonapi{development} - * @param[in] lobby_id lobby to change the chat idnetity for - * @param[in] nick new chat identity - * @return true on success - */ - virtual bool setIdentityForChatLobby(const ChatLobbyId &lobby_id, const RsGxsId &nick) = 0; - - /** - * @brief getIdentityForChatLobby - * @jsonapi{development} - * @param[in] lobby_id lobby to get the chat id from - * @param[out] nick chat identity - * @return true on success - */ - virtual bool getIdentityForChatLobby(const ChatLobbyId &lobby_id, RsGxsId &nick) = 0 ; - - /** - * @brief setDefaultIdentityForChatLobby set the default identity used for chat lobbies - * @jsonapi{development} - * @param[in] nick chat identitiy to use - * @return true on success - */ - virtual bool setDefaultIdentityForChatLobby(const RsGxsId &nick) = 0; - - /** - * @brief getDefaultIdentityForChatLobby get the default identity used for chat lobbies - * @jsonapi{development} - * @param[out] id chat identitiy to use - */ - virtual void getDefaultIdentityForChatLobby(RsGxsId &id) = 0 ; - - /** - * @brief setLobbyAutoSubscribe enable or disable auto subscribe for a chat lobby - * @jsonapi{development} - * @param[in] lobby_id lobby to auto (un)subscribe - * @param[in] autoSubscribe set value for auto subscribe - */ - virtual void setLobbyAutoSubscribe(const ChatLobbyId &lobby_id, const bool autoSubscribe) = 0 ; - - /** - * @brief getLobbyAutoSubscribe get current value of auto subscribe - * @jsonapi{development} - * @param[in] lobby_id lobby to get value from - * @return wether lobby has auto subscribe enabled or disabled - */ - virtual bool getLobbyAutoSubscribe(const ChatLobbyId &lobby_id) = 0 ; - - /** - * @brief createChatLobby create a new chat lobby - * @jsonapi{development} - * @param[in] lobby_name lobby name - * @param[in] lobby_identity chat id to use for new lobby - * @param[in] lobby_topic lobby toppic - * @param[in] invited_friends list of friends to invite - * @param[in] lobby_privacy_type flag for new chat lobby - * @return chat id of new lobby - */ - virtual ChatLobbyId createChatLobby(const std::string &lobby_name, const RsGxsId &lobby_identity, const std::string &lobby_topic, const std::set &invited_friends, ChatLobbyFlags lobby_privacy_type) = 0 ; - -/****************************************/ -/* Distant chat */ -/****************************************/ - - virtual uint32_t getDistantChatPermissionFlags()=0 ; - virtual bool setDistantChatPermissionFlags(uint32_t flags)=0 ; - - /** - * @brief initiateDistantChatConnexion initiate a connexion for a distant chat - * @jsonapi{development} - * @param[in] to_pid RsGxsId to start the connection - * @param[in] from_pid owned RsGxsId who start the connection - * @param[out] pid distant chat id - * @param[out] error_code if the connection can't be stablished - * @param[in] notify notify remote that the connection is stablished - * @return true on success. If you try to initate a connection already started it will return the pid of it. - */ - virtual bool initiateDistantChatConnexion( - const RsGxsId& to_pid, const RsGxsId& from_pid, - DistantChatPeerId& pid, uint32_t& error_code, - bool notify = true ) = 0; - - /** - * @brief getDistantChatStatus receives distant chat info to a given distant chat id - * @jsonapi{development} - * @param[in] pid distant chat id - * @param[out] info distant chat info - * @return true on success - */ - virtual bool getDistantChatStatus(const DistantChatPeerId& pid, DistantChatPeerInfo& info)=0; - - /** - * @brief closeDistantChatConnexion - * @jsonapi{development} - * @param[in] pid distant chat id to close the connection - * @return true on success - */ - virtual bool closeDistantChatConnexion(const DistantChatPeerId& pid)=0; - - /** - * @brief MessageSend - * @jsonapi{development} - * @param[in] info - * @return always true - */ - RS_DEPRECATED_FOR(sendMail) - virtual bool MessageSend(Rs::Msgs::MessageInfo &info) = 0; - - virtual ~RsMsgs(); -}; diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h deleted file mode 100644 index e8c9de614..000000000 --- a/libretroshare/src/retroshare/rsnotify.h +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsnotify.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -#include "rsturtle.h" -#include "rsgxsifacetypes.h" -#include "util/rsdeprecate.h" - -class ChatId; -class ChatMessage; -struct RsGxsChanges; - -class RsNotify; -extern RsNotify *rsNotify; - -const uint32_t RS_SYS_ERROR = 0x0001; -const uint32_t RS_SYS_WARNING = 0x0002; -const uint32_t RS_SYS_INFO = 0x0004; - -const uint32_t RS_POPUP_MSG = 0x0001; -const uint32_t RS_POPUP_CHAT = 0x0002; -//const uint32_t RS_POPUP_CALL = 0x0004; -const uint32_t RS_POPUP_CONNECT = 0x0008; -const uint32_t RS_SYSTRAY_GROUP_MSG = 0x0010; -const uint32_t RS_POPUP_DOWNLOAD = 0x0020; -const uint32_t RS_POPUP_GROUPCHAT = 0x0040; -const uint32_t RS_POPUP_CHATLOBBY = 0x0080; -const uint32_t RS_POPUP_CONNECT_ATTEMPT = 0x0100; -const uint32_t RS_POPUP_ENCRYPTED_MSG = 0x0200; - -/* CHAT flags are here - so they are in the same place as - * other Notify flags... not used by libretroshare though - */ -const uint32_t RS_CHAT_OPEN = 0x0001; -//const uint32_t free = 0x0002; -const uint32_t RS_CHAT_FOCUS = 0x0004; -const uint32_t RS_CHAT_TABBED_WINDOW = 0x0008; -const uint32_t RS_CHAT_BLINK = 0x0010; - -const uint32_t RS_FEED_TYPE_PEER = 0x0010; -const uint32_t RS_FEED_TYPE_CHANNEL = 0x0020; -const uint32_t RS_FEED_TYPE_FORUM = 0x0040; -//const uint32_t RS_FEED_TYPE_BLOG = 0x0080; -const uint32_t RS_FEED_TYPE_CHAT = 0x0100; -const uint32_t RS_FEED_TYPE_MSG = 0x0200; -const uint32_t RS_FEED_TYPE_FILES = 0x0400; -const uint32_t RS_FEED_TYPE_SECURITY = 0x0800; -const uint32_t RS_FEED_TYPE_POSTED = 0x1000; -const uint32_t RS_FEED_TYPE_SECURITY_IP = 0x2000; -const uint32_t RS_FEED_TYPE_CIRCLE = 0x4000; - -const uint32_t RS_FEED_ITEM_PEER_CONNECT = RS_FEED_TYPE_PEER | 0x0001; -const uint32_t RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x0002; -const uint32_t RS_FEED_ITEM_PEER_HELLO = RS_FEED_TYPE_PEER | 0x0003; -const uint32_t RS_FEED_ITEM_PEER_NEW = RS_FEED_TYPE_PEER | 0x0004; -const uint32_t RS_FEED_ITEM_PEER_OFFSET = RS_FEED_TYPE_PEER | 0x0005; -const uint32_t RS_FEED_ITEM_PEER_DENIES_CONNEXION = RS_FEED_TYPE_PEER | 0x0006; - -const uint32_t RS_FEED_ITEM_SEC_CONNECT_ATTEMPT = RS_FEED_TYPE_SECURITY | 0x0001; -const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED = RS_FEED_TYPE_SECURITY | 0x0002; // locally denied connection -const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_IN = RS_FEED_TYPE_SECURITY | 0x0003; -const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_OUT = RS_FEED_TYPE_SECURITY | 0x0004; -const uint32_t RS_FEED_ITEM_SEC_WRONG_SIGNATURE = RS_FEED_TYPE_SECURITY | 0x0005; -const uint32_t RS_FEED_ITEM_SEC_BAD_CERTIFICATE = RS_FEED_TYPE_SECURITY | 0x0006; -const uint32_t RS_FEED_ITEM_SEC_INTERNAL_ERROR = RS_FEED_TYPE_SECURITY | 0x0007; -const uint32_t RS_FEED_ITEM_SEC_MISSING_CERTIFICATE = RS_FEED_TYPE_SECURITY | 0x0008; - -const uint32_t RS_FEED_ITEM_SEC_IP_BLACKLISTED = RS_FEED_TYPE_SECURITY_IP | 0x0001; -const uint32_t RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED = RS_FEED_TYPE_SECURITY_IP | 0x0002; - -const uint32_t RS_FEED_ITEM_CHANNEL_NEW = RS_FEED_TYPE_CHANNEL | 0x0001; -//const uint32_t RS_FEED_ITEM_CHANNEL_UPDATE = RS_FEED_TYPE_CHANNEL | 0x0002; -const uint32_t RS_FEED_ITEM_CHANNEL_MSG = RS_FEED_TYPE_CHANNEL | 0x0003; -const uint32_t RS_FEED_ITEM_CHANNEL_PUBLISHKEY = RS_FEED_TYPE_CHANNEL | 0x0004; - -const uint32_t RS_FEED_ITEM_FORUM_NEW = RS_FEED_TYPE_FORUM | 0x0001; -//const uint32_t RS_FEED_ITEM_FORUM_UPDATE = RS_FEED_TYPE_FORUM | 0x0002; -const uint32_t RS_FEED_ITEM_FORUM_MSG = RS_FEED_TYPE_FORUM | 0x0003; -const uint32_t RS_FEED_ITEM_FORUM_PUBLISHKEY = RS_FEED_TYPE_FORUM | 0x0004; - -//const uint32_t RS_FEED_ITEM_BLOG_NEW = RS_FEED_TYPE_BLOG | 0x0001; -//const uint32_t RS_FEED_ITEM_BLOG_UPDATE = RS_FEED_TYPE_BLOG | 0x0002; -//const uint32_t RS_FEED_ITEM_BLOG_MSG = RS_FEED_TYPE_BLOG | 0x0003; - -const uint32_t RS_FEED_ITEM_POSTED_NEW = RS_FEED_TYPE_POSTED | 0x0001; -//const uint32_t RS_FEED_ITEM_POSTED_UPDATE = RS_FEED_TYPE_POSTED | 0x0002; -const uint32_t RS_FEED_ITEM_POSTED_MSG = RS_FEED_TYPE_POSTED | 0x0003; - -const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001; -const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001; -const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001; - -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001; -const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_REC = RS_FEED_TYPE_CIRCLE | 0x0002; -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003; -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004; -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED = RS_FEED_TYPE_CIRCLE | 0x0005; -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOKED = RS_FEED_TYPE_CIRCLE | 0x0006; -const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED= RS_FEED_TYPE_CIRCLE | 0x0007; - -const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001; - -const int NOTIFY_LIST_NEIGHBOURS = 1; -const int NOTIFY_LIST_FRIENDS = 2; -const int NOTIFY_LIST_SEARCHLIST = 4; -const int NOTIFY_LIST_MESSAGELIST = 5; -const int NOTIFY_LIST_CHANNELLIST = 6; -const int NOTIFY_LIST_TRANSFERLIST = 7; -const int NOTIFY_LIST_CONFIG = 8; -const int NOTIFY_LIST_DIRLIST_LOCAL = 9; -const int NOTIFY_LIST_DIRLIST_FRIENDS = 10; -const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection -const int NOTIFY_LIST_MESSAGE_TAGS = 12; -const int NOTIFY_LIST_PUBLIC_CHAT = 13; -const int NOTIFY_LIST_PRIVATE_INCOMING_CHAT = 14; -const int NOTIFY_LIST_PRIVATE_OUTGOING_CHAT = 15; -const int NOTIFY_LIST_GROUPLIST = 16; -const int NOTIFY_LIST_CHANNELLIST_LOCKED = 17; // use connect with Qt::QueuedConnection -const int NOTIFY_LIST_CHAT_LOBBY_INVITATION = 18; -const int NOTIFY_LIST_CHAT_LOBBY_LIST = 19; - -const int NOTIFY_TYPE_SAME = 0x01; -const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */ -const int NOTIFY_TYPE_ADD = 0x04; /* flagged additions */ -const int NOTIFY_TYPE_DEL = 0x08; /* flagged deletions */ - -const uint32_t NOTIFY_HASHTYPE_EXAMINING_FILES = 1; /* Examining shared files */ -const uint32_t NOTIFY_HASHTYPE_FINISH = 2; /* Finish */ -const uint32_t NOTIFY_HASHTYPE_HASH_FILE = 3; /* Hashing file */ -const uint32_t NOTIFY_HASHTYPE_SAVE_FILE_INDEX = 4; /* Hashing file */ - -class RS_DEPRECATED RsFeedItem -{ - public: - RsFeedItem(uint32_t type, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, uint32_t result1) - :mType(type), mId1(id1), mId2(id2), mId3(id3), mId4(id4), mResult1(result1) {} - - RsFeedItem() :mType(0), mResult1(0) { return; } - - uint32_t mType; - std::string mId1, mId2, mId3, mId4; - uint32_t mResult1; -}; - -// This class implements a generic notify client. To have your own components being notified by -// the Retroshare library, sub-class NotifyClient, and overload the methods you want to make use of -// (The other methods will just ignore the call), and register your ownclient into RsNotify, as: -// -// myNotifyClient: public NotifyClient -// { -// public: -// virtual void void notifyPeerHasNewAvatar(std::string peer_id) -// { -// doMyOwnThing() ; -// } -// } -// -// myNotifyClient *client = new myNotifyClient() ; -// -// rsNotify->registerNotifyClient(client) ; -// -// This mechanism can be used in plugins, new services, etc. -// - -class RS_DEPRECATED NotifyClient; - -class RS_DEPRECATED_FOR(RsEvents) RsNotify -{ - public: - /* registration of notifies clients */ - virtual void registerNotifyClient(NotifyClient *nc) = 0; - /* returns true if NotifyClient was found */ - virtual bool unregisterNotifyClient(NotifyClient *nc) = 0; - - /* Pull methods for retroshare-gui */ - /* this should probably go into a different service. */ - - virtual bool NotifySysMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg) = 0; - virtual bool NotifyPopupMessage(uint32_t &ptype, std::string &name, std::string &title, std::string &msg) = 0; - virtual bool NotifyLogMessage(uint32_t &sysid, uint32_t &type, std::string &title, std::string &msg) = 0; - - virtual bool GetFeedItem(RsFeedItem &item) = 0; - - virtual bool cachePgpPassphrase (const std::string& /* pgp_passphrase */) { return false ; } - virtual bool clearPgpPassphrase () { return false ; } - - virtual bool setDisableAskPassword (const bool /*bValue*/) { return false ; } -}; - -class RS_DEPRECATED NotifyClient -{ -public: - NotifyClient() {} - virtual ~NotifyClient() {} - - virtual void notifyListPreChange (int /* list */, int /* type */) {} - virtual void notifyListChange (int /* list */, int /* type */) {} - virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {} - virtual void notifyChatMessage (const ChatMessage& /* msg */) {} - virtual void notifyChatStatus (const ChatId& /* chat_id */, const std::string& /* status_string */) {} - virtual void notifyChatCleared (const ChatId& /* chat_id */) {} - virtual void notifyChatLobbyEvent (uint64_t /* lobby id */, uint32_t /* event type */ ,const RsGxsId& /* nickname */,const std::string& /* any string */) {} - virtual void notifyChatLobbyTimeShift (int /* time_shift*/) {} - virtual void notifyCustomState (const std::string& /* peer_id */, const std::string& /* status_string */) {} - virtual void notifyHashingInfo (uint32_t /* type */, const std::string& /* fileinfo */) {} - virtual void notifyTurtleSearchResult (const RsPeerId& /* pid */, uint32_t /* search_id */, const std::list& /* files */) {} - virtual void notifyPeerHasNewAvatar (std::string /* peer_id */) {} - virtual void notifyOwnAvatarChanged () {} - virtual void notifyOwnStatusMessageChanged () {} - virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {} - virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {} - - /* one or more peers has changed the states */ - virtual void notifyPeerStatusChangedSummary () {} - virtual void notifyDiscInfoChanged () {} - - virtual void notifyDownloadComplete (const std::string& /* fileHash */) {} - virtual void notifyDownloadCompleteCount (uint32_t /* count */) {} - virtual void notifyHistoryChanged (uint32_t /* msgId */, int /* type */) {} - - virtual bool askForPassword (const std::string& /* title */, const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */,bool& /* cancelled */ ) { return false ;} - virtual bool askForPluginConfirmation (const std::string& /* plugin_filename */, const std::string& /* plugin_file_hash */,bool /* first_time */) { return false ;} -}; diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h deleted file mode 100644 index 3fdbbaf17..000000000 --- a/libretroshare/src/retroshare/rspeers.h +++ /dev/null @@ -1,997 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rspeers.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 by Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "retroshare/rstypes.h" -#include "retroshare/rsfiles.h" -#include "retroshare/rsids.h" -#include "util/rsurl.h" -#include "util/rsdeprecate.h" -#include "util/rstime.h" -#include "retroshare/rsevents.h" - -class RsPeers; - -/** - * Pointer to global instance of RsPeers service implementation - * @jsonapi{development} - */ -extern RsPeers* rsPeers; - -/* TODO: 2015/12/31 As for type safetyness all those constant must be declared as enum! - * C++ now supports typed enum so there is no ambiguity in serialization size - */ - -/* Trust Levels. Should be the same values than what is declared in PGPHandler.h */ - -const uint32_t RS_TRUST_LVL_UNDEFINED = 0; -const uint32_t RS_TRUST_LVL_UNKNOWN = 1; -const uint32_t RS_TRUST_LVL_NEVER = 2; -const uint32_t RS_TRUST_LVL_MARGINAL = 3; -const uint32_t RS_TRUST_LVL_FULL = 4; -const uint32_t RS_TRUST_LVL_ULTIMATE = 5; - - -const uint32_t SELF_SIGNATURE_RESULT_PENDING = 0x00; -const uint32_t SELF_SIGNATURE_RESULT_SUCCESS = 0x01; -const uint32_t SELF_SIGNATURE_RESULT_FAILED = 0x02; - -/* Net Mode */ -const uint32_t RS_NETMODE_UDP = 0x0001; -const uint32_t RS_NETMODE_UPNP = 0x0002; -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 parameter for discovery */ -const uint32_t RS_VS_DISC_OFF = 0x0000; -const uint32_t RS_VS_DISC_MINIMAL = 0x0001; -const uint32_t RS_VS_DISC_FULL = 0x0002; - -const uint32_t RS_VS_DHT_OFF = 0x0000; -const uint32_t RS_VS_DHT_PASSIVE = 0x0001; -const uint32_t RS_VS_DHT_FULL = 0x0002; - -/* State */ -const uint32_t RS_PEER_STATE_FRIEND = 0x0001; -const uint32_t RS_PEER_STATE_ONLINE = 0x0002; -const uint32_t RS_PEER_STATE_CONNECTED = 0x0004; -const uint32_t RS_PEER_STATE_UNREACHABLE= 0x0008; - -// Service option flags. -// -const ServicePermissionFlags RS_NODE_PERM_NONE ( 0x00000000 ) ;// 0x1, 0x2 and Ox4 are deprecated. -const ServicePermissionFlags RS_NODE_PERM_DIRECT_DL ( 0x00000008 ) ;// Accept to directly DL from this peer (breaks anonymity) -const ServicePermissionFlags RS_NODE_PERM_ALLOW_PUSH ( 0x00000010 ) ;// Auto-DL files recommended by this peer -const ServicePermissionFlags RS_NODE_PERM_REQUIRE_WL ( 0x00000020 ) ;// Require white list clearance for connection -const ServicePermissionFlags RS_NODE_PERM_DEFAULT = RS_NODE_PERM_DIRECT_DL ; -const ServicePermissionFlags RS_NODE_PERM_ALL = RS_NODE_PERM_DIRECT_DL | RS_NODE_PERM_ALLOW_PUSH | RS_NODE_PERM_REQUIRE_WL; - -// ... - -/* Connect state */ -const uint32_t RS_PEER_CONNECTSTATE_OFFLINE = 0; -const uint32_t RS_PEER_CONNECTSTATE_TRYING_TCP = 2; -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_I2P = 7; -const uint32_t RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN = 8; - -/* Error codes for certificate cleaning and cert parsing. Numbers should not overlap. */ - -const int RS_PEER_CERT_CLEANING_CODE_NO_ERROR = 0x00 ; -const int RS_PEER_CERT_CLEANING_CODE_UNKOWN_ERROR = 0x01 ; -const int RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG = 0x02 ; -const int RS_PEER_CERT_CLEANING_CODE_NO_END_TAG = 0x03 ; -const int RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM = 0x04 ; -const int RS_PEER_CERT_CLEANING_CODE_WRONG_NUMBER = 0x05 ; -const int RS_PEER_CERT_CLEANING_CODE_WRONG_RADIX_CHAR = 0x06 ; - -const uint32_t CERTIFICATE_PARSING_ERROR_NO_ERROR = 0x10 ; -const uint32_t CERTIFICATE_PARSING_ERROR_SIZE_ERROR = 0x11 ; -const uint32_t CERTIFICATE_PARSING_ERROR_INVALID_LOCATION_ID = 0x12 ; -const uint32_t CERTIFICATE_PARSING_ERROR_INVALID_EXTERNAL_IP = 0x13 ; -const uint32_t CERTIFICATE_PARSING_ERROR_INVALID_LOCAL_IP = 0x14 ; -const uint32_t CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION = 0x15 ; -const uint32_t CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR = 0x16 ; -const uint32_t CERTIFICATE_PARSING_ERROR_UNKNOWN_SECTION_PTAG = 0x17 ; -const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_CHECKSUM = 0x18 ; -const uint32_t CERTIFICATE_PARSING_ERROR_WRONG_VERSION = 0x19 ; -const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT = 0x1a ; -const uint32_t CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID = 0x1b ; - -const uint32_t PGP_KEYRING_REMOVAL_ERROR_NO_ERROR = 0x20 ; -const uint32_t PGP_KEYRING_REMOVAL_ERROR_CANT_REMOVE_SECRET_KEYS = 0x21 ; -const uint32_t PGP_KEYRING_REMOVAL_ERROR_CANNOT_CREATE_BACKUP = 0x22 ; -const uint32_t PGP_KEYRING_REMOVAL_ERROR_CANNOT_WRITE_BACKUP = 0x23 ; -const uint32_t PGP_KEYRING_REMOVAL_ERROR_DATA_INCONSISTENCY = 0x24 ; - -/* LinkType Flags */ - -// CONNECTION -const uint32_t RS_NET_CONN_TRANS_MASK = 0x0000ffff; -const uint32_t RS_NET_CONN_TRANS_TCP_MASK = 0x0000000f; -const uint32_t RS_NET_CONN_TRANS_TCP_UNKNOWN = 0x00000001; -const uint32_t RS_NET_CONN_TRANS_TCP_LOCAL = 0x00000002; -const uint32_t RS_NET_CONN_TRANS_TCP_EXTERNAL = 0x00000004; - -const uint32_t RS_NET_CONN_TRANS_UDP_MASK = 0x000000f0; -const uint32_t RS_NET_CONN_TRANS_UDP_UNKNOWN = 0x00000010; -const uint32_t RS_NET_CONN_TRANS_UDP_DIRECT = 0x00000020; -const uint32_t RS_NET_CONN_TRANS_UDP_PROXY = 0x00000040; -const uint32_t RS_NET_CONN_TRANS_UDP_RELAY = 0x00000080; - -const uint32_t RS_NET_CONN_TRANS_OTHER_MASK = 0x00000f00; - -const uint32_t RS_NET_CONN_TRANS_UNKNOWN = 0x00001000; - - -const uint32_t RS_NET_CONN_SPEED_MASK = 0x000f0000; -const uint32_t RS_NET_CONN_SPEED_UNKNOWN = 0x00000000; -const uint32_t RS_NET_CONN_SPEED_TRICKLE = 0x00010000; -const uint32_t RS_NET_CONN_SPEED_LOW = 0x00020000; -const uint32_t RS_NET_CONN_SPEED_NORMAL = 0x00040000; -const uint32_t RS_NET_CONN_SPEED_HIGH = 0x00080000; - -const uint32_t RS_NET_CONN_QUALITY_MASK = 0x00f00000; -const uint32_t RS_NET_CONN_QUALITY_UNKNOWN = 0x00000000; - -// THIS INFO MUST BE SUPPLIED BY PEERMGR.... -const uint32_t RS_NET_CONN_TYPE_MASK = 0x0f000000; -const uint32_t RS_NET_CONN_TYPE_UNKNOWN = 0x00000000; -const uint32_t RS_NET_CONN_TYPE_ACQUAINTANCE = 0x01000000; -const uint32_t RS_NET_CONN_TYPE_FRIEND = 0x02000000; -const uint32_t RS_NET_CONN_TYPE_SERVER = 0x04000000; -const uint32_t RS_NET_CONN_TYPE_CLIENT = 0x08000000; - -// working state of proxy - -const uint32_t RS_NET_PROXY_STATUS_UNKNOWN = 0x0000 ; -const uint32_t RS_NET_PROXY_STATUS_OK = 0x0001 ; - -// Potential certificate parsing errors. - - -/* Groups */ -static const RsNodeGroupId RS_GROUP_ID_FRIENDS ("00000000000000000000000000000001"); -static const RsNodeGroupId RS_GROUP_ID_FAMILY ("00000000000000000000000000000002"); -static const RsNodeGroupId RS_GROUP_ID_COWORKERS ("00000000000000000000000000000003"); -static const RsNodeGroupId RS_GROUP_ID_OTHERS ("00000000000000000000000000000004"); -static const RsNodeGroupId RS_GROUP_ID_FAVORITES ("00000000000000000000000000000005"); - -#define RS_GROUP_DEFAULT_NAME_FRIENDS "Friends" -#define RS_GROUP_DEFAULT_NAME_FAMILY "Family" -#define RS_GROUP_DEFAULT_NAME_COWORKERS "Co-Workers" -#define RS_GROUP_DEFAULT_NAME_OTHERS "Other Contacts" -#define RS_GROUP_DEFAULT_NAME_FAVORITES "Favorites" - -const uint32_t RS_GROUP_FLAG_STANDARD = 0x0001; - -/* A couple of helper functions for translating the numbers games */ - -std::string RsPeerTrustString(uint32_t trustLvl); -std::string RsPeerNetModeString(uint32_t netModel); -std::string RsPeerLastConnectString(uint32_t lastConnect); - -//===================================================================================================// -// Connexion and security events // -//===================================================================================================// - -enum class RsAuthSslError: uint8_t -{ -// NO_ERROR = 0x00, // enabling break windows build - MISSING_AUTHENTICATION_INFO = 0x01, - PGP_SIGNATURE_VALIDATION_FAILED = 0x02, - MISMATCHED_PGP_ID = 0x03, - NO_CERTIFICATE_SUPPLIED = 0x04, - NOT_A_FRIEND = 0x05, - MISSING_CERTIFICATE = 0x06, - IP_IS_BLACKLISTED = 0x07, - PEER_REFUSED_CONNECTION = 0x08, - UNKNOWN_ERROR = 0x09, -}; - -/** - * Event triggered by AuthSSL when authentication of a connection attempt either - * fail or success - */ -struct RsAuthSslConnectionAutenticationEvent : RsEvent -{ - RsAuthSslConnectionAutenticationEvent() : - RsEvent(RsEventType::AUTHSSL_CONNECTION_AUTENTICATION) {} - - RsPeerId mSslId; - std::string mSslCn; - RsPgpId mPgpId; - RsUrl mLocator; - std::string mErrorMsg; - RsAuthSslError mErrorCode; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mSslCn); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mLocator); - RS_SERIAL_PROCESS(mErrorMsg); - RS_SERIAL_PROCESS(mErrorCode); - } - - ~RsAuthSslConnectionAutenticationEvent() override; -}; - -enum class RsConnectionEventCode: uint8_t -{ - UNKNOWN = 0x00, - PEER_CONNECTED = 0x01, - PEER_DISCONNECTED = 0x02, - PEER_TIME_SHIFT = 0x03, // mTimeShift = time shift in seconds - PEER_REPORTS_WRONG_IP = 0x04, // mPeerLocator = address reported, mOwnLocator = own address -}; - -struct RsConnectionEvent : RsEvent -{ - RsConnectionEvent() - : RsEvent(RsEventType::PEER_CONNECTION), - mConnectionInfoCode(RsConnectionEventCode::UNKNOWN), mTimeShift(0) {} - - RsConnectionEventCode mConnectionInfoCode; - RsPeerId mSslId; - RsUrl mOwnLocator; - RsUrl mReportedLocator; - - /** If there is a time shift with the peer aka - * mConnectionInfoCode == PEER_TIME_SHIFT contains the time shift value in - * seconds */ - rstime_t mTimeShift; - - ///* @see RsEvent @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mConnectionInfoCode); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mOwnLocator); - RS_SERIAL_PROCESS(mReportedLocator); - RS_SERIAL_PROCESS(mTimeShift); - } - - ~RsConnectionEvent() override; -}; - -enum class RsNetworkEventCode: uint8_t { - UNKNOWN = 0x00, - LOCAL_IP_UPDATED = 0x01, - EXTERNAL_IP_UPDATED = 0x02, -}; - -struct RsNetworkEvent : RsEvent -{ - RsNetworkEvent() - : RsEvent(RsEventType::NETWORK), - mNetworkEventCode(RsNetworkEventCode::UNKNOWN){} - - RsNetworkEventCode mNetworkEventCode; - std::string mIPAddress; // local or external IP depending on the event type - - ///* @see RsEvent @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mNetworkEventCode); - RS_SERIAL_PROCESS(mIPAddress); - } -}; - -//===================================================================================================// -// Peer Details // -//===================================================================================================// - -/* We should definitely split this into 2 sub-structures: - * PGP info (or profile info) with all info related to PGP keys - * peer info: all network related information - * - * Plus top level information: - * isOnlyPgpDetail (this could be obsolete if the methods to query about PGP info is a different function) - * peer Id - */ -struct RsPeerDetails : RsSerializable -{ - RsPeerDetails(); - - /* Auth details */ - bool isOnlyGPGdetail; - RsPeerId id; - RsPgpId gpg_id; - - std::string name; - std::string email; - std::string location; - std::string org; - - RsPgpId issuer; - - RsPgpFingerprint fpr; /* pgp fingerprint */ - std::string authcode; // TODO: 2015/12/31 (cyril) what is this used for ????? - std::list gpgSigners; - - uint32_t trustLvl; - uint32_t validLvl; - - bool skip_pgp_signature_validation; - bool ownsign; /* we have signed the remote peer GPG key */ - bool hasSignedMe; /* the remote peer has signed my GPG key */ - - bool accept_connection; - - /* Peer permission flags. What services the peer can use (Only valid if friend).*/ - ServicePermissionFlags service_perm_flags ; - - /* Network details (only valid if friend) */ - uint32_t state; - bool actAsServer; - - // TODO: 2015/12/31 to take advantage of multiple connection this must be - // replaced by a set of addresses - std::string connectAddr ; // current address if connected. - uint16_t connectPort ; - - // Hidden Node details. - bool isHiddenNode; - std::string hiddenNodeAddress; - uint16_t hiddenNodePort; - uint32_t hiddenType; - - // Filled in for Standard Node. - std::string localAddr; - uint16_t localPort; - std::string extAddr; - uint16_t extPort; - std::string dyndns; - std::list ipAddressList; - - uint32_t netMode; - /* vis State */ - uint16_t vs_disc; - uint16_t vs_dht; - - /* basic stats */ - uint32_t lastConnect; /* how long ago */ - uint32_t lastUsed; /* how long ago since last used: signature verif, connect attempt, etc */ - uint32_t connectState; /* RS_PEER_CONNECTSTATE_... */ - std::string connectStateString; /* Additional string like ip address */ - uint32_t connectPeriod; - bool foundDHT; - - /* have we been denied */ - bool wasDeniedConnection; - rstime_t deniedTS; - - /* linkType */ - uint32_t linkType; - - /// @see RsSerializable - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(isOnlyGPGdetail); - RS_SERIAL_PROCESS(id); - RS_SERIAL_PROCESS(gpg_id); - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(email); - RS_SERIAL_PROCESS(location); - RS_SERIAL_PROCESS(org); - RS_SERIAL_PROCESS(issuer); - RS_SERIAL_PROCESS(fpr); - RS_SERIAL_PROCESS(authcode); - RS_SERIAL_PROCESS(gpgSigners); - RS_SERIAL_PROCESS(trustLvl); - RS_SERIAL_PROCESS(validLvl); - RS_SERIAL_PROCESS(ownsign); - RS_SERIAL_PROCESS(hasSignedMe); - RS_SERIAL_PROCESS(accept_connection); - RS_SERIAL_PROCESS(service_perm_flags); - RS_SERIAL_PROCESS(state); - RS_SERIAL_PROCESS(actAsServer); - RS_SERIAL_PROCESS(connectAddr); - RS_SERIAL_PROCESS(connectPort); - RS_SERIAL_PROCESS(isHiddenNode); - RS_SERIAL_PROCESS(hiddenNodeAddress); - RS_SERIAL_PROCESS(hiddenNodePort); - RS_SERIAL_PROCESS(hiddenType); - RS_SERIAL_PROCESS(localAddr); - RS_SERIAL_PROCESS(localPort); - RS_SERIAL_PROCESS(extAddr); - RS_SERIAL_PROCESS(extPort); - RS_SERIAL_PROCESS(dyndns); - RS_SERIAL_PROCESS(ipAddressList); - RS_SERIAL_PROCESS(netMode); - RS_SERIAL_PROCESS(vs_disc); - RS_SERIAL_PROCESS(vs_dht); - RS_SERIAL_PROCESS(lastConnect); - RS_SERIAL_PROCESS(lastUsed); - RS_SERIAL_PROCESS(connectState); - RS_SERIAL_PROCESS(connectStateString); - RS_SERIAL_PROCESS(connectPeriod); - RS_SERIAL_PROCESS(foundDHT); - RS_SERIAL_PROCESS(wasDeniedConnection); - RS_SERIAL_PROCESS(deniedTS); - RS_SERIAL_PROCESS(linkType); - } -}; - -// This class is used to get info about crytographic algorithms used with a -// particular peer. -struct RsPeerCryptoParams -{ - int connexion_state; - std::string cipher_name; -}; - -struct RsGroupInfo : RsSerializable -{ - RsGroupInfo(); - - RsNodeGroupId id; - std::string name; - uint32_t flag; - - std::set peerIds; - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext &ctx) - { - RS_SERIAL_PROCESS(id); - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(flag); - RS_SERIAL_PROCESS(peerIds); - } -}; - -/** Event emitted when a peer change state */ -struct RsPeerStateChangedEvent : RsEvent -{ - /// @param[in] sslId is of the peer which changed state - explicit RsPeerStateChangedEvent(RsPeerId sslId); - - /// Storage fot the id of the peer that changed state - RsPeerId mSslId; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mSslId); - } -}; - -enum class RetroshareInviteFlags:uint32_t { - NOTHING = 0x00, - CURRENT_IP = 0x01, - FULL_IP_HISTORY = 0x02, - DNS = 0x04, - RADIX_FORMAT = 0x08, - PGP_SIGNATURES = 0x10, -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RetroshareInviteFlags) - -/** The Main Interface Class - for information about your Peers - * A peer is another RS instance, means associated with an SSL certificate - * A same GPG person can have multiple peer running with different SSL certs - * signed by the same GPG key - * Thus a peer have SSL cert details, and also the parent GPG details - */ -class RsPeers -{ -public: - - /** - * @brief Get own SSL peer id - * @return own peer id - */ - virtual const RsPeerId& getOwnId() = 0; - - virtual bool haveSecretKey(const RsPgpId& gpg_id) = 0 ; - - /** - * @brief Get trusted peers list - * @jsonapi{development} - * @param[out] sslIds storage for the trusted peers - * @return false if error occurred, true otherwise - */ - virtual bool getFriendList(std::list& sslIds) = 0; - - /** - * @brief Get trusted PGP ids list - * @jsonapi{development} - * @param[out] pgpIds storage for the trusted PGP ids - * @return false if error occurred, true otherwise - */ - virtual bool getPgpFriendList(std::vector& pgpIds) = 0; - - /** - * @brief Get connected peers list - * @jsonapi{development} - * @param[out] sslIds storage for the peers - * @return false if error occurred, true otherwise - */ - virtual bool getOnlineList(std::list &sslIds) = 0; - - /** - * @brief Get peers count - * @jsonapi{development} - * @param[out] peersCount storage for trusted peers count - * @param[out] onlinePeersCount storage for online peers count - * @param[in] countLocations true to count multiple locations of same owner - * @return false if error occurred, true otherwise - */ - virtual bool getPeersCount( - uint32_t& peersCount, uint32_t& onlinePeersCount, - bool countLocations = true ) = 0; - - RS_DEPRECATED - virtual bool getPeerCount(unsigned int *pnFriendCount, unsigned int *pnnOnlineCount, bool ssl) = 0; - - /** - * @brief Check if there is an established connection to the given peer - * @jsonapi{development} - * @param[in] sslId id of the peer to check - * @return true if the connection is establisced, false otherwise - */ - virtual bool isOnline(const RsPeerId &sslId) = 0; - - /** - * @brief Check if given peer is a trusted node - * @jsonapi{development} - * @param[in] sslId id of the peer to check - * @return true if the node is trusted, false otherwise - */ - virtual bool isFriend(const RsPeerId& sslId) = 0; - - /** - * @brief Check if given PGP id is trusted - * @jsonapi{development} - * @param[in] pgpId PGP id to check - * @return true if the PGP id is trusted, false otherwise - */ - virtual bool isPgpFriend(const RsPgpId& pgpId) = 0; - - /** - * @brief Check if given peer is a trusted SSL node pending PGP approval - * Peers added through short invite remain in this state as long as their - * PGP key is not received and verified/approved by the user. - * @jsonapi{development} - * @param[in] sslId id of the peer to check - * @return true if the node is trusted, false otherwise - */ - virtual bool isSslOnlyFriend(const RsPeerId& sslId) = 0; - - virtual std::string getPeerName(const RsPeerId &ssl_id) = 0; - virtual std::string getGPGName(const RsPgpId& gpg_id) = 0; - - /** - * @brief Get details details of the given peer - * @jsonapi{development} - * @param[in] sslId id of the peer - * @param[out] det storage for the details of the peer - * @return false if error occurred, true otherwise - */ - virtual bool getPeerDetails(const RsPeerId& sslId, RsPeerDetails& det) = 0; - - virtual bool getGPGDetails(const RsPgpId& gpg_id, RsPeerDetails &d) = 0; - - /* Using PGP Ids */ - virtual const RsPgpId& getGPGOwnId() = 0; - - /** - * @brief Get PGP id for the given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer - * @return PGP id of the peer - */ - virtual RsPgpId getGPGId(const RsPeerId& sslId) = 0; - virtual bool isKeySupported(const RsPgpId& gpg_ids) = 0; - - RS_DEPRECATED_FOR(getPgpFriendList) - virtual bool getGPGAcceptedList(std::list &gpg_ids) = 0; - virtual bool getGPGSignedList(std::list &gpg_ids) = 0;// keys signed by our own PGP key. - virtual bool getGPGValidList(std::list &gpg_ids) = 0;// all PGP keys without filtering - virtual bool getGPGAllList(std::list &gpg_ids) = 0;// all PGP keys as well - virtual bool getAssociatedSSLIds(const RsPgpId& gpg_id, std::list& ids) = 0; - virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = "") = 0; - - /** - * @brief Convert PGP fingerprint to PGP id - * @jsonapi{development} - * Helper method useful while we port the whole RetroShare codebase from - * RsPgpId to RsPgpFingerprint - * @param[in] fpr PGP fingerprint to convert - * @return PGP id corresponding to the fingerprint - */ - virtual RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& fpr) = 0; - - // Note: the two methods below could be unified. The fact that one of them can take an optional RsPeerDetails struct as parameter - // seems quite inconsistent. - - /** - * @brief Add trusted node - * @jsonapi{development} - * @param[in] sslId SSL id of the node to add - * @param[in] gpgId PGP id of the node to add - * @param[in] flags service permissions flag - * @return false if error occurred, true otherwise - */ - virtual bool addFriend( - const RsPeerId& sslId, const RsPgpId& gpgId, - ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0; - - /** - * @brief Add SSL-only trusted node - * When adding an SSL-only node, it is authorized to connect. Every time a - * connection is established the user is notified about the need to verify - * the PGP fingerprint, until she does, at that point the node become a full - * SSL+PGP friend. - * @jsonapi{development} - * @param[in] sslId SSL id of the node to add - * @param[in] pgpId PGP id of the node to add. Will be used for validation when the key is available. - * @param[in] details Optional extra details known about the node to add - * @return false if error occurred, true otherwise - */ - virtual bool addSslOnlyFriend( - const RsPeerId& sslId, - const RsPgpId& pgpId, - const RsPeerDetails& details = RsPeerDetails() ) = 0; - - /** - * @brief Revoke connection trust from to node - * @jsonapi{development} - * @param[in] pgpId PGP id of the node - * @return false if error occurred, true otherwise - */ - virtual bool removeFriend(const RsPgpId& pgpId) = 0; - - /** - * @brief Remove location of a trusted node, useful to prune old unused - * locations of a trusted peer without revoking trust - * @jsonapi{development} - * @param[in] sslId SSL id of the location to remove - * @return false if error occurred, true otherwise - */ - virtual bool removeFriendLocation(const RsPeerId& sslId) = 0; - - /* keyring management */ - virtual bool removeKeysFromPGPKeyring( - const std::set& pgpIds, std::string& backupFile, - uint32_t& errorCode ) = 0; - - /* Network Stuff */ - - /** - * @brief Trigger connection attempt to given node - * @jsonapi{development} - * @param[in] sslId SSL id of the node to connect - * @return false if error occurred, true otherwise - */ - virtual bool connectAttempt(const RsPeerId& sslId) = 0; - - virtual bool setLocation(const RsPeerId &ssl_id, const std::string &location) = 0; // location is shown in the gui to differentiate ssl certs - - virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) = 0; - virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) = 0; - virtual bool isHiddenNode(const RsPeerId &id) = 0; - - /** - * @brief Add URL locator for given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] locator peer url locator - * @return false if error occurred, true otherwise - */ - virtual bool addPeerLocator(const RsPeerId& sslId, const RsUrl& locator) = 0; - - /** - * @brief Set local IPv4 address for the given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] addr string representation of the local IPv4 address - * @param[in] port local listening port - * @return false if error occurred, true otherwise - */ - virtual bool setLocalAddress( - const RsPeerId& sslId, const std::string& addr, uint16_t port ) = 0; - - /** - * @brief Set external IPv4 address for given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] addr string representation of the external IPv4 address - * @param[in] port external listening port - * @return false if error occurred, true otherwise - */ - virtual bool setExtAddress( - const RsPeerId& sslId, const std::string &addr, uint16_t port ) = 0; - - /** - * @brief Set (dynamical) domain name associated to the given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] addr domain name string representation - * @return false if error occurred, true otherwise - */ - virtual bool setDynDNS(const RsPeerId& sslId, const std::string& addr) = 0; - - /** - * @brief Set network mode of the given peer - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] netMode one of RS_NETMODE_* - * @return false if error occurred, true otherwise - */ - virtual bool setNetworkMode(const RsPeerId &sslId, uint32_t netMode) = 0; - - /** - * @brief set DHT and discovery modes - * @jsonapi{development} - * @param[in] sslId SSL id of the peer, own id is accepted too - * @param[in] vsDisc one of RS_VS_DISC_* - * @param[in] vsDht one of RS_VS_DHT_* - * @return false if error occurred, true otherwise - */ - virtual bool setVisState( const RsPeerId& sslId, - uint16_t vsDisc, uint16_t vsDht ) = 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; - virtual bool resetOwnExternalAddressList() = 0; - virtual bool getAllowServerIPDetermination() = 0 ; - - /** - * @brief Get RetroShare invite of the given peer - * @jsonapi{development} - * @param[in] sslId Id of the peer of which we want to generate an invite, - * a null id (all 0) is passed, an invite for own node is returned. - * @param[in] inviteFlags specify extra data to include in the invite - * @return invite string - */ - virtual std::string GetRetroshareInvite( - const RsPeerId& sslId = RsPeerId(), - RetroshareInviteFlags inviteFlags = - RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP ) = 0; - - /** - * @brief Get RetroShare short invite of the given peer - * @jsonapi{development} - * @param[out] invite storage for the generated invite - * @param[in] sslId Id of the peer of which we want to generate an invite, - * a null id (all 0) is passed, an invite for own node is returned. - * @param[in] inviteFlags specify extra data to include in the invite and - * format. - * @param[in] baseUrl URL into which to sneak in the RetroShare invite - * radix, this is primarly useful to trick other applications into making - * the invite clickable, or to disguise the RetroShare invite into a - * "normal" looking web link. Used only if formatRadix is false. - * @return false if error occurred, true otherwise - */ - virtual bool getShortInvite( - std::string& invite, const RsPeerId& sslId = RsPeerId(), - RetroshareInviteFlags inviteFlags = - RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::DNS, - const std::string& baseUrl = "https://retroshare.me/" ) = 0; - - /** - * @brief Parse the give short invite to extract contained information - * @jsonapi{development} - * @param[in] invite string containing the short invite to parse - * @param[out] details storage for the extracted information, consider it - * @param[out] err_code storage for the error code - * @return false if error occurred, true otherwise - */ - virtual bool parseShortInvite( - const std::string& invite, RsPeerDetails& details,uint32_t& err_code ) = 0; - - /** - * @brief Add trusted node from invite - * @jsonapi{development} - * @param[in] invite invite string being it in cert or URL format - * @param[in] flags service permissions flag - * @return false if error occurred, true otherwise - */ - virtual bool acceptInvite( - const std::string& invite, - ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0; - - - RS_DEPRECATED /// This function doesn't provide meaningful error reporting - virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) = 0; - virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum) = 0; - - /** - * @brief Import certificate into the keyring - * @jsonapi{development} - * @param[in] cert string representation of the certificate - * @param[out] sslId storage for the SSL id of the certificate - * @param[out] pgpId storage for the PGP id of the certificate - * @param[out] errorString storage for the possible error string - * @return false if error occurred, true otherwise - */ - virtual bool loadCertificateFromString( - const std::string& cert, RsPeerId& sslId, RsPgpId& pgpId, - std::string& errorString) = 0; - - /** - * @brief Examine certificate and get details without importing into - * the keyring - * @jsonapi{development} - * @param[in] cert string representation of the certificate - * @param[out] certDetails storage for the certificate details - * @param[out] errorCode storage for possible error number - * @return false if error occurred, true otherwise - */ - virtual bool loadDetailsFromStringCert( - const std::string& cert, RsPeerDetails& certDetails, - uint32_t& errorCode ) = 0; - - virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data, - uint32_t bin_key_len, - RsPgpId& gpg_id, - std::string& error_string )=0; - - // Certificate utils - virtual bool cleanCertificate( - const std::string& certstr, std::string& cleanCert, - bool& is_short_format, uint32_t& error_code ) = 0; - virtual std::string saveCertificateToString(const RsPeerId &id) = 0; - - virtual bool signGPGCertificate(const RsPgpId &gpg_id,const std::string& gpg_passphrase) = 0; - virtual bool trustGPGCertificate(const RsPgpId &gpg_id, uint32_t trustlvl) = 0; - - /* Group Stuff */ - /** - * @brief addGroup create a new group - * @jsonapi{development} - * @param[in] groupInfo - * @return - */ - virtual bool addGroup(RsGroupInfo& groupInfo) = 0; - - /** - * @brief editGroup edit an existing group - * @jsonapi{development} - * @param[in] groupId - * @param[in] groupInfo - * @return - */ - virtual bool editGroup(const RsNodeGroupId& groupId, RsGroupInfo& groupInfo) = 0; - - /** - * @brief removeGroup remove a group - * @jsonapi{development} - * @param[in] groupId - * @return - */ - virtual bool removeGroup(const RsNodeGroupId& groupId) = 0; - - /** - * @brief getGroupInfo get group information to one group - * @jsonapi{development} - * @param[in] groupId - * @param[out] groupInfo - * @return - */ - virtual bool getGroupInfo(const RsNodeGroupId& groupId, RsGroupInfo& groupInfo) = 0; - - /** - * @brief getGroupInfoByName get group information by group name - * @jsonapi{development} - * @param[in] groupName - * @param[out] groupInfo - * @return - */ - virtual bool getGroupInfoByName(const std::string& groupName, RsGroupInfo& groupInfo) = 0; - - /** - * @brief getGroupInfoList get list of all groups - * @jsonapi{development} - * @param[out] groupInfoList - * @return - */ - virtual bool getGroupInfoList(std::list& groupInfoList) = 0; - - // groupId == "" && assign == false -> remove from all groups - /** - * @brief assignPeerToGroup add a peer to a group - * @jsonapi{development} - * @param[in] groupId - * @param[in] peerId - * @param[in] assign true to assign a peer, false to remove a peer - * @return - */ - virtual bool assignPeerToGroup(const RsNodeGroupId& groupId, const RsPgpId& peerId, bool assign) = 0; - - /** - * @brief assignPeersToGroup add a list of peers to a group - * @jsonapi{development} - * @param[in] groupId - * @param[in] peerIds - * @param[in] assign true to assign a peer, false to remove a peer - * @return - */ - virtual bool assignPeersToGroup(const RsNodeGroupId& groupId, const std::list& peerIds, bool assign) = 0; - - /* Group sharing permission */ - - // Given - // - the peer id - // - the permission flags of a given hash, e.g. a combination of - // RS_DIR_FLAGS_NETWORK_WIDE_OTHERS, RS_DIR_FLAGS_NETWORK_WIDE_GROUPS, RS_DIR_FLAGS_BROWSABLE_OTHERS and RS_DIR_FLAGS_BROWSABLE_GROUPS - // - the parent groups of the file - // - // ... computes the sharing file permission hint flags set for this peer, that is a combination of - // RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE. - // - virtual FileSearchFlags computePeerPermissionFlags( - const RsPeerId& peer_id, FileStorageFlags file_sharing_flags, - const std::list& file_parent_groups) = 0; - - /* Service permission flags */ - - virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) = 0; - virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) = 0; - virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) = 0; - - virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) =0; - virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0; - virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0; - - RS_DEPRECATED_FOR(isPgpFriend) - virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend) = 0; - - virtual ~RsPeers(); -}; diff --git a/libretroshare/src/retroshare/rsphoto.h b/libretroshare/src/retroshare/rsphoto.h deleted file mode 100644 index 839b28a90..000000000 --- a/libretroshare/src/retroshare/rsphoto.h +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsphoto.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2020 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSPHOTOV2_H -#define RSPHOTOV2_H - -#include -#include -#include -#include "retroshare/rsgxsservice.h" -#include "retroshare/rsgxscommon.h" -#include "retroshare/rsgxsifacehelper.h" - - -/* The Main Interface Class - for information about your Peers */ -class RsPhoto; -extern RsPhoto *rsPhoto; - -class RsPhotoPhoto -{ -public: - - RsMsgMetaData mMeta; - - RsPhotoPhoto(); - - // V2 PhotoMsg - keep it simple. - // mMeta.mTitle used for Photo Caption. - // mDescription optional field for addtional notes. - // mLowResImage - < 50k jpg of image. - // mPhotoFile - transfer details for original photo. - std::string mDescription; - uint32_t mOrder; - RsGxsImage mLowResImage; - RsGxsFile mPhotoFile; - - // These are not saved. - std::string mPath; // if New photo -}; - -#define RSPHOTO_SHAREMODE_LOWRESONLY (1) -#define RSPHOTO_SHAREMODE_ORIGINAL (2) -#define RSPHOTO_SHAREMODE_DUP_ORIGINAL (3) -#define RSPHOTO_SHAREMODE_DUP_200K (4) -#define RSPHOTO_SHAREMODE_DUP_1M (5) - -struct RsPhotoAlbum: RsGxsGenericGroupData -{ - RsPhotoAlbum(); - - // V2 Album - keep it simple. - // mMeta.mTitle. - uint32_t mShareMode; - - std::string mCaption; - std::string mDescription; - std::string mPhotographer; - std::string mWhere; - std::string mWhen; - - RsGxsImage mThumbnail; - - // Below is not saved. - bool mAutoDownload; -}; - -std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo); -std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album); - -typedef std::map > PhotoResult; - -class RsPhoto: public RsGxsIfaceHelper, public RsGxsCommentService -{ -public: - explicit RsPhoto(RsGxsIface &gxs) : RsGxsIfaceHelper(gxs) { return; } - - virtual ~RsPhoto() { return; } - - /*! - * Use to enquire if groups or msgs have changed - * Poll regularly, particularly after a photo submission - * @return true if msgs or groups have changed - */ - virtual bool updated() = 0; - - /*! - * - * @param grpIds - */ - virtual void groupsChanged(std::list& grpIds) = 0; - - /*! - * - * @param msgs - */ - virtual void msgsChanged(GxsMsgIdResult& msgs) = 0; - - /*! - * To acquire a handle to token service handler - * needed to make requests to the service - * @return handle to token service for this gxs service - */ - virtual RsTokenService* getTokenService() = 0; - - /* Generic Lists */ - - /*! - * - * @param token token to be redeemed for this request - * @param groupIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupList(const uint32_t &token, - std::list &groupIds) = 0; - - /*! - * @param token token to be redeemed for this request - * @param msgIds the ids return for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgList(const uint32_t &token, - GxsMsgIdResult &msgIds) = 0; - - /* Generic Summary */ - - /*! - * @param token token to be redeemed for group summary request - * @param groupInfo the ids returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getGroupSummary(const uint32_t &token, - std::list &groupInfo) = 0; - - /*! - * @param token token to be redeemed for message summary request - * @param msgInfo the message metadata returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getMsgSummary(const uint32_t &token, - MsgMetaResult &msgInfo) = 0; - - /* Specific Service Data */ - - /*! - * @param token token to be redeemed for album request - * @param album the album returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getAlbum(const uint32_t &token, std::vector &album) = 0; - - /*! - * @param token token to be redeemed for photo request - * @param photo the photo returned for given request token - * @return false if request token is invalid, check token status for error report - */ - virtual bool getPhoto(const uint32_t &token, - PhotoResult &photo) = 0; - - /*! - * submits album, which returns a token that needs - * to be acknowledge to get album grp id - * @param token token to redeem for acknowledgement - * @param album album to be submitted - */ - virtual bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) = 0; - - /*! - * submits photo, which returns a token that needs - * to be acknowledged to get photo msg-grp id pair - * @param token token to redeem for acknowledgement - * @param photo photo to be submitted - */ - virtual bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) = 0; - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - virtual bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) = 0; - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) = 0; - - - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - virtual bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) = 0; - - // Blocking versions. - /*! - * request to create a new album. Blocks until process completes. - * @param album album to be submitted - * @return true if created false otherwise - */ - virtual bool createAlbum(RsPhotoAlbum &album) = 0; - - /*! - * request to update an existing album. Blocks until process completes. - * @param album album to be submitted - * @return true if created false otherwise - */ - virtual bool updateAlbum(const RsPhotoAlbum &album) = 0; - - /*! - * retrieve albums based in groupIds. - * @param groupIds the ids to fetch. - * @param albums vector to be filled by request. - * @return true is successful, false otherwise. - */ - virtual bool getAlbums(const std::list &groupIds, - std::vector &albums) = 0; -}; - - -#endif // RSPHOTOV2_H diff --git a/libretroshare/src/retroshare/rsplugin.h b/libretroshare/src/retroshare/rsplugin.h deleted file mode 100644 index 1efa70399..000000000 --- a/libretroshare/src/retroshare/rsplugin.h +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsplugin.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "util/rstime.h" -#include -#include -#include -#include -#include "retroshare/rspeers.h" -#include "retroshare/rsfiles.h" -#include "retroshare/rsversion.h" -#include "util/rsinitedptr.h" -#include "retroshare/rsdisc.h" - -class RsPluginHandler ; -extern RsPluginHandler *rsPlugins ; - -class p3Service ; -class RsServiceControl ; -class RsReputations ; -class RsTurtle ; -class RsGxsTunnelService ; -class RsDht ; -class RsMsgs ; -class RsGxsForums; -class RsGxsChannels; -class RsNotify; -class RsServiceControl; -class p3LinkMgr ; -class MainPage ; -class QIcon ; -class QString ; -class QDialog ; -class QWidget ; -class QTranslator; -class QApplication; -class RsCacheService ; -class ftServer ; -class ConfigPage ; -class RsPQIService ; -class RsAutoUpdatePage ; -class SoundEvents; -class FeedNotify; -class ToasterNotify; -class ChatWidget; -class ChatWidgetHolder; -// for gxs based plugins -struct RsIdentity; -class RsNxsNetMgr; -class RsGxsIdExchange; -class RsGcxs; -class PgpAuxUtils; -class p3Config; - -namespace resource_api -{ - class ResourceRouter; - class StateTokenServer; -} - -// Plugin API version. Not used yet, but will be in the future the -// main value that decides for compatibility. -// -#define RS_PLUGIN_API_VERSION 0x000101 - -// Used for the status of plugins. -// -#define PLUGIN_STATUS_NO_STATUS 0x0000 -#define PLUGIN_STATUS_REJECTED_HASH 0x0001 -#define PLUGIN_STATUS_DLOPEN_ERROR 0x0002 -#define PLUGIN_STATUS_MISSING_SYMBOL 0x0003 -#define PLUGIN_STATUS_NULL_PLUGIN 0x0004 -#define PLUGIN_STATUS_LOADED 0x0005 -#define PLUGIN_STATUS_WRONG_API 0x0006 -#define PLUGIN_STATUS_MISSING_API 0x0007 -#define PLUGIN_STATUS_MISSING_SVN 0x0008 - -class RsPluginHandler; - -/*! - * - * convenience class to store gui interfaces - * - */ -class RsPlugInInterfaces { -public: - RsUtil::inited_ptr mPeers; - RsUtil::inited_ptr mFiles; - RsUtil::inited_ptr mMsgs; - RsUtil::inited_ptr mTurtle; - RsUtil::inited_ptr mDisc; - RsUtil::inited_ptr mDht; - RsUtil::inited_ptr mNotify; - RsUtil::inited_ptr mServiceControl; - RsUtil::inited_ptr mPluginHandler; - - // gxs - std::string mGxsDir; - RsUtil::inited_ptr mIdentity; - RsUtil::inited_ptr mRsNxsNetMgr; - RsUtil::inited_ptr mGxsIdService; - RsUtil::inited_ptr mGxsCirlces; - RsUtil::inited_ptr mPgpAuxUtils; - RsUtil::inited_ptr mGxsForums; - RsUtil::inited_ptr mGxsChannels; - RsUtil::inited_ptr mGxsTunnels; - RsUtil::inited_ptr mReputations; -}; - -class RsPlugin -{ - public: - RsPlugin() {} - virtual ~RsPlugin() {} - - // - //================================ Services ==================================// - // - // Cache service. Use this for providing cache-based services, such as channels, forums. - // Example plugin: LinksCloud - // - virtual RsCacheService *rs_cache_service() const { return NULL ; } - - // Peer-to-Peer service. Use this for providing a service based to friend to friend - // exchange of data, such as chat, messages, etc. - // Example plugin: VOIP - // - //virtual RsPQIService *rs_pqi_service() const { return NULL ; } - // gxs netservice is not a RsPQIService - // so have two fns which result in the same gxs netservice to be returned - virtual p3Service *p3_service() const { return NULL ; } - virtual p3Config *p3_config() const { return NULL ; } - virtual uint16_t rs_service_id() const { return 0 ; } - - - // creates a new resource api handler object. ownership is transferred to the caller. - // the caller should supply a statetokenserver, and keep it valid until destruction - // the plugin should return a entry point name. this is to make the entry point name independent from file names - virtual resource_api::ResourceRouter* new_resource_api_handler(const RsPlugInInterfaces& /* ifaces */, resource_api::StateTokenServer* /* sts */, std::string & /*entrypoint*/) const { return 0;} - - // Shutdown - virtual void stop() {} - - // Filename used for saving the specific plugin configuration. Both RsCacheService and RsPQIService - // derive from p3Config, which means that the service provided by the plugin can load/save its own - // config by deriving loadList() and saveList() from p3Config. - // - virtual std::string configurationFileName() const - { - std::cerr << "(EE) Plugin configuration file name requested in non overloaded method! Plugin code should derive configurationFileName() method!" << std::endl; - return std::string() ; - } - - // - //=================================== GUI ====================================// - // - // Derive the following methods to provide GUI additions to RetroShare's GUI. - // - // Main page: like Transfers, Channels, Forums, etc. - // - virtual MainPage *qt_page() const { return NULL ; } // The page itself - virtual QIcon *qt_icon() const { return NULL ; } // the page icon. Todo: put icon as virtual in MainPage - - virtual QWidget *qt_config_panel() const { return NULL ; } // Config panel, to appear config->plugins->[]-> - virtual QDialog *qt_about_page() const { return NULL ; } // About/Help button in plugin entry will show this up - virtual ConfigPage *qt_config_page() const { return NULL ; } // Config tab to add in config panel. - virtual RsAutoUpdatePage *qt_transfers_tab() const { return NULL ; } // Tab to add in transfers, after turtle statistics. - virtual std::string qt_transfers_tab_name()const { return "Tab" ; } // Tab name - virtual void qt_sound_events(SoundEvents &/*events*/) const { } // Sound events - - // Provide buttons for the ChatWidget - virtual ChatWidgetHolder *qt_get_chat_widget_holder(ChatWidget */*chatWidget*/) const { return NULL ; } - - virtual std::string qt_stylesheet() { return ""; } - virtual QTranslator *qt_translator(QApplication * /* app */, const QString& /* languageCode */, const QString& /* externalDir */ ) const { return NULL ; } - - // - //================================== Notify ==================================// - // - virtual FeedNotify *qt_feedNotify() { return NULL; } - virtual ToasterNotify *qt_toasterNotify() { return NULL; } - - // - //========================== Plugin Description ==============================// - // - // All these items appear in the config->plugins tab, as a description of the plugin. - // - uint32_t getSvnRevision() const { return 0; } // This is read from libretroshare/retroshare/rsversion.h - - virtual std::string getShortPluginDescription() const = 0 ; - virtual std::string getPluginName() const = 0 ; - virtual void getPluginVersion(int& major,int& minor, int& build, int& svn_rev) const = 0 ; - virtual void getLibraries(std::list & /*libraries*/) {} - - // - //========================== Plugin Interface ================================// - // - // Use these methods to access main objects from RetroShare. - // - virtual void setInterfaces(RsPlugInInterfaces& interfaces) = 0; - virtual void setPlugInHandler(RsPluginHandler* pgHandler) = 0; -}; - -class RsPluginHandler -{ - public: - // Returns the number of loaded plugins. - // - virtual int nbPlugins() const = 0 ; - virtual RsPlugin *plugin(int i) = 0 ; - virtual const std::vector& getPluginDirectories() const = 0; - virtual void getPluginStatus(int i,uint32_t& status,std::string& file_name,RsFileHash& file_hash,uint32_t& svn_revision,std::string& error_string) const = 0 ; - virtual void enablePlugin(const RsFileHash& hash) = 0; - virtual void disablePlugin(const RsFileHash& hash) = 0; - - virtual void allowAllPlugins(bool b) = 0 ; - virtual bool getAllowAllPlugins() const = 0 ; - - virtual void slowTickPlugins(rstime_t sec) = 0 ; - - virtual const std::string& getLocalCacheDir() const =0; - virtual const std::string& getRemoteCacheDir() const =0; - - virtual RsServiceControl *getServiceControl() const = 0; -}; - - - diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h deleted file mode 100644 index bdcaa3798..000000000 --- a/libretroshare/src/retroshare/rsposted.h +++ /dev/null @@ -1,228 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsposted.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2008-2012 Robert Fernie, Christopher Evi-Parker * - * Copyright (C) 2020 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsgxscommon.h" -#include "serialiser/rsserializable.h" - -class RsPosted; - -/** - * Pointer to global instance of RsGxsChannels service implementation - * @jsonapi{development} - */ -extern RsPosted* rsPosted; - -struct RsPostedGroup: RsGxsGenericGroupData -{ - std::string mDescription; - RsGxsImage mGroupImage; -}; - -struct RsPostedPost: public RsGxsGenericMsgData -{ - RsPostedPost(): mHaveVoted(false), mUpVotes(0), mDownVotes(0), mComments(0), - mHotScore(0), mTopScore(0), mNewScore(0) {} - - bool calculateScores(rstime_t ref_time); - - std::string mLink; - std::string mNotes; - - bool mHaveVoted; - - // Calculated. - uint32_t mUpVotes; - uint32_t mDownVotes; - uint32_t mComments; - - - // and Calculated Scores:??? - double mHotScore; - double mTopScore; - double mNewScore; - - RsGxsImage mImage; - - /// @see RsSerializable - /*virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(mImage); - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mLink); - RS_SERIAL_PROCESS(mHaveVoted); - RS_SERIAL_PROCESS(mUpVotes); - RS_SERIAL_PROCESS(mDownVotes); - RS_SERIAL_PROCESS(mComments); - RS_SERIAL_PROCESS(mHotScore); - RS_SERIAL_PROCESS(mTopScore); - RS_SERIAL_PROCESS(mNewScore); - }*/ -}; - - -//#define RSPOSTED_MSGTYPE_POST 0x0001 -//#define RSPOSTED_MSGTYPE_VOTE 0x0002 -//#define RSPOSTED_MSGTYPE_COMMENT 0x0004 - -#define RSPOSTED_PERIOD_YEAR 1 -#define RSPOSTED_PERIOD_MONTH 2 -#define RSPOSTED_PERIOD_WEEK 3 -#define RSPOSTED_PERIOD_DAY 4 -#define RSPOSTED_PERIOD_HOUR 5 - -#define RSPOSTED_VIEWMODE_LATEST 1 -#define RSPOSTED_VIEWMODE_TOP 2 -#define RSPOSTED_VIEWMODE_HOT 3 -#define RSPOSTED_VIEWMODE_COMMENTS 4 - - -enum class RsPostedEventCode: uint8_t -{ - UNKNOWN = 0x00, - NEW_POSTED_GROUP = 0x01, - NEW_MESSAGE = 0x02, - SUBSCRIBE_STATUS_CHANGED = 0x03, - UPDATED_POSTED_GROUP = 0x04, - UPDATED_MESSAGE = 0x05, - READ_STATUS_CHANGED = 0x06, - STATISTICS_CHANGED = 0x07, - MESSAGE_VOTES_UPDATED = 0x08, - SYNC_PARAMETERS_UPDATED = 0x09, - NEW_COMMENT = 0x0a, - NEW_VOTE = 0x0b, - BOARD_DELETED = 0x0c, -}; - - -struct RsGxsPostedEvent: RsEvent -{ - RsGxsPostedEvent(): - RsEvent(RsEventType::GXS_POSTED), - mPostedEventCode(RsPostedEventCode::UNKNOWN) {} - - RsPostedEventCode mPostedEventCode; - RsGxsGroupId mPostedGroupId; - RsGxsMessageId mPostedMsgId; - RsGxsMessageId mPostedThreadId; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mPostedEventCode); - RS_SERIAL_PROCESS(mPostedGroupId); - RS_SERIAL_PROCESS(mPostedMsgId); - } - - ~RsGxsPostedEvent() override; -}; - -class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService -{ -public: - explicit RsPosted(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - - virtual bool getBoardsInfo( - const std::list& boardsIds, - std::vector& boardsInfo ) = 0; - - virtual bool getBoardsSummaries(std::list& groupInfo) =0; - - virtual bool getBoardAllContent( - const RsGxsGroupId& boardId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) = 0; - - virtual bool getBoardContent( - const RsGxsGroupId& boardId, - const std::set& contentsIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) = 0; - - virtual bool editBoard(RsPostedGroup& board) =0; - - virtual bool createBoard(RsPostedGroup& board) =0; - - virtual bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) =0; - - virtual bool getBoardsServiceStatistics(GxsServiceStatistic& stat) =0; - - virtual bool voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& voterId) =0; - - virtual bool setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read) = 0; - - enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType }; - - RS_DEPRECATED_FOR(getBoardsInfo) - virtual bool getGroupData( const uint32_t& token, - std::vector &groups ) = 0; - - RS_DEPRECATED_FOR(getBoardsContent) - virtual bool getPostData( - const uint32_t& token, std::vector& posts, - std::vector& cmts, std::vector& vots) = 0; - - RS_DEPRECATED_FOR(getBoardsContent) - virtual bool getPostData( - const uint32_t& token, std::vector& posts, - std::vector& cmts) = 0; - - RS_DEPRECATED_FOR(getBoardsContent) - virtual bool getPostData( - const uint32_t& token, std::vector& posts) = 0; - - virtual bool setCommentAsRead(uint32_t& token,const RsGxsGroupId& gid,const RsGxsMessageId& comment_msg_id) =0; - - //Not currently used -//virtual bool getRelatedPosts(const uint32_t &token, std::vector &posts) = 0; - - /* From RsGxsCommentService */ -//virtual bool getCommentData(const uint32_t &token, std::vector &comments) = 0; -//virtual bool getRelatedComments(const uint32_t &token, std::vector &comments) = 0; -//virtual bool createNewComment(uint32_t &token, RsGxsComment &comment) = 0; -//virtual bool createNewVote(uint32_t &token, RsGxsVote &vote) = 0; - - RS_DEPRECATED_FOR(setPostReadStatus) - virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; - ////////////////////////////////////////////////////////////////////////////// - -virtual bool createGroup(uint32_t &token, RsPostedGroup &group) = 0; -virtual bool createPost(uint32_t &token, RsPostedPost &post) = 0; - -virtual bool updateGroup(uint32_t &token, RsPostedGroup &group) = 0; - - virtual bool groupShareKeys(const RsGxsGroupId& group,const std::set& peers) = 0 ; - - virtual ~RsPosted(); -}; diff --git a/libretroshare/src/retroshare/rsreputations.h b/libretroshare/src/retroshare/rsreputations.h deleted file mode 100644 index b8426e642..000000000 --- a/libretroshare/src/retroshare/rsreputations.h +++ /dev/null @@ -1,245 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsreputations.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Cyril Soler * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsids.h" -#include "retroshare/rsgxsifacetypes.h" -#include "serialiser/rsserializable.h" - -class RsReputations; - -/** - * Pointer to global instance of RsReputations service implementation - * @jsonapi{development} - */ -extern RsReputations* rsReputations; - - -constexpr float RS_REPUTATION_THRESHOLD_DEFAULT = 1.0f; - -enum struct RsOpinion : uint8_t -{ - NEGATIVE = 0, - NEUTRAL = 1, - POSITIVE = 2 -}; - -enum struct RsReputationLevel : uint8_t -{ - /// local opinion is negative - LOCALLY_NEGATIVE = 0x00, - - /// local opinion is neutral and friends are positive in average - REMOTELY_NEGATIVE = 0x01, - - /// no reputation information - NEUTRAL = 0x02, - - /// local opinion is neutral and friends are positive in average - REMOTELY_POSITIVE = 0x03, - - /// local opinion is positive - LOCALLY_POSITIVE = 0x04, - - /// missing info - UNKNOWN = 0x05 -}; - -struct RsReputationInfo : RsSerializable -{ - RsReputationInfo() : - mOwnOpinion(RsOpinion::NEUTRAL), mFriendsPositiveVotes(0), - mFriendsNegativeVotes(0), - mFriendAverageScore(RS_REPUTATION_THRESHOLD_DEFAULT), - mOverallReputationLevel(RsReputationLevel::NEUTRAL) {} - - RsOpinion mOwnOpinion; - - uint32_t mFriendsPositiveVotes; - uint32_t mFriendsNegativeVotes; - - float mFriendAverageScore; - - /// this should help clients in taking decisions - RsReputationLevel mOverallReputationLevel; - - /// @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mOwnOpinion); - RS_SERIAL_PROCESS(mFriendsPositiveVotes); - RS_SERIAL_PROCESS(mFriendsNegativeVotes); - RS_SERIAL_PROCESS(mFriendAverageScore); - RS_SERIAL_PROCESS(mOverallReputationLevel); - } - - virtual ~RsReputationInfo(); -}; - - -class RsReputations -{ -public: - virtual ~RsReputations() {} - - /** - * @brief Set own opinion about the given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[in] op Own opinion - * @return false on error, true otherwise - */ - virtual bool setOwnOpinion(const RsGxsId& id, RsOpinion op) = 0; - - /** - * @brief Get own opition about the given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[out] op Own opinion - * @return false on error, true otherwise - */ - virtual bool getOwnOpinion(const RsGxsId& id, RsOpinion& op) = 0; - - /** - * @brief Get reputation data of given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @param[in] ownerNode Optiona PGP id of the signed identity, accept a null - * (all zero/noninitialized) PGP id - * @param[out] info storage for the information - * @param[in] stamp if true, timestamo the information - * @return false on error, true otherwise - */ - virtual bool getReputationInfo( - const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info, - bool stamp = true ) = 0; - - /** - * @brief Get overall reputation level of given identity - * @jsonapi{development} - * @param[in] id Id of the identity - * @return the calculated reputation level based on available information - */ - virtual RsReputationLevel overallReputationLevel(const RsGxsId& id) = 0; - - /** - * @brief Enable giving automatic positive opinion when flagging as contact - * @jsonapi{development} - * @param[in] b true to enable, false to disable - */ - virtual void setAutoPositiveOpinionForContacts(bool b) = 0; - - /** - * @brief check if giving automatic positive opinion when flagging as - * contact is enbaled - * @jsonapi{development} - * @return true if enabled, false otherwise - */ - virtual bool autoPositiveOpinionForContacts() = 0; - - /** - * @brief Set threshold on remote reputation to consider it remotely - * negative - * @jsonapi{development} - * @param[in] thresh Threshold value - */ - virtual void setThresholdForRemotelyNegativeReputation(uint32_t thresh) = 0; - - /** - * * @brief Get threshold on remote reputation to consider it remotely - * negative - * @jsonapi{development} - * @return Threshold value - */ - virtual uint32_t thresholdForRemotelyNegativeReputation() = 0; - - /** - * @brief Set threshold on remote reputation to consider it remotely - * positive - * @jsonapi{development} - * @param[in] thresh Threshold value - */ - virtual void setThresholdForRemotelyPositiveReputation(uint32_t thresh) = 0; - - /** - * @brief Get threshold on remote reputation to consider it remotely - * negative - * @jsonapi{development} - * @return Threshold value - */ - virtual uint32_t thresholdForRemotelyPositiveReputation() = 0; - - /** - * @brief Get number of days to wait before deleting a banned identity from - * local storage - * @jsonapi{development} - * @return number of days to wait, 0 means never delete - */ - virtual uint32_t rememberBannedIdThreshold() = 0; - - /** - * @brief Set number of days to wait before deleting a banned identity from - * local storage - * @jsonapi{development} - * @param[in] days number of days to wait, 0 means never delete - */ - virtual void setRememberBannedIdThreshold(uint32_t days) = 0; - - /** - * @brief This method allow fast checking if a GXS identity is banned. - * @jsonapi{development} - * @param[in] id Id of the identity to check - * @return true if identity is banned, false otherwise - */ - virtual bool isIdentityBanned(const RsGxsId& id) = 0; - - /** - * @brief Check if automatic banning of all identities signed by the given - * node is enabled - * @jsonapi{development} - * @param[in] id PGP id of the node - * @return true if enabled, false otherwise - */ - virtual bool isNodeBanned(const RsPgpId& id) = 0; - - /** - * @brief Enable automatic banning of all identities signed by the given - * node - * @jsonapi{development} - * @param[in] id PGP id of the node - * @param[in] b true to enable, false to disable - */ - virtual void banNode(const RsPgpId& id, bool b) = 0; - - - /** - * @deprecated - * This returns the reputation level and also the flags of the identity - * service for that id. This is useful in order to get these flags without - * relying on the async method of p3Identity - */ - RS_DEPRECATED - virtual RsReputationLevel overallReputationLevel( - const RsGxsId& id, uint32_t* identity_flags ) = 0; -}; diff --git a/libretroshare/src/retroshare/rsrtt.h b/libretroshare/src/retroshare/rsrtt.h deleted file mode 100644 index e55220307..000000000 --- a/libretroshare/src/retroshare/rsrtt.h +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsposted.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_RTT_INTERFACE_H -#define RETROSHARE_RTT_INTERFACE_H - -#include -#include -#include -#include - -/* The Main Interface Class - for information about your Peers */ -class RsRtt; -extern RsRtt *rsRtt; - - -class RsRttPongResult -{ - public: - RsRttPongResult() - :mTS(0), mRTT(0), mOffset(0) { return; } - - RsRttPongResult(double ts, double rtt, double offset) - :mTS(ts), mRTT(rtt), mOffset(offset) { return; } - - double mTS; - double mRTT; - double mOffset; -}; - -class RsRtt -{ - public: - - RsRtt() { return; } -virtual ~RsRtt() { return; } - -virtual uint32_t getPongResults(const RsPeerId& id, int n, std::list &results) = 0; -virtual double getMeanOffset(const RsPeerId& id) = 0; - -}; - -#endif diff --git a/libretroshare/src/retroshare/rsservicecontrol.h b/libretroshare/src/retroshare/rsservicecontrol.h deleted file mode 100644 index 4946f5247..000000000 --- a/libretroshare/src/retroshare/rsservicecontrol.h +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsservicecontrol.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014-2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_SERVICE_CONTROL_GUI_INTERFACE_H -#define RETROSHARE_SERVICE_CONTROL_GUI_INTERFACE_H - -#include -#include -#include -#include -#include -#include - -/* The Main Interface Class - for information about your Peers */ -class RsServiceControl; - -/** - * Pointer to global instance of RsServiceControl service implementation - * @jsonapi{development} - */ -extern RsServiceControl* rsServiceControl; - -struct RsServiceInfo : RsSerializable -{ - RsServiceInfo(); - RsServiceInfo( - const uint16_t service_type, - const std::string& service_name, - const uint16_t version_major, - const uint16_t version_minor, - const uint16_t min_version_major, - const uint16_t min_version_minor); - - static unsigned int RsServiceInfoUIn16ToFullServiceId(uint16_t serviceType); - - std::string mServiceName; - uint32_t mServiceType; - // current version, we running. - uint16_t mVersionMajor; - uint16_t mVersionMinor; - // minimum version can communicate with. - uint16_t mMinVersionMajor; - uint16_t mMinVersionMinor; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(mServiceName); - RS_SERIAL_PROCESS(mServiceType); - RS_SERIAL_PROCESS(mVersionMajor); - RS_SERIAL_PROCESS(mVersionMinor); - RS_SERIAL_PROCESS(mMinVersionMajor); - RS_SERIAL_PROCESS(mMinVersionMinor); - } -}; - -bool ServiceInfoCompatible(const RsServiceInfo &info1, const RsServiceInfo &info2); - -/* this is what is transmitted to peers */ -struct RsPeerServiceInfo : RsSerializable -{ - RsPeerServiceInfo() : mPeerId(), mServiceList() {} - - RsPeerId mPeerId; - std::map mServiceList; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(mPeerId); - RS_SERIAL_PROCESS(mServiceList); - } -}; - -struct RsServicePermissions : RsSerializable -{ - RsServicePermissions(); - - bool peerHasPermission(const RsPeerId &peerId) const; - - void setPermission(const RsPeerId& peerId) ; - void resetPermission(const RsPeerId& peerId) ; - - uint32_t mServiceId; - std::string mServiceName; - - bool mDefaultAllowed; - // note only one of these is checked. - // if DefaultAllowed = true, then only PeersDenied is checked. - // if DefaultAllowed = false, then only PeersAllowed is checked. - std::set mPeersAllowed; - std::set mPeersDenied; - - // RsSerializable interface - void serial_process(RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext &ctx) { - RS_SERIAL_PROCESS(mServiceId); - RS_SERIAL_PROCESS(mServiceName); - - RS_SERIAL_PROCESS(mDefaultAllowed); - - RS_SERIAL_PROCESS(mPeersAllowed); - RS_SERIAL_PROCESS(mPeersDenied); - } -}; - -class RsServiceControl -{ -public: - - RsServiceControl() {} - virtual ~RsServiceControl(){} - - /** - * @brief get a map off all services. - * @jsonapi{development} - * @param[out] info storage for service information - * @return always true - */ - virtual bool getOwnServices(RsPeerServiceInfo &info) = 0; - - /** - * @brief getServiceName lookup the name of a service. - * @jsonapi{development} - * @param[in] serviceId service to look up - * @return name of service - */ - virtual std::string getServiceName(uint32_t serviceId) = 0; - - /** - * @brief getServiceItemNames return a map of service item names. - * @jsonapi{development} - * @param[in] serviceId service to look up - * @param[out] names names of items - * @return true on success false otherwise - */ - virtual bool getServiceItemNames(uint32_t serviceId, std::map& names) = 0; - - /** - * @brief getServicesAllowed return a mpa with allowed service information. - * @jsonapi{development} - * @param[in] peerId peer to look up - * @param[out] info map with infomration - * @return always true - */ - virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; - - /** - * @brief getServicesProvided return services provided by a peer. - * @jsonapi{development} - * @param[in] peerId peer to look up - * @param[out] info - * @return true on success false otherwise. - */ - virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; - - /** - * @brief getServicePermissions return permissions of one service. - * @jsonapi{development} - * @param[in] serviceId service id to look up - * @param[out] permissions - * @return true on success false otherwise. - */ - virtual bool getServicePermissions(uint32_t serviceId, RsServicePermissions &permissions) = 0; - - /** - * @brief updateServicePermissions update service permissions of one service. - * @jsonapi{development} - * @param[in] serviceId service to update - * @param[in] permissions new permissions - * @return true on success false otherwise. - */ - virtual bool updateServicePermissions(uint32_t serviceId, const RsServicePermissions &permissions) = 0; - - /** - * @brief getPeersConnected return peers using a service. - * @jsonapi{development} - * @param[in] serviceId service to look up. - * @param[out] peerSet set of peers using this service. - */ - virtual void getPeersConnected( uint32_t serviceId, - std::set& peerSet ) = 0; -}; - -#endif diff --git a/libretroshare/src/retroshare/rsstatus.h b/libretroshare/src/retroshare/rsstatus.h deleted file mode 100644 index 3173726bb..000000000 --- a/libretroshare/src/retroshare/rsstatus.h +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsstatus.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Vinny Do, Chris Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_STATUS_INTERFACE_H -#define RS_STATUS_INTERFACE_H - -class RsStatus; - -extern RsStatus *rsStatus; - -#include -#include -#include -#include -#include - - -const uint32_t RS_STATUS_OFFLINE = 0x0000; -const uint32_t RS_STATUS_AWAY = 0x0001; -const uint32_t RS_STATUS_BUSY = 0x0002; -const uint32_t RS_STATUS_ONLINE = 0x0003; -const uint32_t RS_STATUS_INACTIVE = 0x0004; - -const uint32_t RS_STATUS_COUNT = 0x0005; // count of status - -//! data object for peer status information -/*! - * data object used for peer status information - */ -class StatusInfo -{ - public: - StatusInfo() : status(RS_STATUS_OFFLINE), time_stamp(0) {} - - public: - RsPeerId id; - uint32_t status; - rstime_t time_stamp; /// for owner time set, and for their peers time sent -}; - - -//! Interface to retroshare for Rs status -/*! - * Provides an interface for retroshare's status functionality - */ -class RsStatus -{ - public: - - /** - * This retrieves the own status info - * @param statusInfo is populated with own status - */ - virtual bool getOwnStatus(StatusInfo& statusInfo) = 0; - - /** - * This retrieves the status info on the client's peers - * @param statusInfo is populated with client's peer's status - */ - virtual bool getStatusList(std::list& statusInfo) = 0; - - /** - * This retrieves the status info one peer - * @param statusInfo is populated with client's peer's status - */ - virtual bool getStatus(const RsPeerId &id, StatusInfo &statusInfo) = 0; - - /** - * send the client's status to his/her peers - * @param id the peer to send the status (empty, send to all) - * @param status the status of the peers - * @return will return false if status info does not belong to client - */ - virtual bool sendStatus(const RsPeerId &id, uint32_t status) = 0; -}; - - -#endif diff --git a/libretroshare/src/retroshare/rstokenservice.h b/libretroshare/src/retroshare/rstokenservice.h deleted file mode 100644 index a0fbd7258..000000000 --- a/libretroshare/src/retroshare/rstokenservice.h +++ /dev/null @@ -1,285 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rstokenservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Chris Evi-Parker * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "retroshare/rsgxsifacetypes.h" -#include "util/rsdeprecate.h" -#include "util/rsdebug.h" - -// TODO CLEANUP: GXS_REQUEST_TYPE_* should be an inner enum of RsTokReqOptions -#define GXS_REQUEST_TYPE_GROUP_DATA 0x00010000 -#define GXS_REQUEST_TYPE_GROUP_META 0x00020000 -#define GXS_REQUEST_TYPE_GROUP_IDS 0x00040000 -#define GXS_REQUEST_TYPE_MSG_DATA 0x00080000 -#define GXS_REQUEST_TYPE_MSG_META 0x00100000 -#define GXS_REQUEST_TYPE_MSG_IDS 0x00200000 - -#define GXS_REQUEST_TYPE_MSG_RELATED_DATA 0x00400000 -#define GXS_REQUEST_TYPE_MSG_RELATED_META 0x00800000 -#define GXS_REQUEST_TYPE_MSG_RELATED_IDS 0x01000000 - -#define GXS_REQUEST_TYPE_GROUP_STATS 0x01600000 -#define GXS_REQUEST_TYPE_SERVICE_STATS 0x03200000 -#define GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA 0x04000000 - - -// TODO CLEANUP: RS_TOKREQOPT_MSG_* should be an inner enum of RsTokReqOptions -#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId. -#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group. -#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs. -#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group. -#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs. -#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId - - -/* TODO CLEANUP: RS_TOKREQ_ANSTYPE_* values are meaningless and not used by - * RsTokenService or its implementation, and may be arbitrarly defined by each - * GXS client as they are of no usage, their use is deprecated, up until the - * definitive cleanup is done new code must use RS_DEPRECATED_TOKREQ_ANSTYPE for - * easier cleanup. */ -#ifndef RS_NO_WARN_DEPRECATED -# warning RS_TOKREQ_ANSTYPE_* macros are deprecated! -#endif -#define RS_DEPRECATED_TOKREQ_ANSTYPE 0x0000 -#define RS_TOKREQ_ANSTYPE_LIST 0x0001 -#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002 -#define RS_TOKREQ_ANSTYPE_DATA 0x0003 -#define RS_TOKREQ_ANSTYPE_ACK 0x0004 - - -/*! - * This class provides useful generic support for GXS style services. - * I expect much of this will be incorporated into the base GXS. - */ -struct RsTokReqOptions -{ - RsTokReqOptions() : mOptions(0), mStatusFilter(0), mStatusMask(0), - mMsgFlagMask(0), mMsgFlagFilter(0), mReqType(0), mSubscribeFilter(0), - mSubscribeMask(0), mBefore(0), mAfter(0),mPriority(GxsRequestPriority::NORMAL) {} - - /** - * Can be one or multiple RS_TOKREQOPT_* - * TODO: cleanup this should be made with proper flags instead of macros - */ - uint32_t mOptions; - - // Request specific matches with Group / Message Status. - // Should be usable with any Options... applied afterwards. - uint32_t mStatusFilter; - uint32_t mStatusMask; - - // use - uint32_t mMsgFlagMask, mMsgFlagFilter; - - /** - * Must be one of GXS_REQUEST_TYPE_* - * TODO: cleanup this should be made an enum instead of macros - */ - uint32_t mReqType; - - uint32_t mSubscribeFilter, mSubscribeMask; // Only for Groups. - - // Time range... again applied after Options. - rstime_t mBefore; - rstime_t mAfter; - - GxsRequestPriority mPriority; -}; - -/*! - * A proxy class for requesting generic service data for GXS - * This seperates the request mechanism from the actual retrieval of data - */ -class RsTokenService -{ -public: - - enum GxsRequestStatus : uint8_t - { - FAILED = 0, - PENDING = 1, - PARTIAL = 2, - COMPLETE = 3, - DONE = 4, /// Once all data has been retrived - CANCELLED = 5 - }; - - RsTokenService() {} - virtual ~RsTokenService() {} - - /* Data Requests */ - - /*! - * Use this to request group related information - * @param token The token returned for the request, store this value to poll for request completion - * @param ansType The type of result (e.g. group data, meta, ids) - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds group id to request info for - * @return - */ - virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list &groupIds) = 0; - - /*! - * Use this to request all group related info - * @param token The token returned for the request, store this value to poll for request completion - * @param ansType The type of result (e.g. group data, meta, ids) - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @return - */ - virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) = 0; - - /*! - * Use this to get msg related information, store this value to poll for request completion - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) = 0; - - /*! - * Use this to get msg related information, store this value to poll for request completion - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, this retrieves all the msgs info for each grpId in list - * @return true if request successful false otherwise - */ - virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list& grpIds) = 0; - - /*! - * For requesting msgs related to a given msg id within a group - * @param token The token returned for the request - * @param ansType The type of result wanted - * @param opts Additional option that affect outcome of request. Please see specific services, for valid values - * @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs - * @return true if request successful false otherwise - */ - virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector& msgIds) = 0; - - /*! - * This request statistics on amount of data held - * number of groups - * number of groups subscribed - * number of messages - * size of db store - * total size of messages - * total size of groups - * @param token - */ - virtual void requestServiceStatistic(uint32_t& token, const RsTokReqOptions &opts) = 0; - - /*! - * To request statistic on a group - * @param token set to value to be redeemed to get statistic - * @param grpId the id of the group - */ - virtual void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId, const RsTokReqOptions &opts) = 0; - - - /* Poll */ - - /*! - * Request the status of ongoing request. - * Please use this for polling as much cheaper - * than polling the specific service as they might - * not return intermediate status information - * @param token value of token to check status for - * @return the current status of request - */ - virtual GxsRequestStatus requestStatus(const uint32_t token) = 0; - - /*! - * @brief Cancel Request - * If this function returns false, it may be that the request has completed - * already. Useful for very expensive request. - * @param token the token of the request to cancel - * @return false if unusuccessful in cancelling request, true if successful - */ - virtual bool cancelRequest(const uint32_t &token) = 0; - -#ifdef TO_REMOVE - /** - * Block caller while request is being processed. - * Useful for blocking API implementation. - * @param[in] token token associated to the request caller is waiting for - * @param[in] maxWait maximum waiting time in milliseconds - * @param[in] checkEvery time in millisecond between status checks - */ - RsTokenService::GxsRequestStatus waitToken( - uint32_t token, - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000), - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20), - bool auto_delete_if_unsuccessful=true) - { -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - auto wkStartime = std::chrono::steady_clock::now(); - int maxWorkAroundCnt = 10; -LLwaitTokenBeginLabel: -#endif - auto timeout = std::chrono::steady_clock::now() + maxWait; - auto st = requestStatus(token); - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful) - cancelRequest(token); - -#if defined(__ANDROID__) && (__ANDROID_API__ < 24) - /* Work around for very slow/old android devices, we don't expect this - * to be necessary on newer devices. If it take unreasonably long - * something worser is already happening elsewere and we return anyway. - */ - if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE - && maxWorkAroundCnt-- > 0 ) - { - maxWait *= 10; - checkEvery *= 3; - Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device " - << " workaround st: " << st - << " maxWorkAroundCnt: " << maxWorkAroundCnt - << " maxWait: " << maxWait.count() - << " checkEvery: " << checkEvery.count() << std::endl; - goto LLwaitTokenBeginLabel; - } - Dbg3() << __PRETTY_FUNCTION__ << " lasted: " - << std::chrono::duration_cast( - std::chrono::steady_clock::now() - wkStartime ).count() - << "ms" << std::endl; - -#endif - - return st; - } -#endif - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/retroshare/rsturtle.h b/libretroshare/src/retroshare/rsturtle.h deleted file mode 100644 index 76120e85b..000000000 --- a/libretroshare/src/retroshare/rsturtle.h +++ /dev/null @@ -1,170 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsturtle.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "serialiser/rstlvbinary.h" -#include "retroshare/rstypes.h" -#include "retroshare/rsgxsifacetypes.h" -#include "serialiser/rsserializable.h" - -namespace RsRegularExpression { class LinearizedExpression ; } -class RsTurtleClientService ; - -class RsTurtle; - -/** - * Pointer to global instance of RsTurtle service implementation - */ -extern RsTurtle* rsTurtle; - -typedef uint32_t TurtleRequestId ; -typedef RsPeerId TurtleVirtualPeerId; - -struct TurtleFileInfo : RsSerializable -{ - TurtleFileInfo() : size(0) {} - - uint64_t size; /// File size - RsFileHash hash; /// File hash - std::string name; /// File name - - /// @see RsSerializable::serial_process - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(hash); - - // Use String TLV serial process for retrocompatibility - RsTypeSerializer::serial_process( - j, ctx, TLV_TYPE_STR_NAME, name, "name" ); - } -} RS_DEPRECATED_FOR(TurtleFileInfoV2); - -struct TurtleTunnelRequestDisplayInfo -{ - uint32_t request_id ; // Id of the request - RsPeerId source_peer_id ; // Peer that relayed the request - uint32_t age ; // Age in seconds - uint32_t depth ; // Depth of the request. Might be altered. -}; -struct TurtleSearchRequestDisplayInfo -{ - uint32_t request_id ; // Id of the request - RsPeerId source_peer_id ; // Peer that relayed the request - uint32_t age ; // Age in seconds - uint32_t depth ; // Depth of the request. Might be altered. - uint32_t hits ; - std::string keywords; -}; - -class TurtleTrafficStatisticsInfo -{ - public: - float unknown_updn_Bps ; // unknown data transit bitrate (in Bytes per sec.) - float data_up_Bps ; // upload (in Bytes per sec.) - float data_dn_Bps ; // download (in Bytes per sec.) - float tr_up_Bps ; // tunnel requests upload bitrate (in Bytes per sec.) - float tr_dn_Bps ; // tunnel requests dnload bitrate (in Bytes per sec.) - float total_up_Bps ; // turtle network management bitrate (in Bytes per sec.) - float total_dn_Bps ; // turtle network management bitrate (in Bytes per sec.) - - std::vector forward_probabilities ; // probability to forward a TR as a function of depth. -}; - -// Interface class for turtle hopping. -// -// This class mainly interacts with the turtle router, that is responsible -// for routing turtle packets between peers, accepting/forwarding search -// requests and dowloading files. -// -// As seen from here, the interface is really simple. -// -class RsTurtle -{ -public: - RsTurtle() {} - virtual ~RsTurtle() {} - - // This is saved permanently. - virtual void setEnabled(bool) = 0 ; - virtual bool enabled() const = 0 ; - - // This is temporary, used by Operating Mode. - virtual void setSessionEnabled(bool) = 0 ; - virtual bool sessionEnabled() const = 0 ; - - /** Lauches a search request through the pipes, and immediately returns - * the request id, which will be further used by client services to - * handle results as they come back. */ - virtual TurtleRequestId turtleSearch( - unsigned char *search_bin_data, uint32_t search_bin_data_len, - RsTurtleClientService* client_service ) = 0; - - // Initiates tunnel handling for the given file hash. tunnels. Launches - // an exception if an error occurs during the initialization process. The - // turtle router itself does not initiate downloads, it only maintains - // tunnels for the given hash. The download should be driven by the file - // transfer module by calling ftServer::FileRequest(). - // Aggressive mode causes the turtle router to regularly re-ask tunnels in addition to the ones already - // available without replacing them. In non aggressive mode, we wait for all tunnels to die before asking - // for new tunnels. - // - virtual void monitorTunnels(const RsFileHash& file_hash,RsTurtleClientService *client_service,bool use_aggressive_mode) = 0 ; - - // Tells the turtle router to stop handling tunnels for the given file hash. Traditionally this should - // be called after calling ftServer::fileCancel(). - // - virtual void stopMonitoringTunnels(const RsFileHash& file_hash) = 0 ; - - /// Adds a client tunnel service. This means that the service will be added - /// to the list of services that might respond to tunnel requests. - /// Example tunnel services include: - /// - /// p3ChatService: tunnels correspond to private distant chatting - /// ftServer : tunnels correspond to file data transfer - /// - virtual void registerTunnelService(RsTurtleClientService *service) = 0; - - virtual std::string getPeerNameForVirtualPeerId(const RsPeerId& virtual_peer_id) = 0; - - // Get info from the turtle router. I use std strings to hide the internal structs. - // - virtual void getInfo(std::vector >&,std::vector >&, - std::vector&,std::vector&) const = 0; - - // Get info about turtle traffic. See TurtleTrafficStatisticsInfo members for details. - // - virtual void getTrafficStatistics(TurtleTrafficStatisticsInfo& info) const = 0; - - // Convenience function. - virtual bool isTurtlePeer(const RsPeerId& peer_id) const = 0 ; - - // Hardcore handles - virtual void setMaxTRForwardRate(int max_tr_up_rate) = 0 ; - virtual int getMaxTRForwardRate() const = 0 ; -}; diff --git a/libretroshare/src/retroshare/rstypes.h b/libretroshare/src/retroshare/rstypes.h deleted file mode 100644 index 97d97f565..000000000 --- a/libretroshare/src/retroshare/rstypes.h +++ /dev/null @@ -1,564 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: rstypes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_TYPES_GUI_INTERFACE_H -#define RS_TYPES_GUI_INTERFACE_H - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "util/rstime.h" - -#define USE_NEW_CHUNK_CHECKING_CODE - -typedef Sha1CheckSum RsFileHash ; - -const uint32_t FT_STATE_FAILED = 0x0000 ; -const uint32_t FT_STATE_OKAY = 0x0001 ; -const uint32_t FT_STATE_WAITING = 0x0002 ; -const uint32_t FT_STATE_DOWNLOADING = 0x0003 ; -const uint32_t FT_STATE_COMPLETE = 0x0004 ; -const uint32_t FT_STATE_QUEUED = 0x0005 ; -const uint32_t FT_STATE_PAUSED = 0x0006 ; -const uint32_t FT_STATE_CHECKING_HASH = 0x0007 ; - -// These constants are used by RsDiscSpace -// -const uint32_t RS_PARTIALS_DIRECTORY = 0x0000 ; -const uint32_t RS_DOWNLOAD_DIRECTORY = 0x0001 ; -const uint32_t RS_CONFIG_DIRECTORY = 0x0002 ; -const uint32_t RS_PGP_DIRECTORY = 0x0003 ; -const uint32_t RS_DIRECTORY_COUNT = 0x0004 ; - -struct TransferInfo : RsSerializable -{ - /**** Need Some of these Fields ****/ - RsPeerId peerId; - std::string name; /* if has alternative name? */ - double tfRate; /* kbytes */ - int status; /* FT_STATE_... */ - uint64_t transfered ; // used when no chunkmap data is available - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(peerId); - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(tfRate); - RS_SERIAL_PROCESS(status); - RS_SERIAL_PROCESS(transfered); - } -}; - -enum QueueMove { QUEUE_TOP = 0x00, - QUEUE_UP = 0x01, - QUEUE_DOWN = 0x02, - QUEUE_BOTTOM = 0x03 -}; - -enum DwlSpeed : uint8_t -{ - SPEED_LOW = 0x00, - SPEED_NORMAL = 0x01, - SPEED_HIGH = 0x02 -}; - - - - -/********************** For Search Interface *****************/ - -/* This is still rough, implement later! */ - - /* text based ones */ -const std::string TypeExt = "ext"; -const std::string TypeName = "name"; -const std::string TypeHash = "hash"; -const std::string TypeSize = "size"; - -const int OpContains = 0x001; -const int OpExactMatch = 0x002; -const int OpLessThan = 0x003; -const int OpGreaterThan = 0x004; - -class Condition -{ - public: - - std::string type; - int op; - double value; - std::string name; -}; - -struct PeerBandwidthLimits : RsSerializable -{ - PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {} - - uint32_t max_up_rate_kbs; - uint32_t max_dl_rate_kbs; - - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(max_up_rate_kbs); - RS_SERIAL_PROCESS(max_dl_rate_kbs); - } -}; - -//class SearchRequest // unused stuff. -//{ -// public: -// int searchId; -// RsCertId toId; /* all zeros for everyone! */ -// std::list tests; -//}; - - -/********************** For FileCache Interface *****************/ - -#define DIR_TYPE_UNKNOWN 0x00 -#define DIR_TYPE_ROOT 0x01 -#define DIR_TYPE_PERSON 0x02 -#define DIR_TYPE_DIR 0x04 -#define DIR_TYPE_FILE 0x08 -#define DIR_TYPE_EXTRA_FILE 0x10 - -/* flags for Directry request - - * two types; - * (1) Local / Remote (top byte) - * (2) Request type: Parent / Child - allows reduction in workload. - * (TODO) - */ - -const FileStorageFlags DIR_FLAGS_PARENT ( 0x0001 ); -const FileStorageFlags DIR_FLAGS_DETAILS ( 0x0002 ); // apparently unused -const FileStorageFlags DIR_FLAGS_CHILDREN ( 0x0004 ); // apparently unused - -const FileStorageFlags DIR_FLAGS_ANONYMOUS_DOWNLOAD ( 0x0080 ); // Flags for directory sharing permissions. The last -//const FileStorageFlags DIR_FLAGS_BROWSABLE_OTHERS ( 0x0100 ); // one should be the OR of the all four flags. -//const FileStorageFlags DIR_FLAGS_NETWORK_WIDE_GROUPS ( 0x0200 ); -const FileStorageFlags DIR_FLAGS_BROWSABLE ( 0x0400 ); -const FileStorageFlags DIR_FLAGS_ANONYMOUS_SEARCH ( 0x0800 ); -const FileStorageFlags DIR_FLAGS_PERMISSIONS_MASK ( DIR_FLAGS_ANONYMOUS_DOWNLOAD | /*DIR_FLAGS_BROWSABLE_OTHERS - DIR_FLAGS_NETWORK_WIDE_GROUPS*/ DIR_FLAGS_BROWSABLE | DIR_FLAGS_ANONYMOUS_SEARCH); - -const FileStorageFlags DIR_FLAGS_LOCAL ( 0x1000 ); -const FileStorageFlags DIR_FLAGS_REMOTE ( 0x2000 ); - -struct FileInfo : RsSerializable -{ - FileInfo(): - mId(0), searchId(0), size(0), avail(0), rank(0), age(0), - queue_position(0), transfered(0), tfRate(0), downloadStatus(0), - priority(SPEED_NORMAL), lastTS(0) {} - - /// Combination of the four RS_DIR_FLAGS_*. Updated when the file is a local stored file. - FileStorageFlags storage_permission_flags; - - /// various flags from RS_FILE_HINTS_* - TransferRequestFlags transfer_info_flags; - - /** allow this to be tweaked by the GUI Model - * (GUI) Model Id -> unique number - */ - mutable unsigned int mId; - - - /// 0 if none - int searchId; - - std::string path; - std::string fname; - RsFileHash hash; - - RS_DEPRECATED std::string ext; /// @deprecated unused - - uint64_t size; - uint64_t avail; /// how much we have - - double rank; - int age; - uint32_t queue_position; - - /* Transfer Stuff */ - uint64_t transfered; - double tfRate; /// in kbytes - uint32_t downloadStatus; /// FT_STATE_DOWNLOADING & co. See rstypes.h - std::vector peers; - - DwlSpeed priority; - rstime_t lastTS; - - std::list parent_groups; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(storage_permission_flags); - RS_SERIAL_PROCESS(transfer_info_flags); - RS_SERIAL_PROCESS(mId); - RS_SERIAL_PROCESS(searchId); - RS_SERIAL_PROCESS(path); - RS_SERIAL_PROCESS(fname); - RS_SERIAL_PROCESS(hash); - RS_SERIAL_PROCESS(ext); - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(avail); - RS_SERIAL_PROCESS(rank); - RS_SERIAL_PROCESS(age); - RS_SERIAL_PROCESS(queue_position); - RS_SERIAL_PROCESS(transfered); - RS_SERIAL_PROCESS(tfRate); - RS_SERIAL_PROCESS(downloadStatus); - RS_SERIAL_PROCESS(peers); - RS_SERIAL_PROCESS(priority); - RS_SERIAL_PROCESS(lastTS); - RS_SERIAL_PROCESS(parent_groups); - } -}; - -/** - * Pointers in this class have no real meaning as pointers, they are used as - * indexes, internally by retroshare. - */ -struct DirStub : RsSerializable -{ - DirStub() : type(DIR_TYPE_UNKNOWN), ref(nullptr) {} - - uint8_t type; - std::string name; - void *ref; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(type); - RS_SERIAL_PROCESS(name); - -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif // defined(__GNUC__) && !defined(__clang__) - // (Cyril) We have to do this because on some systems (MacOS) uintptr_t is unsigned long which is not well defined. It is always - // preferable to force type serialization to the correct size rather than letting the compiler choose for us. - // /!\ This structure cannot be sent over the network. The serialization would be inconsistent. - - if(sizeof(ref) == 4) - { - std::uint32_t& handle(reinterpret_cast(ref)); - RS_SERIAL_PROCESS(handle); - } - else if(sizeof(ref) == 8) - { - std::uint64_t& handle(reinterpret_cast(ref)); - RS_SERIAL_PROCESS(handle); - } - else - std::cerr << __PRETTY_FUNCTION__ << ": cannot serialize raw pointer of size " << sizeof(ref) << std::endl; - -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif // defined(__GNUC__) && !defined(__clang__) - } -}; - -/** - * Pointers in this class have no real meaning as pointers, they are used as - * indexes, internally by retroshare. - */ -struct DirDetails : RsSerializable -{ - DirDetails() : parent(nullptr), prow(0), ref(nullptr), - type(DIR_TYPE_UNKNOWN), size(0), mtime(0), max_mtime(0) {} - - - /* G10h4ck do we still need to keep this as void* instead of uint64_t for - * retroshare-gui sake? */ - void* parent; - - int prow; /* parent row */ - - /* G10h4ck do we still need to keep this as void* instead of uint64_t for - * retroshare-gui sake? */ - void* ref; - - uint8_t type; - RsPeerId id; - std::string name; - RsFileHash hash; - std::string path; // full path of the parent directory, when it is a file; full path of the dir otherwise. - uint64_t size; // total size of directory, or size of the file. - uint32_t mtime; // file/directory modification time, according to what the system reports - FileStorageFlags flags; - uint32_t max_mtime ; // maximum modification time of the whole hierarchy below. - - std::vector children; - std::list parent_groups; // parent groups for the shared directory - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - /* Enforce serialization as uint64_t because void* changes size - * depending (usually 4 bytes on 32bit arch and 8 bytes on 64bit archs) - */ - uint64_t handle = reinterpret_cast(ref); - RS_SERIAL_PROCESS(handle); - ref = reinterpret_cast(handle); - - uint64_t parentHandle = reinterpret_cast(parent); - RS_SERIAL_PROCESS(parentHandle); - parent = reinterpret_cast(parentHandle); - - RS_SERIAL_PROCESS(prow); - RS_SERIAL_PROCESS(type); - RS_SERIAL_PROCESS(id); - RS_SERIAL_PROCESS(name); - RS_SERIAL_PROCESS(hash); - RS_SERIAL_PROCESS(path); - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(mtime); - RS_SERIAL_PROCESS(flags); - RS_SERIAL_PROCESS(max_mtime); - RS_SERIAL_PROCESS(children); - RS_SERIAL_PROCESS(parent_groups); - } - - ~DirDetails() override = default; -}; - -class FileDetail -{ - public: - RsPeerId id; - std::string name; - RsFileHash hash; - std::string path; - uint64_t size; - uint32_t age; - uint32_t rank; -}; - -class CompressedChunkMap ; - -struct FileChunksInfo : RsSerializable -{ - enum ChunkState : uint8_t - { - CHUNK_OUTSTANDING = 0, - CHUNK_ACTIVE = 1, - CHUNK_DONE = 2, - CHUNK_CHECKING = 3 - }; - - enum ChunkStrategy : uint8_t - { - CHUNK_STRATEGY_STREAMING, - CHUNK_STRATEGY_RANDOM, - CHUNK_STRATEGY_PROGRESSIVE - }; - - struct SliceInfo : RsSerializable - { - uint32_t start; - uint32_t size; - RsPeerId peer_id; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RS_SERIAL_PROCESS(start); - RS_SERIAL_PROCESS(size); - RS_SERIAL_PROCESS(peer_id); - } - }; - - uint64_t file_size; /// real size of the file - uint32_t chunk_size; /// size of chunks - ChunkStrategy strategy; - - /// dl state of chunks. Only the last chunk may have size < chunk_size - std::vector chunks; - - /// For each source peer, gives the compressed bit map of have/don't have sate - std::map compressed_peer_availability_maps; - - /// For each chunk (by chunk number), gives the completion of the chunk. - std::vector > active_chunks; - - /// The list of pending requests, chunk per chunk (by chunk id) - std::map > pending_slices; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(file_size); - RS_SERIAL_PROCESS(chunk_size); - RS_SERIAL_PROCESS(strategy); - RS_SERIAL_PROCESS(chunks); - RS_SERIAL_PROCESS(compressed_peer_availability_maps); - RS_SERIAL_PROCESS(active_chunks); - RS_SERIAL_PROCESS(pending_slices); - } -}; - -class CompressedChunkMap : public RsSerializable -{ - public: - CompressedChunkMap() {} - - CompressedChunkMap(const std::vector& uncompressed_data) - { - _map.resize( getCompressedSize(uncompressed_data.size()),0 ) ; - - for(uint32_t i=0;i>5) + !!(size&31) ; } - - uint32_t filledChunks(uint32_t nbchks) const - { - uint32_t res = 0 ; - for(uint32_t i=0;i> 5] & (1 << (i & 31))) > 0 ; } - - inline void set(uint32_t j) { _map[j >> 5] |= (1 << (j & 31)) ; } - inline void reset(uint32_t j) { _map[j >> 5] &= ~(1 << (j & 31)) ; } - - /// compressed map, one bit per chunk - std::vector _map; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { RS_SERIAL_PROCESS(_map); } -}; - - -template class t_CRCMap -{ - public: - // Build from a file. - // - t_CRCMap(uint64_t file_size,uint32_t chunk_size) - : _crcs( file_size/chunk_size + ( (file_size%chunk_size)>0)), _ccmap(file_size/chunk_size + ( (file_size%chunk_size)>0),0) - { - } - t_CRCMap() {} - - inline void set(uint32_t i,const CRCTYPE& val) { _crcs[i] = val ; _ccmap.set(i) ; } - inline bool isSet(uint32_t i) const { return _ccmap[i] ; } - - inline const CRCTYPE& operator[](int i) const { return _crcs[i] ; } - inline uint32_t size() const { return _crcs.size() ; } - private: - std::vector _crcs; - CompressedChunkMap _ccmap ; - - friend class RsTurtleFileCrcItem ; - friend class RsFileItemSerialiser ; - friend class RsFileCRC32Map ; -}; - -//typedef t_CRCMap CRC32Map ; -typedef t_CRCMap Sha1Map ; - -/* class which encapsulates download details */ -class DwlDetails { -public: - DwlDetails() { return; } - DwlDetails(const std::string& fname, const RsFileHash& hash, int count, std::string dest, - uint32_t flags, std::list srcIds, uint32_t queue_pos) - : fname(fname), hash(hash), count(count), dest(dest), flags(flags), - srcIds(srcIds), queue_position(queue_pos), retries(0) { return; } - - /* download details */ - std::string fname; - RsFileHash hash; - int count; - std::string dest; - uint32_t flags; - std::list srcIds; - - /* internally used in download queue */ - uint32_t queue_position; - - /* how many times a failed dwl will be requeued */ - unsigned int retries; -}; - -/* class for the information about a used library */ -class RsLibraryInfo -{ -public: - RsLibraryInfo() {} - RsLibraryInfo(const std::string &name, const std::string &version) : - mName(name), mVersion(version) - {} - -public: - std::string mName; - std::string mVersion; -}; - -#endif diff --git a/libretroshare/src/retroshare/rsversion.h b/libretroshare/src/retroshare/rsversion.h deleted file mode 100644 index 3d853bc1f..000000000 --- a/libretroshare/src/retroshare/rsversion.h +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsversion.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2018 Retroshare Team * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/** - * @def RS_MINI_VERSION - * First number of RetroShare versioning scheme - * Customize it trough qmake command line @see retroshare.pri - */ -#ifndef RS_MAJOR_VERSION -# define RS_MAJOR_VERSION 0 -#endif - -/** - * @def RS_MINI_VERSION - * Second number of RetroShare versioning scheme - * Customize it trough qmake command line @see retroshare.pri - */ -#ifndef RS_MINOR_VERSION -# define RS_MINOR_VERSION 6 -#endif - -/** - * @def RS_MINI_VERSION - * Third number of RetroShare versioning scheme - * Customize it trough qmake command line @see retroshare.pri - */ -#ifndef RS_MINI_VERSION -# define RS_MINI_VERSION 6 -#endif - -/** - * @def RS_EXTRA_VERSION - * An extra string to append to the version to make it more descriptive. - * Customize it trough qmake command line @see retroshare.pri - */ -#ifndef RS_EXTRA_VERSION -# define RS_EXTRA_VERSION "-RC2" -#endif - - -/** - * Use this macro to check in your code if version of RetroShare is at least the - * specified. - */ -#define RS_VERSION_AT_LEAST(A,B,C) (RS_MAJOR_VERSION > (A) || \ - (RS_MAJOR_VERSION == (A) && \ - (RS_MINOR_VERSION > (B) || \ - (RS_MINOR_VERSION == (B) && RS_MINI_VERSION >= (C))))) - - -#define RS_PRIVATE_STRINGIFY2(X) #X -#define RS_PRIVATE_STRINGIFY(X) RS_PRIVATE_STRINGIFY2(X) - -/** - * Human readable string describing RetroShare version - */ -constexpr auto RS_HUMAN_READABLE_VERSION = - RS_PRIVATE_STRINGIFY(RS_MAJOR_VERSION) "." \ - RS_PRIVATE_STRINGIFY(RS_MINOR_VERSION) "." \ - RS_PRIVATE_STRINGIFY(RS_MINI_VERSION) RS_EXTRA_VERSION; - -/* Because RetroShare-gui include this file in gui/images/retroshare_win.rc - * including any C++ things like `#include ` will break compilation of - * RetroShare-gui on Windows. Therefore this file must be kept minimal. */ diff --git a/libretroshare/src/retroshare/rswebui.h b/libretroshare/src/retroshare/rswebui.h deleted file mode 100644 index d7166f545..000000000 --- a/libretroshare/src/retroshare/rswebui.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * RetroShare Web User Interface public header - * - * Copyright (C) 2019 Cyril Soler - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see - * - * SPDX-FileCopyrightText: 2004-2019 RetroShare Team - * SPDX-License-Identifier: LGPL-3.0-or-later - */ - -#pragma once - -#include - -class RsWebUi; - -/** - * Pointer to global instance of RsWebUi service implementation - * jsonapi_temporarly_disabled{development} because it breaks compilation when - * webui is disabled - */ -extern RsWebUi* rsWebUi; - -class RsWebUi -{ -public: - static const std::string DEFAULT_BASE_DIRECTORY; - - /** - * @brief Restart WebUI - * @jsonapi{development} - */ - virtual bool restart() = 0; - - /** - * @brief Stop WebUI - * @jsonapi{development} - */ - virtual bool stop() = 0; - - /** - * @brief Set WebUI static files directory, need restart to apply - * @param[in] htmlDir directory path - * @jsonapi{development} - */ - virtual void setHtmlFilesDirectory(const std::string& htmlDir) = 0; - - /** - * @brief Set WebUI user password - * @param[in] password new password for WebUI - * @jsonapi{development} - */ - virtual void setUserPassword(const std::string& password) =0; - - /** - * @brief check if WebUI is running - * @jsonapi{development} - * @return true if running, false otherwise - */ - virtual bool isRunning() const = 0; - - virtual ~RsWebUi() = default; -}; diff --git a/libretroshare/src/retroshare/rswiki.h b/libretroshare/src/retroshare/rswiki.h deleted file mode 100644 index 401f2cbab..000000000 --- a/libretroshare/src/retroshare/rswiki.h +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsturtle.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_WIKI_GUI_INTERFACE_H -#define RETROSHARE_WIKI_GUI_INTERFACE_H - -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" - -/* The Main Interface Class - for information about your Peers */ -class RsWiki; -extern RsWiki *rsWiki; - - -/* so the basic idea of Wiki is a set of Collections about subjects. - * - * Collection: RS - * - page: DHT - * - edit - * - edit - * - official revision. (new version of thread head). - * - * A collection will be moderated by it creator - important to prevent stupid changes. - * We need a way to swap out / replace / fork collections if moderator is rubbish. - * - * This should probably be done that the collection level. - * and enable all the references to be modified. - * - * Collection1 (RS DHT) - * : Turtle Link: Collection 0x54e4dafc34 - * - Page 1 - * - Page 2 - * - Link to Self:Page 1 - * - Link to Turtle:Page 1 - * - * - */ - -#define FLAG_MSG_TYPE_WIKI_SNAPSHOT 0x0001 -#define FLAG_MSG_TYPE_WIKI_COMMENT 0x0002 - -class CollectionRef -{ - public: - - std::string KeyWord; - std::string CollectionId; -}; - -struct RsWikiCollection: RsGxsGenericGroupData -{ - public: - std::string mDescription; - std::string mCategory; - - std::string mHashTags; - - // std::map linkReferences; -}; - -class RsWikiSnapshot -{ - public: - - RsMsgMetaData mMeta; - - std::string mPage; // all the text is stored here. - std::string mHashTags; -}; - - -class RsWikiComment -{ - public: - - RsMsgMetaData mMeta; - std::string mComment; -}; - -std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group); -std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot); -std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment); - - -class RsWiki: public RsGxsIfaceHelper -{ -public: - - RsWiki(RsGxsIface& gxs): RsGxsIfaceHelper(gxs) {} - virtual ~RsWiki() {} - - /* Specific Service Data */ -virtual bool getCollections(const uint32_t &token, std::vector &collections) = 0; -virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots) = 0; -virtual bool getComments(const uint32_t &token, std::vector &comments) = 0; - -virtual bool getRelatedSnapshots(const uint32_t &token, std::vector &snapshots) = 0; - -virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) = 0; -virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) = 0; -virtual bool submitComment(uint32_t &token, RsWikiComment &comment) = 0; - -virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) = 0; - - // Blocking Interfaces. -virtual bool createCollection(RsWikiCollection &collection) = 0; -virtual bool updateCollection(const RsWikiCollection &collection) = 0; -virtual bool getCollections(const std::list groupIds, std::vector &groups) = 0; - -}; - -#endif diff --git a/libretroshare/src/retroshare/rswire.h b/libretroshare/src/retroshare/rswire.h deleted file mode 100644 index 34c953cee..000000000 --- a/libretroshare/src/retroshare/rswire.h +++ /dev/null @@ -1,250 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsturtle.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2020 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_WIRE_GUI_INTERFACE_H -#define RETROSHARE_WIRE_GUI_INTERFACE_H - -#include -#include -#include - -#include "retroshare/rstokenservice.h" -#include "retroshare/rsgxsifacehelper.h" -#include "retroshare/rsgxscommon.h" - - -/* The Main Interface Class - for information about your Peers */ -class RsWire; -extern RsWire *rsWire; - -class RsWireGroup; -typedef std::shared_ptr RsWireGroupSPtr; -typedef std::shared_ptr RsWireGroupConstSPtr; - -class RsWireGroup: public RsGxsGenericGroupData -{ - public: - RsWireGroup(); - - std::string mTagline; - std::string mLocation; - - // Images max size should be enforced. - RsGxsImage mHeadshot; // max size? - RsGxsImage mMasthead; // max size? - - // Unserialised stuff --------------------- - - // These are this groups top-level msgs. - uint32_t mGroupPulses; - uint32_t mGroupRepublishes; - uint32_t mGroupLikes; - uint32_t mGroupReplies; - // how do we handle these. TODO - // uint32_t mGroupFollowing; - // uint32_t mGroupFollowers; - - // These are this groups REF / RESPONSE msgs from others. - uint32_t mRefMentions; // TODO how to handle this? - uint32_t mRefRepublishes; - uint32_t mRefLikes; - uint32_t mRefReplies; -}; - - -/*********************************************************************** - * RsWire - is intended to be a Twitter clone - but fully decentralised. - * - * From Twitter: - * twitter can be: embedded, replied to, favourited, unfavourited, - * retweeted, unretweeted and deleted - * - * See: https://dev.twitter.com/docs/platform-objects - * - * Format of message: .... - * - * #HashTags. - * @68769381495134 => ID of Sender. - * - * - ***********************************************************************/ - - - -/************************************************************************ - * Pulse comes in three flavours. - * - * - * Original Msg Pulse - * - Spontaneous msg, on your own group. - * - mPulseType = WIRE_PULSE_TYPE_ORIGINAL_MSG - * - Ref fields are empty. - * - * Reply to a Pulse (i.e Retweet), has two parts. - * as we want the retweet to reference the original, and the original to know about reply. - * This info will be duplicated in two msgs - but allow data to spread easier. - * - * Reply Msg Pulse, will be Top-Level Msg on Publisher's Group. - * - mPulseMode = WIRE_PULSE_TYPE_RESPONSE | WIRE_PULSE_TYPE_REPLY - * - Ref fields refer to Parent (InReplyTo) Msg. - * - * Reply Reference, is Child Msg of Parent Msg, on Parent Publisher's Group. - * - mPulseMode = WIRE_PULSE_TYPE_REFERENCE | WIRE_PULSE_TYPE_REPLY - * - Ref fields refer to Reply Msg. - * - NB: This Msg requires Parent Msg for complete info, while other two are self-contained. - * - * Additionally need to sort out additional relationships. - * - Mentions. - * - Followers. - * - Following. - ***********************************************************************/ - -#define WIRE_PULSE_TYPE_ORIGINAL (0x0001) -#define WIRE_PULSE_TYPE_RESPONSE (0x0002) -#define WIRE_PULSE_TYPE_REFERENCE (0x0004) - -#define WIRE_PULSE_RESPONSE_MASK (0x0f00) -#define WIRE_PULSE_TYPE_REPLY (0x0100) -#define WIRE_PULSE_TYPE_REPUBLISH (0x0200) -#define WIRE_PULSE_TYPE_LIKE (0x0400) - -#define WIRE_PULSE_SENTIMENT_NO_SENTIMENT (0x0000) -#define WIRE_PULSE_SENTIMENT_POSITIVE (0x0001) -#define WIRE_PULSE_SENTIMENT_NEUTRAL (0x0002) -#define WIRE_PULSE_SENTIMENT_NEGATIVE (0x0003) - -class RsWirePulse; - -typedef std::shared_ptr RsWirePulseSPtr; -typedef std::shared_ptr RsWirePulseConstSPtr; - -class RsWirePulse -{ - public: - - RsMsgMetaData mMeta; - - // Store actual Pulse here. - std::string mPulseText; - - uint32_t mPulseType; - uint32_t mSentiment; // sentiment can be asserted at any point. - - // These Ref to the related (parent or reply) if reply (RESPONSE set) - // Mode RESPONSE REFERENCE - RsGxsGroupId mRefGroupId; // PARENT_GrpId REPLY_GrpId - std::string mRefGroupName; // PARENT_GrpName REPLY_GrpName - RsGxsMessageId mRefOrigMsgId; // PARENT_OrigMsgId REPLY_OrigMsgId - RsGxsId mRefAuthorId; // PARENT_AuthorId REPLY_AuthorId - rstime_t mRefPublishTs; // PARENT_PublishTs REPLY_PublishTs - std::string mRefPulseText; // PARENT_PulseText REPLY_PulseText - uint32_t mRefImageCount; // PARENT_#Images REPLY_#Images - - // Additional Fields for version 2. - // Images, need to enforce 20k limit? - RsGxsImage mImage1; - RsGxsImage mImage2; - RsGxsImage mImage3; - RsGxsImage mImage4; - - // Below Here is not serialised. - // They are additional fields linking pulses together or parsing elements of msg. - - // functions. - uint32_t ImageCount(); - - // can't have self referencial list, so need to use pointers. - // using SharedPointers to automatically cleanup. - - // Pointer to WireGroups - // mRefGroupPtr is opportunistically filled in, but will often be empty. - RsWireGroupSPtr mRefGroupPtr; // ORIG: N/A, RESP: Parent, REF: Reply Group - RsWireGroupSPtr mGroupPtr; // ORIG: Own, RESP: Own, REF: Parent Group - - // These are the direct children of this message - // split into likes, replies and retweets. - std::list mReplies; - std::list mLikes; - std::list mRepublishes; - - // parsed from msg. - // do we need references..? - std::list mHashTags; - std::list mMentions; - std::list mUrls; -}; - - -std::ostream &operator<<(std::ostream &out, const RsWireGroup &group); -std::ostream &operator<<(std::ostream &out, const RsWirePulse &pulse); - - -class RsWire: public RsGxsIfaceHelper -{ - public: - - explicit RsWire(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {} - virtual ~RsWire() {} - - /*! - * To acquire a handle to token service handler - * needed to make requests to the service - * @return handle to token service for this gxs service - */ - virtual RsTokenService* getTokenService() = 0; - - /* Specific Service Data */ -virtual bool getGroupData(const uint32_t &token, std::vector &groups) = 0; -virtual bool getPulseData(const uint32_t &token, std::vector &pulses) = 0; - -virtual bool createGroup(uint32_t &token, RsWireGroup &group) = 0; -virtual bool createPulse(uint32_t &token, RsWirePulse &pulse) = 0; - - // Blocking Interfaces. -virtual bool createGroup(RsWireGroup &group) = 0; -virtual bool updateGroup(const RsWireGroup &group) = 0; -virtual bool getGroups(const std::list grpIds, - std::vector &groups) = 0; - - // New Blocking Interfaces. - // Plan to migrate all GUI calls to these, and remove old interfaces above. - // These are not single requests, but return data graphs for display. -virtual bool createOriginalPulse(const RsGxsGroupId &grpId, RsWirePulseSPtr pPulse) = 0; -virtual bool createReplyPulse(RsGxsGroupId grpId, RsGxsMessageId msgId, - RsGxsGroupId replyWith, uint32_t reply_type, - RsWirePulseSPtr pPulse) = 0; - - - // Provide Individual Group Details for display. -virtual bool getWireGroup(const RsGxsGroupId &groupId, RsWireGroupSPtr &grp) = 0; -virtual bool getWirePulse(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, RsWirePulseSPtr &pPulse) = 0; - - // Provide list of pulses associated with groups. -virtual bool getPulsesForGroups(const std::list &groupIds, - std::list &pulsePtrs) = 0; - - // Provide pulse, and associated replies / like etc. -virtual bool getPulseFocus(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, - int type, RsWirePulseSPtr &pPulse) = 0; - -}; - -#endif diff --git a/libretroshare/src/rs_upnp/UPnPBase.cpp b/libretroshare/src/rs_upnp/UPnPBase.cpp deleted file mode 100644 index 353812469..000000000 --- a/libretroshare/src/rs_upnp/UPnPBase.cpp +++ /dev/null @@ -1,1755 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: UPnPBase.cpp * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2004-2009 Marcelo Roberto Jimenez ( phoenix@amule.org ) * - * Copyright (c) 2006-2009 aMule Team ( admin@amule.org / http://www.amule.org)* - * Copyright (c) 2009-2010 Retroshare Team * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#define UPNP_C - -#include "UPnPBase.h" - -#include -#include -#include // for std::istringstream -#include // For transform() - -#include "util/rsstring.h" -#include "rs_upnp/upnp18_retrocompat.h" -#include "util/rstime.h" -#include "util/rsdebug.h" - -#ifdef __GNUC__ - #if __GNUC__ >= 4 - #define REINTERPRET_CAST(x) reinterpret_cast - #endif -#endif -#ifndef REINTERPRET_CAST - // Let's hope that function pointers are equal in size to data pointers - #define REINTERPRET_CAST(x) (x) -#endif - - -/** - * Case insensitive std::string comparison - */ -bool stdStringIsEqualCI(const std::string &s1, const std::string &s2) -{ - std::string ns1(s1); - std::string ns2(s2); - std::transform(ns1.begin(), ns1.end(), ns1.begin(), tolower); - std::transform(ns2.begin(), ns2.end(), ns2.begin(), tolower); - return ns1 == ns2; -} - - -CUPnPPortMapping::CUPnPPortMapping( - int ex_port, - int in_port, - const std::string &protocol, - bool enabled, - const std::string &description) -: -m_ex_port(), -m_in_port(), -m_protocol(protocol), -m_enabled(enabled ? "1" : "0"), -m_description(description), -m_key() -{ - rs_sprintf(m_ex_port, "%d", ex_port); - rs_sprintf(m_in_port, "%d", in_port); - m_key = m_protocol + m_ex_port; -} - - -const std::string &CUPnPLib::UPNP_ROOT_DEVICE = - "upnp:rootdevice"; - -const std::string &CUPnPLib::UPNP_DEVICE_IGW = - "urn:schemas-upnp-org:device:InternetGatewayDevice:1"; -const std::string &CUPnPLib::UPNP_DEVICE_WAN = - "urn:schemas-upnp-org:device:WANDevice:1"; -const std::string &CUPnPLib::UPNP_DEVICE_WAN_CONNECTION = - "urn:schemas-upnp-org:device:WANConnectionDevice:1"; -const std::string &CUPnPLib::UPNP_DEVICE_LAN = - "urn:schemas-upnp-org:device:LANDevice:1"; - -const std::string &CUPnPLib::UPNP_SERVICE_LAYER3_FORWARDING = - "urn:schemas-upnp-org:service:Layer3Forwarding:1"; -const std::string &CUPnPLib::UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG = - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"; -const std::string &CUPnPLib::UPNP_SERVICE_WAN_IP_CONNECTION = - "urn:schemas-upnp-org:service:WANIPConnection:1"; -const std::string &CUPnPLib::UPNP_SERVICE_WAN_PPP_CONNECTION = - "urn:schemas-upnp-org:service:WANPPPConnection:1"; - - -CUPnPLib::CUPnPLib(CUPnPControlPoint &ctrlPoint) -: -m_ctrlPoint(ctrlPoint) -{ -} - - -std::string CUPnPLib::GetUPnPErrorMessage(int code) const -{ - return UpnpGetErrorMessage(code); -} - - -std::string CUPnPLib::processUPnPErrorMessage( - const std::string &message, - int errorCode, - const DOMString errorString, - const IXML_Document* doc) const -{ - /* remove unused parameter warnings */ - (void) message; - (void) errorCode; - (void) errorString; - (void) doc; - - std::string msg; -#ifdef UPNP_DEBUG - if (errorString == NULL || *errorString == 0) { - errorString = "Not available"; - } - if (errorCode > 0) { - std::cerr << "CUPnPLib::processUPnPErrorMessage() Error: " << - message << - ": Error code :'"; - if (doc) { - CUPnPError e(*this, doc); - std::cerr << e.getErrorCode() << - "', Error description :'" << - e.getErrorDescription() << - "'."; - } else { - std::cerr << errorCode << - "', Error description :'" << - errorString << - "'."; - } - std::cerr << std::endl; - } else { - std::cerr << "CUPnPLib::processUPnPErrorMessage() Error: " << - message << - ": UPnP SDK error: " << - GetUPnPErrorMessage(errorCode) << - " (" << errorCode << ")."; - std::cerr << std::endl; - } -#endif - return msg; -} - - -void CUPnPLib::ProcessActionResponse( - const IXML_Document* RespDoc, - const std::string &actionName) const -{ - /* remove unused parameter warnings */ - (void) actionName; - - IXML_Element *root = Element_GetRootElement(RespDoc); - IXML_Element *child = Element_GetFirstChild(root); - if (child) { - while (child) { - const DOMString childTag = Element_GetTag(child); - std::string childValue = Element_GetTextValue(child); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPLib::ProcessActionResponse() \n " << - childTag << "='" << - childValue << "'"; -#endif - //add the variable to the wanservice property map - (m_ctrlPoint.m_WanService->propertyMap)[std::string(childTag)] = std::string(childValue); - child = Element_GetNextSibling(child); - } - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPLib::ProcessActionResponse() \n Empty response for action '" << - actionName << "'."; -#endif - } -#ifdef UPNP_DEBUG - std::cerr << std::endl; -#endif -} - - -/*! - * \brief Returns the root node of a given document. - */ -IXML_Element *CUPnPLib::Element_GetRootElement( - const IXML_Document* doc) const -{ - IXML_Element* root = REINTERPRET_CAST(IXML_Element *)( - ixmlNode_getFirstChild( - REINTERPRET_CAST(IXML_Node *)(const_cast(doc)))); - - return root; -} - - -/*! - * \brief Returns the first child of a given element. - */ -IXML_Element *CUPnPLib::Element_GetFirstChild( - IXML_Element *parent) const -{ - IXML_Node *node = REINTERPRET_CAST(IXML_Node *)(parent); - IXML_Node *child = ixmlNode_getFirstChild(node); - - return REINTERPRET_CAST(IXML_Element *)(child); -} - - -/*! - * \brief Returns the next sibling of a given child. - */ -IXML_Element *CUPnPLib::Element_GetNextSibling( - IXML_Element *child) const -{ - IXML_Node *node = REINTERPRET_CAST(IXML_Node *)(child); - IXML_Node *sibling = ixmlNode_getNextSibling(node); - - return REINTERPRET_CAST(IXML_Element *)(sibling); -} - - -/*! - * \brief Returns the element tag (name) - */ -const DOMString CUPnPLib::Element_GetTag( - IXML_Element *element) const -{ - IXML_Node *node = REINTERPRET_CAST(IXML_Node *)(element); - const DOMString tag = ixmlNode_getNodeName(node); - - return tag; -} - - -/*! - * \brief Returns the TEXT node value of the current node. - */ -const std::string CUPnPLib::Element_GetTextValue( - IXML_Element *element) const -{ - if (!element) { - return stdEmptyString; - } - IXML_Node *text = ixmlNode_getFirstChild( - REINTERPRET_CAST(IXML_Node *)(element)); - const DOMString s = ixmlNode_getNodeValue(text); - std::string ret; - if (s) { - ret = s; - } - - return ret; -} - - -/*! - * \brief Returns the TEXT node value of the first child matching tag. - */ -const std::string CUPnPLib::Element_GetChildValueByTag( - IXML_Element *element, - const DOMString tag) const -{ - IXML_Element *child = - Element_GetFirstChildByTag(element, tag); - - return Element_GetTextValue(child); -} - - -/*! - * \brief Returns the first child element that matches the requested tag or - * NULL if not found. - */ -IXML_Element *CUPnPLib::Element_GetFirstChildByTag( - IXML_Element *element, - const DOMString tag) const -{ - if (!element || !tag) { - return NULL; - } - - IXML_Node *node = REINTERPRET_CAST(IXML_Node *)(element); - IXML_Node *child = ixmlNode_getFirstChild(node); - const DOMString childTag = ixmlNode_getNodeName(child); - while(child && childTag && strcmp(tag, childTag)) { - child = ixmlNode_getNextSibling(child); - childTag = ixmlNode_getNodeName(child); - } - - return REINTERPRET_CAST(IXML_Element *)(child); -} - - -/*! - * \brief Returns the next sibling element that matches the requested tag. Should be - * used with the return value of Element_GetFirstChildByTag(). - */ -IXML_Element *CUPnPLib::Element_GetNextSiblingByTag( - IXML_Element *element, const DOMString tag) const -{ - if (!element || !tag) { - return NULL; - } - - IXML_Node *child = REINTERPRET_CAST(IXML_Node *)(element); - const DOMString childTag = NULL; - do { - child = ixmlNode_getNextSibling(child); - childTag = ixmlNode_getNodeName(child); - } while(child && childTag && strcmp(tag, childTag)); - - return REINTERPRET_CAST(IXML_Element *)(child); -} - - -const std::string CUPnPLib::Element_GetAttributeByTag( - IXML_Element *element, const DOMString tag) const -{ - IXML_NamedNodeMap *NamedNodeMap = ixmlNode_getAttributes( - REINTERPRET_CAST(IXML_Node *)(element)); - IXML_Node *attribute = ixmlNamedNodeMap_getNamedItem(NamedNodeMap, tag); - const DOMString s = ixmlNode_getNodeValue(attribute); - std::string ret; - if (s) { - ret = s; - } - ixmlNamedNodeMap_free(NamedNodeMap); - - return ret; -} - - -CUPnPError::CUPnPError( - const CUPnPLib &upnpLib, - const IXML_Document *errorDoc) - : - m_root (upnpLib.Element_GetRootElement(errorDoc)), - m_ErrorCode (upnpLib.Element_GetChildValueByTag(m_root, "errorCode")), - m_ErrorDescription(upnpLib.Element_GetChildValueByTag(m_root, "errorDescription")) -{ -} - - -CUPnPArgument::CUPnPArgument( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *argument, - const std::string &/*SCPDURL*/) -: -m_UPnPControlPoint(upnpControlPoint), -m_name (upnpLib.Element_GetChildValueByTag(argument, "name")), -m_direction (upnpLib.Element_GetChildValueByTag(argument, "direction")), -m_retval (upnpLib.Element_GetFirstChildByTag(argument, "retval")), -m_relatedStateVariable(upnpLib.Element_GetChildValueByTag(argument, "relatedStateVariable")) -{ - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPArgument::CUPnPArgument() \n Argument:" << - "\n name: " << m_name << - "\n direction: " << m_direction << - "\n retval: " << m_retval << - "\n relatedStateVariable: " << m_relatedStateVariable; - std::cerr << std::endl; -#endif -} - - -CUPnPAction::CUPnPAction( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *action, - const std::string &SCPDURL) -: -m_UPnPControlPoint(upnpControlPoint), -m_ArgumentList(upnpControlPoint, upnpLib, action, SCPDURL), -m_name(upnpLib.Element_GetChildValueByTag(action, "name")) -{ -#ifdef UPNP_DEBUG - std::cerr << "CUPnPAction::CUPnPAction() \n Action:" << - "\n name: " << m_name; - std::cerr << std::endl; -#endif -} - - -CUPnPAllowedValue::CUPnPAllowedValue( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *allowedValue, - const std::string &/*SCPDURL*/) -: -m_UPnPControlPoint(upnpControlPoint), -m_allowedValue(upnpLib.Element_GetTextValue(allowedValue)) -{ -#ifdef UPNP_DEBUG - std::cerr << "CUPnPAllowedValue::CUPnPAllowedValue() \n AllowedValue:" << - "\n allowedValue: " << m_allowedValue; - std::cerr << std::endl; -#endif -} - - -CUPnPStateVariable::CUPnPStateVariable( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *stateVariable, - const std::string &SCPDURL) -: -m_UPnPControlPoint(upnpControlPoint), -m_AllowedValueList(upnpControlPoint, upnpLib, stateVariable, SCPDURL), -m_name (upnpLib.Element_GetChildValueByTag(stateVariable, "name")), -m_dataType (upnpLib.Element_GetChildValueByTag(stateVariable, "dataType")), -m_defaultValue(upnpLib.Element_GetChildValueByTag(stateVariable, "defaultValue")), -m_sendEvents (upnpLib.Element_GetAttributeByTag (stateVariable, "sendEvents")) -{ -#ifdef UPNP_DEBUG - std::cerr << "CUPnPStateVariable::CUPnPStateVariable() \n StateVariable:" << - "\n name: " << m_name << - "\n dataType: " << m_dataType << - "\n defaultValue: " << m_defaultValue << - "\n sendEvents: " << m_sendEvents; - std::cerr << std::endl; -#endif -} - - -CUPnPSCPD::CUPnPSCPD( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *scpd, - const std::string &SCPDURL) -: -m_UPnPControlPoint(upnpControlPoint), -m_ActionList(upnpControlPoint, upnpLib, scpd, SCPDURL), -m_ServiceStateTable(upnpControlPoint, upnpLib, scpd, SCPDURL), -m_SCPDURL(SCPDURL) -{ -} - - -CUPnPArgumentValue::CUPnPArgumentValue() -: -m_argument(), -m_value() -{ -} - - -CUPnPArgumentValue::CUPnPArgumentValue( - const std::string &argument, const std::string &value) -: -m_argument(argument), -m_value(value) -{ -} - - -CUPnPService::CUPnPService( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *service, - const std::string &URLBase) -: -m_UPnPControlPoint(upnpControlPoint), -m_upnpLib(upnpLib), -m_serviceType(upnpLib.Element_GetChildValueByTag(service, "serviceType")), -m_serviceId (upnpLib.Element_GetChildValueByTag(service, "serviceId")), -m_SCPDURL (upnpLib.Element_GetChildValueByTag(service, "SCPDURL")), -m_controlURL (upnpLib.Element_GetChildValueByTag(service, "controlURL")), -m_eventSubURL(upnpLib.Element_GetChildValueByTag(service, "eventSubURL")), -m_timeout(1801), -m_SCPD(NULL) -{ - int errcode; - m_SID[0]=0; - - std::vector vscpdURL(URLBase.length() + m_SCPDURL.length() + 1); - char *scpdURL = &vscpdURL[0]; - errcode = UpnpResolveURL( - URLBase.c_str(), - m_SCPDURL.c_str(), - scpdURL); - if( errcode != UPNP_E_SUCCESS ) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() Error generating scpdURL from " << - "|" << URLBase << "|" << - m_SCPDURL << "|."; - std::cerr << std::endl; -#endif - } else { - m_absSCPDURL = scpdURL; - } - - std::vector vcontrolURL( - URLBase.length() + m_controlURL.length() + 1); - char *controlURL = &vcontrolURL[0]; - errcode = UpnpResolveURL( - URLBase.c_str(), - m_controlURL.c_str(), - controlURL); - if( errcode != UPNP_E_SUCCESS ) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() Error generating controlURL from " << - "|" << URLBase << "|" << - m_controlURL << "|."; - std::cerr << std::endl; -#endif - } else { - m_absControlURL = controlURL; - } - - std::vector veventURL( - URLBase.length() + m_eventSubURL.length() + 1); - char *eventURL = &veventURL[0]; - errcode = UpnpResolveURL( - URLBase.c_str(), - m_eventSubURL.c_str(), - eventURL); - if( errcode != UPNP_E_SUCCESS ) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() Error generating eventURL from " << - "|" << URLBase << "|" << - m_eventSubURL << "|."; - std::cerr << std::endl; -#endif - } else { - m_absEventSubURL = eventURL; - } - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() \n Service:" << - "\n serviceType: " << m_serviceType << - "\n serviceId: " << m_serviceId << - "\n SCPDURL: " << m_SCPDURL << - "\n absSCPDURL: " << m_absSCPDURL << - "\n controlURL: " << m_controlURL << - "\n absControlURL: " << m_absControlURL << - "\n eventSubURL: " << m_eventSubURL << - "\n absEventSubURL: " << m_absEventSubURL; - std::cerr << std::endl; -#endif - - if (m_serviceType == upnpLib.UPNP_SERVICE_WAN_IP_CONNECTION || - m_serviceType == upnpLib.UPNP_SERVICE_WAN_PPP_CONNECTION) { -#if 0 - m_serviceType == upnpLib.UPNP_SERVICE_WAN_PPP_CONNECTION || - m_serviceType == upnpLib.UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG || - m_serviceType == upnpLib.UPNP_SERVICE_LAYER3_FORWARDING) { -#endif -#if 0 -//#warning Delete this code on release. - if (!upnpLib.m_ctrlPoint.WanServiceDetected()) { - // This condition can be used to suspend the parse - // of the XML tree. -#endif -//#warning Delete this code when m_WanService is no longer used. - upnpLib.m_ctrlPoint.SetWanService(this); - // Log it -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() WAN Service Detected: '" << - m_serviceType << "'."; - std::cerr << std::endl; -#endif - // Subscribe - upnpLib.m_ctrlPoint.Subscribe(*this); -#if 0 -//#warning Delete this code on release. - } else { -#ifdef UPNP_DEBUG - std::cerr << "WAN service detected again: '" << - m_serviceType << - "'. Will only use the first instance."; - std::cerr << std::endl; -#endif - } -#endif - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::CUPnPService() Uninteresting service detected: '" << - m_serviceType << "'. Ignoring."; - std::cerr << std::endl; -#endif - } -} - - -CUPnPService::~CUPnPService() -{ -} - - -bool CUPnPService::Execute( - const std::string &ActionName, - const std::vector &ArgValue) const -{ -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() called." << std::endl; -#endif - if (m_SCPD.get() == NULL) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Service without SCPD Document, cannot execute action '" << ActionName << - "' for service '" << GetServiceType() << "'."; - std::cerr << std::endl; -#endif - return false; - } -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Sending action " << std::endl; -#endif - // Check for correct action name - ActionList::const_iterator itAction = - m_SCPD->GetActionList().find(ActionName); - if (itAction == m_SCPD->GetActionList().end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() invalid action name '" << ActionName << - "' for service '" << GetServiceType() << "'."; - std::cerr << std::endl; -#endif - return false; - } -#ifdef UPNP_DEBUG - std::cerr << ActionName << "("; -#endif - bool firstTime = true; - // Check for correct Argument/Value pairs - const CUPnPAction &action = *(itAction->second); - for (unsigned int i = 0; i < ArgValue.size(); ++i) { - ArgumentList::const_iterator itArg = - action.GetArgumentList().find(ArgValue[i].GetArgument()); - if (itArg == action.GetArgumentList().end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Invalid argument name '" << ArgValue[i].GetArgument() << - "' for action '" << action.GetName() << - "' for service '" << GetServiceType() << "'."; - std::cerr << std::endl; -#endif - return false; - } - const CUPnPArgument &argument = *(itArg->second); - if (tolower(argument.GetDirection()[0]) != 'i' || - tolower(argument.GetDirection()[1]) != 'n') { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Invalid direction for argument '" << - ArgValue[i].GetArgument() << - "' for action '" << action.GetName() << - "' for service '" << GetServiceType() << "'."; - std::cerr << std::endl; -#endif - return false; - } - const std::string relatedStateVariableName = - argument.GetRelatedStateVariable(); - if (!relatedStateVariableName.empty()) { - ServiceStateTable::const_iterator itSVT = - m_SCPD->GetServiceStateTable(). - find(relatedStateVariableName); - if (itSVT == m_SCPD->GetServiceStateTable().end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Inconsistent Service State Table, did not find '" << - relatedStateVariableName << - "' for argument '" << argument.GetName() << - "' for action '" << action.GetName() << - "' for service '" << GetServiceType() << "'."; - std::cerr << std::endl; -#endif - return false; - } - const CUPnPStateVariable &stateVariable = *(itSVT->second); - if ( !stateVariable.GetAllowedValueList().empty() && - stateVariable.GetAllowedValueList().find(ArgValue[i].GetValue()) == - stateVariable.GetAllowedValueList().end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Value not allowed '" << ArgValue[i].GetValue() << - "' for state variable '" << relatedStateVariableName << - "' for argument '" << argument.GetName() << - "' for action '" << action.GetName() << - "' for service '" << GetServiceType() << "'."; -#endif - - return false; - } - } - if (firstTime) { - firstTime = false; - } else { -#ifdef UPNP_DEBUG - std::cerr << ", "; -#endif - } -#ifdef UPNP_DEBUG - std::cerr << - ArgValue[i].GetArgument() << - "='" << - ArgValue[i].GetValue() << - "'"; -#endif - } -#ifdef UPNP_DEBUG - std::cerr << ")" << std::endl; -#endif - // Everything is ok, make the action - IXML_Document *ActionDoc = NULL; - if (ArgValue.size()) { - for (unsigned int i = 0; i < ArgValue.size(); ++i) { - int ret = UpnpAddToAction( - &ActionDoc, - action.GetName().c_str(), - GetServiceType().c_str(), - ArgValue[i].GetArgument().c_str(), - ArgValue[i].GetValue().c_str()); - if (ret != UPNP_E_SUCCESS) { - m_upnpLib.processUPnPErrorMessage( - "UpnpAddToAction", ret, NULL, NULL); - return false; - } - } - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() UpnpMakeAction" << std::endl; -#endif - ActionDoc = UpnpMakeAction( - action.GetName().c_str(), - GetServiceType().c_str(), - 0, NULL); - if (!ActionDoc) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::Execute() Error: UpnpMakeAction returned NULL." << std::endl; -#endif - return false; - } - } - - // Send the action asynchronously - UpnpSendActionAsync( - m_UPnPControlPoint.GetUPnPClientHandle(), - GetAbsControlURL().c_str(), - GetServiceType().c_str(), - NULL, ActionDoc, - reinterpret_cast(&CUPnPControlPoint::Callback), - NULL); - return true; -} - - -const std::string CUPnPService::GetStateVariable( - const std::string &stateVariableName) -{ - std::map::iterator it; - it = propertyMap.find(stateVariableName); - if (it != propertyMap.end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::GetStateVariable(" << stateVariableName << ") = " << (*it).second << std::endl; -#endif - return (*it).second; - } else { - //property map is not populated with the specified value. - //we will try to get it with an event - - //this getvar is just to make the event happening - DOMString StVarVal; - UpnpGetServiceVarStatus( - m_UPnPControlPoint.GetUPnPClientHandle(), - GetAbsControlURL().c_str(), - stateVariableName.c_str(), - &StVarVal); - if (StVarVal != NULL) { - std::string varValue = std::string(StVarVal); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::GetStateVariable() varValue returned by UpnpGetServiceVarStatus : " << varValue << std::endl; -#endif - return varValue; - } else { - //use event to get state variable -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::GetStateVariable() pausing in case of an UPnP event incomming."; -#endif - rstime_t begin_time = time(NULL); - while (true) { - if (time(NULL) - begin_time > 7) { - break; - } - } - } - - //propertyMap should be populated by nom - it = propertyMap.find(stateVariableName); - if (it != propertyMap.end()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::GetStateVariable(" << stateVariableName << ") = " << (*it).second << std::endl; -#endif - return (*it).second; - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPService::GetStateVariable(" << stateVariableName << ") = " << "Empty String" << std::endl; -#endif - return stdEmptyString; - } - } -} - - -CUPnPDevice::CUPnPDevice( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *device, - const std::string &URLBase) -: -m_UPnPControlPoint(upnpControlPoint), -m_DeviceList(upnpControlPoint, upnpLib, device, URLBase), -m_ServiceList(upnpControlPoint, upnpLib, device, URLBase), -m_deviceType (upnpLib.Element_GetChildValueByTag(device, "deviceType")), -m_friendlyName (upnpLib.Element_GetChildValueByTag(device, "friendlyName")), -m_manufacturer (upnpLib.Element_GetChildValueByTag(device, "manufacturer")), -m_manufacturerURL (upnpLib.Element_GetChildValueByTag(device, "manufacturerURL")), -m_modelDescription (upnpLib.Element_GetChildValueByTag(device, "modelDescription")), -m_modelName (upnpLib.Element_GetChildValueByTag(device, "modelName")), -m_modelNumber (upnpLib.Element_GetChildValueByTag(device, "modelNumber")), -m_modelURL (upnpLib.Element_GetChildValueByTag(device, "modelURL")), -m_serialNumber (upnpLib.Element_GetChildValueByTag(device, "serialNumber")), -m_UDN (upnpLib.Element_GetChildValueByTag(device, "UDN")), -m_UPC (upnpLib.Element_GetChildValueByTag(device, "UPC")), -m_presentationURL (upnpLib.Element_GetChildValueByTag(device, "presentationURL")) -{ - int presURLlen = strlen(URLBase.c_str()) + - strlen(m_presentationURL.c_str()) + 2; - std::vector vpresURL(presURLlen); - char* presURL = &vpresURL[0]; - int errcode = UpnpResolveURL( - URLBase.c_str(), - m_presentationURL.c_str(), - presURL); - if (errcode != UPNP_E_SUCCESS) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPDevice::CUPnPDevice() Error generating presentationURL from " << - "|" << URLBase << "|" << - m_presentationURL << "|."; - std::cerr << std::endl; -#endif - } else { - m_presentationURL = presURL; - } - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPDevice::CUPnPDevice() \n Device: " << - "\n friendlyName: " << m_friendlyName << - "\n deviceType: " << m_deviceType << - "\n manufacturer: " << m_manufacturer << - "\n manufacturerURL: " << m_manufacturerURL << - "\n modelDescription: " << m_modelDescription << - "\n modelName: " << m_modelName << - "\n modelNumber: " << m_modelNumber << - "\n modelURL: " << m_modelURL << - "\n serialNumber: " << m_serialNumber << - "\n UDN: " << m_UDN << - "\n UPC: " << m_UPC << - "\n presentationURL: " << m_presentationURL - << std::endl; -#endif -} - - -CUPnPRootDevice::CUPnPRootDevice( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *rootDevice, - const std::string &OriginalURLBase, - const std::string &FixedURLBase, - const char *location, - int expires) -: -CUPnPDevice(upnpControlPoint, upnpLib, rootDevice, FixedURLBase), -m_UPnPControlPoint(upnpControlPoint), -m_URLBase(OriginalURLBase), -m_location(location), -m_expires(expires) -{ -#ifdef UPNP_DEBUG - std::cerr << - "CUPnPRootDevice::CUPnPRootDevice() \n Root Device: " << - "\n URLBase: " << m_URLBase << - "\n Fixed URLBase: " << FixedURLBase << - "\n location: " << m_location << - "\n expires: " << m_expires - << std::endl; -#endif -} - - -CUPnPControlPoint *CUPnPControlPoint::s_CtrlPoint = NULL; - - -CUPnPControlPoint::CUPnPControlPoint(unsigned short udpPort) -: -m_upnpLib(*this), -m_UPnPClientHandle(), -m_RootDeviceMap(), -m_ServiceMap(), -m_ActivePortMappingsMap(), -m_RootDeviceListMutex("UPnPControlPoint-RootDeviceList"), -m_IGWDeviceDetected(false), -m_WaitForSearchTimeoutMutex("UPnPControlPoint-WaitForSearchTimeout"), -m_WanService(NULL) -{ -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() Constructor" << std::endl; -#endif - // Pointer to self - s_CtrlPoint = this; - -#ifdef UPNP_DEBUG - int resLog = UpnpInitLog(); - std::cerr << "UPnPControlPoint::CUPnPControlPoint() Init log : " << resLog << std::endl; -#endif - -#if UPNP_VERSION < 11400 - int ret = UpnpInit(nullptr, udpPort); -#else - int ret = UpnpInit2(nullptr, udpPort); -#endif - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint Constructor UpnpInit finished" << std::endl; -#endif - if (ret != UPNP_E_SUCCESS && ret !=UPNP_E_INIT) { -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() error(UpnpInit): Error code : "; -#endif - goto error; - } - - RS_INFO("bound to ", UpnpGetServerIpAddress(), ":", UpnpGetServerPort()); - - ret = UpnpRegisterClient( - reinterpret_cast(&CUPnPControlPoint::Callback), - &m_UPnPClientHandle, - &m_UPnPClientHandle); - if (ret != UPNP_E_SUCCESS) { -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() error(UpnpRegisterClient): Error registering callback: "; -#endif - goto error; - } - - // We could ask for just the right device here. If the root device - // contains the device we want, it will respond with the full XML doc, - // including the root device and every sub-device it has. - // - // But lets find out what we have in our network by calling UPNP_ROOT_DEVICE. - // - // We should not search twice, because this will produce two - // UPNP_DISCOVERY_SEARCH_TIMEOUT events, and we might end with problems - // on the mutex. -// UpnpSetContentLength(m_UPnPClientHandle, 5000000); -// UpnpSetMaxContentLength(5000000); - ret = UpnpSearchAsync(m_UPnPClientHandle, 20, m_upnpLib.UPNP_DEVICE_IGW.c_str(), NULL); - //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_IGW.c_str(), this); - //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_LAN.c_str(), this); - //ret = UpnpSearchAsync(m_UPnPClientHandle, 3, m_upnpLib.UPNP_DEVICE_WAN_CONNECTION.c_str(), this); - if (ret != UPNP_E_SUCCESS) { -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() error(UpnpSearchAsync): Error sending search request: "; -#endif - goto error; - } - - // Wait for the UPnP initialization to complete. - { - // Lock the search timeout mutex - m_WaitForSearchTimeoutMutex.lock(); - - // Lock it again, so that we block. Unlocking will only happen - // when the UPNP_DISCOVERY_SEARCH_TIMEOUT event occurs at the - // callback. -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() blocking m_WaitForSearchTimeoutMutex." << std::endl; -#endif - //RsMutex toto(m_WaitForSearchTimeoutMutex); - m_WaitForSearchTimeoutMutex.lock(); -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() m_WaitForSearchTimeoutMutex blocking finished." << std::endl; -#endif - } - - //clean the PortMappingNumberOfEntries as it is erroneus on the first event with the french neufbox - if (WanServiceDetected()) { - m_WanService->propertyMap.erase("PortMappingNumberOfEntries"); - } - -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() CUPnPControlPoint Constructor finished" << std::endl; -#endif - return; - - // Error processing -error: -#ifdef UPNP_DEBUG - std::cerr << ret << ": " << m_upnpLib.GetUPnPErrorMessage(ret) << "." << std::endl; -#endif - UpnpFinish(); -#ifdef UPNP_DEBUG - std::cerr << "UPnPControlPoint::CUPnPControlPoint() UpnpFinish called within CUPnPControlPoint constructor." << std::endl; -#endif -} - - -char* CUPnPControlPoint::getInternalIpAddress() -{ - char * addr = UpnpGetServerIpAddress(); - if (addr == NULL) { - addr = new char[10] ; - sprintf(addr,"%s","127.0.0.1"); - } - return addr; -} - -CUPnPControlPoint::~CUPnPControlPoint() -{ - for( RootDeviceMap::iterator it = m_RootDeviceMap.begin(); - it != m_RootDeviceMap.end(); - ++it) { - delete it->second; - } - // Remove all first - // RemoveAll(); - UpnpUnRegisterClient(m_UPnPClientHandle); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::~CUPnPControlPoint() UpnpFinish called within CUPnPControlPoint destructor." << std::endl; -#endif - UpnpFinish(); -} - - -bool CUPnPControlPoint::AddPortMappings( - std::vector &upnpPortMapping) -{ - if (!WanServiceDetected()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::AddPortMappings() UPnP Error: " - "CUPnPControlPoint::AddPortMapping: " - "WAN Service not detected." << std::endl; -#endif - return false; - } -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::AddPortMappings() called." << std::endl; -#endif - - int n = upnpPortMapping.size(); - bool ok = false; - - // Check the number of port mappings before - //have a little break in case we just modified the variable, so we have to wait for an event -// std::cerr << "GetStateVariable pausing in case of an UPnP event incomming."; -// rstime_t begin_time = time(NULL); -// while (true) { -// if (time(NULL) - begin_time > 7) { -// break; -// } -// } - std::istringstream OldPortMappingNumberOfEntries( - m_WanService->GetStateVariable( - "PortMappingNumberOfEntries")); - int oldNumberOfEntries; - OldPortMappingNumberOfEntries >> oldNumberOfEntries; - - // Add the enabled port mappings - for (int i = 0; i < n; ++i) { - if (upnpPortMapping[i].getEnabled() == "1") { - // Add the mapping to the control point - // active mappings list - m_ActivePortMappingsMap[upnpPortMapping[i].getKey()] = - upnpPortMapping[i]; - - // Add the port mapping - PrivateAddPortMapping(upnpPortMapping[i]); - } - } - - // Not very good, must find a better test : check the new number of port entries - //have a little break in case we just modified the variable, so we have to wait for an event -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::AddPortMappings() GetStateVariable pausing in case of an UPnP event incomming."; -#endif - rstime_t begin_time = time(NULL); - while (true) { - if (time(NULL) - begin_time > 4) { - break; - } - } - std::istringstream NewPortMappingNumberOfEntries( - m_WanService->GetStateVariable( - "PortMappingNumberOfEntries")); - int newNumberOfEntries; - NewPortMappingNumberOfEntries >> newNumberOfEntries; -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::AddPortMappings() CUPnPControlPoint::AddPortMappings() newNumberOfEntries - oldNumberOfEntries : " << (newNumberOfEntries - oldNumberOfEntries) << std::endl; -#endif - ok = newNumberOfEntries - oldNumberOfEntries >= 1; - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::AddPortMappings() finished. Success = " << ok << std::endl; -#endif - - return ok; -} - -std::string CUPnPControlPoint::getExternalAddress() -{ - if (!WanServiceDetected()) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::getExternalAddress() UPnP Error: " - "CUPnPControlPoint::AddPortMapping: " - "WAN Service not detected." << std::endl; -#endif - return ""; - } - std::string result = m_WanService->GetStateVariable("NewExternalIPAddress"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::getExternalAddress() m_WanService->GetStateVariable(NewExternalIPAddress) = " << result << std::endl; -#endif - if (result == "") { - PrivateGetExternalIpAdress(); - result = m_WanService->GetStateVariable("NewExternalIPAddress"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::getExternalAddress() m_WanService->GetStateVariable(NewExternalIPAddress) = " << result << std::endl; -#endif - if (result == "") { - result = m_WanService->GetStateVariable("ExternalIPAddress"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::getExternalAddress() m_WanService->GetStateVariable(ExternalIPAddress) = " << result << std::endl; -#endif - } - } - return result; -} - -void CUPnPControlPoint::RefreshPortMappings() -{ - for ( PortMappingMap::iterator it = m_ActivePortMappingsMap.begin(); - it != m_ActivePortMappingsMap.end(); - ++it) { - PrivateAddPortMapping(it->second); - } -} - - -bool CUPnPControlPoint::PrivateAddPortMapping( - CUPnPPortMapping &upnpPortMapping) -{ - // Get an IP address. The UPnP server one must do. - std::string ipAddress(UpnpGetServerIpAddress()); - - // Start building the action - std::string actionName("AddPortMapping"); - std::vector argval(8); - - // Action parameters - argval[0].SetArgument("NewRemoteHost"); - argval[0].SetValue(""); - argval[1].SetArgument("NewExternalPort"); - argval[1].SetValue(upnpPortMapping.getExPort()); - argval[2].SetArgument("NewProtocol"); - argval[2].SetValue(upnpPortMapping.getProtocol()); - argval[3].SetArgument("NewInternalPort"); - argval[3].SetValue(upnpPortMapping.getInPort()); - argval[4].SetArgument("NewInternalClient"); - argval[4].SetValue(ipAddress); - argval[5].SetArgument("NewEnabled"); - argval[5].SetValue("1"); - argval[6].SetArgument("NewPortMappingDescription"); - argval[6].SetValue(upnpPortMapping.getDescription()); - argval[7].SetArgument("NewLeaseDuration"); - argval[7].SetValue("0"); - - // Execute - bool ret = true; - for (ServiceMap::iterator it = m_ServiceMap.begin(); - it != m_ServiceMap.end(); ++it) { - ret &= it->second->Execute(actionName, argval); - } - - return ret; -} - - -bool CUPnPControlPoint::DeletePortMappings( - std::vector &upnpPortMapping) -{ -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::DeletePortMappings() called." << std::endl; -#endif - if (!WanServiceDetected()) { -#ifdef UPNP_DEBUG - std::cerr << "UPnP Error: " - "CUPnPControlPoint::DeletePortMapping: " - "WAN Service not detected." << std::endl; -#endif - return false; - } - - int n = upnpPortMapping.size(); - - // Delete the enabled port mappings - for (int i = 0; i < n; ++i) { - if (upnpPortMapping[i].getEnabled() == "1") { - // Delete the mapping from the control point - // active mappings list - PortMappingMap::iterator it = - m_ActivePortMappingsMap.find( - upnpPortMapping[i].getKey()); - if (it != m_ActivePortMappingsMap.end()) { - m_ActivePortMappingsMap.erase(it); - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::DeletePortMappings() UPnP Error: " - "CUPnPControlPoint::DeletePortMapping: " - "Mapping was not found in the active " - "mapping map." << std::endl; -#endif - } - - // Delete the port mapping - PrivateDeletePortMapping(upnpPortMapping[i]); - } - } - - return true; -} - - -bool CUPnPControlPoint::PrivateDeletePortMapping( - CUPnPPortMapping &upnpPortMapping) -{ - // Start building the action - std::string actionName("DeletePortMapping"); - std::vector argval(3); - - // Action parameters - argval[0].SetArgument("NewRemoteHost"); - argval[0].SetValue(""); - argval[1].SetArgument("NewExternalPort"); - argval[1].SetValue(upnpPortMapping.getExPort()); - argval[2].SetArgument("NewProtocol"); - argval[2].SetValue(upnpPortMapping.getProtocol()); - - // Execute - bool ret = true; - for (ServiceMap::iterator it = m_ServiceMap.begin(); - it != m_ServiceMap.end(); ++it) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::PrivateDeletePortMapping() Sending a delete port mapping action." << std::endl; -#endif - ret &= it->second->Execute(actionName, argval); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::PrivateDeletePortMapping() Delete port mapping action finished." << std::endl; -#endif - } - - return ret; -} - -bool CUPnPControlPoint::PrivateGetExternalIpAdress() -{ - // Start building the action - std::string actionName("GetExternalIPAddress"); - std::vector argval(0); - - // Execute - bool ret = true; - for (ServiceMap::iterator it = m_ServiceMap.begin(); - it != m_ServiceMap.end(); ++it) { - ret &= it->second->Execute(actionName, argval); - } - - return ret; -} - - -// This function is static -int CUPnPControlPoint::Callback( - Upnp_EventType EventType, const void* Event, void * /*Cookie*/ ) -{ - if(!Event) return 0; - - std::string msg; - std::string msg2; - - CUPnPControlPoint* upnpCP = CUPnPControlPoint::s_CtrlPoint; - if (!upnpCP) return 0; - - switch (EventType) - { - case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: /*fallthrough*/ - case UPNP_DISCOVERY_SEARCH_RESULT: - { - const UpnpDiscovery* d_event = static_cast(Event); - - // Get the XML tree device description in doc - IXML_Document* doc = nullptr; - UpnpDownloadXmlDoc(UpnpDiscovery_get_Location_cstr(d_event), &doc); - if (!doc) break; - - IXML_Element* root = upnpCP->m_upnpLib.Element_GetRootElement(doc); - - // Extract the URLBase - const std::string urlBase = upnpCP->m_upnpLib. - Element_GetChildValueByTag(root, "URLBase"); - // Get the root device - IXML_Element *rootDevice = upnpCP->m_upnpLib. - Element_GetFirstChildByTag(root, "device"); - // Extract the deviceType - std::string devType(upnpCP->m_upnpLib. - Element_GetChildValueByTag(rootDevice, "deviceType")); - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() EventType==UPNP_DISCOVERY_SEARCH_RESULT" << std::endl - << "urlBase:" << urlBase << std::endl - << "devType:" << devType << std::endl; -#endif - - // Only add device if it is an InternetGatewayDevice - if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW)) - { - // This condition can be used to auto-detect - // the UPnP device we are interested in. - // Obs.: Don't block the entry here on this - // condition! There may be more than one device, - // and the first that enters may not be the one - // we are interested in! - upnpCP->SetIGWDeviceDetected(true); - // Log it if not UPNP_DISCOVERY_ADVERTISEMENT_ALIVE, - // we don't want to spam our logs. - //if (EventType != UPNP_DISCOVERY_ADVERTISEMENT_ALIVE) { - // Add the root device to our list - upnpCP->AddRootDevice( - rootDevice, urlBase, - UpnpDiscovery_get_Location_cstr(d_event), - UpnpDiscovery_get_Expires(d_event) ); - -#if (UPNP_VERSION > 10624) && (UPNP_VERSION < 10800) - upnpCP->m_WaitForSearchTimeoutMutex.unlock(); -#endif - } - - // Free the XML doc tree - ixmlDocument_free(doc); - break; - } - case UPNP_DISCOVERY_SEARCH_TIMEOUT: - { -#if (UPNP_VERSION > 10624) && (UPNP_VERSION < 10800) - std::cerr << "********************************************************************************" << std::endl - << "*** THIS SHOULD NOT HAPPEN !!! TELL IT TO DEVS ***" << std::endl - << "*** UPnPBase.cpp CUPnPControlPoint::Callback() UPNP_DISCOVERY_SEARCH_TIMEOUT ***" << std::endl - << "********************************************************************************" << std::endl; -#endif - - // Unlock the search timeout mutex - upnpCP->m_WaitForSearchTimeoutMutex.unlock(); - break; - } - case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: // UPnP Device Removed - { - const UpnpDiscovery* dab_event = static_cast(Event); - if(!dab_event) break; - - std::string devType = UpnpDiscovery_get_DeviceType_cstr(dab_event); - - // Check for an InternetGatewayDevice and removes it from the list - std::transform(devType.begin(), devType.end(), devType.begin(), tolower); - if (stdStringIsEqualCI(devType, upnpCP->m_upnpLib.UPNP_DEVICE_IGW)) - upnpCP->RemoveRootDevice( - UpnpDiscovery_get_DeviceID_cstr(dab_event) ); - break; - } - case UPNP_EVENT_RECEIVED: - { - // Event reveived - const UpnpEvent* e_event = static_cast(Event); - - const std::string Sid = UpnpEvent_get_SID_cstr(e_event); - - // Parses the event - upnpCP->OnEventReceived( Sid, - UpnpEvent_get_EventKey(e_event), - UpnpEvent_get_ChangedVariables(e_event) ); - break; - } - case UPNP_EVENT_SUBSCRIBE_COMPLETE: - msg += "error(UPNP_EVENT_SUBSCRIBE_COMPLETE): "; - goto upnpEventRenewalComplete; - case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: - msg += "error(UPNP_EVENT_UNSUBSCRIBE_COMPLETE): "; - goto upnpEventRenewalComplete; - case UPNP_EVENT_RENEWAL_COMPLETE: - { - msg += "error(UPNP_EVENT_RENEWAL_COMPLETE): "; -upnpEventRenewalComplete: - const UpnpEventSubscribe* es_event = - static_cast(Event); - - if (UpnpEventSubscribe_get_ErrCode(es_event) != UPNP_E_SUCCESS) - { - msg += "Error in Event Subscribe Callback"; - upnpCP->m_upnpLib.processUPnPErrorMessage( - msg, UpnpEventSubscribe_get_ErrCode(es_event), - nullptr, nullptr ); - } - - break; - } - case UPNP_EVENT_AUTORENEWAL_FAILED: - msg += "CUPnPControlPoint::Callback() error(UPNP_EVENT_AUTORENEWAL_FAILED): "; - msg2 += "UPNP_EVENT_AUTORENEWAL_FAILED: "; - goto upnpEventSubscriptionExpired; - case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { - msg += "CUPnPControlPoint::Callback() error(UPNP_EVENT_SUBSCRIPTION_EXPIRED): "; - msg2 += "UPNP_EVENT_SUBSCRIPTION_EXPIRED: "; -upnpEventSubscriptionExpired: - const UpnpEventSubscribe* es_event = - static_cast(Event); - - Upnp_SID newSID; - int TimeOut = 1801; - int ret = UpnpSubscribe( - upnpCP->m_UPnPClientHandle, -#ifdef PATCHED_LIBUPNP - UpnpString_get_String(es_event->PublisherUrl), -#else - UpnpEventSubscribe_get_PublisherUrl_cstr(es_event), -#endif - &TimeOut, - newSID); - if (ret != UPNP_E_SUCCESS) - { - msg += "Error Subscribing to EventURL"; - upnpCP->m_upnpLib.processUPnPErrorMessage( - msg, UpnpEventSubscribe_get_ErrCode(es_event), - nullptr, nullptr ); - } - else - { - ServiceMap::iterator it = -#ifdef PATCHED_LIBUPNP - upnpCP->m_ServiceMap.find(UpnpString_get_String(es_event->PublisherUrl)); -#else - upnpCP->m_ServiceMap.find( - UpnpEventSubscribe_get_PublisherUrl_cstr(es_event) ); -#endif - if (it != upnpCP->m_ServiceMap.end()) { - CUPnPService &service = *(it->second); - service.SetTimeout(TimeOut); - service.SetSID(newSID); - std::cerr << "CUPnPControlPoint::Callback() Re-subscribed to EventURL '" << -#ifdef PATCHED_LIBUPNP - UpnpString_get_String(es_event->PublisherUrl) << -#else - UpnpEventSubscribe_get_PublisherUrl_cstr(es_event) << -#endif - "' with SID == '" << - newSID << "'." << std::endl; - // In principle, we should test to see if the - // service is the same. But here we only have one - // service, so... - upnpCP->RefreshPortMappings(); - } - else - { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() Error: did not find service " << - newSID << " in the service map." << std::endl; -#endif - } - } - break; - } - case UPNP_CONTROL_ACTION_COMPLETE: - { - // This is here if we choose to do this asynchronously - const UpnpActionComplete* a_event = - static_cast(Event); - if(UpnpActionComplete_get_ErrCode(a_event) != UPNP_E_SUCCESS) - { - upnpCP->m_upnpLib.processUPnPErrorMessage( - "UpnpSendActionAsync", - UpnpActionComplete_get_ErrCode(a_event), nullptr, - UpnpActionComplete_get_ActionResult(a_event) ); - } - else - { - // Check the response document - upnpCP->m_upnpLib.ProcessActionResponse( - UpnpActionComplete_get_ActionResult(a_event), - "" ); - } - /* No need for any processing here, just print out results. - * Service state table updates are handled by events. - */ - break; - } - case UPNP_CONTROL_GET_VAR_COMPLETE: - { - msg += "CUPnPControlPoint::Callback() error(UPNP_CONTROL_GET_VAR_COMPLETE): "; - const UpnpStateVarComplete* sv_event = - static_cast(Event); - if (UpnpStateVarComplete_get_ErrCode(sv_event) != UPNP_E_SUCCESS) - { - msg += "m_UpnpGetServiceVarStatusAsync"; - upnpCP->m_upnpLib.processUPnPErrorMessage( - msg, UpnpStateVarComplete_get_ErrCode(sv_event), - nullptr, nullptr ); - } - else - { - //add the variable to the wanservice property map - (upnpCP->m_WanService->propertyMap)[ - std::string( - UpnpStateVarComplete_get_StateVarName_cstr(sv_event) ) ] - = std::string(UpnpStateVarComplete_get_CurrentVal_cstr(sv_event)); - } - break; - } - // ignore these cases, since this is not a device - case UPNP_CONTROL_GET_VAR_REQUEST: - //fprintf(stderr, "Callback: UPNP_CONTROL_GET_VAR_REQUEST\n"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() error(UPNP_CONTROL_GET_VAR_REQUEST): "; -#endif - goto eventSubscriptionRequest; - case UPNP_CONTROL_ACTION_REQUEST: - //fprintf(stderr, "Callback: UPNP_CONTROL_ACTION_REQUEST\n"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() error(UPNP_CONTROL_ACTION_REQUEST): "; -#endif - goto eventSubscriptionRequest; - case UPNP_EVENT_SUBSCRIPTION_REQUEST: - //fprintf(stderr, "Callback: UPNP_EVENT_SUBSCRIPTION_REQUEST\n"); -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() error(UPNP_EVENT_SUBSCRIPTION_REQUEST): "; -#endif -eventSubscriptionRequest: -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Callback() This is not a UPnP Device, this is a UPnP Control Point, event ignored." << std::endl; -#endif - break; - default: - // Humm, this is not good, we forgot to handle something... -#ifdef UPNP_DEBUG - fprintf(stderr, - "Callback: default... Unknown event:'%d', not good.\n", - EventType); - std::cerr << "CUPnPControlPoint::Callback() error(UPnP::Callback): Event not handled:'" << - EventType << "'." << std::endl; -#endif - // Better not throw in the callback. Who would catch it? - //throw CUPnPException(msg); - break; - } - - return 0; -} - - -void CUPnPControlPoint::OnEventReceived( - const std::string &Sid, - int EventKey, - const IXML_Document* ChangedVariablesDoc) -{ - /* remove unused parameter warnings */ - (void) EventKey; - -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::OnEventReceived() UPNP_EVENT_RECEIVED:" << - "\n SID: " << Sid << - "\n Key: " << EventKey << std::endl; - std::cerr << "CUPnPControlPoint::OnEventReceived() m_WanService->GetServiceId() : " << m_WanService->GetSID() << std::endl; -#endif - - if (m_WanService->GetSID() == Sid) { - //let's store the properties if it is an event of the wan device -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::OnEventReceived() \n Property list:"; -#endif - - IXML_Element *root = - m_upnpLib.Element_GetRootElement(ChangedVariablesDoc); - IXML_Element *child = - m_upnpLib.Element_GetFirstChild(root); - if (child) { - while (child) { - IXML_Element *child2 = - m_upnpLib.Element_GetFirstChild(child); - const DOMString childTag = - m_upnpLib.Element_GetTag(child2); - std::string childValue = - m_upnpLib.Element_GetTextValue(child2); -#ifdef UPNP_DEBUG - std::cerr << "\n " << - childTag << "='" << - childValue << "'"; -#endif - const std::string cTag(childTag); - const std::string cValue(childValue); - (m_WanService->propertyMap)[cTag] = cValue; - child = m_upnpLib.Element_GetNextSibling(child); - } - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::OnEventReceived() \n Empty property list."; -#endif - } -#ifdef UPNP_DEBUG - std::cerr << std::endl; -#endif - // Freeing that doc segfaults. Probably should not be freed. - //ixmlDocument_free(ChangedVariablesDoc); - } -} - - -void CUPnPControlPoint::AddRootDevice( - IXML_Element *rootDevice, const std::string &urlBase, - const char *location, int expires) -{ - // Lock the Root Device List - RsMutex toto(m_RootDeviceListMutex); - - // Root node's URLBase - std::string OriginalURLBase(urlBase); - std::string FixedURLBase(OriginalURLBase.empty() ? - location : - OriginalURLBase); - - // Get the UDN (Unique Device Name) - std::string UDN( - m_upnpLib.Element_GetChildValueByTag(rootDevice, "UDN")); - RootDeviceMap::iterator it = m_RootDeviceMap.find(UDN); - bool alreadyAdded = it != m_RootDeviceMap.end(); - if (alreadyAdded) { - // Just set the expires field - it->second->SetExpires(expires); - } else { - // Add a new root device to the root device list - CUPnPRootDevice *upnpRootDevice = new CUPnPRootDevice( - *this, m_upnpLib, rootDevice, - OriginalURLBase, FixedURLBase, - location, expires); - m_RootDeviceMap[upnpRootDevice->GetUDN()] = upnpRootDevice; - } -} - - -void CUPnPControlPoint::RemoveRootDevice(const char *udn) -{ - // Lock the Root Device List - RsMutex toto(m_RootDeviceListMutex); - - // Remove - std::string UDN(udn); - RootDeviceMap::iterator it = m_RootDeviceMap.find(UDN); - if (it != m_RootDeviceMap.end()) { - delete it->second; - m_RootDeviceMap.erase(UDN); - } -} - - -void CUPnPControlPoint::Subscribe(CUPnPService &service) -{ - - IXML_Document *scpdDoc = NULL; - int errcode = UpnpDownloadXmlDoc( - service.GetAbsSCPDURL().c_str(), &scpdDoc); - if (errcode == UPNP_E_SUCCESS) { - // Get the root node of this service (the SCPD Document) - IXML_Element *scpdRoot = - m_upnpLib.Element_GetRootElement(scpdDoc); - CUPnPSCPD *scpd = new CUPnPSCPD(*this, m_upnpLib, - scpdRoot, service.GetAbsSCPDURL()); - service.SetSCPD(scpd); - m_ServiceMap[service.GetAbsEventSubURL()] = &service; -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Subscribe() Successfully retrieved SCPD Document for service " << - service.GetServiceType() << ", absEventSubURL: " << - service.GetAbsEventSubURL() << "." << std::endl; -#endif - - // Now try to subscribe to this service. If the subscription - // is not successfull, we will not be notified about events, - // but it may be possible to use the service anyway. - errcode = UpnpSubscribe(m_UPnPClientHandle, - service.GetAbsEventSubURL().c_str(), - service.GetTimeoutAddr(), - service.GetSID()); - if (errcode == UPNP_E_SUCCESS) { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Subscribe() Successfully subscribed to service " << - service.GetServiceType() << ", absEventSubURL: " << - service.GetAbsEventSubURL() << "." << std::endl; -#endif - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Subscribe() Error subscribing to service " << - service.GetServiceType() << ", absEventSubURL: " << - service.GetAbsEventSubURL() << ", error: " << - m_upnpLib.GetUPnPErrorMessage(errcode) << "."; -#endif - goto error; - } - } else { -#ifdef UPNP_DEBUG - std::cerr << "CUPnPControlPoint::Subscribe() Error getting SCPD Document from " << - service.GetAbsSCPDURL() << "." << std::endl; -#endif - } - - return; - -error: - ; -#ifdef UPNP_DEBUG - std::cerr << std::endl; -#endif -} - - -void CUPnPControlPoint::Unsubscribe(CUPnPService &service) -{ - ServiceMap::iterator it = m_ServiceMap.find(service.GetAbsEventSubURL()); - if (it != m_ServiceMap.end()) { - m_ServiceMap.erase(it); - UpnpUnSubscribe(m_UPnPClientHandle, service.GetSID()); - } -} - - -// File_checked_for_headers diff --git a/libretroshare/src/rs_upnp/UPnPBase.h b/libretroshare/src/rs_upnp/UPnPBase.h deleted file mode 100644 index e1c41fb83..000000000 --- a/libretroshare/src/rs_upnp/UPnPBase.h +++ /dev/null @@ -1,620 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: UPnPBase.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2004-2009 Marcelo Roberto Jimenez ( phoenix@amule.org ) * - * Copyright (c) 2006-2009 aMule Team ( admin@amule.org / http://www.amule.org)* - * Copyright (c) 2009-2010 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "util/rsthreads.h" - -#include -#include - -#ifdef UPNP_C - std::string stdEmptyString; -#else // UPNP_C - extern std::string stdEmptyString; -#endif // UPNP_C - -//#define UPNP_DEBUG 1 - -/** - * Case insensitive std::string comparison - */ -bool stdStringIsEqualCI( - const std::string &s1, - const std::string &s2); - - -class CUPnPPortMapping -{ -private: - std::string m_ex_port; - std::string m_in_port; - std::string m_protocol; - std::string m_enabled; - std::string m_description; - std::string m_key; - -public: - CUPnPPortMapping( - int ex_port = 0, - int in_port = 0, - const std::string &protocol = stdEmptyString, - bool enabled = false, - const std::string &description = stdEmptyString); - ~CUPnPPortMapping() {} - - const std::string &getExPort() const - { return m_ex_port; } - const std::string &getInPort() const - { return m_in_port; } - const std::string &getProtocol() const - { return m_protocol; } - const std::string &getEnabled() const - { return m_enabled; } - const std::string &getDescription() const - { return m_description; } - const std::string &getKey() const - { return m_key; } -}; - - -class CUPnPControlPoint; - - -class CUPnPLib -{ -public: - static const std::string &UPNP_ROOT_DEVICE; - static const std::string &UPNP_DEVICE_IGW; - static const std::string &UPNP_DEVICE_WAN; - static const std::string &UPNP_DEVICE_WAN_CONNECTION; - static const std::string &UPNP_DEVICE_LAN; - static const std::string &UPNP_SERVICE_LAYER3_FORWARDING; - static const std::string &UPNP_SERVICE_WAN_COMMON_INTERFACE_CONFIG; - static const std::string &UPNP_SERVICE_WAN_IP_CONNECTION; - static const std::string &UPNP_SERVICE_WAN_PPP_CONNECTION; - CUPnPControlPoint &m_ctrlPoint; - -public: - explicit CUPnPLib(CUPnPControlPoint &ctrlPoint); - ~CUPnPLib() {} - - // Convenience function so we don't have to write explicit calls - // to char2unicode every time - std::string GetUPnPErrorMessage(int code) const; - - // Convenience function to avoid repetitive processing of error - // messages - std::string processUPnPErrorMessage(const std::string &messsage, - int code, - const DOMString errorString, - const IXML_Document* doc) const; - - // Processing response to actions - void ProcessActionResponse( - const IXML_Document* RespDoc, - const std::string& actionName ) const; - - // IXML_Element - IXML_Element* Element_GetRootElement(const IXML_Document* doc) const; - IXML_Element *Element_GetFirstChild( - IXML_Element *parent) const; - IXML_Element *Element_GetNextSibling( - IXML_Element *child) const; - const DOMString Element_GetTag( - IXML_Element *element) const; - const std::string Element_GetTextValue( - IXML_Element *element) const; - const std::string Element_GetChildValueByTag( - IXML_Element *element, - const DOMString tag) const; - IXML_Element *Element_GetFirstChildByTag( - IXML_Element *element, - const DOMString tag) const; - IXML_Element *Element_GetNextSiblingByTag( - IXML_Element *element, - const DOMString tag) const; - const std::string Element_GetAttributeByTag( - IXML_Element *element, - const DOMString tag) const; -}; - - -class CUPnPControlPoint; - -/* - * Even though we can retrieve the upnpLib handler from the upnpControlPoint, - * we must pass it separetly at this point, because the class CUPnPControlPoint - * must be declared after. - * - * CUPnPLib can only be removed from the constructor once we agree to link to - * UPnPLib explicitly, making this dlopen() stuff unnecessary. - */ -template -class CXML_List : public std::map -{ -public: - CXML_List( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *parent, - const std::string &url); - ~CXML_List(); -}; - - -template -CXML_List::CXML_List( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *parent, - const std::string &url) -{ - IXML_Element *elementList = - upnpLib.Element_GetFirstChildByTag(parent, XML_LIST_NAME); - unsigned int i = 0; - for ( IXML_Element *element = upnpLib.Element_GetFirstChildByTag(elementList, XML_ELEMENT_NAME); - element; - element = upnpLib.Element_GetNextSiblingByTag(element, XML_ELEMENT_NAME)) { - // Add a new element to the element list - T *upnpElement = new T(upnpControlPoint, upnpLib, element, url); - (*this)[upnpElement->GetKey()] = upnpElement; - ++i; - } - std::cerr << "\n " << XML_LIST_NAME << ": " << - i << " " << XML_ELEMENT_NAME << "s."; -} - - -template -CXML_List::~CXML_List() -{ - typename CXML_List::iterator it; - for(it = this->begin(); it != this->end(); ++it) { - delete (*it).second; - } -} - -extern const char s_argument[]; -extern const char s_argumentList[]; -extern const char s_action[]; -extern const char s_actionList[]; -extern const char s_allowedValue[]; -extern const char s_allowedValueList[]; -extern const char s_stateVariable[]; -extern const char s_serviceStateTable[]; -extern const char s_service[]; -extern const char s_serviceList[]; -extern const char s_device[]; -extern const char s_deviceList[]; - -#ifdef UPNP_C - const char s_argument[] = "argument"; - const char s_argumentList[] = "argumentList"; - const char s_action[] = "action"; - const char s_actionList[] = "actionList"; - const char s_allowedValue[] = "allowedValue"; - const char s_allowedValueList[] = "allowedValueList"; - const char s_stateVariable[] = "stateVariable"; - const char s_serviceStateTable[] = "serviceStateTable"; - const char s_service[] = "service"; - const char s_serviceList[] = "serviceList"; - const char s_device[] = "device"; - const char s_deviceList[] = "deviceList"; -#endif // UPNP_C - - -class CUPnPArgument; -typedef CXML_List ArgumentList; -class CUPnPAction; -typedef CXML_List ActionList; -class CUPnPStateVariable; -typedef CXML_List ServiceStateTable; -class CUPnPAllowedValue; -typedef CXML_List AllowedValueList; -class CUPnPService; -typedef CXML_List ServiceList; -class CUPnPDevice; -typedef CXML_List DeviceList; - - -class CUPnPError -{ -private: - IXML_Element *m_root; - const std::string m_ErrorCode; - const std::string m_ErrorDescription; -public: - CUPnPError( - const CUPnPLib &upnpLib, - const IXML_Document *errorDoc); - ~CUPnPError() {} - const std::string &getErrorCode() const - { return m_ErrorCode; } - const std::string &getErrorDescription() const - { return m_ErrorDescription; } -}; - - -class CUPnPArgument -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - const std::string m_name; - const std::string m_direction; - bool m_retval; - const std::string m_relatedStateVariable; - -public: - CUPnPArgument( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *argument, - const std::string &SCPDURL); - ~CUPnPArgument() {} - const std::string &GetName() const - { return m_name; } - const std::string &GetDirection() const - { return m_direction; } - bool GetRetVal() const - { return m_retval; } - const std::string &GetRelatedStateVariable() const - { return m_relatedStateVariable; } - const std::string &GetKey() const - { return m_name; } -}; - - - -class CUPnPAction -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - ArgumentList m_ArgumentList; - const std::string m_name; - -public: - CUPnPAction( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *action, - const std::string &SCPDURL); - ~CUPnPAction() {} - const std::string &GetName() const - { return m_name; } - const std::string &GetKey() const - { return m_name; } - const ArgumentList &GetArgumentList() const - { return m_ArgumentList; } -}; - - -class CUPnPAllowedValue -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - const std::string m_allowedValue; - -public: - CUPnPAllowedValue( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *allowedValue, - const std::string &SCPDURL); - ~CUPnPAllowedValue() {} - const std::string &GetAllowedValue() const - { return m_allowedValue; } - const std::string &GetKey() const - { return m_allowedValue; } -}; - - -class CUPnPStateVariable -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - AllowedValueList m_AllowedValueList; - const std::string m_name; - const std::string m_dataType; - const std::string m_defaultValue; - const std::string m_sendEvents; - -public: - CUPnPStateVariable( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *stateVariable, - const std::string &URLBase); - ~CUPnPStateVariable() {} - const std::string &GetNname() const - { return m_name; } - const std::string &GetDataType() const - { return m_dataType; } - const std::string &GetDefaultValue() const - { return m_defaultValue; } - const std::string &GetKey() const - { return m_name; } - const AllowedValueList &GetAllowedValueList() const - { return m_AllowedValueList; } -}; - - -class CUPnPSCPD -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - ActionList m_ActionList; - ServiceStateTable m_ServiceStateTable; - const std::string m_SCPDURL; - -public: - CUPnPSCPD( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *scpd, - const std::string &SCPDURL); - ~CUPnPSCPD() {} - const ActionList &GetActionList() const - { return m_ActionList; } - const ServiceStateTable &GetServiceStateTable() const - { return m_ServiceStateTable; } -}; - - -class CUPnPArgumentValue -{ -private: - std::string m_argument; - std::string m_value; - -public: - CUPnPArgumentValue(); - CUPnPArgumentValue(const std::string &argument, const std::string &value); - ~CUPnPArgumentValue() {} - - const std::string &GetArgument() const { return m_argument; } - const std::string &GetValue() const { return m_value; } - const std::string &SetArgument(const std::string& argument) { return m_argument = argument; } - const std::string &SetValue(const std::string &value) { return m_value = value; } -}; - - -class CUPnPService -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - CUPnPLib &m_upnpLib; - const std::string m_serviceType; - const std::string m_serviceId; - const std::string m_SCPDURL; - const std::string m_controlURL; - const std::string m_eventSubURL; - std::string m_absSCPDURL; - std::string m_absControlURL; - std::string m_absEventSubURL; - int m_timeout; - Upnp_SID m_SID; - std::auto_ptr m_SCPD; - -public: - std::map propertyMap; - CUPnPService( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *service, - const std::string &URLBase); - ~CUPnPService(); - - const std::string &GetServiceType() const - { return m_serviceType; } - const std::string &GetServiceId() const - { return m_serviceId; } - const std::string &GetSCPDURL() const - { return m_SCPDURL; } - const std::string &GetAbsSCPDURL() const - { return m_absSCPDURL; } - const std::string &GetControlURL() const - { return m_controlURL; } - const std::string &GetEventSubURL() const - { return m_eventSubURL; } - const std::string &GetAbsControlURL() const - { return m_absControlURL; } - const std::string &GetAbsEventSubURL() const - { return m_absEventSubURL; } - int GetTimeout() const - { return m_timeout; } - void SetTimeout(int t) - { m_timeout = t; } - int *GetTimeoutAddr() - { return &m_timeout; } - char *GetSID() - { return m_SID; } - void SetSID(const char *s) - { memcpy(m_SID, s, sizeof(Upnp_SID)); } - const std::string &GetKey() const - { return m_serviceId; } - bool IsSubscribed() const - { return m_SCPD.get() != NULL; } - void SetSCPD(CUPnPSCPD *SCPD) - { m_SCPD.reset(SCPD); } - - bool Execute( - const std::string &ActionName, - const std::vector &ArgValue) const; - const std::string GetStateVariable( - const std::string &stateVariableName); - -}; - - -class CUPnPDevice -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - - // Please, lock these lists before use - DeviceList m_DeviceList; - ServiceList m_ServiceList; - - const std::string m_deviceType; - const std::string m_friendlyName; - const std::string m_manufacturer; - const std::string m_manufacturerURL; - const std::string m_modelDescription; - const std::string m_modelName; - const std::string m_modelNumber; - const std::string m_modelURL; - const std::string m_serialNumber; - const std::string m_UDN; - const std::string m_UPC; - std::string m_presentationURL; - -public: - CUPnPDevice( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *device, - const std::string &URLBase); - ~CUPnPDevice() {} - - const std::string &GetUDN() const - { return m_UDN; } - const std::string &GetDeviceType() const - { return m_deviceType; } - const std::string &GetFriendlyName() const - { return m_friendlyName; } - const std::string &GetPresentationURL() const - { return m_presentationURL; } - const std::string &GetKey() const - { return m_UDN; } -}; - - -class CUPnPRootDevice : public CUPnPDevice -{ -private: - const CUPnPControlPoint &m_UPnPControlPoint; - const std::string m_URLBase; - const std::string m_location; - int m_expires; - -public: - CUPnPRootDevice( - const CUPnPControlPoint &upnpControlPoint, - CUPnPLib &upnpLib, - IXML_Element *rootDevice, - const std::string &OriginalURLBase, - const std::string &FixedURLBase, - const char *location, - int expires); - ~CUPnPRootDevice() {} - - const std::string &GetURLBase() const - { return m_URLBase; } - const std::string &GetLocation() const - { return m_location; } - int GetExpires() const - { return m_expires; } - void SetExpires(int expires) - { m_expires = expires; } -}; - - -typedef std::map RootDeviceMap; -typedef std::map ServiceMap; -typedef std::map PortMappingMap; - - -class CUPnPControlPoint -{ -private: - // upnp stuff - CUPnPLib m_upnpLib; - UpnpClient_Handle m_UPnPClientHandle; - RootDeviceMap m_RootDeviceMap; - ServiceMap m_ServiceMap; - PortMappingMap m_ActivePortMappingsMap; - RsMutex m_RootDeviceListMutex; - bool m_IGWDeviceDetected; - RsMutex m_WaitForSearchTimeoutMutex; - -public: - CUPnPService *m_WanService; - std::string m_getStateVariableLastResult; - static CUPnPControlPoint *s_CtrlPoint; - explicit CUPnPControlPoint(unsigned short udpPort); - ~CUPnPControlPoint(); - char* getInternalIpAddress(); - std::string getExternalAddress(); - void Subscribe(CUPnPService &service); - void Unsubscribe(CUPnPService &service); - bool AddPortMappings( - std::vector &upnpPortMapping); - bool DeletePortMappings( - std::vector &upnpPortMapping); - - UpnpClient_Handle GetUPnPClientHandle() const - { return m_UPnPClientHandle; } - - bool GetIGWDeviceDetected() const - { return m_IGWDeviceDetected; } - void SetIGWDeviceDetected(bool b) - { m_IGWDeviceDetected = b; } - bool WanServiceDetected() const - { return !m_ServiceMap.empty(); } - void SetWanService(CUPnPService *service) - { m_WanService = service; } - - // Callback function - static int Callback( - Upnp_EventType EventType, const void* Event, void* Cookie ); - void OnEventReceived(const std::string &Sid, - int EventKey, - const IXML_Document* ChangedVariables); - -private: - void AddRootDevice( - IXML_Element *rootDevice, - const std::string &urlBase, - const char *location, - int expires); - void RemoveRootDevice( - const char *udn); - void RefreshPortMappings(); - bool PrivateAddPortMapping( - CUPnPPortMapping &upnpPortMapping); - bool PrivateDeletePortMapping( - CUPnPPortMapping &upnpPortMapping); - bool PrivateGetExternalIpAdress(); -}; - -// File_checked_for_headers diff --git a/libretroshare/src/rs_upnp/upnp18_retrocompat.h b/libretroshare/src/rs_upnp/upnp18_retrocompat.h deleted file mode 100644 index 26fb0a524..000000000 --- a/libretroshare/src/rs_upnp/upnp18_retrocompat.h +++ /dev/null @@ -1,82 +0,0 @@ -/******************************************************************************* - * libupnp-1.8.x -> libupnp-1.6.x retrocompatibility header * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - - -#if UPNP_VERSION < 10800 - -using UpnpDiscovery = Upnp_Discovery; -using UpnpEvent = Upnp_Event; -using UpnpEventSubscribe = Upnp_Event_Subscribe; -using UpnpActionComplete = Upnp_Action_Complete; -using UpnpStateVarComplete = Upnp_State_Var_Complete; - -static inline const char* UpnpStateVarComplete_get_CurrentVal_cstr( - const UpnpStateVarComplete* esvc) noexcept { return esvc->CurrentVal; } - -#endif // UPNP_VERSION < 10800 - -#if UPNP_VERSION < 10624 - -static inline int UpnpDiscovery_get_Expires(const Upnp_Discovery* disc) noexcept -{ return disc->Expires; } - -static inline const char* UpnpDiscovery_get_DeviceID_cstr( - const Upnp_Discovery* disc ) noexcept -{ return disc->DeviceId; } - -static inline const char* UpnpDiscovery_get_DeviceType_cstr( - const Upnp_Discovery* disc ) noexcept -{ return disc->DeviceType; } - -static inline const char* UpnpDiscovery_get_Location_cstr( - const Upnp_Discovery* disc ) noexcept -{ return disc->Location; } - -static inline const char* UpnpEvent_get_SID_cstr(const UpnpEvent* ev) noexcept -{ return ev->Sid; } - -static inline int UpnpEvent_get_EventKey(const UpnpEvent* ev) noexcept -{ return ev->EventKey; } - -static inline const IXML_Document* UpnpEvent_get_ChangedVariables( - const UpnpEvent* ev) noexcept { return ev->ChangedVariables; } - -static inline int UpnpEventSubscribe_get_ErrCode(const UpnpEventSubscribe* evs) -noexcept { return evs->ErrCode; } - -static inline const char* UpnpEventSubscribe_get_PublisherUrl_cstr( - const UpnpEventSubscribe* evs ) noexcept { return evs->PublisherUrl; } - -static inline int UpnpActionComplete_get_ErrCode(const UpnpActionComplete* evc) -noexcept { return evc->ErrCode; } - -static inline const IXML_Document* UpnpActionComplete_get_ActionResult( - const UpnpActionComplete* evc ) noexcept { return evc->ActionResult; } - -static inline int UpnpStateVarComplete_get_ErrCode( - const UpnpStateVarComplete* esvc) noexcept { return esvc->ErrCode; } - -static inline const char* UpnpStateVarComplete_get_StateVarName_cstr( - const UpnpStateVarComplete* esvc) noexcept { return esvc->StateVarName; } - -#endif // UPNP_VERSION < 10624 diff --git a/libretroshare/src/rs_upnp/upnphandler_libupnp.cc b/libretroshare/src/rs_upnp/upnphandler_libupnp.cc deleted file mode 100644 index 17e096a08..000000000 --- a/libretroshare/src/rs_upnp/upnphandler_libupnp.cc +++ /dev/null @@ -1,466 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnphandler_libupnp.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern C */ -#endif -/* This stuff is actually C */ - -#include "rs_upnp/upnphandler_libupnp.h" - -#include "util/rsnet.h" - -bool upnphandler::initUPnPState() -{ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState" << std::endl; - #endif - cUPnPControlPoint = new CUPnPControlPoint(2000); - - bool IGWDetected = cUPnPControlPoint->GetIGWDeviceDetected(); - - if (IGWDetected) { - /* MODIFY STATE */ - dataMtx.lock(); /* LOCK MUTEX */ - upnpState = RS_UPNP_S_READY; - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState cUPnPControlPoint internal ip adress : "; - std::cerr << cUPnPControlPoint->getInternalIpAddress() << std::endl; - #endif - - //const char ipaddr = cUPnPControlPoint->getInternalIpAddress().c_str(); - inet_aton(cUPnPControlPoint->getInternalIpAddress(), &(upnp_iaddr.sin_addr)); - upnp_iaddr.sin_port = htons(iport); - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState READY" << std::endl; - #endif - dataMtx.unlock(); /* UNLOCK MUTEX */ - - } else { - upnpState = RS_UPNP_S_UNAVAILABLE; - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::initUPnPState UNAVAILABLE" << std::endl; - #endif - } - - return 0; -} - -class upnpThreadData -{ - public: - upnphandler *handler; - bool start; - bool stop; -}; - - /* Thread routines */ -extern "C" void* doSetupUPnP(void* p) -{ - #ifdef UPNP_DEBUG - std::cerr << "doSetupUPnP Creating upnp thread." << std::endl; - #endif - upnpThreadData *data = (upnpThreadData *) p; - if ((!data) || (!data->handler)) - { - pthread_exit(NULL); - } - - /* publish it! */ - if (data -> stop) - { - data->handler->shutdown_upnp(); - } - - if (data -> start) - { - data->handler->initUPnPState(); - data->handler->start_upnp(); - } - - delete data; - pthread_exit(NULL); - - return NULL; -} - -bool upnphandler::background_setup_upnp(bool start, bool stop) -{ - pthread_t tid; - - /* launch thread */ - #ifdef UPNP_DEBUG - std::cerr << "background_setup_upnp Creating upnp thread." << std::endl; - #endif - upnpThreadData *data = new upnpThreadData(); - data->handler = this; - data->start = start; - data->stop = stop; - - 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() -{ - if (!(upnpState >= RS_UPNP_S_READY)) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Not Ready" << std::endl; - #endif - return false; - } - - struct sockaddr_in localAddr; - { - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - /* if we're to load -> load */ - /* select external ports */ - eport_curr = eport; - if (!eport_curr) - { - /* use local port if eport is zero */ - eport_curr = iport; - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Using LocalPort for extPort." << std::endl; - #endif - } - - if (!eport_curr) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::start_upnp() Invalid eport ... " << std::endl; - #endif - return false; - } - - /* our port */ - char in_addr[256]; - char in_port1[256]; - - upnp_iaddr.sin_port = htons(iport); - localAddr = upnp_iaddr; - uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr); - snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port)); - snprintf(in_addr, 256, "%d.%d.%d.%d", - ((linaddr >> 24) & 0xff), - ((linaddr >> 16) & 0xff), - ((linaddr >> 8) & 0xff), - ((linaddr >> 0) & 0xff)); - - #ifdef UPNP_DEBUG - std::cerr << "Attempting Redirection: InAddr: " << in_addr; - std::cerr << " InPort: " << in_port1; - std::cerr << " ePort: " << eport_curr; - std::cerr << " eProt: " << "TCP and UDP"; - std::cerr << std::endl; - #endif - } - - //first of all, build the mappings - std::vector upnpPortMapping1; - CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "TCP", true, "tcp retroshare redirection"); - upnpPortMapping1.push_back(cUPnPPortMapping1); - std::vector upnpPortMapping2; - CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, ntohs(localAddr.sin_port), "UDP", true, "udp retroshare redirection"); - upnpPortMapping2.push_back(cUPnPPortMapping2); - - //attempt to remove formal port redirection rules - cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); - - //add new rules - bool res = cUPnPControlPoint->AddPortMappings(upnpPortMapping1); - bool res2 = cUPnPControlPoint->AddPortMappings(upnpPortMapping2); - - struct sockaddr_storage extAddr; - bool extAddrResult = getExternalAddress(extAddr); - - { - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - if (extAddrResult && (res || res2)) { - upnpState = RS_UPNP_S_ACTIVE; - } else { - upnpState = RS_UPNP_S_TCP_AND_FAILED; - } - - toStart = false; - } - - return (upnpState == RS_UPNP_S_ACTIVE); - -} - -bool upnphandler::shutdown_upnp() -{ - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - /* always attempt this (unless no port number) */ - if (eport_curr > 0 && eport > 0 && (upnpState >= RS_UPNP_S_ACTIVE)) - { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; - std::cerr << " Prot: TCP"; - std::cerr << std::endl; - #endif - - std::vector upnpPortMapping1; - CUPnPPortMapping cUPnPPortMapping1 = CUPnPPortMapping(eport_curr, 0, "TCP", true, "tcp redirection"); - upnpPortMapping1.push_back(cUPnPPortMapping1); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping1); - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : Attempting To Remove Redirection: port: " << eport_curr; - std::cerr << " Prot: UDP"; - std::cerr << std::endl; - #endif - - std::vector upnpPortMapping2; - CUPnPPortMapping cUPnPPortMapping2 = CUPnPPortMapping(eport_curr, 0, "UDP", true, "udp redirection"); - upnpPortMapping2.push_back(cUPnPPortMapping2); - cUPnPControlPoint->DeletePortMappings(upnpPortMapping2); - - //destroy the upnp object - cUPnPControlPoint->~CUPnPControlPoint(); - cUPnPControlPoint=NULL ; - } else { - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown_upnp() : avoid upnp connection for shutdonws because probably a net flag went down." << std::endl; - #endif - } - - //stopping os ok, set starting to true for next net reset - toStop = false; - toStart = true; - upnpState = RS_UPNP_S_UNINITIALISED; - - return true; - -} - -/************************ External Interface ***************************** - * - * - * - */ - -upnphandler::upnphandler() - : - upnpState(RS_UPNP_S_UNINITIALISED), dataMtx("upupState"), - cUPnPControlPoint(NULL), - toEnable(false), toStart(false), toStop(false), - iport(0),eport(0), eport_curr(0) -{ -} - -upnphandler::~upnphandler() -{ - return; -} - - /* RsIface */ -void upnphandler::enable(bool active) -{ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::enable called with argument active : " << active << std::endl; - std::cerr << "toEnable : " << toEnable << std::endl; - std::cerr << "toStart : " << toStart << std::endl; - #endif - - dataMtx.lock(); /*** LOCK MUTEX ***/ - if (active != toEnable) - { - if (active) - { - toStart = true; - } - else - { - toStop = true; - } - } - toEnable = active; - - bool start = toStart; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - if (start) - { - /* make background thread to startup UPnP */ - background_setup_upnp(true, false); - } -} - - -void upnphandler::shutdown() -{ - /* blocking call to shutdown upnp */ - - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::shutdown() called." << std::endl; - #endif - shutdown_upnp(); -} - - -void upnphandler::restart() -{ - /* non-blocking call to shutdown upnp, and startup again. */ - #ifdef UPNP_DEBUG - std::cerr << "upnphandler::restart() called." << std::endl; - #endif - background_setup_upnp(true, true); -} - - - -bool upnphandler::getEnabled() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - bool on = toEnable; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - -bool upnphandler::getActive() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - #ifdef UPNP_DEBUG - std::cerr <<"upnphandler::getActive() result : " << (upnpState == RS_UPNP_S_ACTIVE) << std::endl; - #endif - - bool on = (upnpState == RS_UPNP_S_ACTIVE); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - - /* the address that the listening port is on */ -void upnphandler::setInternalPort(unsigned short iport_in) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - if (iport != iport_in) - { - iport = iport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - -void upnphandler::setExternalPort(unsigned short eport_in) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - /* flag both shutdown/start -> for restart */ - if (eport != eport_in) - { - eport = eport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - - /* as determined by uPnP */ -bool upnphandler::getInternalAddress(struct sockaddr_storage &addr) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - bool valid = (upnpState >= RS_UPNP_S_ACTIVE); - - // copy to universal addr. - sockaddr_storage_clear(addr); - sockaddr_storage_setipv4(addr, &upnp_iaddr); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return valid; -} - -bool upnphandler::getExternalAddress(struct sockaddr_storage &addr) -{ - std::string externalAdress = cUPnPControlPoint->getExternalAddress(); - - if(!externalAdress.empty() && externalAdress != "") - { - const char* externalIPAddress = externalAdress.c_str(); - - #ifdef UPNP_DEBUG - std::cerr << " upnphandler::getExternalAddress() : " << externalIPAddress; - std::cerr << ":" << eport_curr; - std::cerr << std::endl; - #endif - - dataMtx.lock(); /*** LOCK MUTEX ***/ - sockaddr_clear(&upnp_eaddr); - inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr)); - upnp_eaddr.sin_family = AF_INET; - upnp_eaddr.sin_port = htons(eport_curr); - - // copy to universal addr. - sockaddr_storage_clear(addr); - sockaddr_storage_setipv4(addr, &upnp_eaddr); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return true; - } - else - { - return false; - } -} - - - diff --git a/libretroshare/src/rs_upnp/upnphandler_libupnp.h b/libretroshare/src/rs_upnp/upnphandler_libupnp.h deleted file mode 100644 index bc04d6d36..000000000 --- a/libretroshare/src/rs_upnp/upnphandler_libupnp.h +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnphandler_libupnp.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -/* platform independent networking... */ -#include "pqi/pqinetwork.h" -#include "pqi/pqiassist.h" - -#include "util/rsthreads.h" - -#include -#include "rs_upnp/UPnPBase.h" - -#define RS_UPNP_S_UNINITIALISED 0 -#define RS_UPNP_S_UNAVAILABLE 1 -#define RS_UPNP_S_READY 2 -#define RS_UPNP_S_TCP_AND_FAILED 3 -//#define RS_UPNP_S_UDP_FAILED 4 -#define RS_UPNP_S_ACTIVE 5 - -class upnphandler: public pqiNetAssistFirewall -{ - public: - - upnphandler(); - virtual ~upnphandler(); - - /* External Interface (pqiNetAssistFirewall) */ - virtual void enable(bool active); - virtual void shutdown(); - virtual void restart(); - - virtual bool getEnabled(); - virtual bool getActive(); - - virtual void setInternalPort(unsigned short iport_in); - virtual void setExternalPort(unsigned short eport_in); - virtual bool getInternalAddress(struct sockaddr_storage &addr); - virtual bool getExternalAddress(struct sockaddr_storage &addr); - - /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ - virtual bool requestPortForward(const PortForwardParams & /* params */) { return false; } - virtual bool statusPortForward(const uint32_t /* fwdId */, PortForwardParams & /*params*/) { return false; } - - /* Public functions - for background thread operation, - * but effectively private from rest of RS, as in derived class - */ - unsigned int upnpState; - - bool start_upnp(); - bool shutdown_upnp(); - - bool initUPnPState(); - - /* Mutex for data below */ - RsMutex dataMtx; - - private: - - CUPnPControlPoint *cUPnPControlPoint; - - bool background_setup_upnp(bool, bool); - - - bool toEnable; /* overall on/off switch */ - bool toStart; /* if set start forwarding */ - bool toStop; /* if set stop forwarding */ - - unsigned short iport; - unsigned short eport; /* config */ - unsigned short eport_curr; /* current forwarded */ - - /* info from upnp */ - struct sockaddr_in upnp_iaddr; - struct sockaddr_in upnp_eaddr; -}; - -/* info from upnp */ -int CtrlPointCallbackEventHandler(Upnp_EventType ,void* , void*); diff --git a/libretroshare/src/rs_upnp/upnphandler_miniupnp.cc b/libretroshare/src/rs_upnp/upnphandler_miniupnp.cc deleted file mode 100644 index ca21804af..000000000 --- a/libretroshare/src/rs_upnp/upnphandler_miniupnp.cc +++ /dev/null @@ -1,677 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnphandler_miniupnp.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -// Windows / Mac version. -/* This stuff is actually C */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} /* extern C */ -#endif -/* This stuff is actually C */ - -#include "rs_upnp/upnphandler_miniupnp.h" -#include "rs_upnp/upnputil.h" - -class uPnPConfigData -{ - public: - struct UPNPDev * devlist; - struct UPNPUrls urls; - struct IGDdatas data; - char lanaddr[16]; /* my ip address on the LAN */ -}; - -#include - -#include "util/rsnet.h" - -bool upnphandler::initUPnPState() -{ - /* allocate memory */ - uPnPConfigData *upcd = new uPnPConfigData; -#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 -#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) - { - struct UPNPDev * device; - printf("List of UPNP devices found on the network :\n"); - for(device=upcd->devlist;device;device=device->pNext) - { - printf("\n desc: %s\n st: %s\n", - device->descURL, device->st); - } - putchar('\n'); - if(UPNP_GetValidIGD(upcd->devlist, &(upcd->urls), - &(upcd->data), upcd->lanaddr, - sizeof(upcd->lanaddr))) - { - printf("Found valid IGD : %s\n", - upcd->urls.controlURL); - printf("Local LAN ip address : %s\n", - upcd->lanaddr); - - /* MODIFY STATE */ - dataMtx.lock(); /* LOCK MUTEX */ - - /* convert to ipaddress. */ - inet_aton(upcd->lanaddr, &(upnp_iaddr.sin_addr)); - upnp_iaddr.sin_port = htons(iport); - - upnpState = RS_UPNP_S_READY; - if (upnpConfig) - { - delete upnpConfig; - } - upnpConfig = upcd; /* */ - - dataMtx.unlock(); /* UNLOCK MUTEX */ - - - /* done -> READY */ - return 1; - - } - else - { - fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n"); - } - - - freeUPNPDevlist(upcd->devlist); - upcd->devlist = 0; - } - else - { - fprintf(stderr, "No IGD UPnP Device found on the network !\n"); - } - - /* MODIFY STATE */ - dataMtx.lock(); /* LOCK MUTEX */ - - upnpState = RS_UPNP_S_UNAVAILABLE; - delete upcd; - upnpConfig = NULL; - - dataMtx.unlock(); /* UNLOCK MUTEX */ - - /* done, FAILED -> NOT AVAILABLE */ - - return 0; -} - -bool upnphandler::printUPnPState() -{ - std::cerr << "upnphandler::printUPnPState() ... locking"; - std::cerr << std::endl; - - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - std::cerr << "upnphandler::printUPnPState() ... locked"; - std::cerr << std::endl; - - uPnPConfigData *config = upnpConfig; - if ((upnpState >= RS_UPNP_S_READY) && (config)) - { - DisplayInfos(&(config -> urls), &(config->data)); - GetConnectionStatus(&(config -> urls), &(config->data)); - ListRedirections(&(config -> urls), &(config->data)); - } - else - { - std::cerr << "UPNP not Ready" << std::endl; - } - - return 1; -} - - -bool upnphandler::checkUPnPActive() -{ - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - uPnPConfigData *config = upnpConfig; - if ((upnpState > RS_UPNP_S_READY) && (config)) - { - char eprot1[] = "TCP"; - char eprot2[] = "UDP"; - - char in_addr[256]; - char in_port1[256]; - char in_port2[256]; - char eport1[256]; - char eport2[256]; - - struct sockaddr_in localAddr = upnp_iaddr; - uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr); - - snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port)); - snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port)); - - snprintf(in_addr, 256, "%d.%d.%d.%d", - ((linaddr >> 24) & 0xff), - ((linaddr >> 16) & 0xff), - ((linaddr >> 8) & 0xff), - ((linaddr >> 0) & 0xff)); - - snprintf(eport1, 256, "%d", eport_curr); - snprintf(eport2, 256, "%d", eport_curr); - - std::cerr << "upnphandler::checkUPnPState()"; - std::cerr << " Checking Redirection: InAddr: " << in_addr; - std::cerr << " InPort: " << in_port1; - std::cerr << " ePort: " << eport1; - std::cerr << " eProt: " << eprot1; - std::cerr << std::endl; - - - bool tcpOk = TestRedirect(&(config -> urls), &(config->data), - in_addr, in_port1, eport1, eprot1); - bool udpOk = TestRedirect(&(config -> urls), &(config->data), - in_addr, in_port2, eport2, eprot2); - - if ((!tcpOk) || (!udpOk)) - { - std::cerr << "upnphandler::checkUPnPState() ... Redirect Expired, restarting"; - std::cerr << std::endl; - - toStop = true; - toStart = true; - } - } - - return true; -} - -class upnpThreadData -{ - public: - upnphandler *handler; - bool start; - bool stop; -}; - - /* Thread routines */ -extern "C" void* doSetupUPnP(void* p) -{ - upnpThreadData *data = (upnpThreadData *) p; - if ((!data) || (!data->handler)) - { - pthread_exit(NULL); - } - - /* publish it! */ - if (data -> stop) - { - data->handler->shutdown_upnp(); - } - - if (data -> start) - { - data->handler->initUPnPState(); - data->handler->start_upnp(); - } - - data->handler->printUPnPState(); - - delete data; - pthread_exit(NULL); - - return NULL; -} - -bool upnphandler::background_setup_upnp(bool start, bool stop) -{ - pthread_t tid; - - /* launch thread */ - upnpThreadData *data = new upnpThreadData(); - data->handler = this; - data->start = start; - data->stop = stop; - - 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() -{ - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - uPnPConfigData *config = upnpConfig; - if (!((upnpState >= RS_UPNP_S_READY) && (config))) - { - std::cerr << "upnphandler::start_upnp() Not Ready"; - std::cerr << std::endl; - return false; - } - - char eprot1[] = "TCP"; - char eprot2[] = "UDP"; - - /* if we're to load -> load */ - /* select external ports */ - eport_curr = eport; - if (!eport_curr) - { - /* use local port if eport is zero */ - eport_curr = iport; - std::cerr << "Using LocalPort for extPort!"; - std::cerr << std::endl; - } - - if (!eport_curr) - { - std::cerr << "Invalid eport ... "; - std::cerr << std::endl; - return false; - } - - - /* our port */ - char in_addr[256]; - char in_port1[256]; - char in_port2[256]; - char eport1[256]; - char eport2[256]; - - upnp_iaddr.sin_port = htons(iport); - struct sockaddr_in localAddr = upnp_iaddr; - uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr); - - snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port)); - snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port)); - snprintf(in_addr, 256, "%d.%d.%d.%d", - ((linaddr >> 24) & 0xff), - ((linaddr >> 16) & 0xff), - ((linaddr >> 8) & 0xff), - ((linaddr >> 0) & 0xff)); - - snprintf(eport1, 256, "%d", eport_curr); - snprintf(eport2, 256, "%d", eport_curr); - - std::cerr << "Attempting Redirection: InAddr: " << in_addr; - std::cerr << " InPort: " << in_port1; - std::cerr << " ePort: " << eport1; - std::cerr << " eProt: " << eprot1; - std::cerr << std::endl; - - if (!SetRedirectAndTest(&(config -> urls), &(config->data), - in_addr, in_port1, eport1, eprot1, - NULL /*leaseDuration*/, "RetroShare_TCP" /*description*/, - 0)) - { - upnpState = RS_UPNP_S_TCP_FAILED; - } - else if (!SetRedirectAndTest(&(config -> urls), &(config->data), - in_addr, in_port2, eport2, eprot2, - NULL /*leaseDuration*/, "RetroShare_UDP" /*description*/, - 0)) - { - upnpState = RS_UPNP_S_UDP_FAILED; - } - else - { - upnpState = RS_UPNP_S_ACTIVE; - } - - - /* now store the external address */ - char externalIPAddress[32]; - UPNP_GetExternalIPAddress(config -> urls.controlURL, -#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); - - if(externalIPAddress[0]) - { - std::cerr << "Stored External address: " << externalIPAddress; - std::cerr << ":" << eport_curr; - std::cerr << std::endl; - - inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr)); - upnp_eaddr.sin_family = AF_INET; - upnp_eaddr.sin_port = htons(eport_curr); - } - else - { - std::cerr << "FAILED To get external Address"; - std::cerr << std::endl; - } - - toStart = false; - - return true; - -} - -bool upnphandler::shutdown_upnp() -{ - RsStackMutex stack(dataMtx); /* LOCK STACK MUTEX */ - - uPnPConfigData *config = upnpConfig; - if (!((upnpState >= RS_UPNP_S_READY) && (config))) - { - return false; - } - - char eprot1[] = "TCP"; - char eprot2[] = "UDP"; - - /* always attempt this (unless no port number) */ - if (eport_curr > 0) - { - - char eport1[256]; - char eport2[256]; - - snprintf(eport1, 256, "%d", eport_curr); - snprintf(eport2, 256, "%d", eport_curr); - - std::cerr << "Attempting To Remove Redirection: port: " << eport1; - std::cerr << " Prot: " << eprot1; - std::cerr << std::endl; - - RemoveRedirect(&(config -> urls), &(config->data), - eport1, eprot1); - - - std::cerr << "Attempting To Remove Redirection: port: " << eport2; - std::cerr << " Prot: " << eprot2; - std::cerr << std::endl; - - RemoveRedirect(&(config -> urls), &(config->data), - eport2, eprot2); - - upnpState = RS_UPNP_S_READY; - toStop = false; - } - - return true; - -} - -/************************ External Interface ***************************** - * - * - * - */ - - -upnphandler::upnphandler() - : dataMtx("upnpState"), toEnable(false), toStart(false), toStop(false), - eport(0), eport_curr(0), - upnpState(RS_UPNP_S_UNINITIALISED), - upnpConfig(NULL) -{ - return; -} - -upnphandler::~upnphandler() -{ - return; -} - - /* RsIface */ -void upnphandler::enable(bool active) -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - if (active != toEnable) - { - if (active) - { - toStart = true; - } - else - { - toStop = true; - } - } - toEnable = active; - - bool start = toStart; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - if (start) - { - /* make background thread to startup UPnP */ - background_setup_upnp(true, false); - } - - -} - - -void upnphandler::shutdown() -{ - /* blocking call to shutdown upnp */ - - shutdown_upnp(); -} - - -void upnphandler::restart() -{ - /* non-blocking call to shutdown upnp, and startup again. */ - background_setup_upnp(true, true); -} - - - -bool upnphandler::getEnabled() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - bool on = toEnable; - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - -bool upnphandler::getActive() -{ - dataMtx.lock(); /*** LOCK MUTEX ***/ - - bool on = (upnpState == RS_UPNP_S_ACTIVE); - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ - - return on; -} - - /* the address that the listening port is on */ -void upnphandler::setInternalPort(unsigned short iport_in) -{ -// std::cerr << "UPnPHandler::setInternalAddress() pre Lock!" << std::endl; - dataMtx.lock(); /*** LOCK MUTEX ***/ -// std::cerr << "UPnPHandler::setInternalAddress() postLock!" << std::endl; - - std::cerr << "UPnPHandler::setInternalPort(" << iport_in << ") current port: "; - std::cerr << iport << std::endl; - - if (iport != iport_in) - { - iport = iport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - -void upnphandler::setExternalPort(unsigned short eport_in) -{ -// std::cerr << "UPnPHandler::getExternalPort() pre Lock!" << std::endl; - dataMtx.lock(); /*** LOCK MUTEX ***/ -// std::cerr << "UPnPHandler::getExternalPort() postLock!" << std::endl; - - std::cerr << "UPnPHandler::setExternalPort(" << eport_in << ") current port: "; - std::cerr << eport << std::endl; - - /* flag both shutdown/start -> for restart */ - if (eport != eport_in) - { - eport = eport_in; - if ((toEnable) && - (upnpState == RS_UPNP_S_ACTIVE)) - { - toStop = true; - toStart = true; - } - } - - dataMtx.unlock(); /*** UNLOCK MUTEX ***/ -} - -/* as determined by uPnP */ -bool upnphandler::getInternalAddress(struct sockaddr_storage &addr) -{ - RS_STACK_MUTEX(dataMtx); - - // copy to universal addr. - sockaddr_storage_clear(addr); - sockaddr_storage_setipv4(addr, &upnp_iaddr); - - bool valid = (upnpState >= RS_UPNP_S_ACTIVE); - - Dbg2() << __PRETTY_FUNCTION__ << " valid: " << valid - << " addr: " << addr << std::endl; - - return valid; -} - -bool upnphandler::getExternalAddress(sockaddr_storage &addr) -{ - RS_STACK_MUTEX(dataMtx); - - // copy to universal addr. - sockaddr_storage_clear(addr); - sockaddr_storage_setipv4(addr, &upnp_eaddr); - - bool valid = (upnpState == RS_UPNP_S_ACTIVE); - - Dbg2() << __PRETTY_FUNCTION__ << " valid: " << valid - << " addr: " << addr << std::endl; - - return valid; -} - diff --git a/libretroshare/src/rs_upnp/upnphandler_miniupnp.h b/libretroshare/src/rs_upnp/upnphandler_miniupnp.h deleted file mode 100644 index 9449661e0..000000000 --- a/libretroshare/src/rs_upnp/upnphandler_miniupnp.h +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnphandler_miniupnp.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2018 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -/* platform independent networking... */ -#include "pqi/pqinetwork.h" -#include "pqi/pqiassist.h" -#include "util/rsdebug.h" -#include "util/rsthreads.h" - -class upnpentry -{ - public: - std::string name; - std::string id; - struct sockaddr_in addr; - unsigned int flags; - int status; - int lastTs; -}; - -class upnpforward -{ - public: - std::string name; - unsigned int flags; - struct sockaddr_in iaddr; - struct sockaddr_in eaddr; - int status; - int lastTs; -}; - - -#define RS_UPNP_S_UNINITIALISED 0 -#define RS_UPNP_S_UNAVAILABLE 1 -#define RS_UPNP_S_READY 2 -#define RS_UPNP_S_TCP_FAILED 3 -#define RS_UPNP_S_UDP_FAILED 4 -#define RS_UPNP_S_ACTIVE 5 - -class uPnPConfigData; - -class upnphandler: public pqiNetAssistFirewall -{ - public: - - upnphandler(); -virtual ~upnphandler(); - - /* External Interface (pqiNetAssistFirewall) */ -virtual void enable(bool active); -virtual void shutdown(); -virtual void restart(); - -virtual bool getEnabled(); -virtual bool getActive(); - -virtual void setInternalPort(unsigned short iport_in); -virtual void setExternalPort(unsigned short eport_in); -virtual bool getInternalAddress(struct sockaddr_storage &addr); -virtual bool getExternalAddress(struct sockaddr_storage &addr); - - /* TO IMPLEMENT: New Port Forward interface to support as many ports as necessary */ -virtual bool requestPortForward(const PortForwardParams &/*params*/) { return false; } -virtual bool statusPortForward(const uint32_t /*fwdId*/, PortForwardParams &/*params*/) { return false; } - -/* Public functions - for background thread operation, - * but effectively private from rest of RS, as in derived class - */ - -bool start_upnp(); -bool shutdown_upnp(); - -bool initUPnPState(); -bool printUPnPState(); - -private: - -bool background_setup_upnp(bool, bool); -bool checkUPnPActive(); - - /* Mutex for data below */ - RsMutex dataMtx; - - bool toEnable; /* overall on/off switch */ - bool toStart; /* if set start forwarding */ - bool toStop; /* if set stop forwarding */ - - unsigned short iport; - unsigned short eport; /* config */ - unsigned short eport_curr; /* current forwarded */ - - /* info from upnp */ - unsigned int upnpState; - uPnPConfigData *upnpConfig; - - struct sockaddr_in upnp_iaddr; - struct sockaddr_in upnp_eaddr; - - /* active port forwarding */ - std::list activeForwards; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; diff --git a/libretroshare/src/rs_upnp/upnptest.cc b/libretroshare/src/rs_upnp/upnptest.cc deleted file mode 100644 index 80d98e4e5..000000000 --- a/libretroshare/src/rs_upnp/upnptest.cc +++ /dev/null @@ -1,86 +0,0 @@ -//this file use miniupnp - -#include - - -int main(int argc, char **argv) -{ - - int id = argc % 3; - - /********* - char *fhash1 = "3509426505463458576487"; - char *hash2 = "1549879882341985914515"; - char *hash3 = "8743598543269526505434"; - - int port1 = 8754; - int port2 = 2355; - int port3 = 6621; - **********/ - - std::cerr << "Starting dhttest Id: " << id << std::endl; -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - #ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); - #endif - - - upnphandler upnp; - - upnp.setInternalPort(12122); - - for(int i = 0; 1; i++) - { - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(1); -#else - - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - if (i % 120 == 10) - { - /* start up a forward */ - upnp.enable(true); - - } - - if (i % 120 == 60) - { - /* shutdown a forward */ - upnp.restart(); - } - - if (i % 120 == 100) - { - /* shutdown a forward */ - upnp.shutdown(); - } - - } -} - diff --git a/libretroshare/src/rs_upnp/upnputil.cc b/libretroshare/src/rs_upnp/upnputil.cc deleted file mode 100644 index 28b0c4de6..000000000 --- a/libretroshare/src/rs_upnp/upnputil.cc +++ /dev/null @@ -1,611 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnputil.c * - * * - * libretroshare: retroshare core library * - * From MiniUPnPc, re-licensed with permission * - * * - * Copyright (c) 2005-2016, Thomas BERNARD * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -//this file uses miniupnp -//From https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/upnpc.c - -#include "rs_upnp/upnputil.h" - -#if MINIUPNPC_API_VERSION >= -4//1.0 2008/02/18 -#include "util/rstime.h" -#endif - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - 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)) ); - 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)) ); - if(b) - return proto_udp; - return 0; -} - -void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - char externalIPAddress[40]; - char connectionType[64]; - char status[64]; - char lastconnerr[64]; - unsigned int uptime; - unsigned int brUp, brDown; - time_t timenow, timestarted; // Don't use rstime_t here or ctime break on windows - 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]) -#endif//>=-7 -#endif//>=-3 - printf("GetConnectionTypeInfo failed.\n"); - 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, - 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) -{ - 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, 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); -} - -void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ - int r; - int i = 0; - char index[6]; - char intClient[40]; - char intPort[6]; - char extPort[6]; - char protocol[4]; - char desc[80]; - 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);*/ - do { - snprintf(index, 6, "%d", i); - 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, - servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - 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); - else - printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); - i++; - } while(r==0); -} - -/* Test function - * 1 - get connection type - * 2 - get extenal ip address - * 3 - Add port mapping - * 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 * leaseDuration, - const char * description, - int addAny) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - 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) - { - fprintf(stderr, "Wrong arguments\n"); - return 0; - } - proto = protofix(proto); - if(!proto) - { - 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, - servicetype, - externalIPAddress); - if(externalIPAddress[0]) - printf("ExternalIPAddress = %s\n", externalIPAddress); - else - printf("GetExternalIPAddress failed.\n"); -#endif//>=-7 -#endif//>=-4 - -#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 - { -#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, description, proto, NULL, NULL); -#else -#if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17 - /* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */ - /* $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, description, proto, NULL); -#else -#if MINIUPNPC_API_VERSION >= -7//Before 1.0 - /* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */ - /* $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, description, 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, - 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)) - { - printf("PortMappingEntry to wrong location! FAILED\n"); - printf("IP1:\"%s\"\n", iaddr); - printf("IP2:\"%s\"\n", intClient); - printf("PORT1:\"%s\"\n", iport); - printf("PORT2:\"%s\"\n", intPort); - ok = 0; - } - - if (ok) - { - printf("uPnP Forward/Mapping Succeeded\n"); - } - else - { - printf("uPnP Forward/Mapping Failed\n"); - } - - return ok; -} - -int TestRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto) -{ - char externalIPAddress[40]; - char intClient[40]; - char intPort[6]; - char duration[16]; - int r = 0; - int ok = 1; - - if(!iaddr || !iport || !eport || !proto) - { - fprintf(stderr, "Wrong arguments\n"); - return 0; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "invalid protocol\n"); - return 0; - } - -#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) - { - printf("uPnP Check: uPnP Forward/Mapping still Active\n"); - } - else - { - printf("uPnP Check: Forward/Mapping has been Dropped\n"); - } - - return ok; -} - -int -RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto) -{ - if(!proto || !eport) - { - fprintf(stderr, "invalid arguments\n"); - return 0; - } - proto = protofix(proto); - if(!proto) - { - fprintf(stderr, "protocol invalid\n"); - return 0; - } -#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); -#else -#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version -#endif//>= -7 -#endif//>= -3 -#endif//>= -2 - - return 1; -} - - -/* EOF */ diff --git a/libretroshare/src/rs_upnp/upnputil.h b/libretroshare/src/rs_upnp/upnputil.h deleted file mode 100644 index 9586418a4..000000000 --- a/libretroshare/src/rs_upnp/upnputil.h +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * libretroshare/src/upnp: upnputil.h * - * * - * libretroshare: retroshare core library * - * From MiniUPnPc, re-licensed with permission * - * * - * Copyright (c) 2005-2016, Thomas BERNARD * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -//this file uses miniupnp - -#ifndef MINIUPNP_UTIL_H_ -#define MINIUPNP_UTIL_H_ - -#include -#include -#include -#ifdef WIN32 -#include -#define snprintf _snprintf -#endif -#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) */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* protofix() checks if protocol is "UDP" or "TCP" - * returns NULL if not */ -const char * protofix(const char * proto); -void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data); - -void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data); - -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, - const char *leaseDuration, - const char *description, - int addAny); - -int TestRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto); - -int RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto); - -#ifdef __cplusplus -} -#endif - -/* EOF */ -#endif diff --git a/libretroshare/src/rsitems/itempriorities.h b/libretroshare/src/rsitems/itempriorities.h deleted file mode 100644 index a376a9d64..000000000 --- a/libretroshare/src/rsitems/itempriorities.h +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsitempriorities.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -// This file centralises QoS priorities for all transfer RsItems -// -const uint8_t QOS_PRIORITY_UNKNOWN = 0 ; -const uint8_t QOS_PRIORITY_DEFAULT = 3 ; -const uint8_t QOS_PRIORITY_TOP = 9 ; - -// Turtle traffic -// -const uint8_t QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL = 7 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_TUNNEL_OK = 7 ; - -const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_REQUEST = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST = 6 ; // unused -const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST = 6 ; // unused - -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_DATA = 5 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_CRC = 6 ; // unused -const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC = 6 ; // unused - -const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA = 7 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT = 6 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ; -const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA = 3 ; // unused - -// File transfer -// -const uint8_t QOS_PRIORITY_RS_FILE_REQUEST = 6 ; -const uint8_t QOS_PRIORITY_RS_FILE_MAP_REQUEST = 6 ; -const uint8_t QOS_PRIORITY_RS_FILE_CRC_REQUEST = 6 ; // unused -const uint8_t QOS_PRIORITY_RS_CHUNK_CRC_REQUEST = 6 ; - -const uint8_t QOS_PRIORITY_RS_FILE_DATA = 5 ; -const uint8_t QOS_PRIORITY_RS_FILE_MAP = 6 ; -const uint8_t QOS_PRIORITY_RS_FILE_CRC = 6 ; // unused -const uint8_t QOS_PRIORITY_RS_CHUNK_CRC = 6 ; - -const uint8_t QOS_PRIORITY_RS_CACHE_ITEM = 3 ; // unused - -// Discovery -// -const uint8_t QOS_PRIORITY_RS_DISC_HEART_BEAT = 8 ; -const uint8_t QOS_PRIORITY_RS_DISC_ASK_INFO = 2 ; -const uint8_t QOS_PRIORITY_RS_DISC_REPLY = 2 ; -const uint8_t QOS_PRIORITY_RS_DISC_VERSION = 2 ; - -const uint8_t QOS_PRIORITY_RS_DISC_CONTACT = 2 ; // CONTACT and PGPLIST must have -const uint8_t QOS_PRIORITY_RS_DISC_PGP_LIST = 2 ; // same priority -const uint8_t QOS_PRIORITY_RS_DISC_SERVICES = 2 ; -const uint8_t QOS_PRIORITY_RS_DISC_PGP_CERT = 2 ; - -// File database -// -const uint8_t QOS_PRIORITY_RS_FAST_SYNC_REQUEST = 7 ; -const uint8_t QOS_PRIORITY_RS_SLOW_SYNC_REQUEST = 3 ; - -// Heartbeat -// -const uint8_t QOS_PRIORITY_RS_HEARTBEAT_PULSE = 8 ; - -// Chat/Msgs -// -const uint8_t QOS_PRIORITY_RS_CHAT_ITEM = 7 ; -const uint8_t QOS_PRIORITY_RS_CHAT_AVATAR_ITEM = 2 ; -const uint8_t QOS_PRIORITY_RS_MSG_ITEM = 2 ; // deprecated -const uint8_t QOS_PRIORITY_RS_MAIL_ITEM = 2 ; // new mail service -const uint8_t QOS_PRIORITY_RS_STATUS_ITEM = 2 ; - -// RTT -// -const uint8_t QOS_PRIORITY_RS_RTT_PING = 9 ; - -// BanList -// -const uint8_t QOS_PRIORITY_RS_BANLIST_ITEM = 3 ; - -// Bandwidth Control -// -const uint8_t QOS_PRIORITY_RS_BWCTRL_ALLOWED_ITEM = 9 ; - -// DsDv Routing -// -const uint8_t QOS_PRIORITY_RS_DSDV_ROUTE = 4 ; -const uint8_t QOS_PRIORITY_RS_DSDV_DATA = 2 ; - -// GXS -// -const uint8_t QOS_PRIORITY_RS_GXS_NET = 6 ; - -// GXS Reputation -// -const uint8_t QOS_PRIORITY_RS_GXSREPUTATION_ITEM = 3 ; - -// Service Info / Control -// -const uint8_t QOS_PRIORITY_RS_SERVICE_INFO_ITEM = 8 ; - diff --git a/libretroshare/src/rsitems/rsbanlistitems.cc b/libretroshare/src/rsitems/rsbanlistitems.cc deleted file mode 100644 index f283f5b43..000000000 --- a/libretroshare/src/rsitems/rsbanlistitems.cc +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsbanlistitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsbaseserial.h" -#include "rsitems/rsbanlistitems.h" - -#include "serialiser/rstypeserializer.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ - -void RsBanListItem::clear() -{ - peerList.TlvClear(); -} - -void RsBanListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,peerList,"peerList") ; -} - -void RsBanListConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,banListType,"type") ; - RsTypeSerializer::serial_process (j,ctx,banListPeerId,"peerId") ; - RsTypeSerializer::serial_process (j,ctx,update_time,"update_time") ; - RsTypeSerializer::serial_process (j,ctx,banned_peers,"banned_peers") ; -} -RsItem *RsBanListSerialiser::create_item(uint16_t service_id,uint8_t item_sub_id) const -{ - if(service_id != RS_SERVICE_TYPE_BANLIST) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_BANLIST_CONFIG_ITEM: return new RsBanListConfigItem ; - case RS_PKT_SUBTYPE_BANLIST_ITEM: return new RsBanListItem ; - default: - std::cerr << "(EE) unknown item subtype " << (int)item_sub_id << " in RsBanListSerialiser::create_item()" << std::endl; - return NULL ; - } -} - - diff --git a/libretroshare/src/rsitems/rsbanlistitems.h b/libretroshare/src/rsitems/rsbanlistitems.h deleted file mode 100644 index 6422340af..000000000 --- a/libretroshare/src/rsitems/rsbanlistitems.h +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsbanlistitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_BANLIST_ITEMS_H -#define RS_BANLIST_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" -#include "serialiser/rstlvbanlist.h" -#include "serialiser/rsserializer.h" - -#define RS_PKT_SUBTYPE_BANLIST_ITEM_deprecated 0x01 -#define RS_PKT_SUBTYPE_BANLIST_CONFIG_ITEM_deprecated 0x02 -#define RS_PKT_SUBTYPE_BANLIST_ITEM 0x03 -#define RS_PKT_SUBTYPE_BANLIST_CONFIG_ITEM 0x04 - -/**************************************************************************/ - -class RsBanListItem: public RsItem -{ - public: - RsBanListItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST, RS_PKT_SUBTYPE_BANLIST_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_BANLIST_ITEM); - return; - } - - virtual ~RsBanListItem(){} - virtual void clear(); - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvBanList peerList; -}; - -class RsBanListConfigItem: public RsItem -{ -public: - RsBanListConfigItem() - : RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BANLIST, RS_PKT_SUBTYPE_BANLIST_CONFIG_ITEM) - , banListType(0), update_time(0) - {} - - virtual ~RsBanListConfigItem(){} - virtual void clear() { banned_peers.TlvClear() ; } - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t banListType ; - RsPeerId banListPeerId ; - rstime_t update_time ; - RsTlvBanList banned_peers; -}; - -class RsBanListSerialiser: public RsServiceSerializer -{ -public: - RsBanListSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_BANLIST) {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const ; -}; - -/**************************************************************************/ - -#endif /* RS_BANLIST_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rsbwctrlitems.cc b/libretroshare/src/rsitems/rsbwctrlitems.cc deleted file mode 100644 index 759264aa0..000000000 --- a/libretroshare/src/rsitems/rsbwctrlitems.cc +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsbwctrlitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsbaseserial.h" -#include "rsitems/rsbwctrlitems.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ - -RsItem *RsBwCtrlSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_TYPE_BWCTRL) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_BWCTRL_ALLOWED_ITEM: return new RsBwCtrlAllowedItem(); - default: - return NULL; - } -} - -void RsBwCtrlAllowedItem::clear() -{ - allowedBw = 0; -} - -void RsBwCtrlAllowedItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_BW,allowedBw,"allowedBw") ; -} - - - diff --git a/libretroshare/src/rsitems/rsbwctrlitems.h b/libretroshare/src/rsitems/rsbwctrlitems.h deleted file mode 100644 index 300bd6f54..000000000 --- a/libretroshare/src/rsitems/rsbwctrlitems.h +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsbwctrlitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_BANDWIDTH_CONTROL_ITEMS_H -#define RS_BANDWIDTH_CONTROL_ITEMS_H - -#include - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rsserializer.h" -#include "serialiser/rstypeserializer.h" - -#define RS_PKT_SUBTYPE_BWCTRL_ALLOWED_ITEM 0x01 - -/**************************************************************************/ - -class RsBwCtrlAllowedItem: public RsItem -{ -public: - RsBwCtrlAllowedItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_BWCTRL, RS_PKT_SUBTYPE_BWCTRL_ALLOWED_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_BWCTRL_ALLOWED_ITEM); - return; - } - - virtual ~RsBwCtrlAllowedItem() {} - virtual void clear(); - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t allowedBw; // Units are bytes/sec => 4Gb/s; -}; - - -class RsBwCtrlSerialiser: public RsServiceSerializer -{ -public: - RsBwCtrlSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_BWCTRL) {} - virtual ~RsBwCtrlSerialiser() {} - - RsItem *create_item(uint16_t /* service */, uint8_t /* item_sub_id */) const; -}; - -/**************************************************************************/ - -#endif /* RS_BANDWIDTH_CONTROL_ITEMS_H */ - diff --git a/libretroshare/src/rsitems/rsconfigitems.cc b/libretroshare/src/rsitems/rsconfigitems.cc deleted file mode 100644 index 654d1a7f6..000000000 --- a/libretroshare/src/rsitems/rsconfigitems.cc +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsconfigitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsbaseserial.h" -#include "rsitems/rsconfigitems.h" -#include "retroshare/rspeers.h" // Needed for RsGroupInfo. - -#include "serialiser/rsserializable.h" -#include "serialiser/rstypeserializer.h" -/*** - * #define RSSERIAL_DEBUG 1 - * #define RSSERIAL_ERROR_DEBUG 1 - ***/ - -#define RSSERIAL_ERROR_DEBUG 1 - -#include - - -/*************************************************************************/ - -RsItem *RsFileConfigSerialiser::create_item(uint8_t item_type,uint8_t item_subtype) const -{ - if(item_type != RS_PKT_TYPE_FILE_CONFIG) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_FILE_TRANSFER: return new RsFileTransfer() ; - case RS_PKT_SUBTYPE_FILE_ITEM: return new RsFileConfigItem() ; - default: - return NULL ; - } -} -void RsFileTransfer::clear() -{ - - file.TlvClear(); - allPeerIds.TlvClear(); - cPeerId.clear() ; - state = 0; - in = false; - transferred = 0; - crate = 0; - trate = 0; - lrate = 0; - ltransfer = 0; - -} - -void RsFileTransfer::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,file,"file") ; - RsTypeSerializer::serial_process(j,ctx,allPeerIds,"allPeerIds") ; - - RsTypeSerializer::serial_process (j,ctx,cPeerId,"cPeerId") ; - - RsTypeSerializer::serial_process (j,ctx,state,"state") ; - RsTypeSerializer::serial_process (j,ctx,in,"in") ; - - RsTypeSerializer::serial_process (j,ctx,transferred,"transferred") ; - - RsTypeSerializer::serial_process (j,ctx,crate,"crate") ; - RsTypeSerializer::serial_process (j,ctx,trate,"trate") ; - RsTypeSerializer::serial_process (j,ctx,lrate,"lrate") ; - RsTypeSerializer::serial_process (j,ctx,ltransfer,"ltransfer") ; - - RsTypeSerializer::serial_process (j,ctx,flags,"flags") ; - RsTypeSerializer::serial_process (j,ctx,chunk_strategy,"chunk_strategy") ; - RS_SERIAL_PROCESS(compressed_chunk_map); -} - -void RsFileConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,file,"file") ; - RsTypeSerializer::serial_process (j,ctx,flags,"flags") ; - RsTypeSerializer::serial_process(j,ctx,parent_groups,"parent_groups") ; -} - -RsItem *RsGeneralConfigSerialiser::create_item(uint8_t item_type,uint8_t item_subtype) const -{ - if(item_type != RS_PKT_TYPE_GENERAL_CONFIG) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_KEY_VALUE: return new RsConfigKeyValueSet(); - default: - return NULL ; - } -} - -void RsConfigKeyValueSet::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tlvkvs,"tlvkvs") ; -} - -RsItem *RsPeerConfigSerialiser::create_item(uint8_t item_type,uint8_t item_subtype) const -{ - if(item_type != RS_PKT_TYPE_PEER_CONFIG) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_PEER_NET: return new RsPeerNetItem(); - case RS_PKT_SUBTYPE_PEER_STUN: return new RsPeerStunItem(); - case RS_PKT_SUBTYPE_NODE_GROUP: return new RsNodeGroupItem() ; - case RS_PKT_SUBTYPE_PEER_PERMISSIONS: return new RsPeerServicePermissionItem(); - case RS_PKT_SUBTYPE_PEER_BANDLIMITS: return new RsPeerBandwidthLimitsItem(); - default: - return NULL ; - } -} - -void RsPeerNetItem::clear() -{ - nodePeerId.clear(); - pgpId.clear(); - location.clear(); - netMode = 0; - vs_disc = 0; - vs_dht = 0; - lastContact = 0; - - localAddrV4.TlvClear(); - extAddrV4.TlvClear(); - localAddrV6.TlvClear(); - extAddrV6.TlvClear(); - - dyndns.clear(); - - localAddrList.TlvClear(); - extAddrList.TlvClear(); - - domain_addr.clear(); - domain_port = 0; -} -void RsPeerNetItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,nodePeerId,"peerId") ; - RsTypeSerializer::serial_process(j,ctx,pgpId,"pgpId") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION,location,"location") ; - - RsTypeSerializer::serial_process(j,ctx,netMode,"netMode") ; - RsTypeSerializer::serial_process(j,ctx,vs_disc,"vs_disc") ; - RsTypeSerializer::serial_process(j,ctx,vs_dht,"vs_dht") ; - RsTypeSerializer::serial_process(j,ctx,lastContact,"lastContact") ; - - RsTypeSerializer::serial_process(j,ctx,localAddrV4,"localAddrV4") ; - RsTypeSerializer::serial_process(j,ctx,extAddrV4,"extAddrV4") ; - RsTypeSerializer::serial_process(j,ctx,localAddrV6,"localAddrV6") ; - RsTypeSerializer::serial_process(j,ctx,extAddrV6,"extAddrV6") ; - - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DYNDNS,dyndns,"dyndns") ; - - RsTypeSerializer::serial_process(j,ctx,localAddrList,"localAddrList") ; - RsTypeSerializer::serial_process(j,ctx,extAddrList,"extAddrList") ; - - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DOMADDR,domain_addr,"domain_addr") ; - RsTypeSerializer::serial_process(j,ctx,domain_port,"domain_port") ; -} - -void RsPeerBandwidthLimitsItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,peers,"peers") ; -} - -void RsPeerStunItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,stunList,"stunList") ; -} - - -RsNodeGroupItem::RsNodeGroupItem(const RsGroupInfo& g) - :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_NODE_GROUP) -{ - id = g.id ; - name = g.name ; - flag = g.flag ; - pgpList.ids = g.peerIds; -} - -void RsNodeGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - uint32_t v=0 ; - - RsTypeSerializer::serial_process(j,ctx,v,"dummy field 0") ; - RsTypeSerializer::serial_process (j,ctx,id,"id") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,name,"name") ; - RsTypeSerializer::serial_process(j,ctx,flag,"flag") ; - RsTypeSerializer::serial_process(j,ctx,pgpList,"pgpList") ; -} - -void RsPeerServicePermissionItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - // We need to hack this because of backward compatibility. The correct way to do it would be: - // - // RsTypeSerializer::serial_process(j,ctx,pgp_ids,"pgp_ids") ; - // RsTypeSerializer::serial_process(j,ctx,service_flags,"service_flags") ; - - if(j == RsGenericSerializer::DESERIALIZE) - { - uint32_t v=0 ; - RsTypeSerializer::serial_process(j,ctx,v,"pgp_ids.size()") ; - - pgp_ids.resize(v) ; - service_flags.resize(v) ; - } - else - { - uint32_t s = pgp_ids.size(); - RsTypeSerializer::serial_process(j,ctx,s,"pgp_ids.size()") ; - } - - for(uint32_t i=0;i * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_CONFIG_ITEMS_SERIALISER_H -#define RS_CONFIG_ITEMS_SERIALISER_H - -#include -#include - -#include "rsitems/rsitem.h" - -#include "retroshare/rstypes.h" -#include "serialiser/rsserial.h" - -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvkeyvalue.h" -#include "serialiser/rstlvaddrs.h" - -#include "serialiser/rsserializer.h" - -struct RsGroupInfo; - -const uint8_t RS_PKT_TYPE_GENERAL_CONFIG = 0x01; -const uint8_t RS_PKT_TYPE_PEER_CONFIG = 0x02; -const uint8_t RS_PKT_TYPE_CACHE_CONFIG = 0x03; -const uint8_t RS_PKT_TYPE_FILE_CONFIG = 0x04; -const uint8_t RS_PKT_TYPE_PLUGIN_CONFIG = 0x05; -const uint8_t RS_PKT_TYPE_HISTORY_CONFIG = 0x06; - - /* GENERAL CONFIG SUBTYPES */ -const uint8_t RS_PKT_SUBTYPE_KEY_VALUE = 0x01; - - /* PEER CONFIG SUBTYPES */ -const uint8_t RS_PKT_SUBTYPE_PEER_STUN = 0x02; -const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03; -const uint8_t RS_PKT_SUBTYPE_PEER_GROUP_deprecated = 0x04; -const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05; -const uint8_t RS_PKT_SUBTYPE_PEER_BANDLIMITS = 0x06; -const uint8_t RS_PKT_SUBTYPE_NODE_GROUP = 0x07; - - /* FILE CONFIG SUBTYPES */ -const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01; -const uint8_t RS_PKT_SUBTYPE_FILE_ITEM_deprecated = 0x02; -const uint8_t RS_PKT_SUBTYPE_FILE_ITEM = 0x03; - -/**************************************************************************/ - -class RsPeerNetItem: public RsItem -{ -public: - RsPeerNetItem() - :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, - RS_PKT_TYPE_PEER_CONFIG, - RS_PKT_SUBTYPE_PEER_NET) - , netMode(0), vs_disc(0), vs_dht(0), lastContact(0), domain_port(0) - {} - - virtual ~RsPeerNetItem(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - /* networking information */ - RsPeerId nodePeerId; /* Mandatory */ - RsPgpId pgpId; /* Mandatory */ - std::string location; /* Mandatory */ - uint32_t netMode; /* Mandatory */ - uint16_t vs_disc; /* Mandatory */ - uint16_t vs_dht; /* Mandatory */ - uint32_t lastContact; /* Mandatory */ - - RsTlvIpAddress localAddrV4; /* Mandatory */ - RsTlvIpAddress extAddrV4; /* Mandatory */ - RsTlvIpAddress localAddrV6; /* Mandatory */ - RsTlvIpAddress extAddrV6; /* Mandatory */ - - std::string dyndns; - - RsTlvIpAddrSet localAddrList; - RsTlvIpAddrSet extAddrList; - - // for proxy connection. - std::string domain_addr; - uint16_t domain_port; -}; - -// This item should be merged with the next item, but that is not backward compatible. -class RsPeerServicePermissionItem : public RsItem -{ - public: - RsPeerServicePermissionItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_PERMISSIONS) {} - virtual ~RsPeerServicePermissionItem() {} - - virtual void clear() - { - pgp_ids.clear() ; - service_flags.clear() ; - } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - - /* Mandatory */ - std::vector pgp_ids ; - std::vector service_flags ; -}; -class RsPeerBandwidthLimitsItem : public RsItem -{ - public: - RsPeerBandwidthLimitsItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_BANDLIMITS) {} - virtual ~RsPeerBandwidthLimitsItem() {} - - virtual void clear() - { - peers.clear() ; - } - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - /* Mandatory */ - std::map peers ; -}; - -class RsNodeGroupItem: public RsItem -{ -public: - RsNodeGroupItem(): RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_NODE_GROUP), flag(0) {} - virtual ~RsNodeGroupItem() {} - - virtual void clear() { pgpList.TlvClear();} - - explicit RsNodeGroupItem(const RsGroupInfo&) ; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // /* set data from RsGroupInfo to RsPeerGroupItem */ - // void set(RsGroupInfo &groupInfo); - // /* get data from RsGroupInfo to RsPeerGroupItem */ - // void get(RsGroupInfo &groupInfo); - - /* Mandatory */ - RsNodeGroupId id; - std::string name; - uint32_t flag; - - RsTlvPgpIdSet pgpList; -}; - -class RsPeerStunItem: public RsItem -{ -public: - RsPeerStunItem() - :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, - RS_PKT_TYPE_PEER_CONFIG, - RS_PKT_SUBTYPE_PEER_STUN) {} - virtual ~RsPeerStunItem(){} - virtual void clear() { stunList.TlvClear() ;} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvPeerIdSet stunList; /* Mandatory */ -}; - -class RsPeerConfigSerialiser: public RsConfigSerializer -{ - public: - RsPeerConfigSerialiser() :RsConfigSerializer(RS_PKT_CLASS_CONFIG,RS_PKT_TYPE_PEER_CONFIG) {} - - virtual ~RsPeerConfigSerialiser(){} - - virtual RsItem *create_item(uint8_t item_type, uint8_t item_subtype) const ; -}; - -/**************************************************************************/ - -class RsFileTransfer: public RsItem -{ - public: - RsFileTransfer() :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FILE_CONFIG, RS_PKT_SUBTYPE_FILE_TRANSFER) - { - state = 0; - in = 0; - transferred = 0; - crate = 0; - trate = 0; - lrate = 0; - ltransfer = 0; - flags = 0; - chunk_strategy = 0; - } - virtual ~RsFileTransfer(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvFileItem file; - RsTlvPeerIdSet allPeerIds; - - RsPeerId cPeerId; - - uint16_t state; - uint16_t in; - - uint64_t transferred; - uint32_t crate; - uint32_t trate; - - uint32_t lrate; - uint32_t ltransfer; - - // chunk information - uint32_t flags ; - uint32_t chunk_strategy ; // strategy flags for chunks - CompressedChunkMap compressed_chunk_map ; // chunk availability (bitwise) -}; - -/**************************************************************************/ - -const uint32_t RS_FILE_CONFIG_CLEANUP_DELETE = 0x0001; - -class RsFileConfigItem: public RsItem -{ -public: - RsFileConfigItem() :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FILE_CONFIG, RS_PKT_SUBTYPE_FILE_ITEM), flags(0) {} - virtual ~RsFileConfigItem() {} - virtual void clear() { parent_groups.TlvClear(); } - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvFileItem file; - uint32_t flags; - RsTlvNodeGroupIdSet parent_groups ; -}; -/**************************************************************************/ - -class RsFileConfigSerialiser: public RsConfigSerializer -{ - public: - RsFileConfigSerialiser() :RsConfigSerializer(RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_FILE_CONFIG) { } - virtual ~RsFileConfigSerialiser() {} - - virtual RsItem *create_item(uint8_t item_type, uint8_t item_subtype) const ; -}; - -/**************************************************************************/ - -/* Config items that are used generally */ - -class RsConfigKeyValueSet: public RsItem -{ -public: - RsConfigKeyValueSet() :RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_GENERAL_CONFIG, RS_PKT_SUBTYPE_KEY_VALUE) {} - virtual ~RsConfigKeyValueSet(){} - virtual void clear() { tlvkvs.TlvClear();} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvKeyValueSet tlvkvs; -}; - - -class RsGeneralConfigSerialiser: public RsConfigSerializer -{ - public: - RsGeneralConfigSerialiser() :RsConfigSerializer(RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_GENERAL_CONFIG) {} - - virtual RsItem *create_item(uint8_t item_type, uint8_t item_subtype) const ; -}; - -#endif /* RS_CONFIG_ITEMS_SERIALISER_H */ diff --git a/libretroshare/src/rsitems/rsfiletransferitems.cc b/libretroshare/src/rsitems/rsfiletransferitems.cc deleted file mode 100644 index 3c34acf6a..000000000 --- a/libretroshare/src/rsitems/rsfiletransferitems.cc +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsfiletransferitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" -#include "rsitems/rsfiletransferitems.h" - -#include "serialiser/rstypeserializer.h" - -/*** - * #define RSSERIAL_DEBUG 1 - * #define DEBUG_TRANSFERS 1 -***/ - - -#ifdef DEBUG_TRANSFERS - #include "util/rsprint.h" -#endif - -#include - -void RsFileTransferDataRequestItem::clear() -{ - file.TlvClear(); - fileoffset = 0; - chunksize = 0; -} -void RsFileTransferDataItem::clear() -{ - fd.TlvClear(); -} - -void RsFileTransferDataRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,fileoffset,"fileoffset") ; - RsTypeSerializer::serial_process (j,ctx,chunksize, "chunksize") ; - RsTypeSerializer::serial_process(j,ctx,file, "file") ; -} - -void RsFileTransferDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,fd,"fd") ; -} - -void RsFileTransferChunkMapRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,is_client,"is_client") ; - RsTypeSerializer::serial_process (j,ctx,hash, "hash") ; -} - -void RsFileTransferChunkMapItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,is_client, "is_client") ; - RsTypeSerializer::serial_process (j,ctx,hash, "hash") ; - RsTypeSerializer::serial_process (j,ctx,compressed_map,"compressed_map") ; -} - -void RsFileTransferSingleChunkCrcRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,hash, "hash") ; - RsTypeSerializer::serial_process(j,ctx,chunk_number,"chunk_number") ; -} - -void RsFileTransferSingleChunkCrcItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,hash, "hash") ; - RsTypeSerializer::serial_process(j,ctx,chunk_number,"chunk_number") ; - RsTypeSerializer::serial_process (j,ctx,check_sum, "check_sum") ; -} - -//===================================================================================================// -// Serializer // -//===================================================================================================// - -RsItem *RsFileTransferSerialiser::create_item(uint16_t service_type,uint8_t item_type) const -{ - if(service_type != RS_SERVICE_TYPE_FILE_TRANSFER) - return NULL ; - - switch(item_type) - { - case RS_PKT_SUBTYPE_FT_DATA_REQUEST : return new RsFileTransferDataRequestItem(); - case RS_PKT_SUBTYPE_FT_DATA : return new RsFileTransferDataItem(); - case RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST : return new RsFileTransferChunkMapRequestItem(); - case RS_PKT_SUBTYPE_FT_CHUNK_MAP : return new RsFileTransferChunkMapItem(); - case RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST : return new RsFileTransferSingleChunkCrcRequestItem(); - case RS_PKT_SUBTYPE_FT_CHUNK_CRC : return new RsFileTransferSingleChunkCrcItem() ; - default: - return NULL ; - } -} diff --git a/libretroshare/src/rsitems/rsfiletransferitems.h b/libretroshare/src/rsitems/rsfiletransferitems.h deleted file mode 100644 index 60514e41f..000000000 --- a/libretroshare/src/rsitems/rsfiletransferitems.h +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsfiletransferitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include "retroshare/rstypes.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvfileitem.h" -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rsserializer.h" - -const uint8_t RS_PKT_SUBTYPE_FT_DATA_REQUEST = 0x01; -const uint8_t RS_PKT_SUBTYPE_FT_DATA = 0x02; -const uint8_t RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST = 0x04; -const uint8_t RS_PKT_SUBTYPE_FT_CHUNK_MAP = 0x05; -const uint8_t RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST = 0x08; -const uint8_t RS_PKT_SUBTYPE_FT_CHUNK_CRC = 0x09; - -const uint8_t RS_PKT_SUBTYPE_FT_CACHE_ITEM = 0x0A; -const uint8_t RS_PKT_SUBTYPE_FT_CACHE_REQUEST = 0x0B; - -//const uint8_t RS_PKT_SUBTYPE_FT_TRANSFER = 0x03; -//const uint8_t RS_PKT_SUBTYPE_FT_CRC32_MAP_REQUEST = 0x06; -//const uint8_t RS_PKT_SUBTYPE_FT_CRC32_MAP = 0x07; - -/**************************************************************************/ - -class RsFileTransferItem: public RsItem -{ - public: - RsFileTransferItem(uint8_t ft_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_FILE_TRANSFER,ft_subtype) {} - - virtual ~RsFileTransferItem() {} - - virtual void clear() = 0 ; -}; - -class RsFileTransferDataRequestItem: public RsFileTransferItem -{ - public: - RsFileTransferDataRequestItem() :RsFileTransferItem(RS_PKT_SUBTYPE_FT_DATA_REQUEST) - { - setPriorityLevel(QOS_PRIORITY_RS_FILE_REQUEST) ; - } - virtual ~RsFileTransferDataRequestItem() {} - virtual void clear(); - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // Private data part. - // - uint64_t fileoffset; /* start of data requested */ - uint32_t chunksize; /* size of data requested */ - RsTlvFileItem file; /* file information */ -}; - -/**************************************************************************/ - -class RsFileTransferDataItem: public RsFileTransferItem -{ - public: - RsFileTransferDataItem() :RsFileTransferItem(RS_PKT_SUBTYPE_FT_DATA) - { - setPriorityLevel(QOS_PRIORITY_RS_FILE_DATA) ; - } - virtual ~RsFileTransferDataItem() { clear() ; } - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - virtual void clear(); - - // Private data part. - // - RsTlvFileData fd; -}; - -class RsFileTransferChunkMapRequestItem: public RsFileTransferItem -{ - public: - RsFileTransferChunkMapRequestItem() :RsFileTransferItem(RS_PKT_SUBTYPE_FT_CHUNK_MAP_REQUEST) - { - setPriorityLevel(QOS_PRIORITY_RS_FILE_MAP_REQUEST) ; - } - virtual ~RsFileTransferChunkMapRequestItem() {} - virtual void clear() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // Private data part. - // - bool is_client ; // is the request for a client, or a server ? - RsFileHash hash ; // hash of the file for which we request the chunk map -}; - -class RsFileTransferChunkMapItem: public RsFileTransferItem -{ - public: - RsFileTransferChunkMapItem() - :RsFileTransferItem(RS_PKT_SUBTYPE_FT_CHUNK_MAP) - { - setPriorityLevel(QOS_PRIORITY_RS_FILE_MAP) ; - } - virtual ~RsFileTransferChunkMapItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear() {} - - // Private data part. - // - bool is_client ; // is the request for a client, or a server ? - RsFileHash hash ; // hash of the file for which we request the chunk map - CompressedChunkMap compressed_map ; // Chunk map of the file. -}; - -class RsFileTransferSingleChunkCrcRequestItem: public RsFileTransferItem -{ - public: - RsFileTransferSingleChunkCrcRequestItem() :RsFileTransferItem(RS_PKT_SUBTYPE_FT_CHUNK_CRC_REQUEST) - { - setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST) ; - } - virtual ~RsFileTransferSingleChunkCrcRequestItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear() {} - - // Private data part. - // - RsFileHash hash ; // hash of the file for which we request the crc - uint32_t chunk_number ; // chunk number -}; - -class RsFileTransferSingleChunkCrcItem: public RsFileTransferItem -{ - public: - RsFileTransferSingleChunkCrcItem() :RsFileTransferItem(RS_PKT_SUBTYPE_FT_CHUNK_CRC) - { - setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC) ; - } - virtual ~RsFileTransferSingleChunkCrcItem() {} - - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear() {} - - // Private data part. - // - RsFileHash hash ; // hash of the file for which we request the chunk map - uint32_t chunk_number ; - Sha1CheckSum check_sum ; // CRC32 map of the file. -}; - -/**************************************************************************/ - -class RsFileTransferSerialiser: public RsServiceSerializer -{ - public: - RsFileTransferSerialiser(): RsServiceSerializer(RS_SERVICE_TYPE_FILE_TRANSFER) {} - - virtual ~RsFileTransferSerialiser() {} - - RsItem *create_item(uint16_t service_type,uint8_t item_type) const ; - -}; - -/**************************************************************************/ - diff --git a/libretroshare/src/rsitems/rsgxschannelitems.cc b/libretroshare/src/rsitems/rsgxschannelitems.cc deleted file mode 100644 index 9ef37d746..000000000 --- a/libretroshare/src/rsitems/rsgxschannelitems.cc +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxschannelitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsgxschannelitems.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" - -#include "serialiser/rstypeserializer.h" - -RsItem *RsGxsChannelSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != RS_SERVICE_GXS_TYPE_CHANNELS) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM: return new RsGxsChannelGroupItem() ; - case RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM: return new RsGxsChannelPostItem(); - default: - return RsGxsCommentSerialiser::create_item(service_id,item_subtype) ; - } -} - -void RsGxsChannelGroupItem::clear() -{ - mDescription.clear(); - mImage.TlvClear(); -} - -bool RsGxsChannelGroupItem::fromChannelGroup(RsGxsChannelGroup &group, bool moveImage) -{ - clear(); - meta = group.mMeta; - mDescription = group.mDescription; - - if (moveImage) - { - mImage.binData.bin_data = group.mImage.mData; - mImage.binData.bin_len = group.mImage.mSize; - group.mImage.shallowClear(); - } - else - { - mImage.binData.setBinData(group.mImage.mData, group.mImage.mSize); - } - return true; -} - - - -bool RsGxsChannelGroupItem::toChannelGroup(RsGxsChannelGroup &group, bool moveImage) -{ - group.mMeta = meta; - group.mDescription = mDescription; - if (moveImage) - { - group.mImage.take((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - // mImage doesn't have a ShallowClear at the moment! - mImage.binData.TlvShallowClear(); - } - else - { - group.mImage.copy((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - } - return true; -} - -void RsGxsChannelGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_DESCR,mDescription,"mDescription") ; - RsTypeSerializer::serial_process(j,ctx,mImage,"mImage") ; -} - -bool RsGxsChannelPostItem::fromChannelPost(RsGxsChannelPost &post, bool moveImage) -{ - clear(); - meta = post.mMeta; - mMsg = post.mMsg; - - if (moveImage) - { - mThumbnail.binData.bin_data = post.mThumbnail.mData; - mThumbnail.binData.bin_len = post.mThumbnail.mSize; - post.mThumbnail.shallowClear(); - } - else - { - mThumbnail.binData.setBinData(post.mThumbnail.mData, post.mThumbnail.mSize); - } - - std::list::iterator fit; - for(fit = post.mFiles.begin(); fit != post.mFiles.end(); ++fit) - { - RsTlvFileItem fi; - fi.name = fit->mName; - fi.filesize = fit->mSize; - fi.hash = fit->mHash; - mAttachment.items.push_back(fi); - } - return true; -} - - - -bool RsGxsChannelPostItem::toChannelPost(RsGxsChannelPost &post, bool moveImage) -{ - post.mMeta = meta; - post.mMsg = mMsg; - if (moveImage) - { - post.mThumbnail.take((uint8_t *) mThumbnail.binData.bin_data, mThumbnail.binData.bin_len); - // mThumbnail doesn't have a ShallowClear at the moment! - mThumbnail.binData.TlvShallowClear(); - } - else - { - post.mThumbnail.copy((uint8_t *) mThumbnail.binData.bin_data, mThumbnail.binData.bin_len); - } - - post.mAttachmentCount = 0; - post.mSize = 0; - std::list::iterator fit; - for(fit = mAttachment.items.begin(); fit != mAttachment.items.end(); ++fit) - { - RsGxsFile fi; - fi.mName = RsDirUtil::getTopDir(fit->name); - fi.mSize = fit->filesize; - fi.mHash = fit->hash; - - post.mFiles.push_back(fi); - post.mAttachmentCount++; - post.mSize += fi.mSize; - } - return true; -} - -void RsGxsChannelPostItem::clear() -{ - mMsg.clear(); - mAttachment.TlvClear(); - mThumbnail.TlvClear(); -} - -void RsGxsChannelPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_MSG,mMsg,"mMsg") ; - RsTypeSerializer::serial_process(j,ctx,mAttachment,"mAttachment") ; - RsTypeSerializer::serial_process(j,ctx,mThumbnail,"mThumbnail") ; -} diff --git a/libretroshare/src/rsitems/rsgxschannelitems.h b/libretroshare/src/rsitems/rsgxschannelitems.h deleted file mode 100644 index fa52c8cfc..000000000 --- a/libretroshare/src/rsitems/rsgxschannelitems.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxschannelitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXS_CHANNEL_ITEMS_H -#define RS_GXS_CHANNEL_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsgxscommentitems.h" -#include "rsitems/rsgxsitems.h" - -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvimage.h" - -#include "retroshare/rsgxschannels.h" - -#include "serialiser/rsserializer.h" - -#include "util/rsdir.h" - -const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; - -class RsGxsChannelGroupItem : public RsGxsGrpItem -{ -public: - - RsGxsChannelGroupItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_CHANNELS, RS_PKT_SUBTYPE_GXSCHANNEL_GROUP_ITEM) {} - virtual ~RsGxsChannelGroupItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // use conversion functions to transform: - bool fromChannelGroup(RsGxsChannelGroup &group, bool moveImage); - bool toChannelGroup(RsGxsChannelGroup &group, bool moveImage); - - std::string mDescription; - RsTlvImage mImage; -}; - -class RsGxsChannelPostItem : public RsGxsMsgItem -{ -public: - - RsGxsChannelPostItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_CHANNELS, RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM) {} - virtual ~RsGxsChannelPostItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // Slightly unusual structure. - // use conversion functions to transform: - bool fromChannelPost(RsGxsChannelPost &post, bool moveImage); - bool toChannelPost(RsGxsChannelPost &post, bool moveImage); - - std::string mMsg; - RsTlvFileSet mAttachment; - RsTlvImage mThumbnail; -}; - - -class RsGxsChannelSerialiser : public RsGxsCommentSerialiser -{ -public: - - RsGxsChannelSerialiser() :RsGxsCommentSerialiser(RS_SERVICE_GXS_TYPE_CHANNELS) {} - virtual ~RsGxsChannelSerialiser() {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -}; - -#endif /* RS_GXS_CHANNEL_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsgxscircleitems.cc b/libretroshare/src/rsitems/rsgxscircleitems.cc deleted file mode 100644 index f93068b5b..000000000 --- a/libretroshare/src/rsitems/rsgxscircleitems.cc +++ /dev/null @@ -1,125 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxscircleitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsgxscircleitems.h" - -#include "serialiser/rstypeserializer.h" - -//#define CIRCLE_DEBUG 1 - -RsItem *RsGxsCircleSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_GXS_TYPE_GXSCIRCLE) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: return new RsGxsCircleGroupItem(); -#ifdef TO_REMOVE - case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: return new RsGxsCircleMsgItem(); -#endif - case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM: return new RsGxsCircleSubscriptionRequestItem(); - default: - return NULL ; - } -} - -void RsGxsCircleSubscriptionRequestItem::clear() -{ - time_stamp = 0 ; - time_out = 0 ; - subscription_type = RsGxsCircleSubscriptionType::UNKNOWN; -} - -#ifdef TO_REMOVE -void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - //RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"mMsg.stuff") ;//Should be this but not retrocompatible... - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"msg.stuff") ; -} - -void RsGxsCircleMsgItem::clear() -{ - mMsg.stuff.clear(); -} -#endif - -void RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,time_stamp,"time_stamp") ; - RsTypeSerializer::serial_process(j,ctx,time_out ,"time_out") ; - RsTypeSerializer::serial_process (j,ctx,subscription_type ,"subscription_type") ; -} - -void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,pgpIdSet,"pgpIdSet") ; - RsTypeSerializer::serial_process(j,ctx,gxsIdSet,"gxsIdSet") ; - RsTypeSerializer::serial_process(j,ctx,subCircleSet,"subCircleSet") ; -} - -void RsGxsCircleGroupItem::clear() -{ - pgpIdSet.TlvClear(); - gxsIdSet.TlvClear(); - subCircleSet.TlvClear(); -} - -bool RsGxsCircleGroupItem::convertFrom(const RsGxsCircleGroup &group) -{ - clear(); - - meta = group.mMeta; - - // Enforce the local rules. - if (meta.mCircleType == GXS_CIRCLE_TYPE_LOCAL) - { - pgpIdSet.ids = group.mLocalFriends; - } - else - { - gxsIdSet.ids = group.mInvitedMembers; - } - - subCircleSet.ids = group.mSubCircles; - return true; -} - -bool RsGxsCircleGroupItem::convertTo(RsGxsCircleGroup &group) const -{ - group.mMeta = meta; - - // Enforce the local rules. - if (meta.mCircleType == GXS_CIRCLE_TYPE_LOCAL) - { - group.mLocalFriends = pgpIdSet.ids; - } - else - { - group.mInvitedMembers = gxsIdSet.ids; - } - - group.mSubCircles = subCircleSet.ids; - return true; -} - diff --git a/libretroshare/src/rsitems/rsgxscircleitems.h b/libretroshare/src/rsitems/rsgxscircleitems.h deleted file mode 100644 index fb720e070..000000000 --- a/libretroshare/src/rsitems/rsgxscircleitems.h +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxscircleitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXSCIRCLE_ITEMS_H -#define RS_GXSCIRCLE_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvstring.h" -#include "serialiser/rstlvidset.h" - -#include "rsitems/rsgxsitems.h" -#include "retroshare/rsgxscircles.h" - -const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM = 0x04; - -const uint16_t GXSCIRCLE_PGPIDSET = 0x0001; -const uint16_t GXSCIRCLE_GXSIDSET = 0x0002; -const uint16_t GXSCIRCLE_SUBCIRCLESET = 0x0003; - -// These classes are a mess. Needs proper item serialisation etc. - -class RsGxsCircleGroupItem : public RsGxsGrpItem -{ - -public: - - RsGxsCircleGroupItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_GXSCIRCLE, RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM) {} - virtual ~RsGxsCircleGroupItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - bool convertFrom(const RsGxsCircleGroup &group); - bool convertTo(RsGxsCircleGroup &group) const; - - // DIFFERENT FROM OTHER ONES, as stupid serialisation otherwise. - RsTlvPgpIdSet pgpIdSet; // For Local Groups. - RsTlvGxsIdSet gxsIdSet; // For External Groups. - RsTlvGxsCircleIdSet subCircleSet; -}; - -#ifdef TO_REMOVE -class RsGxsCircleMsgItem : public RsGxsMsgItem -{ -public: - - RsGxsCircleMsgItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_GXSCIRCLE, RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM) {} - virtual ~RsGxsCircleMsgItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGxsCircleMsg mMsg; -}; -#endif - -class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem -{ -public: - - RsGxsCircleSubscriptionRequestItem() : RsGxsMsgItem(RS_SERVICE_GXS_TYPE_GXSCIRCLE, RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM) { } - virtual ~RsGxsCircleSubscriptionRequestItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t time_stamp ; - uint32_t time_out ; - RsGxsCircleSubscriptionType subscription_type ; -}; - -class RsGxsCircleSerialiser : public RsServiceSerializer -{ -public: - - RsGxsCircleSerialiser() - :RsServiceSerializer(RS_SERVICE_GXS_TYPE_GXSCIRCLE) {} - virtual ~RsGxsCircleSerialiser() {} - - virtual RsItem *create_item(uint16_t service, uint8_t item_sub_id) const; -}; - -#endif /* RS_GXSCIRCLE_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsgxscommentitems.cc b/libretroshare/src/rsitems/rsgxscommentitems.cc deleted file mode 100644 index 2386fb069..000000000 --- a/libretroshare/src/rsitems/rsgxscommentitems.cc +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxscommentitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsgxscommentitems.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstypeserializer.h" - -//#define GXSCOMMENT_DEBUG 1 - -RsItem *RsGxsCommentSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != getRsItemService(PacketId())) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM: return new RsGxsCommentItem(getRsItemService(PacketId())) ; - case RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM: return new RsGxsVoteItem(getRsItemService(PacketId())); - default: - return NULL ; - } -} - - -void RsGxsCommentItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,1,mMsg.mComment,"mMsg.mComment") ; -} - -void RsGxsVoteItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mMsg.mVoteType,"mMsg.mVoteType") ; -} - diff --git a/libretroshare/src/rsitems/rsgxscommentitems.h b/libretroshare/src/rsitems/rsgxscommentitems.h deleted file mode 100644 index c35c6c2aa..000000000 --- a/libretroshare/src/rsitems/rsgxscommentitems.h +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxscommentitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXS_COMMENT_ITEMS_H -#define RS_GXS_COMMENT_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" - -#include "rsgxsitems.h" - -#include "retroshare/rsgxscommon.h" - -const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1; -const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2; - -class RsGxsCommentItem : public RsGxsMsgItem -{ -public: - - RsGxsCommentItem(uint16_t service_type): RsGxsMsgItem(service_type, RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM) {} - virtual ~RsGxsCommentItem() {} - void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - RsGxsComment mMsg; -}; - - -class RsGxsVoteItem : public RsGxsMsgItem -{ -public: - - RsGxsVoteItem(uint16_t service_type): RsGxsMsgItem(service_type, RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM) {} - virtual ~RsGxsVoteItem() {} - void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - RsGxsVote mMsg; -}; - -class RsGxsCommentSerialiser : public RsServiceSerializer -{ -public: - - RsGxsCommentSerialiser(uint16_t service_type) :RsServiceSerializer(service_type) {} - virtual ~RsGxsCommentSerialiser() {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -}; - -#endif /* RS_GXS_COMMENT_ITEMS_H */ - diff --git a/libretroshare/src/rsitems/rsgxsforumitems.cc b/libretroshare/src/rsitems/rsgxsforumitems.cc deleted file mode 100644 index 1918fd980..000000000 --- a/libretroshare/src/rsitems/rsgxsforumitems.cc +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsforumitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsgxsforumitems.h" - -#include "serialiser/rstypeserializer.h" - -//#define GXSFORUM_DEBUG 1 - -RsItem *RsGxsForumSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != RS_SERVICE_GXS_TYPE_FORUMS) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM: return new RsGxsForumGroupItem(); - case RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM: return new RsGxsForumMsgItem(); - default: - return NULL ; - } -} -void RsGxsForumGroupItem::clear() -{ - mGroup.mDescription.clear(); -} - -void RsGxsForumGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,mGroup.mDescription,"mGroup.Description"); - - // This is for backward compatibility: normally all members are serialized, but in the previous version, these members are missing. - - if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) - return ; - - RsTypeSerializer::serial_process(j,ctx,mGroup.mAdminList ,"admin_list" ) ; - RsTypeSerializer::serial_process(j,ctx,mGroup.mPinnedPosts,"pinned_posts") ; -} - -void RsGxsForumMsgItem::clear() -{ - mMsg.mMsg.clear(); -} - -void RsGxsForumMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.mMsg,"mGroup.Description"); -} - - - diff --git a/libretroshare/src/rsitems/rsgxsforumitems.h b/libretroshare/src/rsitems/rsgxsforumitems.h deleted file mode 100644 index 30c6c4e08..000000000 --- a/libretroshare/src/rsitems/rsgxsforumitems.h +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsforumitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXS_FORUM_ITEMS_H -#define RS_GXS_FORUM_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsgxsitems.h" - -#include "serialiser/rsserializer.h" - -#include "retroshare/rsgxsforums.h" - -const uint8_t RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM = 0x03; - -class RsGxsForumGroupItem : public RsGxsGrpItem -{ - -public: - - RsGxsForumGroupItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_FORUMS, RS_PKT_SUBTYPE_GXSFORUM_GROUP_ITEM) {} - virtual ~RsGxsForumGroupItem() {} - - void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGxsForumGroup mGroup; -}; - -class RsGxsForumMsgItem : public RsGxsMsgItem -{ -public: - - RsGxsForumMsgItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_FORUMS, RS_PKT_SUBTYPE_GXSFORUM_MESSAGE_ITEM) {} - virtual ~RsGxsForumMsgItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGxsForumMsg mMsg; -}; - -class RsGxsForumSerialiser : public RsServiceSerializer -{ -public: - RsGxsForumSerialiser() :RsServiceSerializer(RS_SERVICE_GXS_TYPE_FORUMS) {} - virtual ~RsGxsForumSerialiser() {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -}; - -#endif /* RS_GXS_FORUM_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsgxsiditems.cc b/libretroshare/src/rsitems/rsgxsiditems.cc deleted file mode 100644 index 0c37c110e..000000000 --- a/libretroshare/src/rsitems/rsgxsiditems.cc +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsiditems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsgxsiditems.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvstring.h" -#include "util/rsstring.h" - -#include "serialiser/rstypeserializer.h" - -// #define GXSID_DEBUG 1 - -RsItem *RsGxsIdSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != RS_SERVICE_GXS_TYPE_GXSID) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXSID_GROUP_ITEM : return new RsGxsIdGroupItem (); - case RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM: return new RsGxsIdLocalInfoItem() ; - default: - return NULL ; - } -} -void RsGxsIdLocalInfoItem::clear() -{ - mTimeStamps.clear() ; -} -void RsGxsIdGroupItem::clear() -{ - mPgpIdHash.clear(); - mPgpIdSign.clear(); - - mRecognTags.clear(); - mImage.TlvClear(); -} -void RsGxsIdLocalInfoItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mTimeStamps,"mTimeStamps") ; - RsTypeSerializer::serial_process(j,ctx,mContacts,"mContacts") ; -} - -void RsGxsIdGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mPgpIdHash,"mPgpIdHash") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_SIGN,mPgpIdSign,"mPgpIdSign") ; - - RsTlvStringSetRef rset(TLV_TYPE_RECOGNSET,mRecognTags) ; - - RsTypeSerializer::serial_process(j,ctx,rset,"mRecognTags") ; - - // image is optional - - if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) - return ; - - RsTypeSerializer::serial_process(j,ctx,mImage,"mImage") ; -} - -bool RsGxsIdGroupItem::fromGxsIdGroup(RsGxsIdGroup &group, bool moveImage) -{ - clear(); - meta = group.mMeta; - mPgpIdHash = group.mPgpIdHash; - mPgpIdSign = group.mPgpIdSign; - mRecognTags = group.mRecognTags; - - if (moveImage) - { - mImage.binData.bin_data = group.mImage.mData; - mImage.binData.bin_len = group.mImage.mSize; - group.mImage.shallowClear(); - } - else - { - mImage.binData.setBinData(group.mImage.mData, group.mImage.mSize); - } - return true ; -} -bool RsGxsIdGroupItem::toGxsIdGroup(RsGxsIdGroup &group, bool moveImage) -{ - group.mMeta = meta; - group.mPgpIdHash = mPgpIdHash; - group.mPgpIdSign = mPgpIdSign; - group.mRecognTags = mRecognTags; - - if (moveImage) - { - group.mImage.take((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - // mImage doesn't have a ShallowClear at the moment! - mImage.binData.TlvShallowClear(); - } - else - { - group.mImage.copy((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - } - return true ; -} - diff --git a/libretroshare/src/rsitems/rsgxsiditems.h b/libretroshare/src/rsitems/rsgxsiditems.h deleted file mode 100644 index 440247403..000000000 --- a/libretroshare/src/rsitems/rsgxsiditems.h +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsiditems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXS_IDENTITY_ITEMS_H -#define RS_GXS_IDENTITY_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserial.h" - -#include "rsgxsitems.h" -#include "retroshare/rsidentity.h" - -//const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM_deprecated = 0x02; - -const uint8_t RS_PKT_SUBTYPE_GXSID_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXSID_OPINION_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_GXSID_COMMENT_ITEM = 0x04; -const uint8_t RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM = 0x05; - -class RsGxsIdItem: public RsGxsGrpItem -{ - public: - RsGxsIdItem(uint8_t item_subtype) : RsGxsGrpItem(RS_SERVICE_GXS_TYPE_GXSID,item_subtype) {} -}; - -class RsGxsIdGroupItem : public RsGxsIdItem -{ -public: - - RsGxsIdGroupItem(): RsGxsIdItem(RS_PKT_SUBTYPE_GXSID_GROUP_ITEM) {} - virtual ~RsGxsIdGroupItem() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - virtual void clear(); - - bool fromGxsIdGroup(RsGxsIdGroup &group, bool moveImage); - bool toGxsIdGroup(RsGxsIdGroup &group, bool moveImage); - - Sha1CheckSum mPgpIdHash; - // Need a signature as proof - otherwise anyone could add others Hashes. - // This is a string, as the length is variable. - std::string mPgpIdSign; - - // Recognition Strings. MAX# defined above. - std::list mRecognTags; - - // Avatar - RsTlvImage mImage ; -}; - -struct RsGxsIdLocalInfoItem : public RsGxsIdItem -{ - RsGxsIdLocalInfoItem(): RsGxsIdItem(RS_PKT_SUBTYPE_GXSID_LOCAL_INFO_ITEM) {} - virtual ~RsGxsIdLocalInfoItem() {} - - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - std::map mTimeStamps ; - std::set mContacts ; -}; - -class RsGxsIdSerialiser : public RsServiceSerializer -{ -public: - RsGxsIdSerialiser() :RsServiceSerializer(RS_SERVICE_GXS_TYPE_GXSID) {} - virtual ~RsGxsIdSerialiser() {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -}; - -#endif /* RS_GXS_IDENTITY_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsgxsitems.cc b/libretroshare/src/rsitems/rsgxsitems.cc deleted file mode 100644 index 22c379f9e..000000000 --- a/libretroshare/src/rsitems/rsgxsitems.cc +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstypeserializer.h" -#include "serialiser/rsbaseserial.h" -#include "rsgxsitems.h" -#include "gxs/rsgxsdata.h" -#include - - void RsMsgMetaData::operator =(const RsGxsMsgMetaData& rGxsMeta) - { - this->mAuthorId = rGxsMeta.mAuthorId; - this->mChildTs = rGxsMeta.mChildTs; - this->mGroupId = rGxsMeta.mGroupId; - this->mMsgFlags = rGxsMeta.mMsgFlags; - this->mMsgId = rGxsMeta.mMsgId; - this->mMsgName = rGxsMeta.mMsgName; - this->mMsgStatus = rGxsMeta.mMsgStatus; - this->mOrigMsgId = rGxsMeta.mOrigMsgId; - this->mParentId = rGxsMeta.mParentId; - this->mPublishTs = rGxsMeta.mPublishTs; - this->mThreadId = rGxsMeta.mThreadId; - this->mServiceString = rGxsMeta.mServiceString; - } - - - void RsGroupMetaData::operator =(const RsGxsGrpMetaData& rGxsMeta) - { - this->mAuthorId = rGxsMeta.mAuthorId; - this->mGroupFlags = rGxsMeta.mGroupFlags; - this->mGroupId = rGxsMeta.mGroupId; - this->mGroupStatus = rGxsMeta.mGroupStatus; - this->mLastPost = rGxsMeta.mLastPost; - this->mVisibleMsgCount = rGxsMeta.mVisibleMsgCount; - this->mPop = rGxsMeta.mPop; - this->mPublishTs = rGxsMeta.mPublishTs; - this->mSubscribeFlags = rGxsMeta.mSubscribeFlags; - this->mGroupName = rGxsMeta.mGroupName; - this->mServiceString = rGxsMeta.mServiceString; - this->mSignFlags = rGxsMeta.mSignFlags; - this->mCircleId = rGxsMeta.mCircleId; - this->mCircleType = rGxsMeta.mCircleType; - this->mInternalCircle = rGxsMeta.mInternalCircle; - this->mOriginator = rGxsMeta.mOriginator; - this->mAuthenFlags = rGxsMeta.mAuthenFlags; - this->mParentGrpId = rGxsMeta.mParentGrpId; - } - -template<> uint32_t RsTypeSerializer::serial_size(const TurtleGxsInfo& i) -{ - uint32_t s = 0 ; - - s += 2 ; // service_id - s += i.group_id.SIZE_IN_BYTES ; - s += GetTlvStringSize(i.name) ; - - return s; -} - -template<> bool RsTypeSerializer::deserialize(const uint8_t data[],uint32_t size,uint32_t& offset,TurtleGxsInfo& i) -{ - uint32_t saved_offset = offset ; - bool ok = true ; - - ok &= getRawUInt16(data, size, &offset, &i.service_id); // service_id - ok &= i.group_id.deserialise(data, size, offset); // group_id - ok &= GetTlvString(data, size, &offset, TLV_TYPE_STR_NAME, i.name); // group name - - if(!ok) - offset = saved_offset ; - - return ok; -} - -template<> bool RsTypeSerializer::serialize(uint8_t data[],uint32_t size,uint32_t& offset,const TurtleGxsInfo& i) -{ - uint32_t saved_offset = offset ; - bool ok = true ; - - ok &= setRawUInt16(data, size, &offset, i.service_id); // service_id - ok &= i.group_id.serialise(data, size, offset); // group_id - ok &= SetTlvString(data, size, &offset, TLV_TYPE_STR_NAME, i.name); // group name - - if(!ok) - offset = saved_offset ; - - return ok; -} - -template<> void RsTypeSerializer::print_data(const std::string& n, const TurtleGxsInfo& i) -{ - std::cerr << " [GXS Info ] " << n << " group_id=" << i.group_id << " service=" << std::hex << i.service_id << std::dec << ", name=" << i.name << std::endl; -} - -void RsTurtleGxsSearchResultGroupSummaryItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,result,"result") ; -} -void RsTurtleGxsSearchResultGroupDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::TlvMemBlock_proxy prox(encrypted_nxs_group_data,encrypted_nxs_group_data_len) ; - RsTypeSerializer::serial_process(j,ctx,prox,"encrypted_nxs_data") ; -} - -RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(TurtleGxsInfo) -RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(TurtleGxsInfo) - diff --git a/libretroshare/src/rsitems/rsgxsitems.h b/libretroshare/src/rsitems/rsgxsitems.h deleted file mode 100644 index 9b47d5d6d..000000000 --- a/libretroshare/src/rsitems/rsgxsitems.h +++ /dev/null @@ -1,134 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * Copyright 2012-2012 by Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSITEMS_H -#define RSGXSITEMS_H - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "util/rstime.h" -#include "retroshare/rsgxsifacetypes.h" - -class RsGxsGrpItem : public RsItem -{ - -public: - - RsGxsGrpItem(uint16_t service, uint8_t subtype) - : RsItem(RS_PKT_VERSION_SERVICE, service, subtype) { return; } - virtual ~RsGxsGrpItem(){} - - RsGroupMetaData meta; -}; - -class RsGxsMsgItem : public RsItem -{ - -public: - RsGxsMsgItem(uint16_t service, uint8_t subtype) - : RsItem(RS_PKT_VERSION_SERVICE, service, subtype) { return; } - virtual ~RsGxsMsgItem(){} - - RsMsgMetaData meta; -}; - -// We should make these items templates or generic classes so that each GXS service will handle them on its own. - -static const uint8_t RS_PKT_SUBTYPE_GXS_SUBSTRING_SEARCH_ITEM = 0x20 ; -static const uint8_t RS_PKT_SUBTYPE_GXS_GROUP_SEARCH_ITEM = 0x21 ; -static const uint8_t RS_PKT_SUBTYPE_GXS_GROUP_SUMMARY_ITEM = 0x22 ; -static const uint8_t RS_PKT_SUBTYPE_GXS_GROUP_DATA_ITEM = 0x23 ; - -class RsGxsTurtleSubStringSearchItem: public RsItem -{ - public: - RsGxsTurtleSubStringSearchItem(uint16_t service): RsItem(RS_PKT_VERSION_SERVICE,service,RS_PKT_SUBTYPE_GXS_SUBSTRING_SEARCH_ITEM) {} - virtual ~RsGxsTurtleSubStringSearchItem() {} - - std::string match_string ; // string to match - - std::string GetKeywords() { return match_string; } - void clear() { match_string.clear() ; } - - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsGxsTurtleGroupSearchItem: public RsItem -{ - public: - RsGxsTurtleGroupSearchItem(uint16_t service): RsItem(RS_PKT_VERSION_SERVICE,service,RS_PKT_SUBTYPE_GXS_GROUP_SEARCH_ITEM) {} - virtual ~RsGxsTurtleGroupSearchItem() {} - - uint16_t service_id ; // searvice to search - Sha1CheckSum hashed_group_id ; // the group ID is hashed in order to keep it private. - - std::string GetKeywords() { return std::string("Group request for [hashed] ")+hashed_group_id.toStdString() ; } - void clear() { hashed_group_id.clear() ; } - - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -struct TurtleGxsInfo -{ - uint16_t service_id ; - RsGxsGroupId group_id ; - RsGxsId author; - std::string name ; - std::string description ; - rstime_t last_post ; - uint32_t number_of_posts ; -}; - -class RsTurtleGxsSearchResultGroupSummaryItem: public RsItem -{ - public: - RsTurtleGxsSearchResultGroupSummaryItem(uint16_t service) : RsItem(RS_PKT_VERSION_SERVICE,service,RS_PKT_SUBTYPE_GXS_GROUP_SUMMARY_ITEM){} - virtual ~RsTurtleGxsSearchResultGroupSummaryItem() {} - - std::list result ; - - void clear() { result.clear() ; } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleGxsSearchResultGroupDataItem: public RsItem -{ - public: - RsTurtleGxsSearchResultGroupDataItem(uint16_t service) : RsItem(RS_PKT_VERSION_SERVICE,service,RS_PKT_SUBTYPE_GXS_GROUP_DATA_ITEM){} - virtual ~RsTurtleGxsSearchResultGroupDataItem() {} - - unsigned char *encrypted_nxs_group_data; // data is encrypted with group ID. Only the requester, or anyone who already know the group id can decrypt. - uint32_t encrypted_nxs_group_data_len ; - - void clear() { free(encrypted_nxs_group_data); encrypted_nxs_group_data=NULL; encrypted_nxs_group_data_len=0; } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - - - - - -#endif // RSGXSITEMS_H diff --git a/libretroshare/src/rsitems/rsgxsrecognitems.cc b/libretroshare/src/rsitems/rsgxsrecognitems.cc deleted file mode 100644 index 4113a051c..000000000 --- a/libretroshare/src/rsitems/rsgxsrecognitems.cc +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsrecogitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/rsgxsrecognitems.h" -#include "serialiser/rstypeserializer.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ - -RsItem *RsGxsRecognSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_TYPE_GXS_RECOGN) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_RECOGN_REQ: return new RsGxsRecognReqItem(); - case RS_PKT_SUBTYPE_RECOGN_SIGNER: return new RsGxsRecognSignerItem(); - case RS_PKT_SUBTYPE_RECOGN_TAG: return new RsGxsRecognTagItem(); - default: - return NULL ; - } -} - -void RsGxsRecognReqItem::clear() -{ - issued_at = 0; - period = 0; - tag_class = 0; - tag_type = 0; - - identity.clear(); - nickname.clear(); - comment.clear(); - - sign.TlvClear(); - -} -void RsGxsRecognReqItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,issued_at ,"issued_at") ; - RsTypeSerializer::serial_process (j,ctx,period ,"period") ; - RsTypeSerializer::serial_process (j,ctx,tag_class ,"tag_class") ; - RsTypeSerializer::serial_process (j,ctx,tag_type ,"tag_type") ; - RsTypeSerializer::serial_process (j,ctx,identity ,"identity") ; - RsTypeSerializer::serial_process (j,ctx,1,nickname ,"nickname") ; - RsTypeSerializer::serial_process (j,ctx,1,comment ,"comment") ; - RsTypeSerializer::serial_process(j,ctx,sign ,"sign") ; -} - -void RsGxsRecognTagItem::clear() -{ - valid_from = 0; - valid_to = 0; - - tag_class = 0; - tag_type = 0; - - identity.clear(); - nickname.clear(); - - sign.TlvClear(); -} - -void RsGxsRecognTagItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,valid_from ,"valid_from") ; - RsTypeSerializer::serial_process (j,ctx,valid_to ,"valid_to") ; - RsTypeSerializer::serial_process (j,ctx,tag_class ,"tag_class") ; - RsTypeSerializer::serial_process (j,ctx,tag_type ,"tag_type") ; - RsTypeSerializer::serial_process (j,ctx,identity ,"identity"); - RsTypeSerializer::serial_process (j,ctx,1,nickname ,"nickname") ; - RsTypeSerializer::serial_process(j,ctx,sign ,"sign") ; -} - -void RsGxsRecognSignerItem::clear() -{ - signing_classes.TlvClear(); - key.TlvClear(); - sign.TlvClear(); -} - -void RsGxsRecognSignerItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,signing_classes ,"signing_classes") ; - RsTypeSerializer::serial_process(j,ctx,key ,"key"); - RsTypeSerializer::serial_process(j,ctx,sign ,"sign") ; -} - - - diff --git a/libretroshare/src/rsitems/rsgxsrecognitems.h b/libretroshare/src/rsitems/rsgxsrecognitems.h deleted file mode 100644 index 3e049f0c2..000000000 --- a/libretroshare/src/rsitems/rsgxsrecognitems.h +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsrecogitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXS_RECOG_ITEMS_H -#define RS_GXS_RECOG_ITEMS_H - -#include - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rstlvkeys.h" -#include "serialiser/rstlvidset.h" - -#if 0 -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvtypes.h" - -#endif - -#include "retroshare/rsgxsifacetypes.h" - -/**************************************************************************/ - -#define RS_PKT_SUBTYPE_RECOGN_REQ 0x01 -#define RS_PKT_SUBTYPE_RECOGN_TAG 0x02 -#define RS_PKT_SUBTYPE_RECOGN_SIGNER 0x03 - - -class RsGxsRecognReqItem: public RsItem -{ -public: - RsGxsRecognReqItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN, RS_PKT_SUBTYPE_RECOGN_REQ) - , issued_at(0), period(0), tag_class(0), tag_type(0) - { - setPriorityLevel(QOS_PRIORITY_DEFAULT); - return; - } - virtual ~RsGxsRecognReqItem(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t issued_at; - uint32_t period; - uint16_t tag_class; - uint16_t tag_type; - - RsGxsId identity; - std::string nickname; - std::string comment; - - RsTlvKeySignature sign; -}; - - -class RsGxsRecognTagItem: public RsItem -{ - public: - RsGxsRecognTagItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN, RS_PKT_SUBTYPE_RECOGN_TAG) - , valid_from(0), valid_to(0), tag_class(0), tag_type(0) - { - setPriorityLevel(QOS_PRIORITY_DEFAULT); - return; - } - virtual ~RsGxsRecognTagItem(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t valid_from; - uint32_t valid_to; - uint16_t tag_class; - uint16_t tag_type; - - RsGxsId identity; - std::string nickname; - - RsTlvKeySignature sign; -}; - - -class RsGxsRecognSignerItem: public RsItem -{ -public: - RsGxsRecognSignerItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN, RS_PKT_SUBTYPE_RECOGN_SIGNER) - { - setPriorityLevel(QOS_PRIORITY_DEFAULT); - return; - } - virtual ~RsGxsRecognSignerItem(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsTlvServiceIdSet signing_classes; - RsTlvPublicRSAKey key; // has from->to, and flags. - RsTlvKeySignature sign; -}; - - -class RsGxsRecognSerialiser: public RsServiceSerializer -{ - public: - RsGxsRecognSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_GXS_RECOGN) {} - virtual ~RsGxsRecognSerialiser() {} - - virtual RsItem *create_item(uint16_t service, uint8_t item_sub_id) const; -}; - -/**************************************************************************/ - -#endif /* RS_GXS_RECOGN_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rsgxsreputationitems.cc b/libretroshare/src/rsitems/rsgxsreputationitems.cc deleted file mode 100644 index 97d33e3d1..000000000 --- a/libretroshare/src/rsitems/rsgxsreputationitems.cc +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsreputationitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include "util/rstime.h" -#include "serialiser/rsbaseserial.h" -#include "rsitems/rsgxsreputationitems.h" - -#include "serialiser/rstypeserializer.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ - -void RsGxsReputationSetItem::clear() -{ - mOpinions.clear() ; -} - -void RsGxsReputationUpdateItem::clear() -{ - mOpinions.clear() ; -} - -void RsGxsReputationBannedNodeSetItem::clear() -{ - mKnownIdentities.TlvClear(); -} - -void RsGxsReputationConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,mPeerId,"mPeerId") ; - RsTypeSerializer::serial_process(j,ctx,mLatestUpdate,"mLatestUpdate") ; - RsTypeSerializer::serial_process(j,ctx,mLastQuery,"mLastQuery") ; -} - -void RsGxsReputationBannedNodeSetItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,mPgpId,"mPgpId") ; - RsTypeSerializer::serial_process (j,ctx,mLastActivityTS,"mLastActivityTS") ; - RsTypeSerializer::serial_process(j,ctx,mKnownIdentities,"mKnownIdentities") ; -} - -void RsGxsReputationSetItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,mGxsId,"mGxsId") ; - RsTypeSerializer::serial_process(j,ctx,mOwnOpinion,"mOwnOpinion") ; - RsTypeSerializer::serial_process(j,ctx,mOwnOpinionTS,"mOwnOpinionTS") ; - RsTypeSerializer::serial_process(j,ctx,mIdentityFlags,"mIdentityFlags") ; - RsTypeSerializer::serial_process(j,ctx,mLastUsedTS,"mLastUsedTS") ; - RsTypeSerializer::serial_process (j,ctx,mOwnerNodeId,"mOwnerNodeId") ; - RsTypeSerializer::serial_process (j,ctx,mOpinions,"mOpinions") ; -} - -void RsGxsReputationUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mLatestUpdate,"mLatestUpdate") ; - RsTypeSerializer::serial_process (j,ctx,mOpinions,"mOpinions") ; -} -void RsGxsReputationRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mLastUpdate,"mLastUpdate") ; -} - -/*************************************************************************/ - -RsItem *RsGxsReputationSerialiser::create_item(uint16_t service,uint8_t subtype) const -{ - if(service != RS_SERVICE_GXS_TYPE_REPUTATION) - return NULL ; - - switch(subtype) - { - case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return new RsGxsReputationSetItem() ; - case RS_PKT_SUBTYPE_GXS_REPUTATION_BANNED_NODE_SET_ITEM : return new RsGxsReputationBannedNodeSetItem(); - case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return new RsGxsReputationUpdateItem(); - case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM : return new RsGxsReputationRequestItem() ; - case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM : return new RsGxsReputationConfigItem () ; - default: - std::cerr << "(EE) RsGxsReputationSerialiser::create_item(): unhandled item type " << subtype << std::endl; - return NULL ; - } -} - diff --git a/libretroshare/src/rsitems/rsgxsreputationitems.h b/libretroshare/src/rsitems/rsgxsreputationitems.h deleted file mode 100644 index 8028e63f1..000000000 --- a/libretroshare/src/rsitems/rsgxsreputationitems.h +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsreputationitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014-2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_GXSREPUTATION_ITEMS_H -#define RS_GXSREPUTATION_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rsserial.h" -#include "serialiser/rstlvidset.h" -#include "retroshare/rsgxsifacetypes.h" -#include "retroshare/rsreputations.h" - -#include "serialiser/rsserializer.h" - -#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated2 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_deprecated1 0x05 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated3 0x06 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_BANNED_NODE_SET_ITEM 0x07 -#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x08 - -/**************************************************************************/ -class RsReputationItem: public RsItem -{ - public: - RsReputationItem(uint8_t reputation_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_REPUTATION,reputation_subtype) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - } - - virtual ~RsReputationItem() {} - virtual void clear() = 0 ; -}; - -class RsGxsReputationConfigItem: public RsReputationItem -{ -public: - RsGxsReputationConfigItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM) {} - - virtual ~RsGxsReputationConfigItem() {} - virtual void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) ; - - RsPeerId mPeerId; - uint32_t mLatestUpdate; // timestamp they returned. - uint32_t mLastQuery; // when we sent out. -}; - -#ifdef TO_REMOVE -// This class should disappear. Deprecated since Jan 7, 2017. The class definition is actually not needed, -// that is why it's commented out. Kept here in order to explains how the deserialisation works. -// -class RsGxsReputationSetItem_deprecated3: public RsReputationItem -{ -public: - RsGxsReputationSetItem_deprecated3() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM_deprecated3) {} - - virtual ~RsGxsReputationSetItem_deprecated3() {} - virtual void clear() {} - - virtual void serial_process(SerializeJob /* j */,SerializeContext& /* ctx */) ; - - RsGxsId mGxsId; - uint32_t mOwnOpinion; - uint32_t mOwnOpinionTS; - uint32_t mIdentityFlags ; - RsPgpId mOwnerNodeId; - std::map mOpinions; // RsPeerId -> Opinion. -}; -#endif - -class RsGxsReputationSetItem: public RsReputationItem -{ -public: - RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM) - { - mOwnOpinion = static_cast(RsOpinion::NEUTRAL); - mOwnOpinionTS = 0; - mIdentityFlags = 0; - mLastUsedTS = 0; - } - - virtual ~RsGxsReputationSetItem() {} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) ; - - RsGxsId mGxsId; - uint32_t mOwnOpinion; - uint32_t mOwnOpinionTS; - uint32_t mIdentityFlags; - uint32_t mLastUsedTS; - RsPgpId mOwnerNodeId; - std::map mOpinions; // RsPeerId -> Opinion. -}; -class RsGxsReputationBannedNodeSetItem: public RsReputationItem -{ -public: - RsGxsReputationBannedNodeSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_BANNED_NODE_SET_ITEM) {} - - virtual ~RsGxsReputationBannedNodeSetItem() {} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) ; - - RsPgpId mPgpId ; - uint32_t mLastActivityTS ; - RsTlvGxsIdSet mKnownIdentities ; -}; - -class RsGxsReputationUpdateItem: public RsReputationItem -{ -public: - RsGxsReputationUpdateItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM) {} - - virtual ~RsGxsReputationUpdateItem() {} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) ; - - uint32_t mLatestUpdate; - std::map mOpinions; // GxsId -> Opinion. -}; - -class RsGxsReputationRequestItem: public RsReputationItem -{ -public: - RsGxsReputationRequestItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM) {} - - virtual ~RsGxsReputationRequestItem() {} - virtual void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) ; - - uint32_t mLastUpdate; -}; - - -class RsGxsReputationSerialiser: public RsServiceSerializer -{ -public: - RsGxsReputationSerialiser() :RsServiceSerializer(RS_SERVICE_GXS_TYPE_REPUTATION){} - virtual ~RsGxsReputationSerialiser(){} - - virtual RsItem *create_item(uint16_t service,uint8_t item_type) const; -}; - -/**************************************************************************/ - -#endif /* RS_GXSREPUTATION_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rsgxsupdateitems.cc b/libretroshare/src/rsitems/rsgxsupdateitems.cc deleted file mode 100644 index b129dc460..000000000 --- a/libretroshare/src/rsitems/rsgxsupdateitems.cc +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsupdateitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstypeserializer.h" -#include "serialiser/rsbaseserial.h" - -#include "rsgxsupdateitems.h" - -/**********************************************************************************************/ -/* SERIALIZER */ -/**********************************************************************************************/ - -RsItem* RsGxsUpdateSerialiser::create_item(uint16_t service,uint8_t item_subtype) const -{ - if(service != SERVICE_TYPE) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_GXS_MSG_UPDATE: return new RsGxsMsgUpdateItem(SERVICE_TYPE); - case RS_PKT_SUBTYPE_GXS_GRP_UPDATE: return new RsGxsGrpUpdateItem(SERVICE_TYPE); - case RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE: return new RsGxsServerGrpUpdateItem(SERVICE_TYPE); - case RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE: return new RsGxsServerMsgUpdateItem(SERVICE_TYPE); - case RS_PKT_SUBTYPE_GXS_GRP_CONFIG: return new RsGxsGrpConfigItem(SERVICE_TYPE); - default: - return NULL ; - } -} - -/**********************************************************************************************/ -/* CLEAR */ -/**********************************************************************************************/ - -void RsGxsGrpUpdateItem::clear() -{ - grpUpdateTS = 0; - peerID.clear(); -} - -void RsGxsMsgUpdateItem::clear() -{ - msgUpdateInfos.clear(); - peerID.clear(); -} - -void RsGxsServerMsgUpdateItem::clear() -{ - msgUpdateTS = 0; - grpId.clear(); -} - -void RsGxsServerGrpUpdateItem::clear() -{ - grpUpdateTS = 0; -} - -/**********************************************************************************************/ -/* SERIALISER */ -/**********************************************************************************************/ - -void RsGxsGrpUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,peerID,"peerID"); - RsTypeSerializer::serial_process(j,ctx,grpUpdateTS,"grpUpdateTS"); -} - -void RsGxsServerGrpUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,grpUpdateTS,"grpUpdateTS"); -} - -void RsGxsMsgUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,peerID,"peerID"); - RsTypeSerializer::serial_process(j,ctx,msgUpdateInfos,"msgUpdateInfos"); -} - -template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, const RsGxsMsgUpdateItem::MsgUpdateInfo& info) -{ - bool ok = true ; - - ok = ok && setRawUInt32(data,size,&offset,info.time_stamp); - ok = ok && setRawUInt32(data,size,&offset,info.message_count); - - return ok; -} -template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, RsGxsMsgUpdateItem::MsgUpdateInfo& info) -{ - bool ok = true ; - - ok = ok && getRawUInt32(data,size,&offset,&info.time_stamp); - ok = ok && getRawUInt32(data,size,&offset,&info.message_count); - - return ok; -} -template<> uint32_t RsTypeSerializer::serial_size(const RsGxsMsgUpdateItem::MsgUpdateInfo& /* info */) { return 8; } - -template<> void RsTypeSerializer::print_data(const std::string& name,const RsGxsMsgUpdateItem::MsgUpdateInfo& info) -{ - std::cerr << "[MsgUpdateInfo]: " << name << ": " << info.time_stamp << ", " << info.message_count << std::endl; -} - -void RsGxsServerMsgUpdateItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,grpId,"grpId"); - RsTypeSerializer::serial_process(j,ctx,msgUpdateTS,"msgUpdateTS"); -} -void RsGxsGrpConfigItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,grpId,"grpId") ; - RsTypeSerializer::serial_process(j,ctx,msg_keep_delay,"msg_keep_delay") ; - RsTypeSerializer::serial_process(j,ctx,msg_send_delay,"msg_send_delay") ; - RsTypeSerializer::serial_process(j,ctx,msg_req_delay,"msg_req_delay") ; -} - diff --git a/libretroshare/src/rsitems/rsgxsupdateitems.h b/libretroshare/src/rsitems/rsgxsupdateitems.h deleted file mode 100644 index 03bd21800..000000000 --- a/libretroshare/src/rsitems/rsgxsupdateitems.h +++ /dev/null @@ -1,219 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsgxsupdateitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSGXSUPDATEITEMS_H_ -#define RSGXSUPDATEITEMS_H_ - -#include "gxs/rsgxs.h" -#include "gxs/rsgxsdata.h" -#include "gxs/rsgxsnettunnel.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstypeserializer.h" -#include "serialiser/rsserializable.h" - - -const uint8_t RS_PKT_SUBTYPE_GXS_GRP_UPDATE = 0x01; -const uint8_t RS_PKT_SUBTYPE_GXS_MSG_UPDATE_deprecated = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXS_MSG_UPDATE = 0x03; -const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE = 0x04; -const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE = 0x08; -const uint8_t RS_PKT_SUBTYPE_GXS_GRP_CONFIG = 0x09; -const uint8_t RS_PKT_SUBTYPE_GXS_RANDOM_BIAS = 0x0a; - -class RsGxsNetServiceItem: public RsItem -{ -public: - RsGxsNetServiceItem(uint16_t serv_type,uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE, serv_type, subtype) {} - - virtual ~RsGxsNetServiceItem() {} - virtual void clear() = 0 ; -}; - -class RsGxsGrpConfig -{ -public: - RsGxsGrpConfig() - { - msg_keep_delay = RS_GXS_DEFAULT_MSG_STORE_PERIOD ; - msg_send_delay = RS_GXS_DEFAULT_MSG_SEND_PERIOD ; - msg_req_delay = RS_GXS_DEFAULT_MSG_REQ_PERIOD ; - - max_visible_count = 0 ; - statistics_update_TS = 0 ; - last_group_modification_TS = 0 ; - } - - uint32_t msg_keep_delay ; // delay after which we discard the posts - uint32_t msg_send_delay ; // delay after which we dont send the posts anymore - uint32_t msg_req_delay ; // delay after which we dont get the posts from friends - - RsTlvPeerIdSet suppliers; // list of friends who feed this group - uint32_t max_visible_count ; // max visible count reported by contributing friends - rstime_t statistics_update_TS ; // last time the max visible count was updated. - rstime_t last_group_modification_TS ; // last time the group was modified, either in meta data or in the list of messages posted in it. -}; - -class RsGxsGrpConfigItem : public RsGxsNetServiceItem, public RsGxsGrpConfig -{ -public: - explicit RsGxsGrpConfigItem(uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_GRP_CONFIG) {} - RsGxsGrpConfigItem(const RsGxsGrpConfig& m,uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_GRP_CONFIG),RsGxsGrpConfig(m) {} - virtual ~RsGxsGrpConfigItem() {} - - virtual void clear() {} - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGxsGroupId grpId ; -}; - -class RsGxsGrpUpdate -{ -public: - RsGxsGrpUpdate() { grpUpdateTS=0;} - - uint32_t grpUpdateTS; -}; - -class RsGxsGrpUpdateItem : public RsGxsNetServiceItem, public RsGxsGrpUpdate -{ -public: - explicit RsGxsGrpUpdateItem(uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_GRP_UPDATE) {clear();} - RsGxsGrpUpdateItem(const RsGxsGrpUpdate& u,uint16_t serv_type) : RsGxsNetServiceItem(serv_type, RS_PKT_SUBTYPE_GXS_GRP_UPDATE), RsGxsGrpUpdate(u) {} - - virtual ~RsGxsGrpUpdateItem() {} - - virtual void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsPeerId peerID; -}; - -struct RsPeerUpdateTsRecord -{ - RsPeerUpdateTsRecord() : mLastTsReceived(0), mTs(0) {} - - rstime_t mLastTsReceived; // last TS that was sent for this group by this peer ID. - rstime_t mTs; // time at which this TS was sent. -}; - -class RsGxsServerGrpUpdate -{ -public: - RsGxsServerGrpUpdate() { grpUpdateTS = 0 ; } - - uint32_t grpUpdateTS; - - std::map grpUpdateTsRecords; -}; - -class RsGxsServerGrpUpdateItem : public RsGxsNetServiceItem, public RsGxsServerGrpUpdate -{ -public: - explicit RsGxsServerGrpUpdateItem(uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE) { clear();} - RsGxsServerGrpUpdateItem(const RsGxsServerGrpUpdate& u,uint16_t serv_type) : RsGxsNetServiceItem(serv_type, RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE), RsGxsServerGrpUpdate(u) {} - - virtual ~RsGxsServerGrpUpdateItem() {} - - virtual void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsGxsMsgUpdate -{ -public: - struct MsgUpdateInfo : RsSerializable - { - MsgUpdateInfo(): time_stamp(0), message_count(0) {} - - uint32_t time_stamp ; - uint32_t message_count ; - - /// @see RsSerializable - void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) - { - RS_SERIAL_PROCESS(time_stamp); - RS_SERIAL_PROCESS(message_count); - } - }; - - std::map msgUpdateInfos; -}; - - -class RsGxsMsgUpdateItem : public RsGxsNetServiceItem, public RsGxsMsgUpdate -{ -public: - explicit RsGxsMsgUpdateItem(uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_MSG_UPDATE) { clear();} - RsGxsMsgUpdateItem(const RsGxsMsgUpdate& m,uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_MSG_UPDATE), RsGxsMsgUpdate(m) {} - - virtual ~RsGxsMsgUpdateItem() {} - - virtual void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsPeerId peerID; -}; - -class RsGxsServerMsgUpdate -{ -public: - RsGxsServerMsgUpdate() { msgUpdateTS = 0 ;} - - uint32_t msgUpdateTS; // local time stamp at which this group last received a new msg - - // Now we also store for each peer the last own TS the peer sent and when it did so. This allows to detect when transactions are stuck because of - // outqueues clogging. If that happens, we receive multiple times the same TS from the friend, in which case we do not send the list of msgs - // again until a significant amount of time has passed. These values are obviously initialized to 0. - - std::map msgUpdateTsRecords; -}; - -class RsGxsServerMsgUpdateItem : public RsGxsNetServiceItem, public RsGxsServerMsgUpdate -{ -public: - explicit RsGxsServerMsgUpdateItem(uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE) { clear();} - RsGxsServerMsgUpdateItem(const RsGxsServerMsgUpdate& m,uint16_t servType) : RsGxsNetServiceItem(servType, RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE),RsGxsServerMsgUpdate(m) {} - virtual ~RsGxsServerMsgUpdateItem() {} - - virtual void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsGxsGroupId grpId; -}; - -class RsGxsUpdateSerialiser : public RsServiceSerializer -{ -public: - - explicit RsGxsUpdateSerialiser(uint16_t servtype) : RsServiceSerializer(servtype), SERVICE_TYPE(servtype) {} - - virtual ~RsGxsUpdateSerialiser() {} - - virtual RsItem* create_item(uint16_t service,uint8_t item_subtype) const ; - - const uint16_t SERVICE_TYPE; -}; - - - - -#endif /* RSGXSUPDATEITEMS_H_ */ diff --git a/libretroshare/src/rsitems/rsheartbeatitems.h b/libretroshare/src/rsitems/rsheartbeatitems.h deleted file mode 100644 index b7e4f27c6..000000000 --- a/libretroshare/src/rsitems/rsheartbeatitems.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsheartbeatitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_HEARTBEAT_ITEMS_H -#define RS_HEARTBEAT_ITEMS_H - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" - -const uint8_t RS_PKT_SUBTYPE_HEARTBEAT_PULSE = 0x01; - -class RsHeartbeatItem: public RsItem -{ -public: - RsHeartbeatItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_HEARTBEAT, RS_PKT_SUBTYPE_HEARTBEAT_PULSE) - { - setPriorityLevel(QOS_PRIORITY_RS_HEARTBEAT_PULSE) ; - } - virtual ~RsHeartbeatItem() {} - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */) {} - - virtual void clear(){} -}; - -class RsHeartbeatSerialiser: public RsServiceSerializer -{ -public: - RsHeartbeatSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_HEARTBEAT) {} - - virtual ~RsHeartbeatSerialiser() {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const - { - if(service == RS_SERVICE_TYPE_HEARTBEAT && item_subtype == RS_PKT_SUBTYPE_HEARTBEAT_PULSE) - return new RsHeartbeatItem() ; - else - return NULL ; - } -}; - - -#endif // RS_DISC_ITEMS_H - diff --git a/libretroshare/src/rsitems/rshistoryitems.cc b/libretroshare/src/rsitems/rshistoryitems.cc deleted file mode 100644 index 4cfb04945..000000000 --- a/libretroshare/src/rsitems/rshistoryitems.cc +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rshistoryitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/rshistoryitems.h" -#include "rsitems/rsconfigitems.h" - -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" - -#include "serialiser/rstypeserializer.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -void RsHistoryMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - uint16_t version=0; - - RsTypeSerializer::serial_process(j,ctx,version,"version") ; - RsTypeSerializer::serial_process (j,ctx,chatPeerId,"chatPeerId") ; - RsTypeSerializer::serial_process (j,ctx,incoming,"incoming") ; - RsTypeSerializer::serial_process (j,ctx,msgPeerId,"peerId") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_NAME,peerName,"peerName") ; - RsTypeSerializer::serial_process(j,ctx,sendTime,"sendTime") ; - RsTypeSerializer::serial_process(j,ctx,recvTime,"recvTime") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_MSG,message,"message") ; -} - -RsItem *RsHistorySerialiser::create_item(uint8_t item_type,uint8_t item_subtype) const -{ - if(item_type != RS_PKT_TYPE_HISTORY_CONFIG) - return NULL ; - - if(item_subtype == RS_PKT_SUBTYPE_DEFAULT) - return new RsHistoryMsgItem(); - - return NULL ; -} - - -RsHistoryMsgItem::RsHistoryMsgItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_HISTORY_CONFIG, RS_PKT_SUBTYPE_DEFAULT) -{ - incoming = false; - sendTime = 0; - recvTime = 0; - msgId = 0; - saveToDisc = true; -} - - diff --git a/libretroshare/src/rsitems/rshistoryitems.h b/libretroshare/src/rsitems/rshistoryitems.h deleted file mode 100644 index 693817757..000000000 --- a/libretroshare/src/rsitems/rshistoryitems.h +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rshistoryitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_HISTORY_ITEMS_H -#define RS_HISTORY_ITEMS_H - -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserial.h" -#include "rsitems/rsconfigitems.h" -#include "retroshare/rstypes.h" - -#include "serialiser/rsserializer.h" - -/**************************************************************************/ - -class RsHistoryMsgItem: public RsItem -{ -public: - RsHistoryMsgItem(); - virtual ~RsHistoryMsgItem() {} - virtual void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsPeerId chatPeerId; // empty for global chat - bool incoming; - RsPeerId msgPeerId; - std::string peerName; - uint32_t sendTime; - uint32_t recvTime; - std::string message; - - /* not serialised */ - uint32_t msgId; - bool saveToDisc; -}; - -class RsHistorySerialiser: public RsConfigSerializer -{ -public: - RsHistorySerialiser() : RsConfigSerializer(RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_HISTORY_CONFIG) {} - virtual ~RsHistorySerialiser() {} - - virtual RsItem *create_item(uint8_t item_type,uint8_t item_subtype) const ; -}; - -/**************************************************************************/ - -#endif /* RS_HISTORY_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rsitem.h b/libretroshare/src/rsitems/rsitem.h deleted file mode 100644 index 1c8ea9789..000000000 --- a/libretroshare/src/rsitems/rsitem.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsitem.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include // for typeid - -#include "util/smallobject.h" -#include "retroshare/rstypes.h" -#include "serialiser/rsserializer.h" -#include "serialiser/rsserializable.h" -#include "util/stacktrace.h" - -#include - -struct RsItem : RsMemoryManagement::SmallObject, RsSerializable -{ - explicit RsItem(uint32_t t); - RsItem(uint8_t ver, uint8_t cls, uint8_t t, uint8_t subtype); -#ifdef DO_STATISTICS - void *operator new(size_t s) ; - void operator delete(void *,size_t s) ; -#endif - - virtual ~RsItem(); - - /// TODO: Do this make sense with the new serialization system? - virtual void clear() = 0; - - /// @deprecated use << ostream operator instead - RS_DEPRECATED_FOR("<< ostream operator") - virtual std::ostream &print(std::ostream &out, uint16_t /* indent */ = 0) - { - RsGenericSerializer::SerializeContext ctx( - nullptr, 0, RsSerializationFlags::NONE ); - serial_process(RsGenericSerializer::PRINT,ctx); - return out; - } - - void print_string(std::string &out, uint16_t indent = 0); - - /// source / destination id - const RsPeerId& PeerId() const { return peerId; } - void PeerId(const RsPeerId& id) { peerId = id; } - - /// complete id - uint32_t PacketId() const; - - /// id parts - uint8_t PacketVersion(); - uint8_t PacketClass(); - uint8_t PacketType(); - uint8_t PacketSubType() const; - - /// For Service Packets - RsItem(uint8_t ver, uint16_t service, uint8_t subtype); - uint16_t PacketService() const; /* combined Packet class/type (mid 16bits) */ - void setPacketService(uint16_t service); - - inline uint8_t priority_level() const { return _priority_level ;} - inline void setPriorityLevel(uint8_t l) { _priority_level = l ;} - - /* - * TODO: This default implementation should be removed and childs structs - * implement ::serial_process(...) as soon as all the codebase is ported to - * the new serialization system - */ - virtual void serial_process(RsGenericSerializer::SerializeJob, - RsGenericSerializer::SerializeContext&)// = 0; - { - std::cerr << "(EE) RsItem::serial_process(...) called by an item using" - << "new serialization classes, but not derived! Class is " - << typeid(*this).name() << std::endl; - print_stacktrace(); - } - -protected: - uint32_t type; - RsPeerId peerId; - uint8_t _priority_level; -}; - -/// TODO: Do this make sense with the new serialization system? -class RsRawItem: public RsItem -{ -public: - RsRawItem(uint32_t t, uint32_t size) : RsItem(t), len(size) - { data = rs_malloc(len); } - virtual ~RsRawItem() { free(data); } - - uint32_t getRawLength() { return len; } - void * getRawData() { return data; } - - virtual void clear() {} - virtual std::ostream &print(std::ostream &out, uint16_t indent = 0); - -private: - void *data; - uint32_t len; -}; diff --git a/libretroshare/src/rsitems/rsmsgitems.cc b/libretroshare/src/rsitems/rsmsgitems.cc deleted file mode 100644 index 8060248f4..000000000 --- a/libretroshare/src/rsitems/rsmsgitems.cc +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsmsgitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include "util/rstime.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvbase.h" - -#include "rsitems/rsmsgitems.h" - -#include "serialiser/rstypeserializer.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - - -RsItem *RsMsgSerialiser::create_item(uint16_t service,uint8_t type) const -{ - if(service != RS_SERVICE_TYPE_MSG) - return NULL ; - - switch(type) - { - case RS_PKT_SUBTYPE_DEFAULT : return new RsMsgItem() ; //= 0x01; - case RS_PKT_SUBTYPE_MSG_TAG_TYPE : return new RsMsgTagType() ; //= 0x03; - case RS_PKT_SUBTYPE_MSG_TAGS : return new RsMsgTags() ; //= 0x04; - case RS_PKT_SUBTYPE_MSG_SRC_TAG : return new RsMsgSrcId(); //= 0x05; - case RS_PKT_SUBTYPE_MSG_PARENT_TAG : return new RsMsgParentId() ; //= 0x06; - case RS_PKT_SUBTYPE_MSG_GROUTER_MAP : return new RsMsgGRouterMap(); //= 0x08; - case RS_PKT_SUBTYPE_MSG_DISTANT_MSG_MAP : return new RsMsgDistantMessagesHashMap();//= 0x09; - default: - return NULL ; - } -} - -void RsMsgItem::clear() -{ - msgId = 0; - msgFlags = 0; - sendTime = 0; - recvTime = 0; - subject.clear(); - message.clear(); - - rspeerid_msgto.TlvClear(); - rspeerid_msgcc.TlvClear(); - rspeerid_msgbcc.TlvClear(); - - rsgxsid_msgto.TlvClear(); - rsgxsid_msgcc.TlvClear(); - rsgxsid_msgbcc.TlvClear(); - - attachment.TlvClear(); -} - -void RsMsgTagType::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,text,"text") ; - RsTypeSerializer::serial_process(j,ctx,rgb_color,"rgb_color") ; - RsTypeSerializer::serial_process(j,ctx,tagId,"tagId") ; -} - -void RsMsgTags::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,msgId,"msgId") ; - -#warning this is not the correct way to serialise here. We should directly call serial_process >() but for backward compatibility, we cannot - - if(j == RsGenericSerializer::DESERIALIZE) - while(ctx.mOffset < ctx.mSize) - { - uint32_t n = 0;// No real need to initialize but otherwise the compiler complains. - RsTypeSerializer::serial_process(j,ctx,n,"tagIds element") ; - tagIds.push_back(n) ; - } - else - for(std::list::iterator it(tagIds.begin());it!=tagIds.end();++it) - RsTypeSerializer::serial_process(j,ctx,*it,"tagIds element") ; -} - -void RsMsgSrcId::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,msgId,"msgId") ; - RsTypeSerializer::serial_process (j,ctx,srcId,"srcId") ; -} - -void RsMsgGRouterMap::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,ongoing_msgs,"ongoing_msgs") ; -} - -void RsMsgGRouterMap::clear() -{ - ongoing_msgs.clear() ; - - return; -} - -void RsMsgDistantMessagesHashMap::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,hash_map,"hash_map") ; -} - -void RsMsgParentId::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,msgId,"msgId") ; - RsTypeSerializer::serial_process(j,ctx,msgParentId,"msgParentId") ; -} - -void RsMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,msgFlags,"msgFlags"); - RsTypeSerializer::serial_process(j,ctx,sendTime,"sendTime"); - RsTypeSerializer::serial_process(j,ctx,recvTime,"recvTime"); - - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_SUBJECT,subject,"subject"); - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_MSG,message,"message"); - - RsTypeSerializer::serial_process(j,ctx,rspeerid_msgto,"rspeerid_msgto"); - RsTypeSerializer::serial_process(j,ctx,rspeerid_msgcc,"rspeerid_msgcc"); - RsTypeSerializer::serial_process(j,ctx,rspeerid_msgbcc,"rspeerid_msgbcc"); - - RsTypeSerializer::serial_process(j,ctx,rsgxsid_msgto,"rsgxsid_msgto"); - RsTypeSerializer::serial_process(j,ctx,rsgxsid_msgcc,"rsgxsid_msgcc"); - RsTypeSerializer::serial_process(j,ctx,rsgxsid_msgbcc,"rsgxsid_msgbcc"); - - RsTypeSerializer::serial_process(j,ctx,attachment,"attachment"); - - if(!!(ctx.mFlags & RsSerializationFlags::CONFIG)) - RS_SERIAL_PROCESS(msgId); -} - -void RsMsgTagType::clear() -{ - text.clear(); - tagId = 0; - rgb_color = 0; -} - -void RsMsgTags::clear() -{ - msgId = 0; - tagIds.clear(); -} - diff --git a/libretroshare/src/rsitems/rsmsgitems.h b/libretroshare/src/rsitems/rsmsgitems.h deleted file mode 100644 index 27447aec0..000000000 --- a/libretroshare/src/rsitems/rsmsgitems.h +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsmsgitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -#include "retroshare/rstypes.h" -#include "serialiser/rstlvkeys.h" -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserial.h" - -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvfileitem.h" -#include "grouter/grouteritems.h" - - -/**************************************************************************/ - -// for defining tags themselves and msg tags -const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03; -const uint8_t RS_PKT_SUBTYPE_MSG_TAGS = 0x04; -const uint8_t RS_PKT_SUBTYPE_MSG_SRC_TAG = 0x05; -const uint8_t RS_PKT_SUBTYPE_MSG_PARENT_TAG = 0x06; -const uint8_t RS_PKT_SUBTYPE_MSG_INVITE = 0x07; -const uint8_t RS_PKT_SUBTYPE_MSG_GROUTER_MAP = 0x08; -const uint8_t RS_PKT_SUBTYPE_MSG_DISTANT_MSG_MAP = 0x09; - - -/**************************************************************************/ - -const uint32_t RS_MSG_FLAGS_OUTGOING = 0x00000001; -const uint32_t RS_MSG_FLAGS_PENDING = 0x00000002; -const uint32_t RS_MSG_FLAGS_DRAFT = 0x00000004; -const uint32_t RS_MSG_FLAGS_NEW = 0x00000010; -const uint32_t RS_MSG_FLAGS_TRASH = 0x00000020; -const uint32_t RS_MSG_FLAGS_UNREAD_BY_USER = 0x00000040; -const uint32_t RS_MSG_FLAGS_REPLIED = 0x00000080; -const uint32_t RS_MSG_FLAGS_FORWARDED = 0x00000100; -const uint32_t RS_MSG_FLAGS_STAR = 0x00000200; -const uint32_t RS_MSG_FLAGS_PARTIAL = 0x00000400; -const uint32_t RS_MSG_FLAGS_USER_REQUEST = 0x00000800; -const uint32_t RS_MSG_FLAGS_FRIEND_RECOMMENDATION = 0x00001000; -const uint32_t RS_MSG_FLAGS_RETURN_RECEPT = 0x00002000; -const uint32_t RS_MSG_FLAGS_ENCRYPTED = 0x00004000; -const uint32_t RS_MSG_FLAGS_DISTANT = 0x00008000; -const uint32_t RS_MSG_FLAGS_SIGNATURE_CHECKS = 0x00010000; -const uint32_t RS_MSG_FLAGS_SIGNED = 0x00020000; -const uint32_t RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES = 0x00040000; -const uint32_t RS_MSG_FLAGS_DECRYPTED = 0x00080000; -const uint32_t RS_MSG_FLAGS_ROUTED = 0x00100000; -const uint32_t RS_MSG_FLAGS_PUBLISH_KEY = 0x00200000; -const uint32_t RS_MSG_FLAGS_SPAM = 0x00400000; - -const uint32_t RS_MSG_FLAGS_SYSTEM = RS_MSG_FLAGS_USER_REQUEST | RS_MSG_FLAGS_FRIEND_RECOMMENDATION | RS_MSG_FLAGS_PUBLISH_KEY; - -class RsMessageItem: public RsItem -{ - public: - RsMessageItem(uint8_t msg_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_MSG,msg_subtype) - { - setPriorityLevel(QOS_PRIORITY_RS_MSG_ITEM) ; - } - - virtual ~RsMessageItem() {} - virtual void clear() {} -}; - - -class RsMsgItem: public RsMessageItem -{ - public: - RsMsgItem() :RsMessageItem(RS_PKT_SUBTYPE_DEFAULT) {} - - virtual ~RsMsgItem() {} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - // ----------- Specific fields ------------- // - - uint32_t msgFlags; - uint32_t msgId; - - uint32_t sendTime; - uint32_t recvTime; - - std::string subject; - std::string message; - - RsTlvPeerIdSet rspeerid_msgto; - RsTlvPeerIdSet rspeerid_msgcc; - RsTlvPeerIdSet rspeerid_msgbcc; - - RsTlvGxsIdSet rsgxsid_msgto; - RsTlvGxsIdSet rsgxsid_msgcc; - RsTlvGxsIdSet rsgxsid_msgbcc; - - RsTlvFileSet attachment; -}; - -class RsMsgTagType : public RsMessageItem -{ - public: - RsMsgTagType() :RsMessageItem(RS_PKT_SUBTYPE_MSG_TAG_TYPE) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgTagType() {} - virtual void clear(); - - // ----------- Specific fields ------------- // - // - std::string text; - uint32_t rgb_color; - uint32_t tagId; -}; - -class RsMsgTags : public RsMessageItem -{ -public: - RsMsgTags() - :RsMessageItem(RS_PKT_SUBTYPE_MSG_TAGS) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgTags() {} - virtual void clear(); - - // ----------- Specific fields ------------- // - // - uint32_t msgId; - std::list tagIds; -}; - -class RsMsgSrcId : public RsMessageItem -{ - public: - RsMsgSrcId() : RsMessageItem(RS_PKT_SUBTYPE_MSG_SRC_TAG) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgSrcId() {} - virtual void clear(){} - - // ----------- Specific fields ------------- // - // - - uint32_t msgId; - RsPeerId srcId; -}; - -class RsMsgGRouterMap : public RsMessageItem -{ - public: - RsMsgGRouterMap() : RsMessageItem(RS_PKT_SUBTYPE_MSG_GROUTER_MAP) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgGRouterMap() {} - virtual void clear(); - - // ----------- Specific fields ------------- // - // - std::map ongoing_msgs ; -}; -class RsMsgDistantMessagesHashMap : public RsMessageItem -{ - public: - RsMsgDistantMessagesHashMap() : RsMessageItem(RS_PKT_SUBTYPE_MSG_DISTANT_MSG_MAP) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgDistantMessagesHashMap() {} - virtual void clear() { hash_map.clear() ;} - - // ----------- Specific fields ------------- // - // - std::map hash_map ; -}; -class RsMsgParentId : public RsMessageItem -{ - public: - RsMsgParentId() : RsMessageItem(RS_PKT_SUBTYPE_MSG_PARENT_TAG) {} - - virtual void serial_process(RsGenericSerializer::SerializeJob /* j */,RsGenericSerializer::SerializeContext& /* ctx */); - - virtual ~RsMsgParentId() {} - virtual void clear(){} - - // ----------- Specific fields ------------- // - // - uint32_t msgId; - uint32_t msgParentId; -}; - -class RsMsgSerialiser: public RsServiceSerializer -{ -public: - RsMsgSerialiser( - RsSerializationFlags flags = RsSerializationFlags::NONE ): - RsServiceSerializer(RS_SERVICE_TYPE_MSG, flags){} - - RsItem* create_item(uint16_t service,uint8_t type) const override; - - ~RsMsgSerialiser() override = default; -}; diff --git a/libretroshare/src/rsitems/rsnxsitems.cc b/libretroshare/src/rsitems/rsnxsitems.cc deleted file mode 100644 index e8178e045..000000000 --- a/libretroshare/src/rsitems/rsnxsitems.cc +++ /dev/null @@ -1,253 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsnxsitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker,Robert Fernie* - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsnxsitems.h" -#include "util/rsprint.h" -#include - -#include "serialiser/rstypeserializer.h" - -/*** - * #define RSSERIAL_DEBUG 1 - ***/ - -const uint8_t RsNxsSyncGrpItem::FLAG_REQUEST = 0x001; -const uint8_t RsNxsSyncGrpItem::FLAG_RESPONSE = 0x002; - -const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001; -const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002; - -const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x0001; -const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x0001; - -const uint8_t RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID = 0x02; - -/** transaction state **/ -const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001; -const uint16_t RsNxsTransacItem::FLAG_BEGIN_P2 = 0x0002; -const uint16_t RsNxsTransacItem::FLAG_END_SUCCESS = 0x0004; -const uint16_t RsNxsTransacItem::FLAG_CANCEL = 0x0008; -const uint16_t RsNxsTransacItem::FLAG_END_FAIL_NUM = 0x0010; -const uint16_t RsNxsTransacItem::FLAG_END_FAIL_TIMEOUT = 0x0020; -const uint16_t RsNxsTransacItem::FLAG_END_FAIL_FULL = 0x0040; - - -/** transaction type **/ -const uint16_t RsNxsTransacItem::FLAG_TYPE_GRP_LIST_RESP = 0x0100; -const uint16_t RsNxsTransacItem::FLAG_TYPE_MSG_LIST_RESP = 0x0200; -const uint16_t RsNxsTransacItem::FLAG_TYPE_GRP_LIST_REQ = 0x0400; -const uint16_t RsNxsTransacItem::FLAG_TYPE_MSG_LIST_REQ = 0x0800; -const uint16_t RsNxsTransacItem::FLAG_TYPE_GRPS = 0x1000; -const uint16_t RsNxsTransacItem::FLAG_TYPE_MSGS = 0x2000; -const uint16_t RsNxsTransacItem::FLAG_TYPE_ENCRYPTED_DATA = 0x4000; - -RsItem *RsNxsSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != SERVICE_TYPE) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM: return new RsNxsSyncGrpReqItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM: return new RsNxsSyncGrpItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM: return new RsNxsSyncMsgReqItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM: return new RsNxsSyncMsgItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_GRP_ITEM: return new RsNxsGrp(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_MSG_ITEM: return new RsNxsMsg(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM: return new RsNxsTransacItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM:return new RsNxsGroupPublishKeyItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM: return new RsNxsEncryptedDataItem(SERVICE_TYPE) ; - case RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM: return new RsNxsSyncGrpStatsItem(SERVICE_TYPE) ; - - default: - return NULL; - } -} - -void RsNxsSyncMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process (j,ctx,flag ,"flag") ; - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process (j,ctx,msgId ,"msgId") ; - RsTypeSerializer::serial_process (j,ctx,authorId ,"authorId") ; -} - -void RsNxsMsg::serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(transactionNumber); - RS_SERIAL_PROCESS(pos); - RS_SERIAL_PROCESS(msgId); - RS_SERIAL_PROCESS(grpId); - RS_SERIAL_PROCESS(msg); - RS_SERIAL_PROCESS(meta); -} - -void RsNxsGrp::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process (j,ctx,pos ,"pos") ; - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process(j,ctx,grp ,"grp") ; - RsTypeSerializer::serial_process(j,ctx,meta ,"meta") ; -} - -void RsNxsSyncGrpStatsItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,request_type ,"request_type") ; - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process (j,ctx,number_of_posts,"number_of_posts") ; - RsTypeSerializer::serial_process (j,ctx,last_post_TS ,"last_post_TS") ; -} - -void RsNxsSyncGrpReqItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process (j,ctx,flag ,"flag") ; - RsTypeSerializer::serial_process(j,ctx,createdSince ,"createdSince") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_HASH_SHA1,syncHash,"syncHash") ; - RsTypeSerializer::serial_process(j,ctx,updateTS ,"updateTS") ; -} - -void RsNxsTransacItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process(j,ctx,transactFlag ,"transactFlag") ; - RsTypeSerializer::serial_process(j,ctx,nItems ,"nItems") ; - RsTypeSerializer::serial_process(j,ctx,updateTS ,"updateTS") ; -} -void RsNxsSyncGrpItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process (j,ctx,flag ,"flag") ; - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process(j,ctx,publishTs ,"publishTs") ; - RsTypeSerializer::serial_process (j,ctx,authorId ,"authorId") ; -} -void RsNxsSyncMsgReqItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process (j,ctx,flag ,"flag") ; - RsTypeSerializer::serial_process(j,ctx,createdSinceTS ,"createdSinceTS") ; - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_HASH_SHA1,syncHash,"syncHash") ; - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process(j,ctx,updateTS ,"updateTS") ; -} -void RsNxsGroupPublishKeyItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,grpId ,"grpId") ; - RsTypeSerializer::serial_process(j,ctx,private_key ,"private_key") ; -} -void RsNxsEncryptedDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,transactionNumber,"transactionNumber") ; - RsTypeSerializer::serial_process(j,ctx,encrypted_data, "encrypted_data") ; -} - -int RsNxsGrp::refcount = 0; -int RsNxsMsg::refcount = 0; - -/** print and clear functions **/ -void RsNxsMsg::clear() -{ - - msg.TlvClear(); - meta.TlvClear(); -} - -void RsNxsGrp::clear() -{ - grpId.clear(); - grp.TlvClear(); - meta.TlvClear(); -} - -RsNxsGrp* RsNxsGrp::clone() const { - RsNxsGrp* grp = new RsNxsGrp(this->grp.tlvtype); - *grp = *this; - - if(this->metaData) - { - grp->metaData = new RsGxsGrpMetaData(); - *(grp->metaData) = *(this->metaData); - } - - return grp; -} - -void RsNxsSyncGrpReqItem::clear() -{ - flag = 0; - createdSince = 0; - updateTS = 0; - syncHash.clear(); -} -void RsNxsGroupPublishKeyItem::clear() -{ - private_key.TlvClear(); -} -void RsNxsSyncMsgReqItem::clear() -{ - grpId.clear(); - flag = 0; - createdSinceTS = 0; - updateTS = 0; - syncHash.clear(); -} -void RsNxsSyncGrpItem::clear() -{ - flag = 0; - publishTs = 0; - grpId.clear(); - authorId.clear(); -} - -void RsNxsSyncMsgItem::clear() -{ - flag = 0; - grpId.clear(); - msgId.clear(); - authorId.clear(); -} - -void RsNxsTransacItem::clear(){ - transactFlag = 0; - nItems = 0; - updateTS = 0; - timestamp = 0; - transactionNumber = 0; -} -void RsNxsEncryptedDataItem::clear(){ - encrypted_data.TlvClear() ; -} - -#ifdef SUSPENDED_CODE_27042017 -void RsNxsSessionKeyItem::clear() -{ - for(std::map::iterator it(encrypted_session_keys.begin());it!=encrypted_session_keys.end();++it) - it->second.TlvClear() ; - - encrypted_session_keys.clear() ; -} -#endif - - diff --git a/libretroshare/src/rsitems/rsnxsitems.h b/libretroshare/src/rsitems/rsnxsitems.h deleted file mode 100644 index 2b6731bfc..000000000 --- a/libretroshare/src/rsitems/rsnxsitems.h +++ /dev/null @@ -1,516 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsnxsitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker,Robert Fernie* - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSNXSITEMS_H -#define RSNXSITEMS_H - -#include -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvkeys.h" -#include "gxs/rsgxsdata.h" - -// These items have "flag type" numbers, but this is not used. - -const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM = 0x01; -const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_NXS_GRP_ITEM = 0x04; -const uint8_t RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM = 0x05; -const uint8_t RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM = 0x06; -const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM = 0x08; -const uint8_t RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM = 0x10; -const uint8_t RS_PKT_SUBTYPE_NXS_MSG_ITEM = 0x20; -const uint8_t RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM = 0x40; -const uint8_t RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM = 0x80; - -// possibility create second service to deal with this functionality - -const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_GRP = 0x0001; -const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_MSG = 0x0002; -const uint8_t RS_PKT_SUBTYPE_EXT_DELETE_GRP = 0x0004; -const uint8_t RS_PKT_SUBTYPE_EXT_DELETE_MSG = 0x0008; -const uint8_t RS_PKT_SUBTYPE_EXT_SEARCH_REQ = 0x0010; - - -/*! - * Base class for Network exchange service - * Main purpose is for rtti based routing used in the - * serialisation and deserialisation of NXS packets - * - * Service type is set by plugin service - */ -class RsNxsItem : public RsItem -{ - -public: - RsNxsItem(uint16_t servtype, uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) - { - setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); - return; - } - virtual ~RsNxsItem(){} - virtual void clear() = 0; - - uint32_t transactionNumber; // set to zero if this is not a transaction item -}; - - -/*! - * Use to request grp list from peer - * Server may advise client peer to use sync file - * while serving his request. This results - */ -class RsNxsSyncGrpReqItem : public RsNxsItem -{ -public: - - static const uint8_t FLAG_USE_SYNC_HASH; - static const uint8_t FLAG_ONLY_CURRENT; // only send most current version of grps / ignores sync hash - - explicit RsNxsSyncGrpReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_REQ_ITEM) { clear();} - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint8_t flag; // advises whether to use sync hash - uint32_t createdSince; // how far back to sync data - uint32_t updateTS; // time of last group update - std::string syncHash; // use to determine if changes that have occured since last hash -}; - -/*! - * Use to request statistics about a particular group - */ -class RsNxsSyncGrpStatsItem : public RsNxsItem -{ -public: - - explicit RsNxsSyncGrpStatsItem(uint16_t servtype) - : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_STATS_ITEM) - , request_type(0), number_of_posts(0), last_post_TS(0) - {} - - virtual void clear() override {} - - static const uint8_t GROUP_INFO_TYPE_REQUEST = 0x01; - static const uint8_t GROUP_INFO_TYPE_RESPONSE = 0x02; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint32_t request_type; // used to determine the type of request - RsGxsGroupId grpId; // id of the group - uint32_t number_of_posts; // number of posts in that group - uint32_t last_post_TS; // time_stamp of last post -}; - -/*! - * Use to request grp list from peer - * Server may advise client peer to use sync file - * while serving his request. This results - */ -class RsNxsGroupPublishKeyItem : public RsNxsItem -{ -public: - explicit RsNxsGroupPublishKeyItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY_ITEM) { clear(); } - - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - RsGxsGroupId grpId ; - RsTlvPrivateRSAKey private_key ; -}; - - - -/*! - * This RsNxsItem is for use in enabling transactions - * in order to guaranttee a collection of item have been - * received - */ -class RsNxsTransacItem: public RsNxsItem { - -public: - - static const uint16_t FLAG_STATE_MASK = 0xff; - static const uint16_t FLAG_TYPE_MASK = 0xff00; - - /** transaction state **/ - static const uint16_t FLAG_BEGIN_P1; - static const uint16_t FLAG_BEGIN_P2; - static const uint16_t FLAG_END_SUCCESS; - static const uint16_t FLAG_CANCEL; - static const uint16_t FLAG_END_FAIL_NUM; - static const uint16_t FLAG_END_FAIL_TIMEOUT; - static const uint16_t FLAG_END_FAIL_FULL; - - - /** transaction type **/ - static const uint16_t FLAG_TYPE_GRP_LIST_RESP; - static const uint16_t FLAG_TYPE_MSG_LIST_RESP; - static const uint16_t FLAG_TYPE_GRP_LIST_REQ; - static const uint16_t FLAG_TYPE_MSG_LIST_REQ; - static const uint16_t FLAG_TYPE_GRPS; - static const uint16_t FLAG_TYPE_MSGS; - static const uint16_t FLAG_TYPE_ENCRYPTED_DATA; - - explicit RsNxsTransacItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_TRANSAC_ITEM) { clear(); } - virtual ~RsNxsTransacItem() {} - - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint16_t transactFlag; - uint32_t nItems; - uint32_t updateTS; - - // not serialised - uint32_t timestamp; -}; - -/*! - * Use to send to peer list of grps - * held by server peer - */ -class RsNxsSyncGrpItem: public RsNxsItem -{ - -public: - - static const uint8_t FLAG_REQUEST; - static const uint8_t FLAG_RESPONSE; - static const uint8_t FLAG_USE_SYNC_HASH; - - explicit RsNxsSyncGrpItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_GRP_ITEM) { clear();} - virtual ~RsNxsSyncGrpItem() {} - - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint8_t flag; // request or response - uint32_t publishTs; // to compare to Ts of receiving peer's grp of same id - - /// grpId of grp held by sending peer - RsGxsGroupId grpId; - RsGxsId authorId; - -}; - -#ifdef SUSPENDED_CODE_27042017 -/*! - * Use to send to peer list of grps - * held by server peer - */ -class RsNxsSessionKeyItem : public RsNxsItem -{ - -public: - - explicit RsNxsSessionKeyItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SESSION_KEY_ITEM) { clear(); } - virtual ~RsNxsSessionKeyItem() {} - - virtual void clear() override; - - /// Session key encrypted for the whole group - /// - uint8_t iv[EVP_MAX_IV_LENGTH] ; // initialisation vector - std::map encrypted_session_keys; // encrypted session keys -}; -#endif -/*! - * Use to send to peer list of grps - * held by server peer - */ -class RsNxsEncryptedDataItem : public RsNxsItem -{ - -public: - - explicit RsNxsEncryptedDataItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_ENCRYPTED_DATA_ITEM),encrypted_data(servtype) - { - encrypted_data.tlvtype = TLV_TYPE_BIN_ENCRYPTED ; - clear(); - } - virtual ~RsNxsEncryptedDataItem() {} - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - /// grpId of grp held by sending peer - /// - RsTlvBinaryData encrypted_data ; -}; - - -/*! - * Contains serialised group items - * Each item corresponds to a group which needs to be - * deserialised - */ -class RsNxsGrp : public RsNxsItem -{ - -public: - - explicit RsNxsGrp(uint16_t servtype) - : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_GRP_ITEM) - , pos(0), count(0), meta(servtype), grp(servtype), metaData(NULL) - { clear(); } - virtual ~RsNxsGrp() { delete metaData; } - - RsNxsGrp* clone() const; - - virtual void clear() override; - - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - uint8_t pos; /// used for splitting up grp - uint8_t count; /// number of split up messages - RsGxsGroupId grpId; /// group Id, needed to complete version Id (ncvi) - static int refcount; - - /*! - * This should contains all data - * which is not specific to the Gxs service data - */ - // This is the binary data for the group meta that is sent to friends. It *should not* contain any private - // key parts. This is ensured in RsGenExchange - - RsTlvBinaryData meta; - - RsTlvBinaryData grp; /// actual group data - - // Deserialised metaData, this is not serialised by the serialize() method. So it may contain private key parts in some cases. - RsGxsGrpMetaData* metaData; -}; - -/*! - * Use to request list of msg held by peer - * for a given group - */ -class RsNxsSyncMsgReqItem : public RsNxsItem -{ - -public: - -#ifdef UNUSED_CODE - static const uint8_t FLAG_USE_SYNC_HASH; -#endif - static const uint8_t FLAG_USE_HASHED_GROUP_ID; - - explicit RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); } - - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - RsGxsGroupId grpId; - uint8_t flag; - uint32_t createdSinceTS; - uint32_t updateTS; // time of last update - std::string syncHash; -}; - -/*! - * Use to send list msgs for a group held by - * a peer - */ -class RsNxsSyncMsgItem : public RsNxsItem -{ -public: - - static const uint8_t FLAG_REQUEST; - static const uint8_t FLAG_RESPONSE; - static const uint8_t FLAG_USE_SYNC_HASH; - explicit RsNxsSyncMsgItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_ITEM) { clear(); } - - virtual void clear() override; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint8_t flag; // response/req - RsGxsGroupId grpId; - RsGxsMessageId msgId; - RsGxsId authorId; - -}; - - -/*! - * Used to respond to a RsGrpMsgsReq - * with message items satisfying request - */ -struct RsNxsMsg : RsNxsItem -{ - explicit RsNxsMsg(uint16_t servtype) - : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG_ITEM) - , pos(0), count(0), meta(servtype), msg(servtype), metaData(NULL) - { clear(); } - virtual ~RsNxsMsg() { delete metaData; } - - virtual void clear() override; - - virtual void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - uint8_t pos; /// used for splitting up msg - uint8_t count; /// number of split up messages - RsGxsGroupId grpId; /// group id, forms part of version id - RsGxsMessageId msgId; /// msg id - static int refcount; - - /*! - * This should contains all the data - * which is not specific to the Gxs service data - */ - RsTlvBinaryData meta; - - /*! - * This contains Gxs specific data - * only client of API knows how to decode this - */ - RsTlvBinaryData msg; - - RsGxsMsgMetaData* metaData; -}; - -/*! - * Used to request a search of user data - */ -class RsNxsSearchReqItem : public RsNxsItem -{ -public: - - explicit RsNxsSearchReqItem(uint16_t servtype) - : RsNxsItem(servtype, RS_PKT_SUBTYPE_EXT_SEARCH_REQ) - , nHops(0), token(0), serviceSearchItem(servtype), expiration(0) - {} - virtual ~RsNxsSearchReqItem() {} - virtual void clear() override {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override; - - uint8_t nHops; /// how many peers to jump to - uint32_t token; // search token - RsTlvBinaryData serviceSearchItem; // service aware of item class - uint32_t expiration; // expiration date -}; - - -#ifdef UNUSED_CODE - -/*! - * Used to respond to a RsGrpSearchReq - * with grpId/MsgIds that satisfy search request - */ -class RsNxsSearchResultMsgItem -{ -public: - - RsNxsSearchResultMsgItem() - : token(0), context(0), expiration(0) - {} - - void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t token; // search token to be redeemed - RsTlvBinaryData context; // used by client service - std::string msgId; - std::string grpId; - RsTlvKeySignature idSign; - - uint32_t expiration; // expiration date -}; - -/*! - * Used to respond to a RsGrpSearchReq - * with grpId/MsgIds that satisfy search request - */ -class RsNxsSearchResultGrpItem -{ -public: - - RsNxsSearchResultGrpItem(); - - void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t token; // search token to be redeemed - RsTlvBinaryData context; // used by client service - - std::string grpId; - RsTlvKeySignature adminSign; - - uint32_t expiration; // expiration date -}; - -class RsNxsDeleteMsg -{ -public: - - RsNxsDeleteMsg() { return; } - - std::string msgId; - std::string grpId; - RsTlvKeySignature deleteSign; // ( msgId + grpId + msg data ) sign //TODO: add warning not to place msgId+grpId in msg! - -}; - -class RsNxsDeleteGrp -{ -public: - - RsNxsDeleteGrp() { return;} - - std::string grpId; - RsTlvKeySignature idSign; - RsTlvKeySignature deleteSign; // (grpId + grp data) sign // TODO: add warning not to place grpId in msg -}; -#endif - - -class RsNxsSerialiser : public RsServiceSerializer -{ -public: - - explicit RsNxsSerialiser(uint16_t servtype) : RsServiceSerializer(servtype), SERVICE_TYPE(servtype) {} - virtual ~RsNxsSerialiser() {} - - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -protected: - const uint16_t SERVICE_TYPE; -}; - - -#endif // RSNXSITEMS_H diff --git a/libretroshare/src/rsitems/rsphotoitems.cc b/libretroshare/src/rsitems/rsphotoitems.cc deleted file mode 100644 index f9200a83c..000000000 --- a/libretroshare/src/rsitems/rsphotoitems.cc +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsphotoitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker,Robert Fernie* - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsitems/rsphotoitems.h" - -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstypeserializer.h" - -RsItem *RsGxsPhotoSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_GXS_TYPE_PHOTO) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM: return new RsGxsPhotoPhotoItem() ; - case RS_PKT_SUBTYPE_PHOTO_ITEM: return new RsGxsPhotoAlbumItem() ; - default: - return RsGxsCommentSerialiser::create_item(service,item_sub_id) ; - } -} - -void RsGxsPhotoAlbumItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,album.mShareMode,"mShareMode"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CAPTION, album.mCaption, "mCaption"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, album.mDescription, "mDescription"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME, album.mPhotographer, "mPhotographer"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION, album.mWhere, "mWhere"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DATE, album.mWhen, "mWhen"); - - album.mThumbnail.serial_process(j, ctx); -} -void RsGxsPhotoPhotoItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR, photo.mDescription, "mDescription"); - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,photo.mOrder,"mOrder"); - photo.mLowResImage.serial_process(j, ctx); - photo.mPhotoFile.serial_process(j, ctx); -} - -void RsGxsPhotoAlbumItem::clear() -{ - album.mShareMode = RSPHOTO_SHAREMODE_LOWRESONLY; - album.mCaption.clear(); - album.mDescription.clear(); - album.mPhotographer.clear(); - album.mWhere.clear(); - album.mWhen.clear(); - album.mThumbnail.clear(); - - // not saved - album.mAutoDownload = false; -} - -void RsGxsPhotoPhotoItem::clear() -{ - photo.mDescription.clear(); - photo.mOrder = 0; - photo.mLowResImage.clear(); - photo.mPhotoFile.clear(); - - // not saved - photo.mPath.clear(); -} diff --git a/libretroshare/src/rsitems/rsphotoitems.h b/libretroshare/src/rsitems/rsphotoitems.h deleted file mode 100644 index a504ae29b..000000000 --- a/libretroshare/src/rsitems/rsphotoitems.h +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsphotoitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker,Robert Fernie* - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSPHOTOV2ITEMS_H_ -#define RSPHOTOV2ITEMS_H_ - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsgxsitems.h" -#include "rsitems/rsgxscommentitems.h" - -#include "serialiser/rsserial.h" -#include "serialiser/rsserializer.h" - -#include "retroshare/rsphoto.h" - -const uint8_t RS_PKT_SUBTYPE_PHOTO_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM = 0x03; - -class RsGxsPhotoAlbumItem : public RsGxsGrpItem -{ - -public: - - RsGxsPhotoAlbumItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_PHOTO, - RS_PKT_SUBTYPE_PHOTO_ITEM) { return;} - virtual ~RsGxsPhotoAlbumItem() { return;} - - void clear(); -// std::ostream &print(std::ostream &out, uint16_t indent = 0); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsPhotoAlbum album; -}; - -class RsGxsPhotoPhotoItem : public RsGxsMsgItem -{ -public: - - RsGxsPhotoPhotoItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_PHOTO, RS_PKT_SUBTYPE_PHOTO_SHOW_ITEM) {} - virtual ~RsGxsPhotoPhotoItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsPhotoPhoto photo; -}; - -class RsGxsPhotoSerialiser : public RsGxsCommentSerialiser -{ -public: - - RsGxsPhotoSerialiser() :RsGxsCommentSerialiser(RS_SERVICE_GXS_TYPE_PHOTO) {} - virtual ~RsGxsPhotoSerialiser() {} - - virtual RsItem *create_item(uint16_t service, uint8_t item_sub_id) const; -}; - -#endif /* RSPHOTOV2ITEMS_H_ */ diff --git a/libretroshare/src/rsitems/rspluginitems.h b/libretroshare/src/rsitems/rspluginitems.h deleted file mode 100644 index 29069815d..000000000 --- a/libretroshare/src/rsitems/rspluginitems.h +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rspluginitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "rsitems/rsitem.h" -#include "rsitems/rsconfigitems.h" - -#include "serialiser/rstypeserializer.h" - -const uint8_t RS_PKT_CLASS_PLUGIN_SUBTYPE_HASHSET = 0x01 ; - -class RsPluginItem: public RsItem -{ - public: - explicit RsPluginItem(uint8_t plugin_item_subtype): RsItem(RS_PKT_VERSION1,RS_PKT_CLASS_CONFIG,RS_PKT_TYPE_PLUGIN_CONFIG,plugin_item_subtype) {} - virtual ~RsPluginItem() {} - - virtual void clear() {} -}; - -class RsPluginHashSetItem: public RsPluginItem -{ - public: - RsPluginHashSetItem() : RsPluginItem(RS_PKT_CLASS_PLUGIN_SUBTYPE_HASHSET) {} - RsPluginHashSetItem(void *data,uint32_t size) ; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,hashes,"hashes"); - } - - RsTlvHashSet hashes ; -}; - -class RsPluginSerialiser: public RsConfigSerializer -{ - public: - RsPluginSerialiser() : RsConfigSerializer(RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PLUGIN_CONFIG) {} - - virtual RsItem *create_item(uint8_t class_type, uint8_t item_type) const - { - if(class_type == RS_PKT_TYPE_PLUGIN_CONFIG && item_type == RS_PKT_CLASS_PLUGIN_SUBTYPE_HASHSET) - return new RsPluginHashSetItem() ; - - return NULL ; - } -}; - - diff --git a/libretroshare/src/rsitems/rsposteditems.cc b/libretroshare/src/rsitems/rsposteditems.cc deleted file mode 100644 index 3c16ff5bd..000000000 --- a/libretroshare/src/rsitems/rsposteditems.cc +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsposteditems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/rsposteditems.h" -#include "serialiser/rstypeserializer.h" - - - -void RsGxsPostedPostItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LINK,mPost.mLink,"mPost.mLink") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG ,mPost.mNotes,"mPost.mNotes") ; - - // Do not serialize mImage member if it is empty (keeps compatibility of new posts without image toward older RS) - // and do not expect to deserialize mImage member if the data block has been consummed entirely (keeps compatibility - // of new RS with older posts. - - if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) - return ; - - if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mImage.empty()) - return ; - - RsTypeSerializer::serial_process(j,ctx,mImage,"mImage") ; -} - -void RsGxsPostedGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,mDescription,"mDescription") ; - - if(j == RsGenericSerializer::DESERIALIZE && ctx.mOffset == ctx.mSize) - return ; - - if((j == RsGenericSerializer::SIZE_ESTIMATE || j == RsGenericSerializer::SERIALIZE) && mGroupImage.empty()) - return ; - - RsTypeSerializer::serial_process(j,ctx,mGroupImage,"mGroupImage") ; -} - -RsItem *RsGxsPostedSerialiser::create_item(uint16_t service_id,uint8_t item_subtype) const -{ - if(service_id != RS_SERVICE_GXS_TYPE_POSTED) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_POSTED_GRP_ITEM: return new RsGxsPostedGroupItem() ; - case RS_PKT_SUBTYPE_POSTED_POST_ITEM: return new RsGxsPostedPostItem() ; - default: - return RsGxsCommentSerialiser::create_item(service_id,item_subtype) ; - } -} - -bool RsGxsPostedPostItem::fromPostedPost(RsPostedPost &post, bool moveImage) -{ - clear(); - - mPost = post; - meta = post.mMeta; - - if (moveImage) - { - mImage.binData.bin_data = post.mImage.mData; - mImage.binData.bin_len = post.mImage.mSize; - post.mImage.shallowClear(); - } - else - { - mImage.binData.setBinData(post.mImage.mData, post.mImage.mSize); - } - - return true; -} - -bool RsGxsPostedPostItem::toPostedPost(RsPostedPost &post, bool moveImage) -{ - post = mPost; - post.mMeta = meta; - - if (moveImage) - { - post.mImage.take((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - // mImage doesn't have a ShallowClear at the moment! - mImage.binData.TlvShallowClear(); - } - else - { - post.mImage.copy((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len); - } - - return true; -} - -void RsGxsPostedPostItem::clear() -{ - mPost.mLink.clear(); - mPost.mNotes.clear(); - mImage.TlvClear(); -} -void RsGxsPostedGroupItem::clear() -{ - mDescription.clear(); - mGroupImage.TlvClear(); -} - -bool RsGxsPostedGroupItem::fromPostedGroup(RsPostedGroup &group, bool moveImage) -{ - clear(); - meta = group.mMeta; - mDescription = group.mDescription; - - if (moveImage) - { - mGroupImage.binData.bin_data = group.mGroupImage.mData; - mGroupImage.binData.bin_len = group.mGroupImage.mSize; - group.mGroupImage.shallowClear(); - } - else - { - mGroupImage.binData.setBinData(group.mGroupImage.mData, group.mGroupImage.mSize); - } - return true; -} - -bool RsGxsPostedGroupItem::toPostedGroup(RsPostedGroup &group, bool moveImage) -{ - group.mMeta = meta; - group.mDescription = mDescription; - if (moveImage) - { - group.mGroupImage.take((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len); - // mGroupImage doesn't have a ShallowClear at the moment! - mGroupImage.binData.TlvShallowClear(); - } - else - { - group.mGroupImage.copy((uint8_t *) mGroupImage.binData.bin_data, mGroupImage.binData.bin_len); - } - return true; -} diff --git a/libretroshare/src/rsitems/rsposteditems.h b/libretroshare/src/rsitems/rsposteditems.h deleted file mode 100644 index 910471c19..000000000 --- a/libretroshare/src/rsitems/rsposteditems.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsposteditems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSPOSTEDITEMS_H -#define RSPOSTEDITEMS_H - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsgxscommentitems.h" -#include "rsitems/rsgxsitems.h" -#include "serialiser/rstlvimage.h" - -#include "retroshare/rsposted.h" - -const uint8_t RS_PKT_SUBTYPE_POSTED_GRP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_POSTED_POST_ITEM = 0x03; - -class RsGxsPostedGroupItem : public RsGxsGrpItem -{ -public: - RsGxsPostedGroupItem() : RsGxsGrpItem(RS_SERVICE_GXS_TYPE_POSTED, RS_PKT_SUBTYPE_POSTED_GRP_ITEM) {} - virtual ~RsGxsPostedGroupItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // use conversion functions to transform: - bool fromPostedGroup(RsPostedGroup &group, bool moveImage); - bool toPostedGroup(RsPostedGroup &group, bool moveImage); - - std::string mDescription; - RsTlvImage mGroupImage; - -}; - -class RsGxsPostedPostItem : public RsGxsMsgItem -{ -public: - RsGxsPostedPostItem() : RsGxsMsgItem(RS_SERVICE_GXS_TYPE_POSTED, RS_PKT_SUBTYPE_POSTED_POST_ITEM) {} - virtual ~RsGxsPostedPostItem() {} - - void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - // Slightly unusual structure. - // use conversion functions to transform: - bool fromPostedPost(RsPostedPost &post, bool moveImage); - bool toPostedPost(RsPostedPost &post, bool moveImage); - - RsPostedPost mPost; - RsTlvImage mImage; -}; - -class RsGxsPostedSerialiser : public RsGxsCommentSerialiser -{ -public: - - RsGxsPostedSerialiser() :RsGxsCommentSerialiser(RS_SERVICE_GXS_TYPE_POSTED) {} - - virtual ~RsGxsPostedSerialiser() {} - - virtual RsItem *create_item(uint16_t service_id,uint8_t item_subtype) const ; -}; - - -#endif // RSPOSTEDITEMS_H diff --git a/libretroshare/src/rsitems/rsrttitems.cc b/libretroshare/src/rsitems/rsrttitems.cc deleted file mode 100644 index 739f1c06d..000000000 --- a/libretroshare/src/rsitems/rsrttitems.cc +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsrttitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/rsrttitems.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -#include "serialiser/rstypeserializer.h" - -/*************************************************************************/ - -RsItem *RsRttSerialiser::create_item(uint16_t service,uint8_t type) const -{ - if(service != RS_SERVICE_TYPE_RTT) - return NULL ; - - switch(type) - { - case RS_PKT_SUBTYPE_RTT_PING: return new RsRttPingItem() ; //= 0x01; - case RS_PKT_SUBTYPE_RTT_PONG: return new RsRttPongItem() ; // = 0x02; - default: - return NULL ; - } -} - -void RsRttPingItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mSeqNo,"mSeqNo") ; - RsTypeSerializer::serial_process(j,ctx,mPingTS,"mPingTS") ; -} - -void RsRttPongItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,mSeqNo,"mSeqNo") ; - RsTypeSerializer::serial_process(j,ctx,mPingTS,"mPingTS") ; - RsTypeSerializer::serial_process(j,ctx,mPongTS,"mPongTS") ; -} - - - diff --git a/libretroshare/src/rsitems/rsrttitems.h b/libretroshare/src/rsitems/rsrttitems.h deleted file mode 100644 index 54f612ee6..000000000 --- a/libretroshare/src/rsitems/rsrttitems.h +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsrttitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2013 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_RTT_ITEMS_H -#define RS_RTT_ITEMS_H - -#include - -#include "rsitems/rsitem.h" -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "serialiser/rsserial.h" - -#include "serialiser/rsserializer.h" - -/**************************************************************************/ - -const uint8_t RS_PKT_SUBTYPE_RTT_PING = 0x01; -const uint8_t RS_PKT_SUBTYPE_RTT_PONG = 0x02; - -class RsRttItem: public RsItem -{ - public: - explicit RsRttItem(uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_RTT,subtype) - { setPriorityLevel(QOS_PRIORITY_RS_RTT_PING) ;} // should be refined later. - - virtual ~RsRttItem() {} - virtual void clear() {} -}; - -class RsRttPingItem: public RsRttItem -{ - public: - RsRttPingItem() - : RsRttItem(RS_PKT_SUBTYPE_RTT_PING) - , mSeqNo(0), mPingTS(0) - {} - - virtual ~RsRttPingItem(){} - virtual void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t mSeqNo; - uint64_t mPingTS; -}; - -class RsRttPongItem: public RsRttItem -{ - public: - RsRttPongItem() - : RsRttItem(RS_PKT_SUBTYPE_RTT_PONG) - , mSeqNo(0), mPingTS(0), mPongTS(0) - {} - - virtual ~RsRttPongItem(){} - virtual void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t mSeqNo; - uint64_t mPingTS; - uint64_t mPongTS; -}; - - -class RsRttSerialiser: public RsServiceSerializer -{ - public: - RsRttSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_RTT) {} - - virtual ~RsRttSerialiser(){} - - virtual RsItem *create_item(uint16_t service,uint8_t type) const; -}; - -/**************************************************************************/ - -#endif /* RS_RTT_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rsserviceids.h b/libretroshare/src/rsitems/rsserviceids.h deleted file mode 100644 index ead349e32..000000000 --- a/libretroshare/src/rsitems/rsserviceids.h +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsserviceids.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "util/rsdeprecate.h" - -#include - -enum class RsServiceType : uint16_t -{ - NONE = 0, /// To detect non-initialized reads - GOSSIP_DISCOVERY = 0x0011, - CHAT = 0x0012, - MSG = 0x0013, - TURTLE = 0x0014, - TUNNEL = 0x0015, - HEARTBEAT = 0x0016, - FILE_TRANSFER = 0x0017, - GROUTER = 0x0018, - FILE_DATABASE = 0x0019, - SERVICEINFO = 0x0020, - BANDWIDTH_CONTROL = 0x0021, - MAIL = 0x0022, - DIRECT_MAIL = 0x0023, - DISTANT_MAIL = 0x0024, - GWEMAIL_MAIL = 0x0025, - SERVICE_CONTROL = 0x0026, - DISTANT_CHAT = 0x0027, - GXS_TUNNEL = 0x0028, - BANLIST = 0x0101, - STATUS = 0x0102, - NXS = 0x0200, - GXSID = 0x0211, - PHOTO = 0x0212, - WIKI = 0x0213, - WIRE = 0x0214, - FORUMS = 0x0215, - POSTED = 0x0216, - CHANNELS = 0x0217, - GXSCIRCLE = 0x0218, - /// not gxs, but used with identities. - REPUTATION = 0x0219, - GXS_RECOGN = 0x0220, - GXS_TRANS = 0x0230, - JSONAPI = 0x0240, - FORUMS_CONFIG = 0x0315, - POSTED_CONFIG = 0x0316, - CHANNELS_CONFIG = 0x0317, - RTT = 0x1011, /// Round Trip Time - - - /***************** IDS ALLOCATED FOR PLUGINS ******************/ - // 2000+ - PLUGIN_ARADO_ID = 0x2001, - PLUGIN_QCHESS_ID = 0x2002, - PLUGIN_FEEDREADER = 0x2003, - - /// Reserved for packet slicing probes. - PACKET_SLICING_PROBE = 0xAABB, - - // Nabu's experimental services. - PLUGIN_FIDO_GW = 0xF1D0, - PLUGIN_ZERORESERVE = 0xBEEF -}; - - - -// TODO: Port all services types to RsServiceType - -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DISC = 0x0011; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_MSG = 0x0013; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_FILE_DATABASE = 0x0019; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021; /// Bandwidth Control -/// New Mail Service (replace old Msg Service) -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102; -/// Rs Network Exchange Service -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_NXS = 0x0200; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_GXSID = 0x0211; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_PHOTO = 0x0212; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_WIKI = 0x0213; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_WIRE = 0x0214; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_FORUMS = 0x0215; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_POSTED = 0x0216; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_GXSCIRCLE = 0x0218; -/// not gxs, but used with identities. -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_REPUTATION = 0x0219; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0x0220; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_GXS_TRANS = 0x0230; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_JSONAPI = 0x0240; -/// used to save notification records in GXS and possible other service-based configuration -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_FORUMS_CONFIG = 0x0315; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_POSTED_CONFIG = 0x0316; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG = 0x0317; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG = 0x0318; - -// Experimental Services. -/* DSDV Testing at the moment - Service Only */ -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_DSDV = 0x1010; -/* Latency RTT Measurements */ -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_RTT = 0x1011; - - -/***************** IDS ALLOCATED FOR PLUGINS ******************/ -// 2000+ - -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_ID = 0x2001; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PLUGIN_QCHESS_ID = 0x2002; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PLUGIN_FEEDREADER = 0x2003; - -// Reserved for packet slicing probes. -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PACKET_SLICING_PROBE = 0xAABB; - -// Nabu's services. -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PLUGIN_FIDO_GW = 0xF1D0; -RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_PLUGIN_ZERORESERVE = 0xBEEF; diff --git a/libretroshare/src/rsitems/rsserviceinfoitems.cc b/libretroshare/src/rsitems/rsserviceinfoitems.cc deleted file mode 100644 index 8d007941d..000000000 --- a/libretroshare/src/rsitems/rsserviceinfoitems.cc +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsserviceinfoitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstypeserializer.h" -#include "rsitems/rsserviceinfoitems.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ -/***** RsServiceInfo ****/ -/*************************************************************************/ - -void RsServiceInfoListItem::clear() -{ - mServiceInfo.clear(); -} - -void RsServiceInfoListItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTlvServiceInfoMapRef map(mServiceInfo); - - RsTypeSerializer::serial_process(j,ctx,map,"map") ; -} - -void RsServiceInfoPermissionsItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,allowedBw,"allowedBw") ; -} - -RsItem *RsServiceInfoSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_TYPE_SERVICEINFO) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_SERVICELIST_ITEM: return new RsServiceInfoListItem() ; - case RS_PKT_SUBTYPE_SERVICEPERMISSIONS_ITEM: return new RsServiceInfoPermissionsItem() ; - default: - return NULL ; - } -} - - - - -template<> std::ostream& RsTlvParamRef::print(std::ostream &out, uint16_t /*indent*/) const -{ - out << "RsServiceInfo: " << mParam.mServiceType << " name " << mParam.mServiceName; - out << std::endl; - out << "Version(" << mParam.mVersionMajor << "," << mParam.mVersionMinor << ")"; - out << " MinVersion(" << mParam.mMinVersionMajor << "," << mParam.mMinVersionMinor << ")"; - out << std::endl; - return out; -} - -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */ - - s += getRawStringSize(mParam.mServiceName); - s += 4; // type. - s += 4; // version. - s += 4; // min version. - return s; -} - -template<> -void RsTlvParamRef::TlvClear() -{ - mParam = RsServiceInfo(); - mParam.mServiceName.clear(); -} - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { - return false; /* not enough space */ - } - - bool ok = true; - - ok &= SetTlvBase(data, tlvend, offset, mParamType, tlvsize); - ok &= setRawString(data, tlvend, offset, mParam.mServiceName); - ok &= setRawUInt32(data, tlvend, offset, mParam.mServiceType); - ok &= setRawUInt16(data, tlvend, offset, mParam.mVersionMajor); - ok &= setRawUInt16(data, tlvend, offset, mParam.mVersionMinor); - ok &= setRawUInt16(data, tlvend, offset, mParam.mMinVersionMajor); - ok &= setRawUInt16(data, tlvend, offset, mParam.mMinVersionMinor); - - if (!ok) - { - std::cerr << "RsTlvParamRef::SetTlv() Failed"; - std::cerr << std::endl; - } - - return ok; -} - -template<> -bool RsTlvParamRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { - return false; /* not enough space */ - } - - if (tlvtype != mParamType) /* check type */ - { - return false; - } - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= getRawString(data, tlvend, offset, mParam.mServiceName); - ok &= getRawUInt32(data, tlvend, offset, &(mParam.mServiceType)); - ok &= getRawUInt16(data, tlvend, offset, &(mParam.mVersionMajor)); - ok &= getRawUInt16(data, tlvend, offset, &(mParam.mVersionMinor)); - ok &= getRawUInt16(data, tlvend, offset, &(mParam.mMinVersionMajor)); - ok &= getRawUInt16(data, tlvend, offset, &(mParam.mMinVersionMinor)); - - return ok; -} - -template class RsTlvParamRef; - diff --git a/libretroshare/src/rsitems/rsserviceinfoitems.h b/libretroshare/src/rsitems/rsserviceinfoitems.h deleted file mode 100644 index e3d04b3c8..000000000 --- a/libretroshare/src/rsitems/rsserviceinfoitems.h +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsserviceinfoitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_SERVICE_INFO_ITEMS_H -#define RS_SERVICE_INFO_ITEMS_H - -// Provides serialiser for p3ServiceControl & p3ServiceInfo. - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rstlvgenericmap.h" -#include "retroshare/rsservicecontrol.h" - -#define RS_PKT_SUBTYPE_SERVICELIST_ITEM 0x01 -#define RS_PKT_SUBTYPE_SERVICEPERMISSIONS_ITEM 0x02 - -/**************************************************************************/ -#define SERVICE_INFO_MAP 0x01 -#define SERVICE_INFO_KEY 0x01 -#define SERVICE_ID 0x01 -#define SERVICE_INFO 0x01 - -class RsTlvServiceInfoMapRef: public RsTlvGenericMapRef -{ -public: - RsTlvServiceInfoMapRef(std::map &refmap) - :RsTlvGenericMapRef( - SERVICE_INFO_MAP, - SERVICE_INFO_KEY, - SERVICE_ID, - SERVICE_INFO, - refmap) - { - return; - } -}; - -class RsServiceInfoListItem: public RsItem -{ - public: - RsServiceInfoListItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_SERVICEINFO, RS_PKT_SUBTYPE_SERVICELIST_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_SERVICE_INFO_ITEM); - return; - } - - virtual ~RsServiceInfoListItem(){} - virtual void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - std::map mServiceInfo; -}; - -class RsServiceInfoPermissionsItem: public RsItem -{ - public: - RsServiceInfoPermissionsItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_SERVICEINFO, RS_PKT_SUBTYPE_SERVICEPERMISSIONS_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_SERVICE_INFO_ITEM); - return; - } - - virtual ~RsServiceInfoPermissionsItem(){} - virtual void clear(){} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - uint32_t allowedBw; // Units are bytes/sec => 4Gb/s; -}; - -class RsServiceInfoSerialiser: public RsServiceSerializer -{ - public: - RsServiceInfoSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_SERVICEINFO) {} - virtual ~RsServiceInfoSerialiser() {} - - virtual RsItem *create_item(uint16_t /* service */, uint8_t /* item_sub_id */) const; -}; - -/**************************************************************************/ - -#endif /* RS_SERVICE_INFO_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rsstatusitems.h b/libretroshare/src/rsitems/rsstatusitems.h deleted file mode 100644 index e92db7816..000000000 --- a/libretroshare/src/rsitems/rsstatusitems.h +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rsstatusitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Vinny Do. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_STATUS_ITEMS_H -#define RS_STATUS_ITEMS_H - -#include "rsitems/rsserviceids.h" -#include "rsitems/itempriorities.h" -#include "rsitems/rsitem.h" - -#include "serialiser/rstypeserializer.h" - -/**************************************************************************/ - -class RsStatusItem: public RsItem -{ -public: - RsStatusItem() :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_STATUS, RS_PKT_SUBTYPE_DEFAULT) - { - setPriorityLevel(QOS_PRIORITY_RS_STATUS_ITEM); - } - virtual ~RsStatusItem() {} - virtual void clear() {} - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) - { - RsTypeSerializer::serial_process(j,ctx,sendTime,"sendTime") ; - RsTypeSerializer::serial_process(j,ctx,status ,"status") ; - } - - uint32_t sendTime; - uint32_t status; - - /* not serialised */ - uint32_t recvTime; -}; - -class RsStatusSerialiser: public RsServiceSerializer -{ -public: - RsStatusSerialiser() :RsServiceSerializer(RS_SERVICE_TYPE_STATUS) {} - virtual ~RsStatusSerialiser() {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const - { - if(service == RS_SERVICE_TYPE_STATUS && item_subtype == RS_PKT_SUBTYPE_DEFAULT) - return new RsStatusItem(); - else - return NULL ; - } -}; - -/**************************************************************************/ - -#endif /* RS_STATUS_ITEMS_H */ - - diff --git a/libretroshare/src/rsitems/rswikiitems.cc b/libretroshare/src/rsitems/rswikiitems.cc deleted file mode 100644 index e7ffa8508..000000000 --- a/libretroshare/src/rsitems/rswikiitems.cc +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rswikiitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rsitems/rswikiitems.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstypeserializer.h" - -#define GXSID_DEBUG 1 - -RsItem *RsGxsWikiSerialiser::create_item(uint16_t service, uint8_t item_sub_id) const -{ - if(service != RS_SERVICE_GXS_TYPE_WIKI) - return NULL ; - - switch(item_sub_id) - { - case RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM: return new RsGxsWikiCollectionItem(); - case RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM: return new RsGxsWikiCommentItem(); - case RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM: return new RsGxsWikiSnapshotItem(); - default: - return NULL ; - } -} - -void RsGxsWikiCollectionItem::clear() -{ - collection.mDescription.clear(); - collection.mCategory.clear(); - collection.mHashTags.clear(); -} - -void RsGxsWikiCollectionItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR ,collection.mDescription,"collection.mDescription") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_CATEGORY,collection.mCategory ,"collection.mCategory") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG,collection.mHashTags ,"collection.mHashTags") ; -} - -void RsGxsWikiSnapshotItem::clear() -{ - snapshot.mPage.clear(); - snapshot.mHashTags.clear(); -} - -void RsGxsWikiSnapshotItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_WIKI_PAGE,snapshot.mPage,"snapshot.mPage") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_HASH_TAG ,snapshot.mPage,"snapshot.mHashTags") ; -} - -void RsGxsWikiCommentItem::clear() -{ - comment.mComment.clear(); -} - -void RsGxsWikiCommentItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_COMMENT,comment.mComment,"comment.mComment") ; -} - diff --git a/libretroshare/src/rsitems/rswikiitems.h b/libretroshare/src/rsitems/rswikiitems.h deleted file mode 100644 index fa5cf1533..000000000 --- a/libretroshare/src/rsitems/rswikiitems.h +++ /dev/null @@ -1,87 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rswikiitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RS_WIKI_ITEMS_H -#define RS_WIKI_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/rsgxsitems.h" - -#include "retroshare/rswiki.h" - -const uint8_t RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM = 0x03; -const uint8_t RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM = 0x04; - -class RsGxsWikiCollectionItem : public RsGxsGrpItem -{ -public: - RsGxsWikiCollectionItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_WIKI, RS_PKT_SUBTYPE_WIKI_COLLECTION_ITEM) {} - virtual ~RsGxsWikiCollectionItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsWikiCollection collection; -}; - -class RsGxsWikiSnapshotItem : public RsGxsMsgItem -{ -public: - - RsGxsWikiSnapshotItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_WIKI, RS_PKT_SUBTYPE_WIKI_SNAPSHOT_ITEM) {} - virtual ~RsGxsWikiSnapshotItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsWikiSnapshot snapshot; -}; - -class RsGxsWikiCommentItem : public RsGxsMsgItem -{ -public: - - RsGxsWikiCommentItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_WIKI, RS_PKT_SUBTYPE_WIKI_COMMENT_ITEM) {} - virtual ~RsGxsWikiCommentItem() {} - void clear(); - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsWikiComment comment; - -}; - -class RsGxsWikiSerialiser : public RsServiceSerializer -{ -public: - - RsGxsWikiSerialiser() :RsServiceSerializer(RS_SERVICE_GXS_TYPE_WIKI) {} - virtual ~RsGxsWikiSerialiser() {} - - virtual RsItem *create_item(uint16_t /* service */, uint8_t /* item_sub_id */) const; -}; - -#endif /* RS_WIKI_ITEMS_H */ diff --git a/libretroshare/src/rsitems/rswireitems.cc b/libretroshare/src/rsitems/rswireitems.cc deleted file mode 100644 index a618336f7..000000000 --- a/libretroshare/src/rsitems/rswireitems.cc +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rswireitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "rswireitems.h" -#include "serialiser/rstypeserializer.h" - -#define WIRE_DEBUG 1 - - -RsItem *RsGxsWireSerialiser::create_item(uint16_t service,uint8_t item_subtype) const -{ - if(service != RS_SERVICE_GXS_TYPE_WIRE) - return NULL ; - - switch(item_subtype) - { - case RS_PKT_SUBTYPE_WIRE_GROUP_ITEM: return new RsGxsWireGroupItem(); - case RS_PKT_SUBTYPE_WIRE_PULSE_ITEM: return new RsGxsWirePulseItem(); - default: - return NULL ; - } -} - -void RsGxsWireGroupItem::clear() -{ - group.mTagline.clear(); - group.mLocation.clear(); - group.mHeadshot.clear(); - group.mMasthead.clear(); -} - -void RsGxsWireGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_DESCR,group.mTagline,"group.mTagline") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_LOCATION,group.mLocation,"group.mLocation") ; - group.mHeadshot.serial_process(j, ctx); - group.mMasthead.serial_process(j, ctx); -} - -void RsGxsWirePulseItem::clear() -{ - pulse.mPulseText.clear(); - pulse.mPulseType = 0; - pulse.mSentiment = 0; - pulse.mRefGroupId.clear(); - pulse.mRefGroupName.clear(); - pulse.mRefOrigMsgId.clear(); - pulse.mRefAuthorId.clear(); - pulse.mRefPublishTs = 0; - pulse.mRefPulseText.clear(); - pulse.mRefImageCount = 0; - - pulse.mImage1.clear(); - pulse.mImage2.clear(); - pulse.mImage3.clear(); - pulse.mImage4.clear(); -} - -void RsGxsWirePulseItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mPulseText,"pulse.mPulseText") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mPulseType,"pulse.mPulseType") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mSentiment,"pulse.mSentiment") ; - RsTypeSerializer::serial_process(j,ctx,pulse.mRefGroupId,"pulse.mRefGroupId") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,pulse.mRefGroupName,"pulse.mRefGroupName") ; - RsTypeSerializer::serial_process(j,ctx,pulse.mRefOrigMsgId,"pulse.mRefOrigMsgId") ; - RsTypeSerializer::serial_process(j,ctx,pulse.mRefAuthorId,"pulse.mRefAuthorId") ; - RsTypeSerializer::serial_process(j,ctx,pulse.mRefPublishTs,"pulse.mRefPublishTs") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,pulse.mRefPulseText,"pulse.mRefPulseText") ; - RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_UINT32_PARAM,pulse.mRefImageCount,"pulse.mRefImageCount") ; - - pulse.mImage1.serial_process(j, ctx); - pulse.mImage2.serial_process(j, ctx); - pulse.mImage3.serial_process(j, ctx); - pulse.mImage4.serial_process(j, ctx); -} - diff --git a/libretroshare/src/rsitems/rswireitems.h b/libretroshare/src/rsitems/rswireitems.h deleted file mode 100644 index 4db5f3d25..000000000 --- a/libretroshare/src/rsitems/rswireitems.h +++ /dev/null @@ -1,76 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsitems: rswireitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RS_WIRE_ITEMS_H -#define RS_WIRE_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserial.h" -//#include "serialiser/rstlvtypes.h" - -#include "rsgxsitems.h" -#include "retroshare/rswire.h" - -const uint8_t RS_PKT_SUBTYPE_WIRE_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_WIRE_PULSE_ITEM = 0x03; - -class RsGxsWireGroupItem : public RsGxsGrpItem -{ - -public: - - RsGxsWireGroupItem(): RsGxsGrpItem(RS_SERVICE_GXS_TYPE_WIRE, RS_PKT_SUBTYPE_WIRE_GROUP_ITEM) {} - virtual ~RsGxsWireGroupItem() {} - - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsWireGroup group; -}; - -class RsGxsWirePulseItem : public RsGxsMsgItem -{ -public: - - RsGxsWirePulseItem(): RsGxsMsgItem(RS_SERVICE_GXS_TYPE_WIRE, RS_PKT_SUBTYPE_WIRE_PULSE_ITEM) {} - virtual ~RsGxsWirePulseItem() {} - void clear(); - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - RsWirePulse pulse; -}; - -class RsGxsWireSerialiser : public RsServiceSerializer -{ -public: - - RsGxsWireSerialiser() :RsServiceSerializer(RS_SERVICE_GXS_TYPE_WIRE) {} - virtual ~RsGxsWireSerialiser() {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const ; -}; - -#endif /* RS_WIKI_ITEMS_H */ diff --git a/libretroshare/src/rsserver/p3face-config.cc b/libretroshare/src/rsserver/p3face-config.cc deleted file mode 100644 index 3251f33eb..000000000 --- a/libretroshare/src/rsserver/p3face-config.cc +++ /dev/null @@ -1,124 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3face-config.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsserver/p3face.h" - -#include -#include "pqi/authssl.h" -#include "pqi/authgpg.h" -#include "retroshare/rsinit.h" -#include "plugins/pluginmanager.h" -#include "util/rsdebug.h" - -#ifdef RS_JSONAPI -# include "jsonapi/jsonapi.h" -#endif // ifdef RS_JSONAPI - -#include -#include "util/rstime.h" - -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - - -// TO SHUTDOWN THREADS. -#ifdef RS_ENABLE_GXS - -#include "services/autoproxy/rsautoproxymonitor.h" - -#include "services/p3idservice.h" -#include "services/p3gxscircles.h" -#include "services/p3wiki.h" -#include "services/p3posted.h" -#include "services/p3photoservice.h" -#include "services/p3gxsforums.h" -#include "services/p3gxschannels.h" -#include "services/p3wire.h" - -#endif - -/****************************************/ -/* RsIface Config */ -/* Config */ - -void RsServer::ConfigFinalSave() -{ - //TODO: force saving of transfers - //ftserver->saveFileTransferStatus(); - -#ifdef RS_AUTOLOGIN - if(!RsInit::getAutoLogin()) RsInit::RsClearAutoLogin(); -#endif // RS_AUTOLOGIN - - //AuthSSL::getAuthSSL()->FinalSaveCertificates(); - mConfigMgr->completeConfiguration(); -} - -void RsServer::startServiceThread(RsTickingThread *t, const std::string &threadName) -{ - t->start(threadName) ; - mRegisteredServiceThreads.push_back(t) ; -} - -void RsServer::rsGlobalShutDown() -{ - coreReady = false; - // TODO: cache should also clean up old files - - ConfigFinalSave(); // save configuration before exit - - mPluginsManager->stopPlugins(pqih); - - mNetMgr->shutdown(); /* Handles UPnP */ - -#ifdef RS_JSONAPI - rsJsonApi->fullstop(); -#endif - - rsAutoProxyMonitor::instance()->stopAllRSShutdown(); - - fullstop() ; - - // kill all registered service threads - - for(std::list::iterator it= mRegisteredServiceThreads.begin();it!=mRegisteredServiceThreads.end();++it) - { - (*it)->fullstop() ; - } -// #ifdef RS_ENABLE_GXS -// // We should automate this. -// // -// if(mGxsCircles) mGxsCircles->join(); -// if(mGxsForums) mGxsForums->join(); -// if(mGxsChannels) mGxsChannels->join(); -// if(mGxsIdService) mGxsIdService->join(); -// if(mPosted) mPosted->join(); -// if(mWiki) mWiki->join(); -// if(mGxsNetService) mGxsNetService->join(); -// if(mPhoto) mPhoto->join(); -// if(mWire) mWire->join(); -// #endif - - AuthGPG::exit(); - - mShutdownCallback(0); -} diff --git a/libretroshare/src/rsserver/p3face-info.cc b/libretroshare/src/rsserver/p3face-info.cc deleted file mode 100644 index 18fdc40aa..000000000 --- a/libretroshare/src/rsserver/p3face-info.cc +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3face-info.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by RetroShare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsserver/p3face.h" -#include -#include -#include - -#ifdef NO_SQLCIPHER -# include -#else -# include -#endif - -#ifdef RS_USE_LIBUPNP -# include -#elif defined(RS_USE_LIBMINIUPNPC) -# include -#endif // def RS_USE_LIBUPNP - -std::string RsServer::getSQLCipherVersion() -{ - sqlite3* mDb; - std::string versionstring(""); - const char* version; - int rc = sqlite3_open_v2("", &mDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE , NULL); //create DB in a temp file - - if(rc){ - std::cerr << "Can't open database, Error code: " << sqlite3_errmsg(mDb) - << std::endl; - sqlite3_close(mDb); - mDb = NULL; - return ""; - } - - std::string sqlQuery = "PRAGMA cipher_version;"; - sqlite3_stmt* stmt = NULL; - rc = sqlite3_prepare_v2(mDb, sqlQuery.c_str(), sqlQuery.length(), &stmt, NULL); - if (rc == SQLITE_OK) { - rc = sqlite3_step(stmt); - switch (rc) { - case SQLITE_ROW: - version = (const char *)sqlite3_column_text(stmt, 0); //not needed to free - versionstring.append(version); - break; - case SQLITE_DONE: - break; - default: - std::cerr << "RetroDb::tableExists(): Error executing statement (code: " << rc << ")" - << std::endl; - break; - } - } - - if (stmt) { - sqlite3_finalize(stmt); - } - sqlite3_close(mDb); // no-op if mDb is NULL (https://www.sqlite.org/c3ref/close.html) - return versionstring; -} - -void RsServer::getLibraries(std::list &libraries) -{ - libraries.push_back(RsLibraryInfo("bzip2", BZ2_bzlibVersion())); - libraries.push_back(RsLibraryInfo("OpenSSL", SSLeay_version(SSLEAY_VERSION))); - libraries.push_back(RsLibraryInfo("SQLite", SQLITE_VERSION)); -#ifndef NO_SQLCIPHER - libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion())); -#endif - -#ifdef RS_USE_LIBUPNP - libraries.push_back(RsLibraryInfo("UPnP (libupnp)", UPNP_VERSION_STRING)); -#elif defined(RS_USE_LIBMINIUPNPC) - libraries.push_back(RsLibraryInfo("UPnP (MiniUPnP)", MINIUPNPC_VERSION)); -#endif // def RS_USE_LIBUPNP - - libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION)); -} diff --git a/libretroshare/src/rsserver/p3face-server.cc b/libretroshare/src/rsserver/p3face-server.cc deleted file mode 100644 index 8642860b8..000000000 --- a/libretroshare/src/rsserver/p3face-server.cc +++ /dev/null @@ -1,275 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3face-server.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2015 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rstime.h" -#include "rsserver/p3face.h" -#include "retroshare/rsplugin.h" - -#include "tcponudp/tou.h" -#include - -#include "pqi/authssl.h" -#include -#include "util/rstime.h" - -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" - -#include "util/rsdebug.h" - -#include "retroshare/rsevents.h" -#include "services/rseventsservice.h" - -/******************* -#define TICK_DEBUG 1 -*******************/ - -#define WARN_BIG_CYCLE_TIME (0.2) - -#ifdef WINDOWS_SYS -#include "util/rstime.h" -#include -#endif - - -/*extern*/ RsControl* rsControl = nullptr; - -static double getCurrentTS() -{ - -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} - -// These values should be tunable from the GUI, to offer a compromise between speed and CPU use. -// In some cases (VOIP) it's likely that we will need to set them temporarily to a very low -// value, in order to favor a fast feedback - -const double RsServer::minTickInterval = 0.05; -const double RsServer::maxTickInterval = 0.2; - - -RsServer::RsServer() : - coreMutex("RsServer"), mShutdownCallback([](int){}), - coreReady(false) -{ - { - RsEventsService* tmpRsEvtPtr = new RsEventsService(); - rsEvents = tmpRsEvtPtr; - startServiceThread(tmpRsEvtPtr, "RsEventsService"); - } - - // This is needed asap. - // - mNotify = new p3Notify() ; - rsNotify = mNotify ; - - mPeerMgr = NULL; - mLinkMgr = NULL; - mNetMgr = NULL; - mHistoryMgr = NULL; - - pqih = NULL; - - mPluginsManager = NULL; - - /* services */ - mHeart = NULL; - mDisc = NULL; - msgSrv = NULL; - chatSrv = NULL; - mStatusSrv = NULL; - mGxsTunnels = NULL; - - /* timers */ - mLastts = getCurrentTS(); - mTickInterval = maxTickInterval ; - mAvgRunDuration = 0; - mLastRunDuration = 0; - mCycle1 = mLastts; - mCycle2 = mLastts; - mCycle3 = mLastts; - mCycle4 = mLastts; - - /* caches (that need ticking) */ - - /* config */ - mConfigMgr = NULL; - mGeneralConfig = NULL; -} - -RsServer::~RsServer() -{ - delete mGxsTrans; -} - -// General Internal Helper Functions ----> MUST BE LOCKED! - -void RsServer::threadTick() -{ -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking interval " << std::dec << (int) (1000 * mTickInterval) << " ms"; -#endif - -// we try to tick at a regular interval depending on the load -// if there is time left, we sleep - double timeToSleep = mTickInterval - mAvgRunDuration; - -// never sleep less than 50 ms - if (timeToSleep < 0.050) - timeToSleep = 0.050; - -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG will sleep " << std::dec << (int) (1000 * timeToSleep) << " ms"; -#endif - rstime::rs_usleep(timeToSleep * 1000000); - - double ts = getCurrentTS(); - mLastts = ts; - -// stuff we do always - // tick the core -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking RS core"; -#endif - lockRsCore(); - int moreToTick = pqih->tick(); - unlockRsCore(); - // tick the managers -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking mPeerMgr"; -#endif - mPeerMgr->tick(); -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking mLinkMgr"; -#endif - mLinkMgr->tick(); -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking mNetMgr"; -#endif - mNetMgr->tick(); - - -// stuff we do every second - if (ts - mCycle1 > 1) - { -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG every second"; -#endif - // slow services - if (rsPlugins) - { -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking slow tick plugins"; -#endif - rsPlugins->slowTickPlugins((rstime_t)ts); - } - // UDP keepalive - // tou_tick_stunkeepalive(); - // other stuff to tick - // update(); - mCycle1 = ts; - } - -// stuff we do every five seconds - if (ts - mCycle2 > 5) - { -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG every 5 seconds"; -#endif - mCycle2 = ts; - } - -// stuff we do every minute - if (ts - mCycle3 > 60) - { -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG every 60 seconds"; -#endif - // force saving FileTransferStatus TODO - // ftserver->saveFileTransferStatus(); - // see if we need to resave certs - // AuthSSL::getAuthSSL()->CheckSaveCertificates(); - mCycle3 = ts; - } - -// stuff we do every hour - if (ts - mCycle4 > 3600) - { -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG every hour"; -#endif - // save configuration files -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG ticking mConfigMgr"; -#endif - mConfigMgr->tick(); - mCycle4 = ts; - } - -// ticking is done, now compute new values of mLastRunDuration, mAvgRunDuration and mTickInterval - ts = getCurrentTS(); - mLastRunDuration = ts - mLastts; - -// low-pass filter and don't let mAvgRunDuration exceeds maxTickInterval - mAvgRunDuration = 0.1 * mLastRunDuration + 0.9 * mAvgRunDuration; - if (mAvgRunDuration > maxTickInterval) - mAvgRunDuration = maxTickInterval; - -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG mLastRunDuration " << std::dec << (int) (1000 * mLastRunDuration) << " ms, mAvgRunDuration " << (int) (1000 * mAvgRunDuration) << " ms"; - if (mLastRunDuration > WARN_BIG_CYCLE_TIME) - RsDbg() << "TICK_DEBUG excessively long cycle time " << std::dec << (int) (1000 * mLastRunDuration) << " ms"; -#endif - -// if the core has returned that there is more to tick we decrease the ticking interval, else we increase it -// TODO: this should be investigated as it seems that the core never returns 1 -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG moreToTick " << moreToTick; -#endif - if (moreToTick == 1) - mTickInterval = 0.9 * mTickInterval; - else - mTickInterval = 1.1 * mTickInterval; -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG new tick interval " << std::dec << (int) (1000 * mTickInterval) << " ms"; -#endif - -// keep the tick interval target within allowed limits - if (mTickInterval < minTickInterval) - mTickInterval = minTickInterval; - else if (mTickInterval > maxTickInterval) - mTickInterval = maxTickInterval; -#ifdef TICK_DEBUG - RsDbg() << "TICK_DEBUG new tick interval after limiter " << std::dec << (int) (1000 * mTickInterval) << " ms"; -#endif -} - diff --git a/libretroshare/src/rsserver/p3face.h b/libretroshare/src/rsserver/p3face.h deleted file mode 100644 index 661cb244f..000000000 --- a/libretroshare/src/rsserver/p3face.h +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3face.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include - -//#include "server/filedexserver.h" -#include "ft/ftserver.h" -//#include "pqi/pqissl.h" - -#include "pqi/p3cfgmgr.h" -#include "pqi/p3notify.h" -#include "pqi/pqipersongrp.h" - -#include "retroshare/rsiface.h" -#include "retroshare/rstypes.h" -#include "util/rsthreads.h" - -#include "chat/p3chatservice.h" -#include "gxstunnel/p3gxstunnel.h" - -#include "services/p3msgservice.h" -#include "services/p3statusservice.h" - -class p3heartbeat; -class p3discovery2; -class p3I2pBob; - -/* GXS Classes - just declare the classes. - so we don't have to totally recompile to switch */ - -class p3IdService; -class p3GxsCircles; -class p3GxsForums; -class p3GxsChannels; -class p3Wiki; -class p3Posted; -class p3PhotoService; -class p3Wire; - - -class p3PeerMgrIMPL; -class p3LinkMgrIMPL; -class p3NetMgrIMPL; -class p3HistoryMgr; -class RsPluginManager; - -/* The Main Interface Class - for controlling the server */ - -/* The init functions are actually Defined in p3face-startup.cc - */ -//RsInit *InitRsConfig(); -//void CleanupRsConfig(RsInit *); -//int InitRetroShare(int argc, char **argv, RsInit *config); -//int LoadCertificates(RsInit *config); - -class RsServer: public RsControl, public RsTickingThread -{ -public: - RsServer(); - virtual ~RsServer(); - - virtual int StartupRetroShare(); - - /// @see RsControl::isReady() - virtual bool isReady() { return coreReady; } - - /// @see RsControl::setShutdownCallback - void setShutdownCallback(const std::function& callback) - { mShutdownCallback = callback; } - - void threadTick() override; /// @see RsTickingThread - - /* locking stuff */ - void lockRsCore() - { - // std::cerr << "RsServer::lockRsCore()" << std::endl; - coreMutex.lock(); - } - - void unlockRsCore() - { - // std::cerr << "RsServer::unlockRsCore()" << std::endl; - coreMutex.unlock(); - } - - static p3Notify *notify() { return dynamic_cast(instance())->mNotify ; } - - private: - - /* mutex */ - RsMutex coreMutex; - - private: - - /****************************************/ - /****************************************/ - /****************************************/ - /****************************************/ - public: - /* Config */ - - virtual void ConfigFinalSave( ); - virtual void startServiceThread(RsTickingThread *t, const std::string &threadName) ; - - /************* Rs shut down function: in upnp 'port lease time' bug *****************/ - - /** - * This function is responsible for ensuring Retroshare exits in a legal state: - * i.e. releases all held resources and saves current configuration - */ - virtual void rsGlobalShutDown(); - - /****************************************/ - - public: - virtual bool getPeerCryptoDetails(const RsPeerId& ssl_id,RsPeerCryptoParams& params) { return pqih->getCryptoParams(ssl_id,params); } - virtual void getLibraries(std::list &libraries); - - private: - - std::string getSQLCipherVersion(); // TODO: move to rsversion.h - - // The real Server Parts. - - //filedexserver *server; - //ftServer *ftserver; - - p3PeerMgrIMPL *mPeerMgr; - p3LinkMgrIMPL *mLinkMgr; - p3NetMgrIMPL *mNetMgr; - p3HistoryMgr *mHistoryMgr; - - pqipersongrp *pqih; - - RsPluginManager *mPluginsManager; - - /* services */ - p3heartbeat *mHeart; - p3discovery2 *mDisc; - p3MsgService *msgSrv; - p3ChatService *chatSrv; - p3StatusService *mStatusSrv; - p3GxsTunnelService *mGxsTunnels; -#ifdef RS_USE_I2P_BOB - p3I2pBob *mI2pBob; -#endif - - // This list contains all threaded services. It will be used to shut them down properly. - - std::list mRegisteredServiceThreads ; - - /* GXS */ -// p3Wiki *mWiki; -// p3Posted *mPosted; -// p3PhotoService *mPhoto; -// p3GxsCircles *mGxsCircles; -// p3GxsNetService *mGxsNetService; -// p3IdService *mGxsIdService; -// p3GxsForums *mGxsForums; -// p3GxsChannels *mGxsChannels; -// p3Wire *mWire; - p3GxsTrans* mGxsTrans; - - /* Config */ - p3ConfigMgr *mConfigMgr; - p3GeneralConfig *mGeneralConfig; - - // notify - p3Notify *mNotify ; - - // Worker Data..... - - double mLastts; - double mTickInterval; - double mLastRunDuration; - double mAvgRunDuration; - double mCycle1, mCycle2, mCycle3, mCycle4; - - static const double minTickInterval; - static const double maxTickInterval; - - /// @see RsControl::setShutdownCallback - std::function mShutdownCallback; - - /** Keep track of the core being fully ready, true only after - * StartupRetroShare() finish and before rsGlobalShutDown() begin - */ - bool coreReady; -}; - -/* Helper function to convert windows paths - * into unix (ie switch \ to /) for FLTK's file chooser - */ - -std::string make_path_unix(std::string winpath); diff --git a/libretroshare/src/rsserver/p3history.cc b/libretroshare/src/rsserver/p3history.cc deleted file mode 100644 index 2818d9339..000000000 --- a/libretroshare/src/rsserver/p3history.cc +++ /dev/null @@ -1,85 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3history.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "p3history.h" -#include "pqi/p3historymgr.h" - -p3History::p3History(p3HistoryMgr* historyMgr) - : mHistoryMgr(historyMgr) -{ -} - -p3History::~p3History() -{ -} - -bool p3History::chatIdToVirtualPeerId(const ChatId &chat_id, RsPeerId &peer_id) -{ - return mHistoryMgr->chatIdToVirtualPeerId(chat_id, peer_id); -} - -void p3History::setMaxStorageDuration(uint32_t seconds) -{ - mHistoryMgr->setMaxStorageDuration(seconds) ; -} -uint32_t p3History::getMaxStorageDuration() -{ - return mHistoryMgr->getMaxStorageDuration() ; -} -bool p3History::getMessages(const ChatId &chatPeerId, std::list &msgs, const uint32_t loadCount) -{ - return mHistoryMgr->getMessages(chatPeerId, msgs, loadCount); -} - -bool p3History::getMessage(uint32_t msgId, HistoryMsg &msg) -{ - return mHistoryMgr->getMessage(msgId, msg); -} - -void p3History::removeMessages(const std::list &msgIds) -{ - mHistoryMgr->removeMessages(msgIds); -} - -void p3History::clear(const ChatId &chatPeerId) -{ - mHistoryMgr->clear(chatPeerId); -} - -bool p3History::getEnable(uint32_t chat_type) -{ - return mHistoryMgr->getEnable(chat_type); -} - -void p3History::setEnable(uint32_t chat_type, bool enable) -{ - mHistoryMgr->setEnable(chat_type, enable); -} - -uint32_t p3History::getSaveCount(uint32_t chat_type) -{ - return mHistoryMgr->getSaveCount(chat_type); -} - -void p3History::setSaveCount(uint32_t chat_type, uint32_t count) -{ - mHistoryMgr->setSaveCount(chat_type, count); -} diff --git a/libretroshare/src/rsserver/p3history.h b/libretroshare/src/rsserver/p3history.h deleted file mode 100644 index 2a75d328d..000000000 --- a/libretroshare/src/rsserver/p3history.h +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3history.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Thunder. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_P3HISTORY_INTERFACE_H -#define RS_P3HISTORY_INTERFACE_H - -#include "retroshare/rshistory.h" - -class p3HistoryMgr; - -//! Implements abstract interface rsHistory -/*! - * Interfaces with p3HistoryMsg - */ -class p3History : public RsHistory -{ -public: - - p3History(p3HistoryMgr* historyMgr); - virtual ~p3History(); - - virtual bool chatIdToVirtualPeerId(const ChatId &chat_id, RsPeerId &peer_id); - virtual bool getMessages(const ChatId &chatPeerId, std::list &msgs, uint32_t loadCount); - virtual bool getMessage(uint32_t msgId, HistoryMsg &msg); - virtual void removeMessages(const std::list &msgIds); - virtual void clear(const ChatId &chatPeerId); - - virtual bool getEnable(uint32_t chat_type); - virtual void setEnable(uint32_t chat_type, bool enable); - - virtual uint32_t getMaxStorageDuration(); - virtual void setMaxStorageDuration(uint32_t seconds); - - // 0 = no limit, >0 count of saved messages - virtual uint32_t getSaveCount(uint32_t chat_type); - virtual void setSaveCount(uint32_t chat_type, uint32_t count); - -private: - p3HistoryMgr* mHistoryMgr; -}; - -#endif /* RS_P3HISTORY_INTERFACE_H */ diff --git a/libretroshare/src/rsserver/p3msgs.cc b/libretroshare/src/rsserver/p3msgs.cc deleted file mode 100644 index b877c0282..000000000 --- a/libretroshare/src/rsserver/p3msgs.cc +++ /dev/null @@ -1,587 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3msgs.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -#include "util/rsdir.h" -#include "util/rsdebug.h" -//const int p3facemsgzone = 11453; - -#include -#include "util/rstime.h" - -#include "retroshare/rstypes.h" -#include "rsserver/p3msgs.h" - -#include "services/p3msgservice.h" -#include "chat/p3chatservice.h" - -#include "pqi/authgpg.h" - -using namespace Rs::Msgs; - -/*extern*/ RsMsgs* rsMsgs = nullptr; - -/****************************************/ -/****************************************/ - -ChatId::ChatId(): - type(TYPE_NOT_SET), - lobby_id(0) -{ - -} - -ChatId::ChatId(RsPeerId id): - lobby_id(0) -{ - type = TYPE_PRIVATE; - peer_id = id; -} - -ChatId::ChatId(DistantChatPeerId id): - lobby_id(0) -{ - type = TYPE_PRIVATE_DISTANT; - distant_chat_id = id; -} - -ChatId::ChatId(ChatLobbyId id): - lobby_id(0) -{ - type = TYPE_LOBBY; - lobby_id = id; -} - -ChatId::ChatId(std::string str) : lobby_id(0) -{ - type = TYPE_NOT_SET; - if(str.empty()) return; - - if(str[0] == 'P') - { - type = TYPE_PRIVATE; - peer_id = RsPeerId(str.substr(1)); - } - else if(str[0] == 'D') - { - type = TYPE_PRIVATE_DISTANT; - distant_chat_id = DistantChatPeerId(str.substr(1)); - } - else if(str[0] == 'L') - { - if(sizeof(ChatLobbyId) != 8) - { - std::cerr << "ChatId::ChatId(std::string) Error: sizeof(ChatLobbyId) != 8. please report this" << std::endl; - return; - } - str = str.substr(1); - if(str.size() != 16) - return; - ChatLobbyId id = 0; - for(int i = 0; i<16; i++) - { - uint8_t c = str[i]; - if(c <= '9') - c -= '0'; - else - c -= 'A' - 10; - id = id << 4; - id |= c; - } - type = TYPE_LOBBY; - lobby_id = id; - } - else if(str[0] == 'B') - { - type = TYPE_BROADCAST; - } -} - -ChatId ChatId::makeBroadcastId() -{ - ChatId id; - id.type = TYPE_BROADCAST; - return id; -} - -std::string ChatId::toStdString() const -{ - std::string str; - if(type == TYPE_PRIVATE) - { - str += "P"; - str += peer_id.toStdString(); - } - else if(type == TYPE_PRIVATE_DISTANT) - { - str += "D"; - str += distant_chat_id.toStdString(); - } - else if(type == TYPE_LOBBY) - { - if(sizeof(ChatLobbyId) != 8) - { - std::cerr << "ChatId::toStdString() Error: sizeof(ChatLobbyId) != 8. please report this" << std::endl; - return ""; - } - str += "L"; - - ChatLobbyId id = lobby_id; - for(int i = 0; i<16; i++) - { - uint8_t c = id >>(64-4); - if(c > 9) - c += 'A' - 10; - else - c += '0'; - str += c; - id = id << 4; - } - } - else if(type == TYPE_BROADCAST) - { - str += "B"; - } - return str; -} - -bool ChatId::operator <(const ChatId& other) const -{ - if(type != other.type) - return type < other.type; - else - { - switch(type) - { - case TYPE_NOT_SET: - return false; - case TYPE_PRIVATE: - return peer_id < other.peer_id; - case TYPE_PRIVATE_DISTANT: - return distant_chat_id < other.distant_chat_id; - case TYPE_LOBBY: - return lobby_id < other.lobby_id; - case TYPE_BROADCAST: - return false; - default: - return false; - } - } -} - -bool ChatId::isSameEndpoint(const ChatId &other) const -{ - if(type != other.type) - return false; - else - { - switch(type) - { - case TYPE_NOT_SET: - return false; - case TYPE_PRIVATE: - return peer_id == other.peer_id; - case TYPE_PRIVATE_DISTANT: - return distant_chat_id == other.distant_chat_id; - case TYPE_LOBBY: - return lobby_id == other.lobby_id; - case TYPE_BROADCAST: - return true; - default: - return false; - } - } -} - -bool ChatId::isNotSet() const -{ - return type == TYPE_NOT_SET; -} -bool ChatId::isPeerId() const -{ - return type == TYPE_PRIVATE; -} -bool ChatId::isDistantChatId() const -{ - return type == TYPE_PRIVATE_DISTANT; -} -bool ChatId::isLobbyId() const -{ - return type == TYPE_LOBBY; -} -bool ChatId::isBroadcast() const -{ - return type == TYPE_BROADCAST; -} -RsPeerId ChatId::toPeerId() const -{ - if(type == TYPE_PRIVATE) - return peer_id; - else - { - std::cerr << "ChatId Warning: conversation to RsPeerId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl; - return RsPeerId(); - } -} - -DistantChatPeerId ChatId::toDistantChatId() const -{ - if(type == TYPE_PRIVATE_DISTANT) - return distant_chat_id; - else - { - std::cerr << "ChatId Warning: conversation to DistantChatPeerId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl; - return DistantChatPeerId(); - } -} -ChatLobbyId ChatId::toLobbyId() const -{ - if(type == TYPE_LOBBY) - return lobby_id; - else - { - std::cerr << "ChatId Warning: conversation to ChatLobbyId requested, but type is different. Current value=\"" << toStdString() << "\"" << std::endl; - return 0; - } -} - -bool p3Msgs::getMessageSummaries(std::list &msgList) -{ - return mMsgSrv->getMessageSummaries(msgList); -} - - -uint32_t p3Msgs::getDistantMessagingPermissionFlags() -{ - return mMsgSrv->getDistantMessagingPermissionFlags(); -} - -void p3Msgs::setDistantMessagingPermissionFlags(uint32_t flags) -{ - return mMsgSrv->setDistantMessagingPermissionFlags(flags); -} - - -bool p3Msgs::getMessage(const std::string &mid, MessageInfo &msg) -{ - return mMsgSrv->getMessage(mid, msg); -} - -void p3Msgs::getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox) -{ - mMsgSrv->getMessageCount(nInbox, nInboxNew, nOutbox, nDraftbox, nSentbox, nTrashbox); -} - -/****************************************/ -/****************************************/ - /* Message Items */ -bool p3Msgs::MessageSend(MessageInfo &info) -{ - return mMsgSrv->MessageSend(info); -} - -uint32_t p3Msgs::sendMail( - const RsGxsId from, - const std::string& subject, - const std::string& body, - const std::set& to, - const std::set& cc, - const std::set& bcc, - const std::vector& attachments, - std::set& trackingIds, - std::string& errorMsg ) -{ - return mMsgSrv->sendMail( - from, subject, body, to, cc, bcc, attachments, - trackingIds, errorMsg ); -} - -bool p3Msgs::SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag) -{ - return mMsgSrv->SystemMessage(title, message, systemFlag); -} - -bool p3Msgs::MessageToDraft(MessageInfo &info, const std::string &msgParentId) -{ - return mMsgSrv->MessageToDraft(info, msgParentId); -} - -bool p3Msgs::MessageToTrash(const std::string &mid, bool bTrash) -{ - return mMsgSrv->MessageToTrash(mid, bTrash); -} - -bool p3Msgs::getMsgParentId(const std::string &msgId, std::string &msgParentId) -{ - return mMsgSrv->getMsgParentId(msgId, msgParentId); -} - -/****************************************/ -/****************************************/ -bool p3Msgs::MessageDelete(const std::string &mid) -{ - //std::cerr << "p3Msgs::MessageDelete() "; - //std::cerr << "mid: " << mid << std::endl; - - return mMsgSrv -> removeMsgId(mid); -} - -bool p3Msgs::MessageRead(const std::string &mid, bool unreadByUser) -{ - //std::cerr << "p3Msgs::MessageRead() "; - //std::cerr << "mid: " << mid << std::endl; - - return mMsgSrv -> markMsgIdRead(mid, unreadByUser); -} - -bool p3Msgs::MessageReplied(const std::string &mid, bool replied) -{ - return mMsgSrv->setMsgFlag(mid, replied ? RS_MSG_FLAGS_REPLIED : 0, RS_MSG_FLAGS_REPLIED); -} - -bool p3Msgs::MessageForwarded(const std::string &mid, bool forwarded) -{ - return mMsgSrv->setMsgFlag(mid, forwarded ? RS_MSG_FLAGS_FORWARDED : 0, RS_MSG_FLAGS_FORWARDED); -} - -bool p3Msgs::MessageLoadEmbeddedImages(const std::string &mid, bool load) -{ - return mMsgSrv->setMsgFlag(mid, load ? RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES : 0, RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES); -} - -bool p3Msgs::getMessageTagTypes(MsgTagType& tags) -{ - return mMsgSrv->getMessageTagTypes(tags); -} - -bool p3Msgs::MessageStar(const std::string &mid, bool star) -{ - return mMsgSrv->setMsgFlag(mid, star ? RS_MSG_FLAGS_STAR : 0, RS_MSG_FLAGS_STAR); -} - -bool p3Msgs::MessageJunk(const std::string &mid, bool junk) -{ - return mMsgSrv->setMsgFlag(mid, junk ? RS_MSG_FLAGS_SPAM : 0, RS_MSG_FLAGS_SPAM); -} - -bool p3Msgs::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) -{ - return mMsgSrv->setMessageTagType(tagId, text, rgb_color); -} - -bool p3Msgs::removeMessageTagType(uint32_t tagId) -{ - return mMsgSrv->removeMessageTagType(tagId); -} - -bool p3Msgs::getMessageTag(const std::string &msgId, MsgTagInfo& info) -{ - return mMsgSrv->getMessageTag(msgId, info); -} - -bool p3Msgs::setMessageTag(const std::string &msgId, uint32_t tagId, bool set) -{ - return mMsgSrv->setMessageTag(msgId, tagId, set); -} - -bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags) -{ - return mMsgSrv->resetMessageStandardTagTypes(tags); -} - -/****************************************/ -/****************************************/ -bool p3Msgs::sendChat(ChatId destination, std::string msg) -{ - return mChatSrv->sendChat(destination, msg); -} - -uint32_t p3Msgs::getMaxMessageSecuritySize(int type) -{ - return mChatSrv->getMaxMessageSecuritySize(type); -} - -void p3Msgs::sendStatusString(const ChatId& id, const std::string& status_string) -{ - mChatSrv->sendStatusString(id, status_string); -} - -void p3Msgs::clearChatLobby(const ChatId &id) -{ - mChatSrv->clearChatLobby(id); -} - -void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size) -{ - mChatSrv->getOwnAvatarJpegData(data,size) ; -} - -void p3Msgs::setOwnAvatarData(const unsigned char *data,int size) -{ - mChatSrv->setOwnAvatarJpegData(data,size) ; -} - -void p3Msgs::getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size) -{ - mChatSrv->getAvatarJpegData(pid,data,size) ; -} - -std::string p3Msgs::getCustomStateString(const RsPeerId& peer_id) -{ - return mChatSrv->getCustomStateString(peer_id) ; -} - -std::string p3Msgs::getCustomStateString() -{ - return mChatSrv->getOwnCustomStateString() ; -} - -void p3Msgs::setCustomStateString(const std::string& state_string) -{ - mChatSrv->setOwnCustomStateString(state_string) ; -} - -bool p3Msgs::getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& linfo) -{ - return mChatSrv->getChatLobbyInfo(id,linfo) ; -} -void p3Msgs::getChatLobbyList(std::list& lids) -{ - mChatSrv->getChatLobbyList(lids) ; -} -void p3Msgs::invitePeerToLobby(const ChatLobbyId& lobby_id, const RsPeerId& peer_id) -{ - mChatSrv->invitePeerToLobby(lobby_id,peer_id) ; -} -void p3Msgs::sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id) -{ - mChatSrv->sendLobbyStatusPeerLeaving(lobby_id) ; -} -void p3Msgs::unsubscribeChatLobby(const ChatLobbyId& lobby_id) -{ - mChatSrv->unsubscribeChatLobby(lobby_id) ; -} -bool p3Msgs::setDefaultIdentityForChatLobby(const RsGxsId& nick) -{ - return mChatSrv->setDefaultIdentityForChatLobby(nick) ; -} -void p3Msgs::getDefaultIdentityForChatLobby(RsGxsId& nick_name) -{ - mChatSrv->getDefaultIdentityForChatLobby(nick_name) ; -} - -bool p3Msgs::setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& nick) -{ - return mChatSrv->setIdentityForChatLobby(lobby_id,nick) ; -} -bool p3Msgs::getIdentityForChatLobby(const ChatLobbyId& lobby_id,RsGxsId& nick_name) -{ - return mChatSrv->getIdentityForChatLobby(lobby_id,nick_name) ; -} - -bool p3Msgs::joinVisibleChatLobby(const ChatLobbyId& lobby_id,const RsGxsId& own_id) -{ - return mChatSrv->joinVisibleChatLobby(lobby_id,own_id) ; -} - -void p3Msgs::getListOfNearbyChatLobbies(std::vector& public_lobbies) -{ - mChatSrv->getListOfNearbyChatLobbies(public_lobbies) ; -} - -ChatLobbyId p3Msgs::createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set& invited_friends,ChatLobbyFlags privacy_type) -{ - return mChatSrv->createChatLobby(lobby_name,lobby_identity,lobby_topic,invited_friends,privacy_type) ; -} - -void p3Msgs::setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe) -{ - mChatSrv->setLobbyAutoSubscribe(lobby_id, autoSubscribe); -} - -bool p3Msgs::getLobbyAutoSubscribe(const ChatLobbyId& lobby_id) -{ - return mChatSrv->getLobbyAutoSubscribe(lobby_id); -} - - -bool p3Msgs::acceptLobbyInvite(const ChatLobbyId& id,const RsGxsId& gxs_id) -{ - return mChatSrv->acceptLobbyInvite(id,gxs_id) ; -} -void p3Msgs::denyLobbyInvite(const ChatLobbyId& id) -{ - mChatSrv->denyLobbyInvite(id) ; -} -void p3Msgs::getPendingChatLobbyInvites(std::list& invites) -{ - mChatSrv->getPendingChatLobbyInvites(invites) ; -} -bool p3Msgs::initiateDistantChatConnexion( - const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, - DistantChatPeerId& pid, uint32_t& error_code, bool notify ) -{ - return mChatSrv->initiateDistantChatConnexion( to_gxs_id, from_gxs_id, pid, error_code, notify ); -} -bool p3Msgs::getDistantChatStatus(const DistantChatPeerId& pid,DistantChatPeerInfo& info) -{ - return mChatSrv->getDistantChatStatus(pid,info) ; -} -bool p3Msgs::closeDistantChatConnexion(const DistantChatPeerId &pid) -{ - return mChatSrv->closeDistantChatConnexion(pid) ; -} -bool p3Msgs::setDistantChatPermissionFlags(uint32_t flags) -{ - return mChatSrv->setDistantChatPermissionFlags(flags) ; -} -uint32_t p3Msgs::getDistantChatPermissionFlags() -{ - return mChatSrv->getDistantChatPermissionFlags() ; -} - -RsMsgs::~RsMsgs() = default; -Rs::Msgs::MessageInfo::~MessageInfo() = default; -MsgInfoSummary::~MsgInfoSummary() = default; -VisibleChatLobbyRecord::~VisibleChatLobbyRecord() = default; - -void RsMailIdRecipientIdPair::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(mMailId); - RS_SERIAL_PROCESS(mRecipientId); -} - -bool RsMailIdRecipientIdPair::operator<(const RsMailIdRecipientIdPair& o) const -{ - return std::tie( mMailId, mRecipientId) < - std::tie(o.mMailId, o.mRecipientId); -} - -bool RsMailIdRecipientIdPair::operator==(const RsMailIdRecipientIdPair& o) const -{ - return std::tie( mMailId, mRecipientId) == - std::tie(o.mMailId, o.mRecipientId); -} diff --git a/libretroshare/src/rsserver/p3msgs.h b/libretroshare/src/rsserver/p3msgs.h deleted file mode 100644 index 91d044ee5..000000000 --- a/libretroshare/src/rsserver/p3msgs.h +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3msgs.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2007-2008 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsmsgs.h" -#include "retroshare/rsgxsifacetypes.h" - -class p3MsgService; -class p3ChatService; - -class RsChatMsgItem; - -//! provides retroshares chatservice and messaging service -/*! - * Provides rs with the ability to send/receive messages, immediate status, - * custom status, avatar and - * chats (public(group) and private) to peers - */ -class p3Msgs: public RsMsgs -{ -public: - - p3Msgs(p3MsgService *p3m, p3ChatService *p3c) : - mMsgSrv(p3m), mChatSrv(p3c) {} - ~p3Msgs() override = default; - - /// @see RsMsgs - uint32_t sendMail( - const RsGxsId from, - const std::string& subject, - const std::string& body, - const std::set& to = std::set(), - const std::set& cc = std::set(), - const std::set& bcc = std::set(), - const std::vector& attachments = std::vector(), - std::set& trackingIds = - RS_DEFAULT_STORAGE_PARAM(std::set), - std::string& errorMsg = - RS_DEFAULT_STORAGE_PARAM(std::string) ) override; - - /****************************************/ - /* Message Items */ - - /*! - * @param msgList ref to list summarising client's msgs - */ - virtual bool getMessageSummaries(std::list &msgList); - virtual bool getMessage(const std::string &mId, Rs::Msgs::MessageInfo &msg); - virtual void getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox); - - RS_DEPRECATED_FOR(sendMail) - virtual bool MessageSend(Rs::Msgs::MessageInfo &info); - virtual bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag); - virtual bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId); - virtual bool MessageToTrash(const std::string &mid, bool bTrash); - virtual bool MessageDelete(const std::string &mid); - virtual bool MessageRead(const std::string &mid, bool unreadByUser); - virtual bool MessageReplied(const std::string &mid, bool replied); - virtual bool MessageForwarded(const std::string &mid, bool forwarded); - virtual bool MessageStar(const std::string &mid, bool star); - virtual bool MessageJunk(const std::string &mid, bool junk); - virtual bool MessageLoadEmbeddedImages(const std::string &mid, bool load); - virtual bool getMsgParentId(const std::string &msgId, std::string &msgParentId); - - virtual bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags); - virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); - virtual bool removeMessageTagType(uint32_t tagId); - - virtual bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); - /* set == false && tagId == 0 --> remove all */ - virtual bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); - - virtual bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags); - - virtual uint32_t getDistantMessagingPermissionFlags() ; - virtual void setDistantMessagingPermissionFlags(uint32_t flags) ; - - /*! - * gets avatar from peer, image data in jpeg format - */ - virtual void getAvatarData(const RsPeerId& pid,unsigned char *& data,int& size); - - /*! - * sets clients avatar, image data should be in jpeg format - */ - virtual void setOwnAvatarData(const unsigned char *data,int size); - - /*! - * retrieve clients avatar, image data in jpeg format - */ - virtual void getOwnAvatarData(unsigned char *& data,int& size); - - /*! - * sets clients custom status (e.g. "i'm tired") - */ - virtual void setCustomStateString(const std::string& status_string) ; - - /*! - * retrieves client's custom status - */ - virtual std::string getCustomStateString() ; - - /*! - * retrieves peer's custom status - */ - virtual std::string getCustomStateString(const RsPeerId& peer_id) ; - - - /*! - * Send a chat message. - * @param destination where to send the chat message - * @param msg the message - * @see ChatId - */ - virtual bool sendChat(ChatId destination, std::string msg) ; - - /*! - * Return the max message size for security forwarding - */ - virtual uint32_t getMaxMessageSecuritySize(int type); - - /*! - * sends immediate status string to a specific peer, e.g. in a private chat - * @param chat_id chat id to send status string to - * @param status_string immediate status to send - */ - virtual void sendStatusString(const ChatId& id, const std::string& status_string) ; - - /** - * @brief clearChatLobby: Signal chat was cleared by GUI. - * @param id: Chat id cleared. - */ - virtual void clearChatLobby(const ChatId &id); - - /****************************************/ - - virtual bool joinVisibleChatLobby(const ChatLobbyId& id, const RsGxsId &own_id) ; - virtual void getListOfNearbyChatLobbies(std::vector& public_lobbies) ; - virtual void getChatLobbyList(std::list& cl_list) ; - virtual bool getChatLobbyInfo(const ChatLobbyId& id,ChatLobbyInfo& info) ; - virtual void invitePeerToLobby(const ChatLobbyId&, const RsPeerId&) ; - virtual bool acceptLobbyInvite(const ChatLobbyId& id, const RsGxsId &gxs_id) ; - virtual void denyLobbyInvite(const ChatLobbyId& id) ; - virtual void getPendingChatLobbyInvites(std::list& invites) ; - virtual void unsubscribeChatLobby(const ChatLobbyId& lobby_id) ; - virtual void sendLobbyStatusPeerLeaving(const ChatLobbyId& lobby_id); - virtual bool setIdentityForChatLobby(const ChatLobbyId& lobby_id,const RsGxsId&) ; - virtual bool getIdentityForChatLobby(const ChatLobbyId&,RsGxsId& nick) ; - virtual bool setDefaultIdentityForChatLobby(const RsGxsId&) ; - virtual void getDefaultIdentityForChatLobby(RsGxsId& nick) ; - virtual void setLobbyAutoSubscribe(const ChatLobbyId& lobby_id, const bool autoSubscribe); - virtual bool getLobbyAutoSubscribe(const ChatLobbyId& lobby_id); - virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const RsGxsId& lobby_identity,const std::string& lobby_topic,const std::set& invited_friends,ChatLobbyFlags privacy_type) ; - - virtual bool initiateDistantChatConnexion( - const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, - DistantChatPeerId &pid, uint32_t& error_code, - bool notify = true ); - - virtual bool getDistantChatStatus(const DistantChatPeerId& gxs_id,DistantChatPeerInfo& info); - virtual bool closeDistantChatConnexion(const DistantChatPeerId &pid) ; - - virtual uint32_t getDistantChatPermissionFlags() ; - virtual bool setDistantChatPermissionFlags(uint32_t flags) ; - - private: - - p3MsgService *mMsgSrv; - p3ChatService *mChatSrv; -}; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc deleted file mode 100644 index 7223eec90..000000000 --- a/libretroshare/src/rsserver/p3peers.cc +++ /dev/null @@ -1,1927 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3peers.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2015-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "pgp/pgpkeyutil.h" - -#include "rsserver/p3peers.h" -#include "rsserver/p3face.h" - -#include "pqi/p3linkmgr.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - -#include "pqi/authssl.h" -#include "pqi/authgpg.h" -#include "retroshare/rsinit.h" -#include "retroshare/rsnotify.h" -#include "retroshare/rsfiles.h" -#include "util/rsurl.h" -#include "util/radix64.h" -#include "util/rsbase64.h" -#include "pgp/rscertificate.h" - -#include -#include - -//static const int MAX_TIME_KEEP_LOCATION_WITHOUT_CONTACT = 30*24*3600 ; // 30 days. - -#include "pqi/authssl.h" - - -RsPeers *rsPeers = NULL; - -/******* - * #define P3PEERS_DEBUG 1 - *******/ - -//int ensureExtension(std::string &name, std::string def_ext); - -std::string RsPeerTrustString(uint32_t trustLvl) -{ - std::string str; - - switch(trustLvl) - { - default: - case RS_TRUST_LVL_UNKNOWN: - str = "VALIDITY_UNKNOWN"; - break; - case RS_TRUST_LVL_UNDEFINED: - str = "VALIDITY_UNDEFINED"; - break; - case RS_TRUST_LVL_NEVER: - str = "VALIDITY_NEVER"; - break; - case RS_TRUST_LVL_MARGINAL: - str = "VALIDITY_MARGINAL"; - break; - case RS_TRUST_LVL_FULL: - str = "VALIDITY_FULL"; - break; - case RS_TRUST_LVL_ULTIMATE: - str = "VALIDITY_ULTIMATE"; - break; - } - return str; -} - -std::string RsPeerNetModeString(uint32_t netModel) -{ - std::string str; - if (netModel == RS_NETMODE_EXT) - { - str = "External Port"; - } - else if (netModel == RS_NETMODE_UPNP) - { - str = "Ext (UPnP)"; - } - else if (netModel == RS_NETMODE_UDP) - { - str = "UDP Mode"; - } - else if (netModel == RS_NETMODE_HIDDEN) - { - str = "Hidden"; - } - else if (netModel == RS_NETMODE_UNREACHABLE) - { - str = "UDP Mode (Unreachable)"; - } - else - { - str = "Unknown NetMode"; - } - return str; -} - - -p3Peers::p3Peers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm) - :mLinkMgr(lm), mPeerMgr(pm), mNetMgr(nm) {} - - /* Updates ... */ -bool p3Peers::FriendsChanged(bool add) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::FriendsChanged()" << std::endl; -#endif - RsServer::notify()->notifyListChange(NOTIFY_LIST_FRIENDS, add? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL); - - /* TODO */ - return false; -} - -bool p3Peers::OthersChanged() -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::OthersChanged()" << std::endl; -#endif - - /* TODO */ - return false; -} - - /* Peer Details (Net & Auth) */ -const RsPeerId& p3Peers::getOwnId() -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getOwnId()" << std::endl; -#endif - - return AuthSSL::getAuthSSL()->OwnId(); -} - -bool p3Peers::getOnlineList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getOnlineList()" << std::endl; -#endif - - /* get from mConnectMgr */ - mLinkMgr->getOnlineList(ids); - return true; -} - -bool p3Peers::getFriendList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getFriendList()" << std::endl; -#endif - - /* get from mConnectMgr */ - mLinkMgr->getFriendList(ids); - return true; -} - -//bool p3Peers::getOthersList(std::list &ids) -//{ -//#ifdef P3PEERS_DEBUG -// std::cerr << "p3Peers::getOthersList()"; -// std::cerr << std::endl; -//#endif -// -// /* get from mAuthMgr */ -// AuthSSL::getAuthSSL()->getAllList(ids); -// return true; -//} - -bool p3Peers::getPeersCount( - uint32_t& peersCount, uint32_t& onlinePeersCount, - bool countLocations ) -{ - peersCount = mPeerMgr->getFriendCount(countLocations, false); - onlinePeersCount = mPeerMgr->getFriendCount(countLocations, true); - return true; -} - -bool p3Peers::getPeerCount (unsigned int *friendCount, unsigned int *onlineCount, bool ssl) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerCount()" << std::endl; -#endif - - if (friendCount) *friendCount = mPeerMgr->getFriendCount(ssl, false); - if (onlineCount) *onlineCount = mPeerMgr->getFriendCount(ssl, true); - - return true; -} - -bool p3Peers::isOnline(const RsPeerId &id) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::isOnline() " << id << std::endl; -#endif - - /* get from mConnectMgr */ - peerConnectState state; - if (mLinkMgr->getFriendNetStatus(id, state) && - (state.state & RS_PEER_S_CONNECTED)) - { - return true; - } - return false; -} - -bool p3Peers::isFriend(const RsPeerId &ssl_id) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::isFriend() " << ssl_id << std::endl; -#endif - - /* get from mConnectMgr */ - return mPeerMgr->isFriend(ssl_id); -} - -bool p3Peers::getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) -{ - return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ; -} -bool p3Peers::getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) -{ - return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ; -} - -bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) -{ - return mPeerMgr->setMaxRates(pid,maxUploadRate,maxDownloadRate) ; -} - -bool p3Peers::haveSecretKey(const RsPgpId& id) -{ - return AuthGPG::getAuthGPG()->haveSecretKey(id); -} - -/* There are too many dependancies of this function - * to shift it immeidately - */ - -bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerDetails() called for id : " << id << std::endl; -#endif - - RsPeerId sOwnId = AuthSSL::getAuthSSL()->OwnId(); - peerState ps; - - if (id == sOwnId) - { - mPeerMgr->getOwnNetStatus(ps); - ps.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); - } - else if (!mPeerMgr->getFriendNetStatus(id, ps)) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerDetails() ERROR not an SSL Id: " << id << std::endl; -#endif - return false; - } - - /* get from gpg (first), to fill in the sign and trust details */ - /* don't return now, we've got fill in the ssl and connection info */ - - if(!getGPGDetails(ps.gpg_id, d)) - { - if(!ps.skip_pgp_signature_validation) - return false; - - d.gpg_id = ps.gpg_id ; - d.skip_pgp_signature_validation = true; - } - else - d.skip_pgp_signature_validation = false; - - d.isOnlyGPGdetail = false; - - //get the ssl details - d.id = id; - d.location = ps.location; - - d.service_perm_flags = mPeerMgr->servicePermissionFlags(ps.gpg_id); - - /* generate */ - d.authcode = "AUTHCODE"; - - /* fill from pcs */ - d.lastConnect = ps.lastcontact; - d.connectPeriod = 0; - - if (ps.hiddenNode) - { - d.isHiddenNode = true; - d.hiddenNodeAddress = ps.hiddenDomain; - d.hiddenNodePort = ps.hiddenPort; - d.hiddenType = ps.hiddenType; - - if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised. - { - d.localAddr = "INVALID_IP"; - d.localPort = 0 ; - } - else - { - d.localAddr = sockaddr_storage_iptostring(ps.localaddr); - d.localPort = sockaddr_storage_port(ps.localaddr); - } - d.extAddr = "hidden"; - d.extPort = 0; - d.dyndns = ""; - } - else - { - d.isHiddenNode = false; - d.hiddenNodeAddress = ""; - d.hiddenNodePort = 0; - d.hiddenType = RS_HIDDEN_TYPE_NONE; - - if(!sockaddr_storage_isnull(ps.localaddr)) - { - sockaddr_storage_ipv6_to_ipv4(ps.localaddr); - d.localAddr = sockaddr_storage_iptostring(ps.localaddr); - d.localPort = sockaddr_storage_port(ps.localaddr); - } - else - { - d.localAddr = "INVALID_IP"; - d.localPort = 0; - } - - if(!sockaddr_storage_isnull(ps.serveraddr)) - { - sockaddr_storage_ipv6_to_ipv4(ps.serveraddr); - d.extAddr = sockaddr_storage_iptostring(ps.serveraddr); - d.extPort = sockaddr_storage_port(ps.serveraddr); - } - else - { - d.extAddr = "INVALID_IP"; - d.extPort = 0; - } - - d.dyndns = ps.dyndns; - - std::list::iterator it; - for(it = ps.ipAddrs.mLocal.mAddrs.begin(); - it != ps.ipAddrs.mLocal.mAddrs.end(); ++it) - { - sockaddr_storage_ipv6_to_ipv4(it->mAddr); - std::string toto; - toto += sockaddr_storage_tostring(it->mAddr); - rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime); - d.ipAddressList.push_back(toto); - } - for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it) - { - sockaddr_storage_ipv6_to_ipv4(it->mAddr); - std::string toto; - toto += sockaddr_storage_tostring(it->mAddr); - rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime); - d.ipAddressList.push_back(toto); - } - } - - - switch(ps.netMode & RS_NET_MODE_ACTUAL) - { - case RS_NET_MODE_EXT: - d.netMode = RS_NETMODE_EXT; - break; - case RS_NET_MODE_UPNP: - d.netMode = RS_NETMODE_UPNP; - break; - case RS_NET_MODE_UDP: - d.netMode = RS_NETMODE_UDP; - break; - case RS_NET_MODE_HIDDEN: - d.netMode = RS_NETMODE_HIDDEN; - break; - case RS_NET_MODE_UNREACHABLE: - case RS_NET_MODE_UNKNOWN: - default: - d.netMode = RS_NETMODE_UNREACHABLE; - break; - } - - d.vs_disc = ps.vs_disc; - d.vs_dht = ps.vs_dht; - - /* Translate */ - peerConnectState pcs; - if (!mLinkMgr->getFriendNetStatus(id, pcs)) - { - if(id != sOwnId) - std::cerr << "p3Peers::getPeerDetails() ERROR No Link Information : " << id << std::endl; - return true; - } - -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerDetails() got a SSL id and is returning SSL and GPG details for id : " << id << std::endl; -#endif - - if (pcs.state & RS_PEER_S_CONNECTED) - { - sockaddr_storage_ipv6_to_ipv4(pcs.connectaddr); - d.connectAddr = sockaddr_storage_iptostring(pcs.connectaddr); - d.connectPort = sockaddr_storage_port(pcs.connectaddr); - } - else - { - d.connectAddr = ""; - d.connectPort = 0 ; - } - - d.state = 0; - if (pcs.state & RS_PEER_S_FRIEND) d.state |= RS_PEER_STATE_FRIEND; - if (pcs.state & RS_PEER_S_ONLINE) d.state |= RS_PEER_STATE_ONLINE; - if (pcs.state & RS_PEER_S_CONNECTED) d.state |= RS_PEER_STATE_CONNECTED; - if (pcs.state & RS_PEER_S_UNREACHABLE) d.state |= RS_PEER_STATE_UNREACHABLE; - - d.actAsServer = pcs.actAsServer; - - d.linkType = pcs.linkType; - - /* Finally determine AutoConnect Status */ - d.foundDHT = pcs.dht.found; - - d.connectState = RS_PEER_CONNECTSTATE_OFFLINE; - d.connectStateString.clear(); - - if (pcs.inConnAttempt) - { - if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) { - d.connectState = RS_PEER_CONNECTSTATE_TRYING_TCP; - d.connectStateString = sockaddr_storage_tostring(pcs.currentConnAddrAttempt.addr); - } else if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_UDP_ALL) { - d.connectState = RS_PEER_CONNECTSTATE_TRYING_UDP; - d.connectStateString = sockaddr_storage_tostring(pcs.currentConnAddrAttempt.addr); - } - } - else if (pcs.state & RS_PEER_S_CONNECTED) - { - /* 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; - d.deniedTS = pcs.deniedTS; - - return true; -} - -bool p3Peers::isProxyAddress(const uint32_t type, const sockaddr_storage& addr) -{ - uint16_t port ; - std::string string_addr; - uint32_t status ; - - if(!getProxyServer(type, string_addr, port, status)) - return false ; - - return sockaddr_storage_iptostring(addr)==string_addr && sockaddr_storage_port(addr)==port ; -} - -bool p3Peers::isKeySupported(const RsPgpId& id) -{ - return AuthGPG::getAuthGPG()->isKeySupported(id); -} - -std::string p3Peers::getGPGName(const RsPgpId &gpg_id) -{ - /* get from mAuthMgr as it should have more peers? */ - return AuthGPG::getAuthGPG()->getGPGName(gpg_id); -} - -bool p3Peers::isPgpFriend(const RsPgpId& pgpId) -{ return AuthGPG::getAuthGPG()->isGPGAccepted(pgpId); } - -bool p3Peers::isSslOnlyFriend(const RsPeerId& sslId) -{ - bool has_ssl_only_flag = mPeerMgr->isSslOnlyFriend(sslId) ; - - if(has_ssl_only_flag) - { - if(isPgpFriend(getGPGId(sslId))) - { - RsErr() << __PRETTY_FUNCTION__ << ": Peer " << sslId << " has SSL-friend-only flag but his PGP id is in the list of friends. This is inconsistent (Bug in the code). Returning false for security reasons." << std::endl; - return false; - } - return true; - } - return false; -} - -bool p3Peers::isGPGAccepted(const RsPgpId &gpg_id_is_friend) -{ return isPgpFriend(gpg_id_is_friend); } - -std::string p3Peers::getPeerName(const RsPeerId& ssl) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerName() " << ssl_or_gpg_id << std::endl; -#endif - std::string name; - if (ssl == AuthSSL::getAuthSSL()->OwnId()) - return AuthGPG::getAuthGPG()->getGPGOwnName(); - - if (mPeerMgr->getPeerName(ssl, name)) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPeerName() got a ssl id. Name is : " << name << std::endl; -#endif - return name; - } - return std::string() ; -} - - -bool p3Peers::getGPGAllList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getGPGAllList()" << std::endl; -#endif - - /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGAllList(ids); - return true; -} - -bool p3Peers::getGPGValidList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPGPOthersList()" << std::endl; -#endif - - /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGValidList(ids); - return true; -} - -bool p3Peers::getGPGSignedList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPGPOthersList()" << std::endl; -#endif - - /* get from mAuthMgr */ - AuthGPG::getAuthGPG()->getGPGSignedList(ids); - return true; -} - -bool p3Peers::getPgpFriendList(std::vector& pgpIds) -{ - std::list ids; - if(AuthGPG::getAuthGPG()->getGPGAcceptedList(ids)) - { - pgpIds.clear(); - std::copy(ids.begin(), ids.end(), std::back_inserter(pgpIds)); - return true; - } - return false; -} - -bool p3Peers::getGPGAcceptedList(std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getGPGAcceptedList()" << std::endl; -#endif - AuthGPG::getAuthGPG()->getGPGAcceptedList(ids); - return true; -} - - -bool p3Peers::getAssociatedSSLIds(const RsPgpId &gpg_id, std::list &ids) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getAssociatedSSLIds() for id : " << gpg_id << std::endl; -#endif - - return mPeerMgr->getAssociatedPeers(gpg_id, ids); -} - -bool p3Peers::gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason /* = "" */) -{ - return AuthGPG::getAuthGPG()->SignDataBin(data,len,sign,signlen, reason); -} - -RsPgpId p3Peers::pgpIdFromFingerprint(const RsPgpFingerprint& fpr) -{ - return PGPHandler::pgpIdFromFingerprint(fpr); -} - -bool p3Peers::getGPGDetails(const RsPgpId &pgp_id, RsPeerDetails &d) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPgpDetails() called for id : " << pgp_id << std::endl; -#endif - - /* get from mAuthMgr */ - bool res = AuthGPG::getAuthGPG()->getGPGDetails(pgp_id, d); - - d.isOnlyGPGdetail = true ; - d.service_perm_flags = mPeerMgr->servicePermissionFlags(pgp_id) ; - - return res ; -} - -const RsPgpId& p3Peers::getGPGOwnId() -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPGPOwnId()" << std::endl; -#endif - - /* get from mAuthMgr */ - return AuthGPG::getAuthGPG()->getGPGOwnId(); -} - -RsPgpId p3Peers::getGPGId(const RsPeerId& sslid) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getPGPId()" << std::endl; -#endif - - /* get from mAuthMgr */ - if (sslid == AuthSSL::getAuthSSL()->OwnId()) - { - return AuthGPG::getAuthGPG()->getGPGOwnId(); - } - peerState pcs; - if (mPeerMgr->getFriendNetStatus(sslid, pcs)) - return pcs.gpg_id; - - return RsPgpId(); -} - - - /* These Functions are now the only way to authorize a new gpg user... - * if we are passed a ssl_id, then use it... otherwise just auth gpg_id - */ - - /* Add/Remove Friends */ -bool p3Peers::addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePermissionFlags perm_flags) -{ - -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() with : id : " << id << "; gpg_id : " << gpg_id << std::endl; -#endif - if(AuthGPG::getAuthGPG()->isGPGId(gpg_id)) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() Authorising GPG Id: " << gpg_id << std::endl; -#endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpg_id, true)) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() Authorization OK." << std::endl; -#endif - } - else - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() Authorization FAILED." << std::endl; -#endif - return false; - } - } - else - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() Bad gpg_id : " << gpg_id << std::endl; -#endif - return false; - } - - if(ssl_id.isNull()) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addFriend() WARNING id is NULL or gpgId" << std::endl; -#endif - return true; - } - - FriendsChanged(true); - - /* otherwise - we install as ssl_id..... - * If we are adding an SSL certificate. we flag lastcontact as now. - * This will cause the SSL certificate to be retained for 30 days... and give the person a chance to connect! - * */ - rstime_t now = time(NULL); - return mPeerMgr->addFriend(ssl_id, gpg_id, RS_NET_MODE_UDP, RS_VS_DISC_FULL, RS_VS_DHT_FULL, now, perm_flags); -} - -bool p3Peers::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id,const RsPeerDetails& details ) -{ - if( mPeerMgr->addSslOnlyFriend(sslId, pgp_id,details)) - { - FriendsChanged(true); - return true; - } - else - return false; -} - -bool p3Peers::removeKeysFromPGPKeyring(const std::set& pgp_ids,std::string& backup_file,uint32_t& error_code) -{ - return AuthGPG::getAuthGPG()->removeKeysFromPGPKeyring(pgp_ids,backup_file,error_code) ; -} - -bool p3Peers::removeFriendLocation(const RsPeerId &sslId) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeFriendLocation() " << sslId << std::endl; -#endif - //will remove if it's a ssl id - mPeerMgr->removeFriend(sslId, false); - return true; - -} - -bool p3Peers::removeFriend(const RsPgpId& gpgId) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeFriend() " << gpgId << std::endl; -#endif - if (gpgId == AuthGPG::getAuthGPG()->getGPGOwnId()) { - std::cerr << "p3Peers::removeFriend() ERROR we're not going to remove our own GPG id." << std::endl; - return false; - } - -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeFriend() Removing GPG Id: " << gpgId << std::endl; -#endif - if (AuthGPG::getAuthGPG()->AllowConnection(gpgId, false)) - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeFriend() OK." << std::endl; -#endif - mPeerMgr->removeAllFriendLocations(gpgId); - return true; - } - else - { -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeFriend() FAILED." << std::endl; -#endif - mPeerMgr->removeAllFriendLocations(gpgId); - return false; - } -} - - - - /* Network Stuff */ -bool p3Peers::connectAttempt(const RsPeerId &id) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::connectAttempt() " << id << std::endl; -#endif - - return mLinkMgr->retryConnect(id); -} - -void p3Peers::getIPServersList(std::list& ip_servers) -{ - mNetMgr->getIPServersList(ip_servers) ; -} -bool p3Peers::resetOwnExternalAddressList() -{ - return mPeerMgr->resetOwnExternalAddressList(); -} -void p3Peers::allowServerIPDetermination(bool b) -{ - mNetMgr->setIPServersEnabled(b) ; -} - -bool p3Peers::getAllowServerIPDetermination() -{ - return mNetMgr->getIPServersEnabled() ; -} - -bool p3Peers::setLocation(const RsPeerId &ssl_id, const std::string &location) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setLocation() " << ssl_id << std::endl; -#endif - - return mPeerMgr->setLocation(ssl_id, location); -} - - -bool splitAddressString(const std::string &addr, std::string &domain, uint16_t &port) -{ - std::cerr << "splitAddressString() Input: " << addr << std::endl; - - size_t cpos = addr.rfind(':'); - if (cpos == std::string::npos) - { - std::cerr << "splitAddressString Failed to parse (:)"; - std::cerr << std::endl; - return false; - } - - int lenport = addr.length() - (cpos + 1); // +1 to skip over : char. - if (lenport <= 0) - { - std::cerr << "splitAddressString() Missing Port "; - std::cerr << std::endl; - return false; - } - - domain = addr.substr(0, cpos); - std::string portstr = addr.substr(cpos + 1, std::string::npos); - int portint = atoi(portstr.c_str()); - - if ((portint < 0) || (portint > 65535)) - { - std::cerr << "splitAddressString() Invalid Port"; - std::cerr << std::endl; - return false; - } - port = portint; - - std::cerr << "splitAddressString() Domain: " << domain << " Port: " << port; - std::cerr << std::endl; - return true; -} - - -bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setHiddenNode() " << id << std::endl; -#endif - - std::string domain; - uint16_t port; - if (!splitAddressString(hidden_node_address, domain, port)) - { - return false; - } - mPeerMgr->setNetworkMode(id, RS_NET_MODE_HIDDEN); - mPeerMgr->setHiddenDomainPort(id, domain, port); - return true; -} - - -bool p3Peers::isHiddenNode(const RsPeerId &id) -{ - return mPeerMgr->isHiddenNode(id) ; -} - -bool p3Peers::setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setHiddenNode() " << id << std::endl; -#endif - std::cerr << "p3Peers::setHiddenNode() Domain: " << address << " Port: " << port; - std::cerr << std::endl; - - mPeerMgr->setNetworkMode(id, RS_NET_MODE_HIDDEN); - mPeerMgr->setHiddenDomainPort(id, address, port); - return true; -} - -bool p3Peers::addPeerLocator(const RsPeerId &ssl_id, const RsUrl& locator) -{ return mPeerMgr->addPeerLocator(ssl_id, locator); } - -bool p3Peers::setLocalAddress(const RsPeerId &id, - const std::string &addr_str, uint16_t port) -{ -#ifdef P3PEERS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " " - << port << std::endl; -#endif - - sockaddr_storage addr; - if (sockaddr_storage_inet_pton(addr, addr_str)) - if (sockaddr_storage_setport(addr, port)) - return mPeerMgr->setLocalAddress(id, addr); - return false; -} - -bool p3Peers::setExtAddress(const RsPeerId &id, - const std::string &addr_str, uint16_t port) -{ -#ifdef P3PEERS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " " << id << " " << addr_str << " " - << port << std::endl; -#endif - - sockaddr_storage addr; - if (sockaddr_storage_inet_pton(addr, addr_str)) - if (sockaddr_storage_setport(addr, port)) - return mPeerMgr->setExtAddress(id, addr); - return false; -} - -bool p3Peers::setDynDNS(const RsPeerId &id, const std::string &dyndns) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setDynDNS() called with id: " << id << " dyndns: " << dyndns <setDynDNS(id, dyndns); -} - -bool p3Peers::setNetworkMode(const RsPeerId &id, uint32_t extNetMode) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setNetworkMode() " << id << std::endl; -#endif - - /* translate */ - uint32_t netMode = 0; - switch(extNetMode) - { - case RS_NETMODE_EXT: - netMode = RS_NET_MODE_EXT; - break; - case RS_NETMODE_UPNP: - netMode = RS_NET_MODE_UPNP; - break; - case RS_NETMODE_UDP: - netMode = RS_NET_MODE_UDP; - break; - case RS_NETMODE_HIDDEN: - netMode = RS_NET_MODE_HIDDEN; - break; - case RS_NETMODE_UNREACHABLE: - netMode = RS_NET_MODE_UNREACHABLE; - break; - default: - break; - } - - return mPeerMgr->setNetworkMode(id, netMode); -} - - -bool p3Peers::setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::setVisState() " << id << std::endl; -#endif - std::cerr << "p3Peers::setVisState() " << id << " DISC: " << vs_disc; - std::cerr << " DHT: " << vs_dht << std::endl; - - return mPeerMgr->setVisState(id, vs_disc, vs_dht); -} - -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(type, proxy_addr); - addr = sockaddr_storage_iptostring(proxy_addr); - port = sockaddr_storage_port(proxy_addr); - mPeerMgr->getProxyServerStatus(type, status); - return true; -} - -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; - #endif - - if(port < 1024) - { - std::cerr << "(EE) attempt to set proxy server address to something not allowed: " << addr_str << ":" << port << std::endl; - return false ; - } - - std::cerr << "Settign proxy server address to " << addr_str << ":" << port << std::endl; - - struct sockaddr_storage addr; - struct sockaddr_in *addrv4p = (struct sockaddr_in *) &addr; - addrv4p->sin_family = AF_INET; - addrv4p->sin_port = htons(port); - - int ret = 1; -/********************************** WINDOWS/UNIX SPECIFIC PART *******************/ -#ifndef WINDOWS_SYS - if (ret && (0 != inet_aton(addr_str.c_str(), &(addrv4p->sin_addr)))) -#else - addrv4p->sin_addr.s_addr = inet_addr(addr_str.c_str()); - if (ret) -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART *******************/ - { - return mPeerMgr->setProxyServerAddress(type, addr); - } - else - { - std::cerr << "p3Peers::setProxyServer() Failed to Parse Address" << std::endl; - } - - return false; -} - - - - - -//=========================================================================== - /* Auth Stuff */ - -std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) -{ - rs_owner_ptr mem_block = nullptr; - size_t mem_block_size = 0; - - if( !AuthGPG::getAuthGPG()->exportPublicKey( - RsPgpId(pgp_id), mem_block, mem_block_size, - false, include_signatures ) ) - { - RsErr() << __PRETTY_FUNCTION__ - << " Failure retriving certificate for id " << pgp_id - << std::endl; - return ""; - } - - RsPeerDetails details; - if(!getGPGDetails(pgp_id, details)) return ""; - - auto certPtr = - RsCertificate::fromMemoryBlock(details, mem_block, mem_block_size); - - free(mem_block); - - if(certPtr) return certPtr->armouredPGPKey(); - - return ""; -} - - -bool p3Peers::GetPGPBase64StringAndCheckSum( - const RsPgpId& gpg_id, - std::string& gpg_base64_string, std::string& gpg_base64_checksum ) -{ - gpg_base64_string = "" ; - gpg_base64_checksum = "" ; - - rs_owner_ptr mem_block = nullptr; - size_t mem_block_size = 0; - if(!AuthGPG::getAuthGPG()->exportPublicKey( - gpg_id,mem_block,mem_block_size,false,false )) - return false; - - RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false); - - uint32_t crc = PGPKeyManagement::compute24bitsCRC(mem_block,mem_block_size); - - free(mem_block); - - unsigned char tmp[3] = { - uint8_t((crc >> 16) & 0xff), - uint8_t((crc >> 8) & 0xff), - uint8_t(crc & 0xff) } ; - RsBase64::encode(tmp, 3, gpg_base64_checksum, true, false); - - return true; -} - -enum class RsShortInviteFieldType : uint8_t -{ - SSL_ID = 0x00, - PEER_NAME = 0x01, - LOCATOR = 0x02, - PGP_FINGERPRINT = 0x03, - CHECKSUM = 0x04, - - /* The following will be deprecated, and ported to LOCATOR when generic - * trasport layer will be implemented */ - HIDDEN_LOCATOR = 0x90, - DNS_LOCATOR = 0x91, - EXT4_LOCATOR = 0x92, // external IPv4 address - LOC4_LOCATOR = 0x93 // local IPv4 address -}; - -static void addPacketHeader(RsShortInviteFieldType ptag, size_t size, unsigned char *& buf, uint32_t& offset, uint32_t& buf_size) -{ - // Check that the buffer has sufficient size. If not, increase it. - - while(offset + size + 6 >= buf_size) - { - unsigned char *newbuf = new unsigned char[2*buf_size] ; - - memcpy(newbuf, buf, buf_size) ; - buf_size *= 2 ; - delete[] buf ; - buf = newbuf ; - } - - // Write ptag and size - - buf[offset] = static_cast(ptag) ; - offset += 1 ; - - offset += PGPKeyParser::write_125Size(&buf[offset],size) ; -} - -bool p3Peers::getShortInvite(std::string& invite, const RsPeerId& _sslId, RetroshareInviteFlags invite_flags, const std::string& baseUrl ) -{ - RsPeerId sslId = _sslId; - if(sslId.isNull()) sslId = getOwnId(); - - RsPeerDetails tDetails; - if(!getPeerDetails(sslId, tDetails)) return false; - - uint32_t buf_size = 100; - uint32_t offset = 0; - unsigned char *buf = (unsigned char*)malloc(buf_size); - - addPacketHeader(RsShortInviteFieldType::SSL_ID,RsPeerId::SIZE_IN_BYTES,buf,offset,buf_size); - sslId.serialise(buf,buf_size,offset); - - addPacketHeader(RsShortInviteFieldType::PGP_FINGERPRINT,RsPgpFingerprint::SIZE_IN_BYTES,buf,offset,buf_size); - tDetails.fpr.serialise(buf,buf_size,offset); - - addPacketHeader(RsShortInviteFieldType::PEER_NAME,tDetails.name.size(),buf,offset,buf_size); - memcpy(&buf[offset],tDetails.name.c_str(),tDetails.name.size()); - offset += tDetails.name.size(); - - /* If it is a hidden node, always use hidden address and port as locator */ - - if(tDetails.isHiddenNode) - { - addPacketHeader(RsShortInviteFieldType::HIDDEN_LOCATOR,4 + 2 + tDetails.hiddenNodeAddress.size(),buf,offset,buf_size); - - buf[offset+0] = (uint8_t)((tDetails.hiddenType >> 24) & 0xff); - buf[offset+1] = (uint8_t)((tDetails.hiddenType >> 16) & 0xff); - buf[offset+2] = (uint8_t)((tDetails.hiddenType >> 8) & 0xff); - buf[offset+3] = (uint8_t)((tDetails.hiddenType ) & 0xff); - - buf[offset+4] = (uint8_t)((tDetails.hiddenNodePort >> 8) & 0xff); - buf[offset+5] = (uint8_t)((tDetails.hiddenNodePort ) & 0xff); - - memcpy(&buf[offset+6],tDetails.hiddenNodeAddress.c_str(),tDetails.hiddenNodeAddress.size()); - offset += 4 + 2 + tDetails.hiddenNodeAddress.size(); - } - - if( !!(invite_flags & RetroshareInviteFlags::DNS) && !tDetails.dyndns.empty() && (tDetails.extPort || tDetails.localPort)) - { - uint16_t tPort = tDetails.extPort ? tDetails.extPort : tDetails.localPort; - - addPacketHeader(RsShortInviteFieldType::DNS_LOCATOR, 2 + tDetails.dyndns.size(),buf,offset,buf_size); - - buf[offset+0] = (uint8_t)((tPort >> 8) & 0xff); - buf[offset+1] = (uint8_t)((tPort ) & 0xff); - - memcpy(&buf[offset+2],tDetails.dyndns.c_str(),tDetails.dyndns.size()); - offset += 2 + tDetails.dyndns.size(); - } - - if( !!(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY) && (!tDetails.ipAddressList.empty())) - for(auto& s: tDetails.ipAddressList) - { - const std::string& tLc = s; - std::string tLocator = tLc.substr(0, tLc.find_first_of(" ")-1); - - addPacketHeader(RsShortInviteFieldType::LOCATOR, tLocator.size(),buf,offset,buf_size); - memcpy(&buf[offset],tLocator.c_str(),tLocator.size()); - - offset += tLocator.size(); - } - else if( !!(invite_flags & RetroshareInviteFlags::CURRENT_IP) ) // only add at least the local and external IPs - { -#ifdef USE_NEW_LOCATOR_SYSTEM - // This new locator system as some advantages, but here it also has major drawbacks: (1) it cannot differentiate local and external addresses, - // and (2) it's quite larger than the old system, which tends to make certificates more than 1 line long. - - sockaddr_storage tLocal; - - if(sockaddr_storage_inet_pton(tLocal, tDetails.localAddr) && sockaddr_storage_isValidNet(tLocal) && tDetails.localPort ) - { - addPacketHeader(RsShortInviteFieldType::LOCATOR, tDetails.localAddr.size(),buf,offset,buf_size); - memcpy(&buf[offset],tDetails.localAddr.c_str(),tDetails.localAddr.size()); - - offset += tDetails.localAddr.size(); - } - sockaddr_storage tExt; - - if(sockaddr_storage_inet_pton(tExt, tDetails.extAddr) && sockaddr_storage_isValidNet(tExt) && tDetails.extPort ) - { - addPacketHeader(RsShortInviteFieldType::LOCATOR, tDetails.extAddr.size(),buf,offset,buf_size); - memcpy(&buf[offset],tDetails.extAddr.c_str(),tDetails.extAddr.size()); - - offset += tDetails.extAddr.size(); - } -#else - sockaddr_storage tLocal; - if(sockaddr_storage_inet_pton(tLocal, tDetails.localAddr) && sockaddr_storage_isValidNet(tLocal) && sockaddr_storage_ipv6_to_ipv4(tLocal) && tDetails.localPort ) - { - uint32_t t4Addr = reinterpret_cast(tLocal).sin_addr.s_addr; - - addPacketHeader(RsShortInviteFieldType::LOC4_LOCATOR, 4 + 2,buf,offset,buf_size); - - buf[offset+0] = (uint8_t)((t4Addr >> 24) & 0xff); - buf[offset+1] = (uint8_t)((t4Addr >> 16) & 0xff); - buf[offset+2] = (uint8_t)((t4Addr >> 8) & 0xff); - buf[offset+3] = (uint8_t)((t4Addr ) & 0xff); - - buf[offset+4] = (uint8_t)((tDetails.localPort >> 8) & 0xff); - buf[offset+5] = (uint8_t)((tDetails.localPort ) & 0xff); - - offset += 4+2; - } - - sockaddr_storage tExt; - if(sockaddr_storage_inet_pton(tExt, tDetails.extAddr) && sockaddr_storage_isValidNet(tExt) && sockaddr_storage_ipv6_to_ipv4(tExt) && tDetails.extPort ) - { - uint32_t t4Addr = reinterpret_cast(tExt).sin_addr.s_addr; - - addPacketHeader(RsShortInviteFieldType::EXT4_LOCATOR, 4 + 2,buf,offset,buf_size); - - buf[offset+0] = (uint8_t)((t4Addr >> 24) & 0xff); - buf[offset+1] = (uint8_t)((t4Addr >> 16) & 0xff); - buf[offset+2] = (uint8_t)((t4Addr >> 8) & 0xff); - buf[offset+3] = (uint8_t)((t4Addr ) & 0xff); - - buf[offset+4] = (uint8_t)((tDetails.extPort >> 8) & 0xff); - buf[offset+5] = (uint8_t)((tDetails.extPort ) & 0xff); - - offset += 4+2; - } -#endif - - } - - uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(buf,offset) ; - - // handle endian issues. - unsigned char mem[3] ; - mem[0] = computed_crc & 0xff ; - mem[1] = (computed_crc >> 8 ) & 0xff ; - mem[2] = (computed_crc >> 16) & 0xff ; - - addPacketHeader( RsShortInviteFieldType::CHECKSUM,3,buf,offset,buf_size); - memcpy(&buf[offset],mem,3); - offset += 3; - - Radix64::encode(buf, static_cast(offset), invite); - - if(!(invite_flags & RetroshareInviteFlags::RADIX_FORMAT)) - { - RsUrl inviteUrl(baseUrl); - inviteUrl.setQueryKV("rsInvite", invite); - invite = inviteUrl.toString(); - } - - return true; -} - -bool p3Peers::parseShortInvite(const std::string& inviteStrUrl, RsPeerDetails& details, uint32_t &err_code ) -{ - if(inviteStrUrl.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " can't parse empty invite" - << std::endl; - return false; - } - std::string rsInvite = inviteStrUrl; - - RsUrl inviteUrl(inviteStrUrl); - - if(inviteUrl.hasQueryK("rsInvite")) - rsInvite = *inviteUrl.getQueryV("rsInvite"); - - std::vector bf = Radix64::decode(rsInvite); - size_t size = bf.size(); - - unsigned char* buf = bf.data(); - size_t total_s = 0; - bool CRC_ok = false ; // not checked yet - - while(total_s < size) - { - RsShortInviteFieldType ptag = RsShortInviteFieldType(buf[0]); - buf = &buf[1]; - - unsigned char *buf2 = buf; - uint32_t s = 0; - - try { s = PGPKeyParser::read_125Size(buf); } - catch (...) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return false; - } - - total_s += 1 + ( reinterpret_cast(buf) - reinterpret_cast(buf2) ); - - if(total_s > size) - { - err_code = CERTIFICATE_PARSING_ERROR_SIZE_ERROR; - return false; - } - - Dbg3() << __PRETTY_FUNCTION__ << " Read ptag: " - << static_cast(ptag) - << ", size " << s << ", total_s = " << total_s - << ", expected total = " << size << std::endl; - - switch(ptag) - { - case RsShortInviteFieldType::SSL_ID: - details.id = RsPeerId::fromBufferUnsafe(buf) ; - break; - - case RsShortInviteFieldType::PEER_NAME: - details.name = std::string((char*)buf,s); - break; - - case RsShortInviteFieldType::PGP_FINGERPRINT: - details.fpr = RsPgpFingerprint::fromBufferUnsafe(buf); - details.gpg_id = PGPHandler::pgpIdFromFingerprint(details.fpr); - break; - - case RsShortInviteFieldType::LOCATOR: - { - std::string locatorStr((char*)buf,s); - details.ipAddressList.push_back(locatorStr); - } - break; - - case RsShortInviteFieldType::DNS_LOCATOR: - details.extPort = (((int)buf[0]) << 8) + buf[1]; - details.dyndns = std::string((char*)&buf[2],s-2); - break; - - case RsShortInviteFieldType::LOC4_LOCATOR: - { - uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - sockaddr_in tLocalAddr; - tLocalAddr.sin_addr.s_addr = t4Addr; - - details.localAddr = rs_inet_ntoa(tLocalAddr.sin_addr); - details.localPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; - } - break; - - case RsShortInviteFieldType::EXT4_LOCATOR: - { - uint32_t t4Addr = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - sockaddr_in tExtAddr; - tExtAddr.sin_addr.s_addr = t4Addr; - - details.extAddr = rs_inet_ntoa(tExtAddr.sin_addr); - details.extPort = (((uint32_t)buf[4])<<8) + (uint32_t)buf[5]; - } - break; - - case RsShortInviteFieldType::HIDDEN_LOCATOR: - details.hiddenType = (((uint32_t)buf[0]) << 24)+(((uint32_t)buf[1])<<16)+(((uint32_t)buf[2])<<8) + (uint32_t)buf[3]; - details.hiddenNodePort = (((uint32_t)buf[4]) << 8)+ (uint32_t)buf[5]; - details.isHiddenNode = true; - details.hiddenNodeAddress = std::string((char*)&buf[6],s-6); - break; - - case RsShortInviteFieldType::CHECKSUM: - { - if(s != 3 || total_s+3 != size) // make sure the checksum is the last section - { - err_code = CERTIFICATE_PARSING_ERROR_INVALID_CHECKSUM_SECTION; - return false; - } - uint32_t computed_crc = PGPKeyManagement::compute24bitsCRC(bf.data(),size-5); - uint32_t certificate_crc = static_cast( buf[0] + (buf[1] << 8) + (buf[2] << 16) ); - - if(computed_crc != certificate_crc) - { - err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; - return false; - } - CRC_ok = true; - break; - } - - } - - buf = &buf[s]; - total_s += s; - } - - // now check if the PGP key is available. If so, add it in the PeerDetails: - - RsPeerDetails pgp_det ; - if(getGPGDetails(PGPHandler::pgpIdFromFingerprint(details.fpr),pgp_det) && pgp_det.fpr == details.fpr) - { - details.issuer = pgp_det.issuer; - details.gpg_id = pgp_det.gpg_id; - details.gpgSigners = pgp_det.gpgSigners; - details.trustLvl = pgp_det.trustLvl; - details.validLvl = pgp_det.validLvl; - details.ownsign = pgp_det.ownsign; - details.hasSignedMe = pgp_det.hasSignedMe; - details.accept_connection = pgp_det.accept_connection; - } - else - details.skip_pgp_signature_validation = true; - - if(!CRC_ok) - { - err_code = CERTIFICATE_PARSING_ERROR_CHECKSUM_ERROR; - return false; - } - if(details.gpg_id.isNull()) - { - err_code = CERTIFICATE_PARSING_ERROR_MISSING_PGP_FINGERPRINT; - return false; - } - if(details.id.isNull()) - { - err_code = CERTIFICATE_PARSING_ERROR_MISSING_LOCATION_ID; - return false; - } - err_code = CERTIFICATE_PARSING_ERROR_NO_ERROR; - return true; -} - -bool p3Peers::acceptInvite( const std::string& invite, - ServicePermissionFlags flags ) -{ - if(invite.empty()) return false; - - const std::string* radixPtr(&invite); - - RsUrl url(invite); - std::map query(url.query()); - - if(query.find("radix") != query.end()) - radixPtr = &query["radix"]; - - const std::string& radix(*radixPtr); - if(radix.empty()) return false; - - RsPgpId pgpId; - RsPeerId sslId; - std::string errorString; - - if(!loadCertificateFromString(radix, sslId, pgpId, errorString)) - return false; - - RsPeerDetails peerDetails; - uint32_t errorCode; - - if(!loadDetailsFromStringCert(radix, peerDetails, errorCode)) - return false; - - if(peerDetails.gpg_id.isNull()) - return false; - - addFriend(peerDetails.id, peerDetails.gpg_id, flags); - - if (!peerDetails.location.empty()) - setLocation(peerDetails.id, peerDetails.location); - - // Update new address even the peer already existed. - if (peerDetails.isHiddenNode) - { - setHiddenNode( peerDetails.id, - peerDetails.hiddenNodeAddress, - peerDetails.hiddenNodePort ); - } - else - { - //let's check if there is ip adresses in the certificate. - if (!peerDetails.extAddr.empty() && peerDetails.extPort) - setExtAddress( peerDetails.id, - peerDetails.extAddr, - peerDetails.extPort ); - if (!peerDetails.localAddr.empty() && peerDetails.localPort) - setLocalAddress( peerDetails.id, - peerDetails.localAddr, - peerDetails.localPort ); - if (!peerDetails.dyndns.empty()) - setDynDNS(peerDetails.id, peerDetails.dyndns); - for(auto&& ipr : peerDetails.ipAddressList) - addPeerLocator( - peerDetails.id, - RsUrl(ipr.substr(0, ipr.find(' '))) ); - } - - return true; -} - -std::string p3Peers::GetRetroshareInvite( const RsPeerId& sslId, RetroshareInviteFlags invite_flags) -{ -#ifdef P3PEERS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - const RsPeerId& ssl_id(sslId.isNull() ? getOwnId() : sslId); - - //add the sslid, location, ip local and external address after the signature - RsPeerDetails detail; - std::string invite; - - if (getPeerDetails(ssl_id, detail)) - { - if(!(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY) || detail.isHiddenNode) - detail.ipAddressList.clear(); - - unsigned char *mem_block = nullptr; - size_t mem_block_size = 0; - - if(!AuthGPG::getAuthGPG()->exportPublicKey( RsPgpId(detail.gpg_id), mem_block, mem_block_size, false, !!(invite_flags & RetroshareInviteFlags::PGP_SIGNATURES) )) - { - std::cerr << "Cannot output certificate for id \"" << detail.gpg_id - << "\". Sorry." << std::endl; - return ""; - } - - RsCertificate cert(detail, mem_block, mem_block_size); - free(mem_block); - - return cert.toStdString(); - } - -#ifdef P3PEERS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " returns : \n" << invite << std::endl; -#endif - return invite; -} - -//=========================================================================== - -bool p3Peers::loadCertificateFromString( - const std::string& cert, RsPeerId& ssl_id, - RsPgpId& gpg_id, std::string& error_string ) -{ - uint32_t errNum = 0; - auto crt = RsCertificate::fromString(cert, errNum); - - if(!crt) - { - error_string = "RsCertificate failed with errno: " - + std::to_string(errNum) + " parsing: " + cert; - return false; - } - - RsPgpId gpgid; - bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string ); - - gpg_id = gpgid; - ssl_id = crt->sslid(); - - // now get all friends who declare this key ID to be the one needed to check connections, and clear their "skip_pgp_signature_validation" flag - - if(res) - { - mPeerMgr->notifyPgpKeyReceived(gpgid); - FriendsChanged(true); - } - - return res; -} -bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) -{ - bool res = AuthGPG::getAuthGPG()->LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string ); - - if(res) - mPeerMgr->notifyPgpKeyReceived(gpg_id); - - return res; -} - -bool p3Peers::loadDetailsFromStringCert( const std::string &certstr, - RsPeerDetails &pd, - uint32_t& error_code ) -{ - Dbg3() << __PRETTY_FUNCTION__ << std::endl; - - auto certPtr = RsCertificate::fromString(certstr, error_code); - if(!certPtr) return false; - - RsCertificate& cert = *certPtr; - - if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( - cert.pgp_key(), cert.pgp_key_size(), - pd.gpg_id, pd.name, pd.gpgSigners )) - return false; - - Dbg4() << __PRETTY_FUNCTION__ << " Parsing cert for sslid, location, ext " - << " and local address details. : " << certstr << std::endl; - - pd.id = cert.sslid(); - pd.location = cert.location_name_string(); - - pd.isOnlyGPGdetail = pd.id.isNull(); - pd.service_perm_flags = RS_NODE_PERM_DEFAULT; - - if (!cert.hidden_node_string().empty()) - { - pd.isHiddenNode = true; - - std::string domain; - uint16_t port; - if (splitAddressString(cert.hidden_node_string(), domain, port)) - { - pd.hiddenNodeAddress = domain; - pd.hiddenNodePort = port; - pd.hiddenType = mPeerMgr->hiddenDomainToHiddenType(domain); - } - } - else - { - pd.isHiddenNode = false; - pd.localAddr = cert.loc_ip_string(); - pd.localPort = cert.loc_port_us(); - pd.extAddr = cert.ext_ip_string(); - pd.extPort = cert.ext_port_us(); - pd.dyndns = cert.dns_string(); - for(const RsUrl& locator : cert.locators()) - pd.ipAddressList.push_back(locator.toString()); - } - - return true; -} - -bool p3Peers::cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code) -{ - RsCertificate::Format format ; - - bool res = RsCertificate::cleanCertificate(certstr,cleanCert,format,error_code,true) ; - - if(format == RsCertificate::RS_CERTIFICATE_RADIX) - is_short_format = false; - else if(format == RsCertificate::RS_CERTIFICATE_SHORT_RADIX) - is_short_format = true; - else - return false ; - - return res; -} - -std::string p3Peers::saveCertificateToString(const RsPeerId &id) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::SaveCertificateToString() " << id; - std::cerr << std::endl; -#endif - if (id == AuthSSL::getAuthSSL()->OwnId()) { - return AuthSSL::getAuthSSL()->SaveOwnCertificateToString(); - } else { - return ""; - } -} - -bool p3Peers::signGPGCertificate(const RsPgpId &id, const std::string &gpg_passphrase) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::SignCertificate() " << id; - std::cerr << std::endl; -#endif - rsNotify->cachePgpPassphrase(gpg_passphrase); - rsNotify->setDisableAskPassword(true); - - bool res = AuthGPG::getAuthGPG()->SignCertificateLevel0(id); - - rsNotify->clearPgpPassphrase(); - rsNotify->setDisableAskPassword(false); - - return res; -} - -bool p3Peers::trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::TrustCertificate() " << id; - std::cerr << std::endl; -#endif - return AuthGPG::getAuthGPG()->TrustCertificate(id, trustlvl); -} - - /* Group Stuff */ -bool p3Peers::addGroup(RsGroupInfo &groupInfo) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::addGroup()" << std::endl; -#endif - - bool res = mPeerMgr->addGroup(groupInfo); - rsFiles->updateSinceGroupPermissionsChanged() ; - return res ; -} - -bool p3Peers::editGroup(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::editGroup()" << std::endl; -#endif - - bool res = mPeerMgr->editGroup(groupId, groupInfo); - rsFiles->updateSinceGroupPermissionsChanged() ; - - return res ; -} - -bool p3Peers::removeGroup(const RsNodeGroupId &groupId) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::removeGroup()" << std::endl; -#endif - - bool res = mPeerMgr->removeGroup(groupId); - rsFiles->updateSinceGroupPermissionsChanged() ; - return res ; -} - -bool p3Peers::getGroupInfoByName(const std::string& groupName, RsGroupInfo &groupInfo) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getGroupInfo()" << std::endl; -#endif - - return mPeerMgr->getGroupInfoByName(groupName, groupInfo); -} -bool p3Peers::getGroupInfo(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getGroupInfo()" << std::endl; -#endif - - return mPeerMgr->getGroupInfo(groupId, groupInfo); -} - -bool p3Peers::getGroupInfoList(std::list &groupInfoList) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::getGroupInfoList()" << std::endl; -#endif - - return mPeerMgr->getGroupInfoList(groupInfoList); -} - -bool p3Peers::assignPeerToGroup(const RsNodeGroupId &groupId, const RsPgpId& peerId, bool assign) -{ - std::list peerIds; - peerIds.push_back(peerId); - - return assignPeersToGroup(groupId, peerIds, assign); -} - -bool p3Peers::assignPeersToGroup(const RsNodeGroupId &groupId, const std::list &peerIds, bool assign) -{ -#ifdef P3PEERS_DEBUG - std::cerr << "p3Peers::assignPeersToGroup()" << std::endl; -#endif - - bool res = mPeerMgr->assignPeersToGroup(groupId, peerIds, assign); - rsFiles->updateSinceGroupPermissionsChanged() ; - - return res ; -} - -FileSearchFlags p3Peers::computePeerPermissionFlags(const RsPeerId& peer_ssl_id, - FileStorageFlags share_flags, - const std::list& directory_parent_groups) -{ - // We should be able to do that in O(1), using groups based on packs of bits. - // - // But for now, because the implementation of groups is not totally decided yet, we revert to this - // very simple algorithm. - // - - bool found = directory_parent_groups.empty() ; // by default, empty list means browsable by everyone. - RsPgpId pgp_id = getGPGId(peer_ssl_id) ; - - for(std::list::const_iterator it(directory_parent_groups.begin());it!=directory_parent_groups.end() && !found;++it) - { - RsGroupInfo info ; - if(!getGroupInfo(*it,info)) - { - std::cerr << "(EE) p3Peers::computePeerPermissionFlags: no group named " << *it << ": cannot get info." << std::endl; - continue ; - } - - found = found || (info.peerIds.find(pgp_id) != info.peerIds.end()) ; - - //for(std::set::const_iterator it2(info.peerIds.begin());it2!=info.peerIds.end() && !found;++it2) - // if(*it2 == pgp_id) - // found = true ; - } - - bool network_wide = (share_flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) ;//|| ( (share_flags & DIR_FLAGS_NETWORK_WIDE_GROUPS) && found) ; - bool browsable = (share_flags & DIR_FLAGS_BROWSABLE) && found ; - bool searchable = (share_flags & DIR_FLAGS_ANONYMOUS_SEARCH) ; - - FileSearchFlags final_flags ; - - if(network_wide) final_flags |= RS_FILE_HINTS_NETWORK_WIDE ; - if(browsable ) final_flags |= RS_FILE_HINTS_BROWSABLE ; - if(searchable ) final_flags |= RS_FILE_HINTS_SEARCHABLE ; - - return final_flags ; -} - -RsPeerDetails::RsPeerDetails() - :isOnlyGPGdetail(false), - name(""),email(""),location(""), - org(""),authcode(""), - trustLvl(0), validLvl(0),skip_pgp_signature_validation(false),ownsign(false), - hasSignedMe(false),accept_connection(false), - state(0),actAsServer(false), - connectPort(0), - isHiddenNode(false), - hiddenNodePort(0), - hiddenType(RS_HIDDEN_TYPE_NONE), - localAddr(""),localPort(0),extAddr(""),extPort(0),netMode(0),vs_disc(0), vs_dht(0), - lastConnect(0),lastUsed(0),connectState(0),connectStateString(""), - connectPeriod(0), - foundDHT(false), wasDeniedConnection(false), deniedTS(0), - linkType ( RS_NET_CONN_TRANS_TCP_UNKNOWN) {} - -RsGroupInfo::RsGroupInfo() : flag(0) {} - -ServicePermissionFlags p3Peers::servicePermissionFlags(const RsPeerId& ssl_id) -{ - return mPeerMgr->servicePermissionFlags(ssl_id) ; -} -ServicePermissionFlags p3Peers::servicePermissionFlags(const RsPgpId& gpg_id) -{ - return mPeerMgr->servicePermissionFlags(gpg_id) ; -} -void p3Peers::setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) -{ - mPeerMgr->setServicePermissionFlags(gpg_id,flags) ; -} - -RsPeerStateChangedEvent::RsPeerStateChangedEvent(RsPeerId sslId) : - RsEvent(RsEventType::PEER_STATE_CHANGED), mSslId(sslId) {} - -RsPeers::~RsPeers() = default; -RsAuthSslConnectionAutenticationEvent::~RsAuthSslConnectionAutenticationEvent() = default; -RsConnectionEvent::~RsConnectionEvent() = default; diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h deleted file mode 100644 index 9b0a7666f..000000000 --- a/libretroshare/src/rsserver/p3peers.h +++ /dev/null @@ -1,201 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3peers.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_P3_PEER_INTERFACE_H -#define RETROSHARE_P3_PEER_INTERFACE_H -/* get OS-specific definitions for: - * struct sockaddr_storage - */ -#ifndef WINDOWS_SYS - #include -#else - #include -#endif - -#include "retroshare/rspeers.h" -#include "util/rsurl.h" -#include "util/rsdeprecate.h" -#include "util/rsdebug.h" - -class p3LinkMgr; -class p3PeerMgr; -class p3NetMgr; - - -class p3Peers: public RsPeers -{ -public: - - p3Peers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm); - virtual ~p3Peers() {} - - /* Updates ... */ - virtual bool FriendsChanged(bool add); - virtual bool OthersChanged(); - - /* Peer Details (Net & Auth) */ - virtual const RsPeerId& getOwnId() override; - - virtual bool haveSecretKey(const RsPgpId& gpg_id) override; - - virtual bool getOnlineList(std::list &ids) override; - virtual bool getFriendList(std::list &ids) override; - virtual bool getPeersCount( - uint32_t& peersCount, uint32_t& onlinePeersCount, - bool countLocations ) override; - - RS_DEPRECATED - virtual bool getPeerCount (unsigned int *friendCount, unsigned int *onlineCount, bool ssl) override; - - virtual bool isOnline(const RsPeerId &id) override; - virtual bool isFriend(const RsPeerId &id) override; - virtual bool isPgpFriend(const RsPgpId& pgpId) override; - - /// @see RsPeers - bool isSslOnlyFriend(const RsPeerId& sslId) override; - - RS_DEPRECATED_FOR(isPgpFriend) - virtual bool isGPGAccepted(const RsPgpId &gpg_id_is_friend) override; - - virtual std::string getGPGName(const RsPgpId &gpg_id) override; - virtual std::string getPeerName(const RsPeerId& ssl_or_gpg_id) override; - virtual bool getPeerDetails(const RsPeerId& ssl_or_gpg_id, RsPeerDetails &d) override; - - /* Using PGP Ids */ - virtual const RsPgpId& getGPGOwnId() override; - virtual RsPgpId getGPGId(const RsPeerId &ssl_id) override; - virtual bool isKeySupported(const RsPgpId& ids) override; - - /// @see RsPeers - bool getPgpFriendList(std::vector& pgpIds) override; - - RS_DEPRECATED_FOR(getPgpFriendList) - virtual bool getGPGAcceptedList(std::list &ids) override; - virtual bool getGPGSignedList(std::list &ids) override; - virtual bool getGPGValidList(std::list &ids) override; - virtual bool getGPGAllList(std::list &ids) override; - virtual bool getGPGDetails(const RsPgpId &id, RsPeerDetails &d) override; - virtual bool getAssociatedSSLIds(const RsPgpId& gpg_id, std::list &ids) override; - virtual bool gpgSignData(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, std::string reason = "") override; - - virtual RsPgpId pgpIdFromFingerprint(const RsPgpFingerprint& fpr) override; - - /* Add/Remove Friends */ - virtual bool addFriend(const RsPeerId &ssl_id, const RsPgpId &gpg_id,ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT) override; - - /// @see RsPeers - bool addSslOnlyFriend( - const RsPeerId& sslId, - const RsPgpId& pgp_id, - const RsPeerDetails& details = RsPeerDetails() ) override; - - virtual bool removeFriend(const RsPgpId& gpgid) override; - virtual bool removeFriendLocation(const RsPeerId& sslId) override; - - /* keyring management */ - virtual bool removeKeysFromPGPKeyring(const std::set &pgp_ids,std::string& backup_file,uint32_t& error_code) override; - - /* Network Stuff */ - virtual bool connectAttempt(const RsPeerId &id) override; - virtual bool setLocation(const RsPeerId &ssl_id, const std::string &location) override;//location is shown in the gui to differentiate ssl certs - virtual bool setHiddenNode(const RsPeerId &id, const std::string &hidden_node_address) override; - virtual bool setHiddenNode(const RsPeerId &id, const std::string &address, uint16_t port) override; - virtual bool isHiddenNode(const RsPeerId &id) override; - - virtual bool addPeerLocator(const RsPeerId &ssl_id, const RsUrl& locator) override; - virtual bool setLocalAddress(const RsPeerId &id, const std::string &addr, uint16_t port) override; - virtual bool setExtAddress(const RsPeerId &id, const std::string &addr, uint16_t port) override; - virtual bool setDynDNS(const RsPeerId &id, const std::string &dyndns) override; - virtual bool setNetworkMode(const RsPeerId &id, uint32_t netMode) override; - virtual bool setVisState(const RsPeerId &id, uint16_t vs_disc, uint16_t vs_dht) override; - - virtual bool getProxyServer(const uint32_t type, std::string &addr, uint16_t &port,uint32_t& status) override; - virtual bool setProxyServer(const uint32_t type, const std::string &addr, const uint16_t port) override; - virtual bool isProxyAddress(const uint32_t type, const sockaddr_storage &addr); - - virtual void getIPServersList(std::list& ip_servers) override; - virtual void allowServerIPDetermination(bool) override; - virtual bool getAllowServerIPDetermination() override; - virtual bool resetOwnExternalAddressList() override; - - /* Auth Stuff */ - // Get the invitation (GPG cert + local/ext address + SSL id for the given peer) - virtual std::string GetRetroshareInvite(const RsPeerId& ssl_id = RsPeerId(), RetroshareInviteFlags invite_flags = RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP ) override; - - RS_DEPRECATED /// @see RsPeers - std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) override; - - virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum); - - /// @see RsPeers - bool getShortInvite(std::string& invite, const RsPeerId& sslId = RsPeerId(), - RetroshareInviteFlags invite_flags = RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::DNS, - const std::string& baseUrl = "https://retroshare.me/" ) override; - - /// @see RsPeers - bool parseShortInvite(const std::string& invite, RsPeerDetails& details, uint32_t &err_code ) override; - - /// @see RsPeers::acceptInvite - virtual bool acceptInvite( - const std::string& invite, - ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) override; - - virtual bool loadCertificateFromString(const std::string& cert, RsPeerId& ssl_id,RsPgpId& pgp_id, std::string& error_string) override; - virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string ) override; - virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, uint32_t& error_code) override; - - virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, uint32_t& error_code) override; - virtual std::string saveCertificateToString(const RsPeerId &id) override; - - virtual bool signGPGCertificate(const RsPgpId &id,const std::string& gpg_passphrase) override; - virtual bool trustGPGCertificate(const RsPgpId &id, uint32_t trustlvl) override; - - /* Group Stuff */ - virtual bool addGroup(RsGroupInfo &groupInfo) override; - virtual bool editGroup(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) override; - virtual bool removeGroup(const RsNodeGroupId &groupId) override; - virtual bool getGroupInfo(const RsNodeGroupId &groupId, RsGroupInfo &groupInfo) override; - virtual bool getGroupInfoByName(const std::string& groupName, RsGroupInfo& groupInfo) override; - virtual bool getGroupInfoList(std::list &groupInfoList) override; - virtual bool assignPeerToGroup(const RsNodeGroupId &groupId, const RsPgpId &peerId, bool assign) override; - virtual bool assignPeersToGroup(const RsNodeGroupId &groupId, const std::list& peerIds, bool assign) override; - - virtual FileSearchFlags computePeerPermissionFlags(const RsPeerId& peer_id, FileStorageFlags share_flags, const std::list &parent_groups) override; - - // service permission stuff - - virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) override; - virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId & ssl_id) override; - virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) override; - - virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) override; - virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) override; - virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) override; -private: - - p3LinkMgr *mLinkMgr; - p3PeerMgr *mPeerMgr; - p3NetMgr *mNetMgr; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; - -#endif diff --git a/libretroshare/src/rsserver/p3serverconfig.cc b/libretroshare/src/rsserver/p3serverconfig.cc deleted file mode 100644 index 6d3343dc7..000000000 --- a/libretroshare/src/rsserver/p3serverconfig.cc +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3serverconfig.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include "rsserver/p3serverconfig.h" -#include "services/p3bwctrl.h" - -#include "pqi/authgpg.h" -#include "pqi/authssl.h" - -RsServerConfig *rsConfig = NULL; - -static const std::string pqih_ftr("PQIH_FTR"); - -#define DEFAULT_DOWNLOAD_KB_RATE (10000.0) -#define DEFAULT_UPLOAD_KB_RATE (10000.0) - -#define MIN_MINIMAL_RATE (5.0) - - -p3ServerConfig::p3ServerConfig(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr, pqihandler *pqih, p3GeneralConfig *genCfg) -:configMtx("p3ServerConfig") -{ - mPeerMgr = peerMgr; - mLinkMgr = linkMgr; - mNetMgr = netMgr; - mPqiHandler = pqih; - - mGeneralConfig = genCfg; - - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - - mUserLevel = RsConfigUserLvl::NEW; /* START LEVEL */ - mRateDownload = DEFAULT_DOWNLOAD_KB_RATE; - mRateUpload = DEFAULT_UPLOAD_KB_RATE; - - mOpMode = RsOpMode::FULL; - - rsConfig = this; -} - - -p3ServerConfig::~p3ServerConfig() -{ - return; -} - - -void p3ServerConfig::load_config() -{ - /* get the real bandwidth setting from GeneralConfig */ - std::string rates = mGeneralConfig -> getSetting(pqih_ftr); - - float mri, mro; - if (2 == sscanf(rates.c_str(), "%f %f", &mri, &mro)) - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - - mRateDownload = mri; - mRateUpload = mro; - } - else - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - - mRateDownload = DEFAULT_DOWNLOAD_KB_RATE; - mRateUpload = DEFAULT_UPLOAD_KB_RATE; - } - - /* enable operating mode */ - RsOpMode opMode = getOperatingMode(); - switchToOperatingMode(opMode); -} - - -#define RS_CONFIG_ADVANCED_STRING "AdvMode" - -bool p3ServerConfig::findConfigurationOption(uint32_t key, std::string &keystr) -{ - bool found = false; - switch(key) - { - case RS_CONFIG_ADVANCED: - keystr = RS_CONFIG_ADVANCED_STRING; - found = true; - break; - } - return found; -} - - -bool p3ServerConfig::getConfigurationOption(uint32_t key, std::string &opt) -{ - std::string strkey; - if (!findConfigurationOption(key, strkey)) - { - std::cerr << "p3ServerConfig::getConfigurationOption() OPTION NOT VALID: " << key; - std::cerr << std::endl; - return false; - } - - opt = mGeneralConfig->getSetting(strkey); - return true; -} - - -bool p3ServerConfig::setConfigurationOption(uint32_t key, const std::string &opt) -{ - std::string strkey; - if (!findConfigurationOption(key, strkey)) - { - std::cerr << "p3ServerConfig::setConfigurationOption() OPTION NOT VALID: " << key; - std::cerr << std::endl; - return false; - } - - mGeneralConfig->setSetting(strkey, opt); - return true; -} - - /* From RsIface::RsConfig */ -int p3ServerConfig::getConfigNetStatus(RsConfigNetStatus &status) -{ - status.ownId = AuthSSL::getAuthSSL()->OwnId(); - status.ownName = AuthGPG::getAuthGPG()->getGPGOwnName(); - - // Details from PeerMgr. - peerState pstate; - mPeerMgr->getOwnNetStatus(pstate); - - status.localAddr = sockaddr_storage_iptostring(pstate.localaddr); - status.localPort = sockaddr_storage_port(pstate.localaddr); - - status.extAddr = sockaddr_storage_iptostring(pstate.serveraddr); - status.extPort = sockaddr_storage_port(pstate.serveraddr); - status.extDynDns = pstate.dyndns; - - status.firewalled = true; - status.forwardPort = true; - - /* update network configuration */ - pqiNetStatus nstatus; - mNetMgr->getNetStatus(nstatus); - - status.netUpnpOk = nstatus.mUpnpOk; - status.netStunOk = false; - status.netExtAddressOk = nstatus.mExtAddrOk; - - status.netDhtOk = nstatus.mDhtOk; - status.netDhtNetSize = nstatus.mDhtNetworkSize; - status.netDhtRsNetSize = nstatus.mDhtRsNetworkSize; - - /* update DHT/UPnP status */ - status.uPnPState = mNetMgr->getUPnPState(); - status.uPnPActive = mNetMgr->getUPnPEnabled(); - status.DHTActive = mNetMgr->getDHTEnabled(); - - return 1; -} - -int p3ServerConfig::getConfigStartup(RsConfigStartup &/*params*/) -{ - //status.promptAtBoot = true; /* popup the password prompt */ - return 0; -} - -/***** for RsConfig -> p3BandwidthControl ****/ - -int p3ServerConfig::getTrafficInfo(std::list& out_lst,std::list& in_lst) -{ - - if (rsBandwidthControl) - return rsBandwidthControl->ExtractTrafficInfo(out_lst,in_lst); - else - return 0 ; -} - -int p3ServerConfig::getTotalBandwidthRates(RsConfigDataRates &rates) -{ - if (rsBandwidthControl) - { - return rsBandwidthControl->getTotalBandwidthRates(rates); - } - return 0; -} - -int p3ServerConfig::getAllBandwidthRates(std::map &ratemap) -{ - if (rsBandwidthControl) - { - return rsBandwidthControl->getAllBandwidthRates(ratemap); - } - return 0; -} - - - /* From RsInit */ - -std::string p3ServerConfig::RsConfigDirectory() -{ - return std::string(); -} - -std::string p3ServerConfig::RsConfigKeysDirectory() -{ - return std::string(); -} - - -std::string p3ServerConfig::RsProfileConfigDirectory() -{ - return std::string(); -} - -bool p3ServerConfig::getStartMinimised() -{ - return 0; -} - -std::string p3ServerConfig::getRetroShareLink() -{ - return std::string(); -} - - -bool p3ServerConfig::getAutoLogin() -{ - return 0; -} - -void p3ServerConfig::setAutoLogin(bool /*autoLogin*/) -{ - return; -} - -bool p3ServerConfig::RsClearAutoLogin() -{ - return 0; -} - - -std::string p3ServerConfig::getRetroshareDataDirectory() -{ - return std::string(); -} - - /* New Stuff */ - -RsConfigUserLvl p3ServerConfig::getUserLevel() -{ - RsConfigUserLvl userLevel = RsConfigUserLvl::NEW; - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - userLevel = mUserLevel; - } - - switch(userLevel) - { - case RsConfigUserLvl::OVERRIDE: - break; - -#define MIN_BASIC_FRIENDS 2 - - // FALL THROUGH EVERYTHING. - default: - case RsConfigUserLvl::NEW: - { - - if (mPeerMgr->getFriendCount(true, false) > MIN_BASIC_FRIENDS) - { - userLevel = RsConfigUserLvl::BASIC; - } - } - /* fallthrough */ - case RsConfigUserLvl::BASIC: - { - /* check that we have some lastConnect > 0 */ - if (mPeerMgr->haveOnceConnected()) - { - userLevel = RsConfigUserLvl::CASUAL; - } - } - /* fallthrough */ - case RsConfigUserLvl::CASUAL: - case RsConfigUserLvl::POWER: - - { - /* check that the firewall is open */ - - RsNetworkMode netMode = mNetMgr->getNetworkMode(); - RsNatHoleMode firewallMode = mNetMgr->getNatHoleMode(); - - if ((RsNetworkMode::EXTERNALIP == netMode) || - ((RsNetworkMode::BEHINDNAT == netMode) && - (RsNatHoleMode::UPNP == firewallMode || - (RsNatHoleMode::NATPMP == firewallMode) || - (RsNatHoleMode::FORWARDED == firewallMode)))) - { - userLevel = RsConfigUserLvl::POWER; - } - } - break; /* for all */ - } - - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - mUserLevel = userLevel; - } - - return userLevel; -} - - -RsNetState p3ServerConfig::getNetState() -{ - return mNetMgr->getNetStateMode(); -} - -RsNetworkMode p3ServerConfig::getNetworkMode() -{ - return mNetMgr->getNetworkMode(); -} - -RsNatTypeMode p3ServerConfig::getNatTypeMode() -{ - return mNetMgr->getNatTypeMode(); -} - -RsNatHoleMode p3ServerConfig::getNatHoleMode() -{ - return mNetMgr->getNatHoleMode(); -} - -RsConnectModes p3ServerConfig::getConnectModes() -{ - return mNetMgr->getConnectModes(); -} - - /* Operating Mode */ -#define RS_CONFIG_OPERATING_STRING "OperatingMode" - -RsOpMode p3ServerConfig::getOperatingMode() -{ -#ifdef SAVE_OPERATING_MODE - std::string modestr = mGeneralConfig->getSetting(RS_CONFIG_OPERATING_STRING); - uint32_t mode = RsOpMode::FULL; - - if (modestr == "FULL") - { - mode = RsOpMode::FULL; - } - else if (modestr == "NOTURTLE") - { - mode = RsOpMode::NOTURTLE; - } - else if (modestr == "GAMING") - { - mode = RsOpMode::GAMING; - } - else if (modestr == "MINIMAL") - { - mode = RsOpMode::MINIMAL; - } - return mode; -#else - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - return mOpMode; -#endif -} - - -bool p3ServerConfig::setOperatingMode(RsOpMode opMode) -{ -#ifdef SAVE_OPERATING_MODE - std::string modestr = "FULL"; - switch(opMode) - { - case RsOpMode::FULL: - modestr = "FULL"; - break; - case RsOpMode::NOTURTLE: - modestr = "NOTURTLE"; - - break; - case RsOpMode::GAMING: - modestr = "GAMING"; - - break; - case RsOpMode::MINIMAL: - modestr = "MINIMAL"; - break; - } - mGeneralConfig->setSetting(RS_CONFIG_OPERATING_STRING, modestr); -#else - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - mOpMode = opMode; - } -#endif - return switchToOperatingMode(opMode); -} - -bool p3ServerConfig::setOperatingMode(const std::string &opModeStr) -{ - RsOpMode opMode = RsOpMode::FULL; - std::string upper; - stringToUpperCase(opModeStr, upper); - - if (upper == "NOTURTLE") - { - opMode = RsOpMode::NOTURTLE; - } - else if (upper == "GAMING") - { - opMode = RsOpMode::GAMING; - } - else if (upper == "MINIMAL") - { - opMode = RsOpMode::MINIMAL; - } - else // "FULL" by default - { - opMode = RsOpMode::FULL; - } - - return setOperatingMode(opMode); -} - -bool p3ServerConfig::switchToOperatingMode(RsOpMode opMode) -{ - float dl_rate = 0; - float ul_rate = 0; - bool turtle_enabled = true; - - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - dl_rate = mRateDownload; - ul_rate = mRateUpload; - } - - std::cerr << "p3ServerConfig::switchToOperatingMode(" << static_cast::type>(opMode) << ")"; - std::cerr << std::endl; - - switch (opMode) - { - default: - case RsOpMode::FULL: - /* switch on all transfers */ - /* 100% bandwidth */ - /* switch on popups, enable hashing */ - //setMaxRate(true, mri); // In / Download - //setMaxRate(false, mro); // Out / Upload. - turtle_enabled = true; - break; - case RsOpMode::NOTURTLE: - /* switch on all transfers - except turtle, enable hashing */ - /* 100% bandwidth */ - /* switch on popups, enable hashing */ - turtle_enabled = false; - - break; - case RsOpMode::GAMING: - /* switch on all transfers */ - /* reduce bandwidth to 25% */ - /* switch off popups, enable hashing */ - turtle_enabled = true; - - dl_rate *= 0.25; - ul_rate *= 0.25; - break; - case RsOpMode::MINIMAL: - /* switch off all transfers */ - /* reduce bandwidth to 10%, but make sure there is enough for VoIP */ - /* switch on popups, enable hashing */ - - turtle_enabled = false; - - dl_rate *= 0.10; - ul_rate *= 0.10; - if (dl_rate < MIN_MINIMAL_RATE) - { - dl_rate = MIN_MINIMAL_RATE; - } - if (ul_rate < MIN_MINIMAL_RATE) - { - ul_rate = MIN_MINIMAL_RATE; - } - - break; - } - - if (mPqiHandler) - { - mPqiHandler -> setMaxRate(true, dl_rate); - mPqiHandler -> setMaxRate(false, ul_rate); - - std::cerr << "p3ServerConfig::switchToOperatingMode() D/L: " << dl_rate << " U/L: " << ul_rate; - std::cerr << std::endl; - - } - - std::cerr << "p3ServerConfig::switchToOperatingMode() Turtle Mode: " << turtle_enabled; - std::cerr << std::endl; - - rsTurtle->setSessionEnabled(turtle_enabled); - return true; -} - -/* handle data rates. - * Mutex must be handled at the lower levels: TODO */ - -int p3ServerConfig::SetMaxDataRates( int downKb, int upKb ) /* in kbrates */ -{ - char line[512]; - - { - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - mRateDownload = downKb; - mRateUpload = upKb; - sprintf(line, "%f %f", mRateDownload, mRateUpload); - } - mGeneralConfig->setSetting(pqih_ftr, std::string(line)); - - load_config(); // load and setup everything. - return 1; -} - - -int p3ServerConfig::GetMaxDataRates( int &inKb, int &outKb ) /* in kbrates */ -{ - RsStackMutex stack(configMtx); /******* LOCKED MUTEX *****/ - - inKb = mRateDownload; - outKb = mRateUpload; - return 1; -} - -int p3ServerConfig::GetCurrentDataRates( float &inKb, float &outKb ) -{ - mPqiHandler->getCurrentRates(inKb, outKb); - return 1; -} - -int p3ServerConfig::GetTrafficSum(uint64_t &inb, uint64_t &outb ) -{ - mPqiHandler->GetTraffic(inb, outb); - return 1; -} diff --git a/libretroshare/src/rsserver/p3serverconfig.h b/libretroshare/src/rsserver/p3serverconfig.h deleted file mode 100644 index c197aa1b0..000000000 --- a/libretroshare/src/rsserver/p3serverconfig.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3serverconfig.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef LIBRETROSHARE_CONFIG_IMPLEMENTATION_H -#define LIBRETROSHARE_CONFIG_IMPLEMENTATION_H - -#include "retroshare/rsconfig.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/pqihandler.h" - - -#define RS_CONFIG_ADVANCED_STRING "AdvMode" - - - -class p3ServerConfig: public RsServerConfig -{ - public: - - p3ServerConfig(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr, pqihandler *pqih, p3GeneralConfig *genCfg); -virtual ~p3ServerConfig(); - - void load_config(); - - /* From RsIface::RsConfig */ - -virtual int getConfigNetStatus(RsConfigNetStatus &status); -virtual int getConfigStartup(RsConfigStartup ¶ms); -//virtual int getConfigDataRates(RsConfigDataRates ¶ms); - - /***** for RsConfig -> p3BandwidthControl ****/ - -virtual int getTotalBandwidthRates(RsConfigDataRates &rates); -virtual int getAllBandwidthRates(std::map &ratemap); - virtual int getTrafficInfo(std::list& out_lst, std::list &in_lst) ; - - /* From RsInit */ - -virtual std::string RsConfigDirectory(); -virtual std::string RsConfigKeysDirectory(); - -virtual std::string RsProfileConfigDirectory(); -virtual bool getStartMinimised(); -virtual std::string getRetroShareLink(); - -virtual bool getAutoLogin(); -virtual void setAutoLogin(bool autoLogin); -virtual bool RsClearAutoLogin(); - -virtual std::string getRetroshareDataDirectory(); - - /* New Stuff */ - -virtual RsConfigUserLvl getUserLevel(); - -virtual RsNetState getNetState(); -virtual RsNetworkMode getNetworkMode(); -virtual RsNatTypeMode getNatTypeMode(); -virtual RsNatHoleMode getNatHoleMode(); -virtual RsConnectModes getConnectModes(); - -virtual bool getConfigurationOption(uint32_t key, std::string &opt); -virtual bool setConfigurationOption(uint32_t key, const std::string &opt); - - /* Operating Mode */ -virtual RsOpMode getOperatingMode(); -virtual bool setOperatingMode(RsOpMode opMode); -virtual bool setOperatingMode(const std::string &opModeStr); - -virtual int SetMaxDataRates( int downKb, int upKb ); -virtual int GetMaxDataRates( int &downKb, int &upKb ); -virtual int GetCurrentDataRates( float &inKb, float &outKb ); -virtual int GetTrafficSum( uint64_t &inb, uint64_t &outb ); - -/********************* ABOVE is RsConfig Interface *******/ - - private: - -bool switchToOperatingMode(RsOpMode opMode); - -bool findConfigurationOption(uint32_t key, std::string &keystr); - - p3PeerMgr *mPeerMgr; - p3LinkMgr *mLinkMgr; - p3NetMgr *mNetMgr; - pqihandler *mPqiHandler; - p3GeneralConfig *mGeneralConfig; - - RsMutex configMtx; - RsConfigUserLvl mUserLevel; // store last one... will later be a config Item too. - float mRateDownload; - float mRateUpload; - - RsOpMode mOpMode; -}; - -#endif diff --git a/libretroshare/src/rsserver/p3status.cc b/libretroshare/src/rsserver/p3status.cc deleted file mode 100644 index 4185e6802..000000000 --- a/libretroshare/src/rsserver/p3status.cc +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3status.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Chris Evi-Parker. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "p3status.h" -#include "services/p3statusservice.h" - -p3Status::p3Status(p3StatusService* statusSrv) - : mStatusSrv(statusSrv) { - - -} - -p3Status::~p3Status(){ - return; -} - -bool p3Status::getOwnStatus(StatusInfo& statusInfo){ - - return mStatusSrv->getOwnStatus(statusInfo); -} - -bool p3Status::getStatusList(std::list& statusInfo){ - - return mStatusSrv->getStatusList(statusInfo); -} - -bool p3Status::getStatus(const RsPeerId &id, StatusInfo &statusInfo) -{ - return mStatusSrv->getStatus(id, statusInfo); -} - -bool p3Status::sendStatus(const RsPeerId &id, uint32_t status){ - - return mStatusSrv->sendStatus(id, status); -} diff --git a/libretroshare/src/rsserver/p3status.h b/libretroshare/src/rsserver/p3status.h deleted file mode 100644 index a6ae941f0..000000000 --- a/libretroshare/src/rsserver/p3status.h +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: p3status.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Chris Evi-Parker. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_P3STATUS_INTERFACE_H -#define RS_P3STATUS_INTERFACE_H - -#include "retroshare/rsstatus.h" - - -class p3StatusService; - -//! Implements abstract interface rsStatus -/*! - * Interfaces with p3StatusService - */ -class p3Status : public RsStatus -{ -public: - - explicit p3Status(p3StatusService* statusSrv); - virtual ~p3Status(); - - - virtual bool getOwnStatus(StatusInfo& statusInfo); - virtual bool getStatusList(std::list& statusInfo); - virtual bool getStatus(const RsPeerId &id, StatusInfo &statusInfo); - virtual bool sendStatus(const RsPeerId &id, uint32_t status); - -private: - - p3StatusService* mStatusSrv; - -}; - -#endif /* RS_P3STATUS_INTERFACE_H */ diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc deleted file mode 100644 index 8be56073c..000000000 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ /dev/null @@ -1,1449 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: rsaccounts.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/********************************************************************* - * Libretroshare interface declared in rsaccounts.h. - * external interface in rsinit.h RsAccounts namespace. - * - */ - -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif // WINDOWS_SYS - -#include -#include - -#include - -#include "retroshare/rsinit.h" -#include "rsaccounts.h" - -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "util/folderiterator.h" - -#include "pqi/authssl.h" -#include "pqi/sslfns.h" -#include "pqi/authgpg.h" - -#include - -// Global singleton declaration of data. -RsAccountsDetail* RsAccounts::rsAccountsDetails = nullptr; - -/* Uses private class - so must be hidden */ -static bool checkAccount(const std::string &accountdir, AccountDetails &account,std::map >& unsupported_keys); - -AccountDetails::AccountDetails() - :mSslId(""), mAccountDir(""), mPgpId(""), mPgpName(""), mPgpEmail(""), - mLocation(""), mIsHiddenLoc(false), mFirstRun(false) -{ - return; -} - -RsAccountsDetail::RsAccountsDetail() : mAccountsLocked(false), mPreferredId("") -{} - -bool RsAccountsDetail::loadAccounts() -{ - int failing_accounts ; -#warning we might need some switch here for hidden nodes only - getAvailableAccounts(mAccounts,failing_accounts,mUnsupportedKeys,false); - - loadPreferredAccount(); - checkPreferredId(); - - if(failing_accounts > 0 && mAccounts.empty()) - return false; - - return true; -} - -bool RsAccountsDetail::lockPreferredAccount() -{ - if (checkPreferredId()) - { - mAccountsLocked = true; - return true; - } - - return false; -} - -void RsAccountsDetail::unlockPreferredAccount() -{ - mAccountsLocked = false; -} - -bool RsAccountsDetail::checkAccountDirectory() -{ - if (!checkPreferredId()) - { - return false; - } - - return setupAccount(getCurrentAccountPathAccountDirectory()); -} - -#warning we need to clean that up. Login should only ask for a SSL id, instead of a std::string. - -bool RsAccountsDetail::selectAccountByString(const std::string &prefUserString) -{ - if (mAccountsLocked) - { - std::cerr << "RsAccountsDetail::selectAccountByString() ERROR Accounts Locked"; - std::cerr << std::endl; - return false; - } - - // try both. - // - RsPeerId ssl_id(prefUserString) ; - RsPgpId pgp_id(prefUserString) ; - - std::cerr << "RsAccountsDetail::selectAccountByString(" << prefUserString << ")" << std::endl; - - //bool pgpNameFound = false; - std::map::const_iterator it; - for(it = mAccounts.begin() ; it!= mAccounts.end() ; ++it) - { - std::cerr << "\tChecking account (pgpid = " << it->second.mPgpId; - std::cerr << ", name=" << it->second.mPgpName << ", sslId="; - std::cerr << it->second.mSslId << ")" << std::endl; - - if(prefUserString == it->second.mPgpName || pgp_id == it->second.mPgpId || ssl_id == it->second.mSslId) - { - mPreferredId = it->second.mSslId; - //pgpNameFound = true; - - std::cerr << "Account selected: " << ssl_id << std::endl; - - return true; - } - } - std::cerr << "No suitable candidate found." << std::endl; - return false; -} - - -bool RsAccountsDetail::selectId(const RsPeerId& preferredId) -{ - - if (mAccountsLocked) - { - std::cerr << "RsAccountsDetail::selectId() ERROR Accounts Locked"; - std::cerr << std::endl; - return false; - } - - std::map::const_iterator it; - it = mAccounts.find(preferredId); - - if (it != mAccounts.end()) - { - mPreferredId = preferredId; - return true; - } - else - { - return false; - } -} - - -bool RsAccountsDetail::checkPreferredId() -{ - std::map::const_iterator it; - it = mAccounts.find(mPreferredId); - - if (it != mAccounts.end()) - { - return true; - } - else - { - mPreferredId.clear(); - return false; - } -} - -// initial configuration bootstrapping... - -const std::string kPathPGPDirectory = "pgp"; -const std::string kPathKeyDirectory = "keys"; -const std::string kPathConfigDirectory = "config"; - -const std::string kFilenamePreferredAccount = "default_cert_06.txt"; -const std::string kFilenameKey = "user_pk.pem"; -const std::string kFilenameCert = "user_cert.pem"; -const std::string kFilenameLocation = "location_name.txt"; - - -/********************************************************************* - * Directories... based on current PreferredId. - */ - -std::string RsAccountsDetail::PathPGPDirectory() -{ - return mBaseDirectory + "/" + kPathPGPDirectory; -} - - -std::string RsAccountsDetail::PathBaseDirectory() -{ - if(mBaseDirectory.empty()) defaultBaseDirectory(); - return mBaseDirectory; -} - - -std::string RsAccountsDetail::getCurrentAccountPathAccountDirectory() -{ - std::string path; - - std::map::const_iterator it; - it = mAccounts.find(mPreferredId); - if (it == mAccounts.end()) - { - return path; - } - - path = mBaseDirectory + "/"; - path += it->second.mAccountDir; - return path; -} - -std::string RsAccountsDetail::getCurrentAccountPathAccountKeysDirectory() -{ - std::string path = getCurrentAccountPathAccountDirectory(); - if (path.empty()) - { - return path; - } - - path += "/" + kPathKeyDirectory; - return path; -} - -std::string RsAccountsDetail::getCurrentAccountPathKeyFile() -{ - std::string path = getCurrentAccountPathAccountKeysDirectory(); - if (path.empty()) - { - return path; - } - - path += "/" + kFilenameKey; - return path; -} - -std::string RsAccountsDetail::getCurrentAccountPathCertFile() -{ - std::string path = getCurrentAccountPathAccountKeysDirectory(); - if (path.empty()) - { - return path; - } - path += "/" + kFilenameCert; - return path; -} - -std::string RsAccountsDetail::getCurrentAccountLocationName() -{ - std::map::const_iterator it; - it = mAccounts.find(mPreferredId); - if (it == mAccounts.end()) - { - return ""; - } - return it->second.mLocation; -} - - -/********************************************************************* - * Setup Base Directories. - * - */ - -bool RsAccountsDetail::setupBaseDirectory(std::string alt_basedir) -{ - if (alt_basedir.empty()) - { - if (!defaultBaseDirectory()) - { - std::cerr << "RsAccounts::setupBaseDirectory() Cannot find defaultBaseDirectory"; - std::cerr << std::endl; - return false; - } - } - else - { - mBaseDirectory = alt_basedir; - } - - /* Check for trailing '/' */ - if (!mBaseDirectory.empty()) - { - char lastChar = *mBaseDirectory.rbegin(); - if (lastChar == '/' -#ifdef WINDOWS_SYS - || lastChar == '\\' -#endif - ) - { - mBaseDirectory.erase(mBaseDirectory.end() - 1); - } - } - - if (!RsDirUtil::checkCreateDirectory(mBaseDirectory)) - { - std::cerr << "RsAccounts::setupBaseDirectory() Cannot Create BaseConfig Dir:" << mBaseDirectory; - std::cerr << std::endl; - return false ; - } - return true ; -} - - -bool RsAccountsDetail::defaultBaseDirectory() -{ - std::string basedir; - -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - - // unix: homedir + /.retroshare - char *h = getenv("HOME"); - if (h == NULL) - { - std::cerr << "defaultBaseDirectory() Error: cannot determine $HOME dir" - << std::endl; - return false ; - } - - basedir = h; - basedir += "/.retroshare"; - -#else - if (RsInit::isPortable()) - { - // use directory "Data" in portable version - basedir = "Data"; - } - else - { - wchar_t *wh = _wgetenv(L"APPDATA"); - std::string h; - librs::util::ConvertUtf16ToUtf8(std::wstring(wh), h); - if (h.empty()) - { - // generating default - std::cerr << "defaultBaseDirectory() Error: "; - std::cerr << " getEnv Error --Win95/98?"; - std::cerr << std::endl; - basedir="C:\\Retro"; - } - else - { - basedir = h; - } - - if (!RsDirUtil::checkCreateDirectory(basedir)) - { - std::cerr << "defaultBaseDirectory() Error: "; - std::cerr << "Cannot Create BaseConfig Dir : " << basedir << std::endl; - return false ; - } - basedir += "\\RetroShare"; - } -#endif -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - /* store to class variable */ - mBaseDirectory = basedir; - std::cerr << "defaultBaseDirectory() = " << mBaseDirectory; - std::cerr << std::endl; - return true; -} - - -bool RsAccountsDetail::loadPreferredAccount() -{ - std::string initfile = mBaseDirectory + "/"; - initfile += kFilenamePreferredAccount; - - // open and read in the lines. - FILE *ifd = RsDirUtil::rs_fopen(initfile.c_str(), "r"); - char path[1024]; - int i; - - if (ifd != NULL) - { - if (NULL != fgets(path, 1024, ifd)) - { - for(i = 0; (path[i] != '\0') && (path[i] != '\n'); i++) ; - path[i] = '\0'; - - // Store PreferredId. - mPreferredId = RsPeerId(std::string(path)); - - if(mPreferredId.isNull()) - { - fclose(ifd); - return false ; - } - } - fclose(ifd); - return true; - } - return false; -} - -bool RsAccountsDetail::storePreferredAccount() -{ - // Check for config file. - std::string initfile = mBaseDirectory + "/"; - initfile += kFilenamePreferredAccount; - - // open and read in the lines. - FILE *ifd = RsDirUtil::rs_fopen(initfile.c_str(), "w"); - - if (ifd != NULL) - { - fprintf(ifd, "%s\n", mPreferredId.toStdString().c_str()); - fclose(ifd); - - std::cerr << "Creating Init File: " << initfile << std::endl; - std::cerr << "\tId: " << mPreferredId << std::endl; - - return true; - } - std::cerr << "Failed To Create Init File: " << initfile << std::endl; - return false; -} - - -/********************************************************************* - * Accounts - * - */ - -bool RsAccountsDetail::getCurrentAccountId(RsPeerId &id) -{ - id = mPreferredId; - return (!mPreferredId.isNull()); -} - -bool RsAccountsDetail::getAccountIds(std::list &ids) -{ - std::map::iterator it; -#ifdef DEBUG_ACCOUNTS - std::cerr << "getAccountIds:" << std::endl; -#endif - - for(it = mAccounts.begin(); it != mAccounts.end(); ++it) - { -#ifdef DEBUG_ACCOUNTS - std::cerr << "SSL Id: " << it->second.mSslId << " PGP Id " << it->second.mPgpId; - std::cerr << " PGP Name: " << it->second.mPgpName; - std::cerr << " PGP Email: " << it->second.mPgpEmail; - std::cerr << " Location: " << it->second.mLocation; - std::cerr << std::endl; -#endif - - ids.push_back(it->first); - } - return true; -} - - -bool RsAccountsDetail::getCurrentAccountDetails(const RsPeerId &id, - RsPgpId &gpgId, std::string &gpgName, - std::string &gpgEmail, std::string &location) -{ - std::map::iterator it; - it = mAccounts.find(id); - if (it != mAccounts.end()) - { - gpgId = it->second.mPgpId; - gpgName = it->second.mPgpName; - gpgEmail = it->second.mPgpEmail; - location = it->second.mLocation; - return true; - } - return false; -} - -bool RsAccountsDetail::getCurrentAccountOptions(bool &ishidden,bool& isautotor, bool &isFirstTimeRun) -{ - std::map::iterator it; - it = mAccounts.find(mPreferredId); - if (it != mAccounts.end()) - { - ishidden = it->second.mIsHiddenLoc; - isFirstTimeRun = it->second.mFirstRun; - isautotor = it->second.mIsAutoTor; - - return true; - } - return false; -} - - -/* directories with valid certificates in the expected location */ -bool RsAccountsDetail::getAvailableAccounts(std::map &accounts,int& failing_accounts,std::map >& unsupported_keys,bool hidden_only) -{ - failing_accounts = 0 ; - /* get the directories */ - std::list directories; - std::list::iterator it; - - std::cerr << "RsAccounts::getAvailableAccounts()"; - std::cerr << std::endl; - - /* now iterate through the directory... - * directories - flags as old, - * files checked to see if they have changed. (rehashed) - */ - - /* check for the dir existance */ - librs::util::FolderIterator dirIt(mBaseDirectory,false); - - if (!dirIt.isValid()) - { - std::cerr << "Cannot Open Base Dir - No Available Accounts" << std::endl; - return false ; - } - - struct stat64 buf; - - for(;dirIt.isValid();dirIt.next()) - { - /* check entry type */ - std::string fname = dirIt.file_name(); - std::string fullname = mBaseDirectory + "/" + fname; -#ifdef FIM_DEBUG - std::cerr << "calling stats on " << fullname <length() != 32 + 6) - { - std::cerr << "getAvailableAccounts() Skipping Invalid sized dir: " << *it << std::endl; - continue; - } - - std::string prefix = (*it).substr(0, 6); - std::string lochex = (*it).substr(6); // rest of string. - - bool hidden_location = false; - bool auto_tor = false; - bool valid_prefix = false; - - if (prefix == "LOC06_") - { - valid_prefix = true; - } - else if (prefix == "HID06_") - { - valid_prefix = true; - hidden_location = true; - - auto_tor = RsDirUtil::checkDirectory(mBaseDirectory+"/"+*it+"/hidden_service"); - } - else - { - std::cerr << "getAvailableAccounts() Skipping Invalid Prefix dir: " << *it << std::endl; - continue; - } - - if(hidden_only && !hidden_location) - continue ; - - if(valid_prefix && isHexaString(lochex) && (lochex).length() == 32) - { - std::string accountdir = mBaseDirectory + "/" + *it; -#ifdef GPG_DEBUG - std::cerr << "getAvailableAccounts() Checking: " << *it << std::endl; -#endif - - AccountDetails tmpId; - tmpId.mIsHiddenLoc = hidden_location; - tmpId.mIsAutoTor = auto_tor; - tmpId.mAccountDir = *it; - - if (checkAccount(accountdir, tmpId,unsupported_keys)) - { -#ifdef GPG_DEBUG - std::cerr << "getAvailableAccounts() Accepted: " << *it << std::endl; -#endif - - std::map::iterator ait; - ait = accounts.find(tmpId.mSslId); - if (ait != accounts.end()) - { - std::cerr << "getAvailableAccounts() ERROR Duplicate SSLIDs"; - std::cerr << " - only one will be available"; - std::cerr << std::endl; - std::cerr << " ID1 (overridden) : " << ait->first << " Directory: " << ait->second.mAccountDir; - std::cerr << std::endl; - std::cerr << " ID2 (available) : " << tmpId.mSslId << " Directory: " << tmpId.mAccountDir; - std::cerr << std::endl; - - } - - accounts[tmpId.mSslId] = tmpId; - } - else - ++failing_accounts ; - } -#ifdef GPG_DEBUG - else - std::cerr << "Skipped non SSLid directory " << *it << std::endl; -#endif - } - return true; -} - - - -static bool checkAccount(const std::string &accountdir, AccountDetails &account,std::map >& unsupported_keys) -{ - /* check if the cert/key file exists */ - - // Create the filename. - // TODO: use kFilenameKey - std::string basename = accountdir + "/"; - basename += kPathKeyDirectory + "/"; - basename += "user"; - - std::string cert_name = basename + "_cert.pem"; - //std::string userName; - -#ifdef AUTHSSL_DEBUG - std::cerr << "checkAccount() dir: " << accountdir << std::endl; -#endif - bool ret = false; - - /* check against authmanagers private keys */ - if(AuthSSL::instance().parseX509DetailsFromFile( - cert_name, account.mSslId, account.mPgpId, account.mLocation )) - { - // new locations store the name in an extra file - if(account.mLocation == "") - RsDirUtil::loadStringFromFile(accountdir + "/" + kPathKeyDirectory + "/" + kFilenameLocation, - account.mLocation); -#ifdef AUTHSSL_DEBUG - std::cerr << "location: " << account.mLocation << " id: " << account.mSslId << std::endl; - std::cerr << "issuerName: " << account.mPgpId << " id: " << account.mSslId << std::endl; -#endif - - if(! RsAccounts::GetPGPLoginDetails(account.mPgpId, account.mPgpName, account.mPgpEmail)) - return false ; - - if(!AuthGPG::getAuthGPG()->haveSecretKey(account.mPgpId)) - return false ; - - if(!AuthGPG::getAuthGPG()->isKeySupported(account.mPgpId)) - { - std::string keystring = account.mPgpId.toStdString() + " " + account.mPgpName + "<" + account.mPgpEmail ; - unsupported_keys[keystring].push_back("Location: " + account.mLocation + "  (" + account.mSslId.toStdString() + ")") ; - return false ; - } - -#ifdef GPG_DEBUG - std::cerr << "PGPLoginDetails: " << account.mPgpId << " name: " << account.mPgpName; - std::cerr << " email: " << account.mPgpEmail << std::endl; -#endif - ret = true; - } - else - { - std::cerr << "GetIssuerName FAILED!" << std::endl; - ret = false; - } - - return ret; -} - - - - - -/**************************** Access Functions for Init Data **************************/ -/**************************** Private Functions for InitRetroshare ********************/ -/**************************** Private Functions for InitRetroshare ********************/ - - -/*********************************************************** - * This Directory is used to store data and "template" file that Retroshare requires. - * These files will either be copied into Retroshare's configuration directory, - * if they are to be modified. Or used directly, if read-only. - * - * This will initially be used for the DHT bootstrap file. - * - * Please modify the code below to suit your platform! - * - * WINDOWS: - * WINDOWS PORTABLE: - * Linux: - * OSX: - - ***********/ - -#ifdef __APPLE__ - /* needs CoreFoundation Framework */ - #include - //#include - //#include -#endif - -/*static*/ std::string RsAccountsDetail::PathDataDirectory(bool check) -{ - std::string dataDirectory; - -#ifdef __APPLE__ - /* NOTE: OSX also qualifies as BSD... so this #ifdef must be before the BSD check. */ - - /* For OSX, applications are Bundled in a directory... - * need to get the path to the executable Bundle. - * - * Code nicely supplied by Qt! - */ - - CFURLRef pluginRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFStringRef macPath = CFURLCopyFileSystemPath(pluginRef, - kCFURLPOSIXPathStyle); - const char *pathPtr = CFStringGetCStringPtr(macPath, - CFStringGetSystemEncoding()); - dataDirectory = pathPtr; - CFRelease(pluginRef); - CFRelease(macPath); - - dataDirectory += "/Contents/Resources"; - std::cerr << "getRetroshareDataDirectory() OSX: " << dataDirectory; - -#elif (defined(BSD) && (BSD >= 199103)) - /* For BSD, the default is LOCALBASE which will be set - * before compilation via the ports/pkg-src mechanisms. - * For compilation without ports/pkg-src it is set to - * /usr/local (default on Open and Free; Net has /usr/pkg) - */ - dataDirectory = "/usr/local/share/retroshare"; - std::cerr << "getRetroshareDataDirectory() BSD: " << dataDirectory; -#elif defined(WINDOWS_SYS) -// if (RsInitConfig::portable) -// { -// /* For Windows Portable, files must be in the data directory */ -// dataDirectory = "Data"; -// std::cerr << "getRetroshareDataDirectory() WINDOWS PORTABLE: " << dataDirectory; -// std::cerr << std::endl; -// } -// else -// { -// /* For Windows: environment variable APPDATA should be suitable */ -// dataDirectory = getenv("APPDATA"); -// dataDirectory += "\\RetroShare"; -// -// std::cerr << "getRetroshareDataDirectory() WINDOWS: " << dataDirectory; -// std::cerr << std::endl; -// } - - /* Use RetroShare's exe dir */ - dataDirectory = "."; -#elif defined(ANDROID) - dataDirectory = PathBaseDirectory()+"/usr/share/retroshare"; -#elif defined(DATA_DIR) - // cppcheck-suppress ConfigurationNotChecked - dataDirectory = DATA_DIR; - // For all other OS the data directory must be set in libretroshare.pro -#else -# error "For your target OS automatic data dir discovery is not supported, cannot compile if DATA_DIR variable not set." -#endif - - if (!check) - { - std::cerr << "getRetroshareDataDirectory() unckecked: " << dataDirectory << std::endl; - return dataDirectory; - } - - /* Make sure the directory exists, else return emptyString */ - if (!RsDirUtil::checkDirectory(dataDirectory)) - { - std::cerr << "getRetroshareDataDirectory() not found: " << dataDirectory << std::endl; - dataDirectory = ""; - } - else - { - std::cerr << "getRetroshareDataDirectory() found: " << dataDirectory << std::endl; - } - - return dataDirectory; -} - - - -/*****************************************************************************/ -/*****************************************************************************/ -/************************* Generating Certificates ***************************/ -/*****************************************************************************/ -/*****************************************************************************/ - - - /* Generating GPGme Account */ -int RsAccountsDetail::GetPGPLogins(std::list &pgpIds) { - AuthGPG::getAuthGPG()->availableGPGCertificatesWithPrivateKeys(pgpIds); - return 1; -} - -int RsAccountsDetail::GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email) -{ - #ifdef GPG_DEBUG - std::cerr << "RsInit::GetPGPLoginDetails for \"" << id << "\"" << std::endl; - #endif - - bool ok = true ; - name = AuthGPG::getAuthGPG()->getGPGName(id,&ok); - if(!ok) - return 0 ; - email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok); - if(!ok) - return 0 ; - - if (name != "") { - return 1; - } else { - return 0; - } -} - - - -/* Before any SSL stuff can be loaded, the correct PGP must be selected / generated: - **/ - -bool RsAccountsDetail::SelectPGPAccount(const RsPgpId& pgpId) -{ - bool retVal = false; - - if (0 < AuthGPG::getAuthGPG() -> GPGInit(pgpId)) - { - retVal = true; -#ifdef DEBUG_ACCOUNTS - std::cerr << "PGP Auth Success!"; -#endif - } - else - std::cerr << "PGP Auth Failed!"; - -#ifdef DEBUG_ACCOUNTS - std::cerr << " ID: " << pgpId << std::endl; -#endif - - return retVal; -} - - -bool RsAccountsDetail::GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) -{ - return AuthGPG::getAuthGPG()->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); -} - - // PGP Support Functions. -void RsAccountsDetail::getUnsupportedKeys(std::map > &unsupported_keys) -{ - unsupported_keys = mUnsupportedKeys; - return; -} - -bool RsAccountsDetail::exportIdentity(const std::string& fname,const RsPgpId& id) -{ - return AuthGPG::getAuthGPG()->exportProfile(fname,id); -} - -bool RsAccountsDetail::importIdentity(const std::string& fname,RsPgpId& id,std::string& import_error) -{ - return AuthGPG::getAuthGPG()->importProfile(fname,id,import_error); -} - -bool RsAccountsDetail::importIdentityFromString(const std::string &data, RsPgpId &imported_pgp_id, std::string &import_error) -{ - return AuthGPG::getAuthGPG()->importProfileFromString(data, imported_pgp_id, import_error); -} - -bool RsAccountsDetail::exportIdentityToString( - std::string& data, const RsPgpId& pgpId, bool includeSignatures, - std::string& errorMsg ) -{ - return AuthGPG::getAuthGPG()->exportIdentityToString( - data, pgpId, includeSignatures, errorMsg ); -} - -bool RsAccountsDetail::copyGnuPGKeyrings() -{ - std::string pgp_dir = PathPGPDirectory() ; - - if(!RsDirUtil::checkCreateDirectory(pgp_dir)) - throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ; - - std::string source_public_keyring; - std::string source_secret_keyring; - -#ifdef WINDOWS_SYS - source_public_keyring = mBaseDirectory + "/gnupg/pubring.gpg"; - source_secret_keyring = mBaseDirectory + "/gnupg/secring.gpg" ; -#else - char *env_gnupghome = getenv("GNUPGHOME") ; - - if(env_gnupghome != NULL) - { - std::cerr << "looking into $GNUPGHOME/" << std::endl; - - source_public_keyring = std::string(env_gnupghome) + "/pubring.gpg" ; - source_secret_keyring = std::string(env_gnupghome) + "/secring.gpg" ; - } - else - { - char *env_homedir = getenv("HOME") ; - - if(env_homedir != NULL) - { - std::cerr << "looking into $HOME/.gnupg/" << std::endl; - std::string home_dir(env_homedir) ; - - // We need a specific part for MacOS and Linux as well - source_public_keyring = home_dir + "/.gnupg/pubring.gpg" ; - source_secret_keyring = home_dir + "/.gnupg/secring.gpg" ; - } - else - return false ; - } -#endif - - if(!RsDirUtil::copyFile(source_public_keyring,pgp_dir + "/retroshare_public_keyring.gpg")) - { - std::cerr << "Cannot copy pub keyring " << source_public_keyring << " to destination file " << pgp_dir + "/retroshare_public_keyring.gpg. If you believe your keyring is in a different place, please make the copy yourself." << std::endl; - return false ; - } - if(!RsDirUtil::copyFile(source_secret_keyring,pgp_dir + "/retroshare_secret_keyring.gpg")) - { - std::cerr << "Cannot copy sec keyring " << source_secret_keyring << " to destination file " << pgp_dir + "/retroshare_secret_keyring.gpg. your keyring is in a different place, please make the copy yourself." << std::endl; - return false ; - } - - return true ; -} - - - - /* Create SSL Certificates */ -bool RsAccountsDetail::GenerateSSLCertificate(const RsPgpId& pgp_id, const std::string& org, const std::string& loc, const std::string& country, bool ishiddenloc,bool isautotor, const std::string& passwd, RsPeerId &sslId, std::string &errString) -{ - /* select the PGP Identity first */ - if (!SelectPGPAccount(pgp_id)) - { - errString = "Invalid PGP Identity"; - return false; - } - - // generate the private_key / certificate. - // save to file. - // - // then load as if they had entered a passwd. - - // check password. - if (passwd.length() < 4) - { - errString = "Password is Unsatisfactory (must be 4+ chars)"; - return false; - } - - int nbits = 4096; - - //std::string pgp_name = AuthGPG::getAuthGPG()->getGPGName(pgp_id); - - // Create the filename ..... - // Temporary Directory for creating files.... - std::string tmpdir = "TMPCFG"; - - std::string tmpbase = mBaseDirectory + "/" + tmpdir + "/"; - - if(!setupAccount(tmpbase)) - return false ; - - /* create directory structure */ - std::string keypath = tmpbase + kPathKeyDirectory + "/"; - std::string key_name = keypath + kFilenameKey; - std::string cert_name = keypath + kFilenameCert; - - /* Extra step required for SSL + PGP, user must have selected - * or generated a suitable key so the signing can happen. - */ - - X509_REQ *req = GenerateX509Req( - key_name.c_str(), - passwd.c_str(), - "-", //pgp_name.c_str(), // does not allow empty name, set to constant instead - "", //ui -> gen_email -> value(), - org.c_str(), - "", //loc.c_str(), - "", //ui -> gen_state -> value(), - country.c_str(), - nbits, errString); - - if (req == NULL) - { - fprintf(stderr,"RsGenerateCert() Couldn't create Request. Reason: %s\n", errString.c_str()); - return false; - } - - long days = 3000; - X509 *x509 = AuthSSL::getAuthSSL()->SignX509ReqWithGPG(req, days); - - X509_REQ_free(req); - if (x509 == NULL) { - fprintf(stderr,"RsGenerateCert() Couldn't sign ssl certificate. Probably PGP password is wrong.\n"); - return false; - } - - /* save to file */ - - bool gen_ok = true; - - /* Print the signed Certificate! */ - BIO *bio_out = BIO_new(BIO_s_file()); - BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); - - /* Print it out */ - int nmflag = 0; - int reqflag = 0; - - X509_print_ex(bio_out, x509, nmflag, reqflag); - - (void) BIO_flush(bio_out); - BIO_free(bio_out); - - /* Save cert to file */ - // open the file. - FILE *out = NULL; - if (NULL == (out = RsDirUtil::rs_fopen(cert_name.c_str(), "w"))) - { - fprintf(stderr,"RsGenerateCert() Couldn't create Cert File"); - fprintf(stderr," : %s\n", cert_name.c_str()); - gen_ok = false; - } - - if (!PEM_write_X509(out,x509)) - { - fprintf(stderr,"RsGenerateCert() Couldn't Save Cert"); - fprintf(stderr," : %s\n", cert_name.c_str()); - gen_ok = false; - } - - fclose(out); - X509_free(x509); - - // store location name in a file - if(!RsDirUtil::saveStringToFile(keypath + kFilenameLocation, loc)) - std::cerr << "RsInit::GenerateSSLCertificate() failed to save location name to into file." << std::endl; - - if (!gen_ok) - { - errString = "Generation of Certificate Failed"; - return false; - } - - /* try to load it, and get Id */ - - std::string location; - RsPgpId pgpid_retrieved; - - if(!AuthSSL::instance().parseX509DetailsFromFile( - cert_name, sslId, pgpid_retrieved, location )) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot check own signature, maybe " - << "the files are corrupted." << std::endl; - return false; - } - - /* Move directory to correct id */ - std::string accountdir; - if (ishiddenloc) - accountdir = "HID06_" + sslId.toStdString(); - else - accountdir = "LOC06_" + sslId.toStdString(); - - std::string fullAccountDir = mBaseDirectory + "/" + accountdir; - std::string finalbase = fullAccountDir + "/"; - - /* Rename Directory */ - std::cerr << "Mv Config Dir from: " << tmpbase << " to: " << finalbase; - std::cerr << std::endl; - - if (!RsDirUtil::renameFile(tmpbase, finalbase)) - { - std::cerr << "rename FAILED" << std::endl; - } - - AccountDetails newAccount; - - newAccount.mSslId = sslId; - newAccount.mAccountDir = accountdir; - newAccount.mPgpId = pgp_id; - - newAccount.mLocation = loc; - newAccount.mIsHiddenLoc = ishiddenloc; - newAccount.mIsAutoTor = isautotor; - - newAccount.mFirstRun = true; - - // rest of newAccount pgp filled in checkAccount. - if (!checkAccount(fullAccountDir, newAccount, mUnsupportedKeys)) - { - std::cerr << "RsInit::GenerateSSLCertificate() Cannot check own signature, maybe the files are corrupted." << std::endl; - return false; - } - - mAccounts[newAccount.mSslId] = newAccount; - mPreferredId = newAccount.mSslId; - - std::cerr << "RetroShare has Successfully generated a Certficate/Key" << std::endl; - std::cerr << "\tCert Located: " << cert_name << std::endl; - std::cerr << "\tLocated: " << key_name << std::endl; - - return true; -} - - -/******************* PRIVATE FNS TO HELP with GEN **************/ -bool RsAccountsDetail::setupAccount(const std::string& accountdir) -{ - /* actual config directory isd */ - - std::string subdir1 = accountdir + "/"; - subdir1 += kPathKeyDirectory; - - std::string subdir2 = accountdir + "/"; - subdir2 += kPathConfigDirectory; - - std::string subdir3 = accountdir + "/"; - subdir3 += "cache"; - - std::string subdir4 = subdir3 + "/"; - std::string subdir5 = subdir3 + "/"; - subdir4 += "local"; - subdir5 += "remote"; - - // fatal if cannot find/create. - std::cerr << "Checking For Directories" << std::endl; - if (!RsDirUtil::checkCreateDirectory(accountdir)) - { - std::cerr << "Cannot Create BaseConfig Dir" << std::endl; - return false ; - } - if (!RsDirUtil::checkCreateDirectory(subdir1)) - { - std::cerr << "Cannot Create Key Directory" << std::endl; - return false ; - } - if (!RsDirUtil::checkCreateDirectory(subdir2)) - { - std::cerr << "Cannot Create Config Directory" << std::endl; - return false ; - } - if (!RsDirUtil::checkCreateDirectory(subdir3)) - { - std::cerr << "Cannot Create Config/Cache Dir" << std::endl; - return false ; - } - if (!RsDirUtil::checkCreateDirectory(subdir4)) - { - std::cerr << "Cannot Create Config/Cache/local Dir" << std::endl; - return false ; - } - if (!RsDirUtil::checkCreateDirectory(subdir5)) - { - std::cerr << "Cannot Create Config/Cache/remote Dir" << std::endl; - return false ; - } - - return true; -} - - - - - - -/***************************** FINAL LOADING OF SETUP *************************/ - -#if 0 - /* Login SSL */ -bool RsInit::LoadPassword(const std::string& id, const std::string& inPwd) -{ - /* select configDir */ - - RsInitConfig::preferredId = id; - - std::map::iterator it = RsInitConfig::accountIds.find(id); - if (it == RsInitConfig::accountIds.end()) - { - std::cerr << "RsInit::LoadPassword() Cannot Locate Identity: " << id; - std::cerr << std::endl; - exit(1); - } - - std::string accountdir = it->second.accountDir; - - RsInitConfig::configDir = RsInitConfig::basedir + "/" + accountdir; - RsInitConfig::passwd = inPwd; - - // if(inPwd != "") - // RsInitConfig::havePasswd = true; - - // Create the filename. - std::string basename = RsInitConfig::configDir + "/"; - basename += configKeyDir + "/"; - basename += "user"; - - RsInitConfig::load_key = basename + "_pk.pem"; - RsInitConfig::load_cert = basename + "_cert.pem"; - - return true; -} -#endif - -/********************************************************************************* - * PUBLIC INTERFACE FUNCTIONS - ********************************************************************************/ - -bool RsAccounts::init(const std::string& opt_base_dir,int& error_code) -{ - rsAccountsDetails = new RsAccountsDetail; - rsAccounts = new RsAccounts; - - // first check config directories, and set bootstrap values. - if(!rsAccountsDetails->setupBaseDirectory(opt_base_dir)) - { - error_code = RS_INIT_BASE_DIR_ERROR ; - return false ; - } - - // Setup PGP stuff. - std::string pgp_dir = rsAccountsDetails->PathPGPDirectory(); - - if(!RsDirUtil::checkCreateDirectory(pgp_dir)) - throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ; - - AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg", - pgp_dir + "/retroshare_secret_keyring.gpg", - pgp_dir + "/retroshare_trustdb.gpg", - pgp_dir + "/lock"); - - // load Accounts. - if (!rsAccountsDetails->loadAccounts()) - { - error_code = RS_INIT_NO_KEYRING ; - return false ; - } - return true; -} - - // Directories. -std::string RsAccounts::ConfigDirectory() { return RsAccountsDetail::PathBaseDirectory(); } -std::string RsAccounts::systemDataDirectory(bool check) { return RsAccountsDetail::PathDataDirectory(check); } -std::string RsAccounts::PGPDirectory() { return rsAccountsDetails->PathPGPDirectory(); } -std::string RsAccounts::AccountDirectory() { return rsAccountsDetails->getCurrentAccountPathAccountDirectory(); } -std::string RsAccounts::AccountKeysDirectory() { return rsAccountsDetails->getCurrentAccountPathAccountKeysDirectory(); } -std::string RsAccounts::AccountPathCertFile() { return rsAccountsDetails->getCurrentAccountPathCertFile(); } -std::string RsAccounts::AccountPathKeyFile() { return rsAccountsDetails->getCurrentAccountPathKeyFile(); } -std::string RsAccounts::AccountLocationName() { return rsAccountsDetails->getCurrentAccountLocationName(); } - -bool RsAccounts::lockPreferredAccount() { return rsAccountsDetails->lockPreferredAccount();} // are these methods any useful?? -void RsAccounts::unlockPreferredAccount() { rsAccountsDetails->unlockPreferredAccount(); } - -bool RsAccounts::checkCreateAccountDirectory() { return rsAccountsDetails->checkAccountDirectory(); } - -// PGP Accounts. -int RsAccounts::GetPGPLogins(std::list &pgpIds) -{ - return rsAccountsDetails->GetPGPLogins(pgpIds); -} - -int RsAccounts::GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email) -{ - return rsAccountsDetails->GetPGPLoginDetails(id, name, email); -} - -bool RsAccounts::GeneratePGPCertificate(const std::string &name, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString) -{ - return rsAccountsDetails->GeneratePGPCertificate(name, email, passwd, pgpId, keynumbits, errString); -} - -// PGP Support Functions. -bool RsAccounts::ExportIdentity(const std::string& fname,const RsPgpId& pgp_id) -{ - return rsAccountsDetails->exportIdentity(fname,pgp_id); -} - -bool RsAccounts::ImportIdentity(const std::string& fname,RsPgpId& imported_pgp_id,std::string& import_error) -{ - return rsAccountsDetails->importIdentity(fname,imported_pgp_id,import_error); -} - -bool RsAccounts::importIdentityFromString( - const std::string& data, RsPgpId& imported_pgp_id, - std::string& import_error ) -{ - return rsAccountsDetails-> - importIdentityFromString(data, imported_pgp_id, import_error); -} - -/*static*/ bool RsAccounts::exportIdentityToString( - std::string& data, const RsPgpId& pgpId, std::string& errorMsg, - bool includeSignatures ) -{ - return rsAccountsDetails->exportIdentityToString( - data, pgpId, includeSignatures, errorMsg); -} - -void RsAccounts::GetUnsupportedKeys(std::map > &unsupported_keys) -{ - return rsAccountsDetails->getUnsupportedKeys(unsupported_keys); -} - -bool RsAccounts::CopyGnuPGKeyrings() -{ - return rsAccountsDetails->copyGnuPGKeyrings(); -} - -void RsAccounts::storeSelectedAccount() { rsAccountsDetails->storePreferredAccount() ;} -// Rs Accounts -bool RsAccounts::SelectAccount(const RsPeerId &id) -{ - return rsAccountsDetails->selectId(id); -} - -bool RsAccounts::GetPreferredAccountId(RsPeerId &id) -{ - return rsAccountsDetails->getCurrentAccountId(id); -} - -bool RsAccounts::getCurrentAccountOptions(bool& is_hidden,bool& is_tor_auto,bool& is_first_time) -{ - return rsAccountsDetails->getCurrentAccountOptions(is_hidden,is_tor_auto,is_first_time); -} -bool RsAccounts::isHiddenNode() -{ - bool hidden = false ; - bool is_tor_only = false ; - bool is_first_time = false ; - - if(!getCurrentAccountOptions(hidden,is_tor_only,is_first_time)) - { - std::cerr << "(EE) Critical problem: RsAccounts::getCurrentAccountOptions() called but no account chosen!" << std::endl; - throw std::runtime_error("inconsistent configuration") ; - } - - return hidden ; -} -bool RsAccounts::isTorAuto() -{ - bool hidden = false ; - bool is_tor_only = false ; - bool is_first_time = false ; - - if(!getCurrentAccountOptions(hidden,is_tor_only,is_first_time)) - { - std::cerr << "(EE) Critical problem: RsAccounts::getCurrentAccountOptions() called but no account chosen!" << std::endl; - throw std::runtime_error("inconsistent configuration") ; - } - - return is_tor_only ; -} - -bool RsAccounts::GetAccountIds(std::list &ids) -{ - return rsAccountsDetails->getAccountIds(ids); -} - -bool RsAccounts::GetAccountDetails(const RsPeerId &id, - RsPgpId &pgpId, std::string &pgpName, - std::string &pgpEmail, std::string &location) -{ - return rsAccountsDetails->getCurrentAccountDetails(id, pgpId, pgpName, pgpEmail, location); -} - -bool RsAccounts::createNewAccount( - const RsPgpId& pgp_id, const std::string& org, const std::string& loc, - const std::string& country, bool ishiddenloc, bool isautotor, - const std::string& passwd, RsPeerId &sslId, std::string &errString ) -{ - return rsAccountsDetails->GenerateSSLCertificate(pgp_id, org, loc, country, ishiddenloc, isautotor, passwd, sslId, errString); -} - -/********************************************************************************* - * END OF: PUBLIC INTERFACE FUNCTIONS - ********************************************************************************/ - -std::string RsAccountsDetail::mBaseDirectory; diff --git a/libretroshare/src/rsserver/rsaccounts.h b/libretroshare/src/rsserver/rsaccounts.h deleted file mode 100644 index 2db4552a7..000000000 --- a/libretroshare/src/rsserver/rsaccounts.h +++ /dev/null @@ -1,150 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: rsaccounts.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/********************************************************************* - * Header providing interface for libretroshare access to RsAccounts stuff. - * External access must be through rsinit.g where a RsAccounts namespace + fns - * are available. - * - */ - -#pragma once - -#include -#include -#include -#include "retroshare/rstypes.h" - -class AccountDetails -{ - public: - AccountDetails(); - - RsPeerId mSslId; - std::string mAccountDir; - - RsPgpId mPgpId; - std::string mPgpName; - std::string mPgpEmail; - - std::string mLocation; - bool mIsHiddenLoc; - bool mFirstRun; - bool mIsAutoTor; - -}; - -class RsAccountsDetail -{ - public: - RsAccountsDetail(); - - // These functions are externally accessible via RsAccounts namespace. - // These functions are accessible from inside libretroshare. - - bool setupBaseDirectory(std::string alt_basedir); - bool loadAccounts(); - bool lockPreferredAccount(); - void unlockPreferredAccount(); - bool checkAccountDirectory(); - - // Paths. - /** - * @brief PathDataDirectory - * @param check if set to true and directory does not exist, return empty string - * @return path where global platform independent files are stored, like bdboot.txt or webinterface files - */ - static std::string PathDataDirectory(bool check = true); - - /** - * @brief PathBaseDirectory - * @return path where user data is stored ( on Linux and similar - * systems it is usually something like /home/USERNAME/.retroshare ). - */ - static std::string PathBaseDirectory(); - - // PGP Path is only dependent on BaseDirectory. - std::string PathPGPDirectory(); - - // Generate a new account based on a given PGP key returns its SSL id and sets it to be the preferred account. - - bool GenerateSSLCertificate(const RsPgpId& gpg_id, const std::string& org, const std::string& loc, const std::string& country, bool ishiddenloc, bool is_auto_tor,const std::string& passwd, RsPeerId &sslId, std::string &errString); - - // PGP Accounts. - - int GetPGPLogins(std::list &pgpIds); - int GetPGPLoginDetails(const RsPgpId& id, std::string &name, std::string &email); - bool GeneratePGPCertificate(const std::string&, const std::string& email, const std::string& passwd, RsPgpId &pgpId, const int keynumbits, std::string &errString); - bool SelectPGPAccount(const RsPgpId& pgpId); - - // PGP Support Functions. - bool exportIdentity(const std::string& fname,const RsPgpId& pgp_id) ; - bool importIdentity(const std::string& fname,RsPgpId& imported_pgp_id,std::string& import_error) ; - bool exportIdentityToString( - std::string& data, const RsPgpId& pgpId, bool includeSignatures, - std::string& errorMsg ); - bool importIdentityFromString(const std::string& data,RsPgpId& imported_pgp_id,std::string& import_error) ; - void getUnsupportedKeys(std::map > &unsupported_keys); - bool copyGnuPGKeyrings() ; - - // Selecting Rs Account. - bool getAccountIds(std::list &ids); - bool selectAccountByString(const std::string &prefUserString); - bool selectId(const RsPeerId& preferredId); - bool storePreferredAccount(); - bool loadPreferredAccount(); - - // Details of current Rs Account. - bool getCurrentAccountId(RsPeerId &id); - bool getCurrentAccountDetails(const RsPeerId &id, RsPgpId& gpgId, std::string &gpgName, std::string &gpgEmail, std::string &location); - bool getCurrentAccountOptions(bool &ishidden, bool &isautotor, bool &isFirstTimeRun); - - std::string getCurrentAccountPathAccountDirectory(); - std::string getCurrentAccountPathAccountKeysDirectory(); - std::string getCurrentAccountPathKeyFile(); - std::string getCurrentAccountPathCertFile(); - std::string getCurrentAccountLocationName(); - - - private: - bool checkPreferredId(); - - static bool defaultBaseDirectory(); - - bool getAvailableAccounts(std::map &accounts, - int& failing_accounts, - std::map >& unsupported_keys, bool hidden_only=false); - - bool setupAccount(const std::string& accountdir); - - private: - - bool mAccountsLocked; - - std::map mAccounts; - RsPeerId mPreferredId; - static std::string mBaseDirectory; - - std::map > mUnsupportedKeys ; -}; - - diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc deleted file mode 100644 index 8449a9e3e..000000000 --- a/libretroshare/src/rsserver/rsinit.cc +++ /dev/null @@ -1,2073 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsinit.cc * - * * - * Copyright (C) 2004-2014 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/// RetroShare initialization and login API implementation - -#include - -#ifndef WINDOWS_SYS -// for locking instances -#include -#else -#include "util/rswin.h" -#endif - -#ifdef __ANDROID__ -# include // To install bdboot.txt -# include // for QString::fromStdString(...) -#endif - -#include "util/argstream.h" -#include "util/rsdebug.h" -#include "util/rsdir.h" -#include "util/rsrandom.h" -#include "util/folderiterator.h" -#include "util/rsstring.h" -#include "retroshare/rsinit.h" -#include "retroshare/rsnotify.h" -#include "retroshare/rsiface.h" -#include "plugins/pluginmanager.h" -#include "retroshare/rsversion.h" -#include "rsserver/rsloginhandler.h" -#include "rsserver/rsaccounts.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include "gxstunnel/p3gxstunnel.h" -#include "retroshare/rsgxsdistsync.h" -#include "file_sharing/p3filelists.h" - -#define ENABLE_GROUTER - -#if (defined(__unix__) || defined(unix)) && !defined(USG) -#include -#endif - -// This needs to be defined here, because when USE_BITDHT is unset, the variable, that is defined in libbitdht (not compiled!) will be missing. -#ifndef RS_USE_BITDHT -RsDht *rsDht = NULL ; -#endif - -// for blocking signals -#include - -#include - -#include "pqi/authssl.h" -#include "pqi/sslfns.h" -#include "pqi/authgpg.h" - -#ifdef ENABLE_GROUTER -#include "grouter/p3grouter.h" -#endif - -#ifdef RS_USE_DHT_STUNNER -#include "tcponudp/udpstunner.h" -#endif // RS_USE_DHT_STUNNER - -#ifdef RS_GXS_TRANS -# include "gxstrans/p3gxstrans.h" -#endif - -#ifdef RS_JSONAPI -# include "jsonapi/jsonapi.h" -#endif - -#ifdef RS_BROADCAST_DISCOVERY -# include "retroshare/rsbroadcastdiscovery.h" -# include "services/broadcastdiscoveryservice.h" -#endif // def RS_BROADCAST_DISCOVERY - -// #define GPG_DEBUG -// #define AUTHSSL_DEBUG -// #define FIM_DEBUG -// #define DEBUG_RSINIT - -//std::map > RsInit::unsupported_keys ; - -RsLoginHelper* rsLoginHelper = nullptr; - -RsAccounts* rsAccounts = nullptr; - -const RsInitErrorCategory RsInitErrorCategory::instance; - -RsConfigOptions::RsConfigOptions() - : - autoLogin(false), - udpListenerOnly(false), - forcedInetAddress("127.0.0.1"), /* inet address to use.*/ - forcedPort(0), - outStderr(false), - debugLevel(5) -#ifdef RS_JSONAPI - ,jsonApiPort(0) // JSonAPI server is enabled in each main() - ,jsonApiBindAddress("127.0.0.1") -#endif -{ -} - - -struct RsInitConfig -{ - RsInitConfig() -#ifdef RS_JSONAPI - : jsonApiPort(JsonApiServer::DEFAULT_PORT), - jsonApiBindAddress("127.0.0.1") -#endif - {} - - RsFileHash main_executable_hash; - -#ifdef WINDOWS_SYS - bool portable; - bool isWindowsXP; -#endif - rs_lock_handle_t lockHandle; - - std::string passwd; - std::string gxs_passwd; - - bool autoLogin; /* autoLogin allowed */ - bool startMinimised; /* Icon or Full Window */ - - /* Key Parameters that must be set before - * RetroShare will start up: - */ - - /* Listening Port */ - bool forceExtPort; - bool forceLocalAddr; - unsigned short port; - std::string inet ; - - /* v0.6 features */ - bool hiddenNodeSet; - std::string hiddenNodeAddress; - uint16_t hiddenNodePort; - - bool hiddenNodeI2PBOB; - - /* Logging */ - bool haveLogFile; - bool outStderr; - int debugLevel; - std::string logfname; - - bool udpListenerOnly; - std::string opModeStr; - std::string optBaseDir; - - uint16_t jsonApiPort; - std::string jsonApiBindAddress; -}; - -static RsInitConfig* rsInitConfig = nullptr; - -static const std::string configLogFileName = "retro.log"; -static const int SSLPWD_LEN = 64; - -void RsInit::InitRsConfig() -{ - RsInfo() << " libretroshare version: " << RS_HUMAN_READABLE_VERSION - << std::endl; - - rsInitConfig = new RsInitConfig; - - - /* TODO almost all of this should be moved to RsInitConfig::RsInitConfig - * initializers */ - - /* Directories */ -#ifdef WINDOWS_SYS - rsInitConfig->portable = false; - rsInitConfig->isWindowsXP = false; -#endif - /* v0.6 features */ - rsInitConfig->hiddenNodeSet = false; - - - // This doesn't seems a configuration... -#ifndef WINDOWS_SYS - rsInitConfig->lockHandle = -1; -#else - rsInitConfig->lockHandle = NULL; -#endif - - rsInitConfig->port = 0 ; - rsInitConfig->forceLocalAddr = false; - rsInitConfig->haveLogFile = false; - rsInitConfig->outStderr = false; - rsInitConfig->forceExtPort = false; - - rsInitConfig->inet = std::string("127.0.0.1"); - - rsInitConfig->autoLogin = false; // . - rsInitConfig->startMinimised = false; - rsInitConfig->passwd = ""; - rsInitConfig->debugLevel = PQL_WARNING; - rsInitConfig->udpListenerOnly = false; - rsInitConfig->opModeStr = std::string(""); - -#ifdef WINDOWS_SYS - // test for portable version - if (GetFileAttributes(L"portable") != (DWORD) -1) { - // use portable version - rsInitConfig->portable = true; - } - - // test for Windows XP - OSVERSIONINFOEX osvi; - memset(&osvi, 0, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - if (GetVersionEx((OSVERSIONINFO*) &osvi)) { - if (osvi.dwMajorVersion == 5) { - if (osvi.dwMinorVersion == 1) { - /* Windows XP */ - rsInitConfig->isWindowsXP = true; - } else if (osvi.dwMinorVersion == 2) { - SYSTEM_INFO si; - memset(&si, 0, sizeof(si)); - GetSystemInfo(&si); - if (osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) { - /* Windows XP Professional x64 Edition */ - rsInitConfig->isWindowsXP = true; - } - } - } - } - - if (rsInitConfig->isWindowsXP) { - std::cerr << "Running Windows XP" << std::endl; - } else { - std::cerr << "Not running Windows XP" << std::endl; - } -#endif - - setOutputLevel(RsLog::Warning); -} - -#ifdef LOCALNET_TESTING - -std::string portRestrictions; -bool doPortRestrictions = false; - -#endif - -#ifdef WINDOWS_SYS -#ifdef PTW32_STATIC_LIB -#include -#endif -#endif - -/******** - * LOCALNET_TESTING - allows port restrictions - * - * #define LOCALNET_TESTING 1 - * - ********/ -int RsInit::InitRetroShare(const RsConfigOptions& conf) -{ - rsInitConfig->autoLogin = conf.autoLogin; - rsInitConfig->outStderr = conf.outStderr; - rsInitConfig->logfname = conf.logfname ; - rsInitConfig->inet = conf.forcedInetAddress ; - rsInitConfig->port = conf.forcedPort ; - rsInitConfig->debugLevel = conf.debugLevel; - rsInitConfig->udpListenerOnly = conf.udpListenerOnly; - rsInitConfig->optBaseDir = conf.optBaseDir; - rsInitConfig->jsonApiPort = conf.jsonApiPort; - rsInitConfig->jsonApiBindAddress = conf.jsonApiBindAddress; - -#ifdef PTW32_STATIC_LIB - // for static PThreads under windows... we need to init the library... - pthread_win32_process_attach_np(); -#endif - if( rsInitConfig->autoLogin) rsInitConfig->startMinimised = true ; - if( rsInitConfig->outStderr) rsInitConfig->haveLogFile = false ; - if(!rsInitConfig->logfname.empty()) rsInitConfig->haveLogFile = true; - if( rsInitConfig->inet != "127.0.0.1") rsInitConfig->forceLocalAddr = true; - if( rsInitConfig->port != 0) rsInitConfig->forceLocalAddr = true; // previously forceExtPort, which means nothing in this case -#ifdef LOCALNET_TESTING - if(!portRestrictions.empty()) doPortRestrictions = true; -#endif - - setOutputLevel((RsLog::logLvl)rsInitConfig->debugLevel); - - // set the debug file. - if (rsInitConfig->haveLogFile) - setDebugFile(rsInitConfig->logfname.c_str()); - - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif - /********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - // SWITCH off the SIGPIPE - kills process on Linux. - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - struct sigaction sigact; - sigact.sa_handler = SIG_IGN; - sigact.sa_flags = 0; - - sigset_t set; - sigemptyset(&set); - //sigaddset(&set, SIGINT); // or whatever other signal - sigact.sa_mask = set; - - if (0 == sigaction(SIGPIPE, &sigact, NULL)) - { - std::cerr << "RetroShare:: Successfully installed the SIGPIPE Block" << std::endl; - } - else - { - std::cerr << "RetroShare:: Failed to install the SIGPIPE Block" << std::endl; - } -#endif - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - // Hash the main executable. - - uint64_t tmp_size ; - - if(conf.main_executable_path.empty()) - { - std::cerr << "Executable path is unknown. It should normally have been set in passed RsConfigOptions structure" << std::endl; - return 1; - } - if(!RsDirUtil::getFileHash(conf.main_executable_path,rsInitConfig->main_executable_hash,tmp_size,NULL)) - std::cerr << "Cannot hash executable! Plugins will not be loaded correctly." << std::endl; - else - std::cerr << "Hashed main executable: " << rsInitConfig->main_executable_hash << std::endl; - - /* At this point we want to. - * 1) Load up Dase Directory. - * 3) Get Prefered Id. - * 2) Get List of Available Accounts. - * 4) Get List of GPG Accounts. - */ - /* Initialize AuthSSL */ - AuthSSL::instance().InitAuth(nullptr, nullptr, nullptr, ""); - - rsLoginHelper = new RsLoginHelper; - - int error_code ; - - if(!RsAccounts::init(rsInitConfig->optBaseDir,error_code)) - return error_code ; - -#ifdef RS_JSONAPI - // We create the JsonApiServer this early, because it is needed *before* login - RsDbg() << __PRETTY_FUNCTION__ - << " Allocating JSON API server (not launched yet)" << std::endl; - JsonApiServer* jas = new JsonApiServer(); - jas->setListeningPort(conf.jsonApiPort); - jas->setBindingAddress(conf.jsonApiBindAddress); - - if(conf.jsonApiPort != 0) jas->restart(); - - rsJsonApi = jas; -#endif - -#ifdef RS_AUTOLOGIN - /* check that we have selected someone */ - RsPeerId preferredId; - bool existingUser = RsAccounts::GetPreferredAccountId(preferredId); - - if (existingUser) - { - if(RsLoginHandler::getSSLPassword(preferredId,false,rsInitConfig->passwd)) - { - RsInit::setAutoLogin(true); - std::cerr << "Autologin has succeeded" << std::endl; - return RS_INIT_HAVE_ACCOUNT; - } - } -#endif - - return RS_INIT_OK; -} - - -/* - * To prevent several running instances from using the same directory - * simultaneously we have to use a global lock. - * We use a lock file on Unix systems. - * - * Return value: - * 0 : Success - * 1 : Another instance already has the lock - * 2 : Unexpected error - */ -RsInit::LoadCertificateStatus RsInit::LockConfigDirectory( - const std::string& accountDir, std::string& lockFilePath ) -{ - const std::string lockFile = accountDir + "/" + "lock"; - lockFilePath = lockFile; - - int rt = RsDirUtil::createLockFile(lockFile,rsInitConfig->lockHandle); - - switch (rt) - { - case 0: return RsInit::OK; - case 1: return RsInit::ERR_ALREADY_RUNNING; - case 2: return RsInit::ERR_CANT_ACQUIRE_LOCK; - default: return RsInit::ERR_UNKNOWN; - } -} - -/* - * Unlock the currently locked profile, if there is one. - * For Unix systems we simply close the handle of the lock file. - */ -void RsInit::UnlockConfigDirectory() -{ - RsDirUtil::releaseLockFile(rsInitConfig->lockHandle) ; -} - - - - -bool RsInit::collectEntropy(uint32_t n) -{ - RAND_seed(&n,4) ; - - return true ; -} - -/***************************** FINAL LOADING OF SETUP *************************/ - - - /* Login SSL */ -bool RsInit::LoadPassword(const std::string& inPwd) -{ - rsInitConfig->passwd = inPwd; - return true; -} - -std::string RsInit::lockFilePath() -{ - return RsAccounts::AccountDirectory() + "/lock" ; -} - -RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates( - bool autoLoginNT, std::string& lockFilePath ) -{ - try - { - if (!RsAccounts::lockPreferredAccount()) - throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount. - - // Logic that used to be external to RsInit... - RsPeerId accountId; - if (!RsAccounts::GetPreferredAccountId(accountId)) - throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - - RsPgpId pgpId; - std::string pgpName, pgpEmail, location; - - if(!RsAccounts::GetAccountDetails(accountId, pgpId, pgpName, pgpEmail, location)) - throw RsInit::ERR_UNKNOWN; // invalid PreferredAccount; - - if(0 == AuthGPG::getAuthGPG() -> GPGInit(pgpId)) - throw RsInit::ERR_UNKNOWN; // PGP Error. - - LoadCertificateStatus retVal = - LockConfigDirectory(RsAccounts::AccountDirectory(), lockFilePath); - - if(retVal > 0) - throw retVal ; - - if(LoadCertificates(autoLoginNT) != 1) - { - UnlockConfigDirectory(); - throw RsInit::ERR_UNKNOWN; - } - - return RsInit::OK; - } - catch(LoadCertificateStatus retVal) - { - RsAccounts::unlockPreferredAccount(); - return retVal ; - } -} - - -/** *************************** FINAL LOADING OF SETUP ************************* - * Requires: - * PGPid to be selected (Password not required). - * CertId to be selected (Password Required). - * - * Return value: - * 0 : unexpected error - * 1 : success - */ -int RsInit::LoadCertificates(bool autoLoginNT) -{ - RsPeerId preferredId; - if (!RsAccounts::GetPreferredAccountId(preferredId)) - { - std::cerr << "No Account Selected" << std::endl; - return 0; - } - - - if (RsAccounts::AccountPathCertFile() == "") - { - std::cerr << "RetroShare needs a certificate" << std::endl; - return 0; - } - - if (RsAccounts::AccountPathKeyFile() == "") - { - std::cerr << "RetroShare needs a key" << std::endl; - return 0; - } - - //check if password is already in memory - - if(rsInitConfig->passwd == "") { - if (RsLoginHandler::getSSLPassword(preferredId,true,rsInitConfig->passwd) == false) { -#ifdef DEBUG_RSINIT - std::cerr << "RsLoginHandler::getSSLPassword() Failed!"; -#endif - return 0 ; - } - } else { - if (RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile(preferredId,rsInitConfig->passwd) == false) { - std::cerr << "RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile() Failed!"; - return 0; - } - } - - std::cerr << "rsAccounts->PathKeyFile() : " << RsAccounts::AccountPathKeyFile() << std::endl; - - if(0 == AuthSSL::getAuthSSL() -> InitAuth(RsAccounts::AccountPathCertFile().c_str(), RsAccounts::AccountPathKeyFile().c_str(), rsInitConfig->passwd.c_str(), - RsAccounts::AccountLocationName())) - { - std::cerr << "SSL Auth Failed!"; - return 0 ; - } - -#ifdef RS_AUTOLOGIN - if(autoLoginNT) - { - std::cerr << "RetroShare will AutoLogin next time" << std::endl; - - RsLoginHandler::enableAutoLogin(preferredId,rsInitConfig->passwd); - rsInitConfig->autoLogin = true ; - } -#else - (void) autoLoginNT; -#endif // RS_AUTOLOGIN - - /* wipe out password */ - - // store pword to allow gxs use it to services' key their databases - // ideally gxs should have its own password - rsInitConfig->gxs_passwd = rsInitConfig->passwd; - rsInitConfig->passwd = ""; - - RsAccounts::storeSelectedAccount(); - return 1; -} - -#ifdef RS_AUTOLOGIN -bool RsInit::RsClearAutoLogin() -{ - RsPeerId preferredId; - if (!RsAccounts::GetPreferredAccountId(preferredId)) - { - std::cerr << "RsInit::RsClearAutoLogin() No Account Selected" << std::endl; - return 0; - } - return RsLoginHandler::clearAutoLogin(preferredId); -} -#endif // RS_AUTOLOGIN - - -bool RsInit::isPortable() -{ -#ifdef WINDOWS_SYS - return rsInitConfig->portable; -#else - return false; -#endif -} - -bool RsInit::isWindowsXP() -{ -#ifdef WINDOWS_SYS - return rsInitConfig->isWindowsXP; -#else - return false; -#endif -} - -bool RsInit::getStartMinimised() -{ - return rsInitConfig->startMinimised; -} - -int RsInit::getSslPwdLen(){ - return SSLPWD_LEN; -} - -bool RsInit::getAutoLogin(){ - return rsInitConfig->autoLogin; -} - -void RsInit::setAutoLogin(bool autoLogin){ - rsInitConfig->autoLogin = autoLogin; -} - -/* Setup Hidden Location; */ -void RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob) -{ - /* parse the bugger (todo) */ - rsInitConfig->hiddenNodeSet = true; - rsInitConfig->hiddenNodeAddress = hiddenaddress; - rsInitConfig->hiddenNodePort = port; - rsInitConfig->hiddenNodeI2PBOB = useBob; -} - - -/* - * - * Init Part of RsServer... needs the private - * variables so in the same file. - * - */ - -#include -//#include - -#include "ft/ftserver.h" -#include "ft/ftcontroller.h" - -#include "retroshare/rsiface.h" -#include "retroshare/rsturtle.h" - -/* global variable now points straight to - * ft/ code so variable defined here. - */ - -RsFiles *rsFiles = NULL; -RsTurtle *rsTurtle = NULL ; -RsReputations *rsReputations = NULL ; -#ifdef ENABLE_GROUTER -RsGRouter *rsGRouter = NULL ; -#endif - -#include "pqi/pqipersongrp.h" -#include "pqi/pqisslpersongrp.h" -#include "pqi/pqiloopback.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/p3historymgr.h" - -#include "util/rsdebug.h" -#include "util/rsdir.h" -#include "util/rsrandom.h" - -#ifdef RS_USE_LIBUPNP -# include "rs_upnp/upnphandler_libupnp.h" -#else // def RS_USE_LIBUPNP -# include "rs_upnp/upnphandler_miniupnp.h" -#endif // def RS_USE_LIBUPNP - -#include "services/autoproxy/p3i2pbob.h" -#include "services/autoproxy/rsautoproxymonitor.h" - -#include "services/p3gxsreputation.h" -#include "services/p3serviceinfo.h" -#include "services/p3heartbeat.h" -#include "gossipdiscovery/p3gossipdiscovery.h" -#include "services/p3msgservice.h" -#include "services/p3statusservice.h" - -#include "turtle/p3turtle.h" -#include "chat/p3chatservice.h" - -#ifdef RS_ENABLE_GXS -// NEW GXS SYSTEMS. -#include "gxs/rsdataservice.h" -#include "gxs/rsgxsnetservice.h" -#include "retroshare/rsgxsflags.h" - -#include "pgp/pgpauxutils.h" -#include "services/p3idservice.h" -#include "services/p3gxscircles.h" -#include "services/p3posted.h" -#include "services/p3gxsforums.h" -#include "services/p3gxschannels.h" - -#include "services/p3wiki.h" -#include "services/p3wire.h" -#include "services/p3photoservice.h" - -#endif // RS_ENABLE_GXS - - -#include -#include - -// for blocking signals -#include - -/* Implemented Rs Interfaces */ -#include "rsserver/p3face.h" -#include "rsserver/p3peers.h" -#include "rsserver/p3msgs.h" -#include "rsserver/p3status.h" -#include "rsserver/p3history.h" -#include "rsserver/p3serverconfig.h" - - -#include "pqi/p3notify.h" // HACK - moved to pqi for compilation order. - -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" - -#include "tcponudp/tou.h" -#include "tcponudp/rsudpstack.h" - -#ifdef RS_USE_BITDHT -#include "dht/p3bitdht.h" -#ifdef RS_USE_DHT_STUNNER -#include "dht/stunaddrassist.h" -#endif // RS_USE_DHT_STUNNER - -#include "udp/udpstack.h" -#include "tcponudp/udppeer.h" -#include "tcponudp/udprelay.h" -#endif - -/**** - * #define RS_RELEASE 1 - * #define RS_RTT 1 -****/ - -#define RS_RELEASE 1 -#define RS_RTT 1 - - -#ifdef RS_RTT -#include "services/p3rtt.h" -#endif - - -#include "services/p3banlist.h" -#include "services/p3bwctrl.h" - -#ifdef SERVICES_DSDV -#include "services/p3dsdv.h" -#endif - -RsControl *RsControl::instance() -{ - static RsServer rsicontrol; - return &rsicontrol; -} - - -/* - * The Real RetroShare Startup Function. - */ - -int RsServer::StartupRetroShare() -{ - RsPeerId ownId = AuthSSL::getAuthSSL()->OwnId(); - - std::cerr << "========================================================================" << std::endl; - std::cerr << "== RsInit:: starting up Retroshare core ==" << std::endl; - std::cerr << "== ==" << std::endl; - std::cerr << "== Account/SSL ID : " << ownId << " ==" << std::endl; - std::cerr << "== Node type : " << (RsAccounts::isHiddenNode()?"Hidden":"Normal") << " ==" << std::endl; - if(RsAccounts::isHiddenNode()) - std::cerr << "== Tor/I2P configuration : " << (RsAccounts::isTorAuto()?"Tor Auto":"Manual ") << " ==" << std::endl; - std::cerr << "========================================================================" << std::endl; - - /**************************************************************************/ - /* STARTUP procedure */ - /**************************************************************************/ - /**************************************************************************/ - /* (1) Load up own certificate (DONE ALREADY) - just CHECK */ - /**************************************************************************/ - - if (1 != AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "")) - { - std::cerr << "main() - Fatal Error....." << std::endl; - std::cerr << "Invalid Certificate configuration!" << std::endl; - std::cerr << std::endl; - return false ; - } - - /**************************************************************************/ - /* Any Initial Configuration (Commandline Options) */ - /**************************************************************************/ - - /* set the debugging to crashMode */ - std::cerr << "set the debugging to crashMode." << std::endl; - if ((!rsInitConfig->haveLogFile) && (!rsInitConfig->outStderr)) - { - std::string crashfile = RsAccounts::AccountDirectory(); - crashfile += "/" + configLogFileName; - setDebugCrashMode(crashfile.c_str()); - } - - unsigned long flags = 0; - if (rsInitConfig->udpListenerOnly) - { - flags |= PQIPERSON_NO_LISTENER; - } - - /* check account directory */ - if (!RsAccounts::checkCreateAccountDirectory()) - { - std::cerr << "RsServer::StartupRetroShare() - Fatal Error....." << std::endl; - std::cerr << "checkAccount failed!" << std::endl; - std::cerr << std::endl; - return 0; - } - - /**************************************************************************/ - // Load up Certificates, and Old Configuration (if present) - std::cerr << "Load up Certificates, and Old Configuration (if present)." << std::endl; - - std::string emergencySaveDir = RsAccounts::AccountDirectory(); - std::string emergencyPartialsDir = RsAccounts::AccountDirectory(); - if (emergencySaveDir != "") - { - emergencySaveDir += "/"; - emergencyPartialsDir += "/"; - } - emergencySaveDir += "Downloads"; - emergencyPartialsDir += "Partials"; - - /**************************************************************************/ - /* setup Configuration */ - /**************************************************************************/ - std::cerr << "Load Configuration" << std::endl; - - mConfigMgr = new p3ConfigMgr(RsAccounts::AccountDirectory()); - mGeneralConfig = new p3GeneralConfig(); - - // Get configuration options from rsAccounts. - bool isHiddenNode = false; - bool isFirstTimeRun = false; - bool isTorAuto = false; - - RsAccounts::getCurrentAccountOptions(isHiddenNode,isTorAuto, isFirstTimeRun); - - /**************************************************************************/ - /* setup classes / structures */ - /**************************************************************************/ - std::cerr << "setup classes / structures" << std::endl; - - /* History Manager */ - mHistoryMgr = new p3HistoryMgr(); - mPeerMgr = new p3PeerMgrIMPL( AuthSSL::getAuthSSL()->OwnId(), - AuthGPG::getAuthGPG()->getGPGOwnId(), - AuthGPG::getAuthGPG()->getGPGOwnName(), - AuthSSL::getAuthSSL()->getOwnLocation()); - mNetMgr = new p3NetMgrIMPL(); - mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr); - - /* Setup Notify Early - So we can use it. */ - rsPeers = new p3Peers(mLinkMgr, mPeerMgr, mNetMgr); - - mPeerMgr->setManagers(mLinkMgr, mNetMgr); - mNetMgr->setManagers(mPeerMgr, mLinkMgr); - - rsAutoProxyMonitor *autoProxy = rsAutoProxyMonitor::instance(); -#ifdef RS_USE_I2P_BOB - mI2pBob = new p3I2pBob(mPeerMgr); - autoProxy->addProxy(autoProxyType::I2PBOB, mI2pBob); -#endif - - //load all the SSL certs as friends - // std::list sslIds; - // AuthSSL::getAuthSSL()->getAuthenticatedList(sslIds); - // for (std::list::iterator sslIdsIt = sslIds.begin(); sslIdsIt != sslIds.end(); ++sslIdsIt) { - // mConnMgr->addFriend(*sslIdsIt); - // } - //p3DhtMgr *mDhtMgr = new OpenDHTMgr(ownId, mConnMgr, rsInitConfig->configDir); - /**************************** BITDHT ***********************************/ - - // Make up an address. XXX - - struct sockaddr_in tmpladdr; - sockaddr_clear(&tmpladdr); - tmpladdr.sin_port = htons(rsInitConfig->port); - - rsUdpStack *mDhtStack = NULL ; - - if(!RsAccounts::isHiddenNode()) - { -#ifdef LOCALNET_TESTING - - mDhtStack = new rsUdpStack(UDP_TEST_RESTRICTED_LAYER, tmpladdr); - - /* parse portRestrictions */ - unsigned int lport, uport; - - if (doPortRestrictions) - { - if (2 == sscanf(portRestrictions.c_str(), "%u-%u", &lport, &uport)) - { - std::cerr << "Adding Port Restriction (" << lport << "-" << uport << ")"; - std::cerr << std::endl; - } - else - { - std::cerr << "Failed to parse Port Restrictions ... exiting"; - std::cerr << std::endl; - exit(1); - } - - RestrictedUdpLayer *url = (RestrictedUdpLayer *) mDhtStack->getUdpLayer(); - url->addRestrictedPortRange(lport, uport); - } -#else //LOCALNET_TESTING -#ifdef RS_USE_BITDHT - mDhtStack = new rsUdpStack(tmpladdr); -#endif -#endif //LOCALNET_TESTING - } - -#ifdef RS_USE_BITDHT - -#define BITDHT_BOOTSTRAP_FILENAME "bdboot.txt" -#define BITDHT_FILTERED_IP_FILENAME "bdfilter.txt" - - - std::string bootstrapfile = RsAccounts::AccountDirectory(); - if (bootstrapfile != "") - bootstrapfile += "/"; - bootstrapfile += BITDHT_BOOTSTRAP_FILENAME; - - std::string installfile = ""; -#ifndef __ANDROID__ - installfile = RsAccounts::systemDataDirectory(); - installfile += "/"; - installfile += BITDHT_BOOTSTRAP_FILENAME; -#endif - - std::string filteredipfile = RsAccounts::AccountDirectory(); - if (filteredipfile != "") - filteredipfile += "/"; - filteredipfile += BITDHT_FILTERED_IP_FILENAME; - - std::cerr << "Checking for DHT bootstrap file: " << bootstrapfile << std::endl; - - /* check if bootstrap file exists... - * if not... copy from dataDirectory - */ - - uint64_t tmp_size ; - if (!RsDirUtil::checkFile(bootstrapfile,tmp_size,true)) - { - std::cerr << "DHT bootstrap file not in ConfigDir: " << bootstrapfile - << std::endl; -#ifdef __ANDROID__ - QFile bdbootRF("assets:/values/bdboot.txt"); - if(!bdbootRF.open(QIODevice::ReadOnly | QIODevice::Text)) - std::cerr << __PRETTY_FUNCTION__ - << " bdbootRF(assets:/values/bdboot.txt).open(...) fail: " - << bdbootRF.errorString().toStdString() << std::endl; - else - { - QFile bdbootCF(QString::fromStdString(bootstrapfile)); - if(!bdbootCF.open(QIODevice::WriteOnly | QIODevice::Text)) - std::cerr << __PRETTY_FUNCTION__ << " bdbootCF(" - << bootstrapfile << ").open(...) fail: " - << bdbootRF.errorString().toStdString() << std::endl; - else - { - bdbootCF.write(bdbootRF.readAll()); - bdbootCF.close(); - std::cerr << "Installed DHT bootstrap file not in ConfigDir: " - << bootstrapfile << std::endl; - } - - bdbootRF.close(); - } -#else - std::cerr << "Checking for Installation DHT bootstrap file " << installfile << std::endl; - if ((installfile != "") && (RsDirUtil::checkFile(installfile,tmp_size))) - { - std::cerr << "Copying Installation DHT bootstrap file..." << std::endl; - if (RsDirUtil::copyFile(installfile, bootstrapfile)) - { - std::cerr << "Installed DHT bootstrap file in configDir" << std::endl; - } - else - { - std::cerr << "Failed Installation DHT bootstrap file..." << std::endl; - } - } - else - { - std::cerr << "No Installation DHT bootstrap file to copy" << std::endl; - } -#endif // def __ANDROID__ - } - - /* construct the rest of the stack, important to build them in the correct order! */ - /* MOST OF THIS IS COMMENTED OUT UNTIL THE REST OF libretroshare IS READY FOR IT! */ - - p3BitDht *mBitDht = NULL ; - rsDht = NULL ; - rsFixedUdpStack *mProxyStack = NULL ; - - if(!RsAccounts::isHiddenNode()) - { - UdpSubReceiver *udpReceivers[RSUDP_NUM_TOU_RECVERS]; - int udpTypes[RSUDP_NUM_TOU_RECVERS]; - -#ifdef RS_USE_DHT_STUNNER - // FIRST DHT STUNNER. - UdpStunner *mDhtStunner = new UdpStunner(mDhtStack); - mDhtStunner->setTargetStunPeriod(300); /* slow (5mins) */ - mDhtStack->addReceiver(mDhtStunner); - -#ifdef LOCALNET_TESTING - mDhtStunner->SetAcceptLocalNet(); -#endif -#endif // RS_USE_DHT_STUNNER - - - // NEXT BITDHT. - - - mBitDht = new p3BitDht(ownId, mLinkMgr, mNetMgr, mDhtStack, bootstrapfile, installfile, filteredipfile); - - // NEXT THE RELAY (NEED to keep a reference for installing RELAYS) - UdpRelayReceiver *mRelay = new UdpRelayReceiver(mDhtStack); - udpReceivers[RSUDP_TOU_RECVER_RELAY_IDX] = mRelay; /* RELAY Connections (DHT Port) */ - udpTypes[RSUDP_TOU_RECVER_RELAY_IDX] = TOU_RECEIVER_TYPE_UDPRELAY; - mDhtStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_RELAY_IDX]); - - // LAST ON THIS STACK IS STANDARD DIRECT TOU - udpReceivers[RSUDP_TOU_RECVER_DIRECT_IDX] = new UdpPeerReceiver(mDhtStack); /* standard DIRECT Connections (DHT Port) */ - udpTypes[RSUDP_TOU_RECVER_DIRECT_IDX] = TOU_RECEIVER_TYPE_UDPPEER; - mDhtStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_DIRECT_IDX]); - - /* install external Pointer for Interface */ - rsDht = mBitDht; - - // NOW WE BUILD THE SECOND STACK. - // Create the Second UdpStack... Port should be random (but openable!). - // We do this by binding to xx.xx.xx.xx:0 which which gives us a random port. - - struct sockaddr_in sndladdr; - sockaddr_clear(&sndladdr); - -#ifdef LOCALNET_TESTING - - // // HACK Proxy Port near Dht Port - For Relay Testing. - // uint16_t rndport = rsInitConfig->port + 3; - // sndladdr.sin_port = htons(rndport); - - mProxyStack = new rsFixedUdpStack(UDP_TEST_RESTRICTED_LAYER, sndladdr); - - /* portRestrictions already parsed */ - if (doPortRestrictions) - { - RestrictedUdpLayer *url = (RestrictedUdpLayer *) mProxyStack->getUdpLayer(); - url->addRestrictedPortRange(lport, uport); - } -#else - mProxyStack = new rsFixedUdpStack(sndladdr); -#endif - -#ifdef RS_USE_DHT_STUNNER - // FIRSTLY THE PROXY STUNNER. - UdpStunner *mProxyStunner = new UdpStunner(mProxyStack); - mProxyStunner->setTargetStunPeriod(300); /* slow (5mins) */ - mProxyStack->addReceiver(mProxyStunner); - -#ifdef LOCALNET_TESTING - mProxyStunner->SetAcceptLocalNet(); -#endif -#endif // RS_USE_DHT_STUNNER - - - // FINALLY THE PROXY UDP CONNECTIONS - udpReceivers[RSUDP_TOU_RECVER_PROXY_IDX] = new UdpPeerReceiver(mProxyStack); /* PROXY Connections (Alt UDP Port) */ - udpTypes[RSUDP_TOU_RECVER_PROXY_IDX] = TOU_RECEIVER_TYPE_UDPPEER; - mProxyStack->addReceiver(udpReceivers[RSUDP_TOU_RECVER_PROXY_IDX]); - - // REAL INITIALISATION - WITH THREE MODES - tou_init((void **) udpReceivers, udpTypes, RSUDP_NUM_TOU_RECVERS); - -#ifdef RS_USE_DHT_STUNNER - mBitDht->setupConnectBits(mDhtStunner, mProxyStunner, mRelay); -#else // RS_USE_DHT_STUNNER - mBitDht->setupConnectBits(mRelay); -#endif // RS_USE_DHT_STUNNER - -#ifdef RS_USE_DHT_STUNNER - mNetMgr->setAddrAssist(new stunAddrAssist(mDhtStunner), new stunAddrAssist(mProxyStunner)); -#endif // RS_USE_DHT_STUNNER - // #else //RS_USE_BITDHT - // /* install NULL Pointer for rsDht Interface */ - // rsDht = NULL; -#endif //RS_USE_BITDHT - } - - - /**************************** BITDHT ***********************************/ - - p3ServiceControl *serviceCtrl = new p3ServiceControl(mLinkMgr); - rsServiceControl = serviceCtrl; - - pqih = new pqisslpersongrp(serviceCtrl, flags, mPeerMgr); - //pqih = new pqipersongrpDummy(none, flags); - - serviceCtrl->setServiceServer(pqih) ; - - /****** New Ft Server **** !!! */ - ftServer *ftserver = new ftServer(mPeerMgr, serviceCtrl); - ftserver->setConfigDirectory(RsAccounts::AccountDirectory()); - - ftserver->SetupFtServer() ; - - /* setup any extra bits (Default Paths) */ - ftserver->setPartialsDirectory(emergencyPartialsDir); - ftserver->setDownloadDirectory(emergencySaveDir); - - /* This should be set by config ... there is no default */ - //ftserver->setSharedDirectories(fileList); - - rsFiles = ftserver; - - std::vector plugins_directories ; - -#ifdef __APPLE__ - plugins_directories.push_back(RsAccounts::systemDataDirectory()) ; -#endif -#if !defined(WINDOWS_SYS) && defined(PLUGIN_DIR) - plugins_directories.push_back(std::string(PLUGIN_DIR)) ; -#endif - std::string extensions_dir = RsAccounts::ConfigDirectory() + "/extensions6/" ; - plugins_directories.push_back(extensions_dir) ; - - if(!RsDirUtil::checkCreateDirectory(extensions_dir)) - std::cerr << "(EE) Cannot create extensions directory " << extensions_dir - << ". This is not mandatory, but you probably have a permission problem." << std::endl; - -#ifdef DEBUG_PLUGIN_SYSTEM - plugins_directories.push_back(".") ; // this list should be saved/set to some correct value. - // possible entries include: /usr/lib/retroshare, ~/.retroshare/extensions/, etc. -#endif - - mPluginsManager = new RsPluginManager(rsInitConfig->main_executable_hash) ; - rsPlugins = mPluginsManager ; - mConfigMgr->addConfiguration("plugins.cfg", mPluginsManager); - mPluginsManager->loadConfiguration() ; - - // These are needed to load plugins: plugin devs might want to know the place of - // cache directories, get pointers to cache strapper, or access ownId() - // - mPluginsManager->setServiceControl(serviceCtrl) ; - - // Now load the plugins. This parses the available SO/DLL files for known symbols. - // - mPluginsManager->loadPlugins(plugins_directories) ; - - // Also load some plugins explicitly. This is helpful for - // - developping plugins - // - std::vector programatically_inserted_plugins ; - - // Push your own plugins into this list, before the call: - // - // programatically_inserted_plugins.push_back(myCoolPlugin) ; - // - mPluginsManager->loadPlugins(programatically_inserted_plugins) ; - -#ifdef RS_JSONAPI - // add jsonapi server to config manager so that it can save/load its tokens - if(rsJsonApi) rsJsonApi->connectToConfigManager(*mConfigMgr); -#endif - - /**** Reputation system ****/ - - p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ; - rsReputations = mReputations ; - -#ifdef RS_ENABLE_GXS - - std::string currGxsDir = RsAccounts::AccountDirectory() + "/gxs"; - RsDirUtil::checkCreateDirectory(currGxsDir); - - RsNxsNetMgr* nxsMgr = new RsNxsNetMgrImpl(serviceCtrl); - - /**** GXS Dist sync service ****/ - -#ifdef RS_USE_GXS_DISTANT_SYNC - RsGxsNetTunnelService *mGxsNetTunnel = new RsGxsNetTunnelService ; - rsGxsDistSync = mGxsNetTunnel ; -#else - RsGxsNetTunnelService *mGxsNetTunnel = NULL ; -#endif - - /**** Identity service ****/ - - RsGeneralDataService* gxsid_ds = new RsDataService(currGxsDir + "/", "gxsid_db", - RS_SERVICE_GXS_TYPE_GXSID, NULL, rsInitConfig->gxs_passwd); - - // init gxs services - PgpAuxUtils *pgpAuxUtils = new PgpAuxUtilsImpl(); - p3IdService *mGxsIdService = new p3IdService(gxsid_ds, NULL, pgpAuxUtils); - - // circles created here, as needed by Ids. - RsGeneralDataService* gxscircles_ds = new RsDataService(currGxsDir + "/", "gxscircles_db", - RS_SERVICE_GXS_TYPE_GXSCIRCLE, NULL, rsInitConfig->gxs_passwd); - - // create GxsCircles - early, as IDs need it. - p3GxsCircles *mGxsCircles = new p3GxsCircles(gxscircles_ds, NULL, mGxsIdService, pgpAuxUtils); - - // create GXS ID service - RsGxsNetService* gxsid_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_GXSID, gxsid_ds, nxsMgr, - mGxsIdService, mGxsIdService->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils,mGxsNetTunnel, - false,false,true); // don't synchronise group automatic (need explicit group request) - // don't sync messages at all. - // allow distsync, so that we can grab GXS id requests for other services - - // Normally we wouldn't need this (we do in other service): - // mGxsIdService->setNetworkExchangeService(gxsid_ns) ; - // ...since GxsIds are propagated manually. But that requires the gen exchange of GXSids to - // constantly test that mNetService is not null. The call below is to make the service aware of the - // netService so that it can request the missing ids. We'll need to fix this. - - mGxsIdService->setNes(gxsid_ns); - - /**** GxsCircle service ****/ - - // create GXS Circle service - RsGxsNetService* gxscircles_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_GXSCIRCLE, gxscircles_ds, nxsMgr, - mGxsCircles, mGxsCircles->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils); - - mGxsCircles->setNetworkExchangeService(gxscircles_ns) ; - - /**** Posted GXS service ****/ - - RsGeneralDataService* posted_ds = new RsDataService(currGxsDir + "/", "posted_db", - RS_SERVICE_GXS_TYPE_POSTED, - NULL, rsInitConfig->gxs_passwd); - - p3Posted *mPosted = new p3Posted(posted_ds, NULL, mGxsIdService); - - // create GXS photo service - RsGxsNetService* posted_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_POSTED, posted_ds, nxsMgr, - mPosted, mPosted->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils); - - mPosted->setNetworkExchangeService(posted_ns) ; - - /**** Wiki GXS service ****/ - -#ifdef RS_USE_WIKI - RsGeneralDataService* wiki_ds = new RsDataService(currGxsDir + "/", "wiki_db", - RS_SERVICE_GXS_TYPE_WIKI, - NULL, rsInitConfig->gxs_passwd); - - p3Wiki *mWiki = new p3Wiki(wiki_ds, NULL, mGxsIdService); - // create GXS wiki service - RsGxsNetService* wiki_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_WIKI, wiki_ds, nxsMgr, - mWiki, mWiki->getServiceInfo(), - mReputations, mGxsCircles, mGxsIdService, - pgpAuxUtils); - - mWiki->setNetworkExchangeService(wiki_ns) ; -#endif - - /**** Forum GXS service ****/ - - RsGeneralDataService* gxsforums_ds = new RsDataService(currGxsDir + "/", "gxsforums_db", - RS_SERVICE_GXS_TYPE_FORUMS, NULL, rsInitConfig->gxs_passwd); - - - p3GxsForums *mGxsForums = new p3GxsForums(gxsforums_ds, NULL, mGxsIdService); - - // create GXS photo service - RsGxsNetService* gxsforums_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_FORUMS, gxsforums_ds, nxsMgr, - mGxsForums, mGxsForums->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils);//,mGxsNetTunnel,true,true,true); - - mGxsForums->setNetworkExchangeService(gxsforums_ns) ; - - /**** Channel GXS service ****/ - - RsGeneralDataService* gxschannels_ds = new RsDataService(currGxsDir + "/", "gxschannels_db", - RS_SERVICE_GXS_TYPE_CHANNELS, NULL, rsInitConfig->gxs_passwd); - - p3GxsChannels *mGxsChannels = new p3GxsChannels(gxschannels_ds, NULL, mGxsIdService); - - // create GXS photo service - RsGxsNetService* gxschannels_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_CHANNELS, gxschannels_ds, nxsMgr, - mGxsChannels, mGxsChannels->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils,mGxsNetTunnel,true,true,true); - - mGxsChannels->setNetworkExchangeService(gxschannels_ns) ; - -#ifdef RS_USE_PHOTO - /**** Photo service ****/ - RsGeneralDataService* photo_ds = new RsDataService(currGxsDir + "/", "photoV2_db", - RS_SERVICE_GXS_TYPE_PHOTO, NULL, rsInitConfig->gxs_passwd); - - // init gxs services - p3PhotoService *mPhoto = new p3PhotoService(photo_ds, NULL, mGxsIdService); - - // create GXS photo service - RsGxsNetService* photo_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_PHOTO, photo_ds, nxsMgr, - mPhoto, mPhoto->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils); - - mPhoto->setNetworkExchangeService(photo_ns); -#endif - -#ifdef RS_USE_WIRE - /**** Wire GXS service ****/ - RsGeneralDataService* wire_ds = new RsDataService(currGxsDir + "/", "wire_db", - RS_SERVICE_GXS_TYPE_WIRE, NULL, rsInitConfig->gxs_passwd); - - p3Wire *mWire = new p3Wire(wire_ds, NULL, mGxsIdService); - - // create GXS photo service - RsGxsNetService* wire_ns = new RsGxsNetService( - RS_SERVICE_GXS_TYPE_WIRE, wire_ds, nxsMgr, - mWire, mWire->getServiceInfo(), - mReputations, mGxsCircles,mGxsIdService, - pgpAuxUtils); - - mWire->setNetworkExchangeService(wire_ns); -#endif - // now add to p3service - 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); -#ifdef RS_USE_PHOTO - pqih->addService(photo_ns, true); -#endif -#ifdef RS_USE_WIRE - pqih->addService(wire_ns, true); -#endif - -# ifdef RS_GXS_TRANS - RsGeneralDataService* gxstrans_ds = new RsDataService( - currGxsDir + "/", "gxstrans_db", RS_SERVICE_TYPE_GXS_TRANS, - NULL, rsInitConfig->gxs_passwd ); - mGxsTrans = new p3GxsTrans(gxstrans_ds, NULL, *mGxsIdService); - - RsGxsNetService* gxstrans_ns = new RsGxsNetService( - RS_SERVICE_TYPE_GXS_TRANS, gxstrans_ds, nxsMgr, mGxsTrans, - mGxsTrans->getServiceInfo(), mReputations, mGxsCircles, - mGxsIdService, pgpAuxUtils,NULL,true,true,false,p3GxsTrans::GXS_STORAGE_PERIOD,p3GxsTrans::GXS_SYNC_PERIOD); - - mGxsTrans->setNetworkExchangeService(gxstrans_ns); - pqih->addService(gxstrans_ns, true); -# endif // RS_GXS_TRANS - - // remove pword from memory - rsInitConfig->gxs_passwd = ""; - -#endif // RS_ENABLE_GXS. - - /* create Services */ - p3ServiceInfo *serviceInfo = new p3ServiceInfo(serviceCtrl); - mDisc = new p3discovery2(mPeerMgr, mLinkMgr, mNetMgr, serviceCtrl,mGxsIdService); - mHeart = new p3heartbeat(serviceCtrl, pqih); - msgSrv = new p3MsgService( serviceCtrl, mGxsIdService, *mGxsTrans ); - chatSrv = new p3ChatService( serviceCtrl,mGxsIdService, mLinkMgr, - mHistoryMgr, *mGxsTrans ); - mStatusSrv = new p3StatusService(serviceCtrl); - -#ifdef RS_BROADCAST_DISCOVERY - BroadcastDiscoveryService* broadcastDiscoveryService = - new BroadcastDiscoveryService(*rsPeers); - rsBroadcastDiscovery = broadcastDiscoveryService; -#endif // def RS_BROADCAST_DISCOVERY - -#ifdef ENABLE_GROUTER - p3GRouter *gr = new p3GRouter(serviceCtrl,mGxsIdService) ; - rsGRouter = gr ; - pqih->addService(gr,true) ; -#endif - - p3FileDatabase *fdb = new p3FileDatabase(serviceCtrl) ; - p3turtle *tr = new p3turtle(serviceCtrl,mLinkMgr) ; - rsTurtle = tr ; - pqih -> addService(tr,true); - pqih -> addService(fdb,true); - pqih -> addService(ftserver,true); - - mGxsTunnels = new p3GxsTunnelService(mGxsIdService) ; - mGxsTunnels->connectToTurtleRouter(tr) ; - rsGxsTunnel = mGxsTunnels; - - mGxsNetTunnel->connectToTurtleRouter(tr) ; - - rsGossipDiscovery.reset(mDisc); - rsMsgs = new p3Msgs(msgSrv, chatSrv); - - // connect components to turtle router. - - ftserver->connectToTurtleRouter(tr) ; - ftserver->connectToFileDatabase(fdb) ; - chatSrv->connectToGxsTunnelService(mGxsTunnels) ; - gr->connectToTurtleRouter(tr) ; -#ifdef ENABLE_GROUTER - msgSrv->connectToGlobalRouter(gr) ; -#endif - - pqih -> addService(serviceInfo,true); - pqih -> addService(mHeart,true); - pqih -> addService(mDisc,true); - pqih -> addService(msgSrv,true); - pqih -> addService(chatSrv,true); - pqih -> addService(mStatusSrv,true); - pqih -> addService(mGxsTunnels,true); - pqih -> addService(mReputations,true); - - // set interfaces for plugins - // - RsPlugInInterfaces interfaces; - interfaces.mFiles = rsFiles; - interfaces.mPeers = rsPeers; - interfaces.mMsgs = rsMsgs; - interfaces.mTurtle = rsTurtle; - interfaces.mDisc = rsDisc; -#ifdef RS_USE_BITDHT - interfaces.mDht = rsDht; -#else - interfaces.mDht = NULL; -#endif - interfaces.mNotify = mNotify; - interfaces.mServiceControl = serviceCtrl; - interfaces.mPluginHandler = mPluginsManager; - // gxs - interfaces.mGxsDir = currGxsDir; - interfaces.mIdentity = mGxsIdService; - interfaces.mRsNxsNetMgr = nxsMgr; - interfaces.mGxsIdService = mGxsIdService; - interfaces.mGxsCirlces = mGxsCircles; - interfaces.mPgpAuxUtils = pgpAuxUtils; - interfaces.mGxsForums = mGxsForums; - interfaces.mGxsChannels = mGxsChannels; - interfaces.mGxsTunnels = mGxsTunnels; - interfaces.mReputations = mReputations; - - mPluginsManager->setInterfaces(interfaces); - - // now add plugin objects inside the loop: - // - client services provided by plugins. - // - cache services provided by plugins. - // - mPluginsManager->registerClientServices(pqih) ; - mPluginsManager->registerCacheServices() ; - - - -#ifdef RS_RTT - p3rtt *mRtt = new p3rtt(serviceCtrl); - pqih -> addService(mRtt, true); - rsRtt = mRtt; -#endif - - // new services to test. - - p3BanList *mBanList = NULL; - - if(!RsAccounts::isHiddenNode()) - { - mBanList = new p3BanList(serviceCtrl, mNetMgr); - rsBanList = mBanList ; - pqih -> addService(mBanList, true); - } - else - rsBanList = NULL ; - - p3BandwidthControl *mBwCtrl = new p3BandwidthControl(pqih); - pqih -> addService(mBwCtrl, true); - -#ifdef SERVICES_DSDV - p3Dsdv *mDsdv = new p3Dsdv(serviceCtrl); - pqih -> addService(mDsdv, true); - rsDsdv = mDsdv; - mDsdv->addTestService(); -#endif - - /**************************************************************************/ - - if(!RsAccounts::isHiddenNode()) - { -#ifdef RS_USE_BITDHT - mBitDht->setupPeerSharer(mBanList); - - mNetMgr->addNetAssistConnect(1, mBitDht); - mNetMgr->addNetListener(mDhtStack); - mNetMgr->addNetListener(mProxyStack); -#endif - -#if defined(RS_USE_LIBMINIUPNPC) || defined(RS_USE_LIBUPNP) - // Original UPnP Interface. - pqiNetAssistFirewall *mUpnpMgr = new upnphandler(); - mNetMgr->addNetAssistFirewall(1, mUpnpMgr); -#endif // defined(RS_USE_LIBMINIUPNPC) || defined(RS_USE_LIBUPNP) - } - - /**************************************************************************/ - /* need to Monitor too! */ - mLinkMgr->addMonitor(pqih); - mLinkMgr->addMonitor(serviceCtrl); - mLinkMgr->addMonitor(serviceInfo); - - // Services that have been changed to pqiServiceMonitor - serviceCtrl->registerServiceMonitor(msgSrv, msgSrv->getServiceInfo().mServiceType); - serviceCtrl->registerServiceMonitor(mDisc, mDisc->getServiceInfo().mServiceType); - serviceCtrl->registerServiceMonitor(mStatusSrv, mStatusSrv->getServiceInfo().mServiceType); - serviceCtrl->registerServiceMonitor(chatSrv, chatSrv->getServiceInfo().mServiceType); - serviceCtrl->registerServiceMonitor(mBwCtrl, mBwCtrl->getServiceInfo().mServiceType); - - /**************************************************************************/ - // Turtle search for GXS services - - mGxsNetTunnel->registerSearchableService(gxschannels_ns) ; - - /**************************************************************************/ - - //mConfigMgr->addConfiguration("ftserver.cfg", ftserver); - // - mConfigMgr->addConfiguration("gpg_prefs.cfg" , AuthGPG::getAuthGPG()); - mConfigMgr->addConfiguration("gxsnettunnel.cfg", mGxsNetTunnel); - 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); - - if(mBanList != NULL) - mConfigMgr->addConfiguration("banlist.cfg" , mBanList); - - mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl); - mConfigMgr->addConfiguration("reputations.cfg" , mReputations); -#ifdef ENABLE_GROUTER - mConfigMgr->addConfiguration("grouter.cfg" , gr); -#endif - -#ifdef RS_USE_BITDHT - if(mBitDht != NULL) - mConfigMgr->addConfiguration("bitdht.cfg" , mBitDht); -#endif - -#ifdef RS_ENABLE_GXS - -# ifdef RS_GXS_TRANS - mConfigMgr->addConfiguration("gxs_trans_ns.cfg", gxstrans_ns); - mConfigMgr->addConfiguration("gxs_trans.cfg" , mGxsTrans); -# endif // RS_GXS_TRANS - - mConfigMgr->addConfiguration("p3identity.cfg" , mGxsIdService); - mConfigMgr->addConfiguration("identity.cfg" , gxsid_ns); - mConfigMgr->addConfiguration("gxsforums.cfg" , gxsforums_ns); - mConfigMgr->addConfiguration("gxsforums_srv.cfg" , mGxsForums); - mConfigMgr->addConfiguration("gxschannels.cfg" , gxschannels_ns); - mConfigMgr->addConfiguration("gxschannels_srv.cfg", mGxsChannels); - mConfigMgr->addConfiguration("gxscircles.cfg" , gxscircles_ns); - mConfigMgr->addConfiguration("gxscircles_srv.cfg" , mGxsCircles); - mConfigMgr->addConfiguration("posted.cfg" , posted_ns); - mConfigMgr->addConfiguration("gxsposted_srv.cfg" , mPosted); -#ifdef RS_USE_WIKI - mConfigMgr->addConfiguration("wiki.cfg", wiki_ns); -#endif -#ifdef RS_USE_PHOTO - mConfigMgr->addConfiguration("photo.cfg", photo_ns); -#endif -#ifdef RS_USE_WIRE - mConfigMgr->addConfiguration("wire.cfg", wire_ns); -#endif -#endif //RS_ENABLE_GXS -#ifdef RS_USE_I2P_BOB - mConfigMgr->addConfiguration("I2PBOB.cfg", mI2pBob); -#endif - - mPluginsManager->addConfigurations(mConfigMgr) ; - - ftserver->addConfiguration(mConfigMgr); - - /**************************************************************************/ - /* (2) Load configuration files */ - /**************************************************************************/ - std::cerr << "(2) Load configuration files" << std::endl; - - mConfigMgr->loadConfiguration(); - - /**************************************************************************/ - /* trigger generalConfig loading for classes that require it */ - /**************************************************************************/ - p3ServerConfig *serverConfig = new p3ServerConfig(mPeerMgr, mLinkMgr, mNetMgr, pqih, mGeneralConfig); - serverConfig->load_config(); - - /**************************************************************************/ - /* Force Any Configuration before Startup (After Load) */ - /**************************************************************************/ - std::cerr << "Force Any Configuration before Startup (After Load)" << std::endl; - - if (rsInitConfig->forceLocalAddr) - { - struct sockaddr_storage laddr; - - /* clean sockaddr before setting values (MaxOSX) */ - sockaddr_storage_clear(laddr); - - struct sockaddr_in *lap = (struct sockaddr_in *) &laddr; - - lap->sin_family = AF_INET; - lap->sin_port = htons(rsInitConfig->port); - - // universal - lap->sin_addr.s_addr = inet_addr(rsInitConfig->inet.c_str()); - - mPeerMgr->setLocalAddress(ownId, laddr); - } - - if (rsInitConfig->forceExtPort) - { - mPeerMgr->setOwnNetworkMode(RS_NET_MODE_EXT); - mPeerMgr->setOwnVisState(RS_VS_DISC_FULL, RS_VS_DHT_FULL); - } - - if (rsInitConfig->hiddenNodeSet) - { - std::cout << "RsServer::StartupRetroShare setting up hidden locations" << std::endl; - - if (rsInitConfig->hiddenNodeI2PBOB) { - std::cout << "RsServer::StartupRetroShare setting up BOB" << std::endl; - - // we need a local port! - mNetMgr->checkNetAddress(); - - // add i2p proxy - // bob will use this address - sockaddr_storage i2pInstance; - sockaddr_storage_ipv4_aton(i2pInstance, rsInitConfig->hiddenNodeAddress.c_str()); - mPeerMgr->setProxyServerAddress(RS_HIDDEN_TYPE_I2P, i2pInstance); - - std::string addr; // will be set by auto proxy service - uint16_t port = rsInitConfig->hiddenNodePort; // unused by bob - - bool r = autoProxy->initialSetup(autoProxyType::I2PBOB, addr, port); - - if (r && !addr.empty()) { - mPeerMgr->setupHiddenNode(addr, port); - - // now enable bob - bobSettings bs; - autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &bs); - bs.enable = true; - autoProxy->taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &bs); - } else { - std::cerr << "RsServer::StartupRetroShare failed to receive keys" << std::endl; - /// TODO add notify for failed bob setup - } - } else { - mPeerMgr->setupHiddenNode(rsInitConfig->hiddenNodeAddress, rsInitConfig->hiddenNodePort); - } - - std::cout << "RsServer::StartupRetroShare hidden location set up" << std::endl; - } - else if (isHiddenNode) - { - mPeerMgr->forceHiddenNode(); - } - - if (!rsInitConfig->opModeStr.empty()) - { - rsConfig->setOperatingMode(rsInitConfig->opModeStr); - } - mNetMgr -> checkNetAddress(); - - if (rsInitConfig->hiddenNodeSet) { - // newly created location - // mNetMgr->checkNetAddress() will setup ports for us - // trigger updates for auto proxy services - std::vector types; - - // i2p bob need to rebuild its command map - types.push_back(autoProxyType::I2PBOB); - - rsAutoProxyMonitor::taskSync(types, autoProxyTask::reloadConfig); - } - - /**************************************************************************/ - /* startup (stuff dependent on Ids/peers is after this point) */ - /**************************************************************************/ - - autoProxy->startAll(); - - pqih->init_listener(); - mNetMgr->addNetListener(pqih); /* add listener so we can reset all sockets later */ - - /**************************************************************************/ - /* load caches and secondary data */ - /**************************************************************************/ - - // Clear the News Feeds that are generated by Initial Cache Loading. - - /* Peer stuff is up to date */ - - //getPqiNotify()->ClearFeedItems(RS_FEED_ITEM_CHAT_NEW); - mNotify->ClearFeedItems(RS_FEED_ITEM_MESSAGE); - //getPqiNotify()->ClearFeedItems(RS_FEED_ITEM_FILES_NEW); - - /**************************************************************************/ - /* Add AuthGPG services */ - /**************************************************************************/ - - //AuthGPG::getAuthGPG()->addService(mDisc); - - /**************************************************************************/ - /* Force Any Last Configuration Options */ - /**************************************************************************/ - - /**************************************************************************/ - /* Start up Threads */ - /**************************************************************************/ - - // auto proxy threads -#ifdef RS_USE_I2P_BOB - startServiceThread(mI2pBob, "I2P-BOB"); -#endif - -#ifdef RS_ENABLE_GXS - // 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; - rsGxsTrans = mGxsTrans; - -#if RS_USE_PHOTO - rsPhoto = mPhoto; -#endif -#if RS_USE_WIRE - rsWire = mWire; -#endif - - /*** start up GXS core runner ***/ - - startServiceThread(mGxsNetTunnel, "gxs net tunnel"); - startServiceThread(mGxsIdService, "gxs id"); - startServiceThread(mGxsCircles, "gxs circle"); - startServiceThread(mPosted, "gxs posted"); -#if RS_USE_WIKI - startServiceThread(mWiki, "gxs wiki"); -#endif - startServiceThread(mGxsForums, "gxs forums"); - startServiceThread(mGxsChannels, "gxs channels"); - -#if RS_USE_PHOTO - startServiceThread(mPhoto, "gxs photo"); -#endif -#if RS_USE_WIRE - startServiceThread(mWire, "gxs wire"); -#endif - - // cores ready start up GXS net servers - startServiceThread(gxsid_ns, "gxs id ns"); - startServiceThread(gxscircles_ns, "gxs circle ns"); - startServiceThread(posted_ns, "gxs posted ns"); -#if RS_USE_WIKI - startServiceThread(wiki_ns, "gxs wiki ns"); -#endif - startServiceThread(gxsforums_ns, "gxs forums ns"); - startServiceThread(gxschannels_ns, "gxs channels ns"); - -#if RS_USE_PHOTO - startServiceThread(photo_ns, "gxs photo ns"); -#endif -#if RS_USE_WIRE - startServiceThread(wire_ns, "gxs wire ns"); -#endif - -# ifdef RS_GXS_TRANS - startServiceThread(mGxsTrans, "gxs trans"); - startServiceThread(gxstrans_ns, "gxs trans ns"); -# endif // def RS_GXS_TRANS - -#endif // RS_ENABLE_GXS - -#ifdef RS_BROADCAST_DISCOVERY - startServiceThread(broadcastDiscoveryService, "Broadcast Discovery"); -#endif // def RS_BROADCAST_DISCOVERY - - ftserver->StartupThreads(); - ftserver->ResumeTransfers(); - - //mDhtMgr->start(); -#ifdef RS_USE_BITDHT - if(mBitDht != NULL) - mBitDht->start(); -#endif - - /**************************************************************************/ - - // create loopback device, and add to pqisslgrp. - - SearchModule *mod = new SearchModule(); - pqiloopback *ploop = new pqiloopback(ownId); - - mod -> peerid = ownId; - mod -> pqi = ploop; - - pqih->AddSearchModule(mod); - - /* Setup GUI Interfaces. */ - - // rsDisc & RsMsgs done already. - rsBandwidthControl = mBwCtrl; - rsConfig = serverConfig; - - - rsStatus = new p3Status(mStatusSrv); - rsHistory = new p3History(mHistoryMgr); - - /* put a welcome message in! */ - if (isFirstTimeRun) - { - msgSrv->loadWelcomeMsg(); - ftserver->shareDownloadDirectory(true); - mGeneralConfig->saveConfiguration(); - } - - /* Startup this thread! */ - start("rs main") ; - - std::cerr << "========================================================================" << std::endl; - std::cerr << "== RsInit:: Retroshare core started ==" << std::endl; - std::cerr << "========================================================================" << std::endl; - - coreReady = true; - return 1; -} - -RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(const RsPeerId& account, const std::string& password) -{ - if(isLoggedIn()) return RsInit::ERR_ALREADY_RUNNING; - - { - if(!RsAccounts::SelectAccount(account)) - return RsInit::ERR_UNKNOWN; - - if(!password.empty()) - { - rsNotify->cachePgpPassphrase(password); - rsNotify->setDisableAskPassword(true); - } - std::string _ignore_lockFilePath; - RsInit::LoadCertificateStatus ret = RsInit::LockAndLoadCertificates(false, _ignore_lockFilePath); - - rsNotify->setDisableAskPassword(false) ; - rsNotify->clearPgpPassphrase() ; - - if(ret == RsInit::OK && RsControl::instance()->StartupRetroShare() == 1) - return RsInit::OK; - - return ret; - } -} - -/*static*/ bool RsLoginHelper::collectEntropy(uint32_t bytes) -{ return RsInit::collectEntropy(bytes); } - -void RsLoginHelper::getLocations(std::vector& store) -{ - std::list locIds; - RsAccounts::GetAccountIds(locIds); - store.clear(); - - for(const RsPeerId& locId : locIds ) - { - Location l; l.mLocationId = locId; - std::string discardPgpMail; - RsAccounts::GetAccountDetails( locId, l.mPgpId, l.mPgpName, - discardPgpMail, l.mLocationName ); - store.push_back(l); - } -} - -std::error_condition RsLoginHelper::createLocationV2( - RsPeerId& locationId, RsPgpId& pgpId, - const std::string& locationName, const std::string& pgpName, - const std::string& password ) -{ - if(isLoggedIn()) return RsInitErrorNum::ALREADY_LOGGED_IN; - if(locationName.empty()) return RsInitErrorNum::INVALID_LOCATION_NAME; - if(pgpId.isNull() && pgpName.empty()) - return RsInitErrorNum::PGP_NAME_OR_ID_NEEDED; - - std::string errorMessage; - if(pgpId.isNull() && !RsAccounts::GeneratePGPCertificate( - pgpName, "", password, pgpId, 4096, errorMessage ) ) - { - RS_ERR("Failure creating PGP key: ", errorMessage); - return RsInitErrorNum::PGP_KEY_CREATION_FAILED; - } - - std::string sslPassword = - RsRandom::random_alphaNumericString(RsInit::getSslPwdLen()); - - rsNotify->cachePgpPassphrase(password); - rsNotify->setDisableAskPassword(true); - - bool ret = RsAccounts::createNewAccount( - pgpId, "", locationName, "", false, false, sslPassword, - locationId, errorMessage ); - if(!ret) - { - RS_ERR("Failure creating SSL key: ", errorMessage); - return RsInitErrorNum::SSL_KEY_CREATION_FAILED; - } - - RsInit::LoadPassword(sslPassword); - ret = (RsInit::OK == attemptLogin(locationId, password)); - rsNotify->setDisableAskPassword(false); - - return (ret ? std::error_condition() : RsInitErrorNum::LOGIN_FAILED); -} - -#if !RS_VERSION_AT_LEAST(0,6,6) -bool RsLoginHelper::createLocation( - RsLoginHelper::Location& l, const std::string& password, - std::string& errorMessage, bool makeHidden, bool makeAutoTor ) -{ - if(isLoggedIn()) return (errorMessage="Already Running", false); - - if(l.mLocationName.empty()) - { - errorMessage = "Location name is needed"; - return false; - } - - if(l.mPgpId.isNull() && l.mPgpName.empty()) - { - errorMessage = "Either PGP name or PGP id is needed"; - return false; - } - - if(l.mPgpId.isNull() && !RsAccounts::GeneratePGPCertificate( - l.mPgpName, "", password, l.mPgpId, 4096, errorMessage) ) - { - errorMessage = "Failure creating PGP key: " + errorMessage; - return false; - } - - std::string sslPassword = - RSRandom::random_alphaNumericString(RsInit::getSslPwdLen()); - - if(!rsNotify->cachePgpPassphrase(password)) return false; - if(!rsNotify->setDisableAskPassword(true)) return false; - - bool ret = RsAccounts::createNewAccount( - l.mPgpId, "", l.mLocationName, "", makeHidden, makeAutoTor, - sslPassword, l.mLocationId, errorMessage ); - - ret = ret && RsInit::LoadPassword(sslPassword); - ret = ret && RsInit::OK == attemptLogin(l.mLocationId, password); - - rsNotify->setDisableAskPassword(false); - return ret; -} -#endif // !RS_VERSION_AT_LEAST(0,6,6) - -bool RsLoginHelper::isLoggedIn() -{ - return RsControl::instance()->isReady(); -} - -void RsLoginHelper::Location::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(mLocationId); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mLocationName); - RS_SERIAL_PROCESS(mPgpName); -} - -/*static*/ bool RsAccounts::getCurrentAccountId(RsPeerId& id) -{ - return rsAccountsDetails->getCurrentAccountId(id); -} diff --git a/libretroshare/src/rsserver/rsloginhandler.cc b/libretroshare/src/rsserver/rsloginhandler.cc deleted file mode 100644 index dbe023235..000000000 --- a/libretroshare/src/rsserver/rsloginhandler.cc +++ /dev/null @@ -1,792 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: rsloginhandler.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 retroshare team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include "rsloginhandler.h" -#include "util/rsdir.h" -#include "retroshare/rsinit.h" -#include "util/rsdebug.h" - -//#define DEBUG_RSLOGINHANDLER 1 - -bool RsLoginHandler::getSSLPassword( const RsPeerId& ssl_id, - bool enable_gpg_ask_passwd, - std::string& ssl_passwd ) -{ - -#ifdef RS_AUTOLOGIN - // First, see if autologin is available - if(tryAutoLogin(ssl_id,ssl_passwd)) return true; -#endif // RS_AUTOLOGIN - - // If we're not expecting to enter a passwd (e.g. test for autologin before - // display of the login window), safely respond false. - if(!enable_gpg_ask_passwd) return false; - - return getSSLPasswdFromGPGFile(ssl_id,ssl_passwd); -} - -bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile( - const RsPeerId& ssl_id, const std::string& ssl_passwd ) -{ - // We want to pursue login with gpg passwd. Let's do it: - FILE *sslPassphraseFile = RsDirUtil::rs_fopen( - getSSLPasswdFileName(ssl_id).c_str(), "r"); - - if(sslPassphraseFile) // already have it. - { - fclose(sslPassphraseFile); - return true ; - } - - bool ok = AuthGPG::getAuthGPG()->encryptTextToFile( - ssl_passwd, getSSLPasswdFileName(ssl_id)); - - if (!ok) std::cerr << "Encrypting went wrong !" << std::endl; - - return ok; -} - -bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword) -{ - /* Let's read the password from an encrypted file, before check if there's - * an ssl_passpharese_file that we can decrypt with PGP */ - FILE *sslPassphraseFile = RsDirUtil::rs_fopen( - getSSLPasswdFileName(ssl_id).c_str(), "r"); - - if (!sslPassphraseFile) - { - std::cerr << "No password provided, and no sslPassphraseFile : " - << getSSLPasswdFileName(ssl_id).c_str() << std::endl; - return 0; - } - - fclose(sslPassphraseFile); - -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "opening sslPassphraseFile : " - << getSSLPasswdFileName(ssl_id).c_str() << std::endl; -#endif - - std::string plain; - if ( AuthGPG::getAuthGPG()->decryptTextFromFile( plain, getSSLPasswdFileName(ssl_id)) ) - { - sslPassword = plain; -#ifdef DEBUG_RSLOGINHANDLER - if(sslPassword.length() > 0) - std::cerr << "Decrypting went ok !" << std::endl; - else - std::cerr << "Passphrase is empty!" << std::endl; -#endif - - return sslPassword.length() > 0 ; - } - else - { - sslPassword = ""; - std::cerr << "Error : decrypting went wrong !" << std::endl; - - return false; - } -} - - -std::string RsLoginHandler::getSSLPasswdFileName(const RsPeerId& /*ssl_id*/) -{ - return RsAccounts::AccountKeysDirectory() + "/" + "ssl_passphrase.pgp"; -} - -#ifdef RS_AUTOLOGIN - -#if defined(HAS_GNOME_KEYRING) || defined(__FreeBSD__) || defined(__OpenBSD__) -# include - -GnomeKeyringPasswordSchema my_schema = { - GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD, - { - { "RetroShare SSL Id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, - { NULL, (GnomeKeyringAttributeType)0 } - }, - NULL, - NULL, - NULL -}; -#elif defined(HAS_LIBSECRET) -#include -const SecretSchema *libsecret_get_schema(void) -{ - static const SecretSchema the_schema = { - "org.Retroshare.Password", SECRET_SCHEMA_NONE, - { - { "RetroShare SSL Id", SECRET_SCHEMA_ATTRIBUTE_STRING }, - { "NULL", static_cast(0) }, - }, - 0,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr - }; - return &the_schema; -} -#endif - - -#ifdef __APPLE__ - /* OSX Headers */ - -#include -#include - -#endif - -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -/* WINDOWS STRUCTURES FOR DPAPI */ - -#ifndef WINDOWS_SYS /* UNIX */ - -#include - -#else -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - -#include -#include -#include - -/* -class CRYPTPROTECT_PROMPTSTRUCT; -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef WINDOWS_SYS -#if defined(__CYGWIN__) - -typedef struct _CRYPTPROTECT_PROMPTSTRUCT { - DWORD cbSize; - DWORD dwPromptFlags; - HWND hwndApp; - LPCWSTR szPrompt; -} CRYPTPROTECT_PROMPTSTRUCT, - *PCRYPTPROTECT_PROMPTSTRUCT; - -#endif -#endif - -/* definitions for the two functions */ -__declspec (dllimport) -extern BOOL WINAPI CryptProtectData( - DATA_BLOB* pDataIn, - LPCWSTR szDataDescr, - DATA_BLOB* pOptionalEntropy, - PVOID pvReserved, - /* PVOID prompt, */ - /* CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, */ - CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, - DWORD dwFlags, - DATA_BLOB* pDataOut -); - -__declspec (dllimport) -extern BOOL WINAPI CryptUnprotectData( - DATA_BLOB* pDataIn, - LPWSTR* ppszDataDescr, - DATA_BLOB* pOptionalEntropy, - PVOID pvReserved, - /* PVOID prompt, */ - /* CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, */ - CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, - DWORD dwFlags, - DATA_BLOB* pDataOut -); - -#ifdef __cplusplus -} -#endif - -#endif - - -bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd) -{ -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "RsTryAutoLogin()" << std::endl; -#endif - - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef __HAIKU__ -#ifndef WINDOWS_SYS /* UNIX */ -#if defined(HAS_GNOME_KEYRING) || defined(__FreeBSD__) || defined(__OpenBSD__) - - gchar *passwd = NULL; - -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Using attribute: " << ssl_id << std::endl; -#endif - if( gnome_keyring_find_password_sync(&my_schema, &passwd,"RetroShare SSL Id",ssl_id.toStdString().c_str(),NULL) == GNOME_KEYRING_RESULT_OK ) - { - std::cout << "Got SSL passwd ********************" /*<< passwd*/ << " from gnome keyring" << std::endl; - ssl_passwd = std::string(passwd); - return true ; - } - else - { -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Could not get passwd from gnome keyring" << std::endl; -#endif - return false ; - } -#elif defined(HAS_LIBSECRET) - // do synchronous lookup - -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Using attribute: " << ssl_id << std::endl; -#endif - - GError *error = nullptr; - gchar *password = secret_password_lookup_sync (libsecret_get_schema(), nullptr, &error, - "RetroShare SSL Id", ssl_id.toStdString().c_str(), - NULL); - - if (error) { - g_error_free (error); -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Could not get passwd using libsecret: error" << std::endl; -#endif - return false; - } else if (!password) { - /* password will be null, if no matching password found */ -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Could not get passwd using libsecret: not found" << std::endl; -#endif - return false; - } else { - std::cout << "Got SSL passwd ********************" /*<< passwd*/ << " using libsecret" << std::endl; - ssl_passwd = std::string(password); - - secret_password_free (password); - return true; - } -#ifdef DEBUG_RSLOGINHANDLER - std::cerr << "Could not get passwd from gnome keyring: unknown" << std::endl; -#endif - //return false; //Never used returned before -#else - /******************** OSX KeyChain stuff *****************************/ -#ifdef __APPLE__ - - std::cerr << "RsTryAutoLogin() OSX Version" << std::endl; - //Call SecKeychainFindGenericPassword to get a password from the keychain: - - void *passwordData = NULL; - UInt32 passwordLength = 0; - std::string idtemp = ssl_id.toStdString(); - const char *userId = idtemp.c_str(); - UInt32 uidLength = strlen(userId); - SecKeychainItemRef itemRef = NULL; - - OSStatus status = SecKeychainFindGenericPassword ( - NULL, // default keychain - 10, // length of service name - "Retroshare", // service name - uidLength, // length of account name - userId, // account name - &passwordLength, // length of password - &passwordData, // pointer to password data - &itemRef // the item reference - ); - - std::cerr << "RsTryAutoLogin() SecKeychainFindGenericPassword returned: " << status << std::endl; - - if (status != 0) - { - std::cerr << "RsTryAutoLogin() Error " << std::endl; - - /* error */ - if (status == errSecItemNotFound) - { - //Is password on keychain? - std::cerr << "RsTryAutoLogin() Error - Looks like password is not in KeyChain " << std::endl; - } - } - else - { - std::cerr << "RsTryAutoLogin() Password found on KeyChain! " << std::endl; - - /* load up password to correct location */ - ssl_passwd.clear(); - ssl_passwd.insert(0, (char*)passwordData, passwordLength); - } - - //Free the data allocated by SecKeychainFindGenericPassword: - - SecKeychainItemFreeContent ( - NULL, //No attribute data to release - passwordData //Release data buffer allocated by SecKeychainFindGenericPassword - ); - - if (itemRef) CFRelease(itemRef); - - return (status == 0); - - /******************** OSX KeyChain stuff *****************************/ -#endif // APPLE -#endif // HAS_GNOME_KEYRING / HAS_LIBSECRET -#else /******* WINDOWS BELOW *****/ - - /* try to load from file */ - std::string entropy = getSSLPasswdFileName(ssl_id); - /* get the data out */ - - DATA_BLOB DataIn; - DATA_BLOB DataEnt; - DATA_BLOB DataOut; - - BYTE *pbDataEnt =(BYTE *) strdup(entropy.c_str()); - DWORD cbDataEnt = strlen((char *)pbDataEnt)+1; - DataEnt.pbData = pbDataEnt; - DataEnt.cbData = cbDataEnt; - - char *dataptr = NULL; - int datalen = 0; - - /* open the data to the file */ - FILE *fp = RsDirUtil::rs_fopen(getAutologinFileName(ssl_id).c_str(), "rb"); - if (fp != NULL) - { - fseek(fp, 0, SEEK_END); - datalen = ftell(fp); - fseek(fp, 0, SEEK_SET); - dataptr = (char *) rs_malloc(datalen); - - if(dataptr == NULL) - { - fclose(fp); - return false; - } - fread(dataptr, 1, datalen, fp); - fclose(fp); - - /***** - std::cerr << "Data loaded from: " << passwdfile; - std::cerr << std::endl; - - std::cerr << "Size :"; - std::cerr << datalen << std::endl; - - for(unsigned int i = 0; i < datalen; i++) - { - std::cerr << std::setw(2) << (int) dataptr[i]; - std::cerr << " "; - } - std::cerr << std::endl; - *****/ - } - else - { - return false; - } - - BYTE *pbDataInput =(BYTE *) dataptr; - DWORD cbDataInput = datalen; - DataIn.pbData = pbDataInput; - DataIn.cbData = cbDataInput; - - - CRYPTPROTECT_PROMPTSTRUCT prom; - - prom.cbSize = sizeof(prom); - prom.dwPromptFlags = 0; - - - bool isDecrypt = CryptUnprotectData( - &DataIn, - NULL, - &DataEnt, /* entropy.c_str(), */ - NULL, // Reserved - &prom, // Opt. Prompt - 0, - &DataOut); - - if (isDecrypt) - { - //std::cerr << "Decrypted size: " << DataOut.cbData; - //std::cerr << std::endl; - if (DataOut.pbData[DataOut.cbData - 1] != '\0') - { - std::cerr << "Error: Decrypted Data not a string..."; - std::cerr << std::endl; - isDecrypt = false; - } - else - { - //std::cerr << "The decrypted data is: " << DataOut.pbData; - //std::cerr << std::endl; - ssl_passwd = (char *) DataOut.pbData; - } - } - else - { - std::cerr << "Decryption error!"; - std::cerr << std::endl; - } - - /* strings to be freed */ - free(pbDataInput); - free(pbDataEnt); - - /* generated data space */ - LocalFree(DataOut.pbData); - - return isDecrypt; -#endif -#endif - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - //return false; //never used -} - - -bool RsLoginHandler::enableAutoLogin(const RsPeerId& ssl_id,const std::string& ssl_passwd) -{ - std::cerr << "RsStoreAutoLogin()" << std::endl; - - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef __HAIKU__ -#ifndef WINDOWS_SYS /* UNIX */ -#if defined(HAS_GNOME_KEYRING) || 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)) - { - std::cout << "Stored passwd " << "************************" << " into gnome keyring" << std::endl; - return true ; - } - else - { - std::cerr << "Could not store passwd into gnome keyring" << std::endl; - return false ; - } -#elif defined(HAS_LIBSECRET) - // do synchronous store - - GError *error = nullptr; - secret_password_store_sync (libsecret_get_schema(), SECRET_COLLECTION_DEFAULT, - static_cast(("RetroShare password for SSL Id " + ssl_id.toStdString()).c_str()), - static_cast(ssl_passwd.c_str()), - nullptr, &error, - "RetroShare SSL Id", ssl_id.toStdString().c_str(), - NULL); - - if (error) { - RsErr() << __PRETTY_FUNCTION__ - << " Could not store passwd using libsecret with" - << " error.code=" << error->code - << " error.domain=" << error->domain - << " error.message=\"" << error->message << "\"" << std::endl; - if (error->code == 2) - RsErr() << "Do have a key wallet installed?" << std::endl - << "Like gnome-keyring or other using \"Secret Service\" by DBus." << std::endl; - g_error_free (error); - return false; - } - std::cout << "Stored passwd " << "************************" << " using libsecret" << std::endl; - return true; -#else -#ifdef __APPLE__ - /***************** OSX KEYCHAIN ****************/ - //Call SecKeychainAddGenericPassword to add a new password to the keychain: - - std::cerr << "RsStoreAutoLogin() OSX Version!" << std::endl; - - const void *password = ssl_passwd.c_str(); - UInt32 passwordLength = strlen(ssl_passwd.c_str()); - std::string idtemp = ssl_id.toStdString(); - const char *userid = idtemp.c_str(); - UInt32 uidLength = strlen(userid); - - OSStatus status = SecKeychainAddGenericPassword ( - NULL, // default keychain - 10, // length of service name - "Retroshare", // service name - uidLength, // length of account name - userid, // account name - passwordLength, // length of password - password, // pointer to password data - NULL // the item reference - ); - - std::cerr << "RsStoreAutoLogin() Call to SecKeychainAddGenericPassword returned: " << status << std::endl; - - if (status != 0) - { - std::cerr << "RsStoreAutoLogin() SecKeychainAddGenericPassword Failed" << std::endl; - return false; - } - return true; - - /***************** OSX KEYCHAIN ****************/ -#else -#ifdef TODO_CODE_ROTTEN - - /* WARNING: Autologin is inherently unsafe */ - FILE* helpFile = RsDirUtil::rs_fopen(getAutologinFileName.c_str(), "w"); - - if(helpFile == NULL){ - std::cerr << "\nRsStoreAutoLogin(): Failed to open help file\n" << std::endl; - return false; - } - - /* encrypt help */ - - const int DAT_LEN = ssl_passwd.length(); - const int KEY_DAT_LEN = RsInitConfig::load_cert.length(); - unsigned char* key_data = (unsigned char*)RsInitConfig::load_cert.c_str(); - unsigned char* indata = (unsigned char*)ssl_passwd.c_str(); - unsigned char* outdata = new unsigned char[DAT_LEN]; - - RC4_KEY* key = new RC4_KEY; - RC4_set_key(key, KEY_DAT_LEN, key_data); - - RC4(key, DAT_LEN, indata, outdata); - - - fprintf(helpFile, "%s", outdata); - fclose(helpFile); - - delete key; - delete[] outdata; - - - return true; -#endif // TODO_CODE_ROTTEN -#endif // __APPLE__ -#endif // HAS_GNOME_KEYRING / HAS_LIBSECRET -#else /* windows */ - - /* store password encrypted in a file */ - std::string entropy = getSSLPasswdFileName(ssl_id); - - DATA_BLOB DataIn; - DATA_BLOB DataEnt; - DATA_BLOB DataOut; - BYTE *pbDataInput = (BYTE *) strdup(ssl_passwd.c_str()); - DWORD cbDataInput = strlen((char *)pbDataInput)+1; - BYTE *pbDataEnt =(BYTE *) strdup(entropy.c_str()); - DWORD cbDataEnt = strlen((char *)pbDataEnt)+1; - DataIn.pbData = pbDataInput; - DataIn.cbData = cbDataInput; - DataEnt.pbData = pbDataEnt; - DataEnt.cbData = cbDataEnt; - - CRYPTPROTECT_PROMPTSTRUCT prom; - - prom.cbSize = sizeof(prom); - prom.dwPromptFlags = 0; - - /********* - std::cerr << "Password (" << cbDataInput << "):"; - std::cerr << pbDataInput << std::endl; - std::cerr << "Entropy (" << cbDataEnt << "):"; - std::cerr << pbDataEnt << std::endl; - *********/ - - if(CryptProtectData( - &DataIn, - NULL, - &DataEnt, /* entropy.c_str(), */ - NULL, // Reserved. - &prom, - 0, - &DataOut)) - { - - /********** - std::cerr << "The encryption phase worked. ("; - std::cerr << DataOut.cbData << ")" << std::endl; - - for(unsigned int i = 0; i < DataOut.cbData; i++) - { - std::cerr << std::setw(2) << (int) DataOut.pbData[i]; - std::cerr << " "; - } - std::cerr << std::endl; - **********/ - - //std::cerr << "Save to: " << passwdfile; - //std::cerr << std::endl; - - /* save the data to the file */ - FILE *fp = RsDirUtil::rs_fopen(getAutologinFileName(ssl_id).c_str(), "wb"); - if (fp != NULL) - { - fwrite(DataOut.pbData, 1, DataOut.cbData, fp); - fclose(fp); - - std::cerr << "AutoLogin Data saved: "; - std::cerr << std::endl; - } - } - else - { - std::cerr << "Encryption Failed"; - std::cerr << std::endl; - } - - free(pbDataInput); - free(pbDataEnt); - LocalFree(DataOut.pbData); - return false; -#endif - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - -#endif -} - -bool RsLoginHandler::clearAutoLogin(const RsPeerId& ssl_id) -{ -#ifdef HAS_GNOME_KEYRING - if(GNOME_KEYRING_RESULT_OK == gnome_keyring_delete_password_sync(&my_schema,"RetroShare SSL Id", ssl_id.toStdString().c_str(),NULL)) - { - std::cout << "Successfully Cleared gnome keyring passwd for SSLID " << ssl_id << std::endl; - return true ; - } - else - { - std::cerr << "Could not clear gnome keyring passwd for SSLID " << ssl_id << std::endl; - return false ; - } -#elif defined(HAS_LIBSECRET) - // do synchronous clear - - GError *error = nullptr; - gboolean removed = secret_password_clear_sync (libsecret_get_schema(), nullptr, &error, - "RetroShare SSL Id", ssl_id.toStdString().c_str(), - NULL); - - if (error) { - g_error_free (error); - std::cerr << "Could not clearpasswd for SSLID " << ssl_id << " using libsecret: error" << std::endl; - return false ; - } else if (removed == FALSE) { - std::cerr << "Could not clearpasswd for SSLID " << ssl_id << " using libsecret: false" << std::endl; - return false ; - } - - std::cout << "Successfully Cleared passwd for SSLID " << ssl_id << " using libsecret" << std::endl; - return true ; -#else // HAS_GNOME_KEYRING / HAS_LIBSECRET - #ifdef __APPLE__ - - std::cerr << "clearAutoLogin() OSX Version" << std::endl; - //Call SecKeychainFindGenericPassword to get a password from the keychain: - - void *passwordData = NULL; - UInt32 passwordLength = 0; - std::string idtemp = ssl_id.toStdString(); - const char *userId = idtemp.c_str(); - UInt32 uidLength = strlen(userId); - SecKeychainItemRef itemRef = NULL; - - OSStatus status = SecKeychainFindGenericPassword ( - NULL, // default keychain - 10, // length of service name - "Retroshare", // service name - uidLength, // length of account name - userId, // account name - &passwordLength, // length of password - &passwordData, // pointer to password data - &itemRef // the item reference - ); - - std::cerr << "RsTryAutoLogin() SecKeychainFindGenericPassword returned: " << status << std::endl; - - if (status != 0) - { - std::cerr << "clearAutoLogin() Error Finding password " << std::endl; - - /* error */ - if (status == errSecItemNotFound) - { - //Is password on keychain? - std::cerr << "RsTryAutoLogin() Error - Looks like password is not in KeyChain " << std::endl; - } - } - else - { - std::cerr << "clearAutoLogin() Password found on KeyChain! " << std::endl; - - OSStatus deleteStatus = SecKeychainItemDelete (itemRef); - if (status != 0) - { - std::cerr << "clearAutoLogin() Failed to Delete Password status: " << deleteStatus << std::endl; - } - else - { - std::cerr << "clearAutoLogin() Deleted Password" << std::endl; - } - } - - //Free the data allocated by SecKeychainFindGenericPassword: - - SecKeychainItemFreeContent ( - NULL, //No attribute data to release - passwordData //Release data buffer allocated by SecKeychainFindGenericPassword - ); - - if (itemRef) CFRelease(itemRef); - - return (status == 0); - - /******************** OSX KeyChain stuff *****************************/ - - #else // WINDOWS / Generic Linux. - - std::string passwdfile = getAutologinFileName(ssl_id) ; - - FILE *fp = RsDirUtil::rs_fopen(passwdfile.c_str(), "wb"); - - if (fp != NULL) - { - fwrite(" ", 1, 1, fp); - fclose(fp); - bool removed = remove(passwdfile.c_str()); - - if(removed != 0) - std::cerr << "RsLoginHandler::clearAutoLogin(): Failed to Removed help file" << std::endl; - - std::cerr << "AutoLogin Data cleared "; - std::cerr << std::endl; - return true; - } - - return false; - #endif -#endif -} - -std::string RsLoginHandler::getAutologinFileName(const RsPeerId& /*ssl_id*/) -{ - return RsAccounts::AccountKeysDirectory() + "/" + "help.dta" ; -} - -#endif // RS_AUTOLOGIN diff --git a/libretroshare/src/rsserver/rsloginhandler.h b/libretroshare/src/rsserver/rsloginhandler.h deleted file mode 100644 index 1c95a741b..000000000 --- a/libretroshare/src/rsserver/rsloginhandler.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * libretroshare/src/rsserver: rsloginhandler.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2018 retroshare team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include - -/** - * This class handles login, meaning that it retrieves the SSL password from - * either the keyring or help.dta file, if autologin is enabled, or from the - * ssl_passphrase.pgp file, asking for the GPG password to decrypt it. - * - * This class should handle the following scenario: - * - * Normal login: - * - SSL key is stored -> do autologin - * - SSL key is not stored - * - if we're actually in the login process, ask for the gpg passwd, and - * decrypt the key file - * - if we're just trying for autologin, don't ask for the gpg passwd and - * return null - * - * Key creation: - * - the key should be stored in the gpg file. - */ -class RsLoginHandler -{ -public: - /** - * Gets the SSL passwd by any means: try autologin, and look into gpg file - * if enable_gpg_key_callback==true - */ - static bool getSSLPassword( const RsPeerId& ssl_id, - bool enable_gpg_key_callback, - std::string& ssl_password); - - /** - * Checks whether the ssl passwd is already in the gpg file. If the file's - * not here, the passwd is stored there, encrypted with the current GPG key. - */ - static bool checkAndStoreSSLPasswdIntoGPGFile( - const RsPeerId& ssl_id, const std::string& ssl_passwd ); - -#ifdef RS_AUTOLOGIN - /** - * Stores the given ssl_id/passwd pair into the keyring, or by default into - * a file in /[ssl_id]/keys/help.dta - */ - static bool enableAutoLogin(const RsPeerId& ssl_id,const std::string& passwd) ; - - /// Clears autologin entry. - static bool clearAutoLogin(const RsPeerId& ssl_id) ; -#endif // RS_AUTOLOGIN - -private: - static bool getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword); - static std::string getSSLPasswdFileName(const RsPeerId& ssl_id); - -#ifdef RS_AUTOLOGIN - static bool tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd); - static std::string getAutologinFileName(const RsPeerId& ssl_id); -#endif // RS_AUTOLOGIN -}; - diff --git a/libretroshare/src/scripts/checks.mk b/libretroshare/src/scripts/checks.mk deleted file mode 100644 index 61d242ef0..000000000 --- a/libretroshare/src/scripts/checks.mk +++ /dev/null @@ -1,25 +0,0 @@ -#Basic checks - -ifndef RS_TOP_DIR -dummy: - echo "RS_TOP_DIR is not defined in your makefile" -endif - -ifndef SSL_DIR -dummy: - echo "you must define SSL_DIR before you can compile" - -endif - -ifneq ($(OS),Linux) - ifneq ($(OS),MacOSX) - ifndef PTHREADS_DIR -dummy: - echo "you must define PTHREADS_DIR before you can compile" - - endif - endif -endif - - - diff --git a/libretroshare/src/scripts/config-cygwin.mk b/libretroshare/src/scripts/config-cygwin.mk deleted file mode 100644 index ec4518f68..000000000 --- a/libretroshare/src/scripts/config-cygwin.mk +++ /dev/null @@ -1,118 +0,0 @@ -ifneq ($(OS),Cygwin) -dummy: - echo "ERROR Cygwin configuration file included, but (OS != Cygwin) - -endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -SRC_ROOT=../../../.. - -PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads/pthreads.2 - -################### - -#ALT_SRC_ROOT=/cygdrive/c/RetroShareBuild/src -#SRC_ROOT=/cygdrive/c/RetroShareBuild/src - -#PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads-w32-2-8-0-release - -################### - -ZLIB_DIR=$(ALT_SRC_ROOT)/zlib-1.2.3 - -SSL_DIR=$(SRC_ROOT)/openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -ifdef PQI_USE_XPGP - INCLUDE += -I $(SSL_DIR)/include -endif - -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -RSCFLAGS = -Wall -g $(INCLUDE) - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -WININC += -DPTW32_STATIC_LIB -WININC += -mno-cygwin -mwindows -fno-exceptions -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(PTHREADS_DIR) $(WININC) -CFLAGS += -I$(ZLIB_DIR) - -LIBS = -L$(LIBDIR) -lretroshare -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) -endif - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -RSCFLAGS += $(WININC) - - diff --git a/libretroshare/src/scripts/config-linux.mk b/libretroshare/src/scripts/config-linux.mk deleted file mode 100644 index e82e903c2..000000000 --- a/libretroshare/src/scripts/config-linux.mk +++ /dev/null @@ -1,98 +0,0 @@ - -ifneq ($(OS),Linux) -dummy: - echo "ERROR Linux configuration file included, but (OS != Linux) - -endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -#PQI_USE_SSLONLY = 1 -#PQI_USE_XPGP = 1 - - -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -SSL_DIR=../../../../openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=../../../../miniupnpc-1.0 - -# Need to define miniupnpc version because API changed a little between v1.0 and 1.2 -# put 10 for 1.0 and 12 for 1.2 -DEFINES += -DMINIUPNPC_VERSION=10 - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) -#-I$(KADC_DIR) -CFLAGS = -Wall -g $(INCLUDE) -CFLAGS += ${DEFINES} - -ifdef PQI_USE_XPGP - INCLUDE += -I $(SSL_DIR)/include -endif - -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_SSLONLY - CFLAGS += -DPQI_USE_SSLONLY -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -RSCFLAGS = -Wall -g $(INCLUDE) -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# march=i686 causes problems while 64Bit compiling, GCC tries to generate Output for a m64 machine, but the marchi686 -# doesnt allow the instructionfs for that. -# -# gcc docu: http://gcc.gnu.org/onlinedocs/gcc-4.0.3/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options - -# Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include ${DEFINES} -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM - -######################################################################### -# OS specific Linking. -######################################################################### - -LIBS = -L$(LIBDIR) -lretroshare -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) - endif -LIBS += -lssl -lcrypto -lpthread -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += $(XLIB) -ldl -lz -LIBS += -lgpgme - -RSLIBS = $(LIBS) - - diff --git a/libretroshare/src/scripts/config-macosx.mk b/libretroshare/src/scripts/config-macosx.mk deleted file mode 100644 index 7aa56d361..000000000 --- a/libretroshare/src/scripts/config-macosx.mk +++ /dev/null @@ -1,152 +0,0 @@ - -ifneq ($(OS),MacOSX) -dummy: - echo "ERROR MacOSX configuration file included, but (OS != MacOSX) - -endif - -############ LINUX CONFIGURATION ######################## - - -# FLAGS to decide if we want i386 Build or ppc Build -# -# - -# PPC is default -# Could define both for combined compilation... -# except might not work for bio_tou.c file! -# -# MAC_I386_BUILD = 1 -# MAC_PPC_BUILD = 1 - -#MAC_I386_BUILD = 1 -#MAC_PPC_BUILD = 1 - -ifndef MAC_I386_BUILD - MAC_PPC_BUILD = 1 -endif - -# flags for components.... -#PQI_USE_SSLONLY = 1 -#PQI_USE_XPGP = 1 - -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -SSL_DIR=../../../../../src/openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=../../../../../src/miniupnpc-1.0 - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm - -RANLIB = ranlib - -# Dummy ranlib -> can't do it until afterwards with universal binaries. -# RANLIB = ls -l - -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -OPT_DIR = /opt/local -OPT_INCLUDE = $(OPT_DIR)/include -OPT_LIBS = $(OPT_DIR)/lib - -INCLUDE = -I $(RS_TOP_DIR) -I $(OPT_INCLUDE) -#CFLAGS = -Wall -O3 -CFLAGS = -Wall -g - -# Flags for architecture builds. -ifdef MAC_I386_BUILD - CFLAGS += -arch i386 -endif - -ifdef MAC_PPC_BUILD - CFLAGS += -arch ppc -endif - -CFLAGS += $(INCLUDE) - -# This Line is for Universal BUILD for 10.4 + 10.5 -# (but unlikely to work unless Qt Libraries are build properly) -# CFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk - -ifdef PQI_USE_XPGP - INCLUDE += -I $(SSL_DIR)/include - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_SSLONLY - CFLAGS += -DPQI_USE_SSLONLY -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -# RSCFLAGS = -Wall -O3 $(INCLUDE) - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - - -# Flags for architecture builds. -ifdef MAC_I386_BUILD - BIOCFLAGS = -arch i386 -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -endif - -ifdef MAC_PPC_BUILD - BIOCFLAGS = -arch ppc -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN -endif - - - -# MacOSX flags -# BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN - -# This is for the Universal Build... -# but is unlikely to work... as options are PPC specific.... -# -# BIOCFLAGS = -arch ppc -arch i386 -I $(SSL_DIR)/include -DOPENSSL_SYSNAME_MACOSX -DOPENSSL_THREADS -D_REENTRANT -DOPENSSL_NO_KRB5 -O3 -fomit-frame-pointer -fno-common -DB_ENDIAN - - -######################################################################### -# OS specific Linking. -######################################################################### - -LIBS = -Wl,-search_paths_first - -# for Univeral BUILD -# LIBS += -arch ppc -arch i386 -# LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386 - -LIBS += -L$(LIBDIR) -lretroshare -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) - endif -LIBS += -lssl -lcrypto -lpthread -LIBS += -L$(OPT_LIBS) -LIBS += -lgpgme -lgpg-error -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += $(XLIB) -ldl -lz - -RSLIBS = $(LIBS) - - diff --git a/libretroshare/src/scripts/config-mingw.mk b/libretroshare/src/scripts/config-mingw.mk deleted file mode 100644 index c0040ac4e..000000000 --- a/libretroshare/src/scripts/config-mingw.mk +++ /dev/null @@ -1,138 +0,0 @@ -#ifneq ($(OS),"Win ") -#dummy: -# echo "ERROR OS = $(OS)" -# echo "ERROR MinGW configuration file included, but (OS != Win) -# -#endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -#PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -SRC_ROOT_PKG=/home/Mark/prog/retroshare/package/rs-win-v0.5.0/src -SRC_ROOT_GPG=/local - -#ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -#SRC_ROOT=../../../.. - -PTHREADS_DIR=$(SRC_ROOT_PKG)/pthreads-w32-2-8-0/Pre-built.2 -ZLIB_DIR=$(SRC_ROOT_PKG)/zlib-1.2.3 -SSL_DIR=$(SRC_ROOT_PKG)/openssl-tmp -UPNPC_DIR=$(SRC_ROOT_PKG)/miniupnpc-1.3 - -########################################################################### - -#### Enable this section for compiling with MSYS/MINGW compile -#SRC_ROOT=/home/linux - -#SSL_DIR=$(SRC_ROOT)/OpenSSL -#GPGME_DIR=$(SRC_ROOT)/gpgme-1.1.8 -#GPG_ERROR_DIR=$(SRC_ROOT)/libgpg-error-1.7 - -#ZLIB_DIR=$(SRC_ROOT)/zlib-1.2.3 -#UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 -#PTHREADS_DIR=$(SRC_ROOT)/pthreads-w32-2-8-0-release - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ####################################### - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -# These aren't used anymore.... really. -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -# SSL / pthreads / Zlib -# included by default for Windows compilation. -INCLUDE += -I $(SSL_DIR)/include -INCLUDE += -I$(PTHREADS_DIR) -INCLUDE += -I$(ZLIB_DIR) - - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -BIOCFLAGS += -DWINDOWS_SYS - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -#WININC += -DPTW32_STATIC_LIB -#WININC += -mno-cygwin -mwindows -fno-exceptions - -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(SSL_DIR)/include -CFLAGS += -I$(PTHREADS_DIR)/include -CFLAGS += -I$(ZLIB_DIR) -CFLAGS += -I$(SRC_ROOT_GPG)/include - -### Enable this for GPGME and GPG ERROR dirs -#CFLAGS += -I$(GPGME_DIR)/src -#CFLAGS += -I$(GPG_ERROR_DIR)/src - -CFLAGS += $(WININC) - - - -LIBS = -L$(LIBDIR) -lretroshare - -LIBS += -L$(SSL_DIR) - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -#RSCFLAGS = -Wall -g $(INCLUDE) -#RSCFLAGS += $(WININC) - - diff --git a/libretroshare/src/scripts/config.mk b/libretroshare/src/scripts/config.mk deleted file mode 100644 index 9f22fa363..000000000 --- a/libretroshare/src/scripts/config.mk +++ /dev/null @@ -1,27 +0,0 @@ - -# determine which operating system -# -########################################################################### -#Define OS. -# -OS = Linux -#OS = MacOSX -#OS = Cygwin -#OS = Win # MinGw. -########################################################################### - -ifeq ($(OS),Linux) - include $(RS_TOP_DIR)/scripts/config-linux.mk -else - ifeq ($(OS),MacOSX) - include $(RS_TOP_DIR)/scripts/config-macosx.mk - else - ifeq ($(OS),Cygwin) - include $(RS_TOP_DIR)/scripts/config-cygwin.mk - else - include $(RS_TOP_DIR)/scripts/config-mingw.mk - endif - endif -endif - -########################################################################### diff --git a/libretroshare/src/scripts/documentation-script b/libretroshare/src/scripts/documentation-script deleted file mode 100755 index 0d47217bc..000000000 --- a/libretroshare/src/scripts/documentation-script +++ /dev/null @@ -1,16 +0,0 @@ - -#!/bin/bash -# This script creates a doxygen documentation of retroshare -# you need to install doxygen and graph-viz(dot tool) for script to work - - -echo "doxygen and graph viz must be installed" - -# create documentation -doxygen rsDocumentation || exit - -#indicate finshed -echo "complete" - - - diff --git a/libretroshare/src/scripts/makeMacUniversalLibrary.sh b/libretroshare/src/scripts/makeMacUniversalLibrary.sh deleted file mode 100755 index b1222d049..000000000 --- a/libretroshare/src/scripts/makeMacUniversalLibrary.sh +++ /dev/null @@ -1,35 +0,0 @@ -# -## clean up all bits of libretroshare -echo make clobber -make clobber -# -## make the standard version (PPC) -echo make librs -make librs -# -LIB=libretroshare.a -LIB_PPC=libretroshare_ppc.a -LIB_X86=libretroshare_x86.a - -MAC_SCRIPT="./scripts/config-macosx.mk" - -echo cp lib/$LIB lib/$LIB_PPC -cp lib/$LIB lib/$LIB_PPC - -echo make clobber -make clobber - -echo make "MAC_I386_BUILD=1" librs -make "MAC_I386_BUILD=1" librs - -echo cp lib/$LIB lib/$LIB_X86 -cp lib/$LIB lib/$LIB_X86 - -# magic combine trick. -echo cd lib -cd lib - -echo lipo -create libretroshare_*.a -output $LIB -lipo -create libretroshare_*.a -output $LIB - - diff --git a/libretroshare/src/scripts/regress.mk b/libretroshare/src/scripts/regress.mk deleted file mode 100644 index f80b48451..000000000 --- a/libretroshare/src/scripts/regress.mk +++ /dev/null @@ -1,25 +0,0 @@ - -testoutputfiles = $(foreach tt,$(1),$(tt).tstout) - -%.tstout : %.sh - -sh ./$< > $@ 2>&1 - -%.tstout : % - -./$< > $@ 2>&1 - -TESTOUT = $(call testoutputfiles,$(TESTS)) - -.phony : tests regress retest clobber - -tests: $(TESTS) - -regress: $(TESTOUT) - @-echo "--------------- SUCCESS (count):" - @-grep -c SUCCESS $(TESTOUT) - @-echo "--------------- FAILURE REPORTS:" - @-grep FAILURE $(TESTOUT) || echo no failures - @-echo "--------------- end" - -retest: - -/bin/rm $(TESTOUT) - diff --git a/libretroshare/src/scripts/rsDocumentation b/libretroshare/src/scripts/rsDocumentation deleted file mode 100644 index d21dfaa1c..000000000 --- a/libretroshare/src/scripts/rsDocumentation +++ /dev/null @@ -1,281 +0,0 @@ -# Doxyfile 1.5.3 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = retroshare -PROJECT_NUMBER = 1.0 -OUTPUT_DIRECTORY = ../ -CREATE_SUBDIRS = YES -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class " \ - "The $name widget " \ - "The $name file " \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = ../ -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text " -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ../ -INPUT_ENCODING = UTF-8 -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.C \ - *.CC \ - *.C++ \ - *.II \ - *.I++ \ - *.H \ - *.HH \ - *.H++ \ - *.CS \ - *.PHP \ - *.PHP3 \ - *.M \ - *.MM \ - *.PY -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = NO -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = NO -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/libretroshare/src/scripts/rules.mk b/libretroshare/src/scripts/rules.mk deleted file mode 100644 index f8d75c21f..000000000 --- a/libretroshare/src/scripts/rules.mk +++ /dev/null @@ -1,23 +0,0 @@ - -# defines required / used. -# -# CFLAGS -# -# - -librs: $(RSOBJ) - $(AR) r $(LIBRS) $(RSOBJ) - $(RANLIB) $(LIBRS) - -.cc.o: - $(CC) $(CFLAGS) -c $< - -clean: - -/bin/rm $(RSOBJ) $(EXECOBJ) $(TESTOBJ) - -clobber: clean retest - -/bin/rm $(EXEC) $(TESTS) - - -include $(RS_TOP_DIR)/scripts/regress.mk - diff --git a/libretroshare/src/serialiser/rsbaseserial.cc b/libretroshare/src/serialiser/rsbaseserial.cc deleted file mode 100644 index 276872364..000000000 --- a/libretroshare/src/serialiser/rsbaseserial.cc +++ /dev/null @@ -1,311 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsbaseserial.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include /* Included because GCC4.4 wants it */ -#include /* Included because GCC4.4 wants it */ - -#include "retroshare/rstypes.h" -#include "serialiser/rsbaseserial.h" -#include "util/rsnet.h" -#include "util/rstime.h" - -#include -#include - -/* UInt8 get/set */ - -bool getRawUInt8(const void *data, uint32_t size, uint32_t *offset, uint8_t *out) -{ - /* first check there is space */ - if (size < *offset + 1) - { - std::cerr << "(EE) Cannot deserialise uint8_t: not enough size." << std::endl; - return false; - } - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* extract the data */ - memcpy(out, buf, sizeof(uint8_t)); - (*offset) += 1; - - return true; -} - -bool setRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t in) -{ - /* first check there is space */ - if (size < *offset + 1) - { - std::cerr << "(EE) Cannot serialise uint8_t: not enough size." << std::endl; - return false; - } - - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* pack it in */ - memcpy(buf, &in, sizeof(uint8_t)); - - (*offset) += 1; - return true; -} -/* UInt16 get/set */ - -bool getRawUInt16(const void *data, uint32_t size, uint32_t *offset, uint16_t *out) -{ - /* first check there is space */ - if (size < *offset + 2) - { - std::cerr << "(EE) Cannot deserialise uint16_t: not enough size." << std::endl; - return false; - } - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* extract the data */ - uint16_t netorder_num; - memcpy(&netorder_num, buf, sizeof(uint16_t)); - - (*out) = ntohs(netorder_num); - (*offset) += 2; - return true; -} - -bool setRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t in) -{ - /* first check there is space */ - if (size < *offset + 2) - { - std::cerr << "(EE) Cannot serialise uint16_t: not enough size." << std::endl; - return false; - } - - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* convert the data to the right format */ - uint16_t netorder_num = htons(in); - - /* pack it in */ - memcpy(buf, &netorder_num, sizeof(uint16_t)); - - (*offset) += 2; - return true; -} - -/* UInt32 get/set */ - -bool getRawUInt32(const void *data, uint32_t size, uint32_t *offset, uint32_t *out) -{ - /* first check there is space */ - if (size < *offset + 4) - { - std::cerr << "(EE) Cannot deserialise uint32_t: not enough size." << std::endl; - return false; - } - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* extract the data */ - uint32_t netorder_num; - memcpy(&netorder_num, buf, sizeof(uint32_t)); - - (*out) = ntohl(netorder_num); - (*offset) += 4; - return true; -} - -bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in) -{ - /* first check there is space */ - if (size < *offset + 4) - { - std::cerr << "(EE) Cannot serialise uint32_t: not enough size." << std::endl; - return false; - } - - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* convert the data to the right format */ - uint32_t netorder_num = htonl(in); - - /* pack it in */ - memcpy(buf, &netorder_num, sizeof(uint32_t)); - - (*offset) += 4; - return true; -} - -/* UInt64 get/set */ - -bool getRawUInt64(const void *data, uint32_t size, uint32_t *offset, uint64_t *out) -{ - /* first check there is space */ - if (size < *offset + 8) - { - std::cerr << "(EE) Cannot deserialise uint64_t: not enough size." << std::endl; - return false; - } - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* extract the data */ - uint64_t netorder_num; - memcpy(&netorder_num, buf, sizeof(uint64_t)); - - (*out) = ntohll(netorder_num); - (*offset) += 8; - return true; -} - -bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in) -{ - /* first check there is space */ - if (size < *offset + 8) - { - std::cerr << "(EE) Cannot serialise uint64_t: not enough size." << std::endl; - return false; - } - - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* convert the data to the right format */ - uint64_t netorder_num = htonll(in); - - /* pack it in */ - memcpy(buf, &netorder_num, sizeof(uint64_t)); - - (*offset) += 8; - return true; -} - -bool getRawUFloat32(const void *data, uint32_t size, uint32_t *offset, float& f) -{ - uint32_t n ; - if(!getRawUInt32(data, size, offset, &n) ) - return false ; - - f = 1.0f/ ( n/(float)(~(uint32_t)0)) - 1.0f ; - - return true ; -} - -bool setRawUFloat32(void *data,uint32_t size,uint32_t *offset,float f) -{ - uint32_t sz = 4; - - if ( !data || size <= *offset || size < sz + *offset ) - { - std::cerr << "(EE) not enough room. SIZE+offset=" << sz+*offset << " and size is only " << size << std::endl; - return false; - } - if(f < 0.0f) - { - std::cerr << "(EE) Cannot serialise invalid negative float value " << f << " in " << __PRETTY_FUNCTION__ << std::endl; - return false ; - } - - // This serialisation is quite accurate. The max relative error is approx. - // 0.01% and most of the time less than 1e-05% The error is well distributed - // over numbers also. - // - uint32_t n = (f < 1e-7)?(~(uint32_t)0): ((uint32_t)( (1.0f/(1.0f+f) * (~(uint32_t)0)))) ; - - return setRawUInt32(data, size, offset, n); -} - - -uint32_t getRawStringSize(const std::string &outStr) -{ - return outStr.length() + 4; -} - -bool getRawString(const void *data, uint32_t size, uint32_t *offset, std::string &outStr) -{ - outStr.clear(); - - uint32_t len = 0; - if (!getRawUInt32(data, size, offset, &len)) - { - std::cerr << "getRawString() get size failed" << std::endl; - return false; - } - - /* check there is space for string */ - if(len > size || size-len < *offset) // better than if(size < *offset + len) because it avoids integer overflow - { - std::cerr << "getRawString() not enough size" << std::endl; - print_stacktrace(); - return false; - } - uint8_t *buf = &(((uint8_t *) data)[*offset]); - - for (uint32_t i = 0; i < len; i++) - { - outStr += buf[i]; - } - - (*offset) += len; - return true; -} - -bool setRawString(void *data, uint32_t size, uint32_t *offset, const std::string &inStr) -{ - uint32_t len = inStr.length(); - /* first check there is space */ - - if(size < 4 || len > size-4 || size-len-4 < *offset) // better than if(size < *offset + len + 4) because it avoids integer overflow - { - std::cerr << "setRawString() Not enough size" << std::endl; - return false; - } - - if (!setRawUInt32(data, size, offset, len)) - { - std::cerr << "setRawString() set size failed" << std::endl; - return false; - } - - void *buf = (void *) &(((uint8_t *) data)[*offset]); - - /* pack it in */ - memcpy(buf, inStr.c_str(), len); - - (*offset) += len; - return true; -} - -bool getRawTimeT(const void *data,uint32_t size,uint32_t *offset,rstime_t& t) -{ - uint64_t T; - bool res = getRawUInt64(data,size,offset,&T); - t = T; - - if(t < 0) // [[unlikely]] - std::cerr << __PRETTY_FUNCTION__ << " got a negative time: " << t - << " this seems fishy, report to the developers!" << std::endl; - - return res; -} -bool setRawTimeT(void *data, uint32_t size, uint32_t *offset, const rstime_t& t) -{ - if(t < 0) // [[unlikely]] - std::cerr << __PRETTY_FUNCTION__ << " got a negative time: " << t - << " this seems fishy, report to the developers!" << std::endl; - - return setRawUInt64(data,size,offset,t) ; -} diff --git a/libretroshare/src/serialiser/rsbaseserial.h b/libretroshare/src/serialiser/rsbaseserial.h deleted file mode 100644 index 839932927..000000000 --- a/libretroshare/src/serialiser/rsbaseserial.h +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsbaseserial.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_BASE_PACKING_H -#define RS_BASE_PACKING_H - -#include -#include -#include - -#include "retroshare/rsids.h" -#include "util/rstime.h" - -/******************************************************************* - * This is at the lowlevel packing routines. They are usually - * created in pairs - one to pack the data, the other to unpack. - * - * getRawXXX(void *data, uint32_t size, uint32_t *offset, XXX *out); - * setRawXXX(void *data, uint32_t size, uint32_t *offset, XXX *in); - * - * - * data - the base pointer to the serialised data. - * size - size of the memory pointed to by data. - * *offset - where we want to (un)pack the data. - * This is incremented by the datasize. - * - * *in / *out - the data to (un)pack. - * - ******************************************************************/ - -bool getRawUInt8(const void *data, uint32_t size, uint32_t *offset, uint8_t *out); -bool setRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t in); - -bool getRawUInt16(const void *data, uint32_t size, uint32_t *offset, uint16_t *out); -bool setRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t in); - -bool getRawUInt32(const void *data, uint32_t size, uint32_t *offset, uint32_t *out); -bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in); - -bool getRawUInt64(const void *data, uint32_t size, uint32_t *offset, uint64_t *out); -bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in); - -bool getRawUFloat32(const void *data, uint32_t size, uint32_t *offset, float& out); -bool setRawUFloat32(void *data, uint32_t size, uint32_t *offset, float in); - -uint32_t getRawStringSize(const std::string &outStr); -bool getRawString(const void *data, uint32_t size, uint32_t *offset, std::string &outStr); -bool setRawString(void *data, uint32_t size, uint32_t *offset, const std::string &inStr); - -bool getRawTimeT(const void *data, uint32_t size, uint32_t *offset, rstime_t& outTime); -bool setRawTimeT(void *data, uint32_t size, uint32_t *offset, const rstime_t& inTime); - -#endif - diff --git a/libretroshare/src/serialiser/rsserial.cc b/libretroshare/src/serialiser/rsserial.cc deleted file mode 100644 index 52123abf1..000000000 --- a/libretroshare/src/serialiser/rsserial.cc +++ /dev/null @@ -1,563 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsserial.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "serialiser/rsbaseserial.h" - -#include "util/rsthreads.h" -#include "util/rsstring.h" -#include "util/rsprint.h" - -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include -#include -#include -#include -#include - - -/*** - * #define RSSERIAL_DEBUG 1 - * #define RSSERIAL_ERROR_DEBUG 1 -***/ - -// As these represent SERIOUS ERRORs, this debug should be left one. -#define RSSERIAL_ERROR_DEBUG 1 - - -#if defined(RSSERIAL_DEBUG) || defined(RSSERIAL_ERROR_DEBUG) - #include -#endif - -RsItem::RsItem(uint32_t t) -:type(t) -{ - _priority_level = QOS_PRIORITY_UNKNOWN ; // This value triggers PQIInterface to complain about undefined priorities -} - - -#ifdef DO_STATISTICS -class Counter -{ - public: - Counter(int i): _i(i) {} - Counter(): _i(0) {} - - int v() const { return _i ; } - int& v() { return _i ; } - private: - int _i ; -}; - - static RsMutex smtx ; - static std::map size_hits ; - static int nb_rsitem_creations = 0 ; - static int total_rsitem_mallocs = 0 ; - static int total_rsitem_frees = 0 ; - static int total_rsitem_freed = 0 ; - static rstime_t last_time = 0 ; - -void *RsItem::operator new(size_t s) -{ -// std::cerr << "New RsItem: s=" << s << std::endl; - - RsStackMutex m(smtx) ; - - ++size_hits[ s ].v() ; - - rstime_t now = time(NULL); - ++nb_rsitem_creations ; - total_rsitem_mallocs += s ; - - if(last_time + 20 < now) - { - std::cerr << "Memory statistics:" << std::endl; - std::cerr << " Total RsItem memory: " << total_rsitem_mallocs << std::endl; - std::cerr << " Total RsItem creations: " << nb_rsitem_creations << std::endl; - std::cerr << " Total RsItem freed memory: " << total_rsitem_freed << std::endl; - std::cerr << " Total RsItem deletions: " << total_rsitem_frees << std::endl; - std::cerr << "Now printing histogram:" << std::endl; - - for(std::map::const_iterator it(size_hits.begin());it!=size_hits.end();++it) - std::cerr << it->first << " " << it->second.v() << std::endl; - last_time = now ; - } - - RsItem *a = static_cast(::operator new(s)) ; - return a ; -} -void RsItem::operator delete(void *p,size_t s) -{ -// std::cerr << "Delete RsItem: s=" << s << std::endl; - - RsStackMutex m(smtx) ; - total_rsitem_freed += s ; - ++total_rsitem_frees ; - - ::operator delete(p) ; -} -#endif - -RsItem::RsItem(uint8_t ver, uint8_t cls, uint8_t t, uint8_t subtype) -{ - _priority_level = QOS_PRIORITY_UNKNOWN ; // This value triggers PQIInterface to complain about undefined priorities - - type = (ver << 24) + (cls << 16) + (t << 8) + subtype; -} - -RsItem::~RsItem() = default; - -void RsItem::print_string(std::string &out, uint16_t indent) -{ - std::ostringstream stream; - print(stream, indent); - - out += stream.str(); -} -uint32_t RsItem::PacketId() const -{ - return type; -} - -uint8_t RsItem::PacketVersion() -{ - return (type >> 24); -} - - -uint8_t RsItem::PacketClass() -{ - return (type >> 16) & 0xFF; -} - - -uint8_t RsItem::PacketType() -{ - return (type >> 8) & 0xFF; -} - - -uint8_t RsItem::PacketSubType() const -{ - return (type & 0xFF); -} - - - /* For Service Packets */ -RsItem::RsItem(uint8_t ver, uint16_t service, uint8_t subtype) -{ - _priority_level = QOS_PRIORITY_UNKNOWN ; // This value triggers PQIInterface to complain about undefined priorities - type = (ver << 24) + (service << 8) + subtype; - return; -} - -uint16_t RsItem::PacketService() const -{ - return (type >> 8) & 0xFFFF; -} - -void RsItem::setPacketService(uint16_t service) -{ - type &= 0xFF0000FF; - type |= (uint32_t) (service << 8); -} - - -RsSerialType::RsSerialType(uint32_t t) - :type(t & 0xFFFFFF00) -{ - return; -} - -RsSerialType::RsSerialType(uint8_t ver, uint8_t cls, uint8_t t) -{ - type = (ver << 24) + (cls << 16) + (t << 8); - return; -} - -RsSerialType::RsSerialType(uint8_t ver, uint16_t service) -{ - type = (ver << 24) + (service << 8); - return; -} - -RsSerialType::~RsSerialType() -{ - return; -} - -uint32_t RsSerialType::size(RsItem *) -{ -#ifdef RSSERIAL_DEBUG - std::cerr << "RsSerialType::size()" << std::endl; -#endif - - /* base size: type + length */ - return 8; -} - -bool RsSerialType::serialise(RsItem */*item*/, void */*data*/, uint32_t */*size*/) -{ - std::cerr << "(EE) Empty method called for missing serialize() method in serializer class " << typeid(this).name() << std::endl; -#ifdef RSSERIAL_DEBUG - std::cerr << "RsSerialType::serialise()" << std::endl; -#endif - return false; -} - -RsItem * RsSerialType::deserialise(void */*data*/, uint32_t */*size*/) -{ -#ifdef RSSERIAL_DEBUG - std::cerr << "RsSerialType::deserialise()" << std::endl; -#endif - return NULL; -} - -uint32_t RsSerialType::PacketId() const -{ - return type; -} - - - - -RsSerialiser::RsSerialiser() = default; - - -RsSerialiser::~RsSerialiser() -{ - /* clean up the map */ - std::map::iterator it; - for(it = serialisers.begin(); it != serialisers.end(); ++it) - { - delete (it->second); - } - serialisers.clear(); - return; -} - - - -bool RsSerialiser::addSerialType(RsSerialType *serialiser) -{ - uint32_t type = (serialiser->PacketId() & 0xFFFFFF00); - std::map::iterator it; - if (serialisers.end() != (it = serialisers.find(type))) - { -#ifdef RSSERIAL_DEBUG - std::cerr << "RsSerialiser::addSerialType() Error Serialiser already exists!"; - std::cerr << std::endl; -#endif - return false; - } - - serialisers[type] = serialiser; - return true; -} - - - -uint32_t RsSerialiser::size(RsItem *item) -{ - /* find the type */ - uint32_t type = (item->PacketId() & 0xFFFFFF00); - std::map::iterator it; - - if (serialisers.end() == (it = serialisers.find(type))) - { - /* remove 8 more bits -> try again */ - type &= 0xFFFF0000; - if (serialisers.end() == (it = serialisers.find(type))) - { - /* one more try */ - type &= 0xFF000000; - if (serialisers.end() == (it = serialisers.find(type))) - { - -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::size() ERROR serialiser missing!" << std::endl; - - std::string out; - rs_sprintf(out, "%x", item->PacketId()); - - std::cerr << "RsSerialiser::size() PacketId: "; - std::cerr << out; - std::cerr << std::endl; -#endif - return 0; - } - } - } - -#ifdef RSSERIAL_DEBUG - std::string out; - rs_sprintf(out, "RsSerialiser::size() Item->PacketId(): %x matched to Serialiser Type: %lu", item->PacketId(), type); - std::cerr << out << std::endl; -#endif - - return (it->second)->size(item); -} - -bool RsSerialiser::serialise (RsItem *item, void *data, uint32_t *size) -{ - /* find the type */ - uint32_t type = (item->PacketId() & 0xFFFFFF00); - std::map::iterator it; - - if (serialisers.end() == (it = serialisers.find(type))) - { - /* remove 8 more bits -> try again */ - type &= 0xFFFF0000; - if (serialisers.end() == (it = serialisers.find(type))) - { - /* one more try */ - type &= 0xFF000000; - if (serialisers.end() == (it = serialisers.find(type))) - { - -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::serialise() ERROR serialiser missing!"; - std::string out; - rs_sprintf(out, "%x", item->PacketId()); - - std::cerr << "RsSerialiser::serialise() PacketId: "; - std::cerr << out; - std::cerr << std::endl; -#endif - return false; - } - } - } - -#ifdef RSSERIAL_DEBUG - std::string out; - rs_sprintf(out, "RsSerialiser::serialise() Item->PacketId(): %x matched to Serialiser Type: %lu", item->PacketId(), type); - std::cerr << out << std::endl; -#endif - - return (it->second)->serialise(item, data, size); -} - - - -RsItem * RsSerialiser::deserialise(void *data, uint32_t *size) -{ - /* find the type */ - if (*size < 8) - { -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::deserialise() ERROR Not Enough Data(1)"; - std::cerr << std::endl; -#endif - return NULL; - } - - uint32_t type = (getRsItemId(data) & 0xFFFFFF00); - uint32_t pkt_size = getRsItemSize(data); - - //std::cerr << "RsSerialiser::deserialise() RsItem Type: " << std::hex << getRsItemId(data) << " Size: " << pkt_size; - //std::cerr << std::endl; - - if (pkt_size > *size) - { -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::deserialise() ERROR Size mismatch(2)"; - std::cerr << std::endl; -#endif - return NULL; - } - if(pkt_size > getRsPktMaxSize()) - { - std::cerr << "(EE) trying to deserialise a packet with absurdely large size " << pkt_size << ". This means there's a bug upward or packet corruption. Packet content: " << RsUtil::BinToHex((unsigned char*)data,std::min(300u,pkt_size)) ; - return NULL ; - } - - /* store the packet size to return the amount we should use up */ - *size = pkt_size; - - std::map::iterator it; - if (serialisers.end() == (it = serialisers.find(type))) - { - /* remove 8 more bits -> try again */ - type &= 0xFFFF0000; - if (serialisers.end() == (it = serialisers.find(type))) - { - /* one more try */ - type &= 0xFF000000; - if (serialisers.end() == (it = serialisers.find(type))) - { - -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::deserialise() ERROR deserialiser missing!"; - std::string out; - rs_sprintf(out, "%x", getRsItemId(data)); - - std::cerr << "RsSerialiser::deserialise() PacketId: "; - std::cerr << out << std::endl; -#endif - return NULL; - } - } - } - - RsItem *item = (it->second)->deserialise(data, &pkt_size); - if (!item) - { -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::deserialise() ERROR Failed!"; - std::cerr << std::endl; - std::cerr << "RsSerialiser::deserialise() pkt_size: " << pkt_size << " vs *size: " << *size; - std::cerr << std::endl; - - //RsItem *item2 = (it->second)->deserialise(data, &pkt_size); - - uint32_t failedtype = getRsItemId(data); - std::cerr << "RsSerialiser::deserialise() FAILED PACKET Size: "; - std::cerr << getRsItemSize(data) << " ID: "; - std::cerr << std::hex << failedtype << std::endl; - std::cerr << "RsSerialiser::deserialise() FAILED PACKET: "; - std::cerr << " Version: " << std::hex << (uint32_t) getRsItemVersion(failedtype) << std::dec; - std::cerr << " Class: " << std::hex << (uint32_t) getRsItemClass(failedtype) << std::dec; - std::cerr << " Type: " << std::hex << (uint32_t) getRsItemType(failedtype) << std::dec; - std::cerr << " SubType: " << std::hex << (uint32_t) getRsItemSubType(failedtype) << std::dec; - std::cerr << " Data: " << RsUtil::BinToHex((char*)data,pkt_size).substr(0,300) << std::endl; - std::cerr << std::endl; -#endif - return NULL; - } - - if (pkt_size != *size) - { -#ifdef RSSERIAL_ERROR_DEBUG - std::cerr << "RsSerialiser::deserialise() ERROR: size mismatch!"; - std::cerr << std::endl; - std::cerr << "RsSerialiser::deserialise() pkt_size: " << pkt_size << " vs *size: " << *size; - std::cerr << std::endl; - - uint32_t failedtype = getRsItemId(data); - std::cerr << "RsSerialiser::deserialise() FAILED PACKET Size: "; - std::cerr << getRsItemSize(data) << " ID: "; - std::cerr << std::hex << failedtype << std::dec; - std::cerr << "RsSerialiser::deserialise() FAILED PACKET: "; - std::cerr << " Version: " << std::hex << (uint32_t) getRsItemVersion(failedtype) << std::dec; - std::cerr << " Class: " << std::hex << (uint32_t) getRsItemClass(failedtype) << std::dec; - std::cerr << " Type: " << std::hex << (uint32_t) getRsItemType(failedtype) << std::dec; - std::cerr << " SubType: " << std::hex << (uint32_t) getRsItemSubType(failedtype) << std::dec; - std::cerr << " Data: " << RsUtil::BinToHex((char*)data,pkt_size).substr(0,300) << std::endl; - std::cerr << std::endl; -#endif - } - return item; -} - - -bool setRsItemHeader(void *data, uint32_t size, uint32_t type, uint32_t pktsize) -{ - if (size < 8) - return false; - - uint32_t offset = 0; - bool ok = true; - ok &= setRawUInt32(data, 8, &offset, type); - ok &= setRawUInt32(data, 8, &offset, pktsize); - - return ok; -} - - - -uint32_t getRsItemId(void *data) -{ - uint32_t type = 0; - uint32_t offset = 0; - getRawUInt32(data, 4, &offset, &type); - return type; -} - - -uint32_t getRsItemSize(void *data) -{ - uint32_t size = 0; - uint32_t offset = 4; - getRawUInt32(data, 8, &offset, &size); - return size; -} - -uint8_t getRsItemVersion(uint32_t type) -{ - return (type >> 24); -} - -uint8_t getRsItemClass(uint32_t type) -{ - return (type >> 16) & 0xFF; -} - -uint8_t getRsItemType(uint32_t type) -{ - return (type >> 8) & 0xFF; -} - -uint8_t getRsItemSubType(uint32_t type) -{ - return (type & 0xFF); -} - -uint16_t getRsItemService(uint32_t type) -{ - return (type >> 8) & 0xFFFF; -} - - -std::ostream &printRsItemBase(std::ostream &out, std::string clsName, uint16_t indent) -{ - printIndent(out, indent); - out << "RsItem: " << clsName << " ####################################"; - out << std::endl; - return out; -} - -std::ostream &printRsItemEnd(std::ostream &out, std::string clsName, uint16_t indent) -{ - printIndent(out, indent); - out << "###################### " << clsName << " #####################"; - out << std::endl; - return out; -} - -std::ostream &RsRawItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsRawItem", indent); - printIndent(out, indent); - out << "Size: " << len << std::endl; - printRsItemEnd(out, "RsRawItem", indent); - return out; -} - -uint32_t getRsPktMaxSize() { return RsSerialiser::MAX_SERIAL_SIZE; } - -uint32_t getRsPktBaseSize() -{ - return 8; /* 4 + 4 */ -} - diff --git a/libretroshare/src/serialiser/rsserial.h b/libretroshare/src/serialiser/rsserial.h deleted file mode 100644 index 168db8d75..000000000 --- a/libretroshare/src/serialiser/rsserial.h +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsserial.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "util/rsdeprecate.h" - -/******************************************************************* - * This is the Top-Level serialiser/deserialise, - * - * Data is Serialised into the following format - * - * ----------------------------------------- - * | TYPE (4 bytes) | Size (4 bytes) | - * ----------------------------------------- - * | | - * | Data .... | - * | | - * ----------------------------------------- - * - * Size is the total size of the packet (including the 8 byte header) - * Type is composed of: - * - * 8 bits: Version (0x01) - * 8 bits: Class - * 8 bits: Type - * 8 bits: SubType - ******************************************************************/ - -const uint8_t RS_PKT_VERSION1 = 0x01; -const uint8_t RS_PKT_VERSION_SERVICE = 0x02; - -const uint8_t RS_PKT_CLASS_BASE = 0x01; -const uint8_t RS_PKT_CLASS_CONFIG = 0x02; - -const uint8_t RS_PKT_SUBTYPE_DEFAULT = 0x01; /* if only one subtype */ - -struct RsItem; -class RsSerialType ; - - -class RsSerialiser -{ -public: - /** Remember that every pqistreamer allocates an input buffer of this size! - * So don't make it too big! */ - static constexpr uint32_t MAX_SERIAL_SIZE = 262143; /* 2^18 -1 */ - - RsSerialiser(); - ~RsSerialiser(); - bool addSerialType(RsSerialType *type); - - uint32_t size(RsItem *); - bool serialise (RsItem *item, void *data, uint32_t *size); - RsItem * deserialise(void *data, uint32_t *size); - - -private: - std::map serialisers; -}; - -bool setRsItemHeader(void *data, uint32_t size, uint32_t type, uint32_t pktsize); - -/* Extract Header Information from Packet */ -uint32_t getRsItemId(void *data); -uint32_t getRsItemSize(void *data); - -uint8_t getRsItemVersion(uint32_t type); -uint8_t getRsItemClass(uint32_t type); -uint8_t getRsItemType(uint32_t type); -uint8_t getRsItemSubType(uint32_t type); - -uint16_t getRsItemService(uint32_t type); - -/* size constants */ -uint32_t getRsPktBaseSize(); - -RS_DEPRECATED_FOR(RsSerialiser::MAX_SERIAL_SIZE) -uint32_t getRsPktMaxSize(); - - - -/* helper fns for printing */ -std::ostream &printRsItemBase(std::ostream &o, std::string n, uint16_t i); -std::ostream &printRsItemEnd(std::ostream &o, std::string n, uint16_t i); - -/* defined in rstlvtypes.cc - redeclared here for ease */ -std::ostream &printIndent(std::ostream &out, uint16_t indent); -/* Wrapper class for data that is serialised somewhere else */ diff --git a/libretroshare/src/serialiser/rsserializable.cc b/libretroshare/src/serialiser/rsserializable.cc deleted file mode 100644 index a5a329e6d..000000000 --- a/libretroshare/src/serialiser/rsserializable.cc +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * libretroshare: retroshare core library * - * * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "serialiser/rsserializable.h" - -#include - -std::ostream& operator<<(std::ostream& out, const RsSerializable& serializable) -{ - RsGenericSerializer::SerializeContext ctx; - const_cast(serializable) // safe with TO_JSON - .serial_process(RsGenericSerializer::TO_JSON, ctx); - return out << ctx.mJson; -} diff --git a/libretroshare/src/serialiser/rsserializable.h b/libretroshare/src/serialiser/rsserializable.h deleted file mode 100644 index 5e115e673..000000000 --- a/libretroshare/src/serialiser/rsserializable.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsserializable.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "serialiser/rsserializer.h" - -#include - - -/** @brief Minimal ancestor for all serializable structs in RetroShare. - * If you want your struct to be easly serializable you should inherit from this - * struct. - */ -struct RsSerializable -{ - /** Process struct members to serialize in this method taking advantage of - * the helper macro @see RS_SERIAL_PROCESS(I) - */ - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) = 0; - - virtual ~RsSerializable() = default; -}; - -/** @def RS_SERIAL_PROCESS(I) - * Use this macro to process the members of `YourSerializable` for serial - * processing inside `YourSerializable::serial_process(j, ctx)` - * - * Pay special attention for member of enum type which must be declared - * specifying the underlying type otherwise the serialization format may differ - * in an uncompatible way depending on the compiler/platform. - * - * Inspired by http://stackoverflow.com/a/39345864 - */ -#define RS_SERIAL_PROCESS(I) do { \ - RsTypeSerializer::serial_process(j, ctx, I, #I ); \ - } while(0) - -std::ostream &operator<<(std::ostream& out, const RsSerializable& serializable); diff --git a/libretroshare/src/serialiser/rsserializer.cc b/libretroshare/src/serialiser/rsserializer.cc deleted file mode 100644 index 1a029ee2e..000000000 --- a/libretroshare/src/serialiser/rsserializer.cc +++ /dev/null @@ -1,289 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsserializer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016 Cyril Soler * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - ******************************************************************************/ - -#include - -#include "rsitems/rsitem.h" -#include "util/rsprint.h" -#include "serialiser/rsserializer.h" -#include "serialiser/rstypeserializer.h" -#include "util/stacktrace.h" -#include "util/rsdebug.h" - -RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size) -{ - if(!data || !size || *size < 8) - { - RsErr() << __PRETTY_FUNCTION__ << " Called with inconsistent parameters data: " << std::endl; - if(data) - RsErr() << "Data is: " << RsUtil::BinToHex(static_cast(data),std::min(50u,*size)) << ((*size>50)?"...":"") << std::endl; - else - RsErr() << "Null Data" << std::endl; - - RsErr() << " size: " << static_cast(size) << " *size: " << (size ? *size : 0) << std::endl - << " this should never happen!" - << std::endl; - print_stacktrace(); - return nullptr; - } - - if(!!(mFlags & RsSerializationFlags::SKIP_HEADER)) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot deserialise item with flag " - << "SKIP_HEADER. Check your code!" << std::endl; - print_stacktrace(); - return nullptr; - } - - uint32_t rstype = getRsItemId(const_cast((const void*)data)) ; - - RsItem *item = create_item(getRsItemService(rstype),getRsItemSubType(rstype)) ; - - if(!item) - { - std::cerr << "(EE) " << typeid(*this).name() << ": cannot deserialise unknown item subtype " << std::hex << (int)getRsItemSubType(rstype) << std::dec << std::endl; - std::cerr << "(EE) Data is: " << RsUtil::BinToHex(static_cast(data),std::min(50u,*size)) << ((*size>50)?"...":"") << std::endl; - return NULL ; - } - - SerializeContext ctx( - const_cast(static_cast(data)), *size, - mFlags ); - ctx.mOffset = 8 ; - - item->serial_process(RsGenericSerializer::DESERIALIZE, ctx) ; - - if(ctx.mSize < ctx.mOffset) - { - std::cerr << "RsSerializer::deserialise(): ERROR. offset does not match expected size!" << std::endl; - delete item ; - return NULL ; - } - *size = ctx.mOffset ; - - if(ctx.mOk) - return item ; - - delete item ; - return NULL ; -} -RsItem *RsConfigSerializer::deserialise(void *data, uint32_t *size) -{ - if(!!(mFlags & RsSerializationFlags::SKIP_HEADER)) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot deserialise item with flag " - << "SKIP_HEADER. Check your code!" << std::endl; - print_stacktrace(); - return nullptr; - } - - uint32_t rstype = getRsItemId(const_cast((const void*)data)) ; - - RsItem *item = create_item(getRsItemType(rstype),getRsItemSubType(rstype)) ; - - if(!item) - { - std::cerr << "(EE) " << typeid(*this).name() << ": cannot deserialise unknown item subtype " << std::hex << (int)getRsItemSubType(rstype) << std::dec << std::endl; - std::cerr << "(EE) Data is: " << RsUtil::BinToHex(static_cast(data),std::min(50u,*size)) << ((*size>50)?"...":"") << std::endl; - return NULL ; - } - - SerializeContext ctx( - const_cast(static_cast(data)), *size, - mFlags ); - ctx.mOffset = 8 ; - - item->serial_process(DESERIALIZE, ctx) ; - - if(ctx.mSize < ctx.mOffset) - { - std::cerr << "RsSerializer::deserialise(): ERROR. offset does not match expected size!" << std::endl; - delete item ; - return NULL ; - } - *size = ctx.mOffset ; - - if(ctx.mOk) - return item ; - - delete item ; - return NULL ; -} - -bool RsGenericSerializer::serialise(RsItem* item, void* data, uint32_t* size) -{ - uint32_t tlvsize = this->size(item); - - constexpr auto fName = __PRETTY_FUNCTION__; - const auto failure = [=](std::error_condition ec) - { - RsErr() << fName << " " << ec << std::endl; - print_stacktrace(); - return false; - }; - - if(tlvsize > *size) return failure(std::errc::no_buffer_space); - - SerializeContext ctx(static_cast(data), tlvsize, mFlags); - - if(!(mFlags & RsSerializationFlags::SKIP_HEADER)) - { - if(!setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize)) - return failure(std::errc::no_buffer_space); - ctx.mOffset = 8; - } - - item->serial_process(RsGenericSerializer::SERIALIZE,ctx); - - if(ctx.mSize != ctx.mOffset) return failure(std::errc::message_size); - - *size = ctx.mOffset; - return true; -} - -uint32_t RsGenericSerializer::size(RsItem *item) -{ - SerializeContext ctx(nullptr, 0, mFlags); - - if(!!(mFlags & RsSerializationFlags::SKIP_HEADER)) ctx.mOffset = 0; - else ctx.mOffset = 8; // header size - item->serial_process(SIZE_ESTIMATE, ctx) ; - - return ctx.mOffset ; -} - -void RsGenericSerializer::print(RsItem *item) -{ - SerializeContext ctx(nullptr, 0, mFlags); - - std::cerr << "***** RsItem class: \"" << typeid(*item).name() << "\" *****" << std::endl; - item->serial_process(PRINT, ctx) ; - std::cerr << "******************************" << std::endl; -} - -uint32_t RsRawSerialiser::size(RsItem *i) -{ - RsRawItem *item = dynamic_cast(i); - - if (item) - { - return item->getRawLength(); - } - return 0; -} - -/* serialise the data to the buffer */ -bool RsRawSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) -{ - RsRawItem *item = dynamic_cast(i); - if (!item) - { - return false; - } - - #ifdef RSSERIAL_DEBUG - std::cerr << "RsRawSerialiser::serialise() serializing raw item. pktsize : " << *pktsize; - #endif - - uint32_t tlvsize = item->getRawLength(); - #ifdef RSSERIAL_DEBUG - std::cerr << "tlvsize : " << tlvsize << std::endl; - #endif - - if (*pktsize < tlvsize) - return false; /* not enough space */ - - if (tlvsize > getRsPktMaxSize()) - { - std::cerr << "(EE) Serialised packet is too big. Maximum allowed size is " << getRsPktMaxSize() << ". Serialised size is " << tlvsize << ". Please tune your service to correctly split packets" << std::endl; - return false; /* packet too big */ - } - - *pktsize = tlvsize; - - /* its serialised already!!! */ - memcpy(data, item->getRawData(), tlvsize); - - return true; -} - -RsItem *RsRawSerialiser::deserialise(void *data, uint32_t *pktsize) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t rssize = getRsItemSize(data); - - if (RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) - { - return NULL; /* wrong type */ - } - - if (*pktsize < rssize) /* check size */ - return NULL; /* not enough data */ - - if (rssize > getRsPktMaxSize()) - return NULL; /* packet too big */ - - /* set the packet length */ - *pktsize = rssize; - - RsRawItem *item = new RsRawItem(rstype, rssize); - void *item_data = item->getRawData(); - - memcpy(item_data, data, rssize); - - return item; -} - - -RsGenericSerializer::SerializeContext::SerializeContext( - uint8_t* data, uint32_t size, RsSerializationFlags flags, - RsJson::AllocatorType* allocator ) : - mData(data), mSize(size), mOffset(0), mOk(true), mFlags(flags), - mJson(rapidjson::kObjectType, allocator) -{ - if(data) - { - if(size == 0) - { - RsFatal() << __PRETTY_FUNCTION__ << " data passed without " - << "size! This make no sense report to developers!" - << std::endl; - print_stacktrace(); - exit(-EINVAL); - } - - if(!!(flags & RsSerializationFlags::YIELDING)) - { - RsFatal() << __PRETTY_FUNCTION__ - << " Attempt to create a " - << "binary serialization context with " - << "SERIALIZATION_FLAG_YIELDING! " - << "This make no sense report to developers!" - << std::endl; - print_stacktrace(); - exit(-EINVAL); - } - } -} diff --git a/libretroshare/src/serialiser/rsserializer.h b/libretroshare/src/serialiser/rsserializer.h deleted file mode 100644 index 1b67e2675..000000000 --- a/libretroshare/src/serialiser/rsserializer.h +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rsserializer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016 Cyril Soler * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Retroshare Serialization code // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Classes -// ======= -// -// RsSerialiser ----------------+ std::map -// -// RsSerialType -// | -// +----------- RsRawSerializer -// | -// +----------- RsGenericSerializer -// | -// +----------- RsConfigSerializer -// | | -// | +----------- Specific config serializers -// | +----------- ... -// | -// +----------- RsServiceSerializer -// | -// +----------- Specific service serializers -// +----------- ... -// +----------- ... -// -// -// Steps to derive a serializer for a new service: -// ============================================== -// -// 1 - create a serializer class, and overload create_item() to create a new item of your own service for each item type constant: -// -// class MyServiceSerializer: public RsServiceSerializer -// { -// MyServiceSerializer() : RsServiceSerializer(MY_SERVICE_IDENTIFIER) {} -// -// RsItem *create_item(uint16_t service,uint8_t item_subtype) const // mind the "const"! -// { -// if(service != MY_SERVICE_IDENTIFIER) return NULL ; -// -// switch(item_subtype) -// { -// case MY_ITEM_SUBTYPE_01: return new MyServiceItem(); -// default: -// return NULL ; -// } -// } -// } -// -// 2 - create your own items, and overload serial_process in order to define the serialized structure: -// -// class MyServiceItem: public RsItem -// { -// virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -// { -// RsTypeSerializer::serial_process (j,ctx,count,"count") ; // uint32_t is not really needed here, except for explicitly avoiding int types convertion -// RsTypeSerializer::serial_process (j,ctx,update_times,"update_times") ; // will serialize the map and its content -// RsTypeSerializer::serial_process(j,ctx,key,"key") ; // note the explicit call to TlvItem -// RsTypeSerializer::serial_process (j,ctx,dh_key,"dh_key") ; // template will automatically require serialise/deserialise/size/print_data for your type -// } -// -// private: -// uint32_t count ; // example of an int type. All int sizes are supported -// std::map update_times ; // example of a std::map. All std containers are supported. -// RsTlvSecurityKey key ; // example of a TlvItem class. -// BIGNUM *dh_key; // example of a class that needs its own serializer (see below) -// }; -// -// Some types may not be already handled by RsTypeSerializer, so in this case, you need to specialise the template for your own type. But this is quite unlikely to -// happen. In most cases, for instance in your structure types, serialization is directly done by calling RsTypeSerializer::serial_process() on each member of the type. -// In case you really need a specific serialization for soe particular type, here is how to do it, with the example of BIGNUM* (a crypto primitive): -// -// template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM * const & member) -// { -// uint32_t s = BN_num_bytes(member) ; -// -// if(size < offset + 4 + s) -// return false ; -// -// bool ok = true ; -// ok &= setRawUInt32(data, size, &offset, s); -// -// BN_bn2bin(member,&((unsigned char *)data)[offset]) ; -// offset += s ; -// -// return ok; -// } -// template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, BIGNUM *& member) -// { -// uint32_t s=0 ; -// bool ok = true ; -// ok &= getRawUInt32(data, size, &offset, &s); -// -// if(s > size || size - s < offset) -// return false ; -// -// member = BN_bin2bn(&((unsigned char *)data)[offset],s,NULL) ; -// offset += s ; -// -// return ok; -// } -// template<> uint32_t RsTypeSerializer::serial_size(BIGNUM * const & member) -// { -// return 4 + BN_num_bytes(member) ; -// } -// template<> void RsTypeSerializer::print_data(const std::string& name,BIGNUM * const & /* member */) -// { -// std::cerr << "[BIGNUM] : " << name << std::endl; -// } -// -// 3 - in your service, overload the serialiser declaration to add your own: -// -// MyService::MyService() -// { -// addSerialType(new MyServiceSerializer()) ; -// } -// -// If needed, you may serialize your own items by calling: -// -// uint32_t size = MySerializer().size(item) ; -// uint8_t *data = (uint8_t*)malloc(size); -// MySerializer().serialise(item,data,size) ; -// -// 4 - in your service, receive and send items by calling recvItem() and sendItem() respectively. -// -#include -#include -#include -#include - -#include "retroshare/rsflags.h" -#include "serialiser/rsserial.h" -#include "util/rsdeprecate.h" -#include "util/rsjson.h" - -struct RsItem; - -// This is the base class for serializers. - -class RsSerialType -{ -public: - RsSerialType(uint32_t t); /* only uses top 24bits */ - RsSerialType(uint8_t ver, uint8_t cls, uint8_t t); - RsSerialType(uint8_t ver, uint16_t service); - - virtual ~RsSerialType(); - - virtual uint32_t size(RsItem *)=0; - virtual bool serialise (RsItem *item, void *data, uint32_t *size)=0; - virtual RsItem * deserialise(void *data, uint32_t *size)=0; - - uint32_t PacketId() const; -private: - uint32_t type; -}; - -// This class is only used internally to p3service. It should not be used explicitely otherwise. - -class RsRawSerialiser: public RsSerialType -{ - public: - RsRawSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, 0, 0) {} - virtual ~RsRawSerialiser() { } - - virtual uint32_t size(RsItem *); - virtual bool serialise (RsItem *item, void *data, uint32_t *size); - virtual RsItem * deserialise(void *data, uint32_t *size); -}; - -/** These are convenience flags to be used by the items when processing the - * data. The names of the flags are not very important. What matters is that - * the serial_process() method of each item correctly deals with the data - * when it sees the flags, if the serialiser sets them. - * By default the flags are not set and shouldn't be handled. - * When deriving a new serializer, the user can set his own flags, using - * compatible values - */ -enum class RsSerializationFlags -{ - NONE = 0, - CONFIG = 1, - SIGNATURE = 2, - SKIP_HEADER = 4, - - /** Used for JSON deserialization in JSON API, it causes the deserialization - * to continue even if some field is missing (or incorrect), this way the - * API is more user friendly as some methods need just part of the structs - * they take as parameters. */ - YIELDING = 8, - - /** When set integers typer are serialized/deserialized in Variable Length - * Quantity mode - * @see https://en.wikipedia.org/wiki/Variable-length_quantity - * This type of encoding is efficent when absoulte value is usually much - * smaller then the maximum representable with the original type. - * This encoding is also capable of representing big values at expences of a - * one more byte used. - */ - INTEGER_VLQ = 16 -}; -RS_REGISTER_ENUM_FLAGS_TYPE(RsSerializationFlags); - -/// Top class for all services and config serializers. -struct RsGenericSerializer : RsSerialType -{ - typedef enum - { - SIZE_ESTIMATE = 0x01, - SERIALIZE = 0x02, - DESERIALIZE = 0x03, - PRINT = 0x04, /// @deprecated use rsdebug.h << operator instead - TO_JSON, - FROM_JSON - } SerializeJob; - - struct SerializeContext - { - /** Allow shared allocator usage to avoid costly JSON deepcopy for - * nested RsSerializable */ - SerializeContext( - uint8_t* data = nullptr, uint32_t size = 0, - RsSerializationFlags flags = RsSerializationFlags::NONE, - RsJson::AllocatorType* allocator = nullptr); - - unsigned char *mData; - uint32_t mSize; - uint32_t mOffset; - bool mOk; - RsSerializationFlags mFlags; - RsJson mJson; - }; - - /** - * The following functions overload RsSerialType. - * They *should not* need to be further overloaded. - */ - RsItem *deserialise(void *data,uint32_t *size) = 0; - bool serialise(RsItem *item,void *data,uint32_t *size); - uint32_t size(RsItem *item); - void print(RsItem *item); - -protected: - RsGenericSerializer( - uint8_t serial_class, uint8_t serial_type, - RsSerializationFlags flags ): - RsSerialType( RS_PKT_VERSION1, serial_class, serial_type), - mFlags(flags) {} - - RsGenericSerializer( - uint16_t service, RsSerializationFlags flags ): - RsSerialType( RS_PKT_VERSION_SERVICE, service ), mFlags(flags) {} - - RsSerializationFlags mFlags; -}; - - -/** Top class for service serializers. - * Derive your on service serializer from this class and overload creat_item(). - */ -struct RsServiceSerializer : RsGenericSerializer -{ - RsServiceSerializer( - uint16_t service_id, - RsSerializationFlags flags = RsSerializationFlags::NONE ) : - RsGenericSerializer(service_id, flags) {} - - /*! should be overloaded to create the correct type of item depending on the - * data */ - virtual RsItem *create_item( uint16_t /* service */, - uint8_t /* item_sub_id */ ) const = 0; - - RsItem *deserialise(void *data, uint32_t *size); -}; - - -/** Top class for config serializers. - * Config serializers are only used internally by RS core. - * The development of new services or plugins do not need this. - */ -struct RsConfigSerializer : RsGenericSerializer -{ - RsConfigSerializer( - uint8_t config_class, uint8_t config_type, - RsSerializationFlags flags = RsSerializationFlags::NONE ) : - RsGenericSerializer(config_class, config_type, flags) {} - - /*! should be overloaded to create the correct type of item depending on the - * data */ - virtual RsItem *create_item(uint8_t /* item_type */, - uint8_t /* item_sub_type */) const = 0; - - RsItem *deserialise(void *data,uint32_t *size); -}; - diff --git a/libretroshare/src/serialiser/rstlvaddrs.cc b/libretroshare/src/serialiser/rstlvaddrs.cc deleted file mode 100644 index 5f9a06390..000000000 --- a/libretroshare/src/serialiser/rstlvaddrs.cc +++ /dev/null @@ -1,434 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvaddr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvaddrs.h" -#include "serialiser/rsbaseserial.h" - -/************************************* RsTlvIpAddress ************************************/ - -RsTlvIpAddress::RsTlvIpAddress() - :RsTlvItem() -{ - sockaddr_storage_clear(addr); - return; -} - -void RsTlvIpAddress::TlvClear() -{ - sockaddr_storage_clear(addr); -} - -uint32_t RsTlvIpAddress::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; - switch(addr.ss_family) - { - default: - case 0: - break; - case AF_INET: - s += GetTlvIpAddrPortV4Size(); - break; - case AF_INET6: - s += GetTlvIpAddrPortV6Size(); - break; - } - return s; -} - -bool RsTlvIpAddress::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_ADDRESS, tlvsize); - - switch(addr.ss_family) - { - default: - case 0: - break; - case AF_INET: - ok &= SetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4, (struct sockaddr_in *) &addr); - break; - - case AF_INET6: - ok &= SetTlvIpAddrPortV6(data, tlvend, offset, TLV_TYPE_IPV6, (struct sockaddr_in6 *) &addr); - break; - } - return ok; - -} - - -bool RsTlvIpAddress::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_ADDRESS) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - if (*offset == tlvend) - { - /* empty address */ - return ok; - } - - uint16_t iptype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - switch(iptype) - { - case TLV_TYPE_IPV4: - ok &= GetTlvIpAddrPortV4(data, tlvend, offset, TLV_TYPE_IPV4, (struct sockaddr_in *) &addr); - break; - case TLV_TYPE_IPV6: - ok &= GetTlvIpAddrPortV6(data, tlvend, offset, TLV_TYPE_IPV6, (struct sockaddr_in6 *) &addr); - break; - default: - break; - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvIpAddress::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvIpAddress::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvIpAddress", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "Address:" << sockaddr_storage_tostring(addr) << std::endl; - - printEnd(out, "RsTlvIpAddress", indent); - return out; -} - - - - -/************************************* RsTlvIpAddressInfo ************************************/ - -RsTlvIpAddressInfo::RsTlvIpAddressInfo() - :RsTlvItem(), seenTime(0), source(0) -{ - addr.TlvClear(); - return; -} - -void RsTlvIpAddressInfo::TlvClear() -{ - addr.TlvClear(); - seenTime = 0; - source = 0; -} - -uint32_t RsTlvIpAddressInfo::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + IpAddr + 8 for time & 4 for size */ - - s += addr.TlvSize(); - s += 8; // seenTime - s += 4; // source - - return s; - -} - -bool RsTlvIpAddressInfo::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_ADDRESS_INFO, tlvsize); - - ok &= addr.SetTlv(data, tlvend, offset); - ok &= setRawUInt64(data, tlvend, offset, seenTime); - ok &= setRawUInt32(data, tlvend, offset, source); - - return ok; - -} - - -bool RsTlvIpAddressInfo::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_ADDRESS_INFO) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= addr.GetTlv(data, tlvend, offset); - ok &= getRawUInt64(data, tlvend, offset, &(seenTime)); - ok &= getRawUInt32(data, tlvend, offset, &(source)); - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvIpAddressInfo::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvIpAddressInfo::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvIpAddressInfo", indent); - uint16_t int_Indent = indent + 2; - - addr.print(out, int_Indent); - - printIndent(out, int_Indent); - out << "SeenTime:" << seenTime; - out << std::endl; - - printIndent(out, int_Indent); - out << "Source:" << source; - out << std::endl; - - printEnd(out, "RsTlvIpAddressInfo", indent); - return out; -} - - - -#if 0 -/************************************* RsTlvIpAddrSet ************************************/ - -void RsTlvIpAddrSet::TlvClear() -{ - addrs.clear(); -} - -uint32_t RsTlvIpAddrSet::TlvSize() const -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - std::list::iterator it; - - - if(!addrs.empty()) - { - - for(it = addrs.begin(); it != addrs.end() ; ++it) - s += it->TlvSize(); - - } - - return s; -} - -bool RsTlvIpAddrSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_ADDRESS_SET , tlvsize); - - if(!addrs.empty()) - { - std::list::iterator it; - - for(it = addrs.begin(); it != addrs.end() ; ++it) - ok &= it->SetTlv(data, size, offset); - } - - -return ok; - -} - - -bool RsTlvIpAddrSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_ADDRESS_SET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - switch(tlvsubtype) - { - case TLV_TYPE_ADDRESS_INFO: - { - RsTlvIpAddressInfo addr; - ok &= addr.GetTlv(data, size, offset); - if (ok) - { - addrs.push_back(addr); - } - } - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - - } - - if (!ok) - break; - } - - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvIpAddrSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -// prints out contents of RsTlvIpAddrSet -std::ostream &RsTlvIpAddrSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvIpAddrSet", indent); - uint16_t int_Indent = indent + 2; - - std::list::iterator it; - for(it = addrs.begin(); it != addrs.end() ; ++it) - it->print(out, int_Indent); - - printEnd(out, "RsTlvIpAddrSet", indent); - return out; -} - - -/************************************* RsTlvIpAddressInfo ************************************/ - -#endif diff --git a/libretroshare/src/serialiser/rstlvaddrs.h b/libretroshare/src/serialiser/rstlvaddrs.h deleted file mode 100644 index 07b668559..000000000 --- a/libretroshare/src/serialiser/rstlvaddrs.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvaddr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "util/rsnet.h" -#include - -#include "serialiser/rstlvlist.h" - -class RsTlvIpAddress: public RsTlvItem -{ - public: - RsTlvIpAddress(); -virtual ~RsTlvIpAddress() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - struct sockaddr_storage addr; // Mandatory : -}; - - -class RsTlvIpAddressInfo: public RsTlvItem -{ - public: - RsTlvIpAddressInfo(); -virtual ~RsTlvIpAddressInfo() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - RsTlvIpAddress addr; // Mandatory : - uint64_t seenTime; // Mandatory : - uint32_t source; // Mandatory : -}; - -typedef t_RsTlvList RsTlvIpAddrSet; - -#if 0 -class RsTlvIpAddrSet: public RsTlvItem -{ - public: - RsTlvIpAddrSet() { return; } -virtual ~RsTlvIpAddrSet() { return; } -virtual uint32_t TlvSize(); -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ -virtual std::ostream &print(std::ostream &out, uint16_t indent); - - std::list addrs; // Mandatory : -}; -#endif - - diff --git a/libretroshare/src/serialiser/rstlvbanlist.cc b/libretroshare/src/serialiser/rstlvbanlist.cc deleted file mode 100644 index 92bd3a6d2..000000000 --- a/libretroshare/src/serialiser/rstlvbanlist.cc +++ /dev/null @@ -1,172 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbanlist.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvbanlist.h" -#include "serialiser/rstlvbase.h" - -#include "serialiser/rsbaseserial.h" - - -/************************************* RsTlvBanListEntry ************************************/ - -RsTlvBanListEntry::RsTlvBanListEntry() - :RsTlvItem(), level(0), reason(0), age(0) -{ - return; -} - -void RsTlvBanListEntry::TlvClear() -{ - addr.TlvClear(); - level = 0; - reason = 0; - age = 0; - comment.clear(); - masked_bytes = 0; -} - -uint32_t RsTlvBanListEntry::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; - - s += addr.TlvSize(); - s += 4; // level; - s += 4; // reason; - s += 4; // age; - s += 1; // masked_bytes; - s += GetTlvStringSize(comment) ; - - return s; - -} - -bool RsTlvBanListEntry::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_BAN_ENTRY, tlvsize); - - ok &= addr.SetTlv(data, tlvend, offset); - ok &= setRawUInt32(data, tlvend, offset, level); - ok &= setRawUInt32(data, tlvend, offset, reason); - ok &= setRawUInt32(data, tlvend, offset, age); - ok &= setRawUInt8(data, tlvend, offset, masked_bytes); - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_COMMENT, comment); - - return ok; - -} - - -bool RsTlvBanListEntry::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_BAN_ENTRY) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= addr.GetTlv(data, tlvend, offset); - ok &= getRawUInt32(data, tlvend, offset, &(level)); - ok &= getRawUInt32(data, tlvend, offset, &(reason)); - ok &= getRawUInt32(data, tlvend, offset, &(age)); - - uint8_t tmp ; - ok &= getRawUInt8(data, tlvend, offset, &(tmp)); - masked_bytes = tmp ; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_COMMENT, comment); - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvBanListEntry::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvBanListEntry::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvBanListEntry", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "addr:" << std::endl; - addr.print(out, int_Indent); - - printIndent(out, int_Indent); - out << "level:" << level; - out << std::endl; - - printIndent(out, int_Indent); - out << "reason:" << reason; - out << std::endl; - - printIndent(out, int_Indent); - out << "age:" << age; - out << std::endl; - - printIndent(out, int_Indent); - out << "masked bytes:" << masked_bytes; - out << std::endl; - - printEnd(out, "RsTlvBanListEntry", indent); - return out; -} - - - diff --git a/libretroshare/src/serialiser/rstlvbanlist.h b/libretroshare/src/serialiser/rstlvbanlist.h deleted file mode 100644 index a08f92a7a..000000000 --- a/libretroshare/src/serialiser/rstlvbanlist.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbanlist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvaddrs.h" -#include "serialiser/rstlvlist.h" -#include "serialiser/rstlvbase.h" - -#define RSDSDV_MAX_ROUTE_TABLE 1000 - -class RsTlvBanListEntry: public RsTlvItem -{ - public: - RsTlvBanListEntry(); -virtual ~RsTlvBanListEntry() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - RsTlvIpAddress addr; - uint32_t level; - uint32_t reason; - uint32_t age; - uint8_t masked_bytes ; - std::string comment ; -}; - -typedef t_RsTlvList RsTlvBanList; - - - diff --git a/libretroshare/src/serialiser/rstlvbase.cc b/libretroshare/src/serialiser/rstlvbase.cc deleted file mode 100644 index 9cf713193..000000000 --- a/libretroshare/src/serialiser/rstlvbase.cc +++ /dev/null @@ -1,1007 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbase.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie, Horatio, Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" - -//********************* - -// A facility func -inline void* right_shift_void_pointer(const void* p, uint32_t len) { - - return (void*)( (uint8_t*)p + len); -} -//********************* - -//#define TLV_BASE_DEBUG 1 - -/**** Basic TLV Functions ****/ -uint32_t GetTlvSize(void *data) { - if (!data) - return 0; - - uint32_t len; - - void * from =right_shift_void_pointer(data, TLV_HEADER_TYPE_SIZE); - - memcpy((void *)&len, from , TLV_HEADER_LEN_SIZE); - - len = ntohl(len); - - return len; -} - -uint16_t GetTlvType(void *data) { - if (!data) - return 0; - - uint16_t type; - - memcpy((void*)&type, data, TLV_HEADER_TYPE_SIZE); - - type = ntohs(type); - - return type; - -} - -//tested -bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, - uint32_t len) { - if (!data) - return false; - if (!offset) - return false; - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t type_n = htons(type); - - //copy type_n to (data+*offset) - void* to = right_shift_void_pointer(data, *offset); - memcpy(to , (void*)&type_n, TLV_HEADER_TYPE_SIZE); - - uint32_t len_n =htonl(len); - //copy len_n to (data + *offset +2) - to = right_shift_void_pointer(to, TLV_HEADER_TYPE_SIZE); - memcpy((void *)to, (void*)&len_n, TLV_HEADER_LEN_SIZE); - - *offset += TLV_HEADER_SIZE; - - return true; -} - -bool SetTlvType(void *data, uint32_t size, uint16_t type) -{ - if (!data) - return false; - - if(size < TLV_HEADER_SIZE ) - return false; - - uint16_t type_n = htons(type); - memcpy(data , (void*)&type_n, TLV_HEADER_TYPE_SIZE); - return true; -} - -//tested -bool SetTlvSize(void *data, uint32_t size, uint32_t len) { - if (!data) - return false; - - if(size < TLV_HEADER_SIZE ) - return false; - - uint32_t len_n = htonl(len); - - void * to = (void*)((uint8_t *) data + TLV_HEADER_TYPE_SIZE); - - memcpy(to, (void*) &len_n, TLV_HEADER_LEN_SIZE); - - return true; - -} - -/* Step past unknown TLV TYPE */ -bool SkipUnknownTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - return false; - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - //uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SkipUnknownTlv() FAILED - not enough space." << std::endl; - std::cerr << "SkipUnknownTlv() size: " << size << std::endl; - std::cerr << "SkipUnknownTlv() tlvsize: " << tlvsize << std::endl; - std::cerr << "SkipUnknownTlv() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - /* step past this tlv item */ - *offset = tlvend; - return ok; -} - - -/**** Generic TLV Functions **** - * This have the same data (int or string for example), - * but they can have different types eg. a string could represent a name or a path, - * so we include a type parameter in the arguments - */ -//tested -bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, - uint32_t out) -{ - if (!data) - return false; - uint32_t tlvsize = GetTlvUInt32Size(); /* this will always be 8 bytes */ - uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvUInt32() FAILED - not enough space. (or earlier)" << std::endl; - std::cerr << "SetTlvUInt32() size: " << size << std::endl; - std::cerr << "SetTlvUInt32() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvUInt32() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - - /* Now use the function we got to set the TlvHeader */ - /* function shifts offset to the new start for the next data */ - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt32() SetTlvBase FAILED (or earlier)" << std::endl; - } -#endif - - /* now set the UInt32 ( in rsbaseserial.h???) */ - ok &= setRawUInt32(data, tlvend, offset, out); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt32() setRawUInt32 FAILED (or earlier)" << std::endl; - } -#endif - - - return ok; - -} - -//tested -bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset, - uint16_t type, uint32_t *in) -{ - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - return false; - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt32() FAILED - not enough space." << std::endl; - std::cerr << "GetTlvUInt32() size: " << size << std::endl; - std::cerr << "GetTlvUInt32() tlvsize: " << tlvsize << std::endl; - std::cerr << "GetTlvUInt32() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - if (type != tlvtype) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt32() FAILED - Type mismatch" << std::endl; - std::cerr << "GetTlvUInt32() type: " << type << std::endl; - std::cerr << "GetTlvUInt32() tlvtype: " << tlvtype << std::endl; -#endif - return false; - } - - *offset += TLV_HEADER_SIZE; /* step past header */ - - bool ok = true; - ok &= getRawUInt32(data, tlvend, offset, in); - - return ok; -} - -// UInt16 -bool SetTlvUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t type, - uint16_t out) -{ - if (!data) - return false; - uint32_t tlvsize = GetTlvUInt16Size(); /* this will always be 8 bytes */ - uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvUInt16() FAILED - not enough space. (or earlier)" << std::endl; - std::cerr << "SetTlvUInt16() size: " << size << std::endl; - std::cerr << "SetTlvUInt16() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvUInt16() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - - /* Now use the function we got to set the TlvHeader */ - /* function shifts offset to the new start for the next data */ - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt16() SetTlvBase FAILED (or earlier)" << std::endl; - } -#endif - - /* now set the UInt16 ( in rsbaseserial.h???) */ - ok &= setRawUInt16(data, tlvend, offset, out); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt16() setRawUInt16 FAILED (or earlier)" << std::endl; - } -#endif - - - return ok; - -} - -bool GetTlvUInt16(void *data, uint32_t size, uint32_t *offset, - uint16_t type, uint16_t *in) -{ - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - return false; - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt16() FAILED - not enough space." << std::endl; - std::cerr << "GetTlvUInt16() size: " << size << std::endl; - std::cerr << "GetTlvUInt16() tlvsize: " << tlvsize << std::endl; - std::cerr << "GetTlvUInt16() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - if (type != tlvtype) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt16() FAILED - Type mismatch" << std::endl; - std::cerr << "GetTlvUInt16() type: " << type << std::endl; - std::cerr << "GetTlvUInt16() tlvtype: " << tlvtype << std::endl; -#endif - return false; - } - - *offset += TLV_HEADER_SIZE; /* step past header */ - - bool ok = true; - ok &= getRawUInt16(data, tlvend, offset, in); - - return ok; -} - - -uint32_t GetTlvUInt64Size() { - return TLV_HEADER_SIZE + 8; -} - -uint32_t GetTlvUInt32Size() { - return TLV_HEADER_SIZE + 4; -} - -uint32_t GetTlvUInt16Size() { - return TLV_HEADER_SIZE + sizeof(uint16_t); - -} - -uint32_t GetTlvUInt8Size() { - return TLV_HEADER_SIZE + sizeof(uint8_t); - -} - - -bool SetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type, - uint64_t out) -{ - if (!data) - return false; - uint32_t tlvsize = GetTlvUInt64Size(); - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvUInt64() FAILED - not enough space. (or earlier)" << std::endl; - std::cerr << "SetTlvUInt64() size: " << size << std::endl; - std::cerr << "SetTlvUInt64() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvUInt64() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - - /* Now use the function we got to set the TlvHeader */ - /* function shifts offset to the new start for the next data */ - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt64() SetTlvBase FAILED (or earlier)" << std::endl; - } -#endif - - /* now set the UInt64 ( in rsbaseserial.h???) */ - ok &= setRawUInt64(data, tlvend, offset, out); - -#ifdef TLV_BASE_DEBUG - if (!ok) - { - std::cerr << "SetTlvUInt64() setRawUInt64 FAILED (or earlier)" << std::endl; - } -#endif - - return ok; - -} - -bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset, - uint16_t type, uint64_t *in) -{ - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - return false; - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt64() FAILED - not enough space." << std::endl; - std::cerr << "GetTlvUInt64() size: " << size << std::endl; - std::cerr << "GetTlvUInt64() tlvsize: " << tlvsize << std::endl; - std::cerr << "GetTlvUInt64() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - if (type != tlvtype) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvUInt64() FAILED - Type mismatch" << std::endl; - std::cerr << "GetTlvUInt64() type: " << type << std::endl; - std::cerr << "GetTlvUInt64() tlvtype: " << tlvtype << std::endl; -#endif - return false; - } - - *offset += TLV_HEADER_SIZE; /* step past header */ - - bool ok = true; - ok &= getRawUInt64(data, tlvend, offset, in); - - return ok; -} - - -bool SetTlvString(void *data, uint32_t size, uint32_t *offset, - uint16_t type, std::string out) -{ - if (!data) - return false; - uint32_t tlvsize = GetTlvStringSize(out); - uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ - - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvString() FAILED - not enough space" << std::endl; - std::cerr << "SetTlvString() size: " << size << std::endl; - std::cerr << "SetTlvString() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvString() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - - void * to = right_shift_void_pointer(data, *offset); - - uint32_t strlen = tlvsize - TLV_HEADER_SIZE; - memcpy(to, out.c_str(), strlen); - - *offset += strlen; - - return ok; -} - -static bool readHex(char s1,char s2,uint8_t& v) -{ - v=0 ; - - if(s1 >= 'a' && s1 <= 'f') - v += (s1-'a')+10; - else if(s1 >= 'A' && s1 <= 'F') - v += (s1-'A')+10; - else if(s1 >= '0' && s1 <= '9') - v += s1 - '0' ; - else - return false ; - - v = v << 4; - - if(s2 >= 'a' && s2 <= 'f') - v += (s2-'a')+10; - else if(s2 >= 'A' && s2 <= 'F') - v += (s2-'A')+10; - else if(s2 >= '0' && s2 <= '9') - v += s2 - '0' ; - else - return false ; - - return true ; -} - -static bool find_decoded_string(const std::string& in,const std::string& suspicious_string) -{ - uint32_t ss_pointer = 0 ; - - for(uint32_t i=0;i 0x7f. - // We do this for strings that should not contain some - // special characters by design. - - if( type == 0 // this is used for mGroupName and mMsgName - || type == TLV_TYPE_STR_PEERID - || type == TLV_TYPE_STR_NAME - || type == TLV_TYPE_STR_PATH - || type == TLV_TYPE_STR_TITLE - || type == TLV_TYPE_STR_SUBJECT - || type == TLV_TYPE_STR_LOCATION - || type == TLV_TYPE_STR_VERSION ) - { - bool modified = false ; - for(uint32_t i=0;i 0) - { - modified = true ; - in[i] = 0x20 ; - } - - if(modified) - std::cerr << "(WW) De-serialised string of type " << type << " contains forbidden characters. They have been replaced by spaces. New string: \"" << in << "\"" << std::endl; - } - - *offset += tlvsize; /* step along */ - return true; -} - -uint32_t GetTlvStringSize(const std::string &in) { - return TLV_HEADER_SIZE + in.size(); -} - - -#ifdef REMOVED_CODE -/* We must use a consistent wchar size for cross platform ness. - * As unix uses 4bytes, and windows 2bytes? we'll go with 4bytes for maximum flexibility - */ - -const uint32_t RS_WCHAR_SIZE = 4; - -bool SetTlvWideString(void *data, uint32_t size, uint32_t *offset, - uint16_t type, std::wstring out) -{ - if (!data) - return false; - uint32_t tlvsize = GetTlvWideStringSize(out); - uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ - - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvWideString() FAILED - not enough space" << std::endl; - std::cerr << "SetTlvWideString() size: " << size << std::endl; - std::cerr << "SetTlvWideString() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvWideString() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - - uint32_t strlen = out.length(); - - /* Must convert manually to ensure its always the same! */ - for(uint32_t i = 0; i < strlen; i++) - { - uint32_t widechar = out[i]; - ok &= setRawUInt32(data, tlvend, offset, widechar); - } - return ok; -} - -//tested -bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset, - uint16_t type, std::wstring &in) -{ - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvWideString() FAILED - not enough space" << std::endl; - std::cerr << "GetTlvWideString() size: " << size << std::endl; - std::cerr << "GetTlvWideString() *offset: " << *offset << std::endl; -#endif - return false; - } - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvWideString() FAILED - not enough space" << std::endl; - std::cerr << "GetTlvWideString() size: " << size << std::endl; - std::cerr << "GetTlvWideString() tlvsize: " << tlvsize << std::endl; - std::cerr << "GetTlvWideString() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - if (type != tlvtype) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetTlvWideString() FAILED - invalid type" << std::endl; - std::cerr << "GetTlvWideString() type: " << type << std::endl; - std::cerr << "GetTlvWideString() tlvtype: " << tlvtype << std::endl; -#endif - return false; - } - - - bool ok = true; - /* remove the header, calc string length */ - *offset += TLV_HEADER_SIZE; - uint32_t strlen = (tlvsize - TLV_HEADER_SIZE) / RS_WCHAR_SIZE; - - /* Must convert manually to ensure its always the same! */ - for(uint32_t i = 0; i < strlen; i++) - { - uint32_t widechar; - ok &= getRawUInt32(data, tlvend, offset, &widechar); - in += widechar; - } - - // Check for message content. We want to avoid possible lol bombs as soon as possible. - - static const int number_of_suspiscious_strings = 4 ; - static const std::wstring err_in = L"**** String removed (SVG bomb?) ****" ; - static std::wstring suspiscious_strings[number_of_suspiscious_strings] = { L"sin_family = AF_INET; /* set FAMILY */ - in->sin_addr.s_addr = ipaddr; - - uint16_t port; - ok &= getRawUInt16(data, tlvend, offset, &port); - in->sin_port = port; - - return ok; -} - -uint32_t GetTlvIpAddrPortV4Size() { - return TLV_HEADER_SIZE + 4 + 2; /* header + 4 (IP) + 2 (Port) */ -} - - -bool SetTlvIpAddrPortV6(void *data, uint32_t size, uint32_t *offset, - uint16_t type, struct sockaddr_in6 *out) { - if (!data) - return false; - - uint32_t tlvsize = GetTlvIpAddrPortV6Size(); - uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */ - - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "SetTlvIpAddrPortV6() FAILED - not enough space" << std::endl; - std::cerr << "SetTlvIpAddrPortV6() size: " << size << std::endl; - std::cerr << "SetTlvIpAddrPortV6() tlvsize: " << tlvsize << std::endl; - std::cerr << "SetTlvIpAddrPortV6() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - bool ok = true; - ok &= SetTlvBase(data, tlvend, offset, type, tlvsize); - - /* now add the data (keep in network order) */ - uint32_t *ip6addr = (uint32_t *) out->sin6_addr.s6_addr; - for(int i = 0; i < 4; i++) - { - ok &= setRawUInt32(data, tlvend, offset, ip6addr[i]); - } - ok &= setRawUInt16(data, tlvend, offset, out->sin6_port); - return ok; -} - -bool GetTlvIpAddrPortV6(void *data, uint32_t size, uint32_t *offset, - uint16_t type, struct sockaddr_in6 *in) { - if (!data) - return false; - - if (size < *offset + TLV_HEADER_SIZE) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetIpAddrPortV6() FAILED - not enough space" << std::endl; - std::cerr << "GetIpAddrPortV6() size: " << size << std::endl; - std::cerr << "GetIpAddrPortV6() *offset: " << *offset << std::endl; -#endif - return false; - } - - /* extract the type and size */ - void *tlvstart = right_shift_void_pointer(data, *offset); - uint16_t tlvtype = GetTlvType(tlvstart); - uint32_t tlvsize = GetTlvSize(tlvstart); - - /* check that there is size */ - uint32_t tlvend = *offset + tlvsize; - if (size < tlvend) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetIpAddrPortV6() FAILED - not enough space" << std::endl; - std::cerr << "GetIpAddrPortV6() size: " << size << std::endl; - std::cerr << "GetIpAddrPortV6() tlvsize: " << tlvsize << std::endl; - std::cerr << "GetIpAddrPortV6() tlvend: " << tlvend << std::endl; -#endif - return false; - } - - if (type != tlvtype) - { -#ifdef TLV_BASE_DEBUG - std::cerr << "GetIpAddrPortV6() FAILED - invalid type" << std::endl; - std::cerr << "GetIpAddrPortV6() type: " << type << std::endl; - std::cerr << "GetIpAddrPortV6() tlvtype: " << tlvtype << std::endl; -#endif - return false; - } - - *offset += TLV_HEADER_SIZE; /* skip header */ - - bool ok = true; - - /* now get the data (keep in network order) */ - uint32_t *ip6addr = (uint32_t *) in->sin6_addr.s6_addr; - for(int i = 0; i < 4; i++) - { - ok &= getRawUInt32(data, tlvend, offset, &(ip6addr[i])); - } - - in->sin6_family = AF_INET6; /* set FAMILY */ - ok &= getRawUInt16(data, tlvend, offset, &(in->sin6_port)); - - return ok; -} - -uint32_t GetTlvIpAddrPortV6Size() { - return TLV_HEADER_SIZE + 16 + 2; /* header + 16 (IP) + 2 (Port) */ -} - diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h deleted file mode 100644 index e153f1797..000000000 --- a/libretroshare/src/serialiser/rstlvbase.h +++ /dev/null @@ -1,299 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbase.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie, Horatio, Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the general TLV (un)packing routines. - * - * Data is Serialised into the following format - * - * ----------------------------------------- - * | TLV TYPE (2 bytes) | TLV LEN (4 bytes)| - * ----------------------------------------- - * | | - * | Data .... | - * | | - * ----------------------------------------- - * - * Originally TLV TYPE = 2 bytes, and TLV LEN = 2 bytes. - * However with HTML and WSTRINGS the 64K Limit becomes limiting. - * The TLV LEN = 4 bytes now! - * - * Size is the total size of the TLV Field (including the 4 byte header) - * - * Like the lowlevel packing routines. They are usually - * created in pairs - one to pack the data, the other to unpack. - * - * GetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *out); - * SetTlvXXX(void *data, uint32_t size, uint32_t *offset, XXX *in); - * - * - * data - the base pointer to the serialised data. - * size - size of the memory pointed to by data. - * *offset - where we want to (un)pack the data. - * This is incremented by the datasize. - * - * *in / *out - the data to (un)pack. - * - ******************************************************************/ - -#include -#include -#include "util/rsnet.h" - - -/* 0b 0000 0000 0001 XXXX UInt8 */ -/* 0b 0000 0000 0010 XXXX UInt16 */ -/* 0b 0000 0000 0011 XXXX UInt32 */ -/* 0b 0000 0000 0100 XXXX UInt64 */ -/* 0b 0000 0000 0101 XXXX String */ -/* 0b 0000 0000 0110 XXXX Wide String */ -/* 0b 0000 0000 0111 XXXX Hashes */ -/* 0b 0000 0000 1000 XXXX IP:Port V4 */ - -/******* BINARY TYPES *****************/ -/* 0b 0000 0001 0000 XXXX CERT */ -/* 0b 0000 0001 0001 XXXX Priv Key */ -/* 0b 0000 0001 0010 XXXX Pub Key */ -/* 0b 0000 0001 0011 XXXX Signature */ - -/******* COMPOUND TYPES ***************/ -/* 0b 0001 XXXX XXXX XXXX Compound */ -/* 0b 0001 0000 0000 XXXX FILE */ -/* 0b 0001 0000 0001 XXXX KEY VALUE */ -/* 0b 0001 0000 0010 XXXX PEERS */ -/* 0b 0001 0000 0011 XXXX SERVICES */ - -/******* BIG LEN TYPES ***************/ - -/* 0b 1000 XXXX XXXX XXXX BIG LEN */ -/* 0b 1000 0000 0001 XXXX STRINGS */ -/* 0b 1000 0000 0010 XXXX WSTRINGS */ -/* 0b 1000 0000 0011 XXXX BINARY */ - -/* 0b 1001 XXXX XXXX XXXX Compound */ - - -/* TLV HEADER SIZE (Reference) *******************************/ -const uint32_t TLV_HEADER_TYPE_SIZE = 2; -const uint32_t TLV_HEADER_LEN_SIZE = 4; -const uint32_t TLV_HEADER_SIZE = TLV_HEADER_TYPE_SIZE + TLV_HEADER_LEN_SIZE; -/* TLV HEADER SIZE (Reference) *******************************/ - -const uint16_t TLV_TYPE_UINT32_SIZE = 0x0030; -const uint16_t TLV_TYPE_UINT32_POP = 0x0031; -const uint16_t TLV_TYPE_UINT32_AGE = 0x0032; -const uint16_t TLV_TYPE_UINT32_OFFSET = 0x0033; -const uint16_t TLV_TYPE_UINT32_SERID = 0x0034; -const uint16_t TLV_TYPE_UINT32_BW = 0x0035; -const uint16_t TLV_TYPE_UINT32_PARAM = 0x0030; - -const uint16_t TLV_TYPE_UINT64_SIZE = 0x0040; -const uint16_t TLV_TYPE_UINT64_OFFSET = 0x0041; - -const uint16_t TLV_TYPE_STR_PEERID = 0x0050; -const uint16_t TLV_TYPE_STR_NAME = 0x0051; -const uint16_t TLV_TYPE_STR_PATH = 0x0052; -const uint16_t TLV_TYPE_STR_KEY = 0x0053; -const uint16_t TLV_TYPE_STR_VALUE = 0x0054; -const uint16_t TLV_TYPE_STR_COMMENT = 0x0055; -const uint16_t TLV_TYPE_STR_TITLE = 0x0056; -const uint16_t TLV_TYPE_STR_MSG = 0x0057; -const uint16_t TLV_TYPE_STR_SUBJECT = 0x0058; -const uint16_t TLV_TYPE_STR_LINK = 0x0059; -const uint16_t TLV_TYPE_STR_GENID = 0x005a; -const uint16_t TLV_TYPE_STR_GPGID = 0x005b; /* depreciated */ -const uint16_t TLV_TYPE_STR_PGPID = 0x005b; /* same as GPG */ -const uint16_t TLV_TYPE_STR_LOCATION = 0x005c; -const uint16_t TLV_TYPE_STR_CERT_GPG = 0x005d; -const uint16_t TLV_TYPE_STR_PGPCERT = 0x005d; /* same as CERT_GPG */ -const uint16_t TLV_TYPE_STR_CERT_SSL = 0x005e; -const uint16_t TLV_TYPE_STR_VERSION = 0x005f; -const uint16_t TLV_TYPE_STR_PARAM = 0x0054; /* same as VALUE ---- TO FIX */ - -/* Hashs are always strings */ -const uint16_t TLV_TYPE_STR_HASH_SHA1 = 0x0070; -const uint16_t TLV_TYPE_STR_HASH_ED2K = 0x0071; - -const uint16_t TLV_TYPE_IPV4_LOCAL = 0x0080; -const uint16_t TLV_TYPE_IPV4_REMOTE = 0x0081; -const uint16_t TLV_TYPE_IPV4_LAST = 0x0082; -const uint16_t TLV_TYPE_STR_DYNDNS = 0x0083; -const uint16_t TLV_TYPE_STR_DOMADDR = 0x0084; - -// rearrange these in the future. -const uint16_t TLV_TYPE_IPV4 = 0x0085; -const uint16_t TLV_TYPE_IPV6 = 0x0086; - -/*** MORE STRING IDS ****/ -const uint16_t TLV_TYPE_STR_GROUPID = 0x00a0; -const uint16_t TLV_TYPE_STR_MSGID = 0x00a1; -const uint16_t TLV_TYPE_STR_PARENTID = 0x00a2; -const uint16_t TLV_TYPE_STR_THREADID = 0x00a3; -const uint16_t TLV_TYPE_STR_KEYID = 0x00a4; - -/* even MORE string Ids for GXS services */ - -const uint16_t TLV_TYPE_STR_CAPTION = 0x00b1; -const uint16_t TLV_TYPE_STR_CATEGORY = 0x00b2; -const uint16_t TLV_TYPE_STR_DESCR = 0x00b3; -const uint16_t TLV_TYPE_STR_SIGN = 0x00b4; -const uint16_t TLV_TYPE_STR_HASH_TAG = 0x00b5; -const uint16_t TLV_TYPE_STR_WIKI_PAGE = 0x00b6; -const uint16_t TLV_TYPE_STR_DATE = 0x00b7; -const uint16_t TLV_TYPE_STR_PIC_TYPE = 0x00b8; -const uint16_t TLV_TYPE_STR_PIC_AUTH = 0x00b9; -const uint16_t TLV_TYPE_STR_GXS_ID = 0x00ba; - - - /**** Binary Types ****/ -const uint16_t TLV_TYPE_CERT_XPGP_DER = 0x0100; -const uint16_t TLV_TYPE_CERT_X509 = 0x0101; -const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0102; - -const uint16_t TLV_TYPE_KEY_EVP_PKEY = 0x0110; /* Used (Generic - Distrib) */ -const uint16_t TLV_TYPE_KEY_PRIV_RSA = 0x0111; /* not used yet */ -const uint16_t TLV_TYPE_KEY_PUB_RSA = 0x0112; /* not used yet */ - -const uint16_t TLV_TYPE_SIGN_RSA_SHA1 = 0x0120; /* Used (Distrib/Forums) */ - -const uint16_t TLV_TYPE_BIN_IMAGE = 0x0130; /* Used (Generic - Forums) */ -const uint16_t TLV_TYPE_BIN_FILEDATA = 0x0140; /* Used - ACTIVE! */ -const uint16_t TLV_TYPE_BIN_SERIALISE = 0x0150; /* Used (Generic - Distrib) */ -const uint16_t TLV_TYPE_BIN_GENERIC = 0x0160; /* Used (DSDV Data) */ -const uint16_t TLV_TYPE_BIN_ENCRYPTED = 0x0170; /* Encrypted data */ - - - /**** Compound Types ****/ -const uint16_t TLV_TYPE_FILEITEM = 0x1000; -const uint16_t TLV_TYPE_FILESET = 0x1001; -const uint16_t TLV_TYPE_FILEDATA = 0x1002; - -const uint16_t TLV_TYPE_KEYVALUE = 0x1010; -const uint16_t TLV_TYPE_KEYVALUESET = 0x1011; - -const uint16_t TLV_TYPE_STRINGSET = 0x1020; /* dummy non-existant */ -const uint16_t TLV_TYPE_PEERSET = 0x1021; -const uint16_t TLV_TYPE_HASHSET = 0x1022; - -const uint16_t TLV_TYPE_PGPIDSET = 0x1023; -const uint16_t TLV_TYPE_RECOGNSET = 0x1024; -const uint16_t TLV_TYPE_GXSIDSET = 0x1025; -const uint16_t TLV_TYPE_GXSCIRCLEIDSET= 0x1026; -const uint16_t TLV_TYPE_NODEGROUPIDSET= 0x1027; -const uint16_t TLV_TYPE_GXSMSGIDSET = 0x1028; - -const uint16_t TLV_TYPE_SERVICESET = 0x1030; - -// *_deprectate should not be used anymore!! -// We use 1040 for both public and private keys, so that transmitting them still works (backward compatibility), and so that -// signatures are kept. But the two different classes will check that the flags are correct when deserialising. - -const uint16_t TLV_TYPE_SECURITY_KEY = 0x1040; -const uint16_t TLV_TYPE_SECURITYKEYSET = 0x1041; - -const uint16_t TLV_TYPE_KEYSIGNATURE = 0x1050; -const uint16_t TLV_TYPE_KEYSIGNATURESET = 0x1051; -const uint16_t TLV_TYPE_KEYSIGNATURETYPE = 0x1052; - -const uint16_t TLV_TYPE_IMAGE = 0x1060; - -const uint16_t TLV_TYPE_ADDRESS_INFO = 0x1070; -const uint16_t TLV_TYPE_ADDRESS_SET = 0x1071; -const uint16_t TLV_TYPE_ADDRESS = 0x1072; - -const uint16_t TLV_TYPE_DSDV_ENDPOINT = 0x1080; -const uint16_t TLV_TYPE_DSDV_ENTRY = 0x1081; -const uint16_t TLV_TYPE_DSDV_ENTRY_SET= 0x1082; - -const uint16_t TLV_TYPE_BAN_ENTRY_dep = 0x1090; -const uint16_t TLV_TYPE_BAN_ENTRY = 0x1092; -const uint16_t TLV_TYPE_BAN_LIST = 0x1091; - -const uint16_t TLV_TYPE_MSG_ADDRESS = 0x10A0; -const uint16_t TLV_TYPE_MSG_ID = 0x10A1; - - -const uint32_t RSTLV_IMAGE_TYPE_PNG = 0x0001; -const uint32_t RSTLV_IMAGE_TYPE_JPG = 0x0002; - -/**** Basic TLV Functions ****/ -uint32_t GetTlvSize(void *data); -uint16_t GetTlvType(void *data); -bool SetTlvBase(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t len); -bool SetTlvSize(void *data, uint32_t size, uint32_t len); -bool SetTlvType(void *data, uint32_t size, uint16_t type); - -/* skip past the unknown tlv elements */ -bool SkipUnknownTlv(void *data, uint32_t size, uint32_t *offset); - -/**** Generic TLV Functions **** - * This have the same data (int or string for example), - * but they can have different types eg. a string could represent a name or a path, - * so we include a type parameter in the arguments - */ - -bool SetTlvUInt8(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint8_t out); -bool GetTlvUInt8(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint8_t *in); - -bool SetTlvUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t out); -bool GetTlvUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t *in); - -bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t out); -bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t *in); - -bool SetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint64_t out); -bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint64_t *in); - -uint32_t GetTlvUInt8Size(); -uint32_t GetTlvUInt16Size(); -uint32_t GetTlvUInt32Size(); -uint32_t GetTlvUInt64Size(); - - -bool SetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string out); -bool GetTlvString(const void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string &in); -uint32_t GetTlvStringSize(const std::string &in); - -#ifdef REMOVED_CODE -bool SetTlvWideString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::wstring out); -bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::wstring &in); -uint32_t GetTlvWideStringSize(std::wstring &in); -#endif - -bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *out); -bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *in); -uint32_t GetTlvIpAddrPortV4Size(); - -bool SetTlvIpAddrPortV6(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in6 *out); -bool GetTlvIpAddrPortV6(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in6 *in); -uint32_t GetTlvIpAddrPortV6Size(); - -/* additional function to be added - -bool SetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv) - -above(SetTlvbinData) is partially implemented - -bool GetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv) - -*************************************/ diff --git a/libretroshare/src/serialiser/rstlvbinary.cc b/libretroshare/src/serialiser/rstlvbinary.cc deleted file mode 100644 index 7eabf74d9..000000000 --- a/libretroshare/src/serialiser/rstlvbinary.cc +++ /dev/null @@ -1,326 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbinary.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsmemory.h" -#include "serialiser/rstlvbinary.h" - -#include "serialiser/rstlvbase.h" -#include -#include -#include - -// #define TLV_DEBUG 1 - -/*!********************************** RsTlvFileBinaryData **********************************/ - - -RsTlvBinaryData::RsTlvBinaryData() - :tlvtype(0), bin_len(0), bin_data(NULL) -{ -} - -RsTlvBinaryData::RsTlvBinaryData(uint16_t t) - :tlvtype(t), bin_len(0), bin_data(NULL) -{ -} - -RsTlvBinaryData::RsTlvBinaryData(const RsTlvBinaryData &b) - : tlvtype(b.tlvtype), bin_len(0) , bin_data(NULL) { - - setBinData(b.bin_data, b.bin_len); -} - -RsTlvBinaryData::~RsTlvBinaryData() -{ - TlvClear(); -} - -void RsTlvBinaryData::operator =(const RsTlvBinaryData& b){ - - setBinData(b.bin_data, b.bin_len); - tlvtype = b.tlvtype; -} - -/// used to allocate memory andinitialize binary data member -bool RsTlvBinaryData::setBinData(const void *data, uint32_t size) -{ - /* ready to load */ - TlvClear(); - - /* get mandatory */ - /* the rest of the TLV size binary data */ - bin_len = size; - if (bin_len == 0) - { - bin_data = NULL; - return true; - } - - bin_data = rs_malloc(bin_len); - - if(bin_data == NULL) - return false ; - - memcpy(bin_data, data, bin_len); - return true; -} - -void RsTlvBinaryData::TlvClear() -{ - free(bin_data); - TlvShallowClear(); -} - -void RsTlvBinaryData::TlvShallowClear() -{ - bin_data = NULL; - bin_len = 0; -} - -uint32_t RsTlvBinaryData::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - if (bin_data != NULL) - s += bin_len; // len is the size of data - - return s; -} - - -bool RsTlvBinaryData::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, tlvtype, tlvsize); - - /* add mandatory data */ - - // Warning: this is actually not an error if bin_len=0, as it does not - // corrupt the packet structure. We thus still return true in this case. - // - if (bin_data != NULL && bin_len > 0) - { - memcpy(&(((uint8_t *) data)[*offset]), bin_data, bin_len); - *offset += bin_len; - } - return ok; -} - - - -bool RsTlvBinaryData::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - { - return false; /* not enough space to get the header */ - } - - uint16_t tlvtype_in = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvsize < TLV_HEADER_SIZE) - { - return false; /* bad tlv size */ - } - - if (tlvtype != tlvtype_in) /* check type */ - return false; - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - bool ok = setBinData(&(((uint8_t *) data)[*offset]), tlvsize - TLV_HEADER_SIZE); - (*offset) += bin_len; - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvBinaryData::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} -std::ostream &RsTlvBinaryDataRef::print(std::ostream &out, uint16_t indent) const -{ - uint16_t int_Indent = indent + 2; - - uint32_t i; - std::ostringstream sout; - printIndent(sout, indent); - sout << "RsTlvBinaryData: Type: " << tlvtype << " Size: " << mSizeRef; - sout << std::hex; - - for(i = 0; i < mSizeRef; i++) - { - if (i % 16 == 0) - { - sout << std::endl; - printIndent(sout, int_Indent); - } - sout << std::setw(2) << std::setfill('0') - << (int) (((unsigned char *) mDataRef)[i]) << ":"; - } - - sout << std::endl; - out << sout.str(); - - printEnd(out, "RsTlvBinaryData", indent); - return out; - -} - -std::ostream &RsTlvBinaryData::print(std::ostream &out, uint16_t indent) const -{ - uint16_t int_Indent = indent + 2; - - uint32_t i; - std::ostringstream sout; - printIndent(sout, indent); - sout << "RsTlvBinaryData: Type: " << tlvtype << " Size: " << bin_len; - sout << std::hex; - - for(i = 0; i < bin_len; i++) - { - if (i % 16 == 0) - { - sout << std::endl; - printIndent(sout, int_Indent); - } - sout << std::setw(2) << std::setfill('0') - << (int) (((unsigned char *) bin_data)[i]) << ":"; - } - - sout << std::endl; - out << sout.str(); - - printEnd(out, "RsTlvBinaryData", indent); - return out; - -} - -bool RsTlvBinaryDataRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, tlvtype, tlvsize); - - /* add mandatory data */ - - // Warning: this is actually not an error if bin_len=0, as it does not - // corrupt the packet structure. We thus still return true in this case. - // - if (mDataRef != NULL && mSizeRef > 0) - { - memcpy(&(((uint8_t *) data)[*offset]), mDataRef, mSizeRef); - *offset += mSizeRef; - } - return ok; -} -bool RsTlvBinaryDataRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - { - return false; /* not enough space to get the header */ - } - - uint16_t tlvtype_in = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvsize < TLV_HEADER_SIZE) - return false; /* bad tlv size */ - - if (tlvtype != tlvtype_in) /* check type */ - return false; - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - mDataRef = (uint8_t*)rs_malloc(tlvsize - TLV_HEADER_SIZE) ; - - if(mDataRef == NULL) - return false ; - - mSizeRef = tlvsize - TLV_HEADER_SIZE; - - memcpy(mDataRef,&(((uint8_t *) data)[*offset]), tlvsize - TLV_HEADER_SIZE); - *offset += mSizeRef; - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvBinaryData::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return true; -} - -uint32_t RsTlvBinaryDataRef::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - if (mDataRef != NULL) - s += mSizeRef; // len is the size of data - - return s; -} diff --git a/libretroshare/src/serialiser/rstlvbinary.h b/libretroshare/src/serialiser/rstlvbinary.h deleted file mode 100644 index 3d41d5402..000000000 --- a/libretroshare/src/serialiser/rstlvbinary.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvbinary.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvitem.h" - - -class RsTlvBinaryData: public RsTlvItem -{ -public: - RsTlvBinaryData(); - RsTlvBinaryData(uint16_t t); - RsTlvBinaryData(const RsTlvBinaryData& b); // as per rule of three - void operator=(const RsTlvBinaryData& b); // as per rule of three - - virtual ~RsTlvBinaryData(); // as per rule of three - - virtual uint32_t TlvSize() const; - virtual void TlvClear(); /*! Initialize fields to empty legal values ( "0", "", etc) */ - virtual void TlvShallowClear(); /*! Don't delete the binary data */ - - /// Serialise. - /*! Serialise Tlv to buffer(*data) of 'size' bytes starting at *offset */ - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - - /// Deserialise. - /*! Deserialise Tlv buffer(*data) of 'size' bytes starting at *offset */ - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; /*! Error/Debug util function */ - - // mallocs the necessary size, and copies data into the allocated buffer in bin_data - bool setBinData(const void *data, uint32_t size); - - uint16_t tlvtype; /// set/checked against TLV input - uint32_t bin_len; /// size of malloc'ed data (not serialised) - void *bin_data; /// mandatory -}; - -// This class is mainly used for on-the-fly serialization - -class RsTlvBinaryDataRef: public RsTlvItem -{ -public: - RsTlvBinaryDataRef(uint16_t type,uint8_t *& data_ref,uint32_t& size_ref) : mDataRef(data_ref),mSizeRef(size_ref),tlvtype(type) {} - virtual ~RsTlvBinaryDataRef() {} - - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - virtual uint32_t TlvSize() const; - virtual void TlvClear(){} - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - - uint8_t *& mDataRef ; - uint32_t & mSizeRef ; - uint16_t tlvtype ; -}; - - - diff --git a/libretroshare/src/serialiser/rstlvfileitem.cc b/libretroshare/src/serialiser/rstlvfileitem.cc deleted file mode 100644 index 098b8de6f..000000000 --- a/libretroshare/src/serialiser/rstlvfileitem.cc +++ /dev/null @@ -1,703 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvfileitem.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rsbaseserial.h" - -#if 0 -#include - -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvtypes.h" -#endif - -/*** - * #define TLV_FI_DEBUG 1 - **/ - - -RsTlvFileItem::RsTlvFileItem() -{ - TlvClear(); -} - -void RsTlvFileItem::TlvClear() -{ - filesize = 0; - hash.clear() ; - name.clear(); - path.clear(); - pop = 0; - age = 0; - piecesize = 0; - hashset.TlvClear(); -} - -uint32_t RsTlvFileItem::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - s += 8; /* filesize */ - s += hash.serial_size() ; -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() 8 + Hash: " << s << std::endl; -#endif - - - /* now optional ones */ - if (name.length() > 0) - { - s += GetTlvStringSize(name); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() + Name: " << s << std::endl; -#endif - } - - if (path.length() > 0) - { - s += GetTlvStringSize(path); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() + Path: " << s << std::endl; -#endif - } - - if (pop != 0) - { - s += GetTlvUInt32Size(); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() + Pop: " << s << std::endl; -#endif - } - - if (age != 0) - { - s += GetTlvUInt32Size(); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() 4 + Age: " << s << std::endl; -#endif - } - - if (piecesize != 0) - { - s += GetTlvUInt32Size(); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() 4 + PieceSize: " << s << std::endl; -#endif - } - - if (hashset.ids.size() != 0) - { - s += hashset.TlvSize(); -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() 4 + HashSet: " << s << std::endl; -#endif - } - -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::TlvSize() Total: " << s << std::endl; -#endif - - return s; -} - -/* serialise the data to the buffer */ -bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_FI_DEBUG - std::cerr << "RsTlvFileItem::SetTlv() Failed size (" << size; - std::cerr << ") < tlvend (" << tlvend << ")" << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILEITEM, tlvsize); - -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() SetTlvBase Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() PostBase:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - - /* add mandatory parts first */ - ok &= setRawUInt64(data, tlvend, offset, filesize); - -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() SetRawUInt32(FILESIZE) Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() PostSize:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - ok &= hash.serialise(data, tlvend, *offset) ; - - -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() SetTlvString(HASH) Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() PostHash:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - /* now optional ones */ - if (name.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_NAME, name); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Name Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() PostName:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - if (path.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_PATH, path); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Path Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() Pre Pop:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << " type: " << TLV_TYPE_UINT32_POP << " value: " << pop; - std::cerr << std::endl; -#endif - - if (pop != 0) - ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_POP, pop); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Pop Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() Post Pop/Pre Age:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << " type: " << TLV_TYPE_UINT32_AGE << " value: " << age; - std::cerr << std::endl; -#endif - - if (age != 0) - ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_AGE, age); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:Age Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() Post Age:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - if (piecesize != 0) - ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SIZE, piecesize); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:piecesize Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() Post PieceSize:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - if (hashset.ids.size() != 0) - ok &= hashset.SetTlv(data, tlvend, offset); -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Option:hashset Failed (or earlier)" << std::endl; - } - std::cerr << "RsTlvFileItem::SetTlv() Post HashSet:" << std::endl; - std::cerr << "RsTlvFileItem::SetTlv() Data: " << data << " size: " << size << " offset: " << *offset; - std::cerr << std::endl; -#endif - - - -#ifdef TLV_FI_DEBUG - if (!ok) - { - std::cerr << "RsTlvFileItem::SetTlv() Setting Options Failed (or earlier)" << std::endl; - } -#endif - - return ok; -} - -bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_FILEITEM) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* get mandatory parts first */ - ok &= getRawUInt64(data, tlvend, offset, &filesize); - ok &= hash.deserialise(data, tlvend, *offset) ; - - /* while there is more TLV (optional part) */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - switch(tlvsubtype) - { - case TLV_TYPE_STR_NAME: - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_NAME, name); - break; - case TLV_TYPE_STR_PATH: - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_PATH, path); - break; - case TLV_TYPE_UINT32_POP: - ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_POP, &pop); - break; - case TLV_TYPE_UINT32_AGE: - ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_AGE, &age); - break; - case TLV_TYPE_UINT32_SIZE: - ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SIZE, &piecesize); - break; - case TLV_TYPE_HASHSET: - ok &= hashset.GetTlv(data, tlvend, offset); - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - } - if (!ok) - { - break; - } - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvFileItem::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - - -/* print it out */ -std::ostream &RsTlvFileItem::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvFileItem", indent); - uint16_t int_Indent = indent + 2; - - - printIndent(out, int_Indent); - out << "Mandatory: FileSize: " << filesize << " Hash: " << hash; - out << std::endl; - - printIndent(out, int_Indent); - out << "Optional:" << std::endl; - - /* now optional ones */ - if (name.length() > 0) - { - printIndent(out, int_Indent); - out << "Name : " << name << std::endl; - } - if (path.length() > 0) - { - printIndent(out, int_Indent); - out << "Path : " << path << std::endl; - } - if (pop != 0) - { - printIndent(out, int_Indent); - out << "Pop: " << pop << std::endl; - } - if (age != 0) - { - printIndent(out, int_Indent); - out << "Age: " << age << std::endl; - } - if (piecesize != 0) - { - printIndent(out, int_Indent); - out << "PieceSize: " << piecesize << std::endl; - } - if (hashset.ids.size() != 0) - { - hashset.print(out, int_Indent); - } - - printEnd(out, "RsTlvFileItem", indent); - - return out; -} - - -/************************************* RsTlvFileSet ************************************/ - -void RsTlvFileSet::TlvClear() -{ - title.clear(); - comment.clear(); - items.clear(); -} - -uint32_t RsTlvFileSet::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* first determine the total size of RstlvFileItems in list */ - - std::list::const_iterator it; - - for(it = items.begin(); it != items.end() ; ++it) - { - s += (*it).TlvSize(); - } - - /* now add comment and title length of this tlv object */ - - if (title.length() > 0) - s += GetTlvStringSize(title); - if (comment.length() > 0) - s += GetTlvStringSize(comment); - - return s; -} - - -/* serialize data to the buffer */ - -bool RsTlvFileSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILESET, tlvsize); - - /* add mandatory parts first */ - std::list::const_iterator it; - - for(it = items.begin(); it != items.end() ; ++it) - { - ok &= (*it).SetTlv(data, size, offset); - /* drop out if fails */ - if (!ok) - return false; - } - - /* now optional ones */ - if (title.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_TITLE, title); - if (comment.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_COMMENT, comment); - - return ok; - -} - - -bool RsTlvFileSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_FILESET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is more TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - if (tlvsubtype == TLV_TYPE_FILEITEM) - { - RsTlvFileItem newitem; - ok &= newitem.GetTlv(data, size, offset); - if (ok) - { - items.push_back(newitem); - } - } - else if (tlvsubtype == TLV_TYPE_STR_TITLE) - { - ok &= GetTlvString(data, tlvend, offset, - TLV_TYPE_STR_TITLE, title); - } - else if (tlvsubtype == TLV_TYPE_STR_COMMENT) - { - ok &= GetTlvString(data, tlvend, offset, - TLV_TYPE_STR_COMMENT, comment); - } - else - { - /* unknown subtype -> error */ - ok &= SkipUnknownTlv(data, tlvend, offset); - } - - if (!ok) - { - break; - } - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvFileSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -/* print it out */ - -std::ostream &RsTlvFileSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvFileSet", indent); - uint16_t int_Indent = indent + 2; - - - printIndent(out, int_Indent); - out << "Mandatory:" << std::endl; - std::list::const_iterator it; - - for(it = items.begin(); it != items.end() ; ++it) - { - it->print(out, int_Indent); - } - printIndent(out, int_Indent); - out << "Optional:" << std::endl; - - /* now optional ones */ - if (title.length() > 0) - { - printIndent(out, int_Indent); - std::string cnv_title(title.begin(), title.end()); - out << "Title: " << cnv_title << std::endl; - } - if (comment.length() > 0) - { - printIndent(out, int_Indent); - std::string cnv_comment(comment.begin(), comment.end()); - out << "Comment: " << cnv_comment << std::endl; - } - - printEnd(out, "RsTlvFileSet", indent); - - return out; -} - - -/************************************* RsTlvFileData ************************************/ - -RsTlvFileData::RsTlvFileData() - :RsTlvItem(), file_offset(0), binData(TLV_TYPE_BIN_FILEDATA) -{ - return; -} - -void RsTlvFileData::TlvClear() -{ - file.TlvClear(); - binData.TlvClear(); - file_offset = 0; -} - - -uint32_t RsTlvFileData::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* collect sizes for both uInts and data length */ - s+= file.TlvSize(); - s+= GetTlvUInt64Size(); - s+= binData.TlvSize(); - - return s; -} - - -bool RsTlvFileData::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_FILEDATA , tlvsize); - - /* add mandatory part */ - ok &= file.SetTlv(data, size, offset); - ok &= SetTlvUInt64(data,size,offset, - TLV_TYPE_UINT64_OFFSET,file_offset); - ok &= binData.SetTlv(data, size, offset); - - return ok; - - -} - -bool RsTlvFileData::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - { - return false; - } - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_FILEDATA) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= file.GetTlv(data, size, offset); - ok &= GetTlvUInt64(data,size,offset, - TLV_TYPE_UINT64_OFFSET,&file_offset); - ok &= binData.GetTlv(data, size, offset); - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvFileData::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - -/* print it out */ -std::ostream &RsTlvFileData::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvFileData", indent); - uint16_t int_Indent = indent + 2; - - file.print(out, int_Indent); - - printIndent(out, int_Indent); - out << "FileOffset: " << file_offset; - out << std::endl; - - binData.print(out, int_Indent); - - printEnd(out, "RsTlvFileData", indent); - return out; - -} - diff --git a/libretroshare/src/serialiser/rstlvfileitem.h b/libretroshare/src/serialiser/rstlvfileitem.h deleted file mode 100644 index 174753364..000000000 --- a/libretroshare/src/serialiser/rstlvfileitem.h +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvfileitem.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvbinary.h" - -class RsTlvFileItem: public RsTlvItem -{ - public: - RsTlvFileItem(); -virtual ~RsTlvFileItem() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint64_t filesize; /// Mandatory: size of file to be downloaded - RsFileHash hash; /// Mandatory: to find file - std::string name; /// Optional: name of file - std::string path; /// Optional: path on host computer - uint32_t pop; /// Optional: Popularity of file - uint32_t age; /// Optional: age of file - // For chunk hashing. - uint32_t piecesize; /// Optional: bytes/piece for hashset. - RsTlvHashSet hashset; /// Optional: chunk hashes. - -}; - -class RsTlvFileSet: public RsTlvItem -{ - public: - RsTlvFileSet() { return; } -virtual ~RsTlvFileSet() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::list items; /// Mandatory - std::string title; /// Optional: title of file set - std::string comment; /// Optional: comments for file -}; - - -class RsTlvFileData: public RsTlvItem -{ - public: - RsTlvFileData(); - virtual ~RsTlvFileData() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - RsTlvFileItem file; /// Mandatory: file information - uint64_t file_offset; /// Mandatory: where to start in bin data - RsTlvBinaryData binData; /// Mandatory: serialised file info -}; - - diff --git a/libretroshare/src/serialiser/rstlvgenericmap.h b/libretroshare/src/serialiser/rstlvgenericmap.h deleted file mode 100644 index 0cc4a3a88..000000000 --- a/libretroshare/src/serialiser/rstlvgenericmap.h +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvgenericmap.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_TLV_GENERIC_MAP_H -#define RS_TLV_GENERIC_MAP_H - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvgenericparam.h" - -#if 0 -#include - -#include -#include - -#endif - -/*********************************** RsTlvGenericPairRef ***********************************/ - -template -class RsTlvGenericPairRef: public RsTlvItem -{ - public: - RsTlvGenericPairRef(uint16_t pair_type, - uint16_t key_type, uint16_t value_type, K &k, V &v) - :mPairType(pair_type), mKeyType(key_type), - mValueType(value_type), mKey(k), mValue(v) { return; } - -virtual ~RsTlvGenericPairRef() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint16_t mPairType; - uint16_t mKeyType; - uint16_t mValueType; - K &mKey; - V &mValue; -}; - - -/************************************ RsTlvGenericMapRef ***********************************/ - -template -class RsTlvGenericMapRef: public RsTlvItem -{ - public: - RsTlvGenericMapRef(uint16_t map_type, uint16_t pair_type, - uint16_t key_type, uint16_t value_type, std::map &refmap) - :mMapType(map_type), mPairType(pair_type), - mKeyType(key_type), mValueType(value_type), mRefMap(refmap) { return; } - -virtual ~RsTlvGenericMapRef() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint16_t mMapType; - uint16_t mPairType; - uint16_t mKeyType; - uint16_t mValueType; - std::map &mRefMap; -}; - - -#include "rstlvgenericmap.inl" - -#endif - diff --git a/libretroshare/src/serialiser/rstlvgenericmap.inl b/libretroshare/src/serialiser/rstlvgenericmap.inl deleted file mode 100644 index b5239d2f7..000000000 --- a/libretroshare/src/serialiser/rstlvgenericmap.inl +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvgenericmap.inl * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "serialiser/rstlvbase.h" - -// Must be different - as this is inline in headers. -//#define TLV_GENERICMAP_DEBUG 1 - -/*********************************** RsTlvGenericPairRef ***********************************/ - -template -void RsTlvGenericPairRef::TlvClear() -{ - RsTlvParamRef key(mKeyType, mKey); - RsTlvParamRef value(mValueType, mValue); - key.TlvClear(); - value.TlvClear(); -} - -template -uint32_t RsTlvGenericPairRef::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - RsTlvParamRef key(mKeyType, mKey); - RsTlvParamRef value(mValueType, mValue); - - s += key.TlvSize(); - s += value.TlvSize(); - return s; - -} - -template -bool RsTlvGenericPairRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, mPairType, tlvsize); - - RsTlvParamRef key(mKeyType, mKey); - RsTlvParamRef value(mValueType, mValue); - ok &= key.SetTlv(data, tlvend, offset); - ok &= value.SetTlv(data, tlvend, offset); - - if (!ok) - { - std::cerr << "RsTlvGenericPairRef<>::SetTlv() Failed"; - std::cerr << std::endl; - } -#ifdef TLV_GENERICMAP_DEBUG - else - { - std::cerr << "RsTlvGenericPairRef<>::SetTlv() Ok"; - std::cerr << std::endl; - } -#endif - return ok; -} - -template -bool RsTlvGenericPairRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != mPairType) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - RsTlvParamRef key(mKeyType, mKey); - RsTlvParamRef value(mValueType, mValue); - ok &= key.GetTlv(data, tlvend, offset); - ok &= value.GetTlv(data, tlvend, offset); - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_GENERICMAP_DEBUG - std::cerr << "RsTlvGenericPairRef::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - return ok; - -} - -template -std::ostream &RsTlvGenericPairRef::print(std::ostream &out, uint16_t indent) const -{ - //printBase(out, "RsTlvGenericPairRef", indent); - uint16_t int_Indent = indent + 2; - - RsTlvParamRef key(mKeyType, mKey); - RsTlvParamRef value(mValueType, mValue); - - printIndent(out, int_Indent); - out << "Key:"; - key.print(out, 0); - out << std::endl; - - printIndent(out, int_Indent); - out << "Value:"; - value.print(out, 0); - out << std::endl; - - //printEnd(out, "RsTlvGenericPairRef", indent); - return out; -} - -// declare likely combinations. -//template<> class RsTlvGenericPairRef; -//template<> class RsTlvGenericPairRef; -//template<> class RsTlvGenericPairRef; -//template<> class RsTlvGenericPairRef; - -/************************************ RsTlvGenericMapRef ***********************************/ - -template -void RsTlvGenericMapRef::TlvClear() -{ - mRefMap.clear(); //empty list -} - -template -uint32_t RsTlvGenericMapRef::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - typename std::map::iterator it; - for(it = mRefMap.begin(); it != mRefMap.end(); ++it) - { - RsTlvGenericPairRef pair(mPairType, mKeyType, mValueType, it->first, it->second); - s += pair.TlvSize(); - } - - return s; -} - -template -bool RsTlvGenericMapRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, mMapType, tlvsize); - - - typename std::map::iterator it; - for(it = mRefMap.begin(); it != mRefMap.end(); ++it) - { - RsTlvGenericPairRef pair(mPairType, mKeyType, mValueType, it->first, it->second); - ok &= pair.SetTlv(data, size, offset); - } - - if (!ok) - { - std::cerr << "RsTlvGenericMapRef<>::SetTlv() Failed"; - std::cerr << std::endl; - } - - return ok; -} - -template -bool RsTlvGenericMapRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != mMapType) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - if (tlvsubtype == mPairType) - { - K k; - V v; - RsTlvGenericPairRef pair(mPairType, mKeyType, mValueType, k, v); - ok &= pair.GetTlv(data, size, offset); - if (ok) - { - mRefMap[k] = v; - } - } - else - { - ok &= SkipUnknownTlv(data, tlvend, offset); - ok = false; - } - - if (!ok) - break; - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_GENERICMAP_DEBUG - std::cerr << "RsTlvGenericMapRef::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -template -std::ostream &RsTlvGenericMapRef::print(std::ostream &out, uint16_t indent) const -{ - //printBase(out, "RsTlvGenericMapRef", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "MapType:" << mMapType << std::endl; - - typename std::map::iterator it; - for(it = mRefMap.begin(); it != mRefMap.end() ; ++it) - { - RsTlvGenericPairRef pair(mPairType, mKeyType, mValueType, it->first, it->second); - pair.print(out, int_Indent); - } - - //printEnd(out, "RsTlvGenericMapRef", indent); - return out; -} - diff --git a/libretroshare/src/serialiser/rstlvgenericparam.cc b/libretroshare/src/serialiser/rstlvgenericparam.cc deleted file mode 100644 index ef3610813..000000000 --- a/libretroshare/src/serialiser/rstlvgenericparam.cc +++ /dev/null @@ -1,222 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvgenericparam.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvgenericparam.h" -#include "serialiser/rstlvbase.h" -#include - -// #define TLV_DEBUG 1 - -/* generic print */ -template -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << " Param: " << mParam; - return out; -} - - -/***** uint16_t ****/ -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - return GetTlvUInt16Size(); -} - -template<> -void RsTlvParamRef::TlvClear() -{ - mParam = 0; -} - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - return SetTlvUInt16(data, size, offset, mParamType, mParam); -} - -template<> -bool RsTlvParamRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - uint16_t param; - bool retval = GetTlvUInt16(data, size, offset, mParamType, ¶m); - mParam = param; - return retval; -} - -template<> -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << "Param: " << mParam; - return out; -} - - -/***** const uint16_t ****/ - -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - return GetTlvUInt16Size(); -} - -template<> -void RsTlvParamRef::TlvClear() -{ - //mParam = 0; -} - - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - return SetTlvUInt16(data, size, offset, mParamType, mParam); -} - -template<> -bool RsTlvParamRef::GetTlv(void */*data*/, uint32_t /*size*/, uint32_t */*offset*/) -{ - return false; //GetTlvUInt16(data, size, offset, mParamType, &mParam); -} - - -template<> -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << "Param: " << mParam; - return out; -} - -/***** uint32_t ****/ -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - return GetTlvUInt32Size(); -} - -template<> -void RsTlvParamRef::TlvClear() -{ - mParam = 0; -} - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - return SetTlvUInt32(data, size, offset, mParamType, mParam); -} - -template<> -bool RsTlvParamRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - return GetTlvUInt32(data, size, offset, mParamType, &mParam); -} - -template<> -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << "Param: " << mParam; - return out; -} - - - -/***** const uint32_t ****/ -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - return GetTlvUInt32Size(); -} - -template<> -void RsTlvParamRef::TlvClear() -{ - //mParam = 0; -} - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - return SetTlvUInt32(data, size, offset, mParamType, mParam); -} - -template<> -bool RsTlvParamRef::GetTlv(void */*data*/, uint32_t /*size*/, uint32_t */*offset*/) -{ - return false; - //GetTlvUInt32(data, size, offset, mParamType, &mParam); -} - -template<> -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << "Param: " << mParam; - return out; -} - - -/***** std::string ****/ -template<> -uint32_t RsTlvParamRef::TlvSize() const -{ - return GetTlvStringSize(mParam); -} - -template<> -void RsTlvParamRef::TlvClear() -{ - mParam.clear(); -} - -template<> -bool RsTlvParamRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - return SetTlvString(data, size, offset, mParamType, mParam); -} - -template<> -bool RsTlvParamRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - return GetTlvString(data, size, offset, mParamType, mParam); -} - -template<> -std::ostream & RsTlvParamRef::print(std::ostream &out, uint16_t indent) const -{ - printIndent(out, indent); - out << "Type: " << mParamType << "Param: " << mParam; - return out; -} - -// declare likely combinations. -//template class RsTlvParamRef; -//template class RsTlvParamRef; -//template class RsTlvParamRef; - -//template class RsTlvParamRef; -//template class RsTlvParamRef; -//template class RsTlvParamRef; - diff --git a/libretroshare/src/serialiser/rstlvgenericparam.h b/libretroshare/src/serialiser/rstlvgenericparam.h deleted file mode 100644 index b1b6417a7..000000000 --- a/libretroshare/src/serialiser/rstlvgenericparam.h +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvgenericparam.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_TLV_GENERIC_PARAM_H -#define RS_TLV_GENERIC_PARAM_H - -#include "serialiser/rstlvitem.h" - -#if 0 -#include - -#include -#include -#endif - - -/**** TLV ***** - * Generic Parameters / Maps. - */ - - -template -class RsTlvParamRef: public RsTlvItem -{ - public: - RsTlvParamRef(uint16_t param_type, T &p): mParamType(param_type), mParam(p) {} -virtual ~RsTlvParamRef() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint16_t mParamType; - T &mParam; -}; - - -#endif - diff --git a/libretroshare/src/serialiser/rstlvidset.cc b/libretroshare/src/serialiser/rstlvidset.cc deleted file mode 100644 index ef60aca36..000000000 --- a/libretroshare/src/serialiser/rstlvidset.cc +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvidset.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rstlvidset.h" - -// #define TLV_DEBUG 1 - -/************************************* Service Id Set ************************************/ - -void RsTlvServiceIdSet::TlvClear() -{ - ids.clear(); - -} - -uint32_t RsTlvServiceIdSet::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* determine the total size of ids strings in list */ - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (*it > 0) - s += GetTlvUInt32Size(); - } - - return s; -} - -bool RsTlvServiceIdSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SERVICESET , tlvsize); - - /* determine the total size of ids strings in list */ - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (*it > 0) - ok &= SetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SERID, *it); - } - - return ok; - -} - -bool RsTlvServiceIdSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_SERVICESET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - -/* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - if (tlvsubtype == TLV_TYPE_UINT32_SERID) - { - uint32_t newIds; - ok &= GetTlvUInt32(data, tlvend, offset, TLV_TYPE_UINT32_SERID, &newIds); - if(ok) - { - ids.push_back(newIds); - - } - } - else - { - /* Step past unknown TLV TYPE */ - ok &= SkipUnknownTlv(data, tlvend, offset); - } - - if (!ok) - { - break; - } - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvServiceIdSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - - return ok; -} - -/// print to screen RsTlvServiceSet contents -std::ostream &RsTlvServiceIdSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvServiceIdSet", indent); - uint16_t int_Indent = indent + 2; - - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - printIndent(out, int_Indent); - out << "id:" << *it; - out << std::endl; - } - - printEnd(out, "RsTlvServiceIdSet", indent); - return out; - -} - - - diff --git a/libretroshare/src/serialiser/rstlvidset.h b/libretroshare/src/serialiser/rstlvidset.h deleted file mode 100644 index 2e8a3f882..000000000 --- a/libretroshare/src/serialiser/rstlvidset.h +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvidset.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvitem.h" -#include "util/rsdeprecate.h" -#include -#include - -#include - -/// @deprecated use plain std::set<> instead -template class RS_DEPRECATED_FOR(std::set<>) t_RsTlvIdSet - : public RsTlvItem -{ - public: - t_RsTlvIdSet() {} - virtual ~t_RsTlvIdSet() {} - - virtual uint32_t TlvSize() const { return ID_CLASS::SIZE_IN_BYTES * ids.size() + TLV_HEADER_SIZE; } - virtual void TlvClear(){ ids.clear() ; } - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const - { /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok = ok && SetTlvBase(data, tlvend, offset, TLV_TYPE, tlvsize); - - for(typename std::set::const_iterator it(ids.begin());it!=ids.end();++it) - ok = ok && (*it).serialise(data,tlvend,*offset) ; - - return ok ; - } - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset) - { - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - while(*offset + ID_CLASS::SIZE_IN_BYTES <= tlvend) - { - ID_CLASS id ; - ok = ok && id.deserialise(data,tlvend,*offset) ; - ids.insert(id) ; - } - if(*offset != tlvend) - { - std::cerr << "(EE) deserialisaiton error in " << __PRETTY_FUNCTION__ << std::endl; - ok = false; - } - - if(!ok) - std::cerr << "(WW) something wrong in ID_CLASS.deserialise in " << __PRETTY_FUNCTION__ << std::endl; - - return ok; - } - virtual std::ostream &print(std::ostream &out, uint16_t /* indent */) const - { - for(typename std::set::const_iterator it(ids.begin());it!=ids.end();++it) - out << (*it).toStdString() << ", " ; - - return out ; - } - virtual std::ostream &printHex(std::ostream &out, uint16_t /* indent */) const /* SPECIAL One */ - { - for(typename std::set::const_iterator it(ids.begin());it!=ids.end();++it) - out << (*it).toStdString() << ", " ; - - return out ; - } - - std::set ids ; -}; - -typedef t_RsTlvIdSet RsTlvPeerIdSet ; -typedef t_RsTlvIdSet RsTlvPgpIdSet ; -typedef t_RsTlvIdSet RsTlvHashSet ; -typedef t_RsTlvIdSet RsTlvGxsIdSet ; -typedef t_RsTlvIdSet RsTlvGxsMsgIdSet ; -typedef t_RsTlvIdSet RsTlvGxsCircleIdSet ; -typedef t_RsTlvIdSet RsTlvNodeGroupIdSet ; - -class RS_DEPRECATED RsTlvServiceIdSet: public RsTlvItem -{ - public: - RsTlvServiceIdSet() { return; } -virtual ~RsTlvServiceIdSet() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::list ids; /* Mandatory */ -}; - - diff --git a/libretroshare/src/serialiser/rstlvimage.cc b/libretroshare/src/serialiser/rstlvimage.cc deleted file mode 100644 index ce8ea5d6c..000000000 --- a/libretroshare/src/serialiser/rstlvimage.cc +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvimage.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvimage.h" - -#if 0 -#include - -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" -#endif - -/*** - * #define TLV_IMG_DEBUG 1 - **/ - -/************************************* RsTlvImage ************************************/ - -RsTlvImage::RsTlvImage() - :RsTlvItem(), image_type(0), binData(TLV_TYPE_BIN_IMAGE) -{ - return; -} - -void RsTlvImage::TlvClear() -{ - image_type = 0; - binData.TlvClear(); -} - - -uint32_t RsTlvImage::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* collect sizes for both uInts and data length */ - s+= 4; - s+= binData.TlvSize(); - - return s; -} - - -bool RsTlvImage::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::SetTlv()" << std::endl; -#endif - - - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::SetTlv() no space" << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_IMAGE , tlvsize); -#ifdef TLV_IMG_DEBUG - if (!ok) - std::cerr << "RsTlvImage::SetTlv() NOK base" << std::endl; -#endif - - /* add mandatory part */ - ok &= setRawUInt32(data, tlvend, offset, image_type); -#ifdef TLV_IMG_DEBUG - if (!ok) - std::cerr << "RsTlvImage::SetTlv() NOK image" << std::endl; -#endif - - ok &= binData.SetTlv(data, size, offset); -#ifdef TLV_IMG_DEBUG - if (!ok) - std::cerr << "RsTlvImage::SetTlv() NOK binData" << std::endl; -#endif - - - return ok; - - -} - -bool RsTlvImage::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::GetTlv()" << std::endl; -#endif - if (size < *offset + TLV_HEADER_SIZE) - { - return false; - } - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::GetTlv() FAIL no space" << std::endl; -#endif - return false; /* not enough space */ - } - - if (tlvtype != TLV_TYPE_IMAGE) /* check type */ - { -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::GetTlv() FAIL wrong type" << std::endl; -#endif - return false; - } - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* add mandatory parts first */ - ok &= getRawUInt32(data, tlvend, offset, &(image_type)); - ok &= binData.GetTlv(data, size, offset); - -#ifdef TLV_IMG_DEBUG - if (!ok) - std::cerr << "RsTlvImage::GetTlv() NOK" << std::endl; -#endif - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvImage::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - -/* print it out */ -std::ostream &RsTlvImage::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvImage", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "Image_Type: " << image_type; - out << std::endl; - - binData.print(out, int_Indent); - - printEnd(out, "RsTlvImage", indent); - return out; - -} - -RsTlvImage::RsTlvImage(const RsTlvImage& rightOp) -:RsTlvItem(), image_type(0), binData(TLV_TYPE_BIN_IMAGE) -{ - this->image_type = rightOp.image_type; - this->binData.setBinData(rightOp.binData.bin_data, rightOp.binData.bin_len); -} diff --git a/libretroshare/src/serialiser/rstlvimage.h b/libretroshare/src/serialiser/rstlvimage.h deleted file mode 100644 index 562c29090..000000000 --- a/libretroshare/src/serialiser/rstlvimage.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvimage.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" - -class RsTlvImage: public RsTlvItem -{ -public: - RsTlvImage(); - RsTlvImage(const RsTlvImage& ); - virtual ~RsTlvImage() { return; } - virtual uint32_t TlvSize() const; - virtual void TlvClear(); - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - - bool empty() const { return binData.bin_len == 0 ; } - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint32_t image_type; // Mandatory: - RsTlvBinaryData binData; // Mandatory: serialised file info -}; - - diff --git a/libretroshare/src/serialiser/rstlvitem.cc b/libretroshare/src/serialiser/rstlvitem.cc deleted file mode 100644 index 62b40e761..000000000 --- a/libretroshare/src/serialiser/rstlvitem.cc +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvitem.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rstlvitem.h" -#include "rstlvbase.h" -#include - -#if 0 -#include "rsbaseserial.h" -#include "util/rsprint.h" -#include -#include -#include -#endif - -// #define TLV_DEBUG 1 - -void RsTlvItem::TlvShallowClear() -{ - TlvClear(); /* unless overloaded! */ -} - -std::ostream &RsTlvItem::printBase(std::ostream &out, std::string clsName, uint16_t indent) const -{ - printIndent(out, indent); - out << "RsTlvItem: " << clsName << " Size: " << TlvSize() << " ***********************"; - out << std::endl; - return out; -} - -std::ostream &RsTlvItem::printEnd(std::ostream &out, std::string clsName, uint16_t indent) const -{ - printIndent(out, indent); - out << "********************** " << clsName << " *********************"; - out << std::endl; - return out; -} - -std::ostream &printIndent(std::ostream &out, uint16_t indent) -{ - for(int i = 0; i < indent; i++) - { - out << " "; - } - return out; -} - - - -RsTlvUnit::RsTlvUnit(const uint16_t tlv_type) - :RsTlvItem(), mTlvType(tlv_type) -{ - return; -} - -uint32_t RsTlvUnit::TlvSize() const -{ - return TLV_HEADER_SIZE + TlvSizeUnit(); -} - -/* serialise */ -bool RsTlvUnit::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ -#ifdef TLV_DEBUG - std::cerr << "RsTlvUnit::SetTlv()" << std::endl; -#endif - - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvImage::SetTlv() ERROR not enough space" << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_IMAGE , tlvsize); - - if (!ok) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvUnit::SetTlv() ERROR Setting base" << std::endl; -#endif - return false; - } - - ok &= SetTlvUnit(data, tlvend, offset); - -#ifdef TLV_DEBUG - if (!ok) - std::cerr << "RsTlvUnit::SetTlv() ERROR in SetTlvUnit" << std::endl; -#endif - return ok; -} - -/* deserialise */ -bool RsTlvUnit::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvUnit::GetTlv() ERROR not enough size for header"; - std::cerr << std::endl; -#endif - return false; - } - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::GetTlv() ERROR no space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - if (tlvtype != mTlvType) /* check type */ - { -#ifdef TLV_IMG_DEBUG - std::cerr << "RsTlvImage::GetTlv() ERROR wrong type"; - std::cerr << std::endl; -#endif - return false; - } - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* extract components */ - ok &= GetTlvUnit(data, tlvend, offset); - -#ifdef TLV_IMG_DEBUG - if (!ok) - { - std::cerr << "RsTlvUnit::GetTlv() ERROR GetTlvUnit() NOK"; - std::cerr << std::endl; - } -#endif - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvUnit::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - diff --git a/libretroshare/src/serialiser/rstlvitem.h b/libretroshare/src/serialiser/rstlvitem.h deleted file mode 100644 index 4d45cd120..000000000 --- a/libretroshare/src/serialiser/rstlvitem.h +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvitem.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "util/rsdeprecate.h" - -#include -#include -#include - -/*! A base class for all tlv items - * This class is provided to allow the serialisation and deserialization of - * compund tlv items - * @deprecated TLV serialization system is deprecated! - */ -class RS_DEPRECATED_FOR(RsSerializable) RsTlvItem -{ - public: - RsTlvItem() { return; } -virtual ~RsTlvItem() { return; } -virtual uint32_t TlvSize() const = 0; -virtual void TlvClear() = 0; -virtual void TlvShallowClear(); /*! Don't delete allocated data */ -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const = 0; /* serialise */ -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset) = 0; /* deserialise */ -virtual std::ostream &print(std::ostream &out, uint16_t indent) const = 0; -std::ostream &printBase(std::ostream &out, std::string clsName, uint16_t indent) const; -std::ostream &printEnd(std::ostream &out, std::string clsName, uint16_t indent) const; -}; - -std::ostream &printIndent(std::ostream &out, uint16_t indent); - -class RS_DEPRECATED_FOR(RsSerializable) RsTlvUnit: public RsTlvItem -{ - public: - RsTlvUnit(uint16_t tlv_type); -virtual ~RsTlvUnit() { return; } -virtual uint32_t TlvSize() const; -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - -virtual uint16_t TlvType() const { return mTlvType; } - -// These Functions need to be implemented. -//virtual void TlvClear() = 0; -//virtual std::ostream &print(std::ostream &out, uint16_t indent) = 0 const; - -virtual uint32_t TlvSizeUnit() const = 0; -virtual bool SetTlvUnit(void *data, uint32_t size, uint32_t *offset) const = 0; -virtual bool GetTlvUnit(void *data, uint32_t size, uint32_t *offset) = 0; - - - private: - uint16_t mTlvType; -}; - - diff --git a/libretroshare/src/serialiser/rstlvkeys.cc b/libretroshare/src/serialiser/rstlvkeys.cc deleted file mode 100644 index e2be0b666..000000000 --- a/libretroshare/src/serialiser/rstlvkeys.cc +++ /dev/null @@ -1,830 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvkeys.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rstlvkeys.h" -#include "rstlvbase.h" -#include "rsbaseserial.h" -#include "util/stacktrace.h" -#include "gxs/gxssecurity.h" - -#include - -// #define TLV_DEBUG 1 - -// This should be removed eventually, but will break backward compatibility -#define KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - -/************************************* RsTlvSecurityKey ************************************/ - -RsTlvRSAKey::RsTlvRSAKey() - :RsTlvItem(), keyFlags(0), startTS(0), endTS(0), keyData(TLV_TYPE_KEY_EVP_PKEY) -{ - return; -} - -void RsTlvRSAKey::TlvClear() -{ - keyId.clear(); - keyFlags = 0; - startTS = 0; - endTS = 0; - keyData.TlvClear(); -} - -/* clears keyData - but doesn't delete */ -void RsTlvRSAKey::ShallowClear() -{ - keyId.clear(); - keyFlags = 0; - startTS = 0; - endTS = 0; - keyData.bin_data = 0; - keyData.bin_len = 0; -} - -uint32_t RsTlvRSAKey::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */ - - /* now add comment and title length of this tlv object */ - -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - s += GetTlvStringSize(keyId.toStdString()) ; -#else - s += keyId.serial_size(); -#endif - s += 4; - s += 4; - s += 4; - s += keyData.TlvSize(); - - return s; -} - -bool RsTlvRSAKey::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { - std::cerr << "RsTlvSecurityKey::SetTlv() Failed not enough space"; - std::cerr << std::endl; - return false; /* not enough space */ - } - - bool ok = checkKey(); // check before serialise, just in case - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SECURITY_KEY, tlvsize); -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId.toStdString()); -#else - ok &= keyId.serialise(data, tlvend, *offset) ; -#endif - ok &= setRawUInt32(data, tlvend, offset, keyFlags); - ok &= setRawUInt32(data, tlvend, offset, startTS); - ok &= setRawUInt32(data, tlvend, offset, endTS); - ok &= keyData.SetTlv(data, tlvend, offset); - - return ok; - -} - -bool RsTlvRSAKey::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Fail, not enough space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - if (tlvtype != TLV_TYPE_SECURITY_KEY) /* check type */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Fail, wrong type"; - std::cerr << std::endl; -#endif - return false; - } - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - std::string s ; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s); - keyId = RsGxsId(s) ; -#else - ok &= keyId.deserialise(data, tlvend, *offset) ; -#endif - ok &= getRawUInt32(data, tlvend, offset, &(keyFlags)); - ok &= getRawUInt32(data, tlvend, offset, &(startTS)); - ok &= getRawUInt32(data, tlvend, offset, &(endTS)); - ok &= keyData.GetTlv(data, tlvend, offset); - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - if (!ok) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Failed somewhere ok == false"; - std::cerr << std::endl; -#endif - } - return ok && checkKey() ; -} - -/** - * @brief RsTlvRSAKey::getKeyTypeTlv: Deserialize data in temp value to get type of key. - * @param data: Serialized data - * @param size: Size of the data - * @param constoffset: Offset where find first data. Not updated by this function. - * @return The keyFlag filtered by RSTLV_KEY_TYPE_MASK. 0 if failed - */ -uint32_t RsTlvRSAKey::getKeyTypeTlv(void *data, uint32_t size, uint32_t *constoffset) const -{ - //Temporay Value. The same name than class to get same code than RsTlvRSAKey::GetTlv - uint32_t offValue = *constoffset; - uint32_t *offset = &offValue; - RsGxsId keyId; // Mandatory : - uint32_t keyFlags; // Mandatory ; - //The Code below have to be same as RsTlvRSAKey::GetTlv excepted last lines until flag is desserialized. - //Just comment TlvClear(); and unused values - - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Fail, not enough space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - if (tlvtype != TLV_TYPE_SECURITY_KEY) /* check type */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKey::GetTlv() Fail, wrong type"; - std::cerr << std::endl; -#endif - return false; - } - - bool ok = true; - - /* ready to load */ - //TlvClear();//RsTlvRSAKey::getKeyTypeTlv - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - std::string s ; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s); - keyId = RsGxsId(s) ; -#else - ok &= keyId.deserialise(data, tlvend, *offset) ; -#endif - ok &= getRawUInt32(data, tlvend, offset, &(keyFlags)); - //Stop here no need more data - //RsTlvRSAKey::getKeyTypeTlv specific lines - uint32_t ret = keyFlags & RSTLV_KEY_TYPE_MASK; - if (!ok) - { - ret = 0; -#ifdef TLV_DEBUG - std::cerr << "RsTlvRSAKey::getKeyTypeTlv() Failed somewhere ok == false" << std::endl; -#endif - } - return ret ; -} - -std::ostream& RsTlvRSAKey::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvSecurityKey", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "KeyId:" << keyId; - out << std::endl; - - printIndent(out, int_Indent); - out << "KeyFlags:" << keyFlags; - out << std::endl; - - printIndent(out, int_Indent); - out << "StartTS:" << startTS; - out << std::endl; - - printIndent(out, int_Indent); - out << "EndTS:" << endTS; - out << std::endl; - - keyData.print(out, int_Indent); - - out << std::endl; - - printEnd(out, "RsTlvSecurityKey", indent); - return out; -} - - -bool RsTlvPrivateRSAKey::checkKey() const -{ - bool keyFlags_TYPE_FULL = (keyFlags & RSTLV_KEY_TYPE_FULL); - if (!keyFlags_TYPE_FULL) {std::cout << "RsTlvPrivateRSAKey::checkKey() keyFlags not Type Full " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_FULL << std::dec << std::endl;} - bool keyFlags_not_PUBLIC_ONLY = !(keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY); - if (!keyFlags_not_PUBLIC_ONLY) {std::cout << "RsTlvPrivateRSAKey::checkKey() keyFlags is Public Only " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_PUBLIC_ONLY << std::dec << std::endl;} - bool security_OK = false; - if (keyFlags_TYPE_FULL && keyFlags_not_PUBLIC_ONLY) - { - //Don't trigg error if flags already wrong - security_OK = GxsSecurity::checkPrivateKey(*this); - if (!security_OK) {std::cout << "RsTlvPublicRSAKey::checkKey() key is not secure."<< std::endl;} - } - - return keyFlags_TYPE_FULL && keyFlags_not_PUBLIC_ONLY && security_OK ; -} - -bool RsTlvPublicRSAKey::checkKey() const -{ - bool keyFlags_PUBLIC_ONLY = (keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY); - if (!keyFlags_PUBLIC_ONLY) {std::cout << "RsTlvPublicRSAKey::checkKey() keyFlags not Public Only " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_PUBLIC_ONLY << std::dec << std::endl;} - bool keyFlags_not_TYPE_FULL = !(keyFlags & RSTLV_KEY_TYPE_FULL); - if (!keyFlags_not_TYPE_FULL) {std::cout << "RsTlvPublicRSAKey::checkKey() keyFlags is Type Full " << std::hex << keyFlags << " & " << RSTLV_KEY_TYPE_FULL << std::dec << std::endl;} - bool security_OK = false; - if (keyFlags_PUBLIC_ONLY && keyFlags_not_TYPE_FULL) - { - //Don't trigg error if flags already wrong - security_OK = GxsSecurity::checkPublicKey(*this); - if (!security_OK) {std::cout << "RsTlvPublicRSAKey::checkKey() key is not secure."<< std::endl;} - } - - return keyFlags_PUBLIC_ONLY && keyFlags_not_TYPE_FULL && security_OK ; -} - -/************************************* RsTlvSecurityKeySet ************************************/ - -void RsTlvSecurityKeySet::TlvClear() -{ - groupId.clear(); -#ifdef TODO - public_keys.clear(); //empty list - private_keys.clear(); //empty list -#endif -} - -uint32_t RsTlvSecurityKeySet::TlvSize() const -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - s += GetTlvStringSize(groupId); - - for(std::map::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it) - s += (it->second).TlvSize(); - - for(std::map::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it) - s += (it->second).TlvSize(); - - return s; -} - -bool RsTlvSecurityKeySet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKeySet::SetTlv() Failed not enough space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_SECURITYKEYSET , tlvsize); - - /* groupId */ - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GROUPID, groupId); - - for(std::map::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it) - ok &= (it->second).SetTlv(data, size, offset); - - for(std::map::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it) - ok &= (it->second).SetTlv(data, size, offset); - - return ok; -} - - -bool RsTlvSecurityKeySet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_SECURITYKEYSET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* groupId */ - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GROUPID, groupId); - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - // Security key set can be composed of public or private keys. We first ask type to desserialize in good one to not trigg errors. - switch(tlvsubtype) - { - case TLV_TYPE_SECURITY_KEY: - { - RsTlvPublicRSAKey gen_key; - uint32_t keyType = gen_key.getKeyTypeTlv(data, tlvend, offset); - if(keyType == RSTLV_KEY_TYPE_PUBLIC_ONLY) - { - - RsTlvPublicRSAKey public_key; - - if(public_key.GetTlv(data, tlvend, offset)) - public_keys[public_key.keyId] = public_key; - } - else if(keyType == RSTLV_KEY_TYPE_FULL) - { - - RsTlvPrivateRSAKey private_key; - - if(private_key.GetTlv(data, tlvend, offset)) - private_keys[private_key.keyId] = private_key; - } - } - break ; - - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - - } - - if (!ok) - break; - } - - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvSecurityKeySet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - - -// prints out contents of RsTlvSecurityKeySet -std::ostream &RsTlvSecurityKeySet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvSecurityKeySet", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "GroupId: " << groupId; - out << std::endl; - - for( std::map::const_iterator it = public_keys.begin(); it != public_keys.end() ; ++it) - (it->second).print(out, int_Indent); - for( std::map::const_iterator it = private_keys.begin(); it != private_keys.end() ; ++it) - (it->second).print(out, int_Indent); - - printEnd(out, "RsTlvSecurityKeySet", indent); - return out; -} - - -/************************************* RsTlvSecurityKey ************************************/ - -RsTlvKeySignature::RsTlvKeySignature() - :RsTlvItem(), signData(TLV_TYPE_SIGN_RSA_SHA1) -{ - ShallowClear() ; // avoids uninitialized memory if the fields are not initialized. -} - -void RsTlvKeySignature::TlvClear() -{ - keyId.clear(); - signData.TlvClear(); -} - -/* clears signData - but doesn't delete */ -void RsTlvKeySignature::ShallowClear() -{ - keyId.clear(); - signData.bin_data = 0; - signData.bin_len = 0; -} - -uint32_t RsTlvKeySignature::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + 4 for size */ - -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - s += GetTlvStringSize(keyId.toStdString()) ; -#else - s += keyId.serial_size() ; -#endif - s += signData.TlvSize(); - return s; - -} - -bool RsTlvKeySignature::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignature::SetTlv() Fail, not enough space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYSIGNATURE, tlvsize); - -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, keyId.toStdString()); -#else - ok &= keyId.serialise(data, tlvend, *offset) ; -#endif - ok &= signData.SetTlv(data, tlvend, offset); - - if (!ok) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignature::SetTlv() Failed somewhere"; - std::cerr << std::endl; -#endif - } - - return ok; - -} - - -bool RsTlvKeySignature::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignature::GetTlv() Not Enough Space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - if (tlvtype != TLV_TYPE_KEYSIGNATURE) /* check type */ - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignature::GetTlv() Type Fail"; - std::cerr << std::endl; -#endif - return false; - } - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - -#ifdef KEEP_OLD_SIGNATURE_SERIALISE_FORMAT - std::string s ; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEYID, s); - keyId = RsGxsId(s) ; -#else - ok &= keyId.deserialise(data, tlvend, *offset) ; -#endif - ok &= signData.GetTlv(data, tlvend, offset); - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignature::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvKeySignature::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvKeySignature", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "KeyId:" << keyId; - out << std::endl; - - signData.print(out, int_Indent); - - out << std::endl; - - printEnd(out, "RsTlvKeySignature", indent); - return out; -} - - -/************************************* RsTlvKeySignatureSet ************************************/ - -RsTlvKeySignatureSet::RsTlvKeySignatureSet() -{ - -} - -std::ostream &RsTlvKeySignatureSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvKeySignatureSet", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - - std::map::const_iterator mit = keySignSet.begin(); - - for(; mit != keySignSet.end(); ++mit) - { - out << "SignType: " << mit->first << std::endl; - const RsTlvKeySignature& sign = mit->second; - sign.print(out, indent); - } - - out << std::endl; - - printEnd(out, "RsTlvKeySignatureSet", indent); - return out; -} - -void RsTlvKeySignatureSet::TlvClear() -{ - keySignSet.clear(); -} - -bool RsTlvKeySignatureSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignatureSet::SetTlv() Failed not enough space"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYSIGNATURESET , tlvsize); - - - if(!keySignSet.empty()) - { - std::map::const_iterator it; - - for(it = keySignSet.begin(); it != keySignSet.end() ; ++it) - { - ok &= SetTlvUInt32(data, size, offset, TLV_TYPE_KEYSIGNATURETYPE, it->first); - ok &= (it->second).SetTlv(data, size, offset); - } - } - - -return ok; -} - -bool RsTlvKeySignatureSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_KEYSIGNATURESET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - SignType sign_type = 0; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - switch(tlvsubtype) - { - case TLV_TYPE_KEYSIGNATURE: - { - RsTlvKeySignature sign; - ok &= sign.GetTlv(data, size, offset); - if (ok) - { - keySignSet[sign_type] = sign; - } - } - break; - case TLV_TYPE_KEYSIGNATURETYPE: - { - ok = GetTlvUInt32(data, size, offset, TLV_TYPE_KEYSIGNATURETYPE, &sign_type); - } - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - } - - if (!ok) - break; - } - - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeySignatureSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -uint32_t RsTlvKeySignatureSet::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; // header size - std::map::const_iterator it; - - for(it = keySignSet.begin(); it != keySignSet.end() ; ++it) - { - s += GetTlvUInt32Size(); // sign type - s += it->second.TlvSize(); // signature - } - - return s; -} - - - - - - - - - - - - - - - - - - - - diff --git a/libretroshare/src/serialiser/rstlvkeys.h b/libretroshare/src/serialiser/rstlvkeys.h deleted file mode 100644 index 5f82e51f0..000000000 --- a/libretroshare/src/serialiser/rstlvkeys.h +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvkeys.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvbase.h" -#include "retroshare/rsgxsifacetypes.h" - -#include - -const uint32_t RSTLV_KEY_TYPE_MASK = 0x000f; -const uint32_t RSTLV_KEY_TYPE_PUBLIC_ONLY = 0x0001; -const uint32_t RSTLV_KEY_TYPE_FULL = 0x0002; - -const uint32_t RSTLV_KEY_DISTRIB_PUBLIC_deprecated = 0x0010;// was used as PUBLISH flag. Probably a typo. - -const uint32_t RSTLV_KEY_DISTRIB_PUBLISH = 0x0020; -const uint32_t RSTLV_KEY_DISTRIB_ADMIN = 0x0040; -const uint32_t RSTLV_KEY_DISTRIB_IDENTITY = 0x0080; -const uint32_t RSTLV_KEY_DISTRIB_MASK = 0x00f0; - -// Old class for RsTlvSecurityKey. Is kept for backward compatibility, but should not be serialised anymore - -class RsTlvRSAKey: public RsTlvItem -{ -public: - RsTlvRSAKey(); - virtual bool checkKey() const = 0 ; // this pure virtual forces people to explicitly declare if they use a public or a private key. - - virtual uint32_t TlvSize() const; - virtual void TlvClear(); - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - virtual std::ostream& print(std::ostream &out, uint16_t indent) const; - - /* clears KeyData - but doesn't delete - to transfer ownership */ - void ShallowClear(); - - uint32_t getKeyTypeTlv(void *data, uint32_t size, uint32_t *offset) const; - - RsGxsId keyId; // Mandatory : - uint32_t keyFlags; // Mandatory ; - uint32_t startTS; // Mandatory : - uint32_t endTS; // Mandatory : - RsTlvBinaryData keyData; // Mandatory : -}; - -// The two classes below are by design incompatible, making it impossible to pass a private key as a public key - -class RsTlvPrivateRSAKey: public RsTlvRSAKey -{ -public: - RsTlvPrivateRSAKey():RsTlvRSAKey() {} - virtual ~RsTlvPrivateRSAKey() {} - - virtual bool checkKey() const ; -}; -class RsTlvPublicRSAKey: public RsTlvRSAKey -{ -public: - RsTlvPublicRSAKey():RsTlvRSAKey() {} - virtual ~RsTlvPublicRSAKey() {} - - virtual bool checkKey() const ; -}; - -class RsTlvSecurityKeySet: public RsTlvItem -{ -public: - RsTlvSecurityKeySet() { return; } - virtual ~RsTlvSecurityKeySet() { return; } - - // creates the public keys that are possible missing although the private keys are present. - - void createPublicFromPrivateKeys(); - - virtual uint32_t TlvSize() const; - virtual void TlvClear(); - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::string groupId; // Mandatory : - std::map public_keys; // Mandatory : - std::map private_keys; // Mandatory : -}; - - -class RsTlvKeySignature: public RsTlvItem -{ - public: - RsTlvKeySignature(); - virtual ~RsTlvKeySignature() { return; } - virtual uint32_t TlvSize() const; - virtual void TlvClear(); - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - void ShallowClear(); /* clears signData - but doesn't delete */ - - RsGxsId keyId; // Mandatory : - RsTlvBinaryData signData; // Mandatory : -}; - -typedef uint32_t SignType; - -class RsTlvKeySignatureSet : public RsTlvItem -{ -public: - RsTlvKeySignatureSet(); - virtual ~RsTlvKeySignatureSet() { return; } - virtual uint32_t TlvSize() const; - virtual void TlvClear(); - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); - virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::map keySignSet; // mandatory -}; - - diff --git a/libretroshare/src/serialiser/rstlvkeyvalue.cc b/libretroshare/src/serialiser/rstlvkeyvalue.cc deleted file mode 100644 index c666307ef..000000000 --- a/libretroshare/src/serialiser/rstlvkeyvalue.cc +++ /dev/null @@ -1,295 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvkeyvalue.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rstlvkeyvalue.h" -#include "rstlvbase.h" - -// #define TLV_DEBUG 1 - -void RsTlvKeyValue::TlvClear() -{ - key = ""; - value = ""; -} - -uint32_t RsTlvKeyValue::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* now add comment and title length of this tlv object */ - - if (key.length() > 0) - s += GetTlvStringSize(key); - if (value.length() > 0) - s += GetTlvStringSize(value); - - return s; - -} - -bool RsTlvKeyValue::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYVALUE, tlvsize); - - - - /* now optional ones */ - if (key.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEY, key); // no base tlv type for title? - if (value.length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_VALUE, value); // no base tlv type for comment? - -return ok; - -} - -bool RsTlvKeyValue::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_KEYVALUE) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - switch(tlvsubtype) - { - case TLV_TYPE_STR_KEY: - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_KEY, key); - break; - case TLV_TYPE_STR_VALUE: - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_VALUE, value); - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - - } - - if (!ok) - { - break; - } - } - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeyValue::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - -std::ostream &RsTlvKeyValue::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvKeyValue", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "Key:" << key; - printIndent(out, int_Indent); - out << "Value:" << value; - out << std::endl; - - - printEnd(out, "RsTlvKeyValue", indent); - return out; -} - -/************************************* RsTlvKeyValueSet ************************************/ - -void RsTlvKeyValueSet::TlvClear() -{ - pairs.clear(); //empty list -} - -uint32_t RsTlvKeyValueSet::TlvSize() const -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - std::list::const_iterator it; - - if(!pairs.empty()) - { - - for(it = pairs.begin(); it != pairs.end() ; ++it) - s += it->TlvSize(); - - } - - return s; -} - -bool RsTlvKeyValueSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_KEYVALUESET , tlvsize); - - - if(!pairs.empty()) - { - std::list::const_iterator it; - - for(it = pairs.begin(); it != pairs.end() ; ++it) - ok &= it->SetTlv(data, size, offset); - } - - -return ok; - -} - - -bool RsTlvKeyValueSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_KEYVALUESET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - switch(tlvsubtype) - { - case TLV_TYPE_KEYVALUE: - { - RsTlvKeyValue kv; - ok &= kv.GetTlv(data, size, offset); - if (ok) - { - pairs.push_back(kv); - } - } - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - - } - - if (!ok) - break; - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvKeyValueSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -/// prints out contents of RsTlvKeyValueSet -std::ostream &RsTlvKeyValueSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvKeyValue", indent); - - std::list::const_iterator it; - - for(it = pairs.begin(); it != pairs.end() ; ++it) - it->print(out, indent); - - printEnd(out, "RsTlvKeyValue", indent); - return out; -} - diff --git a/libretroshare/src/serialiser/rstlvkeyvalue.h b/libretroshare/src/serialiser/rstlvkeyvalue.h deleted file mode 100644 index 63cf3091f..000000000 --- a/libretroshare/src/serialiser/rstlvkeyvalue.h +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvkeyvalue.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include - -class RsTlvKeyValue: public RsTlvItem -{ - public: - RsTlvKeyValue() { return; } - RsTlvKeyValue(const std::string& k,const std::string& v): key(k),value(v) {} -virtual ~RsTlvKeyValue() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::string key; /// Mandatory : For use in hash tables - std::string value; /// Mandatory : For use in hash tables -}; - -class RsTlvKeyValueSet: public RsTlvItem -{ - public: - RsTlvKeyValueSet() { return; } -virtual ~RsTlvKeyValueSet() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - std::list pairs; /// For use in hash tables -}; - - diff --git a/libretroshare/src/serialiser/rstlvlist.h b/libretroshare/src/serialiser/rstlvlist.h deleted file mode 100644 index 90c430ede..000000000 --- a/libretroshare/src/serialiser/rstlvlist.h +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvlist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvitem.h" - -#include - -// #define TLV_DEBUG_LIST 1 - -template class t_RsTlvList: public RsTlvItem -{ - public: - t_RsTlvList() {} - virtual ~t_RsTlvList() {} - - virtual uint32_t TlvSize() const - { - uint32_t size = TLV_HEADER_SIZE; - typename std::list::const_iterator it; - for(it = mList.begin();it != mList.end(); ++it) - { - size += it->TlvSize(); - } - return size; - } - virtual void TlvClear(){ mList.clear(); } - virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const - { - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - /* must check sizes */ - - if (size < tlvend) - { -#ifdef TLV_DEBUG_LIST - std::cerr << "RsTlvList::SetTlv() Not enough size"; - std::cerr << std::endl; -#endif - return false; /* not enough space */ - } - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE, tlvsize); - - typename std::list::const_iterator it; - for(it = mList.begin();it != mList.end(); ++it) - { - ok &= it->SetTlv(data,tlvend,offset) ; - } - return ok ; - } - virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset) - { - if (size < *offset + TLV_HEADER_SIZE) - { -#ifdef TLV_DEBUG_LIST - std::cerr << "RsTlvList::GetTlv() Not enough size"; - std::cerr << std::endl; -#endif - return false; - } - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV : 2 (type) + 4 (len) */ - while(ok && ((*offset) + 6 < tlvend)) - { - TLV_CLASS item; - ok &= item.GetTlv(data,tlvend,offset); - if (ok) - { - mList.push_back(item); - } - } - - if(*offset != tlvend) - { - std::cerr << "(EE) deserialisation error in " << __PRETTY_FUNCTION__ << std::endl; - } - return *offset == tlvend ; - } - - virtual std::ostream &print(std::ostream &out, uint16_t indent) const - { - printBase(out, "Template TlvList", indent); - typename std::list::const_iterator it; - for(it = mList.begin();it != mList.end(); ++it) - { - it->print(out, indent + 2) ; - } - printEnd(out, "Template TlvList", indent); - return out ; - } - - std::list mList; -}; - - - diff --git a/libretroshare/src/serialiser/rstlvmaps.h b/libretroshare/src/serialiser/rstlvmaps.h deleted file mode 100644 index 49b05e382..000000000 --- a/libretroshare/src/serialiser/rstlvmaps.h +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvmaps.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_TLV_MAPS_H -#define RS_TLV_MAPS_H - -class RsTlvOpinionMapRef: public RsTlvGenericMapRef -{ -public: - RsTlvOpinionMapRef(std::map &refmap) - :RsTlvGenericMapRef(OPINION, STRING_INT_PAIR, refmap) { return; } -}; - - -#endif - diff --git a/libretroshare/src/serialiser/rstlvstring.cc b/libretroshare/src/serialiser/rstlvstring.cc deleted file mode 100644 index d1e636d52..000000000 --- a/libretroshare/src/serialiser/rstlvstring.cc +++ /dev/null @@ -1,371 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvstring.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rstlvstring.h" - -#include "serialiser/rstlvbase.h" -#include "util/rsprint.h" -#include - -// #define TLV_DEBUG 1 - -/************************************* Peer Id Set ************************************/ - - -RsTlvStringSet::RsTlvStringSet(uint16_t type) :mType(type) -{ -} - - -bool RsTlvStringSet::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize); - - /* determine the total size of ids strings in list */ - - std::list::const_iterator it; - - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (it->length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it); - } - - return ok; - -} - - -void RsTlvStringSet::TlvClear() -{ - ids.clear(); - -} - -uint32_t RsTlvStringSet::TlvSize() const -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* determine the total size of ids strings in list */ - - std::list::const_iterator it; - - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (it->length() > 0) - s += GetTlvStringSize(*it); - } - - return s; -} - - -bool RsTlvStringSet::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != mType) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - - -/* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - if (tlvsubtype == TLV_TYPE_STR_GENID) - { - std::string newIds; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds); - if(ok) - { - ids.push_back(newIds); - - } - } - else - { - /* Step past unknown TLV TYPE */ - ok &= SkipUnknownTlv(data, tlvend, offset); - } - - if (!ok) - { - break; - } - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvPeerIdSet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -/// print to screen RsTlvStringSet contents -std::ostream &RsTlvStringSet::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvStringSet", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "type:" << mType; - out << std::endl; - - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - printIndent(out, int_Indent); - out << "id:" << *it; - out << std::endl; - } - - printEnd(out, "RsTlvStringSet", indent); - return out; - -} - -/// print to screen RsTlvStringSet contents -std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvStringSet", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "type:" << mType; - out << std::endl; - - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - printIndent(out, int_Indent); - out << "id: 0x" << RsUtil::BinToHex(*it); - out << std::endl; - } - - printEnd(out, "RsTlvStringSet", indent); - return out; - -} - - -/************************************* String Set Ref ************************************/ -/* This is exactly the same as StringSet, but it uses an alternative list. - */ -RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list &refids) - :mType(type), ids(refids) -{ -} - -void RsTlvStringSetRef::TlvClear() -{ - ids.clear(); - -} - -uint32_t RsTlvStringSetRef::TlvSize() const -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - /* determine the total size of ids strings in list */ - - std::list::const_iterator it; - - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (it->length() > 0) - s += GetTlvStringSize(*it); - } - - return s; -} - - -bool RsTlvStringSetRef::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize); - - /* determine the total size of ids strings in list */ - - std::list::const_iterator it; - - for(it = ids.begin(); it != ids.end() ; ++it) - { - if (it->length() > 0) - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it); - } - - return ok; - -} - - -bool RsTlvStringSetRef::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != mType) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - - -/* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - if (tlvsubtype == TLV_TYPE_STR_GENID) - { - std::string newIds; - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds); - if(ok) - { - ids.push_back(newIds); - - } - } - else - { - /* Step past unknown TLV TYPE */ - ok &= SkipUnknownTlv(data, tlvend, offset); - } - - if (!ok) - { - break; - } - } - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvPeerIdSetRef::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -/// print to screen RsTlvStringSet contents -std::ostream &RsTlvStringSetRef::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvStringSetRef", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "type:" << mType; - out << std::endl; - - std::list::const_iterator it; - for(it = ids.begin(); it != ids.end() ; ++it) - { - printIndent(out, int_Indent); - out << "id:" << *it; - out << std::endl; - } - - printEnd(out, "RsTlvStringSetRef", indent); - return out; - -} - diff --git a/libretroshare/src/serialiser/rstlvstring.h b/libretroshare/src/serialiser/rstlvstring.h deleted file mode 100644 index 5e0c2f276..000000000 --- a/libretroshare/src/serialiser/rstlvstring.h +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstlvstring.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Robert Fernie,Chris Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - * - ******************************************************************/ - -#include "serialiser/rstlvitem.h" - -#include - -class RsTlvStringSet: public RsTlvItem -{ - public: -explicit RsTlvStringSet(uint16_t type); -virtual ~RsTlvStringSet() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; -virtual std::ostream &printHex(std::ostream &out, uint16_t indent) const; - - uint16_t mType; - std::list ids; /* Mandatory */ -}; - -class RsTlvStringSetRef: public RsTlvItem -{ - public: - RsTlvStringSetRef(uint16_t type, std::list &refids); -virtual ~RsTlvStringSetRef() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint16_t mType; - std::list &ids; /* Mandatory */ -}; - - diff --git a/libretroshare/src/serialiser/rstypeserializer.cc b/libretroshare/src/serialiser/rstypeserializer.cc deleted file mode 100644 index 0c7bfc435..000000000 --- a/libretroshare/src/serialiser/rstypeserializer.cc +++ /dev/null @@ -1,712 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstypeserializer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Cyril Soler * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "serialiser/rsserializer.h" -#include "serialiser/rstypeserializer.h" -#include "serialiser/rsbaseserial.h" -#include "serialiser/rstlvkeys.h" -#include "serialiser/rsserializable.h" -#include "util/rsbase64.h" -#include "util/rsprint.h" -#include "util/rstime.h" - -#include -#include -#include // for typeid -#include - -#ifdef RSSERIAL_DEBUG -# define SAFE_GET_JSON_V() \ - const char* mName = memberName.c_str(); \ - bool ret = jDoc.HasMember(mName); \ - if(!ret) \ - { \ - std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName \ - << "\" not found in JSON:" << std::endl \ - << jDoc << std::endl << std::endl; \ - return false; \ - } \ - rapidjson::Value& v = jDoc[mName] -#else // ifdef RSSERIAL_DEBUG -# define SAFE_GET_JSON_V() \ - const char* mName = memberName.c_str(); \ - bool ret = jDoc.HasMember(mName); \ - if(!ret) return false; \ - rapidjson::Value& v = jDoc[mName] -#endif // ifdef RSSERIAL_DEBUG - -//============================================================================// -// std::string // -//============================================================================// - -template<> /*static*/ -bool RsTypeSerializer::to_JSON( const std::string& membername, - const std::string& member, RsJson& jDoc ) -{ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); - - rapidjson::Value key; - key.SetString( membername.c_str(), - static_cast(membername.length()), - allocator ); - - rapidjson::Value value; - value.SetString( member.c_str(), - static_cast(member.length()), - allocator ); - - jDoc.AddMember(key, value, allocator); - - return true; -} -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - std::string& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsString(); - if(ret) member = v.GetString(); - return ret; -} - - -//============================================================================// -// Integral types // -//============================================================================// - -#define SIMPLE_TO_JSON_DEF(T) \ -template<> bool RsTypeSerializer::to_JSON( const std::string& memberName, \ - const T& member, RsJson& jDoc ) \ -{ \ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); \ - \ - rapidjson::Value key; \ - key.SetString( memberName.c_str(), \ - static_cast(memberName.length()), \ - allocator ); \ - \ - rapidjson::Value value(member); \ - \ - jDoc.AddMember(key, value, allocator); \ - \ - return true; \ -} - -SIMPLE_TO_JSON_DEF(bool) -SIMPLE_TO_JSON_DEF(int32_t) - -SIMPLE_TO_JSON_DEF(uint8_t) -SIMPLE_TO_JSON_DEF(uint16_t) -SIMPLE_TO_JSON_DEF(uint32_t) - -/** Be very careful in changing this constant as it would break 64 bit integers - * members JSON string representation retrocompatibility */ -static constexpr char strReprKey[] = "xstr64"; - -/** Be very careful in changing this constant as it would break 64 bit integers - * members JSON string representation retrocompatibility */ -static constexpr char intReprKey[] = "xint64"; - -/** While JSON doesn't have problems representing 64 bits integers JavaScript, - * Dart and other languages represents numbers in a double-like format thus they - * are not capable to handle safely integers outside the range - * [-(2^53 - 1), 2^53 - 1]. - * To overcome this limitation we represent 64 bit integers as an object with - * two keys, one as integer and one as string representation. - * In our case we need to wrap those into an object instead of just adding a key - * with a suffix so support well also containers like std::map or std::vector. - * More discussion on the topic at @see https://stackoverflow.com/a/34989371 - */ -#define SIXTYFOUR_INTEGERS_TO_JSON_DEF(T) \ -template<> bool RsTypeSerializer::to_JSON( const std::string& memberName, \ - const T& member, RsJson& jDoc ) \ -{ \ - using namespace rapidjson; \ - Document::AllocatorType& allocator = jDoc.GetAllocator(); \ - \ - Document wrapper(rapidjson::kObjectType, &allocator); \ - \ - Value intKey; \ - intKey.SetString(intReprKey, allocator ); \ - Value intValue(member); \ - wrapper.AddMember(intKey, intValue, allocator); \ - \ - bool ok = to_JSON(strReprKey, std::to_string(member), wrapper); \ - \ - Value key; \ - key.SetString( memberName.c_str(), \ - static_cast(memberName.length()), \ - allocator ); \ - jDoc.AddMember(key, wrapper, allocator); \ - \ - return ok; \ -} - -SIXTYFOUR_INTEGERS_TO_JSON_DEF(int64_t); -SIXTYFOUR_INTEGERS_TO_JSON_DEF(uint64_t); - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, bool& member, - RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsBool(); - if(ret) member = v.GetBool(); - return ret; -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - int32_t& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsInt(); - if(ret) member = v.GetInt(); - return ret; -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - uint8_t& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsUint(); - if(ret) member = static_cast(v.GetUint()); - return ret; -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - uint16_t& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsUint(); - if(ret) member = static_cast(v.GetUint()); - return ret; -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - uint32_t& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsUint(); - if(ret) member = v.GetUint(); - return ret; -} - -/** inverse of @see SIXTYFOUR_INTEGERS_TO_JSON_DEF */ -#define SIXTYFOUR_INTEGERS_FROM_JSON_DEF(T, PRED, GET, CONV) \ -template<> bool RsTypeSerializer::from_JSON( \ - const std::string& memberName, T& member, RsJson& jDoc ) \ -{ \ - using namespace rapidjson; \ - \ - SAFE_GET_JSON_V(); \ - \ - /* For retro-compatibility take it directly if it is passed as integer */ \ - if(v.PRED()) \ - { \ - member = v.GET(); \ - return true; \ - } \ - \ - ret = ret && v.IsObject(); \ - \ - if(!ret) \ - { \ - RS_DBG3(memberName, " not found"); \ - return false; \ - } \ - \ - if(v.HasMember(intReprKey)) \ - { \ - Value& iVal = v[intReprKey]; \ - if(iVal.PRED()) \ - { \ - member = iVal.GET(); \ - return true; \ - } \ - } \ - \ - Dbg4() << __PRETTY_FUNCTION__ << " integer representation of " << memberName \ - << " not found in JSON then attempt to look for string representation" \ - << std::endl; \ - \ - \ - if(v.HasMember(strReprKey)) \ - { \ - Value& sVal = v[strReprKey]; \ - if(sVal.IsString()) \ - { \ - try { member = CONV(sVal.GetString()); } \ - catch (...) \ - { \ - RsErr() << __PRETTY_FUNCTION__ << " cannot convert " \ - << sVal.GetString() << " to integral type" << std::endl; \ - return false; \ - } \ - \ - return true; \ - } \ - } \ - \ - Dbg3() << __PRETTY_FUNCTION__ << " neither integral representation nor " \ - << "string representation found for: " << memberName << std::endl; \ - \ - return false; \ -} - -SIXTYFOUR_INTEGERS_FROM_JSON_DEF(uint64_t, IsUint64, GetUint64, std::stoull) -SIXTYFOUR_INTEGERS_FROM_JSON_DEF( int64_t, IsInt64, GetInt64, std::stoll) - -//============================================================================// -// Floats // -//============================================================================// - -template<> uint32_t RsTypeSerializer::serial_size(const float&){ return 4; } - -template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t& offset, const float& f) -{ - return setRawUFloat32(data,size,&offset,f) ; -} -template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size, uint32_t &offset, float& f) -{ - return getRawUFloat32(data,size,&offset,f) ; -} -template<> void RsTypeSerializer::print_data(const std::string& n, const float& V) -{ - std::cerr << " [float ] " << n << ": " << V << std::endl; -} - -SIMPLE_TO_JSON_DEF(float) - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - float& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsFloat(); - if(ret) member = v.GetFloat(); - return ret; -} - -template<> /*static*/ -uint32_t RsTypeSerializer::serial_size(const double&) -{ - std::cerr << "Binary [de]serialization not implemented yet for double" - << std::endl; - print_stacktrace(); - return 0; -} - -template<> /*static*/ -bool RsTypeSerializer::serialize(uint8_t[], uint32_t, uint32_t&, const double&) -{ - std::cerr << "Binary [de]serialization not implemented yet for double" - << std::endl; - print_stacktrace(); - return false; -} - -template<> /*static*/ -bool RsTypeSerializer::deserialize(const uint8_t[], uint32_t, uint32_t&, double&) -{ - std::cerr << "Binary [de]serialization not implemented yet for double" - << std::endl; - print_stacktrace(); - return false; -} - -template<> /*static*/ -void RsTypeSerializer::print_data(const std::string& n, const double& V) -{ std::cerr << " [double ] " << n << ": " << V << std::endl; } - -SIMPLE_TO_JSON_DEF(double) - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - double& member, RsJson& jDoc ) -{ - SAFE_GET_JSON_V(); - ret = ret && v.IsDouble(); - if(ret) member = v.GetDouble(); - return ret; -} - - -//============================================================================// -// TlvString with subtype // -//============================================================================// - -template<> uint32_t RsTypeSerializer::serial_size(uint16_t /* type_subtype */,const std::string& s) -{ - return GetTlvStringSize(s) ; -} - -template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, uint32_t &offset,uint16_t type_substring,const std::string& s) -{ - return SetTlvString(data,size,&offset,type_substring,s) ; -} - -template<> bool RsTypeSerializer::deserialize(const uint8_t data[], uint32_t size,uint32_t& offset,uint16_t type_substring,std::string& s) -{ - return GetTlvString((void*)data,size,&offset,type_substring,s) ; -} - -template<> void RsTypeSerializer::print_data(const std::string& n, uint16_t type_substring,const std::string& V) -{ - std::cerr << " [TlvString ] " << n << ": type=" << std::hex < /*static*/ -bool RsTypeSerializer::to_JSON( const std::string& memberName, - uint16_t /*sub_type*/, - const std::string& member, RsJson& jDoc ) -{ - return to_JSON(memberName, member, jDoc); -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - uint16_t /*sub_type*/, - std::string& member, RsJson& jDoc ) -{ - return from_JSON(memberName, member, jDoc); -} - -//============================================================================// -// TlvInt with subtype // -//============================================================================// - -template<> uint32_t RsTypeSerializer::serial_size( uint16_t /* type_subtype */, - const uint32_t& /*s*/ ) -{ - return GetTlvUInt32Size(); -} - -template<> bool RsTypeSerializer::serialize( uint8_t data[], uint32_t size, - uint32_t &offset,uint16_t sub_type, - const uint32_t& s) -{ - return SetTlvUInt32(data,size,&offset,sub_type,s); -} - -template<> bool RsTypeSerializer::deserialize( const uint8_t data[], - uint32_t size, uint32_t& offset, - uint16_t sub_type, uint32_t& s) -{ - return GetTlvUInt32((void*)data, size, &offset, sub_type, &s); -} - -template<> void RsTypeSerializer::print_data(const std::string& n, uint16_t sub_type,const uint32_t& V) -{ - std::cerr << " [TlvUInt32 ] " << n << ": type=" << std::hex - << std::setw(4) << std::setfill('0') << sub_type << std::dec - << " s=\"" << V << "\"" << std::endl; -} - -template<> /*static*/ -bool RsTypeSerializer::to_JSON( const std::string& memberName, - uint16_t /*sub_type*/, - const uint32_t& member, RsJson& jDoc ) -{ - return to_JSON(memberName, member, jDoc); -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& memberName, - uint16_t /*sub_type*/, - uint32_t& member, RsJson& jDoc ) -{ - return from_JSON(memberName, member, jDoc); -} - - -//============================================================================// -// TlvItems // -//============================================================================// - -template<> uint32_t RsTypeSerializer::serial_size(const RsTlvItem& s) -{ - return s.TlvSize(); -} - -template<> bool RsTypeSerializer::serialize(uint8_t data[], uint32_t size, - uint32_t &offset,const RsTlvItem& s) -{ - return s.SetTlv(data,size,&offset); -} - -template<> bool RsTypeSerializer::deserialize(const uint8_t data[], - uint32_t size,uint32_t& offset, - RsTlvItem& s) -{ - return s.GetTlv((void*)data,size,&offset) ; -} - -template<> void RsTypeSerializer::print_data( const std::string& n, - const RsTlvItem& s ) -{ - std::cerr << " [" << typeid(s).name() << "] " << n << std::endl; -} - -template<> /*static*/ -bool RsTypeSerializer::to_JSON( const std::string& memberName, - const RsTlvItem& member, RsJson& jDoc ) -{ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); - - rapidjson::Value key; - key.SetString(memberName.c_str(), memberName.length(), allocator); - - rapidjson::Value value; - const char* tName = typeid(member).name(); - value.SetString(tName, allocator); - - jDoc.AddMember(key, value, allocator); - - return true; -} - -template<> /*static*/ -bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/, - RsTlvItem& member, RsJson& /*jDoc*/) -{ - member.TlvClear(); - return true; -} - - -//============================================================================// -// Binary blocks // -//============================================================================// - -#if __cplusplus < 201703L -/* Solve weird undefined reference error with C++ < 17 see: - * https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char - */ -/*static*/ decltype(RsTypeSerializer::RawMemoryWrapper::base64_key) constexpr -RsTypeSerializer::RawMemoryWrapper::base64_key; - -/*static*/ /* without this Android compilation breaks */ -constexpr uint32_t RsTypeSerializer::RawMemoryWrapper::MAX_SERIALIZED_CHUNK_SIZE; -#endif - -/*static*/ -void RsTypeSerializer::RawMemoryWrapper::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: - RS_SERIAL_PROCESS(second); - ctx.mOffset += second; - break; - case RsGenericSerializer::SERIALIZE: - if(!ctx.mOk) break; - if(second > MAX_SERIALIZED_CHUNK_SIZE) - { - RsErr() << __PRETTY_FUNCTION__ - << std::errc::message_size << " " - << second << " > " << MAX_SERIALIZED_CHUNK_SIZE - << std::endl; - print_stacktrace(); - break; - } - RS_SERIAL_PROCESS(second); - if(!ctx.mOk) break; - ctx.mOk = ctx.mSize >= ctx.mOffset + second; - if(!ctx.mOk) - { - RsErr() << __PRETTY_FUNCTION__ << std::errc::no_buffer_space - << std::endl; - print_stacktrace(); - break; - } - memcpy(ctx.mData + ctx.mOffset, first, second); - ctx.mOffset += second; - break; - case RsGenericSerializer::DESERIALIZE: - freshMemCheck(); - - RS_SERIAL_PROCESS(second); - if(!ctx.mOk) break; - ctx.mOk = (second <= MAX_SERIALIZED_CHUNK_SIZE); - if(!ctx.mOk) - { - RsErr() << __PRETTY_FUNCTION__ - << std::errc::message_size << " " - << second << " > " << MAX_SERIALIZED_CHUNK_SIZE - << std::endl; - clear(); - break; - } - - if(!second) - { - Dbg3() << __PRETTY_FUNCTION__ << " Deserialized empty memory chunk" - << std::endl; - clear(); - break; - } - - ctx.mOk = ctx.mSize >= ctx.mOffset + second; - if(!ctx.mOk) - { - RsErr() << __PRETTY_FUNCTION__ << std::errc::no_buffer_space - << std::endl; - print_stacktrace(); - - clear(); - break; - } - - first = reinterpret_cast(malloc(second)); - memcpy(first, ctx.mData + ctx.mOffset, second); - ctx.mOffset += second; - break; - case RsGenericSerializer::PRINT: break; - case RsGenericSerializer::TO_JSON: - { - if(!ctx.mOk) break; - std::string encodedValue; - RsBase64::encode(first, second, encodedValue, true, false); - ctx.mOk = ctx.mOk && - RsTypeSerializer::to_JSON(base64_key, encodedValue, ctx.mJson); - break; - } - case RsGenericSerializer::FROM_JSON: - { - freshMemCheck(); - - const auto failure = [&]() -> void { ctx.mOk = false; clear(); }; - const bool yielding = !!( - RsSerializationFlags::YIELDING & ctx.mFlags ); - if(!(ctx.mOk || yielding)) return failure(); - - std::string encodedValue; - if(!RsTypeSerializer::from_JSON( - base64_key, encodedValue, ctx.mJson )) return failure(); - - if( encodedValue.length() > - RsBase64::encodedSize(MAX_SERIALIZED_CHUNK_SIZE, true) ) - { - RsErr() << __PRETTY_FUNCTION__ << " " - << std::errc::message_size << std::endl; - print_stacktrace(); - - return failure(); - } - - std::vector decoded; - auto ec = RsBase64::decode(encodedValue, decoded); - if(ec) - { - RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl; - print_stacktrace(); - - return failure(); - } - - const auto decodedSize = decoded.size(); - - if(!decodedSize) - { - clear(); - break; - } - - first = reinterpret_cast(malloc(decodedSize)); - second = static_cast(decodedSize); - - memcpy(first, decoded.data(), second); - break; - } - default: RsTypeSerializer::fatalUnknownSerialJob(j); - } -} - -void RsTypeSerializer::RawMemoryWrapper::clear() -{ - free(first); - first = nullptr; - second = 0; -} - -bool RsTypeSerializer::RawMemoryWrapper::freshMemCheck() -{ - if(first || second) - { - /* Items are created anew before deserialization so buffer pointer - * must be null and size 0 at this point */ - - RsWarn() << __PRETTY_FUNCTION__ << " got uninitialized " - << " or pre-allocated buffer! Buffer pointer: " << first - << " must be null and size: " << second << " must be 0 at " - << "this point. Does your item costructor initialize them " - << "properly?" << std::endl; - print_stacktrace(); - return false; - } - return true; -} - -//============================================================================// -// std::error_condition // -//============================================================================// - -void RsTypeSerializer::ErrConditionWrapper::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: // fallthrough - case RsGenericSerializer::DESERIALIZE: // fallthrough - case RsGenericSerializer::SERIALIZE: // fallthrough - case RsGenericSerializer::FROM_JSON: // [[fallthrough]] - case RsGenericSerializer::PRINT: - RsFatal() << __PRETTY_FUNCTION__ << " SerializeJob: " << j - << "is not supported on std::error_condition " << std::endl; - print_stacktrace(); - exit(-2); - case RsGenericSerializer::TO_JSON: - { - constexpr RsGenericSerializer::SerializeJob rj = - RsGenericSerializer::TO_JSON; - - int32_t tNum = mec.value(); - RsTypeSerializer::serial_process(rj, ctx, tNum, "errorNumber"); - - std::string tStr = mec.category().name(); - RsTypeSerializer::serial_process(rj, ctx, tStr, "errorCategory"); - - tStr = mec.message(); - RsTypeSerializer::serial_process(rj, ctx, tStr, "errorMessage"); - break; - } - default: RsTypeSerializer::fatalUnknownSerialJob(j); - } -} diff --git a/libretroshare/src/serialiser/rstypeserializer.h b/libretroshare/src/serialiser/rstypeserializer.h deleted file mode 100644 index 6474f6971..000000000 --- a/libretroshare/src/serialiser/rstypeserializer.h +++ /dev/null @@ -1,1369 +0,0 @@ -/******************************************************************************* - * libretroshare/src/serialiser: rstypeserializer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Cyril Soler * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include // for typeid -#include -#include -#include -#include -#include - -#include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvlist.h" -#include "retroshare/rsflags.h" -#include "retroshare/rsids.h" -#include "util/rsendian.h" -#include "serialiser/rsserializer.h" -#include "serialiser/rsserializable.h" -#include "util/rsjson.h" -#include "util/rsdebuglevel1.h" -#include "util/cxx14retrocompat.h" - - -struct RsTypeSerializer -{ - /** Use this wrapper to serialize raw memory chunks - * RsTypeSerializer::RawMemoryWrapper chunkWrapper(chunk_data, chunk_size); - * RsTypeSerializer::serial_process(j, ctx, chunkWrapper, "chunk_data"); - **/ - struct RawMemoryWrapper: std::pair, RsSerializable - { - RawMemoryWrapper(uint8_t*& p,uint32_t& s) : - std::pair(p,s) {} - RawMemoryWrapper(void*& p, uint32_t& s) : - std::pair(*(uint8_t**)(&p),s) {} - - /// Maximum supported size 10MB - static constexpr uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024; - - /** Key used for JSON serialization. - * @note Changing this value breaks JSON API retro-compatibility */ - static constexpr char base64_key[] = "base64"; - - /// @see RsSerializable - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - private: - void clear(); - bool freshMemCheck(); - }; - - /// Most types are not valid sequence containers - template - struct is_sequence_container : std::false_type {}; - - /// Trait to match supported strings types - template - struct is_string : std::is_same, std::string> {}; - - /// Integral types - template - typename std::enable_if::value>::type - static /*void*/ serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - INTT& member, const std::string& member_name ) - { - const bool VLQ_ENCODING = !!( - RsSerializationFlags::INTEGER_VLQ & ctx.mFlags ); - - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: - if(VLQ_ENCODING) ctx.mOffset += VLQ_size(member); - else ctx.mOffset += sizeof(INTT); - break; - case RsGenericSerializer::SERIALIZE: - { - if(!ctx.mOk) break; - if(VLQ_ENCODING) - ctx.mOk = VLQ_serialize( - ctx.mData, ctx.mSize, ctx.mOffset, member ); - else - { - ctx.mOk = ctx.mSize >= ctx.mOffset + sizeof(INTT); - if(!ctx.mOk) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot serialise " - << typeid(INTT).name() << " " - << " ctx.mSize: " << ctx.mSize - << " ctx.mOffset: " << ctx.mOffset - << " sizeof(INTT): " << sizeof(INTT) - << std::error_condition(std::errc::no_buffer_space) - << std::endl; - print_stacktrace(); - break; - } - INTT netorder_num = rs_endian_fix(member); - memcpy(ctx.mData + ctx.mOffset, &netorder_num, sizeof(INTT)); - ctx.mOffset += sizeof(INTT); - } - break; - } - case RsGenericSerializer::DESERIALIZE: - if(!ctx.mOk) break; - if(VLQ_ENCODING) ctx.mOk = VLQ_deserialize( - ctx.mData, ctx.mSize, ctx.mOffset, member ); - else - { - ctx.mOk = ctx.mSize >= ctx.mOffset + sizeof(INTT); - if(!ctx.mOk) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot deserialise " - << typeid(INTT).name() << " " - << " ctx.mSize: " << ctx.mSize - << " ctx.mOffset: " << ctx.mOffset - << " sizeof(INTT): " << sizeof(INTT) - << std::error_condition(std::errc::no_buffer_space) - << std::endl; - print_stacktrace(); - exit(-1); - break; - } - memcpy(&member, ctx.mData + ctx.mOffset, sizeof(INTT)); - member = rs_endian_fix(member); - ctx.mOffset += sizeof(INTT); - } - break; - case RsGenericSerializer::PRINT: break; - case RsGenericSerializer::TO_JSON: - ctx.mOk = ctx.mOk && to_JSON(member_name, member, ctx.mJson); - break; - case RsGenericSerializer::FROM_JSON: - ctx.mOk &= ( ctx.mOk || - !!(RsSerializationFlags::YIELDING & ctx.mFlags) ) - && from_JSON(member_name, member, ctx.mJson); - break; - default: fatalUnknownSerialJob(j); - } - } - -//============================================================================// -// Generic types // -//============================================================================// - - template - typename - std::enable_if< std::is_same::value || !( - std::is_integral::value || - std::is_base_of::value || - std::is_enum::value || - std::is_base_of::value || - std::is_same::value || - is_sequence_container::value || is_string::value ) >::type - static /*void*/ serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& memberC, const std::string& member_name ) - { - // Avoid problems with const sneaking into template paramether - using m_t = std::remove_const_t; - m_t& member = const_cast(memberC); - - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: - ctx.mOffset += serial_size(member); - break; - case RsGenericSerializer::DESERIALIZE: - ctx.mOk = ctx.mOk && - deserialize(ctx.mData,ctx.mSize,ctx.mOffset,member); - break; - case RsGenericSerializer::SERIALIZE: - ctx.mOk = ctx.mOk && - serialize(ctx.mData,ctx.mSize,ctx.mOffset,member); - break; - case RsGenericSerializer::PRINT: - print_data(member_name,member); - break; - case RsGenericSerializer::TO_JSON: - ctx.mOk = ctx.mOk && to_JSON(member_name, member, ctx.mJson); - break; - case RsGenericSerializer::FROM_JSON: - ctx.mOk &= ( ctx.mOk || - !!(ctx.mFlags & RsSerializationFlags::YIELDING) ) - && from_JSON(member_name, member, ctx.mJson); - break; - default: fatalUnknownSerialJob(j); - } - } - -//============================================================================// -// Generic types + type_id // -//============================================================================// - - /// Generic types + type_id - template RS_DEPRECATED - static void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - uint16_t type_id, T& member, const std::string& member_name ) - { - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: - ctx.mOffset += serial_size(type_id,member); - break; - case RsGenericSerializer::DESERIALIZE: - ctx.mOk = ctx.mOk && - deserialize(ctx.mData,ctx.mSize,ctx.mOffset,type_id,member); - break; - case RsGenericSerializer::SERIALIZE: - ctx.mOk = ctx.mOk && - serialize(ctx.mData,ctx.mSize,ctx.mOffset,type_id,member); - break; - case RsGenericSerializer::PRINT: break; - case RsGenericSerializer::TO_JSON: - ctx.mOk = ctx.mOk && - to_JSON(member_name, type_id, member, ctx.mJson); - break; - case RsGenericSerializer::FROM_JSON: - ctx.mOk &= - (ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING)) - && from_JSON(member_name, type_id, member, ctx.mJson); - break; - default: fatalUnknownSerialJob(j); - } - } - -//============================================================================// -// std::map // -//============================================================================// - - /// std::map - template - static void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - std::map& member, - const std::string& memberName ) - { - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: // [[falltrough]] - case RsGenericSerializer::SERIALIZE: - { - uint32_t mapSize = member.size(); - RS_SERIAL_PROCESS(mapSize); - - for( auto it = member.begin(); - ctx.mOk && it != member.end(); ++it ) - { - RS_SERIAL_PROCESS(const_cast(it->first)); - RS_SERIAL_PROCESS(const_cast(it->second)); - } - break; - } - case RsGenericSerializer::DESERIALIZE: - { - uint32_t mapSize = 0; - RS_SERIAL_PROCESS(mapSize); - - for(uint32_t i=0; ctx.mOk && i(memberName.length()), allocator ); - Value arr(kArrayType); - - for (auto& kv : member) - { - // Use same allocator to avoid deep copy - RsGenericSerializer::SerializeContext kCtx( - nullptr, 0, ctx.mFlags, &allocator ); - serial_process(j, kCtx, const_cast(kv.first), "key"); - - RsGenericSerializer::SerializeContext vCtx( - nullptr, 0, ctx.mFlags, &allocator ); - serial_process(j, vCtx, const_cast(kv.second), "value"); - - if(kCtx.mOk && vCtx.mOk) - { - Value el(kObjectType); - el.AddMember("key", kCtx.mJson["key"], allocator); - el.AddMember("value", vCtx.mJson["value"], allocator); - - arr.PushBack(el, allocator); - } - } - - ctx.mJson.AddMember(arrKey, arr, allocator); - - break; - } - case RsGenericSerializer::FROM_JSON: - { - using namespace rapidjson; - - bool ok = ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING); - Document& jDoc(ctx.mJson); - Document::AllocatorType& allocator = jDoc.GetAllocator(); - - Value arrKey; - arrKey.SetString( memberName.c_str(), - static_cast(memberName.length()) ); - - ok = ok && jDoc.IsObject(); - ok = ok && jDoc.HasMember(arrKey); - - if(ok && jDoc[arrKey].IsArray()) - { - for (auto&& kvEl : jDoc[arrKey].GetArray()) - { - ok = ok && kvEl.IsObject(); - ok = ok && kvEl.HasMember("key"); - ok = ok && kvEl.HasMember("value"); - if (!ok) break; - - RsGenericSerializer::SerializeContext kCtx( - nullptr, 0, ctx.mFlags, &allocator ); - if(ok) - kCtx.mJson.AddMember("key", kvEl["key"], allocator); - - T key; - ok = ok && (serial_process(j, kCtx, key, "key"), kCtx.mOk); - - RsGenericSerializer::SerializeContext vCtx( - nullptr, 0, ctx.mFlags, &allocator ); - if(ok) - vCtx.mJson.AddMember("value", kvEl["value"], allocator); - - U value; - ok = ok && ( serial_process(j, vCtx, value, "value"), - vCtx.mOk ); - - ctx.mOk &= ok; - if(ok) member.insert(std::pair(key,value)); - else break; - } - } - else ctx.mOk = false; - break; - } - default: fatalUnknownSerialJob(j); - } - } - - -//============================================================================// -// std::pair // -//============================================================================// - - /// std::pair - template - static void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - std::pair& member, const std::string& memberName ) - { - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: // [[fallthrough]] - case RsGenericSerializer::DESERIALIZE: // [[fallthrough]] - case RsGenericSerializer::SERIALIZE: // [[fallthrough]] - case RsGenericSerializer::PRINT: - RS_SERIAL_PROCESS(member.first); - RS_SERIAL_PROCESS(member.second); - break; - case RsGenericSerializer::TO_JSON: - { - RsJson& jDoc(ctx.mJson); - RsJson::AllocatorType& allocator = jDoc.GetAllocator(); - - // Reuse allocator to avoid deep copy later - RsGenericSerializer::SerializeContext lCtx( - nullptr, 0, ctx.mFlags, &allocator ); - - serial_process(j, lCtx, member.first, "first"); - serial_process(j, lCtx, member.second, "second"); - - rapidjson::Value key; - key.SetString( memberName.c_str(), - static_cast(memberName.length()), - allocator); - - /* Because the passed allocator is reused it doesn't go out of scope - * and there is no need of deep copy and we can take advantage of - * the much faster rapidjson move semantic */ - jDoc.AddMember(key, lCtx.mJson, allocator); - - ctx.mOk = ctx.mOk && lCtx.mOk; - break; - } - case RsGenericSerializer::FROM_JSON: - { - RsJson& jDoc(ctx.mJson); - const char* mName = memberName.c_str(); - bool hasMember = jDoc.HasMember(mName); - bool yielding = !!(ctx.mFlags & RsSerializationFlags::YIELDING); - - if(!hasMember) - { - if(!yielding) - { - RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName - << "\" not found in JSON" << std::endl; - print_stacktrace(); - } - ctx.mOk = false; - break; - } - - rapidjson::Value& v = jDoc[mName]; - - RsGenericSerializer::SerializeContext lCtx(nullptr, 0, ctx.mFlags); - lCtx.mJson.SetObject() = v; // Beware of move semantic!! - - serial_process(j, lCtx, member.first, "first"); - serial_process(j, lCtx, member.second, "second"); - ctx.mOk &= lCtx.mOk; - - break; - } - default: fatalUnknownSerialJob(j); - } - } - -//============================================================================// -// Sequence containers // -//============================================================================// - - /** std::list is supported */ template - struct is_sequence_container>: std::true_type {}; - - /** std::set is supported */ template - struct is_sequence_container>: std::true_type {}; - - /** std::vector is supported */ template - struct is_sequence_container>: std::true_type {}; - - - /// STL compatible sequence containers std::list, std::set, std::vector... - template - typename std::enable_if::value>::type - static serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& member, const std::string& memberName ) - { - using el_t = typename T::value_type; - - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: // [[falltrough]]; - case RsGenericSerializer::SERIALIZE: - { - uint32_t aSize = member.size(); - RS_SERIAL_PROCESS(aSize); - for(auto it = member.begin(); it != member.end(); ++it) - { - if(!ctx.mOk) break; - RS_SERIAL_PROCESS(*it); - } - break; - } - case RsGenericSerializer::DESERIALIZE: - { - uint32_t elCount = 0; - RS_SERIAL_PROCESS(elCount); - if(!ctx.mOk) break; - - /* This check is not perfect but will catch most pathological cases. - * Avoid multiplying by sizeof(el_t) as it is not a good estimation - * of the actual serialized size, depending on the elements - * structure and on the so it would raises many false positives. - * Arithmetic operations on elCount are also at risk of overflow */ - if(elCount > RsSerialiser::MAX_SERIAL_SIZE) - { - ctx.mOk = false; - RsErr() << __PRETTY_FUNCTION__ << " attempt to deserialize a " - << "sequence with apparently malformed elements count." - << " elCount: " << elCount - << " ctx.mSize: " << ctx.mSize - << " ctx.mOffset: " << ctx.mOffset << " " - << std::errc::argument_out_of_domain - << std::endl; - print_stacktrace(); - break; - } - - for(uint32_t i=0; ctx.mOk && i < elCount; ++i ) - { - el_t elem; - RS_SERIAL_PROCESS(elem); - member.insert(member.end(), elem); - } - break; - } - case RsGenericSerializer::PRINT: break; - case RsGenericSerializer::TO_JSON: - { - using namespace rapidjson; - - Document::AllocatorType& allocator = ctx.mJson.GetAllocator(); - - Value arrKey; arrKey.SetString(memberName.c_str(), allocator); - Value arr(kArrayType); - - for(auto& const_el : member) - { - auto el = const_cast(const_el); - - /* Use same allocator to avoid deep copy */ - RsGenericSerializer::SerializeContext elCtx( - nullptr, 0, ctx.mFlags, &allocator ); - serial_process(j, elCtx, el, memberName); - - elCtx.mOk = elCtx.mOk && elCtx.mJson.HasMember(arrKey); - if(elCtx.mOk) arr.PushBack(elCtx.mJson[arrKey], allocator); - else - { - ctx.mOk = false; - break; - } - } - - ctx.mJson.AddMember(arrKey, arr, allocator); - break; - } - case RsGenericSerializer::FROM_JSON: - { - using namespace rapidjson; - - bool ok = ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING); - Document& jDoc(ctx.mJson); - Document::AllocatorType& allocator = jDoc.GetAllocator(); - - Value arrKey; - arrKey.SetString( memberName.c_str(), - static_cast(memberName.length()) ); - - ok = ok && jDoc.IsObject() && jDoc.HasMember(arrKey) - && jDoc[arrKey].IsArray(); - if(!ok) { ctx.mOk = false; break; } - - for (auto&& arrEl : jDoc[arrKey].GetArray()) - { - Value arrKeyT; - arrKeyT.SetString( - memberName.c_str(), - static_cast(memberName.length()) ); - - RsGenericSerializer::SerializeContext elCtx( - nullptr, 0, ctx.mFlags, &allocator ); - elCtx.mJson.AddMember(arrKeyT, arrEl, allocator); - - el_t el; - serial_process(j, elCtx, el, memberName); - ok = ok && elCtx.mOk; - ctx.mOk &= ok; - if(ok) member.insert(member.end(), el); - else break; - } - - break; - } - default: fatalUnknownSerialJob(j); - } - } - -//============================================================================// -// Strings // -//============================================================================// - - /// Strings - template - typename std::enable_if::value>::type - static serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& memberC, - const std::string& memberName ) - { - // Avoid problems with const sneaking into template paramether - using m_t = std::remove_const_t; - m_t& member = const_cast(memberC); - - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: - { - uint32_t aSize = static_cast(member.size()); - RS_SERIAL_PROCESS(aSize); - ctx.mOffset += aSize; - break; - } - case RsGenericSerializer::SERIALIZE: - { - uint32_t len = static_cast(member.length()); - RS_SERIAL_PROCESS(len); - if(len + ctx.mOffset > ctx.mSize) - { - RsErr() << __PRETTY_FUNCTION__ << std::errc::no_buffer_space - << std::endl; - ctx.mOk = false; - } - memcpy(ctx.mData + ctx.mOffset, member.c_str(), len); - ctx.mOffset += len; - break; - } - case RsGenericSerializer::DESERIALIZE: - { - uint32_t len; - RS_SERIAL_PROCESS(len); - if(!ctx.mOk) break; - - if(len > RsSerialiser::MAX_SERIAL_SIZE) - { - ctx.mOk = false; - RsErr() << __PRETTY_FUNCTION__ << " attempt to deserialize a " - << "string with apparently malformed length." - << " len: " << len - << " ctx.mSize: " << ctx.mSize - << " ctx.mOffset: " << ctx.mOffset << " " - << std::errc::argument_out_of_domain << std::endl; - print_stacktrace(); - break; - } - - if(len + ctx.mOffset > ctx.mSize) - { - ctx.mOk = false; - RsErr() << __PRETTY_FUNCTION__ << " attempt to deserialize a " - << "string with a length bigger available data." - << " len: " << len - << " ctx.mSize: " << ctx.mSize - << " ctx.mOffset: " << ctx.mOffset << " " - << std::errc::no_buffer_space << std::endl; - print_stacktrace(); - break; - } - - member.resize(len); - memcpy(&member[0], ctx.mData + ctx.mOffset, len); - ctx.mOffset += len; - break; - } - case RsGenericSerializer::PRINT: break; - case RsGenericSerializer::TO_JSON: - ctx.mOk = ctx.mOk && to_JSON(memberName, member, ctx.mJson); - break; - case RsGenericSerializer::FROM_JSON: - { - bool ok = ctx.mOk || !!( - ctx.mFlags & RsSerializationFlags::YIELDING ); - ctx.mOk = ok && from_JSON(memberName, member, ctx.mJson) && ctx.mOk; - break; - } - default: fatalUnknownSerialJob(j); - } - } - - /// t_RsFlags32<> types - template - static void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - t_RsFlags32& v, - const std::string& memberName ) - { serial_process(j, ctx, v._bits, memberName); } - - /** - * @brief serial process enum types - * On declaration of your member of enum type you must specify the - * underlying type otherwise the serialization format may differ in an - * uncompatible way depending on the compiler/platform. - */ - template - typename std::enable_if::value>::type - static /*void*/ serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - E& member, - const std::string& memberName ) - { - RS_DBG4( "processing enum: ", typeid(E).name(), " as ", - typeid(typename std::underlying_type::type).name() ); - - serial_process( - j, ctx, - reinterpret_cast::type&>(member), - memberName ); - } - - /// RsSerializable and derivatives - template - typename std::enable_if::value>::type - static serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& memberC, const std::string& memberName ) - { - using m_t = std::remove_const_t; - m_t& member = const_cast(memberC); - - switch(j) - { - case RsGenericSerializer::SIZE_ESTIMATE: // fallthrough - case RsGenericSerializer::DESERIALIZE: // fallthrough - case RsGenericSerializer::SERIALIZE: // fallthrough - case RsGenericSerializer::PRINT: - member.serial_process(j, ctx); - break; - case RsGenericSerializer::TO_JSON: - { - rapidjson::Document& jDoc(ctx.mJson); - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); - - // Reuse allocator to avoid deep copy later - RsGenericSerializer::SerializeContext lCtx( - nullptr, 0, ctx.mFlags, &allocator ); - - member.serial_process(j, lCtx); - - rapidjson::Value key; - key.SetString( - memberName.c_str(), - static_cast(memberName.length()), - allocator ); - - /* Because the passed allocator is reused it doesn't go out of scope - * and there is no need of deep copy and we can take advantage of - * the much faster rapidjson move semantic */ - jDoc.AddMember(key, lCtx.mJson, allocator); - - ctx.mOk = ctx.mOk && lCtx.mOk; - break; - } - case RsGenericSerializer::FROM_JSON: - { - RsJson& jDoc(ctx.mJson); - const char* mName = memberName.c_str(); - bool hasMember = jDoc.HasMember(mName); - bool yielding = !!(ctx.mFlags & RsSerializationFlags::YIELDING); - - if(!hasMember) - { - if(!yielding) - { - RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName - << "\" not found in JSON:" << std::endl - << jDoc << std::endl << std::endl; - print_stacktrace(); - } - ctx.mOk = false; - break; - } - - rapidjson::Value& v = jDoc[mName]; - - if(!v.IsObject()) - { - RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName - << "\" has wrong type in JSON, object expected, got:" - << std::endl << jDoc << std::endl << std::endl; - print_stacktrace(); - ctx.mOk = false; - break; - } - - RsGenericSerializer::SerializeContext lCtx(nullptr, 0, ctx.mFlags); - lCtx.mJson.SetObject() = v; // Beware of move semantic!! - - member.serial_process(j, lCtx); - ctx.mOk &= lCtx.mOk; - - break; - } - default: fatalUnknownSerialJob(j); - } - } - - /// RsTlvItem derivatives only - template - typename std::enable_if< - std::is_base_of::value && - !std::is_same::value >::type - static serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& member, const std::string& memberName ) - { serial_process(j, ctx, static_cast(member), memberName); } - - /** std::error_condition - * supports only TO_JSON ErrConditionWrapper::serial_process will explode - * at runtime if a different SerializeJob is passed down */ - template - typename std::enable_if< std::is_base_of::value >::type - static /*void*/ serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx, - T& cond, const std::string& member_name ) - { - ErrConditionWrapper ew(cond); - serial_process(j, ctx, ew, member_name); - } - - RS_DEPRECATED_FOR(RawMemoryWrapper) - typedef RawMemoryWrapper TlvMemBlock_proxy; - -protected: - -//============================================================================// -// Generic types declarations // -//============================================================================// - - template static bool serialize( - uint8_t data[], uint32_t size, uint32_t &offset, const T& member ); - - template static bool deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, T& member); - - template static uint32_t serial_size(const T& member); - - template static void print_data( - const std::string& name, const T& member); - - template static bool to_JSON( const std::string& membername, - const T& member, RsJson& jDoc ); - - template static bool from_JSON( const std::string& memberName, - T& member, RsJson& jDoc ); - -//============================================================================// -// Generic types + type_id declarations // -//============================================================================// - - template RS_DEPRECATED - static bool serialize( - uint8_t data[], uint32_t size, uint32_t &offset, uint16_t type_id, - const T& member ); - - template RS_DEPRECATED - static bool deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, - uint16_t type_id, T& member ); - - template RS_DEPRECATED - static uint32_t serial_size(uint16_t type_id,const T& member); - - template RS_DEPRECATED - static void print_data( - const std::string& n, uint16_t type_id,const T& member ); - - template RS_DEPRECATED - static bool to_JSON( - const std::string& membername, uint16_t type_id, - const T& member, RsJson& jVal ); - - template RS_DEPRECATED - static bool from_JSON( - const std::string& memberName, uint16_t type_id, - T& member, RsJson& jDoc ); - -//============================================================================// -// t_RsGenericId<...> declarations // -//============================================================================// - - template - static bool serialize( - uint8_t data[], uint32_t size, uint32_t &offset, - const t_RsGenericIdType& member ); - - template - static bool deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, - t_RsGenericIdType& member ); - - template - static uint32_t serial_size( - const t_RsGenericIdType< - ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ); - - template - static void print_data( - const std::string& name, - const t_RsGenericIdType& member ); - - template - static bool to_JSON( - const std::string& membername, - const t_RsGenericIdType& member, - RsJson& jVal ); - - template - static bool from_JSON( - const std::string& memberName, - t_RsGenericIdType& member, - RsJson& jDoc ); - -//============================================================================// -// t_RsTlvList<...> declarations // -//============================================================================// - - template - static bool serialize( - uint8_t data[], uint32_t size, uint32_t &offset, - const t_RsTlvList& member ); - - template - static bool deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, - t_RsTlvList& member ); - - template - static uint32_t serial_size(const t_RsTlvList& member); - - template - static void print_data( - const std::string& name, - const t_RsTlvList& member); - - template - static bool to_JSON( const std::string& membername, - const t_RsTlvList& member, - RsJson& jVal ); - - template - static bool from_JSON( const std::string& memberName, - t_RsTlvList& member, - RsJson& jDoc ); - -//============================================================================// -// Integral types VLQ // -//============================================================================// - - /** - * Size calculation of unsigned integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - * @see https://techoverflow.net/2013/01/25/efficiently-encoding-variable-length-integers-in-cc/ - */ - template static - std::enable_if_t>::value, uint32_t> - VLQ_size(T member) - { - std::decay_t memberBackup = member; - uint32_t ret = 1; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wbool-compare" - while(member > 127) { ++ret; member >>= 7; } -#pragma GCC diagnostic pop - Dbg2() << __PRETTY_FUNCTION__ << " memberBackup: " << memberBackup - << " return: " << ret << std::endl; - return ret; - } - - /** - * Serialization of unsigned integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - * @see https://techoverflow.net/2013/01/25/efficiently-encoding-variable-length-integers-in-cc/ - */ - template static - std::enable_if_t>::value, bool> - VLQ_serialize( - uint8_t data[], uint32_t size, uint32_t &offset, T member ) - { - std::decay_t backupMember = member; -#if RS_DEBUG_LEVEL >= 3 - uint32_t offsetBackup = offset; -#endif - - bool ok = true; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wbool-compare" - /* Check with < and not with <= here as we write last byte after - * the loop. Order of && operands very important here! */ - while(member > 127 && (ok = (offset < size))) - { - // | 128: Set the next byte flag - data[offset++] = (static_cast(member & 127)) | 128; - // Remove the seven bits we just wrote - member >>= 7; - } -#pragma GCC diagnostic pop - - if(!(ok = ok && offset <= size)) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot serialise " - << typeid(T).name() - << " member " << member - << " size: " << size - << " offset: " << offset - << " backupMember: " << backupMember - << std::error_condition(std::errc::no_buffer_space) - << std::endl; - print_stacktrace(); - return false; - } - - data[offset++] = static_cast(member & 127); - -#if RS_DEBUG_LEVEL >= 3 - RsDbg tdbg( __PRETTY_FUNCTION__, " backupMember: ", backupMember, - " offsetBackup: ", offsetBackup, " offeset: ", offset, - " serialized as: " ); - for(; offsetBackup < offset; ++offsetBackup) - tdbg << " " << std::bitset<8>(data[offsetBackup]); -#endif - return ok; - } - - /** - * Deserialization for unsigned integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - * @see https://techoverflow.net/2013/01/25/efficiently-encoding-variable-length-integers-in-cc/ - */ - template static - std::enable_if_t>::value, bool> - VLQ_deserialize( - const uint8_t data[], uint32_t size, uint32_t& offset, T& member ) - { - member = 0; - uint32_t offsetBackup = offset; - - /* In a reasonable VLQ coding representing an integer - * could take at maximum sizeof(integer) + 1 space, if it is - * not the case something fishy is happening. */ - for (size_t i = 0; offset < size && i <= sizeof(T); ++i) - { - member |= (data[offset] & 127) << (7 * i); - // If the next-byte flag is not set. ++ is after on purpose - if(!(data[offset++] & 128)) - { - Dbg2() << __PRETTY_FUNCTION__ - << " size: " << size - << " backupOffset " << offsetBackup - << " offset: " << offset - << " member " << member << std::endl; - return true; - } - } - - /* If return is not triggered inside the for loop, either the buffer - * ended before we encountered the end of the number, or the number - * is VLQ encoded improperly */ - RsErr rserr; - rserr << __PRETTY_FUNCTION__ << std::errc::illegal_byte_sequence - << " size: " << size - << " offsetBackup: " << offsetBackup - << " offset: " << offset << " bytes: "; - for(; offsetBackup < offset; ++offsetBackup) - rserr << " " << std::bitset<8>(data[offsetBackup]); - print_stacktrace(); - - return false; - } - - /** - * Size calculation of signed integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - */ - template static - std::enable_if_t>::value, uint32_t> - VLQ_size(T member) - { - member = (member << 1) ^ (member >> (sizeof(T)-1)); // ZigZag encoding - return VLQ_size( - static_cast::type>(member)); - } - - /** - * Serialization of signed integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - */ - template static - std::enable_if_t>::value, bool> - VLQ_serialize( - uint8_t data[], uint32_t size, uint32_t &offset, T member ) - { - member = (member << 1) ^ (member >> (sizeof(T)-1)); // ZigZag encoding - return VLQ_serialize( - data, size, offset, - static_cast::type>(member)); - } - - /** - * Deserialization for signed integers as Variable Lenght Quantity - * @see RsSerializationFlags::INTEGER_VLQ - * @see https://en.wikipedia.org/wiki/Variable-length_quantity#Zigzag_encoding - * @see https://golb.hplar.ch/2019/06/variable-length-int-java.html - */ - template static - std::enable_if_t>::value, bool> - VLQ_deserialize( - const uint8_t data[], uint32_t size, uint32_t& offset, T& member ) - { - using DT = std::decay_t; - typename std::make_unsigned
::type temp = 0; - bool ok = VLQ_deserialize(data, size, offset, temp); - // ZizZag decoding - member = (static_cast
(temp) >> 1) ^ -(static_cast
(temp) & 1); - return ok; - } - -//============================================================================// -// Error Condition Wrapper // -//============================================================================// - - struct ErrConditionWrapper : RsSerializable - { - explicit ErrConditionWrapper(const std::error_condition& ec): mec(ec) {} - - /** supports only TO_JSON if a different SerializeJob is passed it will - * explode at runtime */ - void serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override; - - private: - const std::error_condition& mec; - }; - -//============================================================================// -// Miscellanea // -//============================================================================// - - [[noreturn]] static void fatalUnknownSerialJob(int j) - { - RsFatal() << " Unknown serial job: " << j << std::endl; - print_stacktrace(); - exit(EINVAL); - } - - RS_SET_CONTEXT_DEBUG_LEVEL(1) -}; - - -//============================================================================// -// t_RsGenericId<...> // -//============================================================================// - -template -bool RsTypeSerializer::serialize ( - uint8_t data[], uint32_t size, uint32_t &offset, - const t_RsGenericIdType< - ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ) -{ - return (*const_cast *>(&member) - ).serialise(data, size, offset); -} - -template -bool RsTypeSerializer::deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, - t_RsGenericIdType& member ) -{ return member.deserialise(data, size, offset); } - -template -uint32_t RsTypeSerializer::serial_size( - const t_RsGenericIdType& member ) -{ return member.serial_size(); } - -template -void RsTypeSerializer::print_data( - const std::string& /*name*/, - const t_RsGenericIdType& member ) -{ - std::cerr << " [RsGenericId<" << std::hex - << static_cast(UNIQUE_IDENTIFIER) << ">] : " - << member << std::endl; -} - -template -bool RsTypeSerializer::to_JSON( - const std::string& memberName, - const t_RsGenericIdType& member, - RsJson& jDoc ) -{ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); - - rapidjson::Value key; - key.SetString(memberName.c_str(), memberName.length(), allocator); - - const std::string vStr = member.toStdString(); - rapidjson::Value value; - value.SetString(vStr.c_str(), vStr.length(), allocator); - - jDoc.AddMember(key, value, allocator); - - return true; -} - -template -bool RsTypeSerializer::from_JSON( - const std::string& membername, - t_RsGenericIdType& member, - RsJson& jVal ) -{ - const char* mName = membername.c_str(); - bool ret = jVal.HasMember(mName); - if(ret) - { - rapidjson::Value& v = jVal[mName]; - ret = ret && v.IsString(); - if(ret) member = - t_RsGenericIdType( - std::string(v.GetString()) ); - } - return ret; -} - -//============================================================================// -// t_RsTlvList<...> // -//============================================================================// - -template -bool RsTypeSerializer::serialize( - uint8_t data[], uint32_t size, uint32_t &offset, - const t_RsTlvList& member ) -{ - return (*const_cast *>(&member)).SetTlv(data,size,&offset); -} - -template -bool RsTypeSerializer::deserialize( - const uint8_t data[], uint32_t size, uint32_t &offset, - t_RsTlvList& member ) -{ - return member.GetTlv(const_cast(data),size,&offset); -} - -template -uint32_t RsTypeSerializer::serial_size( - const t_RsTlvList& member) -{ return member.TlvSize(); } - -template -void RsTypeSerializer::print_data( - const std::string& /*name*/, - const t_RsTlvList& member) -{ - std::cerr << " [t_RsTlvString<" << std::hex << TLV_TYPE << ">] : size=" - << member.mList.size() << std::endl; -} - -template /* static */ -bool RsTypeSerializer::to_JSON( const std::string& memberName, - const t_RsTlvList& member, - RsJson& jDoc ) -{ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); - - rapidjson::Value key; - key.SetString(memberName.c_str(), memberName.length(), allocator); - - rapidjson::Value value; - const char* tName = typeid(member).name(); - value.SetString(tName, allocator); - - jDoc.AddMember(key, value, allocator); - - std::cerr << __PRETTY_FUNCTION__ << " JSON serialization for type " - << typeid(member).name() << " " << memberName - << " not available." << std::endl; - print_stacktrace(); - return true; -} - -template -bool RsTypeSerializer::from_JSON( const std::string& memberName, - t_RsTlvList& member, - RsJson& /*jVal*/ ) -{ - std::cerr << __PRETTY_FUNCTION__ << " JSON deserialization for type " - << typeid(member).name() << " " << memberName - << " not available." << std::endl; - print_stacktrace(); - return true; -} - -//============================================================================// -// Not implemented types macros // -//============================================================================// - -/** - * @def RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(T) - * @def RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(T) - * Helper macros for types that has not yet implemented to/from JSON - * should be deleted from the code as soon as they are not needed anymore - */ -#define RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(T) \ -template<> /*static*/ \ -bool RsTypeSerializer::to_JSON(const std::string& memberName, T const& member, \ - RsJson& jDoc ) \ -{ \ - rapidjson::Document::AllocatorType& allocator = jDoc.GetAllocator(); \ - \ - rapidjson::Value key; \ - key.SetString(memberName.c_str(), memberName.length(), allocator); \ - \ - rapidjson::Value value; \ - const char* tName = typeid(member).name(); \ - value.SetString(tName, allocator); \ - \ - jDoc.AddMember(key, value, allocator); \ - \ - std::cerr << __FILE__ << __LINE__ << __PRETTY_FUNCTION__ \ - << " JSON serialization for type " \ - << typeid(member).name() << " " << memberName \ - << " not available." << std::endl; \ - print_stacktrace(); \ - return true; \ -} - -#define RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(T) \ -template<> /*static*/ \ -bool RsTypeSerializer::from_JSON( const std::string& memberName, \ - T& member, RsJson& /*jDoc*/ ) \ -{ \ - std::cerr << __FILE__ << __LINE__ << __PRETTY_FUNCTION__ \ - << " JSON deserialization for type " \ - << typeid(member).name() << " " << memberName \ - << " not available." << std::endl; \ - print_stacktrace(); \ - return true; \ -} diff --git a/libretroshare/src/services/autoproxy/p3i2pbob.cc b/libretroshare/src/services/autoproxy/p3i2pbob.cc deleted file mode 100644 index f9eb3d9b3..000000000 --- a/libretroshare/src/services/autoproxy/p3i2pbob.cc +++ /dev/null @@ -1,1117 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: p3i2pbob.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include /* for usleep() */ - -#include "p3i2pbob.h" - -#include "pqi/p3peermgr.h" -#include "rsitems/rsconfigitems.h" -#include "util/radix32.h" -#include "util/radix64.h" -#include "util/rsdebug.h" -#include "util/rstime.h" -#include "util/rsprint.h" -#include "util/rsrandom.h" - -static const std::string kConfigKeyBOBEnable = "BOB_ENABLE"; -static const std::string kConfigKeyBOBKey = "BOB_KEY"; -static const std::string kConfigKeyBOBAddr = "BOB_ADDR"; -static const std::string kConfigKeyInLength = "IN_LENGTH"; -static const std::string kConfigKeyInQuantity = "IN_QUANTITY"; -static const std::string kConfigKeyInVariance = "IN_VARIANCE"; -static const std::string kConfigKeyOutLength = "OUT_LENGTH"; -static const std::string kConfigKeyOutQuantity = "OUT_QUANTITY"; -static const std::string kConfigKeyOutVariance = "OUT_VARIANCE"; - -/// Sleep duration for receiving loop in error/no-data case -static const useconds_t sleepTimeRecv = 250; // times 1000 = 250ms -/// Sleep duration for everything else -static const useconds_t sleepTimeWait = 50; // times 1000 = 50ms or 0.05s -static const int sleepFactorDefault = 10; // 0.5s -static const int sleepFactorFast = 1; // 0.05s -static const int sleepFactorSlow = 20; // 1s - -static const rstime_t selfCheckPeroid = 30; - -void doSleep(useconds_t timeToSleepMS) { - rstime::rs_usleep((useconds_t) (timeToSleepMS * 1000)); -} - -p3I2pBob::p3I2pBob(p3PeerMgr *peerMgr) - : RsTickingThread(), p3Config(), - mState(csIdel), mTask(ctIdle), - mStateOld(csIdel), mTaskOld(ctIdle), - mBOBState(bsCleared), mPeerMgr(peerMgr), - mConfigLoaded(false), mSocket(0), - mLastProxyCheck(time(NULL)), - mProcessing(NULL), mLock("I2P-BOB") -{ - // set defaults - mSetting.initDefault(); - - mCommands.clear(); -} - -bool p3I2pBob::isEnabled() -{ - RS_STACK_MUTEX(mLock); - return mSetting.enable; -} - -bool p3I2pBob::initialSetup(std::string &addr, uint16_t &/*port*/) -{ - RS_DBG(""); - - // update config - { - RS_STACK_MUTEX(mLock); - if (!mConfigLoaded) { - finalizeSettings_locked(); - mConfigLoaded = true; - } else { - updateSettings_locked(); - } - } - - RS_DBG("config updated"); - - // request keys - // p3I2pBob::stateMachineBOB expects mProcessing to be set therefore - // we create this fake ticket without a callback or data - // ticket gets deleted later by this service - taskTicket *fakeTicket = rsAutoProxyMonitor::getTicket(); - fakeTicket->task = autoProxyTask::receiveKey; - processTaskAsync(fakeTicket); - - RS_DBG("fakeTicket requested"); - - // now start thread - start("I2P-BOB gen key"); - - RS_DBG("thread started"); - - int counter = 0; - // wait for keys - for(;;) { - doSleep(sleepTimeWait * sleepFactorDefault); - - RS_STACK_MUTEX(mLock); - - // wait for tast change - if (mTask != ctRunGetKeys) - break; - - if (++counter > 30) { - RS_DBG4("timeout!"); - return false; - } - } - - RS_DBG("got keys"); - - // stop thread - fullstop(); - - RS_DBG("thread stopped"); - - { - RS_STACK_MUTEX(mLock); - addr = mSetting.address.base32; - } - - RS_DBG4("addr ", addr); - - return true; -} - -void p3I2pBob::processTaskAsync(taskTicket *ticket) -{ - switch (ticket->task) { - case autoProxyTask::start: - case autoProxyTask::stop: - case autoProxyTask::receiveKey: - case autoProxyTask::proxyStatusCheck: - { - RS_STACK_MUTEX(mLock); - mPending.push(ticket); - } - break; - default: - RS_DBG("unknown task"); - rsAutoProxyMonitor::taskError(ticket); - break; - } -} - -void p3I2pBob::processTaskSync(taskTicket *ticket) -{ - bool data = !!ticket->data; - - // check wether we can process the task immediately or have to queue it - switch (ticket->task) { - case autoProxyTask::status: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::status data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // get states - getStates((struct bobStates*)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::getSettings: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::getSettings data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // get settings - getBOBSettings((struct bobSettings *)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::setSettings: - // check if everything needed is set - if (!data) { - RS_DBG("autoProxyTask::setSettings data is missing"); - rsAutoProxyMonitor::taskError(ticket); - break; - } - - // set settings - setBOBSettings((struct bobSettings *)ticket->data); - - // finish task - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::reloadConfig: - { - RS_STACK_MUTEX(mLock); - updateSettings_locked(); - } - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - break; - case autoProxyTask::getErrorInfo: - if (!data) { - RS_DBG("autoProxyTask::getErrorInfo data is missing"); - rsAutoProxyMonitor::taskError(ticket); - } else { - RS_STACK_MUTEX(mLock); - *(std::string *)ticket->data = mErrorMsg; - rsAutoProxyMonitor::taskDone(ticket, autoProxyStatus::ok); - } - break; - default: - RS_DBG("unknown task"); - rsAutoProxyMonitor::taskError(ticket); - break; - } -} - -bool inline isAnswerOk(const std::string &answer) { - return (answer.compare(0, 2, "OK") == 0); -} - -bool inline isTunnelActiveError(const std::string &answer) { - return answer.compare(0, 22, "ERROR tunnel is active") == 0; -} - -void p3I2pBob::threadTick() -{ - int sleepTime = 0; - { - RS_STACK_MUTEX(mLock); - RS_DBG4("data_tick mState: ", mState, " mTask: ", mTask, " mBOBState: ", mBOBState, " mPending: ", mPending.size()); - } - - sleepTime += stateMachineController(); - sleepTime += stateMachineBOB(); - - sleepTime >>= 1; - - // sleep outisde of lock! - doSleep(sleepTime * sleepTimeWait); -} - -int p3I2pBob::stateMachineBOB() -{ - std::string answer; - bobStateInfo currentState; - - { - RS_STACK_MUTEX(mLock); - if (mBOBState == bsCleared || !mConfigLoaded) { - // we don't have work to do - sleep longer - return sleepFactorSlow; - } - - // get next command - currentState = mCommands[mBOBState]; - } - - // this call can take a while - // do NOT hold the lock - answer = executeCommand(currentState.command); - - // can hold the lock for the rest of the function - RS_STACK_MUTEX(mLock); - - // special state first - if (mBOBState == bsList) { - int counter = 0; - while (answer.find("OK Listing done") == std::string::npos) { - RS_DBG3("stateMachineBOB status check: read loop, counter: ", counter); - answer += recv(); - counter++; - } - - if (answer.find(mTunnelName) == std::string::npos) { - RS_DBG("status check: tunnel down!"); - // signal error - *((bool *)mProcessing->data) = true; - } - - mBOBState = currentState.nextState; - } else if (isAnswerOk(answer)) { - // check for other special states - std::string key; - switch (mBOBState) { - case bsNewkeysN: - key = answer.substr(3, answer.length()-3); - mSetting.address.base32 = i2p::keyToBase32Addr(key); - IndicateConfigChanged(); - break; - case bsGetkeys: - key = answer.substr(3, answer.length()-3); - mSetting.address.privateKey = key; - IndicateConfigChanged(); - break; - default: - break; - } - - // goto next command - mBOBState = currentState.nextState; - } else { - return stateMachineBOB_locked_failure(answer, currentState); - } - return sleepFactorFast; -} - -int p3I2pBob::stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo ¤tState) -{ - // wait in case of active tunnel - // happens when trying to clear a stopping tunnel - if (isTunnelActiveError(answer)) { - return sleepFactorDefault; - } - - RS_DBG("FAILED to run command: ", currentState.command); - RS_DBG("answer: ", answer); - - mErrorMsg.append("FAILED to run command '" + currentState.command + "'" + '\n'); - mErrorMsg.append("reason '" + answer + "'" + '\n'); - - // this error handling needs testing! - mStateOld = mState; - mState = csError; - switch (mBOBState) { - case bsGetnick: - // failed getting nick - // tunnel is probably non existing - case bsClear: - // tunnel is cleared - mBOBState = bsQuit; - break; - case bsStop: - // failed stopping - // tunnel us probably not running - // continue to clearing - mBOBState = bsClear; - break; - case bsQuit: - // this can happen when the - // connection is somehow broken - // just try to disconnect - disconnectI2P(); - mBOBState = bsCleared; - break; - default: - // try to recover - mBOBState = bsGetnick; - break; - } - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController() -{ - RS_STACK_MUTEX(mLock); - - switch (mState) { - case csIdel: - return stateMachineController_locked_idle(); - case csDoConnect: - if (!connectI2P()) { - RS_DBG("doConnect: unable to connect"); - mStateOld = mState; - mState = csError; - mErrorMsg = "unable to connect to BOB port"; - return sleepFactorSlow; - } - - RS_DBG4("doConnect: connected"); - mState = csConnected; - break; - case csConnected: - return stateMachineController_locked_connected(); - case csWaitForBob: - // check connection problems - if (mSocket == 0) { - RS_DBG("waitForBob: conection lost"); - mStateOld = mState; - mState = csError; - mErrorMsg = "connection lost to BOB"; - return sleepFactorDefault; - } - - // check for finished BOB protocol - if (mBOBState == bsCleared) { - // done - RS_DBG4("waitForBob: mBOBState == bsCleared"); - mState = csDoDisconnect; - } - break; - case csDoDisconnect: - if (!disconnectI2P() || mSocket != 0) { - // just in case - RS_DBG("doDisconnect: can't disconnect"); - mStateOld = mState; - mState = csError; - mErrorMsg = "unable to disconnect from BOB"; - return sleepFactorDefault; - } - - RS_DBG4("doDisconnect: disconnected"); - mState = csDisconnected; - break; - case csDisconnected: - return stateMachineController_locked_disconnected(); - case csError: - return stateMachineController_locked_error(); - } - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_idle() -{ - // do some sanity checks - // use asserts becasue these things indicate wrong/broken state machines that need to be fixed ASAP! - assert(mBOBState == bsCleared); - assert(mSocket == 0); - assert(mState == csIdel || mState == csDisconnected); - - controllerTask oldTask = mTask; - // check for new task - if (mProcessing == NULL && !mPending.empty()) { - mProcessing = mPending.front(); - mPending.pop(); - - if (!mSetting.enable && ( - mProcessing->task == autoProxyTask::start || - mProcessing->task == autoProxyTask::stop || - mProcessing->task == autoProxyTask::proxyStatusCheck)) { - // skip since we are not enabled - RS_DBG1("disabled -> skipping ticket"); - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::disabled); - mProcessing = NULL; - } else { - // set states - switch (mProcessing->task) { - case autoProxyTask::start: - mLastProxyCheck = time(NULL); - mTask = ctRunSetUp; - break; - case autoProxyTask::stop: - mTask = ctRunShutDown; - break; - case autoProxyTask::receiveKey: - mTaskOld = mTask; - mTask = ctRunGetKeys; - break; - case autoProxyTask::proxyStatusCheck: - mTaskOld = mTask; - mTask = ctRunCheck; - break; - default: - RS_DBG1("unknown async task"); - rsAutoProxyMonitor::taskError(mProcessing); - mProcessing = NULL; - break; - } - } - - mErrorMsg.clear(); - } - - // periodically check - if (mTask == ctRunSetUp && mLastProxyCheck < time(NULL) - selfCheckPeroid) { - taskTicket *tt = rsAutoProxyMonitor::getTicket(); - tt->task = autoProxyTask::proxyStatusCheck; - tt->data = (void *) new bool; - - *((bool *)tt->data) = false; - - mPending.push(tt); - - mLastProxyCheck = time(NULL); - } - - // wait for new task - if (!!mProcessing) { - // check if task was changed - if (mTask != oldTask) { - mState = csDoConnect; - } else { - // A ticket shall be processed but the state didn't change. - // This means that what ever is requested in the ticket - // was requested before already. - // -> set mState to csDisconnected to answer the ticket - mState = csDisconnected; - } - return sleepFactorFast; - } - - return sleepFactorSlow; -} - -int p3I2pBob::stateMachineController_locked_connected() -{ - // set proper bob state - switch (mTask) { - case ctRunSetUp: - // when we have a key use it for server tunnel! - if(mSetting.address.privateKey.empty()) { - RS_DBG4("setting mBOBState = setnickC"); - mBOBState = bsSetnickC; - } else { - RS_DBG4("setting mBOBState = setnickS"); - mBOBState = bsSetnickS; - } - break; - case ctRunShutDown: - // shut down existing tunnel - RS_DBG4("setting mBOBState = getnick"); - mBOBState = bsGetnick; - break; - case ctRunCheck: - RS_DBG4("setting mBOBState = list"); - mBOBState = bsList; - break; - case ctRunGetKeys: - RS_DBG4("setting mBOBState = setnickN"); - mBOBState = bsSetnickN; - break; - case ctIdle: - RS_DBG("task is idle. This should not happen!"); - break; - } - - mState = csWaitForBob; - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_disconnected() -{ - // check if we had an error - bool errorHappened = (mStateOld == csError); - - if(errorHappened) { - // reset old state - mStateOld = csIdel; - RS_DBG("error during process!"); - } - - // answer ticket - controllerState newState = csIdel; - switch (mTask) { - case ctRunSetUp: - if (errorHappened) { - rsAutoProxyMonitor::taskError(mProcessing); - // switch to error - newState = csError; - } else { - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::online); - } - break; - case ctRunShutDown: - // don't care about error here - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::offline); - break; - case ctRunCheck: - // get result and delete dummy ticket - errorHappened |= *((bool *)mProcessing->data); - delete (bool *)mProcessing->data; - delete mProcessing; - - // restore old task - mTask = mTaskOld; - - if (!errorHappened) { - RS_DBG4("run check result: ok"); - break; - } - // switch to error - newState = csError; - RS_DBG("run check result: error"); - mErrorMsg = "Connection check failed. Will try to restart tunnel."; - - break; - case ctRunGetKeys: - if (!errorHappened) { - // rebuild commands - updateSettings_locked(); - - if (mProcessing->data) - *((struct bobSettings *)mProcessing->data) = mSetting; - - rsAutoProxyMonitor::taskDone(mProcessing, autoProxyStatus::ok); - } else { - rsAutoProxyMonitor::taskError(mProcessing); - // switch to error - newState = csError; - } - - // restore old task - mTask = mTaskOld; - break; - case ctIdle: - RS_DBG("task is idle. This should not happen!"); - rsAutoProxyMonitor::taskError(mProcessing); - } - mProcessing = NULL; - mState = newState; - - if (newState == csError) - mLastProxyCheck = time(NULL); - - return sleepFactorFast; -} - -int p3I2pBob::stateMachineController_locked_error() -{ - // wait for bob protocoll - if (mBOBState != bsCleared) { - RS_DBG4("waiting for BOB"); - return sleepFactorFast; - } - -#if 0 - RS_DBG4("stateMachineController_locked_error: mProcessing: ", (mProcessing ? "not null" : "null")); -#endif - - // try to finish ticket - if (mProcessing) { - switch (mTask) { - case ctRunCheck: - // connection check failed at some point - RS_DBG("failed to check proxy status (it's likely dead)!"); - *((bool *)mProcessing->data) = true; - mState = csDoDisconnect; - mStateOld = csIdel; - // keep the error message - break; - case ctRunShutDown: - // not a big deal though - RS_DBG("failed to shut down tunnel (it's likely dead though)!"); - mState = csDoDisconnect; - mStateOld = csIdel; - mErrorMsg.clear(); - break; - case ctIdle: - // should not happen but we need to deal with it - // this will produce some error messages in the log and finish the task (marked as failed) - RS_DBG("task is idle. This should not happen!"); - mState = csDoDisconnect; - mStateOld = csIdel; - mErrorMsg.clear(); - break; - case ctRunGetKeys: - case ctRunSetUp: - RS_DBG("failed to receive key / start up"); - mStateOld = csError; - mState = csDoDisconnect; - // keep the error message - break; - } - return sleepFactorFast; - } - - // periodically retry - if (mLastProxyCheck < time(NULL) - (selfCheckPeroid >> 1) && mTask == ctRunSetUp) { - RS_DBG("retrying"); - - mLastProxyCheck = time(NULL); - mErrorMsg.clear(); - - // create fake ticket - taskTicket *tt = rsAutoProxyMonitor::getTicket(); - tt->task = autoProxyTask::start; - mPending.push(tt); - } - - // check for new tickets - if (!mPending.empty()) { - RS_DBG4("processing new ticket"); - - // reset and try new task - mTask = ctIdle; - mState = csIdel; - return sleepFactorFast; - } - - return sleepFactorDefault; -} - -RsSerialiser *p3I2pBob::setupSerialiser() -{ - RsSerialiser* rsSerialiser = new RsSerialiser(); - rsSerialiser->addSerialType(new RsGeneralConfigSerialiser()); - - return rsSerialiser; -} - -#define addKVS(_vitem, _kv, _key, _value) \ - _kv.key = _key;\ - _kv.value = _value;\ - _vitem->tlvkvs.pairs.push_back(_kv); - -#define addKVSInt(_vitem, _kv, _key, _value) \ - _kv.key = _key;\ - rs_sprintf(_kv.value, "%d", _value);\ - _vitem->tlvkvs.pairs.push_back(_kv); - -bool p3I2pBob::saveList(bool &cleanup, std::list &lst) -{ - RS_DBG4(""); - - cleanup = true; - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet; - RsTlvKeyValue kv; - - RS_STACK_MUTEX(mLock); - addKVS(vitem, kv, kConfigKeyBOBEnable, mSetting.enable ? "TRUE" : "FALSE") - addKVS(vitem, kv, kConfigKeyBOBKey, mSetting.address.privateKey) - addKVS(vitem, kv, kConfigKeyBOBAddr, mSetting.address.base32) - addKVSInt(vitem, kv, kConfigKeyInLength, mSetting.inLength) - addKVSInt(vitem, kv, kConfigKeyInQuantity, mSetting.inQuantity) - addKVSInt(vitem, kv, kConfigKeyInVariance, mSetting.inVariance) - addKVSInt(vitem, kv, kConfigKeyOutLength, mSetting.outLength) - addKVSInt(vitem, kv, kConfigKeyOutQuantity, mSetting.outQuantity) - addKVSInt(vitem, kv, kConfigKeyOutVariance, mSetting.outVariance) - - lst.push_back(vitem); - - return true; -} - -#undef addKVS -#undef addKVSUInt - -#define getKVSUInt(_kit, _key, _value) \ - else if (_kit->key == _key) {\ - std::istringstream is(_kit->value);\ - int tmp;\ - is >> tmp;\ - _value = (int8_t)tmp;\ - } - -bool p3I2pBob::loadList(std::list &load) -{ - RS_DBG4(""); - - for(std::list::const_iterator it = load.begin(); it!=load.end(); ++it) { - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - if(vitem != NULL) { - RS_STACK_MUTEX(mLock); - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) { - if (kit->key == kConfigKeyBOBEnable) - mSetting.enable = kit->value == "TRUE"; - else if (kit->key == kConfigKeyBOBKey) - mSetting.address.privateKey = kit->value; - else if (kit->key == kConfigKeyBOBAddr) - mSetting.address.base32 = kit->value; - getKVSUInt(kit, kConfigKeyInLength, mSetting.inLength) - getKVSUInt(kit, kConfigKeyInQuantity, mSetting.inQuantity) - getKVSUInt(kit, kConfigKeyInVariance, mSetting.inVariance) - getKVSUInt(kit, kConfigKeyOutLength, mSetting.outLength) - getKVSUInt(kit, kConfigKeyOutQuantity, mSetting.outQuantity) - getKVSUInt(kit, kConfigKeyOutVariance, mSetting.outVariance) - else - RS_DBG("unknown key: ", kit->key); - } - } - delete vitem; - } - - RS_STACK_MUTEX(mLock); - finalizeSettings_locked(); - mConfigLoaded = true; - - return true; -} - -#undef getKVSUInt - -void p3I2pBob::getBOBSettings(bobSettings *settings) -{ - if (settings == NULL) - return; - - RS_STACK_MUTEX(mLock); - *settings = mSetting; - -} - -void p3I2pBob::setBOBSettings(const bobSettings *settings) -{ - if (settings == NULL) - return; - - RS_STACK_MUTEX(mLock); - mSetting = *settings; - - IndicateConfigChanged(); - - // Note: - // We don't take care of updating a running BOB session here - // This can be done manually by stoping and restarting the session - - // Note2: - // In case there is no config yet to load - // finalize settings here instead - if (!mConfigLoaded) { - finalizeSettings_locked(); - mConfigLoaded = true; - } else { - updateSettings_locked(); - } -} - -void p3I2pBob::getStates(bobStates *bs) -{ - if (bs == NULL) - return; - - RS_STACK_MUTEX(mLock); - bs->cs = mState; - bs->ct = mTask; - bs->bs = mBOBState; - bs->tunnelName = mTunnelName; -} - -std::string p3I2pBob::executeCommand(const std::string &command) -{ - RS_DBG4("running: ", command); - - std::string copy = command; - copy.push_back('\n'); - - // send command - // there is only one thread that touches mSocket - no need for a lock - ::send(mSocket, copy.c_str(), copy.size(), 0); - - // receive answer (trailing new line is already removed!) - std::string ans = recv(); - - RS_DBG4("answer: ", ans); - - return ans; -} - -bool p3I2pBob::connectI2P() -{ - // there is only one thread that touches mSocket - no need for a lock - - if (mSocket != 0) { - RS_DBG("mSocket != 0"); - return false; - } - - // create socket - mSocket = unix_socket(PF_INET, SOCK_STREAM, 0); - if (mSocket < 0) - { - RS_DBG("Failed to open socket! Socket Error: ", socket_errorType(errno)); - return false; - } - - // connect - int err = unix_connect(mSocket, mI2PProxyAddr); - if (err != 0) { - RS_DBG("Failed to connect to BOB! Socket Error: ", socket_errorType(errno)); - return false; - } - - // receive hello msg - recv(); - - RS_DBG4("done"); - return true; -} - -bool p3I2pBob::disconnectI2P() -{ - // there is only one thread that touches mSocket - no need for a lock - - if (mSocket == 0) { - RS_DBG("mSocket == 0"); - return true; - } - - int err = unix_close(mSocket); - if (err != 0) { - RS_DBG("Failed to close socket! Socket Error: ", socket_errorType(errno)); - return false; - } - - RS_DBG4("done"); - mSocket = 0; - return true; -} - -std::string toString(const std::string &a, const int b) { - std::ostringstream oss; - oss << b; - return a + oss.str();; -} - -std::string toString(const std::string &a, const uint16_t b) { - return toString(a, (int)b); -} - -std::string toString(const std::string &a, const int8_t b) { - return toString(a, (int)b); -} - -void p3I2pBob::finalizeSettings_locked() -{ - RS_DBG4(""); - - sockaddr_storage_clear(mI2PProxyAddr); - // get i2p proxy addr - sockaddr_storage proxy; - mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy); - - // overwrite port to bob port - sockaddr_storage_setipv4(mI2PProxyAddr, (sockaddr_in*)&proxy); - sockaddr_storage_setport(mI2PProxyAddr, 2827); - - RS_DBG4("using ", mI2PProxyAddr); - RS_DBG4("using ", mSetting.address.base32); - - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - // setup commands - // new lines are appended later! - - // generate 8 characater long random suffix for name - constexpr size_t len = 8; - const std::string location = RsRandom::alphaNumeric(len); - RS_DBG4("using suffix ", location); - mTunnelName = "RetroShare-" + location; - - const std::string setnick = "setnick RetroShare-" + location; - const std::string getnick = "getnick RetroShare-" + location; - const std::string newkeys = "newkeys"; - const std::string getkeys = "getkeys"; - const std::string setkeys = "setkeys " + mSetting.address.privateKey; - const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy); - const std::string inport = toString("inport ", sockaddr_storage_port(proxy)); - const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr); - const std::string outport = toString("outport ", sockaddr_storage_port(ps.localaddr)); - // length - const std::string inlength = toString("option inbound.length=", mSetting.inLength); - const std::string outlength = toString("option outbound.length=", mSetting.outLength); - // variance - const std::string invariance = toString("option inbound.lengthVariance=", mSetting.inVariance); - const std::string outvariance= toString("option outbound.lengthVariance=", mSetting.outVariance); - // quantity - const std::string inquantity = toString("option inbound.quantity=", mSetting.inQuantity); - const std::string outquantity= toString("option outbound.quantity=", mSetting.outQuantity); - const std::string quiet = "quiet true"; - const std::string start = "start"; - const std::string stop = "stop"; - const std::string clear = "clear"; - const std::string list = "list"; - const std::string quit = "quit"; - - // setup state machine - - // start chain - // -> A: server and client tunnel - mCommands[bsSetnickS] = {setnick, bsSetkeys}; - mCommands[bsSetkeys] = {setkeys, bsOuthost}; - mCommands[bsOuthost] = {outhost, bsOutport}; - mCommands[bsOutport] = {outport, bsInhost}; - // -> B: only client tunnel - mCommands[bsSetnickC] = {setnick, bsNewkeysC}; - mCommands[bsNewkeysC] = {newkeys, bsInhost}; - // -> both - mCommands[bsInhost] = {inhost, bsInport}; - mCommands[bsInport] = {inport, bsInlength}; - mCommands[bsInlength] = {inlength, bsOutlength}; - mCommands[bsOutlength] = {outlength, bsInvariance}; - mCommands[bsInvariance] = {invariance, bsOutvariance}; - mCommands[bsOutvariance]= {outvariance,bsInquantity}; - mCommands[bsInquantity] = {inquantity, bsOutquantity}; - mCommands[bsOutquantity]= {outquantity,bsQuiet}; - mCommands[bsQuiet] = {quiet, bsStart}; - mCommands[bsStart] = {start, bsQuit}; - mCommands[bsQuit] = {quit, bsCleared}; - - // stop chain - mCommands[bsGetnick] = {getnick, bsStop}; - mCommands[bsStop] = {stop, bsClear}; - mCommands[bsClear] = {clear, bsQuit}; - - // getkeys chain - mCommands[bsSetnickN] = {setnick, bsNewkeysN}; - mCommands[bsNewkeysN] = {newkeys, bsGetkeys}; - mCommands[bsGetkeys] = {getkeys, bsClear}; - - // list chain - mCommands[bsList] = {list, bsQuit}; -} - -void p3I2pBob::updateSettings_locked() -{ - RS_DBG4(""); - - sockaddr_storage proxy; - mPeerMgr->getProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy); - - peerState ps; - mPeerMgr->getOwnNetStatus(ps); - - const std::string setkeys = "setkeys " + mSetting.address.privateKey; - const std::string inhost = "inhost " + sockaddr_storage_iptostring(proxy); - const std::string inport = toString("inport ", sockaddr_storage_port(proxy)); - const std::string outhost = "outhost " + sockaddr_storage_iptostring(ps.localaddr); - const std::string outport = toString("outport ", sockaddr_storage_port(ps.localaddr)); - - // length - const std::string inlength = toString("option inbound.length=", mSetting.inLength); - const std::string outlength = toString("option outbound.length=", mSetting.outLength); - // variance - const std::string invariance = toString("option inbound.lengthVariance=", mSetting.inVariance); - const std::string outvariance= toString("option outbound.lengthVariance=", mSetting.outVariance); - // quantity - const std::string inquantity = toString("option inbound.quantity=", mSetting.inQuantity); - const std::string outquantity= toString("option outbound.quantity=", mSetting.outQuantity); - - mCommands[bsSetkeys] = {setkeys, bsOuthost}; - mCommands[bsOuthost] = {outhost, bsOutport}; - mCommands[bsOutport] = {outport, bsInhost}; - mCommands[bsInhost] = {inhost, bsInport}; - mCommands[bsInport] = {inport, bsInlength}; - - mCommands[bsInlength] = {inlength, bsOutlength}; - mCommands[bsOutlength] = {outlength, bsInvariance}; - mCommands[bsInvariance] = {invariance, bsOutvariance}; - mCommands[bsOutvariance]= {outvariance,bsInquantity}; - mCommands[bsInquantity] = {inquantity, bsOutquantity}; - mCommands[bsOutquantity]= {outquantity,bsQuiet}; -} - -std::string p3I2pBob::recv() -{ - // BOB works line based - // -> \n indicates and of the line - - constexpr uint16_t bufferSize = 128; - char buffer[bufferSize]; - - std::string ans; - uint16_t retry = 10; - - do { - memset(buffer, 0, bufferSize); - - // peek at data - auto length = ::recv(mSocket, buffer, bufferSize, MSG_PEEK); - if (length <= 0) { - if (length < 0) { - // error - perror(__PRETTY_FUNCTION__); - } - retry--; - doSleep(sleepTimeRecv); - continue; - } - - // at least one byte was read - - // search for new line - auto bufferStr = std::string(buffer); - size_t pos = bufferStr.find('\n'); - - if (pos == std::string::npos) { - // no new line found -> more to read - - // sanity check - if (length != bufferSize) { - // expectation: a full buffer was peeked) - RS_DBG1("peeked less than bufferSize but also didn't found a new line character"); - } - // this should never happen - assert(length <= bufferSize); - } else { - // new line found -> end of message - - // calculate how much there is to read, read the \n, too! - length = pos + 1; - - // end loop - retry = 0; - } - - // now read for real - memset(buffer, 0, bufferSize); - length = ::recv(mSocket, buffer, length, 0); - bufferStr = std::string(buffer); - ans.append(bufferStr); - } while(retry > 0); - - return ans; -} diff --git a/libretroshare/src/services/autoproxy/p3i2pbob.h b/libretroshare/src/services/autoproxy/p3i2pbob.h deleted file mode 100644 index 29bcbcb61..000000000 --- a/libretroshare/src/services/autoproxy/p3i2pbob.h +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: p3i2pbob.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3I2PBOB_H -#define P3I2PBOB_H - -#include -#include -#include -#include "util/rstime.h" -#ifndef WINDOWS_SYS - #include -#endif - -#include "pqi/p3cfgmgr.h" -#include "services/autoproxy/rsautoproxymonitor.h" -#include "util/rsthreads.h" -#include "util/i2pcommon.h" - -/* - * This class implements I2P BOB (BASIC OPEN BRIDGE) communication to allow RS - * to automatically remote control I2P to setup the needed tunnel. - * BOB is a simple text-based interface: https://geti2p.net/en/docs/api/bob - * - * Note 1: - * One tunnel is enough even for hidden locations since it can be used - * bidirectional. (In contrast to what RS I2P users had to set up manually.) - * - * Note 2: - * BOB tunnels are no SOCKS tunnel. Therefore pqissli2pbob implements a simplified - * proxy specially for BOB tunnels. - * - * Note 3: - * BOB needs a unique name as an ID for each tunnel. - * We use 'RetroShare-' + 8 random base32 characters. - * - * Design: - * The service uses three state machines to manage its task: - * int stateMachineBOB(); - * mBOBState - * int stateMachineController(); - * mState - * mTask - * - * stateMachineBOB: - * This state machine manages the low level communication with BOB. It basically has a linked - * list (currently a implemented as a std::map) that contains a command and the next - * state. - * Each high level operation (start up / shut down / get keys) is represented by a - * chain of states. E.g. the chain to retrieve new keys: - * mCommands[bobState::setnickN] = {setnick, bobState::newkeysN}; - * mCommands[bobState::newkeysN] = {newkeys, bobState::getkeys}; - * mCommands[bobState::getkeys] = {getkeys, bobState::clear}; - * mCommands[bobState::clear] = {clear, bobState::quit}; - * mCommands[bobState::quit] = {quit, bobState::cleared}; - * - * stateMachineController: - * This state machine manages the high level tasks. - * It is controlled by mState and mTask. - * - * mTast: - * Tracks the high level operation (like start up). - * It will keep its value even when a task is done to track - * the requested BOB state. - * When other operations are performed like a conection check - * the last task gets backed up and is later restored again - * - * mState: - * This state lives only for one operation an manages the communication - * with the BOB instance. This is basically connecting, starting BOB - * protocol and disconnecting - * - * How a task looks like: - * 1) RS sets task using the ticket system - * 2) stateMachineController connects to BOBs control port, sets mBobState to a lists head - * 3) stateMachineBOB processes command chain - * 4) stateMachineBOB is done and sets mBobState to cleared signaling that the connection - * is cleared and can be closed - * 5) stateMachineController disconnects from BOBs control port and updates mState - */ - -/// -/// \brief The controllerState enum -/// States for the controller to keep track of what he is currently doing -enum controllerState { - csIdel, - csDoConnect, - csConnected, - csWaitForBob, - csDoDisconnect, - csDisconnected, - csError -}; - -/// -/// \brief The controllerTask enum -/// This state tracks the controllers tast (e.g. setup a BOB tunnel or shut down -/// an existing one). -enum controllerTask { - ctIdle, - ctRunSetUp, - ctRunShutDown, - ctRunGetKeys, - ctRunCheck -}; - -/// -/// \brief The bobState enum -/// One state for each message -/// -enum bobState { - bsCleared, - bsSetnickC, // chain head for only client tunnel - bsSetnickN, // chain head for getting new (server) keys - bsSetnickS, // chain head for client and server tunnel - bsGetnick, - bsNewkeysC, // part of chain for only client tunnel - bsNewkeysN, // part of chain for getting new (server) keys - bsGetkeys, - bsSetkeys, - bsInhost, - bsOuthost, - bsInport, - bsOutport, - bsInlength, - bsOutlength, - bsInvariance, - bsOutvariance, - bsInquantity, - bsOutquantity, - bsQuiet, - bsStart, - bsStop, - bsClear, - bsList, // chain head for 'list' command - bsQuit -}; - -/// -/// \brief The bobStateInfo struct -/// State machine with commands -/// \todo This could be replaced by a linked list instead of a map -struct bobStateInfo { - std::string command; - bobState nextState; -}; - -struct bobSettings : i2p::settings {}; - -/// -/// \brief The bobStates struct -/// This container struct is used to pass all states. -/// Additionally, the tunnel name is included to to show it in the GUI. -/// The advantage of a struct is that it can be forward declared. -struct bobStates { - bobState bs; - controllerState cs; - controllerTask ct; - - std::string tunnelName; -}; - -class p3PeerMgr; - -class p3I2pBob : public RsTickingThread, public p3Config, public autoProxyService -{ -public: - explicit p3I2pBob(p3PeerMgr *peerMgr); - - // autoProxyService interface -public: - bool isEnabled(); - bool initialSetup(std::string &addr, uint16_t &); - void processTaskAsync(taskTicket *ticket); - void processTaskSync(taskTicket *ticket); - - void threadTick() override; /// @see RsTickingThread - -private: - int stateMachineBOB(); - int stateMachineBOB_locked_failure(const std::string &answer, const bobStateInfo ¤tState); - - int stateMachineController(); - int stateMachineController_locked_idle(); - int stateMachineController_locked_connected(); - int stateMachineController_locked_disconnected(); - int stateMachineController_locked_error(); - - // p3Config interface -protected: - RsSerialiser *setupSerialiser(); - bool saveList(bool &cleanup, std::list &lst); - bool loadList(std::list &load); - -private: - // helpers - void getBOBSettings(bobSettings *settings); - void setBOBSettings(const bobSettings *settings); - void getStates(bobStates *bs); - - std::string executeCommand(const std::string &command); - bool connectI2P(); - bool disconnectI2P(); - - void finalizeSettings_locked(); - void updateSettings_locked(); - - std::string recv(); - - // states for state machines - controllerState mState; - controllerTask mTask; - // used to store old state when in error state - // mStateOld is also used as a flag when an error occured in BOB protocol - controllerState mStateOld; - // mTaskOld is used to keep the previous task (start up / shut down) when requesting keys or checking the connection - controllerTask mTaskOld; - bobSettings mSetting; - bobState mBOBState; - - // used variables - p3PeerMgr *mPeerMgr; - bool mConfigLoaded; - int mSocket; - rstime_t mLastProxyCheck; - sockaddr_storage mI2PProxyAddr; - std::map mCommands; - std::string mErrorMsg; - std::string mTunnelName; - - std::queue mPending; - taskTicket *mProcessing; - - // mutex - RsMutex mLock; -}; - -#endif // P3I2PBOB_H diff --git a/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc b/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc deleted file mode 100644 index d58c871e3..000000000 --- a/libretroshare/src/services/autoproxy/rsautoproxymonitor.cc +++ /dev/null @@ -1,342 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: rsautoproximonitor.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsautoproxymonitor.h" - -#include /* for usleep() */ -#include "util/rsdebug.h" -#include "util/rstime.h" - -rsAutoProxyMonitor *rsAutoProxyMonitor::mInstance = NULL; - -rsAutoProxyMonitor::rsAutoProxyMonitor() - : mRSShutDown(false), mLock("rs auto proxy monitor") -{ - mProxies.clear(); -} - -rsAutoProxyMonitor *rsAutoProxyMonitor::instance() -{ - if (mInstance == NULL) - mInstance = new rsAutoProxyMonitor(); - return mInstance; -} - -void rsAutoProxyMonitor::addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service) -{ - RS_STACK_MUTEX(mLock); - if (mProxies.find(type) != mProxies.end()) { - RS_ERR("type ", type, " already added - OVERWRITING"); - print_stacktrace(); - } - - mProxies[type] = service; -} - -void rsAutoProxyMonitor::startAll() -{ - // create ticket - taskTicket *tt = getTicket(); - tt->cb = this; - tt->task = autoProxyTask::start; - - { - std::map::const_iterator it; - - // fill types - RS_STACK_MUTEX(mLock); - for (it = mProxies.begin(); it != mProxies.end(); ++it) - if (it->second->isEnabled()) - tt->types.push_back(it->first); - } - - task(tt); -} - -void rsAutoProxyMonitor::stopAll() -{ - // create ticket - taskTicket *tt = getTicket(); - tt->cb = this; - tt->task = autoProxyTask::stop; - - { - std::map::const_iterator it; - - // fill types - RS_STACK_MUTEX(mLock); - for (it = mProxies.begin(); it != mProxies.end(); ++it) - if (it->second->isEnabled()) - tt->types.push_back(it->first); - } - - task(tt); -} - -void rsAutoProxyMonitor::stopAllRSShutdown() -{ - { - RS_STACK_MUTEX(mLock); - mRSShutDown = true; - - // remove disabled services - std::vector toRemove; - std::map::const_iterator it; - for (it = mProxies.begin(); it != mProxies.end(); ++it) { - if (!it->second->isEnabled()) { - toRemove.push_back(it->first); - } - } - - std::vector::const_iterator it2; - for (it2 = toRemove.begin(); it2 != toRemove.end(); ++it2) { - mProxies.erase(*it2); - } - } - - // stop all remaining - stopAll(); - - // wait for shutdown of all services - uint32_t t = 0, timeout = 15; - do { - rstime::rs_usleep(1000 * 1000); - RS_STACK_MUTEX(mLock); - RS_DBG("waiting for auto proxy service(s) to shut down ", t, "/", timeout, " (remaining: ", mProxies.size(), ")"); - if (mProxies.empty()) - break; - t++; - } while (t < timeout ); -} - -bool rsAutoProxyMonitor::isEnabled(autoProxyType::autoProxyType_enum t) -{ - autoProxyService *s = lookUpService(t); - if (s == NULL) - return false; - - return s->isEnabled(); -} - -bool rsAutoProxyMonitor::initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port) -{ - autoProxyService *s = lookUpService(t); - if (s == NULL) - return false; - - return s->initialSetup(addr, port); -} - -void rsAutoProxyMonitor::task(taskTicket *ticket) -{ - // sanity checks - if (!ticket->async && ticket->types.size() > 1) { - RS_ERR("synchronous call to multiple services. This can cause problems!"); - print_stacktrace(); - } - if (ticket->async && !ticket->cb && ticket->data) { - RS_ERR("asynchronous call with data but no callback. This will likely causes memory leak!"); - print_stacktrace(); - } - if (ticket->types.size() > 1 && ticket->data) { - RS_ERR("call with data to multiple services. This will likely causes memory leak!"); - print_stacktrace(); - } - - std::vector::const_iterator it; - - for (it = ticket->types.begin(); it != ticket->types.end(); ++it) { - autoProxyService* s = lookUpService(*it); - if (s == NULL) - continue; - - if (ticket->async) { - // copy ticket - taskTicket *tt = new taskTicket(); - *tt = *ticket; - tt->types.clear(); - tt->types.push_back(*it); - - // it's async! - RsThread::async([s, tt] { - s->processTaskAsync(tt); - }); - } else { - s->processTaskSync(ticket); - } - } -} - -void rsAutoProxyMonitor::taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data) -{ - std::vector types; - types.push_back(type); - taskAsync(types, task, cb, data); -} - -void rsAutoProxyMonitor::taskAsync(std::vector types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb, void *data) -{ - if (!isAsyncTask(task)) { - // Usually the services will reject this ticket. - // Just print a warning - maybe there is some special case where this is a good idea. - RS_ERR("called with a synchronous task!"); - print_stacktrace(); - } - - taskTicket *tt = getTicket(); - tt->task = task; - tt->types = types; - if (cb) - tt->cb = cb; - if (data) - tt->data = data; - - instance()->task(tt); - // tickets were copied, clean up - delete tt; -} - -void rsAutoProxyMonitor::taskSync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data) -{ - std::vector types; - types.push_back(type); - taskSync(types, task, data); -} - -void rsAutoProxyMonitor::taskSync(std::vector types, autoProxyTask::autoProxyTask_enum task, void *data) -{ - if (isAsyncTask(task)) { - // Usually the services will reject this ticket. - // Just print a warning - maybe there is some special case where this is a good idea. - RS_ERR("called with an asynchronous task!"); - print_stacktrace(); - } - - taskTicket *tt = getTicket(); - tt->async = false; - tt->task = task; - tt->types = types; - if (data) - tt->data = data; - - instance()->task(tt); - // call done, clean up - delete tt; -} - -void rsAutoProxyMonitor::taskError(taskTicket *t) -{ - taskDone(t, autoProxyStatus::error); -} - -void rsAutoProxyMonitor::taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status) -{ - bool cleanUp = false; - - t->result = status; - if (t->cb) { - t->cb->taskFinished(t); - if (t != NULL) { - // callack did not clean up properly - RS_ERR("callback did not clean up!"); - print_stacktrace(); - cleanUp = true; - } - } else if (t->async){ - // async and no callback - // we must take care of deleting - cleanUp = true; - if(t->data) - RS_ERR("async call with data attached but no callback set!"); - } - - if (cleanUp) { - if (t->data) { - RS_ERR("will try to delete void pointer!"); - print_stacktrace(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdelete-incomplete" - delete t->data; -#pragma GCC diagnostic pop - t->data = NULL; - } - delete t; - t = NULL; - } -} - -taskTicket *rsAutoProxyMonitor::getTicket() -{ - taskTicket *tt = new taskTicket(); - tt->cb = NULL; - tt->data = NULL; - tt->async = true; - tt->result = autoProxyStatus::undefined; - return tt; -} - -void rsAutoProxyMonitor::taskFinished(taskTicket *&ticket) -{ - { - RS_STACK_MUTEX(mLock); - if (mRSShutDown && ticket->task == autoProxyTask::stop) { - mProxies.erase(ticket->types.front()); - } - } - - // clean up - if (ticket->data) { - RS_ERR(" data set. Will try to delete void pointer"); - print_stacktrace(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdelete-incomplete" - delete ticket->data; -#pragma GCC diagnostic pop - ticket->data = NULL; - } - delete ticket; - ticket = NULL; -} - -autoProxyService *rsAutoProxyMonitor::lookUpService(autoProxyType::autoProxyType_enum t) -{ - RS_STACK_MUTEX(mLock); - std::map::const_iterator itService; - if ((itService = mProxies.find(t)) != mProxies.end()) { - return itService->second; - } - RS_DBG("no service for type ", t, " found!"); - return NULL; -} - -bool rsAutoProxyMonitor::isAsyncTask(autoProxyTask::autoProxyTask_enum t) -{ - switch (t) { - case autoProxyTask::start: - case autoProxyTask::stop: - case autoProxyTask::receiveKey: - return true; - break; - default: - break; - } - return false; -} diff --git a/libretroshare/src/services/autoproxy/rsautoproxymonitor.h b/libretroshare/src/services/autoproxy/rsautoproxymonitor.h deleted file mode 100644 index d9a4c16aa..000000000 --- a/libretroshare/src/services/autoproxy/rsautoproxymonitor.h +++ /dev/null @@ -1,237 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services/autoproxy: rsautoproximonitor.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2016 by Sehraf * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSAUTOPROXYMONITOR_H -#define RSAUTOPROXYMONITOR_H - -#include -#include - -#include - -class autoProxyCallback; - -namespace autoProxyType { - enum autoProxyType_enum { - I2PBOB - }; -} - -namespace autoProxyTask { - enum autoProxyTask_enum { - /* async tasks */ - start, ///< start up proxy - stop, ///< shut down proxy - receiveKey, ///< renew proxy key (if any) - proxyStatusCheck, ///< use to check if the proxy is still running - /* sync tasks */ - status, ///< get status from auto proxy - getSettings, ///< get setting from auto proxy - setSettings, ///< set setting of auto proxy - reloadConfig, ///< signal config reload/rebuild - getErrorInfo ///< get error information from auto proxy - }; -} - -namespace autoProxyStatus { - enum autoProxyStatus_enum { - undefined, ///< undefined - usually not yet set - disabled, ///< used when a task cannot be done (e.g. a disabled service cannot be startet or stopped) - offline, ///< proxy is not set up - online, ///< proxy is set up - ok, ///< generic ok - error ///< generic error - }; -} - -struct taskTicket { - /// - /// \brief types auto proxy service types that should get the ticket - /// - std::vector types; - - /// - /// \brief task the task to satisfy - /// - autoProxyTask::autoProxyTask_enum task; - - /// - /// \brief cb (optional) callback that gets called once the task is done - /// - autoProxyCallback *cb; - - /// - /// \brief result (optional) result - /// - autoProxyStatus::autoProxyStatus_enum result; - - /// - /// \brief data (optional) service dependent data - /// - /// Needs to be allocated and freed by caller! - /// - void *data; - - /// - /// \brief async is the call Asynchronous - /// - /// Will create a copy of the ticket for each - /// service and delete the original ticket. - /// - bool async; -}; - -class autoProxyCallback { -public: - /// - /// \brief taskFinished called when a task is finished - /// \param ticket - /// - /// Remove everything: ticket and attached data if any! - /// - virtual void taskFinished(taskTicket *&ticket) = 0; -}; - -class autoProxyService { -public: - /// - /// \brief isEnabled must be provided to directly get a result without going through the ticket system - /// \return whether the auto proxy service is enabled or not - /// - virtual bool isEnabled() = 0; - - /// - /// \brief initialSetup used when creating a node - /// \param addr new address for the hidden service - /// \param port new port for the hidden service - /// \return true on success - /// - /// This function is used to do an initial setup when creating a new hidden node. - /// Nothing has been set up at this point to the auto proxy service must take care - /// of everything (e.g. starting (and stoping) of needed threads) - /// - virtual bool initialSetup(std::string &addr, uint16_t &port) = 0; - - /// - /// \brief processTaskAsync adds a ticket to the auto proxies task list - /// \param ticket - /// - /// Don't call the callback in this function as this can cause dead locks! - /// - virtual void processTaskAsync(taskTicket *ticket) = 0; - - /// - /// \brief processTaskSync taskTicket must be satisfied immediately - /// \param ticket - /// - virtual void processTaskSync(taskTicket *ticket) = 0; -}; - -class rsAutoProxyMonitor : autoProxyCallback -{ -public: - static rsAutoProxyMonitor *instance(); - - /// - /// \brief addProxy adds a new auto proxy service to the monitor - /// \param type type of the new auto proxy service - /// \param service pointer to the service - /// - void addProxy(autoProxyType::autoProxyType_enum type, autoProxyService *service); - - // global functions - void startAll(); - void stopAll(); - void stopAllRSShutdown(); - bool isEnabled(autoProxyType::autoProxyType_enum t); - // use this when creating a new node - bool initialSetup(autoProxyType::autoProxyType_enum t, std::string &addr, uint16_t &port); - - /// - /// \brief task Sends a task to all requested services - /// \param ticket Ticket containing required information - /// - /// There are two kind of tasks: asyn and sync. - /// All tasks that involve communication with the target program (e.g. I2P or Tor) are asynchronous. - /// All other task are synchronous (e.g. getting settings) - /// - /// - /// Synchronous: - /// When you want to get the settings from a service you can call task() with a ticket only listing - /// one service and data pointing to the service's settings class/struct. Set async to false so - /// that the service gets your original ticket. Ther service will process the request (get settings) - /// immediately and when the call to task() is done you can access the settings from your ticket. - /// - /// When additionally a call back is set the service will also call it. This can cause deadlocks! - /// - /// - /// Asynchronous: - /// When you want to start up all services or request new keys for all services you can call task() with a list - /// of services and set async to true. When each service has fullfilled the resquest he will - /// use the callback. The original caller ticket will be copied and each call to the callback - /// will use its copy of the original ticket. The attached data is not copied so each service gets - /// the same pointer! - /// - /// - /// Note: - /// Services should not delet or allocate anything unless no call back is provided and it is an - /// async call. In that case the service should delete the ticket and the attacked data. - /// Otherwise the caller must take care of cleaning up. - /// This class provides two wrappers to take care of this that should be used: taskError and taskDone - /// - /// Note2: - /// This function is private so that each user must use the wrappers taskAsync and taskSync that include - /// more sanity checks - /// -private: - void task(taskTicket *ticket); - -public: - static void taskAsync(autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL); - static void taskAsync(std::vector types, autoProxyTask::autoProxyTask_enum task, autoProxyCallback *cb = NULL, void *data = NULL); - static void taskSync (autoProxyType::autoProxyType_enum type, autoProxyTask::autoProxyTask_enum task, void *data = NULL); - static void taskSync (std::vector types, autoProxyTask::autoProxyTask_enum task, void *data = NULL); - - // usefull helpers - static void taskError(taskTicket *t); - static void taskDone(taskTicket *t, autoProxyStatus::autoProxyStatus_enum status); - static taskTicket *getTicket(); - - // autoProxyCallback interface -public: - void taskFinished(taskTicket *&ticket); - -private: - rsAutoProxyMonitor(); - - autoProxyService *lookUpService(autoProxyType::autoProxyType_enum t); - static bool isAsyncTask(autoProxyTask::autoProxyTask_enum t); - - std::map mProxies; - bool mRSShutDown; - RsMutex mLock; - - static rsAutoProxyMonitor *mInstance; -}; - - - -#endif // RSAUTOPROXYMONITOR_H diff --git a/libretroshare/src/services/broadcastdiscoveryservice.cc b/libretroshare/src/services/broadcastdiscoveryservice.cc deleted file mode 100644 index 076244b44..000000000 --- a/libretroshare/src/services/broadcastdiscoveryservice.cc +++ /dev/null @@ -1,319 +0,0 @@ -/******************************************************************************* - * RetroShare Broadcast Domain Discovery * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ - -#include "services/broadcastdiscoveryservice.h" -#include "retroshare/rspeers.h" -#include "serialiser/rsserializable.h" -#include "serialiser/rsserializer.h" -#include "retroshare/rsevents.h" - -/*extern*/ RsBroadcastDiscovery* rsBroadcastDiscovery = nullptr; - -struct BroadcastDiscoveryPack : RsSerializable -{ - BroadcastDiscoveryPack() : mLocalPort(0) {} - - RsPgpFingerprint mPgpFingerprint; - RsPeerId mSslId; - uint16_t mLocalPort; - std::string mProfileName; - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) override - { - RS_SERIAL_PROCESS(mPgpFingerprint); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mLocalPort); - RS_SERIAL_PROCESS(mProfileName); - } - - static BroadcastDiscoveryPack fromPeerDetails(const RsPeerDetails& pd) - { - BroadcastDiscoveryPack bdp; - bdp.mPgpFingerprint = pd.fpr; - bdp.mSslId = pd.id; - bdp.mLocalPort = pd.localPort; - bdp.mProfileName = pd.name; - return bdp; - } - - static BroadcastDiscoveryPack fromSerializedString(const std::string& st) - { - RsGenericSerializer::SerializeContext ctx( - reinterpret_cast(const_cast(st.data())), - static_cast(st.size()) ); - BroadcastDiscoveryPack bdp; - bdp.serial_process(RsGenericSerializer::DESERIALIZE, ctx); - return bdp; - } - - std::string serializeToString() - { - /* After some experiments it seems very unlikely that UDP broadcast - * packets bigger then this could get trought a network */ - std::vector buffer(512, 0); - RsGenericSerializer::SerializeContext ctx( - buffer.data(), static_cast(buffer.size()) ); - serial_process(RsGenericSerializer::SERIALIZE, ctx); - return std::string(reinterpret_cast(buffer.data()), ctx.mOffset); - } - - BroadcastDiscoveryPack(const BroadcastDiscoveryPack&) = default; - ~BroadcastDiscoveryPack() override; -}; - - -BroadcastDiscoveryService::BroadcastDiscoveryService( - RsPeers& pRsPeers ) : - mDiscoveredDataMutex("BroadcastDiscoveryService discovered data mutex"), - mRsPeers(pRsPeers) -{ - if(mRsPeers.isHiddenNode(mRsPeers.getOwnId())) return; - -#ifdef __ANDROID__ - createMulticastLock(); -#endif // def __ANDROID__ - - enableMulticastListening(); - - mUdcParameters.set_can_discover(true); - mUdcParameters.set_can_be_discovered(true); - mUdcParameters.set_port(port); - mUdcParameters.set_application_id(appId); - - mUdcPeer.Start(mUdcParameters, ""); - updatePublishedData(); -} - -BroadcastDiscoveryService::~BroadcastDiscoveryService() -{ - mUdcPeer.Stop(true); - disableMulticastListening(); -} - -std::vector -BroadcastDiscoveryService::getDiscoveredPeers() -{ - std::vector ret; - - RS_STACK_MUTEX(mDiscoveredDataMutex); - for(auto&& pp: mDiscoveredData) - ret.push_back(createResult(pp.first, pp.second)); - - return ret; -} - -void BroadcastDiscoveryService::updatePublishedData() -{ - RsPeerDetails od; - mRsPeers.getPeerDetails(mRsPeers.getOwnId(), od); - mUdcPeer.SetUserData( - BroadcastDiscoveryPack::fromPeerDetails(od).serializeToString()); -} - -void BroadcastDiscoveryService::threadTick() -{ - if( mUdcParameters.can_discover() && - !mRsPeers.isHiddenNode(mRsPeers.getOwnId()) ) - { - auto currentEndpoints = mUdcPeer.ListDiscovered(); - std::map currentMap; - std::map updateMap; - - mDiscoveredDataMutex.lock(); - for(auto&& dEndpoint: currentEndpoints) - { - currentMap[dEndpoint.ip_port()] = dEndpoint.user_data(); - - auto findIt = mDiscoveredData.find(dEndpoint.ip_port()); - if( !dEndpoint.user_data().empty() && ( - findIt == mDiscoveredData.end() || - findIt->second != dEndpoint.user_data() ) ) - updateMap[dEndpoint.ip_port()] = dEndpoint.user_data(); - } - mDiscoveredData = currentMap; - mDiscoveredDataMutex.unlock(); - - if(!updateMap.empty()) - { - for (auto&& pp : updateMap) - { - RsBroadcastDiscoveryResult rbdr = - createResult(pp.first, pp.second); - - const bool isFriend = mRsPeers.isFriend(rbdr.mSslId); - if( isFriend && rbdr.mLocator.hasPort() && - !mRsPeers.isOnline(rbdr.mSslId) ) - { - mRsPeers.setLocalAddress( - rbdr.mSslId, rbdr.mLocator.host(), - rbdr.mLocator.port() ); - mRsPeers.connectAttempt(rbdr.mSslId); - } - else if(!isFriend) - { - if(rsEvents) - { - auto ev = std::make_shared(); - - ev->mDiscoveryEventType = RsBroadcastDiscoveryEventType::PEER_FOUND; - ev->mData = rbdr; - - rsEvents->postEvent(ev); - } - } - } - } - } - - /* Probably this would be better if done only on actual change */ - if( mUdcParameters.can_be_discovered() && - !mRsPeers.isHiddenNode(mRsPeers.getOwnId()) ) updatePublishedData(); - - // This avoids waiting 5 secs when the thread should actually terminate (when RS closes). - for(uint32_t i=0;i<10;++i) - { - if(shouldStop()) - return; - rstime::rs_usleep(500*1000); // sleep for 0.5 sec. - } -} - -RsBroadcastDiscoveryResult BroadcastDiscoveryService::createResult( - const udpdiscovery::IpPort& ipp, const std::string& uData ) -{ - BroadcastDiscoveryPack bdp = - BroadcastDiscoveryPack::fromSerializedString(uData); - - RsBroadcastDiscoveryResult rbdr; - rbdr.mPgpFingerprint = bdp.mPgpFingerprint; - rbdr.mSslId = bdp.mSslId; - rbdr.mProfileName = bdp.mProfileName; - rbdr.mLocator. - setScheme("ipv4"). - setHost(UDC::IpToString(ipp.ip())). - setPort(bdp.mLocalPort); - - return rbdr; -} - -bool BroadcastDiscoveryService::isMulticastListeningEnabled() -{ -#ifdef __ANDROID__ - return assertMulticastLockIsvalid() && - mWifiMulticastLock.callMethod("isHeld"); -#endif // def __ANDROID__ - - return true; -} - -bool BroadcastDiscoveryService::enableMulticastListening() -{ -#ifdef __ANDROID__ - if(assertMulticastLockIsvalid() && !isMulticastListeningEnabled()) - { - mWifiMulticastLock.callMethod("acquire"); - return true; - } -#endif // def __ANDROID__ - - return false; -} - -bool BroadcastDiscoveryService::disableMulticastListening() -{ -#ifdef __ANDROID__ - if(assertMulticastLockIsvalid() && isMulticastListeningEnabled()) - { - mWifiMulticastLock.callMethod("release"); - return true; - } -#endif // def __ANDROID__ - - return false; -} - -#ifdef __ANDROID__ -bool BroadcastDiscoveryService::createMulticastLock() -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(mWifiMulticastLock.isValid()) - return failure("mWifiMulticastLock is already initialized"); - - QAndroidJniObject context = QtAndroid::androidContext(); - if(!context.isValid()) - return failure("Cannot retrieve Android context"); - - QAndroidJniObject WIFI_SERVICE = QAndroidJniObject::getStaticObjectField( - "android.content.Context", "WIFI_SERVICE", "Ljava/lang/String;"); - if(!WIFI_SERVICE.isValid()) - return failure("Cannot retrieve Context.WIFI_SERVICE value"); - - QAndroidJniObject wifiManager = context.callObjectMethod( - "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;", - WIFI_SERVICE.object() ); - if(!wifiManager.isValid()) - return failure("Cannot retrieve Android Wifi Manager"); - - mWifiMulticastLock = wifiManager.callObjectMethod( - "createMulticastLock", - "(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;", - QAndroidJniObject::fromString(fname).object() ); - if(!mWifiMulticastLock.isValid()) - return failure("Cannot create WifiManager.MulticastLock"); - - return true; -} - -bool BroadcastDiscoveryService::assertMulticastLockIsvalid() -{ - if(!mWifiMulticastLock.isValid()) - { - RsErr() << __PRETTY_FUNCTION__ << " mWifiMulticastLock is invalid!" - << std::endl; - print_stacktrace(); - return false; - } - return true; -} -#endif // def __ANDROID__ - -RsBroadcastDiscovery::~RsBroadcastDiscovery() = default; -RsBroadcastDiscoveryResult::~RsBroadcastDiscoveryResult() = default; -BroadcastDiscoveryPack::~BroadcastDiscoveryPack() = default; diff --git a/libretroshare/src/services/broadcastdiscoveryservice.h b/libretroshare/src/services/broadcastdiscoveryservice.h deleted file mode 100644 index ebbec04c1..000000000 --- a/libretroshare/src/services/broadcastdiscoveryservice.h +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * RetroShare Broadcast Domain Discovery * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -#include - -#ifdef __ANDROID__ -# include -#endif // def __ANDROID__ - -#include "retroshare/rsbroadcastdiscovery.h" -#include "util/rsthreads.h" -#include "util/rsdebug.h" - -namespace UDC = udpdiscovery; -class RsPeers; - -class BroadcastDiscoveryService : - public RsBroadcastDiscovery, public RsTickingThread -{ -public: - BroadcastDiscoveryService(RsPeers& pRsPeers); - ~BroadcastDiscoveryService() override; - - /// @see RsBroadcastDiscovery - std::vector getDiscoveredPeers() override; - - /// @see RsBroadcastDiscovery - bool isMulticastListeningEnabled() override; - - /// @see RsBroadcastDiscovery - bool enableMulticastListening() override; - - /// @see RsBroadcastDiscovery - bool disableMulticastListening() override; - - void threadTick() override; /// @see RsTickingThread - -protected: - constexpr static uint16_t port = 36405; - constexpr static uint32_t appId = 904571; - - void updatePublishedData(); - - UDC::PeerParameters mUdcParameters; - UDC::Peer mUdcPeer; - - std::map mDiscoveredData; - RsMutex mDiscoveredDataMutex; - - RsPeers& mRsPeers; // TODO: std::shared_ptr mRsPeers; - - RsBroadcastDiscoveryResult createResult( - const UDC::IpPort& ipp, const std::string& uData ); - -#ifdef __ANDROID__ - /** Android WifiManager.MulticastLock */ - QAndroidJniObject mWifiMulticastLock; - - /** Initialize the wifi multicast lock without acquiring it - * Needed to enable multicast listening in Android, for RetroShare broadcast - * discovery inspired by: - * https://github.com/flutter/flutter/issues/16335#issuecomment-420547860 - */ - bool createMulticastLock(); - - /** Return false if mWifiMulticastLock is invalid and print error messages */ - bool assertMulticastLockIsvalid(); - -#endif // def __ANDROID__ - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; diff --git a/libretroshare/src/services/p3banlist.cc b/libretroshare/src/services/p3banlist.cc deleted file mode 100644 index a257d2772..000000000 --- a/libretroshare/src/services/p3banlist.cc +++ /dev/null @@ -1,1303 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3banlist.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/p3servicecontrol.h" -#include "pqi/p3netmgr.h" -#include "pqi/p3cfgmgr.h" - -#include "util/rsnet.h" - -#include "services/p3banlist.h" -#include "retroshare/rsdht.h" -#include "retroshare/rsbanlist.h" - -#include "rsitems/rsbanlistitems.h" -#include "rsitems/rsconfigitems.h" - -#include -#include - -/**** - * #define DEBUG_BANLIST 1 - ****/ -// #define DEBUG_BANLIST 1 -//#define DEBUG_BANLIST_CONDENSE 1 - - -/* DEFINE INTERFACE POINTER! */ -//RsBanList *rsBanList = NULL; - -#define RSBANLIST_ENTRY_MAX_AGE (60 * 60 * 24) // 24 HOURS -#define RSBANLIST_SEND_PERIOD 600 // 10 Minutes. - -#define RSBANLIST_DELAY_BETWEEN_TALK_TO_DHT 240 // every 4 mins. - -/************ IMPLEMENTATION NOTES ********************************* - * - * Get Bad Peers passed to us (from DHT mainly). - * we distribute and track the network list of bad peers. - * - */ -RsBanList *rsBanList = NULL ; - -p3BanList::p3BanList(p3ServiceControl *sc, p3NetMgr */*nm*/) - : p3Service(), mBanMtx("p3BanList"), mServiceCtrl(sc) - , mSentListTime(0), mLastDhtInfoRequest(0) - // default number of IPs in same range to trigger a complete IP /24 filter. - , mAutoRangeLimit(2), mAutoRangeIps(true) - , mIPFilteringEnabled(true) - , mIPFriendGatheringEnabled(false) - , mIPDHTGatheringEnabled(false) -{ addSerialType(new RsBanListSerialiser()); } - -const std::string BANLIST_APP_NAME = "banlist"; -const uint16_t BANLIST_APP_MAJOR_VERSION = 1; -const uint16_t BANLIST_APP_MINOR_VERSION = 0; -const uint16_t BANLIST_MIN_MAJOR_VERSION = 1; -const uint16_t BANLIST_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3BanList::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_BANLIST, - BANLIST_APP_NAME, - BANLIST_APP_MAJOR_VERSION, - BANLIST_APP_MINOR_VERSION, - BANLIST_MIN_MAJOR_VERSION, - BANLIST_MIN_MINOR_VERSION); -} - -bool p3BanList::ipFilteringEnabled() { return mIPFilteringEnabled ; } -void p3BanList::enableIPFiltering(bool b) { mIPFilteringEnabled = b ; } -void p3BanList::enableIPsFromFriends(bool b) { mIPFriendGatheringEnabled = b; mLastDhtInfoRequest=0;} -void p3BanList::enableIPsFromDHT(bool b) -{ - mIPDHTGatheringEnabled = b; - mLastDhtInfoRequest=0; - - IndicateConfigChanged(); -} -void p3BanList::enableAutoRange(bool b) -{ - mAutoRangeIps = b; - autoFigureOutBanRanges() ; - - IndicateConfigChanged(); -} -void p3BanList::setAutoRangeLimit(int n) -{ - mAutoRangeLimit = n; - autoFigureOutBanRanges(); - - IndicateConfigChanged(); -} - -namespace services { - -class ZeroedInt -{ - public: - ZeroedInt() { n = 0 ; } - uint32_t n ; -}; - -} - -BanListPeer::BanListPeer() -{ - memset(&addr, 0, sizeof(addr)); - masked_bytes=0; - reason=RSBANLIST_REASON_UNKNOWN ; - level=RSBANLIST_ORIGIN_UNKNOWN ; - state = true ; - connect_attempts=0; - mTs=0; -} - -void BanListPeer::toRsTlvBanListEntry(RsTlvBanListEntry &e) const -{ - e.addr.addr = addr; - e.masked_bytes = masked_bytes; - e.reason = reason; - e.level = level; - e.comment = comment; - e.age = time(NULL) - mTs; -} - -void BanListPeer::fromRsTlvBanListEntry(const RsTlvBanListEntry &e) -{ - addr = e.addr.addr; - masked_bytes = e.masked_bytes; // 0 = []/32. 1=[]/24, 2=[]/16 - reason = e.reason; // User, DHT - level = e.level; // LOCAL, FRIEND, FoF. - state = true; // true=>active, false=>just stored but inactive - connect_attempts = 0; // recorded by the BanList service - comment = e.comment; // recorded by the BanList service - mTs = time(NULL) - e.age; -} - -static uint32_t getBitRange(const sockaddr_storage& addr) -{ - sockaddr_storage s ; - sockaddr_storage_clear(s) ; - sockaddr_storage_copyip(s,addr) ; - - sockaddr_in *ad = (sockaddr_in*)(&s) ; - - if( (ad->sin_addr.s_addr & 0xff000000) != 0xff000000) - return 0 ; - - if( (ad->sin_addr.s_addr & 0x00ff0000) != 0x00ff0000) - return 1 ; - - if( (ad->sin_addr.s_addr & 0x0000ff00) != 0x0000ff00) - return 2 ; - - if( (ad->sin_addr.s_addr & 0x000000ff) != 0x000000ff) - return 3 ; - - return 4 ; -} -static sockaddr_storage makeBitsRange(const sockaddr_storage& addr,int masked_bytes) -{ - sockaddr_storage s ; - sockaddr_storage_clear(s) ; - sockaddr_storage_copyip(s,addr) ; - - sockaddr_in *ad = (sockaddr_in*)(&s) ; - - if(masked_bytes == 1) - ad->sin_addr.s_addr |= 0xff000000 ; - else if(masked_bytes == 2) - ad->sin_addr.s_addr |= 0xffff0000 ; - else if(masked_bytes != 0) - std::cerr << "Warning: unhandled mask size for IP range: " << masked_bytes << std::endl; - - return s ; -} - -void p3BanList::autoFigureOutBanRanges() -{ - RS_STACK_MUTEX(mBanMtx) ; - - // clear automatic ban ranges - - for(std::map::iterator it(mBanRanges.begin()); - it!=mBanRanges.end(); ) - { - if(it->second.reason == RSBANLIST_REASON_AUTO_RANGE) - { - std::map::iterator it2=it ; - ++it2 ; - mBanRanges.erase(it) ; - it=it2 ; - } - else ++it; - } - - IndicateConfigChanged(); - - if(!mAutoRangeIps) return; - -#ifdef DEBUG_BANLIST - std::cerr << "Automatically figuring out IP ranges from banned IPs." << std::endl; -#endif - - std::map range_map ; - - for(std::map::iterator it(mBanSet.begin());it!=mBanSet.end();++it) - ++range_map[makeBitsRange(it->first,1)].n ; - - rstime_t now = time(NULL) ; - - for(std::map::const_iterator it=range_map.begin();it!=range_map.end();++it) - { -#ifdef DEBUG_BANLIST - std::cerr << "Ban range: " << sockaddr_storage_iptostring(it->first) << " : " << it->second.n << std::endl; -#endif - - if(it->second.n >= mAutoRangeLimit) - { -#ifdef DEBUG_BANLIST - std::cerr << " --> creating new ban range." << std::endl; -#endif - BanListPeer& peer(mBanRanges[it->first]) ; - - if (peer.reason == RSBANLIST_REASON_USER) - continue; - - peer.addr = it->first ; - peer.masked_bytes = 1 ; - peer.reason = RSBANLIST_REASON_AUTO_RANGE ; - peer.level = RSBANLIST_ORIGIN_SELF ; - peer.state = true ; - peer.mTs = now ; - peer.connect_attempts = 0 ; - peer.connect_attempts = it->second.n; - } - } - - condenseBanSources_locked() ; -} - -bool p3BanList::acceptedBanSet_locked(const BanListPeer& blp) -{ - // REASON_USER REASON_DHT REASON_AUTO - // --------------------------------------------------------- - // banDHT Y/Y/N Y/Y/Y - // --------------------------------------------------------- - // banFriends - // --------------------------------------------------------- - // banAutoRanges - // - - if(blp.level > 1 && mIPFriendGatheringEnabled) - return true ; - - switch(blp.reason) - { - case RSBANLIST_REASON_USER: return true ; - - case RSBANLIST_REASON_DHT: return mIPDHTGatheringEnabled && blp.level==1; - - default: - case RSBANLIST_REASON_AUTO_RANGE: std::cerr << "(EE) Shouldn't find an AUTO RANGE in BanSet. Wrong call?" << std::endl; - return false ; - } - return false ; -} -bool p3BanList::acceptedBanRanges_locked(const BanListPeer& blp) -{ - // REASON_USER REASON_DHT REASON_AUTO - // --------------------------------------------------------- - // banDHT Y/Y/N Y/Y/Y - // --------------------------------------------------------- - // banFriends - // --------------------------------------------------------- - // banAutoRanges - // - - switch(blp.reason) - { - case RSBANLIST_REASON_USER: return true ; - - default: - case RSBANLIST_REASON_DHT: std::cerr << "(EE) Shouldn't find a DHT ip in BanRange. Wrong call?" << std::endl; - return false ; - - case RSBANLIST_REASON_AUTO_RANGE: return mAutoRangeIps ; - } - return false ; -} - -bool p3BanList::isAddressAccepted( - const sockaddr_storage& dAddr, uint32_t checking_flags, - uint32_t& check_result ) -{ - check_result = RSBANLIST_CHECK_RESULT_NOCHECK; - - sockaddr_storage addr; sockaddr_storage_copy(dAddr, addr); - - if(!sockaddr_storage_ipv6_to_ipv4(addr)) return true; - if(sockaddr_storage_isLoopbackNet(addr)) return true; - - - RS_STACK_MUTEX(mBanMtx); - - if(!mIPFilteringEnabled) return true; - -#ifdef DEBUG_BANLIST - std::cerr << "isAddressAccepted(): tested addr=" << sockaddr_storage_iptostring(addr) << ", checking flags=" << checking_flags ; -#endif - - // we should normally work this including entire ranges of IPs. For now, just check the exact IPs. - - sockaddr_storage addr_32 = makeBitsRange(addr,0) ; // this is necessay because it cleans the address - sockaddr_storage addr_24 = makeBitsRange(addr,1) ; - sockaddr_storage addr_16 = makeBitsRange(addr,2) ; - - bool white_list_found = false ; - - white_list_found = white_list_found || (mWhiteListedRanges.find(addr_16) != mWhiteListedRanges.end()) ; - white_list_found = white_list_found || (mWhiteListedRanges.find(addr_24) != mWhiteListedRanges.end()) ; - white_list_found = white_list_found || (mWhiteListedRanges.find(addr_32) != mWhiteListedRanges.end()) ; - - if(white_list_found) - { - check_result = RSBANLIST_CHECK_RESULT_ACCEPTED; -#ifdef DEBUG_BANLIST - std::cerr << ". Address is in whitelist. Accepting" << std::endl; -#endif - return true ; - } - - if(checking_flags & RSBANLIST_CHECKING_FLAGS_WHITELIST) - { - check_result = RSBANLIST_CHECK_RESULT_NOT_WHITELISTED; -#ifdef DEBUG_BANLIST - std::cerr << ". Address is not whitelist, and whitelist is required. Rejecting" << std::endl; -#endif - return false ; - } - - if(!(checking_flags & RSBANLIST_CHECKING_FLAGS_BLACKLIST)) - { -#ifdef DEBUG_BANLIST - std::cerr << ". No blacklisting required. Accepting." << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_ACCEPTED; - return true; - } - - std::map::iterator it ; - - if(((it=mBanRanges.find(addr_16)) != mBanRanges.end()) && acceptedBanRanges_locked(it->second)) - { - ++it->second.connect_attempts; -#ifdef DEBUG_BANLIST - std::cerr << " found in blacklisted range " << sockaddr_storage_iptostring(it->first) << "/16. returning false. attempts=" << it->second.connect_attempts << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED; - return false ; - } - - if(((it=mBanRanges.find(addr_24)) != mBanRanges.end()) && acceptedBanRanges_locked(it->second)) - { - ++it->second.connect_attempts; -#ifdef DEBUG_BANLIST - std::cerr << " found in blacklisted range " << sockaddr_storage_iptostring(it->first) << "/24. returning false. attempts=" << it->second.connect_attempts << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED; - return false ; - } - - if(((it=mBanRanges.find(addr_32)) != mBanRanges.end()) && acceptedBanRanges_locked(it->second)) - { - ++it->second.connect_attempts; -#ifdef DEBUG_BANLIST - std::cerr << " found in blacklisted range " << sockaddr_storage_iptostring(it->first) << "/32. returning false. attempts=" << it->second.connect_attempts << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED; - return false ; - } - - if((it=mBanSet.find(addr_32)) != mBanSet.end() && acceptedBanSet_locked(it->second)) - { - ++it->second.connect_attempts; -#ifdef DEBUG_BANLIST - std::cerr << "found as blacklisted address " << sockaddr_storage_iptostring(it->first) << ". returning false. attempts=" << it->second.connect_attempts << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_BLACKLISTED; - return false ; - } - -#ifdef DEBUG_BANLIST - std::cerr << " not blacklisted. Accepting." << std::endl; -#endif - check_result = RSBANLIST_CHECK_RESULT_ACCEPTED; - return true ; -} - -void p3BanList::getWhiteListedIps(std::list &lst) -{ - RS_STACK_MUTEX(mBanMtx) ; - - lst.clear() ; - for(std::map::const_iterator it(mWhiteListedRanges.begin());it!=mWhiteListedRanges.end();++it) - lst.push_back(it->second) ; -} -void p3BanList::getBannedIps(std::list &lst) -{ - RS_STACK_MUTEX(mBanMtx) ; - - - lst.clear() ; - for(std::map::const_iterator it(mBanSet.begin());it!=mBanSet.end();++it) - { - if(!acceptedBanSet_locked(it->second)) - continue ; - - std::map::const_iterator found1 = mBanRanges.find(makeBitsRange(it->first,1)) ; - - if(found1!=mBanRanges.end() && acceptedBanRanges_locked(found1->second)) - continue ; - - std::map::const_iterator found2 = mBanRanges.find(makeBitsRange(it->first,2)) ; - - if(found2!=mBanRanges.end() && acceptedBanRanges_locked(found2->second)) - continue ; - - lst.push_back(it->second) ; - } - - for(std::map::const_iterator it(mBanRanges.begin());it!=mBanRanges.end();++it) - if(acceptedBanRanges_locked(it->second)) - lst.push_back(it->second) ; -} - -bool p3BanList::removeIpRange( const struct sockaddr_storage& dAddr, - int masked_bytes, uint32_t list_type ) -{ - sockaddr_storage addr; sockaddr_storage_copy(dAddr, addr); - if(!sockaddr_storage_ipv6_to_ipv4(addr)) - { - std::cerr << __PRETTY_FUNCTION__ << " Cannot handle " - << sockaddr_storage_tostring(dAddr) - << " IPv6 not implemented yet!" - << std::endl; - return false; - } - - RS_STACK_MUTEX(mBanMtx); - - bool changed = false; - std::map::iterator it ; - - if(list_type == RSBANLIST_TYPE_BLACKLIST) - { - if( mBanRanges.end() != (it = mBanRanges.find(makeBitsRange(addr,masked_bytes)))) - { - mBanRanges.erase(it) ; - IndicateConfigChanged(); - changed = true; - } - } - else if(list_type == RSBANLIST_TYPE_WHITELIST) - { - if( mWhiteListedRanges.end() != (it = mWhiteListedRanges.find(makeBitsRange(addr,masked_bytes)))) - { - mWhiteListedRanges.erase(it) ; - IndicateConfigChanged(); - changed = true; - } - } - else - std::cerr << "(EE) Only whitelist or blacklist ranges can be removed." << std::endl; - - condenseBanSources_locked() ; - return changed; -} - -bool p3BanList::addIpRange( const sockaddr_storage &dAddr, int masked_bytes, - uint32_t list_type, const std::string& comment ) -{ - sockaddr_storage addr; sockaddr_storage_copy(dAddr, addr); - if(!sockaddr_storage_ipv6_to_ipv4(addr)) - { - std::cerr << __PRETTY_FUNCTION__ << " Cannot handle " - << sockaddr_storage_tostring(dAddr) - << " IPv6 not implemented yet!" - << std::endl; - return false; - } - - RS_STACK_MUTEX(mBanMtx); - - 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 ; - } - - BanListPeer blp ; - blp.level = RSBANLIST_ORIGIN_SELF ; - blp.connect_attempts = 0 ; - blp.addr = addr ; - blp.masked_bytes = masked_bytes ; - blp.mTs = time(NULL) ; - blp.reason = RSBANLIST_REASON_USER; - blp.comment = comment ; - - if(masked_bytes != 0 && masked_bytes != 1 && masked_bytes != 2) - { - std::cerr << "Unhandled masked byte size " << masked_bytes << ". Should be 0,1 or 2" << std::endl; - return false; - } - if(list_type != RSBANLIST_TYPE_BLACKLIST && list_type != RSBANLIST_TYPE_WHITELIST) - { - std::cerr << "(EE) Cannot add IP range. Bad list_type. Should be eiter RSBANLIST_TYPE_BLACKLIST or RSBANLIST_TYPE_WHITELIST" << std::endl; - return false ; - } - - // Remove all existing ranges that are included into current range. - - std::map& banlist( (list_type == RSBANLIST_TYPE_BLACKLIST)?mBanRanges:mWhiteListedRanges) ; - - for(int i=0;i::iterator it = banlist.find(makeBitsRange(addr,i)) ; - - if(it != banlist.end()) - banlist.erase(it) ; - } - // Add range to list. - - banlist[makeBitsRange(addr,masked_bytes)] = blp ; - - IndicateConfigChanged() ; - condenseBanSources_locked() ; - - return true; -} - -int p3BanList::tick() -{ - processIncoming(); - sendPackets(); - - rstime_t now = time(NULL) ; - - if(mLastDhtInfoRequest + RSBANLIST_DELAY_BETWEEN_TALK_TO_DHT < now) - { - getDhtInfo() ; // This is always done, since these IPs are also sent to friends. - - mLastDhtInfoRequest = now; - - if(mAutoRangeIps) - autoFigureOutBanRanges() ; - } - -#ifdef DEBUG_BANLIST - static rstime_t last_print = 0 ; - - if(now > 10+last_print) - { - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - printBanSet_locked(std::cerr); - last_print = now ; - } -#endif - - return 0; -} - -void p3BanList::getDhtInfo() -{ - // Get the list of masquerading peers from the DHT. Add them as potential IPs to be banned. - // Don't make them active. Just insert them in the list. - - std::list filtered_peers ; - - rsDht->getListOfBannedIps(filtered_peers) ; - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::getDhtInfo() Got list of banned IPs." << std::endl; -#endif - RsPeerId ownId = mServiceCtrl->getOwnId(); - - for(std::list::const_iterator it(filtered_peers.begin());it!=filtered_peers.end();++it) - { -#ifdef DEBUG_BANLIST - std::cerr << " filtered peer: " << rs_inet_ntoa((*it).mAddr.sin_addr) << std::endl; -#endif - - int int_reason = RSBANLIST_REASON_DHT ; - int time_stamp = (*it).mLastSeen ; - - sockaddr_storage ad ; - sockaddr_storage_setipv4(ad,&(*it).mAddr) ; - - addBanEntry(ownId, ad, RSBANLIST_ORIGIN_SELF, int_reason, time_stamp); - } - - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - condenseBanSources_locked() ; -} - -/***** Implementation ******/ - -bool p3BanList::processIncoming() -{ - /* for each packet - pass to specific handler */ - RsItem *item = NULL; - bool updated = false; - while(NULL != (item = recvItem())) - { -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::processingIncoming() Received Item:"; - std::cerr << std::endl; - item->print(std::cerr); - std::cerr << std::endl; -#endif - switch(item->PacketSubType()) - { - default: - break; - case RS_PKT_SUBTYPE_BANLIST_ITEM: - { - // Order is important!. - updated = (recvBanItem((RsBanListItem *) item) || updated); - } - break; - } - - /* clean up */ - delete item; - } - - if (updated) - { - { - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - - condenseBanSources_locked(); - } - - /* pass list to NetAssist */ - - } - - return true ; -} - - -bool p3BanList::recvBanItem(RsBanListItem *item) -{ - bool updated = false; - - rstime_t now = time(NULL) ; - std::list::const_iterator it; - - for(it = item->peerList.mList.begin(); it != item->peerList.mList.end(); ++it) - { - // Order is important!. - updated = (addBanEntry(item->PeerId(), it->addr.addr, it->level, it->reason, now - it->age) || updated); - } - return updated; -} - -/* overloaded from pqiNetAssistSharePeer */ -void p3BanList::updatePeer( const RsPeerId& /*id*/, - const sockaddr_storage &dAddr, - int /*type*/, int /*reason*/, int time_stamp ) -{ - sockaddr_storage addr; sockaddr_storage_copy(dAddr, addr); - if(!sockaddr_storage_ipv6_to_ipv4(addr)) - { - std::cerr << __PRETTY_FUNCTION__ << " Cannot handle " - << sockaddr_storage_tostring(dAddr) - << " IPv6 not implemented yet!" - << std::endl; - return; - } - - RsPeerId ownId = mServiceCtrl->getOwnId(); - - int int_reason = RSBANLIST_REASON_DHT; - - addBanEntry(ownId, addr, RSBANLIST_ORIGIN_SELF, int_reason, time_stamp); - - /* process */ - { - RS_STACK_MUTEX(mBanMtx); - condenseBanSources_locked(); - } -} - -RsSerialiser *p3BanList::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - - rss->addSerialType(new RsBanListSerialiser()) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss ; -} - -bool p3BanList::saveList(bool &cleanup, std::list& itemlist) -{ - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - - cleanup = true ; - - for(std::map::const_iterator it(mBanSources.begin());it!=mBanSources.end();++it) - { - RsBanListConfigItem *item = new RsBanListConfigItem ; - - item->banListType = RSBANLIST_TYPE_PEERLIST ; - item->banListPeerId = it->second.mPeerId ; - item->update_time = it->second.mLastUpdate ; - item->banned_peers.TlvClear() ; - - for(std::map::const_iterator it2 = it->second.mBanPeers.begin();it2!=it->second.mBanPeers.end();++it2) - { - RsTlvBanListEntry e ; - it2->second.toRsTlvBanListEntry(e) ; - - item->banned_peers.mList.push_back(e) ; - } - - itemlist.push_back(item) ; - } - - // Add whitelist - RsBanListConfigItem *item = new RsBanListConfigItem ; - - item->banListType = RSBANLIST_TYPE_WHITELIST ; - item->banListPeerId.clear() ; - item->update_time = 0 ; - item->banned_peers.TlvClear() ; - - for(std::map::const_iterator it2 = mWhiteListedRanges.begin();it2!=mWhiteListedRanges.end();++it2) - { - RsTlvBanListEntry e ; - it2->second.toRsTlvBanListEntry(e) ; - - item->banned_peers.mList.push_back(e) ; - } - - itemlist.push_back(item) ; - - // addblacklist - - item = new RsBanListConfigItem ; - - item->banListType = RSBANLIST_TYPE_BLACKLIST ; - item->banListPeerId.clear(); - item->update_time = 0 ; - item->banned_peers.TlvClear() ; - - for(std::map::const_iterator it2 = mBanRanges.begin();it2!=mBanRanges.end();++it2) - { - RsTlvBanListEntry e ; - it2->second.toRsTlvBanListEntry(e) ; - - item->banned_peers.mList.push_back(e) ; - } - - itemlist.push_back(item) ; - - // Other variables - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - - RsTlvKeyValue kv; - - kv.key = "IP_FILTERING_ENABLED"; - kv.value = mIPFilteringEnabled?"TRUE":"FALSE" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "IP_FILTERING_AUTORANGE_IPS"; - kv.value = mAutoRangeIps?"TRUE":"FALSE" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "IP_FILTERING_FRIEND_GATHERING_ENABLED"; - kv.value = mIPFriendGatheringEnabled?"TRUE":"FALSE" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "IP_FILTERING_DHT_GATHERING_ENABLED"; - kv.value = mIPDHTGatheringEnabled?"TRUE":"FALSE" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "IP_FILTERING_AUTORANGE_IPS_LIMIT" ; - std::ostringstream os ; - os << mAutoRangeLimit ; - os.flush() ; - kv.value = os.str() ; - vitem->tlvkvs.pairs.push_back(kv) ; - - itemlist.push_back(vitem) ; - - return true ; -} - -bool p3BanList::loadList(std::list& load) -{ - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - - for(std::list::const_iterator it(load.begin());it!=load.end();++it) - { - RsConfigKeyValueSet *vitem = dynamic_cast( *it ) ; - - if(vitem != NULL) - for(std::list::const_iterator it2(vitem->tlvkvs.pairs.begin());it2!=vitem->tlvkvs.pairs.end();++it2) - { - if(it2->key == "IP_FILTERING_ENABLED") mIPFilteringEnabled = (it2->value=="TRUE") ; - if(it2->key == "IP_FILTERING_AUTORANGE_IPS") mAutoRangeIps = (it2->value=="TRUE") ; - if(it2->key == "IP_FILTERING_FRIEND_GATHERING_ENABLED") mIPFriendGatheringEnabled = (it2->value=="TRUE") ; - if(it2->key == "IP_FILTERING_DHT_GATHERING_ENABLED") mIPDHTGatheringEnabled = (it2->value=="TRUE") ; - - if(it2->key == "IP_FILTERING_AUTORANGE_IPS_LIMIT") - { - int val ; - if(sscanf(it2->value.c_str(),"%d",&val) == 1) - mAutoRangeLimit = val ; - } - } - - RsBanListConfigItem *citem = dynamic_cast( *it ) ; - - if(citem != NULL) - { - if(citem->banListType == RSBANLIST_TYPE_PEERLIST) - { - BanList& bl(mBanSources[citem->banListPeerId]) ; - - bl.mPeerId = citem->banListPeerId ; - bl.mLastUpdate = citem->update_time ; - - bl.mBanPeers.clear() ; - - for(std::list::const_iterator it2(citem->banned_peers.mList.begin());it2!=citem->banned_peers.mList.end();++it2) - { - BanListPeer blp ; - blp.fromRsTlvBanListEntry(*it2) ; - - if(sockaddr_storage_isValidNet(blp.addr)) - bl.mBanPeers[blp.addr] = blp ; - else - std::cerr << "(WW) removed wrong address " << sockaddr_storage_iptostring(blp.addr) << std::endl; - } - } - else if(citem->banListType == RSBANLIST_TYPE_BLACKLIST) - { - mBanRanges.clear() ; - - for(std::list::const_iterator it2(citem->banned_peers.mList.begin());it2!=citem->banned_peers.mList.end();++it2) - { - BanListPeer blp ; - blp.fromRsTlvBanListEntry(*it2) ; - - if(sockaddr_storage_isValidNet(blp.addr)) - mBanRanges[makeBitsRange(blp.addr,blp.masked_bytes)] = blp ; - else - std::cerr << "(WW) removed wrong address " << sockaddr_storage_iptostring(blp.addr) << std::endl; - } - } - else if(citem->banListType == RSBANLIST_TYPE_WHITELIST) - { - mWhiteListedRanges.clear() ; - - for(std::list::const_iterator it2(citem->banned_peers.mList.begin());it2!=citem->banned_peers.mList.end();++it2) - { - BanListPeer blp ; - blp.fromRsTlvBanListEntry(*it2) ; - - if(sockaddr_storage_isValidNet(blp.addr)) - mWhiteListedRanges[makeBitsRange(blp.addr,blp.masked_bytes)] = blp ; - else - std::cerr << "(WW) removed wrong address " << sockaddr_storage_iptostring(blp.addr) << std::endl; - - std::cerr << "Read whitelisted range " << sockaddr_storage_iptostring(blp.addr) << "/" << 32 - 8*(blp.masked_bytes) << std::endl; - } - } - else - std::cerr << "(EE) BanList item unknown type " << citem->banListType << ". This is a bug." << std::endl; - } - - delete *it ; - } - - load.clear() ; - return true ; -} - -bool p3BanList::addBanEntry( const RsPeerId &peerId, - const sockaddr_storage &dAddr, - int level, uint32_t reason, rstime_t time_stamp ) -{ - sockaddr_storage addr; sockaddr_storage_copy(dAddr, addr); - if(!sockaddr_storage_ipv6_to_ipv4(addr)) - { - std::cerr << __PRETTY_FUNCTION__ << " Cannot handle " - << sockaddr_storage_tostring(dAddr) - << " IPv6 not implemented yet!" - << std::endl; - return false; - } - - RS_STACK_MUTEX(mBanMtx); - - rstime_t now = time(NULL); - bool updated = false; - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::addBanEntry() Addr: " << sockaddr_storage_iptostring(addr) << " Origin: " << level; - std::cerr << " Reason: " << reason << " Age: " << now - time_stamp; - std::cerr << std::endl; -#endif - - /* Only Accept it - if external address */ - if (!sockaddr_storage_isExternalNet(addr)) - { -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::addBanEntry() Ignoring Non External Addr: " << sockaddr_storage_iptostring(addr); - std::cerr << std::endl; -#endif - return false; - } - - - std::map::iterator it; - it = mBanSources.find(peerId); - if (it == mBanSources.end()) - { - BanList bl; - bl.mPeerId = peerId; - bl.mLastUpdate = now; - mBanSources[peerId] = bl; - - it = mBanSources.find(peerId); - updated = true; - } - - // index is FAMILY + IP - the rest should be Zeros.. - struct sockaddr_storage bannedaddr; - sockaddr_storage_clear(bannedaddr); - bannedaddr.ss_family = AF_INET ; - sockaddr_storage_copyip(bannedaddr, addr); - sockaddr_storage_setport(bannedaddr, 0); - - std::map::iterator mit; - mit = it->second.mBanPeers.find(bannedaddr); - if (mit == it->second.mBanPeers.end()) - { - /* add in */ - BanListPeer blp; - blp.addr = addr; - blp.reason = reason; - blp.level = level; - blp.mTs = time_stamp ; - blp.masked_bytes = 0 ; - - it->second.mBanPeers[bannedaddr] = blp; - it->second.mLastUpdate = now; - updated = true; - } - else - { - /* see if it needs an update */ - if ((mit->second.reason != reason) || - (mit->second.level != uint32_t(level)) || - (mit->second.mTs < time_stamp)) - { - /* update */ - mit->second.addr = addr; - mit->second.reason = reason; - mit->second.level = level; - mit->second.mTs = time_stamp; - mit->second.masked_bytes = 0 ; - - it->second.mLastUpdate = now; - updated = true; - } - } - - if (updated) - IndicateConfigChanged() ; - - return updated; -} - -bool p3BanList::isWhiteListed_locked(const sockaddr_storage& addr) -{ - if(mWhiteListedRanges.find(makeBitsRange(addr,0)) != mWhiteListedRanges.end()) - return true ; - - if(mWhiteListedRanges.find(makeBitsRange(addr,1)) != mWhiteListedRanges.end()) - return true ; - - if(mWhiteListedRanges.find(makeBitsRange(addr,2)) != mWhiteListedRanges.end()) - return true ; - - return false ; - -} - -/*** - * EXTRA DEBUGGING. - * #define DEBUG_BANLIST_CONDENSE 1 - ***/ - -int p3BanList::condenseBanSources_locked() -{ - mBanSet.clear(); - - rstime_t now = time(NULL); - RsPeerId ownId = mServiceCtrl->getOwnId(); - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << std::endl; -#endif - - std::map::const_iterator it; - for(it = mBanSources.begin(); it != mBanSources.end(); ++it) - { - if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE) - { -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << std::dec ; - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Ignoring Out-Of-Date peer: " << it->first; - std::cerr << std::endl; -#endif - continue; - } - -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << std::dec ; - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Condensing Info from peer: " << it->first; - std::cerr << std::endl; -#endif - - std::map::const_iterator lit; - for(lit = it->second.mBanPeers.begin(); lit != it->second.mBanPeers.end(); ++lit) - { - /* check timestamp */ - if (now > RSBANLIST_ENTRY_MAX_AGE + lit->second.mTs) - { -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << std::dec ; - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Ignoring Out-Of-Date Entry for: "; - std::cerr << sockaddr_storage_iptostring(lit->second.addr); - std::cerr << " time stamp= " << lit->second.mTs << ", age=" << now - lit->second.mTs; - std::cerr << std::endl; -#endif - continue; - } - - uint32_t lvl = lit->second.level; - if (it->first != ownId) - { - /* as from someone else, increment level */ - lvl++; - } - - struct sockaddr_storage bannedaddr; - sockaddr_storage_clear(bannedaddr); - bannedaddr.ss_family = AF_INET; - sockaddr_storage_copyip(bannedaddr, lit->second.addr); - sockaddr_storage_setport(bannedaddr, 0); - - if (isWhiteListed_locked(bannedaddr)) - continue; - - /* check if it exists in the Set already */ - std::map::iterator sit; - sit = mBanSet.find(bannedaddr); - - if ((sit == mBanSet.end()) || (lvl < sit->second.level)) - { - BanListPeer bp = lit->second; - bp.level = lvl; - bp.masked_bytes = 0 ; - sockaddr_storage_setport(bp.addr, 0); - mBanSet[bannedaddr] = bp; -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Added New Entry for: "; - std::cerr << sockaddr_storage_iptostring(bannedaddr); - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Merging Info for: "; - std::cerr << sockaddr_storage_iptostring(bannedaddr); - std::cerr << std::endl; -#endif - /* update if necessary */ - if (lvl == sit->second.level) - { - sit->second.reason |= lit->second.reason; - if (sit->second.mTs < lit->second.mTs) - { - sit->second.mTs = lit->second.mTs; - } - } - } - } - } - - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::condenseBanSources_locked() Printing New Set:"; - std::cerr << std::endl; - - printBanSet_locked(std::cerr); -#endif - - return true ; -} - - - -int p3BanList::sendPackets() -{ - rstime_t now = time(NULL); - rstime_t pt; - { - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - pt = mSentListTime; - } - - if (now - pt > RSBANLIST_SEND_PERIOD) - { - sendBanLists(); - - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::sendPackets() Regular Broadcast"; - std::cerr << std::endl; - - printBanSources_locked(std::cerr); - printBanSet_locked(std::cerr); -#endif - - mSentListTime = now; - } - return true ; -} - -void p3BanList::sendBanLists() -{ - - /* we ping our peers */ - /* who is online? */ - std::set idList; - - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, idList); - -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::sendBanList()"; - std::cerr << std::endl; -#endif - - /* prepare packets */ - std::set::iterator it; - for(it = idList.begin(); it != idList.end(); ++it) - { -#ifdef DEBUG_BANLIST - std::cerr << "p3BanList::sendBanList() To: " << *it; - std::cerr << std::endl; -#endif - sendBanSet(*it); - } -} - -// Send all manually banned ranges to friends - -int p3BanList::sendBanSet(const RsPeerId& peerid) -{ - /* */ - RsBanListItem *item = new RsBanListItem(); - item->PeerId(peerid); - - //rstime_t now = time(NULL); - - { - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ - std::map::iterator it; - for(it = mBanSet.begin(); it != mBanSet.end(); ++it) - { - if (it->second.level >= RSBANLIST_ORIGIN_FRIEND) - continue; // only share OWN for the moment. - - RsTlvBanListEntry bi; - it->second.toRsTlvBanListEntry(bi) ; - - bi.masked_bytes = 0 ; - bi.comment.clear() ; // don't send comments. - item->peerList.mList.push_back(bi); - } - } - - sendItem(item); - return 1; -} - - -int p3BanList::printBanSet_locked(std::ostream &out) -{ - rstime_t now = time(NULL); - - out << "p3BanList::printBanSet_locked()"; - out << " Only printing active filters (due to user options)."; - out << std::endl; - - std::map::iterator it; - for(it = mBanSet.begin(); it != mBanSet.end(); ++it) - if(acceptedBanSet_locked(it->second)) - { - out << "Ban: " << sockaddr_storage_iptostring(it->second.addr); - out << " Reason: " << it->second.reason; - out << " Level: " << it->second.level; - if (it->second.level > RSBANLIST_ORIGIN_FRIEND) - { - out << " (unused)"; - } - - out << " Age: " << now - it->second.mTs; - out << std::endl; - } - - std::cerr << "Current IP black list (only showing manual ranges, not automatically banned IPs): " << std::dec << std::endl; - - for(std::map::const_iterator it(mBanRanges.begin());it!=mBanRanges.end();++it) - if(acceptedBanRanges_locked(it->second)) - std::cerr << " " << sockaddr_storage_iptostring(it->first) << ". masked_bytes=" << (int)it->second.masked_bytes - << ", IP=" << sockaddr_storage_iptostring(it->second.addr) << "/" << ((int)32 - 8*(int)(it->second.masked_bytes)) << std::endl; - - std::cerr << "Current IP white list: " << std::endl; - - for(std::map::const_iterator it(mWhiteListedRanges.begin());it!=mWhiteListedRanges.end();++it) - if(acceptedBanRanges_locked(it->second)) - std::cerr << " " << sockaddr_storage_iptostring(it->first) << ". masked_bytes=" << (int)it->second.masked_bytes - << ", IP=" << sockaddr_storage_iptostring(it->second.addr) << "/" << ((int)32 - 8*(int)(it->second.masked_bytes)) << std::endl; - - return true ; -} - - - -int p3BanList::printBanSources_locked(std::ostream &out) -{ - rstime_t now = time(NULL); - - std::map::const_iterator it; - for(it = mBanSources.begin(); it != mBanSources.end(); ++it) - { - out << "BanList from: " << it->first; - out << " LastUpdate: " << now - it->second.mLastUpdate; - out << std::endl; - - std::map::const_iterator lit; - for(lit = it->second.mBanPeers.begin(); - lit != it->second.mBanPeers.end(); ++lit) - { - out << "\t"; - out << "Ban: " << sockaddr_storage_iptostring(lit->second.addr); - out << " Reason: " << lit->second.reason; - out << " Level: " << lit->second.level; - out << " Age: " << now - lit->second.mTs; - out << std::endl; - } - } - - return true ; -} - -RsBanList::~RsBanList() = default; diff --git a/libretroshare/src/services/p3banlist.h b/libretroshare/src/services/p3banlist.h deleted file mode 100644 index b61b7cb71..000000000 --- a/libretroshare/src/services/p3banlist.h +++ /dev/null @@ -1,166 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3banlist.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSBANLIST_HEADER -#define SERVICE_RSBANLIST_HEADER - -#include -#include -#include - -#include "rsitems/rsbanlistitems.h" -#include "services/p3service.h" -#include "retroshare/rsbanlist.h" - -class p3ServiceControl; -class p3NetMgr; - -class BanList -{ - public: - - RsPeerId mPeerId; /* from */ - rstime_t mLastUpdate; - std::map mBanPeers; -}; - -/** - * The RS BanList service. - * Exchange list of Banned IPv4 addresses with peers. - * - * @warning IPv4 only, IPv6 not supported yet! - */ -class p3BanList: public RsBanList, public p3Service, public pqiNetAssistPeerShare, public p3Config /*, public pqiMonitor */ -{ -public: - p3BanList(p3ServiceControl *sc, p3NetMgr *nm); - virtual RsServiceInfo getServiceInfo(); - - /***** overloaded from RsBanList *****/ - - /// @see RsBanList - virtual bool isAddressAccepted( - const sockaddr_storage& addr, uint32_t checking_flags, - uint32_t& check_result = RS_DEFAULT_STORAGE_PARAM(uint32_t) - ) override; - - virtual void getBannedIps(std::list& list) ; - virtual void getWhiteListedIps(std::list& list) ; - - virtual bool addIpRange( const sockaddr_storage& addr, int masked_bytes, - uint32_t list_type, const std::string& comment ); - virtual bool removeIpRange( const sockaddr_storage &addr, int masked_bytes, - uint32_t list_type ); - - virtual void enableIPFiltering(bool b) ; - virtual bool ipFilteringEnabled() ; - - virtual bool autoRangeEnabled() { return mAutoRangeIps ; } - virtual void enableAutoRange(bool b) ; - - virtual int autoRangeLimit() { return mAutoRangeLimit ; } - virtual void setAutoRangeLimit(int b) ; - - virtual void enableIPsFromFriends(bool b) ; - virtual bool IPsFromFriendsEnabled() { return mIPFriendGatheringEnabled ;} - - virtual void enableIPsFromDHT(bool b) ; - virtual bool iPsFromDHTEnabled() { return mIPDHTGatheringEnabled ;} - - /***** overloaded from pqiNetAssistPeerShare *****/ - - virtual void updatePeer( const RsPeerId& id, const sockaddr_storage &addr, - int type, int reason, int time_stamp ); - - /*********************** p3config ******************************/ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool &cleanup, std::list& itemlist); - virtual bool loadList(std::list& load); - - /***** 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(); - - int sendPackets(); - bool processIncoming(); - - bool recvBanItem(RsBanListItem *item); - bool addBanEntry( const RsPeerId &peerId, - const sockaddr_storage &addr, int level, uint32_t reason, - rstime_t time_stamp ); - void sendBanLists(); - int sendBanSet(const RsPeerId& peerid); - - - /*! - * Interface stuff. - */ - - /*************** pqiMonitor callback ***********************/ - //virtual void statusChange(const std::list &plist); - - - /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; - -private: - void getDhtInfo() ; - - RsMutex mBanMtx; - - bool acceptedBanSet_locked(const BanListPeer &blp); - bool acceptedBanRanges_locked(const BanListPeer &blp); - void autoFigureOutBanRanges(); - int condenseBanSources_locked(); - int printBanSources_locked(std::ostream &out); - int printBanSet_locked(std::ostream &out); - bool isWhiteListed_locked(const sockaddr_storage &addr); - - p3ServiceControl *mServiceCtrl; - //p3NetMgr *mNetMgr; - rstime_t mSentListTime; - std::map mBanSources; - std::map mBanSet; - std::map mBanRanges; - std::map mWhiteListedRanges; - - rstime_t mLastDhtInfoRequest ; - - uint32_t mAutoRangeLimit ; - bool mAutoRangeIps ; - - bool mIPFilteringEnabled ; - bool mIPFriendGatheringEnabled ; - bool mIPDHTGatheringEnabled ; -}; - -#endif // SERVICE_RSBANLIST_HEADER - diff --git a/libretroshare/src/services/p3bwctrl.cc b/libretroshare/src/services/p3bwctrl.cc deleted file mode 100644 index 65add3935..000000000 --- a/libretroshare/src/services/p3bwctrl.cc +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3bwctrl.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" -#include "pqi/pqipersongrp.h" - -#include "util/rsnet.h" - -#include "services/p3bwctrl.h" -#include "rsitems/rsbwctrlitems.h" - -#include - -/**** - * #define DEBUG_BWCTRL 1 - ****/ - - -/************ IMPLEMENTATION NOTES ********************************* - * - */ - -p3BandwidthControl *rsBandwidthControl; - - -p3BandwidthControl::p3BandwidthControl(pqipersongrp *pg) - :p3Service(), mPg(pg), mBwMtx("p3BwCtrl") -{ - addSerialType(new RsBwCtrlSerialiser()); - - mLastCheck = 0; -} - - -const std::string BANDWIDTH_CTRL_APP_NAME = "bandwidth_ctrl"; -const uint16_t BANDWIDTH_CTRL_APP_MAJOR_VERSION = 1; -const uint16_t BANDWIDTH_CTRL_APP_MINOR_VERSION = 0; -const uint16_t BANDWIDTH_CTRL_MIN_MAJOR_VERSION = 1; -const uint16_t BANDWIDTH_CTRL_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3BandwidthControl::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_BWCTRL, - BANDWIDTH_CTRL_APP_NAME, - BANDWIDTH_CTRL_APP_MAJOR_VERSION, - BANDWIDTH_CTRL_APP_MINOR_VERSION, - BANDWIDTH_CTRL_MIN_MAJOR_VERSION, - BANDWIDTH_CTRL_MIN_MINOR_VERSION); -} - - - -int p3BandwidthControl::tick() -{ - processIncoming(); - - bool doCheck = false; - { - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - -#define CHECK_PERIOD 5 - - rstime_t now = time(NULL); - if (now - mLastCheck > CHECK_PERIOD) - { - doCheck = true; - mLastCheck = now; - } - } - - if (doCheck) - { - checkAvailableBandwidth(); - } - - return 0; -} - -int p3BandwidthControl::status() -{ - return 1; -} - - -/***** Implementation ******/ - - -bool p3BandwidthControl::checkAvailableBandwidth() -{ - /* check each connection status */ - std::map rateMap; - RsBwRates total; - - mPg->ExtractRates(rateMap, total); - std::map::iterator it; - std::map::iterator bit; - - /* have to merge with existing list, - * erasing as we go ... then any left have to deal with - */ - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - - mTotalRates = total; - - rstime_t now = time(NULL); - std::list oldIds; // unused for now! - - for(bit = mBwMap.begin(); bit != mBwMap.end(); ++bit) - { - /* check alloc rate */ - //rstime_t age = now - bit->second.mLastSend; - - /* find a matching entry */ - it = rateMap.find(bit->first); - if (it == rateMap.end()) - { - oldIds.push_back(bit->first); - continue; - } - - //float delta = bit->second.mAllocated - it->second.mMaxRateIn; - /* if delta < 0 ... then need update (or else we get a queue) */ - /* if delta > 0 ... then need update (to allow more data) */ - - /* for the moment - always send an update */ - bool updatePeer = true; - -#if 0 - /* if changed significantly */ - if (sig) - { - updatePeer = true; - } - - /* if changed small but old */ - if ((any change) && (timeperiod)) - { - updatePeer = true; - } -#endif - - /* update rates info */ - bit->second.mRates = it->second; - bit->second.mRateUpdateTs = now; - - if (updatePeer) - { -#define ALLOC_FACTOR (1.0) - // save value sent, - bit->second.mAllocated = ALLOC_FACTOR * 1000.0 * it->second.mMaxRateIn; - bit->second.mLastSend = now; - - RsBwCtrlAllowedItem *item = new RsBwCtrlAllowedItem(); - item->PeerId(bit->first); - item->allowedBw = bit->second.mAllocated; - - sendItem(item); - } - - /* now cleanup */ - rateMap.erase(it); - } - - //printRateInfo_locked(std::cerr); - - /* any left over rateMaps ... are bad! (or not active - more likely) */ - return true; -} - - - -bool p3BandwidthControl::processIncoming() -{ - RsItem *item = NULL; - rstime_t now = time(NULL); - - while(NULL != (item = recvItem())) - { - RsBwCtrlAllowedItem *bci = dynamic_cast(item); - if (!bci) - { - delete item; - continue; - } - - /* For each packet */ - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - std::map::iterator bit; - - bit = mBwMap.find(bci->PeerId()); - if (bit == mBwMap.end()) - { - // ERROR. - delete item; - continue; - } - - /* update allowed bandwidth */ - bit->second.mAllowedOut = bci->allowedBw; - bit->second.mLastRecvd = now; - delete item; - - /* store info in data */ - //mPg->setAllowedRate(bit->first, bit->second.mAllowedOut / 1000.0); - } - return true; -} - -int p3BandwidthControl::getTotalBandwidthRates(RsConfigDataRates &rates) -{ - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - - rates.mRateIn = mTotalRates.mRateIn; - rates.mRateMaxIn = mTotalRates.mMaxRateIn; - rates.mRateOut = mTotalRates.mRateOut; - rates.mRateMaxOut = mTotalRates.mMaxRateOut; - - rates.mAllocIn = 0; - rates.mAllocTs = 0; - - rates.mAllowedOut = 0; - rates.mAllowedTs = 0; - - rates.mQueueIn = mTotalRates.mQueueIn; - rates.mQueueOut = mTotalRates.mQueueOut; - - return 1; -} - -int p3BandwidthControl::getAllBandwidthRates(std::map &ratemap) -{ - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - - std::map::iterator bit; - for(bit = mBwMap.begin(); bit != mBwMap.end(); ++bit) - { - RsConfigDataRates rates; - - rates.mRateIn = bit->second.mRates.mRateIn; - rates.mRateMaxIn = bit->second.mRates.mMaxRateIn; - rates.mRateOut = bit->second.mRates.mRateOut; - rates.mRateMaxOut = bit->second.mRates.mMaxRateOut; - - rates.mAllocIn = bit->second.mAllocated / 1000.0; - rates.mAllocTs = bit->second.mLastSend; - - rates.mAllowedOut = bit->second.mAllowedOut / 1000.0; - rates.mAllowedTs = bit->second.mLastRecvd; - - rates.mQueueIn = bit->second.mRates.mQueueIn; - rates.mQueueOut = bit->second.mRates.mQueueOut; - - ratemap[bit->first] = rates; - } - return true ; - - -} - -int p3BandwidthControl::ExtractTrafficInfo(std::list& out_stats, std::list& in_stats) -{ - return mPg->ExtractTrafficInfo(out_stats,in_stats) ; -} - - - - - - -int p3BandwidthControl::printRateInfo_locked(std::ostream &out) -{ - out << "p3BandwidthControl::printRateInfo_locked()"; - out << std::endl; - - //rstime_t now = time(NULL); - out << "Totals: "; - out << " In: " << mTotalRates.mRateIn; - out << " MaxIn: " << mTotalRates.mMaxRateIn; - out << " Out: " << mTotalRates.mRateOut; - out << " MaxOut: " << mTotalRates.mMaxRateOut; - out << std::endl; - - std::map::iterator bit; - for(bit = mBwMap.begin(); bit != mBwMap.end(); ++bit) - { - out << "\t" << bit->first; - out << " In: " << bit->second.mRates.mRateIn; - out << " MaxIn: " << bit->second.mRates.mMaxRateIn; - out << " Out: " << bit->second.mRates.mRateOut; - out << " MaxOut: " << bit->second.mRates.mMaxRateOut; - out << std::endl; - } - return true ; -} - - /*************** pqiMonitor callback ***********************/ -void p3BandwidthControl::statusChange(const std::list &plist) -{ - std::list::const_iterator it; - for (it = plist.begin(); it != plist.end(); ++it) - { - RsStackMutex stack(mBwMtx); /****** LOCKED MUTEX *******/ - - if (it->actions & RS_SERVICE_PEER_DISCONNECTED) - { - /* remove from map */ - std::map::iterator bit; - bit = mBwMap.find(it->id); - if (bit == mBwMap.end()) - { - std::cerr << "p3BandwidthControl::statusChange() ERROR"; - std::cerr << " Entry not in map"; - std::cerr << std::endl; - } - else - { - mBwMap.erase(bit); - } - } - else if (it->actions & RS_SERVICE_PEER_CONNECTED) - { - /* stuff */ - BwCtrlData data; - mBwMap[it->id] = data; - } - } - return; -} - - diff --git a/libretroshare/src/services/p3bwctrl.h b/libretroshare/src/services/p3bwctrl.h deleted file mode 100644 index bd6276d5f..000000000 --- a/libretroshare/src/services/p3bwctrl.h +++ /dev/null @@ -1,126 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3bwctrl.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSBANDWIDTH_CONTROL_HEADER -#define SERVICE_RSBANDWIDTH_CONTROL_HEADER - -#include -#include -#include - -#include "rsitems/rsbwctrlitems.h" -#include "services/p3service.h" -#include "pqi/pqiservicemonitor.h" -#include "retroshare/rsconfig.h" // for datatypes. - -class pqipersongrp; - -// Extern is defined here - as this is bundled with rsconfig.h -class p3BandwidthControl; -extern p3BandwidthControl *rsBandwidthControl; - - -class BwCtrlData -{ - public: - BwCtrlData() - :mRateUpdateTs(0), mAllocated(0), mLastSend(0), mAllowedOut(0), mLastRecvd(0) - { return; } - - /* Rates are floats in KB/s */ - RsBwRates mRates; - rstime_t mRateUpdateTs; - - /* these are integers (B/s) */ - uint32_t mAllocated; - rstime_t mLastSend; - - uint32_t mAllowedOut; - rstime_t mLastRecvd; -}; - - -//!The RS bandwidth Control Service. - /** - * - * Exchange packets to regulate p2p bandwidth. - * - * Sadly this has to be strongly integrated into pqi, with ref to pqipersongrp. - */ - -class p3BandwidthControl: public p3Service, public pqiServiceMonitor -{ - public: - explicit p3BandwidthControl(pqipersongrp *pg); - virtual RsServiceInfo getServiceInfo(); - - /***** overloaded from RsBanList *****/ - - - /***** overloaded from p3Service *****/ - /*! - * This retrieves all BwCtrl items - */ - virtual int tick(); - virtual int status(); - - - /***** for RsConfig (not directly overloaded) ****/ - - virtual int getTotalBandwidthRates(RsConfigDataRates &rates); - virtual int getAllBandwidthRates(std::map &ratemap); - - - virtual int ExtractTrafficInfo(std::list &out_stats, std::list &in_stats); - - /*! - * Interface stuff. - */ - - /*************** pqiMonitor callback ***********************/ - virtual void statusChange(const std::list &plist); - - - /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; - -private: - - bool checkAvailableBandwidth(); - bool processIncoming(); - - pqipersongrp *mPg; - - RsMutex mBwMtx; - - int printRateInfo_locked(std::ostream &out); - - rstime_t mLastCheck; - - RsBwRates mTotalRates; - std::map mBwMap; - -}; - -#endif // SERVICE_RSBANDWIDTH_CONTROL_HEADER diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc deleted file mode 100644 index 1ee9f6d75..000000000 --- a/libretroshare/src/services/p3gxschannels.cc +++ /dev/null @@ -1,2738 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxschannels.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "services/p3gxschannels.h" -#include "rsitems/rsgxschannelitems.h" -#include "util/radix64.h" -#include "util/rsmemory.h" - -#include -#include - - -#include "retroshare/rsgxsflags.h" -#include "retroshare/rsfiles.h" -#include "retroshare/rspeers.h" - -#include "rsserver/p3face.h" -#include "retroshare/rsnotify.h" - -#include -#include -#include - -// For Dummy Msgs. -#include "util/rsrandom.h" -#include "util/rsstring.h" - -#ifdef RS_DEEP_CHANNEL_INDEX -# include "deep_search/channelsindex.hpp" -#endif // RS_DEEP_CHANNEL_INDEX - - -/**** - * #define GXSCHANNEL_DEBUG 1 - ****/ - -/*extern*/ RsGxsChannels* rsGxsChannels = nullptr; - - -#define GXSCHANNEL_STOREPERIOD (3600 * 24 * 30) - -#define GXSCHANNELS_SUBSCRIBED_META 1 -#define GXSCHANNELS_UNPROCESSED_SPECIFIC 2 -#define GXSCHANNELS_UNPROCESSED_GENERIC 3 - -#define CHANNEL_PROCESS 0x0001 -#define CHANNEL_TESTEVENT_DUMMYDATA 0x0002 -#define DUMMYDATA_PERIOD 60 // Long enough for some RsIdentities to be generated. - -#define CHANNEL_DOWNLOAD_PERIOD (3600 * 24 * 7) -#define CHANNEL_MAX_AUTO_DL (8 * 1024 * 1024 * 1024ull) // 8 GB. Just a security ;-) -#define CHANNEL_UNUSED_BY_FRIENDS_DELAY (3600*24*60) // Two months. Will be used to delete a channel if too old -#define CHANNEL_DELAY_FOR_CHECKING_AND_DELETING_OLD_GROUPS 300 // check for old channels every 30 mins. Far too often than above delay by RS needs to run it at least once per session - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3GxsChannels::p3GxsChannels( - RsGeneralDataService *gds, RsNetworkExchangeService *nes, - RsGixs* gixs ) : - RsGenExchange( gds, nes, new RsGxsChannelSerialiser(), - RS_SERVICE_GXS_TYPE_CHANNELS, gixs, channelsAuthenPolicy() ), - RsGxsChannels(static_cast(*this)), GxsTokenQueue(this), - mSubscribedGroupsMutex("GXS channels subscribed groups cache"), - mKnownChannelsMutex("GXS channels known channels timestamp cache") -#ifdef TO_REMOVE - mSearchCallbacksMapMutex("GXS channels search callbacks map"), - mDistantChannelsCallbacksMapMutex("GXS channels distant channels callbacks map") -#endif -{ - // For Dummy Msgs. - mGenActive = false; - mLastDistantSearchNotificationTS = 0; - mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXS_TYPE_CHANNELS); - - // This is not needed since it just loads all channel data ever 5 mins which takes a lot - // of useless CPU/memory. - // - RsTickEvent::schedule_in(CHANNEL_PROCESS, 0); - // - // Test Data disabled in repo. - // - // RsTickEvent::schedule_in(CHANNEL_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); - - mGenToken = 0; - mGenCount = 0; -} - - -const std::string GXS_CHANNELS_APP_NAME = "gxschannels"; -const uint16_t GXS_CHANNELS_APP_MAJOR_VERSION = 1; -const uint16_t GXS_CHANNELS_APP_MINOR_VERSION = 0; -const uint16_t GXS_CHANNELS_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_CHANNELS_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3GxsChannels::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_CHANNELS, - GXS_CHANNELS_APP_NAME, - GXS_CHANNELS_APP_MAJOR_VERSION, - GXS_CHANNELS_APP_MINOR_VERSION, - GXS_CHANNELS_MIN_MAJOR_VERSION, - GXS_CHANNELS_MIN_MINOR_VERSION); -} - - -uint32_t p3GxsChannels::channelsAuthenPolicy() -{ - uint32_t policy = 0; - uint32_t flag = 0; - - flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -static const uint32_t GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months -static const uint8_t GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; - -struct RsGxsChannelNotifyRecordsItem: public RsItem -{ - - RsGxsChannelNotifyRecordsItem() - : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG,GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD) - {} - - virtual ~RsGxsChannelNotifyRecordsItem() {} - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { RS_SERIAL_PROCESS(records); } - - void clear() {} - - std::map records; -}; - -class GxsChannelsConfigSerializer : public RsServiceSerializer -{ -public: - GxsChannelsConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG) {} - virtual ~GxsChannelsConfigSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG) - return NULL; - - switch(item_sub_id) - { - case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsChannelNotifyRecordsItem(); - default: - return NULL; - } - } -}; - -bool p3GxsChannels::saveList(bool &cleanup, std::list&saveList) -{ - cleanup = true ; - - RsGxsChannelNotifyRecordsItem *item = new RsGxsChannelNotifyRecordsItem ; - - { - RS_STACK_MUTEX(mKnownChannelsMutex); - item->records = mKnownChannels; - } - - saveList.push_back(item) ; - return true; -} - -bool p3GxsChannels::loadList(std::list& loadList) -{ - while(!loadList.empty()) - { - RsItem *item = loadList.front(); - loadList.pop_front(); - - rstime_t now = time(NULL); - - RsGxsChannelNotifyRecordsItem *fnr = dynamic_cast(item) ; - - if(fnr) - { - RS_STACK_MUTEX(mKnownChannelsMutex); - mKnownChannels.clear(); - - for(auto it(fnr->records.begin());it!=fnr->records.end();++it) - if(now < it->second + GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE) - mKnownChannels.insert(*it) ; - } - - delete item ; - } - return true; -} - -RsSerialiser* p3GxsChannels::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new GxsChannelsConfigSerializer()); - - return rss; -} - - - /** Overloaded to cache new groups **/ -RsGenExchange::ServiceCreate_Return p3GxsChannels::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /* keySet */) -{ - updateSubscribedGroup(grpItem->meta); - return SERVICE_CREATE_SUCCESS; -} - - -void p3GxsChannels::notifyChanges(std::vector &changes) -{ -#ifdef GXSCHANNEL_DEBUG - RsDbg() << " Processing " << changes.size() << " channel changes..." << std::endl; -#endif - /* iterate through and grab any new messages */ - std::set unprocessedGroups; - - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) - { - RsGxsMsgChange *msgChange = dynamic_cast(*it); - - if (msgChange) - { - if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) - { - /* message received */ - if (rsEvents) - { - auto ev = std::make_shared(); - - ev->mChannelMsgId = msgChange->mMsgId; - ev->mChannelGroupId = msgChange->mGroupId; - - if(nullptr != dynamic_cast(msgChange->mNewMsgItem)) - ev->mChannelEventCode = RsChannelEventCode::NEW_COMMENT; - else - if(nullptr != dynamic_cast(msgChange->mNewMsgItem)) - ev->mChannelEventCode = RsChannelEventCode::NEW_VOTE; - else - ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE; - - rsEvents->postEvent(ev); - } - } - - if (!msgChange->metaChange()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::notifyChanges() Found Message Change Notification"; - std::cerr << std::endl; -#endif - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first; - std::cerr << std::endl; -#endif - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first; - std::cerr << std::endl; -#endif - - /* problem is most of these will be comments and votes, should make it occasional - every 5mins / 10minutes TODO */ - // We do not call if(autoDownLoadEnabled()) here, because it would be too costly when - // many msgs are received from the same group. We back the groupIds and then request one by one. - - unprocessedGroups.insert(msgChange->mGroupId); - } - } - } - - RsGxsGroupChange *grpChange = dynamic_cast(*it); - - if (grpChange && rsEvents) - { -#ifdef GXSCHANNEL_DEBUG - RsDbg() << " Grp Change Event or type " << grpChange->getType() << ":" << std::endl; -#endif - - switch (grpChange->getType()) - { - case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed - { - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - case RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED: - { - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::SYNC_PARAMETERS_UPDATED; - rsEvents->postEvent(ev); - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - - // also update channel usage. Statistics are updated when a friend sends some sync packets - RS_STACK_MUTEX(mKnownChannelsMutex); - mKnownChannels[grpChange->mGroupId] = time(NULL); - IndicateConfigChanged(); - } - break; - - case RsGxsNotify::TYPE_UPDATED: - { - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::UPDATED_CHANNEL; - rsEvents->postEvent(ev); - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - case RsGxsNotify::TYPE_PUBLISHED: - case RsGxsNotify::TYPE_RECEIVED_NEW: - { - /* group received or updated */ - - bool unknown ; - { - RS_STACK_MUTEX(mKnownChannelsMutex); - - unknown = (mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end()); - mKnownChannels[grpChange->mGroupId] = time(NULL); - IndicateConfigChanged(); - } - -#ifdef GXSCHANNEL_DEBUG - RsDbg() << " Type = Published/New " << std::endl; -#endif - if(unknown) - { -#ifdef GXSCHANNEL_DEBUG - RsDbg() << " Status: unknown. Sending notification event." << std::endl; -#endif - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL; - rsEvents->postEvent(ev); - } -#ifdef GXSCHANNEL_DEBUG - else - RsDbg() << " Not notifying already known channel " << grpChange->mGroupId << std::endl; -#endif - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - case RsGxsNotify::TYPE_GROUP_DELETED: - { - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::DELETED_CHANNEL; - rsEvents->postEvent(ev); - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: - { - /* group received */ - auto ev = std::make_shared(); - ev->mChannelGroupId = grpChange->mGroupId; - ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY; - - rsEvents->postEvent(ev); - - unprocessedGroups.insert(grpChange->mGroupId); - } - break; - - default: - RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl; - break; - } - } - - /* shouldn't need to worry about groups - as they need to be subscribed to */ - delete *it; - } - - std::list grps; - for(auto& grp_id:unprocessedGroups) - grps.push_back(grp_id); - - if(!grps.empty()) - request_SpecificSubscribedGroups(grps); -} - -void p3GxsChannels::service_tick() -{ - static rstime_t last_dummy_tick = 0; - rstime_t now = time(NULL); - - if (time(NULL) > last_dummy_tick + 5) - { - dummy_tick(); - last_dummy_tick = now; - } - - RsTickEvent::tick_events(); - GxsTokenQueue::checkRequests(); - - mCommentService->comment_tick(); - - // Notify distant search results, not more than once per sec. Normally we should - // rather send one item for all, but that needs another class type - - if(now > mLastDistantSearchNotificationTS+2 && !mSearchResultsToNotify.empty()) - { - auto ev = std::make_shared(); - ev->mSearchResultsMap = mSearchResultsToNotify; - - mLastDistantSearchNotificationTS = now; - mSearchResultsToNotify.clear(); - - rsEvents->postEvent(ev); - } -} - -bool p3GxsChannels::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) -{ -#ifdef GXSFORUMS_CHANNELS - std::cerr << "p3gxsChannels: Checking unused channel: called by GxsCleaning." << std::endl; -#endif - - // request all group infos at once - - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownChannelsMutex); - - auto it = mKnownChannels.find(meta.mGroupId); - bool unknown_channel = it == mKnownChannels.end(); - -#ifdef GXSFORUMS_CHANNELS - std::cerr << " Channel " << meta.mGroupId ; -#endif - - if(unknown_channel) - { - // This case should normally not happen. It does because this channel was never registered since it may - // arrived before this code was here - -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Not known yet. Adding current time as new TS." << std::endl; -#endif - mKnownChannels[meta.mGroupId] = now; - IndicateConfigChanged(); - - return true; - } - else - { - bool used_by_friends = (now < it->second + CHANNEL_UNUSED_BY_FRIENDS_DELAY); - bool subscribed = static_cast(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)"; -#endif - - if(!subscribed && !used_by_friends) - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Scheduling for deletion" << std::endl; -#endif - return false; - } - else - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Keeping!" << std::endl; -#endif - return true; - } - } -} - -bool p3GxsChannels::getGroupData(const uint32_t &token, std::vector &groups) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::getGroupData()"; - std::cerr << std::endl; -#endif - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsChannelGroupItem* item = dynamic_cast(*vit); - if (item) - { - RsGxsChannelGroup grp; - item->toChannelGroup(grp, true); - delete item; - groups.push_back(grp); - } - else - { - std::cerr << "p3GxsChannels::getGroupData() ERROR in decode"; - std::cerr << std::endl; - delete(*vit); - } - } - } - else - { - std::cerr << "p3GxsChannels::getGroupData() ERROR in request"; - std::cerr << std::endl; - } - - return ok; -} - -bool p3GxsChannels::groupShareKeys( - const RsGxsGroupId &groupId, const std::set& peers ) -{ - RsGenExchange::shareGroupPublishKey(groupId,peers); - return true; -} - - -/* Okay - chris is not going to be happy with this... - * but I can't be bothered with crazy data structures - * at the moment - fix it up later - */ - -bool p3GxsChannels::getPostData( const uint32_t& token, std::vector& msgs, - std::vector& cmts, - std::vector& vots) -{ -#ifdef GXSCHANNELS_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << std::endl; -#endif - - GxsMsgDataMap msgData; - if(!RsGenExchange::getMsgData(token, msgData)) - { - RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl; - return false; - } - - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsChannelPostItem* postItem = - dynamic_cast(*vit); - - if(postItem) - { - RsGxsChannelPost msg; - postItem->toChannelPost(msg, true); - msgs.push_back(msg); - delete postItem; - } - else - { - RsGxsCommentItem* cmtItem = - dynamic_cast(*vit); - if(cmtItem) - { - RsGxsComment cmt; - RsGxsMsgItem *mi = (*vit); - cmt = cmtItem->mMsg; - cmt.mMeta = mi->meta; -#ifdef GXSCOMMENT_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl; - cmt.print(std::cerr," ", "cmt"); -#endif - cmts.push_back(cmt); - delete cmtItem; - } - else - { - RsGxsVoteItem* votItem = - dynamic_cast(*vit); - if(votItem) - { - RsGxsVote vot; - RsGxsMsgItem *mi = (*vit); - vot = votItem->mMsg; - vot.mMeta = mi->meta; - vots.push_back(vot); - delete votItem; - } - else - { - RsGxsMsgItem* msg = (*vit); - //const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217; - //const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; - //const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1; - //const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2; - RsErr() << __PRETTY_FUNCTION__ - << " Not a GxsChannelPostItem neither a " - << "RsGxsCommentItem neither a RsGxsVoteItem" - << " PacketService=" << std::hex << (int)msg->PacketService() << std::dec - << " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec - << " type name =" << typeid(*msg).name() - << " , deleting!" << std::endl; - delete *vit; - } - } - } - } - } - - return true; -} - -bool p3GxsChannels::getPostData( - const uint32_t& token, std::vector& posts, std::vector& cmts ) -{ - std::vector vots; - return getPostData(token, posts, cmts, vots); -} - -bool p3GxsChannels::getPostData( - const uint32_t& token, std::vector& posts ) -{ - std::vector cmts; - std::vector vots; - return getPostData(token, posts, cmts, vots); -} - -//Not currently used -/*bool p3GxsChannels::getRelatedPosts(const uint32_t &token, std::vector &msgs) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::getRelatedPosts()"; - std::cerr << std::endl; -#endif - - GxsMsgRelatedDataMap msgData; - bool ok = RsGenExchange::getMsgRelatedData(token, msgData); - - if(ok) - { - GxsMsgRelatedDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsChannelPostItem* item = dynamic_cast(*vit); - - if(item) - { - RsGxsChannelPost msg; - item->toChannelPost(msg, true); - msgs.push_back(msg); - delete item; - } - else - { - RsGxsCommentItem* cmt = dynamic_cast(*vit); - if(!cmt) - { - RsGxsMsgItem* msg = (*vit); - //const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217; - //const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; - //const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1; - std::cerr << "Not a GxsChannelPostItem neither a RsGxsCommentItem" - << " PacketService=" << std::hex << (int)msg->PacketService() << std::dec - << " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec - << " , deleting!" << std::endl; - } - delete *vit; - } - } - } - } - else - { - std::cerr << "p3GxsChannels::getRelatedPosts() ERROR in request"; - std::cerr << std::endl; - } - - return ok; -}*/ - - -/********************************************************************************************/ -/********************************************************************************************/ - -bool p3GxsChannels::setChannelAutoDownload(const RsGxsGroupId &groupId, bool enabled) -{ - return setAutoDownload(groupId, enabled); -} - - -bool p3GxsChannels::getChannelAutoDownload(const RsGxsGroupId &groupId, bool& enabled) -{ - return autoDownloadEnabled(groupId,enabled); -} - -bool p3GxsChannels::setChannelDownloadDirectory( - const RsGxsGroupId &groupId, const std::string& directory ) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " id: " << groupId << " to: " - << directory << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - - std::map::iterator it; - it = mSubscribedGroups.find(groupId); - if (it == mSubscribedGroups.end()) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Unknown groupId: " - << groupId.toStdString() << std::endl; - return false; - } - - /* extract from ServiceString */ - GxsChannelGroupInfo ss; - ss.load(it->second.mServiceString); - - if (directory == ss.mDownloadDirectory) - { - std::cerr << __PRETTY_FUNCTION__ << " Warning! groupId: " << groupId - << " Was already configured to download into: " << directory - << std::endl; - return false; - } - - ss.mDownloadDirectory = directory; - std::string serviceString = ss.save(); - uint32_t token; - - it->second.mServiceString = serviceString; // update Local Cache. - RsGenExchange::setGroupServiceString(token, groupId, serviceString); // update dbase. - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Feiled setting group " - << " service string" << std::endl; - return false; - } - - /* now reload it */ - std::list groups; - groups.push_back(groupId); - - request_SpecificSubscribedGroups(groups); - - return true; -} - -bool p3GxsChannels::getChannelDownloadDirectory(const RsGxsGroupId & groupId,std::string& directory) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::getChannelDownloadDirectory(" << id << ")" << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - - std::map::iterator it; - - it = mSubscribedGroups.find(groupId); - if (it == mSubscribedGroups.end()) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Unknown groupId: " - << groupId.toStdString() << std::endl; - return false; - } - - /* extract from ServiceString */ - GxsChannelGroupInfo ss; - ss.load(it->second.mServiceString); - directory = ss.mDownloadDirectory; - - return true; -} - -void p3GxsChannels::request_AllSubscribedGroups() -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::request_SubscribedGroups()"; - std::cerr << std::endl; -#endif // GXSCHANNELS_DEBUG - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, GXSCHANNELS_SUBSCRIBED_META); - -//#define PERIODIC_ALL_PROCESS 300 // This -// RsTickEvent::schedule_in(CHANNEL_PROCESS, PERIODIC_ALL_PROCESS); -} - - -void p3GxsChannels::request_SpecificSubscribedGroups( const std::list &groups ) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()"; - std::cerr << std::endl; -#endif // GXSCHANNELS_DEBUG - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - - uint32_t token = 0; - - if(!RsGenExchange::getTokenService()-> requestGroupInfo(token, ansType, opts, groups)) - { - std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!" - << std::endl; - return; - } - - if(!GxsTokenQueue::queueRequest(token, GXSCHANNELS_SUBSCRIBED_META)) - { - std::cerr << __PRETTY_FUNCTION__ << " Failed queuing request!" - << std::endl; - } -} - - -void p3GxsChannels::load_SubscribedGroups(const uint32_t &token) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::load_SubscribedGroups()"; - std::cerr << std::endl; -#endif // GXSCHANNELS_DEBUG - - std::list groups; - std::list groupList; - - getGroupMeta(token, groups); - - std::list::iterator it; - for(it = groups.begin(); it != groups.end(); ++it) - { - if (it->mSubscribeFlags & - (GXS_SERV::GROUP_SUBSCRIBE_ADMIN | - GXS_SERV::GROUP_SUBSCRIBE_PUBLISH | - GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::load_SubscribedGroups() updating Subscribed Group: " << it->mGroupId; - std::cerr << std::endl; -#endif - - updateSubscribedGroup(*it); - bool enabled = false ; - - if (autoDownloadEnabled(it->mGroupId,enabled) && enabled) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::load_SubscribedGroups() remembering AutoDownload Group: " << it->mGroupId; - std::cerr << std::endl; -#endif - groupList.push_back(it->mGroupId); - } - } - else - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::load_SubscribedGroups() clearing unsubscribed Group: " << it->mGroupId; - std::cerr << std::endl; -#endif - clearUnsubscribedGroup(it->mGroupId); - } - } - - /* Query for UNPROCESSED POSTS from checkGroupList */ - request_GroupUnprocessedPosts(groupList); -} - - - -void p3GxsChannels::updateSubscribedGroup(const RsGroupMetaData &group) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::updateSubscribedGroup() id: " << group.mGroupId; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - mSubscribedGroups[group.mGroupId] = group; -} - - -void p3GxsChannels::clearUnsubscribedGroup(const RsGxsGroupId &id) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::clearUnsubscribedGroup() id: " << id; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - std::map::iterator it; - it = mSubscribedGroups.find(id); - if (it != mSubscribedGroups.end()) - { - mSubscribedGroups.erase(it); - } -} - - -bool p3GxsChannels::subscribeToGroup(uint32_t &token, const RsGxsGroupId &groupId, bool subscribe) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::subscribedToGroup() id: " << groupId << " subscribe: " << subscribe; - std::cerr << std::endl; -#endif - - std::list groups; - groups.push_back(groupId); - - // Call down to do the real work. - bool response = RsGenExchange::subscribeToGroup(token, groupId, subscribe); - - // reload Group afterwards. - request_SpecificSubscribedGroups(groups); - - return response; -} - - -void p3GxsChannels::request_SpecificUnprocessedPosts(std::list > &ids) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::request_SpecificUnprocessedPosts()"; - std::cerr << std::endl; -#endif // GXSCHANNELS_DEBUG - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - // Only Fetch UNPROCESSED messages. - opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - uint32_t token = 0; - - /* organise Ids how they want them */ - GxsMsgReq msgIds; - std::list >::iterator it; - for(it = ids.begin(); it != ids.end(); ++it) - msgIds[it->first].insert(it->second); - - RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, msgIds); - GxsTokenQueue::queueRequest(token, GXSCHANNELS_UNPROCESSED_SPECIFIC); -} - - -void p3GxsChannels::request_GroupUnprocessedPosts(const std::list &grouplist) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::request_GroupUnprocessedPosts()"; - std::cerr << std::endl; -#endif // GXSCHANNELS_DEBUG - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - // Only Fetch UNPROCESSED messages. - opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, grouplist); - GxsTokenQueue::queueRequest(token, GXSCHANNELS_UNPROCESSED_GENERIC); -} - - -void p3GxsChannels::load_unprocessedPosts(uint32_t token) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::load_SpecificUnprocessedPosts" << std::endl; -#endif - - std::vector posts; - if (!getPostData(token, posts)) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR getting post data!" - << std::endl; - return; - } - - std::vector::iterator it; - for(it = posts.begin(); it != posts.end(); ++it) - { - /* autodownload the files */ - handleUnprocessedPost(*it); - } -} - -void p3GxsChannels::handleUnprocessedPost(const RsGxsChannelPost &msg) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " GroupId: " << msg.mMeta.mGroupId - << " MsgId: " << msg.mMeta.mMsgId << std::endl; -#endif - - if (!IS_MSG_UNPROCESSED(msg.mMeta.mMsgStatus)) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR Msg already Processed! " - << "mMsgId: " << msg.mMeta.mMsgId << std::endl; - return; - } - - /* check that autodownload is set */ - bool enabled = false; - if (autoDownloadEnabled(msg.mMeta.mGroupId, enabled) && enabled) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " AutoDownload Enabled... handling" - << std::endl; -#endif - - /* check the date is not too old */ - rstime_t age = time(NULL) - msg.mMeta.mPublishTs; - - if (age < (rstime_t) CHANNEL_DOWNLOAD_PERIOD ) - { - /* start download */ - // NOTE WE DON'T HANDLE PRIVATE CHANNELS HERE. - // MORE THOUGHT HAS TO GO INTO THAT STUFF. - -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " START DOWNLOAD" << std::endl; -#endif - - std::list::const_iterator fit; - for(fit = msg.mFiles.begin(); fit != msg.mFiles.end(); ++fit) - { - std::string fname = fit->mName; - Sha1CheckSum hash = Sha1CheckSum(fit->mHash); - uint64_t size = fit->mSize; - - std::list srcIds; - std::string localpath = ""; - TransferRequestFlags flags = RS_FILE_REQ_BACKGROUND | RS_FILE_REQ_ANONYMOUS_ROUTING; - - if (size < CHANNEL_MAX_AUTO_DL) - { - std::string directory ; - if(getChannelDownloadDirectory(msg.mMeta.mGroupId,directory)) - localpath = directory ; - - rsFiles->FileRequest(fname, hash, size, localpath, flags, srcIds); - } - else - std::cerr << __PRETTY_FUNCTION__ << "Channel file is not auto-" - << "downloaded because its size exceeds the threshold" - << " of " << CHANNEL_MAX_AUTO_DL << " bytes." - << std::endl; - } - } - - /* mark as processed */ - uint32_t token; - RsGxsGrpMsgIdPair msgId(msg.mMeta.mGroupId, msg.mMeta.mMsgId); - setMessageProcessedStatus(token, msgId, true); - } -#ifdef GXSCHANNELS_DEBUG - else - { - std::cerr << "p3GxsChannels::handleUnprocessedPost() AutoDownload Disabled ... skipping"; - std::cerr << std::endl; - } -#endif -} - - - // Overloaded from GxsTokenQueue for Request callbacks. -void p3GxsChannels::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl; -#endif // GXSCHANNELS_DEBUG - if (status != RsTokenService::COMPLETE) - return; //For now, only manage Complete request - - // stuff. - switch(req_type) - { - case GXSCHANNELS_SUBSCRIBED_META: - load_SubscribedGroups(token); - break; - - case GXSCHANNELS_UNPROCESSED_SPECIFIC: - load_unprocessedPosts(token); - break; - - case GXSCHANNELS_UNPROCESSED_GENERIC: - load_unprocessedPosts(token); - break; - - default: - std::cerr << __PRETTY_FUNCTION__ << "ERROR Unknown Request Type: " - << req_type << std::endl; - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -/// Blocking API implementation begin -//////////////////////////////////////////////////////////////////////////////// - -bool p3GxsChannels::getChannelsSummaries( - std::list& channels ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token, opts) - || waitToken(token) != RsTokenService::COMPLETE ) return false; - return getGroupSummary(token, channels); -} - -bool p3GxsChannels::getChannelsInfo( const std::list& chanIds, std::vector& channelsInfo ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if(chanIds.empty()) - { - if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - else - { - if( !requestGroupInfo(token, opts, chanIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - - return getGroupData(token, channelsInfo) && !channelsInfo.empty(); -} - -bool p3GxsChannels::getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestGroupStatistic(token, channelId) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getGroupStatistic(token,stat); -} - -bool p3GxsChannels::getChannelServiceStatistics(GxsServiceStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getServiceStatistic(token,stat); -} - -bool p3GxsChannels::getContentSummaries( - const RsGxsGroupId& channelId, std::vector& summaries ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_META; - - std::list channelIds; - channelIds.push_back(channelId); - - if( !requestMsgInfo(token, opts, channelIds) || - waitToken(token, std::chrono::seconds(5)) != RsTokenService::COMPLETE ) - return false; - - GxsMsgMetaMap metaMap; - bool res = RsGenExchange::getMsgMeta(token, metaMap); - summaries = metaMap[channelId]; - - return res; -} - -bool p3GxsChannels::getChannelAllContent( const RsGxsGroupId& channelId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - if( !requestMsgInfo(token, opts,std::list({channelId})) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - - return getPostData(token, posts, comments,votes); -} - -bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId, - const std::set& contentIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - GxsMsgReq msgIds; - msgIds[channelId] = contentIds; - - if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - - return getPostData(token, posts, comments, votes); -} - -bool p3GxsChannels::getChannelComments(const RsGxsGroupId &channelId, - const std::set &contentIds, - std::vector &comments) -{ - std::vector msgIds; - for (auto& msg:contentIds) - msgIds.push_back(RsGxsGrpMsgIdPair(channelId,msg)); - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; - - uint32_t token; - if( !requestMsgRelatedInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - - return getRelatedComments(token,comments); -} - -bool p3GxsChannels::createChannelV2( - const std::string& name, const std::string& description, - const RsGxsImage& thumbnail, const RsGxsId& authorId, - RsGxsCircleType circleType, const RsGxsCircleId& circleId, - RsGxsGroupId& channelId, std::string& errorMessage ) -{ - const auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errorMessage = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(!authorId.isNull() && !rsIdentity->isOwnId(authorId)) - return failure("authorId must be either null, or of an owned identity"); - - if( circleType != RsGxsCircleType::PUBLIC - && circleType != RsGxsCircleType::EXTERNAL - && circleType != RsGxsCircleType::NODES_GROUP - && circleType != RsGxsCircleType::LOCAL - && circleType != RsGxsCircleType::YOUR_EYES_ONLY) - return failure("circleType has invalid value"); - - switch(circleType) - { - case RsGxsCircleType::EXTERNAL: - if(circleId.isNull()) - return failure("circleType is EXTERNAL but circleId is null"); - break; - case RsGxsCircleType::NODES_GROUP: - { - RsGroupInfo ginfo; - - if(!rsPeers->getGroupInfo(RsNodeGroupId(circleId), ginfo)) - return failure( "circleType is NODES_GROUP but circleId does not " - "correspond to an actual group of friends" ); - break; - } - default: - if(!circleId.isNull()) - return failure( "circleType requires a null circleId, but a non " - "null circleId (" + circleId.toStdString() + - ") was supplied" ); - break; - } - - // Create a consistent channel group meta from the information supplied - RsGxsChannelGroup channel; - - channel.mMeta.mGroupName = name; - channel.mMeta.mAuthorId = authorId; - channel.mMeta.mCircleType = static_cast(circleType); - - channel.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ - | GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; - - channel.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - - channel.mMeta.mCircleId.clear(); - channel.mMeta.mInternalCircle.clear(); - - switch(circleType) - { - case RsGxsCircleType::NODES_GROUP: - channel.mMeta.mInternalCircle = circleId; break; - case RsGxsCircleType::EXTERNAL: - channel.mMeta.mCircleId = circleId; break; - default: break; - } - - // Create the channel - channel.mDescription = description; - channel.mImage = thumbnail; - - uint32_t token; - if(!createGroup(token, channel)) - return failure("Failure creating GXS group"); - - // wait for the group creation to complete. - RsTokenService::GxsRequestStatus wSt = - waitToken( token, std::chrono::seconds(5), - std::chrono::milliseconds(50) ); - if(wSt != RsTokenService::COMPLETE) - return failure( "GXS operation waitToken failed with: " + - std::to_string(wSt) ); - - if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta)) - return failure("Failure getting updated group data."); - - channelId = channel.mMeta.mGroupId; - -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex::indexChannelGroup(channel); -#endif // RS_DEEP_CHANNEL_INDEX - - return true; -} - -bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel) -{ - uint32_t token; - if(!createGroup(token, channel)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating group." - << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated " - << " group data." << std::endl; - return false; - } - -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex::indexChannelGroup(channel); -#endif // RS_DEEP_CHANNEL_INDEX - - return true; -} - -bool p3GxsChannels::createVoteV2( - const RsGxsGroupId& channelId, const RsGxsMessageId& postId, - const RsGxsMessageId& commentId, const RsGxsId& authorId, - RsGxsVoteType tVote, RsGxsMessageId& voteId, std::string& errorMessage ) -{ - std::vector channelsInfo; - if(!getChannelsInfo(std::list({channelId}),channelsInfo)) - { - errorMessage = "Channel with Id " + channelId.toStdString() - + " does not exist."; - return false; - } - - if(commentId.isNull()) - { - errorMessage = "You cannot vote on null comment " - + commentId.toStdString(); - return false; - } - - std::set s({commentId}); - std::vector posts; - std::vector comments; - std::vector votes; - - if(!getChannelContent(channelId, s, posts, comments, votes)) - { - errorMessage = "You cannot vote on comment " - + commentId.toStdString() + " of channel with Id " - + channelId.toStdString() - + ": this comment does not exists locally!"; - return false; - } - - // is the ID a comment ID or a post ID? - // It should be comment => should have a parent ID - if(posts.front().mMeta.mParentId.isNull()) - { - errorMessage = "You cannot vote on channel message " - + commentId.toStdString() + " of channel with Id " - + channelId.toStdString() - + ": given id refers to a post, not a comment!"; - return false; - } - - if( tVote != RsGxsVoteType::NONE - && tVote != RsGxsVoteType::UP - && tVote != RsGxsVoteType::DOWN ) - { - errorMessage = "Your vote to channel with Id " - + channelId.toStdString() + " has wrong vote type. " - + " Only RsGxsVoteType::NONE, RsGxsVoteType::UP, " - + "RsGxsVoteType::DOWN are accepted."; - return false; - } - - if(!rsIdentity->isOwnId(authorId)) - { - errorMessage = "You cannot vote to channel with Id " - + channelId.toStdString() + " with identity " - + authorId.toStdString() + " because it is not yours."; - return false; - } - - // Create the vote - RsGxsVote vote; - vote.mMeta.mGroupId = channelId; - vote.mMeta.mThreadId = postId; - vote.mMeta.mParentId = commentId; - vote.mMeta.mAuthorId = authorId; - vote.mVoteType = static_cast(tVote); - - uint32_t token; - if(!createNewVote(token, vote)) - { - errorMessage = "Error! Failed creating vote."; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - errorMessage = "GXS operation failed."; - return false; - } - - if(!RsGenExchange::getPublishedMsgMeta(token, vote.mMeta)) - { - errorMessage = "Failure getting generated vote data."; - return false; - } - - voteId = vote.mMeta.mMsgId; - return true; -} - -/// @deprecated use createVoteV2 instead -bool p3GxsChannels::createVote(RsGxsVote& vote) -{ - uint32_t token; - if(!createNewVote(token, vote)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating vote." - << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedMsgMeta(token, vote.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting generated " - << " vote data." << std::endl; - return false; - } - - return true; -} - -bool p3GxsChannels::editChannel(RsGxsChannelGroup& channel) -{ - uint32_t token; - if(!updateGroup(token, channel)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed updating group." - << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, channel.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated " - << " group data." << std::endl; - return false; - } - -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex::indexChannelGroup(channel); -#endif // RS_DEEP_CHANNEL_INDEX - - return true; -} - -bool p3GxsChannels::createPostV2( - const RsGxsGroupId& channelId, const std::string& title, - const std::string& body, const std::list& files, - const RsGxsImage& thumbnail, const RsGxsMessageId& origPostId, - RsGxsMessageId& postId, std::string& errorMessage ) -{ - // Do some checks - - std::vector channelsInfo; - - if(!getChannelsInfo(std::list({channelId}),channelsInfo)) - { - errorMessage = "Channel with Id " + channelId.toStdString() + - " does not exist."; - return false; - } - - const RsGxsChannelGroup& cg(*channelsInfo.begin()); - - if(!(cg.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)) - { - errorMessage = "You cannot post to channel with Id " + - channelId.toStdString() + ": missing publish rights!"; - return false; - } - - if(!origPostId.isNull()) - { - std::set s({origPostId}); - std::vector posts; - std::vector comments; - std::vector votes; - - if(!getChannelContent(channelId,s,posts,comments,votes)) - { - errorMessage = "You cannot edit post " + origPostId.toStdString() - + " of channel with Id " + channelId.toStdString() - + ": this post does not exist locally!"; - return false; - } - } - - // Create the post - RsGxsChannelPost post; - - post.mMeta.mGroupId = channelId; - post.mMeta.mOrigMsgId = origPostId; - post.mMeta.mMsgName = title; - - post.mMsg = body; - post.mFiles = files; - post.mThumbnail = thumbnail; - - uint32_t token; - if(!createPost(token, post) || waitToken(token) != RsTokenService::COMPLETE) - { - errorMessage = "GXS operation failed"; - return false; - } - - if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta)) - { -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex::indexChannelPost(post); -#endif // RS_DEEP_CHANNEL_INDEX - - postId = post.mMeta.mMsgId; - return true; - } - - errorMessage = "Failed to retrive created post metadata"; - return false; -} - -bool p3GxsChannels::createCommentV2( - const RsGxsGroupId& channelId, - const RsGxsMessageId& threadId, - const std::string& comment, - const RsGxsId& authorId, - const RsGxsMessageId& parentId, - const RsGxsMessageId& origCommentId, - RsGxsMessageId& commentMessageId, - std::string& errorMessage ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errorMessage = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(channelId.isNull()) return failure("channelId cannot be null"); - if(threadId.isNull()) return failure("threadId cannot be null"); - if(parentId.isNull()) return failure("parentId cannot be null"); - - std::vector channelsInfo; - if(!getChannelsInfo(std::list({channelId}),channelsInfo)) - return failure( "Channel with Id " + channelId.toStdString() - + " does not exist." ); - - std::vector posts; - std::vector comments; - std::vector votes; - - if(!getChannelContent( // does the post thread exist? - channelId, std::set({threadId}), - posts, comments, votes) ) - return failure( "You cannot comment post " + threadId.toStdString() + - " of channel with Id " + channelId.toStdString() + - ": this post does not exists locally!" ); - - // check that the post thread Id is actually that of a post thread - if(posts.size() != 1 || !posts[0].mMeta.mParentId.isNull()) - return failure( "You cannot comment post " + threadId.toStdString() + - " of channel with Id " + channelId.toStdString() + - ": supplied threadId is not a thread, or parentMsgId is" - " not a comment!"); - - if(!getChannelContent( // does the post parent exist? - channelId, std::set({parentId}), - posts, comments, votes) ) - return failure( "You cannot comment post " + parentId.toStdString() + - ": supplied parent doesn't exists locally!" ); - - if(!origCommentId.isNull()) - { - std::set s({origCommentId}); - std::vector cmts; - - if( !getChannelContent(channelId, s, posts, cmts, votes) || - comments.size() != 1 ) - return failure( "You cannot edit comment " + - origCommentId.toStdString() + - " of channel with Id " + channelId.toStdString() + - ": this comment does not exist locally!"); - - const RsGxsId& commentAuthor = comments[0].mMeta.mAuthorId; - if(commentAuthor != authorId) - return failure( "Editor identity and creator doesn't match " - + authorId.toStdString() + " != " - + commentAuthor.toStdString() ); - } - - if(!rsIdentity->isOwnId(authorId)) // is the author ID actually ours? - return failure( "You cannot comment to channel with Id " + - channelId.toStdString() + " with identity " + - authorId.toStdString() + " because it is not yours." ); - - // Now create the comment - RsGxsComment cmt; - cmt.mMeta.mGroupId = channelId; - cmt.mMeta.mThreadId = threadId; - cmt.mMeta.mParentId = parentId; - cmt.mMeta.mAuthorId = authorId; - cmt.mMeta.mOrigMsgId = origCommentId; - cmt.mComment = comment; - - uint32_t token; - if(!createNewComment(token, cmt)) - return failure("createNewComment failed"); - - RsTokenService::GxsRequestStatus wSt = waitToken(token); - if(wSt != RsTokenService::COMPLETE) - return failure( "GXS operation waitToken failed with: " + - std::to_string(wSt) ); - - if(!RsGenExchange::getPublishedMsgMeta(token, cmt.mMeta)) - return failure("Failure getting created comment data."); - - commentMessageId = cmt.mMeta.mMsgId; - return true; -} - -bool p3GxsChannels::createComment(RsGxsComment& comment) // deprecated -{ - uint32_t token; - if(!createNewComment(token, comment)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed creating comment." - << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedMsgMeta(token, comment.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting generated " - << " comment data." << std::endl; - return false; - } - - return true; -} - -bool p3GxsChannels::subscribeToChannel( const RsGxsGroupId& groupId, bool subscribe ) -{ - uint32_t token; - if( !subscribeToGroup(token, groupId, subscribe) || waitToken(token) != RsTokenService::COMPLETE ) return false; - - RsGxsGroupId grpId; - acknowledgeGrp(token,grpId); - return true; -} - -bool p3GxsChannels::markRead(const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t token; - setMessageReadStatus(token, msgId, read); - if(waitToken(token) != RsTokenService::COMPLETE ) return false; - - RsGxsGrpMsgIdPair p; - acknowledgeMsg(token,p); - - return true; -} - -bool p3GxsChannels::shareChannelKeys( - const RsGxsGroupId& channelId, const std::set& peers) -{ - return groupShareKeys(channelId, peers); -} - - -//////////////////////////////////////////////////////////////////////////////// -/// Blocking API implementation end -//////////////////////////////////////////////////////////////////////////////// - - -/********************************************************************************************/ -/********************************************************************************************/ - - -bool p3GxsChannels::autoDownloadEnabled(const RsGxsGroupId &groupId,bool& enabled) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::autoDownloadEnabled(" << groupId << ")"; - std::cerr << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - std::map::iterator it; - it = mSubscribedGroups.find(groupId); - if (it == mSubscribedGroups.end()) - { - std::cerr << __PRETTY_FUNCTION__ << " WARNING requested channel: " - << groupId << " is not subscribed" << std::endl; - return false; - } - - /* extract from ServiceString */ - GxsChannelGroupInfo ss; - ss.load(it->second.mServiceString); - enabled = ss.mAutoDownload; - - return true; -} - -bool GxsChannelGroupInfo::load(const std::string &input) -{ - if(input.empty()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "SSGxsChannelGroup::load() asked to load a null string." << std::endl; -#endif - return true ; - } - int download_val; - mAutoDownload = false; - mDownloadDirectory.clear(); - - - RsTemporaryMemory tmpmem(input.length()); - - if (1 == sscanf(input.c_str(), "D:%d", &download_val)) - { - if (download_val == 1) - mAutoDownload = true; - } - else if( 2 == sscanf(input.c_str(),"v2 {D:%d} {P:%[^}]}",&download_val,(unsigned char*)tmpmem)) - { - if (download_val == 1) - mAutoDownload = true; - - std::vector vals = Radix64::decode(std::string((char*)(unsigned char *)tmpmem)) ; - mDownloadDirectory = std::string((char*)vals.data(),vals.size()); - } - else if( 1 == sscanf(input.c_str(),"v2 {D:%d}",&download_val)) - { - if (download_val == 1) - mAutoDownload = true; - } - else - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "SSGxsChannelGroup::load(): could not parse string \"" << input << "\"" << std::endl; -#endif - return false ; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "DECODED STRING: autoDL=" << mAutoDownload << ", directory=\"" << mDownloadDirectory << "\"" << std::endl; -#endif - - return true; -} - -std::string GxsChannelGroupInfo::save() const -{ - std::string output = "v2 "; - - if (mAutoDownload) - output += "{D:1}"; - else - output += "{D:0}"; - - if(!mDownloadDirectory.empty()) - { - std::string encoded_str ; - Radix64::encode((unsigned char*)mDownloadDirectory.c_str(),mDownloadDirectory.length(),encoded_str); - - output += " {P:" + encoded_str + "}"; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "ENCODED STRING: " << output << std::endl; -#endif - - return output; -} - -bool p3GxsChannels::setAutoDownload(const RsGxsGroupId& groupId, bool enabled) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " id: " << groupId - << " enabled: " << enabled << std::endl; -#endif - - RS_STACK_MUTEX(mSubscribedGroupsMutex); - std::map::iterator it; - it = mSubscribedGroups.find(groupId); - if (it == mSubscribedGroups.end()) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR requested channel: " - << groupId.toStdString() << " is not subscribed!" << std::endl; - return false; - } - - /* extract from ServiceString */ - GxsChannelGroupInfo ss; - ss.load(it->second.mServiceString); - if (enabled == ss.mAutoDownload) - { - std::cerr << __PRETTY_FUNCTION__ << " WARNING mAutoDownload was already" - << " properly set to: " << enabled << " for channel:" - << groupId.toStdString() << std::endl; - return false; - } - - ss.mAutoDownload = enabled; - std::string serviceString = ss.save(); - - uint32_t token; - RsGenExchange::setGroupServiceString(token, groupId, serviceString); - - if(waitToken(token) != RsTokenService::COMPLETE) return false; - - it->second.mServiceString = serviceString; // update Local Cache. - - return true; -} - -/********************************************************************************************/ -/********************************************************************************************/ - -void p3GxsChannels::setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool processed) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::setMessageProcessedStatus()"; - std::cerr << std::endl; -#endif - - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - if (processed) - { - status = 0; - } - setMsgStatusFlags(token, msgId, status, mask); -} - -void p3GxsChannels::setMessageReadStatus( uint32_t& token, - const RsGxsGrpMsgIdPair& msgId, - bool read ) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::setMessageReadStatus()"; - std::cerr << std::endl; -#endif - - /* Always remove status unprocessed */ - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - if (read) status = 0; - - setMsgStatusFlags(token, msgId, status, mask); - - if (rsEvents) - { - auto ev = std::make_shared(); - - ev->mChannelMsgId = msgId.second; - ev->mChannelGroupId = msgId.first; - ev->mChannelEventCode = RsChannelEventCode::READ_STATUS_CHANGED; - rsEvents->postEvent(ev); - } -} - -/********************************************************************************************/ -/********************************************************************************************/ - -bool p3GxsChannels::createGroup(uint32_t &token, RsGxsChannelGroup &group) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::createGroup()" << std::endl; -#endif - - RsGxsChannelGroupItem* grpItem = new RsGxsChannelGroupItem(); - grpItem->fromChannelGroup(group, true); - - RsGenExchange::publishGroup(token, grpItem); - return true; -} - - -bool p3GxsChannels::updateGroup(uint32_t &token, RsGxsChannelGroup &group) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::updateGroup()" << std::endl; -#endif - - RsGxsChannelGroupItem* grpItem = new RsGxsChannelGroupItem(); - grpItem->fromChannelGroup(group, true); - - RsGenExchange::updateGroup(token, grpItem); - return true; -} - -/// @deprecated use createPostV2 instead -bool p3GxsChannels::createPost(RsGxsChannelPost& post) -{ - uint32_t token; - if( !createPost(token, post) - || waitToken(token) != RsTokenService::COMPLETE ) return false; - - if(RsGenExchange::getPublishedMsgMeta(token,post.mMeta)) - { -#ifdef RS_DEEP_CHANNEL_INDEX - DeepChannelsIndex::indexChannelPost(post); -#endif // RS_DEEP_CHANNEL_INDEX - - return true; - } - - return false; -} - - -bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " GroupId: " << msg.mMeta.mGroupId - << std::endl; -#endif - - RsGxsChannelPostItem* msgItem = new RsGxsChannelPostItem(); - msgItem->fromChannelPost(msg, true); - - RsGenExchange::publishMsg(token, msgItem); - return true; -} - -/********************************************************************************************/ -/********************************************************************************************/ - -bool p3GxsChannels::ExtraFileHash(const std::string& path) -{ - TransferRequestFlags flags = RS_FILE_REQ_ANONYMOUS_ROUTING; - return rsFiles->ExtraFileHash(path, GXSCHANNEL_STOREPERIOD, flags); -} - - -bool p3GxsChannels::ExtraFileRemove(const RsFileHash& hash) -{ return rsFiles->ExtraFileRemove(hash); } - - -/********************************************************************************************/ -/********************************************************************************************/ - -/* so we need the same tick idea as wiki for generating dummy channels - */ - -#define MAX_GEN_GROUPS 20 -#define MAX_GEN_POSTS 500 -#define MAX_GEN_COMMENTS 600 -#define MAX_GEN_VOTES 700 - -std::string p3GxsChannels::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -bool p3GxsChannels::generateDummyData() -{ - mGenCount = 0; - mGenRefs.resize(MAX_GEN_VOTES); - - std::string groupName; - rs_sprintf(groupName, "TestChannel_%d", mGenCount); - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::generateDummyData() Starting off with Group: " << groupName; - std::cerr << std::endl; -#endif - - /* create a new group */ - generateGroup(mGenToken, groupName); - - mGenActive = true; - - return true; -} - - -void p3GxsChannels::dummy_tick() -{ - /* check for a new callback */ - - if (mGenActive) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummyTick() Gen Active"; - std::cerr << std::endl; -#endif - - uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken); - if (status != RsTokenService::COMPLETE) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Status: " << status; - std::cerr << std::endl; -#endif - - if (status == RsTokenService::FAILED) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() generateDummyMsgs() FAILED"; - std::cerr << std::endl; -#endif - mGenActive = false; - } - return; - } - - if (mGenCount < MAX_GEN_GROUPS) - { - /* get the group Id */ - RsGxsGroupId groupId; - RsGxsMessageId emptyId; - if (!acknowledgeTokenGrp(mGenToken, groupId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Acknowledged GroupId: " << groupId; - std::cerr << std::endl; -#endif - - ChannelDummyRef ref(groupId, emptyId, emptyId); - mGenRefs[mGenCount] = ref; - } - else if (mGenCount < MAX_GEN_POSTS) - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mGenToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Post "; - std::cerr << std::endl; -#endif - - /* store results for later selection */ - - ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second); - mGenRefs[mGenCount] = ref; - } - else if (mGenCount < MAX_GEN_COMMENTS) - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mGenToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Comment "; - std::cerr << std::endl; -#endif - - /* store results for later selection */ - - ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second); - mGenRefs[mGenCount] = ref; - } - else if (mGenCount < MAX_GEN_VOTES) - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeVote(mGenToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Vote "; - std::cerr << std::endl; -#endif - - /* store results for later selection */ - - ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second); - mGenRefs[mGenCount] = ref; - } - else - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Finished"; - std::cerr << std::endl; -#endif - - /* done */ - mGenActive = false; - return; - } - - mGenCount++; - - if (mGenCount < MAX_GEN_GROUPS) - { - std::string groupName; - rs_sprintf(groupName, "TestChannel_%d", mGenCount); - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Generating Group: " << groupName; - std::cerr << std::endl; -#endif - - /* create a new group */ - generateGroup(mGenToken, groupName); - } - else if (mGenCount < MAX_GEN_POSTS) - { - /* create a new post */ - uint32_t idx = (uint32_t) (MAX_GEN_GROUPS * RSRandom::random_f32()); - ChannelDummyRef &ref = mGenRefs[idx]; - - RsGxsGroupId grpId = ref.mGroupId; - RsGxsMessageId parentId = ref.mMsgId; - mGenThreadId = ref.mThreadId; - if (mGenThreadId.isNull()) - { - mGenThreadId = parentId; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Generating Post ... "; - std::cerr << " GroupId: " << grpId; - std::cerr << " ThreadId: " << mGenThreadId; - std::cerr << " ParentId: " << parentId; - std::cerr << std::endl; -#endif - - generatePost(mGenToken, grpId); - } - else if (mGenCount < MAX_GEN_COMMENTS) - { - /* create a new post */ - uint32_t idx = (uint32_t) ((mGenCount - MAX_GEN_GROUPS) * RSRandom::random_f32()); - ChannelDummyRef &ref = mGenRefs[idx + MAX_GEN_GROUPS]; - - RsGxsGroupId grpId = ref.mGroupId; - RsGxsMessageId parentId = ref.mMsgId; - mGenThreadId = ref.mThreadId; - if (mGenThreadId.isNull()) - { - mGenThreadId = parentId; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Generating Comment ... "; - std::cerr << " GroupId: " << grpId; - std::cerr << " ThreadId: " << mGenThreadId; - std::cerr << " ParentId: " << parentId; - std::cerr << std::endl; -#endif - - generateComment(mGenToken, grpId, parentId, mGenThreadId); - } - else - { - /* create a new post */ - uint32_t idx = (uint32_t) ((MAX_GEN_COMMENTS - MAX_GEN_POSTS) * RSRandom::random_f32()); - ChannelDummyRef &ref = mGenRefs[idx + MAX_GEN_POSTS]; - - RsGxsGroupId grpId = ref.mGroupId; - RsGxsMessageId parentId = ref.mMsgId; - mGenThreadId = ref.mThreadId; - if (mGenThreadId.isNull()) - { - mGenThreadId = parentId; - } - -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::dummy_tick() Generating Vote ... "; - std::cerr << " GroupId: " << grpId; - std::cerr << " ThreadId: " << mGenThreadId; - std::cerr << " ParentId: " << parentId; - std::cerr << std::endl; -#endif - - generateVote(mGenToken, grpId, parentId, mGenThreadId); - } - - } - -#ifdef TO_REMOVE - cleanTimedOutCallbacks(); -#endif -} - - -bool p3GxsChannels::generatePost(uint32_t &token, const RsGxsGroupId &grpId) -{ - RsGxsChannelPost msg; - - std::string rndId = genRandomId(); - - rs_sprintf(msg.mMsg, "Channel Msg: GroupId: %s, some randomness: %s", - grpId.toStdString().c_str(), rndId.c_str()); - - msg.mMeta.mMsgName = msg.mMsg; - - msg.mMeta.mGroupId = grpId; - msg.mMeta.mThreadId.clear() ; - msg.mMeta.mParentId.clear() ; - - msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - createPost(token, msg); - - return true; -} - - -bool p3GxsChannels::generateComment(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId) -{ - RsGxsComment msg; - - std::string rndId = genRandomId(); - - rs_sprintf(msg.mComment, "Channel Comment: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s", - grpId.toStdString().c_str(), threadId.toStdString().c_str(), parentId.toStdString().c_str(), rndId.c_str()); - - msg.mMeta.mMsgName = msg.mComment; - - msg.mMeta.mGroupId = grpId; - msg.mMeta.mThreadId = threadId; - msg.mMeta.mParentId = parentId; - - msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - /* chose a random Id to sign with */ - std::list ownIds; - std::list::iterator it; - - rsIdentity->getOwnIds(ownIds); - - uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); - uint32_t i = 0; - for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); ++it, ++i); - - if (it != ownIds.end()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::generateComment() Author: " << *it; - std::cerr << std::endl; -#endif - msg.mMeta.mAuthorId = *it; - } -#ifdef GXSCHANNELS_DEBUG - else - { - std::cerr << "p3GxsChannels::generateComment() No Author!"; - std::cerr << std::endl; - } -#endif - - createNewComment(token, msg); - - return true; -} - - -bool p3GxsChannels::generateVote(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId) -{ - RsGxsVote vote; - - vote.mMeta.mGroupId = grpId; - vote.mMeta.mThreadId = threadId; - vote.mMeta.mParentId = parentId; - vote.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - /* chose a random Id to sign with */ - std::list ownIds; - std::list::iterator it; - - rsIdentity->getOwnIds(ownIds); - - uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); - uint32_t i = 0; - for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); ++it, ++i) ; - - if (it != ownIds.end()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::generateVote() Author: " << *it; - std::cerr << std::endl; -#endif - vote.mMeta.mAuthorId = *it; - } -#ifdef GXSCHANNELS_DEBUG - else - { - std::cerr << "p3GxsChannels::generateVote() No Author!"; - std::cerr << std::endl; - } -#endif - - if (0.7 > RSRandom::random_f32()) - { - // 70 % postive votes - vote.mVoteType = GXS_VOTE_UP; - } - else - { - vote.mVoteType = GXS_VOTE_DOWN; - } - - createNewVote(token, vote); - - return true; -} - - -bool p3GxsChannels::generateGroup(uint32_t &token, std::string groupName) -{ - /* generate a new channel */ - RsGxsChannelGroup channel; - channel.mMeta.mGroupName = groupName; - - createGroup(token, channel); - - return true; -} - - - // Overloaded from RsTickEvent for Event callbacks. -void p3GxsChannels::handle_event(uint32_t event_type, const std::string &elabel) -{ -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::handle_event(" << event_type << ")"; - std::cerr << std::endl; -#endif - - // stuff. - switch(event_type) - { - case CHANNEL_TESTEVENT_DUMMYDATA: - generateDummyData(); - break; - - case CHANNEL_PROCESS: - request_AllSubscribedGroups(); - break; - - default: - /* error */ - std::cerr << "p3GxsChannels::handle_event() Unknown Event Type: " << event_type << " elabel:" << elabel; - std::cerr << std::endl; - break; - } -} - -TurtleRequestId p3GxsChannels::turtleGroupRequest(const RsGxsGroupId& group_id) -{ - return netService()->turtleGroupRequest(group_id) ; -} -TurtleRequestId p3GxsChannels::turtleSearchRequest(const std::string& match_string) -{ - return netService()->turtleSearchRequest(match_string); -} - -bool p3GxsChannels::clearDistantSearchResults(TurtleRequestId req) -{ - return netService()->clearDistantSearchResults(req); -} -bool p3GxsChannels::retrieveDistantSearchResults(TurtleRequestId req,std::map& results) -{ - return netService()->retrieveDistantSearchResults(req,results); -} - -DistantSearchGroupStatus p3GxsChannels::getDistantSearchStatus(const RsGxsGroupId& group_id) -{ - return netService()->getDistantSearchStatus(group_id); -} -bool p3GxsChannels::getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group) -{ - RsGxsGroupSearchResults gs; - - if(netService()->retrieveDistantGroupSummary(group_id,gs)) - { - // This is a placeholder information by the time we receive the full group meta data and check the signature. - distant_group.mMeta.mGroupId = gs.mGroupId ; - distant_group.mMeta.mGroupName = gs.mGroupName; - distant_group.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC ; - distant_group.mMeta.mSignFlags = gs.mSignFlags; - - distant_group.mMeta.mPublishTs = gs.mPublishTs; - distant_group.mMeta.mAuthorId = gs.mAuthorId; - - distant_group.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC ;// guessed, otherwise the group would not be search-able. - - // other stuff. - distant_group.mMeta.mAuthenFlags = 0; // wild guess... - - distant_group.mMeta.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED ; - - distant_group.mMeta.mPop = gs.mPopularity; // Popularity = number of friend subscribers - distant_group.mMeta.mVisibleMsgCount = gs.mNumberOfMessages; // Max messages reported by friends - distant_group.mMeta.mLastPost = gs.mLastMessageTs; // Timestamp for last message. Not used yet. - - return true ; - } - else - return false ; -} - -#ifdef TO_REMOVE -bool p3GxsChannels::turtleSearchRequest( - const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait ) -{ - if(matchString.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << " match string can't be empty!" - << std::endl; - return false; - } - - TurtleRequestId sId = turtleSearchRequest(matchString); - - { - RS_STACK_MUTEX(mSearchCallbacksMapMutex); - mSearchCallbacksMap.emplace( - sId, - std::make_pair( - multiCallback, - std::chrono::system_clock::now() + - std::chrono::seconds(maxWait) ) ); - } - - return true; -} - -/// @see RsGxsChannels::turtleChannelRequest -bool p3GxsChannels::turtleChannelRequest( - const RsGxsGroupId& channelId, - const std::function& multiCallback, - rstime_t maxWait) -{ - if(channelId.isNull()) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! channelId can't be null!" - << std::endl; - return false; - } - - TurtleRequestId sId = turtleGroupRequest(channelId); - - { - RS_STACK_MUTEX(mDistantChannelsCallbacksMapMutex); - mDistantChannelsCallbacksMap.emplace( - sId, - std::make_pair( - multiCallback, - std::chrono::system_clock::now() + - std::chrono::seconds(maxWait) ) ); - } - - return true; -} - -/// @see RsGxsChannels::localSearchRequest -bool p3GxsChannels::localSearchRequest( - const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait ) -{ - if(matchString.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << " match string can't be empty!" - << std::endl; - return false; - } - - auto timeout = std::chrono::steady_clock::now() + std::chrono::seconds(maxWait); - RsThread::async([=]() - { - std::list results; - RsGenExchange::localSearch(matchString, results); - if(std::chrono::steady_clock::now() < timeout) - for(const RsGxsGroupSummary& result : results) multiCallback(result); - }); - - return true; -} -#endif - -void p3GxsChannels::receiveDistantSearchResults( TurtleRequestId id, const RsGxsGroupId& grpId ) -{ - if(!rsEvents) - return; - - // We temporise here, in order to avoid notifying clients with many events - // So we put some data in there and will send an event with all of them at once every 1 sec at most. - - mSearchResultsToNotify[id].insert(grpId); -} - -bool p3GxsChannels::exportChannelLink( std::string& link, const RsGxsGroupId& chanId, bool includeGxsData, const std::string& baseUrl, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(chanId.isNull()) return failure("chanId cannot be null"); - - const bool outputRadix = baseUrl.empty(); - if(outputRadix && !includeGxsData) return - failure("includeGxsData must be true if format requested is base64"); - - if( includeGxsData && - !RsGenExchange::exportGroupBase64(link, chanId, errMsg) ) - return failure(errMsg); - - if(outputRadix) return true; - - std::vector chansInfo; - if( !getChannelsInfo(std::list({chanId}), chansInfo) - || chansInfo.empty() ) - return failure("failure retrieving channel information"); - - RsUrl inviteUrl(baseUrl); - inviteUrl.setQueryKV(CHANNEL_URL_ID_FIELD, chanId.toStdString()); - inviteUrl.setQueryKV(CHANNEL_URL_NAME_FIELD, chansInfo[0].mMeta.mGroupName); - if(includeGxsData) inviteUrl.setQueryKV(CHANNEL_URL_DATA_FIELD, link); - - link = inviteUrl.toString(); - return true; -} - -bool p3GxsChannels::importChannelLink( const std::string& link, RsGxsGroupId& chanId, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(link.empty()) return failure("link is empty"); - - const std::string* radixPtr(&link); - - RsUrl url(link); - const auto& query = url.query(); - const auto qIt = query.find(CHANNEL_URL_DATA_FIELD); - if(qIt != query.end()) radixPtr = &qIt->second; - - if(radixPtr->empty()) return failure(CHANNEL_URL_DATA_FIELD + " is empty"); - - if(!RsGenExchange::importGroupBase64(*radixPtr, chanId, errMsg)) - return failure(errMsg); - - return true; -} - -/*static*/ const std::string RsGxsChannels::DEFAULT_CHANNEL_BASE_URL = "retroshare:///channels"; -/*static*/ const std::string RsGxsChannels::CHANNEL_URL_NAME_FIELD = "chanName"; -/*static*/ const std::string RsGxsChannels::CHANNEL_URL_ID_FIELD = "chanId"; -/*static*/ const std::string RsGxsChannels::CHANNEL_URL_DATA_FIELD = "chanData"; -/*static*/ const std::string RsGxsChannels::CHANNEL_URL_MSG_TITLE_FIELD = "chanMsgTitle"; -/*static*/ const std::string RsGxsChannels::CHANNEL_URL_MSG_ID_FIELD = "chanMsgId"; - -RsGxsChannelGroup::~RsGxsChannelGroup() = default; -RsGxsChannelPost::~RsGxsChannelPost() = default; -RsGxsChannels::~RsGxsChannels() = default; diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h deleted file mode 100644 index b5fe1426f..000000000 --- a/libretroshare/src/services/p3gxschannels.h +++ /dev/null @@ -1,415 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxschannels.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - - -#include "retroshare/rsgxschannels.h" -#include "services/p3gxscommon.h" -#include "gxs/rsgenexchange.h" -#include "gxs/gxstokenqueue.h" -#include "util/rsmemory.h" -#include "util/rsdebug.h" -#include "util/rstickevent.h" - -#include -#include - - -// This class is only a helper to parse the channel group service string. - -class GxsChannelGroupInfo -{ - public: - GxsChannelGroupInfo(): mAutoDownload(false), mDownloadDirectory("") {} - bool load(const std::string &input); - std::string save() const; - - bool mAutoDownload; - std::string mDownloadDirectory; -}; - - -class p3GxsChannels: public RsGenExchange, public RsGxsChannels, - public GxsTokenQueue, public p3Config, - public RsTickEvent /* only needed for testing - remove after */ -{ -public: - p3GxsChannels( RsGeneralDataService* gds, RsNetworkExchangeService* nes, - RsGixs* gixs ); - virtual RsServiceInfo getServiceInfo() override; - - virtual void service_tick() override; - -protected: - - virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override; // see RsGenExchange - - virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser() - virtual bool saveList(bool &cleanup, std::list&saveList) override; // @see p3Config::saveList(bool &cleanup, std::list&) - virtual bool loadList(std::list& loadList) override; // @see p3Config::loadList(std::list&) - - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id) override; - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string) override; - virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &results) override; - virtual bool clearDistantSearchResults(TurtleRequestId req) override; - virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group) override; - virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) override; - - // Overloaded to cache new groups. -virtual RsGenExchange::ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override; - -virtual void notifyChanges(std::vector& changes) override; - - // Overloaded from RsTickEvent. -virtual void handle_event(uint32_t event_type, const std::string &elabel) override; - -public: - -virtual bool getGroupData(const uint32_t &token, std::vector &groups ) override; -virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts, std::vector &vots) override; -virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts) override; -virtual bool getPostData(const uint32_t &token, std::vector &posts) override; -//Not currently used -//virtual bool getRelatedPosts(const uint32_t &token, std::vector &posts); - - ////////////////////////////////////////////////////////////////////////////// - -//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask); -//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask); - -//virtual bool groupRestoreKeys(const std::string &groupId); - virtual bool groupShareKeys( - const RsGxsGroupId &groupId, const std::set& peers) override; - -virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group) override; -virtual bool createPost(uint32_t &token, RsGxsChannelPost &post) override; - -virtual bool updateGroup(uint32_t &token, RsGxsChannelGroup &group) override; - -// no tokens... should be cached. -virtual bool setChannelAutoDownload(const RsGxsGroupId &groupId, bool enabled) override; -virtual bool getChannelAutoDownload(const RsGxsGroupId &groupid, bool& enabled) override; -virtual bool setChannelDownloadDirectory(const RsGxsGroupId &groupId, const std::string& directory) override; -virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::string& directory) override; - -#ifdef TO_REMOVE - /// @see RsGxsChannels::turtleSearchRequest - virtual bool turtleSearchRequest(const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait = 300 ) override; - - /// @see RsGxsChannels::turtleChannelRequest - virtual bool turtleChannelRequest( - const RsGxsGroupId& channelId, - const std::function& multiCallback, - rstime_t maxWait = 300 ) override; - - /// @see RsGxsChannels::localSearchRequest - virtual bool localSearchRequest(const std::string& matchString, - const std::function& multiCallback, - rstime_t maxWait = 30 ) override; -#endif - - /** - * Receive results from turtle search @see RsGenExchange @see RsNxsObserver - * @see RsGxsNetService::receiveTurtleSearchResults - * @see p3turtle::handleSearchResult - */ - void receiveDistantSearchResults( TurtleRequestId id, - const RsGxsGroupId& grpId ) override; - - /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ - virtual bool getCommentData(uint32_t token, std::vector &msgs) override - { return mCommentService->getGxsCommentData(token, msgs); } - - virtual bool getRelatedComments( uint32_t token, - std::vector &msgs ) override - { return mCommentService->getGxsRelatedComments(token, msgs); } - - virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override - { - return mCommentService->createGxsComment(token, msg); - } - - virtual bool setCommentAsRead(uint32_t& token,const RsGxsGroupId& gid,const RsGxsMessageId& comment_msg_id) override - { - setMessageReadStatus(token,RsGxsGrpMsgIdPair(gid,comment_msg_id),true); - return true; - } - - virtual bool createNewVote(uint32_t &token, RsGxsVote &msg) override - { - return mCommentService->createGxsVote(token, msg); - } - - virtual bool acknowledgeComment(uint32_t token, std::pair& msgId) override - { - return acknowledgeMsg(token, msgId); - } - - virtual bool acknowledgeVote(uint32_t token, std::pair& msgId) override - { - if (mCommentService->acknowledgeVote(token, msgId)) - { - return true; - } - return acknowledgeMsg(token, msgId); - } - - - // Overloaded from RsGxsIface. -virtual bool subscribeToGroup(uint32_t &token, const RsGxsGroupId &groupId, bool subscribe) override; - - // Set Statuses. -virtual void setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool processed); -virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override; - - // File Interface - virtual bool ExtraFileHash(const std::string& path) override; -virtual bool ExtraFileRemove(const RsFileHash &hash) override; - - - /// Implementation of @see RsGxsChannels::getChannelsSummaries - bool getChannelsSummaries(std::list& channels) override; - - /// Implementation of @see RsGxsChannels::getChannelsInfo - bool getChannelsInfo( - const std::list& chanIds, - std::vector& channelsInfo ) override; - - /// Implementation of @see RsGxsChannels::getChannelAllMessages - bool getChannelAllContent(const RsGxsGroupId& channelId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) override; - - /// Implementation of @see RsGxsChannels::getChannelMessages - bool getChannelContent(const RsGxsGroupId& channelId, - const std::set& contentIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) override; - - /// Implementation of @see RsGxsChannels::getChannelComments - virtual bool getChannelComments(const RsGxsGroupId &channelId, - const std::set &contentIds, - std::vector &comments) override; - - /// Implementation of @see RsGxsChannels::getContentSummaries - bool getContentSummaries( - const RsGxsGroupId& channelId, - std::vector& summaries ) override; - - /// Implementation of @see RsGxsChannels::getChannelStatistics - bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) override; - - /// Iplementation of @see RsGxsChannels::getChannelServiceStatistics - bool getChannelServiceStatistics(GxsServiceStatistic& stat) override; - - /// Implementation of @see RsGxsChannels::createChannelV2 - bool createChannelV2( - const std::string& name, const std::string& description, - const RsGxsImage& thumbnail = RsGxsImage(), - const RsGxsId& authorId = RsGxsId(), - RsGxsCircleType circleType = RsGxsCircleType::PUBLIC, - const RsGxsCircleId& circleId = RsGxsCircleId(), - RsGxsGroupId& channelId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// Implementation of @see RsGxsChannels::createComment - bool createCommentV2( - const RsGxsGroupId& channelId, - const RsGxsMessageId& threadId, - const std::string& comment, - const RsGxsId& authorId, - const RsGxsMessageId& parentId = RsGxsMessageId(), - const RsGxsMessageId& origCommentId = RsGxsMessageId(), - RsGxsMessageId& commentMessageId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// Implementation of @see RsGxsChannels::editChannel - bool editChannel(RsGxsChannelGroup& channel) override; - - /// Implementation of @see RsGxsChannels::createPostV2 - bool createPostV2( - const RsGxsGroupId& channelId, const std::string& title, - const std::string& body, - const std::list& files = std::list(), - const RsGxsImage& thumbnail = RsGxsImage(), - const RsGxsMessageId& origPostId = RsGxsMessageId(), - RsGxsMessageId& postId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// Implementation of @see RsGxsChannels::createVoteV2 - bool createVoteV2( - const RsGxsGroupId& channelId, const RsGxsMessageId& postId, - const RsGxsMessageId& commentId, const RsGxsId& authorId, - RsGxsVoteType vote, - RsGxsMessageId& voteId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// Implementation of @see RsGxsChannels::subscribeToChannel - bool subscribeToChannel( const RsGxsGroupId &groupId, - bool subscribe ) override; - - /// @see RsGxsChannels - virtual bool markRead(const RsGxsGrpMsgIdPair& msgId, bool read) override; - - /// @see RsGxsChannels - bool exportChannelLink( - std::string& link, const RsGxsGroupId& chanId, - bool includeGxsData = true, - const std::string& baseUrl = DEFAULT_CHANNEL_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsChannels - bool importChannelLink( - const std::string& link, - RsGxsGroupId& chanId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - virtual bool shareChannelKeys( - const RsGxsGroupId& channelId, const std::set& peers ) override; - - /// Implementation of @see RsGxsChannels::createChannel - RS_DEPRECATED_FOR(createChannelV2) - bool createChannel(RsGxsChannelGroup& channel) override; - - /// @deprecated Implementation of @see RsGxsChannels::createPost - RS_DEPRECATED_FOR(createPostV2) - bool createPost(RsGxsChannelPost& post) override; - - /// @deprecated Implementation of @see RsGxsChannels::createComment - RS_DEPRECATED_FOR(createCommentV2) - bool createComment(RsGxsComment &comment) override; - - /// @deprecated Implementation of @see RsGxsChannels::createVote - RS_DEPRECATED_FOR(createVoteV2) - bool createVote(RsGxsVote& vote) override; - - -protected: - // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - -private: - -static uint32_t channelsAuthenPolicy(); - - // Handle Processing. - void request_AllSubscribedGroups(); - void request_SpecificSubscribedGroups(const std::list &groups); - void load_SubscribedGroups(const uint32_t &token); - - void request_SpecificUnprocessedPosts(std::list > &ids); - void request_GroupUnprocessedPosts(const std::list &grouplist); - void load_unprocessedPosts(uint32_t token); - - void handleUnprocessedPost(const RsGxsChannelPost &msg); - - // Local Cache of Subscribed Groups. and AutoDownload Flag. - void updateSubscribedGroup(const RsGroupMetaData &group); - void clearUnsubscribedGroup(const RsGxsGroupId &id); - bool setAutoDownload(const RsGxsGroupId &groupId, bool enabled); - bool autoDownloadEnabled(const RsGxsGroupId &groupId, bool &enabled); - bool checkForOldAndUnusedChannels(); - -// DUMMY DATA, -virtual bool generateDummyData(); - -std::string genRandomId(); - -void dummy_tick(); - -bool generatePost(uint32_t &token, const RsGxsGroupId &grpId); -bool generateComment(uint32_t &token, const RsGxsGroupId &grpId, - const RsGxsMessageId &parentId, const RsGxsMessageId &threadId); -bool generateVote(uint32_t &token, const RsGxsGroupId &grpId, - const RsGxsMessageId &parentId, const RsGxsMessageId &threadId); - -bool generateGroup(uint32_t &token, std::string groupName); - - class ChannelDummyRef - { - public: - ChannelDummyRef() {} - ChannelDummyRef( - const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, - const RsGxsMessageId &msgId ) : - mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) {} - - RsGxsGroupId mGroupId; - RsGxsMessageId mThreadId; - RsGxsMessageId mMsgId; - }; - - std::map mSubscribedGroups; - RsMutex mSubscribedGroupsMutex; - - /** G10h4ck: Is this stuff really used? And for what? BEGIN */ - uint32_t mGenToken; - bool mGenActive; - int mGenCount; - std::vector mGenRefs; - RsGxsMessageId mGenThreadId; - /** G10h4ck: Is this stuff really used? And for what? END */ - - p3GxsCommentService* mCommentService; - - std::map mKnownChannels; - RsMutex mKnownChannelsMutex; - - rstime_t mLastDistantSearchNotificationTS; - - std::map > mSearchResultsToNotify; -#ifdef TO_REMOVE - /** Store search callbacks with timeout*/ - std::map< - TurtleRequestId, - std::pair< - std::function, - std::chrono::system_clock::time_point > - > mSearchCallbacksMap; - RsMutex mSearchCallbacksMapMutex; - - /** Store distant channels requests callbacks with timeout*/ - std::map< - TurtleRequestId, - std::pair< - std::function, - std::chrono::system_clock::time_point > - > mDistantChannelsCallbacksMap; - RsMutex mDistantChannelsCallbacksMapMutex; - - /// Cleanup mSearchCallbacksMap and mDistantChannelsCallbacksMap - void cleanTimedOutCallbacks(); -#endif -}; diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc deleted file mode 100644 index b1a3bc5e2..000000000 --- a/libretroshare/src/services/p3gxscircles.cc +++ /dev/null @@ -1,2759 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxscircles.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/rsgxscircleitems.h" - -#include "services/p3gxscircles.h" -#include "retroshare/rsgxsflags.h" -#include "util/rsrandom.h" -#include "util/rsdir.h" -#include "util/radix64.h" -#include "util/rsstring.h" -#include "util/rsdebug.h" -#include "pgp/pgpauxutils.h" -#include "retroshare/rsgxscircles.h" -#include "retroshare/rspeers.h" -#include "rsserver/p3face.h" - -#include -#include - -/**** - * #define DEBUG_CIRCLES 1 - ****/ - -/*extern*/ RsGxsCircles* rsGxsCircles = nullptr; - -/*static*/ const std::string RsGxsCircles::DEFAULT_CIRCLE_BASE_URL = - "retroshare:///circles"; -/*static*/ const std::string RsGxsCircles::CIRCLE_URL_NAME_FIELD = "circleName"; -/*static*/ const std::string RsGxsCircles::CIRCLE_URL_ID_FIELD = "circleId"; -/*static*/ const std::string RsGxsCircles::CIRCLE_URL_DATA_FIELD = "circleData"; - -static const uint32_t CIRCLES_UNUSED_BY_FRIENDS_DELAY = 60*86400 ; // 60 days ...O... - -RsGxsCircles::~RsGxsCircles() = default; -RsGxsCircleMsg::~RsGxsCircleMsg() = default; -RsGxsCircleDetails::~RsGxsCircleDetails() = default; -RsGxsCircleGroup::~RsGxsCircleGroup() = default; -RsGxsCircleEvent::~RsGxsCircleEvent() = default; - -/****** - * - * GxsCircles are used to limit the spread of Gxs Groups and Messages. - * - * This is done via GxsCircle parameters in GroupMetaData: - * mCircleType (ALL, External, Internal). - * mCircleId. - * - * The Circle Group contains the definition of who is allowed access to the Group. - * and GXS asks this service before forwarding any data. - * - * The CircleGroup contains: - * list of invited GxsId's - * list of GxsCircleId's (subcircles also allowed). - * - * This service runs a background task to transform the CircleGroups - * into a list of friends/peers who are allowed access. - * These results are cached to provide GXS with quick access to the information. - * This involves: - * - fetching the GroupData via GXS. - * - querying the list of GxsId to see if they are known (NB: this will cause caching of GxsId in p3IdService. - * - recursively loading subcircles to complete Circle definition. - * - saving the result into Cache. - * - * For Phase 1, we will only use the list of GxsIds. No subcircles will be allowed. - * Recursively determining membership via sub-circles is complex and needs more thought. - * The data-types for the full system, however, will be in-place. - * - * Circle Membership - * - Actual members of the circle are computed by intersecting the set of invited IDs with the set of IDs actually requesting membership. - * - To be a member, one therefore has to publish a membership message. To leave the circle, a new message is published accordingly. - * - * Circle Subscription system - * - Circles are subscribed only when we need to dispatch information about our own membership, or when we are admin of the circle. - * - Circle (group) membership is decided automatically. Not to be mixed up with whether or not to be a member of the circle, which is GUI based. - * - * Handling of old/dead circles - * - auto-subscription based on own membership requests should limit the spread of unwanted circles (such as when one adds all visible IDs into - * the invited list of a new circle. Such a circle would not be visible beyond friend nodes of the node creating that circle. - * - * - since this feature is new (in 0.6.6), there is already a bunch of unwanted circles. How we can get rid of them is not entirely clear. - * Indeed, once a node requests membership (and even later on denies it), it will have to remain subscribed to the circle group in order - * to ensure that this unsubscribe request keeps spreading from its actual source. A some point however, the circle msgs disappear, and - * therefore the circle will switch to unsubscribe automatically. - */ - -#define CIRCLEREQ_CACHELOAD 0x0001 -#define CIRCLEREQ_CIRCLE_LIST 0x0002 -#define CIRCLEREQ_MESSAGE_DATA 0x0003 - -//#define CIRCLEREQ_PGPHASH 0x0010 -//#define CIRCLEREQ_REPUTATION 0x0020 - -//#define CIRCLEREQ_CACHETEST 0x1000 - -// Events. -#define CIRCLE_EVENT_LOADIDS 0x0001 -#define CIRCLE_EVENT_CACHELOAD 0x0002 -#define CIRCLE_EVENT_RELOADIDS 0x0003 -#define CIRCLE_EVENT_DUMMYSTART 0x0004 -#define CIRCLE_EVENT_DUMMYLOAD 0x0005 -#define CIRCLE_EVENT_DUMMYGEN 0x0006 - -#define CIRCLE_DUMMY_STARTPERIOD 300 // MUST BE LONG ENOUGH FOR IDS TO HAVE BEEN MADE. -#define CIRCLE_DUMMY_GENPERIOD 10 - -//#define CIRCLE_EVENT_CACHETEST 0x1000 -//#define CACHETEST_PERIOD 60 -//#define OWNID_RELOAD_DELAY 10 - -#define GXSID_LOAD_CYCLE 10 // GXSID completes a load in this period. - -#define MIN_CIRCLE_LOAD_GAP 5 -#define GXS_CIRCLE_DELAY_TO_FORCE_MEMBERSHIP_UPDATE 60 // re-check every 1 mins. Normally this shouldn't be necessary since notifications inform abotu new messages. -#define GXS_CIRCLE_DELAY_TO_CHECK_MEMBERSHIP_UPDATE 60 // re-check every 1 mins. Normally this shouldn't be necessary since notifications inform abotu new messages. -#define GXS_CIRCLE_DELAY_TO_SEND_CACHE_UPDATED_EVENT 2 // do not send cache update events more often than every 2 secs. - -//====================================================================================// -// Startup // -//====================================================================================// - -p3GxsCircles::p3GxsCircles( RsGeneralDataService *gds, RsNetworkExchangeService *nes, p3IdService *identities, PgpAuxUtils *pgpUtils) - : RsGxsCircleExchange( gds, nes, new RsGxsCircleSerialiser(), RS_SERVICE_GXS_TYPE_GXSCIRCLE, identities, circleAuthenPolicy() ), - RsGxsCircles(static_cast(*this)), GxsTokenQueue(this), - RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils), - mCircleMtx("p3GxsCircles"), - mKnownCirclesMtx("p3GxsCircles"), -// mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ), - mShouldSendCacheUpdateNotification(false) -{ - // Kick off Cache Testing, + Others. - //RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD); - mLastCacheMembershipUpdateTS = 0 ; - mLastCacheUpdateEvent = 0; - mLastDebugPrintTS = 0; - - RsTickEvent::schedule_now(CIRCLE_EVENT_CACHELOAD); - - mDummyIdToken = 0; -} - -static bool allowedGxsIdFlagTest(uint32_t subscription_flags,bool group_is_self_restricted) -{ - if(group_is_self_restricted) - return (subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) && (subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE); - else - return (subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) && (subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) && (subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE); -} - -const std::string GXS_CIRCLES_APP_NAME = "gxscircle"; -const uint16_t GXS_CIRCLES_APP_MAJOR_VERSION = 1; -const uint16_t GXS_CIRCLES_APP_MINOR_VERSION = 0; -const uint16_t GXS_CIRCLES_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_CIRCLES_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3GxsCircles::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_GXSCIRCLE, - GXS_CIRCLES_APP_NAME, - GXS_CIRCLES_APP_MAJOR_VERSION, - GXS_CIRCLES_APP_MINOR_VERSION, - GXS_CIRCLES_MIN_MAJOR_VERSION, - GXS_CIRCLES_MIN_MINOR_VERSION); -} - -//====================================================================================// -// Synchroneous API from rsGxsCircles // -//====================================================================================// - -bool p3GxsCircles::createCircle( - const std::string& circleName, RsGxsCircleType circleType, - RsGxsCircleId& circleId, const RsGxsCircleId& restrictedId, - const RsGxsId& authorId, const std::set& gxsIdMembers, - const std::set& localMembers ) -{ - // 1 - Check consistency of the request data - - if(circleName.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " Circle name is empty" << std::endl; - return false; - } - - switch(circleType) - { - case RsGxsCircleType::PUBLIC: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::PUBLIC" - << std::endl; - return false; - } - break; - case RsGxsCircleType::EXTERNAL: - if(restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId can't be null " - << "with RsGxsCircleType::EXTERNAL" << std::endl; - return false; - } - break; - case RsGxsCircleType::NODES_GROUP: - if(localMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " localMembers can't be empty " - << "with RsGxsCircleType::NODES_GROUP" << std::endl; - return false; - } - break; - case RsGxsCircleType::LOCAL: - break; - case RsGxsCircleType::EXT_SELF: - if(!restrictedId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " restrictedId: " << restrictedId - << " must be null with RsGxsCircleType::EXT_SELF" - << std::endl; - return false; - } - if(gxsIdMembers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " gxsIdMembers can't be empty " - << "with RsGxsCircleType::EXT_SELF" << std::endl; - return false; - } - break; - case RsGxsCircleType::YOUR_EYES_ONLY: - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Invalid circle type: " - << static_cast(circleType) << std::endl; - return false; - } - - // 2 - Create the actual request - - RsGxsCircleGroup cData; - cData.mMeta.mGroupName = circleName; - cData.mMeta.mAuthorId = authorId; - cData.mMeta.mCircleType = static_cast(circleType); - cData.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - cData.mMeta.mCircleId = restrictedId; - cData.mLocalFriends = localMembers; - cData.mInvitedMembers = gxsIdMembers; - - // 3 - Send it and wait, for a sync response. - - uint32_t token; - createGroup(token, cData); - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting created" << " group data." << std::endl; - return false; - } - - circleId = static_cast(cData.mMeta.mGroupId); - return true; -}; - -bool p3GxsCircles::editCircle(RsGxsCircleGroup& cData) -{ - uint32_t token; - updateGroup(token, cData); - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, cData.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated" - << " group data." << std::endl; - return false; - } - - return true; -} - -bool p3GxsCircles::getCirclesSummaries(std::list& circles) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - { - std::cerr << "Cannot get circles summary. Token queue is overloaded?" << std::endl; - return false; - } - else - return getGroupSummary(token, circles); -} - -bool p3GxsCircles::getCirclesInfo( const std::list& circlesIds, - std::vector& circlesInfo ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - if( !requestGroupInfo(token, opts, circlesIds) || waitToken(token) != RsTokenService::COMPLETE ) - { - std::cerr << "Cannot get circle info. Token queue is overloaded?" << std::endl; - return false; - } - else - return getGroupData(token, circlesInfo); -} - -bool p3GxsCircles::getCircleRequests( const RsGxsGroupId& circleId, - std::vector& requests ) -{ - uint32_t token; - std::list grpIds { circleId }; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - if( !requestMsgInfo(token, opts, grpIds) || - waitToken(token) != RsTokenService::COMPLETE ) return false; - - return getMsgData(token, requests); -} - -bool p3GxsCircles::getCircleRequest(const RsGxsGroupId& circleId,const RsGxsMessageId& msgId,RsGxsCircleMsg& msg) -{ - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - std::set contentsIds; - contentsIds.insert(msgId); - - GxsMsgReq msgIds; - msgIds[circleId] = contentsIds; - - uint32_t token; - if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - - std::vector msgs; - - if(getMsgData(token, msgs) && msgs.size() == 1) - { - msg = msgs.front(); - return true; - } - else - return false; -} - -bool p3GxsCircles::inviteIdsToCircle( const std::set& identities, - const RsGxsCircleId& circleId ) -{ - const std::list circlesIds{ RsGxsGroupId(circleId) }; - std::vector circlesInfo; - - if(!getCirclesInfo(circlesIds, circlesInfo)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting group data." - << std::endl; - return false; - } - - if(circlesInfo.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Circle: " - << circleId.toStdString() << " not found!" << std::endl; - return false; - } - - RsGxsCircleGroup& circleGrp = circlesInfo[0]; - - if(!(circleGrp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Attempt to edit non-own " - << "circle: " << circleId.toStdString() << std::endl; - return false; - } - - circleGrp.mInvitedMembers.insert(identities.begin(), identities.end()); - - return editCircle(circleGrp); -} - -bool p3GxsCircles::revokeIdsFromCircle( const std::set& identities, const RsGxsCircleId& circleId ) -{ - const std::list circlesIds{ RsGxsGroupId(circleId) }; - std::vector circlesInfo; - - if(!getCirclesInfo(circlesIds, circlesInfo)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting group data." << std::endl; - return false; - } - - if(circlesInfo.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Circle: " << circleId.toStdString() << " not found!" << std::endl; - return false; - } - - RsGxsCircleGroup& circleGrp = circlesInfo[0]; - - if(!(circleGrp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Attempt to edit non-own " << "circle: " << circleId.toStdString() << std::endl; - return false; - } - - // /!\ AVOID calling circleGrp.mInvitedMembers.erase(identities.begin(),identities.end()), because it is not the same set. Consequently - // STL code would corrupt the structure of mInvitedMembers. - - std::set new_invited_members; - for(auto& gxs_id: circleGrp.mInvitedMembers) - if(identities.find(gxs_id) == identities.end()) - new_invited_members.insert(gxs_id); - - circleGrp.mInvitedMembers = new_invited_members; - - return editCircle(circleGrp); -} - -bool p3GxsCircles::exportCircleLink( - std::string& link, const RsGxsCircleId& circleId, - bool includeGxsData, const std::string& baseUrl, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(circleId.isNull()) return failure("circleId cannot be null"); - - const bool outputRadix = baseUrl.empty(); - if(outputRadix && !includeGxsData) return - failure("includeGxsData must be true if format requested is base64"); - - RsGxsGroupId&& groupId = static_cast(circleId); - if( includeGxsData && - !RsGenExchange::exportGroupBase64(link, groupId, errMsg) ) - return failure(errMsg); - - if(outputRadix) return true; - - std::vector circlesInfo; - if( !getCirclesInfo( - std::list({groupId}), circlesInfo ) - || circlesInfo.empty() ) - return failure("failure retrieving circle information"); - - RsUrl inviteUrl(baseUrl); - inviteUrl.setQueryKV(CIRCLE_URL_ID_FIELD, circleId.toStdString()); - inviteUrl.setQueryKV(CIRCLE_URL_NAME_FIELD, circlesInfo[0].mMeta.mGroupName); - if(includeGxsData) inviteUrl.setQueryKV(CIRCLE_URL_DATA_FIELD, link); - - link = inviteUrl.toString(); - return true; -} - -bool p3GxsCircles::importCircleLink( - const std::string& link, RsGxsCircleId& circleId, - std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(link.empty()) return failure("link is empty"); - - const std::string* radixPtr(&link); - - RsUrl url(link); - const auto& query = url.query(); - const auto qIt = query.find(CIRCLE_URL_DATA_FIELD); - if(qIt != query.end()) radixPtr = &qIt->second; - - if(radixPtr->empty()) return failure(CIRCLE_URL_DATA_FIELD + " is empty"); - - if(!RsGenExchange::importGroupBase64( - *radixPtr, reinterpret_cast(circleId), errMsg) ) - return failure(errMsg); - - return true; -} - -uint32_t p3GxsCircles::circleAuthenPolicy() -{ - uint32_t policy = 0; - uint8_t flag = 0; - - flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -//====================================================================================// -// Tick // -//====================================================================================// - -void p3GxsCircles::service_tick() -{ - RsTickEvent::tick_events(); - GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests. - - rstime_t now = time(NULL); - - if(mShouldSendCacheUpdateNotification && now > mLastCacheUpdateEvent + GXS_CIRCLE_DELAY_TO_SEND_CACHE_UPDATED_EVENT) - { - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mCircleEventType = RsGxsCircleEventCode::CACHE_DATA_UPDATED; - rsEvents->postEvent(ev); - } - - mLastCacheUpdateEvent = now; - mShouldSendCacheUpdateNotification = false; - } - - if(now > mLastCacheMembershipUpdateTS + GXS_CIRCLE_DELAY_TO_CHECK_MEMBERSHIP_UPDATE) - { - checkCircleCache(); - mLastCacheMembershipUpdateTS = now ; - } - -#ifdef DEBUG_CIRCLES - if(now > mLastDebugPrintTS) - { - mLastDebugPrintTS = now; - debug_dumpCache(); - } -#endif -} - -//====================================================================================// -// Handling of GXS changes // -//====================================================================================// - -void p3GxsCircles::notifyChanges(std::vector &changes) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::notifyChanges()"; - std::cerr << std::endl; -#endif - - //p3Notify *notify = RsServer::notify(); - std::set circles_to_reload; - - for(auto it = changes.begin(); it != changes.end(); ++it) - { - RsGxsNotify *c = *it; - RsGxsMsgChange *msgChange = dynamic_cast(c); - - if (msgChange) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Found circle Message Change Notification for group " << msgChange->mGroupId << ", msg ID " << msgChange->mMsgId << std::endl; - std::cerr << " Msgs for Group: " << msgChange->mGroupId << std::endl; -#endif - RsGxsCircleId circle_id(msgChange->mGroupId); - - if(rsEvents && ((c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) || (c->getType() == RsGxsNotify::TYPE_PUBLISHED))) - { - const RsGxsCircleSubscriptionRequestItem *item = dynamic_cast(msgChange->mNewMsgItem); - - if(item) - { - auto ev = std::make_shared(); - ev->mCircleId = circle_id; - ev->mGxsId = msgChange->mNewMsgItem->meta.mAuthorId; - - if (item->subscription_type == RsGxsCircleSubscriptionType::UNSUBSCRIBE) - { - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE; - rsEvents->postEvent(ev); - } - else if(item->subscription_type == RsGxsCircleSubscriptionType::SUBSCRIBE) - { - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST; - rsEvents->postEvent(ev); - } - else - RsErr() << __PRETTY_FUNCTION__ << " Unknown subscription request type " << static_cast(item->subscription_type) << " in msg item" << std::endl; - } - else - RsErr() << __PRETTY_FUNCTION__ << ": missing SubscriptionRequestItem in msg notification for msg " << msgChange->mMsgId << std::endl; - } - - circles_to_reload.insert(circle_id); - } - - RsGxsGroupChange *groupChange = dynamic_cast(c); - - /* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */ - if (groupChange) - { - const RsGxsGroupId *git(&groupChange->mGroupId); - -#ifdef DEBUG_CIRCLES - std::cerr << " Found Group Change Notification of type " << c->getType() << std::endl; -#endif - switch(c->getType()) - { - case RsGxsNotify::TYPE_RECEIVED_NEW: - case RsGxsNotify::TYPE_UPDATED: - case RsGxsNotify::TYPE_PUBLISHED: - { -#ifdef DEBUG_CIRCLES - std::cerr << " Incoming/created/updated Group: " << *git << ". Forcing cache load." << std::endl; -#endif - - // for new circles we need to add them to the list. - // we don't know the type of this circle here - // original behavior was to add all ids to the external ids list - circles_to_reload.insert(RsGxsCircleId(*git)); - - } // fallthrough - case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - RS_STACK_MUTEX(mKnownCirclesMtx); - mKnownCircles[*git] = time(nullptr); - IndicateConfigChanged(); - } - break; - default: -#ifdef DEBUG_CIRCLES - std::cerr << " Type: " << c->getType() << " is ignored" << std::endl; -#endif - break; - } - - // Now compute which events should be sent. - - if(rsEvents) - { - if(c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) - { - auto ev = std::make_shared(); - ev->mCircleId = RsGxsCircleId(*git); - ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE; - - rsEvents->postEvent(ev); - - // we also need to look into invitee list here! - - RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast(groupChange->mNewGroupItem); - - if(new_circle_grp_item) // groups published by us do not come in the mNewGroupItem field. It's possible to add them, in rsgenexchange.cc:2806 - for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST; - ev->mCircleId = RsGxsCircleId(*git); - ev->mGxsId = gxs_id; - - rsEvents->postEvent(ev); - } - } - else if(c->getType()==RsGxsNotify::TYPE_UPDATED) - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - RsGxsCircleGroupItem *old_circle_grp_item = dynamic_cast(groupChange->mOldGroupItem); - RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast(groupChange->mNewGroupItem); - - if(old_circle_grp_item == nullptr || new_circle_grp_item == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsCircleGroupItem. This is inconsistent!" << std::endl; - delete groupChange; - continue; - } - - const RsGxsCircleId circle_id ( old_circle_grp_item->meta.mGroupId ); - - // First of all, we check if there is a difference between the old and new list of invited members - - for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids) - if(old_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end()) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST; - ev->mCircleId = circle_id; - ev->mGxsId = gxs_id; - - rsEvents->postEvent(ev); - } - - for(auto& gxs_id: old_circle_grp_item->gxsIdSet.ids) - if(new_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end()) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST; - ev->mCircleId = circle_id; - ev->mGxsId = gxs_id; - - rsEvents->postEvent(ev); - } - - if( old_circle_grp_item->meta.mGroupName != new_circle_grp_item->meta.mGroupName - || old_circle_grp_item->meta.mGroupFlags != new_circle_grp_item->meta.mGroupFlags - || old_circle_grp_item->meta.mAuthorId != new_circle_grp_item->meta.mAuthorId - || old_circle_grp_item->meta.mCircleId != new_circle_grp_item->meta.mCircleId - ) - { - auto ev = std::make_shared(); - ev->mCircleId = RsGxsCircleId(new_circle_grp_item->meta.mGroupId); - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_UPDATED; - rsEvents->postEvent(ev); - } - } - else if(c->getType()==RsGxsNotify::TYPE_GROUP_DELETED) - { - auto ev = std::make_shared(); - - ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_DELETED; - ev->mCircleId = RsGxsCircleId(groupChange->mGroupId); - - rsEvents->postEvent(ev); - } - } - } - - delete c; - } - - for(auto& circle_id:circles_to_reload) - force_cache_reload(circle_id); -} - -//====================================================================================// -// Synchroneous API using cache storage // -//====================================================================================// - -bool p3GxsCircles::getCircleDetails(const RsGxsCircleId& id, RsGxsCircleDetails& details) -{ - -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::getCircleDetails(" << id << ")"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - { - bool should_reload = false; - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - RsGxsCircleCache& data(mCircleCache[id]); - - if(data.mStatus < CircleEntryCacheStatus::LOADING) - should_reload = true; - - if(data.mStatus == CircleEntryCacheStatus::LOADING) - return false; - - // should also have meta data.... - - if(!should_reload) - { - details.mCircleId = id; - details.mCircleName = data.mCircleName; - - details.mCircleType = data.mCircleType; - details.mRestrictedCircleId = data.mRestrictedCircleId; - - details.mAllowedNodes = data.mAllowedNodes; - details.mSubscriptionFlags.clear(); - details.mAllowedGxsIds.clear(); - details.mAmIAllowed = false ; - details.mAmIAdmin = bool(data.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); - - for(std::map::const_iterator it(data.mMembershipStatus.begin());it!=data.mMembershipStatus.end();++it) - { - details.mSubscriptionFlags[it->first] = it->second.subscription_flags ; - - if(it->second.subscription_flags == GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED) - { - details.mAllowedGxsIds.insert(it->first) ; - - if(rsIdentity->isOwnId(it->first)) - details.mAmIAllowed = true ; - } - } - - return true; - } - } - - cache_request_load(id); - return false; -} - -bool p3GxsCircles::getCircleExternalIdList(std::set &circleIds) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::getCircleIdList()"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - for(auto& cache: mCircleCache) - if(cache.second.mIsExternal) - circleIds.insert(cache.first); - - return true; -} - -bool p3GxsCircles::isLoaded(const RsGxsCircleId &circleId) -{ - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - return mCircleCache.is_cached(circleId) && (mCircleCache[circleId].mStatus >= CircleEntryCacheStatus::UPDATING); -} - -bool p3GxsCircles::loadCircle(const RsGxsCircleId &circleId) -{ - return cache_request_load(circleId); -} - -int p3GxsCircles::canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool& should_encrypt) -{ - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - if (mCircleCache.is_cached(circleId)) - { - RsGxsCircleCache& data = mCircleCache.ref(circleId); - - if(data.mStatus < CircleEntryCacheStatus::UPDATING) - return 0; - - should_encrypt = (data.mCircleType == RsGxsCircleType::EXTERNAL); - - if (data.isAllowedPeer(id)) - return 1; - - return 0; - } - return -1; -} - -int p3GxsCircles::canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) -{ - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - if (mCircleCache.is_cached(circleId)) - { - RsGxsCircleCache &data = mCircleCache.ref(circleId); - - if(data.mStatus < CircleEntryCacheStatus::UPDATING) - return 0; - - if (data.isAllowedPeer(id)) - { - return 1; - } - return 0; - } - return -1; -} - -bool p3GxsCircles::recipients(const RsGxsCircleId &circleId, std::list& friendlist) -{ - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - if (mCircleCache.is_cached(circleId)) - { - RsGxsCircleCache &data = mCircleCache.ref(circleId); - - if(data.mStatus < CircleEntryCacheStatus::UPDATING) - return 0; - - data.getAllowedPeersList(friendlist); - return true; - } - return false; -} - -bool p3GxsCircles::isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) -{ - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - if (mCircleCache.is_cached(circleId)) - { - const RsGxsCircleCache &data = mCircleCache.ref(circleId); - - if(data.mStatus < CircleEntryCacheStatus::UPDATING) - return 0; - - return data.isAllowedPeer(id,destination_group); - } - return false; -} - -// This function uses the destination group for the transaction in order to decide which list of -// keys to ecnrypt to. When sending to a self-restricted group, the list of recipients is extended to -// the admin list rather than just the members list. - -bool p3GxsCircles::recipients(const RsGxsCircleId& circleId, const RsGxsGroupId& dest_group, std::list& gxs_ids) -{ - gxs_ids.clear() ; - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - if (!mCircleCache.is_cached(circleId)) - return false ; - - const RsGxsCircleCache& cache = mCircleCache.ref(circleId); - - if(cache.mStatus < CircleEntryCacheStatus::UPDATING) - return 0; - - for(std::map::const_iterator it(cache.mMembershipStatus.begin());it!=cache.mMembershipStatus.end();++it) - if(allowedGxsIdFlagTest(it->second.subscription_flags, RsGxsCircleId(dest_group) == circleId)) - gxs_ids.push_back(it->first) ; - - return true; -} - -//====================================================================================// -// Asynchroneous API using token system // -//====================================================================================// - - -bool p3GxsCircles::getGroupData(const uint32_t &token, std::vector &groups) -{ - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsCircleGroupItem* item = dynamic_cast(*vit); - if (item) - { - RsGxsCircleGroup group; - item->convertTo(group); - - // If its cached - add that info (TODO). - groups.push_back(group); - delete(item); - } - else - { - std::cerr << "p3GxsCircles::getGroupData()"; - std::cerr << " Not a RsGxsCircleGroupItem, deleting!"; - std::cerr << std::endl; - delete *vit; - } - } - } - - return ok; -} - -bool p3GxsCircles::getMsgData(const uint32_t &token, std::vector &msgs) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsCircleSubscriptionRequestItem* rsItem = dynamic_cast(*vit); - - if (rsItem) - { - RsGxsCircleMsg msg ;//= rsItem->mMsg; - msg.mMeta = rsItem->meta; - msg.mSubscriptionType = rsItem->subscription_type; - - msgs.push_back(msg); - delete rsItem; - } - else - { - std::cerr << "Not a GxsCircleMsgItem, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - -void p3GxsCircles::createGroup(uint32_t& token, RsGxsCircleGroup &group) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::createGroup()"; - std::cerr << " CircleType: " << (uint32_t) group.mMeta.mCircleType; - std::cerr << " CircleId: " << group.mMeta.mCircleId.toStdString(); - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - RsGxsCircleGroupItem* item = new RsGxsCircleGroupItem(); - item->convertFrom(group); - - RsGenExchange::publishGroup(token, item); -} - -void p3GxsCircles::updateGroup(uint32_t &token, RsGxsCircleGroup &group) -{ - // note: refresh of circle cache gets triggered in the RsGenExchange::notifyChanges() callback - RsGxsCircleGroupItem* item = new RsGxsCircleGroupItem(); - item->convertFrom(group); - - RsGenExchange::updateGroup(token, item); -} - -RsGenExchange::ServiceCreate_Return p3GxsCircles::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& /*keySet*/) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::service_CreateGroup()"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - RsGxsCircleGroupItem *item = dynamic_cast(grpItem); - if (!item) - { - std::cerr << "p3GxsCircles::service_CreateGroup() ERROR invalid cast"; - std::cerr << std::endl; - return SERVICE_CREATE_FAIL; - } - - // Now copy the GroupId into the mCircleId, and set the mode. - if (item->meta.mCircleType == GXS_CIRCLE_TYPE_EXT_SELF) - { - item->meta.mCircleType = GXS_CIRCLE_TYPE_EXTERNAL; - item->meta.mCircleId = RsGxsCircleId(item->meta.mGroupId); - } - - return SERVICE_CREATE_SUCCESS; -} - -//====================================================================================// -// Cache system management // -//====================================================================================// - -RsGxsCircleCache::RsGxsCircleCache() -{ - mCircleType = RsGxsCircleType::EXTERNAL; - mIsExternal = true; - mLastUpdateTime = 0; - mGroupStatus = 0; - mGroupSubscribeFlags = 0; - mLastUpdatedMembershipTS = 0 ; - mStatus = CircleEntryCacheStatus::NO_DATA_YET; - mAllIdsHere = false; - mDoIAuthorAMembershipMsg = false; - - return; -} - -bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup& circle) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "RsGxsCircleCache::loadBaseCircle(" << mCircleId << "):" << std::endl; -#endif // DEBUG_CIRCLES - - mCircleId = RsGxsCircleId(circle.mMeta.mGroupId); - mCircleName = circle.mMeta.mGroupName; - // mProcessedCircles.insert(mCircleId); - - mCircleType = static_cast(circle.mMeta.mCircleType); - mIsExternal = (mCircleType != RsGxsCircleType::LOCAL); - mGroupStatus = circle.mMeta.mGroupStatus; - mGroupSubscribeFlags = circle.mMeta.mSubscribeFlags; - mOriginator = circle.mMeta.mOriginator ; - - mAllowedNodes = circle.mLocalFriends ; - mRestrictedCircleId = circle.mMeta.mCircleId ; - - // We do not clear mMembershipStatus because this might be an update and if we do, it will clear membership requests - // that are not in the invited list! - - for(std::set::const_iterator it(circle.mInvitedMembers.begin());it!=circle.mInvitedMembers.end();++it) - { - RsGxsCircleMembershipStatus& s(mMembershipStatus[*it]) ; - s.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ; - - // This one can be cleared because it will anyway be updated to the latest when loading subscription request messages and it wil only - // be used there as well. - - s.last_subscription_TS = 0 ; - -#ifdef DEBUG_CIRCLES - std::cerr << " Invited member " << *it << " Initializing/updating membership status to " << std::hex << s.subscription_flags << std::dec << std::endl; -#endif // DEBUG_CIRCLES - } - - // also sweep through the list of subscribed members and remove the membership to those who are not in the invitee list anymore - - for(auto& m:mMembershipStatus) - if(circle.mInvitedMembers.find(m.first) == circle.mInvitedMembers.end()) - { - m.second.subscription_flags &= ~GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST; -#ifdef DEBUG_CIRCLES - std::cerr << " member " << m.first << " is not in invitee list. Updating flags to " << std::hex << m.second.subscription_flags << std::dec << std::endl; -#endif // DEBUG_CIRCLES - } - - return true; -} - -bool RsGxsCircleCache::loadSubCircle(const RsGxsCircleCache &subcircle) -{ - /* copy across all the lists */ - - /* should not be any unprocessed circles or peers */ -#ifdef DEBUG_CIRCLES -#endif // DEBUG_CIRCLES - - std::cerr << "RsGxsCircleCache::loadSubCircle(" << subcircle.mCircleId << ") TODO"; - std::cerr << std::endl; - - return true; -} - -bool RsGxsCircleCache::getAllowedPeersList(std::list& friendlist) const -{ - friendlist.clear() ; - - for(auto it = mAllowedNodes.begin(); it != mAllowedNodes.end(); ++it) - friendlist.push_back(*it) ; - - return true; -} - -bool RsGxsCircleCache::isAllowedPeer(const RsGxsId& id,const RsGxsGroupId& destination_group) const -{ - auto it = mMembershipStatus.find(id) ; - - if(it == mMembershipStatus.end()) - return false ; - - return allowedGxsIdFlagTest(it->second.subscription_flags, RsGxsGroupId(mCircleId) == destination_group) ; -} - -bool RsGxsCircleCache::isAllowedPeer(const RsPgpId &id) const -{ - return mAllowedNodes.find(id) != mAllowedNodes.end() ; -} - -bool RsGxsCircleCache::addLocalFriend(const RsPgpId &pgpId) -{ - /* empty list as no GxsID associated */ - mAllowedNodes.insert(pgpId) ; - return true; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -// Complicated deal of loading Circles. - -bool p3GxsCircles::force_cache_reload(const RsGxsCircleId& id) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::force_cache_reload(): Forcing cache reload of Circle ID " << id << std::endl; -#endif - - cache_request_load(id) ; - return true ; -} - -bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_request_load(" << id << ")"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - /* check it is not already being loaded */ - - RsGxsCircleCache& cache(mCircleCache[id]); - - if(cache.mStatus < CircleEntryCacheStatus::LOADING) - cache.mCircleId = id; - - if(cache.mStatus == CircleEntryCacheStatus::LOADING || cache.mStatus == CircleEntryCacheStatus::UPDATING) - return false; - - // Put it into the Loading Cache - so we will detect it later. - - if(cache.mLastUpdateTime > 0) - cache.mStatus = CircleEntryCacheStatus::UPDATING; - else - cache.mStatus = CircleEntryCacheStatus::LOADING; - - mCirclesToLoad.insert(id); - } - - if (RsTickEvent::event_count(CIRCLE_EVENT_CACHELOAD) > 0) /* its already scheduled */ - return true; - - int32_t age = 0; - if (RsTickEvent::prev_event_ago(CIRCLE_EVENT_CACHELOAD, age) && age groupIds; - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ - - for(auto& circle_id:mCirclesToLoad) - { -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_start_load() GroupId: " << circle_id << std::endl; -#endif // DEBUG_CIRCLES - - groupIds.push_back(RsGxsGroupId(circle_id.toStdString())); // might need conversion? - } - - mCirclesToLoad.clear(); - } - - if (groupIds.size() > 0) - { -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_start_load() #Groups: " << groupIds.size(); - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); - GxsTokenQueue::queueRequest(token, CIRCLEREQ_CACHELOAD); - } - return true; -} - - -bool p3GxsCircles::cache_load_for_token(uint32_t token) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_load_for_token() : " << token << std::endl; -#endif // DEBUG_CIRCLES - - std::vector grpData; - - if(!RsGenExchange::getGroupData(token, grpData)) - { - std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; - } - - for(auto vit = grpData.begin(); vit != grpData.end(); ++vit) - { - RsGxsCircleGroupItem *item = dynamic_cast(*vit); - - if (!item) - { - std::cerr << " Not a RsGxsCircleGroupItem Item, deleting!" << std::endl; - delete(*vit); - continue; - } - RsGxsCircleGroup group; - item->convertTo(group); - -#ifdef DEBUG_CIRCLES - std::cerr << " Loaded Id with Meta: " << item->meta << std::endl; -#endif // DEBUG_CIRCLES - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - /* should already have a LoadingCache entry */ - RsGxsCircleId id = RsGxsCircleId(item->meta.mGroupId) ; - RsGxsCircleCache& cache(mCircleCache[id]); - - cache.loadBaseCircle(group); - delete item; - - if(locked_processLoadingCacheEntry(cache)) - { -#ifdef DEBUG_CIRCLES - std::cerr << " All peers available. Moving to cache..." << std::endl; -#endif - cache.mAllIdsHere = true; - - // We can check for self inclusion in the circle right away, since own ids are always loaded. - // that allows to subscribe/unsubscribe uncomplete circles - - cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP; - cache.mLastUpdatedMembershipTS = 0; // force processing of membership request - locked_checkCircleCacheForMembershipUpdate(cache); - } - else - { -#ifdef DEBUG_CIRCLES - std::cerr << " Unprocessed peers. Requesting reload..." << std::endl; -#endif - cache.mAllIdsHere = false; - cache.mStatus = CircleEntryCacheStatus::UPDATING; - - /* schedule event to try reload gxsIds */ - RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, id.toStdString()); - } - mShouldSendCacheUpdateNotification = true; - } - - return true; -} - -// This method parses the cache entry and makes sure that all ids are known. If not, requests the missing ids -// when done, the entry is removed from mLoadingCache - -bool p3GxsCircles::locked_processLoadingCacheEntry(RsGxsCircleCache& cache) -{ - //bool isUnprocessedPeers = false; - - if (!cache.mIsExternal) - return true; - -#ifdef DEBUG_CIRCLES - std::cerr << "Processing External Circle " << cache.mCircleId << std::endl; -#endif - bool all_ids_here = true; - - // Do we actually need to retrieve the missing keys for all members of a circle??? - // These keys are needed for subscribtion request signature checking. But this is only - // when a subscription msg is posted, which would trigger retrieval of the key anyway - // Maybe this can be made an option of p3GxsCircles, or of rsIdentity. - - // need to trigger the searches. - for(std::map::iterator pit = cache.mMembershipStatus.begin(); pit != cache.mMembershipStatus.end(); ++pit) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Member status: " << pit->first << " : " << pit->second.subscription_flags; -#endif - - /* check cache */ - if(!(pit->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE)) - { - if(mIdentities->haveKey(pit->first)) - { - pit->second.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_KEY_AVAILABLE; - -#ifdef DEBUG_CIRCLES - std::cerr << " Key is now available!"<< std::endl; -#endif - } - else - { - std::list peers; - - if(!cache.mOriginator.isNull()) - { - peers.push_back(cache.mOriginator) ; -#ifdef DEBUG_CIRCLES - std::cerr << " Requesting unknown/unloaded identity: " << pit->first << " to originator " << cache.mOriginator << std::endl; -#endif - } - else - { -#ifdef DEBUG_CIRCLES - std::cerr << " (WW) cache entry for circle " << cache.mCircleId << " has empty originator. Asking info for GXS id " << pit->first << " to all connected friends." << std::endl; -#endif - - rsPeers->getOnlineList(peers) ; - } - - mIdentities->requestKey(pit->first, peers,RsIdentityUsage(RsServiceType::GXSCIRCLE,RsIdentityUsage::CIRCLE_MEMBERSHIP_CHECK,RsGxsGroupId(cache.mCircleId))); - - all_ids_here = false; - } - } -#ifdef DEBUG_CIRCLES - else - std::cerr << " Key is available. Nothing to process." << std::endl; -#endif - } - - return all_ids_here; -} - -bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::cache_reloadids()"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - RsGxsCircleCache& cache(mCircleCache[circleId]); - - /* fetch from loadMap */ - - if(locked_processLoadingCacheEntry(cache)) - { - cache.mAllIdsHere = true; - - // We can check for self inclusion in the circle right away, since own ids are always loaded. - // that allows to subscribe/unsubscribe uncomplete circles - - cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP; - locked_checkCircleCacheForMembershipUpdate(cache); - - std::cerr << " Loading complete." << std::endl; - - return true ; - } - - else - { - cache.mAllIdsHere = false; - -#ifdef DEBUG_CIRCLES - std::cerr << " Unprocessed peers. Requesting reload for circle " << circleId << std::endl; -#endif - - /* schedule event to try reload gxsIds */ - RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, circleId.toStdString()); - } - - return true; -} - -bool p3GxsCircles::checkCircleCache() -{ -#ifdef DEBUG_CIRCLES - std::cerr << "checkCircleCache(): calling auto-subscribe check and membership update check." << std::endl; -#endif - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::locked_checkCircleCacheForMembershipUpdate) ; - - return true ; -} - -bool p3GxsCircles::locked_setGroupUnprocessedStatus(RsGxsCircleCache& cache,bool unprocessed) -{ - uint32_t token2; - - if(unprocessed) - cache.mGroupStatus |= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; - else - cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; - - RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), unprocessed, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED); - - // Now we need to async acknowledge the token when the job is finished. We cannot do this sync because it's the - // current thread that takes care of calling the handling of group processing. - - RsThread::async([token2,this]() - { - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); - - auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most - auto st = requestStatus(token2); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token2); - } - - RsGxsGroupId grpId; - acknowledgeGrp(token2,grpId); - }); - return true; -} - -bool p3GxsCircles::locked_subscribeToCircle(const RsGxsCircleId &grpId, bool subscribe) -{ - uint32_t token; - if(!RsGenExchange::subscribeToGroup(token, RsGxsGroupId(grpId), subscribe)) - return false; - - // Now we need to async acknowledge the token when the job is finished. We cannot do this sync because it's the - // current thread that takes care of calling the handling of group processing. - - RsThread::async([token,this]() - { - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); - - auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most - auto st = requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - - RsGxsGroupId grpId; - acknowledgeGrp(token,grpId); - }); - - return true; -} - -bool p3GxsCircles::locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache& cache) -{ - rstime_t now = time(NULL) ; - - if(cache.mStatus < CircleEntryCacheStatus::UPDATING) - return false; - - if(cache.mLastUpdatedMembershipTS + GXS_CIRCLE_DELAY_TO_FORCE_MEMBERSHIP_UPDATE < now) - { -#ifdef DEBUG_CIRCLES - std::cerr << "Cache entry for circle " << cache.mCircleId << " needs a swab over membership requests. Re-scheduling it." << std::endl; -#endif - locked_setGroupUnprocessedStatus(cache,true); // forces the re-check of the group - - // this should be called regularly - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - std::list grpIds ; - uint32_t token2; - - grpIds.push_back(RsGxsGroupId(cache.mCircleId)) ; - - RsGenExchange::getTokenService()->requestMsgInfo(token2, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); - GxsTokenQueue::queueRequest(token2, CIRCLEREQ_MESSAGE_DATA); - } - return true ; -} - -/* We need to AutoSubscribe if the Circle is relevent to us */ - -bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache& cache) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::locked_checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl; -#endif - - /* if processed already - ignore */ - if (!(cache.mGroupStatus & GXS_SERV::GXS_GRP_STATUS_UNPROCESSED)) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Already Processed" << std::endl; -#endif - - return false; - } - - /* if personal - we created ... is subscribed already */ - if (!cache.mIsExternal) - { -#ifdef DEBUG_CIRCLES - std::cerr << " Personal Circle. Nothing to do." << std::endl; -#endif - - return false; - } - - if(cache.mStatus < CircleEntryCacheStatus::UPDATING) - return false; - - /* if we appear in the group - then autosubscribe, and mark as processed. This also applies if we're the group admin */ - - std::list myOwnIds; - - if(!rsIdentity->getOwnIds(myOwnIds)) - { - std::cerr << " own ids not loaded yet." << std::endl; - - /* schedule event to try reload gxsIds */ - RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, cache.mCircleId.toStdString()); - return false ; - } - - bool am_I_invited = false ; - - for(std::list::const_iterator it(myOwnIds.begin());it!=myOwnIds.end() && (!am_I_invited);++it) - { - std::map::const_iterator it2 = cache.mMembershipStatus.find(*it) ; - - if(it2 != cache.mMembershipStatus.end()) - am_I_invited = am_I_invited || bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ; - } - - bool am_I_admin( cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ; - bool do_I_have_a_msg( cache.mDoIAuthorAMembershipMsg ); - -#ifdef DEBUG_CIRCLES - std::cerr << " own ID invited in circle: " << am_I_invited << ", membership msg author: " << do_I_have_a_msg << ", admin: " << am_I_admin << std::endl; -#endif - if(do_I_have_a_msg || am_I_admin) - { - if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)) - { -#ifdef DEBUG_CIRCLES - /* we are part of this group - subscribe, clear unprocessed flag */ - std::cerr << " either admin or have posted a subscribe/unsubscribe message => AutoSubscribing!" << std::endl; -#endif - locked_subscribeToCircle(cache.mCircleId,true); - mShouldSendCacheUpdateNotification = true; - } -#ifdef DEBUG_CIRCLES - else - std::cerr << " either admin or have posted a subscribe/unsubscribe message, already subscribed." << std::endl; -#endif - - cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; - - return true; - } - else - { - /* we know all the peers - we are not part - we can flag as PROCESSED. */ - if(cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - { - locked_subscribeToCircle(cache.mCircleId,false); - mShouldSendCacheUpdateNotification = true; -#ifdef DEBUG_CIRCLES - std::cerr << " Neither admin nor subscription msg author! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl; -#endif - } -#ifdef DEBUG_CIRCLES - else - std::cerr << " Neither admin nor subscription msg author! Not subscribed either." << std::endl; -#endif - return true ; - } - -#ifdef DEBUG_CIRCLES - std::cerr << " Marking the cache entry as processed." << std::endl; -#endif - locked_setGroupUnprocessedStatus(cache,false); - - return true; -} - -rstime_t p3GxsCircles::service_getLastGroupSeenTs(const RsGxsGroupId& gid) -{ - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownCirclesMtx); - - auto it = mKnownCircles.find(gid); - bool unknown_posted = (it == mKnownCircles.end()); - - if(unknown_posted) - { - mKnownCircles[gid] = now; - IndicateConfigChanged(); - return now; - } - else - return it->second; -} -bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) -{ -#ifdef GXSFORUMS_CHANNELS - std::cerr << "p3gxsChannels: Checking unused circles: called by GxsCleaning." << std::endl; -#endif - - // request all group infos at once - - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownCirclesMtx); - - auto it = mKnownCircles.find(meta.mGroupId); - bool unknown_posted = (it == mKnownCircles.end()); - -#ifdef GXSFORUMS_CHANNELS - std::cerr << " Circle " << meta.mGroupId ; -#endif - - if(unknown_posted) - { - // This case should normally not happen. It does because this board was never registered since it may - // arrived before this code was here - -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Not known yet. Adding current time as new TS." << std::endl; -#endif - mKnownCircles[meta.mGroupId] = now; - IndicateConfigChanged(); - - return true; - } - else - { - bool used_by_friends = (now < it->second + CIRCLES_UNUSED_BY_FRIENDS_DELAY); - bool subscribed = static_cast(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - - std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)"; - - if(!subscribed && !used_by_friends) - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Scheduling for deletion" << std::endl; -#endif - return false; - } - else - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Keeping!" << std::endl; -#endif - return true; - } - } -} - -//====================================================================================// -// Event handling // -//====================================================================================// - - // Overloaded from GxsTokenQueue for Request callbacks. -void p3GxsCircles::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl; -#endif // DEBUG_CIRCLES - if (status != RsTokenService::COMPLETE) - return; //For now, only manage Complete request - - - // stuff. - switch(req_type) - { - case CIRCLEREQ_MESSAGE_DATA: - processMembershipRequests(token); - break; - - case CIRCLEREQ_CACHELOAD: - cache_load_for_token(token); - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Unknown Request Type: " - << req_type << std::endl; - break; - } -} - - // Overloaded from RsTickEvent for Event callbacks. -void p3GxsCircles::handle_event(uint32_t event_type, const std::string &elabel) -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::handle_event(" << event_type << ")"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - // stuff. - switch(event_type) - { - case CIRCLE_EVENT_CACHELOAD: - cache_start_load(); - break; - - case CIRCLE_EVENT_RELOADIDS: - cache_reloadids(RsGxsCircleId(elabel)); - break; - - case CIRCLE_EVENT_DUMMYSTART: - generateDummyData(); - break; - - case CIRCLE_EVENT_DUMMYLOAD: - checkDummyIdData(); - break; - - case CIRCLE_EVENT_DUMMYGEN: - generateDummyCircle(); - break; - - default: - RsErr() << __PRETTY_FUNCTION__ << " Unknown Event Type: " << event_type - << std::endl; - break; - } -} - -//====================================================================================// -// Membership request handling // -//====================================================================================// - -// Circle membership is requested/denied by posting a message into the cicle group, according to the following rules: -// -// - a subscription request is a RsItem (which serialises into a radix64 message, that is further signed by the group message publishing system) -// The item contains: -// * subscribe order (yes/no), boolean -// * circle ID (this is important, otherwise people can copy subscribe messages from one circle to another) -// * subscribe date -// * subscribe timeout (how long is the message kept. When timed out, the message is removed and subscription cancelled) -// -// - subscribe messages follow the following rules, which are enforced by a timer-based method: -// * subscription requests from a given user are always replaced by the last subscription request -// * a complete list of who's subscribed to a given group is kept, saved, and regularly updated when new subscribe messages are received, or when admin list is changed. -// * getGroupDetails reads this list in order to respond who's subscribed to a group. The list of -// -// - compatibility with self-restricted circles: -// * subscription should be based on admin list, so that non subscribed peers still receive the invitation -// -// - two possible subscription models for circle member list (Restricted forums only propagate to members): -// 1 - list of admin who have not opposed subscription -// - solves propagation issue. Only admin see data. They can however unsubscribe using a negative req. Admin needs to remove them. -// - bad for security. Admin can refuse to remove them => back to square one -// 2 - list of admin who have also requested membership -// - propagation is ok. On restricted circle, the circle msgs/group should be sent to admin list, instead of member list. -// - solves membership issue since people need to actively be in the group. -// => choose 2 -// - forum group : encrypted for Member list -// - circle group : clear / encrypted for admin list (for self-restricted) -// We decide between the two by comparing the group we're sending and the circle id it is restricted to. -// -// - Use cases -// * user sees group (not self restricted) and requests to subscribe => RS subscribes the group and the user can propagate the response -// * user is invited to self-restricted circle. He will see it and can subscribe, so he will be in admin list and receive e.g. forum posts. -// * -// -// - Threat model -// * a malicious user forges a new subscription request: NP-hard as it needs to break the RSA key of the GXS id. -// * a malicious corrupts a subscription request: NP-hard. Messages are signed. -// * a malicious user copies an old subscription of someone else and inserts it in the system. -// => not possible. Either this existing old susbscription already exists, or it has been replaced by a more recent one, which -// will always replace the old one because of the date. -// * a malicious user removes someone's subscription messages. This is possible, but the mesh nature of the network will allow the message to propagate anyway. -// * a malicious user creates a circle with an incriminating name/content and adds everyone in it -// => people can oppose their membership in the circle using a msg -// -// -// - the table below summarizes the various choices: forum and circle propagation when restricted to a circle, and group subscribe to the circle -// -// +------------------------------+-----------------------------+ -// | User in admin list | User not in admin list | -// +-------------+------------------------------+-----------------------------+ -// | User request| Forum Grp/Msg: YES | Forum Grp/Msg: NO | -// | Subscription| Circle Grp/Msg: YES/YES | Circle Grp/Msg: YES/NO | -// | | Grp Subscribed: YES | Grp Subscribed: YES | -// +-------------+------------------------------+-----------------------------+ -// | No request | Forum Grp/Msg: NO | Forum Grp/Msg: NO | -// | Subscription| Circle Grp/Msg: YES/YES | Circle Grp/Msg: YES/NO | -// | | Grp Subscribed: NO | Grp Subscribed: NO | -// +-------------+------------------------------+-----------------------------+ - -bool p3GxsCircles::pushCircleMembershipRequest( const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type ) -{ - Dbg3() << __PRETTY_FUNCTION__ << "own_gxsid = " << own_gxsid - << ", circle=" << circle_id << ", req type=" << request_type - << std::endl; - - if( request_type != RsGxsCircleSubscriptionType::SUBSCRIBE && request_type != RsGxsCircleSubscriptionType::UNSUBSCRIBE ) - { - RsErr() << __PRETTY_FUNCTION__ << " Unknown request type: " << static_cast(request_type) << std::endl; - return false; - } - - if(!rsIdentity->isOwnId(own_gxsid)) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot generate membership request " - << "from not-own id: " << own_gxsid << std::endl; - return false; - } - - if(!getCirclesInfo( std::list{static_cast(circle_id)}, RS_DEFAULT_STORAGE_PARAM(std::vector) )) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot generate membership request from unknown circle: " << circle_id << std::endl; - return false; - } - // If the circle is not subscribed, then subscribe, whatever the subscription type. Indeed, if we publish a msg, even a msg for - // unsubscribing, we need to have a subscribed group first. - - if(!locked_subscribeToCircle(circle_id,true)) - { - std::cerr << __PRETTY_FUNCTION__ << " Could not subscribe to Circle group." << std::endl; - return false; - } - - // Create a subscribe item - - RsGxsCircleSubscriptionRequestItem *s = new RsGxsCircleSubscriptionRequestItem ; - - s->time_stamp = time(NULL) ; - s->time_out = 0 ; // means never - s->subscription_type = request_type ; - - RsTemporaryMemory tmpmem(circle_id.serial_size() + own_gxsid.serial_size()) ; - - uint32_t off = 0 ; - circle_id.serialise(tmpmem,tmpmem.size(),off) ; - own_gxsid.serialise(tmpmem,tmpmem.size(),off) ; - - s->meta.mGroupId = RsGxsGroupId(circle_id) ; - s->meta.mMsgId.clear(); - s->meta.mThreadId = RsGxsMessageId(RsDirUtil::sha1sum(tmpmem,tmpmem.size())); // make the ID from the hash of the cirle ID and the author ID - s->meta.mAuthorId = own_gxsid; - - // msgItem->meta.mParentId = ; // leave these blank - // msgItem->meta.mOrigMsgId= ; - -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::publishSubscribeRequest()" << std::endl; - std::cerr << " GroupId : " << circle_id << std::endl; - std::cerr << " AuthorId : " << s->meta.mAuthorId << std::endl; - std::cerr << " ThreadId : " << s->meta.mThreadId << std::endl; -#endif - - uint32_t token; - RsGenExchange::publishMsg(token, s); - - // This is manual handling of token. We need to clear it up from the notification when done, and that needs - // to be async-ed, since the processing of message publication is done in the same thread. - - RsThread::async( [this,token]() - { - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); - - auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most - auto st = requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - - std::pair grpmsgId; - acknowledgeMsg(token,grpmsgId); - }); - - // update the cache. - force_cache_reload(circle_id); - - return true; -} - -bool p3GxsCircles::requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id) -{ - return pushCircleMembershipRequest(own_gxsid,circle_id,RsGxsCircleSubscriptionType::SUBSCRIBE) ; -} -bool p3GxsCircles::cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id) -{ - return pushCircleMembershipRequest(own_gxsid,circle_id,RsGxsCircleSubscriptionType::UNSUBSCRIBE) ; -} - -bool p3GxsCircles::locked_processMembershipMessages(RsGxsCircleCache& cache, const std::vector& items, GxsMsgReq& messages_to_delete, const std::set &own_ids) -{ -#ifdef DEBUG_CIRCLES - std::cerr << " Circle found in cache!" << std::endl; - std::cerr << " Retrieving messages..." << std::endl; -#endif - cache.mDoIAuthorAMembershipMsg = false; // default - - for(uint32_t i=0;imeta.mGroupId << ", Message ID: " << items[i]->meta.mMsgId << ", thread ID: " << items[i]->meta.mThreadId << ", author: " << items[i]->meta.mAuthorId << ": " ; -#endif - RsGxsCircleSubscriptionRequestItem *item = dynamic_cast(items[i]) ; - - if(item == NULL) - { - std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird. Scheduling for deletion." << std::endl; - - messages_to_delete[RsGxsGroupId(cache.mCircleId)].insert(item->meta.mMsgId); - continue ; - } - - RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ; - -#ifdef DEBUG_CIRCLES - std::cerr << " " << time(NULL) - item->time_stamp << " seconds ago, " ; -#endif - - if(info.last_subscription_TS <= item->time_stamp) // the <= here allows to make sure we update the flags is something happenned - { - info.last_subscription_TS = item->time_stamp ; - - if(item->subscription_type == RsGxsCircleSubscriptionType::SUBSCRIBE) - info.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED; - else if(item->subscription_type == RsGxsCircleSubscriptionType::UNSUBSCRIBE) - info.subscription_flags &= ~GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED; - else - std::cerr << " (EE) unknown subscription order type: " << static_cast(item->subscription_type) ; - - mShouldSendCacheUpdateNotification = true; -#ifdef DEBUG_CIRCLES - std::cerr << " UPDATING status to " << std::hex << info.subscription_flags << std::dec << std::endl; -#endif - - if(own_ids.end() != own_ids.find(item->meta.mAuthorId)) // we have at least one subscribe/unsubscribe message. So we update the flag accordingly. - cache.mDoIAuthorAMembershipMsg = true; - } - else if(info.last_subscription_TS > item->time_stamp) - std::cerr << " Too old: item->TS=" << item->time_stamp << ", last_subscription_TS=" << info.last_subscription_TS << ". IGNORING." << std::endl; - } - - // now do another sweep and remove all msgs that are older than the latest - -#ifdef DEBUG_CIRCLES - std::cerr << " Cleaning older messages..." << std::endl; -#endif - - for(uint32_t i=0;imeta.mAuthorId]) ; - RsGxsCircleSubscriptionRequestItem *item = dynamic_cast(items[i]) ; - - if(item && info.last_subscription_TS > item->time_stamp) - { -#ifdef DEBUG_CIRCLES - std::cerr << " " << item->meta.mMsgId << ": Older than last known (" << (long int)info.last_subscription_TS - (long int)item->time_stamp << " seconds before): deleting." << std::endl; -#endif - messages_to_delete[RsGxsGroupId(cache.mCircleId)].insert(item->meta.mMsgId) ; - } - } - -#ifdef DEBUG_CIRCLES - std::cerr << " Cleaning older messages..." << std::endl; -#endif - - cache.mLastUpdatedMembershipTS = time(NULL) ; - cache.mStatus = CircleEntryCacheStatus::UP_TO_DATE; - cache.mLastUpdateTime = time(NULL); - mShouldSendCacheUpdateNotification = true; - - return true; -} - -bool p3GxsCircles::processMembershipRequests(uint32_t token) -{ - // Go through membership request messages and process them according to the following rule: - // * for each ID only keep the latest membership request. Delete the older ones. - // * for each circle, keep a list of IDs sorted into membership categories (e.g. keep updated flags for each IDs) - // Because msg loading is async-ed, the job in split in two methods: one calls the loading, the other one handles the loaded data. - -#ifdef DEBUG_CIRCLES - std::cerr << "Processing circle membership requests." << std::endl; -#endif - t_RsGxsGenericDataTemporaryMapVector msgItems; - - if(!RsGenExchange::getMsgData(token, msgItems)) - { - std::cerr << "(EE) Cannot get msg data for circle. Something's weird." << std::endl; - return false; - } - - std::list own_ids ; - rsIdentity->getOwnIds(own_ids); - std::set own_ids_set; - for(auto& id:own_ids) - own_ids_set.insert(id); - - GxsMsgReq messages_to_delete ; - - for(GxsMsgDataMap::const_iterator it(msgItems.begin());it!=msgItems.end();++it) - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ -#ifdef DEBUG_CIRCLES - std::cerr << " Circle ID: " << it->first << std::endl; -#endif - // Find the circle ID in cache and process the list of messages to keep the latest order in time. - - RsGxsCircleId circle_id(it->first); - RsGxsCircleCache& cache( mCircleCache[circle_id] ); - - // First process membership messages -#ifdef DEBUG_CIRCLES - std::cerr << " Processing membership messages..." << std::endl; -#endif - locked_processMembershipMessages(cache,it->second,messages_to_delete,own_ids_set); -#ifdef DEBUG_CIRCLES - std::cerr << " Now checking for auto-subscribe..." << std::endl; -#endif - locked_checkCircleCacheForAutoSubscribe(cache); - } - - if(!messages_to_delete.empty()) - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - uint32_t token2; - RsGenExchange::deleteMsgs(token2,messages_to_delete); - } - return true ; -} - -//====================================================================================// -// p3Config methods // -//====================================================================================// - -static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months -static const uint8_t GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; - -struct RsGxsCirclesNotifyRecordsItem: public RsItem -{ - - RsGxsCirclesNotifyRecordsItem() - : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG,GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD) - {} - - virtual ~RsGxsCirclesNotifyRecordsItem() {} - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { RS_SERIAL_PROCESS(records); } - - void clear() {} - - std::map records; -}; - -class GxsCirclesConfigSerializer : public RsServiceSerializer -{ -public: - GxsCirclesConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG) {} - virtual ~GxsCirclesConfigSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG) - return NULL; - - switch(item_sub_id) - { - case GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsCirclesNotifyRecordsItem(); - default: - return NULL; - } - } -}; - -bool p3GxsCircles::saveList(bool& cleanup, std::list&saveList) -{ - cleanup = true ; - - RsGxsCirclesNotifyRecordsItem *item = new RsGxsCirclesNotifyRecordsItem ; - - { - RS_STACK_MUTEX(mKnownCirclesMtx); - item->records = mKnownCircles ; - } - - saveList.push_back(item) ; - return true; -} - -bool p3GxsCircles::loadList(std::list& loadList) -{ - while(!loadList.empty()) - { - RsItem *item = loadList.front(); - loadList.pop_front(); - - rstime_t now = time(NULL); - - RsGxsCirclesNotifyRecordsItem *fnr = dynamic_cast(item) ; - - if(fnr != NULL) - { - RS_STACK_MUTEX(mKnownCirclesMtx); - - mKnownCircles.clear(); - - for(auto it(fnr->records.begin());it!=fnr->records.end();++it) - if( now < it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE) - mKnownCircles.insert(*it) ; - } - - delete item ; - } - return true; -} - -RsSerialiser* p3GxsCircles::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new GxsCirclesConfigSerializer()); - - return rss; -} - -//====================================================================================// -// DEBUG STUFF // -//====================================================================================// - -bool p3GxsCircles::debug_dumpCacheEntry(RsGxsCircleCache& cache) -{ - std::cerr << " Circle: " << cache.mCircleId - << " status: " << static_cast(cache.mStatus) - << " MembershipTS: " << cache.mLastUpdatedMembershipTS - << " UpdateTS: " << cache.mLastUpdateTime - << " All Ids here: " << cache.mAllIdsHere - << " Has own msg: " << cache.mDoIAuthorAMembershipMsg << std::endl; - - return true; -} - -void p3GxsCircles::debug_dumpCache() -{ - std::cerr << "Debug dump of CircleCache:" << std::endl; - - mCircleCache.printStats(); - mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::debug_dumpCacheEntry); -} - -std::string p3GxsCircles::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -void p3GxsCircles::generateDummyData() -{ - // request Id Data... -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::generateDummyData() getting Id List"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - uint32_t token; - rsIdentity->getTokenService()->requestGroupInfo(token, ansType, opts); - - { - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - mDummyIdToken = token; - } - - RsTickEvent::schedule_in(CIRCLE_EVENT_DUMMYLOAD, CIRCLE_DUMMY_GENPERIOD); -} - - -void p3GxsCircles::checkDummyIdData() -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::checkDummyIdData()"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - // check the token. - uint32_t status = rsIdentity->getTokenService()->requestStatus(mDummyIdToken); - if ( (RsTokenService::FAILED == status) || - (RsTokenService::COMPLETE == status) ) - { - std::vector ids; - if (!rsIdentity->getGroupData(mDummyIdToken, ids)) - { - std::cerr << "p3GxsCircles::checkDummyIdData() ERROR getting data"; - std::cerr << std::endl; - /* error */ - return; - } - - std::vector::iterator it; - for(it = ids.begin(); it != ids.end(); ++it) - { - if (it->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) - { -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::checkDummyIdData() PgpLinkedId: " << it->mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - mDummyPgpLinkedIds.push_back(RsGxsId(it->mMeta.mGroupId.toStdString())); - - if (it->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) - { -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::checkDummyIdData() OwnId: " << it->mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - mDummyOwnIds.push_back(RsGxsId(it->mMeta.mGroupId.toStdString())); - } - } - else - { -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::checkDummyIdData() Other Id: " << it->mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - } - } - - /* schedule the generate events */ -#define MAX_CIRCLES 10 - for(int i = 0; i < MAX_CIRCLES; i++) - { - RsTickEvent::schedule_in(CIRCLE_EVENT_DUMMYGEN, i * CIRCLE_DUMMY_GENPERIOD); - } - return; - } - - // Otherwise - reschedule to come back here. - RsTickEvent::schedule_in(CIRCLE_EVENT_DUMMYLOAD, CIRCLE_DUMMY_GENPERIOD); - return; -} - - -void p3GxsCircles::generateDummyCircle() -{ -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::generateDummyCircle()"; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - int npgps = mDummyPgpLinkedIds.size(); - - if(npgps == 0) - return ; - - RsGxsCircleGroup group; - - std::set idset; - // select a random number of them. -#define MAX_PEERS_PER_CIRCLE_GROUP 20 - int nIds = 1 + (RSRandom::random_u32() % MAX_PEERS_PER_CIRCLE_GROUP); - for(int i = 0; i < nIds; i++) - { - - int selection = (RSRandom::random_u32() % npgps); - std::list::iterator it = mDummyPgpLinkedIds.begin(); - for(int j = 0; (it != mDummyPgpLinkedIds.end()) && (j < selection); j++, ++it) ; - if (it != mDummyPgpLinkedIds.end()) - { - idset.insert(*it); - } - } - - /* be sure to add one of our IDs too (otherwise we wouldn't get the group) - */ - { - - int selection = (RSRandom::random_u32() % mDummyOwnIds.size()); - std::list::iterator it = mDummyOwnIds.begin(); - mDummyOwnIds.push_back(*it); - for(int j = 0; (it != mDummyOwnIds.end()) && (j < selection); j++, ++it) ; - if (it != mDummyOwnIds.end()) - { - idset.insert(*it); - } - } - - group.mMeta.mGroupName = genRandomId(); -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::generateDummyCircle() Name: " << group.mMeta.mGroupName; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - - std::set::iterator it; - for(it = idset.begin(); it != idset.end(); ++it) - { - group.mInvitedMembers.insert(*it); -#ifdef DEBUG_CIRCLES - std::cerr << "p3GxsCircles::generateDummyCircle() Adding: " << *it; - std::cerr << std::endl; -#endif // DEBUG_CIRCLES - } - - uint32_t dummyToken; - createGroup(dummyToken, group); -} - - -/****************************************************************************/ -// ID STUFF. \/ \/ \/ \/ \/ \/ \/ :) -/****************************************************************************/ -#if 0 - -/************************************************************************************/ -/************************************************************************************/ - -bool p3GxsCircles::cachetest_getlist() -{ - std::cerr << "p3GxsCircles::cachetest_getlist() making request"; - std::cerr << std::endl; - - uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, CIRCLEREQ_CACHETEST); - - // Schedule Next Event. - RsTickEvent::schedule_in(CIRCLE_EVENT_CACHETEST, CACHETEST_PERIOD); - return true; -} - -bool p3GxsCircles::cachetest_handlerequest(uint32_t token) -{ - std::cerr << "p3GxsCircles::cachetest_handlerequest() token: " << token; - std::cerr << std::endl; - - std::list grpIds; - bool ok = RsGenExchange::getGroupList(token, grpIds); - - if(ok) - { - std::list::iterator vit = grpIds.begin(); - for(; vit != grpIds.end(); ++vit) - { - /* 5% chance of checking it! */ - if (RSRandom::random_f32() < 0.25) - { - std::cerr << "p3GxsCircles::cachetest_request() Testing Id: " << *vit; - std::cerr << std::endl; - - /* try the cache! */ - if (!haveKey(*vit)) - { - std::list nullpeers; - requestKey(*vit, nullpeers); - - std::cerr << "p3GxsCircles::cachetest_request() Requested Key Id: " << *vit; - std::cerr << std::endl; - } - else - { - RsTlvSecurityKey seckey; - if (getKey(*vit, seckey)) - { - std::cerr << "p3GxsCircles::cachetest_request() Got Key OK Id: " << *vit; - std::cerr << std::endl; - - // success! - seckey.print(std::cerr, 10); - std::cerr << std::endl; - - - } - else - { - std::cerr << "p3GxsCircles::cachetest_request() ERROR no Key for Id: " << *vit; - std::cerr << std::endl; - } - } - - /* try private key too! */ - if (!havePrivateKey(*vit)) - { - requestPrivateKey(*vit); - std::cerr << "p3GxsCircles::cachetest_request() Requested PrivateKey Id: " << *vit; - std::cerr << std::endl; - } - else - { - RsTlvSecurityKey seckey; - if (getPrivateKey(*vit, seckey)) - { - // success! - std::cerr << "p3GxsCircles::cachetest_request() Got PrivateKey OK Id: " << *vit; - std::cerr << std::endl; - } - else - { - std::cerr << "p3GxsCircles::cachetest_request() ERROR no PrivateKey for Id: " << *vit; - std::cerr << std::endl; - } - } - } - } - } - else - { - std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; - } - return true; -} - -/****************************************************************************/ -// ID STUFF. /\ /\ /\ /\ /\ /\ /\ /\ :) -/****************************************************************************/ -#endif - -#ifdef HANDLE_SUBCIRCLES -#if 0 -/**** TODO BELOW ****/ - -bool p3GxsCircles::cache_load_subcircles(uint32_t token) -{ - std::cerr << "p3GxsCircles::cache_load_subcircles() : " << token; - std::cerr << std::endl; - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - - RsGxsCircleId id = item->meta.mGroupId; - RsGxsCircleGroup group = item->group; - group.mMeta = item->meta; - delete item; - - std::cerr << "p3GxsCircles::cache_load_subcircles() Loaded Id with Meta: "; - std::cerr << item->meta; - std::cerr << std::endl; - - - RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/ - - /* stage 2 of loading, load subcircles */ - std::map >::iterator sit; - sit = mCacheLoad_SubCircle.find(id) - if (sit == mCacheLoad_SubCircle.end()) - { - /* ERROR */ - continue; - } - - std::list updateCaches = sit->second; - // cleanup while we're here. - mCacheLoad_SubCircle.erase(sit); - - /* Now iterate through peers / subcircles, and apply - * - similarly to base load function - */ - - - RsGxsCircleCache &cache = it->second; - cache.loadBaseCircle(group); - - bool isComplete = true; - - std::list &peers = group.peers; - std::list::const_iterator pit; - - // need to trigger the searches. - for(pit = peers.begin(); pit != peers.end(); ++pit) - { - /* check cache */ - if (mIdentities->is_cached(*pit)) - { - /* we can process now! */ - RsIdentityDetails details; - if (mIdentities->getDetails(*pit, details)) - { - if (details.isPgpKnown) - { - // Problem - could have multiple GxsIds here! - // TODO. - //cache.mAllowedPeers[details.mPgpId] = *pit; - - for(uit = updateCaches.begin(); uit != updateCaches.end(); ++uit) - { - /* fetch the cache - and update */ - mLoadingCache[id] = RsGxsCircleCache(); - std::map::iterator it; - it = mLoadingCache.find(id); - } - - } - else - { - //cache.mUnknownPeers.push_back(*pit); - } - } - else - { - // ERROR. - } - } - else - { - /* store in to_process queue. */ - cache.mUnprocessedPeers.push_back(*pit); - - if (isComplete) - { - /* store reference to update */ - isComplete = false; - mCacheLoad_KeyWait.push_back(id); - } - } - } - - std::list &circles = group.circles; - std::list::const_iterator cit; - for(cit = circles.begin(); cit != circles.end(); ++cit) - { - /* if its cached already -> then its complete. */ - if (mCircleCache.is_loaded(*cit)) - { - RsGxsCircleCache cachedCircle; - if (mCircleCache.fetch(&cit, cachedCircle)) - { - /* copy cached circle into circle */ - cache.loadSubCircle(cachedCircle); - } - else - { - /* error */ - continue; - } - } - else - { - /* push into secondary processing queues */ - std::list &proc_circles = mCacheLoad_SubCircle[id]; - proc_circles.push_back(id); - - subCirclesToLoad.push_back(id); - - isComplete = false; - } - } - - if (isComplete) - { - /* move straight into the cache */ - mCircleCache.store(id, cache); - - /* remove from loading queue */ - mLoadingCache.erase(it); - } - } - } - else - { - std::cerr << "p3GxsCircles::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; - } - - if (!keysToLoad.empty()) - { - /* schedule event to try reload gxsIds */ - - } - - if (!subCirclesToLoad.empty()) - { - /* request load of subcircles */ - - - } - return true; -} - -#endif -#endif - -#ifdef HANDLE_SUBCIRCLES -#if 0 - std::list &circles = group.mSubCircles; - std::list::const_iterator cit; - for(cit = circles.begin(); cit != circles.end(); ++cit) - { - /* if its cached already -> then its complete. */ - if (mCircleCache.is_loaded(*cit)) - { - RsGxsCircleCache cachedCircle; - if (mCircleCache.fetch(&cit, cachedCircle)) - { - /* copy cached circle into circle */ - cache.loadSubCircle(cachedCircle); - } - else - { - /* error */ - continue; - } - } - else - { - /* push into secondary processing queues */ - std::list &proc_circles = mCacheLoad_SubCircle[*cit]; - proc_circles.push_back(id); - - subCirclesToLoad.push_back(*cit); - - isComplete = false; - isUnprocessedCircles = true; - } - } -#endif -#endif diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h deleted file mode 100644 index a98e09184..000000000 --- a/libretroshare/src/services/p3gxscircles.h +++ /dev/null @@ -1,391 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxscircles.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - - -#include "retroshare/rsgxscircles.h" // External Interfaces. -#include "gxs/rsgenexchange.h" // GXS service. -#include "gxs/rsgixs.h" // Internal Interfaces. -#include "services/p3idservice.h" // For constructing Caches -#include "gxs/gxstokenqueue.h" -#include "util/rstickevent.h" -#include "util/rsmemcache.h" -#include "util/rsdebug.h" - -#include -#include - -// TODO: -// can now edit circles. this leads to the following situation: -// if someone gets removed from a self.retricted circle, he won't notice -// because he can't receive the updated circle group if he is not part of the group anymore -// -// idea 1: refresh circle groups for example every week -// if a circle was not refreshed since two weeks we can assume we where deleted -// pro: does not leak info, simple to implement, does work even if the network topology changed (unfriending) -// con: delay until we know about the deletion -// -// idea 2: add a field with deleted members to the circle group -// then circle members can tell deleted circle members that they where deleted -// pro: faster notification about deletion -// con: more complicated, leaks info because the deleted member learns who is still a member -// question: how to authenticate the deletion message? -// -// idea 3: make a two phase deletion process -// first add members to a to-delete list -// then wait a week to let the changes propagate -// then remove from allowed peers list -// pro: easy to implement -// con: deletion process is slow -// improvement idea: let only circle groups sync when the member is on he to-delete list -// but don't allow sync of data from other services -// this requires that the netservice knows that he is dealing with a circle group -// -// fact: have to use a timeout mechanism. -// a timeout is the only thing which works even with a two months old backup - -/* - * Circles Identity Service - * - * A collection of notes: - * - * We want to be able to express the following types of Circles. - * - * - Public - * - Groups & Messages can be passed onto anyone. ( No Restrictions. ) - * - GXS Notes: - * - This is what we have currently. - * - * - External Circle - * - List of Identities that can receive the Group / Messages. - * - This list will be defined via a set of RsIdentities - which have PGPHashes set. - * - We need the PGPHashes to be able to identify which peers can receive msgs. - * - Messages are passed to the Intersection of (Identified PGPHashes & Friends) - * - Distribution of Circle Definitions can be also be restricted via circles. - * - You can have Public External Groups, or Groups that only the Members know about. - * - Control of these External Groups is determined by Admin / Publish Keys. - * - The Danger with External Groups, is your ID wll be associated with other people... - * - Leaking information!!! - * - GXS Notes: - * - p3Circles will provide a distrib list for a given Circle Group. - * - * - Personal Circle or "Your Eyes Only". - * - Same as an Internal Circle Definition. (What will be used for File Sharing initially) - * - Each peer will have a bunch of these, Friends, Family, etc. - * - * - The list is not publically shared, only the originator of the message will distribute. - * - You can communicate back to the originator, who will share with the other members. - * but you mustn't discuss / share content with anyone else. - * - This is quite a Weak / Fragile Group, as there is only one distributor. - * - GXS NOTES: - * - TO make this work, we need GXS or RsCircles to maintain extra info: - * - GXS stores the original source, so communications can go back there. - * - If Originator, GXS store a REFERENCE, Circles turn this into a distrib list of peers. - * - * - * - * Like RsIdentities are used to validation messages, - * RsCircles will be used to determine if a peer can receive a group / messages. - * - * bool RsCircles::canSend(RsGxsCircleId, RsPeerId) - * bool RsCircles::canSend(RsCircleInternalId, RsPeerId) - * - * or maybe just: - * - * bool RsCircles::recipients(GxsPermission &perms, std::list friendlist); - * - */ - -/* Permissions is part of GroupMetaData - */ - -class RsGxsCircleMembershipStatus -{ -public: - RsGxsCircleMembershipStatus() : last_subscription_TS(0), subscription_flags(0) {} - - rstime_t last_subscription_TS ; - uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED -}; - -enum class CircleEntryCacheStatus: uint8_t { - UNKNOWN = 0x00, // Used to detect uninitialized memory - NO_DATA_YET = 0x01, // Used in the constuctor - LOADING = 0x02, // When the token request to load cache has been sent and no data is present - UPDATING = 0x03, // Starting from this level the cache entry can be used - CHECKING_MEMBERSHIP = 0x04, // Means we're actually looking into msgs to update membership status - UP_TO_DATE = 0x05 // Everything should be loaded here. -}; - -class RsGxsCircleCache -{ -public: - RsGxsCircleCache(); - - bool loadBaseCircle(const RsGxsCircleGroup &circle); - bool loadSubCircle(const RsGxsCircleCache &subcircle); - - bool getAllowedPeersList(std::list &friendlist) const; - bool isAllowedPeer(const RsPgpId &id) const; - bool isAllowedPeer(const RsGxsId &id, const RsGxsGroupId &destination_group) const; - bool addAllowedPeer(const RsPgpId &pgpid); - bool addLocalFriend(const RsPgpId &pgpid); - - // Cache related data - - rstime_t mLastUpdatedMembershipTS ; // Last time the subscribe messages have been requested. Should be reset when new messages arrive. - rstime_t mLastUpdateTime; // Last time the cache entry was loaded - CircleEntryCacheStatus mStatus; // Overall state of the cache entry - bool mAllIdsHere ; // True when all ids are knwon and available. - - // GxsCircle related data - - RsGxsCircleId mCircleId; - std::string mCircleName; - - RsGxsCircleType mCircleType; - bool mIsExternal; - RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to. - - bool mDoIAuthorAMembershipMsg; // Do I have a subscribe/unsubscribe message in the circle group? Will be used to determine if we subscribe to the group or not - uint32_t mGroupStatus; // Copy of the group status from the GXS group. - uint32_t mGroupSubscribeFlags; // Subscribe flags of the group. - -#ifdef SUBSCIRCLES - std::set mUnprocessedCircles; - std::set mProcessedCircles; -#endif - std::map mMembershipStatus; // Membership status of each ID cited in the group (including the ones posting a message) - - std::set mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list. - std::set mAllowedNodes; // List of friend nodes allowed in the circle (local circles only) - - RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids -}; - - -class PgpAuxUtils; - -class RsCirclesMemCache : public std::map -{ -public: - RsCirclesMemCache() : std::map(){} - - bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; } - RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; } - - void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; } - - template void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&)) - { - for(auto& it:*this) - (c.*method)(it.second); - } - template void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&)) - { - for(const auto& it:*this) - (c.*method)(it.second); - } -}; - -class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, public GxsTokenQueue, public RsTickEvent, public p3Config -{ -public: - p3GxsCircles( - RsGeneralDataService* gds, RsNetworkExchangeService* nes, - p3IdService* identities, PgpAuxUtils* pgpUtils ); - - RsServiceInfo getServiceInfo() override; - - /// @see RsGxsCircles - bool createCircle( - const std::string& circleName, RsGxsCircleType circleType, - RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId), - const RsGxsCircleId& restrictedId = RsGxsCircleId(), - const RsGxsId& authorId = RsGxsId(), - const std::set& gxsIdMembers = std::set(), - const std::set& localMembers = std::set() - ) override; - - /// @see RsGxsCircles - bool editCircle(RsGxsCircleGroup& cData) override; - - /// @see RsGxsCircles - bool getCirclesSummaries(std::list& circles) override; - - /// @see RsGxsCircles - bool getCirclesInfo( - const std::list& circlesIds, - std::vector& circlesInfo ) override; - - /// @see RsGxsCircles - bool getCircleRequests( const RsGxsGroupId& circleId, - std::vector& requests ) override; - - /// @see RsGxsCircles - bool inviteIdsToCircle( const std::set& identities, - const RsGxsCircleId& circleId ) override; - - /// @see RsGxsCircles - bool revokeIdsFromCircle( const std::set& identities, - const RsGxsCircleId& circleId ) override; - - /// @see RsGxsCircles - bool getCircleRequest(const RsGxsGroupId& circleId, - const RsGxsMessageId& msgId, - RsGxsCircleMsg& msg) override; - - /// @see RsGxsCircles - bool exportCircleLink( - std::string& link, const RsGxsCircleId& circleId, - bool includeGxsData = true, - const std::string& baseUrl = DEFAULT_CIRCLE_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsCircles - bool importCircleLink( - const std::string& link, - RsGxsCircleId& circleId = RS_DEFAULT_STORAGE_PARAM(RsGxsCircleId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) override; - virtual bool getCircleExternalIdList(std::set &circleIds) override; - - virtual bool isLoaded(const RsGxsCircleId &circleId) override; - virtual bool loadCircle(const RsGxsCircleId &circleId) override; - - virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt) override; - virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) override; - - virtual bool recipients(const RsGxsCircleId &circleId, std::list &friendlist) override; - virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list &gxs_ids) override; - virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) override; - - - virtual bool getGroupData(const uint32_t &token, std::vector &groups) override; - virtual bool getMsgData(const uint32_t &token, std::vector &msgs) override; - virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) override; - virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) override; - - virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override; - virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) override; - - /* membership management for external circles */ - - virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override; - virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override; - - /**********************************************/ - - // needed for background processing. - virtual void service_tick() override; - -protected: - - // overloads p3Config - virtual bool saveList(bool &cleanup, std::list&saveList) override; - virtual bool loadList(std::list& loadList) override; - virtual RsSerialiser *setupSerialiser() override; - - bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ; - static uint32_t circleAuthenPolicy(); - - /** Notifications **/ - virtual void notifyChanges(std::vector& changes) override; - - /** Overloaded to add PgpIdHash to Group Definition **/ - virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override; - - // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - // Overloaded from RsTickEvent. - virtual void handle_event(uint32_t event_type, const std::string &elabel) override; - - private: - - // Load data. - bool processMembershipRequests(uint32_t token); - - // Need some crazy arsed cache to store the circle info. - // so we don't have to keep loading groups. - - int cache_tick(); - - bool cache_request_load(const RsGxsCircleId &id); - bool cache_start_load(); - bool force_cache_reload(const RsGxsCircleId& id); - bool cache_load_for_token(uint32_t token); - bool cache_reloadids(const RsGxsCircleId &circleId); - - bool checkCircleCache(); - - bool locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache); - bool locked_processMembershipMessages(RsGxsCircleCache& cache,const std::vector& items, GxsMsgReq& messages_to_delete,const std::set& own_ids); - bool locked_processLoadingCacheEntry(RsGxsCircleCache &cache); - bool locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache &cache); - bool locked_setGroupUnprocessedStatus(RsGxsCircleCache& cache,bool unprocessed); - bool locked_subscribeToCircle(const RsGxsCircleId &grpId, bool subscribe); - - p3IdService *mIdentities; // Needed for constructing Circle Info, - PgpAuxUtils *mPgpUtils; - - RsMutex mCircleMtx; /* Locked Below Here */ - RsMutex mKnownCirclesMtx; /* Locked Below Here */ - - std::map mKnownCircles; - - /***** Caching Circle Info, *****/ - - // waiting for subcircle to load. (first is part of each of the second list) - // TODO. - //std::map > mCacheLoad_SubCircle; - - std::set mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups. - RsCirclesMemCache mCircleCache; - //RsMemCache mCircleCache; // actual cache data - - void debug_dumpCache(); // debug method to overview what's going on - bool debug_dumpCacheEntry(RsGxsCircleCache &cache); -private: - - std::string genRandomId(); - - void generateDummyData(); - void checkDummyIdData(); - void generateDummyCircle(); - - rstime_t mLastCacheMembershipUpdateTS ; - - uint32_t mDummyIdToken; - std::list mDummyPgpLinkedIds; - std::list mDummyOwnIds; - bool mShouldSendCacheUpdateNotification ; - rstime_t mLastCacheUpdateEvent; - rstime_t mLastDebugPrintTS; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/services/p3gxscommon.cc b/libretroshare/src/services/p3gxscommon.cc deleted file mode 100644 index 7c37bd6aa..000000000 --- a/libretroshare/src/services/p3gxscommon.cc +++ /dev/null @@ -1,772 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxscommon.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "retroshare/rsgxscommon.h" -#include "services/p3gxscommon.h" -#include "rsitems/rsgxscommentitems.h" -#include "util/rsstring.h" - -#include -#include -#include - -//#define DEBUG_GXSCOMMON - -RsGxsComment::RsGxsComment() -{ - mUpVotes = 0; - mDownVotes = 0; - mScore = 0; - mOwnVote = 0; -} - -/********************************************************************************/ - -RsGxsImage::RsGxsImage() -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage(" << this << ")"; - std::cerr << std::endl; -#endif - mData = NULL; - mSize = 0; -} - -RsGxsImage::RsGxsImage(const RsGxsImage& a) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage(" << this << ") = RsGxsImage(" << (void *) &a << ")"; - std::cerr << std::endl; -#endif - mData = NULL; - mSize = 0; - copy(a.mData, a.mSize); -} - - -RsGxsImage::~RsGxsImage() -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "~RsGxsImage(" << this << ")"; - std::cerr << std::endl; -#endif - clear(); -} - - -RsGxsImage &RsGxsImage::operator=(const RsGxsImage &a) -{ - copy(a.mData, a.mSize); - return *this; -} - - -bool RsGxsImage::empty() const -{ - return ((mData == NULL) || (mSize == 0)); -} - -void RsGxsImage::take(uint8_t *data, uint32_t size) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage(" << this << ")::take(" << (void *) data << "," << size << ")"; - std::cerr << std::endl; -#endif - // Copies Pointer. - clear(); - mData = data; - mSize = size; -} - -// NB Must make sure that we always use malloc/free for this data. -uint8_t *RsGxsImage::allocate(uint32_t size) -{ - uint8_t *val = (uint8_t *) rs_malloc(size); - -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage()::allocate(" << (void *) val << ")"; - std::cerr << std::endl; -#endif - return val; -} - -void RsGxsImage::release(void *data) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage()::release(" << (void *) data << ")"; - std::cerr << std::endl; -#endif - free(data); -} - -void RsGxsImage::copy(uint8_t *data, uint32_t size) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "RsGxsImage(" << this << ")::copy(" << (void *) data << "," << size << ")"; - std::cerr << std::endl; -#endif - // Allocates and Copies. - clear(); - if (data && size) - { - mData = allocate(size); - memcpy(mData, data, size); - mSize = size; - } -} - -void RsGxsImage::clear() -{ - // Frees. - if (mData) - { - release(mData); - } - mData = NULL; - mSize = 0; -} - -void RsGxsImage::shallowClear() -{ - // Clears Pointer. - mData = NULL; - mSize = 0; -} - -/********************************************************************************/ - - -RsGxsFile::RsGxsFile() -{ - mSize = 0; -} - -RsGxsVote::RsGxsVote() -{ - mVoteType = 0; -} - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -#define GXSCOMMENTS_VOTE_CHECK 0x0002 -#define GXSCOMMENTS_VOTE_DONE 0x0003 - -p3GxsCommentService::p3GxsCommentService(RsGenExchange *exchange, uint16_t service_type) - : GxsTokenQueue(exchange), mExchange(exchange), mServiceType(service_type) -{ - return; -} - -void p3GxsCommentService::comment_tick() -{ - GxsTokenQueue::checkRequests(); -} - -bool p3GxsCommentService::getGxsCommentData(const uint32_t &token, std::vector &comments) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::getGxsCommentData()"; - std::cerr << std::endl; -#endif - - GxsMsgDataMap msgData; - bool ok = mExchange->getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - std::multimap voteMap; - - for(; mit != msgData.end(); ++mit) - { - //RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - /* now split into Comments and Votes */ - - for(; vit != msgItems.end(); ++vit) - { - RsGxsCommentItem* item = dynamic_cast(*vit); - - if(item) - { - RsGxsComment comment = item->mMsg; - comment.mMeta = item->meta; - comments.push_back(comment); - delete item; - } - else - { - RsGxsVoteItem* vote = dynamic_cast(*vit); - if (vote) - { - voteMap.insert(std::make_pair(vote->meta.mParentId, vote)); - } - else - { - std::cerr << "Not a Comment or Vote, deleting!" << std::endl; - delete *vit; - } - } - } - } - - /* now iterate through comments - and set the vote counts */ - std::vector::iterator cit; - std::multimap::iterator it; - for(cit = comments.begin(); cit != comments.end(); ++cit) - { - for (it = voteMap.lower_bound(cit->mMeta.mMsgId); it != voteMap.upper_bound(cit->mMeta.mMsgId); ++it) - { - if (it->second->mMsg.mVoteType == GXS_VOTE_UP) - { - cit->mUpVotes++; - } - else - { - cit->mDownVotes++; - } - } - cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes); - - /* convert Status -> mHaveVoted */ - if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK) - { - if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_UP) - { - cit->mOwnVote = GXS_VOTE_UP; - } - else - { - cit->mOwnVote = GXS_VOTE_DOWN; - } - } - else - { - cit->mOwnVote = GXS_VOTE_NONE; - } - } - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::getGxsCommentData() Found " << comments.size() << " Comments"; - std::cerr << std::endl; - std::cerr << "p3GxsCommentService::getGxsCommentData() Found " << voteMap.size() << " Votes"; - std::cerr << std::endl; -#endif - - /* delete the votes */ - for (it = voteMap.begin(); it != voteMap.end(); ++it) - { - delete it->second; - } - - - - } - - return ok; -} - - - - -bool p3GxsCommentService::getGxsRelatedComments(const uint32_t &token, std::vector &comments) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::getGxsRelatedComments()"; - std::cerr << std::endl; -#endif - - GxsMsgRelatedDataMap msgData; - bool ok = mExchange->getMsgRelatedData(token, msgData); - - if(ok) - { - GxsMsgRelatedDataMap::iterator mit = msgData.begin(); - std::multimap voteMap; - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsCommentItem* item = dynamic_cast(*vit); - - if(item) - { - RsGxsComment comment = item->mMsg; - comment.mMeta = item->meta; - comments.push_back(comment); - delete item; - } - else - { - RsGxsVoteItem* vote = dynamic_cast(*vit); - if (vote) - { - voteMap.insert(std::make_pair(vote->meta.mParentId, vote)); - } - else - { - std::cerr << "Not a Comment or Vote, deleting!" << std::endl; - delete *vit; - } - } - } - } - - /* now iterate through comments - and set the vote counts */ - std::vector::iterator cit; - std::multimap::iterator it; - for(cit = comments.begin(); cit != comments.end(); ++cit) - { - for (it = voteMap.lower_bound(cit->mMeta.mMsgId); it != voteMap.upper_bound(cit->mMeta.mMsgId); ++it) - { - if (it->second->mMsg.mVoteType == GXS_VOTE_UP) - { - cit->mUpVotes++; - } - else - { - cit->mDownVotes++; - } - } - cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes); - - /* convert Status -> mHaveVoted */ - if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK) - { - if (cit->mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_UP) - { - cit->mOwnVote = GXS_VOTE_UP; - } - else - { - cit->mOwnVote = GXS_VOTE_DOWN; - } - } - else - { - cit->mOwnVote = GXS_VOTE_NONE; - } - } - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::getGxsRelatedComments() Found " << comments.size() << " Comments"; - std::cerr << std::endl; - std::cerr << "p3GxsCommentService::getGxsRelatedComments() Found " << voteMap.size() << " Votes"; - std::cerr << std::endl; -#endif - - /* delete the votes */ - for (it = voteMap.begin(); it != voteMap.end(); ++it) - { - delete it->second; - } - } - - return ok; -} - - - -double p3GxsCommentService::calculateBestScore(int upVotes, int downVotes) -{ - - float score; - int n = upVotes + downVotes; - - if(n==0) - score = 0.0; - else - { - // See https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx#L45 for the source of this nice formula. - // http://www.evanmiller.org/how-not-to-sort-by-average-rating.html for the mathematical explanation. - - float p = upVotes/n; - float z = 1.281551565545 ; - - float left = p + 1/(2*n)*z*z ; - float right = z*sqrt(p*(1-p)/n + z*z/(4*n*n)) ; - float under = 1+1/n*z*z ; - - score = (left - right)/under ; - - //static float z = 1.0; - //score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n); - } - return score; -} - - - -/********************************************************************************************/ - -bool p3GxsCommentService::createGxsComment(uint32_t &token, const RsGxsComment &msg) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::createGxsComment() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; -#endif - - RsGxsCommentItem* msgItem = new RsGxsCommentItem(mServiceType); - msgItem->mMsg = msg; - msgItem->meta = msg.mMeta; - - mExchange->publishMsg(token, msgItem); - return true; -} - - - -bool p3GxsCommentService::createGxsVote(uint32_t &token, RsGxsVote &vote) -{ - // NOTE Because we cannot do this operation immediately, we create a token, - // and monitor acknowledgeTokenMsg ... to return correct answer. - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::createGxsVote() GroupId: " << vote.mMeta.mGroupId; - std::cerr << std::endl; -#endif - - /* vote must be associated with another item */ - if (vote.mMeta.mThreadId.isNull()) - { - std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required ThreadId"; - std::cerr << std::endl; - return false; - } - - if (vote.mMeta.mParentId.isNull()) - { - std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required ParentId"; - std::cerr << std::endl; - return false; - } - - if (vote.mMeta.mGroupId.isNull()) - { - std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required GroupId"; - std::cerr << std::endl; - return false; - } - - if (vote.mMeta.mAuthorId.isNull()) - { - std::cerr << "p3GxsCommentService::createGxsVote() ERROR Missing Required AuthorId"; - std::cerr << std::endl; - return false; - } - - - /* now queue */ - - RsGxsGrpMsgIdPair parentId(vote.mMeta.mGroupId, vote.mMeta.mParentId); - - std::map::iterator it; - it = mPendingVotes.find(parentId); - if (it != mPendingVotes.end()) - { - std::cerr << "p3GxsCommentService::createGxsVote() ERROR Already a pending vote!"; - std::cerr << std::endl; - return false; - } - - token = mExchange->generatePublicToken(); - mPendingVotes[parentId] = VoteHolder(vote, token); - - // request parent, and queue for response. - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_META; - - GxsMsgReq msgIds; - std::set &vect_msgIds = msgIds[parentId.first]; - vect_msgIds.insert(parentId.second); - - uint32_t int_token; - mExchange->getTokenService()->requestMsgInfo(int_token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, msgIds); - GxsTokenQueue::queueRequest(int_token, GXSCOMMENTS_VOTE_CHECK); - - return true; -} - - - - - - - -void p3GxsCommentService::load_PendingVoteParent(const uint32_t &token) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::load_PendingVoteParent()"; - std::cerr << std::endl; -#endif - GxsMsgMetaMap msginfo; - if (!mExchange->getMsgMeta(token, msginfo)) - { - std::cerr << "p3GxsCommentService::load_PendingVoteParent() ERROR Fetching Data"; - std::cerr << std::endl; - std::cerr << "p3GxsCommentService::load_PendingVoteParent() Warning - this means LOST QUEUE ENTRY"; - std::cerr << std::endl; - std::cerr << "p3GxsCommentService::load_PendingVoteParent() Need to track tokens - if this happens"; - std::cerr << std::endl; - return; - } - - GxsMsgMetaMap::iterator it; - for(it = msginfo.begin(); it != msginfo.end(); ++it) - { - std::vector::iterator mit; - for(mit = it->second.begin(); mit != it->second.end(); ++mit) - { - /* find the matching Pending Vote */ - RsMsgMetaData &meta = *mit; - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::load_PendingVoteParent() recv (groupId: " << meta.mGroupId; - std::cerr << ", msgId: " << meta.mMsgId << ")"; - std::cerr << std::endl; -#endif - - RsGxsGrpMsgIdPair parentId(meta.mGroupId, meta.mMsgId); - std::map::iterator pit; - pit = mPendingVotes.find(parentId); - if (pit == mPendingVotes.end()) - { - std::cerr << __PRETTY_FUNCTION__ - << " ERROR Finding Pending Vote" << std::endl; - continue; - } - - RsGxsVote vote = pit->second.mVote; - if (meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR Already Voted" - << std::endl - << "mGroupId: " << meta.mGroupId << std::endl - << "mMsgId: " << meta.mMsgId << std::endl; - - pit->second.mStatus = VoteHolder::VOTE_ERROR; - mExchange->updatePublicRequestStatus( - pit->second.mReqToken, RsTokenService::FAILED ); - continue; - } - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::load_PendingVoteParent() submitting Vote"; - std::cerr << std::endl; -#endif - - uint32_t status_token; - if (vote.mVoteType == GXS_VOTE_UP) - { - mExchange->setMsgStatusFlags(status_token, parentId, - GXS_SERV::GXS_MSG_STATUS_VOTE_UP, GXS_SERV::GXS_MSG_STATUS_VOTE_MASK); - } - else - { - mExchange->setMsgStatusFlags(status_token, parentId, - GXS_SERV::GXS_MSG_STATUS_VOTE_DOWN, GXS_SERV::GXS_MSG_STATUS_VOTE_MASK); - } - - uint32_t vote_token; - castVote(vote_token, vote); - GxsTokenQueue::queueRequest(vote_token, GXSCOMMENTS_VOTE_DONE); - - pit->second.mVoteToken = vote_token; - pit->second.mStatus = VoteHolder::VOTE_SUBMITTED; - } - } -} - - - -void p3GxsCommentService::completeInternalVote(uint32_t &token) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::completeInternalVote() token: " << token; - std::cerr << std::endl; -#endif - std::map::iterator it; - for (it = mPendingVotes.begin(); it != mPendingVotes.end(); ++it) - { - if (it->second.mVoteToken == token) - { - RsTokenService::GxsRequestStatus status = - mExchange->getTokenService()->requestStatus(token); - mExchange->updatePublicRequestStatus(it->second.mReqToken, status); - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::completeInternalVote() Matched to PendingVote. status: " << status; - std::cerr << std::endl; -#endif - - it->second.mStatus = VoteHolder::VOTE_READY; - return; - } - } - - std::cerr << "p3GxsCommentService::completeInternalVote() ERROR Failed to match PendingVote"; - std::cerr << std::endl; - - return; -} - - -bool p3GxsCommentService::acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPair& msgId) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::acknowledgeVote() token: " << token; - std::cerr << std::endl; -#endif - - std::map::iterator it; - for (it = mPendingVotes.begin(); it != mPendingVotes.end(); ++it) - { - if (it->second.mReqToken == token) - { -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::acknowledgeVote() Matched to PendingVote"; - std::cerr << std::endl; -#endif - - bool ans = false; - if (it->second.mStatus == VoteHolder::VOTE_READY) - { -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = READY"; - std::cerr << std::endl; -#endif - - // Finally finish this Vote off. - ans = mExchange->acknowledgeTokenMsg(it->second.mVoteToken, msgId); - } - else if (it->second.mStatus == VoteHolder::VOTE_ERROR) - { - std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = ERROR ???"; - std::cerr << std::endl; - } -#ifdef DEBUG_GXSCOMMON - else - { - std::cerr << "p3GxsCommentService::acknowledgeVote() PendingVote = OTHER STATUS"; - std::cerr << std::endl; - } - - std::cerr << "p3GxsCommentService::acknowledgeVote() cleanup token & PendingVote"; - std::cerr << std::endl; -#endif - mExchange->disposeOfPublicToken(it->second.mReqToken); - mPendingVotes.erase(it); - - return ans; - } - } - -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::acknowledgeVote() Failed to match PendingVote"; - std::cerr << std::endl; -#endif - - return false; -} - - - // Overloaded from GxsTokenQueue for Request callbacks. -void p3GxsCommentService::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl; -#endif - if (status != RsTokenService::COMPLETE) - return; //For now, only manage Complete request - - - // stuff. - switch(req_type) - { - case GXSCOMMENTS_VOTE_CHECK: - load_PendingVoteParent(token); - break; - - case GXSCOMMENTS_VOTE_DONE: - completeInternalVote(token); - break; - - default: - /* error */ - std::cerr << "p3GxsCommentService::handleResponse() Unknown Request Type: " << req_type; - std::cerr << std::endl; - break; - } -} - - - - - -bool p3GxsCommentService::castVote(uint32_t &token, RsGxsVote &msg) -{ -#ifdef DEBUG_GXSCOMMON - std::cerr << "p3GxsCommentService::castVote() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; -#endif - - RsGxsVoteItem* msgItem = new RsGxsVoteItem(mServiceType); - msgItem->mMsg = msg; - msgItem->meta = msg.mMeta; - - mExchange->publishMsg(token, msgItem); - return true; -} - - - - - - - -/********************************************************************************************/ -/********************************************************************************************/ - -#if 0 -void p3GxsCommentService::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD; - if (read) - { - status = 0; - } - - setMsgStatusFlags(token, msgId, status, mask); - -} - -#endif - diff --git a/libretroshare/src/services/p3gxscommon.h b/libretroshare/src/services/p3gxscommon.h deleted file mode 100644 index fb51a0d30..000000000 --- a/libretroshare/src/services/p3gxscommon.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxscommon.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_GXSCOMMON_SERVICE_HEADER -#define P3_GXSCOMMON_SERVICE_HEADER - -#include "retroshare/rsgxscommon.h" -#include "gxs/rsgenexchange.h" -#include "gxs/gxstokenqueue.h" -#include - - -/**** - * This mirrors rsGxsCommentService, with slightly different names, - * provides the implementation for any services requiring Comments. - */ - -# -class VoteHolder -{ - public: - - static const uint32_t VOTE_ERROR = 0; - static const uint32_t VOTE_QUEUED = 1; - static const uint32_t VOTE_SUBMITTED = 2; - static const uint32_t VOTE_READY = 3; - - VoteHolder() :mVoteToken(0), mReqToken(0), mStatus(VOTE_ERROR) { return; } - - VoteHolder(const RsGxsVote &vote, uint32_t reqToken) - :mVote(vote), mVoteToken(0), mReqToken(reqToken), mStatus(VOTE_QUEUED) { return; } - - RsGxsVote mVote; - uint32_t mVoteToken; - uint32_t mReqToken; - uint32_t mStatus; -}; - - -class p3GxsCommentService: public GxsTokenQueue -{ - public: - - p3GxsCommentService(RsGenExchange *exchange, uint16_t service_type); - - void comment_tick(); - - bool getGxsCommentData(const uint32_t &token, std::vector &msgs); - bool getGxsRelatedComments(const uint32_t &token, std::vector &msgs); - - bool createGxsComment(uint32_t &token, const RsGxsComment &msg); - bool createGxsVote(uint32_t &token, RsGxsVote &msg); - - // Special Acknowledge. - bool acknowledgeVote(const uint32_t& token, RsGxsGrpMsgIdPair& msgId); - -static double calculateBestScore(int upVotes, int downVotes); - - -#if 0 - void setGxsMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); -#endif - - protected: - - // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - private: - - void load_PendingVoteParent(const uint32_t &token); - void completeInternalVote(uint32_t &token); - - bool castVote(uint32_t &token, RsGxsVote &msg); - - RsGenExchange *mExchange; - uint16_t mServiceType; - - /* pending queue of Votes */ - std::map mPendingVotes; - - -}; - - -#endif - diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc deleted file mode 100644 index a301997e6..000000000 --- a/libretroshare/src/services/p3gxsforums.cc +++ /dev/null @@ -1,1389 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxsforums.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include - -#include "services/p3gxsforums.h" -#include "rsitems/rsgxsforumitems.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsidentity.h" -#include "util/rsdebug.h" -#include "rsserver/p3face.h" -#include "retroshare/rsnotify.h" -#include "util/rsdebuglevel2.h" -#include "retroshare/rsgxsflags.h" - - -// For Dummy Msgs. -#include "util/rsrandom.h" -#include "util/rsstring.h" - -/**** - * #define GXSFORUM_DEBUG 1 - ****/ - -RsGxsForums *rsGxsForums = NULL; - -#define FORUM_TESTEVENT_DUMMYDATA 0x0001 -#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated. -#define FORUM_UNUSED_BY_FRIENDS_DELAY (2*30*86400) // unused forums are deleted after 2 months - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3GxsForums::p3GxsForums( RsGeneralDataService *gds, - RsNetworkExchangeService *nes, RsGixs* gixs ) : - RsGenExchange( gds, nes, new RsGxsForumSerialiser(), - RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()), - RsGxsForums(static_cast(*this)), mGenToken(0), - mGenActive(false), mGenCount(0), mKnownForumsMutex("GXS forums known forums timestamp cache") -{ - // Test Data disabled in Repo. - //RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); -} - - -const std::string GXS_FORUMS_APP_NAME = "gxsforums"; -const uint16_t GXS_FORUMS_APP_MAJOR_VERSION = 1; -const uint16_t GXS_FORUMS_APP_MINOR_VERSION = 0; -const uint16_t GXS_FORUMS_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_FORUMS_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3GxsForums::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_FORUMS, - GXS_FORUMS_APP_NAME, - GXS_FORUMS_APP_MAJOR_VERSION, - GXS_FORUMS_APP_MINOR_VERSION, - GXS_FORUMS_MIN_MAJOR_VERSION, - GXS_FORUMS_MIN_MINOR_VERSION); -} - - -uint32_t p3GxsForums::forumsAuthenPolicy() -{ - uint32_t policy = 0; - uint32_t flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months -static const uint8_t GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; - -struct RsGxsForumNotifyRecordsItem: public RsItem -{ - - RsGxsForumNotifyRecordsItem() - : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_FORUMS_CONFIG,GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD) - {} - - virtual ~RsGxsForumNotifyRecordsItem() {} - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { RS_SERIAL_PROCESS(records); } - - void clear() {} - - std::map records; -}; - -class GxsForumsConfigSerializer : public RsServiceSerializer -{ -public: - GxsForumsConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_FORUMS_CONFIG) {} - virtual ~GxsForumsConfigSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_GXS_TYPE_FORUMS_CONFIG) - return NULL; - - switch(item_sub_id) - { - case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem(); - default: - return NULL; - } - } -}; - -bool p3GxsForums::saveList(bool &cleanup, std::list&saveList) -{ - cleanup = true ; - - RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ; - - { - RS_STACK_MUTEX(mKnownForumsMutex); - item->records = mKnownForums ; - } - - saveList.push_back(item) ; - return true; -} - -bool p3GxsForums::loadList(std::list& loadList) -{ - while(!loadList.empty()) - { - RsItem *item = loadList.front(); - loadList.pop_front(); - - rstime_t now = time(NULL); - - RsGxsForumNotifyRecordsItem *fnr = dynamic_cast(item) ; - - if(fnr != NULL) - { - RS_STACK_MUTEX(mKnownForumsMutex); - - mKnownForums.clear(); - - for(auto it(fnr->records.begin());it!=fnr->records.end();++it) - if( now < it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE) - mKnownForums.insert(*it) ; - } - - delete item ; - } - return true; -} - -RsSerialiser* p3GxsForums::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new GxsForumsConfigSerializer()); - - return rss; -} - -void p3GxsForums::notifyChanges(std::vector &changes) -{ -#ifdef GXSFORUMS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() : " << changes.size() << "changes to notify" << std::endl; -#endif - - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) - { - RsGxsMsgChange *msgChange = dynamic_cast(*it); - - if (msgChange) - { - if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */ - if (rsEvents) - { - auto ev = std::make_shared(); - ev->mForumMsgId = msgChange->mMsgId; - ev->mForumGroupId = msgChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; - rsEvents->postEvent(ev); - } - -#ifdef NOT_USED_YET - if (!msgChange->metaChange()) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() Found Message Change Notification"; - std::cerr << std::endl; -#endif - - std::map > &msgChangeMap = msgChange->msgChangeMap; - for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsForums::notifyChanges() Msgs for Group: " << mit->first; - std::cerr << std::endl; -#endif - bool enabled = false; - if (autoDownloadEnabled(mit->first, enabled) && enabled) - { -#ifdef GXSCHANNELS_DEBUG - std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first; - std::cerr << std::endl; -#endif - - /* problem is most of these will be comments and votes, - * should make it occasional - every 5mins / 10minutes TODO */ - unprocessedGroups.push_back(mit->first); - } - } - } -#endif - } - else - { - if (rsEvents) - { - RsGxsGroupChange *grpChange = dynamic_cast(*it); - if (grpChange) - { - switch (grpChange->getType()) - { - case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::SYNC_PARAMETERS_UPDATED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_PUBLISHED: - case RsGxsNotify::TYPE_RECEIVED_NEW: - { - /* group received */ - - bool unknown; - { - RS_STACK_MUTEX(mKnownForumsMutex); - unknown = (mKnownForums.find(grpChange->mGroupId)==mKnownForums.end()); - mKnownForums[grpChange->mGroupId] = time(nullptr); - IndicateConfigChanged(); - } - - if(unknown) - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::NEW_FORUM; - rsEvents->postEvent(ev); - } - else - RsInfo() << __PRETTY_FUNCTION__ - << " Not notifying already known forum " - << grpChange->mGroupId << std::endl; - } - break; - - case RsGxsNotify::TYPE_GROUP_DELETED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::DELETED_FORUM; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - auto ev = std::make_shared(); - ev->mForumGroupId = grpChange->mGroupId; - ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - - RS_STACK_MUTEX(mKnownForumsMutex); - mKnownForums[grpChange->mGroupId] = time(nullptr); - IndicateConfigChanged(); - } - break; - - case RsGxsNotify::TYPE_UPDATED: - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast(grpChange->mOldGroupItem); - RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast(grpChange->mNewGroupItem); - - if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr) - { - RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem or NULL. This is inconsistent!" << std::endl; - delete grpChange; - continue; - } - - // First of all, we check if there is a difference between the old and new list of moderators - - std::list added_mods, removed_mods; - - for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids) - if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end()) - added_mods.push_back(gxs_id); - - for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids) - if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end()) - removed_mods.push_back(gxs_id); - - if(!added_mods.empty() || !removed_mods.empty()) - { - auto ev = std::make_shared(); - - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mModeratorsAdded = added_mods; - ev->mModeratorsRemoved = removed_mods; - ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED; - - rsEvents->postEvent(ev); - } - - // check the list of pinned posts - - std::list added_pins, removed_pins; - - for(auto& msg_id: new_forum_grp_item->mGroup.mPinnedPosts.ids) - if(old_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) == old_forum_grp_item->mGroup.mPinnedPosts.ids.end()) - added_pins.push_back(msg_id); - - for(auto& msg_id: old_forum_grp_item->mGroup.mPinnedPosts.ids) - if(new_forum_grp_item->mGroup.mPinnedPosts.ids.find(msg_id) == new_forum_grp_item->mGroup.mPinnedPosts.ids.end()) - removed_pins.push_back(msg_id); - - if(!added_pins.empty() || !removed_pins.empty()) - { - auto ev = std::make_shared(); - - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mForumEventCode = RsForumEventCode::PINNED_POSTS_CHANGED; - - rsEvents->postEvent(ev); - } - - if( old_forum_grp_item->mGroup.mDescription != new_forum_grp_item->mGroup.mDescription - || old_forum_grp_item->meta.mGroupName != new_forum_grp_item->meta.mGroupName - || old_forum_grp_item->meta.mGroupFlags != new_forum_grp_item->meta.mGroupFlags - || old_forum_grp_item->meta.mAuthorId != new_forum_grp_item->meta.mAuthorId - || old_forum_grp_item->meta.mCircleId != new_forum_grp_item->meta.mCircleId - ) - { - auto ev = std::make_shared(); - ev->mForumGroupId = new_forum_grp_item->meta.mGroupId; - ev->mForumEventCode = RsForumEventCode::UPDATED_FORUM; - rsEvents->postEvent(ev); - } - } - break; - - - default: - RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl; - break; - } - } - } - } - - /* shouldn't need to worry about groups - as they need to be subscribed to */ - - delete *it; - } -} - -void p3GxsForums::service_tick() -{ - dummy_tick(); - RsTickEvent::tick_events(); - return; -} - -rstime_t p3GxsForums::service_getLastGroupSeenTs(const RsGxsGroupId& gid) -{ - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownForumsMutex); - - auto it = mKnownForums.find(gid); - bool unknown_forum = it == mKnownForums.end(); - - if(unknown_forum) - { - mKnownForums[gid] = now; - IndicateConfigChanged(); - return now; - } - else - return it->second; -} -bool p3GxsForums::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) -{ -#ifdef GXSFORUMS_DEBUG - std::cerr << "p3gxsForums: Checking unused forums: called by GxsCleaning." << std::endl; -#endif - - // request all group infos at once - - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownForumsMutex); - - auto it = mKnownForums.find(meta.mGroupId); - bool unknown_forum = it == mKnownForums.end(); - -#ifdef GXSFORUMS_DEBUG - std::cerr << " Forum " << meta.mGroupId ; -#endif - - if(unknown_forum) - { - // This case should normally not happen. It does because this forum was never registered since it may - // arrived before this code was here - -#ifdef GXSFORUMS_DEBUG - std::cerr << ". Not known yet. Adding current time as new TS." << std::endl; -#endif - mKnownForums[meta.mGroupId] = now; - IndicateConfigChanged(); - - return true; - } - else - { - bool used_by_friends = (now < it->second + FORUM_UNUSED_BY_FRIENDS_DELAY); - bool subscribed = static_cast(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - -#ifdef GXSFORUMS_DEBUG - std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)"; -#endif - - if(!subscribed && !used_by_friends) - { -#ifdef GXSFORUMS_DEBUG - std::cerr << ". Scheduling for deletion" << std::endl; -#endif - return false; - } - else - { -#ifdef GXSFORUMS_DEBUG - std::cerr << ". Keeping!" << std::endl; -#endif - return true; - } - } -} -bool p3GxsForums::getGroupData(const uint32_t &token, std::vector &groups) -{ - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsForumGroupItem* item = dynamic_cast(*vit); - if (item) - { - RsGxsForumGroup grp = item->mGroup; - grp.mMeta = item->meta; - delete item; - groups.push_back(grp); - } - else - { - std::cerr << "Not a GxsForumGrpItem, deleting!" << std::endl; - delete *vit; - } - } - } - return ok; -} - -bool p3GxsForums::getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas) -{ - return RsGenExchange::getMsgMeta(token, msg_metas); -} - -/* Okay - chris is not going to be happy with this... - * but I can't be bothered with crazy data structures - * at the moment - fix it up later - */ - -bool p3GxsForums::getMsgData(const uint32_t &token, std::vector &msgs) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsForumMsgItem* item = dynamic_cast(*vit); - - if(item) - { - RsGxsForumMsg msg = item->mMsg; - msg.mMeta = item->meta; - msgs.push_back(msg); - delete item; - } - else - { - std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - -bool p3GxsForums::createForumV2( - const std::string& name, const std::string& description, - const RsGxsId& authorId, const std::set& moderatorsIds, - RsGxsCircleType circleType, const RsGxsCircleId& circleId, - RsGxsGroupId& forumId, std::string& errorMessage ) -{ - auto createFail = [&](std::string mErr) - { - errorMessage = mErr; - RsErr() << __PRETTY_FUNCTION__ << " " << errorMessage << std::endl; - return false; - }; - - if(name.empty()) return createFail("Forum name is required"); - - if(!authorId.isNull() && !rsIdentity->isOwnId(authorId)) - return createFail("Author must be iether null or and identity owned by " - "this node"); - - switch(circleType) - { - case RsGxsCircleType::PUBLIC: // fallthrough - case RsGxsCircleType::LOCAL: // fallthrough - case RsGxsCircleType::YOUR_EYES_ONLY: - break; - case RsGxsCircleType::EXTERNAL: - if(circleId.isNull()) - return createFail("circleType is EXTERNAL but circleId is null"); - break; - case RsGxsCircleType::NODES_GROUP: - { - RsGroupInfo ginfo; - if(!rsPeers->getGroupInfo(RsNodeGroupId(circleId), ginfo)) - return createFail("circleType is NODES_GROUP but circleId does not " - "correspond to an actual group of friends"); - break; - } - default: return createFail("circleType has invalid value"); - } - - // Create a consistent channel group meta from the information supplied - RsGxsForumGroup forum; - - forum.mMeta.mGroupName = name; - forum.mMeta.mAuthorId = authorId; - forum.mMeta.mCircleType = static_cast(circleType); - - forum.mMeta.mSignFlags = GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ - | GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED; - - forum.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - - forum.mMeta.mCircleId.clear(); - forum.mMeta.mInternalCircle.clear(); - - switch(circleType) - { - case RsGxsCircleType::NODES_GROUP: - forum.mMeta.mInternalCircle = circleId; break; - case RsGxsCircleType::EXTERNAL: - forum.mMeta.mCircleId = circleId; break; - default: break; - } - - forum.mDescription = description; - forum.mAdminList.ids = moderatorsIds; - - uint32_t token; - if(!createGroup(token, forum)) - return createFail("Failed creating GXS group."); - - // wait for the group creation to complete. - RsTokenService::GxsRequestStatus wSt = - waitToken( token, std::chrono::milliseconds(5000), - std::chrono::milliseconds(20) ); - if(wSt != RsTokenService::COMPLETE) - return createFail( "GXS operation waitToken failed with: " - + std::to_string(wSt) ); - - if(!RsGenExchange::getPublishedGroupMeta(token, forum.mMeta)) - return createFail("Failure getting updated group data."); - - forumId = forum.mMeta.mGroupId; - - return true; -} - -bool p3GxsForums::createPost( - const RsGxsGroupId& forumId, const std::string& title, - const std::string& mBody, - const RsGxsId& authorId, const RsGxsMessageId& parentId, - const RsGxsMessageId& origPostId, RsGxsMessageId& postMsgId, - std::string& errorMessage ) -{ - RsGxsForumMsg post; - - auto failure = [&](std::string errMsg) - { - errorMessage = errMsg; - RsErr() << __PRETTY_FUNCTION__ << " " << errorMessage << std::endl; - return false; - }; - - if(title.empty()) return failure("Title is required"); - - if(authorId.isNull()) return failure("Author id is needed"); - - if(!rsIdentity->isOwnId(authorId)) - return failure( "Author id: " + authorId.toStdString() + " is not of" - "own identity" ); - - if(!parentId.isNull()) - { - std::vector msgs; - if( getForumContent(forumId, std::set({parentId}), msgs) - && msgs.size() == 1 ) - { - post.mMeta.mParentId = parentId; - post.mMeta.mThreadId = msgs[0].mMeta.mThreadId; - } - else return failure("Parent post " + parentId.toStdString() - + " doesn't exists locally"); - } - - std::vector forumInfo; - if(!getForumsInfo(std::list({forumId}), forumInfo)) - return failure( "Forum with Id " + forumId.toStdString() - + " does not exist locally." ); - - if(!origPostId.isNull()) - { - std::vector msgs; - if( getForumContent( forumId, - std::set({origPostId}), msgs) - && msgs.size() == 1 ) - post.mMeta.mOrigMsgId = origPostId; - else return failure("Original post " + origPostId.toStdString() - + " doesn't exists locally"); - } - - post.mMeta.mGroupId = forumId; - post.mMeta.mMsgName = title; - post.mMeta.mAuthorId = authorId; - post.mMsg = mBody; - - uint32_t token; - if( !createMsg(token, post) - || waitToken( - token, - std::chrono::milliseconds(5000) ) != RsTokenService::COMPLETE ) - return failure("Failure creating GXS message"); - - if(!RsGenExchange::getPublishedMsgMeta(token, post.mMeta)) - return failure("Failure getting created GXS message metadata"); - - postMsgId = post.mMeta.mMsgId; - return true; -} - -bool p3GxsForums::createForum(RsGxsForumGroup& forum) -{ - uint32_t token; - if(!createGroup(token, forum)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating group." - << std::endl; - return false; - } - - if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, forum.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated " - << " group data." << std::endl; - return false; - } - - return true; -} - -bool p3GxsForums::editForum(RsGxsForumGroup& forum) -{ - uint32_t token; - if(!updateGroup(token, forum)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group." - << std::endl; - return false; - } - - if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." - << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, forum.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated " - << " group data." << std::endl; - return false; - } - - return true; -} - -bool p3GxsForums::getForumsSummaries( std::list& forums ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token, opts) - || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; - return getGroupSummary(token, forums); -} - -bool p3GxsForums::getForumsInfo( const std::list& forumIds, std::vector& forumsInfo ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if(forumIds.empty()) - { - if( !requestGroupInfo(token, opts) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) - return false; - } - else - { - if( !requestGroupInfo(token, opts, forumIds, forumIds.size()==1) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) - return false; - } - return getGroupData(token, forumsInfo); -} - -bool p3GxsForums::getForumContent( - const RsGxsGroupId& forumId, - const std::set& msgs_to_request, - std::vector& msgs ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - GxsMsgReq msgIds; - msgIds[forumId] = msgs_to_request; - - if( !requestMsgInfo(token, opts, msgIds) || waitToken(token,std::chrono::seconds(5)) != RsTokenService::COMPLETE ) - return false; - - return getMsgData(token, msgs); -} - - -bool p3GxsForums::getForumMsgMetaData(const RsGxsGroupId& forumId, std::vector& msg_metas) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_META; - - GxsMsgMetaMap meta_map; - std::list forumIds; - forumIds.push_back(forumId); - - if( !requestMsgInfo(token, opts, forumIds) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; - - bool res = getMsgMetaData(token, meta_map); - - msg_metas = meta_map[forumId]; - - return res; -} - -bool p3GxsForums::markRead(const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t token; - setMessageReadStatus(token, msgId, read); - if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; - - RsGxsGrpMsgIdPair p; - acknowledgeMsg(token,p); - - return true; -} - -bool p3GxsForums::subscribeToForum(const RsGxsGroupId& groupId, bool subscribe ) -{ - uint32_t token; - if( !RsGenExchange::subscribeToGroup(token, groupId, subscribe) || waitToken(token) != RsTokenService::COMPLETE ) return false; - - RsGxsGroupId grp; - acknowledgeGrp(token,grp); - - return true; -} - -bool p3GxsForums::exportForumLink( - std::string& link, const RsGxsGroupId& forumId, bool includeGxsData, - const std::string& baseUrl, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(forumId.isNull()) return failure("forumId cannot be null"); - - const bool outputRadix = baseUrl.empty(); - if(outputRadix && !includeGxsData) return - failure("includeGxsData must be true if format requested is base64"); - - if( includeGxsData && - !RsGenExchange::exportGroupBase64(link, forumId, errMsg) ) - return failure(errMsg); - - if(outputRadix) return true; - - std::vector forumsInfo; - if( !getForumsInfo(std::list({forumId}), forumsInfo) - || forumsInfo.empty() ) - return failure("failure retrieving forum information"); - - RsUrl inviteUrl(baseUrl); - inviteUrl.setQueryKV(FORUM_URL_ID_FIELD, forumId.toStdString()); - inviteUrl.setQueryKV(FORUM_URL_NAME_FIELD, forumsInfo[0].mMeta.mGroupName); - if(includeGxsData) inviteUrl.setQueryKV(FORUM_URL_DATA_FIELD, link); - - link = inviteUrl.toString(); - return true; -} - -bool p3GxsForums::importForumLink( - const std::string& link, RsGxsGroupId& forumId, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(link.empty()) return failure("link is empty"); - - const std::string* radixPtr(&link); - - RsUrl url(link); - const auto& query = url.query(); - const auto qIt = query.find(FORUM_URL_DATA_FIELD); - if(qIt != query.end()) radixPtr = &qIt->second; - - if(radixPtr->empty()) return failure(FORUM_URL_DATA_FIELD + " is empty"); - - if(!RsGenExchange::importGroupBase64(*radixPtr, forumId, errMsg)) - return failure(errMsg); - - return true; -} - -std::error_condition p3GxsForums::getChildPosts( - const RsGxsGroupId& forumId, const RsGxsMessageId& parentId, - std::vector& childPosts ) -{ - RS_DBG3("forumId: ", forumId, " parentId: ", parentId); - - if(forumId.isNull() || parentId.isNull()) - return std::errc::invalid_argument; - - std::vector msgIds; - msgIds.push_back(RsGxsGrpMsgIdPair(forumId, parentId)); - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_PARENT | RS_TOKREQOPT_MSG_LATEST; - - uint32_t token; - if( !requestMsgRelatedInfo(token, opts, msgIds) || - waitToken(token) != RsTokenService::COMPLETE ) - return std::errc::timed_out; - - GxsMsgRelatedDataMap msgData; - if(!getMsgRelatedData(token, msgData)) - return std::errc::no_message_available; - - for(auto& mit: msgData) - { - for(auto& vit: mit.second) - { - auto msgItem = dynamic_cast(vit); - if(msgItem) - { - RsGxsForumMsg post = msgItem->mMsg; - post.mMeta = msgItem->meta; - childPosts.push_back(post); - } - else RS_WARN("Got item of unexpected type: ", vit); - - delete vit; - } - } - - return std::error_condition(); -} - -bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) -{ - std::cerr << "p3GxsForums::createGroup()" << std::endl; - - RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem(); - grpItem->mGroup = group; - grpItem->meta = group.mMeta; - - RsGenExchange::publishGroup(token, grpItem); - return true; -} - -bool p3GxsForums::getForumServiceStatistics(GxsServiceStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getServiceStatistic(token,stat); -} - -bool p3GxsForums::getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestGroupStatistic(token, ForumId) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getGroupStatistic(token,stat); -} - -bool p3GxsForums::updateGroup(uint32_t &token, const RsGxsForumGroup &group) -{ - std::cerr << "p3GxsForums::updateGroup()" << std::endl; - - - if(group.mMeta.mGroupId.isNull()) - return false; - - RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem(); - grpItem->mGroup = group; - grpItem->meta = group.mMeta; - - RsGenExchange::updateGroup(token, grpItem); - return true; -} - -bool p3GxsForums::createMessage(RsGxsForumMsg& message) -{ - uint32_t token; - if( !createMsg(token, message) - || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false; - - if(RsGenExchange::getPublishedMsgMeta(token, message.mMeta)) return true; - - return false; -} - -bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg) -{ - std::cerr << "p3GxsForums::createForumMsg() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - - RsGxsForumMsgItem* msgItem = new RsGxsForumMsgItem(); - msgItem->mMsg = msg; - msgItem->meta = msg.mMeta; - - RsGenExchange::publishMsg(token, msgItem); - return true; -} - - -/********************************************************************************************/ -/********************************************************************************************/ - -void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - if (read) - status = 0; - - setMsgStatusFlags(token, msgId, status, mask); - - /* WARNING: The event may be received before the operation is completed! - * TODO: move notification to blocking method markRead(...) which wait the - * operation to complete */ - if (rsEvents) - { - auto ev = std::make_shared(); - - ev->mForumMsgId = msgId.second; - ev->mForumGroupId = msgId.first; - ev->mForumEventCode = RsForumEventCode::READ_STATUS_CHANGED; - rsEvents->postEvent(ev); - } -} - -/********************************************************************************************/ -/********************************************************************************************/ - -std::error_condition p3GxsForums::setPostKeepForever( - const RsGxsGroupId& forumId, const RsGxsMessageId& postId, - bool keepForever ) -{ - if(forumId.isNull() || postId.isNull()) return std::errc::invalid_argument; - - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER; - uint32_t status = keepForever ? GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER : 0; - - uint32_t token; - setMsgStatusFlags(token, RsGxsGrpMsgIdPair(forumId, postId), status, mask); - - switch(waitToken(token)) - { - case RsTokenService::PENDING: // [[fallthrough]]; - case RsTokenService::PARTIAL: return std::errc::timed_out; - case RsTokenService::COMPLETE: // [[fallthrough]]; - case RsTokenService::DONE: - { - auto ev = std::make_shared(); - ev->mForumGroupId = forumId; - ev->mForumMsgId = postId; - ev->mForumEventCode = RsForumEventCode::UPDATED_MESSAGE; - rsEvents->postEvent(ev); - return std::error_condition(); - } - case RsTokenService::CANCELLED: return std::errc::operation_canceled; - default: return std::errc::bad_message; - } -} - -/* so we need the same tick idea as wiki for generating dummy forums - */ - -#define MAX_GEN_GROUPS 5 -#define MAX_GEN_MESSAGES 100 - -std::string p3GxsForums::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -bool p3GxsForums::generateDummyData() -{ - mGenCount = 0; - mGenRefs.resize(MAX_GEN_MESSAGES); - - std::string groupName; - rs_sprintf(groupName, "TestForum_%d", mGenCount); - - std::cerr << "p3GxsForums::generateDummyData() Starting off with Group: " << groupName; - std::cerr << std::endl; - - /* create a new group */ - generateGroup(mGenToken, groupName); - - mGenActive = true; - - return true; -} - - -void p3GxsForums::dummy_tick() -{ - /* check for a new callback */ - - if (mGenActive) - { - std::cerr << "p3GxsForums::dummyTick() AboutActive"; - std::cerr << std::endl; - - uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken); - if (status != RsTokenService::COMPLETE) - { - std::cerr << "p3GxsForums::dummy_tick() Status: " << status; - std::cerr << std::endl; - - if (status == RsTokenService::FAILED) - { - std::cerr << "p3GxsForums::dummy_tick() generateDummyMsgs() FAILED"; - std::cerr << std::endl; - mGenActive = false; - } - return; - } - - if (mGenCount < MAX_GEN_GROUPS) - { - /* get the group Id */ - RsGxsGroupId groupId; - RsGxsMessageId emptyId; - if (!acknowledgeTokenGrp(mGenToken, groupId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - - std::cerr << "p3GxsForums::dummy_tick() Acknowledged GroupId: " << groupId; - std::cerr << std::endl; - - ForumDummyRef ref(groupId, emptyId, emptyId); - mGenRefs[mGenCount] = ref; - } - else if (mGenCount < MAX_GEN_MESSAGES) - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mGenToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mGenActive = false; - return; - } - - std::cerr << "p3GxsForums::dummy_tick() Acknowledged "; - std::cerr << std::endl; - - /* store results for later selection */ - - ForumDummyRef ref(msgId.first, mGenThreadId, msgId.second); - mGenRefs[mGenCount] = ref; - } - else - { - std::cerr << "p3GxsForums::dummy_tick() Finished"; - std::cerr << std::endl; - - /* done */ - mGenActive = false; - return; - } - - mGenCount++; - - if (mGenCount < MAX_GEN_GROUPS) - { - std::string groupName; - rs_sprintf(groupName, "TestForum_%d", mGenCount); - - std::cerr << "p3GxsForums::dummy_tick() Generating Group: " << groupName; - std::cerr << std::endl; - - /* create a new group */ - generateGroup(mGenToken, groupName); - } - else - { - /* create a new message */ - uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32()); - ForumDummyRef &ref = mGenRefs[idx]; - - RsGxsGroupId grpId = ref.mGroupId; - RsGxsMessageId parentId = ref.mMsgId; - mGenThreadId = ref.mThreadId; - if (mGenThreadId.isNull()) - { - mGenThreadId = parentId; - } - - std::cerr << "p3GxsForums::dummy_tick() Generating Msg ... "; - std::cerr << " GroupId: " << grpId; - std::cerr << " ThreadId: " << mGenThreadId; - std::cerr << " ParentId: " << parentId; - std::cerr << std::endl; - - generateMessage(mGenToken, grpId, parentId, mGenThreadId); - } - } -} - - -bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId) -{ - RsGxsForumMsg msg; - - std::string rndId = genRandomId(); - - rs_sprintf(msg.mMsg, "Forum Msg: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s", - grpId.toStdString().c_str(), threadId.toStdString().c_str(), parentId.toStdString().c_str(), rndId.c_str()); - - msg.mMeta.mMsgName = msg.mMsg; - - msg.mMeta.mGroupId = grpId; - msg.mMeta.mThreadId = threadId; - msg.mMeta.mParentId = parentId; - - msg.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - - /* chose a random Id to sign with */ - std::list ownIds; - std::list::iterator it; - - rsIdentity->getOwnIds(ownIds); - - uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32()); - uint32_t i = 0; - for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); ++it, i++) ; - - if (it != ownIds.end()) - { - std::cerr << "p3GxsForums::generateMessage() Author: " << *it; - std::cerr << std::endl; - msg.mMeta.mAuthorId = *it; - } - else - { - std::cerr << "p3GxsForums::generateMessage() No Author!"; - std::cerr << std::endl; - } - - createMsg(token, msg); - - return true; -} - - -bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName) -{ - /* generate a new forum */ - RsGxsForumGroup forum; - forum.mMeta.mGroupName = groupName; - - createGroup(token, forum); - - return true; -} - - - // Overloaded from RsTickEvent for Event callbacks. -void p3GxsForums::handle_event(uint32_t event_type, const std::string &/*elabel*/) -{ - std::cerr << "p3GxsForums::handle_event(" << event_type << ")"; - std::cerr << std::endl; - - // stuff. - switch(event_type) - { - case FORUM_TESTEVENT_DUMMYDATA: - generateDummyData(); - break; - - default: - /* error */ - std::cerr << "p3GxsForums::handle_event() Unknown Event Type: " << event_type; - std::cerr << std::endl; - break; - } -} - -void RsGxsForumGroup::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mDescription); - - /* Work around to have usable JSON API, without breaking binary - * serialization retrocompatibility */ - switch (j) - { - case RsGenericSerializer::TO_JSON: // fallthrough - case RsGenericSerializer::FROM_JSON: - RsTypeSerializer::serial_process( j, ctx, - mAdminList.ids, "mAdminList" ); - RsTypeSerializer::serial_process( j, ctx, - mPinnedPosts.ids, "mPinnedPosts" ); - break; - default: - RS_SERIAL_PROCESS(mAdminList); - RS_SERIAL_PROCESS(mPinnedPosts); - } -} - -bool RsGxsForumGroup::canEditPosts(const RsGxsId& id) const -{ - return mAdminList.ids.find(id) != mAdminList.ids.end() || - id == mMeta.mAuthorId; -} - -/*static*/ const std::string RsGxsForums::DEFAULT_FORUM_BASE_URL = - "retroshare:///forums"; -/*static*/ const std::string RsGxsForums::FORUM_URL_NAME_FIELD = - "forumName"; -/*static*/ const std::string RsGxsForums::FORUM_URL_ID_FIELD = - "forumId"; -/*static*/ const std::string RsGxsForums::FORUM_URL_DATA_FIELD = - "forumData"; -/*static*/ const std::string RsGxsForums::FORUM_URL_MSG_TITLE_FIELD = - "forumMsgTitle"; -/*static*/ const std::string RsGxsForums::FORUM_URL_MSG_ID_FIELD = - "forumMsgId"; - -RsGxsForumGroup::~RsGxsForumGroup() = default; -RsGxsForumMsg::~RsGxsForumMsg() = default; -RsGxsForums::~RsGxsForums() = default; -RsGxsForumEvent::~RsGxsForumEvent() = default; diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h deleted file mode 100644 index 97f04cc7b..000000000 --- a/libretroshare/src/services/p3gxsforums.h +++ /dev/null @@ -1,192 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxsforums.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2018-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "retroshare/rsgxsforums.h" -#include "gxs/rsgenexchange.h" -#include "retroshare/rsgxscircles.h" -#include "util/rstickevent.h" -#include "util/rsdebug.h" - - -class p3GxsForums: public RsGenExchange, public RsGxsForums, public p3Config, - public RsTickEvent /* only needed for testing - remove after */ -{ -public: - p3GxsForums( - RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs); - - virtual RsServiceInfo getServiceInfo() override; - virtual void service_tick() override; - -protected: - virtual void notifyChanges(std::vector& changes) override; - /// Overloaded from RsTickEvent. - virtual void handle_event(uint32_t event_type, const std::string &elabel) override; - - virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser() - virtual bool saveList(bool &cleanup, std::list&saveList) override; // @see p3Config::saveList(bool &cleanup, std::list&) - virtual bool loadList(std::list& loadList) override; // @see p3Config::loadList(std::list&) - - virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override; - virtual rstime_t service_getLastGroupSeenTs(const RsGxsGroupId&) override; -public: - /// @see RsGxsForums::createForumV2 - bool createForumV2( - const std::string& name, const std::string& description, - const RsGxsId& authorId = RsGxsId(), - const std::set& moderatorsIds = std::set(), - RsGxsCircleType circleType = RsGxsCircleType::PUBLIC, - const RsGxsCircleId& circleId = RsGxsCircleId(), - RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsForums::createPost - bool createPost( - const RsGxsGroupId& forumId, - const std::string& title, - const std::string& mBody, - const RsGxsId& authorId, - const RsGxsMessageId& parentId = RsGxsMessageId(), - const RsGxsMessageId& origPostId = RsGxsMessageId(), - RsGxsMessageId& postMsgId = RS_DEFAULT_STORAGE_PARAM(RsGxsMessageId), - std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsForums::createForum @deprecated - RS_DEPRECATED_FOR(createForumV2) - virtual bool createForum(RsGxsForumGroup& forum) override; - - /// @see RsGxsForums::createMessage @deprecated - RS_DEPRECATED_FOR(createPost) - virtual bool createMessage(RsGxsForumMsg& message) override; - - /// @see RsGxsForums::editForum - virtual bool editForum(RsGxsForumGroup& forum) override; - - /// @see RsGxsForums::getForumsSummaries - virtual bool getForumsSummaries(std::list& forums) override; - - /// @see RsGxsForums::getForumsInfo - virtual bool getForumsInfo( - const std::list& forumIds, - std::vector& forumsInfo ) override; - - /// Implementation of @see RsGxsForums::getForumStatistics - bool getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) override; - - /// Implementation of @see RsGxsForums::getForumServiceStatistics - bool getForumServiceStatistics(GxsServiceStatistic& stat) override; - - /// @see RsGxsForums::getForumMsgMetaData - virtual bool getForumMsgMetaData(const RsGxsGroupId& forumId, std::vector& msg_metas) override; - - /// @see RsGxsForums::getForumContent - virtual bool getForumContent( - const RsGxsGroupId& forumId, - const std::set& msgs_to_request, - std::vector& msgs ) override; - - /// @see RsGxsForums::markRead - virtual bool markRead(const RsGxsGrpMsgIdPair& messageId, bool read) override; - - /// @see RsGxsForums::subscribeToForum - virtual bool subscribeToForum( const RsGxsGroupId& forumId, - bool subscribe ) override; - - /// @see RsGxsForums - bool exportForumLink( - std::string& link, const RsGxsGroupId& forumId, - bool includeGxsData = true, - const std::string& baseUrl = DEFAULT_FORUM_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsForums - bool importForumLink( - const std::string& link, - RsGxsGroupId& forumId = RS_DEFAULT_STORAGE_PARAM(RsGxsGroupId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsGxsForums - std::error_condition getChildPosts( - const RsGxsGroupId& forumId, const RsGxsMessageId& parentId, - std::vector& childPosts ) override; - - /// @see RsGxsForums - std::error_condition setPostKeepForever( - const RsGxsGroupId& forumId, const RsGxsMessageId& postId, - bool keepForever ) override; - - /// implementation of rsGxsGorums - /// - bool getGroupData(const uint32_t &token, std::vector &groups) override; - bool getMsgData(const uint32_t &token, std::vector &msgs) override; - void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override; - bool createGroup(uint32_t &token, RsGxsForumGroup &group) override; - bool createMsg(uint32_t &token, RsGxsForumMsg &msg) override; - bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) override; - - bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas) ; - -private: - -static uint32_t forumsAuthenPolicy(); - -virtual bool generateDummyData(); - -std::string genRandomId(); - -void dummy_tick(); - -bool generateMessage(uint32_t &token, const RsGxsGroupId &grpId, - const RsGxsMessageId &parentId, const RsGxsMessageId &threadId); -bool generateGroup(uint32_t &token, std::string groupName); - - class ForumDummyRef - { - public: - ForumDummyRef() { return; } - ForumDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId) - :mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; } - - RsGxsGroupId mGroupId; - RsGxsMessageId mThreadId; - RsGxsMessageId mMsgId; - }; - - uint32_t mGenToken; - bool mGenActive; - int mGenCount; - std::vector mGenRefs; - RsGxsMessageId mGenThreadId; - std::map mKnownForums ; - - RsMutex mKnownForumsMutex; -}; diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc deleted file mode 100644 index 4b7383a93..000000000 --- a/libretroshare/src/services/p3gxsreputation.cc +++ /dev/null @@ -1,1635 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxsreputation.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014-2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include "pqi/p3linkmgr.h" - -#include "retroshare/rspeers.h" - -#include "services/p3gxsreputation.h" - -#include "rsitems/rsgxsreputationitems.h" -#include "rsitems/rsconfigitems.h" - -#include - -#include - -/**** - * #define DEBUG_REPUTATION 1 - ****/ - -/************ IMPLEMENTATION NOTES ********************************* - * - * p3GxsReputation shares opinions / reputations with peers. - * This is closely linked to p3IdService, receiving info, updating - * reputations as needed. - * - * It is designed as separate service as the exchange of peer opinions - * is not well suited to Gxs Groups / Messages... - * - * Instead we can broadcast opinions to all peers. - * - * To avoid too much traffic, changes are transmitted rather than whole lists. - * Peer A Peer B - * last update -----------> - * <----------- modified opinions. - * - * 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. - * - * 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: - * [X] Opinions are saved/loaded accross restart - * [X] Opinions are transmitted to friends - * [X] Opinions are transmitted to friends when updated - * - * To do: - * [X] Add debug info - * [X] Test the whole thing - * [X] Implement a system to allow not storing info when we don't have it - */ - -//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 CLEANUP_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. Warning there's a 1 shift with what's shown in GUI. Be careful. -//static const uint32_t PGP_AUTO_BAN_THRESHOLD_DEFAULT = 2 ; // above this, auto ban any GXS id signed by this node -static const uint32_t IDENTITY_FLAGS_UPDATE_DELAY = 100 ; // -static const uint32_t BANNED_NODES_UPDATE_DELAY = 313 ; // update approx every 5 mins. Chosen to not be a multiple of IDENTITY_FLAGS_UPDATE_DELAY -static const uint32_t REPUTATION_INFO_KEEP_DELAY_DEFAULT = 86400*35; // remove old reputation info 5 days after last usage limit, in case the ID would come back.. -static const uint32_t BANNED_NODES_INACTIVITY_KEEP_DEFAULT = 86400*60; // remove all info about banned nodes after 2 months of inactivity - -static const uint32_t REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_POSITIVE = 1; // min difference in votes that makes friends opinion globally positive -static const uint32_t REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_NEGATIVE = 1; // min difference in votes that makes friends opinion globally negative -static const uint32_t MIN_DELAY_BETWEEN_REPUTATION_CONFIG_SAVE = 61 ; // never save more often than once a minute. - -p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) - :p3Service(), p3Config(), - mReputationMtx("p3GxsReputation"), mLinkMgr(lm) -{ - addSerialType(new RsGxsReputationSerialiser()); - - //mPgpAutoBanThreshold = PGP_AUTO_BAN_THRESHOLD_DEFAULT ; - mRequestTime = 0; - mStoreTime = 0; - mReputationsUpdated = false; - mLastIdentityFlagsUpdate = time(NULL) - 3; - mLastBannedNodesUpdate = 0 ; - mBannedNodesProxyNeedsUpdate = false; - - mAutoSetPositiveOptionToContacts = true; // default - mMinVotesForRemotelyPositive = REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_POSITIVE; - mMinVotesForRemotelyNegative = REPUTATION_DEFAULT_MIN_VOTES_FOR_REMOTELY_NEGATIVE; - - mLastReputationConfigSaved = 0; - mChanged = false ; - mMaxPreventReloadBannedIds = 0 ; // default is "never" - mLastCleanUp = time(NULL) ; -} - -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; -const uint16_t GXS_REPUTATION_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_REPUTATION_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3GxsReputation::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_REPUTATION, - GXS_REPUTATION_APP_NAME, - GXS_REPUTATION_APP_MAJOR_VERSION, - GXS_REPUTATION_APP_MINOR_VERSION, - GXS_REPUTATION_MIN_MAJOR_VERSION, - GXS_REPUTATION_MIN_MINOR_VERSION); -} - -int p3GxsReputation::tick() -{ - processIncoming(); - sendPackets(); - - rstime_t now = time(NULL); - - if(mLastCleanUp + CLEANUP_PERIOD < now) - { - cleanup() ; - - mLastCleanUp = now ; - } - - // no more than once per 5 second chunk. - - if(now > IDENTITY_FLAGS_UPDATE_DELAY+mLastIdentityFlagsUpdate) - { - updateStaticIdentityFlags() ; - mLastIdentityFlagsUpdate = now ; - } - if(now > BANNED_NODES_UPDATE_DELAY+mLastBannedNodesUpdate) // 613 is not a multiple of 100, to avoid piling up work - { - updateStaticIdentityFlags() ; // needed before updateBannedNodesList! - updateBannedNodesProxy(); - mLastBannedNodesUpdate = now ; - } - - if(mBannedNodesProxyNeedsUpdate) - { - updateBannedNodesProxy(); - mBannedNodesProxyNeedsUpdate = false ; - } - -#ifdef DEBUG_REPUTATION - static rstime_t last_debug_print = time(NULL) ; - - if(now > 10+last_debug_print) - { - last_debug_print = now ; - debug_print() ; - } -#endif - - if(mChanged && now > mLastReputationConfigSaved + MIN_DELAY_BETWEEN_REPUTATION_CONFIG_SAVE) - { - IndicateConfigChanged() ; - mLastReputationConfigSaved = now ; - mChanged = false ; - } - - return 0; -} - -void p3GxsReputation::setAutoPositiveOpinionForContacts(bool b) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - if(b != mAutoSetPositiveOptionToContacts) - { - mLastIdentityFlagsUpdate = 0 ; - mLastCleanUp = 0 ; - mAutoSetPositiveOptionToContacts = b ; - - IndicateConfigChanged() ; - } -} -bool p3GxsReputation::autoPositiveOpinionForContacts() -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - return mAutoSetPositiveOptionToContacts ; -} - -void p3GxsReputation::setRememberBannedIdThreshold(uint32_t days) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - if(mMaxPreventReloadBannedIds != days*86400) - { - mMaxPreventReloadBannedIds = days*86400 ; - IndicateConfigChanged(); - } -} -uint32_t p3GxsReputation::rememberBannedIdThreshold() -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - return mMaxPreventReloadBannedIds/86400; -} - -int p3GxsReputation::status() -{ - return 1; -} -class ZeroInitCnt -{ - public: - ZeroInitCnt(): cnt(0) {} - uint32_t cnt ; - - operator uint32_t& () { return cnt ; } - operator uint32_t() const { return cnt ; } -}; - -void p3GxsReputation::updateBannedNodesProxy() -{ - // This function keeps the Banned GXS id proxy up to date. - // - - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - mPerNodeBannedIdsProxy.clear(); - - for( std::map::iterator rit = mBannedPgpIds.begin();rit!=mBannedPgpIds.end();++rit) - for(std::set::const_iterator it(rit->second.known_identities.begin());it!=rit->second.known_identities.end();++it) - mPerNodeBannedIdsProxy.insert(*it) ; -} - -void p3GxsReputation::updateStaticIdentityFlags() -{ - // This function is the *only* place where rsIdentity is called. Normally the cross calls between p3IdService and p3GxsReputations should only - // happen one way: from rsIdentity to rsReputations. Still, reputations need to keep track of some identity flags. It's very important to make sure that - // rsIdentity is not called inside a mutex-protected zone, because normally calls happen in the other way. - - 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_UP_TO_DATE)) && (mPerNodeBannedIdsProxy.find(rit->first) == mPerNodeBannedIdsProxy.end())) - 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 = REPUTATION_IDENTITY_FLAG_UP_TO_DATE ; // resets the NEEDS_UPDATE flag. All other flags set later on. - - if(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) - { - it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ; - it->second.mOwnerNode = details.mPgpId ; - } - if(details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN ) 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() ; - mChanged = true ; - } - } -} - -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 - rstime_t now = time(NULL) ; - - // We should keep opinions about identities that do not exist anymore, but only rely on the usage TS. That will in particular avoid asking p3idservice about deleted - // identities, which would cause an excess of hits to the database. We do it in two steps to avoid a deadlock when calling rsIdentity from here. - // Also, neutral opinions for banned PGP linked nodes are kept, so as to be able to not request them again. - - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - for(std::map::iterator it(mReputations.begin());it!=mReputations.end();) - { - bool should_delete = false ; - - if( it->second.mOwnOpinion == - static_cast(RsOpinion::NEGATIVE) && - mMaxPreventReloadBannedIds != 0 && - it->second.mOwnOpinionTs + mMaxPreventReloadBannedIds < now ) - { -#ifdef DEBUG_REPUTATION - std::cerr << " ID " << it->first << ": own is negative for more than " << mMaxPreventReloadBannedIds/86400 << " days. Reseting it!" << std::endl; -#endif - should_delete = true; - } - - // Delete slots with basically no information - - if( it->second.mOpinions.empty() && - it->second.mOwnOpinion == - static_cast(RsOpinion::NEUTRAL) && - it->second.mOwnerNode.isNull() ) - { -#ifdef DEBUG_REPUTATION - std::cerr << " ID " << it->first << ": own is neutral and no opinions from friends => remove entry" << std::endl; -#endif - should_delete = true ; - } - - // Delete slots that havn't been used for a while. The else below is here for debug display purposes, and not harmful since both conditions lead the same effect. - - else if(it->second.mLastUsedTS + REPUTATION_INFO_KEEP_DELAY_DEFAULT < now) - { -#ifdef DEBUG_REPUTATION - std::cerr << " ID " << it->first << ": no request for reputation for more than " << REPUTATION_INFO_KEEP_DELAY_DEFAULT/86400 << " days => deleting." << std::endl; -#endif - should_delete = true ; - } -#ifdef DEBUG_REPUTATION - else - std::cerr << " ID " << it->first << ": flags=" << std::hex << it->second.mIdentityFlags << std::dec << ". Last used: " << (now - it->second.mLastUsedTS)/86400 << " days ago: kept." << std::endl; -#endif - - if(should_delete) - { - std::map::iterator tmp(it) ; - ++tmp ; - mReputations.erase(it) ; - it = tmp ; - mChanged = true ; - } - else - ++it; - } - } - - // Clean up of the banned PGP ids. - - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - for(std::map::iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();) - if(it->second.last_activity_TS + BANNED_NODES_INACTIVITY_KEEP_DEFAULT < now) - { -#ifdef DEBUG_REPUTATION - std::cerr << " Removing all info about banned node " << it->first << " by lack of activity." << std::endl; -#endif - std::map::iterator tmp(it ) ; - ++tmp ; - mBannedPgpIds.erase(it) ; - it = tmp ; - - mChanged = true ; - } - else - ++it ; - } - - // Update opinions based on flags and contact information. - // Note: the call to rsIdentity->isARegularContact() is done off-mutex, in order to avoid a cross-deadlock, as - // normally, p3GxsReputation gets called by p3dentity and not te reverse. That explains the weird implementation - // of these two loops. - { - std::list should_set_to_positive_candidates ; - - if(mAutoSetPositiveOptionToContacts) - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - for(std::map::iterator it(mReputations.begin());it!=mReputations.end();++it) - if( it->second.mOwnOpinion == - static_cast(RsOpinion::NEUTRAL) ) - should_set_to_positive_candidates.push_back(it->first) ; - } - - for(std::list::const_iterator it(should_set_to_positive_candidates.begin());it!=should_set_to_positive_candidates.end();++it) - if(rsIdentity->isARegularContact(*it)) - setOwnOpinion(*it, RsOpinion::POSITIVE); - } -} - -static RsOpinion safe_convert_uint32t_to_opinion(uint32_t op) -{ - return RsOpinion(std::min( static_cast(op), UPPER_LIMIT )); -} -/***** Implementation ******/ - -bool p3GxsReputation::processIncoming() -{ - /* for each packet - pass to specific handler */ - RsItem *item = NULL; - while(NULL != (item = recvItem())) - { -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::processingIncoming() Received Item:"; - std::cerr << std::endl; - item->print(std::cerr); - std::cerr << std::endl; -#endif - bool itemOk = true; - switch(item->PacketSubType()) - { - default: - 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_GXS_REPUTATION_REQUEST_ITEM: - { - RsGxsReputationRequestItem *requestItem = dynamic_cast(item); - if (requestItem) - SendReputations(requestItem); - else - itemOk = false; - } - break; - - case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM: - { - RsGxsReputationUpdateItem *updateItem = dynamic_cast(item); - - if (updateItem) - RecvReputations(updateItem); - else - itemOk = false; - } - break; - } - - if (!itemOk) - { - std::cerr << "p3GxsReputation::processingIncoming() Error with Item"; - std::cerr << std::endl; - } - - /* clean up */ - delete item; - } - return true ; -} - - -bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) -{ -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::SendReputations()" << std::endl; -#endif - - RsPeerId peerId = request->PeerId(); - rstime_t last_update = request->mLastUpdate; - rstime_t now = time(NULL); - - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - std::multimap::iterator tit; - tit = mUpdated.upper_bound(last_update); // could skip some - (fixed below). - - int count = 0; - int totalcount = 0; - RsGxsReputationUpdateItem *pkt = new RsGxsReputationUpdateItem(); - - pkt->PeerId(peerId); - for(;tit != mUpdated.end(); ++tit) - { - /* find */ - std::map::iterator rit = mReputations.find(tit->second); - - if (rit == mReputations.end()) - { - std::cerr << "p3GxsReputation::SendReputations() ERROR Missing Reputation"; - std::cerr << std::endl; - // error. - continue; - } - - if (rit->second.mOwnOpinionTs == 0) - { - std::cerr << "p3GxsReputation::SendReputations() ERROR OwnOpinionTS = 0"; - std::cerr << std::endl; - // error. - continue; - } - - RsGxsId gxsId = rit->first; - 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). - // then set Update back one second to ensure there are none missed. - pkt->mLatestUpdate--; - } - - count++; - totalcount++; - - 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; - } - } - - if (!pkt->mOpinions.empty()) - { -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::SendReputations() Sending Final Packet"; - std::cerr << std::endl; -#endif - - sendItem(pkt); - } - else - { - 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, RsOpinion op ) -{ - /* find matching Reputation */ - std::map::iterator rit = mReputations.find(about); - - RsOpinion new_opinion = op; - RsOpinion old_opinion = RsOpinion::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 != RsOpinion::NEUTRAL) - { - mReputations[about] = Reputation(); - 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 != RsOpinion::NEUTRAL) - { - reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend - updated = true ; - } - } - else - { - old_opinion = it2->second ; - - if(new_opinion == RsOpinion::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 == static_cast(RsOpinion::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) -{ -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::RecvReputations() from " << item->PeerId() << std::endl; -#endif - - RsPeerId peerid = item->PeerId(); - - for( std::map::iterator it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it) - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - locked_updateOpinion(peerid,it->first,safe_convert_uint32t_to_opinion(it->second)); - } - - updateLatestUpdate(peerid,item->mLatestUpdate); - - return true; -} - - -bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,rstime_t latest_update) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - std::map::iterator it = mConfig.find(peerid); - - if (it == mConfig.end()) - { - mConfig[peerid] = ReputationConfig(peerid); - it = mConfig.find(peerid) ; - } - it->second.mLatestUpdate = latest_update ; - - mReputationsUpdated = true; - // Switched to periodic save due to scale of data. - - IndicateConfigChanged(); - - return true; -} - -/******************************************************************** - * Opinion - ****/ - -RsReputationLevel p3GxsReputation::overallReputationLevel( - const RsGxsId& id, uint32_t* identity_flags ) -{ - RsReputationInfo info ; - getReputationInfo(id,RsPgpId(),info) ; - - RsPgpId owner_id ; - - if(identity_flags) - getIdentityFlagsAndOwnerId(id,*identity_flags,owner_id); - - return info.mOverallReputationLevel ; -} - -bool p3GxsReputation::getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t& identity_flags,RsPgpId& owner_id) -{ - if(gxsid.isNull()) - return false ; - - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - std::map::iterator it = mReputations.find(gxsid) ; - - if(it == mReputations.end()) - return false ; - - if(!(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_UP_TO_DATE)) - return false ; - - if(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) - identity_flags |= RS_IDENTITY_FLAGS_PGP_LINKED ; - - if(it->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_KNOWN) - identity_flags |= RS_IDENTITY_FLAGS_PGP_KNOWN ; - - owner_id = it->second.mOwnerNode ; - - return true ; -} - -bool p3GxsReputation::getReputationInfo( - const RsGxsId& gxsid, const RsPgpId& ownerNode, RsReputationInfo& info, - bool stamp ) -{ - if(gxsid.isNull()) - return false ; - - rstime_t now = time(nullptr); - - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_REPUTATION2 - std::cerr << "getReputationInfo() for " << gxsid << ", stamp = " << stamp << std::endl; -#endif - std::map::iterator it = mReputations.find(gxsid) ; - RsPgpId owner_id ; - - if(it == mReputations.end()) - { - info.mOwnOpinion = RsOpinion::NEUTRAL ; - info.mFriendAverageScore = RS_REPUTATION_THRESHOLD_DEFAULT ; - info.mFriendsNegativeVotes = 0 ; - info.mFriendsPositiveVotes = 0 ; - - owner_id = ownerNode ; - } - else - { - Reputation& rep(it->second) ; - - info.mOwnOpinion = - safe_convert_uint32t_to_opinion( - static_cast(rep.mOwnOpinion) ); - info.mFriendAverageScore = rep.mFriendAverage ; - info.mFriendsNegativeVotes = rep.mFriendsNegative ; - info.mFriendsPositiveVotes = rep.mFriendsPositive ; - - if(rep.mOwnerNode.isNull() && !ownerNode.isNull()) - rep.mOwnerNode = ownerNode ; - - owner_id = rep.mOwnerNode ; - - if(stamp) - rep.mLastUsedTS = now ; - - mChanged = true ; - } - - // now compute overall score and reputation - - // 0 - check for own opinion. If positive or negative, it decides on the result - - if(info.mOwnOpinion == RsOpinion::NEGATIVE) - { - // own opinion is always read in priority - - info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE; - return true ; - } - if(info.mOwnOpinion == RsOpinion::POSITIVE) - { - // own opinion is always read in priority - - info.mOverallReputationLevel = RsReputationLevel::LOCALLY_POSITIVE; - return true ; - } - - // 1 - check for banned PGP ids. - - std::map::iterator it2 ; - - if(!owner_id.isNull() && (it2 = mBannedPgpIds.find(owner_id))!=mBannedPgpIds.end()) - { - // Check if current identity is present in the list of known identities for this banned node. - - if(it2->second.known_identities.find(gxsid) == it2->second.known_identities.end()) - { - it2->second.known_identities.insert(gxsid) ; - it2->second.last_activity_TS = now ; - - // if so, update - - mBannedNodesProxyNeedsUpdate = true ; - } - -#ifdef DEBUG_REPUTATION2 - std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in banned nodes list)." << std::endl; -#endif - info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE; - return true ; - } - // also check the proxy - - if(mPerNodeBannedIdsProxy.find(gxsid) != mPerNodeBannedIdsProxy.end()) - { -#ifdef DEBUG_REPUTATION2 - std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << owner_id << " is banned (found in proxy)." << std::endl; -#endif - info.mOverallReputationLevel = RsReputationLevel::LOCALLY_NEGATIVE; - return true; - } - // 2 - now, our own opinion is neutral, which means we rely on what our friends tell - - if(info.mFriendsPositiveVotes >= info.mFriendsNegativeVotes + mMinVotesForRemotelyPositive) - info.mOverallReputationLevel = RsReputationLevel::REMOTELY_POSITIVE; - else if(info.mFriendsPositiveVotes + mMinVotesForRemotelyNegative <= info.mFriendsNegativeVotes) - info.mOverallReputationLevel = RsReputationLevel::REMOTELY_NEGATIVE; - else - info.mOverallReputationLevel = RsReputationLevel::NEUTRAL; - -#ifdef DEBUG_REPUTATION2 - std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", owner node=" << owner_id << ", overall score=" << info.mAssessment << std::endl; -#endif - - return true ; -} - -uint32_t p3GxsReputation::thresholdForRemotelyNegativeReputation() -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - return mMinVotesForRemotelyNegative ; -} -uint32_t p3GxsReputation::thresholdForRemotelyPositiveReputation() -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - return mMinVotesForRemotelyPositive ; -} -void p3GxsReputation::setThresholdForRemotelyPositiveReputation(uint32_t thresh) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - if(mMinVotesForRemotelyPositive == thresh || thresh==0) - return ; - - mMinVotesForRemotelyPositive = thresh ; - IndicateConfigChanged(); -} - -void p3GxsReputation::setThresholdForRemotelyNegativeReputation(uint32_t thresh) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - if(mMinVotesForRemotelyNegative == thresh || thresh==0) - return ; - - mMinVotesForRemotelyNegative = thresh ; - IndicateConfigChanged(); -} - -void p3GxsReputation::banNode(const RsPgpId& id,bool b) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - if(b) - { - if(mBannedPgpIds.find(id) == mBannedPgpIds.end()) - { - mBannedPgpIds[id] = BannedNodeInfo() ; - IndicateConfigChanged(); - } - } - else - { - if(mBannedPgpIds.find(id) != mBannedPgpIds.end()) - { - mBannedPgpIds.erase(id) ; - IndicateConfigChanged(); - } - } -} - -RsReputationLevel p3GxsReputation::overallReputationLevel(const RsGxsId& id) -{ return overallReputationLevel(id, nullptr); } - -bool p3GxsReputation::isNodeBanned(const RsPgpId& id) -{ - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - return mBannedPgpIds.find(id) != mBannedPgpIds.end(); -} - -bool p3GxsReputation::isIdentityBanned(const RsGxsId &id) -{ - RsReputationInfo info; - - if(!getReputationInfo(id,RsPgpId(),info)) - return false ; - -#ifdef DEBUG_REPUTATION - std::cerr << "isIdentityBanned(): returning " << (info.mOverallReputationLevel == RsReputations::REPUTATION_LOCALLY_NEGATIVE) << " for GXS id " << id << std::endl; -#endif - return info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE; -} - -bool p3GxsReputation::getOwnOpinion( - const RsGxsId& gxsid, RsOpinion& 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 ; - } - - RS_STACK_MUTEX(mReputationMtx); - - std::map::iterator rit = mReputations.find(gxsid); - - if(rit != mReputations.end()) - opinion = safe_convert_uint32t_to_opinion( - static_cast(rit->second.mOwnOpinion) ); - else - opinion = RsOpinion::NEUTRAL; - - return true; -} - -bool p3GxsReputation::setOwnOpinion( - const RsGxsId& gxsid, RsOpinion 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 ; - } - - RS_STACK_MUTEX(mReputationMtx); - - std::map::iterator rit; - - /* find matching Reputation */ - rit = mReputations.find(gxsid); - - if (rit == mReputations.end()) - { -#warning csoler 2017-01-05: We should set the owner node id here. - mReputations[gxsid] = Reputation(); - rit = mReputations.find(gxsid); - } - - // we should remove previous entries from Updates... - Reputation &reputation = rit->second; - if (reputation.mOwnOpinionTs != 0) - { - if (reputation.mOwnOpinion == static_cast(opinion)) - { - // if opinion is accurate, don't update. - return false; - } - - std::multimap::iterator uit, euit; - uit = mUpdated.lower_bound(reputation.mOwnOpinionTs); - euit = mUpdated.upper_bound(reputation.mOwnOpinionTs); - for(; uit != euit; ++uit) - { - if (uit->second == gxsid) - { - mUpdated.erase(uit); - break; - } - } - } - - rstime_t now = time(nullptr); - reputation.mOwnOpinion = static_cast(opinion); - reputation.mOwnOpinionTs = now; - reputation.updateReputation(); - - mUpdated.insert(std::make_pair(now, gxsid)); - mReputationsUpdated = true; - mLastBannedNodesUpdate = 0 ; // for update of banned nodes - - // Switched to periodic save due to scale of data. - IndicateConfigChanged(); - - return true; -} - - -/******************************************************************** - * Configuration. - ****/ - -RsSerialiser *p3GxsReputation::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsGxsReputationSerialiser()); - rss->addSerialType(new RsGeneralConfigSerialiser()); - return rss ; -} - -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) - { - if (!rsPeers->isFriend(it->first)) - { - // discard info from non-friends. - continue; - } - - RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem(); - item->mPeerId = it->first; - item->mLatestUpdate = it->second.mLatestUpdate; - item->mLastQuery = it->second.mLastQuery; - savelist.push_back(item); - } - - int count = 0; - std::map::iterator rit; - for(rit = mReputations.begin(); rit != mReputations.end(); ++rit, count++) - { - RsGxsReputationSetItem *item = new RsGxsReputationSetItem(); - item->mGxsId = rit->first; - item->mOwnOpinion = rit->second.mOwnOpinion; - item->mOwnOpinionTS = rit->second.mOwnOpinionTs; - item->mIdentityFlags = rit->second.mIdentityFlags; - item->mOwnerNodeId = rit->second.mOwnerNode; - item->mLastUsedTS = rit->second.mLastUsedTS; - - std::map::iterator oit; - for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit) - { - // should be already limited. - item->mOpinions[oit->first] = (uint32_t)oit->second; - } - - savelist.push_back(item); - count++; - } - - for(std::map::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it) - { - RsGxsReputationBannedNodeSetItem *item = new RsGxsReputationBannedNodeSetItem(); - - item->mPgpId = it->first ; - item->mLastActivityTS = it->second.last_activity_TS; - item->mKnownIdentities.ids = it->second.known_identities; - - savelist.push_back(item) ; - } - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - - kv.key = "AUTO_REMOTELY_POSITIVE_THRESHOLD" ; - rs_sprintf(kv.value, "%d", mMinVotesForRemotelyPositive); - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "AUTO_REMOTELY_NEGATIVE_THRESHOLD" ; - rs_sprintf(kv.value, "%d", mMinVotesForRemotelyNegative); - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "AUTO_POSITIVE_CONTACTS" ; - kv.value = mAutoSetPositiveOptionToContacts?"YES":"NO"; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "MAX_PREVENT_RELOAD_BANNED_IDS" ; - rs_sprintf(kv.value, "%d", mMaxPreventReloadBannedIds) ; - vitem->tlvkvs.pairs.push_back(kv) ; - - savelist.push_back(vitem) ; - - return true; -} - -void p3GxsReputation::saveDone() -{ - return; -} - -bool p3GxsReputation::loadList(std::list& loadList) -{ -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::loadList()" << 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) - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - RsPeerId peerId(item->mPeerId); - ReputationConfig &config = mConfig[peerId]; - config.mPeerId = peerId; - config.mLatestUpdate = item->mLatestUpdate; - config.mLastQuery = 0; - - peerSet.insert(peerId); - } - - RsGxsReputationSetItem *set = dynamic_cast(*it); - - if (set) - loadReputationSet(set, peerSet); - -#ifdef TO_REMOVE - RsGxsReputationSetItem_deprecated3 *set2 = dynamic_cast(*it); - - if(set2) - { - std::cerr << "(II) reading and converting old format ReputationSetItem." << std::endl; - loadReputationSet_deprecated3(set2, peerSet); - } -#endif - - RsGxsReputationBannedNodeSetItem *itm2 = dynamic_cast(*it) ; - - if(itm2 != NULL) - { - BannedNodeInfo& info(mBannedPgpIds[itm2->mPgpId]) ; - info.last_activity_TS = itm2->mLastActivityTS ; - info.known_identities = itm2->mKnownIdentities.ids ; - } - - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - - if(vitem) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if(kit->key == "AUTO_REMOTELY_POSITIVE_THRESHOLD") - { - int val ; - if (sscanf(kit->value.c_str(), "%d", &val) == 1) - { - mMinVotesForRemotelyPositive = val ; - std::cerr << "Setting mMinVotesForRemotelyPositive threshold to " << val << std::endl ; - } - }; - if(kit->key == "AUTO_REMOTELY_NEGATIVE_THRESHOLD") - { - int val ; - if (sscanf(kit->value.c_str(), "%d", &val) == 1) - { - mMinVotesForRemotelyNegative = val ; - std::cerr << "Setting mMinVotesForRemotelyNegative threshold to " << val << std::endl ; - } - }; - if(kit->key == "AUTO_POSITIVE_CONTACTS") - { - mAutoSetPositiveOptionToContacts = (kit->value == "YES"); - std::cerr << "Setting AutoPositiveContacts to " << kit->value << std::endl ; - mLastBannedNodesUpdate = 0 ; // force update - } - if(kit->key == "MAX_PREVENT_RELOAD_BANNED_IDS" ) - { - int val ; - if (sscanf(kit->value.c_str(), "%d", &val) == 1) - { - mMaxPreventReloadBannedIds = val ; - std::cerr << "Setting mMaxPreventReloadBannedIds threshold to " << val << std::endl ; - } - } - } - - delete (*it); - } - - updateBannedNodesProxy(); - loadList.clear() ; - return true; -} -#ifdef TO_REMOVE -bool p3GxsReputation::loadReputationSet_deprecated3(RsGxsReputationSetItem_deprecated3 *item, const std::set &peerSet) -{ - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - 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); - if (rit != mReputations.end()) - { - std::cerr << "ERROR"; - std::cerr << std::endl; - } - - Reputation &reputation = mReputations[gxsId]; - - // install opinions. - 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] = safe_convert_uint32t_to_opinion(oit->second); - } - - reputation.mOwnOpinion = item->mOwnOpinion; - reputation.mOwnOpinionTs = item->mOwnOpinionTS; - reputation.mOwnerNode = item->mOwnerNodeId; - reputation.mIdentityFlags = item->mIdentityFlags & (~REPUTATION_IDENTITY_FLAG_UP_TO_DATE); - reputation.mLastUsedTS = time(NULL); - - // if dropping entries has changed the score -> must update. - - reputation.updateReputation() ; - - mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId)); - } -#ifdef DEBUG_REPUTATION - RsReputations::ReputationInfo info ; - getReputationInfo(item->mGxsId,item->mOwnerNodeId,info) ; - std::cerr << item->mGxsId << " : own: " << info.mOwnOpinion << ", owner node: " << item->mOwnerNodeId << ", overall level: " << info.mOverallReputationLevel << std::endl; -#endif - return true; -} -#endif - -bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std::set &peerSet) -{ - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - 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); - if (rit != mReputations.end()) - { - std::cerr << "ERROR"; - std::cerr << std::endl; - } - - Reputation &reputation = mReputations[gxsId]; - - // install opinions. - 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] = safe_convert_uint32t_to_opinion(oit->second); - } - - reputation.mOwnOpinion = item->mOwnOpinion; - reputation.mOwnOpinionTs = item->mOwnOpinionTS; - reputation.mOwnerNode = item->mOwnerNodeId; - reputation.mIdentityFlags = item->mIdentityFlags; - reputation.mLastUsedTS = item->mLastUsedTS; - - // if dropping entries has changed the score -> must update. - - reputation.updateReputation() ; - - mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId)); - } -#ifdef DEBUG_REPUTATION - RsReputations::ReputationInfo info ; - getReputationInfo(item->mGxsId,item->mOwnerNodeId,info,false) ; - std::cerr << item->mGxsId << " : own: " << info.mOwnOpinion << ", owner node: " << item->mOwnerNodeId << ", level: " << info.mOverallReputationLevel << std::endl; -#endif - return true; -} - - -/******************************************************************** - * Send Requests. - ****/ - -int p3GxsReputation::sendPackets() -{ - rstime_t now = time(NULL); - rstime_t requestTime, storeTime; - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - requestTime = mRequestTime; - storeTime = mStoreTime; - } - - if (now > requestTime + kReputationRequestPeriod) - { - sendReputationRequests(); - - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendPackets() Regular Broadcast"; - std::cerr << std::endl; -#endif - mRequestTime = now; - mStoreTime = now + kReputationStoreWait; - } - - if (now > storeTime) - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendPackets() Regular Broadcast"; - std::cerr << std::endl; -#endif - // push it into the future. - // store time will be reset when requests are send. - mStoreTime = now + kReputationRequestPeriod; - - if (mReputationsUpdated) - { - IndicateConfigChanged(); - mReputationsUpdated = false; - } - } - - return true ; -} - -void p3GxsReputation::sendReputationRequests() -{ - /* we ping our peers */ - /* who is online? */ - std::list idList; - - mLinkMgr->getOnlineList(idList); - - /* prepare packets */ - std::list::iterator it; - for(it = idList.begin(); it != idList.end(); ++it) - sendReputationRequest(*it); -} - -int p3GxsReputation::sendReputationRequest(RsPeerId peerid) -{ -#ifdef DEBUG_REPUTATION - rstime_t now = time(NULL) ; - std::cerr << " p3GxsReputation::sendReputationRequest(" << peerid << ") " ; -#endif - - /* */ - RsGxsReputationRequestItem *requestItem = new RsGxsReputationRequestItem(); - requestItem->PeerId(peerid); - - { - RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - - /* find the last timestamp we have */ - 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; - } - } - - sendItem(requestItem); - return 1; -} - -void Reputation::updateReputation() -{ - // the calculation of reputation makes the whole thing - - int friend_total = 0; - - mFriendsNegative = 0 ; - mFriendsPositive = 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 ) - { - if( it->second == RsOpinion::NEGATIVE) - ++mFriendsNegative ; - - if( it->second == RsOpinion::POSITIVE) - ++mFriendsPositive ; - - friend_total += static_cast(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 == static_cast(RsOpinion::NEUTRAL)) - mReputationScore = mFriendAverage; - else mReputationScore = static_cast(mOwnOpinion); -} - -void p3GxsReputation::debug_print() -{ - std::cerr << "Reputations database: " << std::endl; - std::cerr << " GXS ID data: " << std::endl; - std::cerr << std::dec ; - - std::map rep_copy; - - { - RS_STACK_MUTEX(mReputationMtx); - rep_copy = mReputations; - } - - rstime_t now = time(nullptr); - - - for( std::map::const_iterator it(rep_copy.begin()); - it != rep_copy.end(); ++it ) - { - RsReputationInfo info; - getReputationInfo(it->first, RsPgpId(), info, false); - uint32_t lev = static_cast(info.mOverallReputationLevel); - - std::cerr << " " << it->first << ": own: " << it->second.mOwnOpinion - << ", PGP id=" << it->second.mOwnerNode - << ", flags=" << std::setfill('0') << std::setw(4) << std::hex << it->second.mIdentityFlags << std::dec - << ", Friend pos/neg: " << it->second.mFriendsPositive << "/" << it->second.mFriendsNegative - << ", reputation lev: [" << lev - << "], last own update: " << std::setfill(' ') << std::setw(10) << now - it->second.mOwnOpinionTs << " secs ago" - << ", last needed: " << std::setfill(' ') << std::setw(10) << now - it->second.mLastUsedTS << " secs ago, " - << std::endl; - -#ifdef DEBUG_REPUTATION2 - for(std::map::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2) - std::cerr << " " << it2->first << ": " << it2->second << std::endl; -#endif - } - - RS_STACK_MUTEX(mReputationMtx); - std::cerr << " Banned RS nodes by ID: " << std::endl; - - for(std::map::const_iterator it(mBannedPgpIds.begin());it!=mBannedPgpIds.end();++it) - { - std::cerr << " Node " << it->first << ", last activity: " << now - it->second.last_activity_TS << " secs ago." << std::endl; - - for(std::set::const_iterator it2(it->second.known_identities.begin());it2!=it->second.known_identities.end();++it2) - std::cerr << " " << *it2 << std::endl; - } - - std::cerr << " Per node Banned GXSIds proxy: " << std::endl; - - for(std::set::const_iterator it(mPerNodeBannedIdsProxy.begin());it!=mPerNodeBannedIdsProxy.end();++it) - std::cerr << " " << *it << std::endl; -} - diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h deleted file mode 100644 index 2045e6f05..000000000 --- a/libretroshare/src/services/p3gxsreputation.h +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3gxsreputation.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014-2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSGXSREPUTATION_HEADER -#define SERVICE_RSGXSREPUTATION_HEADER - -#include -#include -#include -#include - -static const uint32_t REPUTATION_IDENTITY_FLAG_UP_TO_DATE = 0x0100; // This flag means that the static info has been initialised from p3IdService. Normally such a call should happen once. -static const uint32_t REPUTATION_IDENTITY_FLAG_PGP_LINKED = 0x0001; -static const uint32_t REPUTATION_IDENTITY_FLAG_PGP_KNOWN = 0x0002; - -#include "rsitems/rsgxsreputationitems.h" - -#include "retroshare/rsidentity.h" -#include "retroshare/rsreputations.h" -#include "gxs/rsgixs.h" -#include "services/p3service.h" - - -class p3LinkMgr; - -class ReputationConfig -{ -public: - ReputationConfig() - :mPeerId(), mLatestUpdate(0), mLastQuery(0) { return; } - - ReputationConfig(const RsPeerId& peerId) - :mPeerId(peerId), mLatestUpdate(0), mLastQuery(0) { return; } - - RsPeerId mPeerId; - rstime_t mLatestUpdate; - rstime_t mLastQuery; -}; - -struct BannedNodeInfo -{ - rstime_t last_activity_TS ; // updated everytime a node or one of its former identities is required - std::set known_identities ; // list of known identities from this node. This is kept for a while, and useful in order to avoid re-asking these keys. -}; - -class Reputation -{ -public: - Reputation() : - mOwnOpinion(static_cast(RsOpinion::NEUTRAL)), - mOwnOpinionTs(0), - mFriendAverage(1.0f), - mFriendsPositive(0), - mFriendsNegative(0), - mReputationScore(1.0f), - mIdentityFlags(0), - mLastUsedTS(0) {} - - void updateReputation(); - - std::map mOpinions; - int32_t mOwnOpinion; - rstime_t mOwnOpinionTs; - - float mFriendAverage ; - uint32_t mFriendsPositive ; // number of positive vites from friends - uint32_t mFriendsNegative ; // number of negative vites from friends - - float mReputationScore; - - RsPgpId mOwnerNode; - - uint32_t mIdentityFlags; - - rstime_t mLastUsedTS ; // last time the reputation was asked. Used to keep track of activity and clean up some reputation data. -}; - - -//!The p3GxsReputation service. -class p3GxsReputation: public p3Service, public p3Config, public RsGixsReputation, public RsReputations /* , public pqiMonitor */ -{ -public: - p3GxsReputation(p3LinkMgr *lm); - virtual RsServiceInfo getServiceInfo(); - - /***** Interface for RsReputations *****/ - virtual bool setOwnOpinion(const RsGxsId& key_id, RsOpinion op); - virtual bool getOwnOpinion(const RsGxsId& key_id, RsOpinion& op) ; - virtual bool getReputationInfo( - const RsGxsId& id, const RsPgpId& ownerNode, RsReputationInfo& info, - bool stamp = true ); - virtual bool isIdentityBanned(const RsGxsId& id) ; - - virtual bool isNodeBanned(const RsPgpId& id); - virtual void banNode(const RsPgpId& id,bool b) ; - - RsReputationLevel overallReputationLevel(const RsGxsId& id) override; - - virtual RsReputationLevel overallReputationLevel( - const RsGxsId& id, uint32_t* identity_flags ); - - virtual void setAutoPositiveOpinionForContacts(bool b) ; - virtual bool autoPositiveOpinionForContacts() ; - - virtual void setRememberBannedIdThreshold(uint32_t days) ; - virtual uint32_t rememberBannedIdThreshold() ; - - uint32_t thresholdForRemotelyNegativeReputation(); - uint32_t thresholdForRemotelyPositiveReputation(); - void setThresholdForRemotelyNegativeReputation(uint32_t thresh); - void setThresholdForRemotelyPositiveReputation(uint32_t thresh); - - /***** overloaded from p3Service *****/ - virtual int tick(); - virtual int status(); - - /*! - * Interface stuff. - */ - - /************* from p3Config *******************/ - virtual RsSerialiser *setupSerialiser() ; - virtual bool saveList(bool& cleanup, std::list&) ; - virtual void saveDone(); - virtual bool loadList(std::list& load) ; - -private: - bool getIdentityFlagsAndOwnerId(const RsGxsId& gxsid, uint32_t& identity_flags, RsPgpId &owner_id); - - bool processIncoming(); - - bool SendReputations(RsGxsReputationRequestItem *request); - bool RecvReputations(RsGxsReputationUpdateItem *item); - bool updateLatestUpdate(RsPeerId peerid, rstime_t latest_update); - - void updateBannedNodesProxy(); - - // internal update of data. Takes care of cleaning empty boxes. - void locked_updateOpinion( - const RsPeerId& from, const RsGxsId& about, RsOpinion op); - bool loadReputationSet(RsGxsReputationSetItem *item, const std::set &peerSet); -#ifdef TO_REMOVE - bool loadReputationSet_deprecated3(RsGxsReputationSetItem_deprecated3 *item, const std::set &peerSet); -#endif - int sendPackets(); - void cleanup(); - void sendReputationRequests(); - int sendReputationRequest(RsPeerId peerid); - void debug_print() ; - void updateStaticIdentityFlags(); - -private: - RsMutex mReputationMtx; - - rstime_t mLastCleanUp; - rstime_t mRequestTime; - rstime_t mStoreTime; - rstime_t mLastBannedNodesUpdate ; - rstime_t mLastIdentityFlagsUpdate ; - bool mReputationsUpdated; - - //float mAutoBanIdentitiesLimit ; - bool mAutoSetPositiveOptionToContacts; - - p3LinkMgr *mLinkMgr; - - // Data for Reputation. - std::map mConfig; - std::map mReputations; - std::multimap mUpdated; - - // PGP Ids auto-banned. This is updated regularly. - std::map mBannedPgpIds ; - std::set mPerNodeBannedIdsProxy ; - bool mBannedNodesProxyNeedsUpdate ; - - uint32_t mMinVotesForRemotelyPositive ; - uint32_t mMinVotesForRemotelyNegative ; - uint32_t mMaxPreventReloadBannedIds ; - - bool mChanged ; // slow version of IndicateConfigChanged(); - rstime_t mLastReputationConfigSaved ; -}; - -#endif //SERVICE_RSGXSREPUTATION_HEADER - diff --git a/libretroshare/src/services/p3heartbeat.cc b/libretroshare/src/services/p3heartbeat.cc deleted file mode 100644 index 38426a454..000000000 --- a/libretroshare/src/services/p3heartbeat.cc +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3heartbeat.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstime.h" - -#include "services/p3heartbeat.h" -#include "rsitems/rsheartbeatitems.h" - -#include "pqi/p3servicecontrol.h" -#include "pqi/pqipersongrp.h" - -//#define HEART_DEBUG 1 - - -p3heartbeat::p3heartbeat(p3ServiceControl *sc, pqipersongrp *pqipg) -:p3Service(), mServiceCtrl(sc), mPqiPersonGrp(pqipg), - mHeartMtx("p3heartbeat") -{ - RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/ - - addSerialType(new RsHeartbeatSerialiser()); - -#ifdef HEART_DEBUG - std::cerr << "p3heartbeat::p3heartbeat()"; - std::cerr << std::endl; -#endif - - mLastHeartbeat = 0; - - return; -} - -p3heartbeat::~p3heartbeat() -{ - return; - -} - - -const std::string HEARTBEAT_APP_NAME = "heartbeat"; -const uint16_t HEARTBEAT_APP_MAJOR_VERSION = 1; -const uint16_t HEARTBEAT_APP_MINOR_VERSION = 0; -const uint16_t HEARTBEAT_MIN_MAJOR_VERSION = 1; -const uint16_t HEARTBEAT_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3heartbeat::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_HEARTBEAT, - HEARTBEAT_APP_NAME, - HEARTBEAT_APP_MAJOR_VERSION, - HEARTBEAT_APP_MINOR_VERSION, - HEARTBEAT_MIN_MAJOR_VERSION, - HEARTBEAT_MIN_MINOR_VERSION); -} - - -int p3heartbeat::tick() -{ - //send a heartbeat to all connected peers - RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/ - - if (time(NULL) - mLastHeartbeat > HEARTBEAT_REPEAT_TIME) - { - mLastHeartbeat = time(NULL); - - std::set peers; - std::set::const_iterator pit; - - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, peers); - for (pit = peers.begin(); pit != peers.end(); ++pit) - { - sendHeartbeat(*pit); - } - } - - int nhandled = 0; - RsItem *item = NULL; - - // While messages read - while(NULL != (item = recvItem())) - { - RsHeartbeatItem *beat = NULL; - nhandled++; - - // if discovery reply then respond if haven't already. - if (NULL != (beat = dynamic_cast (item))) - { - recvHeartbeat(beat->PeerId()); - } - else - { - // unknown. - } - - delete item; - } - - return nhandled ; -} - -void p3heartbeat::sendHeartbeat(const RsPeerId &toId) -{ - -#ifdef HEART_DEBUG - std::cerr << "p3heartbeat::sendHeartbeat() to " << toId; - std::cerr << std::endl; -#endif - RsHeartbeatItem *item = new RsHeartbeatItem(); - item->PeerId(toId); - sendItem(item); -} - - -void p3heartbeat::recvHeartbeat(const RsPeerId &fromId) -{ - -#ifdef HEART_DEBUG - std::cerr << "p3heartbeat::recvHeartbeat() from " << fromId; - std::cerr << std::endl; -#endif - - mPqiPersonGrp->tagHeartbeatRecvd(fromId); -} - - diff --git a/libretroshare/src/services/p3heartbeat.h b/libretroshare/src/services/p3heartbeat.h deleted file mode 100644 index 6dd9f6e5b..000000000 --- a/libretroshare/src/services/p3heartbeat.h +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3heartbeat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MRK_SERVICES_HEARTBEAT_H -#define MRK_SERVICES_HEARTBEAT_H - -// Moved Heartbeat to a seperate service. - -#include "services/p3service.h" - -class p3ServiceControl; -class pqipersongrp; - -class p3heartbeat: public p3Service -{ - public: - - p3heartbeat(p3ServiceControl *sc, pqipersongrp *pqipg); -virtual ~p3heartbeat(); - -virtual RsServiceInfo getServiceInfo(); - - int tick(); - - private: - - void sendHeartbeat(const RsPeerId &toId); - void recvHeartbeat(const RsPeerId &fromId); - - private: - - p3ServiceControl *mServiceCtrl; - pqipersongrp *mPqiPersonGrp; - - /* data */ - RsMutex mHeartMtx; - - rstime_t mLastHeartbeat; -}; - -#endif // MRK_SERVICES_HEARTBEAT_H diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc deleted file mode 100644 index d34f406a6..000000000 --- a/libretroshare/src/services/p3idservice.cc +++ /dev/null @@ -1,4998 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3idservice.cc * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2017-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/// RetroShare GXS identities service - - -#include -#include -#include -#include - -#include "services/p3idservice.h" -#include "pgp/pgpauxutils.h" -#include "rsitems/rsgxsiditems.h" -#include "rsitems/rsconfigitems.h" -#include "retroshare/rsgxsflags.h" -#include "util/rsrandom.h" -#include "util/rsstring.h" -#include "util/radix64.h" -#include "util/rsdir.h" -#include "util/rstime.h" -#include "crypto/hashstream.h" -#include "gxs/gxssecurity.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsnotify.h" - - -/**** - * #define DEBUG_IDS 1 - * #define DEBUG_RECOGN 1 - * #define DEBUG_OPINION 1 - * #define DEBUG_SERVICE_STRING 1 - * #define GXSID_GEN_DUMMY_DATA 1 - ****/ - -#define ID_REQUEST_LIST 0x0001 -#define ID_REQUEST_IDENTITY 0x0002 -#define ID_REQUEST_REPUTATION 0x0003 -#define ID_REQUEST_OPINION 0x0004 - -#define GXSID_MAX_CACHE_SIZE 15000 - -// unused keys are deleted according to some heuristic that should favor known keys, signed keys etc. - -static const rstime_t MAX_KEEP_KEYS_BANNED_DEFAULT = 2 * 86400 ; // get rid of banned ids after 1 days. That gives a chance to un-ban someone before he gets definitely kicked out - -static const rstime_t MAX_KEEP_KEYS_DEFAULT = 5 * 86400 ; // default for unsigned identities: 5 days -static const rstime_t MAX_KEEP_KEYS_SIGNED = 8 * 86400 ; // signed identities by unknown key -static const rstime_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed identities by known node keys - -static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins - -static const uint32_t MAX_SERIALISED_IDENTITY_AGE = 600 ; // after 10 mins, a serialised identity record must be renewed. - -RsIdentity* rsIdentity = nullptr; - -/****** - * Some notes: - * Identity tasks: - * - Provide keys for signing / validating author signatures. - * - Reputations - * - Identify Known Friend's IDs. - * - Provide details to other services (nicknames, reputations, gpg ids, etc) - * - * Background services: - * - Lookup and cache keys / details of identities. - * - Check GPGHashes. - * - Calculate Reputations. - * - * We have a lot of information to store in Service Strings. - * - GPGId or last check ts. - * - Reputation stuff. - */ - -#define RSGXSID_MAX_SERVICE_STRING 1024 - -#define BG_PGPHASH 1 -#define BG_RECOGN 2 -#define BG_REPUTATION 3 - - -#define GXSIDREQ_CACHELOAD 0x0001 -#define GXSIDREQ_CACHEOWNIDS 0x0002 -#define GXSIDREQ_PGPHASH 0x0010 -#define GXSIDREQ_RECOGN 0x0020 -#define GXSIDREQ_OPINION 0x0030 -#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040 -#define GXSIDREQ_LOAD_PGPIDDATA 0x0080 - -#define GXSIDREQ_CACHETEST 0x1000 - -// Events. -#define GXSID_EVENT_CACHEOWNIDS 0x0001 -#define GXSID_EVENT_CACHELOAD 0x0002 - -#define GXSID_EVENT_PGPHASH 0x0010 -#define GXSID_EVENT_PGPHASH_PROC 0x0011 - -#define GXSID_EVENT_RECOGN 0x0020 -#define GXSID_EVENT_RECOGN_PROC 0x0021 - -#define GXSID_EVENT_REPUTATION 0x0030 - -#define GXSID_EVENT_CACHETEST 0x1000 - -#define GXSID_EVENT_DUMMYDATA 0x2000 -#define GXSID_EVENT_DUMMY_OWNIDS 0x2001 -#define GXSID_EVENT_DUMMY_PGPID 0x2002 -#define GXSID_EVENT_DUMMY_UNKNOWN_PGPID 0x2003 -#define GXSID_EVENT_DUMMY_PSEUDOID 0x2004 -#define GXSID_EVENT_REQUEST_IDS 0x2005 - - -/* delays */ - -#define CACHETEST_PERIOD 60 -#define DELAY_BETWEEN_CONFIG_UPDATES 300 -#define GXS_MAX_KEY_TS_USAGE_MAP_SIZE 5 - -#define OWNID_RELOAD_DELAY 10 - -#define PGPHASH_PERIOD 60 -#define PGPHASH_RETRY_PERIOD 11 -#define PGPHASH_PROC_PERIOD 1 - -#define RECOGN_PERIOD 90 -#define RECOGN_RETRY_PERIOD 17 -#define RECOGN_PROC_PERIOD 1 - -#define REPUTATION_PERIOD 60 -#define REPUTATION_RETRY_PERIOD 13 -#define REPUTATION_PROC_PERIOD 1 - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3IdService::p3IdService( RsGeneralDataService *gds - , RsNetworkExchangeService *nes - , PgpAuxUtils *pgpUtils ) - : RsGxsIdExchange( gds, nes, new RsGxsIdSerialiser(), - RS_SERVICE_GXS_TYPE_GXSID, idAuthenPolicy() ) - , RsIdentity(static_cast(*this)) - , GxsTokenQueue(this), RsTickEvent(), p3Config() - , mKeyCache(GXSID_MAX_CACHE_SIZE, "GxsIdKeyCache") - , mBgSchedule_Active(false), mBgSchedule_Mode(0) - , mIdMtx("p3IdService"), mNes(nes), mPgpUtils(pgpUtils) - , mLastConfigUpdate(0), mOwnIdsLoaded(false) - , mAutoAddFriendsIdentitiesAsContacts(true) /*default*/ - , mMaxKeepKeysBanned(MAX_KEEP_KEYS_BANNED_DEFAULT) -{ - mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ; - mLastPGPHashProcessTime = 0; - - // Kick off Cache Testing, + Others. - RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//First Thing to do - RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); - RsTickEvent::schedule_in(GXSID_EVENT_REPUTATION, REPUTATION_PERIOD); - - //RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD); - -#ifdef GXSID_GEN_DUMMY_DATA - //RsTickEvent::schedule_now(GXSID_EVENT_DUMMYDATA); -#endif - - loadRecognKeys(); -} - -const std::string GXSID_APP_NAME = "gxsid"; -const uint16_t GXSID_APP_MAJOR_VERSION = 1; -const uint16_t GXSID_APP_MINOR_VERSION = 0; -const uint16_t GXSID_MIN_MAJOR_VERSION = 1; -const uint16_t GXSID_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3IdService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_GXSID, - GXSID_APP_NAME, - GXSID_APP_MAJOR_VERSION, - GXSID_APP_MINOR_VERSION, - GXSID_MIN_MAJOR_VERSION, - GXSID_MIN_MINOR_VERSION); -} - - - -void p3IdService::setNes(RsNetworkExchangeService *nes) -{ - RsStackMutex stack(mIdMtx); - mNes = nes; -} - -bool p3IdService::getIdentitiesInfo( - const std::set& ids, std::vector& idsInfo ) -{ - uint32_t token; - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - std::list idsList; - for (auto&& id : ids) idsList.push_back(RsGxsGroupId(id)); - - if( !requestGroupInfo(token, opts, idsList) - || waitToken(token) != RsTokenService::COMPLETE ) return false; - return getGroupData(token, idsInfo); -} - -bool p3IdService::getIdentitiesSummaries(std::list& ids) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token, opts) - || waitToken(token) != RsTokenService::COMPLETE ) return false; - return getGroupSummary(token, ids); -} - -uint32_t p3IdService::idAuthenPolicy() -{ - uint32_t policy = 0; - uint8_t flag = 0; - - // Messages are send reputations. normally not by ID holder - so need signatures. - flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - // No ID required. - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -uint32_t p3IdService::nbRegularContacts() -{ - RsStackMutex stack(mIdMtx); - return mContacts.size(); -} - -bool p3IdService::isARegularContact(const RsGxsId& id) -{ - RsStackMutex stack(mIdMtx); - return mContacts.find(id) != mContacts.end() ; -} - -bool p3IdService::receiveNewIdentity(RsNxsGrp *identity_grp) -{ - receiveNewGroups(std::vector{ identity_grp }); - return true; -} - -bool p3IdService::retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp) -{ - return RsGenExchange::retrieveNxsIdentity(RsGxsGroupId(group_id),identity_grp); -} - -bool p3IdService::setAsRegularContact(const RsGxsId& id,bool b) -{ - RsStackMutex stack(mIdMtx); - std::set::iterator it = mContacts.find(id) ; - - if(b && (it == mContacts.end())) - { - mContacts.insert(id) ; - slowIndicateConfigChanged() ; - } - - if( (!b) &&(it != mContacts.end())) - { - mContacts.erase(it) ; - slowIndicateConfigChanged() ; - } - - return true ; -} - -void p3IdService::slowIndicateConfigChanged() -{ - rstime_t now = time(NULL) ; - - if(mLastConfigUpdate + DELAY_BETWEEN_CONFIG_UPDATES < now) - { - IndicateConfigChanged() ; - mLastConfigUpdate = now ; - } -} -rstime_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id) -{ - std::map::const_iterator it = mKeysTS.find(gxs_id) ; - - if(it == mKeysTS.end()) - return 0 ; - else - return it->second.TS ; -} -void p3IdService::timeStampKey(const RsGxsId& gxs_id, const RsIdentityUsage& reason) -{ - if(rsReputations->isIdentityBanned(gxs_id) ) - { - std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl; - return ; - } -#ifdef DEBUG_IDS - std::cerr << "(II) time stamping key " << gxs_id << " for the following reason: " << reason.mUsageCode << std::endl; -#endif - - RS_STACK_MUTEX(mIdMtx) ; - - rstime_t now = time(NULL) ; - - keyTSInfo& info(mKeysTS[gxs_id]) ; - - info.TS = now ; - info.usage_map[reason] = now; - - while(info.usage_map.size() > GXS_MAX_KEY_TS_USAGE_MAP_SIZE) - { - // This is very costly, but normally the outerloop should never be rolled more than once. - - std::map::iterator best_it ; - rstime_t best_time = now+1; - - for(std::map::iterator it(info.usage_map.begin());it!=info.usage_map.end();++it) - if(it->second < best_time) - { - best_time = it->second ; - best_it = it; - } - - info.usage_map.erase(best_it) ; - } - - slowIndicateConfigChanged() ; -} - -bool p3IdService::loadList(std::list& items) -{ - RS_STACK_MUTEX(mIdMtx) ; - RsGxsIdLocalInfoItem *lii; - - for(std::list::const_iterator it = items.begin();it!=items.end();++it) - { - if( (lii = dynamic_cast(*it)) != NULL) - { - for(std::map::const_iterator it2 = lii->mTimeStamps.begin();it2!=lii->mTimeStamps.end();++it2) - mKeysTS[it2->first].TS = it2->second; - - mContacts = lii->mContacts ; - } - - RsConfigKeyValueSet *vitem = dynamic_cast(*it); - - if(vitem) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if(kit->key == "REMOVE_BANNED_IDENTITIES_DELAY") - { - int val ; - if (sscanf(kit->value.c_str(), "%d", &val) == 1) - { - mMaxKeepKeysBanned = val ; - std::cerr << "Setting mMaxKeepKeysBanned threshold to " << val << std::endl ; - } - }; - if(kit->key == "AUTO_SET_FRIEND_IDENTITIES_AS_CONTACT") - mAutoAddFriendsIdentitiesAsContacts = (kit->value == "YES") ; - } - - delete *it ; - } - - items.clear() ; - return true ; -} - -void p3IdService::setDeleteBannedNodesThreshold(uint32_t days) -{ - RsStackMutex stack(mIdMtx); /****** LOCKED MUTEX *******/ - if(mMaxKeepKeysBanned != days*86400) - { - mMaxKeepKeysBanned = days*86400 ; - IndicateConfigChanged(); - } -} -uint32_t p3IdService::deleteBannedNodesThreshold() -{ - RsStackMutex stack(mIdMtx); /****** LOCKED MUTEX *******/ - - return mMaxKeepKeysBanned/86400; -} - -void p3IdService::setAutoAddFriendIdsAsContact(bool b) -{ - RS_STACK_MUTEX(mIdMtx) ; - if(b != mAutoAddFriendsIdentitiesAsContacts) - { - IndicateConfigChanged(); - mAutoAddFriendsIdentitiesAsContacts=b; - } -} -bool p3IdService::autoAddFriendIdsAsContact() -{ - RS_STACK_MUTEX(mIdMtx) ; - return mAutoAddFriendsIdentitiesAsContacts; -} - -bool p3IdService::saveList(bool& cleanup,std::list& items) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::saveList()" << std::endl; -#endif - - RS_STACK_MUTEX(mIdMtx) ; - cleanup = true ; - RsGxsIdLocalInfoItem *item = new RsGxsIdLocalInfoItem ; - - for(std::map::const_iterator it(mKeysTS.begin());it!=mKeysTS.end();++it) - item->mTimeStamps[it->first] = it->second.TS; - - item->mContacts = mContacts ; - - items.push_back(item) ; - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - - kv.key = "REMOVE_BANNED_IDENTITIES_DELAY" ; - rs_sprintf(kv.value, "%d", mMaxKeepKeysBanned); - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "AUTO_SET_FRIEND_IDENTITIES_AS_CONTACT" ; - kv.value = mAutoAddFriendsIdentitiesAsContacts?"YES":"NO"; - vitem->tlvkvs.pairs.push_back(kv) ; - - items.push_back(vitem) ; - - return true ; -} - -class IdCacheEntryCleaner -{ -public: - IdCacheEntryCleaner(const std::map& last_usage_TSs,uint32_t m) : mLastUsageTS(last_usage_TSs),mMaxKeepKeysBanned(m) {} - - bool processEntry(RsGxsIdCache& entry) - { - rstime_t now = time(NULL); - const RsGxsId& gxs_id = entry.details.mId ; - - bool is_id_banned = rsReputations->isIdentityBanned(gxs_id) ; - bool is_own_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) ; - bool is_known_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) ; - bool is_signed_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ; - bool is_a_contact = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT) ; - -#ifdef DEBUG_IDS - std::cerr << "Identity: " << gxs_id << ": banned: " << is_id_banned << ", own: " << is_own_id << ", contact: " << is_a_contact << ", signed: " << is_signed_id << ", known: " << is_known_id; -#endif - - if(is_own_id || is_a_contact) - { -#ifdef DEBUG_IDS - std::cerr << " => kept" << std::endl; -#endif - return true ; - } - - std::map::const_iterator it = mLastUsageTS.find(gxs_id) ; - - bool no_ts = (it == mLastUsageTS.end()) ; - - rstime_t last_usage_ts = no_ts?0:(it->second.TS); - rstime_t max_keep_time = 0; - bool should_check = true ; - - if(no_ts) - max_keep_time = 0 ; - else if(is_id_banned) - { - if(mMaxKeepKeysBanned == 0) - should_check = false ; - else - max_keep_time = mMaxKeepKeysBanned ; - } - else if(is_known_id) - max_keep_time = MAX_KEEP_KEYS_SIGNED_KNOWN ; - else if(is_signed_id) - max_keep_time = MAX_KEEP_KEYS_SIGNED ; - else - max_keep_time = MAX_KEEP_KEYS_DEFAULT ; - -#ifdef DEBUG_IDS - std::cerr << ". Max keep = " << max_keep_time/86400 << " days. Unused for " << (now - last_usage_ts + 86399)/86400 << " days " ; -#endif - - if(should_check && now > last_usage_ts + max_keep_time) - { -#ifdef DEBUG_IDS - std::cerr << " => delete " << std::endl; -#endif - ids_to_delete.push_back(gxs_id) ; - } -#ifdef DEBUG_IDS - else - std::cerr << " => keep " << std::endl; -#endif - - return true; - } - - std::list ids_to_delete ; - const std::map& mLastUsageTS; - uint32_t mMaxKeepKeysBanned ; -}; - -void p3IdService::cleanUnusedKeys() -{ - std::list ids_to_delete ; - - std::cerr << "Cleaning unused keys:" << std::endl; - - // we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock - { - RS_STACK_MUTEX(mIdMtx) ; - - if(!mOwnIdsLoaded) - { - std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl; - return ; - } - - // grab at most 10 identities to delete. No need to send too many requests to the token queue at once. - IdCacheEntryCleaner idcec(mKeysTS,mMaxKeepKeysBanned) ; - - mKeyCache.applyToAllCachedEntries(idcec,&IdCacheEntryCleaner::processEntry); - - ids_to_delete = idcec.ids_to_delete ; - } - std::cerr << "Collected " << ids_to_delete.size() << " keys to delete among " << mKeyCache.size() << std::endl; - - for(std::list::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it) - { -#ifdef DEBUG_IDS - std::cerr << "Deleting identity " << *it << " which is too old." << std::endl; -#endif - uint32_t token ; - RsGxsIdGroup group; - group.mMeta.mGroupId=RsGxsGroupId(*it); - rsIdentity->deleteIdentity(token, group); - - { - RS_STACK_MUTEX(mIdMtx) ; - mKeysTS.erase(*it) ; - - // mPublicKeyCache.erase(*it) ; no need to do it now. It's done in p3IdService::deleteGroup() - } - } -} - -void p3IdService::service_tick() -{ - RsTickEvent::tick_events(); - GxsTokenQueue::checkRequests(); // GxsTokenQueue handles all requests. - - rstime_t now = time(NULL) ; - - if(mLastKeyCleaningTime + MAX_DELAY_BEFORE_CLEANING < now) - { - cleanUnusedKeys() ; - mLastKeyCleaningTime = now ; - } - - if(mLastPGPHashProcessTime + PGPHASH_PROC_PERIOD < now && !mGroupsToProcess.empty()) - { - pgphash_process(); - mLastPGPHashProcessTime=now; - } - - return; -} - -bool p3IdService::acceptNewGroup(const RsGxsGrpMetaData *grpMeta) -{ - bool res = !rsReputations->isIdentityBanned(RsGxsId(grpMeta->mGroupId)) ; - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::acceptNewGroup: ID=" << grpMeta->mGroupId << ": " << (res?"ACCEPTED":"DENIED") << std::endl; -#endif - - return res ; -} - -void p3IdService::notifyChanges(std::vector &changes) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::notifyChanges()"; - std::cerr << std::endl; -#endif - - /* iterate through and grab any new messages */ - std::list unprocessedGroups; - - for(uint32_t i = 0;i(changes[i]); - - if (msgChange && !msgChange->metaChange()) - RsWarn() << __PRETTY_FUNCTION__ << " Found a Msg data change in p3IdService. This is quite unexpected." << std::endl; - - RsGxsGroupChange *groupChange = dynamic_cast(changes[i]); - - if (groupChange) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::notifyChanges() Found Group Change Notification"; - std::cerr << std::endl; -#endif - const RsGxsGroupId& gid(groupChange->mGroupId); -#ifdef DEBUG_IDS - std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << gid; - std::cerr << std::endl; -#endif - - if(!rsReputations->isIdentityBanned(RsGxsId(gid))) - { - // notify that a new identity is received, if needed - - bool should_subscribe = false; - - switch(groupChange->getType()) - { - case RsGxsNotify::TYPE_PROCESSED: break ; // Happens when the group is subscribed. This is triggered by RsGenExchange::subscribeToGroup, so better not - // call it again from here!! - - case RsGxsNotify::TYPE_UPDATED: - case RsGxsNotify::TYPE_PUBLISHED: - { - auto ev = std::make_shared(); - ev->mIdentityId = gid; - ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY; - rsEvents->postEvent(ev); - - // also time_stamp the key that this group represents - timeStampKey(RsGxsId(gid),RsIdentityUsage(RsServiceType(serviceType()),RsIdentityUsage::IDENTITY_NEW_FROM_GXS_SYNC)) ; - should_subscribe = true; - } - break; - - case RsGxsNotify::TYPE_RECEIVED_NEW: - { - auto ev = std::make_shared(); - ev->mIdentityId = gid; - ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY; - rsEvents->postEvent(ev); - - // also time_stamp the key that this group represents - timeStampKey(RsGxsId(gid),RsIdentityUsage(RsServiceType(serviceType()),RsIdentityUsage::IDENTITY_NEW_FROM_GXS_SYNC)) ; - should_subscribe = true; - - std::cerr << "Received new identity " << gid << " and subscribing to it" << std::endl; - } - break; - - default: - break; - } - - if(should_subscribe) - { - uint32_t token; - RsGenExchange::subscribeToGroup(token, gid, true); - - // we need to acknowledge the token in a async process - - RsThread::async( [this,token]() - { - std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000); - std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100); - - auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most - auto st = requestStatus(token); - - while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout ) - { - std::this_thread::sleep_for(checkEvery); - st = requestStatus(token); - } - - RsGxsGroupId grpId; - acknowledgeGrp(token,grpId); - }); - } - - } - } - - delete changes[i]; - } -} - -/********************************************************************************/ -/******************* RsIdentity Interface ***************************************/ -/********************************************************************************/ - -#if 0 -bool p3IdService:: getNickname(const RsGxsId &id, std::string &nickname) -{ - return false; -} -#endif - -rstime_t p3IdService::getLastUsageTS(const RsGxsId &id) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - return locked_getLastUsageTS(id) ; -} - -bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getIdDetails(" << id << ")"; - std::cerr << std::endl; -#endif - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - RsGxsIdCache data; - - if (mKeyCache.fetch(id, data)) - { - bool is_a_contact = (mContacts.find(id) != mContacts.end()); - - details = data.details; - - if(mAutoAddFriendsIdentitiesAsContacts && (!is_a_contact) && (details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) && rsPeers->isPgpFriend(details.mPgpId)) - { - mContacts.insert(id) ; - slowIndicateConfigChanged() ; - - is_a_contact = true; - } - - // This step is needed, because p3GxsReputation does not know all identities, and might not have any data for - // the ones in the contact list. So we change them on demand. - - if(is_a_contact && rsReputations->autoPositiveOpinionForContacts()) - { - RsOpinion op; - if( rsReputations->getOwnOpinion(id,op) && - op == RsOpinion::NEUTRAL ) - rsReputations->setOwnOpinion(id, RsOpinion::POSITIVE); - } - - std::map::const_iterator it = mKeysTS.find(id) ; - - if(it == mKeysTS.end()) - details.mLastUsageTS = 0 ; - else - { - details.mLastUsageTS = it->second.TS ; - details.mUseCases = it->second.usage_map ; - } - details.mPublishTS = data.mPublishTs; - - // 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.mPgpId,details.mReputation) ; - - return true; - } - } - - /* it isn't there - add to public requests */ - cache_request_load(id); - - return false; -} - -bool p3IdService::isOwnId(const RsGxsId& id) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - return std::find(mOwnIds.begin(),mOwnIds.end(),id) != mOwnIds.end() ; -} - - -bool p3IdService::getOwnSignedIds(std::vector& ids) -{ - ids.clear(); - - std::chrono::seconds maxWait(5); - auto timeout = std::chrono::steady_clock::now() + maxWait; - while( !ownIdsAreLoaded() && std::chrono::steady_clock::now() < timeout ) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - if(ownIdsAreLoaded()) - { - RS_STACK_MUTEX(mIdMtx); - ids.resize(mOwnSignedIds.size()); - std::copy(mOwnSignedIds.begin(), mOwnSignedIds.end(), ids.begin()); - return true; - } - - return false; -} - -bool p3IdService::getOwnPseudonimousIds(std::vector& ids) -{ - ids.clear(); - std::vector signedV; - - // this implicitely ensure ids are already loaded ;) - if(!getOwnSignedIds(signedV)) return false; - - std::set signedS(signedV.begin(), signedV.end()); - - { - RS_STACK_MUTEX(mIdMtx); - ids.resize(mOwnIds.size() - signedV.size()); - std::copy_if( mOwnIds.begin(), mOwnIds.end(), ids.begin(), - [&](const RsGxsId& id) {return !signedS.count(id);} ); - } - - return true; -} - -bool p3IdService::getOwnIds(std::list &ownIds,bool signed_only) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if(!mOwnIdsLoaded) - { - std::cerr << "p3IdService::getOwnIds(): own identities are not loaded yet." << std::endl; - return false ; - } - - ownIds = signed_only ? mOwnSignedIds : mOwnIds; - - return true ; -} - -bool p3IdService::isKnownId(const RsGxsId& id) -{ - RS_STACK_MUTEX(mIdMtx); - return mKeyCache.is_cached(id) || - std::find(mOwnIds.begin(), mOwnIds.end(),id) != mOwnIds.end(); -} - -bool p3IdService::serialiseIdentityToMemory( const RsGxsId& id, - std::string& radix_string ) -{ - RS_STACK_MUTEX(mIdMtx); - - // look into cache. If available, return the data. If not, request it. - - std::map::const_iterator it = mSerialisedIdentities.find(id); - - if(it != mSerialisedIdentities.end()) - { - Radix64::encode(it->second.mMem,it->second.mSize,radix_string) ; - - if(it->second.mLastUsageTS + MAX_SERIALISED_IDENTITY_AGE > time(NULL)) - return true ; - - std::cerr << "Identity " << id << " will be re-serialised, because the last record is too old." << std::endl; - } - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token = 0; - std::list groupIds; - - groupIds.push_back(RsGxsGroupId(id)) ; - - RsGenExchange::getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); - GxsTokenQueue::queueRequest(token, GXSIDREQ_SERIALIZE_TO_MEMORY); - - return false; -} - -void p3IdService::handle_get_serialized_grp(uint32_t token) -{ - // store the serialized data in cache. - - unsigned char *mem = NULL; - uint32_t size; - RsGxsGroupId id ; - - if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) - { - std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; - return ; - } - - std::cerr << "Received serialised group from RsGenExchange." << std::endl; - - std::map::const_iterator it = mSerialisedIdentities.find(RsGxsId(id)); - - if(it != mSerialisedIdentities.end()) - free(it->second.mMem) ; - - SerialisedIdentityStruct s ; - s.mMem = mem ; - s.mSize = size ; - s.mLastUsageTS = time(NULL) ; - - mSerialisedIdentities[RsGxsId(id)] = s ; -} - -bool p3IdService::deserialiseIdentityFromMemory(const std::string& radix_string, - RsGxsId* id /* = nullptr */) -{ - std::vector mem = Radix64::decode(radix_string); - - if(mem.empty()) - { - std::cerr << __PRETTY_FUNCTION__ << "Cannot decode radix string \"" - << radix_string << "\"" << std::endl; - return false; - } - - if( !RsGenExchange::deserializeGroupData( - mem.data(), mem.size(), reinterpret_cast(id)) ) - { - std::cerr << __PRETTY_FUNCTION__ << "Cannot load identity from radix " - << "string \"" << radix_string << "\"" << std::endl; - return false; - } - - return true; -} - -bool p3IdService::createIdentity( RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) -{ - bool ret = true; - RsIdentityParameters params; - uint32_t token = 0; - RsGroupMetaData meta; - RsTokenService::GxsRequestStatus wtStatus = RsTokenService::CANCELLED; - - if(!pseudonimous && !pgpPassword.empty()) - { - if(!rsNotify->cachePgpPassphrase(pgpPassword)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure caching password" << std::endl; - ret = false; - goto LabelCreateIdentityCleanup; - } - - if(!rsNotify->setDisableAskPassword(true)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure disabling password user request" << std::endl; - ret = false; - goto LabelCreateIdentityCleanup; - } - } - - params.isPgpLinked = !pseudonimous; - params.nickname = name; - params.mImage = avatar; - - if(!createIdentity(token, params)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failed creating GXS group." << std::endl; - ret = false; - goto LabelCreateIdentityCleanup; - } - - /* Use custom timeout for waitToken because creating identities involves - * creating multiple signatures, which can take a lot of time expecially on - * slow hardware like phones or embedded devices */ - if( (wtStatus = waitToken( - token, std::chrono::seconds(10), std::chrono::milliseconds(20) )) - != RsTokenService::COMPLETE ) - { - RsErr() << __PRETTY_FUNCTION__ << " waitToken("<< token << ") failed with: " << wtStatus << std::endl; - ret = false; - goto LabelCreateIdentityCleanup; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, meta)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure getting updated group data." << std::endl; - ret = false; - goto LabelCreateIdentityCleanup; - } - - id = RsGxsId(meta.mGroupId); - - { - RS_STACK_MUTEX(mIdMtx); - mOwnIds.push_back(id); - if(!pseudonimous) mOwnSignedIds.push_back(id); - } - -LabelCreateIdentityCleanup: - if(!pseudonimous && !pgpPassword.empty()) - { - rsNotify->setDisableAskPassword(false); - rsNotify->clearPgpPassphrase(); - } - - return ret; -} - -bool p3IdService::createIdentity(uint32_t& token, RsIdentityParameters ¶ms) -{ - - RsGxsIdGroup id; - - id.mMeta.mGroupName = params.nickname; - id.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC ; - id.mImage = params.mImage; - - if (params.isPgpLinked) - { -#warning csoler 2017-02-07: Backward compatibility issue to fix here in v0.7.0 - - // This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE. - // In order to keep backward compatibility, we'll also add the new value - // When the ID is not PGP linked, the group flag cannot be let empty, so we use PUBLIC. - // - // The correct combination of flags should be: - // PGP-linked: GXS_SERV::FLAGS_PRIVACY_PUBLIC | RSGXSID_GROUPFLAG_REALID - // Anonymous : GXS_SERV::FLAGS_PRIVACY_PUBLIC - - id.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; // this is also equal to RSGXSID_GROUPFLAG_REALID_deprecated - id.mMeta.mGroupFlags |= RSGXSID_GROUPFLAG_REALID; - - // The current version should be able to produce new identities that old peers will accept as well. - // In the future, we need to: - // - set the current group flags here (see above) - // - replace all occurences of RSGXSID_GROUPFLAG_REALID_deprecated by RSGXSID_GROUPFLAG_REALID in the code. - } - else - id.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; - - // Anticipate signature validation, since we're creating the signature ourselves. - - SSGxsIdGroup ssdata; - ssdata.pgp.validatedSignature = params.isPgpLinked; - - if(params.isPgpLinked) - { - ssdata.pgp.pgpId = AuthGPG::getAuthGPG()->getGPGOwnId(); - ssdata.pgp.lastCheckTs = time(nullptr); - } - - /* save string */ - id.mMeta.mServiceString = ssdata.save(); - - createGroup(token, id); - - return true; -} - -bool p3IdService::updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) -{ - // 1 - get back the identity group - - std::vector idsInfo; - - if(!getIdentitiesInfo(std::set{ id }, idsInfo)) - return false; - - RsGxsIdGroup& group(idsInfo[0]); - - // 2 - update it with the new information - - group.mMeta.mGroupName = name; - group.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC ; - group.mImage = avatar; - - if(!pseudonimous) - { -#warning csoler 2020-01-21: Backward compatibility issue to fix here in v0.7.0 - - // This is a hack, because a bad decision led to having RSGXSID_GROUPFLAG_REALID be equal to GXS_SERV::FLAG_PRIVACY_PRIVATE. - // In order to keep backward compatibility, we'll also add the new value - // When the ID is not PGP linked, the group flag cannot be let empty, so we use PUBLIC. - // - // The correct combination of flags should be: - // PGP-linked: GXS_SERV::FLAGS_PRIVACY_PUBLIC | RSGXSID_GROUPFLAG_REALID - // Anonymous : GXS_SERV::FLAGS_PRIVACY_PUBLIC - - group.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PRIVATE; // this is also equal to RSGXSID_GROUPFLAG_REALID_deprecated - group.mMeta.mGroupFlags |= RSGXSID_GROUPFLAG_REALID; - - // The current version should be able to produce new identities that old peers will accept as well. - // In the future, we need to: - // - set the current group flags here (see above) - // - replace all occurences of RSGXSID_GROUPFLAG_REALID_deprecated by RSGXSID_GROUPFLAG_REALID in the code. - } - else - group.mMeta.mGroupFlags |= GXS_SERV::FLAG_PRIVACY_PUBLIC; - - uint32_t token; - bool ret = true; - - // Cache pgp passphrase to allow a proper re-signing of the group data - - if(!pseudonimous && !pgpPassword.empty()) - { - if(!rsNotify->cachePgpPassphrase(pgpPassword)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure caching password" << std::endl; - ret = false; - goto LabelUpdateIdentityCleanup; - } - - if(!rsNotify->setDisableAskPassword(true)) - { - RsErr() << __PRETTY_FUNCTION__ << " Failure disabling password user request" << std::endl; - ret = false; - goto LabelUpdateIdentityCleanup; - } - } - - if(!updateGroup(token, group)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed updating group." << std::endl; - ret = false; - goto LabelUpdateIdentityCleanup; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; - ret = false; - goto LabelUpdateIdentityCleanup; - } - -LabelUpdateIdentityCleanup: - if(!pseudonimous && !pgpPassword.empty()) - rsNotify->clearPgpPassphrase(); - - return ret; -} - -bool p3IdService::deleteIdentity(RsGxsId& id) -{ - uint32_t token; - RsGxsGroupId grouId = RsGxsGroupId(id); - if(!deleteGroup(token, grouId)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed deleting group." - << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." - << std::endl; - return false; - } - - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mIdentityId = grouId; - ev->mIdentityEventCode = RsGxsIdentityEventCode::DELETED_IDENTITY; - rsEvents->postEvent(ev); - } - - return true; -} - -bool p3IdService::deleteIdentity(uint32_t& token, RsGxsIdGroup &group) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteIdentity()"; - std::cerr << std::endl; -#endif - - deleteGroup(token, group.mMeta.mGroupId); - - return false; -} - - -bool p3IdService::parseRecognTag(const RsGxsId &id, const std::string &nickname, - const std::string &tag, RsRecognTagDetails &details) -{ -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::parseRecognTag()"; - std::cerr << std::endl; -#endif - - RsGxsRecognTagItem *tagitem = RsRecogn::extractTag(tag); - if (!tagitem) - { - return false; - } - - bool isPending = false; - bool isValid = recogn_checktag(id, nickname, tagitem, true, isPending); - - details.valid_from = tagitem->valid_from; - details.valid_to = tagitem->valid_to; - details.tag_class = tagitem->tag_class; - details.tag_type = tagitem->tag_type; - details.signer = tagitem->sign.keyId.toStdString(); - - details.is_valid = isValid; - details.is_pending = isPending; - - delete tagitem; - - return true; -} - -bool p3IdService::getRecognTagRequest(const RsGxsId &id, const std::string &comment, uint16_t tag_class, uint16_t tag_type, std::string &tag) -{ -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::getRecognTagRequest()"; - std::cerr << std::endl; -#endif - if(!isOwnId(id)) - { - std::cerr << "(EE) cannot retrieve own key to create tag request. KeyId=" << id << std::endl; - return false ; - } - - RsTlvPrivateRSAKey key; - std::string nickname; - RsGxsIdCache data ; - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if(!mKeyCache.fetch(id, data)) - return false ; - - nickname = data.details.mNickname ; - key = data.priv_key ; - } - - return RsRecogn::createTagRequest(key, id, nickname, tag_class, tag_type, comment, tag); -} - - - -/********************************************************************************/ -/******************* RsGixs Interface ***************************************/ -/********************************************************************************/ - -bool p3IdService::haveKey(const RsGxsId &id) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - return mKeyCache.is_cached(id); -} - -bool p3IdService::havePrivateKey(const RsGxsId &id) -{ - if(! isOwnId(id)) - return false ; - - RS_STACK_MUTEX(mIdMtx); - return mKeyCache.is_cached(id); -} - -static void mergeIds(std::map >& idmap,const RsGxsId& id,const std::list& peers) -{ - /* merge the two lists, use std::set to avoid duplicates efficiently */ - - std::set new_peers(std::begin(peers), std::end(peers)); - - std::list& stored_peers(idmap[id]); - std::copy( std::begin(stored_peers), std::end(stored_peers), - std::inserter(new_peers, std::begin(new_peers)) ); - stored_peers.clear(); - std::copy( std::begin(new_peers), std::end(new_peers), - std::inserter(stored_peers, std::begin(stored_peers)) ); -} - -bool p3IdService::requestIdentity( - const RsGxsId& id, const std::vector& peers ) -{ - std::list askPeersList(peers.begin(), peers.end()); - - // Empty list passed? Ask to all online peers. - if(askPeersList.empty()) rsPeers->getOnlineList(askPeersList); - - if(askPeersList.empty()) // Still empty? Fail! - { - RsErr() << __PRETTY_FUNCTION__ << " failure retrieving peers list" - << std::endl; - return false; - } - - RsIdentityUsage usageInfo( RsServiceType::GXSID, RsIdentityUsage::IDENTITY_NEW_FROM_EXPLICIT_REQUEST ); - - return requestKey(id, askPeersList, usageInfo); -} - -bool p3IdService::requestKey(const RsGxsId &id, const std::list& peers,const RsIdentityUsage& use_info) -{ - Dbg3() << __PRETTY_FUNCTION__ << " id: " << id << std::endl; - - if(id.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " cannot request null id" - << std::endl; - return false; - } - - if(peers.empty()) - { - RsErr() << __PRETTY_FUNCTION__ << " cannot request id: " << id - << " to empty lists of peers" << std::endl; - return false; - } - - if(isKnownId(id)) return true; - - /* Normally we should call getIdDetails(), but since the key is not known, - * we need to dig a possibly old information from the reputation system, - * which keeps its own list of banned keys. - * Of course, the owner ID is not known at this point.c*/ - - RsReputationInfo info; - rsReputations->getReputationInfo(id, RsPgpId(), info); - - if( info.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE ) - { -#ifdef DEBUG_IDS - RsInfo() << __PRETTY_FUNCTION__ << " not requesting Key " << id << " because it has been banned." << std::endl; -#endif - - RS_STACK_MUTEX(mIdMtx); - mIdsNotPresent.erase(id); - - return false; - } - - { - RS_STACK_MUTEX(mIdMtx); - mergeIds(mIdsNotPresent, id, peers); - mKeysTS[id].usage_map[use_info] = time(nullptr); - } - - return cache_request_load(id, peers); -} - -bool p3IdService::isPendingNetworkRequest(const RsGxsId& gxsId) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - // if ids has beens confirmed as not physically present return - // immediately, id will be removed from list if found by auto nxs net search - if(mIdsNotPresent.find(gxsId) != mIdsNotPresent.end()) - return true; - - return false; -} - -bool p3IdService::getKey(const RsGxsId &id, RsTlvPublicRSAKey &key) -{ - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - RsGxsIdCache data; - - if (mKeyCache.fetch(id, data)) - { - key = data.pub_key; - return true; - } - } - - cache_request_load(id); - - key.keyId.clear() ; - return false; -} - -bool p3IdService::requestPrivateKey(const RsGxsId &id) -{ - if (havePrivateKey(id)) - return true; - - return cache_request_load(id); -} - -bool p3IdService::getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key) -{ - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - RsGxsIdCache data; - - if (mKeyCache.fetch(id, data)) - { - key = data.priv_key; - return true; - } - } - - key.keyId.clear() ; - cache_request_load(id); - - return false ; -} - - -bool p3IdService::signData(const uint8_t *data,uint32_t data_size,const RsGxsId& own_gxs_id,RsTlvKeySignature& signature,uint32_t& error_status) -{ - RsTlvPrivateRSAKey signature_key ; - - int i ; - for(i=0;i<6;++i) - if(!getPrivateKey(own_gxs_id,signature_key) || signature_key.keyData.bin_data == NULL) - { -#ifdef DEBUG_IDS - std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl; -#endif - rstime::rs_usleep(500 * 1000) ; // sleep for 500 msec. - } - else - break ; - - if(i == 6) - { - std::cerr << " (EE) Could not retrieve own private key for ID = " << own_gxs_id << ". Giging up sending DH session params. This should not happen." << std::endl; - error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ; - return false ; - } - -#ifdef DEBUG_IDS - std::cerr << " Signing..." << std::endl; -#endif - - if(!GxsSecurity::getSignature((char *)data,data_size,signature_key,signature)) - { - std::cerr << " (EE) Cannot sign for id " << own_gxs_id << ". Signature call failed." << std::endl; - error_status = RS_GIXS_ERROR_UNKNOWN ; - return false ; - } - error_status = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(own_gxs_id,RsIdentityUsage(RsServiceType(serviceType()),RsIdentityUsage::IDENTITY_GENERIC_SIGNATURE_CREATION)) ; - - return true ; -} -bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,const RsIdentityUsage& info,uint32_t& signing_error) -{ - // RsIdentityDetails details ; - // getIdDetails(signature.keyId,details); - RsTlvPublicRSAKey signature_key ; - - for(int i=0;i< (force_load?6:1);++i) - if(!getKey(signature.keyId,signature_key) || signature_key.keyData.bin_data == NULL) - { -#ifdef DEBUG_IDS - std::cerr << " Cannot get key. Waiting for caching. try " << i << "/6" << std::endl; -#endif - if(force_load) rstime::rs_usleep(500 * 1000) ; // sleep for 500 msec. - } - else - break ; - - if(signature_key.keyData.bin_data == NULL) - { -#ifdef DEBUG_IDS - std::cerr << "(EE) Cannot validate signature for unknown key " << signature.keyId << std::endl; -#endif - signing_error = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ; - return false; - } - - if(!GxsSecurity::validateSignature((char*)data,data_size,signature_key,signature)) - { - std::cerr << "(SS) Signature was verified and it doesn't check! This is a security issue!" << std::endl; - signing_error = RS_GIXS_ERROR_SIGNATURE_MISMATCH ; - return false; - } - signing_error = RS_GIXS_ERROR_NO_ERROR ; - - timeStampKey(signature.keyId,info); - return true ; -} - -bool p3IdService::encryptData( const uint8_t *decrypted_data, - uint32_t decrypted_data_size, - uint8_t *& encrypted_data, - uint32_t& encrypted_data_size, - const RsGxsId& encryption_key_id, - uint32_t& error_status, - bool force_load ) -{ - RsTlvPublicRSAKey encryption_key ; - - // get the key, and let the cache find it. - for(int i=0; i<(force_load?6:1);++i) - if(getKey(encryption_key_id,encryption_key)) - break ; - else - rstime::rs_usleep(500*1000) ; // sleep half a sec. - - if(encryption_key.keyId.isNull()) - { - std::cerr << " (EE) Cannot get encryption key for id " << encryption_key_id << std::endl; - error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE ; - return false ; - } - - if(!GxsSecurity::encrypt(encrypted_data,encrypted_data_size,decrypted_data,decrypted_data_size,encryption_key)) - { - std::cerr << " (EE) Encryption failed." << std::endl; - error_status = RS_GIXS_ERROR_UNKNOWN ; - return false ; - } - error_status = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(encryption_key_id,RsIdentityUsage(RsServiceType::GXSID,RsIdentityUsage::IDENTITY_GENERIC_ENCRYPTION)) ; - - return true ; -} - -bool p3IdService::encryptData( const uint8_t* decrypted_data, - uint32_t decrypted_data_size, - uint8_t*& encrypted_data, - uint32_t& encrypted_data_size, - const std::set& encrypt_ids, - uint32_t& error_status, bool force_load ) -{ - std::set keyNotYetFoundIds; - - for( std::set::const_iterator it = encrypt_ids.begin(); - it != encrypt_ids.end(); ++it ) - { - const RsGxsId& gId(*it); - if(gId.isNull()) - { - std::cerr << "p3IdService::encryptData(...) (EE) got null GXS id" - << std::endl; - return false; - } - else keyNotYetFoundIds.insert(&gId); - } - - if(keyNotYetFoundIds.empty()) - { - std::cerr << "p3IdService::encryptData(...) (EE) got empty GXS ids set" - << std::endl; - print_stacktrace(); - return false; - } - - std::vector encryption_keys; - int maxRounds = force_load ? 6 : 1; - for( int i=0; i < maxRounds; ++i ) - { - for( std::set::iterator it = keyNotYetFoundIds.begin(); - it !=keyNotYetFoundIds.end(); ) - { - RsTlvPublicRSAKey encryption_key; - if(getKey(**it, encryption_key) && !encryption_key.keyId.isNull()) - { - encryption_keys.push_back(encryption_key); - it = keyNotYetFoundIds.erase(it); - } - else - { - ++it; - } - } - - if(keyNotYetFoundIds.empty()) break; - else rstime::rs_usleep(500*1000); - } - - if(!keyNotYetFoundIds.empty()) - { - std::cerr << "p3IdService::encryptData(...) (EE) Cannot get " - << "encryption key for: "; - for( std::set::iterator it = keyNotYetFoundIds.begin(); - it !=keyNotYetFoundIds.end(); ++it ) - std::cerr << **it << " "; - std::cerr << std::endl; - print_stacktrace(); - - error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE; - return false; - } - - if(!GxsSecurity::encrypt( encrypted_data, encrypted_data_size, - decrypted_data, decrypted_data_size, - encryption_keys )) - { - std::cerr << "p3IdService::encryptData(...) (EE) Encryption failed." - << std::endl; - print_stacktrace(); - - error_status = RS_GIXS_ERROR_UNKNOWN; - return false ; - } - - for( std::set::const_iterator it = encrypt_ids.begin(); - it != encrypt_ids.end(); ++it ) - { - timeStampKey( *it, - RsIdentityUsage( - RsServiceType::GXSID, - RsIdentityUsage::IDENTITY_GENERIC_ENCRYPTION ) ); - } - - error_status = RS_GIXS_ERROR_NO_ERROR; - return true; -} - -bool p3IdService::decryptData( const uint8_t *encrypted_data, - uint32_t encrypted_data_size, - uint8_t *& decrypted_data, - uint32_t& decrypted_size, - const RsGxsId& key_id, uint32_t& error_status, - bool force_load ) -{ - RsTlvPrivateRSAKey encryption_key ; - - // Get the key, and let the cache find it. It's our own key, so we should be able to find it, even if it takes - // some seconds. - - int maxRounds = force_load ? 6 : 1; - for(int i=0; i& decrypt_ids, - uint32_t& error_status, - bool force_load ) -{ - std::set keyNotYetFoundIds; - - for( std::set::const_iterator it = decrypt_ids.begin(); - it != decrypt_ids.end(); ++it ) - { - const RsGxsId& gId(*it); - if(gId.isNull()) - { - std::cerr << "p3IdService::decryptData(...) (EE) got null GXS id" - << std::endl; - print_stacktrace(); - return false; - } - else keyNotYetFoundIds.insert(&gId); - } - - if(keyNotYetFoundIds.empty()) - { - std::cerr << "p3IdService::decryptData(...) (EE) got empty GXS ids set" - << std::endl; - print_stacktrace(); - return false; - } - - std::vector decryption_keys; - int maxRounds = force_load ? 6 : 1; - for( int i=0; i < maxRounds; ++i ) - { - for( std::set::iterator it = keyNotYetFoundIds.begin(); - it !=keyNotYetFoundIds.end(); ) - { - RsTlvPrivateRSAKey decryption_key; - if( getPrivateKey(**it, decryption_key) - && !decryption_key.keyId.isNull() ) - { - decryption_keys.push_back(decryption_key); - it = keyNotYetFoundIds.erase(it); - } - else - { - ++it; - } - } - - if(keyNotYetFoundIds.empty()) break; - else rstime::rs_usleep(500*1000); - } - - if(!keyNotYetFoundIds.empty()) - { - std::cerr << "p3IdService::decryptData(...) (EE) Cannot get private key" - << " for: "; - for( std::set::iterator it = keyNotYetFoundIds.begin(); - it !=keyNotYetFoundIds.end(); ++it ) - std::cerr << **it << " "; - std::cerr << std::endl; - print_stacktrace(); - - error_status = RS_GIXS_ERROR_KEY_NOT_AVAILABLE; - return false; - } - - if(!GxsSecurity::decrypt( decrypted_data, decrypted_data_size, - encrypted_data, encrypted_data_size, - decryption_keys )) - { - std::cerr << "p3IdService::decryptData(...) (EE) Decryption failed." - << std::endl; - print_stacktrace(); - - error_status = RS_GIXS_ERROR_UNKNOWN; - return false ; - } - - for( std::set::const_iterator it = decrypt_ids.begin(); - it != decrypt_ids.end(); ++it ) - { - timeStampKey( *it, - RsIdentityUsage( - RsServiceType::GXSID, - RsIdentityUsage::IDENTITY_GENERIC_DECRYPTION ) ); - } - - error_status = RS_GIXS_ERROR_NO_ERROR; - return true; -} - -#ifdef TO_BE_REMOVED -/********************************************************************************/ -/******************* RsGixsReputation ***************************************/ -/********************************************************************************/ - -bool p3IdService::haveReputation(const RsGxsId &id) -{ - return haveKey(id); -} - -bool p3IdService::loadReputation(const RsGxsId &id, const std::list& peers) -{ - if (haveKey(id)) - return true; - else - { - if(isPendingNetworkRequest(id)) - return true; - } - - - return cache_request_load(id, peers); -} - -bool p3IdService::getReputation(const RsGxsId &id, GixsReputation &rep) -{ - /* this is the key part for accepting messages */ - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - RsGxsIdCache data; - - if (mKeyCache.fetch(id, data)) - { - rep.id = id; - rep.score = 0;//data.details.mReputation.mOverallScore; -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getReputation() id: "; - std::cerr << id.toStdString() << " score: " << - rep.score; - std::cerr << std::endl; -#endif - - return true; - } - else - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getReputation() id: "; - std::cerr << id.toStdString() << " not cached"; - std::cerr << std::endl; -#endif - } - return false; -} -#endif - -#if 0 -class RegistrationRequest -{ -public: - RegistrationRequest(uint32_t token, RsGxsId &id, int score) - :m_extToken(token), m_id(id), m_score(score) { return; } - - uint32_t m_intToken; - uint32_t m_extToken; - RsGxsId m_id; - int m_score; -}; -#endif - - -bool p3IdService::submitOpinion(uint32_t& token, const RsGxsId &id, bool absOpinion, int score) -{ -#ifdef DEBUG_OPINION - std::cerr << "p3IdService::submitOpinion()"; - std::cerr << std::endl; -#endif - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - - token = RsGenExchange::generatePublicToken(); - - uint32_t intToken; - std::list groups; - groups.push_back(RsGxsGroupId(id)); - - RsGenExchange::getTokenService()->requestGroupInfo(intToken, ansType, opts, groups); - GxsTokenQueue::queueRequest(intToken, GXSIDREQ_OPINION); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mPendingOpinion[intToken] = OpinionRequest(token, id, absOpinion, score); - return true; -} - - - -bool p3IdService::opinion_handlerequest(uint32_t token) -{ -#ifdef DEBUG_OPINION - std::cerr << "p3IdService::opinion_handlerequest()"; - std::cerr << std::endl; -#endif - - OpinionRequest req; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - /* find in pendingReputation */ - std::map::iterator it; - it = mPendingOpinion.find(token); - if (it == mPendingOpinion.end()) - { - std::cerr << "p3IdService::opinion_handlerequest() ERROR finding PendingOpinion"; - std::cerr << std::endl; - - return false; - } - req = it->second; - mPendingOpinion.erase(it); - } - -#ifdef DEBUG_OPINION - std::cerr << "p3IdService::opinion_handlerequest() Id: " << req.mId << " score: " << req.mScore; - std::cerr << std::endl; -#endif - - std::list groups; - std::list groupList; - - if (!getGroupMeta(token, groups)) - { - std::cerr << "p3IdService::opinion_handlerequest() ERROR getGroupMeta()"; - std::cerr << std::endl; - - updatePublicRequestStatus(req.mToken, RsTokenService::FAILED); - return false; - } - - if (groups.size() != 1) - { - std::cerr << "p3IdService::opinion_handlerequest() ERROR group.size() != 1"; - std::cerr << std::endl; - - // error. - updatePublicRequestStatus(req.mToken, RsTokenService::FAILED); - return false; - } - RsGroupMetaData &meta = *(groups.begin()); - - if (meta.mGroupId != RsGxsGroupId(req.mId)) - { - std::cerr << "p3IdService::opinion_handlerequest() ERROR Id mismatch"; - std::cerr << std::endl; - - // error. - updatePublicRequestStatus(req.mToken, RsTokenService::FAILED); - return false; - } - - /* get the string */ - SSGxsIdGroup ssdata; - ssdata.load(meta.mServiceString); // attempt load - okay if fails. - - /* modify score */ - if (req.mAbsOpinion) - { - ssdata.score.rep.mOwnOpinion = req.mScore; - } - else - { - ssdata.score.rep.mOwnOpinion += req.mScore; - } - - // update IdScore too. - bool pgpId = (meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility); - ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature); - ssdata.score.rep.update(); - - /* save string */ - std::string serviceString = ssdata.save(); -#ifdef DEBUG_OPINION - std::cerr << "p3IdService::opinion_handlerequest() new service_string: " << serviceString; - std::cerr << std::endl; -#endif - - /* set new Group ServiceString */ - uint32_t dummyToken = 0; - setGroupServiceString(dummyToken, meta.mGroupId, serviceString); - cache_update_if_cached(RsGxsId(meta.mGroupId), serviceString); - - updatePublicRequestStatus(req.mToken, RsTokenService::COMPLETE); - return true; -} - - -/********************************************************************************/ -/******************* Get/Set Data ******************************************/ -/********************************************************************************/ - -RsSerialiser *p3IdService::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - - rss->addSerialType(new RsGxsIdSerialiser()) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss ; -} - -bool p3IdService::getGroupData(const uint32_t &token, std::vector &groups) -{ - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - if (item) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getGroupData() Item is:"; - std::cerr << std::endl; - item->print(std::cerr); - std::cerr << std::endl; -#endif // DEBUG_IDS - RsGxsIdGroup group ; - item->toGxsIdGroup(group,false) ; - - { - RS_STACK_MUTEX(mIdMtx) ; - group.mLastUsageTS = locked_getLastUsageTS(RsGxsId(group.mMeta.mGroupId)) ; - } - - // Decode information from serviceString. - SSGxsIdGroup ssdata; - if (ssdata.load(group.mMeta.mServiceString)) - { - group.mPgpKnown = ssdata.pgp.validatedSignature; - group.mPgpId = ssdata.pgp.pgpId; - group.mReputation = ssdata.score.rep; -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getGroupData() Success decoding ServiceString"; - std::cerr << std::endl; - std::cerr << "\t mGpgKnown: " << group.mPgpKnown; - std::cerr << std::endl; - std::cerr << "\t mGpgId: " << group.mPgpId; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { - group.mPgpKnown = false; - group.mPgpId.clear(); - - if(!group.mMeta.mServiceString.empty()) - std::cerr << "p3IdService::getGroupData() " << group.mMeta.mGroupId << " (" << group.mMeta.mGroupName << ") : Failed to decode, or no ServiceString \"" << group.mMeta.mServiceString << "\"" << std::endl; - } - - group.mIsAContact = (mContacts.find(RsGxsId(group.mMeta.mGroupId)) != mContacts.end()); - group.mPgpLinked = (!!(group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)) || !!(group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID); - - groups.push_back(group); - delete(item); - } - else - { - std::cerr << "Not a Id Item, deleting!" << std::endl; - delete(*vit); - } - } - } - - return ok; -} - -bool p3IdService::getGroupSerializedData(const uint32_t &token, std::map& serialized_groups) -{ - unsigned char *mem = NULL; - uint32_t size; - RsGxsGroupId id ; - - serialized_groups.clear() ; - - if(!RsGenExchange::getSerializedGroupData(token,id, mem,size)) - { - std::cerr << "(EE) call to RsGenExchage::getSerializedGroupData() failed." << std::endl; - return false; - } - - std::string radix ; - - Radix64::encode(mem,size,radix) ; - - serialized_groups[RsGxsId(id)] = radix ; - - return true; -} - -/********************************************************************************/ -/********************************************************************************/ -/********************************************************************************/ - -bool p3IdService::createGroup(uint32_t& token, RsGxsIdGroup &group) -{ - RsGxsIdGroupItem* item = new RsGxsIdGroupItem(); - - item->meta = group.mMeta; - item->mImage.binData.setBinData(group.mImage.mData, group.mImage.mSize); - - RsGenExchange::publishGroup(token, item); - return true; -} - -bool p3IdService::updateGroup(uint32_t& token, RsGxsIdGroup &group) -{ - RsGxsId id(group.mMeta.mGroupId); - RsGxsIdGroupItem* item = new RsGxsIdGroupItem(); - - item->fromGxsIdGroup(group,false) ; - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::updateGroup() Updating RsGxsId: " << id; - std::cerr << std::endl; -#endif - - RsGenExchange::updateGroup(token, item); - - // if its in the cache - clear it. - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mKeyCache.erase(id)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::updateGroup() Removed from PublicKeyCache"; - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::updateGroup() Not in PublicKeyCache"; - std::cerr << std::endl; -#endif - } - } - - return true; -} - -bool p3IdService::deleteGroup(uint32_t& token, RsGxsGroupId& groupId) -{ - RsGxsId id(groupId); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteGroup() Deleting RsGxsId: " << id; - std::cerr << std::endl; -#endif - - RsGenExchange::deleteGroup(token, groupId); - - // if its in the cache - clear it. - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (mKeyCache.erase(id)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteGroup() Removed from PublicKeyCache"; - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteGroup() Not in PublicKeyCache"; - std::cerr << std::endl; -#endif - } - - std::list::iterator lit = std::find( mOwnIds.begin(), mOwnIds.end(), id); - if (lit != mOwnIds.end()) - { - mOwnIds.remove((RsGxsId)*lit); -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteGroup() Removed from OwnIds"; - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::deleteGroup() Not in OwnIds"; - std::cerr << std::endl; -#endif - } - } - - return true; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* Encoding / Decoding Group Service String stuff - * - * Pgp stuff. - * - * If flagged as pgp id.... - * then we need to know if its been matched, or when we last tried to match. - * - */ - -bool SSGxsIdPgp::load(const std::string &input) -{ - char pgpline[RSGXSID_MAX_SERVICE_STRING]; - int timestamp = 0; - uint32_t attempts = 0; - if (1 == sscanf(input.c_str(), "K:1 I:%[^)]", pgpline)) - { - validatedSignature = true; - std::string str_line = pgpline; - pgpId = RsPgpId(str_line); - return true; - } - else if (3 == sscanf(input.c_str(), "K:0 T:%d C:%d I:%[^)]", ×tamp, &attempts,pgpline)) - { - lastCheckTs = timestamp; - checkAttempts = attempts; - validatedSignature = false; - std::string str_line = pgpline; - pgpId = RsPgpId(str_line); - return true; - } - else if (2 == sscanf(input.c_str(), "K:0 T:%d C:%d", ×tamp, &attempts)) - { - lastCheckTs = timestamp; - checkAttempts = attempts; - validatedSignature = false; - return true; - } - else if (1 == sscanf(input.c_str(), "K:0 T:%d", ×tamp)) - { - lastCheckTs = timestamp; - checkAttempts = 0; - validatedSignature = false; - return true; - } - else - { - lastCheckTs = 0; - checkAttempts = 0; - validatedSignature = false; - return false; - } -} - -std::string SSGxsIdPgp::save() const -{ - std::string output; - if (validatedSignature) - { - output += "K:1 I:"; - output += pgpId.toStdString(); - } - else - { - rs_sprintf(output, "K:0 T:%d C:%d", lastCheckTs, checkAttempts); - - if(!pgpId.isNull()) - output += " I:"+pgpId.toStdString(); - } - return output; -} - - -/* Encoding / Decoding Group Service String stuff - * - * RecognTags. - */ - -bool SSGxsIdRecognTags::load(const std::string &input) -{ - //char pgpline[RSGXSID_MAX_SERVICE_STRING]; - int pubTs = 0; - int lastTs = 0; - uint32_t flags = 0; - - if (3 == sscanf(input.c_str(), "F:%u P:%d T:%d", &flags, &pubTs, &lastTs)) - { - publishTs = pubTs; - lastCheckTs = lastTs; - tagFlags = flags; - } - else - { - return false; - } - return true; -} - -std::string SSGxsIdRecognTags::save() const -{ - std::string output; - rs_sprintf(output, "F:%u P:%d T:%d", tagFlags, publishTs, lastCheckTs); - return output; -} - -bool SSGxsIdRecognTags::tagsProcessed() const -{ - return (tagFlags & 0x1000); -} - -bool SSGxsIdRecognTags::tagsPending() const -{ - return (tagFlags & 0x2000); -} - -bool SSGxsIdRecognTags::tagValid(int i) const -{ - uint32_t idx = 0x01 << i; - -#ifdef DEBUG_RECOGN - std::cerr << "SSGxsIdRecognTags::tagValid(" << i << ") idx: " << idx; - std::cerr << " result: " << (tagFlags & idx); - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - return (tagFlags & idx); -} - -void SSGxsIdRecognTags::setTags(bool processed, bool pending, uint32_t flags) -{ - flags &= 0x00ff; // clear top bits; - if (processed) - { - flags |= 0x1000; - } - if (pending) - { - flags |= 0x2000; - } - -#ifdef DEBUG_RECOGN - std::cerr << "SSGxsIdRecognTags::setTags(" << processed << "," << pending << "," << flags << ")"; - std::cerr << " tagFlags: " << tagFlags; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - tagFlags = flags; -} - - -GxsReputation::GxsReputation() - :mOverallScore(0), mIdScore(0), mOwnOpinion(0), mPeerOpinion(0) -{ - updateIdScore(false, false); - update(); -} - -static const int kIdReputationPgpKnownScore = 50; -static const int kIdReputationPgpUnknownScore = 20; -static const int kIdReputationAnonScore = 5; - -bool GxsReputation::updateIdScore(bool pgpLinked, bool pgpKnown) -{ - if (pgpLinked) - { - if (pgpKnown) - { - mIdScore = kIdReputationPgpKnownScore; - } - else - { - mIdScore = kIdReputationPgpUnknownScore; - } - } - else - { - mIdScore = kIdReputationAnonScore; - } - return true; -} - -bool GxsReputation::update() -{ - mOverallScore = mIdScore + mOwnOpinion + mPeerOpinion; - return true; -} - - -bool SSGxsIdReputation::load(const std::string &input) -{ - return (4 == sscanf(input.c_str(), "%d %d %d %d", - &(rep.mOverallScore), &(rep.mIdScore), &(rep.mOwnOpinion), &(rep.mPeerOpinion))); -} - -std::string SSGxsIdReputation::save() const -{ - std::string output; - rs_sprintf(output, "%d %d %d %d", rep.mOverallScore, rep.mIdScore, rep.mOwnOpinion, rep.mPeerOpinion); - return output; -} - - -bool SSGxsIdCumulator::load(const std::string &input) -{ - return (4 == sscanf(input.c_str(), "%d %d %lf %lf", &count, &nullcount, &sum, &sumsq)); -} - -std::string SSGxsIdCumulator::save() const -{ - std::string output; - rs_sprintf(output, "%d %d %lf %lf", count, nullcount, sum, sumsq); - return output; -} - -bool SSGxsIdGroup::load(const std::string &input) -{ - char pgpstr[RSGXSID_MAX_SERVICE_STRING]; - char recognstr[RSGXSID_MAX_SERVICE_STRING]; - char scorestr[RSGXSID_MAX_SERVICE_STRING]; - - // split into parts. - if (3 != sscanf(input.c_str(), "v2 {P:%[^}]}{T:%[^}]}{R:%[^}]}", pgpstr, recognstr, scorestr)) - { -#ifdef DEBUG_SERVICE_STRING - std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts"; - std::cerr << std::endl; -#endif // DEBUG_IDS - return false; - } - - bool ok = true; - if (pgp.load(pgpstr)) - { -#ifdef DEBUG_SERVICE_STRING - std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { -#ifdef DEBUG_SERVICE_STRING - std::cerr << "SSGxsIdGroup::load() Invalid pgpstr: " << pgpstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - ok = false; - } - - if (recogntags.load(recognstr)) - { -#ifdef DEBUG_RECOGN - std::cerr << "SSGxsIdGroup::load() recognstr: " << recognstr; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "SSGxsIdGroup::load() Invalid recognstr: " << recognstr; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - ok = false; - } - - if (score.load(scorestr)) - { -#ifdef DEBUG_SERVICE_STRING - std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { -#ifdef DEBUG_SERVICE_STRING - std::cerr << "SSGxsIdGroup::load() Invalid scorestr: " << scorestr; - std::cerr << std::endl; -#endif // DEBUG_IDS - ok = false; - } - -#if 0 - if (opinion.load(opinionstr)) - { -#ifdef DEBUG_IDS - std::cerr << "SSGxsIdGroup::load() opinionstr: " << opinionstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { -#ifdef DEBUG_IDS - std::cerr << "SSGxsIdGroup::load() Invalid opinionstr: " << opinionstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - ok = false; - } - - if (reputation.load(repstr)) - { -#ifdef DEBUG_IDS - std::cerr << "SSGxsIdGroup::load() repstr: " << repstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { -#ifdef DEBUG_IDS - std::cerr << "SSGxsIdGroup::load() Invalid repstr: " << repstr; - std::cerr << std::endl; -#endif // DEBUG_IDS - ok = false; - } -#endif - -#ifdef DEBUG_IDS - std::cerr << "SSGxsIdGroup::load() regurgitated: " << save(); - std::cerr << std::endl; - - std::cerr << "SSGxsIdGroup::load() isOkay?: " << ok; - std::cerr << std::endl; -#endif // DEBUG_IDS - return ok; -} - -std::string SSGxsIdGroup::save() const -{ - std::string output = "v2 "; - - output += "{P:"; - output += pgp.save(); - output += "}"; - - output += "{T:"; - output += recogntags.save(); - output += "}"; - - output += "{R:"; - output += score.save(); - output += "}"; - - //std::cerr << "SSGxsIdGroup::save() output: " << output; - //std::cerr << std::endl; - - return output; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* Cache of recently used keys - * - * It is expensive to fetch the keys, so we want to keep them around if possible. - * It only stores the immutable stuff. - * - * This is probably crude and crap to start with. - * Want Least Recently Used (LRU) discard policy, without having to search whole cache. - * Use two maps: - * - CacheMap[key] => data. - * - LRUMultiMap[AccessTS] => key - * - * NOTE: This could be moved to a seperate class and templated to make generic - * as it might be generally useful. - * - */ - -RsGxsIdCache::RsGxsIdCache() {} - -RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pkey, const std::list &tagList) -{ - init(item,in_pkey,RsTlvPrivateRSAKey(),tagList) ; -} - -RsGxsIdCache::RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pkey, const RsTlvPrivateRSAKey& privkey, const std::list &tagList) -{ - init(item,in_pkey,privkey,tagList) ; -} - -void RsGxsIdCache::init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list &tagList) -{ - // Save Keys. - pub_key = in_pub_key; - priv_key = in_priv_key; - - // Save Time for ServiceString comparisions. - mPublishTs = item->meta.mPublishTs; - - // Save RecognTags. - mRecognTags = tagList; - - details.mAvatar.copy((uint8_t *) item->mImage.binData.bin_data, item->mImage.binData.bin_len); - - // Fill in Details. - details.mNickname = item->meta.mGroupName; - details.mId = RsGxsId(item->meta.mGroupId); - -#ifdef DEBUG_IDS - std::cerr << "RsGxsIdCache::RsGxsIdCache() for: " << details.mId; - std::cerr << std::endl; -#endif // DEBUG_IDS - - details.mFlags = 0 ; - - if(item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) details.mFlags |= RS_IDENTITY_FLAGS_IS_OWN_ID; - if(item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) details.mFlags |= RS_IDENTITY_FLAGS_PGP_LINKED; - - // do some tests - if(details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) - { - if(!priv_key.checkKey()) - std::cerr << "(EE) Private key missing for own identity " << pub_key.keyId << std::endl; - - } - if(!pub_key.checkKey()) - std::cerr << "(EE) Public key missing for identity " << pub_key.keyId << std::endl; - - if(!GxsSecurity::checkFingerprint(pub_key)) - details.mFlags |= RS_IDENTITY_FLAGS_IS_DEPRECATED; - - /* rest must be retrived from ServiceString */ - updateServiceString(item->meta.mServiceString); -} - -void RsGxsIdCache::updateServiceString(std::string serviceString) -{ - details.mRecognTags.clear(); - - SSGxsIdGroup ssdata; - if (ssdata.load(serviceString)) - { - if (details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) - { - if(ssdata.pgp.validatedSignature) details.mFlags |= RS_IDENTITY_FLAGS_PGP_KNOWN ; - - if (details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) - details.mPgpId = ssdata.pgp.pgpId; - else - details.mPgpId.clear(); - } - - - // process RecognTags. - if (ssdata.recogntags.tagsProcessed()) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsGxsIdCache::updateServiceString() updating recogntags"; - std::cerr << std::endl; -#endif - if (ssdata.recogntags.publishTs == mPublishTs) - { - std::list::iterator it; - int i = 0; - for(it = mRecognTags.begin(); it != mRecognTags.end(); ++it, i++) - { - if (ssdata.recogntags.tagValid(i) && it->valid) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsGxsIdCache::updateServiceString() Valid Tag: " << it->tag_class << ":" << it->tag_type; - std::cerr << std::endl; -#endif - details.mRecognTags.push_back(*it); - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "RsGxsIdCache::updateServiceString() Invalid Tag: " << it->tag_class << ":" << it->tag_type; - std::cerr << std::endl; -#endif - } - } - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "RsGxsIdCache::updateServiceString() recogntags old publishTs"; - std::cerr << std::endl; -#endif - } - - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "RsGxsIdCache::updateServiceString() recogntags unprocessed"; - std::cerr << std::endl; -#endif - } - - // copy over Reputation scores. - //details.mReputation = ssdata.score.rep; - } - else - { - details.mFlags &= ~RS_IDENTITY_FLAGS_PGP_KNOWN ; - details.mPgpId.clear(); - //details.mReputation.updateIdScore(false, false); - //details.mReputation.update(); - } -} - - -bool p3IdService::recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list &tagItems) -{ -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_extract_taginfo()"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - /* process Recogn Tags */ - - std::list::const_iterator rit; - int count = 0; - for(rit = item->mRecognTags.begin(); rit != item->mRecognTags.end(); ++rit) - { - if (++count > RSRECOGN_MAX_TAGINFO) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_extract_taginfo() Too many tags."; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - return true; - } - - RsGxsRecognTagItem *tagitem = RsRecogn::extractTag(*rit); - - if (!tagitem) - { - continue; - } - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_extract_taginfo() Got TagItem: "; - std::cerr << std::endl; - tagitem->print(std::cerr); -#endif // DEBUG_RECOGN - - tagItems.push_back(tagitem); - } - return true; -} - - -bool p3IdService::cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list &tagList) -{ - /* ServiceString decode */ - SSGxsIdGroup ssdata; - bool recognProcess = false; - if (ssdata.load(item->meta.mServiceString)) - { - if (!ssdata.recogntags.tagsProcessed()) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() tags not processed"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - /* we need to reprocess it */ - recognProcess = true; - } - else - { - if (item->meta.mPublishTs != ssdata.recogntags.publishTs) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() publishTs old"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - recognProcess = true; - } - else if (ssdata.recogntags.tagsPending()) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() tagsPending"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - /* reprocess once a day */ - recognProcess = true; - } - } - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() ServiceString invalid"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - recognProcess = true; - } - - std::list tagItems; - std::list::iterator it; - - recogn_extract_taginfo(item, tagItems); - - //rstime_t now = time(NULL); - for(it = tagItems.begin(); it != tagItems.end(); ++it) - { - RsRecognTag info((*it)->tag_class, (*it)->tag_type, false); - bool isPending = false; - if (recogn_checktag(RsGxsId(item->meta.mGroupId.toStdString()), item->meta.mGroupName, *it, false, isPending)) - { - info.valid = true; - } -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() Adding Tag: "; - std::cerr << info.tag_class << ":"; - std::cerr << info.tag_type << ":"; - std::cerr << info.valid; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - tagList.push_back(info); - delete *it; - } - - - if (recognProcess) - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mRecognGroupIds.push_back(item->meta.mGroupId); - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::cache_process_recogntaginfo() Reprocessing groupId: "; - std::cerr << item->meta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - recogn_schedule(); - } - - return true; -} - -// Loads in the cache the group data from the given group item, retrieved from sqlite storage. - -bool p3IdService::cache_store(const RsGxsIdGroupItem *item) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_store() Item: " << item->meta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_IDS - //item->print(std::cerr, 0); NEEDS CONST!!!! TODO - //std::cerr << std::endl; - - /* extract key from keys */ - RsTlvSecurityKeySet keySet; - - RsTlvPublicRSAKey pubkey; - RsTlvPrivateRSAKey fullkey; - - bool pub_key_ok = false; - bool full_key_ok = false; - - RsGxsId id (item->meta.mGroupId.toStdString()); - - if (!getGroupKeys(RsGxsGroupId(id.toStdString()), keySet)) - { - std::cerr << "p3IdService::cache_store() ERROR getting GroupKeys for: "<< item->meta.mGroupId << std::endl; - return false; - } - - for (std::map::iterator kit = keySet.private_keys.begin(); kit != keySet.private_keys.end(); ++kit) - if (kit->second.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_store() Found Admin Key" << std::endl; -#endif - fullkey = kit->second; - full_key_ok = true; - } - for (std::map::iterator kit = keySet.public_keys.begin(); kit != keySet.public_keys.end(); ++kit) - if (kit->second.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_store() Found Admin public Key" << std::endl; -#endif - pubkey = kit->second; - pub_key_ok = true ; - } - - assert(!( pubkey.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - assert(!full_key_ok || (fullkey.keyFlags & RSTLV_KEY_TYPE_FULL)) ; - - if (!pub_key_ok) - { - std::cerr << "p3IdService::cache_store() ERROR No Public Key Found"; - std::cerr << std::endl; - return false; - } - - // extract tags. - std::list tagList; - cache_process_recogntaginfo(item, tagList); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - // Create Cache Data. - RsGxsIdCache keycache(item, pubkey, fullkey,tagList); - - if(mContacts.find(id) != mContacts.end()) - keycache.details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT; - - mKeyCache.store(id, keycache); - mKeyCache.resize(); - - return true; -} - - - -/***** BELOW LOADS THE CACHE FROM GXS DATASTORE *****/ - -#define MIN_CYCLE_GAP 2 - -bool p3IdService::cache_request_load(const RsGxsId &id, const std::list &peers) -{ - Dbg4() << __PRETTY_FUNCTION__ << " id: " << id << std::endl; - - { - RS_STACK_MUTEX(mIdMtx); - // merge, even if peers is empty - mergeIds(mCacheLoad_ToCache, id, peers); - } - - if(RsTickEvent::event_count(GXSID_EVENT_CACHELOAD) > 0) - { - Dbg3() << __PRETTY_FUNCTION__ << " cache reload already scheduled " - << "skipping" << std::endl; - return true; - } - - int32_t age = 0; - if( RsTickEvent::prev_event_ago(GXSID_EVENT_CACHELOAD, age) && age < MIN_CYCLE_GAP ) - { - RsTickEvent::schedule_in(GXSID_EVENT_CACHELOAD, MIN_CYCLE_GAP - age); - return true; - } - - RsTickEvent::schedule_now(GXSID_EVENT_CACHELOAD); - return true; -} - - -bool p3IdService::cache_start_load() -{ - /* trigger request to load missing ids into cache */ - std::list groupIds; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - /* now we process the modGroupList -> a map so we can use it easily later, and create id list too */ - std::map >::iterator it; - for(it = mCacheLoad_ToCache.begin(); it != mCacheLoad_ToCache.end(); ++it) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_start_load() GroupId: " << it->first; - std::cerr << std::endl; -#endif // DEBUG_IDS - groupIds.push_back(RsGxsGroupId(it->first)); // might need conversion? - } - - for(std::map >::const_iterator it(mCacheLoad_ToCache.begin());it!=mCacheLoad_ToCache.end();++it) - mergeIds(mPendingCache,it->first,it->second) ; - - mCacheLoad_ToCache.clear(); - } - - if (groupIds.size() > 0) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_start_load() #Groups: " << groupIds.size(); - std::cerr << std::endl; -#endif // DEBUG_IDS - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, groupIds); - GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHELOAD); - } - return 1; -} - - -bool p3IdService::cache_load_for_token(uint32_t token) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_load_for_token() : " << token; - std::cerr << std::endl; -#endif // DEBUG_IDS - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - if (!item) - { - std::cerr << "Not a RsGxsIdGroupItem Item, deleting!" << std::endl; - delete(*vit); - continue; - } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_load_for_token() Loaded Id with Meta: "; - std::cerr << item->meta; - std::cerr << std::endl; -#endif // DEBUG_IDS - - - { - // remove identities that are present - RsStackMutex stack(mIdMtx); - mPendingCache.erase(RsGxsId(item->meta.mGroupId.toStdString())); - } - - /* cache the data */ - cache_store(item); - delete item; - } - - { - // now store identities that aren't present - - RsStackMutex stack(mIdMtx); - - // No need to merge empty peers since the request would fail. - - for(std::map >::const_iterator itt(mPendingCache.begin());itt!=mPendingCache.end();++itt) - if(!itt->second.empty()) - mergeIds(mIdsNotPresent,itt->first,itt->second) ; -#ifdef DEBUG_IDS - else - std::cerr << "(WW) empty list of peers to request ID " << itt->first << ": cannot request" << std::endl; -#endif - - - mPendingCache.clear(); - - if(!mIdsNotPresent.empty()) - schedule_now(GXSID_EVENT_REQUEST_IDS); - } - - } - else - { - std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; - } - return true; -} - -void p3IdService::requestIdsFromNet() -{ - RS_STACK_MUTEX(mIdMtx); - - if(!mNes) - { - RsErr() << __PRETTY_FUNCTION__ << " Cannot request missing GXS IDs " - << "because network service is not present." << std::endl; - return; - } - - std::map >::iterator cit; - std::map > requests; - - /* Transform to appropriate structure ( > map) - * to make request to nes per peer ID - * Only delete entries in mIdsNotPresent that can actually be performed, or - * that have empty peer list */ - - for(cit = mIdsNotPresent.begin(); cit != mIdsNotPresent.end();) - { -#ifdef DEBUG_IDS - Dbg2() << __PRETTY_FUNCTION__ << " Processing missing key RsGxsId: " << cit->first << std::endl; -#endif - RsGxsIdCache data; - - if(mKeyCache.fetch(cit->first,data)) - { -#ifdef DEBUG_IDS - std::cerr << __PRETTY_FUNCTION__ << ". Dropping request for ID " << cit->first << " at last minute, because it was found in cache"<< std::endl; -#endif - auto tmp(cit); - ++tmp; - mIdsNotPresent.erase(cit); - cit = tmp; - continue; - } - - const RsGxsId& gxsId = cit->first; - const std::list& peers = cit->second; - std::list::const_iterator cit2; - - bool request_can_proceed = false ; - - for(cit2 = peers.begin(); cit2 != peers.end(); ++cit2) - { - const RsPeerId& peer = *cit2; - - if(rsPeers->isOnline(peer) || mNes->isDistantPeer(peer)) - { - /* make sure that the peer in online, so that we know that the - * request has some chance to succeed.*/ - requests[peer].push_back(cit->first); - request_can_proceed = true ; - -#ifdef DEBUG_IDS - Dbg2() << __PRETTY_FUNCTION__ << " Moving missing key RsGxsId:" - << gxsId << " to peer: " << peer << " requests queue" - << std::endl; -#endif - } - } - - const bool noPeersFound = peers.empty(); - if(noPeersFound) - RsWarn() << __PRETTY_FUNCTION__ << " No peers supplied to request " - << "RsGxsId: " << gxsId << " dropping." << std::endl; - - if(request_can_proceed || noPeersFound) - { - std::map >::iterator tmp(cit); - ++tmp; - mIdsNotPresent.erase(cit); - cit = tmp; - } - else - { -#ifdef DEBUG_IDS - RsInfo() << __PRETTY_FUNCTION__ << " no online peers among supplied" - << " list in request for RsGxsId: " << gxsId - << ". Keeping it until peers show up."<< std::endl; -#endif - ++cit; - } - } - - for( std::map >::const_iterator cit2( - requests.begin() ); cit2 != requests.end(); ++cit2 ) - { - const RsPeerId& peer = cit2->first; - std::list grpIds; - for( std::list::const_iterator gxs_id_it = cit2->second.begin(); gxs_id_it != cit2->second.end(); ++gxs_id_it ) - { -#ifdef DEBUG_IDS - Dbg2() << __PRETTY_FUNCTION__ << " passing RsGxsId: " << *gxs_id_it - << " request for peer: " << peer - << " to RsNetworkExchangeService " << std::endl; -#endif - grpIds.push_back(RsGxsGroupId(*gxs_id_it)); - } - - mNes->requestGrp(grpIds, peer); - } -} - -bool p3IdService::cache_update_if_cached(const RsGxsId &id, std::string serviceString) -{ - /* if these entries are cached - update with new info */ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_update_if_cached(" << id << ")"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* retrieve - update, save */ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - RsGxsIdCache updated_data; - - if(mKeyCache.fetch(id, updated_data)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_update_if_cached() Updating Public Cache"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - updated_data.updateServiceString(serviceString); - - mKeyCache.store(id, updated_data); - } - - return true; -} - -/************************************************************************************/ -/************************************************************************************/ - -bool p3IdService::cache_request_ownids() -{ - /* trigger request to load missing ids into cache */ - std::list groupIds; -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_request_ownids()"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - //opts.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHEOWNIDS); - return true; -} - - -bool p3IdService::cache_load_ownids(uint32_t token) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cache_load_ownids() : " << token; - std::cerr << std::endl; -#endif // DEBUG_IDS - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - // Save List - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mOwnIds.clear(); - for(vit = grpData.begin(); vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - if (!item) - { - std::cerr << "Not a IdOpinion Item, deleting!" << std::endl; - delete(*vit); - continue; - } - - if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) - { - mOwnIds.push_back(RsGxsId(item->meta.mGroupId)); - - SSGxsIdGroup ssdata; - - std::cerr << "Adding own ID " << item->meta.mGroupId << " mGroupFlags=" << std::hex << item->meta.mGroupFlags << std::dec; - - if (ssdata.load(item->meta.mServiceString) && ssdata.pgp.validatedSignature) // (cyril) note: we cannot use if(item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) - { // or we need to cmbine it with the deprecated value that overlaps with GXS_SERV::FLAG_PRIVACY_PRIVATE - std::cerr << " signed = YES" << std::endl; // see comments line 799 in ::createIdentity(); - mOwnSignedIds.push_back(RsGxsId(item->meta.mGroupId)); - } - else - std::cerr << " signed = NO" << std::endl; - - // This prevents automatic deletion to get rid of them. - // In other words, own ids are always used. - - mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ; - } - delete item ; - } - mOwnIdsLoaded = true ; - - std::cerr << mOwnIds.size() << " own Ids loaded, " << mOwnSignedIds.size() << " of which are signed" << std::endl; - } - - // No need to cache these items... - // as it just causes the cache to be flushed. -#if 0 - // Cache Items too. - for(vit = grpData.begin(); vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - if (item->meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) - { - - std::cerr << "p3IdService::cache_load_ownids() Loaded Id with Meta: "; - std::cerr << item->meta; - std::cerr << std::endl; - - /* cache the data */ - cache_store(item); - } - delete item; - } -#endif - - } - else - { - std::cerr << "p3IdService::cache_load_ownids() ERROR no data"; - std::cerr << std::endl; - - return false; - } - return true; -} - -/************************************************************************************/ -/************************************************************************************/ - -bool p3IdService::cachetest_getlist() -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_getlist() making request"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, GXSIDREQ_CACHETEST); - - // Schedule Next Event. - RsTickEvent::schedule_in(GXSID_EVENT_CACHETEST, CACHETEST_PERIOD); - return true; -} - -bool p3IdService::cachetest_handlerequest(uint32_t token) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_handlerequest() token: " << token; - std::cerr << std::endl; -#endif // DEBUG_IDS - - std::list grpIds; - std::list grpIdsC; - bool ok = RsGenExchange::getGroupList(token, grpIdsC); - - std::list::const_iterator cit = grpIdsC.begin(); - for(; cit != grpIdsC.end(); ++cit) - grpIds.push_back(RsGxsId(cit->toStdString())); - - if(ok) - { - std::list::iterator vit = grpIds.begin(); - for(; vit != grpIds.end(); ++vit) - { - /* 5% chance of checking it! */ - if (RSRandom::random_f32() < 0.25) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_request() Testing Id: " << *vit; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* try the cache! */ - if (!haveKey(*vit)) - { - std::list nullpeers; - requestKey(*vit, nullpeers,RsIdentityUsage(RsServiceType::GXSID,RsIdentityUsage::UNKNOWN_USAGE)); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_request() Requested Key Id: " << *vit; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { - RsTlvPublicRSAKey seckey; - if (getKey(*vit, seckey)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_request() Got Key OK Id: " << *vit; - std::cerr << std::endl; -#endif // DEBUG_IDS - - // success! - seckey.print(std::cerr, 10); - std::cerr << std::endl; - - - } - else - { - std::cerr << "p3IdService::cachetest_request() ERROR no Key for Id: " << *vit; - std::cerr << std::endl; - } - } - - /* try private key too! */ - if (!havePrivateKey(*vit)) - { - requestPrivateKey(*vit); -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_request() Requested PrivateKey Id: " << *vit; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { - RsTlvPrivateRSAKey seckey; - if (getPrivateKey(*vit, seckey)) - { - // success! -#ifdef DEBUG_IDS - std::cerr << "p3IdService::cachetest_request() Got PrivateKey OK Id: " << *vit; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - { - std::cerr << "p3IdService::cachetest_request() ERROR no PrivateKey for Id: " << *vit; - std::cerr << std::endl; - } - } - } - } - } - else - { - std::cerr << "p3IdService::cache_load_for_token() ERROR no data"; - std::cerr << std::endl; - - return false; - } - return true; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* - * We have three background tasks that use the ServiceString: PGPHash & Reputation & Recogn - * - * Only one task can be run at a time - otherwise potential overwrite issues. - * So this part coordinates that part of the code. - * - * We are going to have a "fetcher task", which gets all the UNPROCESSED / UPDATED GROUPS. - * and sets the CHECK_PGP, CHECK_RECOGN, etc... this will reduce the "Get All" calls. - * - */ - - -bool p3IdService::CacheArbitration(uint32_t mode) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if (!mBgSchedule_Active) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::CacheArbitration() Okay: mode " << mode; - std::cerr << std::endl; -#endif // DEBUG_IDS - - mBgSchedule_Active = true; - mBgSchedule_Mode = mode; - return true; - } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::CacheArbitration() Is busy in mode: " << mBgSchedule_Mode; - std::cerr << std::endl; -#endif // DEBUG_IDS - - return false; -} - -void p3IdService::CacheArbitrationDone(uint32_t mode) -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - if (mBgSchedule_Mode != mode) - { - /* issues */ - std::cerr << "p3IdService::CacheArbitrationDone() ERROR Wrong Current Mode"; - std::cerr << std::endl; - return; - } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::CacheArbitrationDone()"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - mBgSchedule_Active = false; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* Task to determine PGPHash matches - * - * Info to be stored in GroupServiceString + Cache. - * - * Actually - it must be a Signature here - otherwise, you could - * put in a hash from someone else! - * - * Don't think that we need to match very often - maybe once a day? - * Actually - we should scale the matching based on number of keys we have. - * - * imagine - 10^6 rsa keys + 10^3 gpg keys => 10^9 combinations. - * -- far too many to check all quickly. - * - * Need to grab and cache data we need... then check over slowly. - * - * maybe grab a list of all gpgids - that we know of: store id list. - * then big GroupRequest, and iterate through these. - **/ - -//const int SHA_DIGEST_LENGTH = 20; - -static void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, Sha1CheckSum &hash); - - -// Must Use meta. -RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup( - RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet ) -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - RsGxsIdGroupItem *item = dynamic_cast(grpItem); - if (!item) - { - std::cerr << "p3IdService::service_CreateGroup() ERROR invalid cast"; - std::cerr << std::endl; - return SERVICE_CREATE_FAIL; - } - - item->meta.mGroupId.clear(); - - /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ - // find private admin key - for( std::map::iterator mit = - keySet.private_keys.begin(); mit != keySet.private_keys.end(); ++mit ) - if(mit->second.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) - { - item->meta.mGroupId = RsGxsGroupId(mit->second.keyId); - break; - } - - if(item->meta.mGroupId.isNull()) - { - RsErr() << __PRETTY_FUNCTION__ << " missing admin key!" << std::endl; - return SERVICE_CREATE_FAIL; - } - mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ; - - /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ - - // SANITY CHECK. - // if (item->mMeta.mAuthorId != item->meta.mAuthorId) - // { - // std::cerr << "p3IdService::service_CreateGroup() AuthorId mismatch("; - // std::cerr << item->mMeta.mAuthorId; - // std::cerr << " vs "; - // std::cerr << item->meta.mAuthorId; - // std::cerr << std::endl; - // } - // - // if (item->group.mMeta.mGroupId != item->meta.mGroupId) - // { - // std::cerr << "p3IdService::service_CreateGroup() GroupId mismatch("; - // std::cerr << item->mMeta.mGroupId; - // std::cerr << " vs "; - // std::cerr << item->meta.mGroupId; - // std::cerr << std::endl; - // } - // - // - // if (item->group.mMeta.mGroupFlags != item->meta.mGroupFlags) - // { - // std::cerr << "p3IdService::service_CreateGroup() GroupFlags mismatch("; - // std::cerr << item->mMeta.mGroupFlags; - // std::cerr << " vs "; - // std::cerr << item->meta.mGroupFlags; - // std::cerr << std::endl; - // } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::service_CreateGroup() for : " << item->meta.mGroupId; - std::cerr << std::endl; - std::cerr << "p3IdService::service_CreateGroup() Alt GroupId : " << item->meta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_IDS - - ServiceCreate_Return createStatus; - - if (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) - { - /* create the hash */ - Sha1CheckSum hash; - - RsPgpFingerprint ownFinger; - RsPgpId ownId(mPgpUtils->getPGPOwnId()); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::service_CreateGroup() OwnPgpID: " << ownId.toStdString(); - std::cerr << std::endl; -#endif - -#ifdef GXSID_GEN_DUMMY_DATA - // if (item->group.mMeta.mAuthorId != "") - // { - // ownId = RsPgpId(item->group.mMeta.mAuthorId); - // } -#endif - - if(!mPgpUtils->getKeyFingerprint(ownId,ownFinger)) - { - RsErr() << __PRETTY_FUNCTION__ - << " failure retriving own PGP fingerprint" << std::endl; - return SERVICE_CREATE_FAIL; // abandon attempt! - } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::service_CreateGroup() OwnFingerprint: " << ownFinger.toStdString(); - std::cerr << std::endl; -#endif - - RsGxsId gxsId(item->meta.mGroupId.toStdString()); - calcPGPHash(gxsId, ownFinger, hash); - item->mPgpIdHash = hash; - -#ifdef DEBUG_IDS - - std::cerr << "p3IdService::service_CreateGroup() Calculated PgpIdHash : " << item->mPgpIdHash; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* do signature */ - - -#define MAX_SIGN_SIZE 2048 - uint8_t signarray[MAX_SIGN_SIZE]; - unsigned int sign_size = MAX_SIGN_SIZE; - memset(signarray,0,MAX_SIGN_SIZE) ; // just in case. - - int result = AuthGPG::getAuthGPG()->SignDataBin( - static_cast(hash.toByteArray()), - hash.SIZE_IN_BYTES, signarray, &sign_size, - __PRETTY_FUNCTION__ ) - ? - SELF_SIGNATURE_RESULT_SUCCESS : - SELF_SIGNATURE_RESULT_FAILED; - - switch(result) - { - case SELF_SIGNATURE_RESULT_PENDING: - createStatus = SERVICE_CREATE_FAIL_TRY_LATER; - Dbg1() << __PRETTY_FUNCTION__ << " signature still pending" - << std::endl; - break; - case SELF_SIGNATURE_RESULT_SUCCESS: - { - // Additional consistency checks. - if(sign_size == MAX_SIGN_SIZE) - { - RsErr() << __PRETTY_FUNCTION__ << "Inconsistent result. " - << "Signature uses full buffer. This is probably an " - << "error." << std::endl; - return SERVICE_CREATE_FAIL; - } - - /* push binary into string -> really bad! */ - item->mPgpIdSign = ""; - for(unsigned int i = 0; i < sign_size; i++) - item->mPgpIdSign += static_cast(signarray[i]); - - createStatus = SERVICE_CREATE_SUCCESS; - break; - } - case SELF_SIGNATURE_RESULT_FAILED: /* fall-through */ - default: - RsErr() << __PRETTY_FUNCTION__ << " signature failed with: " - << result << std::endl; - return SERVICE_CREATE_FAIL; - } - } - else createStatus = SERVICE_CREATE_SUCCESS; - - // Enforce no AuthorId. - item->meta.mAuthorId.clear() ; - //item->mMeta.mAuthorId.clear() ; - // copy meta data to be sure its all the same. - //item->group.mMeta = item->meta; - - // do it like p3gxscircles: save the new grp id - // this allows the user interface - // to see the grp id on the list of ownIds immediately after the group was created - { - RS_STACK_MUTEX(mIdMtx); - RsGxsId gxsId(item->meta.mGroupId); - if (std::find(mOwnIds.begin(), mOwnIds.end(), gxsId) == mOwnIds.end()) - { - mOwnIds.push_back(gxsId); - mKeysTS[gxsId].TS = time(nullptr); - } - } - -#ifdef DEBUG_IDS - Dbg2() << __PRETTY_FUNCTION__ << " returns: " << createStatus << std::endl; -#endif - return createStatus; -} - - -#define HASHPGP_PERIOD 180 - - -bool p3IdService::pgphash_start() -{ - if (!CacheArbitration(BG_PGPHASH)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_start() Other Events running... Rescheduling"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* reschedule in a bit */ - RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_RETRY_PERIOD); - return false; - } - - // SCHEDULE NEXT ONE. - RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH, PGPHASH_PERIOD); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_start() making request"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - // ACTUALLY only need summary - but have written code for data. - // Also need to use opts.groupFlags to filter stuff properly to REALID's only. - // TODO - - uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH); - - return true; -} - - -bool p3IdService::pgphash_handlerequest(uint32_t token) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_handlerequest(" << token << ")"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - // We need full data - for access to Hash & Signature. - // Perhaps we will change this to an initial pass through Meta, - // and use this to discard lots of things. - - // Even better - we can set flags in the Meta Data, (IdType), - // And use GXS to filter out all the AnonIds, and only have to process - // Proper Ids. - - // We Will do this later! - - std::list group_metas; - std::list groups_to_process; - bool ok = getGroupMeta(token, group_metas); - - if(ok) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_request() Have " << group_metas.size() << " Groups" << std::endl; -#endif // DEBUG_IDS - - for(auto vit = group_metas.begin(); vit != group_metas.end(); ++vit) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mGroupId << " "; -#endif // DEBUG_IDS - - /* Filter based on IdType */ - - if (!(vit->mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_request() discarding AnonID" << std::endl; -#endif // DEBUG_IDS - continue; - } - - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if(mGroupsToProcess.find(vit->mGroupId) != mGroupsToProcess.end()) - { -#ifdef DEBUG_IDS - std::cerr << " => already in checking list!" << std::endl; -#endif - continue; - } - } - - /* now we need to decode the Service String - see what is saved there */ - SSGxsIdGroup ssdata; - - if (ssdata.load(vit->mServiceString)) - { - if (ssdata.pgp.validatedSignature) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_request() discarding Already Known" << std::endl; -#endif // DEBUG_IDS - continue; - } - - /* Have a linear attempt policy - - * if zero checks - try now. - * if 1 check, at least a day. - * if 2 checks: 2days, etc. - */ - -#define SECS_PER_DAY (3600 * 24) - rstime_t age = time(NULL) - ssdata.pgp.lastCheckTs; - rstime_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY; - - if (wait_period > 30 * SECS_PER_DAY) - wait_period = 30 * SECS_PER_DAY; - -#ifdef DEBUG_IDS - std::cerr << "p3IdService: group " << *vit << " age=" << age << ", attempts=" << ssdata.pgp.checkAttempts << ", wait period = " << wait_period ; -#endif - - if (age < wait_period) - { -#ifdef DEBUG_IDS - std::cerr << " => discard." << std::endl; -#endif // DEBUG_IDS - continue; - } - - -#ifdef DEBUG_IDS - std::cerr << " => recheck!" << std::endl; -#endif - } - - /* if we get here -> then its to be processed */ - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - groups_to_process.push_back(vit->mGroupId); - } - } - else - { - std::cerr << "p3IdService::pgphash_request() getGroupData ERROR"; - std::cerr << std::endl; - } - - // If they are groups to process, load the data for these groups - - if(!groups_to_process.empty()) - { - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts,groups_to_process); - GxsTokenQueue::queueRequest(token, GXSIDREQ_LOAD_PGPIDDATA); - } - - return true; -} - -bool p3IdService::pgphash_load_group_data(uint32_t token) -{ - // Update PgpIdList -> if there are groups to process. - - getPgpIdList(); - std::vector groups; - - // Add the loaded groups into the list of groups to process - - getGroupData(token, groups); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - for(auto grp:groups) - { - mGroupsToProcess[grp.mMeta.mGroupId] = grp; -#ifdef DEBUG_IDS - std::cerr << "pgphash_load_group_data(): loaded group data for group " << grp.mMeta.mGroupId << ". mGroupsToProcess contains " << mGroupsToProcess.size() << " elements." << std::endl; -#endif - } - - return true; -} - -bool p3IdService::pgphash_process() -{ - /* each time this is called - process one Id from mGroupsToProcess */ - RsGxsIdGroup pg; - bool isDone = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mGroupsToProcess.empty()) - { - pg = mGroupsToProcess.begin()->second; - mGroupsToProcess.erase(mGroupsToProcess.begin()); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_IDS - } - else - isDone = true; - } - - if (isDone) - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_process() List Empty... Done"; - std::cerr << std::endl; -#endif // DEBUG_IDS - // FINISHED. - CacheArbitrationDone(BG_PGPHASH); - return true; - } - - - SSGxsIdGroup ssdata; - ssdata.load(pg.mMeta.mServiceString); // attempt load - okay if fails. - - RsPgpId pgpId; - bool error = false ; - - if (checkId(pg, pgpId,error)) - { - /* found a match - update everything */ - /* Consistency issues here - what if Reputation was recently updated? */ - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_process() CheckId Success for Group: " << pg.mMeta.mGroupId; - std::cerr << " PgpId: " << pgpId; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* update */ - ssdata.pgp.validatedSignature = true; - ssdata.pgp.pgpId = pgpId; - - } - else if(error) - { - std::cerr << "Identity has an invalid signature. It will be deleted." << std::endl; - - uint32_t token ; - deleteIdentity(token,pg) ; - } - else - { -#ifdef DEBUG_IDS - std::cerr << "p3IdService::pgphash_process() No Match for Group: " << pg.mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_IDS - - ssdata.pgp.lastCheckTs = time(NULL); - ssdata.pgp.checkAttempts++; - ssdata.pgp.pgpId = pgpId; // read from the signature, but not verified - } - - if(!error) - { - // update IdScore too. - ssdata.score.rep.updateIdScore(true, ssdata.pgp.validatedSignature); - ssdata.score.rep.update(); - - /* set new Group ServiceString */ - uint32_t dummyToken = 0; - std::string serviceString = ssdata.save(); - setGroupServiceString(dummyToken, pg.mMeta.mGroupId, serviceString); - - cache_update_if_cached(RsGxsId(pg.mMeta.mGroupId), serviceString); - } - return true; -} - -// This method allows to have a null issuer ID in the signature, in which case the signature is anonymous. -// The correct PGP key to check is looked for by bruteforcing -// -// grp.mPgpIdHash == SHA1( GroupId | PgpFingerPrint ) -// -// For now, this is probably never used because signed IDs use a clear signature. The advntage of hiding the -// ID has not been clearly demonstrated anyway, which allows to directly look for the ID in the list of -// known keys instead of computing tons of hashes. - -bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::checkId() Starting Match Check for RsGxsId: "; - std::cerr << grp.mMeta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_IDS - - error = false ; - - /* some sanity checking... make sure hash is the right size */ - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::checkId() PgpIdHash is: " << grp.mPgpIdHash; - std::cerr << std::endl; -#endif // DEBUG_IDS - - /* iterate through and check hash */ - Sha1CheckSum hash; - -#ifdef DEBUG_IDS - std::string esign ; - Radix64::encode((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),esign) ; - std::cerr << "Checking group signature " << esign << std::endl; -#endif - RsPgpId issuer_id ; - RsPgpFingerprint pgp_fingerprint; - pgpId.clear() ; - - if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id) && !issuer_id.isNull()) - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - pgpId = issuer_id ; - - auto mit = mPgpFingerprintMap.find(issuer_id); - - if(mit == mPgpFingerprintMap.end()) - { -#ifdef DEBUG_IDS - std::cerr << "Issuer Id: " << issuer_id << " is not known. Key will be marked as non verified." << std::endl; -#endif - error = false; - return false; - } - calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash); -#ifdef DEBUG_IDS - std::cerr << "Issuer from PGP signature: " << issuer_id << " is known. Computed corresponding hash: " << hash << std::endl; -#endif - if(grp.mPgpIdHash != hash) - { - std::cerr << "(EE) Unexpected situation: GxsId signature hash (" << hash << ") doesn't correspond to what's listed in the mPgpIdHash field (" << grp.mPgpIdHash << ")." << std::endl; - error = true; - return false; - } - pgp_fingerprint = mit->second; - } - else - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_IDS - std::cerr << "Bruteforcing PGP hash from GxsId mPgpHash: " << grp.mPgpIdHash << std::endl; -#endif - for(auto mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); ++mit) - { - calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash); - - std::cerr << " profile key " << mit->first << " (" << mit->second << ") : "; - - if (grp.mPgpIdHash == hash) - { -#ifdef DEBUG_IDS - std::cerr << "MATCH!" << std::endl; -#endif - pgpId = mit->first; - pgp_fingerprint = mit->second; - break; - } -#ifdef DEBUG_IDS - else - std::cerr << "fails" << std::endl; -#endif - } - } - - // Look for the PGP id given by the signature - -#ifdef DEBUG_IDS - std::cerr << "Now checking the signature: "; -#endif - - if (mPgpUtils->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, (unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(), pgp_fingerprint)) - { -#ifdef DEBUG_IDS - std::cerr << " Signature validates!" << std::endl; -#endif - error = false; - return true; - } - else - { -#ifdef DEBUG_IDS - std::cerr << " Signature fails!" << std::endl; -#endif - error = true; - return false; - } -} - -/* worker functions */ -void p3IdService::getPgpIdList() -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getPgpIdList() Starting...."; - std::cerr << std::endl; -#endif // DEBUG_IDS - - std::list list; - mPgpUtils->getGPGAllList(list); - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - mPgpFingerprintMap.clear(); - - std::list::iterator it; - for(it = list.begin(); it != list.end(); ++it) - { - RsPgpId pgpId(*it); - PGPFingerprintType fp; - mPgpUtils->getKeyFingerprint(pgpId, fp); - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getPgpIdList() Id: " << pgpId.toStdString() << " => " << fp.toStdString(); - std::cerr << std::endl; -#endif // DEBUG_IDS - - mPgpFingerprintMap[pgpId] = fp; - } - -#ifdef DEBUG_IDS - std::cerr << "p3IdService::getPgpIdList() Items: " << mPgpFingerprintMap.size(); - std::cerr << std::endl; -#endif // DEBUG_IDS -} - - -void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, Sha1CheckSum &hash) -{ - unsigned char signature[SHA_DIGEST_LENGTH]; - /* hash id + pubkey => pgphash */ - SHA_CTX *sha_ctx = new SHA_CTX; - SHA1_Init(sha_ctx); - - SHA1_Update(sha_ctx, id.toStdString().c_str(), id.toStdString().length()); // TO FIX ONE DAY. - SHA1_Update(sha_ctx, pgp.toByteArray(), pgp.SIZE_IN_BYTES); - SHA1_Final(signature, sha_ctx); - hash = Sha1CheckSum(signature); - -#ifdef DEBUG_IDS - std::cerr << "calcPGPHash():"; - std::cerr << std::endl; - std::cerr << "\tRsGxsId: " << id; - std::cerr << std::endl; - std::cerr << "\tFingerprint: " << pgp.toStdString(); - std::cerr << std::endl; - std::cerr << "\tFinal Hash: " << hash.toStdString(); - std::cerr << std::endl; -#endif // DEBUG_IDS - - delete sha_ctx; -} - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* Task to validate Recogn Tags. - * - * Info to be stored in GroupServiceString + Cache. - **/ - -bool p3IdService::recogn_schedule() -{ -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_schedule()"; - std::cerr << std::endl; -#endif - - int32_t age = 0; - int32_t next_event = 0; - - if (RsTickEvent::event_count(GXSID_EVENT_RECOGN) > 0) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_schedule() Skipping GXSIS_EVENT_RECOGN already scheduled"; - std::cerr << std::endl; -#endif - return false; - } - - if (RsTickEvent::prev_event_ago(GXSID_EVENT_RECOGN, age)) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_schedule() previous event " << age << " secs ago"; - std::cerr << std::endl; -#endif - - next_event = RECOGN_PERIOD - age; - if (next_event < 0) - { - next_event = 0; - } - } - - RsTickEvent::schedule_in(GXSID_EVENT_RECOGN, next_event); - return true; -} - - -bool p3IdService::recogn_start() -{ - if (!CacheArbitration(BG_RECOGN)) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_start() Other Events running... Rescheduling"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - /* reschedule in a bit */ - RsTickEvent::schedule_in(GXSID_EVENT_RECOGN, RECOGN_RETRY_PERIOD); - return false; - } - - // NEXT EVENT is scheduled via recogn_schedule. - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_start() making request"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - std::list recognList; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - recognList = mRecognGroupIds; - mRecognGroupIds.clear(); - } - - if (recognList.empty()) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_start() List is Empty, cancelling"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - // FINISHED. - CacheArbitrationDone(BG_RECOGN); - return false; - } - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts, recognList); - GxsTokenQueue::queueRequest(token, GXSIDREQ_RECOGN); - return true; - -} - - -bool p3IdService::recogn_handlerequest(uint32_t token) -{ -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_handlerequest(" << token << ")"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_request() Have " << grpData.size() << " Groups"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsIdGroupItem* item = dynamic_cast(*vit); - if (item) - { - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_request() Group Id: " << item->meta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - mRecognGroupsToProcess.push_back(item); - } - else - { - delete (*vit); - } - } - } - else - { - std::cerr << "p3IdService::recogn_request() getGroupData ERROR"; - std::cerr << std::endl; - } - - // Schedule Processing. - RsTickEvent::schedule_in(GXSID_EVENT_RECOGN_PROC, RECOGN_PROC_PERIOD); - return true; -} - - -bool p3IdService::recogn_process() -{ - /* each time this is called - process one Id from mGroupsToProcess */ - RsGxsIdGroupItem *item; - bool isDone = false; - { - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - if (!mRecognGroupsToProcess.empty()) - { - item = mRecognGroupsToProcess.front(); - mRecognGroupsToProcess.pop_front(); - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_process() Popped Group: " << item->meta.mGroupId; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - } - else - { - isDone = true; - } - } - - if (isDone) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_process() List Empty... Done"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - // FINISHED. - CacheArbitrationDone(BG_RECOGN); - return true; - } - - - - std::list tagItems; - std::list::iterator it; - - recogn_extract_taginfo(item, tagItems); - - bool isPending = false; - int i = 1; - uint32_t tagValidFlags = 0; - for(it = tagItems.begin(); it != tagItems.end(); ++it) - { - bool isTagPending = false; - bool isTagOk = recogn_checktag(RsGxsId(item->meta.mGroupId.toStdString()), item->meta.mGroupName, *it, true, isPending); - if (isTagOk) - { - tagValidFlags |= i; - } - else - { - isPending |= isTagPending; - } - - delete *it; - i *= 2; - } - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_process() Tags Checked, saving"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - SSGxsIdGroup ssdata; - ssdata.load(item->meta.mServiceString); // attempt load - okay if fails. - - ssdata.recogntags.setTags(true, isPending, tagValidFlags); - ssdata.recogntags.lastCheckTs = time(NULL); - ssdata.recogntags.publishTs = item->meta.mPublishTs; - - // update IdScore too. - bool pgpId = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility); - ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature); - ssdata.score.rep.update(); - - /* set new Group ServiceString */ - uint32_t dummyToken = 0; - std::string serviceString = ssdata.save(); - setGroupServiceString(dummyToken, item->meta.mGroupId, serviceString); - - cache_update_if_cached(RsGxsId(item->meta.mGroupId.toStdString()), serviceString); - - delete item; - - // Schedule Next Processing. - RsTickEvent::schedule_in(GXSID_EVENT_RECOGN_PROC, RECOGN_PROC_PERIOD); - return false; // as there are more items on the queue to process. -} - - -bool p3IdService::recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending) -{ - -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() groupId: " << id; - std::cerr << std::endl; - std::cerr << "p3IdService::recogn_checktag() nickname: " << nickname; - std::cerr << std::endl; - std::cerr << "p3IdService::recogn_checktag() item: "; - std::cerr << std::endl; - ((RsGxsRecognTagItem *) item)->print(std::cerr); -#endif // DEBUG_RECOGN - - // To check: - // ------------------- - // date range. - // id matches. - // nickname matches. - // signer is valid. - // ------ - // signature is valid. (only if doSignCheck == true) - - rstime_t now = time(NULL); - isPending = false; - - // check date range. - if ((item->valid_from > now) || (item->valid_to < now)) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() failed timestamp"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - return false; - } - - // id match. - if (id != item->identity) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() failed identity"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - // nickname match. - if (nickname != item->nickname) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() failed nickname"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - - - { - /* check they validity of the Tag */ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - - std::map::iterator it; - it = mRecognSignKeys.find(item->sign.keyId); - if (it == mRecognSignKeys.end()) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() failed to find signkey"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - - // If OldKey, then we don't want to reprocess. - if (mRecognOldSignKeys.end() != - mRecognOldSignKeys.find(item->sign.keyId)) - { - isPending = true; // need to reprocess later with new key - } - return false; - } - - // Check tag_class is okay for signer. - if (it->second->signing_classes.ids.end() == - std::find(it->second->signing_classes.ids.begin(), it->second->signing_classes.ids.end(), item->tag_class)) - { -#ifdef DEBUG_RECOGN - std::cerr << "p3IdService::recogn_checktag() failed signing_class check"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - // ALL Okay, just signature to check. - if (!doSignCheck) - { - return true; - } - - return RsRecogn::validateTagSignature(it->second, item); - } -} - - -void p3IdService::loadRecognKeys() -{ - RsStackMutex stack(mIdMtx); /**** LOCKED MUTEX ****/ - - RsRecogn::loadSigningKeys(mRecognSignKeys); -} - - - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -#define MAX_KNOWN_PGPIDS 20 -#define MAX_UNKNOWN_PGPIDS 20 -#define MAX_PSEUDOIDS 20 - -#define DUMMY_GXSID_DELAY 5 - -void p3IdService::generateDummyData() -{ - - generateDummy_OwnIds(); - - rstime_t age = 0; - for(int i = 0; i < MAX_KNOWN_PGPIDS; i++) - { - age += DUMMY_GXSID_DELAY; - RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_PGPID, age); - } - - for(int i = 0; i < MAX_PSEUDOIDS; i++) - { - age += DUMMY_GXSID_DELAY; - RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_PSEUDOID, age); - } - - for(int i = 0; i < MAX_UNKNOWN_PGPIDS; i++) - { - age += DUMMY_GXSID_DELAY; - RsTickEvent::schedule_in(GXSID_EVENT_DUMMY_UNKNOWN_PGPID, age); - } -} - - - - - -void p3IdService::generateDummy_OwnIds() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - /* grab all the gpg ids... and make some ids */ - - /*RsPgpId ownId = */mPgpUtils->getPGPOwnId(); - -#if 0 - // generate some ownIds. - //int genCount = 0; - int i; - - int nIds = 2 + (RSRandom::random_u32() % 2); - for(i = 0; i < nIds; i++) - { - RsGxsIdGroup id; - RsPeerDetails details; - - id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID; - -// // HACK FOR DUMMY GENERATION. -// id.mMeta.mAuthorId = ownId.toStdString(); -// if (rsPeers->getPeerDetails(ownId, details)) -// { -// std::ostringstream out; -// out << details.name << "_" << i + 1; -// -// id.mMeta.mGroupName = out.str(); -// } - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); - } -#endif -} - - -void p3IdService::generateDummy_FriendPGP() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - // Now Generate for friends. - std::list gpgids; - std::list::const_iterator it; - mPgpUtils->getGPGAllList(gpgids); - - RsGxsIdGroup id; - - id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility; - - int idx = RSRandom::random_f32() * (gpgids.size() - 1); - it = gpgids.begin(); - for(int j = 0; j < idx; j++, ++it) ; - -#if 0 - // HACK FOR DUMMY GENERATION. - id.mMeta.mAuthorId = RsGxsId::random() ; - - RsPeerDetails details; - if (/*rsPeers->getPeerDetails(*it, details)*/false) - { - std::ostringstream out; - out << details.name << "_" << RSRandom::random_u32() % 1000; - id.mMeta.mGroupName = out.str(); - } - else - { - std::cerr << "p3IdService::generateDummy_FriendPGP() missing" << std::endl; - std::cerr << std::endl; - id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ; - } - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); -#endif -} - - -void p3IdService::generateDummy_UnknownPGP() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - RsGxsIdGroup id; - - // FAKE DATA. - id.mMeta.mGroupFlags = RSGXSID_GROUPFLAG_REALID_kept_for_compatibility; - id.mPgpIdHash = Sha1CheckSum::random() ; - id.mPgpIdSign = RSRandom::random_alphaNumericString(20) ; - id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ; - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); -} - - -void p3IdService::generateDummy_UnknownPseudo() -{ - RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/ - - RsGxsIdGroup id; - - // FAKE DATA. - id.mMeta.mGroupFlags = 0; - id.mMeta.mGroupName = RSRandom::random_alphaNumericString(10) ; - - uint32_t dummyToken = 0; - createGroup(dummyToken, id); -} - - -std::string rsIdTypeToString(uint32_t idtype) -{ - std::string str; - if (idtype & RSID_TYPE_REALID) - { - str += "GPGID "; - } - if (idtype & RSID_TYPE_PSEUDONYM) - { - str += "PSEUDO "; - } - if (idtype & RSID_RELATION_YOURSELF) - { - str += "YOURSELF "; - } - if (idtype & RSID_RELATION_FRIEND) - { - str += "FRIEND "; - } - if (idtype & RSID_RELATION_FOF) - { - str += "FOF "; - } - if (idtype & RSID_RELATION_OTHER) - { - str += "OTHER "; - } - if (idtype & RSID_RELATION_UNKNOWN) - { - str += "UNKNOWN "; - } - return str; -} - - - - - - - - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - - -/* here we are running a background process that calculates the reputation scores - * for each of the IDs.... - * - * As this class will be extensively used by many other threads... it is best - * that we don't block at all. This should be in a background thread. - * Perhaps a generic method to handle this will be advisable.... but we do that later. - * - * - * So Reputation.... - * 4 components: - * 1) Your Opinion: Should override everything else. - * 2) Implicit Factors: Know the associated GPG Key. - * 3) Your Friends Opinions: - * 4) Your Friends Calculated Reputation Scores. - * - * Must make sure that there is no Feedback loop in the Reputation calculation. - * - * So: Our Score + Friends Scores => Local Reputation. - * Local Reputation + Friends Reputations => Final Reputation? - * - * Do we need to 'ignore' Non-scores? - * ---> This becomes like the "Best Comment" algorithm from Reddit... - * Use a statistical mechanism to work out a lower bound on Reputation. - * - * But what if your opinion is wrong?.... well likely your friends will - * get their messages and reply... you'll see the missing message - request it - check reputation etc. - * - * So we are going to have three different scores (Own, Peers, (the neighbour) Hood)... - * - * So next question, when do we need to incrementally calculate the score? - * .... how often do we need to recalculate everything -> this could lead to a flux of messages. - * - * - * - * MORE NOTES: - * - * The Opinion Messages will have to be signed by PGP or SSL Keys, to guarantee that we don't - * multiple votes per person... As the message system doesn't handle uniqueness in this respect, - * we might have to do FULL_CALC for everything - This bit TODO. - * - * This will make IdService quite different to the other GXS services. - */ - -/************************************************************************************/ -/* - * Processing Algorithm: - * - Grab all Groups which have received messages. - * (opt 1)-> grab latest msgs for each of these and process => score. - * (opt 2)-> try incremental system (people probably won't change opinions often -> just set them once) - * --> if not possible, fallback to full calculation. - * - * - */ - -void p3IdService::checkPeerForIdentities() -{ - RsStackMutex stack(mIdMtx); - - // crud, i needed peers instead! - mGroupNotPresent.clear(); -} - - -// Overloaded from GxsTokenQueue for Request callbacks. -void p3IdService::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl; -#endif // DEBUG_IDS - - // stuff. - switch(req_type) - { - case GXSIDREQ_CACHEOWNIDS: - if (status == RsTokenService::COMPLETE) cache_load_ownids(token); - if (status == RsTokenService::CANCELLED) RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//Cancelled by time-out so ask a new time - break; - case GXSIDREQ_CACHELOAD: - if (status == RsTokenService::COMPLETE) cache_load_for_token(token); - break; - case GXSIDREQ_PGPHASH: - if (status == RsTokenService::COMPLETE) pgphash_handlerequest(token); - break; - case GXSIDREQ_RECOGN: - if (status == RsTokenService::COMPLETE) recogn_handlerequest(token); - break; - case GXSIDREQ_CACHETEST: - if (status == RsTokenService::COMPLETE) cachetest_handlerequest(token); - break; - case GXSIDREQ_OPINION: - if (status == RsTokenService::COMPLETE) opinion_handlerequest(token); - break; - case GXSIDREQ_LOAD_PGPIDDATA: - if (status == RsTokenService::COMPLETE) pgphash_load_group_data(token); - break; - case GXSIDREQ_SERIALIZE_TO_MEMORY: - if (status == RsTokenService::COMPLETE) handle_get_serialized_grp(token); - break; - default: - std::cerr << "p3IdService::handleResponse() Unknown Request Type: " - << req_type << std::endl; - break; - } -} - - - // Overloaded from RsTickEvent for Event callbacks. -void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*/) -{ -#ifdef DEBUG_IDS - std::cerr << "p3IdService::handle_event(" << event_type << ")"; - std::cerr << std::endl; -#endif // DEBUG_IDS - - // stuff. - switch(event_type) - { - case GXSID_EVENT_CACHEOWNIDS: - cache_request_ownids(); - break; - - case GXSID_EVENT_CACHELOAD: - cache_start_load(); - break; - - case GXSID_EVENT_CACHETEST: - cachetest_getlist(); - break; - - case GXSID_EVENT_PGPHASH: - pgphash_start(); - break; - - case GXSID_EVENT_RECOGN: - recogn_start(); - break; - - case GXSID_EVENT_RECOGN_PROC: - recogn_process(); - break; - - case GXSID_EVENT_DUMMYDATA: - generateDummyData(); - break; - - case GXSID_EVENT_DUMMY_OWNIDS: - generateDummy_OwnIds(); - break; - - case GXSID_EVENT_DUMMY_PGPID: - generateDummy_FriendPGP(); - break; - - case GXSID_EVENT_DUMMY_UNKNOWN_PGPID: - generateDummy_UnknownPGP(); - break; - - case GXSID_EVENT_DUMMY_PSEUDOID: - generateDummy_UnknownPseudo(); - break; - case GXSID_EVENT_REQUEST_IDS: - requestIdsFromNet(); - break; - case GXSID_EVENT_REPUTATION: - break; - default: - RsErr() << __PRETTY_FUNCTION__ << " Unknown Event Type: " - << event_type << std::endl; - print_stacktrace(); - break; - } -} - -/*static*/ const std::string RsIdentity::DEFAULT_IDENTITY_BASE_URL = - "retroshare:///identities"; -/*static*/ const std::string RsIdentity::IDENTITY_URL_NAME_FIELD = "identityName"; -/*static*/ const std::string RsIdentity::IDENTITY_URL_ID_FIELD = "identityId"; -/*static*/ const std::string RsIdentity::IDENTITY_URL_DATA_FIELD = "identityData"; - -bool p3IdService::exportIdentityLink( - std::string& link, const RsGxsId& id, bool includeGxsData, - const std::string& baseUrl, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(id.isNull()) return failure("id cannot be null"); - - const bool outputRadix = baseUrl.empty(); - if(outputRadix && !includeGxsData) return - failure("includeGxsData must be true if format requested is base64"); - - if( includeGxsData && - !RsGenExchange::exportGroupBase64( - link, reinterpret_cast(id), errMsg ) ) - return failure(errMsg); - - if(outputRadix) return true; - - std::vector idsInfo; - if( !getIdentitiesInfo(std::set({id}), idsInfo ) - || idsInfo.empty() ) - return failure("failure retrieving identity information"); - - RsUrl inviteUrl(baseUrl); - inviteUrl.setQueryKV(IDENTITY_URL_ID_FIELD, id.toStdString()); - inviteUrl.setQueryKV(IDENTITY_URL_NAME_FIELD, idsInfo[0].mMeta.mGroupName); - if(includeGxsData) inviteUrl.setQueryKV(IDENTITY_URL_DATA_FIELD, link); - - link = inviteUrl.toString(); - return true; -} - -bool p3IdService::importIdentityLink( - const std::string& link, RsGxsId& id, std::string& errMsg ) -{ - constexpr auto fname = __PRETTY_FUNCTION__; - const auto failure = [&](const std::string& err) - { - errMsg = err; - RsErr() << fname << " " << err << std::endl; - return false; - }; - - if(link.empty()) return failure("link is empty"); - - const std::string* radixPtr(&link); - - RsUrl url(link); - const auto& query = url.query(); - const auto qIt = query.find(IDENTITY_URL_DATA_FIELD); - if(qIt != query.end()) radixPtr = &qIt->second; - - if(radixPtr->empty()) return failure(IDENTITY_URL_DATA_FIELD + " is empty"); - - if(!RsGenExchange::importGroupBase64( - *radixPtr, reinterpret_cast(id), errMsg )) - return failure(errMsg); - - return true; -} - - -void RsGxsIdGroup::serial_process( - RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - RS_SERIAL_PROCESS(mMeta); - RS_SERIAL_PROCESS(mPgpIdHash); - RS_SERIAL_PROCESS(mPgpIdSign); - RS_SERIAL_PROCESS(mImage); - RS_SERIAL_PROCESS(mLastUsageTS); - RS_SERIAL_PROCESS(mPgpKnown); - RS_SERIAL_PROCESS(mIsAContact); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mReputation); -} - -RsIdentityUsage::RsIdentityUsage(RsServiceType service, RsIdentityUsage::UsageCode code, - const RsGxsGroupId& gid, const RsGxsMessageId& mid, const RsGxsMessageId &pid, const RsGxsMessageId &tid, - uint64_t additional_id, const std::string& comment ) : - mServiceId(service), mUsageCode(code), mGrpId(gid), mMsgId(mid),mParentId(pid),mThreadId(tid), - mAdditionalId(additional_id), mComment(comment) -{ - /* This is a hack, since it will hash also mHash, but because it is - * initialized to 0, and only computed in the constructor here, it should - * be ok. */ - librs::crypto::HashStream hs(librs::crypto::HashStream::SHA1); - - hs << static_cast(service); // G10h4ck: Why uint32 if it's 16 bits? - hs << static_cast(code); - hs << gid; - hs << mid; - hs << static_cast(additional_id); - hs << comment; - - mHash = hs.hash(); -} - -RsIdentityUsage::RsIdentityUsage() : - mServiceId(RsServiceType::NONE), mUsageCode(UNKNOWN_USAGE), mAdditionalId(0) -{} - -RsIdentity::~RsIdentity() = default; -RsReputationInfo::~RsReputationInfo() = default; -RsGixs::~RsGixs() = default; -RsIdentityDetails::~RsIdentityDetails() = default; -GxsReputation::~GxsReputation() = default; -RsGxsIdGroup::~RsGxsIdGroup() = default; diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h deleted file mode 100644 index 370c7a35a..000000000 --- a/libretroshare/src/services/p3idservice.h +++ /dev/null @@ -1,640 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3idservice.h * - * * - * Copyright (C) 2012-2014 Robert Fernie * - * Copyright (C) 2017-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/// RetroShare GXS identities service - - -#include -#include - -#include "retroshare/rsidentity.h" // External Interfaces. -#include "gxs/rsgenexchange.h" // GXS service. -#include "gxs/rsgixs.h" // Internal Interfaces. -#include "util/rsdebug.h" -#include "gxs/gxstokenqueue.h" -#include "rsitems/rsgxsiditems.h" -#include "util/rsmemcache.h" -#include "util/rstickevent.h" -#include "util/rsrecogn.h" -#include "pqi/authgpg.h" -#include "rsitems/rsgxsrecognitems.h" - -class PgpAuxUtils; - -class OpinionRequest -{ - public: - OpinionRequest(uint32_t token, RsGxsId id, bool absOpinion, int32_t score) - :mToken(token), mId(id), mAbsOpinion(absOpinion), mScore(score) - { return; } - OpinionRequest() - :mToken(0), mId(), mAbsOpinion(false), mScore(0) - { return; } - - uint32_t mToken; - RsGxsId mId; - bool mAbsOpinion; - int32_t mScore; -}; - - -// INTERNAL DATA TYPES. -// Describes data stored in GroupServiceString. - -class SSBit -{ - public: -virtual bool load(const std::string &input) = 0; -virtual std::string save() const = 0; -}; - - - -class SSGxsIdPgp: public SSBit -{ - public: - SSGxsIdPgp() - :validatedSignature(false), lastCheckTs(0), checkAttempts(0) { return; } - -virtual bool load(const std::string &input); -virtual std::string save() const; - - bool validatedSignature; - rstime_t lastCheckTs; - uint32_t checkAttempts; - RsPgpId pgpId; -}; - -class SSGxsIdRecognTags: public SSBit -{ - public: - SSGxsIdRecognTags() - :tagFlags(0), publishTs(0), lastCheckTs(0) { return; } - -virtual bool load(const std::string &input); -virtual std::string save() const; - - void setTags(bool processed, bool pending, uint32_t flags); - - bool tagsProcessed() const; // have we processed? - bool tagsPending() const; // should we reprocess? - bool tagValid(int i) const; - - uint32_t tagFlags; - rstime_t publishTs; - rstime_t lastCheckTs; -}; - - -class SSGxsIdReputation: public SSBit -{ - public: - SSGxsIdReputation() - :rep() { return; } - -virtual bool load(const std::string &input); -virtual std::string save() const; - - GxsReputation rep; -}; - -class SSGxsIdCumulator: public SSBit -{ -public: - SSGxsIdCumulator() - :count(0), nullcount(0), sum(0), sumsq(0) { return; } - -virtual bool load(const std::string &input); -virtual std::string save() const; - - uint32_t count; - uint32_t nullcount; - double sum; - double sumsq; - - // derived parameters: -}; - -class SSGxsIdGroup: public SSBit -{ -public: - SSGxsIdGroup() { return; } - -virtual bool load(const std::string &input); -virtual std::string save() const; - - // pgphash status - SSGxsIdPgp pgp; - - // recogTags. - SSGxsIdRecognTags recogntags; - - // reputation score. - SSGxsIdReputation score; - - // These are depreciated (will load, but not save) - SSGxsIdCumulator opinion; - SSGxsIdCumulator reputation; - -}; - -#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000 -#define ID_LOCAL_STATUS_INC_CALC_FLAG 0x00020000 - -class RsGxsIdGroupItem; - -class RsGxsIdCache -{ -public: - RsGxsIdCache(); - - RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pkey, const RsTlvPrivateRSAKey& privkey, const std::list &tagList); - RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pkey, const std::list &tagList); - - void updateServiceString(std::string serviceString); - - rstime_t mPublishTs; - std::list mRecognTags; // Only partially validated. - - RsIdentityDetails details; - - RsTlvPublicRSAKey pub_key; - RsTlvPrivateRSAKey priv_key; - -private: - void init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list &tagList); -}; - -struct SerialisedIdentityStruct -{ - unsigned char *mMem ; - uint32_t mSize ; - rstime_t mLastUsageTS; -}; - -// We cache all identities, and provide alternative (instantaneous) -// functions to extract info, rather than the horrible Token system. -class p3IdService: public RsGxsIdExchange, public RsIdentity, public GxsTokenQueue, public RsTickEvent, public p3Config -{ -public: - p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, PgpAuxUtils *pgpUtils); - - virtual RsServiceInfo getServiceInfo()override; - static uint32_t idAuthenPolicy(); - - virtual void service_tick()override; // needed for background processing. - - - /*! - * Design hack, id service must be constructed first as it - * is need for construction of subsequent net services - */ - void setNes(RsNetworkExchangeService* nes); - - /* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */ - - /* Data Specific Interface */ - - /// @see RsIdentity - bool getIdentitiesInfo(const std::set& ids, - std::vector& idsInfo ) override; - - /// @see RsIdentity - bool getIdentitiesSummaries(std::list& ids) override; - - // These are exposed via RsIdentity. - virtual bool getGroupData(const uint32_t &token, std::vector &groups) override; - virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups) override; - - //virtual bool getMsgData(const uint32_t &token, std::vector &opinions); - - // These are local - and not exposed via RsIdentity. - virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group); - virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group); - virtual bool deleteGroup(uint32_t& token, RsGxsGroupId& group); - //virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); - - virtual bool receiveNewIdentity(RsNxsGrp *identity_grp) override; - virtual bool retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp)override; - - /**************** RsIdentity External Interface. - * Notes: - * - * All the data is cached together for the moment - We should probably - * seperate and sort this out. - * - * Also need to handle Cache updates / invalidation from internal changes. - * - */ - //virtual bool getNickname(const RsGxsId &id, std::string &nickname); - virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) override; - - RS_DEPRECATED_FOR(RsReputations) - virtual bool submitOpinion(uint32_t& token, const RsGxsId &id, - bool absOpinion, int score) override; - - /// @see RsIdentity - virtual bool createIdentity( - RsGxsId& id, - const std::string& name, const RsGxsImage& avatar = RsGxsImage(), - bool pseudonimous = true, const std::string& pgpPassword = "" ) override; - - virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) override; - - /// @see RsIdentity - bool updateIdentity( const RsGxsId& id, const std::string& name, const RsGxsImage& avatar, bool pseudonimous, const std::string& pgpPassword) override; - - /// @see RsIdentity - bool deleteIdentity(RsGxsId& id) override; - - RS_DEPRECATED - virtual bool deleteIdentity(uint32_t& token, RsGxsIdGroup &group) override; - - virtual void setDeleteBannedNodesThreshold(uint32_t days) override; - virtual uint32_t deleteBannedNodesThreshold() override; - - virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname, - const std::string &tag, RsRecognTagDetails &details) override; - virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment, - uint16_t tag_class, uint16_t tag_type, std::string &tag) override; - - virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) override; - virtual bool isARegularContact(const RsGxsId& id) override; - virtual void setAutoAddFriendIdsAsContact(bool b) override; - virtual bool autoAddFriendIdsAsContact() override; - - virtual uint32_t nbRegularContacts() override; - virtual rstime_t getLastUsageTS(const RsGxsId &id) override ; - - /**************** RsGixs Implementation ***************/ - - /// @see RsIdentity - bool getOwnSignedIds(std::vector& ids) override; - - /// @see RsIdentity - bool getOwnPseudonimousIds(std::vector& ids) override; - - /// @see RsIdentity - bool getOwnIds( - std::list &ownIds, bool signed_only = false ) override; - - /// @see RsIdentity - bool isKnownId(const RsGxsId& id) override; - - /// @see RsIdentity - bool isOwnId(const RsGxsId& key_id) override; - - /// @see RsIdentity - bool exportIdentityLink( - std::string& link, const RsGxsId& id, - bool includeGxsData = true, - const std::string& baseUrl = DEFAULT_IDENTITY_BASE_URL, - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - /// @see RsIdentity - bool importIdentityLink( - const std::string& link, - RsGxsId& id = RS_DEFAULT_STORAGE_PARAM(RsGxsId), - std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) - ) override; - - - virtual bool signData( const uint8_t* data, - uint32_t data_size, - const RsGxsId& signer_id, - RsTlvKeySignature& signature, - uint32_t& signing_error)override; - - virtual bool validateData( const uint8_t *data, uint32_t data_size, - const RsTlvKeySignature& signature, - bool force_load, const RsIdentityUsage &info, - uint32_t& signing_error )override; - - virtual bool encryptData( const uint8_t* decrypted_data, - uint32_t decrypted_data_size, - uint8_t*& encrypted_data, - uint32_t& encrypted_data_size, - const RsGxsId& encryption_key_id, - uint32_t& error_status, - bool force_load = true )override; - - bool encryptData( const uint8_t* decrypted_data, - uint32_t decrypted_data_size, - uint8_t*& encrypted_data, - uint32_t& encrypted_data_size, - const std::set& encrypt_ids, - uint32_t& error_status, bool force_loa = true ); - - virtual bool decryptData( const uint8_t* encrypted_data, - uint32_t encrypted_data_size, - uint8_t*& decrypted_data, - uint32_t& decrypted_data_size, - const RsGxsId& decryption_key_id, - uint32_t& error_status, - bool force_load = true )override; - - virtual bool decryptData(const uint8_t* encrypted_data, - uint32_t encrypted_data_size, - uint8_t*& decrypted_data, - uint32_t& decrypted_data_size, - const std::set& decrypt_ids, - uint32_t& error_status, - bool force_load = true ); - - - virtual bool haveKey(const RsGxsId &id)override; - virtual bool havePrivateKey(const RsGxsId &id)override; - - virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key)override; - virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key)override; - - virtual bool requestKey( const RsGxsId &id, - const std::list &peers, - const RsIdentityUsage &use_info )override; - virtual bool requestPrivateKey(const RsGxsId &id)override; - - RS_DEPRECATED_FOR(exportIdentityLink) - virtual bool serialiseIdentityToMemory(const RsGxsId& id, std::string& radix_string) override; - RS_DEPRECATED_FOR(importIdentityLink) - virtual bool deserialiseIdentityFromMemory(const std::string& radix_string, RsGxsId* id = nullptr) override; - - /// @see RsIdentity - bool requestIdentity( - const RsGxsId& id, - const std::vector& peers = std::vector() - ) override; - - /**************** RsGixsReputation Implementation ****************/ - - // get Reputation. -#ifdef TO_BE_REMOVED - virtual bool haveReputation(const RsGxsId &id); - virtual bool loadReputation(const RsGxsId &id, const std::list& peers); - virtual bool getReputation(const RsGxsId &id, GixsReputation &rep); -#endif - - -protected: - /** Notifications **/ - virtual void notifyChanges(std::vector& changes) override; - - /** Overloaded to add PgpIdHash to Group Definition **/ - virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override; - - // Overloads RsGxsGenExchange - virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) override ; - - // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - // Overloaded from RsTickEvent. - virtual void handle_event(uint32_t event_type, const std::string &elabel) override; - - //===================================================// - // p3Config methods // - //===================================================// - - // Load/save the routing info, the pending items in transit, and the config variables. - // - virtual bool loadList(std::list& items) override ; - virtual bool saveList(bool& cleanup,std::list& items) override ; - - virtual RsSerialiser *setupSerialiser() override ; - - -private: - - /************************************************************************ - * This is the Cache for minimising calls to the DataStore. - * - */ - int cache_tick(); - - bool cache_request_load(const RsGxsId &id, const std::list& peers = std::list()); - bool cache_start_load(); - bool cache_load_for_token(uint32_t token); - - bool cache_store(const RsGxsIdGroupItem *item); - bool cache_update_if_cached(const RsGxsId &id, std::string serviceString); - - bool isPendingNetworkRequest(const RsGxsId& gxsId); - void requestIdsFromNet(); - - // Mutex protected. - - //std::list mCacheLoad_ToCache; - std::map > mCacheLoad_ToCache, mPendingCache; - - // Switching to RsMemCache for Key Caching. - RsMemCache mKeyCache; - - /************************************************************************ - * Refreshing own Ids. - * - */ - bool cache_request_ownids(); - bool cache_load_ownids(uint32_t token); - - std::list mOwnIds; - std::list mOwnSignedIds; - - /************************************************************************ - * Test fns for Caching. - * - */ - bool cachetest_tick(); - bool cachetest_getlist(); - bool cachetest_handlerequest(uint32_t token); - - /************************************************************************ - * for processing background tasks that use the serviceString. - * - must be mutually exclusive to avoid clashes. - */ - bool CacheArbitration(uint32_t mode); - void CacheArbitrationDone(uint32_t mode); - - bool mBgSchedule_Active; - uint32_t mBgSchedule_Mode; - - /***********************************8 - * Fonction to receive and handle group serialisation to memory - */ - - virtual void handle_get_serialized_grp(uint32_t token); - - /************************************************************************ - * pgphash processing. - * - */ - bool pgphash_start(); - bool pgphash_load_group_data(uint32_t token); - bool pgphash_handlerequest(uint32_t token); - bool pgphash_process(); - - bool checkId(const RsGxsIdGroup &grp, RsPgpId &pgp_id, bool &error); - void getPgpIdList(); - - /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - - std::map mPgpFingerprintMap; - std::map mGroupsToProcess; - - /************************************************************************ - * recogn processing. - * - */ - bool recogn_schedule(); - bool recogn_start(); - bool recogn_handlerequest(uint32_t token); - bool recogn_process(); - - // helper functions. - bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list &tagItems); - bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list &tagList); - - bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending); - - void loadRecognKeys(); - - - /************************************************************************ - * opinion processing. - * - */ - - bool opinion_handlerequest(uint32_t token); - - /* MUTEX PROTECTED DATA */ - std::map mPendingOpinion; - - - /************************************************************************ - * for getting identities that are not present - * - */ - void checkPeerForIdentities(); - - - /* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */ - - bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature); - bool getRecognKey_locked(std::string signer, RSA &key); - - std::list mRecognGroupIds; - std::list mRecognGroupsToProcess; - std::map mRecognSignKeys; - std::map mRecognOldSignKeys; - - /************************************************************************ - * Below is the background task for processing opinions => reputations - * - */ - - virtual void generateDummyData(); - void generateDummy_OwnIds(); - void generateDummy_FriendPGP(); - void generateDummy_UnknownPGP(); - void generateDummy_UnknownPseudo(); - - void cleanUnusedKeys() ; - void slowIndicateConfigChanged() ; - - virtual void timeStampKey(const RsGxsId& id, const RsIdentityUsage& reason) override; - rstime_t locked_getLastUsageTS(const RsGxsId& gxs_id); - - std::string genRandomId(int len = 20); - -#if 0 - bool reputation_start(); - bool reputation_continue(); - - int background_tick(); - bool background_checkTokenRequest(); - bool background_requestGroups(); - bool background_requestNewMessages(); - bool background_processNewMessages(); - bool background_FullCalcRequest(); - bool background_processFullCalc(); - - bool background_cleanup(); -#endif - - RsMutex mIdMtx; - -#if 0 - /***** below here is locked *****/ - bool mLastBgCheck; - bool mBgProcessing; - - uint32_t mBgToken; - uint32_t mBgPhase; - - std::map mBgGroupMap; - std::list mBgFullCalcGroups; -#endif - - /************************************************************************ - * Other Data that is protected by the Mutex. - */ - -private: - - struct keyTSInfo - { - keyTSInfo() : TS(0) {} - - rstime_t TS ; - std::map usage_map ; - }; - friend class IdCacheEntryCleaner; - - std::map > mIdsPendingCache; - std::map > mGroupNotPresent; - std::map > mIdsNotPresent; - std::map mKeysTS ; - - std::map mSerialisedIdentities ; - - // keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only. - std::set mContacts; - RsNetworkExchangeService* mNes; - - /************************** - * AuxUtils provides interface to Security Function (e.g. GPGAuth(), notify etc.) - * without depending directly on all these classes. - */ - - PgpAuxUtils *mPgpUtils; - rstime_t mLastPGPHashProcessTime ; - rstime_t mLastKeyCleaningTime ; - rstime_t mLastConfigUpdate ; - - bool mOwnIdsLoaded; - bool ownIdsAreLoaded() { RS_STACK_MUTEX(mIdMtx); return mOwnIdsLoaded; } - - bool mAutoAddFriendsIdentitiesAsContacts; - uint32_t mMaxKeepKeysBanned; - - RS_SET_CONTEXT_DEBUG_LEVEL(2) -}; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc deleted file mode 100644 index 5974d7bf3..000000000 --- a/libretroshare/src/services/p3msgservice.cc +++ /dev/null @@ -1,2463 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3msgservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2016-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsidentity.h" - -#include "pqi/pqibin.h" -#include "pqi/p3linkmgr.h" -#include "pqi/authgpg.h" -#include "pqi/p3cfgmgr.h" - -#include "gxs/gxssecurity.h" - -#include "services/p3idservice.h" -#include "services/p3msgservice.h" - -#include "pgp/pgpkeyutil.h" -#include "rsserver/p3face.h" - -#include "rsitems/rsconfigitems.h" - -#include "grouter/p3grouter.h" -#include "grouter/groutertypes.h" - -#include "util/rsdebug.h" -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "util/radix64.h" -#include "util/rsrandom.h" -#include "util/rsmemory.h" -#include "util/rsprint.h" -#include "util/rsthreads.h" - -#include -#include -#include -#include - -using namespace Rs::Msgs; - -/// keep msg hashes for 2 months to avoid re-sent msgs -static constexpr uint32_t RS_MSG_DISTANT_MESSAGE_HASH_KEEP_TIME = 2*30*86400; - -/* Another little hack ..... unique message Ids - * will be handled in this class..... - * These are unique within this run of the server, - * and are not stored long term.... - * - * Only 3 entry points: - * (1) from network.... - * (2) from local send - * (3) from storage... - */ - -p3MsgService::p3MsgService( p3ServiceControl *sc, p3IdService *id_serv, - p3GxsTrans& gxsMS ) - : p3Service(), p3Config(), - gxsOngoingMutex("p3MsgService Gxs Outgoing Mutex"), mIdService(id_serv), - mServiceCtrl(sc), mMsgMtx("p3MsgService"), mMsgUniqueId(0), - recentlyReceivedMutex("p3MsgService recently received hash mutex"), - mGxsTransServ(gxsMS) -{ - /* this serialiser is used for services. It's not the same than the one - * returned by setupSerialiser(). We need both!! */ - _serialiser = new RsMsgSerialiser(); - addSerialType(_serialiser); - - /* MsgIds are not transmitted, but only used locally as a storage index. - * As such, thay do not need to be different at friends nodes. */ - mMsgUniqueId = 1; - - mShouldEnableDistantMessaging = true; - mDistantMessagingEnabled = false; - mDistantMessagePermissions = RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NONE; - - if(sc) initStandardTagTypes(); // Initialize standard tag types - - mGxsTransServ.registerGxsTransClient( GxsTransSubServices::P3_MSG_SERVICE, - this ); -} - -const std::string MSG_APP_NAME = "msg"; -const uint16_t MSG_APP_MAJOR_VERSION = 1; -const uint16_t MSG_APP_MINOR_VERSION = 0; -const uint16_t MSG_MIN_MAJOR_VERSION = 1; -const uint16_t MSG_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3MsgService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_MSG, - MSG_APP_NAME, - MSG_APP_MAJOR_VERSION, - MSG_APP_MINOR_VERSION, - MSG_MIN_MAJOR_VERSION, - MSG_MIN_MINOR_VERSION); -} - -p3MsgService::~p3MsgService() -{ - RS_STACK_MUTEX(mMsgMtx); /********** STACK LOCKED MTX ******/ - - for(auto tag:mTags) delete tag.second; - for(auto tag:mMsgTags) delete tag.second; - for(auto msgid:mSrcIds) delete msgid.second; - for(auto parentid:mParentId) delete parentid.second; - for(auto img:imsg) delete img.second; - for(auto mout:msgOutgoing) delete mout.second; - - for(auto mpend:_pendingPartialMessages) delete mpend.second; -} - -uint32_t p3MsgService::getNewUniqueMsgId() -{ - RS_STACK_MUTEX(mMsgMtx); /********** STACK LOCKED MTX ******/ - return mMsgUniqueId++; -} - -int p3MsgService::tick() -{ - /* don't worry about increasing tick rate! - * (handled by p3service) - */ - - incomingMsgs(); - - static rstime_t last_management_time = 0 ; - rstime_t now = time(NULL) ; - - if(now > last_management_time + 5) - { - manageDistantPeers(); - checkOutgoingMessages(); - cleanListOfReceivedMessageHashes(); - - last_management_time = now; - } - - return 0; -} - -void p3MsgService::cleanListOfReceivedMessageHashes() -{ - RS_STACK_MUTEX(recentlyReceivedMutex); - - rstime_t now = time(nullptr); - - for( auto it = mRecentlyReceivedMessageHashes.begin(); - it != mRecentlyReceivedMessageHashes.end(); ) - if( now > RS_MSG_DISTANT_MESSAGE_HASH_KEEP_TIME + it->second ) - { - std::cerr << "p3MsgService(): cleanListOfReceivedMessageHashes(). " - << "Removing old hash " << it->first << ", aged " - << now - it->second << " secs ago" << std::endl; - - it = mRecentlyReceivedMessageHashes.erase(it); - } - else ++it; -} - -void p3MsgService::processIncomingMsg(RsMsgItem *mi) -{ - mi -> recvTime = static_cast(time(nullptr)); - mi -> msgId = getNewUniqueMsgId(); - - { - RS_STACK_MUTEX(mMsgMtx); - - /* from a peer */ - - mi->msgFlags &= (RS_MSG_FLAGS_DISTANT | RS_MSG_FLAGS_SYSTEM); // remove flags except those - mi->msgFlags |= RS_MSG_FLAGS_NEW; - - if (rsEvents) - { - auto ev = std::make_shared(); - ev->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; - ev->mChangedMsgIds.insert(std::to_string(mi->msgId)); - rsEvents->postEvent(ev); - } - - imsg[mi->msgId] = mi; - RsMsgSrcId* msi = new RsMsgSrcId(); - msi->msgId = mi->msgId; - 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. - - RsIdentityDetails id_details; - if(rsIdentity->getIdDetails(RsGxsId(mi->PeerId()),id_details) && !id_details.mPgpId.isNull() && (rsPeers->servicePermissionFlags(id_details.mPgpId) & 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); -} - -bool p3MsgService::checkAndRebuildPartialMessage(RsMsgItem *ci) -{ - // Check is the item is ending an incomplete item. - // - std::map::iterator it = _pendingPartialMessages.find(ci->PeerId()) ; - - bool ci_is_partial = ci->msgFlags & RS_MSG_FLAGS_PARTIAL ; - - if(it != _pendingPartialMessages.end()) - { -#ifdef MSG_DEBUG - std::cerr << "Pending message found. Appending it." << std::endl; -#endif - // Yes, there is. Append the item to ci. - - ci->message = it->second->message + ci->message ; - ci->msgFlags |= it->second->msgFlags ; - - delete it->second ; - - if(!ci_is_partial) - _pendingPartialMessages.erase(it) ; - } - - if(ci_is_partial) - { -#ifdef MSG_DEBUG - std::cerr << "Message is partial, storing for later." << std::endl; -#endif - // The item is a partial message. Push it, and wait for the rest. - // - _pendingPartialMessages[ci->PeerId()] = ci ; - return false ; - } - else - { -#ifdef MSG_DEBUG - std::cerr << "Message is complete, using it now." << std::endl; -#endif - return true ; - } -} - -int p3MsgService::incomingMsgs() -{ - RsMsgItem *mi; - int i = 0; - - while((mi = (RsMsgItem *) recvItem()) != NULL) - { - handleIncomingItem(mi) ; - ++i ; - } - - return i; -} - -void p3MsgService::handleIncomingItem(RsMsgItem *mi) -{ - bool changed = false ; - - // only returns true when a msg is complete. - if(checkAndRebuildPartialMessage(mi)) - { - processIncomingMsg(mi); - changed = true ; - } - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); -} - -void p3MsgService::statusChange(const std::list &plist) -{ - /* should do it properly! */ - /* only do this when a new peer is connected */ - bool newPeers = false; - std::list::const_iterator it; - for(it = plist.begin(); it != plist.end(); ++it) - { - if (it->actions & RS_SERVICE_PEER_CONNECTED) - { - newPeers = true; - } - } - - if (newPeers) - { - checkOutgoingMessages(); - } -} - -void p3MsgService::checkSizeAndSendMessage(RsMsgItem *msg) -{ - // We check the message item, and possibly split it into multiple messages, if the message is too big. - - static const uint32_t MAX_STRING_SIZE = 15000 ; - - std::cerr << "Msg is size " << msg->message.size() << std::endl; - - while(msg->message.size() > MAX_STRING_SIZE) - { - // chop off the first 15000 wchars - - RsMsgItem *item = new RsMsgItem(*msg) ; - - item->message = item->message.substr(0,MAX_STRING_SIZE) ; - msg->message = msg->message.substr(MAX_STRING_SIZE,msg->message.size()-MAX_STRING_SIZE) ; - -#ifdef DEBUG_DISTANT_MSG - std::cerr << " Chopped off msg of size " << item->message.size() << std::endl; -#endif - - // Indicate that the message is to be continued. - // - item->msgFlags |= RS_MSG_FLAGS_PARTIAL ; - sendItem(item) ; - } -#ifdef DEBUG_DISTANT_MSG - std::cerr << " Chopped off msg of size " << msg->message.size() << std::endl; -#endif - - sendItem(msg) ; -} - -int p3MsgService::checkOutgoingMessages() -{ - bool changed = false; - std::list output_queue; - - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; - - { - RS_STACK_MUTEX(mMsgMtx); /********** STACK LOCKED MTX ******/ - - const RsPeerId& ownId = mServiceCtrl->getOwnId(); - - std::list::iterator it; - std::list toErase; - - std::map::iterator mit; - for( mit = msgOutgoing.begin(); mit != msgOutgoing.end(); ++mit ) - { - if (mit->second->msgFlags & RS_MSG_FLAGS_TRASH) continue; - - /* find the certificate */ - RsPeerId pid = mit->second->PeerId(); - bool should_send = false; - - if( pid == ownId) should_send = true; - - // FEEDBACK Msg to Ourselves - if( mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, - pid) ) - should_send = true; - - if( (mit->second->msgFlags & RS_MSG_FLAGS_DISTANT) && - !(mit->second->msgFlags & RS_MSG_FLAGS_ROUTED)) - should_send = true; - - if(should_send) - { - Dbg3() << __PRETTY_FUNCTION__ << " Sending out message" - << std::endl; - /* remove the pending flag */ - - output_queue.push_back(mit->second); - pEvent->mChangedMsgIds.insert(std::to_string(mit->first)); - - /* When the message is a distant msg, dont remove it yet from - * the list. Only mark it as being sent, so that we don't send - * it again. */ - if(!(mit->second->msgFlags & RS_MSG_FLAGS_DISTANT)) - { - (mit->second)->msgFlags &= ~RS_MSG_FLAGS_PENDING; - toErase.push_back(mit->first); - changed = true; - } - else - { -#ifdef DEBUG_DISTANT_MSG - std::cerr << "Message id " << mit->first << " is distant: " - << "kept in outgoing, and marked as ROUTED" - << std::endl; -#endif - mit->second->msgFlags |= RS_MSG_FLAGS_ROUTED; - } - } -#ifdef DEBUG_DISTANT_MSG - else - Dbg3() << __PRETTY_FUNCTION__ << " Delaying until available..." << std::endl; -#endif - } - - /* clean up */ - for(it = toErase.begin(); it != toErase.end(); ++it) - { - mit = msgOutgoing.find(*it); - if ( mit != msgOutgoing.end() ) msgOutgoing.erase(mit); - - std::map::iterator srcIt = mSrcIds.find(*it); - if (srcIt != mSrcIds.end()) - { - delete (srcIt->second); - mSrcIds.erase(srcIt); - } - } - - if (toErase.size() > 0) IndicateConfigChanged(); - } - - for( std::list::const_iterator it(output_queue.begin()); - it != output_queue.end(); ++it ) - if( (*it)->msgFlags & RS_MSG_FLAGS_DISTANT ) // don't split distant messages. The global router takes care of it. - sendDistantMsgItem(*it); - else - checkSizeAndSendMessage(*it); - - if(changed) - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - - if(rsEvents && !pEvent->mChangedMsgIds.empty()) - rsEvents->postEvent(pEvent); - - return 0; -} - -bool p3MsgService::saveList(bool& cleanup, std::list& itemList) -{ - RsMsgGRouterMap* gxsmailmap = new RsMsgGRouterMap; - { - RS_STACK_MUTEX(gxsOngoingMutex); - gxsmailmap->ongoing_msgs = gxsOngoingMessages; - } - itemList.push_front(gxsmailmap); - - std::map::iterator mit; - std::map::iterator mit2; - std::map::iterator mit3; - std::map::iterator lit; - std::map::iterator mit4; - - cleanup = true; - - mMsgMtx.lock(); - - for(mit = imsg.begin(); mit != imsg.end(); ++mit) - itemList.push_back(new RsMsgItem(*mit->second)); - - for(lit = mSrcIds.begin(); lit != mSrcIds.end(); ++lit) - itemList.push_back(new RsMsgSrcId(*lit->second)); - - - for(mit = msgOutgoing.begin(); mit != msgOutgoing.end(); ++mit) - itemList.push_back(new RsMsgItem(*mit->second)) ; - - for(mit2 = mTags.begin(); mit2 != mTags.end(); ++mit2) - itemList.push_back(new RsMsgTagType(*mit2->second)); - - for(mit3 = mMsgTags.begin(); mit3 != mMsgTags.end(); ++mit3) - itemList.push_back(new RsMsgTags(*mit3->second)); - - for(mit4 = mParentId.begin(); mit4 != mParentId.end(); ++mit4) - itemList.push_back(new RsMsgParentId(*mit4->second)); - - RsMsgGRouterMap *grmap = new RsMsgGRouterMap ; - grmap->ongoing_msgs = _ongoing_messages ; - - itemList.push_back(grmap) ; - - RsMsgDistantMessagesHashMap *ghm = new RsMsgDistantMessagesHashMap; - { - RS_STACK_MUTEX(recentlyReceivedMutex); - ghm->hash_map = mRecentlyReceivedMessageHashes; - } - itemList.push_back(ghm); - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "DISTANT_MESSAGES_ENABLED" ; - kv.value = mShouldEnableDistantMessaging?"YES":"NO" ; - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "DISTANT_MESSAGE_PERMISSION_FLAGS" ; - kv.value = RsUtil::NumberToString(mDistantMessagePermissions) ; - vitem->tlvkvs.pairs.push_back(kv) ; - - itemList.push_back(vitem); - - return true; -} - -void p3MsgService::saveDone() -{ - // unlocks mutex which has been locked by savelist - mMsgMtx.unlock(); -} - -RsSerialiser* p3MsgService::setupSerialiser() // this serialiser is used for config. So it adds somemore info in the serialised items -{ - RsSerialiser *rss = new RsSerialiser ; - - rss->addSerialType(new RsMsgSerialiser(RsSerializationFlags::CONFIG)); - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss; -} - -// build list of standard tag types -static void getStandardTagTypes(MsgTagType &tags) -{ - /* create standard tag types, the text must be translated in the GUI */ - tags.types [RS_MSGTAGTYPE_IMPORTANT] = std::pair ("Important", 0xFF0000); - tags.types [RS_MSGTAGTYPE_WORK] = std::pair ("Work", 0xFF9900); - tags.types [RS_MSGTAGTYPE_PERSONAL] = std::pair ("Personal", 0x009900); - tags.types [RS_MSGTAGTYPE_TODO] = std::pair ("Todo", 0x3333FF); - tags.types [RS_MSGTAGTYPE_LATER] = std::pair ("Later", 0x993399); -} - -// Initialize the standard tag types after load -void p3MsgService::initStandardTagTypes() -{ - bool bChanged = false; - const RsPeerId& ownId = mServiceCtrl->getOwnId(); - - MsgTagType tags; - getStandardTagTypes(tags); - - std::map >::iterator tit; - for (tit = tags.types.begin(); tit != tags.types.end(); ++tit) { - std::map::iterator mit = mTags.find(tit->first); - if (mit == mTags.end()) { - RsMsgTagType* tagType = new RsMsgTagType(); - tagType->PeerId (ownId); - tagType->tagId = tit->first; - tagType->text = tit->second.first; - tagType->rgb_color = tit->second.second; - - mTags.insert(std::pair(tit->first, tagType)); - - bChanged = true; - } - } - - if (bChanged) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } -} - -bool p3MsgService::loadList(std::list& load) -{ - auto gxsmIt = load.begin(); - RsMsgGRouterMap* gxsmailmap = dynamic_cast(*gxsmIt); - if(gxsmailmap) - { - { - RS_STACK_MUTEX(gxsOngoingMutex); - gxsOngoingMessages = gxsmailmap->ongoing_msgs; - } - delete *gxsmIt; load.erase(gxsmIt); - } - - RsMsgItem *mitem; - RsMsgTagType* mtt; - RsMsgTags* mti; - RsMsgSrcId* msi; - RsMsgParentId* msp; - RsMsgGRouterMap* grm; - RsMsgDistantMessagesHashMap *ghm; - - std::list items; - std::list::iterator it; - std::map::iterator tagIt; - std::map srcIdMsgMap; - std::map::iterator srcIt; - - uint32_t max_msg_id = 0 ; - - // load items and calculate next unique msgId - for(it = load.begin(); it != load.end(); ++it) - { - if (NULL != (mitem = dynamic_cast(*it))) - { - /* STORE MsgID */ - if (mitem->msgId > max_msg_id) - max_msg_id = mitem->msgId ; - - items.push_back(mitem); - } - else if (NULL != (grm = dynamic_cast(*it))) - { - typedef std::map tT; - for( tT::const_iterator bit = grm->ongoing_msgs.begin(); - bit != grm->ongoing_msgs.end(); ++bit ) - _ongoing_messages.insert(*bit); - delete *it; - continue; - } - else if(NULL != (ghm = dynamic_cast(*it))) - { - { - RS_STACK_MUTEX(recentlyReceivedMutex); - mRecentlyReceivedMessageHashes = ghm->hash_map; - } -#ifdef DEBUG_DISTANT_MSG - std::cerr << " loaded recently received message map: " << std::endl; - - for(std::map::const_iterator it(mRecentlyReceivedDistantMessageHashes.begin());it!=mRecentlyReceivedDistantMessageHashes.end();++it) - std::cerr << " " << it->first << " received " << time(NULL)-it->second << " secs ago." << std::endl; -#endif - delete *it ; - continue ; - } - else if(NULL != (mtt = dynamic_cast(*it))) - { - // delete standard tags as they are now save in config - if(mTags.end() == (tagIt = mTags.find(mtt->tagId))) - { - mTags.insert(std::pair(mtt->tagId, mtt)); - } - else - { - delete mTags[mtt->tagId]; - mTags.erase(tagIt); - mTags.insert(std::pair(mtt->tagId, mtt)); - } - - } - else if(NULL != (mti = dynamic_cast(*it))) - { - mMsgTags.insert(std::pair(mti->msgId, mti)); - } - else if(NULL != (msi = dynamic_cast(*it))) - { - srcIdMsgMap.insert(std::pair(msi->msgId, msi->srcId)); - mSrcIds.insert(std::pair(msi->msgId, msi)); // does not need to be kept - } - else if(NULL != (msp = dynamic_cast(*it))) - { - mParentId.insert(std::pair(msp->msgId, msp)); - } - - RsConfigKeyValueSet *vitem = NULL ; - - if(NULL != (vitem = dynamic_cast(*it))) - { - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if(kit->key == "DISTANT_MESSAGES_ENABLED") - { -#ifdef MSG_DEBUG - std::cerr << "Loaded config default nick name for distant chat: " << kit->value << std::endl ; -#endif - mShouldEnableDistantMessaging = (kit->value == "YES") ; - } - if(kit->key == "DISTANT_MESSAGE_PERMISSION_FLAGS") - { -#ifdef MSG_DEBUG - std::cerr << "Loaded distant message permission flags: " << kit->value << std::endl ; -#endif - if (!kit->value.empty()) - { - std::istringstream is(kit->value) ; - - uint32_t tmp ; - is >> tmp ; - - if(tmp < 3) - mDistantMessagePermissions = tmp ; - else - std::cerr << "(EE) Invalid value read for DistantMessagePermission flags in config: " << tmp << std::endl; - } - } - } - - delete *it ; - continue ; - } - } - mMsgUniqueId = max_msg_id + 1; // make it unique with respect to what was loaded. Not totally safe, but works 99.9999% of the cases. - load.clear() ; - - // sort items into lists - std::list::iterator msgIt; - for (msgIt = items.begin(); msgIt != items.end(); ++msgIt) - { - mitem = *msgIt; - - /* STORE MsgID */ - if (mitem->msgId == 0) { - mitem->msgId = getNewUniqueMsgId(); - } - - RS_STACK_MUTEX(mMsgMtx); - - srcIt = srcIdMsgMap.find(mitem->msgId); - if(srcIt != srcIdMsgMap.end()) { - mitem->PeerId(srcIt->second); - srcIdMsgMap.erase(srcIt); - } - - /* switch depending on the PENDING - * flags - */ - if (mitem -> msgFlags & RS_MSG_FLAGS_PENDING) - { - - //std::cerr << "MSG_PENDING"; - //std::cerr << std::endl; - //mitem->print(std::cerr); - - msgOutgoing[mitem->msgId] = mitem; - } - else - { - imsg[mitem->msgId] = mitem; - } - } - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - /* remove missing msgId in mSrcIds */ - for (srcIt = srcIdMsgMap.begin(); srcIt != srcIdMsgMap.end(); ++srcIt) { - std::map::iterator it = mSrcIds.find(srcIt->first); - if (it != mSrcIds.end()) { - delete(it->second); - mSrcIds.erase(it); - } - } - - /* remove missing msgId in mParentId */ - std::map::iterator mit = mParentId.begin(); - while (mit != mParentId.end()) { - if (imsg.find(mit->first) == imsg.end()) { - if (msgOutgoing.find(mit->first) == msgOutgoing.end()) { - /* not found */ - mParentId.erase(mit++); - continue; - } - } - - ++mit; - } - - return true; -} - -void p3MsgService::loadWelcomeMsg() -{ - /* Load Welcome Message */ - RsMsgItem *msg = new RsMsgItem(); - - //msg -> PeerId(mServiceCtrl->getOwnId()); - - msg -> sendTime = time(NULL); - msg -> recvTime = time(NULL); - msg -> msgFlags = RS_MSG_FLAGS_NEW; - - msg -> subject = "Welcome to Retroshare"; - - msg -> message = "Send and receive messages with your friends...\n"; - msg -> message += "These can hold recommendations from your local shared files.\n\n"; - msg -> message += "Add recommendations through the Local Files Dialog.\n\n"; - msg -> message += "Enjoy."; - - msg -> msgId = getNewUniqueMsgId(); - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - imsg[msg->msgId] = msg; - - IndicateConfigChanged(); -} - - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - - -/****************************************/ -/****************************************/ - -bool p3MsgService::getMessageSummaries(std::list &msgList) -{ - /* do stuff */ - msgList.clear(); - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit; - for(mit = imsg.begin(); mit != imsg.end(); ++mit) - { - MsgInfoSummary mis; - initRsMIS(mit->second, mis); - msgList.push_back(mis); - } - - for(mit = msgOutgoing.begin(); mit != msgOutgoing.end(); ++mit) - { - MsgInfoSummary mis; - initRsMIS(mit->second, mis); - msgList.push_back(mis); - } - return true; -} - -bool p3MsgService::getMessage(const std::string &mId, MessageInfo &msg) -{ - std::map::iterator mit; - uint32_t msgId = atoi(mId.c_str()); - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - mit = imsg.find(msgId); - if (mit == imsg.end()) - { - mit = msgOutgoing.find(msgId); - if (mit == msgOutgoing.end()) - { - return false; - } - } - - /* mit valid */ - initRsMI(mit->second, msg); - - std::map::const_iterator it = mSrcIds.find(msgId) ; - if(it != mSrcIds.end()) - msg.rsgxsid_srcId = RsGxsId(it->second->srcId) ; // (cyril) this is a hack. Not good. I'm not removing it because it may have consequences, but I dont like this. - - return true; -} - -void p3MsgService::getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox) -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - nInbox = 0; - nInboxNew = 0; - nOutbox = 0; - nDraftbox = 0; - nSentbox = 0; - nTrashbox = 0; - - std::map::iterator mit; - std::map *apMsg [2] = { &imsg, &msgOutgoing }; - - for (int i = 0; i < 2; i++) { - for (mit = apMsg [i]->begin(); mit != apMsg [i]->end(); ++mit) { - MsgInfoSummary mis; - initRsMIS(mit->second, mis); - - if (mis.msgflags & RS_MSG_TRASH) { - ++nTrashbox; - continue; - } - switch (mis.msgflags & RS_MSG_BOXMASK) { - case RS_MSG_INBOX: - ++nInbox; - if ((mis.msgflags & RS_MSG_NEW) == RS_MSG_NEW) - ++nInboxNew; - break; - case RS_MSG_OUTBOX: - ++nOutbox; - break; - case RS_MSG_DRAFTBOX: - ++nDraftbox; - break; - case RS_MSG_SENTBOX: - ++nSentbox; - break; - } - } - } -} - -/* remove based on the unique mid (stored in sid) */ -bool p3MsgService::removeMsgId(const std::string &mid) -{ - std::map::iterator mit; - uint32_t msgId = atoi(mid.c_str()); - if (msgId == 0) { - std::cerr << "p3MsgService::removeMsgId: Unknown msgId " << msgId << std::endl; - return false; - } - - bool changed = false; - - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_REMOVED; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - mit = imsg.find(msgId); - if (mit != imsg.end()) - { - changed = true; - RsMsgItem *mi = mit->second; - imsg.erase(mit); - delete mi; - pEvent->mChangedMsgIds.insert(mid); - } - - mit = msgOutgoing.find(msgId); - if (mit != msgOutgoing.end()) - { - changed = true ; - RsMsgItem *mi = mit->second; - msgOutgoing.erase(mit); - delete mi; - pEvent->mChangedMsgIds.insert(mid); - } - - std::map::iterator srcIt = mSrcIds.find(msgId); - if (srcIt != mSrcIds.end()) { - changed = true; - delete (srcIt->second); - mSrcIds.erase(srcIt); - pEvent->mChangedMsgIds.insert(mid); - } - } - - if(changed) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - setMessageTag(mid, 0, false); - setMsgParentId(msgId, 0); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - - if(rsEvents && !pEvent->mChangedMsgIds.empty()) - rsEvents->postEvent(pEvent); - - return changed; -} - -bool p3MsgService::markMsgIdRead(const std::string &mid, bool unreadByUser) -{ - std::map::iterator mit; - uint32_t msgId = atoi(mid.c_str()); - bool changed = false; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - mit = imsg.find(msgId); - if (mit != imsg.end()) - { - RsMsgItem *mi = mit->second; - - uint32_t msgFlags = mi->msgFlags; - - /* remove new state */ - mi->msgFlags &= ~(RS_MSG_FLAGS_NEW); - - /* set state from user */ - if (unreadByUser) { - mi->msgFlags |= RS_MSG_FLAGS_UNREAD_BY_USER; - } else { - mi->msgFlags &= ~RS_MSG_FLAGS_UNREAD_BY_USER; - } - - if (mi->msgFlags != msgFlags) - { - changed = true; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - } else { - return false; - } - } /* UNLOCKED */ - - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - - return true; -} - -bool p3MsgService::setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mask) -{ - std::map::iterator mit; - uint32_t msgId = atoi(mid.c_str()); - - bool changed = false; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - mit = imsg.find(msgId); - if (mit == imsg.end()) - { - mit = msgOutgoing.find(msgId); - if (mit == msgOutgoing.end()) - { - return false; - } - } - - uint32_t oldFlag = mit->second->msgFlags; - - mit->second->msgFlags &= ~mask; - mit->second->msgFlags |= flag; - - if (mit->second->msgFlags != oldFlag) { - changed = true; - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - } /* UNLOCKED */ - - if (changed) { - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - - return true; -} - -bool p3MsgService::getMsgParentId(const std::string &msgId, std::string &msgParentId) -{ - msgParentId.clear(); - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit = mParentId.find(atoi(msgId.c_str())); - if (mit == mParentId.end()) { - return false; - } - - rs_sprintf(msgParentId, "%lu", mit->second->msgParentId); - - return true; -} - -bool p3MsgService::setMsgParentId(uint32_t msgId, uint32_t msgParentId) -{ - std::map::iterator mit; - - bool changed = false; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - mit = mParentId.find(msgId); - if (mit == mParentId.end()) - { - if (msgParentId) { - RsMsgParentId* msp = new RsMsgParentId(); - msp->PeerId (mServiceCtrl->getOwnId()); - msp->msgId = msgId; - msp->msgParentId = msgParentId; - mParentId.insert(std::pair(msgId, msp)); - - changed = true; - } - } else { - if (msgParentId) { - if (mit->second->msgParentId != msgParentId) { - mit->second->msgParentId = msgParentId; - changed = true; - } - } else { - delete mit->second; - mParentId.erase(mit); - changed = true; - } - } - } /* UNLOCKED */ - - if (changed) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - } - - return true; -} - -/****************************************/ -/****************************************/ - /* Message Items */ -// no from field because it's implicitly our own PeerId -uint32_t p3MsgService::sendMessage(RsMsgItem* item) -{ - if(!item) - { - RsErr() << __PRETTY_FUNCTION__ << " item can't be null" << std::endl; - return 0; - } - - item->msgId = getNewUniqueMsgId(); /* grabs Mtx as well */ - item->msgFlags |= (RS_MSG_FLAGS_OUTGOING | RS_MSG_FLAGS_PENDING); /* add pending flag */ - - { - RS_STACK_MUTEX(mMsgMtx) ; - - /* STORE MsgID */ - msgOutgoing[item->msgId] = item; - - if (item->PeerId() != mServiceCtrl->getOwnId()) - { - /* not to the loopback device */ - - RsMsgSrcId* msi = new RsMsgSrcId(); - msi->msgId = item->msgId; - msi->srcId = mServiceCtrl->getOwnId(); - mSrcIds.insert(std::pair(msi->msgId, msi)); - } - } - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST, NOTIFY_TYPE_ADD); // deprecated - - return item->msgId; -} - -uint32_t p3MsgService::sendDistantMessage(RsMsgItem *item, const RsGxsId& from) -{ - if(!item) - { - RsErr() << __PRETTY_FUNCTION__ << " item can't be null" << std::endl; - print_stacktrace(); - return 0; - } - - item->msgId = getNewUniqueMsgId(); /* grabs Mtx as well */ - item->msgFlags |= ( RS_MSG_FLAGS_DISTANT | RS_MSG_FLAGS_OUTGOING | - RS_MSG_FLAGS_PENDING ); /* add pending flag */ - - { - RS_STACK_MUTEX(mMsgMtx); - - /* STORE MsgID */ - msgOutgoing[item->msgId] = item; - mDistantOutgoingMsgSigners[item->msgId] = from ; - - if (item->PeerId() != mServiceCtrl->getOwnId()) - { - /* not to the loopback device */ - - RsMsgSrcId* msi = new RsMsgSrcId(); - msi->msgId = item->msgId; - msi->srcId = RsPeerId(from); - mSrcIds.insert(std::pair(msi->msgId, msi)); - } - } - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); - return item->msgId; -} - -bool p3MsgService::MessageSend(MessageInfo &info) -{ - for(std::set::const_iterator pit = info.rspeerid_msgto.begin(); pit != info.rspeerid_msgto.end(); ++pit) sendMessage(initMIRsMsg(info, *pit)); - for(std::set::const_iterator pit = info.rspeerid_msgcc.begin(); pit != info.rspeerid_msgcc.end(); ++pit) sendMessage(initMIRsMsg(info, *pit)); - for(std::set::const_iterator pit = info.rspeerid_msgbcc.begin(); pit != info.rspeerid_msgbcc.end(); ++pit) sendMessage(initMIRsMsg(info, *pit)); - - for(std::set::const_iterator pit = info.rsgxsid_msgto.begin(); pit != info.rsgxsid_msgto.end(); ++pit) sendDistantMessage(initMIRsMsg(info, *pit),info.rsgxsid_srcId); - for(std::set::const_iterator pit = info.rsgxsid_msgcc.begin(); pit != info.rsgxsid_msgcc.end(); ++pit) sendDistantMessage(initMIRsMsg(info, *pit),info.rsgxsid_srcId); - for(std::set::const_iterator pit = info.rsgxsid_msgbcc.begin(); pit != info.rsgxsid_msgbcc.end(); ++pit) sendDistantMessage(initMIRsMsg(info, *pit),info.rsgxsid_srcId); - - // store message in outgoing list. In order to appear as sent the message needs to have the OUTGOING flg, but no pending flag on. - - RsMsgItem *msg = initMIRsMsg(info, mServiceCtrl->getOwnId()); - - if (msg) - { - if (msg->msgFlags & RS_MSG_FLAGS_SIGNED) - msg->msgFlags |= RS_MSG_FLAGS_SIGNATURE_CHECKS; // this is always true, since we are sending the message - - /* use processMsg to get the new msgId */ - msg->recvTime = time(NULL); - msg->msgId = getNewUniqueMsgId(); - - msg->msgFlags |= RS_MSG_OUTGOING; - - imsg[msg->msgId] = msg; - - // Update info for caller - info.msgId = std::to_string(msg->msgId); - info .msgflags = msg->msgFlags; - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);// deprecated. Should be removed. Oct. 28, 2020 - } - - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; - pEvent->mChangedMsgIds.insert(std::to_string(msg->msgId)); - rsEvents->postEvent(pEvent); - - return true; -} - -uint32_t p3MsgService::sendMail( - const RsGxsId from, - const std::string& subject, - const std::string& body, - const std::set& to, - const std::set& cc, - const std::set& bcc, - const std::vector& attachments, - std::set& trackingIds, - std::string& errorMsg ) -{ - errorMsg.clear(); - const std::string fname = __PRETTY_FUNCTION__; - auto pCheck = [&](bool test, const std::string& errMsg) - { - if(!test) - { - errorMsg = errMsg; - RsErr() << fname << " " << errMsg << std::endl; - } - return test; - }; - - if(!pCheck(!from.isNull(), "from can't be null")) return false; - if(!pCheck( rsIdentity->isOwnId(from), - "from must be own identity") ) return false; - if(!pCheck(!(to.empty() && cc.empty() && bcc.empty()), - "You must specify at least one recipient" )) return false; - - auto dstCheck = - [&](const std::set& dstSet, const std::string& setName) - { - for(const RsGxsId& dst: dstSet) - { - if(dst.isNull()) - { - errorMsg = setName + " contains a null recipient"; - RsErr() << fname << " " << errorMsg << std::endl; - return false; - } - - if(!rsIdentity->isKnownId(dst)) - { - rsIdentity->requestIdentity(dst); - errorMsg = setName + " contains an unknown recipient: " + - dst.toStdString(); - RsErr() << fname << " " << errorMsg << std::endl; - return false; - } - } - return true; - }; - - if(!dstCheck(to, "to")) return false; - if(!dstCheck(cc, "cc")) return false; - if(!dstCheck(bcc, "bcc")) return false; - - MessageInfo msgInfo; - - msgInfo.rsgxsid_srcId = from; - msgInfo.title = subject; - msgInfo.msg = body; - msgInfo.rsgxsid_msgto = to; - msgInfo.rsgxsid_msgcc = cc; - msgInfo.rsgxsid_msgbcc = bcc; - std::copy( attachments.begin(), attachments.end(), - std::back_inserter(msgInfo.files) ); - - uint32_t ret = 0; - - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; - - auto pSend = [&](const std::set& sDest) - { - for(const RsGxsId& dst : sDest) - { - RsMsgItem* msgItem = initMIRsMsg(msgInfo, dst); - if(!msgItem) - { - errorMsg += " initMIRsMsg from: " + from.toStdString() - + " dst: " + dst.toStdString() + " subject: " + subject - + " returned nullptr!\n"; - RsErr() << fname << errorMsg; - continue; - } - - uint32_t msgId = sendDistantMessage(msgItem, from); - // ensure we don't use that ptr again without noticing - msgItem = nullptr; - - if(!msgId) - { - errorMsg += " sendDistantMessage from: " + from.toStdString() - + " dst: " + dst.toStdString() + " subject: " + subject - + " returned 0!\n"; - RsErr() << fname << errorMsg; - continue; - } - - const RsMailMessageId mailId = std::to_string(msgId); - pEvent->mChangedMsgIds.insert(mailId); - trackingIds.insert(RsMailIdRecipientIdPair(mailId, dst)); - ++ret; - } - }; - - pSend(to); - pSend(cc); - pSend(bcc); - - if(rsEvents) rsEvents->postEvent(pEvent); - return ret; -} - -bool p3MsgService::SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag) -{ - if ((systemFlag & RS_MSG_SYSTEM) == 0) { - /* no flag specified */ - return false; - } - - - RsMsgItem *msg = new RsMsgItem(); - - msg->PeerId();// Notification == null - - msg->msgFlags = 0; - - if (systemFlag & RS_MSG_USER_REQUEST) { - msg->msgFlags |= RS_MSG_FLAGS_USER_REQUEST; - } - if (systemFlag & RS_MSG_FRIEND_RECOMMENDATION) { - msg->msgFlags |= RS_MSG_FLAGS_FRIEND_RECOMMENDATION; - } - if (systemFlag & RS_MSG_PUBLISH_KEY) { - msg->msgFlags |= RS_MSG_FLAGS_PUBLISH_KEY; - } - - msg->msgId = 0; - msg->sendTime = time(NULL); - msg->recvTime = 0; - - msg->subject = title; - msg->message = message; - - msg->rspeerid_msgto.ids.insert(mServiceCtrl->getOwnId()); - - processIncomingMsg(msg); - - return true; -} - -bool p3MsgService::MessageToDraft(MessageInfo &info, const std::string &msgParentId) -{ - RsMsgItem *msg = initMIRsMsg(info, mServiceCtrl->getOwnId()); - if (msg) - { - uint32_t msgId = 0; - if (info.msgId.empty() == false) { - msgId = atoi(info.msgId.c_str()); - } - - if (msgId) { - msg->msgId = msgId; - } else { - msg->msgId = getNewUniqueMsgId(); /* grabs Mtx as well */ - } - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - /* add pending flag */ - msg->msgFlags |= (RS_MSG_OUTGOING | RS_MSG_FLAGS_DRAFT); - - if (msgId) { - // remove existing message - std::map::iterator mit; - mit = imsg.find(msgId); - if (mit != imsg.end()) { - RsMsgItem *mi = mit->second; - imsg.erase(mit); - delete mi; - } - } - /* STORE MsgID */ - imsg[msg->msgId] = msg; - - // return new message id - rs_sprintf(info.msgId, "%lu", msg->msgId); - } - - setMsgParentId(msg->msgId, atoi(msgParentId.c_str())); - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - // RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; - rsEvents->postEvent(pEvent); - - return true; - } - - return false; -} - -bool p3MsgService::getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info) -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - return locked_getMessageTag(msgId,info); -} - -bool p3MsgService::getMessageTagTypes(MsgTagType& tags) -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit; - - for(mit = mTags.begin(); mit != mTags.end(); ++mit) { - std::pair p(mit->second->text, mit->second->rgb_color); - tags.types.insert(std::pair >(mit->first, p)); - } - - return true; -} - -bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) -{ - int nNotifyType = 0; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit; - mit = mTags.find(tagId); - - if (mit == mTags.end()) { - if (tagId < RS_MSGTAGTYPE_USER) { - std::cerr << "p3MsgService::MessageSetTagType: Standard tag type " << tagId << " cannot be inserted" << std::endl; - return false; - } - - /* new tag */ - RsMsgTagType* tagType = new RsMsgTagType(); - tagType->PeerId (mServiceCtrl->getOwnId()); - tagType->rgb_color = rgb_color; - tagType->tagId = tagId; - tagType->text = text; - - mTags.insert(std::pair(tagId, tagType)); - - nNotifyType = NOTIFY_TYPE_ADD; - } else { - if (mit->second->text != text || mit->second->rgb_color != rgb_color) { - /* modify existing tag */ - if (tagId >= RS_MSGTAGTYPE_USER) { - mit->second->text = text; - } else { - /* don't change text for standard tag types */ - if (mit->second->text != text) { - std::cerr << "p3MsgService::MessageSetTagType: Text " << text << " for standard tag type " << tagId << " cannot be changed" << std::endl; - } - } - mit->second->rgb_color = rgb_color; - - nNotifyType = NOTIFY_TYPE_MOD; - } - } - - } /* UNLOCKED */ - - if (nNotifyType) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); - - return true; - } - - return false; -} - -bool p3MsgService::removeMessageTagType(uint32_t tagId) -{ - if (tagId < RS_MSGTAGTYPE_USER) { - std::cerr << "p3MsgService::MessageRemoveTagType: Can't delete standard tag type " << tagId << std::endl; - return false; - } - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit; - mit = mTags.find(tagId); - - if (mit == mTags.end()) { - /* tag id not found */ - std::cerr << "p3MsgService::MessageRemoveTagType: Tag Id not found " << tagId << std::endl; - return false; - } - - /* search for messages with this tag type */ - std::map::iterator mit1; - for (mit1 = mMsgTags.begin(); mit1 != mMsgTags.end(); ) { - RsMsgTags* tag = mit1->second; - - std::list::iterator lit; - lit = std::find(tag->tagIds.begin(), tag->tagIds.end(), tagId); - if (lit != tag->tagIds.end()) { - tag->tagIds.erase(lit); - - if (tag->tagIds.empty()) { - /* remove empty tag */ - delete(tag); - - mMsgTags.erase(mit1++); - continue; - } - } - ++mit1; - } - - /* remove tag type */ - delete(mit->second); - mTags.erase(mit); - - } /* UNLOCKED */ - - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, NOTIFY_TYPE_DEL); - - return true; -} - -bool p3MsgService::locked_getMessageTag(const std::string &msgId, MsgTagInfo& info) -{ - uint32_t mid = atoi(msgId.c_str()); - if (mid == 0) { - std::cerr << "p3MsgService::MessageGetMsgTag: Unknown msgId " << msgId << std::endl; - return false; - } - - std::map::iterator mit; - - if(mMsgTags.end() != (mit = mMsgTags.find(mid))) { - rs_sprintf(info.msgId, "%lu", mit->second->msgId); - info.tagIds = mit->second->tagIds; - - return true; - } - - return false; -} - -/* set == false && tagId == 0 --> remove all */ -bool p3MsgService::setMessageTag(const std::string &msgId, uint32_t tagId, bool set) -{ - uint32_t mid = atoi(msgId.c_str()); - if (mid == 0) { - std::cerr << "p3MsgService::MessageSetMsgTag: Unknown msgId " << msgId << std::endl; - return false; - } - - if (tagId == 0) { - if (set == true) { - std::cerr << "p3MsgService::MessageSetMsgTag: No valid tagId given " << tagId << std::endl; - return false; - } - } - - int nNotifyType = 0; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator mit; - mit = mMsgTags.find(mid); - - if (mit == mMsgTags.end()) { - if (set) { - /* new msg */ - RsMsgTags* tag = new RsMsgTags(); - tag->PeerId (mServiceCtrl->getOwnId()); - - tag->msgId = mid; - tag->tagIds.push_back(tagId); - - mMsgTags.insert(std::pair(tag->msgId, tag)); - - nNotifyType = NOTIFY_TYPE_ADD; - } - } else { - RsMsgTags* tag = mit->second; - - /* search existing tagId */ - std::list::iterator lit; - if (tagId) { - lit = std::find(tag->tagIds.begin(), tag->tagIds.end(), tagId); - } else { - lit = tag->tagIds.end(); - } - - if (set) { - if (lit == tag->tagIds.end()) { - tag->tagIds.push_back(tagId); - /* keep the list sorted */ - tag->tagIds.sort(); - nNotifyType = NOTIFY_TYPE_ADD; - } - } else { - if (tagId == 0) { - /* remove all */ - delete(tag); - mMsgTags.erase(mit); - nNotifyType = NOTIFY_TYPE_DEL; - } else { - if (lit != tag->tagIds.end()) { - tag->tagIds.erase(lit); - nNotifyType = NOTIFY_TYPE_DEL; - - if (tag->tagIds.empty()) { - /* remove empty tag */ - delete(tag); - mMsgTags.erase(mit); - } - } - } - } - } - - } /* UNLOCKED */ - - if (nNotifyType) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType); - - return true; - } - - return false; -} - -bool p3MsgService::resetMessageStandardTagTypes(MsgTagType& tags) -{ - MsgTagType standardTags; - getStandardTagTypes(standardTags); - - std::map >::iterator mit; - for (mit = standardTags.types.begin(); mit != standardTags.types.end(); ++mit) { - tags.types[mit->first] = mit->second; - } - - return true; -} - -/* move message to trash based on the unique mid */ -bool p3MsgService::MessageToTrash(const std::string &mid, bool bTrash) -{ - std::map::iterator mit; - uint32_t msgId = atoi(mid.c_str()); - - bool bChanged = false; - bool bFound = false; - - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - RsMsgItem *mi = NULL; - - mit = imsg.find(msgId); - if (mit != imsg.end()) { - mi = mit->second; - } else { - mit = msgOutgoing.find(msgId); - if (mit != msgOutgoing.end()) { - mi = mit->second; - } - } - - if (mi) { - bFound = true; - - if (bTrash) { - if ((mi->msgFlags & RS_MSG_FLAGS_TRASH) == 0) { - mi->msgFlags |= RS_MSG_FLAGS_TRASH; - bChanged = true; - } - } else { - if (mi->msgFlags & RS_MSG_FLAGS_TRASH) { - mi->msgFlags &= ~RS_MSG_FLAGS_TRASH; - bChanged = true; - } - } - } - } - - if (bChanged) { - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - checkOutgoingMessages(); - - RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); - } - - return bFound; -} - -/****************************************/ -/****************************************/ - - -/****************************************/ - -/**** HELPER FNS For Chat/Msg/Channel Lists ************ - * These aren't required to be locked, unless - * the data used is from internal stores -> then they should be. - */ - -void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi) -{ - - mi.msgflags = 0; - - /* translate flags, if we sent it... outgoing */ - - if (msg->msgFlags & RS_MSG_FLAGS_OUTGOING) mi.msgflags |= RS_MSG_OUTGOING; - if (msg->msgFlags & RS_MSG_FLAGS_PENDING) mi.msgflags |= RS_MSG_PENDING; /* if it has a pending flag, then its in the outbox */ - if (msg->msgFlags & RS_MSG_FLAGS_DRAFT) mi.msgflags |= RS_MSG_DRAFT; - if (msg->msgFlags & RS_MSG_FLAGS_NEW) mi.msgflags |= RS_MSG_NEW; - - if (msg->msgFlags & RS_MSG_FLAGS_SIGNED) mi.msgflags |= RS_MSG_SIGNED ; - if (msg->msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS) mi.msgflags |= RS_MSG_SIGNATURE_CHECKS ; - if (msg->msgFlags & RS_MSG_FLAGS_DISTANT) mi.msgflags |= RS_MSG_DISTANT ; - if (msg->msgFlags & RS_MSG_FLAGS_TRASH) mi.msgflags |= RS_MSG_TRASH; - if (msg->msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER) mi.msgflags |= RS_MSG_UNREAD_BY_USER; - if (msg->msgFlags & RS_MSG_FLAGS_REPLIED) mi.msgflags |= RS_MSG_REPLIED; - if (msg->msgFlags & RS_MSG_FLAGS_FORWARDED) mi.msgflags |= RS_MSG_FORWARDED; - if (msg->msgFlags & RS_MSG_FLAGS_STAR) mi.msgflags |= RS_MSG_STAR; - if (msg->msgFlags & RS_MSG_FLAGS_SPAM) mi.msgflags |= RS_MSG_SPAM; - if (msg->msgFlags & RS_MSG_FLAGS_USER_REQUEST) mi.msgflags |= RS_MSG_USER_REQUEST; - if (msg->msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION) mi.msgflags |= RS_MSG_FRIEND_RECOMMENDATION; - if (msg->msgFlags & RS_MSG_FLAGS_PUBLISH_KEY) mi.msgflags |= RS_MSG_PUBLISH_KEY; - if (msg->msgFlags & RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES) mi.msgflags |= RS_MSG_LOAD_EMBEDDED_IMAGES; - - mi.ts = msg->sendTime; - mi.rspeerid_srcId = msg->PeerId(); - - mi.rspeerid_msgto = msg->rspeerid_msgto.ids ; - mi.rspeerid_msgcc = msg->rspeerid_msgcc.ids ; - mi.rspeerid_msgbcc = msg->rspeerid_msgbcc.ids ; - - mi.rsgxsid_msgto = msg->rsgxsid_msgto.ids ; - mi.rsgxsid_msgcc = msg->rsgxsid_msgcc.ids ; - mi.rsgxsid_msgbcc = msg->rsgxsid_msgbcc.ids ; - - mi.title = msg->subject; - mi.msg = msg->message; - { - //msg->msgId; - rs_sprintf(mi.msgId, "%lu", msg->msgId); - } - - mi.attach_title = msg->attachment.title; - mi.attach_comment = msg->attachment.comment; - - mi.count = 0; - mi.size = 0; - - for(std::list::iterator it = msg->attachment.items.begin(); it != msg->attachment.items.end(); ++it) - { - FileInfo fi; - fi.fname = RsDirUtil::getTopDir(it->name); - fi.size = it->filesize; - fi.hash = it->hash; - fi.path = it->path; - mi.files.push_back(fi); - mi.count++; - mi.size += fi.size; - } -} - -void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis) -{ - mis.msgflags = 0; - - if(msg->msgFlags & RS_MSG_FLAGS_DISTANT) - mis.msgflags |= RS_MSG_DISTANT ; - - if (msg->msgFlags & RS_MSG_FLAGS_SIGNED) - mis.msgflags |= RS_MSG_SIGNED ; - - if (msg->msgFlags & RS_MSG_FLAGS_SIGNATURE_CHECKS) - mis.msgflags |= RS_MSG_SIGNATURE_CHECKS ; - - /* translate flags, if we sent it... outgoing */ - if ((msg->msgFlags & RS_MSG_FLAGS_OUTGOING) - /*|| (msg->PeerId() == mServiceCtrl->getOwnId())*/) - { - mis.msgflags |= RS_MSG_OUTGOING; - } - /* if it has a pending flag, then its in the outbox */ - if (msg->msgFlags & RS_MSG_FLAGS_PENDING) - { - mis.msgflags |= RS_MSG_PENDING; - } - if (msg->msgFlags & RS_MSG_FLAGS_DRAFT) - { - mis.msgflags |= RS_MSG_DRAFT; - } - if (msg->msgFlags & RS_MSG_FLAGS_NEW) - { - mis.msgflags |= RS_MSG_NEW; - } - if (msg->msgFlags & RS_MSG_FLAGS_TRASH) - { - mis.msgflags |= RS_MSG_TRASH; - } - if (msg->msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER) - { - mis.msgflags |= RS_MSG_UNREAD_BY_USER; - } - if (msg->msgFlags & RS_MSG_FLAGS_REPLIED) - { - mis.msgflags |= RS_MSG_REPLIED; - } - if (msg->msgFlags & RS_MSG_FLAGS_FORWARDED) - { - mis.msgflags |= RS_MSG_FORWARDED; - } - if (msg->msgFlags & RS_MSG_FLAGS_STAR) - { - mis.msgflags |= RS_MSG_STAR; - } - if (msg->msgFlags & RS_MSG_FLAGS_SPAM) - { - mis.msgflags |= RS_MSG_SPAM; - } - if (msg->msgFlags & RS_MSG_FLAGS_USER_REQUEST) - { - mis.msgflags |= RS_MSG_USER_REQUEST; - } - if (msg->msgFlags & RS_MSG_FLAGS_FRIEND_RECOMMENDATION) - { - mis.msgflags |= RS_MSG_FRIEND_RECOMMENDATION; - } - if (msg->msgFlags & RS_MSG_FLAGS_PUBLISH_KEY) - { - mis.msgflags |= RS_MSG_PUBLISH_KEY; - } - if (msg->msgFlags & RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES) - { - mis.msgflags |= RS_MSG_LOAD_EMBEDDED_IMAGES; - } - - mis.srcId = msg->PeerId(); - { - //msg->msgId; - rs_sprintf(mis.msgId, "%lu", msg->msgId); - } - - mis.title = msg->subject; - mis.count = msg->attachment.items.size(); - mis.ts = msg->sendTime; - - MsgTagInfo taginfo; - locked_getMessageTag(mis.msgId,taginfo); - mis.msgtags = taginfo.tagIds ; -} - -void p3MsgService::initMIRsMsg(RsMsgItem *msg,const MessageInfo& info) -{ - msg -> msgFlags = 0; - msg -> msgId = 0; - msg -> sendTime = time(NULL); - msg -> recvTime = 0; - msg -> subject = info.title; - msg -> message = info.msg; - - msg->rspeerid_msgto.ids = info.rspeerid_msgto ; - msg->rspeerid_msgcc.ids = info.rspeerid_msgcc ; - - msg->rsgxsid_msgto.ids = info.rsgxsid_msgto ; - msg->rsgxsid_msgcc.ids = info.rsgxsid_msgcc ; - - /* We don't fill in bcc (unless to ourselves) */ - - if (msg->PeerId() == mServiceCtrl->getOwnId()) - { - msg->rsgxsid_msgbcc.ids = info.rsgxsid_msgbcc ; - msg->rspeerid_msgbcc.ids = info.rspeerid_msgbcc ; - } - - msg -> attachment.title = info.attach_title; - msg -> attachment.comment = info.attach_comment; - - for(std::list::const_iterator it = info.files.begin(); it != info.files.end(); ++it) - { - RsTlvFileItem mfi; - mfi.hash = it -> hash; - mfi.name = it -> fname; - mfi.filesize = it -> size; - msg -> attachment.items.push_back(mfi); - } - /* translate flags from outside */ - if (info.msgflags & RS_MSG_USER_REQUEST) - msg->msgFlags |= RS_MSG_FLAGS_USER_REQUEST; - - if (info.msgflags & RS_MSG_FRIEND_RECOMMENDATION) - msg->msgFlags |= RS_MSG_FLAGS_FRIEND_RECOMMENDATION; -} -RsMsgItem *p3MsgService::initMIRsMsg(const MessageInfo& info, const RsGxsId& to) -{ - RsMsgItem *msg = new RsMsgItem(); - - initMIRsMsg(msg,info) ; - - msg->PeerId(RsPeerId(to)); - msg->msgFlags |= RS_MSG_FLAGS_DISTANT; - - if (info.msgflags & RS_MSG_SIGNED) - msg->msgFlags |= RS_MSG_FLAGS_SIGNED; - -// // We replace the msg text by the whole message serialized possibly signed, -// // and binary encrypted, so as to obfuscate all its content. -// // -// if(!createDistantMessage(to,info.rsgxsid_srcId,msg)) -// { -// std::cerr << "Cannot encrypt distant message. Something went wrong." << std::endl; -// delete msg ; -// return NULL ; -// } - - return msg ; -} - -RsMsgItem *p3MsgService::initMIRsMsg(const MessageInfo &info, const RsPeerId& to) -{ - RsMsgItem *msg = new RsMsgItem(); - - initMIRsMsg(msg,info) ; - - msg->PeerId(to) ; - - /* load embedded images from own messages */ - msg->msgFlags |= RS_MSG_FLAGS_LOAD_EMBEDDED_IMAGES; - - return msg; -} - -void p3MsgService::connectToGlobalRouter(p3GRouter *gr) -{ - mGRouter = gr ; - gr->registerClientService(GROUTER_CLIENT_ID_MESSAGES,this) ; -} - -void p3MsgService::enableDistantMessaging(bool b) -{ - // We use a temporary variable because the call to OwnIds() might fail. - - mShouldEnableDistantMessaging = b ; - IndicateConfigChanged() ; -} - -bool p3MsgService::distantMessagingEnabled() -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - return mShouldEnableDistantMessaging ; -} - -void p3MsgService::manageDistantPeers() -{ - // now possibly flush pending messages - - if(mShouldEnableDistantMessaging == mDistantMessagingEnabled) - return ; - -#ifdef DEBUG_DISTANT_MSG - std::cerr << "p3MsgService::manageDistantPeers()" << std::endl; -#endif - std::list own_id_list ; - - if(mIdService->getOwnIds(own_id_list)) - { -#ifdef DEBUG_DISTANT_MSG - for(std::list::const_iterator it(own_id_list.begin());it!=own_id_list.end();++it) - std::cerr << (mShouldEnableDistantMessaging?"Enabling":"Disabling") << " distant messaging, with peer id = " << *it << std::endl; -#endif - - for(std::list::const_iterator it(own_id_list.begin());it!=own_id_list.end();++it) - { - if(mShouldEnableDistantMessaging) - mGRouter->registerKey(*it,GROUTER_CLIENT_ID_MESSAGES,"Messaging contact") ; - else - mGRouter->unregisterKey(*it,GROUTER_CLIENT_ID_MESSAGES) ; - } - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - mDistantMessagingEnabled = mShouldEnableDistantMessaging ; - } -} - -void p3MsgService::notifyDataStatus( const GRouterMsgPropagationId& id, - const RsGxsId &signer_id, - uint32_t data_status ) -{ - if(data_status == GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED) - { - RS_STACK_MUTEX(mMsgMtx); - - auto it = _ongoing_messages.find(id); - if(it == _ongoing_messages.end()) - { - RsErr() << __PRETTY_FUNCTION__ - << " cannot find pending message to acknowledge. " - << "Weird. grouter id: " << id << std::endl; - return; - } - - uint32_t msg_id = it->second; - - RsWarn() << __PRETTY_FUNCTION__ << " Global router tells " - << "us that item ID " << id - << " could not be delivered on time. Message id: " - << msg_id << std::endl; - - /* this is needed because it's not saved in config, but we should - * probably include it in _ongoing_messages */ - mDistantOutgoingMsgSigners[msg_id] = signer_id; - - std::map::iterator mit = msgOutgoing.find(msg_id); - if(mit == msgOutgoing.end()) - { - RsInfo() << __PRETTY_FUNCTION__ - << " message has been notified as not delivered, " - << "but it's not in outgoing list. Probably it has been " - << "delivered successfully by other means." << std::endl; - } - else - { - std::cerr << " reseting the ROUTED flag so that the message is " - << "requested again" << std::endl; - - // clear the routed flag so that the message is requested again - mit->second->msgFlags &= ~RS_MSG_FLAGS_ROUTED; - } - - return; - } - - if(data_status == GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED) - { - RS_STACK_MUTEX(mMsgMtx); -#ifdef DEBUG_DISTANT_MSG - std::cerr << "p3MsgService::acknowledgeDataReceived(): acknowledging data received for msg propagation id " << id << std::endl; -#endif - auto it = _ongoing_messages.find(id); - if(it == _ongoing_messages.end()) - { - std::cerr << " (EE) cannot find pending message to acknowledge. " - << "Weird. grouter id = " << id << std::endl; - return; - } - - uint32_t msg_id = it->second; - - // we should now remove the item from the msgOutgoing list. - std::map::iterator it2 = msgOutgoing.find(msg_id); - if(it2 == msgOutgoing.end()) - { - std::cerr << "(II) message has been notified as delivered, but it's" - << " not in outgoing list. Probably it has been delivered" - << " successfully by other means." << std::endl; - return; - } - -#if 0 - delete it2->second; - msgOutgoing.erase(it2); -#else - // Do not delete it move to sent folder instead! - it2->second->msgFlags &= ~RS_MSG_FLAGS_PENDING; - imsg[msg_id] = it2->second; - msgOutgoing.erase(it2); -#endif - - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); - IndicateConfigChanged(); - - if(rsEvents) - { - auto pEvent = std::make_shared(); - pEvent->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; - pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); - rsEvents->postEvent(pEvent); - } - - return; - } - - RsErr() << __PRETTY_FUNCTION__ - << " unhandled data status info from global router" - << " for msg ID " << id << ": this is a bug." << std::endl; -} - -bool p3MsgService::acceptDataFromPeer(const RsGxsId& to_gxs_id) -{ - if(mDistantMessagePermissions & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS) - return (rsIdentity!=NULL) && rsIdentity->isARegularContact(to_gxs_id) ; - - if(mDistantMessagePermissions & RS_DISTANT_MESSAGING_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY) - return false ; - - return true ; -} - -void p3MsgService::setDistantMessagingPermissionFlags(uint32_t flags) -{ - if(flags != mDistantMessagePermissions) - { - mDistantMessagePermissions = flags ; - - IndicateConfigChanged() ; - } -} - -uint32_t p3MsgService::getDistantMessagingPermissionFlags() -{ - return mDistantMessagePermissions ; -} - -bool p3MsgService::receiveGxsTransMail( const RsGxsId& authorId, - const RsGxsId& recipientId, - const uint8_t* data, uint32_t dataSize ) -{ - Dbg2() << __PRETTY_FUNCTION__ << " " << authorId << ", " << recipientId - << ",, " << dataSize << std::endl; - - Sha1CheckSum hash = RsDirUtil::sha1sum(data, dataSize); - - { - RS_STACK_MUTEX(recentlyReceivedMutex); - if( mRecentlyReceivedMessageHashes.find(hash) != mRecentlyReceivedMessageHashes.end() ) - { - RsInfo() << __PRETTY_FUNCTION__ << " (II) receiving " - << "message of hash " << hash << " more than once. " - << "Probably it has arrived before by other means." - << std::endl; - return true; - } - mRecentlyReceivedMessageHashes[hash] = static_cast(time(nullptr)); - } - - IndicateConfigChanged(); - - RsItem *item = _serialiser->deserialise( const_cast(data), &dataSize ); - RsMsgItem *msg_item = dynamic_cast(item); - - if(msg_item) - { - Dbg3() << __PRETTY_FUNCTION__ << " Encrypted item correctly " - << "deserialised. Passing on to incoming list." - << std::endl; - - msg_item->msgFlags |= RS_MSG_FLAGS_DISTANT; - /* we expect complete msgs - remove partial flag just in case - * someone has funny ideas */ - msg_item->msgFlags &= ~RS_MSG_FLAGS_PARTIAL; - - // hack to pass on GXS id. - msg_item->PeerId(RsPeerId(authorId)); - handleIncomingItem(msg_item); - } - else - { - RsWarn() << __PRETTY_FUNCTION__ << " Item could not be " - << "deserialised. Format error?" << std::endl; - return false; - } - - return true; -} - -bool p3MsgService::notifyGxsTransSendStatus( RsGxsTransId mailId, - GxsTransSendStatus status ) -{ - Dbg2() << __PRETTY_FUNCTION__ << " " << mailId << ", " - << static_cast(status) << std::endl; - - auto pEvent = std::make_shared(); - - if( status == GxsTransSendStatus::RECEIPT_RECEIVED ) - { - pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_RECEIVED_ACK; - uint32_t msg_id; - - { - RS_STACK_MUTEX(gxsOngoingMutex); - - auto it = gxsOngoingMessages.find(mailId); - if(it == gxsOngoingMessages.end()) - { - RsErr() << __PRETTY_FUNCTION__<< " " << mailId << ", " - << static_cast(status) - << " cannot find pending message to acknowledge!" - << std::endl; - return false; - } - - msg_id = it->second; - } - - // we should now remove the item from the msgOutgoing list. - - { - RS_STACK_MUTEX(mMsgMtx); - - auto it2 = msgOutgoing.find(msg_id); - if(it2 == msgOutgoing.end()) - { - RsInfo() << __PRETTY_FUNCTION__ << " " << mailId - << ", " << static_cast(status) - << " received receipt for message that is not in " - << "outgoing list, probably it has been acknoweldged " - << "before by other means." << std::endl; - } - else - { -#if 0 - delete it2->second; - msgOutgoing.erase(it2); -#else - // Do not delete it move to sent folder instead! - it2->second->msgFlags &= ~RS_MSG_FLAGS_PENDING; - imsg[msg_id] = it2->second; - msgOutgoing.erase(it2); -#endif - pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); - } - } - - RsServer::notify()->notifyListChange( NOTIFY_LIST_MESSAGELIST, - NOTIFY_TYPE_ADD ); - IndicateConfigChanged(); - } - else if( status >= GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE ) - { - uint32_t msg_id; - pEvent->mMailStatusEventCode = RsMailStatusEventCode::SIGNATURE_FAILED; - - { - RS_STACK_MUTEX(gxsOngoingMutex); - RsErr() << __PRETTY_FUNCTION__ << " mail delivery " - << "mailId: " << mailId - << " failed with " << static_cast(status); - - auto it = gxsOngoingMessages.find(mailId); - if(it == gxsOngoingMessages.end()) - { - RsErr() << __PRETTY_FUNCTION__ - << " cannot find pending message to notify" - << std::endl; - return false; - } - - msg_id = it->second; - } - - std::cerr << " message id = " << msg_id << std::endl; - - { - RS_STACK_MUTEX(mMsgMtx); - auto mit = msgOutgoing.find(msg_id); - if( mit == msgOutgoing.end() ) - { - std::cerr << " message has been notified as not delivered, " - << "but it not on outgoing list." - << std::endl; - } - else - { - std::cerr << " reseting the ROUTED flag so that the message is " - << "requested again" << std::endl; - // clear the routed flag so that the message is requested again - mit->second->msgFlags &= ~RS_MSG_FLAGS_ROUTED; - - pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); - } - } - } - - if(rsEvents && !pEvent->mChangedMsgIds.empty()) - rsEvents->postEvent(pEvent); - - return true; -} - -void p3MsgService::receiveGRouterData( const RsGxsId &destination_key, - const RsGxsId &signing_key, - GRouterServiceId &/*client_id*/, - uint8_t *data, uint32_t data_size ) -{ - std::cerr << "p3MsgService::receiveGRouterData(): received message item of" - << " size " << data_size << ", for key " << destination_key - << std::endl; - - /* first make sure that we havn't already received the data. Since we allow - * to re-send messages, it's necessary to check. */ - - Sha1CheckSum hash = RsDirUtil::sha1sum(data, data_size); - - { - RS_STACK_MUTEX(recentlyReceivedMutex); - if( mRecentlyReceivedMessageHashes.find(hash) != - mRecentlyReceivedMessageHashes.end() ) - { - std::cerr << "p3MsgService::receiveGRouterData(...) (II) receiving" - << "distant message of hash " << hash << " more than once" - << ". Probably it has arrived before by other means." - << std::endl; - free(data); - return; - } - mRecentlyReceivedMessageHashes[hash] = time(NULL); - } - - IndicateConfigChanged() ; - - RsItem *item = _serialiser->deserialise(data,&data_size) ; - free(data) ; - - RsMsgItem *msg_item = dynamic_cast(item) ; - - if(msg_item != NULL) - { - std::cerr << " Encrypted item correctly deserialised. Passing on to incoming list." << std::endl; - - msg_item->msgFlags |= RS_MSG_FLAGS_DISTANT ; - /* we expect complete msgs - remove partial flag just in case someone has funny ideas */ - msg_item->msgFlags &= ~RS_MSG_FLAGS_PARTIAL; - - msg_item->PeerId(RsPeerId(signing_key)) ; // hack to pass on GXS id. - handleIncomingItem(msg_item) ; - } - else - std::cerr << " Item could not be deserialised. Format error??" << std::endl; -} - -void p3MsgService::sendDistantMsgItem(RsMsgItem *msgitem) -{ - RsGxsId destination_key_id(msgitem->PeerId()); - RsGxsId signing_key_id; - - /* just in case, but normally we should always have this flag set, when - * ending up here. */ - msgitem->msgFlags |= RS_MSG_FLAGS_DISTANT; - - { - RS_STACK_MUTEX(mMsgMtx); - - std::map::const_iterator it = - mDistantOutgoingMsgSigners.find(msgitem->msgId); - - if(it == mDistantOutgoingMsgSigners.end()) - { - std::cerr << "(EE) no signer registered for distant message " - << msgitem->msgId << ". Cannot send!" << std::endl; - return; - } - - signing_key_id = it->second; - - if(signing_key_id.isNull()) - { - std::cerr << "ERROR: cannot find signing key id for msg id " - << msgitem->msgId << " available keys are:" << std::endl; - typedef std::map::const_iterator itT; - for( itT it = mDistantOutgoingMsgSigners.begin(); - it != mDistantOutgoingMsgSigners.end(); ++it ) - std::cerr << "\t" << it->first << " " << it->second - << std::endl; - return; - } - } -#ifdef DEBUG_DISTANT_MSG - std::cerr << "p3MsgService::sendDistanteMsgItem(): sending distant msg item" - << " msg ID: " << msgitem->msgId << " to peer:" - << destination_key_id << " signing: " << signing_key_id - << std::endl; -#endif - - /* The item is serialized and turned into a generic turtle item. Use use the - * explicit serialiser to make sure that the msgId is not included */ - - uint32_t msg_serialized_rssize = RsMsgSerialiser().size(msgitem); - RsTemporaryMemory msg_serialized_data(msg_serialized_rssize) ; - - if( !RsMsgSerialiser(). - serialise(msgitem,msg_serialized_data,&msg_serialized_rssize) ) - { - std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl; - return ; - } -#ifdef DEBUG_DISTANT_MSG - std::cerr << " serialised size : " << msg_serialized_rssize << std::endl; -#endif - - GRouterMsgPropagationId grouter_message_id; - mGRouter->sendData( destination_key_id, GROUTER_CLIENT_ID_MESSAGES, - msg_serialized_data, msg_serialized_rssize, - signing_key_id, grouter_message_id ); - RsGxsTransId gxsMailId; - mGxsTransServ.sendData( gxsMailId, GxsTransSubServices::P3_MSG_SERVICE, - signing_key_id, destination_key_id, - msg_serialized_data, msg_serialized_rssize ); - - /* now store the grouter id along with the message id, so that we can keep - * track of received messages */ - - { - RS_STACK_MUTEX(mMsgMtx); - _ongoing_messages[grouter_message_id] = msgitem->msgId; - } - - { - RS_STACK_MUTEX(gxsOngoingMutex); - gxsOngoingMessages[gxsMailId] = msgitem->msgId; - } - - IndicateConfigChanged(); // save _ongoing_messages -} - - - - diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h deleted file mode 100644 index 30ad1e135..000000000 --- a/libretroshare/src/services/p3msgservice.h +++ /dev/null @@ -1,248 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3msgservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef MESSAGE_SERVICE_HEADER -#define MESSAGE_SERVICE_HEADER - -#include -#include -#include - -#include "retroshare/rsmsgs.h" - -#include "pqi/pqi.h" -#include "pqi/pqiindic.h" - -#include "pqi/pqiservicemonitor.h" -#include "pqi/p3cfgmgr.h" - -#include "services/p3service.h" -#include "rsitems/rsmsgitems.h" -#include "util/rsthreads.h" -#include "util/rsdebug.h" -#include "retroshare/rsgxsifacetypes.h" - -#include "grouter/p3grouter.h" -#include "grouter/grouterclientservice.h" -#include "turtle/p3turtle.h" -#include "turtle/turtleclientservice.h" -#include "gxstrans/p3gxstrans.h" - -class p3LinkMgr; -class p3IdService; - -// Temp tweak to test grouter -class p3MsgService : - public p3Service, public p3Config, public pqiServiceMonitor, GRouterClientService, - GxsTransClient -{ -public: - p3MsgService(p3ServiceControl *sc, p3IdService *id_service, p3GxsTrans& gxsMS); - virtual ~p3MsgService(); - - virtual RsServiceInfo getServiceInfo(); - - /// @see RsMsgs::sendMail - uint32_t sendMail(const RsGxsId from, - const std::string& subject, - const std::string& body, - const std::set& to = std::set(), - const std::set& cc = std::set(), - const std::set& bcc = std::set(), - const std::vector& attachments = std::vector(), - std::set& trackingIds = - RS_DEFAULT_STORAGE_PARAM(std::set), - std::string& errorMsg = - RS_DEFAULT_STORAGE_PARAM(std::string) ); - - /* External Interface */ - bool getMessageSummaries(std::list &msgList); - bool getMessage(const std::string &mid, Rs::Msgs::MessageInfo &msg); - void getMessageCount(uint32_t &nInbox, uint32_t &nInboxNew, uint32_t &nOutbox, uint32_t &nDraftbox, uint32_t &nSentbox, uint32_t &nTrashbox); - - bool decryptMessage(const std::string& mid) ; - bool removeMsgId(const std::string &mid); - bool markMsgIdRead(const std::string &mid, bool bUnreadByUser); - bool setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mask); - bool getMsgParentId(const std::string &msgId, std::string &msgParentId); - // msgParentId == 0 --> remove - bool setMsgParentId(uint32_t msgId, uint32_t msgParentId); - - RS_DEPRECATED_FOR(sendMail) - bool MessageSend(Rs::Msgs::MessageInfo &info); - bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag); - bool MessageToDraft(Rs::Msgs::MessageInfo &info, const std::string &msgParentId); - bool MessageToTrash(const std::string &mid, bool bTrash); - - bool getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); - bool getMessageTagTypes(Rs::Msgs::MsgTagType& tags); - bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color); - bool removeMessageTagType(uint32_t tagId); - - /* set == false && tagId == 0 --> remove all */ - bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set); - - bool resetMessageStandardTagTypes(Rs::Msgs::MsgTagType& tags); - - void loadWelcomeMsg(); /* startup message */ - - - //std::list &getMsgList(); - //std::list &getMsgOutList(); - - int tick(); - - /*** Overloaded from p3Config ****/ - virtual RsSerialiser *setupSerialiser(); - virtual bool saveList(bool& cleanup, std::list&); - virtual bool loadList(std::list& load); - virtual void saveDone(); - /*** Overloaded from p3Config ****/ - - /*** Overloaded from pqiMonitor ***/ - virtual void statusChange(const std::list &plist); - - /// iterate through the outgoing queue if online, send - int checkOutgoingMessages(); - /*** Overloaded from pqiMonitor ***/ - - /*** overloaded from p3turtle ***/ - - virtual void connectToGlobalRouter(p3GRouter *) ; - - struct DistantMessengingInvite - { - rstime_t time_of_validity ; - }; - struct DistantMessengingContact - { - rstime_t last_hit_time ; - RsPeerId virtual_peer_id ; - uint32_t status ; - bool pending_messages ; - }; - void enableDistantMessaging(bool b) ; - bool distantMessagingEnabled() ; - - void setDistantMessagingPermissionFlags(uint32_t flags) ; - uint32_t getDistantMessagingPermissionFlags() ; - - /// @see GxsTransClient::receiveGxsTransMail(...) - virtual bool receiveGxsTransMail( const RsGxsId& authorId, - const RsGxsId& recipientId, - const uint8_t* data, uint32_t dataSize ); - - /// @see GxsTransClient::notifyGxsTransSendStatus(...) - virtual bool notifyGxsTransSendStatus( RsGxsTransId mailId, - GxsTransSendStatus status ); - -private: - void sendDistantMsgItem(RsMsgItem *msgitem); - bool locked_getMessageTag(const std::string &msgId, Rs::Msgs::MsgTagInfo& info); - - /** This contains the ongoing tunnel handling contacts. - * The map is indexed by the hash */ - std::map _ongoing_messages; - - /// Contains ongoing messages handed to gxs mail - std::map gxsOngoingMessages; - RsMutex gxsOngoingMutex; - - // Overloaded from GRouterClientService - virtual bool acceptDataFromPeer(const RsGxsId& gxs_id) ; - virtual void receiveGRouterData(const RsGxsId& destination_key,const RsGxsId& signing_key, GRouterServiceId &client_id, uint8_t *data, uint32_t data_size) ; - virtual void notifyDataStatus(const GRouterMsgPropagationId& msg_id,const RsGxsId& signer_id,uint32_t data_status) ; - - // Utility functions - - bool createDistantMessage(const RsGxsId& destination_gxs_id,const RsGxsId& source_gxs_id,RsMsgItem *msg) ; - bool locked_findHashForVirtualPeerId(const RsPeerId& pid,Sha1CheckSum& hash) ; - void sendGRouterData(const RsGxsId &key_id,RsMsgItem *) ; - - void manageDistantPeers() ; - - void handleIncomingItem(RsMsgItem *) ; - - uint32_t getNewUniqueMsgId(); - uint32_t sendMessage(RsMsgItem *item); - uint32_t sendDistantMessage(RsMsgItem *item,const RsGxsId& signing_gxs_id); - void checkSizeAndSendMessage(RsMsgItem *msg); - void cleanListOfReceivedMessageHashes(); - - int incomingMsgs(); - void processIncomingMsg(RsMsgItem *mi) ; - bool checkAndRebuildPartialMessage(RsMsgItem*) ; - - void initRsMI(RsMsgItem *msg, Rs::Msgs::MessageInfo &mi); - void initRsMIS(RsMsgItem *msg, Rs::Msgs::MsgInfoSummary &mis); - - RsMsgItem *initMIRsMsg(const Rs::Msgs::MessageInfo &info, const RsPeerId& to); - RsMsgItem *initMIRsMsg(const Rs::Msgs::MessageInfo &info, const RsGxsId& to); - void initMIRsMsg(RsMsgItem *item,const Rs::Msgs::MessageInfo &info) ; - - void initStandardTagTypes(); - - p3IdService *mIdService ; - p3ServiceControl *mServiceCtrl; - p3GRouter *mGRouter ; - - /* Mutex Required for stuff below */ - - RsMutex mMsgMtx; - RsMsgSerialiser *_serialiser ; - - /* stored list of messages */ - std::map imsg; - /* ones that haven't made it out yet! */ - std::map msgOutgoing; - - std::map _pendingPartialMessages ; - - /* maps for tags types and msg tags */ - - std::map mTags; - std::map mMsgTags; - - uint32_t mMsgUniqueId; - std::map mRecentlyReceivedMessageHashes; - RsMutex recentlyReceivedMutex; - - // used delete msgSrcIds after config save - std::map mSrcIds; - - // temporary storage. Will not be needed when messages have a proper "from" field. Not saved! - std::map mDistantOutgoingMsgSigners; - - // save the parent of the messages in draft for replied and forwarded - std::map mParentId; - - std::string config_dir; - - bool mDistantMessagingEnabled ; - uint32_t mDistantMessagePermissions ; - bool mShouldEnableDistantMessaging ; - - p3GxsTrans& mGxsTransServ; - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; - -#endif // MESSAGE_SERVICE_HEADER diff --git a/libretroshare/src/services/p3photoservice.cc b/libretroshare/src/services/p3photoservice.cc deleted file mode 100644 index 24e9d90b6..000000000 --- a/libretroshare/src/services/p3photoservice.cc +++ /dev/null @@ -1,351 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3photoservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2012 Robert Fernie,Chris Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "p3photoservice.h" -#include "rsitems/rsphotoitems.h" -#include "retroshare/rsgxsflags.h" - -RsPhoto *rsPhoto = NULL; - -RsPhotoPhoto::RsPhotoPhoto() - :mOrder(0) -{ - return; -} - -RsPhotoAlbum::RsPhotoAlbum() - :mShareMode(RSPHOTO_SHAREMODE_LOWRESONLY), mAutoDownload(false) -{ - return; -} - -std::ostream &operator<<(std::ostream &out, const RsPhotoPhoto &photo) -{ - out << "RsPhotoPhoto [ "; - out << "Title: " << photo.mMeta.mMsgName; - out << "]"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsPhotoAlbum &album) -{ - out << "RsPhotoAlbum [ "; - out << "Title: " << album.mMeta.mGroupName; - out << "]"; - return out; -} - -p3PhotoService::p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs) - : RsGenExchange(gds, nes, new RsGxsPhotoSerialiser(), RS_SERVICE_GXS_TYPE_PHOTO, gixs, photoAuthenPolicy()), - RsPhoto(static_cast(*this)), - mPhotoMutex(std::string("Photo Mutex")) -{ - mCommentService = new p3GxsCommentService(this, RS_SERVICE_GXS_TYPE_PHOTO); -} - -const std::string GXS_PHOTO_APP_NAME = "gxsphoto"; -const uint16_t GXS_PHOTO_APP_MAJOR_VERSION = 1; -const uint16_t GXS_PHOTO_APP_MINOR_VERSION = 0; -const uint16_t GXS_PHOTO_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_PHOTO_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3PhotoService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_PHOTO, - GXS_PHOTO_APP_NAME, - GXS_PHOTO_APP_MAJOR_VERSION, - GXS_PHOTO_APP_MINOR_VERSION, - GXS_PHOTO_MIN_MAJOR_VERSION, - GXS_PHOTO_MIN_MINOR_VERSION); -} - -uint32_t p3PhotoService::photoAuthenPolicy() -{ - uint32_t policy = 0; - uint8_t flag = 0; - - flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -bool p3PhotoService::updated() -{ - RsStackMutex stack(mPhotoMutex); - - bool changed = (!mGroupChange.empty() || !mMsgChange.empty()); - - return changed; -} - -void p3PhotoService::service_tick() -{ - mCommentService->comment_tick(); -} - - -void p3PhotoService::groupsChanged(std::list& grpIds) -{ - RsStackMutex stack(mPhotoMutex); - - while(!mGroupChange.empty()) - { - RsGxsGroupChange* gc = mGroupChange.back(); - grpIds.push_back(gc->mGroupId); - - mGroupChange.pop_back(); - delete gc; - } -} - - -void p3PhotoService::msgsChanged(GxsMsgIdResult& msgs) -{ - RsStackMutex stack(mPhotoMutex); - - while(!mMsgChange.empty()) - { - RsGxsMsgChange* mc = mMsgChange.back(); - - msgs[mc->mGroupId].insert(mc->mMsgId); - mMsgChange.pop_back(); - delete mc; - } -} - - -RsTokenService* p3PhotoService::getTokenService() { - - return RsGenExchange::getTokenService(); -} - - -bool p3PhotoService::getGroupList(const uint32_t& token, - std::list& groupIds) -{ - bool okay = RsGenExchange::getGroupList(token, groupIds); - return okay; -} - - -bool p3PhotoService::getMsgList(const uint32_t& token, - GxsMsgIdResult& msgIds) -{ - - return RsGenExchange::getMsgList(token, msgIds); -} - - -bool p3PhotoService::getGroupSummary(const uint32_t& token, - std::list& groupInfo) -{ - bool okay = RsGenExchange::getGroupMeta(token, groupInfo); - return okay; -} - - -bool p3PhotoService::getMsgSummary(const uint32_t& token, - MsgMetaResult& msgInfo) -{ - return RsGenExchange::getMsgMeta(token, msgInfo); -} - - -bool p3PhotoService::getAlbum(const uint32_t& token, std::vector& albums) -{ - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsPhotoAlbumItem* item = dynamic_cast(*vit); - if (item) - { - RsPhotoAlbum album = item->album; - item->album.mMeta = item->meta; - album.mMeta = item->album.mMeta; - delete item; - albums.push_back(album); - } - else - { - std::cerr << "Not a RsGxsPhotoAlbumItem, deleting!" << std::endl; - delete *vit; - } - } - } - - return ok; -} - -bool p3PhotoService::getPhoto(const uint32_t& token, PhotoResult& photos) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsPhotoPhotoItem* item = dynamic_cast(*vit); - - if(item) - { - RsPhotoPhoto photo = item->photo; - photo.mMeta = item->meta; - photos[grpId].push_back(photo); - delete item; - }else - { - std::cerr << "Not a photo Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - -bool p3PhotoService::submitAlbumDetails(uint32_t& token, RsPhotoAlbum& album) -{ - RsGxsPhotoAlbumItem* albumItem = new RsGxsPhotoAlbumItem(); - albumItem->album = album; - albumItem->meta = album.mMeta; - RsGenExchange::publishGroup(token, albumItem); - return true; -} - -void p3PhotoService::notifyChanges(std::vector& changes) -{ - - RsStackMutex stack(mPhotoMutex); - - std::vector::iterator vit = changes.begin(); - - for(; vit != changes.end(); ++vit) - { - RsGxsNotify* n = *vit; - RsGxsGroupChange* gc; - RsGxsMsgChange* mc; - if((mc = dynamic_cast(n)) != NULL) - { - mMsgChange.push_back(mc); - } - else if((gc = dynamic_cast(n)) != NULL) - { - mGroupChange.push_back(gc); - } - else - { - delete n; - } - } -} - -bool p3PhotoService::submitPhoto(uint32_t& token, RsPhotoPhoto& photo) -{ - RsGxsPhotoPhotoItem* photoItem = new RsGxsPhotoPhotoItem(); - photoItem->photo = photo; - photoItem->meta = photo.mMeta; - - RsGenExchange::publishMsg(token, photoItem); - return true; -} - -bool p3PhotoService::acknowledgeMsg(const uint32_t& token, - std::pair& msgId) -{ - return RsGenExchange::acknowledgeTokenMsg(token, msgId); -} - - -bool p3PhotoService::acknowledgeGrp(const uint32_t& token, - RsGxsGroupId& grpId) -{ - return RsGenExchange::acknowledgeTokenGrp(token, grpId); -} - -bool p3PhotoService::subscribeToAlbum(uint32_t &token, const RsGxsGroupId &grpId, bool subscribe) -{ - if(subscribe) - RsGenExchange::setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED, GXS_SERV::GROUP_SUBSCRIBE_MASK); - else - RsGenExchange::setGroupSubscribeFlags(token, grpId, 0, GXS_SERV::GROUP_SUBSCRIBE_MASK); - - return true; -} - -// Blocking versions ============================================================= - -bool p3PhotoService::createAlbum(RsPhotoAlbum &album) -{ - uint32_t token; - return submitAlbumDetails(token, album) && waitToken(token) == RsTokenService::COMPLETE; -} - -bool p3PhotoService::updateAlbum(const RsPhotoAlbum &/*album*/) -{ - // TODO - return false; -} - -bool p3PhotoService::getAlbums(const std::list &groupIds, - std::vector &albums) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if (groupIds.empty()) - { - if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - else - { - if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - - return getAlbum(token, albums) && !albums.empty(); -} - diff --git a/libretroshare/src/services/p3photoservice.h b/libretroshare/src/services/p3photoservice.h deleted file mode 100644 index f540d4f66..000000000 --- a/libretroshare/src/services/p3photoservice.h +++ /dev/null @@ -1,214 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3photoservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2012 Robert Fernie,Chris Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3PHOTOSERVICEV2_H -#define P3PHOTOSERVICEV2_H - -#include "gxs/rsgenexchange.h" -#include "retroshare/rsphoto.h" -#include "services/p3gxscommon.h" - -class p3PhotoService : public RsGenExchange, public RsPhoto -{ -public: - - p3PhotoService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs); - virtual RsServiceInfo getServiceInfo() override; - - static uint32_t photoAuthenPolicy(); - -public: - - /*! - * @return true if a change has occured - */ - bool updated() override; - - /*! - * - */ - void service_tick() override; - -protected: - - void notifyChanges(std::vector& changes) override; -public: - - /** Requests **/ - - void groupsChanged(std::list& grpIds) override; - - - void msgsChanged(GxsMsgIdResult& msgs) override; - - RsTokenService* getTokenService() override; - - bool getGroupList(const uint32_t &token, std::list &groupIds) override; - bool getMsgList(const uint32_t &token, GxsMsgIdResult& msgIds) override; - - /* Generic Summary */ - bool getGroupSummary(const uint32_t &token, std::list &groupInfo) override; - - bool getMsgSummary(const uint32_t &token, MsgMetaResult &msgInfo) override; - - /* Specific Service Data */ - bool getAlbum(const uint32_t &token, std::vector &albums) override; - bool getPhoto(const uint32_t &token, PhotoResult &photos) override; - -public: - /* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */ - virtual bool getCommentData(uint32_t token, std::vector &msgs) override - { - return mCommentService->getGxsCommentData(token, msgs); - } - - virtual bool getRelatedComments( uint32_t token, std::vector &msgs ) override - { - return mCommentService->getGxsRelatedComments(token, msgs); - } - - virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override - { - return mCommentService->createGxsComment(token, msg); - } - - virtual bool createNewVote(uint32_t &token, RsGxsVote &msg) override - { - return mCommentService->createGxsVote(token, msg); - } - - virtual bool acknowledgeComment(uint32_t token, std::pair& msgId) override - { - return acknowledgeMsg(token, msgId); - } - - virtual bool acknowledgeVote(uint32_t token, std::pair& msgId) override - { - if (mCommentService->acknowledgeVote(token, msgId)) - { - return true; - } - return acknowledgeMsg(token, msgId); - } - - //Not currently used - virtual bool setCommentAsRead(uint32_t& /*token*/,const RsGxsGroupId& /*gid*/,const RsGxsMessageId& /*comment_msg_id*/) override - { - return true; - } - - - // Blocking versions. - virtual bool createComment(RsGxsComment &msg) override - { - uint32_t token; - return mCommentService->createGxsComment(token, msg) && waitToken(token) == RsTokenService::COMPLETE; - } - -public: - - /** Modifications **/ - - /*! - * submits album, which returns a token that needs - * to be acknowledge to get album grp id - * @param token token to redeem for acknowledgement - * @param album album to be submitted - */ - bool submitAlbumDetails(uint32_t& token, RsPhotoAlbum &album) override; - - /*! - * submits photo, which returns a token that needs - * to be acknowledge to get photo msg-grp id pair - * @param token token to redeem for acknowledgement - * @param photo photo to be submitted - */ - bool submitPhoto(uint32_t& token, RsPhotoPhoto &photo) override; - - /*! - * submits photo comment, which returns a token that needs - * to be acknowledged to get photo msg-grp id pair - * The mParentId needs to be set to an existing msg for which - * commenting is enabled - * @param token token to redeem for acknowledgement - * @param comment comment to be submitted - */ - // bool submitComment(uint32_t& token, RsPhotoComment &photo); - - /*! - * subscribes to group, and returns token which can be used - * to be acknowledged to get group Id - * @param token token to redeem for acknowledgement - * @param grpId the id of the group to subscribe to - */ - bool subscribeToAlbum(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) override; - - /*! - * This allows the client service to acknowledge that their msgs has - * been created/modified and retrieve the create/modified msg ids - * @param token the token related to modification/create request - * @param msgIds map of grpid->msgIds of message created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeMsg(const uint32_t& token, std::pair& msgId) override; - - /*! - * This allows the client service to acknowledge that their grps has - * been created/modified and retrieve the create/modified grp ids - * @param token the token related to modification/create request - * @param msgIds vector of ids of groups created/modified - * @return true if token exists false otherwise - */ - bool acknowledgeGrp(const uint32_t& token, RsGxsGroupId& grpId) override; - - // Blocking versions. - /*! - * request to create a new album. Blocks until process completes. - * @param album album to be submitted - * @return true if created false otherwise - */ - virtual bool createAlbum(RsPhotoAlbum &album) override; - - /*! - * request to update an existing album. Blocks until process completes. - * @param album album to be submitted - * @return true if created false otherwise - */ - virtual bool updateAlbum(const RsPhotoAlbum &album) override; - - /*! - * retrieve albums based in groupIds. - * @param groupIds the ids to fetch. - * @param albums vector to be filled by request. - * @return true is successful, false otherwise. - */ - virtual bool getAlbums(const std::list &groupIds, - std::vector &albums) override; -private: - p3GxsCommentService* mCommentService; - - std::vector mGroupChange; - std::vector mMsgChange; - - RsMutex mPhotoMutex; -}; - -#endif // P3PHOTOSERVICEV2_H diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc deleted file mode 100644 index 6792255a4..000000000 --- a/libretroshare/src/services/p3postbase.cc +++ /dev/null @@ -1,1028 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3postbase.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2012 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include - -#include "retroshare/rsgxsflags.h" -#include -#include - -#include "services/p3postbase.h" -#include "rsitems/rsgxscommentitems.h" - -#include "rsserver/p3face.h" -#include "retroshare/rsposted.h" - -// For Dummy Msgs. -#include "util/rsrandom.h" -#include "util/rsstring.h" - -/**** - * #define POSTBASE_DEBUG 1 - ****/ - -#define POSTBASE_BACKGROUND_PROCESSING 0x0002 -#define PROCESSING_START_PERIOD 30 -#define PROCESSING_INC_PERIOD 15 - -#define POSTBASE_ALL_GROUPS 0x0011 -#define POSTBASE_UNPROCESSED_MSGS 0x0012 -#define POSTBASE_ALL_MSGS 0x0013 -#define POSTBASE_BG_POST_META 0x0014 - -#define POSTED_UNUSED_BY_FRIENDS_DELAY (2*30*86400) // delete unused posted groups after 2 months - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3PostBase::p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs, - RsSerialType* serviceSerialiser, uint16_t serviceType) - : RsGenExchange(gds, nes, serviceSerialiser, serviceType, gixs, postBaseAuthenPolicy()), GxsTokenQueue(this), RsTickEvent(), - mPostBaseMtx("PostBaseMutex"), - mKnownPostedMutex("PostBaseKnownPostedMutex") -{ - mBgProcessing = false; - - mCommentService = new p3GxsCommentService(this, serviceType); - RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_START_PERIOD); -} - - -uint32_t p3PostBase::postBaseAuthenPolicy() -{ - uint32_t policy = 0; - uint32_t flag = 0; - - flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -void p3PostBase::notifyChanges(std::vector &changes) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges()"; - std::cerr << std::endl; -#endif - - for(auto it = changes.begin(); it != changes.end(); ++it) - { - RsGxsMsgChange *msgChange = dynamic_cast(*it); - - if(msgChange) - { - // To start with we are just going to trigger updates on these groups. - // FUTURE OPTIMISATION. - // It could be taken a step further and directly request these msgs for an update. - addGroupForProcessing(msgChange->mGroupId); - - if (rsEvents) - { - switch(msgChange->getType()) - { - case RsGxsNotify::TYPE_RECEIVED_NEW: - case RsGxsNotify::TYPE_PUBLISHED: - { - auto ev = std::make_shared(); - ev->mPostedMsgId = msgChange->mMsgId; - ev->mPostedThreadId = msgChange->mNewMsgItem->meta.mThreadId; - ev->mPostedGroupId = msgChange->mGroupId; - - if(nullptr != dynamic_cast(msgChange->mNewMsgItem)) - ev->mPostedEventCode = RsPostedEventCode::NEW_COMMENT; - else - if(nullptr != dynamic_cast(msgChange->mNewMsgItem)) - ev->mPostedEventCode = RsPostedEventCode::NEW_VOTE; - else - ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE; - - rsEvents->postEvent(ev); -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: NEW/PUBLISHED ID=" << msgChange->mMsgId << " in group " << msgChange->mGroupId << ", thread ID = " << msgChange->mNewMsgItem->meta.mThreadId << std::endl; -#endif - - } - break; - - - case RsGxsNotify::TYPE_PROCESSED: - { - auto ev = std::make_shared(); - ev->mPostedMsgId = msgChange->mMsgId; - ev->mPostedGroupId = msgChange->mGroupId; - ev->mPostedEventCode = RsPostedEventCode::MESSAGE_VOTES_UPDATED; - rsEvents->postEvent(ev); -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: PROCESSED ID=" << msgChange->mMsgId << " in group " << msgChange->mGroupId << std::endl; -#endif - } - break; - default: -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification: type " << msgChange->getType() << " (ignored) " << msgChange->mMsgId << std::endl; -#endif - break; - } - } - } - - RsGxsGroupChange *grpChange = dynamic_cast(*it); - - /* pass on Group Changes to GUI */ - if (grpChange && rsEvents) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification"; - std::cerr << std::endl; -#endif - const RsGxsGroupId& group_id(grpChange->mGroupId); - - switch(grpChange->getType()) - { - case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed - { - auto ev = std::make_shared(); - ev->mPostedGroupId = group_id; - ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_GROUP_SYNC_PARAMETERS_UPDATED: - { - auto ev = std::make_shared(); - ev->mPostedGroupId = group_id; - ev->mPostedEventCode = RsPostedEventCode::SYNC_PARAMETERS_UPDATED; - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_GROUP_DELETED: - { - auto ev = std::make_shared(); - ev->mPostedGroupId = group_id; - ev->mPostedEventCode = RsPostedEventCode::BOARD_DELETED; - - rsEvents->postEvent(ev); - } - break; - - case RsGxsNotify::TYPE_STATISTICS_CHANGED: - { - auto ev = std::make_shared(); - ev->mPostedGroupId = group_id; - ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED; - rsEvents->postEvent(ev); - - RS_STACK_MUTEX(mKnownPostedMutex); - mKnownPosted[group_id] = time(nullptr); - IndicateConfigChanged(); - } - break; - - case RsGxsNotify::TYPE_UPDATED: - { - // Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients - - auto ev = std::make_shared(); - ev->mPostedGroupId = grpChange->mGroupId; - ev->mPostedEventCode = RsPostedEventCode::UPDATED_POSTED_GROUP; - rsEvents->postEvent(ev); - } - break; - - - case RsGxsNotify::TYPE_PUBLISHED: - case RsGxsNotify::TYPE_RECEIVED_NEW: - { - /* group received */ - - bool unknown; - { - RS_STACK_MUTEX(mKnownPostedMutex); - - unknown = (mKnownPosted.find(grpChange->mGroupId) == mKnownPosted.end()); - mKnownPosted[group_id] = time(nullptr); - IndicateConfigChanged(); - } - if(unknown) - { - auto ev = std::make_shared(); - ev->mPostedGroupId = group_id; - ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP; - rsEvents->postEvent(ev); - -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id; - std::cerr << std::endl; -#endif - } - else - RsInfo() << __PRETTY_FUNCTION__ - << " Not notifying already known forum " - << group_id << std::endl; - } - break; - - default: - RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl; - break; - } - } - - delete *it; - } -} - -void p3PostBase::service_tick() -{ - RsTickEvent::tick_events(); - GxsTokenQueue::checkRequests(); - - mCommentService->comment_tick(); - - return; -} - -/********************************************************************************************/ -/********************************************************************************************/ - -void p3PostBase::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t mask = GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - uint32_t status = GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; - if (read) - { - status = 0; - } - - setMsgStatusFlags(token, msgId, status, mask); - - if (rsEvents) - { - auto ev = std::make_shared(); - - ev->mPostedMsgId = msgId.second; - ev->mPostedGroupId = msgId.first; - ev->mPostedEventCode = RsPostedEventCode::READ_STATUS_CHANGED; - rsEvents->postEvent(ev); - } -} - - - // Overloaded from RsTickEvent for Event callbacks. -void p3PostBase::handle_event(uint32_t event_type, const std::string & /* elabel */) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::handle_event(" << event_type << ")"; - std::cerr << std::endl; -#endif - - // stuff. - switch(event_type) - { - case POSTBASE_BACKGROUND_PROCESSING: - background_tick(); - break; - - default: - /* error */ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::handle_event() Unknown Event Type: " << event_type; - std::cerr << std::endl; -#endif - break; - } -} - - -/********************************************************************************* - * Background Calculations. - * - * Get list of change groups from Notify.... - * this doesn't imclude your own submissions (at this point). - * So they will not be processed until someone else changes something. - * TODO FIX: Must push for that change. - * - * Eventually, we should just be able to get the new messages from Notify, - * and only process them! - */ - -void p3PostBase::background_tick() -{ - -#if 0 - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - if (mBgGroupList.empty()) - { - background_requestAllGroups(); - } - } -#endif - - background_requestUnprocessedGroup(); - - RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_INC_PERIOD); - -} - -bool p3PostBase::background_requestAllGroups() -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_requestAllGroups()"; - std::cerr << std::endl; -#endif - - uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - - uint32_t token = 0; - RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts); - GxsTokenQueue::queueRequest(token, POSTBASE_ALL_GROUPS); - - return true; -} - - -void p3PostBase::background_loadGroups(const uint32_t &token) -{ - /* get messages */ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_loadGroups()"; - std::cerr << std::endl; -#endif - - std::list groupList; - bool ok = RsGenExchange::getGroupList(token, groupList); - - if (!ok) - { - return; - } - - std::list::iterator it; - for(it = groupList.begin(); it != groupList.end(); ++it) - { - addGroupForProcessing(*it); - } -} - - -void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::addGroupForProcessing(" << grpId << ")"; - std::cerr << std::endl; -#endif // POSTBASE_DEBUG - - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - // no point having multiple lookups queued. - mBgGroupList.insert(grpId); - } -} - - -void p3PostBase::background_requestUnprocessedGroup() -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_requestUnprocessedGroup()"; - std::cerr << std::endl; -#endif // POSTBASE_DEBUG - - - RsGxsGroupId grpId; - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - if (mBgProcessing) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_requestUnprocessedGroup() Already Active"; - std::cerr << std::endl; -#endif - return; - } - if (mBgGroupList.empty()) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_requestUnprocessedGroup() No Groups to Process"; - std::cerr << std::endl; -#endif - return; - } - - grpId = *mBgGroupList.begin(); - mBgGroupList.erase(grpId); - mBgProcessing = true; - } - - background_requestGroupMsgs(grpId, true); -} - - - - - -void p3PostBase::background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_requestGroupMsgs() id: " << grpId; - std::cerr << std::endl; -#endif - - uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - if (unprocessedOnly) - { - opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED; - } - - std::list grouplist; - grouplist.push_back(grpId); - - uint32_t token = 0; - - RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, grouplist); - - if (unprocessedOnly) - { - GxsTokenQueue::queueRequest(token, POSTBASE_UNPROCESSED_MSGS); - } - else - { - GxsTokenQueue::queueRequest(token, POSTBASE_ALL_MSGS); - } -} - - - - -void p3PostBase::background_loadUnprocessedMsgs(const uint32_t &token) -{ - background_loadMsgs(token, true); -} - - -void p3PostBase::background_loadAllMsgs(const uint32_t &token) -{ - background_loadMsgs(token, false); -} - - -/* This function is generalised to support any collection of messages, across multiple groups */ - -void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed) -{ - /* get messages */ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_loadMsgs()"; - std::cerr << std::endl; -#endif - - std::map > msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if (!ok) - { - std::cerr << "p3PostBase::background_loadMsgs() Failed to getMsgData()"; - std::cerr << std::endl; - - /* cleanup */ - background_cleanup(); - return; - - } - - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - mBgStatsMap.clear(); - mBgIncremental = unprocessed; - } - - std::map > postMap; - - // generate vector of changes to push to the GUI. - std::vector changes; - - RsGxsGroupId groupId; - std::map >::iterator mit; - std::vector::iterator vit; - for (mit = msgData.begin(); mit != msgData.end(); ++mit) - { - groupId = mit->first; - for (vit = mit->second.begin(); vit != mit->second.end(); ++vit) - { - RsGxsMessageId parentId = (*vit)->meta.mParentId; - RsGxsMessageId threadId = (*vit)->meta.mThreadId; - - - bool inc_counters = false; - uint32_t vote_up_inc = 0; - uint32_t vote_down_inc = 0; - uint32_t comment_inc = 0; - - bool add_voter = false; - RsGxsId voterId; - RsGxsCommentItem *commentItem; - RsGxsVoteItem *voteItem; - - /* THIS Should be handled by UNPROCESSED Filter - but isn't */ - if (!IS_MSG_UNPROCESSED((*vit)->meta.mMsgStatus)) - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - if (mBgIncremental) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_loadMsgs() Msg already Processed - Skipping"; - std::cerr << std::endl; - std::cerr << "p3PostBase::background_loadMsgs() ERROR This should not happen"; - std::cerr << std::endl; -#endif - delete(*vit); - continue; - } - } - - /* 3 types expected: PostedPost, Comment and Vote */ - if (parentId.isNull()) - { -#ifdef POSTBASE_DEBUG - /* we don't care about top-level (Posts) */ - std::cerr << "\tIgnoring TopLevel Item"; - std::cerr << std::endl; -#endif - - /* but we need to notify GUI about them */ - changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, mit->first,(*vit)->meta.mMsgId, false)); - } - else if (NULL != (commentItem = dynamic_cast(*vit))) - { -#ifdef POSTBASE_DEBUG - /* comment - want all */ - /* Comments are counted by Thread Id */ - std::cerr << "\tProcessing Comment: " << commentItem; - std::cerr << std::endl; -#endif - - inc_counters = true; - comment_inc = 1; - } - else if (NULL != (voteItem = dynamic_cast(*vit))) - { - /* vote - only care about direct children */ - if (parentId == threadId) - { - /* Votes are organised by Parent Id, - * ie. you can vote for both Posts and Comments - */ -#ifdef POSTBASE_DEBUG - std::cerr << "\tProcessing Vote: " << voteItem; - std::cerr << std::endl; -#endif - - inc_counters = true; - add_voter = true; - voterId = voteItem->meta.mAuthorId; - - if (voteItem->mMsg.mVoteType == GXS_VOTE_UP) - { - vote_up_inc = 1; - } - else - { - vote_down_inc = 1; - } - } - } - else - { - /* unknown! */ - std::cerr << "p3PostBase::background_processNewMessages() ERROR Strange NEW Message:" << std::endl; - std::cerr << "\t" << (*vit)->meta; - std::cerr << std::endl; - - } - - if (inc_counters) - { - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator sit = mBgStatsMap.find(threadId); - if (sit == mBgStatsMap.end()) - { - // add to map of ones to update. - postMap[groupId].insert(threadId); - - mBgStatsMap[threadId] = PostStats(0,0,0); - sit = mBgStatsMap.find(threadId); - } - - sit->second.comments += comment_inc; - sit->second.up_votes += vote_up_inc; - sit->second.down_votes += vote_down_inc; - - - if (add_voter) - { - sit->second.voters.push_back(voterId); - } - -#ifdef POSTBASE_DEBUG - std::cerr << "\tThreadId: " << threadId; - std::cerr << " Comment Total: " << sit->second.comments; - std::cerr << " UpVote Total: " << sit->second.up_votes; - std::cerr << " DownVote Total: " << sit->second.down_votes; - std::cerr << std::endl; -#endif - } - - /* flag all messages as processed and new for the gui */ - if ((*vit)->meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED) - { - uint32_t token_a; - RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, (*vit)->meta.mMsgId); - RsGenExchange::setMsgStatusFlags(token_a, msgId, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); - } - delete(*vit); - } - } - - /* push updates of new Posts */ - notifyChanges(changes); - - /* request the summary info from the parents */ - uint32_t token_b; - uint32_t anstype = RS_TOKREQ_ANSTYPE_SUMMARY; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_META; - RsGenExchange::getTokenService()->requestMsgInfo(token_b, anstype, opts, postMap); - - GxsTokenQueue::queueRequest(token_b, POSTBASE_BG_POST_META); - return; -} - - -#define RSGXS_MAX_SERVICE_STRING 1024 -bool encodePostCache(std::string &str, const PostStats &s) -{ - char line[RSGXS_MAX_SERVICE_STRING]; - - snprintf(line, RSGXS_MAX_SERVICE_STRING, "%d %d %d", s.comments, s.up_votes, s.down_votes); - - str = line; - return true; -} - -bool extractPostCache(const std::string &str, PostStats &s) -{ - - uint32_t iupvotes, idownvotes, icomments; - if (3 == sscanf(str.c_str(), "%u %u %u", &icomments, &iupvotes, &idownvotes)) - { - s.comments = icomments; - s.up_votes = iupvotes; - s.down_votes = idownvotes; - return true; - } - return false; -} - - -void p3PostBase::background_updateVoteCounts(const uint32_t &token) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_updateVoteCounts()"; - std::cerr << std::endl; -#endif - - GxsMsgMetaMap parentMsgList; - GxsMsgMetaMap::iterator mit; - std::vector::iterator vit; - - bool ok = RsGenExchange::getMsgMeta(token, parentMsgList); - - if (!ok) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_updateVoteCounts() ERROR"; - std::cerr << std::endl; -#endif - background_cleanup(); - return; - } - - // generate vector of changes to push to the GUI. - std::vector changes; - - for(mit = parentMsgList.begin(); mit != parentMsgList.end(); ++mit) - { - for(vit = mit->second.begin(); vit != mit->second.end(); ++vit) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_updateVoteCounts() Processing Msg(" << mit->first; - std::cerr << ", " << vit->mMsgId << ")"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - - /* extract current vote count */ - PostStats stats; - if (mBgIncremental) - { - if (!extractPostCache(vit->mServiceString, stats)) - { - if (!(vit->mServiceString.empty())) - { - std::cerr << "p3PostBase::background_updateVoteCounts() Failed to extract Votes"; - std::cerr << std::endl; - std::cerr << "\tFrom String: " << vit->mServiceString; - std::cerr << std::endl; - } - } - } - - /* get increment */ - std::map::iterator it; - it = mBgStatsMap.find(vit->mMsgId); - - if (it != mBgStatsMap.end()) - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_updateVoteCounts() Adding to msgChangeMap: "; - std::cerr << mit->first << " MsgId: " << vit->mMsgId; - std::cerr << std::endl; -#endif - - stats.increment(it->second); - - changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED,mit->first,vit->mMsgId, false)); - } - else - { -#ifdef POSTBASE_DEBUG - // warning. - std::cerr << "p3PostBase::background_updateVoteCounts() Warning No New Votes found."; - std::cerr << " For MsgId: " << vit->mMsgId; - std::cerr << std::endl; -#endif - } - - std::string str; - if (!encodePostCache(str, stats)) - { - std::cerr << "p3PostBase::background_updateVoteCounts() Failed to encode Votes"; - std::cerr << std::endl; - } - else - { -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_updateVoteCounts() Encoded String: " << str; - std::cerr << std::endl; -#endif - /* store new result */ - uint32_t token_c; - RsGxsGrpMsgIdPair msgId = std::make_pair(vit->mGroupId, vit->mMsgId); - RsGenExchange::setMsgServiceString(token_c, msgId, str); - } - } - } - - notifyChanges(changes); - - // DONE!. - background_cleanup(); - return; - -} - - -bool p3PostBase::background_cleanup() -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::background_cleanup()"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/ - - // Cleanup. - mBgStatsMap.clear(); - mBgProcessing = false; - - return true; -} - - - // Overloaded from GxsTokenQueue for Request callbacks. -void p3PostBase::handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) -{ -#ifdef POSTBASE_DEBUG - std::cerr << "p3PostBase::handleResponse(" << token << "," << req_type << "," << status << ")" << std::endl; -#endif - if (status != RsTokenService::COMPLETE) - return; //For now, only manage Complete request - - // stuff. - switch(req_type) - { - case POSTBASE_ALL_GROUPS: - background_loadGroups(token); - break; - case POSTBASE_UNPROCESSED_MSGS: - background_loadUnprocessedMsgs(token); - break; - case POSTBASE_ALL_MSGS: - background_loadAllMsgs(token); - break; - case POSTBASE_BG_POST_META: - background_updateVoteCounts(token); - break; - default: - /* error */ - std::cerr << "p3PostBase::handleResponse() Unknown Request Type: " << req_type; - std::cerr << std::endl; - break; - } -} - -static const uint32_t GXS_POSTED_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months -static const uint8_t GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; - -struct RsGxsPostedNotifyRecordsItem: public RsItem -{ - - RsGxsPostedNotifyRecordsItem() - : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_POSTED_CONFIG,GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD) - {} - - virtual ~RsGxsPostedNotifyRecordsItem() {} - - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) - { RS_SERIAL_PROCESS(records); } - - void clear() {} - - std::map records; -}; - -class GxsPostedConfigSerializer : public RsServiceSerializer -{ -public: - GxsPostedConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_POSTED_CONFIG) {} - virtual ~GxsPostedConfigSerializer() {} - - RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const - { - if(service_id != RS_SERVICE_GXS_TYPE_POSTED_CONFIG) - return NULL; - - switch(item_sub_id) - { - case GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsPostedNotifyRecordsItem(); - default: - return NULL; - } - } -}; - -bool p3PostBase::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) -{ -#ifdef GXSFORUMS_CHANNELS - std::cerr << "p3gxsChannels: Checking unused board: called by GxsCleaning." << std::endl; -#endif - - // request all group infos at once - - rstime_t now = time(nullptr); - - RS_STACK_MUTEX(mKnownPostedMutex); - - auto it = mKnownPosted.find(meta.mGroupId); - bool unknown_posted = (it == mKnownPosted.end()); - -#ifdef GXSFORUMS_CHANNELS - std::cerr << " Board " << meta.mGroupId ; -#endif - - if(unknown_posted) - { - // This case should normally not happen. It does because this board was never registered since it may - // arrived before this code was here - -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Not known yet. Adding current time as new TS." << std::endl; -#endif - mKnownPosted[meta.mGroupId] = now; - IndicateConfigChanged(); - - return true; - } - else - { - bool used_by_friends = (now < it->second + POSTED_UNUSED_BY_FRIENDS_DELAY); - bool subscribed = static_cast(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED); - - std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)"; - - if(!subscribed && !used_by_friends) - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Scheduling for deletion" << std::endl; -#endif - return false; - } - else - { -#ifdef GXSFORUMS_CHANNELS - std::cerr << ". Keeping!" << std::endl; -#endif - return true; - } - } -} - -bool p3PostBase::saveList(bool& cleanup, std::list&saveList) -{ - cleanup = true ; - - RsGxsPostedNotifyRecordsItem *item = new RsGxsPostedNotifyRecordsItem ; - - { - RS_STACK_MUTEX(mKnownPostedMutex); - item->records = mKnownPosted ; - } - - saveList.push_back(item) ; - return true; -} - -bool p3PostBase::loadList(std::list& loadList) -{ - while(!loadList.empty()) - { - RsItem *item = loadList.front(); - loadList.pop_front(); - - rstime_t now = time(NULL); - - RsGxsPostedNotifyRecordsItem *fnr = dynamic_cast(item) ; - - if(fnr != NULL) - { - RS_STACK_MUTEX(mKnownPostedMutex); - - mKnownPosted.clear(); - - for(auto it(fnr->records.begin());it!=fnr->records.end();++it) - if( now < it->second + GXS_POSTED_CONFIG_MAX_TIME_NOTIFY_STORAGE) - mKnownPosted.insert(*it) ; - } - - delete item ; - } - return true; -} - -RsSerialiser* p3PostBase::setupSerialiser() -{ - RsSerialiser* rss = new RsSerialiser; - rss->addSerialType(new GxsPostedConfigSerializer()); - - return rss; -} - diff --git a/libretroshare/src/services/p3postbase.h b/libretroshare/src/services/p3postbase.h deleted file mode 100644 index 3c2f5f67f..000000000 --- a/libretroshare/src/services/p3postbase.h +++ /dev/null @@ -1,137 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3postbase.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2012 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_POSTBASE_SERVICE_HEADER -#define P3_POSTBASE_SERVICE_HEADER - - -#include "services/p3gxscommon.h" -#include "gxs/rsgenexchange.h" - -#include "util/rstickevent.h" - -#include - -#include -#include -#include - -/* - * - */ - - -class PostStats -{ - public: - PostStats() :up_votes(0), down_votes(0), comments(0) { return; } - PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; } - - void increment(const PostStats &s) - { - up_votes += s.up_votes; - down_votes += s.down_votes; - comments += s.comments; - return; - } - - int up_votes; - int down_votes; - int comments; - std::list voters; -}; - -bool encodePostCache(std::string &str, const PostStats &s); -bool extractPostCache(const std::string &str, PostStats &s); - - -class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent, public p3Config -{ -public: - - p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs, - RsSerialType* serviceSerialiser, uint16_t serviceType); - - virtual void service_tick() override; - -protected: - - virtual void notifyChanges(std::vector& changes) override; - - // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type - , RsTokenService::GxsRequestStatus status) override; - - // Overloaded from RsTickEvent. - virtual void handle_event(uint32_t event_type, const std::string &elabel) override; - - // overloads p3Config - virtual RsSerialiser* setupSerialiser() override; // @see p3Config::setupSerialiser() - virtual bool saveList(bool &cleanup, std::list&saveList) override; // @see p3Config::saveList(bool &cleanup, std::list&) - virtual bool loadList(std::list& loadList) override; // @see p3Config::loadList(std::list&) - - virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override; -public: - - ////////////////////////////////////////////////////////////////////////////// - - virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); - - -protected: - - p3GxsCommentService *mCommentService; - -private: - - static uint32_t postBaseAuthenPolicy(); - - // Background processing. - void background_tick(); - - bool background_requestAllGroups(); - void background_loadGroups(const uint32_t &token); - - void addGroupForProcessing(RsGxsGroupId grpId); - void background_requestUnprocessedGroup(); - - void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly); - void background_loadUnprocessedMsgs(const uint32_t &token); - void background_loadAllMsgs(const uint32_t &token); - void background_loadMsgs(const uint32_t &token, bool unprocessed); - - - void background_updateVoteCounts(const uint32_t &token); - bool background_cleanup(); - - - RsMutex mPostBaseMtx; - RsMutex mKnownPostedMutex; - - bool mBgProcessing; - bool mBgIncremental; - std::set mBgGroupList; - std::map mBgStatsMap; - - std::map mKnownPosted; -}; - -#endif diff --git a/libretroshare/src/services/p3posted.cc b/libretroshare/src/services/p3posted.cc deleted file mode 100644 index 20c3f2151..000000000 --- a/libretroshare/src/services/p3posted.cc +++ /dev/null @@ -1,526 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3posted.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "services/p3posted.h" -#include "rsitems/rsposteditems.h" - -#include -#include - - -/**** - * #define POSTED_DEBUG 1 - ****/ - -/*extern*/ RsPosted* rsPosted = nullptr; - -/********************************************************************************/ -/******************* Startup / Tick ******************************************/ -/********************************************************************************/ - -p3Posted::p3Posted( - RsGeneralDataService *gds, RsNetworkExchangeService *nes, - RsGixs* gixs ) : - p3PostBase( gds, nes, gixs, new RsGxsPostedSerialiser(), - RS_SERVICE_GXS_TYPE_POSTED ), - RsPosted(static_cast(*this)) {} - -const std::string GXS_POSTED_APP_NAME = "gxsposted"; -const uint16_t GXS_POSTED_APP_MAJOR_VERSION = 1; -const uint16_t GXS_POSTED_APP_MINOR_VERSION = 0; -const uint16_t GXS_POSTED_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_POSTED_MIN_MINOR_VERSION = 0; - -static const uint32_t GXS_POSTED_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months -static const uint8_t GXS_POSTED_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; - -RsServiceInfo p3Posted::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_POSTED, - GXS_POSTED_APP_NAME, - GXS_POSTED_APP_MAJOR_VERSION, - GXS_POSTED_APP_MINOR_VERSION, - GXS_POSTED_MIN_MAJOR_VERSION, - GXS_POSTED_MIN_MINOR_VERSION); -} - -bool p3Posted::groupShareKeys(const RsGxsGroupId& groupId,const std::set& peers) -{ - RsGenExchange::shareGroupPublishKey(groupId,peers) ; - return true ; -} - -bool p3Posted::getGroupData(const uint32_t &token, std::vector &groups) -{ - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsPostedGroupItem* item = dynamic_cast(*vit); - if (item) - { - RsPostedGroup grp; - item->toPostedGroup(grp, true); - delete item; - groups.push_back(grp); - } - else - { - std::cerr << "Not a RsGxsPostedGroupItem, deleting!" << std::endl; - delete *vit; - } - } - } - return ok; -} - -bool p3Posted::getPostData( - const uint32_t &token, std::vector &msgs, - std::vector &cmts, - std::vector &vots) -{ -#ifdef POSTED_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << std::endl; -#endif - - GxsMsgDataMap msgData; - rstime_t now = time(NULL); - if(!RsGenExchange::getMsgData(token, msgData)) - { - RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl; - return false; - } - - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsPostedPostItem* postItem = - dynamic_cast(*vit); - - if(postItem) - { - // TODO Really needed all of these lines? - RsPostedPost msg = postItem->mPost; - msg.mMeta = postItem->meta; - postItem->toPostedPost(msg, true); - msg.calculateScores(now); - - msgs.push_back(msg); - delete postItem; - } - else - { - RsGxsCommentItem* cmtItem = - dynamic_cast(*vit); - if(cmtItem) - { - RsGxsComment cmt; - RsGxsMsgItem *mi = (*vit); - cmt = cmtItem->mMsg; - cmt.mMeta = mi->meta; -#ifdef GXSCOMMENT_DEBUG - RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl; - cmt.print(std::cerr," ", "cmt"); -#endif - cmts.push_back(cmt); - delete cmtItem; - } - else - { - RsGxsVoteItem* votItem = - dynamic_cast(*vit); - if(votItem) - { - RsGxsVote vot; - RsGxsMsgItem *mi = (*vit); - vot = votItem->mMsg; - vot.mMeta = mi->meta; - vots.push_back(vot); - delete votItem; - } - else - { - RsGxsMsgItem* msg = (*vit); - //const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217; - //const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03; - //const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1; - //const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2; - RsErr() << __PRETTY_FUNCTION__ - << "Not a PostedPostItem neither a " - << "RsGxsCommentItem neither a RsGxsVoteItem" - << " PacketService=" << std::hex << (int)msg->PacketService() << std::dec - << " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec - << " type name =" << typeid(*msg).name() - << " , deleting!" << std::endl; - delete *vit; - } - } - } - } - } - - return true; -} - -bool p3Posted::getPostData( - const uint32_t &token, std::vector &posts, std::vector &cmts) -{ - std::vector vots; - return getPostData( token, posts, cmts, vots); -} - -bool p3Posted::getPostData( - const uint32_t &token, std::vector &posts) -{ - std::vector cmts; - std::vector vots; - return getPostData( token, posts, cmts, vots); -} - -//Not currently used -/*bool p3Posted::getRelatedPosts(const uint32_t &token, std::vector &msgs) -{ - GxsMsgRelatedDataMap msgData; - bool ok = RsGenExchange::getMsgRelatedData(token, msgData); - rstime_t now = time(NULL); - - if(ok) - { - GxsMsgRelatedDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsPostedPostItem* item = dynamic_cast(*vit); - - if(item) - { - RsPostedPost msg = item->mPost; - msg.mMeta = item->meta; - msg.calculateScores(now); - - msgs.push_back(msg); - delete item; - } - else - { - std::cerr << "Not a PostedPostItem, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -}*/ - - -/********************************************************************************************/ -/********************************************************************************************/ -/********************************************************************************************/ - -/* Switched from having explicit Ranking calculations to calculating the set of scores - * on each RsPostedPost item. - * - * TODO: move this function to be part of RsPostedPost - then the GUI - * can reuse is as necessary. - * - */ - -bool RsPostedPost::calculateScores(rstime_t ref_time) -{ - /* so we want to calculate all the scores for this Post. */ - - PostStats stats; - extractPostCache(mMeta.mServiceString, stats); - - mUpVotes = stats.up_votes; - mDownVotes = stats.down_votes; - mComments = stats.comments; - mHaveVoted = (mMeta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_VOTE_MASK); - - rstime_t age_secs = ref_time - mMeta.mPublishTs; -#define POSTED_AGESHIFT (2.0) -#define POSTED_AGEFACTOR (3600.0) - - mTopScore = ((int) mUpVotes - (int) mDownVotes); - if (mTopScore > 0) - { - // score drops with time. - mHotScore = mTopScore / pow(POSTED_AGESHIFT + age_secs / POSTED_AGEFACTOR, 1.5); - } - else - { - // gets more negative with time. - mHotScore = mTopScore * pow(POSTED_AGESHIFT + age_secs / POSTED_AGEFACTOR, 1.5); - } - mNewScore = -age_secs; - - return true; -} - -/********************************************************************************************/ -/********************************************************************************************/ - -bool p3Posted::createGroup(uint32_t &token, RsPostedGroup &group) -{ - std::cerr << "p3Posted::createGroup()" << std::endl; - - RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem(); - grpItem->fromPostedGroup(group, true); - - - RsGenExchange::publishGroup(token, grpItem); - return true; -} - - -bool p3Posted::updateGroup(uint32_t &token, RsPostedGroup &group) -{ - std::cerr << "p3Posted::updateGroup()" << std::endl; - - RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem(); - grpItem->fromPostedGroup(group, true); - - - RsGenExchange::updateGroup(token, grpItem); - return true; -} - - -bool p3Posted::createPost(uint32_t &token, RsPostedPost &msg) -{ - std::cerr << "p3Posted::createPost() GroupId: " << msg.mMeta.mGroupId; - std::cerr << std::endl; - - RsGxsPostedPostItem* msgItem = new RsGxsPostedPostItem(); - //msgItem->mPost = msg; - //msgItem->meta = msg.mMeta; - msgItem->fromPostedPost(msg, true); - - - RsGenExchange::publishMsg(token, msgItem); - return true; -} - -bool p3Posted::getBoardsInfo( - const std::list& boardsIds, - std::vector& groupsInfo ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if(boardsIds.empty()) - { - if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - else - { - if( !requestGroupInfo(token, opts, boardsIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - - return getGroupData(token, groupsInfo) && !groupsInfo.empty(); -} - -bool p3Posted::getBoardAllContent( const RsGxsGroupId& groupId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - if( !requestMsgInfo(token, opts, std::list({groupId})) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - - return getPostData(token, posts, comments, votes); -} - -bool p3Posted::getBoardContent( const RsGxsGroupId& groupId, - const std::set& contentsIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - GxsMsgReq msgIds; - msgIds[groupId] = contentsIds; - - if( !requestMsgInfo(token, opts, msgIds) || - waitToken(token) != RsTokenService::COMPLETE ) return false; - - return getPostData(token, posts, comments, votes); -} - -bool p3Posted::getBoardsSummaries(std::list& boards ) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) return false; - - return getGroupSummary(token, boards); -} - -bool p3Posted::getBoardsServiceStatistics(GxsServiceStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestServiceStatistic(token) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getServiceStatistic(token,stat); -} - - -bool p3Posted::getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) -{ - uint32_t token; - if(!RsGxsIfaceHelper::requestGroupStatistic(token, boardId) || waitToken(token) != RsTokenService::COMPLETE) - return false; - - return RsGenExchange::getGroupStatistic(token,stat); -} - -bool p3Posted::createBoard(RsPostedGroup& board) -{ - uint32_t token; - if(!createGroup(token, board)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating group." << std::endl; - return false; - } - - if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated " << " group data." << std::endl; - return false; - } - - return true; -} - -bool p3Posted::voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& authorId) -{ - // Do some basic tests - - if(!rsIdentity->isOwnId(authorId)) // This is ruled out before waitToken complains. Not sure it's needed. - { - std::cerr << __PRETTY_FUNCTION__ << ": vote submitted with an ID that is not yours! This cannot work." << std::endl; - return false; - } - - RsGxsVote vote; - - vote.mMeta.mGroupId = postGrpId; - vote.mMeta.mThreadId = postMsgId; - vote.mMeta.mParentId = postMsgId; - vote.mMeta.mAuthorId = authorId; - - if (up) - vote.mVoteType = GXS_VOTE_UP; - else - vote.mVoteType = GXS_VOTE_DOWN; - - uint32_t token; - - if(!createNewVote(token, vote)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed submitting vote to (group,msg) " << postGrpId << "," << postMsgId << " from author " << authorId << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl; - return false; - } - return true; -} - -bool p3Posted::setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read) -{ - uint32_t token; - - setMessageReadStatus(token,msgId,read); - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl; - return false; - } - RsGxsGrpMsgIdPair p; - acknowledgeMsg(token,p); - return true; -} -bool p3Posted::editBoard(RsPostedGroup& board) -{ - uint32_t token; - if(!updateGroup(token, board)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failed updating group." << std::endl; - return false; - } - - if(waitToken(token) != RsTokenService::COMPLETE) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl; - return false; - } - - if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta)) - { - std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated " << " group data." << std::endl; - return false; - } - - return true; -} - -RsPosted::~RsPosted() = default; -RsGxsPostedEvent::~RsGxsPostedEvent() = default; diff --git a/libretroshare/src/services/p3posted.h b/libretroshare/src/services/p3posted.h deleted file mode 100644 index 0965ec1d1..000000000 --- a/libretroshare/src/services/p3posted.h +++ /dev/null @@ -1,158 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3posted.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef P3_POSTED_SERVICE_HEADER -#define P3_POSTED_SERVICE_HEADER - - -#include "retroshare/rsposted.h" -#include "services/p3postbase.h" - -#include - -#include -#include -#include - -/* - * - */ - -class p3Posted: public p3PostBase, public RsPosted -{ -public: - - p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs); - virtual RsServiceInfo getServiceInfo(); - -protected: - -virtual void notifyChanges(std::vector& changes) -{ - return p3PostBase::notifyChanges(changes); -} - - public: - -#ifdef TO_REMOVE -virtual void receiveHelperChanges(std::vector& changes) -{ - return RsGxsIfaceHelper::receiveChanges(changes); -} -#endif - - bool getBoardsInfo(const std::list& boardsIds, - std::vector& groupsInfo ) override; - - bool getBoardAllContent(const RsGxsGroupId& groupId, - std::vector& posts, - std::vector& comments, - std::vector& votes ) override; - - bool getBoardContent(const RsGxsGroupId& groupId, - const std::set& contentsIds, - std::vector& posts, - std::vector& comments, - std::vector& votes ) override; - - bool getBoardsSummaries(std::list& groupInfo) override; - - bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) override; - - bool getBoardsServiceStatistics(GxsServiceStatistic& stat) override; - - bool editBoard(RsPostedGroup& board) override; - - bool createBoard(RsPostedGroup& board) override; - - bool voteForPost(bool up,const RsGxsGroupId& postGrpId,const RsGxsMessageId& postMsgId,const RsGxsId& voterId) override; - - bool setPostReadStatus(const RsGxsGrpMsgIdPair& msgId, bool read) override; - - virtual bool getGroupData(const uint32_t &token, std::vector &groups) override; - virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts, std::vector &vots) override; - virtual bool getPostData(const uint32_t &token, std::vector &posts, std::vector &cmts) override; - virtual bool getPostData(const uint32_t &token, std::vector &posts) override; - -//Not currently used -//virtual bool getRelatedPosts(const uint32_t &token, std::vector &posts); - -virtual bool createGroup(uint32_t &token, RsPostedGroup &group) override; -virtual bool createPost(uint32_t &token, RsPostedPost &post) override; - -virtual bool updateGroup(uint32_t &token, RsPostedGroup &group) override; -virtual bool groupShareKeys(const RsGxsGroupId &group, const std::set& peers) override; - - ////////////////////////////////////////////////////////////////////////////// - // WRAPPERS due to the separate Interface. - -virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override - { - return p3PostBase::setMessageReadStatus(token, msgId, read); - } - - virtual bool setCommentAsRead(uint32_t& token,const RsGxsGroupId& gid,const RsGxsMessageId& comment_msg_id) override - { - p3PostBase::setMessageReadStatus(token,RsGxsGrpMsgIdPair(gid,comment_msg_id),true); - return true; - } - - - - /** Comment service - Provide RsGxsCommentService - - * redirect to p3GxsCommentService */ - virtual bool getCommentData(uint32_t token, std::vector &msgs) override - { return mCommentService->getGxsCommentData(token, msgs); } - - virtual bool getRelatedComments( uint32_t token, - std::vector &msgs ) override - { return mCommentService->getGxsRelatedComments(token, msgs); } - - virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override - { - return mCommentService->createGxsComment(token, msg); - } - virtual bool createComment(RsGxsComment& msg) override - { - uint32_t token; - - return mCommentService->createGxsComment(token, msg) && waitToken(token) == RsTokenService::COMPLETE ; - } - - virtual bool createNewVote(uint32_t &token, RsGxsVote &msg) override - { - return mCommentService->createGxsVote(token, msg); - } - - virtual bool acknowledgeComment( - uint32_t token, std::pair& msgId ) override - { return acknowledgeMsg(token, msgId); } - - virtual bool acknowledgeVote( - uint32_t token, std::pair& msgId ) override - { - if (mCommentService->acknowledgeVote(token, msgId)) return true; - return acknowledgeMsg(token, msgId); - } -}; - -#endif diff --git a/libretroshare/src/services/p3rtt.cc b/libretroshare/src/services/p3rtt.cc deleted file mode 100644 index 0dc2f41e2..000000000 --- a/libretroshare/src/services/p3rtt.cc +++ /dev/null @@ -1,461 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3rtt.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include - -#include "util/rsdir.h" -#include "retroshare/rsiface.h" -#include "retroshare/rspeers.h" -#include "pqi/pqibin.h" -#include "pqi/pqistore.h" -#include "pqi/p3linkmgr.h" -#include "rsserver/p3face.h" -#include "util/cxx17retrocompat.h" -#include "services/p3rtt.h" -#include "rsitems/rsrttitems.h" - - -/**** - * #define DEBUG_RTT 1 - ****/ - -/* DEFINE INTERFACE POINTER! */ -RsRtt *rsRtt = NULL; - - -#define MAX_PONG_RESULTS 150 -#define RTT_PING_PERIOD 10 - -/************ IMPLEMENTATION NOTES ********************************* - * - * Voice over Retroshare ;) - * - * This will be a simple test VoIP system aimed at testing out the possibilities. - * - * Important things to test: - * 1) lag, and variability in data rate - * - To do this we time tag every packet..., the destination can use this info to calculate the results. - * - Like imixitup. Dt = clock_diff + lag. - * we expect clock_diff to be relatively constant, but lag to vary. - * lag cannot be negative, so minimal Dt is ~clock_diff, and delays on this are considered +lag. - * - * 2) we could directly measure lag. ping back and forth with Timestamps. - * - * 3) we also want to measure bandwidth... - * - not sure the best method? - * one way: send a ping, then a large amount of data (5 seconds worth), then another ping. - * the delta in timestamps should be a decent indication of bandwidth. - * say we have a 100kb/s connection... need 500kb. - * actually the amount of data should be based on a reasonable maximum that we require. - * what does decent video require? - * Audio we can test for 64kb/s - which seems like a decent rate: e.g. mono, 16bit 22k = 1 x 2 x 22k = 44 kilobytes/sec - * best to do this without a VoIP call going on ;) - * - * - */ - - -#ifdef WINDOWS_SYS -#include "util/rstime.h" -#include -#endif - -static double getCurrentTS() -{ - -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} - -static uint64_t convertTsTo64bits(double ts) -{ - uint32_t secs = (uint32_t) ts; - uint32_t usecs = (uint32_t) ((ts - (double) secs) * 1000000); - uint64_t bits = (((uint64_t) secs) << 32) + usecs; - return bits; -} - - -static double convert64bitsToTs(uint64_t bits) -{ - uint32_t usecs = (uint32_t) (bits & 0xffffffff); - uint32_t secs = (uint32_t) ((bits >> 32) & 0xffffffff); - double ts = (secs) + ((double) usecs) / 1000000.0; - - return ts; -} - - - - -p3rtt::p3rtt(p3ServiceControl *sc) - :p3FastService(), mRttMtx("p3rtt"), mServiceCtrl(sc) -{ - addSerialType(new RsRttSerialiser()); - - mSentPingTime = 0; - mCounter = 0; - -} - - -const std::string RTT_APP_NAME = "rtt"; -const uint16_t RTT_APP_MAJOR_VERSION = 1; -const uint16_t RTT_APP_MINOR_VERSION = 0; -const uint16_t RTT_MIN_MAJOR_VERSION = 1; -const uint16_t RTT_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3rtt::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_RTT, - RTT_APP_NAME, - RTT_APP_MAJOR_VERSION, - RTT_APP_MINOR_VERSION, - RTT_MIN_MAJOR_VERSION, - RTT_MIN_MINOR_VERSION); -} - - - -int p3rtt::tick() -{ - sendPackets(); - - return 0; -} - -int p3rtt::status() -{ - return 1; -} - - - -int p3rtt::sendPackets() -{ - rstime_t now = time(NULL); - rstime_t pt; - { - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - pt = mSentPingTime; - } - - if (now >= pt+RTT_PING_PERIOD) - { - sendPingMeasurements(); - - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - mSentPingTime = now; - } - return true ; -} - - - -void p3rtt::sendPingMeasurements() -{ - - - /* we ping our peers */ - /* who is online? */ - std::set idList; - - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, idList); - - /* prepare packets */ - std::set::iterator it; - for(it = idList.begin(); it != idList.end(); ++it) - { - double ts = getCurrentTS(); - - /* create the packet */ - RsRttPingItem *pingPkt = new RsRttPingItem(); - pingPkt->PeerId(*it); - pingPkt->mSeqNo = mCounter; - pingPkt->mPingTS = convertTsTo64bits(ts); - - storePingAttempt(*it, ts, mCounter); - -#ifdef DEBUG_RTT - std::cerr << "p3rtt::sendPingMeasurements() Pinging: " << *it << " [" << pingPkt->mSeqNo << "," << std::hex << pingPkt->mPingTS << std::dec << "]" << std::endl;; -#endif - sendItem(pingPkt); - } - - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - mCounter++; -} - - -bool p3rtt::recvItem(RsItem *item) -{ - switch(item->PacketSubType()) - { - default: - break; - case RS_PKT_SUBTYPE_RTT_PING: - { - handlePing(item); - } - break; - case RS_PKT_SUBTYPE_RTT_PONG: - { - handlePong(item); - } - break; - } - - /* clean up */ - delete item; - return true ; -} - - -int p3rtt::handlePing(RsItem *item) -{ - /* cast to right type */ - RsRttPingItem *ping = (RsRttPingItem *) item; - - double ts = getCurrentTS(); -#ifdef DEBUG_RTT - std::cerr << "p3rtt::handlePing() from: " << ping->PeerId() << " - [" << ping->mSeqNo << "," << std::hex << ping->mPingTS << std::dec << "] " << std::endl; - std::cerr << "incoming ping travel time: " << ts - convert64bitsToTs(ping->mPingTS) << std::endl; -#endif - - /* with a ping, we just respond as quickly as possible - they do all the analysis */ - RsRttPongItem *pong = new RsRttPongItem(); - - pong->PeerId(ping->PeerId()); - pong->mPingTS = ping->mPingTS; - pong->mSeqNo = ping->mSeqNo; - - // add our timestamp. - pong->mPongTS = convertTsTo64bits(ts); - -#ifdef DEBUG_RTT - static double mLastResponseToPong = 0.0 ;// bad stuff - std::cerr << "Delay since last response to PONG: " << ts - mLastResponseToPong << std::endl; - mLastResponseToPong = ts ; -#endif - - sendItem(pong); - return true ; -} - - -int p3rtt::handlePong(RsItem *item) -{ - /* cast to right type */ - RsRttPongItem *pong = (RsRttPongItem *) item; - -#ifdef DEBUG_RTT - std::cerr << "p3rtt::handlePong() from: " << pong->PeerId() << " - [" << pong->mSeqNo << "," << std::hex << pong->mPingTS << " -> " << pong->mPongTS << std::dec << "] "<< std::endl; -#endif - - /* with a pong, we do the maths! */ - double recvTS = getCurrentTS(); - double pingTS = convert64bitsToTs(pong->mPingTS); - double pongTS = convert64bitsToTs(pong->mPongTS); - - double rtt = recvTS - pingTS; - double offset = pongTS - (recvTS - rtt / 2.0); // so to get to their time, we go ourTS + offset. - -#ifdef DEBUG_RTT - std::cerr << "incoming pong travel time: " << recvTS - convert64bitsToTs(pong->mPongTS) << std::endl; - std::cerr << " RTT analysis: pingTS: " << std::setprecision(16) << pingTS << ", pongTS: " << pongTS - << ", recvTS: " << std::setprecision(16) << recvTS << " ==> rtt: " << rtt << ", offset: " << offset << std::endl; -#endif - - storePongResult(pong->PeerId(), pong->mSeqNo, recvTS, rtt, offset); - return true ; -} - - - - -int p3rtt::storePingAttempt(const RsPeerId& id, double ts, uint32_t seqno) -{ - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - - /* find corresponding local data */ - RttPeerInfo *peerInfo = locked_GetPeerInfo(id); - -#ifdef DEBUG_RTT - std::cerr << "Delay since previous ping attempt: " << ts - peerInfo->mCurrentPingTS << std::endl; -#endif - peerInfo->mCurrentPingTS = ts; - peerInfo->mCurrentPingCounter = seqno; - - peerInfo->mSentPings++; - if (!peerInfo->mCurrentPongRecvd) - { - peerInfo->mLostPongs++; - } - - peerInfo->mCurrentPongRecvd = true; - - return 1; -} - - - -int p3rtt::storePongResult(const RsPeerId& id, uint32_t counter, double recv_ts, double rtt, double offset) -{ - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - - /* find corresponding local data */ - RttPeerInfo *peerInfo = locked_GetPeerInfo(id); - - if (peerInfo->mCurrentPingCounter != counter) - { -#ifdef DEBUG_RTT - std::cerr << "p3rtt::storePongResult() ERROR Severly Delayed Measurements!" << std::endl; -#endif - } - else - { - peerInfo->mCurrentPongRecvd = true; - } -#ifdef DEBUG_RTT - if(!peerInfo->mPongResults.empty()) - std::cerr << "Delay since last pong: " << recv_ts - peerInfo->mPongResults.back().mTS << std::endl; -#endif - - peerInfo->mPongResults.push_back(RsRttPongResult(recv_ts, rtt, offset)); - - - while(peerInfo->mPongResults.size() > MAX_PONG_RESULTS) - peerInfo->mPongResults.pop_front(); - - //Wait at least 20 pongs before compute mean time offset - if(peerInfo->mPongResults.size() > 20) - { - double mean = 0; - for(auto prIt : std::as_const(peerInfo->mPongResults)) - mean += prIt.mOffset; - peerInfo->mCurrentMeanOffset = mean / peerInfo->mPongResults.size(); - - if(fabs(peerInfo->mCurrentMeanOffset) > 120) - { - if(rsEvents) - { - auto ev = std::make_shared(); - ev->mSslId = peerInfo->mId; - ev->mTimeShift = static_cast(peerInfo->mCurrentMeanOffset); - ev->mConnectionInfoCode = RsConnectionEventCode::PEER_TIME_SHIFT; - rsEvents->postEvent(ev); - } - RsWarn() << __PRETTY_FUNCTION__ << " Peer: " << peerInfo->mId - << " have a time offset of more than two minutes with you" - << std::endl; - } - } - return 1; -} - - -uint32_t p3rtt::getPongResults(const RsPeerId& id, int n, std::list &results) -{ - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - - RttPeerInfo *peer = locked_GetPeerInfo(id); - - std::list::reverse_iterator it; - int i = 0; - for(it = peer->mPongResults.rbegin(); (it != peer->mPongResults.rend()) && (i < n); ++it, i++) - { - /* reversing order - so its easy to trim later */ - results.push_back(*it); - } - return i ; -} - -double p3rtt::getMeanOffset(const RsPeerId &id) -{ - RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/ - - RttPeerInfo *peer = locked_GetPeerInfo(id); - if(peer) - return peer->mCurrentMeanOffset; - else - return 0; -} - -RttPeerInfo *p3rtt::locked_GetPeerInfo(const RsPeerId& id) -{ - std::map::iterator it; - it = mPeerInfo.find(id); - if (it == mPeerInfo.end()) - { - /* add it in */ - RttPeerInfo pinfo; - - /* initialise entry */ - pinfo.initialisePeerInfo(id); - - mPeerInfo[id] = pinfo; - - it = mPeerInfo.find(id); - - } - - return &(it->second); -} - - - -bool RttPeerInfo::initialisePeerInfo(const RsPeerId& id) -{ - mId = id; - - /* reset variables */ - mCurrentPingTS = 0; - mCurrentPingCounter = 0; - mCurrentPongRecvd = true; - mCurrentMeanOffset = 0; - - mSentPings = 0; - mLostPongs = 0; - - mPongResults.clear(); - - return true; -} - - - - - - - - - - diff --git a/libretroshare/src/services/p3rtt.h b/libretroshare/src/services/p3rtt.h deleted file mode 100644 index c8df64034..000000000 --- a/libretroshare/src/services/p3rtt.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3rtt.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSRTT_HEADER -#define SERVICE_RSRTT_HEADER - -#include -#include - -#include "rsitems/rsrttitems.h" -#include "services/p3service.h" -#include "retroshare/rsrtt.h" - -class p3ServiceControl; - -class RttPeerInfo -{ - public: - RttPeerInfo() - : mCurrentPingTS(0.0),mCurrentPingCounter(0.0),mCurrentPongRecvd(false),mCurrentMeanOffset(0.0),mLostPongs(0),mSentPings(0){} - - bool initialisePeerInfo(const RsPeerId& id); - - RsPeerId mId; - double mCurrentPingTS; - double mCurrentPingCounter; - bool mCurrentPongRecvd; - double mCurrentMeanOffset; - - uint32_t mLostPongs; - uint32_t mSentPings; - - std::list mPongResults; -}; - - -//!The RS Rtt Test service. - /** - * - * Used to test Latency. - */ - -class p3rtt: public RsRtt, public p3FastService -{ - public: - p3rtt(p3ServiceControl *sc); -virtual RsServiceInfo getServiceInfo(); - - /***** overloaded from rsRtt *****/ - -virtual uint32_t getPongResults(const RsPeerId& id, int n, std::list &results); -virtual double getMeanOffset(const RsPeerId &id); - - /***** overloaded from p3Service *****/ - - virtual int tick(); - virtual int status(); - - int sendPackets(); - void sendPingMeasurements(); - -virtual bool recvItem(RsItem *item); // Overloaded from p3FastService. - - int handlePing(RsItem *item); - int handlePong(RsItem *item); - - int storePingAttempt(const RsPeerId& id, double ts, uint32_t mCounter); - int storePongResult(const RsPeerId& id, uint32_t counter, double recv_ts, double rtt, double offset); - - - /*! - * This retrieves all public chat msg items - */ - //bool getPublicChatQueue(std::list &chats); - - /*************** pqiMonitor callback ***********************/ - //virtual void statusChange(const std::list &plist); - - - /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; - - private: - RsMutex mRttMtx; - - RttPeerInfo *locked_GetPeerInfo(const RsPeerId& id); - - std::map mPeerInfo; - rstime_t mSentPingTime; - uint32_t mCounter; - - p3ServiceControl *mServiceCtrl; - -}; - -#endif // SERVICE_RSRTT_HEADER - diff --git a/libretroshare/src/services/p3service.cc b/libretroshare/src/services/p3service.cc deleted file mode 100644 index 54ba176ef..000000000 --- a/libretroshare/src/services/p3service.cc +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3service.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsitems/itempriorities.h" - -#include "pqi/pqi.h" -#include "util/rsstring.h" -#include "services/p3service.h" -#include - -#ifdef WINDOWS_SYS -#include "util/rstime.h" -#endif - -/***** - * #define SERV_DEBUG 1 - ****/ - - - -RsItem *p3Service::recvItem() -{ - RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/ - - if (recv_queue.empty()) - { - return NULL; /* nothing there! */ - } - - /* get something off front */ - RsItem *item = recv_queue.front(); - recv_queue.pop_front(); - - return item; -} - - -bool p3Service::receivedItems() -{ - RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/ - - return (!recv_queue.empty()); -} - - -bool p3Service::recvItem(RsItem *item) -{ - if (item) - { - RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/ - - recv_queue.push_back(item); - } - return true; -} - - - - - -void p3FastService::addSerialType(RsSerialType *st) -{ - rsSerialiser->addSerialType(st); -} - - - // overloaded pqiService interface. -bool p3FastService::recv(RsRawItem *raw) -{ - RsItem *item = NULL; - { - RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/ - - #ifdef SERV_DEBUG - std::cerr << "p3Service::recv()"; - std::cerr << std::endl; - #endif - - /* convert to RsServiceItem */ - uint32_t size = raw->getRawLength(); - item = rsSerialiser->deserialise(raw->getRawData(), &size); - if ((!item) || (size != raw->getRawLength())) - { - /* error in conversion */ - #ifdef SERV_DEBUG - std::cerr << "p3Service::recv() Error" << std::endl; - std::cerr << "p3Service::recv() Size: " << size << std::endl; - std::cerr << "p3Service::recv() RawLength: " << raw->getRawLength() << std::endl; - #endif - - if (item) - { - #ifdef SERV_DEBUG - std::cerr << "p3Service::recv() Bad Item:"; - std::cerr << std::endl; - item->print(std::cerr, 0); - std::cerr << std::endl; - #endif - delete item; - item=NULL ; - } - } - } - - /* if we have something - pass it on */ - if (item) - { -#ifdef SERV_DEBUG - std::cerr << "p3Service::recv() item:"; - std::cerr << std::endl; - item->print(std::cerr, 0); - std::cerr << std::endl; -#endif - - /* ensure PeerId is transferred */ - item->PeerId(raw->PeerId()); - recvItem(item); - } - - /* cleanup input */ - delete raw; - return (item != NULL); -} - - - -int p3FastService::sendItem(RsItem *si) -{ - RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/ - -#ifdef SERV_DEBUG - std::cerr << "p3Service::sendItem() Sending item:"; - std::cerr << std::endl; - si->print(std::cerr, 0); - std::cerr << std::endl; -#endif - - /* try to convert */ - uint32_t size = rsSerialiser->size(si); - if (!size) - { - std::cerr << "p3Service::send() ERROR size == 0"; - std::cerr << std::endl; - - /* can't convert! */ - delete si; - return 0; - } - - RsRawItem *raw = new RsRawItem(si->PacketId(), size); - if (!rsSerialiser->serialise(si, raw->getRawData(), &size)) - { - std::cerr << "p3Service::send() ERROR serialise failed"; - std::cerr << std::endl; - - delete raw; - raw = NULL; - } - - if ((raw) && (size != raw->getRawLength())) - { - std::cerr << "p3Service::send() ERROR serialise size mismatch"; - std::cerr << std::endl; - - delete raw; - raw = NULL; - } - - /* ensure PeerId is transferred */ - if (raw) - { - raw->PeerId(si->PeerId()); - - if(si->priority_level() == QOS_PRIORITY_UNKNOWN) - { - std::cerr << "************************************************************" << std::endl; - std::cerr << "********** Warning: p3Service::send() ********" << std::endl; - std::cerr << "********** Warning: caught a RsItem with undefined ********" << std::endl; - std::cerr << "********** priority level. That should not ********" << std::endl; - std::cerr << "********** happen. Please fix your items! ********" << std::endl; - std::cerr << "************************************************************" << std::endl; - } - raw->setPriorityLevel(si->priority_level()) ; - -#ifdef SERV_DEBUG - std::cerr << "p3Service::send() returning RawItem."; - std::cerr << std::endl; -#endif - delete si; - - return pqiService::send(raw); - } - else - { - std::cerr << "p3service: item could not be properly serialised. Will be wasted. Item is: "<< std::endl; - si->print(std::cerr,0) ; - - /* cleanup */ - delete si; - - return 0 ; - } -} - - diff --git a/libretroshare/src/services/p3service.h b/libretroshare/src/services/p3service.h deleted file mode 100644 index a394b1094..000000000 --- a/libretroshare/src/services/p3service.h +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3service.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_GENERIC_SERVICE_HEADER -#define P3_GENERIC_SERVICE_HEADER - -#include "pqi/pqi.h" -#include "pqi/pqiservice.h" -#include "util/rsthreads.h" - -/* This provides easy to use extensions to the pqiservice class provided in src/pqi. - * - * We will have a number of different strains. - * - * (1) p3Service -> pqiService - * - * Basic service with serialisation handled by a RsSerialiser. - * - * (2) p3ThreadedService -> p3service. - * - * Independent thread with mutex locks for i/o Queues. - * ideal for games etc. - * - * (3) p3CacheService -> p3service + CacheSource + CacheStore. - * - * For both Cached and Messages. - */ - -std::string generateRandomServiceId(); - -//TODO : encryption and upload / download rate implementation - - -// p3FastService(uint16_t type) -// :pqiService((RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(type)), - - -class p3FastService: public pqiService -{ - protected: - - p3FastService() - :pqiService(), - srvMtx("p3FastService"), rsSerialiser(NULL) - { - rsSerialiser = new RsSerialiser(); - return; - } - - public: - -virtual ~p3FastService() { delete rsSerialiser; return; } - -/*************** INTERFACE ******************************/ -int sendItem(RsItem *); -virtual int tick() { return 0; } -/*************** INTERFACE ******************************/ - - public: - // overloaded pqiService interface. -virtual bool recv(RsRawItem *); - - // called by recv(). -virtual bool recvItem(RsItem *item) = 0; - - - protected: -void addSerialType(RsSerialType *); - - RsMutex srvMtx; /* below locked by Mutex */ - - RsSerialiser *rsSerialiser; -}; - - -class p3Service: public p3FastService -{ - protected: - - p3Service() - :p3FastService() - { - return; - } - - public: - -/*************** INTERFACE ******************************/ - /* called from Thread/tick/GUI */ -//int sendItem(RsItem *); -RsItem * recvItem(); -bool receivedItems(); - -//virtual int tick() { return 0; } -/*************** INTERFACE ******************************/ - - public: - // overloaded p3FastService interface. -virtual bool recvItem(RsItem *item); - - private: - - /* below locked by srvMtx Mutex */ - std::list recv_queue; -}; - - -class nullService: public pqiService -{ - protected: - - nullService() - :pqiService() - { - return; - } - -//virtual int tick() - - public: - // overloaded NULL pqiService interface. -virtual bool recv(RsRawItem *item) - { - /* drop any items */ - delete item; - return true; - } - -virtual bool send(RsRawItem *item) - { - delete item; - return true; - } - -}; - - -class p3ThreadedService: public p3Service, public RsTickingThread -{ - protected: - - p3ThreadedService() - :p3Service() { return; } - - public: - -virtual ~p3ThreadedService() { return; } - - private: - -}; - - -#endif // P3_GENERIC_SERVICE_HEADER - diff --git a/libretroshare/src/services/p3serviceinfo.cc b/libretroshare/src/services/p3serviceinfo.cc deleted file mode 100644 index f05604021..000000000 --- a/libretroshare/src/services/p3serviceinfo.cc +++ /dev/null @@ -1,260 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3serviceinfo.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" - -#include "util/rsnet.h" - -#include "services/p3serviceinfo.h" -#include "rsitems/rsbanlistitems.h" - -#include - -/**** - * #define DEBUG_INFO 1 - ****/ - -/************ IMPLEMENTATION NOTES ********************************* - * - * Send Info to peers about services we are providing. - */ - -p3ServiceInfo::p3ServiceInfo(p3ServiceControl *serviceControl) - :p3Service(), mInfoMtx("p3ServiceInfo"), - mServiceControl(serviceControl) -{ - addSerialType(new RsServiceInfoSerialiser()); -} - -const std::string SERVICE_INFO_APP_NAME = "serviceinfo"; -const uint16_t SERVICE_INFO_APP_MAJOR_VERSION = 1; -const uint16_t SERVICE_INFO_APP_MINOR_VERSION = 0; -const uint16_t SERVICE_INFO_MIN_MAJOR_VERSION = 1; -const uint16_t SERVICE_INFO_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3ServiceInfo::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_SERVICEINFO, - SERVICE_INFO_APP_NAME, - SERVICE_INFO_APP_MAJOR_VERSION, - SERVICE_INFO_APP_MINOR_VERSION, - SERVICE_INFO_MIN_MAJOR_VERSION, - SERVICE_INFO_MIN_MINOR_VERSION); -} - - - -int p3ServiceInfo::tick() -{ - processIncoming(); - sendPackets(); - return 0; -} - -int p3ServiceInfo::status() -{ - return 1; -} - - -/***** Implementation ******/ - -bool p3ServiceInfo::processIncoming() -{ - /* for each packet - pass to specific handler */ - RsItem *item = NULL; - while(NULL != (item = recvItem())) - { -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::processingIncoming() Received Item:"; - std::cerr << std::endl; - item->print(std::cerr); - std::cerr << std::endl; -#endif - switch(item->PacketSubType()) - { - default: - break; - case RS_PKT_SUBTYPE_SERVICELIST_ITEM: - { - // Order is important!. - RsServiceInfoListItem *listItem = dynamic_cast(item); - if (listItem) - { - recvServiceInfoList(listItem); - } - else - { - // error. - std::cerr << "p3ServiceInfo::processingIncoming() Error with Received Item:"; - std::cerr << std::endl; - item->print(std::cerr); - std::cerr << std::endl; - } - } - break; - } - - /* clean up */ - delete item; - } - return true ; -} - - -bool convertServiceInfoToItem( - const RsPeerServiceInfo &info, - RsServiceInfoListItem *item) -{ - item->mServiceInfo = info.mServiceList; - item->PeerId(info.mPeerId); - return true; -} - -bool convertServiceItemToInfo( - const RsServiceInfoListItem *item, - RsPeerServiceInfo &info) -{ - info.mServiceList = item->mServiceInfo; - info.mPeerId = item->PeerId(); - return true; -} - - -bool p3ServiceInfo::recvServiceInfoList(RsServiceInfoListItem *item) -{ - RsPeerId peerId = item->PeerId(); - -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::recvServiceInfoList() from: " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - RsPeerServiceInfo info; - if (convertServiceItemToInfo(item, info)) - { - -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::recvServiceInfoList() Info: "; - std::cerr << std::endl; - std::cerr << info; - std::cerr << std::endl; -#endif - - /* update service control */ - mServiceControl->updateServicesProvided(peerId, info); - return true; - } - return false; -} - - -bool p3ServiceInfo::sendPackets() -{ - std::set updateSet; - - { - RsStackMutex stack(mInfoMtx); /****** LOCKED MUTEX *******/ - updateSet = mPeersToUpdate; - mPeersToUpdate.clear(); - } - - mServiceControl->getServiceChanges(updateSet); - - RsStackMutex stack(mInfoMtx); /****** LOCKED MUTEX *******/ - std::set::iterator it; - for(it = updateSet.begin(); it != updateSet.end(); ++it) - { - sendServiceInfoList(*it); - } - - return (!updateSet.empty()); -} - - -int p3ServiceInfo::sendServiceInfoList(const RsPeerId &peerId) -{ -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::sendServiceInfoList() to " << peerId.toStdString(); - std::cerr << std::endl; -#endif - - RsServiceInfoListItem *item = new RsServiceInfoListItem(); - - RsPeerServiceInfo info; - bool sent = false; - if (mServiceControl->getServicesAllowed(peerId, info)) - { -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::sendServiceInfoList() Info: "; - std::cerr << std::endl; - std::cerr << info; - std::cerr << std::endl; -#endif - - if (convertServiceInfoToItem(info, item)) - { - item->PeerId(peerId); - - sent = true; - sendItem(item); - } - } - - if (!sent) - { - delete item; - } - - return sent; -} - -void p3ServiceInfo::statusChange(const std::list &plist) -{ -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::statusChange()"; - std::cerr << std::endl; -#endif - - std::list::const_iterator it; - for (it = plist.begin(); it != plist.end(); ++it) - { - if (it->state & RS_PEER_S_FRIEND) - { - if (it->actions & RS_PEER_CONNECTED) - { -#ifdef DEBUG_INFO - std::cerr << "p3ServiceInfo::statusChange()"; - std::cerr << "Peer: " << it->id; - std::cerr << " Connected"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(mInfoMtx); /****** LOCKED MUTEX *******/ - mPeersToUpdate.insert(it->id); - } - } - } -} - - - diff --git a/libretroshare/src/services/p3serviceinfo.h b/libretroshare/src/services/p3serviceinfo.h deleted file mode 100644 index 2d8f8a8af..000000000 --- a/libretroshare/src/services/p3serviceinfo.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3serviceinfo.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2014 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSSERVICEINFO_HEADER -#define SERVICE_RSSERVICEINFO_HEADER - -#include -#include -#include - -#include "pqi/p3servicecontrol.h" -#include "pqi/pqimonitor.h" - -#include "services/p3service.h" - -#include "rsitems/rsserviceinfoitems.h" - -//!The ServiceInfo service. - /** - * - * Exchange list of Available Services with peers. - */ - -class p3ServiceInfo: public p3Service, public pqiMonitor -{ - public: - p3ServiceInfo(p3ServiceControl *serviceControl); - virtual RsServiceInfo getServiceInfo(); - - virtual int tick(); - virtual int status(); - - /*************** pqiMonitor callback ***********************/ - virtual void statusChange(const std::list &plist); - - private: - - bool sendPackets(); - bool processIncoming(); - - bool recvServiceInfoList(RsServiceInfoListItem *item); - int sendServiceInfoList(const RsPeerId &peerid); - - private: - RsMutex mInfoMtx; - - std::set mPeersToUpdate; - p3ServiceControl *mServiceControl; -}; - -#endif // SERVICE_RSSERVICEINFO_HEADER - diff --git a/libretroshare/src/services/p3statusservice.cc b/libretroshare/src/services/p3statusservice.cc deleted file mode 100644 index f3f44cf9b..000000000 --- a/libretroshare/src/services/p3statusservice.cc +++ /dev/null @@ -1,416 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3statusservice.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Vinny Do, Chris Evi-Parker. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "services/p3statusservice.h" -#include "rsitems/rsstatusitems.h" -#include "rsserver/p3face.h" -#include "retroshare/rsiface.h" - -#include -#include -#include -#include -#include "util/rstime.h" - -#include "pqi/p3linkmgr.h" - -std::ostream& operator<<(std::ostream& out, const StatusInfo& si) -{ - out << "StatusInfo: " << std::endl; - out << "id: " << si.id << std::endl; - out << "status: " << si.status << std::endl; - out << "time_stamp: " << si.time_stamp << std::endl; - return out; -} - -RsStatus *rsStatus = NULL; - -p3StatusService::p3StatusService(p3ServiceControl *sc) - :p3Service(), p3Config(), mServiceCtrl(sc), mStatusMtx("p3StatusService") -{ - addSerialType(new RsStatusSerialiser()); - -} - -p3StatusService::~p3StatusService() -{ -} - - -const std::string STATUS_APP_NAME = "status"; -const uint16_t STATUS_APP_MAJOR_VERSION = 1; -const uint16_t STATUS_APP_MINOR_VERSION = 0; -const uint16_t STATUS_MIN_MAJOR_VERSION = 1; -const uint16_t STATUS_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3StatusService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_STATUS, - STATUS_APP_NAME, - STATUS_APP_MAJOR_VERSION, - STATUS_APP_MINOR_VERSION, - STATUS_MIN_MAJOR_VERSION, - STATUS_MIN_MINOR_VERSION); -} - - -bool p3StatusService::getOwnStatus(StatusInfo& statusInfo) -{ -#ifdef STATUS_DEBUG - std::cerr << "p3StatusService::getOwnStatus() " << std::endl; -#endif - - std::map::iterator it; - const RsPeerId& ownId = mServiceCtrl->getOwnId(); - - RsStackMutex stack(mStatusMtx); - it = mStatusInfoMap.find(ownId); - - if (it == mStatusInfoMap.end()){ - std::cerr << "p3StatusService::saveList() :" << "Did not find your status" << ownId << std::endl; - - // own status not set, set it to online - statusInfo.id = ownId; - statusInfo.status = RS_STATUS_ONLINE; - - std::pair pr(ownId, statusInfo); - mStatusInfoMap.insert(pr); - IndicateConfigChanged(); - - return true; - } - - statusInfo = it->second; - - return true; -} - -bool p3StatusService::getStatusList(std::list& statusInfo) -{ -#ifdef STATUS_DEBUG - std::cerr << "p3StatusService::getStatusList() " << std::endl; -#endif - - statusInfo.clear(); - - RsStackMutex stack(mStatusMtx); - - // fill up statusInfo list with this information - std::map::iterator mit; - for(mit = mStatusInfoMap.begin(); mit != mStatusInfoMap.end(); ++mit){ - statusInfo.push_back(mit->second); - } - - return true; -} - -bool p3StatusService::getStatus(const RsPeerId &id, StatusInfo &statusInfo) -{ -#ifdef STATUS_DEBUG - std::cerr << "p3StatusService::getStatus() " << std::endl; -#endif - - RsStackMutex stack(mStatusMtx); - - std::map::iterator mit = mStatusInfoMap.find(id); - - if (mit == mStatusInfoMap.end()) { - /* return fake status info as offline */ - statusInfo = StatusInfo(); - - statusInfo.id = id; - statusInfo.status = RS_STATUS_OFFLINE; - return false; - } - - statusInfo = mit->second; - - return true; -} - -/* id = "", status is sent to all online peers */ -bool p3StatusService::sendStatus(const RsPeerId &id, uint32_t status) -{ - StatusInfo statusInfo; - std::set onlineList; - - { - RsStackMutex stack(mStatusMtx); - - statusInfo.id = mServiceCtrl->getOwnId(); - statusInfo.status = status; - - // don't save inactive status - if(statusInfo.status != RS_STATUS_INACTIVE){ - - // If your id is not set, set it - if(mStatusInfoMap.find(statusInfo.id) == mStatusInfoMap.end()){ - - std::pair pr(statusInfo.id, statusInfo); - mStatusInfoMap.insert(pr); - IndicateConfigChanged(); - } else if(mStatusInfoMap[statusInfo.id].status != statusInfo.status){ - - IndicateConfigChanged(); - mStatusInfoMap[statusInfo.id] = statusInfo; - } - } - - if (id.isNull()) { - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, onlineList); - } else { - onlineList.insert(id); - } - } - - std::set::iterator it; - -#ifdef STATUS_DEBUG - std::cerr << "p3StatusService::sendStatus() " << std::endl; - std::cerr << statusInfo; -#endif - - // send to all peers online - for(it = onlineList.begin(); it != onlineList.end(); ++it){ - RsStatusItem* statusItem = new RsStatusItem(); - statusItem->sendTime = time(NULL); - statusItem->status = statusInfo.status; - statusItem->PeerId(*it); - sendItem(statusItem); - } - - /* send notify of own status change */ - RsServer::notify()->notifyPeerStatusChanged(statusInfo.id.toStdString(), statusInfo.status); - - return true; -} - -/******************************/ - -void p3StatusService::receiveStatusQueue() -{ - std::map changed; - - { - RsStackMutex stack(mStatusMtx); - - RsItem* item; - - while(NULL != (item = recvItem())){ - - RsStatusItem* status_item = dynamic_cast(item); - - if(status_item == NULL) { - std::cerr << "p3Status::getStatusQueue() " << "Failed to cast Item \n" << std::endl; - delete (item); - continue; - } - -#ifdef STATUS_DEBUG - std::cerr << "p3StatusService::getStatusQueue()" << std::endl; - std::cerr << "PeerId : " << status_item->PeerId() << std::endl; - std::cerr << "Status: " << status_item->status << std::endl; - std::cerr << "Got status Item" << std::endl; -#endif - - std::map::iterator mit = mStatusInfoMap.find(status_item->PeerId()); - - if(mit != mStatusInfoMap.end()){ - mit->second.id = status_item->PeerId(); - - if (mit->second.status != status_item->status) { - changed [mit->second.id] = status_item->status; - } - - mit->second.status = status_item->status; - mit->second.time_stamp = status_item->sendTime; -#ifdef STATUS_DEBUG - } else { - std::cerr << "getStatus() " << "Could not find Peer" << status_item->PeerId(); - std::cerr << std::endl; -#endif - } - - delete (status_item); - } - - } /* UNLOCKED */ - - if (changed.size()) { - std::map::iterator it; - for (it = changed.begin(); it != changed.end(); ++it) { - RsServer::notify()->notifyPeerStatusChanged(it->first.toStdString(), it->second); - } - RsServer::notify()->notifyPeerStatusChangedSummary(); - } -} - -/* p3Config */ - -RsSerialiser* p3StatusService::setupSerialiser(){ - - RsSerialiser *rss = new RsSerialiser; - rss->addSerialType(new RsStatusSerialiser); - - return rss; -} - -bool p3StatusService::saveList(bool& cleanup, std::list& ilist){ - - // save your status before quiting - cleanup = true; - RsStatusItem* own_status = new RsStatusItem; - StatusInfo own_info; - - std::map::iterator it; - - { - RsStackMutex stack(mStatusMtx); - it = mStatusInfoMap.find(mServiceCtrl->getOwnId()); - - if(it == mStatusInfoMap.end()){ - std::cerr << "p3StatusService::saveList() :" << "Did not find your status" - << mServiceCtrl->getOwnId() << std::endl; - delete own_status; - return false; - } - - own_info = it->second; - } - - own_status->PeerId(own_info.id); - own_status->sendTime = own_info.time_stamp; - own_status->status = own_info.status; - - ilist.push_back(own_status); - - return true; -} - -bool p3StatusService::loadList(std::list& load) -{ - // load your status from last rs session - StatusInfo own_info; - - - for(std::list::const_iterator it = load.begin() ; it != load.end(); ++it) - { - RsStatusItem* own_status = dynamic_cast(*it); - - if(own_status != NULL) - { - own_info.id = mServiceCtrl->getOwnId(); - own_info.status = own_status->status; - own_info.time_stamp = own_status->sendTime; - - { - RsStackMutex stack(mStatusMtx); - std::pair pr(mServiceCtrl->getOwnId(), own_info); - mStatusInfoMap.insert(pr); - } - - } - - delete *it ; - } - load.clear() ; - return false; -} - - -int p3StatusService::tick() -{ - if (receivedItems()) { - receiveStatusQueue(); - } - - return 0; -} - -int p3StatusService::status(){ - return 1; -} - -/*************** pqiMonitor callback ***********************/ - -void p3StatusService::statusChange(const std::list &plist) -{ - bool changedState = false; - - StatusInfo statusInfo; - std::list::const_iterator it; - for (it = plist.begin(); it != plist.end(); ++it) - { - if (it->actions & RS_SERVICE_PEER_DISCONNECTED) - { - { - RsStackMutex stack(mStatusMtx); - /* remove peer from status map */ - mStatusInfoMap.erase(it->id); - } /* UNLOCKED */ - - changedState = true; - RsServer::notify()->notifyPeerStatusChanged(it->id.toStdString(), RS_STATUS_OFFLINE); - } - - if (it->actions & RS_SERVICE_PEER_CONNECTED) - { - /* send current status, only call getOwnStatus once in the loop */ - if (statusInfo.id.isNull() == false || getOwnStatus(statusInfo)) - { - sendStatus(it->id, statusInfo.status); - } - - { - RsStackMutex stack(mStatusMtx); - - /* We assume that the peer is online. If not, he send us a new status */ - StatusInfo info; - info.id = it->id; - info.status = RS_STATUS_ONLINE; - info.time_stamp = time(NULL); - - mStatusInfoMap[it->id] = info; - } /* UNLOCKED */ - - changedState = true; - RsServer::notify()->notifyPeerStatusChanged(it->id.toStdString(), RS_STATUS_ONLINE); - } - - if (it->actions & RS_SERVICE_PEER_REMOVED) - { - /* now handle remove */ - { - RsStackMutex stack(mStatusMtx); - /* remove peer from status map */ - mStatusInfoMap.erase(it->id); - } /* UNLOCKED */ - - changedState = true; - RsServer::notify()->notifyPeerStatusChanged(it->id.toStdString(), RS_STATUS_OFFLINE); - } - } - - if (changedState) - { - RsServer::notify()->notifyPeerStatusChangedSummary(); - } -} diff --git a/libretroshare/src/services/p3statusservice.h b/libretroshare/src/services/p3statusservice.h deleted file mode 100644 index ac0b70653..000000000 --- a/libretroshare/src/services/p3statusservice.h +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3statusservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008 by Vinny Do, Chris Evi-Parker. * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_P3_STATUS_INTERFACE_H -#define RS_P3_STATUS_INTERFACE_H - -#include -#include - -#include "rsitems/rsstatusitems.h" -#include "retroshare/rsstatus.h" -#include "services/p3service.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/pqiservicemonitor.h" - -class p3ServiceControl; - -//! handles standard status messages (busy, away, online, offline) set by user -/*! - * The is a retroshare service which allows peers - * to inform each other about their status in a standard way, as opposed to - * custom string. - * @see rsiface/rsstatus.h for status constants - */ -class p3StatusService: public p3Service, public p3Config, public pqiServiceMonitor -{ - public: - - p3StatusService(p3ServiceControl *sc); -virtual ~p3StatusService(); - -virtual RsServiceInfo getServiceInfo(); - -/***** overloaded from p3Service *****/ -virtual int tick(); -virtual int status(); - -/*************** pqiMonitor callback ***********************/ -virtual void statusChange(const std::list &plist); - -/********* RsStatus ***********/ - -/** - * Status is set to offline as default if no info received from relevant peer - */ -virtual bool getOwnStatus(StatusInfo& statusInfo); -virtual bool getStatusList(std::list& statusInfo); -virtual bool getStatus(const RsPeerId &id, StatusInfo &statusInfo); -/* id = "", status is sent to all online peers */ -virtual bool sendStatus(const RsPeerId &id, uint32_t status); - -/******************************/ - - -/** implemented from p3Config **/ - -/*! - * @return The serialiser the enables storage of save info - */ -virtual RsSerialiser *setupSerialiser(); - -/*! - * This stores information on what your status was before you exited rs - */ -virtual bool saveList(bool& cleanup, std::list&); - -/*! - * @param load Should contain a single item which is clients status from last rs session - */ -virtual bool loadList(std::list& load); - - private: - -virtual void receiveStatusQueue(); - -p3ServiceControl *mServiceCtrl; - -std::map mStatusInfoMap; - -RsMutex mStatusMtx; - -}; - -#endif diff --git a/libretroshare/src/services/p3wiki.cc b/libretroshare/src/services/p3wiki.cc deleted file mode 100644 index c1b8f86e1..000000000 --- a/libretroshare/src/services/p3wiki.cc +++ /dev/null @@ -1,798 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3wiki.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "services/p3wiki.h" -#include "retroshare/rsgxsflags.h" -#include "rsitems/rswikiitems.h" - -#include "util/rsrandom.h" - -/**** - * #define WIKI_DEBUG 1 - ****/ - -RsWiki *rsWiki = NULL; - - -#define WIKI_EVENT_DUMMYTICK 0x0001 -#define WIKI_EVENT_DUMMYSTART 0x0002 - -#define DUMMYSTART_PERIOD 60 // some time for dummyIds to be generated. -#define DUMMYTICK_PERIOD 3 - -p3Wiki::p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs) - :RsGenExchange(gds, nes, new RsGxsWikiSerialiser(), RS_SERVICE_GXS_TYPE_WIKI, gixs, wikiAuthenPolicy()), - RsWiki(static_cast(*this)) -{ - // Setup of dummy Pages. - mAboutActive = false; - mImprovActive = false; - mMarkdownActive = false; - - // TestData disabled in Repo. - //RsTickEvent::schedule_in(WIKI_EVENT_DUMMYSTART, DUMMYSTART_PERIOD); - -} - - -const std::string GXS_WIKI_APP_NAME = "gxswiki"; -const uint16_t GXS_WIKI_APP_MAJOR_VERSION = 1; -const uint16_t GXS_WIKI_APP_MINOR_VERSION = 0; -const uint16_t GXS_WIKI_MIN_MAJOR_VERSION = 1; -const uint16_t GXS_WIKI_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3Wiki::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_WIKI, - GXS_WIKI_APP_NAME, - GXS_WIKI_APP_MAJOR_VERSION, - GXS_WIKI_APP_MINOR_VERSION, - GXS_WIKI_MIN_MAJOR_VERSION, - GXS_WIKI_MIN_MINOR_VERSION); -} - - -uint32_t p3Wiki::wikiAuthenPolicy() -{ - uint32_t policy = 0; - uint8_t flag = 0; - - // Edits generally need an authors signature. - - flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - flag |= GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - - -void p3Wiki::service_tick() -{ - RsTickEvent::tick_events(); - return; -} - - -void p3Wiki::notifyChanges(std::vector& changes) -{ - std::cerr << "p3Wiki::notifyChanges() New stuff"; - std::cerr << std::endl; -} - - /* Specific Service Data */ -bool p3Wiki::getCollections(const uint32_t &token, std::vector &collections) -{ - std::cerr << "p3Wiki::getCollections()"; - std::cerr << std::endl; - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsWikiCollectionItem* item = dynamic_cast(*vit); - - if (item) - { - RsWikiCollection collection = item->collection; - collection.mMeta = item->meta; - delete item; - collections.push_back(collection); - - std::cerr << "p3Wiki::getCollections() Adding Collection to Vector: "; - std::cerr << std::endl; - std::cerr << collection; - std::cerr << std::endl; - } - else - { - std::cerr << "Not a WikiCollectionItem, deleting!" << std::endl; - delete *vit; - } - - } - } - return ok; -} - - -bool p3Wiki::getSnapshots(const uint32_t &token, std::vector &snapshots) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsWikiSnapshotItem* item = dynamic_cast(*vit); - - if(item) - { - RsWikiSnapshot snapshot = item->snapshot; - snapshot.mMeta = item->meta; - snapshots.push_back(snapshot); - delete item; - } - else - { - std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - - -bool p3Wiki::getRelatedSnapshots(const uint32_t &token, std::vector &snapshots) -{ - GxsMsgRelatedDataMap msgData; - bool ok = RsGenExchange::getMsgRelatedData(token, msgData); - - if(ok) - { - GxsMsgRelatedDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsWikiSnapshotItem* item = dynamic_cast(*vit); - - if(item) - { - RsWikiSnapshot snapshot = item->snapshot; - snapshot.mMeta = item->meta; - snapshots.push_back(snapshot); - delete item; - } - else - { - std::cerr << "Not a WikiSnapshot Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; -} - - -bool p3Wiki::getComments(const uint32_t &token, std::vector &comments) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - RsGxsGroupId grpId = mit->first; - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); vit++) - { - RsGxsWikiCommentItem* item = dynamic_cast(*vit); - - if(item) - { - RsWikiComment comment = item->comment; - comment.mMeta = item->meta; - comments.push_back(comment); - delete item; - } - else - { - std::cerr << "Not a WikiComment Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - - return ok; - return false; -} - - - -bool p3Wiki::submitCollection(uint32_t &token, RsWikiCollection &collection) -{ - RsGxsWikiCollectionItem* collectionItem = new RsGxsWikiCollectionItem(); - collectionItem->collection = collection; - collectionItem->meta = collection.mMeta; - - std::cerr << "p3Wiki::submitCollection(): "; - std::cerr << std::endl; - std::cerr << collection; - std::cerr << std::endl; - - std::cerr << "p3Wiki::submitCollection() pushing to RsGenExchange"; - std::cerr << std::endl; - - RsGenExchange::publishGroup(token, collectionItem); - return true; -} - - -bool p3Wiki::submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) -{ - std::cerr << "p3Wiki::submitSnapshot(): " << snapshot; - std::cerr << std::endl; - - RsGxsWikiSnapshotItem* snapshotItem = new RsGxsWikiSnapshotItem(); - snapshotItem->snapshot = snapshot; - snapshotItem->meta = snapshot.mMeta; - snapshotItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_SNAPSHOT; - - RsGenExchange::publishMsg(token, snapshotItem); - return true; -} - - -bool p3Wiki::submitComment(uint32_t &token, RsWikiComment &comment) -{ - std::cerr << "p3Wiki::submitComment(): " << comment; - std::cerr << std::endl; - - RsGxsWikiCommentItem* commentItem = new RsGxsWikiCommentItem(); - commentItem->comment = comment; - commentItem->meta = comment.mMeta; - commentItem->meta.mMsgFlags = FLAG_MSG_TYPE_WIKI_COMMENT; - - RsGenExchange::publishMsg(token, commentItem); - return true; -} - -bool p3Wiki::updateCollection(uint32_t &token, RsWikiCollection &group) -{ - std::cerr << "p3Wiki::updateCollection()" << std::endl; - - RsGxsWikiCollectionItem* grpItem = new RsGxsWikiCollectionItem(); - grpItem->collection = group; - grpItem->meta = group.mMeta; - - RsGenExchange::updateGroup(token, grpItem); - return true; -} - -// Blocking Interfaces. -bool p3Wiki::createCollection(RsWikiCollection &group) -{ - uint32_t token; - return submitCollection(token, group) && waitToken(token) == RsTokenService::COMPLETE; -} - -bool p3Wiki::updateCollection(const RsWikiCollection &group) -{ - uint32_t token; - RsWikiCollection update(group); - return updateCollection(token, update) && waitToken(token) == RsTokenService::COMPLETE; -} - -bool p3Wiki::getCollections(const std::list groupIds, std::vector &groups) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if (groupIds.empty()) - { - if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - else - { - if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE ) - return false; - } - return getCollections(token, groups) && !groups.empty(); -} - -std::ostream &operator<<(std::ostream &out, const RsWikiCollection &group) -{ - out << "RsWikiCollection [ "; - out << " Name: " << group.mMeta.mGroupName; - out << " Desc: " << group.mDescription; - out << " Category: " << group.mCategory; - out << " ]"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsWikiSnapshot &shot) -{ - out << "RsWikiSnapshot [ "; - out << "Title: " << shot.mMeta.mMsgName; - out << "]"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsWikiComment &comment) -{ - out << "RsWikiComment [ "; - out << "Title: " << comment.mMeta.mMsgName; - out << "]"; - return out; -} - - -/***** FOR TESTING *****/ - -const int about_len = 10; -const std::string about_txt[] = - { "Welcome to RsWiki, a fully distributed Wiki system that anyone can edit.", - "Please read through these dummy Wiki pages to learn how it should work\n", - "Basic Functionality:", - " - New Group: creates a collection of Wiki Pages, the creator of group", - " and anyone they share the publish keys with) is the moderator\n", - " - New Page: Create a new Wiki Page, only Group Moderators can do this\n", - " - Edit: Anyone Can Edit the Wiki Page, and the changes form a tree under the original\n", - " - RePublish: This is used by the Moderators to accept and reject Edits.", - " the republished page becomes a new version of the Root Page, allowing more edits to be done\n", - "Please read the improvements section to see how we envision the wiki's working", - }; - - -const int improvements_len = 14; -const std::string improvements_txt[] = - { "As you can see, the current Wiki is a basic framework waiting to be expanded.", - "There are lots of potential improvements... some of my ideas are listed below\n", - "Ideas:", - " - Formatting: No HTML, lets use Markdown or something similar.\n", - " - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n", - " - Read Mode... hide all the Edits, and only show the most recently published versions\n", - " - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n", - " - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,", - " to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem\n", - " - work out how to include media (photos, audio, video, etc) without embedding in pages", - " this would leverage the turtle transfer system somehow - maybe like channels.\n", - " - Comments, reviews etc can be incorporated - ideas here are welcome.\n", - " - Any other suggestion???", - " - Come on more ideas!" - }; - - -const int markdown_len = 34; -const std::string markdown_txt[] = { - "# An Example of Markdown Editing.", - "", - "Markdown is quite simple to use, and allows simple HTML.", - "", - "## Some Blocks below an H2 heading.", - "", - " * Firstly, we can put a link [in here][]", - " * Secondly, as you can see we're in a list.", - " * Thirdly, I don't know.", - "", - "### A Sub (H3) heading.", - "", - "#### If we want to get into the very small details. (H6).", - "", - " A bit of code.", - " This is a lit", - " foreach(in loop)", - " a++", - " Double quoted stuff.", - "", - "Or it can be indented like this:", - "", - "> A block of indented stuff looks like this", - "> > With double indenting and ", - "> > > triple indenting possible too", - "", - "Images can be embedded, but thats somethinng to work on in the future.", - "", - "Sadly it doesn't support tables or div's or anything that complex.", - "", - "Keep it simple and help write good wiki pages, thx.", - "", - "[in here]: http://example.com/ \"Optional Title Here\"", - "" - }; - - -void p3Wiki::generateDummyData() -{ - std::cerr << "p3Wiki::generateDummyData()"; - std::cerr << std::endl; - -#define GEN_COLLECTIONS 0 - - int i; - for(i = 0; i < GEN_COLLECTIONS; i++) - { - RsWikiCollection wiki; - wiki.mMeta.mGroupId = RsGxsGroupId::random(); - wiki.mMeta.mGroupFlags = 0; - wiki.mMeta.mGroupName = RsGxsGroupId::random().toStdString(); - - uint32_t dummyToken = 0; - submitCollection(dummyToken, wiki); - } - - - RsWikiCollection wiki; - wiki.mMeta.mGroupFlags = 0; - wiki.mMeta.mGroupName = "About RsWiki"; - - submitCollection(mAboutToken, wiki); - - wiki.mMeta.mGroupFlags = 0; - wiki.mMeta.mGroupName = "RsWiki Improvements"; - - submitCollection(mImprovToken, wiki); - - wiki.mMeta.mGroupFlags = 0; - wiki.mMeta.mGroupName = "RsWiki Markdown"; - - submitCollection(mMarkdownToken, wiki); - - mAboutLines = 0; - mImprovLines = 0; - mMarkdownLines = 0; - - mAboutActive = true; - mImprovActive = true; - mMarkdownActive = true; - - RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD); -} - - -bool generateNextDummyPage(const RsGxsMessageId &threadId, const int lines, const RsGxsGrpMsgIdPair &parentId, - const std::string *page_lines, const int num_pagelines, RsWikiSnapshot &snapshot) -{ - snapshot.mMeta.mGroupId = parentId.first; - - // Create an About Page. -#define NUM_SUB_PAGES 3 - - if ((lines % NUM_SUB_PAGES == 0) || (lines == num_pagelines)) - { - /* do a new baseline */ - snapshot.mMeta.mOrigMsgId = threadId; - } - else - { - snapshot.mMeta.mParentId = parentId.second; - snapshot.mMeta.mThreadId = threadId; - } - - std::string page; - for(int i = 0; (i < lines) && (i < num_pagelines); i++) - { - snapshot.mPage += page_lines[i]; - snapshot.mPage += '\n'; - } - - return (lines <= num_pagelines); -} - - -#include - -RsGxsId chooseRandomAuthorId() -{ - /* chose a random Id to sign with */ - std::list ownIds; - std::list::iterator it; - - rsIdentity->getOwnIds(ownIds); - - uint32_t idx = (uint32_t) (RSRandom::random_u32() % (int)ownIds.size()) ; - int i = 0; - for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); ++it, i++) ; - - return *it ; -} - - - -void p3Wiki::dummyTick() -{ - if (mAboutActive) - { - std::cerr << "p3Wiki::dummyTick() AboutActive"; - std::cerr << std::endl; - - uint32_t status = RsGenExchange::getTokenService()->requestStatus(mAboutToken); - - if (status == RsTokenService::COMPLETE) - { - std::cerr << "p3Wiki::dummyTick() AboutActive, Lines: " << mAboutLines; - std::cerr << std::endl; - - if (mAboutLines == 0) - { - /* get the group Id */ - RsGxsGroupId groupId; - if (!acknowledgeTokenGrp(mAboutToken, groupId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mAboutActive = false; - } - - /* create baseline snapshot */ - RsWikiSnapshot page; - page.mMeta.mGroupId = groupId; - page.mPage = "Baseline page... a placeholder for About Wiki"; - page.mMeta.mMsgName = "About RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - - submitSnapshot(mAboutToken, page); - mAboutLines++; - } - else - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mAboutToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mAboutActive = false; - } - - if (mAboutLines == 1) - { - mAboutThreadId = msgId.second; - } - - RsWikiSnapshot page; - page.mMeta.mMsgName = "About RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - if (!generateNextDummyPage(mAboutThreadId, mAboutLines, msgId, about_txt, about_len, page)) - { - std::cerr << "About Pages Done"; - std::cerr << std::endl; - mAboutActive = false; - } - else - { - mAboutLines++; - submitSnapshot(mAboutToken, page); - } - } - } - } - - if (mImprovActive) - { - std::cerr << "p3Wiki::dummyTick() ImprovActive"; - std::cerr << std::endl; - - uint32_t status = RsGenExchange::getTokenService()->requestStatus(mImprovToken); - - if (status == RsTokenService::COMPLETE) - { - std::cerr << "p3Wiki::dummyTick() ImprovActive, Lines: " << mImprovLines; - std::cerr << std::endl; - - if (mImprovLines == 0) - { - /* get the group Id */ - RsGxsGroupId groupId; - if (!acknowledgeTokenGrp(mImprovToken, groupId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mImprovActive = false; - } - - /* create baseline snapshot */ - RsWikiSnapshot page; - page.mMeta.mGroupId = groupId; - page.mPage = "Baseline page... a placeholder for Improv Wiki"; - page.mMeta.mMsgName = "Improv RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - - submitSnapshot(mImprovToken, page); - mImprovLines++; - } - else - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mImprovToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mImprovActive = false; - } - - if (mImprovLines == 1) - { - mImprovThreadId = msgId.second; - } - - RsWikiSnapshot page; - page.mMeta.mMsgName = "Improv RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - if (!generateNextDummyPage(mImprovThreadId, mImprovLines, msgId, improvements_txt, improvements_len, page)) - { - std::cerr << "Improv Pages Done"; - std::cerr << std::endl; - mImprovActive = false; - } - else - { - mImprovLines++; - submitSnapshot(mImprovToken, page); - } - } - } - } - - - if (mMarkdownActive) - { - std::cerr << "p3Wiki::dummyTick() MarkdownActive"; - std::cerr << std::endl; - - uint32_t status = RsGenExchange::getTokenService()->requestStatus(mMarkdownToken); - - if (status == RsTokenService::COMPLETE) - { - std::cerr << "p3Wiki::dummyTick() MarkdownActive, Lines: " << mMarkdownLines; - std::cerr << std::endl; - - if (mMarkdownLines == 0) - { - /* get the group Id */ - RsGxsGroupId groupId; - if (!acknowledgeTokenGrp(mMarkdownToken, groupId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mMarkdownActive = false; - } - - /* create baseline snapshot */ - RsWikiSnapshot page; - page.mMeta.mGroupId = groupId; - page.mPage = "Baseline page... a placeholder for Markdown Wiki"; - page.mMeta.mMsgName = "Markdown RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - - submitSnapshot(mMarkdownToken, page); - mMarkdownLines++; - } - else - { - /* get the msg Id, and generate next snapshot */ - RsGxsGrpMsgIdPair msgId; - if (!acknowledgeTokenMsg(mMarkdownToken, msgId)) - { - std::cerr << " ERROR "; - std::cerr << std::endl; - mMarkdownActive = false; - } - - if (mMarkdownLines == 1) - { - mMarkdownThreadId = msgId.second; - } - - RsWikiSnapshot page; - page.mMeta.mMsgName = "Markdown RsWiki"; - page.mMeta.mAuthorId = chooseRandomAuthorId(); - if (!generateNextDummyPage(mMarkdownThreadId, mMarkdownLines, msgId, markdown_txt, markdown_len, page)) - { - std::cerr << "Markdown Pages Done"; - std::cerr << std::endl; - mMarkdownActive = false; - } - else - { - mMarkdownLines++; - submitSnapshot(mMarkdownToken, page); - } - } - } - } - - if ((mAboutActive) || (mImprovActive) || (mMarkdownActive)) - { - /* reschedule next one */ - RsTickEvent::schedule_in(WIKI_EVENT_DUMMYTICK, DUMMYTICK_PERIOD); - } -} - - - - - - // Overloaded from RsTickEvent for Event callbacks. -void p3Wiki::handle_event(uint32_t event_type, const std::string &elabel) -{ - std::cerr << "p3Wiki::handle_event(" << event_type << ")"; - std::cerr << std::endl; - - // stuff. - switch(event_type) - { - case WIKI_EVENT_DUMMYSTART: - generateDummyData(); - break; - - case WIKI_EVENT_DUMMYTICK: - dummyTick(); - break; - - default: - /* error */ - std::cerr << "p3Wiki::handle_event() Unknown Event Type: " << event_type; - std::cerr << std::endl; - break; - } -} - - diff --git a/libretroshare/src/services/p3wiki.h b/libretroshare/src/services/p3wiki.h deleted file mode 100644 index a92aec795..000000000 --- a/libretroshare/src/services/p3wiki.h +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3wiki.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_WIKI_SERVICE_HEADER -#define P3_WIKI_SERVICE_HEADER - -#include "retroshare/rswiki.h" -#include "gxs/rsgenexchange.h" - -#include "util/rstickevent.h" - -#include -#include - -/* - * Wiki Service - * - * - */ - -class p3Wiki: public RsGenExchange, public RsWiki, - public RsTickEvent -{ -public: - p3Wiki(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs); -virtual RsServiceInfo getServiceInfo(); -static uint32_t wikiAuthenPolicy(); - -protected: - -virtual void notifyChanges(std::vector& changes) ; - - // Overloaded from RsTickEvent. -virtual void handle_event(uint32_t event_type, const std::string &elabel); - -public: - -virtual void service_tick(); - - /* Specific Service Data */ -virtual bool getCollections(const uint32_t &token, std::vector &collections) override; -virtual bool getSnapshots(const uint32_t &token, std::vector &snapshots) override; -virtual bool getComments(const uint32_t &token, std::vector &comments) override; - -virtual bool getRelatedSnapshots(const uint32_t &token, std::vector &snapshots) override; - -virtual bool submitCollection(uint32_t &token, RsWikiCollection &collection) override; -virtual bool submitSnapshot(uint32_t &token, RsWikiSnapshot &snapshot) override; -virtual bool submitComment(uint32_t &token, RsWikiComment &comment) override; - -virtual bool updateCollection(uint32_t &token, RsWikiCollection &collection) override; - -// Blocking Interfaces. -virtual bool createCollection(RsWikiCollection &collection) override; -virtual bool updateCollection(const RsWikiCollection &collection) override; -virtual bool getCollections(const std::list groupIds, std::vector &groups) override; - - private: - -std::string genRandomId(); -// RsMutex mWikiMtx; - - -virtual void generateDummyData(); - - // Dummy Stuff. - void dummyTick(); - - bool mAboutActive; - uint32_t mAboutToken; - int mAboutLines; - RsGxsMessageId mAboutThreadId; - - bool mImprovActive; - uint32_t mImprovToken; - int mImprovLines; - RsGxsMessageId mImprovThreadId; - - bool mMarkdownActive; - uint32_t mMarkdownToken; - int mMarkdownLines; - RsGxsMessageId mMarkdownThreadId; -}; - -#endif diff --git a/libretroshare/src/services/p3wire.cc b/libretroshare/src/services/p3wire.cc deleted file mode 100644 index 283e9a804..000000000 --- a/libretroshare/src/services/p3wire.cc +++ /dev/null @@ -1,1351 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3wire.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2020 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "services/p3wire.h" -#include "rsitems/rswireitems.h" - -#include "util/rsrandom.h" - -/**** - * #define WIRE_DEBUG 1 - ****/ - -RsWire *rsWire = NULL; - -RsWireGroup::RsWireGroup() - :mGroupPulses(0),mGroupRepublishes(0),mGroupLikes(0),mGroupReplies(0) - ,mRefMentions(0),mRefRepublishes(0),mRefLikes(0),mRefReplies(0) -{ - return; -} - -uint32_t RsWirePulse::ImageCount() -{ - uint32_t images = 0; - if (!mImage1.empty()) { - images++; - } - if (!mImage2.empty()) { - images++; - } - if (!mImage3.empty()) { - images++; - } - if (!mImage4.empty()) { - images++; - } - return images; -} - -p3Wire::p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs) - :RsGenExchange(gds, nes, new RsGxsWireSerialiser(), RS_SERVICE_GXS_TYPE_WIRE, gixs, wireAuthenPolicy()), - RsWire(static_cast(*this)), mWireMtx("WireMtx") -{ - -} - - -const std::string WIRE_APP_NAME = "gxswire"; -const uint16_t WIRE_APP_MAJOR_VERSION = 1; -const uint16_t WIRE_APP_MINOR_VERSION = 0; -const uint16_t WIRE_MIN_MAJOR_VERSION = 1; -const uint16_t WIRE_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3Wire::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_GXS_TYPE_WIRE, - WIRE_APP_NAME, - WIRE_APP_MAJOR_VERSION, - WIRE_APP_MINOR_VERSION, - WIRE_MIN_MAJOR_VERSION, - WIRE_MIN_MINOR_VERSION); -} - - - -uint32_t p3Wire::wireAuthenPolicy() -{ - uint32_t policy = 0; - uint8_t flag = 0; - - // Edits generally need an authors signature. - - // Wire requires all TopLevel (Orig/Reply) msgs to be signed with both PUBLISH & AUTHOR. - // Reply References need to be signed by Author. - flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; - flag |= GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS); - - // expect the requirements to be the same for RESTRICTED / PRIVATE groups too. - // This needs to be worked through / fully evaluated. - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS); - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS); - - flag = 0; - RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS); - - return policy; -} - -void p3Wire::service_tick() -{ - return; -} - -RsTokenService* p3Wire::getTokenService() { - - return RsGenExchange::getTokenService(); -} - -void p3Wire::notifyChanges(std::vector& /*changes*/) -{ - std::cerr << "p3Wire::notifyChanges() New stuff"; - std::cerr << std::endl; -} - - /* Specific Service Data */ -bool p3Wire::getGroupData(const uint32_t &token, std::vector &groups) -{ - std::cerr << "p3Wire::getGroupData()"; - std::cerr << std::endl; - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsWireGroupItem* item = dynamic_cast(*vit); - - if (item) - { - RsWireGroup group = item->group; - group.mMeta = item->meta; - delete item; - groups.push_back(group); - - std::cerr << "p3Wire::getGroupData() Adding WireGroup to Vector: "; - std::cerr << std::endl; - std::cerr << group; - std::cerr << std::endl; - } - else - { - std::cerr << "Not a WireGroupItem, deleting!" << std::endl; - delete *vit; - } - - } - } - return ok; -} - -bool p3Wire::getGroupPtrData(const uint32_t &token, std::map &groups) -{ - std::cerr << "p3Wire::getGroupPtrData()"; - std::cerr << std::endl; - - std::vector grpData; - bool ok = RsGenExchange::getGroupData(token, grpData); - - if(ok) - { - std::vector::iterator vit = grpData.begin(); - - for(; vit != grpData.end(); ++vit) - { - RsGxsWireGroupItem* item = dynamic_cast(*vit); - - if (item) - { - RsWireGroupSPtr pGroup = std::make_shared(item->group); - pGroup->mMeta = item->meta; - delete item; - - groups[pGroup->mMeta.mGroupId] = pGroup; - - std::cerr << "p3Wire::getGroupPtrData() Adding WireGroup to Vector: "; - std::cerr << pGroup->mMeta.mGroupId.toStdString(); - std::cerr << std::endl; - } - else - { - std::cerr << "Not a WireGroupItem, deleting!" << std::endl; - delete *vit; - } - - } - } - return ok; -} - - -bool p3Wire::getPulseData(const uint32_t &token, std::vector &pulses) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsWirePulseItem* item = dynamic_cast(*vit); - - if(item) - { - RsWirePulse pulse = item->pulse; - pulse.mMeta = item->meta; - pulses.push_back(pulse); - delete item; - } - else - { - std::cerr << "Not a WirePulse Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - return ok; -} - -bool p3Wire::getPulsePtrData(const uint32_t &token, std::list &pulses) -{ - GxsMsgDataMap msgData; - bool ok = RsGenExchange::getMsgData(token, msgData); - - if(ok) - { - GxsMsgDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsWirePulseItem* item = dynamic_cast(*vit); - - if(item) - { - RsWirePulseSPtr pPulse = std::make_shared(item->pulse); - pPulse->mMeta = item->meta; - pulses.push_back(pPulse); - delete item; - } - else - { - std::cerr << "Not a WirePulse Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - return ok; -} - -bool p3Wire::getRelatedPulseData(const uint32_t &token, std::vector &pulses) -{ - GxsMsgRelatedDataMap msgData; - std::cerr << "p3Wire::getRelatedPulseData()"; - std::cerr << std::endl; - bool ok = RsGenExchange::getMsgRelatedData(token, msgData); - - if (ok) - { - std::cerr << "p3Wire::getRelatedPulseData() is OK"; - std::cerr << std::endl; - GxsMsgRelatedDataMap::iterator mit = msgData.begin(); - - for(; mit != msgData.end(); ++mit) - { - std::vector& msgItems = mit->second; - std::vector::iterator vit = msgItems.begin(); - - for(; vit != msgItems.end(); ++vit) - { - RsGxsWirePulseItem* item = dynamic_cast(*vit); - - if(item) - { - RsWirePulse pulse = item->pulse; - pulse.mMeta = item->meta; - pulses.push_back(pulse); - delete item; - } - else - { - std::cerr << "Not a WirePulse Item, deleting!" << std::endl; - delete *vit; - } - } - } - } - else - { - std::cerr << "p3Wire::getRelatedPulseData() is NOT OK"; - std::cerr << std::endl; - } - - return ok; -} - - -bool p3Wire::createGroup(uint32_t &token, RsWireGroup &group) -{ - RsGxsWireGroupItem* groupItem = new RsGxsWireGroupItem(); - groupItem->group = group; - groupItem->meta = group.mMeta; - - std::cerr << "p3Wire::createGroup(): "; - std::cerr << std::endl; - std::cerr << group; - std::cerr << std::endl; - - std::cerr << "p3Wire::createGroup() pushing to RsGenExchange"; - std::cerr << std::endl; - - RsGenExchange::publishGroup(token, groupItem); - return true; -} - - -bool p3Wire::createPulse(uint32_t &token, RsWirePulse &pulse) -{ - std::cerr << "p3Wire::createPulse(): " << pulse; - std::cerr << std::endl; - - RsGxsWirePulseItem* pulseItem = new RsGxsWirePulseItem(); - pulseItem->pulse = pulse; - pulseItem->meta = pulse.mMeta; - - RsGenExchange::publishMsg(token, pulseItem); - return true; -} - -// Blocking Interfaces. -bool p3Wire::createGroup(RsWireGroup &group) -{ - uint32_t token; - return createGroup(token, group) && waitToken(token) == RsTokenService::COMPLETE; -} - -bool p3Wire::updateGroup(const RsWireGroup & /*group*/) -{ - // TODO - return false; -} - -bool p3Wire::getGroups(const std::list groupIds, std::vector &groups) -{ - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if (groupIds.empty()) - { - if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - { - return false; - } - } - else - { - if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE ) - { - return false; - } - } - return getGroupData(token, groups) && !groups.empty(); -} - - -std::ostream &operator<<(std::ostream &out, const RsWireGroup &group) -{ - out << "RsWireGroup [ "; - out << " Name: " << group.mMeta.mGroupName; - out << " Tagline: " << group.mTagline; - out << " Location: " << group.mLocation; - out << " ]"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsWirePulse &pulse) -{ - out << "RsWirePulse [ "; - out << "Title: " << pulse.mMeta.mMsgName; - out << "PulseText: " << pulse.mPulseText; - out << "]"; - return out; -} - -/***** FOR TESTING *****/ - -std::string p3Wire::genRandomId() -{ - std::string randomId; - for(int i = 0; i < 20; i++) - { - randomId += (char) ('a' + (RSRandom::random_u32() % 26)); - } - - return randomId; -} - -void p3Wire::generateDummyData() -{ - -} - - -// New Interfaces. -bool p3Wire::fetchPulse(RsGxsGroupId grpId, RsGxsMessageId msgId, RsWirePulseSPtr &pPulse) -{ - std::cerr << "p3Wire::fetchPulse(" << grpId << ", " << msgId << ") waiting for token"; - std::cerr << std::endl; - - uint32_t token; - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST; - - GxsMsgReq ids; - std::set &set_msgIds = ids[grpId]; - set_msgIds.insert(msgId); - - getTokenService()->requestMsgInfo( - token, RS_TOKREQ_ANSTYPE_DATA, opts, ids); - } - - // wait for pulse request to completed. - std::cerr << "p3Wire::fetchPulse() waiting for token"; - std::cerr << std::endl; - - int result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::fetchPulse() token FAILED, result: " << result; - std::cerr << std::endl; - return false; - } - - // retrieve Pulse. - std::cerr << "p3Wire::fetchPulse() retrieving token"; - std::cerr << std::endl; - { - bool okay = true; - std::vector pulses; - if (getPulseData(token, pulses)) { - if (pulses.size() == 1) { - // save to output pulse. - pPulse = std::make_shared(pulses[0]); - std::cerr << "p3Wire::fetchPulse() retrieved token: " << *pPulse; - std::cerr << std::endl; - std::cerr << "p3Wire::fetchPulse() ANS GrpId: " << pPulse->mMeta.mGroupId; - std::cerr << " MsgId: " << pPulse->mMeta.mMsgId; - std::cerr << " OrigMsgId: " << pPulse->mMeta.mOrigMsgId; - std::cerr << std::endl; - } else { - std::cerr << "p3Wire::fetchPulse() ERROR multiple pulses"; - std::cerr << std::endl; - okay = false; - } - } else { - std::cerr << "p3Wire::fetchPulse() ERROR failed to retrieve token"; - std::cerr << std::endl; - okay = false; - } - - if (!okay) { - std::cerr << "p3Wire::fetchPulse() tokenPulse ERROR"; - std::cerr << std::endl; - // TODO cancel other request. - return false; - } - } - return true; -} - -// New Interfaces. -bool p3Wire::createOriginalPulse(const RsGxsGroupId &grpId, RsWirePulseSPtr pPulse) -{ - // request Group. - std::list groupIds = { grpId }; - std::vector groups; - bool groupOkay = getGroups(groupIds, groups); - if (!groupOkay) { - std::cerr << "p3Wire::createOriginalPulse() getGroups failed"; - std::cerr << std::endl; - return false; - } - - if (groups.size() != 1) { - std::cerr << "p3Wire::createOriginalPulse() getGroups invalid size"; - std::cerr << std::endl; - return false; - } - - // ensure Group is suitable. - RsWireGroup group = groups[0]; - if ((group.mMeta.mGroupId != grpId) || - (!(group.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))) - { - std::cerr << "p3Wire::createOriginalPulse() Group unsuitable"; - std::cerr << std::endl; - return false; - } - - // Create Msg. - // Start fresh, just to be sure nothing dodgy happens in UX world. - RsWirePulse pulse; - - pulse.mMeta.mGroupId = group.mMeta.mGroupId; - pulse.mMeta.mAuthorId = group.mMeta.mAuthorId; - pulse.mMeta.mThreadId.clear(); - pulse.mMeta.mParentId.clear(); - pulse.mMeta.mOrigMsgId.clear(); - - // copy info over - pulse.mPulseType = WIRE_PULSE_TYPE_ORIGINAL; - pulse.mSentiment = pPulse->mSentiment; - pulse.mPulseText = pPulse->mPulseText; - pulse.mImage1 = pPulse->mImage1; - pulse.mImage2 = pPulse->mImage2; - pulse.mImage3 = pPulse->mImage3; - pulse.mImage4 = pPulse->mImage4; - - // all mRefs should empty. - - uint32_t token; - createPulse(token, pulse); - - int result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::createOriginalPulse() Failed to create Pulse"; - std::cerr << std::endl; - return false; - } - - return true; -} - -bool p3Wire::createReplyPulse(RsGxsGroupId grpId, RsGxsMessageId msgId, RsGxsGroupId replyWith, uint32_t reply_type, RsWirePulseSPtr pPulse) -{ - // check reply_type. can only be ONE. - if (!((reply_type == WIRE_PULSE_TYPE_REPLY) || - (reply_type == WIRE_PULSE_TYPE_REPUBLISH) || - (reply_type == WIRE_PULSE_TYPE_LIKE))) - { - std::cerr << "p3Wire::createReplyPulse() reply_type is invalid"; - std::cerr << std::endl; - return false; - } - - // request both groups. - std::list groupIds = { grpId, replyWith }; - std::vector groups; - bool groupOkay = getGroups(groupIds, groups); - if (!groupOkay) { - std::cerr << "p3Wire::createReplyPulse() getGroups failed"; - std::cerr << std::endl; - return false; - } - - // extract group info. - RsWireGroup replyToGroup; - RsWireGroup replyWithGroup; - - if (grpId == replyWith) - { - if (groups.size() != 1) { - std::cerr << "p3Wire::createReplyPulse() getGroups != 1"; - std::cerr << std::endl; - return false; - } - - replyToGroup = groups[0]; - replyWithGroup = groups[0]; - } - else - { - if (groups.size() != 2) { - std::cerr << "p3Wire::createReplyPulse() getGroups != 2"; - std::cerr << std::endl; - return false; - } - - if (groups[0].mMeta.mGroupId == grpId) { - replyToGroup = groups[0]; - replyWithGroup = groups[1]; - } else { - replyToGroup = groups[1]; - replyWithGroup = groups[0]; - } - } - - // check groupIds match - if ((replyToGroup.mMeta.mGroupId != grpId) || - (replyWithGroup.mMeta.mGroupId != replyWith)) - { - std::cerr << "p3Wire::createReplyPulse() groupid mismatch"; - std::cerr << std::endl; - return false; - } - - // ensure Group is suitable. - if ((!(replyToGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)) || - (!(replyWithGroup.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH))) - { - std::cerr << "p3Wire::createReplyPulse() Group unsuitable"; - std::cerr << std::endl; - return false; - } - - // ********************************************************** - RsWirePulseSPtr replyToPulse; - if (!fetchPulse(grpId, msgId, replyToPulse)) - { - std::cerr << "p3Wire::createReplyPulse() fetchPulse FAILED"; - std::cerr << std::endl; - return false; - } - - // create Reply Msg. - RsWirePulse responsePulse; - - responsePulse.mMeta.mGroupId = replyWithGroup.mMeta.mGroupId; - responsePulse.mMeta.mAuthorId = replyWithGroup.mMeta.mAuthorId; - responsePulse.mMeta.mThreadId.clear(); - responsePulse.mMeta.mParentId.clear(); - responsePulse.mMeta.mOrigMsgId.clear(); - - responsePulse.mPulseType = WIRE_PULSE_TYPE_RESPONSE | reply_type; - responsePulse.mSentiment = pPulse->mSentiment; - responsePulse.mPulseText = pPulse->mPulseText; - responsePulse.mImage1 = pPulse->mImage1; - responsePulse.mImage2 = pPulse->mImage2; - responsePulse.mImage3 = pPulse->mImage3; - responsePulse.mImage4 = pPulse->mImage4; - - // mRefs refer to parent post. - responsePulse.mRefGroupId = replyToPulse->mMeta.mGroupId; - responsePulse.mRefGroupName = replyToGroup.mMeta.mGroupName; - responsePulse.mRefOrigMsgId = replyToPulse->mMeta.mOrigMsgId; - responsePulse.mRefAuthorId = replyToPulse->mMeta.mAuthorId; - responsePulse.mRefPublishTs = replyToPulse->mMeta.mPublishTs; - responsePulse.mRefPulseText = replyToPulse->mPulseText; - responsePulse.mRefImageCount = replyToPulse->ImageCount(); - - std::cerr << "p3Wire::createReplyPulse() create Response Pulse"; - std::cerr << std::endl; - - uint32_t token; - if (!createPulse(token, responsePulse)) - { - std::cerr << "p3Wire::createReplyPulse() FAILED to create Response Pulse"; - std::cerr << std::endl; - return false; - } - - int result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::createReplyPulse() FAILED(2) to create Response Pulse"; - std::cerr << std::endl; - return false; - } - - // get MsgId. - std::pair responsePair; - if (!acknowledgeMsg(token, responsePair)) - { - std::cerr << "p3Wire::createReplyPulse() FAILED acknowledgeMsg for Response Pulse"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3Wire::createReplyPulse() Response Pulse ID: ("; - std::cerr << responsePair.first.toStdString() << ", "; - std::cerr << responsePair.second.toStdString() << ")"; - std::cerr << std::endl; - - // retrieve newly generated message. - // ********************************************************** - RsWirePulseSPtr createdResponsePulse; - if (!fetchPulse(responsePair.first, responsePair.second, createdResponsePulse)) - { - std::cerr << "p3Wire::createReplyPulse() fetch createdReponsePulse FAILED"; - std::cerr << std::endl; - return false; - } - - /* Check that pulses is created properly */ - if ((createdResponsePulse->mMeta.mGroupId != responsePulse.mMeta.mGroupId) || - (createdResponsePulse->mPulseText != responsePulse.mPulseText) || - (createdResponsePulse->mRefGroupId != responsePulse.mRefGroupId) || - (createdResponsePulse->mRefOrigMsgId != responsePulse.mRefOrigMsgId)) - { - std::cerr << "p3Wire::createReplyPulse() fetch createdReponsePulse FAILED"; - std::cerr << std::endl; - return false; - } - - // create ReplyTo Ref Msg. - std::cerr << "PulseAddDialog::postRefPulse() create Reference!"; - std::cerr << std::endl; - - // Reference Pulse. posted on Parent's Group. - RsWirePulse refPulse; - - refPulse.mMeta.mGroupId = replyToPulse->mMeta.mGroupId; - refPulse.mMeta.mAuthorId = replyWithGroup.mMeta.mAuthorId; // own author Id. - refPulse.mMeta.mThreadId = replyToPulse->mMeta.mOrigMsgId; - refPulse.mMeta.mParentId = replyToPulse->mMeta.mOrigMsgId; - refPulse.mMeta.mOrigMsgId.clear(); - - refPulse.mPulseType = WIRE_PULSE_TYPE_REFERENCE | reply_type; - refPulse.mSentiment = 0; // should this be =? createdResponsePulse->mSentiment; - - // Dont put parent PulseText into refPulse - it is available on Thread Msg. - // otherwise gives impression it is correctly setup Parent / Reply... - // when in fact the parent PublishTS, and AuthorId are wrong. - refPulse.mPulseText = ""; - - // refs refer back to own Post. - refPulse.mRefGroupId = replyWithGroup.mMeta.mGroupId; - refPulse.mRefGroupName = replyWithGroup.mMeta.mGroupName; - refPulse.mRefOrigMsgId = createdResponsePulse->mMeta.mOrigMsgId; - refPulse.mRefAuthorId = replyWithGroup.mMeta.mAuthorId; - refPulse.mRefPublishTs = createdResponsePulse->mMeta.mPublishTs; - refPulse.mRefPulseText = createdResponsePulse->mPulseText; - refPulse.mRefImageCount = createdResponsePulse->ImageCount(); - - // publish Ref Msg. - if (!createPulse(token, refPulse)) - { - std::cerr << "p3Wire::createReplyPulse() FAILED to create Ref Pulse"; - std::cerr << std::endl; - return false; - } - - result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::createReplyPulse() FAILED(2) to create Ref Pulse"; - std::cerr << std::endl; - return false; - } - - // get MsgId. - std::pair refPair; - if (!acknowledgeMsg(token, refPair)) - { - std::cerr << "p3Wire::createReplyPulse() FAILED acknowledgeMsg for Ref Pulse"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3Wire::createReplyPulse() Success: Ref Pulse ID: ("; - std::cerr << refPair.first.toStdString() << ", "; - std::cerr << refPair.second.toStdString() << ")"; - std::cerr << std::endl; - - return true; -} - - - // Blocking, request structures for display. -#if 0 -bool p3Wire::createReplyPulse(uint32_t &token, RsWirePulse &pulse) -{ - - return true; -} - -bool p3Wire::createRepublishPulse(uint32_t &token, RsWirePulse &pulse) -{ - - return true; -} - -bool p3Wire::createLikePulse(uint32_t &token, RsWirePulse &pulse) -{ - - return true; -} -#endif - - // WireGroup Details. -bool p3Wire::getWireGroup(const RsGxsGroupId &groupId, RsWireGroupSPtr &grp) -{ - std::list groupIds = { groupId }; - std::map groups; - if (!fetchGroupPtrs(groupIds, groups)) - { - std::cerr << "p3Wire::getWireGroup() failed to fetchGroupPtrs"; - std::cerr << std::endl; - return false; - } - - if (groups.size() != 1) - { - std::cerr << "p3Wire::getWireGroup() invalid group size"; - std::cerr << std::endl; - return false; - } - - grp = groups.begin()->second; - - // TODO Should fill in Counters of pulses/likes/republishes/replies - return true; -} - -// TODO Remove duplicate ... -bool p3Wire::getWirePulse(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, RsWirePulseSPtr &pPulse) -{ - return fetchPulse(groupId, msgId, pPulse); -} - - - - -bool compare_time(const RsWirePulseSPtr& first, const RsWirePulseSPtr &second) -{ - return first->mMeta.mPublishTs > second->mMeta.mPublishTs; -} - - // should this filter them in some way? - // date, or count would be more likely. -bool p3Wire::getPulsesForGroups(const std::list &groupIds, std::list &pulsePtrs) -{ - // request all the pulses (Top-Level Thread Msgs). - std::cerr << "p3Wire::getPulsesForGroups()"; - std::cerr << std::endl; - - uint32_t token; - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD; - - getTokenService()->requestMsgInfo( - token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds); - } - - // wait for pulse request to completed. - std::cerr << "p3Wire::getPulsesForGroups() waiting for token"; - std::cerr << std::endl; - - int result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::getPulsesForGroups() token FAILED, result: " << result; - std::cerr << std::endl; - return false; - } - - // retrieve Pulses. - std::cerr << "p3Wire::getPulsesForGroups() retrieving token"; - std::cerr << std::endl; - if (!getPulsePtrData(token, pulsePtrs)) - { - std::cerr << "p3Wire::getPulsesForGroups() tokenPulse ERROR"; - std::cerr << std::endl; - return false; - } - - std::cerr << "p3Wire::getPulsesForGroups() size = " << pulsePtrs.size(); - std::cerr << std::endl; - { - std::list::iterator it; - for (it = pulsePtrs.begin(); it != pulsePtrs.end(); it++) - { - std::cerr << "p3Wire::getPulsesForGroups() Flags: "; - std::cerr << (*it)->mPulseType << " Msg: " << (*it)->mPulseText; - std::cerr << std::endl; - } - } - - std::cerr << "p3Wire::getPulsesForGroups() size = " << pulsePtrs.size(); - std::cerr << " sorting and trimming"; - std::cerr << std::endl; - - // sort and filter list. - pulsePtrs.sort(compare_time); - - // trim to N max. - uint32_t N = 10; - if (pulsePtrs.size() > N) { - pulsePtrs.resize(N); - } - - // for each fill in details. - std::list::iterator it; - for (it = pulsePtrs.begin(); it != pulsePtrs.end(); it++) - { - if (!updatePulse(*it, 1)) - { - std::cerr << "p3Wire::getPulsesForGroups() Failed to updatePulse"; - std::cerr << std::endl; - return false; - } - } - - // update GroupPtrs for all pulsePtrs. - if (!updateGroups(pulsePtrs)) - { - std::cerr << "p3Wire::getPulsesForGroups() failed to updateGroups"; - std::cerr << std::endl; - return false; - } - - return true; -} - - -bool p3Wire::getPulseFocus(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, int /* type */, RsWirePulseSPtr &pPulse) -{ - std::cerr << "p3Wire::getPulseFocus("; - std::cerr << "grpId: " << groupId << " msgId: " << msgId; - std::cerr << " )"; - std::cerr << std::endl; - - if (!fetchPulse(groupId, msgId, pPulse)) - { - std::cerr << "p3Wire::getPulseFocus() failed to fetch Pulse"; - std::cerr << std::endl; - return false; - } - - if (!updatePulse(pPulse, 3)) - { - std::cerr << "p3Wire::getPulseFocus() failed to update Pulse"; - std::cerr << std::endl; - return false; - } - - /* Fill in GroupPtrs */ - std::list pulsePtrs; - pulsePtrs.push_back(pPulse); - - if (!updateGroups(pulsePtrs)) - { - std::cerr << "p3Wire::getPulseFocus() failed to updateGroups"; - std::cerr << std::endl; - return false; - } - - return true; -} - - -// function to update a pulse with the (Ref) child with actual data. -bool p3Wire::updatePulse(RsWirePulseSPtr pPulse, int levels) -{ - bool okay = true; - - // setup logging label. - std::ostringstream out; - out << "pulse[" << (void *) pPulse.get() << "], " << levels; - std::string label = out.str(); - - std::cerr << "p3Wire::updatePulse(" << label << ") starting"; - std::cerr << std::endl; - - // is pPulse is a REF, then request the original. - // if no original available the done. - if (pPulse->mPulseType & WIRE_PULSE_TYPE_REFERENCE) - { - RsWirePulseSPtr fullPulse; - std::cerr << "p3Wire::updatePulse(" << label << ") fetching REF ("; - std::cerr << "grpId: " << pPulse->mRefGroupId << " msgId: " << pPulse->mRefOrigMsgId; - std::cerr << " )"; - std::cerr << std::endl; - if (!fetchPulse(pPulse->mRefGroupId, pPulse->mRefOrigMsgId, fullPulse)) - { - std::cerr << "p3Wire::updatePulse(" << label << ") failed to fetch REF"; - std::cerr << std::endl; - return false; - } - std::cerr << "p3Wire::updatePulse(" << label << ") replacing REF"; - std::cerr << std::endl; - - *pPulse = *fullPulse; - } - - // Request children: (Likes / Retweets / Replies) - std::cerr << "p3Wire::updatePulse(" << label << ") requesting children"; - std::cerr << std::endl; - - uint32_t token; - { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - // OR opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT; - opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD; - - std::vector msgIds = { - std::make_pair(pPulse->mMeta.mGroupId, pPulse->mMeta.mOrigMsgId) - }; - - getTokenService()->requestMsgRelatedInfo( - token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds); - } - - // wait for request to complete - std::cerr << "p3Wire::updatePulse(" << label << ") waiting for token"; - std::cerr << std::endl; - - int result = waitToken(token); - if (result != RsTokenService::COMPLETE) - { - std::cerr << "p3Wire::updatePulse(" << label << ") token FAILED, result: " << result; - std::cerr << std::endl; - return false; - } - - /* load children */ - okay = updatePulseChildren(pPulse, token); - if (!okay) - { - std::cerr << "p3Wire::updatePulse(" << label << ") FAILED to update Children"; - std::cerr << std::endl; - return false; - } - - /* if down to last level, no need to updateChildren */ - if (levels <= 1) - { - std::cerr << "p3Wire::updatePulse(" << label << ") Level <= 1 finished"; - std::cerr << std::endl; - return okay; - } - - /* recursively update children */ - std::cerr << "p3Wire::updatePulse(" << label << ") updating children recursively"; - std::cerr << std::endl; - std::list::iterator it; - for (it = pPulse->mReplies.begin(); it != pPulse->mReplies.end(); it++) - { - bool childOkay = updatePulse(*it, levels - 1); - if (!childOkay) { - std::cerr << "p3Wire::updatePulse(" << label << ") update children (reply) failed"; - std::cerr << std::endl; - } - } - - for (it = pPulse->mRepublishes.begin(); it != pPulse->mRepublishes.end(); it++) - { - bool childOkay = updatePulse(*it, levels - 1); - if (!childOkay) { - std::cerr << "p3Wire::updatePulse(" << label << ") update children (repub) failed"; - std::cerr << std::endl; - } - } - - return okay; -} - - -// function to update the (Ref) child with actual data. -bool p3Wire::updatePulseChildren(RsWirePulseSPtr pParent, uint32_t token) -{ - { - bool okay = true; - std::vector pulses; - if (getRelatedPulseData(token, pulses)) { - std::vector::iterator it; - for (it = pulses.begin(); it != pulses.end(); it++) - { - std::cerr << "p3Wire::updatePulseChildren() retrieved child: " << *it; - std::cerr << std::endl; - - RsWirePulseSPtr pPulse = std::make_shared(*it); - // switch on type. - if (it->mPulseType & WIRE_PULSE_TYPE_LIKE) { - pParent->mLikes.push_back(pPulse); - std::cerr << "p3Wire::updatePulseChildren() adding Like"; - std::cerr << std::endl; - } - else if (it->mPulseType & WIRE_PULSE_TYPE_REPUBLISH) { - pParent->mRepublishes.push_back(pPulse); - std::cerr << "p3Wire::updatePulseChildren() adding Republish"; - std::cerr << std::endl; - } - else if (it->mPulseType & WIRE_PULSE_TYPE_REPLY) { - pParent->mReplies.push_back(pPulse); - std::cerr << "p3Wire::updatePulseChildren() adding Reply"; - std::cerr << std::endl; - } - else { - std::cerr << "p3Wire::updatePulseChildren() unknown child type: " << it->mPulseType; - std::cerr << std::endl; - } - } - } else { - std::cerr << "p3Wire::updatePulseChildren() ERROR failed to retrieve token"; - std::cerr << std::endl; - okay = false; - } - - if (!okay) { - std::cerr << "p3Wire::updatePulseChildren() token ERROR"; - std::cerr << std::endl; - } - return okay; - } -} - -/* High-level utility function to update mGroupPtr / mRefGroupPtr links. - * fetches associated groups and reference them from pulses - * - * extractGroupIds (owner + refs). - * fetch all available GroupIDs. (just IDs - so light). - * do intersection of IDs. - * apply IDs. - */ - -bool p3Wire::updateGroups(std::list &pulsePtrs) -{ - std::set pulseGroupIds; - - std::list::iterator it; - for (it = pulsePtrs.begin(); it != pulsePtrs.end(); it++) - { - if (!extractGroupIds(*it, pulseGroupIds)) - { - std::cerr << "p3Wire::updateGroups() failed to extractGroupIds"; - std::cerr << std::endl; - return false; - } - } - - std::list availGroupIds; - if (!trimToAvailGroupIds(pulseGroupIds, availGroupIds)) - { - std::cerr << "p3Wire::updateGroups() failed to trimToAvailGroupIds"; - std::cerr << std::endl; - return false; - } - - std::map groups; - if (!fetchGroupPtrs(availGroupIds, groups)) - { - std::cerr << "p3Wire::updateGroups() failed to fetchGroupPtrs"; - std::cerr << std::endl; - return false; - } - - for (it = pulsePtrs.begin(); it != pulsePtrs.end(); it++) - { - if (!updateGroupPtrs(*it, groups)) - { - std::cerr << "p3Wire::updateGroups() failed to updateGroupPtrs"; - std::cerr << std::endl; - return false; - } - } - return true; -} - - -// this function doesn't depend on p3Wire, could make static. -bool p3Wire::extractGroupIds(RsWirePulseConstSPtr pPulse, std::set &groupIds) -{ - std::cerr << "p3Wire::extractGroupIds()"; - std::cerr << std::endl; - - if (!pPulse) { - std::cerr << "p3Wire::extractGroupIds() INVALID pPulse"; - std::cerr << std::endl; - return false; - } - - // install own groupId. - groupIds.insert(pPulse->mMeta.mGroupId); - - /* do this recursively */ - if (pPulse->mPulseType & WIRE_PULSE_TYPE_REFERENCE) { - // REPLY: mRefGroupId, PARENT was in mMeta.mGroupId. - groupIds.insert(pPulse->mRefGroupId); - /* skipping */ - return true; - } - - - if (pPulse->mPulseType & WIRE_PULSE_TYPE_RESPONSE) { - // REPLY: meta.mGroupId, PARENT: mRefGroupId - groupIds.insert(pPulse->mRefGroupId); - } - - /* iterate through children, recursively */ - std::list::const_iterator it; - for (it = pPulse->mReplies.begin(); it != pPulse->mReplies.end(); it++) - { - bool childOkay = extractGroupIds(*it, groupIds); - if (!childOkay) { - std::cerr << "p3Wire::extractGroupIds() update children (reply) failed"; - std::cerr << std::endl; - return false; - } - } - - for (it = pPulse->mRepublishes.begin(); it != pPulse->mRepublishes.end(); it++) - { - bool childOkay = extractGroupIds(*it, groupIds); - if (!childOkay) { - std::cerr << "p3Wire::extractGroupIds() update children (repub) failed"; - std::cerr << std::endl; - return false; - } - } - - // not bothering with LIKEs at the moment. TODO. - return true; -} - -bool p3Wire::updateGroupPtrs(RsWirePulseSPtr pPulse, const std::map &groups) -{ - std::map::const_iterator git; - git = groups.find(pPulse->mMeta.mGroupId); - if (git == groups.end()) { - // error - return false; - } - - pPulse->mGroupPtr = git->second; - - // if REF, fill in mRefGroupPtr based on mRefGroupId. - if (pPulse->mPulseType & WIRE_PULSE_TYPE_REFERENCE) { - // if RefGroupId is in list, fill in. No error if its not there. - std::map::const_iterator rgit; - rgit = groups.find(pPulse->mRefGroupId); - if (rgit != groups.end()) { - pPulse->mRefGroupPtr = rgit->second; - } - - // no children for REF pulse, so can return now. - return true; - } - - // if Response, fill in mRefGroupPtr based on mRefGroupId. - if (pPulse->mPulseType & WIRE_PULSE_TYPE_RESPONSE) { - // if RefGroupId is in list, fill in. No error if its not there. - std::map::const_iterator rgit; - rgit = groups.find(pPulse->mRefGroupId); - if (rgit != groups.end()) { - pPulse->mRefGroupPtr = rgit->second; - } - // do children as well. - } - - /* recursively apply to children */ - std::list::iterator it; - for (it = pPulse->mReplies.begin(); it != pPulse->mReplies.end(); it++) - { - bool childOkay = updateGroupPtrs(*it, groups); - if (!childOkay) { - std::cerr << "p3Wire::updateGroupPtrs() update children (reply) failed"; - std::cerr << std::endl; - return false; - } - } - - for (it = pPulse->mRepublishes.begin(); it != pPulse->mRepublishes.end(); it++) - { - bool childOkay = updateGroupPtrs(*it, groups); - if (!childOkay) { - std::cerr << "p3Wire::updateGroupPtrs() update children (repub) failed"; - std::cerr << std::endl; - return false; - } - } - - // not bothering with LIKEs at the moment. TODO. - return true; -} - -bool p3Wire::trimToAvailGroupIds(const std::set &pulseGroupIds, - std::list &availGroupIds) -{ - /* request all groupIds */ - std::cerr << "p3Wire::trimToAvailGroupIds()"; - std::cerr << std::endl; - - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - - if (!requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) - { - std::cerr << "p3Wire::trimToAvailGroupIds() failed to fetch groups"; - std::cerr << std::endl; - return false; - } - - std::list localGroupIds; - if (!RsGenExchange::getGroupList(token, localGroupIds)) - { - std::cerr << "p3Wire::trimToAvailGroupIds() failed to get GroupIds"; - std::cerr << std::endl; - return false; - } - - /* do intersection between result ^ pulseGroups -> availGroupIds */ - std::set_intersection(localGroupIds.begin(), localGroupIds.end(), - pulseGroupIds.begin(), pulseGroupIds.end(), - std::back_inserter(availGroupIds)); - - return true; -} - -bool p3Wire::fetchGroupPtrs(const std::list &groupIds, - std::map &groups) -{ - std::cerr << "p3Wire::fetchGroupPtrs()"; - std::cerr << std::endl; - - uint32_t token; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - if (!requestGroupInfo(token, opts, groupIds) || waitToken(token) != RsTokenService::COMPLETE ) - { - std::cerr << "p3Wire::fetchGroupPtrs() failed to fetch groups"; - std::cerr << std::endl; - return false; - } - return getGroupPtrData(token, groups); -} - diff --git a/libretroshare/src/services/p3wire.h b/libretroshare/src/services/p3wire.h deleted file mode 100644 index 2e7375578..000000000 --- a/libretroshare/src/services/p3wire.h +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * libretroshare/src/services: p3wire.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2020 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef P3_WIRE_SERVICE_HEADER -#define P3_WIRE_SERVICE_HEADER - -#include "retroshare/rswire.h" -#include "gxs/rsgenexchange.h" - -#include -#include - -/* - * Wire Service - * - * - */ - -class p3Wire: public RsGenExchange, public RsWire -{ -public: - p3Wire(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs *gixs); - virtual RsServiceInfo getServiceInfo(); - static uint32_t wireAuthenPolicy(); - -protected: - virtual void notifyChanges(std::vector& changes) ; - -public: - virtual void service_tick(); - - virtual RsTokenService* getTokenService(); - - /* Specific Service Data */ - virtual bool getGroupData(const uint32_t &token, std::vector &groups) override; - virtual bool getPulseData(const uint32_t &token, std::vector &pulses) override; - - virtual bool createGroup(uint32_t &token, RsWireGroup &group) override; - virtual bool createPulse(uint32_t &token, RsWirePulse &pulse) override; - - // Blocking Interfaces. - virtual bool createGroup(RsWireGroup &group) override; - virtual bool updateGroup(const RsWireGroup &group) override; - virtual bool getGroups(const std::list grpIds, std::vector &groups) override; - - // New Interfaces. - // Blocking, request structures for display. - virtual bool createOriginalPulse(const RsGxsGroupId &grpId, RsWirePulseSPtr pPulse) override; - virtual bool createReplyPulse(RsGxsGroupId grpId, RsGxsMessageId msgId, - RsGxsGroupId replyWith, uint32_t reply_type, - RsWirePulseSPtr pPulse) override; - -#if 0 - virtual bool createReplyPulse(uint32_t &token, RsWirePulse &pulse) override; - virtual bool createRepublishPulse(uint32_t &token, RsWirePulse &pulse) override; - virtual bool createLikePulse(uint32_t &token, RsWirePulse &pulse) override; -#endif - - virtual bool getWireGroup(const RsGxsGroupId &groupId, RsWireGroupSPtr &grp) override; - virtual bool getWirePulse(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, RsWirePulseSPtr &pPulse) override; - - virtual bool getPulsesForGroups(const std::list &groupIds, std::list &pulsePtrs) override; - - virtual bool getPulseFocus(const RsGxsGroupId &groupId, const RsGxsMessageId &msgId, int type, RsWirePulseSPtr &pPulse) override; - -private: - // Internal Service Data. - // They should eventually all be here. - bool getRelatedPulseData(const uint32_t &token, std::vector &pulses); - bool getGroupPtrData(const uint32_t &token, - std::map &groups); - bool getPulsePtrData(const uint32_t &token, std::list &pulses); - - // util functions fetching data. - bool fetchPulse(RsGxsGroupId grpId, RsGxsMessageId msgId, RsWirePulseSPtr &pPulse); - bool updatePulse(RsWirePulseSPtr pPulse, int levels); - bool updatePulseChildren(RsWirePulseSPtr pParent, uint32_t token); - - // update GroupPtrs - bool updateGroups(std::list &pulsePtrs); - - // sub utility functions used by updateGroups. - bool extractGroupIds(RsWirePulseConstSPtr pPulse, std::set &groupIds); - - bool updateGroupPtrs(RsWirePulseSPtr pPulse, - const std::map &groups); - - bool trimToAvailGroupIds(const std::set &pulseGroupIds, - std::list &availGroupIds); - - bool fetchGroupPtrs(const std::list &groupIds, - std::map &groups); - - - virtual void generateDummyData(); - std::string genRandomId(); - - RsMutex mWireMtx; -}; - -#endif diff --git a/libretroshare/src/services/rseventsservice.cc b/libretroshare/src/services/rseventsservice.cc deleted file mode 100644 index 3bbb852be..000000000 --- a/libretroshare/src/services/rseventsservice.cc +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * Retroshare events service * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Retroshare Team * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include - -#include "services/rseventsservice.h" - - -/*extern*/ RsEvents* rsEvents = nullptr; - -RsEvent::~RsEvent() = default; -RsEvents::~RsEvents() = default; - -/*static*/ const RsEventsErrorCategory RsEventsErrorCategory::instance; - -std::error_condition RsEventsErrorCategory::default_error_condition(int ev) -const noexcept -{ - switch(static_cast(ev)) - { - case RsEventsErrorNum::INVALID_HANDLER_ID: // [[fallthrough]]; - case RsEventsErrorNum::NULL_EVENT_POINTER: // [[fallthrough]]; - case RsEventsErrorNum::EVENT_TYPE_UNDEFINED: // [[fallthrough]]; - case RsEventsErrorNum::EVENT_TYPE_OUT_OF_RANGE: - return std::errc::invalid_argument; - default: - return std::error_condition(ev, *this); - } -} - -std::error_condition RsEventsService::isEventTypeInvalid(RsEventType eventType) -{ - if(eventType == RsEventType::__NONE) - return RsEventsErrorNum::EVENT_TYPE_UNDEFINED; - - if( eventType < RsEventType::__NONE || - eventType >= static_cast(mHandlerMaps.size()) ) - return RsEventsErrorNum::EVENT_TYPE_OUT_OF_RANGE; - - return std::error_condition(); -} - -std::error_condition RsEventsService::isEventInvalid( - std::shared_ptr event) -{ - if(!event) return RsEventsErrorNum::NULL_EVENT_POINTER; - return isEventTypeInvalid(event->mType); -} - -std::error_condition RsEventsService::postEvent( - std::shared_ptr event ) -{ - if(std::error_condition ec = isEventInvalid(event)) return ec; - - RS_STACK_MUTEX(mEventQueueMtx); - mEventQueue.push_back(event); - return std::error_condition(); -} - -std::error_condition RsEventsService::sendEvent( - std::shared_ptr event ) -{ - if(std::error_condition ec = isEventInvalid(event)) return ec; - handleEvent(event); - return std::error_condition(); -} - -RsEventsHandlerId_t RsEventsService::generateUniqueHandlerId() -{ - RS_STACK_MUTEX(mHandlerMapMtx); - return generateUniqueHandlerId_unlocked(); -} - -RsEventsHandlerId_t RsEventsService::generateUniqueHandlerId_unlocked() -{ - if(++mLastHandlerId) return mLastHandlerId; // Avoid 0 after overflow - return 1; -} - -std::error_condition RsEventsService::registerEventsHandler( - std::function)> multiCallback, - RsEventsHandlerId_t& hId, RsEventType eventType ) -{ - RS_STACK_MUTEX(mHandlerMapMtx); - - if(eventType != RsEventType::__NONE) - if(std::error_condition ec = isEventTypeInvalid(eventType)) - return ec; - - if(!hId) hId = generateUniqueHandlerId_unlocked(); - else if (hId > mLastHandlerId) - { - print_stacktrace(); - return RsEventsErrorNum::INVALID_HANDLER_ID; - } - - mHandlerMaps[static_cast(eventType)][hId] = multiCallback; - return std::error_condition(); -} - -std::error_condition RsEventsService::unregisterEventsHandler( - RsEventsHandlerId_t hId ) -{ - RS_STACK_MUTEX(mHandlerMapMtx); - - for(uint32_t i=0; i eventPtr(nullptr); - size_t futureEventsCounter = 0; - -dispatchEventFromQueueLock: - mEventQueueMtx.lock(); - if(mEventQueue.size() > futureEventsCounter) - { - eventPtr = mEventQueue.front(); - mEventQueue.pop_front(); - - if(eventPtr->mTimePoint >= nextRunAt) - { - mEventQueue.push_back(eventPtr); - ++futureEventsCounter; - } - } - mEventQueueMtx.unlock(); - - if(eventPtr) - { - /* It is relevant that this stays out of mEventQueueMtx */ - handleEvent(eventPtr); - eventPtr = nullptr; // ensure refcounter is decremented before sleep - goto dispatchEventFromQueueLock; - } - - std::this_thread::sleep_until(nextRunAt); -} - -void RsEventsService::handleEvent(std::shared_ptr event) -{ - if(std::error_condition ec = isEventInvalid(event)) - { - RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl; - print_stacktrace(); - return; - } - - RS_STACK_MUTEX(mHandlerMapMtx); - /* It is important to also call the callback under mutex protection to - * ensure they are not unregistered in the meanwhile. - * If a callback try to fiddle with registering/unregistering it will - * deadlock */ - - // Call all clients that registered a callback for this event type - for(auto cbit: mHandlerMaps[static_cast(event->mType)]) - cbit.second(event); - - /* Also call all clients that registered with NONE, meaning that they - * expect all events */ - for(auto cbit: mHandlerMaps[static_cast(RsEventType::__NONE)]) - cbit.second(event); -} diff --git a/libretroshare/src/services/rseventsservice.h b/libretroshare/src/services/rseventsservice.h deleted file mode 100644 index 4f6ce98eb..000000000 --- a/libretroshare/src/services/rseventsservice.h +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Retroshare events service * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "retroshare/rsevents.h" -#include "util/rsthreads.h" -#include "util/rsdebug.h" - -class RsEventsService : - public RsEvents, public RsTickingThread -{ -public: - RsEventsService(): - mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1), - mEventQueueMtx("RsEventsService::mEventQueueMtx") {} - - /// @see RsEvents - std::error_condition postEvent( - std::shared_ptr event ) override; - - /// @see RsEvents - std::error_condition sendEvent( - std::shared_ptr event ) override; - - /// @see RsEvents - RsEventsHandlerId_t generateUniqueHandlerId() override; - - /// @see RsEvents - std::error_condition registerEventsHandler( - std::function)> multiCallback, - RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0), - RsEventType eventType = RsEventType::__NONE ) override; - - /// @see RsEvents - std::error_condition unregisterEventsHandler( - RsEventsHandlerId_t hId ) override; - -protected: - std::error_condition isEventTypeInvalid(RsEventType eventType); - std::error_condition isEventInvalid(std::shared_ptr event); - - RsMutex mHandlerMapMtx; - RsEventsHandlerId_t mLastHandlerId; - - /** Storage for event handlers, keep 10 extra types for plugins that might - * be released indipendently */ - std::array< - std::map< - RsEventsHandlerId_t, - std::function)> >, - static_cast(RsEventType::__MAX) + 10 - > mHandlerMaps; - - RsMutex mEventQueueMtx; - std::deque< std::shared_ptr > mEventQueue; - - void threadTick() override; /// @see RsTickingThread - - void handleEvent(std::shared_ptr event); - RsEventsHandlerId_t generateUniqueHandlerId_unlocked(); - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; diff --git a/libretroshare/src/tcponudp/bio_tou.h b/libretroshare/src/tcponudp/bio_tou.h deleted file mode 100644 index a82444ccc..000000000 --- a/libretroshare/src/tcponudp/bio_tou.h +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: bio_tou.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef BIO_TCPONUDP_H -#define BIO_TCPONUDP_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -int BIO_tou_socket_should_retry(int s, int e); -int BIO_tou_socket_non_fatal_error(int error); - -#define BIO_TYPE_TOU_SOCKET (30|0x0400|0x0100) /* NEW rmfern type */ - -BIO_METHOD *BIO_s_tou_socket(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/libretroshare/src/tcponudp/bss_tou.cc b/libretroshare/src/tcponudp/bss_tou.cc deleted file mode 100644 index 286201f53..000000000 --- a/libretroshare/src/tcponudp/bss_tou.cc +++ /dev/null @@ -1,355 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: bss_tou.c * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 1995-1998 Eric Young * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2018-2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef OPENSSL_NO_SOCK - -#include "bio_tou.h" - -#include -#include -#include /* for strlen() */ - -#define USE_SOCKETS -#include - -#include "tou.h" -#include "util/rsdebug.h" - -RS_SET_CONTEXT_DEBUG_LEVEL(0); - -static int tou_socket_write(BIO *h, const char *buf, int num); -static int tou_socket_read(BIO *h, char *buf, int size); -static int tou_socket_puts(BIO *h, const char *str); -static long tou_socket_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int tou_socket_new(BIO *h); -static int tou_socket_free(BIO *data); -static int get_last_tou_socket_error(int s); -static int clear_tou_socket_error(int s); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - -static int BIO_get_init(BIO *a) { return a->init; } - -#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000) \ - || (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) - -static int BIO_get_shutdown(BIO *a) { return a->shutdown; } -static void BIO_set_init(BIO *a,int i) { a->init=i; } -static void BIO_set_data(BIO *a,void *p) { a->ptr = p; } -long (*BIO_meth_get_ctrl(const BIO_METHOD* biom)) (BIO*, int, long, void*) -{ return biom->ctrl; } - -#endif /* (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000) \ -|| (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) */ - -static BIO_METHOD methods_tou_sockp = -{ - BIO_TYPE_TOU_SOCKET, - "tou_socket", - tou_socket_write, - tou_socket_read, - tou_socket_puts, - nullptr, // bgets - tou_socket_ctrl, - tou_socket_new, - tou_socket_free, - nullptr, // callback_ctrl -}; - -BIO_METHOD* BIO_s_tou_socket(void) -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - return(&methods_tou_sockp); -} - -#else // OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - -BIO_METHOD* BIO_s_tou_socket(void) -{ - static BIO_METHOD* methods_tou_sockp_ptr = NULL; - if(!methods_tou_sockp_ptr) - { - methods_tou_sockp_ptr = BIO_meth_new(BIO_TYPE_TOU_SOCKET, "tou_socket"); - - BIO_meth_set_write( methods_tou_sockp_ptr, tou_socket_write ); - BIO_meth_set_read( methods_tou_sockp_ptr, tou_socket_read ); - BIO_meth_set_puts( methods_tou_sockp_ptr, tou_socket_puts ); - BIO_meth_set_ctrl( methods_tou_sockp_ptr, tou_socket_ctrl ); - BIO_meth_set_create( methods_tou_sockp_ptr, tou_socket_new ); - BIO_meth_set_destroy( methods_tou_sockp_ptr, tou_socket_free ); - } - - return methods_tou_sockp_ptr; -} - -#endif // OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - -static int tou_socket_new(BIO *bi) -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - BIO_set_init(bi,0) ; - BIO_set_data(bi, nullptr); // sets bi->ptr - BIO_set_flags(bi,0) ; - BIO_set_fd(bi,0,0) ; - return(1); -} - -static int tou_socket_free(BIO *a) -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - if (!a) return(0); - - if(BIO_get_shutdown(a)) - { - if(BIO_get_init(a)) tou_close(static_cast(BIO_get_fd(a, nullptr))); - BIO_set_init(a,0) ; - BIO_set_flags(a,0) ; - } - return(1); - } - -static int tou_socket_read(BIO *b, char *out, int outl) -{ - Dbg2() << __PRETTY_FUNCTION__ << std::endl; - - int ret=0; - - if (out) - { - clear_tou_socket_error(BIO_get_fd(b,NULL)); - /* call tou library */ - ret=tou_read(BIO_get_fd(b,NULL),out,outl); - BIO_clear_retry_flags(b); - if (ret <= 0) - { - if (BIO_tou_socket_should_retry(BIO_get_fd(b,NULL), ret)) - BIO_set_retry_read(b); - } - } -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_read() = %d\n", ret); -#endif - return(ret); - } - -static int tou_socket_write(BIO *b, const char *in, int inl) - { - int ret; -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_write(%p,%p,%d)\n",b,in,inl); -#endif - - clear_tou_socket_error(BIO_get_fd(b,NULL)); - /* call tou library */ - ret=tou_write(BIO_get_fd(b,NULL),in,inl); - BIO_clear_retry_flags(b); - if (ret <= 0) - { - if (BIO_tou_socket_should_retry(BIO_get_fd(b,NULL),ret)) - { - BIO_set_retry_write(b); -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_write() setting retry flag\n"); -#endif - } - } -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_write() = %d\n", ret); -#endif - return(ret); - } - -static long tou_socket_ctrl(BIO *b, int cmd, long num, void *ptr) - { - long ret=1; -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_ctrl(%p,%d,%ld)\n", b, cmd, num); -#endif - - // We are not allowed to call BIO_set_fd here, because it will trigger a callback, which re-ends here - - switch (cmd) - { - case BIO_CTRL_RESET: - num=0; - /* fallthrough */ - case BIO_C_FILE_SEEK: - ret=0; - break; - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret=0; - break; - case BIO_C_SET_FD: - tou_socket_free(b); - ret = BIO_meth_get_ctrl((BIO_METHOD*)BIO_s_fd())(b,cmd,num,ptr); - break; - case BIO_C_GET_FD: - ret = BIO_meth_get_ctrl((BIO_METHOD*)BIO_s_fd())(b,cmd,num,ptr); - break; - case BIO_CTRL_GET_CLOSE: - ret = BIO_meth_get_ctrl((BIO_METHOD*)BIO_s_fd())(b,cmd,num,ptr); - break; - case BIO_CTRL_SET_CLOSE: - ret = BIO_meth_get_ctrl((BIO_METHOD*)BIO_s_fd())(b,cmd,num,ptr); - break; - case BIO_CTRL_PENDING: - ret = tou_maxread(BIO_get_fd(b,NULL)); -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_pending = %ld\n", ret); -#endif - break; - case BIO_CTRL_WPENDING: - ret = tou_maxwrite(BIO_get_fd(b,NULL)); -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_wpending = %ld\n", ret); -#endif - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret=1; - break; - default: - ret=0; - break; - } - return(ret); - } - -static int tou_socket_puts(BIO *bp, const char *str) - { - int n,ret; - -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "tou_socket_puts()\n"); -#endif - - n=strlen(str); - ret=tou_socket_write(bp,str,n); - return(ret); - } - -static int clear_tou_socket_error(int fd) -{ -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "clear_tou_socket_error()\n"); -#endif - return tou_clear_error(fd); -} - -static int get_last_tou_socket_error(int s) -{ -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "get_last_tou_socket_error()\n"); -#endif - return tou_errno(s); -} - -int BIO_tou_socket_should_retry(int s, int i) - { - int err; -#ifdef DEBUG_TOU_BIO - fprintf(stderr, "BIO_tou_socket_should_retry()\n"); -#endif - - if ((i == 0) || (i == -1)) - { - err=get_last_tou_socket_error(s); - -#if defined(OPENSSL_SYS_WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */ - if ((i == -1) && (err == 0)) - return(1); -#endif - - return(BIO_tou_socket_non_fatal_error(err)); - } - return(0); - } - -int BIO_tou_socket_non_fatal_error(int err) -{ - constexpr int fatalError = 0; - constexpr int nonFatalError = 1; - - switch (err) - { -#if defined(OPENSSL_SYS_WINDOWS) -# if defined(WSAEWOULDBLOCK) - case WSAEWOULDBLOCK: -# endif // defined(WSAEWOULDBLOCK) -#endif // defined(OPENSSL_SYS_WINDOWS) - -#ifdef EWOULDBLOCK -# ifdef WSAEWOULDBLOCK -# if WSAEWOULDBLOCK != EWOULDBLOCK - case EWOULDBLOCK: -# endif // WSAEWOULDBLOCK != EWOULDBLOCK -# else // def WSAEWOULDBLOCK - case EWOULDBLOCK: -# endif // def WSAEWOULDBLOCK -#endif - -#if defined(ENOTCONN) - case ENOTCONN: -#endif // defined(ENOTCONN) - -#ifdef EINTR - case EINTR: -#endif // def EINTR - -#ifdef EAGAIN -# if EWOULDBLOCK != EAGAIN - case EAGAIN: -# endif // EWOULDBLOCK != EAGAIN -#endif // def EAGAIN - -#ifdef EPROTO - case EPROTO: -#endif // def EPROTO - -#ifdef EINPROGRESS - case EINPROGRESS: -#endif // def EINPROGRESS - -#ifdef EALREADY - case EALREADY: -#endif // def EALREADY - - Dbg2() << __PRETTY_FUNCTION__ << " err: " << err - << " return nonFatalError " << nonFatalError << std::endl; - return nonFatalError; - - default: - break; - } - - Dbg2() << __PRETTY_FUNCTION__ << " err: " << err << " return fatalError " - << fatalError << std::endl; - - return fatalError; -} - -#endif // ndef OPENSSL_NO_SOCK diff --git a/libretroshare/src/tcponudp/rsudpstack.h b/libretroshare/src/tcponudp/rsudpstack.h deleted file mode 100644 index 77c25692c..000000000 --- a/libretroshare/src/tcponudp/rsudpstack.h +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: rsudpstack.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RS_UDP_STACK_RECEIVER_H -#define RS_UDP_STACK_RECEIVER_H - -#ifdef RS_USE_BITDHT - -#include "udp/udpstack.h" - - -#else - -class UdpStack -{ - public: - UdpStack(int testmode, struct sockaddr_in &local) { return; } - UdpStack(struct sockaddr_in &local) { return; } - - /* from pqiNetListener */ -virtual bool resetAddress(struct sockaddr_in &local) { return false; } - -}; - -#endif -/*******************************************************/ - -#include "pqi/pqimonitor.h" -#include "util/rsnet.h" -#include "util/stacktrace.h" - -#include - -class rsUdpStack: public UdpStack, public pqiNetListener -{ -public: - rsUdpStack(struct sockaddr_in &local) : UdpStack(local) {} - - rsUdpStack(int testmode, struct sockaddr_in &local) : - UdpStack(testmode, local) {} - - /// @see pqiNetListener - virtual bool resetListener(const sockaddr_storage& local) - { - sockaddr_storage temp; - sockaddr_storage_copy(local, temp); - - if (!sockaddr_storage_ipv6_to_ipv4(temp)) - { - std::cerr << __PRETTY_FUNCTION__ << " Got non IPv4 address ERROR" - << std::endl; - sockaddr_storage_dump(local); - print_stacktrace(); - return -EINVAL; - } - - sockaddr_in *addr = reinterpret_cast(&temp); - return resetAddress(*addr); - } -}; - -class rsFixedUdpStack: public UdpStack, public pqiNetListener -{ - public: - rsFixedUdpStack(struct sockaddr_in &local) - :UdpStack(local) { return; } - - rsFixedUdpStack(int testmode, struct sockaddr_in &local) - :UdpStack(testmode, local) { return; } - - /* from pqiNetListener */ -virtual bool resetListener(const struct sockaddr_storage & /* local */) - { - struct sockaddr_in addr; - getLocalAddress(addr); - - // The const_cast below is not so nice but without it, the compiler can't - // find the correct operator<<(). No idea why! - //std::cerr << "rsFixedUdpStack::resetListener(" << sockaddr_storage_tostring(local) << ")"; - //std::cerr << " Resetting with original addr: " << const_cast(addr); - //std::cerr << std::endl; - - return resetAddress(addr); - } - -}; - -#endif diff --git a/libretroshare/src/tcponudp/tcppacket.cc b/libretroshare/src/tcponudp/tcppacket.cc deleted file mode 100644 index 2da199288..000000000 --- a/libretroshare/src/tcponudp/tcppacket.cc +++ /dev/null @@ -1,262 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tcppacket.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "tcppacket.h" - -/* - * #include - */ - -#include "util/rsnet.h" /* for winsock.h -> htons etc */ - -#include -#include -#include - -#include - -/* NOTE That these BIT #defines will only - * work on little endian machines.... - * due to the ntohs ... - */ - -/* flags 16bit is: - * - * || 0 1 2 3 | 4 5 6 7 || 8 9 | 10 11 12 13 14 15 || - * <- HLen -> <--- unused ---> <---- flags -------> - * URG PSH SYN - * ACK RST FIN - * - * - * So in little endian world. - * 0 & 1 -> unused... - * URG -> bit 2 => 0x0004 - * ACK -> bit 3 => 0x0008 - * PSH -> bit 4 => 0x0010 - * RST -> bit 5 => 0x0020 - * SYN -> bit 6 => 0x0040 - * FIN -> bit 7 => 0x0080 - * - * and second byte 0-3 -> hlen, 4-7 unused. - */ - -#define TCP_URG_BIT 0x0004 -#define TCP_ACK_BIT 0x0008 -#define TCP_PSH_BIT 0x0010 -#define TCP_RST_BIT 0x0020 -#define TCP_SYN_BIT 0x0040 -#define TCP_FIN_BIT 0x0080 - - -TcpPacket::TcpPacket(uint8 *ptr, int size) - :data(0), datasize(0), seqno(0), ackno(0), hlen_flags(0), - winsize(0), ts(0), retrans(0) - { - if (size > 0) - { - datasize = size; - data = (uint8 *) rs_malloc(datasize); - - if(data != NULL) - memcpy(data, (void *) ptr, size); - } - return; - } - -TcpPacket::TcpPacket() /* likely control packet */ - :data(0), datasize(0), seqno(0), ackno(0), hlen_flags(0), - winsize(0), ts(0), retrans(0) - { - return; - } - - -TcpPacket::~TcpPacket() - { - if (data) - free(data); - } - - -int TcpPacket::writePacket(void *buf, int &size) -{ - if (size < TCP_PSEUDO_HDR_SIZE + datasize) - { - size = 0; - return -1; - } - - /* byte: 0 => uint16 srcport = 0 */ - *((uint16 *) &(((uint8 *) buf)[0])) = htons(0); - - /* byte: 2 => uint16 destport = 0 */ - *((uint16 *) &(((uint8 *) buf)[2])) = htons(0); - - /* byte: 4 => uint32 seqno */ - *((uint32 *) &(((uint8 *) buf)[4])) = htonl(seqno); - - /* byte: 8 => uint32 ackno */ - *((uint32 *) &(((uint8 *) buf)[8])) = htonl(ackno); - - /* byte: 12 => uint16 len + flags */ - *((uint16 *) &(((uint8 *) buf)[12])) = htons(hlen_flags); - - /* byte: 14 => uint16 winsize */ - *((uint16 *) &(((uint8 *) buf)[14])) = htons(winsize); - - /* byte: 16 => uint16 chksum */ - *((uint16 *) &(((uint8 *) buf)[16])) = htons(0); - - /* byte: 18 => uint16 urgptr */ - *((uint16 *) &(((uint8 *) buf)[18])) = htons(0); - - /* total 20 bytes */ - - /* now the data */ - memcpy((void *) &(((uint8 *) buf)[20]), data, datasize); - - return size = TCP_PSEUDO_HDR_SIZE + datasize; -} - - -int TcpPacket::readPacket(void *buf, int size) -{ - if (size < TCP_PSEUDO_HDR_SIZE) - { - std::cerr << "TcpPacket::readPacket() Failed Too Small!"; - std::cerr << std::endl; - return -1; - } - - /* byte: 0 => uint16 srcport = 0 ******************* - *((uint16 *) &(((uint8 *) buf)[0])) = htons(0); - ***********/ - - /* byte: 2 => uint16 destport = 0 ****************** - *((uint16 *) &(((uint8 *) buf)[2])) = htons(0); - ***********/ - - /* byte: 4 => uint32 seqno */ - seqno = ntohl( *((uint32 *) &(((uint8 *) buf)[4])) ); - - /* byte: 8 => uint32 ackno */ - ackno = ntohl( *((uint32 *) &(((uint8 *) buf)[8])) ); - - /* byte: 12 => uint16 len + flags */ - hlen_flags = ntohs( *((uint16 *) &(((uint8 *) buf)[12])) ); - - /* byte: 14 => uint16 winsize */ - winsize = ntohs( *((uint16 *) &(((uint8 *) buf)[14])) ); - - /* byte: 16 => uint16 chksum ************************* - *((uint16 *) &(((uint8 *) buf)[16])) = htons(0); - ***********/ - - /* byte: 18 => uint16 urgptr ************************* - *((uint16 *) &(((uint8 *) buf)[18])) = htons(0); - ***********/ - - /* total 20 bytes */ - - if (data) - { - free(data); - data = NULL ; - } - datasize = size - TCP_PSEUDO_HDR_SIZE; - - // this happens for control packets (e.g. syn/ack/fin) - if(datasize == 0) - { - // data is already NULL - // just return packet size - return size; - } - - data = (uint8 *) rs_malloc(datasize); - - if(data == NULL) - { - // malloc failed! - // return 0 to drop packet (will be retransmitted eventually) - return 0 ; - } - - /* now the data */ - memcpy(data, (void *) &(((uint8 *) buf)[20]), datasize); - - return size; -} - - /* flags */ -bool TcpPacket::hasSyn() -{ - return (hlen_flags & TCP_SYN_BIT); -} - -bool TcpPacket::hasFin() -{ - return (hlen_flags & TCP_FIN_BIT); -} - -bool TcpPacket::hasAck() -{ - return (hlen_flags & TCP_ACK_BIT); -} - -bool TcpPacket::hasRst() -{ - return (hlen_flags & TCP_RST_BIT); -} - - -void TcpPacket::setSyn() -{ - hlen_flags |= TCP_SYN_BIT; -} - -void TcpPacket::setFin() -{ - hlen_flags |= TCP_FIN_BIT; -} - -void TcpPacket::setRst() -{ - hlen_flags |= TCP_RST_BIT; -} - -void TcpPacket::setAckFlag() -{ - hlen_flags |= TCP_ACK_BIT; -} - -void TcpPacket::setAck(uint32 val) -{ - setAckFlag(); - ackno = val; -} - -uint32 TcpPacket::getAck() -{ - return ackno; -} - - diff --git a/libretroshare/src/tcponudp/tcppacket.h b/libretroshare/src/tcponudp/tcppacket.h deleted file mode 100644 index e87c3e394..000000000 --- a/libretroshare/src/tcponudp/tcppacket.h +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tcppacket.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef TOU_TCP_PACKET_H -#define TOU_TCP_PACKET_H - -#include - - -typedef unsigned int uint32; -typedef unsigned short uint16; -typedef unsigned char uint8; - -#define TCP_PSEUDO_HDR_SIZE 20 - -class TcpPacket -{ - public: - - uint8 *data; - int datasize; - - - /* ports aren't needed -> in udp - * uint16 srcport, destport - **************************/ - uint32 seqno, ackno; - uint16 hlen_flags; - uint16 winsize; - /* don't need these -> in udp + not supported - uint16 chksum, urgptr; - **************************/ - /* no options. - **************************/ - - - /* other variables */ - double ts; /* transmit time */ - uint16 retrans; /* retransmit counter */ - - TcpPacket(uint8 *ptr, int size); - TcpPacket(); /* likely control packet */ - ~TcpPacket(); - -int writePacket(void *buf, int &size); -int readPacket(void *buf, int size); - -void *getData(); -void *releaseData(); - -void *setData(void *data, int size); -int getDataSize(); - - /* flags */ -bool hasSyn(); -bool hasFin(); -bool hasAck(); -bool hasRst(); - -void setSyn(); -void setFin(); -void setRst(); -void setAckFlag(); - -void setAck(uint32 val); -uint32 getAck(); - - -}; - - -#endif - diff --git a/libretroshare/src/tcponudp/tcpstream.cc b/libretroshare/src/tcponudp/tcpstream.cc deleted file mode 100644 index 439f98854..000000000 --- a/libretroshare/src/tcponudp/tcpstream.cc +++ /dev/null @@ -1,2792 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tcpstream.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -#include "tcpstream.h" -#include -#include -#include -#include -#include -#include - -#include -#include "util/rstime.h" - -/* Debugging for STATE change, and Startup SYNs */ -#include "util/rsdebug.h" -#include "util/rsstring.h" -#include "util/rsrandom.h" - -static struct RsLog::logInfo rstcpstreamzoneInfo = {RsLog::Default, "rstcpstream"}; -#define rstcpstreamzone &rstcpstreamzoneInfo - -/* - * #define DEBUG_TCP_STREAM 1 - * #define DEBUG_TCP_STREAM_RETRANS 1 - * #define DEBUG_TCP_STREAM_CLOSE 1 - */ - -//#define DEBUG_TCP_STREAM_RETRANS 1 -//#define DEBUG_TCP_STREAM_CLOSE 1 - -/* - *#define DEBUG_TCP_STREAM_EXTRA 1 - */ - -/* - * #define TCP_NO_PARTIAL_READ 1 - */ - -#ifdef DEBUG_TCP_STREAM -int checkData(uint8 *data, int size, int idx); -int setupBinaryCheck(std::string fname); -#endif - -static const uint32 kMaxQueueSize = 300; // Was 100, which means max packet size of 100k (smaller than max packet size). -static const uint32 kMaxPktRetransmit = 10; -static const uint32 kMaxSynPktRetransmit = 100; // 100 => 200secs = over 3 minutes startup -static const int TCP_STD_TTL = 64; -static const int TCP_DEFAULT_FIREWALL_TTL = 4; - -static const double RTT_ALPHA = 0.875; - -int dumpPacket(std::ostream &out, unsigned char *pkt, uint32_t size); - -// platform independent fractional timestamp. -static double getCurrentTS(); - -TcpStream::TcpStream(UdpSubReceiver *lyr) - : tcpMtx("TcpStream"), inSize(0), outSizeRead(0), outSizeNet(0), - state(TCP_CLOSED), - inStreamActive(false), - outStreamActive(false), - outSeqno(0), outAcked(0), outWinSize(0), - inAckno(0), inWinSize(0), - maxWinSize(TCP_MAX_WIN), - keepAliveTimeout(TCP_ALIVE_TIMEOUT), - retransTimerOn(false), - retransTimeout(TCP_RETRANS_TIMEOUT), - retransTimerTs(0), - keepAliveTimer(0), - lastIncomingPkt(0), - lastSentAck(0), - lastSentWinSize(0), - initOurSeqno(0), - initPeerSeqno(0), - lastWriteTF(0),lastReadTF(0), - wcount(0), rcount(0), - errorState(0), - /* retranmission variables - init to large */ - rtt_est(TCP_RETRANS_TIMEOUT), - rtt_dev(0), - congestThreshold(TCP_MAX_WIN), - congestWinSize(MAX_SEG), - congestUpdate(0), - ttl(0), - mTTL_period(0), - mTTL_start(0), - mTTL_end(0), - peerKnown(false), - udp(lyr) -{ - sockaddr_clear(&peeraddr); - - return; -} - -/* Stream Control! */ -int TcpStream::connect(const struct sockaddr_in &raddr, uint32_t conn_period) -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - setRemoteAddress(raddr); - - /* check state */ - if (state != TCP_CLOSED) - { - if (state == TCP_ESTABLISHED) - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 0; - } - else if (state < TCP_ESTABLISHED) - { - errorState = EAGAIN; - } - else - { - // major issues! - errorState = EFAULT; - } - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; - } - - /* setup Seqnos */ - outSeqno = genSequenceNo(); - initOurSeqno = outSeqno; - - outAcked = outSeqno; /* min - 1 expected */ - inWinSize = maxWinSize; - - congestThreshold = TCP_MAX_WIN; - congestWinSize = MAX_SEG; - congestUpdate = outAcked + congestWinSize; - - /* Init Connection */ - /* send syn packet */ - TcpPacket *pkt = new TcpPacket(); - pkt -> setSyn(); - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::connect() Send Init Pkt" << std::endl; -#endif - - - /* ********* SLOW START ************* - * As this is the only place where a syn - * is sent ..... we switch the ttl to 0, - * and increment it as we retransmit the packet.... - * This should help the firewalls along. - */ - - setTTL(1); - - mTTL_start = getCurrentTS(); - mTTL_period = conn_period; - mTTL_end = mTTL_start + mTTL_period; - - toSend(pkt); - /* change state */ - state = TCP_SYN_SENT; - errorState = EAGAIN; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_SYN_SENT" << std::endl; -#endif - { - rslog(RSL_WARNING,rstcpstreamzone,"TcpStream::state => TCP_SYN_SENT (Connect)"); - } - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return -1; -} - - -int TcpStream::listenfor(const struct sockaddr_in &raddr) -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - setRemoteAddress(raddr); - - /* check state */ - if (state != TCP_CLOSED) - { - if (state == TCP_ESTABLISHED) - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 0; - } - else if (state < TCP_ESTABLISHED) - { - errorState = EAGAIN; - } - else - { - // major issues! - errorState = EFAULT; - } - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; - } - - errorState = EAGAIN; - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; -} - - -/* Stream Control! */ -int TcpStream::close() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - cleanup(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 0; -} - -int TcpStream::closeWrite() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - /* check state */ - /* will always close socket.... */ - /* if in TCP_ESTABLISHED.... - * -> to state: TCP_FIN_WAIT_1 - * and shutdown outward stream. - */ - - /* if in CLOSE_WAIT.... - * -> to state: TCP_LAST_ACK - * and shutdown outward stream. - * do this one first!. - */ - - outStreamActive = false; - - if (state == TCP_CLOSE_WAIT) - { - /* don't think we need to be - * graceful at this point... - * connection already closed by other end. - * XXX might fix later with scheme - * - * flag stream closed, and when outqueue - * emptied then fin will be sent. - */ - - /* do nothing */ - } - - if (state == TCP_ESTABLISHED) - { - /* fire off the damned thing. */ - /* by changing state */ - - /* again this is handled by internals - * the flag however indicates that - * no more data can be send, - * and once the queue empties - * the FIN will be sent. - */ - - } - if (state == TCP_CLOSED) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::close() Flag Set" << std::endl; -#endif - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return 0; - } - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::close() pending" << std::endl; -#endif - errorState = EAGAIN; - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; -} - -bool TcpStream::isConnected() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - bool isConn = (state == TCP_ESTABLISHED); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return isConn; -} - -int TcpStream::status(std::ostream &out) -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - int s = status_locked(out); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return s; -} - - -int TcpStream::status_locked(std::ostream &out) -{ - - int tmpstate = state; - - // can leave the timestamp here as time()... rough but okay. - out << "TcpStream::status @ (" << time(NULL) << ")" << std::endl; - out << "TcpStream::state = " << (int) state << std::endl; - out << std::endl; - out << "writeBuffer: " << inSize << " + MAX_SEG * " << inQueue.size(); - out << " bytes Queued for transmission" << std::endl; - out << "readBuffer: " << outSizeRead << " + MAX_SEG * "; - out << outQueue.size() << " + " << outSizeNet; - out << " incoming bytes waiting" << std::endl; - out << std::endl; - out << "inPkts: " << inPkt.size() << " packets waiting for processing"; - out << std::endl; - out << "outPkts: " << outPkt.size() << " packets waiting for acks"; - out << std::endl; - out << "us -> peer: nextSeqno: " << outSeqno << " lastAcked: " << outAcked; - out << " winsize: " << outWinSize; - out << std::endl; - out << "peer -> us: Expected SeqNo: " << inAckno; - out << " winsize: " << inWinSize; - out << std::endl; - out << std::endl; - - return tmpstate; -} - -int TcpStream::write_allowed() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - int ret = 1; - if (state == TCP_CLOSED) - { - errorState = EBADF; - ret = -1; - } - else if (state < TCP_ESTABLISHED) - { - errorState = EAGAIN; - ret = -1; - } - else if (!outStreamActive) - { - errorState = EBADF; - ret = -1; - } - - if (ret < 1) - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return ret; - } - - int maxwrite = (kMaxQueueSize - inQueue.size()) * MAX_SEG; - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return maxwrite; -} - -int TcpStream::read_pending() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - /* error should be detected next time */ - int maxread = int_read_pending(); - if (state == TCP_CLOSED) - { - errorState = EBADF; - maxread = -1; - } - else if (state < TCP_ESTABLISHED) - { - errorState = EAGAIN; - maxread = -1; - } - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return maxread; -} - -/* INTERNAL */ -int TcpStream::int_read_pending() -{ - return outSizeRead + outQueue.size() * MAX_SEG + outSizeNet; -} - - - /* stream Interface */ -int TcpStream::write(char *dta, int size) /* write -> pkt -> net */ -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - int ret = 1; /* initial error checking */ - -#ifdef DEBUG_TCP_STREAM_EXTRA -static uint32 TMPtotalwrite = 0; -#endif - - if (state == TCP_CLOSED) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() Error TCP_CLOSED" << std::endl; -#endif - errorState = EBADF; - ret = -1; - } - else if (state < TCP_ESTABLISHED) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() Error TCP Not Established" << std::endl; -#endif - errorState = EAGAIN; - ret = -1; - } - else if (inQueue.size() > kMaxQueueSize) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() Error EAGAIN" << std::endl; -#endif - errorState = EAGAIN; - ret = -1; - } - else if (!outStreamActive) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() Error TCP_CLOSED" << std::endl; -#endif - errorState = EBADF; - ret = -1; - } - - if (ret < 1) /* check for initial error */ - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return ret; - } - - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() = Will Succeed " << size << std::endl; - std::cerr << "TcpStream::write() Write Start: " << TMPtotalwrite << std::endl; - std::cerr << printPktOffset(TMPtotalwrite, dta, size) << std::endl; - TMPtotalwrite += size; -#endif - - - if (size + inSize < MAX_SEG) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() Add Itty Bit" << std::endl; - std::cerr << "TcpStream::write() inData: " << (void *) inData; - std::cerr << " inSize: " << inSize << " dta: " << (void *) dta; - std::cerr << " size: " << size << " dest: " << (void *) &(inData[inSize]); - std::cerr << std::endl; -#endif -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() = " << size << std::endl; -#endif - memcpy((void *) &(inData[inSize]), dta, size); - inSize += size; - //std::cerr << "Small Packet - write to net:" << std::endl; - //std::cerr << printPkt(dta, size) << std::endl; - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; - } - - /* otherwise must construct a dataBuffer. - */ - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() filling 1 dataBuffer" << std::endl; - std::cerr << "TcpStream::write() from inData(" << inSize << ")" << std::endl; - std::cerr << "TcpStream::write() + dta(" << MAX_SEG - inSize; - std::cerr << "/" << size << ")" << std::endl; -#endif - - /* first create 1. */ - dataBuffer *db = new dataBuffer; - memcpy((void *) db->data, (void *) inData, inSize); - - - int remSize = size; - memcpy((void *) &(db->data[inSize]), dta, MAX_SEG - inSize); - - inQueue.push_back(db); - remSize -= (MAX_SEG - inSize); - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() remaining " << remSize << " bytes to load" << std::endl; -#endif - - while(remSize >= MAX_SEG) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() filling whole dataBuffer" << std::endl; - std::cerr << "TcpStream::write() from dta[" << size-remSize << "]" << std::endl; -#endif - db = new dataBuffer; - memcpy((void *) db->data, (void *) &(dta[size-remSize]), MAX_SEG); - - inQueue.push_back(db); - remSize -= MAX_SEG; - } - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::write() = " << size << std::endl; -#endif - - if (remSize > 0) - { - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() putting last bit in inData" << std::endl; - std::cerr << "TcpStream::write() from dta[" << size-remSize << "] size: "; - std::cerr << remSize << std::endl; -#endif - memcpy((void *) inData, (void *) &(dta[size-remSize]), remSize); - inSize = remSize; - } - else - { - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::write() Data fitted exactly in dataBuffer!" << std::endl; -#endif - inSize = 0; - } - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; -} - -int TcpStream::read(char *dta, int size) /* net -> pkt -> read */ -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - -#ifdef DEBUG_TCP_STREAM_EXTRA -static uint32 TMPtotalread = 0; -#endif - /* max available data is - * outDataRead + outQueue + outDataNet - */ - - int maxread = outSizeRead + outQueue.size() * MAX_SEG + outSizeNet; - int ret = 1; /* used only for initial errors */ - - if (state == TCP_CLOSED) - { - errorState = EBADF; - ret = -1; - } - else if (state < TCP_ESTABLISHED) - { - errorState = EAGAIN; - ret = -1; - } - else if ((!inStreamActive) && (maxread == 0)) - { - // finished stream. - ret = 0; - } - else if (maxread == 0) - { - /* must wait for more data */ - errorState = EAGAIN; - ret = -1; - } - - if (ret < 1) /* if ret has been changed */ - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return ret; - } - - if (maxread < size) - { -#ifdef TCP_NO_PARTIAL_READ - if (inStreamActive) - { - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::read() No Partial Read! "; - std::cerr << "Can only supply " << maxread << " of "; - std::cerr << size; - std::cerr << std::endl; -#endif - errorState = EAGAIN; - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return -1; - } -#endif /* TCP_NO_PARTIAL_READ */ - size = maxread; - } - - /* if less than outDataRead size */ - if (((unsigned) (size) < outSizeRead) && (outSizeRead)) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Add Itty Bit" << std::endl; - std::cerr << "TcpStream::read() outSizeRead: " << outSizeRead; - std::cerr << " size: " << size << " remaining: " << outSizeRead - size; - std::cerr << std::endl; -#endif - memcpy(dta,(void *) outDataRead, size); - memmove((void *) outDataRead, - (void *) &(outDataRead[size]), outSizeRead - (size)); - outSizeRead -= size; - - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() = Succeeded " << size << std::endl; - std::cerr << "TcpStream::read() Read Start: " << TMPtotalread << std::endl; - std::cerr << printPktOffset(TMPtotalread, dta, size) << std::endl; -#endif - -#ifdef DEBUG_TCP_STREAM_EXTRA - checkData((uint8 *) dta, size, TMPtotalread); - TMPtotalread += size; -#endif - - /* can allow more in! - update inWinSize */ - UpdateInWinSize(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; - } - - /* move the whole of outDataRead. */ - if (outSizeRead) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Move All outSizeRead" << std::endl; - std::cerr << "TcpStream::read() outSizeRead: " << outSizeRead; - std::cerr << " size: " << size; - std::cerr << std::endl; -#endif - memcpy(dta,(void *) outDataRead, outSizeRead); - - } - - int remSize = size - outSizeRead; - outSizeRead = 0; - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() remaining size: " << remSize << std::endl; -#endif - - while((outQueue.size() > 0) && (remSize > 0)) - { - dataBuffer *db = outQueue.front(); - outQueue.pop_front(); /* remove */ - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Taking Data from outQueue" << std::endl; -#endif - - /* load into outDataRead */ - if (remSize < MAX_SEG) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Partially using Segment" << std::endl; - std::cerr << "TcpStream::read() moving: " << remSize << " to dta @: " << size-remSize; - std::cerr << std::endl; - std::cerr << "TcpStream::read() rest to outDataRead: " << MAX_SEG - remSize; - std::cerr << std::endl; -#endif - memcpy((void *) &(dta[(size)-remSize]), (void *) db->data, remSize); - memcpy((void *) outDataRead, (void *) &(db->data[remSize]), MAX_SEG - remSize); - outSizeRead = MAX_SEG - remSize; - - delete db; - - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() = Succeeded " << size << std::endl; - std::cerr << "TcpStream::read() Read Start: " << TMPtotalread << std::endl; - std::cerr << printPktOffset(TMPtotalread, dta, size) << std::endl; -#endif - -#ifdef DEBUG_TCP_STREAM_EXTRA - checkData((uint8 *) dta, size, TMPtotalread); - TMPtotalread += size; -#endif - - /* can allow more in! - update inWinSize */ - UpdateInWinSize(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; - } -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Move Whole Segment to dta @ " << size-remSize << std::endl; -#endif - - /* else copy whole segment */ - memcpy((void *) &(dta[(size)-remSize]), (void *) db->data, MAX_SEG); - remSize -= MAX_SEG; - delete db; - } - - /* assumes that outSizeNet >= remSize due to initial - * constraint - */ - if ((remSize > 0)) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() Using up : " << remSize; - std::cerr << " last Bytes, leaving: " << outSizeNet - remSize << std::endl; -#endif - - - memcpy((void *) &(dta[(size)-remSize]),(void *) outDataNet, remSize); - outSizeNet -= remSize; - if (outSizeNet > 0) - { - /* move to the outDataRead */ - memcpy((void *) outDataRead,(void *) &(outDataNet[remSize]), outSizeNet); - outSizeRead = outSizeNet; - outSizeNet = 0; -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() moving last of outSizeNet to outSizeRead: " << outSizeRead; - std::cerr << std::endl; -#endif - - } - - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() = Succeeded " << size << std::endl; - std::cerr << "TcpStream::read() Read Start: " << TMPtotalread << std::endl; - std::cerr << printPktOffset(TMPtotalread, dta, size) << std::endl; -#endif - -#ifdef DEBUG_TCP_STREAM_EXTRA - checkData((uint8 *) dta, size, TMPtotalread); - TMPtotalread += size; -#endif - - /* can allow more in! - update inWinSize */ - UpdateInWinSize(); - - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; - } - -#ifdef DEBUG_TCP_STREAM_EXTRA - std::cerr << "TcpStream::read() = Succeeded " << size << std::endl; - std::cerr << "TcpStream::read() Read Start: " << TMPtotalread << std::endl; - std::cerr << printPktOffset(TMPtotalread, dta, size) << std::endl; -#endif - -#ifdef DEBUG_TCP_STREAM_EXTRA - checkData((uint8 *) dta, size, TMPtotalread); - TMPtotalread += size; -#endif - - /* can allow more in! - update inWinSize */ - UpdateInWinSize(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return size; -} - - - /* Callback from lower Layers */ -void TcpStream::recvPkt(void *data, int size) -{ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::recvPkt()"; - std::cerr << std::endl; -#endif - - tcpMtx.lock(); /********** LOCK MUTEX *********/ - uint8 *input = (uint8 *) data; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::recvPkt() Past Lock!"; - std::cerr << std::endl; -#endif - -#ifdef DEBUG_TCP_STREAM - if (state > TCP_SYN_RCVD) - { - int availRead = outSizeRead + outQueue.size() * MAX_SEG + outSizeNet; - std::cerr << "TcpStream::recvPkt() CC: "; - std::cerr << " iWS: " << inWinSize; - std::cerr << " aRead: " << availRead; - std::cerr << " iAck: " << inAckno; - std::cerr << std::endl; - } - else - { - std::cerr << "TcpStream::recv() Not Connected"; - std::cerr << std::endl; - } -#endif - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::recv() ReadPkt(" << size << ")" << std::endl; - //std::cerr << printPkt(input, size); - //std::cerr << std::endl; -#endif - TcpPacket *pkt = new TcpPacket(); - if (0 < pkt -> readPacket(input, size)) - { - lastIncomingPkt = getCurrentTS(); - handleIncoming(pkt); - } - else - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::recv() Bad Packet Deleting!"; - std::cerr << std::endl; -#endif - delete pkt; - } - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return; -} - - -int TcpStream::tick() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - //std::cerr << "TcpStream::tick()" << std::endl; - recv_check(); /* recv is async */ - send(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return 1; -} - -bool TcpStream::getRemoteAddress(struct sockaddr_in &raddr) -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - if (peerKnown) - { - raddr = peeraddr; - } - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return peerKnown; -} - -uint8 TcpStream::TcpState() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - uint8 err = state; - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return err; -} - -int TcpStream::TcpErrorState() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - int err = errorState; - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return err; -} - - - -/********************* SOME EXPOSED DEBUGGING FNS ******************/ - -static int ilevel = 100; - -bool TcpStream::widle() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - /* init */ - if (!lastWriteTF) - { - lastWriteTF = int_wbytes(); - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; - } - - if ((lastWriteTF == int_wbytes()) && (inSize == 0) && inQueue.empty()) - { - wcount++; - if (wcount > ilevel) - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return true; - } - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; - } - wcount = 0; - lastWriteTF = int_wbytes(); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; -} - - -bool TcpStream::ridle() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - /* init */ - if (!lastReadTF) - { - lastReadTF = int_rbytes(); - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; - } - - if ((lastReadTF == int_rbytes()) && (outSizeRead + outQueue.size() + outSizeNet== 0)) - { - rcount++; - if (rcount > ilevel) - { - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return true; - } - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; - } - rcount = 0; - lastReadTF = int_rbytes(); - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return false; -} - -uint32 TcpStream::wbytes() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - uint32 wb = int_wbytes(); - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return wb; -} - -uint32 TcpStream::rbytes() -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - uint32 rb = int_rbytes(); - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - return rb; -} - -/********************* ALL BELOW HERE IS INTERNAL ****************** - ******************* AND ALWAYS PROTECTED BY A MUTEX ***************/ - -int TcpStream::recv_check() -{ - double cts = getCurrentTS(); // fractional seconds. - -#ifdef DEBUG_TCP_STREAM - if (state > TCP_SYN_RCVD) - { - int availRead = outSizeRead + outQueue.size() * MAX_SEG + outSizeNet; - std::cerr << "TcpStream::recv_check() CC: "; - std::cerr << " iWS: " << inWinSize; - std::cerr << " aRead: " << availRead; - std::cerr << " iAck: " << inAckno; - std::cerr << std::endl; - } - else - { - std::cerr << "TcpStream::recv_check() Not Connected"; - std::cerr << std::endl; - } -#endif - - // make sure we've rcvd something! - if ((state > TCP_SYN_RCVD) && - (cts - lastIncomingPkt > kNoPktTimeout)) - { - /* shut it all down */ - /* this period should be equivalent - * to the firewall timeouts ??? - * - * for max efficiency - */ - -#ifdef DEBUG_TCP_STREAM_CLOSE - std::cerr << "TcpStream::recv_check() state = CLOSED (NoPktTimeout)"; - std::cerr << std::endl; - dumpstate_locked(std::cerr); -#endif - - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSED (kNoPktTimeout)"); - - outStreamActive = false; - inStreamActive = false; - state = TCP_CLOSED; - cleanup(); - } - return 1; -} - -int TcpStream::cleanup() -{ - // This shuts it all down! no matter what. - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::cleanup() state = TCP_CLOSED"); - - outStreamActive = false; - inStreamActive = false; - state = TCP_CLOSED; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_CLOSED" << std::endl; -#endif - - //peerKnown = false; //??? NOT SURE -> for a rapid reconnetion this might be key?? - - /* reset TTL */ - setTTL(TCP_STD_TTL); - - // clear arrays. - inSize = 0; - while(inQueue.size() > 0) - { - dataBuffer *db = inQueue.front(); - inQueue.pop_front(); - delete db; - } - - while(outPkt.size() > 0) - { - TcpPacket *pkt = outPkt.front(); - outPkt.pop_front(); - delete pkt; - } - - - // clear arrays. - outSizeRead = 0; - outSizeNet = 0; - while(outQueue.size() > 0) - { - dataBuffer *db = outQueue.front(); - outQueue.pop_front(); - delete db; - } - - while(inPkt.size() > 0) - { - TcpPacket *pkt = inPkt.front(); - inPkt.pop_front(); - delete pkt; - } - return 1; -} - -int TcpStream::handleIncoming(TcpPacket *pkt) -{ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::handleIncoming()" << std::endl; -#endif - switch(state) - { - case TCP_CLOSED: - case TCP_LISTEN: - /* if receive SYN - * -> respond SYN/ACK - * To State: SYN_RCVD - * - * else Discard. - */ - return incoming_Closed(pkt); - break; - case TCP_SYN_SENT: - /* if receive SYN - * -> respond SYN/ACK - * To State: SYN_RCVD - * - * if receive SYN+ACK - * -> respond ACK - * To State: TCP_ESTABLISHED - * - * else Discard. - */ - return incoming_SynSent(pkt); - break; - case TCP_SYN_RCVD: - /* if receive ACK - * To State: TCP_ESTABLISHED - */ - return incoming_SynRcvd(pkt); - break; - case TCP_ESTABLISHED: - /* if receive FIN - * -> respond ACK - * To State: TCP_CLOSE_WAIT - * else Discard. - */ - return incoming_Established(pkt); - break; - case TCP_FIN_WAIT_1: - /* state entered by close() call. - * if receive FIN - * -> respond ACK - * To State: TCP_CLOSING - * - * if receive ACK - * -> no response - * To State: TCP_FIN_WAIT_2 - * - * if receive FIN+ACK - * -> respond ACK - * To State: TCP_TIMED_WAIT - * - */ - return incoming_Established(pkt); - //return incoming_FinWait1(pkt); - break; - case TCP_FIN_WAIT_2: - /* if receive FIN - * -> respond ACK - * To State: TCP_TIMED_WAIT - */ - return incoming_Established(pkt); - //return incoming_FinWait2(pkt); - break; - case TCP_CLOSING: - /* if receive ACK - * To State: TCP_TIMED_WAIT - */ - /* all handled in Established */ - return incoming_Established(pkt); - //return incoming_Closing(pkt); - break; - case TCP_CLOSE_WAIT: - /* - * wait for our close to be called. - */ - /* all handled in Established */ - return incoming_Established(pkt); - //return incoming_CloseWait(pkt); - break; - case TCP_LAST_ACK: - /* entered by the local close() after sending FIN. - * if receive ACK - * To State: TCP_CLOSED - */ - /* all handled in Established */ - return incoming_Established(pkt); - /* - return incoming_LastAck(pkt); - */ - - break; - /* this is actually the only - * final state where packets not expected! - */ - case TCP_TIMED_WAIT: - /* State: TCP_TIMED_WAIT - * - * discard all -> both connections FINed - * timeout of this state. - * - */ - -#ifdef DEBUG_TCP_STREAM_CLOSE - std::cerr << "TcpStream::handleIncoming() state = CLOSED (TimedWait)"; - std::cerr << std::endl; - dumpstate_locked(std::cerr); -#endif - - state = TCP_CLOSED; - // return incoming_TimedWait(pkt); - { - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSED (recvd TCP_TIMED_WAIT?)"); - } - break; - } - delete pkt; - return 1; -} - - -int TcpStream::incoming_Closed(TcpPacket *pkt) -{ - /* if receive SYN - * -> respond SYN/ACK - * To State: SYN_RCVD - * - * else Discard. - */ - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Closed()" << std::endl; -#endif - if ((pkt -> hasSyn()) && (!pkt -> hasAck())) - { - /* Init Connection */ - - /* save seqno */ - initPeerSeqno = pkt -> seqno; - inAckno = initPeerSeqno + 1; - outWinSize = pkt -> winsize; - - - inWinSize = maxWinSize; - - /* we can get from SynSent as well, - * but only send one SYN packet - */ - - /* start packet */ - TcpPacket *rsp = new TcpPacket(); - - if (state == TCP_CLOSED) - { - outSeqno = genSequenceNo(); - initOurSeqno = outSeqno; - outAcked = outSeqno; /* min - 1 expected */ - - /* setup Congestion Charging */ - congestThreshold = TCP_MAX_WIN; - congestWinSize = MAX_SEG; - congestUpdate = outAcked + congestWinSize; - - rsp -> setSyn(); - } - - rsp -> setAck(inAckno); - /* seq + winsize set in toSend() */ - - /* as we have received something ... we can up the TTL */ - setTTL(TCP_STD_TTL); - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Closed() Sending reply" << std::endl; - std::cerr << "SeqNo: " << rsp->seqno << " Ack: " << rsp->ackno; - std::cerr << std::endl; -#endif - - toSend(rsp); - /* change state */ - state = TCP_SYN_RCVD; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_SYN_RCVD" << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_SYN_RECVD (recvd SYN & !ACK)"); - } - - delete pkt; - return 1; -} - - -int TcpStream::incoming_SynSent(TcpPacket *pkt) -{ - /* if receive SYN - * -> respond SYN/ACK - * To State: SYN_RCVD - * - * if receive SYN+ACK - * -> respond ACK - * To State: TCP_ESTABLISHED - * - * else Discard. - */ - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_SynSent()" << std::endl; -#endif - - if ((pkt -> hasSyn()) && (pkt -> hasAck())) - { - /* check stuff */ - if (pkt -> getAck() != outSeqno) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_SynSent() Bad Ack - Deleting " << std::endl; -#endif - /* bad ignore */ - delete pkt; - return -1; - } - - /* Complete Connection */ - - /* save seqno */ - initPeerSeqno = pkt -> seqno; - inAckno = initPeerSeqno + 1; - - outWinSize = pkt -> winsize; - - outAcked = pkt -> getAck(); - - /* before ACK, reset the TTL - * As they have sent something, and we have received - * through the firewall, set to STD. - */ - setTTL(TCP_STD_TTL); - - /* ack the Syn Packet */ - sendAck(); - - /* change state */ - state = TCP_ESTABLISHED; - outStreamActive = true; - inStreamActive = true; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_ESTABLISHED" << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_ESTABLISHED (recvd SUN & ACK)"); - - delete pkt; - } - else /* same as if closed! (simultaneous open) */ - { - return incoming_Closed(pkt); - } - return 1; -} - - -int TcpStream::incoming_SynRcvd(TcpPacket *pkt) -{ - /* if receive ACK - * To State: TCP_ESTABLISHED - */ - if (pkt -> hasRst()) - { - /* trouble */ - state = TCP_CLOSED; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_CLOSED" << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSED (recvd RST)"); - - delete pkt; - return 1; - } - - bool ackWithData = false; - - if (pkt -> hasAck()) - { - if (pkt -> hasSyn()) - { - /* has resent syn -> check it matches */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "incoming_SynRcvd -> Pkt with ACK + SYN" << std::endl; -#endif - } - - /* check stuff */ - if (pkt -> getAck() != outSeqno) - { - /* bad ignore */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "incoming_SynRcvd -> Ignoring Pkt with bad ACK" << std::endl; -#endif - delete pkt; - return -1; - } - - /* Complete Connection */ - - /* save seqno */ - if (pkt -> datasize > 0) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_SynRcvd() ACK with Data!" << std::endl; - std::cerr << "TcpStream::incoming_SynRcvd() Shoudn't recv ... unless initACK lost!" << std::endl; -#endif - // managed to trigger this under windows... - // perhaps the initial Ack was lost, - // believe we should just pass this packet - // directly to the incoming_Established... once - // the following has been done. - // and it should all work! - //exit(1); - ackWithData = true; - } - - inAckno = pkt -> seqno; /* + pkt -> datasize; */ - outWinSize = pkt -> winsize; - - outAcked = pkt -> getAck(); - - - /* As they have sent something, and we have received - * through the firewall, set to STD. - */ - setTTL(TCP_STD_TTL); - - /* change state */ - state = TCP_ESTABLISHED; - outStreamActive = true; - inStreamActive = true; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream STATE -> TCP_ESTABLISHED" << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_ESTABLISHED (have SYN, recvd ACK)"); - } - - if (ackWithData) - { - /* connection Established -> handle normally */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "incoming_SynRcvd -> Handling Data with Ack Pkt!"; - std::cerr << std::endl; -#endif - incoming_Established(pkt); - } - else - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "incoming_SynRcvd -> Ignoring Pkt!" << std::endl; -#endif - /* else nothing */ - delete pkt; - } - return 1; -} - -int TcpStream::incoming_Established(TcpPacket *pkt) -{ - /* first handle the Ack ... - * this must be done before the queue, - * to keep the values as up-to-date as possible. - * - * must sanity check ..... - * make sure that the sequence number is within the correct range. - */ - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Established() "; - std::cerr << " Pkt->seqno: " << std::hex << pkt->seqno; - std::cerr << " Pkt->datasize: " << std::hex << pkt->datasize; - std::cerr << std::dec << std::endl; -#endif - - if ((!isOldSequence(pkt->seqno, inAckno)) && // seq >= inAckno - isOldSequence(pkt->seqno, inAckno + maxWinSize)) // seq < inAckno + maxWinSize. - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Established() valid Packet Seqno."; - std::cerr << std::endl; -#endif - if (pkt->hasAck()) - { -#ifdef DEBUG_TCP_STREAM - if (outAcked != pkt->ackno) - { - std::cerr << "TcpStream::incoming_Established() valid Packet Seqno & new Ackno."; - std::cerr << std::endl; - std::cerr << "\tUpdating OutAcked to: " << outAcked; - std::cerr << std::endl; - } -#endif - outAcked = pkt->ackno; - } - - outWinSize = pkt->winsize; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "\tUpdating OutWinSize to: " << outWinSize; - std::cerr << std::endl; -#endif - } - else - { - /* what we do! (This is actually okay - and happens occasionally) */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Established() ERROR out-of-range Packet Seqno."; - std::cerr << std::endl; - std::cerr << "\t Pkt->SeqNo: " << std::hex << pkt->seqno; - std::cerr << std::endl; - std::cerr << "\t inAckno: " << std::hex << inAckno; - std::cerr << std::endl; - std::cerr << "\t inAckno + maxWinSize: " << std::hex << inAckno + maxWinSize; - std::cerr << std::endl; - std::cerr << "\t outAcked: " << std::hex << outAcked; - std::cerr << std::endl; - std::cerr << "\t Pkt->SeqNo: " << std::hex << pkt->seqno; - std::cerr << std::dec << std::endl; - std::cerr << "\t !isOldSequence(pkt->seqno, inAckno): " << (!isOldSequence(pkt->seqno, inAckno)); - std::cerr << std::endl; - std::cerr << "\t isOldSequence(pkt->seqno, inAckno + maxWinSize): " << isOldSequence(pkt->seqno, inAckno + maxWinSize); - std::cerr << std::endl; - std::cerr << std::endl; - - std::cerr << "TcpStream::incoming_Established() Sending Ack to update Peer"; - std::cerr << std::endl; -#endif - - sendAck(); - } - - - /* add to queue */ - inPkt.push_back(pkt); - - if (inPkt.size() > kMaxQueueSize) - { - TcpPacket *pkt = inPkt.front(); - inPkt.pop_front(); - delete pkt; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::incoming_Established() inPkt reached max size...Discarding Oldest Pkt"; - std::cerr << std::endl; -#endif - - } - - /* use as many packets as possible */ - return check_InPkts(); -} - -int TcpStream::check_InPkts() -{ - bool found = true; - TcpPacket *pkt; - std::list::iterator it; - while(found) - { - found = false; - for(it = inPkt.begin(); (!found) && (it != inPkt.end());) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "Checking expInAck: " << std::hex << inAckno; - std::cerr << " vs: " << std::hex << (*it)->seqno << std::dec << std::endl; -#endif - - pkt = *it; - if ((*it)->seqno == inAckno) - { - //std::cerr << "\tFOUND MATCH!"; - //std::cerr << std::endl; - - found = true; - it = inPkt.erase(it); - - } - - /* see if we can discard it */ - /* if smaller seqno, and not wrapping around */ - else if (isOldSequence((*it)->seqno, inAckno)) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "Discarding Old Packet expAck: " << std::hex << inAckno; - std::cerr << " seqno: " << std::hex << (*it)->seqno; - std::cerr << " pkt->size: " << std::hex << (*it)->datasize; - std::cerr << " pkt->seqno+size: " << std::hex << (*it)->seqno + (*it)->datasize; - std::cerr << std::dec << std::endl; -#endif - - /* discard */ - it = inPkt.erase(it); - delete pkt; - - } - else - { - ++it; - } - } - if (found) - { - -#ifdef DEBUG_TCP_STREAM_EXTRA - if (pkt->datasize) - { - checkData(pkt->data, pkt->datasize, pkt->seqno-initPeerSeqno-1); - } -#endif - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::check_inPkts() Updating inAckno from: " << std::hex << inAckno; -#endif - - /* update ack number - let it rollover */ - inAckno = pkt->seqno + pkt->datasize; - -#ifdef DEBUG_TCP_STREAM - std::cerr << " to: " << std::hex << inAckno; - std::cerr << std::dec << std::endl; -#endif - - /* XXX This shouldn't be here, as it prevents - * the Ack being used until the packet is. - * This means that a dropped packet will stop traffic in both - * directions.... - * - * Moved it to incoming_Established .... but extra - * check here to be sure! - */ - - if (pkt->hasAck()) - { - if (isOldSequence(outAcked, pkt->ackno)) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::check_inPkts() ERROR Ack Not Already Used!"; - std::cerr << std::endl; - std::cerr << "\t Pkt->ackno: " << std::hex << pkt->ackno; - std::cerr << std::endl; - std::cerr << "\t outAcked: " << std::hex << outAcked; - std::cerr << std::endl; - std::cerr << "\t Pkt->winsize: " << std::hex << pkt->winsize; - std::cerr << std::endl; - std::cerr << "\t outWinSize: " << std::hex << outWinSize; - std::cerr << std::endl; - std::cerr << "\t isOldSequence(outAcked, pkt->ackno): " << isOldSequence(outAcked, pkt->ackno); - std::cerr << std::endl; - std::cerr << std::endl; -#endif - - outAcked = pkt->ackno; - outWinSize = pkt->winsize; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "\tUpdating OutAcked to: " << outAcked; - std::cerr << std::endl; - std::cerr << "\tUpdating OutWinSize to: " << outWinSize; - std::cerr << std::endl; -#endif - - } - else - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::check_inPkts() GOOD Ack Already Used!"; - std::cerr << std::endl; -#endif - } - } - - /* push onto queue */ - - if (outSizeNet + pkt->datasize < MAX_SEG) - { - /* move onto outSizeNet */ - if (pkt->datasize) - { - memcpy((void *) &(outDataNet[outSizeNet]), pkt->data, pkt->datasize); - outSizeNet += pkt->datasize; - } - } - else - { - /* if it'll overflow the buffer. */ - dataBuffer *db = new dataBuffer(); - - /* move outDatNet -> buffer */ - memcpy((void *) db->data, (void *) outDataNet, outSizeNet); - - /* fill rest of space */ - int remSpace = MAX_SEG - outSizeNet; - memcpy((void *) &(db->data[outSizeNet]), (void *) pkt->data, remSpace); - - /* push packet onto queue */ - outQueue.push_back(db); - - /* any big chunks that will take up a full dataBuffer */ - int remData = pkt->datasize - remSpace; - while(remData >= MAX_SEG) - { - db = new dataBuffer(); - memcpy((void *) db->data, (void *) &(pkt->data[remSpace]), MAX_SEG); - - remData -= MAX_SEG; - outQueue.push_back(db); - } - - /* remove any remaining to outDataNet */ - outSizeNet = remData; - if (outSizeNet > 0) - { - memcpy((void *) outDataNet, (void *) &(pkt->data[pkt->datasize - remData]), outSizeNet); - } - } - - /* can allow more in! - update inWinSize */ - UpdateInWinSize(); - - /* if pkt is FIN */ - /* these must be here -> at the end of the reliable stream */ - /* if the fin is set, ack it specially close stream */ - if (pkt->hasFin()) - { - /* send final ack */ - sendAck(); - - /* closedown stream */ - inStreamActive = false; - - if (state == TCP_ESTABLISHED) - { - state = TCP_CLOSE_WAIT; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_CLOSE_WAIT"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSE_WAIT (recvd FIN)"); - } - else if (state == TCP_FIN_WAIT_1) - { - state = TCP_CLOSING; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_CLOSING"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSING (FIN_WAIT_1, recvd FIN)"); - } - else if (state == TCP_FIN_WAIT_2) - { - state = TCP_TIMED_WAIT; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_TIMED_WAIT"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_TIMED_WAIT (FIN_WAIT_2, recvd FIN)"); - - cleanup(); - } - } - - /* if ack for our FIN */ - if ((pkt->hasAck()) && (!outStreamActive) - && (pkt->ackno == outSeqno)) - { - if (state == TCP_FIN_WAIT_1) - { - state = TCP_FIN_WAIT_2; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_FIN_WAIT_2"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_FIN_WAIT_2 (FIN_WAIT_1, recvd ACK)"); - } - else if (state == TCP_LAST_ACK) - { -#ifdef DEBUG_TCP_STREAM_CLOSE - std::cerr << "TcpStream::state = TCP_CLOSED (LastAck)"; - std::cerr << std::endl; - dumpstate_locked(std::cerr); -#endif - - state = TCP_CLOSED; - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_CLOSED (LAST_ACK, recvd ACK)"); - - cleanup(); - } - else if (state == TCP_CLOSING) - { - state = TCP_TIMED_WAIT; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_TIMED_WAIT"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_TIMED_WAIT (TCP_CLOSING, recvd ACK)"); - - cleanup(); - } - } - - delete pkt; - - } /* end of found */ - } /* while(found) */ - return 1; -} - -/* This Fn should be called after each read, or recvd data (thats added to the buffer) - */ -int TcpStream::UpdateInWinSize() -{ - /* InWinSize = maxWinSze - QueuedData, - * actually we can allow a lot more to queue up... - * inWinSize = 65536, unless QueuedData > 65536. - * inWinSize = 2 * maxWinSize - QueuedData; - * - */ - - uint32 queuedData = int_read_pending(); - if (queuedData < maxWinSize) - { - inWinSize = maxWinSize; - } - else if (queuedData < 2 * maxWinSize) - { - inWinSize = 2 * maxWinSize - queuedData; - } - else - { - inWinSize = 0; - } - return inWinSize; -} - -int TcpStream::sendAck() -{ - /* simple -> toSend fills in ack/winsize - * and the rest is history - */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::sendAck()"; - std::cerr << std::endl; -#endif - - return toSend(new TcpPacket(), false); -} - -void TcpStream::setRemoteAddress(const struct sockaddr_in &raddr) -{ - peeraddr = raddr; - peerKnown = true; -} - - -int TcpStream::toSend(TcpPacket *pkt, bool retrans) -{ - int outPktSize = MAX_SEG + TCP_PSEUDO_HDR_SIZE; - char tmpOutPkt[outPktSize]; - - if (!peerKnown) - { - /* Major Error! */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::toSend() peerUnknown ERROR!!!"; - std::cerr << std::endl; -#endif - delete pkt; - return 0; - } - - /* get accurate timestamp */ - double cts = getCurrentTS(); - - pkt -> winsize = inWinSize; - pkt -> seqno = outSeqno; - - /* increment seq no */ - if (pkt->datasize) - { -#ifdef DEBUG_TCP_STREAM_EXTRA - checkData(pkt->data, pkt->datasize, outSeqno-initOurSeqno-1); -#endif - outSeqno += pkt->datasize; - } - - if (pkt->hasSyn()) - { - /* should not have data! */ - if (pkt->datasize) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "SYN Packet shouldn't contain data!" << std::endl; -#endif - } - outSeqno++; - } - else - { - /* cannot auto Ack SynPackets */ - pkt -> setAck(inAckno); - } - - pkt -> winsize = inWinSize; - - /* store old info */ - lastSentAck = pkt -> ackno; - lastSentWinSize = pkt -> winsize; - keepAliveTimer = cts; - - pkt -> writePacket(tmpOutPkt, outPktSize); - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::toSend() Seqno: "; - std::cerr << pkt->seqno << " size: " << pkt->datasize; - std::cerr << " Ackno: "; - std::cerr << pkt->ackno << " winsize: " << pkt->winsize; - std::cerr << std::endl; - //std::cerr << printPkt(tmpOutPkt, outPktSize) << std::endl; -#endif - - udp -> sendPkt(tmpOutPkt, outPktSize, peeraddr, ttl); - - if (retrans) - { - /* restart timers */ - pkt -> ts = cts; - pkt -> retrans = 0; - - startRetransmitTimer(); - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::toSend() Adding to outPkt --> Seqno: "; - std::cerr << pkt->seqno << " size: " << pkt->datasize; - std::cerr << std::endl; -#endif - - outPkt.push_back(pkt); - } - else - { - delete pkt; - } - return 1; -} - - -/* single retransmit timer. - * - */ -void TcpStream::startRetransmitTimer() -{ - if (retransTimerOn) - { - return; - } - - retransTimerTs = getCurrentTS(); - retransTimerOn = true; - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::startRetransmitTimer() peer: " << peeraddr; - std::cerr << " retransTimeout: " << retransTimeout; - std::cerr << " retransTimerTs: " << std::setprecision(12) < TCP_RETRANS_MAX_TIMEOUT) - { - retransTimeout = TCP_RETRANS_MAX_TIMEOUT; - } - -#ifdef DEBUG_TCP_STREAM_RETRANS - std::cerr << "TcpStream::incRetransmitTimer() peer: " << peeraddr; - std::cerr << " retransTimeout: " << std::setprecision(12) << retransTimeout; - std::cerr << std::endl; -#endif - -} - - - - - -int TcpStream::retrans() -{ - int outPktSize = MAX_SEG + TCP_PSEUDO_HDR_SIZE; - char tmpOutPkt[outPktSize]; - - if (!peerKnown) - { - /* Major Error! */ -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::retrans() peerUnknown ERROR!!!"; - std::cerr << std::endl; -#endif - return 0; - } - - if (!retransTimerOn) - { - return 0; - } - - double cts = getCurrentTS(); - if (cts - retransTimerTs < retransTimeout) - { - return 0; - } - - if (outPkt.begin() == outPkt.end()) - { - resetRetransmitTimer(); - return 0; - } - - TcpPacket *pkt = outPkt.front(); - - if (!pkt) - { - /* error */ - return 0; - } - - /* retransmission -> adjust the congestWinSize and congestThreshold - */ - - congestThreshold = congestWinSize / 2; - congestWinSize = MAX_SEG; - congestUpdate = outAcked + congestWinSize; // point when we can up the winSize. - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::retrans() Adjusting Congestion Parameters: "; - std::cerr << std::endl; - std::cerr << "\tcongestWinSize: " << congestWinSize; - std::cerr << " congestThreshold: " << congestThreshold; - std::cerr << " congestUpdate: " << congestUpdate; - std::cerr << std::endl; -#endif - - /* update ackno and winsize */ - if (!(pkt->hasSyn())) - { - pkt->setAck(inAckno); - lastSentAck = pkt -> ackno; - } - - pkt->winsize = inWinSize; - lastSentWinSize = pkt -> winsize; - - keepAliveTimer = cts; - - pkt->writePacket(tmpOutPkt, outPktSize); - -#ifdef DEBUG_TCP_STREAM_RETRANS - std::cerr << "TcpStream::retrans()"; - std::cerr << " peer: " << peeraddr; - std::cerr << " hasSyn: " << pkt->hasSyn(); - std::cerr << " Seqno: "; - std::cerr << pkt->seqno << " size: " << pkt->datasize; - std::cerr << " Ackno: "; - std::cerr << pkt->ackno << " winsize: " << pkt->winsize; - std::cerr << " retrans: " << (int) pkt->retrans; - std::cerr << " timeout: " << std::setprecision(12) << retransTimeout; - std::cerr << std::endl; - - //std::cerr << printPkt(tmpOutPkt, outPktSize) << std::endl; -#endif - - /* if its a syn packet ** thats been - * transmitting for a while, maybe - * we should increase the ttl. - */ - - if ((pkt->hasSyn()) && (getTTL() < TCP_STD_TTL)) - { - /* calculate a new TTL */ - if (mTTL_end > cts) - { - setTTL(TCP_DEFAULT_FIREWALL_TTL); - } - else - { - setTTL(getTTL() + 1); - } - - std::string out; - rs_sprintf(out, "TcpStream::retrans() Startup SYNs retrans count: %u New TTL: %d", pkt->retrans, getTTL()); - - rslog(RSL_WARNING, rstcpstreamzone, out); - -#ifdef DEBUG_TCP_STREAM - std::cerr << out.str() << std::endl; -#endif - } - - /* catch excessive retransmits - * - Allow Syn case more.... - * - if not SYN or TTL has reached STD then timeout quickly. - - * OLD 2nd Logic (below) has been replaced with lower logic. - * (((!pkt->hasSyn()) || (TCP_STD_TTL == getTTL())) - * && (pkt->retrans > kMaxPktRetransmit))) - * Problem was that the retransmit of Syn packet had STD_TTL, and was triggering Close (and SeqNo change). - * It seemed to work anyway.... But might cause coonnection failures. Will reduce the MaxSyn Retransmit - * so something more reasonable as well. - * ((!pkt->hasSyn()) && (pkt->retrans > kMaxPktRetransmit))) - */ - - if ((pkt->hasSyn() && (pkt->retrans > kMaxSynPktRetransmit)) || - ((!pkt->hasSyn()) && (pkt->retrans > kMaxPktRetransmit))) - - { - - /* too many attempts close stream */ -#ifdef DEBUG_TCP_STREAM_CLOSE - std::cerr << "TcpStream::retrans() Too many Retransmission Attempts ("; - std::cerr << (int) pkt->retrans << ") for Peer: " << peeraddr << std::endl; - std::cerr << "TcpStream::retrans() Closing Socket Connection"; - std::cerr << std::endl; - - //dumpPacket(std::cerr, (unsigned char *) tmpOutPkt, outPktSize); - dumpstate_locked(std::cerr); -#endif - - rslog(RSL_WARNING,rstcpstreamzone,"TcpStream::state => TCP_CLOSED (Too Many Retransmits)"); - - outStreamActive = false; - inStreamActive = false; - state = TCP_CLOSED; - cleanup(); - return 0; - } - - - udp -> sendPkt(tmpOutPkt, outPktSize, peeraddr, ttl); - - /* restart timers */ - pkt->ts = cts; - pkt->retrans++; - - /* - * finally - double the retransTimeout ... (Karn's Algorithm) - * except if we are starting a connection... i.e. hasSyn() - */ - - if (!pkt->hasSyn()) - { - incRetransmitTimeout(); - restartRetransmitTimer(); - } - else - { - resetRetransmitTimer(); - startRetransmitTimer(); - } - - return 1; -} - - -void TcpStream::acknowledge() -{ - /* cleans up acknowledge packets */ - /* packets are pushed back in order */ - std::list::iterator it; - double cts = getCurrentTS(); - bool updateRTT = true; - bool clearedPkts = false; - - for(it = outPkt.begin(); (it != outPkt.end()) && - (isOldSequence((*it)->seqno, outAcked)); - it = outPkt.erase(it)) - { - TcpPacket *pkt = (*it); - clearedPkts = true; - - /* adjust the congestWinSize and congestThreshold - * congestUpdate <= outAcked - * - ***/ - - if (!isOldSequence(outAcked, congestUpdate)) - { - if (congestWinSize < congestThreshold) - { - /* double it baby! */ - congestWinSize *= 2; - } - else - { - /* linear increase */ - congestWinSize += MAX_SEG; - } - - if (congestWinSize > maxWinSize) - { - congestWinSize = maxWinSize; - } - - congestUpdate = outAcked + congestWinSize; // point when we can up the winSize. - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::acknowledge() Adjusting Congestion Parameters: "; - std::cerr << std::endl; - std::cerr << "\tcongestWinSize: " << congestWinSize; - std::cerr << " congestThreshold: " << congestThreshold; - std::cerr << " congestUpdate: " << congestUpdate; - std::cerr << std::endl; -#endif - } - - - /* update the RoundTripTime, - * using Jacobson's values. - * RTT = a RTT + (1-a) M - * where - * RTT is RoundTripTime estimate. - * a = 7/8, - * M = time for ack. - * - * D = a D + (1 - a) | RTT - M | - * where - * D is approx Deviation. - * a,RTT & M are the same as above. - * - * Timeout = RTT + 4 * D. - * - * And Karn's Algorithm... - * which says - * (1) do not update RTT or D for retransmitted packets. - * + the ones that follow .... (the ones whos ack was - * delayed by the retranmission) - * (2) double timeout, when packets fail. (done in retrans). - */ - - if (pkt->retrans) - { - updateRTT = false; - } - - if (updateRTT) /* can use for RTT calc */ - { - double ack_time = cts - pkt->ts; - rtt_est = RTT_ALPHA * rtt_est + (1.0 - RTT_ALPHA) * ack_time; - rtt_dev = RTT_ALPHA * rtt_dev + (1.0 - RTT_ALPHA) * fabs(rtt_est - ack_time); - retransTimeout = rtt_est + 4.0 * rtt_dev; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::acknowledge() Updating RTT: "; - std::cerr << std::endl; - std::cerr << "\tAckTime: " << ack_time; - std::cerr << std::endl; - std::cerr << "\tRRT_est: " << rtt_est; - std::cerr << std::endl; - std::cerr << "\tRTT_dev: " << rtt_dev; - std::cerr << std::endl; - std::cerr << "\tTimeout: " << retransTimeout; - std::cerr << std::endl; -#endif - } - -#ifdef DEBUG_TCP_STREAM - else - { - std::cerr << "TcpStream::acknowledge() Not Updating RTT for retransmitted Pkt Sequence"; - std::cerr << std::endl; - } -#endif - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::acknowledge() Removing Seqno: "; - std::cerr << pkt->seqno << " size: " << pkt->datasize; - std::cerr << std::endl; -#endif - delete pkt; - } - - /* This is triggered if we have recieved acks for retransmitted packets.... - * In this case we want to reset the timeout, and remove the doubling. - * - * If we don't do this, and there have been more dropped packets, - * the the timeout gets continually doubled. which will virtually stop - * all communication. - * - * This will effectively trigger the retransmission of the next dropped packet. - */ - - /* - * if have acked all data - resetRetransTimer() - */ - - if (it == outPkt.end()) - { - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::acknowledge() peer: " << peeraddr; - std::cerr << " Backlog cleared, resetRetransmitTimer"; - std::cerr << std::endl; -#endif - resetRetransmitTimer(); - } - else if (clearedPkts) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::acknowledge() peer: " << peeraddr; - std::cerr << " Cleared some packets -> resetRetransmitTimer + start"; - std::cerr << std::endl; -#endif - resetRetransmitTimer(); - startRetransmitTimer(); - } - return; -} - - -int TcpStream::send() -{ - /* handle network interface always */ - /* clean up as much as possible */ - acknowledge(); - /* send any old packets */ - retrans(); - - - if (state < TCP_ESTABLISHED) - { - return -1; - } - - /* get the inQueue, can send */ - - - /* determine exactly how much we can send */ - uint32 maxsend = congestWinSize; - uint32 inTransit; - - if (outWinSize < congestWinSize) - { - maxsend = outWinSize; - } - - if (outSeqno < outAcked) - { - inTransit = (TCP_MAX_SEQ - outAcked) + outSeqno; - } - else - { - inTransit = outSeqno - outAcked; - } - - if (maxsend > inTransit) - { - maxsend -= inTransit; - } - else - { - maxsend = 0; - } - -#ifdef DEBUG_TCP_STREAM - int availSend = inQueue.size() * MAX_SEG + inSize; - std::cerr << "TcpStream::send() CC: "; - std::cerr << "oWS: " << outWinSize; - std::cerr << " cWS: " << congestWinSize; - std::cerr << " | inT: " << inTransit; - std::cerr << " mSnd: " << maxsend; - std::cerr << " aSnd: " << availSend; - std::cerr << " | oSeq: " << outSeqno; - std::cerr << " oAck: " << outAcked; - std::cerr << " cUpd: " << congestUpdate; - std::cerr << std::endl; -#endif - - int sent = 0; - while((inQueue.size() > 0) && (maxsend >= MAX_SEG)) - { - dataBuffer *db = inQueue.front(); - inQueue.pop_front(); - - TcpPacket *pkt = new TcpPacket(db->data, MAX_SEG); -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Segment ===> Seqno: "; - std::cerr << pkt->seqno << " size: " << pkt->datasize; - std::cerr << std::endl; -#endif - sent++; - maxsend -= MAX_SEG; - toSend(pkt); - delete db; - } - - /* if inqueue empty, and enough window space, send partial stuff */ - if ((!sent) && (inQueue.empty()) && (maxsend >= inSize) && (inSize)) - { - TcpPacket *pkt = new TcpPacket(inData, inSize); -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Remaining ===>"; - std::cerr << std::endl; -#endif - inSize = 0; - sent++; - maxsend -= inSize; - toSend(pkt); - } - - /* if send nothing */ - bool needsAck = false; - - if (!sent) - { - double cts = getCurrentTS(); - /* if needs ack */ - if (isOldSequence(lastSentAck,inAckno)) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Ack Triggered (Ackno)"; - std::cerr << std::endl; -#endif - needsAck = true; - } - - /* if needs window - * if added enough space for packet, or - * (this case is equivalent to persistence timer) - * haven't sent anything for a while, and the - * window size has drastically increased. - * */ - if (((lastSentWinSize < MAX_SEG) && (inWinSize > MAX_SEG)) || - ((cts - keepAliveTimer > retransTimeout * 4) && - (inWinSize > lastSentWinSize + 4 * MAX_SEG))) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Ack Triggered (Window)"; - std::cerr << std::endl; -#endif - needsAck = true; - } - - /* if needs keepalive */ - if (cts - keepAliveTimer > keepAliveTimeout) - { -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Ack Triggered (KAlive)"; - std::cerr << std::endl; -#endif - needsAck = true; - } - - - /* if end of stream -> switch mode -> send fin (with ack) */ - if ((!outStreamActive) && (inQueue.size() + inSize == 0) && - ((state == TCP_ESTABLISHED) || (state == TCP_CLOSE_WAIT))) - { - /* finish the stream */ - TcpPacket *pkt = new TcpPacket(); - pkt -> setFin(); - - needsAck = false; - toSend(pkt, false); - -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::send() Fin Triggered"; - std::cerr << std::endl; -#endif - - if (state == TCP_ESTABLISHED) - { - state = TCP_FIN_WAIT_1; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_FIN_WAIT_1"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_FIN_WAIT_1 (End of Stream)"); - } - else if (state == TCP_CLOSE_WAIT) - { - state = TCP_LAST_ACK; -#ifdef DEBUG_TCP_STREAM - std::cerr << "TcpStream::state = TCP_LAST_ACK"; - std::cerr << std::endl; -#endif - - rslog(RSL_WARNING, rstcpstreamzone, "TcpStream::state => TCP_LAST_ACK (CLOSE_WAIT, End of Stream)"); - } - - } - - if (needsAck) - { - sendAck(); - } -#ifdef DEBUG_TCP_STREAM_EXTRA - else - { - std::cerr << "TcpStream::send() No Ack"; - std::cerr << std::endl; - } -#endif - } -#ifdef DEBUG_TCP_STREAM_EXTRA - else - { - std::cerr << "TcpStream::send() Stuff Sent"; - std::cerr << std::endl; - } -#endif - return 1; -} - - -uint32 TcpStream::genSequenceNo() -{ - return RSRandom::random_u32(); - //return 1000; // TCP_MAX_SEQ - 1000; //1000; //(rand() - 100000) + time(NULL) % 100000; - //return (rand() - 100000) + time(NULL) % 100000; - -} - - -bool TcpStream::isOldSequence(uint32 tst, uint32 curr) -{ - return ((int)((tst)-(curr)) < 0); - - std::cerr << "TcpStream::isOldSequence(): Case "; - /* if tst < curr */ - if ((int)((tst)-(curr)) < 0) - { - if (curr - tst < TCP_MAX_SEQ/2) /* diff less than half span -> old */ - { - std::cerr << "1T" << std::endl; - return true; - } - std::cerr << "2F" << std::endl; - return false; - } - else if ((tst - curr) > TCP_MAX_SEQ/2) - { - std::cerr << "3T: tst-curr:" << (tst-curr) << std::endl; - return true; - } - std::cerr << "4F: tst-curr:" << (tst-curr) << std::endl; - return false; -} - -#ifdef WINDOWS_SYS -#include "util/rstime.h" -#include -#endif - -// Little fn to get current timestamp in an independent manner. -static double getCurrentTS() -{ - -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} - - - -uint32 TcpStream::int_wbytes() -{ - return outSeqno - initOurSeqno - 1; -} - -uint32 TcpStream::int_rbytes() -{ - return inAckno - initPeerSeqno - 1; -} - - - - -/********* Special debugging stuff *****/ - -#ifdef DEBUG_TCP_STREAM_EXTRA - -#include - -static FILE *bc_fd = 0; -int setupBinaryCheck(std::string fname) -{ - bc_fd = RsDirUtil::rs_fopen(fname.c_str(), "r"); - return 1; -} - -/* uses seq number to track position -> ensure no rollover */ -int checkData(uint8 *data, int size, int idx) -{ - if (bc_fd <= 0) - { - return -1; - } - std::cerr << "checkData(" << idx << "+" << size << ")"; - - int tmpsize = size; - uint8 tmpdata[tmpsize]; - if (-1 == fseek(bc_fd, idx, SEEK_SET)) - { - std::cerr << "Fseek Issues!" << std::endl; - exit(1); - return -1; - } - - if (1 != fread(tmpdata, tmpsize, 1, bc_fd)) - { - std::cerr << "Length Difference!" << std::endl; - exit(1); - return -1; - } - - for(int i = 0; i < size; i++) - { - if (data[i] != tmpdata[i]) - { - std::cerr << "Byte Difference!" << std::endl; - exit(1); - return -1; - } - } - std::cerr << "OK" << std::endl; - return 1; -} - -#endif - - -/***** Dump state of TCP Stream - to workout why it was closed ****/ -int TcpStream::dumpstate_locked(std::ostream &out) -{ - out << "TcpStream::dumpstate()"; - out << "======================================================="; - - out << std::endl; - out << "state: " << (int) state; - out << " errorState: " << (int) errorState; - out << std::endl; - - out << "(Streams) inStreamActive: " << inStreamActive; - out << " outStreamActive: " << outStreamActive; - out << std::endl; - - out << "(Timeouts) maxWinSize: " << maxWinSize; - out << " keepAliveTimeout: " << keepAliveTimeout; - out << " retransTimeout: " << retransTimeout; - out << std::endl; - - out << "(Timers) keepAliveTimer: " << std::setprecision(12) << keepAliveTimer; - out << " lastIncomingPkt: " << std::setprecision(12) << lastIncomingPkt; - out << std::endl; - - out << "(Tracking) lastSendAck: " << lastSentAck; - out << " lastSendWinSize: " << lastSentWinSize; - out << std::endl; - - out << "(Init) initOutSeqno: " << initOurSeqno; - out << " initPeerSeqno: " << initPeerSeqno; - out << std::endl; - - out << "(r/w) lastWriteTF: " << lastWriteTF; - out << " lastReadTF: " << lastReadTF; - out << " wcount: " << wcount; - out << " rcount: " << rcount; - out << std::endl; - - out << "(rtt) rtt_est: " << rtt_est; - out << " rtt_dev: " << rtt_dev; - out << std::endl; - - out << "(congestion) congestThreshold: " << congestThreshold; - out << " congestWinSize: " << congestWinSize; - out << " congestUpdate: " << congestUpdate; - out << std::endl; - - out << "(TTL) mTTL_period: " << mTTL_period; - out << " mTTL_start: " << std::setprecision(12) << mTTL_start; - out << " mTTL_end: " << std::setprecision(12) << mTTL_end; - out << std::endl; - - out << "(Peer) peerKnown: " << peerKnown; - out << " peerAddr: " << peeraddr; - out << std::endl; - - out << "-------------------------------------------------------"; - out << std::endl; - status_locked(out); - out << "======================================================="; - out << std::endl; - - return 1; -} - - -int TcpStream::dumpstate(std::ostream &out) -{ - tcpMtx.lock(); /********** LOCK MUTEX *********/ - - dumpstate_locked(out); - - tcpMtx.unlock(); /******** UNLOCK MUTEX *********/ - - return 1; -} - - -int dumpPacket(std::ostream &out, unsigned char *pkt, uint32_t size) -{ - uint32_t i; - - out << "dumpPacket() Size: " << size; - out << std::endl; - out << "------------------------------------------------------"; - for(i = 0; i < size; i++) - { - if (i % 16 == 0) - { - out << std::endl; - } - out << std::hex << std::setfill('0') << std::setw(2) << (int) pkt[i] << ":"; - } - if ((i - 1) % 16 != 0) - { - out << std::endl; - } - out << "------------------------------------------------------"; - out << std::dec << std::endl; - - return 1; -} - - diff --git a/libretroshare/src/tcponudp/tcpstream.h b/libretroshare/src/tcponudp/tcpstream.h deleted file mode 100644 index 87ed693d0..000000000 --- a/libretroshare/src/tcponudp/tcpstream.h +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tcpstream.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef TOU_TCP_PROTO_H -#define TOU_TCP_PROTO_H - - -/* so the packet will contain - * a tcp header + data. - * - * This is done simplistically for speed. - */ - -#include "tcppacket.h" -#include "udppeer.h" - -// WINDOWS doesn't like UDP packets bigger than 1492 (truncates them). -// We have up to 64 bytes of headers: 28(udp) + 16(relay) + 20(tou) = 64 bytes. -// 64 bytes + 1400 = 1464, leaves a small margin, but close to maximum throughput. -//#define MAX_SEG 1400 -// We are going to start at 1000 (to avoid any fragmentation, and work up). -#define MAX_SEG 1000 - -#define TCP_MAX_SEQ UINT_MAX -#define TCP_MAX_WIN 65500 -#define TCP_ALIVE_TIMEOUT 15 /* 15 sec ... < 20 sec UDP state limit on some firewalls */ -#define TCP_RETRANS_TIMEOUT 1 /* 1 sec (Initial value) */ -#define TCP_RETRANS_MAX_TIMEOUT 15 /* 15 secs */ -#define kNoPktTimeout 60 /* 1 min */ - - -#define TCP_CLOSED 0 -#define TCP_LISTEN 1 -#define TCP_SYN_SENT 2 -#define TCP_SYN_RCVD 3 -#define TCP_ESTABLISHED 4 -#define TCP_FIN_WAIT_1 5 -#define TCP_FIN_WAIT_2 6 -#define TCP_TIMED_WAIT 7 -#define TCP_CLOSING 8 -#define TCP_CLOSE_WAIT 9 -#define TCP_LAST_ACK 10 - -class dataBuffer -{ - public: - uint8 data[MAX_SEG]; -}; - -#include -#include - - -class TcpStream: public UdpPeer -{ - public: - /* Top-Level exposed */ - - TcpStream(UdpSubReceiver *udp); -virtual ~TcpStream() { return; } - - /* user interface */ -int status(std::ostream &out); -int connect(const struct sockaddr_in &raddr, uint32_t conn_period); -int listenfor(const struct sockaddr_in &raddr); -bool isConnected(); - - /* get tcp information */ -bool getRemoteAddress(struct sockaddr_in &raddr); -uint8 TcpState(); -int TcpErrorState(); - - /* stream Interface */ -int write(char *dta, int size); /* write -> pkt -> net */ -int read(char *dta, int size); /* net -> pkt -> read */ - - /* check ahead for allowed bytes */ -int write_allowed(); -int read_pending(); - -int closeWrite(); /* non-standard, but for clean exit */ -int close(); /* standard unix behaviour */ - -int tick(); /* check iface etc */ - - /* Callback Funcion from UDP Layers */ -virtual void recvPkt(void *data, int size); /* overloaded */ - - - - /* Exposed Data Counting */ -bool widle(); /* write idle */ -bool ridle(); /* read idle */ -uint32 wbytes(); -uint32 rbytes(); - - /* Exposed for debugging */ -int dumpstate(std::ostream &out); - - private: - - /* Internal Functions - use the Mutex (not reentrant) */ - /* Internal Functions - that don't need mutex protection */ - -uint32 genSequenceNo(); -bool isOldSequence(uint32 tst, uint32 curr); - - RsMutex tcpMtx; - - /* Internal Functions - only called inside mutex protection */ - -int dumpstate_locked(std::ostream &out); -int status_locked(std::ostream &out); - -int cleanup(); - -/* incoming data */ -int recv_check(); -int handleIncoming(TcpPacket *pkt); -int incoming_Closed(TcpPacket *pkt); -int incoming_SynSent(TcpPacket *pkt); -int incoming_SynRcvd(TcpPacket *pkt); -int incoming_Established(TcpPacket *pkt); -int incoming_FinWait1(TcpPacket *pkt); -int incoming_FinWait2(TcpPacket *pkt); -int incoming_TimedWait(TcpPacket *pkt); -int incoming_Closing(TcpPacket *pkt); -int incoming_CloseWait(TcpPacket *pkt); -int incoming_LastAck(TcpPacket *pkt); -int check_InPkts(); -int UpdateInWinSize(); -int int_read_pending(); - -/* outgoing data */ -int send(); -int toSend(TcpPacket *pkt, bool retrans = true); -void acknowledge(); -int retrans(); -int sendAck(); -void setRemoteAddress(const struct sockaddr_in &raddr); - -int getTTL() { return ttl; } -void setTTL(int t) { ttl = t; } - -/* retransmission */ -void startRetransmitTimer(); -void restartRetransmitTimer(); -void stopRetransmitTimer(); -void resetRetransmitTimer(); -void incRetransmitTimeout(); - - -/* data counting */ -uint32 int_wbytes(); -uint32 int_rbytes(); - - /* Internal Data - must have mutex to access! */ - - /* data (in -> pkts) && (pkts -> out) */ - - /* for small amounts of data */ - uint8 inData[MAX_SEG]; - uint32 inSize; - - - /* two variable sized buffers required here */ - uint8 outDataRead[MAX_SEG]; - uint32 outSizeRead; - uint8 outDataNet[MAX_SEG]; - uint32 outSizeNet; - - /* get packed into here as size increases */ - std::deque inQueue, outQueue; - - /* packets waiting for acks */ - std::list inPkt, outPkt; - - - uint8 state; /* stream state */ - bool inStreamActive; - bool outStreamActive; - - uint32 outSeqno; /* next out */ - uint32 outAcked; /* other size has received */ - uint32 outWinSize; /* we allowed to send */ - - uint32 inAckno; /* next expected */ - uint32 inWinSize; /* allowing other to send */ - - /* some (initially) consts */ - uint32 maxWinSize; - uint32 keepAliveTimeout; - - /* retransmit */ - bool retransTimerOn; - double retransTimeout; - double retransTimerTs; - - /* some timers */ - double keepAliveTimer; - double lastIncomingPkt; - - /* tracking */ - uint32 lastSentAck; - uint32 lastSentWinSize; - uint32 initOurSeqno; - uint32 initPeerSeqno; - - uint32 lastWriteTF,lastReadTF; - uint16 wcount, rcount; - - int errorState; - - /* RoundTripTime estimations */ - double rtt_est; - double rtt_dev; - - /* congestion limits */ - uint32 congestThreshold; - uint32 congestWinSize; - uint32 congestUpdate; - - /* existing TTL for this stream (tweaked at startup) */ - int ttl; - - double mTTL_period; - double mTTL_start; - double mTTL_end; - - struct sockaddr_in peeraddr; - bool peerKnown; - - /* UdpSubReceiver (has own Mutex!) */ - UdpSubReceiver *udp; - -}; - - -/* for debugging */ - -#ifdef TCP_DEBUG_STREAM_EXTRA /* for extra checking! */ -int setupBinaryCheck(std::string fname); -#endif - - - -#endif - diff --git a/libretroshare/src/tcponudp/tou.cc b/libretroshare/src/tcponudp/tou.cc deleted file mode 100644 index 96c8797d9..000000000 --- a/libretroshare/src/tcponudp/tou.cc +++ /dev/null @@ -1,663 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tou.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "tou.h" - -static const int kInitStreamTable = 5; - -#include -#include -#include -#include -#include - -#include "util/rstime.h" -#include "udp/udpstack.h" -#include "pqi/pqinetwork.h" -#include "tcpstream.h" -#include "util/stacktrace.h" - -#define DEBUG_TOU_INTERFACE 1 -#define EUSERS 87 - -struct TcpOnUdp_t -{ - int tou_fd; - int lasterrno; - TcpStream *tcp; - UdpSubReceiver *udpsr; - int udptype; - bool idle; -}; - -typedef struct TcpOnUdp_t TcpOnUdp; - -static RsMutex touMutex("touMutex"); -// Mutex is used to control addition / removals from tou_streams. -// Lookup should be okay - as long as you stick to your allocated ID! - -static std::vector tou_streams; - -static int tou_inited = 0; - - -#include "tcponudp/udppeer.h" -#include "tcponudp/udprelay.h" - -static UdpSubReceiver *udpSR[MAX_TOU_RECEIVERS] = {NULL}; -static uint32_t udpType[MAX_TOU_RECEIVERS] = { 0 }; -static uint32_t noUdpSR = 0; - -/* tou_init - * - * Modified to accept a number of UdpSubRecievers! - * these can be linked to arbitary UdpStacks. - * (removed all UdpStack references here!) - * - * Unfortunately, the UdpSubReceivers have different initialisation for starting a connection. - * So the TOU interface has to accomodate this. - * - */ -/* tou_init - opens the udp port (universal bind) */ -int tou_init(void **in_udpsubrecvs, int *type, int number) -{ - RsStackMutex stack(touMutex); /***** LOCKED ******/ - - UdpSubReceiver **usrArray = (UdpSubReceiver **) in_udpsubrecvs; - if (number > MAX_TOU_RECEIVERS) - { - std::cerr << "tou_init() Invalid number of receivers"; - std::cerr << std::endl; - return 0; - } - - if (tou_inited) - { - return 1; - } - - noUdpSR = number; - uint32_t i; - for(i = 0; i < noUdpSR; i++) - { - udpSR[i] = usrArray[i]; - udpType[i] = type[i]; - } - - tou_streams.resize(kInitStreamTable); - - tou_inited = 1; - return 1; -} - - -/* open - allocates a sockfd, and checks that the type is okay */ -int tou_socket(uint32_t recvIdx, uint32_t type, int /*protocol*/) -{ - RsStackMutex stack(touMutex); /***** LOCKED ******/ - - if (!tou_inited) - { - return -1; - } - - if (recvIdx >= noUdpSR) - { - std::cerr << "tou_socket() ERROR recvIdx greater than #receivers"; - std::cerr << std::endl; - return -1; - } - - /* check that the index matches the type */ - UdpSubReceiver *recver = udpSR[recvIdx]; - uint32_t recverType = udpType[recvIdx]; - - if (recverType != type) - { - std::cerr << "tou_socket() ERROR type doesn't match expected type"; - std::cerr << std::endl; - return -1; - } - - for(unsigned int i = 1; i < tou_streams.size(); i++) - { - if (tou_streams[i] == NULL) - { - tou_streams[i] = new TcpOnUdp(); - tou_streams[i] -> tou_fd = i; - tou_streams[i] -> tcp = NULL; - tou_streams[i] -> udpsr = recver; - tou_streams[i] -> udptype = recverType; - return i; - } - } - - TcpOnUdp *tou = new TcpOnUdp(); - - tou_streams.push_back(tou); - - if (tou == tou_streams[tou_streams.size() -1]) - { - tou -> tou_fd = tou_streams.size() -1; - tou -> tcp = NULL; - tou -> udpsr = recver; - tou -> udptype = recverType; - return tou->tou_fd; - } - - tou -> lasterrno = EUSERS; - - return -1; -} - - -bool tou_stream_check(int sockfd) -{ - if(sockfd < 0) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR sockfd: " << sockfd - << " < 0" << std::endl; - print_stacktrace(); - return false; - } - - if(sockfd >= tou_streams.size()) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR sockfd: " << sockfd - << " out of bound!" << std::endl; - print_stacktrace(); - return false; - } - - if(!tou_streams[sockfd]) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR tou_streams[sockfd] == NULL" - << std::endl; - print_stacktrace(); - return false; - } - - return true; -} - -/* bind - opens the udp port */ -int tou_bind(int sockfd, const struct sockaddr * /* my_addr */, socklen_t /* addrlen */ ) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - /* this now always returns an error! */ - tous -> lasterrno = EADDRINUSE; - return -1; -} - -/* records peers address, and sends syn pkt - * the timeout is very slow initially - to give - * the peer a chance to startup - * - * - like a tcp/ip connection, the connect - * will return -1 EAGAIN, until connection complete. - * - always non blocking. - */ -int tou_connect(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen, uint32_t conn_period) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - - if (addrlen < sizeof(struct sockaddr_in)) - { - std::cerr << "tou_connect() ERROR invalid size of sockaddr"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - // only IPv4 for the moment. - const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) serv_addr; - if (ss_addr->ss_family != AF_INET) - { - std::cerr << "tou_connect() ERROR not ipv4"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - /* enforce that the udptype is correct */ - if (tous -> udptype != TOU_RECEIVER_TYPE_UDPPEER) - { - std::cerr << "tou_connect() ERROR connect method invalid for udptype"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - -#ifdef TOU_DYNAMIC_CAST_CHECK - /* extra checking -> for testing purposes (dynamic cast) */ - UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); - if (!upr) - { - std::cerr << "tou_connect() ERROR cannot convert type to UdpPeerReceiver"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } -#else - UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); -#endif - - /* create a TCP stream to connect with. */ - if (!tous->tcp) - { - tous->tcp = new TcpStream(tous->udpsr); - upr->addUdpPeer(tous->tcp, - *((const struct sockaddr_in *) serv_addr)); - } - - tous->tcp->connect(*(const struct sockaddr_in *) serv_addr, conn_period); - tous->tcp->tick(); - if (tous->tcp->isConnected()) - { - return 0; - } - - tous -> lasterrno = EINPROGRESS; - return -1; -} - -/* is this ever used? should it be depreciated? */ -int tou_listenfor(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - if (addrlen < sizeof(struct sockaddr_in)) - { - std::cerr << "tou_listenfor() ERROR invalid size of sockaddr"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - // only IPv4 for the moment. - const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) serv_addr; - if (ss_addr->ss_family != AF_INET) - { - std::cerr << "tou_listenfor() ERROR not ipv4"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - - /* enforce that the udptype is correct */ - if (tous -> udptype != TOU_RECEIVER_TYPE_UDPPEER) - { - std::cerr << "tou_connect() ERROR connect method invalid for udptype"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - -#ifdef TOU_DYNAMIC_CAST_CHECK - /* extra checking -> for testing purposes (dynamic cast) */ - UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); - if (!upr) - { - std::cerr << "tou_connect() ERROR cannot convert type to UdpPeerReceiver"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } -#else - UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); -#endif - - /* create a TCP stream to connect with. */ - if (!tous->tcp) - { - tous->tcp = new TcpStream(tous->udpsr); - upr->addUdpPeer(tous->tcp, - *((const struct sockaddr_in *) serv_addr)); - } - - tous->tcp->listenfor(*((struct sockaddr_in *) serv_addr)); - tous->tcp->tick(); - - return 0; -} - -int tou_listen(int /* sockfd */ , int /* backlog */ ) -{ - return 1; -} - -/* - * This is the alternative RELAY connection. - * - * User needs to provide 3 ip addresses. - * These addresses should have been provided by the RELAY negogiation - * a) own ip:port - * b) proxy ip:port - * c) dest ip:port - * - * The reset of the startup is similar to other TOU connections. - * As this is likely to be run over an established UDP connection, - * there is little need for a big connection period. - * - * - like a tcp/ip connection, the connect - * will return -1 EAGAIN, until connection complete. - * - always non blocking. - */ -#define DEFAULT_RELAY_CONN_PERIOD 1 - -int tou_connect_via_relay( int sockfd, const sockaddr_in& own_addr, - const sockaddr_in& proxy_addr, - const sockaddr_in& dest_addr ) - -{ - std::cerr << __PRETTY_FUNCTION__ << std::endl; - - if (!tou_stream_check(sockfd)) return -EINVAL; - - TcpOnUdp& tous = *tou_streams[sockfd]; - - /* enforce that the udptype is correct */ - if (tous.udptype != TOU_RECEIVER_TYPE_UDPRELAY) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR connect method invalid for " - << "udptype" << std::endl; - tous.lasterrno = EINVAL; - return -EINVAL; - } - - UdpRelayReceiver* urr_ptr = dynamic_cast(tous.udpsr); - if(!urr_ptr) - { - std::cerr << __PRETTY_FUNCTION__ << " ERROR cannot convert to " - << "UdpRelayReceiver" << std::endl; - tous.lasterrno = EINVAL; - return -EINVAL; - } - - UdpRelayReceiver& urr = *urr_ptr; urr_ptr = nullptr; - - /* create a TCP stream to connect with. */ - if (!tous.tcp) - { - tous.tcp = new TcpStream(tous.udpsr); - - UdpRelayAddrSet addrSet(&own_addr, &dest_addr); - urr.addUdpPeer(tous.tcp, &addrSet, &proxy_addr); - } - - /* We Point it at the Destination Address. - * The UdpRelayReceiver wraps and re-directs the packets to the proxy - */ - tous.tcp->connect(dest_addr, DEFAULT_RELAY_CONN_PERIOD); - tous.tcp->tick(); - if (tous.tcp->isConnected()) return 0; - - tous.lasterrno = EINPROGRESS; - return -EINPROGRESS; -} - - - /* slightly different - returns sockfd on connection */ -int tou_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - if (*addrlen < sizeof(struct sockaddr_in)) - { - std::cerr << "tou_accept() ERROR invalid size of sockaddr"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - // only IPv4 for the moment. - const struct sockaddr_storage *ss_addr = (struct sockaddr_storage *) addr; - if (ss_addr->ss_family != AF_INET) - { - std::cerr << "tou_accept() ERROR not ipv4"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - return -1; - } - - //tous->tcp->connect(); - tous->tcp->tick(); - if (tous->tcp->isConnected()) - { - // should get remote address - tous->tcp->getRemoteAddress(*((struct sockaddr_in *) addr)); - return sockfd; - } - - tous -> lasterrno = EAGAIN; - return -1; -} - - -int tou_connected(int sockfd) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - tous->tcp->tick(); - - return (tous->tcp->TcpState() == 4); -} - - -/* standard stream read/write non-blocking of course - */ - -ssize_t tou_read(int sockfd, void *buf, size_t count) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - tous->tcp->tick(); - - int err = tous->tcp->read((char *) buf, count); - if (err < 0) - { - tous->lasterrno = tous->tcp->TcpErrorState(); - return -1; - } - return err; -} - -ssize_t tou_write(int sockfd, const void *buf, size_t count) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - - - int err = tous->tcp->write((char *) buf, count); - if (err < 0) - { - tous->lasterrno = tous->tcp->TcpErrorState(); - tous->tcp->tick(); - return -1; - } - tous->tcp->tick(); - return err; -} - - /* check stream */ -int tou_maxread(int sockfd) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - tous->tcp->tick(); - - int ret = tous->tcp->read_pending(); - if (ret < 0) - { - tous->lasterrno = tous->tcp->TcpErrorState(); - return 0; // error detected next time. - } - return ret; -} - -int tou_maxwrite(int sockfd) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - tous->tcp->tick(); - - int ret = tous->tcp->write_allowed(); - if (ret < 0) - { - tous->lasterrno = tous->tcp->TcpErrorState(); - return 0; // error detected next time? - } - return ret; -} - - -/* close down the tcp over udp connection */ -int tou_close(int sockfd) -{ - TcpOnUdp *tous = NULL; - { - RsStackMutex stack(touMutex); /***** LOCKED ******/ - if (!tou_stream_check(sockfd)) - { - return -1; - } - tous = tou_streams[sockfd]; - tou_streams[sockfd] = NULL; - } - - if (tous->tcp) - { - tous->tcp->tick(); - - /* shut it down */ - tous->tcp->close(); - - /* now we need to work out which type of receiver we have */ -#ifdef TOU_DYNAMIC_CAST_CHECK - /* extra checking -> for testing purposes (dynamic cast) */ - UdpRelayReceiver *urr = dynamic_cast(tous->udpsr); - UdpPeerReceiver *upr = dynamic_cast(tous->udpsr); - if (urr) - { - urr->removeUdpPeer(tous->tcp); - } - else if (upr) - { - upr->removeUdpPeer(tous->tcp); - } - else - { - /* error */ - std::cerr << "tou_close() ERROR unknown udptype"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - } -#else - if (tous -> udptype == TOU_RECEIVER_TYPE_UDPRELAY) - { - UdpRelayReceiver *urr = (UdpRelayReceiver *) (tous->udpsr); - urr->removeUdpPeer(tous->tcp); - } - else if (tous -> udptype == TOU_RECEIVER_TYPE_UDPPEER) - { - UdpPeerReceiver *upr = (UdpPeerReceiver *) (tous->udpsr); - upr->removeUdpPeer(tous->tcp); - } - else - { - /* error */ - std::cerr << "tou_close() ERROR unknown udptype"; - std::cerr << std::endl; - tous -> lasterrno = EINVAL; - } - -#endif - - delete tous->tcp; - tous->tcp = NULL ; // prevents calling - - } - - delete tous; - return 1; -} - -/* get an error number */ -int tou_errno(int sockfd) -{ - if (!tou_stream_check(sockfd)) - { - return ENOTSOCK; - } - TcpOnUdp *tous = tou_streams[sockfd]; - return tous->lasterrno; -} - -int tou_clear_error(int sockfd) -{ - if (!tou_stream_check(sockfd)) - { - return -1; - } - TcpOnUdp *tous = tou_streams[sockfd]; - tous->lasterrno = 0; - return 0; -} - diff --git a/libretroshare/src/tcponudp/tou.h b/libretroshare/src/tcponudp/tou.h deleted file mode 100644 index 5635c50c5..000000000 --- a/libretroshare/src/tcponudp/tou.h +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: tou.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef TOU_C_HEADER_H -#define TOU_C_HEADER_H - - -/* get OS-specific definitions for: - * struct sockaddr, socklen_t, ssize_t - */ - -#ifndef WINDOWS_SYS - - #include - #include - #include - -#else - #include - #include - #include -// #include - typedef int socklen_t; -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -/* standard C interface (as Unix-like as possible) - * for the tou (Tcp On Udp) library - */ - /* - * Init: - * The TOU library no longer references any UdpStack items. - * instead, two arrays should be passed to the init function. - * int tou_init( (void **) UdpSubReceiver **udpRecvers, int *udpType, int nUdps); - * - * The UdpSubReceivers should be derived classes, with corresponding types: - * UdpPeerReceiver TOU_RECEIVER_TYPE_UDPPEER - * UdpRelayReceiver TOU_RECEIVER_TYPE_UDPRELAY - * - */ - -#define MAX_TOU_RECEIVERS 16 - -#define TOU_RECEIVER_TYPE_NONE 0x0000 -#define TOU_RECEIVER_TYPE_UDPPEER 0x0001 -#define TOU_RECEIVER_TYPE_UDPRELAY 0x0002 - -// hack to avoid classes in C code. (MacOSX complaining) -int tou_init(void **udpSubRecvs, int *udpTypes, int nUdps); - - /* Connections are as similar to UNIX as possible - * (1) create a socket: tou_socket() this reserves a socket id. - * (2) connect: active: tou_connect() or passive: tou_listenfor(). - * (3) use as a normal socket. - * - * connect() now has a conn_period parameter - this is the - * estimate (in seconds) of how slowly the connection should proceed. - * - * tou_bind() is not valid. tou_init performs this role. - * tou_listen() is not valid. (must listen for a specific address) use tou_listenfor() instead. - * tou_accept() can still be used. - * - ****** THE ABOVE IS BECOMING LESS TRUE ******** - * - * I have now added Multiple type of TOU Connections (Proxy, Relay), - * and multiple UDP Receivers (meaning you can use different ports too). - * - * The UDP receivers must be specified at startup (new tou_init()) - * and the Receiver, and Type of connection must be specified when you - * open the socket. - * - * The parameters to tou_socket, therefore mean something! - * some extra checking has been put in to try and catch bad usage. - */ - - /* creation/connections */ -int tou_socket(uint32_t domain, uint32_t type, int protocol); -int tou_bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); /* null op now */ -int tou_listen(int sockfd, int backlog); /* null op now */ -int tou_connect(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen, uint32_t conn_period); -int tou_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - -/* non-standard bonuses */ -int tou_connected(int sockfd); -int tou_listenfor(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); - - - - /* UNIX interface: minimum for the SSL BIO interface */ -ssize_t tou_read(int sockfd, void *buf, size_t count); -ssize_t tou_write(int sockfd, const void *buf, size_t count); -int tou_close(int sockfd); - - /* non-standard */ -int tou_errno(int sockfd); -int tou_clear_error(int sockfd); - - /* check stream */ -int tou_maxread(int sockfd); -int tou_maxwrite(int sockfd); - - -#ifdef __cplusplus -} - -typedef struct sockaddr_in sockaddr_in; - -/// for relay connections -int tou_connect_via_relay( int sockfd, const sockaddr_in& own_addr, - const sockaddr_in& proxy_addr, - const sockaddr_in& dest_addr ); - -#endif -#endif - diff --git a/libretroshare/src/tcponudp/udppeer.cc b/libretroshare/src/tcponudp/udppeer.cc deleted file mode 100644 index b3cf10913..000000000 --- a/libretroshare/src/tcponudp/udppeer.cc +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udppeer.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "udppeer.h" -#include - -/* - * #define DEBUG_UDP_PEER 1 - */ - - -UdpPeerReceiver::UdpPeerReceiver(UdpPublisher *pub) - :UdpSubReceiver(pub), peerMtx("UdpSubReceiver") -{ - return; -} - -/* higher level interface */ -int UdpPeerReceiver::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* print packet information */ -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; -#endif - - RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/ - - /* look for a peer */ - std::map::iterator it; - it = streams.find(from); - - if (it == streams.end()) - { - /* peer unknown */ -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::recvPkt() Peer Unknown!"; - std::cerr << std::endl; -#endif - return 0; - } - else - { - /* forward to them */ -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::recvPkt() Sending to UdpPeer: "; - std::cerr << it->first; - std::cerr << std::endl; -#endif - (it->second)->recvPkt(data, size); - return 1; - } - /* done */ -} - - -int UdpPeerReceiver::status(std::ostream &out) -{ - RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/ - - out << "UdpPeerReceiver::status()" << std::endl; - out << "UdpPeerReceiver::peers:" << std::endl; - std::map::iterator it; - for(it = streams.begin(); it != streams.end(); ++it) - { - out << "\t" << it->first << std::endl; - } - out << std::endl; - - return 1; -} - - /* add a TCPonUDP stream */ -int UdpPeerReceiver::addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr) -{ - RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/ - - - /* check for duplicate */ - std::map::iterator it; - it = streams.find(raddr); - bool ok = (it == streams.end()); - if (!ok) - { -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::addUdpPeer() Peer already exists!" << std::endl; - std::cerr << "UdpPeerReceiver::addUdpPeer() ERROR" << std::endl; -#endif - } - else - { - streams[raddr] = peer; - } - - return ok; -} - -int UdpPeerReceiver::removeUdpPeer(UdpPeer *peer) -{ - RsStackMutex stack(peerMtx); /********** LOCK MUTEX *********/ - - /* check for duplicate */ - std::map::iterator it; - for(it = streams.begin(); it != streams.end(); ++it) - { - if (it->second == peer) - { -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::removeUdpPeer() SUCCESS" << std::endl; -#endif - streams.erase(it); - return 1; - } - } - -#ifdef DEBUG_UDP_PEER - std::cerr << "UdpPeerReceiver::removeUdpPeer() ERROR" << std::endl; -#endif - return 0; -} - - diff --git a/libretroshare/src/tcponudp/udppeer.h b/libretroshare/src/tcponudp/udppeer.h deleted file mode 100644 index 9ecf23419..000000000 --- a/libretroshare/src/tcponudp/udppeer.h +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udppeer.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UDP_PEER_RECV_H -#define RS_UDP_PEER_RECV_H - -#ifndef WINDOWS_SYS -#include -#endif - -#include "util/rsthreads.h" - -#include -#include -#include - -#include "tcponudp/rsudpstack.h" - -class UdpPeer -{ - public: -virtual ~UdpPeer() { return; } -virtual void recvPkt(void *data, int size) = 0; -}; - - -class UdpPeerReceiver: public UdpSubReceiver -{ - public: - - UdpPeerReceiver(UdpPublisher *pub); -virtual ~UdpPeerReceiver() { return; } - - /* add a TCPonUDP stream */ -int addUdpPeer(UdpPeer *peer, const struct sockaddr_in &raddr); -int removeUdpPeer(UdpPeer *peer); - - /* callback for recved data (overloaded from UdpReceiver) */ -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); - -int status(std::ostream &out); - - private: - - RsMutex peerMtx; /* for all class data (below) */ - - std::map streams; - -}; - - -#endif diff --git a/libretroshare/src/tcponudp/udprelay.cc b/libretroshare/src/tcponudp/udprelay.cc deleted file mode 100644 index 68062b860..000000000 --- a/libretroshare/src/tcponudp/udprelay.cc +++ /dev/null @@ -1,1117 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udprelay.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "udprelay.h" -#include -#include "util/rstime.h" -#include - -/* - * #define DEBUG_UDP_RELAY 1 - * #define DEBUG_UDP_RELAY_PKTS 1 - * #define DEBUG_UDP_RELAY_ERRORS 1 - */ - -#define DEBUG_UDP_RELAY_ERRORS 1 - -#ifdef DEBUG_UDP_RELAY -// DEBUG FUNCTION -#include "util/rsstring.h" -#include -int displayUdpRelayPacketHeader(const void *data, const int size); -#endif - -/****************** UDP RELAY STUFF **********/ - -// This packet size must be able to handle TcpStream Packets. -// At the moment, they can be 1000 + 20 for TcpOnUdp ... + 16 => 1036 minimal size. -// See Notes in tcpstream.h for more info -#define MAX_RELAY_UDP_PACKET_SIZE (1400 + 20 + 16) - - -UdpRelayReceiver::UdpRelayReceiver(UdpPublisher *pub) - :UdpSubReceiver(pub), udppeerMtx("UdpSubReceiver"), relayMtx("UdpSubReceiver") -{ - mClassLimit.resize(UDP_RELAY_NUM_CLASS); - mClassCount.resize(UDP_RELAY_NUM_CLASS); - mClassBandwidth.resize(UDP_RELAY_NUM_CLASS); - - - for(int i = 0; i < UDP_RELAY_NUM_CLASS; i++) - { - mClassCount[i] = 0; - mClassBandwidth[i] = 0; - } - - setRelayTotal(UDP_RELAY_DEFAULT_COUNT_ALL); - setRelayClassMax(UDP_RELAY_CLASS_FRIENDS, UDP_RELAY_DEFAULT_FRIEND, UDP_RELAY_DEFAULT_BANDWIDTH); - setRelayClassMax(UDP_RELAY_CLASS_FOF, UDP_RELAY_DEFAULT_FOF, UDP_RELAY_DEFAULT_BANDWIDTH); - setRelayClassMax(UDP_RELAY_CLASS_GENERAL, UDP_RELAY_DEFAULT_GENERAL, UDP_RELAY_DEFAULT_BANDWIDTH); - - /* only allocate this space once */ - mTmpSendPkt = rs_malloc(MAX_RELAY_UDP_PACKET_SIZE); - mTmpSendSize = MAX_RELAY_UDP_PACKET_SIZE; - - clearDataTransferred(); - - return; -} - -UdpRelayReceiver::~UdpRelayReceiver() -{ - free(mTmpSendPkt); -} - - -int UdpRelayReceiver::addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr) -{ - struct sockaddr_in realPeerAddr = endPoints->mDestAddr; - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check for duplicate */ - std::map::iterator it; - it = mStreams.find(realPeerAddr); - bool ok = (it == mStreams.end()); - if (!ok) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::addUdpPeer() ERROR Peer already exists!" << std::endl; -#endif - return 0; - } - - /* setup a peer */ - UdpRelayEnd ure(endPoints, proxyaddr); - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::addUdpPeer() Installing UdpRelayEnd: " << ure << std::endl; -#endif - - mStreams[realPeerAddr] = ure; - } - - { - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::addUdpPeer() Installing UdpPeer" << std::endl; -#endif - - /* just overwrite */ - mPeers[realPeerAddr] = peer; - - } - - return 1; -} - - -int UdpRelayReceiver::removeUdpPeer(UdpPeer *peer) -{ - bool found = false; - struct sockaddr_in realPeerAddr; - - /* cleanup UdpPeer, and get reference for data */ - { - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); ++it) - { - if (it->second == peer) - { - realPeerAddr = it->first; - mPeers.erase(it); - found = true; - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::removeUdpPeer() removing UdpPeer" << std::endl; -#endif - break; - } - } - } - - if (!found) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::removeUdpPeer() Warning: Failed to find UdpPeer" << std::endl; -#endif - return 0; - } - - /* now we cleanup the associated data */ - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - std::map::iterator it; - it = mStreams.find(realPeerAddr); - if (it != mStreams.end()) - { - mStreams.erase(it); - } - else - { - /* ERROR */ -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::removeUdpPeer() ERROR failed to find Mapping" << std::endl; -#endif - } - } - return 1; -} - -int UdpRelayReceiver::getRelayEnds(std::list &relayEnds) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - std::map::iterator rit; - - for(rit = mStreams.begin(); rit != mStreams.end(); ++rit) - { - relayEnds.push_back(rit->second); - } - return 1; - - -} - -int UdpRelayReceiver::getRelayProxies(std::list &relayProxies) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - std::map::iterator rit; - - for(rit = mRelays.begin(); rit != mRelays.end(); ++rit) - { - relayProxies.push_back(rit->second); - } - return 1; -} - -#define RELAY_MAX_BANDWIDTH 1000 -#define RELAY_TIMEOUT 30 - - -int UdpRelayReceiver::checkRelays() -{ - -#ifdef DEBUG_UDP_RELAY - // As this locks - must be out of the Mutex. - status(std::cerr); -#endif - - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* iterate through the Relays */ - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::checkRelays()"; - std::cerr << std::endl; -#endif - - std::list eraseList; - std::map::iterator rit; - rstime_t now = time(NULL); - -#define BANDWIDTH_FILTER_K (0.8) - - for(rit = mRelays.begin(); rit != mRelays.end(); ++rit) - { - /* calc bandwidth */ - //rit->second.mBandwidth = rit->second.mDataSize / (float) (now - rit->second.mLastBandwidthTS); - // Switch to a Low-Pass Filter to average it out. - float instantBandwidth = rit->second.mDataSize / (float) (now - rit->second.mLastBandwidthTS); - - rit->second.mBandwidth *= (BANDWIDTH_FILTER_K); - rit->second.mBandwidth += (1.0 - BANDWIDTH_FILTER_K) * instantBandwidth; - - rit->second.mDataSize = 0; - rit->second.mLastBandwidthTS = now; - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::checkRelays()"; - std::cerr << "Relay: " << rit->first; - std::cerr << " using bandwidth: " << rit->second.mBandwidth; - std::cerr << std::endl; -#endif - - // ONLY A WARNING. -#ifdef DEBUG_UDP_RELAY - if (instantBandwidth > rit->second.mBandwidthLimit) - { - std::cerr << "UdpRelayReceiver::checkRelays() "; - std::cerr << "Warning instantBandwidth: " << instantBandwidth; - std::cerr << " Exceeding Limit: " << rit->second.mBandwidthLimit; - std::cerr << " for Relay: " << rit->first; - std::cerr << std::endl; - } -#endif - - if (rit->second.mBandwidth > rit->second.mBandwidthLimit) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::checkRelays() "; - std::cerr << "Dropping Relay due to excessive Bandwidth: " << rit->second.mBandwidth; - std::cerr << " Exceeding Limit: " << rit->second.mBandwidthLimit; - std::cerr << " Relay: " << rit->first; - std::cerr << std::endl; -#endif - - /* if exceeding bandwidth -> drop */ - eraseList.push_back(rit->first); - } - else if (now - rit->second.mLastTS > RELAY_TIMEOUT) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - /* if haven't transmitted for ages -> drop */ - std::cerr << "UdpRelayReceiver::checkRelays() "; - std::cerr << "Dropping Relay due to Timeout: " << rit->first; - std::cerr << std::endl; -#endif - eraseList.push_back(rit->first); - } - else - { - /* check the length of the relay - we will drop them after a certain amount of time */ - int lifetime = 0; - switch(rit->second.mRelayClass) - { - default: - case UDP_RELAY_CLASS_GENERAL: - lifetime = UDP_RELAY_LIFETIME_GENERAL; - break; - case UDP_RELAY_CLASS_FOF: - lifetime = UDP_RELAY_LIFETIME_FOF; - break; - case UDP_RELAY_CLASS_FRIENDS: - lifetime = UDP_RELAY_LIFETIME_FRIENDS; - break; - } - if (now - rit->second.mStartTS > lifetime) - { -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::checkRelays() "; - std::cerr << "Dropping Relay due to Passing Lifetime Limit: " << lifetime; - std::cerr << " for class: " << rit->second.mRelayClass; - std::cerr << " Relay: " << rit->first; - std::cerr << std::endl; -#endif - - eraseList.push_back(rit->first); - } - } - } - - std::list::iterator it; - for(it = eraseList.begin(); it != eraseList.end(); ++it) - { - removeUdpRelay_relayLocked(&(*it)); - } - - return 1; -} - - -int UdpRelayReceiver::removeUdpRelay(UdpRelayAddrSet *addrSet) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::removeUdpRelay() :" << *addrSet << std::endl; -#endif - - return removeUdpRelay_relayLocked(addrSet); -} - - -int UdpRelayReceiver::addUdpRelay(UdpRelayAddrSet *addrSet, int &relayClass, uint32_t &bandwidth) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check for duplicate */ - std::map::iterator rit = mRelays.find(*addrSet); - int ok = (rit == mRelays.end()); - if (!ok) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::addUdpRelay() ERROR Peer already exists!" << std::endl; -#endif - return 0; - } - - /* will install if there is space! */ - if (installRelayClass_relayLocked(relayClass, bandwidth)) - { -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::addUdpRelay() adding Relay" << std::endl; -#endif - /* create UdpRelay */ - UdpRelayProxy udpRelay(addrSet, relayClass, bandwidth); - UdpRelayAddrSet alt = addrSet->flippedSet(); - UdpRelayProxy altUdpRelay(&alt, relayClass, bandwidth); - - /* must install two (A, B) & (B, A) */ - mRelays[*addrSet] = udpRelay; - mRelays[alt] = altUdpRelay; - - /* grab bandwidth from one set */ - bandwidth = altUdpRelay.mBandwidthLimit; - - return 1; - } - -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::addUdpRelay() WARNING Too many Relays!" << std::endl; -#endif - return 0; -} - - - -int UdpRelayReceiver::removeUdpRelay_relayLocked(UdpRelayAddrSet *addrSet) -{ -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::removeUdpRelay_relayLocked() :" << *addrSet << std::endl; -#endif - - /* find in Relay list */ - std::map::iterator rit = mRelays.find(*addrSet); - if (rit == mRelays.end()) - { - /* ERROR */ - std::cerr << "UdpRelayReceiver::removeUdpRelay()"; - std::cerr << "ERROR Finding Relay: " << *addrSet; - std::cerr << std::endl; - } - else - { - /* lets drop the count here too */ - removeRelayClass_relayLocked(rit->second.mRelayClass); - mRelays.erase(rit); - } - - /* rotate around and delete matching set */ - UdpRelayAddrSet alt = addrSet->flippedSet(); - - rit = mRelays.find(alt); - if (rit == mRelays.end()) - { - std::cerr << "UdpRelayReceiver::removeUdpRelay()"; - std::cerr << "ERROR Finding Alt Relay: " << alt; - std::cerr << std::endl; - /* ERROR */ - } - else - { - mRelays.erase(rit); - } - return 1; -} - - /* Need some stats, to work out how many relays we are supporting - * modified the code to allow degrading of class .... - * so if you have too many friends, they will fill a FOF spot - */ -int UdpRelayReceiver::installRelayClass_relayLocked(int &classIdx, uint32_t &bandwidth) -{ - /* check for total number of Relays */ - if (mClassCount[UDP_RELAY_CLASS_ALL] >= mClassLimit[UDP_RELAY_CLASS_ALL]) - { - std::cerr << "UdpRelayReceiver::installRelayClass() WARNING Too many Relays already"; - std::cerr << std::endl; - return 0; - } - - /* check the idx too */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::installRelayClass() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - /* now check the specifics of the class */ - while(mClassCount[classIdx] >= mClassLimit[classIdx]) - { - std::cerr << "UdpRelayReceiver::installRelayClass() WARNING Relay Class Limit Exceeded"; - std::cerr << std::endl; - std::cerr << "UdpRelayReceiver::installRelayClass() ClassIdx: " << classIdx; - std::cerr << std::endl; - std::cerr << "UdpRelayReceiver::installRelayClass() ClassLimit: " << mClassLimit[classIdx]; - std::cerr << std::endl; - std::cerr << "UdpRelayReceiver::installRelayClass() Degrading Class =>: " << classIdx; - std::cerr << std::endl; - - classIdx--; - if (classIdx == 0) - { - std::cerr << "UdpRelayReceiver::installRelayClass() No Spaces Left"; - std::cerr << std::endl; - - return 0; - } - } - - std::cerr << "UdpRelayReceiver::installRelayClass() Relay Class Ok, Count incremented"; - std::cerr << std::endl; - - /* if we get here we can add one */ - ++mClassCount[UDP_RELAY_CLASS_ALL]; - ++mClassCount[classIdx]; - bandwidth = mClassBandwidth[classIdx]; - - return 1; -} - -int UdpRelayReceiver::removeRelayClass_relayLocked(int classIdx) -{ - /* check for total number of Relays */ - if (mClassCount[UDP_RELAY_CLASS_ALL] < 1) - { - std::cerr << "UdpRelayReceiver::removeRelayClass() ERROR no relays installed"; - std::cerr << std::endl; - return 0; - } - - /* check the idx too */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::removeRelayClass() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - /* now check the specifics of the class */ - if (mClassCount[classIdx] < 1) - { - std::cerr << "UdpRelayReceiver::removeRelayClass() ERROR no relay of class installed"; - std::cerr << std::endl; - - return 0; - } - - std::cerr << "UdpRelayReceiver::removeRelayClass() Ok, Count decremented"; - std::cerr << std::endl; - - /* if we get here we can add one */ - mClassCount[UDP_RELAY_CLASS_ALL]--; - mClassCount[classIdx]--; - - return 1; -} - - -int UdpRelayReceiver::setRelayTotal(int count) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - mClassLimit[UDP_RELAY_CLASS_ALL] = count; - mClassLimit[UDP_RELAY_CLASS_GENERAL] = (int) (UDP_RELAY_FRAC_GENERAL * count); - mClassLimit[UDP_RELAY_CLASS_FOF] = (int) (UDP_RELAY_FRAC_FOF * count); - mClassLimit[UDP_RELAY_CLASS_FRIENDS] = (int) (UDP_RELAY_FRAC_FRIENDS * count); - - return count; -} - - -int UdpRelayReceiver::setRelayClassMax(int classIdx, int count, int bandwidth) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check the idx */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::setRelayMaximum() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - mClassLimit[classIdx] = count; - mClassBandwidth[classIdx] = bandwidth; - return 1; -} - - -int UdpRelayReceiver::getRelayClassMax(int classIdx) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check the idx */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::getRelayMaximum() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - return mClassLimit[classIdx]; -} - -int UdpRelayReceiver::getRelayClassBandwidth(int classIdx) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check the idx */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::getRelayMaximum() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - return mClassBandwidth[classIdx]; -} - -int UdpRelayReceiver::getRelayCount(int classIdx) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* check the idx */ - if ((classIdx < 0) || (classIdx >= UDP_RELAY_NUM_CLASS)) - { - std::cerr << "UdpRelayReceiver::getRelayCount() ERROR class Idx invalid"; - std::cerr << std::endl; - return 0; - } - - return mClassCount[classIdx]; -} - - -int UdpRelayReceiver::RelayStatus(std::ostream &out) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* iterate through the Relays */ - out << "UdpRelayReceiver::RelayStatus()"; - out << std::endl; - - std::map::iterator rit; - for(rit = mRelays.begin(); rit != mRelays.end(); ++rit) - { - out << "Relay for: " << rit->first; - out << std::endl; - - out << "\tClass: " << rit->second.mRelayClass; - out << "\tBandwidth: " << rit->second.mBandwidth; - out << "\tDataSize: " << rit->second.mDataSize; - out << "\tLastBandwidthTS: " << rit->second.mLastBandwidthTS; - out << std::endl; - } - - out << "ClassLimits:" << std::endl; - for(int i = 0; i < UDP_RELAY_NUM_CLASS; i++) - { - out << "Limit[" << i << "] = " << mClassLimit[i]; - out << " Count: " << mClassCount[i]; - out << " Bandwidth: " << mClassBandwidth[i]; - out << std::endl; - } - - return 1; -} - -int UdpRelayReceiver::status(std::ostream &out) -{ - - out << "UdpRelayReceiver::status()" << std::endl; - out << "UdpRelayReceiver::Relayed Connections:" << std::endl; - - RelayStatus(out); - - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - out << "UdpRelayReceiver::Connections:" << std::endl; - - std::map::iterator pit; - for(pit = mStreams.begin(); pit != mStreams.end(); ++pit) - { - out << "\t" << pit->first << " : " << pit->second; - out << std::endl; - } - } - - UdpPeersStatus(out); - - return 1; -} - -int UdpRelayReceiver::UdpPeersStatus(std::ostream &out) -{ - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - /* iterate through the Relays */ - out << "UdpRelayReceiver::UdpPeersStatus()"; - out << std::endl; - - std::map::iterator pit; - for(pit = mPeers.begin(); pit != mPeers.end(); ++pit) - { - out << "UdpPeer for: " << pit->first; - out << " is: " << pit->second; - out << std::endl; - } - return 1; -} - - -void UdpRelayReceiver::clearDataTransferred() -{ - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - mWriteBytes = 0; - mRelayBytes = 0; - } - - { - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - mReadBytes = 0; - } -} - - -void UdpRelayReceiver::getDataTransferred(uint32_t &read, uint32_t &write, uint32_t &relay) -{ - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - write = mWriteBytes; - relay = mRelayBytes; - } - - { - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - read = mReadBytes; - } - clearDataTransferred(); -} - - - -#define UDP_RELAY_HEADER_SIZE 16 - -/* higher level interface */ -int UdpRelayReceiver::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* remove unused parameter warnings */ - (void) from; - - /* print packet information */ -#ifdef DEBUG_UDP_RELAY_PKTS - std::cerr << "UdpRelayReceiver::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; - displayUdpRelayPacketHeader(data, size); - -#endif - - if (!isUdpRelayPacket(data, size)) - { -#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::recvPkt() ERROR: is Not RELAY Pkt"; - std::cerr << std::endl; -#endif - return 0; - } - - /* decide if we are the relay, or the endpoint */ - UdpRelayAddrSet addrSet; - if (!extractUdpRelayAddrSet(data, size, addrSet)) - { -#ifdef DEBUG_UDP_RELAY_ERRORS - std::cerr << "UdpRelayReceiver::recvPkt() ERROR: cannot extract Addresses"; - std::cerr << std::endl; -#endif - /* fails most basic test, drop */ - return 0; - } - - { - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* lookup relay first (double entries) */ - std::map::iterator rit = mRelays.find(addrSet); - if (rit != mRelays.end()) - { - /* we are the relay */ -#ifdef DEBUG_UDP_RELAY_PKTS - std::cerr << "UdpRelayReceiver::recvPkt() We are the Relay. Passing onto: "; - std::cerr << rit->first.mDestAddr; - std::cerr << std::endl; -#endif - /* do accounting */ - rit->second.mLastTS = time(NULL); - rit->second.mDataSize += size; - - mRelayBytes += size; - - mPublisher->sendPkt(data, size, rit->first.mDestAddr, STD_RELAY_TTL); - return 1; - } - } - - /* otherwise we are likely to be the endpoint, - * use the peers Address from the header - */ - - { - RsStackMutex stack(udppeerMtx); /********** LOCK MUTEX *********/ - - std::map::iterator pit = mPeers.find(addrSet.mSrcAddr); - if (pit != mPeers.end()) - { - /* we are the end-point */ -#ifdef DEBUG_UDP_RELAY_PKTS - std::cerr << "UdpRelayReceiver::recvPkt() Sending to UdpPeer: "; - std::cerr << pit->first; - std::cerr << std::endl; -#endif - mReadBytes += size; - - /* remove the header */ - void *pktdata = (void *) (((uint8_t *) data) + UDP_RELAY_HEADER_SIZE); - int pktsize = size - UDP_RELAY_HEADER_SIZE; - if (pktsize > 0) - { - (pit->second)->recvPkt(pktdata, pktsize); - } - else - { - /* packet undersized */ -//#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::recvPkt() ERROR Packet Undersized"; - std::cerr << std::endl; -//#endif - } - return 1; - } - /* done */ - } - - /* unknown */ -//#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::recvPkt() Peer Unknown!"; - std::cerr << std::endl; -//#endif - return 0; -} - - -/* the address here must be the end point!, - * it cannot be proxy, as we could be using the same proxy for multiple connections. - */ -int UdpRelayReceiver::sendPkt(const void *data, int size, const struct sockaddr_in &to, int /*ttl*/) -{ - RsStackMutex stack(relayMtx); /********** LOCK MUTEX *********/ - - /* work out who the proxy is */ - std::map::iterator it; - it = mStreams.find(to); - if (it == mStreams.end()) - { -//#ifdef DEBUG_UDP_RELAY - std::cerr << "UdpRelayReceiver::sendPkt() Peer Unknown!"; - std::cerr << std::endl; -//#endif - return 0; - } - -#ifdef DEBUG_UDP_RELAY_PKTS - std::cerr << "UdpRelayReceiver::sendPkt() to Relay: " << it->second; - std::cerr << std::endl; -#endif - - mWriteBytes += size; - - /* add a header to packet */ - int finalPktSize = createRelayUdpPacket(data, size, mTmpSendPkt, MAX_RELAY_UDP_PACKET_SIZE, &(it->second)); - - /* send the packet on */ - return mPublisher->sendPkt(mTmpSendPkt, finalPktSize, it->second.mProxyAddr, STD_RELAY_TTL); -} - -/***** RELAY PACKET FORMAT **************************** - * - * - * [ 0 | 1 | 2 | 3 ] - * - * [ 'R' 'L' 'Y' Version ] - * [ IP Address 1 ] - * [ Port 1 ][ IP Address 2 .... - * ... IP Address 2][ Port 2 ] - * [.... TUNNELLED DATA .... - * - * - * ... ] - * - * 16 Bytes: 4 ID, 6 IP:Port 1, 6 IP:Port 2 - */ - -#define UDP_IDENTITY_STRING_V1 "RLY1" -#define UDP_IDENTITY_SIZE_V1 4 - -int isUdpRelayPacket(const void *data, const int size) -{ - if (size < UDP_RELAY_HEADER_SIZE) - return 0; - - return (0 == strncmp((char *) data, UDP_IDENTITY_STRING_V1, UDP_IDENTITY_SIZE_V1)); -} - -#ifdef DEBUG_UDP_RELAY - -int displayUdpRelayPacketHeader(const void *data, const int size) -{ - int dsize = UDP_RELAY_HEADER_SIZE + 16; - if (size < dsize) - { - dsize = size; - } - - std::string out; - for(int i = 0; i < dsize; i++) - { - if ((i > 0) && (i % 16 == 0)) - { - out += "\n"; - } - - rs_sprintf_append(out, "%02x", (uint32_t) ((uint8_t*) data)[i]); - } - - std::cerr << "displayUdpRelayPacketHeader()" << std::endl; - std::cerr << out; - std::cerr << std::endl; - - return 1; -} -#endif - - -int extractUdpRelayAddrSet(const void *data, const int size, UdpRelayAddrSet &addrSet) -{ - if (size < UDP_RELAY_HEADER_SIZE) - { - std::cerr << "createRelayUdpPacket() ERROR invalid size"; - std::cerr << std::endl; - return 0; - } - - uint8_t *header = (uint8_t *) data; - - sockaddr_clear(&(addrSet.mSrcAddr)); - sockaddr_clear(&(addrSet.mDestAddr)); - - /* as IP:Port are already in network byte order, we can just write them to the dataspace */ - uint32_t ipaddr; - uint16_t port; - - memcpy(&ipaddr, &(header[4]), 4); - memcpy(&port, &(header[8]), 2); - - addrSet.mSrcAddr.sin_addr.s_addr = ipaddr; - addrSet.mSrcAddr.sin_port = port; - - memcpy(&ipaddr, &(header[10]), 4); - memcpy(&port, &(header[14]), 2); - - addrSet.mDestAddr.sin_addr.s_addr = ipaddr; - addrSet.mDestAddr.sin_port = port; - - return 1; -} - - -int createRelayUdpPacket(const void *data, const int size, void *newpkt, int newsize, UdpRelayEnd *ure) -{ - int pktsize = size + UDP_RELAY_HEADER_SIZE; - if (newsize < pktsize) - { - std::cerr << "createRelayUdpPacket() ERROR invalid size"; - std::cerr << std::endl; - std::cerr << "Incoming DataSize: " << size << " + Header: " << UDP_RELAY_HEADER_SIZE; - std::cerr << " > " << newsize; - std::cerr << std::endl; - return 0; - } - uint8_t *header = (uint8_t *) newpkt; - memcpy(header, UDP_IDENTITY_STRING_V1, UDP_IDENTITY_SIZE_V1); - - /* as IP:Port are already in network byte order, we can just write them to the dataspace */ - uint32_t ipaddr = ure->mLocalAddr.sin_addr.s_addr; - uint16_t port = ure->mLocalAddr.sin_port; - - memcpy(&(header[4]), &ipaddr, 4); - memcpy(&(header[8]), &port, 2); - - ipaddr = ure->mRemoteAddr.sin_addr.s_addr; - port = ure->mRemoteAddr.sin_port; - - memcpy(&(header[10]), &ipaddr, 4); - memcpy(&(header[14]), &port, 2); - - memcpy(&(header[16]), data, size); - - return pktsize; -} - - - -/******* Small Container Class Helper Functions ****/ - -UdpRelayAddrSet::UdpRelayAddrSet() -{ - sockaddr_clear(&mSrcAddr); - sockaddr_clear(&mDestAddr); -} - -UdpRelayAddrSet::UdpRelayAddrSet(const sockaddr_in *ownAddr, const sockaddr_in *destAddr) -{ - mSrcAddr = *ownAddr; - mDestAddr = *destAddr; -} - -UdpRelayAddrSet UdpRelayAddrSet::flippedSet() -{ - UdpRelayAddrSet flipped(&mDestAddr, &mSrcAddr); - return flipped; -} - - -int operator<(const UdpRelayAddrSet &a, const UdpRelayAddrSet &b) -{ - if (a.mSrcAddr < b.mSrcAddr) - { - return 1; - } - - if (a.mSrcAddr == b.mSrcAddr) - { - if (a.mDestAddr < b.mDestAddr) - { - return 1; - } - } - return 0; -} - - -UdpRelayProxy::UdpRelayProxy() -{ - mBandwidth = 0; - mDataSize = 0; - mLastBandwidthTS = 0; - mLastTS = time(NULL); // Must be set here, otherwise Proxy Timesout before anything can happen! - mRelayClass = 0; - - mStartTS = time(NULL); - mBandwidthLimit = 0; -} - -UdpRelayProxy::UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass, uint32_t bandwidth) - : mAddrs(*addrSet), - mBandwidth(0), - mDataSize(0), - mLastBandwidthTS(0), - mLastTS(time(NULL)), - mStartTS(time(NULL)), - mBandwidthLimit(bandwidth), - mRelayClass(relayClass) -{ - /* bandwidth fallback */ - if (bandwidth == 0) - { - switch(relayClass) - { - default: - case UDP_RELAY_CLASS_GENERAL: - mBandwidthLimit = RELAY_MAX_BANDWIDTH; - break; - case UDP_RELAY_CLASS_FOF: - mBandwidthLimit = RELAY_MAX_BANDWIDTH; - break; - case UDP_RELAY_CLASS_FRIENDS: - mBandwidthLimit = RELAY_MAX_BANDWIDTH; - break; - } - } -} - -UdpRelayEnd::UdpRelayEnd() -{ - sockaddr_clear(&mLocalAddr); - sockaddr_clear(&mProxyAddr); - sockaddr_clear(&mRemoteAddr); - -} - -UdpRelayEnd::UdpRelayEnd(UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr) -{ - mLocalAddr = endPoints->mSrcAddr; - mRemoteAddr = endPoints->mDestAddr; - mProxyAddr = *proxyaddr; -} - - - - - -std::ostream &operator<<(std::ostream &out, const UdpRelayAddrSet &uras) -{ - out << "<" << uras.mSrcAddr << "," << uras.mDestAddr << ">"; - return out; -} - -std::ostream &operator<<(std::ostream &out, const UdpRelayProxy &urp) -{ - rstime_t now = time(NULL); - out << "UdpRelayProxy for " << urp.mAddrs; - out << std::endl; - out << "\tRelayClass: " << urp.mRelayClass; - out << std::endl; - out << "\tBandwidth: " << urp.mBandwidth; - out << std::endl; - out << "\tDataSize: " << urp.mDataSize; - out << std::endl; - out << "\tLastBandwidthTS: " << now - urp.mLastBandwidthTS << " secs ago"; - out << std::endl; - out << "\tLastTS: " << now - urp.mLastTS << " secs ago"; - out << std::endl; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const UdpRelayEnd &ure) -{ - out << "UdpRelayEnd: <" << ure.mLocalAddr << " => " << ure.mProxyAddr << " <= "; - out << ure.mRemoteAddr << ">"; - return out; -} - - - - diff --git a/libretroshare/src/tcponudp/udprelay.h b/libretroshare/src/tcponudp/udprelay.h deleted file mode 100644 index ba412ac5a..000000000 --- a/libretroshare/src/tcponudp/udprelay.h +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udprelay.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UDP_RELAY_H -#define RS_UDP_RELAY_H - -#include "tcponudp/udppeer.h" -#include -#include - -class UdpRelayAddrSet; - -class UdpRelayAddrSet -{ - public: - UdpRelayAddrSet(); - UdpRelayAddrSet(const sockaddr_in *ownAddr, const sockaddr_in *destAddr); - - UdpRelayAddrSet flippedSet(); - - struct sockaddr_in mSrcAddr; /* msg source */ - struct sockaddr_in mDestAddr; /* final destination */ -}; - -int operator<(const UdpRelayAddrSet &a, const UdpRelayAddrSet &b); - -class UdpRelayProxy -{ - public: - UdpRelayProxy(); - UdpRelayProxy(UdpRelayAddrSet *addrSet, int relayClass, uint32_t bandwidth); - - UdpRelayAddrSet mAddrs; - double mBandwidth; - uint32_t mDataSize; - rstime_t mLastBandwidthTS; - rstime_t mLastTS; - - rstime_t mStartTS; - double mBandwidthLimit; - - int mRelayClass; -}; - - -class UdpRelayEnd -{ - public: - - UdpRelayEnd(); - UdpRelayEnd(UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr); - - struct sockaddr_in mLocalAddr; - struct sockaddr_in mProxyAddr; - struct sockaddr_in mRemoteAddr; -}; - -std::ostream &operator<<(std::ostream &out, const UdpRelayAddrSet &uras); -std::ostream &operator<<(std::ostream &out, const UdpRelayProxy &urp); -std::ostream &operator<<(std::ostream &out, const UdpRelayEnd &ure); - -/* we define a couple of classes (determining which class is done elsewhere) - * There will be various maximums for each type. - * Ideally you want to allow your friends to use your proxy in preference - * to randoms. - * - * At N x 2 x maxBandwidth. - * - * 10 x 2 x 1Kb/s => 20Kb/s In and Out. (quite a bit!) - * 20 x 2 x 1Kb/s => 40Kb/s Huge. - */ - -#define UDP_RELAY_DEFAULT_COUNT_ALL 2 -#define UDP_RELAY_DEFAULT_FRIEND 0 -#define UDP_RELAY_DEFAULT_FOF 1 -#define UDP_RELAY_DEFAULT_GENERAL 1 -#define UDP_RELAY_DEFAULT_BANDWIDTH 1024 - -#define UDP_RELAY_FRAC_GENERAL (0.5) -#define UDP_RELAY_FRAC_FOF (0.5) -#define UDP_RELAY_FRAC_FRIENDS (0.0) - - - -/**** DEFINED IN EXTERNAL HEADER FILE ***/ -// sehraf: this is a bit ugly but since the int is used as an integer i'lll stick to this hack for now -/// TODO fix me! -#define UDP_RELAY_NUM_CLASS static_cast::type>(RsDhtRelayClass::NUM_CLASS) - -#define UDP_RELAY_CLASS_ALL static_cast::type>(RsDhtRelayClass::ALL) -#define UDP_RELAY_CLASS_GENERAL static_cast::type>(RsDhtRelayClass::GENERAL) -#define UDP_RELAY_CLASS_FOF static_cast::type>(RsDhtRelayClass::FOF) -#define UDP_RELAY_CLASS_FRIENDS static_cast::type>(RsDhtRelayClass::FRIENDS) - -// Just for some testing fun! -//#define UDP_RELAY_LIFETIME_GENERAL 180 // 3 minutes -//#define UDP_RELAY_LIFETIME_FOF 360 // 6 minutes. -//#define UDP_RELAY_LIFETIME_FRIENDS 720 // 12 minutes. - -#define UDP_RELAY_LIFETIME_GENERAL 3600 // 1 hour (chosen so we at least transfer 1 or 2 meg at lowest speed) -#define UDP_RELAY_LIFETIME_FOF 7200 // 2 Hours. -#define UDP_RELAY_LIFETIME_FRIENDS 14400 // 4 Hours. - -#define STD_RELAY_TTL 64 - -class UdpRelayReceiver: public UdpSubReceiver -{ - public: - - UdpRelayReceiver(UdpPublisher *pub); -virtual ~UdpRelayReceiver(); - - /* add a TCPonUDP stream (ENDs) */ -int addUdpPeer(UdpPeer *peer, UdpRelayAddrSet *endPoints, const struct sockaddr_in *proxyaddr); -int removeUdpPeer(UdpPeer *peer); - - /* add a Relay Point (for the Relay). - * These don't have to be explicitly removed. - * They will be timed out when - * the end-points drop the connections - */ - - int addUdpRelay(UdpRelayAddrSet *addrSet, int &relayClass, uint32_t &bandwidth); - int removeUdpRelay(UdpRelayAddrSet *addrs); - - /* Need some stats, to work out how many relays we are supporting */ - int checkRelays(); - - int setRelayTotal(int count); /* sets all the Relay Counts (frac based on total) */ - int setRelayClassMax(int classIdx, int count, int bandwidth); /* set a specific class maximum */ - int getRelayClassMax(int classIdx); - int getRelayClassBandwidth(int classIdx); - int getRelayCount(int classIdx); /* how many relays (of this type) do we have */ - int RelayStatus(std::ostream &out); - - /* Extract Relay Data */ - int getRelayEnds(std::list &relayEnds); - int getRelayProxies(std::list &relayProxies); - - /* callback for recved data (overloaded from UdpReceiver) */ -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); - - /* wrapper function for relay (overloaded from UdpSubReceiver) */ -virtual int sendPkt(const void *data, int size, const struct sockaddr_in &to, int ttl); - -int status(std::ostream &out); -int UdpPeersStatus(std::ostream &out); - -void getDataTransferred(uint32_t &read, uint32_t &write, uint32_t &relay); - - private: - - void clearDataTransferred(); - - int removeUdpRelay_relayLocked(UdpRelayAddrSet *addrs); - int installRelayClass_relayLocked(int &classIdx, uint32_t &bandwidth); - int removeRelayClass_relayLocked(int classIdx); - - /* Unfortunately, Due the reentrant nature of this classes activities... - * the SendPkt() must be callable from inside RecvPkt(). - * This means we need two seperate mutexes. - * - one for UdpPeer's, and one for Relay Data. - * - * care must be taken to lock these mutex's in a consistent manner to avoid deadlock. - * - You are not allowed to hold both at the same time! - */ - - RsMutex udppeerMtx; /* for all class data (below) */ - - std::map mPeers; /* indexed by */ - uint32_t mReadBytes; - - RsMutex relayMtx; /* for all class data (below) */ - - std::vector mClassLimit, mClassCount, mClassBandwidth; - std::map mStreams; /* indexed by */ - std::map mRelays; /* indexed by */ - - void *mTmpSendPkt; - uint32_t mTmpSendSize; - - uint32_t mWriteBytes; - uint32_t mRelayBytes; - -}; - -/* utility functions for creating / extracting UdpRelayPackets */ -int isUdpRelayPacket(const void *data, const int size); -int getPacketFromUdpRelayPacket(const void *data, const int size, void **realdata, int *realsize); - -int createRelayUdpPacket(const void *data, const int size, void *newpkt, int newsize, UdpRelayEnd *ure); -int extractUdpRelayAddrSet(const void *data, const int size, UdpRelayAddrSet &addrSet); - - - - -#endif diff --git a/libretroshare/src/tcponudp/udpstunner.cc b/libretroshare/src/tcponudp/udpstunner.cc deleted file mode 100644 index 4409f256f..000000000 --- a/libretroshare/src/tcponudp/udpstunner.cc +++ /dev/null @@ -1,1194 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udpstunner.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "tcponudp/udpstunner.h" -#include -#include "util/rstime.h" - -#include "util/rsrandom.h" -#include "util/rsprint.h" -#include "util/rsmemory.h" -#include "util/rsstring.h" - -static const int STUN_TTL = 64; - -#define TOU_STUN_MIN_PEERS 20 - -/* - * #define DEBUG_UDP_STUNNER 1 - * #define DEBUG_UDP_STUNNER_FILTER 1 - */ - -//#define DEBUG_UDP_STUNNER 1 - -const uint32_t TOU_STUN_MAX_FAIL_COUNT = 3; /* 3 tries (could be higher?) */ -const int32_t TOU_STUN_MAX_SEND_RATE = 5; /* every 5 seconds */ -const uint32_t TOU_STUN_MAX_RECV_RATE = 25; /* every 25 seconds */ -// TIMEOUT is now tied to STUN RATE ... const int32_t TOU_STUN_ADDR_MAX_AGE = 120; /* 2 minutes */ - -const int32_t TOU_STUN_DEFAULT_TARGET_RATE = 15; /* 20 secs is minimum to keep a NAT UDP port open */ -const double TOU_SUCCESS_LPF_FACTOR = 0.90; - -#define EXCLUSIVE_MODE_TIMEOUT 300 - -UdpStunner::UdpStunner(UdpPublisher *pub) - :UdpSubReceiver(pub), stunMtx("UdpSubReceiver"), eaddrKnown(false), eaddrStable(false), - mStunLastRecvResp(0), mStunLastRecvAny(0), - mStunLastSendStun(0), mStunLastSendAny(0) -{ -#ifdef UDPSTUN_ALLOW_LOCALNET - mAcceptLocalNet = false; - mSimExclusiveNat = false; - mSimSymmetricNat = false; - mSimUnstableExt = false; -#endif - - - - /* these parameters determine the rate we attempt stuns */ - mPassiveStunMode = false; - mSuccessRate = 0.0; - mTargetStunPeriod = TOU_STUN_DEFAULT_TARGET_RATE; - - mExclusiveMode = false; - mExclusiveModeTS = 0; - mForceRestun = false; - - return; -} - -#ifdef UDPSTUN_ALLOW_LOCALNET - - // For Local Testing Only (Releases should have the #define disabled) -void UdpStunner::SetAcceptLocalNet() -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - mAcceptLocalNet = true; -} - - // For Local Testing Only (Releases should have the #define disabled) -void UdpStunner::SimExclusiveNat() -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - mSimExclusiveNat = true; - mSimUnstableExt = true; -} - -void UdpStunner::SimSymmetricNat() -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - mSimSymmetricNat = true; - mSimUnstableExt = true; -} - - - -#endif - - - -int UdpStunner::grabExclusiveMode(std::string holder) /* returns seconds since last send/recv */ -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - rstime_t now = time(NULL); - - -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::grabExclusiveMode()"; - std::cerr << std::endl; -#endif - - if (mExclusiveMode) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::grabExclusiveMode() FAILED"; - std::cerr << std::endl; -#endif - - std::cerr << "UdpStunner::grabExclusiveMode() FAILED, already held by: " << mExclusiveHolder; - std::cerr << std::endl; - std::cerr << "UdpStunner::grabExclusiveMode() Was Grabbed: " << now - mExclusiveModeTS; - std::cerr << " secs ago"; - std::cerr << std::endl; - - /* This can happen if AUTH, but START never received! (occasionally). - */ - if (now - mExclusiveModeTS > EXCLUSIVE_MODE_TIMEOUT) - { - mExclusiveMode = false; - mForceRestun = true; - - std::cerr << "UdpStunner::grabExclusiveMode() Held for too Long... TIMEOUT & Stun Forced"; - std::cerr << std::endl; - } - - return 0; - } - - mExclusiveMode = true; - mExclusiveModeTS = now; - mExclusiveHolder = holder; - - int lastcomms = mStunLastRecvAny; - if (mStunLastSendAny > lastcomms) - { - lastcomms = mStunLastSendAny; - } - - int commsage = now - lastcomms; - - /* cannot return 0, as this indicates error */ - if (commsage == 0) - { - commsage = 1; - } -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::grabExclusiveMode() SUCCESS. last comms: " << commsage; - std::cerr << " ago"; - std::cerr << std::endl; - std::cerr << "UdpStunner::grabExclusiveMode() Exclusive held by: " << mExclusiveHolder; - std::cerr << std::endl; -#endif - - return commsage; -} - -int UdpStunner::releaseExclusiveMode(std::string holder, bool forceStun) -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - if (!mExclusiveMode) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::cancelExclusiveMode() ERROR, not in exclusive Mode"; - std::cerr << std::endl; -#endif - return 0; - } - - mExclusiveMode = false; - if (forceStun) - { - mForceRestun = true; - } - -#ifdef UDPSTUN_ALLOW_LOCALNET - /* if we are simulating an exclusive NAT, then immediately after we release - it'll become unstable. - * In reality, it will only become unstable if we have tried a UDP connection. - * so we use the forceStun parameter (which is true when a UDP connection has been tried). - */ - - if ((mSimExclusiveNat) && (forceStun)) - { - mSimUnstableExt = true; - } -#endif - - if (mExclusiveHolder != holder) - { - std::cerr << "UdpStunner::cancelExclusiveMode() ERROR release MisMatch: "; - std::cerr << " Original Grabber: "; - std::cerr << mExclusiveHolder; - std::cerr << " Releaser: "; - std::cerr << holder; - std::cerr << std::endl; - } - -#ifdef DEBUG_UDP_STUNNER_FILTER - rstime_t now = time(nullptr); - std::cerr << "UdpStunner::cancelExclusiveMode() Canceled. Was in ExclusiveMode for: " << now - mExclusiveModeTS; - std::cerr << " secs"; - std::cerr << std::endl; -#endif - - return 1; -} - - -void UdpStunner::setTargetStunPeriod(int32_t sec_per_stun) -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - if (sec_per_stun < 0) - { - mPassiveStunMode = false; - mTargetStunPeriod = TOU_STUN_DEFAULT_TARGET_RATE; - } - else - { - if (sec_per_stun == 0) - { - mPassiveStunMode = true; - } - else - { - mPassiveStunMode = false; - } - mTargetStunPeriod = sec_per_stun; - } - -} - -/* higher level interface */ -int UdpStunner::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* print packet information */ -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; -#endif - - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - /* check for STUN packet */ - if (UdpStun_isStunPacket(data, size)) - { - mStunLastRecvAny = time(NULL); -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::recvPkt() is Stun Packet"; - std::cerr << std::endl; -#endif - - /* respond */ - locked_handleStunPkt(data, size, from); - - return 1; - } - return 0; -} - - -int UdpStunner::status(std::ostream &out) -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - out << "UdpStunner::status() TargetStunPeriod: " << mTargetStunPeriod; - out << " SuccessRate: " << mSuccessRate; - out << std::endl; - - out << "UdpStunner::status()" << std::endl; - - locked_printStunList(); - - return 1; -} - -int UdpStunner::tick() -{ - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::tick()" << std::endl; -#endif - - if (checkStunDesired()) - { - attemptStun(); -#ifdef DEBUG_UDP_STUNNER - status(std::cerr); -#endif - } - - return 1; -} - -/******************************* STUN Handling ********************************/ - - /* respond */ -bool UdpStunner::locked_handleStunPkt(void *data, int size, struct sockaddr_in &from) -{ - if (size == 20) /* request */ - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::handleStunPkt() got Request from: "; - std::cerr << inet_ntoa(from.sin_addr) << ":" << ntohs(from.sin_port); - std::cerr << std::endl; -#endif - /* generate a response */ - int len; - void *pkt = UdpStun_generate_stun_reply(&from, &len, data); - if (!pkt) - return false; - - rstime_t now = time(NULL); - mStunLastSendAny = now; - int sentlen = sendPkt(pkt, len, from, STUN_TTL); - free(pkt); - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::handleStunPkt() sent Response size:" << sentlen; - std::cerr << std::endl; -#endif - - return (len == sentlen); - } - else if (size == 28) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::handleStunPkt() got Response"; - std::cerr << std::endl; -#endif - /* got response */ - struct sockaddr_in eAddr; - bool good = UdpStun_response(data, size, eAddr); - if (good) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::handleStunPkt() got Ext Addr: "; - std::cerr << inet_ntoa(eAddr.sin_addr) << ":" << ntohs(eAddr.sin_port); - std::cerr << " from: " << from; - std::cerr << std::endl; -#endif - locked_recvdStun(from, eAddr); - - return true; - } - } - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::handleStunPkt() Bad Packet"; - std::cerr << std::endl; -#endif - return false; -} - - -bool UdpStunner::externalAddr(struct sockaddr_in &external, uint8_t &stable) -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - if (eaddrKnown) - { - /* address timeout - * no timeout if in exclusive mode - */ - if ((time(NULL) - eaddrTime > (long) (mTargetStunPeriod * 2)) && (!mExclusiveMode)) - { - std::cerr << "UdpStunner::externalAddr() eaddr expired"; - std::cerr << std::endl; - - eaddrKnown = false; - return false; - } - - /* Force Restun is triggered after an Exclusive Mode... as Ext Address is likely to have changed - * Until the Restun has got an address - we act as if we don't have an external address - */ - if (mForceRestun) - { - return false; - } - - external = eaddr; - - if (eaddrStable) - stable = 1; - else - stable = 0; - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::externalAddr() eaddr:" << inet_ntoa(external.sin_addr); - std::cerr << ":" << ntohs(external.sin_port) << " stable: " << (int) stable; - std::cerr << std::endl; -#endif - - - return true; - } -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::externalAddr() eaddr unknown"; - std::cerr << std::endl; -#endif - - return false; -} - - -int UdpStunner::doStun(struct sockaddr_in stun_addr) -{ -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::doStun()"; - std::cerr << std::endl; -#endif - - /* send out a stun packet -> save in the local variable */ - -#define MAX_STUN_SIZE 64 - char stundata[MAX_STUN_SIZE]; - int tmplen = MAX_STUN_SIZE; - bool done = UdpStun_generate_stun_pkt(stundata, &tmplen); - if (!done) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::doStun() Failed"; - std::cerr << std::endl; -#endif - //pqioutput(PQL_ALERT, pqistunzone, "pqistunner::stun() Failed!"); - return 0; - } - - /* send it off */ -#ifdef DEBUG_UDP_STUNNER - int sentlen = -#endif - sendPkt(stundata, tmplen, stun_addr, STUN_TTL); - - { - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - rstime_t now = time(NULL); - mStunLastSendStun = now; - mStunLastSendAny = now; - } - -#ifdef DEBUG_UDP_STUNNER - std::string out; - rs_sprintf(out, "UdpStunner::doStun() Sent Stun Packet(%d) to:%s:%u", sentlen, rs_inet_ntoa(stun_addr.sin_addr).c_str(), ntohs(stun_addr.sin_port)); - - std::cerr << out << std::endl; - - //pqioutput(PQL_ALERT, pqistunzone, out); -#endif - - return 1; -} - -/******************************* STUN Handling ********************************/ -/***** These next functions are generic and not dependent on class variables **/ -/******************************* STUN Handling ********************************/ - -bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr) -{ - /* check what type it is */ - if (size < 28) - { - return false; - } - - if (htons(((uint16_t *) stun_pkt)[0]) != UdpStunner::STUN_BINDING_RESPONSE) - { - /* not a response */ - return false; - } - - /* iterate through the packet */ - /* for now assume the address follows the header directly */ - /* all stay in netbyteorder! */ - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = ((uint32_t *) stun_pkt)[6]; - addr.sin_port = ((uint16_t *) stun_pkt)[11]; - - -#ifdef DEBUG_UDP_STUNNER_FILTER - std::string out; - rs_sprintf(out, "UdpStunner::response() Recvd a Stun Response, ext_addr: %s:%u", rs_inet_ntoa(addr.sin_addr).c_str(), ntohs(addr.sin_port)); - std::cerr << out << std::endl; -#endif - - return true; - -} - -bool UdpStun_generate_stun_pkt(void *stun_pkt, int *len) -{ - if (*len < 20) - { - return false; - } - - /* just the header */ - ((uint16_t *) stun_pkt)[0] = (uint16_t) htons(UdpStunner::STUN_BINDING_REQUEST); - ((uint16_t *) stun_pkt)[1] = (uint16_t) htons(20); /* only header */ - /* RFC 3489 - * The transaction ID is used to correlate requests and responses. - * - * RFC 5389 introduces a mmgic cokie at the location where preciously the transaction ID was located: - * In RFC 3489, this field was part of - * the transaction ID; placing the magic cookie in this location allows - * a server to detect if the client will understand certain attributes - * that were added in this revised specification. - */ - RsRandom::random_bytes(&((uint8_t *) stun_pkt)[4], 4 * sizeof (uint32_t)); - *len = 20; - return true; -} - - -void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len, const void *transId) -{ - /* just the header */ - void *stun_pkt = rs_malloc(28); - - if(!stun_pkt) - return nullptr ; - - ((uint16_t *) stun_pkt)[0] = (uint16_t) htons(UdpStunner::STUN_BINDING_RESPONSE); - ((uint16_t *) stun_pkt)[1] = (uint16_t) htons(28); /* only header + 8 byte addr */ - /* RFC 3489 - * The Binding Response MUST contain the same transaction ID contained in the Binding Request. - */ - memcpy(&((uint32_t *) stun_pkt)[1], &((uint32_t *) transId)[1], 4 * sizeof (uint32_t)); - - /* now add address - * 0 1 2 3 - * - * - */ - - /* THESE SHOULD BE NET ORDER ALREADY */ - ((uint16_t *) stun_pkt)[10] = AF_INET; - ((uint16_t *) stun_pkt)[11] = stun_addr->sin_port; - ((uint32_t *) stun_pkt)[6] = stun_addr->sin_addr.s_addr; - - *len = 28; - return stun_pkt; -} - -bool UdpStun_isStunPacket(void *data, int size) -{ -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::isStunPacket() ?"; - std::cerr << std::endl; -#endif - - if (size < 20) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::isStunPacket() (size < 20) -> false"; - std::cerr << std::endl; -#endif - return false; - } - - /* match size field */ - uint16_t pktsize = ntohs(((uint16_t *) data)[1]); - if (size != pktsize) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::isStunPacket() (size != pktsize) -> false"; - std::cerr << std::endl; -#endif - return false; - } - - if ((size == 20) && (UdpStunner::STUN_BINDING_REQUEST == ntohs(((uint16_t *) data)[0]))) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::isStunPacket() (size=20 & data[0]=STUN_BINDING_REQUEST) -> true"; - std::cerr << std::endl; -#endif - /* request */ - return true; - } - - if ((size == 28) && (UdpStunner::STUN_BINDING_RESPONSE == ntohs(((uint16_t *) data)[0]))) - { -#ifdef DEBUG_UDP_STUNNER_FILTER - std::cerr << "UdpStunner::isStunPacket() (size=28 & data[0]=STUN_BINDING_RESPONSE) -> true"; - std::cerr << std::endl; -#endif - /* response */ - return true; - } - return false; -} - - -/******************************* STUN Handling ******************************** - * KeepAlive has been replaced by a targetStunRate. Set this to zero to disable. - */ - -/******************************* STUN Handling ********************************/ - - -bool UdpStunner::addStunPeer(const struct sockaddr_in &remote, const char *peerid) -{ - /* add to the list */ -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::addStunPeer()"; - std::cerr << std::endl; -#endif - - bool toStore = true; - { - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - /* only store if we're active */ - toStore = !mPassiveStunMode; - } - - if (toStore) - { - storeStunPeer(remote, peerid, 0); - } - return true; -} - -bool UdpStunner::storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent) -{ - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::storeStunPeer()"; - std::cerr << std::endl; -#endif - - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - std::list::iterator it; - for(it = mStunList.begin(); it != mStunList.end(); ++it) - { - if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) && - (remote.sin_port == it->remote.sin_port)) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::storeStunPeer() Peer Already There!"; - std::cerr << std::endl; -#endif - /* already there */ - if (sent) - { - it->failCount += 1; - it->lastsend = time(NULL); - } - return false; - } - } - - std::string peerstring; - if (peerid) - { - peerstring = std::string(peerid); - } - - TouStunPeer peer(peerstring, remote); - if (sent) - { - peer.failCount += 1; - peer.lastsend = time(NULL); - } - - mStunList.push_back(peer); - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::storeStunPeer() Added Peer"; - std::cerr << std::endl; -#endif - - return true; -} - - -bool UdpStunner::dropStunPeer(const struct sockaddr_in &remote) -{ - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::dropStunPeer() : "; - std::cerr << std::endl; -#endif - - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - std::list::iterator it; - int count = 0; - for(it = mStunList.begin(); it != mStunList.end();) - { - if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) && - (remote.sin_port == it->remote.sin_port)) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::dropStunPeer() Found Entry"; - std::cerr << std::endl; -#endif - - it = mStunList.erase(it); - count++; - } - else - { - ++it; - } - } - - if (count) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::dropStunPeer() Dropped " << count << " Instances"; - std::cerr << std::endl; -#endif - return true; - } - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::dropStunPeer() Peer Not Here"; - std::cerr << std::endl; -#endif - - return false; -} - - -bool UdpStunner::checkStunDesired() -{ - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired()"; - std::cerr << std::endl; -#endif - - rstime_t now; - { - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - if (mPassiveStunMode) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired() In Passive Mode"; - std::cerr << std::endl; -#endif - return false; /* all good */ - } - - if (mExclusiveMode) - { - return false; /* no pings in exclusive mode */ - } - - if (mForceRestun) - { - return true; - } - - - if (!eaddrKnown) - { - /* check properly! (this will limit it to two successful stuns) */ - if (!locked_checkExternalAddress()) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired() YES, we don't have extAddr Yet"; - std::cerr << std::endl; -#endif - return true; /* want our external address */ - } - } - - /* check if we need to send one now */ - now = time(NULL); - - /* based on SuccessRate & TargetStunRate, we work out if we should send one - * - * if we have 100% success rate, then we can delay until exactly TARGET RATE. - * if we have 0% success rate, then try at double TARGET RATE. - * - * generalised to a rate_scale parameter below... - */ - -#define RATE_SCALE (3.0) - double stunPeriod = (mTargetStunPeriod / (RATE_SCALE)) * (1.0 + mSuccessRate * (RATE_SCALE - 1.0)); - rstime_t nextStun = mStunLastRecvResp + (int) stunPeriod; - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired() TargetStunPeriod: " << mTargetStunPeriod; - std::cerr << " SuccessRate: " << mSuccessRate; - std::cerr << " DesiredStunPeriod: " << stunPeriod; - std::cerr << " NextStun: " << nextStun - now << " secs"; - std::cerr << std::endl; -#endif - - if (now >= nextStun) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired() Stun is Desired"; - std::cerr << std::endl; -#endif - return true; - } - else - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::checkStunDesired() Stun is Not Needed"; - std::cerr << std::endl; -#endif - return false; - } - } -} - - -bool UdpStunner::attemptStun() -{ - bool found = false; - TouStunPeer peer; - rstime_t now = time(NULL); - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::attemptStun()"; - std::cerr << std::endl; -#endif - - { - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - size_t i; - for(i = 0; ((i < mStunList.size()) && (mStunList.size() > 0) && (!found)); i++) - { - /* extract entry */ - peer = mStunList.front(); - mStunList.pop_front(); - - /* check if expired */ - if (peer.failCount > TOU_STUN_MAX_FAIL_COUNT) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::attemptStun() Peer has expired, dropping"; - std::cerr << std::endl; -#endif - } - else - { - // Peer Okay, check last send time. - if (now - peer.lastsend < TOU_STUN_MAX_SEND_RATE) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::attemptStun() Peer was sent to Too Recently, pushing back"; - std::cerr << std::endl; -#endif - mStunList.push_back(peer); - } - else - { - /* we have found a peer! */ -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::attemptStun() Found Peer to Stun."; - std::cerr << std::endl; -#endif - peer.failCount++; - peer.lastsend = now; - mStunList.push_back(peer); - mSuccessRate *= TOU_SUCCESS_LPF_FACTOR; - - found = true; - } - } - } // END OF WHILE LOOP. - - if (mStunList.size() < 1) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::attemptStun() No Peers in List. FAILED"; - std::cerr << std::endl; -#endif - return false; - } - -#ifdef DEBUG_UDP_STUNNER - locked_printStunList(); -#endif - - } // END OF MUTEX LOCKING. - - if (found) - { - doStun(peer.remote); - return true; - } - return false; -} - - -bool UdpStunner::locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr) -{ -#ifdef DEBUG_UDP_STUNNER - std::string out; - rs_sprintf(out, "UdpStunner::locked_recvdStun() from:%s:%u", rs_inet_ntoa(remote.sin_addr).c_str(), ntohs(remote.sin_port)); - rs_sprintf_append(out, " claiming ExtAddr is:%s:%u", rs_inet_ntoa(extaddr.sin_addr).c_str(), ntohs(extaddr.sin_port)); - - std::cerr << out << std::endl; -#endif - -#ifdef UDPSTUN_ALLOW_LOCALNET - struct sockaddr_in fakeExtaddr = extaddr; - if (mSimUnstableExt) - { - std::cerr << "UdpStunner::locked_recvdStun() TEST SIM UNSTABLE EXT: Forcing Port to be wrong to sim an ExclusiveNat"; - std::cerr << std::endl; - -#define UNSTABLE_PORT_RANGE 100 - - fakeExtaddr.sin_port = htons(ntohs(fakeExtaddr.sin_port) - (UNSTABLE_PORT_RANGE / 2) + RSRandom::random_u32() % UNSTABLE_PORT_RANGE); - if (!mSimSymmetricNat) - { - mSimUnstableExt = false; - } - } -#endif - - /* sanoty checks on the address - * have nasty peer that is returning its own address.... - */ - -#ifndef UDPSTUN_ALLOW_LOCALNET // CANNOT HAVE THIS CHECK IN TESTING MODE! - - if (remote.sin_addr.s_addr == extaddr.sin_addr.s_addr) - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::locked_recvdStun() WARNING, BAD PEER: "; - std::cerr << "Stun Peer Returned its own address: " << rs_inet_ntoa(remote.sin_addr); - std::cerr << std::endl; -#endif - return false; - } -#endif - - bool found = false; - std::list::iterator it; - for(it = mStunList.begin(); it != mStunList.end(); ++it) - { - if ((remote.sin_addr.s_addr == it->remote.sin_addr.s_addr) && - (remote.sin_port == it->remote.sin_port)) - { - it->failCount = 0; -#ifdef UDPSTUN_ALLOW_LOCALNET - it->eaddr = fakeExtaddr; -#else - it->eaddr = extaddr; -#endif - it->response = true; - - found = true; - break; - } - } - - /* We've received a Stun, so the ForceStun can be cancelled */ - if (found) - { - mForceRestun = false; - } - - /* if not found.. should we add it back in? */ - - /* How do we calculate the success rate? - * Don't want to count all the stuns? - * Low Pass filter won't work either... - * at send... - * mSuccessRate = 0.95 * mSuccessRate. - * at recv... - * mSuccessRate = 0.95 * mSuccessRate + 0.05; - * - * But if we split into a two stage eqn. it'll work! - * a - * mSuccessRate = 0.95 * mSuccessRate. - * at recv... - * mSuccessRate += 0.05; - */ - - mSuccessRate += (1.0-TOU_SUCCESS_LPF_FACTOR); - - rstime_t now = time(NULL); - mStunLastRecvResp = now; - mStunLastRecvAny = now; - -#ifdef DEBUG_UDP_STUNNER - locked_printStunList(); -#endif - - if (!mExclusiveMode) - { - locked_checkExternalAddress(); - } - - return found; -} - -bool UdpStunner::locked_checkExternalAddress() -{ -#ifdef DEBUG_UDP_STUNNER - std::string out = "UdpStunner::locked_checkExternalAddress()"; - std::cerr << out << std::endl; -#endif - - bool found1 = false; - bool found2 = false; - rstime_t now = time(NULL); - /* iterator backwards - as these are the most recent */ - - /******** - * DUE TO PEERS SENDING BACK FAKE STUN PACKETS... we are increasing. - * requirements to three peers...they all need matching IP addresses to have a known ExtAddr - * - * Wanted to compare 3 peer addresses... but this will mean that the UDP connections - * will take much longer... have to think of a better solution. - * - */ - std::list::reverse_iterator it; - std::list::reverse_iterator p1; - std::list::reverse_iterator p2; - for(it = mStunList.rbegin(); it != mStunList.rend(); ++it) - { - /* check: - 1) have response. - 2) have eaddr. - 3) no fails. - 4) recent age. - */ - - rstime_t age = (now - it->lastsend); - if (it->response && -#ifdef UDPSTUN_ALLOW_LOCALNET - ( mAcceptLocalNet || isExternalNet(&(it->eaddr.sin_addr))) && -#else - (isExternalNet(&(it->eaddr.sin_addr))) && -#endif - (it->failCount == 0) && (age < (long) (mTargetStunPeriod * 2))) - { - if (!found1) - { - p1 = it; - found1 = true; - } - else - { - p2 = it; - found2 = true; - break; - } - } - } - - if (found1 && found2) - { - /* If any of the addresses are different - two possibilities... - * 1) We have changed IP address. - * 2) Someone has sent us a fake STUN Packet. (Wrong Address). - * - */ - if (p1->eaddr.sin_addr.s_addr == p2->eaddr.sin_addr.s_addr) - { - eaddrKnown = true; - } - else - { -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::locked_checkExternalAddress() Found Address mismatch:"; - std::cerr << std::endl; - std::cerr << " " << inet_ntoa(p1->eaddr.sin_addr); - std::cerr << " " << inet_ntoa(p2->eaddr.sin_addr); - std::cerr << std::endl; - std::cerr << "UdpStunner::locked_checkExternalAddress() Flagging Ext Addr as Unknown"; - std::cerr << std::endl; -#endif - eaddrKnown = false; - } - - if ((eaddrKnown) && - (p1->eaddr.sin_port == p2->eaddr.sin_port)) - { - eaddrStable = true; - } - else - { - eaddrStable = false; - } - - eaddr = p1->eaddr; - eaddrTime = now; - -#ifdef DEBUG_UDP_STUNNER - std::cerr << "UdpStunner::locked_checkExternalAddress() Found State:"; - if (eaddrStable) - std::cerr << " Stable NAT translation (GOOD!) "; - else - std::cerr << " unStable (symmetric NAT translation (BAD!) or Address Unknown"; - - std::cerr << std::endl; -#endif - - return true; - } - - return false; -} - - - -bool UdpStunner::locked_printStunList() -{ -#ifdef DEBUG_UDP_STUNNER - std::string out = "locked_printStunList()\n"; - - rstime_t now = time(NULL); - rs_sprintf_append(out, "\tLastSendStun: %ld\n", now - mStunLastSendStun); - rs_sprintf_append(out, "\tLastSendAny: %ld\n", now - mStunLastSendAny); - rs_sprintf_append(out, "\tLastRecvResp: %ld\n", now - mStunLastRecvResp); - rs_sprintf_append(out, "\tLastRecvAny: %ld\n", now - mStunLastRecvAny); - - std::list::iterator it; - for(it = mStunList.begin(); it != mStunList.end(); ++it) - { - out += "id:" + RsUtil::BinToHex(it->id); - rs_sprintf_append(out, " addr: %s:%u", rs_inet_ntoa(it->remote.sin_addr).c_str(), htons(it->remote.sin_port)); - rs_sprintf_append(out, " eaddr: %s:%u", rs_inet_ntoa(it->eaddr.sin_addr).c_str(), htons(it->eaddr.sin_port)); - rs_sprintf_append(out, " failCount: %lu", it->failCount); - rs_sprintf_append(out, " lastSend: %ld\n", now - it->lastsend); - } - - std::cerr << out; -#endif - - return true; -} - - -bool UdpStunner::getStunPeer(int idx, std::string &id, - struct sockaddr_in &remote, struct sockaddr_in &eaddr, - uint32_t &failCount, rstime_t &lastSend) -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - std::list::iterator it; - int i; - for(i=0, it=mStunList.begin(); (iid); - remote = it->remote; - eaddr = it->eaddr; - failCount = it->failCount; - lastSend = it->lastsend; - return true; - } - - return false; -} - - -bool UdpStunner::needStunPeers() -{ - RsStackMutex stack(stunMtx); /********** LOCK MUTEX *********/ - - return (mStunList.size() < TOU_STUN_MIN_PEERS); -} - - diff --git a/libretroshare/src/tcponudp/udpstunner.h b/libretroshare/src/tcponudp/udpstunner.h deleted file mode 100644 index 00accaa45..000000000 --- a/libretroshare/src/tcponudp/udpstunner.h +++ /dev/null @@ -1,197 +0,0 @@ -/******************************************************************************* - * libretroshare/src/tcponudp: udpstunner.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UDP_STUN_H -#define RS_UDP_STUN_H - -#ifndef WINDOWS_SYS -#include -#endif - -#include "tcponudp/rsudpstack.h" -#include "util/rsthreads.h" -#include - -/** - * @brief The TouStunPeer class - * Stuns peers to determine external addresses. - */ -class TouStunPeer -{ - public: - TouStunPeer() - :response(false), lastsend(0), failCount(0) - { - eaddr.sin_addr.s_addr = 0; - eaddr.sin_port = 0; - return; - } - - TouStunPeer(std::string id_in, const struct sockaddr_in &addr) - :id(id_in), remote(addr), response(false), lastsend(0), failCount(0) - { - eaddr.sin_addr.s_addr = 0; - eaddr.sin_port = 0; - return; - } - - /// id for identification - std::string id; - /// Remote address of the peer. - struct sockaddr_in remote; - /// Our external IP address as reported by the peer. - struct sockaddr_in eaddr; - /// true when a response was received in the past - bool response; - /// used to rate limit STUN requests - rstime_t lastsend; - /// fail counter for dead/bad peer detection (0 = good) - uint32_t failCount; -}; - -/* - * FOR TESTING ONLY. - * #define UDPSTUN_ALLOW_LOCALNET 1 - */ - -/** - * @brief The UdpStunner class - * The UDP stunner implements the STUN protocol to determin the NAT type (behind that RS is usually running). - * It maintains a list of DHT peers that are regulary contacted. - * - * The actual NAT type determination logic is located in void pqiNetStateBox::determineNetworkState() - */ -class UdpStunner: public UdpSubReceiver -{ - public: - - UdpStunner(UdpPublisher *pub); -virtual ~UdpStunner() { return; } - -#ifdef UDPSTUN_ALLOW_LOCALNET - // For Local Testing Mode. - void SetAcceptLocalNet(); - void SimExclusiveNat(); - void SimSymmetricNat(); -#endif - -int grabExclusiveMode(std::string holder); /* returns seconds since last send/recv */ -int releaseExclusiveMode(std::string holder, bool forceStun); - - -void setTargetStunPeriod(int32_t sec_per_stun); -bool addStunPeer(const struct sockaddr_in &remote, const char *peerid); -bool dropStunPeer(const struct sockaddr_in &remote); - -bool getStunPeer(int idx, std::string &id, - struct sockaddr_in &remote, struct sockaddr_in &eaddr, - uint32_t &failCount, rstime_t &lastSend); - -bool needStunPeers(); - -bool externalAddr(struct sockaddr_in &remote, uint8_t &stable); - - /* Packet IO */ -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); -virtual int status(std::ostream &out); - - /* monitoring / updates */ - int tick(); - - /* - * based on RFC 3489 - */ - static constexpr uint16_t STUN_BINDING_REQUEST = 0x0001; - static constexpr uint16_t STUN_BINDING_RESPONSE = 0x0101; - - private: - -bool checkStunDesired(); -bool attemptStun(); - -int doStun(struct sockaddr_in stun_addr); -bool storeStunPeer(const struct sockaddr_in &remote, const char *peerid, bool sent); - - - /* STUN handling */ -bool locked_handleStunPkt(void *data, int size, struct sockaddr_in &from); - -bool locked_printStunList(); -bool locked_recvdStun(const struct sockaddr_in &remote, const struct sockaddr_in &extaddr); -bool locked_checkExternalAddress(); - - - RsMutex stunMtx; /* for all class data (below) */ - - struct sockaddr_in eaddr; /* external addr */ - - bool eaddrKnown; - bool eaddrStable; /* if true then usable. if false -> Symmettric NAT */ - rstime_t eaddrTime; - - rstime_t mStunLastRecvResp; - rstime_t mStunLastRecvAny; - rstime_t mStunLastSendStun; - rstime_t mStunLastSendAny; - - std::list mStunList; /* potentials */ - -#ifdef UDPSTUN_ALLOW_LOCALNET - // For Local Testing Mode. - bool mAcceptLocalNet; - bool mSimUnstableExt; - bool mSimExclusiveNat; - bool mSimSymmetricNat; - -#endif - - /// The UDP stunner will only (actively) contact it's peers when mPassiveStunMode is false. (has priority over mForceRestun - bool mPassiveStunMode; - /// Time between STUNs - uint32_t mTargetStunPeriod; - /// Rate that determines how often STUN attempts are successfull - double mSuccessRate; - - /// Some variables used for tracking who and when exclusive mode is enabled - bool mExclusiveMode; /* when this is switched on, the stunner stays silent (and extAddr is maintained) */ - rstime_t mExclusiveModeTS; - std::string mExclusiveHolder; - - /// force a STUN immediately - bool mForceRestun; - -}; - - /* generic stun functions */ - -bool UdpStun_isStunPacket(void *data, int size); -bool UdpStun_response(void *stun_pkt, int size, struct sockaddr_in &addr); -/** - * @brief UdpStun_generate_stun_reply Generates a STUN reply package. - * @param stun_addr The address to set in the response field. - * @param len Lenght of the generated package (always 28). - * @param transId The transaction ID of the request package. - * @return Pointer to the generated reply package. - */ -void *UdpStun_generate_stun_reply(struct sockaddr_in *stun_addr, int *len, const void* transId); -bool UdpStun_generate_stun_pkt(void *stun_pkt, int *len); - -#endif diff --git a/libretroshare/src/tests/TestNotes.txt b/libretroshare/src/tests/TestNotes.txt deleted file mode 100644 index 5d993d8d1..000000000 --- a/libretroshare/src/tests/TestNotes.txt +++ /dev/null @@ -1,39 +0,0 @@ - -This file documents the high-level status of the regression cases. ------------+----------------------+------------------------------------------------- -DIRECTORY | STATUS | TODO ------------+----------------------+------------------------------------------------- -services | NO TESTS | write test framework for services. -turtle | NO TESTS | write tests -rsserver | NO TESTS | write tests -upnp | automatic tests | [--S] -pgp | automatic tests | [---] -util | automatic tests | [---] -dbase | automatic tests | [--S] -pqi | automatic tests | [C--] -ft | automatic tests | [-FS] (ftcontrollertest, ftserver2test, fttransfermoduletest) -tcponudp | automatic tests | [-F-] Takes 15 mins. test_tou,bidir_tou,stacks_tou fail -dht | NO TESTS | write tests -serialiser | automatic tests | [-F-] (tlvrandom_test) ------------+----------------------+------------------------------------------------- - -Legend: - [---] : nothing to do. All work perfectly. - [ S] : needs scripts - [ F ] : some tests fail - [C ] : some tests don't compile - [E ] : some test execution fail - -Commands: - - to launch tests in a directory: - > \rm *.tstout - > make regress - - - to use parameters: - * create a script [testname].sh where [testname] is the name of the - executable test. It will be used automatically by the above command. - * in the script, use a single command, or if necessary put all commands - on one line using &&. - - - diff --git a/libretroshare/src/tests/common/testutils.h b/libretroshare/src/tests/common/testutils.h deleted file mode 100644 index f5323139c..000000000 --- a/libretroshare/src/tests/common/testutils.h +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -class TestUtils -{ - public: - // Creates a random file of the given size at the given place. Useful for file transfer tests. - // - static bool createRandomFile(const std::string& filename,const uint64_t size) - { - FILE *f = fopen(filename.c_str(),"wb") ; - - if(f == NULL) - return 0 ; - - uint32_t S = 5000 ; - uint32_t *data = new uint32_t[S] ; - - for(uint64_t i=0;i::random().toStdString(false); - } - static std::string createRandomSSLId() - { - return t_RsGenericIdType<16>::random().toStdString(false); - } - static std::string createRandomPGPId() - { - return t_RsGenericIdType<8>::random().toStdString(true); - } - - class DummyAuthGPG: public AuthGPG - { - public: - DummyAuthGPG(const std::string& ownId) - :AuthGPG("pgp_pubring.pgp","pgp_secring.pgp","pgp_trustdb.pgp","lock"), mOwnId(ownId) - { - } - - virtual std::string getGPGOwnId() - { - return mOwnId ; - } - - virtual bool isGPGAccepted(const std::string& pgp_id) { return true ; } - - private: - std::string mOwnId ; - }; - - class DummyAuthSSL: public AuthSSLimpl - { - public: - DummyAuthSSL(const std::string& ownId) - : mOwnId(ownId) - { - } - - virtual std::string OwnId() - { - return mOwnId ; - } - - private: - std::string mOwnId ; - }; - - class DummyRsPeers: public p3Peers - { - public: - DummyRsPeers(p3LinkMgr *lm, p3PeerMgr *pm, p3NetMgr *nm) : p3Peers(lm,pm,nm) {} - - //virtual bool getFriendList(std::list& fl) { ; return true ;} - - private: - std::list mFriends ; - }; -}; diff --git a/libretroshare/src/tests/dbase/ficachetest.cc b/libretroshare/src/tests/dbase/ficachetest.cc deleted file mode 100644 index 3d2c62074..000000000 --- a/libretroshare/src/tests/dbase/ficachetest.cc +++ /dev/null @@ -1,208 +0,0 @@ -/* - * RetroShare FileCache Module: ficachetest.cc - * - * Copyright 2004-2007 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "dbase/cachestrapper.h" -#include "dbase/cachetest.h" -#include "pqi/p3connmgr.h" - -#include -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS -#else - #include -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - -void handleQuery(CacheStrapper *csp, RsPeerId pid, - std::map &strappers); - -/* A simple test of the CacheStrapper Code. - * - * create 3 different CacheStrappers, each with a Source/Store Pair and Transfer Class. - * pass queries and responses between the CacheStrappers, - * and ensure that the hashes in the Caches are updated. - * - */ - -int main(int argc, char **argv) -{ - - rstime_t period = 11; - RsPeerId pid1("0x0101"); - RsPeerId pid2("0x0102"); - RsPeerId pid3("0x0103"); - - p3ConnectMgr *connMgr1 = new p3ConnectMgr(); - p3ConnectMgr *connMgr2 = connMgr1; - p3ConnectMgr *connMgr3 = connMgr1; - - CacheStrapper sc1(connMgr1); - CacheStrapper sc2(connMgr2); - CacheStrapper sc3(connMgr3); - CacheTransfer ctt1(&sc1); - CacheTransfer ctt2(&sc2); - CacheTransfer ctt3(&sc3); - - std::map strappers; - strappers[pid1] = &sc1; - strappers[pid2] = &sc2; - strappers[pid3] = &sc3; - - - std::string nulldir = ""; - - CacheSource *csrc1 = new CacheTestSource(&sc1, nulldir); - CacheStore *cstore1 = new CacheTestStore(&ctt1, &sc1, nulldir); - CacheId cid1(TESTID, 0); - - CacheSource *csrc2 = new CacheTestSource(&sc2, nulldir); - CacheStore *cstore2 = new CacheTestStore(&ctt2, &sc2, nulldir); - CacheId cid2(TESTID, 0); - - CacheSource *csrc3 = new CacheTestSource(&sc3, nulldir); - CacheStore *cstore3 = new CacheTestStore(&ctt3, &sc3, nulldir); - CacheId cid3(TESTID, 0); - - CachePair cp1(csrc1, cstore1, cid1); - CachePair cp2(csrc2, cstore2, cid2); - CachePair cp3(csrc3, cstore3, cid3); - - sc1.addCachePair(cp1); - sc2.addCachePair(cp2); - sc3.addCachePair(cp3); - - /* add in a cache to sc2 */ - RsCacheData cdata; - - cdata.pid = pid1; - cdata.cid = cid1; - cdata.name = "Perm Cache"; - cdata.path = "./"; - cdata.hash = "GHJKI"; - - csrc1->refreshCache(cdata); - - cdata.pid = pid2; - cdata.cid = cid2; - cdata.name = "Funny Cache"; - cdata.path = "./"; - cdata.hash = "ABCDEF"; - - csrc2->refreshCache(cdata); - - /* now exercise it */ - - for(int i = 0; 1 ; i++) - { - RsPeerId src(""); - CacheStrapper *csp = NULL; - - if (i % 5 == 1) - { - src = pid1; - csp = &sc1; - } - else if (i % 5 == 2) - { - src = pid2; - csp = &sc2; - } - else if (i % 5 == 3) - { - src = pid3; - csp = &sc3; - } - std::cerr << std::endl; - std::cerr << "Cache Iteraton: " << time(NULL) << std::endl; - std::cerr << std::endl; - - if (src != "") - { - handleQuery(csp, src, strappers); - } - - - if (i % 21 == 0) - { - /* print out the resources */ - sc1.listCaches(std::cerr); - sc2.listCaches(std::cerr); - sc3.listCaches(std::cerr); - } - - /* every once in a while change the cache on 2 */ - if (i % 31 == 25) - { - cdata.hash += "X"; - csrc2->refreshCache(cdata); - } - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(1); -#else - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - /* tick the systems */ - - } - - /* Cleanup - TODO */ - - return 1; -} - -void handleQuery(CacheStrapper *csp, RsPeerId pid, - std::map &strappers) -{ - /* query */ - std::list ids; - std::list::iterator pit; - - std::cerr << "Cache Query from: " << pid << std::endl; - - //csp -> sendCacheQuery(ids, time(NULL)); - for(pit = ids.begin(); pit != ids.end(); pit++) - { - std::cerr << "Cache Query for: " << (*pit) << std::endl; - std::map::iterator sit; - if (strappers.end() != (sit = strappers.find(*pit))) - { - std::map hashs; - std::map::iterator hit; - (sit -> second) -> handleCacheQuery(pid, hashs); - for(hit = hashs.begin(); hit != hashs.end(); hit++) - { - csp -> recvCacheResponse(hit->second, time(NULL)); - } - } - else - { - std::cerr << "Unknown Query Destination!" << std::endl; - } - } -} - diff --git a/libretroshare/src/tests/dbase/fimontest.cc b/libretroshare/src/tests/dbase/fimontest.cc deleted file mode 100644 index ec9e9989b..000000000 --- a/libretroshare/src/tests/dbase/fimontest.cc +++ /dev/null @@ -1,99 +0,0 @@ -/* - * RetroShare FileCache Module: fimontest.cc - * - * Copyright 2004-2007 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -//#include "pqi/p3connmgr.h" -#include "retroshare/rsiface.h" -#include "dbase/cachestrapper.h" -#include "dbase/findex.h" -#include "dbase/fimonitor.h" - -#include - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-p ] shareDir1 [shareDir2 [shareDir3 [...]]]"; - std::cerr << std::endl; - exit(1); -} - - -/*! - * What is tested: - * 1. - * 2. - * 3. - */ -int main(int argc, char **argv) -{ - /* handle commandline arguments */ - int c; - int period = 60; /* recheck period in seconds */ - - while((c = getopt(argc, argv,"p:")) != -1) - { - switch(c) - { - case 'p': - period = atoi(optarg); - break; - default: - std::cerr << "Bad Option."; - std::cerr << std::endl; - usage(argv[0]); - break; - } - } - - std::list rootdirs; - - /* add all the rest of the commandline arguments to rootdirs list */ - for(; optind < argc; optind++) - { - SharedDirInfo dir; - dir.filename = argv[optind]; - dir.shareflags = DIR_FLAGS_PERMISSIONS_MASK ; - rootdirs.push_back(dir); - std::cerr << "Adding shared directory: " << argv[optind] << std::endl; - } - - if (rootdirs.size() < 1) - { - usage(argv[0]); - } - - //p3ConnectMgr connMgr; - NotifyBase nb; - CacheStrapper* cs = NULL; - - FileIndexMonitor mon(cs, &nb, "", "OWN ID", std::string(".")); - - /* setup monitor */ - mon.setSharedDirectories(rootdirs); - - /* simulate running the thread */ - mon.run(); - - return 1; -} - - diff --git a/libretroshare/src/tests/dbase/fisavetest.cc b/libretroshare/src/tests/dbase/fisavetest.cc deleted file mode 100644 index 94d2905d6..000000000 --- a/libretroshare/src/tests/dbase/fisavetest.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * RetroShare FileCache Module: fisavetest.cc - * - * Copyright 2004-2007 by Kefei Zhou. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "dbase/findex.h" -#include - -FileIndex *createBasicFileIndex(rstime_t age); - -int main() -{ - FileIndex *fi1 = createBasicFileIndex(100); - FileIndex *fi2 = new FileIndex("A SILLY ID"); - - std::string out ; - fi1->printFileIndex(out); - std::cout << out < forbiddenroots; - fi1->saveIndex("test.index", fhash, size, forbiddenroots); - - std::cout << " Saved Index: Size: " << size << " Hash: " << fhash << std::endl; - std::cout << " -- new file index -- " << std::endl; - - fi2->loadIndex("test.index", fhash, size); - out.clear() ; - fi2->printFileIndex(out); - std::cout << out << std::endl; - - delete fi1; - delete fi2; - - return 1; -} - - -FileIndex *createBasicFileIndex(rstime_t age) -{ - FileIndex *fi = new FileIndex("A SILLY ID"); - - FileEntry fe; - - std::list rootdirs; - rootdirs.push_back("base1"); - rootdirs.push_back("base2"); - rootdirs.push_back("base3"); - - fi -> setRootDirectories(rootdirs, age); - - /* add some entries */ - fe.name = "dir1"; - fi -> updateDirEntry("base1",fe, age); - fe.name = "dir2"; - fi -> updateDirEntry("base1",fe, age); - - fe.name = "dir01"; - fi -> updateDirEntry("/base1/dir1/",fe, age); - - fe.name = "dir001"; - fi -> updateDirEntry("/base1/dir1/dir01/",fe, age); - - fe.name = "file1"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file2"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file3"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file4"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - - - fe.name = "dir2"; - fi -> updateDirEntry("/base1",fe, age); - fe.name = "file5"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file6"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file7"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file8"; - fi -> updateFileEntry("/base1/",fe, age); - - - fe.name = "dir3"; - fi -> updateDirEntry("/base1/dir2/",fe, age); - fe.name = "file10"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - fe.name = "file11"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - fe.name = "file12"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - - - fe.name = "dir4"; - fi -> updateDirEntry("/base3/",fe, age); - fe.name = "file20"; - fi -> updateFileEntry("/base3/dir4/",fe, age); - fe.name = "file21"; - fi -> updateFileEntry("/base3/dir4",fe, age); - - return fi; -} - diff --git a/libretroshare/src/tests/dbase/fitest2.cc b/libretroshare/src/tests/dbase/fitest2.cc deleted file mode 100644 index b3f74775d..000000000 --- a/libretroshare/src/tests/dbase/fitest2.cc +++ /dev/null @@ -1,226 +0,0 @@ -/* - * RetroShare FileCache Module: fitest2.cc - * - * Copyright 2004-2007 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "dbase/findex.h" - -#include - -FileIndex *createBasicFileIndex(rstime_t age); - -int test1(FileIndex *fi); -int test2(FileIndex *fi); - -int main() -{ - FileIndex *fi = createBasicFileIndex(100); - - test1(fi); - - delete fi; - - return 1; -} - -int test1(FileIndex *fi) -{ - /* in this test we are going to get the old directories - and update them */ - rstime_t stamp = 200; - - DirEntry *olddir = NULL; - FileEntry fe; - while((olddir = fi -> findOldDirectory(stamp))) - { - /* update the directories and files here */ - std::map::iterator dit; - std::map::iterator fit; - - /* update this dir */ - fe.name = olddir->name; - fi -> updateDirEntry(olddir->parent->path, fe, stamp); - - /* update subdirs */ - for(dit = olddir->subdirs.begin(); dit != olddir->subdirs.end(); dit++) - { - fe.name = (dit->second)->name; - /* set the age as out-of-date so that it gets checked */ - fi -> updateDirEntry(olddir->path, fe, 0); - } - - /* update files */ - for(fit = olddir->files.begin(); fit != olddir->files.end(); fit++) - { - fe.name = (fit->second)->name; - fi -> updateFileEntry(olddir->path, fe, stamp); - } - - /* clean up the dir (should have no effect) */ - fi -> removeOldDirectory(olddir->parent->path, olddir->name, stamp); - - std::string out ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - } - - std::string out ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - - return 1; -} - - -int test2(FileIndex *fi) -{ - /* in this test we are going to simulate that 2 directories have disappeared */ - rstime_t stamp = 200; - - DirEntry *olddir = NULL; - FileEntry fe; - bool missingdir = false; - int i = 0; - - while((olddir = fi -> findOldDirectory(stamp))) - { - missingdir = false; - if (i % 2 == 0) - { - std::cerr << " Simulating that dir doesnt exist :" << olddir->path; - std::cerr << std::endl; - missingdir = true; - } - i++; - - if (!missingdir) - { - /* update the directories and files here */ - std::map::iterator dit; - std::map::iterator fit; - - /* update this dir */ - fe.name = olddir->name; - fi -> updateDirEntry(olddir->parent->path, fe, stamp); - - /* update subdirs */ - for(dit = olddir->subdirs.begin(); dit != olddir->subdirs.end(); dit++) - { - fe.name = (dit->second)->name; - /* set the age as out-of-date so that it gets checked */ - fi -> updateDirEntry(olddir->path, fe, 0); - } - - /* update files */ - for(fit = olddir->files.begin(); fit != olddir->files.end(); fit++) - { - fe.name = (fit->second)->name; - fi -> updateFileEntry(olddir->path, fe, stamp); - } - } - /* clean up the dir */ - fi -> removeOldDirectory(olddir->parent->path, olddir->name, stamp); - - std::string out ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - } - - std::string out ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - - return 1; -} - - - - - -FileIndex *createBasicFileIndex(rstime_t age) -{ - FileIndex *fi = new FileIndex("A SILLY ID"); - - FileEntry fe; - - /* print empty FileIndex */ - std::string out ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - - std::list rootdirs; - rootdirs.push_back("base1"); - rootdirs.push_back("base2"); - rootdirs.push_back("base3"); - - fi -> setRootDirectories(rootdirs, age); - - /* add some entries */ - fe.name = "dir1"; - fi -> updateDirEntry("base1",fe, age); - fe.name = "file1"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file2"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file3"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - fe.name = "file4"; - fi -> updateFileEntry("/base1/dir1/",fe, age); - - fe.name = "dir2"; - fi -> updateDirEntry("/base1",fe, age); - fe.name = "file5"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file6"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file7"; - fi -> updateFileEntry("/base1/dir2/",fe, age); - fe.name = "file8"; - fi -> updateFileEntry("/base1/",fe, age); - - - fe.name = "dir3"; - fi -> updateDirEntry("/base1/dir2/",fe, age); - fe.name = "file10"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - fe.name = "file11"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - fe.name = "file12"; - fi -> updateFileEntry("/base1/dir2/dir3",fe, age); - - - fe.name = "dir4"; - fi -> updateDirEntry("/base3/",fe, age); - fe.name = "file20"; - fi -> updateFileEntry("/base3/dir4/",fe, age); - fe.name = "file21"; - fi -> updateFileEntry("/base3/dir4",fe, age); - - // one that will fail. - fe.name = "file20"; - fi -> updateFileEntry("/base3/",fe, age); - - out.clear() ; - fi -> printFileIndex(out); - std::cout << out << std::endl; - - return fi; -} - diff --git a/libretroshare/src/tests/dbase/searchtest.cc b/libretroshare/src/tests/dbase/searchtest.cc deleted file mode 100644 index d09e1b565..000000000 --- a/libretroshare/src/tests/dbase/searchtest.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * RetroShare FileCache Module: searchtest.cc - * - * Copyright 2004-2007 by Kefei Zhou. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "dbase/findex.h" -#include -#include - -int main() -{ - - std::cout << std::string::npos << std::endl; - std::string testfile = "searchtest.index"; - std::string fhash = "6851c28d99a6616a86942c3914476bf11997242a"; - FileIndex *fi = new FileIndex("DUMB ID"); - - // loading fileindex - std::cout << std::endl << "Test load" << std::endl; - fi->loadIndex(testfile, fhash, 1532); - fi->printFileIndex(std::cout); - std::cout << "FileIndex Loaded" << std::endl << std::endl; - - std::list hashresult; - std::list termresult; - - // searchhash - std::string findhash = "82bffa6e1cdf8419397311789391238174817481"; - - - std::cout << "Search hash : " << findhash << std::endl; - fi->searchHash(findhash, hashresult); - - while(!hashresult.empty()) - { - std::string out ; - hashresult.back()->print(out); - std::cout << out << std::endl; - hashresult.pop_back(); - } - - // searchterm - std::list terms; - terms.push_back("paper"); - terms.push_back("doc"); - - std::cout << "Search terms" << std::endl; - fi->searchTerms(terms, termresult); - - while(!termresult.empty()) - { - std::string out ; - termresult.back()->print(out); - std::cout << out << std::endl; - termresult.pop_back(); - } - - delete fi; - return 1; -} diff --git a/libretroshare/src/tests/ft/TestNotes.txt b/libretroshare/src/tests/ft/TestNotes.txt deleted file mode 100644 index 013fe879e..000000000 --- a/libretroshare/src/tests/ft/TestNotes.txt +++ /dev/null @@ -1,54 +0,0 @@ - -Features that need to be tested, and which test checks it. ------------------------------------------------------------ - -(*) Transfer Related - -(*) Search Related - -(*) ExtraList Related - -(*) Cache Related - -(*) Config / Storage. - Change Config Directory works dynamically. (no restart required). - - -(*) Miscelleous - - - ------------------------------------------------------------ ------------------------------------------------------------ -Actual Tests, and what they check. ------------------------------------------------------------ - -ftserver1test.cc -================== - -Used to develop test framework. -Tests. - 1) Test Framework. OK - 2) File Indexing. OK - 3) Cache Packet Exchange. OK - 4) Cache downloads (including loopback). FAILS - 5) FileIndex Store loading. - 6) Basic Search. - -ftserver2test.cc -================== - -Test out the ExtraList functions. -Demonstrates the use of libretroshare/src/util/utest.h - -Tests. - 1) Load ExtraList path OK - 2) Hashing of ExtraList File OK - 3) ExtraHashDone. OK - 4) Local Search for ExtraList Data. OK - 5) Remote Search of ExtraList (should Fail) OK - 6) Transfer of ExtraList File (Local) TODO - 7) Transfer of ExtraList File (Remote) TODO - - - diff --git a/libretroshare/src/tests/ft/ftcontrollertest.cc b/libretroshare/src/tests/ft/ftcontrollertest.cc deleted file mode 100644 index 00fb95fa2..000000000 --- a/libretroshare/src/tests/ft/ftcontrollertest.cc +++ /dev/null @@ -1,451 +0,0 @@ -/* - * libretroshare/src/ft: ftserver1test.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * ftServer2Test - Demonstrates how to check for test stuff. - */ - -#include "retroshare/rsfiles.h" -#include "retroshare/rspeers.h" -#include "retroshare/rsiface.h" -#include "rsserver/p3peers.h" -#include "ft/ftserver.h" - -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -//#include "pqi/p3authmgr.h" -//#include "pqi/p3connmgr.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3linkmgr.h" -#include "pqi/p3netmgr.h" - -#include "pqi/authssl.h" -#include "pqi/authgpg.h" - -#include "common/testutils.h" -#include "util/rsdebug.h" - -#include "pqitestor.h" -#include "util/rsdir.h" -#include "util/utest.h" - - -#include - -class TestData -{ - public: - - ftServer *loadServer; - std::list otherServers; - std::list extraList; -}; - - -extern "C" void *do_server_test_thread(void *p); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-sa] [-p ] [-d ] [-e ] [ [ ... ]] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t debugLevel = 5; - bool loadAll = false; - - std::list fileList; - std::list extraList; - std::list peerIds; - std::map mFtServers; - std::map mLinkMgrs; - - ftServer *mLoadServer = NULL; - std::list mOtherServers; - std::list::iterator eit; - - while(-1 != (c = getopt(argc, argv, "asd:p:e:"))) - { - switch (c) - { - case 'p': - peerIds.push_back(optarg); - break; - case 'd': - debugLevel = atoi(optarg); - break; -// case 's': -// debugStderr = true; -// break; - case 'e': - extraList.push_back(optarg); - break; - case 'a': - loadAll = true; - break; - default: - usage(argv[0]); - break; - } - } - - if(peerIds.empty()) - { - peerIds.push_back(TestUtils::createRandomSSLId()) ; - - // then add some other peer ids. - peerIds.push_back(TestUtils::createRandomSSLId()) ; - peerIds.push_back(TestUtils::createRandomSSLId()) ; - peerIds.push_back(TestUtils::createRandomSSLId()) ; - } - - std::string ssl_own_id = TestUtils::createRandomSSLId() ; - std::string gpg_own_id = TestUtils::createRandomPGPId() ; - - TestUtils::DummyAuthGPG fakeGPG(gpg_own_id) ; - AuthGPG::setAuthGPG_debug(&fakeGPG) ; - - TestUtils::DummyAuthSSL fakeSSL(ssl_own_id) ; - AuthSSL::setAuthSSL_debug(&fakeSSL) ; - - /* do logging */ - setOutputLevel(debugLevel); - - if (optind >= argc) - { - std::cerr << "Missing Shared Directories" << std::endl; - usage(argv[0]); - } - - for(; optind < argc; optind++) - { - std::cerr << "Adding: " << argv[optind] << std::endl; - - SharedDirInfo info ; - info.shareflags = DIR_FLAGS_PERMISSIONS_MASK; - info.filename = std::string(argv[optind]); - info.virtualname = info.filename ; - - fileList.push_back(info) ; - } - - /* We need to setup a series 2 - 4 different ftServers.... - * - * Each one needs: - * - * - * A List of peerIds... - */ - - std::list::const_iterator it, jit; - - std::list baseFriendList, friendList; - std::list::iterator fit; - - P3Hub *testHub = new P3Hub(0,NULL); - testHub->start(); - - /* Setup Base Friend Info */ - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - RsPeerDetails pad; - pad.id = *it; - pad.gpg_id = TestUtils::createRandomPGPId() ; - pad.name = *it; - pad.trustLvl = 5; - pad.ownsign = true; - //pad.trusted = false; - - baseFriendList.push_back(pad); - - std::cerr << "ftserver1test::setup peer: " << *it << std::endl; - } - - std::ostringstream pname; - pname << "/tmp/rstst-" << time(NULL); - - std::string basepath = pname.str(); - RsDirUtil::checkCreateDirectory(basepath); - - - - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - friendList = baseFriendList; - /* remove current one */ - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - if (fit->id == *it) - { - friendList.erase(fit); - break; - } - } - - //p3AuthMgr *authMgr = new p3DummyAuthMgr(*it, friendList); - p3PeerMgrIMPL *peerMgr = new p3PeerMgrIMPL(ssl_own_id,gpg_own_id,"My GPG name","My SSL location"); - - p3NetMgrIMPL *netMgr = new p3NetMgrIMPL ; - p3LinkMgrIMPL *linkMgr = new p3LinkMgrIMPL(peerMgr,netMgr); - mLinkMgrs[*it] = linkMgr; - - rsPeers = new TestUtils::DummyRsPeers(linkMgr,peerMgr,netMgr) ; - - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - /* add as peer to authMgr */ - peerMgr->addFriend(fit->id,fit->gpg_id); - } - - P3Pipe *pipe = new P3Pipe(); //(*it); - - /* add server */ - ftServer *server; - server = new ftServer(peerMgr,linkMgr); - mFtServers[*it] = server; - if (!mLoadServer) - { - mLoadServer = server; - } - else - { - mOtherServers.push_back(server); - } - - - server->setP3Interface(pipe); - - std::string configpath = basepath + "/" + *it; - RsDirUtil::checkCreateDirectory(configpath); - - std::string cachepath = configpath + "/cache"; - RsDirUtil::checkCreateDirectory(cachepath); - - std::string localpath = cachepath + "/local"; - RsDirUtil::checkCreateDirectory(localpath); - - std::string remotepath = cachepath + "/remote"; - RsDirUtil::checkCreateDirectory(remotepath); - - server->setConfigDirectory(configpath); - - NotifyBase *base = new NotifyBase; - server->SetupFtServer(base); - - testHub->addP3Pipe(*it, pipe, linkMgr); - server->StartupThreads(); - - /* setup any extra bits */ - if (loadAll) - { - server->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - server->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - } - - if (mLoadServer) - { - mLoadServer->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - mLoadServer->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - - /* stick your real test here */ - std::map::iterator sit; - std::map::iterator cit; - - /* Start up test thread */ - pthread_t tid; - TestData *mFt = new TestData; - - /* set data */ - mFt->loadServer = mLoadServer; - mFt->otherServers = mOtherServers; - mFt->extraList = extraList; - - void *data = (void *) mFt; - pthread_create(&tid, 0, &do_server_test_thread, data); - pthread_detach(tid); /* so memory is reclaimed in linux */ - - while(1) - { - std::cerr << "ftserver2test::sleep()"; - std::cerr << std::endl; - sleep(1); - - /* tick the connmgrs */ - for(sit = mFtServers.begin(); sit != mFtServers.end(); sit++) - { - /* update */ - (sit->second)->tick(); - } - - for(cit = mLinkMgrs.begin(); cit != mLinkMgrs.end(); cit++) - { - /* update */ - (cit->second)->tick(); - } - } -} - -/* So our actual test can run here..... - * - */ - -INITTEST(); - -void *do_server_test_thread(void *data) -{ - TestData *mFt = (TestData *) data; - - std::cerr << "do_server_test_thread() running"; - std::cerr << std::endl; - - /************************* TEST 1 ********************** - * Check that the extra List has been processed. - */ - rstime_t start = time(NULL); - - FileInfo info, info2; - rstime_t now = time(NULL); - std::list::iterator eit; - for(eit = mFt->extraList.begin(); eit != mFt->extraList.end(); eit++) - { - std::cerr << "Treating extra file " << *eit << std::endl; - - while(!mFt->loadServer->ExtraFileStatus(*eit, info)) - { - - /* max of 30 seconds */ - now = time(NULL); - if (now - start > 30) - { - /* FAIL */ - REPORT2( false, "Extra File Hashing"); - } - - sleep(1); - } - - /* Got ExtraFileStatus */ - REPORT("Successfully Found ExtraFile"); - - /* now we can try a search (should succeed) */ - FileSearchFlags hintflags = RS_FILE_HINTS_EXTRA; - - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - CHECK(info2.hash == info.hash); - CHECK(info2.size == info.size); - CHECK(info2.fname == info.fname); - } - else - { - REPORT2( false, "Search for Extra File (Basic)"); - } - - /* search with flags (should succeed) */ - hintflags = RS_FILE_HINTS_EXTRA; - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - CHECK(info2.hash == info.hash); - CHECK(info2.size == info.size); - CHECK(info2.fname == info.fname); - } - else - { - REPORT2( false, "Search for Extra File (Extra Flag)"); - } - - /* search with other flags (should fail) */ - hintflags = RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY; - - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - REPORT2( false, "Search for Extra File (Fail Flags)"); - } - else - { - REPORT("Search for Extra File (Fail Flags)"); - } - - /* if we try to download it ... should just find existing one*/ - - REPORT("Testing with Extra File"); - } - - FINALREPORT("ExtraList Hashing, Searching and Downloading"); - - /************************* TEST 2 ********************** - * test ftController and ftTransferModule - */ - ftServer *server=mFt->loadServer; - - std::string fname,filehash,destination; - FileSearchFlags flags; - std::list srcIds; - - /* select a file from otherServers */ - if (mFt->otherServers.empty() ) - { - REPORT2(false,"No otherServers available"); - exit(1); - } - - DirDetails details; - flags = RS_FILE_HINTS_REMOTE; - void *ref = NULL; - - if(!server->RequestDirDetails(ref,details,flags)) - { - REPORT2(false,"fail to call RequestDirDetails"); - } - - if (details.type == DIR_TYPE_FILE) - { - REPORT("RemoteDirModel::downloadSelected() Calling File Request"); - std::list srcIds; - srcIds.push_back(details.id); - server->FileRequest(details.name, details.hash, details.count, "", TransferRequestFlags(0), srcIds); - } - - exit(1); -} - - - - diff --git a/libretroshare/src/tests/ft/ftcontrollertest.sh b/libretroshare/src/tests/ft/ftcontrollertest.sh deleted file mode 100755 index e4a9d2fa5..000000000 --- a/libretroshare/src/tests/ft/ftcontrollertest.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -./ftcontrollertest -p 8cb3a1677872c9e8248fd5ddeac84000 -p 8cb3a1677872c9e8248fd5ddeac84001 -p 8cb3a1677872c9e8248fd5ddeac84002 -e ftcontrollertest . diff --git a/libretroshare/src/tests/ft/ftcrc32test.cc b/libretroshare/src/tests/ft/ftcrc32test.cc deleted file mode 100644 index f20144df9..000000000 --- a/libretroshare/src/tests/ft/ftcrc32test.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * libretroshare/src/ft: ftcrc32test.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 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 "retroshare@lunamutt.com". - * - */ - -#include -#include -#include "retroshare/rstypes.h" -#include -#include - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "util/rsdir.h" -#include "util/utest.h" -#include -#include - -INITTEST() ; - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t dPeriod = 600; /* default 10 minutes */ - - std::string inputfile ; - - argstream as(argc,argv) ; - - as >> parameter('i',"input",inputfile,"Input file to hash. If none, a random file will be created in /tmp",false) - >> help() ; - - as.defaultErrorHandling() ; - - if(inputfile == "") - { - uint64_t S = 3983782 ; - std::cerr << "Creating a dummy input file in /tmp, of size " << S << std::endl; - inputfile = "crc_test_data.bin" ; - - if(!TestUtils::createRandomFile(inputfile,S)) - return 1 ; - } - - std::list hashList ; - hashList.push_back(inputfile) ; - - uint32_t flags = 0; - for(std::list::const_iterator it(hashList.begin()); it != hashList.end(); it++) - { - std::cerr << "Hashing file :" << *it << std::endl ; - - std::string hash ; - uint64_t size ; - std::string name ; - RsDirUtil::hashFile( *it,name,hash,size) ; - - std::cerr << "Hash = " << hash << std::endl; - - FILE *f = fopen( (*it).c_str(),"rb" ) ; - - if(f == NULL) - { - std::cerr << "Could not open this file! Sorry." << std::endl ; - return 1 ; - } - CRC32Map crc_map ; - - if(fseek(f,0,SEEK_END)) - { - std::cerr << "Could not fseek to end of this file! Sorry." << std::endl ; - fclose(f) ; - return 1 ; - } - - size = ftell(f) ; - - if(fseek(f,0,SEEK_SET)) - { - std::cerr << "Could not fseek to beginning of this file! Sorry." << std::endl ; - fclose(f) ; - return 1 ; - } - - std::cerr << "File size:" << size << std::endl ; - - RsDirUtil::crc32File(f,size,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE,crc_map) ; - fclose(f) ; - - std::cerr << "Got this CRC map: "<< std::endl ; - - for(uint32_t i=0;i -#include "ft/ftfilecreator.h" - -#include "util/utest.h" -#include "util/rsdir.h" -#include "util/rsdiscspace.h" -#include - -#include "util/rswin.h" -#include "ft/ftserver.h" - -INITTEST(); - -static void createTmpFile(const std::string& name,uint64_t size,std::string& hash) ; -static void transfer(ftFileProvider *server, const std::string& server_peer_id,ftFileCreator *client,const std::string& client_peer_id) ; - -static const float TRANSFER_FAIL_PROBABILITY = 0.0f ; - -void validateChunksToCheck(const Sha1Map& chunk_crc_map,ftFileCreator *client,const std::string& client_name) -{ - std::vector chunks ; - client->getChunksToCheck(chunks) ; - - if(chunks.size() > 0) - for(uint32_t i=0;iverifyChunk(chunks[i],chunk_crc_map[chunks[i]]) ; - } -} - -void initChunkCrcMap(const std::string& fname,Sha1Map& map) -{ - FILE *fd = fopen(fname.c_str(),"rb") ; - unsigned char *buf = new unsigned char[ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE] ; - - if(fd == NULL) - { - std::cerr << "Cannot read file " << fname << ". Something's wrong!" << std::endl; - delete[] buf ; - exit(1) ; - } - - for(int i=0;isetChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ; - client2->setChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE) ; - - // 3 - Exchange chunks, and build two copies of the file. - // - std::string peer_id_1("client peer id 1") ; - std::string peer_id_2("client peer id 2") ; - std::string server_id("server peer id") ; - - // 4 - prepare a chunk crc map to verify chunks. - - Sha1Map chunk_crc_map(size,ChunkMap::CHUNKMAP_FIXED_CHUNK_SIZE) ; - - initChunkCrcMap(fname,chunk_crc_map) ; - - std::cerr << "Computed chunk CRC map: " << std::endl; - - for(int i=0;ifinished() && client2->finished())) - { - // 1 - select a random client, get the data from him. - - ftFileProvider *tmpserver ; - ftFileCreator *tmpclient ; - std::string tmpserver_pid ; - std::string tmpclient_pid ; - - // choose client and server, randomly, provided that they are not finished. - // - if((!client1->finished()) && (client2->finished() || (lrand48()&1))) - { - //std::cerr << "###### Client 1 asking to " ; - tmpclient = client1 ; - tmpclient_pid = peer_id_1 ; - - if(lrand48()&1) - { - //std::cerr << "Client 2 " ; - tmpserver = client2 ; - tmpserver_pid = peer_id_2 ; - } - else - { - //std::cerr << "Server "; - tmpserver = server ; - tmpserver_pid = server_id ; - } - } - else // client 2 is necessarily unfinished there. - { - //std::cerr << "###### Client 2 asking to " ; - tmpclient = client2 ; - tmpclient_pid = peer_id_2 ; - - if(lrand48()&1) - { - //std::cerr << "Client 1 " ; - tmpserver = client1 ; - tmpserver_pid = peer_id_1 ; - } - else - { - //std::cerr << "Server " ; - tmpserver = server ; - tmpserver_pid = server_id ; - } - - } - - // 2 - transfer from the server to the client. - - transfer(tmpserver,tmpserver_pid,tmpclient,tmpclient_pid) ; - - printf("Client1: %08lld, Client2: %08lld, transfer from %s to %s\r",client1->getRecvd(),client2->getRecvd(),tmpserver_pid.c_str(),tmpclient_pid.c_str()) ; - fflush(stdout) ; - - // Also get chunk checking list from each server, and validate them. - - validateChunksToCheck(chunk_crc_map,client1,"client 1") ; - validateChunksToCheck(chunk_crc_map,client2,"client 2") ; - } - - // hash the received data - - std::string hash1 ; client1->hashReceivedData(hash1) ; - std::string hash2 ; client2->hashReceivedData(hash2) ; - - std::cout << "Hash = " << hash << std::endl ; - std::cout << "Hash1 = " << hash1 << std::endl ; - std::cout << "Hash2 = " << hash2 << std::endl ; - - if(hash != hash1) FAILED("hashs 0/1 defer after transfer !") ; - if(hash != hash2) FAILED("hashs 0/2 defer after transfer !") ; - if(hash1 != hash2) FAILED("hashs 1/2 defer after transfer !") ; - - FINALREPORT("File transfer test"); - - return TESTRESULT(); -} - -void transfer(ftFileProvider *server, const std::string& server_peer_id,ftFileCreator *client,const std::string& client_peer_id) -{ - uint32_t size_hint = 128 + (lrand48()%1000) ; - uint64_t offset = 0; - uint32_t chunk_size = 0; - bool toOld = false ; - - //std::cerr << " for a pending chunk of size " << size_hint ; - - if(! client->getMissingChunk(server_peer_id, size_hint, offset, chunk_size, toOld)) - { - std::cerr << "###### Server does not have any chunk to offer: server is " << server_peer_id << ", client is " << client_peer_id << std::endl ; - // Normally this can't be true, because the ChunkMap class assumes availability for non turtle - // peers. - if(toOld) - { - std::cerr << "###### Map is too old. Transferring chunk map" << std::endl ; - CompressedChunkMap map ; - server->getAvailabilityMap(map) ; - client->setSourceMap(server_peer_id,map) ; - } - return ; - } - - std::cerr << "###### Got chunk " << offset << ", size=" << chunk_size << std::endl ; - - void *data = malloc(chunk_size) ; - std::cerr << "###### Asking data " << offset << ", size=" << chunk_size << std::endl ; - - if( server->getFileData(client_peer_id,offset,chunk_size,data) ) - { - if(drand48() < TRANSFER_FAIL_PROBABILITY) - { - std::cerr << "simulating faulting data chunk " << offset << " + " << chunk_size << "." << std::endl; - } - else - { - client->addFileData(offset,chunk_size,data) ; - std::cerr << "###### Added data " << offset << ", size=" << chunk_size << std::endl ; - } - } - - std::cerr << ", completion=" << client->getRecvd() << std::endl ; - - - free(data) ; -} - -void createTmpFile(const std::string& name,uint64_t S,std::string& hash) -{ - FILE *tmpf = fopen("source_tmp.bin","w") ; - - // write 1MB chunks - uint64_t C = 1024*1024 ; - uint8_t *data = new uint8_t[C] ; - - for(uint i=0;i<=S/C;++i) - { - int Cp = C ; - if(i==S/C) - { - if(S%C>0) - Cp = S%C ; - else - break ; - } - - for(int k=0;krecvDataRequest(peerId,hash,size,offset,chunksize); -} - - /* Server Send */ -bool ftDataSendPair::sendData(const std::string &peerId, const std::string &hash, - uint64_t size, uint64_t offset, uint32_t chunksize, void *data) -{ - return mDataRecv->recvData(peerId, hash,size,offset,chunksize,data); -} - - /* Send a request for a chunk map */ -bool ftDataSendPair::sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) -{ - return mDataRecv->recvChunkMapRequest(peer_id,hash,is_client); -} - - /* Send a chunk map */ -bool ftDataSendPair::sendChunkMap(const std::string& peer_id,const std::string& hash, const CompressedChunkMap& cmap,bool is_client) -{ - return mDataRecv->recvChunkMap(peer_id,hash,cmap, is_client); -} - /* Send a request for a chunk map */ -bool ftDataSendPair::sendCRC32MapRequest(const std::string& peer_id,const std::string& hash) -{ - return mDataRecv->recvCRC32MapRequest(peer_id,hash); -} - - /* Send a chunk map */ -bool ftDataSendPair::sendCRC32Map(const std::string& peer_id,const std::string& hash, const CRC32Map& crcmap) -{ - return mDataRecv->recvCRC32Map(peer_id,hash,crcmap) ; -} - -bool ftDataSendPair::sendSingleChunkCRCRequest(const std::string& peer_id, const std::string& hash, unsigned int c_id) -{ - return mDataRecv->recvSingleChunkCRCRequest(peer_id,hash,c_id) ; -} -bool ftDataSendPair::sendSingleChunkCRC(const std::string& peer_id, const std::string& hash, uint32_t c_id, const Sha1CheckSum& crc) -{ - return mDataRecv->recvSingleChunkCRC(peer_id,hash,c_id,crc) ; -} - /* Client Send */ -bool ftDataSendDummy::sendDataRequest(const std::string &/*peerId*/, const std::string &/*hash*/, - uint64_t /*size*/, uint64_t /*offset*/, uint32_t /*chunksize*/) -{ - return true; -} - - /* Server Send */ -bool ftDataSendDummy::sendData(const std::string &/*peerId*/, const std::string &/*hash*/, - uint64_t /*size*/, uint64_t /*offset*/, uint32_t /*chunksize*/, void */*data*/) -{ - return true; -} - - - /* Send a request for a chunk map */ -bool ftDataSendDummy::sendChunkMapRequest(const std::string& /*peer_id*/,const std::string& /*hash*/,bool /*is_client*/) -{ - return true; -} - - /* Send a chunk map */ -bool ftDataSendDummy::sendChunkMap(const std::string& /*peer_id*/,const std::string& /*hash*/, const CompressedChunkMap& /*cmap*/,bool /*is_client*/) -{ - return true; -} -bool ftDataSendDummy::sendCRC32MapRequest(const std::string& /*peer_id*/,const std::string& /*hash*/) -{ - return true; -} - - /* Send a chunk map */ -bool ftDataSendDummy::sendCRC32Map(const std::string& /*peer_id*/,const std::string& /*hash*/, const CRC32Map& /*cmap*/) -{ - return true; -} - - /* Client Recv */ -bool ftDataRecvDummy::recvData(const std::string &/*peerId*/, const std::string &/*hash*/, - uint64_t /*size*/, uint64_t /*offset*/, uint32_t /*chunksize*/, void */*data*/) -{ - return true; -} - - - /* Server Recv */ -bool ftDataRecvDummy::recvDataRequest(const std::string &/*peerId*/, const std::string &/*hash*/, - uint64_t /*size*/, uint64_t /*offset*/, uint32_t /*chunksize*/) -{ - return true; -} - - /* Send a request for a chunk map */ -bool ftDataRecvDummy::recvChunkMapRequest(const std::string& /*peer_id*/,const std::string& /*hash*/, - bool /*is_client*/) -{ - return true; -} - - /* Send a chunk map */ -bool ftDataRecvDummy::recvChunkMap(const std::string& /*peer_id*/,const std::string& /*hash*/, - const CompressedChunkMap& /*cmap*/,bool /*is_client*/) -{ - return true; -} -bool ftDataRecvDummy::recvSingleChunkCrcRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_id) -{ - return true ; -} -bool ftDataRecvDummy::recvSingleChunkCrc(const std::string& peer_id,const std::string& hash,uint32_t chunk_id,const Sha1CheckSum& sum) -{ - return true ; -} - -bool ftDataRecvDummy::recvCRC32MapRequest(const std::string& /*peer_id*/,const std::string& /*hash*/) -{ - return true ; -} - - /* Send a chunk map */ -bool ftDataRecvDummy::recvCRC32Map(const std::string& /*peer_id*/,const std::string& /*hash*/, const CompressedChunkMap& /*cmap*/) -{ - return true ; -} - -bool ftDataSendDummy::sendSingleChunkCRCRequest(const std::string&, const std::string&, unsigned int) -{ - return true ; -} -bool ftDataSendDummy::sendSingleChunkCRC(const std::string&, const std::string&, uint32_t, const Sha1CheckSum&) -{ - return true ; -} diff --git a/libretroshare/src/tests/ft/ftdata_dummy.h b/libretroshare/src/tests/ft/ftdata_dummy.h deleted file mode 100644 index 6a30b5606..000000000 --- a/libretroshare/src/tests/ft/ftdata_dummy.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * libretroshare/src/ft: ftdata.h - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef FT_DATA_TEST_INTERFACE_HEADER -#define FT_DATA_TEST_INTERFACE_HEADER - -/* - * ftData. - * - * Internal Interfaces for sending and receiving data. - * Most likely to be implemented by ftServer. - * Provided as an independent interface for testing purposes. - * - */ - -#include -#include - -#include -#include - - /*************** SEND INTERFACE *******************/ - -class CompressedChunkMap ; -class Sha1CheckSum ; - - /**************** FOR TESTING ***********************/ - -/******* Pair of Send/Recv (Only need to handle Send side) ******/ -class ftDataSendPair: public ftDataSend -{ - public: - - ftDataSendPair(ftDataRecv *recv); -virtual ~ftDataSendPair() { return; } - - /* Client Send */ -virtual bool sendDataRequest(const std::string &peerId, const std::string &hash, - uint64_t size, uint64_t offset, uint32_t chunksize); - - /* Server Send */ -virtual bool sendData(const std::string &peerId, const std::string &hash, uint64_t size, - uint64_t offset, uint32_t chunksize, void *data); - - /* Send a request for a chunk map */ -virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client); - - /* Send a chunk map */ -virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash, const CompressedChunkMap& cmap,bool is_client); - - /* Send a request for a chunk map */ -virtual bool sendCRC32MapRequest(const std::string& peer_id,const std::string& hash); - - /* Send a chunk map */ -virtual bool sendCRC32Map(const std::string& peer_id,const std::string& hash, const CRC32Map& cmap); - ftDataRecv *mDataRecv; - - virtual bool sendSingleChunkCRCRequest(const std::string&, const std::string&, uint32_t); - virtual bool sendSingleChunkCRC(const std::string&, const std::string&, uint32_t, const Sha1CheckSum&); -}; - - -class ftDataSendDummy: public ftDataSend -{ - public: - virtual ~ftDataSendDummy() { return; } - - /* Client Send */ - virtual bool sendDataRequest(const std::string &peerId, const std::string &hash, - uint64_t size, uint64_t offset, uint32_t chunksize); - - /* Server Send */ - virtual bool sendData(const std::string &peerId, const std::string &hash, uint64_t size, - uint64_t offset, uint32_t chunksize, void *data); - - /* Send a request for a chunk map */ - virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client); - - /* Send a chunk map */ - virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash, const CompressedChunkMap& cmap,bool is_client); - - /* Send a request for a chunk map */ - virtual bool sendCRC32MapRequest(const std::string& peer_id,const std::string& hash); - - /* Send a chunk map */ - virtual bool sendCRC32Map(const std::string& peer_id,const std::string& hash, const CRC32Map& cmap); - - virtual bool sendSingleChunkCRCRequest(const std::string&, const std::string&, uint32_t); - virtual bool sendSingleChunkCRC(const std::string&, const std::string&, uint32_t, const Sha1CheckSum&); - -}; - -class ftDataRecvDummy: public ftDataRecv -{ - public: - -virtual ~ftDataRecvDummy() { return; } - - /* Client Recv */ -virtual bool recvData(const std::string& peerId, const std::string& hash, - uint64_t size, uint64_t offset, uint32_t chunksize, void *data); - - /* Server Recv */ -virtual bool recvDataRequest(const std::string& peerId, const std::string& hash, - uint64_t size, uint64_t offset, uint32_t chunksize); - - /* Send a request for a chunk map */ -virtual bool recvChunkMapRequest(const std::string& peer_id,const std::string& hash, - bool is_client); - - /* Send a chunk map */ -virtual bool recvChunkMap(const std::string& peer_id,const std::string& hash, - const CompressedChunkMap& cmap,bool is_client); - - /* Send a request for a chunk map */ -virtual bool recvCRC32MapRequest(const std::string& peer_id,const std::string& hash); - - /* Send a chunk map */ -virtual bool recvCRC32Map(const std::string& peer_id,const std::string& hash, const CompressedChunkMap& cmap); - -virtual bool recvSingleChunkCrcRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_id) ; -virtual bool recvSingleChunkCrc(const std::string& peer_id,const std::string& hash,uint32_t chunk_id,const Sha1CheckSum& sum); -}; - -#endif diff --git a/libretroshare/src/tests/ft/ftdataplextest.cc b/libretroshare/src/tests/ft/ftdataplextest.cc deleted file mode 100644 index 7872aa72d..000000000 --- a/libretroshare/src/tests/ft/ftdataplextest.cc +++ /dev/null @@ -1,200 +0,0 @@ -/* - * libretroshare/src/ft: ftextralisttest.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * Test for Multiplexor..... - * As this is a key middle component, it is hard to test without other bits. - * It relies on ftFileProvider/ftFileCreator/ftTransferModule... - * - * And has dummy ftDataSend and ftSearch. - * - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include -#include -#include -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -#include "ftdata_dummy.h" -#include "ftsearch_dummy.h" - -void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files); - -INITTEST() ; - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-p ] [-d ] [ ... ] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t dPeriod = 600; /* default 10 minutes */ - - std::list fileList; - - while(-1 != (c = getopt(argc, argv, "d:p:"))) - { - switch (c) - { - case 'p': - period = atoi(optarg); - break; - case 'd': - dPeriod = atoi(optarg); - break; - default: - usage(argv[0]); - break; - } - } - - if (optind >= argc) - { - uint32_t N = 4 ; - std::cerr << "Missing Files. Generating " << N << " random files." << std::endl; - - for(uint32_t i=0;istart(); - - ftSearch *ftsd = new ftSearchDummy(); - ftFileSearch *ftfs = new ftFileSearch(); - - ftfs-> addSearchMode(ftsd, RS_FILE_HINTS_LOCAL); - ftfs-> addSearchMode(eList, RS_FILE_HINTS_EXTRA); - - ftDataSend *ftds = new ftDataSendDummy(); - - /* setup Actual Test bit */ - ftDataMultiplex *ftmplex = new ftDataMultiplex("ownId", ftds, ftfs); - ftmplex->start(); - - /* Setup Search with some valid results */ - - - /* Request Data */ - - /* now work the thread */ - std::list::iterator it; - TransferRequestFlags flags(0); - for(it = fileList.begin(); it != fileList.end(); it++) - { - eList->hashExtraFile(*it, dPeriod, flags); - } - - - /* now request files from ftDataMultiplex */ - - /* just request random data packets first */ - do_random_server_test(ftmplex, eList, fileList); - - FINALREPORT("FtDataPlex test") ; - - return TESTRESULT() ; -} - - - -uint32_t do_random_server_iteration(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files) -{ - std::cerr << "do_random_server_iteration()"; - std::cerr << std::endl; - - std::list::iterator it; - uint32_t i = 0; - for(it = files.begin(); it != files.end(); it++) - { - FileInfo info; - if (eList->hashExtraFileDone(*it, info)) - { - std::cerr << "Hash Done for: " << *it; - std::cerr << std::endl; - std::cerr << info << std::endl; - - std::cerr << "Requesting Data Packet"; - std::cerr << std::endl; - - /* Server Recv */ - uint64_t offset = 10000; - uint32_t chunk = 20000; - mplex->recvDataRequest("Peer", info.hash, info.size, offset, chunk); - - i++; - } - else - { - std::cerr << "do_random_server_iteration() Hash Not Done for: " << *it; - std::cerr << std::endl; - } - } - - return i; - -} - - -void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files) -{ - std::cerr << "do_random_server_test()"; - std::cerr << std::endl; - - uint32_t size = files.size(); - while(size > do_random_server_iteration(mplex, eList, files)) - { - std::cerr << "do_random_server_test() sleep"; - std::cerr << std::endl; - - sleep(10); - } -} - - diff --git a/libretroshare/src/tests/ft/ftextralisttest.cc b/libretroshare/src/tests/ft/ftextralisttest.cc deleted file mode 100644 index 65f443eb1..000000000 --- a/libretroshare/src/tests/ft/ftextralisttest.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* - * libretroshare/src/ft: ftextralisttest.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "ft/ftextralist.h" -#include "util/utest.h" - -extern "C" void* runExtraList(void* p) -{ - ftExtraList *eList = (ftExtraList *) p; - if (!eList) - { - pthread_exit(NULL); - } - - while (1) - { - //eList->tick(); - sleep(1); - - } - - delete eList; - - pthread_exit(NULL); - - return NULL; -} - - - -void displayExtraListDetails(ftExtraList *eList, std::list toHash, std::list hashed); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " -h -p -d "; - std::cerr << std::endl; -} - -INITTEST() ; - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t dPeriod = 600; /* default 10 minutes */ - - std::list hashList; - - while(-1 != (c = getopt(argc, argv, "h:p:d:"))) - { - switch (c) - { - case 'h': - hashList.push_back(std::string(optarg)); - break; - case 'p': - period = atoi(optarg); - break; - case 'd': - dPeriod = atoi(optarg); - break; - default: - usage(argv[0]); - break; - } - } - - ftExtraList *eList = new ftExtraList(); - - /* now startup background thread to keep it reunning */ - eList->start(); - - - - /* now work the thread */ - std::list toHash; - std::list hashed; - std::list::iterator it; - - TransferRequestFlags flags(0); - for(it = hashList.begin(); it != hashList.end(); it++) - { - sleep(period); - - /* load up file */ - //eList->addExtraFile(*it); - eList->hashExtraFile(*it, dPeriod, flags); - - toHash.push_back(*it); - - displayExtraListDetails(eList, toHash, hashed); - } - - for(int i=0;i<20;++i) - { - sleep(period); - - displayExtraListDetails(eList, toHash, hashed); - } - - FINALREPORT("Extra list test.") ; - return 0; -} - -void displayExtraListDetails(ftExtraList *eList, std::list toHash, std::list hashed) -{ - std::cerr << "displayExtraListDetails()"; - std::cerr << std::endl; - - std::list::iterator it; - for(it = toHash.begin(); it != toHash.end(); it++) - { - FileInfo info; - if (eList->hashExtraFileDone(*it, info)) - { - std::cerr << "displayExtraListDetails() Hash Completed for: " << *it; - std::cerr << std::endl; - std::cerr << info << std::endl; - } - else - { - std::cerr << "displayExtraListDetails() Hash Not Done for: " << *it; - std::cerr << std::endl; - } - } - - for(it = hashed.begin(); it != hashed.end(); it++) - { - FileInfo info; - if (eList->search(*it, FileSearchFlags(0), info)) - { - std::cerr << "displayExtraListDetails() Found Hash: " << *it; - std::cerr << std::endl; - std::cerr << info << std::endl; - } - else - { - std::cerr << "displayExtraListDetails() Hash Not Found: " << *it; - std::cerr << std::endl; - } - } -} - - - diff --git a/libretroshare/src/tests/ft/ftfilecreatortest.cc b/libretroshare/src/tests/ft/ftfilecreatortest.cc deleted file mode 100644 index ae03ded20..000000000 --- a/libretroshare/src/tests/ft/ftfilecreatortest.cc +++ /dev/null @@ -1,165 +0,0 @@ -#include "ft/ftfilecreator.h" - -#include "util/utest.h" -#include "common/testutils.h" -#include - -#include "util/rswin.h" -#include "util/rsdir.h" -#include "util/rsdiscspace.h" -#include "pqi/p3cfgmgr.h" -#include "ft/ftserver.h" -#include "turtle/p3turtle.h" - -INITTEST(); - -static int test_timeout(ftFileCreator *creator); -static int test_fill(ftFileCreator *creator); - -int main() -{ - RsDiscSpace::setDownloadPath("/tmp") ; - RsDiscSpace::setPartialsPath("/tmp") ; - - /* use ftcreator to create a file on tmp drive */ - std::string hash = TestUtils::createRandomFileHash() ; - uint64_t size = 12943090 ; - - ftFileCreator fcreator1("/tmp/rs-ftfc-test.dta",size,hash,true); - ftFileCreator fcreator2("/tmp/rs-ftfc-test.dta",size,hash,true); - - test_timeout(&fcreator1); - test_fill(&fcreator2); - - FINALREPORT("RsTlvItem Stack Tests"); - - return TESTRESULT(); -} - - -int test_timeout(ftFileCreator *creator) -{ - uint32_t chunk = 1000; - uint64_t offset = 0; - int max_timeout = 5; - int max_offset = chunk * max_timeout; - int i; - std::cerr << "60 second test of chunk queue."; - std::cerr << std::endl; - - uint32_t size_hint = 1000; - std::string peer_id = "dummyId"; - bool toOld = false; - - for(i = 0; i < max_timeout; i++) - { - creator->getMissingChunk(peer_id, size_hint, offset, chunk, toOld); - std::cerr << "Allocated Offset: " << offset << " chunk: " << chunk << std::endl; - - CHECK(offset <= max_offset); - // sleep(1); - } - - std::cerr << "Expect Repeats now"; - std::cerr << std::endl; - - for(i = 0; i < max_timeout; i++) - { - // sleep(1); - creator->getMissingChunk(peer_id, size_hint, offset, chunk, toOld); - std::cerr << "Allocated Offset: " << offset << " chunk: " << chunk << std::endl; - - CHECK(offset <= max_offset); - } - REPORT("Chunk Queue"); - - return 1; -} - - -int test_fill(ftFileCreator *creator) -{ - uint32_t chunk = 1000; - uint64_t offset = 0; - - uint64_t init_size = creator->getFileSize(); - uint64_t init_trans = creator->getRecvd(); - std::cerr << "Initial FileSize: " << init_size << std::endl; - std::cerr << "Initial Transferred:" << init_trans << std::endl; - - uint32_t size_hint = 1000; - std::string peer_id = TestUtils::createRandomSSLId(); - bool toOld = false; - std::cerr << "Allocating data size in memory for " << creator->fileSize() << " bytes." << std::endl; - unsigned char *total_file_data = new unsigned char[creator->fileSize()] ; - - while(creator->getMissingChunk(peer_id, size_hint, offset, chunk, toOld)) - { - if (chunk == 0) - { - std::cerr << "Missing Data already Alloced... wait"; - std::cerr << std::endl; - sleep(1); - chunk = 1000; - continue; - } - - /* give it to them */ - void *data = malloc(chunk); - /* fill with ascending numbers */ - for(int i = 0; i < chunk; i++) - { - ((uint8_t *) data)[i] = 'a' + i % 27; - if (i % 27 == 26) - { - ((uint8_t *) data)[i] = '\n'; - } - } - memcpy(total_file_data+offset,data,chunk) ; - - //std::cerr << " adding file data at offset " << offset << ", size = " << chunk << std::endl; - - creator->addFileData(offset, chunk, data); - free(data); -//#ifndef WINDOWS_SYS -///********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -// usleep(250000); /* 1/4 of sec */ -//#else -///********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -// Sleep(250); /* 1/4 of sec */ -//#endif -///********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - chunk = 1000; /* reset chunk size */ - - } - // validate all chunks - - std::vector chunks_to_check ; - creator->getChunksToCheck(chunks_to_check) ; - - std::cerr << "Validating " << chunks_to_check.size() << " chunks." << std::endl; - - uint32_t CHUNKMAP_SIZE = 1024*1024 ; - - for(uint32_t i=0;ifileSize() - chunks_to_check[i]*CHUNKMAP_SIZE)) ; - Sha1CheckSum crc = RsDirUtil::sha1sum(total_file_data+chunks_to_check[i]*CHUNKMAP_SIZE,chunk_size) ; - std::cerr << " Checking crc for chunk " << chunks_to_check[i] << " of size " << chunk_size << ". Reference is " << crc.toStdString() << std::endl; - creator->verifyChunk(chunks_to_check[i],crc) ; - } - delete[] total_file_data ; - - uint64_t end_size = creator->getFileSize(); - uint64_t end_trans = creator->getRecvd(); - std::cerr << "End FileSize: " << end_size << std::endl; - std::cerr << "End Transferred:" << end_trans << std::endl; - CHECK(init_size == end_size); - CHECK(end_trans == end_size); - - REPORT("Test Fill"); - - return 1; -} - diff --git a/libretroshare/src/tests/ft/ftfilemappertest.cc b/libretroshare/src/tests/ft/ftfilemappertest.cc deleted file mode 100644 index 69c97a3c4..000000000 --- a/libretroshare/src/tests/ft/ftfilemappertest.cc +++ /dev/null @@ -1,91 +0,0 @@ -#include "ft/ftfilemapper.h" -#include "ft/ftchunkmap.h" -#include "retroshare/rstypes.h" - -#include -#include -#include -#include -#include - -INITTEST(); - -int main() -{ - /* Use ftfilemapper to create a file with chunks downloaded on a random direction. */ - - static const std::string tmpdir = "." ; - static const std::string input_file = tmpdir+"/"+"input.bin" ; - static const std::string output_file = tmpdir+"/"+"output.bin" ; - static const uint64_t size = 1024*1024*12+234;//4357283 ; // some size. Not an integer number of chunks - static const uint32_t chunk_size = 1024*1024 ; // 1MB - - pid_t pid = getpid() ; - srand48(pid) ; - srand(pid) ; - std::cerr << "Inited random number generator with seed " << pid << std::endl; - - // 0 - create a random file in memory, of size SIZE - - void *membuf = malloc(size) ; - CHECK(membuf != NULL) ; - - for(int i=0;i - -#include "util/rswin.h" - -INITTEST() - -int main() -{ - std::string ownId = TestUtils::createRandomSSLId() ; - - RsDiscSpace::setPartialsPath("/tmp") ; - RsDiscSpace::setDownloadPath("/tmp") ; - - /* create a random file */ - uint64_t size = 10000000; - uint32_t max_chunk = 10000; - uint32_t chunk = 1000; - uint64_t offset = 0; - - std::string filename = "/tmp/ft_test.dta"; - std::string filename2 = "/tmp/ft_test.dta.dup"; - - std::string hash = TestUtils::createRandomFileHash() ; - - /* use creator to make it */ - - TestUtils::createRandomFile(filename,size) ; - - std::cerr << "Created file: " << filename << " of size: " << size; - std::cerr << std::endl; - - /* load it with file provider */ - ftFileCreator *creator = new ftFileCreator(filename2, size, hash, true); - ftFileProvider *provider = new ftFileProvider(filename, size, hash); - - /* create duplicate with file creator */ - std::string peer_id = TestUtils::createRandomSSLId() ; - uint32_t size_hint = 10000; - bool toOld = false; - unsigned char *data = new unsigned char[max_chunk]; - - while(creator->getMissingChunk(peer_id, size_hint, offset, chunk, toOld)) - { - if (chunk == 0) - { - std::cerr << "All currently allocated .... waiting"; - std::cerr << std::endl; - sleep(1); - /* reset chunk size */ - chunk = (uint64_t) max_chunk * (rand() / (1.0 + RAND_MAX)); - std::cerr << "ChunkSize = " << chunk << std::endl; - continue; - } - - if (!provider->getFileData(ownId,offset, chunk, data)) - { - FAILED("Read from Test Data File"); - std::cerr << "Failed to get data"; - std::cerr << std::endl; - } - - if (!creator->addFileData(offset, chunk, data)) - { - FAILED("Write to Duplicate"); - std::cerr << "Failed to add data"; - std::cerr << std::endl; - } - - std::cerr << "Transferred: " << chunk << " @ " << offset; - std::cerr << std::endl; - - - /* reset chunk size */ - chunk = (uint64_t) max_chunk * (rand() / (1.0 + RAND_MAX)); - - std::cerr << "ChunkSize = " << chunk << std::endl; - } - std::string path,hash2 ; - - RsDirUtil::hashFile(filename ,path,hash,size) ; - RsDirUtil::hashFile(filename2,path,hash2,size) ; - - std::cerr << "Checking hash1 : " << hash << std::endl; - std::cerr << "Checking hash2 : " << hash2 << std::endl; - - CHECK(hash == hash2) ; - - FINALREPORT("ftfilecreatortest") ; - - return TESTRESULT(); -} - diff --git a/libretroshare/src/tests/ft/ftsearch_dummy.cc b/libretroshare/src/tests/ft/ftsearch_dummy.cc deleted file mode 100644 index 72b59d471..000000000 --- a/libretroshare/src/tests/ft/ftsearch_dummy.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "ftsearch_dummy.h" - -bool ftSearchDummy::search(const std::string& /*hash*/, FileSearchFlags hintflags, FileInfo &/*info*/) const -{ - /* remove unused parameter warnings */ - (void) hintflags; - -#ifdef DEBUG_SEARCH - std::cerr << "ftSearchDummy::search(" << hash ; - std::cerr << ", " << hintflags << ");"; - std::cerr << std::endl; -#endif - return false; -} - - diff --git a/libretroshare/src/tests/ft/ftsearch_dummy.h b/libretroshare/src/tests/ft/ftsearch_dummy.h deleted file mode 100644 index 9a5ffcdff..000000000 --- a/libretroshare/src/tests/ft/ftsearch_dummy.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * libretroshare/src/ft: ftsearch.h - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#pragma once - -#include "ft/ftsearch.h" - -class ftSearchDummy: public ftSearch -{ - public: - - ftSearchDummy() { return; } -virtual ~ftSearchDummy() { return; } -virtual bool search(const std::string& hash, FileSearchFlags hintflags, FileInfo &info) const; -}; - diff --git a/libretroshare/src/tests/ft/ftserver1test.cc b/libretroshare/src/tests/ft/ftserver1test.cc deleted file mode 100644 index d8722eb9c..000000000 --- a/libretroshare/src/tests/ft/ftserver1test.cc +++ /dev/null @@ -1,351 +0,0 @@ -/* - * libretroshare/src/ft: ftserver1test.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * Test for Whole Basic system..... - * - * Put it all together, and make it compile. - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "ft/ftserver.h" - -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -#include "pqi/p3linkmgr.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - -#include "util/rsdebug.h" -#include "util/utest.h" -#include "common/testutils.h" -#include "retroshare/rsiface.h" - -#include "pqitestor.h" -#include "util/rsdir.h" - -#include - - -INITTEST(); - -void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-p ] [-d ] [ ... ] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t debugLevel = 5; - bool debugStderr = true; - - std::list fileList; - std::list peerIds; - std::map mFtServers; - std::map mLinkMgrs; - -#ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); -#endif - -#ifdef WIN32 - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif - - - while(-1 != (c = getopt(argc, argv, "d:p:s"))) - { - switch (c) - { - case 'p': - peerIds.push_back(optarg); - break; - case 'd': - debugLevel = atoi(optarg); - break; - case 's': - debugStderr = true; - break; - default: - usage(argv[0]); - break; - } - } - - /* do logging */ - setOutputLevel(debugLevel); - - if (optind >= argc) - { - std::cerr << "Missing Files" << std::endl; - usage(argv[0]); - } - std::cerr << "Point 1" << std::endl; - - for(; optind < argc; optind++) - { - std::cerr << "Adding: " << argv[optind] << std::endl; - - SharedDirInfo info ; - info.filename = std::string(argv[optind]) ; - info.virtualname = info.filename ; - info.shareflags = DIR_FLAGS_PERMISSIONS_MASK ; - info.parent_groups.clear() ; - - fileList.push_back(info); - } - std::cerr << "Point 2" << std::endl; - - std::string ssl_own_id = TestUtils::createRandomSSLId() ; - std::string gpg_own_id = TestUtils::createRandomPGPId() ; - - TestUtils::DummyAuthGPG fakeGPG(gpg_own_id) ; - AuthGPG::setAuthGPG_debug(&fakeGPG) ; - - TestUtils::DummyAuthSSL fakeSSL(ssl_own_id) ; - AuthSSL::setAuthSSL_debug(&fakeSSL) ; - - /* We need to setup a series 2 - 4 different ftServers.... - * - * Each one needs: - * - * - * A List of peerIds... - */ - - std::list::const_iterator it, jit; - - std::list baseFriendList, friendList; - std::list::iterator fit; - - P3Hub *testHub = new P3Hub(0,NULL); - testHub->start(); - - /* Setup Base Friend Info */ - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - RsPeerDetails pad; - pad.id = *it; - pad.gpg_id = TestUtils::createRandomPGPId() ; - pad.name = *it; - pad.trustLvl = 5; - pad.ownsign = true; - //pad.trusted = false; - - baseFriendList.push_back(pad); - - std::cerr << "ftserver1test::setup peer: " << *it << std::endl; - } - - std::ostringstream pname; - pname << "/tmp/rstst-" << time(NULL); - - std::string basepath = pname.str(); - RsDirUtil::checkCreateDirectory(basepath); - - - - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - friendList = baseFriendList; - /* remove current one */ - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - if (fit->id == *it) - { - friendList.erase(fit); - break; - } - } - - //p3AuthMgr *authMgr = new p3DummyAuthMgr(*it, friendList); - p3PeerMgrIMPL *peerMgr = new p3PeerMgrIMPL(ssl_own_id,gpg_own_id,"My GPG name","My SSL location"); - - p3NetMgrIMPL *netMgr = new p3NetMgrIMPL ; - p3LinkMgrIMPL *linkMgr = new p3LinkMgrIMPL(peerMgr,netMgr); - mLinkMgrs[*it] = linkMgr; - - rsPeers = new TestUtils::DummyRsPeers(linkMgr,peerMgr,netMgr) ; - - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - /* add as peer to authMgr */ - peerMgr->addFriend(fit->id,fit->gpg_id); - } - - P3Pipe *pipe = new P3Pipe(); //(*it); - - /* add server */ - ftServer *server; - server = new ftServer(peerMgr,linkMgr); - mFtServers[*it] = server; - - server->setP3Interface(pipe); - - std::string configpath = basepath + "/" + *it; - RsDirUtil::checkCreateDirectory(configpath); - - std::string cachepath = configpath + "/cache"; - RsDirUtil::checkCreateDirectory(cachepath); - - std::string partialspath = configpath + "/partials"; - RsDirUtil::checkCreateDirectory(partialspath); - - std::string downloadpath = configpath + "/downloads"; - RsDirUtil::checkCreateDirectory(downloadpath); - - std::string localpath = cachepath + "/local"; - RsDirUtil::checkCreateDirectory(localpath); - - std::string remotepath = cachepath + "/remote"; - RsDirUtil::checkCreateDirectory(remotepath); - - server->setConfigDirectory(configpath); - - //sleep(60); - - NotifyBase *base = new NotifyBase; - server->SetupFtServer(base); - - testHub->addP3Pipe(*it, pipe, linkMgr); - server->StartupThreads(); - - /* setup any extra bits */ - server->setPartialsDirectory(partialspath); - server->setDownloadDirectory(downloadpath); - server->setSharedDirectories(fileList); - } - - /* stick your real test here */ - std::map::iterator sit; - std::map::iterator cit; - - for(int i=0;i < 20;++i) - { - std::cerr << "ftserver1test::sleep()"; - std::cerr << std::endl; - sleep(1); - - /* tick the connmgrs */ - for(sit = mFtServers.begin(); sit != mFtServers.end(); sit++) - { - /* update */ - (sit->second)->tick(); - } - - for(cit = mLinkMgrs.begin(); cit != mLinkMgrs.end(); cit++) - { - /* update */ - (cit->second)->tick(); - } - } - - FINALREPORT("FtServer running.") ; -} - - -#if 0 - -uint32_t do_random_server_iteration(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files) -{ - std::cerr << "do_random_server_iteration()"; - std::cerr << std::endl; - - std::list::iterator it; - uint32_t i = 0; - for(it = files.begin(); it != files.end(); it++) - { - FileInfo info; - if (eList->hashExtraFileDone(*it, info)) - { - std::cerr << "Hash Done for: " << *it; - std::cerr << std::endl; - std::cerr << info << std::endl; - - std::cerr << "Requesting Data Packet"; - std::cerr << std::endl; - - /* Server Recv */ - uint64_t offset = 10000; - uint32_t chunk = 20000; - mplex->recvDataRequest("Peer", info.hash, info.size, offset, chunk); - - i++; - } - else - { - std::cerr << "do_random_server_iteration() Hash Not Done for: " << *it; - std::cerr << std::endl; - } - } - - return i; - -} - - -void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files) -{ - std::cerr << "do_random_server_test()"; - std::cerr << std::endl; - - uint32_t size = files.size(); - while(size > do_random_server_iteration(mplex, eList, files)) - { - std::cerr << "do_random_server_test() sleep"; - std::cerr << std::endl; - - sleep(10); - } -} - - -#endif - diff --git a/libretroshare/src/tests/ft/ftserver1test.sh b/libretroshare/src/tests/ft/ftserver1test.sh deleted file mode 100755 index 379ecc7fa..000000000 --- a/libretroshare/src/tests/ft/ftserver1test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -./ftserver1test -p 8cb3a1677872c9e8248fd5ddeac84000 -p 8cb3a1677872c9e8248fd5ddeac84001 -p 8cb3a1677872c9e8248fd5ddeac84002 . diff --git a/libretroshare/src/tests/ft/ftserver2test.cc b/libretroshare/src/tests/ft/ftserver2test.cc deleted file mode 100644 index 84f4c9937..000000000 --- a/libretroshare/src/tests/ft/ftserver2test.cc +++ /dev/null @@ -1,444 +0,0 @@ -/* - * libretroshare/src/ft: ftserver1test.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * Test for Whole Basic system..... - * - * Put it all together, and make it compile. - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "ft/ftserver.h" - -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -#include "pqi/p3linkmgr.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - -#include "util/rsdebug.h" -#include "util/utest.h" -#include "common/testutils.h" -#include "retroshare/rsiface.h" - -#include "pqitestor.h" -#include "util/rsdir.h" -#include "util/utest.h" - - -#include - - -class TestData -{ - public: - - ftServer *loadServer; - std::list otherServers; - std::list extraList; -}; - - -extern "C" void *do_server_test_thread(void *p); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-sa] [-p ] [-d ] [-e ] [ [ ... ]] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t debugLevel = 5; - bool debugStderr = true; - bool loadAll = false; - - std::list fileList; - std::list extraList; - std::list peerIds; - std::map mFtServers; - std::map mLinkMgrs; - - ftServer *mLoadServer = NULL; - std::list mOtherServers; - std::list::iterator eit; - -#ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); -#endif - -#ifdef WIN32 - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif - - - while(-1 != (c = getopt(argc, argv, "asd:p:e:"))) - { - switch (c) - { - case 'p': - peerIds.push_back(optarg); - break; - case 'd': - debugLevel = atoi(optarg); - break; - case 's': - debugStderr = true; - break; - case 'e': - extraList.push_back(optarg); - break; - case 'a': - loadAll = true; - break; - default: - usage(argv[0]); - break; - } - } - - /* do logging */ - setOutputLevel(debugLevel); - - if (optind >= argc) - { - std::cerr << "Missing Shared Directories" << std::endl; - usage(argv[0]); - } - - for(; optind < argc; optind++) - { - std::cerr << "Adding: " << argv[optind] << std::endl; - SharedDirInfo info ; - info.shareflags = DIR_FLAGS_PERMISSIONS_MASK; - info.filename = std::string(argv[optind]); - info.virtualname = std::string(argv[optind]); - fileList.push_back(info) ; - } - std::cerr << "Point 2" << std::endl; - - std::string ssl_own_id = TestUtils::createRandomSSLId() ; - std::string gpg_own_id = TestUtils::createRandomPGPId() ; - - TestUtils::DummyAuthGPG fakeGPG(gpg_own_id) ; - AuthGPG::setAuthGPG_debug(&fakeGPG) ; - - TestUtils::DummyAuthSSL fakeSSL(ssl_own_id) ; - AuthSSL::setAuthSSL_debug(&fakeSSL) ; - - /* We need to setup a series 2 - 4 different ftServers.... - * - * Each one needs: - * - * - * A List of peerIds... - */ - - std::list::const_iterator it, jit; - - std::list baseFriendList, friendList; - std::list::iterator fit; - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - rss->addSerialType(new RsCacheItemSerialiser()); - rss->addSerialType(new RsServiceSerialiser()); - - - P3Hub *testHub = new P3Hub(0, rss); - testHub->start(); - - /* Setup Base Friend Info */ - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - RsPeerDetails pad; - pad.id = *it; - pad.gpg_id = TestUtils::createRandomPGPId() ; - pad.name = *it; - pad.trustLvl = 5; - pad.ownsign = true; - //pad.trusted = false; - - baseFriendList.push_back(pad); - - std::cerr << "ftserver1test::setup peer: " << *it << std::endl; - } - - std::ostringstream pname; - pname << "/tmp/rstst-" << time(NULL); - - std::string basepath = pname.str(); - RsDirUtil::checkCreateDirectory(basepath); - - - - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - friendList = baseFriendList; - /* remove current one */ - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - if (fit->id == *it) - { - friendList.erase(fit); - break; - } - } - - //p3AuthMgr *authMgr = new p3DummyAuthMgr(*it, friendList); - p3PeerMgrIMPL *peerMgr = new p3PeerMgrIMPL(ssl_own_id,gpg_own_id,"My GPG name","My SSL location"); - - p3NetMgrIMPL *netMgr = new p3NetMgrIMPL ; - p3LinkMgrIMPL *linkMgr = new p3LinkMgrIMPL(peerMgr,netMgr); - mLinkMgrs[*it] = linkMgr; - - //rsPeers = new TestUtils::DummyRsPeers(linkMgr,peerMgr,netMgr) ; - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - /* add as peer to authMgr */ - peerMgr->addFriend(fit->id,fit->gpg_id); - linkMgr->addFriend(fit->id,true); - } - - P3Pipe *pipe = new P3Pipe(); //(*it); - - /* add server */ - ftServer *server; - server = new ftServer(peerMgr,linkMgr); - mFtServers[*it] = server; - if (!mLoadServer) - { - mLoadServer = server; - } - else - { - mOtherServers.push_back(server); - } - - server->setP3Interface(pipe); - - std::string configpath = basepath + "/" + *it; - RsDirUtil::checkCreateDirectory(configpath); - - std::string cachepath = configpath + "/cache"; - RsDirUtil::checkCreateDirectory(cachepath); - - std::string partialspath = configpath + "/partials"; - RsDirUtil::checkCreateDirectory(partialspath); - - std::string downloadpath = configpath + "/downloads"; - RsDirUtil::checkCreateDirectory(downloadpath); - - std::string localpath = cachepath + "/local"; - RsDirUtil::checkCreateDirectory(localpath); - - std::string remotepath = cachepath + "/remote"; - RsDirUtil::checkCreateDirectory(remotepath); - - server->setConfigDirectory(configpath); - - //sleep(60); - - NotifyBase *base = new NotifyBase; - server->SetupFtServer(base); - - testHub->addP3Pipe(*it, pipe, linkMgr); - server->StartupThreads(); - - /* setup any extra bits */ - /* everyone gets download directories */ - server->setPartialsDirectory(partialspath); - server->setDownloadDirectory(downloadpath); - - if (loadAll) - { - server->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - server->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - } - - if (mLoadServer) - { - mLoadServer->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - mLoadServer->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - /* stick your real test here */ - std::map::iterator sit; - std::map::iterator cit; - - /* Start up test thread */ - pthread_t tid; - TestData *mFt = new TestData; - - /* set data */ - mFt->loadServer = mLoadServer; - mFt->otherServers = mOtherServers; - mFt->extraList = extraList; - - void *data = (void *) mFt; - pthread_create(&tid, 0, &do_server_test_thread, data); - pthread_detach(tid); /* so memory is reclaimed in linux */ - - while(1) - { - std::cerr << "ftserver2test::sleep()"; - std::cerr << std::endl; - sleep(1); - - /* tick the connmgrs */ - for(sit = mFtServers.begin(); sit != mFtServers.end(); sit++) - { - /* update */ - (sit->second)->tick(); - } - - for(cit = mLinkMgrs.begin(); cit != mLinkMgrs.end(); cit++) - { - /* update */ - (cit->second)->tick(); - } - } -} - -/* So our actual test can run here..... - * - */ - -INITTEST(); - -void *do_server_test_thread(void *data) -{ - TestData *mFt = (TestData *) data; - - std::cerr << "do_server_test_thread() running"; - std::cerr << std::endl; - - /************************* TEST 1 ********************** - * Check that the extra List has been processed. - */ - rstime_t start = time(NULL); - - FileInfo info, info2; - rstime_t now = time(NULL); - std::list::iterator eit; - for(eit = mFt->extraList.begin(); eit != mFt->extraList.end(); eit++) - { - while(!mFt->loadServer->ExtraFileStatus(*eit, info)) - { - - /* max of 30 seconds */ - now = time(NULL); - if (now - start > 30) - { - /* FAIL */ - REPORT2( false, "Extra File Hashing"); - } - - sleep(1); - } - - /* Got ExtraFileStatus */ - REPORT("Successfully Found ExtraFile"); - - /* now we can try a search (should succeed) */ - FileSearchFlags hintflags = RS_FILE_HINTS_EXTRA; - - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - CHECK(info2.hash == info.hash); - CHECK(info2.size == info.size); - CHECK(info2.fname == info.fname); - } - else - { - REPORT2( false, "Search for Extra File (Basic)"); - } - - /* search with flags (should succeed) */ - hintflags = RS_FILE_HINTS_EXTRA; - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - CHECK(info2.hash == info.hash); - CHECK(info2.size == info.size); - CHECK(info2.fname == info.fname); - } - else - { - REPORT2( false, "Search for Extra File (Extra Flag)"); - } - - /* search with other flags (should fail) */ - hintflags = RS_FILE_HINTS_REMOTE | RS_FILE_HINTS_SPEC_ONLY; - if (mFt->loadServer->FileDetails(info.hash, hintflags, info2)) - { - REPORT2( false, "Search for Extra File (Fail Flags)"); - } - else - { - REPORT("Search for Extra File (Fail Flags)"); - } - - /* if we try to download it ... should just find existing one*/ - - REPORT("Testing with Extra File"); - } - - FINALREPORT("ExtraList Hashing, Searching and Downloading"); - exit(1); -} - - - - diff --git a/libretroshare/src/tests/ft/ftserver2test.sh b/libretroshare/src/tests/ft/ftserver2test.sh deleted file mode 100755 index fce1f4fa6..000000000 --- a/libretroshare/src/tests/ft/ftserver2test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -./ftserver2test -p 8cb3a1677872c9e8248fd5ddeac84000 -p 8cb3a1677872c9e8248fd5ddeac84001 -p 8cb3a1677872c9e8248fd5ddeac84002 . -e ftserver1test ftcontrollertest diff --git a/libretroshare/src/tests/ft/ftserver3test.cc b/libretroshare/src/tests/ft/ftserver3test.cc deleted file mode 100644 index e887eee6b..000000000 --- a/libretroshare/src/tests/ft/ftserver3test.cc +++ /dev/null @@ -1,491 +0,0 @@ -/* - * libretroshare/src/ft: ftserver3test.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * ftServer3Test - Test of the file transfer from a server level. - * Steps: - * 1) load shared directories into others, and let them be - transferred between clients. - * 2) search for local item on others. - * 3) request item on load server. - should transfer from all others simultaneously. - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include -#include "retroshare/rsexpr.h" -#include "retroshare/rstypes.h" -#include "retroshare/rsfiles.h" - -#include "ft/ftserver.h" - -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -#include "pqi/p3linkmgr.h" -#include "pqi/p3peermgr.h" -#include "pqi/p3netmgr.h" - -#include "util/rsdebug.h" -#include "util/utest.h" -#include "common/testutils.h" -#include "retroshare/rsiface.h" - -#include "pqitestor.h" -#include "util/rsdir.h" -#include "util/utest.h" - - -#include - - -class TestData -{ - public: - - ftServer *loadServer; - std::list otherServers; - std::list extraList; -}; - - -extern "C" void *do_server_test_thread(void *p); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-soa] [-p ] [-d ] [-e ] [ [ ... ]] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t debugLevel = 5; - bool debugStderr = true; - bool loadAll = false; - bool loadOthers = false; - - std::list fileList; - std::list extraList; - std::list peerIds; - std::map mFtServers; - std::map mLinkMgrs; - - ftServer *mLoadServer = NULL; - std::list mOtherServers; - std::list::iterator eit; - -#ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); -#endif - -#ifdef WIN32 - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif - - - while(-1 != (c = getopt(argc, argv, "aosd:p:e:"))) - { - switch (c) - { - case 'p': - peerIds.push_back(optarg); - break; - case 'd': - debugLevel = atoi(optarg); - break; - case 's': - debugStderr = true; - break; - case 'e': - extraList.push_back(optarg); - break; - case 'a': - loadAll = true; - break; - case 'o': - loadOthers = true; - break; - default: - usage(argv[0]); - break; - } - } - - /* do logging */ - setOutputLevel(debugLevel); - - if (optind >= argc) - { - std::cerr << "Missing Shared Directories" << std::endl; - usage(argv[0]); - } - - for(; optind < argc; optind++) - { - std::cerr << "Adding: " << argv[optind] << std::endl; - - SharedDirInfo info ; - info.filename = std::string(argv[optind]); - info.virtualname = info.filename ; - info.shareflags = DIR_FLAGS_PERMISSIONS_MASK; - - fileList.push_back(info) ; - } - std::cerr << "Point 2" << std::endl; - - std::string ssl_own_id = TestUtils::createRandomSSLId() ; - std::string gpg_own_id = TestUtils::createRandomPGPId() ; - - TestUtils::DummyAuthGPG fakeGPG(gpg_own_id) ; - AuthGPG::setAuthGPG_debug(&fakeGPG) ; - - TestUtils::DummyAuthSSL fakeSSL(ssl_own_id) ; - AuthSSL::setAuthSSL_debug(&fakeSSL) ; - - /* We need to setup a series 2 - 4 different ftServers.... - * - * Each one needs: - * - * - * A List of peerIds... - */ - - std::list::const_iterator it, jit; - - std::list baseFriendList, friendList; - std::list::iterator fit; - - /* Add in Serialiser Test - */ - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - rss->addSerialType(new RsCacheItemSerialiser()); - rss->addSerialType(new RsServiceSerialiser()); - - P3Hub *testHub = new P3Hub(0, rss); - testHub->start(); - - /* Setup Base Friend Info */ - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - RsPeerDetails pad; - pad.id = *it; - pad.gpg_id = TestUtils::createRandomPGPId() ; - pad.name = *it; - pad.trustLvl = 5; - pad.ownsign = true; - //pad.trusted = false; - - baseFriendList.push_back(pad); - - std::cerr << "ftserver1test::setup peer: " << *it << std::endl; - } - - std::ostringstream pname; - pname << "/tmp/rstst-" << time(NULL); - - std::string basepath = pname.str(); - RsDirUtil::checkCreateDirectory(basepath); - - - - for(it = peerIds.begin(); it != peerIds.end(); it++) - { - friendList = baseFriendList; - /* remove current one */ - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - if (fit->id == *it) - { - friendList.erase(fit); - break; - } - } - - //p3AuthMgr *authMgr = new p3DummyAuthMgr(*it, friendList); - p3PeerMgrIMPL *peerMgr = new p3PeerMgrIMPL(ssl_own_id,gpg_own_id,"My GPG name","My SSL location"); - - p3NetMgrIMPL *netMgr = new p3NetMgrIMPL ; - p3LinkMgrIMPL *linkMgr = new p3LinkMgrIMPL(peerMgr,netMgr); - mLinkMgrs[*it] = linkMgr; - - rsPeers = new TestUtils::DummyRsPeers(linkMgr,peerMgr,netMgr) ; - - for(fit = friendList.begin(); fit != friendList.end(); fit++) - { - /* add as peer to authMgr */ - peerMgr->addFriend(fit->id,fit->gpg_id); - } - - P3Pipe *pipe = new P3Pipe(); //(*it); - - /* add server */ - ftServer *server; - server = new ftServer(peerMgr,linkMgr); - mFtServers[*it] = server; - bool isOther; - if (!mLoadServer) - { - mLoadServer = server; - isOther = false; - } - else - { - mOtherServers.push_back(server); - isOther = true; - } - - - server->setP3Interface(pipe); - - std::string configpath = basepath + "/" + *it; - RsDirUtil::checkCreateDirectory(configpath); - - std::string cachepath = configpath + "/cache"; - RsDirUtil::checkCreateDirectory(cachepath); - - std::string partialspath = configpath + "/partials"; - RsDirUtil::checkCreateDirectory(partialspath); - - std::string downloadpath = configpath + "/downloads"; - RsDirUtil::checkCreateDirectory(downloadpath); - - std::string localpath = cachepath + "/local"; - RsDirUtil::checkCreateDirectory(localpath); - - std::string remotepath = cachepath + "/remote"; - RsDirUtil::checkCreateDirectory(remotepath); - - server->setConfigDirectory(configpath); - - //sleep(60); - - NotifyBase *base = new NotifyBase; - server->SetupFtServer(base); - - testHub->addP3Pipe(*it, pipe, linkMgr); - server->StartupThreads(); - - /* setup any extra bits */ - server->setPartialsDirectory(partialspath); - server->setDownloadDirectory(downloadpath); - - if ((loadAll) || (isOther && loadOthers)) - { - server->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - server->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - } - - if ((mLoadServer) && (!loadOthers)) - { - mLoadServer->setSharedDirectories(fileList); - for(eit = extraList.begin(); eit != extraList.end(); eit++) - { - mLoadServer->ExtraFileHash(*eit, 3600, TransferRequestFlags(0)); - } - } - - - /* stick your real test here */ - std::map::iterator sit; - std::map::iterator cit; - - /* Start up test thread */ - pthread_t tid; - TestData *mFt = new TestData; - - /* set data */ - mFt->loadServer = mLoadServer; - mFt->otherServers = mOtherServers; - mFt->extraList = extraList; - - void *data = (void *) mFt; - pthread_create(&tid, 0, &do_server_test_thread, data); - pthread_detach(tid); /* so memory is reclaimed in linux */ - - while(1) - { - //std::cerr << "ftserver3test::sleep()"; - //std::cerr << std::endl; - sleep(1); - - /* tick the connmgrs */ - for(sit = mFtServers.begin(); sit != mFtServers.end(); sit++) - { - /* update */ - (sit->second)->tick(); - } - - for(cit = mLinkMgrs.begin(); cit != mLinkMgrs.end(); cit++) - { - /* update */ - (cit->second)->tick(); - } - } -} - -/* So our actual test can run here..... - * - */ - -INITTEST(); - -void *do_server_test_thread(void *data) -{ - TestData *mFt = (TestData *) data; - rstime_t startTS = time(NULL); - - std::cerr << "do_server_test_thread() running"; - std::cerr << std::endl; - - /* search Others for a suitable file - * (Tests GUI search functionality) - */ - if (mFt->otherServers.size() < 1) - { - std::cerr << "no Other Servers to search on"; - std::cerr << std::endl; - exit(1); - return NULL; - } - - - for(int i = 0; i < 90; i++) - { - int age = time(NULL) - startTS; - std::cerr << "Waited " << age << " seconds to share caches"; - std::cerr << std::endl; - sleep(1); - } - - ftServer *oServer = *(mFt->otherServers.begin()); - std::string oId = oServer->OwnId(); - - /* create Expression */ - uint64_t minFileSize = 1000; - SizeExpression se(Greater, minFileSize); - //SizeExpression se(Smaller, minFileSize); - Expression *expr = &se; - - std::list results; - std::list::iterator it; - - oServer->SearchBoolExp(expr, results, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_BROWSABLE); - - if (results.size() < 1) - { - std::cerr << "no Shared Files > " << minFileSize; - std::cerr << std::endl; - exit(1); - return NULL; - } - - /* find the first remote entry */ - DirDetails sFile; - bool foundFile = false; - for(it = results.begin(); (it != results.end()); it++) - { - std::cerr << "Shared File: " << it->name; - std::cerr << std::endl; - - if (!foundFile) - { - if (it->id != mFt->loadServer->OwnId()) - { - std::cerr << "Selected: " << it->name; - std::cerr << std::endl; - foundFile = true; - sFile = *it; - } - else - { - std::cerr << "LoadId: "; - std::cerr << mFt->loadServer->OwnId(); - std::cerr << "FileId: "; - std::cerr << it->id; - std::cerr << std::endl; - } - } - } - - if (!foundFile) - { - std::cerr << "Not Found Suitable File"; - std::cerr << std::endl; - } - - - /*** Now Download it! ***/ - std::list srcIds; - //srcIds.push_back(sFile.id); - // Don't add srcId - to test whether the search works - or not - //srcIds.push_back(oId); - if (foundFile) - { - mFt->loadServer->FileRequest(sFile.name, sFile.hash, sFile.count, "", TransferRequestFlags(0), srcIds); - } - - /* Give it a while to transfer */ - for(int i = 0; i < 100; i++) - { - int age = time(NULL) - startTS; - std::cerr << "Waited " << age << " seconds for tranfer"; - std::cerr << std::endl; - sleep(1); - } - - FINALREPORT("Shared Directories, Bool Search, multi-source transfers"); - exit(1); -} - - - - diff --git a/libretroshare/src/tests/ft/ftserver3test.sh b/libretroshare/src/tests/ft/ftserver3test.sh deleted file mode 100644 index 80ffb1166..000000000 --- a/libretroshare/src/tests/ft/ftserver3test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./ftserver3test -p 8cb3a1677872c9e8248fd5ddeac84000 -p 8cb3a1677872c9e8248fd5ddeac84001 -p 8cb3a1677872c9e8248fd5ddeac84002 . ftserver3test diff --git a/libretroshare/src/tests/ft/fttransfermoduletest.cc b/libretroshare/src/tests/ft/fttransfermoduletest.cc deleted file mode 100644 index f98d47a93..000000000 --- a/libretroshare/src/tests/ft/fttransfermoduletest.cc +++ /dev/null @@ -1,182 +0,0 @@ -/* - * libretroshare/src/ft: fttransfermoduletest.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * Test for Multiplexor..... - * As this is a key middle component, it is hard to test without other bits. - * It relies on ftFileProvider/ftFileCreator/ftTransferModule... - * - * And has dummy ftDataSend and ftSearch. - * - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "ft/ftextralist.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftfilesearch.h" - -#include "ft/ftfileprovider.h" -#include "ft/ftfilecreator.h" -#include "ft/ftcontroller.h" -#include "ft/fttransfermodule.h" - -#include "util/utest.h" -#include "ftdata_dummy.h" -#include "ftsearch_dummy.h" - -INITTEST() - - -void do_random_server_test(ftDataMultiplex *mplex, ftExtraList *eList, std::list &files); - - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-p ] [-d ] [ ... ] "; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint32_t period = 1; - uint32_t dPeriod = 600; /* default 10 minutes */ - - std::list fileList; - - while(-1 != (c = getopt(argc, argv, "d:p:"))) - { - switch (c) - { - case 'p': - period = atoi(optarg); - break; - case 'd': - dPeriod = atoi(optarg); - break; - default: - usage(argv[0]); - break; - } - } - - if (optind >= argc) - { - std::cerr << "Missing Files" << std::endl; - usage(argv[0]); - } - - for(; optind < argc; optind++) - { - std::cerr << "Adding: " << argv[optind] << std::endl; - fileList.push_back(std::string(argv[optind])); - } - - ftExtraList *eList = new ftExtraList(); - eList->start(); - - ftSearch *ftsd = new ftSearchDummy(); - ftFileSearch *ftfs = new ftFileSearch(); - - ftfs-> addSearchMode(ftsd, RS_FILE_HINTS_LOCAL); - ftfs-> addSearchMode(eList, RS_FILE_HINTS_EXTRA); - - ftDataSendPair *ftds1 = new ftDataSendPair(NULL); - ftDataSendPair *ftds2 = new ftDataSendPair(NULL); - - /* setup Actual Test bit */ - ftDataMultiplex *ftmplex1 = new ftDataMultiplex("ownId", ftds2, ftfs); - ftDataMultiplex *ftmplex2 = new ftDataMultiplex("ownId", ftds1, ftfs); - - ftds1->mDataRecv = ftmplex1; - ftds2->mDataRecv = ftmplex2; - - ftmplex1->start(); - ftmplex2->start(); - - /* Setup Search with some valid results */ - /* Request Data */ - - /* now work the thread */ - std::list::iterator it; - TransferRequestFlags flags(0); - for(it = fileList.begin(); it != fileList.end(); it++) - { - eList->hashExtraFile(*it, dPeriod, flags); - } - - if (fileList.size() < 1) - { - std::cerr << "come on, give us some files..."; - std::cerr << std::endl; - return 0; - } - - /* now request files from ftDataMultiplex - * by adding in a ftTransferModule! - */ - std::string filename = *(fileList.begin()); - - /* wait for file to hash */ - FileInfo info; - while(!eList->hashExtraFileDone(filename, info)) - { - std::cerr << "Waiting for file to hash"; - std::cerr << std::endl; - sleep(1); - } - - std::string savename = "/tmp/" + info.fname; - ftFileCreator *creator = new ftFileCreator(savename, info.size, info.hash,false); - ftController *controller = NULL; - - ftTransferModule *transfer = new ftTransferModule(creator, ftmplex1, controller); - - ftmplex1->addTransferModule(transfer, creator); - - std::list peerIds; - peerIds.push_back("ownId2"); - - transfer->setFileSources(peerIds); - transfer->setPeerState("ownId2", PQIPEER_IDLE, 1000); - //transfer->resumeTransfer(); - - /* check file progress */ - while(1) - { - std::cerr << "File Transfer Status"; - std::cerr << std::endl; - - std::cerr << "Transfered: " << creator->getRecvd(); - std::cerr << std::endl; - - transfer->tick(); - sleep(1); - } -} - diff --git a/libretroshare/src/tests/ft/pqitestor.cc b/libretroshare/src/tests/ft/pqitestor.cc deleted file mode 100644 index 2e879ff7b..000000000 --- a/libretroshare/src/tests/ft/pqitestor.cc +++ /dev/null @@ -1,333 +0,0 @@ -/* - * libretroshare/src/ft: pqitestor.cc - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "ft/pqitestor.h" -#include "pqi/p3linkmgr.h" - -/****** - *#define HUB_DEBUG 1 - *****/ - -P3Hub::P3Hub(uint32_t flags, RsSerialiser *rss) - :mSerialiser(rss), mUseSerialiser(false) -{ - if (rss) - { - mUseSerialiser = true; - } - return; -} - -void P3Hub::addP3Pipe(std::string id, P3Pipe *pqi, p3LinkMgr *mgr) -{ - hubItem item(id, pqi, mgr); - - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); it++) - { - sockaddr_in remote_addr ; - (it->second).mLinkMgr->connectResult(id, true, 0,remote_addr); - mgr->connectResult(it->first, true, 0,remote_addr); - } - - mPeers[id] = item; - - /* tell all the other peers we are connected */ - -#ifdef HUB_DEBUG - std::cerr << "P3Hub::addPQIPipe()"; - std::cerr << std::endl; -#endif - -} - -RsItem *P3Hub::SerialiserPass(RsItem *inItem) -{ - /* pass through serialiser */ - - RsItem *item = NULL; - - uint32_t pktsize = mSerialiser->size(inItem); - void *ptr = malloc(pktsize); - -#ifdef HUB_DEBUG - std::cerr << "P3Hub::SerialiserPass() Expected Size: " << pktsize; - std::cerr << std::endl; -#endif - - if (!mSerialiser->serialise(inItem, ptr, &pktsize)) - { - -#ifdef HUB_DEBUG - std::cerr << "P3Hub::SerialiserPass() serialise Failed"; - std::cerr << std::endl; -#endif - - } - else - { - -#ifdef HUB_DEBUG - std::cerr << "P3Hub::SerialiserPass() serialise success, size: " << pktsize; - std::cerr << std::endl; -#endif - - item = mSerialiser->deserialise(ptr, &pktsize); - item->PeerId(inItem->PeerId()); - - if (!item) - { -#ifdef HUB_DEBUG - std::cerr << "P3Hub::SerialiserPass() deSerialise Failed"; - std::cerr << std::endl; -#endif - } - } - - delete inItem; - free(ptr); - return item; -} - - -void P3Hub::run() -{ -#ifdef HUB_DEBUG - std::cerr << "P3Hub::run()"; - std::cerr << std::endl; -#endif - - RsItem *item; - std::list > recvdQ; - std::list >::iterator lit; - while(1) - { -#ifdef HUB_DEBUG - std::cerr << "P3Hub::run()"; - std::cerr << std::endl; -#endif - - std::map::iterator it; - for(it = mPeers.begin(); it != mPeers.end(); it++) - { - while (NULL != (item = it->second.mPQI->PopSentItem())) - { -#ifdef HUB_DEBUG - std::cerr << "P3Hub::run() recvd msg from: "; - std::cerr << it->first; - std::cerr << " for " << item->PeerId(); - std::cerr << std::endl; - item->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - if (mUseSerialiser) - { - item = SerialiserPass(item); - } - - /* serialiser might hav munched it. */ - if (item) - { - recvdQ.push_back(make_pair(it->first, item)); - } - } - } - - /* now send out */ - for(lit = recvdQ.begin(); lit != recvdQ.end(); lit++) - { - std::string srcId = lit->first; - std::string destId = (lit->second)->PeerId(); - if (mPeers.end() == (it = mPeers.find(destId))) - { -#ifdef HUB_DEBUG - std::cerr << "Failed to Find destination: " << destId; - std::cerr << std::endl; - std::cerr << "Deleting Packet"; - std::cerr << std::endl; -#endif - - delete (lit->second); - - } - else - { - /* now we have dest, set source Id */ - (lit->second)->PeerId(srcId); -#ifdef HUB_DEBUG - std::cerr << "P3Hub::run() sending msg from: "; - std::cerr << srcId << "to: "; - std::cerr << destId; - std::cerr << std::endl; - (lit->second)->print(std::cerr, 10); - std::cerr << std::endl; -#endif - - (it->second).mPQI->PushRecvdItem(lit->second); - } - } - - recvdQ.clear(); - - - - /* Tick the Connection Managers (normally done by rsserver) - */ - - /* sleep a bit */ -#ifdef WIN32 - Sleep(1000); -#else - sleep(1); -#endif - } -} - - - - - - -PQIPipe::PQIPipe(std::string peerId) - :PQInterface(peerId),pipeMtx("Pipe mutex") -{ - return; -} - -int PQIPipe::SendItem(RsItem *item) -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - mSentItems.push_back(item); - - return 1; -} - -RsItem *PQIPipe::PopSentItem() -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - if (mSentItems.size() == 0) - { - return NULL; - } - - RsItem *item = mSentItems.front(); - mSentItems.pop_front(); - - return item; -} - -int PQIPipe::PushRecvdItem(RsItem *item) -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - mRecvdItems.push_back(item); - - return 1; -} - -RsItem *PQIPipe::GetItem() -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - if (mRecvdItems.size() == 0) - { - return NULL; - } - - RsItem *item = mRecvdItems.front(); - mRecvdItems.pop_front(); - - return item; -} - - - - -/***** P3Pipe here *****/ - - - - -int P3Pipe::SendAllItem(RsItem *item) -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - mSentItems.push_back(item); - - return 1; -} - -RsItem *P3Pipe::PopSentItem() -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - if (mSentItems.size() == 0) - { - return NULL; - } - - RsItem *item = mSentItems.front(); - mSentItems.pop_front(); - - return item; -} - -int P3Pipe::PushRecvdItem(RsItem *item) -{ - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - RsCacheRequest *rcr; - RsCacheItem *rci; - RsFileRequest *rfr; - RsFileData *rfd; - RsRawItem *rri; - - if (NULL != (rcr = dynamic_cast(item))) - { - mRecvdRsCacheRequests.push_back(rcr); - } - else if (NULL != (rci = dynamic_cast(item))) - { - mRecvdRsCacheItems.push_back(rci); - } - else if (NULL != (rfr = dynamic_cast(item))) - { - mRecvdRsFileRequests.push_back(rfr); - } - else if (NULL != (rfd = dynamic_cast(item))) - { - mRecvdRsFileDatas.push_back(rfd); - } - else if (NULL != (rri = dynamic_cast(item))) - { - mRecvdRsRawItems.push_back(rri); - } - - return 1; -} - diff --git a/libretroshare/src/tests/ft/pqitestor.h b/libretroshare/src/tests/ft/pqitestor.h deleted file mode 100644 index 744426e0d..000000000 --- a/libretroshare/src/tests/ft/pqitestor.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * libretroshare/src/ft: pqitestor.h - * - * File Transfer for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef PQI_HUB_TEST_H -#define PQI_HUB_TEST_H - -/* - * pqi Test Interface. - */ - -/*** - * Structures for ftserver simulations - * - ****/ - -#include "pqi/pqi.h" -#include "util/rsthreads.h" -#include "serialiser/rsbaseitems.h" - -#include - -class hubItem; -class PQIPipe; -class PQIHub; -class P3Pipe; -class P3Hub; -class p3LinkMgr; - -class hubItem -{ - public: - hubItem() - :mPQI(NULL), mLinkMgr(NULL) { return; } - - hubItem(std::string id, P3Pipe *pqi, p3LinkMgr *mgr) - :mPeerId(id), mPQI(pqi), mLinkMgr(mgr) { return; } - - std::string mPeerId; - P3Pipe *mPQI; - p3LinkMgr *mLinkMgr; -}; - - -class P3Hub: public RsThread -{ - public: - - P3Hub(uint32_t flags, RsSerialiser *rss); -void addP3Pipe(std::string id, P3Pipe *, p3LinkMgr *mgr); - -virtual void run(); - - private: - -RsItem* SerialiserPass(RsItem *inItem); - - std::map mPeers; - RsSerialiser *mSerialiser; - bool mUseSerialiser; -}; - - -class PQIPipe: public PQInterface -{ -public: - PQIPipe(std::string peerId); - -virtual int SendItem(RsItem *); -virtual RsItem *GetItem(); - - // PQIHub Interface. -RsItem *PopSentItem(); -int PushRecvdItem(RsItem *); - - /* - */ - -private: - - RsMutex pipeMtx; - - std::list mSentItems; - std::list mRecvdItems; - -}; - -class P3Pipe: public P3Interface -{ - public: - P3Pipe() : pipeMtx(std::string("Pipe mutex")) {return; } - virtual ~P3Pipe() {return; } - - virtual int tick() { return 1; } - virtual int status() { return 1; } - - /* Overloaded from P3Interface */ - - virtual RsCacheRequest *RequestedSearch() { return GetSpecificItem(mRecvdRsCacheRequests) ; } - virtual RsCacheItem *GetSearchResult() { return GetSpecificItem(mRecvdRsCacheItems) ; } - virtual RsFileRequest *GetFileRequest() { return GetSpecificItem(mRecvdRsFileRequests) ; } - virtual RsFileData *GetFileData() { return GetSpecificItem(mRecvdRsFileDatas) ; } - virtual RsRawItem *GetRsRawItem() { return GetSpecificItem(mRecvdRsRawItems) ; } - virtual RsFileChunkMapRequest* GetFileChunkMapRequest() { return GetSpecificItem(mRecvdRsChunkMapRequests) ; } - virtual RsFileChunkMap* GetFileChunkMap() { return GetSpecificItem(mRecvdRsChunkMaps) ; } - virtual RsFileCRC32MapRequest* GetFileCRC32MapRequest() { return GetSpecificItem(mRecvdRsCRC32MapRequests) ; } - virtual RsFileCRC32Map* GetFileCRC32Map() { return GetSpecificItem(mRecvdRsCRC32Maps) ; } - virtual RsFileSingleChunkCrcRequest* GetFileSingleChunkCrcRequest() { return GetSpecificItem(mRecvdRsSingleChunkCRCRequests) ; } - virtual RsFileSingleChunkCrc* GetFileSingleChunkCrc() { return GetSpecificItem(mRecvdRsSingleChunkCRCs) ; } - - virtual int SearchSpecific(RsCacheRequest *item) { SendAllItem(item); return 1 ; } - virtual int SendSearchResult(RsCacheItem *item) { SendAllItem(item); return 1 ; } - virtual int SendFileRequest(RsFileRequest *item) { SendAllItem(item); return 1 ; } - virtual int SendFileData(RsFileData *item) { SendAllItem(item); return 1 ; } - virtual int SendRsRawItem(RsRawItem *item) { SendAllItem(item); return 1 ; } - virtual int SendFileChunkMapRequest(RsFileChunkMapRequest*item) { SendAllItem(item); return 1 ; } - virtual int SendFileChunkMap(RsFileChunkMap*item) { SendAllItem(item); return 1 ; } - virtual int SendFileCRC32MapRequest(RsFileCRC32MapRequest*item) { SendAllItem(item); return 1 ; } - virtual int SendFileCRC32Map(RsFileCRC32Map*item) { SendAllItem(item); return 1 ; } - virtual int SendFileSingleChunkCrcRequest(RsFileSingleChunkCrcRequest*item) { SendAllItem(item); return 1 ; } - virtual int SendFileSingleChunkCrc(RsFileSingleChunkCrc*item) { SendAllItem(item); return 1 ; } - - /* Lower Interface for PQIHub */ - - RsItem *PopSentItem(); - int PushRecvdItem(RsItem *item); - - private: - template T *GetSpecificItem(std::list& item_list) - { - RsStackMutex stack(pipeMtx); /***** LOCK MUTEX ****/ - - if (item_list.size() == 0) - return NULL; - - T *item = item_list.front(); - item_list.pop_front(); - - return item; - } - - int SendAllItem(RsItem *item); - - RsMutex pipeMtx; - - std::list mSentItems; - - std::list mRecvdRsCacheRequests; - std::list mRecvdRsCacheItems; - std::list mRecvdRsFileRequests; - std::list mRecvdRsFileDatas; - std::list mRecvdRsRawItems; - std::list mRecvdRsChunkMapRequests; - std::list mRecvdRsChunkMaps; - std::list mRecvdRsCRC32MapRequests; - std::list mRecvdRsCRC32Maps; - std::list mRecvdRsSingleChunkCRCRequests; - std::list mRecvdRsSingleChunkCRCs; -}; - - -#endif diff --git a/libretroshare/src/tests/general/memory_management_test.cc b/libretroshare/src/tests/general/memory_management_test.cc deleted file mode 100644 index 2b680a293..000000000 --- a/libretroshare/src/tests/general/memory_management_test.cc +++ /dev/null @@ -1,61 +0,0 @@ -#ifdef LINUX -#include -#endif -#include -#include -#include -#include -#include "util/utest.h" -#include "serialiser/rsserial.h" - -INITTEST(); - -// Make a fake class of size n. -// -template class RsTestItem: public RsItem -{ - public: - unsigned char buff[n] ; - - RsTestItem(uint32_t s) : RsItem(s) {} - virtual void clear() {} - virtual std::ostream& print(std::ostream& o, uint16_t) { return o ; } -}; - -int main(int argc, char **argv) -{ -#ifdef LINUX - feenableexcept(FE_INVALID) ; - feenableexcept(FE_DIVBYZERO) ; -#endif - typedef RsTestItem<17> Test17 ; - typedef RsTestItem<31> Test31 ; - - std::vector v; - - for(int i=0;i<300;++i) - v.push_back(new Test17(0)) ; - for(int i=0;i<700;++i) - v.push_back(new Test31(0)) ; - - RsMemoryManagement::printStatistics() ; - - // Now delete objects randomly. - // - for(int i=0;i<1000;++i) - { - int indx = lrand48()%(int)v.size() ; - - delete v[indx] ; - v[indx] = v.back() ; - v.pop_back() ; - } - - std::cerr << "After memory free: " << std::endl; - - RsMemoryManagement::printStatistics() ; - - FINALREPORT("memory_management_test"); - exit(TESTRESULT()); -} - diff --git a/libretroshare/src/tests/general/netsetup_test.cc b/libretroshare/src/tests/general/netsetup_test.cc deleted file mode 100644 index 7fe740dfd..000000000 --- a/libretroshare/src/tests/general/netsetup_test.cc +++ /dev/null @@ -1,281 +0,0 @@ - -//#include "pqi/p3connmgr.h" -//#include "pqi/p3authmgr.h" -#include "util/utest.h" - -#include "upnp/upnphandler_linux.h" -#include "dht/opendhtmgr.h" -#include "tcponudp/tou.h" - - -INITTEST(); - -int end_test() -{ - FINALREPORT("net_test1"); - - exit(TESTRESULT()); -} - - -void printNetworkStatus(p3ConnectMgr *connMgr) -{ - std::cerr << "network status for : " << connMgr->getOwnId() << std::endl; - std::cerr << "Net Ok:" << connMgr->getNetStatusOk() << std::endl; - std::cerr << "Upnp Ok:" << connMgr->getNetStatusUpnpOk() << std::endl; - std::cerr << "DHT Ok:" << connMgr->getNetStatusDhtOk() << std::endl; - std::cerr << "Ext Ok:" << connMgr->getNetStatusExtOk() << std::endl; - std::cerr << "Udp Ok:" << connMgr->getNetStatusUdpOk() << std::endl; - std::cerr << "Tcp Ok:" << connMgr->getNetStatusTcpOk() << std::endl; - std::cerr << "network status for : " << connMgr->getOwnId() << std::endl; - - peerConnectState state; - if (connMgr->getOwnNetStatus(state)) - { - std::string txt = textPeerConnectState(state); - std::cerr << "State: " << txt << std::endl; - } - else - { - std::cerr << "No Net Status" << std::endl; - } -} - - -void setupTest(int i, p3ConnectMgr *cMgr) -{ - switch(i) - { - case 1: - { - /* Test One */ - - } - break; - - case 10: - { - /* Test One */ - - } - break; - - case 15: - { - /* Test One */ - - } - break; - - case 20: - { - /* Test One */ - - } - break; - - case 13: - { - /* Test One */ - - } - break; - - default: - std::cerr << "setupTest(" << i << ") no test here" << std::endl; - } -} - -void checkResults(int i, p3ConnectMgr *cMgr) -{ - switch(i) - { - /* Test One: Setup - without any support */ - case 1: - { - /* Expect UDP ports to be established by now */ - - //CHECK(isExternalNet(&loopback_addr)==false); - } - break; - - case 10: - { - /* Expect Local IP Address to be known */ - - } - break; - - case 15: - { - - REPORT("Basic Networking Setup"); - } - break; - - /* Test Two: DHT Running */ - case 111: - { - /* Expect UDP ports to be established by now */ - - //CHECK(isExternalNet(&loopback_addr)==false); - } - break; - - case 110: - { - /* Expect Local IP Address to be known */ - - } - break; - - /* Test 3: */ - case 145: - { - - } - break; - - case 100: - { - /* Test One */ - - } - break; - - case 5000: - { - /* End of Tests */ - end_test(); - } - break; - - default: - { - std::cerr << "checkResults(" << i << ") no test here" << std::endl; - printNetworkStatus(cMgr); - - } - } -} - -class TestMonitor: public pqiMonitor -{ - public: -virtual void statusChange(const std::list &plist) -{ - std::cerr << "TestMonitor::statusChange()"; - std::cerr << std::endl; - std::list::const_iterator it; - for(it = plist.begin(); it != plist.end(); it++) - { - std::cerr << "Event!"; - std::cerr << std::endl; - } -} - -}; - -int main(int argc, char **argv) -{ - /* options */ - bool enable_upnp = true; - bool enable_dht = true; - bool enable_forward = true; - - /* handle options */ - - int testtype = 1; - switch(testtype) - { - case 1: - /* udp test */ - enable_upnp = false; - enable_forward = false; - enable_dht = true; - break; - - } - - -#ifndef WINDOWS_SYS -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#else - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - - std::string ownId = "OWNID"; - - /* create a dummy auth mgr */ - p3AuthMgr *authMgr = new p3DummyAuthMgr(); - p3ConnectMgr *connMgr = new p3ConnectMgr(authMgr); - - /* Setup Notify Early - So we can use it. */ - //rsNotify = new p3Notify(); - - pqiNetAssistFirewall *upnpMgr = NULL; - p3DhtMgr *dhtMgr = NULL; - - if (enable_upnp) - { - std::cerr << "Switching on UPnP" << std::endl; - upnpMgr = new upnphandler(); - connMgr->addNetAssistFirewall(1, upnpMgr); - } - - if (enable_dht) - { - p3DhtMgr *dhtMgr = new OpenDHTMgr(ownId, connMgr, "./"); - connMgr->addNetAssistConnect(1, dhtMgr); - - dhtMgr->start(); - std::cerr << "Switching on DHT" << std::endl; - dhtMgr->enable(true); - } - - - /**************************************************************************/ - /* need to Monitor too! */ - - TestMonitor *testmonitor = new TestMonitor(); - connMgr->addMonitor(testmonitor); - - connMgr->checkNetAddress(); - int i; - for(i=0; 1; i++) - { - connMgr->tick(); - - setupTest(i, connMgr); -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // ie UNIX - sleep(1); -#else - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - connMgr->tick(); - - checkResults(i, connMgr); - - tou_tick_stunkeepalive(); - } -} - diff --git a/libretroshare/src/tests/general/pgpkey_test.cc b/libretroshare/src/tests/general/pgpkey_test.cc deleted file mode 100644 index a6b49651f..000000000 --- a/libretroshare/src/tests/general/pgpkey_test.cc +++ /dev/null @@ -1,59 +0,0 @@ -#ifdef LINUX -#include -#endif -#include -#include -#include -#include -#include -#include "util/utest.h" -#include "pgp/pgpkeyutil.h" - -INITTEST(); - -int main(int argc, char **argv) -{ -#ifdef LINUX - feenableexcept(FE_INVALID) ; - feenableexcept(FE_DIVBYZERO) ; -#endif - try - { - if(argc < 2) - { - std::cerr << argv[0] << ": test gpg certificate cleaning method. " << std::endl; - std::cerr << " Usage: " << argv[0] << " certificate.asc" << std::endl; - return 0 ; - } - - FILE *f = fopen(argv[1],"r") ; - - if(f == NULL) - throw std::runtime_error(std::string("Could not open file ") + argv[1]) ; - - std::string cert ; - int c ; - - while((c = getc(f) ) != EOF) - cert += (char)c ; - - std::cerr << "got this certificate: " << std::endl; - std::cerr << cert << std::endl; - - std::cerr << "Calling cert simplification code..." << std::endl; - std::string cleaned_key ; - - PGPKeyManagement::createMinimalKey(cert,cleaned_key) ; - - std::cerr << "Minimal key produced: " << std::endl; - std::cerr << cleaned_key << std::endl; - FINALREPORT("pgpkey_test"); - exit(TESTRESULT()); - } - catch(std::exception& e) - { - std::cerr << "Exception never handled: " << e.what() << std::endl ; - return 1 ; - } -} - diff --git a/libretroshare/src/tests/general/random_test.cc b/libretroshare/src/tests/general/random_test.cc deleted file mode 100644 index 8340b1d67..000000000 --- a/libretroshare/src/tests/general/random_test.cc +++ /dev/null @@ -1,168 +0,0 @@ -#ifdef LINUX -#include -#endif -#include -#include -#include -#include -#include -#include "util/utest.h" -#include "util/rsrandom.h" - -INITTEST(); -typedef double (* Ifctn)( double t); -/* Numerical integration method */ -double Simpson3_8( Ifctn f, double a, double b, int N) -{ - int j; - double l1; - double h = (b-a)/N; - double h1 = h/3.0; - double sum = f(a) + f(b); - - for (j=3*N-1; j>0; j--) { - l1 = (j%3)? 3.0 : 2.0; - sum += l1*f(a+h1*j) ; - } - return h*sum/8.0; -} - -#define A 12 -double Gamma_Spouge( double z ) -{ - int k; - static double cspace[A]; - static double *coefs = NULL; - double accum; - double a = A; - - if (!coefs) { - double k1_factrl = 1.0; - coefs = cspace; - coefs[0] = sqrt(2.0*M_PI); - for(k=1; k 2.0e-8) && (y < x)) y += .4; - if (y>x) y=x; - - return 1.0 - Simpson3_8( &f0, 0, y, std::max(5,(int)(y/h)))/Gamma_Spouge(a); -} - -double chi2Probability( int dof, double distance) -{ - return GammaIncomplete_Q( 0.5*dof, 0.5*distance); -} - -class myThread: public RsThread -{ - public: - myThread() - { - _finished = false ; - } - virtual void run() - { - // test that random numbers are regularly disposed - // - int N = 5000 ; - int B = 8 ; - - std::vector buckets(B,0) ; - - for(int i=0;i significance) - std::cerr << ": passed" << std::endl ; - else - std::cerr << ": failed" << std::endl ; - - _finished = true ; - } - - bool finished() const { return _finished ; } - private: - bool _finished ; -}; - - -int main(int argc, char **argv) -{ -#ifdef LINUX - feenableexcept(FE_INVALID) ; - feenableexcept(FE_DIVBYZERO) ; -#endif - std::cerr << "Generating random 64 chars string (run that again to test that it's changing): " << RSRandom::random_alphaNumericString(64) << std::endl; - std::cerr << "Generating 10 random uint64_t:" << std::endl; - - for(int i=0;i<10;++i) - std::cerr << std::hex << RSRandom::random_u64() << std::endl; - - int nt = 10 ; // number of threads. - std::vector threads(nt,(myThread*)NULL) ; - - for(int i=0;istart() ; - } - - while(true) - { - bool finished = true ; - - for(int i=0;ifinished()) - finished = false ; - - if(finished) - break ; - } - for(int i=0;imGroupId); - randString(SHORT_STR, metaGrp->mOrigGrpId); - randString(SHORT_STR, metaGrp->mAuthorId); - randString(SHORT_STR, metaGrp->mGroupName); - - init_item(metaGrp->signSet); - init_item(metaGrp->keys); - - metaGrp->mPublishTs = rand()%3452; - metaGrp->mGroupFlags = rand()%43; - - metaGrp->mGroupStatus = rand()%313; - metaGrp->mSubscribeFlags = rand()%2251; - metaGrp->mMsgCount = rand()%2421; - metaGrp->mLastPost = rand()%2211; - metaGrp->mPop = rand()%5262; -} - -void init_item(RsGxsMsgMetaData* metaMsg) -{ - - randString(SHORT_STR, metaMsg->mGroupId); - randString(SHORT_STR, metaMsg->mMsgId); - randString(SHORT_STR, metaMsg->mThreadId); - randString(SHORT_STR, metaMsg->mParentId); - randString(SHORT_STR, metaMsg->mAuthorId); - randString(SHORT_STR, metaMsg->mOrigMsgId); - randString(SHORT_STR, metaMsg->mMsgName); - - init_item(metaMsg->signSet); - - metaMsg->mPublishTs = rand()%313; - metaMsg->mMsgFlags = rand()%224; - metaMsg->mMsgStatus = rand()%4242; - metaMsg->mChildTs = rand()%221; -} diff --git a/libretroshare/src/tests/gxs/common/data_support.h b/libretroshare/src/tests/gxs/common/data_support.h deleted file mode 100644 index 930cfbdc1..000000000 --- a/libretroshare/src/tests/gxs/common/data_support.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef DATA_SUPPORT_H -#define DATA_SUPPORT_H - -#include "serialiser/rsnxsitems.h" -#include "gxs/rsgxsdata.h" - -bool operator==(const RsNxsGrp&, const RsNxsGrp&); -bool operator==(const RsNxsMsg&, const RsNxsMsg&); - -void init_item(RsNxsGrp& nxg); -void init_item(RsNxsMsg& nxm); -void init_item(RsGxsGrpMetaData* metaGrp); -void init_item(RsGxsMsgMetaData* metaMsg); - -#endif // DATA_SUPPORT_H diff --git a/libretroshare/src/tests/gxs/common/support.cc b/libretroshare/src/tests/gxs/common/support.cc deleted file mode 100644 index 9003b6b60..000000000 --- a/libretroshare/src/tests/gxs/common/support.cc +++ /dev/null @@ -1,340 +0,0 @@ -/* - * libretroshare/src/serialiser: t_support.h.cc - * - * RetroShare Serialiser tests. - * - * Copyright 2007-2008 by Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include - -#include "support.h" -#include "serialiser/rstlvbase.h" - -void randString(const uint32_t length, std::string& outStr) -{ - char alpha = 'a'; - char* stringData = NULL; - - stringData = new char[length]; - - for(uint32_t i=0; i != length; i++) - stringData[i] = alpha + (rand() % 26); - - outStr.assign(stringData, length); - delete[] stringData; - - return; -} - -void randString(const uint32_t length, std::wstring& outStr) -{ - wchar_t alpha = L'a'; - wchar_t* stringData = NULL; - - stringData = new wchar_t[length]; - - for(uint32_t i=0; i != length; i++) - stringData[i] = (alpha + (rand() % 26)); - - outStr.assign(stringData, length); - delete[] stringData; - - return; -} - -void init_item(RsTlvSecurityKeySet& ks) -{ - int n = rand()%24; - randString(SHORT_STR, ks.groupId); - for(int i=1; i::const_iterator l_cit = l.keys.begin(), - r_cit = r.keys.begin(); - - for(; l_cit != l.keys.end(); l_cit++, r_cit++){ - if(l_cit->first != r_cit->first) return false; - if(!(l_cit->second == r_cit->second)) return false; - } - - return true; -} - -bool operator==(const RsTlvSecurityKey& sk1, const RsTlvSecurityKey& sk2) -{ - - if(sk1.startTS != sk2.startTS) return false; - if(sk1.endTS != sk2.endTS) return false; - if(sk1.keyFlags != sk2.keyFlags) return false; - if(sk1.keyId != sk2.keyId) return false; - if(!(sk1.keyData == sk1.keyData)) return false; - - return true; -} - -bool operator==(const RsTlvKeySignatureSet& kss1, const RsTlvKeySignatureSet& kss2) -{ - const std::map& set1 = kss1.keySignSet, - &set2 = kss2.keySignSet; - - if(set1.size() != set2.size()) return false; - - std::map::const_iterator it1 = set1.begin(), it2; - - for(; it1 != set1.end(); it1++) - { - SignType st1 = it1->first; - - if( (it2 =set2.find(st1)) == set2.end()) - return false; - - if(!(it1->second == it2->second)) - return false; - - } - - return true; -} - -bool operator==(const RsTlvKeySignature& ks1, const RsTlvKeySignature& ks2) -{ - - if(ks1.keyId != ks2.keyId) return false; - if(!(ks1.signData == ks2.signData)) return false; - - return true; -} - -bool operator==(const RsTlvPeerIdSet& pids1, const RsTlvPeerIdSet& pids2) -{ - std::list::const_iterator it1 = pids1.ids.begin(), - it2 = pids2.ids.begin(); - - - for(; ((it1 != pids1.ids.end()) && (it2 != pids2.ids.end())); it1++, it2++) - { - if(*it1 != *it2) return false; - } - - return true; - -} - - -void init_item(RsTlvImage& im) -{ - std::string imageData; - randString(LARGE_STR, imageData); - im.binData.setBinData(imageData.c_str(), imageData.size()); - im.image_type = RSTLV_IMAGE_TYPE_PNG; - - return; -} - -void init_item(RsTlvKeySignatureSet &kss) -{ - int numSign = rand()%21; - - for(int i=0; i < numSign; i++) - { - RsTlvKeySignature sign; - SignType sType = rand()%2452; - init_item(sign); - kss.keySignSet.insert(std::make_pair(sType, sign)); - } -} - -bool operator==(const RsTlvBinaryData& bd1, const RsTlvBinaryData& bd2) -{ - if(bd1.tlvtype != bd2.tlvtype) return false; - if(bd1.bin_len != bd2.bin_len) return false; - - unsigned char *bin1 = (unsigned char*)(bd1.bin_data), - *bin2 = (unsigned char*)(bd2.bin_data); - - for(uint32_t i=0; i < bd1.bin_len; bin1++, bin2++, i++) - { - if(*bin1 != *bin2) - return false; - } - - return true; -} - - -void init_item(RsTlvSecurityKey& sk) -{ - int randnum = rand()%313131; - - sk.endTS = randnum; - sk.keyFlags = randnum; - sk.startTS = randnum; - randString(SHORT_STR, sk.keyId); - - std::string randomStr; - randString(LARGE_STR, randomStr); - - sk.keyData.setBinData(randomStr.c_str(), randomStr.size()); - - return; -} - -void init_item(RsTlvKeySignature& ks) -{ - randString(SHORT_STR, ks.keyId); - - std::string signData; - randString(LARGE_STR, signData); - - ks.signData.setBinData(signData.c_str(), signData.size()); - - return; -} - - -bool operator==(const RsTlvImage& img1, const RsTlvImage& img2) -{ - if(img1.image_type != img2.image_type) return false; - if(!(img1.binData == img2.binData)) return false; - - return true; - -} - -/** channels, forums and blogs **/ - -void init_item(RsTlvHashSet& hs) -{ - std::string hash; - - for(int i=0; i < 10; i++) - { - randString(SHORT_STR, hash); - hs.ids.push_back(hash); - } - - hs.mType = TLV_TYPE_HASHSET; - return; -} - -void init_item(RsTlvPeerIdSet& ps) -{ - std::string peer; - - for(int i=0; i < 10; i++) - { - randString(SHORT_STR, peer); - ps.ids.push_back(peer); - } - - ps.mType = TLV_TYPE_PEERSET; - return; -} - -bool operator==(const RsTlvHashSet& hs1,const RsTlvHashSet& hs2) -{ - if(hs1.mType != hs2.mType) return false; - - std::list::const_iterator it1 = hs1.ids.begin(), - it2 = hs2.ids.begin(); - - for(; ((it1 != hs1.ids.end()) && (it2 != hs2.ids.end())); it1++, it2++) - { - if(*it1 != *it2) return false; - } - - return true; -} - -void init_item(RsTlvFileItem& fi) -{ - fi.age = rand()%200; - fi.filesize = rand()%34030313; - randString(SHORT_STR, fi.hash); - randString(SHORT_STR, fi.name); - randString(SHORT_STR, fi.path); - fi.piecesize = rand()%232; - fi.pop = rand()%2354; - init_item(fi.hashset); - - return; -} - -void init_item(RsTlvBinaryData& bd){ - bd.TlvClear(); - std::string data; - randString(LARGE_STR, data); - bd.setBinData(data.data(), data.length()); -} - -void init_item(RsTlvFileSet& fSet){ - - randString(LARGE_STR, fSet.comment); - randString(SHORT_STR, fSet.title); - RsTlvFileItem fi1, fi2; - init_item(fi1); - init_item(fi2); - fSet.items.push_back(fi1); - fSet.items.push_back(fi2); - - return; -} - -bool operator==(const RsTlvFileSet& fs1,const RsTlvFileSet& fs2) -{ - if(fs1.comment != fs2.comment) return false; - if(fs1.title != fs2.title) return false; - - std::list::const_iterator it1 = fs1.items.begin(), - it2 = fs2.items.begin(); - - for(; ((it1 != fs1.items.end()) && (it2 != fs2.items.end())); it1++, it2++) - if(!(*it1 == *it2)) return false; - - return true; -} - -bool operator==(const RsTlvFileItem& fi1,const RsTlvFileItem& fi2) -{ - if(fi1.age != fi2.age) return false; - if(fi1.filesize != fi2.filesize) return false; - if(fi1.hash != fi2.hash) return false; - if(!(fi1.hashset == fi2.hashset)) return false; - if(fi1.name != fi2.name) return false; - if(fi1.path != fi2.path) return false; - if(fi1.piecesize != fi2.piecesize) return false; - if(fi1.pop != fi2.pop) return false; - - return true; -} diff --git a/libretroshare/src/tests/gxs/common/support.h b/libretroshare/src/tests/gxs/common/support.h deleted file mode 100644 index bf33716af..000000000 --- a/libretroshare/src/tests/gxs/common/support.h +++ /dev/null @@ -1,226 +0,0 @@ -#ifndef SUPPORT_H_ -#define SUPPORT_H_ - -/* - * libretroshare/src/tests/serialiser: - * - * RetroShare Serialiser tests. - * - * Copyright 2007-2008 by Christopher Evi-Parker, 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 "retroshare@lunamutt.com". - * - */ - -#include -#include -#include - -#include "util/utest.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvutil.h" -#include "serialiser/rstlvkeys.h" -#include "serialiser/rstlvtypes.h" - - - -/** - * This contains functions that may be useful for testing throughout the - * retroshare's serialiser - * package, if you find a function you keep using everywhere, might be a good idea to add it here - */ - - -#define SHORT_STR 100 -#define LARGE_STR 1000 - -void randString(const uint32_t, std::string&); -void randString(const uint32_t, std::wstring&); - - -/* for testing compound tlv items */ - -void init_item(RsTlvSecurityKey&); -void init_item(RsTlvKeySignature&); -void init_item(RsTlvKeySignatureSet&); -void init_item(RsTlvBinaryData&); -void init_item(RsTlvFileItem&); -void init_item(RsTlvFileSet&); -void init_item(RsTlvHashSet&); -void init_item(RsTlvPeerIdSet&); -void init_item(RsTlvImage&); -void init_item(RsTlvPeerIdSet&); -void init_item(RsTlvSecurityKeySet& ); - -bool operator==(const RsTlvSecurityKey&, const RsTlvSecurityKey& ); -bool operator==(const RsTlvKeySignature&, const RsTlvKeySignature& ); -bool operator==(const RsTlvBinaryData&, const RsTlvBinaryData&); -bool operator==(const RsTlvFileItem&, const RsTlvFileItem&); -bool operator==(const RsTlvFileSet&, const RsTlvFileSet& ); -bool operator==(const RsTlvHashSet&, const RsTlvHashSet&); -bool operator==(const RsTlvImage&, const RsTlvImage& ); -bool operator==(const RsTlvPeerIdSet& , const RsTlvPeerIdSet& ); -bool operator==(const RsTlvSecurityKeySet& , const RsTlvSecurityKeySet& ); -bool operator==(const RsTlvKeySignatureSet& , const RsTlvKeySignatureSet& ); - - - -/*! - * This templated test function which allows you to test - * retroshare serialiser items (except compound tlv items) - * you the function must implement a function - * - * 'RsSerialType* init_item(YourRsItem& rs_item)' - * which returns valid serialiser that - * can serialiser rs_item. You also need to implement an operator - * - * Also need to implement a function - * 'bool operator =(YourRsItem& rs_itemL, YourRsItem& rs_temR)' - * which allows this function to test for equality between both parameters. - * rs_temR is the result of deserialising the left operand (1st parameter). - * not YourRsItem in specifier in about functions should be a derived type from RsItem - * - * @param T the item you want to test - */ - -template int test_RsItem() -{ - /* make a serialisable RsTurtleItem */ - - RsSerialiser srl; - - /* initialise */ - T rsfi ; - RsSerialType *rsfis = init_item(rsfi) ; - - /* attempt to serialise it before we add it to the serialiser */ - - CHECK(0 == srl.size(&rsfi)); - - static const uint32_t MAX_BUFSIZE = 22000 ; - - char *buffer = new char[MAX_BUFSIZE]; - uint32_t sersize = MAX_BUFSIZE; - - CHECK(false == srl.serialise(&rsfi, (void *) buffer, &sersize)); - - /* now add to serialiser */ - - srl.addSerialType(rsfis); - - uint32_t size = srl.size(&rsfi); - bool done = srl.serialise(&rsfi, (void *) buffer, &sersize); - - std::cerr << "test_Item() size: " << size << std::endl; - std::cerr << "test_Item() done: " << done << std::endl; - std::cerr << "test_Item() sersize: " << sersize << std::endl; - - std::cerr << "test_Item() serialised:" << std::endl; - //displayRawPacket(std::cerr, (void *) buffer, sersize); - - CHECK(done == true); - - uint32_t sersize2 = sersize; - RsItem *output = srl.deserialise((void *) buffer, &sersize2); - - CHECK(output != NULL); - CHECK(sersize2 == sersize); - - T *outfi = dynamic_cast(output); - - CHECK(outfi != NULL); - - if (outfi) - CHECK(*outfi == rsfi) ; - - sersize2 = MAX_BUFSIZE; - bool done2 = srl.serialise(outfi, (void *) &(buffer[16*8]), &sersize2); - - CHECK(done2) ; - CHECK(sersize2 == sersize); - -// displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2); - - delete[] buffer ; - //delete rsfis; - - return 1; -} - -template int test_RsItem(uint16_t servtype) -{ - /* make a serialisable RsTurtleItem */ - - RsSerialiser srl; - - /* initialise */ - T rsfi(servtype) ; - RsSerialType *rsfis = init_item(rsfi) ; // deleted on destruction of srl - - /* attempt to serialise it before we add it to the serialiser */ - - CHECK(0 == srl.size(&rsfi)); - - static const uint32_t MAX_BUFSIZE = 22000 ; - - char *buffer = new char[MAX_BUFSIZE]; - uint32_t sersize = MAX_BUFSIZE; - - CHECK(false == srl.serialise(&rsfi, (void *) buffer, &sersize)); - - /* now add to serialiser */ - - srl.addSerialType(rsfis); - - uint32_t size = srl.size(&rsfi); - bool done = srl.serialise(&rsfi, (void *) buffer, &sersize); - - std::cerr << "test_Item() size: " << size << std::endl; - std::cerr << "test_Item() done: " << done << std::endl; - std::cerr << "test_Item() sersize: " << sersize << std::endl; - - std::cerr << "test_Item() serialised:" << std::endl; - //displayRawPacket(std::cerr, (void *) buffer, sersize); - - CHECK(done == true); - - uint32_t sersize2 = sersize; - RsItem *output = srl.deserialise((void *) buffer, &sersize2); - - CHECK(output != NULL); - CHECK(sersize2 == sersize); - - T *outfi = dynamic_cast(output); - - CHECK(outfi != NULL); - - if (outfi) - CHECK(*outfi == rsfi) ; - - sersize2 = MAX_BUFSIZE; - bool done2 = srl.serialise(outfi, (void *) &(buffer[16*8]), &sersize2); - - CHECK(done2) ; - CHECK(sersize2 == sersize); - -// displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2); - - delete[] buffer ; - - return 1; -} -#endif /* SUPPORT_H_ */ diff --git a/libretroshare/src/tests/gxs/data_service/nxs_tests.pro b/libretroshare/src/tests/gxs/data_service/nxs_tests.pro deleted file mode 100644 index 8fa292c61..000000000 --- a/libretroshare/src/tests/gxs/data_service/nxs_tests.pro +++ /dev/null @@ -1,203 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2012-05-06T09:19:26 -# -#------------------------------------------------- - - -# -QT += core network - -QT -= gui - -#CONFIG += gen_exchange_target -CONFIG += nxs_net_test -#CONFIG += dstore_target -#CONFIG += gxsdata_target - -CONFIG += bitdht - - - -#gen_exchange_target { - -#TARGET = gen_exchange_test - -#} - -#nxs_net_test { - -TARGET = nxs_net_test - -#} - -#gxsdata_target { - -#TARGET = gxsdata_test -#} - -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -CONFIG += debug - -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 -} -################################# Linux ########################################## -# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib -linux-* { - #CONFIG += version_detail_bash_script - QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 - - system(which gpgme-config >/dev/null 2>&1) { - INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - } else { - message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - } - - PRE_TARGETDEPS *= ../../lib/libretroshare.a - - LIBS += ../../lib/libretroshare.a - LIBS += ../../../../libbitdht/src/lib/libbitdht.a - LIBS += ../../../../openpgpsdk/src/lib/libops.a - LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2 - LIBS *= -rdynamic -frtti - DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions - DEFINES *= HAS_GNOME_KEYRING -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -#################################### Windows ##################################### - -win32 { - - DEFINES *= WINDOWS_SYS \ - WIN32 \ - STATICLIB \ - MINGW - # 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 - -# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a - PRE_TARGETDEPS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - - LIBS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a - LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a - LIBS += -L"../../../../../lib" - LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 -# added after bitdht -# LIBS += -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 - LIBS += -lole32 -lwinmm - - # export symbols for the plugins - #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a - - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 - GPGME_DIR = ../../../../lib/gpgme-1.1.8 - SSL_DIR = ../../../../../OpenSSL - OPENPGPSDK_DIR = ../../../../openpgpsdk/src - INCLUDEPATH += . $${SSL_DIR}/include $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src \ - $${OPENPGPSDK_DIR} - - SQLITE_DIR = ../../../../../../Libraries/sqlite/sqlite-autoconf-3070900 - INCLUDEPATH += . \ - $${SQLITE_DIR} - - - - -} - -bitdht { - - # Chris version. - #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a -} - -win32 { -# must be added after bitdht - LIBS += -lws2_32 -} - -version_detail_bash_script { - DEFINES += ADD_LIBRETROSHARE_VERSION_INFO - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh -} - -install_rs { - INSTALLS += binary_rs - binary_rs.path = $$(PREFIX)/usr/bin - binary_rs.files = ./RetroShare -} - - -#gen_exchange_target { - -# SOURCES += \ -# support.cc \ -# genexchangetester.cpp \ -# genexchangetestservice.cpp \ -# rsdummyservices.cc \ -# rsgenexchange_test.cc - -# HEADERS += support.h \ -# rsdataservice_test.h \ -# rsdummyservices.h \ -# data_support.h -#} - -nxs_net_test { - - SOURCES += \ - support.cc \ - data_support.cc \ - nxstesthub.cc \ - nxstestscenario.cc \ - rsgxsnetservice_test.cc - - HEADERS += support.h \ - nxstestscenario.h \ - nxstesthub.h \ - data_support.h - -} - -INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/data_service/rsdataservice_test.cc b/libretroshare/src/tests/gxs/data_service/rsdataservice_test.cc deleted file mode 100644 index 4cb126cce..000000000 --- a/libretroshare/src/tests/gxs/data_service/rsdataservice_test.cc +++ /dev/null @@ -1,337 +0,0 @@ - -#include "support.h" -#include "data_support.h" -#include "rsdataservice_test.h" -#include "gxs/rsgds.h" -#include "gxs/rsdataservice.h" - -#define DATA_BASE_NAME "msg_grp_Store" - -INITTEST(); -RsGeneralDataService* dStore = NULL; - -void setUp(); -void tearDown(); - -int main() -{ - - std::cerr << "RsDataService Tests" << std::endl; - - test_groupStoreAndRetrieve(); REPORT("test_groupStoreAndRetrieve"); - test_messageStoresAndRetrieve(); REPORT("test_messageStoresAndRetrieve"); - - FINALREPORT("RsDataService Tests"); - - return TESTRESULT(); - -} - - - -/*! - * All memory is disposed off, good for looking - * for memory leaks - */ -void test_groupStoreAndRetrieve(){ - - setUp(); - - int nGrp = rand()%32; - std::map grps, grps_copy; - RsNxsGrp* grp; - RsGxsGrpMetaData* grpMeta; - for(int i = 0; i < nGrp; i++){ - std::pair p; - grp = new RsNxsGrp(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); - grpMeta = new RsGxsGrpMetaData(); - p.first = grp; - p.second = grpMeta; - init_item(*grp); - init_item(grpMeta); - grpMeta->mGroupId = grp->grpId; - grps.insert(p); - RsNxsGrp* grp_copy = new RsNxsGrp(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); - *grp_copy = *grp; - RsGxsGrpMetaData* grpMeta_copy = new RsGxsGrpMetaData(); - *grpMeta_copy = *grpMeta; - grps_copy.insert(std::make_pair(grp_copy, grpMeta_copy )); - grpMeta = NULL; - grp = NULL; - } - - dStore->storeGroup(grps); - - //use copy, a grps are deleted in store - grps.clear(); - grps = grps_copy; - - std::map gR; - std::map grpMetaR; - dStore->retrieveNxsGrps(gR, false, false); - dStore->retrieveGxsGrpMetaData(grpMetaR); - - std::map::iterator mit = grps.begin(); - - bool grpMatch = true, grpMetaMatch = true; - - for(; mit != grps.end(); mit++) - { - const std::string grpId = mit->first->grpId; - - // check if it exists - if(gR.find(grpId) == gR.end()) { - grpMatch = false; - break; - } - - RsNxsGrp *l = mit->first, - *r = gR[grpId]; - - // assign transaction number - // to right to as tn is not stored - // in db - r->transactionNumber = l->transactionNumber; - - // then do a comparison - if(!( *l == *r)) { - grpMatch = false; - break; - } - - // now do a comparison of grp meta types - - if(grpMetaR.find(grpId) == grpMetaR.end()) - { - grpMetaMatch = false; - break; - } - - RsGxsGrpMetaData *l_Meta = mit->second, - *r_Meta = grpMetaR[grpId]; - - if(!(*l_Meta == *r_Meta)) - { - grpMetaMatch = false; - break; - } - - /* release resources */ - delete l_Meta; - delete r_Meta; - delete l; - delete r; - - remove(grpId.c_str()); - } - - grpMetaR.clear(); - - CHECK(grpMatch); - tearDown(); -} - -/*! - * Test for both selective and - * bulk msg retrieval - */ -void test_messageStoresAndRetrieve() -{ - setUp(); - - // first create a grpId - std::string grpId0, grpId1; - - randString(SHORT_STR, grpId0); - randString(SHORT_STR, grpId1); - std::vector grpV; // stores grpIds of all msgs stored and retrieved - grpV.push_back(grpId0); - grpV.push_back(grpId1); - - std::map msgs; - std::map msgs_copy; - RsNxsMsg* msg = NULL; - RsGxsMsgMetaData* msgMeta = NULL; - int nMsgs = rand()%120; - GxsMsgReq req; - - std::map VergrpId0, VergrpId1; - std::map VerMetagrpId0, VerMetagrpId1; - - for(int i=0; i p(msg, msgMeta); - int chosen = 0; - if(rand()%50 > 24){ - chosen = 1; - - } - - const std::string& grpId = grpV[chosen]; - - if(chosen) - req[grpId].push_back(msg->msgId); - - msgMeta->mMsgId = msg->msgId; - msgMeta->mGroupId = msg->grpId = grpId; - - RsNxsMsg* msg_copy = new RsNxsMsg(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); - RsGxsMsgMetaData* msgMeta_copy = new RsGxsMsgMetaData(); - - *msg_copy = *msg; - *msgMeta_copy = *msgMeta; - - // store msgs in map to use for verification - std::pair vP(msg->msgId, msg_copy); - std::pair vPmeta(msg->msgId, msgMeta_copy); - - if(!chosen) - { - VergrpId0.insert(vP); - VerMetagrpId0.insert(vPmeta); - } - else - { - VergrpId1.insert(vP); - VerMetagrpId0.insert(vPmeta); - } - - - - msg = NULL; - msgMeta = NULL; - - msgs.insert(p); - msgs_copy.insert(std::make_pair(msg_copy, msgMeta_copy)); - } - - req[grpV[0]] = std::vector(); // assign empty list for other - - dStore->storeMessage(msgs); - msgs.clear(); - msgs = msgs_copy; - - // now retrieve msgs for comparison - // first selective retrieval - - GxsMsgResult msgResult; - GxsMsgMetaResult msgMetaResult; - dStore->retrieveNxsMsgs(req, msgResult, false); - - dStore->retrieveGxsMsgMetaData(req, msgMetaResult); - - // now look at result for grpId 1 - std::vector& result0 = msgResult[grpId0]; - std::vector& result1 = msgResult[grpId1]; - std::vector& resultMeta0 = msgMetaResult[grpId0]; - std::vector& resultMeta1 = msgMetaResult[grpId1]; - - - - bool msgGrpId0_Match = true, msgGrpId1_Match = true; - bool msgMetaGrpId0_Match = true, msgMetaGrpId1_Match = true; - - // MSG test, selective retrieval - for(std::vector::size_type i = 0; i < result0.size(); i++) - { - RsNxsMsg* l = result0[i] ; - - if(VergrpId0.find(l->msgId) == VergrpId0.end()) - { - msgGrpId0_Match = false; - break; - } - - RsNxsMsg* r = VergrpId0[l->msgId]; - r->transactionNumber = l->transactionNumber; - - if(!(*l == *r)) - { - msgGrpId0_Match = false; - break; - } - } - - CHECK(msgGrpId0_Match); - - // META test - for(std::vector::size_type i = 0; i < resultMeta0.size(); i++) - { - RsGxsMsgMetaData* l = resultMeta0[i] ; - - if(VerMetagrpId0.find(l->mMsgId) == VerMetagrpId0.end()) - { - msgMetaGrpId0_Match = false; - break; - } - - RsGxsMsgMetaData* r = VerMetagrpId0[l->mMsgId]; - - if(!(*l == *r)) - { - msgMetaGrpId0_Match = false; - break; - } - } - - CHECK(msgMetaGrpId0_Match); - - // MSG test, bulk retrieval - for(std::vector::size_type i = 0; i < result1.size(); i++) - { - RsNxsMsg* l = result1[i] ; - - if(VergrpId1.find(l->msgId) == VergrpId1.end()) - { - msgGrpId1_Match = false; - break; - } - - RsNxsMsg* r = VergrpId1[l->msgId]; - - r->transactionNumber = l->transactionNumber; - - if(!(*l == *r)) - { - msgGrpId1_Match = false; - break; - } - } - - CHECK(msgGrpId1_Match); - - //dStore->retrieveGxsMsgMetaData(); - std::string msgFile = grpId0 + "-msgs"; - remove(msgFile.c_str()); - msgFile = grpId1 + "-msgs"; - remove(msgFile.c_str()); - tearDown(); -} - - - -void setUp(){ - dStore = new RsDataService(".", DATA_BASE_NAME, RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -void tearDown(){ - - dStore->resetDataStore(); // reset to clean up store files except db - delete dStore; - dStore = NULL; - int rc = remove(DATA_BASE_NAME); - - if(rc == 0){ - std::cerr << "Successful tear down" << std::endl; - } - else{ - std::cerr << "Tear down failed" << std::endl; - perror("Error: "); - } - -} - diff --git a/libretroshare/src/tests/gxs/data_service/rsdataservice_test.h b/libretroshare/src/tests/gxs/data_service/rsdataservice_test.h deleted file mode 100644 index 89d4a4f5c..000000000 --- a/libretroshare/src/tests/gxs/data_service/rsdataservice_test.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RSDATASERVICE_TEST_H -#define RSDATASERVICE_TEST_H - -#include "util/rsthreads.h" -#include "serialiser/rsnxsitems.h" -#include "gxs/rsgds.h" - -void test_messageStoresAndRetrieve(); - -void test_groupStoreAndRetrieve(); - -void test_storeAndDeleteGroup(); -void test_storeAndDeleteMessage(); - -void test_searchMsg(); -void test_searchGrp(); - -bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r); -bool operator ==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r); - -void test_multiThreaded(); - -class DataReadWrite : RsThread -{ - - - -}; - -void test_cacheSize(); - - -#endif // RSDATASERVICE_TEST_H diff --git a/libretroshare/src/tests/gxs/data_service/rsgxsdata_test.cc b/libretroshare/src/tests/gxs/data_service/rsgxsdata_test.cc deleted file mode 100644 index fa5dc3c6b..000000000 --- a/libretroshare/src/tests/gxs/data_service/rsgxsdata_test.cc +++ /dev/null @@ -1,78 +0,0 @@ - -#include "support.h" -#include "data_support.h" -#include "gxs/rsgxsdata.h" -#include "util/utest.h" - -INITTEST(); - -bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r); -bool operator ==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r); - -int main() -{ - - RsGxsGrpMetaData grpMeta1, grpMeta2; - RsGxsMsgMetaData msgMeta1, msgMeta2; - - grpMeta1.clear(); - init_item(&grpMeta1); - - msgMeta1.clear(); - init_item(&msgMeta1); - - uint32_t pktsize = grpMeta1.serial_size(); - char grp_data[pktsize]; - - bool ok = true; - - ok &= grpMeta1.serialise(grp_data, pktsize); - grpMeta2.clear(); - ok &= grpMeta2.deserialise(grp_data, pktsize); - - CHECK(grpMeta1 == grpMeta2); - - pktsize = msgMeta1.serial_size(); - char msg_data[pktsize]; - - ok &= msgMeta1.serialise(msg_data, &pktsize); - msgMeta2.clear(); - ok &= msgMeta2.deserialise(msg_data, &pktsize); - - CHECK(msgMeta1 == msgMeta2); - - FINALREPORT("GxsMeta Data Test"); - - return TESTRESULT(); -} - - -bool operator ==(const RsGxsGrpMetaData& l, const RsGxsGrpMetaData& r) -{ - if(!(l.signSet == r.signSet)) return false; - if(!(l.keys == r.keys)) return false; - if(l.mGroupFlags != r.mGroupFlags) return false; - if(l.mPublishTs != r.mPublishTs) return false; - if(l.mAuthorId != r.mAuthorId) return false; - if(l.mGroupName != r.mGroupName) return false; - if(l.mGroupId != r.mGroupId) return false; - - return true; -} - -bool operator ==(const RsGxsMsgMetaData& l, const RsGxsMsgMetaData& r) -{ - - if(!(l.signSet == r.signSet)) return false; - if(l.mGroupId != r.mGroupId) return false; - if(l.mAuthorId != r.mAuthorId) return false; - if(l.mParentId != r.mParentId) return false; - if(l.mOrigMsgId != r.mOrigMsgId) return false; - if(l.mThreadId != r.mThreadId) return false; - if(l.mMsgId != r.mMsgId) return false; - if(l.mMsgName != r.mMsgName) return false; - if(l.mPublishTs != r.mPublishTs) return false; - if(l.mMsgFlags != r.mMsgFlags) return false; - - return true; -} diff --git a/libretroshare/src/tests/gxs/gen_exchange/genexchange_test.pro b/libretroshare/src/tests/gxs/gen_exchange/genexchange_test.pro deleted file mode 100644 index d95c4bcd4..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/genexchange_test.pro +++ /dev/null @@ -1,180 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2012-05-06T09:19:26 -# -#------------------------------------------------- - - -# -QT += core network - -QT -= gui - -CONFIG += gen_exchange_target - - -CONFIG += bitdht - - - -TARGET = gen_exchange_test - -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -CONFIG += debug - -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 -} -################################# Linux ########################################## -# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib -linux-* { - #CONFIG += version_detail_bash_script - QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 - - system(which gpgme-config >/dev/null 2>&1) { - INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - } else { - message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - } - - PRE_TARGETDEPS *= ../../../lib/libretroshare.a - - LIBS += ../../../lib/libretroshare.a - LIBS += ../../../../../libbitdht/src/lib/libbitdht.a - LIBS += ../../../../../openpgpsdk/src/lib/libops.a - LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lbz2 - # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. - LIBS += /home/crispy/Development/retroshare/sqlcipher/sqlcipher/.libs/libsqlite3.a - LIBS *= -rdynamic -frtti - DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions - DEFINES *= HAS_GNOME_KEYRING -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -#################################### Windows ##################################### - -win32 { - - DEFINES *= WINDOWS_SYS \ - WIN32 \ - STATICLIB \ - MINGW - # 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 - -# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a - PRE_TARGETDEPS += ../../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - - LIBS += ../../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a - LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a - LIBS += -L"../../../../../lib" - LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 -# added after bitdht -# LIBS += -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 - LIBS += -lole32 -lwinmm - - # export symbols for the plugins - #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a - - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 - GPGME_DIR = ../../../../lib/gpgme-1.1.8 - SSL_DIR = ../../../../../OpenSSL - OPENPGPSDK_DIR = ../../../../openpgpsdk/src - INCLUDEPATH += . $${SSL_DIR}/include $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src \ - $${OPENPGPSDK_DIR} - - SQLITE_DIR = ../../../../../../Libraries/sqlite/sqlite-autoconf-3070900 - INCLUDEPATH += . \ - $${SQLITE_DIR} - - - - -} - -bitdht { - - # Chris version. - #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a -} - -win32 { -# must be added after bitdht - LIBS += -lws2_32 -} - -version_detail_bash_script { - DEFINES += ADD_LIBRETROSHARE_VERSION_INFO - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh -} - -install_rs { - INSTALLS += binary_rs - binary_rs.path = $$(PREFIX)/usr/bin - binary_rs.files = ./RetroShare -} - - -gen_exchange_target { - - SOURCES += \ - ../common/support.cc \ - genexchangetester.cpp \ - genexchangetestservice.cpp \ - rsdummyservices.cc \ - gxspublishgrouptest.cc \ - gxspublishmsgtest.cc \ - rsgenexchange_test.cc - - HEADERS += ../common/support.h \ - ../data_service/rsdataservice_test.h \ - gxspublishgrouptest.h \ - gxspublishmsgtest.h \ - rsdummyservices.h \ - ../common/data_support.h \ - ../common/support.h - -} - - -INCLUDEPATH += ../../../ -INCLUDEPATH += ../common diff --git a/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.cpp b/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.cpp deleted file mode 100644 index f46594d9a..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.cpp +++ /dev/null @@ -1,589 +0,0 @@ -#include "genexchangetester.h" -#include "support.h" -#include "gxs/rsdataservice.h" -#include "retroshare/rsgxsflags.h" - - -GenExchangeTest::GenExchangeTest(GenExchangeTestService* const mTestService, RsGeneralDataService* dataService, int pollingTO) - : mDataService(dataService), mTestService(mTestService), mTokenService(mTestService->getTokenService()), - mPollingTO(pollingTO) -{ -} - -GenExchangeTest::~GenExchangeTest() -{ -} - - -void GenExchangeTest::pollForToken(uint32_t token, const RsTokReqOptions &opts, bool fill) -{ - double timeDelta = 0.2; - rstime_t now = time(NULL); - rstime_t stopw = now + mPollingTO; - - while(now < stopw) - { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - - if((RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == mTokenService->requestStatus(token))) - { - switch(opts.mReqType) - { - case GXS_REQUEST_TYPE_GROUP_DATA: - if(fill) - mTestService->getGroupDataTS(token, mGrpDataIn); - break; - case GXS_REQUEST_TYPE_GROUP_META: - if(fill) - mTestService->getGroupMetaTS(token, mGrpMetaDataIn); - break; - case GXS_REQUEST_TYPE_GROUP_IDS: - if(fill) - mTestService->getGroupListTS(token, mGrpIdsIn); - break; - case GXS_REQUEST_TYPE_MSG_DATA: - if(fill) - mTestService->getMsgDataTS(token, mMsgDataIn); - break; - case GXS_REQUEST_TYPE_MSG_META: - if(fill) - mTestService->getMsgMetaTS(token, mMsgMetaDataIn); - break; - case GXS_REQUEST_TYPE_MSG_IDS: - if(fill) - mTestService->getMsgListTS(token, mMsgIdsIn); - break; - case GXS_REQUEST_TYPE_MSG_RELATED_IDS: - if(fill) - mTestService->getMsgRelatedListTS(token, mMsgRelatedIdsIn); - break; - case GXS_REQUEST_TYPE_MSG_RELATED_DATA: - if(fill) - mTestService->getMsgRelatedDataTS(token, mMsgRelatedDataMapIn); - break; - } - break; - } - else if(RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == mTokenService->requestStatus(token)) - { - mTokenService->cancelRequest(token); - break; - } - now = time(NULL); - } -} - - - -bool GenExchangeTest::pollForMsgAcknowledgement(uint32_t token, - RsGxsGrpMsgIdPair& msgId) -{ - double timeDelta = 0.2; - - rstime_t now = time(NULL); - rstime_t stopw = now + mPollingTO; - - while(now < stopw) - { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - - if((RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == mTokenService->requestStatus(token))) - { - mTestService->acknowledgeTokenMsg(token, msgId); - return true; - } - else if(RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == mTokenService->requestStatus(token)) - { - mTokenService->cancelRequest(token); - return false; - } - now = time(NULL); - } - return false; -} - -GenExchangeTestService* GenExchangeTest::getTestService() -{ - return mTestService; -} - -RsTokenService* GenExchangeTest::getTokenService() -{ - return mTokenService; -} -bool GenExchangeTest::pollForGrpAcknowledgement(uint32_t token, - RsGxsGroupId& grpId) -{ - double timeDelta = 0.2; - rstime_t now = time(NULL); - rstime_t stopw = now + mPollingTO; - while(now < stopw) - { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - - if((RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE == mTokenService->requestStatus(token))) - { - mTestService->acknowledgeTokenGrp(token, grpId); - return true; - } - else if(RsTokenService::GXS_REQUEST_V2_STATUS_FAILED == mTokenService->requestStatus(token)) - { - mTokenService->cancelRequest(token); - return false; - } - now = time(NULL); - } - return false; -} - -void GenExchangeTest::setUp() -{ - mDataService->resetDataStore(); - - // would be useful for genexchange services - // to have a protected reset button - mTestService->start(); -} - -void GenExchangeTest::breakDown() -{ - mDataService->resetDataStore(); - mTestService->join(); - clearAllData(); -} - -bool msgDataSort(const RsDummyMsg* m1, const RsDummyMsg* m2) -{ - return m1->meta.mMsgId < m2->meta.mMsgId; -} - -bool GenExchangeTest::compareMsgDataMaps() -{ - DummyMsgMap::iterator mit = mMsgDataOut.begin(); - - bool ok = true; - for(; mit != mMsgDataOut.end(); mit++) - { - const RsGxsGroupId& grpId = mit->first; - std::vector& v1 = mit->second, - &v2 = mMsgDataIn[grpId]; - - if(v1.size() != v2.size()) - return false; - - std::sort(v1.begin(), v1.end(), msgDataSort); - std::sort(v2.begin(), v2.end(), msgDataSort); - - ok &= Comparison, RsDummyMsg*>::comparison(v1, v2); - } - - return ok; -} - - -bool GenExchangeTest::compareMsgIdMaps() -{ - GxsMsgIdResult::const_iterator mit = mMsgIdsOut.begin(); - bool ok = true; - for(; mit != mMsgIdsOut.end(); mit++) - { - const RsGxsGroupId& grpId = mit->first; - const std::vector& v1 = mit->second, - &v2 = mMsgIdsIn[grpId]; - - ok &= Comparison, RsGxsMessageId>::comparison(v1, v2); - } - return ok; -} - - -bool GenExchangeTest::compareMsgMetaMaps() -{ - GxsMsgMetaMap::iterator mit = mMsgMetaDataOut.begin(); - bool ok = true; - for(; mit != mMsgMetaDataOut.end(); mit++) - { - const RsGxsGroupId& grpId = mit->first; - const std::vector& v1 = mit->second, - &v2 = mMsgMetaDataOut[grpId]; - ok &= Comparison, RsMsgMetaData>::comparison(v1, v2); - } - return ok; -} - - -bool GenExchangeTest::compareMsgRelateIdsMap() -{ - return false; -} - - -bool GenExchangeTest::compareMsgRelatedDataMap() -{ - return false; -} - -bool grpDataSort(const RsDummyGrp* g1, const RsDummyGrp* g2) -{ - return g1->meta.mGroupId < g2->meta.mGroupId; -} - -bool GenExchangeTest::compareGrpData() -{ - - std::sort(mGrpDataIn.begin(), mGrpDataIn.end(), grpDataSort); - std::sort(mGrpDataOut.begin(), mGrpDataOut.end(), grpDataSort); - bool ok = Comparison, RsDummyGrp*>::comparison - (mGrpDataIn, mGrpDataOut); - return ok; -} - -bool operator<(const RsGroupMetaData& l, const RsGroupMetaData& r) -{ - return l.mGroupId < r.mGroupId; -} - -bool GenExchangeTest::compareGrpMeta() -{ - - mGrpMetaDataIn.sort(); - mGrpMetaDataOut.sort(); - - bool ok = Comparison, RsGroupMetaData>::comparison - (mGrpMetaDataIn, mGrpMetaDataOut); - return ok; -} - - -bool GenExchangeTest::compareGrpIds() -{ - mGrpIdsIn.sort(); - mGrpIdsOut.sort(); - bool ok = Comparison, RsGxsGroupId>::comparison - (mGrpIdsIn, mGrpIdsOut); - return ok; -} - -void GenExchangeTest::createGrps(uint32_t nGrps, - std::list& groupId) -{ - // create n groups and publish all nGrps and collect id information - for(uint32_t i=0; i < nGrps; i++) - { - RsDummyGrp* grp = new RsDummyGrp(); - init(*grp); - uint32_t token; - mTestService->publishDummyGrp(token, grp); - RsGxsGroupId grpId; - pollForGrpAcknowledgement(token, grpId); - groupId.push_back(grpId); - } -} - -void GenExchangeTest::init(RsMsgMetaData& msgMetaData) const -{ - //randString(SHORT_STR, msgMeta.mAuthorId); - randString(SHORT_STR, msgMetaData.mMsgName); - randString(SHORT_STR, msgMetaData.mServiceString); - randString(SHORT_STR, msgMetaData.mOrigMsgId); - randString(SHORT_STR, msgMetaData.mParentId); - randString(SHORT_STR, msgMetaData.mThreadId); - randString(SHORT_STR, msgMetaData.mGroupId); - - msgMetaData.mChildTs = randNum(); - msgMetaData.mMsgStatus = randNum(); - msgMetaData.mMsgFlags = randNum(); - msgMetaData.mPublishTs = randNum(); -} - -uint32_t GenExchangeTest::randNum() const -{ - return rand()%23562424; -} - -void GenExchangeTest::init(RsGroupMetaData& grpMetaData) const -{ - randString(SHORT_STR, grpMetaData.mGroupId); - //randString(SHORT_STR, grpMetaData.mAuthorId); - randString(SHORT_STR, grpMetaData.mGroupName); - randString(SHORT_STR, grpMetaData.mServiceString); - - - grpMetaData.mGroupFlags = randNum(); - grpMetaData.mLastPost = randNum(); - grpMetaData.mGroupStatus = randNum(); - grpMetaData.mMsgCount = randNum(); - grpMetaData.mPop = randNum(); - grpMetaData.mSignFlags = randNum(); - grpMetaData.mPublishTs = randNum(); - grpMetaData.mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; -} - -void GenExchangeTest::init(RsDummyGrp& grpItem) const -{ - randString(SHORT_STR, grpItem.grpData); - init(grpItem.meta); -} - - -void GenExchangeTest::init(RsDummyMsg& msgItem) const -{ - randString(SHORT_STR, msgItem.msgData); - init(msgItem.meta); -} - -void GenExchangeTest::storeToMsgDataOutMaps(const DummyMsgMap& msgDataOut) -{ - mMsgDataOut.insert(msgDataOut.begin(), msgDataOut.end()); -} - - -void GenExchangeTest::storeToMsgIdsOutMaps(const GxsMsgIdResult& msgIdsOut) -{ - mMsgIdsOut.insert(msgIdsOut.begin(), msgIdsOut.end()); -} - - -void GenExchangeTest::storeToMsgMetaOutMaps(const GxsMsgMetaMap& msgMetaOut) -{ - mMsgMetaDataOut.insert(msgMetaOut.begin(), msgMetaOut.end()); -} - - -void GenExchangeTest::storeToMsgDataInMaps(const DummyMsgMap& msgDataIn) -{ - mMsgDataIn.insert(msgDataIn.begin(), msgDataIn.end()); -} - - -void GenExchangeTest::storeToMsgIdsInMaps(const GxsMsgIdResult& msgIdsIn) -{ - mMsgIdsIn.insert(msgIdsIn.begin(), msgIdsIn.end()); -} - - -void GenExchangeTest::storeToMsgMetaInMaps(const GxsMsgMetaMap& msgMetaIn) -{ - mMsgMetaDataIn.insert(msgMetaIn.begin(), msgMetaIn.end()); -} - - -void GenExchangeTest::storeToGrpIdsOutList( - const std::list& grpIdOut) -{ - mGrpIdsOut.insert(mGrpIdsOut.end(), grpIdOut.begin(), grpIdOut.end()); -} - - -void GenExchangeTest::storeToGrpMetaOutList( - const std::list& grpMetaOut) -{ - mGrpMetaDataOut.insert(mGrpMetaDataOut.end(), grpMetaOut.begin(), grpMetaOut.end()); -} - - -void GenExchangeTest::storeToGrpDataOutList( - const std::vector& grpDataOut) -{ - mGrpDataOut.insert(mGrpDataOut.end(), grpDataOut.begin(), grpDataOut.end()); -} - - -void GenExchangeTest::storeToGrpIdsInList( - const std::list& grpIdIn) -{ - mGrpIdsIn.insert(mGrpIdsIn.end(), grpIdIn.begin(), grpIdIn.end()); -} - - -void GenExchangeTest::storeToGrpMetaInList( - const std::list& grpMetaIn) -{ - mGrpMetaDataIn.insert(mGrpMetaDataIn.end(), grpMetaIn.begin(), grpMetaIn.end()); -} - - -void GenExchangeTest::storeToGrpDataInList( - const std::vector& grpDataIn) -{ - mGrpDataIn.insert(mGrpDataIn.begin(), grpDataIn.begin(), grpDataIn.end()); -} -void GenExchangeTest::clearAllData() -{ - clearMsgDataInMap(); - clearMsgDataOutMap(); - clearMsgIdInMap(); - clearMsgIdOutMap(); - clearMsgMetaInMap(); - clearMsgMetaOutMap(); - clearGrpDataInList(); - clearGrpDataOutList(); - clearGrpMetaInList(); - clearGrpMetaOutList(); - clearGrpIdInList(); - clearGrpIdOutList(); -} -void GenExchangeTest::clearMsgDataInMap() -{ - mMsgDataIn.clear(); -} - - -void GenExchangeTest::clearMsgDataOutMap() -{ - - clearMsgDataMap(mMsgDataOut); -} - -void GenExchangeTest::clearMsgDataMap(DummyMsgMap& msgDataMap) const -{ - DummyMsgMap::iterator it = msgDataMap.begin(); - - for(; it != msgDataMap.end(); it++) - { - deleteResVector(it->second); - } -} - -void GenExchangeTest::clearMsgMetaInMap() -{ - mMsgMetaDataIn.clear(); -} - - -void GenExchangeTest::clearMsgMetaOutMap() -{ - mMsgMetaDataOut.clear(); -} - - -void GenExchangeTest::clearMsgIdInMap() -{ - mMsgIdsIn.clear(); -} - - -void GenExchangeTest::clearMsgIdOutMap() -{ - mMsgIdsOut.clear(); -} - - -void GenExchangeTest::clearMsgRelatedIdInMap() -{ - mMsgRelatedIdsIn.clear(); -} - - -void GenExchangeTest::clearGrpDataInList() -{ - clearGrpDataList(mGrpDataIn); -} - -void GenExchangeTest::clearGrpDataList(std::vector& grpData) const -{ - deleteResVector(grpData); -} - - -void GenExchangeTest::clearGrpDataOutList() -{ - clearGrpDataList(mGrpDataOut); -} - - -void GenExchangeTest::clearGrpMetaInList() -{ - mGrpMetaDataIn.clear(); -} - - -void GenExchangeTest::clearGrpMetaOutList() -{ - mGrpMetaDataOut.clear(); -} - - -void GenExchangeTest::clearGrpIdInList() -{ - mGrpIdsIn.clear(); -} - - -void GenExchangeTest::clearGrpIdOutList() -{ - mGrpIdsOut.clear(); -} - - -bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta) -{ - - if(lMeta.mAuthorId != rMeta.mAuthorId) return false; - if(lMeta.mChildTs != rMeta.mChildTs) return false; - if(lMeta.mGroupId != rMeta.mGroupId) return false; - if(lMeta.mMsgFlags != rMeta.mMsgFlags) return false; - if(lMeta.mMsgId != rMeta.mMsgId) return false; - if(lMeta.mMsgName != rMeta.mMsgName) return false; - //if(lMeta.mMsgStatus != rMeta.mMsgStatus) return false; - if(lMeta.mOrigMsgId != rMeta.mOrigMsgId) return false; - if(lMeta.mParentId != rMeta.mParentId) return false; - //if(lMeta.mPublishTs != rMeta.mPublishTs) return false; // don't compare this as internally set in gxs - if(lMeta.mThreadId != rMeta.mThreadId) return false; - if(lMeta.mServiceString != rMeta.mServiceString) return false; - - return true; -} - -bool operator ==(const RsGroupMetaData& lMeta, const RsGroupMetaData& rMeta) -{ - if(lMeta.mAuthorId != rMeta.mAuthorId) return false; - if(lMeta.mGroupFlags != rMeta.mGroupFlags) return false; - if(lMeta.mGroupId != rMeta.mGroupId) return false; - if(lMeta.mGroupName != rMeta.mGroupName) return false; - if(lMeta.mGroupStatus != rMeta.mGroupStatus) return false; - if(lMeta.mLastPost != rMeta.mLastPost) return false; - if(lMeta.mMsgCount != rMeta.mMsgCount) return false; - if(lMeta.mPop != rMeta.mPop) return false; - // if(lMeta.mPublishTs != rMeta.mPublishTs) return false; set in gxs - if(lMeta.mServiceString != rMeta.mServiceString) return false; - if(lMeta.mSignFlags != rMeta.mSignFlags) return false; - // if(lMeta.mSubscribeFlags != rMeta.mSubscribeFlags) return false; - - return true; -} - -bool operator ==(const RsDummyGrp& lGrp, const RsDummyGrp& rGrp) -{ - - if(lGrp.grpData != rGrp.grpData) return false; - if(! (lGrp.meta == rGrp.meta)) return false; - - return true; -} - -bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg) -{ - if(lMsg.msgData != rMsg.msgData) return false; - if(!(lMsg.meta == rMsg.meta)) return false; - - return true; -} - -bool operator ==(const RsGxsGrpItem& lGrp, const RsGxsGrpItem& rGrp) -{ - return false; -} - diff --git a/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.h b/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.h deleted file mode 100644 index 13bb1cf6e..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/genexchangetester.h +++ /dev/null @@ -1,278 +0,0 @@ -#ifndef GENEXCHANGETESTER_H -#define GENEXCHANGETESTER_H - -#include "genexchangetestservice.h" -#include "gxs/rsgds.h" -#include "gxs/rsnxs.h" - -bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta); -bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg); -bool operator ==(const RsGxsGrpItem& lMsg, const RsGxsGrpItem& rMsg); - -bool operator ==(const RsGroupMetaData& lMeta, const RsGroupMetaData& rMeta); -bool operator ==(const RsDummyGrp& lMsg, const RsDummyGrp& rMsg); -bool operator ==(const RsGxsMsgItem& lMsg, const RsGxsMsgItem& rMsg); - -/*! - * The idea of GenExchangeTest is to simplify test - * of the RsGenExchange via the RsGxsDummyService - * One can test all publish/request/meta-modify - * capabilities of RsGenExchange - * Simplifications comes from: \n - * - * - ability to store in and out data for comparison (in data are - * usually from requests, out data are from publications, - * but generally what you want to compare) \n - * - convenience function to poll tokens \n - * - also allows filling in-data automatically from polls \n - * - convenience interface for running tests - */ -class GenExchangeTest -{ -public: - - /*! - * Constructs the GenExchangeTest with a tokenService - * @param tokenService This is needed. If not an instance of token service, - * behaviour of GenExchangeTest is undefined - */ - GenExchangeTest(GenExchangeTestService* const mTestService, RsGeneralDataService* dataService, int pollingTO = 5 /* 5 secs default */); - - virtual ~GenExchangeTest(); - - /*! - * This should be called in the main - * routines to execute all tests - * When implementing ensure units test header - * is in same file scope as implementation - * (you chould be using the CHECK functions - * to assert tests has passed) - */ - virtual void runTests() = 0; - -protected: - - /*! - * After each request and publish operation this should - * be called to ensure the operation has completed - * Requests will result in in data maps being filled - * @param - * @param opts - * @param fill if set to true, the received that is - * routed to IN data structures - */ - void pollForToken(uint32_t token, const RsTokReqOptions& opts, bool fill = false); - - /*! - * Allows to poll for token, and receive the message id - * as acknowledgement. This function blocks for as long the - * timeout value set on construction of tester - * @param token - * @param msgId - */ - bool pollForMsgAcknowledgement(uint32_t token, RsGxsGrpMsgIdPair& msgId); - - /*! - * Allows to poll for token, and receive the group id - * as acknowledgement. This function blocks for as long the - * timeout value set on construction of tester - * @param token - * @param msgId - */ - bool pollForGrpAcknowledgement(uint32_t token, RsGxsGroupId& msgId); - - GenExchangeTestService* getTestService(); - RsTokenService* getTokenService(); -// bool testGrpMetaModRequest(); -// bool testMsgMetaModRequest(); - - // convenience functions for clearing IN and OUT data structures - void clearMsgDataInMap(); - void clearMsgDataOutMap(); - void clearMsgMetaInMap(); - void clearMsgMetaOutMap(); - void clearMsgIdInMap(); - void clearMsgIdOutMap(); - void clearMsgRelatedIdInMap(); - void clearGrpDataInList(); - void clearGrpDataOutList(); - void clearGrpMetaInList(); - void clearGrpMetaOutList(); - void clearGrpIdInList(); - void clearGrpIdOutList(); - - /*! - * clears up all internal - * IN and OUT data structure for - * both msgs and groups - * frees resources in relation to allocated data - */ - void clearAllData(); - - template - void deleteResVector(std::vector& v) const - { - typename std::vector::iterator vit = v.begin(); - for(; vit != v.end(); vit++) - delete *vit; - v.clear(); - } - - // using class to enable partial - // function specialisation, bit of a hack in a - // way - template - class Comparison - { - public: - - static bool comparison(const Cont& l, const Cont& r) - { - if(l.size() != r.size()) return false; - - typename Cont::const_iterator vit1 = l.begin(), vit2 = r.begin(); - - while(vit1 != l.end()) - { - const Item& item1 = (*vit1); - const Item& item2 = (*vit2); - if(!(item1 == item2)) return false; - - vit1++; - vit2++; - } - return true; - } - }; - - - template - class Comparison - { - public: - - static bool comparison(const Cont& l, const Cont& r) - { - if(l.size() != r.size()) - return false; - - typename Cont::const_iterator vit1 = l.begin(), vit2 = r.begin(); - - while(vit1 != l.end()) - { - const Item* item1 = (*vit1); - const Item* item2 = (*vit2); - if(!(*item1 == *item2)) - return false; - - vit1++; - vit2++; - } - return true; - } - }; - - // convenience function for comparing IN and OUT data structures - bool compareMsgDataMaps() ; - bool compareMsgIdMaps() ; - bool compareMsgMetaMaps() ; - bool compareMsgRelateIdsMap() ; - bool compareMsgRelatedDataMap() ; - bool compareGrpData() ; - bool compareGrpMeta() ; - bool compareGrpIds() ; - - void storeToMsgDataOutMaps(const DummyMsgMap& msgDataOut); - void storeToMsgIdsOutMaps(const GxsMsgIdResult& msgIdsOut); - void storeToMsgMetaOutMaps(const GxsMsgMetaMap& msgMetaOut); - - void storeToMsgDataInMaps(const DummyMsgMap& msgDataOut); - void storeToMsgIdsInMaps(const GxsMsgIdResult& msgIdsOut); - void storeToMsgMetaInMaps(const GxsMsgMetaMap& msgMetaOut); - - void storeToGrpIdsOutList(const std::list& grpIdOut); - void storeToGrpMetaOutList(const std::list& grpMetaOut); - void storeToGrpDataOutList(const std::vector& grpDataOut); - - void storeToGrpIdsInList(const std::list& grpIdIn); - void storeToGrpMetaInList(const std::list& grpMetaOut); - void storeToGrpDataInList(const std::vector& grpDataOut); - - /*! - * This sets up any resources required to operate a test - */ - void setUp(); - - /*! - * Call at end of test to ensure resources - * used in tests are released - * This can invalidate other test runs if not called - */ - void breakDown(); - - /*! - * initialises item to random data - * @param grpItem item to initialise - */ - void init(RsDummyGrp& grpItem) const; - - /*! - * Initialises meta data to random data - * @param grpMetaData - */ - void init(RsGroupMetaData& grpMetaData) const; - - /*! - * Initialises msg item to random data - * @param msgItem - */ - void init(RsDummyMsg& msgItem) const; - - /*! - * Initialises meta data to random data - * @param msgMetaData - */ - void init(RsMsgMetaData& msgMetaData) const; - - - void clearMsgDataMap(DummyMsgMap& msgDataMap) const; - void clearGrpDataList(std::vector& grpData) const; - - /*! - * Helper function which sets up groups - * data in to be used for publication - * group data - * @param nGrps number of groups to publish - * @param groupId the ids for the created groups - */ - void createGrps(uint32_t nGrps, std::list& groupId); - - /*! - * @return random number - */ - uint32_t randNum() const; - -private: - - std::vector mGrpDataOut, mGrpDataIn; - std::list mGrpMetaDataOut, mGrpMetaDataIn; - std::list mGrpIdsOut, mGrpIdsIn; - - std::map > mMsgDataOut, mMsgDataIn; - GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn; - GxsMsgIdResult mMsgIdsOut, mMsgIdsIn; - - MsgRelatedIdResult mMsgRelatedIdsOut, mMsgRelatedIdsIn; - GxsMsgRelatedDataMap mMsgRelatedDataMapOut, mMsgRelatedDataMapIn; - - std::vector mRandGrpIds; // ids that exist to help group testing - -private: - - RsGeneralDataService* mDataService; - GenExchangeTestService* mTestService; - RsTokenService* mTokenService; - int mPollingTO; -}; - -#endif // GENEXCHANGETESTER_H diff --git a/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.cpp b/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.cpp deleted file mode 100644 index dd9ba328a..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "genexchangetestservice.h" - -GenExchangeTestService::GenExchangeTestService(RsGeneralDataService *dataServ, RsNetworkExchangeService * netService, - RsGixs* gixs) - : RsGenExchange(dataServ, netService, new RsDummySerialiser(), RS_SERVICE_TYPE_DUMMY, gixs, 0) -{ - -} - -void GenExchangeTestService::notifyChanges(std::vector &changes) -{ - return; -} - -void GenExchangeTestService::publishDummyGrp(uint32_t &token, RsDummyGrp *grp) -{ - publishGroup(token, grp); -} - -void GenExchangeTestService::updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta, RsDummyGrp *group) -{ - updateGroup(token, updateMeta, group); -} - -void GenExchangeTestService::publishDummyMsg(uint32_t &token, RsDummyMsg *msg) -{ - publishMsg(token, msg); -} - -bool GenExchangeTestService::getGroupListTS(const uint32_t &token, std::list &groupIds) -{ - return getGroupList(token, groupIds); -} - -bool GenExchangeTestService::getGroupMetaTS(const uint32_t &token, std::list &groupInfo) -{ - return getGroupMeta(token, groupInfo); -} - -bool GenExchangeTestService::getGroupDataTS(const uint32_t &token, std::vector& grpItem) -{ - return getGroupDataT(token, grpItem); -} - -bool GenExchangeTestService::getMsgDataTS(const uint32_t &token, DummyMsgMap &msgItems) -{ - return getMsgDataT(token, msgItems); -} - -bool GenExchangeTestService::getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap &msgItems) -{ - return getMsgRelatedData(token, msgItems); -} - -bool GenExchangeTestService::getMsgMetaTS(const uint32_t &token, GxsMsgMetaMap &msgInfo) -{ - return getMsgMeta(token, msgInfo); -} - -bool GenExchangeTestService::getMsgListTS(const uint32_t &token, GxsMsgIdResult &msgIds) -{ - return getMsgList(token, msgIds); -} - -bool GenExchangeTestService::getMsgRelatedListTS(const uint32_t &token, MsgRelatedIdResult &msgIds) -{ - return getMsgRelatedList(token, msgIds); -} - -void GenExchangeTestService::setGroupServiceStringTS(uint32_t &token, const RsGxsGroupId &grpId, const std::string &servString) -{ - RsGenExchange::setGroupServiceString(token, grpId, servString); -} - -void GenExchangeTestService::setGroupStatusFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) -{ - RsGenExchange::setGroupStatusFlags(token, grpId, status, mask); -} - -void GenExchangeTestService::setGroupSubscribeFlagTS(uint32_t &token, const RsGxsGroupId &grpId, const uint32_t &status, const uint32_t& mask) -{ - RsGenExchange::setGroupSubscribeFlags(token, grpId, status, mask); -} - -void GenExchangeTestService::setMsgServiceStringTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const std::string &servString) -{ - RsGenExchange::setMsgServiceString(token, msgId, servString); -} - -void GenExchangeTestService::setMsgStatusFlagTS(uint32_t &token, const RsGxsGrpMsgIdPair &msgId, const uint32_t &status, const uint32_t& mask) -{ - RsGenExchange::setMsgStatusFlags(token, msgId, status, mask); -} - -void GenExchangeTestService::service_tick() -{ - -} diff --git a/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.h b/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.h deleted file mode 100644 index 588808eb9..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/genexchangetestservice.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef GENEXCHANGETESTSERVICE_H -#define GENEXCHANGETESTSERVICE_H - -#include "gxs/rsgenexchange.h" -#include "retroshare/rsgxsifacehelper.h" -#include "rsdummyservices.h" - -typedef std::map > DummyMsgMap; - -class GenExchangeTestService : public RsGenExchange -{ -public: - GenExchangeTestService(RsGeneralDataService* dataServ, RsNetworkExchangeService* nxs, RsGixs* gixs); - - void notifyChanges(std::vector& changes); - - void publishDummyGrp(uint32_t& token, RsDummyGrp* grp); - void updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsDummyGrp *group); - void publishDummyMsg(uint32_t& token, RsDummyMsg* msg); - - /*! - * Retrieve group list for a given token - * @param token - * @param groupIds - * @return false if token cannot be redeemed, if false you may have tried to redeem when not ready - */ - bool getGroupListTS(const uint32_t &token, std::list &groupIds); - - /*! - * Retrieve msg list for a given token sectioned by group Ids - * @param token token to be redeemed - * @param msgIds a map of grpId -> msgList (vector) - */ - bool getMsgListTS(const uint32_t &token, GxsMsgIdResult &msgIds); - - - /*! - * retrieve group meta data associated to a request token - * @param token - * @param groupInfo - */ - bool getGroupMetaTS(const uint32_t &token, std::list &groupInfo); - - /*! - * retrieves message meta data associated to a request token - * @param token token to be redeemed - * @param msgInfo the meta data to be retrieved for token store here - */ - bool getMsgMetaTS(const uint32_t &token, GxsMsgMetaMap &msgInfo); - - /*! - * retrieves group data associated to a request token - * @param token token to be redeemed for grpitem retrieval - * @param grpItem the items to be retrieved for token are stored here - */ - bool getGroupDataTS(const uint32_t &token, std::vector& grpItem); - - - - /*! - * retrieves message data associated to a request token - * @param token token to be redeemed for message item retrieval - * @param msgItems - */ - bool getMsgDataTS(const uint32_t &token, DummyMsgMap& msgItems); - - /*! - * Retrieve msg related list for a given token sectioned by group Ids - * @param token token to be redeemed - * @param msgIds a map of grpMsgIdPair -> msgList (vector) - */ - bool getMsgRelatedListTS(const uint32_t &token, MsgRelatedIdResult &msgIds); - - /*! - * retrieves msg related data msgItems as a map of msg-grpID pair to vector - * of items - * @param token token to be redeemed - * @param msgItems map of msg items - */ - bool getMsgRelatedDataTS(const uint32_t &token, GxsMsgRelatedDataMap& msgItems); - - - void setGroupSubscribeFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - - void setGroupStatusFlagTS(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask); - - void setGroupServiceStringTS(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString); - - void setMsgStatusFlagTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask); - - void setMsgServiceStringTS(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString ); - - void service_tick(); - -}; - -#endif // GENEXCHANGETESTSERVICE_H diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.cpp b/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.cpp deleted file mode 100644 index 8b2eacd88..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * gxsmsgrelatedtest.cpp - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#include "gxsmsgrelatedtest.h" - -GxsMsgRelatedTest::GxsMsgRelatedTest() { - // TODO Auto-generated constructor stub - -} - -GxsMsgRelatedTest::~GxsMsgRelatedTest() { - // TODO Auto-generated destructor stub -} - diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.h b/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.h deleted file mode 100644 index 2277142d9..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxsmsgrelatedtest.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * gxsmsgrelatedtest.h - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#ifndef GXSMSGRELATEDTEST_H_ -#define GXSMSGRELATEDTEST_H_ - -#include "genexchangetester.h" - -class GxsMsgRelatedTest: public GenExchangeTest { -public: - GxsMsgRelatedTest(); - virtual ~GxsMsgRelatedTest(); - - // request msg related tests - bool testMsgRelatedChildIdRetrieval(); - bool testMsgRelatedChildDataRetrieval(); - bool testMsgRelatedChildDataRetrieval_Multi(); - bool testMsgAllVersions(); -}; - -#endif /* GXSMSGRELATEDTEST_H_ */ diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.cc b/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.cc deleted file mode 100644 index 2fe0d5fac..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.cc +++ /dev/null @@ -1,301 +0,0 @@ -/* - * gxspublishgrouptest.cc - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#include "gxspublishgrouptest.h" -#include "util/utest.h" -#include "support.h" - -#define POLLING_TIME_OUT 5 - -GxsPublishGroupTest::GxsPublishGroupTest(GenExchangeTestService* const testService, - RsGeneralDataService* dataService) - : GenExchangeTest(testService, dataService, POLLING_TIME_OUT) -{ - -} - -GxsPublishGroupTest::~GxsPublishGroupTest() -{ -} - -bool GxsPublishGroupTest::testGrpSubmissionRetrieval() -{ - - setUp(); - - GenExchangeTestService* testService = getTestService(); - RsTokenService* tokenService = getTokenService(); - - // create some random grps to allow msg testing - - RsDummyGrp* dgrp1 = new RsDummyGrp(); - RsDummyGrp* dgrp2 = new RsDummyGrp(); - RsDummyGrp* dgrp3 = new RsDummyGrp(); - - RsDummyGrp* dgrp1_copy = new RsDummyGrp(); - RsDummyGrp* dgrp2_copy = new RsDummyGrp(); - RsDummyGrp* dgrp3_copy = new RsDummyGrp(); - - init(*dgrp1); - init(*dgrp2); - init(*dgrp3); - - RsTokReqOptions opts; - opts.mReqType = 45000; - uint32_t token; - RsGxsGroupId grpId; - - std::vector groupsPublished; - - *dgrp1_copy = *dgrp1; - testService->publishDummyGrp(token, dgrp1); - pollForGrpAcknowledgement(token, grpId); - dgrp1_copy->meta.mGroupId = grpId; - groupsPublished.push_back(dgrp1_copy); - - *dgrp2_copy = *dgrp2; - testService->publishDummyGrp(token, dgrp2); - pollForGrpAcknowledgement(token, grpId); - dgrp2_copy->meta.mGroupId = grpId; - groupsPublished.push_back(dgrp2_copy); - - *dgrp3_copy = *dgrp3; - testService->publishDummyGrp(token, dgrp3); - pollForGrpAcknowledgement(token, grpId); - dgrp3_copy->meta.mGroupId = grpId; - groupsPublished.push_back(dgrp3_copy); - - - storeToGrpDataOutList(groupsPublished); - - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - std::list grpIds; - tokenService->requestGroupInfo(token, 0, opts); - - pollForToken(token, opts, true); - - - bool ok = compareGrpData(); - - breakDown(); - - return ok; -} - -bool GxsPublishGroupTest::testSpecificGrpRetrieval() -{ - setUp(); - - GenExchangeTestService* testService = getTestService(); - RsTokenService* tokenService = getTokenService(); - - // create some random grps to allow msg testing - - RsDummyGrp* dgrp1 = new RsDummyGrp(); - RsDummyGrp* dgrp2 = new RsDummyGrp(); - RsDummyGrp* dgrp3 = new RsDummyGrp(); - - RsDummyGrp* dgrp1_copy = new RsDummyGrp(); - RsDummyGrp* dgrp2_copy = new RsDummyGrp(); - - init(*dgrp1); - init(*dgrp2); - init(*dgrp3); - - RsTokReqOptions opts; - opts.mReqType = 45000; - uint32_t token; - RsGxsGroupId grpId; - - std::vector groupsPublished; - std::list grpIds; - - *dgrp1_copy = *dgrp1; - testService->publishDummyGrp(token, dgrp1); - pollForGrpAcknowledgement(token, grpId); - dgrp1_copy->meta.mGroupId = grpId; - groupsPublished.push_back(dgrp1_copy); - grpIds.push_back(grpId); - - *dgrp2_copy = *dgrp2; - testService->publishDummyGrp(token, dgrp2); - pollForGrpAcknowledgement(token, grpId); - dgrp2_copy->meta.mGroupId = grpId; - groupsPublished.push_back(dgrp2_copy); - grpIds.push_back(grpId); - - - testService->publishDummyGrp(token, dgrp3); - pollForGrpAcknowledgement(token, grpId); - - - storeToGrpDataOutList(groupsPublished); - - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - tokenService->requestGroupInfo(token, 0, opts, grpIds); - - pollForToken(token, opts, true); - - - bool ok = compareGrpData(); - - breakDown(); - - return ok; -} - -bool GxsPublishGroupTest::testGrpIdRetrieval() -{ - setUp(); - - std::list grpIds; - createGrps(5, grpIds); - storeToGrpIdsOutList(grpIds); - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS; - uint32_t token; - - getTokenService()->requestGroupInfo(token, 0, opts); - - pollForToken(token, opts, true); - - bool ok = compareGrpIds(); - - breakDown(); - - return ok; -} - -bool GxsPublishGroupTest::testUpdateGroup() -{ - setUp(); - - GenExchangeTestService* testService = getTestService(); - RsTokenService* tokenService = getTokenService(); - -// create some random grps to allow msg testing - - RsDummyGrp* dgrp1 = new RsDummyGrp(); - RsDummyGrp* dgrp2 = new RsDummyGrp(); - - RsDummyGrp* dgrp2_copy = new RsDummyGrp(); - - init(*dgrp1); - init(*dgrp2); - - RsTokReqOptions opts; - opts.mReqType = 45000; - uint32_t token; - RsGxsGroupId grpId; - - std::vector groupsPublished; - std::list grpIds; - - std::string name = dgrp1->meta.mGroupName; - *dgrp2 = *dgrp1; - testService->publishDummyGrp(token, dgrp1); - bool ok = pollForGrpAcknowledgement(token, grpId); - - grpIds.push_back(grpId); - RsGxsGroupUpdateMeta updateMeta(grpId); - - updateMeta.setMetaUpdate(RsGxsGroupUpdateMeta::NAME, name); - randString(SHORT_STR, dgrp2->grpData); - dgrp2->meta.mGroupId = grpId; - *dgrp2_copy = *dgrp2; - dgrp2->grpData ="ojfosfjsofjsof"; - testService->updateDummyGrp(token, updateMeta, dgrp2); - ok &= pollForGrpAcknowledgement(token, grpId); - - groupsPublished.push_back(dgrp2_copy); - - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - tokenService->requestGroupInfo(token, 0, opts, grpIds); - - pollForToken(token, opts, true); - - - ok &= compareGrpData(); - - breakDown(); - - return ok; - -} - -bool GxsPublishGroupTest::testGrpMetaRetrieval() -{ - - setUp(); - - GenExchangeTestService* testService = getTestService(); - - // create some random grps to allow msg testing - - RsDummyGrp* dgrp1 = new RsDummyGrp(); - RsDummyGrp* dgrp2 = new RsDummyGrp(); - RsDummyGrp* dgrp3 = new RsDummyGrp(); - - init(*dgrp1); - init(*dgrp2); - init(*dgrp3); - - RsTokReqOptions opts; - opts.mReqType = 45000; - uint32_t token; - RsGxsGroupId grpId; - - RsGroupMetaData meta1(dgrp1->meta); - RsGroupMetaData meta2(dgrp2->meta); - RsGroupMetaData meta3(dgrp3->meta); - - std::list groupsMetaPublished; - - testService->publishDummyGrp(token, dgrp1); - pollForGrpAcknowledgement(token, grpId); - meta1.mGroupId = grpId; - groupsMetaPublished.push_back(meta1); - - testService->publishDummyGrp(token, dgrp2); - pollForGrpAcknowledgement(token, grpId); - meta2.mGroupId = grpId; - groupsMetaPublished.push_back(meta2); - - testService->publishDummyGrp(token, dgrp3); - pollForGrpAcknowledgement(token, grpId); - meta3.mGroupId = grpId; - groupsMetaPublished.push_back(meta3); - - storeToGrpMetaOutList(groupsMetaPublished); - - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; - std::list grpIds; - - getTokenService()->requestGroupInfo(token, 0, opts); - - pollForToken(token, opts, true); - - bool ok = compareGrpMeta(); - - breakDown(); - - return ok; -} -void GxsPublishGroupTest::runTests() -{ -// CHECK(testGrpSubmissionRetrieval()); -// CHECK(testGrpIdRetrieval()); -// CHECK(testGrpMetaRetrieval()); - // CHECK(testSpecificGrpRetrieval()); - CHECK(testUpdateGroup()); -} - - - - diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.h b/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.h deleted file mode 100644 index a0f642828..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxspublishgrouptest.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * gxspublishgrouptest.h - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#ifndef GXSPUBLISHGROUPTEST_H_ -#define GXSPUBLISHGROUPTEST_H_ - -#include "genexchangetester.h" - -class GxsPublishGroupTest : public GenExchangeTest { -public: - - GxsPublishGroupTest(GenExchangeTestService* const testService, - RsGeneralDataService* dataService); - virtual ~GxsPublishGroupTest(); - - void runTests(); - -private: - - // group tests - bool testGrpSubmissionRetrieval(); - bool testSpecificGrpRetrieval(); - bool testGrpIdRetrieval(); - bool testGrpMetaRetrieval(); - bool testUpdateGroup(); - - -private: - -}; - -#endif /* GXSPUBLISHGROUPTEST_H_ */ diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.cc b/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.cc deleted file mode 100644 index adfa2026c..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - * gxspublishmsgtest.cpp - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#include "gxspublishmsgtest.h" -#include "util/utest.h" - -#define POLLING_TIME_OUT 5 - -GxsPublishMsgTest::GxsPublishMsgTest(GenExchangeTestService* const testService, - RsGeneralDataService* dataService) - : GenExchangeTest(testService, dataService, POLLING_TIME_OUT) -{ -} - -GxsPublishMsgTest::~GxsPublishMsgTest() -{ -} - -void GxsPublishMsgTest::runTests() -{ - CHECK(testMsgSubmissionRetrieval()); -} - -bool GxsPublishMsgTest::testMsgSubmissionRetrieval() -{ - // start up - setUp(); - std::list grpIds; - createGrps(4, grpIds); - - /********************/ - - RsDummyMsg* msg = new RsDummyMsg(); - init(*msg); - - msg->meta.mGroupId = grpIds.front(); - uint32_t token; - RsDummyMsg* msgOut = new RsDummyMsg(); - *msgOut = *msg; - getTestService()->publishDummyMsg(token, msg); - - - RsGxsGrpMsgIdPair msgId; - pollForMsgAcknowledgement(token, msgId); - msgOut->meta.mMsgId = msgId.second; - - DummyMsgMap msgMap; - std::vector msgV; - msgV.push_back(msgOut); - msgMap[msgOut->meta.mGroupId] = msgV; - storeToMsgDataOutMaps(msgMap); - - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - getTokenService()->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grpIds); - - // poll again - pollForToken(token, opts, true); - - bool ok = compareMsgDataMaps(); - - // complete - breakDown(); - - return ok; -} - - - diff --git a/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.h b/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.h deleted file mode 100644 index bcdfa6aeb..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/gxspublishmsgtest.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * gxspublishmsgtest.h - * - * Created on: 27 Apr 2013 - * Author: crispy - */ - -#ifndef GXSPUBLISHMSGTEST_H_ -#define GXSPUBLISHMSGTEST_H_ - -#include "genexchangetester.h" - -class GxsPublishMsgTest: public GenExchangeTest { -public: - GxsPublishMsgTest(GenExchangeTestService* const testService, - RsGeneralDataService* dataService); - virtual ~GxsPublishMsgTest(); - - void runTests(); - - // message tests - bool testMsgSubmissionRetrieval(); -// bool testMsgIdRetrieval(); -// bool testMsgIdRetrieval_OptParents(); -// bool testMsgIdRetrieval_OptOrigMsgId(); -// bool testMsgIdRetrieval_OptLatest(); -// bool testSpecificMsgMetaRetrieval(); - - -}; - -#endif /* GXSPUBLISHMSGTEST_H_ */ diff --git a/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.cc b/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.cc deleted file mode 100644 index 4d8dd4984..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.cc +++ /dev/null @@ -1,226 +0,0 @@ - - -#include "rsdummyservices.h" - - -uint32_t RsDummySerialiser::size(RsItem *item) -{ - RsDummyMsg* msg; - RsDummyGrp* grp; - - if( (msg = dynamic_cast(item)) != NULL ) - { - return sizeDummyMsgItem(msg); - }else if( (grp = dynamic_cast(item)) != NULL ) - { - return sizeDummyGrpItem(grp); - }else - { - std::cerr << "RsDummySerialiser::size(RsItem *item) Error with dummy cast!\n"; - } - - return 0; -} - - -bool RsDummySerialiser::serialise(RsItem *item, void *data, uint32_t *size) -{ - RsDummyMsg* msg; - RsDummyGrp* grp; - - if( (msg = dynamic_cast(item)) != NULL ) - { - return serialiseDummyMsgItem(msg, data, size); - }else if( (grp = dynamic_cast(item)) != NULL ) - { - return serialiseDummyGrpItem(grp, data, size); - }else - { - std::cerr << "RsDummySerialiser::size(RsItem *item) Error with dummy cast!\n"; - } - - return false; -} - -RsItem* RsDummySerialiser::deserialise(void *data, uint32_t *size) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype))) - { - return NULL; /* wrong type */ - } - - switch(getRsItemSubType(rstype)) - { - case RS_PKT_SUBTYPE_DUMMY_MSG: - return deserialiseDummyMsgItem(data, size); - case RS_PKT_SUBTYPE_DUMMY_GRP: - return deserialiseDummyGrpItem(data, size); - default: - return NULL; - } - - return NULL; -} - - -uint32_t RsDummySerialiser::sizeDummyMsgItem(RsDummyMsg *item) -{ - uint32_t s = 8; // header - s += GetTlvStringSize(item->msgData); - - return s; -} - -bool RsDummySerialiser::serialiseDummyMsgItem (RsDummyMsg *item, void *data, uint32_t *size) -{ - uint32_t tlvsize = sizeDummyMsgItem(item); - uint32_t offset = 0; - - if (*size < tlvsize) - return false; /* not enough space */ - - *size = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); - - /* skip the header */ - offset += 8; - - /* RsDistribMsg first */ - - ok &= SetTlvString(data, *size, &offset, 1, item->msgData); - - if (offset != tlvsize) - { - ok = false; - std::cerr << "RsDummySerialiser::serialiseDummyMsgItem Size Error! " << std::endl; - } - - return ok; -} - -RsDummyMsg * RsDummySerialiser::deserialiseDummyMsgItem(void *data, uint32_t *size) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t rssize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_DUMMY_MSG != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*size < rssize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *size = rssize; - - bool ok = true; - - /* ready to load */ - RsDummyMsg *item = new RsDummyMsg(); - - /* skip the header */ - offset += 8; - - ok &= GetTlvString(data, *size, &offset, 1, item->msgData); - - if (!ok) - { - delete item; - return NULL; - } - - return item; -} - -uint32_t RsDummySerialiser::sizeDummyGrpItem(RsDummyGrp *item) -{ - uint32_t s = 8; - s += GetTlvStringSize(item->grpData); - - return s; -} - -bool RsDummySerialiser::serialiseDummyGrpItem (RsDummyGrp *item, void *data, uint32_t *size) -{ - uint32_t tlvsize = sizeDummyGrpItem(item); - uint32_t offset = 0; - - if (*size < tlvsize) - return false; /* not enough space */ - - *size = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); - - /* skip the header */ - offset += 8; - - ok &= SetTlvString(data, *size, &offset, 1, item->grpData); - - if (offset != tlvsize) - { - ok = false; - std::cerr << "RsDummySerialiser::serialiseDummyGrpItem Size Error! " << std::endl; - } - - return ok; -} - -RsDummyGrp * RsDummySerialiser::deserialiseDummyGrpItem(void *data, uint32_t *size) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t rssize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_DUMMY != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_DUMMY_GRP != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*size < rssize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *size = rssize; - - bool ok = true; - - /* ready to load */ - RsDummyGrp *item = new RsDummyGrp(); - - /* skip the header */ - offset += 8; - - ok &= GetTlvString(data, *size, &offset, 1, item->grpData); - - if (!ok) - { - delete item; - return NULL; - } - - return item; -} - - diff --git a/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.h b/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.h deleted file mode 100644 index 4720f6be7..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/rsdummyservices.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef RSDUMMYSERVICES_H -#define RSDUMMYSERVICES_H - - -// dummy services to make - -#include "gxs/rsnxs.h" -#include "gxs/rsgixs.h" -#include "serialiser/rsgxsitems.h" - -class RsDummyNetService: public RsNetworkExchangeService -{ -public: - - RsDummyNetService(){ return;} - virtual ~RsDummyNetService() { } - - void setSyncAge(uint32_t age){} - - void requestGroupsOfPeer(const std::string& peerId){} - - void requestMessagesOfPeer(const std::string& peerId, const std::string& grpId){} - - void pauseSynchronisation(bool enabled) {} - - int requestMsg(const std::string& msgId, uint8_t hops){ return 0;} - - int requestGrp(const std::list& grpId, uint8_t hops) { return 0;} -}; - - - -const uint16_t RS_SERVICE_TYPE_DUMMY = 0x01; -const uint8_t RS_PKT_SUBTYPE_DUMMY_MSG = 0x02; -const uint8_t RS_PKT_SUBTYPE_DUMMY_GRP = 0x03; - - -class RsDummyMsg : public RsGxsMsgItem -{ -public: - RsDummyMsg() : RsGxsMsgItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_MSG) { return; } - virtual ~RsDummyMsg() { return; } - - std::string msgData; - - std::ostream &print(std::ostream &out, uint16_t indent = 0){ return out; } - void clear() { msgData.clear(); } - -}; - -class RsDummyGrp : public RsGxsGrpItem -{ -public: - - RsDummyGrp() : RsGxsGrpItem(RS_SERVICE_TYPE_DUMMY, RS_PKT_SUBTYPE_DUMMY_GRP) { return; } - virtual ~RsDummyGrp() { return; } - - - std::string grpData; - void clear() { grpData.clear(); } - std::ostream &print(std::ostream &out, uint16_t indent = 0){ return out; } -}; - - - -class RsDummySerialiser : public RsSerialType -{ - -public: - - - RsDummySerialiser() - : RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DUMMY) - { return; } - virtual ~RsDummySerialiser() { return; } - - uint32_t size(RsItem *item); - bool serialise (RsItem *item, void *data, uint32_t *size); - RsItem * deserialise(void *data, uint32_t *size); - - private: - - uint32_t sizeDummyMsgItem(RsDummyMsg *item); - bool serialiseDummyMsgItem (RsDummyMsg *item, void *data, uint32_t *size); - RsDummyMsg * deserialiseDummyMsgItem(void *data, uint32_t *size); - - uint32_t sizeDummyGrpItem(RsDummyGrp *item); - bool serialiseDummyGrpItem (RsDummyGrp *item, void *data, uint32_t *size); - RsDummyGrp * deserialiseDummyGrpItem(void *data, uint32_t *size); - - -}; - -/*! - * Dummy implementation of Gixs service for - * testing - * Limited to creating two ids upon construction which can be used - * for signing data - */ -class RsGixsDummy : public RsGixs -{ - -public: - - /*! - * constructs keys for both incoming and outgoing id (no private keys for incoming id) - * @param - * @param dummyId This is is the only id thats exists in this dummy interface - */ - RsGixsDummy(const RsGxsId& incomingId, const RsGxsId& outgoingId){} - - virtual ~RsGixsDummy(){} - - /*! - * - * @return id used for signing incoming data (should have both public and private components) - */ - const RsGxsId& getOutgoing(){ return mOutgoingId; } - - /*! - * - * @return id used for signing outgoing data(only have public parts) - */ - const RsGxsId& getIncoming(){ return mIncomingId; } - - // Key related interface - used for validating msgs and groups. - /*! - * Use to query a whether given key is available by its key reference - * @param keyref the keyref of key that is being checked for - * @return true if available, false otherwise - */ - bool haveKey(const RsGxsId &id){ return false;} - - /*! - * Use to query whether private key member of the given key reference is available - * @param keyref the KeyRef of the key being checked for - * @return true if private key is held here, false otherwise - */ - bool havePrivateKey(const RsGxsId &id){ return false; } - - // The fetchKey has an optional peerList.. this is people that had the msg with the signature. - // These same people should have the identity - so we ask them first. - /*! - * Use to request a given key reference - * @param keyref the KeyRef of the key being requested - * @return will - */ - bool requestKey(const RsGxsId &id, const std::list &peers){ return false ;} - bool requestPrivateKey(const RsGxsId &id){ return false;} - - - /*! - * Retrieves a key identity - * @param keyref - * @return a pointer to a valid profile if successful, otherwise NULL - * - */ - int getKey(const RsGxsId &id, RsTlvSecurityKey &key){ return false; } - int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key){ return false; } // For signing outgoing messages. - -private: - - RsGxsId mIncomingId, mOutgoingId; -}; - - -#endif // RSDUMMYSERVICES_H diff --git a/libretroshare/src/tests/gxs/gen_exchange/rsgenexchange_test.cc b/libretroshare/src/tests/gxs/gen_exchange/rsgenexchange_test.cc deleted file mode 100644 index 8b28bad17..000000000 --- a/libretroshare/src/tests/gxs/gen_exchange/rsgenexchange_test.cc +++ /dev/null @@ -1,47 +0,0 @@ - - -#include "genexchangetester.h" -#include "gxspublishgrouptest.h" -#include "gxspublishmsgtest.h" -#include "util/utest.h" -#include "gxs/rsdataservice.h" -#include "rsdummyservices.h" - - -/*! - * It always hard to say exactly what coverage of a test would - * be ahead of time. Partly because its difficult to create the - * actual conditions of a test or the permutations of different request - * options to a module is extremely large (and there are probably ways to deal with this) - * In so far as the genexchange test is concerned we are primarily interested that it - * retrieves and stores data correctly - * The auxillary (and important) requirement is authentication and ensuring the authentication - * rules are respected. This auxillary requirement is of the "hard" situation to create as - * genexchange depends on an external module (rsidentity) for satisfying a significant sum - * of its authentication. This difficulty is solved with a dummy identity service. - * Which passes all authentications (In this respect authentication) is reserved for "online" - * testing and is relatively straight forward. - * - */ - -INITTEST(); - - -int main() -{ - - RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL, ""); - - // we want to use default authentication which is NO authentication :) - GenExchangeTestService testService(dataStore, NULL, NULL); - - GxsPublishGroupTest testGrpPublishing(&testService, dataStore); - testGrpPublishing.runTests(); - - //GxsPublishMsgTest testMsgPublishing(&testService, dataStore); - //testMsgPublishing.runTests(); - - FINALREPORT("RsGenExchangeTest"); - - return 0; -} diff --git a/libretroshare/src/tests/gxs/nxs_test/nxs_tests.pro b/libretroshare/src/tests/gxs/nxs_test/nxs_tests.pro deleted file mode 100644 index 8fa292c61..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/nxs_tests.pro +++ /dev/null @@ -1,203 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2012-05-06T09:19:26 -# -#------------------------------------------------- - - -# -QT += core network - -QT -= gui - -#CONFIG += gen_exchange_target -CONFIG += nxs_net_test -#CONFIG += dstore_target -#CONFIG += gxsdata_target - -CONFIG += bitdht - - - -#gen_exchange_target { - -#TARGET = gen_exchange_test - -#} - -#nxs_net_test { - -TARGET = nxs_net_test - -#} - -#gxsdata_target { - -#TARGET = gxsdata_test -#} - -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -CONFIG += debug - -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 -} -################################# Linux ########################################## -# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib -linux-* { - #CONFIG += version_detail_bash_script - QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 - - system(which gpgme-config >/dev/null 2>&1) { - INCLUDEPATH += $$system(gpgme-config --cflags | sed -e "s/-I//g") - } else { - message(Could not find gpgme-config on your system, assuming gpgme.h is in /usr/include) - } - - PRE_TARGETDEPS *= ../../lib/libretroshare.a - - LIBS += ../../lib/libretroshare.a - LIBS += ../../../../libbitdht/src/lib/libbitdht.a - LIBS += ../../../../openpgpsdk/src/lib/libops.a - LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2 - LIBS *= -rdynamic -frtti - DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions - DEFINES *= HAS_GNOME_KEYRING -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -#################################### Windows ##################################### - -win32 { - - DEFINES *= WINDOWS_SYS \ - WIN32 \ - STATICLIB \ - MINGW - # 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 - -# PRE_TARGETDEPS += ../../libretroshare/src/lib/libretroshare.a - PRE_TARGETDEPS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - - LIBS += ../../../../libretroshare/libretroshare-build-desktop/lib/libretroshare.a - LIBS += C:\Development\Rs\v0.5-gxs-b1\openpgpsdk\openpgpsdk-build-desktop\lib\libops.a - LIBS += C:\Development\Libraries\sqlite\sqlite-autoconf-3070900\lib\libsqlite3.a - LIBS += -L"../../../../../lib" - LIBS += -lssl -lcrypto -lgpgme -lpthreadGC2d -lminiupnpc -lz -lbz2 -# added after bitdht -# LIBS += -lws2_32 - LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32 - LIBS += -lole32 -lwinmm - - # export symbols for the plugins - #LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a - - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - GPG_ERROR_DIR = ../../../../lib/libgpg-error-1.7 - GPGME_DIR = ../../../../lib/gpgme-1.1.8 - SSL_DIR = ../../../../../OpenSSL - OPENPGPSDK_DIR = ../../../../openpgpsdk/src - INCLUDEPATH += . $${SSL_DIR}/include $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src \ - $${OPENPGPSDK_DIR} - - SQLITE_DIR = ../../../../../../Libraries/sqlite/sqlite-autoconf-3070900 - INCLUDEPATH += . \ - $${SQLITE_DIR} - - - - -} - -bitdht { - - # Chris version. - #LIBS += ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a - #PRE_TARGETDEPS *= ../../libbitdht/libbitdht-build-desktop/lib/libbitdht.a -} - -win32 { -# must be added after bitdht - LIBS += -lws2_32 -} - -version_detail_bash_script { - DEFINES += ADD_LIBRETROSHARE_VERSION_INFO - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh -} - -install_rs { - INSTALLS += binary_rs - binary_rs.path = $$(PREFIX)/usr/bin - binary_rs.files = ./RetroShare -} - - -#gen_exchange_target { - -# SOURCES += \ -# support.cc \ -# genexchangetester.cpp \ -# genexchangetestservice.cpp \ -# rsdummyservices.cc \ -# rsgenexchange_test.cc - -# HEADERS += support.h \ -# rsdataservice_test.h \ -# rsdummyservices.h \ -# data_support.h -#} - -nxs_net_test { - - SOURCES += \ - support.cc \ - data_support.cc \ - nxstesthub.cc \ - nxstestscenario.cc \ - rsgxsnetservice_test.cc - - HEADERS += support.h \ - nxstestscenario.h \ - nxstesthub.h \ - data_support.h - -} - -INCLUDEPATH += ../../ diff --git a/libretroshare/src/tests/gxs/nxs_test/nxstesthub.cc b/libretroshare/src/tests/gxs/nxs_test/nxstesthub.cc deleted file mode 100644 index e0c505464..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/nxstesthub.cc +++ /dev/null @@ -1,129 +0,0 @@ -#include "nxstesthub.h" - -NxsTestHub::NxsTestHub(NxsTestScenario * nts, std::set &peers) : mTestScenario(nts) -{ - - std::set::iterator sit = peers.begin(); - - for(; sit != peers.end(); sit++) - { - std::set msgPeers = peers; - - // add peers all peers except one iterator currently points to - msgPeers.erase(*sit); - NxsNetDummyMgr* dummyMgr = new NxsNetDummyMgr(*sit, msgPeers); - RsGeneralDataService* ds = mTestScenario->getDataService(*sit); - NxsMessageTestObserver* obs = new NxsMessageTestObserver(ds); - - RsGxsNetService* netService = - new RsGxsNetService(mTestScenario->getServiceType(), - ds, dummyMgr, obs); - - - mNetServices.insert(std::make_pair(*sit, netService)); - mObservers.insert(std::make_pair(*sit, obs)); - } - - sit = peers.begin(); - - // launch net services - for(; sit != peers.end(); sit++) - { - RsGxsNetService* n = mNetServices[*sit]; - createThread(*n); - mServices.insert(std::make_pair(*sit, n)); - } -} - -NxsTestHub::~NxsTestHub() -{ - std::map::iterator mit = mNetServices.begin(); - - for(; mit != mNetServices.end(); mit++) - delete mit->second; -} - - -void NxsTestHub::run() -{ - double timeDelta = .2; - - while(isRunning()){ - - // make thread sleep for a bit - #ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); - #else - Sleep((int) (timeDelta * 1000)); - #endif - - - std::map::iterator mit = mServices.begin(); - - for(; mit != mServices.end(); mit++) - { - p3Service* s = mit->second; - s->tick(); - } - - mit = mServices.begin(); - - // collect msgs to send to peers from peers - for(; mit != mServices.end(); mit++) - { - const std::string& peer = mit->first; - p3Service* s = mit->second; - - // first store all the sends from all services - RsItem* item = NULL; - - while((item = s->send()) != NULL){ - - const std::string peerToReceive = item->PeerId(); - - // set the peer this item comes from - item->PeerId(peer); - mPeerQueues[peerToReceive].push_back(item); - } - - - } - - // now route items to peers - std::map >::iterator mit_queue = mPeerQueues.begin(); - - for(; mit_queue != mPeerQueues.end(); mit_queue++) - { - std::vector& queueV = mit_queue->second; - std::vector::iterator vit = queueV.begin(); - const std::string peerToReceive = mit_queue->first; - for(; vit != queueV.end(); vit++) - { - - RsItem* item = *vit; - p3Service* service = mServices[peerToReceive]; - - service->receive(dynamic_cast(item)); - } - queueV.clear(); - } - } -} - -void NxsTestHub::cleanUp() -{ - std::map::iterator mit = mNetServices.begin(); - for(; mit != mNetServices.end(); mit++) - { - RsGxsNetService* n = mit->second; - n->join(); - } - - // also shut down this net service peers if this goes down - mTestScenario->cleanUp(); -} - -bool NxsTestHub::testsPassed() -{ - return false; -} diff --git a/libretroshare/src/tests/gxs/nxs_test/nxstesthub.h b/libretroshare/src/tests/gxs/nxs_test/nxstesthub.h deleted file mode 100644 index 15f10e0b4..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/nxstesthub.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef NXSTESTHUB_H -#define NXSTESTHUB_H - -#include "util/rsthreads.h" -#include "gxs/rsgxsnetservice.h" -#include "nxstestscenario.h" - -// it would probably be useful if the test scenario -// provided the net dummy managers -// hence one could envision synchronising between an arbitrary number -// of peers - - -class NxsNetDummyMgr : public RsNxsNetMgr -{ - -public: - - NxsNetDummyMgr(std::string ownId, std::set peers) : mOwnId(ownId), mPeers(peers) { - - } - - std::string getOwnId() { return mOwnId; } - void getOnlineList(std::set& ssl_peers) { ssl_peers = mPeers; } - -private: - - std::string mOwnId; - std::set mPeers; - -}; - - -/*! - * Testing of nxs services occurs through use of two services - * When a service sends this class can interrogate the send and the receives of - * - * NxsScenario stores the type of synchronisation to be tested - * Operation: - * First NxsTestHub needs to be instantiated with a test scenario - * * The scenario contains two databases to be used on the communicating pair of RsGxsNetService instances (net instances) - * The Test hub has a ticker service for the p3Services which allows the netservices to search what groups and messages they have - * and synchronise according to their subscriptions. The default is to subscribe to all groups held by other peer - * The threads for both net instances are started which begins their processing of transactions - */ -class NxsTestHub : public RsThread -{ -public: - - - /*! - * This construct the test hub - * for a give scenario in mind - */ - NxsTestHub(NxsTestScenario*, std::set& peers); - - - /*! - * - */ - virtual ~NxsTestHub(); - - /*! - * To be called only after this thread has - * been shutdown - */ - bool testsPassed(); - - /*! - * This simulates the p3Service ticker and calls both gxs net services tick methods - * Also enables transport of messages between both services - */ - void run(); - - - void cleanUp(); -private: - - std::map mServices; - std::map mNetServices; - std::map mObservers; - - std::map > mPeerQueues; - - NxsTestScenario *mTestScenario; - -}; - -#endif // NXSTESTHUB_H diff --git a/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.cc deleted file mode 100644 index c4cf5c666..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.cc +++ /dev/null @@ -1,177 +0,0 @@ -/* - * nxstestscenario.cc - * - * Created on: 10 Jul 2012 - * Author: crispy - */ - -#include "nxstestscenario.h" -#include "gxs/rsdataservice.h" -#include "retroshare/rsgxsflags.h" -#include "data_support.h" -#include - -NxsMessageTest::NxsMessageTest(uint16_t servtype) -: mServType(servtype), mMsgTestMtx("mMsgTestMtx") -{ - -} - -std::string NxsMessageTest::getTestName() -{ - return std::string("Nxs Message Test!"); -} - -NxsMessageTest::~NxsMessageTest(){ - - std::map::iterator mit = mPeerStoreMap.begin(); - - for(; mit != mPeerStoreMap.end(); mit++) - { - delete mit->second; - } - - std::set::iterator sit = mStoreNames.begin(); - - // remove db file - for(; sit != mStoreNames.end(); sit++) - { - const std::string& name = *sit; - remove(name.c_str()); - } -} -RsGeneralDataService* NxsMessageTest::getDataService(const std::string& peer) -{ - if(mPeerStoreMap.find(peer) != mPeerStoreMap.end()) return NULL; - - RsDataService* dStore = new RsDataService("./", peer, mServType); - mStoreNames.insert(peer); - mPeerStoreMap.insert(std::make_pair(peer, dStore)); - populateStore(dStore); - - return dStore; -} - -uint16_t NxsMessageTest::getServiceType() -{ - return mServType; -} - -void NxsMessageTest::populateStore(RsGeneralDataService* dStore) -{ - - int nGrp = (rand()%2)+1; - std::vector grpIdList; - std::map grps; - RsNxsGrp* grp = NULL; - RsGxsGrpMetaData* grpMeta =NULL; - for(int i = 0; i < nGrp; i++) - { - std::pair p; - grp = new RsNxsGrp(mServType); - grpMeta = new RsGxsGrpMetaData(); - p.first = grp; - p.second = grpMeta; - init_item(*grp); - init_item(grpMeta); - grpMeta->mGroupId = grp->grpId; - grps.insert(p); - grpIdList.push_back(grp->grpId); - grpMeta = NULL; - grp = NULL; - } - - dStore->storeGroup(grps); - - int nMsgs = rand()%23; - std::map msgs; - RsNxsMsg* msg = NULL; - RsGxsMsgMetaData* msgMeta = NULL; - - for(int i=0; i p(msg, msgMeta); - - // pick a grp at random to associate the msg to - const std::string& grpId = grpIdList[rand()%nGrp]; - msgMeta->mMsgId = msg->msgId; - msgMeta->mGroupId = msg->grpId = grpId; - - msg = NULL; - msgMeta = NULL; - - msgs.insert(p); - } - - - dStore->storeMessage(msgs); - - return; -} - -void NxsMessageTest::cleanUp() -{ - - std::map::iterator mit = mPeerStoreMap.begin(); - - for(; mit != mPeerStoreMap.end(); mit++) - { - RsGeneralDataService* d = mit->second; - d->resetDataStore(); - } - - return; -} - -bool NxsMessageTest::testPassed(){ - return false; -} - -/*******************************/ - -NxsMessageTestObserver::NxsMessageTestObserver(RsGeneralDataService *dStore) - :mStore(dStore) -{ - -} - -void NxsMessageTestObserver::notifyNewGroups(std::vector &groups) -{ - std::vector::iterator vit = groups.begin(); - std::map grps; - - for(; vit != groups.end(); vit++) - { - RsNxsGrp* grp = *vit; - RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); - meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); - meta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; - meta->mGroupId = grp->grpId; - grps.insert(std::make_pair(grp, meta)); - } - - mStore->storeGroup(grps); -} - -void NxsMessageTestObserver::notifyNewMessages(std::vector &messages) -{ - - std::vector::iterator vit = messages.begin(); - std::map msgs; - - for(; vit != messages.end(); vit++) - { - RsNxsMsg* msg = *vit; - RsGxsMsgMetaData* meta = new RsGxsMsgMetaData(); - meta->mGroupId = msg->grpId; - meta->mMsgId = msg->msgId; - msgs.insert(std::make_pair(msg, meta)); - } - - mStore->storeMessage(msgs); -} - diff --git a/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.h b/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.h deleted file mode 100644 index 72500e4d3..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/nxstestscenario.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nxstestscenario.h - * - * Created on: 10 Jul 2012 - * Author: crispy - */ - -#ifndef NXSTESTSCENARIO_H_ -#define NXSTESTSCENARIO_H_ - -#include -#include "gxs/rsdataservice.h" -#include "gxs/rsnxsobserver.h" - -/*! - * This scenario module provides data resources - */ -class NxsTestScenario -{ - -public: - - virtual std::string getTestName() = 0; - - /*! - * @param peer - * @param namePath - * @return data service with populated with random grp/msg data, null if peer or pathname exists - */ - virtual RsGeneralDataService* getDataService(const std::string& peer) = 0; - - - virtual bool testPassed() = 0; - /*! - * Service type for this test - * should correspond to serialiser service type - */ - virtual uint16_t getServiceType() = 0; - - /*! - * Call to remove files created - * in the test directory - */ - virtual void cleanUp() = 0; - - -}; - -class NxsMessageTestObserver : public RsNxsObserver -{ -public: - - NxsMessageTestObserver(RsGeneralDataService* dStore); - - /*! - * @param messages messages are deleted after function returns - */ - void notifyNewMessages(std::vector& messages); - - /*! - * @param messages messages are deleted after function returns - */ - void notifyNewGroups(std::vector& groups); - -private: - - RsGeneralDataService* mStore; - -}; - -class NxsMessageTest : public NxsTestScenario -{ - -public: - - NxsMessageTest(uint16_t servtype); - virtual ~NxsMessageTest(); - std::string getTestName(); - uint16_t getServiceType(); - RsGeneralDataService* getDataService(const std::string& peer); - - /*! - * Call to remove files created - * in the test directory - */ - void cleanUp(); - - bool testPassed(); - -private: - void setUpDataBases(); - void populateStore(RsGeneralDataService* dStore); - -private: - - std::string mTestName; - std::map mPeerStoreMap; - std::set mStoreNames; - uint16_t mServType; - - RsMutex mMsgTestMtx; - -}; - - -#endif /* NXSTESTSCENARIO_H_ */ diff --git a/libretroshare/src/tests/gxs/nxs_test/rsgxsnetservice_test.cc b/libretroshare/src/tests/gxs/nxs_test/rsgxsnetservice_test.cc deleted file mode 100644 index ddcc2f6c0..000000000 --- a/libretroshare/src/tests/gxs/nxs_test/rsgxsnetservice_test.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * rsgxsnetservice_test.cc - * - * Created on: 11 Jul 2012 - * Author: crispy - */ - -#include "util/utest.h" -#include "nxstesthub.h" -#include "nxstestscenario.h" - -INITTEST(); - - -int main() -{ - - // first setup - NxsMessageTest msgTest(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); - std::set peers; - peers.insert("PeerA"); - peers.insert("PeerB"); - NxsTestHub hub(&msgTest, peers); - - // now get things started - createThread(hub); - - double timeDelta = 50; - - // put this thread to sleep for 10 secs - // make thread sleep for a bit -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - - hub.join(); - CHECK(hub.testsPassed()); - - hub.cleanUp(); - - FINALREPORT("RsGxsNetService Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/network_simulator/README.txt b/libretroshare/src/tests/network_simulator/README.txt deleted file mode 100644 index 2a669d3c3..000000000 --- a/libretroshare/src/tests/network_simulator/README.txt +++ /dev/null @@ -1,87 +0,0 @@ -TODO -==== - -Testing the router algorithm with network simulator - * generate a random network - * simulate disconnections (also in GUI) - * send messages from/to random peers and measure: - - how many times a given message is stored - - how much time a given message took to arrive. - -Implement - * clueing of GR from GXS (simulated in network simulator, when initing the network) - -In GLobal Router, by order of priority - * when a ACK is received for a msg that is already ACKed, we should still update the routing matrix and add a clue, but with lower prioity, - so that the matrix gets filled with additional routes. Can be checked in the simulator - - * routing strategy: - - when a route is known and available, always select it, but possibly add another random route, very rarely. - Peer disconnection is likely to cause the discovery of new routes anyway. - - * we should use clues from GXS to improve the routing matrix - - That would avoid lots of spamming. - - allows to init the routing matrices for all keys - - random walk will be a supplemental help, but restricted to small depth if no indication of route is available. - - needs to be implemented in network simulator. When providing a new key, the key should be spread in the network and new clues - should be added to the RGrouter matrix. - - * make sure the depth is accounted better: - - if single route is known => don't limit depth - - if no route is known => strictly limit depth - => add a counter which is increased when no route is available, and *reset* otherwise, so that the max number of bounce - we can do without knowledge of the keys is limited, but the total depth has no limits. - -Unsolved questions: - * handle dead routes correctly. How? - * should we send ACKs everywhere even upward? No, if we severely limit the depth of random walk. - * better distribute routing events, so that the matrix gets filled better? - * find a strategy to avoid storing too many items - * how to handle cases where a ACK cannot be sent back? The previous peer is going to try indefinitly? - => the ACK will be automatically collected by another route! - * how to make sure ACKed messages are not stored any longer than necessary? - * send signed ACKs, so that the receiver cannot be spoofed. - * only ACK when the message was properly received by the client service. No ACK if the client does not register that item? - -================================================================================================================ - - -The purpose of this directory is to write a Network simulator, that can have multiple turtle routers interact -together. The routers will talk to a fake link manager, which reports the peers for each node of a network graph. - -Required components: -=================== - NetworkGraph: a set of friends, with connections. Should be able to be saved to a file for debugging. - - GraphNode: a RS peer, represented by a random SSL id, a link manager, and possibly components such as file transfer, etc. - - Main loop: a loop calling tick() on all turtle routers. - - Functions: - * gather statistics over network load. See if tunnels are ok, improve bandwidth allocation strategy, see request broadcast. - - GUI: - * visualization of the graph. OpenGL + qglviewer window. Show tunnels, data flow as colors, etc. - * give quantitative information under mouse - * the user can trigger behaviors, execute tunnel handling orders, cause file transfer, etc. - - -Implementation constraints -========================== - * sendItem() and recvItems() should come from above. The class p3Service thus needs to be re-implemented to get/send the - data properly. - - => define subclass of p3turtle , where send() and recv() are redefined. - - * LinkMgr: - getOwnId(), getLinkType(), getOnlineList() - - used by turtle - - * turtle needs LinkMgr and ftServer. The ftServer can be contructed from PeerMgr (not called except in ftServer::setupFtServer. not needed here. - -Complilation -============ - * needs the QGLViewer-dev library (standard on ubuntu, package name is libqglviewer-qt4-dev) - * should compile on windows and MacOS as well. Use http://www.libqglviewer.com - diff --git a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.cpp b/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.cpp deleted file mode 100644 index c1642cbb6..000000000 --- a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 20011, RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include "GlobalRouterStatistics.h" - -static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; - -static QColor colorScale(float f) -{ - if(f == 0) - return QColor::fromHsv(0,0,192) ; - else - return QColor::fromHsv((int)((1.0-f)*280),200,255) ; -} - -GlobalRouterStatistics::GlobalRouterStatistics(QWidget *parent) - : RsAutoUpdatePage(2000,parent) -{ - setupUi(this) ; - - _router_F->setWidget( _tst_CW = new GlobalRouterStatisticsWidget() ) ; - _grouter = NULL ; -} - -GlobalRouterStatistics::~GlobalRouterStatistics() -{ -} - -void GlobalRouterStatistics::setGlobalRouter(const RsGRouter *grouter) -{ - _grouter = const_cast(grouter); - updateDisplay() ; -} -void GlobalRouterStatistics::updateDisplay() -{ - if(_grouter != NULL) - _tst_CW->updateContent(_grouter) ; -} - -QString GlobalRouterStatistics::getPeerName(const RsPeerId &peer_id) -{ - static std::map names ; - - std::map::const_iterator it = names.find(peer_id) ; - - if( it != names.end()) - return it->second ; - else - { - RsPeerDetails detail ; - if(!rsPeers->getPeerDetails(peer_id,detail)) - return tr("Unknown Peer"); - - return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ; - } -} - -GlobalRouterStatisticsWidget::GlobalRouterStatisticsWidget(QWidget *parent) - : QWidget(parent) -{ - maxWidth = 400 ; - maxHeight = 0 ; -} - -void GlobalRouterStatisticsWidget::updateContent(RsGRouter *grouter) -{ - std::vector cache_infos ; - RsGRouter::GRouterRoutingMatrixInfo matrix_info ; - - grouter->getRoutingCacheInfo(cache_infos) ; - grouter->getRoutingMatrixInfo(matrix_info) ; - - // What do we need to draw? - // - // Routing matrix - // Key [][][][][][][][][][] - // - // -> each [] shows a square (one per friend location) that is the routing probabilities for all connected friends - // computed using the "computeRoutingProbabilitites()" method. - // - // Own key ids - // key service id description - // - // Data items - // Msg id Local origin Destination Time Status - // - static const int cellx = 6 ; - static const int celly = 10+4 ; - - QPixmap tmppixmap(maxWidth, maxHeight); - tmppixmap.fill(this, 0, 0); - setFixedHeight(maxHeight); - - QPainter painter(&tmppixmap); - painter.initFrom(this); - painter.setPen(QColor::fromRgb(0,0,0)) ; - - maxHeight = 500 ; - - // std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl; - // draw... - int ox=5,oy=5 ; - - painter.drawText(ox,oy+celly,tr("Pending packets")+":" + QString::number(cache_infos.size())) ; oy += celly*2 ; - - for(uint32_t i=0;i::const_iterator it(matrix_info.published_keys.begin());it!=matrix_info.published_keys.end();++it) - { - QString packet_string ; - packet_string += QString::fromStdString(it->first.toStdString()) ; - packet_string += tr(" : Service ID = ")+QString::number(it->second.service_id,16) ; - packet_string += " \""+QString::fromUtf8(it->second.description_string.c_str()) + "\"" ; - - painter.drawText(ox+2*cellx,oy+celly,packet_string ) ; oy += celly ; - } - oy += celly ; - - QString prob_string ; - - painter.drawText(ox+0*cellx,oy+celly,tr("Routing matrix (")) ; - - // draw scale - - for(int i=0;i<100;++i) - { - painter.setPen(colorScale(i/100.0)) ; - painter.drawLine(ox+120+i,oy+celly+2,ox+120+i,oy+2) ; - } - painter.setPen(QColor::fromRgb(0,0,0)) ; - - painter.drawText(ox+230,oy+celly,")") ; - - oy += celly ; - oy += celly ; - - static const int MaxKeySize = 20 ; - - for(std::map >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it) - { - painter.drawText(ox+2*cellx,oy+celly,QString::fromStdString(it->first.toStdString())+" : ") ; - - for(uint32_t i=0;isecond[i])) ; - - oy += celly ; - } - - oy += celly ; - oy += celly ; - - // update the pixmap - // - pixmap = tmppixmap; - maxHeight = oy ; -} - -QString GlobalRouterStatisticsWidget::speedString(float f) -{ - if(f < 1.0f) - return QString("0 B/s") ; - if(f < 1024.0f) - return QString::number((int)f)+" B/s" ; - - return QString::number(f/1024.0,'f',2) + " KB/s"; -} - -void GlobalRouterStatisticsWidget::paintEvent(QPaintEvent */*event*/) -{ - QStylePainter(this).drawPixmap(0, 0, pixmap); -} - -void GlobalRouterStatisticsWidget::resizeEvent(QResizeEvent *event) -{ - QRect TaskGraphRect = geometry(); - maxWidth = TaskGraphRect.width(); - maxHeight = TaskGraphRect.height() ; - - QWidget::resizeEvent(event); -// updateContent(); -} - diff --git a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.h b/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.h deleted file mode 100644 index b3bc067de..000000000 --- a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 20011, RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#pragma once - -#include -#include -#include - -#include "RsAutoUpdatePage.h" -#include "ui_GlobalRouterStatistics.h" - -class GlobalRouterStatisticsWidget ; -class p3GRouter ; - -class GlobalRouterStatistics: public RsAutoUpdatePage, public Ui::GlobalRouterStatistics -{ - Q_OBJECT - - public: - GlobalRouterStatistics(QWidget *parent = NULL) ; - ~GlobalRouterStatistics(); - - // Cache for peer names. - static QString getPeerName(const RsPeerId& peer_id) ; - - void setGlobalRouter(const RsGRouter *grouter) ; - virtual void updateDisplay() ; - - private: - - - GlobalRouterStatisticsWidget *_tst_CW ; - RsGRouter *_grouter ; -} ; - -class GlobalRouterStatisticsWidget: public QWidget -{ - Q_OBJECT - - public: - GlobalRouterStatisticsWidget(QWidget *parent = NULL) ; - - virtual void paintEvent(QPaintEvent *event) ; - virtual void resizeEvent(QResizeEvent *event); - - void updateContent(RsGRouter *grouter) ; - private: - static QString speedString(float f) ; - - QPixmap pixmap ; - int maxWidth,maxHeight ; -}; - diff --git a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.ui b/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.ui deleted file mode 100644 index 0e6e28f7b..000000000 --- a/libretroshare/src/tests/network_simulator/gui/GlobalRouterStatistics.ui +++ /dev/null @@ -1,55 +0,0 @@ - - - GlobalRouterStatistics - - - - 0 - 0 - 611 - 408 - - - - Router Statistics - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - Qt::Vertical - - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 593 - 390 - - - - - - - - - - - - - diff --git a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.cpp b/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.cpp deleted file mode 100644 index b32e70931..000000000 --- a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include - -#include "NetworkSimulatorGUI.h" -#include "NetworkViewer.h" -#include "TurtleRouterStatistics.h" -#include "GlobalRouterStatistics.h" - -NetworkSimulatorGUI::NetworkSimulatorGUI(Network& net) -{ - setupUi(this) ; - tickTimerId = 0 ; - - QVBoxLayout *layout = new QVBoxLayout(networkViewFrame) ; - layout->addWidget(_viewer = new NetworkViewer(networkViewFrame,net)) ; - - QObject::connect(_viewer,SIGNAL(nodeSelected(int)),this,SLOT(updateSelectedNode(int))) ; - QObject::connect(flow_CB,SIGNAL(toggled(bool)),this,SLOT(toggleNetworkTraffic(bool))) ; - - QVBoxLayout *layout2 = new QVBoxLayout(inspectorFrame) ; - QTabWidget *tabwidget = new QTabWidget() ; - - layout2->addWidget(tabwidget) ; - - tabwidget->addTab(_turtle_router_statistics = new TurtleRouterStatistics(),"Turtle router" ) ; - tabwidget->addTab(_global_router_statistics = new GlobalRouterStatistics(),"Global router" ) ; -} - -void NetworkSimulatorGUI::updateSelectedNode(int node_id) -{ - const RsTurtle *turtle = _viewer->network().node(node_id).turtle_service() ; - const RsGRouter *grouter = _viewer->network().node(node_id).global_router_service() ; - - _turtle_router_statistics->setTurtleRouter( turtle ) ; - _global_router_statistics->setGlobalRouter( grouter ) ; - - // make only the selected node to display grouter info - - for(uint32_t i=0;i<_viewer->network().n_nodes();++i) - _viewer->network().node(i).global_router_service()->setDebugEnabled(i==node_id) ; - - std::cerr << "Selected objects: turtle=" << std::hex << turtle << ", grouter=" << grouter << std::dec << std::endl; -} - -void NetworkSimulatorGUI::toggleNetworkTraffic(bool b) -{ - if(!b && tickTimerId > 0) - { - killTimer(tickTimerId) ; - tickTimerId = 0 ; - return ; - } - - if(b && tickTimerId == 0) - { - tickTimerId = startTimer(1000) ; - return ; - } - - std::cerr << "ERROR !!" << std::endl; -} - -void NetworkSimulatorGUI::timerEvent(QTimerEvent *event) -{ - Q_UNUSED(event) ; - - //std::cerr << "timer event!" << std::endl; - - _viewer->network().tick() ; - -} - diff --git a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.h b/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.h deleted file mode 100644 index ddd2abef6..000000000 --- a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.h +++ /dev/null @@ -1,28 +0,0 @@ -#include "ui_NetworkSimulatorGUI.h" - -class TurtleRouterStatistics ; -class GlobalRouterStatistics ; -class NetworkViewer ; -class Network ; - -class NetworkSimulatorGUI: public QMainWindow, public Ui::NetworkSimulatorGUI -{ - Q_OBJECT - - public: - NetworkSimulatorGUI(Network& net) ; - - public slots: - void updateSelectedNode(int) ; - void toggleNetworkTraffic(bool) ; - - virtual void timerEvent(QTimerEvent *e) ; - - private: - NetworkViewer *_viewer ; - TurtleRouterStatistics *_turtle_router_statistics ; - GlobalRouterStatistics *_global_router_statistics ; - - int tickTimerId ; -}; - diff --git a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.ui b/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.ui deleted file mode 100644 index 6ac45d8bf..000000000 --- a/libretroshare/src/tests/network_simulator/gui/NetworkSimulatorGUI.ui +++ /dev/null @@ -1,106 +0,0 @@ - - - NetworkSimulatorGUI - - - - 0 - 0 - 901 - 600 - - - - MainWindow - - - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - flow - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - - 0 - 0 - 901 - 25 - - - - - File - - - - - - - - - - Load network - - - - - Save network - - - - - - diff --git a/libretroshare/src/tests/network_simulator/gui/NetworkViewer.cpp b/libretroshare/src/tests/network_simulator/gui/NetworkViewer.cpp deleted file mode 100644 index 8f1cf9535..000000000 --- a/libretroshare/src/tests/network_simulator/gui/NetworkViewer.cpp +++ /dev/null @@ -1,681 +0,0 @@ -#include -#include -#include - -#include - -#include "nscore/Network.h" -#include "nscore/MonitoredGRouterClient.h" -#include "NetworkViewer.h" - -NetworkViewer::NetworkViewer(QWidget *parent,Network&net) - : QGLViewer(parent),_network(net) , timerId(0) -{ - _current_selected_node = -1 ; - _current_displayed_node = -1 ; - _current_acted_node = -1 ; - - _dragging = false ; - _nodes_need_recomputing = true ; - - _node_coords.resize(net.n_nodes()) ; - _node_speeds.resize(net.n_nodes()) ; - - for(int i=0;i<_node_coords.size();++i) - { - _node_coords[i].x = drand48()*width()*5; - _node_coords[i].y = drand48()*height()*5 ; - _node_speeds[i].x = 0 ; - _node_speeds[i].y = 0 ; - } - - timerId = startTimer(1000/25) ; - - connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint))); - - action_ClientForHash = new QAction(tr("Client for new random hash"),this) ; - QObject::connect(action_ClientForHash,SIGNAL(triggered()),this,SLOT(actionClientForHash())) ; - - action_ProvideGRKey = new QAction(tr("Provide new GRouter key"),this) ; - QObject::connect(action_ProvideGRKey,SIGNAL(triggered()),this,SLOT(actionProvideGRKey())) ; - - setMouseTracking(true) ; -} - -void NetworkViewer::draw() -{ - glDisable(GL_DEPTH_TEST) ; - glClear(GL_COLOR_BUFFER_BIT) ; - - // for now, view is fixed. - - glMatrixMode(GL_MODELVIEW) ; - glPushMatrix() ; - glLoadIdentity() ; - glMatrixMode(GL_PROJECTION) ; - glPushMatrix() ; - glLoadIdentity() ; - glOrtho(0,width(),0,height(),1,-1) ; - - glEnable(GL_BLEND) ; - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) ; - - // Now, draw all edges - - std::set tunnel_nodes ; - - glEnable(GL_LINE_SMOOTH) ; - glBegin(GL_LINES) ; - - for(uint32_t i=0;i<_network.n_nodes();++i) - { - PeerNode::NodeTrafficInfo traffic_info ; - _network.node(i).getTrafficInfo(traffic_info) ; - - const std::set& neighs( _network.neighbors(i) ) ; - - for(std::set::const_iterator it(neighs.begin());it!=neighs.end();++it) - { - if(traffic_info.local_src.find(_network.node(*it).id().toStdString())!=traffic_info.local_src.end() || traffic_info.local_dst.find(_network.node(*it).id().toStdString())!=traffic_info.local_dst.end()) - { - glColor3f(0.9f,0.4f,0.2f) ; - tunnel_nodes.insert(i) ; - tunnel_nodes.insert(*it) ; - } - else - glColor3f(0.4f,0.4f,0.4f) ; - - if( i < *it ) - { - glVertex2f(_node_coords[ i].x, _node_coords[ i].y) ; - glVertex2f(_node_coords[*it].x, _node_coords[*it].y) ; - } - } - } - - glEnd() ; - - // Draw all nodes. - // - glEnable(GL_POINT_SMOOTH) ; - glPointSize(20.0f) ; - glBegin(GL_POINTS) ; - - if(_current_selected_node > -1) - { - glColor4f(1.0f,0.2f,0.1f,0.7f) ; - glVertex2f(_node_coords[_current_selected_node].x, _node_coords[_current_selected_node].y) ; - } - glEnd() ; - - glPointSize(10.0f) ; - glBegin(GL_POINTS) ; - - for(uint32_t i=0;i<_network.n_nodes();++i) - { - float r = 0.8 ; - float g = 0.8 ; - float b = 0.8 ; - - if(!_network.node(i).providedHashes().empty()) - r *= 2.0, g /= 2.0, b /= 2.0f ; - - if(!_network.node(i).managedHashes().empty()) - g *= 2.0, b /= 2.0, r /= 2.0f ; - - if(tunnel_nodes.find(i) != tunnel_nodes.end() && r==0.8f && g==0.8f && b==0.8f) - r = 0.9f, g=0.4f,b=0.2f ; - - std::vector infos ; - _network.node(i).global_router_service()->getRoutingCacheInfo(infos) ; - - if(infos.size() == 1) - switch(infos[0].status) - { - case 1: r=1 ; g=0.5; b=0.1 ; break ; - case 2: r=0.4; g=0.5; b=0.4 ; break ; - case 3: r=0.2; g=0.2; b=0.7 ; break ; - case 4: r=0.6; g=0.1; b=0.2 ; break ; - default: - r=0.2; g=0.2; b=0.2 ; break ; - } - - glColor3f(r,g,b) ; - - glVertex2f(_node_coords[i].x, _node_coords[i].y) ; - } - - glEnd() ; - - // Draw info about current node under mouse. - // - if(_current_displayed_node > -1) - { - const PeerNode& node(_network.node(_current_displayed_node)) ; - int offset = 0 ; - int text_height = 15 ; - - drawText(10+_node_coords[_current_displayed_node].x,offset + height()-_node_coords[_current_displayed_node].y, "Node id = " + QString::fromStdString(node.id().toStdString())) ; - offset += text_height ; - - for(std::set::const_iterator it(node.providedHashes().begin());it!=node.providedHashes().end();++it) - { - drawText(10+_node_coords[_current_displayed_node].x,offset + height()-_node_coords[_current_displayed_node].y, "Server for hash " + QString::fromStdString((*it).toStdString()) ); - offset += text_height ; - } - - for(std::set::const_iterator it(node.managedHashes().begin());it!=node.managedHashes().end();++it) - { - drawText(10+_node_coords[_current_displayed_node].x,offset + height()-_node_coords[_current_displayed_node].y, "Client for hash " + QString::fromStdString((*it).toStdString()) ) ; - offset += text_height ; - } - } - - glMatrixMode(GL_MODELVIEW) ; - glPopMatrix() ; - glMatrixMode(GL_PROJECTION) ; - glPopMatrix() ; -} - -#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr - -void fourn(double data[],unsigned long nn[],unsigned long ndim,int isign) -{ - int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2; - int ibit,idim,k1,k2,n,nprev,nrem,ntot; - double tempi,tempr; - double theta,wi,wpi,wpr,wr,wtemp; - - ntot=1; - for (idim=1;idim<=(long)ndim;idim++) - ntot *= nn[idim]; - nprev=1; - for (idim=ndim;idim>=1;idim--) { - n=nn[idim]; - nrem=ntot/(n*nprev); - ip1=nprev << 1; - ip2=ip1*n; - ip3=ip2*nrem; - i2rev=1; - for (i2=1;i2<=ip2;i2+=ip1) { - if (i2 < i2rev) { - for (i1=i2;i1<=i2+ip1-2;i1+=2) { - for (i3=i1;i3<=ip3;i3+=ip2) { - i3rev=i2rev+i3-i2; - SWAP(data[i3],data[i3rev]); - SWAP(data[i3+1],data[i3rev+1]); - } - } - } - ibit=ip2 >> 1; - while (ibit >= ip1 && i2rev > ibit) { - i2rev -= ibit; - ibit >>= 1; - } - i2rev += ibit; - } - ifp1=ip1; - while (ifp1 < ip2) { - ifp2=ifp1 << 1; - theta=isign*6.28318530717959/(ifp2/ip1); - wtemp=sin(0.5*theta); - wpr = -2.0*wtemp*wtemp; - wpi=sin(theta); - wr=1.0; - wi=0.0; - for (i3=1;i3<=ifp1;i3+=ip1) { - for (i1=i3;i1<=i3+ip1-2;i1+=2) { - for (i2=i1;i2<=ip3;i2+=ifp2) { - k1=i2; - k2=k1+ifp1; - tempr=wr*data[k2]-wi*data[k2+1]; - tempi=wr*data[k2+1]+wi*data[k2]; - data[k2]=data[k1]-tempr; - data[k2+1]=data[k1+1]-tempi; - data[k1] += tempr; - data[k1+1] += tempi; - } - } - wr=(wtemp=wr)*wpr-wi*wpi+wr; - wi=wi*wpr+wtemp*wpi+wi; - } - ifp1=ifp2; - } - nprev *= n; - } -} - -#undef SWAP - -static void convolveWithGaussian(double *forceMap,int S,int /*s*/) -{ - static double *bf = NULL ; - - if(bf == NULL) - { - bf = new double[S*S*2] ; - - for(int i=0;i derivative is constant - bf[2*(i+S*j)+1] = 0 ; - } - - unsigned long nn[2] = {S,S}; - fourn(&bf[-1],&nn[-1],2,1) ; - } - - unsigned long nn[2] = {S,S}; - fourn(&forceMap[-1],&nn[-1],2,1) ; - - for(int i=0;i=0 && i=0 && j new_coords(_node_coords) ; - - for(uint32_t i=0;i<_network.n_nodes();++i) - if(i != _current_selected_node || !_dragging) - { - float x = _node_coords[i].x ; - float y = _node_coords[i].y ; - - calculateForces(i,forceMap,S,S,x,y,speedf,new_coords[i].x,new_coords[i].y); - } - - bool itemsMoved = false; - for(uint32_t i=0;i<_node_coords.size();++i) - { - if( fabsf(_node_coords[i].x - new_coords[i].x) > 1.0 || fabsf(_node_coords[i].y - new_coords[i].y) > 1.0) - itemsMoved = true; - - //std::cerr << "Old i = " << _node_coords[i].x << ", new = " << new_coords[i].x << std::endl; - _node_coords[i] = new_coords[i] ; - } - - if (!itemsMoved) { - // killTimer(timerId); - //#ifdef DEBUG_ELASTIC - std::cerr << "Killing timr" << std::endl ; - _nodes_need_recomputing = false ; - //#endif - timerId = 0; - } - else - { - updateGL() ; - usleep(2000) ; - } - } - else - updateGL() ; - -} - -void NetworkViewer::mouseMoveEvent(QMouseEvent *e) -{ - if(_dragging && _current_selected_node >= 0) - { - _node_coords[_current_selected_node].x = e->x() ; - _node_coords[_current_selected_node].y = height() - e->y() ; - - _nodes_need_recomputing = true ; - - updateGL() ; - } - - float x = e->x() ; - float y = height()-e->y() ; - - _current_displayed_node = -1 ; - - for(uint32_t i=0;i<_node_coords.size();++i) - if( pow(_node_coords[i].x-x,2)+pow(_node_coords[i].y-y,2) < 5*5) - { - _current_displayed_node = i; - break ; - } -} - -void NetworkViewer::mouseReleaseEvent(QMouseEvent *e) -{ - _dragging = false ; -} - -void NetworkViewer::mousePressEvent(QMouseEvent *e) -{ - float x = e->x() ; - float y = height() - e->y() ; - - // find which node is selected - - for(uint32_t i=0;i<_node_coords.size();++i) - if( pow(_node_coords[i].x - x,2)+pow(_node_coords[i].y - y,2) < 10*10 ) - { - if(e->button() == Qt::LeftButton) - { - _current_selected_node = i ; - _dragging = true ; - updateGL() ; - emit nodeSelected(i) ; - return ; - } - - if(e->button() == Qt::RightButton) - { - _current_acted_node = i ; - emit customContextMenuRequested(QPoint(e->x(),e->y())) ; - return ; - } - } - - _dragging = false ; - _current_selected_node = -1 ; -} - -void NetworkViewer::calculateForces(const Network::NodeId& node_id,const double *map,int W,int H,float x,float y,float /*speedf*/,float& new_x, float& new_y) -{ -#ifdef A_FAIRE - if (mouseGrabberItem() == this) - { - new_x = x ; - new_y = y ; - return; - } -#endif - - // Sum up all forces pushing this item away - qreal xforce = 0; - qreal yforce = 0; - - float dei=0.0f ; - float dej=0.0f ; - - static float *e = NULL ; - static const int KS = 5 ; - - if(e == NULL) - { - e = new float[(2*KS+1)*(2*KS+1)] ; - - for(int i=-KS;i<=KS;++i) - for(int j=-KS;j<=KS;++j) - e[i+KS+(2*KS+1)*(j+KS)] = exp( -(i*i+j*j)/30.0 ) ; // can be precomputed - } - - for(int i=-KS;i<=KS;++i) - for(int j=-KS;j<=KS;++j) - { - int X = std::min(W-1,std::max(0,(int)rint(x/(float)width()*W))) ; - int Y = std::min(H-1,std::max(0,(int)rint(y/(float)height()*H))) ; - - float val = map[2*((i+X+W)%W + W*((j+Y+H)%H))] ; - - dei += i * e[i+KS+(2*KS+1)*(j+KS)] * val ; - dej += j * e[i+KS+(2*KS+1)*(j+KS)] * val ; - } - - xforce = REPULSION_FACTOR * dei/25.0; - yforce = REPULSION_FACTOR * dej/25.0; - - // Now subtract all forces pulling items together - // - const std::set& neighbs(_network.neighbors(node_id)) ; - double weight = neighbs.size() + 1 ; - - for(std::set::const_iterator it(neighbs.begin());it!=neighbs.end();++it) - { - NodeCoord pos; - double w2 ; // This factor makes the edge length depend on connectivity, so clusters of friends tend to stay in the - // same location. - // - - pos.x = _node_coords[*it].x - x ; //mapFromItem(edge->destNode(), 0, 0); - pos.y = _node_coords[*it].y - y ; //mapFromItem(edge->destNode(), 0, 0); - - w2 = sqrtf(std::min(neighbs.size(),_network.neighbors(*it).size())) ; - - float dist = sqrtf(pos.x*pos.x + pos.y*pos.y) ; - float val = dist - NODE_DISTANCE * w2 ; - - xforce += 0.01*pos.x * val / weight; - yforce += 0.01*pos.y * val / weight; - } - - xforce -= FRICTION_FACTOR * _node_speeds[node_id].x ; - yforce -= FRICTION_FACTOR * _node_speeds[node_id].y ; - - // This term drags nodes away from the sides. - // - if(x < 15) xforce += 100.0/(x+0.1) ; - if(y < 15) yforce += 100.0/(y+0.1) ; - if(x > width()-15) xforce -= 100.0/(width()-x+0.1) ; - if(y > height()-15) yforce -= 100.0/(height()-y+0.1) ; - - // now time filter: - - _node_speeds[node_id].x += xforce / MASS_FACTOR; - _node_speeds[node_id].y += yforce / MASS_FACTOR; - - if(_node_speeds[node_id].x > 10) _node_speeds[node_id].x = 10.0f ; - if(_node_speeds[node_id].y > 10) _node_speeds[node_id].y = 10.0f ; - if(_node_speeds[node_id].x <-10) _node_speeds[node_id].x =-10.0f ; - if(_node_speeds[node_id].y <-10) _node_speeds[node_id].y =-10.0f ; - - new_x = x + _node_speeds[node_id].x ; - new_y = y + _node_speeds[node_id].y ; - - new_x = std::min(std::max(new_x, 10.0f), width() - 10.0f); - new_y = std::min(std::max(new_y, 10.0f), height() - 10.0f); -} - -void NetworkViewer::contextMenu(QPoint p) -{ - std::cerr << "Context menu request at point " << p.x() << " " << p.y() << std::endl; - - QMenu contextMnu ;//= ui.msgText->createStandardContextMenu(matrix.map(point)); - - contextMnu.addAction(action_ClientForHash); - - if(_current_acted_node == -1) - return ; - - std::cerr << "acting on node " << _network.node(_current_acted_node).id() << std::endl; - - // make a list of hashes provided by all nodes except this one - std::set managed_hashes ; - std::set provided_hashes ; - - for(uint32_t i=0;i<_network.n_nodes();++i) - if(i != _current_acted_node) - { - managed_hashes.insert( _network.node(i).managedHashes().begin(), _network.node(i).managedHashes().end()) ; - provided_hashes.insert( _network.node(i).providedHashes().begin(), _network.node(i).providedHashes().end()) ; - } - - if(!managed_hashes.empty()) - { - QMenu *Mnu2 = contextMnu.addMenu("Provide hash") ; - - for(std::set::const_iterator it(managed_hashes.begin());it!=managed_hashes.end();++it) - { - QAction* provide_hash_action = new QAction(QString::fromStdString((*it).toStdString()), Mnu2); - connect(provide_hash_action, SIGNAL(triggered()), this, SLOT(actionProvideHash())); - Mnu2->addAction(provide_hash_action); - } - } - if(!provided_hashes.empty()) - { - QMenu *Mnu2 = contextMnu.addMenu("Client for hash") ; - - for(std::set::const_iterator it(provided_hashes.begin());it!=provided_hashes.end();++it) - { - QAction* manage_hash_action = new QAction(QString::fromStdString((*it).toStdString()), Mnu2); - connect(manage_hash_action, SIGNAL(triggered()), this, SLOT(actionClientForHash())); - Mnu2->addAction(manage_hash_action); - } - } - contextMnu.addSeparator() ; - - // GRouter stuff - - contextMnu.addAction(action_ProvideGRKey); - - std::set provided_keys ; - - for(uint32_t i=0;i<_network.n_nodes();++i) - if(i != _current_acted_node) - provided_keys.insert( _network.node(i).providedGRKeys().begin(), _network.node(i).providedGRKeys().end()) ; - - if(!provided_keys.empty()) - { - QMenu *Mnu2 = contextMnu.addMenu("Send message to Key") ; - - for(std::set::const_iterator it(provided_keys.begin());it!=provided_keys.end();++it) - { - QAction* send_message_action = new QAction(QString::fromStdString((*it).toStdString()), Mnu2); - connect(send_message_action, SIGNAL(triggered()), this, SLOT(actionSendToGRKey())); - Mnu2->addAction(send_message_action); - } - } - // Execute! - - contextMnu.exec(mapToGlobal(p)); -} - -void NetworkViewer::actionClientForHash() -{ - if(_current_acted_node < 0) - return ; - - RsFileHash hash ; - - if(qobject_cast(sender())->text().length() == 40) //data().toString().toStdString(); - { - hash = RsFileHash(qobject_cast(sender())->text().toStdString()) ; - - std::cerr << "Managing existing hash " << hash << std::endl; - } - else - { - std::cerr << "Managing random hash..." << std::endl; - - hash = RsFileHash::random() ; - } - - - std::cerr << " current node = " << _current_acted_node << std::endl ; - std::cerr << " adding random hash = " << hash << std::endl; - - _network.node(_current_acted_node).manageFileHash(hash) ; - - updateGL() ; -} - -void NetworkViewer::actionProvideHash() -{ - QString hash = qobject_cast(sender())->text() ;//data().toString().toStdString(); - - if(_current_acted_node < 0) - return ; - - std::cerr << "Providing hash " << hash.toStdString() << std::endl; - _network.node(_current_acted_node).provideFileHash(RsFileHash(hash.toStdString())) ; - - updateGL() ; -} - -void NetworkViewer::actionSendToGRKey() -{ - if(_current_acted_node < 0) - return ; - - GRouterKeyId key_id ; - - if(qobject_cast(sender())->text().length() == 32) //data().toString().toStdString(); - { - key_id = GRouterKeyId(qobject_cast(sender())->text().toStdString()) ; - - std::cerr << "Sending to existing key " << key_id << std::endl; - } - - std::cerr << " current node = " << _current_acted_node << std::endl ; - std::cerr << " sending message = " << key_id << std::endl; - - _network.node(_current_acted_node).sendToGRKey(key_id) ; - - updateGL() ; -} - -void NetworkViewer::actionProvideGRKey() -{ - if(_current_acted_node < 0) - return ; - - GRouterKeyId key_id = GRouterKeyId::random(); - QString key = QString::fromStdString(key_id.toStdString()) ; - - std::cerr << "Providing new grouter key " << key_id << std::endl; - _network.node(_current_acted_node).provideGRKey(key_id) ; - - updateGL() ; -} - - diff --git a/libretroshare/src/tests/network_simulator/gui/NetworkViewer.h b/libretroshare/src/tests/network_simulator/gui/NetworkViewer.h deleted file mode 100644 index f06e493e2..000000000 --- a/libretroshare/src/tests/network_simulator/gui/NetworkViewer.h +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include - -// The network simulator GUI has the following functionalities: -// -// 1 - show the network graph -// * the graph should spread in space automatically. We should use the code from the NetworkView for that. -// * each edge will be drawn with a color that displays used bandwidth along the edge, or TR sent to the edge, etc. -// * individual tunnels should be shown, in order to see what shape they have -// -// 2 - show info about each node. One needs a node widget that gets updated with whatever is to be read from the current node -// -// 3 - buttons to re-initiate a new network, or reset the network. -// -// 4 - buttons to inject information into the network: -// * shared files in some nodes. Should be handled by derivign the component that the turtle router accesses for local searches. -// * file requests in other nodes. Eazy: one just needs to ask the turtle router of the node to handle the hash. -// -// 5 - perturbate the network -// * change the load of each node, and the delay when forwarding requests. -// -#include "nscore/Network.h" - -class NetworkViewer: public QGLViewer -{ - Q_OBJECT - - public: - NetworkViewer(QWidget *parent,Network& network) ; - - virtual void draw() ; - virtual void keyPressEvent(QKeyEvent *) {} - virtual void mousePressEvent(QMouseEvent *) ; - virtual void mouseReleaseEvent(QMouseEvent *) ; - virtual void mouseMoveEvent(QMouseEvent *) ; - - const Network& network() const { return _network ; } - Network& network() { return _network ; } - - signals: - void nodeSelected(int) ; - - public slots: - void timerEvent(QTimerEvent *) ; - void contextMenu(QPoint) ; - void actionClientForHash() ; - void actionProvideHash() ; - void actionSendToGRKey() ; - void actionProvideGRKey() ; - - private: - void calculateForces(const Network::NodeId& node_id,const double *map,int W,int H,float x,float y,float /*speedf*/,float& new_x, float& new_y) ; - - typedef struct - { - float x ; - float y ; - } NodeCoord ; - - Network& _network ; - - std::vector _node_coords ; - std::vector _node_speeds ; - - static const float MASS_FACTOR = 10 ; - static const float FRICTION_FACTOR = 15.8 ; - static const float REPULSION_FACTOR = 8 ; - static const float NODE_DISTANCE = 30.0 ; - - int timerId ; - - int _current_selected_node ; - int _current_displayed_node ; - int _current_acted_node ; - bool _dragging ; - bool _nodes_need_recomputing ; - - QAction *action_SendToGRKey ; - QAction *action_ProvideGRKey ; - QAction *action_ClientForHash ; - QAction *action_ProvideHash ; -}; - diff --git a/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.cpp b/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.cpp deleted file mode 100644 index 9cb849e7f..000000000 --- a/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include "RsAutoUpdatePage.h" - -bool RsAutoUpdatePage::_locked = false ; - -RsAutoUpdatePage::RsAutoUpdatePage(int ms_update_period, QWidget *parent, Qt::WindowFlags flags) - : QWidget(parent, flags) -{ - _timer = new QTimer ; - _timer->setInterval(ms_update_period); - _timer->setSingleShot(true); - - QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(timerUpdate())) ; - - _timer->start() ; -} - -RsAutoUpdatePage::~RsAutoUpdatePage() -{ - if(_timer != NULL) - delete _timer ; - - _timer = NULL ; -} - -void RsAutoUpdatePage::showEvent(QShowEvent */*event*/) -{ - //std::cout << "RsAutoUpdatePage::showEvent() In show event !!" << std::endl ; - if(!_locked) - updateDisplay(); -} - -void RsAutoUpdatePage::timerUpdate() -{ - // only update when the widget is visible. - // - if(_locked == false && isVisible()) { - updateDisplay(); - update() ; // Qt flush - } - - _timer->start() ; -} - -void RsAutoUpdatePage::lockAllEvents() { _locked = true ; } -void RsAutoUpdatePage::unlockAllEvents() { _locked = false ; } -bool RsAutoUpdatePage::eventsLocked() { return _locked ; } diff --git a/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.h b/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.h deleted file mode 100644 index ea1b0c8c8..000000000 --- a/libretroshare/src/tests/network_simulator/gui/RsAutoUpdatePage.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include - -// This class implement a basic RS functionality which is that widgets displayign info -// should update regularly. They also should update only when visible, to save CPU time. -// -// Using this class simply needs to derive your widget from RsAutoUpdateWidget -// and oveload the update() function with the actual code that updates the -// widget. -// -class QTimer ; - -class RsAutoUpdatePage: public QWidget -{ - Q_OBJECT - - public: - RsAutoUpdatePage(int ms_update_period = 1000, QWidget *parent = NULL, Qt::WindowFlags flags = 0) ; - virtual ~RsAutoUpdatePage() ; - - virtual void updateDisplay() {} - - static void lockAllEvents() ; - static void unlockAllEvents() ; - static bool eventsLocked() ; - - protected: - virtual void showEvent(QShowEvent *e) ; - - private slots: - void timerUpdate() ; - - private: - QTimer *_timer ; - - static bool _locked ; -}; - diff --git a/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.cpp b/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.cpp deleted file mode 100644 index b45ac9996..000000000 --- a/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/**************************************************************** - * RetroShare is distributed under the following license: - * - * Copyright (C) 20011, RetroShare Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - ****************************************************************/ - -#include -#include -#include - -#include -#include - -#include -#include -#include "TurtleRouterStatistics.h" - -static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; - -class TRHistogram -{ - public: - TRHistogram(const std::vector& info) :_infos(info) {} - - QColor colorScale(float f) - { - if(f == 0) - return QColor::fromHsv(0,0,192) ; - else - return QColor::fromHsv((int)((1.0-f)*280),200,255) ; - } - - virtual void draw(QPainter *painter,int& ox,int& oy,const QString& title) - { - static const int MaxTime = 61 ; - static const int MaxDepth = 8 ; - static const int cellx = 7 ; - static const int celly = 12 ; - - int save_ox = ox ; - painter->setPen(QColor::fromRgb(0,0,0)) ; - painter->drawText(2+ox,celly+oy,title) ; - oy+=2+2*celly ; - - if(_infos.empty()) - return ; - - ox += 10 ; - std::map > hits ; - std::map > depths ; - std::map >::iterator it ; - - int max_hits = 1; - int max_depth = 1; - - for(uint32_t i=0;i<_infos.size();++i) - { - std::vector& h(hits[_infos[i].source_peer_id]) ; - std::vector& g(depths[_infos[i].source_peer_id]) ; - - if(h.size() <= _infos[i].age) - h.resize(MaxTime,0) ; - - if(g.empty()) - g.resize(MaxDepth,0) ; - - if(_infos[i].age < h.size()) - { - h[_infos[i].age]++ ; - if(h[_infos[i].age] > max_hits) - max_hits = h[_infos[i].age] ; - } - if(_infos[i].depth < g.size()) - { - g[_infos[i].depth]++ ; - - if(g[_infos[i].depth] > max_depth) - max_depth = g[_infos[i].depth] ; - } - } - - int max_bi = std::max(max_hits,max_depth) ; - int p=0 ; - - for(it=depths.begin();it!=depths.end();++it,++p) - for(int i=0;ifillRect(ox+MaxTime*cellx+20+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ; - - painter->setPen(QColor::fromRgb(0,0,0)) ; - painter->drawRect(ox+MaxTime*cellx+20,oy,MaxDepth*cellx,p*celly) ; - - for(int i=0;idrawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; - - p=0 ; - int great_total = 0 ; - - for(it=hits.begin();it!=hits.end();++it,++p) - { - int total = 0 ; - - for(int i=0;ifillRect(ox+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ; - total += it->second[i] ; - } - - painter->setPen(QColor::fromRgb(0,0,0)) ; - painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx,oy+(p+1)*celly,TurtleRouterStatistics::getPeerName(it->first)) ; - painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly,"("+QString::number(total)+")") ; - great_total += total ; - } - - painter->drawRect(ox,oy,MaxTime*cellx,p*celly) ; - - for(int i=0;idrawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; - for(int i=0;idrawText(ox+MaxTime*cellx+20+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; - painter->setPen(QColor::fromRgb(255,130,80)) ; - painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly+4,"("+QString::number(great_total)+")"); - - oy += (p+1)*celly+6 ; - - painter->setPen(QColor::fromRgb(0,0,0)) ; - painter->drawText(ox,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Age in seconds")+")"); - painter->drawText(ox+MaxTime*cellx+20,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Depth")+")"); - - painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "total")+")"); - - oy += 3*celly ; - - // now, draw a scale - - int last_hts = -1 ; - int cellid = 0 ; - - for(int i=0;i<=10;++i) - { - int hts = (int)(max_bi*i/10.0) ; - - if(hts > last_hts) - { - painter->fillRect(ox+cellid*(cellx+22),oy,cellx,celly,colorScale(i/10.0f)) ; - painter->setPen(QColor::fromRgb(0,0,0)) ; - painter->drawRect(ox+cellid*(cellx+22),oy,cellx,celly) ; - painter->drawText(ox+cellid*(cellx+22)+cellx+4,oy+celly,QString::number(hts)) ; - last_hts = hts ; - ++cellid ; - } - } - - oy += celly*2 ; - - ox = save_ox ; - } - - private: - const std::vector& _infos ; -}; - -TurtleRouterStatistics::TurtleRouterStatistics(QWidget *parent) - : RsAutoUpdatePage(2000,parent) -{ - setupUi(this) ; - - _turtle = NULL ; - - _tunnel_statistics_F->setWidget( _tst_CW = new TurtleRouterStatisticsWidget() ) ; - _tunnel_statistics_F->setWidgetResizable(true); - _tunnel_statistics_F->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - _tunnel_statistics_F->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - _tunnel_statistics_F->viewport()->setBackgroundRole(QPalette::NoRole); - _tunnel_statistics_F->setFrameStyle(QFrame::NoFrame); - _tunnel_statistics_F->setFocusPolicy(Qt::NoFocus); -} - -TurtleRouterStatistics::~TurtleRouterStatistics() -{ -} - -void TurtleRouterStatistics::updateDisplay() -{ - if(_turtle == NULL) - return ; - - std::vector > hashes_info ; - std::vector > tunnels_info ; - std::vector search_reqs_info ; - std::vector tunnel_reqs_info ; - - _turtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ; - - //updateTunnelRequests(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ; - _tst_CW->updateTunnelStatistics(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info,_turtle) ; - _tst_CW->update(); -} - -QString TurtleRouterStatistics::getPeerName(const RsPeerId& peer_id) -{ - static std::map names ; - - std::map::const_iterator it = names.find(peer_id) ; - - if( it != names.end()) - return it->second ; - else - return (names[peer_id] = QString::fromStdString(peer_id.toStdString())) ; -} - -TurtleRouterStatisticsWidget::TurtleRouterStatisticsWidget(QWidget *parent) - : QWidget(parent) -{ - maxWidth = 200 ; - maxHeight = 0 ; -} - -void TurtleRouterStatisticsWidget::updateTunnelStatistics(const std::vector >& /*hashes_info*/, - const std::vector >& /*tunnels_info*/, - const std::vector& search_reqs_info, - const std::vector& tunnel_reqs_info, - const RsTurtle *turtle) - -{ - static const int cellx = 6 ; - static const int celly = 10+4 ; - - QPixmap tmppixmap(maxWidth, maxHeight); - tmppixmap.fill(this, 0, 0); - setFixedHeight(maxHeight); - - QPainter painter(&tmppixmap); - painter.initFrom(this); - - maxHeight = 500 ; - - // std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl; - // draw... - int ox=5,oy=5 ; - - TRHistogram(search_reqs_info).draw(&painter,ox,oy,tr("Search requests repartition") + ":") ; - - painter.setPen(QColor::fromRgb(70,70,70)) ; - painter.drawLine(0,oy,maxWidth,oy) ; - oy += celly ; - - TRHistogram(tunnel_reqs_info).draw(&painter,ox,oy,tr("Tunnel requests repartition") + ":") ; - - // now give information about turtle traffic. - // - TurtleTrafficStatisticsInfo info ; - turtle->getTrafficStatistics(info) ; - - painter.setPen(QColor::fromRgb(70,70,70)) ; - painter.drawLine(0,oy,maxWidth,oy) ; - oy += celly ; - - painter.drawText(ox,oy+celly,tr("Turtle router traffic")+":") ; oy += celly*2 ; - painter.drawText(ox+2*cellx,oy+celly,tr("Tunnel requests Up")+"\t: " + speedString(info.tr_up_Bps) ) ; oy += celly ; - painter.drawText(ox+2*cellx,oy+celly,tr("Tunnel requests Dn")+"\t: " + speedString(info.tr_dn_Bps) ) ; oy += celly ; - painter.drawText(ox+2*cellx,oy+celly,tr("Incoming file data")+"\t: " + speedString(info.data_dn_Bps) ) ; oy += celly ; - painter.drawText(ox+2*cellx,oy+celly,tr("Outgoing file data")+"\t: " + speedString(info.data_up_Bps) ) ; oy += celly ; - painter.drawText(ox+2*cellx,oy+celly,tr("Forwarded data ")+"\t: " + speedString(info.unknown_updn_Bps) ) ; oy += celly ; - - QString prob_string ; - - for(uint i=0;i -#include -#include "ui_TurtleRouterStatistics.h" -#include "RsAutoUpdatePage.h" - -class TurtleRouterStatisticsWidget ; - -class TurtleRouterStatistics: public RsAutoUpdatePage, public Ui::TurtleRouterStatistics -{ - Q_OBJECT - - public: - TurtleRouterStatistics(QWidget *parent = NULL) ; - ~TurtleRouterStatistics(); - - // Cache for peer names. - static QString getPeerName(const RsPeerId& peer_id) ; - - void setTurtleRouter(const RsTurtle *turtle) { _turtle = turtle ; } - - virtual void updateDisplay() ; - private: - - TurtleRouterStatisticsWidget *_tst_CW ; - const RsTurtle *_turtle ; -} ; - -class TurtleRouterStatisticsWidget: public QWidget -{ - Q_OBJECT - - public: - TurtleRouterStatisticsWidget(QWidget *parent = NULL) ; - - virtual void paintEvent(QPaintEvent *event) ; - virtual void resizeEvent(QResizeEvent *event); - - void updateTunnelStatistics( const std::vector > >&, - const std::vector > >&, - const std::vector&, - const std::vector&, - const RsTurtle *turtle) ; - - private: - static QString speedString(float f) ; - - QPixmap pixmap ; - int maxWidth,maxHeight ; -}; - diff --git a/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.ui b/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.ui deleted file mode 100644 index 365d3f362..000000000 --- a/libretroshare/src/tests/network_simulator/gui/TurtleRouterStatistics.ui +++ /dev/null @@ -1,55 +0,0 @@ - - - TurtleRouterStatistics - - - - 0 - 0 - 611 - 408 - - - - Router Statistics - - - - :/images/rstray3.png:/images/rstray3.png - - - - - - Qt::Vertical - - - - QFrame::NoFrame - - - Qt::ScrollBarAlwaysOff - - - true - - - - - 0 - 0 - 593 - 390 - - - - - - - - - - - - - diff --git a/libretroshare/src/tests/network_simulator/gui/gui.pro b/libretroshare/src/tests/network_simulator/gui/gui.pro deleted file mode 100644 index 8cb01b4a2..000000000 --- a/libretroshare/src/tests/network_simulator/gui/gui.pro +++ /dev/null @@ -1,25 +0,0 @@ -TEMPLATE = app - -CONFIG *= qt qglviewer uic -QT *= xml opengl - -INCLUDEPATH *= ../../.. .. - -TARGET = NetworkSim -DESTDIR = ../bin - -PRE_TARGETDEPS = ../nscore/nscore.pro - -SOURCES = main.cpp NetworkViewer.cpp NetworkSimulatorGUI.cpp \ - TurtleRouterStatistics.cpp RsAutoUpdatePage.cpp GlobalRouterStatistics.cpp - -HEADERS = NetworkViewer.h NetworkSimulatorGUI.h \ - TurtleRouterStatistics.h RsAutoUpdatePage.h GlobalRouterStatistics.h - -FORMS = NetworkSimulatorGUI.ui TurtleRouterStatistics.ui GlobalRouterStatistics.ui - -LIBS *= ../../../lib/libretroshare.a \ - ../../../../../libbitdht/src/lib/libbitdht.a \ - ../../../../../openpgpsdk/src/lib/libops.a \ - ../lib/libnscore.a \ - -lsqlcipher -lgnome-keyring -lupnp -lssl -lcrypto -lbz2 -lixml diff --git a/libretroshare/src/tests/network_simulator/gui/main.cpp b/libretroshare/src/tests/network_simulator/gui/main.cpp deleted file mode 100644 index f6c1e1c22..000000000 --- a/libretroshare/src/tests/network_simulator/gui/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include - -#include "nscore/Network.h" -#include "nscore/MonitoredRsPeers.h" - -#include - -#include "NetworkSimulatorGUI.h" - -int main(int argc, char *argv[]) -{ - feenableexcept(FE_INVALID) ; - feenableexcept(FE_DIVBYZERO) ; - -#ifndef DEBUG - try - { -#endif - argstream as(argc,argv) ; - bool show_gui = false; - int nb_nodes = 20 ; - float connexion_probability = 0.2 ; - - as >> option('i',"gui",show_gui,"show gui (vs. do the pipeline automatically)") - >> parameter('n',"nodes",nb_nodes,"number of nodes in the network",false) - >> parameter('p',"connexion probability",connexion_probability,"probability that two nodes are connected (exponential law)",false) - >> help() ; - - as.defaultErrorHandling() ; - - // 2 - call the full pipeline - - Network network ; - - network.initRandom(nb_nodes,connexion_probability) ; - - rsPeers = new MonitoredRsPeers(network) ; - - if(show_gui) - { - QApplication app(argc,argv) ; - - NetworkSimulatorGUI pgui(network); - pgui.show() ; - - return app.exec() ; - } - - return 0 ; -#ifndef DEBUG - } - catch(std::exception& e) - { - std::cerr << "Unhandled exception: " << e.what() << std::endl; - return 1 ; - } -#endif -} - diff --git a/libretroshare/src/tests/network_simulator/network_simulator.pro b/libretroshare/src/tests/network_simulator/network_simulator.pro deleted file mode 100644 index 8564c70fe..000000000 --- a/libretroshare/src/tests/network_simulator/network_simulator.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = nscore gui diff --git a/libretroshare/src/tests/network_simulator/nscore/FakeComponents.h b/libretroshare/src/tests/network_simulator/nscore/FakeComponents.h deleted file mode 100644 index b54ed8681..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/FakeComponents.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include -#include -#include - -class FakeLinkMgr: public p3LinkMgrIMPL -{ - public: - FakeLinkMgr(const RsPeerId& own_id,const std::list& friends) - : p3LinkMgrIMPL(NULL,NULL),_own_id(own_id),_friends(friends) - { - } - - virtual const RsPeerId& getOwnId() { return _own_id ; } - virtual void getOnlineList(std::list& lst) { lst = _friends ; } - virtual uint32_t getLinkType(const RsPeerId&) { return RS_NET_CONN_TCP_ALL | RS_NET_CONN_SPEED_NORMAL; } - - virtual bool getPeerName(const RsPeerId &ssl_id, std::string &name) { name = ssl_id.toStdString() ; return true ;} - - private: - RsPeerId _own_id ; - std::list _friends ; -}; - -class FakePublisher: public pqiPublisher -{ - public: - virtual bool sendItem(RsRawItem *item) - { - _item_queue.push_back(item) ; - return true ; - } - - RsRawItem *outgoing() - { - if(_item_queue.empty()) - return NULL ; - - RsRawItem *item = _item_queue.front() ; - _item_queue.pop_front() ; - return item ; - } - - private: - std::list _item_queue ; -}; - -class FakePeerMgr: public p3PeerMgrIMPL -{ - public: - FakePeerMgr(const RsPeerId& own,const std::list& ids) - : p3PeerMgrIMPL(own,RsPgpId(),"no name","location name") - { - for(std::list::const_iterator it(ids.begin());it!=ids.end();++it) - _ids.insert(*it) ; - } - - virtual bool idFriend(const RsPeerId& ssl_id) { return _ids.find(ssl_id) != _ids.end() ; } - - virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) - { - return ~ServicePermissionFlags(0) ; - } - std::set _ids ; -}; - -class FakeServiceControl: public p3ServiceControl -{ - public: - FakeServiceControl(p3LinkMgr *lm) - : p3ServiceControl(lm),mLink(lm) - { - } - - virtual void getPeersConnected(const uint32_t serviceId, std::set &peerSet) - { - std::list ids ; - mLink->getOnlineList(ids) ; - - for(std::list::const_iterator it(ids.begin());it!=ids.end();++it) - peerSet.insert(*it) ; - } - - virtual bool checkFilter(uint32_t,const RsPeerId& id) - { - return true ; - } - p3LinkMgr *mLink; -}; - diff --git a/libretroshare/src/tests/network_simulator/nscore/MainLoop.cpp b/libretroshare/src/tests/network_simulator/nscore/MainLoop.cpp deleted file mode 100644 index 22e89127e..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MainLoop.cpp +++ /dev/null @@ -1,24 +0,0 @@ - -void NetworkLoop() -{ - while(true) - { - std::cerr<< "network loop: tick()" << std::endl; - - // Get items for each components and send them to their destination. - // - for(int i=0;in_nodes();++i) - { - RsRawItem *item ; - - while(item = network->node(i).outgoing()) - { - PeerNode& node = network->node_by_id(item->peerId()) - item->peerId(network->node(i)->id()) ; - - node.received(item) ; - } - } - usleep(500000) ; - } -} diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.cpp b/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.cpp deleted file mode 100644 index 9371bbd29..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "MonitoredGRouterClient.h" - -const uint32_t MonitoredGRouterClient::GROUTER_CLIENT_SERVICE_ID_00 = 0x0111 ; - -void MonitoredGRouterClient::receiveGRouterData(const GRouterKeyId& destination_key,const RsGRouterGenericDataItem *item) -{ - std::cerr << "received one global grouter item for key " << destination_key << std::endl; -} - -void MonitoredGRouterClient::provideKey(const GRouterKeyId& key_id) -{ - _grouter->registerKey(key_id,GROUTER_CLIENT_SERVICE_ID_00,"test grouter address") ; - - std::cerr << "Registered new key " << key_id << " for service " << std::hex << GROUTER_CLIENT_SERVICE_ID_00 << std::dec << std::endl; -} - -void MonitoredGRouterClient::sendMessage(const GRouterKeyId& destination_key_id) const -{ - RsGRouterGenericDataItem *item = new RsGRouterGenericDataItem ; - item->data_size = 1000 + (RSRandom::random_u32()%1000) ; - item->data_bytes = (unsigned char *)malloc(item->data_size) ; - - RSRandom::random_bytes(item->data_bytes,item->data_size) ; - GRouterMsgPropagationId propagation_id ; - - _grouter->sendData(destination_key_id,GROUTER_CLIENT_SERVICE_ID_00,item,propagation_id) ; -} diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.h b/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.h deleted file mode 100644 index a778c8c37..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredGRouterClient.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -class MonitoredGRouterClient: public GRouterClientService -{ - public: - static const uint32_t GROUTER_CLIENT_SERVICE_ID_00 ; - - // Derived from grouterclientservice.h - // - virtual void connectToGlobalRouter(p3GRouter *p) { _grouter = p ; p->registerClientService(GROUTER_CLIENT_SERVICE_ID_00,this) ; } - virtual void receiveGRouterData(const GRouterKeyId& destination_key,const RsGRouterGenericDataItem *item); - - // Own functionality - // - void sendMessage(const GRouterKeyId& destination_key) const ; - void provideKey(const GRouterKeyId& key) ; - - private: - p3GRouter *_grouter ; -}; - diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.cpp b/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.cpp deleted file mode 100644 index aa952ea68..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "MonitoredRsPeers.h" - -MonitoredRsPeers::MonitoredRsPeers(const Network& net) - : p3Peers(NULL,NULL,NULL),_network(net) -{ -} - -bool MonitoredRsPeers::getPeerDetails(const std::string& str,RsPeerDetails& details) -{ - std::cerr << __PRETTY_FUNCTION__ << " called" << std::endl; -} diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.h b/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.h deleted file mode 100644 index 4706cc316..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredRsPeers.h +++ /dev/null @@ -1,14 +0,0 @@ -#include - -class Network ; - -class MonitoredRsPeers: public p3Peers -{ - public: - MonitoredRsPeers(const Network& net) ; - - virtual bool getPeerDetails(const std::string& peer_id,RsPeerDetails& details) ; - - private: - const Network& _network ; -}; diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.cpp b/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.cpp deleted file mode 100644 index 3ed946ac3..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "MonitoredTurtleClient.h" - -bool MonitoredTurtleClient::handleTunnelRequest(const TurtleFileHash& hash,const RsPeerId& peer_id) -{ - std::map::const_iterator it( _local_files.find(hash) ) ; - - return (it != _local_files.end() ) ; -} - -void MonitoredTurtleClient::provideFileHash(const RsFileHash& hash) -{ - FileInfo& info( _local_files[hash] ) ; - - info.fname = "File 1" ; - info.size = 100000 ; - info.hash = hash ; -} - diff --git a/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.h b/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.h deleted file mode 100644 index bb03af705..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/MonitoredTurtleClient.h +++ /dev/null @@ -1,17 +0,0 @@ -#include - -class MonitoredTurtleClient: public RsTurtleClientService -{ -public: - virtual void addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) {} - virtual void removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) {} - virtual void connectToTurtleRouter(p3turtle*p) { p->registerTunnelService(this) ; } - - bool handleTunnelRequest(const TurtleFileHash& hash,const RsPeerId& peer_id); - void provideFileHash(const RsFileHash& hash); - void requestFileHash(const RsFileHash& hash) ; - -private: - std::map _local_files ; -}; - diff --git a/libretroshare/src/tests/network_simulator/nscore/Network.cpp b/libretroshare/src/tests/network_simulator/nscore/Network.cpp deleted file mode 100644 index a24d4a40c..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/Network.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Network.h" -#include "MonitoredTurtleClient.h" -#include "FakeComponents.h" - -bool Network::initRandom(uint32_t nb_nodes,float connexion_probability) -{ - _nodes.clear() ; - _neighbors.clear() ; - - std::vector ids ; - - _neighbors.resize(nb_nodes) ; - ids.resize(nb_nodes) ; - - for(uint32_t i=0;i friends ; - for(std::set::const_iterator it(_neighbors[i].begin());it!=_neighbors[i].end();++it) - friends.push_back( ids[*it] ) ; - - _nodes.push_back( new PeerNode( ids[i], friends )); - } - return true ; -} - -void Network::tick() -{ - //std::cerr<< "network loop: tick()" << std::endl; - - // Tick all nodes. - - for(uint32_t i=0;iPeerId() << " to " << Network::node(i).id() << std::endl; - - PeerNode& node = node_by_id(item->PeerId()) ; - item->PeerId(Network::node(i).id()) ; - - node.incoming(item) ; - } - } - } - catch(...) - { - } -} - -PeerNode& Network::node_by_id(const RsPeerId& id) -{ - std::map::const_iterator it = _node_ids.find(id) ; - - if(it == _node_ids.end()) - throw std::runtime_error("Error. Bad id passed to node_by_id ("+id.toStdString()+")") ; - - return node(it->second) ; -} - diff --git a/libretroshare/src/tests/network_simulator/nscore/Network.h b/libretroshare/src/tests/network_simulator/nscore/Network.h deleted file mode 100644 index adecc5665..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/Network.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "PeerNode.h" - -template class Graph -{ - public: - typedef uint32_t NodeId ; - - void symmetric_connect(uint32_t n1,uint32_t n2) ; - const std::set& neighbors(const NodeId& n) const { return _neighbors[n] ; } - - // number of nodes. - // - uint32_t n_nodes() const { return _nodes.size() ;} - const NODE_TYPE& node(int i) const { return *_nodes[i] ; } - NODE_TYPE& node(int i) { return *_nodes[i] ; } - - protected: - - std::vector _nodes ; - std::vector > _neighbors ; -}; - -class Network: public Graph -{ - public: - // inits the graph as random. Returns true if connected, false otherwise. - // - bool initRandom(uint32_t n_nodes, float connexion_probability) ; - - // ticks all services of all nodes. - // - void tick() ; - - PeerNode& node_by_id(const RsPeerId& node_id) ; - - private: - std::map _node_ids ; -}; - diff --git a/libretroshare/src/tests/network_simulator/nscore/PeerNode.cpp b/libretroshare/src/tests/network_simulator/nscore/PeerNode.cpp deleted file mode 100644 index 569a1347c..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/PeerNode.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "PeerNode.h" -#include "FakeComponents.h" -#include "MonitoredTurtleClient.h" -#include "MonitoredGRouterClient.h" - -PeerNode::PeerNode(const RsPeerId& id,const std::list& friends) - : _id(id) -{ - // add a service server. - - p3LinkMgr *link_mgr = new FakeLinkMgr(id, friends) ; - p3PeerMgr *peer_mgr = new FakePeerMgr(id, friends) ; - - _publisher = new FakePublisher ; - p3ServiceControl *ctrl = new FakeServiceControl(link_mgr) ; - - _service_server = new p3ServiceServer(_publisher,ctrl); - - RsServicePermissions perms; - perms.mDefaultAllowed = true ; - perms.mServiceId = RS_SERVICE_TYPE_TURTLE ; - - ctrl->updateServicePermissions(RS_SERVICE_TYPE_TURTLE,perms) ; - - perms.mDefaultAllowed = true ; - perms.mServiceId = RS_SERVICE_TYPE_GROUTER ; - - ctrl->updateServicePermissions(RS_SERVICE_TYPE_GROUTER,perms) ; - - // Turtle business - - _service_server->addService(_turtle = new p3turtle(ctrl,link_mgr),true) ; - _turtle_client = new MonitoredTurtleClient ; - _turtle_client->connectToTurtleRouter(_turtle) ; - - // global router business. - // - - _service_server->addService(_grouter = new p3GRouter(ctrl,link_mgr),true) ; - _grouter_client = new MonitoredGRouterClient ; - _grouter_client->connectToGlobalRouter(_grouter) ; -} - -PeerNode::~PeerNode() -{ - delete _service_server ; -} - -void PeerNode::tick() -{ - //std::cerr << " ticking peer node " << _id << std::endl; - _service_server->tick() ; -} - -void PeerNode::incoming(RsRawItem *item) -{ - _service_server->recvItem(item) ; -} -RsRawItem *PeerNode::outgoing() -{ - return dynamic_cast(_publisher)->outgoing() ; -} - -void PeerNode::provideFileHash(const RsFileHash& hash) -{ - _provided_hashes.insert(hash) ; - _turtle_client->provideFileHash(hash) ; -} - -void PeerNode::manageFileHash(const RsFileHash& hash) -{ - _managed_hashes.insert(hash) ; - _turtle->monitorTunnels(hash,_turtle_client, false) ; -} -void PeerNode::sendToGRKey(const GRouterKeyId& key_id) -{ - _grouter_client->sendMessage(key_id) ; -} -void PeerNode::provideGRKey(const GRouterKeyId& key_id) -{ - _grouter_client->provideKey(key_id) ; - _provided_keys.insert(key_id); -} -void PeerNode::getTrafficInfo(NodeTrafficInfo& info) -{ - std::vector > hashes_info ; - std::vector > tunnels_info ; - std::vector search_reqs_info ; - std::vector tunnel_reqs_info ; - - _turtle->getInfo(hashes_info,tunnels_info,search_reqs_info,tunnel_reqs_info) ; - - for(uint32_t i=0;i -#include -#include - -class MonitoredTurtleClient ; -class MonitoredGRouterClient ; -class RsTurtle ; -class p3turtle ; -class p3GRouter ; -class pqiPublisher ; -class RsRawItem ; -class p3ServiceServer ; - -class PeerNode -{ - public: - struct NodeTrafficInfo - { - std::map local_src ; // peer id., tunnel id - std::map local_dst ; - }; - - PeerNode(const RsPeerId& id,const std::list& friends) ; - ~PeerNode() ; - - RsRawItem *outgoing() ; - void incoming(RsRawItem *) ; - - const RsPeerId& id() const { return _id ;} - - void tick() ; - - // Turtle-related methods - // - const RsTurtle *turtle_service() const { return _turtle ; } - p3GRouter *global_router_service() const { return _grouter ; } - - void manageFileHash(const RsFileHash& hash) ; - void provideFileHash(const RsFileHash& hash) ; - - const std::set& providedHashes() const { return _provided_hashes; } - const std::set& managedHashes() const { return _managed_hashes; } - - void getTrafficInfo(NodeTrafficInfo& trinfo) ; // - - // GRouter-related methods - // - void provideGRKey(const GRouterKeyId& key_id) ; - void sendToGRKey(const GRouterKeyId& key_id) ; - - const std::set& providedGRKeys() const { return _provided_keys; } - - private: - p3ServiceServer *_service_server ; - pqiPublisher *_publisher ; - RsPeerId _id ; - - // turtle stuff - // - p3turtle *_turtle ; - MonitoredTurtleClient *_turtle_client ; - - // grouter stuff - // - p3GRouter *_grouter ; - MonitoredGRouterClient *_grouter_client ; - - std::set _provided_hashes ; - std::set _managed_hashes ; - std::set _provided_keys ; -}; - diff --git a/libretroshare/src/tests/network_simulator/nscore/nscore.pro b/libretroshare/src/tests/network_simulator/nscore/nscore.pro deleted file mode 100644 index 5a3989a15..000000000 --- a/libretroshare/src/tests/network_simulator/nscore/nscore.pro +++ /dev/null @@ -1,20 +0,0 @@ -TEMPLATE = lib -CONFIG *= staticlib - -INCLUDEPATH *= ../../.. .. - -TARGET = nscore - -SOURCES = Network.cpp \ - PeerNode.cpp \ - MonitoredRsPeers.cpp \ - MonitoredTurtleClient.cpp \ - MonitoredGRouterClient.cpp - -HEADERS = Network.h \ - PeerNode.h \ - MonitoredRsPeers.h \ - MonitoredTurtleClient.h \ - MonitoredGRouterClient.h - -DESTDIR = ../lib diff --git a/libretroshare/src/tests/perform_all_auto_tests.sh b/libretroshare/src/tests/perform_all_auto_tests.sh deleted file mode 100755 index 648bf63c5..000000000 --- a/libretroshare/src/tests/perform_all_auto_tests.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# This is the main script for performing all tests automatically. -# - in order to add new directories, just list them in the $subdirs variable below - -echo "****************************************" -echo "*** RetroShare automatic test suite. ***" -echo "****************************************" -echo "Performing all tests on subdirs." -echo "(Some tests take a few minutes. Be patient) " -echo -echo - -subdirs="util serialiser dbase upnp general pgp tcponudp" - -for dir in $subdirs; do - echo Tests for directory: $dir - cd $dir - ./perform_auto_tests.sh - cd .. -done - diff --git a/libretroshare/src/tests/pgp/test_certificate.cc b/libretroshare/src/tests/pgp/test_certificate.cc deleted file mode 100644 index 6659ea86a..000000000 --- a/libretroshare/src/tests/pgp/test_certificate.cc +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include - -#include -#include -//#include -#include -#include -#include - -INITTEST() ; - -static std::string pgp_pwd_cb(void * /*hook*/, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad) -{ -#define GPG_DEBUG2 -#ifdef GPG_DEBUG2 - fprintf(stderr, "pgp_pwd_callback() called.\n"); -#endif - std::string password; - - std::cerr << "SHould not be called!" << std::endl; - return password ; -} - -int main(int argc,char *argv[]) -{ - try - { - argstream as(argc,argv) ; - std::string keyfile ; - bool clean_cert = false ; - - as >> parameter('i',"input",keyfile,"input certificate file (old or new formats)",true) - >> option('c',"clean",clean_cert,"clean cert before parsing") - >> help() ; - - as.defaultErrorHandling() ; - - FILE *f = fopen(keyfile.c_str(),"rb") ; - - CHECK(f != NULL) ; - - std::string res ; - char c ; - - while( (c = fgetc(f)) != EOF) - res += c ; - - fclose(f) ; - - std::cerr << "Read this string from the file:" << std::endl; - std::cerr << "==========================================" << std::endl; - std::cerr << res << std::endl; - std::cerr << "==========================================" << std::endl; - - if(clean_cert) - { - std::string res2 ; - int err ; - - //res2 = cleanUpCertificate(res,err) ; - - //if(res2 == "") - // std::cerr << "Error while cleaning: " << err << std::endl; - //else - // res = res2 ; - - std::cerr << "Certificate after cleaning:" << std::endl; - std::cerr << "==========================================" << std::endl; - std::cerr << res << std::endl; - std::cerr << "==========================================" << std::endl; - } - std::cerr << "Parsing..." << std::endl; - - RsCertificate cert(res) ; - - std::cerr << "Output from certificate:" << std::endl; - - std::cerr << cert.toStdString_oldFormat() << std::endl ; - - std::cerr << "Output from certificate (new format):" << std::endl; - std::cerr << cert.toStdString() << std::endl ; - - std::string key_id ; - std::string name ; - std::list signers ; - - PGPHandler::setPassphraseCallback(pgp_pwd_cb) ; - PGPHandler handler("toto1","toto2","toto3","toto4") ; - handler.getGPGDetailsFromBinaryBlock(cert.pgp_key(),cert.pgp_key_size(),key_id,name,signers) ; - - CHECK(key_id == "660FB771727CE286") ; - CHECK(name == "Cyril-test (generated by Retroshare) ") ; - - std::cerr << "Details loaded from certificate:" << std::endl; - std::cerr << "PGP id\t: " << key_id << std::endl; - std::cerr << "Key name\t: " << name << std::endl; - std::cerr << "Signers\t:" << std::endl; - - bool found = false ; - - for(std::list::const_iterator it(signers.begin());it!=signers.end();++it) - { - std::cerr << " " << *it << std::endl; - - if(*it == key_id) - found = true ; - } - CHECK(found) ; - - // try to load the certificate. - - std::cerr << "Checking that the certificate is imported correctly" << std::endl; - - std::string error_string ; - PGPIdType found_id ; - - bool result = handler.LoadCertificateFromString(res,found_id,error_string) ; - - if(!result) - std::cerr << "Certificate error: " << error_string << std::endl; - else - std::cerr << "Certificate loaded correctly. Id = " << found_id.toStdString() << std::endl; - - CHECK(result) ; - - FINALREPORT("Test certificate parsing") ; - - return TESTRESULT(); - } - catch(std::exception& e) - { - std::cerr << "Exception never handled: " << e.what() << std::endl; - return 1 ; - } -} - diff --git a/libretroshare/src/tests/pgp/test_certificate.newformat.rsc b/libretroshare/src/tests/pgp/test_certificate.newformat.rsc deleted file mode 100644 index 9bcd0273b..000000000 --- a/libretroshare/src/tests/pgp/test_certificate.newformat.rsc +++ /dev/null @@ -1,15 +0,0 @@ -Af8AAAKHmQENBEyoe/MBCAC9rKm/ehp9Iv1XrOiKIyj1X5nJzQ660+OhmQf4lbJv -krcnvdrdcmlfZQfupWMXHo7A3+27lOpfTvA1xpO8Gze0bRbLsbpx2dARjLUzXJAI -FNCYzH5xlIixxOwgX3tinKfoP3WvZv+nYBac/HeAPUW8BVqx6Y6V/gM3c71XNf9u -hPgArN0jvLOeqAJY+lACJZYlAIw6Jt2FzarC+orWndkvrsgrWmdxkorfZKBfdNwd -f1YYrpUmGaf51x4DkrMWpfHxS8b6cgOmSN3LeAC8LCm5oEXPfNgaRehN9LKrSmcp -cPS2jvDipgGBx+nL7gytCREMJkJoxppXQpVt1whaFDJVABEBAAG0OkN5cmlsLXRl -c3QgKGdlbmVyYXRlZCBieSBSZXRyb3NoYXJlKSA8Y3lyaWwuc29sZXJAaW1hZy5m -cj6JATgEEwECACIFAkyoe/MCGy8GCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJ -EGYPt3FyfOKG+h0H/A+vvryYmGcGFl82D4M0mAPAlbjZFkGCB8qJJSFuor55GJ3V -8pBb4UK7jnLhQhqsdXxAawT9R5RzTDITWHkS4KVaFalOYLxQ8x4s31FWXUiprAvJ -AIVw9gnBC7kDLro2irCljZB5ro8fsg0SJ0ZFc4cZMPZxnMKm5ovC6WggbblyaHrR -rV8jhHFIR+RG9/nnw0PgvGOmV9f4Q0a/7E18AxdBXYMZSp7p/mwbQdkqgm7p73bg -7E2Zz/Fhg1/PguwjlDal+HyUEPDvcPG41NAKwpMeL78qVJTQcBzzo1Irqj5f5UFJ -p4/H7QDlEsz/ZGxXXq3PdAP5BICwiOD44G9dIUECBlLktZUcsQMGwKgAZxyxBAAG -BmxhcHRvcAUQXVLApuPC+s1X/RPnFumDgQ== diff --git a/libretroshare/src/tests/pgp/test_certificate.oldformat.rsc b/libretroshare/src/tests/pgp/test_certificate.oldformat.rsc deleted file mode 100644 index 501e4abd7..000000000 --- a/libretroshare/src/tests/pgp/test_certificate.oldformat.rsc +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: OpenPGP:SDK v0.9 - -mQENBEyoe/MBCAC9rKm/ehp9Iv1XrOiKIyj1X5nJzQ660+OhmQf4lbJvkrcnvdrd -cmlfZQfupWMXHo7A3+27lOpfTvA1xpO8Gze0bRbLsbpx2dARjLUzXJAIFNCYzH5x -lIixxOwgX3tinKfoP3WvZv+nYBac/HeAPUW8BVqx6Y6V/gM3c71XNf9uhPgArN0j -vLOeqAJY+lACJZYlAIw6Jt2FzarC+orWndkvrsgrWmdxkorfZKBfdNwdf1YYrpUm -Gaf51x4DkrMWpfHxS8b6cgOmSN3LeAC8LCm5oEXPfNgaRehN9LKrSmcpcPS2jvDi -pgGBx+nL7gytCREMJkJoxppXQpVt1whaFDJVABEBAAG0OkN5cmlsLXRlc3QgKGdl -bmVyYXRlZCBieSBSZXRyb3NoYXJlKSA8Y3lyaWwuc29sZXJAaW1hZy5mcj6JATgE -EwECACIFAkyoe/MCGy8GCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEGYPt3Fy -fOKG+h0H/A+vvryYmGcGFl82D4M0mAPAlbjZFkGCB8qJJSFuor55GJ3V8pBb4UK7 -jnLhQhqsdXxAawT9R5RzTDITWHkS4KVaFalOYLxQ8x4s31FWXUiprAvJAIVw9gnB -C7kDLro2irCljZB5ro8fsg0SJ0ZFc4cZMPZxnMKm5ovC6WggbblyaHrRrV8jhHFI -R+RG9/nnw0PgvGOmV9f4Q0a/7E18AxdBXYMZSp7p/mwbQdkqgm7p73bg7E2Zz/Fh -g1/PguwjlDal+HyUEPDvcPG41NAKwpMeL78qVJTQcBzzo1Irqj5f5UFJp4/H7QDl -Esz/ZGxXXq3PdAP5BICwiOD44G9dIUE= -=BWkb ------END PGP PUBLIC KEY BLOCK----- ---SSLID--5d52c0a6e3c2facd57fd13e716e98381;--LOCATION--laptop; ---LOCAL--192.168.0.103:7345;--EXT--82.228.181.149:7345; diff --git a/libretroshare/src/tests/pgp/test_certificate.sh b/libretroshare/src/tests/pgp/test_certificate.sh deleted file mode 100755 index e81d89f98..000000000 --- a/libretroshare/src/tests/pgp/test_certificate.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -./test_certificate -i test_certificate.oldformat.rsc && ./test_certificate -i test_certificate.newformat.rsc diff --git a/libretroshare/src/tests/pgp/test_identity_import.c b/libretroshare/src/tests/pgp/test_identity_import.c deleted file mode 100644 index 7fcd14066..000000000 --- a/libretroshare/src/tests/pgp/test_identity_import.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include - -#include -#include -//#include -#include -#include -#include - -INITTEST() ; - -static std::string pgp_pwd_cb(void * /*hook*/, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad) -{ -#define GPG_DEBUG2 -#ifdef GPG_DEBUG2 - fprintf(stderr, "pgp_pwd_callback() called.\n"); -#endif - std::string password; - - std::cerr << "SHould not be called!" << std::endl; - return password ; -} - -int main(int argc,char *argv[]) -{ - try - { - argstream as(argc,argv) ; - std::string idfile ; - bool clean_cert = false ; - - as >> parameter('i',"input",idfile,"input retroshare identity file, ascii format",true) - >> help() ; - - as.defaultErrorHandling() ; - - PGPHandler handler("toto1","toto2","toto3","toto4") ; - - PGPIdType imported_key_id ; - std::string import_error_string ; - - bool res = handler.importGPGKeyPair(idfile,imported_key_id,import_error_string) ; - - handler.syncDatabase() ; - - if(!res) - std::cerr << "Identity Import error: " << import_error_string << std::endl; - - CHECK(res) ; - } - catch(std::exception& e) - { - std::cerr << "Exception never handled: " << e.what() << std::endl; - return 1 ; - } -} - diff --git a/libretroshare/src/tests/pgp/test_key_parsing.cc b/libretroshare/src/tests/pgp/test_key_parsing.cc deleted file mode 100644 index 8e4a8ff64..000000000 --- a/libretroshare/src/tests/pgp/test_key_parsing.cc +++ /dev/null @@ -1,64 +0,0 @@ -// COMPILE_LINE: g++ -o test_key_parsing test_key_parsing.cc -g -I../../../openpgpsdk/include -I../ -L../lib ../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2 -// -#include -#include - -extern "C" -{ - #include - #include - #include -} - -#include -#include - -INITTEST() ; - -int main(int argc,char *argv[]) -{ - try - { - // test PGPHandler - // - // 0 - init - - bool armoured = false ; - std::string keyfile ; - - argstream as(argc,argv) ; - - as >> parameter('i',"input-key",keyfile,"input key file.",true) - >> option('a',"armoured",armoured,"input is armoured") - >> help() ; - - as.defaultErrorHandling() ; - - ops_keyring_t *kr = (ops_keyring_t*)malloc(sizeof(ops_keyring_t)) ; - kr->nkeys = 0 ; - kr->nkeys_allocated = 0 ; - kr->keys = 0 ; - - CHECK(ops_false != ops_keyring_read_from_file(kr,armoured, keyfile.c_str())) ; - - for(int i=0;inkeys;++i) - { - ops_print_public_keydata(&kr->keys[i]) ; - ops_print_public_keydata_verbose(&kr->keys[i]) ; - ops_print_public_key(&kr->keys[i].key.pkey) ; - } - - ops_list_packets(const_cast(keyfile.c_str()),armoured,kr,NULL) ; - - FINALREPORT("Test key parsing") ; - - return TESTRESULT() ; - } - catch(std::exception& e) - { - std::cerr << "Caught exception: " << e.what() << std::endl; - return 1 ; - } -} - - diff --git a/libretroshare/src/tests/pgp/test_key_parsing.sh b/libretroshare/src/tests/pgp/test_key_parsing.sh deleted file mode 100644 index dd9ee9139..000000000 --- a/libretroshare/src/tests/pgp/test_key_parsing.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -./test_key_parsing -i test_pubring.gpg diff --git a/libretroshare/src/tests/pgp/test_pgp_handler.cc b/libretroshare/src/tests/pgp/test_pgp_handler.cc deleted file mode 100644 index b78adc5f5..000000000 --- a/libretroshare/src/tests/pgp/test_pgp_handler.cc +++ /dev/null @@ -1,397 +0,0 @@ -// COMPILE_LINE: g++ -o test_pgp_handler test_pgp_handler.cc -I../../../openpgpsdk/include -I../ -L../lib -lretroshare ../../../libbitdht/src/lib/libbitdht.a ../../../openpgpsdk/lib/libops.a -lgnome-keyring -lupnp -lssl -lcrypto -lbz2 -// -#include -#include -#include -#include -#include -#include -#include - -INITTEST() ; - -static std::string static_passphrase = "" ; -static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad) -{ - if(!static_passphrase.empty()) - return static_passphrase ; - - if(prev_was_bad) - std::cerr << "Bad passphrase." << std::endl; - - std::string wt = std::string("Please enter passphrase for key id ") + uid_info + " :"; - - return std::string(getpass(wt.c_str())) ; -} - -static std::string stringFromBytes(unsigned char *bytes,size_t len) -{ - static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ; - - std::string res ; - - for(uint32_t j = 0; j < len; j++) - { - res += out[ (bytes[j]>>4) ] ; - res += out[ bytes[j] & 0xf ] ; - } - - return res ; -} - -static std::string askForKeyId(PGPHandler& pgph) -{ - // 0 - print keys and key types - - std::list lst ; - pgph.availableGPGCertificatesWithPrivateKeys(lst) ; - - std::cerr << lst.size() << " available key pairs: " << std::endl; - int i=0 ; - - for(std::list::const_iterator it(lst.begin());it!=lst.end();++it,++i) - { - std::cerr << "(" << i << ") ID=" << (*it).toStdString() << ", type = " ; - - const PGPCertificateInfo *cert = pgph.getCertificateInfo(*it) ; - - switch(cert->_type) - { - case PGPCertificateInfo::PGP_CERTIFICATE_TYPE_DSA: std::cerr << "DSA" << std::endl; - break ; - case PGPCertificateInfo::PGP_CERTIFICATE_TYPE_RSA: std::cerr << "RSA" << std::endl; - break ; - default: std::cerr << "Unknown" << std::endl; - } - } - - if(i == 0) - throw std::runtime_error("No key pair available in supplied keyring.") ; - - // 1 - ask for which key to use. - - int num = -1 ; - - while(true) - { - std::cerr << "Please enter selected key number (0 - " << i-1 << ") : " ; - std::cerr.flush() ; - - char buf[10]; - fgets(buf,10,stdin) ; - - if(sscanf(buf,"%d",&num) == 1 && num >= 0 && num < i) - break ; - } - - // 2 - return the id string. - - std::list::const_iterator it(lst.begin()) ; - for(int i=0;i> option('1',"pgptype",test_pgpid_type,"Test pgp ID type") - >> option('2',"keyring-read",test_keyring_read,"Test keyring read") - >> option('3',"file-encryption",test_file_encryption,"Test file encryption. Needs -f, -i, -p and -s") - >> option('4',"keygen",test_gen_key,"Test key generation.") - >> option('5',"signature",test_signature,"Test signature.") - >> option('6',"output",test_output,"Test output.") - >> option('7',"memory-encryption",test_memory_encryption,"Test output.") - >> option('F',"fulltest",full_test,"Test everything.") - >> parameter('f',"file",file_to_encrypt,"File to encrypt. Used with -3",false) - >> parameter('p',"pubring",pubring_file,"Public keyring file.",false) - >> parameter('s',"secring",secring_file,"Secret keyring file.",false) - >> parameter('i',"keyid",key_id_string,"Key id to use. If not supplied, will be asked.",false) - >> help() ; - - as.defaultErrorHandling() ; - - if(!full_test) - if(test_pgpid_type + test_keyring_read + test_file_encryption + test_gen_key + test_signature + test_output + test_memory_encryption != 1) - { - std::cerr << "Options 1 to 6 are mutually exclusive." << std::endl; - return 1; - } - if(full_test || test_pgpid_type) - { - // test pgp ids. - // - std::string st("3e5b22140ef56abb") ; - PGPIdType id = PGPIdType(std::string(st)) ; - - //std::cerr << "Id is : " << std::hex << id.toUInt64() << std::endl; - std::cerr << "Id st : " << id.toStdString() << std::endl; - - CHECK(id.toStdString(false) == st) ; - } - - // test PGPHandler - // - // 0 - init - - std::string pubring = pubring_file.empty()?"pubring.gpg":pubring_file ; - std::string secring = secring_file.empty()?"secring.gpg":secring_file ; - - static const std::string trustdb = "trustdb.gpg" ; - static const std::string lockfile = "lock" ; - - PGPHandler::setPassphraseCallback(&passphrase_callback) ; - PGPHandler pgph(pubring,secring,trustdb,lockfile) ; - - std::string email_str("test@gmail.com") ; - std::string name_str("test") ; - std::string passw_str("test00") ; - PGPIdType cert_id ; ; - - if(full_test || test_gen_key) - { - std::cerr << "Now generating a new PGP certificate: " << std::endl; - std::cerr << " email: " << email_str << std::endl; - std::cerr << " passw: " << passw_str << std::endl; - std::cerr << " name : " << name_str << std::endl; - - PGPIdType newid ; - std::string errString ; - static_passphrase = passw_str ; - - bool res = pgph.GeneratePGPCertificate(name_str, email_str, passw_str, newid, errString) ; - - cert_id = newid ; - - CHECK(res) ; - - if(!res) - std::cerr << "Generation of certificate returned error: " << errString << std::endl; - else - std::cerr << "Certificate generation success. New id = " << newid.toStdString() << std::endl; - } - - if(full_test) - key_id_string = cert_id.toStdString(true) ; - - if(full_test || test_keyring_read) - { - pgph.printKeys() ; - - std::cerr << std::endl ; - std::cerr << std::endl ; - - std::cerr << "Looking for keys with complete secret/public key pair: " << std::endl; - - std::list lst ; - pgph.availableGPGCertificatesWithPrivateKeys(lst) ; - - bool found = false ; - - for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) - { - std::cerr << "Found id : " << (*it).toStdString() << std::endl; - if(cert_id == *it) - found = true ; - } - CHECK(found) ; - } - - if(full_test || test_output) - { - PGPIdType id2( (key_id_string.empty())?askForKeyId(pgph):key_id_string) ; - - std::cerr << "Now extracting key " << id2.toStdString() << " from keyring:" << std::endl ; - std::string cert = pgph.SaveCertificateToString(id2,false) ; - - std::cerr << "Now, trying to re-read this cert from the string:" << std::endl; - - PGPIdType id3 ; - std::string error_string ; - pgph.LoadCertificateFromString(cert,id3,error_string) ; - - std::cerr << "Loaded cert id: " << id3.toStdString() << ", Error string=\"" << error_string << "\"" << std::endl; - - CHECK(id3 == id2) ; - - std::cerr << cert << std::endl; - } - - if(test_passphrase_callback) - { - std::cerr << "Testing password callback: " << std::endl; - std::string newid = "XXXXXXXXXXXXXXXX" ; - std::string pass = passphrase_callback(NULL,newid.c_str(),"Please enter password: ",false) ; - std::cerr << "Password = \"" << pass << "\"" << std::endl; - } - - if(full_test || test_signature) - { - if(key_id_string.empty()) - key_id_string = askForKeyId(pgph) ; - - PGPIdType key_id(key_id_string) ; - std::cerr << "Testing signature with keypair " << key_id_string << std::endl; - - static const size_t BUFF_LEN = 25 ; - unsigned char *test_bin = new unsigned char[BUFF_LEN] ; - for(size_t i=0;i -#include -#include -#include -#include - -INITTEST() ; - -static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad) -{ - return std::string(getpass(what)) ; -} - -static std::string stringFromBytes(unsigned char *bytes,size_t len) -{ - static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ; - - std::string res ; - - for(int j = 0; j < len; j++) - { - res += out[ (bytes[j]>>4) ] ; - res += out[ bytes[j] & 0xf ] ; - } - - return res ; -} - -int main(int argc,char *argv[]) -{ - // test pgp ids. - // - PGPIdType id("3e5b22140ef56abb") ; - - std::cerr << "Id st : " << id.toStdString() << std::endl; - - // test PGPHandler - // - // 0 - init - - static const std::string pubring = "pubring.gpg" ; - static const std::string secring = "secring.gpg" ; - static const std::string trustdb = "trustdb.gpg" ; - static const std::string lockfil = "lock" ; - - PGPHandler::setPassphraseCallback(&passphrase_callback) ; - PGPHandler pgph(pubring,secring,trustdb,lockfil) ; - - pgph.printKeys() ; - - FINALREPORT("Signature parsing") ; - - return TESTRESULT() ; -} - diff --git a/libretroshare/src/tests/pgp/test_pubring.gpg b/libretroshare/src/tests/pgp/test_pubring.gpg deleted file mode 100644 index 338dfe86b..000000000 Binary files a/libretroshare/src/tests/pgp/test_pubring.gpg and /dev/null differ diff --git a/libretroshare/src/tests/pqi/TestNotes.txt b/libretroshare/src/tests/pqi/TestNotes.txt deleted file mode 100644 index 6d6089e9b..000000000 --- a/libretroshare/src/tests/pqi/TestNotes.txt +++ /dev/null @@ -1,94 +0,0 @@ - -There are a huge amount of testing to be done here. - -Components and Tests. -============================================================ ------------------------------------------------------------- -Basic Components ------------------------------------------------------------- -pqinetwork.cc: net_test, net_test1, netiface_test -pqi_base.cc: no need. -pqimonitor.cc: no need. -p3notify.cc: no need. -pqisecurity.cc: no need. -pqiservice.cc: no need. -cleanupxpgp.cc to test. - ------------------------------------------------------------- -Serialisation Components ------------------------------------------------------------- -pqiarchive.cc: pqiarchive_test -pqibin.cc: pqiarchive_test -pqistreamer.cc -pqistore.cc - ------------------------------------------------------------- -SSL Network Components ------------------------------------------------------------- -pqiloopback.cc -pqissltunnel.cc -pqissludp.cc -pqissl.cc -pqiperson.cc -pqipersongrp.cc -pqisslpersongrp.cc -pqissllistener.cc - ------------------------------------------------------------- -Authentication Components ------------------------------------------------------------- -sslcert.cc -xpgpcert.cc -authgpg.cc -authssl.cc - ------------------------------------------------------------- -Manager Components ------------------------------------------------------------- -p3connmgr.cc -pqihandler.cc -p3dhtmgr.cc: dht_test -p3cfgmgr.cc - -============================================================ -Test Specifics -============================================================ ------------------------------------------------------------- -net_test ------------------------------------------------------------- -Tested Code: pqinetwork.cc, rsnet.cc -Description: -(1) Tests ntohll / htonll -(3) Tests socket binding. - ------------------------------------------------------------- -net_test1 ------------------------------------------------------------- -Tested Code: pqinetwork.cc, rsnet.cc -Description: -(1) isExternalNet() -(2) isPrivateNet() -(3) isLoopbackNet() -(5) isValidNet() - ------------------------------------------------------------- -pqiarchive_test ------------------------------------------------------------- -Tested Code: pqiarchive.cc pqibin.cc -Description : - Stores increasingly large packets into an archive file then retrieves them. - - NOTE: This tests packets up to size of 1Mb. This causes the test to FAIL - due to getRsPktMaxSize() returning 262142.... What to do? This needs to be fixed! - - see comments at serialiser/rsserial.cc line 448 - ------------------------------------------------------------- -dht_test ------------------------------------------------------------- -Tested Code : p3dhtmgr.cc -Description : - -This is a manual test of the DHT manager. needs to be -converted to an automatic test. - diff --git a/libretroshare/src/tests/pqi/conn_harness.cc b/libretroshare/src/tests/pqi/conn_harness.cc deleted file mode 100644 index 72da573d4..000000000 --- a/libretroshare/src/tests/pqi/conn_harness.cc +++ /dev/null @@ -1,284 +0,0 @@ -/* - * libretroshare/src/test/pqi testconnect.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pqiperson acts as the wrapper for all connection methods to a single peer. - * - * This test creates, a pqiperson and simulates connections, disconnections. - * packets passing through. - * - */ - - -#include "conn_harness.h" -#include "pqi/pqibin.h" -#include -#include - -/******************************************************* - * - * Test structure - *****************/ - - -/* static test variables */ -uint32_t testCounter = 0; -pqiconnect *testConnectPointer[NUM_CONN_MAX]; -PQInterface *testConnectParent[NUM_CONN_MAX]; -uint32_t testConnectState[NUM_CONN_MAX]; -std::list testConnectTimes[NUM_CONN_MAX]; -std::list testConnectAddrs[NUM_CONN_MAX]; - -std::list testResetState[NUM_CONN_MAX]; -std::list testResetTimes[NUM_CONN_MAX]; - -uint32_t testConnectAction[NUM_CONN_MAX] = { 0 }; -rstime_t testConnectPeriod[NUM_CONN_MAX] = { 0 }; - -uint32_t defTestConnectAction = TST_ACTION_FAILED; - - -uint32_t findWhichConnect(pqiconnect *conn) -{ - int i; - for(i = 0; i < NUM_CONN_MAX; i++) - { - if (testConnectPointer[i] == conn) - { - return i; - } - } - // error. - std::cerr << "Connect Missing" << std::endl; - exit(1); - return 0; -} - -void addTestConnect(pqiconnect *pqi, PQInterface *parent) -{ - testConnectPointer[testCounter] = pqi; - testConnectParent[testCounter] = parent; - testConnectState[testCounter] = 0; - testCounter++; - if (testCounter > NUM_CONN_MAX) - { - std::cerr << "Too Many Connects" << std::endl; - exit(1); - } -} - -void resetTestConnects() -{ - testCounter = 0; - int i; - for(i = 0; i < NUM_CONN_MAX; i++) - { - testConnectAddrs[i].clear(); - testConnectTimes[i].clear(); - testResetState[i].clear(); - testResetTimes[i].clear(); - } -} - -/* setup callback actions */ -void setDefaultTestConnectAction(uint32_t action) -{ - defTestConnectAction = action; -} - -void forceConnect(uint32_t idx) -{ - /* flag as con */ -} - - -testConnect::testConnect(RsSerialiser *rss, NetBinInterface *ni_in) - :pqiconnect(rss, ni_in) -{ - -} - -testConnect::~testConnect() -{ - return; -} - - /* dummyConnect */ -int testConnect::connect(struct sockaddr_in raddr) -{ - int cidx = findWhichConnect(this); - rstime_t now = time(NULL); - - testConnectState[cidx] |= TST_STATE_CONNECT; - testConnectTimes[cidx].push_back(now); - testConnectAddrs[cidx].push_back(raddr); - testConnectAction[cidx] = defTestConnectAction; - - std::cerr << "testConnect[" << cidx << "].connect() called"; - std::cerr << std::endl; - return 0; -} - -int testConnect::listen() -{ - int cidx = findWhichConnect(this); - testConnectState[cidx] |= TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].listen() called"; - std::cerr << std::endl; - return 1; -} - -int testConnect::stoplistening() -{ - int cidx = findWhichConnect(this); - testConnectState[cidx] &= ~TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].stoplistening() called"; - std::cerr << std::endl; - return 1; -} - -int testConnect::reset() -{ - int cidx = findWhichConnect(this); - rstime_t now = time(NULL); - - // reset everything except listening. - testResetState[cidx].push_back(testConnectState[cidx]); - testResetTimes[cidx].push_back(now); - testConnectState[cidx] &= TST_STATE_LISTEN; - - std::cerr << "testConnect[" << cidx << "].reset() called"; - std::cerr << std::endl; - return 1; -} - -// leave this as is virtual int disconnect() { return ni -> reset(); } - -bool testConnect::connect_parameter(uint32_t type, uint32_t value) -{ - int cidx = findWhichConnect(this); - //testConnectState[cidx] |= TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].connect_parameter() called"; - std::cerr << std::endl; - - /* sum up PERIOD and DELAY */ - if (type == NET_PARAM_CONNECT_DELAY) - { - std::cerr << "PARAMETER: DELAY: " << value; - std::cerr << std::endl; - - //testConnectPeriod[cidx] = value; - } - else if (type == NET_PARAM_CONNECT_PERIOD) - { - std::cerr << "PARAMETER: PERIOD: " << value; - std::cerr << std::endl; - - //testConnectPeriod[cidx] += value; - } - else if (type == NET_PARAM_CONNECT_TIMEOUT) - { - std::cerr << "PARAMETER: TIMEOUT: " << value; - std::cerr << std::endl; - - testConnectPeriod[cidx] = value; - //testConnectPeriod[cidx] += value; - } - std::cerr << "total testConnectPeriod: " << testConnectPeriod[cidx]; - std::cerr << std::endl; - - return true; -} - -int testConnect::getConnectAddress(struct sockaddr_in &raddr) -{ - int cidx = findWhichConnect(this); - if (testConnectAddrs[cidx].size() > 0) - { - raddr = testConnectAddrs[cidx].back(); - return 1; - } - std::cerr << "testConnect[" << cidx << "].getConnectAddress() called"; - std::cerr << std::endl; - return 0; -} - - -int testConnect::tick() -{ - int cidx = findWhichConnect(this); - - std::cerr << "testConnect[" << cidx << "].tick()"; - std::cerr << std::endl; - - if (testConnectState[cidx] & TST_STATE_CONNECT) - { - rstime_t now = time(NULL); - rstime_t cTime = testConnectTimes[cidx].back(); - if (now - cTime > testConnectPeriod[cidx]) - { - - std::cerr << "testConnect[" << cidx << "].tick() reached ConnectPeriod"; - std::cerr << " age: " << now - cTime << " period: " << testConnectPeriod[cidx]; - std::cerr << std::endl; - - PQInterface *connParent = testConnectParent[cidx]; - - testConnectState[cidx] &= ~TST_STATE_CONNECT; - /* do callback now */ - if (testConnectAction[cidx] == TST_ACTION_SUCCESS) - { - std::cerr << "testConnect[" << cidx << "].tick() CONNECTED callback"; - std::cerr << std::endl; - - testConnectState[cidx] &= ~TST_STATE_CONNECTED; - /* do callback */ - connParent -> notifyEvent(this->ni, NET_CONNECT_SUCCESS); - - } - else if (testConnectAction[cidx] == TST_ACTION_FAILED) - { - std::cerr << "testConnect[" << cidx << "].tick() FAILED callback"; - std::cerr << std::endl; - - /* do callback */ - connParent -> notifyEvent(this->ni, NET_CONNECT_FAILED); - - } - else - { - std::cerr << "testConnect[" << cidx << "].tick() no callback (BAD)"; - std::cerr << std::endl; - } - - } - } - return 0; -} - - - - - diff --git a/libretroshare/src/tests/pqi/conn_harness.h b/libretroshare/src/tests/pqi/conn_harness.h deleted file mode 100644 index 697faca99..000000000 --- a/libretroshare/src/tests/pqi/conn_harness.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef TEST_PQICONNECT_H -#define TEST_PQICONNECT_H - -/* - * libretroshare/src/test/pqi testconnect.h - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "pqi/pqiperson.h" -//#include "pqi/pqibin.h" -#include "util/rsnet.h" - -/******************************************************* - * - * Test structure - *****************/ - - -#define NUM_CONN_MAX 50 - -#define TST_STATE_CONNECT 0x0001 -#define TST_STATE_LISTEN 0x0002 -#define TST_STATE_CONNECTED 0x0004 - -#define TST_ACTION_NONE 0x0000 -#define TST_ACTION_FAILED 0x0001 -#define TST_ACTION_SUCCESS 0x0002 - -/* static test variables */ -extern uint32_t testCounter; -extern pqiconnect *testConnectPointer[NUM_CONN_MAX]; -extern uint32_t testConnectState[NUM_CONN_MAX]; -extern std::list testConnectTimes[NUM_CONN_MAX]; -extern std::list testConnectAddrs[NUM_CONN_MAX]; - -extern std::list testResetState[NUM_CONN_MAX]; -extern std::list testResetTimes[NUM_CONN_MAX]; - -uint32_t findWhichConnect(pqiconnect *conn); -void addTestConnect(pqiconnect *pqi, PQInterface *parent); -void resetTestConnects(); - -void setDefaultTestConnectAction(uint32_t action); - -class testConnect: public pqiconnect -{ - public: - - testConnect(RsSerialiser *rss, NetBinInterface *ni_in); - virtual ~testConnect(); - - /* dummyConnect */ - virtual int tick(); - virtual int connect(struct sockaddr_in raddr); - virtual int listen(); - virtual int stoplistening(); - virtual int reset(); - virtual bool connect_parameter(uint32_t type, uint32_t value); - virtual int getConnectAddress(struct sockaddr_in &raddr); -}; // end of testConnect. - - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg); - - -#endif - diff --git a/libretroshare/src/tests/pqi/conn_test.cc b/libretroshare/src/tests/pqi/conn_test.cc deleted file mode 100644 index 57ffceafe..000000000 --- a/libretroshare/src/tests/pqi/conn_test.cc +++ /dev/null @@ -1,363 +0,0 @@ - - -#include "pqi/p3connmgr.h" - - -/***** Test for the new DHT system *****/ - - -#include "util/rsnet.h" -#include "util/rsthreads.h" -#include "util/rsprint.h" -#include "pqi/p3dhtmgr.h" -#include "pqi/p3connmgr.h" -#error secpolicy was removed, also remove it from test to fix compile -#include "pqi/pqisecurity.h" -#include "pqi/pqipersongrp.h" - -#include -#include - -#include "tcponudp/udpsorter.h" - -/***** Test Framework *****/ - -const int NumOfPeers = 10; -std::string peerIds[NumOfPeers] = - {"PEER01", - "PEER02", /* Always online, no notify */ - "PEER03", /* notify/online at 20sec */ - "PEER04", /* Always online, notify at 30 sec */ - "PEER05", - "PEER06", /* notify/online at 50sec */ - "PEER07", - "PEER08", - "PEER09", /* notify/online at 80sec */ - "PEER10"}; - -#define STUN_PORT 7777 - -std::string ownId = "OWNID-AAAA"; -rstime_t ownPublishTs; - -RsMutex frmMtx; -std::list searchIds; -std::list searchModes; - -std::map onlineMap; -std::map notifyMap; - -void initTestData() -{ - ownPublishTs = 0; - /* setup Peers that are online always */ - bool online; - uint32_t ts; - for(int i = 0; i < NumOfPeers; i++) - { - online = false; - if ((i == 1) || (i == 3)) - { - online = true; - } - onlineMap[peerIds[i]] = online; - - if ((i == 2) || (i == 3) || - (i == 5) || (i == 8)) - { - ts = i * 10; - notifyMap[ts] = peerIds[i]; - } - } -} - -void respondPublish() -{ - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - if (!ownPublishTs) - { - std::cerr << "Own ID first published!" << std::endl; - ownPublishTs = time(NULL); - } - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ -} - -void respondSearch(p3DhtMgr *mgr, std::string id, uint32_t mode) -{ - std::cerr << "Checking for Search Results" << std::endl; - rstime_t now = time(NULL); - bool doNotify = false; - bool doOnline = false; - std::string notifyId; - - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - if ((mode == DHT_MODE_NOTIFY) && (ownPublishTs)) - { - /* */ - std::map::iterator it; - uint32_t delta_t = now - ownPublishTs; - it = notifyMap.begin(); - if (it != notifyMap.end()) - { - if (it->first <= delta_t) - { - notifyId = it->second; - onlineMap[notifyId] = true; - notifyMap.erase(it); - doNotify = true; - } - } - } - else if (mode == DHT_MODE_SEARCH) - { - - /* translate */ - std::map::iterator mit; - for(mit = onlineMap.begin(); (mit != onlineMap.end()) && - (RsUtil::HashId(mit->first, false) != id); mit++); - - if (mit != onlineMap.end()) - { - doOnline = mit->second; - } - } - - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ - - uint32_t type = 0; - - struct sockaddr_in laddr; - inet_aton("10.0.0.129", &(laddr.sin_addr)); - laddr.sin_port = htons(7812); - laddr.sin_family = AF_INET; - - struct sockaddr_in raddr; - inet_aton("127.0.0.1", &(raddr.sin_addr)); - raddr.sin_port = htons(STUN_PORT); - raddr.sin_family = AF_INET; - - if (doNotify) - { - std::cerr << "Responding to Notify: id:" << notifyId << std::endl; - mgr->dhtResultNotify(RsUtil::HashId(notifyId, true)); - } - - if (doOnline) - { - std::cerr << "Responding to Search" << std::endl; - mgr->dhtResultSearch(id, laddr, raddr, type, ""); - } - -} - - -/***** Test Framework *****/ - -class DhtMgrTester: public p3DhtMgr -{ - - /* Implementation */ - public: - - DhtMgrTester(std::string id, pqiConnectCb *cb) - :p3DhtMgr(id, cb) - { - return; - } - - - - - - /* Blocking calls (only from thread) */ -virtual bool dhtPublish(std::string id, - struct sockaddr_in &laddr, struct sockaddr_in &raddr, - uint32_t type, std::string sign) -{ - std::cerr << "DhtMgrTester::dhtPublish() id: " << RsUtil::BinToHex(id); - std::cerr << " laddr: " << rs_inet_ntoa(laddr.sin_addr) << " lport: " << ntohs(laddr.sin_port); - std::cerr << " raddr: " << rs_inet_ntoa(raddr.sin_addr) << " rport: " << ntohs(raddr.sin_port); - std::cerr << " type: " << type << " sign: " << sign; - std::cerr << std::endl; - - respondPublish(); - - return true; -} - -virtual bool dhtNotify(std::string peerid, std::string ownid, std::string sign) -{ - std::cerr << "DhtMgrTester::dhtNotify() id: " << RsUtil::BinToHex(peerid) << ", ownId: " << RsUtil::BinToHex(ownId); - std::cerr << " sign: " << sign; - std::cerr << std::endl; - - return true; -} - -virtual bool dhtSearch(std::string id, uint32_t mode) -{ - std::cerr << "DhtMgrTester::dhtSearch(id: " << RsUtil::BinToHex(id) << ", mode: " << mode << ")" << std::endl; - - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - searchIds.push_back(id); - searchModes.push_back(mode); - frmMtx.unlock(); /* LOCK TEST FRAMEWORK MUTEX */ - - return true; -} - -}; - - -/* OVERLOAD THE ConnMgr - to insert peers */ -class p3TestConnMgr: public p3ConnectMgr -{ - public: - p3TestConnMgr(int mode) - :p3ConnectMgr(new p3DummyAuthMgr()), mTestMode(mode) { return; } - - protected: - /* must be virtual for testing */ -virtual void loadConfiguration() -{ - - /* setup own address */ - ownState.id = ownId; - ownState.name = "SELF NAME"; - ownState.localaddr.sin_family = AF_INET; - inet_aton("127.0.0.1", &(ownState.localaddr.sin_addr)); - ownState.localaddr.sin_port = htons(7812); - ownState.netMode = RS_NET_MODE_UDP; - ownState.visState = RS_VIS_STATE_STD; - - /* others not important */ - //ownState.state = 0; - //ownState.actions = 0; - - - if (mTestMode == 1) /* Add to Stun List */ - { - for(int i = 0; i < NumOfPeers; i++) - { - mStunList.push_back(peerIds[i]); - } - } - else if (mTestMode == 2) /* add to peers */ - { - /* add in as peers */ - //addPeer(); - for(int i = 0; i < NumOfPeers; i++) - { - if (i < 5) - { - mStunList.push_back(RsUtil::HashId(peerIds[i])); - } - else - { - addFriend(peerIds[i]); - } - } - } -} - - protected: - - uint32_t mTestMode; -}; - - -int main() -{ - rstime_t startTime = time(NULL); - /* setup system */ - initTestData(); - - /* setup a Stunner to respond to ConnMgr */ - - struct sockaddr_in saddr; - saddr.sin_family = AF_INET; - inet_aton("127.0.0.1", &(saddr.sin_addr)); - saddr.sin_port = htons(STUN_PORT); - UdpSorter stunner(saddr); /* starts a receiving thread */ - - p3TestConnMgr connMgr(2); - DhtMgrTester dhtTester(ownId, &connMgr); - - /* now add in some peers */ - connMgr.setDhtMgr(&dhtTester); - connMgr.setUpnpMgr(NULL); - - /************ ADD pqipersongrp as pqimonitor *****************/ -#error secpolicy was removed, should remove it from tests too - SecurityPolicy *pol = secpolicy_create(); - unsigned long flags = 0; - pqipersongrp *pqipg = new pqipersongrpDummy(pol, flags); - - connMgr.addMonitor(pqipg); - - /************ ADD pqipersongrp as pqimonitor *****************/ - - - /* startup dht */ - std::cerr << "Starting up DhtTester()" << std::endl; - dhtTester.start(); - - /* wait for a little before switching on */ -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(1); -#else - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - std::cerr << "Switching on DhtTester()" << std::endl; - dhtTester.setDhtOn(true); - - /* wait loop */ - while(1) - { -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(1); -#else - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - connMgr.tick(); - pqipg->tick(); - - /* handle async search */ - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - - std::string id; - uint32_t mode; - bool doRespond = false; - if (searchIds.size() > 0) - { - id = searchIds.front(); - mode = searchModes.front(); - doRespond = true; - searchIds.pop_front(); - searchModes.pop_front(); - } - - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ - - if (doRespond) - { - respondSearch(&dhtTester, id, mode); - } - } -}; - - - - - - - - - - diff --git a/libretroshare/src/tests/pqi/dht_test.cc b/libretroshare/src/tests/pqi/dht_test.cc deleted file mode 100644 index ccfd117b5..000000000 --- a/libretroshare/src/tests/pqi/dht_test.cc +++ /dev/null @@ -1,310 +0,0 @@ - - -/***** Test for the new DHT system *****/ - - -#include "pqi/pqinetwork.h" - -#include "util/rsnet.h" -#include "util/rsthreads.h" -#include "util/rsprint.h" - -#include "pqi/p3dhtmgr.h" - -#include -#include - - -/***** Test Framework *****/ - -const int NumOfPeers = 10; -std::string peerIds[NumOfPeers] = - {"PEER01", - "PEER02", /* Always online, no notify */ - "PEER03", /* notify/online at 20sec */ - "PEER04", /* Always online, notify at 30 sec */ - "PEER05", - "PEER06", /* notify/online at 50sec */ - "PEER07", - "PEER08", - "PEER09", /* notify/online at 80sec */ - "PEER10"}; - -std::string ownId = "AAAA"; -rstime_t ownPublishTs; - -RsMutex frmMtx; -std::list searchIds; -std::list searchModes; - -std::map onlineMap; -std::map notifyMap; - -void initTestData() -{ - ownPublishTs = 0; - /* setup Peers that are online always */ - bool online; - uint32_t ts; - for(int i = 0; i < NumOfPeers; i++) - { - online = false; - if ((i == 1) || (i == 3)) - { - online = true; - } - onlineMap[peerIds[i]] = online; - - if ((i == 2) || (i == 3) || - (i == 5) || (i == 8)) - { - ts = i * 10; - notifyMap[ts] = peerIds[i]; - } - } -} - -void respondPublish() -{ - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - if (!ownPublishTs) - { - std::cerr << "Own ID first published!" << std::endl; - ownPublishTs = time(NULL); - } - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ -} - -void respondSearch(p3DhtMgr *mgr, std::string id, uint32_t mode) -{ - std::cerr << "Checking for Search Results" << std::endl; - rstime_t now = time(NULL); - bool doNotify = false; - bool doOnline = false; - std::string notifyId; - - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - if ((mode == DHT_MODE_NOTIFY) && (ownPublishTs)) - { - /* */ - std::map::iterator it; - uint32_t delta_t = now - ownPublishTs; - it = notifyMap.begin(); - if (it != notifyMap.end()) - { - if (it->first <= delta_t) - { - notifyId = it->second; - onlineMap[notifyId] = true; - notifyMap.erase(it); - doNotify = true; - } - } - } - else if (mode == DHT_MODE_SEARCH) - { - /* translate */ - std::map::iterator mit; - for(mit = onlineMap.begin(); (mit != onlineMap.end()) && - (RsUtil::HashId(mit->first, false) != id); mit++); - - if (mit != onlineMap.end()) - { - doOnline = mit->second; - } - } - - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ - - uint32_t type = 0; - - struct sockaddr_in laddr; - inet_aton("10.0.0.129", &(laddr.sin_addr)); - laddr.sin_port = htons(7812); - laddr.sin_family = AF_INET; - - struct sockaddr_in raddr; - inet_aton("10.0.0.19", &(raddr.sin_addr)); - raddr.sin_port = htons(7812); - raddr.sin_family = AF_INET; - - if (doNotify) - { - std::cerr << "Responding to Notify" << std::endl; - mgr->dhtResultNotify(RsUtil::HashId(notifyId, true)); - } - - if (doOnline) - { - std::cerr << "Responding to Search" << std::endl; - mgr->dhtResultSearch(id, laddr, raddr, type, ""); - } -} - - - - - - -/***** Test Framework *****/ - - - - -class DhtMgrTester: public p3DhtMgr -{ - - /* Implementation */ - public: - - DhtMgrTester(std::string id, pqiConnectCb *cb) - :p3DhtMgr(id, cb) - { - return; - } - - - /* Blocking calls (only from thread) */ -virtual bool dhtPublish(std::string id, - struct sockaddr_in &laddr, struct sockaddr_in &raddr, - uint32_t type, std::string sign) -{ - std::cerr << "DhtMgrTester::dhtPublish() id: " << RsUtil::BinToHex(id); - std::cerr << " laddr: " << rs_inet_ntoa(laddr.sin_addr) << " lport: " << ntohs(laddr.sin_port); - std::cerr << " raddr: " << rs_inet_ntoa(raddr.sin_addr) << " rport: " << ntohs(raddr.sin_port); - std::cerr << " type: " << type << " sign: " << sign; - std::cerr << std::endl; - - respondPublish(); - - return true; -} - -virtual bool dhtNotify(std::string peerid, std::string ownid, std::string sign) -{ - std::cerr << "DhtMgrTester::dhtNotify() id: " << RsUtil::BinToHex(peerid) << ", ownId: " << RsUtil::BinToHex(ownId); - std::cerr << " sign: " << sign; - std::cerr << std::endl; - - return true; -} - -virtual bool dhtSearch(std::string id, uint32_t mode) -{ - std::cerr << "DhtMgrTester::dhtSearch(id: " << RsUtil::BinToHex(id) << ", mode: " << mode << ")" << std::endl; - - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - searchIds.push_back(id); - searchModes.push_back(mode); - frmMtx.unlock(); /* LOCK TEST FRAMEWORK MUTEX */ - - return true; -} - -}; - -int main() -{ - rstime_t startTime = time(NULL); - bool haveOwnAddress = false; - /* setup system */ - initTestData(); - - pqiConnectCbDummy cbTester; - DhtMgrTester dhtTester(ownId, &cbTester); - - /* now add in some peers */ - - /* startup dht */ - std::cerr << "Starting up DhtTester()" << std::endl; - dhtTester.start(); - - /* wait for a little before switching on */ -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(1); -#else - Sleep(1000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - std::cerr << "Switching on DhtTester()" << std::endl; - dhtTester.enable(true); - - std::cerr << "Adding a List of Peers" << std::endl; - for(int i = 0; i < NumOfPeers; i++) - { - dhtTester.findPeer(peerIds[i]); - } - - - /* wait loop */ - while(1) - { - std::cerr << "Main waiting..." << std::endl; -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - sleep(3); -#else - Sleep(3000); -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - - /* handle async search */ - frmMtx.lock(); /* LOCK TEST FRAMEWORK MUTEX */ - - std::string id; - uint32_t mode; - bool doRespond = false; - if (searchIds.size() > 0) - { - id = searchIds.front(); - mode = searchModes.front(); - doRespond = true; - searchIds.pop_front(); - searchModes.pop_front(); - } - - frmMtx.unlock(); /* UNLOCK TEST FRAMEWORK MUTEX */ - - if (doRespond) - { - respondSearch(&dhtTester, id, mode); - } - - if (!haveOwnAddress) - { - if (time(NULL) - startTime > 20) - { - std::cerr << "Setting Own Address!" << std::endl; - haveOwnAddress = true; - - uint32_t type = DHT_ADDR_UDP; - - struct sockaddr_in laddr; - inet_aton("10.0.0.111", &(laddr.sin_addr)); - laddr.sin_port = htons(7812); - laddr.sin_family = AF_INET; - - struct sockaddr_in raddr; - inet_aton("10.0.0.11", &(raddr.sin_addr)); - raddr.sin_port = htons(7812); - raddr.sin_family = AF_INET; - - dhtTester.setExternalInterface(laddr, raddr, type); - } - } - - } -}; - - - - - - - - - - diff --git a/libretroshare/src/tests/pqi/dnsresolver_test.cc b/libretroshare/src/tests/pqi/dnsresolver_test.cc deleted file mode 100644 index 2a20ecc90..000000000 --- a/libretroshare/src/tests/pqi/dnsresolver_test.cc +++ /dev/null @@ -1,83 +0,0 @@ - -/* - * "$Id:$" - * - * RetroShare C++ Interface. - * - * Copyright 2010-2011 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 "retroshare@lunamutt.com". - * - */ - - - -#include "util/dnsresolver.h" - -#include -#include -#include - -int main() -{ - std::list names; - - DNSResolver *r = new DNSResolver ; - - names.push_back("cortinaire.inrialpes.fr") ; - names.push_back("www.google.com") ; - names.push_back("www.ego.cn") ; - names.push_back("free.fr") ; - - for(int i=0;i<5;++i) - { - for(std::list::const_iterator it = names.begin(); it != names.end(); it++) - { - in_addr addr ; - bool res = r->getIPAddressFromString(*it,addr) ; - - if(res) - std::cerr << "Lookup of " << *it << ": " << (res?"done":"pending") << ": addr = " << (void*)addr.s_addr << std::endl; - else - std::cerr << "Lookup of " << *it << ": " << (res?"done":"pending") << std::endl; - } - - std::cerr << std::endl; - usleep(200000) ; - } - - r->reset() ; - - for(int i=0;i<5;++i) - { - for(std::list::const_iterator it = names.begin(); it != names.end(); it++) - { - in_addr addr ; - bool res = r->getIPAddressFromString(*it,addr) ; - - if(res) - std::cerr << "Lookup of " << *it << ": " << (res?"done":"pending") << ": addr = " << (void*)addr.s_addr << std::endl; - else - std::cerr << "Lookup of " << *it << ": " << (res?"done":"pending") << std::endl ; - } - std::cerr << std::endl; - usleep(200000) ; - } - - delete r ; -} - diff --git a/libretroshare/src/tests/pqi/extaddrfinder_test.cc b/libretroshare/src/tests/pqi/extaddrfinder_test.cc deleted file mode 100644 index 550011d09..000000000 --- a/libretroshare/src/tests/pqi/extaddrfinder_test.cc +++ /dev/null @@ -1,37 +0,0 @@ -#include "util/utest.h" - -#include -#include "pqi/pqinetwork.h" - -#include -#include - -INITTEST(); - -int main() -{ - std::cerr << "Testing the ext address finder service. This might take up to 10 secs..." << std::endl ; - - ExtAddrFinder fnd ; - in_addr addr ; - uint32_t tries = 0 ; - - while(! fnd.hasValidIP( &addr )) - { - sleep(1) ; - - if(++tries > 20) - { - std::cerr << "Failed !" << std::endl ; - CHECK(false) ; - } - } - - std::cerr << "Found the following IP: " << inet_ntoa(addr) << std::endl ; - - FINALREPORT("extaddrfinder_test"); - - return TESTRESULT() ; -} - - diff --git a/libretroshare/src/tests/pqi/gpgme_tst.c b/libretroshare/src/tests/pqi/gpgme_tst.c deleted file mode 100644 index ec88a8439..000000000 --- a/libretroshare/src/tests/pqi/gpgme_tst.c +++ /dev/null @@ -1,76 +0,0 @@ - -#include "pqi/authgpg.h" - -const std::string key_path("./tmp/privkey.pem"); -const std::string passwd("8764"); -const std::string gpg_passwd("aaaa"); -const std::string name("Test X509"); -const std::string email("test@email.com"); -const std::string org("Org"); -const std::string loc("Loc"); -const std::string state("State"); -const std::string country("GB"); - -int main() -{ - /* Init the auth manager */ - - GPGAuthMgr mgr; - - - /* Select which GPG Keys we use */ - - /* print all keys */ - mgr.printKeys(); - - std::list idList; - mgr.availablePGPCertificates(idList); - - if (idList.size() < 1) - { - fprintf(stderr, "No GPG Certificate to use!\n"); - exit(1); - } - std::string id = idList.front(); - fprintf(stderr, "Using GPG Certificate:%s \n", id.c_str()); - - std::string noname; - mgr.GPGInit(id); - mgr.LoadGPGPassword(gpg_passwd); - - /* Init SSL library */ - mgr.InitAuth(NULL, NULL, NULL); - - /* then try to generate and sign a X509 certificate */ - int nbits_in = 2048; - std::string errString; - - /* Generate a Certificate Request */ - X509_REQ *req = GenerateX509Req(key_path, passwd, name, email, org, - loc, state, country, nbits_in, errString); - - // setup output. - BIO *bio_out = NULL; - bio_out = BIO_new(BIO_s_file()); - BIO_set_fp(bio_out,stdout,BIO_NOCLOSE); - - /* Print it out */ - int nmflag = 0; - int reqflag = 0; - - X509_REQ_print_ex(bio_out, req, nmflag, reqflag); - - X509 *x509 = mgr.SignX509Req(req, 100, gpg_passwd); - - X509_print_ex(bio_out, x509, nmflag, reqflag); - - BIO_flush(bio_out); - BIO_free(bio_out); - - /* now try to validate it */ - mgr.AuthX509(x509); - - //sleep(10); -} - - diff --git a/libretroshare/src/tests/pqi/net_test.cc b/libretroshare/src/tests/pqi/net_test.cc deleted file mode 100644 index ff7744141..000000000 --- a/libretroshare/src/tests/pqi/net_test.cc +++ /dev/null @@ -1,127 +0,0 @@ -/* - * libretroshare/src/test/pqi net_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * NETWORKING Test to check Big/Little Endian behaviour - * as well as socket behaviour - * - */ - -#include "util/utest.h" - -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" -#include -#include - - -bool test_byte_manipulation(); -bool test_local_address_manipulation(); - - -INITTEST(); - -int main(int argc, char **argv) -{ - std::cerr << "libretroshare:pqi " << argv[0] << std::endl; - - test_byte_manipulation(); - - FINALREPORT("libretroshare Net Basics Tests"); - return TESTRESULT(); -} - - /* test 1: byte manipulation */ -bool test_byte_manipulation() -{ - uint64_t num1 = 0x0000000000000000ffULL; /* 255 */ - uint64_t num2 = 0x00000000000000ff00ULL; /* */ - - uint64_t n_num1 = htonll(num1); - uint64_t n_num2 = htonll(num2); - - uint64_t h_num1 = ntohll(n_num1); - uint64_t h_num2 = ntohll(n_num2); - - std::ostringstream out; - out << std::hex; - out << "num1: " << num1 << " netOrder: " << n_num1 << " hostOrder: " << h_num1 << std::endl; - out << "num2: " << num2 << " netOrder: " << n_num2 << " hostOrder: " << h_num2 << std::endl; - - std::cerr << out.str(); - - CHECK( num1 == h_num1 ); - CHECK( num2 == h_num2 ); - - REPORT("Test Byte Manipulation"); - - return true; -} - -const char * loopback_addrstr = "127.0.0.1"; -const char * localnet1_addrstr = "192.168.0.1"; -const char * localnet2_addrstr = "10.0.0.1"; -const char * localnet3_addrstr = "10.5.63.78"; -const char * localnet4_addrstr = "192.168.74.91"; - -bool test_bind_addr(struct sockaddr_in addr); - -bool test_bind_addr(struct sockaddr_in addr) -{ - - int err; - - std::cerr << "test_bind_addr()"; - std::cerr << std::endl; - - std::cerr << "\tAddress Family: " << (int) addr.sin_family; - std::cerr << std::endl; - std::cerr << "\tAddress: " << rs_inet_ntoa(addr.sin_addr); - std::cerr << std::endl; - std::cerr << "\tPort: " << ntohs(addr.sin_port); - std::cerr << std::endl; - - int sockfd = unix_socket(PF_INET, SOCK_STREAM, 0); - CHECK( 0 < sockfd ); - - if (0 != (err = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)))) - { - std::cerr << " Failed to Bind to Local Address!" << std::endl; - std::string out ; - showSocketError(out) ; - std::cerr << out << std::endl; - - FAILED("Couldn't Bind to socket"); - - return false; - } - - std::cerr << " Successfully Bound Socket to Address" << std::endl; - unix_close(sockfd); - - return true; -} - - diff --git a/libretroshare/src/tests/pqi/net_test1.cc b/libretroshare/src/tests/pqi/net_test1.cc deleted file mode 100644 index fe0f7e353..000000000 --- a/libretroshare/src/tests/pqi/net_test1.cc +++ /dev/null @@ -1,170 +0,0 @@ -/* - * libretroshare/src/pqi net_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * NETWORKING Test to check Big/Little Endian behaviour - * as well as socket behaviour - * - */ - -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" -#include -#include -#include "util/utest.h" - -const char * loopback_addrstr = "127.0.0.1"; - -const char * localnet1_addrstr = "10.0.0.1"; -const char * localnet2_addrstr = "169.254.0.1"; -const char * localnet3_addrstr = "172.16.0.1"; -const char * localnet4_addrstr = "192.168.1.1"; - -const char * localnet5_addrstr = "10.4.28.34"; -const char * localnet6_addrstr = "169.254.1.81"; -const char * localnet7_addrstr = "172.20.9.201"; -const char * localnet8_addrstr = "192.168.1.254"; - -const char * external_addrstr = "74.125.19.99"; /* google */ -const char * invalid_addrstr = "AAA.BBB.256.256"; - -int test_isExternalNet(); -int test_isPrivateNet(); -int test_isLoopbackNet(); -int test_isValidNet(); - -INITTEST(); - -int main(int argc, char **argv) -{ - std::cerr << "net_test1" << std::endl; - - test_isExternalNet(); - test_isPrivateNet(); - test_isLoopbackNet(); - test_isValidNet(); - - FINALREPORT("net_test1"); - - return TESTRESULT(); -} - -int test_isExternalNet() -{ - struct in_addr loopback_addr; - struct in_addr localnet1_addr; - struct in_addr localnet2_addr; - struct in_addr localnet3_addr; - struct in_addr localnet4_addr; - struct in_addr external_addr; - struct in_addr invalid_addr; - struct in_addr invalid_addr2; - - inet_aton(loopback_addrstr, &loopback_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(external_addrstr, &external_addr); - invalid_addr.s_addr = 0; - invalid_addr2.s_addr = -1; - - CHECK(isExternalNet(&loopback_addr)==false); - CHECK(isExternalNet(&localnet1_addr)==false); - CHECK(isExternalNet(&localnet2_addr)==false); - CHECK(isExternalNet(&localnet3_addr)==false); - CHECK(isExternalNet(&localnet4_addr)==false); - CHECK(isExternalNet(&external_addr)==true); - CHECK(isExternalNet(&invalid_addr)==false); - CHECK(isExternalNet(&invalid_addr2)==false); - - REPORT("isExternalNet()"); - - return 1; -} - -int test_isPrivateNet() -{ - struct in_addr loopback_addr; - struct in_addr localnet1_addr; - struct in_addr localnet2_addr; - struct in_addr localnet3_addr; - struct in_addr localnet4_addr; - struct in_addr external_addr; - - inet_aton(loopback_addrstr, &loopback_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(external_addrstr, &external_addr); - - CHECK(isPrivateNet(&loopback_addr)==false); //loopback not considered a "private network" - CHECK(isPrivateNet(&localnet1_addr)==true); - CHECK(isPrivateNet(&localnet2_addr)==true); - CHECK(isPrivateNet(&localnet3_addr)==true); - CHECK(isPrivateNet(&localnet4_addr)==true); - CHECK(isPrivateNet(&external_addr)==false); - - REPORT("isPrivateNet()"); - - return 1; -} - -int test_isLoopbackNet() -{ - struct in_addr loopback_addr; - struct in_addr localnet1_addr; - struct in_addr external_addr; - - inet_aton(loopback_addrstr, &loopback_addr); - inet_aton(localnet1_addrstr, &localnet1_addr); - inet_aton(external_addrstr, &external_addr); - - CHECK(isLoopbackNet(&loopback_addr)==true); - CHECK(isLoopbackNet(&localnet1_addr)==false); - CHECK(isLoopbackNet(&external_addr)==false); - - REPORT("isLoopbackNet()"); - - return 1; -} - -int test_isValidNet() -{ - struct in_addr localnet1_addr; - struct in_addr invalid_addr; - - inet_aton(localnet1_addrstr, &localnet1_addr); - CHECK(isValidNet(&localnet1_addr)==true); - - CHECK(inet_aton(invalid_addrstr, &invalid_addr)==0); - std::cerr << rs_inet_ntoa(invalid_addr) << std::endl; - //CHECK(isValidNet(&invalid_addr)==false); - - REPORT("isValidNet()"); - - return 1; -} diff --git a/libretroshare/src/tests/pqi/p3connmgr_connect_test.cc b/libretroshare/src/tests/pqi/p3connmgr_connect_test.cc deleted file mode 100644 index 991fb99f3..000000000 --- a/libretroshare/src/tests/pqi/p3connmgr_connect_test.cc +++ /dev/null @@ -1,195 +0,0 @@ -/* - * libretroshare/src/test/pqi p3connmgr_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * p3connmgr test module. - * - * create a p3connmgr and run the following tests. - * 1) UDP test - * 2) UPNP test - * 3) ExtAddr test. - * 4) full reset in between. - * - */ - - -#include -#include -#include - - -#include "ppg_harness.h" -#include "conn_harness.h" - -#include "pqi/p3connmgr.h" -#include "pqi/authssltest.h" -#include "pqi/authgpgtest.h" - -#include "pqi/p3dhtmgr.h" -#include "upnp/upnphandler.h" - -#include "util/rsnet.h" -#include -#include -#include "util/utest.h" - -INITTEST(); - -/* generic startup test */ -#define MAX_TIME_SHORT_TEST 10 -#define MAX_TIME_BASIC_TEST 60 - -int run_connect_test(rstime_t timeout); - -/******************************************************* - * - * Test structure - *****************/ - -#define FLAG_UPNP 1 -#define FLAG_UDP 2 -#define FLAG_DHT 4 -#define FLAG_EXT 8 - -p3ConnectMgr *mConnMgr; -pqiNetAssistFirewall *mUpnpMgr = NULL; -p3DhtMgr *mDhtMgr = NULL; - -void createP3ConnMgr(std::string id, uint32_t testFlags) -{ - /* now add test children */ - { - std::cerr << "createP3ConnMgr()"; - std::cerr << std::endl; - } - - mConnMgr = new p3ConnectMgr(); - - mDhtMgr = NULL; //new p3DhtMgr(); - - /* setup status */ - //mConnMgr->setStatus(UPNP); -} - - -/* ACTUAL TEST */ -int main(int argc, char **argv) -{ - /* test p3connmgr net stuff */ - std::cerr << "p3connmgr_net_connect_test" << std::endl; - - // setup test authssl. - setAuthGPG(new AuthGPGtest()); - setAuthSSL(new AuthSSLtest()); - - createP3ConnMgr("abcd", 0); - pqiNetStatus status; - - setupPqiPersonGrpTH(); - - /* install ppg as a monitor */ - - mConnMgr->addMonitor(mPqiPersonGrpTH); - - - std::string peer1_gpgid = "PEERID0001_GPG__"; - std::string peer1_sslid = "PEERID0001_SSL__"; - - /* first test, add a single peer (no Addresses) */ - mConnMgr->addFriend(peer1_sslid, peer1_gpgid); - - run_connect_test(MAX_TIME_SHORT_TEST); - - mConnMgr->getNetStatus(status); - - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - - // Check that there have been... 1 reset / 0 connects / 1 listen - // per connect. - - REPORT("p3connmgr_connect_test() SINGLE PEER - NO Addresses"); - /* second test, add addresses for peer */ - - rstime_t now = time(NULL); - - pqiIpAddrSet peer1_tst2_addrs; - pqiIpAddress paddr; - inet_aton("192.168.1.1", &(paddr.mAddr.sin_addr)); - paddr.mAddr.sin_port = htons(6411); - paddr.mSeenTime = now - 10; - peer1_tst2_addrs.mLocal.updateIpAddressList(paddr); - - inet_aton("192.168.1.2", &(paddr.mAddr.sin_addr)); - paddr.mAddr.sin_port = htons(6422); - paddr.mSeenTime = now - 20; - peer1_tst2_addrs.mLocal.updateIpAddressList(paddr); - - inet_aton("23.56.25.1", &(paddr.mAddr.sin_addr)); - paddr.mAddr.sin_port = htons(6511); - paddr.mSeenTime = now - 30; - peer1_tst2_addrs.mExt.updateIpAddressList(paddr); - - inet_aton("23.56.25.2", &(paddr.mAddr.sin_addr)); - paddr.mAddr.sin_port = htons(6522); - paddr.mSeenTime = now - 40; - peer1_tst2_addrs.mExt.updateIpAddressList(paddr); - - mConnMgr->updateAddressList(peer1_sslid, peer1_tst2_addrs); - mConnMgr->retryConnect(peer1_sslid); - - run_connect_test(MAX_TIME_BASIC_TEST); - - // Check that there have been: - // 0 Listens / 0 resets. - // 0 connect attempts on UDP - // 4 connect attempts on TCP - // 0 connect attempts on TUNNEL - REPORT("p3connmgr_connect_test() SINGLE PEER - 4 Addresses"); - - /* third test, add an second peer with addresses */ - - /* fourth test, setup default action as connect */ - setDefaultTestConnectAction(TST_ACTION_SUCCESS); -} - -/* Generic restart test */ -int run_connect_test(rstime_t timeout) -{ - /* tick */ - rstime_t start = time(NULL); - bool extAddr = false; - - while ((start > time(NULL) - timeout) && (!extAddr)) - { - mConnMgr->tick(); - tickPqiPersonGrpTH(); - - sleep(1); - } - return 1; -} - - diff --git a/libretroshare/src/tests/pqi/p3connmgr_reset_test.cc b/libretroshare/src/tests/pqi/p3connmgr_reset_test.cc deleted file mode 100644 index d5485101a..000000000 --- a/libretroshare/src/tests/pqi/p3connmgr_reset_test.cc +++ /dev/null @@ -1,320 +0,0 @@ -/* - * libretroshare/src/test/pqi p3connmgr_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * p3connmgr test module. - * - * create a p3connmgr and run the following tests. - * 1) UDP test - * 2) UPNP test - * 3) ExtAddr test. - * 4) full reset in between. - * - */ - - -#include -#include -#include - - - - -//#include "pqi/p3connmgr.h" -#include "pqi/authssltest.h" -#include "pqi/authgpgtest.h" - -#include "pqi/p3dhtmgr.h" -#include "upnp/upnphandler_linux.h" - -#include "util/rsnet.h" -#include -#include -#include "util/utest.h" - -INITTEST(); - -/* generic startup test */ -#define MAX_TIME_BASIC_TEST 40 -#define MAX_TIME_UPNP_TEST 700 /* seems to take a while */ - -#define RESTART_EXPECT_NO_EXT_ADDR 1 -#define RESTART_EXPECT_EXTFINDER_ADDR 2 -#define RESTART_EXPECT_UPNP_ADDR 3 -#define RESTART_EXPECT_DHT_ADDR 4 - -int test_p3connmgr_restart_test(uint32_t expectState, rstime_t timeout); - - -#define RESET_VIA_LOCAL_ADDR 1 -#define RESET_VIA_REMOTE_ADDR 2 - - -int force_reset(uint32_t method); - - -/******************************************************* - * - * Test structure - *****************/ - -#define FLAG_UPNP 1 -#define FLAG_UDP 2 -#define FLAG_DHT 4 -#define FLAG_EXT 8 - -p3ConnectMgr *mConnMgr; -pqiNetAssistFirewall *mUpnpMgr = NULL; -p3DhtMgr *mDhtMgr = NULL; - -void createP3ConnMgr(std::string id, uint32_t testFlags) -{ - /* now add test children */ - { - std::cerr << "createP3ConnMgr()"; - std::cerr << std::endl; - } - - mConnMgr = new p3ConnectMgr(); - - mDhtMgr = NULL; //new p3DhtMgr(); - - /* setup status */ - //mConnMgr->setStatus(UPNP); -} - -void add_upnp() -{ - pqiNetAssistFirewall *mUpnpMgr = new upnphandler(); - mDhtMgr = NULL; //new p3DhtMgr(); - - //mConnMgr->addNetAssistConnect(1, mDhtMgr); - mConnMgr->addNetAssistFirewall(1, mUpnpMgr); -} - -void disableUpnp() -{ - //mConnMgr-> -} - - -void enableUpnp() -{ - - - -} - -void disableExtFinder() -{ - //mConnMgr-> - mConnMgr->setIPServersEnabled(false); -} - - -void enableExtFinder() -{ - mConnMgr->setIPServersEnabled(true); -} - - -/* ACTUAL TEST */ -int main(int argc, char **argv) -{ - /* test p3connmgr net stuff */ - std::cerr << "p3connmgr_net_restart_test" << std::endl; - - // setup test authssl. - setAuthGPG(new AuthGPGtest()); - setAuthSSL(new AuthSSLtest()); - - createP3ConnMgr("abcd", 0); - pqiNetStatus status; - - - /* first test, no Upnp / ExtFinder -> expect no Ext Address */ - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UDP); - disableExtFinder(); - - mConnMgr->getNetStatus(status); - - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - test_p3connmgr_restart_test(RESTART_EXPECT_NO_EXT_ADDR, MAX_TIME_BASIC_TEST); - - REPORT("test_p3connmgr_restart_test()"); - - /* second test, add ExtFinder -> expect Ext Address */ - enableExtFinder(); - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UDP); - force_reset(RESET_VIA_LOCAL_ADDR); - - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - test_p3connmgr_restart_test(RESTART_EXPECT_EXTFINDER_ADDR, MAX_TIME_BASIC_TEST); - - /* third test. disable ExtFinder again -> expect No Ext Address */ - disableExtFinder(); - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UDP); - force_reset(RESET_VIA_LOCAL_ADDR); - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - test_p3connmgr_restart_test(RESTART_EXPECT_NO_EXT_ADDR, MAX_TIME_BASIC_TEST); - - - /* fourth test. enable Upnp -> expect Upnp Ext Address */ - add_upnp(); - enableUpnp(); - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UPNP); - force_reset(RESET_VIA_LOCAL_ADDR); - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - - - test_p3connmgr_restart_test(RESTART_EXPECT_UPNP_ADDR, MAX_TIME_UPNP_TEST); - /* fifth test. disable Upnp -> expect No Ext Address */ - disableUpnp(); - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UDP); - force_reset(RESET_VIA_LOCAL_ADDR); - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - - test_p3connmgr_restart_test(RESTART_EXPECT_NO_EXT_ADDR, MAX_TIME_BASIC_TEST); - /* sixth test. enable both Ext and Upnp -> expect UpnP Ext Address (prefered) */ - enableExtFinder(); - enableUpnp(); - mConnMgr->setNetworkMode(AuthSSL::getAuthSSL()->OwnId(), RS_NET_MODE_UPNP); - force_reset(RESET_VIA_LOCAL_ADDR); - CHECK(status.mLocalAddrOk == false); - CHECK(status.mExtAddrOk == false); - - test_p3connmgr_restart_test(RESTART_EXPECT_UPNP_ADDR, MAX_TIME_UPNP_TEST); - REPORT("test_p3connmgr_restart_test()"); - - FINALREPORT("p3connmgr_net_restart_test"); - - return TESTRESULT(); -} - -/****************************************************** - * - */ - -int force_reset(uint32_t method) -{ - /* force reset network */ - struct sockaddr_in tst_addr; - inet_aton("123.45.2.2", &(tst_addr.sin_addr)); - tst_addr.sin_port = ntohs(8461); - - mConnMgr->setLocalAddress(AuthSSL::getAuthSSL()->OwnId(), tst_addr); - - return 1; -} - -/* Generic restart test */ -int test_p3connmgr_restart_test(uint32_t expectState, rstime_t timeout) -{ - /* force reset network */ - struct sockaddr_in tst_addr; - inet_aton("123.45.2.2", &(tst_addr.sin_addr)); - tst_addr.sin_port = ntohs(8461); - - mConnMgr->setLocalAddress(AuthSSL::getAuthSSL()->OwnId(), tst_addr); - - /* tick */ - rstime_t start = time(NULL); - bool extAddr = false; - - while ((start > time(NULL) - timeout) && (!extAddr)) - { - mConnMgr->tick(); - - pqiNetStatus status; - mConnMgr->getNetStatus(status); - std::cerr << "test_p3connmgr_restart_test() Age: " << time(NULL) - start; - std::cerr << " netStatus:"; - std::cerr << std::endl; - status.print(std::cerr); - - if (status.mExtAddrOk) - { - std::cerr << "test_p3connmgr_restart_test() Got ExtAddr. Finished Restart."; - std::cerr << std::endl; - extAddr = true; - } - sleep(1); - } - - std::cerr << "test_p3connmgr_restart_test() Test Mode: " << expectState << " Complete"; - std::cerr << std::endl; - - pqiNetStatus status; - mConnMgr->getNetStatus(status); - status.print(std::cerr); - if (status.mExtAddrOk) - { - CHECK(isValidNet(&(status.mExtAddr.sin_addr))); - } - CHECK(isValidNet(&(status.mLocalAddr.sin_addr))); - - /* check expectState */ - switch(expectState) - { - default: - case RESTART_EXPECT_NO_EXT_ADDR: - CHECK(status.mLocalAddrOk == true); - CHECK(status.mExtAddrOk == false); - CHECK(status.mExtAddrStableOk == false); - CHECK(status.mUpnpOk == false); - CHECK(status.mDhtOk == false); - break; - - case RESTART_EXPECT_EXTFINDER_ADDR: - CHECK(status.mLocalAddrOk == true); - CHECK(status.mExtAddrOk == true); - CHECK(status.mExtAddrStableOk == false); - CHECK(status.mUpnpOk == false); - break; - - case RESTART_EXPECT_UPNP_ADDR: - CHECK(status.mLocalAddrOk == true); - CHECK(status.mExtAddrOk == true); - CHECK(status.mExtAddrStableOk == true); - CHECK(status.mUpnpOk == true); - break; - - case RESTART_EXPECT_DHT_ADDR: - CHECK(status.mLocalAddrOk == true); - CHECK(status.mExtAddrOk == false); - CHECK(status.mUpnpOk == false); - CHECK(status.mDhtOk == true); - break; - } - - return 1; -} - - diff --git a/libretroshare/src/tests/pqi/pkt_test.cc b/libretroshare/src/tests/pqi/pkt_test.cc deleted file mode 100644 index 49f6edd47..000000000 --- a/libretroshare/src/tests/pqi/pkt_test.cc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * libretroshare/src/tests/pqi pkt_tst.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2009-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pkt_tst. - * - * This is not testing serialisation.... so we only need 1 type of packet. - * using FileData packets - as these can have arbitary size. - */ - -#include "pkt_test.h" -#include - -uint8_t testdata[TEST_DATA_LEN]; - -void generate_test_data() -{ - srand(1); - - int i; - for(i = 0; i < TEST_DATA_LEN; i++) - { - testdata[i] = rand() % 256; - } -} - -bool check_data(void *data_in, int len) -{ - int i; - uint8_t *data = (uint8_t *) data_in; - - for(i = 0; i < len; i++) - { - if (data[i] != testdata[i]) - { - std::cerr << "check_data() Different Byte: " << i; - std::cerr << std::endl; - - return false; - } - } - return true; -} - -RsFileData *gen_packet(int datasize, std::string pid) -{ - /* generate some packets */ - RsFileData *data = new RsFileData(); - data->fd.file.filesize = TEST_PKT_SIZE; - data->fd.file.hash = TEST_PKT_HASH; - data->fd.file_offset = TEST_PKT_OFFSET; - data->fd.binData.setBinData(testdata, datasize); - data->PeerId(pid); - - return data; -} - -bool check_packet(RsFileData *pkt) -{ - if (pkt->fd.file.filesize != TEST_PKT_SIZE) - { - std::cerr << "check_packet() FileSize Different"; - std::cerr << std::endl; - - return false; - } - - if (pkt->fd.file.hash != TEST_PKT_HASH) - { - std::cerr << "check_packet() FileHash Different"; - std::cerr << std::endl; - - return false; - } - - if (pkt->fd.file_offset != TEST_PKT_OFFSET) - { - std::cerr << "check_packet() FileOffset Different"; - std::cerr << std::endl; - - return false; - } - - return check_data(pkt->fd.binData.bin_data, pkt->fd.binData.bin_len); -} - - diff --git a/libretroshare/src/tests/pqi/pkt_test.h b/libretroshare/src/tests/pqi/pkt_test.h deleted file mode 100644 index 072274574..000000000 --- a/libretroshare/src/tests/pqi/pkt_test.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef RS_TEST_PACKETS -#define RS_TEST_PACKETS -/* - * libretroshare/src/tests/pqi pkt_tst.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2009-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pkt_tst. - * - * This is not testing serialisation.... so we only need 1 type of packet. - * using FileData packets - as these can have arbitary size. - */ - -#include "serialiser/rsbaseitems.h" - -#define TEST_PKT_SIZE 1234567 -#define TEST_PKT_HASH "HASHTESTHASH" -#define TEST_PKT_OFFSET 1234 - -#define TEST_DATA_LEN (1024 * 1024) // MB - -void generate_test_data(); -bool check_data(void *data_in, int len); - -RsFileData *gen_packet(int datasize, std::string pid); -bool check_packet(RsFileData *pkt); - - -#endif diff --git a/libretroshare/src/tests/pqi/ppg_harness.cc b/libretroshare/src/tests/pqi/ppg_harness.cc deleted file mode 100644 index 58b89a971..000000000 --- a/libretroshare/src/tests/pqi/ppg_harness.cc +++ /dev/null @@ -1,141 +0,0 @@ -/* - * libretroshare/src/test/pqi pqiperson_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pqiperson acts as the wrapper for all connection methods to a single peer. - * - * This test creates, a pqiperson and simulates connections, disconnections. - * packets passing through. - * - */ - - -#include "conn_harness.h" -#include "ppg_harness.h" - -#include "pqi/pqiperson.h" -#include "pqi/pqibin.h" - -#include "util/rsnet.h" -#include -#include - -/******************************************************* - * - * Test structure - *****************/ - - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg); - -pqipersongrpTestHarness *mPqiPersonGrpTH = NULL; - -void setupPqiPersonGrpTH() -{ - mPqiPersonGrpTH = new pqipersongrpTestHarness(NULL, 0); -} - -void tickPqiPersonGrpTH() -{ - mPqiPersonGrpTH->tick(); -} - - -pqipersongrpTestHarness::pqipersongrpTestHarness(SecurityPolicy *pol, unsigned long flags) - :pqipersongrp(pol, flags) -{ - return; -} - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -pqilistener *pqipersongrpTestHarness::createListener(struct sockaddr_in laddr) -{ - return new pqilistener(); -} - -pqiperson *pqipersongrpTestHarness::createPerson(std::string id, pqilistener *listener) -{ - return createTestPerson(id, this); -} - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ - - - - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg) -{ - /* now add test children */ - { - std::cerr << "createTestPerson()"; - std::cerr << std::endl; - } - - pqiperson *pqip = new pqiperson(id, ppg); - - /* construct the serialiser .... - * Needs: - * * FileItem - * * FileData - * * ServiceGeneric - */ - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - rss->addSerialType(new RsCacheItemSerialiser()); - rss->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP); - pqiconnect *pqisc = new testConnect(rss, dummy1); - addTestConnect(pqisc, pqip); - pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc); - - RsSerialiser *rss2 = new RsSerialiser(); - rss2->addSerialType(new RsFileItemSerialiser()); - rss2->addSerialType(new RsCacheItemSerialiser()); - rss2->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy2 = new NetBinDummy(pqip, id, PQI_CONNECT_TUNNEL); - pqiconnect *pqicontun = new testConnect(rss2, dummy2); - addTestConnect(pqicontun, pqip); - pqip -> addChildInterface(PQI_CONNECT_TUNNEL, pqicontun); - - - RsSerialiser *rss3 = new RsSerialiser(); - rss3->addSerialType(new RsFileItemSerialiser()); - rss3->addSerialType(new RsCacheItemSerialiser()); - rss3->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy3 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP); - pqiconnect *pqiusc = new testConnect(rss3, dummy3); - addTestConnect(pqiusc, pqip); - pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc); - - return pqip; -} - - - - diff --git a/libretroshare/src/tests/pqi/ppg_harness.h b/libretroshare/src/tests/pqi/ppg_harness.h deleted file mode 100644 index 85e664548..000000000 --- a/libretroshare/src/tests/pqi/ppg_harness.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef PPG_HARNESS_TEST_H -#define PPG_HARNESS_TEST_H - -/* - * libretroshare/src/test/pqi ppg_harness.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * test harness for pqipersongrp / pqihandler. - */ - -#include "pqi/pqiperson.h" -#include "pqi/pqipersongrp.h" - -/******************************************************* - * - * Test structure - *****************/ - -void setupPqiPersonGrpTH(); -void tickPqiPersonGrpTH(); - -class pqipersongrpTestHarness; -extern pqipersongrpTestHarness *mPqiPersonGrpTH; - -class pqipersongrpTestHarness: public pqipersongrp -{ - public: - pqipersongrpTestHarness(SecurityPolicy *pol, unsigned long flags); - - protected: - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -virtual pqilistener *createListener(struct sockaddr_in laddr); -virtual pqiperson *createPerson(std::string id, pqilistener *listener); - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -}; - -#endif diff --git a/libretroshare/src/tests/pqi/pqiarchive_test.cc b/libretroshare/src/tests/pqi/pqiarchive_test.cc deleted file mode 100644 index abe88bab7..000000000 --- a/libretroshare/src/tests/pqi/pqiarchive_test.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* - * libretroshare/src/tests/pqi pqiarchive_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2009-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pqiarchive test. - * - * This is not testing serialisation.... so we only need 1 type of packet. - * using FileData packets - as these can have arbitary size. - */ - -#include "pqi/pqiarchive.h" -#include "pqi/pqibin.h" - -#include "serialiser/rsbaseitems.h" - -#include "util/rsnet.h" -#include -#include -#include "util/utest.h" - -#include "pkt_test.h" - -INITTEST(); - -int test_pqiarchive_generate(); - -int main(int argc, char **argv) -{ - std::cerr << "pqiarchive_test" << std::endl; - - generate_test_data(); - - test_pqiarchive_generate(); - - FINALREPORT("pqiarchive_test"); - - return TESTRESULT(); -} - -const char *archive_fname = "/tmp/rs_tst_archive.tmp"; - -int test_pqiarchive_generate() -{ - - std::string pid = "123456789012345678901234567890ZZ"; - /* create a pqiarchive */ - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - - int flags = BIN_FLAGS_WRITEABLE; - BinInterface *bio_in = new BinFileInterface(archive_fname, flags); - - int bio_flagsin = flags; - pqiarchive *pqia = new pqiarchive(rss, bio_in, bio_flagsin); - CHECK(pqia != NULL); - - int i; - for(i = 10; i < TEST_DATA_LEN; i = (int) (i * 1.1)) - { - RsFileData *pkt = gen_packet(i, pid); - pqia->SendItem(pkt); - pqia->tick(); - } - - /* close it up */ - delete pqia; - - /* setup read */ - flags = BIN_FLAGS_READABLE; - - rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - - bio_in = new BinFileInterface(archive_fname, flags); - bio_flagsin = flags; - pqia = new pqiarchive(rss, bio_in, bio_flagsin); - - for(i = 10; i < TEST_DATA_LEN; i = (int) (i * 1.1)) - //for(i = 10; i < TEST_DATA_LEN; i += 111) - { - RsItem *pkt = pqia->GetItem(); - pqia->tick(); - - /* check the packet */ - RsFileData *data = dynamic_cast(pkt); - CHECK(data != NULL); - if (data) - { - CHECK(data->fd.binData.bin_len == i); - CHECK(check_packet(data) == true); - delete data; - } - } - - /* if there are anymore packets -> error! */ - for(i = 0; i < 1000; i++) - { - RsItem *pkt = pqia->GetItem(); - CHECK(pkt == NULL); - } - - REPORT("pqiarchive_generate()"); - - return 1; -} - - - diff --git a/libretroshare/src/tests/pqi/pqiipset_test.cc b/libretroshare/src/tests/pqi/pqiipset_test.cc deleted file mode 100644 index 893fc5223..000000000 --- a/libretroshare/src/tests/pqi/pqiipset_test.cc +++ /dev/null @@ -1,157 +0,0 @@ -/* - * libretroshare/src/test/pqi pqiipset_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * NETWORKING Test to check Big/Little Endian behaviour - * as well as socket behaviour - * - */ - -#include "util/utest.h" - -#include "pqi/pqiipset.h" -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" -#include -#include - - -bool test_addr_list(); - - -INITTEST(); - -int main(int argc, char **argv) -{ - std::cerr << "libretroshare:pqi " << argv[0] << std::endl; - - test_addr_list(); - - FINALREPORT("libretroshare pqiipset Tests"); - return TESTRESULT(); -} - - /* test 1: byte manipulation */ -bool test_addr_list() -{ - pqiIpAddress addr; - pqiIpAddrList list; - - for(int i = 100; i < 150; i++) - { - std::ostringstream out; - out << "192.168.2." << i; - inet_aton(out.str().c_str(), &(addr.mAddr.sin_addr)); - addr.mAddr.sin_port = htons(7812); - addr.mSeenTime = time(NULL) - i; - - list.updateIpAddressList(addr); - - if (i < 100 + 4) - { - /* check that was added to the back */ - CHECK(list.mAddrs.back().mSeenTime == addr.mSeenTime); - CHECK(list.mAddrs.back().mAddr.sin_addr.s_addr == addr.mAddr.sin_addr.s_addr); - CHECK(list.mAddrs.back().mAddr.sin_port == addr.mAddr.sin_port); - } - else - { - /* check that wasn't added to the back */ - CHECK(list.mAddrs.back().mSeenTime != addr.mSeenTime); - CHECK(list.mAddrs.back().mAddr.sin_addr.s_addr != addr.mAddr.sin_addr.s_addr); - } - } - - /* print out the list */ - std::cerr << "IpAddressList (expect variation: 192.168.2.[100-103]:7812)"; - std::cerr << std::endl; - std::string out ; - list.printIpAddressList(out) ; - std::cerr << out << std::endl; - - const uint32_t expectedListSize = 4; - CHECK(list.mAddrs.size() == expectedListSize); - - rstime_t min_time = time(NULL) - expectedListSize + 100; - - /* expect the most recent ones to appear */ - std::list::iterator it; - for(it = list.mAddrs.begin(); it != list.mAddrs.end(); it++) - { - CHECK(it->mSeenTime < min_time); - } - - /* now add some with same address + port */ - { - std::ostringstream out; - out << "192.168.2.200"; - inet_aton(out.str().c_str(), &(addr.mAddr.sin_addr)); - addr.mAddr.sin_port = htons(8812); - } - - /* make sure it more recent than the previous ones */ - for(int i = 99; i > 89; i--) - { - addr.mSeenTime = time(NULL) - i; - list.updateIpAddressList(addr); - - /* check that was added to the front */ - CHECK(list.mAddrs.front().mSeenTime == addr.mSeenTime); - CHECK(list.mAddrs.front().mAddr.sin_addr.s_addr == addr.mAddr.sin_addr.s_addr); - CHECK(list.mAddrs.front().mAddr.sin_port == addr.mAddr.sin_port); - } - - /* print out the list */ - std::cerr << "IpAddressList (first item to be 192.168.2.200:8812)"; - std::cerr << std::endl; - list.printIpAddressList(out) ; - std::cerr << out<< std::endl; - - /* now add with the different ports */ - - for(int i = 70; i > 50; i--) - { - addr.mAddr.sin_port = htons(8000 + i); - addr.mSeenTime = time(NULL) - i; - - list.updateIpAddressList(addr); - - /* check that was added to the back */ - CHECK(list.mAddrs.front().mSeenTime == addr.mSeenTime); - CHECK(list.mAddrs.front().mAddr.sin_addr.s_addr == addr.mAddr.sin_addr.s_addr); - CHECK(list.mAddrs.front().mAddr.sin_port == addr.mAddr.sin_port); - - } - - std::cerr << "IpAddressList (expect same Ip, but variations in port)"; - std::cerr << std::endl; - list.printIpAddressList(out) ; - std::cerr << out < -#include -#include "util/utest.h" - -INITTEST(); - -int test_person_basic_reset(); -int test_person_basic_listen(); - - -int main(int argc, char **argv) -{ - std::cerr << "pqiperson_test" << std::endl; - - test_person_basic_reset(); - test_person_basic_listen(); - - FINALREPORT("pqiperson_test"); - - return TESTRESULT(); -} - -/****************************************************** - * - * tests() - * - **** ensure that functions call children - * pqiperson::reset() - * pqiperson::listen() - * pqiperson::stoplistening() - * - * - * pqiperson::connect(...) - * -> check that gets through to children. - * -> check that cannot have simultaneous connections. - * -> - * - */ - - -/******************************************************* - * - * Test structure - *****************/ - -#define NUM_CHILDREN 3 - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg) -{ - /* now add test children */ - { - std::cerr << "createTestPerson()"; - std::cerr << std::endl; - } - - pqiperson *pqip = new pqiperson(id, ppg); - - /* construct the serialiser .... - * Needs: - * * FileItem - * * FileData - * * ServiceGeneric - */ - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - rss->addSerialType(new RsCacheItemSerialiser()); - rss->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP); - pqiconnect *pqisc = new testConnect(rss, dummy1); - addTestConnect(pqisc); - pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc); - - RsSerialiser *rss2 = new RsSerialiser(); - rss2->addSerialType(new RsFileItemSerialiser()); - rss2->addSerialType(new RsCacheItemSerialiser()); - rss2->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy2 = new NetBinDummy(pqip, id, PQI_CONNECT_TUNNEL); - pqiconnect *pqicontun = new testConnect(rss2, dummy2); - addTestConnect(pqicontun); - pqip -> addChildInterface(PQI_CONNECT_TUNNEL, pqicontun); - - - RsSerialiser *rss3 = new RsSerialiser(); - rss3->addSerialType(new RsFileItemSerialiser()); - rss3->addSerialType(new RsCacheItemSerialiser()); - rss3->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy3 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP); - pqiconnect *pqiusc = new testConnect(rss3, dummy3); - addTestConnect(pqiusc); - pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc); - - return pqip; -} - - -/* First Sets of Tests are very basic: - * reset() - * connect() - * listen() / stoplistening() - * disconnect() - */ - -int test_person_basic_reset() -{ - /* reset test */ - resetTestConnects(); - - /* create test person */ - std::string id = "12345678901234567890123456789012"; - pqipersongrp *ppg = NULL; - pqiperson *person = createTestPerson(id, ppg); - - /* reset person */ - person->reset(); - - /* count number of resets */ - CHECK(NUM_CHILDREN == testCounter); - - int i; - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 1); - CHECK(testConnectState[i] == 0); - CHECK(testConnectTimes[i].size() == 0); - } - - /* clean up */ - delete person; - - REPORT("test_person_basic_reset()"); - - return 1; -} - - -int test_person_basic_listen() -{ - /* reset test */ - resetTestConnects(); - - /* create test person */ - std::string id = "12345678901234567890123456789012"; - pqipersongrp *ppg = NULL; - pqiperson *person = createTestPerson(id, ppg); - - /* reset person */ - person->listen(); - - /* count number of resets */ - CHECK(NUM_CHILDREN == testCounter); - - int i; - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 0); - CHECK(testConnectTimes[i].size() == 0); - CHECK(testConnectState[i] == TST_STATE_LISTEN); - } - - person->stoplistening(); - - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 0); - CHECK(testConnectTimes[i].size() == 0); - CHECK(testConnectState[i] == 0); - } - - /* clean up */ - delete person; - - REPORT("test_person_basic_listen()"); - - return 1; -} - - - - diff --git a/libretroshare/src/tests/pqi/pqipersongrp_test.cc b/libretroshare/src/tests/pqi/pqipersongrp_test.cc deleted file mode 100644 index d189c94fc..000000000 --- a/libretroshare/src/tests/pqi/pqipersongrp_test.cc +++ /dev/null @@ -1,266 +0,0 @@ -/* - * libretroshare/src/test/pqi pqiperson_test.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pqiperson acts as the wrapper for all connection methods to a single peer. - * - * This test creates, a pqiperson and simulates connections, disconnections. - * packets passing through. - * - */ - - - - - - -#include "pqi/pqiperson.h" -#include "pqi/pqibin.h" - -#include "testconnect.h" - -#include "util/rsnet.h" -#include -#include -#include "util/utest.h" - -INITTEST(); - -int test_person_basic_reset(); -int test_person_basic_listen(); - - -int main(int argc, char **argv) -{ - std::cerr << "pqiperson_test" << std::endl; - - test_person_basic_reset(); - test_person_basic_listen(); - - FINALREPORT("pqiperson_test"); - - return TESTRESULT(); -} - -/****************************************************** - * - * tests() - * - **** ensure that functions call children - * pqiperson::reset() - * pqiperson::listen() - * pqiperson::stoplistening() - * - * - * pqiperson::connect(...) - * -> check that gets through to children. - * -> check that cannot have simultaneous connections. - * -> - * - */ - - -/******************************************************* - * - * Test structure - *****************/ - -#define NUM_CHILDREN 3 - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg); - -class pqipersongrpTestHarness: public pqipersongrp -{ - public: - pqipersongrpTestHarness(SecurityPolicy *pol, unsigned long flags) - :pqipersongrp(pol, flags) - { - return; - } - - protected: - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -virtual pqilistener *createListener(struct sockaddr_in laddr) -{ - return new pqilistener(laddr); -} - -virtual pqiperson *createPerson(std::string id, pqilistener *listener) -{ - return createTestPerson(id, this); -} - - /********* FUNCTIONS to OVERLOAD for specialisation ********/ -}; - - - - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg) -{ - /* now add test children */ - { - std::cerr << "createTestPerson()"; - std::cerr << std::endl; - } - - pqiperson *pqip = new pqiperson(id, ppg); - - /* construct the serialiser .... - * Needs: - * * FileItem - * * FileData - * * ServiceGeneric - */ - - RsSerialiser *rss = new RsSerialiser(); - rss->addSerialType(new RsFileItemSerialiser()); - rss->addSerialType(new RsCacheItemSerialiser()); - rss->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy1 = new NetBinDummy(pqip, id, PQI_CONNECT_TCP); - pqiconnect *pqisc = new testConnect(rss, dummy1); - addTestConnect(pqisc); - pqip -> addChildInterface(PQI_CONNECT_TCP, pqisc); - - RsSerialiser *rss2 = new RsSerialiser(); - rss2->addSerialType(new RsFileItemSerialiser()); - rss2->addSerialType(new RsCacheItemSerialiser()); - rss2->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy2 = new NetBinDummy(pqip, id, PQI_CONNECT_TUNNEL); - pqiconnect *pqicontun = new testConnect(rss2, dummy2); - addTestConnect(pqicontun); - pqip -> addChildInterface(PQI_CONNECT_TUNNEL, pqicontun); - - - RsSerialiser *rss3 = new RsSerialiser(); - rss3->addSerialType(new RsFileItemSerialiser()); - rss3->addSerialType(new RsCacheItemSerialiser()); - rss3->addSerialType(new RsServiceSerialiser()); - - NetBinDummy *dummy3 = new NetBinDummy(pqip, id, PQI_CONNECT_UDP); - pqiconnect *pqiusc = new testConnect(rss3, dummy3); - addTestConnect(pqiusc); - pqip -> addChildInterface(PQI_CONNECT_UDP, pqiusc); - - return pqip; -} - - -/* First Sets of Tests are very basic: - * reset() - * connect() - * listen() / stoplistening() - * disconnect() - */ - -int test_person_basic_reset() -{ - /* reset test */ - resetTestConnects(); - - /* create test person */ - std::string id = "12345678901234567890123456789012"; - - pqipersongrp *ppg = pqipersongrpTestHarness(NULL, 0); - - /* setup fake other bits */ - - - /* add peers - and watch it all happen! */ - - - - pqiperson *person = createTestPerson(id, ppg); - - /* reset person */ - person->reset(); - - /* count number of resets */ - CHECK(NUM_CHILDREN == testCounter); - - int i; - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 1); - CHECK(testConnectState[i] == 0); - CHECK(testConnectTimes[i].size() == 0); - } - - /* clean up */ - delete person; - - REPORT("test_person_basic_reset()"); - - return 1; -} - - -int test_person_basic_listen() -{ - /* reset test */ - resetTestConnects(); - - /* create test person */ - std::string id = "12345678901234567890123456789012"; - pqipersongrp *ppg = NULL; - pqiperson *person = createTestPerson(id, ppg); - - /* reset person */ - person->listen(); - - /* count number of resets */ - CHECK(NUM_CHILDREN == testCounter); - - int i; - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 0); - CHECK(testConnectTimes[i].size() == 0); - CHECK(testConnectState[i] == TST_STATE_LISTEN); - } - - person->stoplistening(); - - for(i = 0; i < NUM_CHILDREN; i++) - { - CHECK(testResetTimes[i].size() == 0); - CHECK(testConnectTimes[i].size() == 0); - CHECK(testConnectState[i] == 0); - } - - /* clean up */ - delete person; - - REPORT("test_person_basic_listen()"); - - return 1; -} - - - - diff --git a/libretroshare/src/tests/pqi/pqiqos_test.cc b/libretroshare/src/tests/pqi/pqiqos_test.cc deleted file mode 100644 index eea4846ae..000000000 --- a/libretroshare/src/tests/pqi/pqiqos_test.cc +++ /dev/null @@ -1,191 +0,0 @@ -#include "util/utest.h" - -#include -#include -#include -#include "serialiser/rsserial.h" -#include "util/rsrandom.h" -#include "pqi/pqiqos.h" - -INITTEST(); - -// Class of RsItem with ids to check order -// -class testRawItem: public RsItem -{ - public: - testRawItem() - : RsItem(0,0,0), _id(_static_id++) - { - } - - virtual void clear() {} - virtual std::ostream& print(std::ostream& o, uint16_t) { return o ; } - - static const uint32_t rs_rawitem_size = 10 ; - static uint64_t _static_id ; - uint64_t _id ; -}; -uint64_t testRawItem::_static_id = 1; - -int main() -{ - float alpha = 3 ; - int nb_levels = 10 ; - - ////////////////////////////////////////////// - // 1 - Test consistency of output and order // - ////////////////////////////////////////////// - { - pqiQoS qos(nb_levels,alpha) ; - - // 0 - Fill the queue with fake RsItem. - // - static const uint32_t pushed_items = 10000 ; - - for(uint32_t i=0;isetPriorityLevel(i % nb_levels) ; - - qos.in_rsItem(item,item->priority_level()) ; - } - std::cerr << "QOS is filled with: " << std::endl; - qos.print() ; - - // 1 - checks that all items eventually got out in the same order for - // items of equal priority - // - uint32_t poped = 0; - std::vector last_ids(nb_levels,0) ; - - while(testRawItem *item = static_cast(qos.out_rsItem())) - { - CHECK(last_ids[item->priority_level()] < item->_id) ; - - last_ids[item->priority_level()] = item->_id ; - delete item, ++poped ; - } - - std::cerr << "Push " << pushed_items << " items, poped " << poped << std::endl; - - if(pushed_items != poped) - { - std::cerr << "Queues are: " << std::endl; - qos.print() ; - } - CHECK(pushed_items == poped) ; - } - - ////////////////////////////////////////////////// - // 2 - tests proportionality // - ////////////////////////////////////////////////// - { - // Now we feed the QoS, and check that items get out with probability proportional - // to the priority - // - pqiQoS qos(nb_levels,alpha) ; - - std::cerr << "Feeding 10^6 packets to the QoS service." << std::endl; - for(int i=0;i<1000000;++i) - { - if(i%10000 == 0) - { - fprintf(stderr,"%1.2f %% completed.\r",i/(float)1000000*100.0f) ; - fflush(stderr) ; - } - testRawItem *item = new testRawItem ; - - switch(i%5) - { - case 0: item->setPriorityLevel( 1 ) ; break ; - case 1: item->setPriorityLevel( 4 ) ; break ; - case 2: item->setPriorityLevel( 6 ) ; break ; - case 3: item->setPriorityLevel( 7 ) ; break ; - case 4: item->setPriorityLevel( 8 ) ; break ; - } - - qos.in_rsItem(item,item->priority_level()) ; - } - - // Now perform stats on outputs for the 10000 first elements - - std::vector hist(nb_levels,0) ; - - for(uint32_t i=0;i<10000;++i) - { - testRawItem *item = static_cast(qos.out_rsItem()) ; - hist[item->priority_level()]++ ; - delete item ; - } - - std::cerr << "Histogram: " ; - for(uint32_t i=0;isetPriorityLevel(i%nb_levels) ; - qos.in_rsItem(item,item->priority_level()) ; - } - - // pop a random number of packets out - - std::vector last_ids(nb_levels,0) ; - - for(uint32_t i=0;i(qos.out_rsItem()) ; - - if(item == NULL) - { - std::cerr << "Null output !" << std::endl; - break ; - } - - CHECK(last_ids[item->priority_level()] < item->_id) ; - - last_ids[item->priority_level()] = item->_id ; - delete item ; - } - - // print some info - static rstime_t last = 0 ; - if(now > last) - { - qos.print() ; - last = now ; - } - } - } - - FINALREPORT("pqiqos_test"); - return TESTRESULT() ; -} - - diff --git a/libretroshare/src/tests/pqi/testconnect.cc b/libretroshare/src/tests/pqi/testconnect.cc deleted file mode 100644 index 0dc019c18..000000000 --- a/libretroshare/src/tests/pqi/testconnect.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * libretroshare/src/test/pqi testconnect.cc - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****** - * pqiperson acts as the wrapper for all connection methods to a single peer. - * - * This test creates, a pqiperson and simulates connections, disconnections. - * packets passing through. - * - */ - - -#include "testconnect.h" -#include "pqi/pqibin.h" -#include -#include - -/******************************************************* - * - * Test structure - *****************/ - - -#define NUM_CONN_MAX 10 -#define NUM_CHILDREN 3 - -#define TST_STATE_CONNECT 0x0001 -#define TST_STATE_LISTEN 0x0002 - -/* static test variables */ -uint32_t testCounter = 0; -pqiconnect *testConnectPointer[NUM_CONN_MAX]; -uint32_t testConnectState[NUM_CONN_MAX]; -std::list testConnectTimes[NUM_CONN_MAX]; -std::list testConnectAddrs[NUM_CONN_MAX]; - -std::list testResetState[NUM_CONN_MAX]; -std::list testResetTimes[NUM_CONN_MAX]; - -uint32_t findWhichConnect(pqiconnect *conn) -{ - int i; - for(i = 0; i < NUM_CONN_MAX; i++) - { - if (testConnectPointer[i] == conn) - { - return i; - } - } - // error. - std::cerr << "Connect Missing" << std::endl; - exit(1); - return 0; -} - -void addTestConnect(pqiconnect *pqi) -{ - testConnectPointer[testCounter] = pqi; - testConnectState[testCounter] = 0; - testCounter++; - if (testCounter > NUM_CONN_MAX) - { - std::cerr << "Too Many Connects" << std::endl; - exit(1); - } -} - -void resetTestConnects() -{ - testCounter = 0; - int i; - for(i = 0; i < NUM_CONN_MAX; i++) - { - testConnectAddrs[i].clear(); - testConnectTimes[i].clear(); - testResetState[i].clear(); - testResetTimes[i].clear(); - } -} - - -testConnect::testConnect(RsSerialiser *rss, NetBinInterface *ni_in) - :pqiconnect(rss, ni_in) -{ - -} - -testConnect::~testConnect() -{ - return; -} - - /* dummyConnect */ -int testConnect::connect(struct sockaddr_in raddr) -{ - int cidx = findWhichConnect(this); - rstime_t now = time(NULL); - - testConnectState[cidx] |= TST_STATE_CONNECT; - testConnectTimes[cidx].push_back(now); - testConnectAddrs[cidx].push_back(raddr); - - std::cerr << "testConnect[" << cidx << "].connect() called"; - std::cerr << std::endl; - return 0; -} - -int testConnect::listen() -{ - int cidx = findWhichConnect(this); - testConnectState[cidx] |= TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].listen() called"; - std::cerr << std::endl; - return 1; -} - -int testConnect::stoplistening() -{ - int cidx = findWhichConnect(this); - testConnectState[cidx] &= ~TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].stoplistening() called"; - std::cerr << std::endl; - return 1; -} - -int testConnect::reset() -{ - int cidx = findWhichConnect(this); - rstime_t now = time(NULL); - - // reset everything except listening. - testResetState[cidx].push_back(testConnectState[cidx]); - testResetTimes[cidx].push_back(now); - testConnectState[cidx] &= TST_STATE_LISTEN; - - std::cerr << "testConnect[" << cidx << "].reset() called"; - std::cerr << std::endl; - return 1; -} - -// leave this as is virtual int disconnect() { return ni -> reset(); } - -bool testConnect::connect_parameter(uint32_t type, uint32_t value) -{ - int cidx = findWhichConnect(this); - //testConnectState[cidx] |= TST_STATE_LISTEN; - std::cerr << "testConnect[" << cidx << "].connect_parameter() called"; - std::cerr << std::endl; - return true; -} - -int testConnect::getConnectAddress(struct sockaddr_in &raddr) -{ - int cidx = findWhichConnect(this); - if (testConnectAddrs[cidx].size() > 0) - { - raddr = testConnectAddrs[cidx].back(); - return 1; - } - std::cerr << "testConnect[" << cidx << "].getConnectAddress() called"; - std::cerr << std::endl; - return 0; -} - diff --git a/libretroshare/src/tests/pqi/testconnect.h b/libretroshare/src/tests/pqi/testconnect.h deleted file mode 100644 index c0eda479c..000000000 --- a/libretroshare/src/tests/pqi/testconnect.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef TEST_PQICONNECT_H -#define TEST_PQICONNECT_H - -/* - * libretroshare/src/test/pqi testconnect.h - * - * 3P/PQI network interface for RetroShare. - * - * Copyright 2007-2010 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "pqi/pqiperson.h" -//#include "pqi/pqibin.h" -#include "util/rsnet.h" - -/******************************************************* - * - * Test structure - *****************/ - - -#define NUM_CONN_MAX 10 - -#define TST_STATE_CONNECT 0x0001 -#define TST_STATE_LISTEN 0x0002 - -/* static test variables */ -extern uint32_t testCounter; -extern pqiconnect *testConnectPointer[NUM_CONN_MAX]; -extern uint32_t testConnectState[NUM_CONN_MAX]; -extern std::list testConnectTimes[NUM_CONN_MAX]; -extern std::list testConnectAddrs[NUM_CONN_MAX]; - -extern std::list testResetState[NUM_CONN_MAX]; -extern std::list testResetTimes[NUM_CONN_MAX]; - -uint32_t findWhichConnect(pqiconnect *conn); -void addTestConnect(pqiconnect *pqi); -void resetTestConnects(); - -class testConnect: public pqiconnect -{ - public: - - testConnect(RsSerialiser *rss, NetBinInterface *ni_in); - virtual ~testConnect(); - - /* dummyConnect */ - virtual int connect(struct sockaddr_in raddr); - virtual int listen(); - virtual int stoplistening(); - virtual int reset(); - virtual bool connect_parameter(uint32_t type, uint32_t value); - virtual int getConnectAddress(struct sockaddr_in &raddr); -}; // end of testConnect. - - -pqiperson *createTestPerson(std::string id, pqipersongrp *ppg); - - -#endif - diff --git a/libretroshare/src/tests/printcache/main.cpp b/libretroshare/src/tests/printcache/main.cpp deleted file mode 100644 index 66354946a..000000000 --- a/libretroshare/src/tests/printcache/main.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * main.cpp - * - * Created on: 11 Apr 2011 - * Author: greyfox - */ - -#include -#include -#include - -#include -#include "pqi/pqistreamer.h" -#include "pqi/pqibin.h" -#include "serialiser/rsdistribitems.h" -#include "pqi/pqistore.h" - -int main(int argc, char **argv) -{ - try - { - argstream as(argc,argv) ; - bool full_print = false ; - - std::string cacheFileName; - - as >> parameter('f',"file",cacheFileName,"cache file name to read",true) - >> option('F',"full",full_print,"full dump of distrib items") - >> help() ; - - as.defaultErrorHandling() ; - - std::cout << "opening file: " << cacheFileName << std::endl; - // open file - BinInterface *bio = new BinFileInterface(cacheFileName.c_str(), BIN_FLAGS_READABLE); - RsSerialiser *rsSerialiser = new RsSerialiser(); - RsSerialType *serialType = new RsDistribSerialiser(); - rsSerialiser->addSerialType(serialType); - pqistore *store = new pqistore(rsSerialiser, "", bio, BIN_FLAGS_READABLE); - RsItem* item; - - std::set already ; - int signed_msgs = 0 ; - int distrib_msgs = 0 ; - int nb_duplicated = 0 ; - - // then print out contents to screen - while(NULL != (item = store->GetItem())) - { - - if(full_print) - item->print(std::cout, 0); - else - { - { - RsDistribMsg *i = dynamic_cast(item) ; - if(i!=NULL) - { - std::cerr << "Grp=" << i->grpId << ", parent=" << i->parentId << ", msgId=" << i->msgId ; - - if(already.find(i->msgId)!=already.end()) - { - std::cerr << " *** double ***" ; - ++nb_duplicated ; - } - else - already.insert(i->msgId) ; - - std::cerr << std::endl; - ++distrib_msgs ; - } - } - { - RsDistribSignedMsg *i = dynamic_cast(item) ; - if(i!=NULL) - { - std::cerr << "Grp=" << i->grpId << ", msgId=" << i->msgId << ", type=" << i->packet.tlvtype << ", len=" << i->packet.bin_len ; - - if(already.find(i->msgId)!=already.end()) - { - std::cerr << " *** double ***" ; - ++nb_duplicated ; - } - else - already.insert(i->msgId) ; - - std::cerr << std::endl; - - ++signed_msgs ; - } - } - } - } - - std::cerr << std::endl ; - std::cerr << "Signed messages (RsDistribMsg) : " << distrib_msgs << std::endl; - std::cerr << "Signed messages (RsDistribSignedMsg): " << signed_msgs << std::endl; - std::cerr << "Duplicate messages : " << nb_duplicated << std::endl; - - return 0; - } - catch(std::exception& e) - { - std::cerr << "Unhandled exception: " << e.what() << std::endl; - return 1 ; - } -} - - - diff --git a/libretroshare/src/tests/printcache/main_extended.cpp b/libretroshare/src/tests/printcache/main_extended.cpp deleted file mode 100644 index 2cdba7d8d..000000000 --- a/libretroshare/src/tests/printcache/main_extended.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * main.cpp - * - * Created on: 11 Apr 2011 - * Author: greyfox - */ - -#include -#include -#include - -#include -#include "pqi/pqistreamer.h" -#include "pqi/pqibin.h" -#include "serialiser/rsdistribitems.h" -#include "pqi/pqistore.h" - -int storeMsg(std::map > &msgMap, std::string filename, - std::string grpId, std::string msgId); - -pqistore *BuildSerialiser(int type, std::string filename); - -int main(int argc, char **argv) -{ - - std::list fileList; - std::list::iterator fit; - - for(int i = 1; i < argc; i++) - { - fileList.push_back(argv[i]); - } - - std::map > msgMap; - std::map >::iterator mit; - - bool printInput = true; - bool printAll = true; - bool printSummary = true; - int distrib_msgs = 0; - int signed_msgs = 0; - - for(fit = fileList.begin(); fit != fileList.end(); fit++) - { - if (printInput) - { - std::cerr << "Loading File: " << *fit; - std::cerr << std::endl; - } - - /* process this file */ - pqistore *store = BuildSerialiser(0, *fit); - RsItem* item; - RsDistribMsg *distMsg; - RsDistribSignedMsg *signMsg; - - while(NULL != (item = store->GetItem())) - { - if (NULL != (distMsg = dynamic_cast(item))) - { - if (printInput) - { - std::cerr << "Grp = " << distMsg->grpId; - std::cerr << ", parent = " << distMsg->parentId; - std::cerr << ", msgId = " << distMsg->msgId; - std::cerr << std::endl; - } - storeMsg(msgMap, *fit, distMsg->grpId, distMsg->msgId); - ++distrib_msgs ; - } - if (NULL != (signMsg = dynamic_cast(item))) - { - if (printInput) - { - std::cerr << "Grp = " << signMsg->grpId; - std::cerr << ", msgId = " << signMsg->msgId; - std::cerr << ", type = " << signMsg->packet.tlvtype; - std::cerr << ", len = " << signMsg->packet.bin_len; - std::cerr << std::endl; - } - storeMsg(msgMap, *fit, signMsg->grpId, signMsg->msgId); - ++signed_msgs ; - } - } - - delete store; - } - for(mit = msgMap.begin(); mit != msgMap.end(); mit++) - { - bool print = printAll; - if (mit->second.size() > 1) - { - /* duplicates */ - print = true; - } - - if (print) - { - std::cerr << "MsgId: " << mit->first; - std::cerr << " in Files: "; - - std::list::iterator fit; - for(fit = mit->second.begin(); fit != mit->second.end(); fit++) - { - std::cerr << *fit << " "; - } - std::cerr << std::endl; - } - } - if (printSummary) - { - std::cerr << "# RsDistribMsg(s): " << distrib_msgs << std::endl; - std::cerr << "# RsDistribSignedMsg(s): " << signed_msgs << std::endl; - std::cerr << std::endl; - } -} - - -int storeMsg(std::map > &msgMap, std::string filename, - std::string grpId, std::string msgId) -{ - std::map >::iterator mit; - mit = msgMap.find(msgId); - if (mit == msgMap.end()) - { - std::list fileList; - fileList.push_back(filename); - msgMap[msgId] = fileList; - } - else - { - (mit->second).push_back(filename); - } - return 1; -} - - -pqistore *BuildSerialiser(int type, std::string filename) -{ - BinInterface *bio = new BinFileInterface(filename.c_str(), BIN_FLAGS_READABLE); - RsSerialiser *rsSerialiser = new RsSerialiser(); - RsSerialType *serialType = new RsDistribSerialiser(); - rsSerialiser->addSerialType(serialType); - - // can use type to add more serialiser types - //RsSerialType *serialType = new RsDistribSerialiser(); - //rsSerialiser->addSerialType(serialType); - - pqistore *store = new pqistore(rsSerialiser, "", bio, BIN_FLAGS_READABLE); - return store; -} - - diff --git a/libretroshare/src/tests/printcache/printcache.pro b/libretroshare/src/tests/printcache/printcache.pro deleted file mode 100644 index ed61aa4c9..000000000 --- a/libretroshare/src/tests/printcache/printcache.pro +++ /dev/null @@ -1,31 +0,0 @@ -TEMPLATE = app -CONFIG = debug - -#SOURCES = main.cpp -SOURCES = main_extended.cpp - -LIBS += ../../lib/libretroshare.a ../../../../libbitdht/src/lib/libbitdht.a ../../../../openpgpsdk/src/lib/libops.a -LIBS += -lssl -lcrypto -lupnp -lgnome-keyring -lixml -lbz2 - -INCLUDEPATH *= ../.. .. -linux { - #LIBS = -lstdc++ -lm -} -macx { - # ENABLE THIS OPTION FOR Univeral Binary BUILD. - # CONFIG += ppc x86 - # QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 - # CONFIG -= uitools - - LIBS += ../../lib/libretroshare.a - LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan - LIBS += ../../../../../miniupnpc-1.0/libminiupnpc.a - LIBS += ../../../../libbitdht/src/lib/libbitdht.a - LIBS += -framework CoreFoundation - LIBS += -framework Security - - # LIBS += -framework CoreServices - - -} - diff --git a/libretroshare/src/tests/scripts/checks.mk b/libretroshare/src/tests/scripts/checks.mk deleted file mode 100644 index dcb19ff3f..000000000 --- a/libretroshare/src/tests/scripts/checks.mk +++ /dev/null @@ -1,25 +0,0 @@ -#Basic checks - -ifndef RS_TOP_DIR -dummy: - echo "RS_TOP_DIR is not defined in your makefile" -endif - -#ifndef SSL_DIR -#dummy: -# echo "you must define SSL_DIR before you can compile" -# -#endif - -ifneq ($(OS),Linux) - ifneq ($(OS),MacOSX) - ifndef PTHREADS_DIR -dummy: - echo "you must define PTHREADS_DIR before you can compile" - - endif - endif -endif - - - diff --git a/libretroshare/src/tests/scripts/config-cygwin.mk b/libretroshare/src/tests/scripts/config-cygwin.mk deleted file mode 100644 index ec4518f68..000000000 --- a/libretroshare/src/tests/scripts/config-cygwin.mk +++ /dev/null @@ -1,118 +0,0 @@ -ifneq ($(OS),Cygwin) -dummy: - echo "ERROR Cygwin configuration file included, but (OS != Cygwin) - -endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -SRC_ROOT=../../../.. - -PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads/pthreads.2 - -################### - -#ALT_SRC_ROOT=/cygdrive/c/RetroShareBuild/src -#SRC_ROOT=/cygdrive/c/RetroShareBuild/src - -#PTHREADS_DIR=$(ALT_SRC_ROOT)/pthreads-w32-2-8-0-release - -################### - -ZLIB_DIR=$(ALT_SRC_ROOT)/zlib-1.2.3 - -SSL_DIR=$(SRC_ROOT)/openssl-0.9.7g-xpgp-0.1c -UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -ifdef PQI_USE_XPGP - INCLUDE += -I $(SSL_DIR)/include -endif - -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -RSCFLAGS = -Wall -g $(INCLUDE) - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -WININC += -DPTW32_STATIC_LIB -WININC += -mno-cygwin -mwindows -fno-exceptions -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(PTHREADS_DIR) $(WININC) -CFLAGS += -I$(ZLIB_DIR) - -LIBS = -L$(LIBDIR) -lretroshare -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) -endif - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -RSCFLAGS += $(WININC) - - diff --git a/libretroshare/src/tests/scripts/config-linux.mk b/libretroshare/src/tests/scripts/config-linux.mk deleted file mode 100644 index c97a3c21e..000000000 --- a/libretroshare/src/tests/scripts/config-linux.mk +++ /dev/null @@ -1,78 +0,0 @@ - -ifneq ($(OS),Linux) -dummy: - echo "ERROR Linux configuration file included, but (OS != Linux) - -endif - -############ LINUX CONFIGURATION ######################## - -#UPNPC_DIR=../../../../miniupnpc-1.0 - -# Need to define miniupnpc version because API changed a little between v1.0 and 1.2 -# put 10 for 1.0 and 12 for 1.2 -DEFINES += -D_FILE_OFFSET_BITS=64 -DSQLITE_HAS_CODEC - -include $(RS_TOP_DIR)/tests/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -BITDIR = $(DHT_TOP_DIR)/lib -OPSDIR = $(OPS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a -BITDHT = $(BITDIR)/libbitdht.a -# Unix: Linux/Cygwin -INCLUDE = -I$(RS_TOP_DIR) -I$(OPS_TOP_DIR) -I$(DHT_TOP_DIR) -CFLAGS = -Wall -g $(INCLUDE) -I.. -#CFLAGS += -fprofile-arcs -ftest-coverage -CFLAGS += ${DEFINES} - -#ifdef PQI_USE_XPGP -# INCLUDE += -I $(SSL_DIR)/include -#endif -# -#ifdef PQI_USE_XPGP -# CFLAGS += -DPQI_USE_XPGP -#endif - -RSCFLAGS = -Wall -g $(INCLUDE) -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# march=i686 causes problems while 64Bit compiling, GCC tries to generate Output for a m64 machine, but the marchi686 -# doesnt allow the instructionfs for that. -# -# gcc docu: http://gcc.gnu.org/onlinedocs/gcc-4.0.3/gcc/i386-and-x86_002d64-Options.html#i386-and-x86_002d64-Options - -# Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include ${DEFINES} -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM - -######################################################################### -# OS specific Linking. -######################################################################### - -LIBS = -L$(LIBDIR) -lretroshare -LIBS += -L$(BITDIR) -lbitdht -lgnome-keyring -LIBS += -L$(OPSDIR) -lops -LIBS += -lixml -lbz2 - -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) - endif -LIBS += -lssl -lcrypto -lpthread -#LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += $(XLIB) -ldl -lz -LIBS += -lupnp -LIBS += -lsqlcipher - -RSLIBS = $(LIBS) - - diff --git a/libretroshare/src/tests/scripts/config-macosx.mk b/libretroshare/src/tests/scripts/config-macosx.mk deleted file mode 100644 index b13a471f0..000000000 --- a/libretroshare/src/tests/scripts/config-macosx.mk +++ /dev/null @@ -1,98 +0,0 @@ - -ifneq ($(OS),MacOSX) -dummy: - echo "ERROR MacOSX configuration file included, but (OS != MacOSX) - -endif - -############ LINUX CONFIGURATION ######################## - - -# FLAGS to decide if we want i386 Build or ppc Build -# -# - -# PPC is default -# Could define both for combined compilation... -# except might not work for bio_tou.c file! -# -# MAC_I386_BUILD = 1 -# MAC_PPC_BUILD = 1 - -MAC_I386_BUILD = 1 -#MAC_PPC_BUILD = 1 - -ifndef MAC_I386_BUILD - MAC_PPC_BUILD = 1 -endif - -UPNPC_DIR=../../../../../../src/miniupnpc-1.0 - -include $(RS_TOP_DIR)/tests/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ######################## - -CC = g++ -RM = /bin/rm - -RANLIB = ranlib - -# Dummy ranlib -> can't do it until afterwards with universal binaries. -# RANLIB = ls -l - -OPSDIR = $(OPS_TOP_DIR)/lib -BITDIR = $(DHT_TOP_DIR)/lib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -OPT_DIR = /opt/local -OPT_INCLUDE = $(OPT_DIR)/include -OPT_LIBS = $(OPT_DIR)/lib - -INCLUDE = -I $(RS_TOP_DIR) -I $(OPT_INCLUDE) -#CFLAGS = -Wall -O3 -CFLAGS = -Wall -g - -# Flags for architecture builds. -ifdef MAC_I386_BUILD - CFLAGS += -arch i386 -endif - -ifdef MAC_PPC_BUILD - CFLAGS += -arch ppc -endif - -CFLAGS += $(INCLUDE) - -# This Line is for Universal BUILD for 10.4 + 10.5 -# (but unlikely to work unless Qt Libraries are build properly) -#CFLAGS += -isysroot /Developer/SDKs/MacOSX10.5.sdk - -# RSCFLAGS = -Wall -O3 $(INCLUDE) - -######################################################################### -# OS Compile Options -######################################################################### - -######################################################################### -# OS specific Linking. -######################################################################### - -LIBS = -Wl,-search_paths_first - -# for Univeral BUILD -# LIBS += -arch ppc -arch i386 -#LIBS += -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5u.sdk - -LIBS = -L$(LIBDIR) -lretroshare -LIBS += -L$(BITDIR) -lbitdht -LIBS += -L$(OPSDIR) -lops -ifdef PQI_USE_XPGP - LIBS += -L$(SSL_DIR) - endif -LIBS += -lssl -lcrypto -lpthread -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += $(XLIB) -ldl -lz - - - diff --git a/libretroshare/src/tests/scripts/config-mingw.mk b/libretroshare/src/tests/scripts/config-mingw.mk deleted file mode 100644 index c0040ac4e..000000000 --- a/libretroshare/src/tests/scripts/config-mingw.mk +++ /dev/null @@ -1,138 +0,0 @@ -#ifneq ($(OS),"Win ") -#dummy: -# echo "ERROR OS = $(OS)" -# echo "ERROR MinGW configuration file included, but (OS != Win) -# -#endif - -############ LINUX CONFIGURATION ######################## - -# flags for components.... -#PQI_USE_XPGP = 1 -#PQI_USE_PROXY = 1 -#PQI_USE_CHANNELS = 1 -#USE_FILELOOK = 1 - -########################################################################### - -#### DrBobs Versions.... Please Don't Delete. -### Comment out if needed. -SRC_ROOT_PKG=/home/Mark/prog/retroshare/package/rs-win-v0.5.0/src -SRC_ROOT_GPG=/local - -#ALT_SRC_ROOT=/cygdrive/c/home/rmfern/prog/MinGW -#SRC_ROOT=../../../.. - -PTHREADS_DIR=$(SRC_ROOT_PKG)/pthreads-w32-2-8-0/Pre-built.2 -ZLIB_DIR=$(SRC_ROOT_PKG)/zlib-1.2.3 -SSL_DIR=$(SRC_ROOT_PKG)/openssl-tmp -UPNPC_DIR=$(SRC_ROOT_PKG)/miniupnpc-1.3 - -########################################################################### - -#### Enable this section for compiling with MSYS/MINGW compile -#SRC_ROOT=/home/linux - -#SSL_DIR=$(SRC_ROOT)/OpenSSL -#GPGME_DIR=$(SRC_ROOT)/gpgme-1.1.8 -#GPG_ERROR_DIR=$(SRC_ROOT)/libgpg-error-1.7 - -#ZLIB_DIR=$(SRC_ROOT)/zlib-1.2.3 -#UPNPC_DIR=$(SRC_ROOT)/miniupnpc-1.0 -#PTHREADS_DIR=$(SRC_ROOT)/pthreads-w32-2-8-0-release - -include $(RS_TOP_DIR)/scripts/checks.mk - -############ ENFORCE DIRECTORY NAMING ####################################### - -CC = g++ -RM = /bin/rm -RANLIB = ranlib -LIBDIR = $(RS_TOP_DIR)/lib -LIBRS = $(LIBDIR)/libretroshare.a - -# Unix: Linux/Cygwin -INCLUDE = -I $(RS_TOP_DIR) - -ifdef PQI_DEBUG - CFLAGS = -Wall -g $(INCLUDE) -else - CFLAGS = -Wall -O2 $(INCLUDE) -endif - -# These aren't used anymore.... really. -ifdef PQI_USE_XPGP - CFLAGS += -DPQI_USE_XPGP -endif - -ifdef PQI_USE_PROXY - CFLAGS += -DPQI_USE_PROXY -endif - -ifdef PQI_USE_CHANNELS - CFLAGS += -DPQI_USE_CHANNELS -endif - -ifdef USE_FILELOOK - CFLAGS += -DUSE_FILELOOK -endif - - -# SSL / pthreads / Zlib -# included by default for Windows compilation. -INCLUDE += -I $(SSL_DIR)/include -INCLUDE += -I$(PTHREADS_DIR) -INCLUDE += -I$(ZLIB_DIR) - - -######################################################################### -# OS Compile Options -######################################################################### - -# For the SSL BIO compilation. (Copied from OpenSSL compilation flags) -BIOCC = gcc - -# Cygwin - ?same? as Linux flags -BIOCFLAGS = -I $(SSL_DIR)/include -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -BIOCFLAGS += -DWINDOWS_SYS - -######################################################################### -# OS specific Linking. -######################################################################### - -# for static pthread libs.... -#WININC += -DPTW32_STATIC_LIB -#WININC += -mno-cygwin -mwindows -fno-exceptions - -WININC += -DWINDOWS_SYS - -WINLIB = -lws2_32 -luuid -lole32 -liphlpapi -WINLIB += -lcrypt32 -lwinmm - -CFLAGS += -I$(SSL_DIR)/include -CFLAGS += -I$(PTHREADS_DIR)/include -CFLAGS += -I$(ZLIB_DIR) -CFLAGS += -I$(SRC_ROOT_GPG)/include - -### Enable this for GPGME and GPG ERROR dirs -#CFLAGS += -I$(GPGME_DIR)/src -#CFLAGS += -I$(GPG_ERROR_DIR)/src - -CFLAGS += $(WININC) - - - -LIBS = -L$(LIBDIR) -lretroshare - -LIBS += -L$(SSL_DIR) - -LIBS += -lssl -lcrypto -LIBS += -L$(UPNPC_DIR) -lminiupnpc -LIBS += -L$(ZLIB_DIR) -lz -LIBS += -L$(PTHREADS_DIR) -lpthreadGC2d -LIBS += $(WINLIB) - -#RSCFLAGS = -Wall -g $(INCLUDE) -#RSCFLAGS += $(WININC) - - diff --git a/libretroshare/src/tests/scripts/config.mk b/libretroshare/src/tests/scripts/config.mk deleted file mode 100644 index 951eca4c6..000000000 --- a/libretroshare/src/tests/scripts/config.mk +++ /dev/null @@ -1,27 +0,0 @@ - -# determine which operating system -# -########################################################################### -#Define OS. -# -OS = Linux -#OS = MacOSX -#OS = Cygwin -#OS = Win # MinGw. -########################################################################### - -ifeq ($(OS),Linux) - include $(RS_TOP_DIR)/tests/scripts/config-linux.mk -else - ifeq ($(OS),MacOSX) - include $(RS_TOP_DIR)/tests/scripts/config-macosx.mk - else - ifeq ($(OS),Cygwin) - include $(RS_TOP_DIR)/tests/scripts/config-cygwin.mk - else - include $(RS_TOP_DIR)/tests/scripts/config-mingw.mk - endif - endif -endif - -########################################################################### diff --git a/libretroshare/src/tests/scripts/regress.mk b/libretroshare/src/tests/scripts/regress.mk deleted file mode 100644 index 7d69df664..000000000 --- a/libretroshare/src/tests/scripts/regress.mk +++ /dev/null @@ -1,25 +0,0 @@ - -testoutputfiles = $(foreach tt,$(1),$(tt).tstout) - -%.tstout : %.sh % - -sh ./$< > $@ 2>&1 - -%.tstout : % - -./$< > $@ 2>&1 - -TESTOUT = $(call testoutputfiles,$(TESTS)) - -.phony : tests regress retest clobber - -tests: $(TESTS) - -regress: $(TESTOUT) - @-echo "--------------- SUCCESS (count):" - @-grep -c SUCCESS $(TESTOUT) - @-echo "--------------- FAILURE REPORTS:" - @-grep FAILURE $(TESTOUT) || echo no failures - @-echo "--------------- end" - -retest: - -/bin/rm $(TESTOUT) - diff --git a/libretroshare/src/tests/scripts/rules.mk b/libretroshare/src/tests/scripts/rules.mk deleted file mode 100644 index 3df30a488..000000000 --- a/libretroshare/src/tests/scripts/rules.mk +++ /dev/null @@ -1,24 +0,0 @@ - -# defines required / used. -# -# CFLAGS -# -# - -librs: $(RSOBJ) - $(AR) r $(LIBRS) $(RSOBJ) - $(RANLIB) $(LIBRS) - -.cc.o: - $(CC) $(CFLAGS) -c $< - -clean: - -/bin/rm -f $(RSOBJ) $(EXECOBJ) $(TESTOBJ) *.gcno *.gcda \ - *.gcov *.tstout $(TESTS) - -clobber: clean retest - -/bin/rm $(EXEC) $(TESTS) - - -include $(RS_TOP_DIR)/tests/scripts/regress.mk - diff --git a/libretroshare/src/tests/serialiser/TestNotes.txt b/libretroshare/src/tests/serialiser/TestNotes.txt deleted file mode 100644 index 90c459120..000000000 --- a/libretroshare/src/tests/serialiser/TestNotes.txt +++ /dev/null @@ -1,56 +0,0 @@ - -Few test still need to be done. Needs to be automated - -used support(.h/.cc) file for testing RsItems - -Components and Tests. -============================================================ ------------------------------------------------------------- -Basic Items ------------------------------------------------------------- -rsbaseitems.cc : needed -rsbaseserial.cc : needed -rsconfigitems.cc : needed -rsserial.cc : needed - - - - ------------------------------------------------------------- -Compound TLV Components ------------------------------------------------------------- - -rstlvaddrs.cc : needed -rstlvbase.cc : not finished, tlvbase_test -rstlvfileitem.cc : tlvtypes_test -rstlvimage.cc : tlvtypes_test -rstlvkeys.cc : tlvtypes_test -rstlvkvwide.cc : rstlvwidetest -rstlvtypes.cc : tlvtypes_test -rstlvutil.cc : no need - ------------------------------------------------------------- -Service Components ------------------------------------------------------------- -rstunnelitems.cc : rstunnelitem_test & rsturtleitem_test -rsdistribitem.cc : distribitem_test -rsmsgitem.cc : msgitem_test -rsdiscitems.cc : needed -rsrankitems.cc : needed -rsblogitems.cc : distribitem_test -rschannelitems.cc : distribitem_test -rsforumitems.cc : distribitem_test -rsstatusitems.cc : needed -rsgameitems.cc : TBC -rsphotoitems.cc : TBC - -============================================================ -Test Specifics -============================================================ - ------------------------------------------------------------- -Basic Components ------------------------------------------------------------- - - - diff --git a/libretroshare/src/tests/serialiser/distribitem_test.cc b/libretroshare/src/tests/serialiser/distribitem_test.cc deleted file mode 100644 index 3cc551f0f..000000000 --- a/libretroshare/src/tests/serialiser/distribitem_test.cc +++ /dev/null @@ -1,365 +0,0 @@ -/* - * libretroshare/src/serialiser: distribitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include "util/rstime.h" -#include "serialiser/rsdistribitems.h" -#include "serialiser/rschannelitems.h" -#include "serialiser/rsforumitems.h" -#include "serialiser/rsblogitems.h" -#include "retroshare/rsdistrib.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" -#include "support.h" - -#include "distribitem_test.h" - -INITTEST() - -/** base rs distrib items **/ - - - - -RsSerialType* init_item(RsDistribGrp& grp) -{ - - rstime_t now = time(NULL); - - /* create Keys */ - - /* Create Group Description */ - - randString(SHORT_STR, grp.grpName); - randString(LARGE_STR, grp.grpDesc); - - grp.timestamp = now; - grp.grpFlags = (RS_DISTRIB_PRIVACY_MASK | RS_DISTRIB_AUTHEN_MASK); - grp.grpControlFlags = 0; - - init_item(grp.grpPixmap); - - /* set keys */ - - RsTlvSecurityKey publish_key; - - init_item(grp.adminKey); - init_item(publish_key); - init_item(grp.adminSignature); - - grp.publishKeys.keys[publish_key.keyId] = publish_key; - grp.publishKeys.groupId = grp.adminKey.keyId; - grp.grpId = grp.adminKey.keyId; - - init_item(grp.grpControlList); - - return new RsDistribSerialiser(); - -} - - -RsSerialType* init_item(RsDistribGrpKey& gk) -{ - - init_item(gk.key); - gk.grpId = gk.key.keyId; - - return new RsDistribSerialiser(); - -} - - -bool operator==(const RsDistribGrpKey& gk1, const RsDistribGrpKey& gk2) -{ - if(gk1.grpId != gk1.grpId) return false; - if(!(gk1.key == gk2.key)) return false; - - return true; -} - -RsSerialType* init_item(RsDistribSignedMsg& sMsg) -{ - - RsChannelMsg chMsg; - RsSerialType* ser = init_item(chMsg); - uint32_t chMsgSize = ser->size(&chMsg); - char* chMsgData = new char[chMsgSize]; - ser->serialise(&chMsg, chMsgData, &chMsgSize); - delete ser; - - sMsg.packet.setBinData(chMsgData, chMsgSize); - sMsg.flags = rand()%300; - randString(SHORT_STR, sMsg.grpId); - - return new RsDistribSerialiser(); -} - -bool operator==(const RsDistribSignedMsg& sMsg1,const RsDistribSignedMsg& sMsg2) -{ - - if(!(sMsg1.packet == sMsg2.packet)) return false; - if(sMsg1.grpId != sMsg2.grpId) return false; - if(sMsg1.flags != sMsg2.flags) return false; - - return true; -} - - -RsSerialType* init_item(RsChannelMsg& chMsg) -{ - randString(SHORT_STR, chMsg.grpId); - randString(LARGE_STR, chMsg.message); - randString(SHORT_STR, chMsg.subject); - randString(SHORT_STR, chMsg.threadId); - chMsg.timestamp = rand()%31452; - init_item(chMsg.thumbnail); - init_item(chMsg.attachment); - - return new RsChannelSerialiser(); -} - - -bool operator==(const RsChannelMsg& chMsg1,const RsChannelMsg& chMsg2) -{ - - if(chMsg1.grpId != chMsg2.grpId) return false; - if(chMsg1.message != chMsg2.message) return false; - if(!(chMsg1.attachment == chMsg2.attachment)) return false; - if(chMsg1.subject != chMsg2.subject) return false; - if(chMsg2.threadId != chMsg2.threadId) return false; - if(chMsg1.timestamp != chMsg2.timestamp) return false; - if(!(chMsg1.thumbnail.binData == chMsg2.thumbnail.binData)) return false; - if(chMsg1.thumbnail.image_type != chMsg2.thumbnail.image_type) return false; - - return true; -} - -RsSerialType* init_item(RsForumMsg& fMsg) -{ - - fMsg.timestamp = rand()%242; - randString(SHORT_STR, fMsg.grpId); - randString(LARGE_STR, fMsg.msg); - randString(SHORT_STR, fMsg.parentId); - randString(SHORT_STR, fMsg.srcId); - randString(SHORT_STR, fMsg.threadId); - randString(SHORT_STR, fMsg.title); - - return new RsForumSerialiser(); -} - - - -bool operator==(const RsForumMsg& fMsg1, const RsForumMsg& fMsg2) -{ - if(fMsg1.grpId != fMsg2.grpId) return false; - if(fMsg1.msg != fMsg2.msg) return false; - if(fMsg1.parentId != fMsg2.parentId) return false; - if(fMsg1.srcId != fMsg2.srcId) return false; - if(fMsg1.threadId != fMsg2.threadId) return false; - if(fMsg1.timestamp != fMsg2.timestamp) return false; - if(fMsg1.title != fMsg2.title) return false; - - return true; -} - -RsSerialType* init_item(RsBlogMsg& bMsg) -{ - bMsg.timestamp = rand()%223; - randString(SHORT_STR, bMsg.grpId); - randString(LARGE_STR, bMsg.message); - randString(SHORT_STR, bMsg.subject); - randString(SHORT_STR, bMsg.parentId); - randString(SHORT_STR, bMsg.threadId); - RsTlvImage image; - int nImages = rand()%5; - - for(int i=0; i < nImages; i++) - { - init_item(image); - bMsg.graphic_set.push_back(image); - } - - return new RsBlogSerialiser(); -} - - -bool operator==(const RsDistribGrp& g1, const RsDistribGrp& g2) -{ - - if(g1.grpCategory != g2.grpCategory) return false; - if(g1.grpControlFlags != g2.grpControlFlags) return false; - if(!(g1.grpControlList == g2.grpControlList)) return false; - if(g1.grpDesc != g2.grpDesc) return false; - if(g1.grpFlags != g2.grpFlags) return false; - if(g1.grpId != g2.grpId) return false; - if(g1.grpName != g2.grpName) return false; - if(g1.timestamp != g2.timestamp) return false; - - // admin key - - if(!(g1.adminKey == g2.adminKey)) return false; - if(!(g1.adminSignature == g2.adminSignature)) return false; - if(g1.grpPixmap.image_type != g2.grpPixmap.image_type) return false; - if(!(g1.grpPixmap.binData == g2.grpPixmap.binData)) return false; - - return true; -} - - - -RsSerialType* init_item(RsForumReadStatus& fRdStatus) -{ - randString(SHORT_STR, fRdStatus.forumId); - fRdStatus.save_type = rand()%42; - - std::map::iterator mit = fRdStatus.msgReadStatus.begin(); - - std::string id; - uint32_t status = 0; - - int numMaps = rand()%12; - - for(int i = 0; i < numMaps; i++) - { - randString(SHORT_STR, id); - status = rand()%23; - - fRdStatus.msgReadStatus.insert(std::pair(id, status)); - } - - return new RsForumSerialiser(); -} - -bool operator==(const RsForumReadStatus& frs1, const RsForumReadStatus& frs2) -{ - if(frs1.forumId != frs2.forumId) return false; - if(frs1.save_type != frs2.save_type) return false; - - if(frs1.msgReadStatus.size() != frs2.msgReadStatus.size()) return false; - - std::map::const_iterator mit - = frs1.msgReadStatus.begin(); - - - - for(;mit != frs1.msgReadStatus.end(); mit++) - { - if(mit->second != frs2.msgReadStatus.find(mit->first)->second) return false; - } - - return true; - -} - - - -RsSerialType* init_item(RsChannelReadStatus& fRdStatus) -{ - randString(SHORT_STR, fRdStatus.channelId); - fRdStatus.save_type = rand()%42; - - std::map::iterator mit = fRdStatus.msgReadStatus.begin(); - - std::string id; - uint32_t status = 0; - - int numMaps = rand()%12; - - for(int i = 0; i < numMaps; i++) - { - randString(SHORT_STR, id); - status = rand()%23; - - fRdStatus.msgReadStatus.insert(std::pair(id, status)); - } - - return new RsChannelSerialiser(); -} - -bool operator==(const RsChannelReadStatus& frs1, const RsChannelReadStatus& frs2) -{ - if(frs1.channelId != frs2.channelId) return false; - if(frs1.save_type != frs2.save_type) return false; - - if(frs1.msgReadStatus.size() != frs2.msgReadStatus.size()) return false; - - std::map::const_iterator mit - = frs1.msgReadStatus.begin(); - - - - for(;mit != frs1.msgReadStatus.end(); mit++) - { - if(mit->second != frs2.msgReadStatus.find(mit->first)->second) return false; - } - - return true; - -} - - -bool operator==(const RsBlogMsg& bMsg1,const RsBlogMsg& bMsg2) -{ - - if(bMsg1.timestamp != bMsg2.timestamp) return false; - if(bMsg1.grpId != bMsg2.grpId) return false; - if(bMsg1.message != bMsg2.message) return false; - if(bMsg1.subject != bMsg2.subject) return false; - if(bMsg1.threadId != bMsg2.threadId) return false; - if(bMsg1.parentId != bMsg2.parentId) return false; - - std::list::const_iterator it1 = bMsg1.graphic_set.begin(), - it2 = bMsg2.graphic_set.begin(); - - if(bMsg1.graphic_set.size() != bMsg2.graphic_set.size()) return false; - - for(; it1 != bMsg1.graphic_set.end() ; it1++, it2++) - { - if(!(*it1 == *it2)) return false; - } - - return true; -} - -int main(){ - - std::cerr << "RsDistribItem Tests" << std::endl; - - test_RsItem(); REPORT("Serialise/Deserialise RsDistribGrp"); - test_RsItem(); REPORT("Serialise/Deserialise RsDistribGrpKey"); - test_RsItem(); REPORT("Serialise/Deserialise RsDistribSignedMsg"); - test_RsItem(); REPORT("Serialise/Deserialise RsChannelMsg"); - test_RsItem(); REPORT("Serialise/Deserialise RsChannelReadStatus"); - test_RsItem(); REPORT("Serialise/Deserialise RsForumMsg"); - test_RsItem(); REPORT("Serialise/Deserialise RsForumReadStatus"); - test_RsItem(); REPORT("Serialise/Deserialise RsBlogMsg"); - - - FINALREPORT("RsDistribItem Tests"); - - return TESTRESULT(); -} - diff --git a/libretroshare/src/tests/serialiser/distribitem_test.h b/libretroshare/src/tests/serialiser/distribitem_test.h deleted file mode 100644 index 1eedfd643..000000000 --- a/libretroshare/src/tests/serialiser/distribitem_test.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef DISTRIBITEM_TEST_H_ -#define DISTRIBITEM_TEST_H_ - -/* - * libretroshare/src/serialiser: distribitem_test.h - * - * RetroShare Serialiser tests - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "serialiser/rsdistribitems.h" -#include "serialiser/rschannelitems.h" -#include "serialiser/rsforumitems.h" -#include "serialiser/rsblogitems.h" - - - -RsSerialType* init_item(RsDistribGrp&); -RsSerialType* init_item(RsDistribGrpKey&); -RsSerialType* init_item(RsDistribSignedMsg&); -RsSerialType* init_item(RsChannelMsg&); -RsSerialType* init_item(RsForumMsg&); -RsSerialType* init_item(RsForumReadStatus&); -RsSerialType* init_item(RsBlogMsg&); - -bool operator==(const RsDistribGrp& , const RsDistribGrp& ); -bool operator==(const RsDistribGrpKey& , const RsDistribGrpKey& ); -bool operator==(const RsDistribSignedMsg& , const RsDistribSignedMsg& ); -bool operator==(const RsChannelMsg& , const RsChannelMsg& ); -bool operator==(const RsForumMsg& , const RsForumMsg& ); -bool operator==(const RsForumReadStatus&, const RsForumReadStatus& ); -bool operator==(const RsBlogMsg& , const RsBlogMsg& ); - - - - -#endif /* DISTRIBITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/perform_auto_tests.sh b/libretroshare/src/tests/serialiser/perform_auto_tests.sh deleted file mode 100755 index e9857c4ec..000000000 --- a/libretroshare/src/tests/serialiser/perform_auto_tests.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -printresult() { - if test "$?" = "0"; then - echo ' 'PASSED - else - echo *FAILED* - fi -} - -# Warning: printresult needs to be called before anything else because it contains the -# result of the call to the test program, until the next command. - -exes="rsstatusitem_test \ - tlvbase_test \ - rsserial_test \ - tlvtypes_test \ - rsmsgitem_test \ - rstunnelitem_test \ - tlvrandom_test \ - rstlvwidetest \ - rsconfigitem_test \ - rsturtleitem_test \ - tlvitems_test \ - distribitem_test \ - tlvstack_test \ - tlvbase_test2" - -for exe in $exes; do - ./$exe > /dev/null 2>&1 ; result=`printresult`; echo "-- $exe \t test :" $result ; -done - - - diff --git a/libretroshare/src/tests/serialiser/rsbaseitem_test.cc b/libretroshare/src/tests/serialiser/rsbaseitem_test.cc deleted file mode 100644 index 4743e5248..000000000 --- a/libretroshare/src/tests/serialiser/rsbaseitem_test.cc +++ /dev/null @@ -1,191 +0,0 @@ - -/* - * libretroshare/src/serialiser: rsbaseitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - * tlvfileitem test. - * - * - */ - -#include -#include -#include "serialiser/rstlvtypes.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" - -INITTEST(); - -static int test_RsFileItem(); -static int test_RsFileData(); - -int main() -{ - std::cerr << "RsFile[Item/Data/...] Tests" << std::endl; - - test_RsFileItem(); - test_RsFileData(); - - FINALREPORT("RsTlvFile[Item/Data/...] Tests"); - - return TESTRESULT(); -} - -int test_RsTlvFileItem() -{ - - - - - RsTlvFileItem i1; - RsTlvFileItem i2; - - /* initialise */ - i1.filesize = 101010; - i1.hash = "ABCDEFEGHE"; - i1.name = "TestFile.txt"; - i1.pop = 12; - i1.age = 456; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - /* do it again without optional data */ - i1.filesize = 123; - i1.name = ""; - i1.pop = 0; - i1.age = 0; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - /* one more time - long file name, some optional data */ - i1.filesize = 123; - i1.name = "A Very Long File name that should fit in easily ??? with som $&%&^%* strange char (**$^%#&^$#*^%(&^ in there too!!!! ~~~!!$#(^$)$)(&%^)&\" oiyu thend"; - i1.pop = 666; - i1.age = 0; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - REPORT("Serialise/Deserialise RsTlvFileItem"); - - return 1; -} - -int test_RsTlvFileSet() -{ - RsTlvFileSet s1; - RsTlvFileSet s2; - - int i = 0; - for(i = 0; i < 15; i++) - { - RsTlvFileItem fi; - fi.filesize = 16 + i * i; - fi.hash = "ABCDEF"; - std::ostringstream out; - out << "File" << i << "_inSet.txt"; - fi.name = out.str(); - if (i % 2 == 0) - { - fi.age = 10 * i; - } - else - { - fi.age = 0; - } - fi.pop = 0; - - s1.items.push_back(fi); - } - - CHECK(test_SerialiseTlvItem(std::cerr, &s1, &s2)); - - /* check the data is the same - TODO */ - - REPORT("Serialise/Deserialise RsTlvFileSet"); - - return 1; -} - - -int test_RsTlvFileData() -{ - RsTlvFileData d1; - RsTlvFileData d2; - - /* initialise */ - d1.file.filesize = 101010; - d1.file.hash = "ABCDEFEGHE"; - d1.file.name = ""; - d1.file.age = 0; - d1.file.pop = 0; - - char data[15]; - d1.binData.setBinData(data, 15); - - d1.file_offset = 222; - - CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2)); - - /* check the data is the same */ - CHECK(d1.file.filesize == d2.file.filesize); - CHECK(d1.file.hash == d2.file.hash); - CHECK(d1.file.name == d2.file.name); - CHECK(d1.file.path == d2.file.path); - CHECK(d1.file.pop == d2.file.pop); - CHECK(d1.file.age == d2.file.age); - - CHECK(d1.file_offset == d2.file_offset); - CHECK(d1.binData.bin_len == d2.binData.bin_len); - - REPORT("Serialise/Deserialise RsTlvFileData"); - - return 1; -} - - diff --git a/libretroshare/src/tests/serialiser/rsconfigitem_test.cc b/libretroshare/src/tests/serialiser/rsconfigitem_test.cc deleted file mode 100644 index 1ac41ae09..000000000 --- a/libretroshare/src/tests/serialiser/rsconfigitem_test.cc +++ /dev/null @@ -1,328 +0,0 @@ -/* - * libretroshare/src/tests/serialiser: rsconfigitemstest.cc - * - * RetroShare Serialiser tests. - * - * Copyright 2011 by Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "rsconfigitem_test.h" -#include "util/utest.h" -#include "support.h" - - - -INITTEST() - -RsSerialType* init_item(RsPeerNetItem& rpn) -{ - randString(SHORT_STR, rpn.dyndns); - randString(SHORT_STR, rpn.gpg_id); - randString(SHORT_STR, rpn.location); - randString(SHORT_STR, rpn.pid); - - rpn.lastContact = rand()%42424; - rpn.netMode = rand()%313190; - rpn.visState = rand()%63635; - - - inet_aton("10.0.0.111", &(rpn.currentlocaladdr.sin_addr)); - rpn.currentlocaladdr.sin_port = htons(1111); - - inet_aton("123.1.2.123", &(rpn.currentremoteaddr.sin_addr)); - rpn.currentremoteaddr.sin_port = htons(1234); - - RsTlvIpAddressInfo ipa1, ipa2; - - ipa1.addr = rpn.currentlocaladdr; - ipa1.seenTime = rand()%40149013; - ipa1.source = rand()%13423; - - ipa2.addr = rpn.currentremoteaddr; - ipa2.seenTime = rand()%40139013; - ipa2.source = rand()%1343443; - - rpn.extAddrList.addrs.push_back(ipa1); - rpn.extAddrList.addrs.push_back(ipa2); - - rpn.localAddrList.addrs.push_back(ipa1); - rpn.localAddrList.addrs.push_back(ipa2); - - - return new RsPeerConfigSerialiser(); -} - -RsSerialType* init_item(RsPeerOldNetItem& rpon) -{ - return new RsPeerConfigSerialiser(); -} - -RsSerialType* init_item(RsPeerGroupItem& rpgi){ - - rpgi.flag = rand()%134344; - randString(SHORT_STR, rpgi.id); - randString(SHORT_STR, rpgi.name); - std::string p1, p2, p3; - randString(SHORT_STR, p1); - randString(SHORT_STR, p2); - randString(SHORT_STR, p3); - - rpgi.peerIds.push_back(p1); - rpgi.peerIds.push_back(p2); - rpgi.peerIds.push_back(p3); - - return new RsPeerConfigSerialiser(); -} - -RsSerialType* init_item(CompressedChunkMap& map) -{ - map._map.clear() ; - for(uint32_t i=0;i<15;++i) - map._map.push_back(rand()) ; - - return new RsTurtleSerialiser(); -} - -RsSerialType* init_item(RsPeerStunItem& rpsi) -{ - std::string p1, p2, p3; - randString(SHORT_STR, p1); - randString(SHORT_STR, p2); - randString(SHORT_STR, p3); - - rpsi.stunList.ids.push_back(p1); - rpsi.stunList.ids.push_back(p2); - rpsi.stunList.ids.push_back(p3); - - rpsi.stunList.mType = TLV_TYPE_PEERSET; - - return new RsPeerConfigSerialiser(); -} -RsSerialType* init_item(RsCacheConfig& rcc) -{ - - rcc.cachesubid = rand()%2342; - rcc.cachetypeid = rand()%323; - rcc.recvd = rand()%2252243; - rcc.size = rand()%02203; - randString(SHORT_STR, rcc.hash); - randString(SHORT_STR, rcc.name); - randString(SHORT_STR, rcc.path); - randString(SHORT_STR, rcc.pid); - - return new RsCacheConfigSerialiser(); -} - -RsSerialType* init_item(RsFileTransfer& rft) -{ - - std::string p1, p2, p3; - randString(SHORT_STR, p1); - randString(SHORT_STR, p2); - randString(SHORT_STR, p3); - - rft.allPeerIds.ids.push_back(p1); - rft.allPeerIds.ids.push_back(p2); - rft.allPeerIds.ids.push_back(p3); - rft.allPeerIds.mType = TLV_TYPE_PEERSET; - -// -// rft.compressed_chunk_map._map.clear(); -// const int mapSize = 15; -// rft.compressed_chunk_map._map.resize(mapSize); -// for(int i=0; i& left, - const std::list& right) -{ - std::list::const_iterator cit1 = left.begin(), - cit2 = right.begin(); - - for(; cit1 != left.end() ; cit1++, cit2++){ - - if(*cit1 != *cit2) - return false; - } - - return true; -} - -bool operator!=(const sockaddr_in& left, const sockaddr_in& right) -{ - if(left.sin_addr.s_addr != right.sin_addr.s_addr) return true; - if(left.sin_port != right.sin_port) return true; - - return false; -} - -bool operator!=(const RsTlvIpAddressInfo& left, const RsTlvIpAddressInfo& right) -{ - - if(left.addr != right.addr) return true; - if(left.seenTime != right.seenTime) return true; - if(left.source != right.source) return true; - - return false; -} - - -bool operator==(const RsPeerOldNetItem& left, const RsPeerOldNetItem& right) -{ - return false; -} - -bool operator==(const RsPeerGroupItem& left, const RsPeerGroupItem& right) -{ - if(left.flag != right.flag) return false; - if(left.id != right.id) return false; - if(left.name != right.name) return false; - if(left.peerIds != right.peerIds) return false; - - return true; -} - -bool operator!=(const std::list& left, - const std::list& right) -{ - std::list::const_iterator cit1 = left.begin(), - cit2 = right.begin(); - - for(; cit1 != left.end(); cit1++, cit2++){ - - if(*cit1 != *cit2) - return true; - } - - return false; -} - -bool operator==(const RsPeerStunItem& left, const RsPeerStunItem& right) -{ - if(!(left.stunList == right.stunList)) return false; - - return true; -} - -//bool operator==(const RsTlvPeerIdSet& left, const RsTlvPeerIdSet& right) -//{ -// if(left.mType != right.mType) return false; -// -// std::list::iterator cit1 = left.ids.begin(), -// cit2 = right.ids.begin(); -// -// for(; cit1 != left.ids.end(); cit1++, cit2++){ -// -// if(*cit1 != *cit2) -// return false; -// } -// -// return true; -//} - -bool operator==(const RsCacheConfig& left, const RsCacheConfig& right) -{ - - if(left.cachesubid != right.cachesubid) return false; - if(left.cachetypeid != right.cachetypeid) return false; - if(left.hash != right.hash) return false; - if(left.path != right.path) return false; - if(left.pid != right.pid) return false; - if(left.recvd != right.recvd) return false; - if(left.size != right.size) return false; - - return true; -} - -bool operator==(const RsFileTransfer& left, const RsFileTransfer& right) -{ - - if(!(left.allPeerIds == right.allPeerIds)) return false; - if(left.cPeerId != right.cPeerId) return false; - if(left.chunk_strategy != right.chunk_strategy) return false; - if(left.compressed_chunk_map._map != right.compressed_chunk_map._map) return false; - if(left.crate != right.crate) return false; - if(!(left.file == right.file)) return false; - if(left.flags != right.flags) return false; - if(left.in != right.in) return false; - if(left.lrate != right.lrate) return false; - if(left.ltransfer != right.ltransfer) return false; - if(left.state != right.state) return false; - if(left.transferred != right.transferred) return false; - if(left.trate != right.trate) return false; - - return true; -} - - - -int main() -{ - - std::cerr << "RsConfigItems Tests" << std::endl; - - test_RsItem(); REPORT("Serialise/Deserialise RsPeerNetItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsPeerGroupItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsPeerStunItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsCacheConfig"); - test_RsItem(); REPORT("Serialise/Deserialise RsFileTransfer"); - - FINALREPORT("RsConfigItems Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/serialiser/rsconfigitem_test.h b/libretroshare/src/tests/serialiser/rsconfigitem_test.h deleted file mode 100644 index 2571d5c30..000000000 --- a/libretroshare/src/tests/serialiser/rsconfigitem_test.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * libretroshare/src/serialiser: rsconfigitem_test.h - * - * RetroShare Serialiser tests. - * - * Copyright 2011 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef RSCONFIGITEM_TEST_H_ -#define RSCONFIGITEM_TEST_H_ - -#include "serialiser/rsconfigitems.h" -#include "turtle/rsturtleitem.h" - -RsSerialType* init_item(CompressedChunkMap& map); -RsSerialType* init_item(RsPeerNetItem& ); -RsSerialType* init_item(RsPeerOldNetItem& ); -RsSerialType* init_item(RsPeerGroupItem& ); -RsSerialType* init_item(RsPeerStunItem& ); -RsSerialType* init_item(RsCacheConfig& ); -RsSerialType* init_item(RsFileTransfer& ); - -bool operator==(const RsPeerNetItem&, const RsPeerNetItem& ); -bool operator==(const RsPeerOldNetItem&, const RsPeerOldNetItem& ); -bool operator==(const RsPeerGroupItem&, const RsPeerGroupItem& ); -bool operator==(const RsPeerStunItem&, const RsPeerStunItem& ); -bool operator==(const RsCacheConfig&, const RsCacheConfig& ); -bool operator==(const RsFileTransfer&, const RsFileTransfer& ); - -bool operator==(const std::list&, - const std::list&); - -bool operator!=(const sockaddr_in&, const sockaddr_in&); -bool operator!=(const RsTlvIpAddressInfo&, const RsTlvIpAddressInfo& ); -bool operator!=(const std::list& left, - const std::list& right); -//bool operator==(const RsTlvPeerIdSet& left, const RsTlvPeerIdSet& right); -bool operator==(const RsTlvFileItem&, const RsTlvFileItem& ); - - - -#endif /* RSCONFIGITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rsgrouteritem_test.cc b/libretroshare/src/tests/serialiser/rsgrouteritem_test.cc deleted file mode 100644 index 737b5155f..000000000 --- a/libretroshare/src/tests/serialiser/rsgrouteritem_test.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* - * libretroshare/src/tests/serialiser: msgitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include -#include - -#include "util/rsrandom.h" -#include "grouter/grouteritems.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" -#include "support.h" -#include "rsmsgitem_test.h" - -INITTEST(); - -RsSerialType* init_item(RsGRouterGenericDataItem& cmi) -{ - cmi.data_size = lrand48()%1000 + 1000 ; - cmi.data_bytes = (uint8_t*)malloc(cmi.data_size) ; - RSRandom::random_bytes(cmi.data_bytes,cmi.data_size) ; - cmi.routing_id = RSRandom::random_u32() ; - - Sha1CheckSum cs ; - for(int i=0;i<5;++i) cs.fourbytes[i] = RSRandom::random_u32() ; - cmi.destination_key = cs ; - - return new RsGRouterSerialiser(); -} -RsSerialType* init_item(RsGRouterACKItem& cmi) -{ - cmi.mid = RSRandom::random_u32() ; - cmi.state = RSRandom::random_u32() ; - - return new RsGRouterSerialiser(); -} -RsSerialType* init_item(RsGRouterPublishKeyItem& cmi) -{ - cmi.diffusion_id = RSRandom::random_u32() ; - cmi.service_id = RSRandom::random_u32() ; - cmi.randomized_distance = RSRandom::random_f32() ; - - Sha1CheckSum cs ; - for(int i=0;i<5;++i) cs.fourbytes[i] = RSRandom::random_u32() ; - cmi.published_key = cs ; - cmi.description_string = "test key" ; - - return new RsGRouterSerialiser(); -} -RsSerialType* init_item(RsGRouterRoutingInfoItem& cmi) -{ - cmi.origin = SSLIdType::random() ; - cmi.received_time = RSRandom::random_u64() ; - cmi.status_flags = RSRandom::random_u32() ; - - cmi.data_item = new RsGRouterGenericDataItem ; - - uint32_t n = 10+(RSRandom::random_u32()%30) ; - - for(uint32_t i=0;i 0.001) return false; - if(cmiLeft.description_string != cmiRight.description_string) return false; - - return true ; -} -bool operator ==(const RsGRouterACKItem& cmiLeft,const RsGRouterACKItem& cmiRight) -{ - if(cmiLeft.mid != cmiRight.mid) return false; - if(cmiLeft.state != cmiRight.state) return false; - - return true; -} -bool operator ==(const RsGRouterMatrixCluesItem& cmiLeft,const RsGRouterMatrixCluesItem& cmiRight) -{ - if(!(cmiLeft.destination_key == cmiRight.destination_key)) return false; - if(cmiLeft.clues.size() != cmiRight.clues.size()) return false; - - std::list::const_iterator itl = cmiLeft.clues.begin() ; - std::list::const_iterator itr = cmiRight.clues.begin() ; - - while(itl != cmiLeft.clues.end()) - { - if( (*itl).friend_id != (*itr).friend_id) return false ; - if( (*itl).time_stamp != (*itr).time_stamp) return false ; - - ++itl ; - ++itr ; - } - - return true; -} -bool operator ==(const RsGRouterMatrixFriendListItem& cmiLeft,const RsGRouterMatrixFriendListItem& cmiRight) -{ - if(cmiLeft.reverse_friend_indices.size() != cmiRight.reverse_friend_indices.size()) return false; - - for(uint32_t i=0;i::const_iterator itl(cmiLeft.tried_friends.begin()) ; - std::list::const_iterator itr(cmiRight.tried_friends.begin()) ; - - while(itl != cmiLeft.tried_friends.end()) - { - if( (*itl).friend_id != (*itr).friend_id) return false ; - if( (*itl).time_stamp != (*itr).time_stamp) return false ; - - ++itl ; - ++itr ; - } - - if(!(*cmiLeft.data_item == *cmiRight.data_item)) return false ; - - return true; -} -int main() -{ - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterGenericDataItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterACKItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterPublishKeyItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterRoutingInfoItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterMatrixFriendListItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGRouterMatrixCluesItem"); - - std::cerr << std::endl; - - FINALREPORT("RsGRouter Tests"); - - return TESTRESULT(); -} - - - - - diff --git a/libretroshare/src/tests/serialiser/rsgrouteritem_test.h b/libretroshare/src/tests/serialiser/rsgrouteritem_test.h deleted file mode 100644 index 392792fa3..000000000 --- a/libretroshare/src/tests/serialiser/rsgrouteritem_test.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef MSGITEM_TEST_H_ -#define MSGITEM_TEST_H_ - -/* - * libretroshare/src/tests/serialiser: msgitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include -#include "serialiser/rsmsgitems.h" - - -RsSerialType* init_item(RsChatMsgItem& ); -RsSerialType* init_item(RsChatStatusItem& ); -RsSerialType* init_item(RsChatAvatarItem& ); -RsSerialType* init_item(RsMsgItem& ); -RsSerialType* init_item(RsMsgTagType& ); -RsSerialType* init_item(RsMsgTags& ); -RsSerialType* init_item(RsMsgSrcId& ); - -bool operator ==(const RsChatMsgItem& ,const RsChatMsgItem& ); -bool operator ==(const RsChatStatusItem& , const RsChatStatusItem& ); -bool operator ==(const RsChatAvatarItem&, const RsChatAvatarItem& ); -bool operator ==(const RsMsgTagType&, const RsMsgTagType& ); -bool operator ==(const RsMsgTags&, const RsMsgTags& ); -bool operator ==(const RsMsgItem&, const RsMsgItem& ); -bool operator ==(const RsMsgSrcId&, const RsMsgSrcId& ); - -#endif /* MSGITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.cc b/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.cc deleted file mode 100644 index aa858daf7..000000000 --- a/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * rsgxsupdateitem_test.cc - * - * Created on: 9 Dec 2013 - * Author: crispy - */ - -#include "support.h" -#include "rsgxsupdateitem_test.h" - -INITTEST(); - -RsSerialType* init_item(RsGxsGrpUpdateItem& i) -{ - i.clear(); - i.grpUpdateTS = rand()%2424; - randString(SHORT_STR, i.peerId); - return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsGxsMsgUpdateItem& i) -{ - i.clear(); - randString(SHORT_STR, i.peerId); - int numUpdates = rand()%123; - - std::string peer; - for(int j=0; j < numUpdates; j++) - { - randString(SHORT_STR, peer); - i.msgUpdateTS.insert(std::make_pair(peer, rand()%45)); - } - - return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsGxsServerGrpUpdateItem& i) -{ - i.clear(); - i.grpUpdateTS = rand()%2424; - - return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsGxsServerMsgUpdateItem& i) -{ - i.clear(); - randString(SHORT_STR, i.grpId); - i.msgUpdateTS = rand()%4252; - return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -bool operator ==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r) -{ - bool ok = l.grpUpdateTS == r.grpUpdateTS; - ok &= l.peerId == r.peerId; - - return ok; -} - -bool operator ==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r) -{ - bool ok = l.peerId == r.peerId; - - const std::map& lUp = l.msgUpdateTS, rUp = r.msgUpdateTS; - - ok &= lUp.size() == rUp.size(); - - std::map::const_iterator lit = lUp.begin(), rit; - - for(; lit != lUp.end(); lit++) - { - std::string key = lit->first; - if((rit = rUp.find(key)) != rUp.end()) - ok &= lit->second == rit->second; - else - return false; - } - - return ok; -} - -bool operator ==(const RsGxsServerGrpUpdateItem& l, - const RsGxsServerGrpUpdateItem& r) -{ - return l.grpUpdateTS == r.grpUpdateTS; -} - -bool operator ==(const RsGxsServerMsgUpdateItem& l, - const RsGxsServerMsgUpdateItem& r) -{ - bool ok = l.grpId == r.grpId; - ok &= l.msgUpdateTS == r.msgUpdateTS; - return ok; -} - - -int main() -{ - std::cerr << "RsGxsUpdateItem Tests" << std::endl; - - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsGrpUpdateItem"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsMsgUpdateItem"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerGrpUpdateItem"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerMsgUpdateItem"); - - FINALREPORT("RsGxsUpdateItem Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.h b/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.h deleted file mode 100644 index 57a686241..000000000 --- a/libretroshare/src/tests/serialiser/rsgxsupdateitem_test.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * rsgxsupdateitem_test.h - * - * Created on: 9 Dec 2013 - * Author: crispy - */ - -#ifndef RSGXSUPDATEITEM_TEST_H_ -#define RSGXSUPDATEITEM_TEST_H_ - -#include "serialiser/rsgxsupdateitems.h" -#include "support.h" - - -RsSerialType* init_item(RsGxsGrpUpdateItem& i); -RsSerialType* init_item(RsGxsMsgUpdateItem& i); -RsSerialType* init_item(RsGxsServerGrpUpdateItem& i); -RsSerialType* init_item(RsGxsServerMsgUpdateItem& i); - -bool operator==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r); -bool operator==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r); -bool operator==(const RsGxsServerGrpUpdateItem& l, const RsGxsServerGrpUpdateItem& r); -bool operator==(const RsGxsServerMsgUpdateItem& l, const RsGxsServerMsgUpdateItem& r); - -#endif /* RSGXSUPDATEITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rsmsgitem_test.cc b/libretroshare/src/tests/serialiser/rsmsgitem_test.cc deleted file mode 100644 index c964d97ba..000000000 --- a/libretroshare/src/tests/serialiser/rsmsgitem_test.cc +++ /dev/null @@ -1,366 +0,0 @@ -/* - * libretroshare/src/tests/serialiser: msgitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include - -#include "util/rsrandom.h" -#include "serialiser/rsmsgitems.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" -#include "support.h" -#include "rsmsgitem_test.h" - -INITTEST(); - -RsSerialType* init_item(RsChatMsgItem& cmi) -{ - cmi.chatFlags = rand()%34; - cmi.sendTime = rand()%422224; - randString(LARGE_STR, cmi.message); - - return new RsChatSerialiser(); -} -RsSerialType* init_item(RsChatLobbyListRequestItem& cmi) -{ - return new RsChatSerialiser(); -} -RsSerialType* init_item(RsChatLobbyListItem& cmi) -{ - int n = rand()%20 ; - - cmi.lobby_ids.resize(n) ; - cmi.lobby_names.resize(n) ; - cmi.lobby_topics.resize(n) ; - cmi.lobby_counts.resize(n) ; - - for(int i=0;i(&cmi)) ; - - cmi.msg_id = RSRandom::random_u64() ; - cmi.lobby_id = RSRandom::random_u64() ; - cmi.nick = "My nickname" ; - cmi.subpacket_id = rand()%256 ; - cmi.parent_msg_id = RSRandom::random_u64() ; - - return serial ; -} -RsSerialType *init_item(RsChatLobbyEventItem& cmi) -{ - cmi.event_type = rand()%256 ; - randString(20, cmi.string1); - - return new RsChatSerialiser(); -} - -RsSerialType* init_item(RsChatLobbyInviteItem& cmi) -{ - cmi.lobby_id = RSRandom::random_u64() ; - cmi.lobby_name = "Name of the lobby" ; - cmi.lobby_topic = "Topic of the lobby" ; - - return new RsChatSerialiser(); -} - -RsSerialType* init_item(RsPrivateChatMsgConfigItem& pcmi) -{ - randString(SHORT_STR, pcmi.configPeerId); - pcmi.chatFlags = rand()%34; - pcmi.configFlags = rand()%21; - pcmi.sendTime = rand()%422224; - randString(LARGE_STR, pcmi.message); - pcmi.recvTime = rand()%344443; - - return new RsChatSerialiser(); -} - -RsSerialType* init_item(RsChatStatusItem& csi) -{ - - randString(SHORT_STR, csi.status_string); - csi.flags = rand()%232; - - return new RsChatSerialiser(); - -} - -RsSerialType* init_item(RsChatAvatarItem& cai) -{ - std::string image_data; - randString(LARGE_STR, image_data); - cai.image_data = new unsigned char[image_data.size()]; - - memcpy(cai.image_data, image_data.c_str(), image_data.size()); - cai.image_size = image_data.size(); - - return new RsChatSerialiser(); -} - -RsSerialType* init_item(RsMsgItem& mi) -{ - init_item(mi.attachment); - init_item(mi.msgbcc); - init_item(mi.msgcc); - init_item(mi.msgto); - - randString(LARGE_STR, mi.message); - randString(SHORT_STR, mi.subject); - - mi.msgId = rand()%324232; - mi.recvTime = rand()%44252; - mi.sendTime = mi.recvTime; - mi.msgFlags = mi.recvTime; - - return new RsMsgSerialiser(true); -} - -RsSerialType* init_item(RsMsgTagType& mtt) -{ - mtt.rgb_color = rand()%5353; - mtt.tagId = rand()%24242; - randString(SHORT_STR, mtt.text); - - return new RsMsgSerialiser(); -} - - -RsSerialType* init_item(RsMsgTags& mt) -{ - mt.msgId = rand()%3334; - - int i; - for (i = 0; i < 10; i++) { - mt.tagIds.push_back(rand()%21341); - } - - return new RsMsgSerialiser(); -} - -RsSerialType* init_item(RsMsgSrcId& ms) -{ - ms.msgId = rand()%434; - randString(SHORT_STR, ms.srcId); - - return new RsMsgSerialiser(); -} - -RsSerialType* init_item(RsMsgParentId& ms) -{ - ms.msgId = rand()%354; - ms.msgParentId = rand()%476; - - return new RsMsgSerialiser(); -} - -bool operator ==(const RsChatLobbyListItem& cmiLeft,const RsChatLobbyListItem& cmiRight) -{ - if(cmiLeft.lobby_ids.size() != cmiRight.lobby_ids.size()) return false; - if(cmiLeft.lobby_names.size() != cmiRight.lobby_names.size()) return false; - if(cmiLeft.lobby_topics.size() != cmiRight.lobby_topics.size()) return false; - if(cmiLeft.lobby_counts.size() != cmiRight.lobby_counts.size()) return false; - - for(uint32_t i=0;i(); REPORT("Serialise/Deserialise RsChatMsgItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatLobbyMsgItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatLobbyInviteItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatLobbyEventItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatLobbyListRequestItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatLobbyListItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatStatusItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsChatAvatarItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsMsgItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsMsgTagType"); - test_RsItem(); REPORT("Serialise/Deserialise RsMsgTags"); - test_RsItem(); REPORT("Serialise/Deserialise RsMsgSrcId"); - test_RsItem(); REPORT("Serialise/Deserialise RsMsgParentId"); - - std::cerr << std::endl; - - FINALREPORT("RsMsgItem Tests"); - - return TESTRESULT(); -} - - - - - diff --git a/libretroshare/src/tests/serialiser/rsmsgitem_test.h b/libretroshare/src/tests/serialiser/rsmsgitem_test.h deleted file mode 100644 index 392792fa3..000000000 --- a/libretroshare/src/tests/serialiser/rsmsgitem_test.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef MSGITEM_TEST_H_ -#define MSGITEM_TEST_H_ - -/* - * libretroshare/src/tests/serialiser: msgitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include -#include "serialiser/rsmsgitems.h" - - -RsSerialType* init_item(RsChatMsgItem& ); -RsSerialType* init_item(RsChatStatusItem& ); -RsSerialType* init_item(RsChatAvatarItem& ); -RsSerialType* init_item(RsMsgItem& ); -RsSerialType* init_item(RsMsgTagType& ); -RsSerialType* init_item(RsMsgTags& ); -RsSerialType* init_item(RsMsgSrcId& ); - -bool operator ==(const RsChatMsgItem& ,const RsChatMsgItem& ); -bool operator ==(const RsChatStatusItem& , const RsChatStatusItem& ); -bool operator ==(const RsChatAvatarItem&, const RsChatAvatarItem& ); -bool operator ==(const RsMsgTagType&, const RsMsgTagType& ); -bool operator ==(const RsMsgTags&, const RsMsgTags& ); -bool operator ==(const RsMsgItem&, const RsMsgItem& ); -bool operator ==(const RsMsgSrcId&, const RsMsgSrcId& ); - -#endif /* MSGITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rsnxsitems_test.cc b/libretroshare/src/tests/serialiser/rsnxsitems_test.cc deleted file mode 100644 index b2dab65e9..000000000 --- a/libretroshare/src/tests/serialiser/rsnxsitems_test.cc +++ /dev/null @@ -1,187 +0,0 @@ - -#include "support.h" - -#include "rsnxsitems_test.h" - -INITTEST(); - -#define NUM_BIN_OBJECTS 5 -#define NUM_SYNC_MSGS 8 -#define NUM_SYNC_GRPS 5 - -RsSerialType* init_item(RsNxsGrp& nxg) -{ - nxg.clear(); - - randString(SHORT_STR, nxg.grpId); - nxg.transactionNumber = rand()%23; - init_item(nxg.grp); - init_item(nxg.meta); - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - - -RsSerialType* init_item(RsNxsMsg& nxm) -{ - nxm.clear(); - - randString(SHORT_STR, nxm.msgId); - randString(SHORT_STR, nxm.grpId); - init_item(nxm.msg); - init_item(nxm.meta); - nxm.transactionNumber = rand()%23; - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsNxsSyncGrp& rsg) -{ - rsg.clear(); - rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH; - rsg.createdSince = rand()%2423; - randString(3124,rsg.syncHash); - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsNxsSyncMsg& rsgm) -{ - rsgm.clear(); - - rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH; - rsgm.createdSince = rand()%24232; - rsgm.transactionNumber = rand()%23; - randString(SHORT_STR, rsgm.grpId); - randString(SHORT_STR, rsgm.syncHash); - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsNxsSyncGrpItem& rsgl) -{ - rsgl.clear(); - - rsgl.flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - rsgl.transactionNumber = rand()%23; - rsgl.publishTs = rand()%23; - randString(SHORT_STR, rsgl.grpId); - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsNxsSyncMsgItem& rsgml) -{ - rsgml.clear(); - - rsgml.flag = RsNxsSyncGrpItem::FLAG_RESPONSE; - rsgml.transactionNumber = rand()%23; - randString(SHORT_STR, rsgml.grpId); - randString(SHORT_STR, rsgml.msgId); - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -RsSerialType* init_item(RsNxsTransac& rstx){ - - rstx.clear(); - - rstx.timestamp = rand()%14141; - rstx.transactFlag = rand()%2424; - rstx.nItems = rand()%33132; - rstx.transactionNumber = rand()%242112; - - return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); -} - -bool operator==(const RsNxsGrp& l, const RsNxsGrp& r){ - - if(l.grpId != r.grpId) return false; - if(!(l.grp == r.grp) ) return false; - if(!(l.meta == r.meta) ) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsMsg& l, const RsNxsMsg& r){ - - if(l.msgId != r.msgId) return false; - if(l.grpId != r.grpId) return false; - if(! (l.msg == r.msg) ) return false; - if(! (l.meta == r.meta) ) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r) -{ - - if(l.syncHash != r.syncHash) return false; - if(l.flag != r.flag) return false; - if(l.createdSince != r.createdSince) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsSyncMsg& l, const RsNxsSyncMsg& r) -{ - - if(l.flag != r.flag) return false; - if(l.createdSince != r.createdSince) return false; - if(l.syncHash != r.syncHash) return false; - if(l.grpId != r.grpId) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsSyncGrpItem& l, const RsNxsSyncGrpItem& r) -{ - if(l.flag != r.flag) return false; - if(l.publishTs != r.publishTs) return false; - if(l.grpId != r.grpId) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsSyncMsgItem& l, const RsNxsSyncMsgItem& r) -{ - if(l.flag != r.flag) return false; - if(l.grpId != r.grpId) return false; - if(l.msgId != r.msgId) return false; - if(l.transactionNumber != r.transactionNumber) return false; - - return true; -} - -bool operator==(const RsNxsTransac& l, const RsNxsTransac& r){ - - if(l.transactFlag != r.transactFlag) return false; - if(l.transactionNumber != r.transactionNumber) return false; - if(l.timestamp != r.timestamp) return false; - if(l.nItems != r.nItems) return false; - - - return true; -} - -int main() -{ - std::cerr << "RsNxsItem Tests" << std::endl; - - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGrpResp"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGrpMsgResp"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsNxsSyncGrp"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsNxsSyncMsg"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsNxsSyncGrpItem"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsNxsSyncMsgItem"); - test_RsItem(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsNxsTransac"); - - FINALREPORT("RsNxsItem Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/serialiser/rsnxsitems_test.h b/libretroshare/src/tests/serialiser/rsnxsitems_test.h deleted file mode 100644 index 31dae24b7..000000000 --- a/libretroshare/src/tests/serialiser/rsnxsitems_test.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef RSNXSITEMS_TEST_H -#define RSNXSITEMS_TEST_H - -#include "serialiser/rsnxsitems.h" - - -RsSerialType* init_item(RsNxsGrp&); -RsSerialType* init_item(RsNxsMsg&); -RsSerialType* init_item(RsNxsSyncGrp&); -RsSerialType* init_item(RsNxsSyncMsg&); -RsSerialType* init_item(RsNxsSyncGrpItem&); -RsSerialType* init_item(RsNxsSyncMsgItem&); -RsSerialType* init_item(RsNxsTransac& ); - -bool operator==(const RsNxsGrp&, const RsNxsGrp&); -bool operator==(const RsNxsMsg&, const RsNxsMsg&); -bool operator==(const RsNxsSyncGrp&, const RsNxsSyncGrp&); -bool operator==(const RsNxsSyncMsg&, const RsNxsSyncMsg&); -bool operator==(const RsNxsSyncGrpItem&, const RsNxsSyncGrpItem&); -bool operator==(const RsNxsSyncMsgItem&, const RsNxsSyncMsgItem&); -bool operator==(const RsNxsTransac&, const RsNxsTransac& ); - - -#endif // RSNXSITEMS_TEST_H diff --git a/libretroshare/src/tests/serialiser/rsphotoitem_test.cc b/libretroshare/src/tests/serialiser/rsphotoitem_test.cc deleted file mode 100644 index fafd1650d..000000000 --- a/libretroshare/src/tests/serialiser/rsphotoitem_test.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* - * libretroshare/src/test rsphotoitem_test.cc - * - * Test for photo item serialisation - * - * Copyright 2012-2012 by Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include "rsphotoitem_test.h" - - -RsSerialType* init_item(RsGxsPhotoAlbumItem &album) -{ - RsPhotoAlbum& a = album.album; - - randString(SHORT_STR, a.mCaption); - randString(SHORT_STR, a.mCategory); - randString(SHORT_STR, a.mDescription); - randString(SHORT_STR, a.mHashTags); - randString(SHORT_STR, a.mOther); - randString(SHORT_STR, a.mPhotoPath); - randString(SHORT_STR, a.mPhotographer); - randString(SHORT_STR, a.mWhen); - randString(SHORT_STR, a.mWhere); - randString(SHORT_STR, a.mThumbnail.type); - std::string rStr; - randString(SHORT_STR, rStr); - - a.mThumbnail.data = new uint8_t[SHORT_STR]; - memcpy(a.mThumbnail.data, rStr.data(), SHORT_STR); - a.mThumbnail.size = SHORT_STR; - - return new RsGxsPhotoSerialiser(); -} - -RsSerialType* init_item(RsGxsPhotoPhotoItem &photo) -{ - - RsPhotoPhoto& p = photo.photo; - - randString(SHORT_STR, p.mCaption); - randString(SHORT_STR, p.mCategory); - randString(SHORT_STR, p.mDescription); - randString(SHORT_STR, p.mHashTags); - randString(SHORT_STR, p.mOther); - randString(SHORT_STR, p.mPhotographer); - randString(SHORT_STR, p.mWhen); - randString(SHORT_STR, p.mWhere); - randString(SHORT_STR, p.mThumbnail.type); - std::string rStr; - randString(SHORT_STR, rStr); - - p.mThumbnail.data = new uint8_t[SHORT_STR]; - memcpy(p.mThumbnail.data, rStr.data(), SHORT_STR); - p.mThumbnail.size = SHORT_STR; - - return new RsGxsPhotoSerialiser(); -} - - -bool operator == (RsGxsPhotoAlbumItem& l, RsGxsPhotoAlbumItem& r) -{ - RsPhotoAlbum& la = l.album; - RsPhotoAlbum& ra = r.album; - - if(la.mCaption != ra.mCaption) return false; - if(la.mCategory != ra.mCategory) return false; - if(la.mDescription != ra.mDescription) return false; - if(la.mHashTags != ra.mHashTags) return false; - if(la.mOther != ra.mOther) return false; - if(la.mPhotographer!= ra.mPhotographer) return false; - if(la.mPhotoPath != ra.mPhotoPath) return false; - if(la.mWhere != ra.mWhere) return false; - if(la.mWhen != ra.mWhen) return false; - if(!(la.mThumbnail == ra.mThumbnail)) return false; - - return true; -} - - - -bool operator == (RsGxsPhotoPhotoItem& l, RsGxsPhotoPhotoItem& r) -{ - RsPhotoPhoto& la = l.photo; - RsPhotoPhoto& ra = r.photo; - - if(la.mCaption != ra.mCaption) return false; - if(la.mCategory != ra.mCategory) return false; - if(la.mDescription != ra.mDescription) return false; - if(la.mHashTags != ra.mHashTags) return false; - if(la.mOther != ra.mOther) return false; - if(la.mPhotographer!= ra.mPhotographer) return false; - if(la.mWhere != ra.mWhere) return false; - if(la.mWhen != ra.mWhen) return false; - if(!(la.mThumbnail == ra.mThumbnail)) return false; - - return true; -} - -bool operator == (RsPhotoThumbnail& l, RsPhotoThumbnail& r) -{ - if(l.size != r.size) return false; - if(l.type != r.type) return false; - if(memcmp(l.data, r.data,l.size) != 0) return false; - - return true; -} - -INITTEST() - -int main() -{ - std::cerr << "RsPhotoItem Tests" << std::endl; - - test_RsItem(); REPORT("Serialise/Deserialise RsGxsPhotoAlbumItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsGxsPhotoPhotoItem"); - - FINALREPORT("RsPhotoItem Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/serialiser/rsphotoitem_test.h b/libretroshare/src/tests/serialiser/rsphotoitem_test.h deleted file mode 100644 index cd726198e..000000000 --- a/libretroshare/src/tests/serialiser/rsphotoitem_test.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * libretroshare/src/test rsphotoitem_test.h - * - * Test for photo item serialisation - * - * Copyright 2012-2012 by Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef RSPHOTOITEM_TEST_H_ -#define RSPHOTOITEM_TEST_H_ - -#include "serialiser/rsphotov2items.h" -#include "support.h" - - - -RsSerialType* init_item(RsGxsPhotoAlbumItem& album); -RsSerialType* init_item(RsGxsPhotoPhotoItem& photo); - -bool operator == (RsGxsPhotoAlbumItem& l, RsGxsPhotoAlbumItem& r); -bool operator == (RsGxsPhotoPhotoItem& l, RsGxsPhotoPhotoItem& r); -bool operator == (RsPhotoThumbnail& l, RsPhotoThumbnail& r); - -#endif /* RSPHOTOITEM_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rsserial_test.cc b/libretroshare/src/tests/serialiser/rsserial_test.cc deleted file mode 100644 index e9193fee0..000000000 --- a/libretroshare/src/tests/serialiser/rsserial_test.cc +++ /dev/null @@ -1,136 +0,0 @@ - -/* - * libretroshare/src/serialiser: rsserial_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - * tlvfileitem test. - * - * - */ - -#include -#include -#include "serialiser/rsserial.h" -#include "serialiser/rsbaseitems.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" - -INITTEST(); - -static int test_RsFileItem(); -static int test_RsFileData(); - -int main() -{ - std::cerr << "RsFile[Item/Data/...] Tests" << std::endl; - - - test_RsFileItem(); - //test_RsFileData(); - - FINALREPORT("RsTlvFile[Item/Data/...] Tests"); - - return TESTRESULT(); -} - -int test_RsFileItem() -{ - /* make a serialisable FileItem */ - - RsSerialiser srl; - RsFileRequest rsfi; - - /* initialise */ - rsfi.file.filesize = 101010; - rsfi.file.hash = "ABCDEFEGHE"; - rsfi.file.name = "TestFile.txt"; - rsfi.file.pop = 12; - rsfi.file.age = 456; - - /* attempt to serialise it before we add it to the serialiser */ - - CHECK(0 == srl.size(&rsfi)); - -#define MAX_BUFSIZE 16000 - - char buffer[MAX_BUFSIZE]; - uint32_t sersize = MAX_BUFSIZE; - - CHECK(false == srl.serialise(&rsfi, (void *) buffer, &sersize)); - - - /* now add to serialiser */ - - RsFileItemSerialiser *rsfis = new RsFileItemSerialiser(); - srl.addSerialType(rsfis); - - uint32_t size = srl.size(&rsfi); - bool done = srl.serialise(&rsfi, (void *) buffer, &sersize); - - std::cerr << "test_RsFileItem() size: " << size << std::endl; - std::cerr << "test_RsFileItem() done: " << done << std::endl; - std::cerr << "test_RsFileItem() sersize: " << sersize << std::endl; - - std::cerr << "test_RsFileItem() serialised:" << std::endl; - displayRawPacket(std::cerr, (void *) buffer, sersize); - - CHECK(done == true); - - uint32_t sersize2 = sersize; - RsItem *output = srl.deserialise((void *) buffer, &sersize2); - - CHECK(output != NULL); - CHECK(sersize2 == sersize); - - RsFileRequest *outfi = dynamic_cast(output); - - CHECK(outfi != NULL); - - if (outfi) - { - /* check the data is the same */ - CHECK(rsfi.file.filesize == outfi->file.filesize); - CHECK(rsfi.file.hash == outfi->file.hash); - CHECK(rsfi.file.name == outfi->file.name); - CHECK(rsfi.file.path == outfi->file.path); - CHECK(rsfi.file.pop == outfi->file.pop); - CHECK(rsfi.file.age == outfi->file.age); - } - - sersize2 = MAX_BUFSIZE; - bool done2 = srl.serialise(outfi, (void *) &(buffer[16*8]), &sersize2); - - CHECK(sersize2 == sersize); - - displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2); - - - REPORT("Serialise/Deserialise RsFileRequest"); - - return 1; -} - - - diff --git a/libretroshare/src/tests/serialiser/rsstatusitem_test.cc b/libretroshare/src/tests/serialiser/rsstatusitem_test.cc deleted file mode 100644 index db6d5c181..000000000 --- a/libretroshare/src/tests/serialiser/rsstatusitem_test.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * libretroshare/src/tests/serialiser: rsstatusitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include "support.h" -#include "rsstatusitem_test.h" - -INITTEST(); - -RsSerialType* init_item(RsStatusItem& rsi) -{ - - rsi.sendTime = rand()%5353; - rsi.status = rand()%2032; - return new RsStatusSerialiser(); -} - -bool operator ==(RsStatusItem& rsi1, RsStatusItem& rsi2) -{ - // note: recv time is not serialised - - if(rsi1.sendTime != rsi2.sendTime) return false; - if(rsi1.status != rsi2.status) return false; - - return true; -} - - -int main() -{ - - std::cerr << "RsStatusItem Tests" << std::endl; - - test_RsItem(); REPORT("Serialise/Deserialise RsStatusItem"); - FINALREPORT("RsStatusItem Tests"); - - return TESTRESULT(); -} diff --git a/libretroshare/src/tests/serialiser/rsstatusitem_test.h b/libretroshare/src/tests/serialiser/rsstatusitem_test.h deleted file mode 100644 index cf25c5429..000000000 --- a/libretroshare/src/tests/serialiser/rsstatusitem_test.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef RSSTATUS_TEST_H_ -#define RSSTATUS_TEST_H_ - -/* - * libretroshare/src/tests/serialiser: rsstatusitem_test.h - * - * RetroShare Serialiser. - * - * Copyright 2010 by Christopher Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "serialiser/rsstatusitems.h" - -RsSerialType* init_item(RsStatusItem& ); - -bool operator ==(RsStatusItem& , RsStatusItem& ); - -#endif /* RSSTATUS_TEST_H_ */ diff --git a/libretroshare/src/tests/serialiser/rstlvutil.cc b/libretroshare/src/tests/serialiser/rstlvutil.cc deleted file mode 100644 index 51d1fe1c5..000000000 --- a/libretroshare/src/tests/serialiser/rstlvutil.cc +++ /dev/null @@ -1,187 +0,0 @@ - -/* - * libretroshare/src/serialiser: rstlvutil.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -/* some utility functions mainly for debugging - * - * - * - */ - -#include "serialiser/rstlvutil.h" - -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvitem.h" -#include "util/rsstring.h" -#include "util/utest.h" - -#include -#include - -#if 0 -/* print out a packet */ -#include -#include - - -#endif - -void displayRawPacket(std::ostream &out, void *data, uint32_t size) -{ - uint32_t i; - std::string sout; - rs_sprintf(sout, "DisplayRawPacket: Size: %ld", size); - - for(i = 0; i < size; i++) - { - if (i % 16 == 0) - { - sout += "\n"; - } - rs_sprintf_append(sout, "%02x:", (int) (((unsigned char *) data)[i])); - } - - out << sout << std::endl; -} - - -#define WHOLE_64K_SIZE 65536 - -int test_SerialiseTlvItem(std::ostream &str, RsTlvItem *in, RsTlvItem *out) -{ - uint16_t initsize = in->TlvSize(); - uint32_t serialOffset = 0; - uint32_t deserialOffset = 0; - - str << "test_SerialiseTlvItem() Testing ... Print/Serialise/Deserialise"; - str << std::endl; - - - /* some space to serialise into */ - unsigned char serbuffer[WHOLE_64K_SIZE]; - - CHECK(in->SetTlv(serbuffer, WHOLE_64K_SIZE, &serialOffset)); - - CHECK(serialOffset == initsize); /* check that the offset matches the size */ - CHECK(in->TlvSize() == initsize); /* check size hasn't changed */ - - REPORT("Serialise RsTlvItem"); - - /* now we try to read it back in! */ - CHECK(out->GetTlv(serbuffer, serialOffset, &deserialOffset)); - - /* again check sizes */ - CHECK(serialOffset == deserialOffset); - CHECK(deserialOffset == initsize); - CHECK(out->TlvSize() == initsize); - - str << "Class In/Serialised/Out!" << std::endl; - in->print(str, 0); - displayRawPacket(str, serbuffer, serialOffset); - out->print(str, 0); - - /* Can't check the actual data -> should add function */ - REPORT("DeSerialise RsTlvFileItem"); - - /* print it out */ - - - return 1; -} - -/* This function checks the TLV header, and steps on to the next one - */ - -bool test_StepThroughTlvStack(std::ostream &str, void *data, int size) -{ - uint32_t offset = 0; - uint32_t index = 0; - while (offset + 4 <= size) - { - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[offset]) ); - uint16_t tlvsize = GetTlvSize( &(((uint8_t *) data)[offset]) ); - str << "Tlv Entry[" << index << "] => Offset: " << offset; - str << " Type: " << tlvtype; - str << " Size: " << tlvsize; - str << std::endl; - - offset += tlvsize; - } - CHECK(offset == size); /* we match up exactly */ - - REPORT("Step Through RsTlvStack"); - return 1; -} - - -int test_CreateTlvStack(std::ostream &str, - std::vector items, void *data, uint32_t *totalsize) -{ - /* (1) select a random item - * (2) check size -> if okay serialise onto the end - * (3) loop!. - */ - uint32_t offset = 0; - uint32_t count = 0; - - while(1) - { - int idx = (int) (items.size() * (rand() / (RAND_MAX + 1.0))); - uint32_t tlvsize = items[idx] -> TlvSize(); - - if (offset + tlvsize > *totalsize) - { - *totalsize = offset; - return count; - } - - str << "Stack[" << count << "]"; - str << " Offset: " << offset; - str << " TlvSize: " << tlvsize; - str << std::endl; - - /* serialise it */ - items[idx] -> SetTlv(data, *totalsize, &offset); - items[idx] -> print(str, 10); - count++; - } - *totalsize = offset; - return 0; -} - -int test_TlvSet(std::vector items, int maxsize) -{ - int totalsize = maxsize; - void *data = malloc(totalsize); - uint32_t size = totalsize; - - test_CreateTlvStack(std::cerr, items, data, &size); - test_StepThroughTlvStack(std::cerr, data, size); - - return 1; -} - - diff --git a/libretroshare/src/tests/serialiser/rstlvutil.h b/libretroshare/src/tests/serialiser/rstlvutil.h deleted file mode 100644 index 910c494d3..000000000 --- a/libretroshare/src/tests/serialiser/rstlvutil.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef RS_TLV_UTIL_H -#define RS_TLV_UTIL_H - -/* - * libretroshare/src/serialiser: rstlvutil.h - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* some utility functions mainly for debugging - */ - -#include -#include -#include - -class RsTlvItem; - -/* print out a packet */ -void displayRawPacket(std::ostream &out, void *data, uint32_t size); -int test_SerialiseTlvItem(std::ostream &str, RsTlvItem *in, RsTlvItem *out); - - -bool test_StepThroughTlvStack(std::ostream &str, void *data, int size); -int test_CreateTlvStack(std::ostream &str, - std::vector items, void *data, int totalsize); -int test_TlvSet(std::vector items, int maxsize); - -#endif diff --git a/libretroshare/src/tests/serialiser/rstlvwidetest.cc b/libretroshare/src/tests/serialiser/rstlvwidetest.cc deleted file mode 100644 index 91f663387..000000000 --- a/libretroshare/src/tests/serialiser/rstlvwidetest.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - * libretroshare/src/serialiser: rstlvkvwidetest.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Chris Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include -#include -#include -#include "serialiser/rstlvkvwide.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" - - -INITTEST(); - - /* define utility functions to test out with */ - - //static int testRstlvWide(); -static int testRsTlvWideSet(); - -int main() -{ - std::cerr << "RsTlvWideTest[Item/Data/...] Tests" << std::endl; - - testRsTlvWideSet(); - - FINALREPORT("RsTlvWideTest[Item/Data/...] Tests"); - - return TESTRESULT(); -} - -int testRsTlvWideSet() -{ - RsTlvKeyValueWideSet i1, i2; // one to set and other to get - RsTlvKeyValueWide i_pair; // input pair - RsTlvFileItem hello; - - std::string randString("it should work now."); - int j, k; - - std::cerr << "entering loop now" << std::endl; - /* store a 15 random pairs */ - - for(int i = 0; i < 15 ; i++) - { - j = rand() % 4; - k = rand() % 4; - std::cerr << "j: " << j << " k: " << k << std::endl; - i_pair.wKey.assign(randString.begin(), randString.end()); - std::cerr << "loop count:" << i << std::endl; - i_pair.wValue.assign(randString.begin(), randString.end()); - std::cerr << "loop count:" << i << std::endl; - i1.wPairs.push_back(i_pair); - - i_pair.TlvClear(); - } - - std::cerr << "out of loop now" << std::endl; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /*check that the data is the same*/ - - REPORT("Serialize/Deserialize RsTlvKeyValueWideSet"); - - return 1; -} diff --git a/libretroshare/src/tests/serialiser/rstunnelitem_test.cc b/libretroshare/src/tests/serialiser/rstunnelitem_test.cc deleted file mode 100644 index 88de02517..000000000 --- a/libretroshare/src/tests/serialiser/rstunnelitem_test.cc +++ /dev/null @@ -1,108 +0,0 @@ - -/* - * libretroshare/src/serialiser: rstunnelitems_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 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 "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - */ - -#include -#include -#include -#include -#include "util/utest.h" -#include "support.h" - - - -RsTunnelSerialiser* init_item(RsTunnelDataItem& item) -{ - uint32_t S = rand()%20000 ; - item.encoded_data = malloc(S) ; - item.encoded_data_len = S ; - for(uint32_t i=0;i(); REPORT("Serialise/Deserialise RsTunnelDataItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsTunnelHandshakeItem"); - } - - FINALREPORT("RstunnelItem Tests"); - - return TESTRESULT(); -} - - diff --git a/libretroshare/src/tests/serialiser/rsturtleitem_test.cc b/libretroshare/src/tests/serialiser/rsturtleitem_test.cc deleted file mode 100644 index e7030818f..000000000 --- a/libretroshare/src/tests/serialiser/rsturtleitem_test.cc +++ /dev/null @@ -1,255 +0,0 @@ - -/* - * libretroshare/src/serialiser: rsturtleitems_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 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 "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - */ - -#include -#include -#include "turtle/rsturtleitem.h" -#include "ft/ftturtlefiletransferitem.h" -#include -#include "support.h" -#include "util/utest.h" - -INITTEST(); - -RsSerialType* init_item(CompressedChunkMap& map) -{ - map._map.clear() ; - for(uint32_t i=0;i<15;++i) - map._map.push_back(rand()) ; - - return new RsTurtleSerialiser(); -} -bool operator==(const CompressedChunkMap& m1,const CompressedChunkMap& m2) -{ - if(m1._map.size() != m2._map.size()) return false ; - - for(uint32_t i=0;i::const_iterator i1(it1.result.begin()) ; - std::list::const_iterator i2(it2.result.begin()) ; - - for(;i1!=it1.result.end() && i2!=it2.result.end();++i1,++i2) - if( !(*i1 == *i2)) - return false ; - - return true ; -} - -int main() -{ - std::cerr << "RsTurtleItem Tests" << std::endl; - - for(uint32_t i=0;i<20;++i) - { - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleFileMapRequestItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleFileMapItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleFileDataItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleFileRequestItem"); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleTunnelOkItem "); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleOpenTunnelItem "); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleSearchResultItem "); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleStringSearchRequestItem "); - test_RsItem(); REPORT("Serialise/Deserialise RsTurtleRegExpSearchRequestItem "); - } - - FINALREPORT("RsturtleItem Tests"); - - return TESTRESULT(); -} - - diff --git a/libretroshare/src/tests/serialiser/support.cc b/libretroshare/src/tests/serialiser/support.cc deleted file mode 100644 index 9fbda2e1f..000000000 --- a/libretroshare/src/tests/serialiser/support.cc +++ /dev/null @@ -1,294 +0,0 @@ -/* - * libretroshare/src/serialiser: t_support.h.cc - * - * RetroShare Serialiser tests. - * - * Copyright 2007-2008 by Christopher Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include - -#include "support.h" -#include "serialiser/rstlvbase.h" - -void randString(const uint32_t length, std::string& outStr) -{ - char alpha = 'a'; - char* stringData = NULL; - - stringData = new char[length]; - - for(uint32_t i=0; i != length; i++) - stringData[i] = alpha + (rand() % 26); - - outStr.assign(stringData, length); - delete[] stringData; - - return; -} - -void randString(const uint32_t length, std::wstring& outStr) -{ - wchar_t alpha = L'a'; - wchar_t* stringData = NULL; - - stringData = new wchar_t[length]; - - for(uint32_t i=0; i != length; i++) - stringData[i] = (alpha + (rand() % 26)); - - outStr.assign(stringData, length); - delete[] stringData; - - return; -} - -bool operator==(const RsTlvSecurityKey& sk1, const RsTlvSecurityKey& sk2) -{ - - if(sk1.startTS != sk2.startTS) return false; - if(sk1.endTS != sk2.endTS) return false; - if(sk1.keyFlags != sk2.keyFlags) return false; - if(sk1.keyId != sk2.keyId) return false; - if(!(sk1.keyData == sk1.keyData)) return false; - - return true; -} - -bool operator==(const RsTlvKeySignature& ks1, const RsTlvKeySignature& ks2) -{ - - if(ks1.keyId != ks2.keyId) return false; - if(!(ks1.signData == ks2.signData)) return false; - - return true; -} - -bool operator==(const RsTlvKeySignatureSet& kss1, const RsTlvKeySignatureSet& kss2) -{ - const std::map& set1 = kss1.keySignSet, - &set2 = kss2.keySignSet; - - if(set1.size() != set2.size()) return false; - - std::map::const_iterator it1 = set1.begin(), it2; - - for(; it1 != set1.end(); it1++) - { - SignType st1 = it1->first; - - if( (it2 =set2.find(st1)) == set2.end()) - return false; - - if(!(it1->second == it2->second)) - return false; - - } - - return true; -} - -bool operator==(const RsTlvPeerIdSet& pids1, const RsTlvPeerIdSet& pids2) -{ - std::list::const_iterator it1 = pids1.ids.begin(), - it2 = pids2.ids.begin(); - - - for(; ((it1 != pids1.ids.end()) && (it2 != pids2.ids.end())); it1++, it2++) - { - if(*it1 != *it2) return false; - } - - return true; - -} - - -void init_item(RsTlvImage& im) -{ - std::string imageData; - randString(LARGE_STR, imageData); - im.binData.setBinData(imageData.c_str(), imageData.size()); - im.image_type = RSTLV_IMAGE_TYPE_PNG; - - return; -} - -bool operator==(const RsTlvBinaryData& bd1, const RsTlvBinaryData& bd2) -{ - if(bd1.tlvtype != bd2.tlvtype) return false; - if(bd1.bin_len != bd2.bin_len) return false; - - unsigned char *bin1 = (unsigned char*)(bd1.bin_data), - *bin2 = (unsigned char*)(bd2.bin_data); - - for(uint32_t i=0; i < bd1.bin_len; bin1++, bin2++, i++) - { - if(*bin1 != *bin2) - return false; - } - - return true; -} - - -void init_item(RsTlvSecurityKey& sk) -{ - int randnum = rand()%313131; - - sk.endTS = randnum; - sk.keyFlags = randnum; - sk.startTS = randnum; - randString(SHORT_STR, sk.keyId); - - std::string randomStr; - randString(LARGE_STR, randomStr); - - sk.keyData.setBinData(randomStr.c_str(), randomStr.size()); - - return; -} - -void init_item(RsTlvKeySignature& ks) -{ - randString(SHORT_STR, ks.keyId); - - std::string signData; - randString(LARGE_STR, signData); - - ks.signData.setBinData(signData.c_str(), signData.size()); - - return; -} -void init_item(RsTlvKeySignatureSet &kss) -{ - int numSign = rand()%21; - - for(int i=0; i < numSign; i++) - { - RsTlvKeySignature sign; - SignType sType = rand()%2452; - init_item(sign); - kss.keySignSet.insert(std::make_pair(sType, sign)); - } -} - - -bool operator==(const RsTlvImage& img1, const RsTlvImage& img2) -{ - if(img1.image_type != img2.image_type) return false; - if(!(img1.binData == img2.binData)) return false; - - return true; - -} - -/** channels, forums and blogs **/ - -void init_item(RsTlvHashSet& hs) -{ - for(int i=0; i < 10; i++) - hs.ids.push_back(RsFileHash::random()); - - return; -} - -void init_item(RsTlvPeerIdSet& ps) -{ - for(int i=0; i < 10; i++) - ps.ids.push_back(RsPeerId::random()); - - return; -} - -bool operator==(const RsTlvHashSet& hs1,const RsTlvHashSet& hs2) -{ - std::list::const_iterator it1 = hs1.ids.begin(), - it2 = hs2.ids.begin(); - - for(; ((it1 != hs1.ids.end()) && (it2 != hs2.ids.end())); it1++, it2++) - { - if(*it1 != *it2) return false; - } - - return true; -} - -void init_item(RsTlvFileItem& fi) -{ - fi.age = rand()%200; - fi.filesize = rand()%34030313; - fi.hash = RsFileHash::random(); - randString(SHORT_STR, fi.name); - randString(SHORT_STR, fi.path); - fi.piecesize = rand()%232; - fi.pop = rand()%2354; - init_item(fi.hashset); - - return; -} - -void init_item(RsTlvBinaryData& bd){ - bd.TlvClear(); - std::string data; - randString(LARGE_STR, data); - bd.setBinData(data.data(), data.length()); -} - -void init_item(RsTlvFileSet& fSet){ - - randString(LARGE_STR, fSet.comment); - randString(SHORT_STR, fSet.title); - RsTlvFileItem fi1, fi2; - init_item(fi1); - init_item(fi2); - fSet.items.push_back(fi1); - fSet.items.push_back(fi2); - - return; -} - -bool operator==(const RsTlvFileSet& fs1,const RsTlvFileSet& fs2) -{ - if(fs1.comment != fs2.comment) return false; - if(fs1.title != fs2.title) return false; - - std::list::const_iterator it1 = fs1.items.begin(), - it2 = fs2.items.begin(); - - for(; ((it1 != fs1.items.end()) && (it2 != fs2.items.end())); it1++, it2++) - if(!(*it1 == *it2)) return false; - - return true; -} - -bool operator==(const RsTlvFileItem& fi1,const RsTlvFileItem& fi2) -{ - if(fi1.age != fi2.age) return false; - if(fi1.filesize != fi2.filesize) return false; - if(fi1.hash != fi2.hash) return false; - if(!(fi1.hashset == fi2.hashset)) return false; - if(fi1.name != fi2.name) return false; - if(fi1.path != fi2.path) return false; - if(fi1.piecesize != fi2.piecesize) return false; - if(fi1.pop != fi2.pop) return false; - - return true; -} diff --git a/libretroshare/src/tests/serialiser/support.h b/libretroshare/src/tests/serialiser/support.h deleted file mode 100644 index c9b5eea77..000000000 --- a/libretroshare/src/tests/serialiser/support.h +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef SUPPORT_H_ -#define SUPPORT_H_ - -/* - * libretroshare/src/tests/serialiser: - * - * RetroShare Serialiser tests. - * - * Copyright 2007-2008 by Christopher Evi-Parker, 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 "retroshare@lunamutt.com". - * - */ - -#include -#include -#include - -#include "util/utest.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvutil.h" -#include "serialiser/rstlvkeys.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvimage.h" - - - -/** - * This contains functions that may be useful for testing throughout the - * retroshare's serialiser - * package, if you find a function you keep using everywhere, might be a good idea to add it here - */ - - -#define SHORT_STR 100 -#define LARGE_STR 1000 - -void randString(const uint32_t, std::string&); -void randString(const uint32_t, std::wstring&); - - -/* for testing compound tlv items */ - -void init_item(RsTlvSecurityKey&); -void init_item(RsTlvKeySignature&); -void init_item(RsTlvKeySignatureSet&); -void init_item(RsTlvBinaryData&); -void init_item(RsTlvFileItem&); -void init_item(RsTlvFileSet&); -void init_item(RsTlvHashSet&); -void init_item(RsTlvPeerIdSet&); -void init_item(RsTlvImage&); -void init_item(RsTlvPeerIdSet&); - -bool operator==(const RsTlvSecurityKey&, const RsTlvSecurityKey& ); -bool operator==(const RsTlvKeySignature&, const RsTlvKeySignature& ); -bool operator==(const RsTlvBinaryData&, const RsTlvBinaryData&); -bool operator==(const RsTlvFileItem&, const RsTlvFileItem&); -bool operator==(const RsTlvFileSet&, const RsTlvFileSet& ); -bool operator==(const RsTlvHashSet&, const RsTlvHashSet&); -bool operator==(const RsTlvImage&, const RsTlvImage& ); -bool operator==(const RsTlvPeerIdSet& , const RsTlvPeerIdSet& ); -bool operator==(const RsTlvKeySignatureSet& , const RsTlvKeySignatureSet& ); - - - -/*! - * This templated test function which allows you to test - * retroshare serialiser items (except compound tlv items) - * you the function must implement a function - * - * 'RsSerialType* init_item(YourRsItem& rs_item)' - * which returns valid serialiser that - * can serialiser rs_item. You also need to implement an operator - * - * Also need to implement a function - * 'bool operator =(YourRsItem& rs_itemL, YourRsItem& rs_temR)' - * which allows this function to test for equality between both parameters. - * rs_temR is the result of deserialising the left operand (1st parameter). - * not YourRsItem in specifier in about functions should be a derived type from RsItem - * - * @param T the item you want to test - */ - -template int test_RsItem() -{ - /* make a serialisable RsTurtleItem */ - - RsSerialiser srl; - - /* initialise */ - T rsfi ; - RsSerialType *rsfis = init_item(rsfi) ; - - /* attempt to serialise it before we add it to the serialiser */ - - CHECK(0 == srl.size(&rsfi)); - - static const uint32_t MAX_BUFSIZE = 22000 ; - - char *buffer = new char[MAX_BUFSIZE]; - uint32_t sersize = MAX_BUFSIZE; - - CHECK(false == srl.serialise(&rsfi, (void *) buffer, &sersize)); - - /* now add to serialiser */ - - srl.addSerialType(rsfis); - - uint32_t size = srl.size(&rsfi); - bool done = srl.serialise(&rsfi, (void *) buffer, &sersize); - - std::cerr << "test_Item() size: " << size << std::endl; - std::cerr << "test_Item() done: " << done << std::endl; - std::cerr << "test_Item() sersize: " << sersize << std::endl; - - std::cerr << "test_Item() serialised:" << std::endl; - //displayRawPacket(std::cerr, (void *) buffer, sersize); - - CHECK(done == true); - - uint32_t sersize2 = sersize; - RsItem *output = srl.deserialise((void *) buffer, &sersize2); - - CHECK(output != NULL); - CHECK(sersize2 == sersize); - - T *outfi = dynamic_cast(output); - - CHECK(outfi != NULL); - - if(!(*outfi == rsfi)) - { - std::cerr << "Items differ: "<< std::endl; - outfi->print(std::cerr,0) ; - rsfi.print(std::cerr,0) ; - } - if (outfi) - CHECK(*outfi == rsfi) ; - - - sersize2 = MAX_BUFSIZE; - bool done2 = srl.serialise(outfi, (void *) &(buffer[16*8]), &sersize2); - - CHECK(done2) ; - CHECK(sersize2 == sersize); - -// displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2); - - delete[] buffer ; - //delete rsfis; - - return 1; -} - -template int test_RsItem(uint16_t servtype) -{ - /* make a serialisable RsTurtleItem */ - - RsSerialiser srl; - - /* initialise */ - T rsfi(servtype) ; - RsSerialType *rsfis = init_item(rsfi) ; // deleted on destruction of srl - - /* attempt to serialise it before we add it to the serialiser */ - - CHECK(0 == srl.size(&rsfi)); - - static const uint32_t MAX_BUFSIZE = 22000 ; - - char *buffer = new char[MAX_BUFSIZE]; - uint32_t sersize = MAX_BUFSIZE; - - CHECK(false == srl.serialise(&rsfi, (void *) buffer, &sersize)); - - /* now add to serialiser */ - - srl.addSerialType(rsfis); - - uint32_t size = srl.size(&rsfi); - bool done = srl.serialise(&rsfi, (void *) buffer, &sersize); - - std::cerr << "test_Item() size: " << size << std::endl; - std::cerr << "test_Item() done: " << done << std::endl; - std::cerr << "test_Item() sersize: " << sersize << std::endl; - - std::cerr << "test_Item() serialised:" << std::endl; - //displayRawPacket(std::cerr, (void *) buffer, sersize); - - CHECK(done == true); - - uint32_t sersize2 = sersize; - RsItem *output = srl.deserialise((void *) buffer, &sersize2); - - CHECK(output != NULL); - CHECK(sersize2 == sersize); - - T *outfi = dynamic_cast(output); - - CHECK(outfi != NULL); - - if (outfi) - CHECK(*outfi == rsfi) ; - - sersize2 = MAX_BUFSIZE; - bool done2 = srl.serialise(outfi, (void *) &(buffer[16*8]), &sersize2); - - CHECK(done2) ; - CHECK(sersize2 == sersize); - -// displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2); - - delete[] buffer ; - - return 1; -} -#endif /* SUPPORT_H_ */ diff --git a/libretroshare/src/tests/serialiser/tlvbase_test.cc b/libretroshare/src/tests/serialiser/tlvbase_test.cc deleted file mode 100644 index 1f0e92def..000000000 --- a/libretroshare/src/tests/serialiser/tlvbase_test.cc +++ /dev/null @@ -1,195 +0,0 @@ - -/* - * libretroshare/src/serialiser: tlvbase_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Horatio. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include -#include -#include - -#include "serialiser/rstlvbase.h" -#include "util/utest.h" -#include "util/rsnet.h" - -INITTEST(); - -static int test_RsTlvBase(); -int main() -{ - std::cerr << " RsTlvBase Tests" < -//#include "serialiser/rstlvtypes.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" -#include "util/rsnet.h" - -INITTEST(); - -static int test_RsTlvString(); -static int test_RsTlvUInt32(); -static int test_RsTlvIPAddr(); - -int main() -{ - std::cerr << "RsTlvBase Tests" << std::endl; - - test_RsTlvString(); - test_RsTlvUInt32(); - test_RsTlvIPAddr(); - - FINALREPORT("RsTlvBase Tests"); - - return TESTRESULT(); -} - -int test_RsTlvUInt32() -{ - return 1; -} - -int test_OneString(std::string input, uint16_t type); - -int test_RsTlvString() -{ - std::string nullString; - std::string oneString = "1"; - std::string shortString = "ab cd"; - std::string longString = "abcd efgh ijkl mnop qrst uvw"; - - std::cerr << "test_RsTlvString() Testing" << std::endl; - test_OneString(nullString, 1234); - test_OneString(oneString, 12); - test_OneString(shortString, 79); - test_OneString(longString, 7654); - - REPORT("Serialise RsTlvFileItem"); - - return 1; -} - - -int test_OneString(std::string input, uint16_t type) -{ - /* an array to work from */ - char tlvdata[2048]; - std::string OutString; - - std::cerr << "test_OneString() Testing ... Print/Serialise/Deserialise"; - std::cerr << std::endl; - /* start with SetTlvString() */ - - uint16_t initsize = GetTlvStringSize(input); - uint32_t outOffset = 0; - uint32_t inOffset = 0; - - std::cerr << "Serialising: " << input << std::endl; - CHECK(SetTlvString((void*)tlvdata, 2048, &outOffset, type, input)); - std::cerr << "Init Size: " << initsize << std::endl; - std::cerr << "Serialised Size: " << outOffset << std::endl; - displayRawPacket(std::cerr, tlvdata, outOffset); - - CHECK(outOffset == initsize); /* check that the offset matches the size */ - - std::cerr << "DeSerialising" << std::endl; - - /* fails if type is wrong! */ - CHECK(0 == GetTlvString((void*)tlvdata, outOffset, &inOffset, type-1, OutString)); - CHECK(GetTlvString((void*)tlvdata, outOffset, &inOffset, type, OutString)); - - CHECK(initsize == inOffset); /* check that the offset matches the size */ - CHECK(input == OutString); /* check that strings match */ - std::cerr << "Deserialised: Size: " << inOffset << std::endl; - std::cerr << "Deserialised: String: " << OutString << std::endl; - - REPORT("Serialise OneString"); - - return 1; -} - -int test_IpAddr(struct sockaddr_in *addr, uint16_t type); - -static int test_RsTlvIPAddr() -{ - struct sockaddr_in addr; - - inet_aton("10.0.0.111", &(addr.sin_addr)); - addr.sin_port = htons(1111); - - test_IpAddr(&addr, 1234); - - inet_aton("255.255.255.1", &(addr.sin_addr)); - addr.sin_port = htons(9999); - - test_IpAddr(&addr, 1234); - - inet_aton("128.255.255.1", &(addr.sin_addr)); - addr.sin_port = htons(1); - - test_IpAddr(&addr, 1234); - - return 1; -} - -int test_IpAddr(struct sockaddr_in *addr, uint16_t type) -{ - /* an array to work from */ - char tlvdata[2048]; - struct sockaddr_in outaddr; - - std::cerr << "test_IpAddr() Testing ... Print/Serialise/Deserialise"; - std::cerr << std::endl; - /* start with SetTlvString() */ - - uint16_t initsize = GetTlvIpAddrPortV4Size(); - uint32_t outOffset = 0; - uint32_t inOffset = 0; - - std::cerr << "Serialising IPAddr: " << inet_ntoa(addr->sin_addr) << std::endl; - std::cerr << " Port : " << ntohs(addr->sin_port) << std::endl; - - CHECK(SetTlvIpAddrPortV4((void*)tlvdata, 2048, &outOffset, type, addr)); - std::cerr << "Init Size: " << initsize << std::endl; - std::cerr << "Serialised Size: " << outOffset << std::endl; - displayRawPacket(std::cerr, tlvdata, outOffset); - - CHECK(outOffset == initsize); /* check that the offset matches the size */ - - std::cerr << "DeSerialising" << std::endl; - - /* fails if type is wrong! */ - CHECK(0 == GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type-1, &outaddr)); - CHECK(GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type, &outaddr)); - - CHECK(initsize == inOffset); /* check that the offset matches the size */ - CHECK(addr->sin_addr.s_addr == outaddr.sin_addr.s_addr); /* check that IP match */ - CHECK(addr->sin_port == outaddr.sin_port); /* check that Port match */ - std::cerr << "Deserialised: Size: " << inOffset << std::endl; - std::cerr << "Deserialised IPAddr: " << inet_ntoa(outaddr.sin_addr) << std::endl; - std::cerr << " Port : " << ntohs(outaddr.sin_port) << std::endl; - - REPORT("Serialise OneIP/Port"); - - return 1; -} - - - diff --git a/libretroshare/src/tests/serialiser/tlvitems_test.cc b/libretroshare/src/tests/serialiser/tlvitems_test.cc deleted file mode 100644 index 5d88338bb..000000000 --- a/libretroshare/src/tests/serialiser/tlvitems_test.cc +++ /dev/null @@ -1,89 +0,0 @@ - -/* - * libretroshare/src/serialiser: tlvitems_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - * tlvfileitem test. - * - * - */ - -#include -#include -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" - -INITTEST(); - -static int test_RsTlvBinData(); -static int test_RsTlvStepping(); - -int main() -{ - std::cerr << "RsTlvItems Tests" << std::endl; - - test_RsTlvBinData(); - - FINALREPORT("RsTlvItems Tests"); - - return TESTRESULT(); -} - -#define BIN_LEN 65536 /* bigger than 64k */ - -int test_RsTlvBinData() -{ - RsTlvBinaryData d1(1023); - RsTlvBinaryData d2(1023); - - char data[BIN_LEN] = {0}; - int i, j; - for(i = 0; i < BIN_LEN; i++) - { - data[i] = i%13; - } - - for(j = 1; j < BIN_LEN; j *= 2) - { - d1.setBinData(data, j); - CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2)); - - CHECK(d1.bin_len == d2.bin_len); - CHECK(0 == memcmp(d1.bin_data, d2.bin_data, d1.bin_len)); - } - - REPORT("Serialise/Deserialise RsTlvBinData"); - - return 1; -} - -int test_RsTlvStepping() -{ - - - return 1; -} - diff --git a/libretroshare/src/tests/serialiser/tlvkey_test.cc b/libretroshare/src/tests/serialiser/tlvkey_test.cc deleted file mode 100644 index 23c87a715..000000000 --- a/libretroshare/src/tests/serialiser/tlvkey_test.cc +++ /dev/null @@ -1,36 +0,0 @@ - - -#include "support.h" -#include "serialiser/rstlvkeys.h" - -INITTEST(); - -bool test_RsTlvKeySignatureSet(); - -int main() -{ - test_RsTlvKeySignatureSet(); REPORT("test_RsTlvKeySignatureSet()"); - - FINALREPORT("RsTlvKey Test"); -} - - - -bool test_RsTlvKeySignatureSet() -{ - RsTlvKeySignatureSet set; - - init_item(set); - - char data[set.TlvSize()]; - uint32_t offset = 0; - set.SetTlv(data, set.TlvSize(), &offset); - - RsTlvKeySignatureSet setConfirm; - - offset = 0; - setConfirm.GetTlv(data, set.TlvSize(), &offset); - - CHECK(setConfirm == set); - -} diff --git a/libretroshare/src/tests/serialiser/tlvrandom_test.cc b/libretroshare/src/tests/serialiser/tlvrandom_test.cc deleted file mode 100644 index bed1525f7..000000000 --- a/libretroshare/src/tests/serialiser/tlvrandom_test.cc +++ /dev/null @@ -1,194 +0,0 @@ - -/* - * libretroshare/src/serialiser: tlvrandom_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2009 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - * tlvrandom_test. - * - * This test is designed to attempt to break the TLV serialiser. - * - * To do this we throw random data at the serialisers and try to decode it. - * As the serialiser will only attempt to deserialise if the tlvtype matches - * we cheat a little, and make this match - to increase to actual deserialise - * attempts. - * - * This test runs for 30 seconds and attempts to do as - * many deserialisation as possible. - */ - -#include "util/rstime.h" -#include -#include -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvkeys.h" -#include "serialiser/rstlvutil.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvkeyvalue.h" -#include "serialiser/rstlvimage.h" - -#include "util/utest.h" - -INITTEST(); - -#define TEST_LENGTH 10 - -static int test_TlvRandom(void *data, uint32_t len, uint32_t offset); - -int main() -{ - std::cerr << "TlvRandom Tests" << std::endl; - - /* random data array to work through */ - uint32_t dsize = 10000000; - uint32_t i; - uint8_t *data = (uint8_t *) malloc(dsize); - - if (!data) - { - std::cerr << "Failed to allocate array"; - std::cerr << std::endl; - exit(1); - } - - rstime_t startTs = time(NULL); - rstime_t endTs = startTs + TEST_LENGTH; - - srand(startTs); - for(i = 0; i < dsize; i++) - { - data[i] = rand() % 256; - } - - std::cerr << "TlvRandom Tests: setup data." << std::endl; - - int count = 0; - for(i = 0; endTs > time(NULL); i += 2) - { - uint32_t len = dsize - i; - count += test_TlvRandom(&(data[i]), len, i); - - std::cerr << "Run: " << count << " tests"; - std::cerr << std::endl; - } - - FINALREPORT("RsTlvItems Tests"); - - return TESTRESULT(); -} - -#define BIN_LEN 523456 /* bigger than 64k */ - -bool test_TlvItem(RsTlvItem *item, void *data, uint32_t size, uint32_t offset); -bool test_SetTlvItem(RsTlvItem *item, uint16_t type, void *data, uint32_t size, uint32_t offset); - - -int test_TlvRandom(void *data, uint32_t len, uint32_t offset) -{ - uint32_t tmpoffset = 0; - - /* List of all the TLV types it could be! */ - RsTlvSecurityKey skey; - RsTlvSecurityKeySet skeyset; - RsTlvKeySignature keysign; - - RsTlvBinaryData bindata(TLV_TYPE_IMAGE); - - RsTlvFileItem fileitem; - RsTlvFileSet fileset; - RsTlvFileData filedata; - - RsTlvPeerIdSet peerset; - RsTlvServiceIdSet servset; - - RsTlvKeyValue kv; - RsTlvKeyValueSet kvset; - - RsTlvImage image; - - /* try to decode - with all types first */ - std::cerr << "test_TlvRandom:: Testing Files " << std::endl; - CHECK(test_TlvItem(&bindata, data, len, offset)); - CHECK(test_TlvItem(&fileitem, data, len, offset)); - CHECK(test_TlvItem(&fileset, data, len, offset)); - CHECK(test_TlvItem(&filedata, data, len, offset)); - std::cerr << "test_TlvRandom:: Testing Sets " << std::endl; - CHECK(test_TlvItem(&peerset, data, len, offset)); - CHECK(test_TlvItem(&servset, data, len, offset)); - CHECK(test_TlvItem(&kv, data, len, offset)); - CHECK(test_TlvItem(&kvset, data, len, offset)); - std::cerr << "test_TlvRandom:: Testing Keys " << std::endl; - CHECK(test_TlvItem(&skey, data, len, offset)); - CHECK(test_TlvItem(&skeyset, data, len, offset)); - CHECK(test_TlvItem(&keysign, data, len, offset)); - - /* now set the type correctly before decoding */ - std::cerr << "test_TlvRandom:: Testing Files (TYPESET)" << std::endl; - CHECK(test_SetTlvItem(&bindata, TLV_TYPE_IMAGE, data, len, offset)); - CHECK(test_SetTlvItem(&fileitem,TLV_TYPE_FILEITEM, data, len, offset)); - CHECK(test_SetTlvItem(&fileset, TLV_TYPE_FILESET, data, len, offset)); - CHECK(test_SetTlvItem(&filedata, TLV_TYPE_FILEDATA, data, len, offset)); - std::cerr << "test_TlvRandom:: Testing Sets (TYPESET)" << std::endl; - CHECK(test_SetTlvItem(&peerset, TLV_TYPE_PEERSET, data, len, offset)); - CHECK(test_SetTlvItem(&servset, TLV_TYPE_SERVICESET, data, len, offset)); - CHECK(test_SetTlvItem(&kv, TLV_TYPE_KEYVALUE, data, len, offset)); - CHECK(test_SetTlvItem(&kvset, TLV_TYPE_KEYVALUESET, data, len, offset)); - std::cerr << "test_TlvRandom:: Testing Keys (TYPESET)" << std::endl; - CHECK(test_SetTlvItem(&skey, TLV_TYPE_SECURITYKEY, data, len, offset)); - CHECK(test_SetTlvItem(&skeyset, TLV_TYPE_SECURITYKEYSET, data, len, offset)); - CHECK(test_SetTlvItem(&keysign, TLV_TYPE_KEYSIGNATURE, data, len, offset)); - - return 26; /* number of tests */ -} - -bool test_TlvItem(RsTlvItem *item, void *data, uint32_t size, uint32_t offset) -{ - uint32_t tmp_offset = offset; - if (item->GetTlv(data, size, &tmp_offset)) - { - std::cerr << "TLV decoded Random!"; - std::cerr << std::endl; - item->print(std::cerr, 20); - return false; - } - else - { - std::cerr << "TLV failed to decode"; - std::cerr << std::endl; - return true; - } -} - -bool test_SetTlvItem(RsTlvItem *item, uint16_t type, void *data, uint32_t size, uint32_t offset) -{ - /* set TLV type first! */ - void *typedata = (((uint8_t *) data) + offset); - SetTlvType(typedata, size - offset, type); - - return test_TlvItem(item, data, size, offset); -} - - diff --git a/libretroshare/src/tests/serialiser/tlvstack_test.cc b/libretroshare/src/tests/serialiser/tlvstack_test.cc deleted file mode 100644 index 36527ef8a..000000000 --- a/libretroshare/src/tests/serialiser/tlvstack_test.cc +++ /dev/null @@ -1,105 +0,0 @@ - -/* - * libretroshare/src/serialiser: tlvstack_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/****************************************************************** - * tlvfileitem test. - * - * - */ - -#include -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvutil.h" -#include "util/utest.h" - -INITTEST(); - -static int test_RsTlvStack(); - -int main() -{ - std::cerr << "RsTlvItem Stack Tests" << std::endl; - - test_RsTlvStack(); - - FINALREPORT("RsTlvItem Stack Tests"); - - return TESTRESULT(); -} - - -#define BIN_LEN 53 - -int test_RsTlvStack() -{ - - /* now create a set of TLV items for the random generator */ - - RsTlvBinaryData *bd1 = new RsTlvBinaryData(123); - RsTlvBinaryData *bd2 = new RsTlvBinaryData(125); - - char data[BIN_LEN] = {0}; - int i; - for(i = 0; i < BIN_LEN; i++) - { - data[i] = i%13; - } - - bd1->setBinData(data, 5); - bd2->setBinData(data, 21); - - RsTlvFileItem *fi1 = new RsTlvFileItem(); - RsTlvFileItem *fi2 = new RsTlvFileItem(); - - /* initialise */ - fi1->filesize = 101010; - fi1->hash = "ABCDEFEGHE"; - fi1->name = "TestFile.txt"; - fi1->pop = 12; - fi1->age = 456; - - fi2->filesize = 101010; - fi2->hash = "ABCDEFEGHE"; - fi2->name = "TestFile.txt"; - fi2->pop = 0; - fi2->age = 0;; - - std::vector items; - items.resize(4); - items[0] = bd1; - items[1] = bd2; - items[2] = fi1; - items[3] = fi2; - - test_TlvSet(items, 1024); - - REPORT("Serialise/Deserialise RsTlvBinData"); - - return 1; -} - - diff --git a/libretroshare/src/tests/serialiser/tlvtypes_test.cc b/libretroshare/src/tests/serialiser/tlvtypes_test.cc deleted file mode 100644 index e32dfe0fc..000000000 --- a/libretroshare/src/tests/serialiser/tlvtypes_test.cc +++ /dev/null @@ -1,386 +0,0 @@ -/* - * libretroshare/src/serialiser: tlvfileitem_test.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie, Chris Evi-Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include -#include -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvfileitem.h" -#include "serialiser/rstlvstring.h" -#include "serialiser/rstlvidset.h" -#include "serialiser/rstlvkeyvalue.h" -#include "serialiser/rstlvimage.h" -#include "serialiser/rstlvutil.h" -#include "serialiser/rstlvbase.h" -#include "util/utest.h" - -INITTEST(); - -#define RAND_SEED 1352534 - -static int test_RsTlvBinData(); -static int test_RsTlvFileItem(); -static int test_RsTlvFileSet(); -static int test_RsTlvFileData(); -static int test_RsTlvStringSet(); -static int test_RsTlvPeerIdSet(); -static int test_RsTlvServiceIdSet(); -static int test_RsTlvKeyValue(); -static int test_RsTlvKeyValueSet(); -static int test_RsTlvHashSet(); -static int test_RsTlvImage(); - - - -int main() -{ - std::cerr << "RsTlvTypes[Item/Data/...] Tests" << std::endl; - - srand(RAND_SEED); - - test_RsTlvFileItem(); - test_RsTlvFileData(); - test_RsTlvFileSet(); - test_RsTlvPeerIdSet(); - test_RsTlvServiceIdSet(); - test_RsTlvKeyValue(); - test_RsTlvKeyValueSet(); - test_RsTlvBinData(); - test_RsTlvImage(); - test_RsTlvHashSet(); - - FINALREPORT("RsTlvTypes[Item/Data/...] Tests"); - - return TESTRESULT(); -} - -int test_RsTlvFileItem() -{ - RsTlvFileItem i1; - RsTlvFileItem i2; - - /* initialise */ - i1.filesize = 101010; - i1.hash = "ABCDEFEGHE"; - i1.name = "TestFile.txt"; - i1.pop = 12; - i1.age = 456; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - /* do it again without optional data */ - i1.filesize = 123; - i1.name = ""; - i1.pop = 0; - i1.age = 0; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - /* one more time - long file name, some optional data */ - i1.filesize = 123; - i1.name = "A Very Long File name that should fit in easily ??? with som $&%&^%* strange char (**$^%#&^$#*^%(&^ in there too!!!! ~~~!!$#(^$)$)(&%^)&\" oiyu thend"; - i1.pop = 666; - i1.age = 0; - - CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2)); - - /* check the data is the same */ - CHECK(i1.filesize == i2.filesize); - CHECK(i1.hash == i2.hash); - CHECK(i1.name == i2.name); - CHECK(i1.path == i2.path); - CHECK(i1.pop == i2.pop); - CHECK(i1.age == i2.age); - - REPORT("Serialise/Deserialise RsTlvFileItem"); - - return 1; -} - -int test_RsTlvFileSet() -{ - RsTlvFileSet s1; - RsTlvFileSet s2; - - int i = 0; - for(i = 0; i < 15; i++) - { - RsTlvFileItem fi; - fi.filesize = 16 + i * i; - fi.hash = "ABCDEF"; - std::ostringstream out; - out << "File" << i << "_inSet.txt"; - fi.name = out.str(); - if (i % 2 == 0) - { - fi.age = 10 * i; - } - else - { - fi.age = 0; - } - fi.pop = 0; - - s1.items.push_back(fi); - } - - CHECK(test_SerialiseTlvItem(std::cerr, &s1, &s2)); - - /* check the data is the same - TODO */ - - REPORT("Serialise/Deserialise RsTlvFileSet"); - - return 1; -} - - -int test_RsTlvFileData() -{ - RsTlvFileData d1; - RsTlvFileData d2; - - /* initialise */ - d1.file.filesize = 101010; - d1.file.hash = "ABCDEFEGHE"; - d1.file.name = ""; - d1.file.age = 0; - d1.file.pop = 0; - - char data[15]; - d1.binData.setBinData(data, 15); - - d1.file_offset = 222; - - CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2)); - - /* check the data is the same */ - CHECK(d1.file.filesize == d2.file.filesize); - CHECK(d1.file.hash == d2.file.hash); - CHECK(d1.file.name == d2.file.name); - CHECK(d1.file.path == d2.file.path); - CHECK(d1.file.pop == d2.file.pop); - CHECK(d1.file.age == d2.file.age); - - CHECK(d1.file_offset == d2.file_offset); - CHECK(d1.binData.bin_len == d2.binData.bin_len); - - REPORT("Serialise/Deserialise RsTlvFileData"); - - return 1; -} - - -int test_RsTlvPeerIdSet() -{ - - RsTlvPeerIdSet i1, i2; // one to set and other to get - - RsPeerId testId; - - std::string randString[5]; - randString[0] = "e$424!�!�"; - randString[1] = "e~:@L{L{KHKG"; - randString[2] = "e{@O**/*/*"; - randString[3] = "e?<HG�!�%$"; - randString[4] = "e>HG�!�%$"; - randString[4] = "e>addFriend(fakePeer); -} - -ServiceTest::~ServiceTest() -{ - // release resources - delete mConnMgr; - delete mPersonGrp; - delete mPeers; -} - - - - - - diff --git a/libretroshare/src/tests/services/servicetest.h b/libretroshare/src/tests/services/servicetest.h deleted file mode 100644 index ca24e9f0e..000000000 --- a/libretroshare/src/tests/services/servicetest.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * libretroshare/src/tests/services Service_Test.h - * - * RetroShare Service Testing - * - * Copyright 2010 by Chris Evi-Parker. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#ifndef SERVICE_TEST_H_ -#define SERVICE_TEST_H_ - -#include "pqi/p3connmgr.h" -#include "rsserver/p3peers.h" -#include "dbase/cachestrapper.h" -#include "pqi/pqipersongrp.h" - - - - -/*! - * A convenience class from which tests derive from - * This enables user to test in shallow manner the public methods - * of a service - */ -class ServiceTest { - -public: - ServiceTest(); - virtual ~ServiceTest(); - - /*! - * all tests of service should be implemented here - */ - virtual void runTests() = 0; - - /*! - * use this to populate the service with messages - */ - void sendItem(RsItem* item); - -protected: - - - p3ConnectMgr* mConnMgr; - CacheStrapper *mCs; - CacheTransfer *mCt; - p3Peers* mPeers; - pqipersongrp* mPersonGrp; - - std::string fakePeer; // ssl id of fake receiving peer - -}; - - - -#endif /* SERVICE_TEST_H_ */ diff --git a/libretroshare/src/tests/tcponudp/bidir_tou.cc b/libretroshare/src/tests/tcponudp/bidir_tou.cc deleted file mode 100644 index 5075130d9..000000000 --- a/libretroshare/src/tests/tcponudp/bidir_tou.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* - * "$Id: pair_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include - -// for printing sockaddr -#include "udp/udpstack.h" - -#include "tcponudp/tou.h" -#include "tcponudp/udppeer.h" -#include "tcponudp/udprelay.h" - -#include "util/bdnet.h" - -#include "util/rsrandom.h" - -#include -#include -#include - - -/* - * This test creates the same stacks as are used in RS. - * This additionally tests the "checkFns" for the other UdpReceivers, which could potentially be modifying the data. - * obviously they shouldn't! - * - */ - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - int totalwbytes = 0; - int totalmbytes = 0; - int totalrbytes = 0; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - std::cerr << "Creating with Lossy Udp Layers for further testing"; - std::cerr << std::endl; - - UdpStack *udpStack1 = new UdpStack(UDP_TEST_LOSSY_LAYER,laddr); - UdpStack *udpStack2 = new UdpStack(UDP_TEST_LOSSY_LAYER,raddr); - - UdpSubReceiver *udpReceivers[4]; - int udpTypes[4]; - - // NOTE DHT is too hard to add at the moment. - - UdpRelayReceiver *mRelay1 = new UdpRelayReceiver(udpStack1); - udpReceivers[1] = mRelay1; - udpTypes[1] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack1->addReceiver(udpReceivers[1]); - - udpReceivers[0] = new UdpPeerReceiver(udpStack1); - udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack1->addReceiver(udpReceivers[0]); - - // STACK 2. - UdpRelayReceiver *mRelay2 = new UdpRelayReceiver(udpStack2); - udpReceivers[3] = mRelay2; - udpTypes[3] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack2->addReceiver(udpReceivers[3]); - - udpReceivers[2] = new UdpPeerReceiver(udpStack2); - udpTypes[2] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack2->addReceiver(udpReceivers[2]); - - tou_init((void **) udpReceivers, udpTypes, 4); - - - int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); - int sockfd2 = tou_socket(2, TOU_RECEIVER_TYPE_UDPPEER, 0); - if ((sockfd <= 0) || (sockfd2 <= 0)) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl; - return -1; - } - std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl; - - std::cerr << "Socket Non-Blocking" << std::endl; - - std::cerr << "Socket1 Bound to: " << laddr << std::endl; - std::cerr << "Socket2 Bound to: " << raddr << std::endl; - - int err = 0; - - // listening. - if (1) // socket2. - { - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ - err = tou_listenfor(sockfd2, - (struct sockaddr *) &laddr, sizeof(laddr)); - } - - - if (1) // only one program. - { - std::cerr << "Socket1 Connecting to: " << raddr << std::endl; - err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); - if (err < 0) - { - errno = tou_errno(sockfd); - if (errno != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - usleep(1000); - - - /* sock1 */ - if((!sock1Connected) && (0 == (err = tou_connected(sockfd)))) - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - - if ((!sock2Connected) && (0 > (nsock = tou_accept(sockfd2, - (struct sockaddr *) &inaddr, &addrlen)))) - { - errno = tou_errno(sockfd2); - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - sockfd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - -#define MAX_READ 20000 - - /* send data */ - int bufsize = MAX_READ; - char buffer[MAX_READ]; - char middata[MAX_READ]; - char data[MAX_READ]; - int readsize = 0; - int midsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - - rstime_t lastRead = time(NULL); - bool doneWrite = false; - bool doneRead = false; - bool blockread = false; - bool blockmid = false; - - while((!doneWrite) || (!doneRead)) - { - /* read -> write_socket... */ - usleep(10); - - if (blockread != true) - { - int readbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); - readsize = read(0, buffer, readbuf); - if (readsize) - { - //std::cerr << "read " << readsize << " / " << readbuf; - //std::cerr << std::endl; - } - } - if ((readsize == 0) && (!doneWrite)) - { - /* eof */ - doneWrite = true; - std::cerr << "Write Done Total: " << totalwbytes; - std::cerr << std::endl; - } - /* now we write */ - if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize))) - { - //std::cerr << "Blocked Write "; - //std::cerr << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; - blockread = true; - } - else - { - blockread = false; - totalwbytes += readsize; - - if (readsize) - { - std::cerr << "Written: " << readsize << ", Total: " << totalwbytes; - std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - } - } - - /*************** Here we read it in, and send it back out... - * so the data is flowing both ways through the UDP connection - * - *****/ - - - if (!blockmid) - { - /* read from socket 2, and write back to socket 2 */ - - int readmidbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); - if (0 < (midsize = tou_read(sockfd2, middata, readmidbuf))) - { - //std::cerr << "MidRead: " << mid << " Total: " << totalrbytes; - //std::cerr << " In Transit: " << totalwbytes - totalrbytes; - //std::cerr << std::endl; - } - } - - /* now we write */ - if ((midsize > 0) && (-1 == tou_write(sockfd2, middata, midsize))) - { - //std::cerr << "Blocked Write "; - //std::cerr << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; - blockmid = true; - } - else - { - blockmid = false; - - if (midsize > 0) - { - totalmbytes += midsize; - - std::cerr << "MidRead: " << midsize << ", Total: " << totalmbytes; - std::cerr << " => Transit => : " << totalwbytes - totalmbytes; - std::cerr << " <= Transit <= : " << totalmbytes - totalrbytes; - std::cerr << std::endl; - } - } - - /***** READ FROM FIRST SOCKET *****/ - - int ret = 0; - int readbuf2 = 1 + RSRandom::random_u32() % (MAX_READ - 1); - if (0 < (ret = tou_read(sockfd, data, readbuf2))) - { - //std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - totalrbytes += ret; - - std::cerr << "Read: " << ret << " Total: " << totalrbytes; - std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - - lastRead = time(NULL); - } - else if ((ret == 0) && (!doneRead)) - { - doneRead = true; - std::cerr << "Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - else - { - //std::cerr << "Blocked Read: " << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; -#define TIMEOUT 15 - if ((!doneRead) && (time(NULL) - lastRead > TIMEOUT)) - { - doneRead = true; - std::cerr << "TIMEOUT: Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - } - - - } - - /* this is blocking??? */ - tou_close(sockfd); - tou_close(sockfd2); - - std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; - std::cerr << std::endl; - return 1; -} - diff --git a/libretroshare/src/tests/tcponudp/bidir_tou.sh b/libretroshare/src/tests/tcponudp/bidir_tou.sh deleted file mode 100755 index 048dd67b4..000000000 --- a/libretroshare/src/tests/tcponudp/bidir_tou.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./bidir_tou -DATAFILE=../../lib/libretroshare.a - -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 - -$EXEC 127.0.0.1 4401 127.0.0.1 4032 < $DATAFILE > $TMPOUTPUT - -if diff -s $DATAFILE $TMPOUTPUT -then - echo "SUCCESS" -else - echo "FAILURE to accurately transfer DATA" -fi - -rm $TMPOUTPUT - diff --git a/libretroshare/src/tests/tcponudp/internal_tou.cc b/libretroshare/src/tests/tcponudp/internal_tou.cc deleted file mode 100644 index 353fecedc..000000000 --- a/libretroshare/src/tests/tcponudp/internal_tou.cc +++ /dev/null @@ -1,632 +0,0 @@ -/* - * "$Id: internal_tou.cc,v 1.2 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -/********************************************************** - * There appears (was) to be an elusive bug in the tou internals. - * most likely to be in the packing and unpacking of the - * data queues. - * - * This test is designed to load the queues up and then - * transfer the data, repeatly with different size packets. - * - * to do this effectively we need to access the TcpStream - * objects, instead of the tou.h interface. - * - */ - -#include - -// for printing sockaddr -#include "udplayer.h" -#include "tcpstream.h" - -#include "tou.h" -#include "tou_net.h" - -#include -#include -#include - - -/* This is a simple test to ensure that the tou behaviour - * is almost identical to a standard tcp socket. - * - * In this version we open 2 sockets, and attempt to - * communicate with ourselves.... - * - */ - -int setup_socket(struct sockaddr_in addr); -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2); -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size); - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - int i,j; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - // tounet_init(); - - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - unsigned short laddr_port = atoi(argv[optind+1]); - unsigned short raddr_port = atoi(argv[optind+3]); - - laddr.sin_port = htons(laddr_port); - raddr.sin_port = htons(raddr_port); - - /* so create the Udp/Tcp components */ - //UdpLayer udp1(laddr); - //UdpLayer udp2(raddr); - LossyUdpLayer udp1(laddr, 0.10); - LossyUdpLayer udp2(raddr, 0.10); - - /* check that they are okay */ - if ((!udp1.okay()) || (!udp2.okay())) - { - std::cerr << "Trouble opening udp ports!"; - std::cerr << std::endl; - return 1; - } - - TcpStream tcp1(&udp1); - TcpStream tcp2(&udp2); - - udp1.setRemoteAddr(raddr); - udp2.setRemoteAddr(laddr); - tcp1.connect(); // start the connection. - - /* now connect them */ - while ((!tcp1.isConnected()) || (!tcp2.isConnected())) - { - usleep(10000); /* 10 ms */ - tcp1.tick(); - tcp2.tick(); - } - - std::cerr << "Connection Established!" << std::endl; - - for(i = 0; i < 10; i++) - { - - int size = 1024000; - char rnddata1[size]; - char rnddata2[size]; - - for(j = 0; j < size; j++) - { - rnddata1[j] = (unsigned char) (255.0 * - rand() / (RAND_MAX + 1.0)); - - rnddata2[j] = (unsigned char) (255.0 * - rand() / (RAND_MAX + 1.0)); - } - - /* for each iteration, we want to - * (1) fill up the outgoing buffers with stuff - */ - - int sent1 = 0; - int sent2 = 0; - int fill1, fill2; - int MaxSend = 1000000; - - while((fill1 = tcp1.write_allowed()) && (sent1 < MaxSend)) - { - /* fill with a random little bit more */ - int psize = (int) ((i + 1.0) * 255.0 * - rand() / (RAND_MAX + 1.0)); - - /* don't overload */ - if (psize > fill1) - { - std::cerr << "LAST FILL1" << std::endl; - psize = fill1; - } - - int ret = tcp1.write(&(rnddata1[sent1]), psize); - - if (ret) - { - sent1 += ret; - std::cerr << "Filled tcp1 with " << ret << " more bytes, total:"; - std::cerr << sent1 << " was allowed: " << fill1; - std::cerr << std::endl; - } - - //tcp1.status(std::cerr); - - } - std::cerr << "Tcp1 full with " << sent1 << " bytes "; - std::cerr << std::endl; - - while((fill2 = tcp2.write_allowed()) && (sent2 < MaxSend)) - { - /* fill with a random little bit more */ - /* slightly larger sizes */ - int psize = (int) ((i + 1.0) * 1255.0 * - rand() / (RAND_MAX + 1.0)); - - /* don't overload */ - if (psize > fill2) - { - std::cerr << "LAST FILL2" << std::endl; - psize = fill2; - } - - int ret = tcp2.write(&(rnddata2[sent2]), psize); - - if (ret) - { - sent2 += ret; - std::cerr << "Filled tcp2 with " << ret << " more bytes, total:"; - std::cerr << sent2 << " was allowed: " << fill2; - std::cerr << std::endl; - } - - //tcp2.status(std::cerr); - - } - std::cerr << "Tcp2 full with " << sent2 << " bytes "; - std::cerr << std::endl; - - /* for every second iteration, fill up the read buffer before starting */ - if (i % 2 == 0) - { - for(j = 0; j < 100; j++) - { - tcp1.tick(); - tcp2.tick(); - } - } - - /* now we read/tick and empty */ - int read1 = 0; - int read2 = 0; - - while(read1 < sent2) - { - tcp1.tick(); - tcp2.tick(); - - /* fill with a random little bit more */ - /* This one has a small read, while tcp2 has a large read */ - int psize = (int) ((i + 1.0) * 100.0 * - rand() / (RAND_MAX + 1.0)); - - /* limit to what we have! */ - if (psize > sent2 - read1) - { - std::cerr << "LAST READ1" << std::endl; - psize = sent2 - read1; - } - - char rbuf[psize]; - int rsize = psize; - - int ret = tcp1.read(rbuf, rsize); - if (0 < ret) - { - /* check the data */ - for(j = 0; j < ret; j++) - { - if (rnddata2[read1 + j] != rbuf[j]) - { - std::cerr << "Error Data Mismatch @ read1:" << read1; - std::cerr << " + j:" << j << " rsize: " << rsize; - std::cerr << " Index: " << read1 + j; - std::cerr << std::endl; - - int badoffset = read1 + j; - for(int k = -10; k < 10; k++) - { - printf("Orig: %02x, Trans: %02x\n", - (unsigned char) rnddata2[badoffset+k], - (unsigned char) rbuf[j + k]); - } - - - exit(1); - } - } - read1 += ret; - } - else - { - std::cerr << "Read Error: " << ret << std::endl; - } - std::cerr << "Requested " << psize << ", got " << ret << " bytes" << std::endl; - std::cerr << "Read " << read1 << " of " << sent2 << " bytes" << std::endl; - } - - sleep(2); - - - while(read2 < sent1) - { - tcp1.tick(); - tcp2.tick(); - - /* fill with a random little bit more */ - int psize = (int) ((i + 1.0) * 10000.0 * - rand() / (RAND_MAX + 1.0)); - - /* limit to what we have! */ - if (psize > sent1 - read2) - { - std::cerr << "LAST READ2" << std::endl; - psize = sent1 - read2; - } - - char rbuf[psize]; - int rsize = psize; - - int ret = tcp2.read(rbuf, rsize); - if (0 < ret) - { - /* check the data */ - for(j = 0; j < ret; j++) - { - if (rnddata1[read2 + j] != rbuf[j]) - { - std::cerr << "Error Data Mismatch @ read2:" << read2; - std::cerr << " + j:" << j << " rsize: " << rsize; - std::cerr << " Index: " << read2 + j; - std::cerr << std::endl; - exit(1); - } - } - read2 += ret; - } - else - { - std::cerr << "Read Error: " << ret << std::endl; - } - std::cerr << "Requested " << psize << ", got " << ret << " bytes" << std::endl; - std::cerr << "Read " << read2 << " of " << sent1 << " bytes" << std::endl; - } - - std::cerr << "Iteration " << i + 1 << " finished correctly!" << std::endl; - sleep(5); - - } - return 1; -} - -int setup_socket(struct sockaddr_in addr) -{ - int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0); - - if (sockfd <= 0) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - return -1; - } - - std::cerr << "Socket Created: " << sockfd << std::endl; - - int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)); - - if (err < 0) - { - std::cerr << "Error: Cannot bind socket: "; - std::cerr << err << std::endl; - return -1; - } - - std::cerr << "Socket1 Bound to: " << addr << std::endl; - return sockfd; -} - -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2) -{ - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ - int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1)); - int err_num; - - if (err < 0) - { - err_num = tou_errno(fd2); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Listen!: " << err_num << std::endl; - return -1; - } - } - - - std::cerr << "Socket1 Connecting to: " << addr2 << std::endl; - err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2)); - if (err < 0) - { - err_num = tou_errno(fd1); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << err_num << std::endl; - return -1; - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - sleep(1); - - /* sock1 */ - if((!sock1Connected) && (0 == (err = tou_connected(fd1)))) - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - - if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2, - (struct sockaddr *) &inaddr, &addrlen)))) - { - errno = tou_errno(fd2); - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - fd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - - return 1; -} - - -/* This transmits into sockfd1, and check to see that we recv - * it back from sockfd2 - */ - -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size) -{ - /* what we recvd */ - char *recvd = (char *) malloc(size * 2); - int recvdsize = 0; - int sent = 0; - int sendsize = 0; - - int ts_start = time(NULL); - - int minsends = 100; /* min of 100 sends to complete all data */ - /* ensure we don't end up sending nothing */ - if (minsends * 10 > size) - { - minsends = size / 10; - } - - bool doneWrite = false; - bool doneRead = false; - while((!doneWrite) || (!doneRead)) - { - /* have a little break */ - //usleep(10000); /* 0.01 sec */ - //usleep(250000); /* 0.25 sec */ - usleep(500000); /* 0.50 sec */ - /* decide how much to send */ - sendsize = (int) (((float) (size / minsends)) * - (rand() / (RAND_MAX + 1.0))); - - /* limit send */ - if (sent + sendsize > size) - { - sendsize = size - sent; - } - /* if we've finished */ - if (sent == size) - { - /* eof */ - std::cerr << "Write Done!" << std::endl; - doneWrite = true; - sendsize = 0; - } - - /* now we write */ - if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize))) - { - std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl; - if (tou_errno(sockfd1) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - else - { - sent += sendsize; - } - - int ret = 0; - int readsize = (int) (((float) (size / minsends)) * - (rand() / (RAND_MAX + 1.0))); - - if (readsize > size - recvdsize) - readsize = size - recvdsize; - - if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize))) - { - std::cerr << "TF(" << ret << ")" << std::endl; - recvdsize += ret; - } - else if (ret == 0) - { - doneRead = true; - std::cerr << "Read Done! (ret:0)" << std::endl; - } - else - { - std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl; - std::cerr << "Read " << recvdsize << "/" << size; - std::cerr << " attempted: " << readsize << std::endl; - if (tou_errno(sockfd2) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - - if (recvdsize == size) - { - doneRead = true; - std::cerr << "Read Done!" << std::endl; - } - - } - - /* we have transmitted it all, so - * check the data - */ - - int i; - int diffCount = 0; - for(i = 0; i < size; i++) - { - if (recvd[i] != data[i]) - { - diffCount++; - if (diffCount < 10) - { - std::cerr << "Error Byte:" << i << " is different"; - std::cerr << std::endl; - } - } - } - if (diffCount) - { - std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!"; - std::cerr << std::endl; - exit(1); - } - - int ts_end = time(NULL); - double rough_rate = size / (double) (ts_end - ts_start); - - std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs"; - std::cerr << std::endl; - std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec"; - std::cerr << std::endl; - - return 1; -} - - - - - - - - diff --git a/libretroshare/src/tests/tcponudp/largefile_tou.cc b/libretroshare/src/tests/tcponudp/largefile_tou.cc deleted file mode 100644 index 1bf0bebca..000000000 --- a/libretroshare/src/tests/tcponudp/largefile_tou.cc +++ /dev/null @@ -1,502 +0,0 @@ -/* - * "$Id: largefile_tou.cc,v 1.2 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -/********************************************************** - * This test is designed to test large data blocks/files - * running to tou. Currently we see occasional errors - * every 1/2 -> 1 MB of transfer.... - * - * This test will continually fill the output buffer, - * and then empty the receive one. To ensure the - * whole system gets a good workout. - * - */ - -#include - -// for printing sockaddr -#include "udplayer.h" - -#include "tou.h" -#include "tou_net.h" - -#include -#include -#include - -int setup_socket(struct sockaddr_in addr); -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2); -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size); - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - int i,j; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - tounet_init(); - - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - unsigned short laddr_port = atoi(argv[optind+1]); - unsigned short raddr_port = atoi(argv[optind+3]); - - for(i = 0; i < 10; i++) - { - laddr.sin_port = htons(laddr_port); - raddr.sin_port = htons(raddr_port); - //laddr.sin_port = htons(laddr_port + i); - //raddr.sin_port = htons(raddr_port + i); - - std::cerr << "Interation: " << i << std::endl; - - - /* setup the sockets */ - int sockfd1 = setup_socket(laddr); - int sockfd2 = setup_socket(raddr); - - if ((sockfd1 < 0) || (sockfd2 < 0)) - { - std::cerr << "Failed to setup sockets!"; - std::cerr << std::endl; - return -1; - } - - std::cerr << "Local Address: " << laddr; - std::cerr << " fd: " << sockfd1 << std::endl; - std::cerr << "Remote Address: " << raddr; - std::cerr << " fd: " << sockfd2 << std::endl; - - /* connect */ - int err = connect_socket_pair(sockfd1, sockfd2, laddr, raddr); - if (err < 0) - { - std::cerr << "Failed to connect sockets!"; - std::cerr << std::endl; - return -1; - } - - /* send the data */ - int size = 3093237; - char rnddata[size]; - - int data_loops = (i+1) * (i+1); - for(int k = 0; k < data_loops; k++) - { - std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl; - for(j = 0; j < size; j++) - { - rnddata[j] = (unsigned char) (255.0 * - rand() / (RAND_MAX + 1.0)); - } - send_data_via_pair(sockfd1, sockfd2, rnddata, size); - std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl; - sleep(2); - } - - std::cerr << "Completed Successful transfer of " << size * data_loops << " bytes"; - std::cerr << std::endl; - - sleep(10); - std::cerr << "closing sockfd1: " << sockfd1 << std::endl; - tou_close(sockfd1); - - std::cerr << "closing sockfd2: " << sockfd2 << std::endl; - tou_close(sockfd2); - - - } - return 1; -} - -int setup_socket(struct sockaddr_in addr) -{ - int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0); - - if (sockfd <= 0) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - return -1; - } - - std::cerr << "Socket Created: " << sockfd << std::endl; - - int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)); - - if (err < 0) - { - std::cerr << "Error: Cannot bind socket: "; - std::cerr << err << std::endl; - return -1; - } - - std::cerr << "Socket1 Bound to: " << addr << std::endl; - return sockfd; -} - -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2) -{ - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ - int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1)); - int err_num; - - if (err < 0) - { - err_num = tou_errno(fd2); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Listen!: " << err_num << std::endl; - return -1; - } - } - - - std::cerr << "Socket1 Connecting to: " << addr2 << std::endl; - err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30); - if (err < 0) - { - err_num = tou_errno(fd1); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << err_num << std::endl; - return -1; - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - sleep(1); - - /* sock1 */ - if((!sock1Connected) && (0 == (err = tou_connected(fd1)))) - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - - if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2, - (struct sockaddr *) &inaddr, &addrlen)))) - { - errno = tou_errno(fd2); - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - fd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - - return 1; -} - - -/* This transmits into sockfd1, and check to see that we recv - * it back from sockfd2 - */ - -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size) -{ - /* what we recvd */ - char *recvd = (char *) malloc(size * 2); - int recvdsize = 0; - int sent = 0; - int sendsize = 0; - - int ts_start = time(NULL); - - int minsends = 100; /* min of 100 sends to complete all data */ - /* ensure we don't end up sending nothing */ - if (minsends * 10 > size) - { - minsends = size / 10; - } - - bool doneWrite = false; - bool doneRead = false; - - int maxtransfer = (int) (size / minsends) + (int) (((float) (size / minsends)) * - (rand() / (RAND_MAX + 1.0))); - /* allow the transfer ratio read/write to vary between 0.4->1,5. */ - double tf_ratio = 0.4 + 1.1 * (rand() / (RAND_MAX + 1.0)); - - while((!doneWrite) || (!doneRead)) - { - /* have a little break */ - //usleep(10000); /* 0.01 sec */ - usleep(20000); /* 0.02 sec */ - //usleep(250000); /* 0.25 sec */ - //usleep(500000); /* 0.50 sec */ - /* decide how much to send */ - sendsize = (int) (((float) (maxtransfer)) * - (rand() / (RAND_MAX + 1.0))); - - /* limit send */ - if (sent + sendsize > size) - { - std::cerr << "Last WRITE!" << std::endl; - sendsize = size - sent; - } - /* if we've finished */ - if (sent == size) - { - /* eof */ - std::cerr << "Write Done!" << std::endl; - doneWrite = true; - sendsize = 0; - } - - /* now we write */ - if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize))) - { - std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl; - if (tou_errno(sockfd1) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - else - { - sent += sendsize; - } - - int ret = 0; - - // read size about 1/4 of write to exercise the buffers. - int readsize = (int) (((float) (maxtransfer)) * tf_ratio * - (rand() / (RAND_MAX + 1.0))); - - if (readsize > size - recvdsize) - { - std::cerr << "Last READ!" << std::endl; - readsize = size - recvdsize; - } - - if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize))) - { - std::cerr << "TF(" << ret << ")" << std::endl; - - /* check the data at this point */ - - int i; - int diffCount = 0; - int init_err = 0; - for(i = 0; i < ret; i++) - { - if (recvd[recvdsize + i] != data[recvdsize + i]) - { - if (!diffCount) - { - init_err = i; - } - diffCount++; - if (diffCount < 10) - { - std::cerr << "Error Byte:" << recvdsize + i << " is different"; - std::cerr << std::endl; - } - } - } - if (diffCount) - { - std::cerr << "Errors (" << diffCount << "/" << ret << ") in read, "; - std::cerr << std::endl; - std::cerr << " At Blk Start: " << recvdsize << " offset: " << init_err; - std::cerr << " ==> At index: " << recvdsize + init_err << "... Exiting!"; - std::cerr << std::endl; - exit(1); - } - else - { - std::cerr << "Checked (" << recvdsize << "+ 0 => " << ret << ") Okay" << std::endl; - } - - recvdsize += ret; - } - else if (ret == 0) - { - //doneRead = true; - std::cerr << "Read Done? (ret:0)" << std::endl; - } - else - { - std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl; - std::cerr << "Read " << recvdsize << "/" << size; - std::cerr << " attempted: " << readsize << std::endl; - if (tou_errno(sockfd2) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - - if (recvdsize == size) - { - doneRead = true; - std::cerr << "Read Done!" << std::endl; - } - - } - - /* we have transmitted it all, so - * check the data - */ - - int i; - int diffCount = 0; - for(i = 0; i < size; i++) - { - if (recvd[i] != data[i]) - { - diffCount++; - if (diffCount < 10) - { - std::cerr << "Error Byte:" << i << " is different"; - std::cerr << std::endl; - } - } - } - if (diffCount) - { - std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!"; - std::cerr << std::endl; - exit(1); - } - - int ts_end = time(NULL); - double rough_rate = size / (double) (ts_end - ts_start); - - std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs"; - std::cerr << std::endl; - std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec"; - std::cerr << std::endl; - std::cerr << "Transfer Ratio: " << tf_ratio; - std::cerr << std::endl; - - free(recvd); - - return 1; -} - - - - - - - - diff --git a/libretroshare/src/tests/tcponudp/pair_tou.cc b/libretroshare/src/tests/tcponudp/pair_tou.cc deleted file mode 100644 index 945c6ac31..000000000 --- a/libretroshare/src/tests/tcponudp/pair_tou.cc +++ /dev/null @@ -1,508 +0,0 @@ -/* - * "$Id: pair_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include - -//#define USE_TCP_SOCKET - -// for printing sockaddr -#include "udp/udpstack.h" - -#ifndef USE_TCP_SOCKET - #include "tcponudp/tou.h" - #include "tcponudp/udppeer.h" -#endif - -#include "util/bdnet.h" - -#include -#include -#include - - -/* This is a simple test to ensure that the tou behaviour - * is almost identical to a standard tcp socket. - * - * In this version we open 2 sockets, and attempt to - * communicate with ourselves.... - * - */ - -int Check_Socket(int fd); - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - int totalwbytes = 0; - int totalrbytes = 0; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - UdpStack *udpStack1 = new UdpStack(laddr); - UdpStack *udpStack2 = new UdpStack(raddr); - - UdpSubReceiver *udpReceivers[2]; - int udpTypes[2]; - - udpReceivers[0] = new UdpPeerReceiver(udpStack1); - udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack1->addReceiver(udpReceivers[0]); - - udpReceivers[1] = new UdpPeerReceiver(udpStack2); - udpTypes[1] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack2->addReceiver(udpReceivers[1]); - - tou_init((void **) udpReceivers, udpTypes, 2); - - -#ifdef USE_TCP_SOCKET - int sockfd = socket(PF_INET, SOCK_STREAM, 0); - int sockfd2 = socket(PF_INET, SOCK_STREAM, 0); -#else - int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); - int sockfd2 = tou_socket(1, TOU_RECEIVER_TYPE_UDPPEER, 0); -#endif - if ((sockfd <= 0) || (sockfd2 <= 0)) - { - std::cerr << "Failed to open socket!: "; -#ifdef USE_TCP_SOCKET - std::cerr << "Socket Error:" << errno << std::endl; -#else - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl; -#endif - return -1; - } - std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl; - - - /* make nonblocking */ -#ifdef USE_TCP_SOCKET - int err = fcntl(sockfd,F_SETFD,O_NONBLOCK); - int err2 = fcntl(sockfd2,F_SETFD,O_NONBLOCK); -#else - int err = 0; - int err2 = 0; -#endif - if ((err < 0) || (err2 < 0)) - { - std::cerr << "Error: Cannot make socket NON-Blocking: "; - std::cerr << err << std::endl; - return -1; - } - - std::cerr << "Socket Non-Blocking" << std::endl; - -#ifdef USE_TCP_SOCKET - err = bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr)); - err2 = bind(sockfd2, (struct sockaddr *) &raddr, sizeof(raddr)); - if ((err < 0) || (err2 < 0)) - { - std::cerr << "Error: Cannot bind socket: "; - std::cerr << err << std::endl; - return -1; - } -#else - // No more Bind in tou. - //err = tou_bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr)); - //err2 = tou_bind(sockfd2, (struct sockaddr *) &raddr, sizeof(raddr)); -#endif - - std::cerr << "Socket1 Bound to: " << laddr << std::endl; - std::cerr << "Socket2 Bound to: " << raddr << std::endl; - - // listening. - if (1) // socket2. - { - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ -#ifdef USE_TCP_SOCKET - err = listen(sockfd2, 1); -#else - err = tou_listenfor(sockfd2, - (struct sockaddr *) &laddr, sizeof(laddr)); -#endif - } - - - if (1) // only one program. - { - std::cerr << "Socket1 Connecting to: " << raddr << std::endl; -#ifdef USE_TCP_SOCKET - err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr)); -#else - err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); -#endif - if (err < 0) - { -#ifndef USE_TCP_SOCKET - errno = tou_errno(sockfd); -#endif - if (errno != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - sleep(1); - - - /* sock1 */ -#ifdef USE_TCP_SOCKET - if((!sock1Connected) && (0 == (err = Check_Socket(sockfd)))) -#else - if((!sock1Connected) && (0 == (err = tou_connected(sockfd)))) -#endif - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - -#ifdef USE_TCP_SOCKET - if ((!sock2Connected) && (0 > (nsock = accept(sockfd2, - (struct sockaddr *) &inaddr, &addrlen)))) -#else - if ((!sock2Connected) && (0 > (nsock = tou_accept(sockfd2, - (struct sockaddr *) &inaddr, &addrlen)))) -#endif - { -#ifndef USE_TCP_SOCKET - errno = tou_errno(sockfd2); -#endif - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - sockfd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - - /* send data */ - int bufsize = 1511; - char buffer[bufsize]; - char data[bufsize]; - int readsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - - bool doneWrite = false; - bool doneRead = false; - bool blockread = false; - while((!doneWrite) || (!doneRead)) - { - /* read -> write_socket... */ - sleep(1); - if (blockread != true) - { - readsize = read(0, buffer, bufsize); - } - if (readsize == 0) - { - /* eof */ - doneWrite = true; - } - /* now we write */ -#ifdef USE_TCP_SOCKET - if ((readsize > 0) && (-1 == write(sockfd, buffer, readsize))) -#else - if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize))) -#endif - { - //std::cerr << "Blocked Write!" << std::endl; -#ifndef USE_TCP_SOCKET - //std::cerr << "Error: " << tou_errno(sockfd) << std::endl; -#endif - blockread = true; - } - else - { - blockread = false; - totalwbytes += readsize; - } - - int ret = 0; -#ifdef USE_TCP_SOCKET - if (0 < (ret = read(sockfd2, data, bufsize))) -#else - if (0 < (ret = tou_read(sockfd2, data, bufsize))) -#endif - - { - std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - totalrbytes += ret; - } - else if (ret == 0) - { - doneRead = true; - } - else - { - //std::cerr << "Blocked Read!" << std::endl; -#ifndef USE_TCP_SOCKET - //std::cerr << "Error: " << tou_errno(sockfd) << std::endl; -#endif - } - - - } - -#ifdef USE_TCP_SOCKET - close(sockfd); - close(sockfd2); -#else - /* this is blocking??? */ - tou_close(sockfd); - tou_close(sockfd2); -#endif - - std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; - std::cerr << std::endl; - return 1; -} - -#ifdef USE_TCP_SOCKET - - -int Check_Socket(int fd) -{ - std::cerr << "Check_Socket()" << std::endl; - - std::cerr << "1) Checking with Select()" << std::endl; - - fd_set ReadFDs, WriteFDs, ExceptFDs; - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); - FD_ZERO(&ExceptFDs); - - FD_SET(fd, &ReadFDs); - FD_SET(fd, &WriteFDs); - FD_SET(fd, &ExceptFDs); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - int sr = 0; - if (0 > (sr = select(fd + 1, - &ReadFDs, &WriteFDs, &ExceptFDs, &timeout))) - { - std::cerr << "Check_Socket() Select ERROR: " << sr << std::endl; - return -1; - } - - if (FD_ISSET(fd, &ExceptFDs)) - { - std::cerr << "Check_Socket() Exception on socket!" << std::endl; - return -1; - } - - if (FD_ISSET(fd, &WriteFDs)) - { - std::cerr << "Check_Socket() Can Write!" << std::endl; - } - else - { - // not ready return 0; - std::cerr << "Check_Socket() Cannot Write!" << std::endl; - std::cerr << "Check_Socket() Socket Not Ready!" << std::endl; - return 0; - } - - if (FD_ISSET(fd, &ReadFDs)) - { - std::cerr << "Check_Socket() Can Read!" << std::endl; - } - else - { - std::cerr << "Check_Socket() Cannot Read!" << std::endl; - std::cerr << "Check_Socket() Socket Not Ready!" << std::endl; - return 0; - } - - std::cerr << "Select() Tests indicate Socket Good!" << std::endl; - std::cerr << "2) Checking with getsockopt()" << std::endl; - - int err = 1; - socklen_t optlen = 4; - if (0==getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen)) - { - std::cerr << "Check_Socket() getsockopt returned :" << err; - std::cerr << ", optlen:" << optlen; - std::cerr << std::endl; - - if (err == 0) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection Complete:"; - std::cerr << std::endl; - return 1; - } - else if (err == EINPROGRESS) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection INPROGRESS"; - std::cerr << std::endl; - return 0; - } - else if ((err == ENETUNREACH) || (err == ETIMEDOUT)) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT"; - std::cerr << std::endl; - return -1; - } - else if ((err == EHOSTUNREACH) || (err == EHOSTDOWN)) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT"; - std::cerr << std::endl; - return -1; - } - else - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates Other Error: " << err; - std::cerr << std::endl; - return -1; - } - - - } - else - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " FAILED "; - std::cerr << std::endl; - return -1; - } -} - - -#else - -int Check_Socket(int fd) -{ - return 0; -} - -#endif diff --git a/libretroshare/src/tests/tcponudp/reset_tou.cc b/libretroshare/src/tests/tcponudp/reset_tou.cc deleted file mode 100644 index 3faa8851c..000000000 --- a/libretroshare/src/tests/tcponudp/reset_tou.cc +++ /dev/null @@ -1,453 +0,0 @@ -/* - * "$Id: reset_tou.cc,v 1.4 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -/********************************************************** - * This test is designed to ensure that tou networking - * can be reset, and restarted. - * - */ - -#include - -// for printing sockaddr -#include "udplayer.h" - -#include "tou.h" -#include "tou_net.h" - -#include -#include -#include - - -/* This is a simple test to ensure that the tou behaviour - * is almost identical to a standard tcp socket. - * - * In this version we open 2 sockets, and attempt to - * communicate with ourselves.... - * - */ - -int setup_socket(struct sockaddr_in addr); -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2); -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size); - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - int i,j; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - tounet_init(); - - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!tounet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!tounet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - unsigned short laddr_port = atoi(argv[optind+1]); - unsigned short raddr_port = atoi(argv[optind+3]); - - for(i = 0; i < 10; i++) - { - laddr.sin_port = htons(laddr_port); - raddr.sin_port = htons(raddr_port); - //laddr.sin_port = htons(laddr_port + i); - //raddr.sin_port = htons(raddr_port + i); - - std::cerr << "Interation: " << i << std::endl; - - - /* setup the sockets */ - int sockfd1 = setup_socket(laddr); - int sockfd2 = setup_socket(raddr); - - if ((sockfd1 < 0) || (sockfd2 < 0)) - { - std::cerr << "Failed to setup sockets!"; - std::cerr << std::endl; - return -1; - } - - std::cerr << "Local Address: " << laddr; - std::cerr << " fd: " << sockfd1 << std::endl; - std::cerr << "Remote Address: " << raddr; - std::cerr << " fd: " << sockfd2 << std::endl; - - /* connect */ - int err = connect_socket_pair(sockfd1, sockfd2, laddr, raddr); - if (err < 0) - { - std::cerr << "Failed to connect sockets!"; - std::cerr << std::endl; - return -1; - } - - /* send the data */ - int size = 102400; - char rnddata[size]; - - int data_loops = (i+1) * (i+1); - for(int k = 0; k < data_loops; k++) - { - std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl; - for(j = 0; j < size; j++) - { - rnddata[j] = (unsigned char) (255.0 * - rand() / (RAND_MAX + 1.0)); - } - send_data_via_pair(sockfd1, sockfd2, rnddata, size); - std::cerr << "Send Iteration: " << k+1 << " of " << data_loops << std::endl; - sleep(2); - } - - std::cerr << "Completed Successful transfer of " << size * data_loops << " bytes"; - std::cerr << std::endl; - - sleep(10); - std::cerr << "closing sockfd1: " << sockfd1 << std::endl; - tou_close(sockfd1); - - std::cerr << "closing sockfd2: " << sockfd2 << std::endl; - tou_close(sockfd2); - - - } - return 1; -} - -int setup_socket(struct sockaddr_in addr) -{ - int sockfd = tou_socket(PF_INET, SOCK_STREAM, 0); - - if (sockfd <= 0) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - return -1; - } - - std::cerr << "Socket Created: " << sockfd << std::endl; - - int err = tou_bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)); - - if (err < 0) - { - std::cerr << "Error: Cannot bind socket: "; - std::cerr << err << std::endl; - return -1; - } - - std::cerr << "Socket1 Bound to: " << addr << std::endl; - return sockfd; -} - -int connect_socket_pair(int fd1, int fd2, - struct sockaddr_in addr1, struct sockaddr_in addr2) -{ - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ - int err = tou_listenfor(fd2, (struct sockaddr *) &addr1, sizeof(addr1)); - int err_num; - - if (err < 0) - { - err_num = tou_errno(fd2); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Listen!: " << err_num << std::endl; - return -1; - } - } - - - std::cerr << "Socket1 Connecting to: " << addr2 << std::endl; - err = tou_connect(fd1, (struct sockaddr *) &addr2, sizeof(addr2), 30); - if (err < 0) - { - err_num = tou_errno(fd1); - if (err_num != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << err_num << std::endl; - return -1; - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - sleep(1); - - /* sock1 */ - if((!sock1Connected) && (0 == (err = tou_connected(fd1)))) - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - - if ((!sock2Connected) && (0 > (nsock = tou_accept(fd2, - (struct sockaddr *) &inaddr, &addrlen)))) - { - errno = tou_errno(fd2); - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - fd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - - return 1; -} - - -/* This transmits into sockfd1, and check to see that we recv - * it back from sockfd2 - */ - -int send_data_via_pair(int sockfd1, int sockfd2, char *data, int size) -{ - /* what we recvd */ - char *recvd = (char *) malloc(size * 2); - int recvdsize = 0; - int sent = 0; - int sendsize = 0; - - int ts_start = time(NULL); - - int minsends = 100; /* min of 100 sends to complete all data */ - /* ensure we don't end up sending nothing */ - if (minsends * 10 > size) - { - minsends = size / 10; - } - - bool doneWrite = false; - bool doneRead = false; - while((!doneWrite) || (!doneRead)) - { - /* have a little break */ - //usleep(10000); /* 0.01 sec */ - //usleep(250000); /* 0.25 sec */ - usleep(500000); /* 0.50 sec */ - /* decide how much to send */ - sendsize = (int) (((float) (size / minsends)) * - (rand() / (RAND_MAX + 1.0))); - - /* limit send */ - if (sent + sendsize > size) - { - sendsize = size - sent; - } - /* if we've finished */ - if (sent == size) - { - /* eof */ - std::cerr << "Write Done!" << std::endl; - doneWrite = true; - sendsize = 0; - } - - /* now we write */ - if ((sendsize > 0)&&(-1==tou_write(sockfd1,&(data[sent]),sendsize))) - { - std::cerr << "Write Error: " << tou_errno(sockfd1) << std::endl; - if (tou_errno(sockfd1) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - else - { - sent += sendsize; - } - - int ret = 0; - int readsize = (int) (((float) (size / minsends)) * - (rand() / (RAND_MAX + 1.0))); - - if (readsize > size - recvdsize) - readsize = size - recvdsize; - - if (0 < (ret = tou_read(sockfd2, &(recvd[recvdsize]), readsize))) - { - std::cerr << "TF(" << ret << ")" << std::endl; - recvdsize += ret; - } - else if (ret == 0) - { - doneRead = true; - std::cerr << "Read Done! (ret:0)" << std::endl; - } - else - { - std::cerr << "Read Error: " << tou_errno(sockfd2) << std::endl; - std::cerr << "Read " << recvdsize << "/" << size; - std::cerr << " attempted: " << readsize << std::endl; - if (tou_errno(sockfd2) != EAGAIN) - { - std::cerr << "FATAL ERROR ending transfer" << std::endl; - doneRead = true; - doneWrite = true; - } - - } - - if (recvdsize == size) - { - doneRead = true; - std::cerr << "Read Done!" << std::endl; - } - - } - - /* we have transmitted it all, so - * check the data - */ - - int i; - int diffCount = 0; - for(i = 0; i < size; i++) - { - if (recvd[i] != data[i]) - { - diffCount++; - if (diffCount < 10) - { - std::cerr << "Error Byte:" << i << " is different"; - std::cerr << std::endl; - } - } - } - if (diffCount) - { - std::cerr << "Errors (" << diffCount << "/" << size << ") in tranmission ... Exiting!"; - std::cerr << std::endl; - exit(1); - } - - int ts_end = time(NULL); - double rough_rate = size / (double) (ts_end - ts_start); - - std::cerr << "Successful Data Tranmission: " << size << " in " << ts_end-ts_start << " secs"; - std::cerr << std::endl; - std::cerr << "Approximate Rate: " << rough_rate / 1000.0 << " kbytes/sec"; - std::cerr << std::endl; - - return 1; -} - - - - - - - - diff --git a/libretroshare/src/tests/tcponudp/stacks_tou.cc b/libretroshare/src/tests/tcponudp/stacks_tou.cc deleted file mode 100644 index ece3915b4..000000000 --- a/libretroshare/src/tests/tcponudp/stacks_tou.cc +++ /dev/null @@ -1,354 +0,0 @@ -/* - * "$Id: pair_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include - -// for printing sockaddr -#include "udp/udpstack.h" - -#include "tcponudp/tou.h" -#include "tcponudp/udppeer.h" -#include "tcponudp/udprelay.h" - -#include "util/bdnet.h" - -#include "util/rsrandom.h" - -#include -#include -#include - - -/* - * This test creates the same stacks as are used in RS. - * This additionally tests the "checkFns" for the other UdpReceivers, which could potentially be modifying the data. - * obviously they shouldn't! - * - */ - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - int totalwbytes = 0; - int totalrbytes = 0; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - std::cerr << "Creating with Lossy Udp Layers for further testing"; - std::cerr << std::endl; - - UdpStack *udpStack1 = new UdpStack(UDP_TEST_LOSSY_LAYER,laddr); - UdpStack *udpStack2 = new UdpStack(UDP_TEST_LOSSY_LAYER,raddr); - - UdpSubReceiver *udpReceivers[4]; - int udpTypes[4]; - - // NOTE DHT is too hard to add at the moment. - - UdpRelayReceiver *mRelay1 = new UdpRelayReceiver(udpStack1); - udpReceivers[1] = mRelay1; - udpTypes[1] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack1->addReceiver(udpReceivers[1]); - - udpReceivers[0] = new UdpPeerReceiver(udpStack1); - udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack1->addReceiver(udpReceivers[0]); - - // STACK 2. - UdpRelayReceiver *mRelay2 = new UdpRelayReceiver(udpStack2); - udpReceivers[3] = mRelay2; - udpTypes[3] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack2->addReceiver(udpReceivers[3]); - - udpReceivers[2] = new UdpPeerReceiver(udpStack2); - udpTypes[2] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack2->addReceiver(udpReceivers[2]); - - tou_init((void **) udpReceivers, udpTypes, 4); - - - int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); - int sockfd2 = tou_socket(2, TOU_RECEIVER_TYPE_UDPPEER, 0); - if ((sockfd <= 0) || (sockfd2 <= 0)) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl; - return -1; - } - std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl; - - std::cerr << "Socket Non-Blocking" << std::endl; - - std::cerr << "Socket1 Bound to: " << laddr << std::endl; - std::cerr << "Socket2 Bound to: " << raddr << std::endl; - - int err = 0; - - // listening. - if (1) // socket2. - { - std::cerr << "Socket2 Listening " << std::endl; - /* listen */ - err = tou_listenfor(sockfd2, - (struct sockaddr *) &laddr, sizeof(laddr)); - } - - - if (1) // only one program. - { - std::cerr << "Socket1 Connecting to: " << raddr << std::endl; - err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); - if (err < 0) - { - errno = tou_errno(sockfd); - if (errno != EINPROGRESS) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - } - } - - bool sock1Connected = false; - bool sock2Connected = false; - - while((!sock1Connected) || (!sock2Connected)) - { - usleep(1000); - - - /* sock1 */ - if((!sock1Connected) && (0 == (err = tou_connected(sockfd)))) - { - std::cerr << "Waiting for Connect (Sock1)!" << std::endl; - } - if ((!sock1Connected) && (err < 0)) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - else if (!sock1Connected) - { - // else connected! - sock1Connected = true; - } - - /* accept - sock2 */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock = -1; - - if ((!sock2Connected) && (0 > (nsock = tou_accept(sockfd2, - (struct sockaddr *) &inaddr, &addrlen)))) - { - errno = tou_errno(sockfd2); - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!: " << errno << std::endl; - return 1; - } - else - { - std::cerr << "Waiting for Connect (Sock2)!" << std::endl; - } - } - else if (nsock > 0) - { - /* connected */ - sock2Connected = true; - sockfd2 = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - } - - std::cerr << "Socket Connected" << std::endl; - -#define MAX_READ 20000 - - /* send data */ - int bufsize = MAX_READ; - char buffer[MAX_READ]; - char data[MAX_READ]; - int readsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - - rstime_t lastRead = time(NULL); - bool doneWrite = false; - bool doneRead = false; - bool blockread = false; - - while((!doneWrite) || (!doneRead)) - { - /* read -> write_socket... */ - usleep(10); - - if (blockread != true) - { - int readbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); - readsize = read(0, buffer, readbuf); - if (readsize) - { - //std::cerr << "read " << readsize << " / " << readbuf; - //std::cerr << std::endl; - } - } - if ((readsize == 0) && (!doneWrite)) - { - /* eof */ - doneWrite = true; - std::cerr << "Write Done Total: " << totalwbytes; - std::cerr << std::endl; - } - /* now we write */ - if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize))) - { - //std::cerr << "Blocked Write "; - //std::cerr << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; - blockread = true; - } - else - { - blockread = false; - totalwbytes += readsize; - - if (readsize) - { - std::cerr << "Written: " << readsize << ", Total: " << totalwbytes; - std::cerr << " In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - } - } - - int ret = 0; - int readbuf2 = 1 + RSRandom::random_u32() % (MAX_READ - 1); - if (0 < (ret = tou_read(sockfd2, data, readbuf2))) - { - //std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - totalrbytes += ret; - - std::cerr << "Read: " << ret << " Total: " << totalrbytes; - std::cerr << " In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - - lastRead = time(NULL); - } - else if ((ret == 0) && (!doneRead)) - { - doneRead = true; - std::cerr << "Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - else - { - //std::cerr << "Blocked Read: " << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; -#define TIMEOUT 15 - if ((!doneRead) && (time(NULL) - lastRead > TIMEOUT)) - { - doneRead = true; - std::cerr << "TIMEOUT: Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - } - - - } - - /* this is blocking??? */ - tou_close(sockfd); - tou_close(sockfd2); - - std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; - std::cerr << std::endl; - return 1; -} - diff --git a/libretroshare/src/tests/tcponudp/stacks_tou.sh b/libretroshare/src/tests/tcponudp/stacks_tou.sh deleted file mode 100755 index 7715e769d..000000000 --- a/libretroshare/src/tests/tcponudp/stacks_tou.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./stacks_tou -DATAFILE=./stacks_tou - -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 - -$EXEC 127.0.0.1 4401 127.0.0.1 4032 < $DATAFILE > $TMPOUTPUT - -if diff -s $DATAFILE $TMPOUTPUT -then - echo "SUCCESS" -else - echo "FAILURE to accurately transfer DATA" -fi - -rm $TMPOUTPUT - diff --git a/libretroshare/src/tests/tcponudp/test_tou.cc b/libretroshare/src/tests/tcponudp/test_tou.cc deleted file mode 100644 index 17035f631..000000000 --- a/libretroshare/src/tests/tcponudp/test_tou.cc +++ /dev/null @@ -1,531 +0,0 @@ -/* - * "$Id: test_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include - -//#define USE_TCP_SOCKET 1 - -// for printing sockaddr -#include "udp/udpstack.h" - -#ifndef USE_TCP_SOCKET - #include "tcponudp/tou.h" - #include "tcponudp/udppeer.h" -#endif - -/* shouldn't do this - but for convenience - * using tou_net.h for universal fns - * generally this should be only internal to libtou.h - * - * This includes the whole networking interface - */ - -#include "util/bdnet.h" - -/* These three includes appear to work in both W & L. - * and they shouldn't!!!! maybe cygwin is allowing it... - * will only use them for tou test fns. - * - * they appear to provide getopt + read/write in windows. - */ - -#include -#include -#include - -/* This is a simple test to ensure that the tou behaviour - * is almost identical to a standard tcp socket. - * - */ - -int Check_Socket(int fd); - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - int totalwbytes = 0; - int totalrbytes = 0; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - - - -#ifdef USE_TCP_SOCKET - int sockfd = socket(PF_INET, SOCK_STREAM, 0); -#else - - UdpStack udps(laddr); - - UdpSubReceiver *udpReceivers[1]; - int udpTypes[1]; - - udpReceivers[0] = new UdpPeerReceiver(&udps); - udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; - udps.addReceiver(udpReceivers[0]); - - tou_init((void **) udpReceivers, udpTypes, 1); - - int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); -#endif - if (sockfd < 0) - { - std::cerr << "Failed to open socket!: "; -#ifdef USE_TCP_SOCKET - std::cerr << "Socket Error:" << errno << std::endl; -#else - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; -#endif - return -1; - } - std::cerr << "Socket Created" << std::endl; - - - /* make nonblocking */ -#ifdef USE_TCP_SOCKET - int err = bdnet_fcntl(sockfd,F_SETFL,O_NONBLOCK); -#else - int err = 0; -#endif - if (err < 0) - { - std::cerr << "Error: Cannot make socket NON-Blocking: "; - std::cerr << err << std::endl; - return -1; - } - - std::cerr << "Socket Non-Blocking" << std::endl; - -#ifdef USE_TCP_SOCKET - err = bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr)); - if (err < 0) - { - std::cerr << "Error: Cannot bind socket: "; - std::cerr << err << std::endl; - return -1; - } - std::cerr << "Socket Bound to: " << laddr << std::endl; -#else - err = tou_bind(sockfd, (struct sockaddr *) &laddr, sizeof(laddr)); - if (err < 0) - { - std::cerr << "As expected, cannot bind a tou socket"; - std::cerr << err << std::endl; - //return -1; - } -#endif - - - if (toConnect) - { - std::cerr << "Socket Connecting to: " << raddr << std::endl; -#ifdef USE_TCP_SOCKET - err = connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr)); -#else - err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); -#endif - if (err < 0) - { -#ifndef USE_TCP_SOCKET - errno = tou_errno(sockfd); -#endif - if (errno != EINPROGRESS) - { - std::cerr << "Cannot Connect!" << std::endl; - return 1; - } -#ifdef USE_TCP_SOCKET - while(0 == (err = Check_Socket(sockfd))) -#else - while(0 == (err = tou_connected(sockfd))) -#endif - { - std::cerr << "Waiting for Connect!" << std::endl; - sleep(1); - } - if (err < 0) - { - std::cerr << "Connect Failed" << std::endl; - return 1; - } - // else connected! - } - } - else - { - std::cerr << "Socket Listening " << std::endl; - /* listen */ -#ifdef USE_TCP_SOCKET - err = listen(sockfd, 1); -#else - //err = tou_listen(sockfd, 1); - err = tou_listenfor(sockfd, - (struct sockaddr *) &raddr, sizeof(raddr)); -#endif - - /* accept */ - struct sockaddr_in inaddr; - socklen_t addrlen = sizeof(inaddr); - int nsock; - -#ifdef USE_TCP_SOCKET - while(0 > (nsock = accept(sockfd, - (struct sockaddr *) &inaddr, &addrlen))) -#else - while(0 > (nsock = tou_accept(sockfd, - (struct sockaddr *) &inaddr, &addrlen))) -#endif - { -#ifndef USE_TCP_SOCKET - errno = tou_errno(sockfd); -#endif - if (errno != EAGAIN) - { - std::cerr << "Cannot Connect!" << std::endl; - return 1; - } - sleep(1); - } - /* changed sockfd */ - sockfd = nsock; - std::cerr << "Socket Accepted from: " << inaddr << std::endl; - } - - std::cerr << "Socket Connected" << std::endl; - - if (toConnect) - { - /* send data */ - int bufsize = 15011; - char buffer[bufsize]; - int readsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - - bool done = false; - bool blockread = false; - while(!done) - { - //sleep(1); - //usleep(10000); - usleep(100); - if (blockread != true) - { - readsize = read(0, buffer, bufsize); - } - if (readsize == 0) - { - /* eof */ - done = true; - } - else if ((readsize == -1) && ( EAGAIN == errno )) - { - continue; - } - - - /* now we write */ -#ifdef USE_TCP_SOCKET - if (-1 == write(sockfd, buffer, readsize)) -#else - if (-1 == tou_write(sockfd, buffer, readsize)) -#endif - { - //std::cerr << "Blocked Write!" << std::endl; -#ifndef USE_TCP_SOCKET - //std::cerr << "Error: " << tou_errno(sockfd) << std::endl; -#endif - blockread = true; - } - else - { - blockread = false; - totalwbytes += readsize; - } - } - -#ifdef USE_TCP_SOCKET - close(sockfd); -#else - /* this is blocking??? */ - tou_close(sockfd); -#endif - - std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; - std::cerr << std::endl; - - // ACTUALLY tou_close() is not blocking... - // and kills the connection instantly. - // The transfer will fail if there is any data left in the send queue (which there is in most cases). - // Interestingly.. if we slow the transmit and speed up the recv, - // Then it can succeed. - // - // The settings are done to make this fail. - - return 1; - } - - /* recv data */ - int bufsize = 1523; - char data[bufsize]; - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - while(1) - { - //sleep(1); - //usleep(10000); - //usleep(1000); - usleep(100); - int writesize = bufsize; - int ret; - -#ifdef USE_TCP_SOCKET - if (0 < (ret = read(sockfd, data, writesize))) -#else - if (0 < (ret = tou_read(sockfd, data, writesize))) -#endif - - { - std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - totalrbytes += ret; - } - else if (ret == 0) - { - break; - } - else - { - //std::cerr << "Blocked Read!" << std::endl; -#ifndef USE_TCP_SOCKET - //std::cerr << "Error: " << tou_errno(sockfd) << std::endl; -#endif - - } - } - -#ifdef USE_TCP_SOCKET - close(sockfd); -#else - tou_close(sockfd); -#endif - - std::cerr << "Transfer complete :" << totalrbytes; - std::cerr << " bytes" << std::endl; - close(1); - - return 1; -} - - - -#ifdef USE_TCP_SOCKET - - -int Check_Socket(int fd) -{ - std::cerr << "Check_Socket()" << std::endl; - - std::cerr << "1) Checking with Select()" << std::endl; - - fd_set ReadFDs, WriteFDs, ExceptFDs; - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); - FD_ZERO(&ExceptFDs); - - FD_SET(fd, &ReadFDs); - FD_SET(fd, &WriteFDs); - FD_SET(fd, &ExceptFDs); - - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - int sr = 0; - if (0 > (sr = select(fd + 1, - &ReadFDs, &WriteFDs, &ExceptFDs, &timeout))) - { - std::cerr << "Check_Socket() Select ERROR: " << sr << std::endl; - return -1; - } - - if (FD_ISSET(fd, &ExceptFDs)) - { - std::cerr << "Check_Socket() Exception on socket!" << std::endl; - return -1; - } - - if (FD_ISSET(fd, &WriteFDs)) - { - std::cerr << "Check_Socket() Can Write!" << std::endl; - } - else - { - // not ready return 0; - std::cerr << "Check_Socket() Cannot Write!" << std::endl; - std::cerr << "Check_Socket() Socket Not Ready!" << std::endl; - return 0; - } - - if (FD_ISSET(fd, &ReadFDs)) - { - std::cerr << "Check_Socket() Can Read!" << std::endl; - } - else - { - std::cerr << "Check_Socket() Cannot Read!" << std::endl; - std::cerr << "Check_Socket() Socket Not Ready!" << std::endl; - return 0; - } - - std::cerr << "Select() Tests indicate Socket Good!" << std::endl; - std::cerr << "2) Checking with getsockopt()" << std::endl; - - int err = 1; - socklen_t optlen = 4; - if (0==getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &optlen)) - { - std::cerr << "Check_Socket() getsockopt returned :" << err; - std::cerr << ", optlen:" << optlen; - std::cerr << std::endl; - - if (err == 0) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection Complete:"; - std::cerr << std::endl; - return 1; - } - else if (err == EINPROGRESS) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection INPROGRESS"; - std::cerr << std::endl; - return 0; - } - else if ((err == ENETUNREACH) || (err == ETIMEDOUT)) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT"; - std::cerr << std::endl; - return -1; - } - else if ((err == EHOSTUNREACH) || (err == EHOSTDOWN)) - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates TCP Connection ENETUNREACH/ETIMEDOUT"; - std::cerr << std::endl; - return -1; - } - else - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " Indicates Other Error: " << err; - std::cerr << std::endl; - return -1; - } - - - } - else - { - std::cerr << "Check_Socket() getsockopt"; - std::cerr << " FAILED "; - std::cerr << std::endl; - return -1; - } -} - - -#else - -int Check_Socket(int fd) -{ - return 0; -} - -#endif diff --git a/libretroshare/src/tests/tcponudp/test_tou.sh b/libretroshare/src/tests/tcponudp/test_tou.sh deleted file mode 100755 index 3ae4f0896..000000000 --- a/libretroshare/src/tests/tcponudp/test_tou.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./test_tou -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 -# launches one instance in server mode. -$EXEC 127.0.0.1 4001 127.0.0.1 4002 > $TMPOUTPUT & -#2> udp_server1.cerr & - -# launch a second in connect mode. -$EXEC -c 127.0.0.1 4002 127.0.0.1 4001 < $EXEC -# 2> udp_server2.cerr -# pipe a bunch of data through. -# make sure the data is the same. - -# print success / failure. -sleep $EXPECTEDPERIOD -killall $EXEC - -if diff -s $EXEC $TMPOUTPUT -then - echo "SUCCESS" -else - echo "FAILURE to accurately transfer DATA" -fi - -#rm udp_server1.cerr -#rm udp_server2.cerr -rm $TMPOUTPUT - - diff --git a/libretroshare/src/tests/tcponudp/timed_tou.cc b/libretroshare/src/tests/tcponudp/timed_tou.cc deleted file mode 100644 index 5c89d88e9..000000000 --- a/libretroshare/src/tests/tcponudp/timed_tou.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* - * "$Id: pair_tou.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include -#include - -// for printing sockaddr -#include "udp/udpstack.h" - -#include "tcponudp/tou.h" -#include "tcponudp/udppeer.h" -#include "tcponudp/udprelay.h" - -#include "util/bdnet.h" - -#include "util/rsrandom.h" - -#include -#include -#include - - -/* - * This test creates the same stacks as are used in RS. - * This additionally tests the "checkFns" for the other UdpReceivers, which could potentially be modifying the data. - * obviously they shouldn't! - * - */ - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - int totalwbytes = 0; - int totalmbytes = 0; - int totalrbytes = 0; - - while(-1 != (c = getopt(argc, argv, "pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - - /* setup the local/remote addresses. - */ - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - std::cerr << "Creating with Lossy Udp Layers for further testing"; - std::cerr << std::endl; - - UdpStack *udpStack1 = new UdpStack(UDP_TEST_TIMED_LAYER,laddr); - sleep(1); - UdpStack *udpStack2 = new UdpStack(UDP_TEST_TIMED_LAYER,raddr); - - UdpSubReceiver *udpReceivers[4]; - int udpTypes[4]; - - // NOTE DHT is too hard to add at the moment. - - UdpRelayReceiver *mRelay1 = new UdpRelayReceiver(udpStack1); - udpReceivers[1] = mRelay1; - udpTypes[1] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack1->addReceiver(udpReceivers[1]); - - udpReceivers[0] = new UdpPeerReceiver(udpStack1); - udpTypes[0] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack1->addReceiver(udpReceivers[0]); - - // STACK 2. - UdpRelayReceiver *mRelay2 = new UdpRelayReceiver(udpStack2); - udpReceivers[3] = mRelay2; - udpTypes[3] = TOU_RECEIVER_TYPE_UDPRELAY; - udpStack2->addReceiver(udpReceivers[3]); - - udpReceivers[2] = new UdpPeerReceiver(udpStack2); - udpTypes[2] = TOU_RECEIVER_TYPE_UDPPEER; - udpStack2->addReceiver(udpReceivers[2]); - - tou_init((void **) udpReceivers, udpTypes, 4); - - - int sockfd = tou_socket(0, TOU_RECEIVER_TYPE_UDPPEER, 0); - int sockfd2 = tou_socket(2, TOU_RECEIVER_TYPE_UDPPEER, 0); - if ((sockfd <= 0) || (sockfd2 <= 0)) - { - std::cerr << "Failed to open socket!: "; - std::cerr << "Socket Error:" << tou_errno(sockfd) << std::endl; - std::cerr << "Socket Error:" << tou_errno(sockfd2) << std::endl; - return -1; - } - std::cerr << "Sockets Created: " << sockfd << " & " << sockfd2 << std::endl; - - std::cerr << "Socket Non-Blocking" << std::endl; - - std::cerr << "Socket1 Bound to: " << laddr << std::endl; - std::cerr << "Socket2 Bound to: " << raddr << std::endl; - - int err = 0; - - std::cerr << "Socket1 Connecting to: " << raddr << std::endl; - err = tou_connect(sockfd, (struct sockaddr *) &raddr, sizeof(raddr), 30); - - std::cerr << "Socket2 Connecting to: " << raddr << std::endl; - err = tou_connect(sockfd2, (struct sockaddr *) &laddr, sizeof(laddr), 30); - - while((!tou_connected(sockfd)) && (!tou_connected(sockfd2))) - { - usleep(100000); - std::cerr << "."; - } - - std::cerr << "Socket Connected" << std::endl; - -#define MAX_READ 20000 - - /* send data */ - int bufsize = MAX_READ; - char buffer[MAX_READ]; - char middata[MAX_READ]; - char data[MAX_READ]; - int readsize = 0; - int midsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - - rstime_t lastRead = time(NULL); - bool doneWrite = false; - bool doneRead = false; - bool blockread = false; - bool blockmid = false; - - while((!doneWrite) || (!doneRead)) - { - /* read -> write_socket... */ - usleep(10); - - if (blockread != true) - { - int readbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); - readsize = read(0, buffer, readbuf); - if (readsize) - { - //std::cerr << "read " << readsize << " / " << readbuf; - //std::cerr << std::endl; - } - } - if ((readsize == 0) && (!doneWrite)) - { - /* eof */ - doneWrite = true; - std::cerr << "Write Done Total: " << totalwbytes; - std::cerr << std::endl; - } - /* now we write */ - if ((readsize > 0) && (-1 == tou_write(sockfd, buffer, readsize))) - { - //std::cerr << "Blocked Write "; - //std::cerr << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; - blockread = true; - } - else - { - blockread = false; - totalwbytes += readsize; - - if (readsize) - { - std::cerr << "Written: " << readsize << ", Total: " << totalwbytes; - std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - } - } - - /*************** Here we read it in, and send it back out... - * so the data is flowing both ways through the UDP connection - * - *****/ - - - if (!blockmid) - { - /* read from socket 2, and write back to socket 2 */ - - int readmidbuf = 1 + RSRandom::random_u32() % (MAX_READ - 1); - if (0 < (midsize = tou_read(sockfd2, middata, readmidbuf))) - { - //std::cerr << "MidRead: " << mid << " Total: " << totalrbytes; - //std::cerr << " In Transit: " << totalwbytes - totalrbytes; - //std::cerr << std::endl; - } - } - - /* now we write */ - if ((midsize > 0) && (-1 == tou_write(sockfd2, middata, midsize))) - { - //std::cerr << "Blocked Write "; - //std::cerr << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; - blockmid = true; - } - else - { - blockmid = false; - - if (midsize > 0) - { - totalmbytes += midsize; - - std::cerr << "MidRead: " << midsize << ", Total: " << totalmbytes; - std::cerr << " => Transit => : " << totalwbytes - totalmbytes; - std::cerr << " <= Transit <= : " << totalmbytes - totalrbytes; - std::cerr << std::endl; - } - } - - /***** READ FROM FIRST SOCKET *****/ - - int ret = 0; - int readbuf2 = 1 + RSRandom::random_u32() % (MAX_READ - 1); - if (0 < (ret = tou_read(sockfd, data, readbuf2))) - { - //std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - totalrbytes += ret; - - std::cerr << "Read: " << ret << " Total: " << totalrbytes; - std::cerr << " Total In Transit: " << totalwbytes - totalrbytes; - std::cerr << std::endl; - - lastRead = time(NULL); - } - else if ((ret == 0) && (!doneRead)) - { - doneRead = true; - std::cerr << "Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - else - { - //std::cerr << "Blocked Read: " << "Error: " << tou_errno(sockfd); - //std::cerr << std::endl; -#define TIMEOUT 15 - if ((!doneRead) && (time(NULL) - lastRead > TIMEOUT)) - { - doneRead = true; - std::cerr << "TIMEOUT: Read Done Total: " << totalrbytes; - std::cerr << std::endl; - } - } - - - } - - /* this is blocking??? */ - tou_close(sockfd); - tou_close(sockfd2); - - std::cerr << "Transfer Complete: " << totalwbytes << " bytes"; - std::cerr << std::endl; - return 1; -} - diff --git a/libretroshare/src/tests/tcponudp/timed_tou.sh b/libretroshare/src/tests/tcponudp/timed_tou.sh deleted file mode 100755 index 4d2f7816c..000000000 --- a/libretroshare/src/tests/tcponudp/timed_tou.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./timed_tou -DATAFILE=./timed_tou - -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 - -$EXEC 127.0.0.1 4401 127.0.0.1 4032 < $DATAFILE > $TMPOUTPUT - -if diff -s $DATAFILE $TMPOUTPUT -then - echo "SUCCESS" -else - echo "FAILURE to accurately transfer DATA" -fi - -rm $TMPOUTPUT - diff --git a/libretroshare/src/tests/tcponudp/udp_server.cc b/libretroshare/src/tests/tcponudp/udp_server.cc deleted file mode 100644 index 1f720561a..000000000 --- a/libretroshare/src/tests/tcponudp/udp_server.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* - * "$Id: udp_server.cc,v 1.4 2007-02-18 21:46:50 rmf24 Exp $" - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - - -#include "udp/udpstack.h" -#include "tcponudp/udppeer.h" -#include "tcponudp/tcpstream.h" -#include "tcponudp/tou.h" - -#include - -#include -#include -#include - -void usage(char *name) -{ - std::cerr << "Usage: " << name; - std::cerr << " [-pco] "; - std::cerr << " "; - std::cerr << std::endl; - exit(1); - return; -} - -int main(int argc, char **argv) -{ - int c; - bool isProxy = false; - bool toConnect = false; - bool stayOpen = false; - - while(-1 != (c = getopt(argc, argv, "f:pco"))) - { - switch (c) - { - case 'p': - isProxy = true; - break; - case 'c': - toConnect = true; - break; - case 'o': - stayOpen = true; - break; - case 'f': - /* this can only work when the define below exists in tcpstream */ -#ifdef DEBUG_TCP_STREAM_EXTRA - setupBinaryCheck(std::string(optarg)); -#else - std::cerr << "Binary Check no Enabled!" << std::endl; -#endif - break; - default: - usage(argv[0]); - break; - } - } - - if (argc-optind < 4) - { - usage(argv[0]); - return 1; - } - /* setup the local/remote addresses. - */ - - - struct sockaddr_in laddr; - struct sockaddr_in raddr; - - laddr.sin_family = AF_INET; - raddr.sin_family = AF_INET; - - if ((!bdnet_inet_aton(argv[optind], &(laddr.sin_addr))) || - (!bdnet_inet_aton(argv[optind+2], &(raddr.sin_addr)))) - { - std::cerr << "Invalid addresses!" << std::endl; - usage(argv[0]); - } - - laddr.sin_port = htons(atoi(argv[optind+1])); - raddr.sin_port = htons(atoi(argv[optind+3])); - - std::cerr << "Local Address: " << laddr << std::endl; - std::cerr << "Remote Address: " << raddr << std::endl; - - UdpStack udps(laddr); - UdpPeerReceiver *upr = new UdpPeerReceiver(&udps); - udps.addReceiver(upr); - - if (!udps.okay()) - { - std::cerr << "UdpSorter not Okay (Cannot Open Local Address): " << laddr << std::endl; - exit(1); - } - - TcpStream tcp(upr); - upr->addUdpPeer(&tcp, raddr); - - if (toConnect) - { - tcp.connect(raddr, 30); - } - else - { - tcp.listenfor(raddr); - } - - while(!tcp.isConnected()) - { - sleep(1); - std::cerr << "Waiting for TCP to Connect!" << std::endl; - udps.status(std::cerr); - tcp.status(std::cerr); - tcp.tick(); - } - std::cerr << "TCP Connected***************************" << std::endl; - udps.status(std::cerr); - tcp.status(std::cerr); - std::cerr << "TCP Connected***************************" << std::endl; - - int count = 1; - - if (toConnect) - { - /* send data */ - int bufsize = 51; - char buffer[bufsize]; - int readsize = 0; - - bdnet_fcntl(0, F_SETFL, O_NONBLOCK); - - bool done = false; - bool blockread = false; - while(!done) - { - //sleep(1); - //usleep(100000); - usleep(1000); - if (blockread != true) - { - readsize = read(0, buffer, bufsize); - } - if (readsize == 0) - { - /* eof */ - done = true; - } - else if ((readsize == -1) && ( EAGAIN == errno )) - { - continue; - } - - /* now we write */ - if (-1 == tcp.write(buffer, readsize)) - blockread = true; - else - blockread = false; - - - tcp.tick(); - if (count++ % 10 == 0) - { - std::cerr << "******************************************" << std::endl; - tcp.status(std::cerr); - } - } - - tcp.closeWrite(); - - while(!tcp.widle()) - { - //sleep(1); - usleep(100000); - //usleep(1000); - tcp.tick(); - if (count++ % 10 == 0) - { - std::cerr << "Waiting for Idle()" << std::endl; - std::cerr << "******************************************" << std::endl; - tcp.status(std::cerr); - } - } - - std::cerr << "Transfer Complete: " << tcp.wbytes() << " bytes"; - std::cerr << std::endl; - return 1; - } - - /* recv data */ - int bufsize = 1523; - char data[bufsize]; - bdnet_fcntl(1,F_SETFL,O_NONBLOCK); - while(1) - { - //sleep(1); - usleep(100000); - //usleep(1000); - //int writesize = bufsize; - int ret; - if (0 < (ret = tcp.read(data, bufsize))) - { - std::cerr << "TF(" << ret << ")" << std::endl; - write(1, data, ret); - } - else if (ret == 0) - { - /* completed transfer */ - std::cerr << "Transfer complete :" << tcp.rbytes(); - std::cerr << " bytes" << std::endl; - break; - } - - tcp.tick(); - if (count++ % 10 == 0) - { - std::cerr << "******************************************" << std::endl; - tcp.status(std::cerr); - } - if ((!stayOpen) && tcp.ridle()) - { - std::cerr << "Transfer Idle after " << tcp.rbytes(); - std::cerr << " bytes" << std::endl; - close(1); - break; - } - } - - tcp.closeWrite(); - - /* tick for a bit */ - while((stayOpen) || (!tcp.ridle())) - { - tcp.tick(); - //sleep(1); - usleep(100000); - //usleep(1000); - if (count++ % 10 == 0) - { - std::cerr << "Waiting for Idle()" << std::endl; - std::cerr << "******************************************" << std::endl; - tcp.status(std::cerr); - } - } - - - if ((!stayOpen) && tcp.ridle()) - { - //std::cerr << "Transfer complete :" << tcp.rbytes(); - //std::cerr << " bytes" << std::endl; - close(1); - return 1; - } - - return 1; -} - - - - diff --git a/libretroshare/src/tests/tcponudp/udp_server.sh b/libretroshare/src/tests/tcponudp/udp_server.sh deleted file mode 100755 index 8bbd55887..000000000 --- a/libretroshare/src/tests/tcponudp/udp_server.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./udp_server -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 -# launches one instance in server mode. -$EXEC 127.0.0.1 4001 127.0.0.1 4002 > $TMPOUTPUT & -#2> udp_server1.cerr & - -# launch a second in connect mode. -$EXEC -c 127.0.0.1 4002 127.0.0.1 4001 < $EXEC -# 2> udp_server2.cerr -# pipe a bunch of data through. -# make sure the data is the same. - -# print success / failure. -sleep $EXPECTEDPERIOD -killall $EXEC - -if diff -s $EXEC $TMPOUTPUT -then - echo "SUCCESS" -else - echo "FAILURE to accurately transfer DATA" -fi - -#rm udp_server1.cerr -#rm udp_server2.cerr -rm $TMPOUTPUT - - diff --git a/libretroshare/src/tests/tcponudp/udpsock_test.cc b/libretroshare/src/tests/tcponudp/udpsock_test.cc deleted file mode 100644 index bc9aeaf86..000000000 --- a/libretroshare/src/tests/tcponudp/udpsock_test.cc +++ /dev/null @@ -1,92 +0,0 @@ -/* - * libretroshare/src/tcponudp: udpsock_test.cc - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "udptestfn.h" -#include "udp/udplayer.h" -#include - -#define MAX_PEERS 16 - -int main(int argc, char **argv) -{ - /* get local and remote addresses */ - struct sockaddr_in local; - struct sockaddr_in peers[MAX_PEERS]; - int numpeers = 0; - int i,j; - - local.sin_family = AF_INET; - inet_aton("127.0.0.1", &(local.sin_addr)); - local.sin_port = htons(8767); - - for(i = 0; i < MAX_PEERS; i++) - { - peers[i].sin_family = AF_INET; - inet_aton("127.0.0.1", &(peers[i].sin_addr)); - peers[i].sin_port = htons(8768); - } - - if (argc < 3) - { - std::cerr << "Usage: " << argv[0] << " [ udp_server1.cerr & - -$EXEC 6002 6001 6003 6004 6005 & -$EXEC 6003 6002 6001 6004 6005 & -$EXEC 6004 6002 6003 6001 6005 & -$EXEC 6005 6002 6003 6004 6001 & - -## print success / failure. -sleep $EXPECTEDPERIOD -killall $EXEC - -# -#if diff -s $EXEC $TMPOUTPUT -#then -# echo "SUCCESS" -#else -# echo "FAILURE to accurately transfer DATA" -#fi -# -##rm udp_server1.cerr -##rm udp_server2.cerr -#rm $TMPOUTPUT -## -### diff --git a/libretroshare/src/tests/tcponudp/udpsort_test.cc b/libretroshare/src/tests/tcponudp/udpsort_test.cc deleted file mode 100644 index a4d025a2a..000000000 --- a/libretroshare/src/tests/tcponudp/udpsort_test.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * libretroshare/src/tcponudp: udpsort_test.cc - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "udptestfn.h" -#include "udp/udpstack.h" -#include "tcponudp/udppeer.h" - -#define MAX_PEERS 16 - -int main(int argc, char **argv) -{ - /* get local and remote addresses */ - struct sockaddr_in local; - struct sockaddr_in peers[MAX_PEERS]; - int numpeers = 0; - int i,j; - - local.sin_family = AF_INET; - inet_aton("127.0.0.1", &(local.sin_addr)); - local.sin_port = htons(8767); - - for(i = 0; i < MAX_PEERS; i++) - { - peers[i].sin_family = AF_INET; - inet_aton("127.0.0.1", &(peers[i].sin_addr)); - peers[i].sin_port = htons(8768); - } - - if (argc < 3) - { - std::cerr << "Usage: " << argv[0] << " [addUdpPeer(pt, peers[i-2]); - } - - int size = 12; - void *data = malloc(size); - int ttl = 64; - - /* push packets to the peer */ - for(i = 0; i < 60; i++) - { - sleep(1); - for(j = 0; j < numpeers; j++) - { - udps.sendPkt(data, size, peers[j], ttl); - } - } - return 1; -} - - - diff --git a/libretroshare/src/tests/tcponudp/udpsort_test.sh b/libretroshare/src/tests/tcponudp/udpsort_test.sh deleted file mode 100755 index c6023e93b..000000000 --- a/libretroshare/src/tests/tcponudp/udpsort_test.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -# Script to Test the udp_server code. - -EXEC=./udpsort_test -TMPOUTPUT=tmpoutput$$ -EXPECTEDPERIOD=10 -$EXEC 6001 6002 6003 6004 6005 & -#2> udp_server1.cerr & - -$EXEC 6002 6001 6003 6004 6005 & -$EXEC 6003 6002 6001 6004 6005 & -$EXEC 6004 6002 6003 6001 6005 & -$EXEC 6005 6002 6003 6004 6001 & - -## print success / failure. -sleep $EXPECTEDPERIOD -killall $EXEC - -# -#if diff -s $EXEC $TMPOUTPUT -#then -# echo "SUCCESS" -#else -# echo "FAILURE to accurately transfer DATA" -#fi -# -##rm udp_server1.cerr -##rm udp_server2.cerr -#rm $TMPOUTPUT -## -### diff --git a/libretroshare/src/tests/tcponudp/udptestfn.cc b/libretroshare/src/tests/tcponudp/udptestfn.cc deleted file mode 100644 index 12c7bd264..000000000 --- a/libretroshare/src/tests/tcponudp/udptestfn.cc +++ /dev/null @@ -1,49 +0,0 @@ -/* - * libretroshare/src/tcponudp: udptestfn.cc - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "udptestfn.h" - -int UdpRecvTest::recvPkt(void *data, int size, struct sockaddr_in &from) -{ - /* print packet information */ - std::cerr << "UdpRecvTest::recvPkt(" << size << ") from: " << from; - std::cerr << std::endl; - return -1; -} - -UdpPeerTest::UdpPeerTest(struct sockaddr_in &addr) - :raddr(addr) -{ - return; -} - -void UdpPeerTest::recvPkt(void *data, int size) -{ - /* print packet information */ - std::cerr << "UdpPeerTest::recvPkt(" << size << ") from: " << raddr; - std::cerr << std::endl; -} - - diff --git a/libretroshare/src/tests/tcponudp/udptestfn.h b/libretroshare/src/tests/tcponudp/udptestfn.h deleted file mode 100644 index d25a23223..000000000 --- a/libretroshare/src/tests/tcponudp/udptestfn.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * libretroshare/src/tcponudp: udptestfn.h - * - * TCP-on-UDP (tou) network interface for RetroShare. - * - * Copyright 2007-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "udp/udplayer.h" -#include "udp/udpstack.h" -#include "tcponudp/udppeer.h" - -//#include "udpsorter.h" - -#ifndef TOU_UDP_TEST_FN_H -#define TOU_UDP_TEST_FN_H - -class UdpRecvTest: public UdpReceiver -{ - public: -virtual int recvPkt(void *data, int size, struct sockaddr_in &from); -virtual int status(std::ostream&) { return 0; } -}; - - -class UdpPeerTest: public UdpPeer -{ - public: - UdpPeerTest(struct sockaddr_in &addr); -virtual void recvPkt(void *data, int size); - - struct sockaddr_in raddr; -}; - - -#endif diff --git a/libretroshare/src/tests/upnp/upnpforward.cc b/libretroshare/src/tests/upnp/upnpforward.cc deleted file mode 100644 index 50394d3f1..000000000 --- a/libretroshare/src/tests/upnp/upnpforward.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* - * libretroshare/src/upnp: upnpforward.cc - * - * Upnp Manual Test for RetroShare. - * - * Copyright 2012 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/* - * A Upnp utility to forward a port, specified on the commandline. - */ - -#ifdef WIN32 -#include "util/rswin.h" -#endif - -#include "util/utest.h" -#include "upnp/upnphandler_linux.h" - -INITTEST() ; - -#include - -void usage(char *name) -{ - std::cerr << "Usage: " << name << " [-i ] [-e ]"; - std::cerr << std::endl; -} - -int main(int argc, char **argv) -{ - int c; - uint16_t internalPort = 7812; - uint16_t externalPort = 7812; - -#ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); -#endif - -#ifdef WIN32 - // Windows Networking Init. - WORD wVerReq = MAKEWORD(2,2); - WSADATA wsaData; - - if (0 != WSAStartup(wVerReq, &wsaData)) - { - std::cerr << "Failed to Startup Windows Networking"; - std::cerr << std::endl; - } - else - { - std::cerr << "Started Windows Networking"; - std::cerr << std::endl; - } - -#endif - - - while(-1 != (c = getopt(argc, argv, "i:e:"))) - { - switch (c) - { - case 'i': - internalPort = atoi(optarg); - break; - case 'e': - externalPort = atoi(optarg); - break; - default: - usage(argv[0]); - break; - } - } - - - /* create a upnphandler object */ - //pqiNetAssistFirewall *upnp; - upnphandler *upnp; - - upnp = new upnphandler(); - - /* setup */ - upnp->setInternalPort(internalPort); - upnp->setExternalPort(externalPort); - - /* launch thread */ - upnp->enable(true); - - /* give it a chance to work its magic. */ - sleep(30); - - FINALREPORT("upnpforward") ; - return TESTRESULT(); -} - - - diff --git a/libretroshare/src/tests/util/aes_test.cc b/libretroshare/src/tests/util/aes_test.cc deleted file mode 100644 index cb0d00447..000000000 --- a/libretroshare/src/tests/util/aes_test.cc +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * "$Id: dirtest.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $" - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 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 "retroshare@lunamutt.com". - * - */ - - - -#include "util/rsaes.h" -#include "util/utest.h" -#include - -#include -#include -#include -#include - -void printHelp(int argc,char *argv[]) -{ - std::cerr << argv[0] << ": tests AES encryption/decryption functions." << std::endl; - std::cerr << "Usage: " << argv[0] << std::endl ; -} - -void printHex(unsigned char *data,uint32_t length) -{ - static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ; - static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ; - - for(uint32_t j = 0; j < length; j++) - { - std::cerr << outh[ (data[j]>>4) ] ; - std::cerr << outh[ data[j] & 0xf ] ; - } -} - - -INITTEST() ; - -int main(int argc,char *argv[]) -{ - std::string inputfile ; - argstream as(argc,argv) ; - - as >> help() ; - - as.defaultErrorHandling() ; - - std::cerr << "Testing AES crypt" << std::endl; - - std::string source_string = "This is a very secret string, but ultimately it will always be decyphered" ; - std::cerr << "Input string: length=" << source_string.length() << ", s=\"" << source_string << "\"" << std::endl; - - unsigned char key_data[16] ; - unsigned char salt[8] ; - - for(int i=0;i<16;++i) - key_data[i] = lrand48() & 0xff ; - - std::cerr << "Key: " ; printHex(key_data,16); - std::cerr << std::endl; - - for(int i=5;i - -#include -#include "util/rscompress.h" -#include "util/rsdir.h" -#include "util/utest.h" -#include "util/argstream.h" - -#include -#include -#include -#include - -void printHelp(int argc,char *argv[]) -{ - std::cerr << argv[0] << ": tests AES encryption/decryption functions." << std::endl; - std::cerr << "Usage: " << argv[0] << std::endl ; -} - -bool compareStrings(const std::string& s1,const std::string& s2) -{ - uint32_t L = std::min(s1.length(),s2.length()) ; - - for(int i=0;i>4) ] ; - std::cerr << outh[ data[j] & 0xf ] ; - } -} - -INITTEST() ; - -int main(int argc,char *argv[]) -{ - std::string inputfile ; - argstream as(argc,argv) ; - - as >> help() ; - - as.defaultErrorHandling() ; - - std::cerr << "Testing RsCompress" << std::endl; - - std::string source_string = "This is a very secret string, but ultimately it will always be decyphered \ - ar cqs libretroshare.a temp/linux-g++-64/obj/p3bitdht.o \ - temp/linux-g++-64/obj/p3bitdht_interface.o \ - temp/linux-g++-64/obj/p3bitdht_peers.o \ - temp/linux-g++-64/obj/p3bitdht_peernet.o \ - temp/linux-g++-64/obj/p3bitdht_relay.o \ - temp/linux-g++-64/obj/connectstatebox.o temp/linux-g++-64/obj/udppeer.o \ - temp/linux-g++-64/obj/tcppacket.o temp/linux-g++-64/obj/tcpstream.o \ - temp/linux-g++-64/obj/tou.o temp/linux-g++-64/obj/bss_tou.o \ - temp/linux-g++-64/obj/udpstunner.o temp/linux-g++-64/obj/udprelay.o \ - temp/linux-g++-64/obj/cachestrapper.o temp/linux-g++-64/obj/fimonitor.o \ - temp/linux-g++-64/obj/findex.o temp/linux-g++-64/obj/fistore.o \ - temp/linux-g++-64/obj/rsexpr.o temp/linux-g++-64/obj/ftchunkmap.o \ - temp/linux-g++-64/obj/ftcontroller.o \ - temp/linux-g++-64/obj/ftdatamultiplex.o temp/linux-g++-64/obj/ftdbase.o \ - temp/linux-g++-64/obj/ftextralist.o temp/linux-g++-64/obj/ftfilecreator.o \ - temp/linux-g++-64/obj/ftfileprovider.o \ - temp/linux-g++-64/obj/ftfilesearch.o temp/linux-g++-64/obj/ftserver.o \ - temp/linux-g++-64/obj/fttransfermodule.o \ - temp/linux-g++-64/obj/ftturtlefiletransferitem.o \ - temp/linux-g++-64/obj/authgpg.o temp/linux-g++-64/obj/authssl.o \ - temp/linux-g++-64/obj/pgphandler.o temp/linux-g++-64/obj/pgpkeyutil.o \ - temp/linux-g++-64/obj/rscertificate.o temp/linux-g++-64/obj/p3cfgmgr.o \ - temp/linux-g++-64/obj/p3peermgr.o temp/linux-g++-64/obj/p3linkmgr.o \ - temp/linux-g++-64/obj/p3netmgr.o temp/linux-g++-64/obj/p3notify.o \ - temp/linux-g++-64/obj/pqiqos.o temp/linux-g++-64/obj/pqiarchive.o \ - temp/linux-g++-64/obj/pqibin.o temp/linux-g++-64/obj/pqihandler.o \ - temp/linux-g++-64/obj/p3historymgr.o temp/linux-g++-64/obj/pqiipset.o \ - temp/linux-g++-64/obj/pqiloopback.o temp/linux-g++-64/obj/pqimonitor.o \ - temp/linux-g++-64/obj/pqinetwork.o temp/linux-g++-64/obj/pqiperson.o \ - temp/linux-g++-64/obj/pqipersongrp.o temp/linux-g++-64/obj/pqisecurity.o \ - temp/linux-g++-64/obj/pqiservice.o temp/linux-g++-64/obj/pqissl.o \ - temp/linux-g++-64/obj/pqissllistener.o \ - temp/linux-g++-64/obj/pqisslpersongrp.o temp/linux-g++-64/obj/pqissludp.o \ - temp/linux-g++-64/obj/pqisslproxy.o temp/linux-g++-64/obj/pqistore.o \ - temp/linux-g++-64/obj/pqistreamer.o \ - temp/linux-g++-64/obj/pqithreadstreamer.o \ - temp/linux-g++-64/obj/pqiqosstreamer.o temp/linux-g++-64/obj/sslfns.o \ - temp/linux-g++-64/obj/pqinetstatebox.o \ - temp/linux-g++-64/obj/p3face-config.o temp/linux-g++-64/obj/p3face-msgs.o \ - temp/linux-g++-64/obj/p3face-server.o temp/linux-g++-64/obj/p3history.o \ - temp/linux-g++-64/obj/p3msgs.o temp/linux-g++-64/obj/p3peers.o \ - temp/linux-g++-64/obj/p3status.o temp/linux-g++-64/obj/rsinit.o \ - temp/linux-g++-64/obj/rsloginhandler.o temp/linux-g++-64/obj/rstypes.o \ - temp/linux-g++-64/obj/p3serverconfig.o \ - temp/linux-g++-64/obj/pluginmanager.o temp/linux-g++-64/obj/dlfcn_win32.o \ - temp/linux-g++-64/obj/rspluginitems.o \ - temp/linux-g++-64/obj/rsbaseserial.o \ - temp/linux-g++-64/obj/rsfiletransferitems.o \ - temp/linux-g++-64/obj/rsserviceserialiser.o \ - temp/linux-g++-64/obj/rsconfigitems.o \ - temp/linux-g++-64/obj/rshistoryitems.o temp/linux-g++-64/obj/rsmsgitems.o \ - temp/linux-g++-64/obj/rsserial.o temp/linux-g++-64/obj/rsstatusitems.o \ - temp/linux-g++-64/obj/rstlvaddrs.o temp/linux-g++-64/obj/rstlvbase.o \ - temp/linux-g++-64/obj/rstlvfileitem.o temp/linux-g++-64/obj/rstlvimage.o \ - temp/linux-g++-64/obj/rstlvkeys.o temp/linux-g++-64/obj/rstlvkvwide.o \ - temp/linux-g++-64/obj/rstlvtypes.o temp/linux-g++-64/obj/rstlvutil.o \ - temp/linux-g++-64/obj/rstlvdsdv.o temp/linux-g++-64/obj/rsdsdvitems.o \ - temp/linux-g++-64/obj/rstlvbanlist.o \ - temp/linux-g++-64/obj/rsbanlistitems.o \ - temp/linux-g++-64/obj/rsbwctrlitems.o \ - temp/linux-g++-64/obj/rsdiscovery2items.o \ - temp/linux-g++-64/obj/rsheartbeatitems.o \ - temp/linux-g++-64/obj/rsrttitems.o temp/linux-g++-64/obj/p3chatservice.o \ - temp/linux-g++-64/obj/p3msgservice.o temp/linux-g++-64/obj/p3service.o \ - temp/linux-g++-64/obj/p3statusservice.o temp/linux-g++-64/obj/p3dsdv.o \ - temp/linux-g++-64/obj/p3banlist.o temp/linux-g++-64/obj/p3bwctrl.o \ - temp/linux-g++-64/obj/p3discovery2.o temp/linux-g++-64/obj/p3heartbeat.o \ - temp/linux-g++-64/obj/p3rtt.o temp/linux-g++-64/obj/p3turtle.o \ - temp/linux-g++-64/obj/rsturtleitem.o \ - temp/linux-g++-64/obj/folderiterator.o temp/linux-g++-64/obj/rsdebug.o \ - temp/linux-g++-64/obj/rscompress.o temp/linux-g++-64/obj/smallobject.o \ - temp/linux-g++-64/obj/rsdir.o temp/linux-g++-64/obj/rsdiscspace.o \ - temp/linux-g++-64/obj/rsnet.o temp/linux-g++-64/obj/rsnet_ss.o \ - temp/linux-g++-64/obj/extaddrfinder.o temp/linux-g++-64/obj/dnsresolver.o \ - temp/linux-g++-64/obj/rsprint.o temp/linux-g++-64/obj/rsstring.o \ - temp/linux-g++-64/obj/rsthreads.o temp/linux-g++-64/obj/rsversion.o \ - temp/linux-g++-64/obj/rswin.o temp/linux-g++-64/obj/rsaes.o \ - temp/linux-g++-64/obj/rsrandom.o temp/linux-g++-64/obj/rstickevent.o \ - temp/linux-g++-64/obj/UPnPBase.o \ - temp/linux-g++-64/obj/upnphandler_linux.o \ - temp/linux-g++-64/obj/rsnxsitems.o temp/linux-g++-64/obj/rsdataservice.o \ - temp/linux-g++-64/obj/rsgenexchange.o \ - temp/linux-g++-64/obj/rsgxsnetservice.o temp/linux-g++-64/obj/rsgxsdata.o \ - temp/linux-g++-64/obj/rsgxsitems.o \ - temp/linux-g++-64/obj/rsgxsdataaccess.o temp/linux-g++-64/obj/retrodb.o \ - temp/linux-g++-64/obj/contentvalue.o temp/linux-g++-64/obj/rsdbbind.o \ - temp/linux-g++-64/obj/gxssecurity.o temp/linux-g++-64/obj/gxstokenqueue.o \ - temp/linux-g++-64/obj/rsgxsnetutils.o temp/linux-g++-64/obj/rsgxsutil.o \ - temp/linux-g++-64/obj/p3idservice.o temp/linux-g++-64/obj/rsgxsiditems.o \ - temp/linux-g++-64/obj/p3gxscircles.o \ - temp/linux-g++-64/obj/rsgxscircleitems.o \ - temp/linux-g++-64/obj/p3gxsforums.o \ - temp/linux-g++-64/obj/rsgxsforumitems.o \ - temp/linux-g++-64/obj/p3gxschannels.o temp/linux-g++-64/obj/p3gxscommon.o \ - temp/linux-g++-64/obj/rsgxscommentitems.o \ - temp/linux-g++-64/obj/rsgxschannelitems.o temp/linux-g++-64/obj/p3wiki.o \ - temp/linux-g++-64/obj/rswikiitems.o temp/linux-g++-64/obj/p3wire.o \ - temp/linux-g++-64/obj/rswireitems.o temp/linux-g++-64/obj/p3posted.o \ - temp/linux-g++-64/obj/rsposteditems.o \ - temp/linux-g++-64/obj/p3photoservice.o \ - temp/linux-g++-64/obj/rsphotoitems.o" ; - - for(int i=0;i<5;++i) - source_string = source_string+source_string ; - - source_string = source_string.substr(0,550000) ; - - for(int i=0;i - -int processpath(std::string path); - -int main() -{ - - std::string path1 = "/home/tst1//test2///test3/"; - std::string path2 = "home2/tst4//test5///test6"; - std::string path3 = "//home3"; - std::string path4 = "//"; - std::string path5 = "/a/b/c/d/"; - std::string path6 = "a//b/c//d"; - - processpath(path1); - processpath(path2); - processpath(path3); - processpath(path4); - processpath(path5); - processpath(path6); - - return 1; -} - - -int processpath(std::string path) -{ - std::string pathtogo = path; - while(pathtogo != "") - { - std::string basedir = RsDirUtil::getRootDir(pathtogo); - std::string rempath = RsDirUtil::removeRootDir(pathtogo); - std::string topdir = RsDirUtil::getTopDir(pathtogo); - std::string remtoppath = RsDirUtil::removeTopDir(pathtogo); - - std::cerr << "Processing: \"" << pathtogo << "\"" << std::endl; - std::cerr << "\tRootDir : \"" << basedir << "\"" << std::endl; - std::cerr << "\tRemaining: \"" << rempath << "\"" << std::endl; - std::cerr << "\tTopDir : \"" << topdir << "\"" << std::endl; - std::cerr << "\tRemaining(Top): \"" << remtoppath << "\"" << std::endl; - std::cerr << std::endl; - - pathtogo = rempath; - } - return 1; -} - - - - - diff --git a/libretroshare/src/tests/util/dirtest.cc b/libretroshare/src/tests/util/dirtest.cc deleted file mode 100644 index 862a77913..000000000 --- a/libretroshare/src/tests/util/dirtest.cc +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * "$Id: dirtest.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $" - * - * RetroShare C++ Interface. - * - * Copyright 2004-2007 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - - -#include "util/rsdir.h" -#include "util/utest.h" - -#include -#include -#include - -bool testRsDirUtils(std::string path); - -INITTEST() ; - -int main() -{ - - std::list dirs; - std::list::iterator it; - dirs.push_back("/incoming/htuyr/file.txt"); - dirs.push_back("/incoming/htuyr/file.txt "); - dirs.push_back("/incoming/htuyr/file.txt/"); - dirs.push_back("/incoming/htuyr/file.txt//"); - dirs.push_back("/incoming/htuyr//file.txt//"); - dirs.push_back("/incoming/htuyr//file .txt"); - dirs.push_back("/incoming/htuyr/Q"); - dirs.push_back("/incoming/htuyr/Q//"); - dirs.push_back("/incoming/htuyr/Q/"); - dirs.push_back("/incoming/htuyr/Q/text"); - dirs.push_back("/home/tst1//test2///test3/"); - dirs.push_back("home2/tst4//test5///test6"); - dirs.push_back("//home3"); - dirs.push_back("//"); - dirs.push_back("A"); - dirs.push_back("ABC"); - dirs.push_back("////ABC////"); - dirs.push_back("A/B/C"); - - for(it = dirs.begin(); it != dirs.end(); it++) - { - testRsDirUtils(*it); - } - - FINALREPORT("dirtest"); - - return TESTRESULT() ; -} - -bool testRsDirUtils(std::string path) -{ - - std::cerr << "RsUtilTest input: [" << path << "]"; - std::cerr << std::endl; - - std::string top = RsDirUtil::getTopDir(path); - std::string root = RsDirUtil::getRootDir(path); - std::string topdirs = RsDirUtil::removeRootDir(path); - std::string topdirs2 = RsDirUtil::removeRootDirs(path, root); - std::string restdirs ; - RsDirUtil::removeTopDir(path,restdirs); - std::list split; - std::list::iterator it; - RsDirUtil::breakupDirList(path, split); - - std::cerr << "\tTop: [" << top << "]"; - std::cerr << std::endl; - std::cerr << "\tRest: [" << restdirs << "]"; - std::cerr << std::endl; - - std::cerr << "\tRoot: [" << root << "]"; - std::cerr << std::endl; - std::cerr << "\tRemoveRoot: [" << topdirs << "]"; - std::cerr << std::endl; - std::cerr << "\tSplit Up "; - for(it = split.begin(); it != split.end(); it++) - { - std::cerr << ":" << (*it); - } - std::cerr << std::endl; - std::cerr << std::endl; - return true; -} diff --git a/libretroshare/src/tests/util/sha1_test.cc b/libretroshare/src/tests/util/sha1_test.cc deleted file mode 100644 index 84481aec5..000000000 --- a/libretroshare/src/tests/util/sha1_test.cc +++ /dev/null @@ -1,104 +0,0 @@ - -/* - * "$Id: dirtest.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $" - * - * RetroShare C++ Interface. - * - * Copyright 2012-2012 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 "retroshare@lunamutt.com". - * - */ - - - -#include "util/rsdir.h" -#include "util/utest.h" -#include - -#include -#include -#include -#include - -void printHelp(int argc,char *argv[]) -{ - std::cerr << argv[0] << ": test RS sha1sum class implementation." << std::endl; - std::cerr << "Usage: " << argv[0] << " [test file]" << std::endl ; -} - -INITTEST() ; - -int main(int argc,char *argv[]) -{ - std::string inputfile ; - argstream as(argc,argv) ; - - as >> parameter('i',"input",inputfile,"input file name to hash",false) - >> help() ; - - as.defaultErrorHandling() ; - - if(inputfile.empty()) - inputfile = argv[0] ; - - FILE *f = RsDirUtil::rs_fopen(inputfile.c_str(),"r") ; - - CHECK(f != NULL) ; - - std::cerr << "Testing sha1" << std::endl; - uint32_t SIZE = 1024*1024 ; - unsigned char *buf = new unsigned char[SIZE] ; - int len = fread(buf,1,SIZE,f) ; - - std::cerr << "Read " << len << " bytes" << std::endl; - - Sha1CheckSum sum = RsDirUtil::sha1sum(buf,len) ; - { - std::cerr << std::hex << sum.fourbytes[0] << std::endl; - std::cerr << "New method : " << sum.toStdString() << std::endl; - } - - std::string hash ; - uint64_t size ; - RsDirUtil::getFileHash(inputfile.c_str(),hash,size) ; - - std::cerr << "Old method : " << hash << std::endl; - CHECK(hash == sum.toStdString()) ; - - Sha1CheckSum H(hash) ; - std::cerr << "Hashed transformed: " << H.toStdString() << std::endl; - CHECK(hash == H.toStdString()) ; - - std::cerr << "Computing all chunk hashes:" << std::endl; - - fseek(f,0,SEEK_SET) ; - int n=0 ; - - while(len = fread(buf,1,SIZE,f)) - { - Sha1CheckSum sum = RsDirUtil::sha1sum(buf,len) ; - std::cerr << "Chunk " << n << ": " << sum.toStdString() << std::endl; - n++; - } - - fclose(f) ; - - FINALREPORT("Sha1Test") ; - return TESTRESULT() ; -} - diff --git a/libretroshare/src/tests/util/test_fifo.cpp b/libretroshare/src/tests/util/test_fifo.cpp deleted file mode 100644 index 822117e5d..000000000 --- a/libretroshare/src/tests/util/test_fifo.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// COMPILE_LINE: g++ test_fifo.cpp -o test_fifo -lstdc++ -I.. -// -// This is a test program for fifo previewing of files. -// Usage: -// test_fifo -i [movie file] -// -// The program creates a named pipe /tmp/fifo.avi on Linux, \\.\pipe\fifo.avi on Windows to be played with e.g. mplayer -// On Windows the mplayer needs the argument -noidx, because the pipe is not seekable -// -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef WIN32 -#include -#endif - -#ifdef WIN32 -#define myFIFO TEXT("\\\\.\\pipe\\fifo.avi") -#else -#define myFIFO "/tmp/fifo.avi" -#endif - -int main(int argc,char *argv[]) -{ - try - { - std::string movie_name ; - - argstream as(argc,argv) ; - - as >> parameter('i',"input",movie_name,"file name of the movie to preview",true) - >> help() ; - - as.defaultErrorHandling() ; - - -#ifdef WIN32 - HANDLE fifo = CreateNamedPipe(myFIFO, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT , 2, 1024, 1024, 2000, NULL); -#else - int status, num, fifo; - umask(0); - if (mkfifo(myFIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) - throw std::runtime_error("Cannot create fifo") ; - - fifo = open(myFIFO, O_WRONLY); - - std::cerr << "Opening fifo = " << fifo << " with file name " << myFIFO << std::endl; -#endif - -#ifdef WIN32 - if(fifo == INVALID_HANDLE_VALUE) -#else - if(fifo < 0) -#endif - { - printf("\nCan't open fifo: %s \n", strerror(errno)); - return 0; - } - -#ifdef WIN32 - printf("pipe=%p\n", fifo); - - printf("connect...\n"); - bool connected = ConnectNamedPipe(fifo, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); - if (!connected) { - printf("ConnectNamedPipe failed. error=%ld\n", GetLastError()); - return -1; - } - printf("...connected\n"); -#endif - - static const int SIZE = 1024*1024 ; // 1 MB - - void *membuf = malloc(SIZE) ; - FILE *f = fopen(movie_name.c_str(),"rb") ; - int chunk = 0; - - if(f == NULL) - throw std::runtime_error("Cannot open movie to stream into fifo") ; - - while(true) - { - int n = fread(membuf, 1, SIZE, f) ; - - if(n == 0) - break ; - -#ifdef WIN32 - DWORD dwNumberOfBytesWritten; - if (!WriteFile(fifo, membuf, n, &dwNumberOfBytesWritten, NULL) || dwNumberOfBytesWritten != (DWORD) n) { - printf("WriteFile failed. error=%ld\n", GetLastError()); -#else - if(write(fifo,membuf,SIZE) != n) { -#endif - throw std::runtime_error("Could not write chunk to fifo") ; - } - - std::cerr << "Streamed chunk " << chunk << std::endl; - if(n < SIZE) - break ; - - chunk++ ; - } - - fclose(f) ; - free(membuf) ; - -#ifdef WIN32 -// FlushFileBuffers(fifo); - DisconnectNamedPipe(fifo); -#endif - - std::cerr << "Sleeping 60 sec." << std::endl; -#ifdef WIN32 - Sleep(60000) ; - CloseHandle(fifo); -#else - sleep(60) ; - close(fifo) ; -#endif - - return 0 ; - } - catch(std::exception& e) - { - std::cerr << "Exception caught: " << e.what() << std::endl; - } -} - - diff --git a/libretroshare/src/tests/util/testcontentvalue.cpp b/libretroshare/src/tests/util/testcontentvalue.cpp deleted file mode 100644 index 17993aaab..000000000 --- a/libretroshare/src/tests/util/testcontentvalue.cpp +++ /dev/null @@ -1,374 +0,0 @@ - -#include - -#include "retrodb.h" -#include "utest.h" - -bool operator==(const ContentValue& lCV, ContentValue& rCV){ - - std::map leftKtMap, rightKtMap; - lCV.getKeyTypeMap(leftKtMap); - rCV.getKeyTypeMap(rightKtMap); - - return (leftKtMap == rightKtMap); -} - - -/*! - * Test content value ability to take a set of data and ability to get it out - * For all data types - */ -void testEnterAndRetrieve(); - -/*! - * Check to see if copy constructor intialises - * 'this' correctly - */ -void testCopyConstructor(); - -/*! - * check that key type map returned is consistent - * with data contained in ContentValue - */ -void testGetKeyTypeMap(); - -/*! - * Test the clearing functionality - */ -void testClear(); - -/*! - * check errors are meaningful - */ -void testErrors(); - -/*! - * enter the same key twice and ensure previous data gets overwritten - * - */ -void testSameKey(); - - -INITTEST(); - -int main(){ - - testEnterAndRetrieve(); - testCopyConstructor(); - testClear(); - testSameKey(); - testGetKeyTypeMap(); - testErrors(); - - FINALREPORT("TEST_CONTENT_VALUE"); -} - - -void testSameKey(){ - - - ContentValue cv; - - // test data - - std::string src = "adalkjalfalfalfkal"; - const char* data = src.data(); - uint32_t data_len = src.length(); - std::string data_key = "private_key"; - cv.put(data_key, data_len, data); - - std::string other_src = "daldko5202402224"; - data_len = other_src.length(); - data = other_src.data(); - - cv.put(data_key, data_len, data); - - uint32_t val_len; - char* val; - cv.getAsData(data_key, val_len, val); - std::string str_val(val, val_len); - - - CHECK(str_val == other_src); - - // now check string - - std::string key = "peer"; - cv.put(key, std::string("sexy_girl")); - cv.put(key, std::string("manly man")); - - std::string val_str; - cv.getAsString(key, val_str); - - CHECK(val_str == "manly man"); - - // and double - - cv.put(key, 4.); - cv.put(key, 32.); - double val_d; - cv.getAsDouble(key, val_d); - CHECK(val_d == 32.); - - // and int64 - int64_t large(20420492040123); - cv.put(key, large); - cv.put(key, large+34); - int64_t val_i64; - cv.getAsInt64(key, val_i64); - - CHECK(val_i64 == large+34); - - // and bool - - cv.put(key, false); - cv.put(key, true); - bool bool_val = false; - cv.getAsBool(key, bool_val); - - CHECK(bool_val == true); - - // and int32 - - int32_t medium = 20432123; - cv.put(key, medium); - cv.put(key, medium+34); - int32_t val_i32; - cv.getAsInt32(key, val_i32); - - CHECK(val_i32 == medium+34); - - REPORT("testSameKey()"); -} - - -void testErrors(){ - - - ContentValue cv; - int32_t val_32; - int64_t val_64; - char* data; - uint32_t data_len; - std::string val_str; - bool val_bool; - double val_d; - CHECK(!cv.getAsInt32("dda", val_32)); - CHECK(!cv.getAsInt64("dda", val_64)); - CHECK(!cv.getAsData("ds", data_len, data)); - CHECK(!cv.getAsString("d3536356336356356s", val_str)); - CHECK(!cv.getAsBool("d424s", val_bool)); - CHECK(!cv.getAsDouble("daads", val_d)); - - REPORT("testErrors()"); -} - -void testEnterAndRetrieve(){ - - // INT 32 - int32_t value32 = 1, retval32; - std::string key = "one"; - - ContentValue cv; - cv.put(key, value32); - - cv.getAsInt32(key, retval32); - CHECK(value32 == retval32); - - // INT 64 - int64_t value64 = 423425242, retval64; - key = "int64"; - cv.put(key, value64); - cv.getAsInt64(key, retval64); - CHECK(value64 == retval64); - - - // Double - double dvalue = 3.5, retvaldbl; - key = "double"; - cv.put(key, dvalue); - cv.getAsDouble(key, retvaldbl); - CHECK(dvalue == retvaldbl ); - - // BLOB - uint32_t data_len = 45, get_len = 0; - - char* src = new char[data_len]; - char* get_src = NULL; - memset(src, '$', data_len); - key = "data"; - cv.put(key, data_len, src); - - cv.getAsData(key, get_len, get_src); - - bool fine = true; - - CHECK(get_len = data_len); - - if(data_len == get_len){ - - for(int i=0; i < data_len; i++){ - - if(src[i] != get_src[i]) - fine &= false; - - } - } - - delete[] src; - CHECK(fine); - - // STRING - std::string strVal = "whoo", getVal(""); - key = "string"; - cv.put(key, strVal); - cv.getAsString(key, getVal); - - CHECK(getVal == strVal); - - - // BOOL - bool mefalse = false, retvalBool; - key = "bool"; - cv.put(key, mefalse); - cv.getAsBool(key, retvalBool); - CHECK(mefalse == retvalBool); - - cv.clear(); - - REPORT("testEnterAndRetrieve()"); -} - -void testGetKeyTypeMap(){ - - ContentValue cv; - std::string key1="key1", key2="key2", key3="key3", key4="key4"; - std::string key1_val; - int32_t key2_val = 42; - double key3_val = 23; - int64_t key4_val = 42052094224; - - cv.put(key1, key1_val); - cv.put(key2, key2_val); - cv.put(key3, key3_val); - cv.put(key4, key4_val); - - std::map kvMap; - - cv.getKeyTypeMap(kvMap); - - CHECK(kvMap.size() == 4); - CHECK(kvMap[key1] == ContentValue::STRING_TYPE); - CHECK(kvMap[key2] == ContentValue::INT32_TYPE); - CHECK(kvMap[key3] == ContentValue::DOUBLE_TYPE); - CHECK(kvMap[key4] == ContentValue::INT64_TYPE); - - REPORT("testGetKeyTypeMap()"); -} - -void testCopyConstructor(){ - - ContentValue cv1; - - // INT 32 - int value32 = 1; - std::string key = "one"; - - cv1.put(key, value32); - - // INT 64 - int64_t value64 = 423425242; - key = "int64"; - cv1.put(key, value64); - - // Double - double dvalue = 3.5; - key = "double"; - cv1.put(key, dvalue); - - // BLOB - uint32_t data_len = 45; - char* src = new char[data_len]; - - memset(src, '$', data_len); - key = "data"; - cv1.put(key, data_len, src); - - - delete[] src; - - // STRING - std::string strVal = "whoo"; - key = "string"; - cv1.put(key, strVal); - - // BOOL - bool mefalse = false; - key = "bool"; - cv1.put(key, mefalse); - - ContentValue cv2(cv1); - - CHECK(cv1 == cv2); - - cv1.clear(); - cv2.clear(); - - REPORT("testCopyConstructor()"); -} - - -void testClear(){ - - ContentValue cv1; - - // INT 32 - int value32 = 1; - std::string key = "one"; - - cv1.put(key, value32); - - // INT 64 - int64_t value64 = 423425242; - key = "int64"; - cv1.put(key, value64); - - // Double - double dvalue = 3.5; - key = "double"; - cv1.put(key, dvalue); - - // BLOB - uint32_t data_len = 45; - char* src = new char[data_len]; - - memset(src, '$', data_len); - key = "data"; - cv1.put(key, data_len, src); - - - delete[] src; - - // STRING - std::string strVal = "whoo"; - key = "string"; - cv1.put(key, strVal); - - // BOOL - bool mefalse = false; - key = "bool"; - cv1.put(key, mefalse); - - std::map ktMap; - - cv1.getKeyTypeMap(ktMap); - CHECK(ktMap.size() > 0); - - cv1.clear(); - - cv1.getKeyTypeMap(ktMap); - CHECK(ktMap.size() == 0); - - REPORT("testClear()"); - -} diff --git a/libretroshare/src/tests/util/testretrocursor.cpp b/libretroshare/src/tests/util/testretrocursor.cpp deleted file mode 100644 index 78d77e483..000000000 --- a/libretroshare/src/tests/util/testretrocursor.cpp +++ /dev/null @@ -1,127 +0,0 @@ - -#include -#include -#include -#include "util/rstime.h" - -#include "retrodb.h" -#include "utest.h" - - -#define INT32_KEY "day" -#define INT64_KEY "pub_key" -#define DATA_KEY "data" -#define DOUBLE_KEY "a_double" -#define STRING_KEY "a_string" -#define BOOL_KEY "a_bool" - -#define DB_FILE_NAME "RetroDb" - -static RetroDb* mDb = NULL; - -void createRetroDb(); -void destroyRetroDb(); - -INITTEST(); -// mainly test ability to move up and down result set - - -void testTraverseResult(); - - -int main() { - - testTraverseResult(); - - FINALREPORT("RETRO CURSOR TEST"); - return 0; -} - - - -void createRetroDb(){ - - if(mDb) - destroyRetroDb(); - - - remove(DB_FILE_NAME); // account for interrupted tests - mDb = new RetroDb(DB_FILE_NAME, RetroDb::OPEN_READWRITE_CREATE); -} - -void destroyRetroDb(){ - if(mDb == NULL) - return; - - mDb->closeDb(); - delete mDb; - mDb = NULL; - int rc = remove(DB_FILE_NAME); - std::cerr << "remove code: " << rc << std::endl; - - if(rc !=0){ - perror("Could not delete db: "); - - } -} - - -void testTraverseResult(){ - - - createRetroDb(); - - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, pub_key INT, data BLOB, a_double REAL, a_string VARCHAR(255), a_bool INT);"); - CHECK(statementExecuted); - - ContentValue cv; - - cv.put(INT32_KEY, (int32_t)20); - int64_t large_num = 32432242344423; - cv.put(INT64_KEY, large_num); - std::string str = "3dajaojaljfacjlaf£%£^%\"%\"%$"; - const char* data = str.data(); - int size = str.size(); - cv.put(DATA_KEY, size, data); - cv.put(DOUBLE_KEY, 3.14); - cv.put(STRING_KEY, "hello precious"); - cv.put(BOOL_KEY, false); - - bool insertExecuted = mDb->sqlInsert("retroDB", "", cv); - cv.put(INT32_KEY, (int32_t)21); - insertExecuted &= mDb->sqlInsert("retroDB", "", cv); - cv.put(INT32_KEY, (int32_t)2); - insertExecuted &= mDb->sqlInsert("retroDB", "", cv); - cv.put(INT32_KEY, (int32_t)204); - insertExecuted &= mDb->sqlInsert("retroDB", "", cv); - cv.put(INT32_KEY, (int32_t)22); - insertExecuted &= mDb->sqlInsert("retroDB", "", cv); - - CHECK(insertExecuted); - - std::list columns; - columns.push_back(INT32_KEY); columns.push_back(INT64_KEY); columns.push_back(DOUBLE_KEY); - columns.push_back(DATA_KEY); columns.push_back(BOOL_KEY); columns.push_back(STRING_KEY); - std::string orderBy = std::string(INT32_KEY) + " ASC"; - RetroCursor* cursor = mDb->sqlQuery("retroDB", columns, "", orderBy); - - CHECK(cursor->getResultCount() == 5); - cursor->moveToFirst(); - CHECK(cursor->getPosition() == 0); - - cursor->moveToLast(); - CHECK(cursor->getPosition() == cursor->getResultCount()); - - cursor->moveToFirst(); - - CHECK(cursor->getInt32(0) == 2); - cursor->moveToNext(); - cursor->moveToNext(); - - CHECK(cursor->getInt32(0) == 21); - - delete cursor; - - REPORT("testTraverseResult()"); - destroyRetroDb(); -} diff --git a/libretroshare/src/tests/util/testretrodb.cpp b/libretroshare/src/tests/util/testretrodb.cpp deleted file mode 100644 index 37b9d7d84..000000000 --- a/libretroshare/src/tests/util/testretrodb.cpp +++ /dev/null @@ -1,352 +0,0 @@ - -#include -#include -#include -#include "util/rstime.h" - -#include "retrodb.h" -#include "utest.h" - - -#define DAY_KEY "day" -#define PUB_KEY "pub_key" -#define DATA_KEY "data" -#define DOUBLE_KEY "a_double" - -#define DB_FILE_NAME "RetroDb" - -static RetroDb* mDb = NULL; - -void createRetroDb(); -void destroyRetroDb(); - -void testSqlExec(); -void testSqlUpdate(); -void testSqlInsert(); -void testSqlDelete(); -void testSqlQuery(); -void testBinaryInsertion(); - -INITTEST(); - -int main(){ - - testSqlExec(); - testBinaryInsertion(); - testSqlInsert(); - testSqlUpdate(); - testSqlDelete(); - testSqlQuery(); - - FINALREPORT("RETRO DB TEST"); - return 0; -} - -void createRetroDb(){ - - if(mDb) - destroyRetroDb(); - - - remove(DB_FILE_NAME); // account for interrupted tests - mDb = new RetroDb(DB_FILE_NAME, RetroDb::OPEN_READWRITE_CREATE); -} - -void destroyRetroDb(){ - if(mDb == NULL) - return; - - mDb->closeDb(); - delete mDb; - mDb = NULL; - int rc = remove(DB_FILE_NAME); - std::cerr << "remove code: " << rc << std::endl; - - if(rc !=0){ - perror("Could not delete db: "); - - } -} - -void testSqlExec(){ - - createRetroDb(); - - // create simple table - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, pub_key, data);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(day, pub_key, data) VALUES(1,2,3);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(day, pub_key, data) VALUES(3,4525624,4524);"); - - CHECK(statementExecuted); - - // now check if you can retrieve records - std::list columns; - columns.push_back("day"); - columns.push_back("pub_key"); - columns.push_back("data"); - - std::string selection, orderBy; - RetroCursor* c = mDb->sqlQuery("retroDB", columns, selection, orderBy); - - - CHECK(c->getResultCount() == 2); - - // got to first record - c->moveToFirst(); - int32_t first =c->getInt32(0), second = c->getInt32(1), - third = c->getInt32(2); - - - CHECK(first == 1); - CHECK(second == 2); - CHECK(third == 3); - - // get 2nd record - c->moveToNext(); - - first =c->getInt32(0), second = c->getInt32(1), - third = c->getInt32(2); - - CHECK(first == 3); - CHECK(second == 4525624); - CHECK(third == 4524); - - delete c; - - REPORT("testSqlExec()"); - destroyRetroDb(); -} - -void testBinaryInsertion(){ - - createRetroDb(); - // create simple table - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, data BLOB);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(day, data) VALUES(1, 'dafadfad%$%^%%\"$R\"$\"$\"');"); - - // now check if you can retrieve records - std::list columns; - columns.push_back("day"); - columns.push_back("data"); - - std::string selection, orderBy; - RetroCursor* c = mDb->sqlQuery("retroDB", columns, selection, orderBy); - - c->moveToFirst(); - int first = c->getInt32(0); - uint32_t size; - const char* data = (const char*)c->getData(1, size); - std::string str = "dafadfad%$%^%%\"$R\"$\"$\""; - const char* data_comp = str.data(); - bool binCompare = ok; - - for(int i=0; i < 24 ; i++) - binCompare &= data[i] == data_comp[i]; - - CHECK(first == 1); - CHECK(binCompare); - - delete c; - REPORT("testBinaryInsertion()"); - destroyRetroDb(); -} - - - - -void testSqlUpdate(){ - - createRetroDb(); - - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, data BLOB, peerId VARCHAR(255), time INT);"); - CHECK(statementExecuted); - - std::string data = "dadJOOodaodaoro20r2-0r20002ri02fgi3t0***"; - ContentValue cv; - - cv.put("day", (int32_t)20); - std::string peerid = "TheRetroSquad"; - cv.put("peerId", peerid); - cv.put("data", data.size(), data.data()); - int64_t now = time(NULL); - cv.put("time", now); - bool insertExecuted = mDb->sqlInsert("retroDB", "", cv); - - CHECK(insertExecuted); - - // now check entry is fine - - std::list columns; - columns.push_back("day"); columns.push_back("peerId"); columns.push_back("data"); columns.push_back("time"); - - RetroCursor* c = mDb->sqlQuery("retroDB", columns, "", ""); - - CHECK(c->getResultCount() == 1); - std::string result; - c->moveToFirst(); - c->getString(1, result); - - CHECK(result == peerid); - - delete c; - c = NULL; - - // now make an update and see if this is reflected - - int64_t now_plus = now+203; - cv.put("time", now_plus); - bool update = mDb->sqlUpdate("retroDB", "", cv); - CHECK(update); - c = mDb->sqlQuery("retroDB", columns, "", ""); - c->moveToFirst(); - int64_t now_plus_compare = c->getDouble(3); - - CHECK(now_plus_compare == now_plus); - - // now attempt an update which should find no valid record - - - delete c; - - REPORT("testSqlUpdate()"); - destroyRetroDb(); -} - -void testSqlInsert(){ - - createRetroDb(); - - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, a_double DOUBLE, data BLOB);"); - CHECK(statementExecuted); - - ContentValue cv; - - cv.put("day", (int32_t)20); - std::string str = "3dajaojaljfacjlaf%^%\"%\"%$"; - const char* data = str.data(); - int size = 27; - cv.put(DATA_KEY, size, data); - cv.put(DOUBLE_KEY, 3.14); - bool insertExecuted = mDb->sqlInsert("retroDB", "", cv); - - std::list columns; - columns.push_back("day"); columns.push_back("a_double"); columns.push_back("data"); - RetroCursor* cursor = mDb->sqlQuery("retroDB", columns, "", ""); - - CHECK(cursor != NULL); - - cursor->moveToFirst(); - - CHECK(20 == cursor->getInt32(0)); - CHECK(3.14 == cursor->getDouble(1)); - - CHECK(insertExecuted); - - delete cursor; - FINALREPORT("testSqlInsert()"); - destroyRetroDb(); -} - -void testSqlQuery(){ - // test ordering of data and selection clause - - - createRetroDb(); - - // create simple table - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(priority INTEGER PRIMARY KEY ASC, name VARCHAR(255), friends, games INTEGER);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(priority, name, friends, games) VALUES(4,'sammy',2,30);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(priority, name, friends, games) VALUES(2,'davy',6,9);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(priority, name, friends, games) VALUES(6,'pammy',2,4);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(priority, name, friends, games) VALUES(5,'tommy',3,4534);"); - statementExecuted &= mDb->execSQL("INSERT INTO retroDB(priority, name, friends, games) VALUES(9,'jonny',3,44);"); - - CHECK(statementExecuted); - - std::list columns; - columns.push_back("name"); - std::string selection = "games <= 31"; - std::string orderBy = "priority DESC"; - - - // output should be by name: pammy, sammy and davy - RetroCursor* cursor = mDb->sqlQuery("retroDB", columns,selection, orderBy); - - cursor->moveToFirst(); - std::string name; - cursor->getString(0,name); - CHECK(name == "pammy"); - - cursor->moveToNext(); - cursor->getString(0,name); - CHECK(name == "sammy"); - - cursor->moveToNext(); - cursor->getString(0,name); - CHECK(name == "davy"); - - - delete cursor; - FINALREPORT("testSqlQuery()"); - destroyRetroDb(); - return; -} - -void testSqlDelete(){ - - createRetroDb(); - - bool statementExecuted = mDb->execSQL("CREATE TABLE retroDB(day INTEGER PRIMARY KEY ASC, a_double DOUBLE, data BLOB);"); - CHECK(statementExecuted); - - ContentValue cv; - - cv.put("day", (int32_t)20); - std::string str = "3dajaojaljfacjlaf%^%\"%\"%$"; - const char* data = str.data(); - uint32_t size = str.size(); - cv.put(DATA_KEY, size, data); - cv.put(DOUBLE_KEY, 3.14); - - // insert to records - bool insertExecuted = mDb->sqlInsert("retroDB", "", cv); - cv.put("day", (int32_t(5))); - CHECK(insertExecuted); - mDb->sqlInsert("retroDB", "", cv); - - - // now check that their are two records in the db - std::list columns; - columns.push_back("day"); columns.push_back("a_double"); columns.push_back("data"); - RetroCursor* cursor = mDb->sqlQuery("retroDB", columns, "", ""); - CHECK(cursor->getResultCount() == 2); - delete cursor; - // now remove a record and search for the removed record, query should return no records - mDb->sqlDelete("retroDB", "day=5", ""); - - - cursor = mDb->sqlQuery("retroDB", columns, "day=5", ""); - CHECK(cursor->getResultCount() == 0); - delete cursor; - - // now check for the remaining record - cursor = mDb->sqlQuery("retroDB", columns, "day=20", ""); - CHECK(cursor->getResultCount() == 1); - cursor->moveToFirst(); - - // verify there is no data corruption - const char* data_comp1 = (const char*)cursor->getData(2, size); - const char* data_comp2 = str.data(); - - bool binCompare = true; - - for(int i=0; i < str.size() ; i++) - binCompare &= data_comp1[i] == data_comp2[i]; - - CHECK(binCompare); - - delete cursor; - - FINALREPORT("testSqlDelete()"); - destroyRetroDb(); -} diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc deleted file mode 100644 index 10069056a..000000000 --- a/libretroshare/src/turtle/p3turtle.cc +++ /dev/null @@ -1,2516 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: p3turtle.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -//#define P3TURTLE_DEBUG - -#include -#include -#include -#include - -#include "rsserver/p3face.h" -#include "crypto/rscrypto.h" - -#include "pqi/authssl.h" -#include "pqi/p3linkmgr.h" -#include "retroshare/rspeers.h" - -#include "ft/ftserver.h" -#include "ft/ftdatamultiplex.h" -#include "ft/ftcontroller.h" - -#include "p3turtle.h" - -#include -#include -#include - -#include - -#include "util/rsdebug.h" -#include "util/rsprint.h" -#include "util/rsrandom.h" -#include "pqi/pqinetwork.h" - -#ifdef TUNNEL_STATISTICS -static std::vector TS_tunnel_length(8,0) ; -static std::map > > TS_request_time_stamps ; -static std::map > TS_request_bounces ; -void TS_dumpState() ; -#endif - -#define TURTLE_DEBUG() std::cerr << time(NULL) << " : TURTLE : " << __FUNCTION__ << " : " -#define TURTLE_ERROR() std::cerr << "(EE) TURTLE ERROR : " - -// These number may be quite important. I setup them with sensible values, but -// an in-depth test would be better to get an idea of what the ideal values -// could ever be. -// -// update of 14-03-11: -// - I raised the cache time for tunnel requests. This avoids inconsistencies such as: -// * tunnel requests bouncing back while the original request is not in the cache anymore -// * special case of this for own file transfer: an outgoing tunnel is built with no end. -// - changed tunnel speed estimate time lapse to 5 secs. Too small a value favors high variations. -// - the max number of tunnel requests per second is now enforced. It was before defaulting to -// QUEUE_LENGTH*0.1, meaning 0.5. I set it to 0.1. -// -// update of 19-04-12: -// - The total number of TR per second emmited from self will be MAX_TUNNEL_REQS_PER_SECOND / TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 0.5 -// - I updated forward probabilities to higher values, and min them to 1/nb_connected_friends to prevent blocking tunnels. -// -static const rstime_t TUNNEL_REQUESTS_LIFE_TIME = 600 ; /// life time for tunnel requests in the cache. -static const rstime_t TUNNEL_REQUESTS_RESULT_TIME = 20 ; /// maximum time during which we process/forward results for known tunnel requests -static const rstime_t SEARCH_REQUESTS_LIFE_TIME = 600 ; /// life time for search requests in the cache -static const rstime_t SEARCH_REQUESTS_RESULT_TIME = 20 ; /// maximum time during which we process/forward results for known search requests -static const rstime_t REGULAR_TUNNEL_DIGGING_TIME = 300 ; /// maximum interval between two tunnel digging campaigns. -static const rstime_t MAXIMUM_TUNNEL_IDLE_TIME = 60 ; /// maximum life time of an unused tunnel. -static const rstime_t EMPTY_TUNNELS_DIGGING_TIME = 50 ; /// look into tunnels regularly every 50 sec. -static const rstime_t TUNNEL_SPEED_ESTIMATE_LAPSE = 5 ; /// estimate tunnel speed every 5 seconds -static const rstime_t TUNNEL_CLEANING_LAPS_TIME = 10 ; /// clean tunnels every 10 secs -static const rstime_t TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS = 2 ; /// Tunnel management calls every 2 secs. -static const uint32_t MAX_TUNNEL_REQS_PER_SECOND = 1 ; /// maximum number of tunnel requests issued per second. Was 0.5 before -static const uint32_t MAX_ALLOWED_SR_IN_CACHE = 120 ; /// maximum number of search requests allowed in cache. That makes 2 per sec. -static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_FILES =5000 ; /// maximum number of search results forwarded back to the source. -static const uint32_t TURTLE_SEARCH_RESULT_MAX_HITS_DEFAULT = 100 ; /// default maximum number of search results forwarded back source. - -static const float depth_peer_probability[7] = { 1.0f,0.99f,0.9f,0.7f,0.6f,0.5,0.4f } ; - -static const int TUNNEL_REQUEST_PACKET_SIZE = 50 ; -static const int MAX_TR_FORWARD_PER_SEC = 20 ; -static const int MAX_TR_FORWARD_PER_SEC_UPPER_LIMIT = 30 ; -static const int MAX_TR_FORWARD_PER_SEC_LOWER_LIMIT = 10 ; -static const int DISTANCE_SQUEEZING_POWER = 8 ; - -#define HEX_PRINT(a) std::hex << a << std::dec - -p3turtle::p3turtle(p3ServiceControl *sc,p3LinkMgr *lm) - :p3Service(), p3Config(), mServiceControl(sc), mLinkMgr(lm), mTurtleMtx("p3turtle") -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - _own_id = sc->getOwnId() ; - - if(_own_id.isNull()) - { - std::cerr << "OwnId is null, as returned by the p3ServiceControl object in turtle router. Can't go on!" << std::endl; - exit(-1) ; - } - _turtle_routing_enabled = true ; - _turtle_routing_session_enabled = true; - - _random_bias = RSRandom::random_u32() ; - _serialiser = new RsTurtleSerialiser() ; - - addSerialType(_serialiser); - - _last_clean_time = 0 ; - _last_tunnel_management_time = 0 ; - _last_tunnel_campaign_time = 0 ; - _last_tunnel_speed_estimate_time = 0 ; - - _traffic_info.reset() ; - _max_tr_up_rate = MAX_TR_FORWARD_PER_SEC ; - _service_type = getServiceInfo().mServiceType ; -} - -const std::string TURTLE_APP_NAME = "turtle"; -const uint16_t TURTLE_APP_MAJOR_VERSION = 1; -const uint16_t TURTLE_APP_MINOR_VERSION = 0; -const uint16_t TURTLE_MIN_MAJOR_VERSION = 1; -const uint16_t TURTLE_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3turtle::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_TURTLE, - TURTLE_APP_NAME, - TURTLE_APP_MAJOR_VERSION, - TURTLE_APP_MINOR_VERSION, - TURTLE_MIN_MAJOR_VERSION, - TURTLE_MIN_MINOR_VERSION); -} - -void p3turtle::getItemNames(std::map& names) const -{ - names.clear(); - - names[RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST ] = "Filename substring search request"; - names[RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST ] = "Generic search request"; - names[RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT ] = "File search result"; - names[RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT ] = "Generic search result"; - names[RS_TURTLE_SUBTYPE_OPEN_TUNNEL ] = "Tunnel request"; - names[RS_TURTLE_SUBTYPE_TUNNEL_OK ] = "Tunnel response"; - names[RS_TURTLE_SUBTYPE_FILE_REQUEST ] = "Data request"; - names[RS_TURTLE_SUBTYPE_FILE_DATA ] = "Data chunk"; - names[RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST ] = "Filename RegExp search request"; - names[RS_TURTLE_SUBTYPE_GENERIC_DATA ] = "Generic data"; - names[RS_TURTLE_SUBTYPE_FILE_MAP ] = "Chunk map"; - names[RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST ] = "Chunk map request"; - names[RS_TURTLE_SUBTYPE_CHUNK_CRC ] = "Chunk CRC"; - names[RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST ] = "Chunk CRC request"; -} - -void p3turtle::setEnabled(bool b) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _turtle_routing_enabled = b; - - if(b) - std::cerr << "Enabling turtle routing" << std::endl; - else - std::cerr << "Disabling turtle routing" << std::endl; - - IndicateConfigChanged() ; -} -bool p3turtle::enabled() const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - return _turtle_routing_enabled ; -} - - -void p3turtle::setSessionEnabled(bool b) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _turtle_routing_session_enabled = b; - - if(b) - std::cerr << "Enabling turtle routing for this Session" << std::endl; - else - std::cerr << "Disabling turtle routing for this Session" << std::endl; -} - -bool p3turtle::sessionEnabled() const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - return _turtle_routing_session_enabled ; -} - - -int p3turtle::tick() -{ - // Handle tunnel trafic - // - handleIncoming(); // handle incoming packets - - rstime_t now = time(NULL) ; - -#ifdef TUNNEL_STATISTICS - static rstime_t last_now = now ; - if(now - last_now > 2) - std::cerr << "******************* WARNING: now - last_now = " << now - last_now << std::endl; - last_now = now ; -#endif - - bool should_autowash,should_estimatespeed ; - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - should_autowash = now > TUNNEL_CLEANING_LAPS_TIME+_last_clean_time ; - should_estimatespeed = now >= TUNNEL_SPEED_ESTIMATE_LAPSE + _last_tunnel_speed_estimate_time ; - } - - // Tunnel management: - // - we digg new tunnels at least every 5 min (300 sec). - // - we digg new tunnels each time a new peer connects - // - we digg new tunnels each time a new hash is asked for - // - if(now >= _last_tunnel_management_time+TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS) // call every second - { -#ifdef P3TURTLE_DEBUG - std::cerr << "Calling tunnel management." << std::endl ; -#endif - if(_turtle_routing_enabled && _turtle_routing_session_enabled) - manageTunnels() ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _last_tunnel_management_time = now ; - - // Update traffic statistics. The constants are important: they allow a smooth variation of the - // traffic speed, which is used to moderate tunnel requests statistics. - // - _traffic_info = _traffic_info*0.9 + _traffic_info_buffer* (0.1 / (float)TIME_BETWEEN_TUNNEL_MANAGEMENT_CALLS) ; - _traffic_info_buffer.reset() ; - } - } - - // Clean every 10 sec. - // - if(should_autowash) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "Calling autowash." << std::endl ; -#endif - autoWash() ; // clean old/unused tunnels and file hashes, as well as search and tunnel requests. - - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _last_clean_time = now ; - } - - if(should_estimatespeed) - { - estimateTunnelSpeeds() ; - - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _last_tunnel_speed_estimate_time = now ; - } - -#ifdef TUNNEL_STATISTICS - // Dump state for debugging, every 20 sec. - // - static rstime_t TS_last_dump = time(NULL) ; - - if(now > 20+TS_last_dump) - { - TS_last_dump = now ; - TS_dumpState() ; - } -#endif - -#ifdef P3TURTLE_DEBUG - // Dump state for debugging, every 20 sec. - // - static rstime_t last_dump = time(NULL) ; - - if(now > 20+last_dump) - { - last_dump = now ; - dumpState() ; - } -#endif - return 0 ; -} - -// -----------------------------------------------------------------------------------// -// ------------------------------ Tunnel maintenance. ------------------------------ // -// -----------------------------------------------------------------------------------// -// - -// adds a virtual peer to the list that is communicated ot ftController. -// -void p3turtle::locked_addDistantPeer(const TurtleFileHash&,TurtleTunnelId tid) -{ - unsigned char tmp[RsPeerId::SIZE_IN_BYTES] ; - memset(tmp,0,RsPeerId::SIZE_IN_BYTES) ; - - 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 ; -#ifdef P3TURTLE_DEBUG - assert(_local_tunnels.find(tid)!=_local_tunnels.end()) ; -#endif - _local_tunnels[tid].vpid = virtual_peer_id ; -} - -void p3turtle::getSourceVirtualPeersList(const TurtleFileHash& hash,std::list& list) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - list.clear() ; - - std::map::const_iterator it = _incoming_file_hashes.find(hash) ; - - if(it != _incoming_file_hashes.end()) - for(uint32_t i=0;isecond.tunnels.size();++i) - { - std::map::const_iterator it2 = _local_tunnels.find( it->second.tunnels[i] ) ; - - if(it2 != _local_tunnels.end()) - { - pqipeer vp ; - vp.id = it2->second.vpid ; - vp.name = "Virtual (distant) peer" ; - vp.state = RS_PEER_S_CONNECTED ; - vp.actions = RS_PEER_CONNECTED ; - list.push_back(vp) ; - } - else - std::cerr << "(EE) getSourceVirtualPeersList(): no tunnels for incoming file hash " << hash << ": weird!"<< std::endl; - } -} - -// This method handles digging new tunnels as needed. -// New tunnels are dug when: -// - new peers have connected. The resulting tunnels should be checked against doubling. -// - new hashes are submitted for handling. -// -class hashPairComparator -{ - public: - virtual bool operator()(const std::pair& p1,const std::pair& p2) const - { - return p1.second < p2.second ; - } -}; -void p3turtle::manageTunnels() -{ - // Collect hashes for which tunnel digging is necessary / recommended. Hashes get in the list for two reasons: - // - the hash has no tunnel -> tunnel digging every EMPTY_TUNNELS_DIGGING_TIME seconds - // - the hash hasn't been tunneled for more than REGULAR_TUNNEL_DIGGING_TIME seconds, even if downloading. - // - // Candidate hashes are sorted, by olderness. The older gets tunneled first. At most MAX_TUNNEL_REQS_PER_SECOND are - // treated at once, as this method is called every second. - // Note: Because REGULAR_TUNNEL_DIGGING_TIME is larger than EMPTY_TUNNELS_DIGGING_TIME, files being downloaded get - // re-tunneled in priority. As this happens less, they don't obliterate tunneling for files that have no tunnels yet. - - std::vector > hashes_to_digg ; - rstime_t now = time(NULL) ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // digg new tunnels if no tunnels are available and force digg new tunnels at regular (large) interval - // - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) - { - // get total tunnel speed. - // - uint32_t total_speed = 0 ; - for(uint32_t i=0;isecond.tunnels.size();++i) - total_speed += _local_tunnels[it->second.tunnels[i]].speed_Bps ; - - static const float grow_speed = 1.0f ; // speed at which the time increases. - - float tunnel_keeping_factor = (std::max(1.0f,(float)total_speed/(float)(50*1024)) - 1.0f)*grow_speed + 1.0f ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "Total speed = " << total_speed << ", tunel factor = " << tunnel_keeping_factor << " new time = " << rstime_t(REGULAR_TUNNEL_DIGGING_TIME*tunnel_keeping_factor) << std::endl; -#endif - - if( (it->second.tunnels.empty() && now >= it->second.last_digg_time+EMPTY_TUNNELS_DIGGING_TIME) - || (it->second.use_aggressive_mode && now >= it->second.last_digg_time + rstime_t(REGULAR_TUNNEL_DIGGING_TIME*tunnel_keeping_factor))) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "pushed hash " << it->first << ", for digging. Old = " << now - it->second.last_digg_time << std::endl; -#endif - hashes_to_digg.push_back(std::pair(it->first,it->second.last_digg_time)) ; - } - } - } -#ifdef TUNNEL_STATISTICS - std::cerr << hashes_to_digg.size() << " hashes candidate for tunnel digging." << std::endl; -#endif - - std::sort(hashes_to_digg.begin(),hashes_to_digg.end(),hashPairComparator()) ; - - for(unsigned int i=0;i::iterator it(_local_tunnels.begin());it!=_local_tunnels.end();++it) - { - TurtleTunnel& tunnel(it->second) ; - - float speed_estimate = tunnel.transfered_bytes / float(TUNNEL_SPEED_ESTIMATE_LAPSE) ; - tunnel.speed_Bps = 0.75*tunnel.speed_Bps + 0.25*speed_estimate ; - tunnel.transfered_bytes = 0 ; - } -} - -void p3turtle::autoWash() -{ -#ifdef P3TURTLE_DEBUG - std::cerr << " In autowash." << std::endl ; -#endif - // Remove hashes that are marked as such. - // - - std::vector > > services_vpids_to_remove ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - for(std::set::const_iterator hit(_hashes_to_remove.begin());hit!=_hashes_to_remove.end();++hit) - { - std::map::iterator it(_incoming_file_hashes.find(*hit)) ; - - if(it == _incoming_file_hashes.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: asked to stop monitoring file hash " << *hit << ", but this hash is actually not handled by the turtle router." << std::endl ; -#endif - continue ; - } - - // copy the list of tunnels to remove. -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: stopping monitoring for file hash " << *hit << ", and closing " << it->second.tunnels.size() << " tunnels (" ; -#endif - std::vector tunnels_to_remove ; - - for(std::vector::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2) - { -#ifdef P3TURTLE_DEBUG - std::cerr << HEX_PRINT(*it2) << "," ; -#endif - tunnels_to_remove.push_back(*it2) ; - } -#ifdef P3TURTLE_DEBUG - std::cerr << ")" << std::endl ; -#endif - for(unsigned int k=0;k::iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();) - if(now > (rstime_t)(it->second.time_stamp + SEARCH_REQUESTS_LIFE_TIME)) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " removed search request " << HEX_PRINT(it->first) << ", timeout." << std::endl ; -#endif - std::map::iterator tmp(it) ; - ++tmp ; - _search_requests_origins.erase(it) ; - it = tmp ; - } - else - ++it; - } - - // Tunnel requests - // - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - for(std::map::iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();) - if(now > (rstime_t)(it->second.time_stamp + TUNNEL_REQUESTS_LIFE_TIME)) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " removed tunnel request " << HEX_PRINT(it->first) << ", timeout." << std::endl ; -#endif - std::map::iterator tmp(it) ; - ++tmp ; - _tunnel_requests_origins.erase(it) ; - it = tmp ; - } - else - ++it ; - } - - // Tunnels. - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - std::vector tunnels_to_close ; - - for(std::map::iterator it(_local_tunnels.begin());it!=_local_tunnels.end();++it) - if(now > (rstime_t)(it->second.time_stamp + MAXIMUM_TUNNEL_IDLE_TIME)) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " removing tunnel " << HEX_PRINT(it->first) << ": timeout." << std::endl ; -#endif - tunnels_to_close.push_back(it->first) ; - } - - for(unsigned int i=0;iremoveVirtualPeer(services_vpids_to_remove[i].second.first,services_vpids_to_remove[i].second.second) ; - } -} - -void p3turtle::forceReDiggTunnels(const TurtleFileHash& hash) -{ - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - if( _incoming_file_hashes.find(hash) == _incoming_file_hashes.end()) - { - std::cerr << "(EE) p3turtle::forceReDiggTunnels(): hash " << hash << " is not currently handled by turtle." << std::endl; - return ; - } - } - - diggTunnel(hash) ; -} - -void p3turtle::locked_closeTunnel(TurtleTunnelId tid,std::vector > >& sources_to_remove) -{ - // This is closing a given tunnel, removing it from file sources, and from the list of tunnels of its - // corresponding file hash. In the original turtle4privacy paradigm, they also send back and forward - // tunnel closing commands. In our case, this is not necessary, because if a tunnel is closed somewhere, its - // source is not going to be used and the tunnel will eventually disappear. - // - std::map::iterator it(_local_tunnels.find(tid)) ; - - if(it == _local_tunnels.end()) - { - std::cerr << "p3turtle: was asked to close tunnel " << reinterpret_cast(tid) << ", which actually doesn't exist." << std::endl ; - return ; - } -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: Closing tunnel " << HEX_PRINT(tid) << std::endl ; -#endif - - if(it->second.local_src == _own_id) // this is a starting tunnel. We thus remove - // - the virtual peer from the vpid list - // - the tunnel id from the file hash - // - the virtual peer from the file sources in the file transfer controller. - { - TurtleTunnelId tid = it->first ; - TurtleVirtualPeerId vpid = it->second.vpid ; - TurtleFileHash hash = it->second.hash ; - -#ifdef P3TURTLE_DEBUG - std::cerr << " Tunnel is a starting point. Also removing:" << std::endl ; - std::cerr << " Virtual Peer Id " << vpid << std::endl ; - std::cerr << " Associated file source." << std::endl ; -#endif - std::pair hash_vpid(hash,vpid) ; - - // Let's be cautious. Normally we should never be here without consistent information, - // but still, this happens, rarely. - // - if(_virtual_peers.find(vpid) != _virtual_peers.end()) - _virtual_peers.erase(_virtual_peers.find(vpid)) ; - - std::map::iterator it(_incoming_file_hashes.find(hash)) ; - - if(it != _incoming_file_hashes.end()) - { - std::vector& tunnels(it->second.tunnels) ; - - // Remove tunnel id from it's corresponding hash. For security we - // go through the whole tab, although the tunnel id should only be listed once - // in this tab. - // - for(unsigned int i=0;i >(it->second.service,hash_vpid)) ; - } - } - else if(it->second.local_dst == _own_id) // This is a ending tunnel. We also remove the virtual peer id - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Tunnel is a ending point. Also removing associated outgoing hash." ; -#endif - std::map::iterator itHash = _outgoing_tunnel_client_services.find(tid); - - if(itHash != _outgoing_tunnel_client_services.end()) - { - TurtleVirtualPeerId vpid = it->second.vpid ; - TurtleFileHash hash = it->second.hash ; - - std::pair hash_vpid(hash,vpid) ; - - sources_to_remove.push_back(std::pair >(itHash->second,hash_vpid)) ; - - _outgoing_tunnel_client_services.erase(itHash) ; - - // Also remove the associated virtual peer - // - if(_virtual_peers.find(vpid) != _virtual_peers.end()) - _virtual_peers.erase(_virtual_peers.find(vpid)) ; - } - } - - _local_tunnels.erase(it) ; -} - -void p3turtle::stopMonitoringTunnels(const RsFileHash& hash) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: Marking hash " << hash << " to be removed during autowash." << std::endl ; -#endif - // We don't do the deletion in this process, because it can cause a race with tunnel management. - _hashes_to_remove.insert(hash) ; -} - -// -----------------------------------------------------------------------------------// -// -------------------------------- Config functions ------------------------------ // -// -----------------------------------------------------------------------------------// -// -RsSerialiser *p3turtle::setupSerialiser() -{ - RsSerialiser *rss = new RsSerialiser ; - rss->addSerialType(new RsTurtleSerialiser) ; - rss->addSerialType(new RsGeneralConfigSerialiser()); - - return rss ; -} - -bool p3turtle::saveList(bool& cleanup, std::list& lst) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: saving list..." << std::endl ; -#endif - cleanup = true ; - - RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - RsTlvKeyValue kv; - kv.key = "TURTLE_CONFIG_MAX_TR_RATE" ; - rs_sprintf(kv.value, "%g", _max_tr_up_rate); - vitem->tlvkvs.pairs.push_back(kv) ; - - kv.key = "TURTLE_ENABLED" ; - kv.value = _turtle_routing_enabled?"TRUE":"FALSE" ; - - vitem->tlvkvs.pairs.push_back(kv) ; - - lst.push_back(vitem) ; - - return true ; -} - -bool p3turtle::loadList(std::list& load) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: loading list..." << std::endl ; -#endif - for(std::list::const_iterator it(load.begin());it!=load.end();++it) - { - RsConfigKeyValueSet *vitem = dynamic_cast(*it) ; - - if(vitem != NULL) - for(std::list::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) - { - if(kit->key == "TURTLE_CONFIG_MAX_TR_RATE") - { - int val ; - if (sscanf(kit->value.c_str(), "%d", &val) == 1) - { - setMaxTRForwardRate(val) ; - std::cerr << "Setting max TR forward rate to " << val << std::endl ; - } - } - if(kit->key == "TURTLE_ENABLED") - { - _turtle_routing_enabled = (kit->value == "TRUE") ; - - if(!_turtle_routing_enabled) - std::cerr << "WARNING: turtle routing has been disabled. You can enable it again in config->server->turtle router." << std::endl; - } - } - - delete *it ; - } - load.clear() ; - return true ; -} -int p3turtle::getMaxTRForwardRate() const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - return _max_tr_up_rate ; -} - - -void p3turtle::setMaxTRForwardRate(int val) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - if(val > MAX_TR_FORWARD_PER_SEC_UPPER_LIMIT || val < MAX_TR_FORWARD_PER_SEC_LOWER_LIMIT) - std::cerr << "Warning: MAX_TR_FORWARD_PER_SEC value " << val << " read in config file is off limits [" << MAX_TR_FORWARD_PER_SEC_LOWER_LIMIT << "..." << MAX_TR_FORWARD_PER_SEC_UPPER_LIMIT << "]. Ignoring!" << std::endl; - else - { - _max_tr_up_rate = val ; - std::cerr << "p3turtle: Set max tr up rate to " << val << std::endl; - } - IndicateConfigChanged() ; -} - - -// -----------------------------------------------------------------------------------// -// -------------------------------- Helper functions ------------------------------ // -// -----------------------------------------------------------------------------------// -// -uint32_t p3turtle::generateRandomRequestId() -{ - return RSRandom::random_u32() ; -} - -uint32_t p3turtle::generatePersonalFilePrint(const TurtleFileHash& hash,uint32_t seed,bool b) -{ - // whatever cooking from the file hash and OwnId that cannot be recovered. - // The only important thing is that the saem couple (hash,SSL id) produces the same tunnel - // id. The result uses a boolean to allow generating non symmetric tunnel ids. - - std::string buff(hash.toStdString() + _own_id.toStdString()) ; - uint32_t res = seed ; - uint32_t decal = 0 ; - - for(int i=0;i<(int)buff.length();++i) - { - res += 7*buff[i] + decal ; - - if(b) - decal = decal*44497+15641+(res%86243) ; - else - decal = decal*86243+15649+(res%44497) ; - } - - return res ; -} -// -----------------------------------------------------------------------------------// -// -------------------------------- Global routing. -------------------------------- // -// -----------------------------------------------------------------------------------// -// -int p3turtle::handleIncoming() -{ - int nhandled = 0; - // While messages read - // - RsItem *item = NULL; - - while(NULL != (item = recvItem())) - { - nhandled++; - - if(!(_turtle_routing_enabled && _turtle_routing_session_enabled)) - delete item ; - else - { - RsTurtleGenericTunnelItem *gti = dynamic_cast(item) ; - - if(gti != NULL) - routeGenericTunnelItem(gti) ; /// Generic packets, that travel through established tunnels. - else /// These packets should be destroyed by the client. - { - /// Special packets that require specific treatment, because tunnels do not exist for these packets. - /// These packets are destroyed here, after treatment. - // - switch(item->PacketSubType()) - { - case RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST: - case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST: - case RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST: handleSearchRequest(dynamic_cast(item)) ; - break ; - - case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT : - case RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT : handleSearchResult(dynamic_cast(item)) ; - break ; - - case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : handleTunnelRequest(dynamic_cast(item)) ; - break ; - - case RS_TURTLE_SUBTYPE_TUNNEL_OK : handleTunnelResult(dynamic_cast(item)) ; - break ; - - default: - std::cerr << "p3turtle::handleIncoming: Unknown packet subtype " << item->PacketSubType() << std::endl ; - } - delete item; - } - } - } - - return nhandled; -} - -// -----------------------------------------------------------------------------------// -// -------------------------------- Search handling. ------------------------------- // -// -----------------------------------------------------------------------------------// -// -void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) -{ - Dbg3() << __PRETTY_FUNCTION__ << " " << *item << std::endl; - - // take a look at the item and test against inconsistent values - // - If the item destimation is - -#ifdef P3TURTLE_DEBUG - std::cerr << "Received search request from peer " << item->PeerId() << ": " << std::endl ; - item->print(std::cerr,0) ; -#endif - - uint32_t item_size = RsTurtleSerialiser().size(item); - - if(item_size > TURTLE_MAX_SEARCH_REQ_ACCEPTED_SERIAL_SIZE) - { - RsWarn() << __PRETTY_FUNCTION__ - << " Got a turtle search item with arbitrary large size from " - << item->PeerId() << " of size " << item_size << " and depth " - << item->depth << ". This is not allowed => dropping." - << std::endl; - return; - } - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - if(_search_requests_origins.size() > MAX_ALLOWED_SR_IN_CACHE) - { - RsWarn() << __PRETTY_FUNCTION__ << " More than " - << MAX_ALLOWED_SR_IN_CACHE << " search request in cache. " - << "A peer is probably trying to flood your network See " - "the depth charts to find him." << std::endl; - return; - } - - if( _search_requests_origins.find(item->request_id) != - _search_requests_origins.end() ) - { - /* If the item contains an already handled search request, give up. - * This happens when the same search request gets relayed by - * different peers */ - return; - } - } - - // Perform local search off-mutex,because this might call some services that are above turtle in the mutex chain. - - uint32_t search_result_count = 0; - uint32_t max_allowed_hits = TURTLE_SEARCH_RESULT_MAX_HITS_DEFAULT; - - if(item->PeerId() != _own_id) // is the request not coming from us? - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Request not from us. Performing local search" << std::endl ; -#endif - std::list search_results ; - - performLocalSearch(item,search_result_count,search_results,max_allowed_hits) ; - - for(auto it(search_results.begin());it!=search_results.end();++it) - { - (*it)->request_id = item->request_id ; - (*it)->PeerId(item->PeerId()) ; - -#ifdef P3TURTLE_DEBUG - std::cerr << " sending back search result for request " << item->request_id << " to back to peer " << item->PeerId() << std::endl ; -#endif - sendItem(*it) ; - } - } - - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // This is a new request. Let's add it to the request map, and forward it to - // open peers. - - TurtleSearchRequestInfo& req( _search_requests_origins[item->request_id] ) ; - req.origin = item->PeerId() ; - req.time_stamp = time(NULL) ; - req.depth = item->depth ; - req.result_count = search_result_count; - req.keywords = item->GetKeywords() ; - req.service_id = item->serviceId() ; - req.max_allowed_hits = max_allowed_hits; - - // if enough has been sent back already, do not sarch further - -#ifdef P3TURTLE_DEBUG - std::cerr << " result count = " << req.result_count << std::endl; -#endif - if(req.result_count >= max_allowed_hits) - return ; - - // If search depth not too large, also forward this search request to all other peers. - // - // We use a random factor on the depth test that is biased by a mix between the session id and the partial tunnel id - // to scramble a possible search-by-depth attack. - // - bool random_bypass = (item->depth >= TURTLE_MAX_SEARCH_DEPTH && (((_random_bias ^ item->request_id)&0x7)==2)) ; - bool random_dshift = (item->depth == 1 && (((_random_bias ^ item->request_id)&0x7)==6)) ; - - if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass) - { - std::set onlineIds ; - mServiceControl->getPeersConnected(_service_type, onlineIds); -#ifdef P3TURTLE_DEBUG - std::cerr << " Looking for online peers" << std::endl ; -#endif - - for(std::set::const_iterator it(onlineIds.begin());it!=onlineIds.end();++it) - { -// if(!mServiceControl->isPeerConnected(RS_SERVICE_TYPE_TURTLE,*it)) -// continue ; - - uint32_t linkType = mLinkMgr->getLinkType(*it); - - if ((linkType & RS_NET_CONN_SPEED_TRICKLE) || (linkType & RS_NET_CONN_SPEED_LOW)) // don't forward searches to slow link types (e.g relay peers)! - continue ; - - if(*it != item->PeerId()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding request to peer = " << *it << std::endl ; -#endif - // Copy current item and modify it. - RsTurtleSearchRequestItem *fwd_item = item->clone() ; - - // increase search depth, except in some rare cases, to prevent correlation between - // TR sniffing and friend names. The strategy is to not increase depth if the depth - // is 1: - // If B receives a TR of depth 1 from A, B cannot deduice that A is downloading the - // file, since A might have shifted the depth. - // - if(!random_dshift) - ++(fwd_item->depth) ; - - fwd_item->PeerId(*it) ; - - sendItem(fwd_item) ; - } - } - } -#ifdef P3TURTLE_DEBUG - else - std::cout << " Dropping this item, as search depth is " << item->depth << std::endl ; -#endif -} - -// This function should be removed in the future, when file search will also use generic search items. - -void p3turtle::performLocalSearch( - RsTurtleSearchRequestItem *item, uint32_t& req_result_count, - std::list& search_results, - uint32_t& max_allowed_hits ) -{ - Dbg3() << __PRETTY_FUNCTION__ << " " << item << std::endl; - - RsTurtleFileSearchRequestItem* ftsearch = - dynamic_cast(item); - - if(ftsearch != NULL) - { - performLocalSearch_files( - ftsearch, req_result_count, search_results, - max_allowed_hits ); - return ; - } - - RsTurtleGenericSearchRequestItem *gnsearch = dynamic_cast(item) ; - - if(gnsearch != NULL) - { - performLocalSearch_generic(gnsearch,req_result_count,search_results,max_allowed_hits) ; - return ; - } -} - -void p3turtle::performLocalSearch_generic(RsTurtleGenericSearchRequestItem *item, uint32_t& req_result_count, std::list& result,uint32_t& max_allowed_hits) -{ - unsigned char *search_result_data = NULL ; - uint32_t search_result_data_len = 0 ; - - RsTurtleClientService *client = NULL ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - auto it = _registered_services.find(item->service_id) ; - - if(it == _registered_services.end()) - return ; - - client = it->second ; - } - - if(client->receiveSearchRequest(item->search_data,item->search_data_len,search_result_data,search_result_data_len,max_allowed_hits)) - { - RsTurtleGenericSearchResultItem *result_item = new RsTurtleGenericSearchResultItem ; - - result_item->result_data = search_result_data ; - result_item->result_data_len = search_result_data_len ; - - result.push_back(result_item) ; - } -} - -void p3turtle::performLocalSearch_files( - RsTurtleFileSearchRequestItem *item, uint32_t& req_result_count, - std::list& result, - uint32_t& max_allowed_hits ) -{ - Dbg3() << __PRETTY_FUNCTION__ << " " << *item << std::endl; - - std::list initialResults ; - item->search(initialResults) ; - -#ifdef P3TURTLE_DEBUG - std::cerr << initialResults.size() << " matches found." << std::endl ; -#endif - result.clear() ; - RsTurtleFTSearchResultItem *res_item = NULL ; - uint32_t item_size = 0 ; - - static const uint32_t RSTURTLE_MAX_SEARCH_RESPONSE_SIZE = 10000 ; - max_allowed_hits = TURTLE_SEARCH_RESULT_MAX_HITS_FILES; - - for(auto it(initialResults.begin());it!=initialResults.end();++it) - { - if(res_item == NULL) - { - res_item = new RsTurtleFTSearchResultItem ; - item_size = 0 ; - - result.push_back(res_item) ; - } - res_item->result.push_back(*it); - - // Let's chop search results items into several chunks of finite size to avoid exceeding streamer's capacity. - // - ++req_result_count ; // increase hit number for this particular search request. - - item_size += 8 /* size */ + it->hash.serial_size() + it->name.size() ; - - if(item_size > RSTURTLE_MAX_SEARCH_RESPONSE_SIZE || req_result_count >= max_allowed_hits) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Sending back chunk of size " << item_size << ", for " << res_item->result.size() << " elements." << std::endl ; -#endif - res_item = NULL ; // forces creation of a new item. - } - } - - Dbg3() << __PRETTY_FUNCTION__ << " found " << req_result_count << " results" - << std::endl; -} - -void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item) -{ - // Filter out banned hashes from the result. - - RsTurtleFTSearchResultItem *ftsr_tmp = dynamic_cast(item) ; - - if(ftsr_tmp != NULL) - { - for(auto it(ftsr_tmp->result.begin());it!=ftsr_tmp->result.end();) - if( rsFiles->isHashBanned((*it).hash) ) - { - std::cerr << "(II) filtering out banned hash " << (*it).hash << " from turtle result " << std::hex << item->request_id << std::dec << std::endl; - it = ftsr_tmp->result.erase(it); - } - else - ++it; - - if(ftsr_tmp->result.empty()) - return ; - } - - // Then handle the result - - std::list > results_to_notify_off_mutex ; - - { - RS_STACK_MUTEX(mTurtleMtx); - // Find who actually sent the corresponding request. - // - std::map::iterator it = _search_requests_origins.find(item->request_id) ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "Received search result:" << std::endl ; - item->print(std::cerr,0) ; -#endif - if(it == _search_requests_origins.end()) - { - // This is an error: how could we receive a search result corresponding to a search item we - // have forwarded but that it not in the list ?? - - std::cerr << __PRETTY_FUNCTION__ << ": search result for request " << std::hex << item->request_id << std::dec << " has no peer direction!" << std::endl ; - return ; - } - - // Is this result too old? - // Search Requests younger than SEARCH_REQUESTS_LIFE_TIME are kept in the cache, so that they are not duplicated if they bounce in the network - // Nevertheless results received for Search Requests older than SEARCH_REQUESTS_RESULT_TIME are considered obsolete and discarded - if (time(NULL) > it->second.time_stamp + SEARCH_REQUESTS_RESULT_TIME) - { -#ifdef P3TURTLE_DEBUG - RsDbg() << "TURTLE p3turtle::handleSearchResult Search Request is known, but result arrives too late, dropping"; -#endif - return; - } - - // Is this result's target actually ours ? - - if(it->second.origin == _own_id) - { - it->second.result_count += item->count() ; - - auto it2 = _registered_services.find(it->second.service_id) ; - - if(it2 != _registered_services.end()) - results_to_notify_off_mutex.push_back(std::make_pair(item,it2->second)) ; - else - std::cerr << "(EE) cannot find client service for ID " << std::hex << it->second.service_id << std::dec << ": search result item will be dropped." << std::endl; - } - else - { // Nope, so forward it back. -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding result back to " << it->second.origin << std::endl; -#endif - // We update the total count forwarded back, and chop it to TURTLE_SEARCH_RESULT_MAX_HITS. - - uint32_t n = item->count(); // not so good! - - if(it->second.result_count >= it->second.max_allowed_hits) - { - std::cerr << "(WW) exceeded turtle search result to forward. Req=" << std::hex << item->request_id << std::dec - << " already forwarded: " << it->second.result_count << ", max_allowed: " << it->second.max_allowed_hits << ": dropping item with " << n << " elements." << std::endl; - return ; - } - - if(it->second.result_count + n > it->second.max_allowed_hits) - { - for(uint32_t i=it->second.result_count + n; i>it->second.max_allowed_hits;--i) - item->pop() ; - - it->second.result_count = it->second.max_allowed_hits ; - } - else - it->second.result_count += n ; - - RsTurtleSearchResultItem *fwd_item = item->duplicate(); - - // Normally here, we should setup the forward adress, so that the owner's - // of the files found can be further reached by a tunnel. - - fwd_item->PeerId(it->second.origin) ; - - sendItem(fwd_item) ; - } - } // mTurtleMtx end - - // now we notify clients off-mutex. - - for(auto it(results_to_notify_off_mutex.begin());it!=results_to_notify_off_mutex.end();++it) - { - // Hack to use the old search result handling in ftServer. Normally ftServer should use the new method with serialized result. - -#warning make sure memory is correctly deleted here - RsTurtleFTSearchResultItem *ftsr = dynamic_cast(it->first) ; - - if(ftsr!=NULL) - { - ftServer *client = dynamic_cast((*it).second) ; - - if(!client) - { - std::cerr << "(EE) received turtle FT search result but the service is not a ftServer!!" << std::endl; - continue; - } - //RsServer::notify()->notifyTurtleSearchResult(ftsr->request_id,ftsr->result) ; - - client->ftReceiveSearchResult(ftsr); - continue ; - } - - RsTurtleGenericSearchResultItem *gnsr = dynamic_cast(it->first) ; - - if(gnsr!=NULL) - (*it).second->receiveSearchResult(gnsr->request_id,gnsr->result_data,gnsr->result_data_len) ; - } -} - -// -----------------------------------------------------------------------------------// -// --------------------------------- File Transfer. -------------------------------- // -// -----------------------------------------------------------------------------------// - -// Routing of turtle tunnel items in a generic manner. Most tunnel packets will -// use this function, except packets designed for contructing the tunnels and -// searching, namely TurtleSearchRequests/Results and OpenTunnel/TunnelOkItems -// -// Only packets coming from handleIncoming() end up here, so this function is -// able to catch the transiting traffic. -// -void p3turtle::routeGenericTunnelItem(RsTurtleGenericTunnelItem *item) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "p3Turtle: treating generic tunnel item:" << std::endl ; - item->print(std::cerr,1) ; -#endif - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // look for the tunnel id. - // - std::map::iterator it(_local_tunnels.find(item->tunnelId())) ; - - if(it == _local_tunnels.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: got file map with unknown tunnel id " << HEX_PRINT(item->tunnelId()) << std::endl ; -#endif - delete item; - return ; - } - - TurtleTunnel& tunnel(it->second) ; - - // Only file data transfer updates tunnels time_stamp field, to avoid maintaining tunnel that are incomplete. - if(item->shouldStampTunnel()) - tunnel.time_stamp = time(NULL) ; - - tunnel.transfered_bytes += RsTurtleSerialiser().size(item); - - if(item->PeerId() == tunnel.local_dst) - item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; - else if(item->PeerId() == tunnel.local_src) - item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_SERVER) ; - else - { - std::cerr << "(EE) p3turtle::routeGenericTunnelItem(): item mismatches tunnel src/dst ids." << std::endl; - std::cerr << "(EE) tunnel.local_src = " << tunnel.local_src << std::endl; - std::cerr << "(EE) tunnel.local_dst = " << tunnel.local_dst << std::endl; - std::cerr << "(EE) item->PeerId() = " << item->PeerId() << std::endl; - std::cerr << "(EE) This item is probably lost while tunnel route got redefined. Deleting this item." << std::endl ; - delete item ; - return ; - } - - // Let's figure out whether this packet is for us or not. - - if(item->PeerId() == tunnel.local_dst && tunnel.local_src != _own_id) //direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT && - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding generic item to peer " << tunnel.local_src << std::endl ; -#endif - item->PeerId(tunnel.local_src) ; - - _traffic_info_buffer.unknown_updn_Bps += RsTurtleSerialiser().size(item) ; - - // This has been disabled for compilation reasons. Not sure we actually need it. - // - //if(dynamic_cast(item) != NULL) - // item->setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA) ; - - sendItem(item) ; - return ; - } - - if(item->PeerId() == tunnel.local_src && tunnel.local_dst != _own_id) //direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER && - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding generic item to peer " << tunnel.local_dst << std::endl ; -#endif - item->PeerId(tunnel.local_dst) ; - - _traffic_info_buffer.unknown_updn_Bps += RsTurtleSerialiser().size(item); - - sendItem(item) ; - return ; - } - - // item is for us. Use the locked region to record the data. - - _traffic_info_buffer.data_dn_Bps += RsTurtleSerialiser().size(item); - } - - // The packet was not forwarded, so it is for us. Let's treat it. - // This is done off-mutex, to avoid various deadlocks - // - - handleRecvGenericTunnelItem(item) ; - - delete item ; -} - -void p3turtle::handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "p3Turtle: received Generic tunnel item:" << std::endl ; - item->print(std::cerr,1) ; -#endif - RsFileHash hash ; - RsPeerId vpid ; - RsTurtleClientService *service ; - - if(!getTunnelServiceInfo(item->tunnelId(),vpid,hash,service)) - return ; - - service->receiveTurtleData(item,hash,vpid,item->travelingDirection()) ; -} - -bool p3turtle::getTunnelServiceInfo(TurtleTunnelId tunnel_id,RsPeerId& vpid,RsFileHash& hash,RsTurtleClientService *& service) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it2(_local_tunnels.find(tunnel_id)) ; - - if(it2 == _local_tunnels.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: unknown tunnel id " << std::hex << tunnel_id << std::dec << std::endl ; -#endif - return false; - } - - TurtleTunnel& tunnel(it2->second) ; - -#ifdef P3TURTLE_DEBUG - assert(!tunnel.hash.isNull()) ; - - std::cerr << " This is an endpoint for this file map." << std::endl ; - std::cerr << " Forwarding data to the multiplexer." << std::endl ; - std::cerr << " using peer_id=" << tunnel.vpid << ", hash=" << tunnel.hash << std::endl ; -#endif - // We should check that there is no backward call to the turtle router! - // - vpid = tunnel.vpid ; - hash = tunnel.hash ; - - // Now sort out the case of client vs. server side items. - // - if(tunnel.local_src == _own_id) - { - std::map::const_iterator it = _incoming_file_hashes.find(hash) ; - - if(it == _incoming_file_hashes.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << hash << " for client side tunnel endpoint " << std::hex << tunnel_id << std::dec << " has been removed (probably a late response)! Dropping the item. " << std::endl; -#endif - return false; - } - - service = it->second.service ; - } - else if(tunnel.local_dst == _own_id) - { - std::map::const_iterator it = _outgoing_tunnel_client_services.find(tunnel_id) ; - - if(it == _outgoing_tunnel_client_services.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << tunnel.hash << " for server side tunnel endpoint " << std::hex << tunnel_id << std::dec << " has been removed (probably a late response)! Dropping the item. " << std::endl; -#endif - return false; - } - - service = it->second; - } - else - { - std::cerr << "p3turtle::handleRecvGenericTunnelItem(): hash " << hash << " for tunnel " << std::hex << it2->first << std::dec << ". Tunnel is not a end-point or a starting tunnel!! This is a serious consistency error." << std::endl; - return false ; - } - - return true ; -} -// Send a data request into the correct tunnel for the given file hash -// -void p3turtle::sendTurtleData(const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem *item) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // get the proper tunnel for this file hash and peer id. - std::map::const_iterator it(_virtual_peers.find(virtual_peer_id)) ; - - if(it == _virtual_peers.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle::senddataRequest: cannot find virtual peer " << virtual_peer_id << " in VP list." << std::endl ; -#endif - delete item ; - return ; - } - TurtleTunnelId tunnel_id = it->second ; - std::map::iterator it2( _local_tunnels.find(tunnel_id) ) ; - - if(it2 == _local_tunnels.end()) - { - std::cerr << "p3turtle::client asked to send a packet through tunnel that has previously been deleted. Not a big issue unless it happens in masses." << std::endl; - delete item ; - return ; - } - TurtleTunnel& tunnel(it2->second) ; - - item->tunnel_id = tunnel_id ; // we should randomly select a tunnel, or something more clever. - - uint32_t ss = RsTurtleSerialiser().size(item); - - if(item->shouldStampTunnel()) - tunnel.time_stamp = time(NULL) ; - - tunnel.transfered_bytes += ss ; - - if(tunnel.local_src == _own_id) - { - item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_SERVER) ; - item->PeerId(tunnel.local_dst) ; - _traffic_info_buffer.data_dn_Bps += ss ; - } - else if(tunnel.local_dst == _own_id) - { - item->setTravelingDirection(RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; - item->PeerId(tunnel.local_src) ; - _traffic_info_buffer.data_up_Bps += ss ; - } - else - { - std::cerr << "p3Turtle::sendTurtleData(): asked to send a packet into a tunnel that is not registered. Dropping packet." << std::endl ; - delete item ; - return ; - } - -#ifdef P3TURTLE_DEBUG - std::cerr << "p3turtle: sending service packet to virtual peer id " << virtual_peer_id << ", hash=0x" << tunnel.hash << ", tunnel = " << HEX_PRINT(item->tunnel_id) << ", next peer=" << tunnel.local_dst << std::endl ; -#endif - sendItem(item) ; -} - -bool p3turtle::isTurtlePeer(const RsPeerId& peer_id) const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - return _virtual_peers.find(peer_id) != _virtual_peers.end() ; -} - -RsPeerId p3turtle::getTurtlePeerId(TurtleTunnelId tid) const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - std::map::const_iterator it( _local_tunnels.find(tid) ) ; - -#ifdef P3TURTLE_DEBUG - assert(it!=_local_tunnels.end()) ; - assert(!it->second.vpid.isNull()) ; -#endif - - return it->second.vpid ; -} - -bool p3turtle::isOnline(const RsPeerId& peer_id) const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // we could do something mre clever here... - // - return _virtual_peers.find(peer_id) != _virtual_peers.end() ; -} - - -// -----------------------------------------------------------------------------------// -// -------------------------------- Tunnel handling. ------------------------------- // -// -----------------------------------------------------------------------------------// -// - -TurtleRequestId p3turtle::diggTunnel(const TurtleFileHash& hash) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "DiggTunnel: performing tunnel request. OwnId = " << _own_id << " for hash=" << hash << std::endl ; -#endif - TurtleRequestId id = generateRandomRequestId() ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - // Store the request id, so that we can find the hash back when we get the response. - // - _incoming_file_hashes[hash].last_request = id ; - _incoming_file_hashes[hash].last_digg_time = time(NULL) ; - } - - // Form a tunnel request packet that simulates a request from us. - // - RsTurtleOpenTunnelItem *item = new RsTurtleOpenTunnelItem ; - - item->PeerId(_own_id) ; - item->file_hash = hash ; - item->request_id = id ; - item->partial_tunnel_id = generatePersonalFilePrint(hash,_random_bias,true) ; - item->depth = 0 ; - - // send it - -#ifdef TUNNEL_STATISTICS - TS_request_bounces[item->request_id].clear() ; // forces initialization -#endif - handleTunnelRequest(item) ; - delete item ; - - return id ; -} - -void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item) -{ -#ifdef P3TURTLE_DEBUG - std::cerr << "Received tunnel request from peer " << item->PeerId() << ": " << std::endl ; - item->print(std::cerr,0) ; -#endif - - // check first if the hash is in the ban list. If so, drop the request. - - if(rsFiles->isHashBanned(item->file_hash)) - { - std::cerr << "(II) Rejecting tunnel request to ban hash " << item->file_hash << std::endl; - return ; - } - -#ifdef TUNNEL_STATISTICS - if(TS_request_bounces.find(item->request_id) != TS_request_bounces.end()) - TS_request_bounces[item->request_id].push_back(time(NULL)) ; -#endif - // TR forwarding. We must pay attention not to flood the network. The policy is to force a statistical behavior - // according to the followin grules: - // - below a number of tunnel request forwards per second MAX_TR_FORWARD_PER_SEC, we keep the traffic - // - if we get close to that limit, we drop long tunnels first with a probability that is larger for long tunnels - // - // Variables involved: - // distance_to_maximum : in [0,inf] is the proportion of the current up TR speed with respect to the maximum allowed speed. This is estimated - // as an average between the average number of TR over the 60 last seconds and the current TR up speed. - // corrected_distance : in [0,inf] is a squeezed version of distance: small values become very small and large values become very large. - // depth_peer_probability : basic probability of forwarding when the speed limit is reached. - // forward_probability : final probability of forwarding the packet, per peer. - // - // When the number of peers increases, the speed limit is reached faster, but the behavior per peer is the same. - // - - float forward_probability ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _traffic_info_buffer.tr_dn_Bps += RsTurtleSerialiser().size(item); - - float distance_to_maximum = std::min(100.0f,_traffic_info.tr_up_Bps/(float)(TUNNEL_REQUEST_PACKET_SIZE*_max_tr_up_rate)) ; - float corrected_distance = pow(distance_to_maximum,DISTANCE_SQUEEZING_POWER) ; - forward_probability = pow(depth_peer_probability[std::min((uint16_t)6,item->depth)],corrected_distance) ; -#ifdef P3TURTLE_DEBUG - std::cerr << "Forwarding probability: depth=" << item->depth << ", distance to max speed=" << distance_to_maximum << ", corrected=" << corrected_distance << ", prob.=" << forward_probability << std::endl; -#endif - } - - // If the item contains an already handled tunnel request, give up. This - // happens when the same tunnel request gets relayed by different peers. We - // have to be very careful here, not to call ftController while mTurtleMtx is - // locked. - // - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - std::map::iterator it = _tunnel_requests_origins.find(item->request_id) ; - - if(it != _tunnel_requests_origins.end()) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " This is a bouncing request. Ignoring and deleting item." << std::endl ; -#endif - return ; - } - // This is a new request. Let's add it to the request map, and forward - // it to open peers, while the mutex is locked, so no-one can trigger the - // lock before the data is consistent. - - TurtleTunnelRequestInfo& req( _tunnel_requests_origins[item->request_id] ) ; - req.origin = item->PeerId() ; - req.time_stamp = time(NULL) ; - req.depth = item->depth ; - -#ifdef TUNNEL_STATISTICS - std::cerr << "storing tunnel request " << (void*)(item->request_id) << std::endl ; - - ++TS_tunnel_length[item->depth] ; - TS_request_time_stamps[item->file_hash].push_back(std::pair(time(NULL),item->request_id)) ; -#endif - } - - // If it's not for us, perform a local search. If something found, forward the search result back. - // We're off-mutex here. - - bool found = false ; - //std::string info ; - RsTurtleClientService *service = NULL ; - - if(item->PeerId() != _own_id) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Request not from us. Performing local search" << std::endl ; -#endif - found = performLocalHashSearch(item->file_hash,item->PeerId(),service) ; - } - - { - if(found) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Local hash found. Sending tunnel ok to origin (" << item->PeerId() << ")." << std::endl ; -#endif - // Send back tunnel ok to the same guy - // - RsTurtleTunnelOkItem *res_item = new RsTurtleTunnelOkItem ; - TurtleVirtualPeerId vpid ; - - res_item->request_id = item->request_id ; - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - res_item->tunnel_id = item->partial_tunnel_id ^ generatePersonalFilePrint(item->file_hash,_random_bias,false) ; - - res_item->PeerId(item->PeerId()) ; - - TurtleTunnelId t_id = res_item->tunnel_id ; // save it because sendItem deletes the item - - sendItem(res_item) ; - - // Note in the tunnels list that we have an ending tunnel here. - TurtleTunnel tt ; - tt.local_src = item->PeerId() ; - tt.hash = item->file_hash ; - tt.local_dst = _own_id ; // this means us - tt.time_stamp = time(NULL) ; - tt.transfered_bytes = 0 ; - tt.speed_Bps = 0.0f ; - - _local_tunnels[t_id] = tt ; - - // We add a virtual peer for that tunnel+hash combination. - // - locked_addDistantPeer(item->file_hash,t_id) ; - - // Store some info string about the tunnel. - // - _outgoing_tunnel_client_services[t_id] = service ; - - vpid = _local_tunnels[t_id].vpid; - } - - // Notify the client service that there's a new virtual peer id available as a client. - // - service->addVirtualPeer(item->file_hash,vpid,RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ; - - // We return straight, because when something is found, there's no need to digg a tunnel further. - // - - return ; - } -#ifdef P3TURTLE_DEBUG - else - std::cerr << " No hash found locally, or local file not allowed for distant peers. Forwarding. " << std::endl ; -#endif - } - - // If search depth not too large, also forward this search request to all other peers. - // - bool random_bypass = (item->depth >= TURTLE_MAX_SEARCH_DEPTH && (((_random_bias ^ item->partial_tunnel_id)&0x7)==2)) ; - bool random_dshift = (item->depth == 1 && (((_random_bias ^ item->partial_tunnel_id)&0x7)==6)) ; - - // Multi-tunneling trick: consistently perturbate the half-tunnel id: - // - the tunnel id will now be unique for a given route - // - allows a better balance of bandwidth for a given transfer - // - avoid the waste of items that get lost when re-routing a tunnel - -#ifdef P3TURTLE_DEBUG - std::cerr << "Perturbating partial tunnel id. Original=" << std::hex << item->partial_tunnel_id ; -#endif - item->partial_tunnel_id = generatePersonalFilePrint(item->file_hash,item->partial_tunnel_id ^ _random_bias,true) ; - -#ifdef P3TURTLE_DEBUG - std::cerr << " new=" << item->partial_tunnel_id << std::dec << std::endl; -#endif - - if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass) - { - std::set onlineIds ; - mServiceControl->getPeersConnected(_service_type, onlineIds); - -// for(std::set::iterator it(onlineIds.begin());it!=onlineIds.end();) -// if(!mServiceControl->isPeerConnected(RS_SERVICE_PERM_TURTLE,*it)) -// { -// std::set::iterator tmp = it++ ; -// onlineIds.erase(tmp) ; -// } -// else -// ++it ; - - int nb_online_ids = onlineIds.size() ; - - if(forward_probability * nb_online_ids < 1.0f && nb_online_ids > 0) - { - forward_probability = 1.0f / nb_online_ids ; - - // Setting forward_probability to 1/nb_online_ids forces at most one TR up per TR dn. But if we are overflooded by - // TR dn, we still need to control them to avoid flooding the pqiHandler outqueue. So we additionally moderate the - // forward probability so as to reduct the output rate accordingly. - // - if(_traffic_info.tr_dn_Bps / (float)TUNNEL_REQUEST_PACKET_SIZE > _max_tr_up_rate) - forward_probability *= _max_tr_up_rate*TUNNEL_REQUEST_PACKET_SIZE / (float)_traffic_info.tr_dn_Bps ; - } - -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding tunnel request: Looking for online peers" << std::endl ; -#endif - - for(std::set::const_iterator it(onlineIds.begin());it!=onlineIds.end();++it) - { - uint32_t linkType = mLinkMgr->getLinkType(*it); - - if ((linkType & RS_NET_CONN_SPEED_TRICKLE) || (linkType & RS_NET_CONN_SPEED_LOW)) // don't forward tunnel requests to slow link types (e.g relay peers)! - continue ; - - if(*it != item->PeerId() && RSRandom::random_f32() <= forward_probability) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding request to peer = " << *it << std::endl ; -#endif - // Copy current item and modify it. - RsTurtleOpenTunnelItem *fwd_item = new RsTurtleOpenTunnelItem(*item) ; - - // increase search depth, except in some rare cases, to prevent correlation between - // TR sniffing and friend names. The strategy is to not increase depth if the depth - // is 1: - // If B receives a TR of depth 1 from A, B cannot deduice that A is downloading the - // file, since A might have shifted the depth. - // - if(!random_dshift) - ++(fwd_item->depth) ; // increase tunnel depth - - fwd_item->PeerId(*it) ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - _traffic_info_buffer.tr_up_Bps += RsTurtleSerialiser().size(fwd_item); - } - - sendItem(fwd_item) ; - } - } - } -#ifdef P3TURTLE_DEBUG - else - std::cout << " Dropping this item, as tunnel depth is " << item->depth << std::endl ; -#endif -} - -void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) -{ - bool new_tunnel = false ; - TurtleFileHash new_hash ; - RsPeerId new_vpid ; - RsTurtleClientService *service = NULL ; - - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // Find who actually sent the corresponding turtle tunnel request. - // - std::map::iterator it = _tunnel_requests_origins.find(item->request_id) ; -#ifdef P3TURTLE_DEBUG - std::cerr << "Received tunnel result:" << std::endl ; - item->print(std::cerr,0) ; -#endif - - if(it == _tunnel_requests_origins.end()) - { - // This is an error: how could we receive a tunnel result corresponding to a tunnel item we - // have forwarded but that it not in the list ?? Actually that happens, when tunnel requests - // get too old, before the tunnelOk item gets back. But this is quite unusual. - -#ifdef P3TURTLE_DEBUG - std::cerr << __PRETTY_FUNCTION__ << ": tunnel result has no peer direction!" << std::endl ; -#endif - return ; - } - if(it->second.responses.find(item->tunnel_id) != it->second.responses.end()) - { - std::cerr << "p3turtle: ERROR: received a tunnel response twice. That should not happen." << std::endl; - return ; - } - else - it->second.responses.insert(item->tunnel_id) ; - - // store tunnel info. - bool found = (_local_tunnels.find(item->tunnel_id) != _local_tunnels.end()) ; - TurtleTunnel& tunnel(_local_tunnels[item->tunnel_id]) ; - - if(found) - { -#ifdef P3TURTLE_DEBUG - std::cerr << "Tunnel id " << HEX_PRINT(item->tunnel_id) << " is already there. Not storing." << std::endl ; -#endif - } - else - { - tunnel.local_src = it->second.origin ; - tunnel.local_dst = item->PeerId() ; - tunnel.hash.clear() ; - tunnel.time_stamp = time(NULL) ; - tunnel.transfered_bytes = 0 ; - tunnel.speed_Bps = 0.0f ; - -#ifdef P3TURTLE_DEBUG - std::cerr << " storing tunnel info. src=" << tunnel.local_src << ", dst=" << tunnel.local_dst << ", id=" << item->tunnel_id << std::endl ; -#endif - } - - // Is this result too old? - // Tunnel Requests younger than TUNNEL_REQUESTS_LIFE_TIME are kept in the cache, so that they are not duplicated if they bounce in the network - // Nevertheless results received for Tunnel Requests older than TUNNEL_REQUESTS_RESULT_TIME are considered obsolete and discarded - if (time(NULL) > it->second.time_stamp + TUNNEL_REQUESTS_RESULT_TIME) - { -#ifdef P3TURTLE_DEBUG - RsDbg() << "TURTLE p3turtle::handleTunnelResult Tunnel Request is known, but result arrives too late, dropping"; -#endif - return; - } - - // Is this result's target actually ours ? - - if(it->second.origin == _own_id) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Tunnel starting point. Storing id=" << HEX_PRINT(item->tunnel_id) << " for hash (unknown) and tunnel request id " << it->second.origin << std::endl; -#endif - // Tunnel is ending here. Add it to the list of tunnels for the given hash. - - // 1 - find which file hash issued this request. This is not costly, - // because there is not too much file hashes to be active at a time, - // and this mostly prevents from sending the hash back in the tunnel. - -#ifdef P3TURTLE_DEBUG - bool ext_found = false ; -#endif - for(std::map::iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) - if(it->second.last_request == item->request_id) - { -#ifdef P3TURTLE_DEBUG - ext_found = true ; -#endif - - { - // add the tunnel uniquely - bool found = false ; - - for(unsigned int j=0;jsecond.tunnels.size();++j) - if(it->second.tunnels[j] == item->tunnel_id) - found = true ; - - if(!found) - it->second.tunnels.push_back(item->tunnel_id) ; - - tunnel.hash = it->first ; // because it's a local tunnel - - // Adds a virtual peer to the list of online peers. - // We do this later, because of the mutex protection. - // - new_tunnel = true ; - new_hash = it->first ; - service = it->second.service ; - - locked_addDistantPeer(new_hash,item->tunnel_id) ; - new_vpid = _local_tunnels[item->tunnel_id].vpid ; // save it for off-mutex usage. - } - } -#ifdef P3TURTLE_DEBUG - if(!ext_found) - std::cerr << "p3turtle: error. Could not find hash that emmitted tunnel request " << reinterpret_cast(item->tunnel_id) << std::endl ; -#endif - } - else - { // Nope, forward it back. -#ifdef P3TURTLE_DEBUG - std::cerr << " Forwarding result back to " << it->second.origin << std::endl; -#endif - RsTurtleTunnelOkItem *fwd_item = new RsTurtleTunnelOkItem(*item) ; // copy the item - fwd_item->PeerId(it->second.origin) ; - - sendItem(fwd_item) ; - } - } - - // A new tunnel has been created. Add the corresponding virtual peer to the list, and - // notify the file transfer controller for the new file source. This should be done off-mutex - // so we deported this code here. - // - if(new_tunnel && service != NULL) - service->addVirtualPeer(new_hash,new_vpid,RsTurtleGenericTunnelItem::DIRECTION_SERVER) ; -} - -// -----------------------------------------------------------------------------------// -// ------------------------------ IO with libretroshare ----------------------------// -// -----------------------------------------------------------------------------------// -// - - -void RsTurtleStringSearchRequestItem::search(std::list& result) const -{ - /* call to core */ - std::list initialResults; - std::list words ; - - // to do: split search string into words. - words.push_back(match_string) ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "Performing rsFiles->search()" << std::endl ; -#endif - // now, search! - rsFiles->SearchKeywords(words, initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId()); - -#ifdef P3TURTLE_DEBUG - std::cerr << initialResults.size() << " matches found." << std::endl ; -#endif - result.clear() ; - - for(std::list::const_iterator it(initialResults.begin());it!=initialResults.end();++it) - { - // retain only file type - if (it->type == DIR_TYPE_DIR) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Skipping directory " << it->name << std::endl ; -#endif - continue; - } - - TurtleFileInfo i ; - i.hash = it->hash ; - i.size = it->size ; - i.name = it->name ; - - result.push_back(i) ; - } -} -void RsTurtleRegExpSearchRequestItem::search(std::list& result) const -{ - /* call to core */ - std::list initialResults; - - // to do: split search string into words. - RsRegularExpression::Expression *exp = RsRegularExpression::LinearizedExpression::toExpr(expr) ; - - if(exp == NULL) - return ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "Local search on exp: " << exp->toStdString() << std::endl; -#endif - - // now, search! - rsFiles->SearchBoolExp(exp,initialResults,RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_SEARCHABLE,PeerId()); - - result.clear() ; - - for(std::list::const_iterator it(initialResults.begin());it!=initialResults.end();++it) - { - // retain only file type - if (it->type == DIR_TYPE_DIR) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Skipping directory " << it->name << std::endl ; -#endif - continue; - } - TurtleFileInfo i ; - i.hash = it->hash ; - i.size = it->size ; - i.name = it->name ; - - result.push_back(i) ; - } - delete exp ; -} - -TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match) -{ - // generate a new search id. - - TurtleRequestId id = generateRandomRequestId() ; - - // Form a request packet that simulates a request from us. - // - RsTurtleStringSearchRequestItem *item = new RsTurtleStringSearchRequestItem ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "performing search. OwnId = " << _own_id << std::endl ; -#endif - - item->PeerId(_own_id) ; - item->match_string = string_to_match ; - item->request_id = id ; - item->depth = 0 ; - - // send it - - handleSearchRequest(item) ; - - delete item ; - - return id ; -} -TurtleRequestId p3turtle::turtleSearch(const RsRegularExpression::LinearizedExpression& expr) -{ - // generate a new search id. - - TurtleRequestId id = generateRandomRequestId() ; - - // Form a request packet that simulates a request from us. - // - RsTurtleRegExpSearchRequestItem *item = new RsTurtleRegExpSearchRequestItem ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "performing search. OwnId = " << _own_id << std::endl ; -#endif - - item->PeerId(_own_id) ; - item->expr = expr ; - item->request_id = id ; - item->depth = 0 ; - - // send it - - handleSearchRequest(item) ; - - delete item ; - - return id ; -} - -TurtleRequestId p3turtle::turtleSearch(unsigned char *search_bin_data,uint32_t search_bin_data_len,RsTurtleClientService *client_service) -{ - // generate a new search id. - - TurtleRequestId id = generateRandomRequestId() ; - - // Form a request packet that simulates a request from us. - // - RsTurtleGenericSearchRequestItem item ; - -#ifdef P3TURTLE_DEBUG - std::cerr << "performing search. OwnId = " << _own_id << std::endl ; -#endif - - item.PeerId(_own_id) ; - item.service_id = client_service->serviceId(); - item.search_data = search_bin_data ; - item.search_data_len = search_bin_data_len ; - item.request_id = id ; - item.depth = 0 ; - - // send it - - handleSearchRequest(&item) ; - - return id ; -} - -void p3turtle::monitorTunnels(const RsFileHash& hash,RsTurtleClientService *client_service,bool allow_multi_tunnels) -{ - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - // First, check if the hash is tagged for removal (there's a delay) - - if(_hashes_to_remove.erase(hash) > 0) - { -#ifdef P3TURTLE_DEBUG - TURTLE_DEBUG() << "p3turtle: File hash " << hash << " Was scheduled for removal. Canceling the removal." << std::endl ; -#endif - } - - // Then, check if the hash is already there - // - if(_incoming_file_hashes.find(hash) != _incoming_file_hashes.end()) // download already asked. - { -#ifdef P3TURTLE_DEBUG - TURTLE_DEBUG() << "p3turtle: File hash " << hash << " already in pool. Returning." << std::endl ; -#endif - return ; - } -#ifdef P3TURTLE_DEBUG - TURTLE_DEBUG() << "p3turtle: Received order for turtle download fo hash " << hash << std::endl ; -#endif - - // No tunnels at start, but this triggers digging new tunnels. - // - _incoming_file_hashes[hash].tunnels.clear(); - _incoming_file_hashes[hash].use_aggressive_mode = allow_multi_tunnels ; - - // also should send associated request to the file transfer module. - _incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ; - _incoming_file_hashes[hash].service = client_service ; - } -} - - -// RsTurtleGxsSearchResultGroupSummaryItem *gxs_sr_gs = dynamic_cast(item) ; -// -// if(gxs_sr_gs != NULL) -// { -// RsServer::notify()->notifyTurtleSearchResult(gxs_sr_gs->request_id,gxs_sr_gs->result) ; -// return ; -// } -// RsTurtleGxsSearchResultGroupDataItem *gxs_sr_gd = dynamic_cast(item) ; -// -// if(gxs_sr_gd != NULL) -// { -//#warning MISSING CODE HERE TO HANDLE ENCRYPTED INCOMING GROUP DATA. -// //RsServer::notify()->notifyTurtleSearchResult(gxs_sr_gd->request_id,gxs_sr_gd->encrypted_nxs_group) ; -// return ; -// } - -/// Warning: this function should never be called while the turtle mutex is locked. -/// Otherwize this is a possible source of cross-lock with the File mutex. -// -bool p3turtle::performLocalHashSearch(const TurtleFileHash& hash,const RsPeerId& peer_id,RsTurtleClientService *& service) -{ - std::map client_map ; - { - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - if(_registered_services.empty()) - { - std::cerr << "Turtle router has no services registered. Tunnel requests cannot be handled." << std::endl; - return false ; - } - - client_map = _registered_services ; - } - - for(auto it(client_map.begin());it!=client_map.end();++it) - if( (*it).second->handleTunnelRequest(hash,peer_id)) - { - service = it->second ; - return true ; - } - - return false ; -} - - -void p3turtle::registerTunnelService(RsTurtleClientService *service) -{ - std::cerr << "p3turtle: registered new tunnel service with ID=" << std::hex << service->serviceId() << std::dec << " and pointer " << (void*)service << std::endl; - - _registered_services[service->serviceId()] = service ; - _serialiser->registerClientService(service) ; -} - -static std::string printFloatNumber(float num,bool friendly=false) -{ - if(friendly) - { - char tmp[100] ; - std::string units[4] = { "B/s","KB/s","MB/s","GB/s" } ; - - int k=0 ; - while(num >= 800.0f && k<4) - num /= 1024.0f,++k; - - sprintf(tmp,"%3.2f %s",num,units[k].c_str()) ; - return std::string(tmp) ; - } - else - { - std::string out ; - rs_sprintf(out, "%g", num) ; - return out ; - } -} -static std::string printNumber(uint64_t num,bool hex=false) -{ - if(hex) - { - char tmp[100] ; - - if(num < (((uint64_t)1)<<32)) - sprintf(tmp,"%08x", uint32_t(num)) ; - else - sprintf(tmp,"%08x%08x", uint32_t(num >> 32),uint32_t(num & ( (((uint64_t)1)<<32)-1 ))) ; - return std::string(tmp) ; - } - else - { - std::string out ; - rs_sprintf(out, "%lld", num) ; - return out ; - } -} - -void p3turtle::getTrafficStatistics(TurtleTrafficStatisticsInfo& info) const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - info = _traffic_info ; - - float distance_to_maximum = std::min(100.0f,info.tr_up_Bps/(float)(TUNNEL_REQUEST_PACKET_SIZE*_max_tr_up_rate)) ; - info.forward_probabilities.clear() ; - - std::set onlineIds ; - mServiceControl->getPeersConnected(_service_type, onlineIds); - - int nb_online_ids = onlineIds.size() ; - - for(int i=0;i<=6;++i) - { - float corrected_distance = pow(distance_to_maximum,DISTANCE_SQUEEZING_POWER) ; - float forward_probability = pow(depth_peer_probability[i],corrected_distance) ; - - if(forward_probability * nb_online_ids < 1.0f && nb_online_ids > 0) - { - forward_probability = 1.0f / nb_online_ids ; - - if(_traffic_info.tr_dn_Bps / (float)TUNNEL_REQUEST_PACKET_SIZE > _max_tr_up_rate) - forward_probability *= _max_tr_up_rate*TUNNEL_REQUEST_PACKET_SIZE / (float)_traffic_info.tr_dn_Bps ; - } - - info.forward_probabilities.push_back(forward_probability) ; - } -} - -std::string p3turtle::getPeerNameForVirtualPeerId(const RsPeerId& virtual_peer_id) -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - std::string name = "unknown"; - std::map::const_iterator it(_virtual_peers.find(virtual_peer_id)) ; - if(it != _virtual_peers.end()) - { - std::map::iterator it2( _local_tunnels.find(it->second) ) ; - if(it2 != _local_tunnels.end()) - { - if(it2->second.local_src == _own_id) - mLinkMgr->getPeerName(it2->second.local_dst,name); - else - mLinkMgr->getPeerName(it2->second.local_src,name); - } - } - return name; -} - -bool p3turtle::encryptData(const unsigned char *clear_data,uint32_t clear_data_size,uint8_t *encryption_master_key,RsTurtleGenericDataItem *& encrypted_item) -{ - unsigned char *encrypted_data = NULL ; - uint32_t encrypted_data_len = 0 ; - - if(!librs::crypto::encryptAuthenticateData(clear_data,clear_data_size,encryption_master_key,encrypted_data,encrypted_data_len)) - { - delete encrypted_item ; - return false ; - } - encrypted_item = new RsTurtleGenericDataItem ; - - encrypted_item->data_bytes = encrypted_data ; - encrypted_item->data_size = encrypted_data_len ; - return true; -} - -bool p3turtle::decryptItem(const RsTurtleGenericDataItem* encrypted_item, uint8_t *encryption_master_key, unsigned char *& decrypted_data, uint32_t& decrypted_data_size) -{ - return librs::crypto::decryptAuthenticateData((unsigned char*)encrypted_item->data_bytes,encrypted_item->data_size,encryption_master_key,decrypted_data,decrypted_data_size); -} - -void p3turtle::getInfo( std::vector >& hashes_info, - std::vector >& tunnels_info, - std::vector& search_reqs_info, - std::vector& tunnel_reqs_info) const -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - hashes_info.clear() ; - - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) - { - hashes_info.push_back(std::vector()) ; - - std::vector& hashes(hashes_info.back()) ; - - hashes.push_back(it->first.toStdString()) ; - //hashes.push_back(it->second.name) ; - hashes.push_back("Name not available") ; - hashes.push_back(printNumber(it->second.tunnels.size())) ; - //hashes.push_back(printNumber(now - it->second.time_stamp)+" secs ago") ; - } - - tunnels_info.clear(); - - for(std::map::const_iterator it(_local_tunnels.begin());it!=_local_tunnels.end();++it) - { - tunnels_info.push_back(std::vector()) ; - std::vector& tunnel(tunnels_info.back()) ; - - tunnel.push_back(printNumber(it->first,true)) ; - - std::string name; - if(mLinkMgr->getPeerName(it->second.local_src,name)) - tunnel.push_back(name) ; - else - tunnel.push_back(it->second.local_src.toStdString()) ; - - if(mLinkMgr->getPeerName(it->second.local_dst,name)) - tunnel.push_back(name) ; - else - tunnel.push_back(it->second.local_dst.toStdString()); - - tunnel.push_back(it->second.hash.toStdString()) ; - tunnel.push_back(printNumber(now-it->second.time_stamp) + " secs ago") ; - tunnel.push_back(printFloatNumber(it->second.speed_Bps,false)) ; // - } - - search_reqs_info.clear(); - - for(std::map::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it) - { - TurtleSearchRequestDisplayInfo info ; - - info.request_id = it->first ; - info.source_peer_id = it->second.origin ; - info.age = now - it->second.time_stamp ; - info.depth = it->second.depth ; - info.keywords = it->second.keywords ; - info.hits = it->second.result_count ; - - search_reqs_info.push_back(info) ; - } - - tunnel_reqs_info.clear(); - - for(std::map::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it) - { - TurtleTunnelRequestDisplayInfo info ; - - info.request_id = it->first ; - info.source_peer_id = it->second.origin ; - info.age = now - it->second.time_stamp ; - info.depth = it->second.depth ; - - tunnel_reqs_info.push_back(info) ; - } -} - -#ifdef P3TURTLE_DEBUG -void p3turtle::dumpState() -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - - rstime_t now = time(NULL) ; - - std::cerr << std::endl ; - std::cerr << "********************** Turtle router dump ******************" << std::endl ; - std::cerr << " Active incoming file hashes: " << _incoming_file_hashes.size() << std::endl ; - for(std::map::const_iterator it(_incoming_file_hashes.begin());it!=_incoming_file_hashes.end();++it) - { - std::cerr << " hash=0x" << it->first << ", tunnel ids =" ; - for(std::vector::const_iterator it2(it->second.tunnels.begin());it2!=it->second.tunnels.end();++it2) - std::cerr << " " << HEX_PRINT(*it2) ; - //std::cerr << ", last_req=" << (void*)it->second.last_request << ", time_stamp = " << it->second.time_stamp << "(" << now-it->second.time_stamp << " secs ago)" << std::endl ; - } - std::cerr << " Active outgoing file hashes: " << _outgoing_tunnel_client_services.size() << std::endl ; - for(std::map::const_iterator it(_outgoing_tunnel_client_services.begin());it!=_outgoing_tunnel_client_services.end();++it) - std::cerr << " TID=0x" << it->first << std::endl ; - - std::cerr << " Local tunnels:" << std::endl ; - for(std::map::const_iterator it(_local_tunnels.begin());it!=_local_tunnels.end();++it) - std::cerr << " " << HEX_PRINT(it->first) << ": from=" - << it->second.local_src << ", to=" << it->second.local_dst - << ", hash=0x" << it->second.hash << ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp << " secs ago)" - << ", peer id =" << it->second.vpid << std::endl ; - - std::cerr << " buffered request origins: " << std::endl ; - std::cerr << " Search requests: " << _search_requests_origins.size() << std::endl ; - - for(std::map::const_iterator it(_search_requests_origins.begin());it!=_search_requests_origins.end();++it) - std::cerr << " " << HEX_PRINT(it->first) << ": from=" << it->second.origin - << ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp - << " secs ago)" - << it->second.result_count << " hits" << std::endl ; - - std::cerr << " Tunnel requests: " << _tunnel_requests_origins.size() << std::endl ; - for(std::map::const_iterator it(_tunnel_requests_origins.begin());it!=_tunnel_requests_origins.end();++it) - std::cerr << " " << HEX_PRINT(it->first) << ": from=" << it->second.origin - << ", ts=" << it->second.time_stamp << " (" << now-it->second.time_stamp - << " secs ago)" << std::endl ; - - std::cerr << " Virtual peers:" << std::endl ; - for(std::map::const_iterator it(_virtual_peers.begin());it!=_virtual_peers.end();++it) - std::cerr << " id=" << it->first << ", tunnel=" << HEX_PRINT(it->second) << std::endl ; - std::cerr << " Online peers: " << std::endl ; -// for(std::list::const_iterator it(_online_peers.begin());it!=_online_peers.end();++it) -// std::cerr << " id=" << it->id << ", name=" << it->name << ", state=" << it->state << ", actions=" << it->actions << std::endl ; -} -#endif - -#ifdef TUNNEL_STATISTICS -void p3turtle::TS_dumpState() -{ - RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ - rstime_t now = time(NULL) ; - std::cerr << "Dumping tunnel statistics:" << std::endl; - - std::cerr << "TR Bounces: " << TS_request_bounces.size() << std::endl; - for(std::map >::const_iterator it(TS_request_bounces.begin());it!=TS_request_bounces.end();++it) - { - std::cerr << (void*)it->first << ": " ; - for(uint32_t i=0;isecond.size();++i) - std::cerr << it->second[i] - it->second[0] << " " ; - std::cerr << std::endl; - } - std::cerr << "TR in cache: " << _tunnel_requests_origins.size() << std::endl; - std::cerr << "TR by size: " ; - for(int i=0;i<8;++i) - std::cerr << "N(" << i << ")=" << TS_tunnel_length[i] << ", " ; - std::cerr << std::endl; - - std::cerr << "Total different requested files: " << TS_request_time_stamps.size() << std::endl; - for(std::map > >::const_iterator it(TS_request_time_stamps.begin());it!=TS_request_time_stamps.end();++it) - { - std::cerr << "hash = " << it->first << ": seconds ago: " ; - float average = 0 ; - for(uint32_t i=std::max(0,(int)it->second.size()-25);isecond.size();++i) - { - std::cerr << now - it->second[i].first << " (" << (void*)it->second[i].second << ") " ; - - if(i>0) - average += it->second[i].first - it->second[i-1].first ; - } - - if(it->second.size()>1) - std::cerr << ", average delay=" << average/(float)(it->second.size()-1) << std::endl; - else - std::cerr << std::endl; - } -} -#endif diff --git a/libretroshare/src/turtle/p3turtle.h b/libretroshare/src/turtle/p3turtle.h deleted file mode 100644 index 6c0b0012d..000000000 --- a/libretroshare/src/turtle/p3turtle.h +++ /dev/null @@ -1,473 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: p3turtle.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -//====================================== General setup of the router ===================================// -// -// This class implements the turtle hopping router. It basically serves as -// - a cache of turtle tunnels which are the communicating ways between distant peers. -// - turtle tunnels are either end-point tunnels, or transitory points, in which case items are just -// re-serialized and passed on along the tunnel. -// - turtle tunnels are dug on request when calling diggTurtleTunnel(const std::string& hash) -// this command lets a trace in each peer along the tunnel of where -// packets come from and where they should go. Doing so, once a tunnel is -// dug, packets are directly forwarded to the correct peer. -// - an entry point for search request from the interface -// - search results, as they come back, are forwarded upwards with some additional info: -// - depth // depth of the file. setup to 1 for immediate friends and 2 for long distance friends. -// - hash // hash of the file found -// - name // name of the file found -// - search request id. // -// -// - when downloading: -// - for a given hash, a set of starting tunnels is maintained. Transitory -// tunnels are also maintained for other hashes as requested by distant -// peers. -// -//============================================= Operations =============================================// -// -// A download session works as follows: -// Initiation: -// 1 - the user searches for files (turtle search), and selects one and clicks download. -// 2 - In parallel: -// - the ft module gets a request, and searches for peers to provide this using its search modules. -// - the turtle router is informed that a turtle download will happen with the given hash, so -// it initiates tunnels for this hash. -// In a loop: -// 3 - the ft module asks the hash to the turtle searchModule, and sends file requests to the pqi -// interface of this module. -// 4 - the turtle pqi interface forwards these requests to the turtle router, which sends them to -// the correct peers, selecting randomly among all the possible tunnels for this hash. -// 5 - when a file data packet gets back, the turtle router forwards it back to the file transfer module. -// -//================================ connection to the file transfer module ===============================// -// -// The turtle router should provide the ft module with the necessary interface for asking files, and -// retreiving data: -// - a search module that responds with a given fake peer id for hash request for which it has tunnels. -// - a pqi interface to ask for file data -// - p3turtle sends back file data packets to the file transfer module -// -//========================================== Tunnel usage rules ========================================// -// -// Tunnels should be used according to their capacity. This is an unsolved problem as for now. -// -//======================================= Tunnel maintenance rules =====================================// -// -// P3turtle should derive from pqihandler, just as p3disc, so that newly connected peers should trigger -// asking for new tunnels, and disconnecting peers should produce a close tunnel packet. To simplify this, -// I maintain a time stamp in tunnels, that is updated each time a file data packet travels in the tunnel. -// Doing so, if a tunnel is not used for some time, it just disapears. Additional rules apply: -// -// - when a peer A connects: -// - initiate new tunnels for all active file hashes (go through the list of hashes) by -// asking to A, for the same hash and the same source. Only report tunnels for which the destination -// endpoint is different, which should not happen in fact, because of bouncing gards. -// -// - when a peer A disconnects. -// - do nothing. -// -// - when receive open tunnel from A -// - check whether it's a bouncing request. If yes, give up. -// - check hash against local files. -// if > 0 -// return tunnel ok item. No need to go forward, as sub tunnels are not useful. -// else -// forward request to peers, notting source and hashes. -// -// - when receive tunnel ok from A -// - no need to check whether we already have this tunnel, as bouncing gards prevent this. -// - leave a trace for the tunnel, and send (forward) backward. -// -// Ids management: -// - tunnel ids should be identical for requests between 2 same peers for the same file hash. -// - tunnel ids should be asymetric -// - tunnel requests should never be identical, to allow searching multiple times for the same string. -// So: -// - when issuing an open tunnel order, -// - a random request id is generated and used for packet routing -// - a partial tunnel id is build, which is unique to the pair (source,file hash) -// - when tunnel_ok is sent back, the tunnel id is completed so that it is unique to the -// triplet (source, destination, file hash). -// -// For these needs, tunnels are represented by: -// - their file hash. Each tunnel is only designed for transferring a single and same file. -// - their local endpoints id. These are the ids of the peers in direction to the source and destination. -// - the tunnel id, which is unique to the triple hash+global source+global destination. -// - there is a difference between source and destination in tunnels. The source is the file asker, the -// destination is the file provider. This helps sorting tunnels. -// - a timestamp, used for cleaning unused tunnels. -// -// The turtle router has: -// - a list of search requests and where to bounce them back. -// - a list of tunnel digging requests and where to bounce them, back. -// - a list of active file hashes, for which is should constantly maintain tunnels. -// - a list of active tunnels, some being transitory, some being endpoints. -// -// Turtle router entries: -// - a function for performing turtle search -// - a function for handling tunnels for a given file hash. -// -// Questions: -// - should tunnels be re-used ? nope. The only useful case would be when two peers are exchanging files, which happens quite rarely. -// - -#include -#include -#include - -#include "pqi/pqinetwork.h" -#include "pqi/pqi.h" -#include "pqi/pqimonitor.h" -#include "ft/ftcontroller.h" -#include "pqi/p3cfgmgr.h" -#include "services/p3service.h" -#include "ft/ftsearch.h" -#include "retroshare/rsturtle.h" -#include "rsturtleitem.h" -#include "turtleclientservice.h" -#include "turtlestatistics.h" - -//#define TUNNEL_STATISTICS - -class ftServer ; -class p3LinkMgr; -class ftDataMultiplex; -class RsSerialiser; - -static const int TURTLE_MAX_SEARCH_DEPTH = 6 ; -static const int TURTLE_MAX_SEARCH_REQ_ACCEPTED_SERIAL_SIZE = 200 ; - -// This classes are used to keep trace of requests (searches and tunnels). -// -class TurtleSearchRequestInfo -{ - public: - TurtlePeerId origin ; // where the request came from. - uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels. - int depth ; // depth of the request. Used to optimize tunnel length. - uint32_t result_count; // responses to this request. Useful to avoid spamming tunnel responses. - std::string keywords; - uint16_t service_id; // ID of the client service who issues the request. This is null if the request does not have a local origin. - uint32_t max_allowed_hits;// Max number of hits allowed for this search. This actually depends on the type of search (files, GXS groups, GXS group data, etc) -}; -class TurtleTunnelRequestInfo -{ - public: - TurtlePeerId origin ; // where the request came from. - uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels. - int depth ; // depth of the request. Used to optimize tunnel length. - std::set responses; // responses to this request. Useful to avoid spamming tunnel responses. -}; - -class TurtleTunnel -{ - public: - /* For all tunnels */ - - TurtlePeerId local_src ; // where packets come from. Direction to the source. - TurtlePeerId local_dst ; // where packets should go. Direction to the destination. - uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels. - uint32_t transfered_bytes ; // total bytes transferred in this tunnel. - float speed_Bps ; // speed of the traffic through the tunnel - - /* For ending/starting tunnels only. */ - - TurtleFileHash hash; // Hash of the file for this tunnel - TurtleVirtualPeerId vpid; // Virtual peer id for this tunnel. -}; - -// This class keeps trace of the activity for the file hashes the turtle router is asked to monitor. -// - -class TurtleHashInfo -{ - public: - std::vector tunnels ; // list of active tunnel ids for this file hash - TurtleRequestId last_request ; // last request for the tunnels of this hash - rstime_t last_digg_time ; // last time the tunnel digging happenned. - RsTurtleClientService *service ; // client service to which items should be sent. Never NULL. - bool use_aggressive_mode ; // allow to re-digg tunnels even when some are already available -}; - -// Subclassing: -// -// Class | Brings what | Usage -// -----------+------------------+------------------------------------------------------ -// p3Service | sendItem() | handle packet sending/receiving to/from friend peers. -// pqiMonitor | configChanged() | handle who's connecting/disconnecting to dig new tunnels -// RsTurtle | start/stop file()| brings interface for turtle service -// ftSearch | search() | used to allow searching for monitored files. -// p3Config | ConfigChanged() | used to load/save .cfg file for turtle variales. -// -----------+------------------+------------------------------------------------------ -// -class p3turtle: public p3Service, public RsTurtle, public p3Config -{ - public: - p3turtle(p3ServiceControl *sc,p3LinkMgr *lm) ; - virtual RsServiceInfo getServiceInfo(); - - // Enables/disable the service. Still ticks, but does nothing. Default is true. - // - virtual void setEnabled(bool) ; - virtual bool enabled() const ; - - // This is temporary, used by Operating Mode. - // Turtle operates when both enabled() && sessionEnabled() are true. - virtual void setSessionEnabled(bool); - virtual bool sessionEnabled() const; - - // Lauches a search request through the pipes, and immediately returns - // the request id, which will be further used by the gui to store results - // as they come back. - // - // The first two methods are old style search requests for FT, while the 3rd one is using a generic search data type, that is only to - // be deserialized by the service. The memory ownership is kept by the calling function. Similarly, the search response will be a - // generic data type that is to be deserialized by the client service. - // - // Eventually, search requests will use the generic system - // even for FT. We need to keep the old method for a while for backward compatibility. - // - virtual TurtleRequestId turtleSearch(const RsRegularExpression::LinearizedExpression& expr) ; - virtual TurtleRequestId turtleSearch(const std::string& string_to_match) ; - virtual TurtleRequestId turtleSearch(unsigned char *search_bin_data,uint32_t search_bin_data_len,RsTurtleClientService *client_service) ; - - // Initiates tunnel handling for the given file hash. tunnels. Launches - // an exception if an error occurs during the initialization process. The - // turtle router itself does not initiate downloads, it only maintains - // tunnels for the given hash. The download should be driven by the file - // transfer module. Maybe this function can do the whole thing: - // - initiate tunnel handling - // - send the file request to the file transfer module - // - populate the file transfer module with the adequate pqi interface and search module. - // - // This function should be called in addition to ftServer::FileRequest() so that the turtle router - // automatically provide tunnels for the file to download. - // - virtual void monitorTunnels(const RsFileHash& file_hash,RsTurtleClientService *client_service, bool allow_multi_tunnels) ; - - /// This should be called when canceling a file download, so that the turtle router stops - /// handling tunnels for this file. - /// - virtual void stopMonitoringTunnels(const RsFileHash& file_hash) ; - - /// This is provided to turtle clients to force the TR to ask tunnels again. To be used wisely: - /// too many tunnel requests will kill the network. This might be useful to speed-up the re-establishment - /// of tunnels that have become irresponsive. - - virtual void forceReDiggTunnels(const TurtleFileHash& hash) ; - - /// Adds a client tunnel service. This means that the service will be added - /// to the list of services that might respond to tunnel requests. - /// Example tunnel services include: - /// - /// p3ChatService: tunnels correspond to private distant chatting - /// ftServer : tunnels correspond to file data transfer - /// - virtual void registerTunnelService(RsTurtleClientService *service) ; - - virtual std::string getPeerNameForVirtualPeerId(const RsPeerId& virtual_peer_id); - - /// get info about tunnels - virtual void getInfo(std::vector >&, - std::vector >&, - std::vector&, - std::vector&) const ; - - virtual void getTrafficStatistics(TurtleTrafficStatisticsInfo& info) const ; - - /************* from p3service *******************/ - - /// This function does many things: - /// - It handles incoming and outgoing packets - /// - it sorts search requests and forwards search results upward. - /// - it cleans unused (tunnel+search) requests. - /// - it maintains the pool of tunnels, for each request file hash. - /// - virtual int tick(); - - virtual void getItemNames(std::map& names) const; - - /************* from p3Config *******************/ - virtual RsSerialiser *setupSerialiser() ; - virtual bool saveList(bool& cleanup, std::list&) ; - virtual bool loadList(std::list& /*load*/) ; - - /************* Communication with clients *******************/ - /// Does the turtle router manages tunnels to this peer ? (this is not a - /// real id, but a fake one, that the turtle router is capable of connecting with a tunnel id). - virtual bool isTurtlePeer(const RsPeerId& peer_id) const ; - - /// sets/gets the max number of forwarded tunnel requests per second. - virtual void setMaxTRForwardRate(int max_tr_up_rate) ; - virtual int getMaxTRForwardRate() const ; - - /// Examines the peer id, finds the turtle tunnel in it, and respond yes if the tunnel is ok and operational. - bool isOnline(const RsPeerId& peer_id) const ; - - /// Returns a unique peer id, corresponding to the given tunnel. - RsPeerId getTurtlePeerId(TurtleTunnelId tid) const ; - - /// returns the list of virtual peers for all tunnels. - void getSourceVirtualPeersList(const TurtleFileHash& hash,std::list& list) ; - - /// Send a data request into the correct tunnel for the given file hash - void sendTurtleData(const RsPeerId& virtual_peer_id, RsTurtleGenericTunnelItem *item) ; - - /// Encrypts/decrypts an item, using a autenticated construction + chacha20, based on the given 32 bytes master key. - /// Input values are not touched (memory is not released). Memory ownership of outputs is left to the client. - /// - static bool encryptData(const unsigned char *clear_data,uint32_t clear_data_size,uint8_t *encryption_master_key,RsTurtleGenericDataItem *& encrypted_item); - static bool decryptItem(const RsTurtleGenericDataItem *item, uint8_t* encryption_master_key, unsigned char *& decrypted_data,uint32_t& decrypted_data_size); - - private: - //--------------------------- Admin/Helper functions -------------------------// - - /// Generates a cyphered combination of ownId() and file hash - uint32_t generatePersonalFilePrint(const TurtleFileHash&,uint32_t seed,bool) ; - - /// Generates a random uint32_t number. - uint32_t generateRandomRequestId() ; - - /// Auto cleaning of unused tunnels, search requests and tunnel requests. - void autoWash() ; - - //------------------------------ Tunnel handling -----------------------------// - - /// initiates tunnels from here to any peers having the given file hash - TurtleRequestId diggTunnel(const TurtleFileHash& hash) ; - - /// adds info related to a new virtual peer. - void locked_addDistantPeer(const TurtleFileHash&, TurtleTunnelId) ; - - /// estimates the speed of the traffic into tunnels. - void estimateTunnelSpeeds() ; - - //----------------------------- Routing functions ----------------------------// - - /// Handle tunnel digging for current file hashes - void manageTunnels() ; - - /// Closes a given tunnel. Should be called with mutex set. - /// The hashes and peers to remove (by calling - /// ftController::removeFileSource() are happended to the supplied vector - /// so that they can be removed off the turtle mutex. - void locked_closeTunnel(TurtleTunnelId tid,std::vector > >& peers_to_remove) ; - - /// Main routing function - int handleIncoming(); - - /// Generic routing function for all tunnel packets that derive from RsTurtleGenericTunnelItem - void routeGenericTunnelItem(RsTurtleGenericTunnelItem *item) ; - - /// specific routing functions for handling particular packets. - void handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item); - bool getTunnelServiceInfo(TurtleTunnelId, RsPeerId& virtual_peer_id, RsFileHash& hash, RsTurtleClientService*&) ; - - // following functions should go to ftServer - void handleSearchRequest(RsTurtleSearchRequestItem *item); - void handleSearchResult(RsTurtleSearchResultItem *item); - void handleTunnelRequest(RsTurtleOpenTunnelItem *item); - void handleTunnelResult(RsTurtleTunnelOkItem *item); - - //------ Functions connecting the turtle router to other components.----------// - - /// Performs a search calling local cache and search structure. - void performLocalSearch (RsTurtleSearchRequestItem *item, uint32_t& req_result_count,std::list& result,uint32_t& max_allowed_hits) ; - void performLocalSearch_files (RsTurtleFileSearchRequestItem *item, uint32_t& req_result_count, std::list& result, uint32_t &max_allowed_hits) ; - void performLocalSearch_generic(RsTurtleGenericSearchRequestItem *item, uint32_t& req_result_count, std::list& result, uint32_t &max_allowed_hits) ; - - /// Returns true if the file with given hash is hosted locally, and accessible in anonymous mode the supplied peer. - virtual bool performLocalHashSearch(const TurtleFileHash& hash,const RsPeerId& client_peer_id,RsTurtleClientService *& service); - - //--------------------------- Local variables --------------------------------// - - /* data */ - p3ServiceControl *mServiceControl; - p3LinkMgr *mLinkMgr; - RsTurtleSerialiser *_serialiser ; - RsPeerId _own_id ; - - mutable RsMutex mTurtleMtx; - - /// keeps trace of who emmitted a given search request - std::map _search_requests_origins ; - - /// keeps trace of who emmitted a tunnel request - std::map _tunnel_requests_origins ; - - /// stores adequate tunnels for each file hash locally managed - std::map _incoming_file_hashes ; - - /// stores file info for each file we provide. - std::map _outgoing_tunnel_client_services ; - - /// local tunnels, stored by ids (Either transiting or ending). - std::map _local_tunnels ; - - /// Peers corresponding to each tunnel. - std::map _virtual_peers ; - - /// Hashes marked to be deleted. - std::set _hashes_to_remove ; - - /// List of client services that have regitered. - std::map _registered_services ; - - rstime_t _last_clean_time ; - rstime_t _last_tunnel_management_time ; - rstime_t _last_tunnel_campaign_time ; - rstime_t _last_tunnel_speed_estimate_time ; - - std::list _online_peers; - - /// used to force digging new tunnels - //bool _force_digg_new_tunnels ; - - /// used as a bias to introduce randomness in a consistent way, for - /// altering tunnel request depths, and tunnel re-routing actions. - /// - uint32_t _random_bias ; - - // Used to collect statistics on turtle traffic. - // - TurtleTrafficStatisticsInfoOp _traffic_info ; // used for recording speed - TurtleTrafficStatisticsInfoOp _traffic_info_buffer ; // used as a buffer to collect bytes - - float _max_tr_up_rate ; - bool _turtle_routing_enabled ; - bool _turtle_routing_session_enabled ; - - // p3ServiceControl service type - - uint32_t _service_type ; - - RS_SET_CONTEXT_DEBUG_LEVEL(1) - -#ifdef P3TURTLE_DEBUG - // debug function - void dumpState() ; -#endif -#ifdef TUNNEL_STATISTICS - void TS_dumpState(); -#endif -}; diff --git a/libretroshare/src/turtle/rsturtleitem.cc b/libretroshare/src/turtle/rsturtleitem.cc deleted file mode 100644 index f0128d04a..000000000 --- a/libretroshare/src/turtle/rsturtleitem.cc +++ /dev/null @@ -1,256 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: rsturtleitem.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef WINDOWS_SYS -#include -#endif -#include -#include "turtletypes.h" -#include "rsturtleitem.h" -#include "turtleclientservice.h" - -#include "serialiser/rstypeserializer.h" - -//#define P3TURTLE_DEBUG -// -----------------------------------------------------------------------------------// -// -------------------------------- Serialization. --------------------------------- // -// -----------------------------------------------------------------------------------// -// - -RsItem *RsTurtleSerialiser::create_item(uint16_t service,uint8_t item_subtype) const -{ - if (RS_SERVICE_TYPE_TURTLE != service) - { -#ifdef P3TURTLE_DEBUG - std::cerr << " Wrong type !!" << std::endl ; -#endif - return NULL; /* wrong type */ - } - - switch(getRsItemSubType(item_subtype)) - { - case RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST : return new RsTurtleStringSearchRequestItem(); - case RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST : return new RsTurtleRegExpSearchRequestItem(); - case RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT : return new RsTurtleFTSearchResultItem(); - case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem(); - case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem(); - case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem(); - case RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA : return new RsTurtleGenericFastDataItem(); - case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST : return new RsTurtleGenericSearchRequestItem(); - case RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT : return new RsTurtleGenericSearchResultItem(); - - default: - break ; - } - // now try all client services - // - RsItem *item = NULL ; - - for(uint32_t i=0;i<_client_services.size();++i) - if((_client_services[i]->serializer() != NULL) && (item = _client_services[i]->serializer()->create_item(service,item_subtype)) != NULL) - return item ; - - std::cerr << "Unknown packet type in RsTurtle (not even handled by client services)!" << std::endl ; - return NULL ; -} - -std::string RsTurtleGenericSearchRequestItem::GetKeywords() -{ - return std::string("Generic search : " + RsUtil::BinToHex(search_data,search_data_len,10)); -} - -void RsTurtleStringSearchRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,TLV_TYPE_STR_VALUE,match_string,"match_string") ; - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; - RsTypeSerializer::serial_process(j,ctx,depth ,"depth") ; -} -void RsTurtleRegExpSearchRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; - RsTypeSerializer::serial_process(j,ctx,depth,"depth") ; - RsTypeSerializer::serial_process(j,ctx,expr,"expr") ; -} -void RsTurtleGenericSearchRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; - RsTypeSerializer::serial_process(j,ctx,depth,"depth") ; - RsTypeSerializer::serial_process(j,ctx,service_id,"service_id") ; - RsTypeSerializer::serial_process(j,ctx,request_type,"request_type") ; - - RsTypeSerializer::TlvMemBlock_proxy prox(search_data,search_data_len) ; - RsTypeSerializer::serial_process(j,ctx,prox,"search_data") ; -} -RsTurtleSearchRequestItem *RsTurtleGenericSearchRequestItem::clone() const -{ - return new RsTurtleGenericSearchRequestItem(*this) ; -} - -RsTurtleGenericSearchRequestItem::RsTurtleGenericSearchRequestItem(const RsTurtleGenericSearchRequestItem& it) - : RsTurtleSearchRequestItem(it) -{ - search_data_len = it.search_data_len ; - search_data = (unsigned char*)rs_malloc(it.search_data_len) ; - service_id = it.service_id ; - request_type = it.request_type ; - - memcpy(search_data,it.search_data,it.search_data_len) ; -} - -template<> uint32_t RsTypeSerializer::serial_size(const RsRegularExpression::LinearizedExpression& r) -{ - uint32_t s = 0 ; - - s += 4 ; // number of strings - - for(unsigned int i=0;i bool RsTypeSerializer::deserialize(const uint8_t data[],uint32_t size,uint32_t& offset,RsRegularExpression::LinearizedExpression& expr) -{ - uint32_t saved_offset = offset ; - - uint32_t n =0 ; - bool ok = true ; - - ok &= getRawUInt32(data,size,&offset,&n) ; - - if(ok) expr._tokens.resize(n) ; - - for(uint32_t i=0;i bool RsTypeSerializer::serialize(uint8_t data[],uint32_t size,uint32_t& offset,const RsRegularExpression::LinearizedExpression& expr) -{ - uint32_t saved_offset = offset ; - - bool ok = true ; - - ok &= setRawUInt32(data,size,&offset,expr._tokens.size()) ; - - for(unsigned int i=0;i void RsTypeSerializer::print_data(const std::string& n, const RsRegularExpression::LinearizedExpression& expr) -{ - std::cerr << " [RegExpr ] " << n << ", tokens=" << expr._tokens.size() << " ints=" << expr._ints.size() << " strings=" << expr._strings.size() << std::endl; -} - -RS_TYPE_SERIALIZER_TO_JSON_NOT_IMPLEMENTED_DEF(RsRegularExpression::LinearizedExpression) -RS_TYPE_SERIALIZER_FROM_JSON_NOT_IMPLEMENTED_DEF(RsRegularExpression::LinearizedExpression) - -void RsTurtleFTSearchResultItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; - - // This depth was previously a member of SearchResult parent class that was set to be always 0. It's removed, but we have to stay backward compatible. - uint16_t depth_retrocompat_unused_placeholder = 0 ; - RsTypeSerializer::serial_process(j,ctx,depth_retrocompat_unused_placeholder,"depth") ; - - RsTypeSerializer::serial_process (j,ctx,result ,"result") ; -} -void RsTurtleGenericSearchResultItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; - - // This depth was previously a member of SearchResult parent class that was set to be always 0. It's removed, but we have to stay backward compatible. - uint16_t depth_retrocompat_unused_placeholder = 0 ; - RsTypeSerializer::serial_process(j,ctx,depth_retrocompat_unused_placeholder,"depth") ; - - RsTypeSerializer::TlvMemBlock_proxy prox(result_data,result_data_len) ; - RsTypeSerializer::serial_process(j,ctx,prox,"search_data") ; -} -RsTurtleSearchResultItem *RsTurtleGenericSearchResultItem::duplicate() const -{ - RsTurtleGenericSearchResultItem *sr = new RsTurtleGenericSearchResultItem ; - - sr->result_data = (unsigned char*)rs_malloc(result_data_len) ; - memcpy(sr->result_data,result_data,result_data_len) ; - sr->result_data_len = result_data_len ; - sr->request_id = request_id ; - return sr ; -} - -void RsTurtleOpenTunnelItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process (j,ctx,file_hash ,"file_hash") ; - RsTypeSerializer::serial_process(j,ctx,request_id ,"request_id") ; - RsTypeSerializer::serial_process(j,ctx,partial_tunnel_id,"partial_tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,depth ,"depth") ; -} - -void RsTurtleTunnelOkItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id ,"tunnel_id") ; - RsTypeSerializer::serial_process(j,ctx,request_id,"request_id") ; -} - -void RsTurtleGenericDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id ,"tunnel_id") ; - RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ; - RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ; -} -void RsTurtleGenericFastDataItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) -{ - RsTypeSerializer::serial_process(j,ctx,tunnel_id ,"tunnel_id") ; - RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ; - RsTypeSerializer::serial_process(j,ctx,prox,"data bytes") ; -} diff --git a/libretroshare/src/turtle/rsturtleitem.h b/libretroshare/src/turtle/rsturtleitem.h deleted file mode 100644 index db029cc64..000000000 --- a/libretroshare/src/turtle/rsturtleitem.h +++ /dev/null @@ -1,387 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: rsturtleitem.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2009-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "rsitems/rsserviceids.h" -#include "rsitems/rsitem.h" -#include "rsitems/itempriorities.h" - -#include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rsbaseserial.h" - -#include "retroshare/rsturtle.h" -#include "retroshare/rsexpr.h" -#include "retroshare/rstypes.h" -#include "turtle/turtletypes.h" - -#include "serialiser/rsserializer.h" - -const uint8_t RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST = 0x01 ; -const uint8_t RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT = 0x02 ; -const uint8_t RS_TURTLE_SUBTYPE_OPEN_TUNNEL = 0x03 ; -const uint8_t RS_TURTLE_SUBTYPE_TUNNEL_OK = 0x04 ; -const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ; -const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ; -const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ; -const uint8_t RS_TURTLE_SUBTYPE_GENERIC_DATA = 0x0a ; -const uint8_t RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST = 0x0b ; -const uint8_t RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT = 0x0c ; -const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ; -const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ; -// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ; // unused -// const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST = 0x13 ; -const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC = 0x14 ; -const uint8_t RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST = 0x15 ; -const uint8_t RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA = 0x16 ; - - -class TurtleSearchRequestInfo ; - -/***********************************************************************************/ -/* Basic Turtle Item Class */ -/***********************************************************************************/ - -class RsTurtleItem: public RsItem -{ - public: - RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {} -}; - -/***********************************************************************************/ -/* Turtle Search Item classes */ -/* Specific packets */ -/***********************************************************************************/ - -// Class hierarchy is -// -// RsTurtleItem -// | -// +---- RsTurtleSearchRequestItem -// | | -// | +---- RsTurtleFileSearchRequestItem -// | | | -// | | +---- RsTurtleStringSearchRequestItem -// | | | -// | | +---- RsTurtleReqExpSearchRequestItem -// | | -// | +---- RsTurtleGenericSearchRequestItem -// | -// +---- RsTurtleSearchResultItem -// | -// +---- RsTurtleFTSearchResultItem -// | -// +---- RsTurtleGenericSearchResultItem -// - -class RsTurtleSearchResultItem ; - -class RsTurtleSearchRequestItem: public RsTurtleItem -{ - public: - RsTurtleSearchRequestItem(uint32_t subtype) : RsTurtleItem(subtype), request_id(0), depth(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_REQUEST) ;} - virtual ~RsTurtleSearchRequestItem() {} - - virtual RsTurtleSearchRequestItem *clone() const = 0 ; // used for cloning in routing methods - - virtual std::string GetKeywords() = 0; - virtual uint16_t serviceId() const= 0 ; - - uint32_t request_id ; // randomly generated request id. - uint16_t depth ; // Used for limiting search depth. -}; - -class RsTurtleFileSearchRequestItem: public RsTurtleSearchRequestItem -{ - public: - RsTurtleFileSearchRequestItem(uint32_t subtype) : RsTurtleSearchRequestItem(subtype) {} - virtual ~RsTurtleFileSearchRequestItem() {} - - virtual uint16_t serviceId() const { return RS_SERVICE_TYPE_FILE_TRANSFER ; } - virtual void search(std::list &) const =0; -}; - -class RsTurtleStringSearchRequestItem: public RsTurtleFileSearchRequestItem -{ - public: - RsTurtleStringSearchRequestItem() : RsTurtleFileSearchRequestItem(RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST) {} - virtual ~RsTurtleStringSearchRequestItem() {} - - virtual void search(std::list &) const ; - - std::string match_string ; // string to match - std::string GetKeywords() { return match_string; } - - virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; } - - void clear() { match_string.clear() ; } - - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleRegExpSearchRequestItem: public RsTurtleFileSearchRequestItem -{ - public: - RsTurtleRegExpSearchRequestItem() : RsTurtleFileSearchRequestItem(RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST) {} - virtual ~RsTurtleRegExpSearchRequestItem() {} - - RsRegularExpression::LinearizedExpression expr ; // Reg Exp in linearised mode - - std::string GetKeywords() - { - RsRegularExpression::Expression *ex = RsRegularExpression::LinearizedExpression::toExpr(expr); - std::string exs = ex->toStdString(); - delete ex; - return exs; - } - - virtual void search(std::list &) const ; - - virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleRegExpSearchRequestItem(*this) ; } - void clear() { expr = RsRegularExpression::LinearizedExpression(); } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleGenericSearchRequestItem: public RsTurtleSearchRequestItem -{ - public: - RsTurtleGenericSearchRequestItem() - : RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_REQUEST), - service_id(0), - search_data_len(0), - request_type(0), - search_data(nullptr) - {} - virtual ~RsTurtleGenericSearchRequestItem() { clear(); } - - uint16_t service_id ; // service to search - uint32_t search_data_len ; - uint8_t request_type ; // type of request. This is used to limit the number of responses. - unsigned char *search_data ; - - std::string GetKeywords() ; - virtual uint16_t serviceId() const { return service_id ; } - - virtual RsTurtleSearchRequestItem *clone() const ; - virtual uint32_t requestType() const { return request_type; } - - void clear() { free(search_data); search_data=NULL; search_data_len=0; } - - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); - - private: - RsTurtleGenericSearchRequestItem(const RsTurtleGenericSearchRequestItem&); // make the object non copi-able. - RsTurtleGenericSearchRequestItem& operator=(const RsTurtleGenericSearchRequestItem&) { return *this;} -}; -class RsTurtleSearchResultItem: public RsTurtleItem -{ - public: - RsTurtleSearchResultItem(uint8_t subtype) : RsTurtleItem(subtype), request_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_SEARCH_RESULT) ;} - - TurtleSearchRequestId request_id ; // Randomly generated request id. - - virtual uint32_t count() const =0; - virtual void pop() =0; - - virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)=0; - virtual RsTurtleSearchResultItem *duplicate() const =0; -}; - -class RsTurtleFTSearchResultItem: public RsTurtleSearchResultItem -{ - public: - RsTurtleFTSearchResultItem() : RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_FT_SEARCH_RESULT){} - - std::list result ; - - void clear() { result.clear() ; } - uint32_t count() const { return result.size() ; } - virtual void pop() { result.pop_back() ;} - virtual RsTurtleSearchResultItem *duplicate() const { return new RsTurtleFTSearchResultItem(*this) ; } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleGenericSearchResultItem: public RsTurtleSearchResultItem -{ - public: - RsTurtleGenericSearchResultItem() - : RsTurtleSearchResultItem(RS_TURTLE_SUBTYPE_GENERIC_SEARCH_RESULT), - result_data(nullptr), - result_data_len(0) - {} - virtual ~RsTurtleGenericSearchResultItem() {} - - uint32_t count() const { return result_data_len/50 ; } // This is a blind size estimate. We should probably use the actual size to limit search results. - virtual void pop() {} - - unsigned char *result_data ; - uint32_t result_data_len ; - - virtual RsTurtleSearchResultItem *duplicate() const ; - void clear() { free(result_data); result_data=NULL; result_data_len=0; } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -/***********************************************************************************/ -/* Turtle Tunnel Item classes */ -/***********************************************************************************/ - -class RsTurtleOpenTunnelItem: public RsTurtleItem -{ - public: - RsTurtleOpenTunnelItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_OPEN_TUNNEL), request_id(0), partial_tunnel_id(0), depth(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_OPEN_TUNNEL) ;} - - TurtleFileHash file_hash ; // hash to match - uint32_t request_id ; // randomly generated request id. - uint32_t partial_tunnel_id ; // uncomplete tunnel id. Will be completed at destination. - uint16_t depth ; // Used for limiting search depth. - - void clear() { file_hash.clear() ;} - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -class RsTurtleTunnelOkItem: public RsTurtleItem -{ - public: - RsTurtleTunnelOkItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_TUNNEL_OK), tunnel_id(0), request_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_TUNNEL_OK) ;} - - uint32_t tunnel_id ; // id of the tunnel. Should be identical for a tunnel between two same peers for the same hash. - uint32_t request_id ; // randomly generated request id corresponding to the intial request. - - void clear() {} - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -/***********************************************************************************/ -/* Generic turtle packets for tunnels */ -/***********************************************************************************/ - -class RsTurtleGenericTunnelItem: public RsTurtleItem -{ - public: - RsTurtleGenericTunnelItem(uint8_t sub_packet_id) : RsTurtleItem(sub_packet_id), direction(0), tunnel_id(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM);} - virtual ~RsTurtleGenericTunnelItem() {} - - typedef uint32_t Direction ; - static const Direction DIRECTION_CLIENT = 0x001 ; - static const Direction DIRECTION_SERVER = 0x002 ; - - /// Does this packet stamps tunnels when it passes through ? - /// This is used for keeping trace weither tunnels are active or not. - - virtual bool shouldStampTunnel() const = 0 ; - - /// All tunnels derived from RsTurtleGenericTunnelItem should have a tunnel id to - /// indicate which tunnel they are travelling through. - - virtual TurtleTunnelId tunnelId() const { return tunnel_id ; } - - /// Indicate weither the packet is a client packet (goign back to the - /// client) or a server packet (going to the server. Typically file - /// requests are server packets, whereas file data are client packets. - - virtual Direction travelingDirection() const { return direction ; } - virtual void setTravelingDirection(Direction d) { direction = d; } - - Direction direction ; // This does not need to be serialised. It's only used by the client services, optionnally, - // and is set by the turtle router according to which direction the item travels. - - uint32_t tunnel_id ; // Id of the tunnel to travel through -}; - -/***********************************************************************************/ -/* Specific Turtle Transfer items */ -/***********************************************************************************/ - -// This item can be used by any service to pass-on arbitrary data into a tunnel. -// -class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleGenericDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_DATA);} - virtual ~RsTurtleGenericDataItem() { if(data_bytes != NULL) free(data_bytes) ; } - - virtual bool shouldStampTunnel() const { return true ; } - - uint32_t data_size ; - void *data_bytes ; - - void clear() - { - free(data_bytes) ; - data_bytes = NULL ; - data_size = 0; - } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; - -// Same, but with a fact priority. Can rather be used for e.g. distant chat. -// -class RsTurtleGenericFastDataItem: public RsTurtleGenericTunnelItem -{ - public: - RsTurtleGenericFastDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_FAST_DATA), data_size(0), data_bytes(0) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_FAST_DATA);} - virtual ~RsTurtleGenericFastDataItem() { if(data_bytes != NULL) free(data_bytes) ; } - - virtual bool shouldStampTunnel() const { return true ; } - - uint32_t data_size ; - void *data_bytes ; - - void clear() - { - free(data_bytes) ; - data_bytes = NULL ; - data_size = 0; - } - protected: - void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx); -}; -/***********************************************************************************/ -/* Turtle Serialiser class */ -/***********************************************************************************/ - -class RsTurtleSerialiser: public RsServiceSerializer -{ - public: - RsTurtleSerialiser() : RsServiceSerializer(RS_SERVICE_TYPE_TURTLE) {} - - virtual RsItem *create_item(uint16_t service,uint8_t item_subtype) const; - - // This is used by the turtle router to add services to its serialiser. - // Client services are only used for deserialising, since the serialisation is - // performed using the overloaded virtual functions above. - // - void registerClientService(RsTurtleClientService *service) { _client_services.push_back(service) ; } - - private: - std::vector _client_services ; -}; - diff --git a/libretroshare/src/turtle/turtleclientservice.h b/libretroshare/src/turtle/turtleclientservice.h deleted file mode 100644 index 9cbe5763f..000000000 --- a/libretroshare/src/turtle/turtleclientservice.h +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: rsturtleclientservice.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// This class is the parent class for any service that will use the turtle router to distribute its packets. -// Typical representative clients include: -// -// p3ChatService: opens tunnels to distant peers for chatting -// ftServer: searches and open tunnels to distant sources for file transfer -// -#pragma once - -#include -#include -#include -#include - -struct RsItem; -class p3turtle ; - -class RsTurtleClientService -{ - public: - /*! - * \brief serviceId - * Returns the ID of the client service. This is used to pass the ID to search requests, from the client services - * \return - * The service ID. - */ - - virtual uint16_t serviceId() const - { - std::cerr << "!!!!!! Received request for service ID in turtle router client, but the client service is not handling it !!!!!!!" << std::endl ; - return 0 ; - } - - /*! - * \brief handleTunnelRequest - Handling of tunnel request for the given hash. To be derived by the service in order to tell the turtle router - whether the service handles this hash or not. Most of the time, it's a search in a predefined list. - - * \return true if the service - */ - virtual bool handleTunnelRequest(const RsFileHash& /*hash*/,const RsPeerId& /*peer_id*/) { return false ; } - - /*! - * \brief receiveTurtleData - * This method is called by the turtle router to send data that comes out of a turtle tunnel, and should - * be overloaded by the client service. - * The turtle router stays responsible for the memory management of data. Most of the time the - * data chunk is a serialized item to be de-serialized by the client service. - * - * Parameters: - * virtual_peer_id : name of the tunnel that sent the data - * data : memory chunk for the data - * size : size of data - * item->direction : direction of travel: - * RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a client - * RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a server - * - * Most of the time this parameter is not used by services, except when some info (such as chunk maps, chat items, etc) go - * both ways, and their nature cannot suffice to determine where they should be handled. - * - * By default (if not overloaded), the method will just free the data, as any subclass should do as well. - * Note: p3turtle stays owner of the item, so the client should not delete it! - */ - virtual void receiveTurtleData(const RsTurtleGenericTunnelItem * /* item */,const RsFileHash& /*hash*/,const RsPeerId& /*virtual_peer_id*/,RsTurtleGenericTunnelItem::Direction /*direction*/) - { - std::cerr << "!!!!!! Received Data from turtle router, but the client service is not handling it !!!!!!!!!!" << std::endl ; - } - - /*! - * \brief receiveSearchRequest - * This method is called by the turtle router to notify the client of a search request in the form generic data. The returned - * result contains the serialised generic result returned by the client. - * - * The turtle router keeps the memory ownership over search_request_data - * - * \param search_request_data generic serialized search data - * \param search_request_data_len length of the serialized search data - * \param search_result_data generic serialized search result data - * \param search_result_data_len length of the serialized search result data - * \param max_allowed_hits max number of hits allowed to be sent back and forwarded - * - * \return true if the search is successful. - */ - virtual bool receiveSearchRequest(unsigned char */*search_request_data*/, - uint32_t /*search_request_data_len*/, - unsigned char *& /*search_result_data*/, - uint32_t& /*search_result_data_len*/, - uint32_t& /* max_allows_hits */) - { - std::cerr << "!!!!!! Received search result from turtle router, but the client service who requested it is not handling it !!!!!!!!!!" << std::endl ; - return false; - } - - /*! - * \brief receiveSearchResult - * This method is called by the turtle router to notify the client of a search result. The result is serialized for the current class to read. - * - * \param search_result_data result data. Memory ownership is owned by the turtle router. So do not delete! - * \param search_result_data length of result data - */ - virtual void receiveSearchResult(TurtleSearchRequestId /* request_id */,unsigned char * /*search_result_data*/,uint32_t /*search_result_data_len*/) - { - std::cerr << "!!!!!! Received search result from turtle router, but the client service who requested it is not handling it !!!!!!!!!!" << std::endl ; - } - - /*! - * \brief serializer - * Method for creating specific items of the client service. The - * method has a default behavior of not doing anything, since most client - * services might only use the generic item already provided by the turtle - * router: RsTurtleGenericDataItem - * - * \return the client's serializer is returned - */ - virtual RsServiceSerializer *serializer() { return NULL ; } - - /*! - * \brief addVirtualPeer - * These methods are called by the turtle router to notify the client in order to add/remove virtual peers when tunnels are created/deleted - * These methods must be overloaded, because a service which does not care about tunel being openned or closed is not supposed to need tunnels. - * - * \param hash hash that the tunnel responds to - * \param virtual_peer_id virtual peer id provided by turtle to allow the client to send data into this tunnel. This peer is related to the tunnel itself - * rather than to its destination. As such, multiple peer ids may actually send data to the same computer because multiple tunnels - * arrive at the same location. - * \param dir dir indicates which side the cient will be talking to: CLIENT means that the client is the server. SERVER means that the client acts - * as a client (and therefore actually requested the tunnel). - */ - virtual void addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) = 0 ; - virtual void removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) = 0 ; - - /*! - * \brief connectToTurtleRouter - * This function must be overloaded by the client. It should do two things: - * 1 - keep a pointer to the turtle router, so as to be able to send data (e.g. store pt into a local variable) - * 2 - call pt->registerTunnelService(this), so that the TR knows that service and can send back information to it. - * - * \param pt A pointer to the turtle router. - */ - virtual void connectToTurtleRouter(p3turtle *pt) = 0 ; -}; - - diff --git a/libretroshare/src/turtle/turtlestatistics.h b/libretroshare/src/turtle/turtlestatistics.h deleted file mode 100644 index 5aaeda676..000000000 --- a/libretroshare/src/turtle/turtlestatistics.h +++ /dev/null @@ -1,51 +0,0 @@ -#include - -class TurtleTrafficStatisticsInfoOp: public TurtleTrafficStatisticsInfo -{ - public: - TurtleTrafficStatisticsInfoOp() - { - reset() ; - } - - void reset() - { - unknown_updn_Bps = 0.0f ; - data_up_Bps = 0.0f ; - data_dn_Bps = 0.0f ; - tr_up_Bps = 0.0f ; - tr_dn_Bps = 0.0f ; - total_up_Bps = 0.0f ; - total_dn_Bps = 0.0f ; - } - - TurtleTrafficStatisticsInfoOp operator*(float f) const - { - TurtleTrafficStatisticsInfoOp i(*this) ; - - i.unknown_updn_Bps *= f ; - i.data_up_Bps *= f ; - i.data_dn_Bps *= f ; - i.tr_up_Bps *= f ; - i.tr_dn_Bps *= f ; - i.total_up_Bps *= f ; - i.total_dn_Bps *= f ; - - return i ; - } - TurtleTrafficStatisticsInfoOp operator+(const TurtleTrafficStatisticsInfoOp& j) const - { - TurtleTrafficStatisticsInfoOp i(*this) ; - - i.unknown_updn_Bps += j.unknown_updn_Bps ; - i.data_up_Bps += j.data_up_Bps ; - i.data_dn_Bps += j.data_dn_Bps ; - i.tr_up_Bps += j.tr_up_Bps ; - i.tr_dn_Bps += j.tr_dn_Bps ; - i.total_up_Bps += j.total_up_Bps ; - i.total_dn_Bps += j.total_dn_Bps ; - - return i ; - } -}; - diff --git a/libretroshare/src/turtle/turtletypes.h b/libretroshare/src/turtle/turtletypes.h deleted file mode 100644 index 56fd78f8b..000000000 --- a/libretroshare/src/turtle/turtletypes.h +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * libretroshare/src/turtle: rsturtletypes.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2018 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "retroshare/rsturtle.h" - -typedef RsPeerId TurtlePeerId ; -typedef RsPeerId TurtleVirtualPeerId ; -typedef RsFileHash TurtleFileHash ; -typedef std::string TurtleFileName ; - -typedef TurtleRequestId TurtleSearchRequestId ; - -typedef uint32_t TurtleTunnelRequestId ; -typedef uint32_t TurtleTunnelId ; - - diff --git a/libretroshare/src/unfinished/db_acadeeb.h b/libretroshare/src/unfinished/db_acadeeb.h deleted file mode 100644 index 806422a30..000000000 --- a/libretroshare/src/unfinished/db_acadeeb.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * libretroshare/src/gxp: gxp_apps.h - * - * General Exchange Protocol interface for RetroShare. - * - * Copyright 2011-2011 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef RS_ACADEE_H -#define RS_ACADEE_H - -/******* - * Stores a Bibliography of Academic Articles, with links to allow you to access the actual article. - * The data fields, should contain enough information to - * - extract full biblio (bibtex or ris formats). - * - read abstract. - * - review / rating of the article - * - references to similar papers, and bibliography. - * - keywords, and the like. - * - * It will be possible to have multiple identical / similar / different descriptions of the same article. - * The class will have to handle this: sorting and matching as best it can. - * - ****/ - -class gxp::Paper -{ - /* fields from ris */ - std::string reftype; - std::string journal; - std::string title; - std::string issuetitle; - uint32_t volume; - uint32_t issue; - std::string publisher; - std::string serialnumber; - std::string url; - std::list authors; - rstime_t date; - uint32_t startpage; - uint32_t endpage; - std::string language; - - std::string abstract; - - // KeyWords <- go into hashtags (parent class) - //References & Similar Papers <- go into links (parent class) -}; - - -class rsAcadee: public rsGmxp -{ - public: - - /* we want to access the */ - - - - -}; - - -#endif /* RS_GXP_H */ - - diff --git a/libretroshare/src/unfinished/db_wire.h b/libretroshare/src/unfinished/db_wire.h deleted file mode 100644 index cac3f2747..000000000 --- a/libretroshare/src/unfinished/db_wire.h +++ /dev/null @@ -1,50 +0,0 @@ - -#include "gxp_service.h" - -class db_wire -{ - /* external interface for accessing the info */ - - /** Note this could get very busy with a large number of tweeters. - * need some other method of getting data - */ - - getTweeters(std::list &tweeterIds); - { - getGroups(); - } - - getTweetRange(GxpTimeStamp, GxpTimeStamp, std::list &tweetIds); - { - getTimeRange(); - } - - getTweetRangeSource(GxpTimeStamp, GxpTimeStamp, std::string tweeterId, std::list &tweetIds); - { - getGroupTimeRange(); - } - - getTweet(std::string id, TweetData &tweet); - { - StackLock(); - - RsGxpItem *getMsg_locked(id); - - // translate message into TweetData. - - } - - // Default - getProfile(std::string id, TweetData &tweet); - - /* returns a search code, which is used to id later delivery */ - int searchTweets(GxpSearchCondition cond, std::list); - - /* returns a search code, which is used to id later delivery */ - int fetchPendingSearchResults(int searchId, std::list); - - int cancelSearch(int searchId, std::list); - -}; - - diff --git a/libretroshare/src/unfinished/mail/directmailservice.cc b/libretroshare/src/unfinished/mail/directmailservice.cc deleted file mode 100644 index aa28a7cca..000000000 --- a/libretroshare/src/unfinished/mail/directmailservice.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* - * libretroshare/src/services directmailservice.cc - * - * Services for RetroShare. - * - * Copyright 2014 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include "services/mail/directmailservice.h" - -#include "util/rsdebug.h" - -//#define MSG_DEBUG 1 - -const int directmailzone = 54319; - -using namespace Rs::Mail; - - -DirectMailService::DirectMailService(p3ServiceControl *sc) - :MailTransport(DEFAULT_MAX_MESSAGE_SIZE, RS_SERVICE_TYPE_DIRECT_MAIL), - p3Service(), mServiceCtrl(sc), mMsgMtx("DirectMailService") -{ - mSerialiser = new RsMailTransportSerialiser(RS_SERVICE_TYPE_DIRECT_MAIL); - addSerialType(mSerialiser); -} - -const std::string MSGDIRECT_APP_NAME = "msgdirect"; -const uint16_t MSGDIRECT_APP_MAJOR_VERSION = 1; -const uint16_t MSGDIRECT_APP_MINOR_VERSION = 0; -const uint16_t MSGDIRECT_MIN_MAJOR_VERSION = 1; -const uint16_t MSGDIRECT_MIN_MINOR_VERSION = 0; - -RsServiceInfo DirectMailService::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_DIRECT_MAIL, - MSGDIRECT_APP_NAME, - MSGDIRECT_APP_MAJOR_VERSION, - MSGDIRECT_APP_MINOR_VERSION, - MSGDIRECT_MIN_MAJOR_VERSION, - MSGDIRECT_MIN_MINOR_VERSION); -} - - -bool DirectMailService::CanSend(const RsTlvMailAddress &addr) -{ - /* we can send if MessageAddress is a peerID, - * and the peer ID is a friend. - */ - if (addr.mAddressType == ADDRESS_TYPE_PEER_ID) - { - return true; - } - return false; -} - -bool DirectMailService::sendMail(RsMailChunkItem *item) -{ - // set the right serviceId. - item->setPacketService(RS_SERVICE_TYPE_DIRECT_MAIL); - if (!attemptToSend(item)) - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - mOutgoingMsgs.push_back(item); - } - return true; -} - -RsMailChunkItem *DirectMailService::recvMail() -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - if (!mIncomingMsgs.empty()) - { - RsMailChunkItem *item = mIncomingMsgs.front(); - mIncomingMsgs.pop_front(); - return item; - } - return NULL; -} - -RsPeerId convertAddressToPeerId(RsMailAckItem *item) -{ - RsPeerId id; - return id; -} - -bool DirectMailService::sendMailAck(RsMailAckItem *item) -{ - // set the right serviceId. - item->setPacketService(RS_SERVICE_TYPE_DIRECT_MAIL); - item->PeerId(convertAddressToPeerId(item)); - if (!attemptToSend(item)) - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - mOutgoingMsgs.push_back(item); - } - return true; -} - -RsMailAckItem *DirectMailService::recvMailAck() -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - if (!mIncomingAckMsgs.empty()) - { - RsMailAckItem *item = mIncomingAckMsgs.front(); - mIncomingMsgs.pop_front(); - - return item; - } - return NULL; -} - - -int DirectMailService::tick() -{ - rslog(RSL_DEBUG_BASIC, directmailzone, - "DirectMailService::tick()"); - - incomingMsgs(); - return 0; -} - - -int DirectMailService::status() -{ - rslog(RSL_DEBUG_BASIC, directmailzone, - "DirectMailService::status()"); - - return 1; -} - -void DirectMailService::statusChange(const std::list &plist) -{ - /* should do it properly! */ - /* only do this when a new peer is connected */ - bool newPeers = false; - std::list::const_iterator it; - for(it = plist.begin(); it != plist.end(); it++) - { - if (it->actions & RS_SERVICE_PEER_CONNECTED) - { - newPeers = true; - } - } - - if (newPeers) - { - checkOutgoingMessages(); - } -} - - -int DirectMailService::incomingMsgs() -{ - RsItem *item; - int i = 0; - - while((item = recvItem()) != NULL) - { - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - RsMailChunkItem *mi = dynamic_cast(item); - RsMailAckItem *mai = dynamic_cast(item); - if (mi) - { - mIncomingMsgs.push_back(mi); - } - else if (mai) - { - mIncomingAckMsgs.push_back(mai); - } - else - { - std::cerr << "DirectMailService::incomingMsgs() Unknown incoming Msg"; - std::cerr << std::endl; - delete item; - } - ++i; - } - return i; -} - -// This is a Local copy of an Outgoing message - either SentBox or Draft. -bool DirectMailService::attemptToSend(RsItem *mi) -{ - RsPeerId pid = mi->PeerId(); - if (mServiceCtrl->isPeerConnected(getServiceInfo().mServiceType, pid)) - { - sendItem(mi); - return true; - } - - return false; -} - -void DirectMailService::checkOutgoingMessages() -{ - /* iterate through the outgoing queue and attempt to send. - */ - - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - std::list::iterator mit; - for(mit = mOutgoingMsgs.begin(); mit != mOutgoingMsgs.end(); mit++) - { - if (attemptToSend(*mit)) - { - /* actually sent the message */ - mit = mOutgoingMsgs.erase(mit); - } - else - { - mit++; - } - } -} - -bool DirectMailService::haveIncomingMail() -{ - RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ - - if (!mIncomingMsgs.empty()) - { - return true; - } - - if (!mIncomingAckMsgs.empty()) - { - return true; - } - return false; -} - - diff --git a/libretroshare/src/unfinished/mail/directmailservice.h b/libretroshare/src/unfinished/mail/directmailservice.h deleted file mode 100644 index 7d6ce0d19..000000000 --- a/libretroshare/src/unfinished/mail/directmailservice.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * libretroshare/src/services/mail directmailservice.h - * - * Services for RetroShare. - * - * Copyright 2014 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#ifndef DIRECT_MAIL_SERVICE_HEADER -#define DIRECT_MAIL_SERVICE_HEADER - -#include "services/mail/mailtransport.h" -#include "services/p3service.h" - -#include "pqi/pqiservicemonitor.h" - -#include "util/rsthreads.h" - - -namespace Rs -{ -namespace Mail -{ - -class DirectMailService: public MailTransport, public p3Service, public pqiServiceMonitor -{ - -public: - DirectMailService(p3ServiceControl *sc); - virtual RsServiceInfo getServiceInfo(); - - /******* MailTransport Interface ********************************************************/ - - virtual bool CanSend(const RsTlvMailAddress &addr); - virtual bool haveIncomingMail(); - - virtual bool sendMail(RsMailChunkItem *msg); - virtual RsMailChunkItem *recvMail(); - virtual bool sendMailAck(RsMailAckItem *ack); - virtual RsMailAckItem *recvMailAck(); - - /******* MsgTransport Interface ********************************************************/ - - int tick(); - int status(); - - /*** Overloaded from pqiMonitor ***/ - virtual void statusChange(const std::list &plist); - /*** Overloaded from pqiMonitor ***/ - -private: - - int incomingMsgs(); - void checkOutgoingMessages(); - bool attemptToSend(RsItem *item); - - p3ServiceControl *mServiceCtrl; - - /* Mutex Required for stuff below */ - RsMutex mMsgMtx; - RsMailTransportSerialiser *mSerialiser ; - - /* outgoing messages */ - std::list mOutgoingMsgs; - - /* incoming msgs */ - std::list mIncomingMsgs; - std::list mIncomingAckMsgs; -}; - -} // namspace Msg -} // namspace Rs - -#endif // DIRECT_MESSAGE_SERVICE_HEADER diff --git a/libretroshare/src/unfinished/mail/mailtransport.cc b/libretroshare/src/unfinished/mail/mailtransport.cc deleted file mode 100644 index f342c9fd3..000000000 --- a/libretroshare/src/unfinished/mail/mailtransport.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* - * libretroshare/src/services/mail mailtransport.cc - * - * Services for RetroShare. - * - * Copyright 2014 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "services/mail/mailtransport.h" - -using namespace Rs::Mail; - -MailTransport::MailTransport(uint32_t max_size, uint16_t transport_type) -:mEnabled(true), mMaxSize(max_size), mTransportType(transport_type) -{ - return; -} - -bool MailTransport::isEnabled() -{ - return mEnabled; -} - -void MailTransport::setEnabled(bool enabled) -{ - mEnabled = enabled; -} - -uint32_t MailTransport::getMaxSize() -{ - return mMaxSize; -} - -uint16_t MailTransport::getTransportType() -{ - return mTransportType; -} - - diff --git a/libretroshare/src/unfinished/mail/mailtransport.h b/libretroshare/src/unfinished/mail/mailtransport.h deleted file mode 100644 index 0c6abac08..000000000 --- a/libretroshare/src/unfinished/mail/mailtransport.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#ifndef RS_MAIL_TRANSPORT_HEADER -#define RS_MAIL_TRANSPORT_HEADER -/* - * libretroshare/src/services/mail mailtransport.h - * - * Services for RetroShare. - * - * Copyright 2014 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include "serialiser/rsmailtransportitems.h" - - -namespace Rs -{ -namespace Mail -{ - -const uint32_t DEFAULT_MAX_MESSAGE_SIZE = (64 * 1024); - -// To decide how this will work! -const uint32_t ADDRESS_TYPE_PEER_ID = 0x001; -const uint32_t ADDRESS_TYPE_GXS_ID = 0x002; -const uint32_t ADDRESS_TYPE_EMAIL_ID = 0x003; - - -class MailTransport -{ -public: - MailTransport(uint32_t max_size, uint16_t transport_type); - virtual ~MailTransport(); - - virtual bool CanSend(const RsTlvMailAddress &addr) = 0; - virtual bool haveIncomingMail() = 0; - - virtual bool sendMail(RsMailChunkItem *msg) = 0; - virtual RsMailChunkItem *recvMail() = 0; - virtual bool sendMailAck(RsMailAckItem *ack) = 0; - virtual RsMailAckItem *recvMailAck() = 0; - - virtual bool isEnabled(); - virtual void setEnabled(bool enabled); - - uint32_t getMaxSize(); - uint16_t getTransportType(); - -private: - - bool mEnabled; - uint32_t mMaxSize; - uint16_t mTransportType; -}; - - -} // namespace Mail -} // namespace Rs - -#endif diff --git a/libretroshare/src/unfinished/p3portservice.cc b/libretroshare/src/unfinished/p3portservice.cc deleted file mode 100644 index af4b24a73..000000000 --- a/libretroshare/src/unfinished/p3portservice.cc +++ /dev/null @@ -1,123 +0,0 @@ -/* - * "$Id: p3PortService.cc,v 1.24 2007-05-05 16:10:06 rmf24 Exp $" - * - * Other Bits for RetroShare. - * - * Copyright 2004-2006 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#include "services/p3portservice.h" -#include "serialiser/rsserviceids.h" - -p3PortService::p3PortService(p3ConnectMgr *cm) - :p3Service(RS_SERVICE_TYPE_PORT), mConnMgr(cm), mEnabled(false) -{ - /* For Version 1, we'll just use the very simple RsRawItem packets - * which are handled in the RsServiceSerialiser - */ - addSerialType(new RsServiceSerialiser()); -} - -int p3PortService::tick() -{ -#ifdef PORT_DEBUG - std::cerr << "p3PortService::tick()"; - std::cerr << std::endl; -#endif - - /* discard data if not enabled */ - if (!mEnabled) - { - RsItem *i; - while(NULL != (i = recvItem())) - { - delete i; - } - } - - /* Rough list of what might happen (once the sockets are opened!) */ - - - /* check for data on sockets */ - //int sockfd; - RsRawItem *item; - - //while(0 < (len = recv(sockfd, ....))) ... etc. - { - - /* example of how to package data up - * We use RsRawItem as it'll handle a single binary chunk. - * This is enough for version 1.... but versions 2 + 3 will - * need their own serialiser. - * - * */ - - /* input data TODO! */ - void *data=NULL; - uint32_t len=0; - - uint32_t packetId = (((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + - (((uint32_t) RS_SERVICE_TYPE_PORT) << 8); - - /* create Packet for RS Transport */ - RsRawItem *item = new RsRawItem(packetId, len); - void *item_data = item->getRawData(); - memcpy(item_data, data, len); - - /* set the correct peer destination. */ - item->PeerId(mPeerId); - - /* send data */ - sendItem(item); - - /* no delete -> packet cleaned up by RS internals */ - } - - - /* get any incoming data */ - while(NULL != (item = (RsRawItem*) recvItem())) - { - /* unpackage data */ - std::string src = item->PeerId(); -// void *item_data = item->getRawData(); -// uint32_t item_len = item->getRawLength(); - - /* push out to the socket .... */ - // send(sockfd, item_len, item_data....) - - /* cleanup packet */ - delete item; - } - - return 0; -} - -bool p3PortService::enablePortForwarding(uint32_t port, std::string peerId) -{ - mPort = port; - mPeerId = peerId; - mEnabled = true; - - return true; -} - - - diff --git a/libretroshare/src/unfinished/p3portservice.h b/libretroshare/src/unfinished/p3portservice.h deleted file mode 100644 index b1ef089f9..000000000 --- a/libretroshare/src/unfinished/p3portservice.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * libretroshare/src/services: p3portservice.h - * - * Services for RetroShare. - * - * Copyright 2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -#ifndef SERVICE_PORT_FORWARD_HEADER -#define SERVICE_PORT_FORWARD_HEADER - -/* - * The start of a port forwarding service. - * - * This is just a very rough example of what might be required for version 1. - * - * FIRST VERSION: - * - * listen to a single port and send data with a single RS peer. - * - * - * SECOND VERSION: - * - * enable multiple port forwardings. - * - * each forwarding consists of a 'port, peerId & Connection Id'. - * - * THIRD VERSION: - * - * add broadcast/multicast forwardings. - * i.e. data gets sent to multiple peers. - * - * each forwarding with then consist of 'port, connectionId + list of peerIds' - * NOTE: version 3 needs some thought - might require a master host - * which distributes to all others.... or other more complicated systems. - * - */ - -#include -#include - -#include "serialiser/rsbaseitems.h" -#include "services/p3service.h" -#include "pqi/p3connmgr.h" - - -class p3PortService: public p3Service -{ - public: - p3PortService(p3ConnectMgr *cm); - - /* example setup functions */ -bool enablePortForwarding(uint32_t port, std::string peerId); - - /* overloaded */ -virtual int tick(); - - private: - - p3ConnectMgr *mConnMgr; - - bool mEnabled; - bool mPeerOnline; - - uint32_t mPort; - std::string mPeerId; - -}; - -#endif // SERVICE_PORT_FORWARD_HEADER diff --git a/libretroshare/src/unfinished/p3tunnel.cc b/libretroshare/src/unfinished/p3tunnel.cc deleted file mode 100644 index 50a10b56e..000000000 --- a/libretroshare/src/unfinished/p3tunnel.cc +++ /dev/null @@ -1,347 +0,0 @@ -/* - * libretroshare/src/services: p3tunnel.cc - * - * Services for RetroShare. - * - * Copyright 2004-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - - -//#include "retroshare/rsiface.h" -//#include "retroshare/rsinit.h" /* for PGPSSL flag */ -//#include "retroshare/rspeers.h" -#include "services/p3tunnel.h" -#include "pqi/pqissltunnel.h" - -#include "pqi/authssl.h" -#include "pqi/p3connmgr.h" - -#include - -#include "util/rsdebug.h" -#include "util/rsprint.h" -#include "util/rsversion.h" - -#define TUNNEL_HANDSHAKE_INIT 1 -#define TUNNEL_HANDSHAKE_ACK 2 -#define TUNNEL_HANDSHAKE_REFUSE 0 - - p3tunnel::p3tunnel(p3ConnectMgr *cm, pqipersongrp *perGrp) -:p3Service(RS_SERVICE_TYPE_TUNNEL), mConnMgr(cm), mPqiPersonGrp(perGrp) -{ - RsStackMutex stack(mTunnelMtx); /********** STACK LOCKED MTX ******/ - - ownId = mConnMgr->getOwnId(); - std::cerr << "ownId : " << mConnMgr->getOwnId() << std::endl; - addSerialType(new RsTunnelSerialiser()); - - return; -} - -void p3tunnel::statusChange(const std::list &plist) { -} - -int p3tunnel::tick() -{ - return handleIncoming(); -} - -int p3tunnel::handleIncoming() -{ - RsItem *item = NULL; - -#ifdef P3TUNNEL_DEBUG - //std::cerr << "p3tunnel::handleIncoming() called." << std::endl; -#endif - - int nhandled = 0; - // While messages read - while(NULL != (item = recvItem())) - { - if (!mConnMgr->getTunnelConnection()) { - //no tunnel allowed, just drop the packet - continue; - } - - RsTunnelDataItem *tdi = NULL; - RsTunnelHandshakeItem *thi = NULL; - - { -#ifdef P3TUNNEL_DEBUG - std::string out = "p3tunnel::handleIncoming() Received Message!\n"; - item -> print_string(out); - std::cerr << out; -#endif - } - - if (NULL != (tdi = dynamic_cast (item))) { - recvTunnelData(tdi); - nhandled++; - } else if (NULL != (thi = dynamic_cast (item))) { - recvTunnelHandshake(thi); - nhandled++; - } - delete item; - } - return nhandled; -} - -/*************************************************************************************/ -/* Output Network Msgs */ -/*************************************************************************************/ -void p3tunnel::sendTunnelData(std::string destPeerId, std::string relayPeerId, void *data, int data_length) { - sendTunnelDataPrivate(relayPeerId, ownId,relayPeerId, destPeerId, data, data_length); -} - - -void p3tunnel::sendTunnelDataPrivate(std::string to, std::string sourcePeerId, std::string relayPeerId, std::string destPeerId, void *data, int data_length) { - if (!mConnMgr->getTunnelConnection()) { - //no tunnel allowed, just drop the request - return; - } - - RsStackMutex stack(mTunnelMtx); /********** STACK LOCKED MTX ******/ - - // Then send message. - { -#ifdef P3TUNNEL_DEBUG - std::string out = "p3tunnel::sendTunnelDataPrivate() Constructing a RsTunnelItem Message!\n"; - out += "Sending to: " + to; - std::cerr << out << std::endl; -#endif - } - - // Construct a message - RsTunnelDataItem *rdi = new RsTunnelDataItem(); - rdi->destPeerId = destPeerId; - rdi->sourcePeerId = sourcePeerId; - rdi->relayPeerId = relayPeerId; - rdi->encoded_data_len = data_length; - - if(data_length > 0) - { - rdi->encoded_data = (void*)malloc(data_length); - memcpy(rdi->encoded_data, data, data_length); - } - - rdi->PeerId(to); - -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::sendTunnelDataPrivate() data_length : "<< data_length << std::endl; -#endif - /* send msg */ - sendItem(rdi); -} - -void p3tunnel::pingTunnelConnection(std::string relayPeerId, std::string destPeerId) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::pingTunnelConnection() sending ping with relay id : " << relayPeerId << std::endl; - std::cerr << "ownId : " << ownId << std::endl; - std::cerr << "destPeerId : " << destPeerId << std::endl; -#endif - this->sendTunnelDataPrivate(relayPeerId, ownId, relayPeerId, destPeerId, NULL, 0); -} - -void p3tunnel::initiateHandshake(std::string relayPeerId, std::string destPeerId) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::initiateHandshake() initiating handshake with relay id : " << relayPeerId << std::endl; - std::cerr << "ownId : " << ownId << std::endl; - std::cerr << "destPeerId : " << destPeerId << std::endl; -#endif - // Construct a message - RsTunnelHandshakeItem *rhi = new RsTunnelHandshakeItem(); - rhi->destPeerId = destPeerId; - rhi->sourcePeerId = ownId; - rhi->relayPeerId = relayPeerId; - rhi->connection_accepted = TUNNEL_HANDSHAKE_INIT; - rhi->sslCertPEM = AuthSSL::getAuthSSL()->SaveOwnCertificateToString(); - - rhi->PeerId(relayPeerId); - - /* send msg */ - sendItem(rhi); -} - -/*************************************************************************************/ -/* Input Network Msgs */ -/*************************************************************************************/ -void p3tunnel::recvTunnelHandshake(RsTunnelHandshakeItem *item) -{ -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() From: " << item->PeerId() << std::endl; -#endif - - RsPeerDetails pd; - if (!AuthSSL::getAuthSSL()->LoadDetailsFromStringCert(item->sslCertPEM, pd)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() cert is not valid. This might be a intrusion attempt." << std::endl; -#endif - return; - } - - if (item->sourcePeerId != pd.id) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() cert is not issued from the source id of the tunnel. This might be a intrusion attempt." << std::endl; -#endif - return; - } - - //compare the peer id from the item sender to the ids in the item. - if (item->PeerId() == item->sourcePeerId && ownId == item->relayPeerId) { - if (mConnMgr->isOnline(item->destPeerId)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() relaying packet." << std::endl; -#endif - //relaying the handshake - RsTunnelHandshakeItem* forwardItem = new RsTunnelHandshakeItem(); - forwardItem->sourcePeerId = item->sourcePeerId; - forwardItem->relayPeerId = item->relayPeerId; - forwardItem->destPeerId = item->destPeerId; - forwardItem->connection_accepted = item->connection_accepted; - forwardItem->sslCertPEM = item->sslCertPEM; - forwardItem->PeerId(item->destPeerId); - sendItem(forwardItem); - } else { - //sending back refuse - //not implemented -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() not relaying packet because destination is offline." << std::endl; -#endif - } - } else if (item->PeerId() == item->relayPeerId && ownId == item->destPeerId) { - if (item->connection_accepted == TUNNEL_HANDSHAKE_INIT || item->connection_accepted == TUNNEL_HANDSHAKE_ACK) { - //check if we accept connection - if (!mConnMgr->isFriend(pd.id)) { - //send back a refuse - // not implemented - } else { - if (item->connection_accepted == TUNNEL_HANDSHAKE_INIT) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() sending back acknowledgement to " << item->sourcePeerId << std::endl; -#endif - //send back acknowledgement - RsTunnelHandshakeItem* ack = new RsTunnelHandshakeItem(); - ack->sourcePeerId = ownId; - ack->relayPeerId = item->relayPeerId; - ack->destPeerId = item->sourcePeerId; - ack->connection_accepted = TUNNEL_HANDSHAKE_ACK; - ack->sslCertPEM = AuthSSL::getAuthSSL()->SaveOwnCertificateToString(); - ack->PeerId(item->relayPeerId); - sendItem(ack); - } - - //open the local tunnel connection -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvTunnelHandshake() opening localy the tunnel connection emulation." << std::endl; -#endif - pqiperson *pers = mPqiPersonGrp->getPeer(item->sourcePeerId); - pqissltunnel *pqicon = (pqissltunnel *)(((pqiconnect *) pers->getKid(PQI_CONNECT_TUNNEL))->ni); - pqicon->IncommingHanshakePacket(item->relayPeerId); - } - } - } -} - - -void p3tunnel::recvTunnelData(RsTunnelDataItem *item) -{ -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::recvPeerConnectRequest() From: " << item->PeerId() << std::endl; -#endif - - //compare the peer id from the item sender to the ids in the item. - if (item->PeerId() == item->sourcePeerId && ownId == item->relayPeerId) { - privateRecvTunnelDataRelaying(item); - } else if (item->PeerId() == item->relayPeerId && ownId == item->destPeerId) { - privateRecvTunnelDataDestination(item); - } -} - -void p3tunnel::privateRecvTunnelDataRelaying(RsTunnelDataItem *item) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataRelaying() I am relaying, let's see if it's possible to send the packet to destination." << std::endl; -#endif - if (!mConnMgr->isFriend(item->sourcePeerId) || !mConnMgr->isFriend(item->destPeerId)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() not trusting relay or dest peer. Aborting." << std::endl; -#endif - return; - } - if (mConnMgr->isOnline(item->destPeerId)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataRelaying() I am relaying, relay the packet to destination." << std::endl; -#endif - sendTunnelDataPrivate(item->destPeerId, item->sourcePeerId, ownId, item->destPeerId, item->encoded_data, item->encoded_data_len); - return; - } -} - -void p3tunnel::privateRecvTunnelDataDestination(RsTunnelDataItem *item) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() I am the destination Id, let's make some checks and read the packet." << std::endl; -#endif - - if (!mConnMgr->isFriend(item->sourcePeerId) || !mConnMgr->isFriend(item->relayPeerId)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() not trusting relay or source peer. Aborting." << std::endl; -#endif - return; - } - - if (!mConnMgr->isOnline(item->relayPeerId)) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() relay peer is not connected, connection impossible. Aborting." << std::endl; -#endif - return; - } - - pqiperson *pers = mPqiPersonGrp->getPeer(item->sourcePeerId); - if (pers == NULL) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() tunnel connection not found. Aborting." << std::endl; -#endif - return; - } - - pqissltunnel *pqicon = (pqissltunnel *)(((pqiconnect *) pers->getKid(PQI_CONNECT_TUNNEL))->ni); - if (pqicon == NULL || !pqicon->isactive()) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() tunnel connection not found. Aborting." << std::endl; -#endif - return; - } - - //send the packet to the net emulation layer - if (item->encoded_data_len == 0) { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() receiving a ping packet, activating connection and sending back acknowlegment." << std::endl; -#endif - pqissltunnel *pqicon = (pqissltunnel *)(((pqiconnect *) pers->getKid(PQI_CONNECT_TUNNEL))->ni); - pqicon->IncommingPingPacket(); - } else { -#ifdef P3TUNNEL_DEBUG - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() receiving a data packet, transfer it to the pqissltunnel connection." << std::endl; - std::cerr << "p3tunnel::privateRecvTunnelDataDestination() getRsItemSize(item->encoded_data) : " << getRsItemSize(item->encoded_data) << std::endl; -#endif - pqissltunnel *pqicon = (pqissltunnel *)(((pqiconnect *) pers->getKid(PQI_CONNECT_TUNNEL))->ni); - pqicon->addIncomingPacket(item->encoded_data, item->encoded_data_len); - } - return; -} diff --git a/libretroshare/src/unfinished/p3tunnel.h b/libretroshare/src/unfinished/p3tunnel.h deleted file mode 100644 index ec5a03896..000000000 --- a/libretroshare/src/unfinished/p3tunnel.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * libretroshare/src/services: p3tunnel.h - * - * Services for RetroShare. - * - * Copyright 2004-2008 by Robert Fernie. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#ifndef MRK_PQI_TUNNEL_H -#define MRK_PQI_TUNNEL_H - -// The AutoDiscovery Class - -#include "pqi/pqipersongrp.h" - -// system specific network headers -#include "pqi/pqi.h" - -class p3ConnectMgr; - -#include "pqi/pqimonitor.h" -#include "services/p3service.h" -#include "serialiser/rstunnelitems.h" -#include "pqi/authssl.h" - -class p3tunnel: public p3Service, public pqiMonitor -{ - public: - -virtual void statusChange(const std::list &plist); - - p3tunnel(p3ConnectMgr *cm, pqipersongrp *persGrp); - -int tick(); - -void sendTunnelData(std::string destPeerId, std::string relayPeerId, void *data, int data_length); - -void pingTunnelConnection(std::string relayPeerId, std::string destPeerId); -void initiateHandshake(std::string relayPeerId, std::string destPeerId); - - private: - -void sendTunnelDataPrivate(std::string to, std::string sourcePeerId, std::string relayPeerId, std::string destPeerId, void *data, int data_length); - -void privateRecvTunnelDataRelaying(RsTunnelDataItem *item); //invoked when I am relaying -void privateRecvTunnelDataDestination(RsTunnelDataItem *item); //invoked when I am the destination of the tunnel - - /* Network Input */ -int handleIncoming(); -void recvTunnelData(RsTunnelDataItem *item); -void recvTunnelHandshake(RsTunnelHandshakeItem *item); - - - private: - - p3ConnectMgr *mConnMgr; - pqipersongrp *mPqiPersonGrp; - std::string ownId; - - - /* data */ - RsMutex mTunnelMtx; -}; - -#endif // MRK_PQI_TUNNEL_H diff --git a/libretroshare/src/unfinished/rstlvdsdv.cc b/libretroshare/src/unfinished/rstlvdsdv.cc deleted file mode 100644 index da3abe8c5..000000000 --- a/libretroshare/src/unfinished/rstlvdsdv.cc +++ /dev/null @@ -1,419 +0,0 @@ - -/* - * libretroshare/src/serialiser: rstlvtypes.cc - * - * RetroShare Serialiser. - * - * Copyright 2007-2008 by Robert Fernie, Chris Parker - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -#include "rstlvdsdv.h" -#include "rsbaseserial.h" - - -/************************************* RsTlvDsdvEndPoint ************************************/ - -RsTlvDsdvEndPoint::RsTlvDsdvEndPoint() - :RsTlvItem(), idType(0) -{ - return; -} - -void RsTlvDsdvEndPoint::TlvClear() -{ - idType = 0; - anonChunk.clear(); - serviceId.clear(); -} - -uint32_t RsTlvDsdvEndPoint::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + 4 + str + str */ - - s += 4; // idType; - s += GetTlvStringSize(anonChunk); - s += GetTlvStringSize(serviceId); - - return s; - -} - -bool RsTlvDsdvEndPoint::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENDPOINT, tlvsize); - - ok &= setRawUInt32(data, tlvend, offset, idType); - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, anonChunk); - ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH_SHA1, serviceId); - return ok; - -} - - -bool RsTlvDsdvEndPoint::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_DSDV_ENDPOINT) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= getRawUInt32(data, tlvend, offset, &(idType)); - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, anonChunk); - ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH_SHA1, serviceId); - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvDsdvEndPoint::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvDsdvEndPoint::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvDsdvEndPoint", indent); - uint16_t int_Indent = indent + 2; - - printIndent(out, int_Indent); - out << "idType:" << idType; - out << std::endl; - - printIndent(out, int_Indent); - out << "AnonChunk:" << anonChunk; - out << std::endl; - - printIndent(out, int_Indent); - out << "ServiceId:" << serviceId; - out << std::endl; - - printEnd(out, "RsTlvDsdvEndPoint", indent); - return out; -} - - -/************************************* RsTlvDsdvEntry ************************************/ - -RsTlvDsdvEntry::RsTlvDsdvEntry() - :RsTlvItem(), sequence(0), distance(0) -{ - return; -} - -void RsTlvDsdvEntry::TlvClear() -{ - endPoint.TlvClear(); - sequence = 0; - distance = 0; -} - -uint32_t RsTlvDsdvEntry::TlvSize() const -{ - uint32_t s = TLV_HEADER_SIZE; /* header + EndPoint.Size + 4 + 4 */ - - s += endPoint.TlvSize(); - s += 4; // sequence; - s += 4; // distance; - - return s; - -} - -bool RsTlvDsdvEntry::SetTlv(void *data, uint32_t size, uint32_t *offset) const -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - /* add mandatory parts first */ - - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENTRY, tlvsize); - - ok &= endPoint.SetTlv(data, size, offset); - ok &= setRawUInt32(data, tlvend, offset, sequence); - ok &= setRawUInt32(data, tlvend, offset, distance); - - return ok; - -} - - -bool RsTlvDsdvEntry::GetTlv(void *data, uint32_t size, uint32_t *offset) -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_DSDV_ENTRY) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - ok &= endPoint.GetTlv(data, size, offset); - ok &= getRawUInt32(data, tlvend, offset, &(sequence)); - ok &= getRawUInt32(data, tlvend, offset, &(distance)); - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvDsdvEntry::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; - -} - - -std::ostream &RsTlvDsdvEntry::print(std::ostream &out, uint16_t indent) const -{ - printBase(out, "RsTlvDsdvEntry", indent); - uint16_t int_Indent = indent + 2; - - endPoint.print(out, int_Indent); - - printIndent(out, int_Indent); - out << "Sequence:" << sequence; - out << std::endl; - - printIndent(out, int_Indent); - out << "Distance:" << distance; - out << std::endl; - - printEnd(out, "RsTlvDsdvEntry", indent); - return out; -} - - -/************************************* RsTlvDsdvEntrySet ************************************/ - -#if 0 -RsTlvDsdvEntrySet::RsTlvDsdvEntrySet() -{ - -} - -void RsTlvDsdvEntrySet::TlvClear() -{ - entries.clear(); -} - -uint32_t RsTlvDsdvEntrySet::TlvSize() -{ - - uint32_t s = TLV_HEADER_SIZE; /* header */ - - std::list::iterator it; - - - if(!entries.empty()) - { - - for(it = entries.begin(); it != entries.end() ; ++it) - s += it->TlvSize(); - - } - - return s; -} - -bool RsTlvDsdvEntrySet::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ -{ - /* must check sizes */ - uint32_t tlvsize = TlvSize(); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) - return false; /* not enough space */ - - bool ok = true; - - /* start at data[offset] */ - ok &= SetTlvBase(data, tlvend, offset, TLV_TYPE_DSDV_ENTRY_SET , tlvsize); - - if(!entries.empty()) - { - std::list::iterator it; - - for(it = entries.begin(); it != entries.end() ; ++it) - ok &= it->SetTlv(data, size, offset); - } - - - return ok; - -} - - -bool RsTlvDsdvEntrySet::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */ -{ - if (size < *offset + TLV_HEADER_SIZE) - return false; - - uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) ); - uint32_t tlvend = *offset + tlvsize; - - if (size < tlvend) /* check size */ - return false; /* not enough space */ - - if (tlvtype != TLV_TYPE_DSDV_ENTRY_SET) /* check type */ - return false; - - bool ok = true; - - /* ready to load */ - TlvClear(); - - /* skip the header */ - (*offset) += TLV_HEADER_SIZE; - - /* while there is TLV */ - while((*offset) + 2 < tlvend) - { - /* get the next type */ - uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) ); - - switch(tlvsubtype) - { - case TLV_TYPE_DSDV_ENTRY: - { - RsTlvDsdvEntry entry; - ok &= entry.GetTlv(data, size, offset); - if (ok) - { - entries.push_back(entry); - } - } - break; - default: - ok &= SkipUnknownTlv(data, tlvend, offset); - break; - - } - - if (!ok) - break; - } - - - - /*************************************************************************** - * NB: extra components could be added (for future expansion of the type). - * or be present (if this code is reading an extended version). - * - * We must chew up the extra characters to conform with TLV specifications - ***************************************************************************/ - if (*offset != tlvend) - { -#ifdef TLV_DEBUG - std::cerr << "RsTlvDsdvEntrySet::GetTlv() Warning extra bytes at end of item"; - std::cerr << std::endl; -#endif - *offset = tlvend; - } - - return ok; -} - -// prints out contents of RsTlvDsdvEntrySet -std::ostream &RsTlvDsdvEntrySet::print(std::ostream &out, uint16_t indent) -{ - printBase(out, "RsTlvDsdvEntrySet", indent); - uint16_t int_Indent = indent + 2; - - std::list::iterator it; - for(it = entries.begin(); it != entries.end() ; ++it) - it->print(out, int_Indent); - - printEnd(out, "RsTlvDsdvEntrySet", indent); - return out; -} - - -#endif - - diff --git a/libretroshare/src/unfinished/rstlvdsdv.h b/libretroshare/src/unfinished/rstlvdsdv.h deleted file mode 100644 index b815bb4ed..000000000 --- a/libretroshare/src/unfinished/rstlvdsdv.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -/* - * libretroshare/src/serialiser: rstlvdsdv.h - * - * RetroShare Serialiser. - * - * Copyright 2011 by Robert Fernie - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License Version 2 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. - * - * Please report all bugs and problems to "retroshare@lunamutt.com". - * - */ - -/******************************************************************* - * These are the Compound TLV structures that must be (un)packed. - ******************************************************************/ - -#include "serialiser/rstlvitem.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvlist.h" - -#define RSDSDV_MAX_ROUTE_TABLE 1000 - -class RsTlvDsdvEndPoint: public RsTlvItem -{ - public: - RsTlvDsdvEndPoint(); -virtual ~RsTlvDsdvEndPoint() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - uint32_t idType; - std::string anonChunk; - std::string serviceId; -}; - -class RsTlvDsdvEntry: public RsTlvItem -{ - public: - RsTlvDsdvEntry(); -virtual ~RsTlvDsdvEntry() { return; } -virtual uint32_t TlvSize() const; -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset) const; -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); -virtual std::ostream &print(std::ostream &out, uint16_t indent) const; - - RsTlvDsdvEndPoint endPoint; - uint32_t sequence; - uint32_t distance; -}; - -typedef t_RsTlvList RsTlvDsdvEntrySet; - -#if 0 -class RsTlvDsdvEntrySet: public RsTlvItem -{ - public: - RsTlvDsdvEntrySet(); -virtual ~RsTlvDsdvEntrySet() { return; } -virtual uint32_t TlvSize(); -virtual void TlvClear(); -virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */ -virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */ -virtual std::ostream &print(std::ostream &out, uint16_t indent); - - std::list entries; -}; - -#endif - diff --git a/libretroshare/src/unused/p3dsdv.cc b/libretroshare/src/unused/p3dsdv.cc deleted file mode 100644 index 53880111b..000000000 --- a/libretroshare/src/unused/p3dsdv.cc +++ /dev/null @@ -1,910 +0,0 @@ -/******************************************************************************* - * libretroshare/src/unused: p3dsdv.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include "util/rstime.h" - -//#include "serialiser/rsdsdvitems.h" -#include "services/p3dsdv.h" -#include "pqi/p3linkmgr.h" -#include "util/rsrandom.h" - -#include - -/**** - * #define DEBUG_DSDV 1 - ****/ -#define DEBUG_DSDV 1 - -/* DEFINE INTERFACE POINTER! */ -RsDsdv *rsDsdv = NULL; - -/***** - * Routing Services are provided for any service or peer that wants to access / receive info - * over the internal network. - * - * This is going to be based loosely on Ben's Algorithm... - * Each Service / Peer is identified by a HASH. - * This HASH is disguised by a temporary ANON-CHUNK. - * DSDVID = Sha1(ANONCHUNK + HASH). - * - * Each peer can advertise as many Services as they want. - * The Anon-chunk should be rotated regularly to hide it well. - * period to be defined. - * - * - * Once this Routing table has been established, Routes can be created - in a similar manner to turtle paths. - * (Send Path request (Path Id + Origin + Destination))... path is established. - * - * Then we can do Onion Routing etc, on top of this. - * - ****/ - -p3Dsdv::p3Dsdv(p3ServiceControl *sc) - :p3Service(), /* p3Config(CONFIG_TYPE_DSDV), */ mDsdvMtx("p3Dsdv"), mServiceCtrl(sc) -{ - addSerialType(new RsDsdvSerialiser()); - - mSentTablesTime = 0; - mSentIncrementTime = 0; -} - -const std::string DSDV_APP_NAME = "dsdv"; -const uint16_t DSDV_APP_MAJOR_VERSION = 1; -const uint16_t DSDV_APP_MINOR_VERSION = 0; -const uint16_t DSDV_MIN_MAJOR_VERSION = 1; -const uint16_t DSDV_MIN_MINOR_VERSION = 0; - -RsServiceInfo p3Dsdv::getServiceInfo() -{ - return RsServiceInfo(RS_SERVICE_TYPE_DSDV, - DSDV_APP_NAME, - DSDV_APP_MAJOR_VERSION, - DSDV_APP_MINOR_VERSION, - DSDV_MIN_MAJOR_VERSION, - DSDV_MIN_MINOR_VERSION); -} - - - -int p3Dsdv::tick() -{ - processIncoming(); - sendTables(); - - return 0; -} - -int p3Dsdv::status() -{ - return 1; -} - -#define DSDV_BROADCAST_PERIOD (60*10) // 10 Minutes. -#define DSDV_MIN_INCREMENT_PERIOD 5 -#define DSDV_DISCARD_PERIOD (DSDV_BROADCAST_PERIOD * 2) - -int p3Dsdv::sendTables() -{ - rstime_t now = time(NULL); - rstime_t tt, it; - bool updateRequired = false; - { - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - tt = mSentTablesTime; - it = mSentIncrementTime; - updateRequired = mSignificantChanges; - } - - if (now - tt > DSDV_BROADCAST_PERIOD) - { - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::sendTables() Broadcast Time"; - std::cerr << std::endl; -#endif - selectStableRoutes(); - clearOldRoutes(); - - generateRoutingTables(false); - - printDsdvTable(std::cerr); - - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - mSentTablesTime = now; - mSentIncrementTime = now; - - return true ; - } - - /* otherwise send incremental changes */ - if ((updateRequired) && (now - it > DSDV_MIN_INCREMENT_PERIOD)) - { - selectStableRoutes(); - - generateRoutingTables(true); - - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - mSentIncrementTime = now; - } - - return true; -} - -#define RSDSDV_SEQ_INCREMENT 2 - -void p3Dsdv::advanceLocalSequenceNumbers() -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - rstime_t now = time(NULL); - - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - RsDsdvTableEntry &v = (it->second); - if (v.mOwnSource) - { - v.mStableRoute.mSequence += RSDSDV_SEQ_INCREMENT; - v.mStableRoute.mReceived = now; - } - } -} - -void p3Dsdv::clearSignificantChangesFlags() -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - RsDsdvTableEntry &v = (it->second); - if (v.mFlags & RSDSDV_FLAGS_SIGNIFICANT_CHANGE) - { - v.mFlags &= ~RSDSDV_FLAGS_SIGNIFICANT_CHANGE; - } - } - mSignificantChanges = false; -} - - -int p3Dsdv::generateRoutingTables(bool incremental) -{ - /* we ping our peers */ - /* who is online? */ - std::set idList; - mServiceCtrl->getPeersConnected(getServiceInfo().mServiceType, idList); - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::generateRoutingTables(" << incremental << ")"; - std::cerr << std::endl; -#endif - - if (!incremental) - { - /* now clear significant flag */ - advanceLocalSequenceNumbers(); - } - - /* prepare packets */ - std::set::iterator it; - for(it = idList.begin(); it != idList.end(); ++it) - { -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::generateRoutingTables() For: " << *it; - std::cerr << std::endl; -#endif - - generateRoutingTable(*it, incremental); - } - - - /* now clear significant flag */ - clearSignificantChangesFlags(); - return 1; -} - - -int p3Dsdv::generateRoutingTable(const RsPeerId &peerId, bool incremental) -{ - RsDsdvRouteItem *dsdv = new RsDsdvRouteItem(); - dsdv->PeerId(peerId); - - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - RsDsdvTableEntry &v = (it->second); - - /* discard/ignore criterion */ - if (!v.mIsStable) - { - continue; - } - - if (v.mStableRoute.mDistance >= RSDSDV_MAX_DISTANCE) - { - continue; - } - - if (incremental) - { - if (v.mFlags & RSDSDV_FLAGS_SIGNIFICANT_CHANGE) - { - // Done elsewhere. - //v.mFlags &= ~SIGNIFICANT_CHANGE; - } - else - { - /* ignore non-significant changes */ - continue; - } - } - - RsTlvDsdvEntry entry; - - entry.endPoint.idType = v.mDest.mIdType; - entry.endPoint.anonChunk = v.mDest.mAnonChunk; - entry.endPoint.serviceId = v.mDest.mHash; - entry.sequence = v.mStableRoute.mSequence; - entry.distance = v.mStableRoute.mDistance; - - //dsdv->routes.entries.push_back(entry); - dsdv->routes.mList.push_back(entry); - - //if (dsdv->routes.entries.size() > RSDSDV_MAX_ROUTE_TABLE) - if (dsdv->routes.mList.size() > RSDSDV_MAX_ROUTE_TABLE) - { - sendItem(dsdv); - dsdv = new RsDsdvRouteItem(); - dsdv->PeerId(peerId); - } - } - sendItem(dsdv); - return 1; -} - - -/**************************************************************************** - ****************************************************************************/ - -int p3Dsdv::processIncoming() -{ - /* for each packet - pass to specific handler */ - RsItem *item = NULL; - while(NULL != (item = recvItem())) - { - switch(item->PacketSubType()) - { - default: - break; - case RS_PKT_SUBTYPE_DSDV_ROUTE: - { - handleDSDV((RsDsdvRouteItem *) item); - } - break; - } - - /* clean up */ - delete item; - } - return true ; -} - - -int p3Dsdv::handleDSDV(RsDsdvRouteItem *dsdv) -{ - /* iterate over the entries */ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - rstime_t now = time(NULL); - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Received Pkt from: " << dsdv->PeerId(); - std::cerr << std::endl; - //dsdv->print(std::cerr); - //std::cerr << std::endl; -#endif - - std::list::iterator it; - //for(it = dsdv->routes.entries.begin(); it != dsdv->routes.entries.end(); ++it) - for(it = dsdv->routes.mList.begin(); it != dsdv->routes.mList.end(); ++it) - { - /* check for existing */ - RsTlvDsdvEntry &entry = *it; - uint32_t realDistance = entry.distance + 1; // metric. - - - /* find the entry */ - std::map::iterator tit; - tit = mTable.find(entry.endPoint.serviceId); - if (tit == mTable.end()) - { -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Adding Entry for New ServiceId: "; - std::cerr << entry.endPoint.serviceId; - std::cerr << std::endl; -#endif - /* new entry! */ - RsDsdvTableEntry v; - v.mDest.mIdType = entry.endPoint.idType; - v.mDest.mAnonChunk = entry.endPoint.anonChunk; - v.mDest.mHash = entry.endPoint.serviceId; - - /* add as a possible route */ - RsDsdvRoute newRoute; - - newRoute.mNextHop = dsdv->PeerId(); - newRoute.mReceived = now; - newRoute.mSequence = entry.sequence; - newRoute.mDistance = realDistance; - newRoute.mValidSince = now; - - v.mAllRoutes[dsdv->PeerId()] = newRoute; - v.mIsStable = false; - - v.mFlags = RSDSDV_FLAGS_NEW_ROUTE; - v.mOwnSource = false; - v.mMatched = false; - - // store in table. - mTable[v.mDest.mHash] = v; - } - else - { - RsDsdvTableEntry &v = tit->second; - if (v.mOwnSource) - { -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Ignoring OwnSource Entry:"; - std::cerr << entry.endPoint.serviceId; - std::cerr << std::endl; -#endif - continue; // Ignore if we are source. - } - - /* look for this in mAllRoutes */ - std::map::iterator rit; - rit = v.mAllRoutes.find(dsdv->PeerId()); - if (rit == v.mAllRoutes.end()) - { - /* add a new entry in */ - RsDsdvRoute newRoute; - - newRoute.mNextHop = dsdv->PeerId(); - newRoute.mReceived = now; - newRoute.mSequence = entry.sequence; - newRoute.mDistance = realDistance; - newRoute.mValidSince = now; - - v.mAllRoutes[dsdv->PeerId()] = newRoute; - - /* if we've just added it in - can't be stable one */ -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Adding NewRoute Entry:"; - std::cerr << entry.endPoint.serviceId; - std::cerr << std::endl; -#endif - } - else - { - if (rit->second.mSequence >= entry.sequence) - { -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Ignoring OLDSEQ Entry:"; - std::cerr << entry.endPoint.serviceId; - std::cerr << std::endl; -#endif - /* ignore same/old sequence number??? */ - continue; - } -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::handleDSDV() Updating Entry:"; - std::cerr << entry.endPoint.serviceId; - std::cerr << std::endl; -#endif - - /* update seq,dist,etc */ - if (rit->second.mSequence + 2 < entry.sequence) - { - /* skipped a sequence number - reset timer */ - rit->second.mValidSince = now; - } - - //rit->second.mNextHop; // unchanged. - rit->second.mReceived = now; - rit->second.mSequence = entry.sequence; - rit->second.mDistance = realDistance; - - /* if consistent route... maintain */ - if ((v.mIsStable) && - (rit->second.mNextHop == v.mStableRoute.mNextHop)) - { - v.mStableRoute = rit->second; - } - else - { - /* otherwise we need to wait - see if we get new update */ - } - } - } - } - return 1; -} - - -int p3Dsdv::selectStableRoutes() -{ - /* iterate over the entries */ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - rstime_t now = time(NULL); - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::selectStableRoutes()"; - std::cerr << std::endl; -#endif - - /* find the entry */ - std::map::iterator tit; - for(tit = mTable.begin(); tit != mTable.end(); ++tit) - { - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::selectStableRoutes() For Entry: "; - std::cerr << tit->second; - std::cerr << std::endl; -#endif - if (tit->second.mOwnSource) - { -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::selectStableRoutes() OwnSource... Ignoring"; - std::cerr << std::endl; -#endif - continue; // Ignore if we are source. - } - - std::map::iterator rit; - uint32_t newest = 0; - RsPeerId newestId; - uint32_t closest = RSDSDV_MAX_DISTANCE + 1; - RsPeerId closestId; - rstime_t closestAge = 0; - - /* find newest sequence number */ - for(rit = tit->second.mAllRoutes.begin(); - rit != tit->second.mAllRoutes.end(); ++rit) - { - if ((now - rit->second.mReceived <= DSDV_DISCARD_PERIOD) && - (rit->second.mSequence >= newest)) - { - newest = rit->second.mSequence; - newestId = rit->first; - - /* also becomes default for closest (later) */ - closest = rit->second.mDistance; - closestId = rit->first; - closestAge = now - rit->second.mValidSince; - } - } - - if (closest >= RSDSDV_MAX_DISTANCE + 1) - { -#ifdef DEBUG_DSDV - std::cerr << "\tNo Suitable Route"; - std::cerr << std::endl; -#endif - tit->second.mIsStable = false; - continue; - } - - uint32_t currseq = newest - (newest % 2); // remove 'kill'=ODD Seq. - -#ifdef DEBUG_DSDV - std::cerr << "\t Newest Seq: " << newest << " from: " << newestId; - std::cerr << std::endl; -#endif - - /* find closest distance - with valid seq & max valid time */ - for(rit = tit->second.mAllRoutes.begin(); - rit != tit->second.mAllRoutes.end(); ++rit) - { - /* Maximum difference in Sequence number is 2*DISTANCE - * Otherwise it must be old. - */ - if (rit->second.mSequence + rit->second.mDistance * 2 < currseq) - { -#ifdef DEBUG_DSDV - std::cerr << "\t\tIgnoring OLD SEQ Entry: " << rit->first; - std::cerr << std::endl; -#endif - - continue; // ignore. - } - - /* if we haven't received an update in ages - old */ - if (now - rit->second.mReceived > DSDV_DISCARD_PERIOD) - { -#ifdef DEBUG_DSDV - std::cerr << "\t\tIgnoring OLD TIME Entry: " << rit->first; - std::cerr << std::endl; -#endif - - continue; // ignore. - } - - if (rit->second.mDistance < closest) - { - closest = rit->second.mDistance; - closestId = rit->first; - closestAge = now - rit->second.mValidSince; -#ifdef DEBUG_DSDV - std::cerr << "\t\tUpdating to Closer Entry: " << rit->first; - std::cerr << std::endl; -#endif - } - else if ((rit->second.mDistance == closest) && - (closestAge < now - rit->second.mValidSince)) - { - /* have a more stable (older) one */ - closest = rit->second.mDistance; - closestId = rit->first; - closestAge = now - rit->second.mValidSince; -#ifdef DEBUG_DSDV - std::cerr << "\t\tUpdating to Stabler Entry: " << rit->first; - std::cerr << std::endl; -#endif - } - else - { -#ifdef DEBUG_DSDV - std::cerr << "\t\tIgnoring Distant Entry: " << rit->first; - std::cerr << std::endl; -#endif - } - - } - - tit->second.mIsStable = true; - rit = tit->second.mAllRoutes.find(closestId); - tit->second.mStableRoute = rit->second; - tit->second.mFlags &= ~RSDSDV_FLAGS_NEW_ROUTE; - -#ifdef DEBUG_DSDV - std::cerr << "\tStable Route: " << tit->second.mStableRoute; - std::cerr << std::endl; -#endif - } - return 1; -} - - - - -int p3Dsdv::clearOldRoutes() -{ - /* iterate over the entries */ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::clearOldRoutes()"; - std::cerr << std::endl; -#endif - - /* find the entry */ - std::map::iterator it, it2; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - if (it->second.mOwnSource) - { - continue; - } - - if (it->second.mIsStable) - { - continue; - } - - if (it->second.mFlags & RSDSDV_FLAGS_NEW_ROUTE) - { - continue; - } - - /* backstep iterator for loop, and delete original */ - it2 = it; - it--; - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::clearOldRoutes() Deleting OLD ServiceId: " << it2->first; - std::cerr << std::endl; -#endif - mTable.erase(it2); - } - return 1; -} - - -/*************** pqiMonitor callback ***********************/ -void p3Dsdv::statusChange(const std::list &plist) -{ - std::list::const_iterator it; - for(it = plist.begin(); it != plist.end(); ++it) - { - /* only care about disconnected / not friends cases */ - if ( 1 ) - { - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - - - - - } - } -} - -int p3Dsdv::addTestService() -{ - RsDsdvId testId; - - int rndhash1[SHA_DIGEST_LENGTH / 4]; - int rndhash2[SHA_DIGEST_LENGTH / 4]; - std::string realHash; - std::string seedHash; - - for(int i = 0; i < SHA_DIGEST_LENGTH / 4; i++) - { - rndhash1[i] = RSRandom::random_u32(); - rndhash2[i] = RSRandom::random_u32(); - } - - for(int i = 0; i < SHA_DIGEST_LENGTH; i++) - { - rs_sprintf_append(realHash, "%02x", (uint32_t) ((uint8_t *) rndhash1)[i]); - rs_sprintf_append(seedHash, "%02x", (uint32_t) ((uint8_t *) rndhash2)[i]); - } - - - uint8_t sha_hash[SHA_DIGEST_LENGTH]; - memset(sha_hash,0,SHA_DIGEST_LENGTH*sizeof(uint8_t)) ; - SHA_CTX *sha_ctx = new SHA_CTX; - SHA1_Init(sha_ctx); - - SHA1_Update(sha_ctx, realHash.c_str(), realHash.length()); - SHA1_Update(sha_ctx, seedHash.c_str(), seedHash.length()); - SHA1_Final(sha_hash, sha_ctx); - delete sha_ctx; - - for(int i = 0; i < SHA_DIGEST_LENGTH; i++) - { - rs_sprintf_append(testId.mHash, "%02x", (uint32_t) (sha_hash)[i]); - } - - testId.mIdType = RSDSDV_IDTYPE_TEST; - testId.mAnonChunk = seedHash; - - addDsdvId(&testId, realHash); - return 1; -} - - -int p3Dsdv::addDsdvId(RsDsdvId *id, std::string realHash) -{ - - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::addDsdvId() ID: " << *id << " RealHash: " << realHash; - std::cerr << std::endl; -#endif - - rstime_t now = time(NULL); - - /* check for duplicate */ - std::map::iterator it; - it = mTable.find(id->mHash); - if (it != mTable.end()) - { - /* error */ - std::cerr << "p3Dsdv::addDsdvId() ERROR Duplicate ID"; - std::cerr << std::endl; - - return 0; - } - - /* new entry! */ - RsDsdvTableEntry v; - v.mDest = *id; - - v.mStableRoute.mNextHop = mServiceCtrl->getOwnId(); - v.mStableRoute.mReceived = now; - v.mStableRoute.mValidSince = now; - v.mStableRoute.mSequence = 0; - v.mStableRoute.mDistance = 0; - v.mIsStable = true; - - v.mFlags = RSDSDV_FLAGS_OWN_SERVICE; - v.mOwnSource = true; - v.mMatched = true; - v.mMatchedHash = realHash; - - // store in table. - mTable[v.mDest.mHash] = v; - - return 1; -} - - - - -int p3Dsdv::dropDsdvId(RsDsdvId *id) -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - -#ifdef DEBUG_DSDV - std::cerr << "p3Dsdv::dropDsdvId() ID: " << *id; - std::cerr << std::endl; -#endif - - /* This should send out an infinity packet... and flag for deletion */ - - std::map::iterator it; - it = mTable.find(id->mHash); - if (it == mTable.end()) - { - /* error */ - std::cerr << "p3Dsdv::addDsdvId() ERROR Unknown ID"; - std::cerr << std::endl; - - return 0; - } - - mTable.erase(it); - - return 1; -} - - -int p3Dsdv::printDsdvTable(std::ostream &out) -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - /* iterate over the entries */ - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - RsDsdvTableEntry &v = it->second; - out << v; - out << std::endl; - } - return 1; -} - -/*****************************************/ - -uint32_t p3Dsdv::getLocalServices(std::list &hashes) -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - /* iterate over the entries */ - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - if (it->second.mOwnSource) - { - hashes.push_back(it->first); - } - } - return 1; -} - - -uint32_t p3Dsdv::getAllServices(std::list &hashes) -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - /* iterate over the entries */ - std::map::iterator it; - for(it = mTable.begin(); it != mTable.end(); ++it) - { - hashes.push_back(it->first); - } - return 1; -} - - -int p3Dsdv::getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry) -{ - RsStackMutex stack(mDsdvMtx); /****** LOCKED MUTEX *******/ - - /* iterate over the entries */ - std::map::iterator it; - it = mTable.find(hash); - if (it == mTable.end()) - { - return 0; - } - - entry = it->second; - - return 1; -} - -std::ostream &operator<<(std::ostream &out, const RsDsdvId &id) -{ - out << "[Type: " << id.mIdType << " AMZ: " << id.mAnonChunk << " THASH: " << id.mHash; - out << "]"; - - return out; -} - - -std::ostream &operator<<(std::ostream &out, const RsDsdvRoute &route) -{ - rstime_t now = time(NULL); - out << "< Seq: " << route.mSequence << " Dist: " << route.mDistance; - out << " NextHop: " << route.mNextHop; - out << " recvd: " << now-route.mReceived; - out << " validSince: " << now-route.mValidSince; - out << " >"; - - return out; -} - -std::ostream &operator<<(std::ostream &out, const RsDsdvTableEntry &entry) -{ - out << "DSDV Route for: " << entry.mDest << std::endl; - if (entry.mIsStable) - { - out << "\tStable: " << entry.mStableRoute << std::endl; - } - else - { - out << "\tNo Stable Route" << std::endl; - } - - out << "\tOwnSource: " << entry.mOwnSource; - out << " Flags: " << entry.mFlags; - if (entry.mMatched) - { - out << " Matched: " << entry.mMatchedHash; - } - else - { - out << " Non Matched"; - } - out << std::endl; - if (entry.mAllRoutes.size() > 0) - { - out << "\tAll Routes:" << std::endl; - } - - std::map::const_iterator it; - for(it = entry.mAllRoutes.begin(); it != entry.mAllRoutes.end(); ++it) - { - out << "\t\t" << it->second << std::endl; - } - return out; -} - - diff --git a/libretroshare/src/unused/p3dsdv.h b/libretroshare/src/unused/p3dsdv.h deleted file mode 100644 index 049ed8695..000000000 --- a/libretroshare/src/unused/p3dsdv.h +++ /dev/null @@ -1,118 +0,0 @@ -/******************************************************************************* - * libretroshare/src/unused: p3dsdv.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef SERVICE_RSDSDV_HEADER -#define SERVICE_RSDSDV_HEADER - -#include -#include - -#include "serialiser/rsdsdvitems.h" -#include "services/p3service.h" -#include "pqi/p3cfgmgr.h" -#include "pqi/pqimonitor.h" - -#include "retroshare/rsdsdv.h" - -class p3ServiceControl; - - -#define RSDSDV_MAX_DISTANCE 3 -#define RSDSDV_MAX_SEND_TABLE 100 - -//!The RS DSDV service. - /** - * - * Finds RS wide paths to Services and Peers. - */ - -class p3Dsdv: public RsDsdv, public p3Service /* , public p3Config */, public pqiServiceMonitor -{ - public: - p3Dsdv(p3ServiceControl *cm); -virtual RsServiceInfo getServiceInfo(); - - /*** internal librs interface ****/ - -int addDsdvId(RsDsdvId *id, std::string realHash); -int dropDsdvId(RsDsdvId *id); -int printDsdvTable(std::ostream &out); - -int addTestService(); - - private: - -int sendTables(); -void advanceLocalSequenceNumbers(); -void clearSignificantChangesFlags(); - - -int generateRoutingTables(bool incremental); -int generateRoutingTable(const RsPeerId &peerId, bool incremental); - -int processIncoming(); - -int handleDSDV(RsDsdvRouteItem *dsdv); - -int selectStableRoutes(); -int clearOldRoutes(); - - public: - - /***** overloaded from rsDsdv *****/ - -virtual uint32_t getLocalServices(std::list &hashes); -virtual uint32_t getAllServices(std::list &hashes); -virtual int getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry); - - /***** overloaded from p3Service *****/ - /*! - * Process stuff. - */ - - virtual int tick(); - virtual int status(); - - /*************** pqiMonitor callback ***********************/ - virtual void statusChange(const std::list &plist); - - /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; - - private: - RsMutex mDsdvMtx; - - std::map mTable; - - rstime_t mSentTablesTime; - rstime_t mSentIncrementTime; - - bool mSignificantChanges; - - p3ServiceControl *mServiceCtrl; - -}; - -#endif // SERVICE_RSDSDV_HEADER - diff --git a/libretroshare/src/unused/pqiarchive.cc b/libretroshare/src/unused/pqiarchive.cc deleted file mode 100644 index df7c57f02..000000000 --- a/libretroshare/src/unused/pqiarchive.cc +++ /dev/null @@ -1,419 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiarchive.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/* This is dependent on the sslroot at the moment. - * -> as we need to create/restore references to the Person. - * -> and store the signatures to do this. - */ - -/******************************************************************* - * pqiarchive provides an archive stream. - * This stores RsItem + Person Reference + Timestamp, - * - * and allows Objects to be replayed or restored, - * independently of the rest of the pqi system. - * - */ - -#ifdef SUSPENDED_UNUSED_CODE - -#include "pqi/pqiarchive.h" -#include "serialiser/rsserial.h" -#include -#include - -#include "util/rsdebug.h" -#include "util/rsstring.h" -#include "util/rstime.h" - -const int pqiarchivezone = 9326; - -struct pqiarchive_header -{ - uint32_t type; - uint32_t length; - uint32_t ts; - uint8_t personSig[PQI_PEERID_LENGTH]; -}; - -const int PQIARCHIVE_TYPE_PQITEM = 0x0001; - -/* PeerId of PQInterface is not important ... as we are archiving - * packets from other people... - */ - -pqiarchive::pqiarchive(RsSerialiser *rss, BinInterface *bio_in, int bio_flags_in) - :PQInterface(""), rsSerialiser(rss), bio(bio_in), bio_flags(bio_flags_in), - nextPkt(NULL), nextPktTS(0), firstPktTS(0), initTS(0),realTime(false) -{ - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::pqiarchive() Initialisation!\n"); - - if (!bio_in) - { - pqioutput(PQL_ALERT, pqiarchivezone, "pqiarchive::pqiarchive() NULL bio, FATAL ERROR!\n"); - exit(1); - } - - return; -} - -pqiarchive::~pqiarchive() -{ - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::~pqiarchive() Destruction!\n"); - - if (bio_flags & BIN_FLAGS_NO_CLOSE) - { - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::~pqiarchive() Not Closing BinInterface!\n"); - } - else if (bio) - { - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::~pqiarchive() Deleting BinInterface!\n"); - - delete bio; - } - - if (rsSerialiser) - delete rsSerialiser; - - if (nextPkt) - { - delete nextPkt; - } - return; -} - - -// Get/Send Items. -int pqiarchive::SendItem(RsItem *si) -{ - { - std::string out = "pqiarchive::SendItem()\n"; - si -> print_string(out); - pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out); - } - - // check if this is a writing bio. - - if (!(bio_flags & BIN_FLAGS_WRITEABLE)) - { - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete si; - return -1; - } - -// std::cerr << "SendItem: si->PeerId()=" << si->PeerId() << std::endl ; - - int ret = writePkt(si); - return ret; /* 0 - failure, 1 - success*/ -} - -RsItem *pqiarchive::GetItem() -{ - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::GetItem()"); - - // check if this is a reading bio. - if (!(bio_flags & BIN_FLAGS_READABLE)) - { - pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, "pqiarchive::GetItem() Error Not Readable"); - return NULL; - } - - // load if we dont have a packet. - if (!nextPkt) - { - if (!readPkt(&nextPkt, &nextPktTS)) - { - pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, "pqiarchive::GetItem() Failed to ReadPkt"); - return NULL; - } - } - - if (!nextPkt) return NULL; - - - /* if realtime - check delta */ - bool rtnPkt = true; - if ((realTime) && (initTS)) - { - int delta = time(NULL) - initTS; - int delta2 = nextPktTS - firstPktTS; - if (delta >= delta2) - { - rtnPkt = true; - } - else - { - rtnPkt = false; - } - } - - if (rtnPkt) - { - if (!initTS) - { - /* first read! */ - initTS = time(NULL); - firstPktTS = nextPktTS; - } - RsItem *outPkt = nextPkt; - nextPkt = NULL; - - if (outPkt != NULL) - { - std::string out = "pqiarchive::GetItem() Returning:\n"; - outPkt -> print_string(out); - pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out); - } - return outPkt; - } - return NULL; -} - -// // PQInterface -int pqiarchive::tick() -{ - return 0; -} - -int pqiarchive::status() -{ - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::status()"); - return 0; -} - -// -/**************** HANDLE OUTGOING TRANSLATION + TRANSMISSION ******/ - -int pqiarchive::writePkt(RsItem *pqi) -{ -// std::cerr << "writePkt, pqi->peerId()=" << pqi->PeerId() << std::endl ; - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::writePkt()"); - - uint32_t pktsize = rsSerialiser->size(pqi); - void *ptr = malloc(pktsize); - if (!(rsSerialiser->serialise(pqi, ptr, &pktsize))) - { - std::string out = "pqiarchive::writePkt() Null Pkt generated!\nCaused By:\n"; - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - return 0; - } - - /* extract the extra details */ - uint32_t len = getRsItemSize(ptr); - if (len != pktsize) - { - std::string out; - rs_sprintf(out, "pqiarchive::writePkt() Length MisMatch: len: %lu != pktsize: %lu\nCaused By:\n", len, pktsize); - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - return 0; - } - - - if (!(bio->cansend(0))) - { - std::string out = "pqiarchive::writePkt() BIO cannot write!\nDiscarding:\n"; - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 0; - } - - // using the peerid from the item. - if (pqi->PeerId().length() != PQI_PEERID_LENGTH) - { - std::string out = "pqiarchive::writePkt() Invalid peerId Length!\n"; - rs_sprintf_append(out, "Found %ld instead of %ld\n", pqi->PeerId().length(), PQI_PEERID_LENGTH); - out += "pqi->PeerId() = " + pqi->PeerId() + "\nCaused By:\n"; - pqi -> print_string(out); - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - return 0; - } - - std::string out = "Writing Pkt Header\n"; - struct pqiarchive_header hdr; - hdr.type = PQIARCHIVE_TYPE_PQITEM; - hdr.length = len; - hdr.ts = time(NULL); - memcpy(hdr.personSig, pqi->PeerId().c_str(), PQI_PEERID_LENGTH); - - // write packet header. - if (sizeof(hdr) != bio->senddata(&hdr, sizeof(hdr))) - { - out += "Trouble writing header!\n"; - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 0; - } - - out += "Writing Pkt Body\n"; - - // write packet. - if ((int) len != bio->senddata(ptr, len)) - { - out += "Problems with Send Data!\n"; - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 0; - } - - out += " Success!"; - pqioutput(PQL_DEBUG_BASIC, pqiarchivezone, out); - - free(ptr); - if (!(bio_flags & BIN_FLAGS_NO_DELETE)) - delete pqi; - - return 1; -} - -/* Reads a single packet from the input stream - * gets the timestamp as well. - * - */ - -int pqiarchive::readPkt(RsItem **item_out, long *ts_out) -{ - pqioutput(PQL_DEBUG_ALL, pqiarchivezone, "pqiarchive::readPkt()"); - - if ((!(bio->isactive())) || (!(bio->moretoread(0)))) - { - return 0; - } - - // header - struct pqiarchive_header hdr; - - // enough space to read any packet. - int maxlen = getRsPktMaxSize(); - void *block = malloc(maxlen); - - // initial read size: basic packet. - int blen = getRsPktBaseSize(); - - int tmplen; - - /* read in the header */ - if (sizeof(hdr) != bio->readdata(&hdr, sizeof(hdr))) - { - /* error */ - pqioutput(PQL_WARNING, pqiarchivezone, - "pqiarchive::readPkt() bad read(1)"); - - free(block); - return 0; - } - - /* we have the header */ - - // read the basic block (minimum packet size) - if (blen != (tmplen = bio->readdata(block, blen))) - { - pqioutput(PQL_WARNING, pqiarchivezone, - "pqiarchive::readPkt() bad read(2)"); - - free(block); - return 0; - } - - // workout how much more to read. - int extralen = getRsItemSize(block) - blen; - if (extralen > 0) - { - void *extradata = (void *) (((char *) block) + blen); - if (extralen != (tmplen = bio->readdata(extradata, extralen))) - { - - std::string out; - rs_sprintf(out, "pqiarchive::readPkt() Error Completing Read (read %d/%d)\n", tmplen, extralen); - pqioutput(PQL_ALERT, pqiarchivezone, out); - - free(block); - return 0; - } - } - - // create packet, based on header. - //std::cerr << "Read Data Block -> Incoming Pkt("; - //std::cerr << blen + extralen << ")" << std::endl; - uint32_t readbytes = extralen + blen; - - RsItem *item = rsSerialiser->deserialise(block, &readbytes); - free(block); - - if (item == NULL) - { - pqioutput(PQL_ALERT, pqiarchivezone, - "pqiarchive::readPkt() Failed to create Item from archive!"); - return 0; - } - - /* Cannot detect bad ids here anymore.... - * but removed dependancy on the sslroot! - */ - - std::string peerId = ""; - for(int i = 0; i < PQI_PEERID_LENGTH; i++) - { - peerId += hdr.personSig[i]; - } - item->PeerId(peerId); - - *item_out = item; - *ts_out = hdr.ts; - - return 1; -} - -/**** Hashing Functions ****/ -std::string pqiarchive::gethash() -{ - return bio->gethash(); -} -#endif - - diff --git a/libretroshare/src/unused/pqiarchive.h b/libretroshare/src/unused/pqiarchive.h deleted file mode 100644 index 4c2a82a96..000000000 --- a/libretroshare/src/unused/pqiarchive.h +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * libretroshare/src/pqi: pqiarchive.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifdef SUSPENDED_UNUSED_CODE - -#ifndef MRK_PQI_ARCHIVE_STREAMER_HEADER -#define MRK_PQI_ARCHIVE_STREAMER_HEADER - -#include "pqi/pqi.h" - -#include - -/******************************************************************* - * pqiarchive provides an archive stream. - * This stores RsItem + Person Reference + Timestamp, - * - * and allows Objects to be replayed or restored, - * independently of the rest of the pqi system. - * - */ - -class pqiarchive: public PQInterface -{ -public: - pqiarchive(RsSerialiser *rss, BinInterface *bio_in, int bio_flagsin); -virtual ~pqiarchive(); - -// PQInterface -virtual int SendItem(RsItem *); -virtual RsItem *GetItem(); - -virtual int tick(); -virtual int status(); - -virtual void setRealTime(bool r) { realTime = r; } - -std::string gethash(); - - private: -int writePkt(RsItem *item); -int readPkt(RsItem **item_out, long *ts); - - // Serialiser - RsSerialiser *rsSerialiser; - // Binary Interface for IO, initialisated at startup. - BinInterface *bio; - unsigned int bio_flags; // only BIN_NO_CLOSE at the moment. - - // Temp Storage for transient data..... - RsItem *nextPkt; - long nextPktTS; /* timestamp associated with nextPkt */ - long firstPktTS; /* timestamp associated with first read Pkt */ - long initTS; /* clock timestamp at first read */ - - bool realTime; -}; - - -#endif //MRK_PQI_ARCHIVE_STREAMER_HEADER -#endif //SUSPENDED_UNUSED_CODE diff --git a/libretroshare/src/unused/rscompress.cc b/libretroshare/src/unused/rscompress.cc deleted file mode 100644 index e3aa0f849..000000000 --- a/libretroshare/src/unused/rscompress.cc +++ /dev/null @@ -1,196 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rscompress.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include -#include -#include "rscompress.h" -#include "zlib.h" -#include "util/rsmemory.h" - -// 16K buffer size. -// -static const unsigned int CHUNK = 16384u ; - -bool RsCompress::compress_memory_chunk(const uint8_t *input_mem,const uint32_t input_size,uint8_t *& output_mem,uint32_t& output_size) -{ - - uint32_t remaining_input = input_size ; - uint32_t output_offset = 0 ; - uint32_t input_offset = 0 ; - output_size = 1024 ; - output_mem = (uint8_t*)rs_malloc(output_size) ; - - if(!output_mem) - return false ; - - int ret, flush; - unsigned have; - int level = 9 ; - z_stream strm; - unsigned char in[CHUNK]; - unsigned char out[CHUNK]; - /* allocate deflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - - ret = deflateInit(&strm, level); - if (ret != Z_OK) - return false; - - /* compress until end of file */ - do - { - uint32_t available_in = std::min(CHUNK,remaining_input) ; - memcpy(in,input_mem+input_offset,available_in) ; - strm.avail_in = available_in ; - remaining_input -= available_in ; - input_offset += available_in ; - - flush = /*feof(source)*/ remaining_input ? Z_NO_FLUSH: Z_FINISH ; - strm.next_in = in; - - /* run deflate() on input until output buffer not full, finish - compression if all of source has been read in */ - do - { - strm.avail_out = CHUNK; - strm.next_out = out; - ret = deflate(&strm, flush); /* no bad return value */ - assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - have = CHUNK - strm.avail_out; - - if(output_size < have+output_offset) - { - //std::cerr << "Growing outputbuffer from " << output_size << " to " << have+output_offset << std::endl; - output_mem = (uint8_t*)realloc(output_mem,have+output_offset) ; - output_size = have+output_offset ; - } - - memcpy(output_mem+output_offset,out,have) ; - output_offset += have ; - - //std::cerr << "Copying " << have << " bytes to output. New offset=" << output_offset << std::endl; - } while (strm.avail_out == 0); - assert(strm.avail_in == 0); /* all input will be used */ - - /* done when last data in file processed */ - } while (flush != Z_FINISH); - assert(ret == Z_STREAM_END); /* stream will be complete */ - - /* clean up and return */ - (void)deflateEnd(&strm); - - output_size = output_offset ; - - return true ; -} - -bool RsCompress::uncompress_memory_chunk(const uint8_t *input_mem,const uint32_t input_size,uint8_t *& output_mem,uint32_t& output_size) -{ - uint32_t remaining_input = input_size ; - output_size = input_size ; - uint32_t output_offset = 0 ; - uint32_t input_offset = 0 ; - output_mem = (uint8_t*)rs_malloc(output_size) ; - - if(!output_mem) - return false ; - - int ret; - unsigned have; - z_stream strm; - unsigned char in[CHUNK]; - unsigned char out[CHUNK]; - - /* allocate inflate state */ - memset(&strm,0,sizeof(strm)) ; - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.next_in = Z_NULL; - strm.next_out = Z_NULL; - - ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; - - /* decompress until deflate stream ends or end of file */ - do - { - uint32_t available_in = std::min(CHUNK,remaining_input) ; - memcpy(in,input_mem+input_offset,available_in) ; - strm.avail_in = available_in ; - remaining_input -= available_in ; - input_offset += available_in ; - - if (strm.avail_in == 0) - break; - - strm.next_in = in; - /* run inflate() on input until output buffer not full */ - do { - strm.avail_out = CHUNK; - strm.next_out = out; - - ret = inflate(&strm, Z_NO_FLUSH); - assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; /* and fall through */ - /* fallthrough */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return ret; - } - - - have = CHUNK - strm.avail_out; - - if(output_size < have+output_offset) - { - output_mem = (uint8_t*)realloc(output_mem,have+output_offset) ; - output_size = have+output_offset ; - } - - memcpy(output_mem+output_offset,out,have) ; - output_offset += have ; - - } while (strm.avail_out == 0); - /* done when inflate() says it's done */ - } while (ret != Z_STREAM_END); - - /* clean up and return */ - (void)inflateEnd(&strm); - - output_size = output_offset ; - return ret == Z_STREAM_END ; -} - - - - - - diff --git a/libretroshare/src/unused/rscompress.h b/libretroshare/src/unused/rscompress.h deleted file mode 100644 index 96b9e2092..000000000 --- a/libretroshare/src/unused/rscompress.h +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rscompress.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -class RsCompress -{ - public: - static bool compress_memory_chunk(const uint8_t *input_mem,const uint32_t input_size,uint8_t *& output_mem,uint32_t& output_size) ; - static bool uncompress_memory_chunk(const uint8_t *input_mem,const uint32_t input_size,uint8_t *& output_mem,uint32_t& output_size) ; -}; - diff --git a/libretroshare/src/unused/rsdsdv.h b/libretroshare/src/unused/rsdsdv.h deleted file mode 100644 index 308a1c779..000000000 --- a/libretroshare/src/unused/rsdsdv.h +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * libretroshare/src/unused: rsdsdv.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RETROSHARE_DSDV_INTERFACE_H -#define RETROSHARE_DSDV_INTERFACE_H - -#include -#include -#include - -/* The Main Interface Class - for information about your Peers */ -class RsDsdv; -extern RsDsdv *rsDsdv; - - -#define RSDSDV_IDTYPE_PEER 0x0001 -#define RSDSDV_IDTYPE_SERVICE 0x0002 -#define RSDSDV_IDTYPE_TEST 0x0100 - -#define RSDSDV_FLAGS_SIGNIFICANT_CHANGE 0x0001 -#define RSDSDV_FLAGS_STABLE_ROUTE 0x0002 -#define RSDSDV_FLAGS_NEW_ROUTE 0x0004 -#define RSDSDV_FLAGS_OWN_SERVICE 0x0008 - - -class RsDsdvId -{ - public: - - uint32_t mIdType; - std::string mAnonChunk; - std::string mHash; -}; - -class RsDsdvRoute -{ - public: - - RsPeerId mNextHop; - uint32_t mSequence; - uint32_t mDistance; - rstime_t mReceived; - rstime_t mValidSince; - -}; - -class RsDsdvTableEntry -{ - public: - - RsDsdvId mDest; - bool mIsStable; - RsDsdvRoute mStableRoute; - //RsDsdvRoute mFreshestRoute; - - std::map mAllRoutes; - - uint32_t mFlags; - - /* if we've matched it to someone */ - std::string mMatchedHash; - bool mMatched; - bool mOwnSource; -}; - -std::ostream &operator<<(std::ostream &out, const RsDsdvId &id); -std::ostream &operator<<(std::ostream &out, const RsDsdvRoute &route); -std::ostream &operator<<(std::ostream &out, const RsDsdvTableEntry &entry); - - -class RsDsdv -{ - public: - - RsDsdv() { return; } -virtual ~RsDsdv() { return; } - -virtual uint32_t getLocalServices(std::list &hashes) = 0; -virtual uint32_t getAllServices(std::list &hashes) = 0; -virtual int getDsdvEntry(const std::string &hash, RsDsdvTableEntry &entry) = 0; - -}; - -#endif - diff --git a/libretroshare/src/unused/rsdsdvitems.cc b/libretroshare/src/unused/rsdsdvitems.cc deleted file mode 100644 index 073ebe669..000000000 --- a/libretroshare/src/unused/rsdsdvitems.cc +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * libretroshare/src/unused: rsdsdvitems.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "serialiser/rsbaseserial.h" -#include "serialiser/rsdsdvitems.h" -#include "serialiser/rstlvdsdv.h" - -/*** -#define RSSERIAL_DEBUG 1 -***/ - -#include - -/*************************************************************************/ - -RsDsdvRouteItem::~RsDsdvRouteItem() -{ - return; -} - -void RsDsdvRouteItem::clear() -{ - routes.TlvClear(); -} - -std::ostream &RsDsdvRouteItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsDsdvRouteItem", indent); - uint16_t int_Indent = indent + 2; - routes.print(out, int_Indent); - - printRsItemEnd(out, "RsDsdvRouteItem", indent); - return out; -} - - -uint32_t RsDsdvSerialiser::sizeRoute(RsDsdvRouteItem *item) -{ - uint32_t s = 8; /* header */ - s += item->routes.TlvSize(); - - return s; -} - -/* serialise the data to the buffer */ -bool RsDsdvSerialiser::serialiseRoute(RsDsdvRouteItem *item, void *data, uint32_t *pktsize) -{ - uint32_t tlvsize = sizeRoute(item); - uint32_t offset = 0; - - if (*pktsize < tlvsize) - return false; /* not enough space */ - - *pktsize = tlvsize; - - 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->routes.SetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - ok = false; -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl; -#endif - } - - return ok; -} - -RsDsdvRouteItem *RsDsdvSerialiser::deserialiseRoute(void *data, uint32_t *pktsize) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t tlvsize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_DSDV != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_DSDV_ROUTE != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < tlvsize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = tlvsize; - - bool ok = true; - - /* ready to load */ - RsDsdvRouteItem *item = new RsDsdvRouteItem(); - item->clear(); - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->routes.GetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - /* error */ - delete item; - return NULL; - } - - if (!ok) - { - delete item; - return NULL; - } - - return item; -} - -/*************************************************************************/ - -RsDsdvDataItem::~RsDsdvDataItem() -{ - return; -} - -void RsDsdvDataItem::clear() -{ - src.TlvClear(); - dest.TlvClear(); - ttl = 0; - data.TlvClear(); -} - -std::ostream &RsDsdvDataItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsDsdvDataItem", indent); - uint16_t int_Indent = indent + 2; - src.print(out, int_Indent); - dest.print(out, int_Indent); - - printIndent(out, int_Indent); - out << "TTL: " << ttl << std::endl; - - data.print(out, int_Indent); - - printRsItemEnd(out, "RsDsdvDataItem", indent); - return out; -} - - -uint32_t RsDsdvSerialiser::sizeData(RsDsdvDataItem *item) -{ - uint32_t s = 8; /* header */ - s += item->src.TlvSize(); - s += item->dest.TlvSize(); - s += 4; - s += item->data.TlvSize(); - - return s; -} - -/* serialise the data to the buffer */ -bool RsDsdvSerialiser::serialiseData(RsDsdvDataItem *item, void *data, uint32_t *pktsize) -{ - uint32_t tlvsize = sizeData(item); - uint32_t offset = 0; - - if (*pktsize < tlvsize) - return false; /* not enough space */ - - *pktsize = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); - -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseData() Header: " << ok << std::endl; - std::cerr << "RsDsdvSerialiser::serialiseData() Size: " << tlvsize << std::endl; -#endif - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->src.SetTlv(data, tlvsize, &offset); - ok &= item->dest.SetTlv(data, tlvsize, &offset); - ok &= setRawUInt32(data, tlvsize, &offset, item->ttl); - ok &= item->data.SetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - ok = false; -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseData() Size Error! " << std::endl; -#endif - } - - return ok; -} - -RsDsdvDataItem *RsDsdvSerialiser::deserialiseData(void *data, uint32_t *pktsize) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t tlvsize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_DSDV != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_DSDV_DATA != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < tlvsize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = tlvsize; - - bool ok = true; - - /* ready to load */ - RsDsdvDataItem *item = new RsDsdvDataItem(); - item->clear(); - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->src.GetTlv(data, tlvsize, &offset); - ok &= item->dest.GetTlv(data, tlvsize, &offset); - ok &= getRawUInt32(data, tlvsize, &offset, &(item->ttl)); - ok &= item->data.GetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - /* error */ - delete item; - return NULL; - } - - if (!ok) - { - delete item; - return NULL; - } - - return item; -} - -/*************************************************************************/ - -uint32_t RsDsdvSerialiser::size(RsItem *i) -{ - RsDsdvRouteItem *dri; - RsDsdvDataItem *ddi; - - if (NULL != (dri = dynamic_cast(i))) - { - return sizeRoute(dri); - } - if (NULL != (ddi = dynamic_cast(i))) - { - return sizeData(ddi); - } - return 0; -} - -bool RsDsdvSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) -{ - RsDsdvRouteItem *dri; - RsDsdvDataItem *ddi; - - if (NULL != (dri = dynamic_cast(i))) - { - return serialiseRoute(dri, data, pktsize); - } - if (NULL != (ddi = dynamic_cast(i))) - { - return serialiseData(ddi, data, pktsize); - } - return false; -} - -RsItem *RsDsdvSerialiser::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_DSDV != getRsItemService(rstype))) - { - return NULL; /* wrong type */ - } - - switch(getRsItemSubType(rstype)) - { - case RS_PKT_SUBTYPE_DSDV_ROUTE: - return deserialiseRoute(data, pktsize); - break; - case RS_PKT_SUBTYPE_DSDV_DATA: - return deserialiseData(data, pktsize); - break; - default: - return NULL; - break; - } -} - -/*************************************************************************/ - - - diff --git a/libretroshare/src/unused/rsdsdvitems.h b/libretroshare/src/unused/rsdsdvitems.h deleted file mode 100644 index 856a06b92..000000000 --- a/libretroshare/src/unused/rsdsdvitems.h +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * libretroshare/src/unused: rsdsdvitems.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2011 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_DSDV_ITEMS_H -#define RS_DSDV_ITEMS_H - -#include - -#include "rsitems/rsserviceids.h" -#include "serialiser/rsserial.h" -#include "serialiser/rstlvbase.h" -#include "serialiser/rstlvbinary.h" -#include "serialiser/rstlvdsdv.h" - -/**************************************************************************/ - -#define RS_PKT_SUBTYPE_DSDV_ROUTE 0x01 -#define RS_PKT_SUBTYPE_DSDV_DATA 0x02 - -class RsDsdvRouteItem: public RsItem -{ - public: - RsDsdvRouteItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV, - RS_PKT_SUBTYPE_DSDV_ROUTE) - { - setPriorityLevel(QOS_PRIORITY_RS_DSDV_ROUTE); - return; - } -virtual ~RsDsdvRouteItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); - - RsTlvDsdvEntrySet routes; -}; - -class RsDsdvDataItem: public RsItem -{ - public: - RsDsdvDataItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV, - RS_PKT_SUBTYPE_DSDV_DATA), data(TLV_TYPE_BIN_GENERIC) - { - setPriorityLevel(QOS_PRIORITY_RS_DSDV_DATA); - return; - } -virtual ~RsDsdvDataItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); - - RsTlvDsdvEndPoint src; - RsTlvDsdvEndPoint dest; - uint32_t ttl; - RsTlvBinaryData data; -}; - -class RsDsdvSerialiser: public RsSerialType -{ - public: - RsDsdvSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DSDV) - { return; } -virtual ~RsDsdvSerialiser() - { return; } - -virtual uint32_t size(RsItem *); -virtual bool serialise (RsItem *item, void *data, uint32_t *size); -virtual RsItem * deserialise(void *data, uint32_t *size); - - private: - -virtual uint32_t sizeRoute(RsDsdvRouteItem *); -virtual bool serialiseRoute(RsDsdvRouteItem *item, void *data, uint32_t *size); -virtual RsDsdvRouteItem *deserialiseRoute(void *data, uint32_t *size); - -virtual uint32_t sizeData(RsDsdvDataItem *); -virtual bool serialiseData(RsDsdvDataItem *item, void *data, uint32_t *size); -virtual RsDsdvDataItem *deserialiseData(void *data, uint32_t *size); - - -}; - -/**************************************************************************/ - -#endif /* RS_DSDV_ITEMS_H */ - - diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri deleted file mode 100644 index b76c4a5da..000000000 --- a/libretroshare/src/use_libretroshare.pri +++ /dev/null @@ -1,115 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -RS_SRC_PATH=$$clean_path($${PWD}/../../) -RS_BUILD_PATH=$$clean_path($${OUT_PWD}/../../) - -DEPENDPATH *= $$clean_path($${RS_SRC_PATH}/libretroshare/src/) -INCLUDEPATH *= $$clean_path($${RS_SRC_PATH}/libretroshare/src) - -equals(TARGET, retroshare):equals(TEMPLATE, lib){ -} else { - LIBS *= -L$$clean_path($${RS_BUILD_PATH}/libretroshare/src/lib/) -lretroshare - win32-g++|win32-clang-g++:!isEmpty(QMAKE_SH):libretroshare_shared { - # Windows msys2 - LIBRETROSHARE_TARGET=libretroshare.dll.a - } else { - LIBRETROSHARE_TARGET=libretroshare.a - } - PRE_TARGETDEPS *= $$clean_path($${RS_BUILD_PATH}/libretroshare/src/lib/$${LIBRETROSHARE_TARGET}) -} - -!include("../../openpgpsdk/src/use_openpgpsdk.pri"):error("Including") - -bitdht { - !include("../../libbitdht/src/use_libbitdht.pri"):error("Including") -} - -# when rapidjson is mainstream on all distribs, we will not need the sources -# anymore in the meantime, they are part of the RS directory so that it is -# always possible to find them -RAPIDJSON_AVAILABLE = $$system(pkg-config --atleast-version 1.1 RapidJSON && echo yes) -isEmpty(RAPIDJSON_AVAILABLE) { - message("using rapidjson from submodule") - INCLUDEPATH *= $$clean_path($${PWD}/../../supportlibs/rapidjson/include) -} else { - message("using system rapidjson") -} - - -sLibs = -mLibs = $$RS_SQL_LIB ssl crypto $$RS_THREAD_LIB $$RS_UPNP_LIB -dLibs = - -rs_jsonapi { - no_rs_cross_compiling { - RESTBED_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/restbed) - RESTBED_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/restbed) - INCLUDEPATH *= $$clean_path($${RESTBED_BUILD_PATH}/include/) - DEPENDPATH *= $$clean_path($${RESTBED_BUILD_PATH}/include/) - QMAKE_LIBDIR *= $$clean_path($${RESTBED_BUILD_PATH}/) - # Using sLibs would fail as librestbed.a is generated at compile-time - LIBS *= -L$$clean_path($${RESTBED_BUILD_PATH}/) -lrestbed - } else:sLibs *= restbed - - win32-g++|win32-clang-g++:dLibs *= wsock32 -} - -linux-* { - mLibs += dl -} - -rs_deep_channels_index | rs_deep_files_index { - mLibs += xapian - win32-g++|win32-clang-g++:mLibs += rpcrt4 -} - -rs_deep_files_index_ogg { - mLibs += vorbisfile -} - -rs_deep_files_index_flac { - mLibs += FLAC++ -} - -rs_deep_files_index_taglib { - mLibs += tag -} - -rs_broadcast_discovery { - no_rs_cross_compiling { - UDP_DISCOVERY_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/udp-discovery-cpp/) - UDP_DISCOVERY_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/udp-discovery-cpp/) - INCLUDEPATH *= $$clean_path($${UDP_DISCOVERY_SRC_PATH}) - DEPENDPATH *= $$clean_path($${UDP_DISCOVERY_BUILD_PATH}) - QMAKE_LIBDIR *= $$clean_path($${UDP_DISCOVERY_BUILD_PATH}) - # Using sLibs would fail as libudp-discovery.a is generated at compile-time - LIBS *= -L$$clean_path($${UDP_DISCOVERY_BUILD_PATH}) -ludp-discovery - } else:sLibs *= udp-discovery - - win32-g++|win32-clang-g++:dLibs *= wsock32 -} - -static { - sLibs *= $$mLibs -} else { - dLibs *= $$mLibs -} - -LIBS += $$linkStaticLibs(sLibs) -PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) - -LIBS += $$linkDynamicLibs(dLibs) - -android-* { -## ifaddrs is missing on Android to add them don't use the one from -## https://github.com/morristech/android-ifaddrs -## because it crash, use QNetworkInterface from Qt instead - CONFIG *= qt - QT *= network -} - -################################### Pkg-Config Stuff ############################# -!isEmpty(PKGCONFIG) { - LIBS *= $$system(pkg-config --libs $$PKGCONFIG) -} diff --git a/libretroshare/src/util/androiddebug.h b/libretroshare/src/util/androiddebug.h deleted file mode 100644 index c358be553..000000000 --- a/libretroshare/src/util/androiddebug.h +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: androiddebug.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -// Inspired by: https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/ - -#include -#include -#include -#include // for O_NONBLOCK -#include -#include -#include - -/** - * On Android stdout and stderr of native code is discarded, instancing this - * class at the beginning of the main of your program to get them (stdout and - * stderr) on logcat output. - */ -class AndroidStdIOCatcher -{ -public: - AndroidStdIOCatcher(const std::string& dTag = "RetroShare", - android_LogPriority stdout_pri = ANDROID_LOG_INFO, - android_LogPriority stderr_pri = ANDROID_LOG_ERROR) : - tag(dTag), cout_pri(stdout_pri), cerr_pri(stderr_pri), should_stop(false) - { - // make stdout line-buffered - //setvbuf(stdout, 0, _IOLBF, 0); - - // make stdout and stderr unbuffered - setvbuf(stdout, 0, _IONBF, 0); - setvbuf(stderr, 0, _IONBF, 0); - - // create the pipes and redirect stdout and stderr - pipe2(pout_fd, O_NONBLOCK); - dup2(pout_fd[1], STDOUT_FILENO); - - pipe2(perr_fd, O_NONBLOCK); - dup2(perr_fd[1], STDERR_FILENO); - - // spawn the logging thread - pthread_create(&thr, 0, thread_func, this); - pthread_detach(thr); - } - - ~AndroidStdIOCatcher() - { - should_stop = true; - pthread_join(thr, NULL); - } - -private: - const std::string tag; - const android_LogPriority cout_pri; - const android_LogPriority cerr_pri; - - int pout_fd[2]; - int perr_fd[2]; - pthread_t thr; - std::atomic should_stop; - - static void *thread_func(void* instance) - { - __android_log_write(ANDROID_LOG_INFO, "RetroShare", "Android debugging start"); - - AndroidStdIOCatcher &i = *static_cast(instance); - - std::string out_buf; - std::string err_buf; - - while (!i.should_stop) - { - for(char c; read(i.pout_fd[0], &c, 1) == 1;) - { - out_buf += c; - if(c == '\n') - { - __android_log_write(i.cout_pri, i.tag.c_str(), out_buf.c_str()); - out_buf.clear(); - } - } - - for(char c; read(i.perr_fd[0], &c, 1) == 1;) - { - err_buf += c; - if(c == '\n') - { - __android_log_write(i.cerr_pri, i.tag.c_str(), err_buf.c_str()); - err_buf.clear(); - } - } - - usleep(10000); - } - - __android_log_write(ANDROID_LOG_INFO, "RetroShare", "Android debugging stop"); - - return NULL; - } -}; - diff --git a/libretroshare/src/util/argstream.h b/libretroshare/src/util/argstream.h deleted file mode 100644 index ede11ec2e..000000000 --- a/libretroshare/src/util/argstream.h +++ /dev/null @@ -1,847 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: argstream.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004 Xavier Decoret * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef ARGSTREAM_H -#define ARGSTREAM_H - - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - class argstream; - - template - class ValueHolder; - - template - argstream& operator>> (argstream&, const ValueHolder&); - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueHolder - { - public: - ValueHolder(char s, - const char* l, - T& b, - const char *valueName, - const char* desc, - bool mandatory); - ValueHolder(const char* l, - T& b, - const char *valueName, - const char* desc, - bool mandatory); - ValueHolder(char s, - T& b, - const char *valueName, - const char* desc, - bool mandatory); - friend argstream& operator>><>(argstream& s,const ValueHolder& v); - std::string name() const; - std::string description() const; - private: - std::string shortName_; - std::string longName_; - T* value_; - std::string valueName_; - T initialValue_; - std::string description_; - bool mandatory_; - }; - template - inline ValueHolder - parameter(char s, - const char* l, - T& b, - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,l,b,"value",desc,mandatory); - } - template - inline ValueHolder - parameter(char s, - const char* l, - T& b, - const char* valueName="value", - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,l,b,valueName,desc,mandatory); - } - template - inline ValueHolder - parameter(char s, - T& b, - const char* valueName="value", - const char* desc="", - bool mandatory = true) - { - return ValueHolder(s,b,valueName,desc,mandatory); - } - template - inline ValueHolder - parameter(const char* l, - T& b, - const char* valueName="value", - const char* desc="", - bool mandatory = true) - { - return ValueHolder(l,b,valueName,desc,mandatory); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of OptionHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class OptionHolder - { - public: - inline OptionHolder(char s, - const char* l, - bool& b, - const char* desc); - inline OptionHolder(const char* l, - bool& b, - const char* desc); - inline OptionHolder(char s, - bool& b, - const char* desc); - friend argstream& operator>>(argstream& s,const OptionHolder& v); - inline std::string name() const; - inline std::string description() const; - protected: - inline OptionHolder(char s, - const char* l, - const char* desc); - friend OptionHolder help(char s, - const char* l, - const char* desc); - - private: - std::string shortName_; - std::string longName_; - bool* value_; - std::string description_; - }; - inline OptionHolder - option(char s, - const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(s,l,b,desc); - } - inline OptionHolder - option(char s, - bool& b, - const char* desc="") - { - return OptionHolder(s,b,desc); - } - inline OptionHolder - option(const char* l, - bool& b, - const char* desc="") - { - return OptionHolder(l,b,desc); - } - inline OptionHolder - help(char s, - const char* l, - const char* desc) - { - return OptionHolder(s,l,desc); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValuesHolder - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValuesHolder - { - public: - ValuesHolder(const O& o, - const char* desc, - int len); - template friend argstream& operator>>(argstream& s,const ValuesHolder& v); - std::string name() const; - std::string description() const; - typedef T value_type; - private: - mutable O value_; - std::string description_; - int len_; - char letter_; - }; - template - inline ValuesHolder - values(const O& o, - const char* desc="", - int len=-1) - { - return ValuesHolder(o,desc,len); - } - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of ValueParser - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - template - class ValueParser - { - public: - inline T operator()(const std::string& s) const - { - std::istringstream is(s); - T t; - is>>t; - return t; - } - }; - // We need to specialize for string otherwise parsing of a value that - // contains space (for example a string with space passed in quotes on the - // command line) would parse only the first element of the value!!! - template <> - class ValueParser - { - public: - inline std::string operator()(const std::string& s) const - { - return s; - } - }; - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // Interface of argstream - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - class argstream - { - public: - inline argstream(int argc,char** argv); - inline argstream(const char* c); - template - friend argstream& operator>>(argstream& s,const ValueHolder& v); - friend inline argstream& operator>>(argstream& s,const OptionHolder& v); - template - friend argstream& operator>>(argstream& s,const ValuesHolder& v); - - inline bool helpRequested() const; - inline bool isOk() const; - inline std::string errorLog() const; - inline std::string usage(bool skipCommandLine = false) const; - inline bool defaultErrorHandling(bool ignoreUnused=false,bool skipCommandLine=false) const; - static inline char uniqueLetter(); - protected: - void parse(int argc,char** argv); - private: - typedef std::list::iterator value_iterator; - typedef std::pair help_entry; - std::string progName_; - std::map options_; - std::list values_; - bool minusActive_; - bool isOk_; - std::deque argHelps_; - std::string cmdLine_; - std::deque errors_; - bool helpRequested_; - }; - //************************************************************ - // Implementation of ValueHolder - //************************************************************ - template - ValueHolder::ValueHolder(char s, - const char* l, - T& v, - const char* valueName, - const char* desc, - bool mandatory) - : shortName_(1,s), - longName_(l), - value_(&v), - valueName_(valueName), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(const char* l, - T& v, - const char* valueName, - const char* desc, - bool mandatory) - : longName_(l), - value_(&v), - valueName_(valueName), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - ValueHolder::ValueHolder(char s, - T& v, - const char* valueName, - const char* desc, - bool mandatory) - : shortName_(1,s), - value_(&v), - valueName_(valueName), - initialValue_(v), - description_(desc), - mandatory_(mandatory) - { - } - template - std::string - ValueHolder::name() const - { - std::ostringstream os; - if (!shortName_.empty()) os<<'-'< - std::string - ValueHolder::description() const - { - std::ostringstream os; - os< - //************************************************************ - template - ValuesHolder::ValuesHolder(const O& o, - const char* desc, - int len) - : value_(o), - description_(desc), - len_(len) - { - letter_ = argstream::uniqueLetter(); - } - template - std::string - ValuesHolder::name() const - { - std::ostringstream os; - os< - std::string - ValuesHolder::description() const - { - return description_; - } - //************************************************************ - // Implementation of argstream - //************************************************************ - inline - argstream::argstream(int argc,char** argv) - : progName_(argv[0]), - minusActive_(true), - isOk_(true), - helpRequested_(false) - { - parse(argc,argv); - } - inline - argstream::argstream(const char* c) - : progName_(""), - minusActive_(true), - isOk_(true) - { - std::string s(c); - // Build argc, argv from s. We must add a dummy first element for - // progName because parse() expects it!! - std::deque args; - args.push_back(""); - std::istringstream is(s); - while (is.good()) - { - std::string t; - is>>t; - args.push_back(t); - } - char* pargs[args.size()]; - char** p = pargs; - for (std::deque::const_iterator - iter = args.begin(); - iter != args.end();++iter) - { - *p++ = const_cast(iter->c_str()); - } - parse(args.size(),pargs); - } - inline void - argstream::parse(int argc,char** argv) - { - // Run thru all arguments. - // * it has -- in front : it is a long name option, if remainder is empty, - // it is an error - // * it has - in front : it is a sequence of short name options, if - // remainder is empty, deactivates option (- will - // now be considered a char). - // * if any other char, or if option was deactivated - // : it is a value. Values are split in parameters - // (immediately follow an option) and pure values. - // Each time a value is parsed, if the previously parsed argument was an - // option, then the option is linked to the value in case of it is a - // option with parameter. The subtle point is that when several options - // are given with short names (ex: -abc equivalent to -a -b -c), the last - // parsed option is -c). - // Since we use map for option, any successive call overides the previous - // one: foo -a -b -a hello is equivalent to foo -b -a hello - // For values it is not true since we might have several times the same - // value. - value_iterator* lastOption = NULL; - for (char** a = argv,**astop=a+argc;++a!=astop;) - { - std::string s(*a); - if (minusActive_ && s[0] == '-') - { - if (s.size() > 1 && s[1] == '-') - { - if (s.size() == 2) - { - minusActive_ = false; - continue; - } - lastOption = &(options_[s.substr(2)] = values_.end()); - } - else - { - if (s.size() > 1) - { - // Parse all chars, if it is a minus we have an error - for (std::string::const_iterator cter = s.begin(); - ++cter != s.end();) - { - if (*cter == '-') - { - isOk_ = false; - std::ostringstream os; - os<<"- in the middle of a switch "<::const_iterator - iter = options_.begin();iter != options_.end();++iter) - { - std::cout<<"DEBUG: option "<first; - if (iter->second != values_.end()) - { - std::cout<<" -> "<<*(iter->second); - } - std::cout<::const_iterator - iter = values_.begin();iter != values_.end();++iter) - { - std::cout<<"DEBUG: value "<<*iter<::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - if (lmaxfirst.size()) lmax = iter->first.size(); - } - for (std::deque::const_iterator - iter = argHelps_.begin();iter != argHelps_.end();++iter) - { - os<<'\t'<first<first.size(),' ') - <<" : "<second<<'\n'; - } - return os.str(); - } - inline std::string - argstream::errorLog() const - { - std::string s; - for(std::deque::const_iterator iter = errors_.begin(); - iter != errors_.end();++iter) - { - s += *iter; - s += '\n'; - } - return s; - } - inline char - argstream::uniqueLetter() - { - static unsigned int c = 'a'; - return c++; - } - template - argstream& - operator>>(argstream& s,const ValueHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line, either it - // has an associated value in which case we assign it, or it has not, in - // which case we have an error. - if (iter->second != s.values_.end()) - { -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: found value "<<*(iter->second)< p; - *(v.value_) = p(*(iter->second)); - // The option and its associated value are removed, the subtle thing - // is that someother options might have this associated value too, - // which we must invalidate. - s.values_.erase(iter->second); - for (std::map::iterator - jter = s.options_.begin();jter != s.options_.end();++jter) - { - if (jter->second == iter->second) - { - jter->second = s.values_.end(); - } - } - s.options_.erase(iter); - } - else - { - s.isOk_ = false; - std::ostringstream os; - os<<"No value following switch "<first - <<" on command line"; - s.errors_.push_back(os.str()); - } - } - else - { - if (v.mandatory_) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Mandatory parameter "; - if (!v.shortName_.empty()) os<<'-'<>(argstream& s,const OptionHolder& v) - { - // Search in the options if there is any such option defined either with a - // short name or a long name. If both are found, only the last one is - // used. -#ifdef ARGSTREAM_DEBUG - std::cout<<"DEBUG: searching "<::iterator iter = - s.options_.find(v.shortName_); - if (iter == s.options_.end()) - { - iter = s.options_.find(v.longName_); - } - if (iter != s.options_.end()) - { - // If we find counterpart for value holder on command line then the - // option is true and if an associated value was found, it is ignored - if (v.value_ != NULL) - { - *(v.value_) = true; - } - else - { - s.helpRequested_ = true; - } - // The option only is removed - s.options_.erase(iter); - } - else - { - if (v.value_ != NULL) - { - *(v.value_) = false; - } - else - { - s.helpRequested_ = false; - } - } - return s; - } - template - argstream& - operator>>(argstream& s,const ValuesHolder& v) - { - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - { - std::ostringstream os; - os<<' '<::iterator first = s.values_.begin(); - // We add to the iterator as much values as we can, limited to the length - // specified (if different of -1) - int n = v.len_ != -1?v.len_:s.values_.size(); - while (first != s.values_.end() && n-->0) - { - // Read the value from the string *first - ValueParser p; - *(v.value_++) = p(*first ); - s.argHelps_.push_back(argstream::help_entry(v.name(),v.description())); - // The value we just removed was maybe "remembered" by an option so we - // remove it now. - for (std::map::iterator - jter = s.options_.begin();jter != s.options_.end();++jter) - { - if (jter->second == first) - { - jter->second = s.values_.end(); - } - } - ++first; - } - // Check if we have enough values - if (n != 0) - { - s.isOk_ = false; - std::ostringstream os; - os<<"Expecting "< * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include - -#include "contentvalue.h" - - - - -const uint8_t ContentValue::BOOL_TYPE = 1; -const uint8_t ContentValue::DATA_TYPE = 2; -const uint8_t ContentValue::STRING_TYPE = 3; -const uint8_t ContentValue::DOUBLE_TYPE = 4; -const uint8_t ContentValue::INT32_TYPE = 5; -const uint8_t ContentValue::INT64_TYPE = 6; - - -/**************** content value implementation ******************/ - -typedef std::pair KeyTypePair; - -ContentValue::ContentValue(){ - -} - -ContentValue::~ContentValue(){ - // release resources held in data - clearData(); -} - -ContentValue::ContentValue(const ContentValue &from){ - - std::map keyTypeMap; - from.getKeyTypeMap(keyTypeMap); - std::map::const_iterator cit = - keyTypeMap.begin(); - - uint8_t type = 0; - std::string currKey; - std::string val = ""; - char *src = NULL; - uint32_t data_len = 0; - - for(; cit != keyTypeMap.end(); ++cit){ - - type = cit->second; - currKey = cit->first; - - switch(type){ - - case INT32_TYPE: - { - int32_t value = 0; - if (from.getAsInt32(currKey, value)) - put(currKey, value); - break; - } - case INT64_TYPE: - { - int64_t value = 0; - if (from.getAsInt64(currKey, value)) - put(currKey, value); - break; - } - case STRING_TYPE: - { - if (from.getAsString(currKey, val)) - put(currKey, val); - break; - } - case BOOL_TYPE: - { - bool value = false; - if (from.getAsBool(currKey, value)) - put(currKey, value); - break; - } - case DATA_TYPE: - { - if (from.getAsData(currKey, data_len, src)) - put(currKey, data_len, src); - break; - } - case DOUBLE_TYPE: - { - double value = 0; - if (from.getAsDouble(currKey, value)) - put(currKey, value); - break; - } - default: - std::cerr << "ContentValue::ContentValue(ContentValue &from):" - << "Error! Unrecognised data type!" << std::endl; - break; - } - } -} - -void ContentValue::put(const std::string &key, bool value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, BOOL_TYPE)); - mKvBool.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, const std::string &value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, STRING_TYPE)); - mKvString.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, double value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE)); - mKvDouble.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, int32_t value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, INT32_TYPE)); - mKvInt32.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, int64_t value){ - - if(mKvSet.find(key) != mKvSet.end()) - removeKeyValue(key); - - mKvSet.insert(KeyTypePair(key, INT64_TYPE)); - mKvInt64.insert(std::pair(key, value)); -} - -void ContentValue::put(const std::string &key, uint32_t len, const char* value){ - - - // release memory from old key value if key - // exists - if(mKvSet.find(key) != mKvSet.end()) { - removeKeyValue(key); - } - - mKvSet.insert(KeyTypePair(key, DATA_TYPE)); - char* dest = NULL; - - // len is zero then just put a NULL entry - if(len != 0){ - dest = new char[len]; - memcpy(dest, value, len); - } - - mKvData.insert(std::pair > - (key, std::pair(len, dest))); - //delete[] dest; //Deleted by clearData() - // cppcheck-suppress memleak -} - -bool ContentValue::getAsBool(const std::string &key, bool& value) const{ - - std::map::const_iterator it; - if((it = mKvBool.find(key)) == mKvBool.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{ - - std::map::const_iterator it; - if((it = mKvInt32.find(key)) == mKvInt32.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{ - - std::map::const_iterator it; - if((it = mKvInt64.find(key)) == mKvInt64.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsString(const std::string &key, std::string &value) const{ - - std::map::const_iterator it; - if((it = mKvString.find(key)) == mKvString.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{ - - std::map >::const_iterator it; - if((it = mKvData.find(key)) == mKvData.end()) - return false; - - const std::pair &kvRef = it->second; - - len = kvRef.first; - value = kvRef.second; - return true; -} - -bool ContentValue::getAsDouble(const std::string &key, double& value) const{ - - std::map::const_iterator it; - if((it = mKvDouble.find(key)) == mKvDouble.end()) - return false; - - value = it->second; - return true; -} - -bool ContentValue::removeKeyValue(const std::string &key){ - - std::map::iterator mit; - - if((mit = mKvSet.find(key)) == mKvSet.end()) - return false; - - if(mit->second == BOOL_TYPE) - mKvBool.erase(key); - - if(mit->second == INT64_TYPE) - mKvInt64.erase(key); - - if(mit->second == DATA_TYPE){ - delete[] (mKvData[key].second); - mKvData.erase(key); - } - - if(mit->second == DOUBLE_TYPE) - mKvDouble.erase(key); - - if(mit->second == STRING_TYPE) - mKvString.erase(key); - - if(mit->second == INT32_TYPE) - mKvInt32.erase(key); - - - mKvSet.erase(key); - return true; -} - - -void ContentValue::getKeyTypeMap(std::map &keySet) const { - keySet = mKvSet; -} - -void ContentValue::clear(){ - mKvSet.clear(); - mKvBool.clear(); - mKvDouble.clear(); - mKvString.clear(); - mKvInt32.clear(); - mKvInt64.clear(); - clearData(); -} - -bool ContentValue::empty() const{ - return mKvSet.empty(); -} - -void ContentValue::clearData(){ - - std::map >::iterator - mit = mKvData.begin(); - - for(; mit != mKvData.end(); ++mit){ - - if(mit->second.first != 0) - delete[] (mit->second.second); - } - - mKvData.clear(); -} - - - diff --git a/libretroshare/src/util/contentvalue.h b/libretroshare/src/util/contentvalue.h deleted file mode 100644 index 23ee55eca..000000000 --- a/libretroshare/src/util/contentvalue.h +++ /dev/null @@ -1,187 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: contentvalue.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef CONTENTVALUE_H -#define CONTENTVALUE_H - -#include -#include -#include - -/*! - * @brief Convenience container for making additions to databases - * This class provides a means of holding column values to insert into a database - */ -class ContentValue { - -public: - - static const uint8_t INT32_TYPE; - static const uint8_t INT64_TYPE; - static const uint8_t DOUBLE_TYPE; - static const uint8_t STRING_TYPE; - static const uint8_t DATA_TYPE; - static const uint8_t BOOL_TYPE; - - ContentValue(); - - /*! - * copy constructor that copys the key value set from another \n - * ContentValue object to this one - * makes a deep copy of raw data - * @param from ContentValue instance to copy key value set from - */ - ContentValue(const ContentValue& from);//const damit die äußere klasse einen konstruktor com compielr bekommt - - /*! - * - * - * - */ - ~ContentValue(); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - * @warning cast string literals explicitly as string, observed string literal \n - * being casted to bool instead e.g. string("hello") rather than "hello" - */ - void put(const std::string& key, const std::string& value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, bool value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, int64_t value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, int32_t value); - - /*! - * Adds a value to the set - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, double value); - - /*! - * Adds a value to the set - * Takes a private copy of data - * @param key the name of the value to put - * @param value the data for the value to put - */ - void put(const std::string& key, uint32_t len, const char* value); - - - /*! - * get value as 32 bit signed integer - * @param key the value to get - */ - bool getAsInt32(const std::string& key, int32_t& value) const; - - /*! - * get value as 64 bit signed integer - * @param key the value to get - */ - bool getAsInt64(const std::string& key, int64_t& value) const; - - /*! - * get value as bool - * @param key the value to get - */ - bool getAsBool(const std::string& key, bool& value) const; - - /*! - * get as value double - * @param key the value to get - */ - bool getAsDouble(const std::string& key, double& value) const; - - /*! - * get as value as string - * @param key the value to get - * @param value the data retrieved - */ - bool getAsString(const std::string& key, std::string& value) const; - - /*! - * get as value as raw data - * @warning Deep copy of data reference should be made, if this instance ContentValue \n - * is destroyed pointer returned (value) is pointing to invalid memory - * @param key the value to get - */ - bool getAsData(const std::string&, uint32_t& len, char*& value) const; - - /*! - * @param keySet the is set with key to type pairs contained in the ContentValue instance - */ - void getKeyTypeMap(std::map& keySet) const; - - /*! - * @param key the key of the key value pair to remove - * @return true if key was found and removed, false otherwise - */ - bool removeKeyValue(const std::string& key); - - /*! - * clears this data structure of all its key value pairs held - */ - void clear(); - - /*! - * checks if internal kv map is empty - */ - bool empty() const; - -private: - - /*! - * release memory resource associated with mKvData - */ - void clearData(); - -private: - - std::map mKvInt32; - std::map mKvInt64; - std::map mKvDouble; - std::map mKvString; - std::map > mKvData; - std::map mKvBool; - - std::map mKvSet; - -}; - -#endif // CONTENTVALUE_H diff --git a/libretroshare/src/util/cxx11retrocompat.h b/libretroshare/src/util/cxx11retrocompat.h deleted file mode 100644 index f210cf87b..000000000 --- a/libretroshare/src/util/cxx11retrocompat.h +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: cxx11retrocompat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#if defined(__GNUC__) && !defined(__clang__) -# define GCC_VERSION (__GNUC__*10000+__GNUC_MINOR__*100+__GNUC_PATCHLEVEL__) -# if GCC_VERSION < 40700 -# define override -# define final -# endif // GCC version < 40700 -# if GCC_VERSION < 40600 -# define nullptr NULL -# endif // GCC_VERSION < 40600 -#endif // defined(__GNUC__) && !defined(__clang__) diff --git a/libretroshare/src/util/cxx14retrocompat.h b/libretroshare/src/util/cxx14retrocompat.h deleted file mode 100644 index e7e7d9e99..000000000 --- a/libretroshare/src/util/cxx14retrocompat.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * * - * libretroshare < C++14 retro-compatibility helpers * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#if __cplusplus < 201402L - -#include - -namespace std -{ -template using decay_t = typename decay::type; - -template -using enable_if_t = typename enable_if::type; - -template -using remove_const_t = typename remove_const::type; -} -#endif // __cplusplus < 201402L diff --git a/libretroshare/src/util/cxx17retrocompat.h b/libretroshare/src/util/cxx17retrocompat.h deleted file mode 100644 index 58cdfe84c..000000000 --- a/libretroshare/src/util/cxx17retrocompat.h +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: cxx17retrocompat.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#if __cplusplus < 201703L - -#include - -namespace std -{ -using namespace std; -template constexpr typename add_const::type& as_const(T& t) noexcept -{ return t; } -template void as_const(const T&&) = delete; -} -#endif // __cplusplus < 201703L diff --git a/libretroshare/src/util/dnsresolver.cc b/libretroshare/src/util/dnsresolver.cc deleted file mode 100644 index 3b68a052e..000000000 --- a/libretroshare/src/util/dnsresolver.cc +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: dnsresolver.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "dnsresolver.h" - -#include "pqi/pqinetwork.h" -#include "util/rsnet.h" - - -#ifndef WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "util/rstime.h" - -const rstime_t MAX_TIME_BEFORE_RETRY = 300 ; /* seconds before retrying an ip address */ -const rstime_t MAX_KEEP_DNS_ENTRY = 3600 ; /* seconds during which a DNS entry is considered valid */ - -static const std::string ADDR_AGENT = "Mozilla/5.0"; - -void *solveDNSEntries(void *p) -{ - bool more_to_go = true ; - DNSResolver *dnsr = (DNSResolver*)p ; - - while(more_to_go) - { - // get an address request - rstime_t now = time(NULL) ; - more_to_go = false ; - - std::string next_call = "" ; - - { - RsStackMutex mut(dnsr->_rdnsMtx) ; - - if(dnsr->_addr_map != NULL) - for(std::map::iterator it(dnsr->_addr_map->begin());it!=dnsr->_addr_map->end() && next_call.empty();++it) - { - switch(it->second.state) - { - case DNSResolver::DNS_SEARCHING: - case DNSResolver::DNS_HAVE: break ; - - case DNSResolver::DNS_LOOKUP_ERROR: if(it->second.last_lookup_time + MAX_TIME_BEFORE_RETRY > now) - continue ; - /* fallthrough */ //Not really, but to suppress warning. - case DNSResolver::DNS_DONT_HAVE: next_call = it->first ; - it->second.state = DNSResolver::DNS_SEARCHING ; - it->second.last_lookup_time = now ; - more_to_go = true ; - break ; - } - } - else - return NULL; // the thread has been deleted. Return. - } - - if(!next_call.empty()) - { - in_addr in ; - - bool succeed = rsGetHostByName(next_call.c_str(),in); - - { - RsStackMutex mut(dnsr->_rdnsMtx) ; - - DNSResolver::AddrInfo &info = (*dnsr->_addr_map)[next_call]; - - 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_LOOKUP_ERROR ; - - std::cerr << "DNSResolver: lookup error for address \"" << next_call.c_str() << "\"" << std::endl; - } - } - } - } - - { - RsStackMutex mut(dnsr->_rdnsMtx) ; - *(dnsr->_thread_running) = false ; - } - return NULL ; -} - -void DNSResolver::start_request() -{ - { - RsStackMutex mut(_rdnsMtx) ; - *_thread_running = true ; - } - - 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() -{ - RsStackMutex mut(_rdnsMtx) ; - - *_thread_running = false ; - _addr_map->clear(); -} - -bool DNSResolver::getIPAddressFromString(const std::string& server_name,struct sockaddr_storage &addr) -{ - sockaddr_storage_clear(addr); - bool running = false; - { - RsStackMutex mut(_rdnsMtx) ; - - std::map::iterator it(_addr_map->find(server_name)) ; - rstime_t now = time(NULL) ; - AddrInfo *addr_info ; - - if(it != _addr_map->end()) - { - // check that the address record is not too old - - if(it->second.last_lookup_time + MAX_KEEP_DNS_ENTRY > now && it->second.state == DNSResolver::DNS_HAVE) - { - addr = it->second.addr ; - return true ; - } - else - addr_info = &it->second ; - } - else - addr_info = &(*_addr_map)[server_name] ; - - // We don't have it. Let's push it into the names to lookup for, except if we're already into it. - - if(addr_info->state != DNSResolver::DNS_SEARCHING) - addr_info->state = DNSResolver::DNS_DONT_HAVE ; - - running = *_thread_running ; - } - - if(!running) - start_request(); - - return false ; -} - -DNSResolver::~DNSResolver() -{ - RsStackMutex mut(_rdnsMtx) ; - - delete _addr_map ; - _addr_map = NULL ; - delete _thread_running ; -} - -DNSResolver::DNSResolver() : _rdnsMtx("DNSResolver") -{ - RsStackMutex mut(_rdnsMtx) ; - - _addr_map = new std::map() ; - _thread_running = new bool ; - *_thread_running = false ; -} - diff --git a/libretroshare/src/util/dnsresolver.h b/libretroshare/src/util/dnsresolver.h deleted file mode 100644 index 042654f4e..000000000 --- a/libretroshare/src/util/dnsresolver.h +++ /dev/null @@ -1,63 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: dnsresolver.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "pqi/pqinetwork.h" - -#ifndef WIN32 -#include -#endif - -#include -#include - -#include "util/rsthreads.h" -#include "util/rstime.h" - -struct sockaddr ; - -class DNSResolver -{ - public: - DNSResolver() ; - ~DNSResolver() ; - - bool getIPAddressFromString(const std::string& server_name,struct sockaddr_storage &addr) ; - - void start_request() ; - void reset() ; - - private: - enum { DNS_DONT_HAVE,DNS_SEARCHING, DNS_HAVE, DNS_LOOKUP_ERROR } ; - - struct AddrInfo - { - uint32_t state ; // state: Looked-up, not found, have - rstime_t last_lookup_time ; // last lookup time - struct sockaddr_storage addr ; - }; - friend void *solveDNSEntries(void *p) ; - - RsMutex _rdnsMtx ; - bool *_thread_running ; - std::map *_addr_map ; -}; diff --git a/libretroshare/src/util/exampletst.c b/libretroshare/src/util/exampletst.c deleted file mode 100644 index e96cd037e..000000000 --- a/libretroshare/src/util/exampletst.c +++ /dev/null @@ -1,40 +0,0 @@ - -#include "utest.h" - -#include - -/* must define the global variables */ -INITTEST(); - -int main(int argc, char **argv) -{ - int a = 2; - int b = 3; - int c = 2; - - CHECK( a == c ); - - REPORT( "Initial Tests"); - - CHECK( (0 == strcmp("123", "123")) ); - - REPORT( "Successful Tests"); - - CHECK( a == b ); - CHECK( (0 == strcmp("123", "12345")) ); - - REPORT( "Failed Tests" ); - - CHECK( 1 ); - CHECK( a == c ); - - REPORT( "Later Successful Tests"); - - - FINALREPORT( "Example Tests" ); - - return TESTRESULT(); -} - - - diff --git a/libretroshare/src/util/extaddrfinder.cc b/libretroshare/src/util/extaddrfinder.cc deleted file mode 100644 index b214dc779..000000000 --- a/libretroshare/src/util/extaddrfinder.cc +++ /dev/null @@ -1,323 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: extaddrfinder.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "extaddrfinder.h" - -#include "pqi/pqinetwork.h" -#include "util/rsstring.h" -#include "util/rsmemory.h" - -#ifndef WIN32 -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "util/rstime.h" - -const uint32_t MAX_IP_STORE = 300; /* seconds ip address timeout */ - -//#define EXTADDRSEARCH_DEBUG - -static const std::string ADDR_AGENT = "Mozilla/5.0"; - -static std::string scan_ip(const std::string& text) -{ - std::set digits ; - digits.insert('0') ; digits.insert('3') ; digits.insert('6') ; - digits.insert('1') ; digits.insert('4') ; digits.insert('7') ; - digits.insert('2') ; digits.insert('5') ; digits.insert('8') ; - digits.insert('9') ; - - for(int i=0;i<(int)text.size();++i) - { - while(i < (int)text.size() && digits.find(text[i])==digits.end()) ++i ; - - if(i>=(int)text.size()) - return "" ; - - unsigned int a,b,c,d ; - - if(sscanf(text.c_str()+i,"%u.%u.%u.%u",&a,&b,&c,&d) != 4) - continue ; - - if(a < 256 && b<256 && c<256 && d<256) - { - std::string s ; - rs_sprintf(s, "%u.%u.%u.%u", a, b, c, d) ; - return s; - } - } - return "" ; -} - -static void getPage(const std::string& server_name,std::string& page) -{ - page = "" ; - int sockfd,n=0; // socket descriptor - struct sockaddr_in serveur; // server's parameters - memset(&serveur.sin_zero, 0, sizeof(serveur.sin_zero)); - - char buf[1024]; - char request[1024]; -#ifdef EXTADDRSEARCH_DEBUG - std::cout << "ExtAddrFinder: connecting to " << server_name << std::endl ; -#endif - // socket creation - - sockfd = unix_socket(PF_INET,SOCK_STREAM,0); - if (sockfd < 0) - { - std::cerr << "ExtAddrFinder: Failed to create socket" << std::endl; - return ; - } - - serveur.sin_family = AF_INET; - - // get server's ipv4 adress - - 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 = 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; - - sockaddr_storage server; - sockaddr_storage_setipv4(server, &serveur); - sockaddr_storage_setport(server, 80); - if(unix_connect(sockfd, server) == -1) - { - std::cerr << "ExtAddrFinder: Connection error to " << server_name << std::endl ; - unix_close(sockfd); - return ; - } -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Connection established to " << server_name << std::endl ; -#endif - - // envoi - 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) > 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) - { - std::cerr << "ExtAddrFinder: Could not send request to " << server_name << std::endl ; - unix_close(sockfd); - return ; - } - // recéption - - while((n = recv(sockfd, buf, sizeof buf - 1, 0)) > 0) - { - buf[n] = '\0'; - page += std::string(buf,n) ; - } - // fermeture de la socket - - unix_close(sockfd); -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Got full page from " << server_name << std::endl ; -#endif -} - - -void* doExtAddrSearch(void *p) -{ - - std::vector res ; - - ExtAddrFinder *af = (ExtAddrFinder*)p ; - - for(std::list::const_iterator it(af->_ip_servers.begin());it!=af->_ip_servers.end();++it) - { - std::string page ; - - getPage(*it,page) ; - std::string ip = scan_ip(page) ; - - if(ip != "") - res.push_back(ip) ; -#ifdef EXTADDRSEARCH_DEBUG - std::cout << "ip found through " << *it << ": \"" << ip << "\"" << std::endl ; -#endif - } - - if(res.empty()) - { - // thread safe copy results. - // - { - RsStackMutex mtx(af->mAddrMtx) ; - - af->mFound = false ; - af->mFoundTS = time(NULL) ; - af->mSearching = false ; - } - return NULL ; - } - - sort(res.begin(),res.end()) ; // eliminates outliers. - - - - if(!sockaddr_storage_ipv4_aton(af->mAddr, res[res.size()/2].c_str())) - { - std::cerr << "ExtAddrFinder: Could not convert " << res[res.size()/2] << " into an address." << std::endl ; - { - RsStackMutex mtx(af->mAddrMtx) ; - af->mFound = false ; - af->mFoundTS = time(NULL) ; - af->mSearching = false ; - } - return NULL ; - } - - { - RsStackMutex mtx(af->mAddrMtx) ; - af->mFound = true ; - af->mFoundTS = time(NULL) ; - af->mSearching = false ; - } - - return NULL ; -} - - -void ExtAddrFinder::start_request() -{ - void *data = (void *)this; - pthread_t tid ; - - 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) -{ -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Getting ip." << std::endl ; -#endif - - { - RsStackMutex mut(mAddrMtx) ; - if(mFound) - { -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Has stored ip: responding with this ip." << std::endl ; -#endif - sockaddr_storage_copyip(addr,mAddr); // just copy the IP so we dont erase the port. - } - } - rstime_t delta; - { - RsStackMutex mut(mAddrMtx) ; - //timeout the current ip - delta = time(NULL) - mFoundTS; - } - if((uint32_t)delta > MAX_IP_STORE) {//launch a research - if( mAddrMtx.trylock()) - { - if(!mSearching) - { -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: No stored ip: Initiating new search." << std::endl ; -#endif - mSearching = true ; - start_request() ; - } -#ifdef EXTADDRSEARCH_DEBUG - else - std::cerr << "ExtAddrFinder: Already searching." << std::endl ; -#endif - mAddrMtx.unlock(); - } -#ifdef EXTADDRSEARCH_DEBUG - else - std::cerr << "ExtAddrFinder: (Note) Could not acquire lock. Busy." << std::endl ; -#endif - } - - RsStackMutex mut(mAddrMtx) ; - return mFound ; -} - -void ExtAddrFinder::reset() -{ - RsStackMutex mut(mAddrMtx) ; - - mFound = false ; - mSearching = false ; - mFoundTS = time(NULL) - MAX_IP_STORE; -} - -ExtAddrFinder::~ExtAddrFinder() -{ -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Deleting ExtAddrFinder." << std::endl ; -#endif - -} - -ExtAddrFinder::ExtAddrFinder() : mAddrMtx("ExtAddrFinder") -{ -#ifdef EXTADDRSEARCH_DEBUG - std::cerr << "ExtAddrFinder: Creating new ExtAddrFinder." << std::endl ; -#endif - RsStackMutex mut(mAddrMtx) ; - - mFound = false; - mSearching = false; - mFoundTS = time(NULL) - MAX_IP_STORE; - sockaddr_storage_clear(mAddr); - - _ip_servers.push_back(std::string( "checkip.dyndns.org" )) ; - _ip_servers.push_back(std::string( "www.myip.dk" )) ; - _ip_servers.push_back(std::string( "showip.net" )) ; - _ip_servers.push_back(std::string( "www.displaymyip.com")) ; -} - diff --git a/libretroshare/src/util/extaddrfinder.h b/libretroshare/src/util/extaddrfinder.h deleted file mode 100644 index 22a9a5689..000000000 --- a/libretroshare/src/util/extaddrfinder.h +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: extaddrfinder.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include "util/rsthreads.h" -#include "util/rsnet.h" -#include "util/rstime.h" - -struct sockaddr ; - -class ExtAddrFinder -{ - public: - ExtAddrFinder() ; - ~ExtAddrFinder() ; - - bool hasValidIP(struct sockaddr_storage &addr) ; - void getIPServersList(std::list& ip_servers) { ip_servers = _ip_servers ; } - - void start_request() ; - - void reset() ; - - private: - friend void* doExtAddrSearch(void *p) ; - - RsMutex mAddrMtx ; - rstime_t mFoundTS; - struct sockaddr_storage mAddr; - bool mFound ; - bool mSearching ; - std::list _ip_servers ; -}; diff --git a/libretroshare/src/util/folderiterator.cc b/libretroshare/src/util/folderiterator.cc deleted file mode 100644 index c67204fc6..000000000 --- a/libretroshare/src/util/folderiterator.cc +++ /dev/null @@ -1,257 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: folderiterator.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include -#include -#include "util/rstime.h" - -#ifdef WINDOWS_SYS -#include "util/rswin.h" -#endif - -#include "folderiterator.h" -#include "rsstring.h" - -//#define DEBUG_FOLDER_ITERATOR 1 - -namespace librs { namespace util { - - -FolderIterator::FolderIterator(const std::string& folderName, bool allow_symlinks, bool allow_files_from_the_future) - : mFolderName(folderName),mAllowSymLinks(allow_symlinks),mAllowFilesFromTheFuture(allow_files_from_the_future) -{ - is_open = false ; - validity = false ; - mFileModTime = 0; - mFolderModTime = 0; - mFileSize = 0; - mType = TYPE_UNKNOWN; - - // Grab the last modification time for the directory - - struct stat64 buf ; - -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(folderName, wfullname); - if ( 0 == _wstati64(wfullname.c_str(), &buf)) -#else - if ( 0 == stat64(folderName.c_str(), &buf)) -#endif - { - mFolderModTime = buf.st_mtime ; - } - - // Now open directory content and read the first entry - -#ifdef WINDOWS_SYS - std::wstring utf16Name; - if(! ConvertUtf8ToUtf16(folderName, utf16Name)) { - validity = false; - return; - } - - utf16Name += L"/*.*"; - - // FindFirstFileW does the "next" operation, so after calling it, we need to read the information - // for the current entry. - - handle = FindFirstFileW(utf16Name.c_str(), &fileInfo); - is_open = validity = handle != INVALID_HANDLE_VALUE; - - bool should_skip ; - validity = validity && updateFileInfo(should_skip); - - if(validity && should_skip) - next(); -#else - // On linux, we need to call "next()" once the dir is openned. next() will call updateFileInfo() itself. - - handle = opendir(folderName.c_str()); - is_open = validity = handle != NULL; - next(); -#endif -} - -FolderIterator::~FolderIterator() -{ - closedir(); -} - -void FolderIterator::next() -{ - bool should_skip = false ; - - while(readdir()) - if(updateFileInfo(should_skip) && !should_skip) - return ; - - #ifdef DEBUG_FOLDER_ITERATOR - std::cerr << "End of directory." << std::endl; -#endif - - mType = TYPE_UNKNOWN ; - mFileSize = 0 ; - mFileModTime = 0; - validity = false ; -} - -bool FolderIterator::updateFileInfo(bool& should_skip) -{ - should_skip = false; -#ifdef WINDOWS_SYS - ConvertUtf16ToUtf8(fileInfo.cFileName, mFileName) ; -#else - mFileName = ent->d_name ; -#endif - - if(mFileName == "." || mFileName == "..") - { - should_skip = true ; - return true ; - } - - mFullPath = mFolderName + "/" + mFileName ; - -#warning cyril soler: should we take care of symbolic links on windows? -#ifndef WINDOWS_SYS - if( ent->d_type == DT_LNK) - { - if(!mAllowSymLinks) - { - std::cerr << "(II) Skipping symbolic link " << mFullPath << std::endl; - should_skip = true ; - return true ; - } - } - else if( ent->d_type != DT_DIR && ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN) // DT_UNKNOWN is reported by mounted dirs, by services such as sshfs. - { - std::cerr << "(II) Skipping file of unknown type " << std::dec << (int)ent->d_type << std::dec << ": " << mFullPath << std::endl; - should_skip = true ; - return true ; - } -#endif - - struct stat64 buf ; - -#ifdef DEBUG_FOLDER_ITERATOR - std::cerr << "FolderIterator: next. Looking into file " << mFileName ; -#endif - -#ifdef WINDOWS_SYS - std::wstring wfullname; - librs::util::ConvertUtf8ToUtf16(mFullPath, wfullname); - if ( 0 == _wstati64(wfullname.c_str(), &buf)) -#else - if ( 0 == stat64(mFullPath.c_str(), &buf)) -#endif - { - mFileModTime = buf.st_mtime ; - - if(buf.st_mtime > time(NULL) && !mAllowFilesFromTheFuture) - { - std::cerr << "(II) skipping file with modification time in the future: " << mFullPath << std::endl; - should_skip = true ; - return true ; - } - - if (S_ISDIR(buf.st_mode)) - { -#ifdef DEBUG_FOLDER_ITERATOR - std::cerr << ": is a directory" << std::endl; -#endif - - mType = TYPE_DIR ; - mFileSize = 0 ; - mFileModTime = buf.st_mtime; - - return true; - } - - if (S_ISREG(buf.st_mode)) - { -#ifdef DEBUG_FOLDER_ITERATOR - std::cerr << ": is a file" << std::endl; -#endif - - mType = TYPE_FILE ; - mFileSize = buf.st_size; - mFileModTime = buf.st_mtime; - - return true; - } - } - -#ifdef DEBUG_FOLDER_ITERATOR - std::cerr << ": is unknown skipping" << std::endl; -#endif - - mType = TYPE_UNKNOWN ; - mFileSize = 0 ; - mFileModTime = 0; - - return false; -} - -bool FolderIterator::readdir() -{ - if(!validity) - return false; - -#ifdef WINDOWS_SYS - return FindNextFileW(handle, &fileInfo) != 0; -#else - ent = ::readdir(handle); - return ent != NULL; -#endif -} - -rstime_t FolderIterator::dir_modtime() const { return mFolderModTime ; } - -const std::string& FolderIterator::file_fullpath() { return mFullPath ; } -const std::string& FolderIterator::file_name() { return mFileName ; } -uint64_t FolderIterator::file_size() { return mFileSize ; } -rstime_t FolderIterator::file_modtime() { return mFileModTime ; } -uint8_t FolderIterator::file_type() { return mType ; } - -bool FolderIterator::closedir() -{ - validity = false; - - if(!is_open) - return true ; - - is_open = false ; - -#ifdef WINDOWS_SYS - return FindClose(handle) != 0; -#else - return ::closedir(handle) == 0; -#endif -} - - - - -} } // librs::util diff --git a/libretroshare/src/util/folderiterator.h b/libretroshare/src/util/folderiterator.h deleted file mode 100644 index 19cbb8e9c..000000000 --- a/libretroshare/src/util/folderiterator.h +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: folderiterator.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2017 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef FOLDERITERATOR_H -#define FOLDERITERATOR_H - - -#include -#include -#include - -#ifdef WINDOWS_SYS - #include - #include - #include - #include -#else - #include -#endif - -#include "util/rstime.h" - -namespace librs { namespace util { - - -class FolderIterator -{ -public: - FolderIterator(const std::string& folderName,bool allow_symlinks,bool allow_files_from_the_future = true); - ~FolderIterator(); - - enum { TYPE_UNKNOWN = 0x00, - TYPE_FILE = 0x01, - TYPE_DIR = 0x02 - }; - - // info about current parent directory - rstime_t dir_modtime() const ; - - // info about directory content - - bool isValid() const { return validity; } - bool readdir(); - void next(); - - bool closedir(); - - const std::string& file_name() ; - const std::string& file_fullpath() ; - uint64_t file_size() ; - uint8_t file_type() ; - rstime_t file_modtime() ; - -private: - bool is_open; - bool validity; - -#ifdef WINDOWS_SYS - HANDLE handle; - bool isFirstCall; - _WIN32_FIND_DATAW fileInfo; -#else - DIR* handle; - struct dirent* ent; -#endif - bool updateFileInfo(bool &should_skip) ; - - rstime_t mFileModTime ; - rstime_t mFolderModTime ; - uint64_t mFileSize ; - uint8_t mType ; - std::string mFileName ; - std::string mFullPath ; - std::string mFolderName ; - bool mAllowSymLinks; - bool mAllowFilesFromTheFuture; -}; - - -} } // librs::util - - -#endif // FOLDERITERATOR_H diff --git a/libretroshare/src/util/i2pcommon.cpp b/libretroshare/src/util/i2pcommon.cpp deleted file mode 100644 index ec2ebfd6b..000000000 --- a/libretroshare/src/util/i2pcommon.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include "i2pcommon.h" - -#include "util/rsbase64.h" -#include "util/rsdebug.h" - -namespace i2p { - -std::string keyToBase32Addr(const std::string &key) -{ - std::string copy(key); - - // replace I2P specific chars - std::replace(copy.begin(), copy.end(), '~', '/'); - // replacing the - with a + is not necessary, as RsBase64 can handle base64url encoding, too - // std::replace(copy.begin(), copy.end(), '-', '+'); - - // decode - std::vector bin; - RsBase64::decode(copy, bin); - - // hash - std::vector sha256 = RsUtil::BinToSha256(bin); - // encode - std::string out = Radix32::encode(sha256); - - // i2p uses lowercase - std::transform(out.begin(), out.end(), out.begin(), ::tolower); - out.append(".b32.i2p"); - - return out; -} - -const std::string makeOption(const std::string &lhs, const int8_t &rhs) { - return lhs + "=" + std::to_string(rhs); -} - -uint16_t readTwoBytesBE(std::vector::const_iterator &p) -{ - uint16_t val = 0; - val += *p++; - val <<= 8; - val += *p++; - return val; -} - -std::string publicKeyFromPrivate(std::string const &priv) -{ - /* - * https://geti2p.net/spec/common-structures#destination - * https://geti2p.net/spec/common-structures#keysandcert - * https://geti2p.net/spec/common-structures#certificate - */ - if (priv.length() < 884) // base64 ( = 663 bytes = KeyCert + priv Keys) - return std::string(); - - // creat a copy to work on, need to convert it to standard base64 - auto priv_copy(priv); - std::replace(priv_copy.begin(), priv_copy.end(), '~', '/'); - // replacing the - with a + is not necessary, as RsBase64 can handle base64url encoding, too - // std::replace(copy.begin(), copy.end(), '-', '+'); - - // get raw data - std::vector dataPriv; - RsBase64::decode(priv_copy, dataPriv); - - auto p = dataPriv.cbegin(); - RS_DBG("dataPriv.size ", dataPriv.size()); - - size_t publicKeyLen = 256 + 128; // default length (bytes) - uint8_t certType = 0; - uint16_t len = 0; - uint16_t signingKeyType = 0; - uint16_t cryptKey = 0; - - // only used for easy break - do { - try { - // jump to certificate - p += publicKeyLen; - // try to read type and length - certType = *p++; - len = readTwoBytesBE(p); - - // only 0 and 5 are used / valid at this point - // check for == 0 - if (certType == static_cast::type>(CertType::Null)) { - /* - * CertType.Null - * type null is followed by 0x00 0x00 - * so has to be 0! - */ - RS_DBG("cert is CertType.Null"); - publicKeyLen += 3; // add 0x00 0x00 0x00 - - if (len != 0) - // weird - RS_DBG("cert is CertType.Null but len != 0"); - - break; - } - - // check for != 5 - if (certType != static_cast::type>(CertType::Key)) { - // unsupported - RS_DBG("cert type ", certType, " is unsupported"); - return std::string(); - } - - RS_DBG("cert is CertType.Key"); - publicKeyLen += 7; // = 1 + 2 + 2 + 2 = 7 bytes - - /* - * "Key certificates were introduced in release 0.9.12. Prior to that release, all PublicKeys were 256-byte ElGamal keys, and all SigningPublicKeys were 128-byte DSA-SHA1 keys." - * --> there is space for 256+128 bytes, longer keys are splitted and appended to the certificate - * We don't need to bother with the splitting here as only the lenght is important! - */ - - // Signing Public Key - // likely 7 - signingKeyType = readTwoBytesBE(p); - - RS_DBG("signing pubkey type ", certType); - if (signingKeyType >= 3 && signingKeyType <= 6) { - RS_DBG("signing pubkey type ", certType, " has oversize"); - // calculate oversize - - if (signingKeyType >= signingKeyLengths.size()) { - // just in case - RS_DBG("signing pubkey type ", certType, " cannot be found in size data!"); - return std::string(); - } - - auto values = signingKeyLengths[signingKeyType]; - if (values.first <= 128) { - // just in case, it's supposed to be larger! - RS_DBG("signing pubkey type ", certType, " is oversize but size calculation would underflow!"); - return std::string(); - } - - publicKeyLen += values.first - 128; // 128 = default DSA key length = the space than can be used before the key must be splitted - } - - // Crypto Public Key - // likely 0 - cryptKey = readTwoBytesBE(p); - RS_DBG("crypto pubkey type ", cryptKey); - // info: these are all smaller than the default 256 bytes, so no oversize calculation is needed - - break; - } catch (const std::out_of_range &e) { - RS_DBG("hit exception! ", e.what()); - return std::string(); - } - } while(false); - - std::string pub; - auto data2 = std::vector(dataPriv.cbegin(), dataPriv.cbegin() + publicKeyLen); - RsBase64::encode(data2.data(), data2.size(), pub, false, false); - - return pub; -} - -} // namespace i2p diff --git a/libretroshare/src/util/i2pcommon.h b/libretroshare/src/util/i2pcommon.h deleted file mode 100644 index 1fd152079..000000000 --- a/libretroshare/src/util/i2pcommon.h +++ /dev/null @@ -1,213 +0,0 @@ -#ifndef I2PCOMMON_H -#define I2PCOMMON_H - -#include -#include -#include -#include - -#include "util/rsrandom.h" -#include "util/radix32.h" -#include "util/rsbase64.h" -#include "util/rsprint.h" -#include "util/rsdebug.h" - -/* - * This header provides common code for i2p related code, namely BOB and SAM3 support. - */ - -namespace i2p { - -static constexpr int8_t kDefaultLength = 3; // i2p default -static constexpr int8_t kDefaultQuantity = 3; // i2p default + 1 -static constexpr int8_t kDefaultVariance = 0; -static constexpr int8_t kDefaultBackupQuantity = 0; - -/** - * @brief The address struct - * This structure is a container for any i2p address/key. The public key is used for addressing and can be (optionally) hashed to generate the .b32.i2p address. - */ -struct address { - std::string base32; - std::string publicKey; - std::string privateKey; - - void clear() { - base32.clear(); - publicKey.clear(); - privateKey.clear(); - } -}; - -/** - * @brief The settings struct - * Common structure with all settings that are shared between any i2p backends - */ -struct settings { - bool enable; - struct address address; - - // connection parameter - int8_t inLength; - int8_t inQuantity; - int8_t inVariance; - int8_t inBackupQuantity; - - int8_t outLength; - int8_t outQuantity; - int8_t outVariance; - int8_t outBackupQuantity; - - void initDefault() { - enable = false; - address.clear(); - - inLength = kDefaultLength; - inQuantity = kDefaultQuantity; - inVariance = kDefaultVariance; - inBackupQuantity = kDefaultBackupQuantity; - - outLength = kDefaultLength; - outQuantity = kDefaultQuantity; - outVariance = kDefaultVariance; - outBackupQuantity = kDefaultBackupQuantity; - } -}; - -/* - Type Type Code Payload Length Total Length Notes - Null 0 0 3 - HashCash 1 varies varies Experimental, unused. Payload contains an ASCII colon-separated hashcash string. - Hidden 2 0 3 Experimental, unused. Hidden routers generally do not announce that they are hidden. - Signed 3 40 or 72 43 or 75 Experimental, unused. Payload contains a 40-byte DSA signature, optionally followed by the 32-byte Hash of the signing Destination. - Multiple 4 varies varies Experimental, unused. Payload contains multiple certificates. - Key 5 4+ 7+ Since 0.9.12. See below for details. -*/ -enum class CertType : uint8_t { - Null = 0, - HashCash = 1, - Hidden = 2, - Signed = 3, - Multiple = 4, - Key = 5 -}; - -/* - * public - Type Type Code Total Public Key Length Since Usage - DSA_SHA1 0 128 0.9.12 Legacy Router Identities and Destinations, never explicitly set - ECDSA_SHA256_P256 1 64 0.9.12 Older Destinations - ECDSA_SHA384_P384 2 96 0.9.12 Rarely if ever used for Destinations - ECDSA_SHA512_P521 3 132 0.9.12 Rarely if ever used for Destinations - RSA_SHA256_2048 4 256 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations - RSA_SHA384_3072 5 384 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations - RSA_SHA512_4096 6 512 0.9.12 Offline only; never used in Key Certificates for Router Identities or Destinations - EdDSA_SHA512_Ed25519 7 32 0.9.15 Recent Router Identities and Destinations - EdDSA_SHA512_Ed25519ph 8 32 0.9.25 Offline only; never used in Key Certificates for Router Identities or Destinations - reserved (GOST) 9 64 Reserved, see proposal 134 - reserved (GOST) 10 128 Reserved, see proposal 134 - RedDSA_SHA512_Ed25519 11 32 0.9.39 For Destinations and encrypted leasesets only; never used for Router Identities - reserved 65280-65534 Reserved for experimental use - reserved 65535 Reserved for future expansion - - * private - Type Length (bytes) Since Usage - DSA_SHA1 20 Legacy Router Identities and Destinations - ECDSA_SHA256_P256 32 0.9.12 Recent Destinations - ECDSA_SHA384_P384 48 0.9.12 Rarely used for Destinations - ECDSA_SHA512_P521 66 0.9.12 Rarely used for Destinations - RSA_SHA256_2048 512 0.9.12 Offline signing, never used for Router Identities or Destinations - RSA_SHA384_3072 768 0.9.12 Offline signing, never used for Router Identities or Destinations - RSA_SHA512_4096 1024 0.9.12 Offline signing, never used for Router Identities or Destinations - EdDSA_SHA512_Ed25519 32 0.9.15 Recent Router Identities and Destinations - EdDSA_SHA512_Ed25519ph 32 0.9.25 Offline signing, never used for Router Identities or Destinations - RedDSA_SHA512_Ed25519 32 0.9.39 For Destinations and encrypted leasesets only, never used for Router Identities - */ -enum class SigningKeyType : uint16_t { - DSA_SHA1 = 0, - ECDSA_SHA256_P256 = 1, - ECDSA_SHA384_P384 = 2, - ECDSA_SHA512_P521 = 3, - RSA_SHA256_2048 = 4, - RSA_SHA384_3072 = 5, - RSA_SHA512_4096 = 6, - EdDSA_SHA512_Ed25519 = 7, - EdDSA_SHA512_Ed25519ph = 8, - RedDSA_SHA512_Ed25519 = 11 -}; - -/* - * public - Type Type Code Total Public Key Length Usage - ElGamal 0 256 All Router Identities and Destinations - P256 1 64 Reserved, see proposal 145 - P384 2 96 Reserved, see proposal 145 - P521 3 132 Reserved, see proposal 145 - X25519 4 32 Not for use in key certs. See proposal 144 - reserved 65280-65534 Reserved for experimental use - reserved 65535 Reserved for future expansion - - * private - Type Length (bytes) Since Usage - ElGamal 256 All Router Identities and Destinations - P256 32 TBD Reserved, see proposal 145 - P384 48 TBD Reserved, see proposal 145 - P521 66 TBD Reserved, see proposal 145 - X25519 32 0.9.38 Little-endian. See proposal 144 -*/ -enum class CryptoKeyType : uint16_t { - ElGamal = 0, - P256 = 1, - P384 = 2, - P521 = 3, - X25519 = 4 -}; - -static const std::array, 5> cryptoKeyLengths { - /*CryptoKeyType::ElGamal*/ std::make_pair(256, 256), - /*CryptoKeyType::P256, */ std::make_pair( 64, 32), - /*CryptoKeyType::P384, */ std::make_pair( 96, 48), - /*CryptoKeyType::P521, */ std::make_pair(132, 66), - /*CryptoKeyType::X25519,*/ std::make_pair( 32, 32), -}; - -static const std::array, 12> signingKeyLengths { - /*SigningKeyType::DSA_SHA1, */ std::make_pair(128, 128), - /*SigningKeyType::ECDSA_SHA256_P256, */ std::make_pair( 64, 32), - /*SigningKeyType::ECDSA_SHA384_P384, */ std::make_pair( 96, 48), - /*SigningKeyType::ECDSA_SHA512_P521, */ std::make_pair(132, 66), - /*SigningKeyType::RSA_SHA256_2048, */ std::make_pair(256, 512), - /*SigningKeyType::RSA_SHA384_3072, */ std::make_pair(384, 768), - /*SigningKeyType::RSA_SHA512_4096, */ std::make_pair(512,1024), - /*SigningKeyType::EdDSA_SHA512_Ed25519 */ std::make_pair( 32, 32), - /*SigningKeyType::EdDSA_SHA512_Ed25519ph */ std::make_pair( 32, 32), - /*reserved (GOST) */ std::make_pair( 64, 0), - /*reserved (GOST) */ std::make_pair(128, 0), - /*SigningKeyType::RedDSA_SHA512_Ed25519 */ std::make_pair( 32, 32), -}; - -/** - * @brief makeOption Creates the string "lhs=rhs" used by BOB and SAM. Converts rhs - * @param lhs option to set - * @param rhs value to set - * @return concatenated string - */ -const std::string makeOption(const std::string &lhs, const int8_t &rhs); - -/** - * @brief keyToBase32Addr generated a base32 address (.b32.i2p) from a given public key - * @param key public key - * @return generated base32 address - */ -std::string keyToBase32Addr(const std::string &key); - -/** - * @brief publicKeyFromPrivate parses the private key and calculates the lenght of the public key - * @param priv private key (which includes the public key) to read - * @return public key used for addressing - */ -std::string publicKeyFromPrivate(const std::string &priv); - -} // namespace i2p - -#endif // I2PCOMMON_H diff --git a/libretroshare/src/util/radix32.h b/libretroshare/src/util/radix32.h deleted file mode 100644 index 46219da17..000000000 --- a/libretroshare/src/util/radix32.h +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: radix32.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RADIX32_H -#define RADIX32_H - -#include -#include -#include -#include - -class Radix32 -{ -public: - static std::string encode(const std::vector &in) { - return encode(in.data(), in.size()); - } - - static std::string encode(const uint8_t *data, size_t len) { - std::string out = ""; - - size_t pos = 1; - uint8_t bits = 8, index; - uint16_t tmp = data[0]; // need min. 16 bits here - while (bits > 0 || pos < len) { - if (bits < 5) { - if (pos < len) { - tmp <<= 8; - tmp |= data[pos++] & 0xFF; - bits += 8; - } else { // last byte - tmp <<= (5 - bits); - bits = 5; - } - } - - bits -= 5; - index = (tmp >> bits) & 0x1F; - out.push_back(bintoasc()[index]); - } - - // append padding - while(out.length() % 4 != 0) - out.push_back('='); - - return out; - } - -private: - static const inline char *bintoasc() { static const char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; return bta ; } -}; - -#endif // RADIX32_H diff --git a/libretroshare/src/util/radix64.h b/libretroshare/src/util/radix64.h deleted file mode 100644 index 53dd7c256..000000000 --- a/libretroshare/src/util/radix64.h +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: radix64.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -#include "util/rsdeprecate.h" - -/** @deprecated use RsBase64 instead which supports also URL safe encoding */ -class RS_DEPRECATED_FOR(RsBase64) Radix64 -{ -public: - static std::vector decode(const std::string& buffer) - { - char val; - int c = 0, c2;/* init c because gcc is not clever - enough for the continue */ - int idx; - size_t buffer_pos = 0; - - radix64_init(); - - std::vector buf ; - idx = 0; - val = 0; - - for (buffer_pos = 0; buffer_pos < buffer.length(); buffer_pos++) - { - c = buffer[buffer_pos]; - -again: - if (c == '\n' || c == ' ' || c == '\r' || c == '\t') - continue; - else if (c == '=') - { - /* pad character: stop */ - /* some mailers leave quoted-printable - * encoded characters so we try to - * workaround this */ - if (buffer_pos + 2 < buffer.length()) - { - int cc1, cc2, cc3; - cc1 = buffer[buffer_pos]; - cc2 = buffer[buffer_pos + 1]; - cc3 = buffer[buffer_pos + 2]; - - if (isxdigit((unsigned char)cc1) && isxdigit((unsigned char)cc2) && strchr("=\n\r\t ", cc3)) - { - /* well it seems to be the case - - * adjust */ - c = - isdigit((unsigned char)cc1) ? (cc1 - - '0') - : (toupper((unsigned char)cc1) - 'A' + 10); - c <<= 4; - c |= - isdigit((unsigned char)cc2) ? (cc2 - - '0') - : (toupper((unsigned char)cc2) - 'A' + 10); - buffer_pos += 2; - goto again; - } - } - - if (idx == 1) - buf.push_back(val) ;// buf[n++] = val; - break; - } - else if ((c = asctobin()[(c2 = c)]) == 255) - { - /* invalid radix64 character %02x skipped\n", c2; */ - continue; - } - - switch (idx) - { - case 0: - val = c << 2; - break; - case 1: - val |= (c >> 4) & 3; - buf.push_back(val);//buf[n++] = val; - val = (c << 4) & 0xf0; - break; - case 2: - val |= (c >> 2) & 15; - buf.push_back(val);//buf[n++] = val; - val = (c << 6) & 0xc0; - break; - case 3: - val |= c & 0x3f; - buf.push_back(val);//buf[n++] = val; - break; - } - idx = (idx + 1) % 4; - } - - //idx = idx; - - return buf ; - } - - /**************** - * create a radix64 encoded string. - */ - static void encode( - const unsigned char* data, size_t len, std::string& out_string ) - { - char *buffer, *p; - - radix64_init(); - - size_t size = (len + 2) / 3 * 4 +1; - buffer = p = new char[size] ; - - for (; len >= 3; len -= 3, data += 3) - { - *p++ = bintoasc()[(data[0] >> 2) & 077]; - *p++ = - bintoasc()[ - (((data[0] << 4) & 060) | - ((data[1] >> 4) & 017)) & 077]; - *p++ = - bintoasc()[ - (((data[1] << 2) & 074) | - ((data[2] >> 6) & 03)) & 077]; - *p++ = bintoasc()[data[2] & 077]; - } - if (len == 2) - { - *p++ = bintoasc()[(data[0] >> 2) & 077]; - *p++ = - bintoasc()[ - (((data[0] << 4) & 060) | - ((data[1] >> 4) & 017)) & 077]; - *p++ = bintoasc()[((data[1] << 2) & 074)]; - *p++ = '=' ; - } - else if (len == 1) - { - *p++ = bintoasc()[(data[0] >> 2) & 077]; - *p++ = bintoasc()[(data[0] << 4) & 060]; - *p++ = '=' ; - *p++ = '=' ; - } - //*p = 0; - out_string = std::string(buffer,p-buffer) ; - delete[] buffer ; - } - - private: - static inline char *bintoasc() { static char bta[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; return bta ; } - static inline uint8_t *asctobin() { static uint8_t s[256]; return s ; } /* runtime radix64_initd */ - static int& is_radix64_initd() { static int is_inited = false ; return is_inited ; } - - /* hey, guess what: this is a read-only table. - * we don't _care_ if multiple threads get to initialise it - * at the same time, _except_ that is_radix64_initd=1 _must_ - * be done at the end... - */ - static bool radix64_init() - { - if (is_radix64_initd()) - return true; - - int i; - char *s; - - /* build the helpapr_table_t for radix64 to bin conversion */ - for (i = 0; i < 256; i++) - asctobin()[i] = 255; /* used to detect invalid characters */ - for (s = bintoasc(), i = 0; *s; s++, i++) - asctobin()[(int)*s] = i; - - is_radix64_initd() = 1; - return true ; - } -}; diff --git a/libretroshare/src/util/retrodb.cc b/libretroshare/src/util/retrodb.cc deleted file mode 100644 index 122f3e6a1..000000000 --- a/libretroshare/src/util/retrodb.cc +++ /dev/null @@ -1,866 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: retrodb.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2012 Christopher Evi-Parker * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include -#include -#include - -#include "util/rstime.h" -#include "util/retrodb.h" -#include "util/rsdbbind.h" -#include "util/stacktrace.h" -#include "util/rsdir.h" - -//#define RETRODB_DEBUG - -const int RetroDb::OPEN_READONLY = SQLITE_OPEN_READONLY; -const int RetroDb::OPEN_READWRITE = SQLITE_OPEN_READWRITE; -const int RetroDb::OPEN_READWRITE_CREATE = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; - -RetroDb::RetroDb(const std::string& dbPath, int flags, const std::string& key): - mDb(nullptr), mKey(key) -{ - bool alreadyExists = RsDirUtil::fileExists(dbPath); - - int rc = sqlite3_open_v2(dbPath.c_str(), &mDb, flags, nullptr); - if(rc) - { - RsErr() << __PRETTY_FUNCTION__ << " Can't open database, Error: " - << rc << " " << sqlite3_errmsg(mDb) << std::endl; - closeDb(); - print_stacktrace(); - return; - } - - if(alreadyExists) - { - /* If the database has been created by a RetroShare compiled without - * SQLCipher, open it as a plain SQLite database instead of failing - * miserably. If RetroShare has been compiled without SQLCipher but the - * database seems encrypted print a meaningful error message instead of - * crashing miserably. - * At some point we could implement a migration SQLite <-> SQLCipher - * mecanism and suggest it to the user, or give the option to the user - * to choice between plain SQLite or SQLCipher database, is some cases - * such as encrypted FS it might make sense to keep SQLite even if - * SQLCipher is availble for performance, as encryption is already - * provided at FS level. */ - - rc = sqlite3_exec( mDb, "PRAGMA schema_version;", - nullptr, nullptr, nullptr ); - if( rc == SQLITE_OK ) - { -#ifndef NO_SQLCIPHER - RsWarn() << __PRETTY_FUNCTION__ << " The database is not encrypted: " - << dbPath << std::endl; -#endif // ndef NO_SQLCIPHER - - return; - } - else - { -#ifdef NO_SQLCIPHER - RsErr() << __PRETTY_FUNCTION__ << " Error quering schema version." - << " Are you trying to open an encrypted database without " - << "compiling SQLCipher support?" << std::endl << std::endl; - print_stacktrace(); - closeDb(); -#else // def NO_SQLCIPHER - RsInfo() << __PRETTY_FUNCTION__ << " The database seems encrypted: " - << dbPath << std::endl; -#endif // def NO_SQLCIPHER - } - } - -#ifndef NO_SQLCIPHER - if(!mKey.empty()) - { - rc = sqlite3_key(mDb, mKey.c_str(), static_cast(mKey.size())); - - if(rc) - { - RsErr() << __PRETTY_FUNCTION__ << " Can't key database: " << rc - << " " << sqlite3_errmsg(mDb) << std::endl; - closeDb(); - return; - } - } - - char* err = nullptr; - rc = sqlite3_exec(mDb, "PRAGMA cipher_migrate;", nullptr, nullptr, &err); - if (rc != SQLITE_OK) - { - RsErr() << __PRETTY_FUNCTION__ << " Error upgrading database, error " - << "code: " << rc << " " << err << std::endl; - sqlite3_free(err); - } - - // Test DB for correct sqlcipher version - if(sqlite3_exec( - mDb, "PRAGMA user_version;", - nullptr, nullptr, nullptr ) != SQLITE_OK) - { - RsWarn() << __PRETTY_FUNCTION__ << " Failed to open database: " - << dbPath << std::endl; - - //Reopening the database with correct settings - closeDb(); - if(!rc) rc = sqlite3_open_v2(dbPath.c_str(), &mDb, flags, nullptr); - if(!rc && !mKey.empty()) - rc = sqlite3_key(mDb, mKey.c_str(), static_cast(mKey.size())); - if(!rc) - rc = sqlite3_exec( mDb, "PRAGMA kdf_iter = 64000;", - nullptr, nullptr, nullptr ); - if (!rc && (sqlite3_exec( mDb, "PRAGMA user_version;", - nullptr, nullptr, nullptr ) == SQLITE_OK)) - { - RsInfo() << __PRETTY_FUNCTION__ << " Re-trying with settings for " - << "sqlcipher version 3 successed" << std::endl; - } - else - { - RsErr() << __PRETTY_FUNCTION__ << " Re-trying with settings for " - << "sqlcipher version 3 failed, giving up" << std::endl; - closeDb(); - return; - } - } -#endif // ndef NO_SQLCIPHER -} - -RetroDb::~RetroDb() { closeDb(); } - -void RetroDb::closeDb() -{ - // no-op if mDb is nullptr (https://www.sqlite.org/c3ref/close.html) - int rc = sqlite3_close(mDb); - mDb = nullptr; - - Dbg2() << __PRETTY_FUNCTION__ << " sqlite3_close return: " << rc - << std::endl; -} - -#define TIME_LIMIT 3 - -bool RetroDb::execSQL(const std::string &query){ - - // prepare statement - sqlite3_stmt* stm = NULL; - -#ifdef RETRODB_DEBUG - std::cerr << "Query: " << query << std::endl; -#endif - - int rc = sqlite3_prepare_v2(mDb, query.c_str(), query.length(), &stm, NULL); - - // check if there are any errors - if(rc != SQLITE_OK){ - std::cerr << "RetroDb::execSQL(): Error preparing statement\n"; - std::cerr << "Error code: " << sqlite3_errmsg(mDb) - << std::endl; - return false; - } - - - uint32_t delta = 3; - rstime_t stamp = time(NULL); - bool timeOut = false, ok = false; - - while(!timeOut){ - - rc = sqlite3_step(stm); - - if(rc == SQLITE_DONE){ - ok = true; - break; - } - - if(rc != SQLITE_BUSY){ - ok = false; - break; - } - - if(time(NULL) > stamp + TIME_LIMIT) - { - ok = false; - timeOut = true; - } - // TODO add sleep so not to waste - // precious cycles - } - - if(!ok){ - - if(rc == SQLITE_BUSY){ - std::cerr << "RetroDb::execSQL()\n" ; - std::cerr << "SQL timed out!" << std::endl; - }else{ - std::cerr << "RetroDb::execSQL(): Error executing statement (code: " << rc << ")\n"; - std::cerr << "Sqlite Error msg: " << sqlite3_errmsg(mDb) - << std::endl; - std::cerr << "RetroDb::execSQL() Query: " << query << std::endl; - } - } - - // finalise statement or else db cannot be closed - sqlite3_finalize(stm); - return ok; -} - -RetroCursor* RetroDb::sqlQuery(const std::string& tableName, const std::list& columns, - const std::string& selection, const std::string& orderBy){ - - if(tableName.empty() || columns.empty()){ - std::cerr << "RetroDb::sqlQuery(): No table or columns given" << std::endl; - return NULL; - } - - std::string columnSelection; // the column names to return - sqlite3_stmt* stmt = NULL; - std::list::const_iterator it = columns.begin(); - - for(; it != columns.end(); ++it){ - if (it != columns.begin()) { - columnSelection += ","; - } - - columnSelection += *it; - } - - // construct query - // SELECT columnSelection FROM tableName WHERE selection - std::string sqlQuery = "SELECT " + columnSelection + " FROM " + - tableName; - - // add selection clause if present - if(!selection.empty()) - sqlQuery += " WHERE " + selection; - - - // add 'order by' clause if present - if(!orderBy.empty()) - sqlQuery += " ORDER BY " + orderBy + ";"; - else - sqlQuery += ";"; - -#ifdef RETRODB_DEBUG - std::cerr << "RetroDb::sqlQuery(): " << sqlQuery << std::endl; -#endif - - sqlite3_prepare_v2(mDb, sqlQuery.c_str(), sqlQuery.length(), &stmt, NULL); - return (new RetroCursor(stmt)); -} - -bool RetroDb::isOpen() const { - return (mDb==NULL ? false : true); -} - -bool RetroDb::sqlInsert(const std::string &table, const std::string& /* nullColumnHack */, const ContentValue &cv){ - - std::map keyTypeMap; - cv.getKeyTypeMap(keyTypeMap); - std::map::iterator mit = keyTypeMap.begin(); - - // build columns part of insertion - std::string qColumns = table + "("; - - for(; mit != keyTypeMap.end(); ++mit){ - - qColumns += mit->first; - - ++mit; - - // add comma if more columns left - if(mit == keyTypeMap.end()) - qColumns += ")"; // close bracket if at end - else - qColumns += ","; - - --mit; - } - - // build values part of insertion - std::string qValues; - std::list paramBindings; - buildInsertQueryValue(keyTypeMap, cv, qValues, paramBindings); - - // complete insertion query - std::string sqlQuery = "INSERT INTO " + qColumns + " " + qValues; - - bool ok = execSQL_bind(sqlQuery, paramBindings); - -#ifdef RETRODB_DEBUG - std::cerr << "RetroDb::sqlInsert(): " << sqlQuery << std::endl; -#endif - - return ok; -} - -std::string RetroDb::getKey() const -{ - return mKey; -} - -bool RetroDb::beginTransaction() -{ - if (!isOpen()) { - return false; - } - - return execSQL("BEGIN;"); -} - -bool RetroDb::commitTransaction() -{ - if (!isOpen()) { - return false; - } - - return execSQL("COMMIT;"); -} -bool RetroDb::rollbackTransaction() -{ - if (!isOpen()) { - return false; - } - - return execSQL("ROLLBACK;"); -} - -bool RetroDb::execSQL_bind(const std::string &query, std::list ¶mBindings){ - - // prepare statement - sqlite3_stmt* stm = NULL; - -#ifdef RETRODB_DEBUG - std::cerr << "Query: " << query << std::endl; -#endif - - int rc = sqlite3_prepare_v2(mDb, query.c_str(), query.length(), &stm, NULL); - - // check if there are any errors - if(rc != SQLITE_OK){ - std::cerr << "RetroDb::execSQL_bind(): Error preparing statement\n"; - std::cerr << "Error code: " << sqlite3_errmsg(mDb) - << std::endl; - return false; - } - - std::list::iterator lit = paramBindings.begin(); - - for(; lit != paramBindings.end(); ++lit){ - RetroBind* rb = *lit; - - if(!rb->bind(stm)) - { - std::cerr << "\nBind failed for index: " << rb->getIndex() - << std::endl; - } - - delete rb; - rb = NULL; - } - - uint32_t delta = 3; - rstime_t stamp = time(NULL), now = 0; - bool timeOut = false, ok = false; - - while(!timeOut){ - - rc = sqlite3_step(stm); - - if(rc == SQLITE_DONE){ - ok = true; - break; - } - - if(rc != SQLITE_BUSY){ - ok = false; - break; - } - - now = time(NULL); - delta = stamp - now; - - if(delta > TIME_LIMIT){ - ok = false; - timeOut = true; - } - // TODO add sleep so not to waste - // precious cycles - } - - if(!ok){ - - if(rc == SQLITE_BUSY){ - std::cerr << "RetroDb::execSQL_bind()\n" ; - std::cerr << "SQL timed out!" << std::endl; - }else{ - std::cerr << "RetroDb::execSQL_bind(): Error executing statement (code: " << rc << ")\n"; - std::cerr << "Sqlite Error msg: " << sqlite3_errmsg(mDb) - << std::endl; - std::cerr << "RetroDb::execSQL_bind() Query: " << query << std::endl; - } - } - - // finalise statement or else db cannot be closed - sqlite3_finalize(stm); - return ok; -} - -void RetroDb::buildInsertQueryValue(const std::map keyTypeMap, - const ContentValue& cv, std::string& parameter, - std::list& paramBindings) -{ - std::map::const_iterator mit = keyTypeMap.begin(); - - parameter = "VALUES("; - int index = 0; - for(mit=keyTypeMap.begin(); mit!=keyTypeMap.end(); ++mit) - { - - uint8_t type = mit->second; - std::string key = mit->first; - - RetroBind* rb = NULL; - if(ContentValue::BOOL_TYPE == type) - { - bool value; - cv.getAsBool(key, value); - rb = new RsBoolBind(value, ++index); - } - else if( ContentValue::DOUBLE_TYPE == type) - { - double value; - cv.getAsDouble(key, value); - rb = new RsDoubleBind(value, ++index); - } - else if( ContentValue::DATA_TYPE == type) - { - char* value; - uint32_t len; - cv.getAsData(key, len, value); - rb = new RsBlobBind(value, len, ++index); - } - else if ( ContentValue::STRING_TYPE == type) - { - std::string value; - cv.getAsString(key, value); - rb = new RsStringBind(value, ++index); - } - else if ( ContentValue::INT32_TYPE == type) - { - int32_t value = 0; - cv.getAsInt32(key, value); - rb = new RsInt32Bind(value, ++index); - } - else if( ContentValue::INT64_TYPE == type) - { - int64_t value = 0; - cv.getAsInt64(key, value); - rb = new RsInt64bind(value, ++index); - } - - if(rb) - { - paramBindings.push_back(rb); - - ++mit; - - if(mit == keyTypeMap.end()) - parameter += "?"; - else - parameter += "?,"; - - --mit; - } - } - - parameter += ")"; - - -} - -void RetroDb::buildUpdateQueryValue(const std::map keyTypeMap, - const ContentValue& cv, std::string& parameter, - std::list& paramBindings) -{ - std::map::const_iterator mit = keyTypeMap.begin(); - - int index = 0; - for(mit=keyTypeMap.begin(); mit!=keyTypeMap.end(); ++mit) - { - - uint8_t type = mit->second; - std::string key = mit->first; - - RetroBind* rb = NULL; - if(ContentValue::BOOL_TYPE == type) - { - bool value; - cv.getAsBool(key, value); - rb = new RsBoolBind(value, ++index); - } - else if( ContentValue::DOUBLE_TYPE == type) - { - double value; - cv.getAsDouble(key, value); - rb = new RsDoubleBind(value, ++index); - } - else if( ContentValue::DATA_TYPE == type) - { - char* value; - uint32_t len; - cv.getAsData(key, len, value); - rb = new RsBlobBind(value, len, ++index); - } - else if ( ContentValue::STRING_TYPE == type) - { - std::string value; - cv.getAsString(key, value); - rb = new RsStringBind(value, ++index); - } - else if ( ContentValue::INT32_TYPE == type) - { - int32_t value = 0; - cv.getAsInt32(key, value); - rb = new RsInt32Bind(value, ++index); - } - else if( ContentValue::INT64_TYPE == type) - { - int64_t value = 0; - cv.getAsInt64(key, value); - rb = new RsInt64bind(value, ++index); - } - - if(rb) - { - paramBindings.push_back(rb); - - ++mit; - - if(mit == keyTypeMap.end()) - parameter += key + "=?"; - else - parameter += key + "=?,"; - - --mit; - } - } - -} - -bool RetroDb::sqlDelete(const std::string &tableName, const std::string &whereClause, const std::string &/*whereArgs*/){ - - std::string sqlQuery = "DELETE FROM " + tableName; - - if(!whereClause.empty()){ - sqlQuery += " WHERE " + whereClause + ";"; - }else - sqlQuery += ";"; - - return execSQL(sqlQuery); -} - - -bool RetroDb::sqlUpdate(const std::string &tableName, std::string whereClause, const ContentValue& cv){ - - std::string sqlQuery = "UPDATE " + tableName + " SET "; - - - std::map keyTypeMap; - std::map::iterator mit; - cv.getKeyTypeMap(keyTypeMap); - - // build SET part of update - std::string qValues; - std::list paramBindings; - buildUpdateQueryValue(keyTypeMap, cv, qValues, paramBindings); - - if(qValues.empty()) - return false; - else - sqlQuery += qValues; - - // complete update - if(!whereClause.empty()){ - sqlQuery += " WHERE " + whereClause + ";"; - } - else{ - sqlQuery += ";"; - } - - // execute query - return execSQL_bind(sqlQuery, paramBindings); -} - -bool RetroDb::tableExists(const std::string &tableName) -{ - if (!isOpen()) { - return false; - } - - std::string sqlQuery = "PRAGMA table_info(" + tableName + ");"; - - bool result = false; - sqlite3_stmt* stmt = NULL; - - int rc = sqlite3_prepare_v2(mDb, sqlQuery.c_str(), sqlQuery.length(), &stmt, NULL); - if (rc == SQLITE_OK) { - rc = sqlite3_step(stmt); - switch (rc) { - case SQLITE_ROW: - result = true; - break; - case SQLITE_DONE: - break; - default: - std::cerr << "RetroDb::tableExists(): Error executing statement (code: " << rc << ")" - << std::endl; - return false; - } - } else { - std::cerr << "RetroDb::tableExists(): Error preparing statement\n"; - std::cerr << "Error code: " << sqlite3_errmsg(mDb) - << std::endl; - } - - if (stmt) { - sqlite3_finalize(stmt); - } - - return result; -} - -/********************** RetroCursor ************************/ - -RetroCursor::RetroCursor(sqlite3_stmt *stmt) - : mStmt(NULL) { - - open(stmt); -} - -RetroCursor::~RetroCursor(){ - - // finalise statement - if(mStmt){ - sqlite3_finalize(mStmt); - } -} - -bool RetroCursor::moveToFirst(){ - -#ifdef RETRODB_DEBUG - std::cerr << "RetroCursor::moveToFirst()\n"; -#endif - - if(!isOpen()) - return false; - - // reset statement - int rc = sqlite3_reset(mStmt); - - if(rc != SQLITE_OK){ - -#ifdef RETRODB_DEBUG - std::cerr << "Error code: " << rc << std::endl; -#endif - - return false; - } - - rc = sqlite3_step(mStmt); - - if(rc == SQLITE_ROW){ - return true; - } - -#ifdef RETRODB_DEBUG - std::cerr << "Error code: " << rc << std::endl; -#endif - - return false; -} - -bool RetroCursor::moveToLast(){ - -#ifdef RETRODB_DEBUG - std::cerr << "RetroCursor::moveToLast()\n"; -#endif - - if(!isOpen()) - return -1; - - // go to begining - int rc = sqlite3_reset(mStmt); - - if(rc != SQLITE_OK) - return false; - - rc = sqlite3_step(mStmt); - - while(rc == SQLITE_ROW){ - rc = sqlite3_step(mStmt); - } - - if(rc != SQLITE_DONE){ - std::cerr << "Error executing statement (code: " << rc << ")\n" - << std::endl; - return false; - - }else{ - return true; - } -} - -int RetroCursor::columnCount() const { - - if(isOpen()) - return sqlite3_data_count(mStmt); - else - return -1; -} - -bool RetroCursor::isOpen() const { - return !(mStmt == NULL); -} - -bool RetroCursor::close(){ - - if(!isOpen()) - return false; - - - int rc = sqlite3_finalize(mStmt); - mStmt = NULL; - - return (rc == SQLITE_OK); -} - -bool RetroCursor::open(sqlite3_stmt *stm){ - -#ifdef RETRODB_DEBUG - std::cerr << "RetroCursor::open() \n"; -#endif - - if(isOpen()) - close(); - - mStmt = stm; - - // ensure statement is valid - int rc = sqlite3_reset(mStmt); - - if(rc == SQLITE_OK){ - return true; - } - else{ - std::cerr << "Error Opening cursor (code: " << rc << ")\n"; - close(); - return false; - } - -} - -bool RetroCursor::moveToNext(){ - -#ifdef RETRODB_DEBUG - std::cerr << "RetroCursor::moveToNext()\n"; -#endif - - if(!isOpen()) - return false; - - int rc = sqlite3_step(mStmt); - - if(rc == SQLITE_ROW){ - return true; - - }else if(rc == SQLITE_DONE){ // no more results - return false; - } - else if(rc == SQLITE_BUSY){ // should not enter here - std::cerr << "RetroDb::moveToNext()\n" ; - std::cerr << "Busy!, possible multiple accesses to Db" << std::endl - << "serious error"; - - return false; - - }else{ - std::cerr << "Error executing statement (code: " << rc << ")\n"; - return false; - } -} - -int32_t RetroCursor::getInt32(int columnIndex){ - return sqlite3_column_int(mStmt, columnIndex); -} - -int64_t RetroCursor::getInt64(int columnIndex){ - return sqlite3_column_int64(mStmt, columnIndex); -} - -bool RetroCursor::getBool(int columnIndex){ - return sqlite3_column_int(mStmt, columnIndex); -} - -double RetroCursor::getDouble(int columnIndex){ - return sqlite3_column_double(mStmt, columnIndex); -} - -void RetroCursor::getString(int columnIndex, std::string &str){ - str.clear(); - char* raw_str = (char*)sqlite3_column_text(mStmt, columnIndex); - if(raw_str != NULL) - { - str.assign(raw_str); -#ifdef RADIX_STRING - char* buffer = NULL; - size_t buffLen; - Radix64::decode(str, buffer, buffLen); - str.clear(); - if(buffLen != 0) - { - str.assign(buffer, buffLen); - delete[] buffer; - } - else - str.clear(); -#endif - } - else - { - str.clear(); - } -} - -const void* RetroCursor::getData(int columnIndex, uint32_t &datSize){ - - const void* val = sqlite3_column_blob(mStmt, columnIndex); - datSize = sqlite3_column_bytes(mStmt, columnIndex); - - return val; -} - diff --git a/libretroshare/src/util/retrodb.h b/libretroshare/src/util/retrodb.h deleted file mode 100644 index b48415152..000000000 --- a/libretroshare/src/util/retrodb.h +++ /dev/null @@ -1,322 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: retrodb.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#ifdef NO_SQLCIPHER -#include -#else -#include -#endif - -#include -#include -#include -#include - -#include "util/rsdebug.h" -#include "util/rsdbbind.h" -#include "util/contentvalue.h" - -class RetroCursor; - -/*! - * RetroDb provide a means for Retroshare's core and \n - * services to maintain an easy to use random access file via a database \n - * It models itself after android's sqlite functionality \n - * This is essentially unashamedly a clone of Android's SQLiteDatabase interface - */ -class RetroDb -{ -public: - - /*! - * @param dbPath path to data base file - * @param flags determine where to open read only or read/write - */ - RetroDb(const std::string& dbPath, int flags, const std::string& key = ""); - - /*! - * closes db if it is not already closed - */ - ~RetroDb(); - - /*! - * @return key used to encrypt database - */ - std::string getKey() const; - - /*! - * opens sqlite data base - * @param dbPath - * @param flags - * @return false if failed to open, true otherwise - */ - bool openDb(const std::string& dbPath, int flags = OPEN_READONLY); - - /*! - * close the database - */ - void closeDb(); - - /*! - * - * @return false if database is not open, true otherwise - */ - bool isOpen() const; - - /* modifying db */ -public: - - /*! - * Start transaction - * @return true/false - */ - bool beginTransaction(); - - /*! - * Commit transaction - * @return true/false - */ - bool commitTransaction(); - - /*! - * Rollback transaction - * @return true/false - */ - bool rollbackTransaction(); - - /*! - * To a make query which do not return a result \n - * below are the type of queries this method should be used for \n - * ALTER TABLE \n - * CREATE or DROP table / trigger / view / index / virtual table \n - * REINDEX \n - * RELEASE \n - * SAVEPOINT \n - * PRAGMA that returns no data \n - * @param query SQL query - * @return false if there was an sqlite error, true otherwise - */ - bool execSQL(const std::string& query); - - /*! - * inserts a row in a database table - * @param table table you want to insert content values into - * @param nullColumnHack SQL doesn't allow inserting a completely \n - * empty row without naming at least one column name - * @param cv hold entries to insert - * @return true if insertion successful, false otherwise - */ - bool sqlInsert(const std::string& table,const std::string& nullColumnHack, const ContentValue& cv); - - /*! - * update row in a database table - * @param tableName the table on which to apply the UPDATE - * @param whereClause formatted as where statement without 'WHERE' itself - * @param cv Values used to replace current values in accessed record - * @return true if update was successful, false otherwise - */ - bool sqlUpdate(const std::string& tableName, const std::string whereClause, const ContentValue& cv); - - /*! - * Query the given table, returning a Cursor over the result set - * @param tableName the table name - * @param columns list columns that should be returned and their order (the list's order) - * @param selection A filter declaring which rows to return, formatted as \n - * an SQL WHERE clause (excluding the WHERE itself). Passing null will \n - * return all rows for the given table. - * @param order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself) - * @return cursor over result set, this allocated resource should be free'd after use \n - * column order is in list order. - */ - RetroCursor* sqlQuery(const std::string& tableName, const std::list& columns, - const std::string& selection, const std::string& orderBy); - - /*! - * delete row in an sql table - * @param tableName the table on which to apply the DELETE - * @param whereClause formatted as where statement without 'WHERE' itself - * @return false - */ - bool sqlDelete(const std::string& tableName, const std::string& whereClause, const std::string& whereArgs); - - /*! - * TODO - * defragment database, should be done on databases if many modifications have occured - */ - void vacuum(); - - /*! - * Check if table exist in database - * @param tableName table to check - * @return true/false - */ - bool tableExists(const std::string& tableName); - -public: - - static const int OPEN_READONLY; - static const int OPEN_READWRITE; - static const int OPEN_READWRITE_CREATE; - -private: - - bool execSQL_bind(const std::string &query, std::list& blobs); - - /*! - * Build the "VALUE" part of an insertiong sql query - * @param parameter contains place holder query - * @param paramBindings - */ - void buildInsertQueryValue(const std::map keyMap, const ContentValue& cv, - std::string& parameter, std::list& paramBindings); - - /*! - * Build the "VALUE" part of an insertiong sql query - * @param parameter contains place holder query - * @param paramBindings - */ - void buildUpdateQueryValue(const std::map keyMap, const ContentValue& cv, - std::string& parameter, std::list& paramBindings); - -private: - - sqlite3* mDb; - const std::string mKey; - - RS_SET_CONTEXT_DEBUG_LEVEL(3) -}; - -/*! - * Exposes result set from retrodb query - */ -class RetroCursor { - -public: - - /*! - * Initialises a null cursor - * @warning cursor takes ownership of statement passed to it - */ - RetroCursor(sqlite3_stmt*); - - ~RetroCursor(); - - /*! - * move to first row of results - * @return false if no results - */ - bool moveToFirst(); - - /*! - * move to next row of results - * @return false if no further results - */ - bool moveToNext(); - - /*! - * move to last row of results - * @return false if no result, true otherwise - */ - bool moveToLast(); - - /* data retrieval */ - - /*! - * @return true if cursor is open and active, false otherwise - */ - bool isOpen() const; - - /*! - * cursor is closed, statement used to open cursor is deleted - * @return false if error on close (was already closed, error occured) - */ - bool close(); - - /*! - * - * @return -1 if cursor is in error, otherwise number of columns in result - */ - int32_t columnCount() const ; - - /*! - * Current statement is closed and discarded (finalised) - * before actual opening occurs - * @param stm statement to open cursor on - * @return true if cursor is successfully opened - */ - 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. - * @return the value of the column as 32 bit integer - */ - int32_t getInt32(int columnIndex); - - /*! - * Returns the value of the requested column as a String. - * @param columnIndex the zero-based index of the target column. - * @return the value of the column as 64 bit integer - */ - int64_t getInt64(int columnIndex); - - /*! - * Returns the value of the requested column as a String. - * @param columnIndex the zero-based index of the target column. - * @return the value of the column as 64 bit float - */ - double getDouble(int columnIndex); - - /*! - * Returns the value of the requested column as a String. - * @param columnIndex the zero-based index of the target column. - * @return the value of the column as bool - */ - bool getBool(int columnIndex); - - /*! - * Returns the value of the requested column as a String. - * @param columnIndex the zero-based index of the target column. - * @return the value of the column as a string - */ - void getString(int columnIndex, std::string& str); - - /*! - * Returns the value of the requested column as a String. - * data returned must be copied, as it is freed after RetroDb - * is closed or destroyed - * @param columnIndex the zero-based index of the target column. - * @return the value of the column as pointer to raw data - */ - const void* getData(int columnIndex, uint32_t& datSize); - - template - inline void getStringT(int columnIndex, T &str){ - std::string temp; - getString(columnIndex, temp); - str = T(temp); - } -private: - sqlite3_stmt* mStmt; -}; diff --git a/libretroshare/src/util/rsbase64.cc b/libretroshare/src/util/rsbase64.cc deleted file mode 100644 index f62c40cef..000000000 --- a/libretroshare/src/util/rsbase64.cc +++ /dev/null @@ -1,198 +0,0 @@ -/******************************************************************************* - * * - * libretroshare base64 encoding utilities * - * * - * Copyright (C) 2015 Retroshare Team * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsbase64.h" -#include "util/rsdebug.h" - -#if __cplusplus < 201703L -/* Solve weird undefined reference error with C++ < 17 see: - * https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char - */ -/*static*/ decltype(RsBase64::bDict) constexpr RsBase64::bDict; -/*static*/ decltype(RsBase64::uDict) constexpr RsBase64::uDict; -/*static*/ decltype(RsBase64::rDict) constexpr RsBase64::rDict; -/*static*/ decltype(RsBase64::sPad) constexpr RsBase64::sPad; -#endif - -/*static*/ void RsBase64::encode( - rs_view_ptr data, size_t len, std::string& outString, - bool padding, bool urlSafe ) -{ - if(!data || !len) - { - outString.clear(); - return; - } - - const char* sDict = urlSafe ? uDict : bDict; - - // Workaround if input and output are the same buffer. - bool inplace = (outString.data() == reinterpret_cast(data)); - std::string tBuff; - std::string& outStr = inplace ? tBuff : outString; - - auto encSize = encodedSize(len, padding); - outStr.resize(encSize); - char* p = &outStr[0]; - - for (; len >= 3; len -= 3, data += 3) - { - *p++ = sDict[ (data[0] >> 2) & 077 ]; - *p++ = sDict[ - (((data[0] << 4) & 060) | ((data[1] >> 4) & 017)) & 077 ]; - *p++ = sDict[ - (((data[1] << 2) & 074) | ((data[2] >> 6) & 03)) & 077 ]; - *p++ = sDict[ data[2] & 077 ]; - } - if (len == 2) - { - *p++ = sDict[ (data[0] >> 2) & 077 ]; - *p++ = sDict[ - (((data[0] << 4) & 060) | ((data[1] >> 4) & 017)) & 077 ]; - *p++ = sDict[ ((data[1] << 2) & 074) ]; - if(padding) *p++ = sPad; - } - else if (len == 1) - { - *p++ = sDict[ (data[0] >> 2) & 077 ]; - *p++ = sDict[ (data[0] << 4) & 060 ]; - if(padding) { *p++ = sPad; *p++ = sPad; } - } - - if(inplace) outString = tBuff; -} - -/*static*/ std::error_condition RsBase64::decode( - const std::string& encoded, std::vector& decoded ) -{ - size_t decSize; std::error_condition ec; - std::tie(decSize, ec) = decodedSize(encoded); - if(!decSize || ec) return ec; - - size_t encSize = encoded.size(); - decoded.resize(decSize); - - for (size_t i = 0, o = 0; i < encSize; i += 4, o += 3) - { - char input0 = encoded[i + 0]; - char input1 = encoded[i + 1]; - - /* At the end of the string, missing bytes 2 and 3 are considered - * padding '=' */ - char input2 = i + 2 < encoded.size() ? encoded[i + 2] : sPad; - char input3 = i + 3 < encSize ? encoded[i + 3] : sPad; - - // If any unknown characters appear, it's an error. - if(!( isBase64Char(input0) && isBase64Char(input1) && - isBase64Char(input2) && isBase64Char(input3) )) - return std::errc::argument_out_of_domain; - - /* If padding appears anywhere but the last 1 or 2 characters, or if - * it appears but encoded.size() % 4 != 0, it's an error. */ - bool at_end = (i + 4 >= encSize); - if ( (input0 == sPad) || (input1 == sPad) || - ( input2 == sPad && !at_end ) || - ( input2 == sPad && input3 != sPad ) || - ( input3 == sPad && !at_end) ) - return std::errc::illegal_byte_sequence; - - uint32_t b0 = rDict[static_cast(input0)] & 0x3f; - uint32_t b1 = rDict[static_cast(input1)] & 0x3f; - uint32_t b2 = rDict[static_cast(input2)] & 0x3f; - uint32_t b3 = rDict[static_cast(input3)] & 0x3f; - - uint32_t stream = (b0 << 18) | (b1 << 12) | (b2 << 6) | b3; - decoded[o + 0] = (stream >> 16) & 0xFF; - if (input2 != sPad) decoded[o + 1] = (stream >> 8) & 0xFF; - /* If there are any stale bits in this from input1, the text is - * malformed. */ - else if (((stream >> 8) & 0xFF) != 0) - return std::errc::invalid_argument; - - if (input3 != sPad) decoded[o + 2] = (stream >> 0) & 0xFF; - /* If there are any stale bits in this from input2, the text is - * malformed. */ - else if (((stream >> 0) & 0xFF) != 0) - return std::errc::invalid_argument; - } - - return std::error_condition(); -} - -/*static*/ size_t RsBase64::encodedSize(size_t decodedSize, bool padding) -{ - if(!decodedSize) return 0; - - // Thanks https://stackoverflow.com/a/45401395 - if(padding) return ceilDivision(decodedSize, 3) * 4; - return ceilDivision(decodedSize * 8, 6); -} - -/*static*/ std::tuple RsBase64::decodedSize( - const std::string& input ) -{ - const auto success = [](size_t val) - { return std::make_tuple(val, std::error_condition()); }; - - if(input.empty()) return success(0); - - auto mod = input.size() % 4; - if(mod == 1) std::make_tuple(0, std::errc::invalid_argument); - - size_t padded_size = ((input.size() + 3) / 4) * 3; - if (mod >= 2 || (mod == 0 && input[input.size() - 1] == sPad)) - { - /* If the last byte is '=', or the input size % 4 is 2 or 3 (thus - * there are implied '='s), then the actual size is 1-2 bytes - * smaller. */ - if ( mod == 2 || (mod == 0 && input[input.size() - 2] == sPad) ) - { - /* If the second-to-last byte is also '=', or the input - * size % 4 is 2 (implying a second '='), then the actual size - * is 2 bytes smaller. */ - return success(padded_size - 2); - } - else - { - /* Otherwise it's just the last character and the actual size is - * 1 byte smaller. */ - return success(padded_size - 1); - } - } - return success(padded_size); -} - -/*static*/ size_t RsBase64::stripInvalid( - const std::string& in, std::string& out ) -{ - size_t strippedCnt = 0; - auto inSize = in.size(); - out.resize(inSize); - for(size_t i = 0; i < inSize; ++i) - { - if(isBase64Char(in[i])) out[i-strippedCnt] = in[i]; - else ++strippedCnt; - } - out.resize(inSize-strippedCnt); - return strippedCnt; -} diff --git a/libretroshare/src/util/rsbase64.h b/libretroshare/src/util/rsbase64.h deleted file mode 100644 index 819870089..000000000 --- a/libretroshare/src/util/rsbase64.h +++ /dev/null @@ -1,144 +0,0 @@ -/******************************************************************************* - * * - * libretroshare base64 encoding utilities * - * * - * Copyright (C) 2015 Retroshare Team * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include - -#include "util/rsmemory.h" - -/** - * Implement methods to encode e decode to base64 format as per RFC 4648 - * This implementation support also the file name and URL safe base64url format - * @see https://tools.ietf.org/html/rfc4648#section-5 - */ -class RsBase64 -{ -public: - /// Enable base64url by default - static constexpr bool DEFAULT_URL_SAFE = true; - - /// Disable padding by default - static constexpr bool DEFAULT_PADDING = false; - - /** - * @brief Encode arbitrary data to base64 - * @param[in] data pointer to the input data buffer - * @param[in] len lenght of the input buffer - * @param[out] outString storage for the resulting base64 encoded string - * @param[in] padding set to true to enable padding to 32 bits - * @param[in] urlSafe pass true for base64url format, false for base64 format - */ - static void encode( - rs_view_ptr data, size_t len, - std::string& outString, - bool padding = DEFAULT_PADDING, bool urlSafe = DEFAULT_URL_SAFE ); - - /** - * @brief Decode data from a base64 encoded string - * @param[in] encoded encoded string - * @param[out] decoded storage for decoded data - * @return success or error details - */ - static std::error_condition decode( - const std::string& encoded, std::vector& decoded ); - - /** - * Remove invalid characters from base64 encoded string. - * Often when copy and pasting from one progam to another long base64 - * strings, new lines, spaces or other characters end up polluting the - * original text. This function is useful to cleanup the pollution before - * attempting to decode the message. - * @param in input string - * @param out storage for cleaned string. In-place operation in supported so - * the same input string may be passed. - * @return count of stripped invalid characters - */ - static size_t stripInvalid(const std::string& in, std::string& out); - - /** - * Calculate how much bytes are needed to store the base64 encoded version - * of some data. - * @param decodedSize size of the original decoded data - * @param padding true to enable base64 padding - * @return how much bytes would take to store the encoded version - */ - static size_t encodedSize( - size_t decodedSize, bool padding = DEFAULT_PADDING ); - - /** - * @brief Calculate how much space is needed to store the decoded version of - * a base64 encoded string - * @param input encoded string - * @return decoded size, plus error information on failure - */ - static std::tuple decodedSize( - const std::string& input ); - -private: - /// base64 conversion table - static constexpr char bDict[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /// base64url conversion table - static constexpr char uDict[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - /// This reverse table supports both base64 and base64url - static constexpr int8_t rDict[256] = { - /* index +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 */ - /* 0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 16 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 32 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, - /* 48 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, - /* 64 */ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - /* 80 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, - /* 96 */ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - /* 112 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, - /* 128 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 144 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 160 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 176 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 192 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 208 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 224 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 240 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; - - /// base64 padding character - static constexpr char sPad = '='; - - /** Check if given character is valid either for base64 or for base64url - * @param c character to check - * @return true if valid false otherwise - */ - static inline bool isBase64Char(char c) - { return rDict[static_cast(c)] >= 0; } - - /** Perform ceil division without floating point operations */ - static inline size_t ceilDivision(size_t dividend, size_t divisor) - { return (dividend + divisor - 1) / divisor; } -}; diff --git a/libretroshare/src/util/rsdbbind.cc b/libretroshare/src/util/rsdbbind.cc deleted file mode 100644 index db5233ba8..000000000 --- a/libretroshare/src/util/rsdbbind.cc +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsbdbind.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsdbbind.h" - -RsDoubleBind::RsDoubleBind(double value, int index) - : RetroBind(DOUBLE, index), mValue(value) {} - -RsStringBind::RsStringBind(const std::string& value, int index) - : RetroBind(STRING, index), mValue(value) {} - -RsInt32Bind::RsInt32Bind(int32_t value, int index) - : RetroBind(INT32, index), mValue(value) {} - -RsInt64bind::RsInt64bind(int64_t value, int index) - : RetroBind(INT64, index), mValue(value) {} - -RsBoolBind::RsBoolBind(bool value, int index) - : RetroBind(BOOL, index), mValue(value) {} - -RsBlobBind::RsBlobBind(char* data, uint32_t dataLen, int index) - : RetroBind(BLOB, index), mData(data), mDataLen(dataLen) {} - -bool RsDoubleBind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_double(stm, getIndex(), mValue)); -} - -bool RsStringBind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_text(stm, getIndex(), mValue.c_str(), mValue.size(), SQLITE_TRANSIENT)); -} - -bool RsInt32Bind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_int(stm, getIndex(), mValue)); -} - -bool RsInt64bind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_int64(stm, getIndex(), mValue)); -} - -bool RsBoolBind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_int(stm, getIndex(), mValue ? 1 : 0)); -} - -bool RsBlobBind::bind(sqlite3_stmt* const stm) const -{ - return (SQLITE_OK == sqlite3_bind_blob(stm, getIndex(), mData, mDataLen, SQLITE_TRANSIENT)); -} - diff --git a/libretroshare/src/util/rsdbbind.h b/libretroshare/src/util/rsdbbind.h deleted file mode 100644 index aa41e5b3e..000000000 --- a/libretroshare/src/util/rsdbbind.h +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsbdbind.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013 Christopher Evi-Parker * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSDBBIND_H_ -#define RSDBBIND_H_ - -#include -#include - -#ifdef NO_SQLCIPHER -#include -#else -#include -#endif - -class RetroBind -{ -public: - - enum BindType { BLOB=1, STRING, INT32, INT64, DOUBLE, BOOL } ; - RetroBind(const BindType& type, int index) : mIndex(index), mType(type) {} - - virtual bool bind(sqlite3_stmt* const stm) const = 0; - BindType getType() const { return mType; } - inline int getIndex() const { return mIndex;} - virtual ~RetroBind() {} - -private: - int mIndex; - BindType mType; -}; - -class RsDoubleBind : public RetroBind -{ -public: - RsDoubleBind(double value, int index); - bool bind(sqlite3_stmt* const stm) const; - double mValue; -}; - -class RsStringBind : public RetroBind -{ -public: - RsStringBind(const std::string& value, int index); - bool bind(sqlite3_stmt* const stm) const ; - std::string mValue; -}; - -class RsInt32Bind : public RetroBind -{ -public: - RsInt32Bind(int32_t value, int index); - bool bind(sqlite3_stmt* const stm) const ; - int32_t mValue; -}; - -class RsInt64bind : public RetroBind -{ -public: - RsInt64bind(int64_t value, int index); - bool bind(sqlite3_stmt* const stm) const ; - int64_t mValue; -}; - -class RsBoolBind : public RetroBind -{ -public: - RsBoolBind(bool value, int index); - bool bind(sqlite3_stmt* const stm) const ; - bool mValue; -}; - -class RsBlobBind : public RetroBind -{ -public: - RsBlobBind(char* data, uint32_t dataLen, int index); - bool bind(sqlite3_stmt* const stm) const; - char* mData; - uint32_t mDataLen; -}; - - -#endif /* RSDBBIND_H_ */ diff --git a/libretroshare/src/util/rsdebug.cc b/libretroshare/src/util/rsdebug.cc deleted file mode 100644 index 0a4777ab0..000000000 --- a/libretroshare/src/util/rsdebug.cc +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdebug.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2008 by Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsdebug.h" - -std::ostream &operator<<(std::ostream& out, const std::error_condition& err) -{ - return out << " error: " << err.value() << " " << err.message() - << " category: " << err.category().name(); -} - -std::string rsErrorNotInCategory(int errNum, const std::string& categoryName) -{ - return "Error message for error: " + std::to_string(errNum) + - " not available in category: " + categoryName; -} - - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// All the following lines are DEPRECATED!! - -#include -#include - -#include "util/rsthreads.h" -#include "util/rsdir.h" -#include "util/rstime.h" - -const int RS_DEBUG_STDERR = 1; /* stuff goes to stderr */ -const int RS_DEBUG_LOGFILE = 2; /* stuff goes to logfile */ -const int RS_DEBUG_LOGCRASH = 3; /* minimal logfile stored after crashes */ -const int RS_DEBUG_LOGC_MAX = 100000; /* max length of crashfile log */ -const int RS_DEBUG_LOGC_MIN_SAVE = 100; /* min length of crashfile log */ - -static RsLog::logLvl defaultLevel = RsLog::Warning; -static FILE *ofd = stderr; - -static int debugMode = RS_DEBUG_STDERR; -static int lineCount = 0; -static std::string crashfile; -static int debugTS = 0; - -static RsMutex logMtx("logMtx"); - -int locked_setDebugFile(const char *fname); - -int setDebugCrashMode(const char *cfile) -{ - RsStackMutex stack(logMtx); /******** LOCKED ****************/ - crashfile = cfile; - /* if the file exists - then we crashed, save it */ - FILE *tmpin = RsDirUtil::rs_fopen(crashfile.c_str(), "r"); - if (tmpin) - { - /* see how long it is */ - fseek(tmpin, 0, SEEK_END); - if (ftell(tmpin) > RS_DEBUG_LOGC_MIN_SAVE) - { - std::string crashfile_save = crashfile + "-save"; - fprintf(stderr, "Detected Old Crash File: %s\n", crashfile.c_str()); - fprintf(stderr, "Copying to: %s\n", crashfile_save.c_str()); - - /* go back to the start */ - fseek(tmpin, 0, SEEK_SET); - - FILE *tmpout = RsDirUtil::rs_fopen(crashfile_save.c_str(), "w"); - int da_size = 10240; - char dataarray[da_size]; /* 10k */ - unsigned int da_read = 0; - - if (!tmpout) - { - fprintf(stderr, "Failed to open CrashSave\n"); - fclose(tmpin); - return -1; - } - while(0 != (da_read = fread(dataarray, 1, da_size, tmpin))) - { - if (da_read != fwrite(dataarray, 1, da_read, tmpout)) - { - fprintf(stderr, "Failed writing to CrashSave\n"); - fclose(tmpout); - fclose(tmpin); - return -1; - } - } - fclose(tmpout); - fclose(tmpin); - } - else - { - fprintf(stderr, "Negligable Old CrashLog, ignoring\n"); - fclose(tmpin); - } - } - - if (0 < locked_setDebugFile(crashfile.c_str())) - { - fprintf(stderr, "Switching To CrashLog Mode!\n"); - debugMode = RS_DEBUG_LOGCRASH; - lineCount = 0; - debugTS = time(NULL); - } - return 1; -} - -int setDebugFile(const char *fname) -{ - RsStackMutex stack(logMtx); /******** LOCKED ****************/ - return locked_setDebugFile(fname); -} - -int locked_setDebugFile(const char *fname) -{ - if (NULL != (ofd = RsDirUtil::rs_fopen(fname, "w"))) - { - fprintf(stderr, "Logging redirected to %s\n", fname); - debugMode = RS_DEBUG_LOGFILE; - return 1; - } - else - { - ofd = stderr; - debugMode = RS_DEBUG_STDERR; - fprintf(stderr, "Logging redirect to %s FAILED\n", fname); - return -1; - } -} - -int setOutputLevel(RsLog::logLvl lvl) -{ - RsStackMutex stack(logMtx); /******** LOCKED ****************/ - return defaultLevel = lvl; -} - -void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg) -{ - // skipp when log level is set to 'None' - // NB: when default is set to 'None' the later check will always fail -> no need to check it here - if(info->lvl == RsLog::None) - return; - - bool process = info->lvl == RsLog::Default ? (lvl <= defaultLevel) : lvl <= info->lvl; - if(!process) - return; - - { - RS_STACK_MUTEX(logMtx); - time_t t = time(NULL); // Don't use rstime_t here or ctime break on windows - - if (debugMode == RS_DEBUG_LOGCRASH) - { - if (lineCount > RS_DEBUG_LOGC_MAX) - { - /* restarting logging */ - fprintf(stderr, "Rolling over the CrashLog\n"); - fclose(ofd); - ofd = NULL; - if (0 < locked_setDebugFile(crashfile.c_str())) - { - fprintf(ofd, "Debug CrashLog:"); - fprintf(ofd, " retroShare uptime %ld secs\n", - t-debugTS); - - debugMode = RS_DEBUG_LOGCRASH; - lineCount = 0; - } - else - { - fprintf(stderr, "Rollover Failed!\n"); - } - } - } - - std::string timestr = ctime(&t); - std::string timestr2 = timestr.substr(0,timestr.length()-1); - /* remove the endl */ - fprintf(ofd, "(%s Z: %s, lvl: %u): %s \n", - timestr2.c_str(), info->name.c_str(), (unsigned int)info->lvl, msg.c_str()); - fflush(ofd); - - fprintf(stdout, "(%s Z: %s, lvl: %u): %s \n", - timestr2.c_str(), info->name.c_str(), (unsigned int)info->lvl, msg.c_str()); - lineCount++; - } -} diff --git a/libretroshare/src/util/rsdebug.h b/libretroshare/src/util/rsdebug.h deleted file mode 100644 index 6409e9492..000000000 --- a/libretroshare/src/util/rsdebug.h +++ /dev/null @@ -1,314 +0,0 @@ -/******************************************************************************* - * RetroShare debugging utilities * - * * - * Copyright (C) 2004-2008 Robert Fernie * - * Copyright (C) 2019-2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#ifdef __ANDROID__ -# include -#else // def __ANDROID__ -# include -# include -# include -#endif // def __ANDROID__ - - -#include "util/rsjson.h" - - -#ifdef __ANDROID__ -enum class RsLoggerCategories -{ - DEBUG = ANDROID_LOG_DEBUG, - INFO = ANDROID_LOG_INFO, - WARNING = ANDROID_LOG_WARN, - ERROR = ANDROID_LOG_ERROR, - FATAL = ANDROID_LOG_FATAL -}; -#else // def __ANDROID__ -enum class RsLoggerCategories -{ - DEBUG = 'D', - INFO = 'I', - WARNING = 'W', - ERROR = 'E', - FATAL = 'F' -}; -#endif // def __ANDROID__ - - -/** Stream helper for std::error_condition */ -std::ostream &operator<<(std::ostream& out, const std::error_condition& err); - -/** Provide unkown error message for all error categories to avoid duplicating - * the message around */ -std::string rsErrorNotInCategory(int errNum, const std::string& categoryName); - - -template -struct t_RsLogger : std::ostringstream -{ - t_RsLogger() { setPrefix(); } - ~t_RsLogger() { flush(); } - - /** Offer variadic style, this doesn't supports things like std::endl as - * paramether but when used toghether with conditional debugging macros - * reduces binary size as paramethers of suppressed calls are not evaluated - * and literally disappear in preprocessing fase @see RsDbg */ - template - explicit inline t_RsLogger(Args&&... args) - { - setPrefix(); - - /* Combine initializer list and comma operator so the compiler unpack - * template arguments and feed our own stream without recursion - * see https://stackoverflow.com/a/27375675 */ - using expander = int[]; - (void) expander {0, (void((*this) << std::forward(args)), 0)...}; - } - - /** Dump buffer stream to log */ - void flush() - { -#ifdef __ANDROID__ - __android_log_write( - static_cast(CATEGORY), - "RetroShare", str().c_str() ); -#else // def __ANDROID__ - (*this) << std::endl; - std::cerr << str(); -#endif // def __ANDROID__ - str() = ""; - } - -private: -#ifdef __ANDROID__ - inline void setPrefix() {} -#else // def __ANDROID__ - void setPrefix() - { - using namespace std::chrono; - const auto now = system_clock::now(); - const auto sec = time_point_cast(now); - const auto msec = duration_cast(now - sec); - (*this) << static_cast(CATEGORY) << " " - << sec.time_since_epoch().count() << "." - << std::setfill('0') << std::setw(3) << msec.count() << " "; - } -#endif // def __ANDROID__ -}; - - -/** - * Comfortable debug message logging, supports both variadic style and chaining - * style like std::cerr. - * Can be easly and selectively disabled at compile time. - * To reduce generated binary size and performance impact when debugging is - * disabled without too many \#ifdef around the code combining the variadic - * style with the leveled debugging macros is the way to go. - * - * To selectively debug your file you just need to include the header of desired - * debugging level (0 to 4) -@code{.cpp} -#include "util/rsdebuglevel2.h" -@endcode - * Then where you want to print debug messages use -@code{.cpp} -RS_DBG0("Hello 0 ", "my debug ", my_variable) << " message " << variable2; -RS_DBG1("Hello 1 ", "my debug ", my_variable) << " message " << variable2; -RS_DBG2("Hello 2 ", "my debug ", my_variable) << " message " << variable2; -RS_DBG3("Hello 3 ", "my debug ", my_variable) << " message " << variable2; -RS_DBG4("Hello 4 ", "my debug ", my_variable) << " message " << variable2; -@endcode - * To change the debugging level just include a different level header like - * `util/rsdebuglevel1.h`, debug messages with lower or equal level then the - * included header will be printed, the others will not. - * Remember then on messages with debug level higher then the included the - * paramethers you pass as macro arguments (variadic style) will disappear in - * the preprocessing phase, so their evaluation will not be included in the - * final binary and not executed at runtime, instead the paramether passed with - * `<<` (chaining style) will be in the compiled binary and evaluated at runtime - * even if are not printed, due to how C++ is made it is not possible to avoid - * this, so we suggest to use variadic style for debug messages. - */ -using RsDbg = t_RsLogger; -#define RS_DBG(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -/** - * Comfortable log information reporting helper, supports chaining like - * std::cerr. - * To report an information message you can just write: -@code{.cpp} -RsInfo() << __PRETTY_FUNCTION__ << "My information message" << std::cerr; -@endcode - */ -using RsInfo = t_RsLogger; -#define RS_INFO(...) RsInfo(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -/// Similar to @see RsInfo but for warning messages -using RsWarn = t_RsLogger; -#define RS_WARN(...) RsWarn(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -/// Similar to @see RsInfo but for error messages -using RsErr = t_RsLogger; -#define RS_ERR(...) RsErr(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -/** Similar to @see RsInfo but for fatal errors (the ones which cause RetroShare - * to terminate) messages */ -using RsFatal = t_RsLogger; -#define RS_FATAL(...) RsFatal(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - - -/** - * Keeps compatible syntax with RsDbg but explicitely do nothing in a way that - * any modern compiler should be smart enough to optimize out all the function - * calls. - */ -struct RsNoDbg -{ - inline RsNoDbg() = default; - template inline explicit RsNoDbg(Args...) {} - - /** This match most of the types, but might be not enough for templated - * types */ - template - inline RsNoDbg& operator<<(const T&) { return *this; } - - /// needed for manipulators and things like std::endl - inline RsNoDbg& operator<<(std::ostream& (*/*pf*/)(std::ostream&)) - { return *this; } - - /** Do nothing. Just for code compatibility with other logging classes */ - inline void flush() {} -}; - - - -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -/// All the following lines are DEPRECATED!! - -#include "util/rsdeprecate.h" - -/** - * Concatenate preprocessor tokens A and B without expanding macro definitions - * (however, if invoked from a macro, macro arguments are expanded). - */ -#define RS_CONCAT_MACRO_NX(A, B) A ## B - -/// Concatenate preprocessor tokens A and B after macro-expanding them. -#define RS_CONCAT_MACRO(A, B) RS_CONCAT_MACRO_NX(A, B) - -/** - * Set local context debug level. - * Avoid copy pasting boilerplate code around @see RsDbg for usage details - */ -#define RS_SET_CONTEXT_DEBUG_LEVEL(level) \ - RS_CONCAT_MACRO(RS_SET_CONTEXT_DEBUG_LEVEL, level) - -// A bunch of boilerplate, but just in one place -#define RS_SET_CONTEXT_DEBUG_LEVEL0 \ - using Dbg1 RS_DEPRECATED_FOR(RS_DBG1) = RsNoDbg; \ - using Dbg2 RS_DEPRECATED_FOR(RS_DBG2) = RsNoDbg; \ - using Dbg3 RS_DEPRECATED_FOR(RS_DBG3) = RsNoDbg; \ - using Dbg4 RS_DEPRECATED_FOR(RS_DBG4) = RsNoDbg; -#define RS_SET_CONTEXT_DEBUG_LEVEL1 \ - using Dbg1 RS_DEPRECATED_FOR(RS_DBG1) = RsDbg; \ - using Dbg2 RS_DEPRECATED_FOR(RS_DBG2) = RsNoDbg; \ - using Dbg3 RS_DEPRECATED_FOR(RS_DBG3) = RsNoDbg; \ - using Dbg4 RS_DEPRECATED_FOR(RS_DBG4) = RsNoDbg; -#define RS_SET_CONTEXT_DEBUG_LEVEL2 \ - using Dbg1 RS_DEPRECATED_FOR(RS_DBG1) = RsDbg; \ - using Dbg2 RS_DEPRECATED_FOR(RS_DBG2) = RsDbg; \ - using Dbg3 RS_DEPRECATED_FOR(RS_DBG3) = RsNoDbg; \ - using Dbg4 RS_DEPRECATED_FOR(RS_DBG4) = RsNoDbg; -#define RS_SET_CONTEXT_DEBUG_LEVEL3 \ - using Dbg1 RS_DEPRECATED_FOR(RS_DBG1) = RsDbg; \ - using Dbg2 RS_DEPRECATED_FOR(RS_DBG2) = RsDbg; \ - using Dbg3 RS_DEPRECATED_FOR(RS_DBG3) = RsDbg; \ - using Dbg4 RS_DEPRECATED_FOR(RS_DBG4) = RsNoDbg; -#define RS_SET_CONTEXT_DEBUG_LEVEL4 \ - using Dbg1 RS_DEPRECATED_FOR(RS_DBG1) = RsDbg; \ - using Dbg2 RS_DEPRECATED_FOR(RS_DBG2) = RsDbg; \ - using Dbg3 RS_DEPRECATED_FOR(RS_DBG3) = RsDbg; \ - using Dbg4 RS_DEPRECATED_FOR(RS_DBG4) = RsDbg; - -namespace RsLog { - enum RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") logLvl { - None = -1, - Default = 0, - Alert = 1, - Error = 3, - Warning = 5, - Debug_Alert = 6, - Debug_Basic = 8, - Debug_All = 10 - }; - - // this struct must be provided by the caller (to rslog()) - struct RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") logInfo { - // module specific log lvl - logLvl lvl; - // module name (displayed in log) - const std::string name; - }; -} - -RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") -int setDebugCrashMode(const char *cfile); - -RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") -int setDebugFile(const char *fname); - -RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") -int setOutputLevel(RsLog::logLvl lvl); - -RS_DEPRECATED_FOR("RsErr, RsDbg, RsNoDbg") -void rslog(const RsLog::logLvl lvl, RsLog::logInfo *info, const std::string &msg); - - -/* - * retaining old #DEFINES and functions for backward compatibility. - */ - -#define RSL_NONE RsLog::None -#define RSL_ALERT RsLog::Alert -#define RSL_ERROR RsLog::Error -#define RSL_WARNING RsLog::Warning -#define RSL_DEBUG_ALERT RsLog::Debug_Alert -#define RSL_DEBUG_BASIC RsLog::Debug_Basic -#define RSL_DEBUG_ALL RsLog::Debug_Basic - -//int pqioutput(unsigned int lvl, int zone, std::string msg); -#define pqioutput rslog - -#define PQL_NONE RSL_NONE -#define PQL_ALERT RSL_ALERT -#define PQL_ERROR RSL_ERROR -#define PQL_WARNING RSL_WARNING -#define PQL_DEBUG_ALERT RSL_DEBUG_ALERT -#define PQL_DEBUG_BASIC RSL_DEBUG_BASIC -#define PQL_DEBUG_ALL RSL_DEBUG_ALL diff --git a/libretroshare/src/util/rsdebuglevel0.h b/libretroshare/src/util/rsdebuglevel0.h deleted file mode 100644 index 5c68ec0be..000000000 --- a/libretroshare/src/util/rsdebuglevel0.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * RetroShare debugging level * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// #pragma once // This is commented out on purpose! - -#include - -#undef RS_DEBUG_LEVEL -#define RS_DEBUG_LEVEL 0 - -#undef RS_DBG0 -#define RS_DBG0(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG1 -#define RS_DBG1(...) RsNoDbg("") - -#undef RS_DBG2 -#define RS_DBG2(...) RsNoDbg("") - -#undef RS_DBG3 -#define RS_DBG3(...) RsNoDbg("") - -#undef RS_DBG4 -#define RS_DBG4(...) RsNoDbg("") diff --git a/libretroshare/src/util/rsdebuglevel1.h b/libretroshare/src/util/rsdebuglevel1.h deleted file mode 100644 index 7e968e402..000000000 --- a/libretroshare/src/util/rsdebuglevel1.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * RetroShare debugging level * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// #pragma once // This is commented out on purpose! - -#include - -#undef RS_DEBUG_LEVEL -#define RS_DEBUG_LEVEL 1 - -#undef RS_DBG0 -#define RS_DBG0(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG1 -#define RS_DBG1(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG2 -#define RS_DBG2(...) RsNoDbg() - -#undef RS_DBG3 -#define RS_DBG3(...) RsNoDbg() - -#undef RS_DBG4 -#define RS_DBG4(...) RsNoDbg() diff --git a/libretroshare/src/util/rsdebuglevel2.h b/libretroshare/src/util/rsdebuglevel2.h deleted file mode 100644 index 2cbf1a224..000000000 --- a/libretroshare/src/util/rsdebuglevel2.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * RetroShare debugging level * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// #pragma once // This is commented out on purpose! - -#include - -#undef RS_DEBUG_LEVEL -#define RS_DEBUG_LEVEL 2 - -#undef RS_DBG0 -#define RS_DBG0(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG1 -#define RS_DBG1(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG2 -#define RS_DBG2(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG3 -#define RS_DBG3(...) RsNoDbg() - -#undef RS_DBG4 -#define RS_DBG4(...) RsNoDbg() diff --git a/libretroshare/src/util/rsdebuglevel3.h b/libretroshare/src/util/rsdebuglevel3.h deleted file mode 100644 index 53bcbfe9f..000000000 --- a/libretroshare/src/util/rsdebuglevel3.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * RetroShare debugging level * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// #pragma once // This is commented out on purpose! - -#include - -#undef RS_DEBUG_LEVEL -#define RS_DEBUG_LEVEL 3 - -#undef RS_DBG0 -#define RS_DBG0(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG1 -#define RS_DBG1(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG2 -#define RS_DBG2(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG3 -#define RS_DBG3(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG4 -#define RS_DBG4(...) RsNoDbg() diff --git a/libretroshare/src/util/rsdebuglevel4.h b/libretroshare/src/util/rsdebuglevel4.h deleted file mode 100644 index f8697cad8..000000000 --- a/libretroshare/src/util/rsdebuglevel4.h +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * RetroShare debugging level * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// #pragma once // This is commented out on purpose! - -#include - -#undef RS_DEBUG_LEVEL -#define RS_DEBUG_LEVEL 4 - -#undef RS_DBG0 -#define RS_DBG0(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG1 -#define RS_DBG1(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG2 -#define RS_DBG2(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG3 -#define RS_DBG3(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) - -#undef RS_DBG4 -#define RS_DBG4(...) RsDbg(__PRETTY_FUNCTION__, " ", __VA_ARGS__) diff --git a/libretroshare/src/util/rsdeprecate.h b/libretroshare/src/util/rsdeprecate.h deleted file mode 100644 index 560f91c44..000000000 --- a/libretroshare/src/util/rsdeprecate.h +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdebug.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2016 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -# define RS_DEPRECATED __attribute__((__deprecated__)) -#elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# define RS_DEPRECATED __declspec(deprecated) -#else -# define RS_DEPRECATED -#endif - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -# define RS_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) -#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) -# define RS_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) -#else -# define RS_DEPRECATED_FOR(f) RS_DEPRECATED -#endif diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc deleted file mode 100644 index 8556b8198..000000000 --- a/libretroshare/src/util/rsdir.cc +++ /dev/null @@ -1,1372 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdir.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -// Includes for directory creation. -#include -#include -#include -#include - -#include "util/rsdir.h" -#include "util/rsstring.h" -#include "util/rsrandom.h" -#include "util/rstime.h" -#include "util/rsmemory.h" -#include "util/folderiterator.h" -#include "retroshare/rstypes.h" -#include "retroshare/rsnotify.h" -#include "rsthreads.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#if defined(WIN32) || defined(__CYGWIN__) -#include "util/rsstring.h" -#include "wtypes.h" -#include -#else -#include -#endif - -#ifndef __GLIBC__ -#define canonicalize_file_name(p) realpath(p, NULL) -#endif - -/**** - * #define RSDIR_DEBUG 1 - ****/ - -std::string RsDirUtil::getTopDir(const std::string& dir) -{ - std::string top; - - /* find the subdir: [/][dir1.../][/] - */ - int i,j; - int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--) ; - for(i = j; (i > 0) && (dir[i] != '/'); i--) ; - - if (dir[i] == '/') - i++; - - for(; i <= j; i++) - { - top += dir[i]; - } - - return top; -} - -const char *RsDirUtil::scanf_string_for_uint(int bytes) -{ - const char *strgs[3] = { "%u","%lu","%llu" } ; - - //std::cerr << "RsDirUtil::scanf_string_for_uint(): returning for bytes=" << bytes << std::endl; - - if(sizeof(unsigned int) == bytes) - return strgs[0] ; - if(sizeof(long unsigned int) == bytes) - return strgs[1] ; - if(sizeof(long long unsigned int) == bytes) - return strgs[2] ; - - std::cerr << "RsDirUtil::scanf_string_for_uint(): no corresponding scan string for "<< bytes << " bytes. This will probably cause inconsistencies." << std::endl; - return strgs[0] ; -} - -bool RsDirUtil::splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file) -{ - int i = full_path.rfind('/', full_path.size()-1); - - if(i == full_path.size()-1) // '/' not found! - { - file = full_path ; - dir = "." ; - return true ; - } - - dir.assign(full_path,0,i+1) ; - file.assign(full_path,i+1,full_path.size()) ; - - return true ; -} - -void RsDirUtil::removeTopDir(const std::string& dir, std::string& path) -{ - path.clear(); - - /* remove the subdir: [/][dir1.../][/] - */ - int j = dir.find_last_not_of('/'); - int i = dir.rfind('/', j); - - /* remove any more slashes */ - if (i > 0) - { - i = dir.find_last_not_of('/', i); - } - - if (i > 0) - { - path.assign(dir, 0, i + 1); - } -} - -std::string RsDirUtil::getRootDir(const std::string& dir) -{ - std::string root; - - /* find the subdir: [/]root[/...] - */ - int i,j; - int len = dir.length(); - for(i = 0; (i < len) && (dir[i] == '/'); i++) ; - for(j = i; (j < len) && (dir[j] != '/'); j++) ; - if (i == j) - return root; /* empty */ - for(; i < j; i++) - { - root += dir[i]; - } - return root; -} - -std::string RsDirUtil::removeRootDir(const std::string& path) -{ - unsigned int i, j; - unsigned int len = path.length(); - std::string output; - - /* chew leading '/'s */ - for(i = 0; (i < len) && (path[i] == '/'); i++) ; - if (i == len) - return output; /* empty string */ - - for(j = i; (j < len) && (path[j] != '/'); j++) ; /* run to next '/' */ - for(; (j < len) && (path[j] == '/'); j++) ; /* chew leading '/'s */ - - for(; j < len; j++) - { - output += path[j]; - } - - return output; -} - -std::string RsDirUtil::removeRootDirs(const std::string& path, const std::string& root) -{ - /* too tired */ - std::string notroot; - - unsigned int i = 0, j = 0; - - /* catch empty data */ - if ((root.length() < 1) || (path.length() < 1)) - return notroot; - - if ((path[0] == '/') && (root[0] != '/')) - { - i++; - } - - for(; (i < path.length()) && (j < root.length()) && (path[i] == root[j]); i++, j++) ; - - /* should have consumed root. */ - if (j == root.length()) - { - //std::cerr << "matched root!" << std::endl; - } - else - { - //std::cerr << "failed i: " << i << ", j: " << j << std::endl; - //std::cerr << "root: " << root << " path: " << path << std::endl; - return notroot; - } - - if (path[i] == '/') - { - i++; - } - - for(; i < path.length(); i++) - { - notroot += path[i]; - } - - //std::cerr << "Found NotRoot: " << notroot << std::endl; - - return notroot; -} - - - -int RsDirUtil::breakupDirList(const std::string& path, - std::list &subdirs) -{ - int start = 0; - unsigned int i; - for(i = 0; i < path.length(); i++) - { - if (path[i] == '/') - { - if (i - start > 0) - { - subdirs.push_back(path.substr(start, i-start)); - } - start = i+1; - } - } - // get the final one. - if (i - start > 0) - { - subdirs.push_back(path.substr(start, i-start)); - } - return 1; -} - -/**** Copied and Tweaked from ftcontroller ***/ -bool RsDirUtil::fileExists(const std::string& filename) -{ -#ifdef WINDOWS_SYS - std::wstring wfilename; - librs::util::ConvertUtf8ToUtf16(filename, wfilename); - return ( _waccess( wfilename.c_str(), F_OK ) != -1 ); -#else - return ( access( filename.c_str(), F_OK ) != -1 ); -#endif -} - -bool RsDirUtil::moveFile(const std::string& source,const std::string& dest) -{ - Dbg3() << __PRETTY_FUNCTION__<< " source: " << source - << " dest: " << dest << std::endl; - - std::string dest_dir ; - std::string dest_file ; - - splitDirFromFile(dest, dest_dir, dest_file); - - if(!checkDirectory(dest_dir)) - { - if(!std::filesystem::create_directories(dest_dir)) - { - RsErr() << __PRETTY_FUNCTION__ << " failure creating directory: " - << dest_dir << std::endl; - return false; - } - } - - // First try a rename - if(renameFile(source,dest)) - { - Dbg3() << __PRETTY_FUNCTION__ << " plain rename worked" << std::endl; - return true; - } - - /* If not, try to copy. The src and dest probably belong to different file - * systems */ - if(!copyFile(source,dest)) - { - RsErr() << __PRETTY_FUNCTION__ << " failure copying file" << std::endl; - return false; - } - - // delete the original - if(!removeFile(source)) - { - RsErr() << __PRETTY_FUNCTION__ << " failure deleting original file" - << std::endl; - return false; - } - - return true; -} - -bool RsDirUtil::removeFile(const std::string& filename) -{ -#ifdef CONTROL_DEBUG - std::cerr << "deleting original file " << source << std::endl ; -#endif - -#ifdef WINDOWS_SYS - std::wstring filenameW; - librs::util::ConvertUtf8ToUtf16(filename,filenameW); - - if(0 != DeleteFileW(filenameW.c_str())) -#else - if(0 == remove(filename.c_str())) -#endif - return true ; - else - { - std::cerr << "(EE) File erase error while removing file " << filename << ". Read-only file system ?" << std::endl; - return false ; - } -} - -/**** Copied and Tweaked from ftcontroller ***/ -bool RsDirUtil::copyFile(const std::string& source,const std::string& dest) -{ -#ifdef WINDOWS_SYS - std::wstring sourceW; - std::wstring destW; - librs::util::ConvertUtf8ToUtf16(source,sourceW); - librs::util::ConvertUtf8ToUtf16(dest,destW); - - return (CopyFileW(sourceW.c_str(), destW.c_str(), FALSE) != 0); - -#else - FILE *in = fopen64(source.c_str(),"rb") ; - - if(in == NULL) - { - return false ; - } - - FILE *out = fopen64(dest.c_str(),"wb") ; - - if(out == NULL) - { - fclose (in); - return false ; - } - - size_t s=0; - size_t T=0; - - static const int BUFF_SIZE = 10485760 ; // 10 MB buffer to speed things up. - RsTemporaryMemory buffer(BUFF_SIZE) ; - - if(!buffer) - { - fclose(in) ; - fclose(out) ; - return false ; - } - - bool bRet = true; - - while( (s = fread(buffer,1,BUFF_SIZE,in)) > 0) - { - size_t t = fwrite(buffer,1,s,out) ; - T += t ; - - if(t != s) - { - bRet = false ; - break; - } - } - - fclose(in) ; - fclose(out) ; - - return bRet ; - -#endif - -} - - -bool RsDirUtil::checkFile(const std::string& filename,uint64_t& file_size,bool disallow_empty_file) -{ - int val; - mode_t st_mode; -#ifdef WINDOWS_SYS - std::wstring wfilename; - librs::util::ConvertUtf8ToUtf16(filename, wfilename); - struct _stat buf; - val = _wstat(wfilename.c_str(), &buf); - st_mode = buf.st_mode; -#else - struct stat64 buf; - val = stat64(filename.c_str(), &buf); - st_mode = buf.st_mode; -#endif - if (val == -1) - { -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkFile() "; - std::cerr << filename << " doesn't exist" << std::endl; -#endif - return false; - } - else if (!S_ISREG(st_mode)) - { - // Some other type - error. -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkFile() "; - std::cerr << filename << " is not a Regular File" << std::endl; -#endif - return false; - } - - file_size = buf.st_size ; - - if(disallow_empty_file && buf.st_size == 0) - return false ; - - return true; -} - - -bool RsDirUtil::checkDirectory(const std::string& dir) -{ - int val; - mode_t st_mode; -#ifdef WINDOWS_SYS - std::wstring wdir; - librs::util::ConvertUtf8ToUtf16(dir, wdir); - struct _stat buf; - val = _wstat(wdir.c_str(), &buf); - st_mode = buf.st_mode; -#else - struct stat buf; - val = stat(dir.c_str(), &buf); - st_mode = buf.st_mode; -#endif - if (val == -1) - { -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkDirectory() "; - std::cerr << dir << " doesn't exist" << std::endl; -#endif - return false; - } - else if (!S_ISDIR(st_mode)) - { - // Some other type - error. -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkDirectory() "; - std::cerr << dir << " is not Directory" << std::endl; -#endif - return false; - } - return true; -} - - -bool RsDirUtil::checkCreateDirectory(const std::string& dir) -{ - Dbg3() << __PRETTY_FUNCTION__ << " " << dir << std::endl; - -#ifdef WINDOWS_SYS - std::wstring wdir; - librs::util::ConvertUtf8ToUtf16(dir, wdir); - _WDIR *direc = _wopendir(wdir.c_str()); - if (!direc) -#else - DIR *direc = opendir(dir.c_str()); - if (!direc) -#endif - { - // directory don't exist. create. -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // UNIX - if (-1 == mkdir(dir.c_str(), 0777)) -#else // WIN - if (-1 == _wmkdir(wdir.c_str())) -#endif -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - { -#ifdef RSDIR_DEBUG - std::cerr << "check_create_directory() Fatal Error et oui--"; - std::cerr < &keepFiles) -{ - for(librs::util::FolderIterator it(cleandir,false);it.isValid();it.next()) - if(it.file_type() == librs::util::FolderIterator::TYPE_FILE && (keepFiles.end() == std::find(keepFiles.begin(), keepFiles.end(), it.file_name()))) - remove( (cleandir + "/" + it.file_name()).c_str() ) ; - - return true; -} - -/* slightly nicer helper function */ -bool RsDirUtil::hashFile(const std::string& filepath, - std::string &name, RsFileHash &hash, uint64_t &size) -{ - if (getFileHash(filepath, hash, size)) - { - /* extract file name */ - name = RsDirUtil::getTopDir(filepath); - return true; - } - return false; -} - - -#include -#include - -/* Function to hash, and get details of a file */ -bool RsDirUtil::getFileHash(const std::string& filepath, RsFileHash &hash, uint64_t &size, RsThread *thread /*= NULL*/) -{ - FILE *fd; - - if (NULL == (fd = RsDirUtil::rs_fopen(filepath.c_str(), "rb"))) - return false; - - int len; - SHA_CTX *sha_ctx = new SHA_CTX; - unsigned char sha_buf[SHA_DIGEST_LENGTH]; - - static const uint32_t HASH_BUFFER_SIZE = 1024*1024*10 ;// allocate a 10MB buffer. Too small a buffer will cause multiple HD hits and slow down the hashing process. - RsTemporaryMemory gblBuf(HASH_BUFFER_SIZE) ; - //unsigned char gblBuf[512]; - - /* determine size */ - fseeko64(fd, 0, SEEK_END); - size = ftello64(fd); - fseeko64(fd, 0, SEEK_SET); - - /* check if thread is running */ - bool isRunning = thread ? thread->isRunning() : true; - int runningCheckCount = 0; - - SHA1_Init(sha_ctx); - while(isRunning && (len = fread(gblBuf,1, HASH_BUFFER_SIZE, fd)) > 0) - { - SHA1_Update(sha_ctx, gblBuf, len); - - if (thread && ++runningCheckCount > (10 * 1024)) { - /* check all 50MB if thread is running */ - isRunning = thread->isRunning(); - runningCheckCount = 0; - } - } - - /* Thread has ended */ - if (isRunning == false) - { - delete sha_ctx; - fclose(fd); - return false; - } - - /* reading failed for some reason */ - if (ferror(fd)) - { - delete sha_ctx; - fclose(fd); - return false; - } - - SHA1_Final(&sha_buf[0], sha_ctx); - - hash = Sha1CheckSum(sha_buf); - - delete sha_ctx; - fclose(fd); - return true; -} - -/* Function to hash, and get details of a file */ -Sha1CheckSum RsDirUtil::sha1sum(const unsigned char *data, uint32_t size) -{ - SHA_CTX sha_ctx ; - - if(SHA_DIGEST_LENGTH != 20) - throw std::runtime_error("Warning: can't compute Sha1Sum with sum size != 20") ; - - SHA1_Init(&sha_ctx); - while(size > 512) - { - SHA1_Update(&sha_ctx, data, 512); - data = &data[512] ; - size -= 512 ; - } - SHA1_Update(&sha_ctx, data, size); - - unsigned char sha_buf[SHA_DIGEST_LENGTH]; - SHA1_Final(&sha_buf[0], &sha_ctx); - - return Sha1CheckSum(sha_buf) ; -} - -Sha256CheckSum RsDirUtil::sha256sum(const unsigned char *data, uint32_t size) -{ - SHA256_CTX sha_ctx ; - - if(SHA256_DIGEST_LENGTH != 32) - throw std::runtime_error("Warning: can't compute Sha2561Sum with sum size != 32") ; - - SHA256_Init(&sha_ctx); - while(size > 512) - { - SHA256_Update(&sha_ctx, data, 512); - data = &data[512] ; - size -= 512 ; - } - SHA256_Update(&sha_ctx, data, size); - - unsigned char sha_buf[SHA256_DIGEST_LENGTH]; - SHA256_Final(&sha_buf[0], &sha_ctx); - - return Sha256CheckSum(sha_buf) ; -} -bool RsDirUtil::saveStringToFile(const std::string &file, const std::string &str) -{ - std::ofstream out(file.c_str(), std::ios_base::out | std::ios_base::binary); - if(!out.is_open()) - { - std::cerr << "RsDirUtil::saveStringToFile() ERROR: can't open file " << file << std::endl; - return false; - } - out << str; - return true; -} - -bool RsDirUtil::loadStringFromFile(const std::string &file, std::string &str) -{ - std::ifstream in(file.c_str(), std::ios_base::in | std::ios_base::binary); - if(!in.is_open()) - { - std::cerr << "RsDirUtil::loadStringFromFile() ERROR: can't open file " << file << std::endl; - return false; - } - std::stringstream buffer; - buffer << in.rdbuf(); - str = buffer.str(); - return true; -} - -bool RsDirUtil::renameFile(const std::string& from, const std::string& to) -{ - int loops = 0; - -#ifdef WINDOWS_SYS - std::wstring f; - librs::util::ConvertUtf8ToUtf16(from, f); - std::wstring t; - librs::util::ConvertUtf8ToUtf16(to, t); - - while (!MoveFileEx(f.c_str(), t.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) -#else - std::string f(from),t(to) ; - - while (rename(from.c_str(), to.c_str()) < 0) -#endif - { -#ifdef WIN32 - if (GetLastError() != ERROR_ACCESS_DENIED) -#else - if (errno != EACCES) -#endif - /* set errno? */ - return false ; - rstime::rs_usleep(100 * 1000); // 100 msec - - if (loops >= 30) - return false ; - - loops++; - } - - return true ; -} - -#ifdef UNUSED_CODE -// not used -bool RsDirUtil::createBackup (const std::string& sFilename, unsigned int nCount) -{ -#ifdef WINDOWS_SYS - if (GetFileAttributesA (sFilename.c_str ()) == -1) { - // file doesn't exist - return true; - } - - // search last backup - int nLast; - for (nLast = nCount; nLast >= 1; nLast--) { - std::ostringstream sStream; // please do not use std::ostringstream - sStream << sFilename << nLast << ".bak"; - - if (GetFileAttributesA (sStream.str ().c_str ()) != -1) { - break; - } - } - - // delete max backup - if (nLast == nCount) { - std::ostringstream sStream; // please do not use std::ostringstream - sStream << sFilename << nCount << ".bak"; - if (DeleteFileA (sStream.str ().c_str ()) == FALSE) { - getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File delete error", "Error while deleting file " + sStream.str ()); - return false; - } - nLast--; - } - - // rename backups - for (int nIndex = nLast; nIndex >= 1; nIndex--) { - std::ostringstream sStream; // please do not use std::ostringstream - sStream << sFilename << nIndex << ".bak"; - std::ostringstream sStream1; // please do not use std::ostringstream - sStream1 << sFilename << nIndex + 1 << ".bak"; - - if (renameFile (sStream.str (), sStream1.str ()) == false) { - getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + sStream.str () + " to " + sStream1.str ()); - return false; - } - } - - // copy backup - std::ostringstream sStream; // please do not use std::ostringstream - sStream << sFilename << 1 << ".bak"; - if (CopyFileA (sFilename.c_str (), sStream.str ().c_str (), FALSE) == FALSE) { - getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + sFilename + " to " + sStream.str ()); - return false; - } -#else - /* remove unused parameter warnings */ - (void) sFilename; - (void) nCount; -#endif - return true; -} -#endif - -FILE *RsDirUtil::rs_fopen(const char* filename, const char* mode) -{ -#ifdef WINDOWS_SYS - std::wstring wfilename; - librs::util::ConvertUtf8ToUtf16(filename, wfilename); - std::wstring wmode; - librs::util::ConvertUtf8ToUtf16(mode, wmode); - - return _wfopen(wfilename.c_str(), wmode.c_str()); -#else - return fopen64(filename, mode); -#endif -} - -std::string RsDirUtil::convertPathToUnix(std::string path) -{ - for (unsigned int i = 0; i < path.length(); i++) - { - if (path[i] == '\\') - path[i] = '/'; - } - return path; -} - -std::string RsDirUtil::makePath(const std::string &path1, const std::string &path2) -{ - std::string path = path1; - - if (path.empty() == false && *path.rbegin() != '/') { - path += "/"; - } - path += path2; - - return path; -} - -int RsDirUtil::createLockFile(const std::string& lock_file_path, rs_lock_handle_t &lock_handle) -{ - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS -// Suspended. The user should make sure he's not already using the file descriptor. -// if(lock_handle != -1) -// close(lock_handle); - - // open the file in write mode, create it if necessary, truncate it (it should be empty) - lock_handle = open(lock_file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - if(lock_handle == -1) - { - std::cerr << "Could not open lock file " << lock_file_path.c_str() << std::flush; - perror(NULL); - return 2; - } - - // see "man fcntl" for the details, in short: non blocking lock creation on the whole file contents - struct flock lockDetails; - lockDetails.l_type = F_WRLCK; - lockDetails.l_whence = SEEK_SET; - lockDetails.l_start = 0; - lockDetails.l_len = 0; - - if(fcntl(lock_handle, F_SETLK, &lockDetails) == -1) - { - int fcntlErr = errno; - std::cerr << "Could not request lock on file " << lock_file_path.c_str() << std::flush; - perror(NULL); - - // there's no lock so let's release the file handle immediately - close(lock_handle); - lock_handle = -1; - - if(fcntlErr == EACCES || fcntlErr == EAGAIN) - return 1; - else - return 2; - } - - // Write to lock file our pid - std::string ourPID = std::to_string(::getpid()); - write(lock_handle, ourPID.c_str(), sizeof(char)*ourPID.size() ); - - return 0; -#else -// Suspended. The user should make sure he's not already using the file descriptor. -// -// if (lock_handle) { -// CloseHandle(lock_handle); -// } - - std::wstring wlockFile; - librs::util::ConvertUtf8ToUtf16(lock_file_path, wlockFile); - - // open the file in write mode, create it if necessary - lock_handle = CreateFile(wlockFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - - if (lock_handle == INVALID_HANDLE_VALUE) - { - DWORD lasterror = GetLastError(); - - std::cerr << "Could not open lock file " << lock_file_path.c_str() << std::endl; - std::cerr << "Last error: " << lasterror << std::endl << std::flush; - perror(NULL); - - if (lasterror == ERROR_SHARING_VIOLATION || lasterror == ERROR_ACCESS_DENIED) - return 1; - - return 2; - } - - return 0; -#endif - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -} - -void RsDirUtil::releaseLockFile(rs_lock_handle_t lockHandle) -{ - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - if(lockHandle != -1) - { - close(lockHandle); - lockHandle = -1; - } -#else - if(lockHandle) - { - CloseHandle(lockHandle); - lockHandle = 0; - } -#endif - /******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -} - -RsStackFileLock::RsStackFileLock(const std::string& file_path) -{ - while(RsDirUtil::createLockFile(file_path,_file_handle)) - { - std::cerr << "Cannot acquire file lock " << file_path << ", waiting 1 sec." << std::endl; - rstime::rs_usleep(1 * 1000 * 1000) ; // 1 sec - } -#ifdef RSDIR_DEBUG - std::cerr << "Acquired file handle " << _file_handle << ", lock file:" << file_path << std::endl; -#endif -} -RsStackFileLock::~RsStackFileLock() -{ - RsDirUtil::releaseLockFile(_file_handle) ; -#ifdef RSDIR_DEBUG - std::cerr << "Released file lock with handle " << _file_handle << std::endl; -#endif -} - -#if 0 // NOT ENABLED YET! -/************************* WIDE STRING ***************************/ -/************************* WIDE STRING ***************************/ -/************************* WIDE STRING ***************************/ - -std::wstring RsDirUtil::getWideTopDir(std::wstring dir) -{ - std::wstring top; - - /* find the subdir: [/][dir1.../][/] - */ - int i,j; - int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--); - for(i = j; (i > 0) && (dir[i] != '/'); i--); - - if (dir[i] == '/') - i++; - - for(; i <= j; i++) - { - top += dir[i]; - } - - return top; -} - -std::wstring RsDirUtil::removeWideTopDir(std::wstring dir) -{ - std::wstring rest; - - /* remove the subdir: [/][dir1.../][/] - */ - int i,j; - int len = dir.length(); - for(j = len - 1; (j > 0) && (dir[j] == '/'); j--); - for(i = j; (i >= 0) && (dir[i] != '/'); i--); - - /* remove any more slashes */ - for(; (i >= 0) && (dir[i] == '/'); i--); - - for(j = 0; j <= i; j++) - { - rest += dir[j]; - } - - return rest; -} - -std::wstring RsDirUtil::getWideRootDir(std::wstring dir) -{ - std::wstring root; - - /* find the subdir: [/]root[/...] - */ - int i,j; - int len = dir.length(); - for(i = 0; (i < len) && (dir[i] == '/'); i++); - for(j = i; (j < len) && (dir[j] != '/'); j++); - if (i == j) - return root; /* empty */ - for(; i < j; i++) - { - root += dir[i]; - } - return root; -} - -std::wstring RsDirUtil::removeWideRootDir(std::wstring path) -{ - unsigned int i, j; - unsigned int len = path.length(); - std::wstring output; - - /* chew leading '/'s */ - for(i = 0; (i < len) && (path[i] == '/'); i++); - if (i == len) - return output; /* empty string */ - - for(j = i; (j < len) && (path[j] != '/'); j++); /* run to next '/' */ - for(; (j < len) && (path[j] == '/'); j++); /* chew leading '/'s */ - - for(; j < len; j++) - { - output += path[j]; - } - - return output; -} - -std::wstring RsDirUtil::removeWideRootDirs(std::wstring path, std::wstring root) -{ - /* too tired */ - std::wstring notroot; - - unsigned int i = 0, j = 0; - - /* catch empty data */ - if ((root.length() < 1) || (path.length() < 1)) - return notroot; - - if ((path[0] == '/') && (root[0] != '/')) - { - i++; - } - - for(; (i < path.length()) && (j < root.length()) && (path[i] == root[j]); i++, j++); - - /* should have consumed root. */ - if (j == root.length()) - { - //std::cerr << "matched root!" << std::endl; - } - else - { - //std::cerr << "failed i: " << i << ", j: " << j << std::endl; - //std::cerr << "root: " << root << " path: " << path << std::endl; - return notroot; - } - - if (path[i] == '/') - { - i++; - } - - for(; i < path.length(); i++) - { - notroot += path[i]; - } - - //std::cerr << "Found NotRoot: " << notroot << std::endl; - - return notroot; -} - - - -int RsDirUtil::breakupWideDirList(std::wstring path, - std::list &subdirs) -{ - int start = 0; - unsigned int i; - for(i = 0; i < path.length(); i++) - { - if (path[i] == '/') - { - if (i - start > 0) - { - subdirs.push_back(path.substr(start, i-start)); - } - start = i+1; - } - } - // get the final one. - if (i - start > 0) - { - subdirs.push_back(path.substr(start, i-start)); - } - return 1; -} - - - -bool RsDirUtil::checkWideDirectory(std::wstring dir) -{ - struct stat buf; - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::string d(dir.begin(), dir.end()); - int val = stat(d.c_str(), &buf); - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - if (val == -1) - { -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkDirectory() "; - std::cerr << d << " doesn't exist" << std::endl; -#endif - return false; - } - else if (!S_ISDIR(buf.st_mode)) - { - // Some other type - error. -#ifdef RSDIR_DEBUG - std::cerr << "RsDirUtil::checkDirectory() "; - std::cerr << d << " is not Directory" << std::endl; -#endif - return false; - } - return true; -} - - -bool RsDirUtil::checkWideCreateDirectory(std::wstring dir) -{ - struct stat buf; - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::string d(dir.begin(), dir.end()); - int val = stat(d.c_str(), &buf); - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - if (val == -1) - { - // directory don't exist. create. -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS // UNIX - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - if (-1 == mkdir(d.c_str(), 0777)) - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ -#else // WIN - if (-1 == mkdir(d.c_str())) -#endif -/******************************** WINDOWS/UNIX SPECIFIC PART ******************/ - - { -#ifdef RSDIR_DEBUG - std::cerr << "check_create_directory() Fatal Error --"; - std::cerr < - -bool RsDirUtil::cleanupWideDirectory(std::wstring cleandir, std::list keepFiles) -{ - - /* check for the dir existance */ - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::string cd(cleandir.begin(), cleandir.end()); - DIR *dir = opendir(cd.c_str()); - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::list::const_iterator it; - - if (!dir) - { - return false; - } - - struct dirent *dent; - struct stat buf; - - while(NULL != (dent = readdir(dir))) - { - /* check entry type */ - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::string fname(dent -> d_name); - std::wstring wfname(fname.begin(), fname.end()); - std::string fullname = cd + "/" + fname; - - if (-1 != stat(fullname.c_str(), &buf)) - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - { - /* only worry about files */ - if (S_ISREG(buf.st_mode)) - { - /* check if we should keep it */ - if (keepFiles.end() == (it = std::find(keepFiles.begin(), keepFiles.end(), wfname))) - { - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - /* can remove */ - remove(fullname.c_str()); - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - } - } - } - } - /* close directory */ - closedir(dir); - - return true; -} - -/* slightly nicer helper function */ -bool RsDirUtil::hashWideFile(std::wstring filepath, - std::wstring &name, std::string &hash, uint64_t &size) -{ - if (getWideFileHash(filepath, hash, size)) - { - /* extract file name */ - name = RsDirUtil::getWideTopDir(filepath); - return true; - } - return false; -} - - -#include -#include -#include - -/* Function to hash, and get details of a file */ -bool RsDirUtil::getWideFileHash(std::wstring filepath, - std::string &hash, uint64_t &size) -{ - FILE *fd; - int len; - SHA_CTX *sha_ctx = new SHA_CTX; - unsigned char sha_buf[SHA_DIGEST_LENGTH]; - unsigned char gblBuf[512]; - - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - std::string fp(filepath.begin(), filepath.end()); - - if (NULL == (fd = fopen64(fp.c_str(), "rb"))) - return false; - - /***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/ - - /* determine size */ - fseeko64(fd, 0, SEEK_END); - size = ftello64(fd); - fseeko64(fd, 0, SEEK_SET); - - SHA1_Init(sha_ctx); - while((len = fread(gblBuf,1, 512, fd)) > 0) - { - SHA1_Update(sha_ctx, gblBuf, len); - } - - /* reading failed for some reason */ - if (ferror(fd)) - { - delete sha_ctx; - fclose(fd); - return false; - } - - SHA1_Final(&sha_buf[0], sha_ctx); - - std::ostringstream tmpout; // please do not use std::ostringstream - for(int i = 0; i < SHA_DIGEST_LENGTH; i++) - { - tmpout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) (sha_buf[i]); - } - hash = tmpout.str(); - - delete sha_ctx; - fclose(fd); - return true; -} - -bool RsDirUtil::renameWideFile(const std::wstring& from, const std::wstring& to) -{ - int loops = 0; - -#if defined(WIN32) || defined(MINGW) || defined(__CYGWIN__) -#ifdef WIN_CROSS_UBUNTU - std::wstring f,t ; - for(int i=0;i= 30) - return false ; - - loops++; - } - - return true ; -} - - -#endif // WIDE STUFF NOT ENABLED YET! diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h deleted file mode 100644 index 50e636541..000000000 --- a/libretroshare/src/util/rsdir.h +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdir.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once - -#include -#include -#include -#include - -class RsThread; - -#include - -#ifndef WINDOWS_SYS -typedef int rs_lock_handle_t; -#else -typedef /*HANDLE*/ void *rs_lock_handle_t; -#endif - -// This is a scope guard on a given file. Works like a mutex. Is blocking. -// We could do that in another way: derive RsMutex into RsLockFileMutex, and -// use RsStackMutex on it transparently. Only issue: this will cost little more -// because of the multiple inheritance. -// -class RsStackFileLock -{ - public: - RsStackFileLock(const std::string& file_path) ; - ~RsStackFileLock() ; - - private: - rs_lock_handle_t _file_handle ; -}; - -namespace RsDirUtil { - -std::string getTopDir(const std::string&); -std::string getRootDir(const std::string&); -std::string removeRootDir(const std::string& path); -void removeTopDir(const std::string& dir, std::string &path); -std::string removeRootDirs(const std::string& path, const std::string& root); - -// Renames file from to file to. Files should be on the same file system. -// returns true if succeed, false otherwise. -bool renameFile(const std::string& from,const std::string& to) ; -//bool createBackup (const std::string& sFilename, unsigned int nCount = 5); - -// returns the CRC32 of the data of length len -// -uint32_t rs_CRC32(const unsigned char *data,uint32_t len) ; - -// Returns %u, %lu, or %llu, depending on the size of unsigned int, unsigned long and unsigned long long on the current system. -// Use as; -// sscanf(string, RsDirUtil::scanf_string_for_uint( sizeof(X) ), &X) ; -// -const char *scanf_string_for_uint(int bytes) ; - -int breakupDirList(const std::string& path, std::list &subdirs); - -// Splits the path into parent directory and file. File can be empty if full_path is a dir ending with '/' -// if full_path does not contain a directory, then dir will be "." and file will be full_path. - -bool splitDirFromFile(const std::string& full_path,std::string& dir, std::string& file); - -bool copyFile(const std::string& source,const std::string& dest); - -/** Move file. If destination directory doesn't exists create it. */ -bool moveFile(const std::string& source, const std::string& dest); - -bool removeFile(const std::string& file); -bool fileExists(const std::string& file); -bool checkFile(const std::string& filename,uint64_t& file_size,bool disallow_empty_file = false); -bool checkDirectory(const std::string& dir); -bool checkCreateDirectory(const std::string& dir); - -// Removes all symbolic links along the path and computes the actual location of the file/dir passed as argument. - -std::string removeSymLinks(const std::string& path) ; - -bool cleanupDirectory(const std::string& dir, const std::set &keepFiles); -bool cleanupDirectoryFaster(const std::string& dir, const std::set &keepFiles); - -bool hashFile(const std::string& filepath, std::string &name, RsFileHash &hash, uint64_t &size); -bool getFileHash(const std::string& filepath,RsFileHash &hash, uint64_t &size, RsThread *thread = NULL); - -Sha1CheckSum sha1sum(const uint8_t *data,uint32_t size) ; -Sha256CheckSum sha256sum(const uint8_t *data,uint32_t size) ; - -bool saveStringToFile(const std::string& file, const std::string& str); -bool loadStringFromFile(const std::string& file, std::string& str); - -// Creates a lock file with given path, and returns the lock handle -// returns: -// 0: Success -// 1: Another instance already has the lock -// 2 : Unexpected error -int createLockFile(const std::string& lock_file_path, rs_lock_handle_t& lock_handle) ; - -// Removes the lock file with specified handle. -void releaseLockFile(rs_lock_handle_t lockHandle) ; - -std::wstring getWideTopDir(std::wstring); -std::wstring getWideRootDir(std::wstring); -std::wstring removeWideRootDir(std::wstring path); -std::wstring removeWideTopDir(std::wstring dir); -std::wstring removeWideRootDirs(std::wstring path, std::wstring root); - -// Renames file from to file to. Files should be on the same file system. -// returns true if succeed, false otherwise. -bool renameWideFile(const std::wstring& from,const std::wstring& to) ; - -int breakupWideDirList(std::wstring path, - std::list &subdirs); - -bool checkWideDirectory(std::wstring dir); -bool checkWideCreateDirectory(std::wstring dir); -bool cleanupWideDirectory(std::wstring dir, std::list keepFiles); - -bool hashWideFile(std::wstring filepath,std::wstring &name, RsFileHash &hash, uint64_t &size); - -bool getWideFileHash(std::wstring filepath, RsFileHash &hash, uint64_t &size); - -FILE *rs_fopen(const char* filename, const char* mode); - -std::string convertPathToUnix(std::string path); - -/** Concatenate two path pieces putting '/' separator between them only if - * needed */ -std::string makePath(const std::string &path1, const std::string &path2); - -RS_SET_CONTEXT_DEBUG_LEVEL(1); -} - -#if __cplusplus < 201703L -namespace std -{ -namespace filesystem -{ -bool create_directories(const std::string& path); -} -} -#endif // __cplusplus < 201703L diff --git a/libretroshare/src/util/rsdiscspace.cc b/libretroshare/src/util/rsdiscspace.cc deleted file mode 100644 index a394cd4e5..000000000 --- a/libretroshare/src/util/rsdiscspace.cc +++ /dev/null @@ -1,223 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdiscspace.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include "util/rstime.h" -#include "rsserver/p3face.h" -#include "retroshare/rsfiles.h" -#include "retroshare/rsiface.h" -#include "retroshare/rsinit.h" -#include "rsdiscspace.h" -#include - -#ifdef __ANDROID__ -# include -#endif - -#ifdef WIN32 -# include -#elif defined(__ANDROID__) && (__ANDROID_API__ < 21) -# include -# define statvfs64 statfs -# warning statvfs64 is not supported with android platform < 21 falling back to statfs that is untested (may misbehave) -#else -# include -#endif - -#define DELAY_BETWEEN_CHECKS 2 - -/* - * #define DEBUG_RSDISCSPACE - */ - -rstime_t RsDiscSpace::_last_check[RS_DIRECTORY_COUNT] = { 0,0,0,0 } ; -uint32_t RsDiscSpace::_size_limit_mb = 100 ; -uint32_t RsDiscSpace::_current_size[RS_DIRECTORY_COUNT] = { 10000,10000,10000,10000 } ; -bool RsDiscSpace::_last_res[RS_DIRECTORY_COUNT] = { true,true,true,true }; -RsMutex RsDiscSpace::_mtx("RsDiscSpace") ; -std::string RsDiscSpace::_partials_path = "" ; -std::string RsDiscSpace::_download_path = "" ; - -bool RsDiscSpace::crossSystemDiskStats(const char *file, uint64_t& free_blocks, uint64_t& block_size) -{ -#if defined(WIN32) || defined(MINGW) || defined(__CYGWIN__) - - DWORD dwFreeClusters; - DWORD dwBytesPerSector; - DWORD dwSectorPerCluster; - DWORD dwTotalClusters; - -#ifdef WIN_CROSS_UBUNTU - wchar_t szDrive[4]; - szDrive[0] = file[0] ; - szDrive[1] = file[1] ; - szDrive[2] = file[2] ; -#else - char szDrive[4] = ""; - - char *pszFullPath = _fullpath (NULL, file, 0); - if (pszFullPath == 0) { - std::cerr << "Size estimate failed for drive (_fullpath) " << std::endl ; - return false; - } - _splitpath (pszFullPath, szDrive, NULL, NULL, NULL); - free (pszFullPath); -#endif - szDrive[3] = 0; - - if (!GetDiskFreeSpaceA (szDrive, &dwSectorPerCluster, &dwBytesPerSector, &dwFreeClusters, &dwTotalClusters)) - { - std::cerr << "Size estimate failed for drive " << szDrive << std::endl ; - return false; - } - - free_blocks = dwFreeClusters ; - block_size = dwSectorPerCluster * dwBytesPerSector ; -#else -#ifdef __APPLE__ - struct statvfs buf; - - if (0 != statvfs (file, &buf)) - { - std::cerr << "Size estimate failed for file " << file << std::endl ; - return false; - } - - - free_blocks = buf.f_bavail; - block_size = buf.f_frsize ; -#else - struct statvfs64 buf; - - if (0 != statvfs64 (file, &buf)) - { - std::cerr << "Size estimate failed for file " << file << std::endl ; - return false; - } - - - free_blocks = buf.f_bavail; - block_size = buf.f_bsize ; -#endif - -#endif - return true ; -} - -void RsDiscSpace::setDownloadPath(const std::string& path) -{ - RsStackMutex m(_mtx) ; // Locked - _download_path = path ; -} - -void RsDiscSpace::setPartialsPath(const std::string& path) -{ - RsStackMutex m(_mtx) ; // Locked - _partials_path = path ; -} - -bool RsDiscSpace::checkForDiscSpace(RsDiscSpace::DiscLocation loc) -{ - RsStackMutex m(_mtx) ; // Locked - - if( (_partials_path == "" && loc == RS_PARTIALS_DIRECTORY) || (_download_path == "" && loc == RS_DOWNLOAD_DIRECTORY)) - throw std::runtime_error("Download path and partial path not properly set in RsDiscSpace. Please call RsDiscSpace::setPartialsPath() and RsDiscSpace::setDownloadPath()") ; - - rstime_t now = time(NULL) ; - - if(_last_check[loc]+DELAY_BETWEEN_CHECKS < now) - { - uint64_t free_blocks,block_size ; - int rs = false; - -#ifdef DEBUG_RSDISCSPACE - std::cerr << "Size determination:" << std::endl ; -#endif - switch(loc) - { - case RS_DOWNLOAD_DIRECTORY: rs = crossSystemDiskStats(_download_path.c_str(),free_blocks,block_size) ; -#ifdef DEBUG_RSDISCSPACE - std::cerr << " path = " << _download_path << std::endl ; -#endif - break ; - - case RS_PARTIALS_DIRECTORY: rs = crossSystemDiskStats(_partials_path.c_str(),free_blocks,block_size) ; -#ifdef DEBUG_RSDISCSPACE - std::cerr << " path = " << _partials_path << std::endl ; -#endif - break ; - - case RS_CONFIG_DIRECTORY: rs = crossSystemDiskStats(RsAccounts::AccountDirectory().c_str(),free_blocks,block_size) ; -#ifdef DEBUG_RSDISCSPACE - std::cerr << " path = " << RsInit::RsConfigDirectory() << std::endl ; -#endif - break ; - - case RS_PGP_DIRECTORY: rs = crossSystemDiskStats(RsAccounts::PGPDirectory().c_str(),free_blocks,block_size) ; -#ifdef DEBUG_RSDISCSPACE - std::cerr << " path = " << RsInit::RsPGPDirectory() << std::endl ; -#endif - break ; - } - - if(!rs) - { - std::cerr << "Determination of free disc space failed ! Be careful !" << std::endl ; - return true ; - } - _last_check[loc] = now ; - - // Now compute the size in megabytes - // - _current_size[loc] = uint32_t(block_size * free_blocks / (uint64_t)(1024*1024)) ; // on purpose integer division - -#ifdef DEBUG_RSDISCSPACE - std::cerr << " blocks available = " << free_blocks << std::endl ; - std::cerr << " blocks size = " << block_size << std::endl ; - std::cerr << " free MBs = " << _current_size[loc] << std::endl ; -#endif - } - - bool res = _current_size[loc] > _size_limit_mb ; - - if(_last_res[loc] && !res) - RsServer::notify()->notifyDiskFull(loc,_size_limit_mb) ; - - _last_res[loc] = res ; - - return res ; -} - -void RsDiscSpace::setFreeSpaceLimit(uint32_t size_in_mb) -{ - RsStackMutex m(_mtx) ; // Locked - - _size_limit_mb = size_in_mb ; -} - -uint32_t RsDiscSpace::freeSpaceLimit() -{ - RsStackMutex m(_mtx) ; // Locked - - return _size_limit_mb ; -} - diff --git a/libretroshare/src/util/rsdiscspace.h b/libretroshare/src/util/rsdiscspace.h deleted file mode 100644 index 834561e6a..000000000 --- a/libretroshare/src/util/rsdiscspace.h +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsdiscspace.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include - -class RsDiscSpace -{ - public: - typedef uint32_t DiscLocation ; - - // Returns false is the disc space is lower than the given size limit, true otherwise. - // When the size limit is reached, this class calls notify to warn the user (possibly - // with a popup window). - // - static bool checkForDiscSpace(DiscLocation loc) ; - - // Allow the user to specify his own size limit. Should not be too low, especially not 0 MB ;-) - // 10MB to 100MB are sensible values. - // - static void setFreeSpaceLimit(uint32_t mega_bytes) ; - static uint32_t freeSpaceLimit() ; - - static void setPartialsPath(const std::string& path) ; - static void setDownloadPath(const std::string& path) ; - private: - static bool crossSystemDiskStats(const char *file, uint64_t& free_blocks, uint64_t& block_size) ; - - static RsMutex _mtx ; - - static rstime_t _last_check[RS_DIRECTORY_COUNT] ; - static uint32_t _size_limit_mb ; - static uint32_t _current_size[RS_DIRECTORY_COUNT] ; - static bool _last_res[RS_DIRECTORY_COUNT] ; - - static std::string _partials_path ; - static std::string _download_path ; -}; - diff --git a/libretroshare/src/util/rsendian.h b/libretroshare/src/util/rsendian.h deleted file mode 100644 index d27c374ff..000000000 --- a/libretroshare/src/util/rsendian.h +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * * - * libretroshare endiannes utilities * - * * - * Copyright (C) 2020 Gioacchino Mazzurco * - * Copyright (C) 2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -/** - * @file - * This file provide convenient integer endiannes conversion utilities. - * Instead of providing them with different names for each type (a la C htonl, - * htons, ntohl, ntohs ), which make them uncomfortable to use, expose a - * templated function `rs_endian_fix` to reorder integers bytes representation - * when sending or receiving from the network. */ - -/* enforce LITTLE_ENDIAN on Windows */ -#ifdef WINDOWS_SYS -# define BYTE_ORDER 1234 -# define LITTLE_ENDIAN 1234 -# define BIG_ENDIAN 4321 -#else -#include -#endif - -template inline INTTYPE rs_endian_fix(INTTYPE val) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - INTTYPE swapped = 0; - for (size_t i = 0; i < sizeof(INTTYPE); ++i) - swapped |= (val >> (8*(sizeof(INTTYPE)-i-1)) & 0xFF) << (8*i); - return swapped; -#else - return val; -#endif -}; - -#ifndef BYTE_ORDER -# error "ENDIAN determination Failed (BYTE_ORDER not defined)" -#endif - -#if !(BYTE_ORDER == BIG_ENDIAN || BYTE_ORDER == LITTLE_ENDIAN) -# error "ENDIAN determination Failed (unkown BYTE_ORDER value)" -#endif diff --git a/libretroshare/src/util/rserrno.cc b/libretroshare/src/util/rserrno.cc deleted file mode 100644 index b62394d69..000000000 --- a/libretroshare/src/util/rserrno.cc +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rserrno.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#define RS_INTERNAL_ERRNO_CASE(e) case e: return #e - -const char* rsErrnoName(int err) -{ - switch (err) - { - RS_INTERNAL_ERRNO_CASE(EINVAL); - RS_INTERNAL_ERRNO_CASE(EBUSY); - RS_INTERNAL_ERRNO_CASE(EAGAIN); - RS_INTERNAL_ERRNO_CASE(EDEADLK); - RS_INTERNAL_ERRNO_CASE(EPERM); - RS_INTERNAL_ERRNO_CASE(EBADF); - RS_INTERNAL_ERRNO_CASE(EFAULT); - RS_INTERNAL_ERRNO_CASE(ENOTSOCK); - RS_INTERNAL_ERRNO_CASE(EISCONN); - RS_INTERNAL_ERRNO_CASE(ECONNREFUSED); - RS_INTERNAL_ERRNO_CASE(ETIMEDOUT); - RS_INTERNAL_ERRNO_CASE(ENETUNREACH); - RS_INTERNAL_ERRNO_CASE(EADDRINUSE); - RS_INTERNAL_ERRNO_CASE(EINPROGRESS); - RS_INTERNAL_ERRNO_CASE(EALREADY); - RS_INTERNAL_ERRNO_CASE(ENOTCONN); - RS_INTERNAL_ERRNO_CASE(EPIPE); - RS_INTERNAL_ERRNO_CASE(ECONNRESET); - RS_INTERNAL_ERRNO_CASE(EHOSTUNREACH); - RS_INTERNAL_ERRNO_CASE(EADDRNOTAVAIL); - } - - return "rsErrnoName UNKNOWN ERROR CODE"; -} diff --git a/libretroshare/src/util/rserrno.h b/libretroshare/src/util/rserrno.h deleted file mode 100644 index 526a4890a..000000000 --- a/libretroshare/src/util/rserrno.h +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rserrno.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2019 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -const char* rsErrnoName(int err); diff --git a/libretroshare/src/util/rsexpr.cc b/libretroshare/src/util/rsexpr.cc deleted file mode 100644 index dff5a5fa5..000000000 --- a/libretroshare/src/util/rsexpr.cc +++ /dev/null @@ -1,320 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare: rsexpr.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2007-2008 by Kashif Kaleem * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "retroshare/rsexpr.h" -#include "retroshare/rstypes.h" -#include -#include - -/****************************************************************************************** -eval functions of relational expressions. - -******************************************************************************************/ - -namespace RsRegularExpression -{ -template<> -void RelExpression::linearize(LinearizedExpression& e) const -{ - e._ints.push_back(Op) ; - e._ints.push_back(LowerValue) ; - e._ints.push_back(HigherValue) ; -} - - -bool DateExpression::eval(const ExpFileEntry& file) -{ - return evalRel(file.file_modtime()); -} - -bool SizeExpressionMB::eval(const ExpFileEntry& file) -{ - return evalRel((int)(file.file_size()/(uint64_t)(1024*1024))); -} - -bool SizeExpression::eval(const ExpFileEntry& file) -{ - return evalRel(file.file_size()); -} - -bool PopExpression::eval(const ExpFileEntry& file) -{ - return evalRel(file.file_popularity()); -} - -/****************************************************************************************** -Code for evaluating string expressions - -******************************************************************************************/ - -bool NameExpression::eval(const ExpFileEntry& file) -{ - return evalStr(file.file_name()); -} - -bool PathExpression::eval(const ExpFileEntry& file) -{ - return evalStr(file.file_parent_path()); -} - -bool ExtExpression::eval(const ExpFileEntry& file) -{ - std::string ext; - /*Get the part of the string after the last instance of . in the filename */ - size_t index = file.file_name().find_last_of('.'); - if (index != std::string::npos) { - ext = file.file_name().substr(index+1); - if (ext != "" ){ - return evalStr(ext); - } - } - return false; -} - -bool HashExpression::eval(const ExpFileEntry& file){ - return evalStr(file.file_hash().toStdString()); -} - -/*Check whether two strings are 'equal' to each other*/ -static bool StrEquals(const std::string & str1, const std::string & str2, - bool IgnoreCase ){ - if ( str1.size() != str2.size() ){ - return false; - } else if (IgnoreCase) { - std::equal( str1.begin(), str1.end(), - str2.begin(), CompareCharIC() ); - } - return std::equal( str1.begin(), str1.end(), - str2.begin()); -} - -/*Check whether one string contains the other*/ -static bool StrContains( const std::string & str1, const std::string & str2, - bool IgnoreCase){ - - std::string::const_iterator iter ; - if (IgnoreCase) { - iter = std::search( str1.begin(), str1.end(), - str2.begin(), str2.end(), CompareCharIC() ); - } else { - iter = std::search( str1.begin(), str1.end(), - str2.begin(), str2.end()); - } - - return ( iter != str1.end() ); -} - - -std::string StringExpression::toStdStringWithParam(const std::string& varstr) const -{ - std::string strlist ; - for (auto iter = terms.begin(); iter != terms.end(); ++iter ) - strlist += *iter + " "; - - if(!strlist.empty()) - strlist.resize(strlist.size()-1); //strlist.pop_back(); // pops the last ",". c++11 is needed for pop_back() - - switch(Op) - { - case ContainsAllStrings: return varstr + " CONTAINS ALL "+strlist ; - case ContainsAnyStrings: if(terms.size() == 1) - return varstr + " CONTAINS "+strlist ; - else - return varstr + " CONTAINS ONE OF "+strlist ; - case EqualsString: if(terms.size() == 1) - return varstr + " IS "+strlist ; - else - return varstr + " IS ONE OF "+strlist ; - - default: - return "" ; - } -} - -bool StringExpression :: evalStr ( const std::string &str ){ - std::list::iterator iter; - switch (Op) { - case ContainsAllStrings: - for ( iter = terms.begin(); iter != terms.end(); ++iter ) { - if ( StrContains (str, *iter, IgnoreCase) == false ){ - return false; - } - } - return true; - break; - case ContainsAnyStrings: - for ( iter = terms.begin(); iter != terms.end(); ++iter ) { - if ( StrContains (str,*iter, IgnoreCase) == true ) { - return true; - } - } - break; - case EqualsString: - for ( iter = terms.begin(); iter != terms.end(); ++iter ) { - if ( StrEquals (str,*iter, IgnoreCase) == true ) { - return true; - } - } - break; - default: - return false; - } - return false; -} - -/************************************************************************* - * linearization code - *************************************************************************/ - -void CompoundExpression::linearize(LinearizedExpression& e) const -{ - e._tokens.push_back(LinearizedExpression::EXPR_COMP) ; - e._ints.push_back(Op) ; - - Lexp->linearize(e) ; - Rexp->linearize(e) ; -} - -void StringExpression::linearize(LinearizedExpression& e) const -{ - e._ints.push_back(Op) ; - e._ints.push_back(IgnoreCase) ; - e._ints.push_back(terms.size()) ; - - for(std::list::const_iterator it(terms.begin());it!=terms.end();++it) - e._strings.push_back(*it) ; -} - -Expression *LinearizedExpression::toExpr(const LinearizedExpression& e) -{ - int i=0,j=0,k=0 ; - return toExpr(e,i,j,k) ; -} - -void LinearizedExpression::readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list& strings,bool& b,StringOperator& op) -{ - op = static_cast(e._ints[n_ints++]) ; - b = e._ints[n_ints++] ; - int n = e._ints[n_ints++] ; - - strings.clear() ; - for(int i=0;i::const_iterator i = this->_strings.begin(); i != this->_strings.end(); ++i) - { - str += *i; - str += " "; - } - return str; -} - -Expression *LinearizedExpression::toExpr(const LinearizedExpression& e,int& n_tok,int& n_ints,int& n_strings) -{ - LinearizedExpression::token tok = static_cast(e._tokens[n_tok++]) ; - - switch(tok) - { - case EXPR_DATE: { - RelOperator op = static_cast(e._ints[n_ints++]) ; - int lv = e._ints[n_ints++] ; - int hv = e._ints[n_ints++] ; - - return new DateExpression(op,lv,hv) ; - } - - case EXPR_POP: { - RelOperator op = static_cast(e._ints[n_ints++]) ; - int lv = e._ints[n_ints++] ; - int hv = e._ints[n_ints++] ; - - return new PopExpression(op,lv,hv) ; - } - case EXPR_SIZE: { - RelOperator op = static_cast(e._ints[n_ints++]) ; - int lv = e._ints[n_ints++] ; - int hv = e._ints[n_ints++] ; - - return new SizeExpression(op,lv,hv) ; - } - case EXPR_HASH: { - std::list strings ; - StringOperator op ; - bool b ; - - readStringExpr(e,n_ints,n_strings,strings,b,op) ; - return new HashExpression(op,strings) ; - } - case EXPR_NAME: { - std::list strings ; - StringOperator op ; - bool b ; - - readStringExpr(e,n_ints,n_strings,strings,b,op) ; - - return new NameExpression(op,strings,b) ; - } - case EXPR_PATH: { - std::list strings ; - StringOperator op ; - bool b ; - - readStringExpr(e,n_ints,n_strings,strings,b,op) ; - - return new ExtExpression(op,strings,b) ; - } - case EXPR_EXT: { - std::list strings ; - StringOperator op ; - bool b ; - - readStringExpr(e,n_ints,n_strings,strings,b,op) ; - - return new ExtExpression(op,strings,b) ; - } - case EXPR_COMP: { - LogicalOperator op = static_cast(e._ints[n_ints++]) ; - - Expression *e1 = toExpr(e,n_tok,n_ints,n_strings) ; - Expression *e2 = toExpr(e,n_tok,n_ints,n_strings) ; - - return new CompoundExpression(op,e1,e2) ; - } - case EXPR_SIZE_MB: { - RelOperator op = static_cast(e._ints[n_ints++]) ; - int lv = e._ints[n_ints++] ; - int hv = e._ints[n_ints++] ; - - return new SizeExpressionMB(op,lv,hv) ; - } - default: - std::cerr << "No expression match the current value " << tok << std::endl ; - return NULL ; - } -} - - -} diff --git a/libretroshare/src/util/rsinitedptr.h b/libretroshare/src/util/rsinitedptr.h deleted file mode 100644 index 09aaa871a..000000000 --- a/libretroshare/src/util/rsinitedptr.h +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsinitedptr.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2010-2010 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#pragma once -/** -helper class to store a pointer -it is usefull because it initialises itself to NULL - -usage: -replace - type* ptr; -with - inited_ptr ptr; - -this class can -- get assigned a pointer -- be dereferenced -- be converted back to a pointer -*/ -namespace RsUtil{ -template class inited_ptr{ -public: - inited_ptr(): _ptr(NULL){} - inited_ptr(const inited_ptr& other): _ptr(other._ptr){} - inited_ptr& operator= (const inited_ptr& other){ _ptr = other._ptr; return *this;} - inited_ptr& operator= (T* ptr){ _ptr = ptr; return *this;} - operator T* () const { return _ptr;} - T* operator ->() const { return _ptr;} - T& operator *() const { return *_ptr;} -private: - T* _ptr; -}; -}//namespace RsUtil diff --git a/libretroshare/src/util/rsjson.cc b/libretroshare/src/util/rsjson.cc deleted file mode 100644 index 8af1cf942..000000000 --- a/libretroshare/src/util/rsjson.cc +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include -#include -#include - -#include "util/rsjson.h" - -inline int getJsonManipulatorStatePosition() -{ - static int p = std::ios_base::xalloc(); - return p; -} - -std::ostream& compactJSON(std::ostream &out) -{ - out.iword(getJsonManipulatorStatePosition()) = 1; - return out; -} - -std::ostream& prettyJSON(std::ostream &out) -{ - out.iword(getJsonManipulatorStatePosition()) = 0; - return out; -} - -std::ostream& operator<<(std::ostream &out, const RsJson &jDoc) -{ - rapidjson::StringBuffer buffer; buffer.Clear(); - if(out.iword(getJsonManipulatorStatePosition())) - { - rapidjson::Writer writer(buffer); - jDoc.Accept(writer); - } - else - { - rapidjson::PrettyWriter writer(buffer); - jDoc.Accept(writer); - } - - return out << buffer.GetString(); -} diff --git a/libretroshare/src/util/rsjson.h b/libretroshare/src/util/rsjson.h deleted file mode 100644 index 13073f3b2..000000000 --- a/libretroshare/src/util/rsjson.h +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -/** - * Use this type for JSON documents representations in RetroShare code - */ -typedef rapidjson::Document RsJson; - -/** - * Print out RsJson to a stream, use std::ostringstream to get the string - * @param[out] out output stream - * @param[in] jDoc JSON document to print - * @return same output stream passed as out parameter - */ -std::ostream& operator<<(std::ostream &out, const RsJson &jDoc); - -/** - * Stream manipulator to print RsJson in compact format - * @param[out] out output stream - * @return same output stream passed as out parameter - */ -std::ostream& compactJSON(std::ostream &out); - -/** - * Stream manipulator to print RsJson in human readable format - * @param[out] out output stream - * @return same output stream passed as out parameter - */ -std::ostream& prettyJSON(std::ostream &out); diff --git a/libretroshare/src/util/rskbdinput.cc b/libretroshare/src/util/rskbdinput.cc deleted file mode 100644 index 38b0307a2..000000000 --- a/libretroshare/src/util/rskbdinput.cc +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * libretroshare/src/retroshare/util/rskbdinput.cc * - * * - * Copyright (C) 2019 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef __ANDROID__ - -#include -#include - -#ifdef WINDOWS_SYS -#include -#include - -#define PASS_MAX 512 - -namespace RsUtil { -std::string rs_getpass(const std::string& prompt,bool no_echo) -{ - static char getpassbuf [PASS_MAX + 1]; - size_t i = 0; - int c; - - if (!prompt.empty()) { - std::cerr << prompt ; - std::cerr.flush(); - } - - for (;;) { - c = _getch (); - if (c == '\r') { - getpassbuf [i] = '\0'; - break; - } - else if (i < PASS_MAX) { - getpassbuf[i++] = c; - } - - if (i >= PASS_MAX) { - getpassbuf [i] = '\0'; - break; - } - } - - if (!prompt.empty()) { - std::cerr << "\r\n" ; - std::cerr.flush(); - } - - return std::string(getpassbuf); -} -} -#else - -#include -#include -#include -#include -#include - -static int getch() -{ - int ch; - struct termios t_old, t_new; - - tcgetattr(STDIN_FILENO, &t_old); - t_new = t_old; - t_new.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &t_new); - - ch = getchar(); - - tcsetattr(STDIN_FILENO, TCSANOW, &t_old); - return ch; -} - -namespace RsUtil { - -std::string rs_getpass(const std::string& prompt, bool no_echo) -{ - const char BACKSPACE=127; - const char RETURN=10; - - std::string password; - unsigned char ch=0; - - std::cout < * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -namespace RsUtil { - - std::string rs_getpass(const std::string& prompt,bool no_echo=true) ; - -} diff --git a/libretroshare/src/util/rsmemcache.h b/libretroshare/src/util/rsmemcache.h deleted file mode 100644 index 53d5efa27..000000000 --- a/libretroshare/src/util/rsmemcache.h +++ /dev/null @@ -1,492 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsmemcache.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UTIL_MEM_CACHE -#define RS_UTIL_MEM_CACHE - -#include -#include "util/rstime.h" -#include -#include -#include - -/************************************************************************************/ -/************************************************************************************/ -/************************************************************************************/ - -/* Generic Memoory Cache - * - * This is probably crude and crap to start with. - * Want Least Recently Used (LRU) discard policy, without having to search whole cache. - * Use two maps: - * - mDataMap[key] => data. - * - mLruMap[AccessTS] => key (multimap) - */ - -/*** - * #define DEBUG_RSMEMCACHE 1 - ***/ - -#define DEFAULT_MEM_CACHE_SIZE 100 - -template class RsMemCache -{ -public: - - RsMemCache(uint32_t max_size = DEFAULT_MEM_CACHE_SIZE, std::string name = "UnknownMemCache") - :mDataCount(0), mMaxSize(max_size), mName(name) - { - clearStats(); - return; - } - - bool is_cached(const Key &key) const; - bool fetch(const Key &key, Value &data); - - // Like map[] installs empty one if non-existent. - - Value& ref(const Key &key); - Value& operator[](const Key& key) { return ref(key); } - - bool store(const Key &key, const Value &data); - bool erase(const Key &key); // clean up cache. - - bool resize(); // should be called periodically to cleanup old entries. - - // Apply a method of a given class ClientClass to all cached data. Can be useful... - - template bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&)); - - uint32_t size() const { return mDataMap.size() ; } - void printStats(std::ostream& out); -private: - - bool update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts); - bool discard_LRU(int count_to_clear); - - // internal class. - class cache_data - { - public: - cache_data() { return; } - cache_data(Key in_key, Value in_data, rstime_t in_ts) - :key(in_key), data(in_data), ts(in_ts) { return; } - Key key; - Value data; - rstime_t ts; - }; - - - std::map mDataMap; - std::multimap mLruMap; - uint32_t mDataCount; - uint32_t mMaxSize; - std::string mName; - - // some statistics. - void clearStats(); - - mutable uint32_t mStats_inserted; - mutable uint32_t mStats_dropped; - mutable uint32_t mStats_iscached; - mutable uint32_t mStats_cachemiss; - mutable uint32_t mStats_access; - mutable uint32_t mStats_accessmiss; -}; - - -template bool RsMemCache::is_cached(const Key &key) const -{ - typename std::map::const_iterator it; - it = mDataMap.find(key); - if (it == mDataMap.end()) - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::is_cached(" << key << ") false"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - mStats_cachemiss++; - return false; - } -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::is_cached(" << key << ") false"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - mStats_iscached++; - return true; - -} - -template template bool RsMemCache::applyToAllCachedEntries(ClientClass& c, bool (ClientClass::*method)(Value&)) -{ - bool res = true ; - - for(typename std::map::iterator it(mDataMap.begin());it!=mDataMap.end();++it) - res = res && ((c.*method)(it->second.data)) ; - - return res ; -} - -template bool RsMemCache::fetch(const Key &key, Value& data) -{ -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::fetch()"; - std::cerr << std::endl; - printStats(std::cerr); -#endif // DEBUG_RSMEMCACHE - - typename std::map::iterator it; - it = mDataMap.find(key); - if (it == mDataMap.end()) - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::fetch(" << key << ") false"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - mStats_accessmiss++; - return false; - } - -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::fetch(" << key << ") OK"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - data = it->second.data; - - /* update ts on data */ - rstime_t old_ts = it->second.ts; - rstime_t new_ts = time(NULL); - it->second.ts = new_ts; - - update_lrumap(key, old_ts, new_ts); - - mStats_access++; - return true; -} - - -template bool RsMemCache::erase(const Key &key) -{ -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::erase()"; - std::cerr << std::endl; - printStats(std::cerr); -#endif // DEBUG_RSMEMCACHE - - typename std::map::iterator it; - it = mDataMap.find(key); - if (it == mDataMap.end()) - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::erase(" << key << ") false"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - mStats_accessmiss++; - return false; - } - -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::erase(" << key << ") OK"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - - /* get timestamps */ - rstime_t old_ts = it->second.ts; - rstime_t new_ts = 0; - - // remove from lru. - mDataMap.erase(it); - update_lrumap(key, old_ts, new_ts); - mDataCount--; - - mStats_access++; - return true; -} - - - -template Value &RsMemCache::ref(const Key &key) -{ -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::ref()"; - std::cerr << std::endl; - printStats(std::cerr); -#endif // DEBUG_RSMEMCACHE - - typename std::map::iterator it; - it = mDataMap.find(key); - if (it == mDataMap.end()) - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::ref(" << key << ") ERROR missing Key inserting Empty Data in LRU slot"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - // insert operation. - rstime_t new_ts = 0; - Value data; - mDataMap[key] = cache_data(key, data, new_ts); - mDataCount++; - - update_lrumap(key, 0, new_ts); - it = mDataMap.find(key); - - mStats_accessmiss++; - } - else - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::ref(" << key << ") OK"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - /* update ts on data */ - rstime_t old_ts = it->second.ts; - rstime_t new_ts = time(NULL); - it->second.ts = new_ts; - - update_lrumap(key, old_ts, new_ts); - - mStats_access++; - } - return it->second.data; -} - -template bool RsMemCache::store(const Key &key, const Value &data) -{ -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::store()"; - std::cerr << std::endl; - printStats(std::cerr); -#endif // DEBUG_RSMEMCACHE - - /* update lrumap entry */ - rstime_t old_ts = 0; - rstime_t new_ts = time(NULL); - - // For consistency - typename std::map::const_iterator it; - it = mDataMap.find(key); - if (it != mDataMap.end()) - { - // ERROR. -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::store() WARNING overriding existing entry"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - old_ts = it->second.ts; - } - else - { - mDataCount++; - } - - mDataMap[key] = cache_data(key, data, new_ts); - - update_lrumap(key, old_ts, new_ts); - - mStats_inserted++; - return true; -} - - -template bool RsMemCache::update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts) -{ - if (old_ts == 0) - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") just insert!"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - /* new insertion */ - mLruMap.insert(std::make_pair(new_ts, key)); - return true; - } - - /* find old entry */ - typename std::multimap::iterator mit; - typename std::multimap::iterator sit = mLruMap.lower_bound(old_ts); - typename std::multimap::iterator eit = mLruMap.upper_bound(old_ts); - - for(mit = sit; mit != eit; ++mit) - { - if (mit->second == key) - { - mLruMap.erase(mit); -#ifdef DEBUG_RSMEMCACHE - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") rm old"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - if (new_ts != 0) // == 0, means remove. - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") added new_ts"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - mLruMap.insert(std::make_pair(new_ts, key)); - } - return true; - } - } -#ifdef DEBUG_RSMEMCACHE - std::cerr << "p3IdService::locked_cache_update_lrumap(" << key << ") ERROR"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - return false; -} - -template bool RsMemCache::resize() -{ -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::resize()"; - std::cerr << std::endl; - printStats(std::cerr); -#endif // DEBUG_RSMEMCACHE - - int count_to_clear = 0; - { - // consistency check. - if ((mDataMap.size() != mDataCount) || - (mLruMap.size() != mDataCount)) - { - // ERROR. - std::cerr << "RsMemCache::resize() CONSISTENCY ERROR"; - std::cerr << std::endl; - std::cerr << "\tmDataMap.size() = " << mDataMap.size(); - std::cerr << std::endl; - std::cerr << "\tmLruMap.size() = " << mLruMap.size(); - std::cerr << std::endl; - std::cerr << "\tmDataCount = " << mDataCount; - std::cerr << std::endl; - } - - if (mDataCount > mMaxSize) - { - count_to_clear = mDataCount - mMaxSize; -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::resize() to_clear: " << count_to_clear; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - } - } - - if (count_to_clear > 0) - { - discard_LRU(count_to_clear); - } - return true; -} - - - -template bool RsMemCache::discard_LRU(int count_to_clear) -{ - while(count_to_clear > 0) - { - typename std::multimap::iterator mit = mLruMap.begin(); - if (mit != mLruMap.end()) - { - Key key = mit->second; - mLruMap.erase(mit); - - /* now clear from real cache */ - //std::map >::iterator it; - typename std::map::iterator it; - it = mDataMap.find(key); - if (it == mDataMap.end()) - { - // ERROR - std::cerr << "RsMemCache::discard_LRU(): ERROR Missing key: " << key; - std::cerr << std::endl; - return false; - } - else - { -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::discard_LRU() removing: " << key; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - mDataMap.erase(it); - mDataCount--; - mStats_dropped++; - } - } - else - { - // No More Data, ERROR. -#ifdef DEBUG_RSMEMCACHE - std::cerr << "RsMemCache::discard_LRU(): INFO more more cache data"; - std::cerr << std::endl; -#endif // DEBUG_RSMEMCACHE - - return true; - } - count_to_clear--; - } - return true; -} - -// These aren't templated functions. -template void RsMemCache::printStats(std::ostream &out) -{ - typename std::multimap::iterator mit = mLruMap.begin(); - rstime_t age = 0; - if (mit != mLruMap.end()) - { - age = time(NULL) - mit->first; - } - - out << "RsMemCache<" << mName << ">::printStats() Size: " << mDataCount << " Size2: " << mDataMap.size() << " Size3: " << mLruMap.size() << " MaxSize: " << mMaxSize << " LRU Age: " << age; - out << std::endl; - - out << "\tInsertions: " << mStats_inserted << " Drops: " << mStats_dropped; - out << std::endl; - - out << "\tCache Hits: " << mStats_iscached << " Misses: " << mStats_cachemiss; - out << std::endl; - - out << "\tAccess Hits: " << mStats_access << " Misses: " << mStats_accessmiss; - out << std::endl; -} - -template void RsMemCache::clearStats() -{ - mStats_inserted = 0; - mStats_dropped = 0; - mStats_iscached = 0; - mStats_cachemiss = 0; - mStats_access = 0; - mStats_accessmiss = 0; -} - - - - -#endif // RS_UTIL_MEM_CACHE diff --git a/libretroshare/src/util/rsmemory.cc b/libretroshare/src/util/rsmemory.cc deleted file mode 100644 index 2b162c77d..000000000 --- a/libretroshare/src/util/rsmemory.cc +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsmemory.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rsmemory.h" - -void *rs_malloc(size_t size) -{ - static const size_t SAFE_MEMALLOC_THRESHOLD = 1024*1024*1024 ; // 1Gb should be enough for everything! - - if(size == 0) - { - std::cerr << "(EE) Memory allocation error. A chunk of size 0 was requested. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - if(size > SAFE_MEMALLOC_THRESHOLD) - { - std::cerr << "(EE) Memory allocation error. A chunk of size larger than " << SAFE_MEMALLOC_THRESHOLD << " was requested. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - void *mem = malloc(size) ; - - if(mem == NULL) - { - std::cerr << "(EE) Memory allocation error for a chunk of " << size << " bytes. Callstack:" << std::endl; - print_stacktrace() ; - return NULL ; - } - - return mem ; -} - diff --git a/libretroshare/src/util/rsmemory.h b/libretroshare/src/util/rsmemory.h deleted file mode 100644 index eb2889a6f..000000000 --- a/libretroshare/src/util/rsmemory.h +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsmemory.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012 Cyril Soler * - * Copyright 2019-2020 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#include "util/stacktrace.h" - -/** - * @brief Shorthand macro to declare optional functions output parameters - * To define an optional output paramether use the following syntax - * -\code{.cpp} -bool myFunnyFunction( - int mandatoryParamether, - BigType& myOptionalOutput = RS_DEFAULT_STORAGE_PARAM(BigType) ) -\endcode - * - * The function caller then can call myFunnyFunction either passing - * myOptionalOutput parameter or not. - * @see RsGxsChannels methods for real usage examples. - * - * @details - * When const references are used to pass function parameters it is easy do make - * those params optional by defining a default value in the function - * declaration, because a temp is accepted as default parameter in those cases. - * It is not as simple when one want to make optional a non-const reference - * parameter that is usually used as output, in that case as a temp is in theory - * not acceptable. - * Yet it is possible to overcome that limitation with the following trick: - * If not passed as parameter the storage for the output parameter can be - * dinamically allocated directly by the function call, to avoid leaking memory - * on each function call the pointer to that storage is made unique so once the - * function returns it goes out of scope and is automatically deleted. - * About performance overhead: std::unique_ptr have very good performance and - * modern compilers may be even able to avoid the dynamic allocation in this - * case, any way the allocation would only happen if the parameter is not - * passed, so any effect on performace would happen only in case where the - * function is called without the parameter. - */ -#define RS_DEFAULT_STORAGE_PARAM(Type,...) *std::unique_ptr(new Type(__VA_ARGS__)) - -/** @brief Safely dynamic cast between std::unique_ptr of different types - * std::unique_ptr semantic rely on the invariant that only one instance own - * the object, when casting between differents types one would be tempted to do - * it in a one liner that easly end up breaking that condition ending up in a - * double delete and crash or in a silent memleak. - * With this function one can do that with same comfort of a plain dynamic_cast, - * plus the std::unique_ptr safety. - * @param[inout] src reference to source pointer. If the cast is successfull it - * is released, otherwise it is left untouched. - * @param[out] dst reference to destination pointer. If the cast is successful - * it get reseated to the object address, otherwise it is left untouched. - * @return true on success, false otherwise - */ -template -bool rs_unique_cast( - std::unique_ptr& src, std::unique_ptr& dst ) -{ - T_DST* dstPtr = dynamic_cast(src.get()); - if(dstPtr) - { - src.release(); - dst.reset(dstPtr); - return true; - } - return false; -} - -/** Mark a pointer as non-owned aka it must not be deleted/freed in that context. - * If a function take an `rs_view_ptr` as paramether it means that she will not - * own (aka free/delete) the passed memory, instead the caller is in charge of - * managing it. If a function return an `rs_view_ptr` it means the memory is - * managed internally and the caller should not call free/delete on it. - * @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf */ -template using rs_view_ptr = T*; - -/** Mark a pointer as owned aka the receiving context is in charge of dealing - * with it by free/delete once finished. - * If a function take an `rs_owner_ptr` as paramether it means that she will own - * (aka free/delete when finished using it) the passed memory, instead the - * caller is NOT in charge of managing it. - * If a function return an `rs_owner_ptr` it means the memory is NOT managed - * internally and the caller should call free/delete on it once finished using - * it. - * @see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf */ -template using rs_owner_ptr = T*; - -void *rs_malloc(size_t size) ; - -/** @deprecated use std::unique_ptr instead -// This is a scope guard to release the memory block when going of of the current scope. -// Can be very useful to auto-delete some memory on quit without the need to call free each time. -// -// Usage: -// -// { -// TemporaryMemoryHolder mem(size) ; -// -// if(mem != NULL) -// [ do something ] ; -// -// memcopy(mem, some_other_memory, size) ; -// -// [do something] -// -// } // mem gets freed automatically -*/ -class RsTemporaryMemory -{ -public: - explicit RsTemporaryMemory(size_t s) - { - _mem = (unsigned char *)rs_malloc(s) ; - - if(_mem) - _size = s ; - else - _size = 0 ; - } - - operator unsigned char *() { return _mem ; } - - size_t size() const { return _size ; } - - ~RsTemporaryMemory() { free(_mem); } - -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 deleted file mode 100644 index 1e5f79181..000000000 --- a/libretroshare/src/util/rsnet.cc +++ /dev/null @@ -1,176 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsnet.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 Robert Fernie * - * Copyright 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsnet.h" -#include "util/rsthreads.h" -#include "util/rsstring.h" -#include "util/rsmemory.h" - -#ifdef WINDOWS_SYS -#else -#include -#endif - -#include - -/* enforce LITTLE_ENDIAN on Windows */ -#ifdef WINDOWS_SYS - #define BYTE_ORDER 1234 - #define LITTLE_ENDIAN 1234 - #define BIG_ENDIAN 4321 -#endif - -#ifndef ntohll -uint64_t ntohll(uint64_t x) -{ -#ifdef BYTE_ORDER - #if BYTE_ORDER == BIG_ENDIAN - return x; - #elif BYTE_ORDER == LITTLE_ENDIAN - - uint32_t top = (uint32_t) (x >> 32); - uint32_t bot = (uint32_t) (0x00000000ffffffffULL & x); - - uint64_t rev = ((uint64_t) ntohl(top)) | (((uint64_t) ntohl(bot)) << 32); - - return rev; - #else - #error "ENDIAN determination Failed" - #endif -#else - #error "ENDIAN determination Failed (BYTE_ORDER not defined)" -#endif - -} -#endif -#ifndef htonll -uint64_t htonll(uint64_t x) -{ - return ntohll(x); -} -#endif - -void sockaddr_clear(struct sockaddr_in *addr) -{ - memset(addr, 0, sizeof(struct sockaddr_in)); - addr->sin_family = AF_INET; -} - -bool rsGetHostByName(const std::string& hostname, in_addr& returned_addr) -{ - addrinfo hint; memset(&hint, 0, sizeof(hint)); - hint.ai_family = AF_INET; - addrinfo* info = nullptr; - int res = getaddrinfo(hostname.c_str(), nullptr, &hint, &info); - - bool ok = true; - if(res > 0 || !info || !info->ai_addr) - { - std::cerr << __PRETTY_FUNCTION__ << "(EE) getaddrinfo returned error " - << res << " on string \"" << hostname << "\"" << std::endl; - returned_addr.s_addr = 0; - ok = false; - } - else - returned_addr.s_addr = ((sockaddr_in*)info->ai_addr)->sin_addr.s_addr; - - if(info) freeaddrinfo(info); - - return ok; -} - -bool isValidNet(const struct in_addr *addr) -{ - // invalid address. - if((*addr).s_addr == INADDR_NONE) - return false; - if((*addr).s_addr == 0) - return false; - // should do more tests. - return true; -} - - -bool isLoopbackNet(const struct in_addr *addr) -{ - in_addr_t taddr = ntohl(addr->s_addr); - return (taddr == (127 << 24 | 1)); -} - -bool isPrivateNet(const struct in_addr *addr) -{ - in_addr_t taddr = ntohl(addr->s_addr); - - if ( (taddr>>24 == 10) || // 10.0.0.0/8 - (taddr>>20 == (172<<4 | 16>>4)) || // 172.16.0.0/12 - (taddr>>16 == (192<<8 | 168)) || // 192.168.0.0/16 - (taddr>>16 == (169<<8 | 254)) ) // 169.254.0.0/16 - return true; - - return false; -} - -bool isLinkLocalNet(const struct in_addr *addr) -{ - in_addr_t taddr = ntohl(addr->s_addr); - if ( taddr>>16 == (169<<8 | 254) ) return true; // 169.254.0.0/16 - - return false; -} - -bool isExternalNet(const struct in_addr *addr) -{ - if (!isValidNet(addr)) - { - return false; - } - if (isLoopbackNet(addr)) - { - return false; - } - if (isPrivateNet(addr)) - { - return false; - } - return true; -} - -std::ostream &operator<<(std::ostream &out, const struct sockaddr_in &addr) -{ - out << "[" << rs_inet_ntoa(addr.sin_addr) << ":"; - out << htons(addr.sin_port) << "]"; - return out; -} - -std::ostream& operator<<(std::ostream& o, const sockaddr_storage& addr) -{ return o << sockaddr_storage_tostring(addr); } - -/* thread-safe version of inet_ntoa */ - -std::string rs_inet_ntoa(struct in_addr in) -{ - std::string str; - uint8_t *bytes = (uint8_t *) &(in.s_addr); - rs_sprintf(str, "%u.%u.%u.%u", (int) bytes[0], (int) bytes[1], (int) bytes[2], (int) bytes[3]); - return str; -} diff --git a/libretroshare/src/util/rsnet.h b/libretroshare/src/util/rsnet.h deleted file mode 100644 index cad2c116a..000000000 --- a/libretroshare/src/util/rsnet.h +++ /dev/null @@ -1,162 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsnet.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 Robert Fernie * - * Copyright 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UNIVERSAL_NETWORK_HEADER -#define RS_UNIVERSAL_NETWORK_HEADER - -#include -#include /* Included because GCC4.4 wants it */ -#include /* Included because GCC4.4 wants it */ -#include - -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ -#ifndef WINDOWS_SYS - -#include -#include -#include -#include - -#include -#include - -#else - -#include -typedef uint32_t in_addr_t; - -int inet_aton(const char *name, struct in_addr *addr); - -// Missing defines in MinGW -#ifndef MSG_WAITALL -#define MSG_WAITALL 8 -#endif - -#endif -/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ - -/** - * Workaround for binary compatibility between Windows XP (which miss - * IPV6_V6ONLY define), and newer Windows that has it. - * @see http://lua-users.org/lists/lua-l/2013-04/msg00191.html - */ -#ifndef IPV6_V6ONLY -# define IPV6_V6ONLY 27 -#endif - -/* 64 bit conversions */ -#ifndef ntohll -uint64_t ntohll(uint64_t x); -#endif -#ifndef htonll -uint64_t htonll(uint64_t x); -#endif - -/* blank a network address */ -void sockaddr_clear(struct sockaddr_in *addr); - -/* determine network type (moved from pqi/pqinetwork.cc) */ -bool isValidNet(const struct in_addr *addr); -bool isLoopbackNet(const struct in_addr *addr); -bool isPrivateNet(const struct in_addr *addr); -bool isLinkLocalNet(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 sockaddr_in&); -std::ostream& operator<<(std::ostream& o, const sockaddr_storage&); - -/* thread-safe version of inet_ntoa */ -std::string rs_inet_ntoa(struct in_addr in); - - -/***************************/ -// sockaddr_storage fns. - -int rs_bind(int fd, const sockaddr_storage& addr); - -void sockaddr_storage_clear(struct sockaddr_storage &addr); - -// mods. -bool sockaddr_storage_zeroip(struct sockaddr_storage &addr); - -/** - * @brief Use this function to copy sockaddr_storage. - * - * POSIX does not require that objects of type sockaddr_storage can be copied - * as aggregates thus it is unsafe to aggregate copy ( operator = ) - * sockaddr_storage and unexpected behaviors may happens due to padding - * and alignment. - * - * @see https://sourceware.org/bugzilla/show_bug.cgi?id=20111 - * @see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71120 - */ -bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst); - -bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src); -uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr); -bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port); - -bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4); -bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6); - -bool sockaddr_storage_inet_pton( sockaddr_storage &addr, - const std::string& ipStr ); -bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name); - -bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, const uint16_t port); - -bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr); -bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr); - -// comparisons. -bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b); - -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); - -// string, -std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr); -bool sockaddr_storage_fromString(const std::string& str, sockaddr_storage &addr); -std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr); -std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr); -std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr); -void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString = NULL); - -// net checks. -bool sockaddr_storage_isnull(const struct sockaddr_storage &addr); -bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr); -bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr); - -bool sockaddr_storage_inet_ntop(const sockaddr_storage &addr, std::string &dst); - -int rs_setsockopt( int sockfd, int level, int optname, - const uint8_t *optval, uint32_t optlen ); - -#endif /* RS_UNIVERSAL_NETWORK_HEADER */ diff --git a/libretroshare/src/util/rsnet_ss.cc b/libretroshare/src/util/rsnet_ss.cc deleted file mode 100644 index c084f516e..000000000 --- a/libretroshare/src/util/rsnet_ss.cc +++ /dev/null @@ -1,1282 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsnet_ss.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2004-2006 Robert Fernie * - * Copyright 2015-2018 Gioacchino Mazzurco * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsurl.h" - -#include -#include -#include - -#ifdef WINDOWS_SYS -# include -/** Provides Linux like accessor for in6_addr.s6_addr16 for Windows. - * Yet Windows doesn't provide 32 bits accessors so there is no way to use - * in6_addr.s6_addr32 crossplatform. - */ -# define s6_addr16 u.Word -#else -# include -# include -# include -# ifdef __APPLE__ -/// Provides Linux like accessor for in6_addr.s6_addr16 for Mac. -# define s6_addr16 __u6_addr.__u6_addr16 -#endif // __APPLE__ -#endif // WINDOWS_SYS - -#include "util/rsnet.h" -#include "util/rsstring.h" -#include "pqi/pqinetwork.h" -#include "util/stacktrace.h" - -/***************************** Internal Helper Fns ******************************/ - -/******************************** Casting **************************************/ -struct sockaddr_in *to_ipv4_ptr(struct sockaddr_storage &addr); -struct sockaddr_in6 *to_ipv6_ptr(struct sockaddr_storage &addr); - -const struct sockaddr_in *to_const_ipv4_ptr(const struct sockaddr_storage &addr); -const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr); - - -/******************************** Set / Clear ***********************************/ - -bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src); - -uint16_t sockaddr_storage_ipv4_port(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, uint16_t port); - -bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src); - -uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port); - -/******************************** Comparisions **********************************/ - -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_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); - - -/********************************* Output ***********************************/ -std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr); -std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage &addr); - -/********************************* Net Checks ***********************************/ -bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_isValidNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_isLoopbackNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_isPrivateNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv4_isExternalNet(const struct sockaddr_storage &addr); - -bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &addr); -bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &addr); - - -/***************************/ - -/******************************** Socket Fns ***********************************/ -// Standard bind, on OSX anyway will not accept a longer socklen for IPv4. -// so hidding details behind function. -int rs_bind(int fd, const sockaddr_storage& addr) -{ -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - socklen_t len = 0; - switch (addr.ss_family) - { - case AF_INET: - len = sizeof(struct sockaddr_in); - break; - case AF_INET6: - len = sizeof(struct sockaddr_in6); - break; - } - - return bind(fd, reinterpret_cast(&addr), len); -} - - - - -/******************************** Set / Clear ***********************************/ - -void sockaddr_storage_clear(struct sockaddr_storage &addr) -{ - memset(&addr, 0, sizeof(addr)); -} - -// mods. -bool sockaddr_storage_zeroip(struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_zeroip()"; - std::cerr << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_zeroip(addr); - break; - case AF_INET6: - return sockaddr_storage_ipv6_zeroip(addr); - break; - default: - std::cerr << "sockaddr_storage_zeroip() invalid addr.ss_family clearing whole address"; - std::cerr << std::endl; - sockaddr_storage_clear(addr); - break; - } - return false; -} - -bool sockaddr_storage_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_copyip()" << std::endl; -#endif - - switch(src.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_copyip(dst, src); - break; - case AF_INET6: - return sockaddr_storage_ipv6_copyip(dst, src); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_copyip() Unknown ss_family: " << src.ss_family << std::endl; -#endif - break; - } - return false; -} - - -uint16_t sockaddr_storage_port(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_port()" << std::endl; -#endif - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_port(addr); - case AF_INET6: - return sockaddr_storage_ipv6_port(addr); - default: - std::cerr << "sockaddr_storage_port() invalid addr.ss_family" << std::endl; -#ifdef SS_DEBUG - sockaddr_storage_dump(addr); - print_stacktrace(); -#endif - break; - } - return 0; -} - -bool sockaddr_storage_setport(struct sockaddr_storage &addr, uint16_t port) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_setport()" << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_setport(addr, port); - break; - case AF_INET6: - return sockaddr_storage_ipv6_setport(addr, port); - break; - default: - std::cerr << "sockaddr_storage_setport() invalid addr.ss_family" << std::endl; - break; - } - return false; -} - - -bool sockaddr_storage_setipv4(struct sockaddr_storage &addr, const sockaddr_in *addr_ipv4) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_setipv4()"; - std::cerr << std::endl; -#endif - - sockaddr_storage_clear(addr); - struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); - - ipv4_ptr->sin_family = AF_INET; - ipv4_ptr->sin_addr = addr_ipv4->sin_addr; - ipv4_ptr->sin_port = addr_ipv4->sin_port; - - return true; -} - -bool sockaddr_storage_setipv6(struct sockaddr_storage &addr, const sockaddr_in6 *addr_ipv6) -{ - std::cerr << "sockaddr_storage_setipv6()" << std::endl; - - sockaddr_storage_clear(addr); - struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); - - ipv6_ptr->sin6_family = AF_INET6; - ipv6_ptr->sin6_addr = addr_ipv6->sin6_addr; - ipv6_ptr->sin6_port = addr_ipv6->sin6_port; - - return true; -} - -#ifdef WINDOWS_SYS -int inet_pton(int af, const char *src, void *dst) -{ - sockaddr_storage ss; - int size = sizeof(ss); - char src_copy[INET6_ADDRSTRLEN+1]; - - ZeroMemory(&ss, sizeof(ss)); - /* stupid non-const API */ - strncpy (src_copy, src, INET6_ADDRSTRLEN+1); - src_copy[INET6_ADDRSTRLEN] = 0; - - if (WSAStringToAddressA(src_copy, af, NULL, (sockaddr *)&ss, &size) == 0) - { - switch(af) - { - case AF_INET: - *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; - return 1; - case AF_INET6: - *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; - return 1; - } - } - return 0; -} -#endif - -bool sockaddr_storage_inet_pton( sockaddr_storage &addr, - const std::string& ipStr ) -{ -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - struct sockaddr_in6 * addrv6p = (struct sockaddr_in6 *) &addr; - struct sockaddr_in * addrv4p = (struct sockaddr_in *) &addr; - - if ( 1 == inet_pton(AF_INET6, ipStr.c_str(), &(addrv6p->sin6_addr)) ) - { - addr.ss_family = AF_INET6; - return true; - } - else if ( 1 == inet_pton(AF_INET, ipStr.c_str(), &(addrv4p->sin_addr)) ) - { - addr.ss_family = AF_INET; - return sockaddr_storage_ipv4_to_ipv6(addr); - } - - return false; -} - - -bool sockaddr_storage_ipv4_aton(struct sockaddr_storage &addr, const char *name) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_aton()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); - ipv4_ptr->sin_family = AF_INET; - return (1 == inet_aton(name, &(ipv4_ptr->sin_addr))); -} - -bool sockaddr_storage_ipv4_to_ipv6(sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - if ( addr.ss_family == AF_INET6 ) return true; - - if ( addr.ss_family == AF_INET ) - { - sockaddr_in & addr_ipv4 = (sockaddr_in &) addr; - sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr; - - uint32_t ip = addr_ipv4.sin_addr.s_addr; - uint16_t port = addr_ipv4.sin_port; - - sockaddr_storage_clear(addr); - addr_ipv6.sin6_family = AF_INET6; - addr_ipv6.sin6_port = port; - addr_ipv6.sin6_addr.s6_addr16[5] = htons(0xffff); - memmove( reinterpret_cast(&(addr_ipv6.sin6_addr.s6_addr16[6])), - reinterpret_cast(&ip), 4 ); - return true; - } - - return false; -} - -bool sockaddr_storage_ipv6_to_ipv4(sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - if ( addr.ss_family == AF_INET ) return true; - - if ( addr.ss_family == AF_INET6 ) - { - sockaddr_in6 & addr_ipv6 = (sockaddr_in6 &) addr; - bool ipv4m = addr_ipv6.sin6_addr.s6_addr16[5] == htons(0xffff); - for ( int i = 0; ipv4m && i < 5 ; ++i ) - ipv4m &= addr_ipv6.sin6_addr.s6_addr16[i] == htons(0x0000); - - if(ipv4m) - { - uint32_t ip; - memmove( reinterpret_cast(&ip), - reinterpret_cast(&(addr_ipv6.sin6_addr.s6_addr16[6])), - 4 ); - uint16_t port = addr_ipv6.sin6_port; - - sockaddr_in & addr_ipv4 = (sockaddr_in &) addr; - - sockaddr_storage_clear(addr); - addr_ipv4.sin_family = AF_INET; - addr_ipv4.sin_port = port; - addr_ipv4.sin_addr.s_addr = ip; - - return true; - } - } - - return false; -} - - -/******************************** Comparisions **********************************/ - -bool operator<(const struct sockaddr_storage &a, const struct sockaddr_storage &b) -{ - if (!sockaddr_storage_samefamily(a, b)) - { - return (a.ss_family < b.ss_family); - } - - switch(a.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_lessthan(a, b); - break; - case AF_INET6: - return sockaddr_storage_ipv6_lessthan(a, b); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_operator<() INVALID Family - error"; - std::cerr << std::endl; -#endif - break; - } - return false; -} - - -bool sockaddr_storage_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_same()"; - std::cerr << std::endl; -#endif - - if (!sockaddr_storage_samefamily(addr, addr2)) - return false; - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_same(addr, addr2); - break; - case AF_INET6: - return sockaddr_storage_ipv6_same(addr, addr2); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_same() INVALID Family - error"; - std::cerr << std::endl; -#endif - break; - } - return false; -} - - -bool sockaddr_storage_samefamily(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_samefamily()"; - std::cerr << std::endl; -#endif - - return (addr.ss_family == addr2.ss_family); -} - -bool sockaddr_storage_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_sameip()"; - std::cerr << std::endl; -#endif - - if (!sockaddr_storage_samefamily(addr, addr2)) - return false; - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_sameip(addr, addr2); - break; - case AF_INET6: - return sockaddr_storage_ipv6_sameip(addr, addr2); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_sameip() INVALID Family - error"; - std::cerr << std::endl; -#endif - break; - } - return false; -} - -/********************************* Output ***********************************/ - -std::string sockaddr_storage_tostring(const struct sockaddr_storage &addr) -{ - RsUrl url; - - switch(addr.ss_family) - { - case AF_INET: - url.setScheme("ipv4"); - break; - case AF_INET6: - url.setScheme("ipv6"); - break; - default: - return "AF_INVALID"; - } - - url.setHost(sockaddr_storage_iptostring(addr)) - .setPort(sockaddr_storage_port(addr)); - - return url.toString(); -} - -bool sockaddr_storage_fromString(const std::string& str, sockaddr_storage &addr) -{ - RsUrl url(str); - bool valid = sockaddr_storage_inet_pton(addr, url.host()); - if(url.hasPort()) sockaddr_storage_setport(addr, url.port()); - return valid; -} - -void sockaddr_storage_dump(const sockaddr_storage & addr, std::string * outputString) -{ - // This function must not rely on others sockaddr_storage_* - - std::stringstream output; - output << "sockaddr_storage_dump(addr) "; - - switch (addr.ss_family) - { - case AF_INET: - { - const sockaddr_in * in = (const sockaddr_in *) & addr; - output << "addr.ss_family = AF_INET"; - output << " in->sin_addr = "; - output << inet_ntoa(in->sin_addr); - output << " in->sin_port = "; - output << in->sin_port; - break; - } - case AF_INET6: - { - const sockaddr_in6 * in6 = (const sockaddr_in6 *) & addr; - std::string addrStr = "INVALID_IPV6"; - sockaddr_storage_inet_ntop(addr, addrStr); - output << "addr.ss_family = AF_INET6"; - output << " in6->sin6_addr = "; - output << addrStr; - output << " in6->sin6_scope_id = "; - output << in6->sin6_scope_id; - output << " in6->sin6_port = "; - output << in6->sin6_port; - break; - } - default: - { - output << "unknown addr.ss_family "; - const uint8_t * buf = reinterpret_cast(&addr); - for( uint32_t i = 0; i < sizeof(addr); ++i ) - output << std::setw(2) << std::setfill('0') << std::hex << +buf[i]; - /* The unary +buf[i] operation forces a no-op type conversion to an int - * with the correct sign */ - } - } - - if(outputString) - { - outputString->append(output.str() + "\n"); -#ifdef SS_DEBUG - std::cerr << output.str() << std::endl; -#endif - } - else - std::cerr << output.str() << std::endl; -} - -std::string sockaddr_storage_familytostring(const struct sockaddr_storage &addr) -{ - std::string output; - switch(addr.ss_family) - { - case AF_INET: - output = "IPv4"; - break; - case AF_INET6: - output = "IPv6"; - break; - default: - output = "AF_INVALID"; -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Got invalid address!" - << std::endl; - sockaddr_storage_dump(addr); - print_stacktrace(); -#endif - break; - } - return output; -} - -std::string sockaddr_storage_iptostring(const struct sockaddr_storage &addr) -{ - std::string output; - switch(addr.ss_family) - { - case AF_INET: - output = sockaddr_storage_ipv4_iptostring(addr); - break; - case AF_INET6: - output = sockaddr_storage_ipv6_iptostring(addr); - break; - default: - output = "INVALID_IP"; - std::cerr << __PRETTY_FUNCTION__ << " Got invalid IP!" << std::endl; -#ifdef SS_DEBUG - sockaddr_storage_dump(addr); - print_stacktrace(); -#endif - break; - } - return output; -} - -std::string sockaddr_storage_porttostring(const struct sockaddr_storage &addr) -{ - std::string output; - uint16_t port = sockaddr_storage_port(addr); - rs_sprintf(output, "%u", port); - return output; -} - - -/********************************* Net Checks ***********************************/ -bool sockaddr_storage_isnull(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isnull()"; - std::cerr << std::endl; -#endif - - if (addr.ss_family == 0) - return true; - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_isnull(addr); - break; - case AF_INET6: - return sockaddr_storage_ipv6_isnull(addr); - break; - default: - return true; - break; - } - return true; -} - -bool sockaddr_storage_isValidNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isValidNet()" << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_isValidNet(addr); - case AF_INET6: - return sockaddr_storage_ipv6_isValidNet(addr); - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isValidNet() INVALID Family" << std::endl; - sockaddr_storage_dump(addr); -#endif - break; - } - return false; -} - -bool sockaddr_storage_isLoopbackNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isLoopbackNet()"; - std::cerr << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_isLoopbackNet(addr); - break; - case AF_INET6: - return sockaddr_storage_ipv6_isLoopbackNet(addr); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isLoopbackNet() INVALID Family - error: " << sockaddr_storage_iptostring(addr); - std::cerr << std::endl; -#endif - break; - } - return false; -} - - -bool sockaddr_storage_isPrivateNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isPrivateNet()"; - std::cerr << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_isPrivateNet(addr); - break; - case AF_INET6: - return sockaddr_storage_ipv6_isPrivateNet(addr); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isPrivateNet() INVALID Family - error: " << sockaddr_storage_iptostring(addr); - std::cerr << std::endl; -#endif - break; - } - return false; -} - -bool sockaddr_storage_isLinkLocalNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return isLinkLocalNet(&(to_const_ipv4_ptr(addr)->sin_addr)); - case AF_INET6: - return sockaddr_storage_ipv6_isLinkLocalNet(addr); - default: -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ <<" INVALID Family:" << std::endl; - sockaddr_storage_dump(addr); -#endif - break; - } - - return false; -} - -bool sockaddr_storage_ipv6_isLinkLocalNet(const sockaddr_storage &addr) -{ - if(addr.ss_family != AF_INET6) return false; - - const sockaddr_in6 * addr6 = (const sockaddr_in6 *) &addr; - uint16_t mask = htons(0xffc0); - uint16_t llPrefix = htons(0xfe80); - return ((addr6->sin6_addr.s6_addr16[0] & mask ) == llPrefix); -} - - -bool sockaddr_storage_isExternalNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isExternalNet()"; - std::cerr << std::endl; -#endif - - switch(addr.ss_family) - { - case AF_INET: - return sockaddr_storage_ipv4_isExternalNet(addr); - break; - case AF_INET6: - return sockaddr_storage_ipv6_isExternalNet(addr); - break; - default: -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_isExternalNet() INVALID Family - error"; - std::cerr << std::endl; -#endif - break; - } - return false; -} - - - - - -/***************************** Internal Helper Fns ******************************/ - - -/******************************** Casting **************************************/ - -struct sockaddr_in *to_ipv4_ptr(struct sockaddr_storage &addr) -{ - struct sockaddr_in *ipv4_ptr = (struct sockaddr_in *) &addr; - return ipv4_ptr; -} - -struct sockaddr_in6 *to_ipv6_ptr(struct sockaddr_storage &addr) -{ - struct sockaddr_in6 *ipv6_ptr = (struct sockaddr_in6 *) &addr; - return ipv6_ptr; -} - -const struct sockaddr_in *to_const_ipv4_ptr(const struct sockaddr_storage &addr) -{ - const struct sockaddr_in *ipv4_ptr = (const struct sockaddr_in *) &addr; - return ipv4_ptr; -} - -const struct sockaddr_in6 *to_const_ipv6_ptr(const struct sockaddr_storage &addr) -{ - const struct sockaddr_in6 *ipv6_ptr = (const struct sockaddr_in6 *) &addr; - return ipv6_ptr; -} - - -/******************************** Set / Clear ***********************************/ - -bool sockaddr_storage_copy(const sockaddr_storage& src, sockaddr_storage& dst) -{ - if(&src == &dst) return true; - - switch(src.ss_family) - { - case AF_INET: - { - sockaddr_storage_clear(dst); - const sockaddr_in& ins(reinterpret_cast(src)); - sockaddr_in& ind(reinterpret_cast(dst)); - - ind.sin_family = AF_INET; - ind.sin_addr.s_addr = ins.sin_addr.s_addr; - ind.sin_port = ins.sin_port; - - return true; - } - case AF_INET6: - { - sockaddr_storage_clear(dst); - const sockaddr_in6& ins6(reinterpret_cast(src)); - sockaddr_in6& ind6(reinterpret_cast(dst)); - - ind6.sin6_family = AF_INET6; - for(int i=0; i<8; ++i) - ind6.sin6_addr.s6_addr16[i] = ins6.sin6_addr.s6_addr16[i]; - ind6.sin6_flowinfo = ins6.sin6_flowinfo; - ind6.sin6_port = ins6.sin6_port; - ind6.sin6_scope_id = ins6.sin6_scope_id; - - return true; - } - default: -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " Attempt to copy unknown family! " - << src.ss_family << " defaulting to memmove!" << std::endl; - sockaddr_storage_dump(src); - print_stacktrace(); -#endif // SS_DEBUG - memmove(&dst, &src, sizeof(sockaddr_storage)); - return true; - } -} - -bool sockaddr_storage_ipv4_zeroip(struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_zeroip()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); - memset(&(ipv4_ptr->sin_addr), 0, sizeof(ipv4_ptr->sin_addr)); - return true; -} - - -bool sockaddr_storage_ipv4_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_copyip()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in *dst_ptr = to_ipv4_ptr(dst); - const struct sockaddr_in *src_ptr = to_const_ipv4_ptr(src); - - dst_ptr->sin_family = AF_INET; - memcpy(&(dst_ptr->sin_addr), &(src_ptr->sin_addr), sizeof(src_ptr->sin_addr)); - return true; -} - -uint16_t sockaddr_storage_ipv4_port(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_port()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in *ipv4_ptr = to_const_ipv4_ptr(addr); - uint16_t port = ntohs(ipv4_ptr->sin_port); - return port; -} - -bool sockaddr_storage_ipv4_setport(struct sockaddr_storage &addr, uint16_t port) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_setport()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in *ipv4_ptr = to_ipv4_ptr(addr); - ipv4_ptr->sin_port = htons(port); - return true; -} - -bool sockaddr_storage_ipv6_zeroip(struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_zeroip()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); - memset(&(ipv6_ptr->sin6_addr), 0, sizeof(ipv6_ptr->sin6_addr)); - return true; -} - -bool sockaddr_storage_ipv6_copyip(struct sockaddr_storage &dst, const struct sockaddr_storage &src) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_copyip()" << std::endl; -#endif - - struct sockaddr_in6 *dst_ptr = to_ipv6_ptr(dst); - const struct sockaddr_in6 *src_ptr = to_const_ipv6_ptr(src); - - dst_ptr->sin6_family = AF_INET6; - memcpy(&(dst_ptr->sin6_addr), &(src_ptr->sin6_addr), sizeof(src_ptr->sin6_addr)); - return true; -} - -uint16_t sockaddr_storage_ipv6_port(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_port()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in6 *ipv6_ptr = to_const_ipv6_ptr(addr); - uint16_t port = ntohs(ipv6_ptr->sin6_port); - return port; -} - -bool sockaddr_storage_ipv6_setport(struct sockaddr_storage &addr, uint16_t port) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_setport()"; - std::cerr << std::endl; -#endif - - struct sockaddr_in6 *ipv6_ptr = to_ipv6_ptr(addr); - ipv6_ptr->sin6_port = htons(port); - return true; -} - - -/******************************** Comparisions **********************************/ - -bool sockaddr_storage_ipv4_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_lessthan()"; - 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); - - if (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr) - { - return ptr1->sin_port < ptr2->sin_port; - } - return (ptr1->sin_addr.s_addr < ptr2->sin_addr.s_addr); -} - -bool sockaddr_storage_ipv4_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_same()"; - 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 (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr) && - (ptr1->sin_port == ptr2->sin_port); -} - -bool sockaddr_storage_ipv4_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_sameip()"; - 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 (ptr1->sin_addr.s_addr == ptr2->sin_addr.s_addr); -} - -// IPV6 -bool sockaddr_storage_ipv6_lessthan(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_lessthan()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); - const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); - - uint32_t *ip6addr1 = (uint32_t *) ptr1->sin6_addr.s6_addr; - uint32_t *ip6addr2 = (uint32_t *) ptr2->sin6_addr.s6_addr; - for(int i = 0; i < 4; i++) - { - if (ip6addr1[i] == ip6addr2[i]) - { - continue; - } - - return (ip6addr1[i] < ip6addr2[i]); - } - - return (ptr1->sin6_port < ptr2->sin6_port); -} - -bool sockaddr_storage_ipv6_same(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_same()"; - std::cerr << std::endl; -#endif - const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); - const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); - - return sockaddr_storage_ipv6_sameip(addr, addr2) && (ptr1->sin6_port == ptr2->sin6_port); -} - -bool sockaddr_storage_ipv6_sameip(const struct sockaddr_storage &addr, const struct sockaddr_storage &addr2) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv6_sameip()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in6 *ptr1 = to_const_ipv6_ptr(addr); - const struct sockaddr_in6 *ptr2 = to_const_ipv6_ptr(addr2); - - uint32_t *ip6addr1 = (uint32_t *) ptr1->sin6_addr.s6_addr; - uint32_t *ip6addr2 = (uint32_t *) ptr2->sin6_addr.s6_addr; - - for(int i = 0; i < 4; i++) - { - if (ip6addr1[i] != ip6addr2[i]) - { - return false; - } - } - return true; -} - -/********************************* Output ***********************************/ -std::string sockaddr_storage_ipv4_iptostring(const struct sockaddr_storage &addr) -{ - const struct sockaddr_in *ptr = to_const_ipv4_ptr(addr); - std::string output; - output = rs_inet_ntoa(ptr->sin_addr); - return output; -} - -std::string sockaddr_storage_ipv6_iptostring(const struct sockaddr_storage & addr) -{ - std::string addrStr; - sockaddr_storage_inet_ntop(addr, addrStr); - return addrStr; -} - - -/********************************* Net Checks ***********************************/ -bool sockaddr_storage_ipv4_isnull(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_isnull()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - if (ptr1->sin_family != AF_INET) - { - return true; - } - if ((ptr1->sin_addr.s_addr == 0) || (ptr1->sin_addr.s_addr == 1)) - { - return true; - } - return false; -} - -bool sockaddr_storage_ipv4_isValidNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_isValidNet()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - if (ptr1->sin_family != AF_INET) - { - return false; - } - return isValidNet(&(ptr1->sin_addr)); -} - - -bool sockaddr_storage_ipv4_isLoopbackNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_isLoopbackNet()"; - std::cerr << std::endl; -#endif - - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - if (ptr1->sin_family != AF_INET) - { - return false; - } - return isLoopbackNet(&(ptr1->sin_addr)); -} - -bool sockaddr_storage_ipv4_isPrivateNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_isPrivateNet()"; - std::cerr << std::endl; -#endif - - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - if (ptr1->sin_family != AF_INET) - { - return false; - } - return isPrivateNet(&(ptr1->sin_addr)); -} - -bool sockaddr_storage_ipv4_isExternalNet(const struct sockaddr_storage &addr) -{ -#ifdef SS_DEBUG - std::cerr << "sockaddr_storage_ipv4_isExternalNet()"; - std::cerr << std::endl; -#endif - - const struct sockaddr_in *ptr1 = to_const_ipv4_ptr(addr); - if (ptr1->sin_family != AF_INET) - { - return false; - } - return isExternalNet(&(ptr1->sin_addr)); -} - - -bool sockaddr_storage_ipv6_isnull(const struct sockaddr_storage& addr) -{ - const sockaddr_in6& addr6 = reinterpret_cast(addr); - - uint16_t nZero = htons(0); // anyway 0 should be the same in host and net - bool isZero = (addr6.sin6_addr.s6_addr16[7] == nZero); - for (int i=0; isZero && i<7; ++i) - isZero &= (addr6.sin6_addr.s6_addr16[i] == nZero); - - return nZero; -} - -bool sockaddr_storage_ipv6_isValidNet(const struct sockaddr_storage& addr) -{ - return !sockaddr_storage_ipv6_isnull(addr); -} - -bool sockaddr_storage_ipv6_isLoopbackNet(const struct sockaddr_storage& addr) -{ - const sockaddr_in6& addr6 = reinterpret_cast(addr); - bool isLoopBack = (addr6.sin6_addr.s6_addr16[7] == htons(0x0001)); - uint16_t nZero = htons(0); // anyway 0 should be the same in host and net - for (int i=0; isLoopBack && i<7; ++i) - isLoopBack &= (addr6.sin6_addr.s6_addr16[i] == nZero); - -#ifdef SS_DEBUG - std::cerr << __PRETTY_FUNCTION__ << " " << sockaddr_storage_tostring(addr) - << " " << isLoopBack << std::endl; -#endif - - return isLoopBack; -} - -bool sockaddr_storage_ipv6_isPrivateNet(const struct sockaddr_storage &/*addr*/) -{ - /* It is unlikely that we end up connecting to an IPv6 address behind NAT - * W.R.T. RS it is probably better to consider all IPv6 as internal/local - * addresses as direct connection should be always possible. */ - - return true; -} - -bool sockaddr_storage_ipv6_isExternalNet(const struct sockaddr_storage &/*addr*/) -{ - /* It is unlikely that we end up connecting to an IPv6 address behind NAT - * W.R.T. RS it is probably better to consider all IPv6 as internal/local - * addresses as direct connection should be always possible. */ - - return false; -} - -bool sockaddr_storage_inet_ntop (const sockaddr_storage &addr, std::string &dst) -{ - bool success = false; - char ipStr[255]; - -#ifdef WINDOWS_SYS - // Use WSAAddressToString instead of InetNtop because the latter is missing - // on XP and is present only on Vista and newers - wchar_t wIpStr[255]; - long unsigned int len = 255; - sockaddr_storage tmp; - sockaddr_storage_clear(tmp); - sockaddr_storage_copyip(tmp, addr); - sockaddr * sptr = (sockaddr *) &tmp; - success = (0 == WSAAddressToString( sptr, sizeof(sockaddr_storage), NULL, wIpStr, &len )); - wcstombs(ipStr, wIpStr, len); -#else // WINDOWS_SYS - switch(addr.ss_family) - { - case AF_INET: - { - const struct sockaddr_in * addrv4p = (const struct sockaddr_in *) &addr; - success = inet_ntop( addr.ss_family, (const void *) &(addrv4p->sin_addr), ipStr, INET_ADDRSTRLEN ); - } - break; - case AF_INET6: - { - const struct sockaddr_in6 * addrv6p = (const struct sockaddr_in6 *) &addr; - success = inet_ntop( addr.ss_family, (const void *) &(addrv6p->sin6_addr), ipStr, INET6_ADDRSTRLEN ); - } - break; - } -#endif // WINDOWS_SYS - - dst = ipStr; - return success; -} - -int rs_setsockopt( int sockfd, int level, int optname, - const uint8_t *optval, uint32_t optlen ) -{ -#ifdef WINDOWS_SYS - return setsockopt( sockfd, level, optname, - reinterpret_cast(optval), optlen ); -#else - return setsockopt( sockfd, level, optname, - reinterpret_cast(optval), optlen ); -#endif // WINDOWS_SYS -} diff --git a/libretroshare/src/util/rsprint.cc b/libretroshare/src/util/rsprint.cc deleted file mode 100644 index 4e547736a..000000000 --- a/libretroshare/src/util/rsprint.cc +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsprint.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "util/rsprint.h" -#include "util/rsstring.h" -#include -#include -#include -#include - -#ifdef WINDOWS_SYS -#include "util/rstime.h" -#include -#endif - -std::string RsUtil::NumberToString(uint64_t n,bool hex) -{ - std::ostringstream os ; - - if(hex) - os << std::hex ; - - os << n ; - os.flush() ; - - return os.str(); -} - -std::string RsUtil::BinToHex(const std::string &bin) -{ - return BinToHex(bin.c_str(), bin.length()); -} - -std::string RsUtil::BinToHex(const unsigned char *arr, const uint32_t len,uint32_t max_len) -{ - if(max_len > 0) - return BinToHex((char*)arr,std::min(max_len,len)) + ((len > max_len)?"...":"") ; - else - return BinToHex((char*)arr,len) ; -} -std::string RsUtil::BinToHex(const char *arr, const uint32_t len) -{ - std::string out; - - for(uint32_t j = 0; j < len; j++) - { - rs_sprintf_append(out, "%02x", (int32_t) (((const uint8_t *) arr)[j])); - } - - return out; -} - -std::string RsUtil::HashId(const std::string &id, bool reverse) -{ - std::string hash; - std::string tohash; - if (reverse) - { - std::string::const_reverse_iterator rit; - for(rit = id.rbegin(); rit != id.rend(); ++rit) - { - tohash += (*rit); - } - } - else - { - tohash = id; - } - - SHA_CTX *sha_ctx = new SHA_CTX; - uint8_t sha_hash[SHA_DIGEST_LENGTH]; - - SHA1_Init(sha_ctx); - SHA1_Update(sha_ctx, tohash.c_str(), tohash.length()); - SHA1_Final(sha_hash, sha_ctx); - - for(uint16_t i = 0; i < SHA_DIGEST_LENGTH; i++) - { - hash += sha_hash[i]; - } - - /* cleanup */ - delete sha_ctx; - - return hash; -} - -static int toHalfByte(char u,bool& ok) -{ - if(u >= 'a' && u <= 'f') return u-'a' + 0xa; - if(u >= 'A' && u <= 'F') return u-'A' + 0xa; - if(u >= '0' && u <= '9') return u-'0' + 0x0; - - ok = false ; - - return 0; -} - -bool RsUtil::HexToBin(const std::string& input,unsigned char *data, const uint32_t len) -{ - if(input.size() & 1) - return false ; - - if(len != input.size()/2) - return false ; - - bool ok = true ; - - for(uint32_t i=0;(i RsUtil::BinToSha256(const std::vector &in) -{ - std::vector out; - - SHA256_CTX *sha_ctx = new SHA256_CTX; - uint8_t sha_hash[SHA256_DIGEST_LENGTH] = {0}; - - SHA256_Init(sha_ctx); - SHA256_Update(sha_ctx, in.data(), in.size()); - SHA256_Final(sha_hash, sha_ctx); - - for(uint16_t i = 0; i < SHA256_DIGEST_LENGTH; i++) - { - out.push_back(sha_hash[i]); - } - - /* cleanup */ - delete sha_ctx; - return out; -} diff --git a/libretroshare/src/util/rsprint.h b/libretroshare/src/util/rsprint.h deleted file mode 100644 index dcaab6311..000000000 --- a/libretroshare/src/util/rsprint.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsprint.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2008-2008 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSUTIL_PRINTFNS_H -#define RSUTIL_PRINTFNS_H - -#include -#include -#include - -namespace RsUtil { - -std::string BinToHex(const std::string &bin); -std::string BinToHex(const char *arr, const uint32_t len); - -// proxy function. When max_len>0 and len>max_len, only the first "max_len" bytes are writen to the string and "..." is happened. - -std::string BinToHex(const unsigned char *arr, const uint32_t len, uint32_t max_len=0); -bool HexToBin(const std::string& input,unsigned char *data, const uint32_t len); -std::string NumberToString(uint64_t n, bool hex=false); -std::string HashId(const std::string &id, bool reverse = false); -std::vector BinToSha256(const std::vector &in); - -//std::string AccurateTimeString(); - -} - -#endif diff --git a/libretroshare/src/util/rsrandom.cc b/libretroshare/src/util/rsrandom.cc deleted file mode 100644 index dc7d9ac67..000000000 --- a/libretroshare/src/util/rsrandom.cc +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsrandom.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2010 Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsrandom.h" - -#include -#include -#include -#include - -uint32_t RsRandom::index = RsRandom::N; -std::vector RsRandom::MT(RsRandom::N,0u); -RsMutex RsRandom::rndMtx("RsRandom"); - -/* According to our tests (cyril+thunder), on both Windows and Linux does - * RAND_bytes init itself automatically at first call, from system-based - * unpredictable values, so that seeding is not even needed. - * This call still adds some randomness (not much actually, but it's always good - * to have anyway) */ -#ifdef WINDOWS_SYS -# include "util/rstime.h" -# ifdef WIN_PTHREADS_H -static bool auto_seed = RsRandom::seed( - (time(nullptr) + - static_cast(pthread_self()) *0x1293fe)^0x18e34a12 ); -# else // def WIN_PTHREADS_H -static bool auto_seed = RsRandom::seed( - (time(nullptr) + - static_cast(pthread_self().p)*0x1293fe)^0x18e34a12 ); -# endif // def WIN_PTHREADS_H -#endif - -bool RsRandom::seed(uint32_t s) -{ - RS_STACK_MUTEX(rndMtx); - - MT.resize(N,0) ; // because MT might not be already resized - - uint32_t j ; - MT[0]= s & 0xffffffffUL; - for (j=1; j> 30)) + j) & 0xffffffffUL ; - - // This *does not* replace the internal seed state of RAND_bytes(), but only *adds* entropy to the random pool - // So calling this method with the same value twice does not guarranty that the output of the random bytes - // will be the same. - - RAND_seed((unsigned char *)&MT[0],N*sizeof(uint32_t)) ; - locked_next_state() ; - - return true ; -} - -void RsRandom::random_bytes(unsigned char *data,uint32_t size) -{ - RAND_bytes(data,size) ; -} -void RsRandom::locked_next_state() -{ - RAND_bytes((unsigned char *)&MT[0],N*sizeof(uint32_t)) ; - index = 0 ; -} - -uint32_t RsRandom::random_u32() -{ - uint32_t y; - - { - RS_STACK_MUTEX(rndMtx); - - index++ ; - - if(index >= N) - locked_next_state(); - - y = MT[index] ; - } - -#ifdef UNNECESSARY_CODE - // Tempering - y ^= (y >> 11); - y ^= (y << 7 ) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); -#endif - - return y; -} - -uint64_t RsRandom::random_u64() -{ - return ((uint64_t)random_u32() << 32ul) + random_u32() ; -} - -float RsRandom::random_f32() -{ - return random_u32() / (float)(~(uint32_t)0) ; -} - -double RsRandom::random_f64() -{ - return random_u64() / (double)(~(uint64_t)0) ; -} - -/*static*/ std::string RsRandom::alphaNumeric(uint32_t length) -{ - std::string s; - while(s.size() < length) - { - uint8_t rChar; random_bytes(&rChar, 1); rChar = rChar % 123; - /* if(isalnum(val)) isalnum result may vary depend on locale!! */ - if( (rChar >= 48 && rChar <= 57) /* 0-9 */ || - (rChar >= 65 && rChar <= 90) /* A-Z */ || - (rChar >= 97 && rChar <= 122) /* a-z */ ) - s += static_cast(rChar); - } - - return s; -} - -/*static*/ std::string RsRandom::printable(uint32_t length) -{ - std::string ret(length, 0); - random_bytes(reinterpret_cast(&ret[0]), length); - for(uint32_t i=0; i * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - - -#include -#include - -#include "util/rsthreads.h" -#include "util/rsdeprecate.h" - -/** - * RsRandom provide a random number generator that is - * - thread safe - * - platform independent - * - fast - * - CRYPTOGRAPHICALLY SAFE, because it is based on openssl random number - * generator - */ -class RsRandom -{ -public: - static uint32_t random_u32(); - static uint64_t random_u64(); - static float random_f32(); - static double random_f64(); - - static bool seed(uint32_t s); - - static void random_bytes(uint8_t* data, uint32_t length); - - /// Return a random alphanumeric *[0-9,A-Z,a-z] string of the given lenght - static std::string alphaNumeric(uint32_t length); - - /** Return a random printable string of the given lenght */ - static std::string printable(uint32_t length); - - /** This return a printable string not an alphanumeric one @deprecated */ - RS_DEPRECATED_FOR("RsRandom::printable") - static inline std::string random_alphaNumericString(uint32_t length) - { return printable(length); } - -private: - static RsMutex rndMtx; - - static const uint32_t N = 1024; - - static void locked_next_state(); - static uint32_t index; - static std::vector MT; -}; - -/// @deprecated this alias is provided only for code retro-compatibility -using RSRandom RS_DEPRECATED_FOR(RsRandom) = RsRandom; diff --git a/libretroshare/src/util/rsrecogn.cc b/libretroshare/src/util/rsrecogn.cc deleted file mode 100644 index 5cc0a5e09..000000000 --- a/libretroshare/src/util/rsrecogn.cc +++ /dev/null @@ -1,656 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsrandom.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "pqi/pqi_base.h" - -#include "util/rsrecogn.h" -#include "util/radix64.h" -#include "util/rsstring.h" -#include "util/rsdir.h" - -#include "gxs/gxssecurity.h" - -#include -#include - -/*** - * #define DEBUG_RECOGN 1 - ***/ - -#define DEBUG_RECOGN 1 - -static std::string RecognKey = "MIICCgKCAgEA4/i2fy+zR27/H8fzphM8mR/Nz+yXjMJTtqKlCvEMQlyk7lKzDbKifNjGSiAXjSv3b9TRgMtje7hfEhs3//Oeu4KsCf6sz17aj2StBF579IdJTSUPDwq6jCsZ6NDEYpG8xz3FVV+Ac8q5Vpr/+jdg23ta09zq4aV8VIdIsroVOmZQqjwPcmQK57iWHd538i/XBtc2rnzbYq5bprnmtAKdx55gXVXDfALa0s6yR0HYvCaWguMEJhMIKWfi/9PEgLgwF9OmRwywc2TU/EdvYJo8fYHLfGk0PnYBuL1oSnn3cwAAef02W2JyCzQ84g30tLSUk+hC1LLi+iYj3x7IRR4q7Rlf/FYv/Q5fvjRtPT9eqM6fKyJ9ZO4NjlrSPFGydNbgABzP6WMhBzFjUkEKS27bGmr8Qxdj3Zp0TvR2IkyM6oM+6YknuM4RndUEgC1ZxtoIhugMjm6HdMQmoaHNK3kXewgQB90HHqzKA/J1gok3NcqL8Yls5g0LHepVHsU4cuaIqQr5yr665ZTLU2oqn1HIdkgydBYYUt6G3eWJKXYRbDhWPthGo/HK+W+iw6cTGWxzlCZS40EU9efxz4mDuhow67jOe704lBP3kiYXu05Y5uspaYnuvrvIwaRWBYapyR9UmKktnY8xJYrZvrcZgCovAbiodTzWeYg37xjFfGgYNI8CAwEAAQ=="; - -#define NUM_RECOGN_SIGN_KEYS 3 -static std::string RecognSigningKeys[NUM_RECOGN_SIGN_KEYS] = -{ - "AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmYjI2ZTUyNGFlZjczYmY3Y2MyMzUwNTc0ZTMyMjcxZWEAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCyblJK73O/fMI1BXTjInHqIWma62Z2r3K7/giT6Xm3k+lyNokvpR+I45XdEvPRmFVZmTU7XT2n3YiPDLe7y2r9fnYiLvBCdu+FBaVv5UQG8nvFGMLKbhdyRpOSBgDc+Y+8plMPn8jqgfNhLROMowmvDJQkJQjlm80d/9wj+VZ+tLiPPo8uOlghqNhdXDGK7HnfeLrJyD8kLEW7+4huaxR8IsLgjzuK8rovGLYCBcnx4TXvtbEeafJBBBt8S/GPeUaB1rxWpVV6fi+oBU6cvjbEqPzSalIrwNPyqlj+1SbL1jGEGEr1XIMzDa96SVsJ0F93lS3H9c8HdvByAifgzbPZAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBp1w449QGjchVotgHvGWRh18zpsDUHRv8PlRX1vXy8FMstTrnRjaDofFitmpJm8K6F1t/9jviCdB+BCvRzAS4SxER49YCBp04xZfX7c03xdq/e27jYRds2w6YHTiEgNi5v1cyWhrwDcCdefXRnHTH1UOw3jOoWnlnmM6jEsL39XI5fvsog9z8GxcG54APKA7JgiqhgMcrKRwNk74XJAzcjB6FS8xaV2gzpZZLNZ1TU+tJoLSiRqTU8UiAGbAR85lYLT5Ozdd2C+bTQ9f6vltz8bpzicJzxGCIsYtSL44InQsO/Oar9IgZu8QE4pTuunGJhVqEZru7ZN+oV+wXt51n+24SS0sNgNKVUFS74RfvsFi67CrXSWTOI8bVS0Lvv3EMWMdSF9dHGbdCFnp2/wqbW/4Qz7XYF4lcu9gLe4UtIrZ6TkAvBtnSfvTTdXj7kD6oHDjrUCjHPxdhz3BLRbj1wENZsoS3QDl22Ts7dbO8wHjutsS3/zx4DLlADoFlU8p7HJaCdrsq20P4WCeQJb6JbbLpGRAccKAidAPHMxQ4fr3b+GtjxpLJtXaytr4CPSXsCt4TloE9g5yCE6n/2UxQACp8Guh9l2MXmrD7qEGexhYqFB/OG84u3vL+gskmsKXTEqi2SiSmhvzta2p2hGCLCKRQeYbn+4TsIQfgWtYNQvC", - "AvMxAwAAA5YQMAAAABAANAAAAAoAAAACEEAAAAFMAKQAAAAmYjY0OTJkODMzNTI5ZjMxMGM1MmRjMDc3ZjBmZDgyMjcAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQC2SS2DNSnzEMUtwHfw/YInm/XLXEUMktyZTmyMWACBbEfmU6aztT3vxz6UHoCBYtKkzKrfDZLvXe0a5TRLMmK+yfl5IzIVUPdqTg6FF3Bx/GXdj4v/ZP6lAuqY5YeI4wPcKldrrIJ9DTUdhZhgdtgDtxGvrXZ8eFjcl9zM+QEykYKMwfnTCixzVOPCCo3q1lJO13NmlhVQDO+f9vvTZsYDCcZHMqlKZWcCEyY1ZpQiCqlsL8wN6tKxMuSQO8EGdH/tNzsGHwCoZq6EEL7SX/pmc2ABjpDQTLixgXwJtCpw8Fwj1xiavsFFbqSLu3SjUCcrMz9f8U5p2ROyv//lWxsXAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBksDPQ93PdZBGCEnKXcQsdB4yBA9NpImVR81JZdPmWlTwZGAXGJwt4EkBcz+xdey84JDujVtHJUzIL9Ws/Jq5MuXHr0tP5ebah1GCQF2/Ov7sctUk3UPBxeroon7gZQhuzaIJVhl0rzwWriFUbTu7H7g9eaTHMvyfUg+S0Z2p+e0+PdL5rfGOJJZ6+NJCXxxbQ//cF4s0PAzkjAuwDmC+OiUiU5V6fY4XtRMCEI7w+UCj+wQn2Wu1Wc7xVM9uow13rGaLPYkWZ/9v+wNhg0KCsVfKGhkAGGzGyKI9LAppFVTu52pBlRu9Ung7VkhF0JC2aadYKKFl99wCbsGqUYN/gtfgHYCV24LNVah2dAy8CI9UmHdWk1kIwWazbPTYKLfpYCTFxqEqXqo3ijLf0YPsfhIvCQpc5VHAvLJlDm0RFKwzK6N9Zu9s9IvJHzIpaAAHCQJPtYxPwWMdt83njGo9wu1+aVkl5Sb5X8N16AybbnQ7fCBqJruGBM0LHtWVbHEiEygD7OStzyhT5rXKZSQYMA9I2CvK1t7qfDXDM40k8SVQ5CrS9R8x1wqQbe+DqNJ9tMfbUmN0xrO/w2pTl/4edKW30TShW/fr3vCWpVq8gcm3CVFSZUaC4T9wqH96K6KgIPbmg1Hk158pxXYXopEv6ZxR7UTPxKB0O22aIHB6UQ5", - "AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmOTdhNTJkMThjMDBjYWE3YmZlYmQ4NTg0MDJkMzBhY2QAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCXpS0YwAyqe/69hYQC0wrNz7eUHAmJfR5EV7NVFQeOxtTlFwbdvRMK8ZpfqEoRhIPXAYCc9Dv3F7WcmcFer8d50EWhlK7rCQScaRdwL1UmF1dUY8bR8QxhJOUgwmrlzeKOHi2DJ3/9AXm7NJR8XMJgHEQQwi3z/aQsWrwCUA0mk68C8a3vjLtcMj5XBuNXRtGZ9zFjiI9Xt19y0iIKdYpfzOnJTKVETcjH7XPBBbJETWkrEyToHXPjcfhESAbJDOoyfQQbxHMQNE7no7owN08LoWX2kOSGtl2m6JbE2OEdJig83a6U3PDYfYM5LCfsAJEIroYhB3qZJDE98zGC8jihAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBiwl7oRPJzLlwDd8AzVolFQH1ZS+MWLA4B1eHCjCXSMn+zS0Su6CrpC6/vLwECaKSfNZ8y7T2fNDPJHMLmc1F6jJkdNZq3TZGNRgJx24OF3G5MU6mAH7DBsz7muFto+URTJl9CdJviIyQAn5E+R4Gp531RJdKlbqJl/gWuQMVem+eo3elpVEn8Ckg0yvFaFdhGFTOPyrXOZ6fI0pdCX0SH2q/vAIxGDRzaSYmsR0Y+oYZs0AeRnZD9iEh1v17xnVEdSoLZmZbjlLXXgqhbdXGik6ZoXQg3bTfl5D1j8Tk/d/CXqf0SUKBnIafaNgUeQSMY95M3k3vjPQN7vHdXmg19GnqQmBnGq45qdKI7+0Erfhl4po1z6yVvx9JfIMIDOsKwO3U/As5zbO2BYso0pUP4+gndissfDfqlPRni3orA0tlV6NuLmXi1wkHCu8HQ8WOqEUlWDJNLNpHW5OmgjMFqlIPt7hX5jlc9eXd4oMyaqXm1Tg8Cgbh5DYaT9A7He47+QhqYlPygqK9Fm0ZnH3Yz51cm3p2tRB1JU7qH9h5UqLLKJMBuIx7e9L5ieTfzKmTw6tqpIpHpiR/8bSQlKkw2LxikFy3OXL5obY1t9sWk35BNZQqcqflI6mkPrvGQKwN+co8GjUon5/Y1HSM6ursaJtkD8dz+oXVyWAokkuD7QZ", - - -}; - - - -EVP_PKEY *RsRecogn::loadMasterKey() -{ - /* load master signing key */ - std::vector decoded = Radix64::decode(RecognKey); - - const unsigned char *keyptr2 = decoded.data(); - long keylen2 = decoded.size(); - - RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr2), keylen2); - - if (!rsakey) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadMasterKeys() failed rsakey load"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return NULL; - } - - - EVP_PKEY *signKey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(signKey, rsakey); - - return signKey; -} - - -bool RsRecogn::loadSigningKeys(std::map &signMap) -{ - - EVP_PKEY *signKey = loadMasterKey(); - RsGxsRecognSerialiser recognSerialiser; - - if (!signKey) - { - std::cerr << "RsRecogn::loadSigningKeys() missing Master Key"; - return false; - } - - - rstime_t now = time(NULL); - - for(int i = 0; i < NUM_RECOGN_SIGN_KEYS; i++) - { - std::vector signerbuf = Radix64::decode(RecognSigningKeys[i]); - - uint32_t pktsize = signerbuf.size(); - RsItem *pktitem = recognSerialiser.deserialise(signerbuf.data(), &pktsize); - RsGxsRecognSignerItem *item = dynamic_cast(pktitem); - - if (!item) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadSigningKeys() failed to deserialise SignerItem from string \"" << RecognSigningKeys[i] << "\""; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - continue; - } - -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadSigningKeys() SignerItem: "; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - - /* check dates */ - if ((item->key.startTS > (unsigned) now) || (item->key.endTS < (unsigned) now)) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadSigningKeys() failed timestamp"; - std::cerr << std::endl; - std::cerr << "RsRecogn::loadSigningKeys() key.startTS: " << item->key.startTS; - std::cerr << std::endl; - std::cerr << "RsRecogn::loadSigningKeys() now: " << now; - std::cerr << std::endl; - std::cerr << "RsRecogn::loadSigningKeys() key.endTS: " << item->key.endTS; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - delete item; - continue; - } - - /* check signature */ - RsTlvKeySignature signature = item->sign; - item->sign.TlvShallowClear(); - - unsigned int siglen = signature.signData.bin_len; - unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data; - - /* store in */ - uint32_t datalen = recognSerialiser.size(item); - - RsTemporaryMemory data(datalen) ; - - if(!data) - return false ; - - uint32_t pktlen = datalen; - int signOk = 0; - - if (recognSerialiser.serialise(item, data, &pktlen)) - { - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - EVP_VerifyInit(mdctx, EVP_sha1()); - EVP_VerifyUpdate(mdctx, data, pktlen); - signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); - - EVP_MD_CTX_destroy(mdctx); - - item->sign = signature; - signature.TlvShallowClear(); - - if (signOk) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadSigningKeys() signature ok"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - RsGxsId signerId = item->key.keyId; - signMap[signerId] = item; - } - } - - if (!signOk) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::loadSigningKeys() signature failed"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - delete item; - } - } - - /* clean up */ - EVP_PKEY_free(signKey); - return true; -} - - - -bool RsRecogn::validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item) -{ - if (item->sign.keyId != signer->key.keyId) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::validateTagSignature() keyId mismatch"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - const unsigned char *keyptr = (const unsigned char *) signer->key.keyData.bin_data; - long keylen = signer->key.keyData.bin_len; - - /* extract admin key */ - RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen); - if (!rsakey) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::validateTagSignature() failed extract signkey"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - /* check signature */ - RsTlvKeySignature signature = item->sign; - item->sign.TlvShallowClear(); - - unsigned int siglen = signature.signData.bin_len; - unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data; - - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - EVP_PKEY *signKey = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(signKey, rsakey); - - - /* store in */ - RsGxsRecognSerialiser serialiser; - - uint32_t datalen = serialiser.size(item); - - RsTemporaryMemory data(datalen) ; - - if(!data) - return false ; - - int signOk = 0; - - uint32_t pktlen = datalen; - if (serialiser.serialise(item, data, &pktlen)) - { - - EVP_VerifyInit(mdctx, EVP_sha1()); - EVP_VerifyUpdate(mdctx, data, pktlen); - signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey); -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::validateTagSignature() sign_result: " << signOk; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - } - else - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::validateTagSignature() failed to serialise"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - } - - // Clean up. - item->sign = signature; - signature.TlvShallowClear(); - - EVP_MD_CTX_destroy(mdctx); - EVP_PKEY_free(signKey); - - return (signOk == 1); -} - - -bool rsa_sanity_check(RSA *rsa) -{ - std::cerr << "rsa_sanity_check()"; - std::cerr << std::endl; - - if (!rsa) - { - std::cerr << "rsa_sanity_check() RSA == NULL"; - std::cerr << std::endl; - return false; - } - - RSA *pubkey = RSAPublicKey_dup(rsa); - - std::string signId = RsRecogn::getRsaKeyId(rsa); - std::string signId2 = RsRecogn::getRsaKeyId(pubkey); - - bool ok = true; - if (signId != signId2) - { - std::cerr << "rsa_sanity_check() ERROR SignId Failure"; - std::cerr << std::endl; - ok = false; - } - - if (1 != RSA_check_key(rsa)) - { - std::cerr << "rsa_sanity_check() ERROR RSA key is not private"; - std::cerr << std::endl; - ok = false; - } - -#if 0 - if (1 == RSA_check_key(pubkey)) - { - std::cerr << "rsa_sanity_check() ERROR RSA dup key is private"; - std::cerr << std::endl; - ok = false; - } -#endif - - RSA_free(pubkey); - - if (!ok) - { - exit(1); - } - - return true; -} - - -#warning csoler: this code should be using GxsSecurity signature code. Not some own made signature call. - -bool RsRecogn::signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item) -{ - RsGxsRecognSerialiser serialiser; - - RSA *rsa = EVP_PKEY_get1_RSA(signKey); - std::string signId = getRsaKeyId(rsa); - rsa_sanity_check(rsa); - RSA_free(rsa); - - item->sign.TlvClear(); - - /* write out the item for signing */ - uint32_t len = serialiser.size(item); - char *buf = new char[len]; - if (!serialiser.serialise(item, buf, &len)) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::signTag() Failed serialise TagItem:"; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete []buf; - return false; - } - - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - EVP_SignInit(mdctx, EVP_sha1()); - EVP_SignUpdate(mdctx, buf, len); - - unsigned int siglen = EVP_PKEY_size(signKey); - unsigned char sigbuf[siglen]; - EVP_SignFinal(mdctx, sigbuf, &siglen, signKey); - - /* save signature */ - item->sign.signData.setBinData(sigbuf, siglen); - item->sign.keyId = RsGxsId(signId); - - /* clean up */ - EVP_MD_CTX_destroy(mdctx); - delete []buf; - - return true; -} - -#warning csoler: this code should be using GxsSecurity signature code. Not some own made signature call. - -bool RsRecogn::signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item) -{ - std::cerr << "RsRecogn::signSigner()"; - std::cerr << std::endl; - - RsGxsRecognSerialiser serialiser; - - std::cerr << "RsRecogn::signSigner() Checking Key"; - std::cerr << std::endl; - - RSA *rsa = EVP_PKEY_get1_RSA(signKey); - std::string signId = getRsaKeyId(rsa); - rsa_sanity_check(rsa); - RSA_free(rsa); - - std::cerr << "RsRecogn::signSigner() Key Okay"; - std::cerr << std::endl; - - item->sign.TlvClear(); - - /* write out the item for signing */ - uint32_t len = serialiser.size(item); - char *buf = new char[len]; - if (!serialiser.serialise(item, buf, &len)) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::signSigner() Failed serialise SignerItem:"; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete []buf; - return false; - } - - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - EVP_SignInit(mdctx, EVP_sha1()); - EVP_SignUpdate(mdctx, buf, len); - - unsigned int siglen = EVP_PKEY_size(signKey); - unsigned char sigbuf[siglen]; - EVP_SignFinal(mdctx, sigbuf, &siglen, signKey); - - /* save signature */ - item->sign.signData.setBinData(sigbuf, siglen); - item->sign.keyId = RsGxsId(signId); - - /* clean up */ - EVP_MD_CTX_destroy(mdctx); - delete []buf; - - return true; -} - -#warning csoler: this code should be using GxsSecurity signature code. Not some own made signature call. - -bool RsRecogn::signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item) -{ - std::cerr << "RsRecogn::signTagRequest()"; - std::cerr << std::endl; - - RsGxsRecognSerialiser serialiser; - - RSA *rsa = EVP_PKEY_get1_RSA(signKey); - std::string signId = getRsaKeyId(rsa); - rsa_sanity_check(rsa); - RSA_free(rsa); - - item->sign.TlvClear(); - - /* write out the item for signing */ - uint32_t len = serialiser.size(item); - char *buf = new char[len]; - if (!serialiser.serialise(item, buf, &len)) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::signTagRequest() Failed serialise Tag Request:"; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete []buf; - return false; - } - - /* calc and check signature */ - EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); - - EVP_SignInit(mdctx, EVP_sha1()); - EVP_SignUpdate(mdctx, buf, len); - - unsigned int siglen = EVP_PKEY_size(signKey); - unsigned char sigbuf[siglen]; - EVP_SignFinal(mdctx, sigbuf, &siglen, signKey); - - /* save signature */ - item->sign.signData.setBinData(sigbuf, siglen); - item->sign.keyId = RsGxsId(signId); - - /* clean up */ - EVP_MD_CTX_destroy(mdctx); - delete []buf; - - return true; -} - - -bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr) -{ - RsGxsRecognSerialiser serialiser; - - /* write out the item for signing */ - uint32_t len = serialiser.size(item); - - RsTemporaryMemory buf(len) ; - - if (!serialiser.serialise(item, buf, &len)) - { - return false; - } - - radstr.clear(); - Radix64::encode(buf, len, radstr); - - return true; -} - - -std::string RsRecogn::getRsaKeyId(RSA *pubkey) -{ -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - int len = BN_num_bytes(pubkey -> n); - unsigned char tmp[len]; - BN_bn2bin(pubkey -> n, tmp); -#else - const BIGNUM *nn=NULL ; - RSA_get0_key(pubkey,&nn,NULL,NULL) ; - - int len = BN_num_bytes(nn); - unsigned char tmp[len]; - BN_bn2bin(nn, tmp); -#endif - - return RsDirUtil::sha1sum(tmp,len).toStdString(); - -#ifdef OLD_VERSION_REMOVED - // (cyril) I removed this because this is cryptographically insane, as it allows to easily forge a RSA key with the same ID. - - // copy first CERTSIGNLEN bytes... - if (len > CERTSIGNLEN) - { - len = CERTSIGNLEN; - } - - std::string id; - for(uint32_t i = 0; i < CERTSIGNLEN; i++) - { - rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i])); - } - - return id; -#endif -} - - - -RsGxsRecognTagItem *RsRecogn::extractTag(const std::string &encoded) -{ - // Decode from Radix64 encoded Packet. - uint32_t pktsize; - - std::vector buffer = Radix64::decode(encoded); - pktsize = buffer.size(); - - if( buffer.empty() ) - return NULL; - - RsGxsRecognSerialiser serialiser; - RsItem *item = serialiser.deserialise(buffer.data(), &pktsize); - - if (!item) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::extractTag() ERROR Deserialise failed"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return NULL; - } - - RsGxsRecognTagItem *tagitem = dynamic_cast(item); - - if (!tagitem) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::extractTag() ERROR Not TagItem, is: "; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete item; - } - - return tagitem; -} - - -bool RsRecogn::createTagRequest(const RsTlvPrivateRSAKey &key, const RsGxsId &id, const std::string &nickname, uint16_t tag_class, uint16_t tag_type, const std::string &comment, std::string &tag) -{ - EVP_PKEY *signKey = EVP_PKEY_new(); - RSA *rsakey = d2i_RSAPrivateKey(NULL, (const unsigned char **)&key.keyData.bin_data, key.keyData.bin_len); - - if (!rsakey) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::createTagRequest() Failed to extract key"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - if (!EVP_PKEY_assign_RSA(signKey, rsakey)) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::createTagRequest() Failed to assign key"; - std::cerr << std::endl; -#endif // DEBUG_RECOGN - return false; - } - - RsGxsRecognReqItem *item = new RsGxsRecognReqItem(); - - item->issued_at = time(NULL); - item->period = 365 * 24 * 3600; - item->tag_class = tag_class; - item->tag_type = tag_type; - - item->nickname = nickname; - item->identity = id; - item->comment = comment; - - bool signOk = RsRecogn::signTagRequest(signKey,item); - EVP_PKEY_free(signKey); - - if (!signOk) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::createTagRequest() Failed to sign Tag Request:"; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete item; - return false; - } - - /* write out the item for signing */ - RsGxsRecognSerialiser serialiser; - uint32_t len = serialiser.size(item); - RsTemporaryMemory buf(len) ; - bool serOk = serialiser.serialise(item, buf, &len); - - if (serOk) - { - Radix64::encode(buf, len, tag); - } - - if (!serOk) - { -#ifdef DEBUG_RECOGN - std::cerr << "RsRecogn::createTagRequest() Failed serialise Tag Request:"; - std::cerr << std::endl; - item->print(std::cerr); -#endif // DEBUG_RECOGN - delete item; - return false; - } - - delete item; - return serOk; -} - - diff --git a/libretroshare/src/util/rsrecogn.h b/libretroshare/src/util/rsrecogn.h deleted file mode 100644 index 7cc33ec76..000000000 --- a/libretroshare/src/util/rsrecogn.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsrandom.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2013 Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef RSUTIL_RECOGN_H -#define RSUTIL_RECOGN_H - -#include -#include -#include -#include - -#include "rsitems/rsgxsrecognitems.h" -#include "retroshare/rsgxsifacetypes.h" - -namespace RsRecogn { - -EVP_PKEY * loadMasterKey(); -bool loadSigningKeys(std::map &signMap); -bool validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item); - -bool signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item); -bool signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item); -bool signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item); - -bool itemToRadix64(RsItem *item, std::string &radstr); - -std::string getRsaKeyId(RSA *pubkey); - -RsGxsRecognTagItem *extractTag(const std::string &encoded); - -bool createTagRequest(const RsTlvPrivateRSAKey &key, - const RsGxsId &id, const std::string &nickname, - uint16_t tag_class, uint16_t tag_type, - const std::string &comment, std::string &tag); - -} - -#endif diff --git a/libretroshare/src/util/rssharedptr.h b/libretroshare/src/util/rssharedptr.h deleted file mode 100644 index ca54f85b2..000000000 --- a/libretroshare/src/util/rssharedptr.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * rssharedptr.h - * - * Created on: 16 Apr 2014 - * Author: crispy - */ - -#ifndef RSSHAREDPTR_H_ -#define RSSHAREDPTR_H_ - -#include - -/*! - * Not thread safe!! - * And also has a memory leak. Do not use (csoler, 24 Jul 2017). - */ -template -class RsSharedPtr -{ -public: - - RsSharedPtr() : mShared(NULL), mCount(NULL), mSharedPtrMutex(NULL){} - - RsSharedPtr(T* shared) - : mShared(shared), mCount(new int(0)), mSharedPtrMutex(new RsMutex("SharedMutex")) - { - mCount++; - } - - RsSharedPtr(const RsSharedPtr& rsp) - { - rsp.lock(); - mShared = rsp.mShared; - mCount = rsp.mCount; - mCount++; - mSharedPtrMutex = rsp.mSharedPtrMutex; - rsp.unlock(); - - } - - void operator=(const RsSharedPtr& rsp) - { - rsp.lock(); - mSharedPtrMutex = rsp.mSharedPtrMutex; - DecrementAndDeleteIfLast(); - mShared = rsp.mShared; - RepointAndIncrement(rsp.mCount); - - mSharedPtrMutex->unlock(); - } - - T* release() { - - lock(); - - mCount--; T* temp = mShared; mShared = NULL; - - unlock(); - - return temp; - } - T* get() { return mShared; } - - T& operator*(){ return *mShared; } - T* operator->(){ return mShared; } - - ~RsSharedPtr() - { - lock(); - DecrementAndDeleteIfLast(); - unlock(); - } -private: - - void DecrementAndDeleteIfLast() - { - mCount--; - if(mCount == 0 && mShared != NULL) - { - delete mShared; - delete mCount; - } - - mShared = NULL; - mCount = NULL; - } - - void RepointAndIncrement(int* count) - { - mCount = count; - mCount++; - - } - - void lock() const { mSharedPtrMutex->lock(); } - void unlock() const { mSharedPtrMutex->unlock(); } - -private: - - T* mShared; - int* mCount; - RsMutex* mSharedPtrMutex; - -}; - -template -RsSharedPtr rs_make_shared(T* ptr){ return RsSharedPtr(ptr); } - -#endif /* RSSHAREDPTR_H_ */ diff --git a/libretroshare/src/util/rsstd.h b/libretroshare/src/util/rsstd.h deleted file mode 100644 index 2cf3ae31d..000000000 --- a/libretroshare/src/util/rsstd.h +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsstd.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2015 Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSSTD_H_ -#define RSSTD_H_ - -namespace rsstd { - -template -void delete_all(_IIter iter_begin, _IIter iter_end) -{ - for (_IIter it = iter_begin; it != iter_end; ++it) { - delete(*it); - } -} - -} - -#endif // RSSTD_H_ diff --git a/libretroshare/src/util/rsstring.cc b/libretroshare/src/util/rsstring.cc deleted file mode 100644 index 6dcb8bd21..000000000 --- a/libretroshare/src/util/rsstring.cc +++ /dev/null @@ -1,334 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsstd.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2010, Thomas Kister * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "rsstring.h" - -#ifdef WINDOWS_SYS -#include -#include -#else -#include -#include -#include -#endif -#include -#include - -namespace librs { namespace util { - -bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest) -{ - if (source.empty()) { - dest.clear(); - return true; - } - -#ifdef WINDOWS_SYS - int nbChars = MultiByteToWideChar(CP_UTF8, 0, source.c_str(), -1, 0, 0); - if(nbChars == 0) { - return false; - } - - wchar_t* utf16Name = new wchar_t[nbChars]; - if( MultiByteToWideChar(CP_UTF8, 0, source.c_str(), -1, utf16Name, nbChars) == 0) { - delete[] utf16Name; - return false; - } - - dest = utf16Name; - delete[] utf16Name; -#else - std::vector res; - std::string::size_type len = source.length(); - - unsigned int i = 0; - unsigned long temp; - - while (i < len) { - char src = source[i]; - if ((src & 0x80) == 0) { // ASCII : 0000 0000-0000 007F 0xxxxxxx - temp = src; - ++i; - } else if ((src & 0xE0) == 0xC0) { // 0000 0080-0000 07FF 110xxxxx 10xxxxxx - temp = (src & 0x1F); - temp <<= 6; - temp += (source[i + 1] & 0x3F); - i += 2; - } else if ((src & 0xF0) == 0xE0) { // 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - temp = (src & 0x0F); - temp <<= 6; - temp += (source[i + 1] & 0x3F); - temp <<= 6; - temp += (source[i + 2] & 0x3F); - i += 3; - } else if ((src & 0xF8) == 0xF0) { // 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - temp = (src & 0x07); - temp <<= 6; - temp += (source[i + 1] & 0x3F); - temp <<= 6; - temp += (source[i + 2] & 0x3F); - temp <<= 6; - temp += (source[i + 3] & 0x3F); - i += 4; - } else if ((src & 0xFC) == 0xF8) { // 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - temp = (src & 0x03); - temp <<= 6; - temp += (source[i + 1] & 0x3F); - temp <<= 6; - temp += (source[i + 2] & 0x3F); - temp <<= 6; - temp += (source[i + 3] & 0x3F); - temp <<= 6; - temp += (source[i + 4] & 0x3F); - i += 5; - } else if ((src & 0xFE) == 0xFC) { // 0400 0000-7FFF FFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - temp = (src & 0x01); - temp <<= 6; - temp += (source[i + 1] & 0x3F); - temp <<= 6; - temp += (source[i + 2] & 0x3F); - temp <<= 6; - temp += (source[i + 3] & 0x3F); - temp <<= 6; - temp += (source[i + 4] & 0x3F); - temp <<= 6; - temp += (source[i + 5] & 0x3F); - i += 6; - } else { - temp = '?'; - } - // Need to transform to UTF-16 > handle surrogates - if (temp > 0xFFFF) { - // First high surrogate - res.push_back(0xD800 + wchar_t(temp >> 10)); - // Now low surrogate - res.push_back(0xDC00 + wchar_t(temp & 0x3FF)); - } else { - res.push_back(wchar_t(temp)); - } - } - // Check whether first wchar_t is the BOM 0xFEFF - if (res[0] == 0xFEFF) { - dest.append(&res[1], res.size() - 1); - } else { - dest.append(&res[0], res.size()); - } -#endif - - return true; -} - -bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest) -{ -#ifdef WINDOWS_SYS - int nbChars = WideCharToMultiByte(CP_UTF8, 0, source.c_str(), -1, 0, 0, 0, 0); - if(nbChars == 0) { - return false; - } - - char* utf8Name = new char[nbChars]; - if( WideCharToMultiByte(CP_UTF8, 0, source.c_str(), -1, utf8Name, nbChars, 0, 0) == 0) { - delete[] utf8Name; - return false; - } - - dest = utf8Name; - delete[] utf8Name; -#else - std::vector res; - - std::wstring::size_type len = source.length(); - unsigned int i = 0; - unsigned long temp; - - while (i < len) { - if ((source[i] & 0xD800) == 0xD800) { // surrogate - temp = (source[i] - 0xD800); - temp <<= 10; - temp += (source[i + 1] - 0xDC00); - i += 2; - } else { - temp = source[i]; - ++i; - } - if (temp < 0x00000080) { // ASCII : 0000 0000-0000 007F 0xxxxxxx - res.push_back(char(temp)); - } else if (temp < 0x00000800) { // 0000 0080-0000 07FF 110xxxxx 10xxxxxx - res.push_back(char(0xC0 | (temp >> 6))); - res.push_back(char(0x80 | (temp & 0x3F))); - } else if (temp < 0x00010000) { // 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - res.push_back(char(0xE0 | (temp >> 12))); - res.push_back(char(0x80 | ((temp >> 6) & 0x3F))); - res.push_back(char(0x80 | (temp & 0x3F))); - } else if (temp < 0x00200000) { // 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - res.push_back(char(0xF0 | (temp >> 18))); - res.push_back(char(0x80 | ((temp >> 12) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 6) & 0x3F))); - res.push_back(char(0x80 | (temp & 0x3F))); - } else if (temp < 0x04000000) { // 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - res.push_back(char(0xF8 | (temp >> 24))); - res.push_back(char(0x80 | ((temp >> 18) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 12) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 6) & 0x3F))); - res.push_back(char(0x80 | (temp & 0x3F))); - } else if (temp < 0x80000000) { // 0400 0000-7FFF FFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - res.push_back(char(0xFC | (temp >> 30))); - res.push_back(char(0x80 | ((temp >> 24) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 18) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 12) & 0x3F))); - res.push_back(char(0x80 | ((temp >> 6) & 0x3F))); - res.push_back(char(0x80 | (temp & 0x3F))); - } - } - - dest.append(&res[0], res.size()); -#endif - - return true; -} - -#if 0 -bool is_alphanumeric(char c) -{ - return (c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z'); -} - -bool is_alphanumeric(const std::string& s) -{ - for( uint32_t i=0; i < s.size(); ++i) - if(!is_alphanumeric(s[i])) return false; - return true; -} -#endif - -} } // librs::util - -#ifdef WINDOWS_SYS -// asprintf() and vasprintf() are missing in Win32 -static int vasprintf(char **sptr, const char *fmt, va_list argv) -{ - int wanted = __mingw_vsnprintf(*sptr = NULL, 0, fmt, argv); - if ((wanted > 0) && ((*sptr = (char*) malloc(wanted + 1)) != NULL)) { - return __mingw_vsprintf(*sptr, fmt, argv); - } - - return wanted; -} - -//static int asprintf(char **sptr, const char *fmt, ...) -//{ -// int retval; -// va_list argv; -// va_start( argv, fmt ); -// retval = vasprintf(sptr, fmt, argv); -// va_end(argv); -// return retval; -//} -#endif - -int rs_sprintf_args(std::string &str, const char *fmt, va_list ap) -{ - char *buffer = NULL; - - int retval = vasprintf(&buffer, fmt, ap); - - if (retval >= 0) { - if (buffer) { - str = buffer; - free(buffer); - } else { - str.clear(); - } - } else { - str.clear(); - } - - return retval; -} - -int rs_sprintf(std::string &str, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - int retval = rs_sprintf_args(str, fmt, ap); - va_end(ap); - - return retval; -} - -int rs_sprintf_append_args(std::string &str, const char *fmt, va_list ap) -{ - char *buffer = NULL; - - int retval = vasprintf(&buffer, fmt, ap); - - if (retval >= 0) { - if (buffer) { - str.append(buffer); - free(buffer); - } - } - - return retval; -} - -int rs_sprintf_append(std::string &str, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - int retval = rs_sprintf_append_args(str, fmt, ap); - va_end(ap); - - return retval; -} - -void stringToUpperCase(const std::string& s, std::string &upper) -{ - upper = s ; - - for(uint32_t i=0;i 96 && upper[i] < 123) - upper[i] -= 97-65 ; -} - -void stringToLowerCase(const std::string& s, std::string &lower) -{ - lower = s ; - - for(uint32_t i=0;i 64 && lower[i] < 91) - lower[i] += 97-65 ; -} - - - -bool isHexaString(const std::string& s) -{ - for(uint32_t i=0;i= 'A' && s[i] <= 'F') || (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'f'))) - return false ; - - return true ; -} - - diff --git a/libretroshare/src/util/rsstring.h b/libretroshare/src/util/rsstring.h deleted file mode 100644 index b3fd2553c..000000000 --- a/libretroshare/src/util/rsstring.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsstd.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2010, Thomas Kister * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RSSTRING_H_ -#define RSSTRING_H_ - -#include -#include - -namespace librs { - namespace util { - - bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest); - bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest); -#if 0 - bool is_alphanumeric(char c) ; - bool is_alphanumeric(const std::string& s); -#endif -} } // librs::util - -#ifdef WIN32 -#define INT64FMT "%I64d" -#define UINT64FMT "%I64u" -#else -#define INT64FMT "%lld" -#define UINT64FMT "%llu" -#endif - -int rs_sprintf_args(std::string &str, const char *fmt, va_list ap); -int rs_sprintf(std::string &str, const char *fmt, ...); -int rs_sprintf_append_args(std::string &str, const char *fmt, va_list ap); -int rs_sprintf_append(std::string &str, const char *fmt, ...); - -void stringToUpperCase(const std::string& s, std::string &upper); -void stringToLowerCase(const std::string& s, std::string &lower); - -bool isHexaString(const std::string& s); - -#endif // RSSTRING_H_ diff --git a/libretroshare/src/util/rsthreads.cc b/libretroshare/src/util/rsthreads.cc deleted file mode 100644 index e931c8f1f..000000000 --- a/libretroshare/src/util/rsthreads.cc +++ /dev/null @@ -1,330 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsthreads.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2007 Robert Fernie * - * Copyright (C) 2016-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include "rsthreads.h" - -#include "util/rsdebug.h" -#include "util/rserrno.h" - -#include -#include -#include -#include - -#ifdef RS_MUTEX_DEBUG -#include -#include -#endif - -#ifdef __APPLE__ -int __attribute__((weak)) pthread_setname_np(const char *__buf) ; -int RS_pthread_setname_np(pthread_t /*__target_thread*/, const char *__buf) { - return pthread_setname_np(__buf); -} -#else -int __attribute__((weak)) pthread_setname_np(pthread_t __target_thread, const char *__buf) ; -int RS_pthread_setname_np(pthread_t __target_thread, const char *__buf) { - return pthread_setname_np(__target_thread, __buf); -} -#endif - - -/******* - * #define DEBUG_THREADS 1 - * #define RSMUTEX_ABORT 1 // Catch wrong pthreads mode. - *******/ -#define THREAD_DEBUG RsDbg() << "[this=" << static_cast(this) \ - << ", caller thread ID: " << std::hex << pthread_self() << ", thread ID: " \ - << mTid << std::dec << "] " - -#ifdef RSMUTEX_ABORT - #include -#endif - -#ifdef DEBUG_THREADS - #include -#endif - -/*static*/ void* RsThread::rsthread_init(void* p) -{ - RsThread* thread = reinterpret_cast(p); - if(!thread) return nullptr; - - /* Using pthread_detach(...) the thread resources will be automatically - * freed when this function return, so there is no need for pthread_join() - * later. */ - pthread_detach(pthread_self()); - -#ifdef DEBUG_THREADS - std::cerr << "[Thread ID:" << std::hex << pthread_self() << std::dec - << "] thread is started. Calling wrapRun()..." << std::endl; -#endif - - thread->wrapRun(); - return nullptr; -} - -void RsThread::resetTid() -{ -#ifdef WINDOWS_SYS - memset (&mTid, 0, sizeof(mTid)); -#else - mTid = 0; -#endif -} - -RsThread::RsThread() : mHasStopped(true), mShouldStop(false), mLastTid() -#ifdef RS_THREAD_FORCE_STOP - , mStopTimeout(0) -#endif -{ resetTid(); } - -bool RsThread::isRunning() { return !mHasStopped; } - -bool RsThread::shouldStop() { return mShouldStop; } - -void RsThread::askForStop() -{ - /* Call onStopRequested() only once even if askForStop() is called multiple - * times */ - if(!mShouldStop.exchange(true)) onStopRequested(); -} - -void RsThread::wrapRun() -{ - run(); - resetTid(); - mHasStopped = true; -} - -void RsThread::fullstop() -{ -#ifdef RS_THREAD_FORCE_STOP - const rstime_t stopRequTS = time(nullptr); -#endif - - askForStop(); - - const pthread_t callerTid = pthread_self(); - if(pthread_equal(mTid, callerTid)) - { - RsErr() << __PRETTY_FUNCTION__ << " called by same thread. This should " - << "never happen! this: " << static_cast(this) - << std::hex << ", callerTid: " << callerTid - << ", mTid: " << mTid << std::dec - << ", mFullName: " << mFullName << std::endl; - print_stacktrace(); - return; - } - - // Wait for the thread being stopped - auto i = 1; - while(!mHasStopped) - { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - ++i; - if(!(i%5)) - RsDbg() << __PRETTY_FUNCTION__ << " " << i*0.2 << " seconds passed" - << " waiting for thread: " << std::hex << mLastTid - << std::dec << " " << mFullName << " to stop" << std::endl; - -#ifdef RS_THREAD_FORCE_STOP - if(mStopTimeout && time(nullptr) > stopRequTS + mStopTimeout) - { - RsErr() << __PRETTY_FUNCTION__ << " thread mLastTid: " << std::hex - << mLastTid << " mTid: " << mTid << std::dec << " " - << mFullName - << " ignored our nice stop request for more then " - << mStopTimeout - << " seconds, will be forcefully stopped. " - << "Please submit a report to RetroShare developers" - << std::endl; - - const auto terr = pthread_cancel(mTid); - if(terr == 0) mHasStopped = true; - else - { - RsErr() << __PRETTY_FUNCTION__ << " pthread_cancel(" - << std::hex << mTid << std::dec <<") returned " - << terr << " " << rsErrnoName(terr) << std::endl; - print_stacktrace(); - } - - break; - } -#endif // def RS_THREAD_FORCE_STOP - } -} - -bool RsThread::start(const std::string& threadName) -{ - // Atomically check if the thread was already started and set it as running - if(mHasStopped.exchange(false)) - { - mShouldStop = false; - int pError = pthread_create( - &mTid, nullptr, &rsthread_init, static_cast(this) ); - if(pError) - { - RsErr() << __PRETTY_FUNCTION__ << " pthread_create could not create" - << " new thread: " << threadName << " pError: " << pError - << std::endl; - mHasStopped = true; - print_stacktrace(); - return false; - } - if(!mTid) - { - RsErr() << __PRETTY_FUNCTION__ << " pthread_create could not create" - << " new thread: " << threadName << " mTid: " << mTid - << std::endl; - mHasStopped = true; - print_stacktrace(); - return false; - } - - /* Store an extra copy of thread id for debugging */ - mLastTid = mTid; - - /* Store thread full name as PThread is not able to keep it entirely */ - mFullName = threadName; - - /* Set PThread thread name which is restricted to 16 characters - * including the terminating null byte */ - if(pthread_setname_np && !threadName.empty()) - RS_pthread_setname_np(mTid, threadName.substr(0, 15).c_str()); - - return true; - } - - RsErr() << __PRETTY_FUNCTION__ << " attempt to start already running thread" - << std::endl; - print_stacktrace(); - return false; -} - -RsQueueThread::RsQueueThread(uint32_t min, uint32_t max, double relaxFactor ) - :mMinSleep(min), mMaxSleep(max), mRelaxFactor(relaxFactor) -{ - mLastSleep = (uint32_t)mMinSleep ; - mLastWork = time(NULL) ; -} - -void RsQueueThread::threadTick() -{ - bool doneWork = false; - while(workQueued() && doWork()) - { - doneWork = true; - } - time_t now = time(NULL); - if (doneWork) - { - mLastWork = now; - mLastSleep = (uint32_t) (mMinSleep + (mLastSleep - mMinSleep) / 2.0); -#ifdef DEBUG_TICKING - THREAD_DEBUG << "RsQueueThread::data_tick() done work: sleeping for: " << mLastSleep << " ms" << std::endl; -#endif - - } - else - { - uint32_t deltaT = now - mLastWork; - double frac = deltaT / mRelaxFactor; - - mLastSleep += (uint32_t) - ((mMaxSleep-mMinSleep) * (frac + 0.05)); - if (mLastSleep > mMaxSleep) - { - mLastSleep = mMaxSleep; - } -#ifdef DEBUG_TICKING - THREAD_DEBUG << "RsQueueThread::data_tick() no work: sleeping for: " << mLastSleep << " ms" << std::endl; -#endif - } - - std::this_thread::sleep_for(std::chrono::milliseconds(mLastSleep)); -} - -void RsMutex::unlock() -{ - _thread_id = 0; - pthread_mutex_unlock(&realMutex); -} - -void RsMutex::lock() -{ - int err = pthread_mutex_lock(&realMutex); - if( err != 0) - { - RsErr() << __PRETTY_FUNCTION__ << "pthread_mutex_lock returned: " - << rsErrnoName(err) -#ifdef RS_MUTEX_DEBUG - << " name: " << name() -#endif - << std::endl; - - print_stacktrace(); - -#ifdef RSMUTEX_ABORT - abort(); -#endif - } - - _thread_id = pthread_self(); -} - -#ifdef RS_MUTEX_DEBUG -double RsStackMutex::getCurrentTS() -{ - -#ifndef WINDOWS_SYS - struct timeval cts_tmp; - gettimeofday(&cts_tmp, NULL); - double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; -#else - struct _timeb timebuf; - _ftime( &timebuf); - double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; -#endif - return cts; -} -#endif - - -RsThread::~RsThread() -{ - if(!mHasStopped) - { - RsErr() << __PRETTY_FUNCTION__ << " deleting thread: " << mLastTid - << " " << mFullName << " that is still " - << "running! Something seems very wrong here and RetroShare is " - << "likely to crash because of this." << std::endl; - print_stacktrace(); - - fullstop(); - } -} - -RsQueueThread::~RsQueueThread() = default; diff --git a/libretroshare/src/util/rsthreads.h b/libretroshare/src/util/rsthreads.h deleted file mode 100644 index 82221ebbb..000000000 --- a/libretroshare/src/util/rsthreads.h +++ /dev/null @@ -1,336 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rsthreads.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (C) 2004-2006 Robert Fernie * - * Copyright (C) 2016-2020 Gioacchino Mazzurco * - * Copyright (C) 2019-2020 Asociación Civil Altermundi * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util/rsmemory.h" -#include "util/rsdeprecate.h" - -#ifdef RS_THREAD_FORCE_STOP -# include "util/rstime.h" -#endif - -/** - * @brief Provide mutexes that keep track of the owner. Based on pthread mutex. - */ -class RsMutex -{ -public: - - RsMutex(const std::string& name) : _thread_id(0) -#ifdef RS_MUTEX_DEBUG - , _name(name) -#endif - { - pthread_mutex_init(&realMutex, nullptr); - -#ifndef RS_MUTEX_DEBUG - (void) name; // remove unused parameter warnings -#endif - } - - ~RsMutex() { pthread_mutex_destroy(&realMutex); } - - inline const pthread_t& owner() const { return _thread_id; } - - void lock(); - void unlock(); - bool trylock() { return (0 == pthread_mutex_trylock(&realMutex)); } - -#ifdef RS_MUTEX_DEBUG - const std::string& name() const { return _name ; } -#endif - -private: - pthread_mutex_t realMutex; - pthread_t _thread_id; - -#ifdef RS_MUTEX_DEBUG - std::string _name; -#endif -}; - -/** - * @def RS_STACK_MUTEX(m) - * This macro allows you to trace which mutex in the code is locked and for how - * much time. You can use this as follows: - * @code - * { - * RS_STACK_MUTEX(myMutex); - * do_something(); - * } - * @endcode - */ -#define RS_STACK_MUTEX(m) \ - RsStackMutex __local_retroshare_stack_mutex_##m( \ - m, __PRETTY_FUNCTION__, __FILE__, __LINE__ ) - -/** - * Provide mutexes that automatically lock/unlock on creation/destruction and - * have powerfull debugging facilities (if RS_MUTEX_DEBUG is defined at - * compiletime). - * In most of the cases you should not use this directly instead - * @see RS_STACK_MUTEX(m) - */ -class RsStackMutex -{ -public: - - RsStackMutex(RsMutex &mtx) : mMtx(mtx) - { - mMtx.lock(); -#ifdef RS_MUTEX_DEBUG - double ts = getCurrentTS(); - _time_stamp = ts; - _lineno = 0; - _info = "[no info]"; -#endif - } - - RsStackMutex(RsMutex &mtx, const char *function_name, const char *file_name, - int lineno) : mMtx(mtx) -#ifdef RS_MUTEX_DEBUG - , _info(std::string(function_name)+" in file "+file_name), _lineno(lineno) -#endif - { -#ifdef RS_MUTEX_DEBUG - double ts = getCurrentTS(); - _time_stamp = ts; - pthread_t owner = mMtx.owner(); -#else - // remove unused parameter warnings - (void) function_name; (void) file_name; (void) lineno; -#endif - - mMtx.lock(); - -#ifdef RS_MUTEX_DEBUG - ts = getCurrentTS(); - - if(ts - _time_stamp > 1.0) - std::cerr << "Mutex " << (void*)&mMtx << " \"" << mtx.name() << "\"" - << " waited for " << ts - _time_stamp - << " seconds in thread " << pthread_self() - << " for locked thread " << owner << ". in " << _info - << ":" << _lineno << std::endl; - _time_stamp = ts ; // This is to re-init the locking time without accounting for how much we waited. -#endif - } - - ~RsStackMutex() - { - mMtx.unlock(); - -#ifdef RS_MUTEX_DEBUG - double ts = getCurrentTS(); - - if(ts - _time_stamp > 1.0) - std::cerr << "Mutex " << (void*)&mMtx << " \"" << mMtx.name() - << "\"" << " locked for " << ts - _time_stamp - << " seconds in thread " << pthread_self() - << ". in " << _info << ":" << _lineno << std::endl; -#endif - } - -private: - RsMutex &mMtx; - -#ifdef RS_MUTEX_DEBUG - static double getCurrentTS(); - double _time_stamp; - std::string _info; - int _lineno; -#endif -}; - - - -/// @brief Offer basic threading functionalities. -class RsThread -{ -public: - RsThread(); - virtual ~RsThread(); - - /** - * @brief start the thread and call run() on it. - * @param threadName string containing the name of the thread used for - * debugging purposes, @note inside PThread it is - * truncated to 16 characters including \0 at the end of - * the string. - * @return false on error, true otherwise - */ - bool start(const std::string& threadName = ""); - - /** - * @brief Check if thread is running. - * @return true if the thread is still running, false otherwise. - */ - bool isRunning(); - - /** - * @brief Check if the thread should stop. - * Expecially useful for subclasses which implement a @see run() method - * which may take lot of time before returning when not asked, to check if - * stop has been requested and therefore interrupting the execution ASAP - * returning in a coherent state. - * @return true if the thread received a stopping order. - */ - bool shouldStop(); - - /** - * @brief Asyncronously ask the thread to stop. - * The real stop will happen when the @see run() method finish. - */ - void askForStop(); - - /** - * Call @see askForStop() then wait it has really stopped before returning. - * It must not be called in the same thread, as it would not wait for the - * effective stop to occur as it would cause a deadlock. - */ - void fullstop(); - - /** - * Execute given function on a detached thread without blocking the caller - * execution. - * This can be generalized with variadic template, ATM it is enough to wrap - * any kind of function call or job into a lambda which get no paramethers - * and return nothing but can capture - * This can be easly optimized later by using a thread pool - */ - static void async(const std::function& fn) - { std::thread(fn).detach(); } - - /** @return RsThread full name */ - const std::string& threadName() { return mFullName; } - -protected: - /** - * This method must be implemented by sublasses, will be called once the - * thread is started. Should return on request, use @see shouldStop() to - * check if stop has been requested. - */ - virtual void run() = 0; - - /** - * This method is meant to be overridden by subclasses with long running - * @see run() method and is executed asyncronously when @see askForStop() - * is called, any task necessary to stop the thread (aka inducing @see run() - * to return in a coherent state) should be done in the overridden version - * of this method, @see JsonApiServer for an usage example. */ - virtual void onStopRequested() {} - -#ifdef RS_THREAD_FORCE_STOP - /** Set last resort timeout to forcefully kill thread if it didn't stop - * nicely, one should never use this, still we needed to introduce this - * to investigate some bugs in external libraries */ - void setStopTimeout(rstime_t timeout) { mStopTimeout = timeout; } -#endif - -private: - /** Call @see run() setting the appropriate flags around it*/ - void wrapRun(); - - /// True if thread is stopped, false otherwise - std::atomic mHasStopped; - - /// True if stop has been requested - std::atomic mShouldStop; - - /// Passed as argument for pthread_create(), call start() - static void *rsthread_init(void*); - - /// Store the id of the corresponding pthread - pthread_t mTid; - void resetTid(); - - /** Store thread full name for debugging because PThread is limited to 15 - * char thread names */ - std::string mFullName; - - /** Store a copy of thread id which is never reset to 0 after initialization - * due to RsThread functioning. After RsThread initialization this member is - * only re-written with a new tread id in start(...). - * This is useful for debugging because mTid is reset at the end of wrapRun - * and that might happens concurrently (or just before) a debug message - * being printed, thus causing the debug message to print a mangled value.*/ - pthread_t mLastTid; - -#ifdef RS_THREAD_FORCE_STOP - /// @see setStopTimeout - rstime_t mStopTimeout; -#endif -}; - -/** - * Provide a detached execution loop that continuously call data_tick() once the - * thread is started - */ -class RsTickingThread: public RsThread -{ -public: - - /** - * Subclasses must implement this method, it will be called in a loop once - * the thread is started, so repetitive work (like checking if data is - * available on a socket) should be done here, at the end of this method - * sleep_for(...) or similar function should be called or the CPU will - * be used as much as possible also if there is nothing to do. - */ - virtual void threadTick() = 0; - -private: - /// Implement the run loop and continuously call threadTick() in it - void run() override { while(!shouldStop()) threadTick(); } -}; - -// TODO: Used just one time, is this really an useful abstraction? -class RsQueueThread: public RsTickingThread -{ -public: - RsQueueThread(uint32_t min, uint32_t max, double relaxFactor); - ~RsQueueThread() override; - -protected: - virtual bool workQueued() = 0; - virtual bool doWork() = 0; - - void threadTick() override; /// @see RsTickingThread - -private: - uint32_t mMinSleep; /* ms */ - uint32_t mMaxSleep; /* ms */ - uint32_t mLastSleep; /* ms */ - time_t mLastWork; /* secs */ - float mRelaxFactor; -}; diff --git a/libretroshare/src/util/rstickevent.cc b/libretroshare/src/util/rstickevent.cc deleted file mode 100644 index d596d417c..000000000 --- a/libretroshare/src/util/rstickevent.cc +++ /dev/null @@ -1,199 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rstickevent.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include "util/rstickevent.h" - -#include -#include - -//#define DEBUG_EVENTS 1 - -void RsTickEvent::tick_events() -{ -#ifdef DEBUG_EVENTS - std::cerr << "RsTickEvent::tick_events() Event List:"; - std::cerr << std::endl; -#endif - - rstime_t now = time(NULL); - { - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - -#ifdef DEBUG_EVENTS - if (!mEvents.empty()) - { - std::multimap::iterator it; - - for(it = mEvents.begin(); it != mEvents.end(); ++it) - { - std::cerr << "\tEvent type: "; - std::cerr << it->second << " in " << it->first - now << " secs"; - std::cerr << std::endl; - } - } -#endif - - if (mEvents.empty()) - { - return; - } - - /* all events in the future */ - if (mEvents.begin()->first > now) - { - return; - } - } - - std::list toProcess; - std::list::iterator it; - - { - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - while((!mEvents.empty()) && (mEvents.begin()->first <= now)) - { - std::multimap::iterator it = mEvents.begin(); - uint32_t event_type = it->second.mEventType; - toProcess.push_back(it->second); - mEvents.erase(it); - - count_adjust_locked(event_type, -1); - note_event_locked(event_type); - } - } - - for(it = toProcess.begin(); it != toProcess.end(); ++it) - { -#ifdef DEBUG_EVENTS - std::cerr << "RsTickEvent::tick_events() calling handle_event("; - std::cerr << it->mEventType << ", " << it->mEventLabel << ")"; - std::cerr << std::endl; -#endif // DEBUG_EVENTS - handle_event(it->mEventType, it->mEventLabel); - } -} - -void RsTickEvent::schedule_now(uint32_t event_type) -{ - std::string elabel; - RsTickEvent::schedule_in(event_type, 0, elabel); -} - - -void RsTickEvent::schedule_now(uint32_t event_type, const std::string &elabel) -{ - RsTickEvent::schedule_in(event_type, 0, elabel); -} - -void RsTickEvent::schedule_event(uint32_t event_type, rstime_t when, const std::string &elabel) -{ - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - mEvents.insert(std::make_pair(when, EventData(event_type, elabel))); - - count_adjust_locked(event_type, 1); -} - -void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs) -{ - std::string elabel; - RsTickEvent::schedule_in(event_type, in_secs, elabel); -} - - -void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs, const std::string &elabel) -{ -#ifdef DEBUG_EVENTS - std::cerr << "RsTickEvent::schedule_in(" << event_type << ", " << elabel << ") in " << in_secs << " secs"; - std::cerr << std::endl; -#endif // DEBUG_EVENTS - - rstime_t event_time = time(NULL) + in_secs; - RsTickEvent::schedule_event(event_type, event_time, elabel); -} - - -void RsTickEvent::handle_event(uint32_t event_type, const std::string &elabel) -{ - std::cerr << "RsTickEvent::handle_event(" << event_type << ", " << elabel; - std::cerr << ") ERROR Not Handled"; - std::cerr << std::endl; -} - - -int32_t RsTickEvent::event_count(uint32_t event_type) -{ - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it; - - it = mEventCount.find(event_type); - if (it == mEventCount.end()) - { - return 0; - } - - return it->second; -} - - -bool RsTickEvent::prev_event_ago(uint32_t event_type, int32_t &age) -{ - RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/ - std::map::iterator it; - - it = mPreviousEvent.find(event_type); - if (it == mPreviousEvent.end()) - { - return false; - } - - age = time(NULL) - it->second; - return true; -} - - -void RsTickEvent::count_adjust_locked(uint32_t event_type, int32_t change) -{ - std::map::iterator it; - - it = mEventCount.find(event_type); - if (it == mEventCount.end()) - { - mEventCount[event_type] = 0; - it = mEventCount.find(event_type); - } - - it->second += change; - if (it->second < 0) - { - std::cerr << "RsTickEvent::count_adjust() ERROR: COUNT < 0"; - std::cerr << std::endl; - - it->second = 0; - } -} - - -void RsTickEvent::note_event_locked(uint32_t event_type) -{ - mPreviousEvent[event_type] = time(NULL); -} - - diff --git a/libretroshare/src/util/rstickevent.h b/libretroshare/src/util/rstickevent.h deleted file mode 100644 index 7f2c9188c..000000000 --- a/libretroshare/src/util/rstickevent.h +++ /dev/null @@ -1,81 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rstickevent.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2012-2012 by Robert Fernie * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#ifndef RS_UTIL_TICK_EVENT -#define RS_UTIL_TICK_EVENT - - -/* - * - * A simple event queue... to avoid having to continually write separate one. - */ - -#include -#include "util/rstime.h" - -#include "util/rsthreads.h" - -class RsTickEvent -{ - public: - RsTickEvent():mEventMtx("TickEventMtx") { return; } - -void tick_events(); - -void schedule_now(uint32_t event_type); -void schedule_now(uint32_t event_type, const std::string &elabel); - -void schedule_event(uint32_t event_type, rstime_t when, const std::string &elabel); - -void schedule_in(uint32_t event_type, uint32_t in_secs); -void schedule_in(uint32_t event_type, uint32_t in_secs, const std::string &elabel); - -int32_t event_count(uint32_t event_type); -bool prev_event_ago(uint32_t event_type, int32_t &age); - - protected: - - // Overloaded to handle the events. -virtual void handle_event(uint32_t event_type, const std::string &event_label); - - private: - - class EventData - { - public: - EventData() :mEventType(0) { return; } - EventData(uint32_t etype) :mEventType(etype) { return; } - EventData(uint32_t etype, std::string elabel) :mEventLabel(elabel), mEventType(etype) { return; } - - std::string mEventLabel; - uint32_t mEventType; - }; - -void count_adjust_locked(uint32_t event_type, int32_t change); -void note_event_locked(uint32_t event_type); - - RsMutex mEventMtx; - std::map mEventCount; - std::map mPreviousEvent; - std::multimap mEvents; -}; - -#endif // RS_UTIL_TICK_EVENT diff --git a/libretroshare/src/util/rstime.cc b/libretroshare/src/util/rstime.cc deleted file mode 100644 index d2180775e..000000000 --- a/libretroshare/src/util/rstime.cc +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rstime.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include -#include -#include - -#include "rstime.h" - -namespace rstime { - -int rs_usleep(uint32_t micro_seconds) -{ - while(micro_seconds >= 1000000) - { - // usleep cannot be called with 1000000 or more. - - usleep(500000) ; - usleep(500000) ; - - micro_seconds -= 1000000 ; - } - usleep(micro_seconds) ; - - return 0 ; -} - -RsScopeTimer::RsScopeTimer(const std::string& name) -{ - _name = name ; - start(); -} - -RsScopeTimer::~RsScopeTimer() -{ - if (!_name.empty()) - { - std::cerr << "Time for \"" << _name << "\": " << duration() << std::endl; - } -} - -double RsScopeTimer::currentTime() -{ - timeval tv ; - gettimeofday(&tv,NULL) ; - return (tv.tv_sec % 10000) + tv.tv_usec/1000000.0f ; // the %1000 is here to allow double precision to cover the decimals. -} - -void RsScopeTimer::start() -{ - _seconds = currentTime(); -} - -double RsScopeTimer::duration() -{ - return currentTime() - _seconds; -} - -} diff --git a/libretroshare/src/util/rstime.h b/libretroshare/src/util/rstime.h deleted file mode 100644 index 6cc01e486..000000000 --- a/libretroshare/src/util/rstime.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rstime.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright 2013-2013 by Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#ifdef WINDOWS_SYS -#include -#else -#include -#endif -#include // Added for comfort of users of this util header -#include "util/rsdeprecate.h" - -/** - * Safer alternative to time_t. - * As time_t have not same lenght accross platforms, even though representation - * is not guaranted to be the same but we found it being number of seconds since - * the epoch for time points in all platforms we could test, or plain seconds - * for intervals. - * Still in some platforms it's 32bit long and in other 64bit long. - * To avoid uncompatibility due to different serialzation format use this - * reasonably safe alternative instead. - */ -typedef int64_t rstime_t; - -// Do we really need this? Our names have rs prefix to avoid pollution already! -namespace rstime { - -/** - * @deprecated { std::this_thread::sleep_for or - * std::this_thread::sleep_until instead } - * @brief This is a cross-system definition of usleep, which accepts any - * 32 bits number of micro-seconds. - */ -RS_DEPRECATED_FOR("std::this_thread::sleep_for") -int rs_usleep(uint32_t micro_seconds); - - /* Use this class to measure and display time duration of a given environment: - - { - RsScopeTimer timer("callToMeasure()") ; - - callToMeasure() ; - } - - */ - - class RsScopeTimer - { - public: - RsScopeTimer(const std::string& name); - ~RsScopeTimer(); - - void start(); - double duration(); - - static double currentTime(); - - private: - std::string _name ; - double _seconds ; - }; - -} diff --git a/libretroshare/src/util/rsurl.cc b/libretroshare/src/util/rsurl.cc deleted file mode 100644 index 5da7bbaf4..000000000 --- a/libretroshare/src/util/rsurl.cc +++ /dev/null @@ -1,304 +0,0 @@ -/* - * RetroShare - * Copyright (C) 2018-2019 Gioacchino Mazzurco - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include -#include - -#include "rsurl.h" -#include "serialiser/rstypeserializer.h" -#include "util/rsnet.h" - -using namespace std; - -RsUrl::RsUrl() : mPort(0), mHasPort(false) {} - -RsUrl::RsUrl(const std::string& urlStr) : mPort(0), mHasPort(false) -{ fromString(urlStr); } - -RsUrl::RsUrl(const sockaddr_storage& addr): mPort(0), mHasPort(false) -{ - switch(addr.ss_family) - { - case AF_INET: setScheme("ipv4"); break; - case AF_INET6: setScheme("ipv6"); break; - default: - { - std::string addrDump; - sockaddr_storage_dump(addr, &addrDump); - RsErr() << __PRETTY_FUNCTION__ << " got invalid addr: " << addrDump - << std::endl; - return; - } - } - - setHost(sockaddr_storage_iptostring(addr)); - setPort(sockaddr_storage_port(addr)); -} - -RsUrl& RsUrl::fromString(const std::string& urlStr) -{ - size_t endI = urlStr.size()-1; - - size_t schemeEndI = urlStr.find(schemeSeparator); - if(schemeEndI >= endI) - { - mScheme = urlStr; - return *this; - } - - mScheme = urlStr.substr(0, schemeEndI); - - size_t hostBeginI = schemeEndI + 3; - if(hostBeginI >= endI) return *this; - - bool hasSquareBr = (urlStr[hostBeginI] == ipv6WrapOpen[0]); - size_t hostEndI; - if(hasSquareBr) - { - if(++hostBeginI >= endI) return *this; - hostEndI = urlStr.find(ipv6WrapClose, hostBeginI); - mHost = urlStr.substr(hostBeginI, hostEndI - hostBeginI); - ++hostEndI; - } - else - { - hostEndI = urlStr.find(pathSeparator, hostBeginI); - hostEndI = min(hostEndI, urlStr.find(portSeparator, hostBeginI)); - hostEndI = min(hostEndI, urlStr.find(querySeparator, hostBeginI)); - hostEndI = min(hostEndI, urlStr.find(fragmentSeparator, hostBeginI)); - - mHost = urlStr.substr(hostBeginI, hostEndI - hostBeginI); - } - - if( hostEndI >= endI ) return *this; - - mHasPort = (sscanf(&urlStr[hostEndI], ":%hu", &mPort) == 1); - - size_t pathBeginI = urlStr.find(pathSeparator, hostBeginI); - size_t pathEndI = string::npos; - if(pathBeginI < endI) - { - pathEndI = urlStr.find(querySeparator, pathBeginI); - pathEndI = min(pathEndI, urlStr.find(fragmentSeparator, pathBeginI)); - mPath = UrlDecode(urlStr.substr(pathBeginI, pathEndI - pathBeginI)); - if(pathEndI >= endI) return *this; - } - - size_t queryBeginI = urlStr.find(querySeparator, hostBeginI); - size_t queryEndI = urlStr.find(fragmentSeparator, hostBeginI); - if(queryBeginI < endI) - { - string qStr = urlStr.substr(queryBeginI+1, queryEndI-queryBeginI-1); - - size_t kPos = 0; - size_t assPos = qStr.find(queryAssign); - do - { - size_t vEndPos = qStr.find(queryFieldSep, assPos); - mQuery.insert( std::make_pair( qStr.substr(kPos, assPos-kPos), - UrlDecode(qStr.substr(assPos+1, vEndPos-assPos-1)) - ) ); - kPos = vEndPos+1; - assPos = qStr.find(queryAssign, vEndPos); - } - while(assPos < endI); - - if(queryEndI >= endI) return *this; - } - - size_t fragmentBeginI = urlStr.find(fragmentSeparator, hostBeginI); - if(fragmentBeginI < endI) - mFragment = UrlDecode(urlStr.substr(++fragmentBeginI)); - - return *this; -} - -std::string RsUrl::toString() const -{ - std::string urlStr(mScheme); - urlStr += schemeSeparator; - - if(!mHost.empty()) - { - if(mHost.find(ipv6Separator) != string::npos && - mHost[0] != ipv6WrapOpen[0] ) - urlStr += ipv6WrapOpen + mHost + ipv6WrapClose; - else urlStr += mHost; - } - - if(mHasPort) urlStr += portSeparator + std::to_string(mPort); - - urlStr += UrlEncode(mPath, pathSeparator); - - bool hasQuery = !mQuery.empty(); - if(hasQuery) urlStr += querySeparator; - for(auto&& kv : mQuery) - { - urlStr += kv.first; - urlStr += queryAssign; - urlStr += UrlEncode(kv.second); - urlStr += queryFieldSep; - } - if(hasQuery) urlStr.pop_back(); - - if(!mFragment.empty()) urlStr += fragmentSeparator + UrlEncode(mFragment); - - return urlStr; -} - -const std::string& RsUrl::scheme() const { return mScheme; } -RsUrl& RsUrl::setScheme(const std::string& scheme) -{ - mScheme = scheme; - return *this; -} - -const std::string& RsUrl::host() const { return mHost; } -RsUrl& RsUrl::setHost(const std::string& host) -{ - mHost = host; - return *this; -} - -bool RsUrl::hasPort() const { return mHasPort; } -uint16_t RsUrl::port(uint16_t def) const -{ - if(mHasPort) return mPort; - return def; -} -RsUrl& RsUrl::setPort(uint16_t port) -{ - mPort = port; - mHasPort = true; - return *this; -} -RsUrl& RsUrl::unsetPort() -{ - mPort = 0; - mHasPort = false; - return *this; -} - -const std::string& RsUrl::path() const { return mPath; } -RsUrl& RsUrl::setPath(const std::string& path) -{ - mPath = path; - return *this; -} - -const std::map& RsUrl::query() const -{ return mQuery; } -RsUrl& RsUrl::setQuery(const std::map& query) -{ - mQuery = query; - return *this; -} -RsUrl& RsUrl::setQueryKV(const std::string& key, const std::string& value) -{ - mQuery.insert(std::make_pair(key, value)); - return *this; -} -RsUrl& RsUrl::delQueryK(const std::string& key) -{ - mQuery.erase(key); - return *this; -} -bool RsUrl::hasQueryK(const std::string& key) -{ return (mQuery.find(key) != mQuery.end()); } -rs_view_ptr RsUrl::getQueryV(const std::string& key) -{ - if(hasQueryK(key)) return &(mQuery.find(key)->second); - return nullptr; -} - -const std::string& RsUrl::fragment() const { return mFragment; } -RsUrl& RsUrl::setFragment(const std::string& fragment) -{ - mFragment = fragment; - return *this; -} - -/*static*/ std::string RsUrl::UrlEncode( const std::string& str, - const std::string& ignore ) -{ - ostringstream escaped; - escaped.fill('0'); - escaped << hex; - - for (string::value_type c : str) - { - // Keep alphanumeric and other accepted characters intact - if ( isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' - || ignore.find(c) != string::npos ) - { - escaped << c; - continue; - } - - // Any other characters are percent-encoded - escaped << uppercase; - escaped << '%' << setw(2) << int((unsigned char) c); - escaped << nouppercase; - } - - return escaped.str(); -} - -/*static*/ std::string RsUrl::UrlDecode(const std::string& str) -{ - ostringstream decoded; - - size_t len = str.size(); - size_t boundary = len-2; // % Encoded char must be at least 2 hex char - for (size_t i = 0; i < len; ++i) - { - if(str[i] == '%' && i < boundary) - { - decoded << static_cast(std::stoi( - str.substr(++i, 2), nullptr, 16 )); - ++i; - } - else decoded << str[i]; - } - - return decoded.str(); -} - -void RsUrl::serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx ) -{ - std::string urlString = toString(); - RS_SERIAL_PROCESS(urlString); - fromString(urlString); -} - -/*static*/ const std::string RsUrl::schemeSeparator("://"); -/*static*/ const std::string RsUrl::ipv6WrapOpen("["); -/*static*/ const std::string RsUrl::ipv6Separator(":"); -/*static*/ const std::string RsUrl::ipv6WrapClose("]"); -/*static*/ const std::string RsUrl::portSeparator(":"); -/*static*/ const std::string RsUrl::pathSeparator("/"); -/*static*/ const std::string RsUrl::querySeparator("?"); -/*static*/ const std::string RsUrl::queryAssign("="); -/*static*/ const std::string RsUrl::queryFieldSep("&"); -/*static*/ const std::string RsUrl::fragmentSeparator("#"); - diff --git a/libretroshare/src/util/rsurl.h b/libretroshare/src/util/rsurl.h deleted file mode 100644 index 6e6d124c3..000000000 --- a/libretroshare/src/util/rsurl.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once -/* - * RetroShare - * Copyright (C) 2018 Gioacchino Mazzurco - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "util/rsmemory.h" -#include "serialiser/rsserializable.h" - -struct sockaddr_storage; - -/** - * Very simplistic and minimal URL helper class for RetroShare, after looking - * for a small and self-contained C/C++ URL parsing and manipulation library, - * haven't found nothing satisfactory except for implementation like QUrl that - * rely on bigger library. - * ATM this implementation is not standard compliant and doesn't aim to be. - * Improvements to this are welcome. - * - * Anyway this should support most common URLs of the form - * scheme://host[:port][/path][?query][#fragment] - */ -struct RsUrl : RsSerializable -{ - RsUrl(); - explicit RsUrl(const std::string& urlStr); - explicit RsUrl(const sockaddr_storage& ssas); - - RsUrl& fromString(const std::string& urlStr); - std::string toString() const; - - const std::string& scheme() const; - RsUrl& setScheme(const std::string& scheme); - - const std::string& host() const; - RsUrl& setHost(const std::string& host); - - bool hasPort() const; - uint16_t port(uint16_t def = 0) const; - RsUrl& setPort(uint16_t port); - RsUrl& unsetPort(); - - const std::string& path() const; - RsUrl& setPath(const std::string& path); - - const std::map& query() const; - RsUrl& setQuery(const std::map& query); - RsUrl& setQueryKV(const std::string& key, const std::string& value); - RsUrl& delQueryK(const std::string& key); - bool hasQueryK(const std::string& key); - rs_view_ptr getQueryV(const std::string& key); - - const std::string& fragment() const; - RsUrl& setFragment(const std::string& fragment); - - static std::string UrlEncode(const std::string& str, - const std::string& ignoreChars = ""); - static std::string UrlDecode(const std::string& str); - - inline bool operator<(const RsUrl& rhs) const - { return toString() < rhs.toString(); } - inline bool operator>(const RsUrl& rhs) const - { return toString() > rhs.toString(); } - inline bool operator<=(const RsUrl& rhs) const - { return toString() <= rhs.toString(); } - inline bool operator>=(const RsUrl& rhs) const - { return toString() >= rhs.toString(); } - inline bool operator==(const RsUrl& rhs) const - { return toString() == rhs.toString(); } - inline bool operator!=(const RsUrl& rhs) const - { return toString() != rhs.toString(); } - - /// @see RsSerializable - virtual void serial_process(RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx); - - static const std::string schemeSeparator; - static const std::string ipv6WrapOpen; - static const std::string ipv6Separator; - static const std::string ipv6WrapClose; - static const std::string portSeparator; - static const std::string pathSeparator; - static const std::string querySeparator; - static const std::string queryAssign; - static const std::string queryFieldSep; - static const std::string fragmentSeparator; - -private: - - std::string mScheme; - std::string mHost; - uint16_t mPort; - bool mHasPort; - std::string mPath; - std::map mQuery; - std::string mFragment; -}; - diff --git a/libretroshare/src/util/rswin.h b/libretroshare/src/util/rswin.h deleted file mode 100644 index 22e2ead96..000000000 --- a/libretroshare/src/util/rswin.h +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: rswin.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2010, Thomas Kister * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -/** - * This file provides helper functions for the windows environment - */ - - -#ifndef RSWIN_H_ -#define RSWIN_H_ - -#ifdef WINDOWS_SYS - -#include -#include - -// For win32 systems (tested on MingW+Ubuntu) -#define stat64 _stati64 - -// Should be in Iphlpapi.h, but mingw doesn't seem to have these -// Values copied directly from: -// http://msdn.microsoft.com/en-us/library/aa366845(v=vs.85).aspx -// (Title: MIB_IPADDRROW structure) - -#ifndef MIB_IPADDR_DISCONNECTED -#define MIB_IPADDR_DISCONNECTED 0x0008 // Address is on disconnected interface -#endif - -#ifndef MIB_IPADDR_DELETED -#define MIB_IPADDR_DELETED 0x0040 // Address is being deleted -#endif - -#endif // WINDOWS_SYS - -#endif // RSWIN_H_ diff --git a/libretroshare/src/util/smallobject.cc b/libretroshare/src/util/smallobject.cc deleted file mode 100644 index 5559e2af6..000000000 --- a/libretroshare/src/util/smallobject.cc +++ /dev/null @@ -1,349 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: smallobject.cc * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2011, Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#include -#include "smallobject.h" -#include "util/rsthreads.h" -#include "util/rsmemory.h" - -using namespace RsMemoryManagement ; - -RsMutex SmallObject::_mtx("SmallObject") ; -SmallObjectAllocator SmallObject::_allocator(RsMemoryManagement::MAX_SMALL_OBJECT_SIZE) ; - -void Chunk::init(size_t blockSize,unsigned char blocks) -{ - _data = new unsigned char[blockSize*blocks] ; - _firstAvailableBlock = 0 ; - _blocksAvailable = blocks ; - - // Inits the first byte of each block to point to the next available block - // - unsigned char *p = _data ; - - for(unsigned char i=0;i= 2) ; - - unsigned char *result = _data + _firstAvailableBlock*blockSize ; - - // Grab id of next available block from the block being allocated. - - // Always the case because the first available block is the first, so the next - // available block is given by *result. - // - _firstAvailableBlock = *result ; - --_blocksAvailable ; - - return result ; -} - -void Chunk::deallocate(void *p,size_t blockSize) -{ - assert(p >= _data) ; - - unsigned char *toRelease = static_cast(p) ; - - // alignment check - - assert( (toRelease - _data) % blockSize == 0 ) ; - - *toRelease = _firstAvailableBlock ; - _firstAvailableBlock = static_cast( (toRelease - _data)/blockSize) ; - - // truncation check - - assert(_firstAvailableBlock == (toRelease - _data)/blockSize); - - ++_blocksAvailable ; -} - -void Chunk::printStatistics(int blockSize) const -{ - std::cerr << " blocksAvailable : " << (int)_blocksAvailable << std::endl; - std::cerr << " firstBlockAvailable: " << (int)_firstAvailableBlock << std::endl; - std::cerr << " blocks : " << (void*)_data << " to " << (void*)(_data+BLOCKS_PER_CHUNK*blockSize) << std::endl; -} - -FixedAllocator::FixedAllocator(size_t bytes) -{ - _blockSize = bytes ; - _numBlocks = BLOCKS_PER_CHUNK ; - _allocChunk = -1 ; - _deallocChunk = -1 ; -} -FixedAllocator::~FixedAllocator() -{ - for(uint32_t i=0;i<_chunks.size();++i) - { - _chunks[i]->free() ; - delete _chunks[i] ; - } -} - -void *FixedAllocator::allocate() -{ - if(_allocChunk < 0 || _chunks[_allocChunk]->_blocksAvailable == 0) - { - // find availabel memory in this chunk - // - uint32_t i ; - _allocChunk = -1 ; - for(i=0;i<_chunks.size();++i) - if(_chunks[i]->_blocksAvailable > 0) // found a chunk - { - _allocChunk = i ; - break ; - } - if( _allocChunk < 0 ) - { - _chunks.reserve(_chunks.size()+1) ; - Chunk *newChunk = new Chunk; - - if(newChunk == NULL) - { - std::cerr << "RsMemoryManagement: ran out of memory !" << std::endl; - exit(-1) ; - } - newChunk->init(_blockSize,_numBlocks) ; - _chunks.push_back(newChunk) ; - - _allocChunk = _chunks.size()-1 ; - _deallocChunk = _chunks.size()-1 ; - } - - } - assert(_chunks[_allocChunk] != NULL) ; - assert(_chunks[_allocChunk]->_blocksAvailable > 0) ; - - return _chunks[_allocChunk]->allocate(_blockSize) ; -} -void FixedAllocator::deallocate(void *p) -{ - if(_deallocChunk < 0 || !chunkOwnsPointer(*_chunks[_deallocChunk],p)) - { - // find the chunk that contains this pointer. Perform a linear search. - - _deallocChunk = -1 ; - - for(uint32_t i=0;i<_chunks.size();++i) - if(chunkOwnsPointer(*_chunks[i],p)) - { - _deallocChunk = i ; - break ; - } - } - assert(_chunks[_deallocChunk] != NULL) ; - - _chunks[_deallocChunk]->deallocate(p,_blockSize) ; - - if(_chunks[_deallocChunk]->_blocksAvailable == BLOCKS_PER_CHUNK) - { - _chunks[_deallocChunk]->free() ; - delete _chunks[_deallocChunk] ; - - _chunks[_deallocChunk] = _chunks.back() ; - if(_allocChunk == _deallocChunk) _allocChunk = -1 ; - if(_allocChunk == ((int)_chunks.size())-1) _allocChunk = _deallocChunk ; - _deallocChunk = -1 ; - _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; - std::cerr << " blockSize=" << (int)_blockSize << std::endl; - std::cerr << " Number of chunks: " << _chunks.size() << std::endl; - for(uint32_t i=0;i<_chunks.size();++i) - _chunks[i]->printStatistics(_blockSize) ; -} - -SmallObjectAllocator::SmallObjectAllocator(size_t maxObjectSize) - : _maxObjectSize(maxObjectSize) -{ - RsStackMutex m(SmallObject::_mtx) ; - - _lastAlloc = NULL ; - _lastDealloc = NULL ; - _active = true ; -} - -SmallObjectAllocator::~SmallObjectAllocator() -{ - RsStackMutex m(SmallObject::_mtx) ; - - //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) -{ - if(bytes > _maxObjectSize) - return rs_malloc(bytes) ; - else if(_lastAlloc != NULL && _lastAlloc->blockSize() == bytes) - return _lastAlloc->allocate() ; - else - { - std::map::iterator it(_pool.find(bytes)) ; - - if(it == _pool.end()) - { - _pool[bytes] = new FixedAllocator(bytes) ; - it = _pool.find(bytes) ; - } - _lastAlloc = it->second ; - - return it->second->allocate() ; - } -} - -void SmallObjectAllocator::deallocate(void *p,size_t bytes) -{ - if(bytes > _maxObjectSize) - free(p) ; - else if(_lastDealloc != NULL && _lastDealloc->blockSize() == bytes) - _lastDealloc->deallocate(p) ; - else - { - std::map::iterator it(_pool.find(bytes)) ; - - if(it == _pool.end()) - { - _pool[bytes] = new FixedAllocator(bytes) ; - it = _pool.find(bytes) ; - } - it->second->deallocate(p) ; - _lastDealloc = it->second ; - } -} - -void SmallObjectAllocator::printStatistics() const -{ - std::cerr << "RsMemoryManagement Statistics:" << std::endl; - std::cerr << " Total Fixed-size allocators: " << _pool.size() << std::endl; - std::cerr << "Pool" << std::endl; - - for(std::map::const_iterator it(_pool.begin());it!=_pool.end();++it) - { - std::cerr << " Allocator for size " << it->first << " : " << std::endl; - std::cerr << " Last Alloc: " << _lastAlloc << std::endl; - std::cerr << " Last Dealloc: " << _lastDealloc << std::endl; - it->second->printStatistics() ; - } -} - -void *SmallObject::operator new(size_t size) -{ -#ifdef DEBUG_MEMORY - bool print=false ; - { - RsStackMutex m(_mtx) ; - static rstime_t last_time = 0 ; - rstime_t now = time(NULL) ; - if(now > last_time + 20) - { - last_time = now ; - print=true ; - } - } - if(print) - printStatistics() ; -#endif - - RsStackMutex m(_mtx) ; - - // This should normally not happen. But that prevents a crash when quitting, since we cannot prevent the constructor - // of an object to call operator new(), nor to handle the case where it returns NULL. - // The memory will therefore not be deleted if that happens. We thus print a warning. - - if(_allocator._active) - return _allocator.allocate(size) ; - else - { - std::cerr << "(EE) allocating " << size << " bytes of memory that cannot be deleted. This is a bug, except if it happens when closing Retroshare" << std::endl; - return malloc(size) ; - } - -#ifdef DEBUG_MEMORY - std::cerr << "new RsItem: " << p << ", size=" << size << std::endl; -#endif -} - -void SmallObject::operator delete(void *p,size_t size) -{ - RsStackMutex m(_mtx) ; - - if(!_allocator._active) - return ; - - _allocator.deallocate(p,size) ; -#ifdef DEBUG_MEMORY - std::cerr << "del RsItem: " << p << ", size=" << size << std::endl; -#endif -} - -void SmallObject::printStatistics() -{ - RsStackMutex m(_mtx) ; - - if(!_allocator._active) - return ; - - _allocator.printStatistics() ; -} - -void RsMemoryManagement::printStatistics() -{ - SmallObject::printStatistics(); -} - - diff --git a/libretroshare/src/util/smallobject.h b/libretroshare/src/util/smallobject.h deleted file mode 100644 index 452037ac6..000000000 --- a/libretroshare/src/util/smallobject.h +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * libretroshare/src/util: smallobject.h * - * * - * libretroshare: retroshare core library * - * * - * Copyright (c) 2011, Cyril Soler * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include - -#include -#include - -#include - -namespace RsMemoryManagement -{ - static const int MAX_SMALL_OBJECT_SIZE = 128 ; - static const unsigned char BLOCKS_PER_CHUNK = 255 ; - - struct Chunk - { - void init(size_t blockSize,unsigned char blocks); - void free() ; - - void *allocate(size_t); - void deallocate(void *p,size_t blockSize); - - unsigned char *_data ; - unsigned char _firstAvailableBlock ; - unsigned char _blocksAvailable ; - - void printStatistics(int blockSize) const ; - }; - - class FixedAllocator - { - public: - FixedAllocator(size_t bytes) ; - virtual ~FixedAllocator() ; - - void *allocate(); - void deallocate(void *p) ; - inline size_t blockSize() const { return _blockSize ; } - - inline bool chunkOwnsPointer(const Chunk& c,void *p) const - { - return intptr_t(p) >= intptr_t(c._data) && (intptr_t(static_cast(p))-intptr_t(c._data))/intptr_t(_blockSize)< intptr_t( _numBlocks ); - } - - void printStatistics() const ; - uint32_t currentSize() const; - private: - size_t _blockSize ; - unsigned char _numBlocks ; - std::vector _chunks ; - int _allocChunk ; // last chunk that provided allocation. -1 if not inited - int _deallocChunk ; // last chunk that provided de-allocation. -1 if not inited - }; - - class SmallObjectAllocator - { - public: - SmallObjectAllocator(size_t maxObjectSize) ; - virtual ~SmallObjectAllocator() ; - - void *allocate(size_t numBytes) ; - void deallocate(void *p,size_t size) ; - - void printStatistics() const ; - - bool _active ; - private: - std::map _pool ; - FixedAllocator *_lastAlloc ; - FixedAllocator *_lastDealloc ; - size_t _maxObjectSize ; - }; - - class SmallObject - { - public: - static void *operator new(size_t size) ; - static void operator delete(void *p,size_t size) ; - - static void printStatistics() ; - - virtual ~SmallObject() {} - - private: - static SmallObjectAllocator _allocator ; - static RsMutex _mtx; - - friend class SmallObjectAllocator ; - }; - - extern void printStatistics() ; -} - - diff --git a/libretroshare/src/util/stacktrace.h b/libretroshare/src/util/stacktrace.h deleted file mode 100644 index cb7dc4e71..000000000 --- a/libretroshare/src/util/stacktrace.h +++ /dev/null @@ -1,312 +0,0 @@ -/******************************************************************************* - * libretroshare * - * * - * Copyright (C) 2016-2018 Gioacchino Mazzurco * - * Copyright (C) 2008 Timo Bingmann http://idlebox.net/ * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include -#include -#include - -#ifdef __ANDROID__ -# include "util/rsdebug.h" -#endif - -/** - * @brief Print a backtrace to FILE* out. - * @param[in] demangle true to demangle C++ symbols requires malloc working, in - * some patological cases like a SIGSEGV received during a malloc this would - * cause deadlock so pass false if you may be in such situation (like in a - * SIGSEGV handler ) - * @param[in] out output file - * @param[in] maxFrames maximum number of stack frames you want to bu printed - */ -static inline void print_stacktrace( - bool demangle = true, FILE *out = stderr, unsigned int maxFrames = 63 ); - - -#if defined(__linux__) && defined(__GLIBC__) - -#include -#include - -static inline void print_stacktrace( - bool demangle, FILE* out, unsigned int maxFrames ) -{ - if(!out) - { - fprintf(stderr, "print_stacktrace invalid output file!\n"); - return; - } - - fprintf(out, "stack trace:\n"); - - // storage array for stack trace address data - void* addrlist[maxFrames+1]; - - // retrieve current stack addresses - int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); - - if (addrlen == 0) - { - fprintf(out, " \n"); - return; - } - - if(!demangle) - { - int outFd = fileno(out); - if(outFd < 0) - { - fprintf(stderr, "print_stacktrace invalid output file descriptor!\n"); - return; - } - - backtrace_symbols_fd(addrlist, addrlen, outFd); - return; - } - - // resolve addresses into strings containing "filename(function+address)", - // this array must be free()-ed - char** symbollist = backtrace_symbols(addrlist, addrlen); - - // allocate string which will be filled with the demangled function name - size_t funcnamesize = 256; - char* funcname = (char*)malloc(funcnamesize); - - // iterate over the returned symbol lines. skip the first, it is the - // address of this function. - for (int i = 1; i < addrlen; i++) - { - char *begin_name = 0, *begin_offset = 0, *end_offset = 0; - - /* find parentheses and +address offset surrounding the mangled - * name: ./module(function+0x15c) [0x8048a6d] */ - for (char *p = symbollist[i]; *p; ++p) - { - if (*p == '(') begin_name = p; - else if (*p == '+') begin_offset = p; - else if (*p == ')' && begin_offset) - { - end_offset = p; - break; - } - } - - if ( begin_name && begin_offset && end_offset - && begin_name < begin_offset ) - { - *begin_name++ = '\0'; - *begin_offset++ = '\0'; - *end_offset = '\0'; - - // mangled name is now in [begin_name, begin_offset) and caller - // offset in [begin_offset, end_offset). now apply - // __cxa_demangle(): - - int status; - char* ret = abi::__cxa_demangle( - begin_name, funcname, &funcnamesize, &status ); - if (status == 0) - { - funcname = ret; // use possibly realloc()-ed string - fprintf( out, " %s : %s+%s\n", - symbollist[i], funcname, begin_offset ); - } - else - { - // demangling failed. Output function name as a C function with - // no arguments. - fprintf( out, " %s : %s()+%s\n", - symbollist[i], begin_name, begin_offset ); - } - } - else - { - // couldn't parse the line? print the whole line. - fprintf(out, " %s\n", symbollist[i]); - } - } - - free(funcname); - free(symbollist); -} -#elif defined(__ANDROID__) // defined(__linux__) && defined(__GLIBC__) - -/* Inspired by the solution proposed by Louis Semprini on this thread - * https://stackoverflow.com/questions/8115192/android-ndk-getting-the-backtrace/35586148 - */ - -#include -#include -#include - -struct RsAndroidBacktraceState -{ - void** current; - void** end; -}; - -static inline _Unwind_Reason_Code android_unwind_callback( - struct _Unwind_Context* context, void* arg ) -{ - RsAndroidBacktraceState* state = static_cast(arg); - uintptr_t pc = _Unwind_GetIP(context); - if(pc) - { - if (state->current == state->end) return _URC_END_OF_STACK; - - *state->current++ = reinterpret_cast(pc); - } - return _URC_NO_REASON; -} - -static inline void print_stacktrace( - bool demangle, FILE* /*out*/, unsigned int /*maxFrames*/) -{ - constexpr int max = 5000; - void* buffer[max]; - - RsAndroidBacktraceState state; - state.current = buffer; - state.end = buffer + max; - - _Unwind_Backtrace(android_unwind_callback, &state); - - RsDbg() << std::endl << std::endl - << 0 << " " << buffer[0] << " " << __PRETTY_FUNCTION__ << std::endl; - - // Skip first frame which is print_stacktrace - int count = static_cast(state.current - buffer); - for(int idx = 1; idx < count; ++idx) - { - const void* addr = buffer[idx]; - - /* Ignore null addresses. - * They sometimes happen when using _Unwind_Backtrace() - * with compiler optimizations, when the Link Register is overwritten by - * the inner stack frames. */ - if(!addr) continue; - - /* Ignore duplicate addresses. - * They sometimes happen when using _Unwind_Backtrace() with compiler - * optimizations. */ - if(addr == buffer[idx-1]) continue; - - Dl_info info; - if( !(dladdr(addr, &info) && info.dli_sname) ) - { - RsDbg() << idx << " " << addr << " " << info.dli_fname - << " symbol not found" << std::endl; - continue; - } - - if(demangle) - { - int status = 0; - char* demangled = __cxxabiv1::__cxa_demangle( - info.dli_sname, nullptr, nullptr, &status ); - - if(demangled && (status == 0)) - RsDbg() << idx << " " << addr << " " << demangled << std::endl; - else - RsDbg() << idx << " " << addr << " " - << (info.dli_sname ? info.dli_sname : info.dli_fname) - << " __cxa_demangle failed with: " << status - << std::endl; - - free(demangled); - } - else RsDbg() << idx << " " << addr << " " - << (info.dli_sname ? info.dli_sname : info.dli_fname) - << std::endl; - } - - RsDbg() << std::endl << std::endl; -} - -#else // defined(__linux__) && defined(__GLIBC__) - -static inline void print_stacktrace( - bool /*demangle*/, FILE* out, unsigned int /*max_frames*/ ) -{ - /** Notify the user which signal was caught. We use printf, because this - * is the most basic output function. Once you get a crash, it is - * possible that more complex output systems like streams and the like - * may be corrupted. So we make the most basic call possible to the - * lowest level, most standard print function. */ - fprintf(out, "print_stacktrace Not implemented yet for this platform\n"); -} -#endif // defined(__linux__) && defined(__GLIBC__) - -/** - * @brief CrashStackTrace catch crash signals and print stack trace - * Inspired too https://oroboro.com/stack-trace-on-crash/ - */ -struct CrashStackTrace -{ - CrashStackTrace() - { - signal(SIGABRT, &CrashStackTrace::abortHandler); - signal(SIGSEGV, &CrashStackTrace::abortHandler); - signal(SIGILL, &CrashStackTrace::abortHandler); - signal(SIGFPE, &CrashStackTrace::abortHandler); -#ifdef SIGBUS - signal(SIGBUS, &CrashStackTrace::abortHandler); -#endif - } - - [[ noreturn ]] - static void abortHandler(int signum) - { - // associate each signal with a signal name string. - const char* name = nullptr; - switch(signum) - { - case SIGABRT: name = "SIGABRT"; break; - case SIGSEGV: name = "SIGSEGV"; break; - case SIGILL: name = "SIGILL"; break; - case SIGFPE: name = "SIGFPE"; break; -#ifdef SIGBUS - case SIGBUS: name = "SIGBUS"; break; -#endif - } - -#ifndef __ANDROID__ - /** Notify the user which signal was caught. We use printf, because this - * is the most basic output function. Once you get a crash, it is - * possible that more complex output systems like streams and the like - * may be corrupted. So we make the most basic call possible to the - * lowest level, most standard print function. */ - if(name) - fprintf(stderr, "Caught signal %d (%s)\n", signum, name); - else - fprintf(stderr, "Caught signal %d\n", signum); -#else // ndef __ANDROID__ - /** On Android the best we can to is to rely on RS debug utils */ - RsFatal() << __PRETTY_FUNCTION__ << " Caught signal " << signum << " " - << (name ? name : "") << std::endl; -#endif - - print_stacktrace(false); - - exit(-signum); - } -}; - diff --git a/libretroshare/src/util/utest.h b/libretroshare/src/util/utest.h deleted file mode 100644 index 1ebd9875a..000000000 --- a/libretroshare/src/util/utest.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _UNIT_TEST_MACROS_H__ -#define _UNIT_TEST_MACROS_H__ - -#include - -#define TFAILURE( s ) printf( "FAILURE: " __FILE__ ":%-4d %s\n", __LINE__, s ) -#define TSUCCESS( s ) printf( "SUCCESS: " __FILE__ ":%-4d %s\n", __LINE__, s ) - -/* careful with this line (no protection) */ -#define INITTEST() int ok = 1; int gok = 1; - -/* declare the variables */ -extern int ok; -extern int gok; - -#define CHECK( b ) do { if ( ! (b) ) { ok = 0; TFAILURE( #b ); } } while(0) -#define FAILED( s ) do { ok = 0; TFAILURE( s ); } while(0) -#define REPORT( s ) do { if ( ! (ok) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) -#define REPORT2( b, s ) do { if ( ! (b) ) { ok = 0; TFAILURE( s ); } else { TSUCCESS( s );} gok &= ok; ok = 1; } while(0) -#define FINALREPORT( s ) do { gok &= ok; ok = 1; if ( ! (gok) ) { TFAILURE( s ); } else { TSUCCESS( s );} } while(0) -#define TESTRESULT() (!gok) - -#endif diff --git a/openpgpsdk b/openpgpsdk new file mode 160000 index 000000000..b41667912 --- /dev/null +++ b/openpgpsdk @@ -0,0 +1 @@ +Subproject commit b41667912751a453e8e5d4733215a0609277a26f diff --git a/openpgpsdk/src/openpgpsdk.pro b/openpgpsdk/src/openpgpsdk.pro deleted file mode 100644 index 66341d0a3..000000000 --- a/openpgpsdk/src/openpgpsdk.pro +++ /dev/null @@ -1,144 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") - -TEMPLATE = lib -CONFIG += staticlib - -DEFINES *= OPENSSL_NO_IDEA - -QMAKE_CXXFLAGS *= -Wall -Werror -W - -TARGET = ops -DESTDIR = lib - -!include(use_openpgpsdk.pri):error("Including") - -#################################### Windows ##################################### - -linux-* { - OBJECTS_DIR = temp/linux/obj -} - -win32-g++|win32-clang-g++ { - - HEADERS += openpgpsdk/opsstring.h - SOURCES += openpgpsdk/opsstring.c - - DEFINES *= WIN32_LEAN_AND_MEAN - - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 - - mLibs = bz2 z ssl crypto - static { - LIBS += $$linkStaticLibs(mLibs) - PRE_TARGETDEPS += $$pretargetStaticLibs(mLibs) - } else { - LIBS += $$linkDynamicLibs(mLibs) - } -} - - -macx { - for(lib, LIB_DIR):LIBS += -L"$$lib" - for(bin, BIN_DIR):LIBS += -L"$$bin" - DEFINES += OPENSSL_NO_CAMELLIA -} - -# Input -HEADERS += openpgpsdk/writer.h \ - openpgpsdk/writer_armoured.h \ - openpgpsdk/version.h \ - openpgpsdk/validate.h \ - openpgpsdk/util.h \ - openpgpsdk/types.h \ - openpgpsdk/streamwriter.h \ - openpgpsdk/std_print.h \ - openpgpsdk/signature.h \ - openpgpsdk/readerwriter.h \ - openpgpsdk/random.h \ - openpgpsdk/partial.h \ - openpgpsdk/packet-show.h \ - openpgpsdk/packet-show-cast.h \ - openpgpsdk/packet-parse.h \ - openpgpsdk/packet.h \ - openpgpsdk/memory.h \ - openpgpsdk/literal.h \ - openpgpsdk/lists.h \ - openpgpsdk/keyring.h \ - openpgpsdk/hash.h \ - openpgpsdk/final.h \ - openpgpsdk/defs.h \ - openpgpsdk/errors.h \ - openpgpsdk/crypto.h \ - openpgpsdk/create.h \ - openpgpsdk/configure.h \ - openpgpsdk/compress.h \ - openpgpsdk/callback.h \ - openpgpsdk/accumulate.h \ - openpgpsdk/armour.h \ - openpgpsdk/parse_local.h \ - openpgpsdk/keyring_local.h \ - openpgpsdk/opsdir.h - -SOURCES += openpgpsdk/accumulate.c \ - openpgpsdk/compress.c \ - openpgpsdk/create.c \ - openpgpsdk/crypto.c \ - openpgpsdk/errors.c \ - openpgpsdk/fingerprint.c \ - openpgpsdk/hash.c \ - openpgpsdk/keyring.c \ - openpgpsdk/lists.c \ - openpgpsdk/memory.c \ - openpgpsdk/openssl_crypto.c \ - openpgpsdk/packet-parse.c \ - openpgpsdk/packet-print.c \ - openpgpsdk/packet-show.c \ - openpgpsdk/random.c \ - openpgpsdk/reader.c \ - openpgpsdk/reader_armoured.c \ - openpgpsdk/reader_encrypted_se.c \ - openpgpsdk/reader_encrypted_seip.c \ - openpgpsdk/reader_fd.c \ - openpgpsdk/reader_hashed.c \ - openpgpsdk/reader_mem.c \ - openpgpsdk/readerwriter.c \ - openpgpsdk/signature.c \ - openpgpsdk/symmetric.c \ - openpgpsdk/util.c \ - openpgpsdk/validate.c \ - openpgpsdk/writer.c \ - openpgpsdk/writer_armour.c \ - openpgpsdk/writer_partial.c \ - openpgpsdk/writer_literal.c \ - openpgpsdk/writer_encrypt.c \ - openpgpsdk/writer_encrypt_se_ip.c \ - openpgpsdk/writer_fd.c \ - openpgpsdk/writer_memory.c \ - openpgpsdk/writer_skey_checksum.c \ - openpgpsdk/writer_stream_encrypt_se_ip.c \ - openpgpsdk/opsdir.c - - -################################# Android ##################################### - -android-* { - -## Add this here because static library are very sensible to order in -## command line - LIBS += -L$$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/ -lssl - INCLUDEPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include - DEPENDPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include - PRE_TARGETDEPS += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.a - - LIBS += -L$$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/ -lcrypto - INCLUDEPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include - DEPENDPATH += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/include - PRE_TARGETDEPS += $$NATIVE_LIBS_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.a -} diff --git a/openpgpsdk/src/openpgpsdk/accumulate.c b/openpgpsdk/src/openpgpsdk/accumulate.c deleted file mode 100644 index 025e08e74..000000000 --- a/openpgpsdk/src/openpgpsdk/accumulate.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include "keyring_local.h" -#include "parse_local.h" -#include -#include -#include - -#include - -typedef struct - { - ops_keyring_t *keyring; - } accumulate_arg_t; - -/** - * \ingroup Core_Callbacks - */ -static ops_parse_cb_return_t accumulate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) -{ - accumulate_arg_t *arg=ops_parse_cb_get_arg(cbinfo); - const ops_parser_content_union_t *content=&content_->content; - ops_keyring_t *keyring=arg->keyring; - ops_keydata_t *cur=NULL; - const ops_public_key_t *pkey; - - if(keyring->nkeys >= 0) - cur=&keyring->keys[keyring->nkeys]; - - switch(content_->tag) - { - case OPS_PTAG_CT_PUBLIC_KEY: - case OPS_PTAG_CT_SECRET_KEY: - case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: - // printf("New key\n"); - ++keyring->nkeys; - EXPAND_ARRAY(keyring,keys); - - if(content_->tag == OPS_PTAG_CT_PUBLIC_KEY) - pkey=&content->public_key; - else - pkey=&content->secret_key.public_key; - - memset(&keyring->keys[keyring->nkeys],'\0', sizeof keyring->keys[keyring->nkeys]); - - ops_keyid(keyring->keys[keyring->nkeys].key_id,pkey); - ops_fingerprint(&keyring->keys[keyring->nkeys].fingerprint,pkey); - - keyring->keys[keyring->nkeys].type=content_->tag; - - if(content_->tag == OPS_PTAG_CT_PUBLIC_KEY) - keyring->keys[keyring->nkeys].key.pkey=*pkey; - else - keyring->keys[keyring->nkeys].key.skey=content->secret_key; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_USER_ID: - // printf("User ID: %s\n",content->user_id.user_id); - if (!cur) - { - OPS_ERROR(cbinfo->errors,OPS_E_P_NO_USERID, "No user id found"); - return OPS_KEEP_MEMORY; - } - ops_add_userid_to_keydata(cur, &content->user_id); - free(content->user_id.user_id); - return OPS_KEEP_MEMORY; - - case OPS_PARSER_PACKET_END: - if(!cur) - return OPS_RELEASE_MEMORY; - ops_add_packet_to_keydata(cur, &content->packet); - free(content->packet.raw); - return OPS_KEEP_MEMORY; - - case OPS_PARSER_ERROR: - fprintf(stderr,"Error: %s\n",content->error.error); - break; - - case OPS_PARSER_ERRCODE: - switch(content->errcode.errcode) - { - default: - fprintf(stderr,"parse error: %s\n", ops_errcode(content->errcode.errcode)); - } - break; - - default: - break; - } - - // XXX: we now exclude so many things, we should either drop this or - // do something to pass on copies of the stuff we keep - return ops_parse_stacked_cb(content_,cbinfo); -} - -/** - * \ingroup Core_Parse - * - * Parse packets from an input stream until EOF or error. - * - * Key data found in the parsed data is added to #keyring. - * - * \param keyring Pointer to an existing keyring - * \param parse_info Options to use when parsing -*/ - -int ops_parse_and_accumulate(ops_keyring_t *keyring, - ops_parse_info_t *parse_info) - { - int rtn; - - accumulate_arg_t arg; - - if(parse_info->rinfo.accumulate) - { - fprintf(stderr,"Structural error: parse_info->rinfo.accumulate should be ops_false" ) ; - return 0 ; // error - } - //assert(!parse_info->rinfo.accumulate); - - memset(&arg,'\0',sizeof arg); - - arg.keyring=keyring; - /* Kinda weird, but to do with counting, and we put it back after */ - --keyring->nkeys; - - ops_parse_cb_push(parse_info,accumulate_cb,&arg); - - parse_info->rinfo.accumulate=ops_true; - - rtn=ops_parse(parse_info,ops_false); - ++keyring->nkeys; - - return rtn; - } - -static void dump_one_keydata(const ops_keydata_t *key) - { - unsigned n; - - printf("Key ID: "); - hexdump(key->key_id,8); - - printf("\nFingerpint: "); - hexdump(key->fingerprint.fingerprint,key->fingerprint.length); - - printf("\n\nUIDs\n====\n\n"); - for(n=0 ; n < key->nuids ; ++n) - printf("%s\n",key->uids[n].user_id); - - printf("\nPackets\n=======\n"); - for(n=0 ; n < key->npackets ; ++n) - { - printf("\n%03d: ",n); - hexdump(key->packets[n].raw,key->packets[n].length); - } - printf("\n\n"); - } - -// XXX: not a maintained part of the API - use ops_keyring_list() -/** ops_dump_keyring -*/ -void ops_dump_keyring(const ops_keyring_t *keyring) - { - int n; - - for(n=0 ; n < keyring->nkeys ; ++n) - dump_one_keydata(&keyring->keys[n]); - } diff --git a/openpgpsdk/src/openpgpsdk/accumulate.h b/openpgpsdk/src/openpgpsdk/accumulate.h deleted file mode 100644 index eeadb4011..000000000 --- a/openpgpsdk/src/openpgpsdk/accumulate.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_ACCUMULATE_H -#define OPS_ACCUMULATE_H -#endif - -#include "keyring.h" -#include "packet-parse.h" - -int ops_parse_and_accumulate(ops_keyring_t *keyring, - ops_parse_info_t *parse_info); diff --git a/openpgpsdk/src/openpgpsdk/armour.h b/openpgpsdk/src/openpgpsdk/armour.h deleted file mode 100644 index b2f3a8d69..000000000 --- a/openpgpsdk/src/openpgpsdk/armour.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OPS_ARMOUR_H__ -#define __OPS_ARMOUR_H__ - -#include "packet-parse.h" -#include "signature.h" - -unsigned ops_crc24(unsigned checksum,unsigned char c); - -void ops_reader_push_dearmour(ops_parse_info_t *parse_info); - -void ops_reader_pop_dearmour(ops_parse_info_t *parse_info); -ops_boolean_t ops_writer_push_clearsigned(ops_create_info_t *info, - ops_create_signature_t *sig); -void ops_writer_push_armoured_message(ops_create_info_t *info); -ops_boolean_t ops_writer_switch_to_armoured_signature(ops_create_info_t *info); - -typedef enum - { - OPS_PGP_MESSAGE=1, - OPS_PGP_PUBLIC_KEY_BLOCK, - OPS_PGP_PRIVATE_KEY_BLOCK, - OPS_PGP_MULTIPART_MESSAGE_PART_X_OF_Y, - OPS_PGP_MULTIPART_MESSAGE_PART_X, - OPS_PGP_SIGNATURE - } ops_armor_type_t; - -void ops_writer_push_armoured(ops_create_info_t *info, ops_armor_type_t type); - -#define CRC24_INIT 0xb704ceL - -#endif /* __OPS_ARMOUR_H__ */ - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/callback.h b/openpgpsdk/src/openpgpsdk/callback.h deleted file mode 100644 index 399c3d118..000000000 --- a/openpgpsdk/src/openpgpsdk/callback.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OPS_CALLBACK_H__ -#define __OPS_CALLBACK_H__ - -#define CB(cbinfo,t,pc) do { (pc)->tag=(t); if(ops_parse_cb((pc),(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) -/*#define CB(cbinfo,t,pc) do { (pc)->tag=(t); if((cbinfo)->cb(pc,(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0)*/ -//#define CB(cbinfo,t,pc) do { (pc)->tag=(t); if((cbinfo)->cb(pc,(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) - -#define CBP(info,t,pc) CB(&(info)->cbinfo,t,pc) - -#define ERR(cbinfo,err,code) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,(cbinfo)); OPS_ERROR(errors,code,err); return -1; } while(0) - /*#define ERR(err) do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,cbinfo); return -1; } while(0)*/ - -#define ERRP(info,err) do { C.error.error=err; CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) - - -#endif /*__OPS_CALLBACK_H__*/ diff --git a/openpgpsdk/src/openpgpsdk/compress.c b/openpgpsdk/src/openpgpsdk/compress.c deleted file mode 100644 index afe3db6ac..000000000 --- a/openpgpsdk/src/openpgpsdk/compress.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh. - * The Contributors have asserted their moral rights under the - * UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include - -#include -#include -#include -#include -#include "parse_local.h" -#include -#include - -static const int debug = 0; - -#define DECOMPRESS_BUFFER 1024 -#define COMPRESS_BUFFER 32768 - -typedef struct - { - ops_compression_type_t type; - ops_region_t *region; - unsigned char in[DECOMPRESS_BUFFER]; - unsigned char out[DECOMPRESS_BUFFER]; - z_stream zstream; // ZIP and ZLIB - size_t offset; - int inflate_ret; - } z_decompress_arg_t; - -typedef struct - { - ops_compression_type_t type; - ops_region_t *region; - char in[DECOMPRESS_BUFFER]; - char out[DECOMPRESS_BUFFER]; - bz_stream bzstream; // BZIP2 - size_t offset; - int inflate_ret; - } bz_decompress_arg_t; - -typedef struct - { - z_stream stream; - unsigned char *src; - unsigned char *dst; - size_t bytes_in; - size_t bytes_out; - } compress_arg_t; - -// \todo remove code duplication between this and bzip2_compressed_data_reader -static int zlib_compressed_data_reader(void *dest,size_t length, - ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - z_decompress_arg_t *arg=ops_reader_get_arg(rinfo); - - if(! (arg->type==OPS_C_ZIP || arg->type==OPS_C_ZLIB) ) // ASSERT(arg->type==OPS_C_ZIP || arg->type==OPS_C_ZLIB); - { - fprintf(stderr,"zlib_compressed_data_reader: unexpected compress format %d\n",arg->type) ; - return -1 ; - } - - //ops_parser_content_t content; - int saved=length; - - if(/*arg->region->indeterminate && */ arg->inflate_ret == Z_STREAM_END - && arg->zstream.next_out == &arg->out[arg->offset]) - return 0; - - if(arg->region->length_read == arg->region->length) - { - if(arg->inflate_ret != Z_STREAM_END) - OPS_ERROR(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Compressed data didn't end when region ended."); - /* - else - return 0; - www.zlib.org - */ - } - - while(length > 0) - { - unsigned len; - - if(&arg->out[arg->offset] == arg->zstream.next_out) - { - int ret; - - arg->zstream.next_out=arg->out; - arg->zstream.avail_out=sizeof arg->out; - arg->offset=0; - if(arg->zstream.avail_in == 0) - { - unsigned n=arg->region->length; - - if(!arg->region->indeterminate) - { - n-=arg->region->length_read; - if(n > sizeof arg->in) - n=sizeof arg->in; - } - else - n=sizeof arg->in; - - if(!ops_stacked_limited_read(arg->in,n,arg->region, - errors,rinfo,cbinfo)) - return -1; - - arg->zstream.next_in=arg->in; - arg->zstream.avail_in=arg->region->indeterminate - ? arg->region->last_read : n; - } - - ret=inflate(&arg->zstream,Z_SYNC_FLUSH); - if(ret == Z_STREAM_END) - { - if(!arg->region->indeterminate - && arg->region->length_read != arg->region->length) - OPS_ERROR(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR, - "Compressed stream ended before packet end."); - } - else if(ret != Z_OK) - { - fprintf(stderr,"ret=%d\n",ret); - OPS_ERROR(cbinfo->errors,OPS_E_P_DECOMPRESSION_ERROR, arg->zstream.msg); - } - arg->inflate_ret=ret; - } - - if(!(arg->zstream.next_out > &arg->out[arg->offset])) // ASSERT(arg->zstream.next_out > &arg->out[arg->offset]); - { - fprintf(stderr,"decompression error: next packet is too large.\n"); - return -1 ; - } - len=arg->zstream.next_out-&arg->out[arg->offset]; - if(len > length) - len=length; - memcpy(dest,&arg->out[arg->offset],len); - arg->offset+=len; - length-=len; - } - - return saved; -} - -// \todo remove code duplication between this and zlib_compressed_data_reader -static int bzip2_compressed_data_reader(void *dest,size_t length, - ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - bz_decompress_arg_t *arg=ops_reader_get_arg(rinfo); - - if(!(arg->type==OPS_C_BZIP2)) // ASSERT(arg->type==OPS_C_BZIP2); - { - fprintf(stderr,"bzip2_compressed_data_reader: unexpected compress format %d\n",arg->type) ; - return -1 ; - } - - //ops_parser_content_t content; - int saved=length; - - if(arg->inflate_ret == BZ_STREAM_END - && arg->bzstream.next_out == &arg->out[arg->offset]) - return 0; - - if(arg->region->length_read == arg->region->length) - { - if(arg->inflate_ret != BZ_STREAM_END) - OPS_ERROR(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Compressed data didn't end when region ended."); - } - - while(length > 0) - { - unsigned len; - - if(&arg->out[arg->offset] == arg->bzstream.next_out) - { - int ret; - - arg->bzstream.next_out=(char *) arg->out; - arg->bzstream.avail_out=sizeof arg->out; - arg->offset=0; - if(arg->bzstream.avail_in == 0) - { - unsigned n=arg->region->length; - - if(!arg->region->indeterminate) - { - n-=arg->region->length_read; - if(n > sizeof arg->in) - n=sizeof arg->in; - } - else - n=sizeof arg->in; - - if(!ops_stacked_limited_read(arg->in, n, arg->region, errors, - rinfo, cbinfo)) - return -1; - - arg->bzstream.next_in=arg->in; - arg->bzstream.avail_in=arg->region->indeterminate - ? arg->region->last_read : n; - } - - ret=BZ2_bzDecompress(&arg->bzstream); - if(ret == BZ_STREAM_END) - { - if(!arg->region->indeterminate - && arg->region->length_read != arg->region->length) - OPS_ERROR(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Compressed stream ended before packet end."); - } - else if(ret != BZ_OK) - { - OPS_ERROR_1(cbinfo->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Invalid return %d from BZ2_bzDecompress", ret); - } - arg->inflate_ret=ret; - } - if(!(arg->bzstream.next_out > &arg->out[arg->offset])) // ASSERT(arg->bzstream.next_out > &arg->out[arg->offset]); - { - fprintf(stderr,"bzip2_compressed_data_reader: unexpected size in compressed packet.\n") ; - return -1 ; - } - len=arg->bzstream.next_out-&arg->out[arg->offset]; - if(len > length) - len=length; - memcpy(dest,&arg->out[arg->offset],len); - arg->offset+=len; - length-=len; - } - - return saved; -} - -/** - * \ingroup Core_Compress - * - * \param *region Pointer to a region - * \param *parse_info How to parse - * \param type Which compression type to expect -*/ - -int ops_decompress(ops_region_t *region,ops_parse_info_t *parse_info, - ops_compression_type_t type) - { - z_decompress_arg_t z_arg; - bz_decompress_arg_t bz_arg; - int ret; - - switch (type) - { - case OPS_C_ZIP: - case OPS_C_ZLIB: - memset(&z_arg,'\0',sizeof z_arg); - - z_arg.region=region; - z_arg.offset=0; - z_arg.type=type; - - z_arg.zstream.next_in=Z_NULL; - z_arg.zstream.avail_in=0; - z_arg.zstream.next_out=z_arg.out; - z_arg.zstream.zalloc=Z_NULL; - z_arg.zstream.zfree=Z_NULL; - z_arg.zstream.opaque=Z_NULL; - break; - - case OPS_C_BZIP2: - memset(&bz_arg,'\0',sizeof bz_arg); - - bz_arg.region=region; - bz_arg.offset=0; - bz_arg.type=type; - - bz_arg.bzstream.next_in=NULL; - bz_arg.bzstream.avail_in=0; - bz_arg.bzstream.next_out=bz_arg.out; - bz_arg.bzstream.bzalloc=NULL; - bz_arg.bzstream.bzfree=NULL; - bz_arg.bzstream.opaque=NULL; - break; - - default: - OPS_ERROR_1(&parse_info->errors, OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - switch(type) - { - case OPS_C_ZIP: - ret=inflateInit2(&z_arg.zstream,-15); - break; - - case OPS_C_ZLIB: - ret=inflateInit(&z_arg.zstream); - break; - - case OPS_C_BZIP2: - /* - OPS_ERROR_1(&parse_info->errors, OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG, "Compression algorithm %s is not yet supported", "BZIP2"); - return 0; - */ - ret=BZ2_bzDecompressInit(&bz_arg.bzstream, 1, 0); - break; - - default: - OPS_ERROR_1(&parse_info->errors, OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - switch (type) - { - case OPS_C_ZIP: - case OPS_C_ZLIB: - if(ret != Z_OK) - { - OPS_ERROR_1(&parse_info->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Cannot initialise ZIP or ZLIB stream " - "for decompression: error=%d", ret); - return 0; - } - ops_reader_push(parse_info,zlib_compressed_data_reader,NULL,&z_arg); - break; - - case OPS_C_BZIP2: - if (ret != BZ_OK) - { - OPS_ERROR_1(&parse_info->errors, OPS_E_P_DECOMPRESSION_ERROR, - "Cannot initialise BZIP2 stream " - "for decompression: error=%d", ret); - return 0; - } - ops_reader_push(parse_info,bzip2_compressed_data_reader,NULL,&bz_arg); - break; - - default: - OPS_ERROR_1(&parse_info->errors, OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG, - "Compression algorithm %d is not yet supported", type); - return 0; - } - - ret=ops_parse(parse_info,ops_true); - - ops_reader_pop(parse_info); - - return ret; - } - -/** -\ingroup Core_WritePackets -\brief Writes Compressed packet -\param data Data to write out -\param len Length of data -\param cinfo Write settings -\return ops_true if OK; else ops_false -*/ - -ops_boolean_t ops_write_compressed(const unsigned char *data, - const unsigned int len, - ops_create_info_t *cinfo) -{ - int r=0; - int sz_in=0; - int sz_out=0; - compress_arg_t* compress=ops_mallocz(sizeof *compress); - - // compress the data - const int level=Z_DEFAULT_COMPRESSION; // \todo allow varying levels - compress->stream.zalloc=Z_NULL; - compress->stream.zfree=Z_NULL; - compress->stream.opaque=NULL; - - // all other fields set to zero by use of ops_mallocz - - if (deflateInit(&compress->stream,level) != Z_OK) - { - // can't initialise - - fprintf(stderr,"ops_write_compressed: can't initialise compression engine\n") ; - return ops_false ; - } - - // do necessary transformation - // copy input to maintain const'ness of src - - if(!(compress->src==NULL)) // ASSERT(compress->src==NULL); - { - fprintf(stderr,"ops_write_compressed: compress->src should be NULL\n") ; - return ops_false ; - } - if(!(compress->dst==NULL)) // ASSERT(compress->dst==NULL); - { - fprintf(stderr,"ops_write_compressed: compress->dst should be NULL\n") ; - return ops_false ; - } - - sz_in=len * sizeof (unsigned char); - sz_out= (sz_in * 1.01) + 12; // from zlib webpage - compress->src=ops_mallocz(sz_in); - compress->dst=ops_mallocz(sz_out); - memcpy(compress->src,data,len); - - // setup stream - compress->stream.next_in=compress->src; - compress->stream.avail_in=sz_in; - compress->stream.total_in=0; - - compress->stream.next_out=compress->dst; - compress->stream.avail_out=sz_out; - compress->stream.total_out=0; - - r=deflate(&compress->stream, Z_FINISH); - - if(!(r==Z_STREAM_END)) // ASSERT(r==Z_STREAM_END); // need to loop if not - { - fprintf(stderr,"ops_write_compressed: compression failed.\n") ; - return ops_false ; - } - - // write it out - return (ops_write_ptag(OPS_PTAG_CT_COMPRESSED, cinfo) - && ops_write_length(1+compress->stream.total_out, cinfo) - && ops_write_scalar(OPS_C_ZLIB,1,cinfo) - && ops_write(compress->dst, compress->stream.total_out,cinfo)); -} - - -// Writes out the header for the compressed packet. Invoked by the -// partial stream writer. Note that writing the packet tag and the -// packet length is handled by the partial stream writer. -static ops_boolean_t write_compressed_header(ops_create_info_t *info, - void *header_data) - { - OPS_USED(header_data); - // Write the compression type. Currently we just use ZLIB - ops_write_scalar(OPS_C_ZLIB, 1, info); - return ops_true; - } - -static void zlib_error(ops_error_t **errors, z_stream *stream, int error) - { - OPS_ERROR_2(errors,OPS_E_FAIL, - "Error from compression stream %d (%s)", error, - stream->msg == NULL ? "Unknown" : stream->msg); - } - -static ops_boolean_t stream_compress_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - // ZLib doesn't like being asked to compress nothing, so return if - // we are given no input. - if (length == 0) - return ops_true; - if (debug) - fprintf(stderr, "Compressing %u bytes\n", length); - compress_arg_t* compress = ops_writer_get_arg(winfo); - compress->bytes_in += length; - compress->stream.next_in = (void*) src; - compress->stream.avail_in = length; - ops_boolean_t result = ops_true; - do - { - compress->stream.next_out = compress->dst; - compress->stream.avail_out = COMPRESS_BUFFER; - int retcode = deflate(&compress->stream, Z_NO_FLUSH); - if (retcode != Z_OK) - { - zlib_error(errors, &compress->stream, retcode); - deflateEnd(&compress->stream); - return ops_false; - } - unsigned bytes_to_write = COMPRESS_BUFFER - compress->stream.avail_out; - if (debug) - fprintf(stderr, "bytes_to_write = %u\n", bytes_to_write); - compress->bytes_out += bytes_to_write; - result = ops_stacked_write(compress->dst, bytes_to_write, errors, - winfo); - } - while (result && compress->stream.avail_out == 0); - - return result; - } - -static ops_boolean_t stream_compress_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - compress_arg_t* compress = ops_writer_get_arg(winfo); - compress->stream.next_in = NULL; - compress->stream.avail_in = 0; - int retcode = Z_OK; - int output_size = COMPRESS_BUFFER; - ops_boolean_t result = ops_true; - do - { - compress->stream.next_out = compress->dst; - compress->stream.avail_out = output_size; - retcode = deflate(&compress->stream, Z_FINISH); - if (retcode != Z_STREAM_END && retcode != Z_OK) - { - zlib_error(errors, &compress->stream, retcode); - deflateEnd(&compress->stream); - return ops_false; - } - int bytes_to_write = output_size - compress->stream.avail_out; - if (debug) - fprintf(stderr, "At end, bytes_to_write = %u\n", bytes_to_write); - compress->bytes_out += bytes_to_write; - result = ops_stacked_write(compress->dst, bytes_to_write, errors, - winfo); - - // If deflate returns Z_OK after we have asked to flush, it means - // that there was not enough space in the output buffer. Increase - // the buffer size and try again. - if (retcode != Z_STREAM_END) - { - if (debug) - fprintf(stderr, "Reallocating %u\n", output_size * 2); - output_size *= 2; - compress->dst = realloc(compress->dst, output_size); - } - } - while (result && retcode != Z_STREAM_END); - - int error = deflateEnd(&compress->stream); - if (error != Z_OK) - { - zlib_error(errors, &compress->stream, error); - return ops_false; - } - return result; - } - -static void stream_compress_destroyer(ops_writer_info_t *winfo) - { - compress_arg_t* compress = ops_writer_get_arg(winfo); - if (debug) - fprintf(stderr, "Compressed %zu to %zu\n", compress->bytes_in, - compress->bytes_out); - free(compress->dst); - free(compress); - } - -/** -\ingroup Core_WritePackets -\brief Pushes a compressed writer onto the stack. Data written - will be encoded as a compressed packet. -\param cinfo Write settings -*/ -ops_boolean_t ops_writer_push_compressed(ops_create_info_t *cinfo) -{ - // This is a streaming writer, so we don't know the length in - // advance. Use a partial writer to handle the partial body - // packet lengths. - ops_writer_push_partial(COMPRESS_BUFFER, - cinfo, OPS_PTAG_CT_COMPRESSED, - write_compressed_header, NULL); - - // Create arg to be used with this writer - // Remember to free this in the destroyer - compress_arg_t *compress = ops_mallocz(sizeof *compress); - - compress->dst = malloc(COMPRESS_BUFFER); - const int level=Z_DEFAULT_COMPRESSION; // \todo allow varying levels - compress->stream.zalloc=Z_NULL; - compress->stream.zfree=Z_NULL; - compress->stream.opaque=NULL; - compress->stream.avail_out = COMPRESS_BUFFER; - // all other fields set to zero by use of ops_mallocz - - if (deflateInit(&compress->stream, level) != Z_OK) - // can't initialise. Is there a better way to handle this? - return ops_false ; - - // And push writer on stack - ops_writer_push(cinfo, stream_compress_writer, stream_compress_finaliser, - stream_compress_destroyer, compress); - - return ops_true ; -} - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/compress.h b/openpgpsdk/src/openpgpsdk/compress.h deleted file mode 100644 index 04d124e41..000000000 --- a/openpgpsdk/src/openpgpsdk/compress.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include "packet-parse.h" - -int ops_decompress(ops_region_t *region,ops_parse_info_t *parse_info, - ops_compression_type_t type); - -ops_boolean_t ops_write_compressed(const unsigned char* data, - const unsigned int len, - ops_create_info_t *cinfo); - -ops_boolean_t ops_writer_push_compressed(ops_create_info_t *cinfo); diff --git a/openpgpsdk/src/openpgpsdk/configure.h b/openpgpsdk/src/openpgpsdk/configure.h deleted file mode 100644 index 63051b316..000000000 --- a/openpgpsdk/src/openpgpsdk/configure.h +++ /dev/null @@ -1,15 +0,0 @@ -/* generated by configure from include/openpgpsdk/configure.h.template. Don't edit. */ - -#define HAVE_ALLOCA_H 0 -#define TIME_T_FMT "%ld" - -/* for silencing unused parameter warnings */ -#define OPS_USED(x) (x)=(x) - -/* for tests, flag to tell gpg not to use blocking randomness */ -#define GNUPG_QUICK_RANDOM "--quick-random" - -/* Avoid a bunch of #ifs */ -#ifndef O_BINARY -# define O_BINARY 0 -#endif diff --git a/openpgpsdk/src/openpgpsdk/create.c b/openpgpsdk/src/openpgpsdk/create.c deleted file mode 100644 index b4fe548a7..000000000 --- a/openpgpsdk/src/openpgpsdk/create.c +++ /dev/null @@ -1,1396 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include - -#include -#include -#include -#include -#include -#include -#include "keyring_local.h" -#include -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif -#include - -#include -#include - -static int debug=0; - -/** - * \ingroup Core_Create - * \param length - * \param type - * \param info - * \return ops_true if OK, otherwise ops_false - */ - -ops_boolean_t ops_write_ss_header(unsigned length,ops_content_tag_t type, - ops_create_info_t *info) - { - return ops_write_length(length,info) - && ops_write_scalar(type-OPS_PTAG_SIGNATURE_SUBPACKET_BASE,1,info); - } - -/* XXX: the general idea of _fast_ is that it doesn't copy stuff - * the safe (i.e. non _fast_) version will, and so will also need to - * be freed. */ - -/** - * \ingroup Core_Create - * - * ops_fast_create_user_id() sets id->user_id to the given user_id. - * This is fast because it is only copying a char*. However, if user_id - * is changed or freed in the future, this could have injurious results. - * \param id - * \param user_id - */ - -void ops_fast_create_user_id(ops_user_id_t *id,unsigned char *user_id) - { - id->user_id=user_id; - } - -/** - * \ingroup Core_WritePackets - * \brief Writes a User Id packet - * \param id - * \param info - * \return ops_true if OK, otherwise ops_false - */ -ops_boolean_t ops_write_struct_user_id(ops_user_id_t *id, - ops_create_info_t *info) - { - return ops_write_ptag(OPS_PTAG_CT_USER_ID,info) - && ops_write_length(strlen((char *)id->user_id),info) - && ops_write(id->user_id,strlen((char *)id->user_id),info); - } - -/** - * \ingroup Core_WritePackets - * \brief Write a User Id packet. - * \param user_id - * \param info - * - * \return return value from ops_write_struct_user_id() - */ -ops_boolean_t ops_write_user_id(const unsigned char *user_id, - ops_create_info_t *info) - { - ops_user_id_t id; - - id.user_id=(unsigned char *)user_id; - return ops_write_struct_user_id(&id,info); - } - -/** -\ingroup Core_MPI -*/ -static unsigned mpi_length(const BIGNUM *bn) -{ - return 2+(BN_num_bits(bn)+7)/8; -} - -static unsigned public_key_length(const ops_public_key_t *key) -{ - switch(key->algorithm) - { - case OPS_PKA_RSA: return mpi_length(key->key.rsa.n) - +mpi_length(key->key.rsa.e); - - case OPS_PKA_DSA: return mpi_length(key->key.dsa.p) - +mpi_length(key->key.dsa.q) - +mpi_length(key->key.dsa.g) - +mpi_length(key->key.dsa.y); - case OPS_PKA_ELGAMAL: - return mpi_length(key->key.elgamal.p) - +mpi_length(key->key.elgamal.g) - +mpi_length(key->key.elgamal.y) ; - - default: - fprintf(stderr,"Bad algorithm type in key: %d\n",key->algorithm) ; - assert(!"unknown key algorithm"); - } - /* not reached */ - return 0; -} - -static unsigned secret_key_length(const ops_secret_key_t *key) -{ - int l; - - switch(key->public_key.algorithm) - { - case OPS_PKA_RSA: l=mpi_length(key->key.rsa.d) - +mpi_length(key->key.rsa.p) - +mpi_length(key->key.rsa.q) - +mpi_length(key->key.rsa.u); - break ; - - case OPS_PKA_DSA: l=mpi_length(key->key.dsa.x); - break; - - default: - assert(!"unknown key algorithm"); - } - - return l+public_key_length(&key->public_key); -} - -/** - * \ingroup Core_Create - * \param key - * \param time - * \param n - * \param e -*/ -void ops_fast_create_rsa_public_key(ops_public_key_t *key,time_t time, - BIGNUM *n,BIGNUM *e) - { - key->version=4; - key->creation_time=time; - key->algorithm=OPS_PKA_RSA; - key->key.rsa.n=n; - key->key.rsa.e=e; - } - -/* Note that we support v3 keys here because they're needed for - * for verification - the writer doesn't allow them, though */ -static ops_boolean_t write_public_key_body(const ops_public_key_t *key, - ops_create_info_t *info) -{ - if(!(ops_write_scalar(key->version,1,info) && ops_write_scalar(key->creation_time,4,info))) - return ops_false; - - if(key->version != 4 && !ops_write_scalar(key->days_valid,2,info)) - return ops_false; - - if(!ops_write_scalar(key->algorithm,1,info)) - return ops_false; - - switch(key->algorithm) - { - case OPS_PKA_DSA: - return ops_write_mpi(key->key.dsa.p,info) - && ops_write_mpi(key->key.dsa.q,info) - && ops_write_mpi(key->key.dsa.g,info) - && ops_write_mpi(key->key.dsa.y,info); - - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - return ops_write_mpi(key->key.rsa.n,info) - && ops_write_mpi(key->key.rsa.e,info); - - case OPS_PKA_ELGAMAL: - return ops_write_mpi(key->key.elgamal.p,info) - && ops_write_mpi(key->key.elgamal.g,info) - && ops_write_mpi(key->key.elgamal.y,info); - - default: - fprintf(stderr, "Unknown algorithm %d\n", key->algorithm); - assert(0); - break; - } - - /* not reached */ - return ops_false; -} - -/* Note that we support v3 keys here because they're needed for - * for verification - the writer doesn't allow them, though */ -static ops_boolean_t write_secret_key_body(const ops_secret_key_t *key, - const unsigned char* passphrase, - const size_t pplen, - ops_create_info_t *info) -{ - /* RFC4880 Section 5.5.3 Secret-Key Packet Formats */ - - ops_crypt_t crypt; - ops_hash_t hash; - unsigned char hashed[OPS_SHA1_HASH_SIZE]; - unsigned char session_key[CAST_KEY_LENGTH]; - unsigned int done=0; - unsigned int i=0; - - if(!write_public_key_body(&key->public_key,info)) - return ops_false; - - assert(key->s2k_usage==OPS_S2KU_ENCRYPTED_AND_HASHED); /* = 254 */ - if(!ops_write_scalar(key->s2k_usage,1,info)) - return ops_false; - - assert(key->algorithm==OPS_SA_CAST5); - if (!ops_write_scalar(key->algorithm,1,info)) - return ops_false; - - assert(key->s2k_specifier==OPS_S2KS_SIMPLE - || key->s2k_specifier==OPS_S2KS_SALTED); // = 1 \todo could also be iterated-and-salted - if (!ops_write_scalar(key->s2k_specifier,1,info)) - return ops_false; - - assert(key->hash_algorithm==OPS_HASH_SHA1); - if (!ops_write_scalar(key->hash_algorithm,1,info)) - return ops_false; - - switch(key->s2k_specifier) - { - case OPS_S2KS_SIMPLE: - // nothing more to do - break; - - case OPS_S2KS_SALTED: - // 8-octet salt value - ops_random((void *)&key->salt[0],OPS_SALT_SIZE); - if (!ops_write(key->salt, OPS_SALT_SIZE, info)) - return ops_false; - break; - - /* \todo - case OPS_S2KS_ITERATED_AND_SALTED: - // 8-octet salt value - // 1-octet count - break; - */ - - default: - fprintf(stderr,"invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - assert(0); - } - - if (!ops_write(&key->iv[0],ops_block_size(key->algorithm),info)) - return ops_false; - - /* create the session key for encrypting the algorithm-specific fields */ - - switch(key->s2k_specifier) - { - case OPS_S2KS_SIMPLE: - case OPS_S2KS_SALTED: - // RFC4880: section 3.7.1.1 and 3.7.1.2 - - done=0; - for (i=0; donehash_algorithm); - hash.init(&hash); - - // preload if iterating - for (j=0; js2k_specifier==OPS_S2KS_SALTED) - { hash.add(&hash, key->salt, OPS_SALT_SIZE); } - - hash.add(&hash, passphrase, pplen); - hash.finish(&hash, hashed); - - // if more in hash than is needed by session key, use the - // leftmost octets - memcpy(session_key+(i*SHA_DIGEST_LENGTH), hashed, use); - done += use; - assert(done<=CAST_KEY_LENGTH); - } - - break; - - /* \todo - case OPS_S2KS_ITERATED_AND_SALTED: - // 8-octet salt value - // 1-octet count - break; - */ - - default: - fprintf(stderr,"invalid/unsupported s2k specifier %d\n", - key->s2k_specifier); - assert(0); - } - - /* use this session key to encrypt */ - - ops_crypt_any(&crypt,key->algorithm); - crypt.set_iv(&crypt, key->iv); - crypt.set_key(&crypt, session_key); - ops_encrypt_init(&crypt); - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"\nWRITING:\niv="); - for (i=0; ialgorithm); i++) - { - fprintf(stderr, "%02x ", key->iv[i]); - } - fprintf(stderr,"\n"); - - fprintf(stderr,"key="); - for (i=0; ipublic_key.algorithm) - { - case OPS_PKA_DSA: - return ops_write_mpi(key->key.dsa.x,info); - - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - - if(!ops_write_mpi(key->key.rsa.d,info) - || !ops_write_mpi(key->key.rsa.p,info) - || !ops_write_mpi(key->key.rsa.q,info) - || !ops_write_mpi(key->key.rsa.u,info)) - { - if (debug) - { fprintf(stderr,"4 x mpi not written - problem\n"); } - return ops_false; - } - - break; - - // case OPS_PKA_ELGAMAL: - // return ops_write_mpi(key->key.elgamal.x,info); - - default: - assert(0); - break; - } - - if(!ops_write(key->checkhash, OPS_CHECKHASH_SIZE, info)) - return ops_false; - - ops_writer_pop(info); - - free(crypt.encrypt_key) ; - free(crypt.decrypt_key) ; - - return ops_true; -} - - -/** - \ingroup HighLevel_KeyWrite - - \brief Writes a transferable PGP public key to the given output stream. - - \param keydata Key to be written - \param armoured Flag is set for armoured output - \param info Output stream - - Example code: - \code - void example(const ops_keydata_t* keydata) - { - ops_boolean_t armoured=ops_true; - char* filename="/tmp/testkey.asc"; - - int fd; - ops_boolean_t overwrite=ops_true; - ops_create_info_t* cinfo; - - fd=ops_setup_file_write(&cinfo, filename, overwrite); - ops_write_transferable_public_key(keydata,armoured,cinfo); - ops_teardown_file_write(cinfo,fd); - } - \endcode -*/ - -ops_boolean_t ops_write_transferable_public_key(const ops_keydata_t *keydata, - ops_boolean_t armoured, - ops_create_info_t *info) -{ - ops_boolean_t rtn; - unsigned int i=0,j=0; - - if (armoured) - { ops_writer_push_armoured(info, OPS_PGP_PUBLIC_KEY_BLOCK); } - - // public key - rtn=ops_write_struct_public_key(&keydata->key.skey.public_key,info); - if (rtn!=ops_true) - return rtn; - - // TODO: revocation signatures go here - - // user ids and corresponding signatures - for (i=0; inuids; i++) - { - ops_user_id_t* uid=&keydata->uids[i]; - - rtn=ops_write_struct_user_id(uid, info); - - if (!rtn) - return rtn; - - // find signature for this packet if it exists - for (j=0; jnsigs; j++) - { - sigpacket_t* sig=&keydata->sigs[i]; - if (!strcmp((char *)sig->userid->user_id, (char *)uid->user_id)) - { - rtn=ops_write(sig->packet->raw, sig->packet->length, info); - if (!rtn) - return !rtn; - } - } - } - - // TODO: user attributes and corresponding signatures - - // subkey packets and corresponding signatures and optional revocation - - if (armoured) - { - writer_info_finalise(&info->errors, &info->winfo); - ops_writer_pop(info); - } - - return rtn; -} - -ops_boolean_t ops_write_transferable_public_key_from_packet_data(const ops_keydata_t *keydata, - ops_boolean_t armoured, - ops_create_info_t *info) -{ - ops_boolean_t rtn = ops_true; - unsigned int i=0; - - if (armoured) - { ops_writer_push_armoured(info, OPS_PGP_PUBLIC_KEY_BLOCK); } - - for(i=0;inpackets;++i) - if(!ops_write(keydata->packets[i].raw, keydata->packets[i].length, info)) - return ops_false ; - - if (armoured) - { - writer_info_finalise(&info->errors, &info->winfo); - ops_writer_pop(info); - } - - return rtn; -} - -ops_boolean_t ops_write_transferable_secret_key_from_packet_data(const ops_keydata_t *keydata, - ops_boolean_t armoured, - ops_create_info_t *info) -{ - ops_boolean_t rtn = ops_true; - unsigned int i=0; - - if(keydata->type != OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - { - fprintf(stderr,"Can only output encrypted secret keys from raw packet data. Current type is %d\n",keydata->type) ; - return ops_false ; - } - if (armoured) - { ops_writer_push_armoured(info, OPS_PGP_PRIVATE_KEY_BLOCK); } - - for(i=0;inpackets;++i) - if(!ops_write(keydata->packets[i].raw, keydata->packets[i].length, info)) - return ops_false ; - - if (armoured) - { - writer_info_finalise(&info->errors, &info->winfo); - ops_writer_pop(info); - } - - return rtn; -} -/** - \ingroup HighLevel_KeyWrite - - \brief Writes a transferable PGP secret key to the given output stream. - - \param keydata Key to be written - \param passphrase - \param pplen - \param armoured Flag is set for armoured output - \param info Output stream - - Example code: - \code - void example(const ops_keydata_t* keydata) - { - const unsigned char* passphrase=NULL; - const size_t passphraselen=0; - ops_boolean_t armoured=ops_true; - - int fd; - char* filename="/tmp/testkey.asc"; - ops_boolean_t overwrite=ops_true; - ops_create_info_t* cinfo; - - fd=ops_setup_file_write(&cinfo, filename, overwrite); - ops_write_transferable_secret_key(keydata,passphrase,pplen,armoured,cinfo); - ops_teardown_file_write(cinfo,fd); - } - \endcode -*/ - -ops_boolean_t ops_write_transferable_secret_key(const ops_keydata_t *keydata, const unsigned char* passphrase, const size_t pplen, ops_boolean_t armoured, ops_create_info_t *info) - { - ops_boolean_t rtn; - unsigned int i=0,j=0; - - if (armoured) - { ops_writer_push_armoured(info,OPS_PGP_PRIVATE_KEY_BLOCK); } - - // public key - rtn=ops_write_struct_secret_key(&keydata->key.skey,passphrase,pplen,info); - if (rtn!=ops_true) - return rtn; - - // TODO: revocation signatures go here - - // user ids and corresponding signatures - for (i=0; inuids; i++) - { - ops_user_id_t* uid=&keydata->uids[i]; - - rtn=ops_write_struct_user_id(uid, info); - - if (!rtn) - return rtn; - - // find signature for this packet if it exists - for (j=0; jnsigs; j++) - { - sigpacket_t* sig=&keydata->sigs[i]; - if (!strcmp((char *)sig->userid->user_id, (char *)uid->user_id)) - { - rtn=ops_write(sig->packet->raw, sig->packet->length, info); - if (!rtn) - return !rtn; - } - } - } - - // TODO: user attributes and corresponding signatures - - // subkey packets and corresponding signatures and optional revocation - - if (armoured) - { - writer_info_finalise(&info->errors, &info->winfo); - ops_writer_pop(info); - } - - return rtn; - } - -/** - * \ingroup Core_WritePackets - * \brief Writes a Public Key packet - * \param key - * \param info - * \return ops_true if OK, otherwise ops_false - */ -ops_boolean_t ops_write_struct_public_key(const ops_public_key_t *key, - ops_create_info_t *info) -{ - assert(key->version == 4); - - if(key->algorithm != OPS_PKA_RSA) - { - fprintf(stderr,"\nUnhandled key algorithm %d\n",key->algorithm); - return ops_false ; - } - - return ops_write_ptag(OPS_PTAG_CT_PUBLIC_KEY,info) - && ops_write_length(1+4+1+public_key_length(key),info) - && write_public_key_body(key,info); -} - -/** - * \ingroup Core_WritePackets - * \brief Writes one RSA public key packet. - * \param time Creation time - * \param n RSA public modulus - * \param e RSA public encryption exponent - * \param info Writer settings - * - * \return ops_true if OK, otherwise ops_false - */ - -ops_boolean_t ops_write_rsa_public_key(time_t time,const BIGNUM *n, - const BIGNUM *e, - ops_create_info_t *info) - { - ops_public_key_t key; - - ops_fast_create_rsa_public_key(&key,time,DECONST(BIGNUM,n), - DECONST(BIGNUM,e)); - return ops_write_struct_public_key(&key,info); - } - -/** - * \ingroup Core_Create - * \param out - * \param key - * \param make_packet - */ - -void ops_build_public_key(ops_memory_t *out,const ops_public_key_t *key, - ops_boolean_t make_packet) - { - ops_create_info_t *info; - - info=ops_create_info_new(); - - ops_memory_init(out,128); - ops_writer_set_memory(info,out); - - write_public_key_body(key,info); - - if(make_packet) - ops_memory_make_packet(out,OPS_PTAG_CT_PUBLIC_KEY); - - ops_create_info_delete(info); - } - -/** - * \ingroup Core_Create - * - * Create an RSA secret key structure. If a parameter is marked as - * [OPTIONAL], then it can be omitted and will be calculated from - * other parameters - or, in the case of e, will default to 0x10001. - * - * Parameters are _not_ copied, so will be freed if the structure is - * freed. - * - * \param key The key structure to be initialised. - * \param time - * \param d The RSA parameter d (=e^-1 mod (p-1)(q-1)) [OPTIONAL] - * \param p The RSA parameter p - * \param q The RSA parameter q (q > p) - * \param u The RSA parameter u (=p^-1 mod q) [OPTIONAL] - * \param n The RSA public parameter n (=p*q) [OPTIONAL] - * \param e The RSA public parameter e */ - -void ops_fast_create_rsa_secret_key(ops_secret_key_t *key,time_t time, - BIGNUM *d,BIGNUM *p,BIGNUM *q,BIGNUM *u, - BIGNUM *n,BIGNUM *e) - { - ops_fast_create_rsa_public_key(&key->public_key,time,n,e); - - // XXX: calculate optionals - key->key.rsa.d=d; - key->key.rsa.p=p; - key->key.rsa.q=q; - key->key.rsa.u=u; - - key->s2k_usage=OPS_S2KU_NONE; - - // XXX: sanity check and add errors... - } - -/** - * \ingroup Core_WritePackets - * \brief Writes a Secret Key packet. - * \param key The secret key - * \param passphrase The passphrase - * \param pplen Length of passphrase - * \param info - * \return ops_true if OK; else ops_false - */ -ops_boolean_t ops_write_struct_secret_key(const ops_secret_key_t *key, - const unsigned char* passphrase, - const size_t pplen, - ops_create_info_t *info) - { - int length=0; - - assert(key->public_key.version == 4); - - // Ref: RFC4880 Section 5.5.3 - - // public_key, excluding MPIs - length += 1+4+1+1; - - // s2k usage - length+=1; - - switch (key->s2k_usage) - { - case OPS_S2KU_NONE: - // nothing to add - break; - - case OPS_S2KU_ENCRYPTED_AND_HASHED: // 254 - case OPS_S2KU_ENCRYPTED: // 255 - - // Ref: RFC4880 Section 3.7 - length+=1; // s2k_specifier - - switch(key->s2k_specifier) - { - case OPS_S2KS_SIMPLE: - length+=1; // hash algorithm - break; - - case OPS_S2KS_SALTED: - length+=1+8; // hash algorithm + salt - break; - - case OPS_S2KS_ITERATED_AND_SALTED: - length+=1+8+1; // hash algorithm, salt + count - break; - - default: - assert(0); - } - break; - - default: - assert(0); - } - - // IV - if (key->s2k_usage != 0) - { - length += ops_block_size(key->algorithm); - } - - // checksum or hash - switch (key->s2k_usage) - { - case 0: - case 255: - length += 2; - break; - - case 254: - length += 20; - break; - - default: - assert(0); - } - - // secret key and public key MPIs - length += secret_key_length(key); - - return ops_write_ptag(OPS_PTAG_CT_SECRET_KEY,info) - // && ops_write_length(1+4+1+1+secret_key_length(key)+2,info) - && ops_write_length(length,info) - && write_secret_key_body(key,passphrase,pplen,info); - } - -/** - * \ingroup InternalAPI - * - * \brief Initialise a temporary info structure that can be used for - * writing to a writer's parent. - * - * This is used by writers who want to use the various ops_write functions - * in order to write to the parent writer. - * Example code: - * \code - * ops_boolean_t writer(const unsigned char *src, - * unsigned length, - * ops_error_t **errors, - * ops_writer_info_t *winfo) { - * ops_create_info_t parent; - * ops_prepare_parent_info(&parent, winfo, errors); - * - * // The ptag will be written to the parent writer - * ops_write_ptag(OPS_PTAG_CT_LITERAL_DATA, &parent); - * - * // The data is written to the parent. This line is - // equivalent to: - * // ops_stacked_write(src, length, errors, winfo); - * ops_boolean_t result = ops_write(src, length, info); - * ops_move_errors(&parent_info, errors); - * return result; - * \endcode - * - * \note It is the responsiblity of the caller to assign space for the parent - * structure, typically on the stack. IOn order to report errors correctly, - * use ops_move_errors() after the write operation. - * - * \see ops_move_errors - */ -void ops_prepare_parent_info(ops_create_info_t *parent_info, - ops_writer_info_t *winfo) - { - parent_info->winfo = *winfo->next; - parent_info->errors = NULL; - } - -/** - * \ingroup Core_Create - * - * \brief Create a new ops_create_info_t structure. - * - * \return the new structure. - * \note It is the responsiblity of the caller to call ops_create_info_delete(). - * \sa ops_create_info_delete() - */ -ops_create_info_t *ops_create_info_new(void) - { return ops_mallocz(sizeof(ops_create_info_t)); } - -/** - * \ingroup Core_Create - * \brief Delete an ops_create_info_t strucut and associated resources. - * - * Delete an ops_create_info_t structure. If a writer is active, then - * that is also deleted. - * - * \param info the structure to be deleted. - */ -void ops_create_info_delete(ops_create_info_t *info) - { - writer_info_delete(&info->winfo); - free(info); - } - -/** - \ingroup Core_Create - \brief Calculate the checksum for a session key - \param session_key Session Key to use - \param cs Checksum to be written - \return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_calc_session_key_checksum(ops_pk_session_key_t *session_key, - unsigned char cs[2]) - { - unsigned int i=0; - unsigned long checksum=0; - - if (!ops_is_sa_supported(session_key->symmetric_algorithm)) - return ops_false; - - for (i=0; isymmetric_algorithm); i++) - { - checksum+=session_key->key[i]; - } - checksum = checksum % 65536; - - cs[0]=checksum >> 8; - cs[1]=checksum & 0xFF; - - return ops_true; - // fprintf(stderr,"\nm buf checksum: "); - // fprintf(stderr," %2x",cs[0]); - // fprintf(stderr," %2x\n",cs[1]); - } - -static ops_boolean_t create_unencoded_m_buf(ops_pk_session_key_t *session_key, - unsigned char *m_buf) - { - int i=0; - // unsigned long checksum=0; - - // m_buf is the buffer which will be encoded in PKCS#1 block - // encoding to form the "m" value used in the - // Public Key Encrypted Session Key Packet - // as defined in RFC Section 5.1 "Public-Key Encrypted Session Key Packet" - - m_buf[0]=session_key->symmetric_algorithm; - - assert(session_key->symmetric_algorithm == OPS_SA_CAST5); - for (i=0; ikey[i]; - } - - return(ops_calc_session_key_checksum(session_key, m_buf+1+CAST_KEY_LENGTH)); - } - -/** -\ingroup Core_Create -\brief implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC -\param M -\param mLen -\param pkey -\param EM -\return ops_true if OK; else ops_false -*/ -ops_boolean_t encode_m_buf(const unsigned char *M, size_t mLen, - const ops_public_key_t *pkey, - unsigned char* EM -) - { - unsigned int k; - unsigned i; - - // implementation of EME-PKCS1-v1_5-ENCODE, as defined in OpenPGP RFC - - if(pkey->algorithm != OPS_PKA_RSA) - { - fprintf(stderr,"\nUnhandled key algorithm %d\n",pkey->algorithm); - return ops_false ; - } - - k=BN_num_bytes(pkey->key.rsa.n); - assert(mLen <= k-11); - if (mLen > k-11) - { - fprintf(stderr,"message too long\n"); - return ops_false; - } - - // these two bytes defined by RFC - EM[0]=0x00; - EM[1]=0x02; - - // add non-zero random bytes of length k - mLen -3 - for(i=2 ; i < k-mLen-1 ; ++i) - do - ops_random(EM+i, 1); - while(EM[i] == 0); - - assert (i >= 8+2); - - EM[i++]=0; - - memcpy(EM+i, M, mLen); - - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"Encoded Message: \n"); - for (i=0; ikey.rsa.n); - unsigned char* encoded_m_buf = ops_mallocz(sz_encoded_m_buf); - - ops_pk_session_key_t *session_key=ops_mallocz(sizeof *session_key); - - assert(key->type == OPS_PTAG_CT_PUBLIC_KEY); - session_key->version=OPS_PKSK_V3; - memcpy(session_key->key_id, key->key_id, sizeof session_key->key_id); - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"Encrypting for RSA key id : "); - for (i=0; ikey_id; i++) - fprintf(stderr,"%2x ", key->key_id[i]); - fprintf(stderr,"\n"); - } - - assert(key->key.pkey.algorithm == OPS_PKA_RSA); - session_key->algorithm=key->key.pkey.algorithm; - - // \todo allow user to specify other algorithm - session_key->symmetric_algorithm=OPS_SA_CAST5; - ops_random(session_key->key, CAST_KEY_LENGTH); - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"CAST5 session key created (len=%d):\n ", - CAST_KEY_LENGTH); - for (i=0; ikey[i]); - fprintf(stderr,"\n"); - } - - if (create_unencoded_m_buf(session_key, &unencoded_m_buf[0])==ops_false) - { - free(encoded_m_buf); - return NULL; - } - - if (debug) - { - unsigned int i=0; - printf("unencoded m buf:\n"); - for (i=0; iparameters)) - { - free (encoded_m_buf); - return NULL; - } - - free(encoded_m_buf); - return session_key; - } - -/** -\ingroup Core_WritePackets -\brief Writes Public Key Session Key packet -\param info Write settings -\param pksk Public Key Session Key to write out -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_write_pk_session_key(ops_create_info_t *info, - ops_pk_session_key_t *pksk) - { - assert(pksk); - assert(pksk->algorithm == OPS_PKA_RSA); - - return ops_write_ptag(OPS_PTAG_CT_PK_SESSION_KEY, info) - && ops_write_length(1 + 8 + 1 - + BN_num_bytes(pksk->parameters.rsa.encrypted_m) - + 2, info) - && ops_write_scalar(pksk->version, 1, info) - && ops_write(pksk->key_id, 8, info) - && ops_write_scalar(pksk->algorithm, 1, info) - && ops_write_mpi(pksk->parameters.rsa.encrypted_m, info) - //?? && ops_write_scalar(0, 2, info); - ; - } - -/** -\ingroup Core_WritePackets -\brief Writes MDC packet -\param hashed Hash for MDC -\param info Write settings -\return ops_true if OK; else ops_false -*/ - -ops_boolean_t ops_write_mdc(const unsigned char *hashed, - ops_create_info_t* info) - { - // write it out - return ops_write_ptag(OPS_PTAG_CT_MDC, info) - && ops_write_length(OPS_SHA1_HASH_SIZE,info) - && ops_write(hashed, OPS_SHA1_HASH_SIZE, info); - } - -/** -\ingroup Core_WritePackets -\brief Writes Literal Data packet from buffer -\param data Buffer to write out -\param maxlen Max length of buffer -\param type Literal Data Type -\param info Write settings -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_write_literal_data_from_buf(const unsigned char *data, - const int maxlen, - const ops_literal_data_type_t type, - ops_create_info_t *info) - { - /* - * RFC4880 does not specify a meaning for filename or date. - * It is implementation-dependent. - * We will not implement them. - */ - // \todo do we need to check text data for line endings ? - return ops_write_ptag(OPS_PTAG_CT_LITERAL_DATA, info) - && ops_write_length(1+1+4+maxlen,info) - && ops_write_scalar(type, 1, info) - && ops_write_scalar(0, 1, info) - && ops_write_scalar(0, 4, info) - && ops_write(data, maxlen, info); - } - -/** -\ingroup Core_WritePackets -\brief Writes Literal Data packet from contents of file -\param filename Name of file to read from -\param type Literal Data Type -\param info Write settings -\return ops_true if OK; else ops_false -*/ - -ops_boolean_t -ops_write_literal_data_from_file(const char *filename, - const ops_literal_data_type_t type, - ops_create_info_t *info) - { - size_t initial_size=1024; - int fd=0; - ops_boolean_t rtn; - unsigned char buf[1024]; - ops_memory_t* mem=NULL; - size_t len=0; - - fd=ops_open(filename,O_RDONLY | O_BINARY, 0); - - if (fd < 0) - return ops_false; - - mem=ops_memory_new(); - ops_memory_init(mem,initial_size); - for (;;) - { - ssize_t n=0; - n=read(fd,buf,1024); - if (!n) - break; - if (n == -1) - { - close(fd); - ops_memory_free(mem); - return ops_false; - } - ops_memory_add(mem, &buf[0], n); - } - close(fd); - - // \todo do we need to check text data for line endings ? - len=ops_memory_get_length(mem); - rtn=ops_write_ptag(OPS_PTAG_CT_LITERAL_DATA, info) - && ops_write_length(1+1+4+len,info) - && ops_write_scalar(type, 1, info) - && ops_write_scalar(0, 1, info) // filename - && ops_write_scalar(0, 4, info) // date - && ops_write(ops_memory_get_data(mem), len, info); - - ops_memory_free(mem); - return rtn; - } - -/** - \ingroup HighLevel_General - - \brief Reads contents of file into new ops_memory_t struct. - - \param filename Filename to read from - \param errnum Pointer to error - \return new ops_memory_t pointer containing the contents of the file - - \note If there was an error opening the file or reading from it, - errnum is set to the cause - - \note It is the caller's responsibility to call ops_memory_free(mem) -*/ - -ops_memory_t* ops_write_mem_from_file(const char *filename, int* errnum) - { - size_t initial_size=1024; - int fd=0; - unsigned char buf[1024]; - ops_memory_t* mem=NULL; - - *errnum=0; - - fd=ops_open(filename,O_RDONLY | O_BINARY, 0); - - if (fd < 0) - { - *errnum=errno; - return ops_false; - } - - mem=ops_memory_new(); - ops_memory_init(mem,initial_size); - for (;;) - { - ssize_t n=0; - n=read(fd,buf,1024); - if (n<0) - { - *errnum=errno; - break; - } - if (!n) - break; - ops_memory_add(mem, &buf[0], n); - } - close(fd); - return mem; - } - -/** - \ingroup HighLevel_General - - \brief Reads contents of buffer into file - - \param filename Filename to write to - \param buf Buffer to write to file - \param len Size of buffer - \param overwrite Flag to set whether to overwrite an existing file - \return 1 if OK; 0 if error -*/ - -int ops_write_file_from_buf(const char *filename, const char* buf, - const size_t len, const ops_boolean_t overwrite) - { - int fd=0; - size_t n=0; - int flags=0; - - flags=O_WRONLY | O_CREAT; - if (overwrite==ops_true) - flags |= O_TRUNC; - else - flags |= O_EXCL; - - flags |= O_BINARY; - - fd=ops_open(filename,flags, 0600); - if (fd < 0) - { - perror(NULL); - return 0; - } - - n=write(fd,buf,len); - if (n!=len) - return 0; - - if(!close(fd)) - return 1; - - return 0; - } - -/** -\ingroup Core_WritePackets -\brief Write Symmetrically Encrypted packet -\param data Data to encrypt -\param len Length of data -\param info Write settings -\return ops_true if OK; else ops_false -\note Hard-coded to use AES256 -*/ -ops_boolean_t ops_write_symmetrically_encrypted_data(const unsigned char *data, - const int len, - ops_create_info_t *info) - { - int done=0; - ops_crypt_t crypt_info; - int encrypted_sz=0;// size of encrypted data - unsigned char *encrypted=NULL; // buffer to write encrypted data to - - // \todo assume AES256 for now - ops_crypt_any(&crypt_info, OPS_SA_AES_256); - ops_encrypt_init(&crypt_info); - - encrypted_sz=len+crypt_info.blocksize+2; - encrypted=ops_mallocz(encrypted_sz); - - done=ops_encrypt_se(&crypt_info, encrypted, data, len); - assert(done==len); - // printf("len=%d, done: %d\n", len, done); - - return ops_write_ptag(OPS_PTAG_CT_SE_DATA, info) - && ops_write_length(1+encrypted_sz,info) - && ops_write(data, len, info); - } - -/** -\ingroup Core_WritePackets -\brief Write a One Pass Signature packet -\param skey Secret Key to use -\param hash_alg Hash Algorithm to use -\param sig_type Signature type -\param info Write settings -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_write_one_pass_sig(const ops_secret_key_t* skey, - const ops_hash_algorithm_t hash_alg, - const ops_sig_type_t sig_type, - ops_create_info_t* info) - { - unsigned char keyid[OPS_KEY_ID_SIZE]; - if (debug) - fprintf(stderr, "calling ops_keyid in write_one_pass_sig: " - "this calls sha1_init\n"); - ops_keyid(keyid,&skey->public_key); - - return ops_write_ptag(OPS_PTAG_CT_ONE_PASS_SIGNATURE, info) - && ops_write_length(1+1+1+1+8+1, info) - && ops_write_scalar (3, 1, info) // version - && ops_write_scalar (sig_type, 1, info) - && ops_write_scalar (hash_alg, 1, info) - && ops_write_scalar (skey->public_key.algorithm, 1, info) - && ops_write(keyid, 8, info) - && ops_write_scalar (1, 1, info); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/create.h b/openpgpsdk/src/openpgpsdk/create.h deleted file mode 100644 index aaeec0d51..000000000 --- a/openpgpsdk/src/openpgpsdk/create.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_CREATE_H -#define OPS_CREATE_H - -#include -#include -#include -#include -#include -#include -#include - -/** - * \ingroup Create - * This struct contains the required information about how to write this stream - */ -struct ops_create_info - { - ops_writer_info_t winfo; - ops_error_t *errors; /*!< an error stack */ - }; - -void ops_prepare_parent_info(ops_create_info_t *parent_info, - ops_writer_info_t *winfo); -ops_create_info_t *ops_create_info_new(void); -void ops_create_info_delete(ops_create_info_t *info); - -ops_memory_t* ops_write_mem_from_file(const char *filename, int* errnum); -int ops_write_file_from_buf(const char *filename, const char* buf, const size_t len, const ops_boolean_t overwrite); - -ops_boolean_t ops_calc_session_key_checksum(ops_pk_session_key_t *session_key, unsigned char *cs); -void ops_build_public_key(ops_memory_t *out,const ops_public_key_t *key, - ops_boolean_t make_packet); -ops_boolean_t ops_write_struct_user_id(ops_user_id_t *id, - ops_create_info_t *info); -ops_boolean_t ops_write_struct_public_key(const ops_public_key_t *key, - ops_create_info_t *info); - -ops_boolean_t ops_write_ss_header(unsigned length,ops_content_tag_t type, - ops_create_info_t *info); -ops_boolean_t ops_write_struct_secret_key(const ops_secret_key_t *key, - const unsigned char* passphrase, - const size_t pplen, - ops_create_info_t *info); -ops_boolean_t ops_write_one_pass_sig(const ops_secret_key_t* skey, - const ops_hash_algorithm_t hash_alg, - const ops_sig_type_t sig_type, - ops_create_info_t* info); -ops_boolean_t ops_write_literal_data_from_buf(const unsigned char *data, - const int maxlen, - const ops_literal_data_type_t type, - ops_create_info_t *info); -ops_pk_session_key_t *ops_create_pk_session_key(const ops_keydata_t *key); -ops_boolean_t ops_write_pk_session_key(ops_create_info_t *info, - ops_pk_session_key_t *pksk); -ops_boolean_t ops_write_transferable_public_key(const ops_keydata_t *key, ops_boolean_t armoured, ops_create_info_t *info); -ops_boolean_t ops_write_transferable_secret_key(const ops_keydata_t *key, const unsigned char* passphrase, const size_t pplen, ops_boolean_t armoured, ops_create_info_t *info); -ops_boolean_t ops_write_transferable_public_key_from_packet_data(const ops_keydata_t *keydata, ops_boolean_t armoured, ops_create_info_t *info); -ops_boolean_t ops_write_transferable_secret_key_from_packet_data(const ops_keydata_t *keydata, ops_boolean_t armoured, ops_create_info_t *info); - - -#endif /*OPS_CREATE_H*/ - -// eof diff --git a/openpgpsdk/src/openpgpsdk/crypto.c b/openpgpsdk/src/openpgpsdk/crypto.c deleted file mode 100644 index 86acebaca..000000000 --- a/openpgpsdk/src/openpgpsdk/crypto.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "parse_local.h" - -#include -#include -#include - -#include -#include - -/** -\ingroup Core_MPI -\brief Decrypt and unencode MPI -\param buf Buffer in which to write decrypted unencoded MPI -\param buflen Length of buffer -\param encmpi -\param skey -\return length of MPI -\note only RSA at present -*/ -int ops_decrypt_and_unencode_mpi(unsigned char *buf, unsigned buflen, - const BIGNUM *encmpi, - const ops_secret_key_t *skey) - { - unsigned char encmpibuf[8192]; - unsigned char mpibuf[8192]; - unsigned mpisize; - int n; - int i; - - mpisize=BN_num_bytes(encmpi); - /* MPI can't be more than 65,536 */ - - if(!(mpisize <= sizeof encmpibuf)) // ASSERT(mpisize <= sizeof encmpibuf); - { - fprintf(stderr,"ops_decrypt_and_unencode_mpi: number size too large (%d bytes!).\n",mpisize) ; - return -1 ; - } - - BN_bn2bin(encmpi, encmpibuf); - - if(!(skey->public_key.algorithm == OPS_PKA_RSA)) // ASSERT(skey->public_key.algorithm == OPS_PKA_RSA); - { - fprintf(stderr,"ops_decrypt_and_unencode_mpi: encryption algorithm %02x is not supported. Sorry.\n",skey->public_key.algorithm) ; - return -1 ; - } - - /* - fprintf(stderr,"\nDECRYPTING\n"); - fprintf(stderr,"encrypted data : "); - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", encmpibuf[i]); - fprintf(stderr,"\n"); - */ - - n=ops_rsa_private_decrypt(mpibuf, encmpibuf, (BN_num_bits(encmpi)+7)/8, - &skey->key.rsa, &skey->public_key.key.rsa); - -// if(n == -1) // assert(n != -1); -// return ops_false ; - - /* - fprintf(stderr,"decrypted encoded m buf : "); - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", mpibuf[i]); - fprintf(stderr,"\n"); - */ - - if(n <= 0) - return -1; - - /* - printf(" decrypted=%d ",n); - hexdump(mpibuf,n); - printf("\n"); - */ - - // Decode EME-PKCS1_V1_5 (RFC 2437). - - if(mpibuf[0] != 0 || mpibuf[1] != 2) - return ops_false; - - // Skip the random bytes. - for(i=2 ; i < n && mpibuf[i] ; ++i) - ; - - if(i == n || i < 10) - return ops_false; - - // Skip the zero - ++i; - - // this is the unencoded m buf - if((unsigned)(n-i) <= buflen) - memcpy(buf, mpibuf+i, n-i); - - /* - printf("decoded m buf:\n"); - int j; - for (j=0; jkey.rsa.n))) // ASSERT(sz_encoded_m_buf==(size_t) BN_num_bytes(pkey->key.rsa.n)); - return ops_false ; - - unsigned char encmpibuf[8192]; - int n=0; - - n=ops_rsa_public_encrypt(encmpibuf, encoded_m_buf, sz_encoded_m_buf, &pkey->key.rsa); - - //if(!(n!=-1)) // ASSERT(n!=-1); - // return ops_false ; - - if(n <= 0) - return ops_false; - - skp->rsa.encrypted_m=BN_bin2bn(encmpibuf, n, NULL); - - /* - fprintf(stderr,"encrypted mpi buf : "); - int i; - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", encmpibuf[i]); - fprintf(stderr,"\n"); - */ - - return ops_true; -} - -#define MAXBUF 1024 - -static ops_parse_cb_return_t -callback_write_parsed(const ops_parser_content_t *content_, - ops_parse_cb_info_t *cbinfo); - -/** -\ingroup HighLevel_Crypto -Encrypt a file -\param input_filename Name of file to be encrypted -\param output_filename Name of file to write to. If NULL, name is constructed from input_filename -\param pub_key Public Key to encrypt file for -\param use_armour Write armoured text, if set -\param allow_overwrite Allow output file to be overwrwritten if it exists -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_encrypt_file(const char* input_filename, - const char* output_filename, - const ops_keydata_t *pub_key, - const ops_boolean_t use_armour, - const ops_boolean_t allow_overwrite) - { - int fd_in=0; - int fd_out=0; - - ops_create_info_t *cinfo; -#ifdef WIN32 - fd_in=ops_open(input_filename, O_RDONLY | O_BINARY, 0); -#else - fd_in=ops_open(input_filename, O_RDONLY, 0); -#endif - if(fd_in < 0) - { - perror(input_filename); - return ops_false; - } - - fd_out=ops_setup_file_write(&cinfo, output_filename, allow_overwrite); - if (fd_out < 0) - return ops_false; - - // set armoured/not armoured here - if (use_armour) - ops_writer_push_armoured_message(cinfo); - - // Push the encrypted writer - ops_writer_push_stream_encrypt_se_ip(cinfo, pub_key); - ops_writer_push_literal(cinfo); - - // Do the writing - - unsigned buffer[10240]; - for (;;) - { - int n=0; - - n=read(fd_in, buffer, sizeof buffer); - if (!n) - break; - - if(n < 0) - return ops_false ; - - // FIXME: apparently writing can't fail. - ops_write(buffer, n, cinfo); - } - - - // tidy up - close(fd_in); - ops_teardown_file_write(cinfo, fd_out); - - return ops_true; - } - -/** - \ingroup HighLevel_Crypto - Encrypt a compressed, signed stream. - \param cinfo the structure describing where the output will be written. - \param public_key the key used to encrypt the data - \param secret_key the key used to sign the data. If NULL, the data - will not be signed - \param compress If true, compress the stream before encrypting - \param use_armour Write armoured text, if set - \see ops_setup_file_write - - Example Code: - \code - const char* filename = "armour_nocompress_sign.asc"; - ops_create_info_t *info; - int fd = ops_setup_file_write(&info, filename, ops_true); - if (fd < 0) { - fprintf(stderr, "Cannot write to %s\n", filename); - return -1; - } - ops_encrypt_stream(info, public_key, secret_key, ops_false, ops_true); - ops_write(cleartext, strlen(cleartext), info); - ops_writer_close(info); - ops_create_info_delete(info); - \endcode -*/ -extern ops_boolean_t ops_encrypt_stream(ops_create_info_t* cinfo, - const ops_keydata_t* public_key, - const ops_secret_key_t* secret_key, - const ops_boolean_t compress, - const ops_boolean_t use_armour) -{ - if (use_armour) - ops_writer_push_armoured_message(cinfo); - - ops_writer_push_stream_encrypt_se_ip(cinfo, public_key); - - if(compress) - if(!ops_writer_push_compressed(cinfo)) - return ops_false ; - - if (secret_key != NULL) - ops_writer_push_signed(cinfo, OPS_SIG_BINARY, secret_key); - else - ops_writer_push_literal(cinfo); - - return ops_true ; -} - -/** - \ingroup HighLevel_Crypto - \brief Decrypt a chunk of memory, containing a encrypted stream. - \param input_filename Name of file to be decrypted - \param output_filename Name of file to write to. If NULL, the filename is constructed from the input filename, following GPG conventions. - \param keyring Keyring to use - \param use_armour Expect armoured text, if set - \param allow_overwrite Allow output file to overwritten, if set. - \param cb_get_passphrase Callback to use to get passphrase -*/ - -ops_boolean_t ops_decrypt_memory(const unsigned char *encrypted_memory,int em_length, - unsigned char **decrypted_memory,int *out_length, - ops_keyring_t* keyring, - const ops_boolean_t use_armour, - ops_parse_cb_t* cb_get_passphrase) -{ - ops_parse_info_t *pinfo=NULL; - - // setup for reading from given input file - - ops_memory_t *input_mem = ops_memory_new() ; - ops_memory_add(input_mem,encrypted_memory,em_length) ; - - ops_setup_memory_read(&pinfo, input_mem, NULL, callback_write_parsed, ops_false); - - if (pinfo == NULL) - { - perror("cannot create memory read"); - return ops_false; - } - - // setup memory chunk - - ops_memory_t *output_mem; - - ops_setup_memory_write(&pinfo->cbinfo.cinfo, &output_mem,0) ; - - if (output_mem == NULL) - { - perror("Cannot create output memory"); - ops_teardown_memory_read(pinfo, input_mem); - return ops_false; - } - - // \todo check for suffix matching armour param - - // setup keyring and passphrase callback - pinfo->cbinfo.cryptinfo.keyring=keyring; - pinfo->cbinfo.cryptinfo.cb_get_passphrase=cb_get_passphrase; - - // Set up armour/passphrase options - - if (use_armour) - ops_reader_push_dearmour(pinfo); - - // Do it - - ops_boolean_t res = ops_parse_and_print_errors(pinfo); - - // Unsetup - - if (use_armour) - ops_reader_pop_dearmour(pinfo); - - // copy output memory to supplied buffer. - // - *out_length = ops_memory_get_length(output_mem) ; - *decrypted_memory = ops_mallocz(*out_length) ; - memcpy(*decrypted_memory,ops_memory_get_data(output_mem),*out_length) ; - - ops_teardown_memory_write(pinfo->cbinfo.cinfo, output_mem); - ops_teardown_memory_read(pinfo, input_mem); - - return res ; -} - -/** - \ingroup HighLevel_Crypto - \brief Decrypt a file. - \param input_filename Name of file to be decrypted - \param output_filename Name of file to write to. If NULL, the filename is constructed from the input filename, following GPG conventions. - \param keyring Keyring to use - \param use_armour Expect armoured text, if set - \param allow_overwrite Allow output file to overwritten, if set. - \param cb_get_passphrase Callback to use to get passphrase -*/ - -ops_boolean_t ops_decrypt_file(const char* input_filename, - const char* output_filename, - ops_keyring_t* keyring, - const ops_boolean_t use_armour, - const ops_boolean_t allow_overwrite, - ops_parse_cb_t* cb_get_passphrase) -{ - int fd_in=0; - int fd_out=0; - char* myfilename=NULL; - - // - ops_parse_info_t *pinfo=NULL; - - // setup for reading from given input file - fd_in=ops_setup_file_read(&pinfo, input_filename, - NULL, - callback_write_parsed, - ops_false); - if (fd_in < 0) - { - perror(input_filename); - return ops_false; - } - - // setup output filename - - if (output_filename) - { - fd_out=ops_setup_file_write(&pinfo->cbinfo.cinfo, output_filename, - allow_overwrite); - - if (fd_out < 0) - { - perror(output_filename); - ops_teardown_file_read(pinfo, fd_in); - return ops_false; - } - } - else - { - int suffixlen=4; - char *defaultsuffix=".decrypted"; - const char *suffix=input_filename+strlen(input_filename)-suffixlen; - if (!strcmp(suffix, ".gpg") || !strcmp(suffix, ".asc")) - { - myfilename=ops_mallocz(strlen(input_filename)-suffixlen+1); - strncpy(myfilename, input_filename, - strlen(input_filename)-suffixlen); - } - else - { - unsigned filenamelen=strlen(input_filename)+strlen(defaultsuffix)+1; - myfilename=ops_mallocz(filenamelen); - snprintf(myfilename, filenamelen, "%s%s", input_filename, - defaultsuffix); - } - - fd_out=ops_setup_file_write(&pinfo->cbinfo.cinfo, myfilename, - allow_overwrite); - - if (fd_out < 0) - { - perror(myfilename); - free(myfilename); - ops_teardown_file_read(pinfo, fd_in); - return ops_false; - } - - free (myfilename); - } - - // \todo check for suffix matching armour param - - // setup for writing decrypted contents to given output file - - // setup keyring and passphrase callback - pinfo->cbinfo.cryptinfo.keyring=keyring; - pinfo->cbinfo.cryptinfo.cb_get_passphrase=cb_get_passphrase; - - // Set up armour/passphrase options - - if (use_armour) - ops_reader_push_dearmour(pinfo); - - // Do it - - ops_boolean_t res = ops_parse_and_print_errors(pinfo); - - // Unsetup - - if (use_armour) - ops_reader_pop_dearmour(pinfo); - - ops_teardown_file_write(pinfo->cbinfo.cinfo, fd_out); - ops_teardown_file_read(pinfo, fd_in); - // \todo cleardown crypt - - return res; -} -static ops_parse_cb_return_t -callback_write_parsed(const ops_parser_content_t *content_, - ops_parse_cb_info_t *cbinfo) -{ - ops_parser_content_union_t* content - =(ops_parser_content_union_t *)&content_->content; - static ops_boolean_t skipping; - // ops_boolean_t write=ops_true; - - OPS_USED(cbinfo); - - // ops_print_packet(content_); - - if(content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT && skipping) - { - puts("...end of skip"); - skipping=ops_false; - } - - switch(content_->tag) - { - case OPS_PTAG_CT_UNARMOURED_TEXT: - printf("OPS_PTAG_CT_UNARMOURED_TEXT\n"); - if(!skipping) - { - puts("Skipping..."); - skipping=ops_true; - } - fwrite(content->unarmoured_text.data, 1, - content->unarmoured_text.length, stdout); - break; - - case OPS_PTAG_CT_PK_SESSION_KEY: - return callback_pk_session_key(content_, cbinfo); - break; - - case OPS_PARSER_CMD_GET_SECRET_KEY: - return callback_cmd_get_secret_key(content_, cbinfo); - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: - // return callback_cmd_get_secret_key_passphrase(content_,cbinfo); - return cbinfo->cryptinfo.cb_get_passphrase(content_, cbinfo); - break; - - case OPS_PTAG_CT_LITERAL_DATA_BODY: - return callback_literal_data(content_, cbinfo); - break; - - case OPS_PTAG_CT_ARMOUR_HEADER: - case OPS_PTAG_CT_ARMOUR_TRAILER: - case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - case OPS_PTAG_CT_COMPRESSED: - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - case OPS_PTAG_CT_SE_IP_DATA_BODY: - case OPS_PTAG_CT_SE_IP_DATA_HEADER: - case OPS_PTAG_CT_SE_DATA_BODY: - case OPS_PTAG_CT_SE_DATA_HEADER: - - // Ignore these packets - // They're handled in ops_parse_one_packet() - // and nothing else needs to be done - break; - - default: - // return callback_general(content_,cbinfo); - break; - // fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag, - // content_->tag); - } - - return OPS_RELEASE_MEMORY; -} - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/crypto.h b/openpgpsdk/src/openpgpsdk/crypto.h deleted file mode 100644 index 25bffa073..000000000 --- a/openpgpsdk/src/openpgpsdk/crypto.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_CRYPTO_H -#define OPS_CRYPTO_H - -#include "keyring.h" -#include "util.h" -#include "packet.h" -#include "packet-parse.h" -#include -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x00908030L -# define OPENSSL_NO_CAMELLIA -#endif - -#define OPS_MIN_HASH_SIZE 16 - -typedef void ops_hash_init_t(ops_hash_t *hash); -typedef void ops_hash_add_t(ops_hash_t *hash,const unsigned char *data, - unsigned length); -typedef unsigned ops_hash_finish_t(ops_hash_t *hash,unsigned char *out); - -/** _ops_hash_t */ -struct _ops_hash_t - { - ops_hash_algorithm_t algorithm; - size_t size; - const char *name; - ops_hash_init_t *init; - ops_hash_add_t *add; - ops_hash_finish_t *finish; - void *data; - }; - -typedef void ops_crypt_set_iv_t(ops_crypt_t *crypt, - const unsigned char *iv); -typedef void ops_crypt_set_key_t(ops_crypt_t *crypt, - const unsigned char *key); -typedef void ops_crypt_init_t(ops_crypt_t *crypt); -typedef void ops_crypt_resync_t(ops_crypt_t *crypt); -typedef void ops_crypt_block_encrypt_t(ops_crypt_t *crypt,void *out, - const void *in); -typedef void ops_crypt_block_decrypt_t(ops_crypt_t *crypt,void *out, - const void *in); -typedef void ops_crypt_cfb_encrypt_t(ops_crypt_t *crypt,void *out, - const void *in, size_t count); -typedef void ops_crypt_cfb_decrypt_t(ops_crypt_t *crypt,void *out, - const void *in, size_t count); -typedef void ops_crypt_finish_t(ops_crypt_t *crypt); - -/** _ops_crypt_t */ -struct _ops_crypt_t - { - ops_symmetric_algorithm_t algorithm; - size_t blocksize; - size_t keysize; - ops_crypt_set_iv_t *set_iv; /* Call this before decrypt init! */ - ops_crypt_set_key_t *set_key; /* Call this before init! */ - ops_crypt_init_t *base_init; - ops_crypt_resync_t *decrypt_resync; - // encrypt/decrypt one block - ops_crypt_block_encrypt_t *block_encrypt; - ops_crypt_block_decrypt_t *block_decrypt; - - // Standard CFB encrypt/decrypt (as used by Sym Enc Int Prot packets) - ops_crypt_cfb_encrypt_t *cfb_encrypt; - ops_crypt_cfb_decrypt_t *cfb_decrypt; - - ops_crypt_finish_t *decrypt_finish; - unsigned char iv[OPS_MAX_BLOCK_SIZE]; - unsigned char civ[OPS_MAX_BLOCK_SIZE]; - unsigned char siv[OPS_MAX_BLOCK_SIZE]; /* Needed for weird v3 resync */ - unsigned char key[OPS_MAX_KEY_SIZE]; - size_t num; /* Offset - see openssl _encrypt doco */ - void *encrypt_key; - void *decrypt_key; - }; - -void ops_crypto_init(void); -void ops_crypto_finish(void); -void ops_hash_md5(ops_hash_t *hash); -void ops_hash_sha1(ops_hash_t *hash); -void ops_hash_sha256(ops_hash_t *hash); -void ops_hash_sha512(ops_hash_t *hash); -void ops_hash_sha384(ops_hash_t *hash); -void ops_hash_sha224(ops_hash_t *hash); -void ops_hash_any(ops_hash_t *hash,ops_hash_algorithm_t alg); -ops_hash_algorithm_t ops_hash_algorithm_from_text(const char *hash); -const char *ops_text_from_hash(ops_hash_t *hash); -unsigned ops_hash_size(ops_hash_algorithm_t alg); -unsigned ops_hash(unsigned char *out,ops_hash_algorithm_t alg,const void *in, - size_t length); - -void ops_hash_add_int(ops_hash_t *hash,unsigned n,unsigned length); - -ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length, - const ops_dsa_signature_t *sig, - const ops_dsa_public_key_t *dsa); -int ops_rsa_public_decrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_public_key_t *rsa); -int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_public_key_t *rsa); -int ops_rsa_private_encrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_secret_key_t *srsa, - const ops_rsa_public_key_t *rsa); -int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_secret_key_t *srsa, - const ops_rsa_public_key_t *rsa); - -unsigned ops_block_size(ops_symmetric_algorithm_t alg); -unsigned ops_key_size(ops_symmetric_algorithm_t alg); - -int ops_decrypt_data(ops_content_tag_t tag,ops_region_t *region, - ops_parse_info_t *parse_info); - -int ops_crypt_any(ops_crypt_t *decrypt,ops_symmetric_algorithm_t alg); -void ops_decrypt_init(ops_crypt_t *decrypt); -void ops_encrypt_init(ops_crypt_t *encrypt); -size_t ops_decrypt_se(ops_crypt_t *decrypt,void *out,const void *in, - size_t count); -size_t ops_encrypt_se(ops_crypt_t *encrypt,void *out,const void *in, - size_t count); -size_t ops_decrypt_se_ip(ops_crypt_t *decrypt,void *out,const void *in, - size_t count); -size_t ops_encrypt_se_ip(ops_crypt_t *encrypt,void *out,const void *in, - size_t count); -ops_boolean_t ops_is_sa_supported(ops_symmetric_algorithm_t alg); - -void ops_reader_push_decrypt(ops_parse_info_t *pinfo,ops_crypt_t *decrypt, - ops_region_t *region); -void ops_reader_pop_decrypt(ops_parse_info_t *pinfo); - -// Hash everything that's read -void ops_reader_push_hash(ops_parse_info_t *pinfo,ops_hash_t *hash); -void ops_reader_pop_hash(ops_parse_info_t *pinfo); - -int ops_decrypt_and_unencode_mpi(unsigned char *buf,unsigned buflen,const BIGNUM *encmpi, - const ops_secret_key_t *skey); -ops_boolean_t ops_rsa_encrypt_mpi(const unsigned char *buf, const size_t buflen, - const ops_public_key_t *pkey, - ops_pk_session_key_parameters_t *spk); - - -// Encrypt everything that's written -struct ops_key_data; -void ops_writer_push_encrypt(ops_create_info_t *info, - const struct ops_key_data *key); - -ops_boolean_t ops_encrypt_file(const char* input_filename, const char* output_filename, const ops_keydata_t *pub_key, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite); -ops_boolean_t ops_decrypt_file(const char* input_filename, const char* output_filename, ops_keyring_t *keyring, const ops_boolean_t use_armour, const ops_boolean_t allow_overwrite,ops_parse_cb_t* cb_get_passphrase); -extern ops_boolean_t ops_encrypt_stream(ops_create_info_t* cinfo, const ops_keydata_t* public_key, const ops_secret_key_t* secret_key, const ops_boolean_t compress, const ops_boolean_t use_armour); -ops_boolean_t ops_decrypt_memory(const unsigned char *encrypted_memory,int em_length, unsigned char **decrypted_memory,int *out_length, ops_keyring_t* keyring, const ops_boolean_t use_armour, ops_parse_cb_t* cb_get_passphrase) ; -// Keys -ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e, ops_keydata_t* keydata); -ops_keydata_t* ops_rsa_create_selfsigned_keypair(const int numbits, const unsigned long e, ops_user_id_t * userid); - -int ops_dsa_size(const ops_dsa_public_key_t *dsa); -DSA_SIG* ops_dsa_sign(unsigned char* hashbuf, unsigned hashsize, const ops_dsa_secret_key_t *sdsa, const ops_dsa_public_key_t *dsa); -#endif diff --git a/openpgpsdk/src/openpgpsdk/defs.h b/openpgpsdk/src/openpgpsdk/defs.h deleted file mode 100644 index e4f8b48ba..000000000 --- a/openpgpsdk/src/openpgpsdk/defs.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_DEFS_H -#define OPS_DEFS_H - -#define OPS_ARMOURED ops_true -#define OPS_UNARMOURED ops_false - -#define OPS_OVERWRITE_YES ops_true -#define OPS_OVERWRITE_NO ops_false - -#define OPS_ACCUMULATE_YES ops_true -#define OPS_ACCUMULATE_NO ops_false - -#endif /* OPS_DEFS_H */ diff --git a/openpgpsdk/src/openpgpsdk/errors.c b/openpgpsdk/src/openpgpsdk/errors.c deleted file mode 100644 index 2de42341b..000000000 --- a/openpgpsdk/src/openpgpsdk/errors.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * \brief Error Handling - */ - -#include -#include - -#include -#include -#include -#include - -#ifdef WIN32 -#define vsnprintf _vsnprintf -#endif - -#include -#include - -#define ERRNAME(code) { code, #code } - -static ops_errcode_name_map_t errcode_name_map[] = - { - ERRNAME(OPS_E_OK), - ERRNAME(OPS_E_FAIL), - ERRNAME(OPS_E_SYSTEM_ERROR), - ERRNAME(OPS_E_UNIMPLEMENTED), - - ERRNAME(OPS_E_R), - ERRNAME(OPS_E_R_READ_FAILED), - ERRNAME(OPS_E_R_EARLY_EOF), - ERRNAME(OPS_E_R_BAD_FORMAT), - ERRNAME(OPS_E_R_UNCONSUMED_DATA), - - ERRNAME(OPS_E_W), - ERRNAME(OPS_E_W_WRITE_FAILED), - ERRNAME(OPS_E_W_WRITE_TOO_SHORT), - - ERRNAME(OPS_E_P), - ERRNAME(OPS_E_P_NOT_ENOUGH_DATA), - ERRNAME(OPS_E_P_UNKNOWN_TAG), - ERRNAME(OPS_E_P_PACKET_CONSUMED), - ERRNAME(OPS_E_P_MPI_FORMAT_ERROR), - - ERRNAME(OPS_E_C), - - ERRNAME(OPS_E_V), - ERRNAME(OPS_E_V_BAD_SIGNATURE), - ERRNAME(OPS_E_V_NO_SIGNATURE), - ERRNAME(OPS_E_V_UNKNOWN_SIGNER), - - ERRNAME(OPS_E_ALG), - ERRNAME(OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG), - ERRNAME(OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG), - ERRNAME(OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG), - ERRNAME(OPS_E_ALG_UNSUPPORTED_HASH_ALG), - - ERRNAME(OPS_E_PROTO), - ERRNAME(OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT), - ERRNAME(OPS_E_PROTO_UNKNOWN_SS), - ERRNAME(OPS_E_PROTO_CRITICAL_SS_IGNORED), - ERRNAME(OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN), - ERRNAME(OPS_E_PROTO_BAD_SIGNATURE_VRSN), - ERRNAME(OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN), - ERRNAME(OPS_E_PROTO_BAD_PKSK_VRSN), - ERRNAME(OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN), - ERRNAME(OPS_E_PROTO_BAD_SK_CHECKSUM), - - { 0x00, NULL }, /* this is the end-of-array marker */ - }; - -/** - * \ingroup Core_Errors - * \brief returns error code name - * \param errcode - * \return error code name or "Unknown" - */ -char *ops_errcode(const ops_errcode_t errcode) - { - return(ops_str_from_map((int) errcode, (ops_map_t *) errcode_name_map)); - } - -/** - * \ingroup Core_Errors - * \brief Pushes the given error on the given errorstack - * \param errstack Error stack to use - * \param errcode Code of error to push - * \param sys_errno System errno (used if errcode=OPS_E_SYSTEM_ERROR) - * \param file Source filename where error occurred - * \param line Line in source file where error occurred - * \param fmt Comment - * - */ - -void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, - const char *file,int line,const char *fmt,...) - { - // first get the varargs and generate the comment - char *comment; - int maxbuf=128; - va_list args; - ops_error_t *err; - - comment=malloc(maxbuf+1); - assert(comment); - - va_start(args, fmt); - vsnprintf(comment,maxbuf+1,fmt,args); - va_end(args); - - // alloc a new error and add it to the top of the stack - - err=malloc(sizeof(ops_error_t)); - assert(err); - - err->next=*errstack; - *errstack=err; - - // fill in the details - err->errcode=errcode; - err->sys_errno=sys_errno; - err->file=file; - err->line=line; - - err->comment=comment; - } - -/** -\ingroup Core_Errors -\brief print this error -\param err Error to print -*/ -void ops_print_error(ops_error_t *err) - { - printf("%s:%d: ",err->file,err->line); - if(err->errcode==OPS_E_SYSTEM_ERROR) - printf("system error %d returned from %s()\n",err->sys_errno, - err->comment); - else - printf("%s, %s\n",ops_errcode(err->errcode),err->comment); - } - -/** -\ingroup Core_Errors -\brief Print all errors on stack -\param errstack Error stack to print -*/ -void ops_print_errors(ops_error_t *errstack) - { - ops_error_t *err; - - for(err=errstack ; err!=NULL ; err=err->next) - ops_print_error(err); - } - -/** -\ingroup Core_Errors -\brief Return true if given error is present anywhere on stack -\param errstack Error stack to check -\param errcode Error code to look for -\return 1 if found; else 0 -*/ -int ops_has_error(ops_error_t *errstack, ops_errcode_t errcode) - { - ops_error_t *err; - for (err=errstack; err!=NULL; err=err->next) - { - if (err->errcode==errcode) - return 1; - } - return 0; - } - -/** -\ingroup Core_Errors -\brief Frees all errors on stack -\param errstack Error stack to free -*/ -void ops_free_errors(ops_error_t *errstack) -{ - ops_error_t *next; - while(errstack!=NULL) { - next=errstack->next; - free(errstack->comment); - free(errstack); - errstack=next; - } -} - -/** -\ingroup InternalAPI -\brief Moves errors from a create info structure to another error stack. - -The error stack wil be moved from the source structure to the destination -stack. If the destination already has errors defined, the errors will -be appended. -*/ -void ops_move_errors(ops_create_info_t *source, ops_error_t **dest) - { - if (*dest == NULL) - *dest = source->errors; - else - { - ops_error_t *last = *dest; - while(last->next != NULL) - last = last->next; - last->next = source->errors; - } - source->errors = NULL; - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/errors.h b/openpgpsdk/src/openpgpsdk/errors.h deleted file mode 100644 index 6ff958c2d..000000000 --- a/openpgpsdk/src/openpgpsdk/errors.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_ERRORS -#define OPS_ERRORS - -#include "openpgpsdk/types.h" -#include - -/** error codes */ -// Remember to add names to map in errors.c -typedef enum - { - OPS_E_OK=0x0000, /* no error */ - OPS_E_FAIL=0x0001, /* general error */ - OPS_E_SYSTEM_ERROR=0x0002, /* system error, look at errno for details */ - OPS_E_UNIMPLEMENTED=0x0003, /* feature not yet implemented */ - - /* reader errors */ - OPS_E_R=0x1000, /* general reader error */ - OPS_E_R_READ_FAILED =OPS_E_R+1, - OPS_E_R_EARLY_EOF =OPS_E_R+2, - OPS_E_R_BAD_FORMAT =OPS_E_R+3, // For example, malformed armour - OPS_E_R_UNSUPPORTED =OPS_E_R+4, - OPS_E_R_UNCONSUMED_DATA =OPS_E_R+5, - - /* writer errors */ - OPS_E_W=0x2000, /* general writer error */ - OPS_E_W_WRITE_FAILED = OPS_E_W+1, - OPS_E_W_WRITE_TOO_SHORT = OPS_E_W+2, - - /* parser errors */ - OPS_E_P=0x3000, /* general parser error */ - OPS_E_P_NOT_ENOUGH_DATA =OPS_E_P+1, - OPS_E_P_UNKNOWN_TAG =OPS_E_P+2, - OPS_E_P_PACKET_CONSUMED =OPS_E_P+3, - OPS_E_P_MPI_FORMAT_ERROR =OPS_E_P+4, - OPS_E_P_PACKET_NOT_CONSUMED =OPS_E_P+5, - OPS_E_P_DECOMPRESSION_ERROR =OPS_E_P+6, - OPS_E_P_NO_USERID =OPS_E_P+7, - - /* creator errors */ - OPS_E_C=0x4000, /* general creator error */ - - /* validation errors */ - OPS_E_V=0x5000, /* general validation error */ - OPS_E_V_BAD_SIGNATURE =OPS_E_V+1, - OPS_E_V_NO_SIGNATURE =OPS_E_V+2, - OPS_E_V_UNKNOWN_SIGNER =OPS_E_V+3, - OPS_E_V_BAD_HASH =OPS_E_V+4, - - /* Algorithm support errors */ - OPS_E_ALG=0x6000, /* general algorithm error */ - OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG =OPS_E_ALG+1, - OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG =OPS_E_ALG+2, - OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG =OPS_E_ALG+3, - OPS_E_ALG_UNSUPPORTED_HASH_ALG =OPS_E_ALG+4, - OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG =OPS_E_ALG+5, - - /* Protocol errors */ - OPS_E_PROTO=0x7000, /* general protocol error */ - OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT =OPS_E_PROTO+2, - OPS_E_PROTO_UNKNOWN_SS =OPS_E_PROTO+3, - OPS_E_PROTO_CRITICAL_SS_IGNORED =OPS_E_PROTO+4, - OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN =OPS_E_PROTO+5, - OPS_E_PROTO_BAD_SIGNATURE_VRSN =OPS_E_PROTO+6, - OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN =OPS_E_PROTO+7, - OPS_E_PROTO_BAD_PKSK_VRSN =OPS_E_PROTO+8, - OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN =OPS_E_PROTO+9, - OPS_E_PROTO_BAD_SK_CHECKSUM =OPS_E_PROTO+10, - } ops_errcode_t; - -/** ops_errcode_name_map_t */ -typedef ops_map_t ops_errcode_name_map_t; - -/** one entry in a linked list of errors */ -typedef struct ops_error - { - ops_errcode_t errcode; - int sys_errno; /*!< irrelevent unless errcode == OPS_E_SYSTEM_ERROR */ - char *comment; - const char *file; - int line; - struct ops_error *next; - } ops_error_t; - -char *ops_errcode(const ops_errcode_t errcode); - -void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, - const char *file,int line,const char *comment,...); -void ops_print_error(ops_error_t *err); -void ops_print_errors(ops_error_t *errstack); -void ops_free_errors(ops_error_t *errstack); -int ops_has_error(ops_error_t *errstack, ops_errcode_t errcode); -void ops_move_errors(ops_create_info_t *source, ops_error_t **errstack); - -#define OPS_SYSTEM_ERROR_1(err,code,syscall,fmt,arg) do { ops_push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,syscall); ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) -#define OPS_MEMORY_ERROR(err) {fprintf(stderr, "Memory error\n");} // \todo placeholder for better error handling -#define OPS_ERROR(err,code,fmt) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt); } while(0) -#define OPS_ERROR_1(err,code,fmt,arg) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) -#define OPS_ERROR_2(err,code,fmt,arg,arg2) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2); } while(0) -#define OPS_ERROR_3(err,code,fmt,arg,arg2,arg3) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3); } while(0) -#define OPS_ERROR_4(err,code,fmt,arg,arg2,arg3,arg4) do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3,arg4); } while(0) - -#endif /* OPS_ERRORS */ diff --git a/openpgpsdk/src/openpgpsdk/final.h b/openpgpsdk/src/openpgpsdk/final.h deleted file mode 100644 index 404391d2f..000000000 --- a/openpgpsdk/src/openpgpsdk/final.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* A header that is always included last, for things that need to come last */ - -#ifdef DMALLOC -# include -#endif - diff --git a/openpgpsdk/src/openpgpsdk/fingerprint.c b/openpgpsdk/src/openpgpsdk/fingerprint.c deleted file mode 100644 index 61702f292..000000000 --- a/openpgpsdk/src/openpgpsdk/fingerprint.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include - -#include -#if HAVE_ALLOCA_H -# include -#endif - -#ifdef WIN32 -#define alloca _alloca -#endif - -#include - -static int debug=0; - -/** - * \ingroup Core_Keys - * \brief Calculate a public key fingerprint. - * \param fp Where to put the calculated fingerprint - * \param key The key for which the fingerprint is calculated - */ - -void ops_fingerprint(ops_fingerprint_t *fp,const ops_public_key_t *key) - { - if(key->version == 2 || key->version == 3) - { - unsigned char *bn; - int n; - ops_hash_t md5; - - assert(key->algorithm == OPS_PKA_RSA - || key->algorithm == OPS_PKA_RSA_ENCRYPT_ONLY - || key->algorithm == OPS_PKA_RSA_SIGN_ONLY ); - - ops_hash_md5(&md5); - md5.init(&md5); - - n=BN_num_bytes(key->key.rsa.n); - bn=alloca(n); - BN_bn2bin(key->key.rsa.n,bn); - md5.add(&md5,bn,n); - - n=BN_num_bytes(key->key.rsa.e); - bn=alloca(n); - BN_bn2bin(key->key.rsa.e,bn); - md5.add(&md5,bn,n); - - md5.finish(&md5,fp->fingerprint); - fp->length=16; - } - else - { - ops_memory_t *mem=ops_memory_new(); - ops_hash_t sha1; - size_t l; - - ops_build_public_key(mem,key,ops_false); - - if (debug) - { fprintf(stderr,"--- creating key fingerprint\n"); } - - ops_hash_sha1(&sha1); - sha1.init(&sha1); - - l=ops_memory_get_length(mem); - - ops_hash_add_int(&sha1,0x99,1); - ops_hash_add_int(&sha1,l,2); - sha1.add(&sha1,ops_memory_get_data(mem),l); - sha1.finish(&sha1,fp->fingerprint); - - if (debug) - { fprintf(stderr,"--- finished creating key fingerprint\n"); } - - fp->length=20; - - ops_memory_free(mem); - } - } - -/** - * \ingroup Core_Keys - * \brief Calculate the Key ID from the public key. - * \param keyid Space for the calculated ID to be stored - * \param key The key for which the ID is calculated - */ - -void ops_keyid(unsigned char keyid[8],const ops_public_key_t *key) - { - if(key->version == 2 || key->version == 3) - { - unsigned char bn[8192]; - unsigned n=BN_num_bytes(key->key.rsa.n); - - assert(n <= sizeof bn); - assert(key->algorithm == OPS_PKA_RSA - || key->algorithm == OPS_PKA_RSA_ENCRYPT_ONLY - || key->algorithm == OPS_PKA_RSA_SIGN_ONLY ); - BN_bn2bin(key->key.rsa.n,bn); - memcpy(keyid,bn+n-8,8); - } - else - { - ops_fingerprint_t fingerprint; - - ops_fingerprint(&fingerprint,key); - memcpy(keyid,fingerprint.fingerprint+fingerprint.length-8,8); - } - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/hash.c b/openpgpsdk/src/openpgpsdk/hash.c deleted file mode 100644 index 5154f46ac..000000000 --- a/openpgpsdk/src/openpgpsdk/hash.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include - -#include - -static int debug=0; - -/** -\ingroup Core_Hashes -\brief Add to the hash -\param hash Hash to add to -\param n Int to add -\param length Length of int in bytes -*/ -void ops_hash_add_int(ops_hash_t *hash,unsigned n,unsigned length) - { - while(length--) - { - unsigned char c[1]; - - c[0]=n >> (length*8); - hash->add(hash,c,1); - } - } - -/** -\ingroup Core_Hashes -\brief Setup hash for given hash algorithm -\param hash Hash to set up -\param alg Hash algorithm to use -*/ -void ops_hash_any(ops_hash_t *hash,ops_hash_algorithm_t alg) - { - switch(alg) - { - case OPS_HASH_MD5: - ops_hash_md5(hash); - break; - - case OPS_HASH_SHA1: - ops_hash_sha1(hash); - break; - - case OPS_HASH_SHA256: - ops_hash_sha256(hash); - break; - - case OPS_HASH_SHA384: - ops_hash_sha384(hash); - break; - - case OPS_HASH_SHA512: - ops_hash_sha512(hash); - break; - - case OPS_HASH_SHA224: - ops_hash_sha224(hash); - break; - - default: - assert(0); - } - } - -/** -\ingroup Core_Hashes -\brief Returns size of hash for given hash algorithm -\param alg Hash algorithm to use -\return Size of hash algorithm in bytes -*/ -unsigned ops_hash_size(ops_hash_algorithm_t alg) - { - switch(alg) - { - case OPS_HASH_MD5: - return 16; - - case OPS_HASH_SHA1: - return 20; - - case OPS_HASH_SHA256: - return 32; - - case OPS_HASH_SHA224: - return 28; - - case OPS_HASH_SHA512: - return 64; - - case OPS_HASH_SHA384: - return 48; - - default: - assert(0); - } - - return 0; - } - -/** -\ingroup Core_Hashes -\brief Returns hash enum corresponding to given string -\param hash Text name of hash algorithm i.e. "SHA1" -\returns Corresponding enum i.e. OPS_HASH_SHA1 -*/ -ops_hash_algorithm_t ops_hash_algorithm_from_text(const char *hash) - { - if(!strcmp(hash,"SHA1")) - return OPS_HASH_SHA1; - else if(!strcmp(hash,"MD5")) - return OPS_HASH_MD5; - else if (!strcmp(hash,"SHA256")) - return OPS_HASH_SHA256; - /* - else if (!strcmp(hash,"SHA224")) - return OPS_HASH_SHA224; - */ - else if (!strcmp(hash,"SHA512")) - return OPS_HASH_SHA512; - else if (!strcmp(hash,"SHA384")) - return OPS_HASH_SHA384; - - return OPS_HASH_UNKNOWN; - } - -/** -\ingroup Core_Hashes -\brief Hash given data -\param out Where to write the hash -\param alg Hash algorithm to use -\param in Data to hash -\param length Length of data -\return Size of hash created -*/ -unsigned ops_hash(unsigned char *out,ops_hash_algorithm_t alg,const void *in, - size_t length) - { - ops_hash_t hash; - - ops_hash_any(&hash,alg); - hash.init(&hash); - hash.add(&hash,in,length); - return hash.finish(&hash,out); - } - -/** -\ingroup Core_Hashes -\brief Calculate hash for MDC packet -\param preamble Preamble to hash -\param sz_preamble Size of preamble -\param plaintext Plaintext to hash -\param sz_plaintext Size of plaintext -\param hashed Resulting hash -*/ -void ops_calc_mdc_hash(const unsigned char* preamble, const size_t sz_preamble, const unsigned char* plaintext, const unsigned int sz_plaintext, unsigned char *hashed) - { - ops_hash_t hash; - unsigned char c[1]; - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"ops_calc_mdc_hash():\n"); - - fprintf(stderr,"\npreamble: "); - for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "keyring_local.h" -#include "parse_local.h" - -#include -#include -#ifndef WIN32 -#include -#include -#endif -#include -#include - -#include -#include - -/** - \ingroup HighLevel_Keyring - - \brief Creates a new ops_keydata_t struct - - \return A new ops_keydata_t struct, initialised to zero. - - \note The returned ops_keydata_t struct must be freed after use with ops_keydata_free. -*/ - -ops_keydata_t *ops_keydata_new(void) - { return ops_mallocz(sizeof(ops_keydata_t)); } - - -// Frees the content of a keydata structure, but not the keydata itself. -static void keydata_internal_free(ops_keydata_t *keydata) - { - unsigned n; - - for(n=0 ; n < keydata->nuids ; ++n) - ops_user_id_free(&keydata->uids[n]); - free(keydata->uids); - keydata->uids=NULL; - keydata->nuids=0; - - for(n=0 ; n < keydata->npackets ; ++n) - ops_packet_free(&keydata->packets[n]); - free(keydata->packets); - keydata->packets=NULL; - keydata->npackets=0; - -/* for(n=0;nnsigs;++n) - { - ops_user_id_free(keydata->sigs[n].userid) ; - ops_packet_free(keydata->sigs[n].packet) ; - }*/ - free(keydata->sigs) ; - - if(keydata->type == OPS_PTAG_CT_PUBLIC_KEY) - ops_public_key_free(&keydata->key.pkey); - else - ops_secret_key_free(&keydata->key.skey); - - } - -/** - \ingroup HighLevel_Keyring - - \brief Frees keydata and its memory - - \param keydata Key to be freed. - - \note This frees the keydata itself, as well as any other memory - alloc-ed by it. -*/ -void ops_keydata_free(ops_keydata_t *keydata) - { - keydata_internal_free(keydata); - free(keydata); - } - -// \todo check where userid pointers are copied -/** -\ingroup Core_Keys -\brief Copy user id, including contents -\param dst Destination User ID -\param src Source User ID -\note If dst already has a user_id, it will be freed. -*/ -void ops_copy_userid(ops_user_id_t* dst, const ops_user_id_t* src) - { - int len=strlen((char *)src->user_id); - if (dst->user_id) - free(dst->user_id); - dst->user_id=ops_mallocz(len+1); - - memcpy(dst->user_id, src->user_id, len); - } -// \todo check where pkt pointers are copied -/** -\ingroup Core_Keys -\brief Copy packet, including contents -\param dst Destination packet -\param src Source packet -\note If dst already has a packet, it will be freed. -*/ -void ops_copy_packet(ops_packet_t* dst, const ops_packet_t* src) - { - if (dst->raw) - free(dst->raw); - dst->raw=ops_mallocz(src->length); - - dst->length=src->length; - memcpy(dst->raw, src->raw, src->length); - } - - - -/** -\ingroup Core_Keys -\brief Copies entire key data -\param dst Destination key where to copy -\param src Source key to copy -*/ -void ops_keydata_copy(ops_keydata_t *dst,const ops_keydata_t *src) -{ - unsigned n; - - keydata_internal_free(dst) ; - memset(dst,0,sizeof(ops_keydata_t)) ; - - dst->uids = (ops_user_id_t*)ops_mallocz(src->nuids * sizeof(ops_user_id_t)) ; - dst->nuids = src->nuids ; - dst->nuids_allocated = src->nuids ; - - for(n=0 ; n < src->nuids ; ++n) - ops_copy_userid(&dst->uids[n],&src->uids[n]) ; - - dst->packets = (ops_packet_t*)ops_mallocz(src->npackets * sizeof(ops_packet_t)) ; - dst->npackets = src->npackets ; - dst->npackets_allocated = src->npackets ; - - for(n=0 ; n < src->npackets ; ++n) - ops_copy_packet(&(dst->packets[n]),&(src->packets[n])); - - dst->nsigs = src->nsigs ; - dst->sigs = (sigpacket_t*)ops_mallocz(src->nsigs * sizeof(sigpacket_t)) ; - dst->nsigs_allocated = src->nsigs ; - - for(n=0 ; n < src->nsigs ; ++n) - { - dst->sigs[n].userid = (ops_user_id_t*)ops_mallocz(sizeof(ops_user_id_t)) ; - dst->sigs[n].packet = (ops_packet_t*)ops_mallocz(sizeof(ops_packet_t)) ; - - ops_copy_userid(dst->sigs[n].userid,src->sigs[n].userid) ; - ops_copy_packet(dst->sigs[n].packet,src->sigs[n].packet) ; - } - - dst->key_id[0] = src->key_id[0] ; - dst->key_id[1] = src->key_id[1] ; - dst->key_id[2] = src->key_id[2] ; - dst->key_id[3] = src->key_id[3] ; - dst->key_id[4] = src->key_id[4] ; - dst->key_id[5] = src->key_id[5] ; - dst->key_id[6] = src->key_id[6] ; - dst->key_id[7] = src->key_id[7] ; - dst->type = src->type ; - dst->key = src->key ; - dst->fingerprint = src->fingerprint ; - - if(src->type == OPS_PTAG_CT_PUBLIC_KEY) - ops_public_key_copy(&dst->key.pkey,&src->key.pkey); - else - ops_secret_key_copy(&dst->key.skey,&src->key.skey); -} - - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the public key in the given keydata. - \param keydata - - \return Pointer to public key - - \note This is not a copy, do not free it after use. -*/ - -const ops_public_key_t * -ops_get_public_key_from_data(const ops_keydata_t *keydata) - { - if(keydata->type == OPS_PTAG_CT_PUBLIC_KEY) - return &keydata->key.pkey; - return &keydata->key.skey.public_key; - } - -/** -\ingroup HighLevel_KeyGeneral - -\brief Check whether this is a secret key or not. -*/ - -ops_boolean_t ops_is_key_secret(const ops_keydata_t *data) - { return data->type != OPS_PTAG_CT_PUBLIC_KEY; } - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the secret key in the given keydata. - - \note This is not a copy, do not free it after use. - - \note This returns a const. If you need to be able to write to this pointer, use ops_get_writable_secret_key_from_data -*/ - -const ops_secret_key_t * -ops_get_secret_key_from_data(const ops_keydata_t *data) - { - if(data->type != OPS_PTAG_CT_SECRET_KEY) - return NULL; - - return &data->key.skey; - } - -/** - \ingroup HighLevel_KeyGeneral - - \brief Returns the secret key in the given keydata. - - \note This is not a copy, do not free it after use. - - \note If you do not need to be able to modify this key, there is an equivalent read-only function ops_get_secret_key_from_data. -*/ - -ops_secret_key_t * -ops_get_writable_secret_key_from_data(ops_keydata_t *data) - { - if (data->type != OPS_PTAG_CT_SECRET_KEY) - return NULL; - - return &data->key.skey; - } - -typedef struct - { - const ops_keydata_t *key; - char *pphrase; - ops_secret_key_t *skey; - } decrypt_arg_t; - -static ops_parse_cb_return_t decrypt_cb(const ops_parser_content_t *content_, - ops_parse_cb_info_t *cbinfo) - { - const ops_parser_content_union_t *content=&content_->content; - decrypt_arg_t *arg=ops_parse_cb_get_arg(cbinfo); - - OPS_USED(cbinfo); - - switch(content_->tag) - { - case OPS_PARSER_PTAG: - case OPS_PTAG_CT_USER_ID: - case OPS_PTAG_CT_SIGNATURE: - case OPS_PTAG_CT_SIGNATURE_HEADER: - case OPS_PTAG_CT_SIGNATURE_FOOTER: - case OPS_PTAG_CT_TRUST: - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - *content->secret_key_passphrase.passphrase=arg->pphrase; - return OPS_KEEP_MEMORY; - - case OPS_PARSER_ERRCODE: - switch(content->errcode.errcode) - { - case OPS_E_P_MPI_FORMAT_ERROR: - /* Generally this means a bad passphrase */ - fprintf(stderr,"Bad passphrase!\n"); - goto done; - - case OPS_E_P_PACKET_CONSUMED: - /* And this is because of an error we've accepted */ - goto done; - - default: - fprintf(stderr,"parse error: %s\n", - ops_errcode(content->errcode.errcode)); - assert(0); - break; - } - - break; - - case OPS_PARSER_ERROR: - printf("parse error: %s\n",content->error.error); - assert(0); - break; - - case OPS_PTAG_CT_SECRET_KEY: - arg->skey=malloc(sizeof *arg->skey); - *arg->skey=content->secret_key; - return OPS_KEEP_MEMORY; - - case OPS_PARSER_PACKET_END: - // nothing to do - break; - - default: - fprintf(stderr,"Unexpected tag %d (0x%x)\n",content_->tag, - content_->tag); - assert(0); - } - - done: - return OPS_RELEASE_MEMORY; - } - -/** -\ingroup Core_Keys -\brief Decrypts secret key from given keydata with given passphrase -\param key Key from which to get secret key -\param pphrase Passphrase to use to decrypt secret key -\return secret key -*/ -ops_secret_key_t *ops_decrypt_secret_key_from_data(const ops_keydata_t *key, - const char *pphrase) - { - ops_parse_info_t *pinfo; - decrypt_arg_t arg; - - memset(&arg,'\0',sizeof arg); - arg.key=key; - arg.pphrase=strdup(pphrase); - - pinfo=ops_parse_info_new(); - - ops_keydata_reader_set(pinfo,key); - ops_parse_cb_set(pinfo,decrypt_cb,&arg); - pinfo->rinfo.accumulate=ops_true; - - ops_parse(pinfo,ops_false); - - ops_parse_info_delete(pinfo); - - return arg.skey; - } - -/** -\ingroup Core_Keys -\brief Set secret key in content -\param content Content to be set -\param key Keydata to get secret key from -*/ -void ops_set_secret_key(ops_parser_content_union_t* content,const ops_keydata_t *key) - { - *content->get_secret_key.secret_key=&key->key.skey; - } - -/** -\ingroup Core_Keys -\brief Get Key ID from keydata -\param key Keydata to get Key ID from -\return Pointer to Key ID inside keydata -*/ -const unsigned char* ops_get_key_id(const ops_keydata_t *key) - { - return key->key_id; - } - -/** -\ingroup Core_Keys -\brief How many User IDs in this key? -\param key Keydata to check -\return Num of user ids -*/ -unsigned ops_get_user_id_count(const ops_keydata_t *key) - { - return key->nuids; - } - -/** -\ingroup Core_Keys -\brief Get indexed user id from key -\param key Key to get user id from -\param index Which key to get -\return Pointer to requested user id -*/ -const unsigned char* ops_get_user_id(const ops_keydata_t *key, unsigned index) - { - return key->uids[index].user_id; - } - -/** - \ingroup HighLevel_Supported - \brief Checks whether key's algorithm and type are supported by OpenPGP::SDK - \param keydata Key to be checked - \return ops_true if key algorithm and type are supported by OpenPGP::SDK; ops_false if not -*/ - -ops_boolean_t ops_is_key_supported(const ops_keydata_t *keydata) -{ - if(keydata->type == OPS_PTAG_CT_PUBLIC_KEY) - { - if(keydata->key.pkey.algorithm == OPS_PKA_RSA) - return ops_true; - } - return ops_false; -} - - -/** - \ingroup HighLevel_KeyringFind - - \brief Returns key inside a keyring, chosen by index - - \param keyring Pointer to existing keyring - \param index Index of required key - - \note Index starts at 0 - - \note This returns a pointer to the original key, not a copy. You do not need to free the key after use. - - \return Pointer to the required key; or NULL if index too large. - - Example code: - \code - void example(const ops_keyring_t* keyring) - { - ops_keydata_t* keydata=NULL; - keydata=ops_keyring_get_key_by_index(keyring, 0); - ... - } - \endcode -*/ - -const ops_keydata_t* ops_keyring_get_key_by_index(const ops_keyring_t *keyring, int index) - { - if (index >= keyring->nkeys) - return NULL; - return &keyring->keys[index]; - } - -/** -\ingroup Core_Keys -\brief Add User ID to keydata -\param keydata Key to which to add User ID -\param userid User ID to add -\return Pointer to new User ID -*/ -ops_user_id_t* ops_add_userid_to_keydata(ops_keydata_t* keydata, const ops_user_id_t* userid) - { - ops_user_id_t* new_uid=NULL; - - EXPAND_ARRAY(keydata, uids); - - // initialise new entry in array - new_uid=&keydata->uids[keydata->nuids]; - - new_uid->user_id=NULL; - - // now copy it - ops_copy_userid(new_uid,userid); - keydata->nuids++; - - return new_uid; - } - -/** -\ingroup Core_Keys -\brief Add packet to key -\param keydata Key to which to add packet -\param packet Packet to add -\return Pointer to new packet -*/ -ops_packet_t* ops_add_packet_to_keydata(ops_keydata_t* keydata, const ops_packet_t* packet) - { - ops_packet_t* new_pkt=NULL; - - EXPAND_ARRAY(keydata, packets); - - // initialise new entry in array - new_pkt=&keydata->packets[keydata->npackets]; - new_pkt->length=0; - new_pkt->raw=NULL; - - // now copy it - ops_copy_packet(new_pkt, packet); - keydata->npackets++; - - return new_pkt; - } - -/** -\ingroup Core_Keys -\brief Add signed User ID to key -\param keydata Key to which to add signed User ID -\param user_id User ID to add -\param sigpacket Packet to add -*/ -void ops_add_signed_userid_to_keydata(ops_keydata_t* keydata, const ops_user_id_t* user_id, const ops_packet_t* sigpacket) - { - //int i=0; - ops_user_id_t * uid=NULL; - ops_packet_t * pkt=NULL; - - uid=ops_add_userid_to_keydata(keydata, user_id); - pkt=ops_add_packet_to_keydata(keydata, sigpacket); - - /* - * add entry in sigs array to link the userid and sigpacket - */ - - // and add ptr to it from the sigs array - EXPAND_ARRAY(keydata, sigs); - - // setup new entry in array - - keydata->sigs[keydata->nsigs].userid=uid; - keydata->sigs[keydata->nsigs].packet=pkt; - - keydata->nsigs++; - } - -/** -\ingroup Core_Keys -\brief Add selfsigned User ID to key -\param keydata Key to which to add user ID -\param userid Self-signed User ID to add -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_add_selfsigned_userid_to_keydata(ops_keydata_t* keydata, ops_user_id_t* userid) - { - ops_packet_t sigpacket; - - ops_memory_t* mem_userid=NULL; - ops_create_info_t* cinfo_userid=NULL; - - ops_memory_t* mem_sig=NULL; - ops_create_info_t* cinfo_sig=NULL; - - ops_create_signature_t *sig=NULL; - - /* - * create signature packet for this userid - */ - - // create userid pkt - ops_setup_memory_write(&cinfo_userid, &mem_userid, 128); - ops_write_struct_user_id(userid, cinfo_userid); - - // create sig for this pkt - - sig=ops_create_signature_new(); - ops_signature_start_key_signature(sig, &keydata->key.skey.public_key, userid, OPS_CERT_POSITIVE); - ops_signature_add_creation_time(sig,time(NULL)); - ops_signature_add_issuer_key_id(sig,keydata->key_id); - ops_signature_add_primary_user_id(sig, ops_true); - ops_signature_hashed_subpackets_end(sig); - - ops_setup_memory_write(&cinfo_sig, &mem_sig, 128); - ops_write_signature(sig,&keydata->key.skey.public_key,&keydata->key.skey, cinfo_sig); - - // add this packet to keydata - - sigpacket.length=ops_memory_get_length(mem_sig); - sigpacket.raw=ops_memory_get_data(mem_sig); - - // add userid to keydata - ops_add_signed_userid_to_keydata(keydata, userid, &sigpacket); - - // cleanup - ops_create_signature_delete(sig); - ops_create_info_delete(cinfo_userid); - ops_create_info_delete(cinfo_sig); - ops_memory_free(mem_userid); - ops_memory_free(mem_sig); - - return ops_true; - } - -/** -\ingroup Core_Keys -\brief Add signature to given key -\return ops_true if OK; else ops_false -*/ -ops_boolean_t ops_sign_key(ops_keydata_t* keydata, const unsigned char *signers_key_id,ops_secret_key_t *signers_key) -{ -/* ops_memory_t* mem_userid=NULL; */ - ops_memory_t* mem_sig=NULL; - ops_create_info_t* cinfo_sig=NULL; - - ops_create_signature_t *sig=NULL; - - /* - * create signature packet for this userid - */ - - // create sig for this pkt - - sig=ops_create_signature_new(); - ops_signature_start_key_signature(sig, &keydata->key.skey.public_key, &keydata->uids[0], OPS_CERT_GENERIC); - ops_signature_add_creation_time(sig,time(NULL)); - ops_signature_add_issuer_key_id(sig,signers_key_id); - ops_signature_hashed_subpackets_end(sig); - - ops_setup_memory_write(&cinfo_sig, &mem_sig, 128); - ops_write_signature(sig,&signers_key->public_key,signers_key, cinfo_sig); - - // add this packet to keydata - - ops_packet_t sigpacket; - sigpacket.length=ops_memory_get_length(mem_sig); - sigpacket.raw=ops_memory_get_data(mem_sig); - - // add userid to keydata - ops_add_packet_to_keydata(keydata, &sigpacket); - - // cleanup - ops_create_signature_delete(sig); - ops_create_info_delete(cinfo_sig); - ops_memory_free(mem_sig); - - return ops_true; -} -/** -\ingroup Core_Keys -\brief Initialise ops_keydata_t -\param keydata Keydata to initialise -\param type OPS_PTAG_CT_PUBLIC_KEY or OPS_PTAG_CT_SECRET_KEY -*/ -void ops_keydata_init(ops_keydata_t* keydata, const ops_content_tag_t type) - { - assert(keydata->type==OPS_PTAG_CT_RESERVED); - assert(type==OPS_PTAG_CT_PUBLIC_KEY || type==OPS_PTAG_CT_SECRET_KEY); - - keydata->type=type; - } - -/** - Example Usage: - \code - - // definition of variables - ops_keyring_t keyring; - char* filename="~/.gnupg/pubring.gpg"; - - // Read keyring from file - ops_keyring_read_from_file(&keyring,filename); - - // do actions using keyring - ... - - // Free memory alloc-ed in ops_keyring_read_from_file() - ops_keyring_free(keyring); - \endcode -*/ - -static ops_parse_cb_return_t -cb_keyring_read(const ops_parser_content_t *content_, - ops_parse_cb_info_t *cbinfo); - -/** - \ingroup HighLevel_KeyringRead - - \brief Reads a keyring from a file - - \param keyring Pointer to an existing ops_keyring_t struct - \param armour ops_true if file is armoured; else ops_false - \param filename Filename of keyring to be read - - \return ops true if OK; ops_false on error - - \note Keyring struct must already exist. - - \note Can be used with either a public or secret keyring. - - \note You must call ops_keyring_free() after usage to free alloc-ed memory. - - \note If you call this twice on the same keyring struct, without calling - ops_keyring_free() between these calls, you will introduce a memory leak. - - \sa ops_keyring_read_from_mem() - \sa ops_keyring_free() - - Example code: - \code - ops_keyring_t* keyring=ops_mallocz(sizeof *keyring); - ops_boolean_t armoured=ops_false; - ops_keyring_read_from_file(keyring, armoured, "~/.gnupg/pubring.gpg"); - ... - ops_keyring_free(keyring); - free (keyring); - - \endcode -*/ - -ops_boolean_t ops_keyring_read_from_file(ops_keyring_t *keyring, const ops_boolean_t armour, const char *filename) - { - ops_parse_info_t *pinfo; - int fd; - ops_boolean_t res = ops_true; - - pinfo=ops_parse_info_new(); - - // add this for the moment, - // \todo need to fix the problems with reading signature subpackets later - - // ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); - ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); - - fd=ops_open(filename,O_RDONLY | O_BINARY, 0); - - if(fd < 0) - { - ops_parse_info_delete(pinfo); - perror(filename); - return ops_false; - } - - ops_reader_set_fd(pinfo,fd); - - ops_parse_cb_set(pinfo,cb_keyring_read,NULL); - - if (armour) - { ops_reader_push_dearmour(pinfo); } - - if ( ops_parse_and_accumulate(keyring,pinfo) == 0 ) { - res = ops_false; - } - else - { - res = ops_true; - } - ops_print_errors(ops_parse_info_get_errors(pinfo)); - - if (armour) - ops_reader_pop_dearmour(pinfo); - - close(fd); - - ops_parse_info_delete(pinfo); - - return res; - } - -/** - \ingroup HighLevel_KeyringRead - - \brief Reads a keyring from memory - - \param keyring Pointer to existing ops_keyring_t struct - \param armour ops_true if file is armoured; else ops_false - \param mem Pointer to a ops_memory_t struct containing keyring to be read - - \return ops true if OK; ops_false on error - - \note Keyring struct must already exist. - - \note Can be used with either a public or secret keyring. - - \note You must call ops_keyring_free() after usage to free alloc-ed memory. - - \note If you call this twice on the same keyring struct, without calling - ops_keyring_free() between these calls, you will introduce a memory leak. - - \sa ops_keyring_read_from_file - \sa ops_keyring_free - - Example code: - \code - ops_memory_t* mem; // Filled with keyring packets - ops_keyring_t* keyring=ops_mallocz(sizeof *keyring); - ops_boolean_t armoured=ops_false; - ops_keyring_read_from_mem(keyring, armoured, mem); - ... - ops_keyring_free(keyring); - free (keyring); - \endcode -*/ -ops_boolean_t ops_keyring_read_from_mem(ops_keyring_t *keyring, const ops_boolean_t armour, ops_memory_t* mem) - { - ops_parse_info_t *pinfo=NULL; - ops_boolean_t res = ops_true; - - ops_setup_memory_read(&pinfo, mem, NULL, cb_keyring_read, - OPS_ACCUMULATE_NO); - ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); - - if (armour) - { ops_reader_push_dearmour(pinfo); } - - if ( ops_parse_and_accumulate(keyring,pinfo) == 0 ) - { - res = ops_false; - } - else - { - res = ops_true; - } - ops_print_errors(ops_parse_info_get_errors(pinfo)); - - if (armour) - ops_reader_pop_dearmour(pinfo); - - // don't call teardown_memory_read because memory was passed - // in. But we need to free the parse_info object allocated by - // ops_setup_memory_read(). - ops_parse_info_delete(pinfo); - - return res; - } - -/** - \ingroup HighLevel_KeyringRead - - \brief Frees keyring's contents (but not keyring itself) - - \param keyring Keyring whose data is to be freed - - \note This does not free keyring itself, just the memory alloc-ed in it. - */ -void ops_keyring_free(ops_keyring_t *keyring) - { - int i; - - for (i = 0; i < keyring->nkeys; i++) - keydata_internal_free(&keyring->keys[i]); - - free(keyring->keys); - keyring->keys=NULL; - keyring->nkeys=0; - keyring->nkeys_allocated=0; - } - -void ops_keyring_remove_key(ops_keyring_t *keyring,int index) -{ - if(index > keyring->nkeys-1) - { - fprintf(stderr,"ops_keyring_remove_key: ERROR: cannot remove key with index %d > %d.",index,keyring->nkeys-1) ; - return ; - } - - if(index < keyring->nkeys-1) - ops_keydata_copy(&keyring->keys[index],&keyring->keys[keyring->nkeys-1]) ; - - keydata_internal_free(&keyring->keys[keyring->nkeys-1]) ; - keyring->nkeys-- ; - - // keyring->nkeys_allocated is left untouched intentionnaly. -} - -/** - \ingroup HighLevel_KeyringFind - - \brief Finds key in keyring from its Key ID - - \param keyring Keyring to be searched - \param keyid ID of required key - - \return Pointer to key, if found; NULL, if not found - - \note This returns a pointer to the key inside the given keyring, not a copy. Do not free it after use. - - Example code: - \code - void example(ops_keyring_t* keyring) - { - ops_keydata_t* keydata=NULL; - unsigned char keyid[OPS_KEY_ID_SIZE]; // value set elsewhere - keydata=ops_keyring_find_key_by_id(keyring,keyid); - ... - } - \endcode -*/ -const ops_keydata_t * -ops_keyring_find_key_by_id(const ops_keyring_t *keyring, - const unsigned char keyid[OPS_KEY_ID_SIZE]) - { - int n; - - if (!keyring) - return NULL; - - for(n=0 ; n < keyring->nkeys ; ++n) - { - if(!memcmp(keyring->keys[n].key_id,keyid,OPS_KEY_ID_SIZE)) - return &keyring->keys[n]; - } - - return NULL; - } - -/** - \ingroup HighLevel_KeyringFind - - \brief Finds key from its User ID - - \param keyring Keyring to be searched - \param userid User ID of required key - - \return Pointer to Key, if found; NULL, if not found - - \note This returns a pointer to the key inside the keyring, not a copy. Do not free it. - - Example code: - \code - void example(ops_keyring_t* keyring) - { - ops_keydata_t* keydata=NULL; - keydata=ops_keyring_find_key_by_userid(keyring,"user@domain.com"); - ... - } - \endcode -*/ -const ops_keydata_t * -ops_keyring_find_key_by_userid(const ops_keyring_t *keyring, - const char *userid) - { - int n=0; - unsigned int i=0; - - if (!keyring) - return NULL; - - for(n=0 ; n < keyring->nkeys ; ++n) - { - for(i=0; ikeys[n].nuids; i++) - { - //printf("[%d][%d] userid %s\n",n,i,keyring->keys[n].uids[i].user_id); - if(!strncmp((char *)keyring->keys[n].uids[i].user_id,userid,strlen(userid))) - return &keyring->keys[n]; - } - } - - //printf("end: n=%d,i=%d\n",n,i); - return NULL; - } - -/** - \ingroup HighLevel_KeyringList - - \brief Prints all keys in keyring to stdout. - - \param keyring Keyring to use - - \return none - - Example code: - \code - void example() - { - ops_keyring_t* keyring=ops_mallocz(sizeof *keyring); - ops_boolean_t armoured=ops_false; - ops_keyring_read_from_file(keyring, armoured, "~/.gnupg/pubring.gpg"); - - ops_keyring_list(keyring); - - ops_keyring_free(keyring); - free (keyring); - } - \endcode -*/ - -void -ops_keyring_list(const ops_keyring_t* keyring) - { - int n; - unsigned int i; - ops_keydata_t* key; - - printf ("%d keys\n", keyring->nkeys); - for(n=0,key=&keyring->keys[n] ; n < keyring->nkeys ; ++n,++key) - { - for(i=0; inuids; i++) - { - if (ops_is_key_secret(key)) - ops_print_secret_keydata(key); - else - ops_print_public_keydata(key); - } - - } - } - -/* Static functions */ - -static ops_parse_cb_return_t -cb_keyring_read(const ops_parser_content_t *content_, - ops_parse_cb_info_t *cbinfo) -{ - OPS_USED(cbinfo); - - switch(content_->tag) - { - case OPS_PARSER_PTAG: - case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: // we get these because we didn't prompt - case OPS_PTAG_CT_SIGNATURE_HEADER: - case OPS_PTAG_CT_SIGNATURE_FOOTER: - case OPS_PTAG_CT_SIGNATURE: - case OPS_PTAG_CT_TRUST: - case OPS_PARSER_ERRCODE: - break; - - default: - ; - } - - return OPS_RELEASE_MEMORY; -} - -/** - \ingroup HighLevel_KeyringList - - \brief Saves keyring to specified file - - \param keyring Keyring to save - \param armoured Save in ascii armoured format - \param output filename - - \return ops_true is anything when ok -*/ - -ops_boolean_t ops_write_keyring_to_file(const ops_keyring_t *keyring,ops_boolean_t armoured,const char *filename,ops_boolean_t write_all_packets) -{ - ops_create_info_t *info; - int fd = ops_setup_file_write(&info, filename, ops_true); - - if (fd < 0) - { - fprintf(stderr,"ops_write_keyring(): ERROR: Cannot write to %s\n",filename ) ; - return ops_false ; - } - - int i; - for(i=0;inkeys;++i) -// if(keyring->keys[i].key.pkey.algorithm == OPS_PKA_RSA) - if(write_all_packets) - ops_write_transferable_public_key_from_packet_data(&keyring->keys[i],armoured,info) ; - else - ops_write_transferable_public_key(&keyring->keys[i],armoured,info) ; -// else -// { -// fprintf(stdout, "ops_write_keyring: not writing key. Algorithm not handled: ") ; -// ops_print_public_keydata(&keyring->keys[i]); -// fprintf(stdout, "\n") ; -// } - - ops_teardown_file_write(info, fd); - - return ops_true ; -} - -/*\@}*/ - -// eof diff --git a/openpgpsdk/src/openpgpsdk/keyring.h b/openpgpsdk/src/openpgpsdk/keyring.h deleted file mode 100644 index 028416cec..000000000 --- a/openpgpsdk/src/openpgpsdk/keyring.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_KEYRING_H -#define OPS_KEYRING_H - -#include "packet.h" -#include "memory.h" - -typedef struct ops_keydata ops_keydata_t; - -/** \struct ops_keyring_t - * A keyring - */ - -typedef struct - { - int nkeys; // while we are constructing a key, this is the offset - int nkeys_allocated; - ops_keydata_t *keys; - } ops_keyring_t; - -const ops_keydata_t * -ops_keyring_find_key_by_id(const ops_keyring_t *keyring, - const unsigned char keyid[OPS_KEY_ID_SIZE]); -const ops_keydata_t * -ops_keyring_find_key_by_userid(const ops_keyring_t *keyring, - const char* userid); -void ops_keydata_free(ops_keydata_t *key); -void ops_keydata_copy(ops_keydata_t *dst,const ops_keydata_t *src); -void ops_keyring_free(ops_keyring_t *keyring); -void ops_dump_keyring(const ops_keyring_t *keyring); -const ops_public_key_t * -ops_get_public_key_from_data(const ops_keydata_t *data); -ops_boolean_t ops_is_key_secret(const ops_keydata_t *data); -const ops_secret_key_t * -ops_get_secret_key_from_data(const ops_keydata_t *data); -ops_secret_key_t * -ops_get_writable_secret_key_from_data(ops_keydata_t *data); -ops_secret_key_t *ops_decrypt_secret_key_from_data(const ops_keydata_t *key, - const char *pphrase); - -ops_boolean_t ops_keyring_read_from_file(ops_keyring_t *keyring, const ops_boolean_t armour, const char *filename); -ops_boolean_t ops_keyring_read_from_mem(ops_keyring_t *keyring, const ops_boolean_t armour, ops_memory_t *mem); -ops_boolean_t ops_write_keyring_to_file(const ops_keyring_t *keyring,ops_boolean_t armoured,const char *filename,ops_boolean_t write_all_packets); - -char *ops_malloc_passphrase(char *passphrase); -char *ops_get_passphrase(void); - -void ops_keyring_list(const ops_keyring_t* keyring); - -void ops_set_secret_key(ops_parser_content_union_t* content,const ops_keydata_t *key); - -const unsigned char* ops_get_key_id(const ops_keydata_t *key); -unsigned ops_get_user_id_count(const ops_keydata_t *key); -const unsigned char* ops_get_user_id(const ops_keydata_t *key, unsigned index); -ops_boolean_t ops_is_key_supported(const ops_keydata_t *key); -const ops_keydata_t* ops_keyring_get_key_by_index(const ops_keyring_t *keyring, int index); -void ops_keyring_remove_key(ops_keyring_t *keyring,int index) ; - -ops_user_id_t* ops_add_userid_to_keydata(ops_keydata_t* keydata, const ops_user_id_t* userid); -ops_packet_t* ops_add_packet_to_keydata(ops_keydata_t* keydata, const ops_packet_t* packet); -void ops_add_signed_userid_to_keydata(ops_keydata_t* keydata, const ops_user_id_t* userid, const ops_packet_t* packet); - -ops_boolean_t ops_add_selfsigned_userid_to_keydata(ops_keydata_t* keydata, ops_user_id_t* userid); -ops_boolean_t ops_sign_key(ops_keydata_t* keydata_to_sign, const unsigned char *signers_key_id,ops_secret_key_t *signers_decrypted_private_key); - -ops_keydata_t *ops_keydata_new(void); -void ops_keydata_init(ops_keydata_t* keydata, const ops_content_tag_t type); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/keyring_local.h b/openpgpsdk/src/openpgpsdk/keyring_local.h deleted file mode 100644 index 5c3860f35..000000000 --- a/openpgpsdk/src/openpgpsdk/keyring_local.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include - -#define DECLARE_ARRAY(type,arr) unsigned n##arr; unsigned n##arr##_allocated; type *arr -#define EXPAND_ARRAY(str,arr) do if(str->n##arr == str->n##arr##_allocated) \ - { \ - str->n##arr##_allocated=str->n##arr##_allocated*2+10; \ - str->arr=realloc(str->arr,str->n##arr##_allocated*sizeof *str->arr); \ - } while(0) - -/** ops_keydata_key_t - */ -typedef union - { - ops_public_key_t pkey; - ops_secret_key_t skey; - } ops_keydata_key_t; - - -/** sigpacket_t */ -typedef struct - { - ops_user_id_t* userid; - ops_packet_t* packet; - } sigpacket_t; - -// XXX: gonna have to expand this to hold onto subkeys, too... -/** \struct ops_keydata - * \todo expand to hold onto subkeys - */ -struct ops_keydata - { - DECLARE_ARRAY(ops_user_id_t,uids); - DECLARE_ARRAY(ops_packet_t,packets); - DECLARE_ARRAY(sigpacket_t, sigs); - unsigned char key_id[8]; - ops_fingerprint_t fingerprint; - ops_content_tag_t type; - ops_keydata_key_t key; - }; diff --git a/openpgpsdk/src/openpgpsdk/lists.c b/openpgpsdk/src/openpgpsdk/lists.c deleted file mode 100644 index 5be1e2e2c..000000000 --- a/openpgpsdk/src/openpgpsdk/lists.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * \file - * - * Set of functions to manage a dynamic list - */ - -#include - -#include - -#include - -/** - * \ingroup Core_Lists - * \brief Initialises ulong list - * \param *list Pointer to existing list structure - */ -void ops_ulong_list_init(ops_ulong_list_t *list) - { - list->size=0; - list->used=0; - list->ulongs=NULL; - } - -/** - * \ingroup Core_Lists - * \brief Frees allocated memory in ulong list. Does not free *list itself. - * \param *list - */ -void ops_ulong_list_free(ops_ulong_list_t *list) - { - if (list->ulongs) - free(list->ulongs); - ops_ulong_list_init(list); - } - -/** - * \ingroup Core_Lists - * \brief Resizes ulong list. - * - * We only resize in one direction - upwards. - * Algorithm used : double the current size then add 1 - * - * \param *list Pointer to list - * \return 1 if success, else 0 - */ - -static unsigned int ops_ulong_list_resize(ops_ulong_list_t *list) - { - - int newsize=0; - - newsize=list->size*2 + 1; - list->ulongs=realloc(list->ulongs,newsize*sizeof *list->ulongs); - if (list->ulongs) - { - list->size=newsize; - return 1; - } - else - { - /* xxx - realloc failed. error message? - rachel */ - return 0; - } - } - -/** - * \ingroup Core_Lists - * Adds entry to ulong list - * - * \param *list - * \param *ulong - * - * \return 1 if success, else 0 - */ -unsigned int ops_ulong_list_add(ops_ulong_list_t *list, unsigned long *ulong) - { - if (list->size==list->used) - if (!ops_ulong_list_resize(list)) - return 0; - - list->ulongs[list->used]=*ulong; - list->used++; - return 1; - } - diff --git a/openpgpsdk/src/openpgpsdk/lists.h b/openpgpsdk/src/openpgpsdk/lists.h deleted file mode 100644 index 520b1d432..000000000 --- a/openpgpsdk/src/openpgpsdk/lists.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_LISTS_H -#define OPS_LISTS_H - -/** ops_ulong_list_t */ -typedef struct - { - unsigned int size;/* num of array slots allocated */ - unsigned int used; /* num of array slots currently used */ - unsigned long *ulongs; - } ops_ulong_list_t; - -void ops_ulong_list_init(ops_ulong_list_t *list); -void ops_ulong_list_free(ops_ulong_list_t *list); -unsigned int ops_ulong_list_add(ops_ulong_list_t *list, unsigned long *ulong); - -#endif /* OPS_LISTS_H */ diff --git a/openpgpsdk/src/openpgpsdk/literal.h b/openpgpsdk/src/openpgpsdk/literal.h deleted file mode 100644 index 8b1c30e6b..000000000 --- a/openpgpsdk/src/openpgpsdk/literal.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OPS_LITERAL_H__ -#define __OPS_LITERAL_H__ - - -ops_boolean_t write_literal_header(ops_create_info_t *info, - void *header_data); - -void ops_writer_push_literal(ops_create_info_t *info); -void ops_writer_push_literal_with_opts(ops_create_info_t *info, - unsigned int buf_size); - -#endif /* __OPS_LITERAL_H__ */ - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/memory.c b/openpgpsdk/src/openpgpsdk/memory.c deleted file mode 100644 index 4093e5657..000000000 --- a/openpgpsdk/src/openpgpsdk/memory.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include - -#include - -struct ops_memory - { - unsigned char *buf; - size_t length; - size_t allocated; - }; - -/** -\ingroup HighLevel_Memory -\brief Memory to initialise -\param mem memory to initialise -\param initial_size Size to initialise to -*/ -void ops_memory_init(ops_memory_t *mem,size_t initial_size) - { - mem->length=0; - if(mem->buf) - { - if(mem->allocated < initial_size) - { - mem->buf=realloc(mem->buf,initial_size); - mem->allocated=initial_size; - } - return; - } - mem->buf=malloc(initial_size); - mem->allocated=initial_size; - } - -/** -\ingroup HighLevel_Memory -\brief Pad memory to required length -\param mem Memory to use -\param length New size -*/ -void ops_memory_pad(ops_memory_t *mem,size_t length) - { - assert(mem->allocated >= mem->length); - if(mem->allocated < mem->length+length) - { - mem->allocated=mem->allocated*2+length; - mem->buf=realloc(mem->buf,mem->allocated); - } - assert(mem->allocated >= mem->length+length); - } - -/** -\ingroup HighLevel_Memory -\brief Add data to memory -\param mem Memory to which to add -\param src Data to add -\param length Length of data to add -*/ -void ops_memory_add(ops_memory_t *mem,const unsigned char *src,size_t length) - { - ops_memory_pad(mem,length); - memcpy(mem->buf+mem->length,src,length); - mem->length+=length; - } - -// XXX: this could be refactored via the writer, but an awful lot of -// hoops to jump through for 2 lines of code! -void ops_memory_place_int(ops_memory_t *mem,unsigned offset,unsigned n, - size_t length) - { - assert(mem->allocated >= offset+length); - - while(length--) - mem->buf[offset++]=n >> (length*8); - } - -/** - * \ingroup HighLevel_Memory - * \brief Retains allocated memory and set length of stored data to zero. - * \param mem Memory to clear - * \sa ops_memory_release() - * \sa ops_memory_free() - */ -void ops_memory_clear(ops_memory_t *mem) - { mem->length=0; } - -/** -\ingroup HighLevel_Memory -\brief Free memory and associated data -\param mem Memory to free -\note This does not free mem itself -\sa ops_memory_clear() -\sa ops_memory_free() -*/ -void ops_memory_release(ops_memory_t *mem) - { - free(mem->buf); - mem->buf=NULL; - mem->length=0; - } - -void ops_memory_make_packet(ops_memory_t *out,ops_content_tag_t tag) - { - size_t extra; - - if(out->length < 192) - extra=1; - else if(out->length < 8384) - extra=2; - else - extra=5; - - ops_memory_pad(out,extra+1); - memmove(out->buf+extra+1,out->buf,out->length); - - out->buf[0]=OPS_PTAG_ALWAYS_SET|OPS_PTAG_NEW_FORMAT|tag; - - if(out->length < 192) - out->buf[1]=out->length; - else if(out->length < 8384) - { - out->buf[1]=((out->length-192) >> 8)+192; - out->buf[2]=out->length-192; - } - else - { - out->buf[1]=0xff; - out->buf[2]=out->length >> 24; - out->buf[3]=out->length >> 16; - out->buf[4]=out->length >> 8; - out->buf[5]=out->length; - } - - out->length+=extra+1; - } - -/** - \ingroup HighLevel_Memory - \brief Create a new zeroed ops_memory_t - \return Pointer to new ops_memory_t - \note Free using ops_memory_free() after use. - \sa ops_memory_free() -*/ - -ops_memory_t *ops_memory_new() - { return ops_mallocz(sizeof(ops_memory_t)); } - -/** - \ingroup HighLevel_Memory - \brief Free memory ptr and associated memory - \param mem Memory to be freed - \sa ops_memory_release() - \sa ops_memory_clear() -*/ - -void ops_memory_free(ops_memory_t *mem) - { - ops_memory_release(mem); - free(mem); - } - -/** - \ingroup HighLevel_Memory - \brief Get length of data stored in ops_memory_t struct - \return Number of bytes in data -*/ -size_t ops_memory_get_length(const ops_memory_t *mem) - { return mem->length; } - -/** - \ingroup HighLevel_Memory - \brief Get data stored in ops_memory_t struct - \return Pointer to data -*/ -void *ops_memory_get_data(ops_memory_t *mem) - { return mem->buf; } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/memory.h b/openpgpsdk/src/openpgpsdk/memory.h deleted file mode 100644 index 3fa098026..000000000 --- a/openpgpsdk/src/openpgpsdk/memory.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include "packet.h" - -#ifndef OPS_MEMORY_H -#define OPS_MEMORY_H - -/** ops_memory_t - */ -typedef struct ops_memory ops_memory_t; - -ops_memory_t *ops_memory_new(void); -void ops_memory_free(ops_memory_t *mem); -void ops_memory_init(ops_memory_t *mem,size_t initial_size); -void ops_memory_pad(ops_memory_t *mem,size_t length); -void ops_memory_add(ops_memory_t *mem,const unsigned char *src,size_t length); -void ops_memory_place_int(ops_memory_t *mem,unsigned offset,unsigned n, - size_t length); -void ops_memory_make_packet(ops_memory_t *out,ops_content_tag_t tag); -void ops_memory_clear(ops_memory_t *mem); -void ops_memory_release(ops_memory_t *mem); - -void ops_writer_set_memory(ops_create_info_t *info,ops_memory_t *mem); - -size_t ops_memory_get_length(const ops_memory_t *mem); -void *ops_memory_get_data(ops_memory_t *mem); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/openssl_crypto.c b/openpgpsdk/src/openpgpsdk/openssl_crypto.c deleted file mode 100644 index 086dad77a..000000000 --- a/openpgpsdk/src/openpgpsdk/openssl_crypto.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "keyring_local.h" -#include - -#include - -static int debug=0; - -void test_secret_key(const ops_secret_key_t *skey) - { - RSA* test=RSA_new(); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - test->n=BN_dup(skey->public_key.key.rsa.n); - test->e=BN_dup(skey->public_key.key.rsa.e); - test->d=BN_dup(skey->key.rsa.d); - - test->p=BN_dup(skey->key.rsa.p); - test->q=BN_dup(skey->key.rsa.q); -#else - RSA_set0_key(test, - BN_dup(skey->public_key.key.rsa.n), - BN_dup(skey->public_key.key.rsa.e), - BN_dup(skey->key.rsa.d)); - - RSA_set0_factors(test, BN_dup(skey->key.rsa.p), BN_dup(skey->key.rsa.q)); -#endif - - assert(RSA_check_key(test)==1); - RSA_free(test); - } - -static void md5_init(ops_hash_t *hash) - { - assert(!hash->data); - hash->data=malloc(sizeof(MD5_CTX)); - MD5_Init(hash->data); - } - -static void md5_add(ops_hash_t *hash,const unsigned char *data,unsigned length) - { - MD5_Update(hash->data,data,length); - } - -static unsigned md5_finish(ops_hash_t *hash,unsigned char *out) - { - MD5_Final(out,hash->data); - free(hash->data); - hash->data=NULL; - return 16; - } - -static ops_hash_t md5={OPS_HASH_MD5,MD5_DIGEST_LENGTH,"MD5",md5_init,md5_add, - md5_finish,NULL}; - -/** - \ingroup Core_Crypto - \brief Initialise to MD5 - \param hash Hash to initialise -*/ -void ops_hash_md5(ops_hash_t *hash) - { - *hash=md5; - } - -static void sha1_init(ops_hash_t *hash) - { - if (debug) - { - fprintf(stderr,"***\n***\nsha1_init\n***\n"); - } - assert(!hash->data); - hash->data=malloc(sizeof(SHA_CTX)); - SHA1_Init(hash->data); - } - -static void sha1_add(ops_hash_t *hash,const unsigned char *data, - unsigned length) - { - if (debug) - { - unsigned int i=0; - fprintf(stderr,"adding %d to hash:\n ", length); - for (i=0; idata,data,length); - } - -static unsigned sha1_finish(ops_hash_t *hash,unsigned char *out) - { - SHA1_Final(out,hash->data); - if (debug) - { - unsigned i=0; - fprintf(stderr,"***\n***\nsha1_finish\n***\n"); - for (i=0; idata); - hash->data=NULL; - return SHA_DIGEST_LENGTH; - } - -static ops_hash_t sha1={OPS_HASH_SHA1,SHA_DIGEST_LENGTH,"SHA1",sha1_init, - sha1_add,sha1_finish,NULL}; - -/** - \ingroup Core_Crypto - \brief Initialise to SHA1 - \param hash Hash to initialise -*/ -void ops_hash_sha1(ops_hash_t *hash) - { - *hash=sha1; - } - -static void sha256_init(ops_hash_t *hash) - { - if (debug) - { - fprintf(stderr,"***\n***\nsha256_init\n***\n"); - } - assert(!hash->data); - hash->data=malloc(sizeof(SHA256_CTX)); - SHA256_Init(hash->data); - } - -static void sha256_add(ops_hash_t *hash,const unsigned char *data, - unsigned length) - { - if (debug) - { - unsigned int i=0; - fprintf(stderr,"adding %d to hash:\n ", length); - for (i=0; idata,data,length); - } - -static unsigned sha256_finish(ops_hash_t *hash,unsigned char *out) - { - SHA256_Final(out,hash->data); - if (debug) - { - unsigned i=0; - fprintf(stderr,"***\n***\nsha1_finish\n***\n"); - for (i=0; idata); - hash->data=NULL; - return SHA256_DIGEST_LENGTH; - } - -static ops_hash_t sha256={OPS_HASH_SHA256,SHA256_DIGEST_LENGTH,"SHA256",sha256_init, - sha256_add,sha256_finish,NULL}; - -void ops_hash_sha256(ops_hash_t *hash) - { - *hash=sha256; - } - -/* - * SHA384 - */ - -static void sha384_init(ops_hash_t *hash) - { - if (debug) - { - fprintf(stderr,"***\n***\nsha384_init\n***\n"); - } - assert(!hash->data); - hash->data=malloc(sizeof(SHA512_CTX)); - SHA384_Init(hash->data); - } - -static void sha384_add(ops_hash_t *hash,const unsigned char *data, - unsigned length) - { - if (debug) - { - unsigned int i=0; - fprintf(stderr,"adding %d to hash:\n ", length); - for (i=0; idata,data,length); - } - -static unsigned sha384_finish(ops_hash_t *hash,unsigned char *out) - { - SHA384_Final(out,hash->data); - if (debug) - { - unsigned i=0; - fprintf(stderr,"***\n***\nsha1_finish\n***\n"); - for (i=0; idata); - hash->data=NULL; - return SHA384_DIGEST_LENGTH; - } - -static ops_hash_t sha384={OPS_HASH_SHA384,SHA384_DIGEST_LENGTH,"SHA384",sha384_init, - sha384_add,sha384_finish,NULL}; - -void ops_hash_sha384(ops_hash_t *hash) - { - *hash=sha384; - } - -/* - * SHA512 - */ - -static void sha512_init(ops_hash_t *hash) - { - if (debug) - { - fprintf(stderr,"***\n***\nsha512_init\n***\n"); - } - assert(!hash->data); - hash->data=malloc(sizeof(SHA512_CTX)); - SHA512_Init(hash->data); - } - -static void sha512_add(ops_hash_t *hash,const unsigned char *data, - unsigned length) - { - if (debug) - { - unsigned int i=0; - fprintf(stderr,"adding %d to hash:\n ", length); - for (i=0; idata,data,length); - } - -static unsigned sha512_finish(ops_hash_t *hash,unsigned char *out) - { - SHA512_Final(out,hash->data); - if (debug) - { - unsigned i=0; - fprintf(stderr,"***\n***\nsha1_finish\n***\n"); - for (i=0; idata); - hash->data=NULL; - return SHA512_DIGEST_LENGTH; - } - -static ops_hash_t sha512={OPS_HASH_SHA512,SHA512_DIGEST_LENGTH,"SHA512",sha512_init, - sha512_add,sha512_finish,NULL}; - -void ops_hash_sha512(ops_hash_t *hash) - { - *hash=sha512; - } - -/* - * SHA224 - */ - -static void sha224_init(ops_hash_t *hash) - { - if (debug) - { - fprintf(stderr,"***\n***\nsha1_init\n***\n"); - } - assert(!hash->data); - hash->data=malloc(sizeof(SHA256_CTX)); - SHA224_Init(hash->data); - } - -static void sha224_add(ops_hash_t *hash,const unsigned char *data, - unsigned length) - { - if (debug) - { - unsigned int i=0; - fprintf(stderr,"adding %d to hash:\n ", length); - for (i=0; idata,data,length); - } - -static unsigned sha224_finish(ops_hash_t *hash,unsigned char *out) - { - SHA224_Final(out,hash->data); - if (debug) - { - unsigned i=0; - fprintf(stderr,"***\n***\nsha1_finish\n***\n"); - for (i=0; idata); - hash->data=NULL; - return SHA224_DIGEST_LENGTH; - } - -static ops_hash_t sha224={OPS_HASH_SHA224,SHA224_DIGEST_LENGTH,"SHA224",sha224_init, - sha224_add,sha224_finish,NULL}; - -void ops_hash_sha224(ops_hash_t *hash) - { - *hash=sha224; - } - -ops_boolean_t already_said = ops_false ; - -ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length, - const ops_dsa_signature_t *sig, - const ops_dsa_public_key_t *dsa) - { - DSA_SIG *osig; - DSA *odsa; - int ret; - - osig=DSA_SIG_new(); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - osig->r=sig->r; - osig->s=sig->s; -#else - DSA_SIG_set0(osig,BN_dup(sig->r),BN_dup(sig->s)) ; -#endif - - if(BN_num_bits(dsa->q) != 160) - { - if(!already_said) - { - fprintf(stderr,"(WW) ops_dsa_verify: openssl does only supports 'q' of 160 bits. Current is %d bits.\n",BN_num_bits(dsa->q)) ; - already_said=ops_true ; - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - osig->r=NULL; // in this case, the values are not copied. - osig->s=NULL; -#endif - - DSA_SIG_free(osig); - return ops_false ; - } - - odsa=DSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - odsa->p=dsa->p; - odsa->q=dsa->q; - odsa->g=dsa->g; - - odsa->pub_key=dsa->y; -#else - DSA_set0_pqg(odsa,BN_dup(dsa->p),BN_dup(dsa->q),BN_dup(dsa->g)); - DSA_set0_key(odsa,BN_dup(dsa->y),NULL) ; -#endif - - if (debug) - { - fprintf(stderr,"hash passed in:\n"); - unsigned i; - for (i=0; iq)); - unsigned int qlen=BN_num_bytes(dsa->q); - - if (qlen < hash_length) - hash_length=qlen; - // ret=DSA_do_verify(hash,hash_length,osig,odsa); - ret=DSA_do_verify(hash,hash_length,osig,odsa); - if (debug) - { - fprintf(stderr,"ret=%d\n",ret); - } - - if(ret < 0) - { - ERR_load_crypto_strings() ; - unsigned long err = 0 ; - while((err = ERR_get_error()) > 0) - fprintf(stderr,"DSA_do_verify(): ERR = %ld. lib error:\"%s\", func_error:\"%s\", reason:\"%s\"\n",err,ERR_lib_error_string(err),ERR_func_error_string(err),ERR_reason_error_string(err)) ; - //assert(ret >= 0); - return ops_false ; - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - osig->r=NULL; - osig->s=NULL; - - odsa->p=NULL; - odsa->q=NULL; - odsa->g=NULL; - odsa->pub_key=NULL; -#endif - - DSA_free(odsa); - DSA_SIG_free(osig); - - return ret != 0; - } - -/** - \ingroup Core_Crypto - \brief Recovers message digest from the signature - \param out Where to write decrypted data to - \param in Encrypted data - \param length Length of encrypted data - \param rsa RSA public key - \return size of recovered message digest -*/ -int ops_rsa_public_decrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_public_key_t *rsa) - { - RSA *orsa; - int n; - - orsa=RSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=rsa->n; - orsa->e=rsa->e; -#else - RSA_set0_key(orsa,BN_dup(rsa->n),BN_dup(rsa->e),NULL) ; -#endif - - n=RSA_public_decrypt(length,in,out,orsa,RSA_NO_PADDING); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=orsa->e=NULL; -#endif - RSA_free(orsa); - - return n; - } - -/** - \ingroup Core_Crypto - \brief Signs data with RSA - \param out Where to write signature - \param in Data to sign - \param length Length of data - \param srsa RSA secret key - \param rsa RSA public key - \return number of bytes decrypted -*/ -int ops_rsa_private_encrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_secret_key_t *srsa, - const ops_rsa_public_key_t *rsa) - { - RSA *orsa; - int n; - - orsa=RSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=rsa->n; // XXX: do we need n? - orsa->d=srsa->d; - orsa->p=srsa->q; - orsa->q=srsa->p; - - /* debug */ - orsa->e=rsa->e; - - // If this isn't set, it's very likely that the programmer hasn't - // decrypted the secret key. RSA_check_key segfaults in that case. - // Use ops_decrypt_secret_key_from_data() to do that. - assert(orsa->d); -#else - RSA_set0_key(orsa,BN_dup(rsa->n),BN_dup(rsa->e),BN_dup(srsa->d)) ; - RSA_set0_factors(orsa,BN_dup(srsa->p),BN_dup(srsa->q)); -#endif - - assert(RSA_check_key(orsa) == 1); - /* end debug */ - - // WARNING: this function should *never* be called for direct encryption, because of the padding. - // It's actually only called in the signature function now, where an adapted padding is placed. - - n=RSA_private_encrypt(length,in,out,orsa,RSA_NO_PADDING); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=orsa->d=orsa->p=orsa->q=NULL; - orsa->e=NULL; -#endif - RSA_free(orsa); - - return n; - } - -/** -\ingroup Core_Crypto -\brief Decrypts RSA-encrypted data -\param out Where to write the plaintext -\param in Encrypted data -\param length Length of encrypted data -\param srsa RSA secret key -\param rsa RSA public key -\return size of recovered plaintext -*/ -int ops_rsa_private_decrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_secret_key_t *srsa, - const ops_rsa_public_key_t *rsa) - { - RSA *orsa; - int n; - char errbuf[1024]; - - orsa=RSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=rsa->n; // XXX: do we need n? - orsa->d=srsa->d; - orsa->p=srsa->q; - orsa->q=srsa->p; - orsa->e=rsa->e; -#else - RSA_set0_key(orsa,BN_dup(rsa->n),BN_dup(rsa->e),BN_dup(srsa->d)) ; - RSA_set0_factors(orsa,BN_dup(srsa->p),BN_dup(srsa->q)); -#endif - - /* debug */ - assert(RSA_check_key(orsa) == 1); - /* end debug */ - - n=RSA_private_decrypt(length,in,out,orsa,RSA_NO_PADDING); - - // printf("ops_rsa_private_decrypt: n=%d\n",n); - - errbuf[0]='\0'; - if (n==-1) - { - unsigned long err=ERR_get_error(); - ERR_error_string(err,&errbuf[0]); - fprintf(stderr,"openssl error : %s\n",errbuf); - } -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=orsa->d=orsa->p=orsa->q=NULL; - orsa->e=NULL; -#endif - RSA_free(orsa); - - return n; - } - -/** - \ingroup Core_Crypto - \brief RSA-encrypts data - \param out Where to write the encrypted data - \param in Plaintext - \param length Size of plaintext - \param rsa RSA Public Key -*/ -int ops_rsa_public_encrypt(unsigned char *out,const unsigned char *in, - size_t length,const ops_rsa_public_key_t *rsa) - { - RSA *orsa; - int n; - - // printf("ops_rsa_public_encrypt: length=%ld\n", length); - - orsa=RSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=rsa->n; - orsa->e=rsa->e; -#else - RSA_set0_key(orsa,BN_dup(rsa->n),BN_dup(rsa->e),NULL); -#endif - - // printf("len: %ld\n", length); - // ops_print_bn("n: ", orsa->n); - // ops_print_bn("e: ", orsa->e); - 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_free(fd_out) ; - } - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - orsa->n=orsa->e=NULL; -#endif - RSA_free(orsa); - - return n; - } - -/** - \ingroup Core_Crypto - \brief initialises openssl - \note Would usually call ops_init() instead - \sa ops_init() -*/ -void ops_crypto_init() - { -#ifdef DMALLOC - CRYPTO_malloc_debug_init(); - CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); -#endif - } - -/** - \ingroup Core_Crypto - \brief Finalise openssl - \note Would usually call ops_finish() instead - \sa ops_finish() -*/ -void ops_crypto_finish() - { - CRYPTO_cleanup_all_ex_data(); - // FIXME: what should we do instead (function is deprecated)? - // ERR_remove_state(0); -#ifdef DMALLOC - CRYPTO_mem_leaks_fp(stderr); -#endif - } - -/** - \ingroup Core_Hashes - \brief Get Hash name - \param hash Hash struct - \return Hash name -*/ -const char *ops_text_from_hash(ops_hash_t *hash) - { return hash->name; } - -/** - \ingroup HighLevel_KeyGenerate - \brief Generates an RSA keypair - \param numbits Modulus size - \param e Public Exponent - \param keydata Pointer to keydata struct to hold new key - \return ops_true if key generated successfully; otherwise ops_false - \note It is the caller's responsibility to call ops_keydata_free(keydata) -*/ -ops_boolean_t ops_rsa_generate_keypair(const int numbits, const unsigned long e, - ops_keydata_t* keydata) - { - ops_secret_key_t *skey=NULL; - RSA *rsa=RSA_new(); - BN_CTX *ctx=BN_CTX_new(); - BIGNUM *ebn=BN_new(); - - ops_keydata_init(keydata,OPS_PTAG_CT_SECRET_KEY); - skey=ops_get_writable_secret_key_from_data(keydata); - - // generate the key pair - - BN_set_word(ebn,e); - RSA_generate_key_ex(rsa,numbits,ebn,NULL); - - // populate ops key from ssl key - - skey->public_key.version=4; - skey->public_key.creation_time=time(NULL); - skey->public_key.days_valid=0; - skey->public_key.algorithm= OPS_PKA_RSA; - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - skey->public_key.key.rsa.n=BN_dup(rsa->n); - skey->public_key.key.rsa.e=BN_dup(rsa->e); - skey->key.rsa.d=BN_dup(rsa->d); -#else - const BIGNUM *nn=NULL,*ee=NULL,*dd=NULL ; - - RSA_get0_key(rsa,&nn,&ee,&dd) ; - - skey->public_key.key.rsa.n=BN_dup(nn) ; - skey->public_key.key.rsa.e=BN_dup(ee) ; - skey->key.rsa.d=BN_dup(dd) ; -#endif - - skey->s2k_usage=OPS_S2KU_ENCRYPTED_AND_HASHED; - skey->s2k_specifier=OPS_S2KS_SALTED; - //skey->s2k_specifier=OPS_S2KS_SIMPLE; - skey->algorithm=OPS_SA_CAST5; // \todo make param - skey->hash_algorithm=OPS_HASH_SHA1; // \todo make param - skey->octet_count=0; - skey->checksum=0; - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - skey->key.rsa.p=BN_dup(rsa->p); - skey->key.rsa.q=BN_dup(rsa->q); - skey->key.rsa.u=BN_mod_inverse(NULL,rsa->p, rsa->q, ctx); -#else - const BIGNUM *pp=NULL,*qq=NULL ; - - RSA_get0_factors(rsa,&pp,&qq) ; - - skey->key.rsa.p=BN_dup(pp); - skey->key.rsa.q=BN_dup(qq); - - skey->key.rsa.u=BN_mod_inverse(NULL,pp,qq, ctx); -#endif - assert(skey->key.rsa.u); - BN_CTX_free(ctx); - - RSA_free(rsa); - - ops_keyid(keydata->key_id, &keydata->key.skey.public_key); - ops_fingerprint(&keydata->fingerprint, &keydata->key.skey.public_key); - - // Generate checksum - - ops_create_info_t *cinfo=NULL; - ops_memory_t *mem=NULL; - - ops_setup_memory_write(&cinfo, &mem, 128); - - ops_push_skey_checksum_writer(cinfo, skey); - - switch(skey->public_key.algorithm) - { - // case OPS_PKA_DSA: - // return ops_write_mpi(key->key.dsa.x,info); - - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - if(!ops_write_mpi(skey->key.rsa.d,cinfo) - || !ops_write_mpi(skey->key.rsa.p,cinfo) - || !ops_write_mpi(skey->key.rsa.q,cinfo) - || !ops_write_mpi(skey->key.rsa.u,cinfo)) - return ops_false; - break; - - // case OPS_PKA_ELGAMAL: - // return ops_write_mpi(key->key.elgamal.x,info); - - default: - assert(0); - break; - } - - // close rather than pop, since its the only one on the stack - ops_writer_close(cinfo); - ops_teardown_memory_write(cinfo, mem); - - // should now have checksum in skey struct - - // test - if (debug) - test_secret_key(skey); - - return ops_true; - } - -/** - \ingroup HighLevel_KeyGenerate - \brief Creates a self-signed RSA keypair - \param numbits Modulus size - \param e Public Exponent - \param userid User ID - \return The new keypair or NULL - - \note It is the caller's responsibility to call ops_keydata_free(keydata) - \sa ops_rsa_generate_keypair() - \sa ops_keydata_free() -*/ -ops_keydata_t* ops_rsa_create_selfsigned_keypair(const int numbits, const unsigned long e, ops_user_id_t * userid) - { - ops_keydata_t *keydata=NULL; - - keydata=ops_keydata_new(); - - if (ops_rsa_generate_keypair(numbits, e, keydata) != ops_true - || ops_add_selfsigned_userid_to_keydata(keydata, userid) != ops_true) - { - ops_keydata_free(keydata); - return NULL; - } - - return keydata; - } - -/* -int ops_dsa_size(const ops_dsa_public_key_t *dsa) - { - int size; - DSA *odsa; - odsa=DSA_new(); - odsa->p=dsa->p; - odsa->q=dsa->q; - odsa->g=dsa->g; - odsa->pub_key=dsa->y; - - DSAparams_print_fp(stderr, odsa); - size=DSA_size(odsa); - - odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL; - DSA_free(odsa); - - return size; - } -*/ - -DSA_SIG* ops_dsa_sign(unsigned char* hashbuf, unsigned hashsize, const ops_dsa_secret_key_t *sdsa, const ops_dsa_public_key_t *dsa) - { - DSA *odsa; - DSA_SIG *dsasig; - - odsa=DSA_new(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - odsa->p=dsa->p; - odsa->q=dsa->q; - odsa->g=dsa->g; - odsa->pub_key=dsa->y; - odsa->priv_key=sdsa->x; -#else - DSA_set0_pqg(odsa,BN_dup(dsa->p),BN_dup(dsa->q),BN_dup(dsa->g)); - DSA_set0_key(odsa,BN_dup(dsa->y),BN_dup(sdsa->x)); -#endif - - dsasig=DSA_do_sign(hashbuf,hashsize,odsa); - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - odsa->p=odsa->q=odsa->g=odsa->pub_key=odsa->priv_key=NULL; -#endif - DSA_free(odsa); - - return dsasig; - } - -// eof diff --git a/openpgpsdk/src/openpgpsdk/opsdir.c b/openpgpsdk/src/openpgpsdk/opsdir.c deleted file mode 100644 index b966f090f..000000000 --- a/openpgpsdk/src/openpgpsdk/opsdir.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "opsdir.h" -#ifdef WIN32 -#include "opsstring.h" -#endif -#include - -int ops_open(const char* filename, int flag, int pmode) -{ -#ifdef WIN32 - wchar_t *wfilename = ConvertUtf8ToUtf16(filename); - if (!wfilename) - { - return -1; - } - - int result = _wopen(wfilename, flag, pmode); - free(wfilename); - - return result; -#else - return open(filename, flag, pmode); -#endif -} diff --git a/openpgpsdk/src/openpgpsdk/opsdir.h b/openpgpsdk/src/openpgpsdk/opsdir.h deleted file mode 100644 index 78f7ad8e8..000000000 --- a/openpgpsdk/src/openpgpsdk/opsdir.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef OPUTIL_H -#define OPUTIL_H - -int ops_open(const char* filename, int flag, int pmode); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/opsstring.c b/openpgpsdk/src/openpgpsdk/opsstring.c deleted file mode 100644 index 6a0e2b072..000000000 --- a/openpgpsdk/src/openpgpsdk/opsstring.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "opsstring.h" - -#ifdef WIN32 -wchar_t *ConvertUtf8ToUtf16(const char* source) -{ - if (!source) { - return NULL; - } - -#ifdef WIN32 - int nbChars = MultiByteToWideChar(CP_UTF8, 0, source, -1, 0, 0); - if (nbChars == 0) { - return NULL; - } - - wchar_t* utf16Name = (wchar_t*) malloc(nbChars * sizeof(wchar_t)); - if (MultiByteToWideChar(CP_UTF8, 0, source, -1, utf16Name, nbChars) == 0) { - free(utf16Name); - return NULL; - } - - return utf16Name; -#else - // currently only for WIN32 - // convert code from rsstring.cc - return NULL; -#endif -} - -char* ConvertUtf16ToUtf8(const wchar_t *source) -{ - if (!source) { - return NULL; - } - -#ifdef WIN32 - int nbChars = WideCharToMultiByte(CP_UTF8, 0, source, -1, 0, 0, 0, 0); - if (nbChars == 0) { - return NULL; - } - - char* utf8Name = (char*) malloc(nbChars * sizeof(char)); - if (WideCharToMultiByte(CP_UTF8, 0, source, -1, utf8Name, nbChars, 0, 0) == 0) { - free(utf8Name); - return NULL; - } - - return utf8Name; -#else - // currently only for WIN32 - // convert code from rsstring.cc - return NULL; -#endif -} -#endif diff --git a/openpgpsdk/src/openpgpsdk/opsstring.h b/openpgpsdk/src/openpgpsdk/opsstring.h deleted file mode 100644 index 3bbaed494..000000000 --- a/openpgpsdk/src/openpgpsdk/opsstring.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef OPSSTRING_H -#define OPSSTRING_H - -#ifdef WIN32 -#include -#endif - -#ifdef WIN32 -// currently only for WIN32 - -// Convert strings between UTF8 and UTF16 -// Don't forget to free the returned string. -wchar_t* ConvertUtf8ToUtf16(const char *source); -char* ConvertUtf16ToUtf8(const wchar_t* source); -#endif - -#endif // OPSSTRING_H diff --git a/openpgpsdk/src/openpgpsdk/packet-parse.c b/openpgpsdk/src/openpgpsdk/packet-parse.c deleted file mode 100644 index e641eae41..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-parse.c +++ /dev/null @@ -1,3477 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * \brief Parser for OpenPGP packets - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "parse_local.h" - -#include -#include -#include -#ifndef WIN32 -#include -#endif -#include -#include - -#include - -static int debug=0; -static const size_t MAX_RECURSIVE_COMPRESSION_DEPTH = 32 ; - -/** - * limited_read_data reads the specified amount of the subregion's data - * into a data_t structure - * - * \param data Empty structure which will be filled with data - * \param len Number of octets to read - * \param subregion - * \param pinfo How to parse - * - * \return 1 on success, 0 on failure - */ -static int limited_read_data(ops_data_t *data,unsigned int len, - ops_region_t *subregion,ops_parse_info_t *pinfo) -{ - data->len = len; - - if(!(subregion->length-subregion->length_read >= len)) // ASSERT(subregion->length-subregion->length_read >= len); - { - fprintf(stderr,"Data length error: announced size %d larger than expected size %d. Giving up.",len,subregion->length-subregion->length_read) ; - return 0 ; - } - - data->contents=malloc(data->len); - if (!data->contents) - return 0; - - if (!ops_limited_read(data->contents, data->len,subregion,&pinfo->errors, - &pinfo->rinfo,&pinfo->cbinfo)) - return 0; - - return 1; -} - -/** - * read_data reads the remainder of the subregion's data - * into a data_t structure - * - * \param data - * \param subregion - * \param pinfo - * - * \return 1 on success, 0 on failure - */ -static int read_data(ops_data_t *data,ops_region_t *subregion, - ops_parse_info_t *pinfo) - { - int len; - - len=subregion->length-subregion->length_read; - - if ( len >= 0 ) { - return(limited_read_data(data,len,subregion,pinfo)); - } - return 0; - } - -/** - * Reads the remainder of the subregion as a string. - * It is the user's responsibility to free the memory allocated here. - */ - -static int read_unsigned_string(unsigned char **str,ops_region_t *subregion, - ops_parse_info_t *pinfo) - { - int len=0; - - len=subregion->length-subregion->length_read; - - *str=malloc(len+1); - if(!(*str)) - return 0; - - if(len && !ops_limited_read(*str,len,subregion,&pinfo->errors, - &pinfo->rinfo,&pinfo->cbinfo)) - return 0; - - /*! ensure the string is NULL-terminated */ - - (*str)[len]='\0'; - - return 1; - } - -static int read_string(char **str, ops_region_t *subregion, ops_parse_info_t *pinfo) - { - return (read_unsigned_string((unsigned char **)str, subregion, pinfo)); - } - -void ops_init_subregion(ops_region_t *subregion,ops_region_t *region) - { - memset(subregion,'\0',sizeof *subregion); - subregion->parent=region; - } - -/*! macro to save typing */ -#define C content.content - -/* XXX: replace ops_ptag_t with something more appropriate for limiting - reads */ - -/** - * low-level function to read data from reader function - * - * Use this function, rather than calling the reader directly. - * - * If the accumulate flag is set in *pinfo, the function - * adds the read data to the accumulated data, and updates - * the accumulated length. This is useful if, for example, - * the application wants access to the raw data as well as the - * parsed data. - * - * This function will also try to read the entire amount asked for, but not - * if it is over INT_MAX. Obviously many callers will know that they - * never ask for that much and so can avoid the extra complexity of - * dealing with return codes and filled-in lengths. - * - * \param *dest - * \param *plength - * \param flags - * \param *pinfo - * - * \return OPS_R_OK - * \return OPS_R_PARTIAL_READ - * \return OPS_R_EOF - * \return OPS_R_EARLY_EOF - * - * \sa #ops_reader_ret_t for details of return codes - */ - -static int sub_base_read(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) -{ - size_t n; - - /* reading more than this would look like an error */ - if(length > INT_MAX) - length=INT_MAX; - - for(n=0 ; n < length ; ) - { - int r=rinfo->reader((char*)dest+n,length-n,errors,rinfo,cbinfo); - - if(!(r <= (int)(length-n))) // ASSERT(r <= (int)(length-n)) - { - fprintf(stderr,"sub_base_read: error in length. Read %d, remaining length is %d",r,(int)(length-n)) ; - return -1 ; - } - - // XXX: should we save the error and return what was read so far? - // - if(r < 0) - return r; - - if(r == 0) - break; - - n+=r; - } - - if(n == 0) - return 0; - - if(rinfo->accumulate) - { - if(!(rinfo->asize >= rinfo->alength)) // ASSERT(rinfo->asize >= rinfo->alength) - { - fprintf(stderr,"sub_base_read: error in accumulated length.") ; - return -1 ; - } - - if(rinfo->alength+n > rinfo->asize) - { - rinfo->asize=rinfo->asize*2+n; - rinfo->accumulated=realloc(rinfo->accumulated,rinfo->asize); - } - if(!(rinfo->asize >= rinfo->alength+n)) // ASSERT(rinfo->asize >= rinfo->alength+n) - { - fprintf(stderr,"sub_base_read: error in accumulated length.") ; - return -1 ; - } - - memcpy(rinfo->accumulated+rinfo->alength,dest,n); - } - // we track length anyway, because it is used for packet offsets - rinfo->alength+=n; - // and also the position - rinfo->position+=n; - - return n; -} - -int ops_stacked_read(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) - { return sub_base_read(dest,length,errors,rinfo->next,cbinfo); } - -/* This will do a full read so long as length < MAX_INT */ -static int base_read(unsigned char *dest,size_t length, - ops_parse_info_t *pinfo) - { - return sub_base_read(dest,length,&pinfo->errors,&pinfo->rinfo, - &pinfo->cbinfo); - } - -/* Read a full size_t's worth. If the return is < than length, then - * *last_read tells you why - < 0 for an error, == 0 for EOF */ - -static size_t full_read(unsigned char *dest,size_t length,int *last_read, - ops_error_t **errors,ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) - { - size_t t; - int r=0; /* preset in case some loon calls with length == 0 */ - - for(t=0 ; t < length ; ) - { - r=sub_base_read(dest+t,length-t,errors,rinfo,cbinfo); - - if(r <= 0) - { - *last_read=r; - return t; - } - - t+=r; - } - - *last_read=r; - - return t; - } - - - -/** Read a scalar value of selected length from reader. - * - * Read an unsigned scalar value from reader in Big Endian representation. - * - * This function does not know or care about packet boundaries. It - * also assumes that an EOF is an error. - * - * \param *result The scalar value is stored here - * \param *reader Our reader - * \param length How many bytes to read - * \return ops_true on success, ops_false on failure - */ -static ops_boolean_t _read_scalar(unsigned *result,unsigned length, - ops_parse_info_t *pinfo) - { - unsigned t=0; - - if(! (length <= sizeof(*result))) // ASSERT(length <= sizeof(*result)) - { - fprintf(stderr,"_read_scalar: length to read is larger than buffer size.") ; - return ops_false ; - } - - while(length--) - { - unsigned char c[1]; - int r; - - r=base_read(c,1,pinfo); - if(r != 1) - return ops_false; - t=(t << 8)+c[0]; - } - - *result=t; - return ops_true; - } - -/** - * \ingroup Core_ReadPackets - * \brief Read bytes from a region within the packet. - * - * Read length bytes into the buffer pointed to by *dest. - * Make sure we do not read over the packet boundary. - * Updates the Packet Tag's ops_ptag_t::length_read. - * - * If length would make us read over the packet boundary, or if - * reading fails, we call the callback with an error. - * - * Note that if the region is indeterminate, this can return a short - * read - check region->last_read for the length. EOF is indicated by - * a success return and region->last_read == 0 in this case (for a - * region of known length, EOF is an error). - * - * This function makes sure to respect packet boundaries. - * - * \param dest The destination buffer - * \param length How many bytes to read - * \param region Pointer to packet region - * \param errors Error stack - * \param rinfo Reader info - * \param cbinfo Callback info - * \return ops_true on success, ops_false on error - */ -ops_boolean_t ops_limited_read(unsigned char *dest,size_t length, - ops_region_t *region,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - size_t r; - int lr; - - if(!region->indeterminate && region->length_read+length > region->length) - { - OPS_ERROR(errors,OPS_E_P_NOT_ENOUGH_DATA,"Not enough data"); - return ops_false; - } - - r=full_read(dest,length,&lr,errors,rinfo,cbinfo); - - if(lr < 0) - { - OPS_ERROR(errors,OPS_E_R_READ_FAILED,"Read failed"); - return ops_false; - } - - if(!region->indeterminate && r != length) - { - OPS_ERROR(errors,OPS_E_R_READ_FAILED,"Read failed"); - return ops_false; - } - - region->last_read=r; - do - { - region->length_read+=r; - - if(!(!region->parent || region->length <= region->parent->length)) // ASSERT(!region->parent || region->length <= region->parent->length) - { - OPS_ERROR(errors,OPS_E_R_READ_FAILED,"Read failed"); - return ops_false; - } - } - while((region=region->parent)); - - return ops_true; -} - -/** - \ingroup Core_ReadPackets - \brief Call ops_limited_read on next in stack -*/ -ops_boolean_t ops_stacked_limited_read(void *dest, unsigned length, - ops_region_t *region, - ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) - { - return ops_limited_read(dest, length, region, errors, rinfo->next, cbinfo); - } - -static ops_boolean_t limited_read(unsigned char *dest,unsigned length, - ops_region_t *region,ops_parse_info_t *info) - { - return ops_limited_read(dest,length,region,&info->errors, - &info->rinfo,&info->cbinfo); - } - -static ops_boolean_t exact_limited_read(unsigned char *dest,unsigned length, - ops_region_t *region, - ops_parse_info_t *pinfo) - { - ops_boolean_t ret; - - pinfo->exact_read=ops_true; - ret=limited_read(dest,length,region,pinfo); - pinfo->exact_read=ops_false; - - return ret; - } - -/** Skip over length bytes of this packet. - * - * Calls limited_read() to skip over some data. - * - * This function makes sure to respect packet boundaries. - * - * \param length How many bytes to skip - * \param *region Pointer to packet region - * \param *pinfo How to parse - * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limited_read()). - */ -static int limited_skip(unsigned length,ops_region_t *region, - ops_parse_info_t *pinfo) - { - unsigned char buf[8192]; - - while(length) - { - int n=length%8192; - if(!limited_read(buf,n,region,pinfo)) - return 0; - length-=n; - } - return 1; - } - -/** Read a scalar. - * - * Read a big-endian scalar of length bytes, respecting packet - * boundaries (by calling limited_read() to read the raw data). - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The scalar value is stored here - * \param length How many bytes make up this scalar (at most 4) - * \param *region Pointer to current packet region - * \param *pinfo How to parse - * \param *cb The callback - * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limited_read()). - * - * \see RFC4880 3.1 - */ -static int limited_read_scalar(unsigned *dest,unsigned length, - ops_region_t *region, - ops_parse_info_t *pinfo) -{ - unsigned char c[4]=""; - unsigned t; - unsigned n; - - if(!(length <= 4)) // ASSERT(length <= 4) - { - fprintf(stderr,"limited_read_scalar: wrong size for scalar %d\n",length) ; - return ops_false ; - } - if(!(sizeof(*dest) >= 4)) // ASSERT(sizeof(*dest) >= 4) - { - fprintf(stderr,"limited_read_scalar: wrong size for dest %lu\n",sizeof(*dest)) ; - return ops_false ; - } - if(!limited_read(c,length,region,pinfo)) - return 0; - - for(t=0,n=0 ; n < length ; ++n) - t=(t << 8)+c[n]; - *dest=t; - - return 1; -} - -/** Read a scalar. - * - * Read a big-endian scalar of length bytes, respecting packet - * boundaries (by calling limited_read() to read the raw data). - * - * The value read is stored in a size_t, which is a different size - * from an unsigned on some platforms. - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The scalar value is stored here - * \param length How many bytes make up this scalar (at most 4) - * \param *region Pointer to current packet region - * \param *pinfo How to parse - * \param *cb The callback - * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limited_read()). - * - * \see RFC4880 3.1 - */ -static int limited_read_size_t_scalar(size_t *dest,unsigned length, - ops_region_t *region, - ops_parse_info_t *pinfo) -{ - unsigned tmp; - - if(!(sizeof(*dest) >= 4)) // ASSERT(sizeof(*dest) >= 4) - { - fprintf(stderr,"limited_read_scalar: wrong dest size for scalar %lu\n",sizeof(*dest)) ; - return ops_false ; - } - - /* Note that because the scalar is at most 4 bytes, we don't care - if size_t is bigger than usigned */ - if(!limited_read_scalar(&tmp,length,region,pinfo)) - return 0; - - *dest=tmp; - return 1; -} - -/** Read a timestamp. - * - * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch (1.1.1970). They are stored in an unsigned scalar - * of 4 bytes. - * - * This function reads the timestamp using limited_read_scalar(). - * - * This function makes sure to respect packet boundaries. - * - * \param *dest The timestamp is stored here - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return see limited_read_scalar() - * - * \see RFC4880 3.5 - */ -static int limited_read_time(time_t *dest,ops_region_t *region, - ops_parse_info_t *pinfo) -{ - /* - * Cannot assume that time_t is 4 octets long - - * there is at least one architecture (SunOS 5.10) where it is 8. - */ - if (sizeof(*dest)==4) - { - return limited_read_scalar((unsigned *)dest,4,region,pinfo); - } - else - { - time_t mytime=0; - int i=0; - unsigned char c[1]; - for (i=0; i<4; i++) - { - if (!limited_read(c,1,region,pinfo)) - return 0; - mytime=(mytime << 8) + c[0]; - } - *dest=mytime; - return 1; - } -} - -/** - * \ingroup Core_MPI - * Read a multiprecision integer. - * - * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts. First there is a 2 byte scalar - * indicating the length of the following MPI in Bits. Then follow the bits that make up the actual number, most - * significant bits first (Big Endian). The most significant bit in the MPI is supposed to be 1 (unless the MPI is - * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted). - * - * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are - * supposed to be cleared - I guess. XXX - does anything actually say so? - * - * This function makes sure to respect packet boundaries. - * - * \param **pgn return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed - * by the caller XXX right ben? - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error (by limited_read_scalar() or limited_read() or if the MPI is not properly formed (XXX - * see comment below - the callback is called with a OPS_PARSER_ERROR in case of an error) - * - * \see RFC4880 3.2 - */ -static int limited_read_mpi(BIGNUM **pbn,ops_region_t *region, - ops_parse_info_t *pinfo) - { - unsigned length; - unsigned nonzero; - unsigned char buf[8192]=""; /* an MPI has a 2 byte length part. Length - is given in bits, so the largest we should - ever need for the buffer is 8192 bytes. */ - ops_boolean_t ret; - - pinfo->reading_mpi_length=ops_true; - ret=limited_read_scalar(&length,2,region,pinfo); - - pinfo->reading_mpi_length=ops_false; - if(!ret) - return 0; - - nonzero=length&7; /* there should be this many zero bits in the MS byte */ - if(!nonzero) - nonzero=8; - length=(length+7)/8; - - if(!(length <= 8192)) // ASSERT(length <= 8192) - { - fprintf(stderr,"limited_read_mpi: wrong size to read %d > 8192",length) ; - return 0 ; - } - - if(!limited_read(buf,length,region,pinfo)) - return 0; - - if((buf[0] >> nonzero) != 0 || !(buf[0]&(1 << (nonzero-1)))) - { - OPS_ERROR(&pinfo->errors,OPS_E_P_MPI_FORMAT_ERROR,"MPI Format error"); /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ - return 0; - } - - *pbn=BN_bin2bn(buf,length,NULL); - return 1; - } - -/** Read some data with a New-Format length from reader. - * - * \sa Internet-Draft RFC4880.txt Section 4.2.2 - * - * \param *length Where the decoded length will be put - * \param *pinfo How to parse - * \return ops_true if OK, else ops_false - * - */ - -static ops_boolean_t read_new_length(unsigned *length,ops_parse_info_t *pinfo) - { - unsigned char c[1]; - - if(base_read(c,1,pinfo) != 1) - return ops_false; - if(c[0] < 192) - { - // 1. One-octet packet - *length=c[0]; - return ops_true; - } - - else if (c[0]>=192 && c[0]<=223) - { - // 2. Two-octet packet - unsigned t=(c[0]-192) << 8; - - if(base_read(c,1,pinfo) != 1) - return ops_false; - *length=t+c[0]+192; - return ops_true; - } - - else if (c[0]==255) - { - // 3. Five-Octet packet - return _read_scalar(length,4,pinfo); - } - - else if (c[0]>=224 && c[0]<255) - { - // 4. Partial Body Length - OPS_ERROR(&pinfo->errors,OPS_E_UNIMPLEMENTED, - "New format Partial Body Length fields not yet implemented"); - return ops_false; - } - return ops_false; - } - -/** Read the length information for a new format Packet Tag. - * - * New style Packet Tags encode the length in one to five octets. This function reads the right amount of bytes and - * decodes it to the proper length information. - * - * This function makes sure to respect packet boundaries. - * - * \param *length return the length here - * \param *ptag Pointer to current packet's Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error (by limited_read_scalar() or limited_read() or if the MPI is not properly formed (XXX - * see comment below) - * - * \see RFC4880 4.2.2 - * \see ops_ptag_t - */ -static int limited_read_new_length(unsigned *length,ops_region_t *region, - ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - - if(!limited_read(c,1,region,pinfo)) - return 0; - if(c[0] < 192) - { - *length=c[0]; - return 1; - } - if(c[0] < 255) - { - unsigned t=(c[0]-192) << 8; - - if(!limited_read(c,1,region,pinfo)) - return 0; - *length=t+c[0]+192; - return 1; - } - return limited_read_scalar(length,4,region,pinfo); - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void data_free(ops_data_t *data) - { - free(data->contents); - data->contents=NULL; - data->len=0; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void string_free(char **str) - { - free(*str); - *str=NULL; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free packet memory, set pointer to NULL */ -void ops_packet_free(ops_packet_t *packet) - { - free(packet->raw); - packet->raw=NULL; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void ops_headers_free(ops_headers_t *headers) - { - unsigned n; - - for(n=0 ; n < headers->nheaders ; ++n) - { - free(headers->headers[n].key); - free(headers->headers[n].value); - } - free(headers->headers); - headers->headers=NULL; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void ops_signed_cleartext_trailer_free(ops_signed_cleartext_trailer_t *trailer) - { - free(trailer->hash); - trailer->hash=NULL; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void ops_cmd_get_passphrase_free(ops_secret_key_passphrase_t *skp) - { - if (skp->passphrase && *skp->passphrase) - { - free(*skp->passphrase); - *skp->passphrase=NULL; - } - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free any memory allocated when parsing the packet content */ -void ops_parser_content_free(ops_parser_content_t *c) -{ - switch(c->tag) - { - case OPS_PARSER_PTAG: - case OPS_PTAG_CT_COMPRESSED: - case OPS_PTAG_SS_CREATION_TIME: - case OPS_PTAG_SS_EXPIRATION_TIME: - case OPS_PTAG_SS_KEY_EXPIRATION_TIME: - case OPS_PTAG_SS_TRUST: - case OPS_PTAG_SS_ISSUER_KEY_ID: - case OPS_PTAG_CT_ONE_PASS_SIGNATURE: - case OPS_PTAG_SS_PRIMARY_USER_ID: - case OPS_PTAG_SS_REVOCABLE: - case OPS_PTAG_SS_REVOCATION_KEY: - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - case OPS_PTAG_CT_LITERAL_DATA_BODY: - case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: - case OPS_PTAG_CT_UNARMOURED_TEXT: - case OPS_PTAG_CT_ARMOUR_TRAILER: - case OPS_PTAG_CT_SIGNATURE_HEADER: - case OPS_PTAG_CT_SE_DATA_HEADER: - case OPS_PTAG_CT_SE_IP_DATA_HEADER: - case OPS_PTAG_CT_SE_IP_DATA_BODY: - case OPS_PTAG_CT_MDC: - case OPS_PARSER_CMD_GET_SECRET_KEY: - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - ops_headers_free(&c->content.signed_cleartext_header.headers); - break; - - case OPS_PTAG_CT_ARMOUR_HEADER: - ops_headers_free(&c->content.armour_header.headers); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - ops_signed_cleartext_trailer_free(&c->content.signed_cleartext_trailer); - break; - - case OPS_PTAG_CT_TRUST: - ops_trust_free(&c->content.trust); - break; - - case OPS_PTAG_CT_SIGNATURE: - case OPS_PTAG_CT_SIGNATURE_FOOTER: - ops_signature_free(&c->content.signature); - break; - - case OPS_PTAG_CT_PUBLIC_KEY: - case OPS_PTAG_CT_PUBLIC_SUBKEY: - ops_public_key_free(&c->content.public_key); - break; - - case OPS_PTAG_CT_USER_ID: - ops_user_id_free(&c->content.user_id); - break; - - case OPS_PTAG_SS_SIGNERS_USER_ID: - ops_user_id_free(&c->content.ss_signers_user_id); - break; - - case OPS_PTAG_CT_USER_ATTRIBUTE: - ops_user_attribute_free(&c->content.user_attribute); - break; - - case OPS_PTAG_SS_PREFERRED_SKA: - ops_ss_preferred_ska_free(&c->content.ss_preferred_ska); - break; - - case OPS_PTAG_SS_PREFERRED_HASH: - ops_ss_preferred_hash_free(&c->content.ss_preferred_hash); - break; - - case OPS_PTAG_SS_PREFERRED_COMPRESSION: - ops_ss_preferred_compression_free(&c->content.ss_preferred_compression); - break; - - case OPS_PTAG_SS_KEY_FLAGS: - ops_ss_key_flags_free(&c->content.ss_key_flags); - break; - - case OPS_PTAG_SS_KEY_SERVER_PREFS: - ops_ss_key_server_prefs_free(&c->content.ss_key_server_prefs); - break; - - case OPS_PTAG_SS_FEATURES: - ops_ss_features_free(&c->content.ss_features); - break; - - case OPS_PTAG_SS_NOTATION_DATA: - ops_ss_notation_data_free(&c->content.ss_notation_data); - break; - - case OPS_PTAG_SS_REGEXP: - ops_ss_regexp_free(&c->content.ss_regexp); - break; - - case OPS_PTAG_SS_POLICY_URI: - ops_ss_policy_url_free(&c->content.ss_policy_url); - break; - - case OPS_PTAG_SS_PREFERRED_KEY_SERVER: - ops_ss_preferred_key_server_free(&c->content.ss_preferred_key_server); - break; - - case OPS_PTAG_SS_USERDEFINED00: - case OPS_PTAG_SS_USERDEFINED01: - case OPS_PTAG_SS_USERDEFINED02: - case OPS_PTAG_SS_USERDEFINED03: - case OPS_PTAG_SS_USERDEFINED04: - case OPS_PTAG_SS_USERDEFINED05: - case OPS_PTAG_SS_USERDEFINED06: - case OPS_PTAG_SS_USERDEFINED07: - case OPS_PTAG_SS_USERDEFINED08: - case OPS_PTAG_SS_USERDEFINED09: - case OPS_PTAG_SS_USERDEFINED10: - ops_ss_userdefined_free(&c->content.ss_userdefined); - break; - - case OPS_PTAG_SS_RESERVED: - ops_ss_reserved_free(&c->content.ss_unknown); - break; - - case OPS_PTAG_SS_REVOCATION_REASON: - ops_ss_revocation_reason_free(&c->content.ss_revocation_reason); - break; - - case OPS_PTAG_SS_EMBEDDED_SIGNATURE: - ops_ss_embedded_signature_free(&c->content.ss_embedded_signature); - break; - - case OPS_PARSER_PACKET_END: - ops_packet_free(&c->content.packet); - break; - - case OPS_PARSER_ERROR: - case OPS_PARSER_ERRCODE: - break; - - case OPS_PTAG_CT_SECRET_KEY: - case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: - ops_secret_key_free(&c->content.secret_key); - break; - - case OPS_PTAG_CT_PK_SESSION_KEY: - case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - ops_pk_session_key_free(&c->content.pk_session_key); - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - case OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD: - ops_cmd_get_passphrase_free(&c->content.secret_key_passphrase); - break; - - default: - fprintf(stderr,"Can't free %d (0x%x)\n",c->tag,c->tag); - //ASSERT(0); - } -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -static void free_BN(BIGNUM **pp) - { - BN_free(*pp); - *pp=NULL; - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -void ops_pk_session_key_free(ops_pk_session_key_t *sk) -{ - switch(sk->algorithm) - { - case OPS_PKA_RSA: - free_BN(&sk->parameters.rsa.encrypted_m); - break; - - case OPS_PKA_ELGAMAL: - free_BN(&sk->parameters.elgamal.g_to_k); - free_BN(&sk->parameters.elgamal.encrypted_m); - break; - - default: - fprintf(stderr,"ops_pk_session_key_free: Unknown algorithm: %d \n",sk->algorithm); - //ASSERT(0); - } -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing a public key */ -void ops_public_key_free(ops_public_key_t *p) -{ - switch(p->algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - free_BN(&p->key.rsa.n); - free_BN(&p->key.rsa.e); - break; - - case OPS_PKA_DSA: - free_BN(&p->key.dsa.p); - free_BN(&p->key.dsa.q); - free_BN(&p->key.dsa.g); - free_BN(&p->key.dsa.y); - break; - - case OPS_PKA_ELGAMAL: - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - free_BN(&p->key.elgamal.p); - free_BN(&p->key.elgamal.g); - free_BN(&p->key.elgamal.y); - break; - - default: - fprintf(stderr,"ops_public_key_free: Unknown algorithm: %d \n",p->algorithm); - //ASSERT(0); - } -} - -void ops_public_key_copy(ops_public_key_t *dst,const ops_public_key_t *src) -{ - *dst = *src ; - - switch(src->algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - dst->key.rsa.n = BN_dup(src->key.rsa.n); - dst->key.rsa.e = BN_dup(src->key.rsa.e); - break; - - case OPS_PKA_DSA: - dst->key.dsa.p = BN_dup(src->key.dsa.p); - dst->key.dsa.q = BN_dup(src->key.dsa.q); - dst->key.dsa.g = BN_dup(src->key.dsa.g); - dst->key.dsa.y = BN_dup(src->key.dsa.y); - break; - - case OPS_PKA_ELGAMAL: - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - dst->key.elgamal.p = BN_dup(src->key.elgamal.p); - dst->key.elgamal.g = BN_dup(src->key.elgamal.g); - dst->key.elgamal.y = BN_dup(src->key.elgamal.y); - break; - - //case 0: - // nothing to free - // break; - - default: - fprintf(stderr,"ops_public_key_copy: Unknown algorithm: %d \n",src->algorithm); - //ASSERT(0); - } -} -/** - \ingroup Core_ReadPackets -*/ -static int parse_public_key_data(ops_public_key_t *key,ops_region_t *region, - ops_parse_info_t *pinfo) -{ - unsigned char c[1]=""; - - if(!(region->length_read == 0)) // ASSERT(region->length_read == 0) /* We should not have read anything so far */ - { - fprintf(stderr,"parse_public_key_data: read length error\n") ; - return 0 ; - } - - if(!limited_read(c,1,region,pinfo)) - return 0; - key->version=c[0]; - if(key->version < 2 || key->version > 4) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN, - "Bad public key version (0x%02x)",key->version); - return 0; - } - - if(!limited_read_time(&key->creation_time,region,pinfo)) - return 0; - - key->days_valid=0; - if((key->version == 2 || key->version == 3) - && !limited_read_scalar(&key->days_valid,2,region,pinfo)) - return 0; - - if(!limited_read(c,1,region,pinfo)) - return 0; - - key->algorithm=c[0]; - - switch(key->algorithm) - { - case OPS_PKA_DSA: - if(!limited_read_mpi(&key->key.dsa.p,region,pinfo) - || !limited_read_mpi(&key->key.dsa.q,region,pinfo) - || !limited_read_mpi(&key->key.dsa.g,region,pinfo) - || !limited_read_mpi(&key->key.dsa.y,region,pinfo)) - return 0; - break; - - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - if(!limited_read_mpi(&key->key.rsa.n,region,pinfo) - || !limited_read_mpi(&key->key.rsa.e,region,pinfo)) - return 0; - break; - - case OPS_PKA_ELGAMAL: - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if(!limited_read_mpi(&key->key.elgamal.p,region,pinfo) - || !limited_read_mpi(&key->key.elgamal.g,region,pinfo) - || !limited_read_mpi(&key->key.elgamal.y,region,pinfo)) - return 0; - break; - - default: - OPS_ERROR_1(&pinfo->errors,OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,"Unsupported Public Key algorithm (%s)",ops_show_pka(key->algorithm)); - return 0; - } - - return 1; -} - - -/** - * \ingroup Core_ReadPackets - * \brief Parse a public key packet. - * - * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys. - * - * Once the key has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the current Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.5.2 - */ -static int parse_public_key(ops_content_tag_t tag,ops_region_t *region, - ops_parse_info_t *pinfo) - { - ops_parser_content_t content; - - if(!parse_public_key_data(&C.public_key,region,pinfo)) - return 0; - - // XXX: this test should be done for all packets, surely? - if(region->length_read != region->length) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", region->length-region->length_read); - return 0; - } - - CBP(pinfo,tag,&content); - - return 1; - } - - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing this signature sub-packet type */ -void ops_ss_regexp_free(ops_ss_regexp_t *regexp) - { - string_free(®exp->text); - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing this signature sub-packet type */ -void ops_ss_policy_url_free(ops_ss_policy_url_t *policy_url) - { - string_free(&policy_url->text); - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing this signature sub-packet type */ -void ops_ss_preferred_key_server_free(ops_ss_preferred_key_server_t *preferred_key_server) - { - string_free(&preferred_key_server->text); - } - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing this packet type */ -void ops_user_attribute_free(ops_user_attribute_t *user_att) - { - data_free(&user_att->data); - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse one user attribute packet. - * - * User attribute packets contain one or more attribute subpackets. - * For now, handle the whole packet as raw data. - */ - -static int parse_user_attribute(ops_region_t *region, ops_parse_info_t *pinfo) -{ - - ops_parser_content_t content; - - /* xxx- treat as raw data for now. Could break down further - into attribute sub-packets later - rachel */ - - if(!(region->length_read == 0)) // ASSERT(region->length_read == 0) /* We should not have read anything so far */ - { - fprintf(stderr,"parse_user_attribute: read length error\n") ; - return 0 ; - } - - if(!read_data(&C.user_attribute.data,region,pinfo)) - return 0; - - CBP(pinfo,OPS_PTAG_CT_USER_ATTRIBUTE,&content); - - return 1; -} - -/** -\ingroup Core_Create -\brief Free allocated memory -*/ -/*! Free the memory used when parsing this packet type */ -void ops_user_id_free(ops_user_id_t *id) - { - free(id->user_id); - id->user_id=NULL; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse a user id. - * - * This function parses an user id packet, which is basically just a char array the size of the packet. - * - * The char array is to be treated as an UTF-8 string. - * - * The userid gets null terminated by this function. Freeing it is the responsibility of the caller. - * - * Once the userid has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.11 - */ -static int parse_user_id(ops_region_t *region,ops_parse_info_t *pinfo) -{ - ops_parser_content_t content; - - if(!(region->length_read == 0)) // ASSERT(region->length_read == 0) /* We should not have read anything so far */ - { - fprintf(stderr,"parse_user_id: region read size should be 0. Corrupted data ?\n") ; - return 0 ; - } - - /* From gnupg parse-packet.c: - Cap the size of a user ID at 2k: a value absurdly large enough - that there is no sane user ID string (which is printable text - as of RFC2440bis) that won't fit in it, but yet small enough to - avoid allocation problems. */ - - if(region->length > 2048) - { - fprintf(stderr,"parse_user_id(): invalid region length (%u)\n",region->length); - return 0; - } - C.user_id.user_id=malloc(region->length +1); /* XXX should we not like check malloc's return value? */ - - if(C.user_id.user_id==NULL) - { - fprintf(stderr,"malloc failed in parse_user_id\n") ; - return 0 ; - } - - if(region->length && !limited_read(C.user_id.user_id,region->length,region, - pinfo)) - return 0; - - C.user_id.user_id[region->length]='\0'; /* terminate the string */ - - CBP(pinfo,OPS_PTAG_CT_USER_ID,&content); - - return 1; -} - -/** - * \ingroup Core_Create - * \brief Free the memory used when parsing a private/experimental PKA signature - * \param unknown_sig - */ -void free_unknown_sig_pka(ops_unknown_signature_t *unknown_sig) - { - data_free(&unknown_sig->data); - } - -/** - * \ingroup Core_Create - * \brief Free the memory used when parsing a signature - * \param sig - */ -void ops_signature_free(ops_signature_t *sig) - { - switch(sig->info.key_algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_SIGN_ONLY: - free_BN(&sig->info.signature.rsa.sig); - break; - - case OPS_PKA_DSA: - free_BN(&sig->info.signature.dsa.r); - free_BN(&sig->info.signature.dsa.s); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - free_BN(&sig->info.signature.elgamal.r); - free_BN(&sig->info.signature.elgamal.s); - break; - - case OPS_PKA_PRIVATE00: - case OPS_PKA_PRIVATE01: - case OPS_PKA_PRIVATE02: - case OPS_PKA_PRIVATE03: - case OPS_PKA_PRIVATE04: - case OPS_PKA_PRIVATE05: - case OPS_PKA_PRIVATE06: - case OPS_PKA_PRIVATE07: - case OPS_PKA_PRIVATE08: - case OPS_PKA_PRIVATE09: - case OPS_PKA_PRIVATE10: - free_unknown_sig_pka(&sig->info.signature.unknown); - break; - - default: - fprintf(stderr,"ops_signature_free: Unknown algorithm: %d \n",sig->info.key_algorithm); - //ASSERT(0); - } - free(sig->info.v4_hashed_data); - } - -/** - * \ingroup Core_Parse - * \brief Parse a version 3 signature. - * - * This function parses an version 3 signature packet, handling RSA and DSA signatures. - * - * Once the signature has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.2 - */ -static int parse_v3_signature(ops_region_t *region, - ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - ops_parser_content_t content; - - // clear signature - memset(&C.signature,'\0',sizeof C.signature); - - C.signature.info.version=OPS_V3; - - /* hash info length */ - if(!limited_read(c,1,region,pinfo)) - return 0; - if(c[0] != 5) - ERRP(pinfo,"bad hash info length"); - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.type=c[0]; - /* XXX: check signature type */ - - if(!limited_read_time(&C.signature.info.creation_time,region,pinfo)) - return 0; - C.signature.info.creation_time_set=ops_true; - - if(!limited_read(C.signature.info.signer_id,OPS_KEY_ID_SIZE,region,pinfo)) - return 0; - C.signature.info.signer_id_set=ops_true; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.key_algorithm=c[0]; - /* XXX: check algorithm */ - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.hash_algorithm=c[0]; - /* XXX: check algorithm */ - - if(!limited_read(C.signature.hash2,2,region,pinfo)) - return 0; - - switch(C.signature.info.key_algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_SIGN_ONLY: - if(!limited_read_mpi(&C.signature.info.signature.rsa.sig,region,pinfo)) - return 0; - break; - - case OPS_PKA_DSA: - if(!limited_read_mpi(&C.signature.info.signature.dsa.r,region,pinfo) - || !limited_read_mpi(&C.signature.info.signature.dsa.s,region,pinfo)) - return 0; - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if(!limited_read_mpi(&C.signature.info.signature.elgamal.r,region,pinfo) - || !limited_read_mpi(&C.signature.info.signature.elgamal.s,region,pinfo)) - return 0; - break; - - default: - OPS_ERROR_1(&pinfo->errors,OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG, - "Unsupported signature key algorithm (%s)", - ops_show_pka(C.signature.info.key_algorithm)); - return 0; - } - - if(region->length_read != region->length) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_R_UNCONSUMED_DATA,"Unconsumed data (%d)",region->length-region->length_read); - return 0; - } - - if(C.signature.info.signer_id_set) - C.signature.hash=ops_parse_hash_find(pinfo,C.signature.info.signer_id); - - CBP(pinfo,OPS_PTAG_CT_SIGNATURE,&content); - - return 1; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse one signature sub-packet. - * - * Version 4 signatures can have an arbitrary amount of (hashed and unhashed) subpackets. Subpackets are used to hold - * optional attributes of subpackets. - * - * This function parses one such signature subpacket. - * - * Once the subpacket has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. This function should consume the entire subpacket. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int parse_one_signature_subpacket(ops_signature_t *sig, - ops_region_t *region, - ops_parse_info_t *pinfo) - { - ops_region_t subregion; - unsigned char c[1]=""; - ops_parser_content_t content; - unsigned t8,t7; - ops_boolean_t read=ops_true; - unsigned char bool[1]=""; - - ops_init_subregion(&subregion,region); - if(!limited_read_new_length(&subregion.length,region,pinfo)) - return 0; - - if(subregion.length > region->length) - ERRP(pinfo,"Subpacket too long"); - - if(!limited_read(c,1,&subregion,pinfo)) - return 0; - - t8=(c[0]&0x7f)/8; - t7=1 << (c[0]&7); - - content.critical=c[0] >> 7; - content.tag=OPS_PTAG_SIGNATURE_SUBPACKET_BASE+(c[0]&0x7f); - - /* Application wants it delivered raw */ - if(pinfo->ss_raw[t8]&t7) - { - C.ss_raw.tag=content.tag; - C.ss_raw.length=subregion.length-1; - C.ss_raw.raw=malloc(C.ss_raw.length); - - if(C.ss_raw.raw==NULL) - { - fprintf(stderr,"malloc failed in parse_signature_subpackets") ; - return 0 ; - } - if(!limited_read(C.ss_raw.raw,C.ss_raw.length,&subregion,pinfo)) - return 0; - CBP(pinfo,OPS_PTAG_RAW_SS,&content); - return 1; - } - - switch(content.tag) - { - case OPS_PTAG_SS_CREATION_TIME: - case OPS_PTAG_SS_EXPIRATION_TIME: - case OPS_PTAG_SS_KEY_EXPIRATION_TIME: - if(!limited_read_time(&C.ss_time.time,&subregion,pinfo)) - return 0; - if(content.tag == OPS_PTAG_SS_CREATION_TIME) - { - sig->info.creation_time=C.ss_time.time; - sig->info.creation_time_set=ops_true; - } - break; - - case OPS_PTAG_SS_TRUST: - if(!limited_read(&C.ss_trust.level,1,&subregion,pinfo) - || !limited_read(&C.ss_trust.amount,1,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_REVOCABLE: - if(!limited_read(bool,1,&subregion,pinfo)) - return 0; - C.ss_revocable.revocable=!!bool[0]; - break; - - case OPS_PTAG_SS_ISSUER_KEY_ID: - if(!limited_read(C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE, - &subregion,pinfo)) - return 0; - memcpy(sig->info.signer_id,C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE); - sig->info.signer_id_set=ops_true; - break; - - case OPS_PTAG_SS_PREFERRED_SKA: - if(!read_data(&C.ss_preferred_ska.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_PREFERRED_HASH: - if(!read_data(&C.ss_preferred_hash.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_PREFERRED_COMPRESSION: - if(!read_data(&C.ss_preferred_compression.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_PRIMARY_USER_ID: - if(!limited_read (bool,1,&subregion,pinfo)) - return 0; - C.ss_primary_user_id.primary_user_id = !!bool[0]; - break; - - case OPS_PTAG_SS_KEY_FLAGS: - if(!read_data(&C.ss_key_flags.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_KEY_SERVER_PREFS: - if(!read_data(&C.ss_key_server_prefs.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_FEATURES: - if(!read_data(&C.ss_features.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_SIGNERS_USER_ID: - if(!read_unsigned_string(&C.ss_signers_user_id.user_id,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_EMBEDDED_SIGNATURE: - // \todo should do something with this sig? - if (!read_data(&C.ss_embedded_signature.sig,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_NOTATION_DATA: - if(!limited_read_data(&C.ss_notation_data.flags,4,&subregion,pinfo)) - return 0; - if(!limited_read_size_t_scalar(&C.ss_notation_data.name.len,2, - &subregion,pinfo)) - return 0; - if(!limited_read_size_t_scalar(&C.ss_notation_data.value.len,2, - &subregion,pinfo)) - return 0; - if(!limited_read_data(&C.ss_notation_data.name, - C.ss_notation_data.name.len,&subregion,pinfo)) - return 0; - if(!limited_read_data(&C.ss_notation_data.value, - C.ss_notation_data.value.len,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_POLICY_URI: - if(!read_string(&C.ss_policy_url.text,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_REGEXP: - if(!read_string(&C.ss_regexp.text,&subregion, pinfo)) - return 0; - break; - - case OPS_PTAG_SS_PREFERRED_KEY_SERVER: - if(!read_string(&C.ss_preferred_key_server.text,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_USERDEFINED00: - case OPS_PTAG_SS_USERDEFINED01: - case OPS_PTAG_SS_USERDEFINED02: - case OPS_PTAG_SS_USERDEFINED03: - case OPS_PTAG_SS_USERDEFINED04: - case OPS_PTAG_SS_USERDEFINED05: - case OPS_PTAG_SS_USERDEFINED06: - case OPS_PTAG_SS_USERDEFINED07: - case OPS_PTAG_SS_USERDEFINED08: - case OPS_PTAG_SS_USERDEFINED09: - case OPS_PTAG_SS_USERDEFINED10: - if(!read_data(&C.ss_userdefined.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_RESERVED: - if(!read_data(&C.ss_unknown.data,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_REVOCATION_REASON: - /* first byte is the machine-readable code */ - if(!limited_read(&C.ss_revocation_reason.code,1,&subregion,pinfo)) - return 0; - - /* the rest is a human-readable UTF-8 string */ - if(!read_string(&C.ss_revocation_reason.text,&subregion,pinfo)) - return 0; - break; - - case OPS_PTAG_SS_REVOCATION_KEY: - /* octet 0 = clss. Bit 0x80 must be set */ - if(!limited_read (&C.ss_revocation_key.clss,1,&subregion,pinfo)) - return 0; - if(!(C.ss_revocation_key.clss&0x80)) - { - printf("Warning: OPS_PTAG_SS_REVOCATION_KEY class: " - "Bit 0x80 should be set\n"); - return 0; - } - - /* octet 1 = algid */ - if(!limited_read(&C.ss_revocation_key.algid,1,&subregion,pinfo)) - return 0; - - /* octets 2-21 = fingerprint */ - if(!limited_read(&C.ss_revocation_key.fingerprint[0],20,&subregion, - pinfo)) - return 0; - break; - - default: - if(pinfo->ss_parsed[t8]&t7) - OPS_ERROR_1(&pinfo->errors, OPS_E_PROTO_UNKNOWN_SS, - "Unknown signature subpacket type (%d)", c[0]&0x7f); - read=ops_false; - break; - } - - /* Application doesn't want it delivered parsed */ - if(!(pinfo->ss_parsed[t8]&t7)) - { - if(content.critical) - OPS_ERROR_1(&pinfo->errors,OPS_E_PROTO_CRITICAL_SS_IGNORED, - "Critical signature subpacket ignored (%d)", - c[0]&0x7f); - if(!read && !limited_skip(subregion.length-1,&subregion,pinfo)) - return 0; - // printf("skipped %d length %d\n",c[0]&0x7f,subregion.length); - if(read) - ops_parser_content_free(&content); - return 1; - } - - if(read && subregion.length_read != subregion.length) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", - subregion.length-subregion.length_read); - return 0; - } - - CBP(pinfo,content.tag,&content); - - return 1; - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type - \param ss_preferred_ska -*/ -void ops_ss_preferred_ska_free(ops_ss_preferred_ska_t *ss_preferred_ska) - { - data_free(&ss_preferred_ska->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type - \param ss_preferred_hash -*/ -void ops_ss_preferred_hash_free(ops_ss_preferred_hash_t *ss_preferred_hash) - { - data_free(&ss_preferred_hash->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_preferred_compression_free(ops_ss_preferred_compression_t *ss_preferred_compression) - { - data_free(&ss_preferred_compression->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_key_flags_free(ops_ss_key_flags_t *ss_key_flags) - { - data_free(&ss_key_flags->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_features_free(ops_ss_features_t *ss_features) - { - data_free(&ss_features->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_key_server_prefs_free(ops_ss_key_server_prefs_t *ss_key_server_prefs) - { - data_free(&ss_key_server_prefs->data); - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse several signature subpackets. - * - * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set. - * This function parses this length and then calls parse_one_signature_subpacket() for each subpacket until the - * entire set is consumed. - * - * This function does not call the callback directly, parse_one_signature_subpacket() does for each subpacket. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int parse_signature_subpackets(ops_signature_t *sig, - ops_region_t *region, - ops_parse_info_t *pinfo) - { - ops_region_t subregion; - ops_parser_content_t content; - - ops_init_subregion(&subregion,region); - if(!limited_read_scalar(&subregion.length,2,region,pinfo)) - return 0; - - if(subregion.length > region->length) - ERRP(pinfo,"Subpacket set too long"); - - while(subregion.length_read < subregion.length) - if(!parse_one_signature_subpacket(sig,&subregion,pinfo)) - return 0; - - if(subregion.length_read != subregion.length) - { - if(!limited_skip(subregion.length-subregion.length_read,&subregion, - pinfo)) - ERRP(pinfo,"Read failed while recovering from subpacket length mismatch"); - ERRP(pinfo,"Subpacket length mismatch"); - } - - return 1; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse a version 4 signature. - * - * This function parses a version 4 signature including all its hashed and unhashed subpackets. - * - * Once the signature packet has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - * - * \see RFC4880 5.2.3 - */ -static int parse_v4_signature(ops_region_t *region,ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - ops_parser_content_t content; - - //debug=1; - if (debug) - { fprintf(stderr, "\nparse_v4_signature\n"); } - - // clear signature - memset(&C.signature,'\0',sizeof C.signature); - - /* We need to hash the packet data from version through the hashed subpacket data */ - - C.signature.v4_hashed_data_start=pinfo->rinfo.alength-1; - - /* Set version,type,algorithms */ - - C.signature.info.version=OPS_V4; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.type=c[0]; - if (debug) - { fprintf(stderr, "signature type=%d\n", C.signature.info.type); } - - /* XXX: check signature type */ - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.key_algorithm=c[0]; - /* XXX: check algorithm */ - if (debug) - { fprintf(stderr, "key_algorithm=%d\n", C.signature.info.key_algorithm); } - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.signature.info.hash_algorithm=c[0]; - /* XXX: check algorithm */ - if (debug) - { fprintf(stderr, "hash_algorithm=%d %s\n", C.signature.info.hash_algorithm, ops_show_hash_algorithm(C.signature.info.hash_algorithm)); } - - CBP(pinfo,OPS_PTAG_CT_SIGNATURE_HEADER,&content); - - if(!parse_signature_subpackets(&C.signature,region,pinfo)) - return 0; - - C.signature.info.v4_hashed_data_length=pinfo->rinfo.alength - -C.signature.v4_hashed_data_start; - - // copy hashed subpackets - if (C.signature.info.v4_hashed_data) - free(C.signature.info.v4_hashed_data); - C.signature.info.v4_hashed_data=ops_mallocz(C.signature.info.v4_hashed_data_length); - - if (!pinfo->rinfo.accumulate) - { - /* We must accumulate, else we can't check the signature */ - fprintf(stderr,"*** ERROR: must set accumulate to true\n"); - return 0 ; //ASSERT(0); - } - - memcpy(C.signature.info.v4_hashed_data, - pinfo->rinfo.accumulated+C.signature.v4_hashed_data_start, - C.signature.info.v4_hashed_data_length); - - if(!parse_signature_subpackets(&C.signature,region,pinfo)) - return 0; - - if(!limited_read(C.signature.hash2,2,region,pinfo)) - return 0; - - switch(C.signature.info.key_algorithm) - { - case OPS_PKA_RSA: - if(!limited_read_mpi(&C.signature.info.signature.rsa.sig,region,pinfo)) - return 0; - break; - - case OPS_PKA_DSA: - if(!limited_read_mpi(&C.signature.info.signature.dsa.r,region,pinfo)) - ERRP(pinfo,"Error reading DSA r field in signature"); - if (!limited_read_mpi(&C.signature.info.signature.dsa.s,region,pinfo)) - ERRP(pinfo,"Error reading DSA s field in signature"); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - if(!limited_read_mpi(&C.signature.info.signature.elgamal.r,region,pinfo) - || !limited_read_mpi(&C.signature.info.signature.elgamal.s,region,pinfo)) - return 0; - break; - - case OPS_PKA_PRIVATE00: - case OPS_PKA_PRIVATE01: - case OPS_PKA_PRIVATE02: - case OPS_PKA_PRIVATE03: - case OPS_PKA_PRIVATE04: - case OPS_PKA_PRIVATE05: - case OPS_PKA_PRIVATE06: - case OPS_PKA_PRIVATE07: - case OPS_PKA_PRIVATE08: - case OPS_PKA_PRIVATE09: - case OPS_PKA_PRIVATE10: - if (!read_data(&C.signature.info.signature.unknown.data,region,pinfo)) - return 0; - break; - - default: - OPS_ERROR_1(&pinfo->errors,OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG, - "Bad v4 signature key algorithm (%s)", - ops_show_pka(C.signature.info.key_algorithm)); - return 0; - } - - if(region->length_read != region->length) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_R_UNCONSUMED_DATA, - "Unconsumed data (%d)", - region->length-region->length_read); - return 0; - } - - CBP(pinfo,OPS_PTAG_CT_SIGNATURE_FOOTER,&content); - - return 1; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse a signature subpacket. - * - * This function calls the appropriate function to handle v3 or v4 signatures. - * - * Once the signature packet has been parsed successfully, it is passed to the callback. - * - * \param *ptag Pointer to the Packet Tag. - * \param *reader Our reader - * \param *cb The callback - * \return 1 on success, 0 on error - */ -static int parse_signature(ops_region_t *region,ops_parse_info_t *pinfo) -{ - unsigned char c[1]=""; - ops_parser_content_t content; - - if(!(region->length_read == 0)) // ASSERT(region->length_read == 0) /* We should not have read anything so far */ - { - fprintf(stderr,"parse_signature: region read is not empty! Data is corrupted?") ; - return 0 ; - } - - memset(&content,'\0',sizeof content); - - if(!limited_read(c,1,region,pinfo)) - return 0; - - if(c[0] == 2 || c[0] == 3) - return parse_v3_signature(region,pinfo); - else if(c[0] == 4) - return parse_v4_signature(region,pinfo); - - OPS_ERROR_1(&pinfo->errors,OPS_E_PROTO_BAD_SIGNATURE_VRSN, - "Bad signature version (%d)",c[0]); - return 0; -} - -/** - \ingroup Core_ReadPackets - \brief Parse Compressed packet -*/ -static int parse_compressed(ops_region_t *region,ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - ops_parser_content_t content; - - if(pinfo->recursive_compression_depth > MAX_RECURSIVE_COMPRESSION_DEPTH) - { - fprintf(stderr,"Recursive compression down to depth 32. This is weird. Probably a packet crafted to crash PGP. Will be dropped!\n") ; - return 0 ; - } - - if(!limited_read(c,1,region,pinfo)) - return 0; - -pinfo->recursive_compression_depth++ ; - - C.compressed.type=c[0]; - - CBP(pinfo,OPS_PTAG_CT_COMPRESSED,&content); - - /* The content of a compressed data packet is more OpenPGP packets - once decompressed, so recursively handle them */ - - int res = ops_decompress(region,pinfo,C.compressed.type); - -pinfo->recursive_compression_depth-- ; - - return res ; - } - -/** - \ingroup Core_ReadPackets - \brief Parse a One Pass Signature packet -*/ -static int parse_one_pass(ops_region_t *region,ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - ops_parser_content_t content; - - if(!limited_read(&C.one_pass_signature.version,1,region,pinfo)) - return 0; - if(C.one_pass_signature.version != 3) - { - OPS_ERROR_1(&pinfo->errors,OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN, - "Bad one-pass signature version (%d)", - C.one_pass_signature.version); - return 0; - } - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.one_pass_signature.sig_type=c[0]; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.one_pass_signature.hash_algorithm=c[0]; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.one_pass_signature.key_algorithm=c[0]; - - if(!limited_read(C.one_pass_signature.keyid, - sizeof C.one_pass_signature.keyid,region,pinfo)) - return 0; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.one_pass_signature.nested=!!c[0]; - - CBP(pinfo,OPS_PTAG_CT_ONE_PASS_SIGNATURE,&content); - - // XXX: we should, perhaps, let the app choose whether to hash or not - ops_parse_hash_init(pinfo,C.one_pass_signature.hash_algorithm, - C.one_pass_signature.keyid); - - return 1; - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_userdefined_free(ops_ss_userdefined_t *ss_userdefined) - { - data_free(&ss_userdefined->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_reserved_free(ops_ss_unknown_t *ss_unknown) - { - data_free(&ss_unknown->data); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_notation_data_free(ops_ss_notation_data_t *ss_notation_data) - { - data_free(&ss_notation_data->name); - data_free(&ss_notation_data->value); - } - -void ops_ss_embedded_signature_free(ops_ss_embedded_signature_t *ss_embedded_signature) - { - data_free(&ss_embedded_signature->sig); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this signature sub-packet type -*/ -void ops_ss_revocation_reason_free(ops_ss_revocation_reason_t *ss_revocation_reason) - { - string_free(&ss_revocation_reason->text); - } - -/** - \ingroup Core_Create - \brief Free the memory used when parsing this packet type -*/ -void ops_trust_free(ops_trust_t *trust) - { - data_free(&trust->data); - } - -/** - \ingroup Core_ReadPackets - \brief Parse a Trust packet -*/ -static int -parse_trust (ops_region_t *region, ops_parse_info_t *pinfo) - { - ops_parser_content_t content; - - if(!read_data(&C.trust.data,region,pinfo)) - return 0; - - CBP(pinfo,OPS_PTAG_CT_TRUST, &content); - - return 1; - } - -/** - \ingroup Core_ReadPackets - \brief Parse a Literal Data packet -*/ -static int parse_literal_data(ops_region_t *region,ops_parse_info_t *pinfo) - { - ops_parser_content_t content; - unsigned char c[1]=""; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.literal_data_header.format=c[0]; - - if(!limited_read(c,1,region,pinfo)) - return 0; - if(!limited_read((unsigned char *)C.literal_data_header.filename,c[0], - region,pinfo)) - return 0; - C.literal_data_header.filename[c[0]]='\0'; - - if(!limited_read_time(&C.literal_data_header.modification_time,region,pinfo)) - return 0; - - CBP(pinfo,OPS_PTAG_CT_LITERAL_DATA_HEADER,&content); - - while(region->length_read < region->length) - { - unsigned l=region->length-region->length_read; - - C.literal_data_body.data = (unsigned char *)malloc(l) ; - - if(C.literal_data_body.data == NULL) - { - fprintf(stderr,"parse_literal_data(): cannot malloc for requested size %d.\n",l) ; - return 0 ; - } - - if(!limited_read(C.literal_data_body.data,l,region,pinfo)) - { - free(C.literal_data_body.data); - return 0; - } - - C.literal_data_body.length=l; - - ops_parse_hash_data(pinfo,C.literal_data_body.data,l); - - CBP(pinfo,OPS_PTAG_CT_LITERAL_DATA_BODY,&content); - free(C.literal_data_body.data); - } - - return 1; - } - -/** - * \ingroup Core_Create - * - * ops_secret_key_free() frees the memory associated with "key". Note that - * the key itself is not freed. - * - * \param key - */ - -void ops_secret_key_free(ops_secret_key_t *key) - { - switch(key->public_key.algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - free_BN(&key->key.rsa.d); - free_BN(&key->key.rsa.p); - free_BN(&key->key.rsa.q); - free_BN(&key->key.rsa.u); - break; - - case OPS_PKA_DSA: - free_BN(&key->key.dsa.x); - break; - - default: - fprintf(stderr,"ops_secret_key_free: Unknown algorithm: %d (%s)\n",key->public_key.algorithm, ops_show_pka(key->public_key.algorithm)); - //ASSERT(0); - } - - ops_public_key_free(&key->public_key); - } - -void ops_secret_key_copy(ops_secret_key_t *dst,const ops_secret_key_t *src) -{ - *dst = *src ; - ops_public_key_copy(&dst->public_key,&src->public_key); - - switch(src->public_key.algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - dst->key.rsa.d = BN_dup(src->key.rsa.d) ; - dst->key.rsa.p = BN_dup(src->key.rsa.p) ; - dst->key.rsa.q = BN_dup(src->key.rsa.q) ; - dst->key.rsa.u = BN_dup(src->key.rsa.u) ; - break; - - case OPS_PKA_DSA: - dst->key.dsa.x = BN_dup(src->key.dsa.x) ; - break; - - default: - fprintf(stderr,"ops_secret_key_copy: Unknown algorithm: %d (%s)\n",src->public_key.algorithm, ops_show_pka(src->public_key.algorithm)); - //ASSERT(0); - } -} -static int consume_packet(ops_region_t *region,ops_parse_info_t *pinfo, - ops_boolean_t warn) - { - ops_data_t remainder; - ops_parser_content_t content; - - if(region->indeterminate) - ERRP(pinfo,"Can't consume indeterminate packets"); - - if(read_data(&remainder,region,pinfo)) - { - /* now throw it away */ - data_free(&remainder); - if(warn) - OPS_ERROR(&pinfo->errors,OPS_E_P_PACKET_CONSUMED,"Warning: packet consumer"); - } - else if(warn) - OPS_ERROR(&pinfo->errors,OPS_E_P_PACKET_NOT_CONSUMED,"Warning: Packet was not consumed"); - else - { - OPS_ERROR(&pinfo->errors,OPS_E_P_PACKET_NOT_CONSUMED,"Packet was not consumed"); - return 0; - } - - return 1; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse a secret key - */ -static int parse_secret_key(ops_region_t *region,ops_parse_info_t *pinfo) -{ - ops_parser_content_t content; - unsigned char c[1]=""; - ops_crypt_t decrypt; - int ret=1; - ops_region_t encregion; - ops_region_t *saved_region=NULL; - ops_hash_t checkhash; - int blocksize; - ops_boolean_t crypted; - - if (debug) - { fprintf(stderr,"\n---------\nparse_secret_key:\n"); - fprintf(stderr,"region length=%d, length_read=%d, remainder=%d\n", region->length, region->length_read, region->length-region->length_read); - } - - memset(&content,'\0',sizeof content); - if(!parse_public_key_data(&C.secret_key.public_key,region,pinfo)) - return 0; - - if (debug) - { - fprintf(stderr,"parse_secret_key: public key parsed\n"); - ops_print_public_key(&C.secret_key.public_key); - } - - pinfo->reading_v3_secret=C.secret_key.public_key.version != OPS_V4; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.secret_key.s2k_usage=c[0]; - - if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED - || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) - { - if(!limited_read(c,1,region,pinfo)) - return 0; - C.secret_key.algorithm=c[0]; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.secret_key.s2k_specifier=c[0]; - - if(!(C.secret_key.s2k_specifier == OPS_S2KS_SIMPLE || C.secret_key.s2k_specifier == OPS_S2KS_SALTED || C.secret_key.s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED)) // ASSERT(C.secret_key.s2k_specifier == OPS_S2KS_SIMPLE || C.secret_key.s2k_specifier == OPS_S2KS_SALTED || C.secret_key.s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) - { - fprintf(stderr,"parse_secret_key: error in secret key format. Bad flags combination.\n") ; - return 0; - } - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.secret_key.hash_algorithm=c[0]; - - if(C.secret_key.s2k_specifier != OPS_S2KS_SIMPLE - && !limited_read(C.secret_key.salt,8,region,pinfo)) - { - return 0; - } - - if(C.secret_key.s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) - { - if(!limited_read(c,1,region,pinfo)) - return 0; - C.secret_key.octet_count=(16+(c[0]&15)) << ((c[0] >> 4)+6); - } - } - else if(C.secret_key.s2k_usage != OPS_S2KU_NONE) - { - // this is V3 style, looks just like a V4 simple hash - C.secret_key.algorithm=(ops_symmetric_algorithm_t)C.secret_key.s2k_usage; - C.secret_key.s2k_usage=OPS_S2KU_ENCRYPTED; - C.secret_key.s2k_specifier=OPS_S2KS_SIMPLE; - C.secret_key.hash_algorithm=OPS_HASH_MD5; - } - - crypted=C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED - || C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED; - - if(crypted) - { - int n; - ops_parser_content_t pc; - char *passphrase; - unsigned char key[OPS_MAX_KEY_SIZE+OPS_MAX_HASH_SIZE]; - ops_hash_t hashes[(OPS_MAX_KEY_SIZE+OPS_MIN_HASH_SIZE-1)/OPS_MIN_HASH_SIZE]; - int keysize; - int hashsize; - size_t l; - - blocksize=ops_block_size(C.secret_key.algorithm); - if(!(blocksize > 0 && blocksize <= OPS_MAX_BLOCK_SIZE)) // ASSERT(blocksize > 0 && blocksize <= OPS_MAX_BLOCK_SIZE); - { - fprintf(stderr,"parse_secret_key: block size error. Data seems corrupted.") ; - return 0; - } - - if(!limited_read(C.secret_key.iv,blocksize,region,pinfo)) - return 0; - - memset(&pc,'\0',sizeof pc); - passphrase=NULL; - pc.content.secret_key_passphrase.passphrase=&passphrase; - pc.content.secret_key_passphrase.secret_key=&C.secret_key; - CBP(pinfo,OPS_PARSER_CMD_GET_SK_PASSPHRASE,&pc); - if(!passphrase) - { - if (debug) - { - // \todo make into proper error - fprintf(stderr,"parse_secret_key: can't get passphrase\n"); - } - - if(!consume_packet(region,pinfo,ops_false)) - return 0; - - CBP(pinfo,OPS_PTAG_CT_ENCRYPTED_SECRET_KEY,&content); - - return 1; - } - - keysize=ops_key_size(C.secret_key.algorithm); - if(!(keysize > 0 && keysize <= OPS_MAX_KEY_SIZE)) // ASSERT(keysize > 0 && keysize <= OPS_MAX_KEY_SIZE); - { - fprintf(stderr,"parse_secret_key: keysize %d exceeds maximum allowed size %d\n",keysize,OPS_MAX_KEY_SIZE); - return 0 ; - } - - hashsize=ops_hash_size(C.secret_key.hash_algorithm); - if(!(hashsize > 0 && hashsize <= OPS_MAX_HASH_SIZE)) // ASSERT(hashsize > 0 && hashsize <= OPS_MAX_HASH_SIZE); - { - fprintf(stderr,"parse_secret_key: hashsize %d exceeds maximum allowed size %d\n",keysize,OPS_MAX_HASH_SIZE); - return 0 ; - } - - for(n=0 ; n*hashsize < keysize ; ++n) - { - int i; - - ops_hash_any(&hashes[n],C.secret_key.hash_algorithm); - hashes[n].init(&hashes[n]); - // preload hashes with zeroes... - for(i=0 ; i < n ; ++i) - hashes[n].add(&hashes[n],(unsigned char *)"",1); - } - - l=strlen(passphrase); - - for(n=0 ; n*hashsize < keysize ; ++n) - { - unsigned i; - - switch(C.secret_key.s2k_specifier) - { - case OPS_S2KS_SALTED: - hashes[n].add(&hashes[n],C.secret_key.salt,OPS_SALT_SIZE); - /* fallthrough */ - case OPS_S2KS_SIMPLE: - hashes[n].add(&hashes[n],(unsigned char*)passphrase,l); - break; - - case OPS_S2KS_ITERATED_AND_SALTED: - for(i=0 ; i < C.secret_key.octet_count ; i+=l+OPS_SALT_SIZE) - { - int j=l+OPS_SALT_SIZE; - - if(i+j > C.secret_key.octet_count && i != 0) - j=C.secret_key.octet_count-i; - - hashes[n].add(&hashes[n],C.secret_key.salt, - j > OPS_SALT_SIZE ? OPS_SALT_SIZE : j); - if(j > OPS_SALT_SIZE) - hashes[n].add(&hashes[n],(unsigned char *)passphrase,j-OPS_SALT_SIZE); - } - - } - } - - for(n=0 ; n*hashsize < keysize ; ++n) - { - int r=hashes[n].finish(&hashes[n],key+n*hashsize); - if(!(r == hashsize)) // ASSERT(r == hashsize); - { - fprintf(stderr,"parse_secret_key: read error. Data probably corrupted.") ; - return 0 ; - } - } - - free(passphrase); - - ops_crypt_any(&decrypt,C.secret_key.algorithm); - if (debug) - { - unsigned int i=0; - fprintf(stderr,"\nREADING:\niv="); - for (i=0; ilength-region->length_read; - if(C.secret_key.public_key.version != OPS_V4) - { - encregion.length-=2; - } - saved_region=region; - region=&encregion; - } - - if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) - { - ops_hash_sha1(&checkhash); - ops_reader_push_hash(pinfo,&checkhash); - } - else - { - ops_reader_push_sum16(pinfo); - } - - switch(C.secret_key.public_key.algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - if(!limited_read_mpi(&C.secret_key.key.rsa.d,region,pinfo) - || !limited_read_mpi(&C.secret_key.key.rsa.p,region,pinfo) - || !limited_read_mpi(&C.secret_key.key.rsa.q,region,pinfo) - || !limited_read_mpi(&C.secret_key.key.rsa.u,region,pinfo)) - ret=0; - - break; - - case OPS_PKA_DSA: - - if(!limited_read_mpi(&C.secret_key.key.dsa.x,region,pinfo)) - ret=0; - break; - - default: - OPS_ERROR_2(&pinfo->errors,OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG,"Unsupported Public Key algorithm %d (%s)",C.secret_key.public_key.algorithm,ops_show_pka(C.secret_key.public_key.algorithm)); - ret=0; - // ASSERT(0); - } - - if (debug) - { - fprintf(stderr,"4 MPIs read\n"); - // ops_print_secret_key_verbose(OPS_PTAG_CT_SECRET_KEY, &C.secret_key); - } - - pinfo->reading_v3_secret=ops_false; - - if(C.secret_key.s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) - { - unsigned char hash[20]; - - ops_reader_pop_hash(pinfo); - checkhash.finish(&checkhash,hash); - - if(crypted && C.secret_key.public_key.version != OPS_V4) - { - ops_reader_pop_decrypt(pinfo); - region=saved_region; - } - - if(ret) - { - if(!limited_read(C.secret_key.checkhash,20,region,pinfo)) - return 0; - - if(memcmp(hash,C.secret_key.checkhash,20)) - ERRP(pinfo,"Hash mismatch in secret key"); - } - } - else - { - unsigned short sum; - - sum=ops_reader_pop_sum16(pinfo); - - if(crypted && C.secret_key.public_key.version != OPS_V4) - { - ops_reader_pop_decrypt(pinfo); - region=saved_region; - } - - if(ret) - { - if(!limited_read_scalar(&C.secret_key.checksum,2,region, - pinfo)) - return 0; - - if(sum != C.secret_key.checksum) - ERRP(pinfo,"Checksum mismatch in secret key"); - } - } - - if(crypted && C.secret_key.public_key.version == OPS_V4) - { - ops_reader_pop_decrypt(pinfo); - } - - if(!(!ret || region->length_read == region->length)) // ASSERT(!ret || region->length_read == region->length) - { - fprintf(stderr,"parse_secret_key: read error. data probably corrupted.") ; - return 0 ; - } - - if(!ret) - return 0; - - CBP(pinfo,OPS_PTAG_CT_SECRET_KEY,&content); - - if (debug) - { fprintf(stderr, "--- end of parse_secret_key\n\n"); } - - return 1; -} - -/** - \ingroup Core_ReadPackets - \brief Parse a Public Key Session Key packet -*/ -static int parse_pk_session_key(ops_region_t *region, - ops_parse_info_t *pinfo) - { - unsigned char c[1]=""; - ops_parser_content_t content; - ops_parser_content_t pc; - - int n; - BIGNUM *enc_m; - unsigned k; - const ops_secret_key_t *secret; - unsigned char cs[2]; - unsigned char* iv; - - // Can't rely on it being CAST5 - // \todo FIXME RW - // const size_t sz_unencoded_m_buf=CAST_KEY_LENGTH+1+2; - const size_t sz_unencoded_m_buf=1024; - unsigned char unencoded_m_buf[sz_unencoded_m_buf]; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.pk_session_key.version=c[0]; - if(C.pk_session_key.version != OPS_PKSK_V3) - { - OPS_ERROR_1(&pinfo->errors, OPS_E_PROTO_BAD_PKSK_VRSN, - "Bad public-key encrypted session key version (%d)", - C.pk_session_key.version); - return 0; - } - - if(!limited_read(C.pk_session_key.key_id, - sizeof C.pk_session_key.key_id,region,pinfo)) - return 0; - - if (debug) - { - int i; - int x=sizeof C.pk_session_key.key_id; - printf("session key: public key id: x=%d\n",x); - for (i=0; ierrors, OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG, - "Unknown public key algorithm in session key (%s)", - ops_show_pka(C.pk_session_key.algorithm)); - return 0; - } - - memset(&pc,'\0',sizeof pc); - secret=NULL; - pc.content.get_secret_key.secret_key=&secret; - pc.content.get_secret_key.pk_session_key=&C.pk_session_key; - - CBP(pinfo,OPS_PARSER_CMD_GET_SECRET_KEY,&pc); - - if(!secret) - { - CBP(pinfo,OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,&content); - - return 1; - } - - // n=ops_decrypt_mpi(buf,sizeof buf,enc_m,secret); - n=ops_decrypt_and_unencode_mpi(unencoded_m_buf,sizeof unencoded_m_buf,enc_m,secret); - - if(n < 1) - { - ERRP(pinfo,"decrypted message too short"); - return 0; - } - - // PKA - C.pk_session_key.symmetric_algorithm=unencoded_m_buf[0]; - - if (!ops_is_sa_supported(C.pk_session_key.symmetric_algorithm)) - { - // ERR1P - OPS_ERROR_1(&pinfo->errors,OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG, - "Symmetric algorithm %s not supported", - ops_show_symmetric_algorithm(C.pk_session_key.symmetric_algorithm)); - return 0; - } - - k=ops_key_size(C.pk_session_key.symmetric_algorithm); - - if((unsigned)n != k+3) - { - OPS_ERROR_2(&pinfo->errors,OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN, - "decrypted message wrong length (got %d expected %d)", - n,k+3); - return 0; - } - - if(!(k <= sizeof C.pk_session_key.key)) // ASSERT(k <= sizeof C.pk_session_key.key); - { - fprintf(stderr,"ops_decrypt_se_data: error in session key size. Corrupted data?") ; - return 0 ; - } - - memcpy(C.pk_session_key.key,unencoded_m_buf+1,k); - - if (debug) - { - printf("session key recovered (len=%d):\n",k); - unsigned int j; - for(j=0; jerrors, OPS_E_PROTO_BAD_SK_CHECKSUM, - "Session key checksum wrong: expected %2x %2x, got %2x %2x", - cs[0], cs[1], unencoded_m_buf[k+1], unencoded_m_buf[k+2]); - return 0; - } - - // all is well - CBP(pinfo,OPS_PTAG_CT_PK_SESSION_KEY,&content); - - ops_crypt_any(&pinfo->decrypt,C.pk_session_key.symmetric_algorithm); - iv=ops_mallocz(pinfo->decrypt.blocksize); - pinfo->decrypt.set_iv(&pinfo->decrypt, iv); - pinfo->decrypt.set_key(&pinfo->decrypt,C.pk_session_key.key); - ops_encrypt_init(&pinfo->decrypt); - return 1; - } - -// XXX: make this static? -int ops_decrypt_se_data(ops_content_tag_t tag,ops_region_t *region, ops_parse_info_t *pinfo) -{ - int r=1; - ops_crypt_t *decrypt=ops_parse_get_decrypt(pinfo); - - if(decrypt) - { - unsigned char buf[OPS_MAX_BLOCK_SIZE+2]=""; - size_t b=decrypt->blocksize; - // ops_parser_content_t content; - ops_region_t encregion; - - - ops_reader_push_decrypt(pinfo,decrypt,region); - - ops_init_subregion(&encregion,NULL); - encregion.length=b+2; - - if(!exact_limited_read(buf,b+2,&encregion,pinfo)) - return 0; - - if(buf[b-2] != buf[b] || buf[b-1] != buf[b+1]) - { - ops_reader_pop_decrypt(pinfo); - OPS_ERROR_4(&pinfo->errors, OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT, - "Bad symmetric decrypt (%02x%02x vs %02x%02x)", - buf[b-2],buf[b-1],buf[b],buf[b+1]); - return 0; - } - - if(tag == OPS_PTAG_CT_SE_DATA_BODY) - { - decrypt->decrypt_resync(decrypt); - decrypt->block_encrypt(decrypt,decrypt->civ,decrypt->civ); - } - - - r=ops_parse(pinfo,ops_false); - - ops_reader_pop_decrypt(pinfo); - } - else - { - ops_parser_content_t content; - - while(region->length_read < region->length) - { - unsigned l=region->length-region->length_read; - - if(l > sizeof C.se_data_body.data) - l=sizeof C.se_data_body.data; - - if(!limited_read(C.se_data_body.data,l,region,pinfo)) - return 0; - - C.se_data_body.length=l; - - CBP(pinfo,tag,&content); - } - } - - return r; -} - -int ops_decrypt_se_ip_data(ops_content_tag_t tag,ops_region_t *region, - ops_parse_info_t *pinfo) -{ - int r=1; - ops_crypt_t *decrypt=ops_parse_get_decrypt(pinfo); - - if(decrypt) - { - ops_reader_push_decrypt(pinfo,decrypt,region); - ops_reader_push_se_ip_data(pinfo,decrypt,region); - - r=ops_parse(pinfo,ops_false); - - ops_reader_pop_se_ip_data(pinfo); - ops_reader_pop_decrypt(pinfo); - } - else - { - ops_parser_content_t content; - - while(region->length_read < region->length) - { - unsigned l=region->length-region->length_read; - - if(l > sizeof C.se_data_body.data) - l=sizeof C.se_data_body.data; - - if(!limited_read(C.se_data_body.data,l,region,pinfo)) - return 0; - - C.se_data_body.length=l; - - CBP(pinfo,tag,&content); - } - } - - return r; -} - -/** - \ingroup Core_ReadPackets - \brief Read a Symmetrically Encrypted packet -*/ -static int parse_se_data(ops_region_t *region,ops_parse_info_t *pinfo) - { - ops_parser_content_t content; - - /* there's no info to go with this, so just announce it */ - CBP(pinfo,OPS_PTAG_CT_SE_DATA_HEADER,&content); - - /* The content of an encrypted data packet is more OpenPGP packets - once decrypted, so recursively handle them */ - return ops_decrypt_se_data(OPS_PTAG_CT_SE_DATA_BODY,region,pinfo); - } - -/** - \ingroup Core_ReadPackets - \brief Read a Symmetrically Encrypted Integrity Protected packet -*/ -static int parse_se_ip_data(ops_region_t *region,ops_parse_info_t *pinfo) -{ - unsigned char c[1]=""; - ops_parser_content_t content; - - if(!limited_read(c,1,region,pinfo)) - return 0; - C.se_ip_data_header.version=c[0]; - - if(!(C.se_ip_data_header.version == OPS_SE_IP_V1)) // ASSERT(C.se_ip_data_header.version == OPS_SE_IP_V1); - { - fprintf(stderr,"parse_se_ip_data: packet header version should be %d, it is %d. Packet dropped.",OPS_SE_IP_V1,C.se_ip_data_header.version) ; - return 0 ; - } - - /* The content of an encrypted data packet is more OpenPGP packets - once decrypted, so recursively handle them */ - return ops_decrypt_se_ip_data(OPS_PTAG_CT_SE_IP_DATA_BODY,region,pinfo); -} - -/** - \ingroup Core_ReadPackets - \brief Read a MDC packet -*/ -static int parse_mdc(ops_region_t *region, ops_parse_info_t *pinfo) - { - ops_parser_content_t content; - - if (!limited_read((unsigned char *)&C.mdc,OPS_SHA1_HASH_SIZE,region,pinfo)) - return 0; - - CBP(pinfo,OPS_PTAG_CT_MDC,&content); - - return 1; - } - -/** - * \ingroup Core_ReadPackets - * \brief Parse one packet. - * - * This function parses the packet tag. It computes the value of the - * content tag and then calls the appropriate function to handle the - * content. - * - * \param *pinfo How to parse - * \param *pktlen On return, will contain number of bytes in packet - * \return 1 on success, 0 on error, -1 on EOF */ -static int ops_parse_one_packet(ops_parse_info_t *pinfo, - unsigned long *pktlen) - { - unsigned char ptag[1]; - ops_parser_content_t content; - int r; - ops_region_t region; - ops_boolean_t indeterminate=ops_false; - - C.ptag.position=pinfo->rinfo.position; - - r=base_read(ptag,1,pinfo); - - // errors in the base read are effectively EOF. - if(r <= 0) - return -1; - - *pktlen=0; - - if(!(*ptag&OPS_PTAG_ALWAYS_SET)) - { - C.error.error="Format error (ptag bit not set)"; - CBP(pinfo,OPS_PARSER_ERROR,&content); - OPS_ERROR(&pinfo->errors, OPS_E_P_UNKNOWN_TAG, C.error.error); - return 0; - } - C.ptag.new_format=!!(*ptag&OPS_PTAG_NEW_FORMAT); - if(C.ptag.new_format) - { - C.ptag.content_tag=*ptag&OPS_PTAG_NF_CONTENT_TAG_MASK; - C.ptag.length_type=0; - if(!read_new_length(&C.ptag.length,pinfo)) - return 0; - - } - else - { - ops_boolean_t rb = ops_false; - - C.ptag.content_tag=(*ptag&OPS_PTAG_OF_CONTENT_TAG_MASK) - >> OPS_PTAG_OF_CONTENT_TAG_SHIFT; - C.ptag.length_type=*ptag&OPS_PTAG_OF_LENGTH_TYPE_MASK; - switch(C.ptag.length_type) - { - case OPS_PTAG_OF_LT_ONE_BYTE: - rb=_read_scalar(&C.ptag.length,1,pinfo); - break; - - case OPS_PTAG_OF_LT_TWO_BYTE: - rb=_read_scalar(&C.ptag.length,2,pinfo); - break; - - case OPS_PTAG_OF_LT_FOUR_BYTE: - rb=_read_scalar(&C.ptag.length,4,pinfo); - break; - - case OPS_PTAG_OF_LT_INDETERMINATE: - C.ptag.length=0; - indeterminate=ops_true; - rb=ops_true; - break; - } - if(!rb) - { - OPS_ERROR(&pinfo->errors, OPS_E_P, "Cannot read tag length"); - return 0; - } - } - - CBP(pinfo,OPS_PARSER_PTAG,&content); - - ops_init_subregion(®ion,NULL); - region.length=C.ptag.length; - region.indeterminate=indeterminate; - switch(C.ptag.content_tag) - { - case OPS_PTAG_CT_SIGNATURE: - r=parse_signature(®ion,pinfo); - break; - - case OPS_PTAG_CT_PUBLIC_KEY: - case OPS_PTAG_CT_PUBLIC_SUBKEY: - r=parse_public_key(C.ptag.content_tag,®ion,pinfo); - break; - - case OPS_PTAG_CT_TRUST: - r=parse_trust(®ion, pinfo); - break; - - case OPS_PTAG_CT_USER_ID: - r=parse_user_id(®ion,pinfo); - break; - - case OPS_PTAG_CT_COMPRESSED: - r=parse_compressed(®ion,pinfo); - break; - - case OPS_PTAG_CT_ONE_PASS_SIGNATURE: - r=parse_one_pass(®ion,pinfo); - break; - - case OPS_PTAG_CT_LITERAL_DATA: - r=parse_literal_data(®ion,pinfo); - break; - - case OPS_PTAG_CT_USER_ATTRIBUTE: - r=parse_user_attribute(®ion,pinfo); - break; - - case OPS_PTAG_CT_SECRET_KEY: - r=parse_secret_key(®ion,pinfo); - break; - - case OPS_PTAG_CT_SECRET_SUBKEY: - r=parse_secret_key(®ion,pinfo); - break; - - case OPS_PTAG_CT_PK_SESSION_KEY: - r=parse_pk_session_key(®ion,pinfo); - break; - - case OPS_PTAG_CT_SE_DATA: - r=parse_se_data(®ion,pinfo); - break; - - case OPS_PTAG_CT_SE_IP_DATA: - r=parse_se_ip_data(®ion,pinfo); - break; - - case OPS_PTAG_CT_MDC: - r=parse_mdc(®ion, pinfo); - break; - - default: - OPS_ERROR_1(&pinfo->errors,OPS_E_P_UNKNOWN_TAG, - "Unknown content tag 0x%x", C.ptag.content_tag); - r=0; - } - - /* Ensure that the entire packet has been consumed */ - - if(region.length != region.length_read && !region.indeterminate) - if(!consume_packet(®ion,pinfo,ops_false)) - r=-1; - - // also consume it if there's been an error? - // \todo decide what to do about an error on an - // indeterminate packet - if (r==0) - { - if (!consume_packet(®ion,pinfo,ops_false)) - r=-1; - } - - /* set pktlen */ - - *pktlen=pinfo->rinfo.alength; - - /* do callback on entire packet, if desired and there was no error */ - - if(r > 0 && pinfo->rinfo.accumulate) - { - C.packet.length=pinfo->rinfo.alength; - C.packet.raw=pinfo->rinfo.accumulated; - - CBP(pinfo,OPS_PARSER_PACKET_END,&content); - //free(pinfo->rinfo.accumulated); - pinfo->rinfo.accumulated=NULL; - pinfo->rinfo.asize=0; - } - else - C.packet.raw = NULL ; - - pinfo->rinfo.alength=0; - - if(r < 0) - return -1; - - return r ? 1 : 0; - } - -/** - * \ingroup Core_ReadPackets - * - * \brief Parse packets from an input stream until EOF or error. - * - * \details Setup the necessary parsing configuration in "pinfo" before calling ops_parse(). - * - * That information includes : - * - * - a "reader" function to be used to get the data to be parsed - * - * - a "callback" function to be called when this library has identified - * a parseable object within the data - * - * - whether the calling function wants the signature subpackets returned raw, parsed or not at all. - * - * After returning, pinfo->errors holds any errors encountered while parsing. - * - * \param pinfo Parsing configuration - * \return 1 on success in all packets, 0 on error in any packet - * - * \sa CoreAPI Overview - * - * \sa ops_print_errors(), ops_parse_and_print_errors() - * - * Example code - * \code -ops_parse_cb_t* example_callback(); -void example() - { - int fd=0; - ops_parse_info_t *pinfo=NULL; - char *filename="pubring.gpg"; - - // setup pinfo to read from file with example callback - fd=ops_setup_file_read(&pinfo, filename, NULL, example_callback, ops_false); - - // specify how we handle signature subpackets - ops_parse_options(pinfo, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); - - if (!ops_parse(pinfo)) - ops_print_errors(pinfo->errors); - - ops_teardown_file_read(pinfo,fd); - } - * \endcode - */ - -int ops_parse(ops_parse_info_t *pinfo,ops_boolean_t limit_packets) -{ - int r; - unsigned long pktlen; - int n_packets = 0 ; - - do - // Parse until we get a return code of 0 (error) or -1 (EOF) - { - r=ops_parse_one_packet(pinfo,&pktlen); - - if(++n_packets > 500 && limit_packets) - { - fprintf(stderr,"More than 500 packets parsed in a row. This is likely to be a buggy certificate.") ; - return 0 ; - } - } while (r > 0); - - return pinfo->errors ? 0 : 1; - //return r == -1 ? 0 : 1; -} - -/** -\ingroup Core_ReadPackets -\brief Parse packets and print any errors - * \param pinfo Parsing configuration - * \return 1 on success in all packets, 0 on error in any packet - * \sa CoreAPI Overview - * \sa ops_parse() -*/ - -int ops_parse_and_print_errors(ops_parse_info_t *pinfo) -{ - ops_parse(pinfo,ops_false); - ops_print_errors(pinfo->errors); - return pinfo->errors ? 0 : 1; -} - -/** - * \ingroup Core_ReadPackets - * - * \brief Specifies whether one or more signature - * subpacket types should be returned parsed; or raw; or ignored. - * - * \param pinfo Pointer to previously allocated structure - * \param tag Packet tag. OPS_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag - * \param type Parse type - * \todo Make all packet types optional, not just subpackets */ -void ops_parse_options(ops_parse_info_t *pinfo, - ops_content_tag_t tag, - ops_parse_type_t type) -{ - int t8,t7; - - if(tag == OPS_PTAG_SS_ALL) - { - int n; - - for(n=0 ; n < 256 ; ++n) - ops_parse_options(pinfo,OPS_PTAG_SIGNATURE_SUBPACKET_BASE+n, - type); - return; - } - - if(!(tag >= OPS_PTAG_SIGNATURE_SUBPACKET_BASE && tag <= OPS_PTAG_SIGNATURE_SUBPACKET_BASE+NTAGS-1)) // ASSERT(tag >= OPS_PTAG_SIGNATURE_SUBPACKET_BASE && tag <= OPS_PTAG_SIGNATURE_SUBPACKET_BASE+NTAGS-1) - { - fprintf(stderr,"ops_parse_options: format error in options. Will not be parsed. Correct your code!\n") ; - return ; - } - - t8=(tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE)/8; - t7=1 << ((tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE)&7); - switch(type) - { - case OPS_PARSE_RAW: - pinfo->ss_raw[t8] |= t7; - pinfo->ss_parsed[t8] &= ~t7; - break; - - case OPS_PARSE_PARSED: - pinfo->ss_raw[t8] &= ~t7; - pinfo->ss_parsed[t8] |= t7; - break; - - case OPS_PARSE_IGNORE: - pinfo->ss_raw[t8] &= ~t7; - pinfo->ss_parsed[t8] &= ~t7; - break; - } -} - -/** -\ingroup Core_ReadPackets -\brief Creates a new zero-ed ops_parse_info_t struct -\sa ops_parse_info_delete() -*/ -ops_parse_info_t *ops_parse_info_new(void) - { return ops_mallocz(sizeof(ops_parse_info_t)); } - -/** -\ingroup Core_ReadPackets -\brief Free ops_parse_info_t struct and its contents -\sa ops_parse_info_new() -*/ -void ops_parse_info_delete(ops_parse_info_t *pinfo) - { - ops_parse_cb_info_t *cbinfo,*next; - - for(cbinfo=pinfo->cbinfo.next ; cbinfo ; cbinfo=next) - { - next=cbinfo->next; - free(cbinfo); - } - if(pinfo->rinfo.destroyer) - pinfo->rinfo.destroyer(&pinfo->rinfo); - ops_free_errors(pinfo->errors); - if(pinfo->rinfo.accumulated) - free(pinfo->rinfo.accumulated); - free(pinfo); - } - -/** -\ingroup Core_ReadPackets -\brief Returns the parse_info's reader_info -\return Pointer to the reader_info inside the parse_info -*/ -ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo) - { return &pinfo->rinfo; } - -/** -\ingroup Core_ReadPackets -\brief Sets the parse_info's callback -This is used when adding the first callback in a stack of callbacks. -\sa ops_parse_cb_push() -*/ - -void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) - { - pinfo->cbinfo.cb=cb; - pinfo->cbinfo.arg=arg; - pinfo->cbinfo.errors=&pinfo->errors; - } - -/** -\ingroup Core_ReadPackets -\brief Adds a further callback to a stack of callbacks -\sa ops_parse_cb_set() -*/ -void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) - { - ops_parse_cb_info_t *cbinfo=malloc(sizeof *cbinfo); - - *cbinfo=pinfo->cbinfo; - pinfo->cbinfo.next=cbinfo; - ops_parse_cb_set(pinfo,cb,arg); - } - -/** -\ingroup Core_ReadPackets -\brief Returns callback's arg -*/ -void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo) - { return cbinfo->arg; } - -/** -\ingroup Core_ReadPackets -\brief Returns callback's errors -*/ -void *ops_parse_cb_get_errors(ops_parse_cb_info_t *cbinfo) - { return cbinfo->errors; } - -/** -\ingroup Core_ReadPackets -\brief Calls the parse_cb_info's callback if present -\return Return value from callback, if present; else OPS_FINISHED -*/ -ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, - ops_parse_cb_info_t *cbinfo) - { - if(cbinfo->cb) - return cbinfo->cb(content,cbinfo); - else - return OPS_FINISHED; - } - -/** -\ingroup Core_ReadPackets -\brief Calls the next callback in the stack -\return Return value from callback -*/ -ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, - ops_parse_cb_info_t *cbinfo) - { return ops_parse_cb(content,cbinfo->next); } - -/** -\ingroup Core_ReadPackets -\brief Returns the parse_info's errors -\return parse_info's errors -*/ -ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo) - { return pinfo->errors; } - -ops_crypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo) - { - if(pinfo->decrypt.algorithm) - return &pinfo->decrypt; - return NULL; - } - -// XXX: this could be improved by sharing all hashes that are the -// same, then duping them just before checking the signature. -void ops_parse_hash_init(ops_parse_info_t *pinfo,ops_hash_algorithm_t type, - const unsigned char *keyid) - { - ops_parse_hash_info_t *hash; - - pinfo->hashes=realloc(pinfo->hashes, - (pinfo->nhashes+1)*sizeof *pinfo->hashes); - hash=&pinfo->hashes[pinfo->nhashes++]; - - ops_hash_any(&hash->hash,type); - hash->hash.init(&hash->hash); - memcpy(hash->keyid,keyid,sizeof hash->keyid); - } - -void ops_parse_hash_data(ops_parse_info_t *pinfo,const void *data, - size_t length) - { - size_t n; - - for(n=0 ; n < pinfo->nhashes ; ++n) - pinfo->hashes[n].hash.add(&pinfo->hashes[n].hash,data,length); - } - -ops_hash_t *ops_parse_hash_find(ops_parse_info_t *pinfo, - const unsigned char keyid[OPS_KEY_ID_SIZE]) - { - size_t n; - - for(n=0 ; n < pinfo->nhashes ; ++n) - if(!memcmp(pinfo->hashes[n].keyid,keyid,OPS_KEY_ID_SIZE)) - return &pinfo->hashes[n].hash; - return NULL; - } - -/* vim:set textwidth=120: */ -/* vim:set ts=8: */ diff --git a/openpgpsdk/src/openpgpsdk/packet-parse.h b/openpgpsdk/src/openpgpsdk/packet-parse.h deleted file mode 100644 index fe65060c0..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-parse.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * Parser for OpenPGP packets - headers. - */ - -#ifndef OPS_PACKET_PARSE_H -#define OPS_PACKET_PARSE_H - -#include "types.h" -#include "packet.h" -#include "lists.h" - -/** ops_region_t */ -typedef struct ops_region - { - struct ops_region *parent; - unsigned length; - unsigned length_read; - unsigned last_read; /*!< length of last read, only valid in deepest child */ - ops_boolean_t indeterminate:1; - } ops_region_t; - -void ops_init_subregion(ops_region_t *subregion,ops_region_t *region); - -#if 0 -/** Return values for reader functions e.g. ops_packet_reader_t() */ -enum ops_reader_ret_t - { - OPS_R_OK =0, /*!< success */ - OPS_R_EOF =1, /*!< reached end of file, no data has been returned */ - OPS_R_EARLY_EOF =2, /*!< could not read the requested - number of bytes and either - OPS_RETURN_LENGTH was not set and at - least 1 byte was read, or there was - an abnormal end to the file (or - armoured block) */ - OPS_R_PARTIAL_READ =3, /*!< if OPS_RETURN_LENGTH is set and - the buffer was not filled */ - OPS_R_ERROR =4, /*!< if there was an error reading */ - }; -#endif - -/** ops_parse_callback_return_t */ -typedef enum - { - OPS_RELEASE_MEMORY, - OPS_KEEP_MEMORY, - OPS_FINISHED - } ops_parse_cb_return_t; - -typedef struct ops_parse_cb_info ops_parse_cb_info_t; - -typedef ops_parse_cb_return_t -ops_parse_cb_t(const ops_parser_content_t *content, - ops_parse_cb_info_t *cbinfo); - -typedef struct ops_parse_info ops_parse_info_t; -typedef struct ops_reader_info ops_reader_info_t; -typedef struct ops_crypt_info ops_crypt_info_t; - -/* - A reader MUST read at least one byte if it can, and should read up - to the number asked for. Whether it reads more for efficiency is - its own decision, but if it is a stacked reader it should never - read more than the length of the region it operates in (which it - would have to be given when it is stacked). - - If a read is short because of EOF, then it should return the short - read (obviously this will be zero on the second attempt, if not the - first). Because a reader is not obliged to do a full read, only a - zero return can be taken as an indication of EOF. - - If there is an error, then the callback should be notified, the - error stacked, and -1 should be returned. - - Note that although length is a size_t, a reader will never be asked - to read more than INT_MAX in one go. - - */ - -typedef int ops_reader_t(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo); - -typedef void ops_reader_destroyer_t(ops_reader_info_t *rinfo); - -ops_parse_info_t *ops_parse_info_new(void); -void ops_parse_info_delete(ops_parse_info_t *pinfo); -ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo); -ops_crypt_t *ops_parse_get_decrypt(ops_parse_info_t *pinfo); - -void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); -void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); -void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); -void *ops_parse_cb_get_errors(ops_parse_cb_info_t *cbinfo); -void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,ops_reader_destroyer_t *destroyer,void *arg); -void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,ops_reader_destroyer_t *destroyer,void *arg); -void ops_reader_pop(ops_parse_info_t *pinfo); -void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo); - -void *ops_reader_get_arg(ops_reader_info_t *rinfo); - -ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, - ops_parse_cb_info_t *cbinfo); -ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, - ops_parse_cb_info_t *cbinfo); -ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo); - -int ops_parse(ops_parse_info_t *parse_info,ops_boolean_t limit_packets); -int ops_parse_and_print_errors(ops_parse_info_t *parse_info); -int ops_parse_and_save_errs(ops_parse_info_t *parse_info,ops_ulong_list_t *errs); -int ops_parse_errs(ops_parse_info_t *parse_info,ops_ulong_list_t *errs); - -void ops_parse_and_validate(ops_parse_info_t *parse_info); - -void ops_parse_options(ops_parse_info_t *pinfo,ops_content_tag_t tag, - ops_parse_type_t type); - -ops_boolean_t ops_limited_read(unsigned char *dest,size_t length, - ops_region_t *region,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo); -ops_boolean_t ops_stacked_limited_read(void *dest,unsigned length, - ops_region_t *region, - ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo); -void ops_parse_hash_init(ops_parse_info_t *pinfo,ops_hash_algorithm_t type, - const unsigned char *keyid); -void ops_parse_hash_data(ops_parse_info_t *pinfo,const void *data, - size_t length); -void ops_parse_hash_finish(ops_parse_info_t *pinfo); -ops_hash_t *ops_parse_hash_find(ops_parse_info_t *pinfo, - const unsigned char keyid[OPS_KEY_ID_SIZE]); - -ops_reader_t ops_stacked_read; - -/* vim:set textwidth=120: */ -/* vim:set ts=8: */ - - -#endif diff --git a/openpgpsdk/src/openpgpsdk/packet-print.c b/openpgpsdk/src/openpgpsdk/packet-print.c deleted file mode 100644 index 012531aab..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-print.c +++ /dev/null @@ -1,1836 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*! \file - \brief Standard API print functions -*/ - -#include -#include -#include "openpgpsdk/crypto.h" -#include "openpgpsdk/keyring.h" -#include "keyring_local.h" -#include "parse_local.h" -#include "openpgpsdk/packet-show.h" -#include "openpgpsdk/util.h" -#include "openpgpsdk/std_print.h" -#include "openpgpsdk/readerwriter.h" -#include "openpgpsdk/armour.h" - -static int indent=0; - -void print_bn( const char *name, - const BIGNUM *bn); -static void print_hex(const unsigned char *src, - size_t length); -static void print_hexdump(const char *name, - const unsigned char *data, - unsigned int len); -static void print_hexdump_data(const char *name, - const unsigned char *data, - unsigned int len); -static void print_indent(); -static void print_name(const char *name); -static void print_string_and_value(char *name, - const char *str, - unsigned char value); -static void print_tagname(const char *str); -static void print_time( char *name, - time_t time); -static void print_time_short(time_t time); -static void print_unsigned_int(char *name, - unsigned int val); -static void showtime(const char *name,time_t t); -static void showtime_short(time_t t); - -/** - \ingroup Core_Print - - Prints a public key in succinct detail - - \param key Ptr to public key -*/ - -void -ops_print_public_keydata(const ops_keydata_t *key) - { - printf("pub "); - - ops_show_pka(key->key.pkey.algorithm); - printf(" "); - - hexdump(key->key_id, OPS_KEY_ID_SIZE); - printf(" "); - - print_time_short(key->key.pkey.creation_time); - printf(" "); - - if (key->nuids==1) - { - // print on same line as other info - printf ("%s\n", key->uids[0].user_id); - } - else - { - // print all uids on separate line - unsigned int i; - printf("\n"); - for (i=0; inuids; i++) - { - printf("uid %s\n",key->uids[i].user_id); - } - } - } - -/** -\ingroup Core_Print -\param pkey -*/ -void -ops_print_public_key(const ops_public_key_t *pkey) - { - printf("------- PUBLIC KEY ------\n"); - print_unsigned_int("Version",pkey->version); - print_time("Creation Time", pkey->creation_time); - if(pkey->version == OPS_V3) - print_unsigned_int("Days Valid",pkey->days_valid); - - print_string_and_value("Algorithm",ops_show_pka(pkey->algorithm), - pkey->algorithm); - - switch(pkey->algorithm) - { - case OPS_PKA_DSA: - print_bn("p",pkey->key.dsa.p); - print_bn("q",pkey->key.dsa.q); - print_bn("g",pkey->key.dsa.g); - print_bn("y",pkey->key.dsa.y); - break; - - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - print_bn("n",pkey->key.rsa.n); - print_bn("e",pkey->key.rsa.e); - break; - - case OPS_PKA_ELGAMAL: - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - print_bn("p",pkey->key.elgamal.p); - print_bn("g",pkey->key.elgamal.g); - print_bn("y",pkey->key.elgamal.y); - break; - - default: - assert(0); - } - - printf("------- end of PUBLIC KEY ------\n"); - } - -/** - \ingroup Core_Print - - Prints a public key in full detail - - \param key Ptr to public key -*/ - -void -ops_print_public_keydata_verbose(const ops_keydata_t *key) - { - const ops_public_key_t* pkey=&key->key.pkey; - - ops_print_public_key(pkey); - } - -/** - \ingroup Core_Print - - Prints a secret key - - \param key Ptr to public key -*/ - -void -ops_print_secret_keydata(const ops_keydata_t *key) - { - printf("sec "); - ops_show_pka(key->key.pkey.algorithm); - printf(" "); - - hexdump(key->key_id, OPS_KEY_ID_SIZE); - printf(" "); - - print_time_short(key->key.pkey.creation_time); - printf(" "); - - if (key->nuids==1) - { - // print on same line as other info - printf ("%s\n", key->uids[0].user_id); - } - else - { - // print all uids on separate line - unsigned int i; - printf("\n"); - for (i=0; inuids; i++) - { - printf("uid %s\n",key->uids[i].user_id); - } - } - } - -/* -void -ops_print_secret_key_verbose(const ops_secret_key_t* skey) - { - if(key->type == OPS_PTAG_CT_SECRET_KEY) - print_tagname("SECRET_KEY"); - else - print_tagname("ENCRYPTED_SECRET_KEY"); - ops_print_secret_key(key->type,skey); - } -*/ - -/** -\ingroup Core_Print -\param type -\param skey -*/ -void -ops_print_secret_key_verbose(const ops_content_tag_t type, const ops_secret_key_t* skey) - { - printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n"); - if(type == OPS_PTAG_CT_SECRET_KEY) - print_tagname("SECRET_KEY"); - else - print_tagname("ENCRYPTED_SECRET_KEY"); - // ops_print_public_key(key); - printf("S2K Usage: %d\n",skey->s2k_usage); - if(skey->s2k_usage != OPS_S2KU_NONE) - { - printf("S2K Specifier: %d\n",skey->s2k_specifier); - printf("Symmetric algorithm: %d (%s)\n",skey->algorithm, - ops_show_symmetric_algorithm(skey->algorithm)); - printf("Hash algorithm: %d (%s)\n",skey->hash_algorithm, - ops_show_hash_algorithm(skey->hash_algorithm)); - if(skey->s2k_specifier != OPS_S2KS_SIMPLE) - print_hexdump("Salt",skey->salt,sizeof skey->salt); - if(skey->s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) - printf("Octet count: %d\n",skey->octet_count); - print_hexdump("IV",skey->iv,ops_block_size(skey->algorithm)); - } - - /* no more set if encrypted */ - if(type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) - return; - - switch(skey->public_key.algorithm) - { - case OPS_PKA_RSA: - print_bn("d",skey->key.rsa.d); - print_bn("p",skey->key.rsa.p); - print_bn("q",skey->key.rsa.q); - print_bn("u",skey->key.rsa.u); - break; - - case OPS_PKA_DSA: - print_bn("x",skey->key.dsa.x); - break; - - default: - assert(0); - } - - if(skey->s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) - print_hexdump("Checkhash",skey->checkhash,OPS_CHECKHASH_SIZE); - else - printf("Checksum: %04x\n",skey->checksum); - - printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n"); - } - -/** -\ingroup Core_Print -\param key -*/ -void -ops_print_secret_keydata_verbose(const ops_keydata_t *key) - { - const ops_secret_key_t* skey=&key->key.skey; - ops_print_public_keydata(key); - ops_print_secret_key_verbose(key->type,skey); - } - -// static functions - -static void print_unsigned_int(char *name, unsigned int val) - { - print_name(name); - printf("%d\n", val); - } - -static void print_time( char *name, time_t time) - { - print_indent(); - printf("%s: ",name); - showtime("time",time); - printf("\n"); - } - -static void print_time_short(time_t time) - { - showtime_short(time); - } - -static void print_string_and_value(char *name,const char *str, - unsigned char value) - { - print_name(name); - - printf("%s", str); - printf(" (0x%x)", value); - printf("\n"); - } - -void print_bn( const char *name, const BIGNUM *bn) - { - print_indent(); - printf("%s=",name); - if(bn) - { - BN_print_fp(stdout,bn); - putchar('\n'); - } - else - puts("(unset)"); - } - -static void print_tagname(const char *str) - { - print_indent(); - printf("%s packet\n", str); - } - -static void print_hexdump(const char *name, - const unsigned char *data, - unsigned int len) - { - print_name(name); - - printf("len=%d, data=0x", len); - print_hex(data,len); - printf("\n"); - } - -static void print_hexdump_data(const char *name, - const unsigned char *data, - unsigned int len) - { - print_name(name); - - printf("0x"); - print_hex(data,len); - printf("\n"); - } - -static void print_data(const char *name,const ops_data_t *data) - { - print_hexdump(name,data->contents,data->len); - } - - -static void print_name(const char *name) - { - print_indent(); - if(name) - printf("%s: ",name); - } - -static void print_indent() - { - int i=0; - - for(i=0 ; i < indent ; i++) - printf(" "); - } - -/* printhex is now print_hex for consistency */ -static void print_hex(const unsigned char *src,size_t length) - { - while(length--) - printf("%02X",*src++); - } - -static void showtime(const char *name,time_t t) - { - printf("%s=" TIME_T_FMT " (%.24s)",name,t,ctime(&t)); - } -static void showtime_short(time_t t) - { - struct tm* tm; - /* - const int maxbuf=512; - char buf[maxbuf+1]; - buf[maxbuf]='\0'; - // this needs to be tm struct - strftime(buf,maxbuf,"%F",&t); - printf(buf); - */ - tm=gmtime(&t); - printf ("%04d-%02d-%02d", tm->tm_year+1900, tm->tm_mon, tm->tm_mday); - } - - -static void print_packet_hex(const ops_packet_t *packet) - { - unsigned char *cur; - int i; - int rem; - int blksz=4; - - printf("\nhexdump of packet contents follows:\n"); - - - for (i=1,cur=packet->raw; cur<(packet->raw+packet->length); cur+=blksz,i++) - { - rem = packet->raw+packet->length-cur; - hexdump(cur,rem<=blksz ? rem : blksz); - printf(" "); - if (!(i%8)) - printf("\n"); - - } - - printf("\n"); - } - -static void print_escaped(const unsigned char *data,size_t length) - { - while(length-- > 0) - { - if((*data >= 0x20 && *data < 0x7f && *data != '%') || *data == '\n') - putchar(*data); - else - printf("%%%02x",*data); - ++data; - } - } - -static void print_string(const char *name,const char *str) - { - print_name(name); - print_escaped((unsigned char *)str,strlen(str)); - putchar('\n'); - } - -static void print_utf8_string(const char *name,const unsigned char *str) - { - // \todo Do this better for non-English character sets - print_string(name,(const char *)str); - } - -static void print_duration(char *name, time_t time) - { - int mins, hours, days, years; - - print_indent(); - printf("%s: ",name); - printf("duration " TIME_T_FMT " seconds",time); - - mins=time/60; - hours=mins/60; - days=hours/24; - years=days/365; - - printf(" (approx. "); - if (years) - printf("%d %s",years,years==1?"year":"years"); - else if (days) - printf("%d %s",days,days==1?"day":"days"); - else if (hours) - printf("%d %s", hours, hours==1?"hour":"hours"); - - printf(")"); - printf("\n"); - } - -static void print_boolean(const char *name, unsigned char bool) - { - print_name(name); - - if(bool) - printf("Yes"); - else - printf("No"); - printf("\n"); - } - -static void print_text_breakdown( ops_text_t *text) - { - unsigned i; - char *prefix=".. "; - - /* these were recognised */ - - for(i=0 ; iknown.used ; i++) - { - print_indent(); - fputs(prefix,stdout); - printf("%s\n",text->known.strings[i]); - } - - /* these were not recognised. the strings will contain the hex value - of the unrecognised value in string format - see process_octet_str() - */ - - if(text->unknown.used) - { - printf("\n"); - print_indent(); - printf("Not Recognised: "); - } - for( i=0; i < text->unknown.used; i++) - { - print_indent(); - fputs(prefix,stdout); - printf("%s\n",text->unknown.strings[i]); - } - - } - -static void print_headers(const ops_headers_t *headers) - { - unsigned n; - - for(n=0 ; n < headers->nheaders ; ++n) - printf("%s=%s\n",headers->headers[n].key,headers->headers[n].value); - } - -static void print_block(const char *name,const unsigned char *str, - size_t length) - { - int o=length; - - print_indent(); - printf(">>>>> %s >>>>>\n",name); - - print_indent(); - for( ; length > 0 ; --length) - { - if(*str >= 0x20 && *str < 0x7f && *str != '%') - putchar(*str); - else if(*str == '\n') - { - putchar(*str); - print_indent(); - } - else - printf("%%%02x",*str); - ++str; - } - if(o && str[-1] != '\n') - { - putchar('\n'); - print_indent(); - fputs("[no newline]",stdout); - } - else - print_indent(); - printf("<<<<< %s <<<<<\n",name); - } - -/** -\ingroup Core_Print -\param tag -\param key -*/ -void ops_print_pk_session_key(ops_content_tag_t tag, - const ops_pk_session_key_t *key) - { - if(tag == OPS_PTAG_CT_PK_SESSION_KEY) - print_tagname("PUBLIC KEY SESSION KEY"); - else - print_tagname("ENCRYPTED PUBLIC KEY SESSION KEY"); - - printf("Version: %d\n",key->version); - print_hexdump("Key ID",key->key_id,sizeof key->key_id); - printf("Algorithm: %d (%s)\n",key->algorithm, - ops_show_pka(key->algorithm)); - switch(key->algorithm) - { - case OPS_PKA_RSA: - print_bn("encrypted_m",key->parameters.rsa.encrypted_m); - break; - - case OPS_PKA_ELGAMAL: - print_bn("g_to_k",key->parameters.elgamal.g_to_k); - print_bn("encrypted_m",key->parameters.elgamal.encrypted_m); - break; - - default: - assert(0); - } - - if(tag != OPS_PTAG_CT_PK_SESSION_KEY) - return; - - printf("Symmetric algorithm: %d (%s)\n",key->symmetric_algorithm, - ops_show_symmetric_algorithm(key->symmetric_algorithm)); - print_hexdump("Key",key->key,ops_key_size(key->symmetric_algorithm)); - printf("Checksum: %04x\n",key->checksum); - } - -static void start_subpacket(unsigned type) - { - indent++; - print_indent(); - printf("-- %s (type 0x%02x)\n", - ops_show_ss_type(type), - type-OPS_PTAG_SIGNATURE_SUBPACKET_BASE); - } - -static void end_subpacket() - { - indent--; - } - -/** -\ingroup Core_Print -\param content_ -*/ -int ops_print_packet(const ops_parser_content_t *content_) - { - const ops_parser_content_union_t *content=&content_->content; - ops_text_t *text; - const char *str; - static ops_boolean_t unarmoured; - - if(unarmoured && content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT) - { - unarmoured=ops_false; - puts("UNARMOURED TEXT ends"); - } - - if (content_->tag==OPS_PARSER_PTAG) - { - printf("=> OPS_PARSER_PTAG: %s\n", ops_show_packet_tag(content->ptag.content_tag)); - } - else - { - printf("=> %s\n", ops_show_packet_tag(content_->tag)); - } - - switch(content_->tag) - { - case OPS_PARSER_ERROR: - printf("parse error: %s\n",content->error.error); - break; - - case OPS_PARSER_ERRCODE: - printf("parse error: %s\n", - ops_errcode(content->errcode.errcode)); - break; - - case OPS_PARSER_PACKET_END: - print_packet_hex(&content->packet); - break; - - case OPS_PARSER_PTAG: - if(content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY) - { - indent=0; - printf("\n*** NEXT KEY ***\n"); - } - - printf("\n"); - print_indent(); - printf("==== ptag new_format=%d content_tag=%d length_type=%d" - " length=0x%x (%d) position=0x%x (%d)\n",content->ptag.new_format, - content->ptag.content_tag,content->ptag.length_type, - content->ptag.length,content->ptag.length, - content->ptag.position,content->ptag.position); - print_tagname(ops_show_packet_tag(content->ptag.content_tag)); - break; - - case OPS_PTAG_CT_SE_DATA_HEADER: - print_tagname("SYMMETRIC ENCRYPTED DATA"); - break; - - case OPS_PTAG_CT_SE_IP_DATA_HEADER: - print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER"); - printf("Version: %d\n",content->se_ip_data_header.version); - break; - - case OPS_PTAG_CT_SE_IP_DATA_BODY: - print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY"); - printf(" data body length=%d\n", - content->se_data_body.length); - printf(" data="); - hexdump(content->se_data_body.data, - content->se_data_body.length); - printf("\n"); - break; - - case OPS_PTAG_CT_PUBLIC_KEY: - case OPS_PTAG_CT_PUBLIC_SUBKEY: - if (content_->tag == OPS_PTAG_CT_PUBLIC_KEY) - print_tagname("PUBLIC KEY"); - else - print_tagname("PUBLIC SUBKEY"); - ops_print_public_key(&content->public_key); - break; - - case OPS_PTAG_CT_TRUST: - print_tagname("TRUST"); - print_data("Trust",&content->trust.data); - break; - - case OPS_PTAG_CT_USER_ID: - /* XXX: how do we print UTF-8? */ - print_tagname("USER ID"); - print_utf8_string("user_id",content->user_id.user_id); - break; - - case OPS_PTAG_CT_SIGNATURE: - print_tagname("SIGNATURE"); - print_indent(); - print_unsigned_int("Signature Version", - content->signature.info.version); - if (content->signature.info.creation_time_set) - print_time("Signature Creation Time", - content->signature.info.creation_time); - - print_string_and_value("Signature Type", - ops_show_sig_type(content->signature.info.type), - content->signature.info.type); - - if(content->signature.info.signer_id_set) - print_hexdump_data("Signer ID", - content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->signature.info.key_algorithm), - content->signature.info.key_algorithm); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->signature.info.hash_algorithm), - content->signature.info.hash_algorithm); - - print_unsigned_int("Hashed data len", content->signature.info.v4_hashed_data_length); - - print_indent(); - print_hexdump_data("hash2",&content->signature.hash2[0],2); - - switch(content->signature.info.key_algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_SIGN_ONLY: - print_bn("sig",content->signature.info.signature.rsa.sig); - break; - - case OPS_PKA_DSA: - print_bn("r",content->signature.info.signature.dsa.r); - print_bn("s",content->signature.info.signature.dsa.s); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - print_bn("r",content->signature.info.signature.elgamal.r); - print_bn("s",content->signature.info.signature.elgamal.s); - break; - - default: - assert(0); - } - - if(content->signature.hash) - printf("data hash is set\n"); - - break; - - case OPS_PTAG_CT_COMPRESSED: - print_tagname("COMPRESSED"); - print_unsigned_int("Compressed Data Type", content->compressed.type); - break; - - case OPS_PTAG_CT_ONE_PASS_SIGNATURE: - print_tagname("ONE PASS SIGNATURE"); - - print_unsigned_int("Version",content->one_pass_signature.version); - print_string_and_value("Signature Type", - ops_show_sig_type(content->one_pass_signature.sig_type), - content->one_pass_signature.sig_type); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->one_pass_signature.hash_algorithm), - content->one_pass_signature.hash_algorithm); - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->one_pass_signature.key_algorithm), - content->one_pass_signature.key_algorithm); - print_hexdump_data("Signer ID", - content->one_pass_signature.keyid, - sizeof content->one_pass_signature.keyid); - - print_unsigned_int("Nested", - content->one_pass_signature.nested); - break; - - case OPS_PTAG_CT_USER_ATTRIBUTE: - print_tagname("USER ATTRIBUTE"); - print_hexdump("User Attribute", - content->user_attribute.data.contents, - content->user_attribute.data.len); - break; - - case OPS_PTAG_RAW_SS: - assert(!content_->critical); - start_subpacket(content_->tag); - print_unsigned_int("Raw Signature Subpacket: tag", - content->ss_raw.tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE); - print_hexdump("Raw Data", - content->ss_raw.raw, - content->ss_raw.length); - break; - - case OPS_PTAG_SS_CREATION_TIME: - start_subpacket(content_->tag); - print_time("Signature Creation Time",content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_EXPIRATION_TIME: - start_subpacket(content_->tag); - print_duration("Signature Expiration Time",content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_EXPIRATION_TIME: - start_subpacket(content_->tag); - print_duration("Key Expiration Time", content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_TRUST: - start_subpacket(content_->tag); - print_string("Trust Signature",""); - print_unsigned_int("Level", - content->ss_trust.level); - print_unsigned_int("Amount", - content->ss_trust.amount); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCABLE: - start_subpacket(content_->tag); - print_boolean("Revocable",content->ss_revocable.revocable); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCATION_KEY: - start_subpacket(content_->tag); - /* not yet tested */ - printf (" revocation key: class=0x%x", - content->ss_revocation_key.clss); - if (content->ss_revocation_key.clss&0x40) - printf (" (sensitive)"); - printf (", algid=0x%x", content->ss_revocation_key.algid); - printf(", fingerprint="); - hexdump(content->ss_revocation_key.fingerprint,20); - printf("\n"); - end_subpacket(); - break; - - case OPS_PTAG_SS_ISSUER_KEY_ID: - start_subpacket(content_->tag); - print_hexdump("Issuer Key Id", &content->ss_issuer_key_id.key_id[0], - sizeof content->ss_issuer_key_id.key_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_SKA: - start_subpacket(content_->tag); - print_data( "Preferred Symmetric Algorithms", - &content->ss_preferred_ska.data); - - text = ops_showall_ss_preferred_ska(content->ss_preferred_ska); - print_text_breakdown(text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_PRIMARY_USER_ID: - start_subpacket(content_->tag); - print_boolean("Primary User ID", - content->ss_primary_user_id.primary_user_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_HASH: - start_subpacket(content_->tag); - print_data("Preferred Hash Algorithms", - &content->ss_preferred_hash.data); - - text = ops_showall_ss_preferred_hash(content->ss_preferred_hash); - print_text_breakdown(text); - ops_text_free(text); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_COMPRESSION: - start_subpacket(content_->tag); - print_data( "Preferred Compression Algorithms", - &content->ss_preferred_compression.data); - - text = ops_showall_ss_preferred_compression(content->ss_preferred_compression); - print_text_breakdown(text); - ops_text_free(text); - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_FLAGS: - start_subpacket(content_->tag); - print_data( "Key Flags", &content->ss_key_flags.data); - - text = ops_showall_ss_key_flags(content->ss_key_flags); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_SERVER_PREFS: - start_subpacket(content_->tag); - print_data( "Key Server Preferences", - &content->ss_key_server_prefs.data); - - text = ops_showall_ss_key_server_prefs(content->ss_key_server_prefs); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_FEATURES: - start_subpacket(content_->tag); - print_data( "Features", - &content->ss_features.data); - - text = ops_showall_ss_features(content->ss_features); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_NOTATION_DATA: - start_subpacket(content_->tag); - print_indent(); - printf("Notation Data:\n"); - - indent++; - print_data( "Flags", - &content->ss_notation_data.flags); - text = ops_showall_ss_notation_data_flags(content->ss_notation_data); - print_text_breakdown( text); - ops_text_free(text); - - /* xxx - TODO: print out UTF - rachel */ - - print_data( "Name", - &content->ss_notation_data.name); - - print_data( "Value", - &content->ss_notation_data.value); - - indent--; - end_subpacket(); - break; - - case OPS_PTAG_SS_REGEXP: - start_subpacket(content_->tag); - print_hexdump("Regular Expression", - (unsigned char *)content->ss_regexp.text, - strlen(content->ss_regexp.text)); - print_string(NULL, - content->ss_regexp.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_POLICY_URI: - start_subpacket(content_->tag); - print_string("Policy URL", - content->ss_policy_url.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_SIGNERS_USER_ID: - start_subpacket(content_->tag); - print_utf8_string("Signer's User ID",content->ss_signers_user_id.user_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_KEY_SERVER: - start_subpacket(content_->tag); - print_string("Preferred Key Server", - content->ss_preferred_key_server.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_EMBEDDED_SIGNATURE: - start_subpacket(content_->tag); - end_subpacket(); // \todo print out contents? - break; - - case OPS_PTAG_SS_USERDEFINED00: - case OPS_PTAG_SS_USERDEFINED01: - case OPS_PTAG_SS_USERDEFINED02: - case OPS_PTAG_SS_USERDEFINED03: - case OPS_PTAG_SS_USERDEFINED04: - case OPS_PTAG_SS_USERDEFINED05: - case OPS_PTAG_SS_USERDEFINED06: - case OPS_PTAG_SS_USERDEFINED07: - case OPS_PTAG_SS_USERDEFINED08: - case OPS_PTAG_SS_USERDEFINED09: - case OPS_PTAG_SS_USERDEFINED10: - start_subpacket(content_->tag); - print_hexdump("Internal or user-defined", - content->ss_userdefined.data.contents, - content->ss_userdefined.data.len); - end_subpacket(); - break; - - case OPS_PTAG_SS_RESERVED: - start_subpacket(content_->tag); - print_hexdump("Reserved", - content->ss_userdefined.data.contents, - content->ss_userdefined.data.len); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCATION_REASON: - start_subpacket(content_->tag); - print_hexdump("Revocation Reason", - &content->ss_revocation_reason.code, - 1); - str=ops_show_ss_rr_code(content->ss_revocation_reason.code); - print_string(NULL,str); - /* xxx - todo : output text as UTF-8 string */ - end_subpacket(); - break; - - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - print_tagname("LITERAL DATA HEADER"); - printf(" literal data header format=%c filename='%s'\n", - content->literal_data_header.format, - content->literal_data_header.filename); - showtime(" modification time", - content->literal_data_header.modification_time); - printf("\n"); - break; - - case OPS_PTAG_CT_LITERAL_DATA_BODY: - print_tagname("LITERAL DATA BODY"); - printf(" literal data body length=%d\n", - content->literal_data_body.length); - printf(" data="); - print_escaped(content->literal_data_body.data, - content->literal_data_body.length); - printf("\n"); - break; - - case OPS_PTAG_CT_SIGNATURE_HEADER: - print_tagname("SIGNATURE"); - print_indent(); - print_unsigned_int("Signature Version", - content->signature.info.version); - if(content->signature.info.creation_time_set) - print_time("Signature Creation Time", content->signature.info.creation_time); - - print_string_and_value("Signature Type", - ops_show_sig_type(content->signature.info.type), - content->signature.info.type); - - if(content->signature.info.signer_id_set) - print_hexdump_data("Signer ID", - content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->signature.info.key_algorithm), - content->signature.info.key_algorithm); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->signature.info.hash_algorithm), - content->signature.info.hash_algorithm); - - break; - - case OPS_PTAG_CT_SIGNATURE_FOOTER: - print_indent(); - print_hexdump_data("hash2",&content->signature.hash2[0],2); - - switch(content->signature.info.key_algorithm) - { - case OPS_PKA_RSA: - print_bn("sig",content->signature.info.signature.rsa.sig); - break; - - case OPS_PKA_DSA: - print_bn("r",content->signature.info.signature.dsa.r); - print_bn("s",content->signature.info.signature.dsa.s); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - print_bn("r",content->signature.info.signature.elgamal.r); - print_bn("s",content->signature.info.signature.elgamal.s); - break; - - case OPS_PKA_PRIVATE00: - case OPS_PKA_PRIVATE01: - case OPS_PKA_PRIVATE02: - case OPS_PKA_PRIVATE03: - case OPS_PKA_PRIVATE04: - case OPS_PKA_PRIVATE05: - case OPS_PKA_PRIVATE06: - case OPS_PKA_PRIVATE07: - case OPS_PKA_PRIVATE08: - case OPS_PKA_PRIVATE09: - case OPS_PKA_PRIVATE10: - print_data("Private/Experimental", - &content->signature.info.signature.unknown.data); - break; - - default: - assert(0); - } - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - print_tagname("OPS_PARSER_CMD_GET_SK_PASSPHRASE"); - /* - if(passphrase_prompt) - { - print_secret_key(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY, - content->secret_key_passphrase.secret_key); - *content->secret_key_passphrase.passphrase=ops_get_passphrase(); - if(!**content->secret_key_passphrase.passphrase) - break; - return OPS_KEEP_MEMORY; - } - else - printf(">>> ASKED FOR PASSPHRASE <<<\n"); - */ - - break; - - case OPS_PTAG_CT_SECRET_KEY: - print_tagname("OPS_PTAG_CT_SECRET_KEY"); - ops_print_secret_key_verbose(content_->tag,&content->secret_key); - break; - - case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: - // print_secret_key(content_->tag,&content->secret_key); - print_tagname("OPS_PTAG_CT_ENCRYPTED_SECRET_KEY"); - ops_print_secret_key_verbose(content_->tag,&content->secret_key); - break; - - case OPS_PTAG_CT_ARMOUR_HEADER: - print_tagname("ARMOUR HEADER"); - print_string("type",content->armour_header.type); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - print_tagname("SIGNED CLEARTEXT HEADER"); - print_headers(&content->signed_cleartext_header.headers); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: - print_tagname("SIGNED CLEARTEXT BODY"); - print_block("signed cleartext",content->signed_cleartext_body.data, - content->signed_cleartext_body.length); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - print_tagname("SIGNED CLEARTEXT TRAILER"); - printf("hash algorithm: %d\n", - content->signed_cleartext_trailer.hash->algorithm); - printf("\n"); - break; - - case OPS_PTAG_CT_UNARMOURED_TEXT: - if(!unarmoured) - { - print_tagname("UNARMOURED TEXT"); - unarmoured=ops_true; - } - putchar('['); - print_escaped(content->unarmoured_text.data, - content->unarmoured_text.length); - putchar(']'); - break; - - case OPS_PTAG_CT_ARMOUR_TRAILER: - print_tagname("ARMOUR TRAILER"); - print_string("type",content->armour_header.type); - break; - - case OPS_PTAG_CT_PK_SESSION_KEY: - case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - ops_print_pk_session_key(content_->tag,&content->pk_session_key); - break; - - case OPS_PARSER_CMD_GET_SECRET_KEY: - ops_print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, - content->get_secret_key.pk_session_key); - break; - - default: - print_tagname("UNKNOWN PACKET TYPE"); - fprintf(stderr,"ops_print_packet: unknown tag=%d (0x%x)\n",content_->tag, - content_->tag); - exit(1); - } - return 1; - } - -static ops_parse_cb_return_t cb_list_packets(const ops_parser_content_t * content_, ops_parse_cb_info_t *cbinfo) - { - OPS_USED(cbinfo); - - ops_print_packet(content_); -#ifdef XXX - if(unarmoured && content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT) - { - unarmoured=ops_false; - puts("UNARMOURED TEXT ends"); - } - - switch(content_->tag) - { - case OPS_PARSER_ERROR: - printf("parse error: %s\n",content->error.error); - break; - - case OPS_PARSER_ERRCODE: - printf("parse error: %s\n", - ops_errcode(content->errcode.errcode)); - break; - - case OPS_PARSER_PACKET_END: - print_packet_hex(&content->packet); - break; - - case OPS_PARSER_PTAG: - if(content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY) - { - indent=0; - printf("\n*** NEXT KEY ***\n"); - } - - printf("\n"); - print_indent(); - printf("==== ptag new_format=%d content_tag=%d length_type=%d" - " length=0x%x (%d) position=0x%x (%d)\n",content->ptag.new_format, - content->ptag.content_tag,content->ptag.length_type, - content->ptag.length,content->ptag.length, - content->ptag.position,content->ptag.position); - print_tagname(ops_show_packet_tag(content->ptag.content_tag)); - break; - - case OPS_PTAG_CT_SE_DATA_HEADER: - print_tagname("SYMMETRIC ENCRYPTED DATA"); - break; - - case OPS_PTAG_CT_SE_IP_DATA_HEADER: - print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER"); - printf("Version: %d\n",content->se_ip_data_header.version); - break; - - case OPS_PTAG_CT_SE_IP_DATA_BODY: - print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY"); - printf(" data body length=%d\n", - content->se_data_body.length); - printf(" data="); - hexdump(content->se_data_body.data, - content->se_data_body.length); - printf("\n"); - break; - - case OPS_PTAG_CT_PUBLIC_KEY: - case OPS_PTAG_CT_PUBLIC_SUBKEY: - if (content_->tag == OPS_PTAG_CT_PUBLIC_KEY) - print_tagname("PUBLIC KEY"); - else - print_tagname("PUBLIC SUBKEY"); - - ops_print_public_key(&content->public_key); - break; - - case OPS_PTAG_CT_TRUST: - print_tagname("TRUST"); - print_data("Trust",&content->trust.data); - break; - - case OPS_PTAG_CT_USER_ID: - /* XXX: how do we print UTF-8? */ - print_tagname("USER ID"); - print_utf8_string("user_id",content->user_id.user_id); - break; - - case OPS_PTAG_CT_SIGNATURE: - print_tagname("SIGNATURE"); - print_indent(); - print_unsigned_int("Signature Version", - content->signature.info.version); - if (content->signature.info.creation_time_set) - print_time("Signature Creation Time", - content->signature.info.creation_time); - - print_string_and_value("Signature Type", - ops_show_sig_type(content->signature.info.type), - content->signature.info.type); - - if(content->signature.info.signer_id_set) - print_hexdump_data("Signer ID", - content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->signature.info.key_algorithm), - content->signature.info.key_algorithm); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->signature.info.hash_algorithm), - content->signature.info.hash_algorithm); - print_unsigned_int("Hashed data len", content->signature.info.v4_hashed_data_length); - - print_indent(); - print_hexdump_data("hash2",&content->signature.hash2[0],2); - - switch(content->signature.info.key_algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_SIGN_ONLY: - print_bn("sig",content->signature.info.signature.rsa.sig); - break; - - case OPS_PKA_DSA: - print_bn("r",content->signature.info.signature.dsa.r); - print_bn("s",content->signature.info.signature.dsa.s); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - print_bn("r",content->signature.info.signature.elgamal.r); - print_bn("s",content->signature.info.signature.elgamal.s); - break; - - default: - assert(0); - } - - if(content->signature.hash) - printf("data hash is set\n"); - - break; - - case OPS_PTAG_CT_COMPRESSED: - print_tagname("COMPRESSED"); - print_unsigned_int("Compressed Data Type", content->compressed.type); - break; - - case OPS_PTAG_CT_ONE_PASS_SIGNATURE: - print_tagname("ONE PASS SIGNATURE"); - - print_unsigned_int("Version",content->one_pass_signature.version); - print_string_and_value("Signature Type", - ops_show_sig_type(content->one_pass_signature.sig_type), - content->one_pass_signature.sig_type); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->one_pass_signature.hash_algorithm), - content->one_pass_signature.hash_algorithm); - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->one_pass_signature.key_algorithm), - content->one_pass_signature.key_algorithm); - print_hexdump_data("Signer ID", - content->one_pass_signature.keyid, - sizeof content->one_pass_signature.keyid); - - print_unsigned_int("Nested", - content->one_pass_signature.nested); - break; - - case OPS_PTAG_CT_USER_ATTRIBUTE: - print_tagname("USER ATTRIBUTE"); - print_hexdump("User Attribute", - content->user_attribute.data.contents, - content->user_attribute.data.len); - break; - - case OPS_PTAG_RAW_SS: - assert(!content_->critical); - start_subpacket(content_->tag); - print_unsigned_int("Raw Signature Subpacket: tag", - content->ss_raw.tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE); - print_hexdump("Raw Data", - content->ss_raw.raw, - content->ss_raw.length); - break; - - case OPS_PTAG_SS_CREATION_TIME: - start_subpacket(content_->tag); - print_time("Signature Creation Time",content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_EXPIRATION_TIME: - start_subpacket(content_->tag); - print_duration("Signature Expiration Time",content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_EXPIRATION_TIME: - start_subpacket(content_->tag); - print_duration("Key Expiration Time", content->ss_time.time); - end_subpacket(); - break; - - case OPS_PTAG_SS_TRUST: - start_subpacket(content_->tag); - print_string("Trust Signature",""); - print_unsigned_int("Level", - content->ss_trust.level); - print_unsigned_int("Amount", - content->ss_trust.amount); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCABLE: - start_subpacket(content_->tag); - print_boolean("Revocable",content->ss_revocable.revocable); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCATION_KEY: - start_subpacket(content_->tag); - /* not yet tested */ - printf (" revocation key: class=0x%x", - content->ss_revocation_key.clss); - if (content->ss_revocation_key.clss&0x40) - printf (" (sensitive)"); - printf (", algid=0x%x", content->ss_revocation_key.algid); - printf(", fingerprint="); - hexdump(content->ss_revocation_key.fingerprint,20); - printf("\n"); - end_subpacket(); - break; - - case OPS_PTAG_SS_ISSUER_KEY_ID: - start_subpacket(content_->tag); - print_hexdump("Issuer Key Id", - &content->ss_issuer_key_id.key_id[0], - sizeof content->ss_issuer_key_id.key_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_SKA: - start_subpacket(content_->tag); - print_data( "Preferred Symmetric Algorithms", - &content->ss_preferred_ska.data); - - text = ops_showall_ss_preferred_ska(content->ss_preferred_ska); - print_text_breakdown(text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_PRIMARY_USER_ID: - start_subpacket(content_->tag); - print_boolean("Primary User ID", - content->ss_primary_user_id.primary_user_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_HASH: - start_subpacket(content_->tag); - print_data("Preferred Hash Algorithms", - &content->ss_preferred_hash.data); - - text = ops_showall_ss_preferred_hash(content->ss_preferred_hash); - print_text_breakdown(text); - ops_text_free(text); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_COMPRESSION: - start_subpacket(content_->tag); - print_data( "Preferred Compression Algorithms", - &content->ss_preferred_compression.data); - - text = ops_showall_ss_preferred_compression(content->ss_preferred_compression); - print_text_breakdown(text); - ops_text_free(text); - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_FLAGS: - start_subpacket(content_->tag); - print_data( "Key Flags", &content->ss_key_flags.data); - - text = ops_showall_ss_key_flags(content->ss_key_flags); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_KEY_SERVER_PREFS: - start_subpacket(content_->tag); - print_data( "Key Server Preferences", - &content->ss_key_server_prefs.data); - - text = ops_showall_ss_key_server_prefs(content->ss_key_server_prefs); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_FEATURES: - start_subpacket(content_->tag); - print_data( "Features", - &content->ss_features.data); - - text = ops_showall_ss_features(content->ss_features); - print_text_breakdown( text); - ops_text_free(text); - - end_subpacket(); - break; - - case OPS_PTAG_SS_NOTATION_DATA: - start_subpacket(content_->tag); - print_indent(); - printf("Notation Data:\n"); - - indent++; - print_data( "Flags", - &content->ss_notation_data.flags); - text = ops_showall_ss_notation_data_flags(content->ss_notation_data); - print_text_breakdown( text); - ops_text_free(text); - - /* xxx - TODO: print out UTF - rachel */ - - print_data( "Name", - &content->ss_notation_data.name); - - print_data( "Value", - &content->ss_notation_data.value); - - indent--; - end_subpacket(); - break; - - case OPS_PTAG_SS_REGEXP: - start_subpacket(content_->tag); - print_hexdump("Regular Expression", - (unsigned char *)content->ss_regexp.text, - strlen(content->ss_regexp.text)); - print_string(NULL, - content->ss_regexp.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_POLICY_URL: - start_subpacket(content_->tag); - print_string("Policy URL", - content->ss_policy_url.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_SIGNERS_USER_ID: - start_subpacket(content_->tag); - print_utf8_string("Signer's User ID",content->ss_signers_user_id.user_id); - end_subpacket(); - break; - - case OPS_PTAG_SS_PREFERRED_KEY_SERVER: - start_subpacket(content_->tag); - print_string("Preferred Key Server", - content->ss_preferred_key_server.text); - end_subpacket(); - break; - - case OPS_PTAG_SS_USERDEFINED00: - case OPS_PTAG_SS_USERDEFINED01: - case OPS_PTAG_SS_USERDEFINED02: - case OPS_PTAG_SS_USERDEFINED03: - case OPS_PTAG_SS_USERDEFINED04: - case OPS_PTAG_SS_USERDEFINED05: - case OPS_PTAG_SS_USERDEFINED06: - case OPS_PTAG_SS_USERDEFINED07: - case OPS_PTAG_SS_USERDEFINED08: - case OPS_PTAG_SS_USERDEFINED09: - case OPS_PTAG_SS_USERDEFINED10: - start_subpacket(content_->tag); - print_hexdump("Internal or user-defined", - content->ss_userdefined.data.contents, - content->ss_userdefined.data.len); - end_subpacket(); - break; - - case OPS_PTAG_SS_RESERVED: - start_subpacket(content_->tag); - print_hexdump("Reserved", - content->ss_userdefined.data.contents, - content->ss_userdefined.data.len); - end_subpacket(); - break; - - case OPS_PTAG_SS_REVOCATION_REASON: - start_subpacket(content_->tag); - print_hexdump("Revocation Reason", - &content->ss_revocation_reason.code, - 1); - str=ops_show_ss_rr_code(content->ss_revocation_reason.code); - print_string(NULL,str); - /* xxx - todo : output text as UTF-8 string */ - end_subpacket(); - break; - - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - print_tagname("LITERAL DATA HEADER"); - printf(" literal data header format=%c filename='%s'\n", - content->literal_data_header.format, - content->literal_data_header.filename); - print_time(" modification time", - content->literal_data_header.modification_time); - printf("\n"); - break; - - case OPS_PTAG_CT_LITERAL_DATA_BODY: - print_tagname("LITERAL DATA BODY"); - printf(" literal data body length=%d\n", - content->literal_data_body.length); - printf(" data="); - print_escaped(content->literal_data_body.data, - content->literal_data_body.length); - printf("\n"); - break; - - case OPS_PTAG_CT_SIGNATURE_HEADER: - print_tagname("SIGNATURE"); - print_indent(); - print_unsigned_int("Signature Version", - content->signature.info.version); - if(content->signature.info.creation_time_set) - print_time("Signature Creation Time", content->signature.info.creation_time); - - print_string_and_value("Signature Type", - ops_show_sig_type(content->signature.info.type), - content->signature.info.type); - - if(content->signature.info.signer_id_set) - print_hexdump_data("Signer ID", - content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - - print_string_and_value("Public Key Algorithm", - ops_show_pka(content->signature.info.key_algorithm), - content->signature.info.key_algorithm); - print_string_and_value("Hash Algorithm", - ops_show_hash_algorithm(content->signature.info.hash_algorithm), - content->signature.info.hash_algorithm); - - break; - - case OPS_PTAG_CT_SIGNATURE_FOOTER: - print_indent(); - print_hexdump_data("hash2",&content->signature.hash2[0],2); - - switch(content->signature.info.key_algorithm) - { - case OPS_PKA_RSA: - print_bn("sig",content->signature.info.signature.rsa.sig); - break; - - case OPS_PKA_DSA: - print_bn("r",content->signature.info.signature.dsa.r); - print_bn("s",content->signature.info.signature.dsa.s); - break; - - case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: - print_bn("r",content->signature.info.signature.elgamal.r); - print_bn("s",content->signature.info.signature.elgamal.s); - break; - - case OPS_PKA_PRIVATE00: - case OPS_PKA_PRIVATE01: - case OPS_PKA_PRIVATE02: - case OPS_PKA_PRIVATE03: - case OPS_PKA_PRIVATE04: - case OPS_PKA_PRIVATE05: - case OPS_PKA_PRIVATE06: - case OPS_PKA_PRIVATE07: - case OPS_PKA_PRIVATE08: - case OPS_PKA_PRIVATE09: - case OPS_PKA_PRIVATE10: - print_data("Private/Experimental", - &content->signature.info.signature.unknown.data); - break; - - default: - assert(0); - } - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: -#ifdef XXX - if(passphrase_prompt) - { - ops_print_secret_key(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY, - content->secret_key_passphrase.secret_key); - *content->secret_key_passphrase.passphrase=ops_get_passphrase(); - if(!**content->secret_key_passphrase.passphrase) - break; - return OPS_KEEP_MEMORY; - } - else - printf(">>> ASKED FOR PASSPHRASE <<<\n"); -#else - if (cbinfo->cryptinfo.cb_get_passphrase) - return cbinfo->cryptinfo.cb_get_passphrase(content_,cbinfo); -#endif /*XXX*/ - break; - - case OPS_PTAG_CT_SECRET_KEY: - case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: - ops_print_secret_key_verbose(content_->tag,&content->secret_key); - break; - - case OPS_PTAG_CT_ARMOUR_HEADER: - print_tagname("ARMOUR HEADER"); - print_string("type",content->armour_header.type); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - print_tagname("SIGNED CLEARTEXT HEADER"); - print_headers(&content->signed_cleartext_header.headers); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: - print_tagname("SIGNED CLEARTEXT BODY"); - print_block("signed cleartext",content->signed_cleartext_body.data, - content->signed_cleartext_body.length); - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - print_tagname("SIGNED CLEARTEXT TRAILER"); - printf("hash algorithm: %d\n", - content->signed_cleartext_trailer.hash->algorithm); - printf("\n"); - break; - - case OPS_PTAG_CT_UNARMOURED_TEXT: - if(!unarmoured) - { - print_tagname("UNARMOURED TEXT"); - unarmoured=ops_true; - } - putchar('['); - print_escaped(content->unarmoured_text.data, - content->unarmoured_text.length); - putchar(']'); - break; - - case OPS_PTAG_CT_ARMOUR_TRAILER: - print_tagname("ARMOUR TRAILER"); - print_string("type",content->armour_header.type); - break; - - case OPS_PTAG_CT_PK_SESSION_KEY: - case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: - ops_print_pk_session_key(content_->tag,&content->pk_session_key); - break; - - case OPS_PARSER_CMD_GET_SECRET_KEY: - ops_print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, - content->get_secret_key.pk_session_key); - -#ifdef XXX - decrypter=ops_keyring_find_key_by_id(&keyring, - content->get_secret_key.pk_session_key->key_id); - if(!decrypter || !ops_key_is_secret(decrypter)) - break; - - puts("[Decryption key found in keyring]"); - - secret=ops_get_secret_key_from_data(decrypter); - while(!secret) - { - /* then it must be encrypted */ - char *phrase=ops_get_passphrase(); - secret=ops_decrypt_secret_key_from_data(decrypter,phrase); - free(phrase); - } - - *content->get_secret_key.secret_key=secret; -#else - return callback_cmd_get_secret_key(content_,cbinfo); -#endif /*XXX*/ - break; - - default: - print_tagname("UNKNOWN PACKET TYPE"); - fprintf(stderr,"packet-dump: unknown tag=%d (0x%x)\n",content_->tag, - content_->tag); - exit(1); - } -#endif /*XXX*/ - return OPS_RELEASE_MEMORY; - } - -/** -\ingroup Core_Print -\param filename -\param armour -\param keyring -\param cb_get_passphrase -*/ -void ops_list_packets(char* filename, ops_boolean_t armour, ops_keyring_t* keyring, ops_parse_cb_t* cb_get_passphrase) - { - int fd=0; - ops_parse_info_t *pinfo=NULL; - const ops_boolean_t accumulate=ops_true; - - fd=ops_setup_file_read(&pinfo, filename, NULL, cb_list_packets, accumulate); - ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); - pinfo->cryptinfo.keyring=keyring; - pinfo->cryptinfo.cb_get_passphrase=cb_get_passphrase; - - if(armour) - ops_reader_push_dearmour(pinfo); - - ops_parse_and_print_errors(pinfo); - - ops_teardown_file_read(pinfo,fd); - } diff --git a/openpgpsdk/src/openpgpsdk/packet-show-cast.h b/openpgpsdk/src/openpgpsdk/packet-show-cast.h deleted file mode 100644 index b5c8b0ab4..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-show-cast.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Generated from packet-show.cast by ../../util/caster.pl, do not edit. */ - -#include "types.h" - -/* (line 4) char *show_packet_tag(ops_packet_tag_t packet_tag, packet_tag_map_t *packet_tag_map) -> char *ops_str_from_map(int packet_tag, ops_map_t *packet_tag_map) */ -char *ops_str_from_map(int packet_tag, ops_map_t *packet_tag_map); -#define show_packet_tag(packet_tag,packet_tag_map) ops_str_from_map(CHECKED_INSTANCE_OF(ops_packet_tag_t , packet_tag),CHECKED_INSTANCE_OF( packet_tag_map_t *, packet_tag_map)) -typedef char * show_packet_tag_t(ops_packet_tag_t , packet_tag_map_t *); - -/* (line 5) char *show_sig_type(ops_sig_type_t sig_type, sig_type_map_t *sig_type_map) -> char *ops_str_from_map(int sig_type, ops_map_t *sig_type_map) */ -char *ops_str_from_map(int sig_type, ops_map_t *sig_type_map); -#define show_sig_type(sig_type,sig_type_map) ops_str_from_map(CHECKED_INSTANCE_OF(ops_sig_type_t , sig_type),CHECKED_INSTANCE_OF( sig_type_map_t *, sig_type_map)) -typedef char * show_sig_type_t(ops_sig_type_t , sig_type_map_t *); - -/* (line 6) char *show_pka(ops_public_key_algorithm_t pka, public_key_algorithm_map_t *pka_map) -> char *ops_str_from_map(int pka, ops_map_t *pka_map) */ -char *ops_str_from_map(int pka, ops_map_t *pka_map); -#define show_pka(pka,pka_map) ops_str_from_map(CHECKED_INSTANCE_OF(ops_public_key_algorithm_t , pka),CHECKED_INSTANCE_OF( public_key_algorithm_map_t *, pka_map)) -typedef char * show_pka_t(ops_public_key_algorithm_t , public_key_algorithm_map_t *); - -/* (line 7) char *show_ss_type(ops_ss_type_t ss_type, ss_type_map_t *ss_type_map) -> char *ops_str_from_map(int ss_type, ops_map_t *ss_type_map) */ -char *ops_str_from_map(int ss_type, ops_map_t *ss_type_map); -#define show_ss_type(ss_type,ss_type_map) ops_str_from_map(CHECKED_INSTANCE_OF(ops_ss_type_t , ss_type),CHECKED_INSTANCE_OF( ss_type_map_t *, ss_type_map)) -typedef char * show_ss_type_t(ops_ss_type_t , ss_type_map_t *); - -/* (line 8) char *show_ss_rr_code(ops_ss_rr_code_t ss_rr_code, ss_rr_code_map_t *ss_rr_code_map) -> char *ops_str_from_map(int ss_rr_code, ops_map_t *ss_rr_code_map) */ -char *ops_str_from_map(int ss_rr_code, ops_map_t *ss_rr_code_map); -#define show_ss_rr_code(ss_rr_code,ss_rr_code_map) ops_str_from_map(CHECKED_INSTANCE_OF(ops_ss_rr_code_t , ss_rr_code),CHECKED_INSTANCE_OF( ss_rr_code_map_t *, ss_rr_code_map)) -typedef char * show_ss_rr_code_t(ops_ss_rr_code_t , ss_rr_code_map_t *); - -/* (line 9) char *show_hash_algorithm(unsigned char hash,+ops_map_t *hash_algorithm_map) -> char *ops_str_from_map(int hash,ops_map_t *hash_algorithm_map) */ -char *ops_str_from_map(int hash,ops_map_t *hash_algorithm_map); -#define show_hash_algorithm(hash) ops_str_from_map(CHECKED_INSTANCE_OF(unsigned char , hash),CHECKED_INSTANCE_OF(ops_map_t *, hash_algorithm_map)) -typedef char * show_hash_algorithm_t(unsigned char ); - -/* (line 10) char *show_symmetric_algorithm(unsigned char hash,+ops_map_t *symmetric_algorithm_map) -> char *ops_str_from_map(int hash,ops_map_t *symmetric_algorithm_map) */ -char *ops_str_from_map(int hash,ops_map_t *symmetric_algorithm_map); -#define show_symmetric_algorithm(hash) ops_str_from_map(CHECKED_INSTANCE_OF(unsigned char , hash),CHECKED_INSTANCE_OF(ops_map_t *, symmetric_algorithm_map)) -typedef char * show_symmetric_algorithm_t(unsigned char ); diff --git a/openpgpsdk/src/openpgpsdk/packet-show.c b/openpgpsdk/src/openpgpsdk/packet-show.c deleted file mode 100644 index 8be6c7563..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-show.c +++ /dev/null @@ -1,857 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * - * Creates printable text strings from packet contents - * - */ - -#include - -#include -#include - -#include -#include - -#include - -/* - * Arrays of value->text maps - */ - -static ops_map_t packet_tag_map[] = - { - { OPS_PTAG_CT_RESERVED, "Reserved" }, - { OPS_PTAG_CT_PK_SESSION_KEY, "Public-Key Encrypted Session Key" }, - { OPS_PTAG_CT_SIGNATURE, "Signature" }, - { OPS_PTAG_CT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key" }, - { OPS_PTAG_CT_ONE_PASS_SIGNATURE, "One-Pass Signature" }, - { OPS_PTAG_CT_SECRET_KEY, "Secret Key" }, - { OPS_PTAG_CT_PUBLIC_KEY, "Public Key" }, - { OPS_PTAG_CT_SECRET_SUBKEY, "Secret Subkey" }, - { OPS_PTAG_CT_COMPRESSED, "Compressed Data" }, - { OPS_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data" }, - { OPS_PTAG_CT_MARKER, "Marker" }, - { OPS_PTAG_CT_LITERAL_DATA, "Literal Data" }, - { OPS_PTAG_CT_TRUST, "Trust" }, - { OPS_PTAG_CT_USER_ID, "User ID" }, - { OPS_PTAG_CT_PUBLIC_SUBKEY, "Public Subkey" }, - { OPS_PTAG_CT_RESERVED2, "reserved" }, - { OPS_PTAG_CT_RESERVED3, "reserved" }, - { OPS_PTAG_CT_USER_ATTRIBUTE, "User Attribute" }, - { OPS_PTAG_CT_SE_IP_DATA, "Sym. Encrypted and Integrity Protected Data" }, - { OPS_PTAG_CT_MDC, "Modification Detection Code" }, - { OPS_PARSER_PTAG, "OPS_PARSER_PTAG" }, - { OPS_PTAG_RAW_SS, "OPS_PTAG_RAW_SS" }, - { OPS_PTAG_SS_ALL, "OPS_PTAG_SS_ALL" }, - { OPS_PARSER_PACKET_END, "OPS_PARSER_PACKET_END" }, - { OPS_PTAG_SIGNATURE_SUBPACKET_BASE, "OPS_PTAG_SIGNATURE_SUBPACKET_BASE" }, - - { OPS_PTAG_SS_CREATION_TIME, "SS: Signature Creation Time" }, - { OPS_PTAG_SS_EXPIRATION_TIME, "SS: Signature Expiration Time" }, - { OPS_PTAG_SS_EXPORTABLE_CERTIFICATION, "SS: Exportable Certification" }, - { OPS_PTAG_SS_TRUST, "SS: Trust Signature" }, - { OPS_PTAG_SS_REGEXP, "SS: Regular Expression" }, - { OPS_PTAG_SS_REVOCABLE, "SS: Revocable" }, - { OPS_PTAG_SS_KEY_EXPIRATION_TIME, "SS: Key Expiration Time" }, - { OPS_PTAG_SS_RESERVED, "SS: Reserved" }, - { OPS_PTAG_SS_PREFERRED_SKA, "SS: Preferred Secret Key Algorithm" }, - { OPS_PTAG_SS_REVOCATION_KEY, "SS: Revocation Key" }, - { OPS_PTAG_SS_ISSUER_KEY_ID, "SS: Issuer Key Id" }, - { OPS_PTAG_SS_NOTATION_DATA, "SS: Notation Data" }, - { OPS_PTAG_SS_PREFERRED_HASH, "SS: Preferred Hash Algorithm" }, - { OPS_PTAG_SS_PREFERRED_COMPRESSION,"SS: Preferred Compression Algorithm" }, - { OPS_PTAG_SS_KEY_SERVER_PREFS, "SS: Key Server Preferences" }, - { OPS_PTAG_SS_PREFERRED_COMPRESSION,"SS: Preferred Key Server" }, - { OPS_PTAG_SS_PRIMARY_USER_ID, "SS: Primary User ID" }, - { OPS_PTAG_SS_POLICY_URI, "SS: Policy URI" }, - { OPS_PTAG_SS_KEY_FLAGS, "SS: Key Flags" }, - { OPS_PTAG_SS_SIGNERS_USER_ID, "SS: Signer's User ID" }, - { OPS_PTAG_SS_REVOCATION_REASON, "SS: Reason for Revocation" }, - { OPS_PTAG_SS_FEATURES, "SS: Features" }, - { OPS_PTAG_SS_SIGNATURE_TARGET, "SS: Signature Target" }, - { OPS_PTAG_SS_EMBEDDED_SIGNATURE, "SS: Embedded Signature" }, - - { OPS_PTAG_CT_LITERAL_DATA_HEADER, "CT: Literal Data Header" }, - { OPS_PTAG_CT_LITERAL_DATA_BODY, "CT: Literal Data Body" }, - { OPS_PTAG_CT_SIGNATURE_HEADER, "CT: Signature Header" }, - { OPS_PTAG_CT_SIGNATURE_FOOTER, "CT: Signature Footer" }, - { OPS_PTAG_CT_ARMOUR_HEADER, "CT: Armour Header" }, - { OPS_PTAG_CT_ARMOUR_TRAILER, "CT: Armour Trailer" }, - { OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER, "CT: Signed Cleartext Header" }, - { OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY, "CT: Signed Cleartext Body" }, - { OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, "CT: Signed Cleartext Trailer" }, - { OPS_PTAG_CT_UNARMOURED_TEXT, "CT: Unarmoured Text" }, - { OPS_PTAG_CT_ENCRYPTED_SECRET_KEY, "CT: Encrypted Secret Key" }, - { OPS_PTAG_CT_SE_DATA_HEADER, "CT: Sym Encrypted Data Header" }, - { OPS_PTAG_CT_SE_DATA_BODY, "CT: Sym Encrypted Data Body" }, - { OPS_PTAG_CT_SE_IP_DATA_HEADER, "CT: Sym Encrypted IP Data Header" }, - { OPS_PTAG_CT_SE_IP_DATA_BODY, "CT: Sym Encrypted IP Data Body" }, - { OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, "CT: Encrypted PK Session Key" }, - { OPS_PARSER_CMD_GET_SK_PASSPHRASE, "CMD: Get Secret Key Passphrase" }, - { OPS_PARSER_CMD_GET_SECRET_KEY, "CMD: Get Secret Key" }, - { OPS_PARSER_ERROR, "OPS_PARSER_ERROR" }, - { OPS_PARSER_ERRCODE, "OPS_PARSER_ERRCODE" }, - - { 0x00, NULL }, /* this is the end-of-array marker */ - }; -typedef ops_map_t packet_tag_map_t; - -static ops_map_t ss_type_map[] = - { - { OPS_PTAG_SS_CREATION_TIME, "Signature Creation Time" }, - { OPS_PTAG_SS_EXPIRATION_TIME, "Signature Expiration Time" }, - { OPS_PTAG_SS_TRUST, "Trust Signature" }, - { OPS_PTAG_SS_REGEXP, "Regular Expression" }, - { OPS_PTAG_SS_REVOCABLE, "Revocable" }, - { OPS_PTAG_SS_KEY_EXPIRATION_TIME, "Key Expiration Time" }, - { OPS_PTAG_SS_PREFERRED_SKA, "Preferred Symmetric Algorithms" }, - { OPS_PTAG_SS_REVOCATION_KEY, "Revocation Key" }, - { OPS_PTAG_SS_ISSUER_KEY_ID, "Issuer key ID" }, - { OPS_PTAG_SS_NOTATION_DATA, "Notation Data" }, - { OPS_PTAG_SS_PREFERRED_HASH, "Preferred Hash Algorithms" }, - { OPS_PTAG_SS_PREFERRED_COMPRESSION,"Preferred Compression Algorithms" }, - { OPS_PTAG_SS_KEY_SERVER_PREFS, "Key Server Preferences" }, - { OPS_PTAG_SS_PREFERRED_KEY_SERVER, "Preferred Key Server" }, - { OPS_PTAG_SS_PRIMARY_USER_ID, "Primary User ID" }, - { OPS_PTAG_SS_POLICY_URI, "Policy URI" }, - { OPS_PTAG_SS_KEY_FLAGS, "Key Flags" }, - { OPS_PTAG_SS_REVOCATION_REASON, "Reason for Revocation" }, - { OPS_PTAG_SS_FEATURES, "Features" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; -typedef ops_map_t ss_type_map_t; - - -static ops_map_t ss_rr_code_map[] = - { - { 0x00, "No reason specified" }, - { 0x01, "Key is superseded" }, - { 0x02, "Key material has been compromised" }, - { 0x03, "Key is retired and no longer used" }, - { 0x20, "User ID information is no longer valid" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; -typedef ops_map_t ss_rr_code_map_t; - -static ops_map_t sig_type_map[] = - { - { OPS_SIG_BINARY, "Signature of a binary document" }, - { OPS_SIG_TEXT, "Signature of a canonical text document" }, - { OPS_SIG_STANDALONE, "Standalone signature" }, - { OPS_CERT_GENERIC, "Generic certification of a User ID and Public Key packet" }, - { OPS_CERT_PERSONA, "Persona certification of a User ID and Public Key packet" }, - { OPS_CERT_CASUAL, "Casual certification of a User ID and Public Key packet" }, - { OPS_CERT_POSITIVE, "Positive certification of a User ID and Public Key packet" }, - { OPS_SIG_SUBKEY, "Subkey Binding Signature" }, - { OPS_SIG_PRIMARY, "Primary Key Binding Signature" }, - { OPS_SIG_DIRECT, "Signature directly on a key" }, - { OPS_SIG_REV_KEY, "Key revocation signature" }, - { OPS_SIG_REV_SUBKEY, "Subkey revocation signature" }, - { OPS_SIG_REV_CERT, "Certification revocation signature" }, - { OPS_SIG_TIMESTAMP, "Timestamp signature" }, - { OPS_SIG_3RD_PARTY, "Third-Party Confirmation signature" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; -typedef ops_map_t sig_type_map_t; - -static ops_map_t public_key_algorithm_map[] = - { - { OPS_PKA_RSA, "RSA (Encrypt or Sign)" }, - { OPS_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only" }, - { OPS_PKA_RSA_SIGN_ONLY, "RSA Sign-Only" }, - { OPS_PKA_ELGAMAL, "Elgamal (Encrypt-Only)" }, - { OPS_PKA_DSA, "DSA" }, - { OPS_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve" }, - { OPS_PKA_RESERVED_ECDSA, "Reserved for ECDSA" }, - { OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign" }, - { OPS_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)" }, - { OPS_PKA_PRIVATE00, "Private/Experimental" }, - { OPS_PKA_PRIVATE01, "Private/Experimental" }, - { OPS_PKA_PRIVATE02, "Private/Experimental" }, - { OPS_PKA_PRIVATE03, "Private/Experimental" }, - { OPS_PKA_PRIVATE04, "Private/Experimental" }, - { OPS_PKA_PRIVATE05, "Private/Experimental" }, - { OPS_PKA_PRIVATE06, "Private/Experimental" }, - { OPS_PKA_PRIVATE07, "Private/Experimental" }, - { OPS_PKA_PRIVATE08, "Private/Experimental" }, - { OPS_PKA_PRIVATE09, "Private/Experimental" }, - { OPS_PKA_PRIVATE10, "Private/Experimental" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; -typedef ops_map_t public_key_algorithm_map_t; - -static ops_map_t symmetric_algorithm_map[] = - { - { OPS_SA_PLAINTEXT, "Plaintext or unencrypted data" }, - { OPS_SA_IDEA, "IDEA" }, - { OPS_SA_TRIPLEDES, "TripleDES" }, - { OPS_SA_CAST5, "CAST5" }, - { OPS_SA_BLOWFISH, "Blowfish" }, - { OPS_SA_AES_128, "AES (128-bit key)" }, - { OPS_SA_AES_192, "AES (192-bit key)" }, - { OPS_SA_AES_256, "AES (256-bit key)" }, - { OPS_SA_TWOFISH, "Twofish(256-bit key)" }, - { OPS_SA_CAMELLIA_128, "Camellia (128-bit key)" }, - { OPS_SA_CAMELLIA_192, "Camellia (192-bit key)" }, - { OPS_SA_CAMELLIA_256, "Camellia (256-bit key)" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; - -static ops_map_t hash_algorithm_map[] = - { - { OPS_HASH_MD5, "MD5" }, - { OPS_HASH_SHA1, "SHA1" }, - { OPS_HASH_RIPEMD, "RIPEMD160" }, - { OPS_HASH_SHA256, "SHA256" }, - { OPS_HASH_SHA384, "SHA384" }, - { OPS_HASH_SHA512, "SHA512" }, - { OPS_HASH_SHA224, "SHA224" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; - -static ops_map_t compression_algorithm_map[] = - { - { OPS_C_NONE, "Uncompressed" }, - { OPS_C_ZIP, "ZIP(RFC1951)" }, - { OPS_C_ZLIB, "ZLIB(RFC1950)" }, - { OPS_C_BZIP2, "Bzip2(BZ2)" }, - { 0x00, NULL }, /* this is the end-of-array marker */ - }; - -static ops_bit_map_t ss_notation_data_map_byte0[] = - { - { 0x80, "Human-readable" }, - { 0x00, NULL }, - }; - -static ops_bit_map_t *ss_notation_data_map[] = - { - ss_notation_data_map_byte0, - }; - -static ops_bit_map_t ss_feature_map_byte0[] = - { - { 0x01, "Modification Detection" }, - { 0x00, NULL }, - }; - -static ops_bit_map_t *ss_feature_map[] = - { - ss_feature_map_byte0, - }; - -static ops_bit_map_t ss_key_flags_map[] = - { - { 0x01, "May be used to certify other keys" }, - { 0x02, "May be used to sign data" }, - { 0x04, "May be used to encrypt communications" }, - { 0x08, "May be used to encrypt storage" }, - { 0x10, "Private component may have been split by a secret-sharing mechanism"}, - { 0x80, "Private component may be in possession of more than one person"}, - { 0x00, NULL }, - }; - -static ops_bit_map_t ss_key_server_prefs_map[] = - { - { 0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server" }, - { 0x00, NULL }, - }; - -#include - -/* - * Private functions - */ - -static void list_init(ops_list_t *list) - { - list->size=0; - list->used=0; - list->strings=NULL; - } - -static void list_free_strings(ops_list_t *list) - { - unsigned i; - - for(i=0; i < list->used ; i++) - { - free(list->strings[i]); - list->strings[i]=NULL; - } - } - -static void list_free(ops_list_t *list) - { - if (list->strings) - free(list->strings); - list_init(list); - } - -static unsigned int list_resize(ops_list_t *list) - { - /* We only resize in one direction - upwards. - Algorithm used : double the current size then add 1 - */ - - int newsize=0; - - newsize=list->size*2 + 1; - list->strings=realloc(list->strings,newsize*sizeof(char *)); - if (list->strings) - { - list->size=newsize; - return 1; - } - else - { - /* xxx - realloc failed. error message? - rachel */ - return 0; - } - } - -static unsigned int add_str(ops_list_t *list,char *str) - { - if (list->size==list->used) - if (!list_resize(list)) - return 0; - - list->strings[list->used]=str; - list->used++; - return 1; - } - -static char *str_from_bitfield_or_null(unsigned char octet, ops_bit_map_t *map) - { - ops_bit_map_t *row; - - for ( row=map; row->string != NULL; row++ ) - if (row->mask == octet) - return row->string; - - return NULL; - } - -static char *str_from_bitfield(unsigned char octet, ops_bit_map_t *map) - { - char *str; - str=str_from_bitfield_or_null(octet,map); - if (str) - return str; - else - return "Unknown"; - } - -/*! generic function to initialise ops_text_t structure */ -void ops_text_init(ops_text_t *text) - { - list_init(&text->known); - list_init(&text->unknown); - } - -/** - * \ingroup Core_Print - * - * ops_text_free() frees the memory used by an ops_text_t structure - * - * \param text Pointer to a previously allocated structure. This structure and its contents will be freed. - */ -void ops_text_free(ops_text_t *text) - { - /* Strings in "known" array will be constants, so don't free them */ - list_free(&text->known); - - /* Strings in "unknown" array will be dynamically allocated, so do free them */ - list_free_strings(&text->unknown); - list_free(&text->unknown); - - /* finally, free the text structure itself */ - free(text); - } - -// XXX: should this (and many others) be ops_boolean_t? -/*! generic function which adds text derived from single octet map to text */ -static unsigned int add_str_from_octet_map(ops_text_t *text,char *str, - unsigned char octet) - { - if (str && !add_str(&text->known,str)) - { - /* value recognised, but there was a problem adding it to the list */ - /* XXX - should print out error msg here, Ben? - rachel */ - return 0; - } - else if (!str) - { - /* value not recognised and there was a problem adding it to the unknown list */ - unsigned len=2+2+1; /* 2 for "0x", 2 for single octet in hex format, 1 for NULL */ - str=malloc(len); - snprintf(str,len,"0x%x",octet); - if (!add_str(&text->unknown,str)) - return 0; - } - return 1; - } - -/*! generic function which adds text derived from single bit map to text */ -static unsigned int add_str_from_bit_map(ops_text_t *text, char *str, unsigned char bit) - { - char *fmt_unknown="Unknown bit(0x%x)"; - - if (str && !add_str(&text->known,str)) - { - /* value recognised, but there was a problem adding it to the list */ - /* XXX - should print out error msg here, Ben? - rachel */ - return 0; - } - else if (!str) - { - /* value not recognised and there was a problem adding it to the unknown list */ - /* 2 chars of the string are the format definition, - this will be replaced in the output by 2 chars of hex, - so the length will be correct */ - unsigned len=strlen(fmt_unknown)+1; - str=malloc(len); - - snprintf(str,len,fmt_unknown,bit); - if (!add_str(&text->unknown,str)) - return 0; - } - return 1; - } - -/** - * Produce a structure containing human-readable textstrings - * representing the recognised and unrecognised contents - * of this byte array. text_fn() will be called on each octet in turn. - * Each octet will generate one string representing the whole byte. - * - */ - -static ops_text_t *text_from_bytemapped_octets(ops_data_t *data, - const char *(*text_fn)(unsigned char octet)) - { - - ops_text_t *text=NULL; - const char *str; - unsigned i; - - /*! allocate and initialise ops_text_t structure to store derived strings */ - text=malloc(sizeof(ops_text_t)); - if (!text) - return NULL; - - ops_text_init(text); - - /*! for each octet in field ... */ - for(i=0 ; i < data->len ; i++) - { - /*! derive string from octet */ - str=(*text_fn)(data->contents[i]); - - /*! and add to text */ - if (!add_str_from_octet_map(text,strdup(str),data->contents[i])) - { - ops_text_free(text); - return NULL; - } - - } - /*! All values have been added to either the known or the unknown list */ - /*! Return text */ - return text; - } - -/** - * Produce a structure containing human-readable textstrings - * representing the recognised and unrecognised contents - * of this byte array, derived from each bit of each octet. - * - */ -static ops_text_t *showall_octets_bits(ops_data_t *data,ops_bit_map_t **map, - size_t nmap) - { - ops_text_t *text=NULL; - char *str; - unsigned i; - int j=0; - unsigned char mask, bit; - - /*! allocate and initialise ops_text_t structure to store derived strings */ - text=malloc(sizeof(ops_text_t)); - if (!text) - return NULL; - - ops_text_init(text); - - /*! for each octet in field ... */ - for(i=0 ; i < data->len ; i++) - { - /*! for each bit in octet ... */ - for (j=0, mask=0x80; j<8; j++, mask = mask>>1 ) - { - bit = data->contents[i]&mask; - if (bit) - { - if(i >= nmap) - str="Unknown"; - else - str=str_from_bitfield ( bit, map[i] ); - if (!add_str_from_bit_map( text, str, bit)) - { - ops_text_free(text); - return NULL; - } - } - } - } - return text; - } - -/* - * Public Functions - */ - -/** - * \ingroup Core_Print - * returns description of the Packet Tag - * \param packet_tag - * \return string or "Unknown" -*/ -const char *ops_show_packet_tag(ops_packet_tag_t packet_tag) - { - char *rtn=NULL; - rtn=show_packet_tag(packet_tag,packet_tag_map); - - if (!rtn) - rtn="Unknown Tag"; - - return rtn; - } - -/** - * \ingroup Core_Print - * - * returns description of the Signature Sub-Packet type - * \param ss_type Signature Sub-Packet type - * \return string or "Unknown" - */ -const char *ops_show_ss_type(ops_ss_type_t ss_type) - { - return show_ss_type(ss_type,ss_type_map); - } - -/** - * \ingroup Core_Print - * - * returns description of the Revocation Reason code - * \param ss_rr_code Revocation Reason code - * \return string or "Unknown" - */ -const char *ops_show_ss_rr_code(ops_ss_rr_code_t ss_rr_code) - { - return show_ss_rr_code(ss_rr_code,ss_rr_code_map); - } - -/** - * \ingroup Core_Print - * - * returns description of the given Signature type - * \param sig_type Signature type - * \return string or "Unknown" - */ -const char *ops_show_sig_type(ops_sig_type_t sig_type) - { - return show_sig_type(sig_type, sig_type_map); - } - -/** - * \ingroup Core_Print - * - * returns description of the given Public Key Algorithm - * \param pka Public Key Algorithm type - * \return string or "Unknown" - */ -const char *ops_show_pka(ops_public_key_algorithm_t pka) - { - return show_pka(pka, public_key_algorithm_map); - } - -/** - * \ingroup Core_Print - * returns description of the Preferred Compression - * \param octet Preferred Compression - * \return string or "Unknown" -*/ -const char *ops_show_ss_preferred_compression(unsigned char octet) - { - return ops_str_from_map(octet,compression_algorithm_map); - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given Preferred Compression Algorithms - * \param ss_preferred_compression Array of Preferred Compression Algorithms - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -ops_text_t *ops_showall_ss_preferred_compression(ops_ss_preferred_compression_t ss_preferred_compression) - { - return text_from_bytemapped_octets(&ss_preferred_compression.data, - &ops_show_ss_preferred_compression); - } - - -/** - * \ingroup Core_Print - * - * returns description of the Hash Algorithm type - * \param hash Hash Algorithm type - * \return string or "Unknown" - */ -const char *ops_show_hash_algorithm(unsigned char hash) - { - return show_hash_algorithm(hash); - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given Preferred Hash Algorithms - * \param ss_preferred_hash Array of Preferred Hash Algorithms - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -ops_text_t *ops_showall_ss_preferred_hash(ops_ss_preferred_hash_t ss_preferred_hash) - { - return text_from_bytemapped_octets(&ss_preferred_hash.data, - &ops_show_hash_algorithm); - } - -const char *ops_show_symmetric_algorithm(unsigned char hash) - { - return show_symmetric_algorithm(hash); - } - -/** - * \ingroup Core_Print - * returns description of the given Preferred Symmetric Key Algorithm - * \param octet - * \return string or "Unknown" -*/ -const char *ops_show_ss_preferred_ska(unsigned char octet) - { - return ops_str_from_map(octet,symmetric_algorithm_map); - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given Preferred Symmetric Key Algorithms - * \param ss_preferred_ska Array of Preferred Symmetric Key Algorithms - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -ops_text_t *ops_showall_ss_preferred_ska(ops_ss_preferred_ska_t ss_preferred_ska) - { - return text_from_bytemapped_octets(&ss_preferred_ska.data, - &ops_show_ss_preferred_ska); - } - -/** - * \ingroup Core_Print - * returns description of one SS Feature - * \param octet - * \return string or "Unknown" -*/ -static char *ops_show_ss_feature(unsigned char octet,unsigned offset) - { - if(offset >= OPS_ARRAY_SIZE(ss_feature_map)) - return "Unknown"; - return str_from_bitfield(octet,ss_feature_map[offset]); - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given SS Features - * \param ss_features Signature Sub-Packet Features - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -/* XXX: shouldn't this use show_all_octets_bits? */ -ops_text_t *ops_showall_ss_features(ops_ss_features_t ss_features) - { - ops_text_t *text=NULL; - char *str; - unsigned i; - int j=0; - unsigned char mask, bit; - - text=malloc(sizeof(ops_text_t)); - if (!text) - return NULL; - - ops_text_init(text); - - for(i=0 ; i < ss_features.data.len ; i++) - { - for (j=0, mask=0x80; j<8; j++, mask = mask>>1 ) - { - bit = ss_features.data.contents[i]&mask; - if (bit) - { - str=ops_show_ss_feature ( bit, i ); - if (!add_str_from_bit_map( text, str, bit)) - { - ops_text_free(text); - return NULL; - } - } - } - } - return text; - } - -/** - * \ingroup Core_Print - * returns description of SS Key Flag - * \param octet - * \param map - * \return -*/ -const char *ops_show_ss_key_flag(unsigned char octet, ops_bit_map_t *map) - { - return str_from_bitfield(octet,map); - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given Preferred Key Flags - * \param ss_key_flags Array of Key Flags - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -ops_text_t *ops_showall_ss_key_flags(ops_ss_key_flags_t ss_key_flags) - { - ops_text_t *text=NULL; - const char *str; - int i=0; - unsigned char mask, bit; - - text=malloc(sizeof(ops_text_t)); - if (!text) - return NULL; - - ops_text_init(text); - - /* xxx - TBD: extend to handle multiple octets of bits - rachel */ - - for (i=0,mask=0x80 ; i < 8 ; i++,mask=mask >> 1) - { - bit=ss_key_flags.data.contents[0]&mask; - if(bit) - { - str=ops_show_ss_key_flag(bit,&ss_key_flags_map[0]); - if(!add_str_from_bit_map(text,strdup(str),bit)) - { - ops_text_free(text); - return NULL; - } - } - } -/* xxx - must add error text if more than one octet. Only one currently specified -- rachel */ - return text; - } - -/** - * \ingroup Core_Print - * - * returns description of one given Key Server Preference - * - * \param prefs Byte containing bitfield of preferences - * \param map - * \return string or "Unknown" - */ -const char *ops_show_ss_key_server_prefs(unsigned char prefs, - ops_bit_map_t *map) - { - return str_from_bitfield(prefs,map); - } - -/** - * \ingroup Core_Print - * returns set of descriptions of given Key Server Preferences - * \param ss_key_server_prefs - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - * -*/ -ops_text_t *ops_showall_ss_key_server_prefs(ops_ss_key_server_prefs_t ss_key_server_prefs) - { - ops_text_t *text=NULL; - const char *str; - int i=0; - unsigned char mask, bit; - - text=malloc(sizeof(ops_text_t)); - if (!text) - return NULL; - - ops_text_init(text); - - /* xxx - TBD: extend to handle multiple octets of bits - rachel */ - - for (i=0,mask=0x80 ; i < 8 ; i++,mask=mask >> 1) - { - bit=ss_key_server_prefs.data.contents[0]&mask; - if (bit) - { - str=ops_show_ss_key_server_prefs(bit, - &ss_key_server_prefs_map[0]); - if(!add_str_from_bit_map( text, strdup(str), bit)) - { - ops_text_free(text); - return NULL; - } - } - } -/* xxx - must add error text if more than one octet. Only one currently specified -- rachel */ - return text; - } - -/** - * \ingroup Core_Print - * - * returns set of descriptions of the given SS Notation Data Flags - * \param ss_notation_data Signature Sub-Packet Notation Data - * \return NULL if cannot allocate memory or other error - * \return pointer to structure, if no error - */ -ops_text_t *ops_showall_ss_notation_data_flags(ops_ss_notation_data_t ss_notation_data) - { - return showall_octets_bits(&ss_notation_data.flags,ss_notation_data_map, - OPS_ARRAY_SIZE(ss_notation_data_map)); - } diff --git a/openpgpsdk/src/openpgpsdk/packet-show.h b/openpgpsdk/src/openpgpsdk/packet-show.h deleted file mode 100644 index f8dc4050f..000000000 --- a/openpgpsdk/src/openpgpsdk/packet-show.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_PACKET_TO_TEXT_H -#define OPS_PACKET_TO_TEXT_H - -#ifndef OPS_PACKET_H -#include "packet.h" -#endif - -/** ops_list_t - */ -typedef struct - { - unsigned int size;/* num of array slots allocated */ - unsigned int used; /* num of array slots currently used */ - char **strings; - } ops_list_t; - -/** ops_text_t - */ -typedef struct - { - ops_list_t known; - ops_list_t unknown; - } ops_text_t; - -/** ops_bit_map_t - */ -typedef struct - { - unsigned char mask; - char *string; - } ops_bit_map_t; - -void ops_text_init(ops_text_t *text); -void ops_text_free(ops_text_t *text); - -const char *ops_show_packet_tag(ops_packet_tag_t packet_tag); -const char *ops_show_ss_type(ops_ss_type_t ss_type); - -const char *ops_show_sig_type(ops_sig_type_t sig_type); -const char *ops_show_pka(ops_public_key_algorithm_t pka); - -ops_text_t *ops_showall_ss_preferred_compression(ops_ss_preferred_compression_t ss_preferred_compression); -const char *ops_show_ss_preferred_compression(unsigned char octet); - -ops_text_t *ops_showall_ss_preferred_hash(ops_ss_preferred_hash_t ss_preferred_hash); -const char *ops_show_hash_algorithm(unsigned char octet); -const char *ops_show_symmetric_algorithm(unsigned char hash); - -ops_text_t *ops_showall_ss_preferred_ska(ops_ss_preferred_ska_t ss_preferred_ska); -const char *ops_show_ss_preferred_ska(unsigned char octet); - -const char *ops_show_ss_rr_code(ops_ss_rr_code_t ss_rr_code); - -ops_text_t *ops_showall_ss_features(ops_ss_features_t ss_features); - -ops_text_t *ops_showall_ss_key_flags(ops_ss_key_flags_t ss_key_flags); -const char *ops_show_ss_key_flag(unsigned char octet, ops_bit_map_t *map); - -ops_text_t *ops_showall_ss_key_server_prefs(ops_ss_key_server_prefs_t ss_key_server_prefs); -const char *ops_show_ss_key_server_prefs(unsigned char octet, - ops_bit_map_t *map); - -ops_text_t *ops_showall_ss_notation_data_flags(ops_ss_notation_data_t ss_notation_data); - -char *ops_str_from_map(int code, ops_map_t *map); - -/* vim:set textwidth=120: */ -/* vim:set ts=8: */ - -#endif /* OPS_PACKET_TO_TEXT_H */ diff --git a/openpgpsdk/src/openpgpsdk/packet.h b/openpgpsdk/src/openpgpsdk/packet.h deleted file mode 100644 index 49e59a556..000000000 --- a/openpgpsdk/src/openpgpsdk/packet.h +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * packet related headers. - */ - -#ifndef OPS_PACKET_H -#define OPS_PACKET_H - -#include "configure.h" - -#include -#include -#include -#include "types.h" -#include "errors.h" - -/** General-use structure for variable-length data - */ - -typedef struct - { - size_t len; - unsigned char *contents; - } ops_data_t; - -/************************************/ -/* Packet Tags - RFC4880, 4.2 */ -/************************************/ - -/** Packet Tag - Bit 7 Mask (this bit is always set). - * The first byte of a packet is the "Packet Tag". It always - * has bit 7 set. This is the mask for it. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_ALWAYS_SET 0x80 - -/** Packet Tag - New Format Flag. - * Bit 6 of the Packet Tag is the packet format indicator. - * If it is set, the new format is used, if cleared the - * old format is used. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_NEW_FORMAT 0x40 - - -/** Old Packet Format: Mask for content tag. - * In the old packet format bits 5 to 2 (including) - * are the content tag. This is the mask to apply - * to the packet tag. Note that you need to - * shift by #OPS_PTAG_OF_CONTENT_TAG_SHIFT bits. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_OF_CONTENT_TAG_MASK 0x3c -/** Old Packet Format: Offset for the content tag. - * As described at #OPS_PTAG_OF_CONTENT_TAG_MASK the - * content tag needs to be shifted after being masked - * out from the Packet Tag. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_OF_CONTENT_TAG_SHIFT 2 -/** Old Packet Format: Mask for length type. - * Bits 1 and 0 of the packet tag are the length type - * in the old packet format. - * - * See #ops_ptag_of_lt_t for the meaning of the values. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_OF_LENGTH_TYPE_MASK 0x03 - - -/** Old Packet Format Lengths. - * Defines the meanings of the 2 bits for length type in the - * old packet format. - * - * \see RFC4880 4.2.1 - */ -typedef enum - { - OPS_PTAG_OF_LT_ONE_BYTE =0x00, /*!< Packet has a 1 byte length - header is 2 bytes long. */ - OPS_PTAG_OF_LT_TWO_BYTE =0x01, /*!< Packet has a 2 byte length - header is 3 bytes long. */ - OPS_PTAG_OF_LT_FOUR_BYTE =0x02, /*!< Packet has a 4 byte length - header is 5 bytes long. */ - OPS_PTAG_OF_LT_INDETERMINATE =0x03 /*!< Packet has a indeterminate length. */ - } ops_ptag_of_lt_t; - - -/** New Packet Format: Mask for content tag. - * In the new packet format the 6 rightmost bits - * are the content tag. This is the mask to apply - * to the packet tag. Note that you need to - * shift by #OPS_PTAG_NF_CONTENT_TAG_SHIFT bits. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_NF_CONTENT_TAG_MASK 0x3f -/** New Packet Format: Offset for the content tag. - * As described at #OPS_PTAG_NF_CONTENT_TAG_MASK the - * content tag needs to be shifted after being masked - * out from the Packet Tag. - * - * \see RFC4880 4.2 - */ -#define OPS_PTAG_NF_CONTENT_TAG_SHIFT 0 - - -/** Structure to hold one parse error string. */ -typedef struct - { - const char *error; /*!< error message. */ - } ops_parser_error_t; - -/** Structure to hold one error code */ -typedef struct - { - ops_errcode_t errcode; - } ops_parser_errcode_t; - -/** Structure to hold one packet tag. - * \see RFC4880 4.2 - */ -typedef struct - { - unsigned new_format; /*!< Whether this packet tag is new (true) or old format (false) */ - unsigned content_tag; /*!< content_tag value - See #ops_content_tag_t for meanings */ - ops_ptag_of_lt_t length_type; /*!< Length type (#ops_ptag_of_lt_t) - only if this packet tag is old format. Set to 0 if new format. */ - unsigned length; /*!< The length of the packet. This value is set when we read and compute the - length information, not at the same moment we create the packet tag structure. - Only defined if #length_read is set. */ /* XXX: Ben, is this correct? */ - unsigned position; /*!< The position (within the current reader) of the packet */ - } ops_ptag_t; - -/** Public Key Algorithm Numbers. - * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP. - * - * This lists algorithm numbers for public key algorithms. - * - * \see RFC4880 9.1 - */ -typedef enum - { - OPS_PKA_RSA =1, /*!< RSA (Encrypt or Sign) */ - OPS_PKA_RSA_ENCRYPT_ONLY =2, /*!< RSA Encrypt-Only (deprecated - \see RFC4880 13.5) */ - OPS_PKA_RSA_SIGN_ONLY =3, /*!< RSA Sign-Only (deprecated - \see RFC4880 13.5) */ - OPS_PKA_ELGAMAL =16, /*!< Elgamal (Encrypt-Only) */ - OPS_PKA_DSA =17, /*!< DSA (Digital Signature Algorithm) */ - OPS_PKA_RESERVED_ELLIPTIC_CURVE =18, /*!< Reserved for Elliptic Curve */ - OPS_PKA_RESERVED_ECDSA =19, /*!< Reserved for ECDSA */ - OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN =20, /*!< Deprecated. */ - OPS_PKA_RESERVED_DH =21, /*!< Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) */ - OPS_PKA_PRIVATE00 =100, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE01 =101, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE02 =102, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE03 =103, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE04 =104, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE05 =105, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE06 =106, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE07 =107, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE08 =108, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE09 =109, /*!< Private/Experimental Algorithm */ - OPS_PKA_PRIVATE10 =110, /*!< Private/Experimental Algorithm */ - } ops_public_key_algorithm_t; - -/** Structure to hold one DSA public key parameters. - * - * \see RFC4880 5.5.2 - */ -typedef struct - { - BIGNUM *p; /*!< DSA prime p */ - BIGNUM *q; /*!< DSA group order q */ - BIGNUM *g; /*!< DSA group generator g */ - BIGNUM *y; /*!< DSA public key value y (= g^x mod p with x being the secret) */ - } ops_dsa_public_key_t; - -/** Structure to hold on RSA public key. - * - * \see RFC4880 5.5.2 - */ -typedef struct - { - BIGNUM *n; /*!< RSA public modulus n */ - BIGNUM *e; /*!< RSA public encryptiong exponent e */ - } ops_rsa_public_key_t; - -/** Structure to hold on ElGamal public key parameters. - * - * \see RFC4880 5.5.2 - */ -typedef struct - { - BIGNUM *p; /*!< ElGamal prime p */ - BIGNUM *g; /*!< ElGamal group generator g */ - BIGNUM *y; /*!< ElGamal public key value y (= g^x mod p with x being the secret) */ - } ops_elgamal_public_key_t; - -/** Union to hold public key parameters of any algorithm */ -typedef union - { - ops_dsa_public_key_t dsa; /*!< A DSA public key */ - ops_rsa_public_key_t rsa; /*!< An RSA public key */ - ops_elgamal_public_key_t elgamal; /*!< An ElGamal public key */ - } ops_public_key_union_t; - -/** Version. - * OpenPGP has two different protocol versions: version 3 and version 4. - * - * \see RFC4880 5.2 - */ -typedef enum - { - OPS_V2=2, /*contents to be a null-terminated list */ - } ops_ss_preferred_ska_t; - -/** Signature Subpacket : Preferrred Hash Algorithm */ -typedef struct - { - ops_data_t data; - } ops_ss_preferred_hash_t; - -/** Signature Subpacket : Preferred Compression */ -typedef struct - { - ops_data_t data; - } ops_ss_preferred_compression_t; - -/** Signature Subpacket : Key Flags */ -typedef struct - { - ops_data_t data; - } ops_ss_key_flags_t; - -/** Signature Subpacket : Key Server Preferences */ -typedef struct - { - ops_data_t data; - } ops_ss_key_server_prefs_t; - -/** Signature Subpacket : Features */ -typedef struct - { - ops_data_t data; - } ops_ss_features_t; - -/** Signature Subpacket : Signature Target */ -typedef struct - { - ops_public_key_algorithm_t pka_alg; - ops_hash_algorithm_t hash_alg; - ops_data_t hash; - } ops_ss_signature_target_t; - -/** Signature Subpacket : Embedded Signature */ -typedef struct - { - ops_data_t sig; - } ops_ss_embedded_signature_t; - -/** ops_packet_t */ - -typedef struct - { - size_t length; - unsigned char *raw; - } ops_packet_t; - -/** Types of Compression */ -typedef enum - { - OPS_C_NONE=0, - OPS_C_ZIP=1, - OPS_C_ZLIB=2, - OPS_C_BZIP2=3, - } ops_compression_type_t; - -/* unlike most structures, this will feed its data as a stream - * to the application instead of directly including it */ -/** ops_compressed_t */ -typedef struct - { - ops_compression_type_t type; - } ops_compressed_t; - -/** ops_one_pass_signature_t */ -typedef struct - { - unsigned char version; - ops_sig_type_t sig_type; - ops_hash_algorithm_t hash_algorithm; - ops_public_key_algorithm_t key_algorithm; - unsigned char keyid[OPS_KEY_ID_SIZE]; - ops_boolean_t nested; - } ops_one_pass_signature_t; - -/** Signature Subpacket : Primary User ID */ -typedef struct - { - ops_boolean_t primary_user_id; - } ops_ss_primary_user_id_t; - -/** Signature Subpacket : Regexp */ -typedef struct - { - char *text; - } ops_ss_regexp_t; - -/** Signature Subpacket : Policy URL */ -typedef struct - { - char *text; - } ops_ss_policy_url_t; - -/** Signature Subpacket : Preferred Key Server */ -typedef struct - { - char *text; - } ops_ss_preferred_key_server_t; - -/** Signature Subpacket : Revocation Key */ -typedef struct - { - unsigned char clss; /* class - name changed for C++ */ - unsigned char algid; - unsigned char fingerprint[20]; - } ops_ss_revocation_key_t; - -/** Signature Subpacket : Revocation Reason */ -typedef struct - { - unsigned char code; - char *text; - } ops_ss_revocation_reason_t; - -/** literal_data_type_t */ -typedef enum - { - OPS_LDT_BINARY='b', - OPS_LDT_TEXT='t', - OPS_LDT_UTF8='u', - OPS_LDT_LOCAL='l', - OPS_LDT_LOCAL2='1' - } ops_literal_data_type_t; - -/** ops_literal_data_header_t */ -typedef struct - { - ops_literal_data_type_t format; - char filename[256]; - time_t modification_time; - } ops_literal_data_header_t; - -/** ops_literal_data_body_t */ -typedef struct - { - unsigned length; - unsigned char *data;//[8192]; - } ops_literal_data_body_t; - -/** ops_mdc_t */ -typedef struct - { - unsigned char data[20]; // size of SHA1 hash - } ops_mdc_t; - -/** ops_armoured_header_value_t */ -typedef struct - { - char *key; - char *value; - } ops_armoured_header_value_t; - -/** ops_headers_t */ -typedef struct - { - ops_armoured_header_value_t *headers; - unsigned nheaders; - } ops_headers_t; - -/** ops_armour_header_t */ -typedef struct - { - const char *type; - ops_headers_t headers; - } ops_armour_header_t; - -/** ops_armour_trailer_t */ -typedef struct - { - const char *type; - } ops_armour_trailer_t; - -/** ops_signed_cleartext_header_t */ -typedef struct - { - ops_headers_t headers; - } ops_signed_cleartext_header_t; - -/** ops_signed_cleartext_body_t */ -typedef struct - { - unsigned length; - unsigned char *data; // \todo fix hard-coded value? - } ops_signed_cleartext_body_t; - -/** ops_signed_cleartext_trailer_t */ -typedef struct - { - struct _ops_hash_t *hash; /*!< This will not have been finalised, but will have seen all the cleartext data in canonical form */ - } ops_signed_cleartext_trailer_t; - -/** ops_unarmoured_text_t */ -typedef struct - { - unsigned length; - unsigned char *data; - } ops_unarmoured_text_t; - -typedef enum - { - SE_IP_DATA_VERSION=1 - } ops_se_ip_data_version_t; - -typedef enum - { - OPS_PKSK_V3=3 - } ops_pk_session_key_version_t; - -/** ops_pk_session_key_parameters_rsa_t */ -typedef struct - { - BIGNUM *encrypted_m; - BIGNUM *m; - } ops_pk_session_key_parameters_rsa_t; - -/** ops_pk_session_key_parameters_elgamal_t */ -typedef struct - { - BIGNUM *g_to_k; - BIGNUM *encrypted_m; - } ops_pk_session_key_parameters_elgamal_t; - -/** ops_pk_session_key_parameters_t */ -typedef union - { - ops_pk_session_key_parameters_rsa_t rsa; - ops_pk_session_key_parameters_elgamal_t elgamal; - } ops_pk_session_key_parameters_t; - -/** ops_pk_session_key_t */ -typedef struct - { - ops_pk_session_key_version_t version; - unsigned char key_id[OPS_KEY_ID_SIZE]; - ops_public_key_algorithm_t algorithm; - ops_pk_session_key_parameters_t parameters; - ops_symmetric_algorithm_t symmetric_algorithm; - unsigned char key[OPS_MAX_KEY_SIZE]; - unsigned short checksum; - } ops_pk_session_key_t; - -/** ops_secret_key_passphrase_t */ -typedef struct - { - const ops_secret_key_t *secret_key; - char **passphrase; /* point somewhere that gets filled in to work around constness of content */ - } ops_secret_key_passphrase_t; - -typedef enum - { - OPS_SE_IP_V1=1 - } ops_se_ip_version_t; - -/** ops_se_ip_data_header_t */ -typedef struct - { - ops_se_ip_version_t version; - } ops_se_ip_data_header_t; - -/** ops_se_ip_data_body_t */ -typedef struct - { - unsigned length; - unsigned char* data; // \todo remember to free this - } ops_se_ip_data_body_t; - -/** ops_se_data_body_t */ -typedef struct - { - unsigned length; - unsigned char data[8192]; // \todo parameterise this! - } ops_se_data_body_t; - -/** ops_get_secret_key_t */ -typedef struct - { - const ops_secret_key_t **secret_key; - const ops_pk_session_key_t *pk_session_key; - } ops_get_secret_key_t; - -/** ops_parser_union_content_t */ -typedef union - { - ops_parser_error_t error; - ops_parser_errcode_t errcode; - ops_ptag_t ptag; - ops_public_key_t public_key; - ops_trust_t trust; - ops_user_id_t user_id; - ops_user_attribute_t user_attribute; - ops_signature_t signature; - ops_ss_raw_t ss_raw; - ops_ss_trust_t ss_trust; - ops_ss_revocable_t ss_revocable; - ops_ss_time_t ss_time; - ops_ss_key_id_t ss_issuer_key_id; - ops_ss_notation_data_t ss_notation_data; - ops_packet_t packet; - ops_compressed_t compressed; - ops_one_pass_signature_t one_pass_signature; - ops_ss_preferred_ska_t ss_preferred_ska; - ops_ss_preferred_hash_t ss_preferred_hash; - ops_ss_preferred_compression_t ss_preferred_compression; - ops_ss_key_flags_t ss_key_flags; - ops_ss_key_server_prefs_t ss_key_server_prefs; - ops_ss_primary_user_id_t ss_primary_user_id; - ops_ss_regexp_t ss_regexp; - ops_ss_policy_url_t ss_policy_url; - ops_ss_preferred_key_server_t ss_preferred_key_server; - ops_ss_revocation_key_t ss_revocation_key; - ops_ss_userdefined_t ss_userdefined; - ops_ss_unknown_t ss_unknown; - ops_literal_data_header_t literal_data_header; - ops_literal_data_body_t literal_data_body; - ops_mdc_t mdc; - ops_ss_features_t ss_features; - ops_ss_signature_target_t ss_signature_target; - ops_ss_embedded_signature_t ss_embedded_signature; - ops_ss_revocation_reason_t ss_revocation_reason; - ops_secret_key_t secret_key; - ops_user_id_t ss_signers_user_id; - ops_armour_header_t armour_header; - ops_armour_trailer_t armour_trailer; - ops_signed_cleartext_header_t signed_cleartext_header; - ops_signed_cleartext_body_t signed_cleartext_body; - ops_signed_cleartext_trailer_t signed_cleartext_trailer; - ops_unarmoured_text_t unarmoured_text; - ops_pk_session_key_t pk_session_key; - ops_secret_key_passphrase_t secret_key_passphrase; - ops_se_ip_data_header_t se_ip_data_header; - ops_se_ip_data_body_t se_ip_data_body; - ops_se_data_body_t se_data_body; - ops_get_secret_key_t get_secret_key; - } ops_parser_content_union_t; - -/** ops_parser_content_t */ -struct ops_parser_content_t - { - ops_content_tag_t tag; - unsigned char critical; /* for signature subpackets */ - ops_parser_content_union_t content; - }; - -/** ops_fingerprint_t */ -typedef struct - { - unsigned char fingerprint[20]; - unsigned length; - } ops_fingerprint_t; - -void ops_init(void); -void ops_finish(void); -void ops_keyid(unsigned char keyid[OPS_KEY_ID_SIZE], - const ops_public_key_t *key); -void ops_fingerprint(ops_fingerprint_t *fp,const ops_public_key_t *key); -void ops_public_key_free(ops_public_key_t *key); -void ops_public_key_copy(ops_public_key_t *dst,const ops_public_key_t *src); -void ops_user_id_free(ops_user_id_t *id); -void ops_user_attribute_free(ops_user_attribute_t *att); -void ops_signature_free(ops_signature_t *sig); -void ops_trust_free(ops_trust_t *trust); -void ops_ss_preferred_ska_free(ops_ss_preferred_ska_t *ss_preferred_ska); -void ops_ss_preferred_hash_free(ops_ss_preferred_hash_t *ss_preferred_hash); -void ops_ss_preferred_compression_free(ops_ss_preferred_compression_t *ss_preferred_compression); -void ops_ss_key_flags_free(ops_ss_key_flags_t *ss_key_flags); -void ops_ss_key_server_prefs_free(ops_ss_key_server_prefs_t *ss_key_server_prefs); -void ops_ss_features_free(ops_ss_features_t *ss_features); -void ops_ss_notation_data_free(ops_ss_notation_data_t *ss_notation_data); -void ops_ss_policy_url_free(ops_ss_policy_url_t *ss_policy_url); -void ops_ss_preferred_key_server_free(ops_ss_preferred_key_server_t *ss_preferred_key_server); -void ops_ss_regexp_free(ops_ss_regexp_t *ss_regexp); -void ops_ss_userdefined_free(ops_ss_userdefined_t *ss_userdefined); -void ops_ss_reserved_free(ops_ss_unknown_t *ss_unknown); -void ops_ss_revocation_reason_free(ops_ss_revocation_reason_t *ss_revocation_reason); -void ops_ss_signature_target_free(ops_ss_signature_target_t *ss_signature_target); -void ops_ss_embedded_signature_free(ops_ss_embedded_signature_t *ss_embedded_signature); - -void ops_packet_free(ops_packet_t *packet); -void ops_parser_content_free(ops_parser_content_t *c); -void ops_secret_key_free(ops_secret_key_t *key); -void ops_secret_key_copy(ops_secret_key_t *dst,const ops_secret_key_t *src); -void ops_pk_session_key_free(ops_pk_session_key_t *sk); - -/* vim:set textwidth=120: */ -/* vim:set ts=8: */ - -#endif diff --git a/openpgpsdk/src/openpgpsdk/parse_local.h b/openpgpsdk/src/openpgpsdk/parse_local.h deleted file mode 100644 index 64fd013b6..000000000 --- a/openpgpsdk/src/openpgpsdk/parse_local.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file */ - -#include -#include - -/** ops_reader_info */ -struct ops_reader_info - { - ops_reader_t *reader; /*!< the reader function to use to get the - data to be parsed */ - ops_reader_destroyer_t *destroyer; - void *arg; /*!< the args to pass to the reader function */ - - ops_boolean_t accumulate:1; /*!< set to accumulate packet data */ - unsigned char *accumulated; /*!< the accumulated data */ - unsigned asize; /*!< size of the buffer */ - unsigned alength; /*!< used buffer */ - /* XXX: what do we do about offsets into compressed packets? */ - unsigned position; /*!< the offset from the beginning (with this reader) */ - - ops_reader_info_t *next; - ops_parse_info_t *pinfo; /*!< A pointer back to the parent parse_info structure */ - }; - - -/** ops_crypt_info - Encrypt/decrypt settings -*/ -struct ops_crypt_info - { - char *passphrase; /* - -#include - -void ops_random(void *dest,size_t length) - { - RAND_bytes(dest,length); - } diff --git a/openpgpsdk/src/openpgpsdk/random.h b/openpgpsdk/src/openpgpsdk/random.h deleted file mode 100644 index 833094353..000000000 --- a/openpgpsdk/src/openpgpsdk/random.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifdef WIN32 -#include -#else -#include -#endif - -void ops_random(void *dest,size_t length); diff --git a/openpgpsdk/src/openpgpsdk/reader.c b/openpgpsdk/src/openpgpsdk/reader.c deleted file mode 100644 index 24fc8a041..000000000 --- a/openpgpsdk/src/openpgpsdk/reader.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#ifndef WIN32 -#include -#else -#include -#endif -#include -#include -#include - -#include -#include - -#include "parse_local.h" - - -/** - * \ingroup Internal_Readers_Generic - * \brief Starts reader stack - * \param pinfo Parse settings - * \param reader Reader to use - * \param destroyer Destroyer to use - * \param arg Reader-specific arg - */ -void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,ops_reader_destroyer_t *destroyer,void *arg) - { - pinfo->rinfo.reader=reader; - pinfo->rinfo.destroyer=destroyer; - pinfo->rinfo.arg=arg; - } - -/** - * \ingroup Internal_Readers_Generic - * \brief Adds to reader stack - * \param pinfo Parse settings - * \param reader Reader to use - * \param destroyer Reader's destroyer - * \param arg Reader-specific arg - */ -void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,ops_reader_destroyer_t *destroyer,void *arg) - { - ops_reader_info_t *rinfo=malloc(sizeof *rinfo); - - *rinfo=pinfo->rinfo; - memset(&pinfo->rinfo,'\0',sizeof pinfo->rinfo); - pinfo->rinfo.next=rinfo; - pinfo->rinfo.pinfo=pinfo; - - // should copy accumulate flags from other reader? RW - pinfo->rinfo.accumulate=rinfo->accumulate; - - ops_reader_set(pinfo,reader,destroyer,arg); - } - -/** - * \ingroup Internal_Readers_Generic - * \brief Removes from reader stack - * \param pinfo Parse settings - */ -void ops_reader_pop(ops_parse_info_t *pinfo) - { - ops_reader_info_t *next=pinfo->rinfo.next; - // We are about to overwrite pinfo->rinfo, so free any data in the - // old rinfo structure first. - free(pinfo->rinfo.accumulated); - pinfo->rinfo=*next; - free(next); - } - -/** - * \ingroup Internal_Readers_Generic - * \brief Gets arg from reader - * \param rinfo Reader info - * \return Pointer to reader info's arg - */ -void *ops_reader_get_arg(ops_reader_info_t *rinfo) - { return rinfo->arg; } - -/** - * \ingroup Internal_Readers_Generic - * \brief Gets reader's arg from parse_info - * \param pinfo - * \return Pointer to parse_info's reader_info's arg - */ -void *ops_reader_get_arg_from_pinfo(ops_parse_info_t *pinfo) - { return pinfo->rinfo.arg; } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/reader_armoured.c b/openpgpsdk/src/openpgpsdk/reader_armoured.c deleted file mode 100644 index 44ed56592..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_armoured.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * \brief Code for dealing with ASCII-armoured packets - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "parse_local.h" - -#include - -#include - -static int debug=0; - -#define CRC24_POLY 0x1864cfbL - -/** - * \struct dearmour_arg_t - */ -typedef struct - { - enum - { - OUTSIDE_BLOCK=0, - BASE64, - AT_TRAILER_NAME, - } state; - - enum - { - NONE=0, - BEGIN_PGP_MESSAGE, - BEGIN_PGP_PUBLIC_KEY_BLOCK, - BEGIN_PGP_PRIVATE_KEY_BLOCK, - BEGIN_PGP_MULTI, - BEGIN_PGP_SIGNATURE, - - END_PGP_MESSAGE, - END_PGP_PUBLIC_KEY_BLOCK, - END_PGP_PRIVATE_KEY_BLOCK, - END_PGP_MULTI, - END_PGP_SIGNATURE, - - BEGIN_PGP_SIGNED_MESSAGE - } lastseen; - - ops_parse_info_t *parse_info; - ops_boolean_t seen_nl:1; - ops_boolean_t prev_nl:1; - ops_boolean_t allow_headers_without_gap:1; /*!< allow headers in - armoured data that - are not separated - from the data by a - blank line */ - ops_boolean_t allow_no_gap:1; /*!< allow no blank line at the - start of armoured data */ - ops_boolean_t allow_trailing_whitespace:1; /*!< allow armoured - stuff to have - trailing whitespace - where we wouldn't - strictly expect it */ - - // it is an error to get a cleartext message without a sig - ops_boolean_t expect_sig:1; - ops_boolean_t got_sig:1; - - // base64 stuff - unsigned buffered; - unsigned char buffer[3]; - ops_boolean_t eof64; - unsigned long checksum; - unsigned long read_checksum; - // unarmoured text blocks - unsigned char unarmoured[8192]; - size_t num_unarmoured; - // pushed back data (stored backwards) - unsigned char *pushed_back; - unsigned npushed_back; - // armoured block headers - ops_headers_t headers; - } dearmour_arg_t; - -static void push_back(dearmour_arg_t *arg,const unsigned char *buf, unsigned length) -{ - unsigned n; - - //ASSERT(!arg->pushed_back); // in the least, there will be a memory leak. Not a big issue. - arg->pushed_back=malloc(length); - for(n=0 ; n < length ; ++n) - arg->pushed_back[n]=buf[length-n-1]; - arg->npushed_back=length; -} - -static int set_lastseen_headerline(dearmour_arg_t* arg, char* buf, ops_error_t **errors) - { - char* begin_msg="BEGIN PGP MESSAGE"; - char* begin_public="BEGIN PGP PUBLIC KEY BLOCK"; - char* begin_private="BEGIN PGP PRIVATE KEY BLOCK"; - char* begin_multi="BEGIN PGP MESSAGE, PART "; - char* begin_sig="BEGIN PGP SIGNATURE"; - - char* end_msg="END PGP MESSAGE"; - char* end_public="END PGP PUBLIC KEY BLOCK"; - char* end_private="END PGP PRIVATE KEY BLOCK"; - char* end_multi="END PGP MESSAGE, PART "; - char* end_sig="END PGP SIGNATURE"; - - char* begin_signed_msg="BEGIN PGP SIGNED MESSAGE"; - - int prev=arg->lastseen; - - if (!strncmp(buf,begin_msg,strlen(begin_msg))) - arg->lastseen=BEGIN_PGP_MESSAGE; - else if (!strncmp(buf,begin_public,strlen(begin_public))) - arg->lastseen=BEGIN_PGP_PUBLIC_KEY_BLOCK; - else if (!strncmp(buf,begin_private,strlen(begin_private))) - arg->lastseen=BEGIN_PGP_PRIVATE_KEY_BLOCK; - else if (!strncmp(buf,begin_multi,strlen(begin_multi))) - arg->lastseen=BEGIN_PGP_MULTI; - else if (!strncmp(buf,begin_sig,strlen(begin_sig))) - arg->lastseen=BEGIN_PGP_SIGNATURE; - - else if (!strncmp(buf,end_msg,strlen(end_msg))) - arg->lastseen=END_PGP_MESSAGE; - else if (!strncmp(buf,end_public,strlen(end_public))) - arg->lastseen=END_PGP_PUBLIC_KEY_BLOCK; - else if (!strncmp(buf,end_private,strlen(end_private))) - arg->lastseen=END_PGP_PRIVATE_KEY_BLOCK; - else if (!strncmp(buf,end_multi,strlen(end_multi))) - arg->lastseen=END_PGP_MULTI; - else if (!strncmp(buf,end_sig,strlen(end_sig))) - arg->lastseen=END_PGP_SIGNATURE; - - else if (!strncmp(buf,begin_signed_msg,strlen(begin_signed_msg))) - arg->lastseen=BEGIN_PGP_SIGNED_MESSAGE; - - else - { - OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unrecognised Header Line %s", buf); - return 0; - } - - if (debug) - printf("set header: buf=%s, arg->lastseen=%d, prev=%d\n", buf, arg->lastseen, prev); - - switch (arg->lastseen) - { - case NONE: - OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unrecognised last seen Header Line %s", buf); - break; - - case END_PGP_MESSAGE: - if (prev!=BEGIN_PGP_MESSAGE) - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP MESSAGE, but not after BEGIN"); - break; - - case END_PGP_PUBLIC_KEY_BLOCK: - if (prev!=BEGIN_PGP_PUBLIC_KEY_BLOCK) - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP PUBLIC KEY BLOCK, but not after BEGIN"); - break; - - case END_PGP_PRIVATE_KEY_BLOCK: - if (prev!=BEGIN_PGP_PRIVATE_KEY_BLOCK) - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP PRIVATE KEY BLOCK, but not after BEGIN"); - break; - - case BEGIN_PGP_MULTI: - case END_PGP_MULTI: - OPS_ERROR(errors,OPS_E_R_UNSUPPORTED,"Multi-part messages are not yet supported"); - break; - - case END_PGP_SIGNATURE: - if (prev!=BEGIN_PGP_SIGNATURE) - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Got END PGP SIGNATURE, but not after BEGIN"); - break; - - case BEGIN_PGP_MESSAGE: - case BEGIN_PGP_PUBLIC_KEY_BLOCK: - case BEGIN_PGP_PRIVATE_KEY_BLOCK: - case BEGIN_PGP_SIGNATURE: - case BEGIN_PGP_SIGNED_MESSAGE: - break; - } - - return 1; - } - -static int read_char(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo, - ops_boolean_t skip) - { - unsigned char c[1]; - - do - { - if(arg->npushed_back) - { - c[0]=arg->pushed_back[--arg->npushed_back]; - if(!arg->npushed_back) - { - free(arg->pushed_back); - arg->pushed_back=NULL; - } - } - /* XXX: should ops_stacked_read exist? Shouldn't this be a limited_read? */ - else if(ops_stacked_read(c,1,errors,rinfo,cbinfo) != 1) - return -1; - } - while(skip && c[0] == '\r'); - - arg->prev_nl=arg->seen_nl; - arg->seen_nl=c[0] == '\n'; - - return c[0]; - } - -static int eat_whitespace(int first, - dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo, - ops_boolean_t skip) - { - int c=first; - - while(c == ' ' || c == '\t') - c=read_char(arg,errors,rinfo,cbinfo,skip); - - return c; - } - -static int read_and_eat_whitespace(dearmour_arg_t *arg, - ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo, - ops_boolean_t skip) - { - int c; - - do - c=read_char(arg,errors,rinfo,cbinfo,skip); - while(c == ' ' || c == '\t'); - - return c; - } - -static void flush(dearmour_arg_t *arg,ops_parse_cb_info_t *cbinfo) - { - ops_parser_content_t content; - - if(arg->num_unarmoured == 0) - return; - - content.content.unarmoured_text.data=arg->unarmoured; - content.content.unarmoured_text.length=arg->num_unarmoured; - CB(cbinfo,OPS_PTAG_CT_UNARMOURED_TEXT,&content); - arg->num_unarmoured=0; - } - -static int unarmoured_read_char(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo, - ops_boolean_t skip) - { - int c; - - do - { - c=read_char(arg,errors,rinfo,cbinfo,ops_false); - if(c < 0) - return c; - arg->unarmoured[arg->num_unarmoured++]=c; - if(arg->num_unarmoured == sizeof arg->unarmoured) - flush(arg,cbinfo); - } - while(skip && c == '\r'); - - return c; - } - -/** - * \param headers - * \param key - * - * \return header value if found, otherwise NULL - */ -const char *ops_find_header(ops_headers_t *headers,const char *key) - { - unsigned n; - - for(n=0 ; n < headers->nheaders ; ++n) - if(!strcmp(headers->headers[n].key,key)) - return headers->headers[n].value; - return NULL; - } - -/** - * \param dest - * \param src - */ -void ops_dup_headers(ops_headers_t *dest,const ops_headers_t *src) - { - unsigned n; - - dest->headers=malloc(src->nheaders*sizeof *dest->headers); - dest->nheaders=src->nheaders; - - for(n=0 ; n < src->nheaders ; ++n) - { - dest->headers[n].key=strdup(src->headers[n].key); - dest->headers[n].value=strdup(src->headers[n].value); - } - } - -/* Note that this skips CRs so implementations always see just - straight LFs as line terminators */ -static int process_dash_escaped(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - ops_parser_content_t content; - ops_parser_content_t content2; - ops_signed_cleartext_body_t *body=&content.content.signed_cleartext_body; - ops_signed_cleartext_trailer_t *trailer - =&content2.content.signed_cleartext_trailer; - const char *hashstr; - ops_hash_t *hash; - int total; - - hash=malloc(sizeof *hash); - hashstr=ops_find_header(&arg->headers,"Hash"); - if(hashstr) - { - ops_hash_algorithm_t alg; - - alg=ops_hash_algorithm_from_text(hashstr); - - if(!ops_is_hash_alg_supported(&alg)) - { - free(hash); - OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unsupported hash algorithm '%s'",hashstr); - return -1; - } - if(alg == OPS_HASH_UNKNOWN) - { - free(hash); - OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Unknown hash algorithm '%s'",hashstr); - return -1; - } - ops_hash_any(hash,alg); - } - else - ops_hash_md5(hash); - - hash->init(hash); - - body->length=0; - total=0; - for( ; ; ) - { - int c; - unsigned count; - - if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) - return -1; - if(arg->prev_nl && c == '-') - { - if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return -1; - if(c != ' ') - { - /* then this had better be a trailer! */ - if(c != '-') - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad dash-escaping"); - for(count=2 ; count < 5 ; ++count) - { - if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return -1; - if(c != '-') - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad dash-escaping (2)"); - } - arg->state=AT_TRAILER_NAME; - break; - } - /* otherwise we read the next character */ - if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return -1; - } - if(c == '\n' && body->length) - { - if(!(memchr(body->data+1,'\n',body->length-1) == NULL)) // ASSERT(memchr(body->data+1,'\n',body->length-1) == NULL); - { - fprintf(stderr,"no \\n in armoured file.") ; - return -1 ; - } - if(body->data[0] == '\n') - hash->add(hash,(unsigned char *)"\r",1); - hash->add(hash,body->data,body->length); - if (debug) - { fprintf(stderr,"Got body:\n%s\n",body->data); } - CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); - body->length=0; - } - - body->data[body->length++]=c; - ++total; - if(body->length == sizeof body->data) - { - if (debug) - { fprintf(stderr,"Got body (2):\n%s\n",body->data); } - CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); - body->length=0; - } - } - - if(!(body->data[0] == '\n')) // ASSERT(body->data[0] == '\n'); - { - fprintf(stderr,"Body should end with \\n\n"); - return -1 ; - } - if(!(body->length == 1)) // ASSERT(body->length == 1); - { - fprintf(stderr,"Body length error\n"); - return -1 ; - } - /* don't send that one character, because its part of the trailer. */ - - trailer->hash=hash; - CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2); - - return total; -} - -static int add_header(dearmour_arg_t *arg,const char *key,const char - *value) - { - /* - * Check that the header is valid - */ - if ( !strcmp(key,"Version") || !strcmp(key,"Comment") - || !strcmp(key,"MessageID") || !strcmp(key,"Hash") - || !strcmp(key,"Charset")) - { - arg->headers.headers=realloc(arg->headers.headers, - (arg->headers.nheaders+1) - *sizeof *arg->headers.headers); - arg->headers.headers[arg->headers.nheaders].key=strdup(key); - arg->headers.headers[arg->headers.nheaders].value=strdup(value); - ++arg->headers.nheaders; - return 1; - } - else - { - return 0; - } - } - -/* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */ -static int parse_headers(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) -{ - int rtn=1; - char *buf; - unsigned nbuf; - unsigned size; - ops_boolean_t first=ops_true; - //ops_parser_content_t content; - - buf=NULL; - nbuf=size=0; - - for( ; ; ) - { - int c; - - if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Unexpected EOF"); - rtn=-1; - break; - } - - if(c == '\n') - { - char *s; - - if(nbuf == 0) - break; - - if(!(nbuf < size)) // ASSERT(nbuf < size); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Size error in armour header"); - return -1 ; - } - buf[nbuf]='\0'; - - s=strchr(buf,':'); - if(!s) - if(!first && !arg->allow_headers_without_gap) - { - // then we have seriously malformed armour - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No colon in armour header"); - rtn=-1; - break; - } - else - { - if(first && - !(arg->allow_headers_without_gap || arg->allow_no_gap)) - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No colon in armour header (2)"); - // then we have a nasty armoured block with no - // headers, not even a blank line. - buf[nbuf]='\n'; - push_back(arg,(unsigned char *)buf,nbuf+1); - rtn=-1; - break; - } - } - else - { - *s='\0'; - if(s[1] != ' ') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No space in armour header"); - rtn=-1; - goto end; - } - if (!add_header(arg,buf,s+2)) - { - OPS_ERROR_1(errors,OPS_E_R_BAD_FORMAT,"Invalid header %s", buf); - rtn=-1; - goto end; - } - nbuf=0; - } - first=ops_false; - } - else - { - if(size <= nbuf+1) - { - size+=size+80; - char *nbuf; - nbuf=realloc(buf,size); - if (nbuf == NULL) - { - free(buf); - buf = NULL ; - rtn=-1; - goto end; - } - buf = nbuf; - } - buf[nbuf++]=c; - } - } - -end: - free(buf); - - return rtn; -} - -static int read4(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo, - int *pc,unsigned *pn,unsigned long *pl) - { - int n,c; - unsigned long l=0; - - for(n=0 ; n < 4 ; ++n) - { - c=read_char(arg,errors,rinfo,cbinfo,ops_true); - if(c < 0) - { - arg->eof64=ops_true; - return -1; - } - if(c == '-') - break; - if(c == '=') - break; - l <<= 6; - if(c >= 'A' && c <= 'Z') - l+=c-'A'; - else if(c >= 'a' && c <= 'z') - l+=c-'a'+26; - else if(c >= '0' && c <= '9') - l+=c-'0'+52; - else if(c == '+') - l+=62; - else if(c == '/') - l+=63; - else - { - --n; - l >>= 6; - } - } - - *pc=c; - *pn=n; - *pl=l; - - return 4; - } - -unsigned ops_crc24(unsigned checksum,unsigned char c) - { - unsigned i; - - checksum ^= c << 16; - for(i=0 ; i < 8 ; i++) - { - checksum <<= 1; - if(checksum & 0x1000000) - checksum ^= CRC24_POLY; - } - return checksum&0xffffffL; - } - -static int decode64(dearmour_arg_t *arg,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) -{ - unsigned n; - int n2; - unsigned long l; - int c; - int ret; - - if(!(arg->buffered == 0)) // ASSERT(arg->buffered == 0); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly formed base64"); - return 0; - } - - ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&l); - if(ret < 0) - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly formed base64"); - return 0; - } - - if(n == 3) - { - if(c != '=') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated base64 (2)"); - return 0; - } - arg->buffered=2; - arg->eof64=ops_true; - l >>= 2; - } - else if(n == 2) - { - if(c != '=') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated base64 (3)"); - return 0; - } - arg->buffered=1; - arg->eof64=ops_true; - l >>= 4; - c=read_char(arg,errors,rinfo,cbinfo,ops_false); - if(c != '=') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated base64"); - return 0; - } - } - else if(n == 0) - { - if(!arg->prev_nl || c != '=') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated base64 (4)"); - return 0; - } - arg->buffered=0; - } - else - { - if(n != 4) // ASSERT(n == 4); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"n should be 4"); - return 0; - } - arg->buffered=3; - - if(!(c != '-' && c != '=')) // ASSERT(c != '-' && c != '='); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated Base64 chunk"); - return 0; - } - } - - if(arg->buffered < 3 && arg->buffered > 0) - { - // then we saw padding - if(!(c == '=')) // ASSERT(c == '='); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated Base64 chunk"); - return 0; - } - c=read_and_eat_whitespace(arg,errors,rinfo,cbinfo,ops_true); - if(c != '\n') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No newline at base64 end"); - return 0; - } - c=read_char(arg,errors,rinfo,cbinfo,ops_false); - if(c != '=') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"No checksum at base64 end"); - return 0; - } - } - - if(c == '=') - { - // now we are at the checksum - ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&arg->read_checksum); - if(ret < 0 || n != 4) - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Error in checksum"); - return 0; - } - c=read_char(arg,errors,rinfo,cbinfo,ops_true); - if(arg->allow_trailing_whitespace) - c=eat_whitespace(c,arg,errors,rinfo,cbinfo,ops_true); - if(c != '\n') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Badly terminated checksum"); - return 0; - } - c=read_char(arg,errors,rinfo,cbinfo,ops_false); - if(c != '-') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad base64 trailer (2)"); - return 0; - } - } - - if(c == '-') - { - for(n=0 ; n < 4 ; ++n) - if(read_char(arg,errors,rinfo,cbinfo,ops_false) != '-') - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad base64 trailer"); - return 0; - } - arg->eof64=ops_true; - } - else if(!(arg->buffered)) // ASSERT(arg->buffered); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Buffer error"); - return 0; - } - - for(n=0 ; n < arg->buffered ; ++n) - { - arg->buffer[n]=l; - l >>= 8; - } - - for(n2=arg->buffered-1 ; n2 >= 0 ; --n2) - arg->checksum=ops_crc24(arg->checksum,arg->buffer[n2]); - - if(arg->eof64 && arg->read_checksum != arg->checksum) - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Checksum mismatch"); - return 0; - } - - return 1; -} - -static void base64(dearmour_arg_t *arg) - { - arg->state=BASE64; - arg->checksum=CRC24_INIT; - arg->eof64=ops_false; - arg->buffered=0; - } - -// This reader is rather strange in that it can generate callbacks for -// content - this is because plaintext is not encapsulated in PGP -// packets... it also calls back for the text between the blocks. - -static int armoured_data_reader(void *dest_,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - dearmour_arg_t *arg=ops_reader_get_arg(rinfo); - ops_parser_content_t content; - int ret; - ops_boolean_t first; - unsigned char *dest=dest_; - int saved=length; - - if(arg->eof64 && !arg->buffered) - if(!(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME)) // ASSERT(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Outside block or trailer name expected"); - return -1 ; - } - - while(length > 0) - { - unsigned count; - unsigned n; - char buf[1024]; - int c; - - flush(arg,cbinfo); - switch(arg->state) - { - case OUTSIDE_BLOCK: - /* This code returns EOF rather than EARLY_EOF because if - we don't see a header line at all, then it is just an - EOF (and not a BLOCK_END) */ - while(!arg->seen_nl) - if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) - return 0; - - /* flush at this point so we definitely have room for the - header, and so we can easily erase it from the buffer */ - flush(arg,cbinfo); - /* Find and consume the 5 leading '-' */ - for(count=0 ; count < 5 ; ++count) - { - if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return 0; - if(c != '-') - goto reloop; - } - - /* Now find the block type */ - for(n=0 ; n < sizeof buf-1 ; ) - { - if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return 0; - if(c == '-') - goto got_minus; - buf[n++]=c; - } - /* then I guess this wasn't a proper header */ - break; - -got_minus: - buf[n]='\0'; - - /* Consume trailing '-' */ - for(count=1 ; count < 5 ; ++count) - { - if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return 0; - if(c != '-') - /* wasn't a header after all */ - goto reloop; - } - - /* Consume final NL */ - if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) - return 0; - if(arg->allow_trailing_whitespace) - if((c=eat_whitespace(c,arg,errors,rinfo,cbinfo, - ops_true)) < 0) - return 0; - if(c != '\n') - /* wasn't a header line after all */ - break; - - /* Now we've seen the header, scrub it from the buffer */ - arg->num_unarmoured=0; - - /* But now we've seen a header line, then errors are - EARLY_EOF */ - if((ret=parse_headers(arg,errors,rinfo,cbinfo)) <= 0) - return -1; - - if (!set_lastseen_headerline(arg,buf,errors)) - return -1; - - if(!strcmp(buf,"BEGIN PGP SIGNED MESSAGE")) - { - ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); - CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); - ret=process_dash_escaped(arg,errors,rinfo,cbinfo); - if(ret <= 0) - return ret; - } - else - { - content.content.armour_header.type=buf; - content.content.armour_header.headers=arg->headers; - memset(&arg->headers,'\0',sizeof arg->headers); - CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); - base64(arg); - } - break; - - case BASE64: - first=ops_true; - while(length > 0) - { - if(!arg->buffered) - { - if(!arg->eof64) - { - ret=decode64(arg,errors,rinfo,cbinfo); - if(ret <= 0) - return ret; - } - if(!arg->buffered) - { - if(!(arg->eof64)) // ASSERT(arg->eof64); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Format error"); - return -1 ; - } - if(first) - { - arg->state=AT_TRAILER_NAME; - goto reloop; - } - return -1; - } - } - - if(!(arg->buffered)) // ASSERT(arg->buffered); - { - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Format error"); - return -1 ; - } - *dest=arg->buffer[--arg->buffered]; - ++dest; - --length; - first=ops_false; - } - if(arg->eof64 && !arg->buffered) - arg->state=AT_TRAILER_NAME; - break; - - case AT_TRAILER_NAME: - for(n=0 ; n < sizeof buf-1 ; ) - { - if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return -1; - if(c == '-') - goto got_minus2; - buf[n++]=c; - } - /* then I guess this wasn't a proper trailer */ - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad ASCII armour trailer"); - break; - -got_minus2: - buf[n]='\0'; - - if (!set_lastseen_headerline(arg,buf,errors)) - return -1; - - /* Consume trailing '-' */ - for(count=1 ; count < 5 ; ++count) - { - if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) - return -1; - if(c != '-') - /* wasn't a trailer after all */ - OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,"Bad ASCII armour trailer (2)"); - } - - /* Consume final NL */ - if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) - return -1; - if(arg->allow_trailing_whitespace) - if((c=eat_whitespace(c,arg,errors,rinfo,cbinfo, - ops_true)) < 0) - return 0; - if(c != '\n') - /* wasn't a trailer line after all */ - OPS_ERROR(errors,OPS_E_R_BAD_FORMAT,"Bad ASCII armour trailer (3)"); - - if(!strncmp(buf,"BEGIN ",6)) - { - if (!set_lastseen_headerline(arg,buf,errors)) - return -1; - if((ret=parse_headers(arg,errors,rinfo,cbinfo)) <= 0) - return ret; - content.content.armour_header.type=buf; - content.content.armour_header.headers=arg->headers; - memset(&arg->headers,'\0',sizeof arg->headers); - CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); - base64(arg); - } - else - { - content.content.armour_trailer.type=buf; - CB(cbinfo,OPS_PTAG_CT_ARMOUR_TRAILER,&content); - arg->state=OUTSIDE_BLOCK; - } - break; - } -reloop: - continue; - } - - return saved; -} - -static void armoured_data_destroyer(ops_reader_info_t *rinfo) - { free(ops_reader_get_arg(rinfo)); } - -/** - * \ingroup Core_Readers_Armour - * \brief Pushes dearmouring reader onto stack - * \param parse_info Usual structure containing information about to how to do the parse - * \sa ops_reader_pop_dearmour() - */ -void ops_reader_push_dearmour(ops_parse_info_t *parse_info) - /* - This function originally had these parameters to cater for - packets which didn't strictly match the RFC. - The initial 0.5 release is only going to support - strict checking. - If it becomes desirable to support loose checking of armoured packets - and these params are reinstated, parse_headers() must be fixed - so that these flags work correctly. - - // Allow headers in armoured data that are not separated from the data by a blank line - ops_boolean_t without_gap, - - // Allow no blank line at the start of armoured data - ops_boolean_t no_gap, - - //Allow armoured data to have trailing whitespace where we strictly would not expect it - ops_boolean_t trailing_whitespace - */ - { - dearmour_arg_t *arg; - - arg=ops_mallocz(sizeof *arg); - arg->seen_nl=ops_true; -/* - arg->allow_headers_without_gap=without_gap; - arg->allow_no_gap=no_gap; - arg->allow_trailing_whitespace=trailing_whitespace; -*/ - arg->expect_sig=ops_false; - arg->got_sig=ops_false; - - ops_reader_push(parse_info,armoured_data_reader,armoured_data_destroyer,arg); - } - -/** - * \ingroup Core_Readers_Armour - * \brief Pops dearmour reader from stock - * \param pinfo - * \sa ops_reader_push_dearmour() - */ -void ops_reader_pop_dearmour(ops_parse_info_t *pinfo) - { - dearmour_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(pinfo)); - free(arg); - ops_reader_pop(pinfo); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/reader_encrypted_se.c b/openpgpsdk/src/openpgpsdk/reader_encrypted_se.c deleted file mode 100644 index d45fa8108..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_encrypted_se.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#ifndef OPENSSL_NO_IDEA -#include -#endif -#include -#include -#include "parse_local.h" - -#include -#include - -static int debug=0; - -#ifndef ATTRIBUTE_UNUSED - -#ifndef WIN32 -#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#else -#define ATTRIBUTE_UNUSED -#endif // #ifndef WIN32 - -#endif /* ATTRIBUTE_UNUSED */ - - -// \todo there's also a encrypted_arg_t in adv_create.c -// which is used for *encrypting* whereas this is used -// for *decrypting* - -typedef struct - { - unsigned char decrypted[1024]; - size_t decrypted_count; - size_t decrypted_offset; - ops_crypt_t *decrypt; - ops_region_t *region; - ops_boolean_t prev_read_was_plain:1; - } encrypted_arg_t; - -static int encrypted_data_reader(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - encrypted_arg_t *arg=ops_reader_get_arg(rinfo); - int saved=length; - - // V3 MPIs have the count plain and the cipher is reset after each count - if(arg->prev_read_was_plain && !rinfo->pinfo->reading_mpi_length) - { - if(!(rinfo->pinfo->reading_v3_secret)) // ASSERT(rinfo->pinfo->reading_v3_secret); - { - fprintf(stderr,"encrypted_data_reader: Expected non null value for rinfo->pinfo->reading_v3_secret") ; - return -1 ; - } - arg->decrypt->decrypt_resync(arg->decrypt); - arg->prev_read_was_plain=ops_false; - } - else if(rinfo->pinfo->reading_v3_secret - && rinfo->pinfo->reading_mpi_length) - { - arg->prev_read_was_plain=ops_true; - } - - while(length > 0) - { - if(arg->decrypted_count) - { - - unsigned n; - - // if we are reading v3 we should never read more than - // we're asked for - if(!(length >= arg->decrypted_count || (!rinfo->pinfo->reading_v3_secret && !rinfo->pinfo->exact_read))) // ASSERT(length >= arg->decrypted_count || (!rinfo->pinfo->reading_v3_secret && !rinfo->pinfo->exact_read)); - { - fprintf(stderr,"encrypted_data_reader: inconsistency in packet sizes") ; - return -1 ; - } - - if(length > arg->decrypted_count) - n=arg->decrypted_count; - else - n=length; - - memcpy(dest,arg->decrypted+arg->decrypted_offset,n); - arg->decrypted_count-=n; - arg->decrypted_offset+=n; - length-=n; - dest+=n; - } - else - { - unsigned n=arg->region->length; - unsigned char buffer[1024]; - - if(!n) - { - return -1; - } - - if(!arg->region->indeterminate) - { - n-=arg->region->length_read; - if(n == 0) - return saved-length; - if(n > sizeof buffer) - n=sizeof buffer; - } - else - { - n=sizeof buffer; - } - - // we can only read as much as we're asked for in v3 keys - // because they're partially unencrypted! - if((rinfo->pinfo->reading_v3_secret || rinfo->pinfo->exact_read) - && n > length) - n=length; - - if(!ops_stacked_limited_read(buffer,n,arg->region,errors,rinfo, - cbinfo)) - { - return -1; - } - - if(!rinfo->pinfo->reading_v3_secret - || !rinfo->pinfo->reading_mpi_length) - { - arg->decrypted_count=ops_decrypt_se_ip(arg->decrypt, - arg->decrypted, - buffer,n); - - if (debug) - { - fprintf(stderr,"READING:\nencrypted: "); - int i=0; - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", buffer[i]); - fprintf(stderr,"\n"); - fprintf(stderr,"decrypted: "); - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", arg->decrypted[i]); - fprintf(stderr,"\n"); - } - } - else - { - memcpy(arg->decrypted,buffer,n); - arg->decrypted_count=n; - } - - if(!(arg->decrypted_count > 0)) // ASSERT(arg->decrypted_count > 0); - { - fprintf(stderr,"encrypted_data_reader: inconsistency in decrypted count") ; - return -1 ; - } - - arg->decrypted_offset=0; - } - } - - return saved; -} - -static void encrypted_data_destroyer(ops_reader_info_t *rinfo) - { free(ops_reader_get_arg(rinfo)); } - -/** - * \ingroup Core_Readers_SE - * \brief Pushes decryption reader onto stack - * \sa ops_reader_pop_decrypt() - */ -void ops_reader_push_decrypt(ops_parse_info_t *pinfo,ops_crypt_t *decrypt, - ops_region_t *region) - { - encrypted_arg_t *arg=ops_mallocz(sizeof *arg); - - arg->decrypt=decrypt; - arg->region=region; - - ops_decrypt_init(arg->decrypt); - - ops_reader_push(pinfo,encrypted_data_reader,encrypted_data_destroyer,arg); - } - -/** - * \ingroup Core_Readers_Encrypted - * \brief Pops decryption reader from stack - * \sa ops_reader_push_decrypt() - */ -void ops_reader_pop_decrypt(ops_parse_info_t *pinfo) - { - encrypted_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(pinfo)); - - arg->decrypt->decrypt_finish(arg->decrypt); - free(arg); - - ops_reader_pop(pinfo); - } - -// eof diff --git a/openpgpsdk/src/openpgpsdk/reader_encrypted_seip.c b/openpgpsdk/src/openpgpsdk/reader_encrypted_seip.c deleted file mode 100644 index 4e5251648..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_encrypted_seip.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - * \brief Parser for OpenPGP packets - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "parse_local.h" - -#include -#include -#include -#ifndef WIN32 -#include -#endif -#include -#include - -#include - -static int debug=0; - -typedef struct - { - // boolean: false once we've done the preamble/MDC checks - // and are reading from the plaintext - int passed_checks; - unsigned char *plaintext; - size_t plaintext_available; - size_t plaintext_offset; - ops_region_t *region; - ops_crypt_t *decrypt; - } decrypt_se_ip_arg_t; - -static int se_ip_data_reader(void *dest_, size_t len, ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) - { - - /* - Gets entire SE_IP data packet. - Verifies leading preamble - Verifies trailing MDC packet - Then passes up plaintext as requested - */ - - unsigned int n=0; - - ops_region_t decrypted_region; - - decrypt_se_ip_arg_t *arg=ops_reader_get_arg(rinfo); - - if (!arg->passed_checks) - { - unsigned char*buf=NULL; - - ops_hash_t hash; - unsigned char hashed[SHA_DIGEST_LENGTH]; - - size_t b; - size_t sz_preamble; - size_t sz_mdc_hash; - size_t sz_mdc; - size_t sz_plaintext; - - unsigned char* preamble; - unsigned char* plaintext; - unsigned char* mdc; - unsigned char* mdc_hash; - - ops_hash_any(&hash,OPS_HASH_SHA1); - hash.init(&hash); - - ops_init_subregion(&decrypted_region,NULL); - decrypted_region.length = arg->region->length - arg->region->length_read; - buf=ops_mallocz(decrypted_region.length); - - // read entire SE IP packet - - if (!ops_stacked_limited_read(buf,decrypted_region.length, &decrypted_region,errors,rinfo,cbinfo)) - { - free (buf); - return -1; - } - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"\n\nentire SE IP packet (len=%d):\n",decrypted_region.length); - for (i=0; idecrypt->blocksize+2;i++) - fprintf(stderr," 0x%02x", buf[i]); - fprintf(stderr,"\n"); - } - - b=arg->decrypt->blocksize; - if(buf[b-2] != buf[b] || buf[b-1] != buf[b+1]) - { - fprintf(stderr,"Bad symmetric decrypt (%02x%02x vs %02x%02x)\n", - buf[b-2],buf[b-1],buf[b],buf[b+1]); - OPS_ERROR(errors, OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT,"Bad symmetric decrypt when parsing SE IP packet"); - free(buf); - return -1; - } - - // Verify trailing MDC hash - - sz_preamble=arg->decrypt->blocksize+2; - sz_mdc_hash=OPS_SHA1_HASH_SIZE; - sz_mdc=1+1+sz_mdc_hash; - sz_plaintext=decrypted_region.length-sz_preamble-sz_mdc; - - preamble=buf; - plaintext=buf+sz_preamble; - mdc=plaintext+sz_plaintext; - mdc_hash=mdc+2; - -#ifdef DEBUG - if (debug) - { - unsigned int i=0; - - fprintf(stderr,"\nplaintext (len=%ld): ",sz_plaintext); - for (i=0; iplaintext) // ASSERT(!arg->plaintext); - { - fprintf(stderr,"se_ip_data_reader: consistency error\n"); - return -1 ; - } - arg->plaintext=ops_mallocz(sz_plaintext); - memcpy(arg->plaintext, plaintext, sz_plaintext); - arg->plaintext_available=sz_plaintext; - - arg->passed_checks=1; - - free(buf); - } - - n=len; - if (n > arg->plaintext_available) - n=arg->plaintext_available; - - memcpy(dest_, arg->plaintext+arg->plaintext_offset, n); - arg->plaintext_available-=n; - arg->plaintext_offset+=n; - len-=n; - - return n; - } - -static void se_ip_data_destroyer(ops_reader_info_t *rinfo) - { - decrypt_se_ip_arg_t* arg=ops_reader_get_arg(rinfo); - free (arg->plaintext); - free (arg); - // free(ops_reader_get_arg(rinfo)); - } - -/** - \ingroup Internal_Readers_SEIP -*/ -void ops_reader_push_se_ip_data(ops_parse_info_t *pinfo, ops_crypt_t *decrypt, - ops_region_t *region) - { - decrypt_se_ip_arg_t *arg=ops_mallocz(sizeof *arg); - arg->region=region; - arg->decrypt=decrypt; - - ops_reader_push(pinfo, se_ip_data_reader, se_ip_data_destroyer,arg); - } - -/** - \ingroup Internal_Readers_SEIP - */ -void ops_reader_pop_se_ip_data(ops_parse_info_t* pinfo) - { - // decrypt_se_ip_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(pinfo)); - // free(arg); - ops_reader_pop(pinfo); - } - -// eof diff --git a/openpgpsdk/src/openpgpsdk/reader_fd.c b/openpgpsdk/src/openpgpsdk/reader_fd.c deleted file mode 100644 index 8681c65d7..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_fd.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef WIN32 -#include -#endif - -#include - -#include - -/** Arguments for reader_fd - */ -typedef struct - { - int fd; /*!< file descriptor */ - } reader_fd_arg_t; - -/** - * \ingroup Core_Readers - * - * ops_reader_fd() attempts to read up to "plength" bytes from the file - * descriptor in "parse_info" into the buffer starting at "dest" using the - * rules contained in "flags" - * - * \param dest Pointer to previously allocated buffer - * \param plength Number of bytes to try to read - * \param flags Rules about reading to use - * \param parse_info Gets cast to ops_reader_fd_arg_t - * - * \return OPS_R_EOF if no bytes were read - * \return OPS_R_PARTIAL_READ if not enough bytes were read, and OPS_RETURN_LENGTH is set in "flags" - * \return OPS_R_EARLY_EOF if not enough bytes were read, and OPS_RETURN_LENGTH was not set in "flags" - * \return OPS_R_OK if expected length was read - * \return OPS_R_ERROR if cannot read - * - * OPS_R_EARLY_EOF and OPS_R_ERROR push errors on the stack - * - * \sa enum opt_reader_ret_t - * - * \todo change arg_ to typesafe? - */ -static int fd_reader(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) - { - reader_fd_arg_t *arg=ops_reader_get_arg(rinfo); - int n=read(arg->fd,dest,length); - - OPS_USED(cbinfo); - - if(n == 0) - return 0; - - if(n < 0) - { - OPS_SYSTEM_ERROR_1(errors,OPS_E_R_READ_FAILED,"read", - "file descriptor %d",arg->fd); - return -1; - } - - return n; - } - -static void fd_destroyer(ops_reader_info_t *rinfo) - { free(ops_reader_get_arg(rinfo)); } - -/** - \ingroup Core_Readers_First - \brief Starts stack with file reader -*/ - -void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd) - { - reader_fd_arg_t *arg=malloc(sizeof *arg); - - arg->fd=fd; - ops_reader_set(pinfo,fd_reader,fd_destroyer,arg); - } - -// eof diff --git a/openpgpsdk/src/openpgpsdk/reader_hashed.c b/openpgpsdk/src/openpgpsdk/reader_hashed.c deleted file mode 100644 index 3cc6d2bc2..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_hashed.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include - -#include - -static int hash_reader(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) - { - ops_hash_t *hash=ops_reader_get_arg(rinfo); - int r=ops_stacked_read(dest,length,errors,rinfo,cbinfo); - - if(r <= 0) - return r; - - hash->add(hash,dest,r); - - return r; - } - -/** - \ingroup Internal_Readers_Hash - \brief Push hashed data reader on stack -*/ -void ops_reader_push_hash(ops_parse_info_t *pinfo,ops_hash_t *hash) - { - hash->init(hash); - ops_reader_push(pinfo,hash_reader,NULL,hash); - } - -/** - \ingroup Internal_Readers_Hash - \brief Pop hashed data reader from stack -*/ -void ops_reader_pop_hash(ops_parse_info_t *pinfo) - { ops_reader_pop(pinfo); } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/reader_mem.c b/openpgpsdk/src/openpgpsdk/reader_mem.c deleted file mode 100644 index 2802673c8..000000000 --- a/openpgpsdk/src/openpgpsdk/reader_mem.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef WIN32 -#include -#endif - -#include - -#include - -typedef struct - { - const unsigned char *buffer; - size_t length; - size_t offset; - } reader_mem_arg_t; - -static int mem_reader(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) - { - reader_mem_arg_t *arg=ops_reader_get_arg(rinfo); - unsigned n; - - OPS_USED(cbinfo); - OPS_USED(errors); - - if(arg->offset+length > arg->length) - n=arg->length-arg->offset; - else - n=length; - - if(n == 0) - return 0; - - memcpy(dest,arg->buffer+arg->offset,n); - arg->offset+=n; - - return n; - } - -static void mem_destroyer(ops_reader_info_t *rinfo) - { free(ops_reader_get_arg(rinfo)); } - -/** - \ingroup Core_Readers_First - \brief Starts stack with memory reader -*/ - -void ops_reader_set_memory(ops_parse_info_t *pinfo,const void *buffer, - size_t length) - { - reader_mem_arg_t *arg=malloc(sizeof *arg); - - arg->buffer=buffer; - arg->length=length; - arg->offset=0; - ops_reader_set(pinfo,mem_reader,mem_destroyer,arg); - } - -/* eof */ diff --git a/openpgpsdk/src/openpgpsdk/readerwriter.c b/openpgpsdk/src/openpgpsdk/readerwriter.c deleted file mode 100644 index 78b45e28c..000000000 --- a/openpgpsdk/src/openpgpsdk/readerwriter.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#ifndef WIN32 -#include -#include -#else -#include -#endif -#include -#include - -#include -#include -#include - -#include "parse_local.h" - -#ifdef WIN32 -#include -#include - -#define PASS_MAX 512 - -char *getpass (const char *prompt) -{ - static char getpassbuf [PASS_MAX + 1]; - size_t i = 0; - int c; - - if (prompt) { - fputs (prompt, stderr); - fflush (stderr); - } - - for (;;) { - c = _getch (); - if (c == '\r') { - getpassbuf [i] = '\0'; - break; - } - else if (i < PASS_MAX) { - getpassbuf[i++] = c; - } - - if (i >= PASS_MAX) { - getpassbuf [i] = '\0'; - break; - } - } - - if (prompt) { - fputs ("\r\n", stderr); - fflush (stderr); - } - - return getpassbuf; -} -#endif - -/** - \ingroup Core_Writers - \brief Create and initialise cinfo and mem; Set for writing to mem - \param cinfo Address where new cinfo pointer will be set - \param mem Address when new mem pointer will be set - \param bufsz Initial buffer size (will automatically be increased when necessary) - \note It is the caller's responsiblity to free cinfo and mem. - \sa ops_teardown_memory_write() -*/ -void ops_setup_memory_write(ops_create_info_t **cinfo, ops_memory_t **mem, size_t bufsz) - { - /* - * initialise needed structures for writing to memory - */ - - *cinfo=ops_create_info_new(); - *mem=ops_memory_new(); - - ops_memory_init(*mem,bufsz); - - ops_writer_set_memory(*cinfo,*mem); - } - -/** - \ingroup Core_Writers - \brief Closes writer and frees cinfo and mem - \param cinfo - \param mem - \sa ops_setup_memory_write() -*/ -void ops_teardown_memory_write(ops_create_info_t *cinfo, ops_memory_t *mem) - { - ops_writer_close(cinfo); // new - ops_create_info_delete(cinfo); - ops_memory_free(mem); - } - -/** - \ingroup Core_Readers - \brief Create parse_info and sets to read from memory - \param pinfo Address where new parse_info will be set - \param mem Memory to read from - \param arg Reader-specific arg - \param callback Callback to use with reader - \param accumulate Set if we need to accumulate as we read. (Usually false unless doing signature verification) - \note It is the caller's responsiblity to free parse_info - \sa ops_teardown_memory_read() -*/ -void ops_setup_memory_read(ops_parse_info_t **pinfo, ops_memory_t *mem, - void* arg, - ops_parse_cb_return_t callback(const ops_parser_content_t *, ops_parse_cb_info_t *), - ops_boolean_t accumulate) - { - /* - * initialise needed uctures for reading - */ - - *pinfo=ops_parse_info_new(); - ops_parse_cb_set(*pinfo,callback,arg); - ops_reader_set_memory(*pinfo, - ops_memory_get_data(mem), - ops_memory_get_length(mem)); - - if (accumulate) - (*pinfo)->rinfo.accumulate=ops_true; - } - -/** - \ingroup Core_Readers - \brief Frees pinfo and mem - \param pinfo - \param mem - \sa ops_setup_memory_read() -*/ -void ops_teardown_memory_read(ops_parse_info_t *pinfo, ops_memory_t *mem) - { - ops_parse_info_delete(pinfo); - ops_memory_free(mem); - } - -/** - \ingroup Core_Writers - \brief Create and initialise cinfo and mem; Set for writing to file - \param cinfo Address where new cinfo pointer will be set - \param filename File to write to - \param allow_overwrite Allows file to be overwritten, if set. - \return Newly-opened file descriptor - \note It is the caller's responsiblity to free cinfo and to close fd. - \sa ops_teardown_file_write() -*/ -int ops_setup_file_write(ops_create_info_t **cinfo, const char* filename, ops_boolean_t allow_overwrite) - { - int fd=0; - int flags=0; - - /* - * initialise needed structures for writing to file - */ - - flags=O_WRONLY | O_CREAT; - if (allow_overwrite==ops_true) - flags |= O_TRUNC; - else - flags |= O_EXCL; - flags |= O_BINARY; - - fd=ops_open(filename, flags, 0600); - if(fd < 0) - { - perror(filename); - return fd; - } - - *cinfo=ops_create_info_new(); - - ops_writer_set_fd(*cinfo,fd); - - return fd; - } - -/** - \ingroup Core_Writers - \brief Closes writer, frees info, closes fd - \param cinfo - \param fd -*/ -void ops_teardown_file_write(ops_create_info_t *cinfo, int fd) - { - ops_writer_close(cinfo); - close(fd); - ops_create_info_delete(cinfo); - } - -/** - \ingroup Core_Writers - \brief As ops_setup_file_write, but appends to file -*/ -int ops_setup_file_append(ops_create_info_t **cinfo, const char* filename) - { - int fd; - /* - * initialise needed structures for writing to file - */ - - fd=ops_open(filename,O_WRONLY | O_APPEND | O_BINARY | O_CREAT, 0600); - - if(fd < 0) - { - perror(filename); - return fd; - } - - *cinfo=ops_create_info_new(); - - ops_writer_set_fd(*cinfo,fd); - - return fd; - } - -/** - \ingroup Core_Writers - \brief As ops_teardown_file_write() -*/ -void ops_teardown_file_append(ops_create_info_t *cinfo, int fd) - { - ops_teardown_file_write(cinfo,fd); - } - -/** - \ingroup Core_Readers - \brief Creates parse_info, opens file, and sets to read from file - \param pinfo Address where new parse_info will be set - \param filename Name of file to read - \param arg Reader-specific arg - \param callback Callback to use when reading - \param accumulate Set if we need to accumulate as we read. (Usually false unless doing signature verification) - \note It is the caller's responsiblity to free parse_info and to close fd - \sa ops_teardown_file_read() -*/ - -int ops_setup_file_read(ops_parse_info_t **pinfo, const char *filename, - void* arg, - ops_parse_cb_return_t callback(const ops_parser_content_t *, ops_parse_cb_info_t *), - ops_boolean_t accumulate) - { - int fd=0; - /* - * initialise needed structures for reading - */ - - fd=ops_open(filename,O_RDONLY | O_BINARY, 0); - - if (fd < 0) - { - perror(filename); - return fd; - } - - *pinfo=ops_parse_info_new(); - ops_parse_cb_set(*pinfo,callback,arg); - ops_reader_set_fd(*pinfo,fd); - - if (accumulate) - (*pinfo)->rinfo.accumulate=ops_true; - - return fd; - } - -/** - \ingroup Core_Readers - \brief Frees pinfo and closes fd - \param pinfo - \param fd - \sa ops_setup_file_read() -*/ -void ops_teardown_file_read(ops_parse_info_t *pinfo, int fd) - { - close(fd); - ops_parse_info_delete(pinfo); - } - -ops_parse_cb_return_t -callback_literal_data(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) - { - ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content; - - OPS_USED(cbinfo); - - // ops_print_packet(content_); - - // Read data from packet into static buffer - switch(content_->tag) - { - case OPS_PTAG_CT_LITERAL_DATA_BODY: - // if writer enabled, use it - if (cbinfo->cinfo) - { - ops_write(content->literal_data_body.data, - content->literal_data_body.length, - cbinfo->cinfo); - } - /* - ops_memory_add(mem_literal_data, - content->literal_data_body.data, - content->literal_data_body.length); - */ - break; - - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - // ignore - break; - - default: - // return callback_general(content_,cbinfo); - break; - } - - return OPS_RELEASE_MEMORY; - } - -ops_parse_cb_return_t -callback_pk_session_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) - { - ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content; - - OPS_USED(cbinfo); - - // ops_print_packet(content_); - - // Read data from packet into static buffer - switch(content_->tag) - { - case OPS_PTAG_CT_PK_SESSION_KEY: - // printf ("OPS_PTAG_CT_PK_SESSION_KEY\n"); - if(!(cbinfo->cryptinfo.keyring)) // ASSERT(cbinfo->cryptinfo.keyring); - { - fprintf(stderr,"No keyring supplied!") ; - return 0 ; - } - cbinfo->cryptinfo.keydata=ops_keyring_find_key_by_id(cbinfo->cryptinfo.keyring, - content->pk_session_key.key_id); - if(!cbinfo->cryptinfo.keydata) - break; - break; - - default: - // return callback_general(content_,cbinfo); - break; - } - - return OPS_RELEASE_MEMORY; - } - -/** - \ingroup Core_Callbacks - -\brief Callback to get secret key, decrypting if necessary. - -@verbatim - This callback does the following: - * finds the session key in the keyring - * gets a passphrase if required - * decrypts the secret key, if necessary - * sets the secret_key in the content struct -@endverbatim -*/ - -ops_parse_cb_return_t -callback_cmd_get_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) -{ - ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content; - const ops_secret_key_t *secret; - ops_parser_content_t pc; - - OPS_USED(cbinfo); - - // ops_print_packet(content_); - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SECRET_KEY: - cbinfo->cryptinfo.keydata=ops_keyring_find_key_by_id(cbinfo->cryptinfo.keyring,content->get_secret_key.pk_session_key->key_id); - if (!cbinfo->cryptinfo.keydata || !ops_is_key_secret(cbinfo->cryptinfo.keydata)) - return 0; - - /* now get the key from the data */ - secret=ops_get_secret_key_from_data(cbinfo->cryptinfo.keydata); - int tag_to_use = OPS_PARSER_CMD_GET_SK_PASSPHRASE ; - int nbtries = 0 ; - - while( (!secret) && nbtries++ < 3) - { - if (!cbinfo->cryptinfo.passphrase) - { - cbinfo->arg = malloc(sizeof(unsigned char)) ; - *(unsigned char *)cbinfo->arg = 0 ; - - memset(&pc,'\0',sizeof pc); - pc.content.secret_key_passphrase.passphrase=&cbinfo->cryptinfo.passphrase; - CB(cbinfo,tag_to_use,&pc); - - if(*(unsigned char*)(cbinfo->arg) == 1) - { - fprintf(stderr,"passphrase cancelled\n"); - free(cbinfo->arg) ; - cbinfo->arg=NULL ; - return 0 ; // ASSERT(0); - } - if (!cbinfo->cryptinfo.passphrase) - { - free(cbinfo->arg) ; - cbinfo->arg=NULL ; - fprintf(stderr,"can't get passphrase\n"); - return 0 ; // ASSERT(0); - } - free(cbinfo->arg) ; - cbinfo->arg=NULL ; - } - /* then it must be encrypted */ - secret=ops_decrypt_secret_key_from_data(cbinfo->cryptinfo.keydata,cbinfo->cryptinfo.passphrase); - - free(cbinfo->cryptinfo.passphrase) ; - cbinfo->cryptinfo.passphrase = NULL ; - - tag_to_use = OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD ; - } - - if(!secret) - return 0 ; - - *content->get_secret_key.secret_key=secret; - break; - - default: - // return callback_general(content_,cbinfo); - break; - } - - return OPS_RELEASE_MEMORY; -} - -char *ops_get_passphrase(void) - { -#ifndef __ANDROID__ - return ops_malloc_passphrase(getpass("Passphrase: ")); -#else // __ANDROID - // We should never get here on Android, getpass not supported. - abort(); -#endif // __ANDROID__ - } - -char *ops_malloc_passphrase(char *pp) - { - char *passphrase; - size_t n; - - n=strlen(pp); - passphrase=malloc(n+1); - strncpy(passphrase,pp,n+1); - - return passphrase; - } - -/** - \ingroup HighLevel_Callbacks - \brief Callback to use when you need to prompt user for passphrase - \param content_ - \param cbinfo -*/ -ops_parse_cb_return_t -callback_cmd_get_passphrase_from_cmdline(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) - { - ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content; - - OPS_USED(cbinfo); - -// ops_print_packet(content_); - - switch(content_->tag) - { - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - *(content->secret_key_passphrase.passphrase)=ops_get_passphrase(); - return OPS_KEEP_MEMORY; - break; - - default: - // return callback_general(content_,cbinfo); - break; - } - - return OPS_RELEASE_MEMORY; - } - -ops_boolean_t ops_reader_set_accumulate(ops_parse_info_t* pinfo, ops_boolean_t state) - { - pinfo->rinfo.accumulate=state; - return state; - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/readerwriter.h b/openpgpsdk/src/openpgpsdk/readerwriter.h deleted file mode 100644 index 6961bafef..000000000 --- a/openpgpsdk/src/openpgpsdk/readerwriter.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OPS_READERWRITER_H__ -#define __OPS_READERWRITER_H__ - -#include -#include - - -void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd); -void ops_reader_set_memory(ops_parse_info_t *pinfo,const void *buffer, - size_t length); - -// Do a sum mod 65536 of all bytes read (as needed for secret keys) -void ops_reader_push_sum16(ops_parse_info_t *pinfo); -unsigned short ops_reader_pop_sum16(ops_parse_info_t *pinfo); - -void ops_reader_push_se_ip_data(ops_parse_info_t *pinfo, ops_crypt_t *decrypt, - ops_region_t *region); -void ops_reader_pop_se_ip_data(ops_parse_info_t* pinfo); - -// -ops_boolean_t ops_write_mdc(const unsigned char *hashed, - ops_create_info_t* info); -ops_boolean_t ops_write_se_ip_pktset(const unsigned char *data, - const unsigned int len, - ops_crypt_t *crypt, - ops_create_info_t *info); -void ops_writer_push_encrypt_crypt(ops_create_info_t *cinfo, - ops_crypt_t *crypt); -void ops_writer_push_encrypt_se_ip(ops_create_info_t *cinfo, - const ops_keydata_t *pub_key); -// Secret Key checksum - -void ops_push_skey_checksum_writer(ops_create_info_t *cinfo, ops_secret_key_t *skey); -ops_boolean_t ops_pop_skey_checksum_writer(ops_create_info_t *cinfo); - - -// memory writing -void ops_setup_memory_write(ops_create_info_t **cinfo, ops_memory_t **mem, size_t bufsz); -void ops_teardown_memory_write(ops_create_info_t *cinfo, ops_memory_t *mem); - -// memory reading -void ops_setup_memory_read(ops_parse_info_t **pinfo, ops_memory_t *mem, - void* arg, - ops_parse_cb_return_t callback(const ops_parser_content_t *, ops_parse_cb_info_t *),ops_boolean_t accumulate); -void ops_teardown_memory_read(ops_parse_info_t *pinfo, ops_memory_t *mem); - -// file writing -int ops_setup_file_write(ops_create_info_t **cinfo, const char* filename, ops_boolean_t allow_overwrite); -void ops_teardown_file_write(ops_create_info_t *cinfo, int fd); - -// file appending -int ops_setup_file_append(ops_create_info_t **cinfo, const char* filename); -void ops_teardown_file_append(ops_create_info_t *cinfo, int fd); - -// file reading -int ops_setup_file_read(ops_parse_info_t **pinfo, const char *filename, void* arg, - ops_parse_cb_return_t callback(const ops_parser_content_t *, ops_parse_cb_info_t *), ops_boolean_t accumulate); -void ops_teardown_file_read(ops_parse_info_t *pinfo, int fd); - -ops_boolean_t ops_reader_set_accumulate(ops_parse_info_t* pinfo, ops_boolean_t state); - -// useful callbacks -ops_parse_cb_return_t -callback_literal_data(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo); -ops_parse_cb_return_t -callback_pk_session_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo); -ops_parse_cb_return_t -callback_cmd_get_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo); -ops_parse_cb_return_t -callback_cmd_get_passphrase_from_cmdline(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo); - -#endif /*OPS_READERWRITER_H__*/ diff --git a/openpgpsdk/src/openpgpsdk/signature.c b/openpgpsdk/src/openpgpsdk/signature.c deleted file mode 100644 index b62ebdb9f..000000000 --- a/openpgpsdk/src/openpgpsdk/signature.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh. - * The Contributors have asserted their moral rights under the - * UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -static int debug=0; -#define MAXBUF 1024 /*info); - sig->info=NULL; - free(sig); - } - -static unsigned char prefix_md5[]={ 0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86, - 0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00, - 0x04,0x10 }; - -static unsigned char prefix_sha1[]={ 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0E, - 0x03,0x02,0x1A,0x05,0x00,0x04,0x14 }; - -static unsigned char prefix_sha224[]={ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, - 0x00, 0x04, 0x1C }; - -static unsigned char prefix_sha256[]={ 0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86, - 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05, - 0x00,0x04,0x20 }; - -static unsigned char prefix_sha384[]={ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, - 0x00, 0x04, 0x30 }; - -static unsigned char prefix_sha512[]={ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, - 0x00, 0x04, 0x40 }; - -static unsigned char prefix_ripemd[]={ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, - 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; -/** - \ingroup Core_Create - implementation of EMSA-PKCS1-v1_5, as defined in OpenPGP RFC - \param M - \param mLen - \param hash_alg Hash algorithm to use - \param EM - \return ops_true if OK; else ops_false -*/ -ops_boolean_t encode_hash_buf(const unsigned char *M, size_t mLen, - const ops_hash_algorithm_t hash_alg, - unsigned char* EM) -{ - // implementation of EMSA-PKCS1-v1_5, as defined in OpenPGP RFC - - unsigned i; - int n; - ops_hash_t hash; - int hash_sz=0; - // int encoded_hash_sz=0; - int prefix_sz=0; - unsigned padding_sz=0; - unsigned encoded_msg_sz=0; - unsigned char* prefix=NULL; - - if(hash_alg != OPS_HASH_SHA1) - { - fprintf(stderr,"encode_hash_buf: unsupported hash algorithm %x. Sorry.",hash_alg) ; - return ops_false ; - } - - // 1. Apply hash function to M - - ops_hash_any(&hash, hash_alg); - hash.init(&hash); - hash.add(&hash, M, mLen); - - // \todo combine with rsa_sign - - // 2. Get hash prefix - - switch(hash_alg) - { - case OPS_HASH_SHA1: - prefix=prefix_sha1; - prefix_sz=sizeof prefix_sha1; - hash_sz=OPS_SHA1_HASH_SIZE; - // encoded_hash_sz=hash_sz+prefix_sz; - // \todo why is Ben using a PS size of 90 in rsa_sign? - // (keysize-hashsize-1-2) - padding_sz=90; - break; - - default: - return ops_false ; // according to the test at start, this should never happen, so no error handling is necessary. - } - - // \todo 3. Test for len being too short - - // 4 and 5. Generate PS and EM - - EM[0]=0x00; - EM[1]=0x01; - - for (i=0; ialgorithm) - { - case OPS_HASH_SHA1: hashsize=OPS_SHA1_HASH_SIZE+sizeof prefix_sha1; - hash_length=OPS_SHA1_HASH_SIZE ; - prefix = prefix_sha1; - plen = sizeof prefix_sha1 ; - break ; - - case OPS_HASH_SHA224: hashsize=OPS_SHA224_HASH_SIZE+sizeof prefix_sha224; - hash_length=OPS_SHA224_HASH_SIZE ; - prefix = prefix_sha224; - plen = sizeof prefix_sha224 ; - break ; - - case OPS_HASH_SHA256: hashsize=OPS_SHA256_HASH_SIZE+sizeof prefix_sha256; - hash_length=OPS_SHA256_HASH_SIZE ; - prefix = prefix_sha256; - plen = sizeof prefix_sha256 ; - break ; - - case OPS_HASH_SHA384: hashsize=OPS_SHA384_HASH_SIZE+sizeof prefix_sha384; - hash_length=OPS_SHA384_HASH_SIZE ; - prefix = prefix_sha384; - plen = sizeof prefix_sha384 ; - break ; - - case OPS_HASH_SHA512: hashsize=OPS_SHA512_HASH_SIZE+sizeof prefix_sha512; - hash_length=OPS_SHA512_HASH_SIZE ; - prefix = prefix_sha512; - plen = sizeof prefix_sha512 ; - break ; - - case OPS_HASH_MD5: fprintf(stderr,"(insecure) MD5+RSA signatures not supported in RSA sign") ; - return ops_false ; - - default: fprintf(stderr,"Hash algorithm %d not supported in RSA sign",hash->algorithm) ; - return ops_false ; - } - // XXX: we assume hash is sha-1 for now - - keysize=BN_num_bytes(rsa->n); - - if(keysize > sizeof hashbuf) - { - fprintf(stderr,"Keysize too large. limit is %lu, size was %u",sizeof(hashbuf), keysize) ; - return ops_false ; - } - if(10+hashsize > keysize) - { - fprintf(stderr,"10+hashsize > keysize. Can't sign!") ; - return ops_false ; - } - - hashbuf[0]=0; - hashbuf[1]=1; - if (debug) - printf("rsa_sign: PS is %d\n", keysize-hashsize-1-2); - for(n=2 ; n < keysize-hashsize-1 ; ++n) - hashbuf[n]=0xff; - hashbuf[n++]=0; - - memcpy(&hashbuf[n], prefix, plen); - n+=plen; - - t=hash->finish(hash, &hashbuf[n]); - - if(t != hash_length) - { - fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ; - return ops_false ; - } - - ops_write(&hashbuf[n], 2, opt); - - n+=t; - - if(n != keysize) - { - fprintf(stderr,"Size error in hashed data. can't sign.") ; - return ops_false ; - } - - t=ops_rsa_private_encrypt(sigbuf, hashbuf, keysize, srsa, rsa); - bn=BN_bin2bn(sigbuf, t, NULL); - ops_write_mpi(bn, opt); - BN_free(bn); - - return ops_true ; -} - -static ops_boolean_t dsa_sign(ops_hash_t *hash, const ops_dsa_public_key_t *dsa, - const ops_dsa_secret_key_t *sdsa, ops_create_info_t *cinfo) -{ - unsigned char hashbuf[8192]; - unsigned hashsize; - unsigned t; - - // hashsize must be "equal in size to the number of bits of q, - // the group generated by the DSA key's generator value - // 160/8 = 20 - - hashsize=20; - - // finalise hash - t=hash->finish(hash, &hashbuf[0]); - - if(t != 20) - { - fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ; - return ops_false ; - } - - ops_write(&hashbuf[0], 2, cinfo); - - // write signature to buf - DSA_SIG* dsasig; - dsasig=ops_dsa_sign(hashbuf, hashsize, sdsa, dsa); - - // convert and write the sig out to memory -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - ops_write_mpi(dsasig->r, cinfo); - ops_write_mpi(dsasig->s, cinfo); -#else - const BIGNUM *rr=NULL,*ss=NULL ; - - DSA_SIG_get0(dsasig,&rr,&ss) ; - - ops_write_mpi(rr, cinfo); - ops_write_mpi(ss, cinfo); -#endif - - DSA_SIG_free(dsasig); - - return ops_true ; -} - -static ops_boolean_t rsa_verify(ops_hash_algorithm_t type, - const unsigned char *hash, size_t hash_length, - const ops_rsa_signature_t *sig, - const ops_rsa_public_key_t *rsa) -{ - unsigned char sigbuf[8192]; - unsigned char hashbuf_from_sig[8192]; - unsigned n; - unsigned keysize; - unsigned char *prefix; - int plen; - - keysize=BN_num_bytes(rsa->n); - /* RSA key can't be bigger than 65535 bits, so... */ - - if(keysize > sizeof hashbuf_from_sig) - { - fprintf(stderr,"Can't verify signature: keysize too big.") ; - return ops_false ; - } - if((unsigned)BN_num_bits(sig->sig) > 8*sizeof sigbuf) - { - fprintf(stderr,"Can't verify signature: signature too big.") ; - return ops_false ; - } - BN_bn2bin(sig->sig, sigbuf); - - n=ops_rsa_public_decrypt(hashbuf_from_sig, sigbuf, BN_num_bytes(sig->sig), rsa); - int debug_len_decrypted=n; - - if(n != keysize) // obviously, this includes error returns - return ops_false; - - // XXX: why is there a leading 0? The first byte should be 1... - // XXX: because the decrypt should use keysize and not sigsize? - if(hashbuf_from_sig[0] != 0 || hashbuf_from_sig[1] != 1) - return ops_false; - - switch(type) - { - case OPS_HASH_MD5 : prefix=prefix_md5 ; plen=sizeof prefix_md5; break; - case OPS_HASH_SHA1 : prefix=prefix_sha1 ; plen=sizeof prefix_sha1; break; - case OPS_HASH_SHA224 : prefix=prefix_sha224 ; plen=sizeof prefix_sha224; break; - case OPS_HASH_SHA256 : prefix=prefix_sha256 ; plen=sizeof prefix_sha256; break; - case OPS_HASH_SHA384 : prefix=prefix_sha384 ; plen=sizeof prefix_sha384; break; - case OPS_HASH_SHA512 : prefix=prefix_sha512 ; plen=sizeof prefix_sha512; break; - case OPS_HASH_RIPEMD : prefix=prefix_ripemd ; plen=sizeof prefix_ripemd; break; - - default: - fprintf(stderr,"Warning: unhandled hash type in signature verification code: %d\n",type) ; - return ops_false ; - } - - if(keysize-plen-hash_length < 10) - return ops_false; - - for(n=2 ; n < keysize-plen-hash_length-1 ; ++n) - if(hashbuf_from_sig[n] != 0xff) - return ops_false; - - if(hashbuf_from_sig[n++] != 0) - return ops_false; - - if (debug) - { - int zz; - - printf("\n"); - printf("hashbuf_from_sig\n"); - for (zz=0; zzadd(hash, ops_memory_get_data(mem), l); - - ops_memory_free(mem); - } - -static void initialise_hash(ops_hash_t *hash, const ops_signature_t *sig) - { - ops_hash_any(hash, sig->info.hash_algorithm); - hash->init(hash); - } - -static void init_key_signature(ops_hash_t *hash, const ops_signature_t *sig, - const ops_public_key_t *key) - { - initialise_hash(hash, sig); - hash_add_key(hash, key); - } - -static void hash_add_trailer(ops_hash_t *hash, const ops_signature_t *sig, - const unsigned char *raw_packet) - { - if(sig->info.version == OPS_V4) - { - if(raw_packet) - hash->add(hash, raw_packet+sig->v4_hashed_data_start, - sig->info.v4_hashed_data_length); - ops_hash_add_int(hash, sig->info.version, 1); - ops_hash_add_int(hash, 0xff, 1); - ops_hash_add_int(hash, sig->info.v4_hashed_data_length, 4); - } - else - { - ops_hash_add_int(hash, sig->info.type, 1); - ops_hash_add_int(hash, sig->info.creation_time, 4); - } - } - -/** - \ingroup Core_Signature - \brief Checks a signature - \param hash Signature Hash to be checked - \param length Signature Length - \param sig The Signature to be checked - \param signer The signer's public key - \return ops_true if good; else ops_false -*/ -ops_boolean_t ops_check_signature(const unsigned char *hash, unsigned length, - const ops_signature_t *sig, - const ops_public_key_t *signer) -{ - ops_boolean_t ret; - - /* - printf(" hash="); - // hashout[0]=0; - hexdump(hash,length); - */ - - switch(sig->info.key_algorithm) - { - case OPS_PKA_DSA: - ret=ops_dsa_verify(hash, length, &sig->info.signature.dsa, - &signer->key.dsa); - /* fprintf(stderr,"Cannot verify DSA signature. skipping.\n") ; - ret = ops_false ; */ - break; - - case OPS_PKA_RSA: - ret=rsa_verify(sig->info.hash_algorithm, hash, length, - &sig->info.signature.rsa, &signer->key.rsa); - break; - - default: - fprintf(stderr,"Cannot verify signature. Unknown key signing algorithm %d. skipping.\n",sig->info.key_algorithm) ; - ret = ops_false ; - - } - - return ret; -} - -static ops_boolean_t hash_and_check_signature(ops_hash_t *hash, - const ops_signature_t *sig, - const ops_public_key_t *signer) - { - int n; - unsigned char hashout[OPS_MAX_HASH_SIZE]; - - n=hash->finish(hash, hashout); - - return ops_check_signature(hashout, n, sig, signer); - } - -static ops_boolean_t finalise_signature(ops_hash_t *hash, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet) - { - hash_add_trailer(hash, sig, raw_packet); - return hash_and_check_signature(hash, sig, signer); - } - -/** - * \ingroup Core_Signature - * - * \brief Verify a certification signature. - * - * \param key The public key that was signed. - * \param id The user ID that was signed - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return ops_true if OK; else ops_false - */ -ops_boolean_t -ops_check_user_id_certification_signature(const ops_public_key_t *key, - const ops_user_id_t *id, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet) - { - ops_hash_t hash; - size_t user_id_len=strlen((char *)id->user_id); - - init_key_signature(&hash, sig, key); - - if(sig->info.version == OPS_V4) - { - ops_hash_add_int(&hash, 0xb4, 1); - ops_hash_add_int(&hash, user_id_len, 4); - } - hash.add(&hash, id->user_id, user_id_len); - - return finalise_signature(&hash, sig, signer, raw_packet); - } - -/** - * \ingroup Core_Signature - * - * Verify a certification signature. - * - * \param key The public key that was signed. - * \param attribute The user attribute that was signed - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return ops_true if OK; else ops_false - */ -ops_boolean_t -ops_check_user_attribute_certification_signature(const ops_public_key_t *key, - const ops_user_attribute_t *attribute, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet) - { - ops_hash_t hash; - - init_key_signature(&hash, sig, key); - - if(sig->info.version == OPS_V4) - { - ops_hash_add_int(&hash, 0xd1, 1); - ops_hash_add_int(&hash, attribute->data.len, 4); - } - hash.add(&hash, attribute->data.contents, attribute->data.len); - - return finalise_signature(&hash, sig, signer, raw_packet); - } - -/** - * \ingroup Core_Signature - * - * Verify a subkey signature. - * - * \param key The public key whose subkey was signed. - * \param subkey The subkey of the public key that was signed. - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return ops_true if OK; else ops_false - */ -ops_boolean_t -ops_check_subkey_signature(const ops_public_key_t *key, - const ops_public_key_t *subkey, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet) - { - ops_hash_t hash; - - init_key_signature(&hash, sig, key); - hash_add_key(&hash, subkey); - - return finalise_signature(&hash, sig, signer, raw_packet); - } - -/** - * \ingroup Core_Signature - * - * Verify a direct signature. - * - * \param key The public key which was signed. - * \param sig The signature. - * \param signer The public key of the signer. - * \param raw_packet The raw signature packet. - * \return ops_true if OK; else ops_false - */ -ops_boolean_t -ops_check_direct_signature(const ops_public_key_t *key, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet) - { - ops_hash_t hash; - - init_key_signature(&hash, sig, key); - return finalise_signature(&hash, sig, signer, raw_packet); - } - -/** - * \ingroup Core_Signature - * - * Verify a signature on a hash (the hash will have already been fed - * the material that was being signed, for example signed cleartext). - * - * \param hash A hash structure of appropriate type that has been fed - * the material to be signed. This MUST NOT have been finalised. - * \param sig The signature to be verified. - * \param signer The public key of the signer. - * \return ops_true if OK; else ops_false - */ -ops_boolean_t -ops_check_hash_signature(ops_hash_t *hash, const ops_signature_t *sig, - const ops_public_key_t *signer) - { - if(sig->info.hash_algorithm != hash->algorithm) - return ops_false; - - return finalise_signature(hash, sig, signer, NULL); - } - -static void start_signature_in_mem(ops_create_signature_t *sig) - { - // since this has subpackets and stuff, we have to buffer the whole - // thing to get counts before writing. - sig->mem=ops_memory_new(); - ops_memory_init(sig->mem, 100); - ops_writer_set_memory(sig->info, sig->mem); - - // write nearly up to the first subpacket - ops_write_scalar(sig->sig.info.version, 1, sig->info); - ops_write_scalar(sig->sig.info.type, 1, sig->info); - ops_write_scalar(sig->sig.info.key_algorithm, 1, sig->info); - ops_write_scalar(sig->sig.info.hash_algorithm, 1, sig->info); - - // dummy hashed subpacket count - sig->hashed_count_offset=ops_memory_get_length(sig->mem); - ops_write_scalar(0, 2, sig->info); - } - -/** - * \ingroup Core_Signature - * - * ops_signature_start() creates a V4 public key signature with a SHA1 hash. - * - * \param sig The signature structure to initialise - * \param key The public key to be signed - * \param id The user ID being bound to the key - * \param type Signature type - */ -void ops_signature_start_key_signature(ops_create_signature_t *sig, - const ops_public_key_t *key, - const ops_user_id_t *id, - ops_sig_type_t type) - { - sig->info=ops_create_info_new(); - - // XXX: refactor with check (in several ways - check should probably - // use the buffered writer to construct packets (done), and also should - // share code for hash calculation) - sig->sig.info.version=OPS_V4; - sig->sig.info.hash_algorithm=OPS_HASH_SHA1; - sig->sig.info.key_algorithm=key->algorithm; - sig->sig.info.type=type; - - sig->hashed_data_length=-1; - - init_key_signature(&sig->hash, &sig->sig, key); - - ops_hash_add_int(&sig->hash, 0xb4, 1); - ops_hash_add_int(&sig->hash, strlen((char *)id->user_id), 4); - sig->hash.add(&sig->hash, id->user_id, strlen((char *)id->user_id)); - - start_signature_in_mem(sig); - } - -/** - * \ingroup Core_Signature - * - * Create a V4 public key signature over some cleartext. - * - * \param sig The signature structure to initialise - * \param id - * \param type - * \todo Expand description. Allow other hashes. - */ - -static void ops_signature_start_signature(ops_create_signature_t *sig, - const ops_secret_key_t *key, - const ops_hash_algorithm_t hash, - const ops_sig_type_t type) - { - sig->info=ops_create_info_new(); - - // XXX: refactor with check (in several ways - check should probably - // use the buffered writer to construct packets (done), and also should - // share code for hash calculation) - sig->sig.info.version=OPS_V4; - sig->sig.info.key_algorithm=key->public_key.algorithm; - sig->sig.info.hash_algorithm=hash; - sig->sig.info.type=type; - - sig->hashed_data_length=-1; - - if (debug) - { fprintf(stderr, "initialising hash for sig in mem\n"); } - initialise_hash(&sig->hash, &sig->sig); - start_signature_in_mem(sig); - } - -/** - * \ingroup Core_Signature - * \brief Setup to start a cleartext's signature - */ -void ops_signature_start_cleartext_signature(ops_create_signature_t *sig, - const ops_secret_key_t *key, - const ops_hash_algorithm_t hash, - const ops_sig_type_t type) - { - ops_signature_start_signature(sig, key, hash, type); - } - -/** - * \ingroup Core_Signature - * \brief Setup to start a message's signature - */ -void ops_signature_start_message_signature(ops_create_signature_t *sig, - const ops_secret_key_t *key, - const ops_hash_algorithm_t hash, - const ops_sig_type_t type) - { - ops_signature_start_signature(sig, key, hash, type); - } - -/** - * \ingroup Core_Signature - * - * Add plaintext data to a signature-to-be. - * - * \param sig The signature-to-be. - * \param buf The plaintext data. - * \param length The amount of plaintext data. - */ -void ops_signature_add_data(ops_create_signature_t *sig, const void *buf, - size_t length) - { - if (debug) - { fprintf(stderr, "ops_signature_add_data adds to hash\n"); } - sig->hash.add(&sig->hash, buf, length); - } - -/** - * \ingroup Core_Signature - * - * Mark the end of the hashed subpackets in the signature - * - * \param sig - */ - -ops_boolean_t ops_signature_hashed_subpackets_end(ops_create_signature_t *sig) - { - sig->hashed_data_length=ops_memory_get_length(sig->mem) - -sig->hashed_count_offset-2; - ops_memory_place_int(sig->mem, sig->hashed_count_offset, - sig->hashed_data_length, 2); - // dummy unhashed subpacket count - sig->unhashed_count_offset=ops_memory_get_length(sig->mem); - return ops_write_scalar(0, 2, sig->info); - } - -/** - * \ingroup Core_Signature - * - * Write out a signature - * - * \param sig - * \param key - * \param skey - * \param info - * - */ - -ops_boolean_t ops_write_signature(ops_create_signature_t *sig, - const ops_public_key_t *key, - const ops_secret_key_t *skey, - ops_create_info_t *info) -{ - ops_boolean_t rtn=ops_false; - size_t l=ops_memory_get_length(sig->mem); - - // check key not decrypted - switch (skey->public_key.algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - if(skey->key.rsa.d == NULL) - { - fprintf(stderr, "Malformed secret key when signing (rsa.d = 0). Can't sign.\n") ; - return ops_false ; - } - break; - - case OPS_PKA_DSA: - if(skey->key.dsa.x == NULL) - { - fprintf(stderr, "Malformed secret key when signing (dsa.x = 0). Can't sign.\n") ; - return ops_false ; - } - break; - - default: - fprintf(stderr, "Unsupported algorithm %d when signing. Sorry.\n", skey->public_key.algorithm); - return ops_false ; - } - - if(sig->hashed_data_length == (unsigned)-1) - { - fprintf(stderr, "Hashed data not initialized properly when signing. Sorry.\n") ; - return ops_false ; - } - - ops_memory_place_int(sig->mem, sig->unhashed_count_offset, - l-sig->unhashed_count_offset-2, 2); - - // add the packet from version number to end of hashed subpackets - - if (debug) - { fprintf(stderr, "--- Adding packet to hash from version number to" - " hashed subpkts\n"); } - - sig->hash.add(&sig->hash, ops_memory_get_data(sig->mem), - sig->unhashed_count_offset); - - // add final trailer - ops_hash_add_int(&sig->hash, sig->sig.info.version, 1); - ops_hash_add_int(&sig->hash, 0xff, 1); - // +6 for version, type, pk alg, hash alg, hashed subpacket length - ops_hash_add_int(&sig->hash, sig->hashed_data_length+6, 4); - - if (debug) - { fprintf(stderr, "--- Finished adding packet to hash from version" - " number to hashed subpkts\n"); } - - // XXX: technically, we could figure out how big the signature is - // and write it directly to the output instead of via memory. - switch(skey->public_key.algorithm) - { - case OPS_PKA_RSA: - case OPS_PKA_RSA_ENCRYPT_ONLY: - case OPS_PKA_RSA_SIGN_ONLY: - if(!rsa_sign(&sig->hash, &key->key.rsa, &skey->key.rsa, sig->info)) - { - fprintf(stderr, "error in rsa_sign. Can't produce signature\n") ; - return ops_false; - } - break; - - case OPS_PKA_DSA: - if(!dsa_sign(&sig->hash, &key->key.dsa, &skey->key.dsa, sig->info)) - { - fprintf(stderr, "error in dsa_sign. Can't produce signature\n") ; - return ops_false; - } - break; - - default: - fprintf(stderr, "Unsupported algorithm %d in signature\n", skey->public_key.algorithm); - return ops_false ; - } - - rtn=ops_write_ptag(OPS_PTAG_CT_SIGNATURE, info); - if (rtn) - { - l=ops_memory_get_length(sig->mem); - rtn = ops_write_length(l, info) - && ops_write(ops_memory_get_data(sig->mem), l, info); - } - - ops_memory_free(sig->mem); - - if (!rtn) - OPS_ERROR(&info->errors, OPS_E_W, "Cannot write signature"); - return rtn; -} - -/** - * \ingroup Core_Signature - * - * ops_signature_add_creation_time() adds a creation time to the signature. - * - * \param sig - * \param when - */ -ops_boolean_t ops_signature_add_creation_time(ops_create_signature_t *sig, - time_t when) - { - return ops_write_ss_header(5, OPS_PTAG_SS_CREATION_TIME, sig->info) - && ops_write_scalar(when, 4, sig->info); - } - -/** - * \ingroup Core_Signature - * - * Adds issuer's key ID to the signature - * - * \param sig - * \param keyid - */ - -ops_boolean_t -ops_signature_add_issuer_key_id(ops_create_signature_t *sig, - const unsigned char keyid[OPS_KEY_ID_SIZE]) - { - return ops_write_ss_header(OPS_KEY_ID_SIZE+1, OPS_PTAG_SS_ISSUER_KEY_ID, - sig->info) - && ops_write(keyid, OPS_KEY_ID_SIZE, sig->info); - } - -/** - * \ingroup Core_Signature - * - * Adds primary user ID to the signature - * - * \param sig - * \param primary - */ -void ops_signature_add_primary_user_id(ops_create_signature_t *sig, - ops_boolean_t primary) - { - ops_write_ss_header(2, OPS_PTAG_SS_PRIMARY_USER_ID, sig->info); - ops_write_scalar(primary, 1, sig->info); - } - -/** - * \ingroup Core_Signature - * - * Get the hash structure in use for the signature. - * - * \param sig The signature structure. - * \return The hash structure. - */ -ops_hash_t *ops_signature_get_hash(ops_create_signature_t *sig) - { return &sig->hash; } - -static int open_output_file(ops_create_info_t **cinfo, - const char* input_filename, - const char* output_filename, - const ops_boolean_t use_armour, - const ops_boolean_t overwrite) - { - int fd_out; - - // setup output file - - if (output_filename) - fd_out=ops_setup_file_write(cinfo, output_filename, overwrite); - else - { - char *myfilename=NULL; - unsigned filenamelen=strlen(input_filename)+4+1; - myfilename=ops_mallocz(filenamelen); - if (use_armour) - snprintf(myfilename, filenamelen, "%s.asc", input_filename); - else - snprintf(myfilename, filenamelen, "%s.gpg", input_filename); - fd_out=ops_setup_file_write(cinfo, myfilename, overwrite); - free(myfilename); - } - - return fd_out; - } - -/** - \ingroup HighLevel_Sign - \brief Sign a file with a Cleartext Signature - \param input_filename Name of file to be signed - \param output_filename Filename to be created. If NULL, filename will be constructed from the input_filename. - \param skey Secret Key to sign with - \param overwrite Allow output file to be overwritten, if set - \return ops_true if OK, else ops_false - - Example code: - \code - void example(const ops_secret_key_t *skey, ops_boolean_t overwrite) - { - if (ops_sign_file_as_cleartext("mytestfile.txt",NULL,skey,overwrite)==ops_true) - printf("OK"); - else - printf("ERR"); - } - \endcode -*/ -ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, - const char* output_filename, - const ops_secret_key_t *skey, - const ops_boolean_t overwrite) -{ - // \todo allow choice of hash algorithams - // enforce use of SHA1 for now - - unsigned char keyid[OPS_KEY_ID_SIZE]; - ops_create_signature_t *sig=NULL; - - int fd_in=0; - int fd_out=0; - ops_create_info_t *cinfo=NULL; - unsigned char buf[MAXBUF]; - //int flags=0; - ops_boolean_t rtn=ops_false; - ops_boolean_t use_armour=ops_true; - - // open file to sign - - fd_in=ops_open(input_filename, O_RDONLY | O_BINARY, 0); - - if(fd_in < 0) - { - return ops_false; - } - - // set up output file - - fd_out=open_output_file(&cinfo, input_filename, output_filename, use_armour, - overwrite); - - if (fd_out < 0) - { - close(fd_in); - return ops_false; - } - - // set up signature - sig=ops_create_signature_new(); - if (!sig) - { - close (fd_in); - ops_teardown_file_write(cinfo, fd_out); - return ops_false; - } - - // \todo could add more error detection here - ops_signature_start_cleartext_signature(sig, skey, OPS_HASH_SHA1, OPS_SIG_BINARY); - - if (!ops_writer_push_clearsigned(cinfo, sig)) - return ops_false; - - // Do the signing - - for (;;) - { - int n=0; - - n=read(fd_in, buf, sizeof(buf)); - if (!n) - break; - - if(n < 0) - { - fprintf(stderr, "Read error in ops_sign_file_as_cleartext\n"); - close(fd_in) ; - ops_teardown_file_write(cinfo, fd_out); - return ops_false ; - } - ops_write(buf, n, cinfo); - } - close(fd_in); - - // add signature with subpackets: - // - creation time - // - key id - rtn = ops_writer_switch_to_armoured_signature(cinfo) - && ops_signature_add_creation_time(sig, time(NULL)); - - if (!rtn) - { - ops_teardown_file_write(cinfo, fd_out); - return ops_false; - } - - ops_keyid(keyid, &skey->public_key); - - rtn = ops_signature_add_issuer_key_id(sig, keyid) - && ops_signature_hashed_subpackets_end(sig) - && ops_write_signature(sig, &skey->public_key, skey, cinfo); - - if (!rtn) - OPS_ERROR(&cinfo->errors, OPS_E_W, "Cannot sign file as cleartext"); - - // we can't get errors in cinfo->errors while closing - // because ops_teardown_file_write frees everything - // it seems that writer finalisers do not report errors anyway - // and ops_teardown_file_write does not have an return value, so we could not bubble something up - ops_teardown_file_write(cinfo, fd_out); - - return rtn; -} - - -/** - * \ingroup HighLevel_Sign - * \brief Sign a buffer with a Cleartext signature - * \param cleartext Text to be signed - * \param len Length of text - * \param signed_cleartext ops_memory_t struct in which to write the signed cleartext - * \param skey Secret key with which to sign the cleartext - * \return ops_true if OK; else ops_false - - * \note It is the calling function's responsibility to free signed_cleartext - * \note signed_cleartext should be a NULL pointer when passed in - - Example code: - \code - void example(const ops_secret_key_t *skey) - { - ops_memory_t* mem=NULL; - const char* buf="Some example text"; - size_t len=strlen(buf); - if (ops_sign_buf_as_cleartext(buf,len, &mem, skey)==ops_true) - printf("OK"); - else - printf("ERR"); - // free signed cleartext after use - ops_memory_free(mem); - } - \endcode - */ -ops_boolean_t ops_sign_buf_as_cleartext(const char* cleartext, const size_t len, - ops_memory_t** signed_cleartext, - const ops_secret_key_t *skey) -{ - ops_boolean_t rtn=ops_false; - - // \todo allow choice of hash algorithams - // enforce use of SHA1 for now - - unsigned char keyid[OPS_KEY_ID_SIZE]; - ops_create_signature_t *sig=NULL; - - ops_create_info_t *cinfo=NULL; - - if(*signed_cleartext != NULL) - { - fprintf(stderr,"ops_sign_buf_as_cleartext: error. Variable signed_cleartext should point to NULL.\n") ; - return ops_false ; - } - - // set up signature - sig=ops_create_signature_new(); - if (!sig) - return ops_false; - - // \todo could add more error detection here - ops_signature_start_cleartext_signature(sig, skey, OPS_HASH_SHA1, OPS_SIG_BINARY); - - // set up output file - ops_setup_memory_write(&cinfo, signed_cleartext, len); - - // Do the signing - // add signature with subpackets: - // - creation time - // - key id - rtn = ops_writer_push_clearsigned(cinfo, sig) - && ops_write(cleartext, len, cinfo) - && ops_writer_switch_to_armoured_signature(cinfo) - && ops_signature_add_creation_time(sig, time(NULL)); - - if (!rtn) - return ops_false; - - ops_keyid(keyid, &skey->public_key); - - rtn = ops_signature_add_issuer_key_id(sig, keyid) - && ops_signature_hashed_subpackets_end(sig) - && ops_write_signature(sig, &skey->public_key, skey, cinfo) - && ops_writer_close(cinfo); - - // Note: the calling function must free signed_cleartext - ops_create_info_delete(cinfo); - - return rtn; -} - -/** -\ingroup HighLevel_Sign -\brief Sign a file -\param input_filename Input filename -\param output_filename Output filename. If NULL, a name is constructed from the input filename. -\param skey Secret Key to use for signing -\param use_armour Write armoured text, if set. -\param overwrite May overwrite existing file, if set. -\return ops_true if OK; else ops_false; - -Example code: -\code -void example(const ops_secret_key_t *skey) -{ - const char* filename="mytestfile"; - const ops_boolean_t use_armour=ops_false; - const ops_boolean_t overwrite=ops_false; - if (ops_sign_file(filename, NULL, skey, use_armour, overwrite)==ops_true) - printf("OK"); - else - printf("ERR"); -} -\endcode -*/ -ops_boolean_t ops_sign_file(const char* input_filename, - const char* output_filename, - const ops_secret_key_t *skey, - const ops_boolean_t use_armour, - const ops_boolean_t overwrite) - { - // \todo allow choice of hash algorithams - // enforce use of SHA1 for now - - unsigned char keyid[OPS_KEY_ID_SIZE]; - ops_create_signature_t *sig=NULL; - - int fd_out=0; - ops_create_info_t *cinfo=NULL; - - ops_hash_algorithm_t hash_alg=OPS_HASH_SHA1; - ops_sig_type_t sig_type=OPS_SIG_BINARY; - - ops_memory_t* mem_buf=NULL; - ops_hash_t* hash=NULL; - - // read input file into buf - - int errnum; - mem_buf=ops_write_mem_from_file(input_filename, &errnum); - if (errnum) - return ops_false; - - // setup output file - - fd_out=open_output_file(&cinfo, input_filename, output_filename, use_armour, - overwrite); - - if (fd_out < 0) - { - ops_memory_free(mem_buf); - return ops_false; - } - - // set up signature - sig=ops_create_signature_new(); - ops_signature_start_message_signature(sig, skey, hash_alg, sig_type); - - // set armoured/not armoured here - if (use_armour) - ops_writer_push_armoured_message(cinfo); - - if (debug) - { fprintf(stderr, "** Writing out one pass sig\n"); } - - // write one_pass_sig - ops_write_one_pass_sig(skey, hash_alg, sig_type, cinfo); - - // hash file contents - hash=ops_signature_get_hash(sig); - hash->add(hash, ops_memory_get_data(mem_buf), - ops_memory_get_length(mem_buf)); - - // output file contents as Literal Data packet - - if (debug) - fprintf(stderr,"** Writing out data now\n"); - - ops_write_literal_data_from_buf(ops_memory_get_data(mem_buf), - ops_memory_get_length(mem_buf), - OPS_LDT_BINARY, cinfo); - - if (debug) - fprintf(stderr, "** After Writing out data now\n"); - - // add subpackets to signature - // - creation time - // - key id - - ops_signature_add_creation_time(sig, time(NULL)); - - ops_keyid(keyid, &skey->public_key); - ops_signature_add_issuer_key_id(sig, keyid); - - ops_signature_hashed_subpackets_end(sig); - - // write out sig - ops_write_signature(sig, &skey->public_key, skey, cinfo); - - ops_teardown_file_write(cinfo, fd_out); - - // tidy up - ops_create_signature_delete(sig); - ops_memory_free(mem_buf); - - return ops_true; - } - -/** -\ingroup HighLevel_Sign -\brief Signs a buffer -\param input Input text to be signed -\param input_len Length of input text -\param sig_type Signature type -\param skey Secret Key -\param use_armour Write armoured text, if set -\param include_data Includes the signed data in the output message. If not, creates a detached signature. -\return New ops_memory_t struct containing signed text -\note It is the caller's responsibility to call ops_memory_free(me) - -Example Code: -\code -void example(const ops_secret_key_t *skey) -{ - const char* buf="Some example text"; - const size_t len=strlen(buf); - const ops_boolean_t use_armour=ops_true; - - ops_memory_t* mem=NULL; - - mem=ops_sign_buf(buf,len,OPS_SIG_BINARY,skey,use_armour); - if (mem) - { - printf ("OK"); - ops_memory_free(mem); - } - else - { - printf("ERR"); - } -} -\endcode -*/ -ops_memory_t* ops_sign_buf(const void* input, const size_t input_len, - const ops_sig_type_t sig_type, - const ops_hash_algorithm_t hash_algorithm, - const ops_secret_key_t *skey, - const ops_boolean_t use_armour, - ops_boolean_t include_data, - ops_boolean_t include_creation_time, - ops_boolean_t include_key_id) - { - // \todo allow choice of hash algorithams - // enforce use of SHA1 for now - - unsigned char keyid[OPS_KEY_ID_SIZE]; - ops_create_signature_t *sig=NULL; - - ops_create_info_t *cinfo=NULL; - ops_memory_t *mem=ops_memory_new(); - - ops_hash_algorithm_t hash_alg=hash_algorithm ; - ops_literal_data_type_t ld_type; - ops_hash_t* hash=NULL; - - // setup literal data packet type - if (sig_type == OPS_SIG_BINARY) - ld_type=OPS_LDT_BINARY; - else - ld_type=OPS_LDT_TEXT; - - // set up signature - sig=ops_create_signature_new(); - ops_signature_start_message_signature(sig, skey, hash_alg, sig_type); - - // setup writer - ops_setup_memory_write(&cinfo, &mem, input_len); - - // set armoured/not armoured here - if (use_armour) - ops_writer_push_armoured_message(cinfo); - - if (debug) - fprintf(stderr, "** Writing out one pass sig\n"); - - // write one_pass_sig - if(include_data) - ops_write_one_pass_sig(skey, hash_alg, sig_type, cinfo); - - // hash file contents - hash=ops_signature_get_hash(sig); - hash->add(hash, input, input_len); - - // output file contents as Literal Data packet - - if (debug) - fprintf(stderr,"** Writing out data now\n"); - - if(include_data) - ops_write_literal_data_from_buf(input, input_len, ld_type, cinfo); - - if (debug) - fprintf(stderr,"** After Writing out data now\n"); - - // add subpackets to signature - // - creation time - // - key id - - if(include_creation_time) - ops_signature_add_creation_time(sig, time(NULL)); - - if(include_key_id) - { - ops_keyid(keyid, &skey->public_key); - ops_signature_add_issuer_key_id(sig, keyid); - } - - ops_signature_hashed_subpackets_end(sig); - - // write out sig - ops_write_signature(sig, &skey->public_key, skey, cinfo); - - // tidy up - ops_writer_close(cinfo); - free(cinfo) ; - ops_create_signature_delete(sig); - - return mem; - } - -typedef struct { - ops_create_signature_t *signature; - const ops_secret_key_t *skey; - ops_hash_algorithm_t hash_alg; - ops_sig_type_t sig_type; -} signature_arg_t; - -static ops_boolean_t stream_signature_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - signature_arg_t* arg = ops_writer_get_arg(winfo); - // Add the input data to the hash. At the end, we will use the hash - // to generate a signature packet. - ops_hash_t* hash = ops_signature_get_hash(arg->signature); - hash->add(hash, src, length); - - return ops_stacked_write(src, length, errors, winfo); - } - -static ops_boolean_t stream_signature_write_trailer(ops_create_info_t *cinfo, - void *data) - { - signature_arg_t* arg = data; - unsigned char keyid[OPS_KEY_ID_SIZE]; - - // add subpackets to signature - // - creation time - // - key id - ops_signature_add_creation_time(arg->signature,time(NULL)); - ops_keyid(keyid, &arg->skey->public_key); - ops_signature_add_issuer_key_id(arg->signature, keyid); - ops_signature_hashed_subpackets_end(arg->signature); - - // write out signature - return ops_write_signature(arg->signature, &arg->skey->public_key, - arg->skey, cinfo); - } - -static void stream_signature_destroyer(ops_writer_info_t *winfo) - { - signature_arg_t* arg = ops_writer_get_arg(winfo); - ops_create_signature_delete(arg->signature); - free(arg); - } - -/** -\ingroup Core_WritePackets -\brief Pushes a signed writer onto the stack. - -Data written will be encoded as a onepass signature packet, followed -by a literal packet, followed by a signature packet. Once this writer -has been added to the stack, cleartext can be written straight to the -output, and it will be encoded as a literal packet and signed. - -\param cinfo Write settings -\param sig_type the type of input to be signed (text or binary) -\param skey the key used to sign the stream. -\return false if the initial onepass packet could not be created. -*/ -ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo, - const ops_sig_type_t sig_type, - const ops_secret_key_t *skey) - { - // \todo allow choice of hash algorithams - // enforce use of SHA1 for now - - // Create arg to be used with this writer - // Remember to free this in the destroyer - signature_arg_t *signature_arg = ops_mallocz(sizeof *signature_arg); - signature_arg->signature = ops_create_signature_new(); - signature_arg->hash_alg = OPS_HASH_SHA1; - signature_arg->skey = skey; - signature_arg->sig_type = sig_type; - ops_signature_start_message_signature(signature_arg->signature, - signature_arg->skey, - signature_arg->hash_alg, - signature_arg->sig_type); - - if (!ops_write_one_pass_sig(signature_arg->skey, - signature_arg->hash_alg, - signature_arg->sig_type, - cinfo)) - return ops_false; - - ops_writer_push_partial_with_trailer(0, cinfo, OPS_PTAG_CT_LITERAL_DATA, - write_literal_header, NULL, - stream_signature_write_trailer, - signature_arg); - // And push writer on stack - ops_writer_push(cinfo, stream_signature_writer, NULL, - stream_signature_destroyer,signature_arg); - return ops_true; - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/signature.h b/openpgpsdk/src/openpgpsdk/signature.h deleted file mode 100644 index eb87d0ee5..000000000 --- a/openpgpsdk/src/openpgpsdk/signature.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_SIGNATURE_H -#define OPS_SIGNATURE_H - -#include "packet.h" -#include "util.h" -#include "create.h" - -typedef struct ops_create_signature ops_create_signature_t; - -ops_create_signature_t *ops_create_signature_new(void); -void ops_create_signature_delete(ops_create_signature_t *sig); - -ops_boolean_t -ops_check_user_id_certification_signature(const ops_public_key_t *key, - const ops_user_id_t *id, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet); -ops_boolean_t -ops_check_user_attribute_certification_signature(const ops_public_key_t *key, - const ops_user_attribute_t *attribute, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet); -ops_boolean_t -ops_check_subkey_signature(const ops_public_key_t *key, - const ops_public_key_t *subkey, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet); -ops_boolean_t -ops_check_direct_signature(const ops_public_key_t *key, - const ops_signature_t *sig, - const ops_public_key_t *signer, - const unsigned char *raw_packet); -ops_boolean_t -ops_check_hash_signature(ops_hash_t *hash, - const ops_signature_t *sig, - const ops_public_key_t *signer); -void ops_signature_start_key_signature(ops_create_signature_t *sig, - const ops_public_key_t *key, - const ops_user_id_t *id, - ops_sig_type_t type); -void ops_signature_start_cleartext_signature(ops_create_signature_t *sig, - const ops_secret_key_t *key, - const ops_hash_algorithm_t hash, - const ops_sig_type_t type); -void ops_signature_start_message_signature(ops_create_signature_t *sig, - const ops_secret_key_t *key, - const ops_hash_algorithm_t hash, - const ops_sig_type_t type); - -void ops_signature_add_data(ops_create_signature_t *sig,const void *buf, - size_t length); -ops_hash_t *ops_signature_get_hash(ops_create_signature_t *sig); -ops_boolean_t ops_signature_hashed_subpackets_end(ops_create_signature_t *sig); -ops_boolean_t ops_write_signature(ops_create_signature_t *sig,const ops_public_key_t *key, - const ops_secret_key_t *skey, ops_create_info_t *opt); -ops_boolean_t ops_signature_add_creation_time(ops_create_signature_t *sig,time_t when); -ops_boolean_t ops_signature_add_issuer_key_id(ops_create_signature_t *sig, - const unsigned char keyid[OPS_KEY_ID_SIZE]); -void ops_signature_add_primary_user_id(ops_create_signature_t *sig, - ops_boolean_t primary); - -// Standard Interface -ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t overwrite); -ops_boolean_t ops_sign_buf_as_cleartext(const char* input, const size_t len, ops_memory_t** output, const ops_secret_key_t *skey); -ops_boolean_t ops_sign_file(const char* input_filename, const char* output_filename, const ops_secret_key_t *skey, const ops_boolean_t use_armour, const ops_boolean_t overwrite); -ops_memory_t * ops_sign_buf(const void* input, const size_t input_len, const ops_sig_type_t sig_type, const ops_hash_algorithm_t hash_algorithm, const ops_secret_key_t *skey, const ops_boolean_t use_armour, ops_boolean_t include_data, ops_boolean_t include_creation_time, ops_boolean_t include_key_id); -ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo, const ops_sig_type_t sig_type, const ops_secret_key_t *skey); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/std_print.h b/openpgpsdk/src/openpgpsdk/std_print.h deleted file mode 100644 index f6ae7dba1..000000000 --- a/openpgpsdk/src/openpgpsdk/std_print.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_STD_PRINT_H -#define OPS_STD_PRINT_H - -#include "openpgpsdk/packet.h" -#include "openpgpsdk/packet-parse.h" -#include "openpgpsdk/keyring.h" - -void print_bn( const char *name, - const BIGNUM *bn); -void ops_print_pk_session_key(ops_content_tag_t tag, - const ops_pk_session_key_t *key); -void ops_print_public_keydata(const ops_keydata_t *key); - -void ops_print_public_keydata_verbose(const ops_keydata_t *key); -void ops_print_public_key(const ops_public_key_t *pkey); - -void ops_print_secret_keydata(const ops_keydata_t *key); -void ops_print_secret_keydata_verbose(const ops_keydata_t *key); -//void ops_print_secret_key(const ops_content_tag_t type, const ops_secret_key_t* skey); -int ops_print_packet(const ops_parser_content_t *content_); -void ops_list_packets(char *filename, ops_boolean_t armour, ops_keyring_t* pubring, ops_parse_cb_t* cb_get_passphrase); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/streamwriter.h b/openpgpsdk/src/openpgpsdk/streamwriter.h deleted file mode 100644 index 70f77990d..000000000 --- a/openpgpsdk/src/openpgpsdk/streamwriter.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OPS_STREAMWRITER_H__ -#define __OPS_STREAMWRITER_H__ - -#include - -void ops_writer_push_stream_encrypt_se_ip(ops_create_info_t *cinfo, - const ops_keydata_t *pub_key); - -#endif /*__OPS_STREAMWRITER_H__*/ diff --git a/openpgpsdk/src/openpgpsdk/symmetric.c b/openpgpsdk/src/openpgpsdk/symmetric.c deleted file mode 100644 index 30dc0b74b..000000000 --- a/openpgpsdk/src/openpgpsdk/symmetric.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#ifndef OPENSSL_NO_IDEA -# include -#endif -#include -#ifndef OPENSSL_NO_CAMELLIA -# include -#endif -#include -#include "parse_local.h" - -#include -#include - -//static int debug=0; - -#ifndef ATTRIBUTE_UNUSED - -#ifndef WIN32 -#define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -#else -#define ATTRIBUTE_UNUSED -#endif // #ifndef WIN32 - -#endif /* ATTRIBUTE_UNUSED */ - -static void std_set_iv(ops_crypt_t *crypt,const unsigned char *iv) - { - memcpy(crypt->iv,iv,crypt->blocksize); - crypt->num=0; - } - -static void std_set_key(ops_crypt_t *crypt,const unsigned char *key) - { memcpy(crypt->key,key,crypt->keysize); } - -static void std_resync(ops_crypt_t *decrypt) - { - if(decrypt->num == decrypt->blocksize) - return; - - memmove(decrypt->civ+decrypt->blocksize-decrypt->num,decrypt->civ, - decrypt->num); - memcpy(decrypt->civ,decrypt->siv+decrypt->num, - decrypt->blocksize-decrypt->num); - decrypt->num=0; - } - -static void std_finish(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - { - free(crypt->encrypt_key); - crypt->encrypt_key=NULL; - } - if (crypt->decrypt_key) - { - free(crypt->decrypt_key); - crypt->decrypt_key=NULL; - } - } - -static void cast5_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(CAST_KEY)); - CAST_set_key(crypt->encrypt_key,crypt->keysize,crypt->key); - crypt->decrypt_key=malloc(sizeof(CAST_KEY)); - CAST_set_key(crypt->decrypt_key,crypt->keysize,crypt->key); - } - -static void cast5_block_encrypt(ops_crypt_t *crypt,void *out,const void *in) - { CAST_ecb_encrypt(in,out,crypt->encrypt_key,CAST_ENCRYPT); } - -static void cast5_block_decrypt(ops_crypt_t *crypt,void *out,const void *in) - { CAST_ecb_encrypt(in,out,crypt->encrypt_key,CAST_DECRYPT); } - -static void cast5_cfb_encrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - CAST_cfb64_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - CAST_ENCRYPT); - } - -static void cast5_cfb_decrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - CAST_cfb64_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - CAST_DECRYPT); - } - -#define TRAILER "","","","",0,NULL,NULL - -static ops_crypt_t cast5= - { - OPS_SA_CAST5, - CAST_BLOCK, - CAST_KEY_LENGTH, - std_set_iv, - std_set_key, - cast5_init, - std_resync, - cast5_block_encrypt, - cast5_block_decrypt, - cast5_cfb_encrypt, - cast5_cfb_decrypt, - std_finish, - TRAILER - }; - -#ifndef OPENSSL_NO_IDEA -static void idea_init(ops_crypt_t *crypt) - { - assert(crypt->keysize == IDEA_KEY_LENGTH); - - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(IDEA_KEY_SCHEDULE)); - - // note that we don't invert the key when decrypting for CFB mode - idea_set_encrypt_key(crypt->key,crypt->encrypt_key); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(IDEA_KEY_SCHEDULE)); - - idea_set_decrypt_key(crypt->encrypt_key,crypt->decrypt_key); - } - -static void idea_block_encrypt(ops_crypt_t *crypt,void *out,const void *in) - { idea_ecb_encrypt(in,out,crypt->encrypt_key); } - -static void idea_block_decrypt(ops_crypt_t *crypt,void *out,const void *in) - { idea_ecb_encrypt(in,out,crypt->decrypt_key); } - -static void idea_cfb_encrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - idea_cfb64_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - CAST_ENCRYPT); - } - -static void idea_cfb_decrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - idea_cfb64_encrypt(in,out,count, - crypt->decrypt_key, crypt->iv, (int *)&crypt->num, - CAST_DECRYPT); - } - -static const ops_crypt_t idea= - { - OPS_SA_IDEA, - IDEA_BLOCK, - IDEA_KEY_LENGTH, - std_set_iv, - std_set_key, - idea_init, - std_resync, - idea_block_encrypt, - idea_block_decrypt, - idea_cfb_encrypt, - idea_cfb_decrypt, - std_finish, - TRAILER - }; -#endif /* OPENSSL_NO_IDEA */ - -// AES with 128-bit key (AES) - -#define KEYBITS_AES128 128 - -static void aes128_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(AES_KEY)); - if (AES_set_encrypt_key(crypt->key,KEYBITS_AES128,crypt->encrypt_key)) - fprintf(stderr,"aes128_init: Error setting encrypt_key\n"); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(AES_KEY)); - if (AES_set_decrypt_key(crypt->key,KEYBITS_AES128,crypt->decrypt_key)) - fprintf(stderr,"aes128_init: Error setting decrypt_key\n"); - } - -static void aes_block_encrypt(ops_crypt_t *crypt,void *out,const void *in) - { AES_encrypt(in,out,crypt->encrypt_key); } - -static void aes_block_decrypt(ops_crypt_t *crypt,void *out,const void *in) - { AES_decrypt(in,out,crypt->decrypt_key); } - -static void aes_cfb_encrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - AES_cfb128_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - AES_ENCRYPT); - } - -static void aes_cfb_decrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - AES_cfb128_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - AES_DECRYPT); - } - -static const ops_crypt_t aes128= - { - OPS_SA_AES_128, - AES_BLOCK_SIZE, - KEYBITS_AES128/8, - std_set_iv, - std_set_key, - aes128_init, - std_resync, - aes_block_encrypt, - aes_block_decrypt, - aes_cfb_encrypt, - aes_cfb_decrypt, - std_finish, - TRAILER - }; - -// AES with 256-bit key - -#define KEYBITS_AES256 256 - -static void aes256_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(AES_KEY)); - if (AES_set_encrypt_key(crypt->key,KEYBITS_AES256,crypt->encrypt_key)) - fprintf(stderr,"aes256_init: Error setting encrypt_key\n"); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(AES_KEY)); - if (AES_set_decrypt_key(crypt->key,KEYBITS_AES256,crypt->decrypt_key)) - fprintf(stderr,"aes256_init: Error setting decrypt_key\n"); - } - -static const ops_crypt_t aes256= - { - OPS_SA_AES_256, - AES_BLOCK_SIZE, - KEYBITS_AES256/8, - std_set_iv, - std_set_key, - aes256_init, - std_resync, - aes_block_encrypt, - aes_block_decrypt, - aes_cfb_encrypt, - aes_cfb_decrypt, - std_finish, - TRAILER - }; - -#ifndef OPENSSL_NO_CAMELLIA - -// CAMELLIA with 128-bit key - -#define KEYBITS_CAMELLIA128 128 - -static void camellia128_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA128,crypt->encrypt_key)) - fprintf(stderr,"camellia128_init: Error setting encrypt_key\n"); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA128,crypt->decrypt_key)) - fprintf(stderr,"camellia128_init: Error setting decrypt_key\n"); - } - -static void camellia_block_encrypt(ops_crypt_t *crypt,void *out,const void *in) - { Camellia_encrypt(in,out,crypt->encrypt_key); } - -static void camellia_block_decrypt(ops_crypt_t *crypt,void *out,const void *in) - { Camellia_decrypt(in,out,crypt->decrypt_key); } - -static void camellia_cfb_encrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - Camellia_cfb128_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - CAMELLIA_ENCRYPT); - } - -static void camellia_cfb_decrypt(ops_crypt_t *crypt,void *out,const void *in, size_t count) - { - Camellia_cfb128_encrypt(in,out,count, - crypt->encrypt_key, crypt->iv, (int *)&crypt->num, - CAMELLIA_DECRYPT); - } - -static const ops_crypt_t camellia128= - { - OPS_SA_CAMELLIA_128, - CAMELLIA_BLOCK_SIZE, - KEYBITS_CAMELLIA128/8, - std_set_iv, - std_set_key, - camellia128_init, - std_resync, - camellia_block_encrypt, - camellia_block_decrypt, - camellia_cfb_encrypt, - camellia_cfb_decrypt, - std_finish, - TRAILER - }; - -// CAMELLIA with 192-bit key - -#define KEYBITS_CAMELLIA192 192 - -static void camellia192_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA192,crypt->encrypt_key)) - fprintf(stderr,"camellia192_init: Error setting encrypt_key\n"); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA192,crypt->decrypt_key)) - fprintf(stderr,"camellia192_init: Error setting decrypt_key\n"); - } - -static const ops_crypt_t camellia192= - { - OPS_SA_CAMELLIA_192, - CAMELLIA_BLOCK_SIZE, - KEYBITS_CAMELLIA192/8, - std_set_iv, - std_set_key, - camellia192_init, - std_resync, - camellia_block_encrypt, - camellia_block_decrypt, - camellia_cfb_encrypt, - camellia_cfb_decrypt, - std_finish, - TRAILER - }; - -// CAMELLIA with 256-bit key - -#define KEYBITS_CAMELLIA256 256 - -static void camellia256_init(ops_crypt_t *crypt) - { - if (crypt->encrypt_key) - free(crypt->encrypt_key); - crypt->encrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA256,crypt->encrypt_key)) - fprintf(stderr,"camellia256_init: Error setting encrypt_key\n"); - - if (crypt->decrypt_key) - free(crypt->decrypt_key); - crypt->decrypt_key=malloc(sizeof(CAMELLIA_KEY)); - if (Camellia_set_key(crypt->key,KEYBITS_CAMELLIA256,crypt->decrypt_key)) - fprintf(stderr,"camellia256_init: Error setting decrypt_key\n"); - } - -static const ops_crypt_t camellia256= - { - OPS_SA_CAMELLIA_256, - CAMELLIA_BLOCK_SIZE, - KEYBITS_CAMELLIA256/8, - std_set_iv, - std_set_key, - camellia256_init, - std_resync, - camellia_block_encrypt, - camellia_block_decrypt, - camellia_cfb_encrypt, - camellia_cfb_decrypt, - std_finish, - TRAILER - }; - -#endif // ndef OPENSSL_NO_CAMELLIA - -// Triple DES - -static void tripledes_init(ops_crypt_t *crypt) - { - DES_key_schedule *keys; - int n; - - if (crypt->encrypt_key) - free(crypt->encrypt_key); - keys=crypt->encrypt_key=malloc(3*sizeof(DES_key_schedule)); - - for(n=0 ; n < 3 ; ++n) - DES_set_key((DES_cblock *)(crypt->key+n*8),&keys[n]); - } - -static void tripledes_block_encrypt(ops_crypt_t *crypt,void *out, - const void *in) - { - DES_key_schedule *keys=crypt->encrypt_key; - - DES_ecb3_encrypt((void *)in,out,&keys[0],&keys[1],&keys[2],DES_ENCRYPT); - } - -static void tripledes_block_decrypt(ops_crypt_t *crypt,void *out, - const void *in) - { - DES_key_schedule *keys=crypt->encrypt_key; - - DES_ecb3_encrypt((void *)in,out,&keys[0],&keys[1],&keys[2],DES_DECRYPT); - } - -static void tripledes_cfb_encrypt(ops_crypt_t *crypt ATTRIBUTE_UNUSED, - void *out ATTRIBUTE_UNUSED, - const void *in ATTRIBUTE_UNUSED, - size_t count ATTRIBUTE_UNUSED) - { - DES_key_schedule *keys=crypt->encrypt_key; - DES_ede3_cfb64_encrypt(in,out,count, - &keys[0],&keys[1],&keys[2], - (DES_cblock *)crypt->iv, (int *)&crypt->num, - DES_ENCRYPT); - } - -static void tripledes_cfb_decrypt(ops_crypt_t *crypt ATTRIBUTE_UNUSED, - void *out ATTRIBUTE_UNUSED, - const void *in ATTRIBUTE_UNUSED, - size_t count ATTRIBUTE_UNUSED) - { - DES_key_schedule *keys=crypt->encrypt_key; - DES_ede3_cfb64_encrypt(in,out,count, - &keys[0],&keys[1],&keys[2], - (DES_cblock *)crypt->iv, (int *)&crypt->num, - DES_DECRYPT); - } - -static const ops_crypt_t tripledes= - { - OPS_SA_TRIPLEDES, - 8, - 24, - std_set_iv, - std_set_key, - tripledes_init, - std_resync, - tripledes_block_encrypt, - tripledes_block_decrypt, - tripledes_cfb_encrypt, - tripledes_cfb_decrypt, - std_finish, - TRAILER - }; - -static const ops_crypt_t *get_proto(ops_symmetric_algorithm_t alg) - { - switch(alg) - { - case OPS_SA_CAST5: - return &cast5; - -#ifndef OPENSSL_NO_IDEA - case OPS_SA_IDEA: - return &idea; -#endif /* OPENSSL_NO_IDEA */ - - case OPS_SA_AES_128: - return &aes128; - - case OPS_SA_AES_256: - return &aes256; - -#ifndef OPENSSL_NO_CAMELLIA - case OPS_SA_CAMELLIA_128: - return &camellia128; - - case OPS_SA_CAMELLIA_192: - return &camellia192; - - case OPS_SA_CAMELLIA_256: - return &camellia256; -#endif // ndef OPENSSL_NO_CAMELLIA - - case OPS_SA_TRIPLEDES: - return &tripledes; - - default: - fprintf(stderr,"Unknown algorithm: %d (%s)\n",alg, - ops_show_symmetric_algorithm(alg)); - // assert(0); - } - - return NULL; - } - -int ops_crypt_any(ops_crypt_t *crypt,ops_symmetric_algorithm_t alg) - { - const ops_crypt_t *ptr=get_proto(alg); - if (ptr) - { - *crypt=*ptr; - return 1; - } - else - { - memset(crypt,'\0',sizeof *crypt); - return 0; - } - } - -unsigned ops_block_size(ops_symmetric_algorithm_t alg) - { - const ops_crypt_t *p=get_proto(alg); - - if(!p) - return 0; - - return p->blocksize; - } - -unsigned ops_key_size(ops_symmetric_algorithm_t alg) - { - const ops_crypt_t *p=get_proto(alg); - - if(!p) - return 0; - - return p->keysize; - } - -void ops_encrypt_init(ops_crypt_t * encrypt) - { - // \todo should there be a separate ops_encrypt_init? - ops_decrypt_init(encrypt); - } - -void ops_decrypt_init(ops_crypt_t *decrypt) - { - decrypt->base_init(decrypt); - decrypt->block_encrypt(decrypt,decrypt->siv,decrypt->iv); - memcpy(decrypt->civ,decrypt->siv,decrypt->blocksize); - decrypt->num=0; - } - -size_t ops_decrypt_se -(ops_crypt_t *decrypt,void *out_,const void *in_, - size_t count) - { - unsigned char *out=out_; - const unsigned char *in=in_; - int saved=count; - - /* in order to support v3's weird resyncing we have to implement CFB mode - ourselves */ - while(count-- > 0) - { - unsigned char t; - - if(decrypt->num == decrypt->blocksize) - { - memcpy(decrypt->siv,decrypt->civ,decrypt->blocksize); - decrypt->block_decrypt(decrypt,decrypt->civ,decrypt->civ); - decrypt->num=0; - } - t=decrypt->civ[decrypt->num]; - *out++=t^(decrypt->civ[decrypt->num++]=*in++); - } - - return saved; - } - -size_t ops_encrypt_se(ops_crypt_t *encrypt,void *out_,const void *in_, - size_t count) - { - unsigned char *out=out_; - const unsigned char *in=in_; - int saved=count; - - /* in order to support v3's weird resyncing we have to implement CFB mode - ourselves */ - while(count-- > 0) - { - if(encrypt->num == encrypt->blocksize) - { - memcpy(encrypt->siv,encrypt->civ,encrypt->blocksize); - encrypt->block_encrypt(encrypt,encrypt->civ,encrypt->civ); - encrypt->num=0; - } - encrypt->civ[encrypt->num]=*out++=encrypt->civ[encrypt->num]^*in++; - ++encrypt->num; - } - - return saved; - } - -/** -\ingroup HighLevel_Supported -\brief Is this Symmetric Algorithm supported? -\param alg Symmetric Algorithm to check -\return ops_true if supported; else ops_false -*/ -ops_boolean_t ops_is_sa_supported(ops_symmetric_algorithm_t alg) - { - switch (alg) - { - case OPS_SA_AES_128: - case OPS_SA_AES_256: - case OPS_SA_CAMELLIA_128: - case OPS_SA_CAMELLIA_192: - case OPS_SA_CAMELLIA_256: - case OPS_SA_CAST5: - case OPS_SA_TRIPLEDES: -#ifndef OPENSSL_NO_IDEA - case OPS_SA_IDEA: -#endif - return ops_true; - break; - - default: - fprintf(stderr,"\nWarning: %s not supported\n", - ops_show_symmetric_algorithm(alg)); - return ops_false; - } - } - -size_t ops_encrypt_se_ip(ops_crypt_t *crypt,void *out_,const void *in_, - size_t count) - { - if (!ops_is_sa_supported(crypt->algorithm)) - return -1; - - crypt->cfb_encrypt(crypt, out_, in_, count); - - // \todo test this number was encrypted - return count; - } - -size_t ops_decrypt_se_ip(ops_crypt_t *crypt,void *out_,const void *in_, - size_t count) - { - if (!ops_is_sa_supported(crypt->algorithm)) - return -1; - - crypt->cfb_decrypt(crypt, out_, in_, count); - - // \todo check this number was in fact decrypted - return count; - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/types.h b/openpgpsdk/src/openpgpsdk/types.h deleted file mode 100644 index 50d4107a0..000000000 --- a/openpgpsdk/src/openpgpsdk/types.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_TYPES_H -#define OPS_TYPES_H - -/** Special type for intermediate function casting, avoids warnings on - some platforms -*/ -typedef void (*ops_void_fptr)(void); -#define ops_fcast(f) ((ops_void_fptr)f) - -/** ops_map_t - */ -typedef struct - { - int type; - char *string; - } ops_map_t; - -/** Boolean type */ -typedef unsigned ops_boolean_t; - -/** ops_content_tag_t */ - -/* PTag Content Tags */ -/***************************/ - -/** Package Tags (aka Content Tags) and signature subpacket types. - * This enumerates all rfc-defined packet tag values and the - * signature subpacket type values that we understand. - * - * \see RFC4880 4.3 - * \see RFC4880 5.2.3.1 - */ - -#ifndef __cplusplus -typedef enum ops_content_tag_t ops_content_tag_t ; -#endif - -enum ops_content_tag_t - { - OPS_PTAG_CT_RESERVED = 0, /*!< Reserved - a packet tag must not have this value */ - OPS_PTAG_CT_PK_SESSION_KEY = 1, /*!< Public-Key Encrypted Session Key Packet */ - OPS_PTAG_CT_SIGNATURE = 2, /*!< Signature Packet */ - OPS_PTAG_CT_SK_SESSION_KEY = 3, /*!< Symmetric-Key Encrypted Session Key Packet */ - OPS_PTAG_CT_ONE_PASS_SIGNATURE = 4, /*!< One-Pass Signature Packet */ - OPS_PTAG_CT_SECRET_KEY = 5, /*!< Secret Key Packet */ - OPS_PTAG_CT_PUBLIC_KEY = 6, /*!< Public Key Packet */ - OPS_PTAG_CT_SECRET_SUBKEY = 7, /*!< Secret Subkey Packet */ - OPS_PTAG_CT_COMPRESSED = 8, /*!< Compressed Data Packet */ - OPS_PTAG_CT_SE_DATA = 9, /*!< Symmetrically Encrypted Data Packet */ - OPS_PTAG_CT_MARKER =10, /*!< Marker Packet */ - OPS_PTAG_CT_LITERAL_DATA =11, /*!< Literal Data Packet */ - OPS_PTAG_CT_TRUST =12, /*!< Trust Packet */ - OPS_PTAG_CT_USER_ID =13, /*!< User ID Packet */ - OPS_PTAG_CT_PUBLIC_SUBKEY =14, /*!< Public Subkey Packet */ - OPS_PTAG_CT_RESERVED2 =15, /*!< reserved */ - OPS_PTAG_CT_RESERVED3 =16, /*!< reserved */ - OPS_PTAG_CT_USER_ATTRIBUTE =17, /*!< User Attribute Packet */ - OPS_PTAG_CT_SE_IP_DATA =18, /*!< Sym. Encrypted and Integrity Protected Data Packet */ - OPS_PTAG_CT_MDC =19, /*!< Modification Detection Code Packet */ - - OPS_PARSER_PTAG =0x100, /*!< Internal Use: The packet is the "Packet Tag" itself - used when - callback sends back the PTag. */ - OPS_PTAG_RAW_SS =0x101, /*!< Internal Use: content is raw sig subtag */ - OPS_PTAG_SS_ALL =0x102, /*!< Internal Use: select all subtags */ - OPS_PARSER_PACKET_END =0x103, - - /* signature subpackets (0x200-2ff) (type+0x200) */ - /* only those we can parse are listed here */ - OPS_PTAG_SIGNATURE_SUBPACKET_BASE =0x200, /*!< Base for signature subpacket types - All signature type - values are relative to this value. */ - OPS_PTAG_SS_CREATION_TIME =0x200+2, /*!< signature creation time */ - OPS_PTAG_SS_EXPIRATION_TIME =0x200+3, /*!< signature expiration time */ - - OPS_PTAG_SS_EXPORTABLE_CERTIFICATION =0x200+4, /*!< exportable certification */ - OPS_PTAG_SS_TRUST =0x200+5, /*!< trust signature */ - OPS_PTAG_SS_REGEXP =0x200+6, /*!< regular expression */ - OPS_PTAG_SS_REVOCABLE =0x200+7, /*!< revocable */ - OPS_PTAG_SS_KEY_EXPIRATION_TIME =0x200+9, /*!< key expiration time */ - OPS_PTAG_SS_RESERVED =0x200+10, /*!< reserved */ - OPS_PTAG_SS_PREFERRED_SKA =0x200+11, /*!< preferred symmetric algorithms */ - OPS_PTAG_SS_REVOCATION_KEY =0x200+12, /*!< revocation key */ - OPS_PTAG_SS_ISSUER_KEY_ID =0x200+16, /*!< issuer key ID */ - OPS_PTAG_SS_NOTATION_DATA =0x200+20, /*!< notation data */ - OPS_PTAG_SS_PREFERRED_HASH =0x200+21, /*!< preferred hash algorithms */ - OPS_PTAG_SS_PREFERRED_COMPRESSION =0x200+22, /*!< preferred compression algorithms */ - OPS_PTAG_SS_KEY_SERVER_PREFS =0x200+23, /*!< key server preferences */ - OPS_PTAG_SS_PREFERRED_KEY_SERVER =0x200+24, /*!< Preferred Key Server */ - OPS_PTAG_SS_PRIMARY_USER_ID =0x200+25, /*!< primary User ID */ - OPS_PTAG_SS_POLICY_URI =0x200+26, /*!< Policy URI */ - OPS_PTAG_SS_KEY_FLAGS =0x200+27, /*!< key flags */ - OPS_PTAG_SS_SIGNERS_USER_ID =0x200+28, /*!< Signer's User ID */ - OPS_PTAG_SS_REVOCATION_REASON =0x200+29, /*!< reason for revocation */ - OPS_PTAG_SS_FEATURES =0x200+30, /*!< features */ - OPS_PTAG_SS_SIGNATURE_TARGET =0x200+31, /*!< signature target */ - OPS_PTAG_SS_EMBEDDED_SIGNATURE=0x200+32, /*!< embedded signature */ - - OPS_PTAG_SS_USERDEFINED00 =0x200+100, /*!< internal or user-defined */ - OPS_PTAG_SS_USERDEFINED01 =0x200+101, - OPS_PTAG_SS_USERDEFINED02 =0x200+102, - OPS_PTAG_SS_USERDEFINED03 =0x200+103, - OPS_PTAG_SS_USERDEFINED04 =0x200+104, - OPS_PTAG_SS_USERDEFINED05 =0x200+105, - OPS_PTAG_SS_USERDEFINED06 =0x200+106, - OPS_PTAG_SS_USERDEFINED07 =0x200+107, - OPS_PTAG_SS_USERDEFINED08 =0x200+108, - OPS_PTAG_SS_USERDEFINED09 =0x200+109, - OPS_PTAG_SS_USERDEFINED10 =0x200+110, - - - /* pseudo content types */ - OPS_PTAG_CT_LITERAL_DATA_HEADER =0x300, - OPS_PTAG_CT_LITERAL_DATA_BODY =0x300+1, - OPS_PTAG_CT_SIGNATURE_HEADER =0x300+2, - OPS_PTAG_CT_SIGNATURE_FOOTER =0x300+3, - OPS_PTAG_CT_ARMOUR_HEADER =0x300+4, - OPS_PTAG_CT_ARMOUR_TRAILER =0x300+5, - OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER =0x300+6, - OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY =0x300+7, - OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER=0x300+8, - OPS_PTAG_CT_UNARMOURED_TEXT =0x300+9, - OPS_PTAG_CT_ENCRYPTED_SECRET_KEY =0x300+10, // In this case the algorithm specific fields will not be initialised - OPS_PTAG_CT_SE_DATA_HEADER =0x300+11, - OPS_PTAG_CT_SE_DATA_BODY =0x300+12, - OPS_PTAG_CT_SE_IP_DATA_HEADER =0x300+13, - OPS_PTAG_CT_SE_IP_DATA_BODY =0x300+14, - OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY=0x300+15, - - /* commands to the callback */ - OPS_PARSER_CMD_GET_SK_PASSPHRASE =0x400, - OPS_PARSER_CMD_GET_SECRET_KEY =0x400+1, - OPS_PARSER_CMD_GET_SK_PASSPHRASE_PREV_WAS_BAD =0x400+2, - - /* Errors */ - OPS_PARSER_ERROR =0x500, /*!< Internal Use: Parser Error */ - OPS_PARSER_ERRCODE =0x500+1, /*! < Internal Use: Parser Error with errcode returned */ - }; - -/** Used to specify whether subpackets should be returned raw, parsed or ignored. - */ - -enum ops_parse_type_t - { - OPS_PARSE_RAW, /*!< Callback Raw */ - OPS_PARSE_PARSED, /*!< Callback Parsed */ - OPS_PARSE_IGNORE, /*!< Don't callback */ - }; - -typedef struct _ops_crypt_t ops_crypt_t; - -/** ops_hash_t */ -typedef struct _ops_hash_t ops_hash_t; - -/** - keep both ops_content_tag_t and ops_packet_tag_t because we might - want to introduce some bounds checking i.e. is this really a valid value - for a packet tag? -*/ -typedef enum ops_content_tag_t ops_packet_tag_t; -/** SS types are a subset of all content types. -*/ -typedef enum ops_content_tag_t ops_ss_type_t; -/* typedef enum ops_sig_type_t ops_sig_type_t; */ - -/** Revocation Reason type */ -typedef unsigned char ops_ss_rr_code_t; - -/** ops_parse_type_t */ - -/** Used to specify whether subpackets should be returned raw, parsed or ignored. - */ - -typedef enum ops_parse_type_t ops_parse_type_t; - -/** ops_parser_content_t */ -typedef struct ops_parser_content_t ops_parser_content_t; - -/** Reader Flags */ -/* -typedef enum - { - OPS_RETURN_LENGTH=1, - } ops_reader_flags_t; -typedef enum ops_reader_ret_t ops_reader_ret_t; -*/ - -/** Writer flags */ -typedef enum - { - OPS_WF_DUMMY, - } ops_writer_flags_t; - -/** - * \ingroup Create - * Contains the required information about how to write - */ -typedef struct ops_create_info ops_create_info_t; - -#endif diff --git a/openpgpsdk/src/openpgpsdk/util.c b/openpgpsdk/src/openpgpsdk/util.c deleted file mode 100644 index 2dced1ff0..000000000 --- a/openpgpsdk/src/openpgpsdk/util.c +++ /dev/null @@ -1,179 +0,0 @@ - /* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef WIN32 -#include -#endif - -#include - -#include - -/** - * Searches the given map for the given type. - * Returns a human-readable descriptive string if found, - * returns NULL if not found - * - * It is the responsibility of the calling function to handle the - * error case sensibly (i.e. don't just print out the return string. - * - */ -static char *str_from_map_or_null(int type, ops_map_t *map) - { - ops_map_t *row; - - for ( row=map; row->string != NULL; row++ ) - if (row->type == type) - return row->string; - return NULL; - } - -/** - * \ingroup Core_Print - * - * Searches the given map for the given type. - * Returns a readable string if found, "Unknown" if not. - */ - -char *ops_str_from_map(int type, ops_map_t *map) - { - char *str; - str=str_from_map_or_null(type,map); - if (str) - return(str); - else - return("Unknown"); - } - -void hexdump(const unsigned char *src,size_t length) - { - while(length--) - printf("%02X",*src++); - } - -/** - * \ingroup HighLevel_Functions - * \brief Initialises OpenPGP::SDK. To be called before any other OPS function. - * - * Initialises OpenPGP::SDK and the underlying openssl library. - */ - -void ops_init(void) - { - ops_crypto_init(); - } - -/** - * \ingroup HighLevel_Functions - * \brief Closes down OpenPGP::SDK. - * - * Close down OpenPGP:SDK, release any resources under the control of - * the library. No OpenPGP:SDK function other than ops_init() should - * be called after this function. - */ - -void ops_finish(void) - { - ops_crypto_finish(); - } - -/** - \ingroup HighLevel_Misc - \brief mallocs and zeros memory - \param n Number of bytes to be alloc-ed. - \return Pointer to new memory. - \note Should be freed after use with free(). -*/ -void *ops_mallocz(size_t n) -{ - void *m=malloc(n); - - if(m == NULL) - fprintf(stderr,"(EE) Cannot allocate %lu bytes of memory in %s\n",n,__PRETTY_FUNCTION__) ; - else - memset(m,'\0',n); - - return m; -} - -typedef struct - { - unsigned short sum; - } sum16_arg_t; - -static int sum16_reader(void *dest_,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo) - { - const unsigned char *dest=dest_; - sum16_arg_t *arg=ops_reader_get_arg(rinfo); - int r=ops_stacked_read(dest_,length,errors,rinfo,cbinfo); - int n; - - if(r < 0) - return r; - - for(n=0 ; n < r ; ++n) - arg->sum=(arg->sum+dest[n])&0xffff; - - return r; - } - -static void sum16_destroyer(ops_reader_info_t *rinfo) - { free(ops_reader_get_arg(rinfo)); } - -/** - \ingroup Internal_Readers_Sum16 - \param pinfo Parse settings -*/ - -void ops_reader_push_sum16(ops_parse_info_t *pinfo) - { - sum16_arg_t *arg=ops_mallocz(sizeof *arg); - - ops_reader_push(pinfo,sum16_reader,sum16_destroyer,arg); - } - -/** - \ingroup Internal_Readers_Sum16 - \param pinfo Parse settings - \return sum -*/ -unsigned short ops_reader_pop_sum16(ops_parse_info_t *pinfo) - { - sum16_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(pinfo)); - unsigned short sum=arg->sum; - - ops_reader_pop(pinfo); - free(arg); - - return sum; - } diff --git a/openpgpsdk/src/openpgpsdk/util.h b/openpgpsdk/src/openpgpsdk/util.h deleted file mode 100644 index 88d7b10a8..000000000 --- a/openpgpsdk/src/openpgpsdk/util.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_UTIL_H -#define OPS_UTIL_H - -#include "openpgpsdk/types.h" -#include "openpgpsdk/create.h" -#include "openpgpsdk/packet-parse.h" -#include - -#define ops_false 0 -#define ops_true 1 - -void hexdump(const unsigned char *src,size_t length); - -/* - * These macros code ensures that you are casting what you intend to cast. - * It works because in "a ? b : c", b and c must have the same type. - * This is a copy of the macro defined in openssl/asn1.h. - */ -#ifndef CHECKED_PTR_OF -#define CHECKED_PTR_OF(type, p) ((void*) (1 ? p : (type *)0)) -#endif -#define CHECKED_INSTANCE_OF(type, p) (1 ? p : (type)0) -#define DECONST(type,p) ((type *)CHECKED_PTR_OF(const type, p)) - -/* number of elements in an array */ -#define OPS_ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) - -void *ops_mallocz(size_t n); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/validate.c b/openpgpsdk/src/openpgpsdk/validate.c deleted file mode 100644 index d42d6becd..000000000 --- a/openpgpsdk/src/openpgpsdk/validate.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "keyring_local.h" -#include "parse_local.h" -#include -#include -#include -#include -#include -#include -#include - -#include - -static int debug=0; - -static ops_boolean_t check_binary_signature(const unsigned len, - const unsigned char *data, - const ops_signature_t *sig, - const ops_public_key_t *signer __attribute__((unused))) -{ - // Does the signed hash match the given hash? - - int n=0; - ops_hash_t hash; - unsigned char hashout[OPS_MAX_HASH_SIZE]; - unsigned char trailer[6]; - unsigned int hashedlen; - - //common_init_signature(&hash,sig); - ops_hash_any(&hash,sig->info.hash_algorithm); - hash.init(&hash); - hash.add(&hash,data,len); - switch (sig->info.version) - { - case OPS_V3: - trailer[0]=sig->info.type; - trailer[1]=sig->info.creation_time >> 24; - trailer[2]=sig->info.creation_time >> 16; - trailer[3]=sig->info.creation_time >> 8; - trailer[4]=sig->info.creation_time; - hash.add(&hash,&trailer[0],5); - break; - - case OPS_V4: - hash.add(&hash,sig->info.v4_hashed_data,sig->info.v4_hashed_data_length); - - trailer[0]=0x04; // version - trailer[1]=0xFF; - hashedlen=sig->info.v4_hashed_data_length; - trailer[2]=hashedlen >> 24; - trailer[3]=hashedlen >> 16; - trailer[4]=hashedlen >> 8; - trailer[5]=hashedlen; - hash.add(&hash,&trailer[0],6); - - break; - - default: - fprintf(stderr,"Invalid signature version %d\n", sig->info.version); - return ops_false; - } - - n=hash.finish(&hash,hashout); - - // return ops_false; - return ops_check_signature(hashout,n,sig,signer); -} - -static int keydata_reader(void *dest,size_t length,ops_error_t **errors, - ops_reader_info_t *rinfo, - ops_parse_cb_info_t *cbinfo) -{ - validate_reader_arg_t *arg=ops_reader_get_arg(rinfo); - - OPS_USED(errors); - OPS_USED(cbinfo); - if(arg->offset == arg->key->packets[arg->packet].length) - { - ++arg->packet; - arg->offset=0; - } - - if(arg->packet == arg->key->npackets) - return 0; - - // we should never be asked to cross a packet boundary in a single read - // - if(arg->key->packets[arg->packet].length >= arg->offset+length) - { - memcpy(dest,&arg->key->packets[arg->packet].raw[arg->offset],length); - arg->offset+=length; - - return length; - } - else - { - // If that happens, we set the offet to the total length and return 0. - // - fprintf(stderr,"WARNING: keydata_reader: packet length %lu goes beyond actual data size %lu. Consistency error!",arg->offset+length,arg->key->packets[arg->packet].length) ; - - arg->offset = arg->key->packets[arg->packet].length ; - return 0 ; - } -} - -static void free_signature_info(ops_signature_info_t *sig,int n) -{ - int i ; - for(i=0;iv4_hashed_data=ops_mallocz(src->v4_hashed_data_length); - memcpy(dst->v4_hashed_data,src->v4_hashed_data,src->v4_hashed_data_length); -} - -static void add_sig_to_valid_list(ops_validate_result_t * result, const ops_signature_info_t* sig) -{ - size_t newsize; - - // increment count - ++result->valid_count; - - // increase size of array - newsize=(sizeof *sig) * result->valid_count; - if (!result->valid_sigs) - result->valid_sigs=malloc(newsize); - else - result->valid_sigs=realloc(result->valid_sigs, newsize); - - // copy key ptr to array - copy_signature_info(&result->valid_sigs[result->valid_count-1],sig); -} - -static void add_sig_to_invalid_list(ops_validate_result_t * result, const ops_signature_info_t *sig) -{ - size_t newsize; - - // increment count - ++result->invalid_count; - - // increase size of array - newsize=(sizeof *sig) * result->invalid_count; - if (!result->invalid_sigs) - result->invalid_sigs=malloc(newsize); - else - result->invalid_sigs=realloc(result->invalid_sigs, newsize); - - // copy key ptr to array - copy_signature_info(&result->invalid_sigs[result->invalid_count-1],sig); -} - -static void add_sig_to_unknown_list(ops_validate_result_t * result, const ops_signature_info_t *sig) -{ - size_t newsize; - - // increment count - ++result->unknown_signer_count; - - // increase size of array - newsize=(sizeof *sig) * result->unknown_signer_count; - if (!result->unknown_sigs) - result->unknown_sigs=malloc(newsize); - else - result->unknown_sigs=realloc(result->unknown_sigs, newsize); - - // copy key id to array - copy_signature_info(&result->unknown_sigs[result->unknown_signer_count-1],sig); -} - - ops_parse_cb_return_t -ops_validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) -{ - const ops_parser_content_union_t *content=&content_->content; - validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); - ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); - const ops_keydata_t *signer; - ops_boolean_t valid=ops_false; - - if (debug) - printf("%s\n",ops_show_packet_tag(content_->tag)); - - switch(content_->tag) - { - case OPS_PTAG_CT_PUBLIC_KEY: - if(arg->pkey.version != 0) - { - fprintf(stderr,"arg->pkey.version should be 0! It's %d. Giving up.",arg->pkey.version) ; - return OPS_RELEASE_MEMORY ; - } - arg->pkey=content->public_key; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_PUBLIC_SUBKEY: - if(arg->subkey.version) - ops_public_key_free(&arg->subkey); - arg->subkey=content->public_key; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_SECRET_KEY: - arg->skey=content->secret_key; - arg->pkey=arg->skey.public_key; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_USER_ID: - if(arg->user_id.user_id) - ops_user_id_free(&arg->user_id); - arg->user_id=content->user_id; - arg->last_seen=ID; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_USER_ATTRIBUTE: - if(!content->user_attribute.data.len) - { - fprintf(stderr,"User attribute length is 0. Not possible! Giving up.") ; - return OPS_RELEASE_MEMORY ; - } - printf("user attribute, length=%d\n",(int)content->user_attribute.data.len); - if(arg->user_attribute.data.len) - ops_user_attribute_free(&arg->user_attribute); - arg->user_attribute=content->user_attribute; - arg->last_seen=ATTRIBUTE; - return OPS_KEEP_MEMORY; - - case OPS_PTAG_CT_SIGNATURE: // V3 sigs - case OPS_PTAG_CT_SIGNATURE_FOOTER: // V4 sigs - - if(debug) - { - printf(" type=%02x signer_id=",content->signature.info.type); - hexdump(content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - printf("\n"); - } - - signer=ops_keyring_find_key_by_id(arg->keyring, - content->signature.info.signer_id); - if(!signer) - { - add_sig_to_unknown_list(arg->result, &content->signature.info); - break; - } - - switch(content->signature.info.type) - { - case OPS_CERT_GENERIC: - case OPS_CERT_PERSONA: - case OPS_CERT_CASUAL: - case OPS_CERT_POSITIVE: - case OPS_SIG_REV_CERT: - if(arg->last_seen == ID) - valid=ops_check_user_id_certification_signature(&arg->pkey, - &arg->user_id, - &content->signature, - ops_get_public_key_from_data(signer), - arg->rarg->key->packets[arg->rarg->packet].raw); - else - valid=ops_check_user_attribute_certification_signature(&arg->pkey, - &arg->user_attribute, - &content->signature, - ops_get_public_key_from_data(signer), - arg->rarg->key->packets[arg->rarg->packet].raw); - - break; - - case OPS_SIG_SUBKEY: - // XXX: we should also check that the signer is the key we are validating, I think. - valid=ops_check_subkey_signature(&arg->pkey,&arg->subkey, - &content->signature, - ops_get_public_key_from_data(signer), - arg->rarg->key->packets[arg->rarg->packet].raw); - break; - - case OPS_SIG_DIRECT: - valid=ops_check_direct_signature(&arg->pkey,&content->signature, - ops_get_public_key_from_data(signer), - arg->rarg->key->packets[arg->rarg->packet].raw); - break; - - case OPS_SIG_STANDALONE: - case OPS_SIG_PRIMARY: - case OPS_SIG_REV_KEY: - case OPS_SIG_REV_SUBKEY: - case OPS_SIG_TIMESTAMP: - case OPS_SIG_3RD_PARTY: - OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED, - "Verification of signature type 0x%02x not yet implemented\n", content->signature.info.type); - break; - - default: - OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED, - "Unexpected signature type 0x%02x\n", content->signature.info.type); - } - - if(valid) - { - // printf(" validated\n"); - //++arg->result->valid_count; - add_sig_to_valid_list(arg->result, &content->signature.info); - } - else - { - OPS_ERROR(errors,OPS_E_V_BAD_SIGNATURE,"Bad Signature"); - // printf(" BAD SIGNATURE\n"); - // ++arg->result->invalid_count; - add_sig_to_invalid_list(arg->result, &content->signature.info); - } - break; - - // ignore these - case OPS_PARSER_PTAG: - case OPS_PTAG_CT_SIGNATURE_HEADER: - case OPS_PARSER_PACKET_END: - case OPS_PTAG_CT_TRUST: - break; - - case OPS_PARSER_CMD_GET_SK_PASSPHRASE: - if (arg->cb_get_passphrase) - { - return arg->cb_get_passphrase(content_,cbinfo); - } - break; - - default: - fprintf(stderr,"unexpected tag=0x%x\n",content_->tag); - //assert(0); - OPS_ERROR_1(errors, OPS_E_V_NO_SIGNATURE, "Unknown PTAG 0x%02x in validation packet\n",content_->tag); - break; - } - return OPS_RELEASE_MEMORY; -} - - ops_parse_cb_return_t -validate_data_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo) -{ - const ops_parser_content_union_t *content=&content_->content; - validate_data_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo); - ops_error_t **errors=ops_parse_cb_get_errors(cbinfo); - const ops_keydata_t *signer; - ops_boolean_t valid=ops_false; - ops_memory_t* mem=NULL; - - if (debug) - printf("%s\n",ops_show_packet_tag(content_->tag)); - - switch(content_->tag) - { - case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: - // ignore - this gives us the "Armor Header" line "Hash: SHA1" or similar - break; - - case OPS_PTAG_CT_LITERAL_DATA_HEADER: - // ignore - break; - - case OPS_PTAG_CT_LITERAL_DATA_BODY: - arg->literal_data_body=content->literal_data_body; - arg->use=LITERAL_DATA; - return OPS_KEEP_MEMORY; - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: - arg->signed_cleartext_body=content->signed_cleartext_body; - arg->use=SIGNED_CLEARTEXT; - return OPS_KEEP_MEMORY; - break; - - case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: - // this gives us an ops_hash_t struct - break; - - case OPS_PTAG_CT_SIGNATURE: // V3 sigs - case OPS_PTAG_CT_SIGNATURE_FOOTER: // V4 sigs - - if (debug) - { - printf("\n*** hashed data:\n"); - unsigned int zzz=0; - for (zzz=0; zzzsignature.info.v4_hashed_data_length; zzz++) - printf("0x%02x ", content->signature.info.v4_hashed_data[zzz]); - printf("\n"); - printf(" type=%02x signer_id=",content->signature.info.type); - hexdump(content->signature.info.signer_id, - sizeof content->signature.info.signer_id); - } - - signer=ops_keyring_find_key_by_id(arg->keyring, - content->signature.info.signer_id); - if(!signer) - { - OPS_ERROR(errors,OPS_E_V_UNKNOWN_SIGNER,"Unknown Signer"); - add_sig_to_unknown_list(arg->result, &content->signature.info); - break; - } - - mem=ops_memory_new(); - ops_memory_init(mem,128); - - switch(content->signature.info.type) - { - case OPS_SIG_BINARY: - case OPS_SIG_TEXT: - switch(arg->use) - { - case LITERAL_DATA: - ops_memory_add(mem, - arg->literal_data_body.data, - arg->literal_data_body.length); - break; - - case SIGNED_CLEARTEXT: - ops_memory_add(mem, - arg->signed_cleartext_body.data, - arg->signed_cleartext_body.length); - break; - - default: - OPS_ERROR_1(errors,OPS_E_UNIMPLEMENTED,"Unimplemented Sig Use %d", arg->use); - printf(" Unimplemented Sig Use %d\n", arg->use); - break; - } - - valid=check_binary_signature(ops_memory_get_length(mem), - ops_memory_get_data(mem), - &content->signature, - ops_get_public_key_from_data(signer)); - break; - - default: - OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED, - "Verification of signature type 0x%02x not yet implemented\n", content->signature.info.type); - break; - - } - ops_memory_free(mem); - - if(valid) - { - add_sig_to_valid_list(arg->result, &content->signature.info); - } - else - { - OPS_ERROR(errors,OPS_E_V_BAD_SIGNATURE,"Bad Signature"); - add_sig_to_invalid_list(arg->result, &content->signature.info); - } - break; - - // ignore these - case OPS_PARSER_PTAG: - case OPS_PTAG_CT_SIGNATURE_HEADER: - case OPS_PTAG_CT_ARMOUR_HEADER: - case OPS_PTAG_CT_ARMOUR_TRAILER: - case OPS_PTAG_CT_ONE_PASS_SIGNATURE: - case OPS_PARSER_PACKET_END: - break; - - default: - fprintf(stderr,"unexpected tag=0x%x\n",content_->tag); - //assert(0); - OPS_ERROR_1(errors, OPS_E_V_NO_SIGNATURE, "Unknown PTAG 0x%02x in validation packet\n",content_->tag); - break; - } - return OPS_RELEASE_MEMORY; -} - -static void keydata_destroyer(ops_reader_info_t *rinfo) -{ free(ops_reader_get_arg(rinfo)); } - -void ops_keydata_reader_set(ops_parse_info_t *pinfo,const ops_keydata_t *key) -{ - validate_reader_arg_t *arg=malloc(sizeof *arg); - - memset(arg,'\0',sizeof *arg); - - arg->key=key; - arg->packet=0; - arg->offset=0; - - ops_reader_set(pinfo,keydata_reader,keydata_destroyer,arg); -} - -/** - * \ingroup HighLevel_Verify - * \brief Indicicates whether any errors were found - * \param result Validation result to check - * \return ops_false if any invalid signatures or unknown signers or no valid signatures; else ops_true - */ -ops_boolean_t validate_result_status(ops_validate_result_t* result) -{ - if (result->invalid_count || result->unknown_signer_count || !result->valid_count) - return ops_false; - else - return ops_true; -} - -/** - * \ingroup HighLevel_Verify - * \brief Validate all signatures on a single key against the given keyring - * \param result Where to put the result - * \param key Key to validate - * \param keyring Keyring to use for validation - * \param cb_get_passphrase Callback to use to get passphrase - * \return ops_true if all signatures OK; else ops_false - * \note It is the caller's responsiblity to free result after use. - * \sa ops_validate_result_free() - - Example Code: - \code - void example(const ops_keydata_t* key, const ops_keyring_t *keyring) - { - ops_validate_result_t *result=NULL; - if (ops_validate_key_signatures(result, key, keyring, callback_cmd_get_passphrase_from_cmdline)==ops_true) - printf("OK"); - else - printf("ERR"); - printf("valid=%d, invalid=%d, unknown=%d\n", - result->valid_count, - result->invalid_count, - result->unknown_signer_count); - ops_validate_result_free(result); - } - - \endcode - */ -ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result,const ops_keydata_t *key, - const ops_keyring_t *keyring, - ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *) - ) -{ - ops_parse_info_t *pinfo; - validate_key_cb_arg_t carg; - - memset(&carg,'\0',sizeof carg); - carg.result=result; - carg.cb_get_passphrase=cb_get_passphrase; - - pinfo=ops_parse_info_new(); - // ops_parse_options(&opt,OPS_PTAG_CT_SIGNATURE,OPS_PARSE_PARSED); - - carg.keyring=keyring; - - ops_parse_cb_set(pinfo,ops_validate_key_cb,&carg); - pinfo->rinfo.accumulate=ops_true; - ops_keydata_reader_set(pinfo,key); - - // Note: Coverity incorrectly reports an error that carg.rarg - // is never used. - carg.rarg=ops_reader_get_arg_from_pinfo(pinfo); - - ops_parse(pinfo,ops_true); - - ops_public_key_free(&carg.pkey); - if(carg.subkey.version) - ops_public_key_free(&carg.subkey); - ops_user_id_free(&carg.user_id); - ops_user_attribute_free(&carg.user_attribute); - - ops_parse_info_delete(pinfo); - -/* if(carg.literal_data_body.data != NULL) - free(carg.literal_data_body.data) ; */ - - if (result->invalid_count || result->unknown_signer_count || !result->valid_count) - return ops_false; - else - return ops_true; -} - -/** - \ingroup HighLevel_Verify - \param result Where to put the result - \param ring Keyring to use - \param cb_get_passphrase Callback to use to get passphrase - \note It is the caller's responsibility to free result after use. - \sa ops_validate_result_free() - */ -ops_boolean_t ops_validate_all_signatures(ops_validate_result_t *result, - const ops_keyring_t *ring, - ops_parse_cb_return_t cb_get_passphrase (const ops_parser_content_t *, ops_parse_cb_info_t *) - ) -{ - int n; - - memset(result,'\0',sizeof *result); - for(n=0 ; n < ring->nkeys ; ++n) - ops_validate_key_signatures(result,&ring->keys[n],ring, cb_get_passphrase); - return validate_result_status(result); -} - -/** - \ingroup HighLevel_Verify - \brief Frees validation result and associated memory - \param result Struct to be freed - \note Must be called after validation functions - */ -void ops_validate_result_free(ops_validate_result_t *result) -{ - if (!result) - return; - - if (result->valid_sigs) - free_signature_info(result->valid_sigs,result->valid_count); - if (result->invalid_sigs) - free_signature_info(result->invalid_sigs,result->invalid_count); - if (result->unknown_sigs) - free_signature_info(result->unknown_sigs,result->unknown_signer_count); - - free(result); - result=NULL; -} - -/** - \ingroup HighLevel_Verify - \brief Verifies the signatures in a signed file - \param result Where to put the result - \param filename Name of file to be validated - \param armoured Treat file as armoured, if set - \param keyring Keyring to use - \return ops_true if signatures validate successfully; ops_false if signatures fail or there are no signatures - \note After verification, result holds the details of all keys which - have passed, failed and not been recognised. - \note It is the caller's responsiblity to call ops_validate_result_free(result) after use. - - Example code: - \code - void example(const char* filename, const int armoured, const ops_keyring_t* keyring) - { - ops_validate_result_t* result=ops_mallocz(sizeof *result); - - if (ops_validate_file(result, filename, armoured, keyring)==ops_true) - { - printf("OK"); -// look at result for details of keys with good signatures -} -else -{ -printf("ERR"); -// look at result for details of failed signatures or unknown signers -} - -ops_validate_result_free(result); -} -\endcode - */ -ops_boolean_t ops_validate_file(ops_validate_result_t *result, const char* filename, const int armoured, const ops_keyring_t* keyring) -{ - ops_parse_info_t *pinfo=NULL; - validate_data_cb_arg_t validate_arg; - - int fd=0; - - // - fd=ops_setup_file_read(&pinfo, filename, &validate_arg, validate_data_cb, ops_true); - if (fd < 0) - return ops_false; - - // Set verification reader and handling options - - memset(&validate_arg,'\0',sizeof validate_arg); - validate_arg.result=result; - validate_arg.keyring=keyring; - // Note: Coverity incorrectly reports an error that carg.rarg - // is never used. - validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo); - - if (armoured) - ops_reader_push_dearmour(pinfo); - - // Do the verification - - ops_parse(pinfo,ops_true); - - if (debug) - { - printf("valid=%d, invalid=%d, unknown=%d\n", - result->valid_count, - result->invalid_count, - result->unknown_signer_count); - } - - // Tidy up - if (armoured) - ops_reader_pop_dearmour(pinfo); - ops_teardown_file_read(pinfo, fd); - - if(validate_arg.literal_data_body.data != NULL) free(validate_arg.literal_data_body.data) ; - - return validate_result_status(result); -} - -/** - \ingroup HighLevel_Verify - \brief Verifies the signatures in a ops_memory_t struct - \param result Where to put the result - \param mem Memory to be validated - \param armoured Treat data as armoured, if set - \param keyring Keyring to use - \return ops_true if signature validates successfully; ops_false if not - \note After verification, result holds the details of all keys which - have passed, failed and not been recognised. - \note It is the caller's responsiblity to call ops_validate_result_free(result) after use. - */ - -ops_boolean_t ops_validate_mem(ops_validate_result_t *result, ops_memory_t* mem, const int armoured, const ops_keyring_t* keyring) -{ - ops_parse_info_t *pinfo=NULL; - validate_data_cb_arg_t validate_arg; - - // - ops_setup_memory_read(&pinfo, mem, &validate_arg, validate_data_cb, ops_true); - - // Set verification reader and handling options - - memset(&validate_arg,'\0',sizeof validate_arg); - validate_arg.result=result; - validate_arg.keyring=keyring; - // Note: Coverity incorrectly reports an error that carg.rarg - // is never used. - validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo); - - if (armoured) - ops_reader_push_dearmour(pinfo); - - // Do the verification - - ops_parse(pinfo,ops_true); - - if (debug) - { - printf("valid=%d, invalid=%d, unknown=%d\n", - result->valid_count, - result->invalid_count, - result->unknown_signer_count); - } - - // Tidy up - if (armoured) - ops_reader_pop_dearmour(pinfo); - ops_teardown_memory_read(pinfo, mem); - - if(validate_arg.literal_data_body.data != NULL) free(validate_arg.literal_data_body.data) ; - if(validate_arg.signed_cleartext_body.data != NULL) free(validate_arg.signed_cleartext_body.data) ; - - return validate_result_status(result); -} - -/** - \ingroup HighLevel_Verify - \brief Verifies the signature in a detached signature data packet, given the literal data - \param literal_data Literal data that is signed - \param literal_data_length length of the literal data that is signed - \param signature_packet signature packet in binary PGP format - \param signature_packet_length length of the signature packet - \param signers_key Public key of the signer to check the signature for. - \return ops_true if signature validates successfully; ops_false if not - */ - -ops_boolean_t ops_validate_detached_signature(const void *literal_data, unsigned int literal_data_length, const unsigned char *signature_packet, unsigned int signature_packet_length,const ops_keydata_t *signers_key) -{ - ops_validate_result_t *result = (ops_validate_result_t*)ops_mallocz(sizeof(ops_validate_result_t)); - - ops_memory_t *mem = ops_memory_new() ; - ops_memory_add(mem,signature_packet,signature_packet_length) ; - - ops_parse_info_t *pinfo=NULL; - validate_data_cb_arg_t validate_arg; - - ops_setup_memory_read(&pinfo, mem, &validate_arg, validate_data_cb, ops_true); - - // Set verification reader and handling options - - ops_keyring_t tmp_keyring ; - tmp_keyring.nkeys = 1 ; - tmp_keyring.nkeys_allocated = 1 ; - tmp_keyring.keys = (ops_keydata_t *)signers_key ; // this is a const_cast, somehow - - memset(&validate_arg,'\0',sizeof validate_arg); - - validate_arg.result=result; - validate_arg.keyring=&tmp_keyring; - - int length = literal_data_length ; - - validate_arg.literal_data_body.data = (unsigned char *)malloc(length) ; - memcpy(validate_arg.literal_data_body.data, literal_data, length) ; - validate_arg.literal_data_body.length = length ; - - // Note: Coverity incorrectly reports an error that carg.rarg - // is never used. - validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo); - - //if (armoured) - // ops_reader_push_dearmour(pinfo); - - // Do the verification - - ops_parse(pinfo,ops_true); - - if(debug) - printf("valid=%d, invalid=%d, unknown=%d\n", result->valid_count, result->invalid_count, result->unknown_signer_count); - - // Tidy up - //if (armoured) - // ops_reader_pop_dearmour(pinfo); - - ops_teardown_memory_read(pinfo, mem); - - ops_boolean_t res = validate_result_status(result); - ops_validate_result_free(result) ; - - if(validate_arg.literal_data_body.data != NULL) free(validate_arg.literal_data_body.data) ; - if(validate_arg.signed_cleartext_body.data != NULL) free(validate_arg.signed_cleartext_body.data) ; - - return res ; -} - -// eof diff --git a/openpgpsdk/src/openpgpsdk/validate.h b/openpgpsdk/src/openpgpsdk/validate.h deleted file mode 100644 index a078b7916..000000000 --- a/openpgpsdk/src/openpgpsdk/validate.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -typedef struct - { - unsigned int valid_count; - ops_signature_info_t * valid_sigs; - unsigned int invalid_count; - ops_signature_info_t * invalid_sigs; - unsigned int unknown_signer_count; - ops_signature_info_t * unknown_sigs; - } ops_validate_result_t; - -void ops_validate_result_free(ops_validate_result_t *result); - -ops_boolean_t ops_validate_key_signatures(ops_validate_result_t *result, - const ops_keydata_t* keydata, - const ops_keyring_t *ring, - ops_parse_cb_return_t cb (const ops_parser_content_t *, ops_parse_cb_info_t *)); -ops_boolean_t ops_validate_all_signatures(ops_validate_result_t *result, - const ops_keyring_t *ring, - ops_parse_cb_return_t (const ops_parser_content_t *, ops_parse_cb_info_t *)); - -void ops_keydata_reader_set(ops_parse_info_t *pinfo, - const ops_keydata_t *key); - -typedef struct - { - const ops_keydata_t *key; - unsigned packet; - unsigned offset; - } validate_reader_arg_t; - -/** Struct used with the validate_key_cb callback */ -typedef struct - { - ops_public_key_t pkey; - ops_public_key_t subkey; - ops_secret_key_t skey; - enum - { - ATTRIBUTE=1, - ID, - } last_seen; - ops_user_id_t user_id; - ops_user_attribute_t user_attribute; - unsigned char hash[OPS_MAX_HASH_SIZE]; - const ops_keyring_t *keyring; - validate_reader_arg_t *rarg; - ops_validate_result_t *result; - ops_parse_cb_return_t (*cb_get_passphrase) (const ops_parser_content_t *, ops_parse_cb_info_t *); - } validate_key_cb_arg_t; - -/** Struct use with the validate_data_cb callback */ -typedef struct validate_data_cb_arg - { - enum - { - LITERAL_DATA, - SIGNED_CLEARTEXT - } use; /* - -#include -#include -#include -#include -#include -#include -#include "keyring_local.h" -#include -#include -#include -#include -#include -#include -#ifndef WIN32 -#include -#endif - -#include - -//static int debug=0; - -/* - * return true if OK, otherwise false - */ -static ops_boolean_t base_write(const void *src,unsigned length, - ops_create_info_t *info) - { - return info->winfo.writer(src,length,&info->errors,&info->winfo); - } - -/** - * \ingroup Core_WritePackets - * - * \param src - * \param length - * \param info - * \return 1 if OK, otherwise 0 - */ - -ops_boolean_t ops_write(const void *src,unsigned length, - ops_create_info_t *info) - { - return base_write(src,length,info); - } - -/** - * \ingroup Core_WritePackets - * \param n - * \param length - * \param info - * \return ops_true if OK, otherwise ops_false - */ - -ops_boolean_t ops_write_scalar(unsigned n,unsigned length, - ops_create_info_t *info) - { - while(length-- > 0) - { - unsigned char c[1]; - - c[0]=n >> (length*8); - if(!base_write(c,1,info)) - return ops_false; - } - return ops_true; - } - -/** - * \ingroup Core_WritePackets - * \param bn - * \param info - * \return 1 if OK, otherwise 0 - */ - -ops_boolean_t ops_write_mpi(const BIGNUM *bn,ops_create_info_t *info) - { - unsigned char buf[8192]; - int bits=BN_num_bits(bn); - - assert(bits <= 65535); - BN_bn2bin(bn,buf); - return ops_write_scalar(bits,2,info) - && ops_write(buf,(bits+7)/8,info); - } - -/** - * \ingroup Core_WritePackets - * \param tag - * \param info - * \return 1 if OK, otherwise 0 - */ - -ops_boolean_t ops_write_ptag(ops_content_tag_t tag,ops_create_info_t *info) - { - unsigned char c[1]; - - c[0]=tag|OPS_PTAG_ALWAYS_SET|OPS_PTAG_NEW_FORMAT; - - return base_write(c,1,info); - } - -/** - * \ingroup Core_WritePackets - * \param length - * \param info - * \return 1 if OK, otherwise 0 - */ - -ops_boolean_t ops_write_length(unsigned length,ops_create_info_t *info) - { - unsigned char c[2]; - - if(length < 192) - { - c[0]=length; - return base_write(c,1,info); - } - else if(length < 8384) - { - c[0]=((length-192) >> 8)+192; - c[1]=(length-192)%256; - return base_write(c,2,info); - } - return ops_write_scalar(0xff,1,info) && ops_write_scalar(length,4,info); - } - -/* Note that we finalise from the top down, so we don't use writers below - * that have already been finalised - */ -ops_boolean_t writer_info_finalise(ops_error_t **errors, - ops_writer_info_t *winfo) - { - ops_boolean_t ret=ops_true; - - if(winfo->finaliser) - { - ret=winfo->finaliser(errors,winfo); - winfo->finaliser=NULL; - } - if(winfo->next && !writer_info_finalise(errors,winfo->next)) - { - winfo->finaliser=NULL; - return ops_false; - } - return ret; - } - -void writer_info_delete(ops_writer_info_t *winfo) - { - // we should have finalised before deleting - assert(!winfo->finaliser); - if(winfo->next) - { - writer_info_delete(winfo->next); - free(winfo->next); - winfo->next=NULL; - } - if(winfo->destroyer) - { - winfo->destroyer(winfo); - winfo->destroyer=NULL; - } - winfo->writer=NULL; - } - -/** - * \ingroup Core_Writers - * - * Set a writer in info. There should not be another writer set. - * - * \param info The info structure - * \param writer - * \param finaliser - * \param destroyer - * \param arg The argument for the writer and destroyer - */ -void ops_writer_set(ops_create_info_t *info, - ops_writer_t *writer, - ops_writer_finaliser_t *finaliser, - ops_writer_destroyer_t *destroyer, - void *arg) - { - assert(!info->winfo.writer); - info->winfo.writer=writer; - info->winfo.finaliser=finaliser; - info->winfo.destroyer=destroyer; - info->winfo.arg=arg; - } - -/** - * \ingroup Core_Writers - * - * Push a writer in info. There must already be another writer set. - * - * \param info The info structure - * \param writer - * \param finaliser - * \param destroyer - * \param arg The argument for the writer and destroyer - */ -void ops_writer_push(ops_create_info_t *info, - ops_writer_t *writer, - ops_writer_finaliser_t *finaliser, - ops_writer_destroyer_t *destroyer, - void *arg) - { - ops_writer_info_t *copy=ops_mallocz(sizeof *copy); - - assert(info->winfo.writer); - *copy=info->winfo; - info->winfo.next=copy; - - info->winfo.writer=writer; - info->winfo.finaliser=finaliser; - info->winfo.destroyer=destroyer; - info->winfo.arg=arg; - } - -void ops_writer_pop(ops_create_info_t *info) - { - ops_writer_info_t *next; - - // Make sure the finaliser has been called. - assert(!info->winfo.finaliser); - // Make sure this is a stacked writer - assert(info->winfo.next); - if(info->winfo.destroyer) - info->winfo.destroyer(&info->winfo); - - next=info->winfo.next; - info->winfo=*next; - - free(next); - } - -/** - * \ingroup Core_Writers - * - * Close the writer currently set in info. - * - * \param info The info structure - */ -ops_boolean_t ops_writer_close(ops_create_info_t *info) - { - ops_boolean_t ret=writer_info_finalise(&info->errors,&info->winfo); - - writer_info_delete(&info->winfo); - - return ret; - } - -/** - * \ingroup Core_Writers - * - * Get the arg supplied to ops_create_info_set_writer(). - * - * \param winfo The writer_info structure - * \return The arg - */ -void *ops_writer_get_arg(ops_writer_info_t *winfo) - { return winfo->arg; } - -/** - * \ingroup Core_Writers - * - * Write to the next writer down in the stack. - * - * \param src The data to write. - * \param length The length of src. - * \param errors A place to store errors. - * \param winfo The writer_info structure. - * \return Success - if ops_false, then errors should contain the error. - */ -ops_boolean_t ops_stacked_write(const void *src,unsigned length, - ops_error_t **errors,ops_writer_info_t *winfo) - { - return winfo->next->writer(src,length,errors,winfo->next); - } - -/** - * \ingroup Core_Writers - * - * Free the arg. Many writers just have a malloc()ed lump of storage, this - * function releases it. - * - * \param winfo the info structure. - */ -void ops_writer_generic_destroyer(ops_writer_info_t *winfo) - { free(ops_writer_get_arg(winfo)); } - -/** - * \ingroup Core_Writers - * - * A writer that just writes to the next one down. Useful for when you - * want to insert just a finaliser into the stack. - */ -ops_boolean_t ops_writer_passthrough(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { return ops_stacked_write(src,length,errors,winfo); } - - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer.h b/openpgpsdk/src/openpgpsdk/writer.h deleted file mode 100644 index 2b15c8206..000000000 --- a/openpgpsdk/src/openpgpsdk/writer.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#ifndef OPS_WRITER_H -#define OPS_WRITER_H - -#include "types.h" -#include "packet.h" -#include "crypto.h" -#include "memory.h" -#include "errors.h" -#include "keyring.h" - -/** - * \ingroup Create - * This struct contains the required information about one writer - */ -/** - * \ingroup Writer - * the writer function prototype - */ - -typedef struct ops_writer_info ops_writer_info_t; -typedef ops_boolean_t ops_writer_t(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo); -typedef ops_boolean_t ops_writer_finaliser_t(ops_error_t **errors, - ops_writer_info_t *winfo); -typedef void ops_writer_destroyer_t(ops_writer_info_t *winfo); -/** Writer settings */ -struct ops_writer_info - { - ops_writer_t *writer; /*!< the writer itself */ - ops_writer_finaliser_t *finaliser; /*!< the writer's finaliser */ - ops_writer_destroyer_t *destroyer; /*!< the writer's destroyer */ - void *arg; /* writer-specific argument */ - ops_writer_info_t *next; /*!< next writer in the stack */ - }; - - -void *ops_writer_get_arg(ops_writer_info_t *winfo); -ops_boolean_t ops_stacked_write(const void *src,unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo); - -void ops_writer_set(ops_create_info_t *info, - ops_writer_t *writer, - ops_writer_finaliser_t *finaliser, - ops_writer_destroyer_t *destroyer, - void *arg); -void ops_writer_push(ops_create_info_t *info, - ops_writer_t *writer, - ops_writer_finaliser_t *finaliser, - ops_writer_destroyer_t *destroyer, - void *arg); -void ops_writer_pop(ops_create_info_t *info); -void ops_writer_generic_destroyer(ops_writer_info_t *winfo); -ops_boolean_t ops_writer_passthrough(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo); - -void ops_writer_set_fd(ops_create_info_t *info,int fd); -ops_boolean_t ops_writer_close(ops_create_info_t *info); - -ops_boolean_t ops_write(const void *src,unsigned length, - ops_create_info_t *opt); -ops_boolean_t ops_write_length(unsigned length,ops_create_info_t *opt); -ops_boolean_t ops_write_ptag(ops_content_tag_t tag,ops_create_info_t *opt); -ops_boolean_t ops_write_scalar(unsigned n,unsigned length, - ops_create_info_t *opt); -ops_boolean_t ops_write_mpi(const BIGNUM *bn,ops_create_info_t *opt); -ops_boolean_t ops_write_encrypted_mpi(const BIGNUM *bn, ops_crypt_t* crypt, ops_create_info_t *info); - -void writer_info_delete(ops_writer_info_t *winfo); -ops_boolean_t writer_info_finalise(ops_error_t **errors, ops_writer_info_t *winfo); - -#endif diff --git a/openpgpsdk/src/openpgpsdk/writer_armour.c b/openpgpsdk/src/openpgpsdk/writer_armour.c deleted file mode 100644 index cd828e6a6..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_armour.c +++ /dev/null @@ -1,517 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include - -#include -#include -#include -#include - -#include - -static int debug=0; - -#define LINE_LENGTH 64 - -static const char newline[] = "\r\n"; - -/** - * \struct dash_escaped_arg_t - */ -typedef struct - { - ops_boolean_t seen_nl:1; - ops_boolean_t seen_cr:1; - ops_create_signature_t *sig; - ops_memory_t *trailing; - } dash_escaped_arg_t; - -static ops_boolean_t dash_escaped_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - dash_escaped_arg_t *arg=ops_writer_get_arg(winfo); - unsigned n; - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"dash_escaped_writer writing %d:\n", length); - for (i=0; iseen_nl) - { - if(src[n] == '-' && !ops_stacked_write("- ",2,errors,winfo)) - return ops_false; - arg->seen_nl=ops_false; - } - - arg->seen_nl=src[n] == '\n'; - - if(arg->seen_nl && !arg->seen_cr) - { - if(!ops_stacked_write("\r",1,errors,winfo)) - return ops_false; - ops_signature_add_data(arg->sig,"\r",1); - } - - arg->seen_cr=src[n] == '\r'; - - if(!ops_stacked_write(&src[n],1,errors,winfo)) - return ops_false; - - /* trailing whitespace isn't included in the signature */ - if(src[n] == ' ' || src[n] == '\t') - ops_memory_add(arg->trailing,&src[n],1); - else - { - if((l=ops_memory_get_length(arg->trailing))) - { - if(!arg->seen_nl && !arg->seen_cr) - ops_signature_add_data(arg->sig, - ops_memory_get_data(arg->trailing), - l); - ops_memory_clear(arg->trailing); - } - ops_signature_add_data(arg->sig,&src[n],1); - } - } - - return ops_true; - } - -/** - * \param winfo - */ -static void dash_escaped_destroyer(ops_writer_info_t *winfo) - { - dash_escaped_arg_t *arg=ops_writer_get_arg(winfo); - - ops_memory_free(arg->trailing); - free(arg); - } - -/** - * \ingroup Core_WritersNext - * \brief Push Clearsigned Writer onto stack - * \param info - * \param sig - */ -ops_boolean_t ops_writer_push_clearsigned(ops_create_info_t *info, - ops_create_signature_t *sig) - { - static char header[]="-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "; - const char *hash=ops_text_from_hash(ops_signature_get_hash(sig)); - dash_escaped_arg_t *arg=ops_mallocz(sizeof *arg); - - ops_boolean_t rtn; - - rtn= ( ops_write(header,sizeof header-1,info) - && ops_write(hash,strlen(hash),info) - && ops_write("\r\n\r\n",4,info)); - - if (rtn==ops_false) - { - OPS_ERROR(&info->errors, OPS_E_W, "Error pushing clearsigned header"); - free(arg); - return rtn; - } - - arg->seen_nl=ops_true; - arg->sig=sig; - arg->trailing=ops_memory_new(); - ops_writer_push(info,dash_escaped_writer,NULL,dash_escaped_destroyer,arg); - return rtn; - } - - -/** - * \struct base64_arg_t - */ -typedef struct - { - size_t chars_written; - ops_boolean_t writing_trailer; - unsigned pos; - unsigned char t; - unsigned checksum; - } base64_arg_t; - -static char b64map[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" -"0123456789+/"; - -static ops_boolean_t check_newline(base64_arg_t* arg, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - arg->chars_written++; - if (!arg->writing_trailer && arg->chars_written % LINE_LENGTH == 0) - if (!ops_stacked_write(newline, strlen(newline), errors, winfo)) - return ops_false; - return ops_true; - } - -static ops_boolean_t base64_writer(const unsigned char *src, - unsigned length,ops_error_t **errors, - ops_writer_info_t *winfo) - { - base64_arg_t *arg=ops_writer_get_arg(winfo); - unsigned n; - - for(n=0 ; n < length ; ) - { - arg->checksum=ops_crc24(arg->checksum,src[n]); - if(arg->pos == 0) - { - /* XXXXXX00 00000000 00000000 */ - if(!ops_stacked_write(&b64map[src[n] >> 2],1,errors,winfo)) - return ops_false; - - /* 000000XX xxxx0000 00000000 */ - arg->t=(src[n++]&3) << 4; - arg->pos=1; - } - else if(arg->pos == 1) - { - /* 000000xx XXXX0000 00000000 */ - arg->t+=src[n] >> 4; - if(!ops_stacked_write(&b64map[arg->t],1,errors,winfo)) - return ops_false; - - /* 00000000 0000XXXX xx000000 */ - arg->t=(src[n++]&0xf) << 2; - arg->pos=2; - } - else if(arg->pos == 2) - { - /* 00000000 0000xxxx XX000000 */ - arg->t+=src[n] >> 6; - if(!ops_stacked_write(&b64map[arg->t],1,errors,winfo)) - return ops_false; - if(!check_newline(arg, errors, winfo)) - return ops_false; - - /* 00000000 00000000 00XXXXXX */ - if(!ops_stacked_write(&b64map[src[n++]&0x3f],1,errors,winfo)) - return ops_false; - - arg->pos=0; - } - if (!check_newline(arg, errors, winfo)) - return ops_false; - } - return ops_true; - } - -static ops_boolean_t signature_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - base64_arg_t *arg=ops_writer_get_arg(winfo); - static char trailer[]="\r\n-----END PGP SIGNATURE-----\r\n"; - unsigned char c[3]; - - if(arg->pos) - { - if(!ops_stacked_write(&b64map[arg->t],1,errors,winfo)) - return ops_false; - if(arg->pos == 1 && !ops_stacked_write("==",2,errors,winfo)) - return ops_false; - if(arg->pos == 2 && !ops_stacked_write("=",1,errors,winfo)) - return ops_false; - } - /* Ready for the checksum */ - if(!ops_stacked_write("\r\n=",3,errors,winfo)) - return ops_false; - - arg->pos=0; /* get ready to write the checksum */ - - c[0]=arg->checksum >> 16; - c[1]=arg->checksum >> 8; - c[2]=arg->checksum; - /* push the checksum through our own writer. Turn off the - writing_body flag so we don't put a newline in the trailer. - */ - arg->writing_trailer = ops_true; - if(!base64_writer(c,3,errors,winfo)) - return ops_false; - - return ops_stacked_write(trailer,sizeof trailer-1,errors,winfo); - } - -/** - * \struct linebreak_arg_t - */ -typedef struct - { - unsigned pos; - } linebreak_arg_t; - -#define BREAKPOS 65 - -static ops_boolean_t linebreak_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - linebreak_arg_t *arg=ops_writer_get_arg(winfo); - unsigned n; - - for(n=0 ; n < length ; ++n,++arg->pos) - { - if(src[n] == '\r' || src[n] == '\n') - arg->pos=0; - - if(arg->pos == BREAKPOS) - { - if(!ops_stacked_write(newline,strlen(newline),errors,winfo)) - return ops_false; - arg->pos=0; - } - if(!ops_stacked_write(&src[n],1,errors,winfo)) - return ops_false; - } - - return ops_true; - } - -/** - * \ingroup Core_WritersNext - * \brief Push armoured signature on stack - * \param info - */ -ops_boolean_t ops_writer_switch_to_armoured_signature(ops_create_info_t *info) - { - static char header[]="\r\n-----BEGIN PGP SIGNATURE-----\r\nVersion: " - OPS_VERSION_STRING "\r\n\r\n"; - base64_arg_t *base64; - - ops_writer_pop(info); - if (ops_write(header,sizeof header-1,info)==ops_false) - { - OPS_ERROR(&info->errors, OPS_E_W, "Error switching to armoured signature"); - return ops_false; - } - - ops_writer_push(info,linebreak_writer,NULL,ops_writer_generic_destroyer, - ops_mallocz(sizeof(linebreak_arg_t))); - - base64=ops_mallocz(sizeof *base64); - if (!base64) - { - OPS_MEMORY_ERROR(&info->errors); - return ops_false; - } - base64->checksum=CRC24_INIT; - ops_writer_push(info,base64_writer,signature_finaliser, - ops_writer_generic_destroyer,base64); - return ops_true; - } - -static ops_boolean_t armoured_message_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - // TODO: This is same as signature_finaliser apart from trailer. - base64_arg_t *arg=ops_writer_get_arg(winfo); - static char trailer[]="\r\n-----END PGP MESSAGE-----\r\n"; - unsigned char c[3]; - - if(arg->pos) - { - if(!ops_stacked_write(&b64map[arg->t],1,errors,winfo)) - return ops_false; - if(arg->pos == 1 && !ops_stacked_write("==",2,errors,winfo)) - return ops_false; - if(arg->pos == 2 && !ops_stacked_write("=",1,errors,winfo)) - return ops_false; - } - /* Ready for the checksum */ - if(!ops_stacked_write("\r\n=",3,errors,winfo)) - return ops_false; - - arg->pos=0; /* get ready to write the checksum */ - - c[0]=arg->checksum >> 16; - c[1]=arg->checksum >> 8; - c[2]=arg->checksum; - /* push the checksum through our own writer. Turn off the - writing_body flag so we don't put a newline in the trailer. - */ - arg->writing_trailer = ops_true; - if(!base64_writer(c,3,errors,winfo)) - return ops_false; - - return ops_stacked_write(trailer,sizeof trailer-1,errors,winfo); - } - -/** - \ingroup Core_WritersNext - \brief Write a PGP MESSAGE - \todo replace with generic function -*/ -void ops_writer_push_armoured_message(ops_create_info_t *info) -// ops_create_signature_t *sig) - { - static char header[]="-----BEGIN PGP MESSAGE-----\r\n"; - - base64_arg_t *base64; - - ops_write(header,sizeof header-1,info); - ops_write(newline,strlen(newline),info); - base64=ops_mallocz(sizeof *base64); - base64->checksum=CRC24_INIT; - ops_writer_push(info,base64_writer,armoured_message_finaliser,ops_writer_generic_destroyer,base64); - } - -static ops_boolean_t armoured_finaliser(ops_armor_type_t type, ops_error_t **errors, - ops_writer_info_t *winfo) - { - static char tail_public_key[]="\r\n-----END PGP PUBLIC KEY BLOCK-----\r\n"; - static char tail_private_key[]="\r\n-----END PGP PRIVATE KEY BLOCK-----\r\n"; - - char* tail=NULL; - unsigned int sz_tail=0; - - switch(type) - { - case OPS_PGP_PUBLIC_KEY_BLOCK: - tail=tail_public_key; - sz_tail=sizeof tail_public_key-1; - break; - - case OPS_PGP_PRIVATE_KEY_BLOCK: - tail=tail_private_key; - sz_tail=sizeof tail_private_key-1; - break; - - default: - assert(0); - } - - base64_arg_t *arg=ops_writer_get_arg(winfo); - unsigned char c[3]; - - if(arg->pos) - { - if(!ops_stacked_write(&b64map[arg->t],1,errors,winfo)) - return ops_false; - if(arg->pos == 1 && !ops_stacked_write("==",2,errors,winfo)) - return ops_false; - if(arg->pos == 2 && !ops_stacked_write("=",1,errors,winfo)) - return ops_false; - } - - /* Ready for the checksum */ - if(!ops_stacked_write("\r\n=",3,errors,winfo)) - return ops_false; - - arg->pos=0; /* get ready to write the checksum */ - - c[0]=arg->checksum >> 16; - c[1]=arg->checksum >> 8; - c[2]=arg->checksum; - /* push the checksum through our own writer. Turn off the - writing_body flag so we don't put a newline in the trailer. - */ - arg->writing_trailer = ops_true; - if(!base64_writer(c,3,errors,winfo)) - return ops_false; - - return ops_stacked_write(tail,sz_tail,errors,winfo); - } - -static ops_boolean_t armoured_public_key_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - return armoured_finaliser(OPS_PGP_PUBLIC_KEY_BLOCK,errors,winfo); - } - -static ops_boolean_t armoured_private_key_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - return armoured_finaliser(OPS_PGP_PRIVATE_KEY_BLOCK,errors,winfo); - } - -// \todo use this for other armoured types -/** - \ingroup Core_WritersNext - \brief Push Armoured Writer on stack (generic) -*/ -void ops_writer_push_armoured(ops_create_info_t *info, ops_armor_type_t type) - { - static char hdr_public_key[]="-----BEGIN PGP PUBLIC KEY BLOCK-----\r\nVersion: " - OPS_VERSION_STRING "\r\n\r\n"; - static char hdr_private_key[]="-----BEGIN PGP PRIVATE KEY BLOCK-----\r\nVersion: " - OPS_VERSION_STRING "\r\n\r\n"; - - char* header=NULL; - unsigned int sz_hdr=0; - ops_boolean_t (* finaliser)(ops_error_t **errors, ops_writer_info_t *winfo); - - switch(type) - { - case OPS_PGP_PUBLIC_KEY_BLOCK: - header=hdr_public_key; - sz_hdr=sizeof hdr_public_key-1; - finaliser=armoured_public_key_finaliser; - break; - - case OPS_PGP_PRIVATE_KEY_BLOCK: - header=hdr_private_key; - sz_hdr=sizeof hdr_private_key-1; - finaliser=armoured_private_key_finaliser; - break; - - default: - assert(0); - } - - ops_write(header,sz_hdr,info); - - ops_writer_push(info,linebreak_writer,NULL,ops_writer_generic_destroyer, - ops_mallocz(sizeof(linebreak_arg_t))); - - base64_arg_t *arg=ops_mallocz(sizeof *arg); - arg->checksum=CRC24_INIT; - ops_writer_push(info,base64_writer,finaliser,ops_writer_generic_destroyer,arg); - } - - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_armoured.h b/openpgpsdk/src/openpgpsdk/writer_armoured.h deleted file mode 100644 index bf81141b8..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_armoured.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -ops_boolean_t ops_writer_push_clearsigned(ops_create_info_t *info, - ops_create_signature_t *sig); -void ops_writer_push_armoured_message(ops_create_info_t *info); -ops_boolean_t ops_writer_switch_to_armoured_signature(ops_create_info_t *info); - -void ops_writer_push_armoured(ops_create_info_t *info, ops_armor_type_t type); - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_encrypt.c b/openpgpsdk/src/openpgpsdk/writer_encrypt.c deleted file mode 100644 index 4224fca42..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_encrypt.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include - -static int debug=0; - -typedef struct - { - ops_crypt_t* crypt; - int free_crypt; - } crypt_arg_t; - -/* - * This writer simply takes plaintext as input, - * encrypts it with the given key - * and outputs the resulting encrypted text - */ -static ops_boolean_t encrypt_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - -#define BUFSZ 1024 // arbitrary number - unsigned char encbuf[BUFSZ]; - unsigned remaining=length; - unsigned done=0; - - crypt_arg_t *arg=(crypt_arg_t *)ops_writer_get_arg(winfo); - - if (!ops_is_sa_supported(arg->crypt->algorithm)) - assert(0); // \todo proper error handling - - while (remaining) - { - unsigned len = remaining < BUFSZ ? remaining : BUFSZ; - // memcpy(buf,src,len); // \todo copy needed here? - - arg->crypt->cfb_encrypt(arg->crypt, encbuf, src+done, len); - - if (debug) - { - int i=0; - fprintf(stderr,"WRITING:\nunencrypted: "); - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", src[done+i]); - fprintf(stderr,"\n"); - fprintf(stderr,"encrypted: "); - for (i=0; i<16; i++) - fprintf(stderr,"%2x ", encbuf[i]); - fprintf(stderr,"\n"); - } - - if (!ops_stacked_write(encbuf,len,errors,winfo)) - { - if (debug) - { fprintf(stderr, "encrypted_writer got error from stacked write, returning\n"); } - return ops_false; - } - remaining-=len; - done+=len; - } - - return ops_true; - } - -static void encrypt_destroyer (ops_writer_info_t *winfo) - - { - crypt_arg_t *arg=(crypt_arg_t *)ops_writer_get_arg(winfo); - if (arg->free_crypt) - free(arg->crypt); - free (arg); - } - -/** -\ingroup Core_WritersNext -\brief Push Encrypted Writer onto stack (create SE packets) -*/ -void ops_writer_push_encrypt_crypt(ops_create_info_t *cinfo, - ops_crypt_t *crypt) - { - // Create arg to be used with this writer - // Remember to free this in the destroyer - - crypt_arg_t *arg=ops_mallocz(sizeof *arg); - - // Setup the arg - - arg->crypt=crypt; - arg->free_crypt=0; - - // And push writer on stack - ops_writer_push(cinfo,encrypt_writer,NULL,encrypt_destroyer,arg); - - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_encrypt_se_ip.c b/openpgpsdk/src/openpgpsdk/writer_encrypt_se_ip.c deleted file mode 100644 index 0c1b2c78d..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_encrypt_se_ip.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include - -#ifndef WIN32 - #include -#endif - -#include - -#include "keyring_local.h" -#include -#include -#include -#include -#include -#include - -static int debug=0; - -typedef struct - { - ops_crypt_t* crypt; - } encrypt_se_ip_arg_t; - -static ops_boolean_t encrypt_se_ip_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo); -static void encrypt_se_ip_destroyer(ops_writer_info_t *winfo); - -// - -/** -\ingroup Core_WritersNext -\brief Push Encrypted SE IP Writer onto stack -*/ -void ops_writer_push_encrypt_se_ip(ops_create_info_t *cinfo, - const ops_keydata_t *pub_key) - { - ops_crypt_t *encrypt; - unsigned char *iv=NULL; - - // Create arg to be used with this writer - // Remember to free this in the destroyer - encrypt_se_ip_arg_t *arg=ops_mallocz(sizeof *arg); - - // Create and write encrypted PK session key - ops_pk_session_key_t *encrypted_pk_session_key; - encrypted_pk_session_key=ops_create_pk_session_key(pub_key); - ops_write_pk_session_key(cinfo, encrypted_pk_session_key); - - // Setup the arg - encrypt=ops_mallocz(sizeof *encrypt); - ops_crypt_any(encrypt, encrypted_pk_session_key->symmetric_algorithm); - iv=ops_mallocz(encrypt->blocksize); - encrypt->set_iv(encrypt, iv); - encrypt->set_key(encrypt, &encrypted_pk_session_key->key[0]); - ops_encrypt_init(encrypt); - - arg->crypt=encrypt; - - // And push writer on stack - ops_writer_push(cinfo, encrypt_se_ip_writer, NULL, encrypt_se_ip_destroyer, - arg); - // tidy up - ops_pk_session_key_free(encrypted_pk_session_key); - free(encrypted_pk_session_key); - free(iv); - } - -static ops_boolean_t encrypt_se_ip_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - encrypt_se_ip_arg_t *arg=ops_writer_get_arg(winfo); - - ops_boolean_t rtn=ops_true; - - ops_memory_t *mem_literal; - ops_create_info_t *cinfo_literal; - - ops_memory_t *mem_compressed; - ops_create_info_t *cinfo_compressed; - - ops_memory_t *my_mem; - ops_create_info_t *my_cinfo; - - const unsigned int bufsz=128; // initial value; gets expanded as necessary - ops_setup_memory_write(&cinfo_literal, &mem_literal, bufsz); - ops_setup_memory_write(&cinfo_compressed, &mem_compressed, bufsz); - ops_setup_memory_write(&my_cinfo, &my_mem, bufsz); - - // create literal data packet from source data - ops_write_literal_data_from_buf(src, length, OPS_LDT_BINARY, cinfo_literal); - assert(ops_memory_get_length(mem_literal) > length); - - // create compressed packet from literal data packet - ops_write_compressed(ops_memory_get_data(mem_literal), - ops_memory_get_length(mem_literal), - cinfo_compressed); - - // create SE IP packet set from this compressed literal data - ops_write_se_ip_pktset(ops_memory_get_data(mem_compressed), - ops_memory_get_length(mem_compressed), - arg->crypt, my_cinfo); - assert(ops_memory_get_length(my_mem) - > ops_memory_get_length(mem_compressed)); - - // now write memory to next writer - rtn=ops_stacked_write(ops_memory_get_data(my_mem), - ops_memory_get_length(my_mem), - errors, winfo); - - ops_memory_free(my_mem); - ops_memory_free(mem_compressed); - ops_memory_free(mem_literal); - - return rtn; - } - -static void encrypt_se_ip_destroyer (ops_writer_info_t *winfo) - - { - encrypt_se_ip_arg_t *arg=ops_writer_get_arg(winfo); - - free(arg->crypt); - free(arg); - } - -ops_boolean_t ops_write_se_ip_pktset(const unsigned char *data, - const unsigned int len, - ops_crypt_t *crypt, - ops_create_info_t *cinfo) - { - unsigned char hashed[SHA_DIGEST_LENGTH]; - const size_t sz_mdc=1+1+SHA_DIGEST_LENGTH; - - size_t sz_preamble=crypt->blocksize+2; - unsigned char* preamble=ops_mallocz(sz_preamble); - - size_t sz_buf=sz_preamble+len+sz_mdc; - - ops_memory_t *mem_mdc; - ops_create_info_t *cinfo_mdc; - - if (!ops_write_ptag(OPS_PTAG_CT_SE_IP_DATA, cinfo) - || !ops_write_length(1+sz_buf, cinfo) - || !ops_write_scalar(SE_IP_DATA_VERSION, 1, cinfo)) - { - free (preamble); - return 0; - } - - ops_random(preamble, crypt->blocksize); - preamble[crypt->blocksize]=preamble[crypt->blocksize-2]; - preamble[crypt->blocksize+1]=preamble[crypt->blocksize-1]; - - if (debug) - { - unsigned int i=0; - fprintf(stderr,"\npreamble: "); - for (i=0; i -#include -#include -#endif - -#include - -#include - -typedef struct - { - int fd; - } writer_fd_arg_t; - -static ops_boolean_t fd_writer(const unsigned char *src,unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - writer_fd_arg_t *arg=ops_writer_get_arg(winfo); - int n=write(arg->fd,src,length); - - if(n == -1) - { - OPS_SYSTEM_ERROR_1(errors,OPS_E_W_WRITE_FAILED,"write", - "file descriptor %d",arg->fd); - return ops_false; - } - - if((unsigned)n != length) - { - OPS_ERROR_1(errors,OPS_E_W_WRITE_TOO_SHORT, - "file descriptor %d",arg->fd); - return ops_false; - } - - return ops_true; - } - -static void fd_destroyer(ops_writer_info_t *winfo) - { - free(ops_writer_get_arg(winfo)); - } - -/** - * \ingroup Core_WritersFirst - * \brief Write to a File - * - * Set the writer in info to be a stock writer that writes to a file - * descriptor. If another writer has already been set, then that is - * first destroyed. - * - * \param info The info structure - * \param fd The file descriptor - * - */ - -void ops_writer_set_fd(ops_create_info_t *info,int fd) - { - writer_fd_arg_t *arg=malloc(sizeof *arg); - - arg->fd=fd; - ops_writer_set(info,fd_writer,NULL,fd_destroyer,arg); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_literal.c b/openpgpsdk/src/openpgpsdk/writer_literal.c deleted file mode 100644 index 64b3f650c..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_literal.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh. - * The Contributors have asserted their moral rights under the - * UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** Writes a literal data packet, using the partial data length encoding. - */ - -#include -#include - -#ifndef WIN32 -#include -#endif - -#include -#include -#include - -//#define MIN_PARTIAL_DATA_LENGTH 512 // now defined in partial.h -#define MAX_PARTIAL_DATA_LENGTH 1073741824 - - -ops_boolean_t write_literal_header(ops_create_info_t *info, - void *header_data) - { - OPS_USED(header_data); - // \todo add the literal type as a header_data argument - // \todo add filename - // \todo add date - // \todo do we need to check text data for line endings ? - - ops_write_scalar(OPS_LDT_BINARY, 1, info); // data type - ops_write_scalar(0, 1, info); // Filename (length = 0) - ops_write_scalar(0, 4, info); // Date (unspecified) - return ops_true; - } - -/** - * \ingroup InternalAPI - * \brief Pushes a literal writer onto the stack. - * \param cinfo the writer info - * \param buf_size the size of the internal buffer. For best - * throughput, write data in multiples of buf_size - */ -void ops_writer_push_literal_with_opts(ops_create_info_t *cinfo, - unsigned int buf_size) - { - // The literal writer doesn't need to transform the data, so we just - // push a partial packet writer onto the stack. This will handle - // the packet length encoding. All we need to provide is a function - // to write the header. - ops_writer_push_partial(buf_size, cinfo, OPS_PTAG_CT_LITERAL_DATA, - write_literal_header, NULL); - -} - -/** - * \ingroup InternalAPI - * \brief Pushes a literal writer onto the stack. - * \param cinfo the writer info - */ -void ops_writer_push_literal(ops_create_info_t *cinfo) - { - ops_writer_push_literal_with_opts(cinfo, 0); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_memory.c b/openpgpsdk/src/openpgpsdk/writer_memory.c deleted file mode 100644 index 0c8fa57c4..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_memory.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include -#include -#include - -#include - -static ops_boolean_t memory_writer(const unsigned char *src,unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - ops_memory_t *mem=ops_writer_get_arg(winfo); - - OPS_USED(errors); - ops_memory_add(mem,src,length); - return ops_true; - } - -/** - * \ingroup Core_WritersFirst - * \brief Write to memory - * - * Set a memory writer. - * - * \param info The info structure - * \param mem The memory structure - * \note It is the caller's responsiblity to call ops_memory_free(mem) - * \sa ops_memory_free() - */ - -void ops_writer_set_memory(ops_create_info_t *info,ops_memory_t *mem) - { - ops_writer_set(info,memory_writer,NULL,NULL,mem); - } - - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_partial.c b/openpgpsdk/src/openpgpsdk/writer_partial.c deleted file mode 100644 index 9c59c27f9..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_partial.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh. - * The Contributors have asserted their moral rights under the - * UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** Writes data using a series of partial body length headers. - * (See RFC 4880 4.2.2.4). This is normally used in conjunction - * with a streaming writer of some kind that needs to write out - * data packets of unknown length. - */ - -#include -#include - -#ifndef WIN32 -#include -#endif - -#include -#include -#include -#include - -static const int debug = 0; - -#define MAX_PARTIAL_DATA_LENGTH 1073741824 - -typedef struct - { - size_t packet_size; // size of packets - ops_memory_t *buffer; // Data is buffered here until written - ops_content_tag_t tag; // Packet tag - ops_memory_t *header; // Header is written here - ops_boolean_t written_first; // Has the first packet been written? - ops_write_partial_trailer_t *trailer_fn; // Custom end-of-packet fn - void *trailer_data; // data for end-of-packet fn - } stream_partial_arg_t; - - - -static unsigned int ops_calc_partial_data_length(unsigned int len) - { - int i; - unsigned int mask = MAX_PARTIAL_DATA_LENGTH; - assert( len > 0 ); - - if (len > MAX_PARTIAL_DATA_LENGTH) - return MAX_PARTIAL_DATA_LENGTH; - - for (i = 0 ; i <= 30 ; i++) - { - if (mask & len) - break; - mask >>= 1; - } - - return mask; - } - -static ops_boolean_t ops_write_partial_data_length(unsigned int len, - ops_create_info_t *info) - { - // len must be a power of 2 from 0 to 30 - unsigned i; - unsigned char c[1]; - - for (i = 0 ; i <= 30 ; i++) - if ((len >> i) & 1) - break; - - assert((1u << i) == len); - - c[0] = 224 + i; - - return ops_write(c, 1, info); - } - -static ops_boolean_t write_partial_data(const unsigned char *data, - size_t len, - ops_create_info_t *info) - { - if (debug) - fprintf(stderr, "Writing %zu bytes\n", len); - while (len > 0) - { - size_t pdlen = ops_calc_partial_data_length(len); - ops_write_partial_data_length(pdlen, info); - ops_write(data, pdlen, info); - data += pdlen; - len -= pdlen; - } - return ops_true; - } - -static ops_boolean_t write_partial_data_first(stream_partial_arg_t *arg, - const unsigned char *data, - unsigned int len, - ops_create_info_t *info) - { - size_t header_len = ops_memory_get_length(arg->header); - - size_t sz_towrite = len + header_len; - size_t sz_pd = ops_calc_partial_data_length(sz_towrite); - size_t first_data_len = (sz_pd - header_len); - assert(sz_pd >= MIN_PARTIAL_DATA_LENGTH); - - if (debug) - fprintf(stderr, "Writing first packet of len %zu (%zu + %u)\n", - sz_towrite, header_len, len); - - // Write the packet tag, the partial size and the header, followed - // by the first chunk of data and then the remainder of the data. - // (We have to do this in two chunks, as the partial length may not - // match the number of bytes to write.) - return ops_write_ptag(arg->tag, info) && - ops_write_partial_data_length(sz_pd, info) && - ops_write(ops_memory_get_data(arg->header), header_len, info) && - ops_write(data, first_data_len, info) && - write_partial_data(data + first_data_len, len - first_data_len, info); - } - -/* - * Writes out the last packet. The length is encoded as a fixed-length - * packet. Note that even if there is no data accumulated in the - * buffer, we stil lneed to write out a packet, as the final packet in - * a partially-encoded stream must be a fixed-lngth packet. - */ -static ops_boolean_t write_partial_data_last(stream_partial_arg_t *arg, - ops_create_info_t *info) - { - size_t buffer_length = ops_memory_get_length(arg->buffer); - if (debug) - fprintf(stderr, "writing final packet of %zu bytes\n", buffer_length); - return ops_write_length(buffer_length, info) && - ops_write(ops_memory_get_data(arg->buffer), buffer_length, info); - } - -/* - * Writes out the data accumulated in the in-memory buffer. - */ -static ops_boolean_t flush_buffer(stream_partial_arg_t *arg, - ops_create_info_t *info) - { - ops_boolean_t result = ops_true; - size_t buffer_length = ops_memory_get_length(arg->buffer); - if (buffer_length > 0) - { - if (debug) - fprintf(stderr, "Flushing %zu bytes\n", buffer_length); - - result = write_partial_data(ops_memory_get_data(arg->buffer), - buffer_length, - info); - ops_memory_clear(arg->buffer); - } - return result; - } - -static ops_boolean_t stream_partial_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - stream_partial_arg_t *arg = ops_writer_get_arg(winfo); - - // For the first write operation, we need to write out the header - // plus the data. The total size that we write out must be at least - // MIN_PARTIAL_DATA_LENGTH bytes. (See RFC 4880, sec 4.2.2.4, - // Partial Body Lengths.) If we are given less than this, - // then we need to store the data in the buffer until we have the - // minumum - if (!arg->written_first) - { - ops_memory_add(arg->buffer, src, length); - size_t buffer_length = ops_memory_get_length(arg->buffer); - size_t header_length = ops_memory_get_length(arg->header); - if (header_length + buffer_length < MIN_PARTIAL_DATA_LENGTH) - { - if (debug) - fprintf(stderr, "Storing %zu (%zu + %zu) bytes\n", - header_length + buffer_length, header_length, - buffer_length); - return ops_true; // will wait for more data or end of stream - } - arg->written_first = ops_true; - - // Create a writer that will write to the parent stream. Allows - // useage of ops_write_ptag, etc. - ops_create_info_t parent_info; - ops_prepare_parent_info(&parent_info, winfo); - ops_boolean_t result = - write_partial_data_first(arg, ops_memory_get_data(arg->buffer), - buffer_length, &parent_info); - ops_memory_clear(arg->buffer); - ops_move_errors(&parent_info, errors); - return result; - } - else - { - size_t buffer_length = ops_memory_get_length(arg->buffer); - if (buffer_length + length < arg->packet_size) - { - ops_memory_add(arg->buffer, src, length); - if (debug) - fprintf(stderr, "Storing %u bytes (total %zu)\n", - length, buffer_length); - return ops_true; - } - else - { - ops_create_info_t parent_info; - parent_info.winfo = *winfo->next; - parent_info.errors = *errors; - return flush_buffer(arg, &parent_info) && - write_partial_data(src, length, &parent_info); - } - } - return ops_true; - } - -/* - * Invoked when the total packet size is less than - * MIN_PARTIAL_DATA_LENGTH. In that case, we write out the whole - * packet in a single operation, without using partial body length - * packets. - */ -static ops_boolean_t write_complete_packet(stream_partial_arg_t *arg, - ops_create_info_t *info) - { - size_t data_len = ops_memory_get_length(arg->buffer); - size_t header_len = ops_memory_get_length(arg->header); - - // Write the header tag, the length of the packet, and the - // packet. Note that the packet includes the header - // bytes. - size_t total = data_len + header_len; - if (debug) - fprintf(stderr, "writing entire packet with length %zu (%zu + %zu)\n", - total, data_len, header_len); - return ops_write_ptag(arg->tag, info) && - ops_write_length(total, info) && - ops_write(ops_memory_get_data(arg->header), header_len, info) && - ops_write(ops_memory_get_data(arg->buffer), data_len, info); - } - -static ops_boolean_t stream_partial_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - stream_partial_arg_t *arg = ops_writer_get_arg(winfo); - // write last chunk of data - - // Create a writer that will write to the parent stream. Allows - // useage of ops_write_ptag, etc. - ops_create_info_t parent_info; - ops_prepare_parent_info(&parent_info, winfo); - ops_boolean_t result; - if (!arg->written_first) - result = write_complete_packet(arg, &parent_info); - else - // finish writing - result = write_partial_data_last(arg, &parent_info); - if (result && arg->trailer_fn != NULL) - result = arg->trailer_fn(&parent_info, arg->trailer_data); - ops_move_errors(&parent_info, errors); - return result; - } - -static void stream_partial_destroyer(ops_writer_info_t *winfo) - { - stream_partial_arg_t *arg = ops_writer_get_arg(winfo); - ops_memory_free(arg->buffer); - ops_memory_free(arg->header); - free(arg); - } - -/** - * \ingroup InternalAPI - * \brief Pushes a partial packet writer onto the stack. - * - * This writer is used in conjunction with another writer that - * generates streaming data of unknown length. The partial writer - * handles the various partial body length packets. When writing the - * initial packet header, the partial writer will write out the given - * tag, write out an initial length, and then invoke the 'header' - * function to write the remainder of the header. Note that the header - * function should not write a packet tag or a length. - * - * \param packet_size the expected size of the incoming packets. Must - * be >= 512 bytes. Must be a power of 2. The partial writer - * will buffer incoming writes into packets of this size. Note - * that writes will be most efficient if done in chunks of - * packet_size. If the packet size is unknown, specify 0, and - * the default size will be used. - * \param cinfo the writer info - * \param tag the packet tag - * \param header_writer a function that writes the packet header. - * \param header_data passed into header_writer - */ -void ops_writer_push_partial(size_t packet_size, - ops_create_info_t *cinfo, - ops_content_tag_t tag, - ops_write_partial_header_t *header_writer, - void *header_data) - { - ops_writer_push_partial_with_trailer(packet_size, cinfo, tag, header_writer, - header_data, NULL, NULL); - } - -/** - * \ingroup InternalAPI - * \brief Pushes a partial packet writer onto the stack. Adds a trailer - * function that will be invoked after writing out the partial - * packet. - * - * This writer is primarily used by the signature writer, which needs - * to append a signature packet after the literal data packet. - * - * \param trailer_writer a function that writes the trailer - * \param trailer_data passed into trailer_data - * \see ops_writer_push_partial - * \see ops_writer_push_signed - */ -void ops_writer_push_partial_with_trailer( - size_t packet_size, - ops_create_info_t *cinfo, - ops_content_tag_t tag, - ops_write_partial_header_t *header_writer, - void *header_data, - ops_write_partial_trailer_t *trailer_writer, - void *trailer_data) - { - if (packet_size == 0) - packet_size = MIN_PARTIAL_DATA_LENGTH; - assert(packet_size >= MIN_PARTIAL_DATA_LENGTH); - // Verify that the packet size is a valid power of 2. - assert(ops_calc_partial_data_length(packet_size) == packet_size); - - // Create arg to be used with this writer - // Remember to free this in the destroyer - stream_partial_arg_t *arg = ops_mallocz(sizeof *arg); - arg->tag = tag; - arg->written_first = ops_false; - arg->packet_size = packet_size; - arg->buffer = ops_memory_new(); - ops_memory_init(arg->buffer, arg->packet_size); - arg->trailer_fn = trailer_writer; - arg->trailer_data = trailer_data; - - // Write out the header into the memory buffer. Later we will write - // this buffer to the underlying output stream. - ops_create_info_t *header_info; - ops_setup_memory_write(&header_info, &arg->header, 128); - header_writer(header_info, header_data); - ops_writer_close(header_info); - ops_create_info_delete(header_info); - - // And push writer on stack - ops_writer_push(cinfo, stream_partial_writer, stream_partial_finaliser, - stream_partial_destroyer, arg); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_skey_checksum.c b/openpgpsdk/src/openpgpsdk/writer_skey_checksum.c deleted file mode 100644 index 6b8a480de..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_skey_checksum.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted - * their moral rights under the UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include - -#include - -//static int debug=0; - -typedef struct - { - ops_hash_algorithm_t hash_algorithm; - ops_hash_t hash; - unsigned char *hashed; - } skey_checksum_arg_t; - -static ops_boolean_t skey_checksum_writer(const unsigned char *src, const unsigned length, ops_error_t **errors, ops_writer_info_t *winfo) - { - skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); - ops_boolean_t rtn=ops_true; - - // add contents to hash - arg->hash.add(&arg->hash, src, length); - - // write to next stacked writer - rtn=ops_stacked_write(src,length,errors,winfo); - - // tidy up and return - return rtn; - } - -static ops_boolean_t skey_checksum_finaliser(ops_error_t **errors __attribute__((unused)), ops_writer_info_t *winfo) - { - skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); - arg->hash.finish(&arg->hash, arg->hashed); - return ops_true; - } - -static void skey_checksum_destroyer(ops_writer_info_t* winfo) - { - skey_checksum_arg_t *arg=ops_writer_get_arg(winfo); - free(arg); - } - -/** -\ingroup Core_WritersNext -\param cinfo -\param skey -*/ -void ops_push_skey_checksum_writer(ops_create_info_t *cinfo, ops_secret_key_t *skey) - { - // OPS_USED(info); - // XXX: push a SHA-1 checksum writer (and change s2k to 254). - skey_checksum_arg_t *arg=ops_mallocz(sizeof *arg); - - // configure the arg - arg->hash_algorithm=skey->hash_algorithm; - arg->hashed=&skey->checkhash[0]; - - // init the hash - ops_hash_any(&arg->hash, arg->hash_algorithm); - arg->hash.init(&arg->hash); - - ops_writer_push(cinfo, skey_checksum_writer, skey_checksum_finaliser, skey_checksum_destroyer, arg); - } - -// EOF diff --git a/openpgpsdk/src/openpgpsdk/writer_stream_encrypt_se_ip.c b/openpgpsdk/src/openpgpsdk/writer_stream_encrypt_se_ip.c deleted file mode 100644 index d882e9022..000000000 --- a/openpgpsdk/src/openpgpsdk/writer_stream_encrypt_se_ip.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2005-2009 Nominet UK (www.nic.uk) - * All rights reserved. - * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh. - * The Contributors have asserted their moral rights under the - * UK Copyright Design and Patents Act 1988 to - * be recorded as the authors of this copyright work. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** \file - */ - -#include -#include - -#ifndef WIN32 -#include -#endif - -#include - -#include "keyring_local.h" -#include -#include -#include -#include -#include - -typedef struct - { - ops_crypt_t*crypt; - ops_memory_t *mem_se_ip; - ops_create_info_t *cinfo_se_ip; - ops_hash_t hash; - } stream_encrypt_se_ip_arg_t; - -static ops_boolean_t write_encrypt_se_ip_header(ops_create_info_t *info, - void *header_data); - - -static ops_boolean_t stream_encrypt_se_ip_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo); - -static ops_boolean_t stream_encrypt_se_ip_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo); - -static void stream_encrypt_se_ip_destroyer (ops_writer_info_t *winfo); - - -/** -\ingroup Core_WritersNext -\brief Pushes a streaming encryption writer onto the stack. - -Data written to the stream will be encoded in a Symmetrically -Encrypted Integrity Protected packet. Note that this writer must be -used in conjunction with a literal writer or a signed writer. - -\param cinfo -\param pub_key -Example Code: -\code - ops_writer_push_stream_encrypt_se_ip(cinfo, public_key); - if (compress) - ops_writer_push_compressed(cinfo); - if (sign) - ops_writer_push_signed(cinfo, OPS_SIG_BINARY, secret_key); - else - ops_writer_push_literal(cinfo); -\endcode -*/ - -void ops_writer_push_stream_encrypt_se_ip(ops_create_info_t *cinfo, - const ops_keydata_t *pub_key) - { - ops_crypt_t *encrypt; - unsigned char *iv=NULL; - const unsigned int bufsz=1024; // initial value; gets expanded as necessary - - // Create arg to be used with this writer - // Remember to free this in the destroyer - stream_encrypt_se_ip_arg_t *arg=ops_mallocz(sizeof *arg); - - // Create and write encrypted PK session key - ops_pk_session_key_t *encrypted_pk_session_key; - encrypted_pk_session_key=ops_create_pk_session_key(pub_key); - ops_write_pk_session_key(cinfo, encrypted_pk_session_key); - - // Setup the arg - encrypt=ops_mallocz(sizeof *encrypt); - ops_crypt_any(encrypt, encrypted_pk_session_key->symmetric_algorithm); - iv=ops_mallocz(encrypt->blocksize); - encrypt->set_iv(encrypt, iv); - encrypt->set_key(encrypt, &encrypted_pk_session_key->key[0]); - ops_encrypt_init(encrypt); - - arg->crypt=encrypt; - - ops_setup_memory_write(&arg->cinfo_se_ip, &arg->mem_se_ip, bufsz); - - ops_hash_any(&arg->hash, OPS_HASH_SHA1); - arg->hash.init(&arg->hash); - - // This is a streaming writer, so we don't know the length in - // advance. Use a partial writer to handle the partial body - // packet lengths. - ops_writer_push_partial(PARTIAL_PACKET_SIZE, cinfo, OPS_PTAG_CT_SE_IP_DATA, - write_encrypt_se_ip_header, arg); - - // And push encryption writer on stack - ops_writer_push(cinfo, - stream_encrypt_se_ip_writer, - stream_encrypt_se_ip_finaliser, - stream_encrypt_se_ip_destroyer, arg); - // tidy up - ops_pk_session_key_free(encrypted_pk_session_key); - free(encrypted_pk_session_key); - free(iv); - } - -static ops_boolean_t ops_stream_write_se_ip(const unsigned char *data, - unsigned int len, - stream_encrypt_se_ip_arg_t *arg, - ops_create_info_t *cinfo) - { - ops_writer_push_encrypt_crypt(cinfo, arg->crypt); - ops_write(data, len, cinfo); - ops_writer_pop(cinfo); - arg->hash.add(&arg->hash, data, len); - return ops_true; - } - -// Writes out the header for the encrypted packet. Invoked by the -// partial stream writer. Note that writing the packet tag and the -// packet length is handled by the partial stream writer. -static ops_boolean_t write_encrypt_se_ip_header(ops_create_info_t *cinfo, - void *data) - { - stream_encrypt_se_ip_arg_t *arg = data; - size_t sz_preamble = arg->crypt->blocksize + 2; - unsigned char* preamble = ops_mallocz(sz_preamble); - - ops_write_scalar(SE_IP_DATA_VERSION, 1, cinfo); - - ops_writer_push_encrypt_crypt(cinfo, arg->crypt); - - ops_random(preamble, arg->crypt->blocksize); - preamble[arg->crypt->blocksize]=preamble[arg->crypt->blocksize-2]; - preamble[arg->crypt->blocksize+1]=preamble[arg->crypt->blocksize-1]; - - ops_write(preamble, sz_preamble, cinfo); - arg->hash.add(&arg->hash, preamble, sz_preamble); - ops_writer_pop(cinfo); - free(preamble); - - return ops_true; - } - -static ops_boolean_t -ops_stream_write_se_ip_last(stream_encrypt_se_ip_arg_t *arg, - ops_create_info_t *cinfo) - { - unsigned char c[1]; - unsigned char hashed[SHA_DIGEST_LENGTH]; - const size_t sz_mdc = 1 + 1 + SHA_DIGEST_LENGTH; - - ops_memory_t *mem_mdc; - ops_create_info_t *cinfo_mdc; - - // MDC packet tag - c[0]=0xD3; - arg->hash.add(&arg->hash, &c[0], 1); - - // MDC packet len - c[0]=0x14; - arg->hash.add(&arg->hash, &c[0], 1); - - //finish - arg->hash.finish(&arg->hash, hashed); - - ops_setup_memory_write(&cinfo_mdc, &mem_mdc, sz_mdc); - ops_write_mdc(hashed, cinfo_mdc); - - // encode everthing - ops_writer_push_encrypt_crypt(cinfo, arg->crypt); - - ops_write(ops_memory_get_data(mem_mdc), ops_memory_get_length(mem_mdc), - cinfo); - - ops_writer_pop(cinfo); - - ops_teardown_memory_write(cinfo_mdc, mem_mdc); - - return ops_true; - } - -static ops_boolean_t stream_encrypt_se_ip_writer(const unsigned char *src, - unsigned length, - ops_error_t **errors, - ops_writer_info_t *winfo) - { - stream_encrypt_se_ip_arg_t *arg=ops_writer_get_arg(winfo); - - ops_boolean_t rtn=ops_true; - - ops_stream_write_se_ip(src, length, - arg, arg->cinfo_se_ip); - // now write memory to next writer - rtn=ops_stacked_write(ops_memory_get_data(arg->mem_se_ip), - ops_memory_get_length(arg->mem_se_ip), - errors, winfo); - - ops_memory_clear(arg->mem_se_ip); - - return rtn; - } - -static ops_boolean_t stream_encrypt_se_ip_finaliser(ops_error_t **errors, - ops_writer_info_t *winfo) - { - stream_encrypt_se_ip_arg_t *arg=ops_writer_get_arg(winfo); - // write trailer - ops_stream_write_se_ip_last(arg, arg->cinfo_se_ip); - // now write memory to next writer - return ops_stacked_write(ops_memory_get_data(arg->mem_se_ip), - ops_memory_get_length(arg->mem_se_ip), - errors, winfo); - } - -static void stream_encrypt_se_ip_destroyer(ops_writer_info_t *winfo) - - { - stream_encrypt_se_ip_arg_t *arg=ops_writer_get_arg(winfo); - - ops_teardown_memory_write(arg->cinfo_se_ip, arg->mem_se_ip); - arg->crypt->decrypt_finish(arg->crypt); - - free(arg->crypt); - free(arg); - } - -// EOF diff --git a/openpgpsdk/src/use_openpgpsdk.pri b/openpgpsdk/src/use_openpgpsdk.pri deleted file mode 100644 index ba82100d8..000000000 --- a/openpgpsdk/src/use_openpgpsdk.pri +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-FileCopyrightText: (C) 2004-2019 Retroshare Team -# SPDX-License-Identifier: CC0-1.0 - -DEPENDPATH *= $$system_path($$clean_path($${PWD}/../../openpgpsdk/src)) -INCLUDEPATH *= $$system_path($$clean_path($${PWD}/../../openpgpsdk/src)) -LIBS *= -L$$system_path($$clean_path($${OUT_PWD}/../../openpgpsdk/src/lib/)) -lops - -!equals(TARGET, ops):PRE_TARGETDEPS *= $$system_path($$clean_path($${OUT_PWD}/../../openpgpsdk/src/lib/libops.a)) - -sLibs = -mLibs = ssl crypto z bz2 -dLibs = - -static { - sLibs *= $$mLibs -} else { - dLibs *= $$mLibs -} - -LIBS += $$linkStaticLibs(sLibs) -PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) - -LIBS += $$linkDynamicLibs(dLibs) diff --git a/plugins/Common/retroshare_plugin.pri b/plugins/Common/retroshare_plugin.pri index 77812db81..a3a6c5d8d 100644 --- a/plugins/Common/retroshare_plugin.pri +++ b/plugins/Common/retroshare_plugin.pri @@ -53,10 +53,6 @@ win32 { LIBS += -L"$$OUT_PWD/../../libretroshare/src/lib" -lretroshare } - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - CONFIG(debug, debug|release) { } else { # Tell linker to use ASLR protection @@ -102,6 +98,9 @@ win32 { for(lib, LIB_DIR):LIBS += -L"$$lib" for(bin, BIN_DIR):LIBS += -L"$$bin" LIBS += -lpthread + + # Do not add for MinGW + !isEmpty(QMAKE_SH): QMAKE_LFLAGS += -Wl,--end-group } macx { diff --git a/plugins/FeedReader/FeedReader.pro b/plugins/FeedReader/FeedReader.pro index b78dda911..5c696b5c3 100644 --- a/plugins/FeedReader/FeedReader.pro +++ b/plugins/FeedReader/FeedReader.pro @@ -44,6 +44,7 @@ SOURCES = FeedReaderPlugin.cpp \ gui/FeedReaderFeedNotify.cpp \ gui/FeedReaderUserNotify.cpp \ gui/FeedReaderFeedItem.cpp \ + gui/FeedTreeWidget.cpp \ util/CURLWrapper.cpp \ util/XMLWrapper.cpp \ util/HTMLWrapper.cpp \ @@ -64,6 +65,7 @@ HEADERS = FeedReaderPlugin.h \ gui/FeedReaderFeedNotify.h \ gui/FeedReaderUserNotify.h \ gui/FeedReaderFeedItem.h \ + gui/FeedTreeWidget.h \ util/CURLWrapper.h \ util/XMLWrapper.h \ util/HTMLWrapper.h \ @@ -121,6 +123,11 @@ win32 { #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} + isEmpty(QMAKE_SH) { + # MinGW + LIBS += -lcrypt32 + } + # Check for msys2 !isEmpty(PREFIX_MSYS2) { message(Use msys2 xml2.) diff --git a/plugins/FeedReader/FeedReaderPlugin.cpp b/plugins/FeedReader/FeedReaderPlugin.cpp index 24b602f9c..bc44a3036 100644 --- a/plugins/FeedReader/FeedReaderPlugin.cpp +++ b/plugins/FeedReader/FeedReaderPlugin.cpp @@ -92,7 +92,7 @@ void FeedReaderPlugin::setInterfaces(RsPlugInInterfaces &interfaces) { mInterfaces = interfaces; - mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums); + mFeedReader = new p3FeedReader(mPlugInHandler, mInterfaces.mGxsForums, mInterfaces.mPosted); rsFeedReader = mFeedReader; mNotify = new FeedReaderNotify(); diff --git a/plugins/FeedReader/gui/AddFeedDialog.cpp b/plugins/FeedReader/gui/AddFeedDialog.cpp index 19d02d968..59baf908a 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.cpp +++ b/plugins/FeedReader/gui/AddFeedDialog.cpp @@ -30,9 +30,11 @@ #include "gui/common/UIStateHelper.h" #include +#include #include -#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_FORUM_GROUPS 1 +#define TOKEN_TYPE_POSTED_GROUPS 2 AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) : QDialog(parent, Qt::Window), mFeedReader(feedReader), mNotify(notify), ui(new Ui::AddFeedDialog) @@ -47,9 +49,12 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->forumComboBox, UISTATE_LOADING_DISABLED); mStateHelper->addWidget(TOKEN_TYPE_FORUM_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->postedComboBox, UISTATE_LOADING_DISABLED); + mStateHelper->addWidget(TOKEN_TYPE_POSTED_GROUPS, ui->buttonBox->button(QDialogButtonBox::Ok), UISTATE_LOADING_DISABLED); /* Setup TokenQueue */ - mTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mForumTokenQueue = new TokenQueue(rsGxsForums->getTokenService(), this); + mPostedTokenQueue = new TokenQueue(rsPosted->getTokenService(), this); /* Connect signals */ connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(createFeed())); @@ -59,18 +64,23 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, connect(ui->useStandardStorageTimeCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardStorageTimeToggled())); connect(ui->useStandardUpdateInterval, SIGNAL(toggled(bool)), this, SLOT(useStandardUpdateIntervalToggled())); connect(ui->useStandardProxyCheckBox, SIGNAL(toggled(bool)), this, SLOT(useStandardProxyToggled())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeForumToggled())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(typePostedToggled())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(typeLocalToggled())); + connect(ui->postedFirstImageCheckBox, SIGNAL(toggled(bool)), this, SLOT(postedFirstImageToggled())); connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(preview())); /* currently only for local feeds */ - connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumToggled())); + connect(ui->saveCompletePageCheckBox, SIGNAL(toggled(bool)), this, SLOT(denyForumAndPostedToggled())); connect(ui->urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->nameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(validate())); connect(ui->useInfoFromFeedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeLocalRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); - connect(ui->typeForumRadio, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeLocalCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->typeForumCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); connect(ui->forumComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); + connect(ui->typePostedCheckBox, SIGNAL(toggled(bool)), this, SLOT(validate())); + connect(ui->postedComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(validate())); connect(ui->clearCachePushButton, SIGNAL(clicked()), this, SLOT(clearMessageCache())); @@ -79,13 +89,24 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, ui->activatedCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); ui->useInfoFromFeedCheckBox->setChecked(true); ui->updateForumInfoCheckBox->setEnabled(false); ui->updateForumInfoCheckBox->setChecked(true); + ui->updatePostedInfoCheckBox->setEnabled(false); + ui->updatePostedInfoCheckBox->setChecked(true); + ui->postedFirstImageCheckBox->setEnabled(false); + ui->postedFirstImageCheckBox->setChecked(false); + ui->postedOnlyImageCheckBox->setEnabled(false); + ui->postedOnlyImageCheckBox->setChecked(false); + ui->postedShinkImageCheckBox->setEnabled(false); + ui->postedShinkImageCheckBox->setChecked(true); ui->useAuthenticationCheckBox->setChecked(false); ui->useStandardStorageTimeCheckBox->setChecked(true); ui->useStandardUpdateInterval->setChecked(true); ui->useStandardProxyCheckBox->setChecked(true); + ui->embedImagesCheckBox->setChecked(true); + ui->saveCompletePageCheckBox->setEnabled(false); /* not yet supported */ ui->authenticationGroupBox->setEnabled(false); @@ -98,6 +119,9 @@ AddFeedDialog::AddFeedDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, /* fill own forums */ requestForumGroups(); + /* fill own posted */ + requestPostedGroups(); + validate(); ui->urlLineEdit->setFocus(); @@ -112,7 +136,8 @@ AddFeedDialog::~AddFeedDialog() processSettings(false); delete(ui); - delete(mTokenQueue); + delete(mForumTokenQueue); + delete(mPostedTokenQueue); } void AddFeedDialog::processSettings(bool load) @@ -161,18 +186,66 @@ void AddFeedDialog::useStandardProxyToggled() void AddFeedDialog::typeForumToggled() { - bool checked = ui->typeForumRadio->isChecked(); + bool checked = ui->typeForumCheckBox->isChecked(); mStateHelper->setWidgetEnabled(ui->forumComboBox, checked); ui->updateForumInfoCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + } } -void AddFeedDialog::denyForumToggled() +void AddFeedDialog::postedFirstImageToggled() +{ + bool checked = ui->postedFirstImageCheckBox->isChecked(); + ui->postedOnlyImageCheckBox->setEnabled(checked); + + if (!checked) { + ui->postedOnlyImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typePostedToggled() +{ + bool checked = ui->typePostedCheckBox->isChecked(); + mStateHelper->setWidgetEnabled(ui->postedComboBox, checked); + ui->updatePostedInfoCheckBox->setEnabled(checked); + ui->postedFirstImageCheckBox->setEnabled(checked); + ui->postedShinkImageCheckBox->setEnabled(checked); + + if (checked) { + ui->typeLocalCheckBox->setChecked(false); + }else { + ui->postedFirstImageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::typeLocalToggled() +{ + bool checked = ui->typeLocalCheckBox->isChecked(); + if (checked) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, false); + mStateHelper->setWidgetEnabled(ui->postedComboBox, false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setChecked(false); + ui->saveCompletePageCheckBox->setEnabled(true); + } else { + ui->saveCompletePageCheckBox->setEnabled(false); + ui->saveCompletePageCheckBox->setChecked(false); + } +} + +void AddFeedDialog::denyForumAndPostedToggled() { if (ui->saveCompletePageCheckBox->isChecked()) { - ui->typeForumRadio->setEnabled(false); - ui->typeLocalRadio->setChecked(true); + ui->typeForumCheckBox->setEnabled(false); + ui->typeForumCheckBox->setChecked(false); + ui->typePostedCheckBox->setEnabled(false); + ui->typePostedCheckBox->setChecked(false); + ui->typeLocalCheckBox->setChecked(true); } else { - ui->typeForumRadio->setEnabled(true); + ui->typeForumCheckBox->setEnabled(true); + ui->typePostedCheckBox->setEnabled(true); } } @@ -189,11 +262,15 @@ void AddFeedDialog::validate() ui->previewButton->setEnabled(ok); - if (!ui->typeLocalRadio->isChecked() && !ui->typeForumRadio->isChecked()) { + if (!ui->typeLocalCheckBox->isChecked() && !ui->typeForumCheckBox->isChecked() && !ui->typePostedCheckBox->isChecked()) { ok = false; } - if (ui->typeForumRadio->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + if (ui->typeForumCheckBox->isChecked() && ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().isEmpty()) { + ok = false; + } + + if (ui->typePostedCheckBox->isChecked() && ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().isEmpty()) { ok = false; } @@ -224,20 +301,32 @@ bool AddFeedDialog::fillFeed(uint32_t feedId) ui->urlLineEdit->setText(QString::fromUtf8(feedInfo.url.c_str())); ui->useInfoFromFeedCheckBox->setChecked(feedInfo.flag.infoFromFeed); ui->updateForumInfoCheckBox->setChecked(feedInfo.flag.updateForumInfo); + ui->updatePostedInfoCheckBox->setChecked(feedInfo.flag.updatePostedInfo); + ui->postedFirstImageCheckBox->setChecked(feedInfo.flag.postedFirstImage); + ui->postedOnlyImageCheckBox->setChecked(feedInfo.flag.postedOnlyImage); + ui->postedShinkImageCheckBox->setChecked(feedInfo.flag.postedShrinkImage); ui->activatedCheckBox->setChecked(!feedInfo.flag.deactivated); ui->embedImagesCheckBox->setChecked(feedInfo.flag.embedImages); ui->saveCompletePageCheckBox->setChecked(feedInfo.flag.saveCompletePage); ui->descriptionPlainTextEdit->setPlainText(QString::fromUtf8(feedInfo.description.c_str())); - if (feedInfo.flag.forum) { - mStateHelper->setWidgetEnabled(ui->forumComboBox, true); - ui->typeForumRadio->setChecked(true); - ui->saveCompletePageCheckBox->setEnabled(false); + if (feedInfo.flag.forum || feedInfo.flag.posted) { + if (feedInfo.flag.forum) { + mStateHelper->setWidgetEnabled(ui->forumComboBox, true); + ui->typeForumCheckBox->setChecked(true); - setActiveForumId(feedInfo.forumId); + setActiveForumId(feedInfo.forumId); + } + if (feedInfo.flag.posted) { + mStateHelper->setWidgetEnabled(ui->postedComboBox, true); + ui->typePostedCheckBox->setChecked(true); + + setActivePostedId(feedInfo.postedId); + } + ui->saveCompletePageCheckBox->setEnabled(false); } else { - ui->typeLocalRadio->setChecked(true); + ui->typeLocalCheckBox->setChecked(true); mStateHelper->setWidgetEnabled(ui->forumComboBox, false); } @@ -286,6 +375,21 @@ void AddFeedDialog::setActiveForumId(const std::string &forumId) } } +void AddFeedDialog::setActivePostedId(const std::string &postedId) +{ + if (mStateHelper->isLoading(TOKEN_TYPE_POSTED_GROUPS)) { + mFillPostedId = postedId; + return; + } + + int index = ui->postedComboBox->findData(QString::fromStdString(postedId)); + if (index >= 0) { + ui->postedComboBox->setCurrentIndex(index); + } else { + ui->postedComboBox->setCurrentIndex(0); + } +} + void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) { feedInfo.parentId = mParentId; @@ -294,18 +398,28 @@ void AddFeedDialog::getFeedInfo(FeedInfo &feedInfo) feedInfo.url = ui->urlLineEdit->text().toUtf8().constData(); feedInfo.flag.infoFromFeed = ui->useInfoFromFeedCheckBox->isChecked(); feedInfo.flag.updateForumInfo = ui->updateForumInfoCheckBox->isChecked() && ui->updateForumInfoCheckBox->isEnabled(); + feedInfo.flag.updatePostedInfo = ui->updatePostedInfoCheckBox->isChecked() && ui->updatePostedInfoCheckBox->isEnabled(); + feedInfo.flag.postedFirstImage = ui->postedFirstImageCheckBox->isChecked() && ui->postedFirstImageCheckBox->isEnabled(); + feedInfo.flag.postedOnlyImage = ui->postedOnlyImageCheckBox->isChecked() && ui->postedOnlyImageCheckBox->isEnabled(); + feedInfo.flag.postedShrinkImage = ui->postedShinkImageCheckBox->isChecked() && ui->postedShinkImageCheckBox->isEnabled(); feedInfo.flag.deactivated = !ui->activatedCheckBox->isChecked(); feedInfo.flag.embedImages = ui->embedImagesCheckBox->isChecked(); feedInfo.flag.saveCompletePage = ui->saveCompletePageCheckBox->isChecked(); feedInfo.description = ui->descriptionPlainTextEdit->toPlainText().toUtf8().constData(); - feedInfo.flag.forum = ui->typeForumRadio->isChecked(); + feedInfo.flag.forum = ui->typeForumCheckBox->isChecked(); if (feedInfo.flag.forum) { feedInfo.forumId = ui->forumComboBox->itemData(ui->forumComboBox->currentIndex()).toString().toStdString(); } + feedInfo.flag.posted = ui->typePostedCheckBox->isChecked(); + + if (feedInfo.flag.posted) { + feedInfo.postedId = ui->postedComboBox->itemData(ui->postedComboBox->currentIndex()).toString().toStdString(); + } + feedInfo.flag.authentication = ui->useAuthenticationCheckBox->isChecked(); feedInfo.user = ui->userLineEdit->text().toUtf8().constData(); feedInfo.password = ui->passwordLineEdit->text().toUtf8().constData(); @@ -340,12 +454,12 @@ void AddFeedDialog::createFeed() if (mFeedId == 0) { /* add new feed */ - RsFeedAddResult result = mFeedReader->addFeed(feedInfo, mFeedId); + RsFeedResult result = mFeedReader->addFeed(feedInfo, mFeedId); if (FeedReaderStringDefs::showError(this, result, tr("Create feed"), tr("Cannot create feed."))) { return; } } else { - RsFeedAddResult result = mFeedReader->setFeed(mFeedId, feedInfo); + RsFeedResult result = mFeedReader->setFeed(mFeedId, feedInfo); if (FeedReaderStringDefs::showError(this, result, tr("Edit feed"), tr("Cannot change feed."))) { return; } @@ -382,10 +496,10 @@ void AddFeedDialog::requestForumGroups() RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - mTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_FORUM_GROUPS); uint32_t token; - mTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); + mForumTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_FORUM_GROUPS); } void AddFeedDialog::loadForumGroups(const uint32_t &token) @@ -416,9 +530,50 @@ void AddFeedDialog::loadForumGroups(const uint32_t &token) } } +void AddFeedDialog::requestPostedGroups() +{ + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, true); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + mPostedTokenQueue->cancelActiveRequestTokens(TOKEN_TYPE_POSTED_GROUPS); + + uint32_t token; + mPostedTokenQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, TOKEN_TYPE_POSTED_GROUPS); +} + +void AddFeedDialog::loadPostedGroups(const uint32_t &token) +{ + std::vector groups; + rsPosted->getGroupData(token, groups); + + ui->postedComboBox->clear(); + + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsPostedGroup &group = *it; + + /* show only own posted */ + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags) && !group.mMeta.mAuthorId.isNull()) { + ui->postedComboBox->addItem(QString::fromUtf8(group.mMeta.mGroupName.c_str()), QString::fromStdString(group.mMeta.mGroupId.toStdString())); + } + } + + /* insert empty item */ + ui->postedComboBox->insertItem(0, "", ""); + ui->postedComboBox->setCurrentIndex(0); + + mStateHelper->setLoading(TOKEN_TYPE_POSTED_GROUPS, false); + + if (!mFillPostedId.empty()) { + setActivePostedId(mFillPostedId); + mFillPostedId.clear(); + } +} + void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) { - if (queue == mTokenQueue) + if (queue == mForumTokenQueue) { /* now switch on req */ switch(req.mUserType) @@ -433,4 +588,20 @@ void AddFeedDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req } } + + if (queue == mPostedTokenQueue) + { + /* now switch on req */ + switch(req.mUserType) + { + case TOKEN_TYPE_POSTED_GROUPS: + loadPostedGroups(req.mToken); + break; + + default: + std::cerr << "AddFeedDialog::loadRequest() ERROR: INVALID TYPE"; + std::cerr << std::endl; + + } + } } diff --git a/plugins/FeedReader/gui/AddFeedDialog.h b/plugins/FeedReader/gui/AddFeedDialog.h index 111238d33..e557580e1 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.h +++ b/plugins/FeedReader/gui/AddFeedDialog.h @@ -53,7 +53,10 @@ private slots: void useStandardUpdateIntervalToggled(); void useStandardProxyToggled(); void typeForumToggled(); - void denyForumToggled(); + void postedFirstImageToggled(); + void typePostedToggled(); + void typeLocalToggled(); + void denyForumAndPostedToggled(); void validate(); void createFeed(); void preview(); @@ -63,9 +66,12 @@ private: void processSettings(bool load); void getFeedInfo(FeedInfo &feedInfo); void setActiveForumId(const std::string &forumId); + void setActivePostedId(const std::string &postedId); void requestForumGroups(); void loadForumGroups(const uint32_t &token); + void requestPostedGroups(); + void loadPostedGroups(const uint32_t &token); private: RsFeedReader *mFeedReader; @@ -73,13 +79,15 @@ private: uint32_t mFeedId; uint32_t mParentId; std::string mFillForumId; + std::string mFillPostedId; RsFeedTransformationType mTransformationType; std::list mXPathsToUse; std::list mXPathsToRemove; std::string mXslt; - TokenQueue *mTokenQueue; + TokenQueue *mForumTokenQueue; + TokenQueue *mPostedTokenQueue; UIStateHelper *mStateHelper; Ui::AddFeedDialog *ui; diff --git a/plugins/FeedReader/gui/AddFeedDialog.ui b/plugins/FeedReader/gui/AddFeedDialog.ui index ff657b6ff..ebb478162 100644 --- a/plugins/FeedReader/gui/AddFeedDialog.ui +++ b/plugins/FeedReader/gui/AddFeedDialog.ui @@ -6,8 +6,8 @@ 0 0 - 715 - 605 + 739 + 653 @@ -37,56 +37,14 @@ - + QFrame::NoFrame QFrame::Raised - - - - - Type - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - - Forum - - - - - - - - - - - - Local Feed - - - - - - + @@ -306,6 +264,13 @@ + + + 11 + true + true + + Name: @@ -316,7 +281,44 @@ - + + + + Misc + + + + + + Activated + + + + + + + Use name and description from feed + + + + + + + Embed images + + + + + + + Save complete web page (experimental for local feeds) + + + + + + + Transformation @@ -349,46 +351,99 @@ - - + + - Misc + Type - - - + + + 6 + + + 6 + + + 6 + + + 6 + + + + + + 0 + 0 + + - Activated + Forum - - + + + + + - Use name and description from feed + Local Feed - - + + + + + + Update forum information + + + + + + + + + + - Update forum information + Board - - - - Embed images - - - - - - - Save complete web page (experimental for local feeds) - - + + + + + + Update board information + + + + + + + Only image + + + + + + + Use first image as board image + + + + + + + Shrink image + + + + @@ -405,27 +460,42 @@
gui/common/HeaderFrame.h
1 + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
urlLineEdit nameLineEdit descriptionPlainTextEdit - typeForumRadio + typeForumCheckBox forumComboBox + updateForumInfoCheckBox + typePostedCheckBox + postedComboBox + updatePostedInfoCheckBox + postedShinkImageCheckBox + postedFirstImageCheckBox + postedOnlyImageCheckBox + typeLocalCheckBox activatedCheckBox useInfoFromFeedCheckBox - updateForumInfoCheckBox + embedImagesCheckBox + saveCompletePageCheckBox + previewButton useAuthenticationCheckBox userLineEdit passwordLineEdit useStandardStorageTimeCheckBox + clearCachePushButton storageTimeSpinBox useStandardUpdateInterval updateIntervalSpinBox useStandardProxyCheckBox proxyAddressLineEdit proxyPortSpinBox - buttonBox diff --git a/plugins/FeedReader/gui/FeedReaderDialog.cpp b/plugins/FeedReader/gui/FeedReaderDialog.cpp index abc2f1aa5..08f390a09 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.cpp +++ b/plugins/FeedReader/gui/FeedReaderDialog.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "FeedReaderDialog.h" #include "FeedReaderMessageWidget.h" @@ -35,6 +36,8 @@ #include "gui/settings/rsharesettings.h" #include "gui/notifyqt.h" #include "FeedReaderUserNotify.h" +#include "gui/Posted/PostedCreatePostDialog.h" +#include "util/imageutil.h" #include "interface/rsFeedReader.h" #include "retroshare/rsiface.h" @@ -55,6 +58,8 @@ #define ROLE_FEED_ERROR Qt::UserRole + 9 #define ROLE_FEED_DEACTIVATED Qt::UserRole + 10 +const int MAXMESSAGESIZE = RsSerialiser::MAX_SERIAL_SIZE - 70000; + FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent) : MainPage(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::FeedReaderDialog) { @@ -66,6 +71,7 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n mMessageWidget = NULL; connect(mNotify, &FeedReaderNotify::feedChanged, this, &FeedReaderDialog::feedChanged, Qt::QueuedConnection); + connect(mNotify, &FeedReaderNotify::optimizeImage, this, &FeedReaderDialog::optimizeImage, Qt::QueuedConnection); connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); @@ -84,9 +90,16 @@ FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *n connect(ui->feedAddButton, SIGNAL(clicked()), this, SLOT(newFeed())); connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed())); + connect(ui->feedTreeWidget, SIGNAL(feedReparent(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(feedTreeReparent(QTreeWidgetItem*,QTreeWidgetItem*))); + mFeedCompareRole = new RSTreeWidgetItemCompareRole; mFeedCompareRole->setRole(COLUMN_FEED_NAME, ROLE_FEED_SORT); + /* enable drag and drop */ + ui->feedTreeWidget->setAcceptDrops(true); + ui->feedTreeWidget->setDragEnabled(true); + ui->feedTreeWidget->setDragDropMode(QAbstractItemView::InternalMove); + /* initialize root item */ mRootItem = new QTreeWidgetItem(ui->feedTreeWidget); QString name = tr("Message Folders"); @@ -395,6 +408,9 @@ void FeedReaderDialog::updateFeeds(uint32_t parentId, QTreeWidgetItem *parentIte mOpenFeedIds->removeAt(index); } } + } else { + /* disable drop */ + item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); } } @@ -594,6 +610,55 @@ void FeedReaderDialog::feedChanged(uint32_t feedId, int type) calculateFeedItems(); } +void FeedReaderDialog::optimizeImage() +{ + while (true) { + FeedReaderOptimizeImageTask *optimizeImageTask = mFeedReader->getOptimizeImageTask(); + + if (!optimizeImageTask) { + return; + } + + optimizeImageTask->mResult = false; + + QImage image; + if (image.loadFromData(optimizeImageTask->mImage.data(), optimizeImageTask->mImage.size())) { + QByteArray optimizedImageData; + std::string optimizedImageMimeType; + QImage imageOptDummy; + + switch (optimizeImageTask->mType) { + case FeedReaderOptimizeImageTask::POSTED: + if (PostedCreatePostDialog::optimizeImage(image, optimizedImageData, imageOptDummy)) { + optimizedImageMimeType = "image/jpeg"; + optimizeImageTask->mResult = true; + } + break; + case FeedReaderOptimizeImageTask::SIZE: + if (ImageUtil::optimizeSizeBytes(optimizedImageData, image, imageOptDummy, "JPG", 0, MAXMESSAGESIZE)) { + optimizedImageMimeType = "image/jpg"; + optimizeImageTask->mResult = true; + } + break; + } + + if (optimizeImageTask->mResult) { + if (optimizedImageData.size() < (ssize_t) optimizeImageTask->mImage.size()) { + /* use optimized image */ + optimizeImageTask->mImageResult.assign(optimizedImageData.begin(), optimizedImageData.end()); + optimizeImageTask->mMimeTypeResult = optimizedImageMimeType; + } else { + /* use original image */ + optimizeImageTask->mImageResult = optimizeImageTask->mImage; + optimizeImageTask->mMimeTypeResult = optimizeImageTask->mMimeType; + } + } + } + + mFeedReader->setOptimizeImageTaskResult(optimizeImageTask); + } +} + FeedReaderMessageWidget *FeedReaderDialog::feedMessageWidget(uint32_t id) { int tabCount = ui->messageTabWidget->count(); @@ -738,7 +803,7 @@ void FeedReaderDialog::newFolder() if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { uint32_t feedId; - RsFeedAddResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); + RsFeedResult result = mFeedReader->addFolder(currentFeedId(), dialog.textValue().toUtf8().constData(), feedId); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } @@ -791,7 +856,7 @@ void FeedReaderDialog::editFeed() dialog.setTextValue(item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString()); if (dialog.exec() == QDialog::Accepted && !dialog.textValue().isEmpty()) { - RsFeedAddResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); + RsFeedResult result = mFeedReader->setFolder(feedId, dialog.textValue().toUtf8().constData()); FeedReaderStringDefs::showError(this, result, tr("Create folder"), tr("Cannot create folder.")); } } else { @@ -832,3 +897,30 @@ void FeedReaderDialog::processFeed() mFeedReader->processFeed(feedId); } + +void FeedReaderDialog::feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent) +{ + if (!item || ! newParent) { + return; + } + + uint32_t feedId = item->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toUInt(); + uint32_t parentId = newParent->data(COLUMN_FEED_DATA, ROLE_FEED_ID).toUInt(); + + if (feedId == 0) { + return; + } + + RsFeedResult result = mFeedReader->setParent(feedId, parentId); + if (FeedReaderStringDefs::showError(this, result, tr("Move feed"), tr("Cannot move feed."))) { + return; + } + + bool expanded = item->isExpanded(); + item->parent()->removeChild(item); + newParent->addChild(item); + item->setExpanded(expanded); + newParent->setExpanded(true); + + calculateFeedItems(); +} diff --git a/plugins/FeedReader/gui/FeedReaderDialog.h b/plugins/FeedReader/gui/FeedReaderDialog.h index a221cfe64..12e11ee7f 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.h +++ b/plugins/FeedReader/gui/FeedReaderDialog.h @@ -61,6 +61,7 @@ private slots: void editFeed(); void activateFeed(); void processFeed(); + void feedTreeReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent); void messageTabCloseRequested(int index); void messageTabChanged(int index); @@ -68,6 +69,7 @@ private slots: /* FeedReaderNotify */ void feedChanged(uint32_t feedId, int type); + void optimizeImage(); private: uint32_t currentFeedId(); diff --git a/plugins/FeedReader/gui/FeedReaderDialog.ui b/plugins/FeedReader/gui/FeedReaderDialog.ui index 7c77717bb..b6b004d69 100644 --- a/plugins/FeedReader/gui/FeedReaderDialog.ui +++ b/plugins/FeedReader/gui/FeedReaderDialog.ui @@ -86,7 +86,14 @@
- + + + + 12 + 75 + true + + Feeds @@ -143,7 +150,7 @@ - + Qt::CustomContextMenu @@ -179,14 +186,9 @@ - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - RSTreeWidget + FeedTreeWidget QTreeWidget -
gui/common/RSTreeWidget.h
+
gui/FeedTreeWidget.h
RSTabWidget diff --git a/plugins/FeedReader/gui/FeedReaderFeedItem.ui b/plugins/FeedReader/gui/FeedReaderFeedItem.ui index 37c2df915..47d56f441 100644 --- a/plugins/FeedReader/gui/FeedReaderFeedItem.ui +++ b/plugins/FeedReader/gui/FeedReaderFeedItem.ui @@ -10,7 +10,7 @@ 123
- + 1 @@ -30,7 +30,7 @@ 1 - + 0 @@ -46,9 +46,9 @@ QFrame::Sunken - + - + @@ -66,9 +66,9 @@ - + - + @@ -92,7 +92,7 @@ - + 0 @@ -101,7 +101,9 @@ + 11 75 + true true @@ -127,7 +129,7 @@ - + 8 @@ -195,7 +197,7 @@ p, li { white-space: pre-wrap; } Expand - + :/icons/png/down-arrow.png:/icons/png/down-arrow.png @@ -221,7 +223,7 @@ p, li { white-space: pre-wrap; } Set as read and remove item - + :/icons/png/correct.png:/icons/png/correct.png @@ -247,7 +249,7 @@ p, li { white-space: pre-wrap; } Remove Item - + :/icons/png/exit2.png:/icons/png/exit2.png @@ -260,7 +262,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -287,7 +289,7 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - + 5 @@ -336,16 +338,8 @@ p, li { white-space: pre-wrap; } - - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
- diff --git a/plugins/FeedReader/gui/FeedReaderFeedNotify.cpp b/plugins/FeedReader/gui/FeedReaderFeedNotify.cpp index 16a3099e6..23d95f50e 100644 --- a/plugins/FeedReader/gui/FeedReaderFeedNotify.cpp +++ b/plugins/FeedReader/gui/FeedReaderFeedNotify.cpp @@ -90,7 +90,7 @@ void FeedReaderFeedNotify::msgChanged(uint32_t feedId, const QString &msgId, int mMutex->unlock(); } -FeedItem *FeedReaderFeedNotify::feedItem(FeedHolder *parent) +FeedItem *FeedReaderFeedNotify::feedItem(FeedHolder */*parent*/) { bool msgPending = false; FeedInfo feedInfo; @@ -119,7 +119,7 @@ FeedItem *FeedReaderFeedNotify::feedItem(FeedHolder *parent) return new FeedReaderFeedItem(mFeedReader, mNotify, feedInfo, msgInfo); } -FeedItem *FeedReaderFeedNotify::testFeedItem(FeedHolder *parent) +FeedItem *FeedReaderFeedNotify::testFeedItem(FeedHolder */*parent*/) { FeedInfo feedInfo; feedInfo.name = tr("Test").toUtf8().constData(); diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp index 1550bc636..59f72103c 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "FeedReaderMessageWidget.h" #include "ui_FeedReaderMessageWidget.h" @@ -36,8 +37,14 @@ #include "gui/settings/rsharesettings.h" #include "util/HandleRichText.h" #include "util/QtVersion.h" +#include "gui/Posted/PostedCreatePostDialog.h" +#include "gui/gxsforums/CreateGxsForumMsg.h" +#include "gui/common/FilesDefs.h" +#include "util/imageutil.h" #include "retroshare/rsiface.h" +#include "retroshare/rsgxsforums.h" +#include "retroshare/rsposted.h" #define COLUMN_MSG_COUNT 4 #define COLUMN_MSG_TITLE 0 @@ -83,6 +90,12 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(uint32_t feedId, RsFeedReader * connect(ui->msgRemoveButton, SIGNAL(clicked()), this, SLOT(removeMsg())); connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed())); + /* Set initial size the splitter */ + QList sizes; + sizes << 250 << width(); // Qt calculates the right sizes + ui->pictureSplitter->setSizes(sizes); + ui->pictureSplitter->hide(); + // create timer for navigation mTimer = new QTimer(this); mTimer->setInterval(300); @@ -115,6 +128,10 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(uint32_t feedId, RsFeedReader * ui->filterLineEdit->addFilter(QIcon(), tr("Author"), COLUMN_MSG_AUTHOR, tr("Search Author")); ui->filterLineEdit->setCurrentFilter(COLUMN_MSG_TITLE); + /* add image actions */ + ui->attachmentLabel->addContextMenuAction(ui->actionAttachmentCopyLinkLocation); + connect(ui->actionAttachmentCopyLinkLocation, &QAction::triggered, this, &FeedReaderMessageWidget::attachmentCopyLinkLocation); + /* load settings */ processSettings(true); @@ -175,6 +192,7 @@ void FeedReaderMessageWidget::processSettings(bool load) // state of splitter ui->msgSplitter->restoreState(Settings->value("msgSplitter").toByteArray()); + ui->pictureSplitter->restoreState(Settings->value("pictureSplitter").toByteArray()); } else { // save settings @@ -183,6 +201,7 @@ void FeedReaderMessageWidget::processSettings(bool load) // state of splitter Settings->setValue("msgSplitter", ui->msgSplitter->saveState()); + Settings->setValue("pictureSplitter", ui->pictureSplitter->saveState()); } Settings->endGroup(); @@ -245,9 +264,19 @@ void FeedReaderMessageWidget::setFeedId(uint32_t feedId) ui->msgReadAllButton->setEnabled(false); ui->msgTreeWidget->setPlaceholderText(""); } else { - if (mFeedInfo.flag.forum) { + if (mFeedInfo.flag.forum || mFeedInfo.flag.posted) { ui->msgReadAllButton->setEnabled(false); - ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + + if (mFeedInfo.flag.forum && mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum and the board")); + } else { + if (mFeedInfo.flag.forum) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the forum")); + } + if (mFeedInfo.flag.posted) { + ui->msgTreeWidget->setPlaceholderText(tr("The messages will be added to the board")); + } + } } else { ui->msgReadAllButton->setEnabled(true); ui->msgTreeWidget->setPlaceholderText(""); @@ -340,6 +369,20 @@ void FeedReaderMessageWidget::msgTreeCustomPopupMenu(QPoint /*point*/) action = contextMnu.addAction(QIcon(""), tr("Remove"), this, SLOT(removeMsg())); action->setEnabled(!selectedItems.empty()); + if (selectedItems.size() == 1 && (mFeedReader->forums() || mFeedReader->posted())) { + contextMnu.addSeparator(); + + if (mFeedReader->forums()) { + QMenu *menu = contextMnu.addMenu(tr("Add to forum")); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(fillForumMenu())); + } + + if (mFeedReader->posted()) { + QMenu *menu = contextMnu.addMenu(tr("Add to board")); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(fillPostedMenu())); + } + } + contextMnu.addSeparator(); action = contextMnu.addAction(QIcon(""), tr("Retransform"), this, SLOT(retransformMsg())); @@ -571,6 +614,21 @@ void FeedReaderMessageWidget::msgItemChanged() mTimer->start(); } +void FeedReaderMessageWidget::clearMessage() +{ + ui->msgTitle->clear(); +// ui->msgLink->clear(); + ui->msgText->clear(); + ui->msgTextSplitter->clear(); + ui->attachmentLabel->clear(); + ui->linkButton->setEnabled(false); + ui->msgText->show(); + ui->pictureSplitter->hide(); + + ui->actionAttachmentCopyLinkLocation->setData(QVariant()); + ui->actionAttachmentCopyLinkLocation->setEnabled(false); +} + void FeedReaderMessageWidget::updateCurrentMessage() { mTimer->stop(); @@ -580,10 +638,7 @@ void FeedReaderMessageWidget::updateCurrentMessage() std::string msgId = currentMsgId(); if (mFeedId == 0 || msgId.empty()) { - ui->msgTitle->clear(); -// ui->msgLink->clear(); - ui->msgText->clear(); - ui->linkButton->setEnabled(false); + clearMessage(); ui->msgReadButton->setEnabled(false); ui->msgUnreadButton->setEnabled(false); @@ -594,10 +649,7 @@ void FeedReaderMessageWidget::updateCurrentMessage() QTreeWidgetItem *item = ui->msgTreeWidget->currentItem(); if (!item) { /* there is something wrong */ - ui->msgTitle->clear(); -// ui->msgLink->clear(); - ui->msgText->clear(); - ui->linkButton->setEnabled(false); + clearMessage(); ui->msgReadButton->setEnabled(false); ui->msgUnreadButton->setEnabled(false); @@ -612,10 +664,7 @@ void FeedReaderMessageWidget::updateCurrentMessage() /* get msg */ FeedMsgInfo msgInfo; if (!mFeedReader->getMsgInfo(mFeedId, msgId, msgInfo)) { - ui->msgTitle->clear(); -// ui->msgLink->clear(); - ui->msgText->clear(); - ui->linkButton->setEnabled(false); + clearMessage(); return; } @@ -635,9 +684,41 @@ void FeedReaderMessageWidget::updateCurrentMessage() setMsgAsReadUnread(row, setToReadOnActive); } + ui->actionAttachmentCopyLinkLocation->setData(QVariant()); + ui->actionAttachmentCopyLinkLocation->setEnabled(false); + + if (!msgInfo.attachment.empty()) { + QByteArray imageData((char*) msgInfo.attachment.data(), msgInfo.attachment.size()); + QPixmap pixmap; + if (pixmap.loadFromData(imageData)) { + ui->attachmentLabel->setPixmap(pixmap); + ui->pictureSplitter->show(); + ui->msgText->hide(); + } else { + ui->pictureSplitter->hide(); + ui->msgText->show(); + } + + if (!msgInfo.attachmentLink.empty()) { + ui->actionAttachmentCopyLinkLocation->setData(QString::fromUtf8(msgInfo.attachmentLink.c_str())); + ui->actionAttachmentCopyLinkLocation->setEnabled(true); + } + } else { + ui->pictureSplitter->hide(); + ui->msgText->show(); + } + QString msgTxt = RsHtml().formatText(ui->msgText->document(), QString::fromUtf8((msgInfo.descriptionTransformed.empty() ? msgInfo.description : msgInfo.descriptionTransformed).c_str()), RSHTML_FORMATTEXT_EMBED_LINKS); - ui->msgText->setHtml(msgTxt); + if (ui->pictureSplitter->isVisible()) { + ui->msgTextSplitter->setHtml(msgTxt); + ui->msgText->clear(); + } else { + ui->msgText->setHtml(msgTxt); + ui->msgTextSplitter->clear(); + ui->attachmentLabel->clear(); + } + ui->msgTitle->setText(QString::fromUtf8(msgInfo.title.c_str())); ui->linkButton->setEnabled(!msgInfo.link.empty()); @@ -714,11 +795,11 @@ void FeedReaderMessageWidget::toggleMsgText() void FeedReaderMessageWidget::toggleMsgText_internal() { if (ui->expandButton->isChecked()) { - ui->msgText->setVisible(true); + ui->horizontalLayoutWidget->setVisible(true); ui->expandButton->setIcon(QIcon(QString(":/images/edit_remove24.png"))); ui->expandButton->setToolTip(tr("Hide")); } else { - ui->msgText->setVisible(false); + ui->horizontalLayoutWidget->setVisible(false); ui->expandButton->setIcon(QIcon(QString(":/images/edit_add24.png"))); ui->expandButton->setToolTip(tr("Expand")); } @@ -840,3 +921,123 @@ void FeedReaderMessageWidget::openLinkMsg() QDesktopServices::openUrl(QUrl(link)); } + +void FeedReaderMessageWidget::fillForumMenu() +{ + QMenu *menu = dynamic_cast(sender()) ; + if (!menu) { + return; + } + + disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillForumMenu())); + + std::vector groups; + if (mFeedReader->getForumGroups(groups, true)) { + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsGxsForumGroup &group = *it; + QAction *action = menu->addAction(QString::fromUtf8(group.mMeta.mGroupName.c_str()), this, SLOT(addToForum())); + action->setData(QString::fromUtf8(group.mMeta.mGroupId.toStdString().c_str())); + } + } +} + +void FeedReaderMessageWidget::fillPostedMenu() +{ + QMenu *menu = dynamic_cast(sender()) ; + if (!menu) { + return; + } + + disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(fillPostedMenu())); + + std::vector groups; + if (mFeedReader->getPostedGroups(groups, true)) { + for (std::vector::iterator it = groups.begin(); it != groups.end(); ++it) { + const RsPostedGroup &group = *it; + QAction *action = menu->addAction(QString::fromUtf8(group.mMeta.mGroupName.c_str()), this, SLOT(addToPosted())); + action->setData(QString::fromUtf8(group.mMeta.mGroupId.toStdString().c_str())); + } + } +} + +void FeedReaderMessageWidget::addToForum() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QString id = action->data().toString(); + if (id.isEmpty()) { + return; + } + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + if (selectedItems.size() != 1) { + return; + } + + std::string msgId = selectedItems[0]->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + FeedMsgInfo msgInfo; + if (!mFeedReader->getMsgInfo(mFeedId, msgId, msgInfo)) { + return; + } + + RsGxsGroupId forumId(id.toStdString()); + + CreateGxsForumMsg *msgDialog = new CreateGxsForumMsg(forumId, RsGxsMessageId(), RsGxsMessageId(), RsGxsId()) ; + msgDialog->setSubject(QString::fromUtf8(msgInfo.title.c_str())); + msgDialog->insertPastedText(QString::fromUtf8(msgInfo.description.c_str())); + msgDialog->show(); +} + +void FeedReaderMessageWidget::addToPosted() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QString id = action->data().toString(); + if (id.isEmpty()) { + return; + } + + QList selectedItems = ui->msgTreeWidget->selectedItems(); + if (selectedItems.size() != 1) { + return; + } + + std::string msgId = selectedItems[0]->data(COLUMN_MSG_DATA, ROLE_MSG_ID).toString().toStdString(); + FeedMsgInfo msgInfo; + if (!mFeedReader->getMsgInfo(mFeedId, msgId, msgInfo)) { + return; + } + + RsGxsGroupId postedId(id.toStdString()); + + PostedCreatePostDialog *msgDialog = new PostedCreatePostDialog(mFeedReader->posted(), postedId); + msgDialog->setTitle(QString::fromUtf8(msgInfo.title.c_str())); + msgDialog->setNotes(QString::fromUtf8(msgInfo.description.c_str())); + msgDialog->setLink(QString::fromUtf8(msgInfo.link.c_str())); + msgDialog->show(); +} + +void FeedReaderMessageWidget::attachmentCopyLinkLocation() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QVariant data = action->data(); + if (!data.isValid()) { + return; + } + + if (data.type() != QVariant::String) { + return; + } + + QApplication::clipboard()->setText(data.toString()); +} diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.h b/plugins/FeedReader/gui/FeedReaderMessageWidget.h index 452c407ad..1223b3b4e 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.h +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.h @@ -73,6 +73,11 @@ private slots: void openLinkMsg(); void copyLinkMsg(); void retransformMsg(); + void fillForumMenu(); + void fillPostedMenu(); + void addToForum(); + void addToPosted(); + void attachmentCopyLinkLocation(); /* FeedReaderNotify */ void feedChanged(uint32_t feedId, int type); @@ -88,6 +93,7 @@ private: void filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn); void filterItem(QTreeWidgetItem *item); void toggleMsgText_internal(); + void clearMessage(); bool mProcessSettings; RSTreeWidgetItemCompareRole *mMsgCompareRole; diff --git a/plugins/FeedReader/gui/FeedReaderMessageWidget.ui b/plugins/FeedReader/gui/FeedReaderMessageWidget.ui index 3542c5375..fada5279e 100644 --- a/plugins/FeedReader/gui/FeedReaderMessageWidget.ui +++ b/plugins/FeedReader/gui/FeedReaderMessageWidget.ui @@ -182,7 +182,7 @@ - + :/images/message-state-header.png:/images/message-state-header.png @@ -245,7 +245,7 @@ - + :/images/edit_remove24.png:/images/edit_remove24.png @@ -260,20 +260,63 @@
- - - - 0 - 10 - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - + + + + + + + 0 + 10 + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + + + + pictureLabel + + + Qt::AlignCenter + + + + + + + + + 0 + 10 + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + Copy Link Location + + @@ -297,10 +340,14 @@
gui/common/ElidedLabel.h
1
+ + AspectRatioPixmapLabel + QLabel +
util/AspectRatioPixmapLabel.h
+
- diff --git a/plugins/FeedReader/gui/FeedReaderNotify.cpp b/plugins/FeedReader/gui/FeedReaderNotify.cpp index f2aa7ad1d..95728b225 100644 --- a/plugins/FeedReader/gui/FeedReaderNotify.cpp +++ b/plugins/FeedReader/gui/FeedReaderNotify.cpp @@ -33,3 +33,8 @@ void FeedReaderNotify::notifyMsgChanged(uint32_t feedId, const std::string &msgI { emit msgChanged(feedId, QString::fromStdString(msgId), type); } + +void FeedReaderNotify::notifyOptimizeImage() +{ + emit optimizeImage(); +} diff --git a/plugins/FeedReader/gui/FeedReaderNotify.h b/plugins/FeedReader/gui/FeedReaderNotify.h index 5a8ad712a..5913f1985 100644 --- a/plugins/FeedReader/gui/FeedReaderNotify.h +++ b/plugins/FeedReader/gui/FeedReaderNotify.h @@ -34,10 +34,12 @@ public: /* RsFeedReaderNotify */ virtual void notifyFeedChanged(uint32_t feedId, int type); virtual void notifyMsgChanged(uint32_t feedId, const std::string &msgId, int type); + virtual void notifyOptimizeImage(); signals: void feedChanged(uint32_t feedId, int type); void msgChanged(uint32_t feedId, const QString &msgId, int type); + void optimizeImage(); }; #endif diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp index 99c537498..53a62e669 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.cpp +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.cpp @@ -23,27 +23,27 @@ #include "FeedReaderStringDefs.h" -bool FeedReaderStringDefs::showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text) +bool FeedReaderStringDefs::showError(QWidget *parent, RsFeedResult result, const QString &title, const QString &text) { QString error; switch (result) { - case RS_FEED_ADD_RESULT_SUCCESS: + case RS_FEED_RESULT_SUCCESS: /* no error */ return false; - case RS_FEED_ADD_RESULT_FEED_NOT_FOUND: + case RS_FEED_RESULT_FEED_NOT_FOUND: error = QApplication::translate("FeedReaderStringDefs", "Feed not found."); break; - case RS_FEED_ADD_RESULT_PARENT_NOT_FOUND: + case RS_FEED_RESULT_PARENT_NOT_FOUND: error = QApplication::translate("FeedReaderStringDefs", "Parent not found."); break; - case RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER: + case RS_FEED_RESULT_PARENT_IS_NO_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Parent is no folder."); break; - case RS_FEED_ADD_RESULT_FEED_IS_FOLDER: + case RS_FEED_RESULT_FEED_IS_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Feed is a folder."); break; - case RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER: + case RS_FEED_RESULT_FEED_IS_NO_FOLDER: error = QApplication::translate("FeedReaderStringDefs", "Feed is no folder."); break; default: @@ -101,6 +101,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE: errorText = QApplication::translate("FeedReaderStringDefs", "Unknown response code"); break; + case RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED: + errorText = QApplication::translate("FeedReaderStringDefs", "Download blocked"); + break; /* process */ case RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR: @@ -109,9 +112,9 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT: errorText = QApplication::translate("FeedReaderStringDefs", "Unknown XML format"); break; - case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: - errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); - break; +// case RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create forum"); +// break; case RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND: errorText = QApplication::translate("FeedReaderStringDefs", "Forum not found"); break; @@ -121,6 +124,21 @@ QString FeedReaderStringDefs::errorString(RsFeedReaderErrorState errorState, con case RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR: errorText = QApplication::translate("FeedReaderStringDefs", "Forum has no author"); break; +// case RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE: +// errorText = QApplication::translate("FeedReaderStringDefs", "Can't create board"); +// break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND: + errorText = QApplication::translate("FeedReaderStringDefs", "Board not found"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN: + errorText = QApplication::translate("FeedReaderStringDefs", "You are not admin of the board"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR: + errorText = QApplication::translate("FeedReaderStringDefs", "Board has no author"); + break; + case RS_FEED_ERRORSTATE_PROCESS_POST: + errorText = QApplication::translate("FeedReaderStringDefs", "Some posts could not be created"); + break; case RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR: errorText = QApplication::translate("FeedReaderStringDefs", "Can't read html"); diff --git a/plugins/FeedReader/gui/FeedReaderStringDefs.h b/plugins/FeedReader/gui/FeedReaderStringDefs.h index f4b384c8f..587621e7d 100644 --- a/plugins/FeedReader/gui/FeedReaderStringDefs.h +++ b/plugins/FeedReader/gui/FeedReaderStringDefs.h @@ -30,7 +30,7 @@ class QWidget; class FeedReaderStringDefs { public: - static bool showError(QWidget *parent, RsFeedAddResult result, const QString &title, const QString &text); + static bool showError(QWidget *parent, RsFeedResult result, const QString &title, const QString &text); static QString workState(FeedInfo::WorkState state); static QString errorString(const FeedInfo &feedInfo); static QString errorString(RsFeedReaderErrorState errorState, const std::string &errorString); diff --git a/plugins/FeedReader/gui/FeedTreeWidget.cpp b/plugins/FeedReader/gui/FeedTreeWidget.cpp new file mode 100644 index 000000000..37baaf235 --- /dev/null +++ b/plugins/FeedReader/gui/FeedTreeWidget.cpp @@ -0,0 +1,119 @@ +/******************************************************************************* + * plugins/FeedReader/gui/FeedTreeWidget.cpp * + * * + * Copyright (C) 2012 RetroShare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include "FeedTreeWidget.h" + +FeedTreeWidget::FeedTreeWidget(QWidget *parent) : RSTreeWidget(parent) +{ + mDraggedItem = NULL; +} + +void FeedTreeWidget::dragEnterEvent(QDragEnterEvent *event) +{ + mDraggedItem = currentItem(); + RSTreeWidget::dragEnterEvent(event); +} + +void FeedTreeWidget::dragLeaveEvent(QDragLeaveEvent *event) +{ + RSTreeWidget::dragLeaveEvent(event); + mDraggedItem = NULL; +} + +bool FeedTreeWidget::canDrop(QDropEvent *event, QTreeWidgetItem **dropItem) +{ + if (dropItem) { + *dropItem = NULL; + } + + if (!mDraggedItem) { + /* no drag item */ + return false; + } + + QModelIndex droppedIndex = indexAt(event->pos()); + if (!droppedIndex.isValid()) { + /* no drop target */ + return false; + } + + QTreeWidgetItem *dropItemIntern = itemFromIndex(droppedIndex); + if (!dropItemIntern) { + /* no drop item */ + return false; + } + + if ((dropItemIntern->flags() & Qt::ItemIsDropEnabled) == 0) { + /* drop is disabled */ + return false; + } + + if (dropItemIntern == mDraggedItem->parent()) { + /* drag item parent */ + return false; + } + + if (dropItem) { + *dropItem = dropItemIntern; + } + + return true; +} + +void FeedTreeWidget::dragMoveEvent(QDragMoveEvent *event) +{ + if (!canDrop(event)) { + event->ignore(); + return; + } + + RSTreeWidget::dragMoveEvent(event); +} + +void FeedTreeWidget::dropEvent(QDropEvent *event) +{ + QTreeWidgetItem *dropItem; + if (!canDrop(event, &dropItem)) { + event->ignore(); + return; + } + + if (!mDraggedItem) { + /* no drag item */ + event->ignore(); + return; + } + + QTreeWidgetItem *draggedParent = mDraggedItem->parent(); + if (!draggedParent) { + /* no drag item parent */ + event->ignore(); + return; + } + + if (!dropItem) { + /* no drop item */ + event->ignore(); + return; + } + + emit feedReparent(mDraggedItem, dropItem); +} diff --git a/retroshare-gui/src/gui/common/StyledLabel.h b/plugins/FeedReader/gui/FeedTreeWidget.h similarity index 66% rename from retroshare-gui/src/gui/common/StyledLabel.h rename to plugins/FeedReader/gui/FeedTreeWidget.h index faf0654da..e9eb197a9 100644 --- a/retroshare-gui/src/gui/common/StyledLabel.h +++ b/plugins/FeedReader/gui/FeedTreeWidget.h @@ -1,7 +1,7 @@ /******************************************************************************* - * gui/common/StyledLabel.h * + * plugins/FeedReader/gui/FeedTreeWidget.h * * * - * Copyright (c) 2014, RetroShare Team * + * Copyright (C) 2012 by Retroshare Team * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -18,25 +18,33 @@ * * *******************************************************************************/ -#ifndef _STYLEDLABEL_H -#define _STYLEDLABEL_H +#ifndef _FEEDTREEWIDGET_H +#define _FEEDTREEWIDGET_H -#include +#include "gui/common/RSTreeWidget.h" -class StyledLabel : public QLabel +/* Subclassing RSTreeWidget */ +class FeedTreeWidget : public RSTreeWidget { Q_OBJECT - Q_PROPERTY(int fontSizeFactor READ fontSizeFactor WRITE setFontSizeFactor) public: - StyledLabel(QWidget *parent = NULL); - StyledLabel(const QString &text, QWidget *parent = NULL); + FeedTreeWidget(QWidget *parent = 0); - int fontSizeFactor(); - void setFontSizeFactor(int factor); +Q_SIGNALS: + void feedReparent(QTreeWidgetItem *item, QTreeWidgetItem *newParent); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); private: - int mFontSizeFactor; + bool canDrop(QDropEvent *event, QTreeWidgetItem **dropItem = NULL); + +private: + QTreeWidgetItem *mDraggedItem; }; #endif diff --git a/plugins/FeedReader/gui/PreviewFeedDialog.ui b/plugins/FeedReader/gui/PreviewFeedDialog.ui index 14868c082..41cebc153 100644 --- a/plugins/FeedReader/gui/PreviewFeedDialog.ui +++ b/plugins/FeedReader/gui/PreviewFeedDialog.ui @@ -7,7 +7,7 @@ 0 0 800 - 521 + 564 @@ -16,7 +16,7 @@ true - + 0 @@ -28,7 +28,7 @@ 0 - + 0 @@ -57,6 +57,14 @@ 0 + + + 11 + 75 + true + true + + Name: @@ -284,7 +292,7 @@ - + @@ -324,6 +332,14 @@ 0 + + + 11 + 75 + true + true + + Title: @@ -365,7 +381,7 @@ false - + 0 @@ -387,7 +403,7 @@ - + 0 @@ -451,7 +467,7 @@ QFrame::Raised - + 0 @@ -472,7 +488,7 @@ QFrame::Raised - + 0 @@ -499,7 +515,7 @@ QFrame::Raised - + 0 @@ -513,7 +529,7 @@ 0 - + @@ -572,11 +588,13 @@ - titleFrame - splitter - buttonBox + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
RSPlainTextEdit QPlainTextEdit diff --git a/plugins/FeedReader/interface/rsFeedReader.h b/plugins/FeedReader/interface/rsFeedReader.h index bf524ad0c..326d3e022 100644 --- a/plugins/FeedReader/interface/rsFeedReader.h +++ b/plugins/FeedReader/interface/rsFeedReader.h @@ -25,8 +25,13 @@ #include #include #include +#include class RsFeedReader; +class RsGxsForums; +class RsPosted; +class RsGxsForumGroup; +class RsPostedGroup; extern RsFeedReader *rsFeedReader; enum RsFeedReaderErrorState { @@ -38,14 +43,20 @@ enum RsFeedReaderErrorState { RS_FEED_ERRORSTATE_DOWNLOAD_UNKNOWN_CONTENT_TYPE = 3, RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND = 4, RS_FEED_ERRORSTATE_DOWNLOAD_UNKOWN_RESPONSE_CODE = 5, + RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED = 6, /* process */ RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR = 50, RS_FEED_ERRORSTATE_PROCESS_UNKNOWN_FORMAT = 51, - RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, +// RS_FEED_ERRORSTATE_PROCESS_FORUM_CREATE = 100, RS_FEED_ERRORSTATE_PROCESS_FORUM_NOT_FOUND = 101, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_ADMIN = 102, RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR = 103, +// RS_FEED_ERRORSTATE_PROCESS_POSTED_CREATE = 104, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND = 105, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN = 106, + RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR = 107, + RS_FEED_ERRORSTATE_PROCESS_POST = 108, RS_FEED_ERRORSTATE_PROCESS_HTML_ERROR = 150, RS_FEED_ERRORSTATE_PROCESS_XPATH_INTERNAL_ERROR = 151, @@ -56,14 +67,14 @@ enum RsFeedReaderErrorState { RS_FEED_ERRORSTATE_PROCESS_XSLT_NO_RESULT = 156 }; -enum RsFeedAddResult +enum RsFeedResult { - RS_FEED_ADD_RESULT_SUCCESS, - RS_FEED_ADD_RESULT_FEED_NOT_FOUND, - RS_FEED_ADD_RESULT_PARENT_NOT_FOUND, - RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER, - RS_FEED_ADD_RESULT_FEED_IS_FOLDER, - RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER + RS_FEED_RESULT_SUCCESS, + RS_FEED_RESULT_FEED_NOT_FOUND, + RS_FEED_RESULT_PARENT_NOT_FOUND, + RS_FEED_RESULT_PARENT_IS_NO_FOLDER, + RS_FEED_RESULT_FEED_IS_FOLDER, + RS_FEED_RESULT_FEED_IS_NO_FOLDER }; enum RsFeedTransformationType @@ -102,6 +113,8 @@ public: flag.deactivated = false; flag.forum = false; flag.updateForumInfo = false; + flag.posted = false; + flag.updatePostedInfo = false; flag.embedImages = false; flag.saveCompletePage = false; flag.preview = false; @@ -122,6 +135,7 @@ public: time_t lastUpdate; uint32_t storageTime; std::string forumId; + std::string postedId; WorkState workstate; RsFeedReaderErrorState errorState; std::string errorString; @@ -141,6 +155,11 @@ public: bool deactivated : 1; bool forum : 1; bool updateForumInfo : 1; + bool posted : 1; + bool updatePostedInfo : 1; + bool postedFirstImage : 1; + bool postedOnlyImage : 1; + bool postedShrinkImage : 1; bool embedImages : 1; bool saveCompletePage : 1; bool preview : 1; @@ -166,6 +185,9 @@ public: std::string description; std::string descriptionTransformed; time_t pubDate; + std::string attachmentLink; + std::vector attachment; + std::string attachmentMimeType; struct { bool isnew : 1; @@ -174,6 +196,32 @@ public: } flag; }; +class FeedReaderOptimizeImageTask +{ +public: + enum Type { + POSTED, + SIZE + }; + +public: + Type mType; + std::vector mImage; + std::string mMimeType; + std::vector mImageResult; + std::string mMimeTypeResult; + bool mResult; + +public: + FeedReaderOptimizeImageTask(Type type, const std::vector &image, const std::string &mimeType) + { + mType = type; + mImage = image; + mMimeType = mimeType; + mResult = false; + } +}; + class RsFeedReaderNotify { public: @@ -181,6 +229,7 @@ public: virtual void notifyFeedChanged(uint32_t /*feedId*/, int /*type*/) {} virtual void notifyMsgChanged(uint32_t /*feedId*/, const std::string &/*msgId*/, int /*type*/) {} + virtual void notifyOptimizeImage() {} }; class RsFeedReader @@ -201,24 +250,33 @@ public: virtual bool getSaveInBackground() = 0; virtual void setSaveInBackground(bool saveInBackground) = 0; - virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0; - virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name) = 0; - virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; - virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; - virtual bool removeFeed(uint32_t feedId) = 0; - virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; - virtual void getFeedList(uint32_t parentId, std::list &feedInfos) = 0; - virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0; - virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; - virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0; - virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds) = 0; - virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; - virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos) = 0; - virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds) = 0; - virtual bool processFeed(uint32_t feedId) = 0; - virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0; - virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; - virtual bool clearMessageCache(uint32_t feedId) = 0; + virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) = 0; + virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name) = 0; + virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; + virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo) = 0; + virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId) = 0; + virtual bool removeFeed(uint32_t feedId) = 0; + virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) = 0; + virtual void getFeedList(uint32_t parentId, std::list &feedInfos) = 0; + virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo) = 0; + virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo) = 0; + virtual bool removeMsg(uint32_t feedId, const std::string &msgId) = 0; + virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds) = 0; + virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount) = 0; + virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos) = 0; + virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds) = 0; + virtual bool processFeed(uint32_t feedId) = 0; + virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read) = 0; + virtual bool retransformMsg(uint32_t feedId, const std::string &msgId) = 0; + virtual bool clearMessageCache(uint32_t feedId) = 0; + + virtual RsGxsForums* forums() = 0; + virtual RsPosted* posted() = 0; + virtual bool getForumGroups(std::vector &groups, bool onlyOwn) = 0; + virtual bool getPostedGroups(std::vector &groups, bool onlyOwn) = 0; + + virtual FeedReaderOptimizeImageTask *getOptimizeImageTask() = 0; + virtual void setOptimizeImageTaskResult(FeedReaderOptimizeImageTask *optimizeImageTask) = 0; virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString) = 0; virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString) = 0; diff --git a/plugins/FeedReader/lang/FeedReader_en.ts b/plugins/FeedReader/lang/FeedReader_en.ts index 89cde2fe0..707c8cec9 100644 --- a/plugins/FeedReader/lang/FeedReader_en.ts +++ b/plugins/FeedReader/lang/FeedReader_en.ts @@ -9,7 +9,32 @@ - + + Board + + + + + Update board information + + + + + Only image + + + + + Use first image as board image + + + + + Shrink image + + + + Authentication (not yet supported) @@ -59,12 +84,12 @@ - + Embed images - + Storage time @@ -99,22 +124,22 @@ - + Type - + Forum - + Local Feed - + Transformation @@ -129,7 +154,7 @@ - + Misc @@ -144,17 +169,17 @@ - + Update forum information - + Save complete web page (experimental for local feeds) - + Description: @@ -164,18 +189,18 @@ - + Name: - + Feed Details - - + + Edit feed @@ -277,7 +302,7 @@ FeedReaderDialog - + Feeds @@ -292,7 +317,7 @@ - + Message Folders @@ -342,12 +367,12 @@ - + No name - + Add new folder @@ -398,11 +423,21 @@ Please enter a new name for the folder + + + Move feed + + + + + Cannot move feed. + + FeedReaderFeedItem - + Expand @@ -500,7 +535,7 @@ - + Title @@ -542,12 +577,22 @@ - + The messages will be added to the forum - + + The messages will be added to the forum and the board + + + + + The messages will be added to the board + + + + No name @@ -576,8 +621,18 @@ Remove + + + Add to forum + + + Add to board + + + + Retransform @@ -659,12 +714,12 @@ - + Unknown - + Internal download error @@ -688,6 +743,11 @@ Unknown response code + + + Download blocked + + Internal process error @@ -699,12 +759,7 @@ - - Can't create forum - - - - + Forum not found @@ -718,6 +773,26 @@ Forum has no author + + + Board not found + + + + + You are not admin of the board + + + + + Board has no author + + + + + Some posts could not be created + + Can't read html @@ -790,7 +865,7 @@ - + Name: @@ -825,7 +900,7 @@ - + Title: diff --git a/plugins/VOIP/qss/VOIP_qss.default b/plugins/FeedReader/qss/FeedReader_default.qss similarity index 52% rename from plugins/VOIP/qss/VOIP_qss.default rename to plugins/FeedReader/qss/FeedReader_default.qss index abe80ad93..9b964468c 100644 --- a/plugins/VOIP/qss/VOIP_qss.default +++ b/plugins/FeedReader/qss/FeedReader_default.qss @@ -1,9 +1,3 @@ /* Default stylesheet This file is used as default for all stylesheets and can be overloaded */ -/* Font */ - -VOIPToasterItem QLabel#textLabel -{ - qproperty-fontSizeFactor: 115; -} diff --git a/plugins/FeedReader/qss/FeedReader_qss.qrc b/plugins/FeedReader/qss/FeedReader_qss.qrc index 437503d74..adefd6b1b 100644 --- a/plugins/FeedReader/qss/FeedReader_qss.qrc +++ b/plugins/FeedReader/qss/FeedReader_qss.qrc @@ -1,6 +1,6 @@ - FeedReader_qss.default + FeedReader_default.qss FeedReader_Standard.qss diff --git a/plugins/FeedReader/services/p3FeedReader.cc b/plugins/FeedReader/services/p3FeedReader.cc index d70591c36..3e46a027c 100644 --- a/plugins/FeedReader/services/p3FeedReader.cc +++ b/plugins/FeedReader/services/p3FeedReader.cc @@ -24,6 +24,7 @@ #include "rsitems/rsconfigitems.h" #include "retroshare/rsiface.h" #include "retroshare/rsgxsforums.h" +#include "retroshare/rsposted.h" #include "util/rsstring.h" #include "util/rstime.h" #include "gxs/rsgenexchange.h" @@ -34,6 +35,7 @@ RsFeedReader *rsFeedReader = NULL; #define FEEDREADER_CLEAN_INTERVAL 1 * 60 * 60 // check every hour #define FEEDREADER_FORUM_PREFIX "RSS: " +#define FEEDREADER_POSTED_PREFIX "RSS: " #define MAX_REQUEST_AGE 30 // 30 seconds @@ -41,9 +43,9 @@ RsFeedReader *rsFeedReader = NULL; * #define FEEDREADER_DEBUG *********/ -p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) +p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums, RsPosted *posted) : RsPQIService(RS_SERVICE_TYPE_PLUGIN_FEEDREADER, 5, pgHandler), - mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mPreviewMutex("p3FeedReaderPreview") + mFeedReaderMtx("p3FeedReader"), mDownloadMutex("p3FeedReaderDownload"), mProcessMutex("p3FeedReaderProcess"), mImageMutex("p3FeedReaderImage"), mPreviewMutex("p3FeedReaderPreview") { mNextFeedId = 1; mNextMsgId = 1; @@ -55,6 +57,7 @@ p3FeedReader::p3FeedReader(RsPluginHandler* pgHandler, RsGxsForums *forums) mStandardProxyPort = 0; mLastClean = 0; mForums = forums; + mPosted = posted; mNotify = NULL; mSaveInBackground = false; mStopped = false; @@ -92,6 +95,7 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.updateInterval = feed->updateInterval; info.lastUpdate = feed->lastUpdate; info.forumId = feed->forumId; + info.postedId = feed->postedId; info.storageTime = feed->storageTime; info.errorState = feed->errorState; info.errorString = feed->errorString; @@ -110,6 +114,11 @@ static void feedToInfo(const RsFeedReaderFeed *feed, FeedInfo &info) info.flag.deactivated = (feed->flag & RS_FEED_FLAG_DEACTIVATED); info.flag.forum = (feed->flag & RS_FEED_FLAG_FORUM); info.flag.updateForumInfo = (feed->flag & RS_FEED_FLAG_UPDATE_FORUM_INFO); + info.flag.posted = (feed->flag & RS_FEED_FLAG_POSTED); + info.flag.updatePostedInfo = (feed->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO); + info.flag.postedFirstImage = (feed->flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE); + info.flag.postedOnlyImage = (feed->flag & RS_FEED_FLAG_POSTED_ONLY_IMAGE); + info.flag.postedShrinkImage = (feed->flag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE); info.flag.embedImages = (feed->flag & RS_FEED_FLAG_EMBED_IMAGES); info.flag.saveCompletePage = (feed->flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE); @@ -151,6 +160,7 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) feed->storageTime = info.storageTime; feed->forumId = info.forumId; + feed->postedId = info.postedId; feed->transformationType = info.transformationType; feed->xpathsToUse.ids = info.xpathsToUse; @@ -193,6 +203,24 @@ static void infoToFeed(const FeedInfo &info, RsFeedReaderFeed *feed) if (info.flag.updateForumInfo) { feed->flag |= RS_FEED_FLAG_UPDATE_FORUM_INFO; } + if (info.flag.posted) { + feed->flag |= RS_FEED_FLAG_POSTED; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.updatePostedInfo) { + feed->flag |= RS_FEED_FLAG_UPDATE_POSTED_INFO; + } + if (info.flag.postedFirstImage) { + feed->flag |= RS_FEED_FLAG_POSTED_FIRST_IMAGE; + } + if (info.flag.postedOnlyImage) { + feed->flag |= RS_FEED_FLAG_POSTED_ONLY_IMAGE; + } + if (info.flag.postedShrinkImage) { + feed->flag |= RS_FEED_FLAG_POSTED_SHRINK_IMAGE; + } } static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) @@ -205,6 +233,13 @@ static void feedMsgToInfo(const RsFeedReaderMsg *msg, FeedMsgInfo &info) info.description = msg->description; info.descriptionTransformed = msg->descriptionTransformed; info.pubDate = msg->pubDate; + info.attachmentLink = msg->attachmentLink; + if (!msg->attachment.empty()) { + p3FeedReaderThread::fromBase64(msg->attachment, info.attachment); + } else { + info.attachment.clear(); + } + info.attachmentMimeType = msg->attachmentMimeType; info.flag.isnew = (msg->flag & RS_FEEDMSG_FLAG_NEW); info.flag.read = (msg->flag & RS_FEEDMSG_FLAG_READ); @@ -245,7 +280,7 @@ void p3FeedReader::setStandardStorageTime(uint32_t storageTime) if (mStandardStorageTime != storageTime) { mStandardStorageTime = storageTime; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -262,7 +297,7 @@ void p3FeedReader::setStandardUpdateInterval(uint32_t updateInterval) if (mStandardUpdateInterval != updateInterval) { mStandardUpdateInterval = updateInterval; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -284,7 +319,7 @@ void p3FeedReader::setStandardProxy(bool useProxy, const std::string &proxyAddre mStandardProxyAddress = proxyAddress; mStandardProxyPort = proxyPort; mStandardUseProxy = useProxy; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -301,7 +336,7 @@ void p3FeedReader::setSaveInBackground(bool saveInBackground) if (saveInBackground != mSaveInBackground) { mSaveInBackground = saveInBackground; - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -342,7 +377,7 @@ void p3FeedReader::stopPreviewThreads_locked() } } -RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) +RsFeedResult p3FeedReader::addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId) { feedId = 0; @@ -356,14 +391,14 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFolder - parent id " << parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFolder - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -377,16 +412,16 @@ RsFeedAddResult p3FeedReader::addFolder(uint32_t parentId, const std::string &na feedId = fi->feedId; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name) +RsFeedResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name) { { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -400,33 +435,33 @@ RsFeedAddResult p3FeedReader::setFolder(uint32_t feedId, const std::string &name #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFolder - feed id " << feedId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + return RS_FEED_RESULT_FEED_NOT_FOUND; } if ((feedIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFolder - feed " << feedIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_IS_NO_FOLDER; + return RS_FEED_RESULT_FEED_IS_NO_FOLDER; } RsFeedReaderFeed *fi = feedIt->second; if (fi->name == name) { - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } fi->name = name; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId) +RsFeedResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId) { feedId = 0; @@ -444,14 +479,14 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFeed - parent id " << feedInfo.parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::addFeed - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } @@ -464,20 +499,23 @@ RsFeedAddResult p3FeedReader::addFeed(const FeedInfo &feedInfo, uint32_t &feedId feedId = fi->feedId; } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_ADD); } - return RS_FEED_ADD_RESULT_SUCCESS; + return RS_FEED_RESULT_SUCCESS; } -RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) +RsFeedResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) { std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -491,14 +529,14 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - feed id " << feedId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_NOT_FOUND; + return RS_FEED_RESULT_FEED_NOT_FOUND; } if (feedIt->second->flag & RS_FEED_FLAG_FOLDER) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - feed " << feedIt->second->name << " is a folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_FEED_IS_FOLDER; + return RS_FEED_RESULT_FEED_IS_FOLDER; } if (feedInfo.parentId) { @@ -508,19 +546,20 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - parent id " << feedInfo.parentId << " not found" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_NOT_FOUND; + return RS_FEED_RESULT_PARENT_NOT_FOUND; } if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::setFeed - parent " << parentIt->second->name << " is no folder" << std::endl; #endif - return RS_FEED_ADD_RESULT_PARENT_IS_NO_FOLDER; + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; } } RsFeedReaderFeed *fi = feedIt->second; std::string oldForumId = fi->forumId; + std::string oldPostedId = fi->postedId; std::string oldName = fi->name; std::string oldDescription = fi->description; @@ -534,9 +573,18 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && + (fi->postedId != oldPostedId || fi->name != oldName || fi->description != oldDescription)) { + /* name or description changed, update posted */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -550,7 +598,71 @@ RsFeedAddResult p3FeedReader::setFeed(uint32_t feedId, const FeedInfo &feedInfo) //TODO: error } - return RS_FEED_ADD_RESULT_SUCCESS; + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } + + return RS_FEED_RESULT_SUCCESS; +} + +RsFeedResult p3FeedReader::setParent(uint32_t feedId, uint32_t parentId) +{ + bool changed = false; + + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ + +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - set parent " << parentId << std::endl; +#endif + + std::map::iterator feedIt = mFeeds.find(feedId); + if (feedIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - feed id " << feedId << " not found" << std::endl; +#endif + return RS_FEED_RESULT_FEED_NOT_FOUND; + } + + if (parentId) { + /* check parent id */ + std::map::iterator parentIt = mFeeds.find(parentId); + if (parentIt == mFeeds.end()) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - parent id " << parentId << " not found" << std::endl; +#endif + return RS_FEED_RESULT_PARENT_NOT_FOUND; + } + + if ((parentIt->second->flag & RS_FEED_FLAG_FOLDER) == 0) { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::setParent - parent " << parentIt->second->name << " is no folder" << std::endl; +#endif + return RS_FEED_RESULT_PARENT_IS_NO_FOLDER; + } + } + + RsFeedReaderFeed *fi = feedIt->second; + + if (fi->parentId != parentId) { + fi->parentId = parentId; + changed = true; + } + } + + if (changed) { + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); + + if (mNotify) { + mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); + } + } + + return RS_FEED_RESULT_SUCCESS; } void p3FeedReader::deleteAllMsgs_locked(RsFeedReaderFeed *fi) @@ -628,7 +740,7 @@ bool p3FeedReader::removeFeed(uint32_t feedId) } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (preview) { @@ -682,6 +794,7 @@ bool p3FeedReader::addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId) fi->updateInterval = 0; fi->lastUpdate = 0; fi->forumId.clear(); + fi->postedId.clear(); fi->storageTime = 0; mFeeds[fi->feedId] = fi; @@ -808,7 +921,7 @@ bool p3FeedReader::removeMsg(uint32_t feedId, const std::string &msgId) } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify) { @@ -860,7 +973,7 @@ bool p3FeedReader::removeMsgs(uint32_t feedId, const std::list &msg } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify && !removedMsgs.empty()) { @@ -1158,7 +1271,7 @@ bool p3FeedReader::setMessageRead(uint32_t feedId, const std::string &msgId, boo } if (changed) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_OFTEN); if (mNotify) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); mNotify->notifyMsgChanged(feedId, msgId, NOTIFY_TYPE_MOD); @@ -1212,7 +1325,7 @@ bool p3FeedReader::retransformMsg(uint32_t feedId, const std::string &msgId) } if (feedChanged || msgChanged) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { if (feedChanged) { mNotify->notifyFeedChanged(feedId, NOTIFY_TYPE_MOD); @@ -1266,7 +1379,7 @@ bool p3FeedReader::clearMessageCache(uint32_t feedId) } } - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); return true; } @@ -1343,10 +1456,21 @@ int p3FeedReader::tick() } } + // check images + bool imageToOptimze = false; + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + imageToOptimze = !mImages.empty(); + } + if (mNotify) { for (it = notifyIds.begin(); it != notifyIds.end(); ++it) { mNotify->notifyFeedChanged(*it, NOTIFY_TYPE_MOD); } + if (imageToOptimze) { + mNotify->notifyOptimizeImage(); + } } return 0; @@ -1397,7 +1521,7 @@ void p3FeedReader::cleanFeeds() mLastClean = currentTime; if (removedMsgIds.size()) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); if (mNotify) { std::list >::iterator it; @@ -1709,7 +1833,7 @@ void p3FeedReader::onDownloadSuccess(uint32_t feedId, const std::string &content fi->icon = icon; if (!preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -1760,7 +1884,7 @@ void p3FeedReader::onDownloadError(uint32_t feedId, RsFeedReaderErrorState resul #endif if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -1872,21 +1996,26 @@ void p3FeedReader::onProcessSuccess_filterMsg(uint32_t feedId, std::listerrorString.clear(); if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } } -void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list &msgs, bool single) +void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::list &msgs) { #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " got " << msgs.size() << " messages" << std::endl; #endif + RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; std::list addedMsgs; std::string forumId; - RsGxsId authorId; + RsGxsId forumAuthorId; std::list forumMsgs; + std::string postedId; + RsGxsId postedAuthorId; + std::list postedMsgs; + uint32_t feedFlag = 0; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -1903,7 +2032,8 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listsecond; bool forum = (fi->flag & RS_FEED_FLAG_FORUM) && !fi->preview; - RsFeedReaderErrorState errorState = RS_FEED_ERRORSTATE_OK; + bool posted = (fi->flag & RS_FEED_FLAG_POSTED) && !fi->preview; + feedFlag = fi->flag; if (forum && !msgs.empty()) { if (mForums) { @@ -1913,9 +2043,9 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listforumId), forumGroup)) { if (IS_GROUP_PUBLISHER(forumGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(forumGroup.mMeta.mSubscribeFlags)) { forumId = fi->forumId; - authorId = forumGroup.mMeta.mAuthorId; + forumAuthorId = forumGroup.mMeta.mAuthorId; - if (authorId.isNull()) { + if (forumAuthorId.isNull()) { errorState = RS_FEED_ERRORSTATE_PROCESS_FORUM_NO_AUTHOR; } } else { @@ -1933,6 +2063,34 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listpostedId.empty()) { + /* check posted */ + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(fi->postedId), postedGroup)) { + if (IS_GROUP_PUBLISHER(postedGroup.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(postedGroup.mMeta.mSubscribeFlags)) { + postedId = fi->postedId; + postedAuthorId = postedGroup.mMeta.mAuthorId; + + if (postedAuthorId.isNull()) { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_AUTHOR; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NO_ADMIN; + } + } else { + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - posted id is empty (" << fi->name << ")" << std::endl; + errorState = RS_FEED_ERRORSTATE_PROCESS_POSTED_NOT_FOUND; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } + } + /* process msgs */ if (errorState == RS_FEED_ERRORSTATE_OK) { /* process msgs */ @@ -1949,11 +2107,19 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listmsgId, "%lu", mNextMsgId++); } - if (forum) { + if (forum || posted) { miNew->flag = RS_FEEDMSG_FLAG_DELETED; - forumMsgs.push_back(*miNew); + if (forum) { + forumMsgs.push_back(*miNew); + } + if (posted) { + postedMsgs.push_back(*miNew); + } miNew->description.clear(); miNew->descriptionTransformed.clear(); + miNew->attachmentLink.clear(); + miNew->attachment.clear(); + miNew->attachmentMimeType.clear(); } else { miNew->flag = RS_FEEDMSG_FLAG_NEW; addedMsgs.push_back(miNew->msgId); @@ -1969,60 +2135,190 @@ void p3FeedReader::onProcessSuccess_addMsgs(uint32_t feedId, std::listfeedId << " (" << fi->name << ") added " << newMsgs << "/" << msgs.size() << " messages" << std::endl; #endif } + } - if (!single) { - fi->workstate = RsFeedReaderFeed::WAITING; - fi->content.clear(); - fi->errorState = errorState; - fi->lastUpdate = time(NULL); + bool postError = false; + + if (errorState == RS_FEED_ERRORSTATE_OK) { + if (!forumId.empty() && !forumMsgs.empty()) { + if (mForums) { + /* a bit tricky */ + RsGenExchange *genExchange = dynamic_cast(mForums); + if (genExchange) { + /* add messages as forum messages */ + std::list::iterator msgIt; + for (msgIt = forumMsgs.begin(); msgIt != forumMsgs.end(); ++msgIt) { + RsFeedReaderMsg &mi = *msgIt; + + /* convert to forum messages */ + RsGxsForumMsg forumMsg; + forumMsg.mMeta.mGroupId = RsGxsGroupId(forumId); + forumMsg.mMeta.mMsgName = mi.title; + forumMsg.mMeta.mAuthorId = forumAuthorId; + + std::string description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + /* add link */ + if (!mi.link.empty()) { + description += "
" + mi.link + ""; + } + + if (!mi.attachmentBinary.empty()) { + if (p3FeedReaderThread::isContentType(mi.attachmentMimeType, "image/")) { + /* add attachement to description */ + + // optimize image + std::vector optimizedImage; + std::string optimizedMimeType; + if (optimizeImage(FeedReaderOptimizeImageTask::SIZE, mi.attachmentBinary, mi.attachmentBinaryMimeType, optimizedImage, optimizedMimeType)) { + std::string base64; + if (p3FeedReaderThread::toBase64(optimizedImage, base64)) { + std::string imageBase64; + rs_sprintf(imageBase64, "data:%s;base64,%s", optimizedMimeType.c_str(), base64.c_str()); + description += "
"; + } + } + } + } + + forumMsg.mMsg = description; + + uint32_t token; + if (mForums->createMsg(token, forumMsg) && waitForToken(mForums, token)) { + RsGxsGrpMsgIdPair msgPair; + if (mForums->acknowledgeMsg(token, msgPair)) { + /* set to new */ + genExchange->setMsgStatusFlags(token, msgPair, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't add forum message " << mi.title << " for feed " << forumId << std::endl; +#endif + postError = true; + } + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not derived from RsGenExchange" << std::endl; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not set" << std::endl; + } } - if (!fi->preview) { - IndicateConfigChanged(); + if (!postedId.empty() && !postedMsgs.empty()) { + if (mPosted) { + /* a bit tricky */ + RsGenExchange *genExchange = dynamic_cast(mPosted); + if (genExchange) { + /* add messages as posted messages */ + std::list::iterator msgIt; + for (msgIt = postedMsgs.begin(); msgIt != postedMsgs.end(); ++msgIt) { + RsFeedReaderMsg &mi = *msgIt; + + /* convert to posted messages */ + RsPostedPost postedPost; + postedPost.mMeta.mGroupId = RsGxsGroupId(postedId); + postedPost.mMeta.mMsgName = mi.title; + postedPost.mMeta.mAuthorId = postedAuthorId; + postedPost.mLink = mi.link; + + std::string description; + if (feedFlag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) { + if (!mi.postedFirstImage.empty()) { + /* use first image as image for posted and description without image as notes */ + if (feedFlag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE) { + // optimize image + std::vector optimizedImage; + std::string optimizedMimeType; + if (optimizeImage(FeedReaderOptimizeImageTask::POSTED, mi.postedFirstImage, mi.postedFirstImageMimeType, optimizedImage, optimizedMimeType)) { + postedPost.mImage.copy(optimizedImage.data(), optimizedImage.size()); + } + } else { + postedPost.mImage.copy(mi.postedFirstImage.data(), mi.postedFirstImage.size()); + } + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore description */ + } else { + description = mi.postedDescriptionWithoutFirstImage; + } + } else { + if (feedFlag & RS_FEED_FLAG_POSTED_ONLY_IMAGE) { + /* ignore messages without image */ + continue; + } + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + } + } else { + description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; + + if (!mi.attachmentBinary.empty()) { + if (p3FeedReaderThread::isContentType(mi.attachmentMimeType, "image/")) { + /* use attachement as image */ + + if (feedFlag & RS_FEED_FLAG_POSTED_SHRINK_IMAGE) { + // optimize image + std::vector optimizedImage; + std::string optimizedMimeType; + if (optimizeImage(FeedReaderOptimizeImageTask::POSTED, mi.attachmentBinary, mi.attachmentBinaryMimeType, optimizedImage, optimizedMimeType)) { + postedPost.mImage.copy(optimizedImage.data(), optimizedImage.size()); + } + } else { + postedPost.mImage.copy(mi.attachmentBinary.data(), mi.attachmentBinary.size()); + } + } + } + } + + postedPost.mNotes = description; + + uint32_t token; + if (mPosted->createPost(token, postedPost) && waitForToken(mPosted, token)) { + RsGxsGrpMsgIdPair msgPair; + if (mPosted->acknowledgeMsg(token, msgPair)) { + /* set to new */ + genExchange->setMsgStatusFlags(token, msgPair, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); + } + } else { +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't add posted message " << mi.title << " for feed " << postedId << std::endl; +#endif + postError = true; + } + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not derived from RsGenExchange" << std::endl; + } + } else { + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process posted, member mPosted is not set" << std::endl; + } } } - if (!forumId.empty() && !forumMsgs.empty()) { - if (mForums) { - /* a bit tricky */ - RsGenExchange *genExchange = dynamic_cast(mForums); - if (genExchange) { - /* add messages as forum messages */ - std::list::iterator msgIt; - for (msgIt = forumMsgs.begin(); msgIt != forumMsgs.end(); ++msgIt) { - RsFeedReaderMsg &mi = *msgIt; + { + RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ - /* convert to forum messages */ - RsGxsForumMsg forumMsg; - forumMsg.mMeta.mGroupId = RsGxsGroupId(forumId); - forumMsg.mMeta.mMsgName = mi.title; - forumMsg.mMeta.mAuthorId = authorId; - - std::string description = mi.descriptionTransformed.empty() ? mi.description : mi.descriptionTransformed; - /* add link */ - if (!mi.link.empty()) { - description += "
" + mi.link + ""; - } - forumMsg.mMsg = description; - - uint32_t token; - if (mForums->createMsg(token, forumMsg) && waitForToken(token)) { - RsGxsGrpMsgIdPair msgPair; - if (mForums->acknowledgeMsg(token, msgPair)) { - /* set to new */ - genExchange->setMsgStatusFlags(token, msgPair, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD, GXS_SERV::GXS_MSG_STATUS_GUI_NEW | GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD); - } - } else { + /* find feed */ + std::map::iterator it = mFeeds.find(feedId); + if (it == mFeeds.end()) { + /* feed not found */ #ifdef FEEDREADER_DEBUG - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't add forum message " << mi.title << " for feed " << forumId << std::endl; + std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - feed " << feedId << " not found" << std::endl; #endif - } - } - } else { - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not derived from RsGenExchange" << std::endl; + return; + } + + RsFeedReaderFeed *fi = it->second; + + if (!fi->preview) { + fi->workstate = RsFeedReaderFeed::WAITING; + fi->content.clear(); + if (errorState == RS_FEED_ERRORSTATE_OK && postError) { + // post error occured + errorState = RS_FEED_ERRORSTATE_PROCESS_POST; } - } else { - std::cerr << "p3FeedReader::onProcessSuccess_addMsgs - can't process forum, member mForums is not set" << std::endl; + fi->errorState = errorState; + fi->lastUpdate = time(NULL); + + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -2064,7 +2360,7 @@ void p3FeedReader::onProcessError(uint32_t feedId, RsFeedReaderErrorState result #endif if (!fi->preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } } @@ -2080,6 +2376,9 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s std::string forumId; std::string forumName; std::string forumDescription; + std::string postedId; + std::string postedName; + std::string postedDescription; { RsStackMutex stack(mFeedReaderMtx); /******* LOCK STACK MUTEX *********/ @@ -2118,11 +2417,19 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s forumDescription = fi->description; forumName.insert(0, FEEDREADER_FORUM_PREFIX); } + + if ((fi->flag & RS_FEED_FLAG_POSTED) && (fi->flag & RS_FEED_FLAG_UPDATE_POSTED_INFO) && !fi->postedId.empty() && !preview) { + /* change posted too */ + postedId = fi->postedId; + postedName = fi->name; + postedDescription = fi->description; + postedName.insert(0, FEEDREADER_POSTED_PREFIX); + } } if (changed) { if (!preview) { - IndicateConfigChanged(); + IndicateConfigChanged(RsConfigMgr::CheckPriority::SAVE_NOW); } if (mNotify) { @@ -2137,6 +2444,14 @@ void p3FeedReader::setFeedInfo(uint32_t feedId, const std::string &name, const s } //TODO: error } + + if (!postedId.empty()) { + RsPostedGroup postedGroup; + if (getPostedGroup(RsGxsGroupId(postedId), postedGroup)) { + updatePostedGroup(postedGroup, postedName, postedDescription); + } + //TODO: error + } } bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup) @@ -2159,7 +2474,7 @@ bool p3FeedReader::getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &f uint32_t token; mForums->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::getForumGroup - waitForToken for request failed" << std::endl; return false; } @@ -2202,7 +2517,7 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return false; } - if (!waitForToken(token)) { + if (!waitForToken(mForums, token)) { std::cerr << "p3FeedReader::updateForumGroup - waitForToken for update failed" << std::endl; return false; } @@ -2211,13 +2526,85 @@ bool p3FeedReader::updateForumGroup(const RsGxsForumGroup &forumGroup, const std return true; } -bool p3FeedReader::waitForToken(uint32_t token) +bool p3FeedReader::getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup) { - if (!mForums) { + if (!mPosted) { + std::cerr << "p3FeedReader::getPostedGroup - can't get posted group " << groupId.toStdString() << ", member mPosted is not set" << std::endl; return false; } - RsTokenService *service = mForums->getTokenService(); + if (groupId.isNull()) { + std::cerr << "p3FeedReader::getPostedGroup - group id is not valid" << std::endl; + return false; + } + + std::list grpIds; + grpIds.push_back(groupId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mPosted->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds); + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::getPostedGroup - waitForToken for request failed" << std::endl; + return false; + } + + std::vector groups; + if (!mPosted->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getPostedGroup - Error getting data" << std::endl; + return false; + } + + if (groups.size() != 1) { + std::cerr << "p3FeedReader::getPostedGroup - Wrong number of items" << std::endl; + return false; + } + + postedGroup = groups[0]; + + return true; +} + +bool p3FeedReader::updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription) +{ + if (!mPosted) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << postedGroup.mMeta.mGroupId.toStdString() << ", member mPosted is not set" << std::endl; + return false; + } + + if (postedGroup.mMeta.mGroupName == groupName && postedGroup.mDescription == groupDescription) { + /* No change */ + return true; + } + + RsPostedGroup newPostedGroup = postedGroup; + newPostedGroup.mMeta.mGroupName = groupName; + newPostedGroup.mDescription = groupDescription; + + uint32_t token; + if (!mPosted->updateGroup(token, newPostedGroup)) { + std::cerr << "p3FeedReader::updatePostedGroup - can't change posted " << newPostedGroup.mMeta.mGroupId.toStdString() << std::endl; + return false; + } + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::updatePostedGroup - waitForToken for update failed" << std::endl; + return false; + } + + /* Posted updated */ + return true; +} + +bool p3FeedReader::waitForToken(RsGxsIfaceHelper *interface, uint32_t token) +{ + if (!interface) { + return false; + } + + RsTokenService *service = interface->getTokenService(); int count = MAX_REQUEST_AGE * 2; while (!mStopped) { @@ -2239,3 +2626,169 @@ bool p3FeedReader::waitForToken(uint32_t token) return false; } + +bool p3FeedReader::getForumGroups(std::vector &groups, bool onlyOwn) +{ + if (!mForums) { + std::cerr << "p3FeedReader::getForumGroups - can't get groups, member mForums is not set" << std::endl; + return false; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + uint32_t token; + if (!mForums->requestGroupInfo(token, opts)) { + std::cerr << "p3FeedReader::getForumGroups - can't get group list" << std::endl; + return false; + } + + if (!waitForToken(mForums, token)) { + std::cerr << "p3FeedReader::getForumGroups - waitForToken for list failed" << std::endl; + return false; + } + + if (!mForums->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getForumGroups - getGroupData failed" << std::endl; + return false; + } + + if (onlyOwn) { + // filter groups + for (std::vector::iterator it = groups.begin(); it != groups.end(); ) { + const RsGxsForumGroup &group = *it; + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags)) { + ++it; + } else { + it = groups.erase(it); + } + } + } + + return true; +} + +bool p3FeedReader::getPostedGroups(std::vector &groups, bool onlyOwn) +{ + if (!mPosted) { + std::cerr << "p3FeedReader::getPostedGroups - can't get groups, member mPosted is not set" << std::endl; + return false; + } + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + + uint32_t token; + if (!mPosted->requestGroupInfo(token, opts)) { + std::cerr << "p3FeedReader::getPostedGroups - can't get group list" << std::endl; + return false; + } + + if (!waitForToken(mPosted, token)) { + std::cerr << "p3FeedReader::getPostedGroups - waitForToken for list failed" << std::endl; + return false; + } + + if (!mPosted->getGroupData(token, groups)) { + std::cerr << "p3FeedReader::getForumGroups - getGroupData failed" << std::endl; + return false; + } + + if (onlyOwn) { + // filter groups + for (std::vector::iterator it = groups.begin(); it != groups.end(); ) { + const RsPostedGroup &group = *it; + if (IS_GROUP_PUBLISHER(group.mMeta.mSubscribeFlags) && IS_GROUP_ADMIN(group.mMeta.mSubscribeFlags)) { + ++it; + } else { + it = groups.erase(it); + } + } + } + + return true; +} + +bool p3FeedReader::optimizeImage(FeedReaderOptimizeImageTask::Type type, const std::vector &image, const std::string &mimeType, std::vector &resultImage, std::string &resultMimeType) +{ + if (!mNotify) { + return false; + } + + FeedReaderOptimizeImageTask *optimizeImageTask = new FeedReaderOptimizeImageTask(type, image, mimeType); + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + mImages.push_back(optimizeImageTask); + } + + /* Wait until task is complete */ + int nSeconds = 0; + while (true) { + if (mStopped) { + return false; + } + + rstime::rs_usleep(1000 * 1000); // 1 second + + if (++nSeconds >= 30) { + // timeout + std::list::iterator it = std::find(mImages.begin(), mImages.end(), optimizeImageTask); + if (it != mImages.end()) { + mImages.erase(it); + + delete(optimizeImageTask); + + return false; + } + + // not found in mImages? + } + + { + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + std::list::iterator it = std::find(mResultImages.begin(), mResultImages.end(), optimizeImageTask); + if (it != mResultImages.end()) { + mResultImages.erase(it); + + bool result = optimizeImageTask->mResult; + if (result) { + resultImage = optimizeImageTask->mImageResult; + resultMimeType = optimizeImageTask->mMimeTypeResult; + } + + delete(optimizeImageTask); + + return result; + } + } + } + + return false; +} + +FeedReaderOptimizeImageTask *p3FeedReader::getOptimizeImageTask() +{ + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + if (mImages.empty()) { + return NULL; + } + + FeedReaderOptimizeImageTask *imageResize = mImages.front(); + mImages.pop_front(); + + return imageResize; +} + +void p3FeedReader::setOptimizeImageTaskResult(FeedReaderOptimizeImageTask *optimizeImageTask) +{ + if (!optimizeImageTask) { + return; + } + + RsStackMutex stack(mImageMutex); /******* LOCK STACK MUTEX *********/ + + mResultImages.push_back(optimizeImageTask); +} diff --git a/plugins/FeedReader/services/p3FeedReader.h b/plugins/FeedReader/services/p3FeedReader.h index 08fa3619b..0df9bf79e 100644 --- a/plugins/FeedReader/services/p3FeedReader.h +++ b/plugins/FeedReader/services/p3FeedReader.h @@ -33,11 +33,14 @@ class p3FeedReaderThread; class RsGxsForums; struct RsGxsForumGroup; +class RsPosted; +struct RsPostedGroup; +class RsGxsIfaceHelper; class p3FeedReader : public RsPQIService, public RsFeedReader { public: - p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums); + p3FeedReader(RsPluginHandler *pgHandler, RsGxsForums *forums, RsPosted *posted); /****************** FeedReader Interface *************/ virtual void stop(); @@ -52,24 +55,33 @@ public: virtual bool getSaveInBackground(); virtual void setSaveInBackground(bool saveInBackground); - virtual RsFeedAddResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId); - virtual RsFeedAddResult setFolder(uint32_t feedId, const std::string &name); - virtual RsFeedAddResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); - virtual RsFeedAddResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); - virtual bool removeFeed(uint32_t feedId); - virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); - virtual void getFeedList(uint32_t parentId, std::list &feedInfos); - virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo); - virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo); - virtual bool removeMsg(uint32_t feedId, const std::string &msgId); - virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds); - virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); - virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos); - virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds); - virtual bool processFeed(uint32_t feedId); - virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read); - virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); - virtual bool clearMessageCache(uint32_t feedId); + virtual RsFeedResult addFolder(uint32_t parentId, const std::string &name, uint32_t &feedId); + virtual RsFeedResult setFolder(uint32_t feedId, const std::string &name); + virtual RsFeedResult addFeed(const FeedInfo &feedInfo, uint32_t &feedId); + virtual RsFeedResult setFeed(uint32_t feedId, const FeedInfo &feedInfo); + virtual RsFeedResult setParent(uint32_t feedId, uint32_t parentId); + virtual bool removeFeed(uint32_t feedId); + virtual bool addPreviewFeed(const FeedInfo &feedInfo, uint32_t &feedId); + virtual void getFeedList(uint32_t parentId, std::list &feedInfos); + virtual bool getFeedInfo(uint32_t feedId, FeedInfo &feedInfo); + virtual bool getMsgInfo(uint32_t feedId, const std::string &msgId, FeedMsgInfo &msgInfo); + virtual bool removeMsg(uint32_t feedId, const std::string &msgId); + virtual bool removeMsgs(uint32_t feedId, const std::list &msgIds); + virtual bool getMessageCount(uint32_t feedId, uint32_t *msgCount, uint32_t *newCount, uint32_t *unreadCount); + virtual bool getFeedMsgList(uint32_t feedId, std::list &msgInfos); + virtual bool getFeedMsgIdList(uint32_t feedId, std::list &msgIds); + virtual bool processFeed(uint32_t feedId); + virtual bool setMessageRead(uint32_t feedId, const std::string &msgId, bool read); + virtual bool retransformMsg(uint32_t feedId, const std::string &msgId); + virtual bool clearMessageCache(uint32_t feedId); + + virtual RsGxsForums* forums() { return mForums; } + virtual RsPosted* posted() { return mPosted; } + virtual bool getForumGroups(std::vector &groups, bool onlyOwn); + virtual bool getPostedGroups(std::vector &groups, bool onlyOwn); + + virtual FeedReaderOptimizeImageTask *getOptimizeImageTask(); + virtual void setOptimizeImageTaskResult(FeedReaderOptimizeImageTask *optimizeImageTask); virtual RsFeedReaderErrorState processXPath(const std::list &xpathsToUse, const std::list &xpathsToRemove, std::string &description, std::string &errorString); virtual RsFeedReaderErrorState processXslt(const std::string &xslt, std::string &description, std::string &errorString); @@ -83,7 +95,7 @@ public: void onDownloadSuccess(uint32_t feedId, const std::string &content, std::string &icon); void onDownloadError(uint32_t feedId, RsFeedReaderErrorState result, const std::string &errorString); void onProcessSuccess_filterMsg(uint32_t feedId, std::list &msgs); - void onProcessSuccess_addMsgs(uint32_t feedId, std::list &msgs, bool single); + void onProcessSuccess_addMsgs(uint32_t feedId, std::list &msgs); void onProcessError(uint32_t feedId, RsFeedReaderErrorState result, const std::string &errorString); bool getFeedToProcess(RsFeedReaderFeed &feed, uint32_t neededFeedId); @@ -92,7 +104,10 @@ public: bool getForumGroup(const RsGxsGroupId &groupId, RsGxsForumGroup &forumGroup); bool updateForumGroup(const RsGxsForumGroup &forumGroup, const std::string &groupName, const std::string &groupDescription); - bool waitForToken(uint32_t token); + bool getPostedGroup(const RsGxsGroupId &groupId, RsPostedGroup &postedGroup); + bool updatePostedGroup(const RsPostedGroup &postedGroup, const std::string &groupName, const std::string &groupDescription); + bool waitForToken(RsGxsIfaceHelper *interface, uint32_t token); + bool optimizeImage(FeedReaderOptimizeImageTask::Type type, const std::vector &image, const std::string &mimeType, std::vector &resultImage, std::string &resultMimeType); protected: /****************** p3Config STUFF *******************/ @@ -109,6 +124,7 @@ private: private: time_t mLastClean; RsGxsForums *mForums; + RsPosted *mPosted; RsFeedReaderNotify *mNotify; volatile bool mStopped; @@ -133,6 +149,10 @@ private: RsMutex mProcessMutex; std::list mProcessFeeds; + RsMutex mImageMutex; + std::list mImages; + std::list mResultImages; + RsMutex mPreviewMutex; p3FeedReaderThread *mPreviewDownloadThread; p3FeedReaderThread *mPreviewProcessThread; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.cc b/plugins/FeedReader/services/p3FeedReaderThread.cc index 38f966663..845b5c82b 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.cc +++ b/plugins/FeedReader/services/p3FeedReaderThread.cc @@ -89,7 +89,7 @@ void p3FeedReaderThread::threadTick() /* first, filter the messages */ mFeedReader->onProcessSuccess_filterMsg(feed.feedId, msgs); if (isRunning()) { - /* second, process the descriptions */ + /* second, process the descriptions and attachment */ for (it = msgs.begin(); it != msgs.end(); ) { if (!isRunning()) { break; @@ -107,7 +107,7 @@ void p3FeedReaderThread::threadTick() std::list msgSingle; msgSingle.push_back(mi); - mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgSingle, true); + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgSingle); /* delete not accepted message */ std::list::iterator it1; @@ -122,12 +122,15 @@ void p3FeedReaderThread::threadTick() ++it; } } - if (isRunning()) { - if (result == RS_FEED_ERRORSTATE_OK) { - /* third, add messages */ - mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgs, false); - } else { - mFeedReader->onProcessError(feed.feedId, result, errorString); + + if (!feed.preview) { + if (isRunning()) { + if (result == RS_FEED_ERRORSTATE_OK) { + /* third, add messages */ + mFeedReader->onProcessSuccess_addMsgs(feed.feedId, msgs); + } else { + mFeedReader->onProcessError(feed.feedId, result, errorString); + } } } } @@ -150,12 +153,12 @@ void p3FeedReaderThread::threadTick() /****************************** Download ***********************************/ /***************************************************************************/ -static bool isContentType(const std::string &contentType, const char *type) +bool p3FeedReaderThread::isContentType(const std::string &contentType, const char *type) { return (strncasecmp(contentType.c_str(), type, strlen(type)) == 0); } -static bool toBase64(const std::vector &data, std::string &base64) +bool p3FeedReaderThread::toBase64(const std::vector &data, std::string &base64) { bool result = false; @@ -184,6 +187,28 @@ static bool toBase64(const std::vector &data, std::string &base64 return result; } +bool p3FeedReaderThread::fromBase64(const std::string &base64, std::vector &data) +{ + bool result = false; + + BIO *b64 = BIO_new(BIO_f_base64()); + if (b64) { + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + BIO *source = BIO_new_mem_buf(base64.c_str(), -1); // read-only source + if (source) { + BIO_push(b64, source); + const int maxlen = base64.length() / 4 * 3 + 1; + data.resize(maxlen); + const int len = BIO_read(b64, data.data(), maxlen); + data.resize(len); + result = true; + } + BIO_free_all(b64); + } + + return result; +} + static std::string getBaseLink(std::string link) { size_t found = link.rfind('/'); @@ -196,7 +221,7 @@ static std::string getBaseLink(std::string link) static std::string calculateLink(const std::string &baseLink, const std::string &link) { - if (link.substr(0, 7) == "http://") { + if (link.substr(0, 7) == "http://" || link.substr(0, 8) == "https://") { /* absolute link */ return link; } @@ -204,8 +229,14 @@ static std::string calculateLink(const std::string &baseLink, const std::string /* calculate link of base link */ std::string resultLink = baseLink; - /* link should begin with "http://" */ - if (resultLink.substr(0, 7) != "http://") { + int hostStart = 0; + /* link should begin with "http://" or "https://" */ + if (resultLink.substr(0, 7) == "http://") { + hostStart = 7; + } else if (resultLink.substr(0, 8) == "https://") { + hostStart = 8; + } else { + hostStart = 7; resultLink.insert(0, "http://"); } @@ -216,7 +247,7 @@ static std::string calculateLink(const std::string &baseLink, const std::string if (*link.begin() == '/') { /* link begins with "/" */ - size_t found = resultLink.find('/', 7); + size_t found = resultLink.find('/', hostStart); if (found != std::string::npos) { resultLink.erase(found); } @@ -245,12 +276,12 @@ static bool getFavicon(CURLWrapper &CURL, const std::string &url, std::string &i if (code == CURLE_OK) { if (CURL.responseCode() == 200) { std::string contentType = CURL.contentType(); - if (isContentType(contentType, "image/x-icon") || - isContentType(contentType, "application/octet-stream") || - isContentType(contentType, "text/plain")) { + if (p3FeedReaderThread::isContentType(contentType, "image/") || + p3FeedReaderThread::isContentType(contentType, "application/octet-stream") || + p3FeedReaderThread::isContentType(contentType, "text/plain")) { if (!vicon.empty()) { #warning p3FeedReaderThread.cc TODO thunder2: check it - result = toBase64(vicon, icon); + result = p3FeedReaderThread::toBase64(vicon, icon); } } } @@ -296,6 +327,9 @@ RsFeedReaderErrorState p3FeedReaderThread::download(const RsFeedReaderFeed &feed } } break; + case 403: + result = RS_FEED_ERRORSTATE_DOWNLOAD_BLOCKED; + break; case 404: result = RS_FEED_ERRORSTATE_DOWNLOAD_NOT_FOUND; break; @@ -959,6 +993,19 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed, item->pubDate = time(NULL); } + if (feedFormat == FORMAT_RSS) { + /* */ + xmlNodePtr enclosure = xml.findNode(node->children, "enclosure", false); + if (enclosure) { + std::string enclosureMimeType = xml.getAttr(enclosure, "type"); + std::string enclosureUrl = xml.getAttr(enclosure, "url"); + if (!enclosureUrl.empty()) { + item->attachmentLink = enclosureUrl; + item->attachmentMimeType = enclosureMimeType; + } + } + } + entries.push_back(item); } } else { @@ -1013,6 +1060,40 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe RsFeedReaderErrorState result = RS_FEED_ERRORSTATE_OK; std::string proxy = getProxyForFeed(feed); + /* attachment */ + if (!msg->attachmentLink.empty()) { + if (isContentType(msg->attachmentMimeType, "image/")) { + CURLWrapper CURL(proxy); + CURLcode code = CURL.downloadBinary(msg->attachmentLink, msg->attachmentBinary); + if (code == CURLE_OK && CURL.responseCode() == 200) { + std::string contentType = CURL.contentType(); + if (isContentType(contentType, "image/")) { + msg->attachmentBinaryMimeType = contentType; + + bool forum = (feed.flag & RS_FEED_FLAG_FORUM) && !feed.preview; + bool posted = (feed.flag & RS_FEED_FLAG_POSTED) && !feed.preview; + + if (!forum && ! posted) { + /* no need to optimize image */ + std::vector optimizedBinary; + std::string optimizedMimeType; + if (mFeedReader->optimizeImage(FeedReaderOptimizeImageTask::SIZE, msg->attachmentBinary, msg->attachmentBinaryMimeType, optimizedBinary, optimizedMimeType)) { + if (toBase64(optimizedBinary, msg->attachment)) { + msg->attachmentMimeType = optimizedMimeType; + } else { + msg->attachment.clear(); + } + } + } + } else { + msg->attachmentBinary.clear(); + } + } else { + msg->attachmentBinary.clear(); + } + } + } + std::string url; if (feed.flag & RS_FEED_FLAG_SAVE_COMPLETE_PAGE) { #ifdef FEEDREADER_DEBUG @@ -1070,12 +1151,19 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (isRunning()) { /* process description */ + bool processPostedFirstImage = (feed.flag & RS_FEED_FLAG_POSTED_FIRST_IMAGE) ? true : false; + if (!msg->attachmentBinary.empty()) { + /* use attachment as image */ + processPostedFirstImage = false; + } + //long todo; // encoding HTMLWrapper html; if (html.readHTML(msg->description.c_str(), url.c_str())) { xmlNodePtr root = html.getRootElement(); if (root) { std::list nodesToDelete; + xmlNodePtr postedFirstImageNode = NULL; /* process all children */ std::list nodes; @@ -1200,14 +1288,24 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (code == CURLE_OK && CURL.responseCode() == 200) { std::string contentType = CURL.contentType(); if (isContentType(contentType, "image/")) { - std::string base64; - if (toBase64(data, base64)) { - std::string imageBase64; - rs_sprintf(imageBase64, "data:%s;base64,%s", contentType.c_str(), base64.c_str()); - if (html.setAttr(node, "src", imageBase64.c_str())) { - removeImage = false; + std::vector optimizedData; + std::string optimizedMimeType; + if (mFeedReader->optimizeImage(FeedReaderOptimizeImageTask::SIZE, data, contentType, optimizedData, optimizedMimeType)) { + std::string base64; + if (toBase64(optimizedData, base64)) { + std::string imageBase64; + rs_sprintf(imageBase64, "data:%s;base64,%s", optimizedMimeType.c_str(), base64.c_str()); + if (html.setAttr(node, "src", imageBase64.c_str())) { + removeImage = false; + } } } + if (processPostedFirstImage && postedFirstImageNode == NULL) { + /* set first image */ + msg->postedFirstImage = data; + msg->postedFirstImageMimeType = contentType; + postedFirstImageNode = node; + } } } } @@ -1241,7 +1339,22 @@ RsFeedReaderErrorState p3FeedReaderThread::processMsg(const RsFeedReaderFeed &fe if (result == RS_FEED_ERRORSTATE_OK) { if (isRunning()) { - if (!html.saveHTML(msg->description)) { + if (html.saveHTML(msg->description)) { + if (postedFirstImageNode) { + /* Remove first image and create description without the image */ + xmlUnlinkNode(postedFirstImageNode); + xmlFreeNode(postedFirstImageNode); + + if (!html.saveHTML(msg->postedDescriptionWithoutFirstImage)) { + errorString = html.lastError(); +#ifdef FEEDREADER_DEBUG + std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; + std::cerr << " Error: " << errorString << std::endl; +#endif + result = RS_FEED_ERRORSTATE_PROCESS_INTERNAL_ERROR; + } + } + } else { errorString = html.lastError(); #ifdef FEEDREADER_DEBUG std::cerr << "p3FeedReaderThread::processHTML - feed " << feed.feedId << " (" << feed.name << ") cannot dump html" << std::endl; diff --git a/plugins/FeedReader/services/p3FeedReaderThread.h b/plugins/FeedReader/services/p3FeedReaderThread.h index 48d920dd6..a9be84010 100644 --- a/plugins/FeedReader/services/p3FeedReaderThread.h +++ b/plugins/FeedReader/services/p3FeedReaderThread.h @@ -54,6 +54,11 @@ public: static RsFeedReaderErrorState processXslt(const std::string &xslt, HTMLWrapper &html, std::string &errorString); static RsFeedReaderErrorState processTransformation(const RsFeedReaderFeed &feed, RsFeedReaderMsg *msg, std::string &errorString); + + static bool isContentType(const std::string &contentType, const char *type); + static bool toBase64(const std::vector &data, std::string &base64); + static bool fromBase64(const std::string &base64, std::vector &data); + private: virtual void threadTick() override; /// @see RsTickingThread diff --git a/plugins/FeedReader/services/rsFeedReaderItems.cc b/plugins/FeedReader/services/rsFeedReaderItems.cc index 04a6c8f1e..0d5b1f60b 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.cc +++ b/plugins/FeedReader/services/rsFeedReaderItems.cc @@ -46,6 +46,7 @@ void RsFeedReaderFeed::clear() storageTime = 0; flag = 0; forumId.clear(); + postedId.clear(); description.clear(); icon.clear(); errorState = RS_FEED_ERRORSTATE_OK; @@ -85,6 +86,7 @@ uint32_t RsFeedReaderSerialiser::sizeFeed(RsFeedReaderFeed *item) s += item->xpathsToUse.TlvSize(); s += item->xpathsToRemove.TlvSize(); s += GetTlvStringSize(item->xslt); + s += GetTlvStringSize(item->postedId); return s; } @@ -108,7 +110,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u offset += 8; /* add values */ - ok &= setRawUInt16(data, tlvsize, &offset, 2); /* version */ + ok &= setRawUInt16(data, tlvsize, &offset, 3); /* version */ ok &= setRawUInt32(data, tlvsize, &offset, item->feedId); ok &= setRawUInt32(data, tlvsize, &offset, item->parentId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, item->url); @@ -124,6 +126,7 @@ bool RsFeedReaderSerialiser::serialiseFeed(RsFeedReaderFeed *item, void *data, u ok &= setRawUInt32(data, tlvsize, &offset, item->storageTime); ok &= setRawUInt32(data, tlvsize, &offset, item->flag); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->postedId); ok &= setRawUInt32(data, tlvsize, &offset, item->errorState); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, item->errorString); ok &= setRawUInt32(data, tlvsize, &offset, item->transformationType); @@ -208,6 +211,9 @@ RsFeedReaderFeed *RsFeedReaderSerialiser::deserialiseFeed(void *data, uint32_t * ok &= getRawUInt32(data, rssize, &offset, &(item->storageTime)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->forumId); + if (version >= 3) { + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_VALUE, item->postedId); + } uint32_t errorState = 0; ok &= getRawUInt32(data, rssize, &offset, &errorState); item->errorState = (RsFeedReaderErrorState) errorState; @@ -268,6 +274,9 @@ void RsFeedReaderMsg::clear() descriptionTransformed.clear(); pubDate = 0; flag = 0; + attachmentLink.clear(); + attachment.clear(); + attachmentMimeType.clear(); } std::ostream &RsFeedReaderMsg::print(std::ostream &out, uint16_t /*indent*/) @@ -288,6 +297,9 @@ uint32_t RsFeedReaderSerialiser::sizeMsg(RsFeedReaderMsg *item) s += GetTlvStringSize(item->descriptionTransformed); s += sizeof(uint32_t); /* pubDate */ s += sizeof(uint32_t); /* flag */ + s += GetTlvStringSize(item->attachmentLink); + s += GetTlvStringSize(item->attachment); + s += GetTlvStringSize(item->attachmentMimeType); return s; } @@ -311,7 +323,7 @@ bool RsFeedReaderSerialiser::serialiseMsg(RsFeedReaderMsg *item, void *data, uin offset += 8; /* add values */ - ok &= setRawUInt16(data, tlvsize, &offset, 2); /* version */ + ok &= setRawUInt16(data, tlvsize, &offset, 3); /* version */ ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GENID, item->msgId); ok &= setRawUInt32(data, tlvsize, &offset, item->feedId); ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, item->title); @@ -321,6 +333,9 @@ bool RsFeedReaderSerialiser::serialiseMsg(RsFeedReaderMsg *item, void *data, uin ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_COMMENT, item->descriptionTransformed); ok &= setRawUInt32(data, tlvsize, &offset, item->pubDate); ok &= setRawUInt32(data, tlvsize, &offset, item->flag); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LOCATION, item->attachmentLink); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_PIC_AUTH, item->attachment); + ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_PIC_TYPE, item->attachmentMimeType); if (offset != tlvsize) { @@ -384,6 +399,11 @@ RsFeedReaderMsg *RsFeedReaderSerialiser::deserialiseMsg(void *data, uint32_t *pk } ok &= getRawUInt32(data, rssize, &offset, (uint32_t*) &(item->pubDate)); ok &= getRawUInt32(data, rssize, &offset, &(item->flag)); + if (version >= 3) { + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LOCATION, item->attachmentLink); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_PIC_AUTH, item->attachment); + ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_PIC_TYPE, item->attachmentMimeType); + } if (offset != rssize) { diff --git a/plugins/FeedReader/services/rsFeedReaderItems.h b/plugins/FeedReader/services/rsFeedReaderItems.h index a8cce7084..4e343be75 100644 --- a/plugins/FeedReader/services/rsFeedReaderItems.h +++ b/plugins/FeedReader/services/rsFeedReaderItems.h @@ -34,17 +34,22 @@ const uint8_t RS_PKT_SUBTYPE_FEEDREADER_MSG = 0x03; /**************************************************************************/ -#define RS_FEED_FLAG_FOLDER 0x001 -#define RS_FEED_FLAG_INFO_FROM_FEED 0x002 -#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x004 -#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x008 -#define RS_FEED_FLAG_STANDARD_PROXY 0x010 -#define RS_FEED_FLAG_AUTHENTICATION 0x020 -#define RS_FEED_FLAG_DEACTIVATED 0x040 -#define RS_FEED_FLAG_FORUM 0x080 -#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x100 -#define RS_FEED_FLAG_EMBED_IMAGES 0x200 -#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x400 +#define RS_FEED_FLAG_FOLDER 0x0001 +#define RS_FEED_FLAG_INFO_FROM_FEED 0x0002 +#define RS_FEED_FLAG_STANDARD_STORAGE_TIME 0x0004 +#define RS_FEED_FLAG_STANDARD_UPDATE_INTERVAL 0x0008 +#define RS_FEED_FLAG_STANDARD_PROXY 0x0010 +#define RS_FEED_FLAG_AUTHENTICATION 0x0020 +#define RS_FEED_FLAG_DEACTIVATED 0x0040 +#define RS_FEED_FLAG_FORUM 0x0080 +#define RS_FEED_FLAG_UPDATE_FORUM_INFO 0x0100 +#define RS_FEED_FLAG_EMBED_IMAGES 0x0200 +#define RS_FEED_FLAG_SAVE_COMPLETE_PAGE 0x0400 +#define RS_FEED_FLAG_POSTED 0x0800 +#define RS_FEED_FLAG_UPDATE_POSTED_INFO 0x1000 +#define RS_FEED_FLAG_POSTED_FIRST_IMAGE 0x2000 +#define RS_FEED_FLAG_POSTED_ONLY_IMAGE 0x4000 +#define RS_FEED_FLAG_POSTED_SHRINK_IMAGE 0x8000 class RsFeedReaderFeed : public RsItem { @@ -62,6 +67,7 @@ public: virtual ~RsFeedReaderFeed() {} virtual void clear(); + virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {} uint32_t feedId; uint32_t parentId; @@ -75,6 +81,7 @@ public: time_t lastUpdate; uint32_t flag; // RS_FEED_FLAG_... std::string forumId; + std::string postedId; uint32_t storageTime; std::string description; std::string icon; @@ -105,6 +112,7 @@ public: virtual ~RsFeedReaderMsg() {} virtual void clear(); + virtual void serial_process(RsGenericSerializer::SerializeJob, RsGenericSerializer::SerializeContext&) {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); std::string msgId; @@ -116,6 +124,16 @@ public: std::string descriptionTransformed; time_t pubDate; uint32_t flag; // RS_FEEDMSG_FLAG_... + std::string attachmentLink; + std::string attachment; // binary as base64 + std::string attachmentMimeType; + + // Only in memory when receiving messages + std::vector attachmentBinary; + std::string attachmentBinaryMimeType; + std::vector postedFirstImage; + std::string postedFirstImageMimeType; + std::string postedDescriptionWithoutFirstImage; }; class RsFeedReaderSerialiser: public RsSerialType diff --git a/plugins/FeedReader/util/CURLWrapper.cpp b/plugins/FeedReader/util/CURLWrapper.cpp index 4e8c5c9bb..94ae7beaa 100644 --- a/plugins/FeedReader/util/CURLWrapper.cpp +++ b/plugins/FeedReader/util/CURLWrapper.cpp @@ -21,6 +21,8 @@ #include "CURLWrapper.h" #include +#define USERAGENT "Mozilla/5.0 (rv:109.0) Gecko/20100101 Firefox/112.0" + CURLWrapper::CURLWrapper(const std::string &proxy) { mCurl = curl_easy_init(); @@ -65,6 +67,7 @@ CURLcode CURLWrapper::downloadText(const std::string &link, std::string &data) curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, writeFunctionString); curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, &data); curl_easy_setopt(mCurl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(mCurl, CURLOPT_USERAGENT, USERAGENT); return curl_easy_perform(mCurl); } @@ -94,6 +97,8 @@ CURLcode CURLWrapper::downloadBinary(const std::string &link, std::vector #include #define IMAGE_VOIP ":/images/talking_on.svg" @@ -113,7 +112,7 @@ ConfigPage *VOIPPlugin::qt_config_page() const // The config pages are deleted when config is closed, so it's important not to static the // created object. // - return new AudioInputConfig() ; + return new VOIPConfigPanel() ; } QDialog *VOIPPlugin::qt_about_page() const @@ -188,8 +187,6 @@ std::string VOIPPlugin::getPluginName() const void VOIPPlugin::getLibraries(std::list &libraries) { - libraries.push_back(RsLibraryInfo("OpenCV", CV_VERSION)); - const char *speexVersion = NULL; if (speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &speexVersion) == 0 && speexVersion) { libraries.push_back(RsLibraryInfo("Speex", speexVersion)); diff --git a/plugins/VOIP/gui/AudioInputConfig.cpp b/plugins/VOIP/gui/AudioInputConfig.cpp deleted file mode 100644 index b063d5e48..000000000 --- a/plugins/VOIP/gui/AudioInputConfig.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/******************************************************************************* - * plugins/VOIP/gui/AudioInputConfig.h * - * * - * Copyright (C) 2008, Andreas Messer * - * Copyright (C) 2005-2010 Thorvald Natvig * - * Copyright (C) 2012 by Retroshare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ -#pragma once - -#include "AudioStats.h" -#include "AudioInputConfig.h" -#include "audiodevicehelper.h" -#include "AudioWizard.h" -#include "gui/VideoProcessor.h" -#include "gui/common/RSGraphWidget.h" -#include "util/RsProtectedTimer.h" - -#include - -#define iroundf(x) ( static_cast(x) ) - -class voipGraphSource: public RSGraphSource -{ -public: - voipGraphSource() : video_input(NULL) {} - - void setVideoInput(const QVideoInputDevice *vid) { video_input = vid ; } - - virtual QString displayName(int) const { return tr("Required bandwidth") ;} - - virtual QString displayValue(float v) const - { - if(v < 1000) - return QString::number(v,10,2) + " B/s" ; - else if(v < 1000*1024) - return QString::number(v/1024,10,2) + " KB/s" ; - else - return QString::number(v/(1024*1024),10,2) + " MB/s" ; - } - - virtual void getValues(std::map& vals) const - { - vals.clear() ; - - if(video_input) - vals[std::string("bw")] = video_input->currentBandwidth() ; - } - -private: - const QVideoInputDevice *video_input ; -}; - -void voipGraph::setVoipSource(voipGraphSource *gs) -{ -_src = gs ; -RSGraphWidget::setSource(gs) ; -} - -voipGraph::voipGraph(QWidget *parent) - : RSGraphWidget(parent) -{ - setFlags(RSGraphWidget::RSGRAPH_FLAGS_SHOW_LEGEND) ; - setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ; - - _src = NULL ; -} - -/** Constructor */ -AudioInputConfig::AudioInputConfig(QWidget * parent, Qt::WindowFlags flags) - : ConfigPage(parent, flags) -{ - std::cerr << "Creating audioInputConfig object" << std::endl; - - /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); - - loaded = false; - - inputAudioProcessor = NULL; - inputAudioDevice = NULL; - abSpeech = NULL; - qtTick = NULL; - - // Create the video pipeline. - // - videoInput = new QVideoInputDevice(this) ; - videoInput->setEchoVideoTarget(ui.videoDisplay) ; - - videoProcessor = new VideoProcessor() ; - videoProcessor->setDisplayTarget(NULL) ; - - videoProcessor->setMaximumBandwidth(ui.availableBW_SB->value()) ; - - videoInput->setVideoProcessor(videoProcessor) ; - - graph_source = new voipGraphSource ; - ui.voipBwGraph->setSource(graph_source); - - graph_source->setVideoInput(videoInput) ; - graph_source->setCollectionTimeLimit(1000*300) ; - graph_source->start() ; - - QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ; - QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ; -} - -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) ; - } - else - { - videoProcessor->setDisplayTarget(NULL) ; - videoInput->setEchoVideoTarget(ui.videoDisplay) ; - } -} - -AudioInputConfig::~AudioInputConfig() -{ - disconnect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); - - graph_source->stop() ; - graph_source->setVideoInput(NULL) ; - - std::cerr << "Deleting audioInputConfig object" << std::endl; - if(videoInput != NULL) - { - videoInput->stop() ; - delete videoInput ; - } - - if (inputAudioDevice) { - inputAudioDevice->stop(); - delete inputAudioDevice ; - inputAudioDevice = NULL ; - } - - if(inputAudioProcessor) - { - delete inputAudioProcessor ; - inputAudioProcessor = NULL ; - } -} - -/** Loads the settings for this page */ -void AudioInputConfig::load() -{ - //connect( ui.allowIpDeterminationCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleIpDetermination(bool) ) ); - //connect( ui.allowTunnelConnectionCB, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) ); - - qtTick = new RsProtectedTimer(this); - connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); - qtTick->start(20); - /*if (AudioInputRegistrar::qmNew) { - QList keys = AudioInputRegistrar::qmNew->keys(); - foreach(QString key, keys) { - qcbSystem->addItem(key); - } - } - qcbSystem->setEnabled(qcbSystem->count() > 1);*/ - - ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); - ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD); - ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk); - - abSpeech = new AudioBar(); - abSpeech->qcBelow = Qt::red; - abSpeech->qcInside = Qt::yellow; - abSpeech->qcAbove = Qt::green; - //abSpeech->setGeometry(9,20,50,10); - ui.qwVadLayout_2->addWidget(abSpeech,0,0,1,0); - - //on_qcbPushClick_clicked(g.s.bPushClick); - //ui.on_Tick_timeout(); - loadSettings(); -} - - -void AudioInputConfig::loadSettings() { - /*QList keys; - - if (AudioInputRegistrar::qmNew) - keys=AudioInputRegistrar::qmNew->keys(); - else - keys.clear(); - i=keys.indexOf(AudioInputRegistrar::current); - if (i >= 0) - loadComboBox(qcbSystem, i); - - loadCheckBox(qcbExclusive, r.bExclusiveInput);*/ - - //qlePushClickPathOn->setText(r.qsPushClickOn); - //qlePushClickPathOff->setText(r.qsPushClickOff); - - /*loadComboBox(qcbTransmit, r.atTransmit); - loadSlider(qsTransmitHold, r.iVoiceHold); - loadSlider(qsTransmitMin, iroundf(r.fVADmin * 32767.0f + 0.5f)); - loadSlider(qsTransmitMax, iroundf(r.fVADmax * 32767.0f + 0.5f)); - loadSlider(qsFrames, (r.iFramesPerPacket == 1) ? 1 : (r.iFramesPerPacket/2 + 1)); - loadSlider(qsDoublePush, iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f));*/ - ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit()); - on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit()); - ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold()); - on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold()); - ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin()); - ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax()); - ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel()); - //ui.qsDoublePush->setValue(iroundf(static_cast(r.uiDoublePush) / 1000.f + 0.5f)); - - //loadCheckBox(qcbPushClick, r.bPushClick); - //loadSlider(qsQuality, r.iQuality); - if (rsVOIP->getVoipiNoiseSuppress() != 0) - ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress()); - else - ui.qsNoise->setValue(14); - - on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress()); - - ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness()); - on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness()); - //loadSlider(qsIdle, r.iIdleTime); - - /*int echo = 0; - if (r.bEcho) - echo = r.bEchoMulti ? 2 : 1; - - loadComboBox(qcbEcho, echo);*/ - connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); - connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); - connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); - connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) ); - loaded = true; - - std::cerr << "AudioInputConfig:: starting video." << std::endl; - videoInput->start() ; -} - -bool AudioInputConfig::save(QString &/*errmsg*/) {//mainly useless beacause saving occurs in realtime - //s.iQuality = qsQuality->value(); - rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); - rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); - rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value()); - rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); - /*s.uiDoublePush = qsDoublePush->value() * 1000;*/ - rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); - rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); - - return true; -} - -void AudioInputConfig::on_qsTransmitHold_valueChanged(int v) { - float val = static_cast(v * FRAME_SIZE); - val = val / SAMPLING_RATE; - ui.qlTransmitHold->setText(tr("%1 s").arg(val, 0, 'f', 2)); - rsVOIP->setVoipVoiceHold(v); -} - -void AudioInputConfig::on_qsNoise_valueChanged(int v) { - QPalette pal; - - if (v < 15) { - ui.qlNoise->setText(tr("Off")); - pal.setColor(ui.qlNoise->foregroundRole(), Qt::red); - } else { - ui.qlNoise->setText(tr("-%1 dB").arg(v)); - } - ui.qlNoise->setPalette(pal); - rsVOIP->setVoipiNoiseSuppress(- ui.qsNoise->value()); -} - -void AudioInputConfig::on_qsAmp_valueChanged(int v) { - v = 20000 - v; - float d = 20000.0f/static_cast(v); - ui.qlAmp->setText(QString::fromLatin1("%1").arg(d, 0, 'f', 2)); - rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); -} - -void AudioInputConfig::on_qcbEchoCancel_clicked() { - rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); -} - - -void AudioInputConfig::on_qcbTransmit_currentIndexChanged(int v) { - switch (v) { - case 0: - ui.qswTransmit->setCurrentWidget(ui.qwContinuous); - break; - case 1: - ui.qswTransmit->setCurrentWidget(ui.qwVAD); - break; - case 2: - ui.qswTransmit->setCurrentWidget(ui.qwPTT); - break; - } - if (loaded) - rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); -} - - -void AudioInputConfig::on_Tick_timeout() -{ - if (!inputAudioProcessor) - { - inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); - inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); - - if (!inputAudioDevice) { - inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); - } - inputAudioDevice->start(inputAudioProcessor); - connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer())); - } - - abSpeech->iBelow = ui.qsTransmitMin->value(); - abSpeech->iAbove = ui.qsTransmitMax->value(); - if (loaded) { - rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); - rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); - } - - abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); - - abSpeech->update(); - - // also transmit encoded video - RsVOIPDataChunk chunk ; - - while((!videoInput->stopped()) && videoInput->getNextEncodedPacket(chunk)) - { - videoProcessor->receiveEncodedData(chunk) ; - chunk.clear() ; - } -} - -void AudioInputConfig::emptyBuffer() { - while(inputAudioProcessor->hasPendingPackets()) { - inputAudioProcessor->getNetworkPacket(); //that will purge the buffer - } -} - -void AudioInputConfig::on_qpbAudioWizard_clicked() { - AudioWizard aw(this); - aw.exec(); - loadSettings(); -} diff --git a/plugins/VOIP/gui/AudioStats.cpp b/plugins/VOIP/gui/AudioStats.cpp index 536cf0a1d..96ea93b83 100644 --- a/plugins/VOIP/gui/AudioStats.cpp +++ b/plugins/VOIP/gui/AudioStats.cpp @@ -25,7 +25,7 @@ #include #include "AudioStats.h" -#include "AudioInputConfig.h" +#include "VOIPConfigPanel.h" //#include "Global.h" //#include "smallft.h" diff --git a/plugins/VOIP/gui/AudioWizard.cpp b/plugins/VOIP/gui/AudioWizard.cpp index cbf24d9b4..8c0841d1f 100644 --- a/plugins/VOIP/gui/AudioWizard.cpp +++ b/plugins/VOIP/gui/AudioWizard.cpp @@ -104,8 +104,8 @@ AudioWizard::AudioWizard(QWidget *p) : QWizard(p) { iMaxPeak = 0; iTicks = 0; - qpTalkingOn = QPixmap::fromImage(QImage(QLatin1String("skin:talking_on.svg")).scaled(64,64)); - qpTalkingOff = QPixmap::fromImage(QImage(QLatin1String("skin:talking_off.svg")).scaled(64,64)); + qpTalkingOn = QPixmap::fromImage(QImage(QLatin1String(":/images/talking_on.svg")).scaled(64,64)); + qpTalkingOff = QPixmap::fromImage(QImage(QLatin1String(":/images/talking_off.svg")).scaled(64,64)); bInit = false; diff --git a/plugins/VOIP/gui/AudioWizard.ui b/plugins/VOIP/gui/AudioWizard.ui index dfe9578f6..22d848fc4 100644 --- a/plugins/VOIP/gui/AudioWizard.ui +++ b/plugins/VOIP/gui/AudioWizard.ui @@ -202,7 +202,16 @@ - + + 0 + + + 0 + + + 0 + + 0 diff --git a/plugins/VOIP/gui/QVideoDevice.cpp b/plugins/VOIP/gui/QVideoDevice.cpp index 1a3d084db..51e3a83bf 100644 --- a/plugins/VOIP/gui/QVideoDevice.cpp +++ b/plugins/VOIP/gui/QVideoDevice.cpp @@ -18,15 +18,18 @@ * * *******************************************************************************/ -#include -#include -#include - #include #include +#include +#include +#include +#include +#include #include "QVideoDevice.h" #include "VideoProcessor.h" +// #define DEBUG_QVIDEODEVICE 1 + QVideoInputDevice::QVideoInputDevice(QWidget *parent) :QObject(parent) { @@ -36,16 +39,28 @@ QVideoInputDevice::QVideoInputDevice(QWidget *parent) _echo_output_device = NULL ; } -bool QVideoInputDevice::stopped() +QVideoInputDevice::~QVideoInputDevice() +{ + stop() ; + _video_processor = NULL ; + + delete _image_capture; + delete _capture_device; + delete _timer; +} + +bool QVideoInputDevice::stopped() const { return _timer == NULL ; } void QVideoInputDevice::stop() { + _capture_device_info = QCameraInfo(); + if(_timer != NULL) { - QObject::disconnect(_timer,SIGNAL(timeout()),this,SLOT(grabFrame())) ; + _capture_device->stop(); _timer->stop() ; delete _timer ; _timer = NULL ; @@ -53,57 +68,122 @@ void QVideoInputDevice::stop() if(_capture_device != NULL) { // the camera will be deinitialized automatically in VideoCapture destructor - _capture_device->release(); - delete _capture_device ; + delete _image_capture ; + delete _capture_device ; + _capture_device = NULL ; - } + _image_capture = NULL ; + } + if(_echo_output_device != NULL) + _echo_output_device->showFrameOff() ; } -void QVideoInputDevice::start() +void QVideoInputDevice::getAvailableDevices(QList& device_desc) +{ + device_desc.clear(); + + QList dev_list = QCameraInfo::availableCameras(); + + for(auto& cam:dev_list) + device_desc.push_back(cam.deviceName()); +} + +void QVideoInputDevice::start(const QString& description) { // make sure everything is re-initialised // stop() ; - // Initialise la capture - static const int cam_id = 0 ; - _capture_device = new cv::VideoCapture(cam_id); + QCameraInfo caminfo ; - if(!_capture_device->isOpened()) - { - std::cerr << "Cannot initialise camera. Something's wrong." << std::endl; - return ; - } + if(description.isNull()) + caminfo = QCameraInfo::defaultCamera(); + else + { + auto cam_list = QCameraInfo::availableCameras(); - _timer = new QTimer ; - QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(grabFrame())) ; + for(auto& s:cam_list) + if(s.deviceName() == description) + caminfo = s; + } - _timer->start(50) ; // 10 images per second. + if(caminfo.isNull()) + { + std::cerr << "No video camera available in this system!" << std::endl; + return ; + } + _capture_device_info = caminfo; + _capture_device = new QCamera(caminfo); + + if(_capture_device->error() != QCamera::NoError) + { + emit cameraCaptureInfo(CANNOT_INITIALIZE_CAMERA,_capture_device->error()); + std::cerr << "Cannot initialise camera. Something's wrong." << std::endl; + return; + } + _capture_device->setCaptureMode(QCamera::CaptureStillImage); + + if(_capture_device->error() == QCamera::NoError) + emit cameraCaptureInfo(CAMERA_IS_READY,QCamera::NoError); + + _image_capture = new QCameraImageCapture(_capture_device); + + if(!_image_capture->isCaptureDestinationSupported(QCameraImageCapture::CaptureToBuffer)) + { + emit cameraCaptureInfo(CAMERA_IS_READY,QCamera::NoError); + + delete _capture_device; + delete _image_capture; + return; + } + + _image_capture->setCaptureDestination(QCameraImageCapture::CaptureToBuffer); + + QObject::connect(_image_capture,SIGNAL(imageAvailable(int,QVideoFrame)),this,SLOT(grabFrame(int,QVideoFrame))); + QObject::connect(this,SIGNAL(cameraCaptureInfo(CameraStatus,QCamera::Error)),this,SLOT(errorHandling(CameraStatus,QCamera::Error))); + + _timer = new QTimer ; + QObject::connect(_timer,SIGNAL(timeout()),_image_capture,SLOT(capture())) ; + + _timer->start(50) ; // 10 images per second. + + _capture_device->start(); } -void QVideoInputDevice::grabFrame() +void QVideoInputDevice::errorHandling(CameraStatus status,QCamera::Error error) { - if(!_timer) - return ; - - cv::Mat frame; - if(!_capture_device->read(frame)) +#ifdef DEBUG_QVIDEODEVICE + std::cerr << "Received msg from camera capture: status=" << (int)status << " error=" << (int)error << std::endl; +#else + Q_UNUSED(error); +#endif + if(status == CANNOT_INITIALIZE_CAMERA) { - std::cerr << "(EE) Cannot capture image from camera. Something's wrong." << std::endl; - return ; + std::cerr << "Cannot initialize camera. Make sure to install package libqt5multimedia5-plugins, as this is a common cause for camera not being found." << std::endl; + } +} + +void QVideoInputDevice::grabFrame(int id,QVideoFrame frame) +{ + if(frame.size().isEmpty()) + { + std::cerr << "Empty frame!" ; + return; } - // get the image data + frame.map(QAbstractVideoBuffer::ReadOnly); + QByteArray data((const char *)frame.bits(), frame.mappedBytes()); + QBuffer buffer; + buffer.setData(data); + buffer.open(QIODevice::ReadOnly); + QImageReader reader(&buffer, "JPG"); + reader.setScaledSize(QSize(640,480)); + QImage image(reader.read()); - if(frame.channels() != 3) - { - 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(frame, img_rgb, CV_BGR2RGB); - QImage image = QImage(img_rgb.data,img_rgb.cols,img_rgb.rows,QImage::Format_RGB888); +#ifdef DEBUG_QVIDEODEVICE + std::cerr << "Frame " << id << ". Pixel format: " << frame.pixelFormat() << ". Size: " << image.size().width() << " x " << image.size().height() << std::endl; // if(frame.pixelFormat() != QVideoFrame::Format_Jpeg) +#else + Q_UNUSED(id); +#endif if(_video_processor != NULL) { @@ -128,16 +208,12 @@ bool QVideoInputDevice::getNextEncodedPacket(RsVOIPDataChunk& chunk) uint32_t QVideoInputDevice::currentBandwidth() const { - return _video_processor->currentBandwidthOut() ; + if(stopped()) + return 0; + else + return _video_processor->currentBandwidthOut() ; } -QVideoInputDevice::~QVideoInputDevice() -{ - stop() ; - _video_processor = NULL ; -} - - QVideoOutputDevice::QVideoOutputDevice(QWidget *parent) : QLabel(parent) { @@ -152,7 +228,9 @@ void QVideoOutputDevice::showFrameOff() void QVideoOutputDevice::showFrame(const QImage& img) { +#ifdef DEBUG_QVIDEODEVICE std::cerr << "img.size = " << img.width() << " x " << img.height() << std::endl; +#endif 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 e0c21778e..63d83b4e1 100644 --- a/plugins/VOIP/gui/QVideoDevice.h +++ b/plugins/VOIP/gui/QVideoDevice.h @@ -21,13 +21,14 @@ #pragma once #include +#include +#include #include "interface/rsVOIP.h" -#include "opencv2/opencv.hpp" - #include "gui/VideoProcessor.h" class VideoEncoder ; +class QCameraImageCapture; // Responsible from displaying the video. The source of the video is // a VideoDecoder object, which uses a codec. @@ -49,7 +50,7 @@ class QVideoInputDevice: public QObject Q_OBJECT public: - QVideoInputDevice(QWidget *parent = 0) ; + QVideoInputDevice(QWidget *parent = 0) ; ~QVideoInputDevice() ; // Captured images are sent to this encoder. Can be NULL. @@ -71,19 +72,35 @@ class QVideoInputDevice: public QObject // control - void start() ; + void start(const QString &description = QString()) ; void stop() ; - bool stopped(); + bool stopped() const; + + enum CameraStatus { + CAMERA_IS_READY = 0x00, + CANNOT_INITIALIZE_CAMERA = 0x01, + CAMERA_CANNOT_GRAB_FRAMES = 0x02 + }; + + // Gets the list of available devices. The id string for each device can be used when creating a QVideoDevice + + static void getAvailableDevices(QList& device_desc); + + QString currentCameraDescriptionString() const { return _capture_device_info.deviceName(); } protected slots: - void grabFrame() ; + void grabFrame(int id, QVideoFrame f) ; + void errorHandling(CameraStatus status,QCamera::Error error); signals: void networkPacketReady() ; + void cameraCaptureInfo(CameraStatus status,QCamera::Error qt_cam_err_code); private: VideoProcessor *_video_processor ; QTimer *_timer ; - cv::VideoCapture *_capture_device ; + QCamera *_capture_device; + QCameraImageCapture *_image_capture; + QCameraInfo _capture_device_info; QVideoOutputDevice *_echo_output_device ; diff --git a/plugins/VOIP/gui/VOIPConfigPanel.cpp b/plugins/VOIP/gui/VOIPConfigPanel.cpp new file mode 100644 index 000000000..a9912af8b --- /dev/null +++ b/plugins/VOIP/gui/VOIPConfigPanel.cpp @@ -0,0 +1,473 @@ +/******************************************************************************* + * plugins/VOIP/gui/AudioInputConfig.h * + * * + * Copyright (C) 2008, Andreas Messer * + * Copyright (C) 2005-2010 Thorvald Natvig * + * Copyright (C) 2012 by Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "AudioStats.h" +#include "VOIPConfigPanel.h" +#include "audiodevicehelper.h" +#include "AudioWizard.h" +#include "gui/VideoProcessor.h" +#include "gui/VideoProcessor.h" +#include "util/misc.h" +#include "util/RsProtectedTimer.h" + +#include + +#define iroundf(x) ( static_cast(x) ) + +class voipGraphSource: public RSGraphSource +{ +public: + voipGraphSource() : video_input(NULL) {} + + void setVideoInput(const QVideoInputDevice *vid) { video_input = vid ; } + + virtual QString displayName(int) const { return tr("Required bandwidth") ;} + + virtual QString displayValue(float v) const + { + if(v < 1000) + return QString::number(v,10,2) + " B/s" ; + else if(v < 1000*1024) + return QString::number(v/1024,10,2) + " KB/s" ; + else + return QString::number(v/(1024*1024),10,2) + " MB/s" ; + } + + virtual void getValues(std::map& vals) const + { + vals.clear() ; + + if(video_input) + vals[std::string("bw")] = video_input->currentBandwidth() ; + } + +private: + const QVideoInputDevice *video_input ; +}; + +void voipGraph::setVoipSource(voipGraphSource *gs) +{ +_src = gs ; +RSGraphWidget::setSource(gs) ; +} + +voipGraph::voipGraph(QWidget *parent) + : RSGraphWidget(parent) +{ + setFlags(RSGraphWidget::RSGRAPH_FLAGS_SHOW_LEGEND) ; + setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_PLAIN) ; + + _src = NULL ; +} + +/** Constructor */ +VOIPConfigPanel::VOIPConfigPanel(QWidget * parent, Qt::WindowFlags flags) + : ConfigPage(parent, flags) +{ + std::cerr << "Creating audioInputConfig object" << std::endl; + + /* Invoke the Qt Designer generated object setup routine */ + ui.setupUi(this); + + loaded = false; + + inputAudioProcessor = NULL; + inputAudioDevice = NULL; + graph_source = nullptr; + videoInput = nullptr; + videoProcessor = nullptr; + qtTick = NULL; + + ui.qcbTransmit->addItem(tr("Continuous"), RsVOIP::AudioTransmitContinous); + ui.qcbTransmit->addItem(tr("Voice Activity"), RsVOIP::AudioTransmitVAD); + ui.qcbTransmit->addItem(tr("Push To Talk"), RsVOIP::AudioTransmitPushToTalk); + + ui.abSpeech->qcBelow = Qt::red; + ui.abSpeech->qcInside = Qt::yellow; + ui.abSpeech->qcAbove = Qt::green; + + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + ui.inputDevice_CB->clear(); + ui.inputDevice_CB->addItem(tr("[No video]"),QString("")); + for(auto& s:input_devices) + ui.inputDevice_CB->addItem(s,QVariant(s)); + + if(!input_devices.empty()) + whileBlocking(ui.inputDevice_CB)->setCurrentIndex(1); // select default cam + + connect( ui.qsTransmitHold, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsTransmitHold_valueChanged(int) ) ); + connect( ui.qsNoise, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsNoise_valueChanged(int) ) ); + connect( ui.qsAmp, SIGNAL( valueChanged ( int ) ), this, SLOT( on_qsAmp_valueChanged(int) ) ); + connect( ui.qcbTransmit, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_qcbTransmit_currentIndexChanged(int) ) ); + connect( ui.inputDevice_CB, SIGNAL( currentIndexChanged ( int ) ), this, SLOT( on_changedCurrentInputDevice(int) ) ); +} + +void VOIPConfigPanel::showEvent(QShowEvent *) +{ + std::cerr << "Creating the audio pipeline" << std::endl; + + inputAudioProcessor = new QtSpeex::SpeexInputProcessor(); + inputAudioProcessor->open(QIODevice::WriteOnly | QIODevice::Unbuffered); + + inputAudioDevice = AudioDeviceHelper::getPreferedInputDevice(); + inputAudioDevice->start(inputAudioProcessor); + + connect(inputAudioProcessor, SIGNAL(networkPacketReady()), this, SLOT(emptyBuffer())); + + std::cerr << "Creating the video pipeline" << std::endl; + + // Create the video pipeline. + // + + videoInput = new QVideoInputDevice(this) ; + + videoProcessor = new VideoProcessor() ; + videoProcessor->setDisplayTarget(NULL) ; + + videoProcessor->setMaximumBandwidth(ui.availableBW_SB->value()) ; + + videoInput->setVideoProcessor(videoProcessor) ; + + graph_source = new voipGraphSource ; + ui.voipBwGraph->setSource(graph_source); + + graph_source->setVideoInput(videoInput) ; + graph_source->setCollectionTimeLimit(1000*300) ; + graph_source->start() ; + + if(ui.showEncoded_CB->isChecked()) + { + videoInput->setEchoVideoTarget(nullptr) ; + videoProcessor->setDisplayTarget(ui.videoDisplay) ; + } + else + { + videoInput->setEchoVideoTarget(ui.videoDisplay) ; + videoProcessor->setDisplayTarget(nullptr); + } + + QObject::connect(ui.showEncoded_CB,SIGNAL(toggled(bool)),this,SLOT(togglePreview(bool))) ; + QObject::connect(ui.availableBW_SB,SIGNAL(valueChanged(double)),this,SLOT(updateAvailableBW(double))) ; + + loadSettings(); + + qtTick = new RsProtectedTimer(this); + connect( qtTick, SIGNAL( timeout ( ) ), this, SLOT( on_Tick_timeout() ) ); + qtTick->start(20); + + videoInput->start(); +} + +void VOIPConfigPanel::hideEvent(QHideEvent *) +{ + std::cerr << "Deleting the video pipeline" << std::endl; + + clearPipeline(); +} + +void VOIPConfigPanel::updateAvailableBW(double r) +{ + std::cerr << "Setting max bandwidth to " << r << " KB/s" << std::endl; + videoProcessor->setMaximumBandwidth((uint32_t)(r*1024)) ; +} + +void VOIPConfigPanel::togglePreview(bool b) +{ + if(b) + { + videoInput->setEchoVideoTarget(NULL) ; + videoProcessor->setDisplayTarget(ui.videoDisplay) ; + } + else + { + videoProcessor->setDisplayTarget(NULL) ; + videoInput->setEchoVideoTarget(ui.videoDisplay) ; + } +} + +VOIPConfigPanel::~VOIPConfigPanel() +{ + clearPipeline(); +} + +void VOIPConfigPanel::clearPipeline() +{ + if (qtTick) { + delete qtTick; + qtTick = nullptr; + } + + if (graph_source) { + graph_source->stop() ; + graph_source->setVideoInput(NULL) ; + graph_source=nullptr; // is deleted by setSource below. This is a bad design. + } + + ui.voipBwGraph->setSource(nullptr); + + std::cerr << "Deleting audioInputConfig object" << std::endl; + if(videoInput != NULL) + { + videoInput->stop() ; + delete videoInput ; + + videoInput = nullptr; + } + if (videoProcessor) { + delete videoProcessor; + videoProcessor = nullptr; + } + + if (inputAudioDevice) { + inputAudioDevice->stop(); + delete inputAudioDevice ; + inputAudioDevice = nullptr ; + } + + if(inputAudioProcessor) + { + delete inputAudioProcessor ; + inputAudioProcessor = nullptr ; + } +} + +void VOIPConfigPanel::load() +{ +} + +/** Loads the settings for this page */ + +void VOIPConfigPanel::loadSettings() +{ + ui.qcbTransmit->setCurrentIndex(rsVOIP->getVoipATransmit()); + on_qcbTransmit_currentIndexChanged(rsVOIP->getVoipATransmit()); + ui.qsTransmitHold->setValue(rsVOIP->getVoipVoiceHold()); + on_qsTransmitHold_valueChanged(rsVOIP->getVoipVoiceHold()); + ui.qsTransmitMin->setValue(rsVOIP->getVoipfVADmin()); + ui.qsTransmitMax->setValue(rsVOIP->getVoipfVADmax()); + ui.qcbEchoCancel->setChecked(rsVOIP->getVoipEchoCancel()); + + if (rsVOIP->getVoipiNoiseSuppress() != 0) + ui.qsNoise->setValue(-rsVOIP->getVoipiNoiseSuppress()); + else + ui.qsNoise->setValue(14); + + on_qsNoise_valueChanged(-rsVOIP->getVoipiNoiseSuppress()); + + ui.qsAmp->setValue(20000 - rsVOIP->getVoipiMinLoudness()); + on_qsAmp_valueChanged(20000 - rsVOIP->getVoipiMinLoudness()); + + loaded = true; +} + +bool VOIPConfigPanel::save(QString &/*errmsg*/) +{ + //mainly useless beacause saving occurs in realtime + //s.iQuality = qsQuality->value(); + rsVOIP->setVoipiNoiseSuppress((ui.qsNoise->value() == 14) ? 0 : - ui.qsNoise->value()); + rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); + rsVOIP->setVoipVoiceHold(ui.qsTransmitHold->value()); + rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); + /*s.uiDoublePush = qsDoublePush->value() * 1000;*/ + rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); + rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); + + return true; +} + +void VOIPConfigPanel::on_qsTransmitHold_valueChanged(int v) { + float val = static_cast(v * FRAME_SIZE); + val = val / SAMPLING_RATE; + ui.qlTransmitHold->setText(tr("%1 s").arg(val, 0, 'f', 2)); + rsVOIP->setVoipVoiceHold(v); +} + +void VOIPConfigPanel::on_qsNoise_valueChanged(int v) { + QPalette pal; + + if (v < 15) { + ui.qlNoise->setText(tr("Off")); + pal.setColor(ui.qlNoise->foregroundRole(), Qt::red); + } else { + ui.qlNoise->setText(tr("-%1 dB").arg(v)); + } + ui.qlNoise->setPalette(pal); + rsVOIP->setVoipiNoiseSuppress(- ui.qsNoise->value()); +} + +void VOIPConfigPanel::on_qsAmp_valueChanged(int v) { + v = 20000 - v; + float d = 20000.0f/static_cast(v); + ui.qlAmp->setText(QString::fromLatin1("%1").arg(d, 0, 'f', 2)); + rsVOIP->setVoipiMinLoudness(20000 - ui.qsAmp->value()); +} + +void VOIPConfigPanel::on_qcbEchoCancel_clicked() { + rsVOIP->setVoipEchoCancel(ui.qcbEchoCancel->isChecked()); +} + + +void VOIPConfigPanel::on_qcbTransmit_currentIndexChanged(int v) { + switch (v) { + case 0: + ui.qswTransmit->setCurrentWidget(ui.qwContinuous); + break; + case 1: + ui.qswTransmit->setCurrentWidget(ui.qwVAD); + break; + case 2: + ui.qswTransmit->setCurrentWidget(ui.qwPTT); + break; + } + if (loaded) + rsVOIP->setVoipATransmit(static_cast(ui.qcbTransmit->currentIndex() )); +} + + +void VOIPConfigPanel::on_Tick_timeout() +{ + // update the sound capture bar + + ui.abSpeech->iBelow = ui.qsTransmitMin->value(); + ui.abSpeech->iAbove = ui.qsTransmitMax->value(); + + if (loaded) { + rsVOIP->setVoipfVADmin(ui.qsTransmitMin->value()); + rsVOIP->setVoipfVADmax(ui.qsTransmitMax->value()); + } + + ui.abSpeech->iValue = iroundf(inputAudioProcessor->dVoiceAcivityLevel * 32767.0f + 0.5f); + ui.abSpeech->update(); + + // also transmit encoded video + + RsVOIPDataChunk chunk ; + + while((!videoInput->stopped()) && videoInput->getNextEncodedPacket(chunk)) + { + videoProcessor->receiveEncodedData(chunk) ; + chunk.clear() ; + } +} + +void VOIPConfigPanel::emptyBuffer() { + while(inputAudioProcessor->hasPendingPackets()) { + inputAudioProcessor->getNetworkPacket(); //that will purge the buffer + } +} + +void VOIPConfigPanel::on_qpbAudioWizard_clicked() { + AudioWizard aw(this); + aw.exec(); + loadSettings(); +} + +void VOIPConfigPanel::on_changedCurrentInputDevice(int i) +{ + QString s = dynamic_cast(sender())->itemData(i).toString(); + + videoInput->stop(); + + // check that the camera still exists + + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + + for(const QString& cams:input_devices) + if(s == cams) + { + std::cerr << "Switching to camera \"" << s.toStdString() << "\"" << std::endl; + + videoInput->start(s); + + return; + } + + // if not, re-create the ComboBox + + checkAvailableCameras(); +} + +void VOIPConfigPanel::checkAvailableCameras() +{ + // save current camera + QString current_cam = videoInput->currentCameraDescriptionString(); + + // Check that the list of cams we had previously is the same than the list of available camera. + + QList input_devices; + QVideoInputDevice::getAvailableDevices(input_devices); + + bool same = true; + if(input_devices.size() != ui.inputDevice_CB->count()) + same = false; + + if(same) + { + int n=0; + for(auto& s:input_devices) + { + if(ui.inputDevice_CB->itemData(n).toString() != s) + { + same = false; + break; + } + n++; + } + } + + // If not, re-add them to the comboBox and make sure to re-select the same camera. + + if(!same) + { + whileBlocking(ui.inputDevice_CB)->clear(); // remove existing entries + whileBlocking(ui.inputDevice_CB)->addItem(tr("[No video]"),QString("")); + int n=0; + int found_index = -1; + + for(auto& s:input_devices) + { + whileBlocking(ui.inputDevice_CB)->addItem(s,QVariant(s)); + + if(s == current_cam) + found_index = n; + + n++; + } + + if(found_index >= 0) + ui.inputDevice_CB->setCurrentIndex(found_index); + else + ui.inputDevice_CB->setCurrentIndex(0); // no video + } +} + + + + + + + + + diff --git a/plugins/VOIP/gui/AudioInputConfig.h b/plugins/VOIP/gui/VOIPConfigPanel.h similarity index 77% rename from plugins/VOIP/gui/AudioInputConfig.h rename to plugins/VOIP/gui/VOIPConfigPanel.h index 3dd2cecae..dcfc0323b 100644 --- a/plugins/VOIP/gui/AudioInputConfig.h +++ b/plugins/VOIP/gui/VOIPConfigPanel.h @@ -19,7 +19,6 @@ * * *******************************************************************************/ #pragma once -#pragma once #include #include @@ -46,9 +45,9 @@ private: voipGraphSource *_src ; }; -#include "ui_AudioInputConfig.h" +#include "ui_VOIPConfigPanel.h" -class AudioInputConfig : public ConfigPage +class VOIPConfigPanel : public ConfigPage { Q_OBJECT @@ -60,33 +59,37 @@ class AudioInputConfig : public ConfigPage //VideoDecoder *videoDecoder ; //VideoEncoder *videoEncoder ; QVideoInputDevice *videoInput ; - VideoProcessor *videoProcessor ; + VideoProcessor *videoProcessor ; bool loaded; + QString currentCameraDescription; voipGraphSource *graph_source ; protected: QTimer *qtTick; - /*void hideEvent(QHideEvent *event); - void showEvent(QShowEvent *event);*/ + void clearPipeline(); public: /** Default Constructor */ - AudioInputConfig(QWidget * parent = 0, Qt::WindowFlags flags = 0); + VOIPConfigPanel(QWidget * parent = 0, Qt::WindowFlags flags = 0); /** Default Destructor */ - ~AudioInputConfig(); + ~VOIPConfigPanel(); /** Saves the changes on this page */ - virtual bool save(QString &errmsg); + virtual bool save(QString &errmsg)override ; /** Loads the settings for this page */ - virtual void load(); + virtual void load()override ; - virtual QPixmap iconPixmap() const { return QPixmap(":/images/talking_on.svg") ; } - virtual QString pageName() const { return tr("VOIP") ; } - virtual QString helpText() const { return ""; } + virtual QPixmap iconPixmap() const override { return QPixmap(":/images/talking_on.svg") ; } + virtual QString pageName() const override { return tr("VOIP") ; } + virtual QString helpText() const override { return ""; } + virtual void showEvent(QShowEvent *) override; + virtual void hideEvent(QHideEvent *event) override; private slots: - void updateAvailableBW(double r); + void on_changedCurrentInputDevice(int i); + void checkAvailableCameras(); + void updateAvailableBW(double r); void loadSettings(); void emptyBuffer(); void togglePreview(bool) ; diff --git a/plugins/VOIP/gui/AudioInputConfig.ui b/plugins/VOIP/gui/VOIPConfigPanel.ui similarity index 55% rename from plugins/VOIP/gui/AudioInputConfig.ui rename to plugins/VOIP/gui/VOIPConfigPanel.ui index 62e8c98a6..9fbb9008c 100644 --- a/plugins/VOIP/gui/AudioInputConfig.ui +++ b/plugins/VOIP/gui/VOIPConfigPanel.ui @@ -10,50 +10,289 @@ 832 - + - - - Audio Wizard + + + Video + + + + + + + + 170 + 128 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + Input device: + + + + + + + + + + + 0 + 0 + + + + Available bandwidth: + + + + + + + <html><head/><body><p>Use this field to simulate the maximum bandwidth available so as to preview what the encoded video will look like with the corresponding compression rate.</p></body></html> + + + KB/s + + + 1 + + + 2.000000000000000 + + + 200.000000000000000 + + + 30.000000000000000 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Display encoded (and then decoded) frame, to check the codec's quality. If not selected, the image above only shows the frame that is grabbed from your camera.</p></body></html> + + + preview + + + + + + - - - - 0 - 0 - - + - Transmission + Audio - - - - - &Transmit + + + + + + 30 + 0 + - - qcbTransmit + + - - + + + + true + - When to transmit your speech + Noise suppression - <b>This sets when speech should be transmitted.</b><br /><i>Continuous</i> - All the time<br /><i>Voice Activity</i> - When you are speaking clearly.<br /><i>Push To Talk</i> - When you hold down the hotkey set under <i>Shortcuts</i>. + <b>This sets the amount of noise suppression to apply.</b><br />The higher this value, the more aggressively stationary noise will be suppressed. + + + 14 + + + 60 + + + 5 + + + Qt::Horizontal - + + + + Noise Suppression + + + qsNoise + + + + + + + + 30 + 0 + + + + + + + + + + + Maximum amplification of input sound + + + <b>Maximum amplification of input.</b><br />RetroShare normalizes the input volume before compressing, and this sets how much it's allowed to amplify.<br />The actual level is continually updated based on your current speech pattern, but it will never go above the level specified here.<br />If the <i>Microphone loudness</i> level of the audio statistics hover around 100%, you probably want to set this to 2.0 or so, but if, like most people, you are unable to reach 100%, set this to something much higher.<br />Ideally, set it so <i>Microphone Loudness * Amplification Factor >= 100</i>, even when you're speaking really soft.<br /><br />Note that there is no harm in setting this to maximum, but RetroShare will start picking up other conversations if you leave it to auto-tune to that level. + + + 19500 + + + 500 + + + 2000 + + + Qt::Horizontal + + + + + + + Amplification + + + qsAmp + + + + + + + + + + 0 + 0 + + + + Echo Cancellation Processing + + + false + + + + + + + + + + 0 + 0 + + + + &Transmit: + + + qcbTransmit + + + + + + + When to transmit your speech + + + <b>This sets when speech should be transmitted.</b><br /><i>Continuous</i> - All the time<br /><i>Voice Activity</i> - When you are speaking clearly.<br /><i>Push To Talk</i> - When you hold down the hotkey set under <i>Shortcuts</i>. + + + + + + + + + + 0 + 0 + + + + Audio Wizard + + + + + + + + + 0 + 0 + + - 2 + 1 @@ -231,218 +470,21 @@ - - - - - - - - - Audio Processing - - - - - - Noise Suppression - - - qsNoise - - - - - - - true - - - Noise suppression - - - <b>This sets the amount of noise suppression to apply.</b><br />The higher this value, the more aggressively stationary noise will be suppressed. - - - 14 - - - 60 - - - 5 - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - - - - - - - - Amplification - - - qsAmp - - - - - - - Maximum amplification of input sound - - - <b>Maximum amplification of input.</b><br />RetroShare normalizes the input volume before compressing, and this sets how much it's allowed to amplify.<br />The actual level is continually updated based on your current speech pattern, but it will never go above the level specified here.<br />If the <i>Microphone loudness</i> level of the audio statistics hover around 100%, you probably want to set this to 2.0 or so, but if, like most people, you are unable to reach 100%, set this to something much higher.<br />Ideally, set it so <i>Microphone Loudness * Amplification Factor >= 100</i>, even when you're speaking really soft.<br /><br />Note that there is no harm in setting this to maximum, but RetroShare will start picking up other conversations if you leave it to auto-tune to that level. - - - 19500 - - - 500 - - - 2000 - - - Qt::Horizontal - - - - - - - - 30 - 0 - - - - - - - - - - - Echo Cancellation Processing - - - false - - - - - - - - - - - - Video Processing - - - - - - 170 - 128 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - 0 - 0 - - - - QFrame::StyledPanel - - - QFrame::Raised - - + - - - - - Available bandwidth: - - - - - - - <html><head/><body><p>Use this field to simulate the maximum bandwidth available so as to preview what the encoded video will look like with the corresponding compression rate.</p></body></html> - - - KB/s - - - 1 - - - 2.000000000000000 - - - 200.000000000000000 - - - 30.000000000000000 - - - - - - - - - <html><head/><body><p>Display encoded (and then decoded) frame, to check the codec's quality. If not selected, the image above only shows the frame that is grabbed from your camera.</p></body></html> - - - preview - - - - - + Qt::Vertical - 1 - 151 + 20 + 40 @@ -459,12 +501,22 @@ voipGraph QFrame -
gui/AudioInputConfig.h
+
gui/VOIPConfigPanel.h
1
+ + AudioBar + QWidget +
gui/AudioStats.h
+ 1 +
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
- qcbTransmit qsDoublePush qsTransmitHold qsTransmitMin diff --git a/plugins/VOIP/gui/VOIPToasterItem.ui b/plugins/VOIP/gui/VOIPToasterItem.ui index ef1a3e402..676e787e2 100644 --- a/plugins/VOIP/gui/VOIPToasterItem.ui +++ b/plugins/VOIP/gui/VOIPToasterItem.ui @@ -22,7 +22,7 @@ 102 - + 0 @@ -39,14 +39,14 @@ 0 - + QFrame::WinPanel QFrame::Raised - + 2 @@ -63,7 +63,7 @@ 2 - + 6 @@ -97,13 +97,20 @@ + + + 12 + 75 + true + + RetroShare - + Qt::Horizontal @@ -141,7 +148,7 @@ - + 6 @@ -240,7 +247,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - + 0 @@ -255,6 +262,7 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, + 12 75 true @@ -272,11 +280,6 @@ background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 0.67, - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
AvatarWidget QLabel diff --git a/plugins/VOIP/qss/VOIP_Standard.qss b/plugins/VOIP/qss/VOIP_Standard.qss index ee40c6344..851f9af4f 100644 --- a/plugins/VOIP/qss/VOIP_Standard.qss +++ b/plugins/VOIP/qss/VOIP_Standard.qss @@ -1 +1 @@ -/* Standard stylesheet for FeedReader */ +/* Standard stylesheet for VOIP */ diff --git a/plugins/FeedReader/qss/FeedReader_qss.default b/plugins/VOIP/qss/VOIP_default.qss similarity index 51% rename from plugins/FeedReader/qss/FeedReader_qss.default rename to plugins/VOIP/qss/VOIP_default.qss index 27ca35f0c..9b964468c 100644 --- a/plugins/FeedReader/qss/FeedReader_qss.default +++ b/plugins/VOIP/qss/VOIP_default.qss @@ -1,9 +1,3 @@ /* Default stylesheet This file is used as default for all stylesheets and can be overloaded */ -/* Font */ - -FeedReaderFeedItem QLabel#titleLabel -{ - qproperty-fontSizeFactor: 135; -} diff --git a/plugins/VOIP/qss/VOIP_qss.qrc b/plugins/VOIP/qss/VOIP_qss.qrc index f82c259d4..81df6f74d 100644 --- a/plugins/VOIP/qss/VOIP_qss.qrc +++ b/plugins/VOIP/qss/VOIP_qss.qrc @@ -1,6 +1,6 @@ - VOIP_qss.default + VOIP_default.qss VOIP_Standard.qss diff --git a/plugins/plugins.pro b/plugins/plugins.pro index 209b82898..7ecbc32c7 100644 --- a/plugins/plugins.pro +++ b/plugins/plugins.pro @@ -19,5 +19,5 @@ TEMPLATE = subdirs SUBDIRS += \ - VOIP \ + VOIP \ FeedReader diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc new file mode 100644 index 000000000..19c286256 --- /dev/null +++ b/retroshare-friendserver/src/friendserver.cc @@ -0,0 +1,561 @@ +#include "util/rsdebug.h" +#include "util/rsprint.h" +#include "util/rsdir.h" +#include "util/rsbase64.h" +#include "util/radix64.h" + +#include "crypto/hashstream.h" + +#include "pgp/pgpkeyutil.h" +#include "pgp/rscertificate.h" +#include "pgp/openpgpsdkhandler.h" + +#include "friendserver.h" +#include "friend_server/fsitem.h" + +static const rstime_t MAXIMUM_PEER_INACTIVE_DELAY = 600; +static const rstime_t DELAY_BETWEEN_TWO_AUTOWASH = 60; +static const rstime_t DELAY_BETWEEN_TWO_DEBUG_PRINT = 10; +static const uint32_t MAXIMUM_PEERS_TO_REQUEST = 10; + +void FriendServer::threadTick() +{ + // Listen to the network interface, capture incoming data etc. + + RsItem *item; + + while(nullptr != (item = mni->GetItem())) + { + RsFriendServerItem *fsitem = dynamic_cast(item); + + if(!fsitem) + { + RsErr() << "Received an item of the wrong type!" ; + + continue; + } + std::cerr << "Received item: " << std::endl << *fsitem << std::endl; + + switch(fsitem->PacketSubType()) + { + case RS_PKT_SUBTYPE_FS_CLIENT_PUBLISH: handleClientPublish(dynamic_cast(fsitem)); + break; + case RS_PKT_SUBTYPE_FS_CLIENT_REMOVE: handleClientRemove(dynamic_cast(fsitem)); + break; + default: ; + } + delete item; + } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + static rstime_t last_autowash_TS = time(nullptr); + rstime_t now = time(nullptr); + + if(last_autowash_TS + DELAY_BETWEEN_TWO_AUTOWASH < now) + { + last_autowash_TS = now; + autoWash(); + } + + static rstime_t last_debugprint_TS = time(nullptr); + + if(last_debugprint_TS + DELAY_BETWEEN_TWO_DEBUG_PRINT < now) + { + last_debugprint_TS = now; + debugPrint(false); + } +} + +void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *item) +{ + // We always respond with exactly one item, be it an error item or a list of friends to connect to. + + try + { + RsDbg() << "Received a client publish item from " << item->PeerId() << ":"; + RsDbg() << *item ; + + // First of all, read PGP key and short invites, parse them, and check that they contain the same information + + RsPeerId pid; + + if(!handleIncomingClientData(item->pgp_public_key_b64,item->short_invite,pid)) + { + RsErr() << "Client data is dropped because of error." ; + return ; + } + + // All good. + + auto pi(mCurrentClientPeers.find(pid)); + + // Update the list of closest peers for other peers, based on which known friends it reports, and of current peer depending + // on friendship levels of other peers. + + updateClosestPeers(pi->first,pi->second.pgp_fingerprint,item->already_received_peers); + + RsDbg() << "Sending response item to " << item->PeerId() ; + + RsFriendServerServerResponseItem sr_item; + + std::set friends; + sr_item.unique_identifier = pi->second.last_identifier; + sr_item.friend_invites = computeListOfFriendInvites(pi->first,item->n_requested_friends,item->already_received_peers,friends); + sr_item.PeerId(item->PeerId()); + + RsDbg() << " Got " << sr_item.friend_invites.size() << " closest peers not in the list." ; + RsDbg() << " Updating local information for destination peer." ; + + // Update friendship levels of the peer that will receive the new list + + for(auto fr:friends) + { + auto& p(pi->second.friendship_levels[fr]); + + RsDbg() << " Already a friend: " << fr << ", with local status " << static_cast(p) ; + + if(static_cast(p) < static_cast(RsFriendServer::PeerFriendshipLevel::HAS_KEY)) + { + p = RsFriendServer::PeerFriendshipLevel::HAS_KEY; + RsDbg() << " --> updating status to HAS_KEY" ; + } + } + + // Now encrypt the item with the public PGP key of the destination. This prevents the wrong person to request for + // someone else's data. + + RsDbg() << " Encrypting item..." ; + + RsFriendServerEncryptedServerResponseItem *encrypted_response_item = new RsFriendServerEncryptedServerResponseItem; + uint32_t serialized_clear_size = FsSerializer().size(&sr_item); + RsTemporaryMemory serialized_clear_mem(serialized_clear_size); + FsSerializer().serialise(&sr_item,serialized_clear_mem,&serialized_clear_size); + + uint32_t encrypted_mem_size = serialized_clear_size+1000; // leave some extra space + RsTemporaryMemory encrypted_mem(encrypted_mem_size); + + if(!mPgpHandler->encryptDataBin(PGPHandler::pgpIdFromFingerprint(pi->second.pgp_fingerprint), + serialized_clear_mem,serialized_clear_size, + encrypted_mem,&encrypted_mem_size)) + { + RsErr() << "Cannot encrypt item for PGP Id/FPR " << pi->second.pgp_fingerprint << ". Something went wrong." ; + return; + } + encrypted_response_item->PeerId(item->PeerId()); + encrypted_response_item->bin_len = encrypted_mem_size; + encrypted_response_item->bin_data = malloc(encrypted_mem_size); + + memcpy(encrypted_response_item->bin_data,encrypted_mem,encrypted_mem_size); + + // Send the item. + + RsDbg() << " Sending item..." ; + mni->SendItem(encrypted_response_item); + } + catch(std::exception& e) + { + RsErr() << "ERROR: " << e.what() ; + + RsFriendServerStatusItem *status_item = new RsFriendServerStatusItem; + status_item->status = RsFriendServerStatusItem::END_OF_TRANSMISSION; + status_item->PeerId(item->PeerId()); + mni->SendItem(status_item); + return; + } +} + +std::map FriendServer::computeListOfFriendInvites(const RsPeerId &pid, uint32_t nb_reqs_invites, + const std::map& already_known_peers, + std::set& chosen_peers) const +{ + // Strategy: we want to return the same set of friends for a given PGP profile key. + // Still, using some closest distance strategy, the n-closest peers for profile A is not the + // same set than the n-closest peers for profile B, so some peers will not be in both sets. + // We have multiple options: + // + // Option 1: + // + // (1) for each profile, keep the list of n-closest peers updated (when a new peer if added/removed all lists are updated) + // + // When a peer asks for k friends, read from (1), until the number of collected peers + // reaches the requested value. Then when a peer receives a connection request, ask the friend server if the + // peer has been sent your own cert. + // + // Option 2: + // + // (1) for each profile, keep the list of n-closest peers updated (when a new peer if added/removed all lists are updated) + // (2) for each profile, keep the list of which peers have been sent this profile already + // + // When a peer asks for k friends, read from (2) first, then (1), until the number of collected peers + // reaches the requested value. + // + // So we choose Option 2. + + std::map res; + chosen_peers.clear(); + auto pinfo_it(mCurrentClientPeers.find(pid)); + + if(pinfo_it == mCurrentClientPeers.end()) + { + RsErr() << "inconsistency in computeListOfFriendInvites. Something's wrong in the code." ; + return res; + } + auto pinfo(pinfo_it->second); + + for(const auto& pit:pinfo.closest_peers) + { + if(already_known_peers.find(pit.second) == already_known_peers.end()) + { + RsDbg() << " peer " << pit.second << ": not in supplied list => adding it."; + + const auto p = mCurrentClientPeers.find(pit.second); + + if(p == mCurrentClientPeers.end()) // should not happen, but just an extra security. + continue; + + auto pp = p->second.friendship_levels.find(pid); + + auto peer_friendship_level = (pp==p->second.friendship_levels.end())?(RsFriendServer::PeerFriendshipLevel::UNKNOWN):(pp->second); + + res[p->second.short_certificate] = peer_friendship_level; + chosen_peers.insert(p->first); + + if(res.size() + already_known_peers.size() >= nb_reqs_invites) + break; + } + else + { + auto p = already_known_peers.find(pit.second); + RsDbg() << " peer " << pit.second << ": already in supplied list, with status " << static_cast(p->second) << ". Not adding it."; + } + } + + return res; +} + +bool FriendServer::handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64,RsPeerId& pid) +{ + // 1 - Check that the incoming data is sound. + + try + { + RsDbg() << " Checking item data..."; + + std::string error_string; + std::vector key_binary_data ; + + if(RsBase64::decode(pgp_public_key_b64,key_binary_data)) + throw std::runtime_error(" Cannot decode client pgp public key: \"" + pgp_public_key_b64 + "\". Wrong format??"); + + RsDbg() << " Parsing public key:" ; + + PGPKeyInfo received_key_info; + + if(!PGPKeyManagement::parsePGPPublicKey(key_binary_data.data(),key_binary_data.size(),received_key_info)) + throw std::runtime_error("Cannot parse received pgp public key.") ; + + RsDbg() << " Issuer : \"" << received_key_info.user_id << "\"" ; + RsDbg() << " Fingerprint: " << RsPgpFingerprint::fromBufferUnsafe(received_key_info.fingerprint) ; + + RsDbg() << " Parsing short invite:" ; + + RsPeerDetails shortInviteDetails; + uint32_t errorCode = 0; + + if(short_invite_b64.empty() || !RsCertificate::decodeRadix64ShortInvite(short_invite_b64, shortInviteDetails,errorCode )) + throw std::runtime_error("Could not parse short certificate. Error = " + RsUtil::NumberToString(errorCode)); + + RsDbg() << " Fingerprint: " << shortInviteDetails.fpr ; + RsDbg() << " Peer ID: " << shortInviteDetails.id ; + + if(shortInviteDetails.fpr != RsPgpFingerprint::fromBufferUnsafe(received_key_info.fingerprint)) + throw std::runtime_error("Fingerpring from short invite and public key are different! Very unexpected! Message will be ignored."); + + // 3 - if the key is not already here, add it to keyring. + + { + RsPgpFingerprint fpr_test; + if(mPgpHandler->isPgpPubKeyAvailable(RsPgpId::fromBufferUnsafe(received_key_info.fingerprint+12))) + RsDbg() << " PGP Key is already into keyring."; + else + { + RsPgpId pgp_id; + if(!mPgpHandler->LoadCertificateFromBinaryData(key_binary_data.data(),key_binary_data.size(), pgp_id, error_string)) + throw std::runtime_error("Cannot load client's pgp public key into keyring: " + error_string) ; + + RsDbg() << " Public key added to keyring."; + RsDbg() << " Sync-ing the PGP keyring on disk"; + + mPgpHandler->syncDatabase(); + } + } + // Store/update the peer info + + auto& pi(mCurrentClientPeers[shortInviteDetails.id]); + + pi.short_certificate = short_invite_b64; + pi.last_connection_TS = time(nullptr); + pi.pgp_fingerprint = shortInviteDetails.fpr; + + while(pi.last_identifier == 0) // reuse the same identifier (so it's not really a nonce, but it's kept secret whatsoever). + pi.last_identifier = RsRandom::random_u64(); + + pid = shortInviteDetails.id; + return true; + } + catch (std::exception& e) + { + RsErr() << "Exception while adding client data: " << e.what() ; + return false; + } +} + +void FriendServer::handleClientRemove(const RsFriendServerClientRemoveItem *item) +{ + RsDbg() << "Received a client remove item:" << *item ; + + auto it = mCurrentClientPeers.find(item->peer_id); + + if(it == mCurrentClientPeers.end()) + { + RsErr() << " ERROR: Client " << item->peer_id << " is not known to the server." ; + return; + } + + if(it->second.last_identifier != item->unique_identifier) + { + RsErr() << " ERROR: Client supplied a nonce " << std::hex << item->unique_identifier << std::dec << " that is not correct (expected " + << std::hex << it->second.last_identifier << std::dec << ")"; + return; + } + + RsDbg() << " Nonce is correct: " << std::hex << item->unique_identifier << std::dec << ". Removing peer " << item->peer_id ; + + removePeer(item->peer_id); +} + +void FriendServer::removePeer(const RsPeerId& peer_id) +{ + auto it = mCurrentClientPeers.find(peer_id); + + if(it != mCurrentClientPeers.end()) + mCurrentClientPeers.erase(it); + + for(auto& it:mCurrentClientPeers) + { + // Also remove that peer from all n-closest lists + + for(auto pit(it.second.closest_peers.begin());pit!=it.second.closest_peers.end();) + if(pit->second == peer_id) + { + RsDbg() << " Removing from n-closest peers of peer " << it.first ; + + auto tmp(pit); + ++tmp; + it.second.closest_peers.erase(pit); + pit=tmp; + } + else + ++pit; + + // Also remove that peer from friendship levels of that particular peer. + + auto fit = it.second.friendship_levels.find(peer_id); + + if(fit != it.second.friendship_levels.end()) + { + RsDbg() << " Removing from have_added_as_friend peers of peer " << it.first ; + it.second.friendship_levels.erase(fit); + } + } +} + +PeerInfo::PeerDistance FriendServer::computePeerDistance(const RsPgpFingerprint& p1,const RsPgpFingerprint& p2) +{ + auto res = (p1 ^ p2)^mRandomPeerBias; + auto res2 = RsDirUtil::sha1sum(res.toByteArray(),res.SIZE_IN_BYTES); // sha1sum prevents reverse finding the random bias + + std::cerr << "Computing peer distance: p1=" << p1 << " p2=" << p2 << " p1^p2=" << (p1^p2) << " distance=" << res2 << std::endl; + + return res2; +} +FriendServer::FriendServer(const std::string& base_dir,const std::string& listening_address,uint16_t listening_port) + : mListeningAddress(listening_address),mListeningPort(listening_port) +{ + RsDbg() << "Creating friend server." ; + mBaseDirectory = base_dir; + + // Create a PGP Handler + + std::string pgp_public_keyring_path = RsDirUtil::makePath(base_dir,"pgp_public_keyring") ; + std::string pgp_lock_path = RsDirUtil::makePath(base_dir,"pgp_lock") ; + + std::string pgp_private_keyring_path = RsDirUtil::makePath(base_dir,"pgp_private_keyring") ; // not used. + std::string pgp_trustdb_path = RsDirUtil::makePath(base_dir,"pgp_trustdb") ; // not used. + + mPgpHandler = new OpenPGPSDKHandler(pgp_public_keyring_path,pgp_private_keyring_path,pgp_trustdb_path,pgp_lock_path); + + // Random bias. Should be cryptographically safe. + + mRandomPeerBias = RsPgpFingerprint::random(); +} + +void FriendServer::run() +{ + // 1 - create network interface. + + mni = new FsNetworkInterface(mListeningAddress,mListeningPort); + mni->start(); + + while(!shouldStop()) { threadTick() ; } +} + +void FriendServer::autoWash() +{ + rstime_t now = time(nullptr); + std::list to_remove; + + for(std::map::iterator it(mCurrentClientPeers.begin());it!=mCurrentClientPeers.end();++it) + if(it->second.last_connection_TS + MAXIMUM_PEER_INACTIVE_DELAY < now) + { + RsDbg() << "Removing client peer " << it->first << " because it's inactive for more than " << MAXIMUM_PEER_INACTIVE_DELAY << " seconds." ; + to_remove.push_back(it->first); + } + + for(auto peer_id:to_remove) + removePeer(peer_id); +} + +void FriendServer::updateClosestPeers(const RsPeerId& pid,const RsPgpFingerprint& fpr,const std::map& friended_peers) +{ + auto find_multi = [](PeerInfo::PeerDistance dist,std::map< std::pair,RsPeerId >& mp) + -> std::map< std::pair,RsPeerId >::iterator + { + auto it = mp.find(std::make_pair(RsFriendServer::PeerFriendshipLevel::UNKNOWN,dist)) ; + + if(it == mp.end()) it = mp.find(std::make_pair(RsFriendServer::PeerFriendshipLevel::NO_KEY ,dist)); + if(it == mp.end()) it = mp.find(std::make_pair(RsFriendServer::PeerFriendshipLevel::HAS_KEY ,dist)); + if(it == mp.end()) it = mp.find(std::make_pair(RsFriendServer::PeerFriendshipLevel::HAS_ACCEPTED_KEY,dist)); + + return it; + }; + auto remove_from_map = [find_multi](PeerInfo::PeerDistance dist, + std::map< std::pair,RsPeerId>& mp) -> bool + { + auto mpit = find_multi(dist,mp); + + if(mpit != mp.end()) + { + mp.erase(mpit); + return true; + } + else + return false; + }; + + auto& pit(mCurrentClientPeers[pid]); + + for(auto& it:mCurrentClientPeers) + if(it.first != pid) + { + // 1 - for all existing peers, update the level at which the given peer has added the peer as friend. + + auto peer_iterator = friended_peers.find(it.first); + auto peer_friendship_level = (peer_iterator==friended_peers.end())? (RsFriendServer::PeerFriendshipLevel::UNKNOWN):(peer_iterator->second); + + PeerInfo::PeerDistance d = computePeerDistance(fpr,it.second.pgp_fingerprint); + + // Remove the peer from the map. This is costly. I need to find something better. If the peer is already + // in the list, it has a map key with the same distance. + + remove_from_map(d,it.second.closest_peers); + + it.second.closest_peers[std::make_pair(peer_friendship_level,d)] = pid; + + while(it.second.closest_peers.size() > MAXIMUM_PEERS_TO_REQUEST) + it.second.closest_peers.erase(std::prev(it.second.closest_peers.end())); + + // 2 - for the current peer, update the list of closest peers + + auto pit2 = it.second.friendship_levels.find(pid); + peer_friendship_level = (pit2==it.second.friendship_levels.end())? (RsFriendServer::PeerFriendshipLevel::UNKNOWN):(pit2->second); + + remove_from_map(d,pit.closest_peers); + + pit.closest_peers[std::make_pair(peer_friendship_level,d)] = it.first; + + while(pit.closest_peers.size() > MAXIMUM_PEERS_TO_REQUEST) + pit.closest_peers.erase(std::prev(pit.closest_peers.end())); + } + + // Also update the friendship levels for the current peer, of all friends from the list. + + for(auto it:friended_peers) + pit.friendship_levels[it.first] = it.second; +} + +Sha1CheckSum FriendServer::computeDataHash() +{ + librs::crypto::HashStream s(librs::crypto::HashStream::SHA1); + + for(auto p(mCurrentClientPeers.begin());p!=mCurrentClientPeers.end();++p) + { + s << p->first; + + const auto& inf(p->second); + + s << inf.pgp_fingerprint; + s << inf.short_certificate; + s << (uint64_t)inf.last_connection_TS; + s << inf.last_identifier; + + for(auto d(inf.closest_peers.begin());d!=inf.closest_peers.end();++d) + { + s << static_cast(d->first.first) ; + s << d->first.second ; + s << d->second; + } + for(auto d:inf.friendship_levels) + { + s << d.first ; + s << static_cast(d.second); + } + } + return s.hash(); +} +void FriendServer::debugPrint(bool force) +{ + auto h = computeDataHash(); + + if((h != mCurrentDataHash) || force) + { + RsDbg() << "========== FriendServer statistics ============"; + RsDbg() << " Base directory: "<< mBaseDirectory; + RsDbg() << " Random peer bias: "<< mRandomPeerBias; + RsDbg() << " Current hash: "<< h; + RsDbg() << " Network interface: "; + RsDbg() << " Max peers in n-closest list: " << MAXIMUM_PEERS_TO_REQUEST; + RsDbg() << " Current active peers: " << mCurrentClientPeers.size() ; + + rstime_t now = time(nullptr); + + for(const auto& it:mCurrentClientPeers) + { + RsDbg() << " " << it.first << ": identifier=" << std::hex << it.second.last_identifier << std::dec << " fpr: " << it.second.pgp_fingerprint << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; + RsDbg() << " Closest peers:" ; + + for(auto pit:it.second.closest_peers) + RsDbg() << " " << pit.second << " distance=" << pit.first.second << " Peer reciprocal status:" << static_cast(pit.first.first); + } + + RsDbg() << "==============================================="; + + mCurrentDataHash = h; + } + +} + + + + diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h new file mode 100644 index 000000000..259b0e5ba --- /dev/null +++ b/retroshare-friendserver/src/friendserver.h @@ -0,0 +1,181 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#pragma once + +#include "util/rsthreads.h" +#include "pqi/pqistreamer.h" +#include "pgp/pgphandler.h" +#include "retroshare/rsfriendserver.h" + +#include "network.h" + +class RsFriendServerClientRemoveItem; +class RsFriendServerClientPublishItem; + +// +================================================================+ +// | o---o o | +// | \ / - Retroshare Friend Server - / \ | +// | o o---o | +// +================================================================+ +// +// The friend server facilitates a group of RS Tor-nodes to make friends. It maintains a pool of +// participants (RS nodes currently susbscribing to the friend server) and advertise them to each other +// as possible friends. Its goal is to allow new RS users to quickly experiment with the software without +// compromising their anonymity. +// +// Implementation +// ============== +// +// The implementation is entirely client-based: clients make a request, and get a response. No connection is maintained +// beyond this interaction. Consequently, the friend server returns a random ID to each client that the client can use to +// e.g. signal its departure from the friend server and the release of its data. +// +// Both client and server use a binary interface linked to a proxy-connected socket to stream RS items, everything +// happenning on top of Tor connections. +// +// Algorithms +// ========== +// +// * Protocol +// +// Retroshare Client Server (Friend Server) +// +// ------------ Tor connection --------> no action +// Server online MSG <-------------- Tor ACK ------------ +// +// +// Friend Req. loop ------------ Friend Request --------> Friend list calculation / update +// <---------- Friend list + ID -------- +// +// +// FS disabled ------------ FS Close + ID ---------> Data cleaning, peer removal. +// +// +// * Friend selection +// +// In order to reduce the ease to retrieve the list of all participants to a friend server, the +// friend server always returns the same list of friends to a given peer. To do so, participants are sorted +// for each peer, using a XOR distance such as: +// +// d(P1,P2) = P1 (XOR) P2 (XOR) R +// +// ...where R is a random bias. +// +// Since being in the n closest peers is not a reflexive relationship (P1 may be within the n closest peers +// to P2 but P2 may not be in the n closest peers to P1), selected friends for peer A are picked from both +// the closest peers of A, and the peers that received the RS certificate of A. +// +// Another important effect of the stability of retrieved friends is to maintain a network that is not +// fully connected and stable over time, which corresponds to the mesh model of the RS network. +// +// * Peer friendship level +// +// For display purposes, the friend server also stores the "friendship level" for each pair of peers, +// that means whether the peer has added the other peer as friend, or only reveived his key, etc. +// +// Peers send to the friend server the list of peers they already have, with their own friendship +// level with that peer. The FS needs to send back a list of peers, with the friendship level to the current peer. +// In the list of closest peers, the reverse friendship levels are stored: for a peer A the reverse friendship +// level to peer B is whether B has added A as friend or not.In the list of friends for a peer, the forward FL +// is stored. The forward FL of a peer A to a peer B is whether A has added B as friend or not. +// +// * Security +// +// Obviously the friend server knows who is possibly connected to whom. Since the connections to the +// friend server are anonymous, this information is difficult to protect, although the implementation +// currently makes it difficult to retrieve. +// +// The friend server is only available to Tor nodes, since it allows RS nodes to connect to random peers. +// This allows trying the software without compromizing one's privacy. + +struct PeerInfo +{ + typedef Sha1CheckSum PeerDistance; + + RsPgpFingerprint pgp_fingerprint; + std::string short_certificate; + rstime_t last_connection_TS; + uint64_t last_identifier; + + // The following map contains the list of closest peers. The sorting is based + // on a combination of the peer XOR distance and the friendship level, so that + // peers which already have added a peer are considered first as potential receivers of his key. + // The friendship level here is a reverse FL, e.g. whether each closest peer has added the current peer as friend. + + std::map,RsPeerId > closest_peers; // limited in size. + + // Which peers have received the key for that particular peer, along with the direct friendship level: whether current peer has added each peer. + + std::map friendship_levels; // unlimited in size, but no distance sorting. +}; + +class FriendServer : public RsTickingThread +{ +public: + FriendServer(const std::string& base_directory,const std::string& listening_address,uint16_t listening_port); + +private: + // overloads RsTickingThread + + virtual void threadTick() override; + virtual void run() override; + + // Own algorithmics + + void handleClientRemove(const RsFriendServerClientRemoveItem *item); + void handleClientPublish(const RsFriendServerClientPublishItem *item); + + // Updates for each peer in the database, the list of closest peers w.r.t. some arbitrary distance. + void updateClosestPeers(const RsPeerId& pid, const RsPgpFingerprint& fpr, const std::map &friended_peers); + + // removes a single peer from all lists. + void removePeer(const RsPeerId& peer_id); + + // Adds the incoming peer data to the list of current clients and returns the + bool handleIncomingClientData(const std::string& pgp_public_key_b64, const std::string& short_invite_b64, RsPeerId &pid); + + // Computes the appropriate list of short invites to send to a given peer. + std::map computeListOfFriendInvites(const RsPeerId &pid, uint32_t nb_reqs_invites, + const std::map& already_known_peers, + std::set& chosen_peers) const; + + // Compute the distance between peers using the random bias (It's not really a distance though. I'm not sure about the triangular inequality). + PeerInfo::PeerDistance computePeerDistance(const RsPgpFingerprint &p1, const RsPgpFingerprint &p2); + + void autoWash(); + void debugPrint(bool force); + Sha1CheckSum computeDataHash(); + + // Local members + + FsNetworkInterface *mni; + PGPHandler *mPgpHandler; + + std::string mBaseDirectory; + RsPgpFingerprint mRandomPeerBias; + + std::map mCurrentClientPeers; + std::string mListeningAddress; + uint16_t mListeningPort; + + Sha1CheckSum mCurrentDataHash; +}; diff --git a/retroshare-friendserver/src/network.cc b/retroshare-friendserver/src/network.cc new file mode 100644 index 000000000..f28a38de0 --- /dev/null +++ b/retroshare-friendserver/src/network.cc @@ -0,0 +1,324 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef WINDOWS_SYS +#include +#include +#include +#else +#include +#endif + +#include "util/rsnet.h" +#include "util/rsprint.h" +#include "util/rsdebug.h" + +#include "pqi/pqithreadstreamer.h" +#include "pqi/pqifdbin.h" + +#include "network.h" +#include "friend_server/fsitem.h" + +FsNetworkInterface::FsNetworkInterface(const std::string& listening_address,uint16_t listening_port) + : PQInterface(RsPeerId()),mFsNiMtx(std::string("FsNetworkInterface")),mListeningAddress(listening_address),mListeningPort(listening_port) +{ + RS_STACK_MUTEX(mFsNiMtx); + + mClintListn = 0; + mClintListn = socket(AF_INET, SOCK_STREAM, 0); // creating socket + + int flags=1; + setsockopt(mClintListn,SOL_SOCKET,TCP_NODELAY,(char*)&flags,sizeof(flags)); + + unix_fcntl_nonblock(mClintListn); + + struct sockaddr_in ipOfServer; + memset(&ipOfServer, '0', sizeof(ipOfServer)); + + assert(mListeningPort > 1024); + + ipOfServer.sin_family = AF_INET; + ipOfServer.sin_port = htons(mListeningPort); // this is the port number of running server + + int addr[4]; + if(sscanf(listening_address.c_str(),"%d.%d.%d.%d",&addr[0],&addr[1],&addr[2],&addr[3]) != 4) + throw std::runtime_error("Cannot parse a proper IPv4 address in \""+listening_address+"\""); + + for(int i=0;i<4;++i) + if(addr[i] < 0 || addr[i] > 255) + throw std::runtime_error("Cannot parse a proper IPv4 address in \""+listening_address+"\""); + + ipOfServer.sin_addr.s_addr = htonl( (addr[0] << 24) + (addr[1] << 16) + (addr[2] << 8) + addr[3] ); + + if(bind(mClintListn, (struct sockaddr*)&ipOfServer , sizeof(ipOfServer)) < 0) + { + RsErr() << "Error while binding: errno=" << errno ; + return; + } + + if(listen(mClintListn , 40) < 0) + { + RsErr() << "Error while calling listen: errno=" << errno ; + return; + } + + RsDbg() << "Network interface now listening for TCP on " << sockaddr_storage_tostring( *(sockaddr_storage*)&ipOfServer) ; +} + +FsNetworkInterface::~FsNetworkInterface() +{ + RS_STACK_MUTEX(mFsNiMtx); + for(auto& it:mConnections) + { + delete it.second.pqi_thread; + std::cerr << "Releasing socket " << it.second.socket << std::endl; + close(it.second.socket); + } + std::cerr << "Releasing listening socket " << mClintListn << std::endl; + close(mClintListn); +} +void FsNetworkInterface::threadTick() +{ + // 1 - check for new connections + + checkForNewConnections(); + + // 2 - tick all streamers + + std::list to_close; + + { + RS_STACK_MUTEX(mFsNiMtx); + for(auto& it:mConnections) + { + it.second.pqi_thread->tick(); + + if(!it.second.bio->isactive() && !it.second.bio->moretoread(0)) + to_close.push_back(it.first); + } + + for(const auto& pid:to_close) + locked_closeConnection(pid); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(200)); +} + +static RsPeerId makePeerId(int t) +{ + unsigned char s[RsPeerId::SIZE_IN_BYTES]; + memset(s,0,sizeof(s)); + + *reinterpret_cast(&s) = t; + return RsPeerId::fromBufferUnsafe(s); +} +bool FsNetworkInterface::checkForNewConnections() +{ + // look for incoming data + + struct sockaddr addr; + socklen_t addr_len = sizeof(sockaddr); + + int clintConnt = accept(mClintListn, &addr, &addr_len); // accept is a blocking call! + + if(clintConnt < 0) + { + int err = rs_socket_error(); + + if(err == EWOULDBLOCK || err == EAGAIN) + ;//RsErr()<< "Incoming connection with nothing to read!" << std::endl; + else + RsErr()<< "Error when accepting connection." << std::endl; + + return false; + } + RsDbg() << "Got incoming connection from " << sockaddr_storage_tostring( *(sockaddr_storage*)&addr); + + // Make the socket non blocking so that we can read from it and return if nothing comes + + int flags=1; + setsockopt(clintConnt,SOL_SOCKET,TCP_NODELAY,(char*)&flags,sizeof(flags)); + + unix_fcntl_nonblock(clintConnt); + + // Create connection info + + RsDbg() << " Creating connection data." ; + + ConnectionData c; + c.socket = clintConnt; + c.client_address = addr; + RsPeerId pid = makePeerId(clintConnt); + + RsDbg() << " socket: " << clintConnt; + RsDbg() << " client address: " << sockaddr_storage_tostring(*(sockaddr_storage*)&addr); + RsDbg() << " peer id: " << pid ; + + // Setup a pqistreamer to deserialize whatever comes from this connection + + RsSerialiser *rss = new RsSerialiser ; + rss->addSerialType(new FsSerializer) ; + + RsFdBinInterface *bio = new RsFdBinInterface(clintConnt,true); + + auto pqi = new pqithreadstreamer(this,rss, pid, bio,BIN_FLAGS_READABLE | BIN_FLAGS_WRITEABLE); + + c.pqi_thread = pqi; + c.bio = bio; + + { + RS_STACK_MUTEX(mFsNiMtx); + mConnections[pid] = c; + + pqi->start(); + } + + RsDbg() << " streamer has properly started." ; + return true; +} + +bool FsNetworkInterface::RecvItem(RsItem *item) +{ + RS_STACK_MUTEX(mFsNiMtx); + + RsDbg() << "FsNetworkInterface: received item " << (void*)item; + + auto it = mConnections.find(item->PeerId()); + + if(it == mConnections.end()) + { + RsErr() << "Receiving an item for peer ID " << item->PeerId() << " but no connection is known for that peer." << std::endl; + delete item; + return false; + } + + it->second.incoming_items.push_back(item); + return true; +} + +RsItem *FsNetworkInterface::GetItem() +{ + RS_STACK_MUTEX(mFsNiMtx); + + for(auto& it:mConnections) + { + if(!it.second.incoming_items.empty()) + { + RsItem *item = it.second.incoming_items.front(); + it.second.incoming_items.pop_front(); + + RsDbg() << "FsNetworkInterface: returning item " << (void*)item << " to caller."; + return item; + } + } + return nullptr; +} + +int FsNetworkInterface::SendItem(RsItem *item) +{ + RS_STACK_MUTEX(mFsNiMtx); + + const auto& it = mConnections.find(item->PeerId()); + + if(it == mConnections.end()) + { + RsErr() << "Cannot send item to peer " << item->PeerId() << ": no pending sockets available." ; + delete item; + return 0; + } + + uint32_t ss; + return it->second.pqi_thread->SendItem(item,ss); +} + +void FsNetworkInterface::closeConnection(const RsPeerId& peer_id) +{ + RS_STACK_MUTEX(mFsNiMtx); + + locked_closeConnection(peer_id); +} +void FsNetworkInterface::locked_closeConnection(const RsPeerId& peer_id) +{ + RsDbg() << "Closing connection to virtual peer " << peer_id ; + + const auto& it = mConnections.find(peer_id); + + if(it == mConnections.end()) + { + RsErr() << " Cannot close connection to peer " << peer_id << ": no pending sockets available." ; + return; + } + + if(!it->second.incoming_items.empty()) + { + RsErr() << " Trying to close an incoming connection with incoming items still pending! The items will be lost:" << std::endl; + + for(auto& item:it->second.incoming_items) + { + RsErr() << *item; + delete item; + } + + it->second.incoming_items.clear(); + } + // Close the socket and delete everything. + + close(it->second.socket); + it->second.pqi_thread->fullstop(); + it->second.bio->close(); + + delete it->second.pqi_thread; + + mConnections.erase(it); +} + +void FsNetworkInterface::debugPrint() +{ + RsDbg() << " " << mClintListn ; // listening socket + RsDbg() << " Connections: " << mConnections.size() ; + + for(auto& it:mConnections) + RsDbg() << " " << it.first << ": from \"" << sockaddr_storage_tostring(*(sockaddr_storage*)(&it.second.client_address)) << "\", socket=" << it.second.socket ; + + std::map mConnections; +} + + + + + + + + + + + + + + diff --git a/retroshare-friendserver/src/network.h b/retroshare-friendserver/src/network.h new file mode 100644 index 000000000..fcec0648b --- /dev/null +++ b/retroshare-friendserver/src/network.h @@ -0,0 +1,86 @@ +/* + * RetroShare Friend Server + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#pragma once + +#include "util/rsthreads.h" +#include "pqi/pqi_base.h" +#include "retroshare/rspeers.h" + +class pqithreadstreamer; +class RsFdBinInterface; + +struct ConnectionData +{ + sockaddr client_address; + int socket; + pqithreadstreamer *pqi_thread; + RsFdBinInterface *bio; + + std::list incoming_items; +}; + +// This class handles multiple connections to the server and supplies RsItem elements + +class FsNetworkInterface: public RsTickingThread, public PQInterface +{ +public: + FsNetworkInterface(const std::string& listening_address,uint16_t listening_port) ; + virtual ~FsNetworkInterface() ; + + // basic functionality + + void debugPrint(); + + // Implements PQInterface + + bool RecvItem(RsItem *item) override; + int SendItem(RsItem *item) override; + RsItem *GetItem() override; + + void closeConnection(const RsPeerId& peer_id); + + // Implements RsTickingThread + + void threadTick() override; + +protected: + bool checkForNewConnections(); + void locked_closeConnection(const RsPeerId& peer_id); + +private: + RsMutex mFsNiMtx; + + void initListening(); + void stopListening(); + + int mClintListn ; // listening socket + std::map mConnections; + + std::string mListeningAddress; + uint16_t mListeningPort; +}; + + + + + + diff --git a/retroshare-friendserver/src/retroshare-friendserver.cc b/retroshare-friendserver/src/retroshare-friendserver.cc new file mode 100644 index 000000000..fabe3889d --- /dev/null +++ b/retroshare-friendserver/src/retroshare-friendserver.cc @@ -0,0 +1,140 @@ +/* + * RetroShare Service + * Copyright (C) 2021-2021 retroshare team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "util/stacktrace.h" +#include "util/rsdir.h" +#include "util/argstream.h" +#include "util/rstime.h" +#include "util/rsdebug.h" + +#include "retroshare/rstor.h" +#include "retroshare/rsinit.h" +#include "pqi/authgpg.h" + +#include "friendserver.h" + +// debug +#include "friend_server/fsitem.h" +#include "friend_server/fsclient.h" + +int main(int argc, char* argv[]) +{ + RsInfo() << "\n" << + "+================================================================+\n" + "| o---o o |\n" + "| \\ / - Retroshare Friend Server - / \\ |\n" + "| o o---o |\n" + "+================================================================+" + << std::endl << std::endl; + + //RsControl::earlyInitNotificationSystem(); + + std::string base_directory = "FSData"; + std::string tor_executable_path ; + bool verbose = false; + + argstream as(argc,argv); + + as >> parameter( 'c',"base-dir", base_directory, "set base directory to store data files (keys, etc)", false ) + >> parameter( 't',"tor-executable", tor_executable_path, "set absolute path for tor executable", false ) + >> option( 'v',"verbose", verbose, "display additional debug information") + >> help( 'h', "help", "Display this Help" ); + + as.defaultErrorHandling(true, true); + + RsConfigOptions conf; + conf.optBaseDir = base_directory; + conf.main_executable_path = argv[0]; + + if(!tor_executable_path.empty()) + RsTor::setTorExecutablePath(tor_executable_path); + + RsTor::setVerbose(verbose); + + RsInit::InitRsConfig(); + RsInit::InitRetroShare(conf); + + AuthPGP::exit(); // This allows to release the keyring created by libretroshare, since it's not useful, as TorManager has its own. + + // Create the base directory if needed + + if(!RsDirUtil::checkCreateDirectory(base_directory)) + { + RsErr() << "Cannot create base directory \"" << base_directory << "\". Check permissions, paths, etc." ; + return 1; + } + + // Check the existance of the Tor executable path + + auto tor_path = RsTor::torExecutablePath(); + + if (!RsDirUtil::fileExists(tor_path)) + { + RsErr() << "Tor executable \"" << tor_path << "\" not found. Try supplying the correct full path for a tor executable with the -t option."; + return 1; + } + else + RsDbg() << "Using Tor executable: \"" << tor_path << "\""; + + // Create/start TorManager + + RsTor::setTorDataDirectory(RsDirUtil::makePath(base_directory,"tor")); + RsTor::setHiddenServiceDirectory(RsDirUtil::makePath(base_directory,"hidden_service")); + + if(! RsTor::start() || RsTor::hasError()) + { + RsErr() << "Tor cannot be started on your system: " << RsTor::errorMessage() ; + return 1 ; + } + + std::string service_id; + + while(RsTor::torStatus() != RsTorStatus::READY || RsTor::getHiddenServiceStatus(service_id) != RsTorHiddenServiceStatus::ONLINE) + std::this_thread::sleep_for(std::chrono::seconds(1)); + + std::string onion_address,service_target_address; + uint16_t service_port,target_port; + + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,target_port) ; + + RsInfo() << "Tor properly started: " ; + RsInfo() << " Hidden service address: " << onion_address << ":" << service_port; + RsInfo() << " Target address : " << service_target_address << ":" << target_port; + + // Now start the real thing. + + FriendServer fs(base_directory,service_target_address,target_port); + fs.start(); + + RsInfo() << ""; + RsInfo() << "================== Retroshare Friend Server has properly started =====================" ; + RsInfo() << "= ="; + RsInfo() << "= Address:Port " << onion_address << ":" << service_port << ((service_port<10000)?" ":"") << " ="; + RsInfo() << "= ="; + RsInfo() << "======================================================================================" ; + RsInfo() << ""; + + while(fs.isRunning()) + std::this_thread::sleep_for(std::chrono::seconds(2)); + + return 0; +} + diff --git a/retroshare-friendserver/src/retroshare-friendserver.pro b/retroshare-friendserver/src/retroshare-friendserver.pro new file mode 100644 index 000000000..eda1f35cb --- /dev/null +++ b/retroshare-friendserver/src/retroshare-friendserver.pro @@ -0,0 +1,50 @@ +# RetroShare service qmake build script +# +# Copyright (C) 2021-2021, retroshare team +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see . +# +# SPDX-FileCopyrightText: Retroshare Team +# SPDX-License-Identifier: AGPL-3.0-or-later + +!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") + +TARGET = retroshare-friendserver + +!include("../../libretroshare/src/use_libretroshare.pri"):error("Including") + +SOURCES += retroshare-friendserver.cc \ + friendserver.cc \ + network.cc + +HEADERS += friendserver.h \ + network.h + +################################# Linux ########################################## + +unix { + target.path = "$${RS_BIN_DIR}" + INSTALLS += target +} + +################################# Windows ########################################## + +win32-g++|win32-clang-g++ { + dLib = ws2_32 iphlpapi crypt32 + LIBS *= $$linkDynamicLibs(dLib) + CONFIG += console +} + +################################### COMMON stuff ################################## + diff --git a/retroshare-gui/CMakeLists.txt b/retroshare-gui/CMakeLists.txt new file mode 100644 index 000000000..314edf1ab --- /dev/null +++ b/retroshare-gui/CMakeLists.txt @@ -0,0 +1,492 @@ +################################################################################ +# retroshare-gui/CMakeLists.txt # +# Copyright (C) 2022, Retroshare team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see . # +################################################################################ + +cmake_minimum_required (VERSION 3.18.0) +project(retroshare-gui VERSION 0.6.6 LANGUAGES CXX) + +include(CMakeDependentOption) + +set( + RS_BIN_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/bin" + CACHE PATH + "Path where to install retroshare-service compiled binary" ) + +option( + RS_DEVELOPMENT_BUILD + "Disable optimization to speed up build, enable verbose build log. \ + just for development purposes, not suitable for library usage" + ON ) + +option( + RS_JSON_API + "Use restbed to expose libretroshare as JSON API via HTTP" + OFF ) + +option( + RS_SERVICE_DESKTOP + "Install icons and shortcuts for desktop environements" + OFF ) + +option( + RS_SERVICE_TERMINAL_LOGIN + "Enable RetroShare login via terminal" + ON ) + +option( RS_GXSGUI "Enable GXS services in GUI" ON ) +option( RS_GXSCHANNELS "Enable GXS channels in GUI" ON ) +option( RS_GXSFORUMS "Enable GXS forums in GUI" ON ) +option( RS_GXSPOSTED "Enable GXS posted in GUI" ON ) +option( RS_GXSCIRCLES "Enable GXS circles in GUI" ON ) + +cmake_dependent_option( + RS_SERVICE_TERMINAL_WEBUI_PASSWORD + "Enable settin Web UI password via terminal in retroshare-service" + OFF + "RS_WEBUI" + ON ) + +cmake_dependent_option( + RS_WEBUI + "Install RetroShare Web UI" + OFF + "RS_JSON_API" + ON ) + +################################ QT FILES ####################################### + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) + +find_package( Qt5 COMPONENTS Core REQUIRED) +find_package( Qt5 COMPONENTS Widgets REQUIRED) +find_package( Qt5 COMPONENTS Xml REQUIRED) +find_package( Qt5 COMPONENTS Network REQUIRED) +find_package( Qt5 COMPONENTS Multimedia REQUIRED) +find_package( Qt5 COMPONENTS PrintSupport REQUIRED) + +list( APPEND RS_LINK_LIBRARIES Qt5::Multimedia Qt5::Widgets Qt5::Xml Qt5::Network Qt5::PrintSupport) + +################################################################################ + +set(FETCHCONTENT_QUIET OFF) +include(FetchContent) + +find_package(Git REQUIRED) + +################################################################################ + +if(RS_DEVELOPMENT_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +endif(RS_DEVELOPMENT_BUILD) + +################################################################################ + +include(src/CMakeLists.txt) + +qt5_wrap_ui(RS_UI_HEADERS ${RS_GUI_FORMS}) + +add_executable(${PROJECT_NAME} ${RS_GUI_SOURCES} ${RS_UI_HEADERS} ${RS_GUI_QTRESOURCES}) +install(TARGETS ${PROJECT_NAME} DESTINATION ${RS_BIN_INSTALL_DIR}) + +include_directories( ${CMAKE_BINARY_DIR} ) + +################################################################################ + +if(RS_DEVELOPMENT_BUILD) + target_compile_options(${PROJECT_NAME} PRIVATE "-O0") +endif(RS_DEVELOPMENT_BUILD) + +################################################################################ + +set(LIBRETROSHARE_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../libretroshare/") +if(EXISTS "${LIBRETROSHARE_DEVEL_DIR}/.git" ) + message( + STATUS + "libretroshare submodule found at ${LIBRETROSHARE_DEVEL_DIR} using it" ) + add_subdirectory( + "${LIBRETROSHARE_DEVEL_DIR}" "${CMAKE_BINARY_DIR}/libretroshare" ) +else() + FetchContent_Declare( + libretroshare + GIT_REPOSITORY "https://gitlab.com/RetroShare/libretroshare.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(libretroshare) +endif() + +target_include_directories(${PROJECT_NAME} PRIVATE ${LIBRETROSHARE_DEVEL_DIR}/src/) + +################################################################################ + +if(RS_SERVICE_DESKTOP) + if(UNIX AND NOT APPLE) + install( + FILES data/retroshare.svg + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/ ) + + install( + FILES data/retroshare.xpm + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps/ ) + + install( + FILES data/24x24/apps/retroshare.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/24x24/apps/retroshare.png ) + + install( + FILES data/48x48/apps/retroshare.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/retroshare.png ) + + install( + FILES data/64x64/apps/retroshare.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps/retroshare.png ) + + install( + FILES data/128x128/apps/retroshare.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps/retroshare.png ) + + install( + FILES data/retroshare.desktop + DESTINATION ${CMAKE_INSTALL_PREFIX}/data/retroshare.desktop ) + + install( + FILES gui/qss/chat/Bubble gui/qss/chat/Bubble_Compact + DESTINATION ${CMAKE_INSTALL_PREFIX}/data/stylesheets/ ) + + install( + FILES src/sounds/ src/qss/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/ ) + endif(UNIX AND NOT APPLE) +endif(RS_SERVICE_DESKTOP) + +################################################################################ + +if(RS_JSON_API) + target_compile_definitions(${PROJECT_NAME} PUBLIC RS_JSONAPI) +endif(RS_JSON_API) + +################################# CMark ######################################## + +if(RS_GUI_CMARK) + set(CMARK_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../supportlibs/cmark/") + if(EXISTS "${LIBRETROSHARE_DEVEL_DIR}/.git" ) + message( STATUS "cmark submodule found at ${LIBRETROSHARE_DEVEL_DIR} using it" ) + add_subdirectory( "${LIBRETROSHARE_DEVEL_DIR}" "${CMAKE_BINARY_DIR}/cmark" ) + else() + FetchContent_Declare( + cmark + GIT_REPOSITORY "https://github.com/commonmark/cmark.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(cmark) + endif() +endif(RS_GUI_CMARK) + +################################# LibSam v3 #################################### + +set(SAM3_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../supportlibs/libsam3/") +if(EXISTS "${SAM3_DEVEL_DIR}/.git" ) + message( STATUS "libsam3 submodule found at ${SAM3_DEVEL_DIR} using it" ) + add_subdirectory( "${SAM3_DEVEL_DIR}" "${CMAKE_BINARY_DIR}/libsam3" ) +else() + FetchContent_Declare( + libsam3 + GIT_REPOSITORY "https://github.com/i2p/libsam3.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(libsam3) +endif() + +################################################################################ +# TODO # +################################################################################ + +# # Auto detect installed version of cmark +# rs_gui_cmark { +# DEFINES *= USE_CMARK +# no_rs_cross_compiling { +# message("Using compiled cmark") +# CMARK_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/cmark) +# CMARK_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/cmark/build) +# INCLUDEPATH *= $$clean_path($${CMARK_SRC_PATH}/src/) +# DEPENDPATH *= $$clean_path($${CMARK_SRC_PATH}/src/) +# QMAKE_LIBDIR *= $$clean_path($${CMARK_BUILD_PATH}/) +# # Using sLibs would fail as libcmark.a is generated at compile-time +# LIBS *= -L$$clean_path($${CMARK_BUILD_PATH}/src/) -lcmark +# +# DUMMYCMARKINPUT = FORCE +# CMAKE_GENERATOR_OVERRIDE="" +# win32-g++|win32-clang-g++:CMAKE_GENERATOR_OVERRIDE="-G \"MSYS Makefiles\"" +# gencmarklib.name = Generating libcmark. +# gencmarklib.input = DUMMYCMARKINPUT +# gencmarklib.output = $$clean_path($${CMARK_BUILD_PATH}/src/libcmark.a) +# gencmarklib.CONFIG += target_predeps combine +# gencmarklib.variable_out = PRE_TARGETDEPS +# gencmarklib.commands = \ +# cd $${RS_SRC_PATH} && ( \ +# git submodule update --init supportlibs/cmark ; \ +# cd $${CMARK_SRC_PATH} ; \ +# true ) && \ +# mkdir -p $${CMARK_BUILD_PATH} && cd $${CMARK_BUILD_PATH} && \ +# cmake \ +# -DCMAKE_CXX_COMPILER=$$QMAKE_CXX \ +# \"-DCMAKE_CXX_FLAGS=$${QMAKE_CXXFLAGS}\" \ +# $${CMAKE_GENERATOR_OVERRIDE} \ +# -DCMAKE_INSTALL_PREFIX=. \ +# -B. \ +# -H$$shell_path($${CMARK_SRC_PATH}) && \ +# $(MAKE) +# QMAKE_EXTRA_COMPILERS += gencmarklib +# } else { +# message("Using systems cmark") +# sLibs *= libcmark +# } +# } + +################################# Linux ########################################## +# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib + +if(UNIX) + find_package(PkgConfig REQUIRED) + + pkg_check_modules(X11 REQUIRED x11) + pkg_check_modules(XSCRNSAVER REQUIRED xscrnsaver) + + list( APPEND RS_LINK_LIBRARIES ${X11_LIBRARIES} ) + list( APPEND RS_LINK_LIBRARIES ${XSCRNSAVER_LIBRARIES} ) + + target_include_directories(${PROJECT_NAME} PRIVATE ${X11_INCLUDE_DIRS}) + target_compile_options(${PROJECT_NAME} PRIVATE ${X11_CFLAGS_OTHER}) + + target_include_directories(retroshare-gui PRIVATE ${XSCRNSAVER_INCLUDE_DIRS}) + target_compile_options(retroshare-gui PRIVATE ${XSCRNSAVER_CFLAGS_OTHER}) + + target_compile_definitions(${PROJECT_NAME} PRIVATE HAVE_XSS) + target_compile_definitions(${PROJECT_NAME} PRIVATE _FILE_OFFSET_BITS=64) + target_link_options(${PROJECT_NAME} PRIVATE LINKER:-rdynamic) +endif(UNIX) + +if(RS_SANITIZE) + list( APPEND RS_LINK_LIBRARIES asan ) + list( APPEND RS_LINK_LIBRARIES ubsan ) +endif(RS_SANITIZE) + +# #################### Cross compilation for windows under Linux ################### +# +# win32-x-g++ { +# OBJECTS_DIR = temp/win32-x-g++/obj +# +# 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 +# LIBS += ../../../../lib/win32-x-g++-v0.5/libminiupnpc.a +# LIBS += ../../../../lib/win32-x-g++-v0.5/libz.a +# LIBS += -L${HOME}/.wine/drive_c/pthreads/lib -lpthreadGCE2 +# LIBS += -lQtUiTools +# LIBS += -lws2_32 -luuid -lole32 -liphlpapi -lcrypt32 -gdi32 +# LIBS += -lole32 -lwinmm +# +# DEFINES *= WINDOWS_SYS WIN32 WIN32_CROSS_UBUNTU +# +# INCLUDEPATH += ../../../../gpgme-1.1.8/src/ +# INCLUDEPATH += ../../../../libgpg-error-1.7/src/ +# +# RC_FILE = gui/images/retroshare_win.rc +# } +# +# #################################### Windows ##################################### +# +# win32-g++|win32-clang-g++ { +# CONFIG(debug, debug|release) { +# # show console output +# CONFIG += console +# } else { +# CONFIG -= console +# } +# +# CONFIG(debug, debug|release) { +# } else { +# # Tell linker to use ASLR protection +# QMAKE_LFLAGS += -Wl,-dynamicbase +# # Tell linker to use DEP protection +# QMAKE_LFLAGS += -Wl,-nxcompat +# } +# +# # Fix linking error (ld.exe: Error: export ordinal too large) due to too +# # many exported symbols. +# !libretroshare_shared:QMAKE_LFLAGS+=-Wl,--exclude-libs,ALL +# +# # 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 +# +# OBJECTS_DIR = temp/obj +# +# dLib = ws2_32 gdi32 uuid ole32 iphlpapi crypt32 winmm +# LIBS *= $$linkDynamicLibs(dLib) +# +# RC_FILE = gui/images/retroshare_win.rc +# +# # export symbols for the plugins +# LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a +# +# # create lib directory +# isEmpty(QMAKE_SH) { +# QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib +# } else { +# QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib || $(MKDIR) lib +# } +# +# greaterThan(QT_MAJOR_VERSION, 4) { +# # Qt 5 +# RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src +# } else { +# # Qt 4 +# QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src +# } +# } +# +# ##################################### MacOS ###################################### +# +# macx { +# # ENABLE THIS OPTION FOR Univeral Binary BUILD. +# #CONFIG += ppc x86 +# #QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 +# QMAKE_INFO_PLIST = Info.plist +# mac_icon.files = $$files($$PWD/rsMacIcon.icns) +# mac_icon.path = Contents/Resources +# QMAKE_BUNDLE_DATA += mac_icon +# dplQSS.files = $$PWD/qss +# dplQSS.path = Contents/Resources +# QMAKE_BUNDLE_DATA += dplQSS +# dplChatStyles.files = \ +# $$PWD/gui/qss/chat/Bubble \ +# $$PWD/gui/qss/chat/Bubble_Compact +# dplChatStyles.path = Contents/Resources/stylesheets +# QMAKE_BUNDLE_DATA += dplChatStyles +# # mac_webui.files = $$files($$PWD/../../libresapi/src/webui) +# # mac_webui.path = Contents/Resources +# # QMAKE_BUNDLE_DATA += mac_webui +# +# OBJECTS_DIR = temp/obj +# +# CONFIG += version_detail_bash_script +# LIBS += -lssl -lcrypto -lz +# for(lib, LIB_DIR):exists($$lib/libminiupnpc.a){ LIBS += $$lib/libminiupnpc.a} +# LIBS += -framework CoreFoundation +# LIBS += -framework Security +# LIBS += -framework Carbon +# +# for(lib, LIB_DIR):LIBS += -L"$$lib" +# for(bin, BIN_DIR):LIBS += -L"$$bin" +# +# DEPENDPATH += . $$INC_DIR +# INCLUDEPATH += . $$INC_DIR +# +# #DEFINES *= MAC_IDLE # for idle feature +# CONFIG -= uitools +# } +# +# ##################################### FreeBSD ###################################### +# +# freebsd-* { +# INCLUDEPATH *= /usr/local/include/gpgme +# 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 +# } +# +# ##################################### OpenBSD ###################################### +# +# openbsd-* { +# INCLUDEPATH *= /usr/local/include +# +# LIBS *= -lssl -lcrypto +# LIBS *= -lgpgme +# LIBS *= -lupnp +# LIBS *= -lgnome-keyring +# LIBS += -lsqlite3 +# LIBS *= -rdynamic +# } +# +# ################################### COMMON stuff ################################## +# +# wikipoos { +# PRE_TARGETDEPS *= $$OUT_PWD/../../supportlibs/pegmarkdown/lib/libpegmarkdown.a +# LIBS *= $$OUT_PWD/../../supportlibs/pegmarkdown/lib/libpegmarkdown.a +# LIBS *= -lglib-2.0 +# } + +################################ GENERAL ####################################### + +target_link_libraries(${PROJECT_NAME} PRIVATE ${RS_LINK_LIBRARIES}) + +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/) + +set( CMAKE_CXX_FLAGS "-Wno-deprecated-declarations" ) +target_compile_definitions(${PROJECT_NAME} PUBLIC RS_NO_WARN_DEPRECATED ) +target_compile_definitions(${PROJECT_NAME} PRIVATE RS_RELEASE_VERSION ) +target_compile_definitions(${PROJECT_NAME} PRIVATE TARGET=\"retroshare\") + +if(RS_GXS_CIRCLES) + target_compile_definitions(${PROJECT_NAME} PRIVATE RS_USE_CIRCLES ) +endif(RS_GXS_CIRCLES) + +#add_dependencies(${PROJECT_NAME} libretroshare) + diff --git a/retroshare-gui/src/CMakeLists.txt b/retroshare-gui/src/CMakeLists.txt new file mode 100644 index 000000000..b936552ed --- /dev/null +++ b/retroshare-gui/src/CMakeLists.txt @@ -0,0 +1,1279 @@ +################################################################################ +# uselibresapi.pri # +# Copyright (C) 2018, Retroshare team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU Affero General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU Affero General Public License for more details. # +# # +# You should have received a copy of the GNU Affero General Public License # +# along with this program. If not, see . # +################################################################################ + +list( + APPEND RS_GUI_SOURCES + src/TorControl/TorControlWindow.cpp + + src/main.cpp + src/rshare.cpp + + src/gui/notifyqt.cpp + src/gui/AboutDialog.cpp + src/gui/AboutWidget.cpp + src/gui/QuickStartWizard.cpp + src/gui/StartDialog.cpp + src/gui/HomePage.cpp + src/gui/ChatLobbyWidget.cpp + src/gui/GetStartedDialog.cpp + src/gui/GenCertDialog.cpp + src/gui/NetworkDialog.cpp + src/gui/mainpagestack.cpp + src/gui/MainWindow.cpp + src/gui/NetworkView.cpp + src/gui/FriendsDialog.cpp + src/gui/ServicePermissionDialog.cpp + src/gui/RemoteDirModel.cpp + src/gui/RsAutoUpdatePage.cpp + src/gui/RetroShareLink.cpp + src/gui/SearchTreeWidget.cpp + src/gui/ShareManager.cpp + # src/gui/ShareDialog.cpp + src/gui/NewsFeed.cpp + src/gui/MainPage.cpp + src/gui/HelpDialog.cpp + src/gui/LogoBar.cpp + src/gui/SoundManager.cpp + + src/gui/im_history/ImHistoryBrowser.cpp + src/gui/im_history/IMHistoryItemDelegate.cpp + src/gui/im_history/IMHistoryItemPainter.cpp + + src/gui/help/browser/helpbrowser.cpp + src/gui/help/browser/helptextbrowser.cpp + + src/gui/FileTransfer/SearchDialog.cpp + src/gui/FileTransfer/SharedFilesDialog.cpp + src/gui/FileTransfer/TransfersDialog.cpp + src/gui/FileTransfer/FileTransferInfoWidget.cpp + src/gui/FileTransfer/DLListDelegate.cpp + src/gui/FileTransfer/ULListDelegate.cpp + src/gui/FileTransfer/xprogressbar.cpp + src/gui/FileTransfer/DetailsDialog.cpp + src/gui/FileTransfer/TransferUserNotify.cpp + src/gui/FileTransfer/BannedFilesDialog.cpp + + src/lang/languagesupport.cpp + + src/util/RsProtectedTimer.cpp + src/util/stringutil.cpp + src/util/RsNetUtil.cpp + src/util/DateTime.cpp + src/util/RetroStyleLabel.cpp + src/util/WidgetBackgroundImage.cpp + src/util/PixmapMerging.cpp + src/util/MouseEventFilter.cpp + src/util/EventFilter.cpp + src/util/Widget.cpp + src/util/RsAction.cpp + src/util/printpreview.cpp + src/util/log.cpp + src/util/misc.cpp + src/util/HandleRichText.cpp + src/util/ObjectPainter.cpp + src/util/RsFile.cpp + src/util/RichTextEdit.cpp + src/util/ClickableLabel.cpp + src/util/AspectRatioPixmapLabel.cpp + + src/gui/profile/ProfileWidget.cpp + src/gui/profile/StatusMessage.cpp + src/gui/profile/ProfileManager.cpp + + src/gui/chat/PopupChatWindow.cpp + src/gui/chat/PopupChatDialog.cpp + src/gui/chat/PopupDistantChatDialog.cpp + src/gui/chat/ChatTabWidget.cpp + src/gui/chat/ChatWidget.cpp + src/gui/chat/ChatDialog.cpp + src/gui/chat/ChatLobbyDialog.cpp + src/gui/chat/CreateLobbyDialog.cpp + src/gui/chat/ChatStyle.cpp + src/gui/chat/ChatUserNotify.cpp + src/gui/chat/ChatLobbyUserNotify.cpp + + src/gui/connect/ConfCertDialog.cpp + src/gui/connect/PGPKeyDialog.cpp + src/gui/connect/ConnectFriendWizard.cpp + src/gui/connect/ConnectProgressDialog.cpp + src/gui/connect/FriendRecommendDialog.cpp + + src/gui/msgs/MessagesDialog.cpp + src/gui/msgs/MessageComposer.cpp + src/gui/msgs/MessageWidget.cpp + src/gui/msgs/MessageWindow.cpp + src/gui/msgs/MessageModel.cpp + src/gui/msgs/TagsMenu.cpp + src/gui/msgs/MessageUserNotify.cpp + + src/gui/common/RsButtonOnText.cpp + src/gui/common/RSGraphWidget.cpp + src/gui/common/ElidedLabel.cpp + src/gui/common/vmessagebox.cpp + src/gui/common/RsCollectionDialog.cpp + src/gui/common/RsCollection.cpp + src/gui/common/RsUrlHandler.cpp + src/gui/common/rwindow.cpp + src/gui/common/rshtml.cpp + src/gui/common/AvatarDefs.cpp + src/gui/common/AvatarDialog.cpp + src/gui/common/GroupFlagsWidget.cpp + src/gui/common/GroupSelectionBox.cpp + src/gui/common/GroupChooser.cpp + src/gui/common/StatusDefs.cpp + src/gui/common/TagDefs.cpp + src/gui/common/GroupDefs.cpp + src/gui/common/Emoticons.cpp + src/gui/common/RSComboBox.cpp + src/gui/common/RSListWidgetItem.cpp + src/gui/common/RSTextEdit.cpp + src/gui/common/RSPlainTextEdit.cpp + src/gui/common/RSTreeWidget.cpp + src/gui/common/RSTreeWidgetItem.cpp + src/gui/common/RSFeedWidget.cpp + src/gui/common/RSTabWidget.cpp + src/gui/common/RSElidedItemDelegate.cpp + src/gui/common/RSItemDelegate.cpp + src/gui/common/PeerDefs.cpp + src/gui/common/FilesDefs.cpp + src/gui/common/PopularityDefs.cpp + src/gui/common/RsBanListDefs.cpp + src/gui/common/GroupTreeWidget.cpp + src/gui/common/RSTreeView.cpp + src/gui/common/AvatarWidget.cpp + src/gui/common/FriendListModel.cpp + src/gui/common/NewFriendList.cpp + src/gui/common/FriendSelectionWidget.cpp + src/gui/common/FriendSelectionDialog.cpp + src/gui/common/HashBox.cpp + src/gui/common/LineEditClear.cpp + src/gui/common/DropLineEdit.cpp + src/gui/common/RSTextBrowser.cpp + src/gui/common/RSImageBlockWidget.cpp + src/gui/common/FeedNotify.cpp + src/gui/common/UserNotify.cpp + src/gui/common/HeaderFrame.cpp + src/gui/common/MimeTextEdit.cpp + src/gui/common/UIStateHelper.cpp + src/gui/common/FloatingHelpBrowser.cpp + src/gui/common/SubscribeToolButton.cpp + src/gui/common/RsBanListToolButton.cpp + src/gui/common/FlowLayout.cpp + src/gui/common/PictureFlow.cpp + src/gui/common/ToasterNotify.cpp + + src/gui/style/RSStyle.cpp + src/gui/style/StyleDialog.cpp + + src/gui/settings/RSPermissionMatrixWidget.cpp + src/gui/settings/rsharesettings.cpp + src/gui/settings/RsharePeerSettings.cpp + src/gui/settings/rsettings.cpp + src/gui/settings/rsettingswin.cpp + src/gui/settings/GeneralPage.cpp + src/gui/settings/AboutPage.cpp + src/gui/settings/ServerPage.cpp + src/gui/settings/NotifyPage.cpp + src/gui/settings/CryptoPage.cpp + src/gui/settings/PeoplePage.cpp + src/gui/settings/MessagePage.cpp + src/gui/settings/NewTag.cpp + src/gui/settings/ForumPage.cpp + src/gui/settings/PluginsPage.cpp + src/gui/settings/PluginItem.cpp + src/gui/settings/AppearancePage.cpp + src/gui/settings/FileAssociationsPage.cpp + src/gui/settings/SoundPage.cpp + src/gui/settings/TransferPage.cpp + src/gui/settings/ChatPage.cpp + src/gui/settings/ChannelPage.cpp + src/gui/settings/PostedPage.cpp + src/gui/settings/ServicePermissionsPage.cpp + src/gui/settings/AddFileAssociationDialog.cpp + src/gui/settings/GroupFrameSettingsWidget.cpp + + src/gui/statusbar/peerstatus.cpp + src/gui/statusbar/natstatus.cpp + src/gui/statusbar/dhtstatus.cpp + src/gui/statusbar/torstatus.cpp + src/gui/statusbar/ratesstatus.cpp + src/gui/statusbar/hashingstatus.cpp + src/gui/statusbar/discstatus.cpp + src/gui/statusbar/SoundStatus.cpp + src/gui/statusbar/OpModeStatus.cpp + src/gui/statusbar/ToasterDisable.cpp + src/gui/statusbar/SysTrayStatus.cpp + + src/gui/toaster/ToasterItem.cpp + src/gui/toaster/MessageToaster.cpp + src/gui/toaster/DownloadToaster.cpp + src/gui/toaster/OnlineToaster.cpp + src/gui/toaster/ChatToaster.cpp + src/gui/toaster/GroupChatToaster.cpp + src/gui/toaster/ChatLobbyToaster.cpp + src/gui/toaster/FriendRequestToaster.cpp + + src/gui/advsearch/advancedsearchdialog.cpp + src/gui/advsearch/expressionwidget.cpp + src/gui/advsearch/guiexprelement.cpp + + src/gui/elastic/graphwidget.cpp + src/gui/elastic/edge.cpp + src/gui/elastic/arrow.cpp + src/gui/elastic/elnode.cpp + + src/gui/feeds/BoardsCommentsItem.cpp + src/gui/feeds/FeedItem.cpp + src/gui/feeds/FeedHolder.cpp + src/gui/feeds/GxsCircleItem.cpp + src/gui/feeds/ChannelsCommentsItem.cpp + src/gui/feeds/PeerItem.cpp + src/gui/feeds/MsgItem.cpp + src/gui/feeds/ChatMsgItem.cpp + src/gui/feeds/SubFileItem.cpp + src/gui/feeds/AttachFileItem.cpp + src/gui/feeds/SecurityItem.cpp + src/gui/feeds/SecurityIpItem.cpp + src/gui/feeds/NewsFeedUserNotify.cpp + + src/gui/groups/CreateGroup.cpp + + src/gui/statistics/BandwidthGraphWindow.cpp + src/gui/statistics/BandwidthStatsWidget.cpp + src/gui/statistics/DhtWindow.cpp + src/gui/statistics/Histogram.cpp + src/gui/statistics/TurtleRouterDialog.cpp + src/gui/statistics/TurtleRouterStatistics.cpp + src/gui/statistics/GxsIdStatistics.cpp + src/gui/statistics/GlobalRouterStatistics.cpp + src/gui/statistics/GxsTransportStatistics.cpp + src/gui/statistics/StatisticsWindow.cpp + src/gui/statistics/BwCtrlWindow.cpp + src/gui/statistics/RttStatistics.cpp + src/gui/statistics/BWGraph.cpp + + src/util/RsSyntaxHighlighter.cpp + src/util/imageutil.cpp + src/util/retroshareWin32.cpp + + src/gui/NetworkDialog/pgpid_item_model.cpp + src/gui/NetworkDialog/pgpid_item_proxy.cpp + ) + +list( + APPEND RS_GUI_FORMS + src/TorControl/TorControlWindow.ui + + src/gui/StartDialog.ui + src/gui/HomePage.ui + src/gui/GetStartedDialog.ui + src/gui/GenCertDialog.ui + src/gui/AboutDialog.ui + src/gui/AboutWidget.ui + src/gui/QuickStartWizard.ui + src/gui/NetworkDialog.ui + src/gui/common/AvatarDialog.ui + src/gui/MainWindow.ui + src/gui/NetworkView.ui + src/gui/FriendsDialog.ui + src/gui/NewsFeed.ui + src/gui/ShareManager.ui + src/gui/help/browser/helpbrowser.ui + src/gui/HelpDialog.ui + src/gui/ServicePermissionDialog.ui + src/gui/ChatLobbyWidget.ui + + src/gui/FileTransfer/TransfersDialog.ui + src/gui/FileTransfer/DetailsDialog.ui + src/gui/FileTransfer/SearchDialog.ui + src/gui/FileTransfer/SharedFilesDialog.ui + src/gui/FileTransfer/BannedFilesDialog.ui + + src/gui/profile/ProfileWidget.ui + src/gui/profile/StatusMessage.ui + src/gui/profile/ProfileManager.ui + + src/gui/chat/PopupChatWindow.ui + src/gui/chat/PopupChatDialog.ui + src/gui/chat/ChatTabWidget.ui + src/gui/chat/ChatWidget.ui + src/gui/chat/ChatLobbyDialog.ui + src/gui/chat/CreateLobbyDialog.ui + + src/gui/connect/ConfCertDialog.ui + src/gui/connect/PGPKeyDialog.ui + src/gui/connect/ConnectFriendWizard.ui + src/gui/connect/ConnectProgressDialog.ui + src/gui/connect/FriendRecommendDialog.ui + + src/gui/msgs/MessagesDialog.ui + src/gui/msgs/MessageComposer.ui + src/gui/msgs/MessageWindow.ui + src/gui/msgs/MessageWidget.ui + + src/gui/settings/settingsw.ui + src/gui/settings/GeneralPage.ui + src/gui/settings/ServerPage.ui + src/gui/settings/NotifyPage.ui + src/gui/settings/PeoplePage.ui + src/gui/settings/CryptoPage.ui + src/gui/settings/MessagePage.ui + src/gui/settings/NewTag.ui + src/gui/settings/ForumPage.ui + src/gui/settings/AboutPage.ui + src/gui/settings/PluginsPage.ui + src/gui/settings/AppearancePage.ui + src/gui/settings/TransferPage.ui + src/gui/settings/SoundPage.ui + src/gui/settings/ChatPage.ui + src/gui/settings/ChannelPage.ui + src/gui/settings/PostedPage.ui + src/gui/settings/ServicePermissionsPage.ui + src/gui/settings/PluginItem.ui + src/gui/settings/GroupFrameSettingsWidget.ui + + src/gui/toaster/MessageToaster.ui + src/gui/toaster/OnlineToaster.ui + src/gui/toaster/DownloadToaster.ui + src/gui/toaster/ChatToaster.ui + src/gui/toaster/GroupChatToaster.ui + src/gui/toaster/ChatLobbyToaster.ui + src/gui/toaster/FriendRequestToaster.ui + + src/gui/advsearch/AdvancedSearchDialog.ui + src/gui/advsearch/expressionwidget.ui + + src/gui/feeds/BoardsCommentsItem.ui + src/gui/feeds/GxsCircleItem.ui + src/gui/feeds/ChannelsCommentsItem.ui + src/gui/feeds/PeerItem.ui + src/gui/feeds/MsgItem.ui + src/gui/feeds/ChatMsgItem.ui + src/gui/feeds/SubFileItem.ui + src/gui/feeds/AttachFileItem.ui + src/gui/feeds/SecurityItem.ui + src/gui/feeds/SecurityIpItem.ui + + src/gui/im_history/ImHistoryBrowser.ui + + src/gui/groups/CreateGroup.ui + + src/gui/common/GroupTreeWidget.ui + src/gui/common/AvatarWidget.ui + src/gui/common/NewFriendList.ui + src/gui/common/FriendSelectionWidget.ui + src/gui/common/HashBox.ui + src/gui/common/RSImageBlockWidget.ui + src/gui/common/RsCollectionDialog.ui + src/gui/common/HeaderFrame.ui + src/gui/common/RSFeedWidget.ui + + src/gui/style/StyleDialog.ui + + src/gui/statistics/BandwidthGraphWindow.ui + src/gui/statistics/BandwidthStatsWidget.ui + src/gui/statistics/DhtWindow.ui + src/gui/statistics/TurtleRouterDialog.ui + src/gui/statistics/TurtleRouterStatistics.ui + src/gui/statistics/GxsIdStatistics.ui + src/gui/statistics/GlobalRouterStatistics.ui + src/gui/statistics/GxsTransportStatistics.ui + src/gui/statistics/StatisticsWindow.ui + src/gui/statistics/BwCtrlWindow.ui + src/gui/statistics/RttStatistics.ui + + src/util/RichTextEdit.ui + ) + +list( + APPEND RS_IMPLEMENTATION_HEADERS + + src/TorControl/TorControlWindow.h + + src/chat/distantchat.h + src/chat/distributedchat.h + src/chat/p3chatservice.h + src/chat/rschatitems.h + + src/rshare.h + src/retroshare-gui/configpage.h + src/retroshare-gui/RsAutoUpdatePage.h + src/retroshare-gui/mainpage.h + + src/control/bandwidthevent.h + src/control/eventtype.h + + src/gui/QuickStartWizard.h + src/gui/notifyqt.h + src/gui/GetStartedDialog.h + src/gui/StartDialog.h + src/gui/HomePage.h + src/gui/NetworkDialog.h + src/gui/GenCertDialog.h + src/gui/linetypes.h + src/gui/mainpagestack.h + src/gui/MainWindow.h + src/gui/RSHumanReadableDelegate.h + src/gui/AboutDialog.h + src/gui/AboutWidget.h + src/gui/NetworkView.h + src/gui/FriendsDialog.h + src/gui/ServicePermissionDialog.h + src/gui/RemoteDirModel.h + src/gui/RetroShareLink.h + src/gui/SearchTreeWidget.h + src/gui/ShareManager.h + src/gui/NewsFeed.h + src/gui/ShareDialog.h + src/gui/SFListDelegate.h + src/gui/SoundManager.h + src/gui/HelpDialog.h + src/gui/LogoBar.h + + src/gui/common/AvatarDialog.h + + src/gui/NetworkDialog/pgpid_item_model.h + src/gui/NetworkDialog/pgpid_item_proxy.h + + src/gui/FileTransfer/SearchDialog.h + src/gui/FileTransfer/SharedFilesDialog.h + src/gui/FileTransfer/xprogressbar.h + src/gui/FileTransfer/DetailsDialog.h + src/gui/FileTransfer/FileTransferInfoWidget.h + src/gui/FileTransfer/DLListDelegate.h + src/gui/FileTransfer/ULListDelegate.h + src/gui/FileTransfer/TransfersDialog.h + src/gui/FileTransfer/BannedFilesDialog.h + src/gui/FileTransfer/TransferUserNotify.h + + src/gui/statistics/TurtleRouterDialog.h + src/gui/statistics/TurtleRouterStatistics.h + src/gui/statistics/GxsIdStatistics.h + src/gui/statistics/dhtgraph.h + src/gui/statistics/Histogram.h + src/gui/statistics/BandwidthGraphWindow.h + src/gui/statistics/turtlegraph.h + src/gui/statistics/BandwidthStatsWidget.h + src/gui/statistics/DhtWindow.h + src/gui/statistics/GlobalRouterStatistics.h + src/gui/statistics/GxsTransportStatistics.h + src/gui/statistics/StatisticsWindow.h + src/gui/statistics/BwCtrlWindow.h + src/gui/statistics/BWGraph.h + src/gui/statistics/RttStatistics.h + + src/gui/plugins/PluginInterface.h + + src/gui/im_history/ImHistoryBrowser.h + src/gui/im_history/IMHistoryItemDelegate.h + src/gui/im_history/IMHistoryItemPainter.h + + src/lang/languagesupport.h + + src/util/RsSyntaxHighlighter.h + src/util/imageutil.h + src/util/RichTextEdit.h + src/util/retroshareWin32.h + src/util/RsProtectedTimer.h + src/util/stringutil.h + src/util/RsNetUtil.h + src/util/DateTime.h + src/util/RetroStyleLabel.h + src/util/dllexport.h + src/util/NonCopyable.h + src/util/rsutildll.h + src/util/dllexport.h + src/util/global.h + src/util/rsqtutildll.h + src/util/Interface.h + src/util/PixmapMerging.h + src/util/MouseEventFilter.h + src/util/EventFilter.h + src/util/Widget.h + src/util/RsAction.h + src/util/RsUserdata.h + src/util/printpreview.h + src/util/log.h + src/util/misc.h + src/util/HandleRichText.h + src/util/ObjectPainter.h + src/util/QtVersion.h + src/util/RsFile.h + src/util/qtthreadsutils.h + src/util/ClickableLabel.h + src/util/AspectRatioPixmapLabel.h + + src/gui/profile/ProfileWidget.h + src/gui/profile/ProfileManager.h + src/gui/profile/StatusMessage.h + + src/gui/chat/PopupChatWindow.h + src/gui/chat/PopupChatDialog.h + src/gui/chat/PopupDistantChatDialog.h + src/gui/chat/ChatTabWidget.h + src/gui/chat/ChatWidget.h + src/gui/chat/ChatDialog.h + src/gui/ChatLobbyWidget.h + src/gui/chat/ChatLobbyDialog.h + src/gui/chat/CreateLobbyDialog.h + src/gui/chat/ChatStyle.h + src/gui/chat/ChatUserNotify.h + src/gui/chat/ChatLobbyUserNotify.h + + src/gui/connect/ConfCertDialog.h + src/gui/connect/PGPKeyDialog.h + src/gui/connect/FriendRecommendDialog.h + + src/gui/msgs/MessagesDialog.h + src/gui/msgs/MessageInterface.h + src/gui/msgs/MessageComposer.h + src/gui/msgs/MessageWindow.h + src/gui/msgs/MessageWidget.h + src/gui/msgs/MessageModel.h + src/gui/msgs/TagsMenu.h + src/gui/msgs/textformat.h + src/gui/msgs/MessageUserNotify.h + + src/gui/images/retroshare_win.rc.h + + src/gui/settings/RSPermissionMatrixWidget.h + src/gui/settings/rsharesettings.h + src/gui/settings/RsharePeerSettings.h + src/gui/settings/rsettings.h + src/gui/settings/rsettingswin.h + src/gui/settings/GeneralPage.h + src/gui/settings/PeoplePage.h + src/gui/settings/AboutPage.h + src/gui/settings/ServerPage.h + src/gui/settings/NotifyPage.h + src/gui/settings/CryptoPage.h + src/gui/settings/MessagePage.h + src/gui/settings/NewTag.h + src/gui/settings/ForumPage.h + src/gui/settings/PluginsPage.h + src/gui/settings/PluginItem.h + src/gui/settings/AppearancePage.h + src/gui/settings/FileAssociationsPage.h + src/gui/settings/SoundPage.h + src/gui/settings/TransferPage.h + src/gui/settings/ChatPage.h + src/gui/settings/ChannelPage.h + src/gui/settings/PostedPage.h + src/gui/settings/ServicePermissionsPage.h + src/gui/settings/AddFileAssociationDialog.h + src/gui/settings/GroupFrameSettingsWidget.h + + src/gui/toaster/ToasterItem.h + src/gui/toaster/MessageToaster.h + src/gui/toaster/OnlineToaster.h + src/gui/toaster/DownloadToaster.h + src/gui/toaster/ChatToaster.h + src/gui/toaster/GroupChatToaster.h + src/gui/toaster/ChatLobbyToaster.h + src/gui/toaster/FriendRequestToaster.h + + src/gui/common/RsButtonOnText.h + src/gui/common/RsCollection.h + src/gui/common/RSGraphWidget.h + src/gui/common/ElidedLabel.h + src/gui/common/vmessagebox.h + src/gui/common/RsUrlHandler.h + src/gui/common/RsCollectionDialog.h + src/gui/common/rwindow.h + src/gui/common/rshtml.h + src/gui/common/AvatarDefs.h + src/gui/common/GroupFlagsWidget.h + src/gui/common/GroupSelectionBox.h + src/gui/common/GroupChooser.h + src/gui/common/StatusDefs.h + src/gui/common/TagDefs.h + src/gui/common/GroupDefs.h + src/gui/common/Emoticons.h + src/gui/common/RSComboBox.h + src/gui/common/RSListWidgetItem.h + src/gui/common/RSTextEdit.h + src/gui/common/RSPlainTextEdit.h + src/gui/common/RSTreeWidget.h + src/gui/common/RSTreeWidgetItem.h + src/gui/common/RSFeedWidget.h + src/gui/common/RSTabWidget.h + src/gui/common/RSElidedItemDelegate.h + src/gui/common/RSItemDelegate.h + src/gui/common/PeerDefs.h + src/gui/common/FilesDefs.h + src/gui/common/PopularityDefs.h + src/gui/common/RsBanListDefs.h + src/gui/common/GroupTreeWidget.h + src/gui/common/RSTreeView.h + src/gui/common/AvatarWidget.h + src/gui/common/FriendListModel.h + src/gui/common/NewFriendList.h + src/gui/common/FriendSelectionWidget.h + src/gui/common/FriendSelectionDialog.h + src/gui/common/HashBox.h + src/gui/common/LineEditClear.h + src/gui/common/DropLineEdit.h + src/gui/common/RSTextBrowser.h + src/gui/common/RSImageBlockWidget.h + src/gui/common/FeedNotify.h + src/gui/common/UserNotify.h + src/gui/common/HeaderFrame.h + src/gui/common/MimeTextEdit.h + src/gui/common/UIStateHelper.h + src/gui/common/FloatingHelpBrowser.h + src/gui/common/SubscribeToolButton.h + src/gui/common/RsBanListToolButton.h + src/gui/common/FlowLayout.h + src/gui/common/PictureFlow.h + src/gui/common/ToasterNotify.h + + src/gui/style/RSStyle.h + src/gui/style/StyleDialog.h + + src/gui/help/browser/helpbrowser.h + src/gui/help/browser/helptextbrowser.h + + src/gui/statusbar/peerstatus.h + src/gui/statusbar/natstatus.h + src/gui/statusbar/dhtstatus.h + src/gui/statusbar/torstatus.h + src/gui/statusbar/ratesstatus.h + src/gui/statusbar/hashingstatus.h + src/gui/statusbar/discstatus.h + src/gui/statusbar/SoundStatus.h + src/gui/statusbar/OpModeStatus.h + src/gui/statusbar/ToasterDisable.h + src/gui/statusbar/SysTrayStatus.h + + src/gui/advsearch/advancedsearchdialog.h + src/gui/advsearch/expressionwidget.h + src/gui/advsearch/guiexprelement.h + + src/gui/elastic/graphwidget.h + src/gui/elastic/edge.h + src/gui/elastic/arrow.h + src/gui/elastic/elnode.h + + src/gui/feeds/BoardsCommentsItem.h + src/gui/feeds/FeedItem.h + src/gui/feeds/FeedHolder.h + src/gui/feeds/GxsCircleItem.h + src/gui/feeds/ChannelsCommentsItem.h + src/gui/feeds/PeerItem.h + src/gui/feeds/MsgItem.h + src/gui/feeds/ChatMsgItem.h + src/gui/feeds/SubFileItem.h + src/gui/feeds/AttachFileItem.h + src/gui/feeds/SecurityItem.h + src/gui/feeds/SecurityIpItem.h + src/gui/feeds/NewsFeedUserNotify.h + + src/gui/connect/ConnectFriendWizard.h + src/gui/connect/ConnectProgressDialog.h + + src/gui/groups/CreateGroup.h + ) + +if(RS_JSON_API) + list( + APPEND RS_GUI_SOURCES + src/gui/settings/JsonApiPage.cc + ) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/settings/JsonApiPage.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/settings/JsonApiPage.ui + ) +endif(RS_JSON_API) + +if(RS_WEBUI) + list( + APPEND RS_GUI_SOURCES + src/gui/settings/WebuiPage.cpp + ) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/jsonapi/p3webui.h + src/gui/settings/WebuiPage.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/settings/WebuiPage.ui + ) +endif(RS_WEBUI) + +list( + APPEND RS_GUI_QTRESOURCES + src/gui/images.qrc + src/gui/icons.qrc + src/lang/lang.qrc + src/gui/help/content/content.qrc + src/gui/emojione.qrc + src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc + src/gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc + ) + +list( + APPEND RS_TRANSLATIONS + src/lang/retroshare_ca_ES.ts + src/lang/retroshare_cs.ts + src/lang/retroshare_da.ts + src/lang/retroshare_de.ts + src/lang/retroshare_el.ts + src/lang/retroshare_en.ts + src/lang/retroshare_es.ts + src/lang/retroshare_fi.ts + src/lang/retroshare_fr.ts + src/lang/retroshare_hu.ts + src/lang/retroshare_it.ts + src/lang/retroshare_ja_JP.ts + src/lang/retroshare_nl.ts + src/lang/retroshare_ko.ts + src/lang/retroshare_pl.ts + src/lang/retroshare_ru.ts + src/lang/retroshare_sv.ts + src/lang/retroshare_tr.ts + src/lang/retroshare_zh_CN.ts + ) + +if(RS_UNFINISHED_TRANSLATIONS) + list( + APPEND RS_TRANSLATIONS + src/lang/retroshare_bg.ts + src/lang/retroshare_af.ts + src/lang/retroshare_pt.ts + src/lang/retroshare_sl.ts + src/lang/retroshare_sr.ts + src/lang/retroshare_zh_TW.ts + ) +endif(RS_UNFINISHED_TRANSLATIONS) + +if(RS_MESSENGER) + + target_compile_definitions( ${PROJECT_NAME} PUBLIC MESSENGER_WINDOW ) + + list( + APPEND RS_GUI_SOURCES + src/gui/MessengerWindow.cpp + src/gui/common/FriendList.cpp + ) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/MessengerWindow.h + src/gui/common/FriendList.h + ) + list( + APPEND RS_GUI_FORMS + src/gui/MessengerWindow.ui + src/gui/common/FriendList.ui + ) +endif(RS_MESSENGER) + +if(RS_IDLE) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/idle/idle.h + ) + list( + APPEND RS_GUI_SOURCES + src/idle/idle.cpp + src/idle/idle_platform.cpp + ) +endif(RS_IDLE) + +if(RS_FRAMECATCHER) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/util/framecatcher.h + ) + list( + APPEND RS_GUI_SOURCES + src/util/framecatcher.cpp + ) + + # TODO: LIBS += -lxine + + target_compile_definitions( + ${PROJECT_NAME} PUBLIC CHANNELS_FRAME_CATCHER + ) +endif(RS_FRAMECATCHER) + +# Embedded Friend Server + +if(RS_EFS) + target_compile_definitions( + ${PROJECT_NAME} PUBLIC RS_EMBEDED_FRIEND_SERVER + ) + list( + APPEND RS_GUI_SOURCES + src/gui/FriendServerControl.cpp + ) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/FriendServerControl.h + ) + list( + APPEND RS_GUI_FORMS + src/gui/FriendServerControl.ui + ) +endif(RS_EFS) + +# BELOW IS GXS Unfinished Services. + +if(RS_UNFINISHED) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/unfinished/ApplicationWindow.h + + # gui/unfinished/CalDialog.h + # gui/unfinished/ExampleDialog.h + # gui/unfinished/GamesDialog.h + # gui/unfinished/profile/ProfileView.h + # gui/unfinished/profile/ProfileEdit.h + # gui/unfinished/StatisticDialog.h + # gui/unfinished/PhotoDialog.h + # gui/unfinished/PhotoShow.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/unfinished/ApplicationWindow.ui + + # gui/unfinished/CalDialog.ui + # gui/unfinished/ExampleDialog.ui + # gui/unfinished/GamesDialog.ui + # gui/unfinished/profile/ProfileView.ui + # gui/unfinished/profile/ProfileEdit.ui + # gui/unfinished/StatisticDialog.ui + # gui/unfinished/PhotoDialog.ui + # gui/unfinished/PhotoShow.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/unfinished/ApplicationWindow.cpp + + # gui/unfinished/CalDialog.cpp + # gui/unfinished/ExampleDialog.cpp + # gui/unfinished/GamesDialog.cpp + # gui/unfinished/profile/ProfileView.cpp + # gui/unfinished/profile/ProfileEdit.cpp + # gui/unfinished/StatisticDialog.cpp + # gui/unfinished/PhotoDialog.cpp + # gui/unfinished/PhotoShow.cpp + ) + + target_compile_definitions( + ${PROJECT_NAME} PUBLIC UNFINISHED + ) +endif(RS_UNFINISHED) + +if(RS_GXSPHOTOSHARE) + target_compile_definitions( + ${PROJECT_NAME} PUBLIC RS_USE_PHOTO + ) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/PhotoShare/AlbumGroupDialog.h + src/gui/PhotoShare/AlbumExtra.h + src/gui/PhotoShare/PhotoDrop.h + src/gui/PhotoShare/AlbumItem.h + src/gui/PhotoShare/AlbumDialog.h + src/gui/PhotoShare/PhotoItem.h + src/gui/PhotoShare/PhotoShareItemHolder.h + src/gui/PhotoShare/PhotoShare.h + src/gui/PhotoShare/PhotoSlideShow.h + src/gui/PhotoShare/PhotoDialog.h + ) + list( + APPEND RS_GUI_FORMS + src/gui/PhotoShare/AlbumExtra.ui + src/gui/PhotoShare/PhotoItem.ui + src/gui/PhotoShare/PhotoDialog.ui + src/gui/PhotoShare/AlbumItem.ui + src/gui/PhotoShare/AlbumDialog.ui + src/gui/PhotoShare/PhotoShare.ui + src/gui/PhotoShare/PhotoSlideShow.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/PhotoShare/AlbumGroupDialog.cpp + src/gui/PhotoShare/AlbumExtra.cpp + src/gui/PhotoShare/PhotoItem.cpp + src/gui/PhotoShare/PhotoDialog.cpp + src/gui/PhotoShare/PhotoDrop.cpp + src/gui/PhotoShare/AlbumItem.cpp + src/gui/PhotoShare/AlbumDialog.cpp + src/gui/PhotoShare/PhotoShareItemHolder.cpp + src/gui/PhotoShare/PhotoShare.cpp + src/gui/PhotoShare/PhotoSlideShow.cpp + ) + + list( + APPEND RS_GUI_QTRESOURCES + src/gui/PhotoShare/Photo_images.qrc + ) +endif(RS_GXSPHOTOSHARE) + +if(RS_GXSWIKIPOS) + target_compile_definitions( + ${PROJECT_NAME} PUBLIC RS_USE_WIKI + ) + + target_include_directories(${PROJECT_NAME} PUBLIC ../../supportlibs/pegmarkdown) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/WikiPoos/WikiDialog.h + src/gui/WikiPoos/WikiAddDialog.h + src/gui/WikiPoos/WikiEditDialog.h + src/gui/gxs/WikiGroupDialog.h + src/gui/gxs/RsGxsUpdateBroadcastBase.h + src/gui/gxs/RsGxsUpdateBroadcastWidget.h + src/gui/gxs/RsGxsUpdateBroadcastPage.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/WikiPoos/WikiDialog.ui + src/gui/WikiPoos/WikiAddDialog.ui + src/gui/WikiPoos/WikiEditDialog.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/WikiPoos/WikiDialog.cpp + src/gui/WikiPoos/WikiAddDialog.cpp + src/gui/WikiPoos/WikiEditDialog.cpp + src/gui/gxs/WikiGroupDialog.cpp + src/gui/gxs/RsGxsUpdateBroadcastBase.cpp + src/gui/gxs/RsGxsUpdateBroadcastWidget.cpp + src/gui/gxs/RsGxsUpdateBroadcastPage.cpp + ) + + list( + APPEND RS_GUI_QTRESOURCES + src/gui/WikiPoos/Wiki_images.qrc + ) +endif(RS_GXSWIKIPOS) + +if(RS_GXSTHEWIRE) + target_compile_definitions( + ${PROJECT_NAME} PUBLIC RS_USE_WIRE + ) + + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/TheWire/WireDialog.h + src/gui/TheWire/WireGroupItem.h + src/gui/TheWire/WireGroupDialog.h + src/gui/TheWire/WireGroupExtra.h + src/gui/TheWire/PulseAddDialog.h + src/gui/TheWire/PulseViewItem.h + src/gui/TheWire/PulseTopLevel.h + src/gui/TheWire/PulseViewGroup.h + src/gui/TheWire/PulseReply.h + src/gui/TheWire/PulseReplySeperator.h + src/gui/TheWire/PulseMessage.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/TheWire/WireDialog.ui + src/gui/TheWire/WireGroupItem.ui + src/gui/TheWire/WireGroupExtra.ui + src/gui/TheWire/PulseAddDialog.ui + src/gui/TheWire/PulseTopLevel.ui + src/gui/TheWire/PulseViewGroup.ui + src/gui/TheWire/PulseReply.ui + src/gui/TheWire/PulseReplySeperator.ui + src/gui/TheWire/PulseMessage.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/TheWire/WireDialog.cpp + src/gui/TheWire/WireGroupItem.cpp + src/gui/TheWire/WireGroupDialog.cpp + src/gui/TheWire/WireGroupExtra.cpp + src/gui/TheWire/PulseAddDialog.cpp + src/gui/TheWire/PulseViewItem.cpp + src/gui/TheWire/PulseTopLevel.cpp + src/gui/TheWire/PulseViewGroup.cpp + src/gui/TheWire/PulseReply.cpp + src/gui/TheWire/PulseReplySeperator.cpp + src/gui/TheWire/PulseMessage.cpp + ) + + list( + APPEND RS_GUI_QTRESOURCES + RESOURCES += src/gui/TheWire/TheWire_images.qrc + ) +endif(RS_GXSTHEWIRE) + +if(RS_GXSIDENTITIES) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/Identity/IdDialog.h + src/gui/Identity/IdEditDialog.h + src/gui/Identity/IdDetailsDialog.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/Identity/IdDialog.ui + src/gui/Identity/IdEditDialog.ui + src/gui/Identity/IdDetailsDialog.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/Identity/IdDialog.cpp + src/gui/Identity/IdEditDialog.cpp + src/gui/Identity/IdDetailsDialog.cpp + ) +endif(RS_GXSIDENTITIES) + +if(RS_GXSCIRCLES) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/Circles/CirclesDialog.h + src/gui/Circles/CreateCircleDialog.h + src/gui/People/PeopleDialog.h + src/gui/People/CircleWidget.h + src/gui/People/IdentityWidget.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/Circles/CirclesDialog.ui + src/gui/Circles/CreateCircleDialog.ui + src/gui/People/PeopleDialog.ui + src/gui/People/CircleWidget.ui + src/gui/People/IdentityWidget.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/Circles/CirclesDialog.cpp + src/gui/Circles/CreateCircleDialog.cpp + src/gui/People/PeopleDialog.cpp + src/gui/People/CircleWidget.cpp + src/gui/People/IdentityWidget.cpp + ) +endif(RS_GXSCIRCLES) + +if(RS_GXSGUI) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/gxs/GxsGroupDialog.h + src/gui/gxs/GxsIdDetails.h + src/gui/gxs/GxsIdChooser.h + src/gui/gxs/GxsIdLabel.h + src/gui/gxs/GxsCircleChooser.h + src/gui/gxs/GxsCircleLabel.h + src/gui/gxs/GxsIdTreeWidgetItem.h + src/gui/gxs/GxsCommentTreeWidget.h + src/gui/gxs/GxsCommentContainer.h + src/gui/gxs/GxsCommentDialog.h + src/gui/gxs/GxsCreateCommentDialog.h + src/gui/gxs/GxsGroupFrameDialog.h + src/gui/gxs/GxsMessageFrameWidget.h + src/gui/gxs/GxsMessageFramePostWidget.h + src/gui/gxs/GxsGroupFeedItem.h + src/gui/gxs/GxsFeedItem.h + src/gui/gxs/GxsGroupShareKey.h + src/gui/gxs/GxsUserNotify.h + src/gui/gxs/GxsFeedWidget.h + src/util/TokenQueue.h + src/util/RsGxsUpdateBroadcast.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/gxs/GxsGroupDialog.ui + src/gui/gxs/GxsCommentContainer.ui + src/gui/gxs/GxsCommentDialog.ui + src/gui/gxs/GxsCreateCommentDialog.ui + src/gui/gxs/GxsGroupFrameDialog.ui + src/gui/gxs/GxsGroupShareKey.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/gxs/GxsGroupDialog.cpp + src/gui/gxs/GxsIdDetails.cpp + src/gui/gxs/GxsIdChooser.cpp + src/gui/gxs/GxsIdLabel.cpp + src/gui/gxs/GxsCircleChooser.cpp + src/gui/gxs/GxsGroupShareKey.cpp + src/gui/gxs/GxsCircleLabel.cpp + src/gui/gxs/GxsIdTreeWidgetItem.cpp + src/gui/gxs/GxsCommentTreeWidget.cpp + src/gui/gxs/GxsCommentContainer.cpp + src/gui/gxs/GxsCommentDialog.cpp + src/gui/gxs/GxsCreateCommentDialog.cpp + src/gui/gxs/GxsGroupFrameDialog.cpp + src/gui/gxs/GxsMessageFrameWidget.cpp + src/gui/gxs/GxsMessageFramePostWidget.cpp + src/gui/gxs/GxsGroupFeedItem.cpp + src/gui/gxs/GxsFeedItem.cpp + src/gui/gxs/GxsUserNotify.cpp + src/gui/gxs/GxsFeedWidget.cpp + src/util/TokenQueue.cpp + src/util/RsGxsUpdateBroadcast.cpp + ) +endif(RS_GXSGUI) + +if(RS_GXSFORUMS) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/gxsforums/GxsForumsDialog.h + src/gui/gxsforums/GxsForumGroupDialog.h + src/gui/gxsforums/CreateGxsForumMsg.h + src/gui/gxsforums/GxsForumThreadWidget.h + src/gui/gxsforums/GxsForumModel.h + src/gui/gxsforums/GxsForumUserNotify.h + src/gui/feeds/GxsForumGroupItem.h + src/gui/feeds/GxsForumMsgItem.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/gxsforums/CreateGxsForumMsg.ui + src/gui/gxsforums/GxsForumThreadWidget.ui + src/gui/feeds/GxsForumGroupItem.ui + src/gui/feeds/GxsForumMsgItem.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/gxsforums/GxsForumsDialog.cpp + src/gui/gxsforums/GxsForumGroupDialog.cpp + src/gui/gxsforums/CreateGxsForumMsg.cpp + src/gui/gxsforums/GxsForumThreadWidget.cpp + src/gui/gxsforums/GxsForumModel.cpp + src/gui/gxsforums/GxsForumUserNotify.cpp + src/gui/feeds/GxsForumGroupItem.cpp + src/gui/feeds/GxsForumMsgItem.cpp + ) +endif(RS_GXSFORUMS) + + +if(RS_GXSCHANNELS) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/gxschannels/GxsChannelDialog.h + src/gui/gxschannels/GxsChannelGroupDialog.h + src/gui/gxschannels/CreateGxsChannelMsg.h + src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h + src/gui/gxschannels/GxsChannelPostsModel.h + src/gui/gxschannels/GxsChannelPostFilesModel.h + src/gui/gxschannels/GxsChannelPostThumbnail.h + src/gui/gxschannels/GxsChannelFilesStatusWidget.h + src/gui/feeds/GxsChannelGroupItem.h + src/gui/feeds/GxsChannelPostItem.h + src/gui/gxschannels/GxsChannelUserNotify.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui + src/gui/gxschannels/GxsChannelFilesStatusWidget.ui + src/gui/gxschannels/CreateGxsChannelMsg.ui + src/gui/feeds/GxsChannelGroupItem.ui + src/gui/feeds/GxsChannelPostItem.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/gxschannels/GxsChannelDialog.cpp + src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp + src/gui/gxschannels/GxsChannelPostsModel.cpp + src/gui/gxschannels/GxsChannelPostFilesModel.cpp + src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp + src/gui/gxschannels/GxsChannelPostThumbnail.cpp + src/gui/gxschannels/GxsChannelGroupDialog.cpp + src/gui/gxschannels/CreateGxsChannelMsg.cpp + src/gui/feeds/GxsChannelGroupItem.cpp + src/gui/feeds/GxsChannelPostItem.cpp + src/gui/gxschannels/GxsChannelUserNotify.cpp + ) +endif(RS_GXSCHANNELS) + +if(RS_GXSPOSTED) + list( + APPEND RS_IMPLEMENTATION_HEADERS + src/gui/Posted/PostedDialog.h + src/gui/Posted/PostedListWidgetWithModel.h + src/gui/Posted/PostedPostsModel.h + src/gui/Posted/BoardPostDisplayWidget.h + src/gui/Posted/PostedItem.h + src/gui/Posted/PostedCardView.h + src/gui/Posted/PostedGroupDialog.h + src/gui/feeds/PostedGroupItem.h + src/gui/Posted/PostedCreatePostDialog.h + src/gui/Posted/PhotoView.h + src/gui/Posted/PostedUserNotify.h + ) + + list( + APPEND RS_GUI_FORMS + src/gui/Posted/PostedListWidgetWithModel.ui + src/gui/feeds/PostedGroupItem.ui + src/gui/Posted/BoardPostDisplayWidget_compact.ui + src/gui/Posted/BoardPostDisplayWidget_card.ui + src/gui/Posted/PostedItem.ui + src/gui/Posted/PostedCardView.ui + src/gui/Posted/PostedCreatePostDialog.ui + src/gui/Posted/PhotoView.ui + ) + + list( + APPEND RS_GUI_SOURCES + src/gui/Posted/PostedDialog.cpp + src/gui/Posted/PostedListWidgetWithModel.cpp + src/gui/Posted/BoardPostDisplayWidget.cpp + src/gui/Posted/PostedPostsModel.cpp + src/gui/feeds/PostedGroupItem.cpp + src/gui/Posted/PostedItem.cpp + src/gui/Posted/PostedCardView.cpp + src/gui/Posted/PostedGroupDialog.cpp + src/gui/Posted/PostedCreatePostDialog.cpp + src/gui/Posted/PhotoView.cpp + src/gui/Posted/PostedUserNotify.cpp + ) + + list( + APPEND RS_GUI_QTRESOURCES + src/gui/Posted/Posted_images.qrc + ) +endif(RS_GXSPOSTED) + + + diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.cpp b/retroshare-gui/src/TorControl/AddOnionCommand.cpp deleted file mode 100644 index fb2047dc7..000000000 --- a/retroshare-gui/src/TorControl/AddOnionCommand.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2016, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "AddOnionCommand.h" -#include "HiddenService.h" -#include "CryptoKey.h" -#include "StrUtil.h" - -using namespace Tor; - -AddOnionCommand::AddOnionCommand(HiddenService *service) - : m_service(service) -{ - Q_ASSERT(m_service); -} - -bool AddOnionCommand::isSuccessful() const -{ - return statusCode() == 250 && m_errorMessage.isEmpty(); -} - -QByteArray AddOnionCommand::build() -{ - QByteArray out("ADD_ONION"); - - if (m_service->privateKey().isLoaded()) { - out += " "; - out += m_service->privateKey().bytes(); - } else { - //out += " NEW:RSA1024"; // this is v2. For v3, use NEW:BEST, or NEW:ED25519-V3 - //out += " NEW:ED25519-V3"; // this is v3. - out += " NEW:BEST"; // this is v3, but without control of key type. Generates a RSA1024 key on older Tor versions. - } - - foreach (const HiddenService::Target &target, m_service->targets()) { - out += " Port="; - out += QByteArray::number(target.servicePort); - out += ","; - out += target.targetAddress.toString().toLatin1(); - out += ":"; - out += QByteArray::number(target.targetPort); - } - - out.append("\r\n"); - return out; -} - -void AddOnionCommand::onReply(int statusCode, const QByteArray &data) -{ - TorControlCommand::onReply(statusCode, data); - if (statusCode != 250) { - m_errorMessage = QString::fromLatin1(data); - return; - } - - const QByteArray keyPrefix("PrivateKey="); - const QByteArray sidPrefix("ServiceID="); - - if(data.startsWith("ServiceID=")){ - QByteArray service_id = data.mid(sidPrefix.size()); - m_service->setServiceId(service_id); - } - - if (data.startsWith(keyPrefix)) { - - QByteArray keyData(data.mid(keyPrefix.size())); - CryptoKey key; - - if (!key.loadFromTorMessage(keyData)) { - m_errorMessage = QStringLiteral("Key structure check failed"); - return; - } - - m_service->setPrivateKey(key); - } -} - -void AddOnionCommand::onFinished(int statusCode) -{ - TorControlCommand::onFinished(statusCode); - if (isSuccessful()) - emit succeeded(); - else - emit failed(statusCode); -} - - diff --git a/retroshare-gui/src/TorControl/AddOnionCommand.h b/retroshare-gui/src/TorControl/AddOnionCommand.h deleted file mode 100644 index 7c0afaf5e..000000000 --- a/retroshare-gui/src/TorControl/AddOnionCommand.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2016, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ADDONIONCOMMAND_H -#define ADDONIONCOMMAND_H - -#include "TorControlCommand.h" -#include -#include -#include - -namespace Tor -{ - -class HiddenService; - -class AddOnionCommand : public TorControlCommand -{ - Q_OBJECT - Q_DISABLE_COPY(AddOnionCommand) - - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) - Q_PROPERTY(bool successful READ isSuccessful CONSTANT) - -public: - AddOnionCommand(HiddenService *service); - - QByteArray build(); - - QString errorMessage() const { return m_errorMessage; } - bool isSuccessful() const; - -signals: - void succeeded(); - void failed(int code); - -protected: - HiddenService *m_service; - QString m_errorMessage; - - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onFinished(int statusCode); -}; - -} - -#endif // ADDONIONCOMMAND_H - diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.cpp b/retroshare-gui/src/TorControl/AuthenticateCommand.cpp deleted file mode 100644 index 497c28f89..000000000 --- a/retroshare-gui/src/TorControl/AuthenticateCommand.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "AuthenticateCommand.h" - -using namespace Tor; - -AuthenticateCommand::AuthenticateCommand() -{ -} - -QByteArray AuthenticateCommand::build(const QByteArray &data) -{ - if (data.isNull()) - return QByteArray("AUTHENTICATE\r\n"); - - return QByteArray("AUTHENTICATE ") + data.toHex() + "\r\n"; -} - -void AuthenticateCommand::onReply(int statusCode, const QByteArray &data) -{ - TorControlCommand::onReply(statusCode, data); - m_statusMessage = QString::fromLatin1(data); -} - -void AuthenticateCommand::onFinished(int statusCode) -{ - if (statusCode == 515) { - m_statusMessage = QStringLiteral("Authentication failed - incorrect password"); - } else if (statusCode != 250) { - if (m_statusMessage.isEmpty()) - m_statusMessage = QStringLiteral("Authentication failed (error %1").arg(statusCode); - } - TorControlCommand::onFinished(statusCode); -} diff --git a/retroshare-gui/src/TorControl/AuthenticateCommand.h b/retroshare-gui/src/TorControl/AuthenticateCommand.h deleted file mode 100644 index 79c901d98..000000000 --- a/retroshare-gui/src/TorControl/AuthenticateCommand.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AUTHENTICATECOMMAND_H -#define AUTHENTICATECOMMAND_H - -#include "TorControlCommand.h" - -namespace Tor -{ - -class AuthenticateCommand : public TorControlCommand -{ - Q_OBJECT - -public: - AuthenticateCommand(); - - QByteArray build(const QByteArray &data = QByteArray()); - - bool isSuccessful() const { return statusCode() == 250; } - QString errorMessage() const { return m_statusMessage; } - -protected: - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onFinished(int statusCode); - -private: - QString m_statusMessage; -}; - -} - -#endif // AUTHENTICATECOMMAND_H diff --git a/retroshare-gui/src/TorControl/CryptoKey.cpp b/retroshare-gui/src/TorControl/CryptoKey.cpp deleted file mode 100644 index 9be9a6699..000000000 --- a/retroshare-gui/src/TorControl/CryptoKey.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "CryptoKey.h" -#include "SecureRNG.h" -#include "Useful.h" -#include -#include -#include -#include -#include -#include - -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -{ - *p = r->p; - *q = r->q; -} -#define RSA_bits(o) (BN_num_bits((o)->n)) -#endif - -#ifdef TO_REMOVE -void base32_encode(char *dest, unsigned destlen, const char *src, unsigned srclen); -bool base32_decode(char *dest, unsigned destlen, const char *src, unsigned srclen); -#endif - -CryptoKey::CryptoKey() -{ -} - -CryptoKey::~CryptoKey() -{ - clear(); -} - -#ifdef TO_REMOVE -CryptoKey::Data::~Data() -{ - if (key) - { - RSA_free(key); - key = 0; - } -} -#endif - -void CryptoKey::clear() -{ - key_data.clear(); -} - -#ifdef TO_REMOVE -bool CryptoKey::loadFromData(const QByteArray &data, KeyType type, KeyFormat format) -{ - RSA *key = NULL; - clear(); - - if (data.isEmpty()) - return false; - - if (format == PEM) { - BIO *b = BIO_new_mem_buf((void*)data.constData(), -1); - - if (type == PrivateKey) - key = PEM_read_bio_RSAPrivateKey(b, NULL, NULL, NULL); - else - key = PEM_read_bio_RSAPublicKey(b, NULL, NULL, NULL); - - BIO_free(b); - } else if (format == DER) { - const uchar *dp = reinterpret_cast(data.constData()); - - if (type == PrivateKey) - key = d2i_RSAPrivateKey(NULL, &dp, data.size()); - else - key = d2i_RSAPublicKey(NULL, &dp, data.size()); - } else { - Q_UNREACHABLE(); - } - - if (!key) { - qWarning() << "Failed to parse" << (type == PrivateKey ? "private" : "public") << "key from data"; - return false; - } - - d = new Data(key); - return true; -} -#endif - -bool CryptoKey::loadFromFile(const QString& path) -{ - QFile file(path); - if (!file.open(QIODevice::ReadOnly)) - { - qWarning() << "Failed to open Tor key file " << path << ": " << file.errorString(); - return false; - } - - QByteArray data = file.readAll(); - file.close(); - - if(data.contains("-----BEGIN RSA PRIVATE KEY-----")) - { - std::cerr << "Note: Reading/converting Tor v2 key format." << std::endl; - - // This to be compliant with old format. New format is oblivious to the type of key so we dont need a header - data = data.replace("-----BEGIN RSA PRIVATE KEY-----",nullptr); - data = data.replace("-----END RSA PRIVATE KEY-----",nullptr); - data = data.replace("\n",nullptr); - data = data.replace("\t",nullptr); - - data = "RSA1024:"+data; - } - - std::cerr << "Have read the following key: " << std::endl; - std::cerr << QString(data).toStdString() << std::endl; - - key_data = data; - - return true; -} - -bool CryptoKey::loadFromTorMessage(const QByteArray& b) -{ - // note: We should probably check the structure a bit more, for security. - - std::cerr << "Loading new key:" << std::endl; - - if(b.startsWith("RSA1024")) - std::cerr << " type: RSA-1024 (Tor v2)" << std::endl; - else if(b.startsWith("ED25519-V3")) - std::cerr << " type: ED25519-V3 (Tor v3)" << std::endl; - else if(b.indexOf(':')) - { - std::cerr << " unknown type, or bad syntax in key: \"" << b.left(b.indexOf(':')).toStdString() << "\". Not accepted." << std::endl; - return false; - } - - key_data = b; - return true; -} - -/* Cryptographic hash of a password as expected by Tor's HashedControlPassword */ -QByteArray torControlHashedPassword(const QByteArray &password) -{ - QByteArray salt = SecureRNG::random(8); - if (salt.isNull()) - return QByteArray(); - - int count = ((quint32)16 + (96 & 15)) << ((96 >> 4) + 6); - - SHA_CTX hash; - SHA1_Init(&hash); - - QByteArray tmp = salt + password; - while (count) - { - int c = qMin(count, tmp.size()); - SHA1_Update(&hash, reinterpret_cast(tmp.constData()), c); - count -= c; - } - - unsigned char md[20]; - SHA1_Final(md, &hash); - - /* 60 is the hex-encoded value of 96, which is a constant used by Tor's algorithm. */ - return QByteArray("16:") + salt.toHex().toUpper() + QByteArray("60") + - QByteArray::fromRawData(reinterpret_cast(md), 20).toHex().toUpper(); -} - - -#ifdef TO_REMOVE -bool CryptoKey::isPrivate() const -{ - if (!isLoaded()) { - return false; - } else { - const BIGNUM *p, *q; - RSA_get0_factors(d->key, &p, &q); - return (p != 0); - } -} - -int CryptoKey::bits() const -{ - return isLoaded() ? RSA_bits(d->key) : 0; -} - -QByteArray CryptoKey::publicKeyDigest() const -{ - if (!isLoaded()) - return QByteArray(); - - QByteArray buf = encodedPublicKey(DER); - - QByteArray re(20, 0); - bool ok = SHA1(reinterpret_cast(buf.constData()), buf.size(), - reinterpret_cast(re.data())) != NULL; - - if (!ok) - { - qWarning() << "Failed to hash public key data for digest"; - return QByteArray(); - } - - return re; -} - -QByteArray CryptoKey::encodedPublicKey(KeyFormat format) const -{ - if (!isLoaded()) - return QByteArray(); - - if (format == PEM) { - BIO *b = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSAPublicKey(b, d->key)) { - BUG() << "Failed to encode public key in PEM format"; - BIO_free(b); - return QByteArray(); - } - - BUF_MEM *buf; - BIO_get_mem_ptr(b, &buf); - - /* Close BIO, but don't free buf. */ - (void)BIO_set_close(b, BIO_NOCLOSE); - BIO_free(b); - - QByteArray re((const char *)buf->data, (int)buf->length); - BUF_MEM_free(buf); - return re; - } else if (format == DER) { - uchar *buf = NULL; - int len = i2d_RSAPublicKey(d->key, &buf); - if (len <= 0 || !buf) { - BUG() << "Failed to encode public key in DER format"; - return QByteArray(); - } - - QByteArray re((const char*)buf, len); - OPENSSL_free(buf); - return re; - } else { - Q_UNREACHABLE(); - } - - return QByteArray(); -} - -QByteArray CryptoKey::encodedPrivateKey(KeyFormat format) const -{ - if (!isLoaded() || !isPrivate()) - return QByteArray(); - - if (format == PEM) { - BIO *b = BIO_new(BIO_s_mem()); - - if (!PEM_write_bio_RSAPrivateKey(b, d->key, NULL, NULL, 0, NULL, NULL)) { - BUG() << "Failed to encode private key in PEM format"; - BIO_free(b); - return QByteArray(); - } - - BUF_MEM *buf; - BIO_get_mem_ptr(b, &buf); - - /* Close BIO, but don't free buf. */ - (void)BIO_set_close(b, BIO_NOCLOSE); - BIO_free(b); - - QByteArray re((const char *)buf->data, (int)buf->length); - BUF_MEM_free(buf); - return re; - } else if (format == DER) { - uchar *buf = NULL; - int len = i2d_RSAPrivateKey(d->key, &buf); - if (len <= 0 || !buf) { - BUG() << "Failed to encode private key in DER format"; - return QByteArray(); - } - - QByteArray re((const char*)buf, len); - OPENSSL_free(buf); - return re; - } else { - Q_UNREACHABLE(); - } - - return QByteArray(); -} - -QString CryptoKey::torServiceID() const -{ - if (!isLoaded()) - return QString(); - - QByteArray digest = publicKeyDigest(); - if (digest.isNull()) - return QString(); - - static const int hostnameDigestSize = 10; - static const int hostnameEncodedSize = 16; - - QByteArray re(hostnameEncodedSize+1, 0); - base32_encode(re.data(), re.size(), digest.constData(), hostnameDigestSize); - - // Chop extra null byte - re.chop(1); - - return QString::fromLatin1(re); -} - -QByteArray CryptoKey::signData(const QByteArray &data) const -{ - QByteArray digest(32, 0); - bool ok = SHA256(reinterpret_cast(data.constData()), data.size(), - reinterpret_cast(digest.data())) != NULL; - if (!ok) { - qWarning() << "Digest for RSA signature failed"; - return QByteArray(); - } - - return signSHA256(digest); -} - -QByteArray CryptoKey::signSHA256(const QByteArray &digest) const -{ - if (!isPrivate()) - return QByteArray(); - - QByteArray re(RSA_size(d->key), 0); - unsigned sigsize = 0; - int r = RSA_sign(NID_sha256, reinterpret_cast(digest.constData()), digest.size(), - reinterpret_cast(re.data()), &sigsize, d->key); - - if (r != 1) { - qWarning() << "RSA encryption failed when generating signature"; - return QByteArray(); - } - - re.truncate(sigsize); - return re; -} - -bool CryptoKey::verifyData(const QByteArray &data, QByteArray signature) const -{ - QByteArray digest(32, 0); - bool ok = SHA256(reinterpret_cast(data.constData()), data.size(), - reinterpret_cast(digest.data())) != NULL; - - if (!ok) { - qWarning() << "Digest for RSA verify failed"; - return false; - } - - return verifySHA256(digest, signature); -} - -bool CryptoKey::verifySHA256(const QByteArray &digest, QByteArray signature) const -{ - if (!isLoaded()) - return false; - - int r = RSA_verify(NID_sha256, reinterpret_cast(digest.constData()), digest.size(), - reinterpret_cast(signature.data()), signature.size(), d->key); - if (r != 1) - return false; - return true; -} - -/* Copyright (c) 2001-2004, Roger Dingledine - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson - * Copyright (c) 2007-2010, The Tor Project, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567" - -/* Implements base32 encoding as in rfc3548. Requires that srclen*8 is a multiple of 5. */ -void base32_encode(char *dest, unsigned destlen, const char *src, unsigned srclen) -{ - unsigned i, bit, v, u; - unsigned nbits = srclen * 8; - - /* We need an even multiple of 5 bits, and enough space */ - if ((nbits%5) != 0 || destlen > (nbits/5)+1) { - Q_ASSERT(false); - memset(dest, 0, destlen); - return; - } - - for (i = 0, bit = 0; bit < nbits; ++i, bit += 5) - { - /* set v to the 16-bit value starting at src[bits/8], 0-padded. */ - v = ((quint8) src[bit / 8]) << 8; - if (bit + 5 < nbits) - v += (quint8) src[(bit/8)+1]; - - /* set u to the 5-bit value at the bit'th bit of src. */ - u = (v >> (11 - (bit % 8))) & 0x1F; - dest[i] = BASE32_CHARS[u]; - } - - dest[i] = '\0'; -} - -/* Implements base32 decoding as in rfc3548. Requires that srclen*5 is a multiple of 8. */ -bool base32_decode(char *dest, unsigned destlen, const char *src, unsigned srclen) -{ - unsigned int i, j, bit; - unsigned nbits = srclen * 5; - - /* We need an even multiple of 8 bits, and enough space */ - if ((nbits%8) != 0 || (nbits/8)+1 > destlen) { - Q_ASSERT(false); - return false; - } - - char *tmp = new char[srclen]; - - /* Convert base32 encoded chars to the 5-bit values that they represent. */ - for (j = 0; j < srclen; ++j) - { - if (src[j] > 0x60 && src[j] < 0x7B) - tmp[j] = src[j] - 0x61; - else if (src[j] > 0x31 && src[j] < 0x38) - tmp[j] = src[j] - 0x18; - else if (src[j] > 0x40 && src[j] < 0x5B) - tmp[j] = src[j] - 0x41; - else - { - delete[] tmp; - return false; - } - } - - /* Assemble result byte-wise by applying five possible cases. */ - for (i = 0, bit = 0; bit < nbits; ++i, bit += 8) - { - switch (bit % 40) - { - case 0: - dest[i] = (((quint8)tmp[(bit/5)]) << 3) + (((quint8)tmp[(bit/5)+1]) >> 2); - break; - case 8: - dest[i] = (((quint8)tmp[(bit/5)]) << 6) + (((quint8)tmp[(bit/5)+1]) << 1) - + (((quint8)tmp[(bit/5)+2]) >> 4); - break; - case 16: - dest[i] = (((quint8)tmp[(bit/5)]) << 4) + (((quint8)tmp[(bit/5)+1]) >> 1); - break; - case 24: - dest[i] = (((quint8)tmp[(bit/5)]) << 7) + (((quint8)tmp[(bit/5)+1]) << 2) - + (((quint8)tmp[(bit/5)+2]) >> 3); - break; - case 32: - dest[i] = (((quint8)tmp[(bit/5)]) << 5) + ((quint8)tmp[(bit/5)+1]); - break; - } - } - - delete[] tmp; - return true; -} - -#endif diff --git a/retroshare-gui/src/TorControl/CryptoKey.h b/retroshare-gui/src/TorControl/CryptoKey.h deleted file mode 100644 index c99703444..000000000 --- a/retroshare-gui/src/TorControl/CryptoKey.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CRYPTOKEY_H -#define CRYPTOKEY_H - -#include -#include -#include - -class CryptoKey -{ -public: - enum KeyType { - PrivateKey, - PublicKey - }; - - enum KeyFormat { - PEM, - DER - }; - - CryptoKey(); - ~CryptoKey(); - -#ifdef TO_REMOVE - bool loadFromData(const QByteArray &data, KeyType type, KeyFormat format = PEM); - bool loadFromFile(const QString &path, KeyType type, KeyFormat format = PEM); -#endif - bool loadFromFile(const QString &path); - void clear(); - - const QByteArray bytes() const { return key_data; } - bool loadFromTorMessage(const QByteArray& b); - bool isLoaded() const { return !key_data.isNull(); } -#ifdef TO_REMOVE - bool isPrivate() const; - - QByteArray publicKeyDigest() const; - QByteArray encodedPublicKey(KeyFormat format) const; - QByteArray encodedPrivateKey(KeyFormat format) const; - QString torServiceID() const; - int bits() const; - - // Calculate and sign SHA-256 digest of data using this key and PKCS #1 v2.0 padding - QByteArray signData(const QByteArray &data) const; - // Verify a signature as per signData - bool verifyData(const QByteArray &data, QByteArray signature) const; - - // Sign the input SHA-256 digest using this key and PKCS #1 v2.0 padding - QByteArray signSHA256(const QByteArray &digest) const; - // Verify a signature as per signSHA256 - bool verifySHA256(const QByteArray &digest, QByteArray signature) const; -#endif - -private: -#ifdef TO_REMOVE - struct Data : public QSharedData - { - typedef struct rsa_st RSA; - RSA *key; - - Data(RSA *k = 0) : key(k) { } - ~Data(); - }; -#endif - - QByteArray key_data; -#ifdef TO_REMOVE - QExplicitlySharedDataPointer d; -#endif -}; - -QByteArray torControlHashedPassword(const QByteArray &password); - -#endif // CRYPTOKEY_H diff --git a/retroshare-gui/src/TorControl/GetConfCommand.cpp b/retroshare-gui/src/TorControl/GetConfCommand.cpp deleted file mode 100644 index 933def562..000000000 --- a/retroshare-gui/src/TorControl/GetConfCommand.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "GetConfCommand.h" -#include "StrUtil.h" -#include - -using namespace Tor; - -GetConfCommand::GetConfCommand(Type t) - : type(t) -{ -} - -QByteArray GetConfCommand::build(const QByteArray &key) -{ - return build(QList() << key); -} - -QByteArray GetConfCommand::build(const QList &keys) -{ - QByteArray out; - if (type == GetConf) { - out = "GETCONF"; - } else if (type == GetInfo) { - out = "GETINFO"; - } else { - Q_ASSERT(false); - return out; - } - - foreach (const QByteArray &key, keys) { - out.append(' '); - out.append(key); - } - - out.append("\r\n"); - return out; -} - -void GetConfCommand::onReply(int statusCode, const QByteArray &data) -{ - TorControlCommand::onReply(statusCode, data); - if (statusCode != 250) - return; - - int kep = data.indexOf('='); - QString key = QString::fromLatin1(data.mid(0, kep)); - QVariant value; - if (kep >= 0) - value = QString::fromLatin1(unquotedString(data.mid(kep + 1))); - - m_lastKey = key; - QVariantMap::iterator it = m_results.find(key); - if (it != m_results.end()) { - // Make a list of values - QVariantList results = it->toList(); - if (results.isEmpty()) - results.append(*it); - results.append(value); - *it = QVariant(results); - } else { - m_results.insert(key, value); - } -} - -void GetConfCommand::onDataLine(const QByteArray &data) -{ - if (m_lastKey.isEmpty()) { - qWarning() << "torctrl: Unexpected data line in GetConf command"; - return; - } - - QVariantMap::iterator it = m_results.find(m_lastKey); - if (it != m_results.end()) { - QVariantList results = it->toList(); - if (results.isEmpty() && !it->toByteArray().isEmpty()) - results.append(*it); - results.append(data); - *it = QVariant(results); - } else { - m_results.insert(m_lastKey, QVariantList() << data); - } -} - -void GetConfCommand::onDataFinished() -{ - m_lastKey.clear(); -} - -QVariant GetConfCommand::get(const QByteArray &key) const -{ - return m_results.value(QString::fromLatin1(key)); -} - diff --git a/retroshare-gui/src/TorControl/GetConfCommand.h b/retroshare-gui/src/TorControl/GetConfCommand.h deleted file mode 100644 index 0de97d1b7..000000000 --- a/retroshare-gui/src/TorControl/GetConfCommand.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef GETCONFCOMMAND_H -#define GETCONFCOMMAND_H - -#include "TorControlCommand.h" -#include -#include - -namespace Tor -{ - -class GetConfCommand : public TorControlCommand -{ - Q_OBJECT - Q_DISABLE_COPY(GetConfCommand) - - Q_PROPERTY(QVariantMap results READ results CONSTANT) - -public: - enum Type { - GetConf, - GetInfo - }; - const Type type; - - GetConfCommand(Type type); - - QByteArray build(const QByteArray &key); - QByteArray build(const QList &keys); - - const QVariantMap &results() const { return m_results; } - QVariant get(const QByteArray &key) const; - -protected: - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onDataLine(const QByteArray &data); - virtual void onDataFinished(); - -private: - QVariantMap m_results; - QString m_lastKey; -}; - -} - -#endif // GETCONFCOMMAND_H diff --git a/retroshare-gui/src/TorControl/HiddenService.cpp b/retroshare-gui/src/TorControl/HiddenService.cpp deleted file mode 100644 index b2b58626a..000000000 --- a/retroshare-gui/src/TorControl/HiddenService.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "HiddenService.h" -#include "TorControl.h" -#include "TorSocket.h" -#include "CryptoKey.h" -#include "Useful.h" -#include -#include -#include -#include - -using namespace Tor; - -HiddenService::HiddenService(QObject *parent) - : QObject(parent), m_status(NotCreated) -{ -} - -HiddenService::HiddenService(const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) -{ - /* Set the initial status and, if possible, load the hostname */ - if (QDir(m_dataPath).exists(QLatin1String("private_key"))) { - loadPrivateKey(); - if (!m_hostname.isEmpty()) - m_status = Offline; - } -} - -HiddenService::HiddenService(const CryptoKey &privateKey, const QString &path, QObject *parent) - : QObject(parent), m_dataPath(path), m_status(NotCreated) -{ - setPrivateKey(privateKey); - m_status = Offline; -} - -void HiddenService::setStatus(Status newStatus) -{ - if (m_status == newStatus) - return; - - Status old = m_status; - m_status = newStatus; - - emit statusChanged(m_status, old); - - if (m_status == Online) - emit serviceOnline(); -} - -void HiddenService::addTarget(const Target &target) -{ - m_targets.append(target); -} - -void HiddenService::addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort) -{ - Target t = { targetAddress, servicePort, targetPort }; - m_targets.append(t); -} - -void HiddenService::setServiceId(const QByteArray& sid) -{ - m_service_id = sid; - m_hostname = sid + ".onion"; - - emit hostnameChanged(); -} -void HiddenService::setPrivateKey(const CryptoKey &key) -{ - if (m_privateKey.isLoaded()) { - BUG() << "Cannot change the private key on an existing HiddenService"; - return; - } - -#ifdef TO_REMOVE - if (!key.isPrivate()) { - BUG() << "Cannot create a hidden service with a public key"; - return; - } -#endif - - m_privateKey = key; - - emit privateKeyChanged(); -} - -void HiddenService::loadPrivateKey() -{ - if (m_privateKey.isLoaded() || m_dataPath.isEmpty()) - return; - - bool ok = m_privateKey.loadFromFile(m_dataPath + QLatin1String("/private_key")); - - if (!ok) { - qWarning() << "Failed to load hidden service key"; - return; - } - - emit privateKeyChanged(); -} - -void HiddenService::servicePublished() -{ - loadPrivateKey(); - - if (m_hostname.isEmpty()) { - std::cerr << "Failed to read hidden service hostname" << std::endl; - return; - } - - std::cerr << "Hidden service published successfully" << std::endl; - setStatus(Online); -} - diff --git a/retroshare-gui/src/TorControl/HiddenService.h b/retroshare-gui/src/TorControl/HiddenService.h deleted file mode 100644 index 20fa1d851..000000000 --- a/retroshare-gui/src/TorControl/HiddenService.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef HIDDENSERVICE_H -#define HIDDENSERVICE_H - -#include -#include -#include -#include "CryptoKey.h" - -namespace Tor -{ - -class TorSocket; - -class HiddenService : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(HiddenService) - - friend class TorControlPrivate; - -public: - struct Target - { - QHostAddress targetAddress; - quint16 servicePort, targetPort; - }; - - enum Status - { - NotCreated = -1, /* Service has not been created yet */ - Offline = 0, /* Data exists, but service is not published */ - Online /* Published */ - }; - - HiddenService(QObject *parent = 0); - HiddenService(const QString &dataPath, QObject *parent = 0); - HiddenService(const CryptoKey &privateKey, const QString &dataPath = QString(), QObject *parent = 0); - - Status status() const { return m_status; } - - const QString& hostname() const { return m_hostname; } - const QString serviceId() const { return QString(m_service_id); } - const QString& dataPath() const { return m_dataPath; } - - CryptoKey privateKey() { return m_privateKey; } - void setPrivateKey(const CryptoKey &privateKey); - void setServiceId(const QByteArray& sid); - - const QList &targets() const { return m_targets; } - void addTarget(const Target &target); - void addTarget(quint16 servicePort, QHostAddress targetAddress, quint16 targetPort); - -signals: - void statusChanged(int newStatus, int oldStatus); - void serviceOnline(); - void privateKeyChanged(); - void hostnameChanged(); - -private slots: - void servicePublished(); - -private: - QString m_dataPath; - QList m_targets; - QString m_hostname; - Status m_status; - CryptoKey m_privateKey; - QByteArray m_service_id; - - void loadPrivateKey(); - void setStatus(Status newStatus); -}; - -} - -#endif // HIDDENSERVICE_H diff --git a/retroshare-gui/src/TorControl/PendingOperation.cpp b/retroshare-gui/src/TorControl/PendingOperation.cpp deleted file mode 100644 index 4a11f3e75..000000000 --- a/retroshare-gui/src/TorControl/PendingOperation.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "PendingOperation.h" - -PendingOperation::PendingOperation(QObject *parent) - : QObject(parent), m_finished(false) -{ -} - -bool PendingOperation::isFinished() const -{ - return m_finished; -} - -bool PendingOperation::isSuccess() const -{ - return m_finished && m_errorMessage.isNull(); -} - -bool PendingOperation::isError() const -{ - return m_finished && !m_errorMessage.isNull(); -} - -QString PendingOperation::errorMessage() const -{ - return m_errorMessage; -} - -void PendingOperation::finishWithError(const QString &message) -{ - if (message.isEmpty()) - m_errorMessage = QStringLiteral("Unknown Error"); - m_errorMessage = message; - - if (!m_finished) { - m_finished = true; - emit finished(); - emit error(m_errorMessage); - } -} - -void PendingOperation::finishWithSuccess() -{ - Q_ASSERT(m_errorMessage.isNull()); - - if (!m_finished) { - m_finished = true; - emit finished(); - if (isSuccess()) - emit success(); - } -} - diff --git a/retroshare-gui/src/TorControl/PendingOperation.h b/retroshare-gui/src/TorControl/PendingOperation.h deleted file mode 100644 index 8f776a8d7..000000000 --- a/retroshare-gui/src/TorControl/PendingOperation.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PENDINGOPERATION_H -#define PENDINGOPERATION_H - -#include - -/* Represents an asynchronous operation for reporting status - * - * This class is used for asynchronous operations that report a - * status and errors when finished, particularly for exposing them - * to QML. - * - * Subclass PendingOperation to implement your operation's logic. - * You also need to handle the object's lifetime, for example by - * calling deleteLater() when finished() is emitted. - * - * PendingOperation will emit finished() and one of success() or - * error() when completed. - */ -class PendingOperation : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool isFinished READ isFinished NOTIFY finished FINAL) - Q_PROPERTY(bool isSuccess READ isSuccess NOTIFY success FINAL) - Q_PROPERTY(bool isError READ isError NOTIFY error FINAL) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY finished FINAL) - -public: - PendingOperation(QObject *parent = 0); - - bool isFinished() const; - bool isSuccess() const; - bool isError() const; - QString errorMessage() const; - -signals: - // Always emitted once when finished, regardless of status - void finished(); - - // One of error() or success() is emitted once - void error(const QString &errorMessage); - void success(); - -protected slots: - void finishWithError(const QString &errorMessage); - void finishWithSuccess(); - -private: - bool m_finished; - QString m_errorMessage; -}; - -Q_DECLARE_METATYPE(PendingOperation*) - -#endif diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp b/retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp deleted file mode 100644 index a365a5c4d..000000000 --- a/retroshare-gui/src/TorControl/ProtocolInfoCommand.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ProtocolInfoCommand.h" -#include "TorControl.h" -#include "StrUtil.h" -#include - -using namespace Tor; - -ProtocolInfoCommand::ProtocolInfoCommand(TorControl *m) - : manager(m) -{ -} - -QByteArray ProtocolInfoCommand::build() -{ - return QByteArray("PROTOCOLINFO 1\r\n"); -} - -void ProtocolInfoCommand::onReply(int statusCode, const QByteArray &data) -{ - TorControlCommand::onReply(statusCode, data); - if (statusCode != 250) - return; - - if (data.startsWith("AUTH ")) - { - QList tokens = splitQuotedStrings(data.mid(5), ' '); - - foreach (QByteArray token, tokens) - { - if (token.startsWith("METHODS=")) - { - QList textMethods = unquotedString(token.mid(8)).split(','); - for (QList::Iterator it = textMethods.begin(); it != textMethods.end(); ++it) - { - if (*it == "NULL") - m_authMethods |= AuthNull; - else if (*it == "HASHEDPASSWORD") - m_authMethods |= AuthHashedPassword; - else if (*it == "COOKIE") - m_authMethods |= AuthCookie; - } - } - else if (token.startsWith("COOKIEFILE=")) - { - m_cookieFile = QString::fromLatin1(unquotedString(token.mid(11))); - } - } - } - else if (data.startsWith("VERSION Tor=")) - { - m_torVersion = QString::fromLatin1(unquotedString(data.mid(12, data.indexOf(' ', 12)))); - } -} diff --git a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h b/retroshare-gui/src/TorControl/ProtocolInfoCommand.h deleted file mode 100644 index 7789cfefd..000000000 --- a/retroshare-gui/src/TorControl/ProtocolInfoCommand.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PROTOCOLINFOCOMMAND_H -#define PROTOCOLINFOCOMMAND_H - -#include "TorControlCommand.h" -#include - -namespace Tor -{ - -class TorControl; - -class ProtocolInfoCommand : public TorControlCommand -{ - Q_OBJECT - Q_DISABLE_COPY(ProtocolInfoCommand) - -public: - enum AuthMethod - { - AuthUnknown = 0, - AuthNull = 0x1, - AuthHashedPassword = 0x2, - AuthCookie = 0x4 - }; - Q_DECLARE_FLAGS(AuthMethods, AuthMethod) - - ProtocolInfoCommand(TorControl *manager); - QByteArray build(); - - AuthMethods authMethods() const { return m_authMethods; } - QString torVersion() const { return m_torVersion; } - QString cookieFile() const { return m_cookieFile; } - -protected: - virtual void onReply(int statusCode, const QByteArray &data); - -private: - TorControl *manager; - AuthMethods m_authMethods; - QString m_torVersion; - QString m_cookieFile; -}; - -} - -#endif // PROTOCOLINFOCOMMAND_H diff --git a/retroshare-gui/src/TorControl/SecureRNG.cpp b/retroshare-gui/src/TorControl/SecureRNG.cpp deleted file mode 100644 index 60cf3c048..000000000 --- a/retroshare-gui/src/TorControl/SecureRNG.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SecureRNG.h" -#include -#include -#include -#include - -#ifdef Q_OS_WIN -#include -#include -#endif - -#if QT_VERSION >= 0x040700 -#include -#endif - -bool SecureRNG::seed() -{ -#if QT_VERSION >= 0x040700 - QElapsedTimer timer; - timer.start(); -#endif - -#ifdef Q_OS_WIN - /* RAND_poll is very unreliable on windows; with older versions of OpenSSL, - * it can take up to several minutes to run and has been known to crash. - * Even newer versions seem to take around 400ms, which is far too long for - * interactive startup. Random data from the windows CSP is used as a seed - * instead, as it should be very high quality random and fast. */ - HCRYPTPROV provider = 0; - if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { - qWarning() << "Failed to acquire CSP context for RNG seed:" << hex << GetLastError(); - return false; - } - - /* Same amount of entropy OpenSSL uses, apparently. */ - char buf[32]; - - if (!CryptGenRandom(provider, sizeof(buf), reinterpret_cast(buf))) - { - qWarning() << "Failed to get entropy from CSP for RNG seed: " << hex << GetLastError(); - CryptReleaseContext(provider, 0); - return false; - } - - CryptReleaseContext(provider, 0); - - RAND_seed(buf, sizeof(buf)); - memset(buf, 0, sizeof(buf)); -#else - if (!RAND_poll()) - { - qWarning() << "OpenSSL RNG seed failed:" << ERR_get_error(); - return false; - } -#endif - -#if QT_VERSION >= 0x040700 - qDebug() << "RNG seed took" << timer.elapsed() << "ms"; -#endif - - return true; -} - -void SecureRNG::random(char *buf, int size) -{ - int r = RAND_bytes(reinterpret_cast(buf), size); - if (r <= 0) - qFatal("RNG failed: %lu", ERR_get_error()); -} - -QByteArray SecureRNG::random(int size) -{ - QByteArray re(size, 0); - random(re.data(), size); - return re; -} - -QByteArray SecureRNG::randomPrintable(int length) -{ - QByteArray re(length, 0); - for (int i = 0; i < re.size(); i++) - re[i] = randomInt(95) + 32; - return re; -} - -unsigned SecureRNG::randomInt(unsigned max) -{ - unsigned cutoff = UINT_MAX - (UINT_MAX % max); - unsigned value = 0; - - for (;;) - { - random(reinterpret_cast(&value), sizeof(value)); - if (value < cutoff) - return value % max; - } -} - -#ifndef UINT64_MAX -#define UINT64_MAX ((quint64)-1) -#endif - -quint64 SecureRNG::randomInt64(quint64 max) -{ - quint64 cutoff = UINT64_MAX - (UINT64_MAX % max); - quint64 value = 0; - - for (;;) - { - random(reinterpret_cast(value), sizeof(value)); - if (value < cutoff) - return value % max; - } -} diff --git a/retroshare-gui/src/TorControl/SecureRNG.h b/retroshare-gui/src/TorControl/SecureRNG.h deleted file mode 100644 index f3b2a4b64..000000000 --- a/retroshare-gui/src/TorControl/SecureRNG.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SECURERNG_H -#define SECURERNG_H - -#include - -class SecureRNG -{ -public: - static bool seed(); - - static void random(char *buf, int size); - static QByteArray random(int size); - - static QByteArray randomPrintable(int length); - static unsigned randomInt(unsigned max); - static quint64 randomInt64(quint64 max); -}; - -#endif // SECURERNG_H diff --git a/retroshare-gui/src/TorControl/SetConfCommand.cpp b/retroshare-gui/src/TorControl/SetConfCommand.cpp deleted file mode 100644 index f13a9fdef..000000000 --- a/retroshare-gui/src/TorControl/SetConfCommand.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "SetConfCommand.h" -#include "StrUtil.h" - -using namespace Tor; - -SetConfCommand::SetConfCommand() - : m_resetMode(false) -{ -} - -void SetConfCommand::setResetMode(bool enabled) -{ - m_resetMode = enabled; -} - -bool SetConfCommand::isSuccessful() const -{ - return statusCode() == 250; -} - -QByteArray SetConfCommand::build(const QByteArray &key, const QByteArray &value) -{ - return build(QList >() << qMakePair(key, value)); -} - -QByteArray SetConfCommand::build(const QVariantMap &data) -{ - QList > out; - - for (QVariantMap::ConstIterator it = data.begin(); it != data.end(); it++) { - QByteArray key = it.key().toLatin1(); - - if (static_cast(it.value().type()) == QMetaType::QVariantList) { - QVariantList values = it.value().value(); - foreach (const QVariant &value, values) - out.append(qMakePair(key, value.toString().toLatin1())); - } else { - out.append(qMakePair(key, it.value().toString().toLatin1())); - } - } - - return build(out); -} - -QByteArray SetConfCommand::build(const QList > &data) -{ - QByteArray out(m_resetMode ? "RESETCONF" : "SETCONF"); - - for (int i = 0; i < data.size(); i++) { - out += " " + data[i].first; - if (!data[i].second.isEmpty()) - out += "=" + quotedString(data[i].second); - } - - out.append("\r\n"); - return out; -} - -void SetConfCommand::onReply(int statusCode, const QByteArray &data) -{ - TorControlCommand::onReply(statusCode, data); - if (statusCode != 250) - m_errorMessage = QString::fromLatin1(data); -} - -void SetConfCommand::onFinished(int statusCode) -{ - TorControlCommand::onFinished(statusCode); - if (isSuccessful()) - emit setConfSucceeded(); - else - emit setConfFailed(statusCode); -} - diff --git a/retroshare-gui/src/TorControl/SetConfCommand.h b/retroshare-gui/src/TorControl/SetConfCommand.h deleted file mode 100644 index 5bdcb9329..000000000 --- a/retroshare-gui/src/TorControl/SetConfCommand.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SETCONFCOMMAND_H -#define SETCONFCOMMAND_H - -#include "TorControlCommand.h" -#include -#include -#include - -namespace Tor -{ - -class SetConfCommand : public TorControlCommand -{ - Q_OBJECT - Q_DISABLE_COPY(SetConfCommand) - - Q_PROPERTY(QString errorMessage READ errorMessage CONSTANT) - Q_PROPERTY(bool successful READ isSuccessful CONSTANT) - -public: - SetConfCommand(); - - void setResetMode(bool resetMode); - - QByteArray build(const QByteArray &key, const QByteArray &value); - QByteArray build(const QVariantMap &data); - QByteArray build(const QList > &data); - - QString errorMessage() const { return m_errorMessage; } - bool isSuccessful() const; - -signals: - void setConfSucceeded(); - void setConfFailed(int code); - -protected: - QString m_errorMessage; - bool m_resetMode; - - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onFinished(int statusCode); -}; - -} - -#endif // SETCONFCOMMAND_H diff --git a/retroshare-gui/src/TorControl/Settings.cpp b/retroshare-gui/src/TorControl/Settings.cpp deleted file mode 100644 index b20d330b7..000000000 --- a/retroshare-gui/src/TorControl/Settings.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "Settings.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SettingsFilePrivate : public QObject -{ - Q_OBJECT - -public: - SettingsFile *q; - QString filePath; - QString errorMessage; - QTimer syncTimer; - QJsonObject jsonRoot; - SettingsObject *rootObject; - - SettingsFilePrivate(SettingsFile *qp); - virtual ~SettingsFilePrivate(); - - void reset(); - void setError(const QString &message); - bool checkDirPermissions(const QString &path); - bool readFile(); - bool writeFile(); - - static QStringList splitPath(const QString &input, bool &ok); - QJsonValue read(const QJsonObject &base, const QStringList &path); - bool write(const QStringList &path, const QJsonValue &value); - -signals: - void modified(const QStringList &path, const QJsonValue &value); - -private slots: - void sync(); -}; - -SettingsFile::SettingsFile(QObject *parent) - : QObject(parent), d(new SettingsFilePrivate(this)) -{ - d->rootObject = new SettingsObject(this, QString()); -} - -SettingsFile::~SettingsFile() -{ -} - -SettingsFilePrivate::SettingsFilePrivate(SettingsFile *qp) - : QObject(qp) - , q(qp) - , rootObject(0) -{ - syncTimer.setInterval(0); - syncTimer.setSingleShot(true); - connect(&syncTimer, &QTimer::timeout, this, &SettingsFilePrivate::sync); -} - -SettingsFilePrivate::~SettingsFilePrivate() -{ - if (syncTimer.isActive()) - sync(); - delete rootObject; -} - -void SettingsFilePrivate::reset() -{ - filePath.clear(); - errorMessage.clear(); - - jsonRoot = QJsonObject(); - emit modified(QStringList(), jsonRoot); -} - -QString SettingsFile::filePath() const -{ - return d->filePath; -} - -bool SettingsFile::setFilePath(const QString &filePath) -{ - if (d->filePath == filePath) - return hasError(); - - d->reset(); - d->filePath = filePath; - - QFileInfo fileInfo(filePath); - QDir dir(fileInfo.path()); - if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) { - d->setError(QStringLiteral("Cannot create directory: %1").arg(dir.path())); - return false; - } - d->checkDirPermissions(fileInfo.path()); - - if (!d->readFile()) - return false; - - return true; -} - -QString SettingsFile::errorMessage() const -{ - return d->errorMessage; -} - -bool SettingsFile::hasError() const -{ - return !d->errorMessage.isEmpty(); -} - -void SettingsFilePrivate::setError(const QString &message) -{ - errorMessage = message; - emit q->error(); -} - -bool SettingsFilePrivate::checkDirPermissions(const QString &path) -{ - static QFile::Permissions desired = QFileDevice::ReadUser | QFileDevice::WriteUser | QFileDevice::ExeUser; - static QFile::Permissions ignored = QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner; - - QFile file(path); - if ((file.permissions() & ~ignored) != desired) { - qDebug() << "Correcting permissions on configuration directory"; - if (!file.setPermissions(desired)) { - qWarning() << "Correcting permissions on configuration directory failed"; - return false; - } - } - - return true; -} - -SettingsObject *SettingsFile::root() -{ - return d->rootObject; -} - -const SettingsObject *SettingsFile::root() const -{ - return d->rootObject; -} - -void SettingsFilePrivate::sync() -{ - if (filePath.isEmpty()) - return; - - syncTimer.stop(); - writeFile(); -} - -bool SettingsFilePrivate::readFile() -{ - QFile file(filePath); - if (!file.open(QIODevice::ReadWrite)) { - setError(file.errorString()); - return false; - } - - QByteArray data = file.readAll(); - if (data.isEmpty() && (file.error() != QFileDevice::NoError || file.size() > 0)) { - setError(file.errorString()); - return false; - } - - if (data.isEmpty()) { - jsonRoot = QJsonObject(); - return true; - } - - QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(data, &parseError); - if (document.isNull()) { - setError(parseError.errorString()); - return false; - } - - if (!document.isObject()) { - setError(QStringLiteral("Invalid configuration file (expected object)")); - return false; - } - - jsonRoot = document.object(); - - emit modified(QStringList(), jsonRoot); - return true; -} - -bool SettingsFilePrivate::writeFile() -{ - QSaveFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { - setError(file.errorString()); - return false; - } - - QJsonDocument document(jsonRoot); - QByteArray data = document.toJson(); - if (data.isEmpty() && !document.isEmpty()) { - setError(QStringLiteral("Encoding failure")); - return false; - } - - if (file.write(data) < data.size() || !file.commit()) { - setError(file.errorString()); - return false; - } - - return true; -} - -QStringList SettingsFilePrivate::splitPath(const QString &input, bool &ok) -{ - QStringList components = input.split(QLatin1Char('.')); - - // Allow a leading '.' to simplify concatenation - if (!components.isEmpty() && components.first().isEmpty()) - components.takeFirst(); - - // No other empty components, including a trailing . - foreach (const QString &word, components) { - if (word.isEmpty()) { - ok = false; - return QStringList(); - } - } - - ok = true; - return components; -} - -QJsonValue SettingsFilePrivate::read(const QJsonObject &base, const QStringList &path) -{ - QJsonValue current = base; - - foreach (const QString &key, path) { - QJsonObject object = current.toObject(); - if (object.isEmpty() || (current = object.value(key)).isUndefined()) - return QJsonValue::Undefined; - } - - return current; -} - -// Compare two QJsonValue to find keys that have changed, -// recursing into objects and building paths as necessary. -typedef QList > ModifiedList; -static void findModifiedRecursive(ModifiedList &modified, const QStringList &path, const QJsonValue &oldValue, const QJsonValue &newValue) -{ - if (oldValue.isObject() || newValue.isObject()) { - // If either is a non-object type, this returns an empty object - QJsonObject oldObject = oldValue.toObject(); - QJsonObject newObject = newValue.toObject(); - - // Iterate keys of the original object and compare to new - for (QJsonObject::iterator it = oldObject.begin(); it != oldObject.end(); it++) { - QJsonValue newSubValue = newObject.value(it.key()); - if (*it == newSubValue) - continue; - - if ((*it).isObject() || newSubValue.isObject()) - findModifiedRecursive(modified, QStringList() << path << it.key(), *it, newSubValue); - else - modified.append(qMakePair(QStringList() << path << it.key(), newSubValue)); - } - - // Iterate keys of the new object that may not be in original - for (QJsonObject::iterator it = newObject.begin(); it != newObject.end(); it++) { - if (oldObject.contains(it.key())) - continue; - - if ((*it).isObject()) - findModifiedRecursive(modified, QStringList() << path << it.key(), QJsonValue::Undefined, it.value()); - else - modified.append(qMakePair(QStringList() << path << it.key(), it.value())); - } - } else - modified.append(qMakePair(path, newValue)); -} - -bool SettingsFilePrivate::write(const QStringList &path, const QJsonValue &value) -{ - typedef QVarLengthArray > ObjectStack; - ObjectStack stack; - QJsonValue current = jsonRoot; - QJsonValue originalValue; - QString currentKey; - - foreach (const QString &key, path) { - const QJsonObject &parent = current.toObject(); - stack.append(qMakePair(currentKey, parent)); - current = parent.value(key); - currentKey = key; - } - - // Stack now contains parent objects starting with the root, and current - // is the old value. Write back changes in reverse. - if (current == value) - return false; - originalValue = current; - current = value; - - ObjectStack::const_iterator it = stack.end(), begin = stack.begin(); - while (it != begin) { - --it; - QJsonObject update = it->second; - update.insert(currentKey, current); - current = update; - currentKey = it->first; - } - - // current is now the updated jsonRoot - jsonRoot = current.toObject(); - syncTimer.start(); - - ModifiedList modified; - findModifiedRecursive(modified, path, originalValue, value); - - for (ModifiedList::iterator it = modified.begin(); it != modified.end(); it++) - emit this->modified(it->first, it->second); - - return true; -} - -class SettingsObjectPrivate : public QObject -{ - Q_OBJECT - -public: - explicit SettingsObjectPrivate(SettingsObject *q); - - SettingsObject *q; - SettingsFile *file; - QStringList path; - QJsonObject object; - bool invalid; - - void setFile(SettingsFile *file); - -public slots: - void modified(const QStringList &absolutePath, const QJsonValue &value); -}; - -SettingsObject::SettingsObject(QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(defaultFile()); - if (d->file) - setPath(QString()); -} - -SettingsObject::SettingsObject(const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(defaultFile()); - setPath(path); -} - -SettingsObject::SettingsObject(SettingsFile *file, const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(file); - setPath(path); -} - -SettingsObject::SettingsObject(SettingsObject *base, const QString &path, QObject *parent) - : QObject(parent) - , d(new SettingsObjectPrivate(this)) -{ - d->setFile(base->d->file); - setPath(base->path() + QLatin1Char('.') + path); -} - -SettingsObjectPrivate::SettingsObjectPrivate(SettingsObject *qp) - : QObject(qp) - , q(qp) - , file(0) - , invalid(true) -{ -} - -void SettingsObjectPrivate::setFile(SettingsFile *value) -{ - if (file == value) - return; - - if (file) - disconnect(file, 0, this, 0); - file = value; - if (file) - connect(file->d, &SettingsFilePrivate::modified, this, &SettingsObjectPrivate::modified); -} - -// Emit SettingsObject::modified with a relative path if path is matched -void SettingsObjectPrivate::modified(const QStringList &key, const QJsonValue &value) -{ - if (key.size() < path.size()) - return; - - for (int i = 0; i < path.size(); i++) { - if (path[i] != key[i]) - return; - } - - object = file->d->read(file->d->jsonRoot, path).toObject(); - emit q->modified(QStringList(key.mid(path.size())).join(QLatin1Char('.')), value); - emit q->dataChanged(); -} - -static QPointer defaultObjectFile; - -SettingsFile *SettingsObject::defaultFile() -{ - return defaultObjectFile; -} - -void SettingsObject::setDefaultFile(SettingsFile *file) -{ - defaultObjectFile = file; -} - -QString SettingsObject::path() const -{ - return d->path.join(QLatin1Char('.')); -} - -void SettingsObject::setPath(const QString &input) -{ - bool ok = false; - QStringList newPath = SettingsFilePrivate::splitPath(input, ok); - if (!ok) { - d->invalid = true; - d->path.clear(); - d->object = QJsonObject(); - - emit pathChanged(); - emit dataChanged(); - return; - } - - if (!d->invalid && d->path == newPath) - return; - - d->path = newPath; - if (d->file) { - d->invalid = false; - d->object = d->file->d->read(d->file->d->jsonRoot, d->path).toObject(); - emit dataChanged(); - } - - emit pathChanged(); -} - -QJsonObject SettingsObject::data() const -{ - return d->object; -} - -void SettingsObject::setData(const QJsonObject &input) -{ - if (d->invalid || d->object == input) - return; - - d->object = input; - d->file->d->write(d->path, d->object); -} - -QJsonValue SettingsObject::read(const QString &key, const QJsonValue &defaultValue) const -{ - bool ok = false; - QStringList splitKey = SettingsFilePrivate::splitPath(key, ok); - if (d->invalid || !ok || splitKey.isEmpty()) { - qDebug() << "Invalid settings read of path" << key; - return defaultValue; - } - - QJsonValue ret = d->file->d->read(d->object, splitKey); - if (ret.isUndefined()) - ret = defaultValue; - return ret; -} - -void SettingsObject::write(const QString &key, const QJsonValue &value) -{ - bool ok = false; - QStringList splitKey = SettingsFilePrivate::splitPath(key, ok); - if (d->invalid || !ok || splitKey.isEmpty()) { - qDebug() << "Invalid settings write of path" << key; - return; - } - - splitKey = d->path + splitKey; - d->file->d->write(splitKey, value); -} - -void SettingsObject::unset(const QString &key) -{ - write(key, QJsonValue()); -} - -void SettingsObject::undefine() -{ - if (d->invalid) - return; - - d->object = QJsonObject(); - d->file->d->write(d->path, QJsonValue::Undefined); -} - -#include "Settings.moc" diff --git a/retroshare-gui/src/TorControl/Settings.h b/retroshare-gui/src/TorControl/Settings.h deleted file mode 100644 index 79ad032d1..000000000 --- a/retroshare-gui/src/TorControl/Settings.h +++ /dev/null @@ -1,257 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include -#include -#include -#include -#include -#include - -class SettingsObject; -class SettingsFilePrivate; -class SettingsObjectPrivate; - -/* SettingsFile represents a JSON-encoded configuration file. - * - * SettingsFile is an API for reading, writing, and change notification - * on JSON-encoded settings files. - * - * Data is accessed via SettingsObject, either using the root property - * or by creating a SettingsObject, optionally using a base path. - */ -class SettingsFile : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(SettingsFile) - - Q_PROPERTY(SettingsObject *root READ root CONSTANT) - Q_PROPERTY(QString filePath READ filePath WRITE setFilePath NOTIFY filePathChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY error) - Q_PROPERTY(bool hasError READ hasError NOTIFY error) - -public: - explicit SettingsFile(QObject *parent = 0); - virtual ~SettingsFile(); - - QString filePath() const; - bool setFilePath(const QString &filePath); - - QString errorMessage() const; - bool hasError() const; - - SettingsObject *root(); - const SettingsObject *root() const; - -signals: - void filePathChanged(); - void error(); - -private: - SettingsFilePrivate *d; - - friend class SettingsObject; - friend class SettingsObjectPrivate; -}; - -/* SettingsObject reads and writes data within a SettingsFile - * - * A SettingsObject is associated with a SettingsFile and represents an object - * tree within that file. It refers to the JSON object tree using a path - * notation with keys separated by '.'. For example: - * - * { - * "one": { - * "two": { - * "three": "value" - * } - * } - * } - * - * With this data, a SettingsObject with an empty path can read with the path - * "one.two.three", and a SettingsObject with a path of "one.two" can simply - * read or write on "three". - * - * Multiple SettingsObjects may be created for the same path, and will be kept - * synchronized with changes. The modified signal is emitted for all changes - * affecting keys within a path, including writes of object trees and from other - * instances. - */ -class SettingsObject : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(SettingsObject) - - Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged) - Q_PROPERTY(QJsonObject data READ data WRITE setData NOTIFY dataChanged) - -public: - explicit SettingsObject(QObject *parent = 0); - explicit SettingsObject(const QString &path, QObject *parent = 0); - explicit SettingsObject(SettingsFile *file, const QString &path, QObject *parent = 0); - explicit SettingsObject(SettingsObject *base, const QString &path, QObject *parent = 0); - - /* Specify a SettingsFile to use by default on SettingsObject instances. - * - * After calling setDefaultFile, a SettingsObject created without any file, e.g.: - * - * SettingsObject settings; - * SettingsObject animals(QStringLiteral("animals")); - * - * Will use the specified SettingsFile instance by default. This is a convenience - * over passing around instances of SettingsFile in application use cases, and is - * particularly useful for QML. - */ - static SettingsFile *defaultFile(); - static void setDefaultFile(SettingsFile *file); - - QString path() const; - void setPath(const QString &path); - - QJsonObject data() const; - void setData(const QJsonObject &data); - - Q_INVOKABLE QJsonValue read(const QString &key, const QJsonValue &defaultValue = QJsonValue::Undefined) const; - template T read(const QString &key) const; - Q_INVOKABLE void write(const QString &key, const QJsonValue &value); - template void write(const QString &key, const T &value); - Q_INVOKABLE void unset(const QString &key); - - // const char* key overloads - QJsonValue read(const char *key, const QJsonValue &defaultValue = QJsonValue::Undefined) const - { - return read(QString::fromLatin1(key), defaultValue); - } - template T read(const char *key) const - { - return read(QString::fromLatin1(key)); - } - void write(const char *key, const QJsonValue &value) - { - write(QString::fromLatin1(key), value); - } - template void write(const char *key, const T &value) - { - write(QString::fromLatin1(key), value); - } - void unset(const char *key) - { - unset(QString::fromLatin1(key)); - } - - Q_INVOKABLE void undefine(); - -signals: - void pathChanged(); - void dataChanged(); - - void modified(const QString &path, const QJsonValue &value); - -private: - SettingsObjectPrivate *d; -}; - -template inline void SettingsObject::write(const QString &key, const T &value) -{ - write(key, QJsonValue(value)); -} - -template<> inline QString SettingsObject::read(const QString &key) const -{ - return read(key).toString(); -} - -template<> inline QJsonArray SettingsObject::read(const QString &key) const -{ - return read(key).toArray(); -} - -template<> inline QJsonObject SettingsObject::read(const QString &key) const -{ - return read(key).toObject(); -} - -template<> inline double SettingsObject::read(const QString &key) const -{ - return read(key).toDouble(); -} - -template<> inline int SettingsObject::read(const QString &key) const -{ - return read(key).toInt(); -} - -template<> inline bool SettingsObject::read(const QString &key) const -{ - return read(key).toBool(); -} - -template<> inline QDateTime SettingsObject::read(const QString &key) const -{ - QString value = read(key).toString(); - if (value.isEmpty()) - return QDateTime(); - return QDateTime::fromString(value, Qt::ISODate).toLocalTime(); -} - -template<> inline void SettingsObject::write(const QString &key, const QDateTime &value) -{ - write(key, QJsonValue(value.toUTC().toString(Qt::ISODate))); -} - -// Explicitly store value encoded as base64. Decodes and casts implicitly to QByteArray for reads. -class Base64Encode -{ -public: - explicit Base64Encode(const QByteArray &value) : d(value) { } - operator QByteArray() { return d; } - QByteArray encoded() const { return d.toBase64(); } - -private: - QByteArray d; -}; - -template<> inline Base64Encode SettingsObject::read(const QString &key) const -{ - return Base64Encode(QByteArray::fromBase64(read(key).toString().toLatin1())); -} - -template<> inline void SettingsObject::write(const QString &key, const Base64Encode &value) -{ - write(key, QJsonValue(QString::fromLatin1(value.encoded()))); -} - -#endif - diff --git a/retroshare-gui/src/TorControl/StrUtil.cpp b/retroshare-gui/src/TorControl/StrUtil.cpp deleted file mode 100644 index 81de151b0..000000000 --- a/retroshare-gui/src/TorControl/StrUtil.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "StrUtil.h" - -QByteArray quotedString(const QByteArray &string) -{ - QByteArray out; - out.reserve(string.size() * 2); - - out.append('"'); - - for (int i = 0; i < string.size(); ++i) - { - switch (string[i]) - { - case '"': - out.append("\\\""); - break; - case '\\': - out.append("\\\\"); - break; - default: - out.append(string[i]); - break; - } - } - - out.append('"'); - return out; -} - -QByteArray unquotedString(const QByteArray &string) -{ - if (string.size() < 2 || string[0] != '"') - return string; - - QByteArray out; - out.reserve(string.size() - 2); - - for (int i = 1; i < string.size(); ++i) - { - switch (string[i]) - { - case '\\': - if (++i < string.size()) - out.append(string[i]); - break; - case '"': - return out; - default: - out.append(string[i]); - } - } - - return out; -} - -QList splitQuotedStrings(const QByteArray &input, char separator) -{ - QList out; - bool inquote = false; - int start = 0; - - for (int i = 0; i < input.size(); ++i) - { - switch (input[i]) - { - case '"': - inquote = !inquote; - break; - case '\\': - if (inquote) - ++i; - break; - } - - if (!inquote && input[i] == separator) - { - out.append(input.mid(start, i - start)); - start = i+1; - } - } - - if (start < input.size()) - out.append(input.mid(start)); - - return out; -} diff --git a/retroshare-gui/src/TorControl/StrUtil.h b/retroshare-gui/src/TorControl/StrUtil.h deleted file mode 100644 index c86d2c6ec..000000000 --- a/retroshare-gui/src/TorControl/StrUtil.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef STRINGUTIL_H -#define STRINGUTIL_H - -#include -#include - -QByteArray quotedString(const QByteArray &string); - -/* Return the unquoted contents of a string, either until an end quote or an unescaped separator character. */ -QByteArray unquotedString(const QByteArray &string); - -QList splitQuotedStrings(const QByteArray &input, char separator); - -#endif // STRINGUTIL_H diff --git a/retroshare-gui/src/TorControl/TorControl.cpp b/retroshare-gui/src/TorControl/TorControl.cpp deleted file mode 100644 index 29979e2b3..000000000 --- a/retroshare-gui/src/TorControl/TorControl.cpp +++ /dev/null @@ -1,788 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "TorControl.h" -#include "TorControlSocket.h" -#include "HiddenService.h" -#include "ProtocolInfoCommand.h" -#include "AuthenticateCommand.h" -#include "SetConfCommand.h" -#include "GetConfCommand.h" -#include "AddOnionCommand.h" -#include "StrUtil.h" -#include "Settings.h" -#include "PendingOperation.h" -#include -#include -#include -//#include -#include -#include -#include -#include - -Tor::TorControl *torControl = 0; - -class nullstream: public std::ostream {}; - -static std::ostream& torctrldebug() -{ - static nullstream null ; - - if(true) - return std::cerr << time(NULL) << ":TOR CONTROL: " ; - else - return null ; -} - -#define torCtrlDebug torctrldebug - - -using namespace Tor; - -namespace Tor { - -class TorControlPrivate : public QObject -{ - Q_OBJECT - -public: - TorControl *q; - - TorControlSocket *socket; - QHostAddress torAddress; - QString errorMessage; - QString torVersion; - QByteArray authPassword; - QHostAddress socksAddress; - QList services; - quint16 controlPort, socksPort; - TorControl::Status status; - TorControl::TorStatus torStatus; - QVariantMap bootstrapStatus; - bool hasOwnership; - - TorControlPrivate(TorControl *parent); - - void setStatus(TorControl::Status status); - void setTorStatus(TorControl::TorStatus status); - - void getTorInfo(); - void publishServices(); - -public slots: - void socketConnected(); - void socketDisconnected(); - void socketError(); - - void authenticateReply(); - void protocolInfoReply(); - void getTorInfoReply(); - void setError(const QString &message); - - void statusEvent(int code, const QByteArray &data); - void updateBootstrap(const QList &data); -}; - -} - -TorControl::TorControl(QObject *parent) - : QObject(parent), d(new TorControlPrivate(this)) -{ -} - -TorControlPrivate::TorControlPrivate(TorControl *parent) - : QObject(parent), q(parent), controlPort(0), socksPort(0), - status(TorControl::NotConnected), torStatus(TorControl::TorUnknown), - hasOwnership(false) -{ - socket = new TorControlSocket(this); - QObject::connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); - QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); - QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError())); - QObject::connect(socket, SIGNAL(error(QString)), this, SLOT(setError(QString))); -} - -QNetworkProxy TorControl::connectionProxy() -{ - return QNetworkProxy(QNetworkProxy::Socks5Proxy, d->socksAddress.toString(), d->socksPort); -} - -void TorControlPrivate::setStatus(TorControl::Status n) -{ - if (n == status) - return; - - TorControl::Status old = status; - status = n; - - if (old == TorControl::Error) - errorMessage.clear(); - - emit q->statusChanged(status, old); - - if (status == TorControl::Connected && old < TorControl::Connected) - emit q->connected(); - else if (status < TorControl::Connected && old >= TorControl::Connected) - emit q->disconnected(); -} - -void TorControlPrivate::setTorStatus(TorControl::TorStatus n) -{ - if (n == torStatus) - return; - - TorControl::TorStatus old = torStatus; - torStatus = n; - emit q->torStatusChanged(torStatus, old); - emit q->connectivityChanged(); - - if (torStatus == TorControl::TorReady && socksAddress.isNull()) { - // Request info again to read the SOCKS port - getTorInfo(); - } -} - -void TorControlPrivate::setError(const QString &message) -{ - errorMessage = message; - setStatus(TorControl::Error); - - qWarning() << "torctrl: Error:" << errorMessage; - - socket->abort(); - - QTimer::singleShot(15000, q, SLOT(reconnect())); -} - -TorControl::Status TorControl::status() const -{ - return d->status; -} - -TorControl::TorStatus TorControl::torStatus() const -{ - return d->torStatus; -} - -QString TorControl::torVersion() const -{ - return d->torVersion; -} - -QString TorControl::errorMessage() const -{ - return d->errorMessage; -} - -bool TorControl::hasConnectivity() const -{ - return torStatus() == TorReady && !d->socksAddress.isNull(); -} - -QHostAddress TorControl::socksAddress() const -{ - return d->socksAddress; -} - -quint16 TorControl::socksPort() const -{ - return d->socksPort; -} - -QList TorControl::hiddenServices() const -{ - return d->services; -} - -QVariantMap TorControl::bootstrapStatus() const -{ - return d->bootstrapStatus; -} - -void TorControl::setAuthPassword(const QByteArray &password) -{ - d->authPassword = password; -} - -void TorControl::connect(const QHostAddress &address, quint16 port) -{ - if (status() > Connecting) - { - torCtrlDebug() << "Ignoring TorControl::connect due to existing connection" << std::endl; - return; - } - - d->torAddress = address; - d->controlPort = port; - d->setTorStatus(TorUnknown); - - bool b = d->socket->blockSignals(true); - d->socket->abort(); - d->socket->blockSignals(b); - - d->setStatus(Connecting); - d->socket->connectToHost(address, port); -} - -void TorControl::reconnect() -{ - Q_ASSERT(!d->torAddress.isNull() && d->controlPort); - if (d->torAddress.isNull() || !d->controlPort || status() >= Connecting) - return; - - d->setStatus(Connecting); - d->socket->connectToHost(d->torAddress, d->controlPort); -} - -void TorControlPrivate::authenticateReply() -{ - AuthenticateCommand *command = qobject_cast(sender()); - Q_ASSERT(command); - Q_ASSERT(status == TorControl::Authenticating); - if (!command) - return; - - if (!command->isSuccessful()) { - setError(command->errorMessage()); - return; - } - - torCtrlDebug() << "torctrl: Authentication successful" << std::endl; - setStatus(TorControl::Connected); - - setTorStatus(TorControl::TorUnknown); - - TorControlCommand *clientEvents = new TorControlCommand; - connect(clientEvents, &TorControlCommand::replyLine, this, &TorControlPrivate::statusEvent); - socket->registerEvent("STATUS_CLIENT", clientEvents); - - getTorInfo(); - publishServices(); - - // XXX Fix old configurations that would store unwanted options in torrc. - // This can be removed some suitable amount of time after 1.0.4. - if (hasOwnership) - q->saveConfiguration(); -} - - -void TorControlPrivate::socketConnected() -{ - Q_ASSERT(status == TorControl::Connecting); - - torCtrlDebug() << "torctrl: Connected socket; querying information" << std::endl; - setStatus(TorControl::Authenticating); - - ProtocolInfoCommand *command = new ProtocolInfoCommand(q); - connect(command, &TorControlCommand::finished, this, &TorControlPrivate::protocolInfoReply); - socket->sendCommand(command, command->build()); -} - -void TorControlPrivate::socketDisconnected() -{ - /* Clear some internal state */ - torVersion.clear(); - socksAddress.clear(); - socksPort = 0; - setTorStatus(TorControl::TorUnknown); - - /* This emits the disconnected() signal as well */ - setStatus(TorControl::NotConnected); -} - -void TorControlPrivate::socketError() -{ - setError(QStringLiteral("Connection failed: %1").arg(socket->errorString())); -} - -void TorControlPrivate::protocolInfoReply() -{ - ProtocolInfoCommand *info = qobject_cast(sender()); - if (!info) - return; - - torVersion = info->torVersion(); - - if (status == TorControl::Authenticating) - { - AuthenticateCommand *auth = new AuthenticateCommand; - connect(auth, &TorControlCommand::finished, this, &TorControlPrivate::authenticateReply); - - QByteArray data; - ProtocolInfoCommand::AuthMethods methods = info->authMethods(); - - if (methods.testFlag(ProtocolInfoCommand::AuthNull)) - { - torCtrlDebug() << "torctrl: Using null authentication" << std::endl; - data = auth->build(); - } - else if (methods.testFlag(ProtocolInfoCommand::AuthCookie) && !info->cookieFile().isEmpty()) - { - QString cookieFile = info->cookieFile(); - QString cookieError; - torCtrlDebug() << "torctrl: Using cookie authentication with file" << cookieFile.toStdString() << std::endl; - - QFile file(cookieFile); - if (file.open(QIODevice::ReadOnly)) - { - QByteArray cookie = file.readAll(); - file.close(); - - /* Simple test to avoid a vulnerability where any process listening on what we think is - * the control port could trick us into sending the contents of an arbitrary file */ - if (cookie.size() == 32) - data = auth->build(cookie); - else - cookieError = QStringLiteral("Unexpected file size"); - } - else - cookieError = file.errorString(); - - if (!cookieError.isNull() || data.isNull()) - { - /* If we know a password and password authentication is allowed, try using that instead. - * This is a strange corner case that will likely never happen in a normal configuration, - * but it has happened. */ - if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.isEmpty()) - { - torCtrlDebug() << "torctrl: Unable to read authentication cookie file:" << cookieError.toStdString() << std::endl; - goto usePasswordAuth; - } - - setError(QStringLiteral("Unable to read authentication cookie file: %1").arg(cookieError)); - delete auth; - return; - } - } - else if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword) && !authPassword.isEmpty()) - { - usePasswordAuth: - torCtrlDebug() << "torctrl: Using hashed password authentication" << std::endl; - data = auth->build(authPassword); - } - else - { - if (methods.testFlag(ProtocolInfoCommand::AuthHashedPassword)) - setError(QStringLiteral("Tor requires a control password to connect, but no password is configured.")); - else - setError(QStringLiteral("Tor is not configured to accept any supported authentication methods.")); - delete auth; - return; - } - - socket->sendCommand(auth, data); - } -} - -void TorControlPrivate::getTorInfo() -{ - Q_ASSERT(q->isConnected()); - - GetConfCommand *command = new GetConfCommand(GetConfCommand::GetInfo); - connect(command, &TorControlCommand::finished, this, &TorControlPrivate::getTorInfoReply); - - QList keys; - keys << QByteArray("status/circuit-established") << QByteArray("status/bootstrap-phase"); - - /* If these are set in the config, they override the automatic behavior. */ - SettingsObject settings(QStringLiteral("tor")); - QHostAddress forceAddress(settings.read("socksAddress").toString()); - quint16 port = (quint16)settings.read("socksPort").toInt(); - - if (!forceAddress.isNull() && port) { - torCtrlDebug() << "torctrl: Using manually specified SOCKS connection settings"; - socksAddress = forceAddress; - socksPort = port; - emit q->connectivityChanged(); - } else - keys << QByteArray("net/listeners/socks"); - - socket->sendCommand(command, command->build(keys)); -} - -void TorControlPrivate::getTorInfoReply() -{ - GetConfCommand *command = qobject_cast(sender()); - if (!command || !q->isConnected()) - return; - - QList listenAddresses = splitQuotedStrings(command->get(QByteArray("net/listeners/socks")).toString().toLatin1(), ' '); - for (QList::Iterator it = listenAddresses.begin(); it != listenAddresses.end(); ++it) { - QByteArray value = unquotedString(*it); - int sepp = value.indexOf(':'); - QHostAddress address(QString::fromLatin1(value.mid(0, sepp))); - quint16 port = (quint16)value.mid(sepp+1).toUInt(); - - /* Use the first address that matches the one used for this control connection. If none do, - * just use the first address and rely on the user to reconfigure if necessary (not a problem; - * their setup is already very customized) */ - if (socksAddress.isNull() || address == socket->peerAddress()) { - socksAddress = address; - socksPort = port; - if (address == socket->peerAddress()) - break; - } - } - - /* It is not immediately an error to have no SOCKS address; when DisableNetwork is set there won't be a - * listener yet. To handle that situation, we'll try to read the socks address again when TorReady state - * is reached. */ - if (!socksAddress.isNull()) { - torCtrlDebug() << "torctrl: SOCKS address is " << socksAddress.toString().toStdString() << ":" << socksPort << std::endl; - emit q->connectivityChanged(); - } - - if (command->get(QByteArray("status/circuit-established")).toInt() == 1) { - torCtrlDebug() << "torctrl: Tor indicates that circuits have been established; state is TorReady" << std::endl; - setTorStatus(TorControl::TorReady); - } else { - setTorStatus(TorControl::TorOffline); - } - - QByteArray bootstrap = command->get(QByteArray("status/bootstrap-phase")).toString().toLatin1(); - if (!bootstrap.isEmpty()) - updateBootstrap(splitQuotedStrings(bootstrap, ' ')); -} - -void TorControl::addHiddenService(HiddenService *service) -{ - if (d->services.contains(service)) - return; - - d->services.append(service); -} - -void TorControlPrivate::publishServices() -{ - torCtrlDebug() << "Publish Services... " ; - - Q_ASSERT(q->isConnected()); - if (services.isEmpty()) - { - std::cerr << "No service regstered!" << std::endl; - return; - } - std::cerr << std::endl; - - SettingsObject settings(QStringLiteral("tor")); - if (settings.read("neverPublishServices").toBool()) - { - torCtrlDebug() << "torctrl: Skipping service publication because neverPublishService is enabled" << std::endl; - - /* Call servicePublished under the assumption that they're published externally. */ - for (QList::Iterator it = services.begin(); it != services.end(); ++it) - (*it)->servicePublished(); - - return; - } - - if (q->torVersionAsNewAs(QStringLiteral("0.2.7"))) { - foreach (HiddenService *service, services) { - if (service->hostname().isEmpty()) - torCtrlDebug() << "torctrl: Creating a new hidden service" << std::endl; - else - torCtrlDebug() << "torctrl: Publishing hidden service: " << service->hostname().toStdString() << std::endl; - AddOnionCommand *onionCommand = new AddOnionCommand(service); - QObject::connect(onionCommand, &AddOnionCommand::succeeded, service, &HiddenService::servicePublished); - socket->sendCommand(onionCommand, onionCommand->build()); - } - } else { - torCtrlDebug() << "torctrl: Using legacy SETCONF hidden service configuration for tor" << torVersion.toStdString() << std::endl; - SetConfCommand *command = new SetConfCommand; - QList > torConfig; - - foreach (HiddenService *service, services) - { - if (service->dataPath().isEmpty()) - continue; - - if (service->privateKey().isLoaded() && !QFile::exists(service->dataPath() + QStringLiteral("/private_key"))) { - // This case can happen if tor is downgraded after the profile is created - qWarning() << "Cannot publish ephemeral hidden services with this version of tor; skipping"; - continue; - } - - torCtrlDebug() << "torctrl: Configuring hidden service at" << service->dataPath().toStdString() << std::endl; - - QDir dir(service->dataPath()); - torConfig.append(qMakePair(QByteArray("HiddenServiceDir"), dir.absolutePath().toLocal8Bit())); - - const QList &targets = service->targets(); - for (QList::ConstIterator tit = targets.begin(); tit != targets.end(); ++tit) - { - QString target = QString::fromLatin1("%1 %2:%3").arg(tit->servicePort) - .arg(tit->targetAddress.toString()) - .arg(tit->targetPort); - torConfig.append(qMakePair(QByteArray("HiddenServicePort"), target.toLatin1())); - } - - QObject::connect(command, &SetConfCommand::setConfSucceeded, service, &HiddenService::servicePublished); - } - - if (!torConfig.isEmpty()) - socket->sendCommand(command, command->build(torConfig)); - } -} - -void TorControl::shutdown() -{ - if (!hasOwnership()) { - qWarning() << "torctrl: Ignoring shutdown command for a tor instance I don't own"; - return; - } - - d->socket->sendCommand("SIGNAL SHUTDOWN\r\n"); -} - -void TorControl::shutdownSync() -{ - if (!hasOwnership()) { - qWarning() << "torctrl: Ignoring shutdown command for a tor instance I don't own"; - return; - } - - shutdown(); - while (d->socket->bytesToWrite()) - { - if (!d->socket->waitForBytesWritten(5000)) - return; - } -} - -void TorControlPrivate::statusEvent(int code, const QByteArray &data) -{ - Q_UNUSED(code); - - QList tokens = splitQuotedStrings(data.trimmed(), ' '); - if (tokens.size() < 3) - return; - - torCtrlDebug() << "torctrl: status event:" << QString(data.trimmed()).toStdString() << std::endl; - - if (tokens[2] == "CIRCUIT_ESTABLISHED") { - setTorStatus(TorControl::TorReady); - } else if (tokens[2] == "CIRCUIT_NOT_ESTABLISHED") { - setTorStatus(TorControl::TorOffline); - } else if (tokens[2] == "BOOTSTRAP") { - tokens.takeFirst(); - updateBootstrap(tokens); - } -} - -void TorControlPrivate::updateBootstrap(const QList &data) -{ - bootstrapStatus.clear(); - // WARN or NOTICE - bootstrapStatus[QStringLiteral("severity")] = data.value(0); - for (int i = 1; i < data.size(); i++) { - int equals = data[i].indexOf('='); - QString key = QString::fromLatin1(data[i].mid(0, equals)); - QString value; - if (equals >= 0) - value = QString::fromLatin1(unquotedString(data[i].mid(equals + 1))); - bootstrapStatus[key.toLower()] = value; - } - - //torCtrlDebug() << bootstrapStatus << std::endl; - - emit q->bootstrapStatusChanged(); -} - -QObject *TorControl::getConfiguration(const QString &options) -{ - GetConfCommand *command = new GetConfCommand(GetConfCommand::GetConf); - d->socket->sendCommand(command, command->build(options.toLatin1())); - - //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); - return command; -} - -QObject *TorControl::setConfiguration(const QVariantMap &options) -{ - SetConfCommand *command = new SetConfCommand; - command->setResetMode(true); - d->socket->sendCommand(command, command->build(options)); - - //QQmlEngine::setObjectOwnership(command, QQmlEngine::CppOwnership); - return command; -} - -namespace Tor { - -class SaveConfigOperation : public PendingOperation -{ - Q_OBJECT - -public: - SaveConfigOperation(QObject *parent) - : PendingOperation(parent), command(0) - { - } - - void start(TorControlSocket *socket) - { - Q_ASSERT(!command); - command = new GetConfCommand(GetConfCommand::GetInfo); - QObject::connect(command, &TorControlCommand::finished, this, &SaveConfigOperation::configTextReply); - socket->sendCommand(command, command->build(QList() << "config-text" << "config-file")); - } - -private slots: - void configTextReply() - { - Q_ASSERT(command); - if (!command) - return; - - QString path = QFile::decodeName(command->get("config-file").toByteArray()); - if (path.isEmpty()) { - finishWithError(QStringLiteral("Cannot write torrc without knowing its path")); - return; - } - - // Out of paranoia, refuse to write any file not named 'torrc', or if the - // file doesn't exist - QFileInfo fileInfo(path); - if (fileInfo.fileName() != QStringLiteral("torrc") || !fileInfo.exists()) { - finishWithError(QStringLiteral("Refusing to write torrc to unacceptable path %1").arg(path)); - return; - } - - QSaveFile file(path); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - finishWithError(QStringLiteral("Failed opening torrc file for writing: %1").arg(file.errorString())); - return; - } - - // Remove these keys when writing torrc; they are set at runtime and contain - // absolute paths or port numbers - static const char *bannedKeys[] = { - "ControlPortWriteToFile", - "DataDirectory", - "HiddenServiceDir", - "HiddenServicePort", - 0 - }; - - QVariantList configText = command->get("config-text").toList(); - foreach (const QVariant &value, configText) { - QByteArray line = value.toByteArray(); - - bool skip = false; - for (const char **key = bannedKeys; *key; key++) { - if (line.startsWith(*key)) { - skip = true; - break; - } - } - if (skip) - continue; - - file.write(line); - file.write("\n"); - } - - if (!file.commit()) { - finishWithError(QStringLiteral("Failed writing torrc: %1").arg(file.errorString())); - return; - } - - torCtrlDebug() << "torctrl: Wrote torrc file" << std::endl; - finishWithSuccess(); - } - -private: - GetConfCommand *command; -}; - -} - -PendingOperation *TorControl::saveConfiguration() -{ - if (!hasOwnership()) { - qWarning() << "torctrl: Ignoring save configuration command for a tor instance I don't own"; - return 0; - } - - SaveConfigOperation *operation = new SaveConfigOperation(this); - QObject::connect(operation, &PendingOperation::finished, operation, &QObject::deleteLater); - operation->start(d->socket); - - //QQmlEngine::setObjectOwnership(operation, QQmlEngine::CppOwnership); - return operation; -} - -bool TorControl::hasOwnership() const -{ - return d->hasOwnership; -} - -void TorControl::takeOwnership() -{ - d->hasOwnership = true; - d->socket->sendCommand("TAKEOWNERSHIP\r\n"); - - // Reset PID-based polling - QVariantMap options; - options[QStringLiteral("__OwningControllerProcess")] = QVariant(); - setConfiguration(options); -} - -bool TorControl::torVersionAsNewAs(const QString &match) const -{ - QRegularExpression r(QStringLiteral("[.-]")); - QStringList split = torVersion().split(r); - QStringList matchSplit = match.split(r); - - for (int i = 0; i < matchSplit.size(); i++) { - if (i >= split.size()) - return false; - bool ok1 = false, ok2 = false; - int currentVal = split[i].toInt(&ok1); - int matchVal = matchSplit[i].toInt(&ok2); - if (!ok1 || !ok2) - return false; - if (currentVal > matchVal) - return true; - if (currentVal < matchVal) - return false; - } - - // Versions are equal, up to the length of match - return true; -} - -#include "TorControl.moc" - diff --git a/retroshare-gui/src/TorControl/TorControl.h b/retroshare-gui/src/TorControl/TorControl.h deleted file mode 100644 index 5d208656e..000000000 --- a/retroshare-gui/src/TorControl/TorControl.h +++ /dev/null @@ -1,144 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORCONTROL_H -#define TORCONTROL_H - -#include - -#include -#include -#include "PendingOperation.h" - -class QNetworkProxy; - -namespace Tor -{ - -class HiddenService; -class TorControlPrivate; - -class TorControl : public QObject -{ - Q_OBJECT - Q_ENUMS(Status TorStatus) - - // Status of the control connection - Q_PROPERTY(Status status READ status NOTIFY statusChanged) - // Status of Tor (and whether it believes it can connect) - Q_PROPERTY(TorStatus torStatus READ torStatus NOTIFY torStatusChanged) - // Whether it's possible to make a SOCKS connection and connect - Q_PROPERTY(bool hasConnectivity READ hasConnectivity NOTIFY connectivityChanged) - Q_PROPERTY(QString torVersion READ torVersion NOTIFY connected) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY statusChanged) - Q_PROPERTY(QVariantMap bootstrapStatus READ bootstrapStatus NOTIFY bootstrapStatusChanged) - Q_PROPERTY(bool hasOwnership READ hasOwnership NOTIFY hasOwnershipChanged) - -public: - enum Status - { - Error = -1, - NotConnected = 0x00, - Connecting = 0x01, - Authenticating = 0x02, - Connected = 0x03 - }; - - enum TorStatus - { - TorUnknown = 0x00, - TorOffline = 0x01, - TorReady = 0x02 - }; - - - explicit TorControl(QObject *parent = 0); - - /* Information */ - Status status() const; - TorStatus torStatus() const; - QString torVersion() const; - bool torVersionAsNewAs(const QString &version) const; - QString errorMessage() const; - - bool hasConnectivity() const; - QHostAddress socksAddress() const; - quint16 socksPort() const; - QNetworkProxy connectionProxy(); - - /* Authentication */ - void setAuthPassword(const QByteArray &password); - - /* Connection */ - bool isConnected() const { return status() == Connected; } - void connect(const QHostAddress &address, quint16 port); - - /* Ownership means that tor is managed by this socket, and we - * can shut it down, own its configuration, etc. */ - bool hasOwnership() const; - void takeOwnership(); - - /* Hidden Services */ - QList hiddenServices() const; - void addHiddenService(HiddenService *service); - - QVariantMap bootstrapStatus() const; - Q_INVOKABLE QObject *getConfiguration(const QString &options); - Q_INVOKABLE QObject *setConfiguration(const QVariantMap &options); - Q_INVOKABLE PendingOperation *saveConfiguration(); - -signals: - void statusChanged(int newStatus, int oldStatus); - void torStatusChanged(int newStatus, int oldStatus); - void connected(); - void disconnected(); - void connectivityChanged(); - void bootstrapStatusChanged(); - void hasOwnershipChanged(); - -public slots: - /* Instruct Tor to shutdown */ - void shutdown(); - /* Call shutdown(), and wait synchronously for the command to be written */ - void shutdownSync(); - - void reconnect(); - -private: - TorControlPrivate *d; -}; - -} - -extern Tor::TorControl *torControl; - -#endif // TORCONTROLMANAGER_H diff --git a/retroshare-gui/src/TorControl/TorControlCommand.cpp b/retroshare-gui/src/TorControl/TorControlCommand.cpp deleted file mode 100644 index 48d4aab8b..000000000 --- a/retroshare-gui/src/TorControl/TorControlCommand.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "TorControlCommand.h" -#include - -using namespace Tor; - -TorControlCommand::TorControlCommand() - : m_finalStatus(0) -{ -} - -void TorControlCommand::onReply(int statusCode, const QByteArray &data) -{ - emit replyLine(statusCode, data); -} - -void TorControlCommand::onFinished(int statusCode) -{ - m_finalStatus = statusCode; - emit finished(); -} - -void TorControlCommand::onDataLine(const QByteArray &data) -{ - Q_UNUSED(data); -} - -void TorControlCommand::onDataFinished() -{ - qWarning() << "torctrl: Unexpected data response for command"; -} - diff --git a/retroshare-gui/src/TorControl/TorControlCommand.h b/retroshare-gui/src/TorControl/TorControlCommand.h deleted file mode 100644 index 894381054..000000000 --- a/retroshare-gui/src/TorControl/TorControlCommand.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORCONTROLCOMMAND_H -#define TORCONTROLCOMMAND_H - -#include -#include - -namespace Tor -{ - -class TorControlCommand : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(TorControlCommand) - - friend class TorControlSocket; - -public: - TorControlCommand(); - - int statusCode() const { return m_finalStatus; } - -signals: - void replyLine(int statusCode, const QByteArray &data); - void finished(); - -protected: - virtual void onReply(int statusCode, const QByteArray &data); - virtual void onFinished(int statusCode); - virtual void onDataLine(const QByteArray &data); - virtual void onDataFinished(); - -private: - int m_finalStatus; -}; - -} - -#endif // TORCONTROLCOMMAND_H diff --git a/retroshare-gui/src/TorControl/TorControlSocket.cpp b/retroshare-gui/src/TorControl/TorControlSocket.cpp deleted file mode 100644 index c6b1eb707..000000000 --- a/retroshare-gui/src/TorControl/TorControlSocket.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "TorControlSocket.h" -#include "TorControlCommand.h" -#include - -using namespace Tor; - -TorControlSocket::TorControlSocket(QObject *parent) - : QTcpSocket(parent), currentCommand(0), inDataReply(false) -{ - connect(this, SIGNAL(readyRead()), this, SLOT(process())); - connect(this, SIGNAL(disconnected()), this, SLOT(clear())); -} - -TorControlSocket::~TorControlSocket() -{ - clear(); -} - -void TorControlSocket::sendCommand(TorControlCommand *command, const QByteArray &data) -{ - Q_ASSERT(data.endsWith("\r\n")); - - commandQueue.append(command); - write(data); - - std::cerr << "[TOR CTRL] Sent: \"" << QString(data.trimmed()).toStdString() << "\"" << std::endl; -} - -void TorControlSocket::registerEvent(const QByteArray &event, TorControlCommand *command) -{ - eventCommands.insert(event, command); - - QByteArray data("SETEVENTS"); - foreach (const QByteArray &key, eventCommands.keys()) { - data += ' '; - data += key; - } - data += "\r\n"; - - sendCommand(data); -} - -void TorControlSocket::clear() -{ - qDeleteAll(commandQueue); - commandQueue.clear(); - qDeleteAll(eventCommands); - eventCommands.clear(); - inDataReply = false; - currentCommand = 0; -} - -void TorControlSocket::setError(const QString &message) -{ - m_errorMessage = message; - emit error(message); - abort(); -} - -void TorControlSocket::process() -{ - for (;;) { - if (!canReadLine()) - return; - - QByteArray line = readLine(5120); - if (!line.endsWith("\r\n")) { - setError(QStringLiteral("Invalid control message syntax")); - return; - } - line.chop(2); - - if (inDataReply) { - if (line == ".") { - inDataReply = false; - if (currentCommand) - currentCommand->onDataFinished(); - currentCommand = 0; - } else { - if (currentCommand) - currentCommand->onDataLine(line); - } - continue; - } - - if (line.size() < 4) { - setError(QStringLiteral("Invalid control message syntax")); - return; - } - - int statusCode = line.left(3).toInt(); - char type = line[3]; - bool isFinalReply = (type == ' '); - inDataReply = (type == '+'); - - // Trim down to just data - line = line.mid(4); - - if (!isFinalReply && !inDataReply && type != '-') { - setError(QStringLiteral("Invalid control message syntax")); - return; - } - - // 6xx replies are asynchronous responses - if (statusCode >= 600 && statusCode < 700) { - if (!currentCommand) { - int space = line.indexOf(' '); - if (space > 0) - currentCommand = eventCommands.value(line.mid(0, space)); - - if (!currentCommand) { - qWarning() << "torctrl: Ignoring unknown event"; - continue; - } - } - - currentCommand->onReply(statusCode, line); - if (isFinalReply) { - currentCommand->onFinished(statusCode); - currentCommand = 0; - } - continue; - } - - if (commandQueue.isEmpty()) { - qWarning() << "torctrl: Received unexpected data"; - continue; - } - - TorControlCommand *command = commandQueue.first(); - if (command) - command->onReply(statusCode, line); - - if (inDataReply) { - currentCommand = command; - } else if (isFinalReply) { - commandQueue.takeFirst(); - if (command) { - command->onFinished(statusCode); - command->deleteLater(); - } - } - } -} diff --git a/retroshare-gui/src/TorControl/TorControlSocket.h b/retroshare-gui/src/TorControl/TorControlSocket.h deleted file mode 100644 index 2db911503..000000000 --- a/retroshare-gui/src/TorControl/TorControlSocket.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORCONTROLSOCKET_H -#define TORCONTROLSOCKET_H - -#include -#include - -namespace Tor -{ - -class TorControlCommand; - -class TorControlSocket : public QTcpSocket -{ -Q_OBJECT -public: - explicit TorControlSocket(QObject *parent = 0); - virtual ~TorControlSocket(); - - QString errorMessage() const { return m_errorMessage; } - - void registerEvent(const QByteArray &event, TorControlCommand *handler); - - void sendCommand(const QByteArray &data) { sendCommand(0, data); } - void sendCommand(TorControlCommand *command, const QByteArray &data); - -signals: - void error(const QString &message); - -private slots: - void process(); - void clear(); - -private: - QQueue commandQueue; - QHash eventCommands; - QString m_errorMessage; - TorControlCommand *currentCommand; - bool inDataReply; - - void setError(const QString &message); -}; - -} - -#endif // TORCONTROLSOCKET_H diff --git a/retroshare-gui/src/TorControl/TorControlWindow.cpp b/retroshare-gui/src/TorControl/TorControlWindow.cpp index 6da6b8d7a..ddab3f281 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.cpp +++ b/retroshare-gui/src/TorControl/TorControlWindow.cpp @@ -9,42 +9,59 @@ #include #include "util/rstime.h" +#include "retroshare/rstor.h" +#include "retroshare/rsevents.h" + #include "TorControlWindow.h" -#include "TorManager.h" -#include "TorControl.h" -#include "HiddenService.h" +#include "util/qtthreadsutils.h" -TorControlDialog::TorControlDialog(Tor::TorManager *tm,QWidget *parent) - : mTorManager(tm) +TorControlDialog::TorControlDialog(QWidget *) { - setupUi(this) ; + setupUi(this) ; - QObject::connect(tm->control(),SIGNAL(statusChanged(int,int)),this,SLOT(statusChanged())) ; - QObject::connect(tm->control(),SIGNAL(connected()),this,SLOT(statusChanged())); - QObject::connect(tm->control(),SIGNAL(disconnected()),this,SLOT(statusChanged())); - QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged())); - QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged())); - QObject::connect(tm ,SIGNAL(errorChanged()),this,SLOT(statusChanged())); + mEventHandlerId = 0; // very important! - //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId, RsEventType::TOR_MANAGER ); - mIncomingServer = new QTcpServer(this) ; - mHiddenService = NULL ; - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_UNKNOWN; - //mBootstrapPhaseFinished = false ; + mIncomingServer = new QTcpServer(this) ; - connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); + connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); - QTimer *timer = new QTimer ; + QTimer *timer = new QTimer ; - QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; - timer->start(500) ; + QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; + timer->start(300) ; - // Hide some debug output for the released version + // Hide some debug output for the released version - setWindowFlags( Qt::Dialog | Qt::FramelessWindowHint ); + setWindowFlags( Qt::Dialog | Qt::FramelessWindowHint ); - adjustSize(); + adjustSize(); +} + +TorControlDialog::~TorControlDialog() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void TorControlDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::TOR_MANAGER) return; + + const RsTorManagerEvent *fe = dynamic_cast(event.get()); + if(!fe) + return; + + switch(fe->mTorManagerEventType) + { + case RsTorManagerEventCode::TOR_STATUS_CHANGED: + case RsTorManagerEventCode::TOR_CONNECTIVITY_CHANGED: statusChanged(fe->mTorStatus,fe->mTorConnectivityStatus); + break; + default: ; + } } void TorControlDialog::onIncomingConnection() @@ -52,67 +69,66 @@ void TorControlDialog::onIncomingConnection() std::cerr << "Incoming connection !!" << std::endl; } -void TorControlDialog::statusChanged() +void TorControlDialog::statusChanged(RsTorStatus torstatus, RsTorConnectivityStatus tor_control_status) { - int tor_control_status = mTorManager->control()->status(); - int torstatus = mTorManager->control()->torStatus(); - QString tor_control_status_str,torstatus_str ; - if(mTorManager->hasError()) - mErrorMsg = mTorManager->errorMessage() ; + if(RsTor::hasError()) + mErrorMsg = QString::fromStdString(RsTor::errorMessage()) ; switch(tor_control_status) { default: - case Tor::TorControl::Error : tor_control_status_str = "Error" ; break ; - case Tor::TorControl::NotConnected: tor_control_status_str = "Not connected" ; break ; - case Tor::TorControl::Connecting: tor_control_status_str = "Connecting" ; break ; - case Tor::TorControl::Authenticating: tor_control_status_str = "Authenticating" ; break ; - case Tor::TorControl::Connected: tor_control_status_str = "Connected" ; break ; - } + case RsTorConnectivityStatus::ERROR: tor_control_status_str = tr("Error") ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_status_str = tr("Not connected") ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_status_str = tr("Connecting") ; break ; + case RsTorConnectivityStatus::SOCKET_CONNECTED: tor_control_status_str = tr("Socket connected") ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_status_str = tr("Authenticating") ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_status_str = tr("Authenticated") ; break ; + case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_status_str = tr("Hidden service ready") ; break ; + case RsTorConnectivityStatus::UNKNOWN: tor_control_status_str = tr("Unknown") ; break ; + } switch(torstatus) { default: - case Tor::TorControl::TorUnknown: torstatus_str = "Unknown" ; break ; - case Tor::TorControl::TorOffline: torstatus_str = "Tor offline" ; break ; - case Tor::TorControl::TorReady: torstatus_str = "Tor ready" ; break ; + case RsTorStatus::UNKNOWN: torstatus_str = tr("Unknown") ; break ; + case RsTorStatus::OFFLINE: torstatus_str = tr("Tor offline") ; break ; + case RsTorStatus::READY: torstatus_str = tr("Tor ready") ; break ; } torStatus_LB->setText(torstatus_str) ; - if(torstatus == Tor::TorControl::TorUnknown) + if(torstatus == RsTorStatus::UNKNOWN) torStatus_LB->setToolTip(tr("Check that Tor is accessible in your executable path")) ; else torStatus_LB->setToolTip("") ; - QVariantMap qvm = mTorManager->control()->bootstrapStatus(); + std::map qvm = RsTor::bootstrapStatus(); QString bootstrapstatus_str ; std::cerr << "Tor control status: " << tor_control_status_str.toStdString() << std::endl; std::cerr << "Tor status: " << torstatus_str.toStdString() << std::endl; - std::cerr << "Bootstrap status map: " << std::endl; for(auto it(qvm.begin());it!=qvm.end();++it) - std::cerr << " " << it.key().toStdString() << " : " << it.value().toString().toStdString() << std::endl; + std::cerr << " " << it->first << " : " << it->second << std::endl; - if(!qvm["progress"].toString().isNull()) - torBootstrapStatus_LB->setText(qvm["progress"].toString() + " % (" + qvm["summary"].toString() + ")") ; + if(!qvm["progress"].empty()) + torBootstrapStatus_LB->setText(QString::fromStdString(qvm["progress"]) + " % (" + QString::fromStdString(qvm["summary"]) + ")") ; else torBootstrapStatus_LB->setText(tr("[Waiting for Tor...]")) ; - QString service_id ; - QString onion_address ; - QHostAddress service_target_address ; + std::string service_id ; + std::string onion_address ; + std::string service_target_address ; uint16_t service_port ; uint16_t target_port ; - if(mTorManager->getHiddenServiceInfo(service_id,onion_address,service_port, service_target_address,target_port)) + if(RsTor::getHiddenServiceInfo(service_id,onion_address,service_port, service_target_address,target_port)) { - hiddenServiceAddress_LB->setText(QString::number(service_port) + ":" + service_target_address.toString() + ":" + QString::number(target_port)); - onionAddress_LB->setText(onion_address); + hiddenServiceAddress_LB->setText(QString::number(service_port) + ":" + QString::fromStdString(service_target_address) + ":" + QString::number(target_port)); + onionAddress_LB->setText(QString::fromStdString(onion_address)); } else { @@ -123,34 +139,39 @@ void TorControlDialog::statusChanged() showLog(); adjustSize(); - QCoreApplication::processEvents(); // forces update + QCoreApplication::processEvents(); // forces update } void TorControlDialog::showLog() { - static std::set already_seen ; + static std::set already_seen ; - QString s ; - QStringList logmsgs = mTorManager->logMessages() ; - bool can_print = false ; + std::string s ; + std::list logmsgs = RsTor::logMessages() ; + bool can_print = false ; - for(QStringList::const_iterator it(logmsgs.begin());it!=logmsgs.end();++it) - { + for(auto it(logmsgs.begin());it!=logmsgs.end();++it) + { s += *it + "\n" ; - if(already_seen.find(*it) == already_seen.end()) - { - can_print = true ; - already_seen.insert(*it); - } + if(already_seen.find(*it) == already_seen.end()) + { + can_print = true ; + already_seen.insert(*it); + } - if(can_print) - std::cerr << "[TOR DEBUG LOG] " << (*it).toStdString() << std::endl; - } + if(can_print) + { + std::cerr << "[TOR DEBUG LOG] " << *it << std::endl; -// torLog_TB->setText(s) ;: + QString s = QString::fromStdString(*it); + int n = s.indexOf(QString("Bootstrapped")); - std::cerr << "Connexion Proxy: " << mTorManager->control()->socksAddress().toString().toStdString() << ":" << mTorManager->control()->socksPort() << std::endl; + if(n >= 0) + torBootstrapStatus_LB->setText(s.mid(n+QString("Bootstrapped").length())); + } + } + //std::cerr << "Connexion Proxy: " << RsTor::socksAddress() << ":" << QString::number(RsTor::socksPort()).toStdString() << std::endl; } TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) @@ -161,9 +182,9 @@ TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) return TorControlDialog::TOR_STATUS_FAIL ; } - switch(mTorManager->control()->torStatus()) + switch(RsTor::torStatus()) { - case Tor::TorControl::TorReady: rstime::rs_usleep(1*1000*1000);return TOR_STATUS_OK ; + case RsTorStatus::READY: rstime::rs_usleep(1*1000*1000);return TOR_STATUS_OK ; default: return TOR_STATUS_UNKNOWN ; } @@ -171,60 +192,35 @@ TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() { - std::cerr << "Checking for hidden services:" ; + std::cerr << "Checking for hidden services:" ; - switch(mHiddenServiceStatus) - { - default: - case HIDDEN_SERVICE_STATUS_UNKNOWN: { + std::string service_id; - std::cerr << " trying to setup. " ; + RsTorHiddenServiceStatus service_status = RsTor::getHiddenServiceStatus(service_id); - if(!mTorManager->setupHiddenService()) - { - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ; - std::cerr << "Failed." << std::endl; - return mHiddenServiceStatus ; - } - std::cerr << "Done." << std::endl; - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ; - return mHiddenServiceStatus ; - } + if(service_id.empty()) + { + std::cerr << "Not ready yet." << std::endl; + return HIDDEN_SERVICE_STATUS_REQUESTED ; + } + else + { + if(mHiddenService.empty()) + mHiddenService = service_id ; - case HIDDEN_SERVICE_STATUS_REQUESTED: { - QList hidden_services = mTorManager->control()->hiddenServices(); + std::cerr << "New service acquired. Status is " << (int)service_status ; - if(hidden_services.empty()) - { - std::cerr << "Not ready yet." << std::endl; - return mHiddenServiceStatus ; - } - else - { - if(mHiddenService == NULL) - mHiddenService = *(hidden_services.begin()) ; + if(service_status == RsTorHiddenServiceStatus::ONLINE) + { + std::cerr << ": published and running!" << std::endl; - Tor::HiddenService::Status hss = mHiddenService->status(); - - std::cerr << "New service acquired. Status is " << hss ; - - if(hss == Tor::HiddenService::Online) - { - mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_OK ; - std::cerr << ": published and running!" << std::endl; - - return mHiddenServiceStatus ; - } - else - { - std::cerr << ": not ready yet." << std::endl; - return mHiddenServiceStatus ; - } - } - } - case HIDDEN_SERVICE_STATUS_OK : - std::cerr << "New service acquired." << std::endl; - return mHiddenServiceStatus ; - } + return HIDDEN_SERVICE_STATUS_OK ; + } + else + { + std::cerr << ": not ready yet." << std::endl; + return HIDDEN_SERVICE_STATUS_REQUESTED ; + } + } } diff --git a/retroshare-gui/src/TorControl/TorControlWindow.h b/retroshare-gui/src/TorControl/TorControlWindow.h index c4e8ce522..412c08ed5 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.h +++ b/retroshare-gui/src/TorControl/TorControlWindow.h @@ -1,3 +1,5 @@ +#include "retroshare/rsevents.h" +#include "retroshare/rstor.h" #include "ui_TorControlWindow.h" class QTcpServer ; @@ -12,7 +14,8 @@ class TorControlDialog: public QWidget, public Ui::TorControlDialog Q_OBJECT public: - TorControlDialog(Tor::TorManager *tm,QWidget *parent =NULL); + TorControlDialog(QWidget *parent =NULL); + virtual ~TorControlDialog(); enum TorStatus { TOR_STATUS_UNKNOWN = 0x00, @@ -34,15 +37,14 @@ public: protected slots: void showLog(); - void statusChanged(); - void onIncomingConnection(); + void statusChanged(RsTorStatus torstatus,RsTorConnectivityStatus tor_control_status); + void onIncomingConnection(); + void handleEvent_main_thread(std::shared_ptr event); private: QString mErrorMsg ; - HiddenServiceStatus mHiddenServiceStatus ; - - Tor::TorManager *mTorManager ; - Tor::HiddenService *mHiddenService ; + std::string mHiddenService; QTcpServer *mIncomingServer ; + RsEventsHandlerId_t mEventHandlerId; }; diff --git a/retroshare-gui/src/TorControl/TorControlWindow.ui b/retroshare-gui/src/TorControl/TorControlWindow.ui index 602146641..6077485e5 100644 --- a/retroshare-gui/src/TorControl/TorControlWindow.ui +++ b/retroshare-gui/src/TorControl/TorControlWindow.ui @@ -40,6 +40,12 @@ + + + 0 + 0 + + @@ -55,6 +61,12 @@ + + + 0 + 0 + + Tor status: @@ -79,8 +91,14 @@ + + + 0 + 0 + + - Hidden service address: + Hidden address: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -89,8 +107,14 @@ + + + 0 + 0 + + - Tor bootstrap status: + Tor status: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -106,6 +130,12 @@ + + + 0 + 0 + + Onion address: diff --git a/retroshare-gui/src/TorControl/TorManager.cpp b/retroshare-gui/src/TorControl/TorManager.cpp deleted file mode 100644 index 221a55935..000000000 --- a/retroshare-gui/src/TorControl/TorManager.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include "TorManager.h" -#include "TorProcess.h" -#include "TorControl.h" -#include "CryptoKey.h" -#include "HiddenService.h" -#include "GetConfCommand.h" -#include "Settings.h" -#include -#include -#include -#include -#include - -using namespace Tor; - -namespace Tor -{ - -class TorManagerPrivate : public QObject -{ - Q_OBJECT - -public: - TorManager *q; - TorProcess *process; - TorControl *control; - QString dataDir; - QString hiddenServiceDir; - QStringList logMessages; - QString errorMessage; - bool configNeeded; - - HiddenService *hiddenService ; - - explicit TorManagerPrivate(TorManager *parent = 0); - - QString torExecutablePath() const; - bool createDataDir(const QString &path); - bool createDefaultTorrc(const QString &path); - - void setError(const QString &errorMessage); - -public slots: - void processStateChanged(int state); - void processErrorChanged(const QString &errorMessage); - void processLogMessage(const QString &message); - void controlStatusChanged(int status); - void getConfFinished(); -}; - -} - -TorManager::TorManager(QObject *parent) - : QObject(parent), d(new TorManagerPrivate(this)) -{ -} - -TorManagerPrivate::TorManagerPrivate(TorManager *parent) - : QObject(parent) - , q(parent) - , process(0) - , control(new TorControl(this)) - , configNeeded(false) - , hiddenService(NULL) -{ - connect(control, SIGNAL(statusChanged(int,int)), SLOT(controlStatusChanged(int))); -} - -TorManager *TorManager::instance() -{ - static TorManager *p = 0; - if (!p) - p = new TorManager(qApp); - return p; -} - -TorControl *TorManager::control() -{ - return d->control; -} - -TorProcess *TorManager::process() -{ - return d->process; -} - -bool TorManager::isTorAvailable() -{ - return !instance()->d->torExecutablePath().isNull(); -} - -QString TorManager::torDataDirectory() const -{ - return d->dataDir; -} - -void TorManager::setTorDataDirectory(const QString &path) -{ - d->dataDir = QDir::fromNativeSeparators(path); - - if (!d->dataDir.isEmpty() && !d->dataDir.endsWith(QLatin1Char('/'))) - d->dataDir.append(QLatin1Char('/')); -} - -QString TorManager::hiddenServiceDirectory() const -{ - return d->hiddenServiceDir; -} -void TorManager::setHiddenServiceDirectory(const QString &path) -{ - d->hiddenServiceDir = QDir::fromNativeSeparators(path); - - if (!d->hiddenServiceDir.isEmpty() && !d->hiddenServiceDir.endsWith(QLatin1Char('/'))) - d->hiddenServiceDir.append(QLatin1Char('/')); -} - -bool TorManager::setupHiddenService() -{ - if(d->hiddenService != NULL) - { - std::cerr << "TorManager: setupHiddenService() called twice! Not doing anything this time." << std::endl; - return true ; - } - - QString keyData ;//= m_settings->read("serviceKey").toString(); - QString legacyDir = d->hiddenServiceDir; - - std::cerr << "TorManager: setting up hidden service." << std::endl; - - if(legacyDir.isNull()) - { - std::cerr << "legacy dir not set! Cannot proceed." << std::endl; - return false ; - } - - std::cerr << "Using legacy dir: " << legacyDir.toStdString() << std::endl; - - if (!legacyDir.isEmpty() && QFile::exists(legacyDir + QLatin1String("/private_key"))) - { - std::cerr << "Attempting to load key from legacy filesystem format in " << legacyDir.toStdString() << std::endl; - - CryptoKey key; - if (!key.loadFromFile(legacyDir + QLatin1String("/private_key"))) - { - qWarning() << "Cannot load legacy format key from" << legacyDir << "for conversion"; - return false; - } - - d->hiddenService = new Tor::HiddenService(key, legacyDir, this); - - std::cerr << "Got key from legacy dir: " << std::endl; - std::cerr << key.bytes().toStdString() << std::endl; - } - else - { - d->hiddenService = new Tor::HiddenService(legacyDir, this); - - std::cerr << "Creating new hidden service." << std::endl; - - connect(d->hiddenService, SIGNAL(privateKeyChanged()), this, SLOT(hiddenServicePrivateKeyChanged())) ; - connect(d->hiddenService, SIGNAL(hostnameChanged()), this, SLOT(hiddenServiceHostnameChanged())) ; - } - - Q_ASSERT(d->hiddenService); - connect(d->hiddenService, SIGNAL(statusChanged(int,int)), this, SLOT(hiddenServiceStatusChanged(int,int))); - - // Generally, these are not used, and we bind to localhost and port 0 - // for an automatic (and portable) selection. - - QHostAddress address = QHostAddress::LocalHost; // we only listen from localhost - - quint16 port = 7934;//(quint16)m_settings->read("localListenPort").toInt(); - - std::cerr << "Testing host address: " << address.toString().toStdString() << ":" << port ; - - if (!QTcpServer().listen(address, port)) - { - // XXX error case - std::cerr << " Failed to open incoming socket" << std::endl; - return false; - } - - std::cerr << " OK - Adding hidden service to TorControl." << std::endl; - - //d->hiddenService->addTarget(9878, mIncomingServer->serverAddress(), mIncomingServer->serverPort()); - d->hiddenService->addTarget(9878, QHostAddress::LocalHost,7934); - control()->addHiddenService(d->hiddenService); - - return true ; -} - -void TorManager::hiddenServiceStatusChanged(int old_status,int new_status) -{ - std::cerr << "Hidden service status changed from " << old_status << " to " << new_status << std::endl; -} - -void TorManager::hiddenServicePrivateKeyChanged() -{ - QString key = QString::fromLatin1(d->hiddenService->privateKey().bytes()); - - QFile outfile(d->hiddenServiceDir + QLatin1String("/private_key")) ; - outfile.open( QIODevice::WriteOnly | QIODevice::Text ); - QTextStream s(&outfile); - -#ifdef TO_REMOVE - s << "-----BEGIN RSA PRIVATE KEY-----" << endl; - - for(int i=0;ihiddenServiceDir + QLatin1String("/hostname")) ; - outfile2.open( QIODevice::WriteOnly | QIODevice::Text ); - QTextStream t(&outfile2); - - QString hostname(d->hiddenService->hostname()); - - t << hostname << endl; - outfile2.close(); - - std::cerr << "Hidden service hostname changed: " << hostname.toStdString() << std::endl; -} - -bool TorManager::configurationNeeded() const -{ - return d->configNeeded; -} - -QStringList TorManager::logMessages() const -{ - return d->logMessages; -} - -bool TorManager::hasError() const -{ - return !d->errorMessage.isEmpty(); -} - -QString TorManager::errorMessage() const -{ - return d->errorMessage; -} - -bool TorManager::start() -{ - if (!d->errorMessage.isEmpty()) { - d->errorMessage.clear(); - emit errorChanged(); - } - - SettingsObject settings(QStringLiteral("tor")); - - // If a control port is defined by config or environment, skip launching tor - if (!settings.read("controlPort").isUndefined() || - !qEnvironmentVariableIsEmpty("TOR_CONTROL_PORT")) - { - QHostAddress address(settings.read("controlAddress").toString()); - quint16 port = (quint16)settings.read("controlPort").toInt(); - QByteArray password = settings.read("controlPassword").toString().toLatin1(); - - if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_HOST")) - address = QHostAddress(QString::fromLatin1(qgetenv("TOR_CONTROL_HOST"))); - - if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_PORT")) { - bool ok = false; - port = qgetenv("TOR_CONTROL_PORT").toUShort(&ok); - if (!ok) - port = 0; - } - - if (!qEnvironmentVariableIsEmpty("TOR_CONTROL_PASSWD")) - password = qgetenv("TOR_CONTROL_PASSWD"); - - if (!port) { - d->setError(QStringLiteral("Invalid control port settings from environment or configuration")); - return false; - } - - if (address.isNull()) - address = QHostAddress::LocalHost; - - d->control->setAuthPassword(password); - d->control->connect(address, port); - } else { - // Launch a bundled Tor instance - QString executable = d->torExecutablePath(); - - std::cerr << "Executable path: " << executable.toStdString() << std::endl; - - if (executable.isEmpty()) { - d->setError(QStringLiteral("Cannot find tor executable")); - return false; - } - - if (!d->process) { - d->process = new TorProcess(this); - connect(d->process, SIGNAL(stateChanged(int)), d, SLOT(processStateChanged(int))); - connect(d->process, SIGNAL(errorMessageChanged(QString)), d, - SLOT(processErrorChanged(QString))); - connect(d->process, SIGNAL(logMessage(QString)), d, SLOT(processLogMessage(QString))); - } - - if (!QFile::exists(d->dataDir) && !d->createDataDir(d->dataDir)) { - d->setError(QStringLiteral("Cannot write data location: %1").arg(d->dataDir)); - return false; - } - - QString defaultTorrc = d->dataDir + QStringLiteral("default_torrc"); - if (!QFile::exists(defaultTorrc) && !d->createDefaultTorrc(defaultTorrc)) { - d->setError(QStringLiteral("Cannot write data files: %1").arg(defaultTorrc)); - return false; - } - - QFile torrc(d->dataDir + QStringLiteral("torrc")); - if (!torrc.exists() || torrc.size() == 0) { - d->configNeeded = true; - emit configurationNeededChanged(); - } - - d->process->setExecutable(executable); - d->process->setDataDir(d->dataDir); - d->process->setDefaultTorrc(defaultTorrc); - d->process->start(); - } - return true ; -} - -bool TorManager::getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port) -{ - proxy_server_adress = control()->socksAddress(); - proxy_server_port = control()->socksPort(); - - return proxy_server_port > 1023 ; -} - -bool TorManager::getHiddenServiceInfo(QString& service_id,QString& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port) -{ - QList hidden_services = control()->hiddenServices(); - - if(hidden_services.empty()) - return false ; - - // Only return the first one. - - for(auto it(hidden_services.begin());it!=hidden_services.end();++it) - { - service_onion_address = (*it)->hostname(); - service_id = (*it)->serviceId(); - - for(auto it2((*it)->targets().begin());it2!=(*it)->targets().end();++it2) - { - service_port = (*it2).servicePort ; - service_target_address = (*it2).targetAddress ; - target_port = (*it2).targetPort; - break ; - } - break ; - } - return true ; -} - -void TorManagerPrivate::processStateChanged(int state) -{ - std::cerr << Q_FUNC_INFO << "state: " << state << " passwd=\"" << QString(process->controlPassword()).toStdString() << "\" " << process->controlHost().toString().toStdString() - << ":" << process->controlPort() << std::endl; - if (state == TorProcess::Ready) { - control->setAuthPassword(process->controlPassword()); - control->connect(process->controlHost(), process->controlPort()); - } -} - -void TorManagerPrivate::processErrorChanged(const QString &errorMessage) -{ - std::cerr << "tor error:" << errorMessage.toStdString() << std::endl; - setError(errorMessage); -} - -void TorManagerPrivate::processLogMessage(const QString &message) -{ - std::cerr << "tor:" << message.toStdString() << std::endl; - if (logMessages.size() >= 50) - logMessages.takeFirst(); - logMessages.append(message); -} - -void TorManagerPrivate::controlStatusChanged(int status) -{ - if (status == TorControl::Connected) { - if (!configNeeded) { - // If DisableNetwork is 1, trigger configurationNeeded - connect(control->getConfiguration(QStringLiteral("DisableNetwork")), - SIGNAL(finished()), SLOT(getConfFinished())); - } - - if (process) { - // Take ownership via this control socket - control->takeOwnership(); - } - } -} - -void TorManagerPrivate::getConfFinished() -{ - GetConfCommand *command = qobject_cast(sender()); - if (!command) - return; - - if (command->get("DisableNetwork").toInt() == 1 && !configNeeded) { - configNeeded = true; - emit q->configurationNeededChanged(); - } -} - -QString TorManagerPrivate::torExecutablePath() const -{ - SettingsObject settings(QStringLiteral("tor")); - QString path = settings.read("executablePath").toString(); - - if (!path.isEmpty() && QFile::exists(path)) - return path; - -#ifdef Q_OS_WIN - QString filename(QStringLiteral("/tor.exe")); -#else - QString filename(QStringLiteral("/tor")); -#endif - - path = qApp->applicationDirPath(); - - if (QFile::exists(path + filename)) - return path + filename; - -#ifdef BUNDLED_TOR_PATH - path = QStringLiteral(BUNDLED_TOR_PATH); - if (QFile::exists(path + filename)) - return path + filename; -#endif - -#ifdef __APPLE__ - // on MacOS, try traditional brew installation path - - path = QStringLiteral("/usr/local/opt/tor/bin") ; - - if (QFile::exists(path + filename)) - return path + filename; -#endif - - // Try $PATH - return filename.mid(1); -} - -bool TorManagerPrivate::createDataDir(const QString &path) -{ - QDir dir(path); - return dir.mkpath(QStringLiteral(".")); -} - -bool TorManagerPrivate::createDefaultTorrc(const QString &path) -{ - static const char defaultTorrcContent[] = - "SocksPort auto\n" - "AvoidDiskWrites 1\n" -// "DisableNetwork 1\n" // (cyril) I removed this because it prevents Tor to bootstrap. - "__ReloadTorrcOnSIGHUP 0\n"; - - QFile file(path); - if (!file.open(QIODevice::WriteOnly)) - return false; - if (file.write(defaultTorrcContent) < 0) - return false; - return true; -} - -void TorManagerPrivate::setError(const QString &message) -{ - errorMessage = message; - emit q->errorChanged(); -} - -#include "TorManager.moc" - diff --git a/retroshare-gui/src/TorControl/TorManager.h b/retroshare-gui/src/TorControl/TorManager.h deleted file mode 100644 index e9acc1208..000000000 --- a/retroshare-gui/src/TorControl/TorManager.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// This code has been further modified to fit Retroshare context. - -#ifndef TORMANAGER_H -#define TORMANAGER_H - -#include -#include -#include - -namespace Tor -{ - -class TorProcess; -class TorControl; -class TorManagerPrivate; - -/* Run/connect to an instance of Tor according to configuration, and manage - * UI interaction, first time configuration, etc. */ -class TorManager : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool configurationNeeded READ configurationNeeded NOTIFY configurationNeededChanged) - Q_PROPERTY(QStringList logMessages READ logMessages CONSTANT) - Q_PROPERTY(Tor::TorProcess* process READ process CONSTANT) - Q_PROPERTY(Tor::TorControl* control READ control CONSTANT) - Q_PROPERTY(bool hasError READ hasError NOTIFY errorChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorChanged) - Q_PROPERTY(QString torDataDirectory READ torDataDirectory WRITE setTorDataDirectory) - -public: - static bool isTorAvailable() ; - static TorManager *instance(); - - TorProcess *process(); - TorControl *control(); - - - QString torDataDirectory() const; - void setTorDataDirectory(const QString &path); - - QString hiddenServiceDirectory() const; - void setHiddenServiceDirectory(const QString &path); - - // Starts a hidden service, loading it from the config directory that has been set earlier. - bool setupHiddenService() ; - - // True on first run or when the Tor configuration wizard needs to be shown - bool configurationNeeded() const; - - QStringList logMessages() const; - - bool hasError() const; - QString errorMessage() const; - - bool getHiddenServiceInfo(QString& service_id,QString& service_onion_address,uint16_t& service_port, QHostAddress& service_target_address,uint16_t& target_port); - bool getProxyServerInfo(QHostAddress& proxy_server_adress,uint16_t& proxy_server_port); - -public slots: - bool start(); - -private slots: - void hiddenServicePrivateKeyChanged(); - void hiddenServiceHostnameChanged(); - void hiddenServiceStatusChanged(int old_status,int new_status); - -signals: - void configurationNeededChanged(); - void errorChanged(); - -private: - explicit TorManager(QObject *parent = 0); - TorManagerPrivate *d; -}; - -} - -#endif -# diff --git a/retroshare-gui/src/TorControl/TorProcess.cpp b/retroshare-gui/src/TorControl/TorProcess.cpp deleted file mode 100644 index ca1aecfe5..000000000 --- a/retroshare-gui/src/TorControl/TorProcess.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "TorProcess_p.h" -#include "CryptoKey.h" -#include "SecureRNG.h" -#include -#include -#include - -using namespace Tor; - -TorProcess::TorProcess(QObject *parent) - : QObject(parent), d(new TorProcessPrivate(this)) -{ -} - -TorProcess::~TorProcess() -{ - if (state() > NotStarted) - stop(); -} - -TorProcessPrivate::TorProcessPrivate(TorProcess *q) - : QObject(q), q(q), state(TorProcess::NotStarted), controlPort(0), controlPortAttempts(0) -{ - connect(&process, &QProcess::started, this, &TorProcessPrivate::processStarted); - connect(&process, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, - this, &TorProcessPrivate::processFinished); - connect(&process, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, - this, &TorProcessPrivate::processError); - connect(&process, &QProcess::readyRead, this, &TorProcessPrivate::processReadable); - - controlPortTimer.setInterval(500); - connect(&controlPortTimer, &QTimer::timeout, this, &TorProcessPrivate::tryReadControlPort); -} - -QString TorProcess::executable() const -{ - return d->executable; -} - -void TorProcess::setExecutable(const QString &path) -{ - d->executable = path; -} - -QString TorProcess::dataDir() const -{ - return d->dataDir; -} - -void TorProcess::setDataDir(const QString &path) -{ - d->dataDir = path; -} - -QString TorProcess::defaultTorrc() const -{ - return d->defaultTorrc; -} - -void TorProcess::setDefaultTorrc(const QString &path) -{ - d->defaultTorrc = path; -} - -QStringList TorProcess::extraSettings() const -{ - return d->extraSettings; -} - -void TorProcess::setExtraSettings(const QStringList &settings) -{ - d->extraSettings = settings; -} - -TorProcess::State TorProcess::state() const -{ - return d->state; -} - -QString TorProcess::errorMessage() const -{ - return d->errorMessage; -} - -void TorProcess::start() -{ - if (state() > NotStarted) - return; - - d->errorMessage.clear(); - - if (d->executable.isEmpty() || d->dataDir.isEmpty()) { - d->errorMessage = QStringLiteral("Tor executable and data directory not specified"); - d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); - return; - } - - if (!d->ensureFilesExist()) { - d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); - return; - } - - QByteArray password = controlPassword(); - QByteArray hashedPassword = torControlHashedPassword(password); - if (password.isEmpty() || hashedPassword.isEmpty()) { - d->errorMessage = QStringLiteral("Random password generation failed"); - d->state = Failed; - emit errorMessageChanged(d->errorMessage); - emit stateChanged(d->state); - } - - QStringList args; - if (!d->defaultTorrc.isEmpty()) - args << QStringLiteral("--defaults-torrc") << d->defaultTorrc; - args << QStringLiteral("-f") << d->torrcPath(); - args << QStringLiteral("DataDirectory") << d->dataDir; - args << QStringLiteral("HashedControlPassword") << QString::fromLatin1(hashedPassword); - args << QStringLiteral("ControlPort") << QStringLiteral("auto"); - args << QStringLiteral("ControlPortWriteToFile") << d->controlPortFilePath(); - args << QStringLiteral("__OwningControllerProcess") << QString::number(qApp->applicationPid()); - args << d->extraSettings; - - d->state = Starting; - emit stateChanged(d->state); - - if (QFile::exists(d->controlPortFilePath())) - QFile::remove(d->controlPortFilePath()); - d->controlPort = 0; - d->controlHost.clear(); - - d->process.setProcessChannelMode(QProcess::MergedChannels); - d->process.start(d->executable, args, QIODevice::ReadOnly); -} - -void TorProcess::stop() -{ - if (state() < Starting) - return; - - d->controlPortTimer.stop(); - - if (d->process.state() == QProcess::Starting) - d->process.waitForStarted(2000); - - d->state = NotStarted; - - // Windows can't terminate the process well, but Tor will clean itself up -#ifndef Q_OS_WIN - if (d->process.state() == QProcess::Running) { - d->process.terminate(); - if (!d->process.waitForFinished(5000)) { - qWarning() << "Tor process" << d->process.pid() << "did not respond to terminate, killing..."; - d->process.kill(); - if (!d->process.waitForFinished(2000)) { - qCritical() << "Tor process" << d->process.pid() << "did not respond to kill!"; - } - } - } -#endif - - emit stateChanged(d->state); -} - -QByteArray TorProcess::controlPassword() -{ - if (d->controlPassword.isEmpty()) - d->controlPassword = SecureRNG::randomPrintable(16); - return d->controlPassword; -} - -QHostAddress TorProcess::controlHost() -{ - return d->controlHost; -} - -quint16 TorProcess::controlPort() -{ - return d->controlPort; -} - -bool TorProcessPrivate::ensureFilesExist() -{ - QFile torrc(torrcPath()); - if (!torrc.exists()) { - QDir dir(dataDir); - if (!dir.exists() && !dir.mkpath(QStringLiteral("."))) { - errorMessage = QStringLiteral("Cannot create Tor data directory: %1").arg(dataDir); - return false; - } - - if (!torrc.open(QIODevice::ReadWrite)) { - errorMessage = QStringLiteral("Cannot create Tor configuration file: %1").arg(torrcPath()); - return false; - } - } - - return true; -} - -QString TorProcessPrivate::torrcPath() const -{ - return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("torrc"); -} - -QString TorProcessPrivate::controlPortFilePath() const -{ - return QDir::toNativeSeparators(dataDir) + QDir::separator() + QStringLiteral("control-port"); -} - -void TorProcessPrivate::processStarted() -{ - state = TorProcess::Connecting; - emit q->stateChanged(state); - - controlPortAttempts = 0; - controlPortTimer.start(); -} - -void TorProcessPrivate::processFinished() -{ - if (state < TorProcess::Starting) - return; - - controlPortTimer.stop(); - errorMessage = process.errorString(); - if (errorMessage.isEmpty()) - errorMessage = QStringLiteral("Process exited unexpectedly (code %1)").arg(process.exitCode()); - state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); -} - -void TorProcessPrivate::processError(QProcess::ProcessError error) -{ - if (error == QProcess::FailedToStart || error == QProcess::Crashed) - processFinished(); -} - -void TorProcessPrivate::processReadable() -{ - while (process.bytesAvailable() > 0) { - QByteArray line = process.readLine(2048).trimmed(); - if (!line.isEmpty()) - emit q->logMessage(QString::fromLatin1(line)); - } -} - -void TorProcessPrivate::tryReadControlPort() -{ - QFile file(controlPortFilePath()); - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.readLine().trimmed(); - - int p; - if (data.startsWith("PORT=") && (p = data.lastIndexOf(':')) > 0) { - controlHost = QHostAddress(QString::fromLatin1(data.mid(5, p - 5))); - controlPort = data.mid(p+1).toUShort(); - - if (!controlHost.isNull() && controlPort > 0) { - controlPortTimer.stop(); - state = TorProcess::Ready; - emit q->stateChanged(state); - return; - } - } - } - - if (++controlPortAttempts * controlPortTimer.interval() > 10000) { - errorMessage = QStringLiteral("No control port available after launching process"); - state = TorProcess::Failed; - emit q->errorMessageChanged(errorMessage); - emit q->stateChanged(state); - } -} - diff --git a/retroshare-gui/src/TorControl/TorProcess.h b/retroshare-gui/src/TorControl/TorProcess.h deleted file mode 100644 index ad489dc43..000000000 --- a/retroshare-gui/src/TorControl/TorProcess.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORPROCESS_H -#define TORPROCESS_H - -#include -#include - -namespace Tor -{ - -class TorProcessPrivate; - -/* Launches and controls a Tor instance with behavior suitable for bundling - * an instance with the application. */ -class TorProcess : public QObject -{ - Q_OBJECT - Q_ENUMS(State) - - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged) - -public: - enum State { - Failed = -1, - NotStarted, - Starting, - Connecting, - Ready - }; - - explicit TorProcess(QObject *parent = 0); - virtual ~TorProcess(); - - QString executable() const; - void setExecutable(const QString &path); - - QString dataDir() const; - void setDataDir(const QString &path); - - QString defaultTorrc() const; - void setDefaultTorrc(const QString &path); - - QStringList extraSettings() const; - void setExtraSettings(const QStringList &settings); - - State state() const; - QString errorMessage() const; - QHostAddress controlHost(); - quint16 controlPort(); - QByteArray controlPassword(); - -public slots: - void start(); - void stop(); - -signals: - void stateChanged(int newState); - void errorMessageChanged(const QString &errorMessage); - void logMessage(const QString &message); - -private: - TorProcessPrivate *d; -}; - -} - -#endif - diff --git a/retroshare-gui/src/TorControl/TorProcess_p.h b/retroshare-gui/src/TorControl/TorProcess_p.h deleted file mode 100644 index 9aa2585e3..000000000 --- a/retroshare-gui/src/TorControl/TorProcess_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORPROCESS_P_H -#define TORPROCESS_P_H - -#include "TorProcess.h" -#include -#include - -namespace Tor { - -class TorProcessPrivate : public QObject -{ - Q_OBJECT - -public: - TorProcess *q; - QProcess process; - QString executable; - QString dataDir; - QString defaultTorrc; - QStringList extraSettings; - TorProcess::State state; - QString errorMessage; - QHostAddress controlHost; - quint16 controlPort; - QByteArray controlPassword; - - QTimer controlPortTimer; - int controlPortAttempts; - - TorProcessPrivate(TorProcess *q); - - QString torrcPath() const; - QString controlPortFilePath() const; - bool ensureFilesExist(); - -public slots: - void processStarted(); - void processFinished(); - void processError(QProcess::ProcessError error); - void processReadable(); - void tryReadControlPort(); -}; - -} - -#endif - diff --git a/retroshare-gui/src/TorControl/TorSocket.cpp b/retroshare-gui/src/TorControl/TorSocket.cpp deleted file mode 100644 index fb9c07b26..000000000 --- a/retroshare-gui/src/TorControl/TorSocket.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "TorSocket.h" -#include "TorControl.h" -#include - -using namespace Tor; - -TorSocket::TorSocket(QObject *parent) - : QTcpSocket(parent) - , m_port(0) - , m_reconnectEnabled(true) - , m_maxInterval(900) - , m_connectAttempts(0) -{ - connect(torControl, SIGNAL(connectivityChanged()), SLOT(connectivityChanged())); - connect(&m_connectTimer, SIGNAL(timeout()), SLOT(reconnect())); - connect(this, SIGNAL(disconnected()), SLOT(onFailed())); - connect(this, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onFailed())); - - m_connectTimer.setSingleShot(true); - connectivityChanged(); -} - -TorSocket::~TorSocket() -{ -} - -void TorSocket::setReconnectEnabled(bool enabled) -{ - if (enabled == m_reconnectEnabled) - return; - - m_reconnectEnabled = enabled; - if (m_reconnectEnabled) { - m_connectAttempts = 0; - reconnect(); - } else { - m_connectTimer.stop(); - } -} - -void TorSocket::setMaxAttemptInterval(int interval) -{ - m_maxInterval = interval; -} - -void TorSocket::resetAttempts() -{ - m_connectAttempts = 0; - if (m_connectTimer.isActive()) { - m_connectTimer.stop(); - m_connectTimer.start(reconnectInterval() * 1000); - } -} - -int TorSocket::reconnectInterval() -{ - int delay = 0; - if (m_connectAttempts <= 4) - delay = 30; - else if (m_connectAttempts <= 6) - delay = 120; - else - delay = m_maxInterval; - - return qMin(delay, m_maxInterval); -} - -void TorSocket::reconnect() -{ - if (!torControl->hasConnectivity() || !reconnectEnabled()) - return; - - m_connectTimer.stop(); - if (!m_host.isEmpty() && m_port) { - std::cerr << "Attempting reconnection of socket to" << m_host.toStdString() << ":" << m_port << std::endl; - connectToHost(m_host, m_port); - } -} - -void TorSocket::connectivityChanged() -{ - if (torControl->hasConnectivity()) { - setProxy(torControl->connectionProxy()); - if (state() == QAbstractSocket::UnconnectedState) - reconnect(); - } else { - m_connectTimer.stop(); - m_connectAttempts = 0; - } -} - -void TorSocket::connectToHost(const QString &hostName, quint16 port, OpenMode openMode, - NetworkLayerProtocol protocol) -{ - m_host = hostName; - m_port = port; - - if (!torControl->hasConnectivity()) - return; - - if (proxy() != torControl->connectionProxy()) - setProxy(torControl->connectionProxy()); - - QAbstractSocket::connectToHost(hostName, port, openMode, protocol); -} - -void TorSocket::connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode) -{ - TorSocket::connectToHost(address.toString(), port, openMode); -} - -void TorSocket::onFailed() -{ - // Make sure the internal connection to the SOCKS proxy is closed - // Otherwise reconnect attempts will fail (#295) - close(); - - if (reconnectEnabled() && !m_connectTimer.isActive()) { - m_connectAttempts++; - m_connectTimer.start(reconnectInterval() * 1000); - std::cerr << "Reconnecting socket to" << m_host.toStdString() << ":" << m_port << "in" << m_connectTimer.interval() / 1000 << "seconds" << std::endl; - } -} diff --git a/retroshare-gui/src/TorControl/TorSocket.h b/retroshare-gui/src/TorControl/TorSocket.h deleted file mode 100644 index 0c68f7854..000000000 --- a/retroshare-gui/src/TorControl/TorSocket.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TORSOCKET_H -#define TORSOCKET_H - -#include -#include - -namespace Tor { - -/* Specialized QTcpSocket which makes connections over the SOCKS proxy - * from a TorControl instance, automatically attempts reconnections, and - * reacts to Tor's connectivity state. - * - * Use normal QTcpSocket/QAbstractSocket API. When a connection fails, it - * will be retried automatically after the correct interval and when - * connectivity is available. - * - * To fully disconnect, destroy the object, or call - * setReconnectEnabled(false) and disconnect the socket with - * disconnectFromHost or abort. - * - * The caller is responsible for resetting the attempt counter if a - * connection was successful and reconnection will be used again. - */ -class TorSocket : public QTcpSocket -{ - Q_OBJECT - -public: - explicit TorSocket(QObject *parent = 0); - virtual ~TorSocket(); - - bool reconnectEnabled() const { return m_reconnectEnabled; } - void setReconnectEnabled(bool enabled); - int maxAttemptInterval() { return m_maxInterval; } - void setMaxAttemptInterval(int interval); - void resetAttempts(); - - virtual void connectToHost(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol); - virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite); - - QString hostName() const { return m_host; } - quint16 port() const { return m_port; } - -protected: - virtual int reconnectInterval(); - -private slots: - void reconnect(); - void connectivityChanged(); - void onFailed(); - -private: - QString m_host; - quint16 m_port; - QTimer m_connectTimer; - bool m_reconnectEnabled; - int m_maxInterval; - int m_connectAttempts; - - using QAbstractSocket::connectToHost; -}; - -} - -#endif diff --git a/retroshare-gui/src/TorControl/Useful.h b/retroshare-gui/src/TorControl/Useful.h deleted file mode 100644 index 6bb6e44c1..000000000 --- a/retroshare-gui/src/TorControl/Useful.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Ricochet - https://ricochet.im/ - * Copyright (C) 2014, John Brooks - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * * Neither the names of the copyright owners nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef UTILS_USEFUL_H -#define UTILS_USEFUL_H - -#include -#include - -/* Print a warning for bug conditions, and assert on a debug build. - * - * This should be used in place of Q_ASSERT for bug conditions, along - * with a proper error case for release-mode builds. For example: - * - * if (!connection || !user) { - * BUG() << "Request" << request << "should have a connection and user"; - * return false; - * } - * - * Do not confuse bugs with actual error cases; BUG() should never be - * triggered unless the code or logic is wrong. - */ -#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) -# define BUG() Explode(__FILE__,__LINE__), qWarning() << "BUG:" -namespace { -class Explode -{ -public: - const char *file; - int line; - Explode(const char *file, int line) : file(file), line(line) { } - ~Explode() { - qt_assert("something broke!", file, line); - } -}; -} -#else -# define BUG() qWarning() << "BUG:" -#endif - -#endif - diff --git a/retroshare-gui/src/changelog.txt b/retroshare-gui/src/changelog.txt index 3da31f03c..24c784d1a 100644 --- a/retroshare-gui/src/changelog.txt +++ b/retroshare-gui/src/changelog.txt @@ -439,7 +439,7 @@ Changes for 0.5.4e - Enabled embedded images in private chat and messages (only for QT version 4.7.0 and higher) - added tooltips to GroupFlagsWidget when buttons are unchecked (Patch from Anonym) - when an unknow user attempt to connect, show the name in the security item (Patch from Anonym) - - Load new stylesheets for locale depended things. Loading order: qss.default (internal), qss. (internal e.g. qss.de_DE) + - Load new stylesheets for locale depended things. Loading order: default.qss (internal), .qss (internal e.g. de_DE.qss) stylesheet.qss (internal or external), stylesheet_.lqss (parallel to stylesheet) - Added api for news feeds to the plugin interface. Added news feeds to the FeedReader plugin. - Removed toaster for muted participant of a chat lobby. @@ -586,7 +586,7 @@ Changes for 0.5.4c - GUI * patch from AC to perform html optimization of forum posts using the canonical function optimizeHtml() * fixed bug preventing share manager to modify more than one directory at once - * Moved most of the hardcoded colors of lists and trees to the file qss.default (with help from braindead). + * Moved most of the hardcoded colors of lists and trees to the file default.qss (with help from braindead). Now the stylesheet can redefine these colors. * Added multiselective mute/unmute to chat lobby. Added mute/unmute with double click on icon. * Added flag for hungarian language. @@ -790,10 +790,10 @@ Changes for 0.5.4a * Set the built-in stylesheet "Standard" as default for new profiles. * Removed some unnecessary style sheets. * Added two internal stylesheets: - - qss.default - This file is used as default for all stylesheets (e.g. the frames of + - default.qss - This file is used as default for all stylesheets (e.g. the frames of the AvatarWidget) and can be overloaded from the selected stylesheet - Standard.qss - The standard stylesheet for the current look of RetroShare. More internal stylesheets can be added. - The plan is to move nearly all internal stylesheets to the files Standard.qss/qss.default. + The plan is to move nearly all internal stylesheets to the files Standard.qss/default.qss. After that the "empty" stylesheet should represent the system theme of the os. - Added clear chat history to the context menu of the message text browser @@ -3121,4 +3121,4 @@ We have available for those interested in retroshare: (2) deb installation files for debian/etch and kubuntu/feisty (3) Language pack for those interested in translating. - \ No newline at end of file + diff --git a/retroshare-gui/src/gui/AboutWidget.cpp b/retroshare-gui/src/gui/AboutWidget.cpp index aa239650e..b468550b1 100644 --- a/retroshare-gui/src/gui/AboutWidget.cpp +++ b/retroshare-gui/src/gui/AboutWidget.cpp @@ -21,7 +21,7 @@ #include "AboutDialog.h" #include "HelpDialog.h" -#include "qmake_info.h" +#include "include/qmake_info.h" #include "rshare.h" #ifdef RS_JSONAPI @@ -52,8 +52,8 @@ AboutWidget::AboutWidget(QWidget* parent) l->setMargin(0); l->addStretch(1); l->addStretch(1); - frame->setContentsMargins(0, 0, 0, 0); - frame->setLayout(l); + specialFrame->setContentsMargins(0, 0, 0, 0); + specialFrame->setLayout(l); tWidget = NULL; aWidget = NULL; installAWidget(); @@ -67,7 +67,7 @@ AboutWidget::AboutWidget(QWidget* parent) void AboutWidget::installAWidget() { assert(tWidget == NULL); aWidget = new AWidget(); - QVBoxLayout* l = (QVBoxLayout*)frame->layout(); + QVBoxLayout* l = (QVBoxLayout*)specialFrame->layout(); l->insertWidget(0, aWidget); l->setStretchFactor(aWidget, 100); aWidget->setFocus(); @@ -96,10 +96,10 @@ void AboutWidget::installTWidget() { vl->addWidget(levelLabel); vl->addStretch(); - QHBoxLayout* l = (QHBoxLayout*)frame->layout(); + QHBoxLayout* l = (QHBoxLayout*)specialFrame->layout(); l->insertWidget(0, pan); l->insertWidget(0, tWidget); - QRect cRect = frame->contentsRect(); + QRect cRect = specialFrame->contentsRect(); int height = tWidget->heightForWidth(cRect.width()); tWidget->setFixedSize(cRect.width() * cRect.height() / height, cRect.height()); npLabel->setFixedSize(tWidget->squareWidth()*4, tWidget->squareHeight()*5); @@ -117,7 +117,7 @@ void AboutWidget::installTWidget() { void AboutWidget::switchPages() { QLayoutItem* li = NULL; - QLayout* l = frame->layout(); + QLayout* l = specialFrame->layout(); while ((li = l->takeAt(0)) && li->widget()) { li->widget()->deleteLater(); } @@ -158,9 +158,9 @@ void AboutWidget::updateTitle() void AboutWidget::mousePressEvent(QMouseEvent *e) { QPoint globalPos = mapToGlobal(e->pos()); - QPoint framePos = frame->mapFromGlobal(globalPos); + QPoint framePos = specialFrame->mapFromGlobal(globalPos); - if (frame->contentsRect().contains(framePos)) { + if (specialFrame->contentsRect().contains(framePos)) { { if(e->modifiers() & Qt::ControlModifier) switchPages(); diff --git a/retroshare-gui/src/gui/AboutWidget.ui b/retroshare-gui/src/gui/AboutWidget.ui index 99b638388..548d6fd9a 100644 --- a/retroshare-gui/src/gui/AboutWidget.ui +++ b/retroshare-gui/src/gui/AboutWidget.ui @@ -57,7 +57,7 @@ - + QFrame::StyledPanel diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.cpp b/retroshare-gui/src/gui/ChatLobbyWidget.cpp index 475495674..0b5350110 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.cpp +++ b/retroshare-gui/src/gui/ChatLobbyWidget.cpp @@ -22,19 +22,20 @@ #include "ChatLobbyWidget.h" #include "notifyqt.h" +#include "RetroShareLink.h" #include "chat/ChatLobbyDialog.h" #include "chat/ChatLobbyUserNotify.h" #include "chat/ChatTabWidget.h" #include "chat/CreateLobbyDialog.h" +#include "common/FilesDefs.h" #include "common/RSTreeWidgetItem.h" #include "common/RSElidedItemDelegate.h" -#include "gui/RetroShareLink.h" -#include "gui/gxs/GxsIdDetails.h" -#include "gui/Identity/IdEditDialog.h" -#include "gui/settings/rsharesettings.h" +#include "gxs/GxsIdDetails.h" +#include "Identity/IdEditDialog.h" +#include "settings/rsharesettings.h" #include "util/HandleRichText.h" +#include "util/misc.h" #include "util/QtVersion.h" -#include "gui/common/FilesDefs.h" #include "retroshare/rsmsgs.h" #include "retroshare/rspeers.h" @@ -59,6 +60,10 @@ #define COLUMN_COUNT 3 #define COLUMN_DATA 0 +#define COLUMN_NAME_NB_CHAR 30 +#define COLUMN_USER_COUNT_NB_CHAR 4 +#define COLUMN_TOPIC_NB_CHAR 25 + #define ROLE_SORT Qt::UserRole #define ROLE_ID Qt::UserRole + 1 #define ROLE_SUBSCRIBED Qt::UserRole + 2 @@ -88,26 +93,37 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) { ui.setupUi(this); + int H = QFontMetricsF(ui.lobbyTreeWidget->font()).height(); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui.lobbyTreeWidget->font()).width("_"); +#else + int W = QFontMetricsF(ui.lobbyTreeWidget->font()).horizontalAdvance("_"); +#endif + m_bProcessSettings = false; myChatLobbyUserNotify = NULL; myInviteYesButton = NULL; myInviteIdChooser = NULL; QObject::connect( NotifyQt::getInstance(), SIGNAL(lobbyListChanged()), SLOT(lobbyChanged())); - QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&)), this, SLOT(displayChatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&))); + QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyEvent(qulonglong,int,RsGxsId,QString)), this, SLOT(displayChatLobbyEvent(qulonglong,int,RsGxsId,QString))); QObject::connect( NotifyQt::getInstance(), SIGNAL(chatLobbyInviteReceived()), this, SLOT(readChatLobbyInvites())); QObject::connect( ui.lobbyTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(lobbyTreeWidgetCustomPopupMenu(QPoint))); QObject::connect( ui.lobbyTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*,int))); QObject::connect( ui.lobbyTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(updateCurrentLobby())); - QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString))); + QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); QObject::connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); QObject::connect( ui.createLobbyToolButton, SIGNAL(clicked()), this, SLOT(createChatLobby())); compareRole = new RSTreeWidgetItemCompareRole; compareRole->setRole(COLUMN_NAME, ROLE_SORT); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(W/2, H/4)); + ui.lobbyTreeWidget->setItemDelegate(itemDelegate); + ui.lobbyTreeWidget->setColumnCount(COLUMN_COUNT); ui.lobbyTreeWidget->sortItems(COLUMN_NAME, Qt::AscendingOrder); @@ -159,14 +175,11 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ; ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ; ui.lobbyTreeWidget->setSortingEnabled(true) ; - ui.lobbyTreeWidget->setItemDelegateForColumn(COLUMN_NAME, new RSElidedItemDelegate()); - float fact = QFontMetricsF(font()).height()/14.0f; - ui.lobbyTreeWidget->adjustSize(); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_NAME,100*fact); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_USER_COUNT, 50*fact); - ui.lobbyTreeWidget->setColumnWidth(COLUMN_TOPIC, 50*fact); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_NAME,COLUMN_NAME_NB_CHAR*W); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_USER_COUNT, COLUMN_USER_COUNT_NB_CHAR*W); + ui.lobbyTreeWidget->setColumnWidth(COLUMN_TOPIC, COLUMN_TOPIC_NB_CHAR*W); /** Setup the actions for the header context menu */ showUserCountAct= new QAction(headerItem->text(COLUMN_USER_COUNT),this); @@ -181,7 +194,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) ui.splitter->setStretchFactor(1, 1); QList sizes; - sizes << 200*fact << width(); // Qt calculates the right sizes + sizes << ui.lobbyTreeWidget->columnWidth(COLUMN_NAME) << width(); // Qt calculates the right sizes ui.splitter->setSizes(sizes); lobbyChanged(); @@ -194,29 +207,29 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags) // load settings processSettings(true); - int S = QFontMetricsF(font()).height(); - QString help_str = tr("\ -

  Chat Rooms

\ -

Chat rooms work pretty much like IRC. \ - They allow you to talk anonymously with tons of people without the need to make friends.

\ -

A chat room can be public (your friends see it) or private (your friends can't see it, unless you \ - invite them with ). \ - Once you have been invited to a private room, you will be able to see it when your friends \ - are using it.

\ -

The list at left shows \ - chat lobbies your friends are participating in. You can either \ -

    \ -
  • Right click to create a new chat room
  • \ -
  • Double click a chat room to enter, chat, and show it to your friends
  • \ -
\ - Note: For the chat rooms to work properly, your computer needs be on time. So check your system clock!\ -

\ - " - ).arg(QString::number(2*S)).arg(QString::number(S)) ; + int hbH = misc::getFontSizeFactor("HelpButton").height(); + QString help_str = tr( + "

  Chat Rooms

" + "

Chat rooms work pretty much like IRC." + " They allow you to talk anonymously with tons of people without the need to make friends.

" + "

A chat room can be public (your friends see it) or private (your friends can't see it, unless you" + " invite them with )." + " Once you have been invited to a private room, you will be able to see it when your friends" + " are using it.

" + "

The list at left shows" + " chat lobbies your friends are participating in. You can either" + "

    " + "
  • Right click to create a new chat room
  • " + "
  • Double click a chat room to enter, chat, and show it to your friends
  • " + "
" + " Note: For the chat rooms to work properly, your computer needs be on time. So check your system clock!" + "

" + ).arg(QString::number(2*hbH), QString::number(hbH)) ; - registerHelpButton(ui.helpButton,help_str,"ChatLobbyDialog") ; - - ui.lobbyTreeWidget->setIconSize(QSize(S*1.5,S*1.5)); + registerHelpButton(ui.helpButton,help_str,"ChatLobbyDialog") ; + + int ltwH = misc::getFontSizeFactor("LobbyTreeWidget", 1.5).height(); + ui.lobbyTreeWidget->setIconSize(QSize(ltwH,ltwH)); } ChatLobbyWidget::~ChatLobbyWidget() @@ -232,7 +245,7 @@ ChatLobbyWidget::~ChatLobbyWidget() UserNotify *ChatLobbyWidget::createUserNotify(QObject *parent) { myChatLobbyUserNotify = new ChatLobbyUserNotify(parent); - connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId, unsigned int)), this, SLOT(updateNotify(ChatLobbyId, unsigned int))); + connect(myChatLobbyUserNotify, SIGNAL(countChanged(ChatLobbyId,uint)), this, SLOT(updateNotify(ChatLobbyId,uint))); return myChatLobbyUserNotify; } @@ -282,87 +295,84 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint) QMenu contextMnu(this); if (item && item->type() == TYPE_FOLDER) { - QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_CREATE), tr("Create chat room"), this, SLOT(createChatLobby())); + QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_CREATE), tr("Create chat room"), this, SLOT(createChatLobby())); action->setData(item->data(COLUMN_DATA, ROLE_PRIVACYLEVEL).toInt()); } - if (item && item->type() == TYPE_LOBBY) - { - std::list own_identities ; - rsIdentity->getOwnIds(own_identities) ; + if (item && item->type() == TYPE_LOBBY) + { + std::list own_identities ; + rsIdentity->getOwnIds(own_identities) ; - if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) - contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_UNSUBSCRIBE), tr("Leave this room"), this, SLOT(unsubscribeItem())); - else - { - QTreeWidgetItem *item = ui.lobbyTreeWidget->currentItem(); + if (item->data(COLUMN_DATA, ROLE_SUBSCRIBED).toBool()) + contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_UNSUBSCRIBE), tr("Leave this room"), this, SLOT(unsubscribeItem())); + else + { + ChatLobbyFlags flags(item->data(COLUMN_DATA, ROLE_FLAGS).toUInt()); - //ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong(); - ChatLobbyFlags flags(item->data(COLUMN_DATA, ROLE_FLAGS).toUInt()); + bool removed = false ; + if(flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) + removed = trimAnonIds(own_identities) ; - bool removed = false ; - if(flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) - removed = trimAnonIds(own_identities) ; - - if(own_identities.empty()) - { - if(removed) - contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Create a non anonymous identity and enter this room"), this, SLOT(createIdentityAndSubscribe())); - else - contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Create an identity and enter this chat room"), this, SLOT(createIdentityAndSubscribe())); - } - else if(own_identities.size() == 1) - { - QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Enter this chat room"), this, SLOT(subscribeChatLobbyAs())); - action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; - } - else - { - QMenu *mnu = contextMnu.addMenu(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE),tr("Enter this chat room as...")) ; + if(own_identities.empty()) + { + if(removed) + contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Create a non anonymous identity and enter this room"), this, SLOT(createIdentityAndSubscribe())); + else + contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Create an identity and enter this chat room"), this, SLOT(createIdentityAndSubscribe())); + } + else if(own_identities.size() == 1) + { + QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE), tr("Enter this chat room"), this, SLOT(subscribeChatLobbyAs())); + action->setData(QString::fromStdString((own_identities.front()).toStdString())) ; + } + else + { + QMenu *mnu = contextMnu.addMenu(FilesDefs::getIconFromQtResourcePath(IMAGE_SUBSCRIBE),tr("Enter this chat room as...")) ; - for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) - { - RsIdentityDetails idd ; - rsIdentity->getIdDetails(*it,idd) ; + for(std::list::const_iterator it=own_identities.begin();it!=own_identities.end();++it) + { + RsIdentityDetails idd ; + rsIdentity->getIdDetails(*it,idd) ; - QPixmap pixmap ; + QPixmap pixmap ; - if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap, GxsIdDetails::SMALL)) - pixmap = GxsIdDetails::makeDefaultIcon(*it,GxsIdDetails::SMALL) ; + if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap, GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(*it,GxsIdDetails::SMALL) ; - QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(subscribeChatLobbyAs())); - action->setData(QString::fromStdString((*it).toStdString())) ; - } - } - } + QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(subscribeChatLobbyAs())); + action->setData(QString::fromStdString((*it).toStdString())) ; + } + } + } #ifdef TO_BE_REMOVED - // This code is not needed anymore because AutoSubscribe is now automatically handled with chat room subscription. + // This code is not needed anymore because AutoSubscribe is now automatically handled with chat room subscription. - if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool()) - contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem())); - else if(!own_identities.empty()) - contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem())); + if (item->data(COLUMN_DATA, ROLE_AUTOSUBSCRIBE).toBool()) + contextMnu.addAction(QIcon(IMAGE_AUTOSUBSCRIBE), tr("Remove Auto Subscribe"), this, SLOT(autoSubscribeItem())); + else if(!own_identities.empty()) + contextMnu.addAction(QIcon(IMAGE_SUBSCRIBE), tr("Add Auto Subscribe"), this, SLOT(autoSubscribeItem())); #endif - contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYRSLINK), tr("Copy RetroShare Link"), this, SLOT(copyItemLink())); - } + contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYRSLINK), tr("Copy RetroShare Link"), this, SLOT(copyItemLink())); + } - contextMnu.addSeparator();//------------------------------------------------------------------- + contextMnu.addSeparator();//------------------------------------------------------------------- - showUserCountAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_USER_COUNT)); - showTopicAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_TOPIC)); + showUserCountAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_USER_COUNT)); + showTopicAct->setChecked(!ui.lobbyTreeWidget->isColumnHidden(COLUMN_TOPIC)); - QMenu *menu = contextMnu.addMenu(tr("Columns")); - menu->addAction(showUserCountAct); - menu->addAction(showTopicAct); + QMenu *menu = contextMnu.addMenu(tr("Columns")); + menu->addAction(showUserCountAct); + menu->addAction(showTopicAct); - contextMnu.exec(QCursor::pos()); + contextMnu.exec(QCursor::pos()); } void ChatLobbyWidget::lobbyChanged() { - updateDisplay(); + ChatLobbyWidget::updateDisplay(); } static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobbyId id, const std::string &name, const std::string &topic, int count, bool subscribed, bool autoSubscribe,ChatLobbyFlags lobby_flags) @@ -596,7 +606,7 @@ void ChatLobbyWidget::updateDisplay() QTreeWidgetItem *itemLoop = lobby_other_item->child(childIndex); if (itemLoop->type() == TYPE_LOBBY && itemLoop->data(COLUMN_DATA, ROLE_ID).toULongLong() == lobby.lobby_id) { delete(lobby_other_item->takeChild(lobby_other_item->indexOfChild(itemLoop))); - childCnt = lobby_other_item->childCount(); + //childCnt = lobby_other_item->childCount(); break; } } @@ -920,7 +930,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/) } } - ui.lobbyInfoLabel->setText(text); + ui.info_Label_Lobby->setText(text); return ; } @@ -932,7 +942,7 @@ void ChatLobbyWidget::showBlankPage(ChatLobbyId id, bool subscribed /*= false*/) ui.lobbysec_lineEdit->clear(); QString text = tr("No chat room selected. \nSelect chat rooms at left to show details.\nDouble click a chat room to enter and chat.") ; - ui.lobbyInfoLabel->setText(text) ; + ui.info_Label_Lobby->setText(text) ; } void ChatLobbyWidget::subscribeItem() @@ -1116,6 +1126,7 @@ void ChatLobbyWidget::updateCurrentLobby() filterItems(ui.filterLineEdit->text()); } } + void ChatLobbyWidget::updateMessageChanged(bool incoming, ChatLobbyId id, QDateTime time, QString senderName, QString msg) { QTreeWidgetItem *current_item = ui.lobbyTreeWidget->currentItem(); @@ -1174,9 +1185,11 @@ void ChatLobbyWidget::readChatLobbyInvites() if(found) continue ; - QMessageBox mb(QObject::tr("Join chat room"), - tr("%1 invites you to chat room named %2").arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str())).arg(RsHtml::plainText(it->lobby_name)), - QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0); + QMessageBox mb(QObject::tr("Join chat room") + , tr("%1 invites you to chat room named %2") + .arg(QString::fromUtf8(rsPeers->getPeerName((*it).peer_id).c_str()) + , RsHtml::plainText(it->lobby_name)) + , QMessageBox::Question, QMessageBox::Yes,QMessageBox::No, 0); QLabel *label; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.h b/retroshare-gui/src/gui/ChatLobbyWidget.h index a9bb01895..a5055788e 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.h +++ b/retroshare-gui/src/gui/ChatLobbyWidget.h @@ -56,18 +56,18 @@ class ChatLobbyWidget : public RsAutoUpdatePage public: /** Default constructor */ - ChatLobbyWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ChatLobbyWidget(QWidget *parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()); /** Default destructor */ ~ChatLobbyWidget(); - virtual QIcon iconPixmap() const { return QIcon(IMAGE_CHATLOBBY) ; } //MainPage - virtual QString pageName() const { return tr("Chats") ; } //MainPage - virtual QString helpText() const { return ""; } //MainPage + virtual QIcon iconPixmap() const override { return QIcon(IMAGE_CHATLOBBY) ; } //MainPage + virtual QString pageName() const override { return tr("Chats") ; } //MainPage + virtual QString helpText() const override { return ""; } //MainPage virtual UserNotify *createUserNotify(QObject *parent) override; //MainPage - virtual void updateDisplay(); + virtual void updateDisplay() override; //RsAutoUpdatePage void setCurrentChatPage(ChatLobbyDialog *) ; // used by ChatLobbyDialog to raise. void addChatPage(ChatLobbyDialog *) ; diff --git a/retroshare-gui/src/gui/ChatLobbyWidget.ui b/retroshare-gui/src/gui/ChatLobbyWidget.ui index 4a4f863ef..8f8e8f29d 100644 --- a/retroshare-gui/src/gui/ChatLobbyWidget.ui +++ b/retroshare-gui/src/gui/ChatLobbyWidget.ui @@ -70,7 +70,14 @@
- + + + + 12 + 75 + true + + Chat rooms @@ -95,7 +102,7 @@ Qt::NoFocus - + :/icons/help_64.png:/icons/help_64.png @@ -183,7 +190,12 @@ - + + + + 11 + + 16 @@ -228,6 +240,13 @@ + + + 12 + 75 + true + + @@ -244,6 +263,7 @@ + 12 75 true @@ -261,6 +281,13 @@ 0 + + + 16 + 75 + true + + TextLabel @@ -270,6 +297,7 @@ + 12 75 true @@ -296,6 +324,7 @@ + 12 75 true @@ -325,6 +354,7 @@ + 12 75 true @@ -351,6 +381,7 @@ + 12 75 true @@ -371,6 +402,7 @@ + 12 75 true @@ -396,7 +428,7 @@
- + TextLabel @@ -435,13 +467,12 @@
gui/common/LineEditClear.h
- StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSTreeWidget + QTreeWidget +
gui/common/RSTreeWidget.h
- diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.cpp b/retroshare-gui/src/gui/Circles/CirclesDialog.cpp index 41fd4e9f2..a05ff2f20 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.cpp @@ -25,6 +25,7 @@ #include "gui/Circles/CirclesDialog.h" #include "gui/Circles/CreateCircleDialog.h" #include "gui/common/UIStateHelper.h" +#include "util/qtthreadsutils.h" #include #include @@ -72,9 +73,6 @@ CirclesDialog::CirclesDialog(QWidget *parent) connect(ui.treeWidget_membership, SIGNAL(itemSelectionChanged()), this, SLOT(circle_selected())); - /* Setup TokenQueue */ - mCircleQueue = new TokenQueue(rsGxsCircles->getTokenService(), this); - /* Set header resize modes and initial section sizes */ QHeaderView * membership_header = ui.treeWidget_membership->header () ; membership_header->resizeSection ( CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 200 ); @@ -82,7 +80,6 @@ CirclesDialog::CirclesDialog(QWidget *parent) CirclesDialog::~CirclesDialog() { - delete mCircleQueue; } void CirclesDialog::todo() @@ -564,38 +561,36 @@ void CirclesDialog::requestGroupMeta() { mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, true); - std::cerr << "CirclesDialog::requestGroupMeta()"; - std::cerr << std::endl; + RsThread::async([this]() + { + std::list circles; - mCircleQueue->cancelActiveRequestTokens(CIRCLESDIALOG_GROUPMETA); + if(!rsGxsCircles->getCirclesSummaries(circles)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to get circles summaries " << std::endl; + return; + } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + RsQThreadUtils::postToObject( [this,circles]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ - uint32_t token; - mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA); + loadGroupMeta(circles); + + }, this ); + }); } -void CirclesDialog::loadGroupMeta(const uint32_t &token) +void CirclesDialog::loadGroupMeta(const std::list& groupInfo) { mStateHelper->setLoading(CIRCLESDIALOG_GROUPMETA, false); - std::cerr << "CirclesDialog::loadGroupMeta()"; - std::cerr << std::endl; - ui.treeWidget_membership->clear(); - std::list groupInfo; - std::list::iterator vit; - - if (!rsGxsCircles->getGroupSummary(token,groupInfo)) - { - std::cerr << "CirclesDialog::loadGroupMeta() Error getting GroupMeta"; - std::cerr << std::endl; - mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, false); - return; - } - mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true); /* add the top level item */ @@ -615,7 +610,7 @@ void CirclesDialog::loadGroupMeta(const uint32_t &token) externalOtherCirclesItem->setText(0, tr("External Circles (Other)")); ui.treeWidget_membership->addTopLevelItem(externalOtherCirclesItem); - for(vit = groupInfo.begin(); vit != groupInfo.end(); ++vit) + for(auto vit = groupInfo.begin(); vit != groupInfo.end(); ++vit) { /* Add Widget, and request Pages */ std::cerr << "CirclesDialog::loadGroupMeta() GroupId: " << vit->mGroupId; @@ -647,25 +642,3 @@ void CirclesDialog::loadGroupMeta(const uint32_t &token) } } } - -void CirclesDialog::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - std::cerr << "CirclesDialog::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; - - if (queue == mCircleQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - case CIRCLESDIALOG_GROUPMETA: - loadGroupMeta(req.mToken); - break; - - default: - std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; - break; - } - } -} diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.h b/retroshare-gui/src/gui/Circles/CirclesDialog.h index ac87f9f61..56011dc61 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.h +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.h @@ -24,14 +24,13 @@ #define MRK_CIRCLE_DIALOG_H #include "gui/gxs/RsGxsUpdateBroadcastPage.h" -#include "util/TokenQueue.h" #include "ui_CirclesDialog.h" #define IMAGE_CIRCLES ":/icons/png/circles.png" class UIStateHelper; -class CirclesDialog : public MainPage, public TokenResponse +class CirclesDialog : public MainPage { Q_OBJECT @@ -43,8 +42,6 @@ public: virtual QString pageName() const { return tr("Circles") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage - void loadRequest(const TokenQueue *queue, const TokenRequest &req); - protected: virtual void updateDisplay(bool complete); @@ -62,9 +59,8 @@ private: void reloadAll(); void requestGroupMeta(); - void loadGroupMeta(const uint32_t &token); + void loadGroupMeta(const std::list& groupInfo); - TokenQueue *mCircleQueue; UIStateHelper *mStateHelper; /* UI - from Designer */ diff --git a/retroshare-gui/src/gui/Circles/CirclesDialog.ui b/retroshare-gui/src/gui/Circles/CirclesDialog.ui index da9da0b8b..05b89146b 100644 --- a/retroshare-gui/src/gui/Circles/CirclesDialog.ui +++ b/retroshare-gui/src/gui/Circles/CirclesDialog.ui @@ -49,7 +49,14 @@
- + + + + 12 + 75 + true + + Circles @@ -247,13 +254,6 @@
- - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
-
diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index d0640e4ea..92003e0a6 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -98,7 +98,7 @@ CreateCircleDialog::CreateCircleDialog() connect(ui.addButton, SIGNAL(clicked()), this, SLOT(addMember())); connect(ui.removeButton, SIGNAL(clicked()), this, SLOT(removeMember())); - connect(ui.createButton, SIGNAL(clicked()), this, SLOT(createCircle())); + connect(ui.postButton, SIGNAL(clicked()), this, SLOT(createCircle())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(close())); connect(ui.treeWidget_membership, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectedMember(QTreeWidgetItem*, QTreeWidgetItem*))); @@ -187,14 +187,14 @@ void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool ui.idChooser->setVisible(true) ; } - ui.createButton->setText(tr("Update")); + ui.postButton->setText(tr("Update")); ui.addButton->setEnabled(!readonly) ; ui.removeButton->setEnabled(!readonly) ; if(readonly) { - ui.createButton->hide() ; + ui.postButton->hide() ; ui.cancelButton->setText(tr("Close")); ui.peersSelection_GB->hide() ; ui.addButton->hide() ; @@ -216,7 +216,7 @@ void CreateCircleDialog::editNewId(bool isExternal) { setupForExternalCircle(); ui.headerFrame->setHeaderText(tr("Create New Circle")); - ui.createButton->setText(tr("Create")); + ui.postButton->setText(tr("Create")); } else { @@ -357,8 +357,8 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype, member->setText(RSCIRCLEID_COL_IDTYPE, idtype); tree->addTopLevelItem(member); - - ui.members_groupBox->setTitle( tr("Invited Members") + " (" + QString::number(ui.treeWidget_membership->topLevelItemCount()) + ")" ); + + updateMembership(); } /** Maybe we can use RsGxsCircleGroup instead of RsGxsCircleDetails ??? (TODO)**/ @@ -413,6 +413,8 @@ void CreateCircleDialog::removeMember() // does this just work? (TODO) delete(item); + + updateMembership(); } void CreateCircleDialog::createCircle() @@ -422,7 +424,7 @@ void CreateCircleDialog::createCircle() close() ; return ; } - + #ifdef DEBUG_CREATE_CIRCLE_DIALOG std::cerr << "CreateCircleDialog::createCircle()"; std::cerr << std::endl; @@ -431,10 +433,10 @@ void CreateCircleDialog::createCircle() QString name = ui.circleName->text(); if(name.isEmpty()) { - /* error message */ - QMessageBox::warning(this, tr("RetroShare"),tr("Please set a name for your Circle"), QMessageBox::Ok, QMessageBox::Ok); + /* error message */ + QMessageBox::warning(this, tr("RetroShare"),tr("Please set a name for your Circle"), QMessageBox::Ok, QMessageBox::Ok); - return; //Don't add a empty Subject!! + return; //Don't add a empty Subject!! } RsGxsCircleGroup circle = mCircleGroup; // init with loaded group @@ -448,19 +450,23 @@ void CreateCircleDialog::createCircle() { case GxsIdChooser::KnowId: case GxsIdChooser::UnKnowId: - circle.mMeta.mAuthorId = authorId; -#ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() AuthorId: " << authorId; - std::cerr << std::endl; + circle.mMeta.mAuthorId = authorId; + circle.mMeta.mAuthenFlags = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; + +#ifdef DEBUG_CREATE_CIRCLE_DIALOG + std::cerr << "CreateCircleDialog::createCircle() AuthorId: " << authorId; + std::cerr << std::endl; #endif - break; + break; case GxsIdChooser::NoId: case GxsIdChooser::None: + circle.mMeta.mAuthorId.clear(); + circle.mMeta.mAuthenFlags = 0; default: ; #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() No AuthorId Chosen!"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() No AuthorId Chosen!"; + std::cerr << std::endl; #endif } @@ -468,144 +474,164 @@ void CreateCircleDialog::createCircle() /* copy Ids from GUI */ QTreeWidget *tree = ui.treeWidget_membership; int count = tree->topLevelItemCount(); - for(int i = 0; i < count; ++i) + for(int i = 0; i < count; ++i) { - QTreeWidgetItem *item = tree->topLevelItem(i); - QString keyId = item->text(RSCIRCLEID_COL_KEYID); + QTreeWidgetItem *item = tree->topLevelItem(i); + QString keyId = item->text(RSCIRCLEID_COL_KEYID); - /* insert into circle */ - if (mIsExternalCircle) - { - RsGxsId key_id_gxs(keyId.toStdString()) ; + /* insert into circle */ + if (mIsExternalCircle) + { + RsGxsId key_id_gxs(keyId.toStdString()) ; - if(key_id_gxs.isNull()) - { - std::cerr << "Error: Not a proper keyID: " << keyId.toStdString() << std::endl; - continue ; - } + if(key_id_gxs.isNull()) + { + std::cerr << "Error: Not a proper keyID: " << keyId.toStdString() << std::endl; + continue ; + } - circle.mInvitedMembers.insert(key_id_gxs) ; + circle.mInvitedMembers.insert(key_id_gxs) ; #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() Inserting Member: " << keyId.toStdString(); - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() Inserting Member: " << keyId.toStdString(); + std::cerr << std::endl; #endif - } - else - { - RsPgpId key_id_pgp(keyId.toStdString()) ; + } + else + { + RsPgpId key_id_pgp(keyId.toStdString()) ; - if(key_id_pgp.isNull()) - { - std::cerr << "Error: Not a proper PGP keyID: " << keyId.toStdString() << std::endl; - continue ; - } + if(key_id_pgp.isNull()) + { + std::cerr << "Error: Not a proper PGP keyID: " << keyId.toStdString() << std::endl; + continue ; + } - circle.mLocalFriends.insert(key_id_pgp) ; + circle.mLocalFriends.insert(key_id_pgp) ; #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() Inserting Friend: " << keyId.toStdString(); - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() Inserting Friend: " << keyId.toStdString(); + std::cerr << std::endl; #endif - } + } } - if (mIsExternalCircle) + if (mIsExternalCircle) { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() External Circle"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() External Circle"; + std::cerr << std::endl; #endif - // set distribution from GUI. - circle.mMeta.mCircleId.clear() ; + // set distribution from GUI. + circle.mMeta.mCircleId.clear() ; circle.mMeta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_PUBLIC; - if (ui.radioButton_Public->isChecked()) { + if (ui.radioButton_Public->isChecked()) { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() Public Circle"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() Public Circle"; + std::cerr << std::endl; #endif - circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC; + circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_PUBLIC; - } else if (ui.radioButton_Self->isChecked()) { + } else if (ui.radioButton_Self->isChecked()) { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() ExtSelfRef Circle"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() ExtSelfRef Circle"; + std::cerr << std::endl; #endif - circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXT_SELF; - } else if (ui.radioButton_Restricted->isChecked()) { + circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXT_SELF; + } else if (ui.radioButton_Restricted->isChecked()) { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() External (Other) Circle"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() External (Other) Circle"; + std::cerr << std::endl; #endif - circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXTERNAL; + circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_EXTERNAL; - /* grab circle ID from chooser */ - RsGxsCircleId chosenId; - if (ui.circleComboBox->getChosenCircle(chosenId)) { + /* grab circle ID from chooser */ + RsGxsCircleId chosenId; + if (ui.circleComboBox->getChosenCircle(chosenId)) { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() ChosenId: " << chosenId; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() ChosenId: " << chosenId; + std::cerr << std::endl; #endif - circle.mMeta.mCircleId = chosenId; - } else {//if (ui.circleComboBox->getChosenCircle(chosenId)) + circle.mMeta.mCircleId = chosenId; + } else {//if (ui.circleComboBox->getChosenCircle(chosenId)) #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() Error no Id Chosen"; - std::cerr << std::endl; + std::cerr << "CreateCircleDialog::createCircle() Error no Id Chosen"; + std::cerr << std::endl; #endif - QMessageBox::warning(this, tr("RetroShare"),tr("No Restriction Circle Selected"), QMessageBox::Ok, QMessageBox::Ok); - return; - }//else (ui.circleComboBox->getChosenCircle(chosenId)) - } - else - { - QMessageBox::warning(this, tr("RetroShare"),tr("No Circle Limitations Selected"), QMessageBox::Ok, QMessageBox::Ok); - return; - } - } - else - { -#ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() Personal Circle"; - std::cerr << std::endl; -#endif - - // set personal distribution - circle.mMeta.mCircleId.clear() ; - circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_LOCAL; - } - - uint32_t token; - - if(mIsExistingCircle) - { -#ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::updateCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl; - std::cerr << "CreateCircleDialog::updateCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl; - std::cerr << "CreateCircleDialog::updateCircle() : mGroupId: " << circle.mMeta.mGroupId << std::endl; - - std::cerr << "CreateCircleDialog::updateCircle() Checks and Balances Okay - calling service proper.."<< std::endl; -#endif - - rsGxsCircles->updateGroup(token, circle); + QMessageBox::warning(this, tr("RetroShare"),tr("No Restriction Circle Selected"), QMessageBox::Ok, QMessageBox::Ok); + return; + }//else (ui.circleComboBox->getChosenCircle(chosenId)) + } + else + { + QMessageBox::warning(this, tr("RetroShare"),tr("No Circle Limitations Selected"), QMessageBox::Ok, QMessageBox::Ok); + return; + } } else - { + { #ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::createCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl; - std::cerr << "CreateCircleDialog::createCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl; - - std::cerr << "CreateCircleDialog::createCircle() Checks and Balances Okay - calling service proper.."<< std::endl; + std::cerr << "CreateCircleDialog::createCircle() Personal Circle"; + std::cerr << std::endl; #endif - rsGxsCircles->createGroup(token, circle); + // set personal distribution + circle.mMeta.mCircleId.clear() ; + circle.mMeta.mCircleType = GXS_CIRCLE_TYPE_LOCAL; } + bool is_existing_circle(mIsExistingCircle); + + RsThread::async([circle,is_existing_circle]() + { + RsGxsCircleId circleId; + + if(is_existing_circle) + { +#ifdef DEBUG_CREATE_CIRCLE_DIALOG + std::cerr << "CreateCircleDialog::updateCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl; + std::cerr << "CreateCircleDialog::updateCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl; + std::cerr << "CreateCircleDialog::updateCircle() : mGroupId: " << circle.mMeta.mGroupId << std::endl; + + std::cerr << "CreateCircleDialog::updateCircle() Checks and Balances Okay - calling service proper.."<< std::endl; +#endif + rsGxsCircles->editCircle(*const_cast(&circle)); // const_cast: Not nice, but simpler. + + circleId = RsGxsCircleId(circle.mMeta.mGroupId); + } + else + { +#ifdef DEBUG_CREATE_CIRCLE_DIALOG + std::cerr << "CreateCircleDialog::createCircle() : mCircleType: " << circle.mMeta.mCircleType << std::endl; + std::cerr << "CreateCircleDialog::createCircle() : mCircleId: " << circle.mMeta.mCircleId << std::endl; + + std::cerr << "CreateCircleDialog::createCircle() Checks and Balances Okay - calling service proper.."<< std::endl; +#endif + rsGxsCircles->createCircle(circle.mMeta.mGroupName, + static_cast(circle.mMeta.mCircleType), + circleId, + circle.mMeta.mCircleId, + circle.mMeta.mAuthorId, + circle.mInvitedMembers, + circle.mLocalFriends); + } + + if(!is_existing_circle) + RsQThreadUtils::postToObject( [circle,circleId]() + { + QMessageBox::information(nullptr,tr("Circle created"), + tr("Your new circle has been created:\n Name: %1\n Id: %2.") + .arg(QString::fromUtf8(circle.mMeta.mGroupName.c_str())) + .arg(QString::fromStdString(circleId.toStdString()))); + }); + }); + close(); } @@ -806,11 +832,6 @@ void CreateCircleDialog::loadIdentities() void CreateCircleDialog::fillIdentitiesList(const std::vector& id_groups) { -#ifdef DEBUG_CREATE_CIRCLE_DIALOG - std::cerr << "CreateCircleDialog::loadIdentities(" << token << ")"; - std::cerr << std::endl; -#endif - QTreeWidget *tree = ui.treeWidget_IdList; tree->clear(); @@ -826,7 +847,6 @@ void CreateCircleDialog::fillIdentitiesList(const std::vector& id_ bool isSignedByFriendNode = isSigned && rsPeers->isPgpFriend(idGroup.mPgpId); /* do filtering */ - bool ok = false; if(!(acceptAll ||(acceptOnlySignedIdentities && isSigned) ||(acceptOnlyIdentitiesSignedByFriend && isSignedByFriendNode))) { @@ -934,3 +954,8 @@ void CreateCircleDialog::MembershipListCustomPopupMenu( QPoint ) contextMnu.exec(QCursor::pos()); } +void CreateCircleDialog::updateMembership() +{ + ui.members_groupBox->setTitle( tr("Invited Members") + " (" + QString::number(ui.treeWidget_membership->topLevelItemCount()) + ")" ); +} + diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.h b/retroshare-gui/src/gui/Circles/CreateCircleDialog.h index fbbaacb2c..5e713b9c3 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.h +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.h @@ -56,6 +56,7 @@ private slots: void filterChanged(const QString &text); void createNewGxsId(); void idTypeChanged(); + void updateMembership(); /** Create the context popup menu and it's submenus */ void IdListCustomPopupMenu( QPoint point ); diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui index 54e1fe80f..62390e56a 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui @@ -13,7 +13,7 @@ - + 0 @@ -40,226 +40,225 @@ - + QFrame::StyledPanel QFrame::Raised - + Circle Details - + + + 11 + - - - - - - 75 - true - - - - Qt::LeftToRight - - - Name: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - <html><head/><body><p>The circle name, contact author and invited member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.</p></body></html> - - - - - - - - 75 - true - - - - Contact author: - - - - - - - - 0 - 0 - - - - <html><head/><body><p>The creator of a circle is purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.</p></body></html> - - - - - - - [Circle Admin] - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - 75 - true - - - - Distribution: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 2 + + + + 75 + true + + + + Qt::LeftToRight + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <html><head/><body><p>The circle name, contact author and invited member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.</p></body></html> + + + + + + + + 75 + true + + + + Contact author: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>The creator of a circle is purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.</p></body></html> + + + + + + + [Circle Admin] + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 75 + true + + + + Distribution: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + 2 + + + 2 + + + + + <html><head/><body><p>Publicly distributed circles are visible to your friends, which will get to know the circle data (Creator, members, etc)</p></body></html> - - 2 + + Public - - 2 + + + :/icons/png/network-puplic.png:/icons/png/network-puplic.png - - 2 + + + 24 + 24 + - - - - <html><head/><body><p>Publicly distributed circles are visible to your friends, which will get to know the circle data (Creator, members, etc)</p></body></html> - - - Public - - - - :/icons/png/network-puplic.png:/icons/png/network-puplic.png - - - - 24 - 24 - - - - - - - - <html><head/><body><p>Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. </p></body></html> - - - Private - - - - :/icons/png/person.png:/icons/png/person.png - - - - 24 - 24 - - - - - - - - <html><head/><body><p>Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).</p></body></html> - - - Only &visible to members of: - - - - :/icons/png/circles.png:/icons/png/circles.png - - - - 24 - 24 - - - - - - - - - - - Qt::Horizontal - - - - 147 - 20 - - - - - - - - + + + + + + <html><head/><body><p>Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. </p></body></html> + + + Private + + + + :/icons/png/person.png:/icons/png/person.png + + + + 24 + 24 + + + + + + + + <html><head/><body><p>Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).</p></body></html> + + + Only &visible to members of: + + + + :/icons/png/circles.png:/icons/png/circles.png + + + + 24 + 24 + + + + + + + + + + + Qt::Horizontal + + + + 147 + 20 + + + + + + - + Invited Members - + @@ -287,9 +286,9 @@ - + - + Qt::Vertical @@ -330,7 +329,7 @@ - + Qt::Vertical @@ -378,7 +377,7 @@ QFrame::Raised - + 0 @@ -419,9 +418,9 @@ - + - + Filter @@ -438,7 +437,7 @@ - + Qt::Horizontal @@ -451,7 +450,14 @@ - + + + + 12 + 75 + true + + Create @@ -503,7 +509,6 @@ - diff --git a/retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp b/retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp index 4385af476..3fc982012 100644 --- a/retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp +++ b/retroshare-gui/src/gui/FileTransfer/DLListDelegate.cpp @@ -32,6 +32,8 @@ Q_DECLARE_METATYPE(FileProgressInfo) +#define MAX_CHAR_TMP 128 + DLListDelegate::DLListDelegate(QObject *parent) : QAbstractItemDelegate(parent) { } @@ -180,7 +182,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti } painter->drawText(option.rect, Qt::AlignCenter, newopt.text); break; - case COLUMN_SOURCES: + case COLUMN_SOURCES: { double dblValue = index.data().toDouble(); @@ -188,7 +190,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti painter->drawText(option.rect, Qt::AlignCenter, temp); } break; - case COLUMN_PRIORITY: + case COLUMN_PRIORITY: { double dblValue = index.data().toDouble(); if (dblValue == PRIORITY_NULL) @@ -205,7 +207,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti painter->drawText(option.rect, Qt::AlignCenter, temp); } break; - case COLUMN_DOWNLOADTIME: + case COLUMN_DOWNLOADTIME: downloadtime = index.data().toLongLong(); minutes = downloadtime / 60; seconds = downloadtime % 60; @@ -225,7 +227,7 @@ void DLListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti temp = "" ; painter->drawText(option.rect, Qt::AlignCenter, temp); break; - case COLUMN_NAME: + case COLUMN_NAME: { // decoration int pixOffset = 0; diff --git a/retroshare-gui/src/gui/FileTransfer/DLListDelegate.h b/retroshare-gui/src/gui/FileTransfer/DLListDelegate.h index 3b67934fe..19b9306a5 100644 --- a/retroshare-gui/src/gui/FileTransfer/DLListDelegate.h +++ b/retroshare-gui/src/gui/FileTransfer/DLListDelegate.h @@ -18,55 +18,40 @@ * * *******************************************************************************/ -#ifndef DLLISTDELEGATE_H -#define DLLISTDELEGATE_H +#pragma once #include #include "xprogressbar.h" - -// Defines for download list list columns -#define COLUMN_NAME 0 -#define COLUMN_SIZE 1 -#define COLUMN_COMPLETED 2 -#define COLUMN_DLSPEED 3 -#define COLUMN_PROGRESS 4 -#define COLUMN_SOURCES 5 -#define COLUMN_STATUS 6 -#define COLUMN_PRIORITY 7 -#define COLUMN_REMAINING 8 -#define COLUMN_DOWNLOADTIME 9 -#define COLUMN_ID 10 -#define COLUMN_LASTDL 11 -#define COLUMN_PATH 12 -#define COLUMN_COUNT 13 - -#define PRIORITY_NULL 0.0 -#define PRIORITY_FASTER 0.1 -#define PRIORITY_AVERAGE 0.2 -#define PRIORITY_SLOWER 0.3 - -#define MAX_CHAR_TMP 128 - class QModelIndex; class QPainter; +class DLListDelegate: public QAbstractItemDelegate +{ +public: + DLListDelegate(QObject *parent=0); + virtual ~DLListDelegate(){} + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; + QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const; -class DLListDelegate: public QAbstractItemDelegate { + static constexpr int COLUMN_NAME = 0; + static constexpr int COLUMN_SIZE = 1; + static constexpr int COLUMN_COMPLETED = 2; + static constexpr int COLUMN_DLSPEED = 3; + static constexpr int COLUMN_PROGRESS = 4; + static constexpr int COLUMN_SOURCES = 5; + static constexpr int COLUMN_STATUS = 6; + static constexpr int COLUMN_PRIORITY = 7; + static constexpr int COLUMN_REMAINING = 8; + static constexpr int COLUMN_DOWNLOADTIME= 9; + static constexpr int COLUMN_ID = 10; + static constexpr int COLUMN_LASTDL = 11; + static constexpr int COLUMN_PATH = 12; + static constexpr int COLUMN_COUNT = 13; - Q_OBJECT - - public: - DLListDelegate(QObject *parent=0); - virtual ~DLListDelegate(){} - void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; - QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const; - - private: - - public slots: - - signals: + static constexpr float PRIORITY_NULL = 0.0; + static constexpr float PRIORITY_FASTER = 0.1; + static constexpr float PRIORITY_AVERAGE = 0.2; + static constexpr float PRIORITY_SLOWER = 0.3; }; -#endif diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 9c3703032..832970833 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -37,6 +37,7 @@ #include "gui/advsearch/advancedsearchdialog.h" #include "gui/common/RSTreeWidgetItem.h" #include "util/QtVersion.h" +#include "util/qtthreadsutils.h" #include #include @@ -85,6 +86,18 @@ const int SearchDialog::FILETYPE_IDX_DIRECTORY = 8; QMap * SearchDialog::FileTypeExtensionMap = new QMap(); bool SearchDialog::initialised = false; +struct SearchDialog::FileDetail +{ +public: + RsPeerId id; + std::string name; + RsFileHash hash; + std::string path; + uint64_t size; + uint32_t mtime; + uint32_t rank; +}; + /** Constructor */ SearchDialog::SearchDialog(QWidget *parent) : MainPage(parent), @@ -121,10 +134,10 @@ SearchDialog::SearchDialog(QWidget *parent) connect( ui.searchSummaryWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( searchSummaryWidgetCustomPopupMenu( QPoint ) ) ); connect( ui.showBannedFiles_TB, SIGNAL( clicked() ), this, SLOT( openBannedFiles() ) ); - connect( ui.lineEdit, SIGNAL( returnPressed ( void ) ), this, SLOT( searchKeywords( void ) ) ); + connect( ui.lineEdit, SIGNAL( returnPressed () ), this, SLOT( searchKeywords() ) ); connect( ui.lineEdit, SIGNAL( textChanged ( const QString& ) ), this, SLOT( checkText( const QString& ) ) ); - connect( ui.pushButtonSearch, SIGNAL( released ( void ) ), this, SLOT( searchKeywords( void ) ) ); - connect( ui.pushButtonDownload, SIGNAL( released ( void ) ), this, SLOT( download( void ) ) ); + connect( ui.searchButton, SIGNAL( released () ), this, SLOT( searchKeywords() ) ); + connect( ui.pushButtonDownload, SIGNAL( released () ), this, SLOT( download() ) ); connect( ui.cloaseallsearchresultsButton, SIGNAL(clicked()), this, SLOT(searchRemoveAll())); connect( ui.searchResultWidget, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *, int)), this, SLOT(download())); @@ -186,13 +199,12 @@ SearchDialog::SearchDialog(QWidget *parent) _smheader->resizeSection ( SR_AGE_COL, 90*f ); _smheader->resizeSection ( SR_HASH_COL, 240*f ); - // set header text aligment - QTreeWidgetItem * headerItem = ui.searchResultWidget->headerItem(); - headerItem->setTextAlignment(SR_NAME_COL, Qt::AlignRight | Qt::AlignRight); - headerItem->setTextAlignment(SR_SIZE_COL, Qt::AlignRight | Qt::AlignRight); - ui.searchResultWidget->sortItems(SR_NAME_COL, Qt::AscendingOrder); + QFontMetricsF fontMetrics(ui.searchResultWidget->font()); + int iconHeight = fontMetrics.height() * 1.4; + ui.searchResultWidget->setIconSize(QSize(iconHeight, iconHeight)); + /* Set initial size the splitter */ QList sizes; sizes << 250 << width(); // Qt calculates the right sizes @@ -218,6 +230,15 @@ SearchDialog::SearchDialog(QWidget *parent) checkText(ui.lineEdit->text()); + // add an event handler to get search results (previously available through notifyQt) + + mEventHandlerId = 0; + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId, RsEventType::FILE_TRANSFER ); + } SearchDialog::~SearchDialog() @@ -236,6 +257,31 @@ SearchDialog::~SearchDialog() ui.searchResultWidget->setItemDelegateForColumn(SR_SIZE_COL, nullptr); ui.searchResultWidget->setItemDelegateForColumn(SR_AGE_COL, nullptr); + + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void SearchDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::FILE_TRANSFER) + return; + + auto fe = dynamic_cast(event.get()); + + if(!fe || fe->mFileTransferEventCode!=RsFileTransferEventCode::NEW_DISTANT_SEARCH_RESULTS) + return; + + for(uint32_t i=0;imResults.size();++i) + { + FileDetail f; + f.hash = fe->mResults[i].fHash; + f.name = fe->mResults[i].fName; + f.size = fe->mResults[i].fSize; + f.mtime = 0; // zero what's not available, otherwise we'll get some random values displayed. + f.rank = 0; + + updateFiles(fe->mRequestId,f); + } } void SearchDialog::processSettings(bool bLoad) @@ -276,30 +322,9 @@ void SearchDialog::processSettings(bool bLoad) void SearchDialog::checkText(const QString& txt) { - bool valid; - QColor color; - - if(txt.length() < 3) - { - std::cout << "setting palette 1" << std::endl ; - valid = false; - color = QApplication::palette().color(QPalette::Disabled, QPalette::Base); - } - else - { - std::cout << "setting palette 2" << std::endl ; - valid = true; - color = QApplication::palette().color(QPalette::Active, QPalette::Base); - } - - /* unpolish widget to clear the stylesheet's palette cache */ + ui.searchButton->setDisabled(txt.length() < 3); + ui.searchLineFrame->setProperty("valid", (txt.length() >= 3)); ui.searchLineFrame->style()->unpolish(ui.searchLineFrame); - - QPalette palette = ui.lineEdit->palette(); - palette.setColor(ui.lineEdit->backgroundRole(), color); - ui.lineEdit->setPalette(palette); - - ui.searchLineFrame->setProperty("valid", valid); Rshare::refreshStyleSheet(ui.searchLineFrame, false); } @@ -308,7 +333,7 @@ void SearchDialog::initialiseFileTypeMappings() /* edit these strings to change the range of extensions recognised by the search */ SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_ANY, ""); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_AUDIO, - "aac aif flac iff m3u m4a mid midi mp3 mpa ogg ra ram wav wma"); + "aac aif flac iff m3u m4a mid midi mp3 mpa ogg ra ram wav wma weba"); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_ARCHIVE, "7z bz2 gz pkg rar sea sit sitx tar zip tgz"); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_CDIMAGE, @@ -317,11 +342,11 @@ void SearchDialog::initialiseFileTypeMappings() "doc odt ott rtf pdf ps txt log msg wpd wps ods xls epub" ); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PICTURE, "3dm 3dmf ai bmp drw dxf eps gif ico indd jpe jpeg jpg mng pcx pcc pct pgm " - "pix png psd psp qxd qxprgb sgi svg tga tif tiff xbm xcf"); + "pix png psd psp qxd qxprgb sgi svg tga tif tiff xbm xcf webp"); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_PROGRAM, "app bat cgi com bin exe js pif py pl sh vb ws bash"); SearchDialog::FileTypeExtensionMap->insert(FILETYPE_IDX_VIDEO, - "3gp asf asx avi mov mp4 mkv flv mpeg mpg qt rm swf vob wmv"); + "3gp asf asx avi mov mp4 mkv flv mpeg mpg qt rm swf vob wmv webm"); SearchDialog::initialised = true; } @@ -393,11 +418,10 @@ void SearchDialog::download() /* should also be able to handle multi-selection */ QList itemsForDownload = ui.searchResultWidget->selectedItems() ; int numdls = itemsForDownload.size() ; - QTreeWidgetItem * item ; bool attemptDownloadLocal = false ; for (int i = 0; i < numdls; ++i) { - item = itemsForDownload.at(i) ; + QTreeWidgetItem *item = itemsForDownload.at(i) ; // call the download // * if (item->text(SR_HASH_COL).isEmpty()) { // we have a folder @@ -421,8 +445,8 @@ void SearchDialog::download() std::cout << *it << "-" << std::endl; QColor foreground = textColorDownloading(); - for (int i = 0; i < item->columnCount(); ++i) - item->setData(i, Qt::ForegroundRole, foreground ); + for (int j = 0; j < item->columnCount(); ++j) + item->setData(j, Qt::ForegroundRole, foreground ); } } } @@ -828,28 +852,29 @@ void SearchDialog::advancedSearch(RsRegularExpression::Expression* expression) { advSearchDialog->hide(); - /* call to core */ - std::list results; - // send a turtle search request RsRegularExpression::LinearizedExpression e ; expression->linearize(e) ; - TurtleRequestId req_id = rsFiles->turtleSearch(e) ; + TurtleRequestId req_id ; - // This will act before turtle results come to the interface, thanks to the signals scheduling policy. - initSearchResult(QString::fromStdString(e.GetStrings()),req_id, ui.FileTypeComboBox->currentIndex(), true) ; + if(ui._anonF2Fsearch_CB->isChecked()) + req_id = rsFiles->turtleSearch(e) ; + else + req_id = RSRandom::random_u32() ; // generate a random 32 bits request id - rsFiles -> SearchBoolExp(expression, results, RS_FILE_HINTS_REMOTE);// | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE); + initSearchResult(QString::fromStdString(e.GetStrings()),req_id, ui.FileTypeComboBox->currentIndex(), true) ; + + std::list results; + + FileSearchFlags flags(0); + if(ui._ownFiles_CB->isChecked()) flags |= RS_FILE_HINTS_LOCAL; + if(ui._friendListsearch_SB->isChecked()) flags |= RS_FILE_HINTS_REMOTE; + + rsFiles -> SearchBoolExp(expression, results, flags); /* abstraction to allow reusee of tree rendering code */ - resultsToTree(advSearchDialog->getSearchAsString(),req_id, results); - -// // debug stuff -// Expression *expression2 = LinearizedExpression::toExpr(e) ; -// results.clear() ; -// rsFiles -> SearchBoolExp(expression2, results, DIR_FLAGS_REMOTE | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE); -// resultsToTree((advSearchDialog->getSearchAsString()).toStdString(),req_id+1, results); + resultsToTree(advSearchDialog->getSearchAsString(),req_id, results); } void SearchDialog::searchKeywords() @@ -955,7 +980,7 @@ void SearchDialog::searchKeywords(const QString& keywords) } } -void SearchDialog::updateFiles(qulonglong search_id,FileDetail file) +void SearchDialog::updateFiles(qulonglong search_id,const FileDetail& file) { searchResultsQueue.push_back(std::pair(search_id,file)) ; @@ -983,7 +1008,7 @@ void SearchDialog::processResultQueue() while(!searchResultsQueue.empty() && nb_treated_elements++ < 250) { qulonglong search_id = searchResultsQueue.back().first ; - FileDetail& file = searchResultsQueue.back().second ; + const FileDetail& file = searchResultsQueue.back().second ; #ifdef DEBUG std::cout << "Updating file detail:" << std::endl ; @@ -1209,17 +1234,16 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s // bool found = false ; bool altname = false ; - int sources; - int friendSource = 0; - int anonymousSource = 0; QString modifiedResult; - QList itms = ui.searchResultWidget->findItems(QString::fromStdString(file.hash.toStdString()),Qt::MatchExactly,SR_HASH_COL) ; + QList itms = ui.searchResultWidget->findItems(QString::fromStdString(file.hash.toStdString()),Qt::MatchExactly,SR_HASH_COL) ; - for(QList::const_iterator it(itms.begin());it!=itms.end();++it) - if((*it)->text(SR_SEARCH_ID_COL) == sid_hexa) + for(auto &it : itms) + if(it->text(SR_SEARCH_ID_COL) == sid_hexa) { - QString resultCount = (*it)->text(SR_SOURCES_COL); + int friendSource = 0; + int anonymousSource = 0; + QString resultCount = it->text(SR_SOURCES_COL); QStringList modifiedResultCount = resultCount.split("/", QString::SkipEmptyParts); if(searchType == FRIEND_SEARCH) { @@ -1233,13 +1257,13 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } modifiedResult = QString::number(friendSource) + "/" + QString::number(anonymousSource); float fltRes = friendSource + (float)anonymousSource/1000; - (*it)->setText(SR_SOURCES_COL,modifiedResult); - (*it)->setData(SR_SOURCES_COL, ROLE_SORT, fltRes); - QTreeWidgetItem *item = (*it); + it->setText(SR_SOURCES_COL,modifiedResult); + it->setData(SR_SOURCES_COL, ROLE_SORT, fltRes); + QTreeWidgetItem *item = it; found = true ; - if(QString::compare((*it)->text(SR_NAME_COL), QString::fromUtf8(file.name.c_str()), Qt::CaseSensitive)!=0) + if(QString::compare(it->text(SR_NAME_COL), QString::fromUtf8(file.name.c_str()), Qt::CaseSensitive)!=0) altname = true; if (!item->data(SR_DATA_COL, SR_ROLE_LOCAL).toBool()) { @@ -1280,19 +1304,18 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } } - if(altname) - { - QTreeWidgetItem *item = new RSTreeWidgetItem(compareResultRole); - item->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); - item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); - setIconAndType(item, QString::fromUtf8(file.name.c_str())); - item->setText(SR_SIZE_COL, QString::number(file.size)); - setIconAndType(item, QString::fromUtf8(file.name.c_str())); - (*it)->addChild(item); + if(altname) + { + QTreeWidgetItem *altItem = new RSTreeWidgetItem(compareResultRole); + altItem->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); + altItem->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); + setIconAndType(altItem, QString::fromUtf8(file.name.c_str())); + altItem->setText(SR_SIZE_COL, QString::number(file.size)); + setIconAndType(altItem, QString::fromUtf8(file.name.c_str())); + it->addChild(altItem); + } } - } - if(!found) { ++nb_results[searchId] ; @@ -1301,7 +1324,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s QTreeWidgetItem *item = new RSTreeWidgetItem(compareResultRole); item->setText(SR_NAME_COL, QString::fromUtf8(file.name.c_str())); - item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); + item->setText(SR_HASH_COL, QString::fromStdString(file.hash.toStdString())); setIconAndType(item, QString::fromUtf8(file.name.c_str())); @@ -1311,9 +1334,11 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s item->setText(SR_SIZE_COL, QString::number(file.size)); item->setData(SR_SIZE_COL, ROLE_SORT, (qulonglong) file.size); - item->setText(SR_AGE_COL, QString::number(file.age)); - item->setData(SR_AGE_COL, ROLE_SORT, file.age); + item->setText(SR_AGE_COL, QString::number(file.mtime)); + item->setData(SR_AGE_COL, ROLE_SORT, file.mtime); item->setTextAlignment( SR_SIZE_COL, Qt::AlignRight ); + int friendSource = 0; + int anonymousSource = 0; if(searchType == FRIEND_SEARCH) { friendSource = 1; @@ -1344,7 +1369,7 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s } else { item->setData(SR_DATA_COL, SR_ROLE_LOCAL, false); - sources = item->text(SR_SOURCES_COL).toInt(); + int sources = item->text(SR_SOURCES_COL).toInt(); if (sources == 1) { foreground = ui.searchResultWidget->palette().color(QPalette::Text); @@ -1369,11 +1394,8 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s /* hide/show this search result */ hideOrShowSearchResult(item); - } - /* update the summary as well */ - if(!found) // only increment result when it's a new item. - { + // only increment result when it's a new item. int s = ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->text(SS_RESULTS_COL).toInt() ; ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->setText(SS_RESULTS_COL, QString::number(s+1)); ui.searchSummaryWidget->topLevelItem(summaryItemIndex)->setData(SS_RESULTS_COL, ROLE_SORT, s+1); @@ -1388,21 +1410,21 @@ void SearchDialog::resultsToTree(const QString& txt,qulonglong searchId, const s std::list::const_iterator it; for(it = results.begin(); it != results.end(); ++it) - if (it->type == DIR_TYPE_FILE) { + if (it->type == DIR_TYPE_FILE) + { FileDetail fd; fd.id = it->id; fd.name = it->name; fd.hash = it->hash; fd.path = it->path; fd.size = it->size; - fd.age = it->mtime; + fd.mtime= it->mtime; fd.rank = 0; insertFile(searchId,fd, FRIEND_SEARCH); - } else if (it->type == DIR_TYPE_DIR) { -// insertDirectory(txt, searchId, *it, NULL); + } + else if (it->type == DIR_TYPE_DIR) insertDirectory(txt, searchId, *it); - } ui.searchResultWidget->setSortingEnabled(true); } @@ -1481,33 +1503,38 @@ void SearchDialog::copyResultLink() { /* should also be able to handle multi-selection */ QList itemsForCopy = ui.searchResultWidget->selectedItems(); - int numdls = itemsForCopy.size(); - QTreeWidgetItem * item; - QList urls ; + std::set already_seen_hashes; + QList urls ; - for (int i = 0; i < numdls; ++i) - { - item = itemsForCopy.at(i); - // call copy + for (auto item:itemsForCopy) + { + // call copy - if (!item->childCount()) - { - std::cerr << "SearchDialog::copyResultLink() Calling set retroshare link"; - std::cerr << std::endl; + QString fhash = item->text(SR_HASH_COL); + RsFileHash hash(fhash.toStdString()); - QString fhash = item->text(SR_HASH_COL); - qulonglong fsize = item->text(SR_SIZE_COL).toULongLong(); - QString fname = item->text(SR_NAME_COL); + if(!hash.isNull() && (already_seen_hashes.end() == already_seen_hashes.find(hash))) + { + std::cerr << "SearchDialog::copyResultLink() Calling set retroshare link"; + std::cerr << std::endl; - RetroShareLink link = RetroShareLink::createFile(fname, fsize, fhash); - if (link.valid()) { - std::cerr << "new link added to clipboard: " << link.toString().toStdString() << std::endl ; - urls.push_back(link) ; - } - } - } - RSLinkClipboard::copyLinks(urls) ; + qulonglong fsize = item->text(SR_SIZE_COL).toULongLong(); + QString fname = item->text(SR_NAME_COL); + + RetroShareLink link = RetroShareLink::createFile(fname, fsize, fhash); + + if (link.valid()) + { + std::cerr << "new link added to clipboard: " << link.toString().toStdString() << std::endl ; + urls.push_back(link); + already_seen_hashes.insert(hash); + } + } + } + + if(!urls.empty()) + RSLinkClipboard::copyLinks(urls) ; } void SearchDialog::sendLinkTo( ) diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h index 83eb3b1b2..8aa7bac64 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.h @@ -21,9 +21,10 @@ #ifndef _SEARCHDIALOG_H #define _SEARCHDIALOG_H -#include +#include "retroshare/rstypes.h" +#include "retroshare/rsevents.h" #include "ui_SearchDialog.h" -#include +#include "retroshare-gui/mainpage.h" class AdvancedSearchDialog; class RSTreeWidgetItemCompareRole; @@ -42,6 +43,7 @@ class SearchDialog : public MainPage Q_PROPERTY(QColor textColorLowSources READ textColorLowSources WRITE setTextColorLowSources) Q_PROPERTY(QColor textColorHighSources READ textColorHighSources WRITE setTextColorHighSources) + struct FileDetail; // useful structure to store search results. public: /** Default Constructor */ SearchDialog(QWidget *parent = 0); @@ -62,8 +64,7 @@ public: void setTextColorLowSources(QColor color) { mTextColorLowSources = color; } void setTextColorHighSources(QColor color) { mTextColorHighSources = color; } -public slots: - void updateFiles(qulonglong request_id,FileDetail file) ; + void updateFiles(qulonglong request_id, const FileDetail& file) ; private slots: @@ -125,6 +126,7 @@ private: void setIconAndType(QTreeWidgetItem *item, const QString& filename); void downloadDirectory(const QTreeWidgetItem *item, const QString &base); void getSourceFriendsForHash(const RsFileHash &hash,std::list &srcIds); + void handleEvent_main_thread(std::shared_ptr event); /** the advanced search dialog instance */ AdvancedSearchDialog * advSearchDialog; @@ -159,7 +161,7 @@ private: QAbstractItemDelegate *mAgeColumnDelegate; QAbstractItemDelegate *mSizeColumnDelegate; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorLocal; QColor mTextColorDownloading; QColor mTextColorNoSources; @@ -176,6 +178,8 @@ private: bool _queueIsAlreadyTakenCareOf ; std::vector > searchResultsQueue ; + + RsEventsHandlerId_t mEventHandlerId ; }; #endif diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui index ad8c61068..f121c16c1 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.ui @@ -16,7 +16,7 @@ 1 - + @@ -31,7 +31,7 @@ QFrame::Plain - + 3 @@ -45,43 +45,28 @@ 3 - + 2 - - - 0 - 22 - - - - - 16777215 - 22 - - - + - 0 + 2 - 0 + 2 - 0 + 2 - 0 + 2 - + 0 - - 1 - @@ -93,7 +78,14 @@ - + + + + 12 + 75 + true + + Qt::NoFocus @@ -223,6 +215,9 @@ true + + false + KeyWords @@ -261,6 +256,9 @@ true + + false + Filename @@ -336,14 +334,14 @@ - + Any - - :/images/FileTypeAny.png:/images/FileTypeAny.png + + :/icons/filetype/any.svg:/icons/filetype/any.svg @@ -351,8 +349,8 @@ Archive - - :/images/FileTypeArchive.png:/images/FileTypeArchive.png + + :/icons/filetype/archive.svg:/icons/filetype/archive.svg @@ -360,8 +358,8 @@ Audio - - :/images/FileTypeAudio.png:/images/FileTypeAudio.png + + :/icons/filetype/audio.svg:/icons/filetype/audio.svg @@ -369,8 +367,8 @@ CD-Image - - :/images/FileTypeCDImage.png:/images/FileTypeCDImage.png + + :/icons/filetype/img.svg:/icons/filetype/img.svg @@ -378,8 +376,8 @@ Document - - :/images/FileTypeDocument.png:/images/FileTypeDocument.png + + :/icons/filetype/document.svg:/icons/filetype/document.svg @@ -387,8 +385,8 @@ Picture - - :/images/FileTypePicture.png:/images/FileTypePicture.png + + :/icons/filetype/picture.svg:/icons/filetype/picture.svg @@ -396,8 +394,8 @@ Program - - :/images/FileTypeProgram.png:/images/FileTypeProgram.png + + :/icons/filetype/program.svg:/icons/filetype/program.svg @@ -405,8 +403,8 @@ Video - - :/images/FileTypeVideo.png:/images/FileTypeVideo.png + + :/icons/filetype/video.svg:/icons/filetype/video.svg @@ -414,8 +412,8 @@ Directory - - :/images/foldermail.png:/images/foldermail.png + + :/icons/folder.png:/icons/folder.png @@ -460,6 +458,11 @@ QLineEdit
gui/common/LineEditClear.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
SearchTreeWidget QTreeWidget @@ -467,8 +470,8 @@ - + diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp index 20de4b9e9..74a7d5744 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp @@ -55,6 +55,16 @@ #include +#define SHARED_FILES_DIALOG_COLUMN_NAME 0 +#define SHARED_FILES_DIALOG_COLUMN_FILENB 1 +#define SHARED_FILES_DIALOG_COLUMN_SIZE 2 +#define SHARED_FILES_DIALOG_COLUMN_AGE 3 +#define SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS 4 +#define SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR 5 +#define SHARED_FILES_DIALOG_COLUMN_COUNT 6 + +#define SHARED_FILES_DIALOG_FILTER_STRING "filtered" + /* Images for context menu icons */ #define IMAGE_DOWNLOAD ":/icons/png/download.png" #define IMAGE_PLAY ":/images/start.png" @@ -75,7 +85,7 @@ #define IMAGE_COLLOPEN ":/icons/collections.png" #define IMAGE_EDITSHARE ":/icons/png/pencil-edit-button.png" #define IMAGE_MYFILES ":/icons/svg/folders1.svg" -#define IMAGE_UNSHAREEXTRA ":/images/button_cancel.png" +#define IMAGE_UNSHAREEXTRA ":/icons/cancel.svg" /*define viewType_CB value */ #define VIEW_TYPE_TREE 0 @@ -91,7 +101,7 @@ //#define DEBUG_SHARED_FILES_DIALOG 1 -const QString Image_AddNewAssotiationForFile = ":/images/kcmsystem24.png"; +const QString Image_AddNewAssotiationForFile = ":/icons/svg/options.svg"; class SFDSortFilterProxyModel : public QSortFilterProxyModel { @@ -187,17 +197,17 @@ SharedFilesDialog::SharedFilesDialog(bool remote_mode, QWidget *parent) tree_proxyModel->setSourceModel(tree_model); tree_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); tree_proxyModel->setSortRole(RetroshareDirModel::SortRole); - tree_proxyModel->sort(COLUMN_NAME); + tree_proxyModel->sort(SHARED_FILES_DIALOG_COLUMN_NAME); tree_proxyModel->setFilterRole(RetroshareDirModel::FilterRole); - tree_proxyModel->setFilterRegExp(QRegExp(QString(RETROSHARE_DIR_MODEL_FILTER_STRING))) ; + tree_proxyModel->setFilterRegExp(QRegExp(QString(SHARED_FILES_DIALOG_FILTER_STRING))) ; flat_proxyModel = new SFDSortFilterProxyModel(flat_model, this); flat_proxyModel->setSourceModel(flat_model); flat_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); flat_proxyModel->setSortRole(RetroshareDirModel::SortRole); - flat_proxyModel->sort(COLUMN_NAME); + flat_proxyModel->sort(SHARED_FILES_DIALOG_COLUMN_NAME); flat_proxyModel->setFilterRole(RetroshareDirModel::FilterRole); - flat_proxyModel->setFilterRegExp(QRegExp(QString(RETROSHARE_DIR_MODEL_FILTER_STRING))) ; + flat_proxyModel->setFilterRegExp(QRegExp(QString(SHARED_FILES_DIALOG_FILTER_STRING))) ; connect(ui.filterClearButton, SIGNAL(clicked()), this, SLOT(clearFilter())); connect(ui.filterStartButton, SIGNAL(clicked()), this, SLOT(startFilter())); @@ -213,15 +223,20 @@ SharedFilesDialog::SharedFilesDialog(bool remote_mode, QWidget *parent) /* Set header resize modes and initial section sizes */ QHeaderView * header = ui.dirTreeView->header () ; +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int charWidth = ui.dirTreeView->fontMetrics().width("_"); +#else + int charWidth = ui.dirTreeView->fontMetrics().horizontalAdvance("_"); +#endif - header->resizeSection ( COLUMN_NAME, 490 ); - header->resizeSection ( COLUMN_FILENB, 70 ); - header->resizeSection ( COLUMN_SIZE, 70 ); - header->resizeSection ( COLUMN_AGE, 100 ); - header->resizeSection ( COLUMN_FRIEND_ACCESS,100); - header->resizeSection ( COLUMN_WN_VISU_DIR, 100 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_NAME , charWidth*100 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_FILENB , charWidth*15 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_SIZE , charWidth*10 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_AGE , charWidth*6 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, charWidth*10 ); + header->resizeSection ( SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR , charWidth*20 ); - header->setStretchLastSection(false); + header->setStretchLastSection(true); /* Set Multi Selection */ ui.dirTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -251,7 +266,7 @@ LocalSharedFilesDialog::LocalSharedFilesDialog(QWidget *parent) : SharedFilesDialog(false,parent) { // Hide columns after loading the settings - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, false) ; ui.downloadButton->hide() ; // load settings @@ -270,14 +285,14 @@ LocalSharedFilesDialog::LocalSharedFilesDialog(QWidget *parent) ui.titleBarPixmap->setPixmap(FilesDefs::getPixmapFromQtResourcePath(IMAGE_MYFILES)) ; - ui.dirTreeView->setItemDelegateForColumn(COLUMN_FRIEND_ACCESS,new ShareFlagsItemDelegate()) ; + ui.dirTreeView->setItemDelegateForColumn(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS,new ShareFlagsItemDelegate()) ; } RemoteSharedFilesDialog::RemoteSharedFilesDialog(QWidget *parent) : SharedFilesDialog(true,parent) { - ui.dirTreeView->setColumnHidden(COLUMN_FRIEND_ACCESS, false) ; - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, true) ; ui.checkButton->hide() ; connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadRemoteSelected())); @@ -304,7 +319,7 @@ void SharedFilesDialog::hideEvent(QHideEvent *) model->setVisible(false) ; } -void SharedFilesDialog::showEvent(QShowEvent *) +void SharedFilesDialog::showEvent(QShowEvent *event) { if(model!=NULL) { @@ -317,6 +332,10 @@ void SharedFilesDialog::showEvent(QShowEvent *) restoreExpandedPathsAndSelection(expanded_indexes,hidden_indexes,selected_indexes); } + + if (!event->spontaneous()) { + updateFontSize(); + } } RemoteSharedFilesDialog::~RemoteSharedFilesDialog() { @@ -431,9 +450,9 @@ void SharedFilesDialog::changeCurrentViewModel(int viewTypeIndex) restoreExpandedPathsAndSelection(expanded_indexes,hidden_indexes,selected_indexes); QHeaderView * header = ui.dirTreeView->header () ; - QHeaderView_setSectionResizeModeColumn(header, COLUMN_NAME, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(header, SHARED_FILES_DIALOG_COLUMN_NAME, QHeaderView::Interactive); - ui.dirTreeView->header()->headerDataChanged(Qt::Horizontal, COLUMN_NAME, COLUMN_WN_VISU_DIR) ; + ui.dirTreeView->header()->headerDataChanged(Qt::Horizontal, SHARED_FILES_DIALOG_COLUMN_NAME, SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR) ; // recursRestoreExpandedItems(ui.dirTreeView->rootIndex(),expanded_indexes); FilterItems(); @@ -443,9 +462,9 @@ void LocalSharedFilesDialog::showProperColumns() { if(model == tree_model) { - ui.dirTreeView->setColumnHidden(COLUMN_FILENB, false) ; - ui.dirTreeView->setColumnHidden(COLUMN_FRIEND_ACCESS, false) ; - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FILENB, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, false) ; #ifdef DONT_USE_SEARCH_IN_TREE_VIEW ui.filterLabel->hide(); ui.filterPatternLineEdit->hide(); @@ -455,9 +474,9 @@ void LocalSharedFilesDialog::showProperColumns() } else { - ui.dirTreeView->setColumnHidden(COLUMN_FILENB, true) ; - ui.dirTreeView->setColumnHidden(COLUMN_FRIEND_ACCESS, true) ; - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FILENB, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, false) ; #ifdef DONT_USE_SEARCH_IN_TREE_VIEW ui.filterLabel->show(); ui.filterPatternLineEdit->show(); @@ -468,9 +487,9 @@ void RemoteSharedFilesDialog::showProperColumns() { if(model == tree_model) { - ui.dirTreeView->setColumnHidden(COLUMN_FILENB, false) ; - ui.dirTreeView->setColumnHidden(COLUMN_FRIEND_ACCESS, true) ; - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FILENB, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, true) ; #ifdef DONT_USE_SEARCH_IN_TREE_VIEW ui.filterLabel->hide(); ui.filterPatternLineEdit->hide(); @@ -480,9 +499,9 @@ void RemoteSharedFilesDialog::showProperColumns() } else { - ui.dirTreeView->setColumnHidden(COLUMN_FILENB, true) ; - ui.dirTreeView->setColumnHidden(COLUMN_FRIEND_ACCESS, false) ; - ui.dirTreeView->setColumnHidden(COLUMN_WN_VISU_DIR, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FILENB, true) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_FRIEND_ACCESS, false) ; + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_WN_VISU_DIR, false) ; #ifdef DONT_USE_SEARCH_IN_TREE_VIEW ui.filterLabel->show(); ui.filterPatternLineEdit->show(); @@ -510,7 +529,6 @@ void LocalSharedFilesDialog::checkUpdate() void LocalSharedFilesDialog::forceCheck() { rsFiles->ForceDirectoryCheck(); - return; } void RemoteSharedFilesDialog::spawnCustomPopupMenu( QPoint point ) @@ -1328,9 +1346,9 @@ void SharedFilesDialog::indicatorChanged(int index) ui.dirTreeView->update(ui.dirTreeView->rootIndex()); if (correct_indicator[index] != IND_ALWAYS) - ui.dirTreeView->sortByColumn(COLUMN_AGE, Qt::AscendingOrder); + ui.dirTreeView->sortByColumn(SHARED_FILES_DIALOG_COLUMN_AGE, Qt::AscendingOrder); else - ui.dirTreeView->sortByColumn(COLUMN_NAME, Qt::AscendingOrder); + ui.dirTreeView->sortByColumn(SHARED_FILES_DIALOG_COLUMN_NAME, Qt::AscendingOrder); updateDisplay() ; } @@ -1667,3 +1685,16 @@ bool SharedFilesDialog::tree_FilterItem(const QModelIndex &index, const QString return (visible || visibleChildCount); } #endif + +void SharedFilesDialog::updateFontSize() +{ + int customFontSize = Settings->valueFromGroup("File", "MinimumFontSize", 11).toInt(); + QFont newFont = ui.dirTreeView->font(); + if (newFont.pointSize() != customFontSize) { + newFont.setPointSize(customFontSize); + QFontMetricsF fontMetrics(newFont); + int iconHeight = fontMetrics.height(); + ui.dirTreeView->setFont(newFont); + ui.dirTreeView->setIconSize(QSize(iconHeight, iconHeight)); + } +} diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h index c406821c9..7524d5035 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h @@ -117,6 +117,8 @@ protected: QModelIndexList getSelected(); + void updateFontSize(); + /** Defines the actions for the context menu for QTreeWidget */ QAction* copylinkAct; QAction* sendlinkAct; diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui index b1f4ceb9b..cd79340dd 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.ui @@ -61,7 +61,14 @@
- + + + + 12 + 75 + true + + Files @@ -216,7 +223,7 @@ border-image: url(:/images/closepressed.png)
- + Tree view @@ -230,14 +237,14 @@ border-image: url(:/images/closepressed.png) - + All - - :/images/view_calendar_list.png:/images/view_calendar_list.png + + :/icons/svg/calendar-blank.svg:/icons/svg/calendar-blank.svg @@ -245,8 +252,8 @@ border-image: url(:/images/closepressed.png) One day old - - :/images/view_calendar_day.png:/images/view_calendar_day.png + + :/icons/svg/calendar-today.svg:/icons/svg/calendar-today.svg @@ -254,8 +261,8 @@ border-image: url(:/images/closepressed.png) One Week old - - :/images/view_calendar_week.png:/images/view_calendar_week.png + + :/icons/svg/calendar-week.svg:/icons/svg/calendar-week.svg @@ -263,8 +270,8 @@ border-image: url(:/images/closepressed.png) One month old - - :/images/view_calendar_month.png:/images/view_calendar_month.png + + :/icons/svg/calendar-month.svg:/icons/svg/calendar-month.svg @@ -278,9 +285,16 @@ border-image: url(:/images/closepressed.png) + + <html><head/><body><p>Forces the re-check of all shared directories. While automatic file checking only cares for new/removed files for efficiency reasons, this button will force the re-scan of all files, possibly re-hashing existing files that may have changed. </p></body></html> + check files + + + :/icons/svg/refresh.svg:/icons/svg/refresh.svg + @@ -304,8 +318,8 @@ border-image: url(:/images/closepressed.png) Download - - :/images/download16.png:/images/download16.png + + :/icons/png/download.png:/icons/png/download.png @@ -366,9 +380,9 @@ border-image: url(:/images/closepressed.png) true - + false - +
@@ -379,14 +393,14 @@ border-image: url(:/images/closepressed.png) - StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
- + diff --git a/retroshare-gui/src/gui/FileTransfer/TransferUserNotify.cpp b/retroshare-gui/src/gui/FileTransfer/TransferUserNotify.cpp index b424d922b..fa0c33046 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransferUserNotify.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransferUserNotify.cpp @@ -27,8 +27,6 @@ TransferUserNotify::TransferUserNotify(QObject *parent) : UserNotify(parent) { newTransferCount = 0; - -// connect(NotifyQt::getInstance(), SIGNAL(downloadCompleteCountChanged(int)), this, SLOT(downloadCountChanged(int))); } bool TransferUserNotify::hasSetting(QString *name, QString *group) diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index 9fa03f3fd..6fc45a070 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -21,6 +21,7 @@ #include "TransfersDialog.h" #include "gui/notifyqt.h" +#include "gui/SoundManager.h" #include "gui/RetroShareLink.h" #include "gui/common/FilesDefs.h" #include "gui/common/RsCollection.h" @@ -144,7 +145,7 @@ public: } int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { - return COLUMN_COUNT ; + return DLListDelegate::COLUMN_COUNT ; } bool hasChildren(const QModelIndex &parent = QModelIndex()) const { @@ -176,7 +177,7 @@ public: QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const { - if(row < 0 || column < 0 || column >= COLUMN_COUNT) + if(row < 0 || column < 0 || column >= DLListDelegate::COLUMN_COUNT) return QModelIndex(); void *parent_ref = (parent.isValid())?parent.internalPointer():NULL ; @@ -258,19 +259,19 @@ public: switch(section) { default: - case COLUMN_NAME: return tr("Name", "i.e: file name"); - case COLUMN_SIZE: return tr("Size", "i.e: file size"); - case COLUMN_COMPLETED: return tr("Completed", ""); - case COLUMN_DLSPEED: return tr("Speed", "i.e: Download speed"); - case COLUMN_PROGRESS: return tr("Progress / Availability", "i.e: % downloaded"); - case COLUMN_SOURCES: return tr("Sources", "i.e: Sources"); - case COLUMN_STATUS: return tr("Status"); - case COLUMN_PRIORITY: return tr("Speed / Queue position"); - case COLUMN_REMAINING: return tr("Remaining"); - case COLUMN_DOWNLOADTIME: return tr("Download time", "i.e: Estimated Time of Arrival / Time left"); - case COLUMN_ID: return tr("Hash"); - case COLUMN_LASTDL: return tr("Last Time Seen", "i.e: Last Time Receiced Data"); - case COLUMN_PATH: return tr("Path", "i.e: Where file is saved"); + case DLListDelegate::COLUMN_NAME: return tr("Name", "i.e: file name"); + case DLListDelegate::COLUMN_SIZE: return tr("Size", "i.e: file size"); + case DLListDelegate::COLUMN_COMPLETED: return tr("Completed", ""); + case DLListDelegate::COLUMN_DLSPEED: return tr("Speed", "i.e: Download speed"); + case DLListDelegate::COLUMN_PROGRESS: return tr("Progress / Availability", "i.e: % downloaded"); + case DLListDelegate::COLUMN_SOURCES: return tr("Sources", "i.e: Sources"); + case DLListDelegate::COLUMN_STATUS: return tr("Status"); + case DLListDelegate::COLUMN_PRIORITY: return tr("Speed / Queue position"); + case DLListDelegate::COLUMN_REMAINING: return tr("Remaining"); + case DLListDelegate::COLUMN_DOWNLOADTIME: return tr("Download time", "i.e: Estimated Time of Arrival / Time left"); + case DLListDelegate::COLUMN_ID: return tr("Hash"); + case DLListDelegate::COLUMN_LASTDL: return tr("Last Time Seen", "i.e: Last Time Receiced Data"); + case DLListDelegate::COLUMN_PATH: return tr("Path", "i.e: Where file is saved"); } } @@ -352,19 +353,19 @@ public: switch(col) { default: - case COLUMN_NAME: return QVariant( QSize(factor * 170, factor*14.0f )); - case COLUMN_SIZE: return QVariant( QSize(factor * 70 , factor*14.0f )); - case COLUMN_COMPLETED: return QVariant( QSize(factor * 75 , factor*14.0f )); - case COLUMN_DLSPEED: return QVariant( QSize(factor * 75 , factor*14.0f )); - case COLUMN_PROGRESS: return QVariant( QSize(factor * 170, factor*14.0f )); - case COLUMN_SOURCES: return QVariant( QSize(factor * 90 , factor*14.0f )); - case COLUMN_STATUS: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_PRIORITY: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_REMAINING: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_DOWNLOADTIME: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_ID: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_LASTDL: return QVariant( QSize(factor * 100, factor*14.0f )); - case COLUMN_PATH: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_NAME: return QVariant( QSize(factor * 170, factor*14.0f )); + case DLListDelegate::COLUMN_SIZE: return QVariant( QSize(factor * 70 , factor*14.0f )); + case DLListDelegate::COLUMN_COMPLETED: return QVariant( QSize(factor * 75 , factor*14.0f )); + case DLListDelegate::COLUMN_DLSPEED: return QVariant( QSize(factor * 75 , factor*14.0f )); + case DLListDelegate::COLUMN_PROGRESS: return QVariant( QSize(factor * 170, factor*14.0f )); + case DLListDelegate::COLUMN_SOURCES: return QVariant( QSize(factor * 90 , factor*14.0f )); + case DLListDelegate::COLUMN_STATUS: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_PRIORITY: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_REMAINING: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_DOWNLOADTIME: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_ID: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_LASTDL: return QVariant( QSize(factor * 100, factor*14.0f )); + case DLListDelegate::COLUMN_PATH: return QVariant( QSize(factor * 100, factor*14.0f )); } } @@ -374,11 +375,11 @@ public: if(source_id == -1) // toplevel switch(col) { - case COLUMN_NAME: return QVariant(QString::fromUtf8(fileInfo.fname.c_str())); - case COLUMN_COMPLETED: return QVariant((qlonglong)fileInfo.transfered); - case COLUMN_DLSPEED: return QVariant((double)((fileInfo.downloadStatus == FT_STATE_DOWNLOADING) ? (fileInfo.tfRate * 1024.0) : 0.0)); - case COLUMN_PROGRESS: return QVariant((float)((fileInfo.size == 0) ? 0 : (fileInfo.transfered * 100.0 / (float)fileInfo.size))); - case COLUMN_STATUS: + case DLListDelegate::COLUMN_NAME: return QVariant(QString::fromUtf8(fileInfo.fname.c_str())); + case DLListDelegate::COLUMN_COMPLETED: return QVariant((qlonglong)fileInfo.transfered); + case DLListDelegate::COLUMN_DLSPEED: return QVariant((double)((fileInfo.downloadStatus == FT_STATE_DOWNLOADING) ? (fileInfo.tfRate * 1024.0) : 0.0)); + case DLListDelegate::COLUMN_PROGRESS: return QVariant((float)((fileInfo.size == 0) ? 0 : (fileInfo.transfered * 100.0 / (float)fileInfo.size))); + case DLListDelegate::COLUMN_STATUS: { QString status; switch (fileInfo.downloadStatus) @@ -396,9 +397,9 @@ public: return QVariant(status); } - case COLUMN_PRIORITY: + case DLListDelegate::COLUMN_PRIORITY: { - double priority = PRIORITY_NULL; + double priority = DLListDelegate::PRIORITY_NULL; if (fileInfo.downloadStatus == FT_STATE_QUEUED) priority = fileInfo.queue_position; @@ -407,18 +408,18 @@ public: else switch (fileInfo.priority) { - case SPEED_LOW: priority = PRIORITY_SLOWER; break; - case SPEED_NORMAL: priority = PRIORITY_AVERAGE; break; - case SPEED_HIGH: priority = PRIORITY_FASTER; break; - default: priority = PRIORITY_AVERAGE; break; + case SPEED_LOW: priority = DLListDelegate::PRIORITY_SLOWER; break; + case SPEED_NORMAL: priority = DLListDelegate::PRIORITY_AVERAGE; break; + case SPEED_HIGH: priority = DLListDelegate::PRIORITY_FASTER; break; + default: priority = DLListDelegate::PRIORITY_AVERAGE; break; } return QVariant(priority); } - case COLUMN_REMAINING: return QVariant((qlonglong)(fileInfo.size - fileInfo.transfered)); - case COLUMN_DOWNLOADTIME: return QVariant((qlonglong)(fileInfo.tfRate > 0)?( (fileInfo.size - fileInfo.transfered) / (fileInfo.tfRate * 1024.0) ) : 0); - case COLUMN_LASTDL: + case DLListDelegate::COLUMN_REMAINING: return QVariant((qlonglong)(fileInfo.size - fileInfo.transfered)); + case DLListDelegate::COLUMN_DOWNLOADTIME: return QVariant((qlonglong)(fileInfo.tfRate > 0)?( (fileInfo.size - fileInfo.transfered) / (fileInfo.tfRate * 1024.0) ) : 0); + case DLListDelegate::COLUMN_LASTDL: { qint64 qi64LastDL = fileInfo.lastTS ; @@ -437,19 +438,19 @@ public: } return QVariant(qi64LastDL) ; } - case COLUMN_PATH: + case DLListDelegate::COLUMN_PATH: { QString strPath = QString::fromUtf8(fileInfo.path.c_str()); QString strPathAfterDL = strPath; - strPathAfterDL.replace(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()),""); + strPathAfterDL.replace(QString::fromUtf8(rsFiles->getDownloadDirectory().c_str()),"[Download Dir]"); return QVariant(strPathAfterDL); } - case COLUMN_SOURCES: + case DLListDelegate::COLUMN_SOURCES: { int active = 0; - QString fileHash = QString::fromStdString(fileInfo.hash.toStdString()); + //QString fileHash = QString::fromStdString(fileInfo.hash.toStdString()); if (fileInfo.downloadStatus != FT_STATE_COMPLETE) for (std::vector::const_iterator pit = fileInfo.peers.begin() ; pit != fileInfo.peers.end(); ++pit) @@ -478,9 +479,9 @@ public: } - case COLUMN_SIZE: return QVariant((qlonglong) fileInfo.size); + case DLListDelegate::COLUMN_SIZE: return QVariant((qlonglong) fileInfo.size); - case COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString())); + case DLListDelegate::COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString())); default: return QVariant("[ TODO ]"); @@ -492,16 +493,16 @@ public: switch(col) { default: - case COLUMN_SOURCES: - case COLUMN_COMPLETED: - case COLUMN_REMAINING: - case COLUMN_LASTDL: - case COLUMN_ID: - case COLUMN_PATH: - case COLUMN_DOWNLOADTIME: - case COLUMN_SIZE: return QVariant(); - case COLUMN_PROGRESS: return QVariant( (fileInfo.size>0)?((fileInfo.peers[source_id].transfered % chunk_size)*100.0/fileInfo.size):0.0) ; - case COLUMN_DLSPEED: + case DLListDelegate::COLUMN_SOURCES: + case DLListDelegate::COLUMN_COMPLETED: + case DLListDelegate::COLUMN_REMAINING: + case DLListDelegate::COLUMN_LASTDL: + case DLListDelegate::COLUMN_ID: + case DLListDelegate::COLUMN_PATH: + case DLListDelegate::COLUMN_DOWNLOADTIME: + case DLListDelegate::COLUMN_SIZE: return QVariant(); + case DLListDelegate::COLUMN_PROGRESS: return QVariant( (fileInfo.size>0)?((fileInfo.peers[source_id].transfered % chunk_size)*100.0/fileInfo.size):0.0) ; + case DLListDelegate::COLUMN_DLSPEED: { double peerDlspeed = 0; if((uint32_t)fileInfo.peers[source_id].status == FT_STATE_DOWNLOADING && fileInfo.downloadStatus != FT_STATE_PAUSED && fileInfo.downloadStatus != FT_STATE_COMPLETE) @@ -509,13 +510,13 @@ public: return QVariant((double)peerDlspeed) ; } - case COLUMN_NAME: + case DLListDelegate::COLUMN_NAME: { QString iconName,tooltip; return QVariant(TransfersDialog::getPeerName(fileInfo.peers[source_id].peerId, iconName, tooltip)); } - case COLUMN_PRIORITY: return QVariant((double)PRIORITY_NULL); + case DLListDelegate::COLUMN_PRIORITY: return QVariant((double)DLListDelegate::PRIORITY_NULL); } } @@ -527,7 +528,7 @@ public: if(source_id == -1) switch(col) { - case COLUMN_PROGRESS: + case DLListDelegate::COLUMN_PROGRESS: { FileChunksInfo fcinfo; if (!rsFiles->FileDownloadChunksDetails(fileInfo.hash, fcinfo)) @@ -554,7 +555,7 @@ public: return QVariant::fromValue(pinfo); } - case COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString())); + case DLListDelegate::COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString())); default: @@ -563,7 +564,7 @@ public: else switch(col) { - case COLUMN_PROGRESS: + case DLListDelegate::COLUMN_PROGRESS: { FileChunksInfo fcinfo; if (!rsFiles->FileDownloadChunksDetails(fileInfo.hash, fcinfo)) @@ -582,7 +583,7 @@ public: return QVariant::fromValue(pinfo); } - case COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString()) + QString::fromStdString(fileInfo.peers[source_id].peerId.toStdString())); + case DLListDelegate::COLUMN_ID: return QVariant(QString::fromStdString(fileInfo.hash.toStdString()) + QString::fromStdString(fileInfo.peers[source_id].peerId.toStdString())); default: return QVariant(); @@ -592,7 +593,7 @@ public: QVariant decorationRole(const FileInfo& fileInfo,int source_id,int col) const { - if(col == COLUMN_NAME) + if(col == DLListDelegate::COLUMN_NAME) { if(source_id == -1) return QVariant(FilesDefs::getIconFromFileType(QString::fromUtf8(fileInfo.fname.c_str()))); @@ -635,27 +636,27 @@ public: for(auto it(downHashes.begin());it!=downHashes.end();++it,++i) { FileInfo fileInfo(mDownloads[i]); // we dont update the data itself but only a copy of it.... - int old_size = fileInfo.peers.size() ; + int old_peers_size = fileInfo.peers.size() ; rsFiles->FileDetails(*it, RS_FILE_HINTS_DOWNLOAD, fileInfo); int new_size = fileInfo.peers.size() ; - if(old_size < new_size) + if(old_peers_size < new_size) { - beginInsertRows(index(i,0), old_size, new_size-1); - insertRows(old_size, new_size - old_size,index(i,0)); + beginInsertRows(index(i,0), old_peers_size, new_size-1); + insertRows(old_peers_size, new_size - old_peers_size,index(i,0)); #ifdef DEBUG_DOWNLOADLIST - std::cerr << "called insert rows ( " << old_size << ", " << new_size - old_size << ",index(" << index(i,0)<< "))" << std::endl; + std::cerr << "called insert rows ( " << old_peers_size << ", " << new_size - old_peers_size << ",index(" << index(i,0)<< "))" << std::endl; #endif endInsertRows(); } - else if(new_size < old_size) + else if(new_size < old_peers_size) { - beginRemoveRows(index(i,0), new_size, old_size-1); - removeRows(new_size, old_size - new_size,index(i,0)); + beginRemoveRows(index(i,0), new_size, old_peers_size-1); + removeRows(new_size, old_peers_size - new_size,index(i,0)); #ifdef DEBUG_DOWNLOADLIST - std::cerr << "called remove rows ( " << old_size << ", " << old_size - new_size << ",index(" << index(i,0)<< "))" << std::endl; + std::cerr << "called remove rows ( " << old_peers_size << ", " << old_peers_size - new_size << ",index(" << index(i,0)<< "))" << std::endl; #endif endRemoveRows(); } @@ -666,7 +667,7 @@ public: if(fileInfo.downloadStatus == FT_STATE_DOWNLOADING || old_status != fileInfo.downloadStatus) { - QModelIndex topLeft = createIndex(i,0), bottomRight = createIndex(i, COLUMN_COUNT-1); + QModelIndex topLeft = createIndex(i,0), bottomRight = createIndex(i, DLListDelegate::COLUMN_COUNT-1); emit dataChanged(topLeft, bottomRight); } @@ -674,7 +675,7 @@ public: // // if(!mDownloads.empty()) // { - // QModelIndex topLeft = createIndex(0,0), bottomRight = createIndex(mDownloads.size()-1, COLUMN_COUNT-1); + // QModelIndex topLeft = createIndex(0,0), bottomRight = createIndex(mDownloads.size()-1, DLListDelegate::COLUMN_COUNT-1); // emit dataChanged(topLeft, bottomRight); // mDownloads[i] = fileInfo ; // } @@ -742,7 +743,7 @@ private: class SortByNameItem : public QStandardItem { public: - SortByNameItem(QHeaderView *header) : QStandardItem() + explicit SortByNameItem(QHeaderView *header) : QStandardItem() { this->header = header; } @@ -761,8 +762,8 @@ public: return QStandardItem::operator<(other); } - QStandardItem *myName = myParent->child(index().row(), COLUMN_NAME); - QStandardItem *otherName = otherParent->child(other.index().row(), COLUMN_NAME); + QStandardItem *myName = myParent->child(index().row(), DLListDelegate::COLUMN_NAME); + QStandardItem *otherName = otherParent->child(other.index().row(), DLListDelegate::COLUMN_NAME); if (header == NULL || header->sortIndicatorOrder() == Qt::AscendingOrder) { /* Ascending */ @@ -780,9 +781,9 @@ private: class ProgressItem : public SortByNameItem { public: - ProgressItem(QHeaderView *header) : SortByNameItem(header) {} + explicit ProgressItem(QHeaderView *header) : SortByNameItem(header) {} - virtual bool operator<(const QStandardItem &other) const + virtual bool operator<(const QStandardItem &other) const override { const int role = model() ? model()->sortRole() : Qt::DisplayRole; @@ -847,41 +848,41 @@ TransfersDialog::TransfersDialog(QWidget *parent) // /* Set header resize modes and initial section sizes Downloads TreeView*/ QHeaderView * dlheader = ui.downloadList->header () ; - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_NAME, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SIZE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_COMPLETED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DLSPEED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PROGRESS, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_SOURCES, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_STATUS, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PRIORITY, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_REMAINING, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_DOWNLOADTIME, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_ID, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_LASTDL, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(dlheader, COLUMN_PATH, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_NAME, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_SIZE, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_COMPLETED, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_DLSPEED, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_PROGRESS, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_SOURCES, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_STATUS, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_PRIORITY, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_REMAINING, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_DOWNLOADTIME, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_ID, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_LASTDL, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(dlheader, DLListDelegate::COLUMN_PATH, QHeaderView::Interactive); // set default column and sort order for download - ui.downloadList->sortByColumn(COLUMN_NAME, Qt::AscendingOrder); + ui.downloadList->sortByColumn(DLListDelegate::COLUMN_NAME, Qt::AscendingOrder); connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); /* Add filter actions */ - QString headerName = DLListModel->headerData(COLUMN_NAME, Qt::Horizontal).toString(); - ui.filterLineEdit->addFilter(QIcon(), headerName, COLUMN_NAME , QString("%1 %2").arg(tr("Search"), headerName)); - QString headerID = DLListModel->headerData(COLUMN_ID, Qt::Horizontal).toString(); - ui.filterLineEdit->addFilter(QIcon(), headerID, COLUMN_ID , QString("%1 %2").arg(tr("Search"), headerID)); + QString headerName = DLListModel->headerData(DLListDelegate::COLUMN_NAME, Qt::Horizontal).toString(); + ui.filterLineEdit->addFilter(QIcon(), headerName, DLListDelegate::COLUMN_NAME , QString("%1 %2").arg(tr("Search"), headerName)); + QString headerID = DLListModel->headerData(DLListDelegate::COLUMN_ID, Qt::Horizontal).toString(); + ui.filterLineEdit->addFilter(QIcon(), headerID, DLListDelegate::COLUMN_ID , QString("%1 %2").arg(tr("Search"), headerID)); connect( ui.uploadsList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( uploadsListCustomPopupMenu( QPoint ) ) ); // Set Upload list model - ULListModel = new QStandardItemModel(0,COLUMN_UCOUNT); - ULListModel->setHeaderData(COLUMN_UNAME, Qt::Horizontal, tr("Name", "i.e: file name")); - ULListModel->setHeaderData(COLUMN_UPEER, Qt::Horizontal, tr("Peer", "i.e: user name / tunnel id")); - ULListModel->setHeaderData(COLUMN_USIZE, Qt::Horizontal, tr("Size", "i.e: file size")); - ULListModel->setHeaderData(COLUMN_UTRANSFERRED, Qt::Horizontal, tr("Transferred", "")); - ULListModel->setHeaderData(COLUMN_ULSPEED, Qt::Horizontal, tr("Speed", "i.e: upload speed")); - ULListModel->setHeaderData(COLUMN_UPROGRESS, Qt::Horizontal, tr("Progress", "i.e: % uploaded")); - ULListModel->setHeaderData(COLUMN_UHASH, Qt::Horizontal, tr("Hash", "")); + ULListModel = new QStandardItemModel(0,ULListDelegate::COLUMN_UCOUNT); + ULListModel->setHeaderData(ULListDelegate::COLUMN_UNAME, Qt::Horizontal, tr("Name", "i.e: file name")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_UPEER, Qt::Horizontal, tr("Peer", "i.e: user name / tunnel id")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_USIZE, Qt::Horizontal, tr("Size", "i.e: file size")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_UTRANSFERRED, Qt::Horizontal, tr("Transferred", "")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_ULSPEED, Qt::Horizontal, tr("Speed", "i.e: upload speed")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_UPROGRESS, Qt::Horizontal, tr("Progress", "i.e: % uploaded")); + ULListModel->setHeaderData(ULListDelegate::COLUMN_UHASH, Qt::Horizontal, tr("Hash", "")); ui.uploadsList->setModel(ULListModel); @@ -901,22 +902,22 @@ TransfersDialog::TransfersDialog(QWidget *parent) /* Set header resize modes and initial section sizes Uploads TreeView*/ QHeaderView * upheader = ui.uploadsList->header () ; - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_UNAME, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_UPEER, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_USIZE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_UTRANSFERRED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_ULSPEED, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(upheader, COLUMN_UPROGRESS, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_UNAME, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_UPEER, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_USIZE, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_UTRANSFERRED, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_ULSPEED, QHeaderView::Interactive); + QHeaderView_setSectionResizeModeColumn(upheader, ULListDelegate::COLUMN_UPROGRESS, QHeaderView::Interactive); - upheader->resizeSection ( COLUMN_UNAME, 260 ); - upheader->resizeSection ( COLUMN_UPEER, 120 ); - upheader->resizeSection ( COLUMN_USIZE, 70 ); - upheader->resizeSection ( COLUMN_UTRANSFERRED, 75 ); - upheader->resizeSection ( COLUMN_ULSPEED, 75 ); - upheader->resizeSection ( COLUMN_UPROGRESS, 170 ); + upheader->resizeSection ( ULListDelegate::COLUMN_UNAME, 260 ); + upheader->resizeSection ( ULListDelegate::COLUMN_UPEER, 120 ); + upheader->resizeSection ( ULListDelegate::COLUMN_USIZE, 70 ); + upheader->resizeSection ( ULListDelegate::COLUMN_UTRANSFERRED, 75 ); + upheader->resizeSection ( ULListDelegate::COLUMN_ULSPEED, 75 ); + upheader->resizeSection ( ULListDelegate::COLUMN_UPROGRESS, 170 ); // set default column and sort order for upload - ui.uploadsList->sortByColumn(COLUMN_UNAME, Qt::AscendingOrder); + ui.uploadsList->sortByColumn(ULListDelegate::COLUMN_UNAME, Qt::AscendingOrder); QObject::connect(ui.downloadList->selectionModel(),SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)),this,SLOT(showFileDetails())) ; @@ -1077,24 +1078,23 @@ TransfersDialog::TransfersDialog(QWidget *parent) // load settings processSettings(true); - int S = static_cast(QFontMetricsF(font()).height()); + int H = misc::getFontSizeFactor("HelpButton").height(); QString help_str = tr( - "

  " - "File Transfer

" - "

Retroshare brings two ways of transferring files: direct " - "transfers from your friends, and distant anonymous tunnelled " - "transfers. In addition, file transfer is multi-source and " - "allows swarming (you can be a source while downloading)

" - "

You can share files using the " - "" - " icon from the left side bar. These files will be listed in " - "the My Files tab. You can decide for each friend group whether" - " they can or not see these files in their Friends Files tab

" - "

The search tab reports files from your friends' file lists," - " and distant files that can be reached anonymously using the " - "multi-hop tunnelling system.

") - .arg(QString::number(2*S)).arg(QString::number(S)) ; - + "

  " + " File Transfer

" + "

Retroshare brings two ways of transferring files: direct " + " transfers from your friends, and distant anonymous tunnelled " + " transfers. In addition, file transfer is multi-source and " + " allows swarming (you can be a source while downloading)

" + "

You can share files using the " + " " + " icon from the left side bar. These files will be listed in " + " the My Files tab. You can decide for each friend group whether" + " they can or not see these files in their Friends Files tab

" + "

The search tab reports files from your friends' file lists," + " and distant files that can be reached anonymously using the " + " multi-hop tunnelling system.

" + ).arg(QString::number(2*H), QString::number(H)) ; registerHelpButton(ui.helpButton,help_str,"TransfersDialog") ; @@ -1114,6 +1114,16 @@ void TransfersDialog::handleEvent_main_thread(std::shared_ptr eve switch (fe->mFileTransferEventCode) { case RsFileTransferEventCode::DOWNLOAD_COMPLETE: + { + FileInfo nfo ; + if(!rsFiles->FileDetails(fe->mHash, RS_FILE_HINTS_DOWNLOAD, nfo)) + break; + + SoundManager::play(SOUND_DOWNLOAD_COMPLETE); + NotifyQt::getInstance()->addToaster(RS_POPUP_DOWNLOAD, fe->mHash.toStdString(), nfo.fname.c_str(),""); + } + [[fallthrough]]; + case RsFileTransferEventCode::COMPLETED_FILES_REMOVED: getUserNotify()->updateIcon(); @@ -1175,18 +1185,18 @@ void TransfersDialog::processSettings(bool bLoad) // state of splitter ui.splitter->restoreState(Settings->value("Splitter").toByteArray()); - setShowDLSizeColumn(Settings->value("showDLSizeColumn", !ui.downloadList->isColumnHidden(COLUMN_SIZE)).toBool()); - setShowDLCompleteColumn(Settings->value("showDLCompleteColumn", !ui.downloadList->isColumnHidden(COLUMN_COMPLETED)).toBool()); - setShowDLDLSpeedColumn(Settings->value("showDLDLSpeedColumn", !ui.downloadList->isColumnHidden(COLUMN_DLSPEED)).toBool()); - setShowDLProgressColumn(Settings->value("showDLProgressColumn", !ui.downloadList->isColumnHidden(COLUMN_PROGRESS)).toBool()); - setShowDLSourcesColumn(Settings->value("showDLSourcesColumn", !ui.downloadList->isColumnHidden(COLUMN_SOURCES)).toBool()); - setShowDLStatusColumn(Settings->value("showDLStatusColumn", !ui.downloadList->isColumnHidden(COLUMN_STATUS)).toBool()); - setShowDLPriorityColumn(Settings->value("showDLPriorityColumn", !ui.downloadList->isColumnHidden(COLUMN_PRIORITY)).toBool()); - setShowDLRemainingColumn(Settings->value("showDLRemainingColumn", !ui.downloadList->isColumnHidden(COLUMN_REMAINING)).toBool()); - setShowDLDownloadTimeColumn(Settings->value("showDLDownloadTimeColumn", !ui.downloadList->isColumnHidden(COLUMN_DOWNLOADTIME)).toBool()); - setShowDLIDColumn(Settings->value("showDLIDColumn", !ui.downloadList->isColumnHidden(COLUMN_ID)).toBool()); - setShowDLLastDLColumn(Settings->value("showDLLastDLColumn", !ui.downloadList->isColumnHidden(COLUMN_LASTDL)).toBool()); - setShowDLPath(Settings->value("showDLPath", !ui.downloadList->isColumnHidden(COLUMN_PATH)).toBool()); + setShowDLSizeColumn(Settings->value("showDLSizeColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SIZE)).toBool()); + setShowDLCompleteColumn(Settings->value("showDLCompleteColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_COMPLETED)).toBool()); + setShowDLDLSpeedColumn(Settings->value("showDLDLSpeedColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DLSPEED)).toBool()); + setShowDLProgressColumn(Settings->value("showDLProgressColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PROGRESS)).toBool()); + setShowDLSourcesColumn(Settings->value("showDLSourcesColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SOURCES)).toBool()); + setShowDLStatusColumn(Settings->value("showDLStatusColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_STATUS)).toBool()); + setShowDLPriorityColumn(Settings->value("showDLPriorityColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PRIORITY)).toBool()); + setShowDLRemainingColumn(Settings->value("showDLRemainingColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_REMAINING)).toBool()); + setShowDLDownloadTimeColumn(Settings->value("showDLDownloadTimeColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DOWNLOADTIME)).toBool()); + setShowDLIDColumn(Settings->value("showDLIDColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_ID)).toBool()); + setShowDLLastDLColumn(Settings->value("showDLLastDLColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_LASTDL)).toBool()); + setShowDLPath(Settings->value("showDLPath", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PATH)).toBool()); // selected tab ui.tabWidget->setCurrentIndex(Settings->value("selectedTab").toInt()); @@ -1200,18 +1210,18 @@ void TransfersDialog::processSettings(bool bLoad) // state of splitter Settings->setValue("Splitter", ui.splitter->saveState()); - Settings->setValue("showDLSizeColumn", !ui.downloadList->isColumnHidden(COLUMN_SIZE)); - Settings->setValue("showDLCompleteColumn", !ui.downloadList->isColumnHidden(COLUMN_COMPLETED)); - Settings->setValue("showDLDLSpeedColumn", !ui.downloadList->isColumnHidden(COLUMN_DLSPEED)); - Settings->setValue("showDLProgressColumn", !ui.downloadList->isColumnHidden(COLUMN_PROGRESS)); - Settings->setValue("showDLSourcesColumn", !ui.downloadList->isColumnHidden(COLUMN_SOURCES)); - Settings->setValue("showDLStatusColumn", !ui.downloadList->isColumnHidden(COLUMN_STATUS)); - Settings->setValue("showDLPriorityColumn", !ui.downloadList->isColumnHidden(COLUMN_PRIORITY)); - Settings->setValue("showDLRemainingColumn", !ui.downloadList->isColumnHidden(COLUMN_REMAINING)); - Settings->setValue("showDLDownloadTimeColumn", !ui.downloadList->isColumnHidden(COLUMN_DOWNLOADTIME)); - Settings->setValue("showDLIDColumn", !ui.downloadList->isColumnHidden(COLUMN_ID)); - Settings->setValue("showDLLastDLColumn", !ui.downloadList->isColumnHidden(COLUMN_LASTDL)); - Settings->setValue("showDLPath", !ui.downloadList->isColumnHidden(COLUMN_PATH)); + Settings->setValue("showDLSizeColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SIZE)); + Settings->setValue("showDLCompleteColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_COMPLETED)); + Settings->setValue("showDLDLSpeedColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DLSPEED)); + Settings->setValue("showDLProgressColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PROGRESS)); + Settings->setValue("showDLSourcesColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SOURCES)); + Settings->setValue("showDLStatusColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_STATUS)); + Settings->setValue("showDLPriorityColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PRIORITY)); + Settings->setValue("showDLRemainingColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_REMAINING)); + Settings->setValue("showDLDownloadTimeColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DOWNLOADTIME)); + Settings->setValue("showDLIDColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_ID)); + Settings->setValue("showDLLastDLColumn", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_LASTDL)); + Settings->setValue("showDLPath", !ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PATH)); // selected tab Settings->setValue("selectedTab", ui.tabWidget->currentIndex()); @@ -1424,18 +1434,18 @@ void TransfersDialog::downloadListHeaderCustomPopupMenu( QPoint /*point*/ ) std::cerr << "TransfersDialog::downloadListHeaderCustomPopupMenu()" << std::endl; QMenu contextMnu( this ); - showDLSizeAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_SIZE)); - showDLCompleteAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_COMPLETED)); - showDLDLSpeedAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_DLSPEED)); - showDLProgressAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_PROGRESS)); - showDLSourcesAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_SOURCES)); - showDLStatusAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_STATUS)); - showDLPriorityAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_PRIORITY)); - showDLRemainingAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_REMAINING)); - showDLDownloadTimeAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_DOWNLOADTIME)); - showDLIDAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_ID)); - showDLLastDLAct->setChecked(!ui.downloadList->isColumnHidden(COLUMN_LASTDL)); - showDLPath->setChecked(!ui.downloadList->isColumnHidden(COLUMN_PATH)); + showDLSizeAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SIZE)); + showDLCompleteAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_COMPLETED)); + showDLDLSpeedAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DLSPEED)); + showDLProgressAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PROGRESS)); + showDLSourcesAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_SOURCES)); + showDLStatusAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_STATUS)); + showDLPriorityAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PRIORITY)); + showDLRemainingAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_REMAINING)); + showDLDownloadTimeAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_DOWNLOADTIME)); + showDLIDAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_ID)); + showDLLastDLAct->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_LASTDL)); + showDLPath->setChecked(!ui.downloadList->isColumnHidden(DLListDelegate::COLUMN_PATH)); QMenu *menu = contextMnu.addMenu(tr("Columns")); menu->addAction(showDLSizeAct); @@ -1487,12 +1497,12 @@ void TransfersDialog::uploadsListHeaderCustomPopupMenu( QPoint /*point*/ ) std::cerr << "TransfersDialog::uploadsListHeaderCustomPopupMenu()" << std::endl; QMenu contextMnu( this ); - showULPeerAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_UPEER)); - showULSizeAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_USIZE)); - showULTransferredAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_UTRANSFERRED)); - showULSpeedAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_ULSPEED)); - showULProgressAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_UPROGRESS)); - showULHashAct->setChecked(!ui.uploadsList->isColumnHidden(COLUMN_UHASH)); + showULPeerAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_UPEER)); + showULSizeAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_USIZE)); + showULTransferredAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_UTRANSFERRED)); + showULSpeedAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_ULSPEED)); + showULProgressAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_UPROGRESS)); + showULHashAct->setChecked(!ui.uploadsList->isColumnHidden(ULListDelegate::COLUMN_UHASH)); QMenu *menu = contextMnu.addMenu(tr("Columns")); menu->addAction(showULPeerAct); @@ -1555,20 +1565,20 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) // change progress column to own class for sorting //ULListModel->setItem(row, COLUMN_UPROGRESS, new ProgressItem(NULL)); - ULListModel->setData(ULListModel->index(row, COLUMN_UNAME), fileName); - ULListModel->setData(ULListModel->index(row, COLUMN_UNAME), FilesDefs::getIconFromFileType(fileName), Qt::DecorationRole); - ULListModel->setData(ULListModel->index(row, COLUMN_UHASH), fileHash); - ULListModel->setData(ULListModel->index(row, COLUMN_UHASH), fileHash, Qt::UserRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UNAME), fileName); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UNAME), FilesDefs::getIconFromFileType(fileName), Qt::DecorationRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UHASH), fileHash); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UHASH), fileHash, Qt::UserRole); } - ULListModel->setData(ULListModel->index(row, COLUMN_USIZE), QVariant((qlonglong)fileSize)); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_USIZE), QVariant((qlonglong)fileSize)); //Reset Parent info if child present - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QVariant(QString(tr("%1 tunnels").arg(fileInfo.peers.size()))) ); - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QIcon(), Qt::DecorationRole); - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QVariant(), Qt::ToolTipRole); - ULListModel->setData(ULListModel->index(row, COLUMN_UTRANSFERRED), QVariant()); - ULListModel->setData(ULListModel->index(row, COLUMN_UPROGRESS), QVariant()); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QVariant(QString(tr("%1 tunnels").arg(fileInfo.peers.size()))) ); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QIcon(), Qt::DecorationRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QVariant(), Qt::ToolTipRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UTRANSFERRED), QVariant()); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPROGRESS), QVariant()); QStandardItem *ulItem = ULListModel->item(row); std::set used_rows ; @@ -1584,7 +1594,6 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) //unique combination: fileHash + peerId, variant: hash + peerName (too long) QString hashFileAndPeerId = fileHash + QString::fromStdString(transferInfo.peerId.toStdString()); - qlonglong completed = transferInfo.transfered; double peerULSpeed = transferInfo.tfRate * 1024.0; @@ -1602,6 +1611,7 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) peerpinfo.type = FileProgressInfo::UPLOAD_LINE ; peerpinfo.nb_chunks = peerpinfo.cmap._map.empty()?0:nb_chunks ; + qlonglong completed = 0; if(filled_chunks > 0 && nb_chunks > 0) { completed = peerpinfo.cmap.computeProgress(fileInfo.size,chunk_size) ; @@ -1618,11 +1628,11 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) //Only one peer so update parent QString iconName; QString tooltip; - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QVariant(getPeerName(transferInfo.peerId, iconName, tooltip))); - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QIcon(iconName), Qt::DecorationRole); - ULListModel->setData(ULListModel->index(row, COLUMN_UPEER), QVariant(tooltip), Qt::ToolTipRole); - ULListModel->setData(ULListModel->index(row, COLUMN_UTRANSFERRED), QVariant(completed)); - ULListModel->setData(ULListModel->index(row, COLUMN_UPROGRESS), QVariant::fromValue(peerpinfo)); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QVariant(getPeerName(transferInfo.peerId, iconName, tooltip))); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QIcon(iconName), Qt::DecorationRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPEER), QVariant(tooltip), Qt::ToolTipRole); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UTRANSFERRED), QVariant(completed)); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_UPROGRESS), QVariant::fromValue(peerpinfo)); } else { int row_id = addPeerToULItem(ulItem, transferInfo.peerId, hashFileAndPeerId, completed, peerULSpeed, peerpinfo); @@ -1633,7 +1643,7 @@ int TransfersDialog::addULItem(int row, const FileInfo &fileInfo) } // Update Parent UpLoad Speed - ULListModel->setData(ULListModel->index(row, COLUMN_ULSPEED), QVariant((double)peerULSpeedTotal)); + ULListModel->setData(ULListModel->index(row, ULListDelegate::COLUMN_ULSPEED), QVariant((double)peerULSpeedTotal)); // This is not optimal, but we deal with a small number of elements. The reverse order is really important, @@ -1654,7 +1664,7 @@ int TransfersDialog::addPeerToULItem(QStandardItem *ulItem, const RsPeerId& peer int childRow = -1; QStandardItem *childId = NULL; - for (int count = 0; (childId = ulItem->child(count, COLUMN_UHASH)) != NULL; ++count) { + for (int count = 0; (childId = ulItem->child(count, ULListDelegate::COLUMN_UHASH)) != NULL; ++count) { if (childId->data(Qt::UserRole).toString() == coreID) { childRow = count; break; @@ -1701,9 +1711,9 @@ int TransfersDialog::addPeerToULItem(QStandardItem *ulItem, const RsPeerId& peer childRow = ulItem->rowCount() - 1; } else { // just update the child (peer) - ulItem->child(childRow, COLUMN_ULSPEED)->setData(QVariant((double)ulspeed), Qt::DisplayRole); - ulItem->child(childRow, COLUMN_UTRANSFERRED)->setData(QVariant((qlonglong)completed), Qt::DisplayRole); - ulItem->child(childRow, COLUMN_UPROGRESS)->setData(QVariant::fromValue(peerInfo), Qt::DisplayRole); + ulItem->child(childRow, ULListDelegate::COLUMN_ULSPEED)->setData(QVariant((double)ulspeed), Qt::DisplayRole); + ulItem->child(childRow, ULListDelegate::COLUMN_UTRANSFERRED)->setData(QVariant((qlonglong)completed), Qt::DisplayRole); + ulItem->child(childRow, ULListDelegate::COLUMN_UPROGRESS)->setData(QVariant::fromValue(peerInfo), Qt::DisplayRole); } return childRow; @@ -1720,9 +1730,6 @@ void TransfersDialog::insertTransfers() { // Since downloads use an AstractItemModel, we just need to update it, while saving the selected and expanded items. - std::set expanded_hashes ; - std::set selected_hashes ; - DLListModel->update_transfers(); // Now show upload hashes. Here we use the "old" way, since the number of uploads is generally not so large. @@ -1747,7 +1754,7 @@ void TransfersDialog::insertTransfers() int rowCount = ULListModel->rowCount(); for (int row = 0; row < rowCount; ) { - RsFileHash hash ( ULListModel->item(row, COLUMN_UHASH)->data(Qt::UserRole).toString().toStdString()); + RsFileHash hash ( ULListModel->item(row, ULListDelegate::COLUMN_UHASH)->data(Qt::UserRole).toString().toStdString()); std::set::iterator hashIt = hashs.find(hash); if (hashIt == hashs.end()) { @@ -1957,16 +1964,16 @@ void TransfersDialog::pasteLink() RsCollection col ; RSLinkClipboard::pasteLinks(links,RetroShareLink::TYPE_FILE_TREE); - for(QList::const_iterator it(links.begin());it!=links.end();++it) + for(auto &it: links) { - auto ft = RsFileTree::fromRadix64((*it).radix().toStdString()); + auto ft = RsFileTree::fromRadix64(it.radix().toStdString()); col.merge_in(*ft); } links.clear(); RSLinkClipboard::pasteLinks(links,RetroShareLink::TYPE_FILE); - for(QList::const_iterator it(links.begin());it!=links.end();++it) - col.merge_in((*it).name(),(*it).size(),RsFileHash((*it).hash().toStdString())) ; + for(auto &it : links) + col.merge_in(it.name(),it.size(),RsFileHash(it.hash().toStdString())) ; col.downloadFiles(); } @@ -1980,13 +1987,13 @@ void TransfersDialog::getDLSelectedItems(std::set *ids, std::setclear(); if (rows) rows->clear(); - QModelIndexList selectedRows = selection->selectedRows(COLUMN_ID); + QModelIndexList selectedRows = selection->selectedRows(DLListDelegate::COLUMN_ID); int i, imax = selectedRows.count(); for (i = 0; i < imax; ++i) { QModelIndex index = selectedRows.at(i); - if (index.parent().isValid()) - index = index.model()->index(index.parent().row(), COLUMN_ID); + if (index.parent().isValid() && index.model()) + index = index.model()->index(index.parent().row(), DLListDelegate::COLUMN_ID); if (ids) { ids->insert(RsFileHash(index.data(Qt::DisplayRole).toString().toStdString())); @@ -2014,7 +2021,7 @@ void TransfersDialog::getULSelectedItems(std::set *ids, std::setitem(index.row(), COLUMN_UHASH); + QStandardItem *id = ULListModel->item(index.row(), ULListDelegate::COLUMN_UHASH); ids->insert(RsFileHash(id->data(Qt::DisplayRole).toString().toStdString())); } if (rows) { @@ -2067,22 +2074,23 @@ void TransfersDialog::dlOpenFolder() break; } + openFolder(info); +} + +void TransfersDialog::openFolder(const FileInfo& info) +{ /* make path for downloaded or downloading files */ - QFileInfo qinfo; - std::string path; - if (info.downloadStatus == FT_STATE_COMPLETE) { - path = info.path; - } else { - path = rsFiles->getPartialsDirectory(); - } + QDir directory; + + if (info.downloadStatus == FT_STATE_COMPLETE) + directory = QFileInfo(QString::fromStdString(info.path)).absoluteDir().path(); + else + directory = QDir(QString::fromStdString(rsFiles->getPartialsDirectory())); /* open folder with a suitable application */ - qinfo.setFile(QString::fromUtf8(path.c_str())); - if (qinfo.exists() && qinfo.isDir()) { - if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) { - std::cerr << "dlOpenFolder(): can't open folder " << path << std::endl; - } - } + + if (directory.exists() && !RsUrlHandler::openUrl(QUrl::fromLocalFile(directory.path()))) + std::cerr << "dlOpenFolder(): can't open folder " << directory.path().toStdString() << std::endl; } void TransfersDialog::ulOpenFolder() @@ -2097,19 +2105,7 @@ void TransfersDialog::ulOpenFolder() break; } - /* make path for uploading files */ - QFileInfo qinfo; - std::string path; - path = info.path.substr(0,info.path.length()-info.fname.length()); - - /* open folder with a suitable application */ - qinfo.setFile(QString::fromUtf8(path.c_str())); - if (qinfo.exists() && qinfo.isDir()) { - if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) { - std::cerr << "ulOpenFolder(): can't open folder " << path << std::endl; - } - } - + openFolder(info); } void TransfersDialog::dlPreviewFile() @@ -2132,7 +2128,7 @@ void TransfersDialog::dlPreviewFile() /* make path for downloaded or downloading files */ QFileInfo fileInfo; if (info.downloadStatus == FT_STATE_COMPLETE) { - fileInfo = QFileInfo(QString::fromUtf8(info.path.c_str()), QString::fromUtf8(info.fname.c_str())); + fileInfo = QFileInfo(QString::fromUtf8(info.path.c_str())); } else { fileInfo = QFileInfo(QString::fromUtf8(rsFiles->getPartialsDirectory().c_str()), QString::fromUtf8(info.hash.toStdString().c_str())); @@ -2197,7 +2193,7 @@ void TransfersDialog::dlOpenFile() /* make path for downloaded or downloading files */ std::string path; if (info.downloadStatus == FT_STATE_COMPLETE) { - path = info.path + "/" + info.fname; + path = info.path ; /* open file with a suitable application */ QFileInfo qinfo; @@ -2237,6 +2233,10 @@ void TransfersDialog::chunkStreaming() } void TransfersDialog::chunkRandom() { +#ifdef WINDOWS_SYS + if(QMessageBox::Yes != QMessageBox::warning(nullptr,tr("Warning"),tr("On Windows systems, writing in the middle of large empty files may hang the software for several seconds. Do you want to use this option anyway?"),QMessageBox::Yes,QMessageBox::No)) + return; +#endif setChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ; } void TransfersDialog::chunkProgressive() @@ -2387,72 +2387,72 @@ return 0.0 ; double TransfersDialog::getSpeed(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_DLSPEED), Qt::DisplayRole).toDouble(); + return model->data(model->index(row, DLListDelegate::COLUMN_DLSPEED), Qt::DisplayRole).toDouble(); } QString TransfersDialog::getFileName(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_NAME), Qt::DisplayRole).toString(); + return model->data(model->index(row, DLListDelegate::COLUMN_NAME), Qt::DisplayRole).toString(); } QString TransfersDialog::getStatus(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_STATUS), Qt::DisplayRole).toString(); + return model->data(model->index(row, DLListDelegate::COLUMN_STATUS), Qt::DisplayRole).toString(); } QString TransfersDialog::getID(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_ID), Qt::UserRole).toString().left(40); // gets only the "hash" part of the name + return model->data(model->index(row, DLListDelegate::COLUMN_ID), Qt::UserRole).toString().left(40); // gets only the "hash" part of the name } QString TransfersDialog::getID(int row, QSortFilterProxyModel *filter) { - QModelIndex index = filter->mapToSource(filter->index(row, COLUMN_ID)); + QModelIndex index = filter->mapToSource(filter->index(row, DLListDelegate::COLUMN_ID)); return filter->sourceModel()->data(index, Qt::UserRole).toString().left(40); // gets only the "hash" part of the name } QString TransfersDialog::getPriority(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_PRIORITY), Qt::DisplayRole).toString(); + return model->data(model->index(row, DLListDelegate::COLUMN_PRIORITY), Qt::DisplayRole).toString(); } qlonglong TransfersDialog::getFileSize(int row, QStandardItemModel *model) { bool ok = false; - return model->data(model->index(row, COLUMN_SIZE), Qt::DisplayRole).toULongLong(&ok); + return model->data(model->index(row, DLListDelegate::COLUMN_SIZE), Qt::DisplayRole).toULongLong(&ok); } qlonglong TransfersDialog::getTransfered(int row, QStandardItemModel *model) { bool ok = false; - return model->data(model->index(row, COLUMN_COMPLETED), Qt::DisplayRole).toULongLong(&ok); + return model->data(model->index(row, DLListDelegate::COLUMN_COMPLETED), Qt::DisplayRole).toULongLong(&ok); } qlonglong TransfersDialog::getRemainingTime(int row, QStandardItemModel *model) { bool ok = false; - return model->data(model->index(row, COLUMN_REMAINING), Qt::DisplayRole).toULongLong(&ok); + return model->data(model->index(row, DLListDelegate::COLUMN_REMAINING), Qt::DisplayRole).toULongLong(&ok); } qlonglong TransfersDialog::getDownloadTime(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_DOWNLOADTIME), Qt::DisplayRole).toULongLong(); + return model->data(model->index(row, DLListDelegate::COLUMN_DOWNLOADTIME), Qt::DisplayRole).toULongLong(); } qlonglong TransfersDialog::getLastDL(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_LASTDL), Qt::DisplayRole).toULongLong(); + return model->data(model->index(row, DLListDelegate::COLUMN_LASTDL), Qt::DisplayRole).toULongLong(); } qlonglong TransfersDialog::getPath(int row, QStandardItemModel *model) { - return model->data(model->index(row, COLUMN_PATH), Qt::DisplayRole).toULongLong(); + return model->data(model->index(row, DLListDelegate::COLUMN_PATH), Qt::DisplayRole).toULongLong(); } QString TransfersDialog::getSources(int row, QStandardItemModel *model) { - double dblValue = model->data(model->index(row, COLUMN_SOURCES), Qt::DisplayRole).toDouble(); + double dblValue = model->data(model->index(row, DLListDelegate::COLUMN_SOURCES), Qt::DisplayRole).toDouble(); QString temp = QString("%1 (%2)").arg((int)dblValue).arg((int)((fmod(dblValue,1)*1000)+0.5)); return temp; @@ -2612,25 +2612,25 @@ void TransfersDialog::collAutoOpen(const QString &fileHash) } } -void TransfersDialog::setShowDLSizeColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_SIZE, !show); } -void TransfersDialog::setShowDLCompleteColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_COMPLETED, !show); } -void TransfersDialog::setShowDLDLSpeedColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_DLSPEED, !show); } -void TransfersDialog::setShowDLProgressColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_PROGRESS, !show); } -void TransfersDialog::setShowDLSourcesColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_SOURCES, !show); } -void TransfersDialog::setShowDLStatusColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_STATUS, !show); } -void TransfersDialog::setShowDLPriorityColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_PRIORITY, !show); } -void TransfersDialog::setShowDLRemainingColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_REMAINING, !show); } -void TransfersDialog::setShowDLDownloadTimeColumn(bool show) { ui.downloadList->setColumnHidden(COLUMN_DOWNLOADTIME, !show); } -void TransfersDialog::setShowDLIDColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_ID, !show); } -void TransfersDialog::setShowDLLastDLColumn (bool show) { ui.downloadList->setColumnHidden(COLUMN_LASTDL, !show); } -void TransfersDialog::setShowDLPath (bool show) { ui.downloadList->setColumnHidden(COLUMN_PATH, !show); } +void TransfersDialog::setShowDLSizeColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_SIZE, !show); } +void TransfersDialog::setShowDLCompleteColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_COMPLETED, !show); } +void TransfersDialog::setShowDLDLSpeedColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_DLSPEED, !show); } +void TransfersDialog::setShowDLProgressColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_PROGRESS, !show); } +void TransfersDialog::setShowDLSourcesColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_SOURCES, !show); } +void TransfersDialog::setShowDLStatusColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_STATUS, !show); } +void TransfersDialog::setShowDLPriorityColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_PRIORITY, !show); } +void TransfersDialog::setShowDLRemainingColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_REMAINING, !show); } +void TransfersDialog::setShowDLDownloadTimeColumn(bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_DOWNLOADTIME, !show); } +void TransfersDialog::setShowDLIDColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_ID, !show); } +void TransfersDialog::setShowDLLastDLColumn (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_LASTDL, !show); } +void TransfersDialog::setShowDLPath (bool show) { ui.downloadList->setColumnHidden(DLListDelegate::COLUMN_PATH, !show); } -void TransfersDialog::setShowULPeerColumn (bool show) { ui.uploadsList->setColumnHidden(COLUMN_UPEER, !show); } -void TransfersDialog::setShowULSizeColumn (bool show) { ui.uploadsList->setColumnHidden(COLUMN_USIZE, !show); } -void TransfersDialog::setShowULTransferredColumn(bool show) { ui.uploadsList->setColumnHidden(COLUMN_UTRANSFERRED, !show); } -void TransfersDialog::setShowULSpeedColumn (bool show) { ui.uploadsList->setColumnHidden(COLUMN_ULSPEED, !show); } -void TransfersDialog::setShowULProgressColumn (bool show) { ui.uploadsList->setColumnHidden(COLUMN_UPROGRESS, !show); } -void TransfersDialog::setShowULHashColumn (bool show) { ui.uploadsList->setColumnHidden(COLUMN_UHASH, !show); } +void TransfersDialog::setShowULPeerColumn (bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_UPEER, !show); } +void TransfersDialog::setShowULSizeColumn (bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_USIZE, !show); } +void TransfersDialog::setShowULTransferredColumn(bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_UTRANSFERRED, !show); } +void TransfersDialog::setShowULSpeedColumn (bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_ULSPEED, !show); } +void TransfersDialog::setShowULProgressColumn (bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_UPROGRESS, !show); } +void TransfersDialog::setShowULHashColumn (bool show) { ui.uploadsList->setColumnHidden(ULListDelegate::COLUMN_UHASH, !show); } void TransfersDialog::expandAllDL() { diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h index 87396fc81..19e2df363 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.h @@ -173,6 +173,7 @@ signals: void playFiles(QStringList files); private: + void openFolder(const FileInfo& info); RsDownloadListModel *DLListModel; QSortFilterProxyModel *DLLFilterModel; diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui index d2e7a9ab6..f329509b1 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.ui @@ -70,7 +70,14 @@ - + + + + 12 + 75 + true + + File Transfers @@ -213,6 +220,9 @@ true + + false + false @@ -280,6 +290,9 @@ true + + false +
@@ -294,11 +307,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
LineEditClear QLineEdit diff --git a/retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp b/retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp index c4c9bb90d..6bad045e0 100644 --- a/retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp +++ b/retroshare-gui/src/gui/FileTransfer/ULListDelegate.cpp @@ -25,14 +25,14 @@ Q_DECLARE_METATYPE(FileProgressInfo) +#define MAX_CHAR_TMP 128 + ULListDelegate::ULListDelegate(QObject *parent) : QAbstractItemDelegate(parent) { - ; } ULListDelegate::~ULListDelegate(void) { - ; } void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const @@ -65,7 +65,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti // draw the background color bool bDrawBackground = true; - if(index.column() == COLUMN_UPROGRESS) { + if(index.column() == COLUMN_UPROGRESS) { FileProgressInfo pinfo = index.data().value() ; bDrawBackground = (pinfo.type == FileProgressInfo::UNINIT); } @@ -133,7 +133,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti } painter->drawText(option.rect, Qt::AlignRight, temp); break; - case COLUMN_UPROGRESS: + case COLUMN_UPROGRESS: { FileProgressInfo pinfo = index.data().value() ; if (pinfo.type == FileProgressInfo::UNINIT) @@ -143,7 +143,7 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti painter->save() ; xProgressBar progressBar(pinfo,option.rect,painter,0);// the 3rd param is the color schema (0 is the default value) - QString ext = QFileInfo(QString::fromStdString(index.sibling(index.row(), COLUMN_UNAME).data().toString().toStdString())).suffix();; + QString ext = QFileInfo(QString::fromStdString(index.sibling(index.row(), COLUMN_UNAME).data().toString().toStdString())).suffix();; if (ext == "rsfc" || ext == "rsrl" || ext == "dist" || ext == "rsfb") progressBar.setColorSchema( 9); else @@ -157,8 +157,8 @@ void ULListDelegate::paint(QPainter * painter, const QStyleOptionViewItem & opti } painter->drawText(option.rect, Qt::AlignCenter, newopt.text); break; - case COLUMN_UNAME: - case COLUMN_UPEER: + case COLUMN_UNAME: + case COLUMN_UPEER: // decoration value = index.data(Qt::DecorationRole); pixmap = qvariant_cast(value).pixmap(option.decorationSize, option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled, option.state & QStyle::State_Open ? QIcon::On : QIcon::Off); diff --git a/retroshare-gui/src/gui/FileTransfer/ULListDelegate.h b/retroshare-gui/src/gui/FileTransfer/ULListDelegate.h index 24a7d66d1..fc65c3a8f 100644 --- a/retroshare-gui/src/gui/FileTransfer/ULListDelegate.h +++ b/retroshare-gui/src/gui/FileTransfer/ULListDelegate.h @@ -18,43 +18,27 @@ * * *******************************************************************************/ -#ifndef ULLISTDELEGATE_H -#define ULLISTDELEGATE_H +#pragma once #include -// Defines for upload list list columns -#define COLUMN_UNAME 0 -#define COLUMN_UPEER 1 -#define COLUMN_USIZE 2 -#define COLUMN_UTRANSFERRED 3 -#define COLUMN_ULSPEED 4 -#define COLUMN_UPROGRESS 5 -#define COLUMN_UHASH 6 -#define COLUMN_UCOUNT 7 - - -#define MAX_CHAR_TMP 128 - class QModelIndex; class QPainter; +class ULListDelegate: public QAbstractItemDelegate +{ +public: + ULListDelegate(QObject *parent=0); + ~ULListDelegate(); + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; + QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const; -class ULListDelegate: public QAbstractItemDelegate { - - Q_OBJECT - - public: - ULListDelegate(QObject *parent=0); - ~ULListDelegate(); - void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; - QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const; - - private: - - public slots: - - signals: + static constexpr int COLUMN_UNAME = 0; + static constexpr int COLUMN_UPEER = 1; + static constexpr int COLUMN_USIZE = 2; + static constexpr int COLUMN_UTRANSFERRED = 3; + static constexpr int COLUMN_ULSPEED = 4; + static constexpr int COLUMN_UPROGRESS = 5; + static constexpr int COLUMN_UHASH = 6; + static constexpr int COLUMN_UCOUNT = 7; }; -#endif - diff --git a/retroshare-gui/src/gui/FriendServerControl.cpp b/retroshare-gui/src/gui/FriendServerControl.cpp new file mode 100644 index 000000000..7b031e7e2 --- /dev/null +++ b/retroshare-gui/src/gui/FriendServerControl.cpp @@ -0,0 +1,362 @@ +/******************************************************************************* + * gui/FriendServer.cpp * + * * + * Copyright (c) 2021 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "retroshare/rsfriendserver.h" +#include "retroshare/rstor.h" + +#include "util/qtthreadsutils.h" +#include "util/misc.h" +#include "gui/common/FilesDefs.h" + +#include "FriendServerControl.h" + +#include + +#define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" +#define ICON_STATUS_OK ":/images/ledon1.png" + +#define NAME_COLUMN 0 +#define NODE_COLUMN 1 +#define ADDR_COLUMN 2 +#define STAT_COLUMN 3 + +/** Constructor */ +FriendServerControl::FriendServerControl(QWidget *parent) + : MainPage(parent) +{ + /* Invoke the Qt Designer generated object setup routine */ + setupUi(this); + + friendServerOnOff_CB->setEnabled(false); // until FS is connected. + mCurrentlyCheckingServerAddress = false; + + if(!rsFriendServer) + { + setEnabled(false); + return; + } + + int H = QFontMetricsF(torServerAddress_LE->font()).height(); + + QString help_str = tr("\ +

  Friend Server

\ +

This configuration panel allows you to specify the onion address of a \ + friend server. Retroshare will talk to that server anonymously through Tor \ + and use it to acquire a fixed number of friends.

\ +

The friend server will continue supplying new friends until that number is reached \ + in particular if you add your own friends manually, the friend server may become useless \ + and you will save bandwidth disabling it. When disabling it, you will keep existing friends.

\ +

The friend server only knows your peer ID and profile public key. It doesn't know your IP address.

\ + " + ).arg(QString::number(2*H), QString::number(2*H)) ; + + registerHelpButton(helpButton,help_str,"Friend Server") ; + + mConnectionCheckTimer = new QTimer; + + whileBlocking(autoAccept_CB)->setChecked(rsFriendServer->autoAddFriends()); + + // Init values + + whileBlocking(torServerFriendsToRequest_SB)->setValue(rsFriendServer->friendsToRequest()); + + // Connect slignals/slots + + QObject::connect(friendServerOnOff_CB,SIGNAL(toggled(bool)),this,SLOT(onOnOffClick(bool))); + QObject::connect(torServerFriendsToRequest_SB,SIGNAL(valueChanged(int)),this,SLOT(onFriendsToRequestChanged(int))); + QObject::connect(torServerAddress_LE,SIGNAL(textEdited(const QString&)),this,SLOT(onOnionAddressEdit(const QString&))); + QObject::connect(torServerPort_SB,SIGNAL(valueChanged(int)),this,SLOT(onOnionPortEdit(int))); + QObject::connect(autoAccept_CB,SIGNAL(toggled(bool)),this,SLOT(onAutoAddFriends(bool))); + + QObject::connect(mConnectionCheckTimer,SIGNAL(timeout()),this,SLOT(checkServerAddress())); + QObject::connect(status_TW, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(launchStatusContextMenu(QPoint))); + + mCheckingServerMovie = new QMovie(":/images/loader/circleball-16.gif"); + + // Do not block signal for these two, since we want to trigger a test to initialise the online status. + torServerAddress_LE->setText(QString::fromStdString(rsFriendServer->friendsServerAddress().c_str())); + torServerPort_SB->setValue(rsFriendServer->friendsServerPort()); + + updateFriendServerStatusIcon(false); + + makeFriend_ACT = new QAction(tr("Make friend")); // makes SSL-only friend with the peer + + QObject::connect(makeFriend_ACT,SIGNAL(triggered()),this,SLOT(makeFriend())); + + mEventHandlerId_fs = 0; + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId_fs, RsEventType::FRIEND_SERVER ); + + mEventHandlerId_peer = 0; + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); + }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION ); +} + +void FriendServerControl::onAutoAddFriends(bool b) +{ + rsFriendServer->setAutoAddFriends(b); +} +void FriendServerControl::handleEvent_main_thread(std::shared_ptr event) +{ + { + const RsFriendServerEvent *fe = dynamic_cast(event.get()); + + if(fe) + switch(fe->mFriendServerEventType) + { + case RsFriendServerEventCode::PEER_INFO_CHANGED: updateContactsStatus(); + break; + + case RsFriendServerEventCode::FRIEND_SERVER_STATUS_CHANGED: updateFriendServerStatusIcon(fe->mFriendServerStatus == RsFriendServerStatus::ONLINE); + break; + + default: + case RsFriendServerEventCode::UNKNOWN: break; + } + } + + { + const RsConnectionEvent *pe = dynamic_cast(event.get()); + + if(pe) + switch(pe->mConnectionInfoCode) + { + case RsConnectionEventCode::PEER_ADDED: + case RsConnectionEventCode::PEER_REMOVED: + case RsConnectionEventCode::PEER_CONNECTED: updateContactsStatus(); + break; + + default: ; + } + } +} + +FriendServerControl::~FriendServerControl() +{ + delete mCheckingServerMovie; + delete mConnectionCheckTimer; + + rsEvents->unregisterEventsHandler(mEventHandlerId_fs); + rsEvents->unregisterEventsHandler(mEventHandlerId_peer); +} + +void FriendServerControl::launchStatusContextMenu(QPoint p) +{ + RsPeerId peer_id = getCurrentPeer(); + + RsPeerDetails det; + if(rsPeers->getPeerDetails(peer_id,det) && det.accept_connection) + return; + + QMenu contextMnu(this); + contextMnu.addAction(makeFriend_ACT); + + contextMnu.exec(QCursor::pos()); +} +void FriendServerControl::onOnOffClick(bool b) +{ + if(b) + { + if(passphrase_LE->text().isNull()) + { + QMessageBox::critical(nullptr,tr("Missing profile passphrase."),tr("Your profile passphrase is missing. Please enter is in the field below before enabling the friend server.")); + whileBlocking(friendServerOnOff_CB)->setCheckState(Qt::Unchecked); + return; + } + rsFriendServer->setProfilePassphrase(passphrase_LE->text().toStdString()); + rsFriendServer->startServer(); + } + else + rsFriendServer->stopServer(); +} +void FriendServerControl::onOnionPortEdit(int) +{ + // Setup timer to auto-check the friend server address + + mConnectionCheckTimer->stop(); + mConnectionCheckTimer->setSingleShot(true); + mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time. + + mConnectionCheckTimer->start(); + + if(mCheckingServerMovie->fileName() != QString(":/images/loader/circleball-16.gif" )) + { + mCheckingServerMovie->setFileName(":/images/loader/circleball-16.gif"); + mCheckingServerMovie->start(); + } +} + +void FriendServerControl::onOnionAddressEdit(const QString&) +{ + while(mCurrentlyCheckingServerAddress) + { + std::cerr << " waiting for free slot" << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); // wait for ongoing check to finish. + } + + std::cerr << "Resetting connection proxy timer" << std::endl; + + // Setup timer to auto-check the friend server address + mConnectionCheckTimer->setSingleShot(true); + mConnectionCheckTimer->setInterval(5000); // check in 5 secs unless something is changed in the mean time. + mConnectionCheckTimer->start(); +} + +void FriendServerControl::checkServerAddress() +{ + std::cerr << "In checkServerAddress() ..." << std::endl; + + mCurrentlyCheckingServerAddress = true; + + serverStatusCheckResult_LB->setMovie(mCheckingServerMovie); + serverStatusCheckResult_LB->setToolTip(tr("Trying to contact friend server\nThis may take up to 1 min.")) ; + mCheckingServerMovie->setFileName(":/images/loader/circleball-16.gif"); + mCheckingServerMovie->start(); + + RsThread::async( [this]() + { + auto port = torServerPort_SB->value(); + auto addr = torServerAddress_LE->text().toStdString(); + + std::cerr << "calling sync test..." << std::endl; + bool succeed = rsFriendServer->checkServerAddress(addr,port,5000); + std::cerr << "result is " << succeed << std::endl; + + RsQThreadUtils::postToObject( [addr,port,succeed,this]() + { + if(succeed) + rsFriendServer->setServerAddress(addr,port); + + mCheckingServerMovie->stop(); + updateFriendServerStatusIcon(succeed); + mCurrentlyCheckingServerAddress = false; + + },this); + }); +} + +void FriendServerControl::onNbFriendsToRequestsChanged(int n) +{ + rsFriendServer->setFriendsToRequest(n); +} + +void FriendServerControl::updateFriendServerStatusIcon(bool ok) +{ + std::cerr << "updating proxy status icon" << std::endl; + + if(ok) + { + serverStatusCheckResult_LB->setToolTip(tr("Friend server is currently reachable.")) ; + serverStatusCheckResult_LB->setPixmap(QPixmap(ICON_STATUS_OK)); + friendServerOnOff_CB->setEnabled(true); + status_TW->setEnabled(true); + } + else + { + rsFriendServer->stopServer(); + serverStatusCheckResult_LB->setToolTip(tr("The proxy is not enabled or broken.\nAre all services up and running fine??\nAlso check your ports!")) ; + serverStatusCheckResult_LB->setPixmap(QPixmap(ICON_STATUS_UNKNOWN)); + friendServerOnOff_CB->setChecked(false); + friendServerOnOff_CB->setEnabled(false); + status_TW->setEnabled(false); + } +} + +void FriendServerControl::updateContactsStatus() +{ + std::map pinfo = rsFriendServer->getPeersInfo(); + + status_TW->clear(); + int row = 0; + status_TW->setRowCount(pinfo.size()); + status_TW->setColumnCount(4); + + status_TW->setHorizontalHeaderItem(NAME_COLUMN,new QTableWidgetItem(QObject::tr("Name"))); + status_TW->setHorizontalHeaderItem(NODE_COLUMN,new QTableWidgetItem(QObject::tr("Node"))); + status_TW->setHorizontalHeaderItem(ADDR_COLUMN,new QTableWidgetItem(QObject::tr("Address"))); + status_TW->setHorizontalHeaderItem(STAT_COLUMN,new QTableWidgetItem(QObject::tr("Status"))); + + for(auto it:pinfo) + { + uint32_t err_code=0; + RsPeerDetails details; + + rsPeers->parseShortInvite(it.second.mInvite,details,err_code); + + status_TW->setItem(row,NAME_COLUMN,new QTableWidgetItem(QString::fromStdString(details.name))); + status_TW->setItem(row,NODE_COLUMN,new QTableWidgetItem(QString::fromStdString(details.id.toStdString()))); + status_TW->setItem(row,ADDR_COLUMN,new QTableWidgetItem(QString::fromStdString(details.hiddenNodeAddress)+":"+QString::number(details.hiddenNodePort))); + + QString status_string; + if(details.accept_connection) + status_string += QString("Friend"); + else + status_string += QString("Not friend"); + + status_string += QString(" / "); + + switch(it.second.mPeerLevel) + { + case RsFriendServer::PeerFriendshipLevel::NO_KEY: status_string += "Doesn't have my key" ; break; + case RsFriendServer::PeerFriendshipLevel::HAS_KEY: status_string += "Has my key" ; break; + case RsFriendServer::PeerFriendshipLevel::HAS_ACCEPTED_KEY: status_string += "Has friended me" ; break; + default: + case RsFriendServer::PeerFriendshipLevel::UNKNOWN: status_string += "Unkn" ; break; + } + + status_TW->setItem(row,STAT_COLUMN,new QTableWidgetItem(status_string)); + + row++; + } +} + +RsPeerId FriendServerControl::getCurrentPeer() +{ + QTableWidgetItem *item = status_TW->currentItem(); + + if(!item) + return RsPeerId(); + + return RsPeerId(status_TW->item(item->row(),NODE_COLUMN)->text().toStdString()); +} +void FriendServerControl::makeFriend() +{ + RsPeerId peer_id = getCurrentPeer(); + + rsFriendServer->allowPeer(peer_id); +} + + + + + + diff --git a/retroshare-gui/src/gui/common/StyledElidedLabel.cpp b/retroshare-gui/src/gui/FriendServerControl.h similarity index 52% rename from retroshare-gui/src/gui/common/StyledElidedLabel.cpp rename to retroshare-gui/src/gui/FriendServerControl.h index 43fc85220..ddc66ee8a 100644 --- a/retroshare-gui/src/gui/common/StyledElidedLabel.cpp +++ b/retroshare-gui/src/gui/FriendServerControl.h @@ -1,7 +1,7 @@ /******************************************************************************* - * gui/common/StyleElidedLabel.cpp * + * gui/NetworkView.h * * * - * Copyright (c) 2014, RetroShare Team * + * Copyright (c) 2008 Robert Fernie * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -18,29 +18,48 @@ * * *******************************************************************************/ -#include -#include "StyledElidedLabel.h" +#pragma once -/** Constructor */ -StyledElidedLabel::StyledElidedLabel(QWidget *parent) - : ElidedLabel(parent), _lastFactor(-1) -{ -} +#include -StyledElidedLabel::StyledElidedLabel(const QString &text, QWidget *parent) - : ElidedLabel(text, parent), _lastFactor(-1) -{ -} +#include "retroshare/rsevents.h" -void StyledElidedLabel::setFontSizeFactor(int factor) +#include "retroshare-gui/mainpage.h" +#include "ui_FriendServerControl.h" + +class FriendServerControl : public MainPage, public Ui::FriendServerControl { - int newFactor = factor; - if (factor > 0) { - if (_lastFactor > 0) newFactor = 100 + factor - _lastFactor; - _lastFactor = factor; - QFont f = font(); - qreal fontSize = newFactor * f.pointSizeF() / 100; - f.setPointSizeF(fontSize); - setFont(f); - } -} + Q_OBJECT + +public: + FriendServerControl(QWidget *parent = 0); + virtual ~FriendServerControl(); + +protected slots: + void onOnOffClick(bool b); + void onOnionAddressEdit(const QString &); + void onOnionPortEdit(int); + void onNbFriendsToRequestsChanged(int n); + void checkServerAddress(); + void onAutoAddFriends(bool b); + void launchStatusContextMenu(QPoint p); + void makeFriend(); + +private: + RsPeerId getCurrentPeer(); + void updateContactsStatus(); + void updateFriendServerStatusIcon(bool ok); + void handleEvent_main_thread(std::shared_ptr event); + + QTimer *mConnectionCheckTimer; + QMovie *mCheckingServerMovie; + bool mCurrentlyCheckingServerAddress; + + RsEventsHandlerId_t mEventHandlerId_fs; + RsEventsHandlerId_t mEventHandlerId_peer; + + QAction *makeFriend_ACT; + QAction *unmakeFriend_ACT; + QAction *removePeer_ACT; + QAction *removePeerPermanently_ACT; +}; diff --git a/retroshare-gui/src/gui/FriendServerControl.ui b/retroshare-gui/src/gui/FriendServerControl.ui new file mode 100644 index 000000000..e3faac36b --- /dev/null +++ b/retroshare-gui/src/gui/FriendServerControl.ui @@ -0,0 +1,241 @@ + + + FriendServerControl + + + + 0 + 0 + 620 + 499 + + + + + + + + + Server onion address: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Enter here the onion address of the Friend Server that was given to you. The address will be automatically checked after you enter it and a green bullet will appear if the server is online.</p></body></html> + + + Onion address of the friend server + + + + + + + <html><head/><body><p>Communication port of the server. You usually get a server address as somestring.onion:port. The port is the number right after &quot;:&quot;</p></body></html> + + + 1025 + + + 65536 + + + 2017 + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + Qt::NoFocus + + + + :/icons/help_64.png:/icons/help_64.png + + + true + + + false + + + true + + + + + + + + + + + + + + Retroshare passphrase: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Your Retroshare login passphrase is needed to ensure the security of data exchange with the friend server.</p></body></html> + + + QLineEdit::Password + + + Your retroshare passphrase + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + On/Off + + + + + + + Qt::Horizontal + + + + 302 + 26 + + + + + + + + Friends to request: + + + + + + + 1 + + + 15 + + + 5 + + + + + + + Auto accept received certificates as friends + + + Auto-accept + + + + + + + + + + Qt::CustomContextMenu + + + + Name + + + + + Node ID + + + + + Address + + + + + Status + + + + + + + + Qt::Vertical + + + + 20 + 380 + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/FriendsDialog.cpp b/retroshare-gui/src/gui/FriendsDialog.cpp index 660f13fa7..532a87f4a 100644 --- a/retroshare-gui/src/gui/FriendsDialog.cpp +++ b/retroshare-gui/src/gui/FriendsDialog.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "chat/ChatUserNotify.h" #include "connect/ConnectFriendWizard.h" @@ -44,6 +45,9 @@ #include "NetworkView.h" #include "NetworkDialog.h" #include "gui/common/NewFriendList.h" +#ifdef RS_EMBEDED_FRIEND_SERVER +#include "gui/FriendServerControl.h" +#endif #include "gui/Identity/IdDialog.h" /* Images for Newsfeed icons */ //#define IMAGE_NEWSFEED "" @@ -88,6 +92,10 @@ FriendsDialog::FriendsDialog(QWidget *parent) : MainPage(parent) ui.avatar->setFrameType(AvatarWidget::STATUS_FRAME); ui.tabWidget->setTabPosition(QTabWidget::North); +#ifdef RS_EMBEDED_FRIEND_SERVER + if(RsAccounts::isTorAuto()) + ui.tabWidget->addTab(friendServerControl = new FriendServerControl(),QIcon(IMAGE_PEERS), tr("Friend Server")); +#endif ui.tabWidget->addTab(networkView = new NetworkView(),QIcon(IMAGE_NETWORK2), tr("Network graph")); ui.tabWidget->addTab(networkDialog = new NetworkDialog(),QIcon(IMAGE_PEERS), tr("Keyring")); @@ -117,25 +125,24 @@ FriendsDialog::FriendsDialog(QWidget *parent) : MainPage(parent) // add self nick and Avatar to Friends. RsPeerDetails pd ; - if (rsPeers->getPeerDetails(rsPeers->getOwnId(),pd)) { + if (rsPeers->getPeerDetails(rsPeers->getOwnId(),pd)) ui.nicknameLabel->setText(QString::fromUtf8(pd.name.c_str()) + " (" + QString::fromUtf8(pd.location.c_str())+")"); - } - QString hlp_str = tr( - "

  Network

\ -

The Network tab shows your friend Retroshare nodes: the neighbor Retroshare nodes that are connected to you. \ -

\ -

You can group nodes together to allow a finer level of information access, for instance to only allow \ - some nodes to see some of your files.

\ -

On the right, you will find 3 useful tabs: \ -

    \ -
  • Broadcast sends messages to all connected nodes at once
  • \ -
  • Local network graph shows the network around you, based on discovery information
  • \ -
  • Keyring contains node keys you collected, mostly forwarded to you by your friend nodes
  • \ -

\ - ") ; + int H = misc::getFontSizeFactor("HelpButton").height(); + QString hlp_str = tr( + "

  Network

" + "

The Network tab shows your friend Retroshare nodes: the neighbor Retroshare nodes that are connected to you.

" + "

You can group nodes together to allow a finer level of information access, for instance to only allow" + " some nodes to see some of your files.

" + "

On the right, you will find 3 useful tabs:" + "

    " + "
  • Broadcast sends messages to all connected nodes at once
  • " + "
  • Local network graph shows the network around you, based on discovery information
  • " + "
  • Keyring contains node keys you collected, mostly forwarded to you by your friend nodes
  • " + "

" + ).arg(QString::number(2*H)); - registerHelpButton(ui.helpButton, hlp_str,"FriendsDialog") ; + registerHelpButton(ui.helpButton, hlp_str,"FriendsDialog") ; } FriendsDialog::~FriendsDialog () @@ -252,13 +259,9 @@ void FriendsDialog::loadmypersonalstatus() QString statustring = QString::fromUtf8(rsMsgs->getCustomStateString().c_str()); if (statustring.isEmpty()) - { ui.mypersonalstatusLabel->setText(tr("Set your status message here.")); - } else - { ui.mypersonalstatusLabel->setText(statustring); - } } void FriendsDialog::clearChatNotify() @@ -275,13 +278,11 @@ void FriendsDialog::statusmessage() /*static*/ bool FriendsDialog::isGroupChatActive() { FriendsDialog *friendsDialog = dynamic_cast(MainWindow::getPage(MainWindow::Friends)); - if (!friendsDialog) { + if (!friendsDialog) return false; - } - if (friendsDialog->ui.tabWidget->currentWidget() == friendsDialog->ui.groupChatTab) { + if (friendsDialog->ui.tabWidget->currentWidget() == friendsDialog->ui.groupChatTab) return true; - } return false; } diff --git a/retroshare-gui/src/gui/FriendsDialog.h b/retroshare-gui/src/gui/FriendsDialog.h index bd8979224..7e86669b8 100644 --- a/retroshare-gui/src/gui/FriendsDialog.h +++ b/retroshare-gui/src/gui/FriendsDialog.h @@ -30,6 +30,7 @@ class NetworkDialog; class NetworkView; class IdDialog; class CirclesDialog; +class FriendServerControl; class FriendsDialog : public MainPage { @@ -64,7 +65,8 @@ public: NetworkDialog *networkDialog ; NetworkView *networkView ; - + FriendServerControl *friendServerControl ; + IdDialog *idDialog; private slots: diff --git a/retroshare-gui/src/gui/FriendsDialog.ui b/retroshare-gui/src/gui/FriendsDialog.ui index b32c71465..02408e382 100644 --- a/retroshare-gui/src/gui/FriendsDialog.ui +++ b/retroshare-gui/src/gui/FriendsDialog.ui @@ -10,7 +10,7 @@ 491 - + 0 @@ -37,7 +37,7 @@ QFrame::Sunken - + 2 @@ -70,14 +70,21 @@ - + + + + 12 + 75 + true + + Network - + Qt::Horizontal @@ -115,12 +122,12 @@ Qt::Horizontal - + 1 - + @@ -130,7 +137,7 @@ QFrame::Sunken - + 1 @@ -192,7 +199,14 @@ - + + + + 20 + 75 + true + + Nickname (Location) @@ -240,7 +254,7 @@ Broadcast - + @@ -362,11 +376,6 @@
gui/common/AvatarWidget.h
1
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
ChatWidget QWidget @@ -380,9 +389,9 @@ 1 - StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
NewFriendList diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e106146fb..b71e324c7 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -33,27 +33,27 @@ #include #include "gui/settings/rsharesettings.h" -#include "TorControl/TorManager.h" #include "util/misc.h" #include "gui/common/FilesDefs.h" -#include -#include -#include -#include -#include +#include "retroshare/rstor.h" +#include "retroshare/rsidentity.h" +#include "retroshare/rsinit.h" +#include "retroshare/rsnotify.h" +#include "rsserver/rsaccounts.h" +#include "util/rsrandom.h" #include #include #include #define IMAGE_GOOD ":/images/accepted16.png" -#define IMAGE_BAD ":/images/cancel.png" +#define IMAGE_BAD ":/icons/cancel.svg" class EntropyCollectorWidget: public QTextBrowser { public: - EntropyCollectorWidget(QProgressBar *pr,QWidget *p = NULL) + explicit EntropyCollectorWidget(QProgressBar *pr,QWidget *p = NULL) : QTextBrowser(p) { progress = pr ; @@ -150,7 +150,7 @@ GenCertDialog::GenCertDialog(bool onlyGenerateIdentity, QWidget *parent) connect(ui.node_input, SIGNAL(textChanged(QString)), this, SLOT(updateCheckLabels())); connect(ui.reuse_existing_node_CB, SIGNAL(toggled(bool)), this, SLOT(updateCheckLabels())); - connect(ui.cbUseBob, SIGNAL(clicked(bool)), this, SLOT(useBobChecked(bool)));; + connect(ui.cbUseBob, SIGNAL(clicked(bool)), this, SLOT(useI2pChecked(bool)));; entropy_timer = new QTimer ; entropy_timer->start(20) ; @@ -288,8 +288,6 @@ void GenCertDialog::setupState() break; } - //ui.no_node_label->setVisible(false); - setWindowTitle(generate_new?tr("Create new profile and new Retroshare node"):tr("Create new Retroshare node")); //ui.headerFrame->setHeaderText(generate_new?tr("Create a new profile and node"):tr("Create a new node")); @@ -300,15 +298,9 @@ void GenCertDialog::setupState() ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ; - //ui.genprofileinfo_label->setVisible(false); - //ui.no_gpg_key_label->setText(tr("Welcome to Retroshare. Before you can proceed you need to create a profile and associate a node with it. To do so please fill out this form.\nAlternatively you can import a (previously exported) profile. Just uncheck \"Create a new profile\"")); - //no_gpg_key_label->setVisible(false); - ui.name_label->setVisible(true); ui.name_input->setVisible(generate_new); - //ui.header_label->setVisible(false) ; - ui.nickname_label->setVisible(adv_state && !mOnlyGenerateIdentity); ui.nickname_input->setVisible(adv_state && !mOnlyGenerateIdentity); @@ -341,9 +333,9 @@ void GenCertDialog::setupState() ui.hiddenport_spinBox->setVisible(hidden_state && !tor_auto); ui.cbUseBob->setVisible(hidden_state && !tor_auto); -#ifndef RS_USE_I2P_BOB +#ifndef RS_USE_I2P_SAM3 ui.cbUseBob->setDisabled(true); - ui.cbUseBob->setToolTip(tr("BOB support is not available")); + ui.cbUseBob->setToolTip(tr("SAMv3 support is not available")); #endif if(!mAllFieldsOk) @@ -352,8 +344,8 @@ void GenCertDialog::setupState() ui.genButton->setVisible(false) ; ui.generate_label->setVisible(false) ; - ui.info_label->setText("Please choose a profile name and password...") ; - ui.info_label->setVisible(true) ; + ui.info_Label->setText("Please choose a profile name and password...") ; + ui.info_Label->setVisible(true) ; } else if(!mEntropyOk) { @@ -361,8 +353,8 @@ void GenCertDialog::setupState() ui.genButton->setVisible(false) ; ui.generate_label->setVisible(false) ; - ui.info_label->setText("Please move your mouse randomly to generate enough random data to create your profile.") ; - ui.info_label->setVisible(true) ; + ui.info_Label->setText("Please move your mouse randomly to generate enough random data to create your profile.") ; + ui.info_Label->setVisible(true) ; } else { @@ -371,7 +363,7 @@ void GenCertDialog::setupState() ui.genButton->setToolTip(tr("Click to create your node and/or profile")) ; ui.genButton->setVisible(true) ; ui.generate_label->setVisible(false) ; - ui.info_label->setVisible(false) ; + ui.info_Label->setVisible(false) ; } } @@ -407,7 +399,7 @@ void GenCertDialog::updateCheckLabels() ui.node_name_check_LB ->setPixmap(bad) ; } - if(!generate_new || ui.name_input->text().length() >= 3) + if(!generate_new || ui.name_input->text().trimmed().length() >= 3) ui.profile_name_check_LB ->setPixmap(good) ; else { @@ -440,10 +432,10 @@ void GenCertDialog::updateCheckLabels() setupState(); } -void GenCertDialog::useBobChecked(bool checked) +void GenCertDialog::useI2pChecked(bool checked) { if (checked) { - ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with BOB enabled")); + ui.hiddenaddr_input->setPlaceholderText(tr("I2P instance address with SAMv3 enabled")); ui.hiddenaddr_label->setText(tr("I2P instance address")); ui.hiddenport_spinBox->setEnabled(false); @@ -528,7 +520,7 @@ void GenCertDialog::genPerson() bool isHiddenLoc = (ui.nodeType_CB->currentIndex()>0); bool isAutoTor = (ui.nodeType_CB->currentIndex()==1); - if(isAutoTor && !Tor::TorManager::isTorAvailable()) + if(isAutoTor && !RsTor::isTorAvailable()) { QMessageBox::critical(this,tr("Tor is not available"),tr("No Tor executable has been found on your system. You need to install Tor before creating a hidden identity.")) ; return ; @@ -539,12 +531,12 @@ void GenCertDialog::genPerson() std::string hl = ui.hiddenaddr_input->text().toStdString(); uint16_t port = ui.hiddenport_spinBox->value(); - bool useBob = ui.cbUseBob->isChecked(); + bool useI2p = ui.cbUseBob->isChecked(); - if (useBob && hl.empty()) + if (useI2p && hl.empty()) hl = "127.0.0.1"; - RsInit::SetHiddenLocation(hl, port, useBob); /* parses it */ + RsInit::SetHiddenLocation(hl, port, useI2p); /* parses it */ } @@ -591,7 +583,6 @@ void GenCertDialog::genPerson() //generate a new gpg key std::string err_string; //_key_label->setText(tr("Generating new node key, please be patient: this process needs generating large prime numbers, and can take some minutes on slow computers. \n\nFill in your password when asked, to sign your new key.")); - //ui.no_gpg_key_label->show(); //ui.reuse_existing_node_CB->hide(); ui.name_label->hide(); ui.name_input->hide(); @@ -609,7 +600,6 @@ void GenCertDialog::genPerson() ui.node_input->hide(); ui.genButton->hide(); ui.importIdentity_PB->hide(); - //ui.genprofileinfo_label->hide(); ui.nodeType_CB->hide(); //ui.adv_checkbox->hide(); ui.keylength_label->hide(); diff --git a/retroshare-gui/src/gui/GenCertDialog.h b/retroshare-gui/src/gui/GenCertDialog.h index afd82e5f0..6d9d3610a 100644 --- a/retroshare-gui/src/gui/GenCertDialog.h +++ b/retroshare-gui/src/gui/GenCertDialog.h @@ -31,7 +31,7 @@ class GenCertDialog : public QDialog public: /** Default constructor */ - GenCertDialog(bool onlyGenerateIdentity, QWidget *parent = 0); + explicit GenCertDialog(bool onlyGenerateIdentity, QWidget *parent = 0); virtual ~GenCertDialog() ; virtual void mouseMoveEvent(QMouseEvent *e) ; @@ -44,7 +44,7 @@ private slots: void switchReuseExistingNode(); void grabMouse(); void updateCheckLabels(); - void useBobChecked(bool checked); + void useI2pChecked(bool checked); private: void initKeyList(); diff --git a/retroshare-gui/src/gui/GenCertDialog.ui b/retroshare-gui/src/gui/GenCertDialog.ui index 96f09cae2..a747709d3 100644 --- a/retroshare-gui/src/gui/GenCertDialog.ui +++ b/retroshare-gui/src/gui/GenCertDialog.ui @@ -111,7 +111,7 @@ - + 0 @@ -187,7 +187,7 @@ - + 0 @@ -245,6 +245,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> @@ -303,6 +309,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Your node name designates the Retroshare instance that</p><p>will run on this computer.</p></body></html> @@ -340,6 +352,12 @@ 32 + + + 75 + true + + <html><head/><body><p>The profile name identifies you over the network.</p><p>It is used by your friends to accept connections from you.</p><p>You can create multiple Retroshare nodes with the</p><p>same profile on different computers.</p><p><br/></p></body></html> @@ -352,13 +370,19 @@ - + 0 0 + + + 75 + true + + Your profile is associated with a PGP key pair. RetroShare currently ignores DSA keys. @@ -417,6 +441,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Put a strong password here. This password protects your private node key!</p></body></html> @@ -456,6 +486,12 @@ 32 + + + 75 + true + + <html><head/><body><p>This should 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. </p><p>You can also leave this blank now, but your node will only work if you correctly set the Tor/I2P service address in Options-&gt;Network-&gt;Hidden Service configuration panel.</p></body></html> @@ -479,6 +515,12 @@ 0 + + + 75 + true + + <html><head/><body><p>This is your connection port.</p><p>Any value between 1024 and 65535 </p><p>should be ok. You can change it later.</p></body></html> @@ -496,7 +538,7 @@ - Use BOB + Use I2P @@ -510,6 +552,12 @@ 0 + + + 75 + true + + <html><head/><body><p>Identities are used when you write in chat rooms, forums and channel comments. </p><p>They also receive/send email over the Retroshare network. You can create</p><p>a signed identity now, or do it later on when you get to need it.</p></body></html> @@ -532,6 +580,8 @@ 12 + 75 + true @@ -721,7 +771,12 @@ - + + + + 12 + + TextLabel @@ -751,6 +806,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
name_input node_input @@ -764,8 +826,8 @@ importIdentity_PB - + diff --git a/retroshare-gui/src/gui/GetStartedDialog.cpp b/retroshare-gui/src/gui/GetStartedDialog.cpp index d525808b6..e3bbd7170 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.cpp +++ b/retroshare-gui/src/gui/GetStartedDialog.cpp @@ -53,19 +53,19 @@ GetStartedDialog::GetStartedDialog(QWidget *parent) mFirstShow = true; - connect(ui.inviteCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickInviteChanged())); - connect(ui.addCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickAddChanged())); - connect(ui.connectCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickConnectChanged())); - connect(ui.firewallCheckBox, SIGNAL(stateChanged( int )), this, SLOT(tickFirewallChanged())); + connect(ui.inviteCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickInviteChanged())); + connect(ui.addCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickAddChanged())); + connect(ui.connectCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickConnectChanged())); + connect(ui.firewallCheckBox, SIGNAL(stateChanged(int)), this, SLOT(tickFirewallChanged())); - connect(ui.pushButton_InviteFriends, SIGNAL(clicked( bool )), this, SLOT(inviteFriends())); - connect(ui.pushButton_AddFriend, SIGNAL(clicked( bool )), this, SLOT(addFriends())); + connect(ui.pushButton_InviteFriends, SIGNAL(clicked(bool)), this, SLOT(inviteFriends())); + connect(ui.pushButton_AddFriend, SIGNAL(clicked(bool)), this, SLOT(addFriends())); - connect(ui.pushButton_FAQ, SIGNAL(clicked( bool )), this, SLOT(OpenFAQ())); - connect(ui.pushButton_Forums, SIGNAL(clicked( bool )), this, SLOT(OpenForums())); - connect(ui.pushButton_Website, SIGNAL(clicked( bool )), this, SLOT(OpenWebsite())); - connect(ui.pushButton_EmailFeedback, SIGNAL(clicked( bool )), this, SLOT(emailFeedback())); - connect(ui.pushButton_EmailSupport, SIGNAL(clicked( bool )), this, SLOT(emailSupport())); + connect(ui.pushButton_FAQ, SIGNAL(clicked(bool)), this, SLOT(OpenFAQ())); + connect(ui.pushButton_Forums, SIGNAL(clicked(bool)), this, SLOT(OpenForums())); + connect(ui.pushButton_Website, SIGNAL(clicked(bool)), this, SLOT(OpenWebsite())); + connect(ui.pushButton_EmailFeedback, SIGNAL(clicked(bool)), this, SLOT(emailFeedback())); + connect(ui.pushButton_EmailSupport, SIGNAL(clicked(bool)), this, SLOT(emailSupport())); } GetStartedDialog::~GetStartedDialog() @@ -105,8 +105,7 @@ void GetStartedDialog::showEvent ( QShowEvent * /*event*/ ) void GetStartedDialog::updateFromUserLevel() { - RsConfigUserLvl userLevel = RsConfigUserLvl::NEW; - userLevel = rsConfig->getUserLevel(); + RsConfigUserLvl userLevel = rsConfig->getUserLevel(); ui.inviteCheckBox->setChecked(false); ui.addCheckBox->setChecked(false); @@ -185,17 +184,12 @@ void GetStartedDialog::tickFirewallChanged() } } -static void sendMail(const QString &address, const QString &subject, QString body) +static void sendMail(const QString &address, const QString &subject, const QString &body) { - /* Only under windows do we need to do this! */ -#ifdef Q_OS_WIN - /* search and replace the end of lines with: "%0D%0A" */ - body.replace("\n", "%0D%0A"); -#endif QString mailstr = "mailto:" + address; - mailstr += "?subject=" + subject; - mailstr += "&body=" + body; + mailstr += "?subject=" + QUrl::toPercentEncoding(subject); + mailstr += "&body=" + QUrl::toPercentEncoding(body); std::cerr << "MAIL STRING:" << mailstr.toStdString() << std::endl; @@ -235,12 +229,12 @@ void GetStartedDialog::inviteFriends() { RsAutoUpdatePage::lockAllEvents(); - cert = rsPeers->GetRetroshareInvite(RsPeerId(),RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::FULL_IP_HISTORY); + cert = rsPeers->GetRetroshareInvite(RsPeerId(),RsPeers::defaultCertificateFlags | RetroshareInviteFlags::FULL_IP_HISTORY); RsAutoUpdatePage::unlockAllEvents() ; } - QString text = QString("%1\n%2\n\n%3\n").arg(GetInviteText()).arg(GetCutBelowText()).arg(QString::fromUtf8(cert.c_str())); + QString text = QString("%1\n%2\n\n%3\n").arg(GetInviteText(), GetCutBelowText(), QString::fromUtf8(cert.c_str())); sendMail("", tr("RetroShare Invitation"), text); } @@ -427,8 +421,10 @@ void GetStartedDialog::emailSupport() sysVersion = "Linux"; #endif #endif - text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true)).arg(sysVersion).arg(static_cast::type>(userLevel)) + "\n"; - text += "\n"; + text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true) + , sysVersion + ).arg(static_cast::type>(userLevel)) + "\n"; + text += "\n"; text += QString("I am having trouble with RetroShare."); text += QString(" Can you help me with....") + "\n"; diff --git a/retroshare-gui/src/gui/GetStartedDialog.ui b/retroshare-gui/src/gui/GetStartedDialog.ui index 13698c204..5c0a78e6b 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.ui +++ b/retroshare-gui/src/gui/GetStartedDialog.ui @@ -10,7 +10,7 @@ 582 - + 0 @@ -32,11 +32,20 @@ Getting Started - + 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -53,12 +62,12 @@ 732 - + 0 - + @@ -121,20 +130,20 @@ <!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:'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;">RetroShare is nothing without your Friends. Click on the Button to start the process.</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;">Email an Invitation with your &quot;ID Certificate&quot; to your 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;">Be sure to get their invitation back as well... </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;">You can only connect with friends if you have both added each other.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:12pt;">RetroShare is nothing without your Friends. Click on the Button to start the process.</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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">Email an Invitation with your &quot;ID Certificate&quot; to your 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">Be sure to get their invitation back as well... </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-family:'MS Shell Dlg 2'; font-size:12pt;">You can only connect with friends if you have both added each other.</span></p></body></html>
- + @@ -197,17 +206,17 @@ p, li { white-space: pre-wrap; } <!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:'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 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;">Paste your Friends' &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">Paste your Friends' &quot;ID Certificates&quot; into the window and add them as friends.</span></p></body></html>
- + 0 @@ -282,25 +291,25 @@ p, li { white-space: pre-wrap; } <!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:'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 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> -<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 DHT indicator (in the Status Bar) turns Green when it can make connections.</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;">After a couple of minutes, the NAT indicator (also in the Status Bar) switch to Yellow or Green.</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 it remains Red, then you have a Nasty Firewall, that RetroShare struggles to connect through.</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;">Look in the Further Help section for more advice about connecting.</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;">This takes 5-30 minutes the first time you start up 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">The DHT indicator (in the Status Bar) turns Green when it can make connections.</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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">After a couple of minutes, the NAT indicator (also in the Status Bar) switch to Yellow or Green.</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-family:'MS Shell Dlg 2'; font-size:12pt;">If it remains Red, then you have a Nasty Firewall, that RetroShare struggles to connect through.</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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">Look in the Further Help section for more advice about connecting.</span></p></body></html>
- + @@ -366,23 +375,23 @@ p, li { white-space: pre-wrap; } <!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:'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="-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 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 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> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p></body></html>
- + Qt::Vertical @@ -407,31 +416,31 @@ p, li { white-space: pre-wrap; } Further Help and Support - + - + <!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:'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 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="-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;"> - 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> -<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;">Enjoy Retrosharing</span></p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; 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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">4) If you are still stuck. Email us.</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-family:'MS Shell Dlg 2'; font-size:12pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:12pt;">Enjoy Retrosharing</span></p></body></html>
- + @@ -454,7 +463,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -481,7 +490,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -494,7 +503,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical diff --git a/retroshare-gui/src/gui/HelpDialog.ui b/retroshare-gui/src/gui/HelpDialog.ui index 66884029f..3d40a8a90 100644 --- a/retroshare-gui/src/gui/HelpDialog.ui +++ b/retroshare-gui/src/gui/HelpDialog.ui @@ -56,7 +56,7 @@ 6 - + @@ -72,13 +72,13 @@ - + <!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:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -97,16 +97,6 @@ p, li { white-space: pre-wrap; } - - - - QFrame::StyledPanel - - - QFrame::Raised - - - @@ -223,7 +213,7 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> diff --git a/retroshare-gui/src/gui/HomePage.cpp b/retroshare-gui/src/gui/HomePage.cpp index 3caba0ca1..ff7622b4b 100644 --- a/retroshare-gui/src/gui/HomePage.cpp +++ b/retroshare-gui/src/gui/HomePage.cpp @@ -24,6 +24,7 @@ #include "retroshare/rsinit.h" #include "util/qtthreadsutils.h" +#include "util/misc.h" #include "gui/notifyqt.h" #include "gui/msgs/MessageComposer.h" @@ -49,14 +50,10 @@ HomePage::HomePage(QWidget *parent) : MainPage(parent), - ui(new Ui::HomePage), - mIncludeAllIPs(false), - mUseShortFormat(true) + ui(new Ui::HomePage) { ui->setupUi(this); - updateCertificate(); - connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addFriend())); connect(ui->copyIDButton, SIGNAL(clicked()), this, SLOT(copyId())); @@ -72,52 +69,72 @@ HomePage::HomePage(QWidget *parent) : QAction *CopyIdAction = new QAction(QIcon(),tr("Copy your Retroshare ID to Clipboard"), this); connect(CopyIdAction, SIGNAL(triggered()), this, SLOT(copyId())); - QMenu *menu = new QMenu(); + QMenu *menu = new QMenu(); menu->addAction(CopyIdAction); - if(!RsAccounts::isHiddenNode()) - { - QAction *includeIPsAct = new QAction(QIcon(), tr("Include all your known IPs"),this); - connect(includeIPsAct, SIGNAL(triggered()), this, SLOT(toggleIncludeAllIPs())); - includeIPsAct->setCheckable(true); - includeIPsAct->setChecked(mIncludeAllIPs); - - menu->addAction(includeIPsAct); - } - QAction *useOldFormatAct = new QAction(QIcon(), tr("Use old certificate format"),this); - useOldFormatAct->setToolTip(tr("Displays the certificate format used up to version 0.6.5\nOld Retroshare nodes will not understand the\nnew short format")); - connect(useOldFormatAct, SIGNAL(triggered()), this, SLOT(toggleUseOldFormat())); - useOldFormatAct->setCheckable(true); - useOldFormatAct->setChecked(!mUseShortFormat); - menu->addAction(useOldFormatAct); - menu->addSeparator(); menu->addAction(SendAction); menu->addAction(WebMailAction); menu->addAction(RecAction); + menu->addSeparator(); + + mUseOldFormatact = new QAction(QIcon(), tr("Use old certificate format"),this); + mUseOldFormatact->setToolTip(tr("Displays the certificate format used up to version 0.6.5\nOld Retroshare nodes will not understand the\nnew short format")); + connect(mUseOldFormatact, SIGNAL(triggered()), this, SLOT(updateOwnCert())); + mUseOldFormatact->setCheckable(true); + mUseOldFormatact->setChecked(false); + menu->addAction(mUseOldFormatact); + + if(!RsAccounts::isHiddenNode()) + { + mIncludeLocIPact = new QAction(QIcon(), tr("Include current local IP"),this); + connect(mIncludeLocIPact, SIGNAL(triggered()), this, SLOT(updateOwnCert())); + mIncludeLocIPact->setCheckable(true); + mIncludeLocIPact->setChecked(true); + menu->addAction(mIncludeLocIPact); + + mIncludeExtIPact = new QAction(QIcon(), tr("Include current external IP"),this); + connect(mIncludeExtIPact, SIGNAL(triggered()), this, SLOT(updateOwnCert())); + mIncludeExtIPact->setCheckable(true); + mIncludeExtIPact->setChecked(true); + menu->addAction(mIncludeExtIPact); + + mIncludeDNSact = new QAction(QIcon(), tr("Include my DNS"),this); + connect(mIncludeDNSact, SIGNAL(triggered()), this, SLOT(updateOwnCert())); + mIncludeDNSact->setCheckable(true); + mIncludeDNSact->setChecked(true); + menu->addAction(mIncludeDNSact); + + mIncludeIPHistoryact = new QAction(QIcon(), tr("Include all IPs history"),this); + connect(mIncludeIPHistoryact, SIGNAL(triggered()), this, SLOT(updateOwnCert())); + mIncludeIPHistoryact->setCheckable(true); + mIncludeIPHistoryact->setChecked(false); + menu->addAction(mIncludeIPHistoryact); + } ui->shareButton->setMenu(menu); connect(ui->openwebhelp,SIGNAL(clicked()), this,SLOT(openWebHelp())) ; - int S = QFontMetricsF(font()).height(); - QString help_str = tr( - "

  Welcome to Retroshare!

\ -

You need to make friends! After you create a network of friends or join an existing network,\ - you'll be able to exchange files, chat, talk in forums, etc.

\ -
\ - \ -
\ -

To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.

\ -

Another option is to search the internet for \"Retroshare chat servers\" (independently administrated). These servers allow you to exchange \ - Retroshare ID with a dedicated Retroshare node, through which\ - you will be able to anonymously meet other people.

").arg(QString::number(2*S)).arg(width()*0.5); - registerHelpButton(ui->helpButton,help_str,"HomePage") ; + int H = misc::getFontSizeFactor("HelpButton").height(); + QString help_str = tr( + "

  Welcome to Retroshare!

" + "

You need to make friends! After you create a network of friends or join an existing network," + " you'll be able to exchange files, chat, talk in forums, etc.

" + "
" + "

To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.

" + "

Another option is to search the internet for \"Retroshare chat servers\" (independently administrated). These servers allow you to exchange" + " Retroshare ID with a dedicated Retroshare node, through which" + " you will be able to anonymously meet other people.

" + ).arg(QString::number(2*H), QString::number(width()*0.5), QString::number(width()*0.5*(337.0/800.0)));// needs height and width defined. + registerHelpButton(ui->helpButton,help_str,"HomePage") ; - // register a event handler to catch IP updates + // register a event handler to catch IP updates mEventHandlerId = 0; rsEvents->registerEventsHandler( [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId, RsEventType::NETWORK ); + + updateOwnCert(); } void HomePage::handleEvent(std::shared_ptr e) @@ -136,16 +153,19 @@ void HomePage::handleEvent(std::shared_ptr e) { case RsNetworkEventCode::LOCAL_IP_UPDATED: // [fallthrough] case RsNetworkEventCode::EXTERNAL_IP_UPDATED: // [fallthrough] + case RsNetworkEventCode::DNS_UPDATED: // [fallthrough] RsQThreadUtils::postToObject( [=]() { - updateCertificate(); + updateOwnCert(); },this); break; default: break; } } -void HomePage::certContextMenu(QPoint point) + +#ifdef DEAD_CODE +void HomePage::certContextMenu(QPoint /*point*/) { QMenu menu(this) ; @@ -177,17 +197,7 @@ void HomePage::certContextMenu(QPoint point) menu.exec(QCursor::pos()); } - -void HomePage::toggleUseShortFormat() -{ - mUseShortFormat = !mUseShortFormat; - updateCertificate(); -} -void HomePage::toggleIncludeAllIPs() -{ - mIncludeAllIPs = !mIncludeAllIPs; - updateCertificate(); -} +#endif HomePage::~HomePage() { @@ -195,15 +205,29 @@ HomePage::~HomePage() delete ui; } -void HomePage::updateCertificate() +RetroshareInviteFlags HomePage::currentInviteFlags() const { - updateOwnCert(); + RetroshareInviteFlags invite_flags = RetroshareInviteFlags::NOTHING; + + if(!RsAccounts::isHiddenNode()) + { + if(mIncludeLocIPact->isChecked()) + invite_flags |= RetroshareInviteFlags::CURRENT_LOCAL_IP; + + if(mIncludeExtIPact->isChecked()) + invite_flags |= RetroshareInviteFlags::CURRENT_EXTERNAL_IP; + + if(mIncludeDNSact->isChecked()) + invite_flags |= RetroshareInviteFlags::DNS; + + if(mIncludeIPHistoryact->isChecked()) + invite_flags |= RetroshareInviteFlags::FULL_IP_HISTORY; + } + + return invite_flags; } - -void HomePage::updateOwnCert() +void HomePage::getOwnCert(QString& invite,QString& description) const { - bool include_extra_locators = mIncludeAllIPs; - RsPeerDetails detail; if (!rsPeers->getPeerDetails(rsPeers->getOwnId(), detail)) @@ -211,24 +235,36 @@ void HomePage::updateOwnCert() std::cerr << "(EE) Cannot retrieve information about own certificate. That is a real problem!!" << std::endl; return ; } + auto invite_flags = currentInviteFlags(); - QString invite ; - RetroshareInviteFlags invite_flags = RetroshareInviteFlags::CURRENT_IP; + invite_flags |= RetroshareInviteFlags::SLICE_TO_80_CHARS; - if(mIncludeAllIPs) - invite_flags |= RetroshareInviteFlags::FULL_IP_HISTORY; - - if(mUseShortFormat) + if(!mUseOldFormatact->isChecked()) { std::string short_invite; rsPeers->getShortInvite(short_invite,rsPeers->getOwnId(),invite_flags | RetroshareInviteFlags::RADIX_FORMAT); + invite = QString::fromStdString(short_invite); + } + else + invite = QString::fromStdString(rsPeers->GetRetroshareInvite(detail.id,invite_flags)); + description = ConfCertDialog::getCertificateDescription(detail,false,!mUseOldFormatact->isChecked(),invite_flags); +} + +void HomePage::updateOwnCert() +{ + QString certificate, description; + + getOwnCert(certificate,description); + + if(!mUseOldFormatact->isChecked()) // in this case we have to split the cert for a better display + { QString S; QString txt; - for(uint32_t i=0;iGetRetroshareInvite(detail.id,invite_flags)); - - ui->retroshareid->setText("\n"+invite+"\n"); - - QString description = ConfCertDialog::getCertificateDescription(detail,false,mUseShortFormat,include_extra_locators); + ui->retroshareid->setText("\n"+certificate+"\n"); ui->retroshareid->setToolTip(description); } -static void sendMail(QString sAddress, QString sSubject, QString sBody) +static void sendMail(const QString &sAddress, const QString &sSubject, const QString &sBody) { -#ifdef Q_OS_WIN - /* search and replace the end of lines with: "%0D%0A" */ - sBody.replace("\n", "%0D%0A"); -#endif - QUrl url = QUrl("mailto:" + sAddress); #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) @@ -265,7 +290,12 @@ static void sendMail(QString sAddress, QString sSubject, QString sBody) #endif urlQuery.addQueryItem("subject", sSubject); +#ifdef Q_OS_WIN + /* search and replace the end of lines with: "%0D%0A" */ + urlQuery.addQueryItem("body", QString(sBody).replace("\n", "%0D%0A")); +#else urlQuery.addQueryItem("body", sBody); +#endif #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) url.setQuery(urlQuery); @@ -347,9 +377,3 @@ void HomePage::openWebHelp() { QDesktopServices::openUrl(QUrl(QString("https://retrosharedocs.readthedocs.io/en/latest/"))); } - -void HomePage::toggleUseOldFormat() -{ - mUseShortFormat = !mUseShortFormat; - updateCertificate(); -} diff --git a/retroshare-gui/src/gui/HomePage.h b/retroshare-gui/src/gui/HomePage.h index 2b9e28c18..aa77ed1a3 100644 --- a/retroshare-gui/src/gui/HomePage.h +++ b/retroshare-gui/src/gui/HomePage.h @@ -46,28 +46,33 @@ public: virtual QString pageName() const { return tr("Home") ; } //MainPage virtual QString helpText() const { return ""; } //MainPage + // Returns the certificate along with its description using current options. + + void getOwnCert(QString& invite,QString& description) const; + RetroshareInviteFlags currentInviteFlags() const ; + private slots: - void certContextMenu(QPoint); +#ifdef DEAD_CODE + void certContextMenu(QPoint); +#endif void updateOwnCert(); - void updateCertificate(); void runEmailClient(); void copyCert(); void copyId(); void saveCert(); void addFriend(); void webMail(); - //void loadCert(); void openWebHelp() ; - void toggleUseOldFormat() ; void recommendFriends(); - void toggleIncludeAllIPs(); - void toggleUseShortFormat(); private: Ui::HomePage *ui; - bool mIncludeAllIPs; - bool mUseShortFormat; + QAction *mIncludeDNSact; + QAction *mIncludeIPHistoryact; + QAction *mIncludeExtIPact; + QAction *mIncludeLocIPact; + QAction *mUseOldFormatact; RsEventsHandlerId_t mEventHandlerId; diff --git a/retroshare-gui/src/gui/HomePage.ui b/retroshare-gui/src/gui/HomePage.ui index 60743b3c1..5de0fa6fe 100644 --- a/retroshare-gui/src/gui/HomePage.ui +++ b/retroshare-gui/src/gui/HomePage.ui @@ -89,6 +89,8 @@ 11 + 75 + true @@ -105,7 +107,7 @@ ... - + :/icons/help_64.png:/icons/help_64.png @@ -289,6 +291,13 @@ private and secure decentralized communication platform.
+ + + 15 + 75 + true + + Add friend @@ -415,8 +424,8 @@ private and secure decentralized communication platform. - + diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h index ba53b2bba..abefaf872 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.h @@ -23,7 +23,6 @@ #include -#include "util/TokenQueue.h" #include namespace Ui { diff --git a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui index 6a681f142..f54a19b8c 100644 --- a/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDetailsDialog.ui @@ -355,7 +355,7 @@ - + 0 @@ -493,12 +493,16 @@ p, li { white-space: pre-wrap; } - - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 + + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1
-
- + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 84f6ab2a3..5397f6300 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -169,15 +169,18 @@ IdDialog::IdDialog(QWidget *parent) //connect(mCirclesBroadcastBase, SIGNAL(fillDisplay(bool)), this, SLOT(updateCirclesDisplay(bool))); ownItem = new QTreeWidgetItem(); - ownItem->setText(0, tr("My own identities")); + ownItem->setText(RSID_COL_NICKNAME, tr("My own identities")); + ownItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); ownItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); // this is in order to prevent displaying a reputaiton icon next to these items. allItem = new QTreeWidgetItem(); - allItem->setText(0, tr("All")); + allItem->setText(RSID_COL_NICKNAME, tr("All")); + allItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); allItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); contactsItem = new QTreeWidgetItem(); - contactsItem->setText(0, tr("My contacts")); + contactsItem->setText(RSID_COL_NICKNAME, tr("My contacts")); + contactsItem->setFont(RSID_COL_NICKNAME, ui->idTreeWidget->font()); contactsItem->setData(RSID_COL_VOTES, Qt::DecorationRole,0xff); @@ -252,12 +255,14 @@ IdDialog::IdDialog(QWidget *parent) connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); connect(ui->inviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); + connect(ui->editButton, SIGNAL(clicked()), this, SLOT(editIdentity())); connect( ui->idTreeWidget, &RSTreeWidget::itemDoubleClicked, this, &IdDialog::chatIdentityItem ); + ui->editButton->hide(); - ui->avlabel_Circles->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/circles.png")); + ui->avLabel_Circles->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/circles.png")); ui->headerTextLabel_Circles->setText(tr("Circles")); @@ -364,6 +369,7 @@ IdDialog::IdDialog(QWidget *parent) ui->idTreeWidget->setColumnWidth(RSID_COL_IDTYPE, 18 * fontWidth); ui->idTreeWidget->setColumnWidth(RSID_COL_VOTES, 2 * fontWidth); + ui->idTreeWidget->setItemDelegate(new RSElidedItemDelegate()); ui->idTreeWidget->setItemDelegateForColumn( RSID_COL_NICKNAME, new GxsIdTreeItemDelegate()); @@ -379,20 +385,22 @@ IdDialog::IdDialog(QWidget *parent) mStateHelper->setActive(IDDIALOG_IDDETAILS, false); mStateHelper->setActive(IDDIALOG_REPLIST, false); + int H = misc::getFontSizeFactor("HelpButton").height(); QString hlp_str = tr( - "

  Identities

\ -

In this tab you can create/edit pseudo-anonymous identities, and circles.

\ -

Identities are used to securely identify your data: sign messages in chat lobbies, forum and channel posts,\ - receive feedback using the Retroshare built-in email system, post comments \ - after channel posts, chat using secured tunnels, etc.

\ -

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.

\ -

Anonymous identities allow you to anonymously interact with other users. They cannot be \ - spoofed, but noone can prove who really owns a given identity.

\ -

Circles are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be \ - used to restrict the visibility to forums, channels, etc.

\ -

An circle can be restricted to another circle, thereby limiting its visibility to members of that circle \ - or even self-restricted, meaning that it is only visible to invited members.

") ; + "

  Identities

" + "

In this tab you can create/edit pseudo-anonymous identities, and circles.

" + "

Identities are used to securely identify your data: sign messages in chat lobbies, forum and channel posts," + " receive feedback using the Retroshare built-in email system, post comments" + " after channel posts, chat using secured tunnels, etc.

" + "

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.

" + "

Anonymous identities allow you to anonymously interact with other users. They cannot be" + " spoofed, but noone can prove who really owns a given identity.

" + "

Circles are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be" + " used to restrict the visibility to forums, channels, etc.

" + "

An circle can be restricted to another circle, thereby limiting its visibility to members of that circle" + " or even self-restricted, meaning that it is only visible to invited members.

" + ).arg(QString::number(2*H)); registerHelpButton(ui->helpButton, hlp_str,"PeopleDialog") ; @@ -406,9 +414,7 @@ IdDialog::IdDialog(QWidget *parent) connect(ui->autoBanIdentities_CB, SIGNAL(toggled(bool)), this, SLOT(toggleAutoBanIdentities(bool))); updateIdTimer.setSingleShot(true); - updateCircleTimer.setSingleShot(true); connect(&updateIdTimer, SIGNAL(timeout()), this, SLOT(updateIdList())); - connect(&updateCircleTimer, SIGNAL(timeout()), this, SLOT(updateCircles())); } void IdDialog::handleEvent_main_thread(std::shared_ptr event) @@ -427,7 +433,10 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsIdentityEventCode::UPDATED_IDENTITY: if (isVisible()) { - updateIdTimer.start(5000); + if(rsIdentity->isOwnId(RsGxsId(e->mIdentityId))) + updateIdList(); + else + updateIdTimer.start(3000); // use a timer for events not generated by local changes } else needUpdateIdsOnNextShow = true; @@ -458,9 +467,7 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr event) case RsGxsCircleEventCode::CACHE_DATA_UPDATED: if (isVisible()) - { - updateCircleTimer.start(5000); - } + updateCircles(); else needUpdateCirclesOnNextShow = true; default: @@ -474,10 +481,10 @@ void IdDialog::clearPerson() { QFontMetricsF f(ui->avLabel_Person->font()) ; - ui->avLabel_Person->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); + ui->avLabel_Person->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/people.png").scaled(f.height()*4,f.height()*4,Qt::KeepAspectRatio,Qt::SmoothTransformation)); ui->headerTextLabel_Person->setText(tr("People")); - ui->inviteFrame->hide(); + ui->info_Frame_Invite->hide(); ui->avatarLabel->clear(); whileBlocking(ui->ownOpinion_CB)->setCurrentIndex(1); @@ -647,15 +654,16 @@ void IdDialog::loadCircles(const std::list& groupInfo) if(!mExternalOtherCircleItem) { mExternalOtherCircleItem = new QTreeWidgetItem(); - mExternalOtherCircleItem->setText(0, tr("Other circles")); - + mExternalOtherCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Other circles")); + mExternalOtherCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font()); ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem); } if(!mExternalBelongingCircleItem ) { mExternalBelongingCircleItem = new QTreeWidgetItem(); - mExternalBelongingCircleItem->setText(0, tr("Circles I belong to")); + mExternalBelongingCircleItem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Circles I belong to")); + mExternalBelongingCircleItem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, ui->treeWidget_membership->font()); ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem); } #endif @@ -731,14 +739,11 @@ void IdDialog::loadCircles(const std::list& groupInfo) item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tooltip); - if (am_I_admin) - { - QFont font = item->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; - font.setBold(true) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; - item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; - } + QFont font = ui->treeWidget_membership->font() ; + font.setBold(am_I_admin) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; + item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; // now determine for this circle wether we have pending invites // we add a sub-item to the circle (to show the invite system info) in the following two cases: @@ -853,12 +858,10 @@ void IdDialog::loadCircles(const std::list& groupInfo) subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole, QVariant(it->second)) ; subitem->setData(CIRCLEGROUP_CIRCLE_COL_GROUPID, Qt::UserRole, QString::fromStdString(it->first.toStdString())) ; - //subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap)); - - new_sub_items.push_back(subitem); + new_sub_items.push_back(subitem); } - else - subitem = item->child(subitem_index); + else + subitem = item->child(subitem_index); if(invited && !subscrb) { @@ -877,15 +880,12 @@ void IdDialog::loadCircles(const std::list& groupInfo) if(invited && subscrb) subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ; - if (is_own_id) - { - QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; - font.setBold(true) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; - subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; - } - } + QFont font = ui->treeWidget_membership->font() ; + font.setBold(is_own_id) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,font) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPID,font) ; + subitem->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; + } // add all items item->addChildren(new_sub_items); @@ -1111,7 +1111,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint ) static const int CANCEL = 3 ; // Admin list: no Subscription request: yes const QString menu_titles[4] = { tr("Request subscription"), tr("Accept circle invitation"), tr("Quit this circle"),tr("Cancel subscribe request")} ; - const QString image_names[4] = { ":/images/edit_add24.png",":/images/accepted16.png",":/icons/png/enter.png",":/images/cancel.png" } ; + const QString image_names[4] = { ":/images/edit_add24.png",":/images/accepted16.png",":/icons/png/enter.png",":/icons/cancel.svg" } ; std::vector< std::vector > ids(4) ; @@ -1388,73 +1388,42 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, uint32_t item_flags = 0; /* do filtering */ - bool ok = false; if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) - { - if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF)) - { - ok = true; - item_flags |= RSID_FILTER_YOURSELF ; - } + { + if (isLinkedToOwnNode && (accept & RSID_FILTER_YOURSELF)) + item_flags |= RSID_FILTER_YOURSELF ; - if (data.mPgpKnown && (accept & RSID_FILTER_FRIENDS)) - { - ok = true; - item_flags |= RSID_FILTER_FRIENDS ; - } + if (data.mPgpKnown && (accept & RSID_FILTER_FRIENDS)) + item_flags |= RSID_FILTER_FRIENDS ; - if (accept & RSID_FILTER_OTHERS) - { - ok = true; - item_flags |= RSID_FILTER_OTHERS ; - } - } - else if (accept & RSID_FILTER_PSEUDONYMS) - { - ok = true; - item_flags |= RSID_FILTER_PSEUDONYMS ; - } + if (accept & RSID_FILTER_OTHERS) + item_flags |= RSID_FILTER_OTHERS ; + } + else if (accept & RSID_FILTER_PSEUDONYMS) + item_flags |= RSID_FILTER_PSEUDONYMS ; - if (isOwnId && (accept & RSID_FILTER_OWNED_BY_YOU)) - { - ok = true; - item_flags |= RSID_FILTER_OWNED_BY_YOU ; - } + if (isOwnId && (accept & RSID_FILTER_OWNED_BY_YOU)) + item_flags |= RSID_FILTER_OWNED_BY_YOU ; if (isBanned && (accept & RSID_FILTER_BANNED)) - { - ok = true; item_flags |= RSID_FILTER_BANNED ; - } - if (!ok) + if (item_flags == 0) return false; if (!item) - { - item = new TreeWidgetItem(); - } - + item = new TreeWidgetItem(); + item->setText(RSID_COL_NICKNAME, QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE)); item->setData(RSID_COL_NICKNAME, Qt::UserRole, QString::fromStdString(data.mMeta.mGroupId.toStdString())); item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString())); - if(isBanned) - { - //TODO (Phenom): Add qproperty for these text colors in stylesheets - item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red)); - item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QColor(Qt::red)); - } - else - { - item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QVariant()); - item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QVariant()); - } + //TODO (Phenom): Add qproperty for these text colors in stylesheets + item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_KEYID , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); + item->setData(RSID_COL_VOTES , Qt::ForegroundRole, isBanned ? QColor(Qt::red) : QVariant() ); item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ; item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter); @@ -1465,16 +1434,9 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, RSID_COL_VOTES,SortRole, static_cast(idd.mReputation.mOverallReputationLevel)); - if(isOwnId) - { - QFont font = item->font(RSID_COL_NICKNAME) ; - - font.setBold(true) ; - item->setFont(RSID_COL_NICKNAME,font) ; - item->setFont(RSID_COL_IDTYPE,font) ; - item->setFont(RSID_COL_KEYID,font) ; - - QString tooltip = tr("This identity is owned by you"); + if(isOwnId) + { + QString tooltip = tr("This identity is owned by you"); if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED) { @@ -1486,10 +1448,16 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ; } - item->setToolTip(RSID_COL_NICKNAME, tooltip) ; - item->setToolTip(RSID_COL_KEYID, tooltip) ; - item->setToolTip(RSID_COL_IDTYPE, tooltip) ; - } + item->setToolTip(RSID_COL_NICKNAME, tooltip) ; + item->setToolTip(RSID_COL_KEYID, tooltip) ; + item->setToolTip(RSID_COL_IDTYPE, tooltip) ; + } + QFont font = ui->idTreeWidget->font() ; + font.setBold(isOwnId) ; + item->setFont(RSID_COL_NICKNAME,font) ; + item->setFont(RSID_COL_IDTYPE,font) ; + item->setFont(RSID_COL_KEYID,font) ; + //QPixmap pixmap ; // @@ -1500,8 +1468,6 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, // Icon Place Holder item->setIcon(RSID_COL_NICKNAME,FilesDefs::getIconFromQtResourcePath(":/icons/png/anonymous.png")); - QString tooltip; - if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) { if (data.mPgpKnown) @@ -1512,25 +1478,25 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item, item->setToolTip(RSID_COL_IDTYPE,"Verified signature from node "+QString::fromStdString(data.mPgpId.toStdString())) ; - tooltip += tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n"; - tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ; + QString tooltip = tr("Node name:")+" " + QString::fromUtf8(details.name.c_str()) + "\n"; + tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ; item->setToolTip(RSID_COL_KEYID,tooltip) ; } else { - QString txt = tr("[Unknown node]"); + QString txt = tr("[Unknown node]"); item->setText(RSID_COL_IDTYPE, txt); - - if(!data.mPgpId.isNull()) - { - item->setToolTip(RSID_COL_IDTYPE,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; - item->setToolTip(RSID_COL_KEYID,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; - } - else - { - item->setToolTip(RSID_COL_IDTYPE,tr("Unchecked signature")) ; - item->setToolTip(RSID_COL_KEYID,tr("Unchecked signature")) ; - } + + if(!data.mPgpId.isNull()) + { + item->setToolTip(RSID_COL_IDTYPE,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; + item->setToolTip(RSID_COL_KEYID,tr("Unverified signature from node ")+QString::fromStdString(data.mPgpId.toStdString())) ; + } + else + { + item->setToolTip(RSID_COL_IDTYPE,tr("Unchecked signature")) ; + item->setToolTip(RSID_COL_KEYID,tr("Unchecked signature")) ; + } } } else @@ -1810,7 +1776,8 @@ void IdDialog::loadIdentity(RsGxsIdGroup data) // ui->editIdentity->setEnabled(true); // ui->removeIdentity->setEnabled(true); ui->chatIdentity->setEnabled(false); - ui->inviteButton->setEnabled(false); + ui->inviteButton->hide(); + ui->editButton->show(); } else { @@ -1820,7 +1787,8 @@ void IdDialog::loadIdentity(RsGxsIdGroup data) // ui->editIdentity->setEnabled(false); // ui->removeIdentity->setEnabled(false); ui->chatIdentity->setEnabled(true); - ui->inviteButton->setEnabled(true); + ui->inviteButton->show(); + ui->editButton->hide(); } ui->autoBanIdentities_CB->setChecked(rsReputations->isNodeBanned(data.mPgpId)); @@ -2221,8 +2189,9 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) if(!one_item_owned_by_you) { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -2230,12 +2199,14 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); - QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setObjectName("trans_Icon"); + QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("" + ui->titleBarLabel->text() + "", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); @@ -2289,7 +2260,7 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) contextMenu->addAction(QIcon(""),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; if(n_is_not_a_contact == 0) - contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/cancel.png"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); + contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"), tr("Remove from Contacts"), this, SLOT(removefromContacts())); contextMenu->addSeparator(); @@ -2308,8 +2279,8 @@ void IdDialog::IdListCustomPopupMenu( QPoint ) contextMenu->addSeparator(); contextMenu->addAction(QIcon(""),tr("Copy identity to clipboard"),this,SLOT(copyRetroshareLink())) ; - contextMenu->addAction(ui->editIdentity); - contextMenu->addAction(ui->removeIdentity); + contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_EDIT),tr("Edit identity"),this,SLOT(editIdentity())) ; + contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"),tr("Delete identity"),this,SLOT(removeIdentity())) ; } } @@ -2487,7 +2458,7 @@ void IdDialog::sendInvite() { MessageComposer::sendInvite(id,false); - ui->inviteFrame->show(); + ui->info_Frame_Invite->show(); ui->inviteButton->setEnabled(false); } @@ -2569,9 +2540,9 @@ void IdDialog::removefromContacts() updateIdList(); } -void IdDialog::on_closeInfoFrameButton_clicked() +void IdDialog::on_closeInfoFrameButton_Invite_clicked() { - ui->inviteFrame->setVisible(false); + ui->info_Frame_Invite->setVisible(false); } // We need to use indexes here because saving items is not possible since they can be re-created. diff --git a/retroshare-gui/src/gui/Identity/IdDialog.h b/retroshare-gui/src/gui/Identity/IdDialog.h index 709fd3692..403b3a437 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.h +++ b/retroshare-gui/src/gui/Identity/IdDialog.h @@ -89,7 +89,7 @@ private slots: void chatIdentityItem(QTreeWidgetItem* item); void sendMsg(); void copyRetroshareLink(); - void on_closeInfoFrameButton_clicked(); + void on_closeInfoFrameButton_Invite_clicked(); void updateSelection(); @@ -154,7 +154,6 @@ private: RsEventsHandlerId_t mEventHandlerId_circles; QTimer updateIdTimer; - QTimer updateCircleTimer; bool needUpdateIdsOnNextShow; bool needUpdateCirclesOnNextShow; diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index d785dbc4c..ff3775aee 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -6,7 +6,7 @@ 0 0 - 987 + 800 584 @@ -88,7 +88,14 @@
- + + + + 12 + 75 + true + + People @@ -211,6 +218,11 @@ 0 + + + 11 + + Qt::CustomContextMenu @@ -289,13 +301,13 @@ 0 0 - 634 - 523 + 456 + 731 - + 0 @@ -308,37 +320,44 @@ QFrame::Raised - + 12 - + + + + 22 + + People - - - Qt::Vertical + + + + 0 + 0 + - - - 518 - 17 - - - - - - + + + + 0 + 0 + 0 + + + @@ -359,6 +378,15 @@ + + + + 0 + 0 + 0 + + + @@ -379,6 +407,15 @@ + + + + 154 + 154 + 154 + + + @@ -409,7 +446,7 @@ QFrame::Box - + 6 @@ -423,7 +460,7 @@ 6 - + 16 @@ -442,14 +479,17 @@ - + Invite messages stay into your Outbox until an acknowledgement of receipt has been received. + + true + - + 16 @@ -609,6 +649,13 @@ border-image: url(:/images/closepressed.png) + + + + Edit Identity + + + @@ -796,7 +843,7 @@ border-image: url(:/images/closepressed.png) - + <html><head/><body><p><span style=" font-family:'Sans'; font-size:9pt;">Your own opinion about an identity rules the visibility of that identity for yourself and your friend nodes. Your own opinion is shared among friends and used to compute a reputation score: If your opinion about an identity is neutral, the reputation score is the difference between friend's positive and negative opinions. If not, your own opinion gives the score.</span></p><p><span style=" font-family:'Sans'; font-size:9pt;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity. When the overall score is lower than -1, the identity is banned, which prevents all messages and forums/channels authored by this identity to be forwarded, both ways. Some forums also have special anti-spam flags that require a non negative reputation level, making them more sensitive to bad opinions. Banned identities gradually lose their activity and eventually disappear (after 5 days).</span></p><p><span style=" font-family:'Sans'; font-size:9pt;">You can change the thresholds and the time of inactivity to delete identities in preferences -&gt; people. </span></p></body></html> @@ -844,9 +891,12 @@ border-image: url(:/images/closepressed.png) - + Auto-Ban all identities signed by the same node + + Auto-Ban profile + @@ -931,7 +981,7 @@ border-image: url(:/images/closepressed.png) detailsGroupBox usageStatisticsGBox - headerFramePerson + headerBFramePerson @@ -947,19 +997,19 @@ border-image: url(:/images/closepressed.png) - + QFrame::StyledPanel QFrame::Raised - + 12 - + 64 @@ -984,7 +1034,12 @@ border-image: url(:/images/closepressed.png) - + + + + 22 + + Circles @@ -995,6 +1050,11 @@ border-image: url(:/images/closepressed.png) + + + 11 + + Qt::CustomContextMenu @@ -1030,10 +1090,6 @@ border-image: url(:/images/closepressed.png) - - - :/images/edit_16.png:/images/edit_16.png - Edit identity @@ -1042,19 +1098,11 @@ border-image: url(:/images/closepressed.png) - - - :/images/delete.png:/images/delete.png - Delete identity - - - :/images/toaster/chat.png:/images/toaster/chat.png - Chat with this peer @@ -1067,7 +1115,7 @@ border-image: url(:/images/closepressed.png) LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
RSTreeWidget @@ -1075,14 +1123,14 @@ border-image: url(:/images/closepressed.png)
gui/common/RSTreeWidget.h
- StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
- StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSTextBrowser diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index 7f9f179cb..ac9965d2a 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -31,9 +31,10 @@ #include "util/misc.h" #include "gui/notifyqt.h" -#include -#include +#include "retroshare/rsidentity.h" +#include "retroshare/rspeers.h" #include "gui/common/FilesDefs.h" +#include "util/imageutil.h" #include @@ -46,6 +47,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) : ui(new(Ui::IdEditDialog)) { mIsNew = true; + mAvatarIsSet = false; ui->setupUi(this); @@ -76,7 +78,7 @@ IdEditDialog::IdEditDialog(QWidget *parent) : /* Connect signals */ connect(ui->radioButton_GpgId, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); connect(ui->radioButton_Pseudo, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool))); - connect(ui->createButton, SIGNAL(clicked()), this, SLOT(submit())); + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(submit())); connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(ui->plainTextEdit_Tag, SIGNAL(textChanged()), this, SLOT(checkNewTag())); @@ -87,6 +89,12 @@ IdEditDialog::IdEditDialog(QWidget *parent) : connect(ui->toolButton_Tag4, SIGNAL(clicked(bool)), this, SLOT(rmTag4())); connect(ui->toolButton_Tag5, SIGNAL(clicked(bool)), this, SLOT(rmTag5())); connect(ui->avatarButton, SIGNAL(clicked(bool)), this, SLOT(changeAvatar())); + connect(ui->removeButton, SIGNAL(clicked(bool)), this, SLOT(removeAvatar())); + + connect(ui->avatarLabel,SIGNAL(cleared()),this,SLOT(avatarCleared())); + + ui->avatarLabel->setEnableClear(true); + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); /* Initialize ui */ ui->lineEdit_Nickname->setMaxLength(RSID_MAXIMUM_NICKNAME_SIZE); @@ -96,6 +104,8 @@ IdEditDialog::IdEditDialog(QWidget *parent) : ui->plainTextEdit_Tag->hide(); ui->label_TagCheck->hide(); ui->frame_Tags->setHidden(true); + + updateInterface(); } IdEditDialog::~IdEditDialog() {} @@ -125,10 +135,13 @@ void IdEditDialog::changeAvatar() ui->avatarLabel->setPicture(QPixmap::fromImage(img)); ui->avatarLabel->setEnableZoom(true); - ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar.")); + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); + mAvatarIsSet = true; // shows the tooltip for a while QToolTip::showText( ui->avatarLabel->mapToGlobal( QPoint( 0, 0 ) ), ui->avatarLabel->toolTip() ); + + updateInterface(); } void IdEditDialog::setupNewId(bool pseudo,bool enable_anon) @@ -205,16 +218,25 @@ void IdEditDialog::updateIdType(bool pseudo) } } +void IdEditDialog::avatarCleared() +{ + setAvatar(QPixmap()); +} + void IdEditDialog::setAvatar(const QPixmap &avatar) { mAvatar = avatar; if (!mAvatar.isNull()) { ui->avatarLabel->setPicture(avatar); + mAvatarIsSet = true; + ui->avatarLabel->setToolTip(tr("Use the mouse to zoom and adjust the image for your avatar. Hit Del to remove it.")); } else { // we need to use the default pixmap here, generated from the ID - ui->avatarLabel->setPicture(GxsIdDetails::makeDefaultIcon(RsGxsId(mEditGroup.mMeta.mGroupId))); - } + ui->avatarLabel->setText(tr("No avatar chosen")); // This clears up the image + mAvatarIsSet = false; + ui->avatarLabel->setToolTip(tr("No Avatar chosen. A default image will be automatically displayed from your new identity.")); + } } void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId) @@ -222,7 +244,7 @@ void IdEditDialog::setupExistingId(const RsGxsGroupId& keyId) setWindowTitle(tr("Edit identity")); ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/person.png")); ui->headerFrame->setHeaderText(tr("Edit identity")); - ui->createButton->setText(tr("Update")); + ui->postButton->setText(tr("Update")); mStateHelper->setLoading(IDEDITDIALOG_LOADID, true); @@ -337,6 +359,7 @@ void IdEditDialog::loadExistingId(const RsGxsIdGroup& id_group) ui->frame_Tags->setHidden(true); loadRecognTags(); + updateInterface(); } #define MAX_RECOGN_TAGS 5 @@ -517,13 +540,9 @@ void IdEditDialog::loadRecognTags() void IdEditDialog::submit() { if (mIsNew) - { createId(); - } else - { updateId(); - } } void IdEditDialog::createId() @@ -551,15 +570,17 @@ void IdEditDialog::createId() params.nickname = groupname.toUtf8().constData(); params.isPgpLinked = (ui->radioButton_GpgId->isChecked()); - mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); - - if (!mAvatar.isNull()) + if(mAvatarIsSet) { + mAvatar = ui->avatarLabel->extractCroppedScaledPicture(); + QByteArray ba; QBuffer buffer(&ba); + bool has_transparency = ImageUtil::hasAlphaContent(mAvatar.toImage()); + buffer.open(QIODevice::WriteOnly); - mAvatar.save(&buffer, "PNG"); // writes image into ba in PNG format + mAvatar.save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format params.mImage.copy((uint8_t *) ba.data(), ba.size()); } @@ -589,7 +610,7 @@ void IdEditDialog::createId() if(rsIdentity->createIdentity(keyId,params.nickname,params.mImage,!params.isPgpLinked,gpg_password)) { - ui->createButton->setEnabled(false); + ui->postButton->setEnabled(false); if(!keyId.isNull()) { @@ -630,8 +651,10 @@ void IdEditDialog::updateId() QByteArray ba; QBuffer buffer(&ba); - buffer.open(QIODevice::WriteOnly); - mAvatar.save(&buffer, "PNG"); // writes image into ba in PNG format + bool has_transparency = ImageUtil::hasAlphaContent(mAvatar.toImage()); + + buffer.open(QIODevice::WriteOnly); + mAvatar.save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format mEditGroup.mImage.copy((uint8_t *) ba.data(), ba.size()); } @@ -667,3 +690,22 @@ void IdEditDialog::updateId() accept(); } +void IdEditDialog::removeAvatar() +{ + ui->avatarLabel->setPicture(QPixmap()); + mEditGroup.mImage.clear(); + + updateInterface(); +} + +void IdEditDialog::updateInterface() +{ + const QPixmap *pixmap = ui->avatarLabel->pixmap(); + if (pixmap && !pixmap->isNull()) { + ui->removeButton->setEnabled(true); + } else if (mEditGroup.mImage.mSize != NULL) { + ui->removeButton->setEnabled(true); + } else { + ui->removeButton->setEnabled(false); + } +} diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.h b/retroshare-gui/src/gui/Identity/IdEditDialog.h index 36eed2891..714a79256 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.h +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.h @@ -23,7 +23,6 @@ #include -#include "util/TokenQueue.h" #include #include #include @@ -51,8 +50,11 @@ public: private slots: void idTypeToggled(bool checked); void submit(); + void avatarCleared(); void changeAvatar(); + void removeAvatar(); + void updateInterface(); void addRecognTag(); void checkNewTag(); @@ -68,7 +70,6 @@ private: void updateIdType(bool pseudo); void loadExistingId(const RsGxsIdGroup& id_group); void setAvatar(const QPixmap &avatar); - void idCreated(uint32_t token); void loadRecognTags(); // extract details. @@ -84,6 +85,7 @@ protected: RsGxsGroupId mGroupId; QPixmap mAvatar; // Avatar from identity (not calculated) + bool mAvatarIsSet; }; #endif diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.ui b/retroshare-gui/src/gui/Identity/IdEditDialog.ui index fee114a9d..d0a625c00 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.ui @@ -55,10 +55,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -79,6 +88,15 @@ + + + + 0 + 0 + 0 + + + @@ -99,6 +117,15 @@ + + + + 154 + 154 + 154 + + + @@ -120,6 +147,11 @@ + + + 12 + + true @@ -310,6 +342,9 @@ 128 + + Qt::StrongFocus + QFrame::Box @@ -334,6 +369,13 @@ + + + + Remove + + + @@ -362,7 +404,7 @@ QFrame::Raised - + @@ -474,7 +516,7 @@ - + 9 @@ -504,7 +546,14 @@ - + + + + 12 + 75 + true + + Create diff --git a/retroshare-gui/src/gui/MainPage.cpp b/retroshare-gui/src/gui/MainPage.cpp index 545f1270e..6136343d7 100644 --- a/retroshare-gui/src/gui/MainPage.cpp +++ b/retroshare-gui/src/gui/MainPage.cpp @@ -18,12 +18,14 @@ * * *******************************************************************************/ -#include -#include - #include + #include "common/FloatingHelpBrowser.h" #include "gui/settings/rsharesettings.h" +#include "util/misc.h" + +#include +#include MainPage::MainPage(QWidget *parent , Qt::WindowFlags flags ) : QWidget(parent, flags) { @@ -44,13 +46,13 @@ UserNotify *MainPage::getUserNotify() void MainPage::registerHelpButton(QToolButton *button, const QString& help_html_text, const QString &code_name) { - mHelpCodeName = code_name ; + mHelpCodeName = code_name ; - if (mHelpBrowser == NULL) + if (mHelpBrowser == nullptr) mHelpBrowser = new FloatingHelpBrowser(this, button) ; - float S = QFontMetricsF(button->font()).height() ; - button->setIconSize(QSize(S,S)) ; + int H = misc::getFontSizeFactor("HelpButton").height(); + button->setIconSize(QSize(H, H)) ;//Square Icon mHelpBrowser->setHelpText(help_html_text) ; } diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index 8ba6a0a90..a59d76dfb 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -140,12 +141,10 @@ #define IMAGE_OVERLAY ":/icons/star_overlay_128.png" #define IMAGE_BWGRAPH ":/icons/png/bandwidth.png" -#define IMAGE_MESSENGER ":/images/rsmessenger48.png" #define IMAGE_COLOR ":/images/highlight.png" #define IMAGE_NEWRSCOLLECTION ":/images/library.png" #define IMAGE_ADDSHARE ":/images/directoryadd_24x24_shadow.png" #define IMAGE_OPTIONS ":/images/settings.png" -#define IMAGE_UNFINISHED ":/images/underconstruction.png" #define IMAGE_MINIMIZE ":/icons/fullscreen.png" #define IMAGE_MAXIMIZE ":/icons/fullscreen-exit.png" @@ -247,12 +246,13 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) statusBar()->setVisible(Settings->valueFromGroup("StatusBar", "ShowStatusBar", QVariant(true)).toBool()); /* initialize combobox in status bar */ - statusComboBox = new QComboBox(statusBar()); + statusComboBox = new RSComboBox(statusBar()); statusComboBox->setVisible(Settings->valueFromGroup("StatusBar", "ShowStatus", QVariant(true)).toBool()); statusComboBox->setFocusPolicy(Qt::ClickFocus); initializeStatusObject(statusComboBox, true); QWidget *widget = new QWidget(); + widget->setObjectName("trans_statusComboBoxFrame"); QHBoxLayout *hbox = new QHBoxLayout(); hbox->setMargin(0); hbox->setSpacing(6); @@ -466,10 +466,8 @@ void MainWindow::initStackedPage() } #ifndef RS_RELEASE_VERSION -#ifdef PLUGINMGR addPage(pluginsPage = new gui::PluginsPage(ui->stackPages), grp, NULL); #endif -#endif #undef GETSTARTED_GUI #ifdef GETSTARTED_GUI @@ -487,11 +485,11 @@ void MainWindow::initStackedPage() addPage(newsFeed = new NewsFeed(ui->stackPages), grp, ¬ify); //List All notify before Setting was created - QList > >::iterator notifyIt; - for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) { - UserNotify *userNotify = notifyIt->first->getUserNotify(); + for (auto notifyIt:notify) + { + UserNotify *userNotify = notifyIt.first->getUserNotify(); if (userNotify) { - userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second); + userNotify->initialize(ui->toolBarPage, notifyIt.second.first, notifyIt.second.second); connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine())); userNotifyList.push_back(userNotify); } @@ -505,7 +503,7 @@ void MainWindow::initStackedPage() #ifdef UNFINISHED - addAction(new QAction(QIcon(IMAGE_UNFINISHED), tr("Unfinished"), ui->toolBar), &MainWindow::showApplWindow, SLOT(showApplWindow())); + addAction(new QAction(QIcon(), tr("Unfinished"), ui->toolBar), &MainWindow::showApplWindow, SLOT(showApplWindow())); ui->toolBarAction->addSeparator(); notify += applicationWindow->getNotify(); #endif @@ -623,7 +621,7 @@ void MainWindow::createTrayIcon() trayMenu->addSeparator(); #ifdef MESSENGER_WINDOW - trayMenu->addAction(QIcon(IMAGE_MESSENGER), tr("Open Messenger"), this, SLOT(showMessengerWindow())); + trayMenu->addAction(QIcon(), tr("Open Messenger"), this, SLOT(showMessengerWindow())); #endif trayMenu->addAction(QIcon(IMAGE_MESSAGES), tr("Open Messages"), this, SLOT(showMess())); #ifdef RS_JSONAPI @@ -636,7 +634,7 @@ void MainWindow::createTrayIcon() #ifdef UNFINISHED - trayMenu->addAction(QIcon(IMAGE_UNFINISHED), tr("Applications"), this, SLOT(showApplWindow())); + trayMenu->addAction(QIcon(), tr("Applications"), this, SLOT(showApplWindow())); #endif trayMenu->addAction(QIcon(IMAGE_PREFERENCES), tr("Options"), this, SLOT(showSettings())); trayMenu->addAction(QIcon(IMG_HELP), tr("Help"), this, SLOT(showHelpDialog())); @@ -1081,7 +1079,9 @@ void SetForegroundWindowInternal(HWND hWnd) return _instance->gxsforumDialog; case Posted: return _instance->postedDialog; - } + case Home: + return _instance->homePage; + } return NULL; } @@ -1300,7 +1300,7 @@ static void setStatusObject(QObject *pObject, int nStatus) } return; } - QComboBox *pComboBox = dynamic_cast(pObject); + RSComboBox *pComboBox = dynamic_cast(pObject); if (pComboBox) { /* set index of combobox */ int nIndex = pComboBox->findData(nStatus, Qt::UserRole); @@ -1389,7 +1389,7 @@ void MainWindow::initializeStatusObject(QObject *pObject, bool bConnect) } } else { /* initialize combobox */ - QComboBox *pComboBox = dynamic_cast(pObject); + RSComboBox *pComboBox = dynamic_cast(pObject); if (pComboBox) { pComboBox->addItem(QIcon(StatusDefs::imageStatus(RS_STATUS_ONLINE)), StatusDefs::name(RS_STATUS_ONLINE), RS_STATUS_ONLINE); pComboBox->addItem(QIcon(StatusDefs::imageStatus(RS_STATUS_BUSY)), StatusDefs::name(RS_STATUS_BUSY), RS_STATUS_BUSY); @@ -1613,7 +1613,7 @@ void MainWindow::switchVisibilityStatus(StatusElement e,bool b) //{ // ServicePermissionDialog::showYourself(); //} -QComboBox *MainWindow::statusComboBoxInstance() +RSComboBox *MainWindow::statusComboBoxInstance() { return statusComboBox; } @@ -1628,6 +1628,11 @@ NATStatus *MainWindow::natstatusInstance() return natstatus; } +void MainWindow::torstatusReset() +{ + if(torstatus != nullptr) + torstatus->reset(); +} DHTStatus *MainWindow::dhtstatusInstance() { return dhtstatus; @@ -1688,3 +1693,19 @@ void MainWindow::setCompactStatusMode(bool compact) ratesstatus->setCompactMode(compact); //opModeStatus: TODO Show only ??? } + +Gui_InputDialogReturn MainWindow::guiInputDialog(const QString& windowTitle, const QString& labelText, QLineEdit::EchoMode textEchoMode, bool modal) +{ + + QInputDialog dialog(this); + dialog.setWindowTitle(windowTitle); + dialog.setLabelText(labelText); + dialog.setTextEchoMode(textEchoMode); + dialog.setModal(modal); + + Gui_InputDialogReturn ret; + ret.execReturn = dialog.exec(); + ret.textValue = dialog.textValue(); + + return ret; +} diff --git a/retroshare-gui/src/gui/MainWindow.h b/retroshare-gui/src/gui/MainWindow.h index be459d295..bac210f2c 100644 --- a/retroshare-gui/src/gui/MainWindow.h +++ b/retroshare-gui/src/gui/MainWindow.h @@ -21,16 +21,17 @@ #ifndef _MainWindow_H #define _MainWindow_H +#include #include #include #include "gui/common/rwindow.h" +#include "gui/common/RSComboBox.h" namespace Ui { class MainWindow; } -class QComboBox; class QLabel; class QActionGroup; class QListWidgetItem; @@ -74,6 +75,14 @@ class MessengerWindow; class ApplicationWindow; #endif + +struct Gui_InputDialogReturn +{ + int execReturn; + QString textValue; +}; +Q_DECLARE_METATYPE(Gui_InputDialogReturn); + class MainWindow : public RWindow { Q_OBJECT @@ -91,9 +100,10 @@ public: Channels = 6, /** Channels page. */ Forums = 7, /** Forums page. */ Search = 8, /** Search page. */ - Posted = 11, /** Posted links */ - People = 12, /** People page. */ - Options = 13 /** People page. */ + Posted = 11, /** Posted links */ + People = 12, /** People page. */ + Options = 13, /** People page. */ + Home = 14 /** Home page. */ }; @@ -174,9 +184,10 @@ public: void removeStatusObject(QObject *pObject); void setStatus(QObject *pObject, int nStatus); - QComboBox *statusComboBoxInstance(); + RSComboBox *statusComboBoxInstance(); PeerStatus *peerstatusInstance(); NATStatus *natstatusInstance(); + void torstatusReset(); DHTStatus *dhtstatusInstance(); HashingStatus *hashingstatusInstance(); DiscStatus *discstatusInstance(); @@ -192,7 +203,7 @@ public: } static bool hiddenmode; - + public slots: void receiveNewArgs(QStringList args); void displayErrorMessage(int,int,const QString&) ; @@ -210,9 +221,35 @@ public slots: void showBandwidthGraph(); void toggleStatusToolTip(bool toggle); + + /** + * @brief Create a QInputDialog. This must be called in MainWindow thread because Widgets must be created in the GUI thread. + * Here an exemple how to call it: + * + * bool sameThread = QThread::currentThread() == qApp->thread(); + * Gui_InputDialogReturn ret; + * qRegisterMetaType("Gui_InputDialogReturn"); + * QMetaObject::invokeMethod( MainWindow::getInstance() + * , "guiInputDialog" + * , sameThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection + * , Q_RETURN_ARG(Gui_InputDialogReturn, ret) + * , Q_ARG(QString, windowTitle) + * , Q_ARG(QString, labelText) + * , Q_ARG(QLineEdit::EchoMode, textEchoMode) + * , Q_ARG(bool, modal) + * ); + * + * @param windowTitle: the window title (caption). + * @param labelText: label's text which describes what needs to be input. + * @param textEchoMode: the echo mode for the text value. + * @param modal: pop up the dialog as modal or modeless. + * @return Gui_InputDialogReturn ( Accepted(1)|Rejected(0), text value for the input dialog) + */ + Gui_InputDialogReturn guiInputDialog(const QString& windowTitle, const QString& labelText, QLineEdit::EchoMode textEchoMode, bool modal); + protected: /** Default Constructor */ - MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + MainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); void closeEvent(QCloseEvent *); @@ -294,7 +331,7 @@ private: QAction *toggleVisibilityAction, *toolAct; QList userNotifyList; - QComboBox *statusComboBox; + RSComboBox *statusComboBox; PeerStatus *peerstatus; NATStatus *natstatus; DHTStatus *dhtstatus; diff --git a/retroshare-gui/src/gui/MainWindow.ui b/retroshare-gui/src/gui/MainWindow.ui index d1dc1c2f7..55a7145e0 100644 --- a/retroshare-gui/src/gui/MainWindow.ui +++ b/retroshare-gui/src/gui/MainWindow.ui @@ -33,6 +33,11 @@ 0 + + + 12 + + QFrame::NoFrame @@ -143,7 +148,7 @@
- + :/images/add-share24.png:/images/add-share24.png @@ -161,7 +166,7 @@ - + :/images/messenger.png:/images/messenger.png @@ -187,7 +192,7 @@ - + :/images/exit_24x24.png:/images/exit_24x24.png diff --git a/retroshare-gui/src/gui/MessengerWindow.ui b/retroshare-gui/src/gui/MessengerWindow.ui index 7e952e86b..cc81303b8 100644 --- a/retroshare-gui/src/gui/MessengerWindow.ui +++ b/retroshare-gui/src/gui/MessengerWindow.ui @@ -74,7 +74,7 @@ - + true @@ -124,7 +124,7 @@ - + 0 @@ -175,7 +175,7 @@ 0 0 258 - 21 + 27 @@ -199,6 +199,11 @@
gui/LogoBar.h
1 + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/NetworkDialog.cpp b/retroshare-gui/src/gui/NetworkDialog.cpp index 539e103fd..8db3e1e85 100644 --- a/retroshare-gui/src/gui/NetworkDialog.cpp +++ b/retroshare-gui/src/gui/NetworkDialog.cpp @@ -73,7 +73,7 @@ NetworkDialog::NetworkDialog(QWidget */*parent*/) PGPIdItemProxy = new pgpid_item_proxy(this); connect(ui.onlyTrustedKeys, SIGNAL(toggled(bool)), PGPIdItemProxy, SLOT(use_only_trusted_keys(bool))); PGPIdItemProxy->setSourceModel(PGPIdItemModel); - PGPIdItemProxy->setFilterKeyColumn(COLUMN_PEERNAME); + PGPIdItemProxy->setFilterKeyColumn(pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERNAME); PGPIdItemProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); PGPIdItemProxy->setSortRole(Qt::EditRole); //use edit role to get raw data since we do not have edit for this model. ui.connectTreeWidget->setModel(PGPIdItemProxy); @@ -90,9 +90,9 @@ NetworkDialog::NetworkDialog(QWidget */*parent*/) ui.onlyTrustedKeys->setMinimumWidth(20*f); /* add filter actions */ - ui.filterLineEdit->addFilter(QIcon(), tr("Name"), COLUMN_PEERNAME, tr("Search name")); - ui.filterLineEdit->addFilter(QIcon(), tr("Peer ID"), COLUMN_PEERID, tr("Search peer ID")); - ui.filterLineEdit->setCurrentFilter(COLUMN_PEERNAME); + ui.filterLineEdit->addFilter(QIcon(), tr("Name"), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERNAME, tr("Search name")); + ui.filterLineEdit->addFilter(QIcon(), tr("Peer ID"), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID, tr("Search peer ID")); + ui.filterLineEdit->setCurrentFilter(pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERNAME); connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), PGPIdItemProxy, SLOT(setFilterWildcard(QString))); } @@ -118,6 +118,7 @@ void NetworkDialog::connectTreeWidgetCostumPopupMenu( QPoint /*point*/ ) return; } QMenu *contextMnu = new QMenu; + contextMnu->addAction(QIcon(IMAGE_PEERDETAILS), tr("Profile details..."), this, SLOT(peerdetails())); contextMnu->addSeparator() ; contextMnu->addAction(QIcon(), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys())); @@ -165,6 +166,7 @@ void NetworkDialog::removeSelectedKeys() if(l.empty()) return; std::set selected; + std::set friends; for (int i = 0; i < l.size(); i++) { @@ -189,6 +191,7 @@ void NetworkDialog::removeSelectedKeys() } if(!selected.empty()) removeKeys(selected); + updateDisplay(); } @@ -236,7 +239,7 @@ void NetworkDialog::denyFriend() if(l.empty()) return; - RsPgpId peer_id(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()); + RsPgpId peer_id(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()); rsPeers->removeFriend(peer_id) ; securedUpdateDisplay(); @@ -249,7 +252,7 @@ void NetworkDialog::makeFriend() if(l.empty()) return; - PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails); + PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails); } /** Shows Peer Information/Auth Dialog */ @@ -259,7 +262,7 @@ void NetworkDialog::peerdetails() if(l.empty()) return; - PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails); + PGPKeyDialog::showIt(RsPgpId(ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()), PGPKeyDialog::PageDetails); } void NetworkDialog::copyLink() @@ -269,7 +272,7 @@ void NetworkDialog::copyLink() return; - RsPgpId peer_id (ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), COLUMN_PEERID)).toString().toStdString()) ; + RsPgpId peer_id (ui.connectTreeWidget->model()->data(ui.connectTreeWidget->model()->index(l.begin()->row(), pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID)).toString().toStdString()) ; QList urls; RetroShareLink link = RetroShareLink::createPerson(peer_id); diff --git a/retroshare-gui/src/gui/NetworkDialog.h b/retroshare-gui/src/gui/NetworkDialog.h index 6a5b1c367..216cd8cc5 100644 --- a/retroshare-gui/src/gui/NetworkDialog.h +++ b/retroshare-gui/src/gui/NetworkDialog.h @@ -43,6 +43,7 @@ class NetworkDialog : public RsAutoUpdatePage Q_PROPERTY(QColor backgroundColorAcceptConnection READ backgroundColorAcceptConnection WRITE setBackgroundColorAcceptConnection) Q_PROPERTY(QColor backgroundColorHasSignedMe READ backgroundColorHasSignedMe WRITE setBackgroundColorHasSignedMe) Q_PROPERTY(QColor backgroundColorDenied READ backgroundColorDenied WRITE setBackgroundColorDenied) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) public: /** Default Constructor */ @@ -55,12 +56,14 @@ public: QColor backgroundColorAcceptConnection() const { return mBackgroundColorAcceptConnection; } QColor backgroundColorHasSignedMe() const { return mBackgroundColorHasSignedMe; } QColor backgroundColorDenied() const { return mBackgroundColorDenied; } + QColor textColor() const { return mTextColor; } void setBackgroundColorSelf(QColor color) { PGPIdItemModel->setBackgroundColorSelf(color); mBackgroundColorSelf = color; } void setBackgroundColorOwnSign(QColor color) { PGPIdItemModel->setBackgroundColorOwnSign(color); mBackgroundColorOwnSign = color; } void setBackgroundColorAcceptConnection(QColor color) { PGPIdItemModel->setBackgroundColorAcceptConnection(color); mBackgroundColorAcceptConnection = color; } void setBackgroundColorHasSignedMe(QColor color) { PGPIdItemModel->setBackgroundColorHasSignedMe(color); mBackgroundColorHasSignedMe = color; } void setBackgroundColorDenied(QColor color) { PGPIdItemModel->setBackgroundColorDenied(color); mBackgroundColorDenied = color; } + void setTextColor(QColor color) { PGPIdItemModel->setTextColor(color); mTextColor = color; } protected: void changeEvent(QEvent *e); @@ -89,12 +92,13 @@ private: void removeKeys(std::set selected) ; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mBackgroundColorSelf; QColor mBackgroundColorOwnSign; QColor mBackgroundColorAcceptConnection; QColor mBackgroundColorHasSignedMe; QColor mBackgroundColorDenied; + QColor mTextColor; RSTreeWidgetItemCompareRole *compareNetworkRole ; diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp index 96ab24e92..016692092 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.cpp @@ -24,6 +24,9 @@ #include #include +#define IMAGE_AUTHED ":/images/accepted16.png" +#define IMAGE_DENIED ":/images/denied16.png" +#define IMAGE_TRUSTED ":/images/rs-2.png" /*TODO: * using list here for internal data storage is not best option @@ -41,22 +44,22 @@ QVariant pgpid_item_model::headerData(int section, Qt::Orientation orientation, { switch(section) { - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: return QString(tr(" Do you accept connections signed by this profile?")); break; - case COLUMN_PEERNAME: + case PGP_ITEM_MODEL_COLUMN_PEERNAME: return QString(tr("Name of the profile")); break; - case COLUMN_I_AUTH_PEER: + case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: return QString(tr("This column indicates the trust level you indicated and whether you signed the profile PGP key")); break; - case COLUMN_PEER_AUTH_ME: + case PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME: return QString(tr("Did that peer sign your own profile PGP key")); break; - case COLUMN_PEERID: + case PGP_ITEM_MODEL_COLUMN_PEERID: return QString(tr("PGP Key Id of that profile")); break; - case COLUMN_LAST_USED: + case PGP_ITEM_MODEL_COLUMN_LAST_USED: return QString(tr("Last time this key was used (received time, or to check connection)")); break; } @@ -65,22 +68,22 @@ QVariant pgpid_item_model::headerData(int section, Qt::Orientation orientation, { switch(section) { - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: return QString(tr("Connections")); break; - case COLUMN_PEERNAME: + case PGP_ITEM_MODEL_COLUMN_PEERNAME: return QString(tr("Profile")); break; - case COLUMN_I_AUTH_PEER: + case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: return QString(tr("Trust level")); break; - case COLUMN_PEER_AUTH_ME: + case PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME: return QString(tr("Has signed your key?")); break; - case COLUMN_PEERID: + case PGP_ITEM_MODEL_COLUMN_PEERID: return QString(tr("Id")); break; - case COLUMN_LAST_USED: + case PGP_ITEM_MODEL_COLUMN_LAST_USED: return QString(tr("Last used")); break; } @@ -98,13 +101,13 @@ QVariant pgpid_item_model::headerData(int section, Qt::Orientation orientation, { switch(section) { - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: return 25*font_height; break; - case COLUMN_PEERNAME: case COLUMN_I_AUTH_PEER: case COLUMN_PEER_AUTH_ME: + case PGP_ITEM_MODEL_COLUMN_PEERNAME: case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: case PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME: return 200*font_height; break; - case COLUMN_LAST_USED: + case PGP_ITEM_MODEL_COLUMN_LAST_USED: return 75*font_height; break; } @@ -122,7 +125,7 @@ int pgpid_item_model::rowCount(const QModelIndex &/*parent*/) const int pgpid_item_model::columnCount(const QModelIndex &/*parent*/) const { - return COLUMN_COUNT; + return PGP_ITEM_MODEL_COLUMN_COUNT; } @@ -148,20 +151,20 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const { switch(index.column()) { - case COLUMN_LAST_USED: + case PGP_ITEM_MODEL_COLUMN_LAST_USED: return detail.lastUsed; break; - case COLUMN_I_AUTH_PEER: + case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: { if (detail.ownsign) return RS_TRUST_LVL_ULTIMATE; return detail.trustLvl; } break; - case COLUMN_PEER_AUTH_ME: + case PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME: return detail.hasSignedMe; break; - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: return detail.accept_connection; break; default: @@ -174,13 +177,13 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const { switch(index.column()) { - case COLUMN_PEERNAME: + case PGP_ITEM_MODEL_COLUMN_PEERNAME: return QString::fromUtf8(detail.name.c_str()); break; - case COLUMN_PEERID: + case PGP_ITEM_MODEL_COLUMN_PEERID: return QString::fromStdString(detail.gpg_id.toStdString()); break; - case COLUMN_I_AUTH_PEER: + case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: { if (detail.ownsign) return tr("Personal signature"); @@ -199,7 +202,7 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const } } break; - case COLUMN_PEER_AUTH_ME: + case PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME: { if (detail.hasSignedMe) return tr("Yes"); @@ -207,7 +210,7 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const return tr("No"); } break; - case COLUMN_LAST_USED: + case PGP_ITEM_MODEL_COLUMN_LAST_USED: { time_t now = time(NULL); uint64_t last_time_used = now - detail.lastUsed ; @@ -226,7 +229,7 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const return lst_used_str; } break; - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: { if (detail.accept_connection || rsPeers->getGPGOwnId() == detail.gpg_id) return tr("Accepted"); @@ -242,7 +245,7 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const { switch(index.column()) { - case COLUMN_I_AUTH_PEER: + case PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER: { if (detail.ownsign) return tr("PGP key signed by you"); @@ -263,7 +266,7 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const { switch(index.column()) { - case COLUMN_CHECK: + case PGP_ITEM_MODEL_COLUMN_CHECK: { if (detail.accept_connection) return QIcon(IMAGE_AUTHED); @@ -299,6 +302,10 @@ QVariant pgpid_item_model::data(const QModelIndex &index, int role) const } } } + else if(role == Qt::ForegroundRole) + { + return QBrush(mTextColor); + } return QVariant(); } @@ -341,14 +348,14 @@ void pgpid_item_model::data_updated(std::list &new_neighs) break; if(*i1 != *i2) { - QModelIndex topLeft = createIndex(ii1,0), bottomRight = createIndex(ii1, COLUMN_COUNT-1); + QModelIndex topLeft = createIndex(ii1,0), bottomRight = createIndex(ii1, PGP_ITEM_MODEL_COLUMN_COUNT-1); emit dataChanged(topLeft, bottomRight); } } } if(new_size > old_size) { - QModelIndex topLeft = createIndex(old_size ? old_size -1 : 0 ,0), bottomRight = createIndex(new_size -1, COLUMN_COUNT-1); + QModelIndex topLeft = createIndex(old_size ? old_size -1 : 0 ,0), bottomRight = createIndex(new_size -1, PGP_ITEM_MODEL_COLUMN_COUNT-1); emit dataChanged(topLeft, bottomRight); } //dirty solution for initial data fetch diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h index 1e38e0461..7a17f48cb 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_model.h @@ -25,20 +25,6 @@ #include #include -#define IMAGE_AUTHED ":/images/accepted16.png" -#define IMAGE_DENIED ":/images/denied16.png" -#define IMAGE_TRUSTED ":/images/rs-2.png" - - -#define COLUMN_CHECK 0 -#define COLUMN_PEERNAME 1 -#define COLUMN_I_AUTH_PEER 2 -#define COLUMN_PEER_AUTH_ME 3 -#define COLUMN_PEERID 4 -#define COLUMN_LAST_USED 5 -#define COLUMN_COUNT 6 - - class pgpid_item_model : public QAbstractTableModel { Q_OBJECT @@ -60,7 +46,15 @@ public: void setBackgroundColorAcceptConnection(QColor color) { mBackgroundColorAcceptConnection = color; } void setBackgroundColorHasSignedMe(QColor color) { mBackgroundColorHasSignedMe = color; } void setBackgroundColorDenied(QColor color) { mBackgroundColorDenied = color; } + void setTextColor(QColor color) { mTextColor = color; } + static constexpr int PGP_ITEM_MODEL_COLUMN_CHECK = 0; + static constexpr int PGP_ITEM_MODEL_COLUMN_PEERNAME = 1; + static constexpr int PGP_ITEM_MODEL_COLUMN_I_AUTH_PEER = 2; + static constexpr int PGP_ITEM_MODEL_COLUMN_PEER_AUTH_ME = 3; + static constexpr int PGP_ITEM_MODEL_COLUMN_PEERID = 4; + static constexpr int PGP_ITEM_MODEL_COLUMN_LAST_USED = 5; + static constexpr int PGP_ITEM_MODEL_COLUMN_COUNT = 6; public slots: void data_updated(std::list &new_neighs); @@ -73,6 +67,7 @@ private: QColor mBackgroundColorAcceptConnection; QColor mBackgroundColorHasSignedMe; QColor mBackgroundColorDenied; + QColor mTextColor; }; #endif // KEY_ITEM_MODEL_H diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.cpp b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.cpp index 29acee273..e7b81ef2b 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.cpp +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.cpp @@ -26,17 +26,13 @@ #include #include - -//TODO: set this defines in one place -// Defines for key list columns -#define COLUMN_CHECK 0 -#define COLUMN_PEERNAME 1 -#define COLUMN_I_AUTH_PEER 2 -#define COLUMN_PEER_AUTH_ME 3 -#define COLUMN_PEERID 4 -#define COLUMN_LAST_USED 5 -#define COLUMN_COUNT 6 - +bool pgpid_item_proxy::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + if(left.column() == pgpid_item_model::PGP_ITEM_MODEL_COLUMN_LAST_USED) + return left.data(Qt::EditRole).toUInt() < right.data(Qt::EditRole).toUInt(); + else + return left.data(Qt::DisplayRole).toString().toUpper() < right.data(Qt::DisplayRole).toString().toUpper(); +} pgpid_item_proxy::pgpid_item_proxy(QObject *parent) : @@ -57,7 +53,7 @@ bool pgpid_item_proxy::filterAcceptsRow(int sourceRow, const QModelIndex &source { if(!rsPeers) return false; - RsPgpId peer_id (sourceModel()->data(sourceModel()->index(sourceRow, COLUMN_PEERID, sourceParent)).toString().toStdString()); + RsPgpId peer_id (sourceModel()->data(sourceModel()->index(sourceRow, pgpid_item_model::PGP_ITEM_MODEL_COLUMN_PEERID, sourceParent)).toString().toStdString()); RsPeerDetails details; if(!rsPeers->getGPGDetails(peer_id, details)) return false; diff --git a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.h b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.h index 0260b815d..5608862a2 100644 --- a/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.h +++ b/retroshare-gui/src/gui/NetworkDialog/pgpid_item_proxy.h @@ -34,14 +34,7 @@ class pgpid_item_proxy : public: pgpid_item_proxy(QObject *parent = nullptr); bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override - { - if(left.column() == COLUMN_LAST_USED) - return left.data(Qt::EditRole).toUInt() < right.data(Qt::EditRole).toUInt(); - else - return left.data(Qt::DisplayRole).toString().toUpper() < right.data(Qt::DisplayRole).toString().toUpper(); - } + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; public slots: void use_only_trusted_keys(bool val); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 4d552735e..c73f834fb 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -32,6 +32,7 @@ #include #include +#include "util/misc.h" #include "util/qtthreadsutils.h" #include "feeds/BoardsCommentsItem.h" #include "feeds/ChatMsgItem.h" @@ -83,7 +84,10 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), RsEventType::MAIL_STATUS }) { - for(uint32_t i=0;isetupUi(this); + + for(uint32_t i=0;iregisterEventsHandler( @@ -91,9 +95,6 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), mEventHandlerIds.back(), mEventTypes[i] ); } - /* Invoke the Qt Designer generated object setup routine */ - ui->setupUi(this); - if (!instance) { instance = this; } @@ -111,22 +112,23 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), connect(ui->feedOptionsButton, SIGNAL(clicked()), this, SLOT(feedoptions())); ui->feedOptionsButton->hide(); // (csoler) Hidden until we repare the system to display a specific settings page. -QString hlp_str = tr( - "

  Activity Feed

\ -

The Activity Feed displays the last events on your network, sorted by the time you received them. \ - This gives you a summary of the activity of your friends. \ - You can configure which events to show by pressing on Options.

\ -

The various events shown are: \ -

    \ -
  • Connection attempts (useful to make friends with new people and control who's trying to reach you)
  • \ -
  • Channel, Forum and Board posts
  • \ -
  • Circle membership requests and invites
  • \ -
  • New Channels, Forums and Boards you can subscribe to
  • \ -
  • Channel and Board comments
  • \ -
  • New Mail messages
  • \ -
  • Private messages from your friends
  • \ -

\ - ") ; + int H = misc::getFontSizeFactor("HelpButton").height(); + QString hlp_str = tr( + "

  Activity Feed

" + "

The Activity Feed displays the last events on your network, sorted by the time you received them." + " This gives you a summary of the activity of your friends." + " You can configure which events to show by pressing on Options.

" + "

The various events shown are:" + "

    " + "
  • Connection attempts (useful to make friends with new people and control who's trying to reach you)
  • " + "
  • Channel, Forum and Board posts
  • " + "
  • Circle membership requests and invites
  • " + "
  • New Channels, Forums and Boards you can subscribe to
  • " + "
  • Channel and Board comments
  • " + "
  • New Mail messages
  • " + "
  • Private messages from your friends
  • " + "

" + ).arg(QString::number(2*H)); registerHelpButton(ui->helpButton,hlp_str,"NewFeed") ; @@ -270,7 +272,10 @@ void NewsFeed::handleForumEvent(std::shared_ptr event) case RsForumEventCode::UPDATED_MESSAGE: case RsForumEventCode::NEW_MESSAGE: - addFeedItem(new GxsForumMsgItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, pe->mForumMsgId, false, true)); + addFeedItem(new GxsForumMsgItem( + this, NEWSFEED_NEW_FORUM, + pe->mForumGroupId, pe->mForumMsgId, + false, true )); break; default: break; @@ -436,6 +441,7 @@ void NewsFeed::handleConnectionEvent(std::shared_ptr event) { case RsConnectionEventCode::PEER_CONNECTED: addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_CONNECT, false), true); + NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT, e.mSslId.toStdString().c_str(), "", ""); break; case RsConnectionEventCode::PEER_DISCONNECTED: // not handled yet break; @@ -471,6 +477,7 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr event) addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_HELLO, false), true ); return; } + uint32_t FeedItemType=0; @@ -499,9 +506,11 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr event) if (Settings->getMessageFlags() & RS_MESSAGE_CONNECT_ATTEMPT) MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")")); + + NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT_ATTEMPT, e.mPgpId.toStdString().c_str(), det.location, e.mSslId.toStdString().c_str()); } -void NewsFeed::testFeeds(uint notifyFlags) +void NewsFeed::testFeeds(uint /*notifyFlags*/) { #ifdef TO_REMOVE if (!instance) { diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index 2e3d7e5ed..2b246fb4c 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -24,7 +24,6 @@ #include #include "gui/feeds/FeedHolder.h" -#include "util/TokenQueue.h" #include #define IMAGE_NEWSFEED ":/icons/png/newsfeed.png" diff --git a/retroshare-gui/src/gui/NewsFeed.ui b/retroshare-gui/src/gui/NewsFeed.ui index 1314c60c7..32a679a74 100644 --- a/retroshare-gui/src/gui/NewsFeed.ui +++ b/retroshare-gui/src/gui/NewsFeed.ui @@ -67,7 +67,14 @@
- + + + + 12 + 75 + true + + Activity Stream @@ -87,7 +94,7 @@ - + @@ -143,9 +150,9 @@ - StyledLabel - QLabel -
gui/common/StyledLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSFeedWidget diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index 2d1e7de4e..ef39eac4a 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -138,14 +138,14 @@
- + 0 1 - + 0 @@ -185,8 +185,8 @@ p, li { white-space: pre-wrap; } 0 0 - 757 - 395 + 741 + 316
diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui b/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui index 23b0a462f..ee8c173fc 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumExtra.ui @@ -28,7 +28,7 @@
- + 0 @@ -111,6 +111,13 @@
+ + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp index a28b500e5..fea04adbc 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumItem.cpp @@ -47,7 +47,7 @@ void AlbumItem::setUp() if(mAlbum.mThumbnail.mSize != 0) { QPixmap qtn; - qtn.loadFromData(mAlbum.mThumbnail.mData, mAlbum.mThumbnail.mSize, "PNG"); + qtn.loadFromData(mAlbum.mThumbnail.mData, mAlbum.mThumbnail.mSize, "JPG"); ui->label_Thumbnail->setPixmap(qtn); } else diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui index cf809286c..7be276b77 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.ui @@ -153,7 +153,7 @@
- + 50 % @@ -302,6 +302,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui index 19230a67f..e5476486f 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoShare.ui @@ -61,7 +61,7 @@ Edit Album Details - + :/images/edit_16.png:/images/edit_16.png @@ -186,6 +186,11 @@ + + + 12 + + My Albums @@ -212,6 +217,11 @@ + + + 12 + + Subscribed Albums @@ -238,6 +248,11 @@ + + + 12 + + Shared Albums @@ -286,7 +301,7 @@ 0 0 804 - 208 + 205 @@ -322,7 +337,7 @@ 0 0 804 - 208 + 205 diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui index b8509703e..03c5093ad 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui +++ b/retroshare-gui/src/gui/PhotoShare/PhotoSlideShow.ui @@ -24,6 +24,11 @@ 0 + + + 12 + + Album Name @@ -155,8 +160,6 @@ - - diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp index 7dc90eb82..541cecac0 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "rshare.h" #include "BoardPostDisplayWidget.h" @@ -43,6 +44,7 @@ #define LINK_IMAGE ":/images/thumb-link.png" + // #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET 1 /** Constructor */ @@ -58,6 +60,7 @@ BoardPostDisplayWidgetBase::BoardPostDisplayWidgetBase(const RsPostedPost& post, { } + void BoardPostDisplayWidgetBase::setCommentsSize(int comNb) { QString sComButText = tr("Comment"); @@ -108,28 +111,28 @@ void BoardPostDisplayWidgetBase::makeUpVote() void BoardPostDisplayWidgetBase::setReadStatus(bool isNew, bool isUnread) { if (isUnread) - readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); + readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); else - readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); + readButton()->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); - newLabel()->setVisible(isNew); + newLabel()->setVisible(isNew); - mainFrame()->setProperty("new", isNew); - mainFrame()->style()->unpolish(mainFrame()); - mainFrame()->style()->polish(mainFrame()); + feedFrame()->setProperty("new", isNew); + feedFrame()->style()->unpolish(feedFrame()); + feedFrame()->style()->polish( feedFrame()); } void BoardPostDisplayWidget_compact::doExpand(bool e) { #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET - std::cerr << "Expanding" << std::endl; + std::cerr << "Expanding" << std::endl; #endif - if(e) - ui->frame_notes->show(); - else - ui->frame_notes->hide(); + if(e) + ui->frame_notes->show(); + else + ui->frame_notes->hide(); - emit expand(mPost.mMeta.mMsgId,e); + emit expand(mPost.mMeta.mMsgId,e); } void BoardPostDisplayWidgetBase::loadComments(bool e) @@ -144,7 +147,7 @@ void BoardPostDisplayWidgetBase::readToggled() emit changeReadStatusRequested(mPost.mMeta.mMsgId,s); } -void BoardPostDisplayWidgetBase::setup() +void BoardPostDisplayWidgetBase::baseSetup() { // show/hide things based on the view type @@ -166,16 +169,17 @@ void BoardPostDisplayWidgetBase::setup() QAction *CopyLinkAction = new QAction(QIcon(""),tr("Copy RetroShare Link"), this); connect(CopyLinkAction, SIGNAL(triggered()), this, SLOT(handleCopyLinkClicked())); - int S = QFontMetricsF(font()).height() ; - readButton()->setChecked(false); +#ifdef TO_REMOVE QMenu *menu = new QMenu(); menu->addAction(CopyLinkAction); menu->addSeparator(); shareButton()->setMenu(menu); + shareButton()->setPopupMode(QToolButton::InstantPopup); - connect(shareButton(),SIGNAL(pressed()),this,SLOT(handleShareButtonClicked())); + connect(menu,SIGNAL(aboutToShow()),this,SLOT(handleShareButtonClicked())); +#endif RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId); bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE); @@ -183,6 +187,9 @@ void BoardPostDisplayWidgetBase::setup() if(redacted) { commentButton()->setDisabled(true); +#ifdef TO_REMOVE + shareButton()->setDisabled(true); +#endif voteUpButton()->setDisabled(true); voteDownButton()->setDisabled(true); fromLabel()->setId(mPost.mMeta.mAuthorId); @@ -195,8 +202,6 @@ void BoardPostDisplayWidgetBase::setup() } else { - QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); - QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy"); @@ -210,8 +215,6 @@ void BoardPostDisplayWidgetBase::setup() // The only combination that seems to work: load as EncodedUrl, extract toEncoded(). QByteArray urlarray(mPost.mLink.c_str()); QUrl url = QUrl::fromEncoded(urlarray.trimmed()); - QString urlstr = "Invalid Link"; - QString sitestr = "Invalid Link"; bool urlOkay = url.isValid(); if (urlOkay) @@ -223,25 +226,24 @@ void BoardPostDisplayWidgetBase::setup() && (scheme != "retroshare")) { urlOkay = false; - sitestr = "Invalid Link Scheme"; } } + ElidedLabel *label = titleLabel(); + label->setText( QString::fromUtf8(mPost.mMeta.mMsgName.c_str()) ); + if (urlOkay) { - urlstr = QString(" "); - urlstr += QString::fromUtf8(mPost.mMeta.mMsgName.c_str()); - urlstr += QString(" "); - QString siteurl = url.toEncoded(); - titleLabel()->setText(urlstr); - titleLabel()->setToolTip(siteurl); + label->setStyleSheet("text-decoration: underline; color:#2255AA;"); + label->setCursor(QCursor(Qt::PointingHandCursor)); + label->setToolTip(siteurl); + + connect(label, &ElidedLabel::clicked, this, [url] () { + QDesktopServices::openUrl(url); + }, Qt::QueuedConnection); } - else - titleLabel()->setText( QString::fromUtf8(mPost.mMeta.mMsgName.c_str()) ); } //QString score = "Hot" + QString::number(post.mHotScore); @@ -277,6 +279,7 @@ void BoardPostDisplayWidgetBase::setup() emit sizeChanged(this); #endif } +#ifdef TO_REMOVE void BoardPostDisplayWidgetBase::handleShareButtonClicked() { emit shareButtonClicked(); @@ -286,6 +289,8 @@ void BoardPostDisplayWidgetBase::handleCopyLinkClicked() { emit copylinkClicked(); } +#endif + //=================================================================================================================================== //== class BoardPostDisplayWidget == //=================================================================================================================================== @@ -293,17 +298,9 @@ void BoardPostDisplayWidgetBase::handleCopyLinkClicked() BoardPostDisplayWidget_compact::BoardPostDisplayWidget_compact(const RsPostedPost& post, uint8_t display_flags,QWidget *parent=nullptr) : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_compact()) { - ui->setupUi(this); - setup(); - - ui->verticalLayout->addStretch(); - ui->verticalLayout->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->verticalLayout_2->addStretch(); - - adjustSize(); + ui->setupUi(this); + ui->shareButton->hide(); + BoardPostDisplayWidget_compact::setup(); } BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact() @@ -313,7 +310,7 @@ BoardPostDisplayWidget_compact::~BoardPostDisplayWidget_compact() void BoardPostDisplayWidget_compact::setup() { - BoardPostDisplayWidgetBase::setup(); + baseSetup(); // show/hide things based on the view type @@ -341,7 +338,7 @@ void BoardPostDisplayWidget_compact::setup() #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET std::cerr << "Got pixmap of size " << pixmap.width() << " x " << pixmap.height() << std::endl; std::cerr << "Saving to pix.png" << std::endl; - pixmap.save("pix.png","PNG"); + pixmap.save("pix.png","JPG"); #endif ui->pictureLabel->setPicture(pixmap); @@ -355,7 +352,7 @@ void BoardPostDisplayWidget_compact::setup() QObject::connect(ui->expandButton, SIGNAL(toggled(bool)), this, SLOT(doExpand(bool))); QTextDocument doc; - doc.setHtml(notes()->text()); + doc.setHtml(BoardPostDisplayWidget_compact::notes()->text()); if(mDisplayFlags & SHOW_NOTES) { @@ -411,12 +408,12 @@ QLabel *BoardPostDisplayWidget_compact::newLabel() { return ui->ne QToolButton *BoardPostDisplayWidget_compact::readButton() { return ui->readButton; } GxsIdLabel *BoardPostDisplayWidget_compact::fromLabel() { return ui->fromLabel; } QLabel *BoardPostDisplayWidget_compact::dateLabel() { return ui->dateLabel; } -QLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; } +ElidedLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; } QLabel *BoardPostDisplayWidget_compact::scoreLabel() { return ui->scoreLabel; } QLabel *BoardPostDisplayWidget_compact::notes() { return ui->notes; } -QPushButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; } +//QToolButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; } QLabel *BoardPostDisplayWidget_compact::pictureLabel() { return ui->pictureLabel; } -QFrame *BoardPostDisplayWidget_compact::mainFrame() { return ui->mainFrame; } +QFrame *BoardPostDisplayWidget_compact::feedFrame() { return ui->feedFrame; } //=================================================================================================================================== //== class BoardPostDisplayWidget_card == @@ -425,17 +422,9 @@ QFrame *BoardPostDisplayWidget_compact::mainFrame() { return ui->ma BoardPostDisplayWidget_card::BoardPostDisplayWidget_card(const RsPostedPost& post, uint8_t display_flags, QWidget *parent) : BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_card()) { - ui->setupUi(this); - setup(); - - ui->verticalLayout->addStretch(); - ui->verticalLayout->setAlignment(Qt::AlignTop); - ui->topLayout->setAlignment(Qt::AlignTop); - ui->arrowsLayout->addStretch(); - ui->arrowsLayout->setAlignment(Qt::AlignTop); - ui->verticalLayout_2->addStretch(); - - adjustSize(); + ui->setupUi(this); + ui->shareButton->hide(); + BoardPostDisplayWidget_card::setup(); } BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card() @@ -445,7 +434,7 @@ BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card() void BoardPostDisplayWidget_card::setup() { - BoardPostDisplayWidgetBase::setup(); + baseSetup(); RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId); bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE); @@ -462,7 +451,6 @@ void BoardPostDisplayWidget_card::setup() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap scaledpixmap; if(pixmap.width() > 800){ QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); ui->pictureLabel->setPixmap(scaledpixmap); @@ -477,10 +465,10 @@ void BoardPostDisplayWidget_card::setup() } QTextDocument doc; - doc.setHtml(notes()->text()); + doc.setHtml(BoardPostDisplayWidget_card::notes()->text()); if(doc.toPlainText().trimmed().isEmpty()) - notes()->hide(); + BoardPostDisplayWidget_card::notes()->hide(); } QToolButton *BoardPostDisplayWidget_card::voteUpButton() { return ui->voteUpButton; } @@ -490,10 +478,10 @@ QLabel *BoardPostDisplayWidget_card::newLabel() { return ui->newLa QToolButton *BoardPostDisplayWidget_card::readButton() { return ui->readButton; } GxsIdLabel *BoardPostDisplayWidget_card::fromLabel() { return ui->fromLabel; } QLabel *BoardPostDisplayWidget_card::dateLabel() { return ui->dateLabel; } -QLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; } +ElidedLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; } QLabel *BoardPostDisplayWidget_card::scoreLabel() { return ui->scoreLabel; } QLabel *BoardPostDisplayWidget_card::notes() { return ui->notes; } -QPushButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; } +//QToolButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; } QLabel *BoardPostDisplayWidget_card::pictureLabel() { return ui->pictureLabel; } -QFrame *BoardPostDisplayWidget_card::mainFrame() { return ui->mainFrame; } +QFrame *BoardPostDisplayWidget_card::feedFrame() { return ui->feedFrame; } diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h index 32ce60a2a..731ddc9da 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h @@ -37,6 +37,7 @@ class QToolButton; class QTextEdit; class ClickableLabel; class GxsIdLabel; +class ElidedLabel; struct RsPostedPost; @@ -62,34 +63,37 @@ public: static const char *DEFAULT_BOARD_IMAGE; -protected slots: +protected: /* GxsGroupFeedItem */ - virtual void setup(); // to be overloaded by the different views + void baseSetup(); + virtual void setup() =0; // to be overloaded by the different views virtual QToolButton *voteUpButton() =0; virtual QToolButton *commentButton() =0; virtual QToolButton *voteDownButton() =0; virtual QLabel *newLabel() =0; - virtual QLabel *titleLabel()=0; + virtual ElidedLabel *titleLabel()=0; virtual GxsIdLabel *fromLabel()=0; virtual QLabel *dateLabel()=0; virtual QLabel *scoreLabel() =0; virtual QLabel *notes() =0; virtual QLabel *pictureLabel()=0; virtual QToolButton *readButton() =0; - virtual QPushButton *shareButton() =0; - virtual QFrame *mainFrame() =0; +// virtual QToolButton *shareButton() =0; + virtual QFrame *feedFrame() =0; +protected slots: void loadComments(bool e); void readToggled(); void setReadStatus(bool isNew, bool isUnread) ; void makeUpVote() ; void makeDownVote() ; void setCommentsSize(int comNb) ; +#ifdef TO_REMOVE void handleShareButtonClicked() ; void handleCopyLinkClicked() ; - +#endif signals: void changeReadStatusRequested(const RsGxsMessageId&,bool); @@ -97,8 +101,8 @@ signals: void expand(RsGxsMessageId,bool); void commentsRequested(const RsGxsMessageId&,bool); void thumbnailOpenned(); - void shareButtonClicked(); - void copylinkClicked(); +// void shareButtonClicked(); +// void copylinkClicked(); protected: RsPostedPost mPost; @@ -121,13 +125,15 @@ public: QLabel *newLabel() override; GxsIdLabel *fromLabel() override; QLabel *dateLabel() override; - QLabel *titleLabel() override; + ElidedLabel *titleLabel() override; QLabel *scoreLabel() override; QLabel *notes() override; QLabel *pictureLabel() override; QToolButton *readButton() override; - QPushButton *shareButton() override; - QFrame *mainFrame() override; +#ifdef TO_REMOVE + QToolButton *shareButton() override; +#endif + QFrame *feedFrame() override; public slots: void viewPicture() ; @@ -160,13 +166,13 @@ public: QLabel *newLabel() override; GxsIdLabel *fromLabel() override; QLabel *dateLabel() override; - QLabel *titleLabel() override; + ElidedLabel *titleLabel() override; QLabel *scoreLabel() override; QLabel *notes() override; QToolButton *readButton() override; - QPushButton *shareButton() override; +// QToolButton *shareButton() override; QLabel *pictureLabel() override; - QFrame *mainFrame() override; + QFrame *feedFrame() override; protected slots: /* GxsGroupFeedItem */ diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui index 42dc90f44..553577fb8 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_card.ui @@ -22,7 +22,7 @@ - + 0 @@ -42,7 +42,7 @@ 2 - + 0 @@ -55,7 +55,7 @@ QFrame::Raised - + 2 @@ -90,7 +90,10 @@ - + + + 0 + 0 @@ -127,10 +130,10 @@ - + - 9 + 14 @@ -173,13 +176,20 @@ + + + + Qt::Vertical + + +
- + - + 5 @@ -199,8 +209,8 @@ - 50 - false + 75 + true @@ -277,7 +287,7 @@ - + Qt::Horizontal @@ -295,7 +305,7 @@ - + 0 @@ -304,9 +314,9 @@ - Arial - 10 + 12 75 + true true @@ -340,7 +350,7 @@ - + Qt::Horizontal @@ -371,7 +381,7 @@ - + @@ -393,7 +403,7 @@ - + Share @@ -401,13 +411,16 @@ :/images/share.png:/images/share.png - + + Qt::ToolButtonTextBesideIcon + + true - + Qt::Horizontal @@ -421,30 +434,51 @@ + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + + ElidedLabel + QLabel +
gui/common/ElidedLabel.h
+ 1 +
GxsIdLabel QLabel
gui/gxs/GxsIdLabel.h
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- + diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui index 411d4583e..5e920cfed 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget_compact.ui @@ -7,7 +7,7 @@ 0 0 542 - 150 + 151 @@ -22,7 +22,7 @@ - + 0 @@ -42,7 +42,7 @@ 2 - + 0 @@ -55,7 +55,7 @@ QFrame::Raised - + 2 @@ -89,78 +89,102 @@ 2 - - - - - - 0 - 0 - - - - Vote up - - - - - - - :/images/up-arrow.png:/images/up-arrow.png - - - true - - - - - - - - 9 - - - - 0 - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Vote down - - - - - - \/ - - - - :/images/down-arrow.png:/images/down-arrow.png - - - true - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Vote up + + + + + + + :/images/up-arrow.png:/images/up-arrow.png + + + true + + + + + + + + 14 + + + + 0 + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Vote down + + + + + + \/ + + + + :/images/down-arrow.png:/images/down-arrow.png + + + true + + + + + + + Qt::Vertical + + + + + @@ -182,12 +206,12 @@ - + 3 - + 0 @@ -196,9 +220,9 @@ - Arial - 10 + 12 75 + true true @@ -220,7 +244,7 @@ - + 6 @@ -243,8 +267,8 @@ - 50 - false + 75 + true @@ -285,7 +309,7 @@ - + Qt::Horizontal @@ -303,7 +327,7 @@ - + @@ -345,7 +369,7 @@ - + Share @@ -353,7 +377,10 @@ :/images/share.png:/images/share.png - + + Qt::ToolButtonTextBesideIcon + + true @@ -395,7 +422,7 @@ - + Qt::Horizontal @@ -409,6 +436,13 @@ + + + + Qt::Vertical + + + @@ -421,7 +455,7 @@ QFrame::Raised - + 2 @@ -468,6 +502,13 @@ + + + + Qt::Vertical + + + @@ -475,9 +516,10 @@ - StyledLabel + ElidedLabel QLabel -
gui/common/StyledLabel.h
+
gui/common/ElidedLabel.h
+ 1
GxsIdLabel diff --git a/retroshare-gui/src/gui/Posted/PhotoView.ui b/retroshare-gui/src/gui/Posted/PhotoView.ui index e0d4dce64..e1e7a21e5 100644 --- a/retroshare-gui/src/gui/Posted/PhotoView.ui +++ b/retroshare-gui/src/gui/Posted/PhotoView.ui @@ -24,6 +24,7 @@ MS Sans Serif 11 75 + true true @@ -36,14 +37,14 @@ - + 0 0 - + 0 @@ -133,7 +134,10 @@ MS Sans Serif - 9 + 11 + 75 + true + true diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.cpp b/retroshare-gui/src/gui/Posted/PostedCardView.cpp index b7ead3c0b..9824cfda2 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCardView.cpp @@ -104,12 +104,12 @@ void PostedCardView::setReadStatus(bool isNew, bool isUnread) ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } -void PostedCardView::setComment(const RsGxsComment& cmt) {} +void PostedCardView::setComment(const RsGxsComment& /*cmt*/) {} PostedCardView::~PostedCardView() { @@ -192,11 +192,11 @@ void PostedCardView::fill() ui->dateLabel->setText(timestamp); } else { - QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); + //QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); mInFill = true; - int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); - int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); + //int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); + //int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); @@ -211,7 +211,6 @@ void PostedCardView::fill() // The only combination that seems to work: load as EncodedUrl, extract toEncoded(). QByteArray urlarray(mPost.mLink.c_str()); QUrl url = QUrl::fromEncoded(urlarray.trimmed()); - QString urlstr = "Invalid Link"; QString sitestr = "Invalid Link"; bool urlOkay = url.isValid(); @@ -230,7 +229,7 @@ void PostedCardView::fill() if (urlOkay) { - urlstr = QString(" "); urlstr += messageName(); @@ -259,7 +258,6 @@ void PostedCardView::fill() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap scaledpixmap; if(pixmap.width() > 800){ QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); ui->pictureLabel->setPixmap(scaledpixmap); @@ -267,14 +265,14 @@ void PostedCardView::fill() ui->pictureLabel->setPixmap(pixmap); } } - else if (mPost.mImage.mData == NULL) + else //if (mPost.mImage.mData == NULL) { ui->picture_frame->hide(); } - else - { - ui->picture_frame->show(); - } + //else + //{ + // ui->picture_frame->show(); + //} } //QString score = "Hot" + QString::number(post.mHotScore); diff --git a/retroshare-gui/src/gui/Posted/PostedCardView.ui b/retroshare-gui/src/gui/Posted/PostedCardView.ui index 8cbbd4d56..dba517263 100644 --- a/retroshare-gui/src/gui/Posted/PostedCardView.ui +++ b/retroshare-gui/src/gui/Posted/PostedCardView.ui @@ -7,7 +7,7 @@ 0 0 614 - 182 + 198 @@ -16,7 +16,7 @@ - + 0 @@ -33,7 +33,7 @@ 0 - + 0 @@ -49,7 +49,7 @@ QFrame::Sunken - + 0 @@ -69,7 +69,7 @@ 6 - + 0 @@ -78,9 +78,9 @@ - Arial - 10 + 11 75 + true true @@ -118,7 +118,7 @@ - + 5 @@ -216,7 +216,7 @@ - + Qt::Horizontal @@ -241,30 +241,27 @@ 0 - - - QFrame::NoFrame QFrame::Plain - + 0 - 3 + 0 - 3 + 0 - 3 + 0 - 3 + 0 @@ -290,10 +287,10 @@ - + - 9 + 14 @@ -337,26 +334,20 @@ - + Qt::Vertical QSizePolicy::Expanding - - - 20 - 5 - - - + @@ -389,7 +380,7 @@ - + Qt::Horizontal @@ -461,7 +452,7 @@ - + 0 @@ -485,7 +476,7 @@ - + Qt::Horizontal @@ -506,11 +497,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
GxsIdLabel QLabel @@ -519,8 +505,8 @@
- + diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 6bbfa3e37..bfccd3fc7 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -19,6 +19,7 @@ *******************************************************************************/ #include +#include #include #include #include @@ -28,6 +29,7 @@ #include "ui_PostedCreatePostDialog.h" #include "util/misc.h" +#include "util/qtthreadsutils.h" #include "util/RichTextEdit.h" #include "gui/feeds/SubFileItem.h" #include "util/rsdir.h" @@ -41,9 +43,14 @@ #include "gui/common/FilesDefs.h" /* View Page */ -#define VIEW_POST 1 -#define VIEW_IMAGE 2 -#define VIEW_LINK 3 +#define VIEW_POST 0 +#define VIEW_IMAGE 1 +#define VIEW_LINK 2 +/* View Image */ +#define IMG_ATTACH 0 +#define IMG_PICTURE 1 + +const int MAXMESSAGESIZE = 199000; PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGroupId& grpId, const RsGxsId& default_author, QWidget *parent): QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), @@ -53,10 +60,10 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou ui->setupUi(this); Settings->loadWidgetInformation(this); - connect(ui->submitButton, SIGNAL(clicked()), this, SLOT(createPost())); - connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createPost())); connect(ui->addPicButton, SIGNAL(clicked() ), this , SLOT(addPicture())); - connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->submitButton, SLOT(setEnabled(bool))); + connect(ui->pasteButton, SIGNAL(clicked() ), this , SLOT(pastePicture())); + connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->postButton, SLOT(setEnabled(bool))); ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/postedlinks.png")); ui->headerFrame->setHeaderText(tr("Create a new Post")); @@ -74,16 +81,17 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, default_author); QSignalMapper *signalMapper = new QSignalMapper(this); - connect(ui->postButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - connect(ui->imageButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - connect(ui->linkButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewPostButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewImageButton, SIGNAL(clicked()), signalMapper, SLOT(map())); + connect(ui->viewLinkButton, SIGNAL(clicked()), signalMapper, SLOT(map())); - signalMapper->setMapping(ui->postButton, VIEW_POST); - signalMapper->setMapping(ui->imageButton, VIEW_IMAGE); - signalMapper->setMapping(ui->linkButton, VIEW_LINK); + signalMapper->setMapping(ui->viewPostButton, VIEW_POST); + signalMapper->setMapping(ui->viewImageButton, VIEW_IMAGE); + signalMapper->setMapping(ui->viewLinkButton, VIEW_LINK); connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setPage(int))); ui->removeButton->hide(); + ui->stackedWidgetPicture->setCurrentIndex(IMG_ATTACH); /* load settings */ processSettings(true); @@ -175,10 +183,20 @@ void PostedCreatePostDialog::createPost() return; } - uint32_t token; - mPosted->createPost(token, post); + RsThread::async([this,post]() + { + RsGxsMessageId post_id; - accept(); + bool res = rsPosted->createPost(post,post_id); + + RsQThreadUtils::postToObject( [res,this]() + { + if(!res) + QMessageBox::information(nullptr,tr("Error while creating post"),tr("An error occurred while creating the post.")); + + accept(); + }, this ); + }); } void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) @@ -189,7 +207,7 @@ void PostedCreatePostDialog::fileHashingFinished(QList hashedFiles) link = RetroShareLink::createFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString())); ui->linkEdit->setText(link.toString()); } - ui->submitButton->setEnabled(true); + ui->postButton->setEnabled(true); ui->addPicButton->setEnabled(true); } @@ -202,7 +220,6 @@ void PostedCreatePostDialog::addPicture() // select a picture file if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", imagefilename)) { - QString encodedImage; QImage image; if (image.load(imagefilename) == false) { fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", imagefilename.toLatin1().constData()); @@ -211,9 +228,9 @@ void PostedCreatePostDialog::addPicture() } QImage opt; - if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt, 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff + if (optimizeImage(image, imagebytes, opt)) { ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); - ui->stackedWidgetPicture->setCurrentIndex(1); + ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); ui->removeButton->show(); } else { imagefilename = ""; @@ -233,7 +250,7 @@ void PostedCreatePostDialog::addPicture() //If still yes then link it if(answer == QMessageBox::Yes) { - ui->submitButton->setEnabled(false); + ui->postButton->setEnabled(false); ui->addPicButton->setEnabled(false); QStringList files; files.append(imagefilename); @@ -243,13 +260,48 @@ void PostedCreatePostDialog::addPicture() } +void PostedCreatePostDialog::pastePicture() +{ + imagefilename = ""; + imagebytes.clear(); + QPixmap empty; + ui->imageLabel->setPixmap(empty); + + // paste picture from clipboard + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); + + QImage image; + if (mimeData->hasImage()) { + image = (qvariant_cast(mimeData->imageData())); + + QImage opt; + if (optimizeImage(image, imagebytes, opt)) { + ui->imageLabel->setPixmap(QPixmap::fromImage(opt)); + ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE); + ui->removeButton->show(); + } + } else { + QMessageBox::information(nullptr,tr("No clipboard image found."),tr("There is no image data in the clipboard to paste")); + imagefilename = ""; + imagebytes.clear(); + return; + } +} + +bool PostedCreatePostDialog::optimizeImage(const QImage &image, QByteArray &imagebytes, QImage &imageOpt) +{ + // Leave space for other stuff + return ImageUtil::optimizeSizeBytes(imagebytes, image, imageOpt, "JPG", 640*480, MAXMESSAGESIZE - 2000); +} + int PostedCreatePostDialog::viewMode() { - if (ui->postButton->isChecked()) { + if (ui->viewPostButton->isChecked()) { return VIEW_POST; - } else if (ui->imageButton->isChecked()) { + } else if (ui->viewImageButton->isChecked()) { return VIEW_IMAGE; - } else if (ui->linkButton->isChecked()) { + } else if (ui->viewLinkButton->isChecked()) { return VIEW_LINK; } @@ -259,45 +311,24 @@ int PostedCreatePostDialog::viewMode() void PostedCreatePostDialog::setPage(int viewMode) { - switch (viewMode) { - case VIEW_POST: - ui->stackedWidget->setCurrentIndex(0); + if( (viewMode < 0) || (viewMode > ui->stackedWidget->count()-1) ) + viewMode = VIEW_POST; - ui->postButton->setChecked(true); - ui->imageButton->setChecked(false); - ui->linkButton->setChecked(false); + ui->stackedWidget->setCurrentIndex(viewMode); - break; - case VIEW_IMAGE: - ui->stackedWidget->setCurrentIndex(1); + ui->viewPostButton ->setChecked(viewMode==VIEW_POST); + ui->viewImageButton->setChecked(viewMode==VIEW_IMAGE); + ui->viewLinkButton ->setChecked(viewMode==VIEW_LINK); - ui->imageButton->setChecked(true); - ui->postButton->setChecked(false); - ui->linkButton->setChecked(false); - - break; - case VIEW_LINK: - ui->stackedWidget->setCurrentIndex(2); - - ui->linkButton->setChecked(true); - ui->postButton->setChecked(false); - ui->imageButton->setChecked(false); - - break; - default: - setPage(VIEW_POST); - return; - } } void PostedCreatePostDialog::on_removeButton_clicked() { imagefilename = ""; imagebytes.clear(); - QPixmap empty; - ui->imageLabel->setPixmap(empty); + ui->imageLabel->setPixmap(QPixmap()); ui->removeButton->hide(); - ui->stackedWidgetPicture->setCurrentIndex(0); + ui->stackedWidgetPicture->setCurrentIndex(IMG_ATTACH); } void PostedCreatePostDialog::reject() @@ -307,3 +338,18 @@ void PostedCreatePostDialog::reject() QDialog::reject(); } + +void PostedCreatePostDialog::setTitle(const QString& title) +{ + ui->titleEdit->setText(title); +} + +void PostedCreatePostDialog::setNotes(const QString& notes) +{ + ui->RichTextEditWidget->setText(notes); +} + +void PostedCreatePostDialog::setLink(const QString& link) +{ + ui->linkEdit->setText(link); +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index a62fe46c6..5ac2c2e7d 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -24,7 +24,6 @@ #include #include #include "retroshare/rsposted.h" -#include "util/RichTextEdit.h" namespace Ui { class PostedCreatePostDialog; @@ -42,17 +41,23 @@ public: explicit PostedCreatePostDialog(RsPosted* posted, const RsGxsGroupId& grpId, const RsGxsId& default_author=RsGxsId(),QWidget *parent = 0); ~PostedCreatePostDialog(); + void setTitle(const QString& title); + void setNotes(const QString& notes); + void setLink(const QString& link); + + static bool optimizeImage(const QImage &image, QByteArray &imagebytes, QImage &imageOpt); + private: QString imagefilename; QByteArray imagebytes; - const int MAXMESSAGESIZE = 199000; private slots: void createPost(); void addPicture(); + void pastePicture(); void on_removeButton_clicked(); void fileHashingFinished(QList hashedFiles); - void reject(); + void reject() override; //QDialog void setPage(int viewMode); private: diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index bd44c4d0a..2a19f02d8 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -7,7 +7,7 @@ 0 0 575 - 518 + 468 @@ -40,21 +40,21 @@
- + QFrame::StyledPanel QFrame::Raised - + 0 - + 0 @@ -73,7 +73,7 @@ - + 0 @@ -104,7 +104,7 @@ Preview - + 0 @@ -115,7 +115,7 @@ 0 - + Qt::Horizontal @@ -128,7 +128,7 @@ - + Qt::Horizontal @@ -146,14 +146,14 @@ 0 - + - + 9 - - + + Qt::Horizontal @@ -182,15 +182,8 @@ - - - - Post size is limited to 32 KB, pictures will be downscaled. - - - - - + + Qt::Horizontal @@ -203,7 +196,14 @@ - + + + Post size is limited to 32 KB, pictures will be downscaled. + + + + + Qt::Vertical @@ -215,17 +215,37 @@ + + + + Paste image from clipboard + + + Paste Picture + + + + :/icons/svg/paste_image.svg:/icons/svg/paste_image.svg + + + + 32 + 32 + + + + - + Qt::Horizontal 267 - 138 + 20 @@ -233,7 +253,7 @@ - + 2 @@ -267,7 +287,7 @@ - + Qt::Horizontal @@ -305,7 +325,7 @@ - + 0 @@ -323,7 +343,7 @@ - + Qt::Vertical @@ -340,7 +360,7 @@ - + @@ -367,13 +387,20 @@ - + 0 0 + + + 12 + 75 + true + + @@ -399,12 +426,12 @@ - + 2 - + Post @@ -424,7 +451,7 @@ - + Image @@ -450,7 +477,7 @@ - + Link @@ -473,7 +500,7 @@ - + Qt::Horizontal @@ -488,10 +515,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -512,6 +548,15 @@ + + + + 0 + 0 + 0 + + + @@ -532,6 +577,15 @@ + + + + 154 + 154 + 154 + + + @@ -553,6 +607,11 @@ + + + 12 + + true @@ -584,7 +643,7 @@ - + 6 @@ -613,15 +672,9 @@ - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - HashBox - QScrollArea -
gui/common/HashBox.h
- 1 + GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
HeaderFrame @@ -629,21 +682,22 @@
gui/common/HeaderFrame.h
1
- - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
-
RichTextEdit QWidget
util/RichTextEdit.h
1
+ + HashBox + QScrollArea +
gui/common/HashBox.h
+ 1 +
- + diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index 1364cf2d7..733878810 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -26,6 +26,7 @@ #include "gui/gxs/GxsGroupShareKey.h" #include "gui/settings/rsharesettings.h" #include "gui/common/GroupTreeWidget.h" +#include "util/misc.h" #include "util/qtthreadsutils.h" #include @@ -42,7 +43,7 @@ public: /** Constructor */ PostedDialog::PostedDialog(QWidget *parent): - GxsGroupFrameDialog(rsPosted, parent), mEventHandlerId(0) + GxsGroupFrameDialog(rsPosted, settingsGroupName(),parent), mEventHandlerId(0) { // Needs to be asynced because this function is likely to be called by another thread! rsEvents->registerEventsHandler( @@ -95,14 +96,19 @@ UserNotify *PostedDialog::createUserNotify(QObject *parent) QString PostedDialog::getHelpString() const { - QString hlp_str = tr("

  Boards

\ -

The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and \ - channels

\ -

Posts can be commented by subscribed users. A promotion system also gives the opportunity to \ - enlight important links.

\ -

There is no restriction on which links are shared. Be careful when clicking on them.

\ -

Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.

\ - ").arg(QString::number(rsPosted->getDefaultStoragePeriod()/86400)).arg(QString::number(rsPosted->getDefaultSyncPeriod()/86400)); + int H = misc::getFontSizeFactor("HelpButton").height(); + + QString hlp_str = tr( + "

  Boards

" + "

The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and" + " channels

" + "

Posts can be commented by subscribed users. A promotion system also gives the opportunity to" + " enlight important links.

" + "

There is no restriction on which links are shared. Be careful when clicking on them.

" + "

Boards are kept for %2 days, and sync-ed over the last %3 days, unless you change this.

" + ).arg( QString::number(2*H) + , QString::number(rsPosted->getDefaultStoragePeriod()/86400) + , QString::number(rsPosted->getDefaultSyncPeriod()/86400)); return hlp_str ; } @@ -192,7 +198,8 @@ GxsGroupDialog *PostedDialog::createGroupDialog(GxsGroupDialog::Mode mode, RsGxs int PostedDialog::shareKeyType() { - return POSTED_KEY_SHARE; + //return POSTED_KEY_SHARE; + return GroupShareKey::NO_KEY_SHARE; // Boards are public. By the time we offer the possibility to make them restricted, we need to not show the 'share publish permission' entry in the drop menu. } GxsMessageFrameWidget *PostedDialog::createMessageFrameWidget(const RsGxsGroupId &groupId) @@ -210,34 +217,6 @@ QWidget *PostedDialog::createCommentHeaderWidget(const RsGxsGroupId &grpId, cons return new PostedItem(NULL, 0, grpId, msgId, true, false); } -#ifdef TO_REMOVE -void PostedDialog::loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata *&userdata) -{ - std::vector groups; - rsPosted->getGroupData(token, groups); - - /* Save groups to fill description */ - PostedGroupInfoData *postedData = new PostedGroupInfoData; - userdata = postedData; - - std::vector::iterator groupIt; - for (groupIt = groups.begin(); groupIt != groups.end(); ++groupIt) { - RsPostedGroup &group = *groupIt; - groupInfo.push_back(group.mMeta); - - if (group.mGroupImage.mData != NULL) { - QPixmap image; - GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, image,GxsIdDetails::ORIGINAL); - postedData->mIcon[group.mMeta.mGroupId] = image; - } - - if (!group.mDescription.empty()) { - postedData->mDescription[group.mMeta.mGroupId] = QString::fromUtf8(group.mDescription.c_str()); - } - } -} -#endif - void PostedDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) { GxsGroupFrameDialog::groupInfoToGroupItemInfo(groupData, groupItemInfo); diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index c516f7520..f2b011adb 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -22,8 +22,9 @@ #include "PostedGroupDialog.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/common/FilesDefs.h" +#include "util/imageutil.h" -#include +#include "retroshare/rswiki.h" #include const uint32_t PostedCreateEnabledFlags = ( @@ -104,8 +105,10 @@ void PostedGroupDialog::preparePostedGroup(RsPostedGroup &group, const RsGroupMe QByteArray ba; QBuffer buffer(&ba); - buffer.open(QIODevice::WriteOnly); - pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format + bool has_transparency = ImageUtil::hasAlphaContent(pixmap.toImage()); + + buffer.open(QIODevice::WriteOnly); + pixmap.save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format group.mGroupImage.copy((uint8_t *) ba.data(), ba.size()); } else { @@ -136,7 +139,7 @@ bool PostedGroupDialog::service_updateGroup(const RsGroupMetaData& editedMeta) return rsPosted->editBoard(grp); } -bool PostedGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, Mode mode, QString& description) +bool PostedGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, Mode /*mode*/, QString& description) { const RsPostedGroup *pgroup = dynamic_cast(data); diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index fa79b9d70..8f1cddf7d 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -74,7 +74,7 @@ BasePostedItem::BasePostedItem( FeedHolder *feedHolder, uint32_t feedId BasePostedItem::~BasePostedItem() { - auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200); + auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200); while( (mIsLoadingGroup || mIsLoadingMessage || mIsLoadingComment) && std::chrono::steady_clock::now() < timeout) { @@ -279,16 +279,16 @@ void BasePostedItem::loadComments() } void BasePostedItem::readToggled(bool checked) { - if (mInFill) { - return; - } + if (mInFill) { + return; + } + setReadStatus(false, checked); - RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); - - uint32_t token; - rsPosted->setMessageReadStatus(token, msgPair, !checked); - - setReadStatus(false, checked); + RsThread::async([this,checked]() + { + RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + rsPosted->setPostReadStatus(msgPair, !checked); + }); } void BasePostedItem::readAndClearItem() @@ -495,7 +495,7 @@ void PostedItem::fill() ui->voteUpButton->setDisabled(true); ui->voteDownButton->setDisabled(true); - ui->thumbnailLabel->setPixmap( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png")); + ui->thumbnailLabel->setPicture( FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png")); ui->fromLabel->setId(mPost.mMeta.mAuthorId); ui->titleLabel->setText(tr( "

The author of this message (with ID %1) is banned.").arg(QString::fromStdString(mPost.mMeta.mAuthorId.toStdString()))) ; QDateTime qtime; @@ -509,8 +509,10 @@ void PostedItem::fill() QPixmap sqpixmap2 = FilesDefs::getPixmapFromQtResourcePath(":/images/thumb-default.png"); mInFill = true; - int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); - int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); + int desired_height = ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height(); + int desired_width = 16/9.0 * desired_height; //sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); + + ui->thumbnailLabel->setFixedSize(desired_width,desired_height); QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); @@ -573,17 +575,17 @@ void PostedItem::fill() GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); // Wiping data - as its been passed to thumbnail. - QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - ui->thumbnailLabel->setPixmap(sqpixmap); +// QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + ui->thumbnailLabel->setPicture(pixmap); ui->thumbnailLabel->setToolTip(tr("Click to view Picture")); + ui->thumbnailLabel->setEnableZoom(false); - QPixmap scaledpixmap; - if(pixmap.width() > 800){ - QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); - ui->pictureLabel->setPixmap(scaledpixmap); - }else{ - ui->pictureLabel->setPixmap(pixmap); - } + QPixmap scaledpixmap; + if(pixmap.width() > 800){ + QPixmap scaledpixmap = pixmap.scaledToWidth(800, Qt::SmoothTransformation); + ui->pictureLabel->setPixmap(scaledpixmap); + }else + ui->pictureLabel->setPixmap(pixmap); } else if (urlOkay && (mPost.mImage.mData == NULL)) { @@ -705,9 +707,9 @@ void PostedItem::setReadStatus(bool isNew, bool isUnread) //ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index d726cf830..a2f432dc0 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -112,11 +112,11 @@ protected: void setCommentsSize(int comNb) override; private slots: - void doExpand(bool open); - void toggle(); - void makeUpVote(); - void makeDownVote(); - void toggleNotes() ; + void doExpand(bool open) override; + void toggle() override; + void makeUpVote() override; + void makeDownVote() override; + void toggleNotes() override; private: /** Qt Designer generated object */ diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index f16c7b100..24d570b16 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -16,7 +16,7 @@ - + 1 @@ -33,7 +33,7 @@ 0 - + 0 @@ -49,7 +49,7 @@ QFrame::Sunken - + 0 @@ -82,21 +82,21 @@ QFrame::Plain - + 0 - 3 + 0 - 3 + 0 - 3 + 0 - 3 + 0 @@ -125,7 +125,12 @@ - + + + + 14 + + 0 @@ -164,7 +169,7 @@ - + Qt::Vertical @@ -173,8 +178,8 @@ - 20 - 5 + 0 + 0 @@ -183,7 +188,7 @@ - + 9 @@ -191,7 +196,7 @@ 6 - + 0 @@ -228,7 +233,7 @@ - + Qt::Vertical @@ -243,12 +248,12 @@ - + 6 - + 0 @@ -257,7 +262,9 @@ + 11 75 + true true @@ -279,7 +286,7 @@ - + 0 @@ -305,7 +312,7 @@ - + 0 @@ -313,7 +320,7 @@ QLayout::SetDefaultConstraint - + 5 @@ -327,6 +334,7 @@ + 11 75 true true @@ -408,7 +416,7 @@ - + Qt::Horizontal @@ -426,7 +434,7 @@ - + 6 @@ -559,7 +567,7 @@ - + Qt::Horizontal @@ -623,9 +631,9 @@ QFrame::Raised - + - + Qt::Horizontal @@ -651,7 +659,7 @@ - + Qt::Horizontal @@ -677,7 +685,7 @@ QFrame::Sunken - + 3 @@ -718,31 +726,26 @@ - - StyledLabel - QLabel -

gui/common/StyledLabel.h
-
- - ElidedLabel - QLabel -
gui/common/ElidedLabel.h
- 1 -
GxsIdLabel QLabel
gui/gxs/GxsIdLabel.h
- ClickableLabel + ElidedLabel QLabel -
util/ClickableLabel.h
+
gui/common/ElidedLabel.h
+ 1 +
+ + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
- + diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index a88a1d6b5..c5f95aa24 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -102,7 +102,7 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent available posts from your subscribed friends, and make the \ links visible to all other friends.

Afterwards you can unsubscribe from the context menu of the links list at left.

")); - ui->infoframe->hide(); + ui->infoFrame->hide(); /* load settings */ processSettings(true); @@ -417,7 +417,7 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group) if (IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) { - ui->infoframe->hide(); + ui->infoFrame->hide(); } else { @@ -472,7 +472,7 @@ void PostedListWidget::insertPostedDetails(const RsPostedGroup &group) ui->infoDistribution->setText(distrib_string); - ui->infoframe->show(); + ui->infoFrame->show(); } } @@ -771,7 +771,7 @@ void PostedListWidget::applyRanking() void PostedListWidget::blank() { clearPosts(); - ui->infoframe->hide(); + ui->infoFrame->hide(); } void PostedListWidget::clearPosts() { diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.ui b/retroshare-gui/src/gui/Posted/PostedListWidget.ui index f59ee76ee..22f1761ca 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.ui @@ -30,7 +30,7 @@ 0 - + QFrame::Box @@ -106,7 +106,7 @@ - + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -260,7 +260,7 @@ - + QFrame::StyledPanel @@ -323,7 +323,7 @@ <!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:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html> @@ -515,7 +515,10 @@ p, li { white-space: pre-wrap; } - 14 + 11 + 75 + true + true @@ -658,16 +661,21 @@ p, li { white-space: pre-wrap; } QLabel
gui/gxs/GxsIdLabel.h
- - SubscribeToolButton - QToolButton -
gui/common/SubscribeToolButton.h
-
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + SubscribeToolButton + QToolButton +
gui/common/SubscribeToolButton.h
+
diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp index 8ff178af6..1798bb4bc 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "retroshare/rsgxscircles.h" @@ -58,9 +59,7 @@ // number of posts to show at once. #define POSTS_CHUNK_SIZE 25 -/**** - * #define DEBUG_POSTED - ***/ +//#define DEBUG_POSTED static const int POSTED_TABS_POSTS = 1; @@ -74,6 +73,7 @@ static const int POSTED_TABS_POSTS = 1; // #define IMAGE_COPYLINK ":/images/copyrslink.png" #define IMAGE_AUTHOR ":/images/user/personal64.png" +#define IMAGE_COPYHTTP ":/images/emblem-web.png" Q_DECLARE_METATYPE(RsPostedPost); @@ -87,8 +87,12 @@ std::ostream& operator<<(std::ostream& o,const QSize& s) { return o << s.width() void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { +#ifdef DEBUG_POSTED + if(option.state & QStyle::State_Selected) RS_DBG("Selected"); +#endif + if((option.state & QStyle::State_Selected)) // Avoids double display. The selected widget is never exactly the size of the rendered one, - return; // so when selected, we only draw the selected one. + return; // so when selected, we only draw the selected one. // prepare painter->save(); @@ -98,7 +102,7 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & painter->save(); - painter->fillRect( option.rect, option.palette.background()); + painter->fillRect( option.rect, option.palette.window()); painter->restore(); QPixmap pixmap(option.rect.size()); @@ -109,9 +113,9 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & BoardPostDisplayWidget_compact w(post,displayFlags(post.mMeta.mMsgId),nullptr); w.setFixedSize(option.rect.size()); - w.updateGeometry(); w.adjustSize(); + w.render(&pixmap,QPoint(0,0),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background } else @@ -121,6 +125,7 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & w.setFixedSize(option.rect.size()); w.updateGeometry(); w.adjustSize(); + w.render(&pixmap,QPoint(0,0),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background } @@ -145,6 +150,10 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & painter->save(); painter->drawPixmap(option.rect.topLeft(), pixmap /*,.scaled(option.rect.width(),option.rect.width()*w.height()/(float)w.width(),Qt::KeepAspectRatio,Qt::SmoothTransformation)*/); +#ifdef DEBUG_POSTED + painter->drawText(option.rect.bottomLeft(),QString::number(time(nullptr))); + RS_DBG("DisplayMode=", mDisplayMode == BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT? "Compact":"Card", " Title:", post.mMeta.mMsgName.c_str()); +#endif painter->restore(); } @@ -193,40 +202,45 @@ uint8_t PostedPostDelegate::displayFlags(const RsGxsMessageId &id) const QWidget *PostedPostDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex& index) const { - RsPostedPost post = index.data(Qt::UserRole).value() ; - if(index.column() == RsPostedPostsModel::COLUMN_POSTS) - { - QWidget *w ; + if (!index.isValid()) + return nullptr; - if(mDisplayMode==BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT) - w = new BoardPostDisplayWidget_compact(post,displayFlags(post.mMeta.mMsgId),parent); - else - w = new BoardPostDisplayWidget_card(post,displayFlags(post.mMeta.mMsgId),parent); + if(index.column() != RsPostedPostsModel::COLUMN_POSTS) + return nullptr; - QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool))); - QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(expandItem(RsGxsMessageId,bool))); - QObject::connect(w,SIGNAL(commentsRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(openComments(const RsGxsMessageId&))); - QObject::connect(w,SIGNAL(changeReadStatusRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(changeReadStatus(const RsGxsMessageId&,bool))); + QWidget *w ; + RsPostedPost post = index.data(Qt::UserRole).value() ; - // All other interactions with the widget should cause the msg to be set as read. - QObject::connect(w,SIGNAL(thumbnailOpenned()),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(commentsRequested(const RsGxsMessageId&,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(shareButtonClicked()),mPostListWidget,SLOT(markCurrentPostAsRead())); - QObject::connect(w,SIGNAL(copylinkClicked()),mPostListWidget,SLOT(copyMessageLink())); +#ifdef DEBUG_POSTED + RS_DBG("Title:", post.mMeta.mMsgName.c_str()); +#endif - w->setFixedSize(option.rect.size()); - w->adjustSize(); - w->updateGeometry(); - w->adjustSize(); + if(mDisplayMode==BoardPostDisplayWidget_compact::DISPLAY_MODE_COMPACT) + w = new BoardPostDisplayWidget_compact(post,displayFlags(post.mMeta.mMsgId),parent); + else + w = new BoardPostDisplayWidget_card(post,displayFlags(post.mMeta.mMsgId),parent); - return w; - } - else - return NULL; + QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool))); + QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(expandItem(RsGxsMessageId,bool))); + QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(openComments(RsGxsMessageId))); + QObject::connect(w,SIGNAL(changeReadStatusRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(changeReadStatus(RsGxsMessageId,bool))); + + // All other interactions with the widget should cause the msg to be set as read. + QObject::connect(w,SIGNAL(thumbnailOpenned()),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(markCurrentPostAsRead())); + QObject::connect(w,SIGNAL(shareButtonClicked()),mPostListWidget,SLOT(markCurrentPostAsRead())); + + w->setGeometry(option.rect); + w->adjustSize(); + w->updateGeometry(); + w->adjustSize(); + + return w; } + void PostedPostDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { editor->setGeometry(option.rect); @@ -264,13 +278,10 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI connect(ui->nextButton,SIGNAL(clicked()),this,SLOT(nextPosts())); connect(ui->prevButton,SIGNAL(clicked()),this,SLOT(prevPosts())); - connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&))); connect(ui->viewModeButton,SIGNAL(clicked()),this,SLOT(switchDisplayMode())); connect(mPostedPostsModel,SIGNAL(boardPostsLoaded()),this,SLOT(postPostLoad())); - QFontMetricsF fm(font()); - /* Setup UI helper */ /* Connect signals */ @@ -285,7 +296,11 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI connect(ui->postsTree,SIGNAL(sizeChanged(QSize)),this,SLOT(handlePostsTreeSizeChange(QSize))); - /* load settings */ + ui->postsTree->setContextMenuPolicy(Qt::CustomContextMenu); + //QObject::connect(this,SIGNAL(copylinkClicked()),this,SLOT(copyMessageLink())); + connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&))); + + /* load settings */ processSettings(true); /* Initialize subscribe button */ @@ -314,6 +329,43 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI }, mEventHandlerId, RsEventType::GXS_POSTED ); } +void PostedListWidgetWithModel::postContextMenu(const QPoint& point) +{ + QMenu menu(this); + + // 1 - check that we are clicking on a post + + QModelIndex index = ui->postsTree->indexAt(point); + + if(!index.isValid()) + return; + + // 2 - generate the menu for that post. + + RsPostedPost post = index.data(Qt::UserRole).value() ; + + menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()))->setData(index); + + QByteArray urlarray(post.mLink.c_str()); + QUrl url = QUrl::fromEncoded(urlarray.trimmed()); + + std::cerr << "Using link: \"" << post.mLink << "\"" << std::endl; + + if(url.scheme()=="http" || url.scheme()=="https") + menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYHTTP), tr("Copy http Link"), this, SLOT(copyHttpLink()))->setData(index); + + menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index); + +#ifdef TODO + // This feature is not implemented yet in libretroshare. + + if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) + menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/edit_16.png"), tr("Edit"), this, SLOT(editPost())); +#endif + + menu.exec(QCursor::pos()); +} + void PostedListWidgetWithModel::switchDisplayMode() { if(mPostedPostsDelegate->getDisplayMode() == BoardPostDisplayWidget_compact::DISPLAY_MODE_CARD) @@ -374,28 +426,25 @@ void PostedListWidgetWithModel::filterItems(QString text) void PostedListWidgetWithModel::nextPosts() { - ui->postsTree->selectionModel()->clear(); - if(mPostedPostsModel->displayedStartPostIndex() + POSTS_CHUNK_SIZE < mPostedPostsModel->filteredPostsCount()) - { - mPostedPostsModel->setPostsInterval(POSTS_CHUNK_SIZE+mPostedPostsModel->displayedStartPostIndex(),POSTS_CHUNK_SIZE); + if(mPostedPostsModel->displayedStartPostIndex() + POSTS_CHUNK_SIZE < mPostedPostsModel->filteredPostsCount()) + { + mPostedPostsModel->setPostsInterval(POSTS_CHUNK_SIZE+mPostedPostsModel->displayedStartPostIndex(),POSTS_CHUNK_SIZE); updateShowLabel(); - } + } } void PostedListWidgetWithModel::prevPosts() { - ui->postsTree->selectionModel()->clear(); - - if((int)mPostedPostsModel->displayedStartPostIndex() > 0) - { - mPostedPostsModel->setPostsInterval((int)mPostedPostsModel->displayedStartPostIndex()-POSTS_CHUNK_SIZE,POSTS_CHUNK_SIZE); - updateShowLabel(); - } + if((int)mPostedPostsModel->displayedStartPostIndex() > 0) + { + mPostedPostsModel->setPostsInterval((int)mPostedPostsModel->displayedStartPostIndex()-POSTS_CHUNK_SIZE,POSTS_CHUNK_SIZE); + updateShowLabel(); + } } void PostedListWidgetWithModel::showAuthorInPeople() { - QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); + QModelIndex index = qobject_cast(QObject::sender())->data().toModelIndex(); if(!index.isValid()) throw std::runtime_error("No post under mouse!"); @@ -420,23 +469,31 @@ void PostedListWidgetWithModel::showAuthorInPeople() MainWindow::showWindow(MainWindow::People); idDialog->navigate(RsGxsId(post.mMeta.mAuthorId)); } -void PostedListWidgetWithModel::postContextMenu(const QPoint&) +void PostedListWidgetWithModel::copyHttpLink() { - QMenu menu(this); + try + { + if (groupId().isNull()) + throw std::runtime_error("No channel currently selected!"); - menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink())); - menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople())); + QModelIndex index = qobject_cast(QObject::sender())->data().toModelIndex(); -#ifdef TODO - // This feature is not implemented yet in libretroshare. + if(!index.isValid()) + throw std::runtime_error("No post under mouse!"); - if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) - menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/edit_16.png"), tr("Edit"), this, SLOT(editPost())); -#endif + RsPostedPost post = index.data(Qt::UserRole).value() ; - menu.exec(QCursor::pos()); + if(post.mMeta.mMsgId.isNull()) + throw std::runtime_error("Post has empty MsgId!"); + + QApplication::clipboard()->setText(QString::fromStdString(post.mLink)) ; + QMessageBox::information(NULL,tr("information"),tr("The Retrohare link was copied to your clipboard.")) ; + } + catch(std::exception& e) + { + QMessageBox::critical(NULL,tr("Link creation error"),tr("Link could not be created: ")+e.what()); + } } - void PostedListWidgetWithModel::copyMessageLink() { try @@ -444,7 +501,7 @@ void PostedListWidgetWithModel::copyMessageLink() if (groupId().isNull()) throw std::runtime_error("No channel currently selected!"); - QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); + QModelIndex index = qobject_cast(QObject::sender())->data().toModelIndex(); if(!index.isValid()) throw std::runtime_error("No post under mouse!"); @@ -490,116 +547,36 @@ void PostedListWidgetWithModel::handleEvent_main_thread(std::shared_ptrmPostedEventCode) { - case RsPostedEventCode::NEW_COMMENT: // [[fallthrough]]; - case RsPostedEventCode::NEW_VOTE: // [[fallthrough]]; - { - // special treatment here because the message might be a comment, so we need to refresh the comment tab if openned + case RsPostedEventCode::NEW_COMMENT: [[fallthrough]]; + case RsPostedEventCode::NEW_VOTE: + { + // special treatment here because the message might be a comment, so we need to refresh the comment tab if openned - for(int i=2;itabWidget->count();++i) - { - auto *t = dynamic_cast(ui->tabWidget->widget(i)); + for(int i=2;itabWidget->count();++i) + { + auto *t = dynamic_cast(ui->tabWidget->widget(i)); - if(t->groupId() == e->mPostedGroupId) - t->refresh(); - } - } - case RsPostedEventCode::NEW_MESSAGE: // [[fallthrough]]; - case RsPostedEventCode::NEW_POSTED_GROUP: // [[fallthrough]]; - case RsPostedEventCode::UPDATED_POSTED_GROUP: // [[fallthrough]]; - case RsPostedEventCode::UPDATED_MESSAGE: - case RsPostedEventCode::BOARD_DELETED: - case RsPostedEventCode::SYNC_PARAMETERS_UPDATED: - { + if(t->groupId() == e->mPostedGroupId) + t->refresh(); + } + } + [[clang::fallthrough]]; + case RsPostedEventCode::NEW_MESSAGE: [[fallthrough]]; + case RsPostedEventCode::NEW_POSTED_GROUP: [[fallthrough]]; + case RsPostedEventCode::UPDATED_POSTED_GROUP: [[fallthrough]]; + case RsPostedEventCode::UPDATED_MESSAGE: [[fallthrough]]; + case RsPostedEventCode::BOARD_DELETED: [[fallthrough]]; + case RsPostedEventCode::SYNC_PARAMETERS_UPDATED: + { if(e->mPostedGroupId == groupId()) updateDisplay(true); - } + } default: break; } } -#ifdef TO_REMOVE -void PostedListWidgetWithModel::showPostDetails() -{ - QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); - RsPostedPost post = index.data(Qt::UserRole).value() ; - - QTextDocument doc; - doc.setHtml(post.mMsg.c_str()); - - if(post.mMeta.mPublishTs == 0) - { - ui->postDetails_TE->clear(); - ui->postLogo_LB->hide(); - ui->postName_LB->hide(); - ui->postTime_LB->hide(); - mChannelPostFilesModel->clear(); - - return; - } - - ui->postLogo_LB->show(); - ui->postName_LB->show(); - ui->postTime_LB->show(); - - if(index.row()==0 && index.column()==0) - std::cerr << "here" << std::endl; - - std::cerr << "showPostDetails: setting mLastSelectedPosts[groupId()] to current post Id " << post.mMeta.mMsgId << ". Previous value: " << mLastSelectedPosts[groupId()] << std::endl; - mLastSelectedPosts[groupId()] = post.mMeta.mMsgId; - - std::list files; - for(auto& file:post.mFiles) - files.push_back(ChannelPostFileInfo(file,post.mMeta.mPublishTs)); - - mChannelPostFilesModel->setFiles(files); - - auto all_msgs_versions(post.mOlderVersions); - all_msgs_versions.insert(post.mMeta.mMsgId); - - ui->commentsDialog->commentLoad(post.mMeta.mGroupId, all_msgs_versions, post.mMeta.mMsgId); - - std::cerr << "Showing details about selected index : "<< index.row() << "," << index.column() << std::endl; - - ui->postDetails_TE->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), /* RSHTML_FORMATTEXT_EMBED_SMILEYS |*/ RSHTML_FORMATTEXT_EMBED_LINKS)); - - QPixmap postImage; - - if (post.mThumbnail.mData != NULL) - GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData, post.mThumbnail.mSize, postImage,GxsIdDetails::ORIGINAL); - else - postImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); - - int W = QFontMetricsF(font()).height() * 8; - - // Using fixed width so that the post will not displace the text when we browse. - - ui->postLogo_LB->setPixmap(postImage); - ui->postLogo_LB->setFixedSize(W,postImage.height()/(float)postImage.width()*W); - - ui->postName_LB->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())); - ui->postName_LB->setFixedWidth(W); - ui->postTime_LB->setText(QDateTime::fromMSecsSinceEpoch(post.mMeta.mPublishTs*1000).toString("MM/dd/yyyy, hh:mm")); - ui->postTime_LB->setFixedWidth(W); - - //ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_FILE); - //ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE); - ui->channelPostFiles_TV->setAutoSelect(true); - - // Now also set the post as read - - if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) - { - RsGxsGrpMsgIdPair postId; - postId.second = post.mMeta.mMsgId; - postId.first = post.mMeta.mGroupId; - - RsThread::async([postId]() { rsGxsChannels->markRead(postId, true) ; } ); - } -} -#endif - void PostedListWidgetWithModel::updateGroupData() { if(groupId().isNull()) @@ -764,7 +741,7 @@ QIcon PostedListWidgetWithModel::groupIcon() return QIcon(postedImage); } -void PostedListWidgetWithModel::setAllMessagesReadDo(bool read, uint32_t &/*token*/) +void PostedListWidgetWithModel::setAllMessagesReadDo(bool read) { if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) return; @@ -786,7 +763,7 @@ void PostedListWidgetWithModel::openComments(const RsGxsMessageId& msgId) ui->idChooser->getChosenId(current_author); RsPostedPost post = index.data(Qt::UserRole).value() ; - auto *commentDialog = new GxsCommentDialog(this,current_author,rsPosted->getTokenService(),rsPosted); + auto *commentDialog = new GxsCommentDialog(this,current_author,rsPosted); std::set msg_versions({post.mMeta.mMsgId}); commentDialog->commentLoad(post.mMeta.mGroupId, msg_versions, post.mMeta.mMsgId); @@ -884,6 +861,7 @@ void PostedListWidgetWithModel::insertBoardDetails(const RsPostedGroup& group) ui->subscribeToolButton->setText(tr("Subscribe")); ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount)); + ui->poplabel->setText(QString::number(group.mMeta.mPop)); if(group.mMeta.mLastPost==0) ui->infoLastPost->setText(tr("Never")); @@ -923,7 +901,7 @@ void PostedListWidgetWithModel::insertBoardDetails(const RsPostedGroup& group) formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag); - ui->infoDescription->setText(formatDescription); + ui->trans_Description->setText(formatDescription); ui->infoAdministrator->setId(group.mMeta.mAuthorId) ; link = RetroShareLink::createMessage(group.mMeta.mAuthorId, ""); @@ -1181,8 +1159,7 @@ void PostedListWidgetWithModel::subscribeGroup(bool subscribe) RsThread::async([=]() { - uint32_t token; - rsPosted->subscribeToGroup(token,grpId, subscribe); + rsPosted->subscribeToBoard(grpId, subscribe); } ); } @@ -1195,51 +1172,13 @@ void PostedListWidgetWithModel::voteMsg(RsGxsGrpMsgIdPair msg,bool up_or_down) return; } - rsPosted->voteForPost(up_or_down,msg.first,msg.second,voter_id); + RsGxsVoteType tvote = up_or_down?(RsGxsVoteType::UP):(RsGxsVoteType::DOWN); + + std::string error_str; + RsGxsMessageId vote_id; + if(!rsPosted->voteForPost(msg.first,msg.second,voter_id,tvote,vote_id,error_str)) + QMessageBox::critical(nullptr,tr("Could not vote"), tr("Error occured while voting: ")+QString::fromStdString(error_str)); + else + updateDisplay(true); } -#ifdef TODO -class PostedPostsReadData -{ -public: - PostedPostsReadData(bool read) - { - mRead = read; - mLastToken = 0; - } - -public: - bool mRead; - uint32_t mLastToken; -}; - -static void setAllMessagesReadCallback(FeedItem *feedItem, void *data) -{ - GxsChannelPostItem *channelPostItem = dynamic_cast(feedItem); - if (!channelPostItem) { - return; - } - - GxsChannelPostsReadData *readData = (GxsChannelPostsReadData*) data; - bool isRead = !channelPostItem->isUnread() ; - - if(channelPostItem->isLoaded() && (isRead == readData->mRead)) - return ; - - RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId()); - rsGxsChannels->setMessageReadStatus(readData->mLastToken, msgPair, readData->mRead); -} - -void PostedListWidgetWithModel::setAllMessagesReadDo(bool read, uint32_t &token) -{ - if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) { - return; - } - - GxsChannelPostsReadData data(read); - //ui->feedWidget->withAll(setAllMessagesReadCallback, &data); - - token = data.mLastToken; -} - -#endif diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h index a38e0d036..cb7dcfd39 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h @@ -130,12 +130,13 @@ protected: #endif /* GxsMessageFrameWidget */ - virtual void setAllMessagesReadDo(bool read, uint32_t &token) override; + virtual void setAllMessagesReadDo(bool read) override; private slots: #ifdef TO_REMOVE void showPostDetails(); #endif + void postContextMenu(const QPoint&); void showAuthorInPeople(); void tabCloseRequested(int index); void updateSorting(int); @@ -145,8 +146,8 @@ private slots: void subscribeGroup(bool subscribe); void settingsChanged(); void postPostLoad(); - void postContextMenu(const QPoint&); void copyMessageLink(); + void copyHttpLink(); void nextPosts(); void prevPosts(); void filterItems(QString s); diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui index ccba99f67..8074388dc 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui @@ -46,7 +46,7 @@
- + @@ -54,7 +54,7 @@ <!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:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; 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-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html>
@@ -84,8 +84,11 @@ p, li { white-space: pre-wrap; } true
+ + <html><head/><body><p>Maximum number of data items (including posts, comments, votes) across friend nodes.</p></body></html> + - Contributions: + Items (at friends): @@ -179,6 +182,9 @@ p, li { white-space: pre-wrap; } true
+ + Number of subscribed friend nodes + Popularity: @@ -251,7 +257,7 @@ p, li { white-space: pre-wrap; } Qt::Vertical - QSizePolicy::Preferred + QSizePolicy::Expanding @@ -271,9 +277,10 @@ p, li { white-space: pre-wrap; } - 50 + 15 + 75 false - false + true @@ -300,7 +307,7 @@ p, li { white-space: pre-wrap; } - + 0 @@ -309,7 +316,9 @@ p, li { white-space: pre-wrap; } + 25 75 + true true @@ -344,7 +353,7 @@ p, li { white-space: pre-wrap; } - + QFrame::Box @@ -372,6 +381,12 @@ p, li { white-space: pre-wrap; } 0 + + + 75 + true + + Create Post @@ -394,7 +409,13 @@ p, li { white-space: pre-wrap; } - + + + + 75 + true + + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -439,22 +460,6 @@ p, li { white-space: pre-wrap; } - - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 40 - 20 - - - - @@ -572,14 +577,15 @@ p, li { white-space: pre-wrap; } - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
+ ElidedLabel + QLabel +
gui/common/ElidedLabel.h
+ 1
- SubscribeToolButton - QToolButton -
gui/common/SubscribeToolButton.h
+ GxsIdChooser + QComboBox +
gui/gxs/GxsIdChooser.h
GxsIdLabel @@ -587,15 +593,14 @@ p, li { white-space: pre-wrap; }
gui/gxs/GxsIdLabel.h
- RSTreeView - QTreeView -
gui/common/RSTreeView.h
- 1 + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
- StyledElidedLabel - QLabel -
gui/common/StyledElidedLabel.h
+ RSComboBox + QComboBox +
gui/common/RSComboBox.h
RSTabWidget @@ -604,14 +609,20 @@ p, li { white-space: pre-wrap; } 1 - GxsIdChooser - QComboBox -
gui/gxs/GxsIdChooser.h
+ RSTreeView + QTreeView +
gui/common/RSTreeView.h
+ 1 +
+ + SubscribeToolButton + QToolButton +
gui/common/SubscribeToolButton.h
- + diff --git a/retroshare-gui/src/gui/QuickStartWizard.cpp b/retroshare-gui/src/gui/QuickStartWizard.cpp index f442d2f1b..ce953a32e 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.cpp +++ b/retroshare-gui/src/gui/QuickStartWizard.cpp @@ -20,27 +20,30 @@ #include "QuickStartWizard.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include "gui/common/FilesDefs.h" +#ifdef USE_COMBOBOX +#include "gui/common/RSComboBox.h" +#endif #include "settings/rsharesettings.h" #include "util/QtVersion.h" -#include "gui/common/FilesDefs.h" + +#include "retroshare/rsfiles.h" +#include "retroshare/rsconfig.h" +#include "retroshare/rspeers.h" +#include "retroshare/rstypes.h" + +#include +#include +#include +#include +#include QuickStartWizard::QuickStartWizard(QWidget *parent) : QDialog(parent) { ui.setupUi(this); - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/rs_wizard.png")); + ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/tools_wizard.png")); ui.headerFrame->setHeaderText("RetroShare"); ui.pagesWizard->setCurrentIndex(0); @@ -53,7 +56,7 @@ QuickStartWizard::QuickStartWizard(QWidget *parent) : // ui.checkBoxF2FRouting->setChecked(true) ; // ui.checkBoxF2FRouting->setEnabled(false) ; - connect( ui.netModeComboBox, SIGNAL( activated ( int ) ), this, SLOT( toggleUPnP( ) ) ); + connect( ui.netModeComboBox, SIGNAL( activated(int) ), this, SLOT( toggleUPnP() ) ); // connect( ui.checkBoxTunnelConnection, SIGNAL( toggled( bool ) ), this, SLOT( toggleTunnelConnection(bool) ) ); // bool b = rsPeers->getAllowTunnelConnection() ; @@ -299,7 +302,7 @@ void QuickStartWizard::loadShare() listWidget->insertRow(row) ; listWidget->setItem(row,0,new QTableWidgetItem(QString::fromStdString((*it).filename))); #ifdef USE_COMBOBOX - QComboBox *cb = new QComboBox ; + RSComboBox *cb = new RSComboBox ; cb->addItem(tr("Network Wide")) ; cb->addItem(tr("Browsable")) ; cb->addItem(tr("Universal")) ; @@ -494,7 +497,6 @@ void QuickStartWizard::loadNetwork() void QuickStartWizard::saveChanges() { - QString str; //bool saveAddr = false; diff --git a/retroshare-gui/src/gui/QuickStartWizard.ui b/retroshare-gui/src/gui/QuickStartWizard.ui index ede111c52..fc8832637 100644 --- a/retroshare-gui/src/gui/QuickStartWizard.ui +++ b/retroshare-gui/src/gui/QuickStartWizard.ui @@ -334,7 +334,7 @@ p, li { white-space: pre-wrap; }
- + Automatic (UPnP) @@ -360,7 +360,7 @@ p, li { white-space: pre-wrap; } - + Public: DHT & Discovery @@ -1072,6 +1072,11 @@ p, li { white-space: pre-wrap; }
gui/common/HeaderFrame.h
1 + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/RSHumanReadableDelegate.h b/retroshare-gui/src/gui/RSHumanReadableDelegate.h index 3e9a3e412..18943c1dc 100644 --- a/retroshare-gui/src/gui/RSHumanReadableDelegate.h +++ b/retroshare-gui/src/gui/RSHumanReadableDelegate.h @@ -91,7 +91,8 @@ class RSHumanReadableAgeDelegate: public RSHumanReadableDelegate QStyleOptionViewItem opt(option) ; setPainterOptions(painter,opt,index) ; - painter->drawText(opt.rect, Qt::AlignCenter, misc::timeRelativeToNow(index.data().toLongLong())) ; + if(index.data().toLongLong() > 0) // no date is present. + painter->drawText(opt.rect, Qt::AlignCenter, misc::timeRelativeToNow(index.data().toLongLong())) ; } }; diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index 0cfcc9772..05e19857f 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -48,6 +48,15 @@ * #define RDM_SEARCH_DEBUG ****/ +#define REMOTEDIRMODEL_COLUMN_NAME 0 +#define REMOTEDIRMODEL_COLUMN_FILENB 1 +#define REMOTEDIRMODEL_COLUMN_SIZE 2 +#define REMOTEDIRMODEL_COLUMN_AGE 3 +#define REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS 4 +#define REMOTEDIRMODEL_COLUMN_WN_VISU_DIR 5 +#define REMOTEDIRMODEL_COLUMN_COUNT 6 +#define RETROSHARE_DIR_MODEL_FILTER_STRING "filtered" + static const uint32_t FLAT_VIEW_MAX_REFS_PER_SECOND = 2000 ; static const size_t FLAT_VIEW_MAX_REFS_TABLE_SIZE = 10000 ; // static const uint32_t FLAT_VIEW_MIN_DELAY_BETWEEN_UPDATES = 120 ; // dont rebuild ref list more than every 2 mins. @@ -136,7 +145,7 @@ void RetroshareDirModel::treeStyle() { categoryIcon.addPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/folder.png"), QIcon::Normal, QIcon::Off); categoryIcon.addPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/folderopen.png"), QIcon::Normal, QIcon::On); - peerIcon = FilesDefs::getIconFromQtResourcePath(":/images/user/identity16.png"); + peerIcon = FilesDefs::getIconFromQtResourcePath(":/icons/folder-account.svg"); } void TreeStyle_RDM::update() { @@ -295,11 +304,11 @@ int FlatStyle_RDM::rowCount(const QModelIndex &parent) const int TreeStyle_RDM::columnCount(const QModelIndex &/*parent*/) const { - return COLUMN_COUNT; + return REMOTEDIRMODEL_COLUMN_COUNT; } int FlatStyle_RDM::columnCount(const QModelIndex &/*parent*/) const { - return COLUMN_COUNT; + return REMOTEDIRMODEL_COLUMN_COUNT; } QString RetroshareDirModel::getFlagsString(FileStorageFlags flags) @@ -416,7 +425,7 @@ QVariant RetroshareDirModel::filterRole(const DirDetails& details, int /*coln*/) QVariant RetroshareDirModel::decorationRole(const DirDetails& details,int coln) const { - if(coln == COLUMN_FRIEND_ACCESS) + if(coln == REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS) { if(details.type == DIR_TYPE_PERSON) return QVariant() ; @@ -484,7 +493,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const { switch(coln) { - case COLUMN_NAME: { + case REMOTEDIRMODEL_COLUMN_NAME: { //SharedDirStats stats ; QString res ; @@ -497,7 +506,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const return res ; } - case COLUMN_FILENB: { + case REMOTEDIRMODEL_COLUMN_FILENB: { SharedDirStats stats ; if(RemoteMode) @@ -516,7 +525,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const } return tr("Empty"); } - case COLUMN_SIZE: { + case REMOTEDIRMODEL_COLUMN_SIZE: { SharedDirStats stats ; if(RemoteMode) @@ -531,7 +540,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const return QString(); } - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: if(!isNewerThanEpoque(details.max_mtime)) return QString(); else if(details.id != rsPeers->getOwnId()) @@ -547,13 +556,13 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const { switch(coln) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: return QVariant(); - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return misc::friendlyUnit(details.size); - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: { if(details.type == DIR_TYPE_FILE) return misc::timeRelativeToNow(details.max_mtime); @@ -567,9 +576,9 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const else return QString(); } - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return QVariant(); - case COLUMN_WN_VISU_DIR: + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: return getGroupsString(details.flags,details.parent_groups) ; default: @@ -580,22 +589,22 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const { switch(coln) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); break; - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: if (details.children.size() > 1) { return QString::number(details.children.size()) + " " + tr("Files"); } return QString::number(details.children.size()) + " " + tr("File"); - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return misc::friendlyUnit(details.size); - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return QVariant(); - case COLUMN_WN_VISU_DIR: + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: return getGroupsString(details.flags,details.parent_groups) ; default: @@ -650,12 +659,12 @@ QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */ switch(coln) { - case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - case COLUMN_FILENB: return QString(); - case COLUMN_SIZE: return misc::friendlyUnit(details.size); - case COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); - case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); - case COLUMN_WN_VISU_DIR: return computeDirectoryPath(details); + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); + case REMOTEDIRMODEL_COLUMN_FILENB: return QString(); + case REMOTEDIRMODEL_COLUMN_SIZE: return misc::friendlyUnit(details.size); + case REMOTEDIRMODEL_COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: return computeDirectoryPath(details); default: return QVariant() ; } @@ -675,9 +684,9 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& { switch(coln) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: return (RemoteMode)?(QString::fromUtf8(rsPeers->getPeerName(details.id).c_str())):tr("My files"); - case COLUMN_FILENB: { + case REMOTEDIRMODEL_COLUMN_FILENB: { SharedDirStats stats ; if(RemoteMode) @@ -687,7 +696,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& return (qulonglong) stats.total_number_of_files; } - case COLUMN_SIZE: { + case REMOTEDIRMODEL_COLUMN_SIZE: { SharedDirStats stats ; if(RemoteMode) @@ -697,7 +706,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& return (qulonglong) stats.total_shared_size; } - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return details.max_mtime; default: return QString(); @@ -707,17 +716,17 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& { switch(coln) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: return (qulonglong) 0; - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return (qulonglong) details.size; - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return details.max_mtime; - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return getFlagsString(details.flags); - case COLUMN_WN_VISU_DIR: + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: { QString ind(""); if (ageIndicator != IND_ALWAYS) @@ -732,15 +741,15 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& { switch(coln) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: return (qulonglong) details.children.size(); - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return (qulonglong) 0; - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return details.max_mtime; - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return getFlagsString(details.flags); default: return tr("DIR"); @@ -760,12 +769,12 @@ QVariant FlatStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& { switch(coln) { - case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - case COLUMN_FILENB: return (qulonglong) 0; - case COLUMN_SIZE: return (qulonglong) details.size; - case COLUMN_AGE: return details.max_mtime; - case COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); - case COLUMN_WN_VISU_DIR: { + case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); + case REMOTEDIRMODEL_COLUMN_FILENB: return (qulonglong) 0; + case REMOTEDIRMODEL_COLUMN_SIZE: return (qulonglong) details.size; + case REMOTEDIRMODEL_COLUMN_AGE: return details.max_mtime; + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: return QString::fromUtf8(rsPeers->getPeerName(details.id).c_str()); + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: { RS_STACK_MUTEX(_ref_mutex) ; return computeDirectoryPath(details); @@ -793,7 +802,7 @@ QVariant RetroshareDirModel::data(const QModelIndex &index, int role) const if (role == Qt::TextAlignmentRole) { - if((coln == COLUMN_FILENB) || (coln == COLUMN_SIZE)) + if((coln == REMOTEDIRMODEL_COLUMN_FILENB) || (coln == REMOTEDIRMODEL_COLUMN_SIZE)) return int( Qt::AlignRight | Qt::AlignVCenter); else return QVariant(); @@ -895,7 +904,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ; int defh = QFontMetricsF(QWidget().font()).height(); - if (section < COLUMN_AGE) + if (section < REMOTEDIRMODEL_COLUMN_AGE) { defw = 200/16.0*defh; } @@ -909,7 +918,7 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int { switch(section) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: if (RemoteMode) if(mUpdating) return tr("Friends Directories [updating...]"); @@ -920,18 +929,18 @@ QVariant TreeStyle_RDM::headerData(int section, Qt::Orientation orientation, int return tr("My Directories [updating...]"); else return tr("My Directories"); - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: return tr("# Files"); - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return tr("Size"); - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return tr("Age"); - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: if (RemoteMode) return tr("Friend"); else return tr("Access"); - case COLUMN_WN_VISU_DIR: + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: if (RemoteMode) return tr("What's new"); else @@ -949,7 +958,7 @@ QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int int defw = QFontMetricsF(QWidget().font()).width(headerData(section,Qt::Horizontal,Qt::DisplayRole).toString()) ; int defh = QFontMetricsF(QWidget().font()).height(); - if (section < COLUMN_AGE) + if (section < REMOTEDIRMODEL_COLUMN_AGE) { defw = defh*200/16.0; } @@ -963,24 +972,24 @@ QVariant FlatStyle_RDM::headerData(int section, Qt::Orientation orientation, int { switch(section) { - case COLUMN_NAME: + case REMOTEDIRMODEL_COLUMN_NAME: if (RemoteMode) { return tr("Friends Directories"); } return tr("My Directories"); - case COLUMN_FILENB: + case REMOTEDIRMODEL_COLUMN_FILENB: return tr("# Files"); - case COLUMN_SIZE: + case REMOTEDIRMODEL_COLUMN_SIZE: return tr("Size"); - case COLUMN_AGE: + case REMOTEDIRMODEL_COLUMN_AGE: return tr("Age"); - case COLUMN_FRIEND_ACCESS: + case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: if(RemoteMode) return tr("Friend"); else return tr("Share Flags"); - case COLUMN_WN_VISU_DIR: + case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: return tr("Directory"); } return tr("Column %1").arg(section); @@ -1096,7 +1105,7 @@ QModelIndex TreeStyle_RDM::parent( const QModelIndex & index ) const std::cerr << "Creating index 3 row=" << details.prow << ", column=" << 0 << ", ref=" << (void*)details.parent << std::endl; #endif - return createIndex(details.prow, COLUMN_NAME, details.parent); + return createIndex(details.prow, REMOTEDIRMODEL_COLUMN_NAME, details.parent); } QModelIndex FlatStyle_RDM::parent( const QModelIndex & index ) const { @@ -1167,7 +1176,7 @@ void RetroshareDirModel::postMods() endResetModel(); - emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,COLUMN_COUNT-1,(void*)NULL)); + emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,REMOTEDIRMODEL_COLUMN_COUNT-1,(void*)NULL)); } void FlatStyle_RDM::postMods() @@ -1340,7 +1349,7 @@ void RetroshareDirModel::getDirDetailsFromSelect (const QModelIndexList &list, s QModelIndexList::const_iterator it; for(it = list.begin(); it != list.end(); ++it) { - if(it->column()==COLUMN_FILENB) + if(it->column()==REMOTEDIRMODEL_COLUMN_FILENB) { void *ref = it -> internalPointer(); @@ -1377,7 +1386,7 @@ void RetroshareDirModel::getFileInfoFromIndexList(const QModelIndexList& list, s std::set already_in ; for(QModelIndexList::const_iterator it(list.begin()); it != list.end(); ++it) - if(it->column()==COLUMN_NAME) + if(it->column()==REMOTEDIRMODEL_COLUMN_NAME) { void *ref = it -> internalPointer(); @@ -1458,7 +1467,7 @@ void RetroshareDirModel::openSelected(const QModelIndexList &qmil, bool openDir) void RetroshareDirModel::getFilePath(const QModelIndex& index, std::string& fullpath) { - void *ref = index.sibling(index.row(),COLUMN_FILENB).internalPointer(); + void *ref = index.sibling(index.row(),REMOTEDIRMODEL_COLUMN_FILENB).internalPointer(); DirDetails details ; diff --git a/retroshare-gui/src/gui/RemoteDirModel.h b/retroshare-gui/src/gui/RemoteDirModel.h index 9d94abf32..83028dd48 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.h +++ b/retroshare-gui/src/gui/RemoteDirModel.h @@ -32,15 +32,6 @@ #include #include -#define COLUMN_NAME 0 -#define COLUMN_FILENB 1 -#define COLUMN_SIZE 2 -#define COLUMN_AGE 3 -#define COLUMN_FRIEND_ACCESS 4 -#define COLUMN_WN_VISU_DIR 5 -#define COLUMN_COUNT 6 -#define RETROSHARE_DIR_MODEL_FILTER_STRING "filtered" - struct DirDetails; class DirDetailsVector : public DirDetails diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index d34871104..6e377f70e 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -22,6 +22,7 @@ #include "ChatLobbyWidget.h" #include "MainWindow.h" +#include "HomePage.h" #include "chat/ChatDialog.h" #include "common/PeerDefs.h" #include "common/RsCollection.h" @@ -551,32 +552,45 @@ RetroShareLink RetroShareLink::createMessage(const RsGxsId& peerId, const QStrin RetroShareLink RetroShareLink::createCertificate(const RsPeerId& ssl_id) { - RetroShareLink link; - link.clear(); + RetroShareLink link; + link.clear(); #ifndef RS_NO_WARN_CPP #pragma message("csoler 2012-08-14: This is baaaaaad code") #endif - // - we should not need to parse and re-read a cert in old format. - // - RsPeerDetails detail; - if (rsPeers->getPeerDetails(ssl_id, detail) == false) { - std::cerr << "RetroShareLink::createPerson() Couldn't find peer id " << ssl_id << std::endl; - } else { + // - we should not need to parse and re-read a cert in old format. + // + RsPeerDetails detail; + if (rsPeers->getPeerDetails(ssl_id, detail) == false) + std::cerr << "RetroShareLink::createPerson() Couldn't find peer id " << ssl_id << std::endl; + else + { + link._type = TYPE_CERTIFICATE; - link._type = TYPE_CERTIFICATE; - link._radix = QString::fromUtf8(rsPeers->GetRetroshareInvite(ssl_id).c_str()); - link._name = QString::fromUtf8(detail.name.c_str()); - link._location = QString::fromUtf8(detail.location.c_str()); - link._radix.replace("\n",""); + if(rsPeers->getOwnId() == ssl_id) // in this case, use application-wide parameters set in HomePage + { + QString description; + auto invite_flags = static_cast(MainWindow::getPage(MainWindow::Home))->currentInviteFlags(); - std::cerr << "Found radix = " << link._radix.toStdString() << std::endl; - } + invite_flags &= ~RetroshareInviteFlags::SLICE_TO_80_CHARS; + invite_flags |= RetroshareInviteFlags::RADIX_FORMAT; - link.check(); + link._radix = QString::fromUtf8(rsPeers->GetRetroshareInvite(ssl_id,invite_flags).c_str()); + } + else + link._radix = QString::fromUtf8(rsPeers->GetRetroshareInvite(ssl_id).c_str()); - return link; + link._name = QString::fromUtf8(detail.name.c_str()); + link._location = QString::fromUtf8(detail.location.c_str()); + link._radix.replace("\n",""); + + std::cerr << "Found radix = " << link._radix.toStdString() << std::endl; + } + + link.check(); + + return link; } RetroShareLink RetroShareLink::createUnknownSslCertificate(const RsPeerId& sslId, const RsPgpId& gpgId) { diff --git a/retroshare-gui/src/gui/ServicePermissionDialog.ui b/retroshare-gui/src/gui/ServicePermissionDialog.ui index 0acd51c75..7354fe9ae 100644 --- a/retroshare-gui/src/gui/ServicePermissionDialog.ui +++ b/retroshare-gui/src/gui/ServicePermissionDialog.ui @@ -16,8 +16,17 @@ true - - + + + 0 + + + 0 + + + 0 + + 0 @@ -37,14 +46,14 @@
- + QFrame::StyledPanel QFrame::Raised - + @@ -69,7 +78,7 @@ - frame + gradFrame headerFrame diff --git a/retroshare-gui/src/gui/ShareManager.cpp b/retroshare-gui/src/gui/ShareManager.cpp index 8f4e32542..6681e30c5 100644 --- a/retroshare-gui/src/gui/ShareManager.cpp +++ b/retroshare-gui/src/gui/ShareManager.cpp @@ -66,7 +66,7 @@ ShareManager::ShareManager() Settings->loadWidgetInformation(this); connect(ui.addButton, SIGNAL(clicked( bool ) ), this , SLOT( addShare() ) ); - connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); + connect(ui.applyButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(ui.shareddirList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(shareddirListCustomPopupMenu(QPoint))); diff --git a/retroshare-gui/src/gui/ShareManager.ui b/retroshare-gui/src/gui/ShareManager.ui index e20074f9a..2799737c9 100644 --- a/retroshare-gui/src/gui/ShareManager.ui +++ b/retroshare-gui/src/gui/ShareManager.ui @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -47,14 +47,14 @@ - + QFrame::NoFrame QFrame::Raised - + 6 @@ -63,10 +63,7 @@ Shared Folder Manager - - - 2 - + @@ -97,7 +94,7 @@ false - 22 + 43 @@ -132,17 +129,12 @@ - - - 0 - 0 - - - - - 200 - 200 - + + + 12 + 75 + true + Add a Share Directory @@ -150,16 +142,10 @@ Add new - - - 24 - 24 - - - + Qt::Horizontal @@ -172,7 +158,14 @@ - + + + + 12 + 75 + true + + Apply and close @@ -186,10 +179,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -210,6 +212,15 @@ + + + + 0 + 0 + 0 + + + @@ -230,6 +241,15 @@ + + + + 154 + 154 + 154 + + + @@ -251,6 +271,11 @@ + + + 12 + + true @@ -274,11 +299,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
HeaderFrame QFrame diff --git a/retroshare-gui/src/gui/StartDialog.cpp b/retroshare-gui/src/gui/StartDialog.cpp index 4a07d43c8..d6f9f707d 100644 --- a/retroshare-gui/src/gui/StartDialog.cpp +++ b/retroshare-gui/src/gui/StartDialog.cpp @@ -123,7 +123,7 @@ void StartDialog::loadPerson() rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ; rsNotify->setDisableAskPassword(true); - bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; + bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; rsNotify->setDisableAskPassword(false); rsNotify->clearPgpPassphrase(); diff --git a/retroshare-gui/src/gui/StartDialog.ui b/retroshare-gui/src/gui/StartDialog.ui index a49d51e9b..8c491caeb 100644 --- a/retroshare-gui/src/gui/StartDialog.ui +++ b/retroshare-gui/src/gui/StartDialog.ui @@ -252,7 +252,7 @@
- + @@ -298,6 +298,8 @@ 12 + 75 + true @@ -355,16 +357,21 @@ p, li { white-space: pre-wrap; } - - - - - LineEditClear QLineEdit
gui/common/LineEditClear.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+ + + + + diff --git a/retroshare-gui/src/gui/common/StyledLabel.cpp b/retroshare-gui/src/gui/TheWire/CustomFrame.cpp similarity index 67% rename from retroshare-gui/src/gui/common/StyledLabel.cpp rename to retroshare-gui/src/gui/TheWire/CustomFrame.cpp index 2eabc9852..4f1308df5 100644 --- a/retroshare-gui/src/gui/common/StyledLabel.cpp +++ b/retroshare-gui/src/gui/TheWire/CustomFrame.cpp @@ -1,49 +1,41 @@ -/******************************************************************************* - * gui/common/StyledLabel.cpp * - * * - * Copyright (c) 2014, RetroShare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#include - -#include "StyledLabel.h" - -/** Constructor */ -StyledLabel::StyledLabel(QWidget *parent) - : QLabel(parent) -{ -} - -StyledLabel::StyledLabel(const QString &text, QWidget *parent) - : QLabel(text, parent) -{ -} - -int StyledLabel::fontSizeFactor() -{ - return mFontSizeFactor; -} - -void StyledLabel::setFontSizeFactor(int factor) -{ - mFontSizeFactor = factor; - - QFont f = font(); - qreal fontSize = mFontSizeFactor * f.pointSizeF() / 100; - f.setPointSizeF(fontSize); - setFont(f); -} +/******************************************************************************* + * gui/TheWire/CustomFrame.cpp * + * * + * Copyright (c) 2012-2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "CustomFrame.h" +#include + +// Constructor +CustomFrame::CustomFrame(QWidget *parent) : QFrame(parent) +{ + // Any initializations for this frame. +} + +// Overriding the inbuilt paint function +void CustomFrame::paintEvent(QPaintEvent *event) +{ + QFrame::paintEvent(event); + QPainter painter(this); + painter.drawPixmap(rect(), backgroundImage); +} + +// Function to set the member variable 'backgroundImage' +void CustomFrame::setPixmap(QPixmap pixmap){ + backgroundImage = pixmap; +} diff --git a/retroshare-gui/src/gui/common/StyledElidedLabel.h b/retroshare-gui/src/gui/TheWire/CustomFrame.h similarity index 70% rename from retroshare-gui/src/gui/common/StyledElidedLabel.h rename to retroshare-gui/src/gui/TheWire/CustomFrame.h index d6467ab1f..e75a6087a 100644 --- a/retroshare-gui/src/gui/common/StyledElidedLabel.h +++ b/retroshare-gui/src/gui/TheWire/CustomFrame.h @@ -1,42 +1,44 @@ -/******************************************************************************* - * gui/common/StyleElidedLabel.h * - * * - * Copyright (c) 2014, RetroShare Team * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with this program. If not, see . * - * * - *******************************************************************************/ - -#ifndef _STYLEDELIDEDLABEL_H -#define _STYLEDELIDEDLABEL_H - -#include "ElidedLabel.h" - -class StyledElidedLabel : public ElidedLabel -{ - Q_OBJECT - Q_PROPERTY(int fontSizeFactor READ fontSizeFactor WRITE setFontSizeFactor) - -public: - StyledElidedLabel(QWidget *parent = NULL); - StyledElidedLabel(const QString &text, QWidget *parent = NULL); - - void setFontSizeFactor(int factor); - int fontSizeFactor() {return _lastFactor;} - -private: - int _lastFactor; -}; - -#endif +/******************************************************************************* + * gui/TheWire/CustomFrame.h * + * * + * Copyright (c) 2012-2020 Robert Fernie * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef CUSTOMFRAMEH_H +#define CUSTOMFRAMEH_H + +#include +#include + +// This class is made to implement the background image in a Qframe or any widget + +class CustomFrame : public QFrame +{ + Q_OBJECT + +public: + explicit CustomFrame(QWidget *parent = nullptr); + void setPixmap(QPixmap pixmap); + +protected: + void paintEvent(QPaintEvent *event) override; + +private: + QPixmap backgroundImage; +}; + +#endif //CUSTOMFRAMEH_H diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp index ee9c562a2..8877d5cf6 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.cpp @@ -24,6 +24,7 @@ #include "PulseReply.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/common/FilesDefs.h" +#include "util/misc.h" #include "PulseAddDialog.h" @@ -35,15 +36,32 @@ PulseAddDialog::PulseAddDialog(QWidget *parent) { ui.setupUi(this); - connect(ui.pushButton_Post, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) ); + connect(ui.postButton, SIGNAL( clicked( void ) ), this, SLOT( postPulse( void ) ) ); connect(ui.pushButton_AddURL, SIGNAL( clicked( void ) ), this, SLOT( addURL( void ) ) ); connect(ui.pushButton_ClearDisplayAs, SIGNAL( clicked( void ) ), this, SLOT( clearDisplayAs( void ) ) ); connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) ); connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) ); connect(ui.pushButton_picture, SIGNAL(clicked()), this, SLOT( toggle())); + connect(ui.pushButton_remove, SIGNAL(clicked()), this, SLOT( removePictures())); + + + // this connection is from browse push button to the slot function onBrowseButtonClicked() + connect(ui.pushButton_Browse, SIGNAL(clicked()), this, SLOT( onBrowseButtonClicked())); ui.pushButton_picture->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/photo.png"))); + ui.pushButton_Browse->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/add-image.png"))); + ui.pushButton_remove->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/mail/delete.png"))); + ui.frame_picture->hide(); + ui.pushButton_picture->hide(); + + // initially hiding the browse button as the attach image button is not pressed + //ui.frame_PictureBrowse->hide(); + + ui.label_image1->hide(); + ui.label_image2->hide(); + ui.label_image3->hide(); + ui.label_image4->hide(); setAcceptDrops(true); } @@ -98,10 +116,9 @@ void PulseAddDialog::cleanup() QLayout *layout = ui.widget_replyto->layout(); // completely delete layout and sublayouts QLayoutItem * item; - QWidget * widget; while ((item = layout->takeAt(0))) { - if ((widget = item->widget()) != 0) + if (QWidget *widget = item->widget()) { std::cerr << "PulseAddDialog::cleanup() removing widget"; std::cerr << std::endl; @@ -129,8 +146,8 @@ void PulseAddDialog::cleanup() ui.frame_URL->setEnabled(false); ui.frame_URL->hide(); - ui.pushButton_Post->setEnabled(false); - ui.pushButton_Post->setText(tr("Post")); + ui.postButton->setEnabled(false); + ui.postButton->setText(tr("Post")); ui.textEdit_Pulse->setPlaceholderText(tr("Whats happening?")); ui.frame_input->setVisible(true); ui.widget_sentiment->setVisible(true); @@ -154,8 +171,11 @@ void PulseAddDialog::cleanup() ui.label_image4->clear(); ui.label_image4->setText(tr("Drag and Drop Image")); - // Hide Drag & Drop Frame - ui.frame_picture->hide(); + // Hide Drag & Drop Frame and the browse frame + ui.frame_picture->hide(); + //ui.frame_PictureBrowse->hide(); + ui.pushButton_picture->hide(); + ui.pushButton_picture->setChecked(false); } @@ -163,12 +183,12 @@ void PulseAddDialog::pulseTextChanged() { std::string pulseText = ui.textEdit_Pulse->toPlainText().toStdString(); bool enable = (pulseText.size() > 0) && (pulseText.size() < PULSE_MAX_SIZE); - ui.pushButton_Post->setEnabled(enable); + ui.postButton->setEnabled(enable); } // Old Interface, deprecate / make internal. // TODO: Convert mReplyToPulse to be an SPtr, and remove &pulse parameter. -void PulseAddDialog::setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType) +void PulseAddDialog::setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &/*groupName*/, uint32_t replyType) { mIsReply = true; mReplyToPulse = pulse; @@ -191,21 +211,21 @@ void PulseAddDialog::setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std: if (mReplyType & WIRE_PULSE_TYPE_REPLY) { - ui.pushButton_Post->setText(tr("Reply to Pulse")); + ui.postButton->setText(tr("Reply to Pulse")); ui.textEdit_Pulse->setPlaceholderText(tr("Pulse your reply")); } else { // cannot add msg for like / republish. - ui.pushButton_Post->setEnabled(true); + ui.postButton->setEnabled(true); ui.frame_input->setVisible(false); ui.widget_sentiment->setVisible(false); if (mReplyType & WIRE_PULSE_TYPE_REPUBLISH) { - ui.pushButton_Post->setText(tr("Republish Pulse")); + ui.postButton->setText(tr("Republish Pulse")); ui.pushButton_picture->hide(); } else if (mReplyType & WIRE_PULSE_TYPE_LIKE) { - ui.pushButton_Post->setText(tr("Like Pulse")); + ui.postButton->setText(tr("Like Pulse")); ui.pushButton_picture->hide(); } } @@ -479,24 +499,29 @@ void PulseAddDialog::addImage(const QString &path) std::cerr << "PulseAddDialog::addImage() Installing in Image1"; std::cerr << std::endl; ui.label_image1->setPixmap(icon); + ui.label_image1->show(); + ui.frame_picture->show(); mImage1.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image1 Size: " << mImage1.mSize; std::cerr << std::endl; } else if (mImage2.empty()) { ui.label_image2->setPixmap(icon); + ui.label_image2->show(); mImage2.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image2 Size: " << mImage2.mSize; std::cerr << std::endl; } else if (mImage3.empty()) { ui.label_image3->setPixmap(icon); + ui.label_image3->show(); mImage3.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image3 Size: " << mImage3.mSize; std::cerr << std::endl; } else if (mImage4.empty()) { ui.label_image4->setPixmap(icon); + ui.label_image4->show(); mImage4.copy((uint8_t *) ba.data(), ba.size()); std::cerr << "PulseAddDialog::addImage() Installing in Image4 Size: " << mImage4.mSize; std::cerr << std::endl; @@ -511,12 +536,47 @@ void PulseAddDialog::toggle() { if (ui.pushButton_picture->isChecked()) { + // Show the input methods (drag and drop field and the browse button) ui.frame_picture->show(); + ui.pushButton_picture->setToolTip(tr("Hide Pictures")); } else { + // Hide the input methods (drag and drop field and the browse button) ui.frame_picture->hide(); + ui.pushButton_picture->setToolTip(tr("Add Pictures")); } } + +// Function to get the file dialog for the browse button +void PulseAddDialog::onBrowseButtonClicked() +{ + QString filePath; + misc::getOpenFileName(this, RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", filePath); + if (!filePath.isEmpty()) { + //ui.lineEdit_FilePath->setText(filePath); + addImage(filePath); + } +} + +void PulseAddDialog::removePictures() +{ + + mImage1.clear(); + ui.label_image1->clear(); + mImage2.clear(); + ui.label_image2->clear(); + mImage3.clear(); + ui.label_image3->clear(); + mImage4.clear(); + ui.label_image4->clear(); + + ui.label_image1->hide(); + ui.label_image2->hide(); + ui.label_image3->hide(); + ui.label_image4->hide(); + + ui.frame_picture->hide(); +} diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h index ab386df2e..b1e8eca47 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.h +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.h @@ -53,11 +53,13 @@ private slots: void clearDialog(); void pulseTextChanged(); void toggle(); + void onBrowseButtonClicked(); + void removePictures(); private: // OLD VERSIONs, private now. void setGroup(RsWireGroup &group); - void setReplyTo(RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType); + void setReplyTo(const RsWirePulse &pulse, RsWirePulseSPtr pPulse, std::string &groupName, uint32_t replyType); void postOriginalPulse(); void postReplyPulse(); diff --git a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui index 1b8fb24cc..c09119a40 100644 --- a/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui +++ b/retroshare-gui/src/gui/TheWire/PulseAddDialog.ui @@ -6,22 +6,22 @@ 0 0 - 720 - 449 + 735 + 513 - - - 0 - + 6 - - + + 0 + + + 0 @@ -34,18 +34,15 @@ 16777215 - - QFrame::StyledPanel - - - QFrame::Raised - - + + + 0 + 0 - + 100 @@ -72,7 +69,7 @@ - + Qt::Horizontal @@ -86,6 +83,11 @@ + + + 12 + + GroupLabel @@ -116,15 +118,9 @@ - + - - QFrame::StyledPanel - - - QFrame::Raised - - + 0 @@ -142,7 +138,7 @@ - + 20 @@ -175,7 +171,7 @@ - + Qt::Horizontal @@ -188,14 +184,14 @@ - + Response Sentiment: - + 0 @@ -236,18 +232,21 @@ - + - - QFrame::StyledPanel - - - QFrame::Raised - - + + + 0 + 0 + + 0 + + + 0 + @@ -263,10 +262,16 @@ + + + 0 + 0 + + 0 - 100 + 80 @@ -275,45 +280,13 @@ QFrame::Raised - - - - - - 80 - 80 - - - - Drag and Drop Image - - - Qt::AlignCenter - - - + - 80 - 80 - - - - Drag and Drop Image - - - Qt::AlignCenter - - - - - - - - 80 - 80 + 40 + 40 @@ -328,8 +301,8 @@ - 80 - 80 + 40 + 40 @@ -340,19 +313,60 @@ + + + + + 40 + 40 + + + + Drag and Drop Image + + + Qt::AlignCenter + + + + + + + + 40 + 40 + + + + Drag and Drop Image + + + Qt::AlignCenter + + + + + + + Remove all images + + + + + + + 24 + 24 + + + + - - - - - URL - - - + @@ -363,13 +377,6 @@ - - - - Display As - - - @@ -380,19 +387,36 @@ + + + + Display As + + + + + + + URL + + + + frame_URL + frame_picture + textEdit_Pulse - - + + 6 - + @@ -408,7 +432,23 @@ - + + + Add Picture + + + + + + + 24 + 24 + + + + + + Qt::Horizontal @@ -421,7 +461,14 @@ - + + + + 12 + 75 + true + + Post @@ -444,9 +491,12 @@ QLabel
gui/gxs/GxsIdLabel.h
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
- - - + diff --git a/retroshare-gui/src/gui/TheWire/PulseMessage.cpp b/retroshare-gui/src/gui/TheWire/PulseMessage.cpp index 8f4a91873..34724282f 100644 --- a/retroshare-gui/src/gui/TheWire/PulseMessage.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseMessage.cpp @@ -29,10 +29,10 @@ PulseMessage::PulseMessage(QWidget *parent) { setupUi(this); - connect(label_image1, SIGNAL(clicked()), this, SLOT(viewPicture())); - connect(label_image2, SIGNAL(clicked()), this, SLOT(viewPicture())); - connect(label_image3, SIGNAL(clicked()), this, SLOT(viewPicture())); - connect(label_image4, SIGNAL(clicked()), this, SLOT(viewPicture())); + connect(label_image1, SIGNAL(clicked()), this, SLOT(viewPictureOne())); + connect(label_image2, SIGNAL(clicked()), this, SLOT(viewPictureTwo())); + connect(label_image3, SIGNAL(clicked()), this, SLOT(viewPictureThree())); + connect(label_image4, SIGNAL(clicked()), this, SLOT(viewPictureFour())); } void PulseMessage::setup(RsWirePulseSPtr pulse) @@ -148,7 +148,7 @@ void PulseMessage::setRefImageCount(uint32_t count) } } -void PulseMessage::viewPicture() +void PulseMessage::viewPictureOne() { PhotoView *photoView = new PhotoView(this); @@ -158,21 +158,69 @@ void PulseMessage::viewPicture() pixmap.loadFromData(mPulse->mImage1.mData, mPulse->mImage1.mSize); photoView->setPixmap(pixmap); } - + + QString timestamp = misc::timeRelativeToNow(mPulse->mRefPublishTs); + + photoView->setTitle(QString::fromStdString(mPulse->mPulseText)); + photoView->setGroupNameString(QString::fromStdString(mPulse->mRefGroupName)); + photoView->setTime(timestamp); + //photoView->setGroupId(mPulse->mRefGroupId); + + photoView->show(); + + /* window will destroy itself! */ +} + +void PulseMessage::viewPictureTwo() +{ + PhotoView *photoView = new PhotoView(this); + if (!mPulse->mImage2.empty()) { // install image. QPixmap pixmap; pixmap.loadFromData(mPulse->mImage2.mData, mPulse->mImage2.mSize); photoView->setPixmap(pixmap); } - + + QString timestamp = misc::timeRelativeToNow(mPulse->mRefPublishTs); + + photoView->setTitle(QString::fromStdString(mPulse->mPulseText)); + photoView->setGroupNameString(QString::fromStdString(mPulse->mRefGroupName)); + photoView->setTime(timestamp); + //photoView->setGroupId(mPulse->mRefGroupId); + + photoView->show(); + + /* window will destroy itself! */ +} + +void PulseMessage::viewPictureThree() +{ + PhotoView *photoView = new PhotoView(this); + if (!mPulse->mImage3.empty()) { // install image. QPixmap pixmap; pixmap.loadFromData(mPulse->mImage3.mData, mPulse->mImage3.mSize); photoView->setPixmap(pixmap); } - + + QString timestamp = misc::timeRelativeToNow(mPulse->mRefPublishTs); + + photoView->setTitle(QString::fromStdString(mPulse->mPulseText)); + photoView->setGroupNameString(QString::fromStdString(mPulse->mRefGroupName)); + photoView->setTime(timestamp); + //photoView->setGroupId(mPulse->mRefGroupId); + + photoView->show(); + + /* window will destroy itself! */ +} + +void PulseMessage::viewPictureFour() +{ + PhotoView *photoView = new PhotoView(this); + if (!mPulse->mImage4.empty()) { // install image. QPixmap pixmap; diff --git a/retroshare-gui/src/gui/TheWire/PulseMessage.h b/retroshare-gui/src/gui/TheWire/PulseMessage.h index a2372ebbf..234f0da02 100644 --- a/retroshare-gui/src/gui/TheWire/PulseMessage.h +++ b/retroshare-gui/src/gui/TheWire/PulseMessage.h @@ -37,7 +37,10 @@ public: void setRefImageCount(uint32_t count); private slots: - void viewPicture(); + void viewPictureOne(); + void viewPictureTwo(); + void viewPictureThree(); + void viewPictureFour(); private: RsWirePulseSPtr mPulse; diff --git a/retroshare-gui/src/gui/TheWire/PulseMessage.ui b/retroshare-gui/src/gui/TheWire/PulseMessage.ui index 8af226cea..46e4d8cd5 100644 --- a/retroshare-gui/src/gui/TheWire/PulseMessage.ui +++ b/retroshare-gui/src/gui/TheWire/PulseMessage.ui @@ -14,6 +14,18 @@ Form + + 0 + + + 0 + + + 0 + + + 0 + @@ -53,7 +65,7 @@ MS Sans Serif - 10 + 11 diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.cpp b/retroshare-gui/src/gui/TheWire/PulseReply.cpp index 92dccabf5..5067b5f9b 100644 --- a/retroshare-gui/src/gui/TheWire/PulseReply.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseReply.cpp @@ -50,7 +50,7 @@ void PulseReply::setup() // connect(pushButton_tmpViewGroup, SIGNAL(clicked()), this, SLOT(actionViewGroup())); // connect(pushButton_tmpViewParent, SIGNAL(clicked()), this, SLOT(actionViewParent())); - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); // connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate())); connect(toolButton_reply, SIGNAL(clicked()), this, SLOT(actionReply())); @@ -118,7 +118,7 @@ void PulseReply::setPulseStatus(PulseStatus status) { widget_actions->setVisible(status == PulseStatus::FULL); widget_follow->setVisible(status != PulseStatus::FULL); - toolButton_follow->setEnabled(status == PulseStatus::UNSUBSCRIBED); + followButton->setEnabled(status == PulseStatus::UNSUBSCRIBED); switch(status) { diff --git a/retroshare-gui/src/gui/TheWire/PulseReply.ui b/retroshare-gui/src/gui/TheWire/PulseReply.ui index 1ffbbdf85..497d606de 100644 --- a/retroshare-gui/src/gui/TheWire/PulseReply.ui +++ b/retroshare-gui/src/gui/TheWire/PulseReply.ui @@ -25,8 +25,20 @@ + + 0 + + + 0 + + + 0 + + + 0 + - + 0 @@ -48,10 +60,13 @@ QFrame::Raised - + 0 + + 1 + @@ -149,6 +164,9 @@ + + 9 + 0 @@ -380,7 +398,14 @@ - + + + + 12 + 75 + true + + FOLLOW @@ -433,10 +458,22 @@ 0 - 40 + 0 + + 6 + + + 0 + + + 0 + + + 0 + @@ -604,13 +641,19 @@ 0 - 40 + 0 + + 6 + 0 + + 0 + 0 diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp index e8c830a0b..0948e745b 100644 --- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.cpp @@ -48,7 +48,7 @@ void PulseTopLevel::setup() { connect(toolButton_viewGroup, SIGNAL(clicked()), this, SLOT(actionViewGroup())); connect(toolButton_viewParent, SIGNAL(clicked()), this, SLOT(actionViewParent())); - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); connect(toolButton_followParent, SIGNAL(clicked()), this, SLOT(actionFollowParent())); // connect(toolButton_rate, SIGNAL(clicked()), this, SLOT(rate())); @@ -58,7 +58,7 @@ void PulseTopLevel::setup() connect(toolButton_view, SIGNAL(clicked()), this, SLOT(actionViewPulse())); } -void PulseTopLevel::setRefMessage(QString msg, uint32_t image_count) +void PulseTopLevel::setRefMessage(QString /*msg*/, uint32_t /*image_count*/) { // This should never happen. //widget_message->setRefMessage(msg, image_count); @@ -149,7 +149,7 @@ void PulseTopLevel::setReferenceString(QString ref) } } -void PulseTopLevel::mousePressEvent(QMouseEvent *event) +void PulseTopLevel::mousePressEvent(QMouseEvent */*event*/) { } diff --git a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui index 35f763948..1959244d3 100644 --- a/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui +++ b/retroshare-gui/src/gui/TheWire/PulseTopLevel.ui @@ -24,9 +24,9 @@ - + - + 0 @@ -48,7 +48,7 @@ QFrame::Raised - + @@ -63,7 +63,7 @@ 40 - + 0 @@ -77,7 +77,7 @@ 0 - + Qt::Horizontal @@ -171,7 +171,7 @@ - + Qt::Horizontal @@ -200,9 +200,9 @@ 60 - + - + Qt::Vertical @@ -256,7 +256,7 @@ - + Qt::Horizontal @@ -336,7 +336,7 @@ 16777215 - + @@ -345,7 +345,7 @@ - + Qt::Horizontal @@ -361,7 +361,7 @@ - + Qt::Horizontal @@ -381,9 +381,9 @@ 40 - + - + @@ -392,14 +392,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Replies</span></p></body></html> - + Qt::Horizontal @@ -417,7 +417,7 @@ - + @@ -426,14 +426,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Republishes</span></p></body></html> - + Qt::Horizontal @@ -451,7 +451,7 @@ - + @@ -460,14 +460,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Likes</span></p></body></html> - + Qt::Horizontal @@ -485,7 +485,7 @@ - + Qt::Horizontal @@ -501,7 +501,7 @@ - + Qt::Horizontal @@ -521,11 +521,11 @@ 40 - + - + - + Qt::Horizontal @@ -562,7 +562,7 @@ - + Qt::Horizontal @@ -577,9 +577,9 @@ - + - + Qt::Horizontal @@ -616,7 +616,7 @@
- + Qt::Horizontal @@ -631,9 +631,9 @@
- + - + Qt::Horizontal @@ -670,7 +670,7 @@ - + Qt::Horizontal @@ -685,9 +685,9 @@ - + - + Qt::Horizontal @@ -717,7 +717,7 @@ - + Qt::Horizontal @@ -748,9 +748,9 @@ 40 - + - + Qt::Horizontal @@ -763,7 +763,13 @@ - + + + + 12 + true + + FOLLOW @@ -773,7 +779,7 @@ - + Qt::Horizontal diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp index 547fabbab..475c74034 100644 --- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp +++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.cpp @@ -24,86 +24,149 @@ #include #include "PulseViewGroup.h" +#include "CustomFrame.h" +#include "WireGroupDialog.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/common/FilesDefs.h" #include "util/DateTime.h" +Q_DECLARE_METATYPE(RsWireGroup) + /** Constructor */ PulseViewGroup::PulseViewGroup(PulseViewHolder *holder, RsWireGroupSPtr group) :PulseViewItem(holder), mGroup(group) { - setupUi(this); - setAttribute ( Qt::WA_DeleteOnClose, true ); - setup(); + setupUi(this); + setAttribute ( Qt::WA_DeleteOnClose, true ); + setup(); + + connect(editButton, SIGNAL(clicked()), this, SLOT(editProfile())); + } void PulseViewGroup::setup() { - if (mGroup) { - connect(toolButton_follow, SIGNAL(clicked()), this, SLOT(actionFollow())); + if (mGroup) { + connect(followButton, SIGNAL(clicked()), this, SLOT(actionFollow())); - label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName)); - label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString()))); - label_date->setText(DateTime::formatDateTime(mGroup->mMeta.mPublishTs)); - label_tagline->setText(QString::fromStdString(mGroup->mTagline)); - label_location->setText(QString::fromStdString(mGroup->mLocation)); + label_groupName->setText("@" + QString::fromStdString(mGroup->mMeta.mGroupName)); + label_authorName->setText(BoldString(QString::fromStdString(mGroup->mMeta.mAuthorId.toStdString()))); + label_date->setText(DateTime::formatDateTime(mGroup->mMeta.mPublishTs)); + label_tagline->setText(QString::fromStdString(mGroup->mTagline)); + label_location->setText(QString::fromStdString(mGroup->mLocation)); - // need to draw mGroup->mMasthead, as background to headshot. - // TODO frame_headerBackground->setBackground() - if (mGroup->mHeadshot.mData) - { - QPixmap pixmap; - if (GxsIdDetails::loadPixmapFromData( - mGroup->mHeadshot.mData, - mGroup->mHeadshot.mSize, - pixmap,GxsIdDetails::ORIGINAL)) - { - pixmap = pixmap.scaled(50,50); - label_headshot->setPixmap(pixmap); - } - } - else - { + if (mGroup->mMasthead.mData) + { + QPixmap pixmap; + if (GxsIdDetails::loadPixmapFromData( + mGroup->mMasthead.mData, + mGroup->mMasthead.mSize, + pixmap, GxsIdDetails::ORIGINAL)) + { + QSize frameSize = frame_masthead->size(); + + // Scale the pixmap based on the frame size + pixmap = pixmap.scaledToWidth(frameSize.width(), Qt::SmoothTransformation); + frame_masthead->setPixmap(pixmap); + } + } +// Uncomment the below code for default background +// else +// { +// // Default pixmap +// QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png"); +// QSize frameSize = frame_masthead->size(); + +// // Scale the pixmap based on the frame size +// pixmap = pixmap.scaled(frameSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); +// frame_masthead->setPixmap(pixmap); +// } + + if (mGroup->mHeadshot.mData) + { + QPixmap pixmap; + if (GxsIdDetails::loadPixmapFromData( + mGroup->mHeadshot.mData, + mGroup->mHeadshot.mSize, + pixmap,GxsIdDetails::ORIGINAL)) + { + pixmap = pixmap.scaled(100,100, Qt::KeepAspectRatio, Qt::SmoothTransformation); + label_headshot->setPixmap(pixmap); + } + } + else + { // default. - QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png").scaled(50,50); - label_headshot->setPixmap(pixmap); - } + QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(100,100, Qt::KeepAspectRatio, Qt::SmoothTransformation); + label_headshot->setPixmap(pixmap); + } - if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) - { - uint32_t pulses = mGroup->mGroupPulses + mGroup->mGroupReplies; - uint32_t replies = mGroup->mRefReplies; - uint32_t republishes = mGroup->mRefRepublishes; - uint32_t likes = mGroup->mRefLikes; + if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + { + uint32_t pulses = mGroup->mGroupPulses + mGroup->mGroupReplies; + uint32_t replies = mGroup->mRefReplies; + uint32_t republishes = mGroup->mRefRepublishes; + uint32_t likes = mGroup->mRefLikes; - label_extra_pulses->setText(BoldString(ToNumberUnits(pulses))); - label_extra_replies->setText(BoldString(ToNumberUnits(replies))); - label_extra_republishes->setText(BoldString(ToNumberUnits(republishes))); - label_extra_likes->setText(BoldString(ToNumberUnits(likes))); + label_extra_pulses->setText(BoldString(ToNumberUnits(pulses))); + label_extra_replies->setText(BoldString(ToNumberUnits(replies))); + label_extra_republishes->setText(BoldString(ToNumberUnits(republishes))); + label_extra_likes->setText(BoldString(ToNumberUnits(likes))); - // hide follow. - widget_actions->setVisible(false); - } - else - { - // hide stats. - widget_replies->setVisible(false); - } + // hide follow. + widget_actions->setVisible(false); + } + else + { + // hide stats. + widget_replies->setVisible(false); + } + } + + setGroupSet(); +} + +void PulseViewGroup::setGroupSet() +{ + if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + editButton->show(); + } + else if (mGroup->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) + { + editButton->hide(); + } + else + { + editButton->hide(); } } void PulseViewGroup::actionFollow() { - RsGxsGroupId groupId = mGroup->mMeta.mGroupId; - std::cerr << "PulseViewGroup::actionFollow() following "; - std::cerr << groupId; - std::cerr << std::endl; + RsGxsGroupId groupId = mGroup->mMeta.mGroupId; + std::cerr << "PulseViewGroup::actionFollow() following "; + std::cerr << groupId; + std::cerr << std::endl; - if (mHolder) { - mHolder->PVHfollow(groupId); - } + if (mHolder) { + mHolder->PVHfollow(groupId); + } +} + +void PulseViewGroup::editProfile() +{ + RsGxsGroupId groupId = mGroup->mMeta.mGroupId; + if (groupId.isNull()) + { + std::cerr << "PulseViewGroup::editProfile() No Group selected"; + std::cerr << std::endl; + return; + } + + WireGroupDialog wireEdit(GxsGroupDialog::MODE_EDIT, groupId, this); + wireEdit.exec (); } diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.h b/retroshare-gui/src/gui/TheWire/PulseViewGroup.h index 4d00090ca..62da0a228 100644 --- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.h +++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.h @@ -35,10 +35,13 @@ public: private slots: void actionFollow(); + void editProfile(); protected: void setup(); +private: + void setGroupSet(); protected: RsWireGroupSPtr mGroup; diff --git a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui index 41a2bf23a..79d9964f6 100644 --- a/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui +++ b/retroshare-gui/src/gui/TheWire/PulseViewGroup.ui @@ -6,7 +6,7 @@ 0 0 - 745 + 746 483 @@ -24,9 +24,9 @@ - + - + 0 @@ -50,17 +50,35 @@ - - + + + + 0 + 0 + + + + + 700 + 135 + + + + + + - + Qt::Horizontal + + QSizePolicy::Expanding + - 283 - 20 + 277 + 17 @@ -79,19 +97,22 @@ 100 + + + headshot - + Qt::Horizontal - 23 + 281 20 @@ -114,16 +135,38 @@ 60 - - - + + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> + + + + + - Qt::Horizontal + Qt::Vertical + + + QSizePolicy::Minimum - 518 - 58 + 20 + 10 @@ -147,41 +190,26 @@ - - - - - 0 - 0 - - - - - 0 - 20 - - - - <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - - - - - + + - Qt::Vertical - - - QSizePolicy::Minimum + Qt::Horizontal - 20 - 10 + 518 + 58 + + + + Edit profile + + + @@ -205,42 +233,7 @@ 16777215 - - - - - - 0 - 0 - - - - - 0 - 20 - - - - <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - + @@ -260,19 +253,6 @@ - - - - Qt::Horizontal - - - - 2000 - 20 - - - - @@ -292,11 +272,59 @@ + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> + + + + + + + Qt::Horizontal + + + + 2000 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + - + Qt::Horizontal @@ -316,9 +344,9 @@ 40 - + - + @@ -327,14 +355,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Pulses</span></p></body></html> - + Qt::Horizontal @@ -352,7 +380,7 @@ - + @@ -361,14 +389,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Replies</span></p></body></html> - + Qt::Horizontal @@ -386,7 +414,7 @@ - + @@ -395,14 +423,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Republishes</span></p></body></html> - + Qt::Horizontal @@ -420,7 +448,7 @@ - + @@ -429,14 +457,14 @@ - + <html><head/><body><p><span style=" color:#2e3436;">Likes</span></p></body></html> - + Qt::Horizontal @@ -454,7 +482,7 @@ - + Qt::Horizontal @@ -470,7 +498,7 @@ - + Qt::Horizontal @@ -490,9 +518,9 @@ 40 - + - + Qt::Horizontal @@ -505,7 +533,14 @@ - + + + + 12 + 75 + true + + FOLLOW @@ -515,7 +550,7 @@ - + Qt::Horizontal @@ -531,12 +566,25 @@ + widget_header + widget_publish + line_1 + widget_replies + line_2 + widget_actions + frame_masthead
- - - + + + CustomFrame + QFrame +
gui/TheWire/CustomFrame.h
+ 1 +
+
+ diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.cpp b/retroshare-gui/src/gui/TheWire/WireDialog.cpp index ed2ee5edd..38ea1b398 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireDialog.cpp @@ -23,6 +23,8 @@ #include "WireGroupDialog.h" #include "WireGroupItem.h" #include "gui/settings/rsharesettings.h" +#include "gui/gxs/GxsIdDetails.h" +#include "gui/common/FilesDefs.h" #include "PulseViewGroup.h" #include "PulseReplySeperator.h" @@ -57,17 +59,14 @@ /** Constructor */ WireDialog::WireDialog(QWidget *parent) -: MainPage(parent), mGroupSet(GROUP_SET_ALL) + : MainPage(parent), mGroupSet(GROUP_SET_ALL) + , mAddDialog(nullptr), mGroupSelected(nullptr), mWireQueue(nullptr) + , mHistoryIndex(-1), mEventHandlerId(0) { ui.setupUi(this); - mAddDialog = NULL; - mGroupSelected = NULL; - mHistoryIndex = -1; - connect( ui.toolButton_createAccount, SIGNAL(clicked()), this, SLOT(createGroup())); connect( ui.toolButton_createPulse, SIGNAL(clicked()), this, SLOT(createPulse())); - connect( ui.toolButton_refresh, SIGNAL(clicked()), this, SLOT(refreshGroups())); connect(ui.comboBox_groupSet, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSet(int))); connect(ui.comboBox_filterTime, SIGNAL(currentIndexChanged(int)), this, SLOT(selectFilterTime(int))); @@ -91,6 +90,48 @@ WireDialog::WireDialog(QWidget *parent) // load settings processSettings(true); + + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=]() { handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::WIRE ); +} + +void WireDialog::handleEvent_main_thread(std::shared_ptr event) +{ + const RsWireEvent *e = dynamic_cast(event.get()); + + if(e) + { + +#ifdef GXSWIRE_DEBUG + RsDbg() << " Refreshing the feed if there is a matching event. "<< std::endl; +#endif + + // The following switch statements refresh the wire feed whenever there is a new event + switch(e->mWireEventCode) + { + case RsWireEventCode::NEW_POST: + + case RsWireEventCode::NEW_REPLY: + + case RsWireEventCode::NEW_LIKE: + + case RsWireEventCode::NEW_REPUBLISH: + + case RsWireEventCode::POST_UPDATED: + + case RsWireEventCode::NEW_WIRE: + + case RsWireEventCode::FOLLOW_STATUS_CHANGED: + + default: + refreshGroups(); + break; + + } + } } WireDialog::~WireDialog() @@ -98,7 +139,10 @@ WireDialog::~WireDialog() // save settings processSettings(false); - delete(mWireQueue); + clearTwitterView(); + delete(mWireQueue); + + rsEvents->unregisterEventsHandler(mEventHandlerId); } void WireDialog::processSettings(bool load) @@ -127,7 +171,7 @@ void WireDialog::refreshGroups() void WireDialog::addGroup(QWidget *item) { - QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + QLayout *alayout = ui.groupsWidget->layout(); alayout->addWidget(item); } @@ -268,7 +312,7 @@ void WireDialog::deleteGroups() mGroupSelected = NULL; - QLayout *alayout = ui.scrollAreaWidgetContents_groups->layout(); + QLayout *alayout = ui.groupsWidget->layout(); QLayoutItem *item; int i = 0; while (i < alayout->count()) @@ -300,17 +344,28 @@ void WireDialog::updateGroups(std::vector& groups) mOwnGroups.clear(); ui.groupChooser->clear(); - std::vector::const_iterator it; - for(it = groups.begin(); it != groups.end(); it++) { + for(auto &it : groups) { // save list of all groups. - mAllGroups[it->mMeta.mGroupId] = *it; + mAllGroups[it.mMeta.mGroupId] = it; - if (it->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) + if (it.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { // grab own groups. // setup Chooser too. - mOwnGroups.push_back(*it); - ui.groupChooser->addItem(QString::fromStdString(it->mMeta.mGroupName)); + mOwnGroups.push_back(it); + QPixmap pixmap; + if (it.mHeadshot.mData) + { + if (GxsIdDetails::loadPixmapFromData( it.mHeadshot.mData,it.mHeadshot.mSize,pixmap,GxsIdDetails::ORIGINAL)) + pixmap = pixmap.scaled(32,32); + } + else + { + // default. + pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32); + } + + ui.groupChooser->addItem(QPixmap(pixmap),QString::fromStdString(it.mMeta.mGroupName)); } } } @@ -362,16 +417,15 @@ void WireDialog::showGroups() std::list allGroupIds; /* depends on the comboBox */ - std::map::const_iterator it; - for (it = mAllGroups.begin(); it != mAllGroups.end(); it++) + for (auto &it : mAllGroups) { bool add = (mGroupSet == GROUP_SET_ALL); - if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { + if (it.second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) { if (mGroupSet == GROUP_SET_OWN) { add = true; } } - else if (it->second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { + else if (it.second.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) { if (mGroupSet == GROUP_SET_SUBSCRIBED) { add = true; } @@ -383,11 +437,11 @@ void WireDialog::showGroups() } if (add) { - addGroup(it->second); + addGroup(it.second); // request data. std::list grpIds; - grpIds.push_back(it->second.mMeta.mGroupId); - allGroupIds.push_back(it->second.mMeta.mGroupId); + grpIds.push_back(it.second.mMeta.mGroupId); + allGroupIds.push_back(it.second.mMeta.mGroupId); } } @@ -790,20 +844,21 @@ void WireDialog::showPulseFocus(const RsGxsGroupId groupId, const RsGxsMessageId // fetch data from backend. RsWirePulseSPtr pPulse; int type = 0; - bool success = rsWire->getPulseFocus(groupId, msgId, type, pPulse); - - // sleep(2); - - /* now insert the pulse + children into the layput */ - RsQThreadUtils::postToObject([pPulse,this]() + if(rsWire->getPulseFocus(groupId, msgId, type, pPulse)) { - /* Here it goes any code you want to be executed on the Qt Gui + // sleep(2); + + /* now insert the pulse + children into the layput */ + RsQThreadUtils::postToObject([pPulse,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - postPulseFocus(pPulse); + postPulseFocus(pPulse); - }, this); + }, this); + } }); } @@ -822,10 +877,9 @@ void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse) addTwitterView(new PulseTopLevel(this, pPulse)); - std::list::iterator it; - for(it = pPulse->mReplies.begin(); it != pPulse->mReplies.end(); it++) + for(auto &it : pPulse->mReplies) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; PulseReply *firstReply = new PulseReply(this, reply); addTwitterView(firstReply); @@ -857,9 +911,9 @@ void WireDialog::postPulseFocus(RsWirePulseSPtr pPulse) addTwitterView(new PulseReplySeperator()); } - for(it = pPulse->mRepublishes.begin(); it != pPulse->mRepublishes.end(); it++) + for(auto &it : pPulse->mRepublishes) { - RsWirePulseSPtr repub = *it; + RsWirePulseSPtr repub = it; PulseReply *firstRepub = new PulseReply(this, repub); firstRepub->showReplyLine(false); @@ -928,10 +982,9 @@ void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list::iterator it; - for(it = pulses.begin(); it != pulses.end(); it++) + for(auto &it : pulses) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; // don't show likes if (reply->mPulseType & WIRE_PULSE_TYPE_LIKE) { @@ -949,7 +1002,7 @@ void WireDialog::postGroupFocus(RsWireGroupSPtr group, std::list groupIds) +void WireDialog::requestGroupsPulses(const std::list& groupIds) { WireViewHistory view; view.viewType = WireViewType::GROUPS; @@ -959,7 +1012,7 @@ void WireDialog::requestGroupsPulses(const std::list groupIds) showGroupsPulses(groupIds); } -void WireDialog::showGroupsPulses(const std::list groupIds) +void WireDialog::showGroupsPulses(const std::list& groupIds) { clearTwitterView(); @@ -968,20 +1021,21 @@ void WireDialog::showGroupsPulses(const std::list groupIds) { // fetch data from backend. std::list pulses; - bool success = rsWire->getPulsesForGroups(groupIds, pulses); - - // sleep(2); - - /* now insert the pulse + children into the layput */ - RsQThreadUtils::postToObject([pulses,this]() + if(rsWire->getPulsesForGroups(groupIds, pulses)) { - /* Here it goes any code you want to be executed on the Qt Gui + // sleep(2); + + /* now insert the pulse + children into the layput */ + RsQThreadUtils::postToObject([pulses,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - postGroupsPulses(pulses); + postGroupsPulses(pulses); - }, this); + }, this); + } }); } @@ -992,10 +1046,9 @@ void WireDialog::postGroupsPulses(std::list pulses) ui.label_viewMode->setText("Groups Pulses"); - std::list::iterator it; - for(it = pulses.begin(); it != pulses.end(); it++) + for(auto &it : pulses) { - RsWirePulseSPtr reply = *it; + RsWirePulseSPtr reply = it; // don't show likes if (reply->mPulseType & WIRE_PULSE_TYPE_LIKE) { std::cerr << "WireDialog::postGroupsPulses() Not showing LIKE"; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.h b/retroshare-gui/src/gui/TheWire/WireDialog.h index 100cedeec..a55369fc0 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.h +++ b/retroshare-gui/src/gui/TheWire/WireDialog.h @@ -76,9 +76,9 @@ public: WireDialog(QWidget *parent = 0); ~WireDialog(); - virtual QIcon iconPixmap() const { return QIcon(IMAGE_WIRE) ; } - virtual QString pageName() const { return tr("The Wire") ; } - virtual QString helpText() const { return ""; } + virtual QIcon iconPixmap() const override { return QIcon(IMAGE_WIRE) ; } + virtual QString pageName() const override { return tr("The Wire") ; } + virtual QString helpText() const override { return ""; } // WireGroupHolder interface. virtual void subscribe(RsGxsGroupId &groupId) override; @@ -114,8 +114,8 @@ public: void showGroupFocus(const RsGxsGroupId groupId); void postGroupFocus(RsWireGroupSPtr group, std::list pulses); - void requestGroupsPulses(const std::list groupIds); - void showGroupsPulses(const std::list groupIds); + void requestGroupsPulses(const std::list& groupIds); + void showGroupsPulses(const std::list& groupIds); void postGroupsPulses(std::list pulses); private slots: @@ -153,7 +153,7 @@ private: bool loadGroupData(const uint32_t &token); void acknowledgeGroup(const uint32_t &token, const uint32_t &userType); - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); + virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req) override; int mGroupSet; @@ -164,6 +164,10 @@ private: std::map mAllGroups; std::vector mOwnGroups; + // This function and variable below it handle the events for the wire + void handleEvent_main_thread(std::shared_ptr event); + RsEventsHandlerId_t mEventHandlerId; + int32_t mHistoryIndex; std::vector mHistory; diff --git a/retroshare-gui/src/gui/TheWire/WireDialog.ui b/retroshare-gui/src/gui/TheWire/WireDialog.ui index 2aeefe92f..4cdf4a174 100644 --- a/retroshare-gui/src/gui/TheWire/WireDialog.ui +++ b/retroshare-gui/src/gui/TheWire/WireDialog.ui @@ -6,7 +6,7 @@ 0 0 - 804 + 809 586 @@ -33,7 +33,7 @@ 0 - + 0 @@ -46,7 +46,7 @@ QFrame::Plain - + 0 @@ -101,14 +101,7 @@ - - - Refresh - - - - - + @@ -134,7 +127,7 @@ Qt::Horizontal - + 1 @@ -159,9 +152,9 @@ QFrame::Raised - + - + All @@ -189,7 +182,6 @@ 10 - 75 true @@ -199,22 +191,22 @@ - + true - + 0 0 - 228 - 488 + 224 + 465 - + - + Qt::Vertical @@ -305,6 +297,11 @@ + + + 12 + + Most Recent @@ -337,7 +334,7 @@ - + 0 @@ -383,7 +380,7 @@ 0 0 523 - 484 + 462 @@ -429,9 +426,16 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
- + diff --git a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp index 1be0c9a2c..e832540de 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp +++ b/retroshare-gui/src/gui/TheWire/WireGroupDialog.cpp @@ -109,7 +109,7 @@ void WireGroupDialog::prepareWireGroup(RsWireGroup &group, const RsGroupMetaData QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); - pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format + pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format group.mHeadshot.copy((uint8_t *) ba.data(), ba.size()); } else { @@ -126,7 +126,7 @@ void WireGroupDialog::prepareWireGroup(RsWireGroup &group, const RsGroupMetaData QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); - pixmap.save(&buffer, "JPG"); + pixmap.save(&buffer, "PNG"); group.mMasthead.copy((uint8_t *) ba.data(), ba.size()); } else { @@ -152,7 +152,7 @@ bool WireGroupDialog::service_updateGroup(const RsGroupMetaData &editedMeta) std::cerr << "WireGroupDialog::service_updateGroup() submitting changes"; std::cerr << std::endl; - bool success = rsWire->updateGroup(grp); + bool success = rsWire->editWire(grp); // TODO updateGroup should refresh groupId or Data return success; } diff --git a/retroshare-gui/src/gui/TheWire/WireGroupExtra.cpp b/retroshare-gui/src/gui/TheWire/WireGroupExtra.cpp index b6a1c5440..8ed6d4d4b 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupExtra.cpp +++ b/retroshare-gui/src/gui/TheWire/WireGroupExtra.cpp @@ -34,13 +34,19 @@ WireGroupExtra::~WireGroupExtra() void WireGroupExtra::setUp() { - connect(ui.pushButton_masthead, SIGNAL(clicked() ), this , SLOT(addMasthead())); -} + connect(ui.pushButton_masthead, SIGNAL(clicked() ), this , SLOT(addMasthead())); + int desired_height = ui.pushButton_masthead->height() + ui.removeButton->height() + ui.lineEdit_Tagline->height(); + int desired_width = 3/1.0 * desired_height + ui.lineEdit_Tagline->width(); + + ui.label_masthead->setFixedSize(desired_width, desired_height); + + setMasthead(QPixmap()); +} void WireGroupExtra::addMasthead() { - QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Masthead"), 400, 100); + QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Masthead"), 800, 600); if (img.isNull()) return; @@ -48,7 +54,6 @@ void WireGroupExtra::addMasthead() setMasthead(img); } - void WireGroupExtra::setTagline(const std::string &str) { ui.lineEdit_Tagline->setText(QString::fromStdString(str)); @@ -61,8 +66,21 @@ void WireGroupExtra::setLocation(const std::string &str) void WireGroupExtra::setMasthead(const QPixmap &pixmap) { - mMasthead = pixmap; - ui.label_masthead->setPixmap(mMasthead); + mMasthead = pixmap; + + if (!mMasthead.isNull()) { + ui.label_masthead->setPicture(mMasthead); + ui.label_masthead->setToolTip(tr("Use the mouse to zoom and adjust the image for your background.")); + } else { + ui.label_masthead->setPicture(QPixmap()); + ui.label_masthead->setText(tr("MastHead background Image")); + } +} + +void WireGroupExtra::on_removeButton_clicked() +{ + ui.label_masthead->setPicture(QPixmap()); + ui.label_masthead->setText(tr("MastHead background Image")); } std::string WireGroupExtra::getTagline() @@ -77,7 +95,5 @@ std::string WireGroupExtra::getLocation() QPixmap WireGroupExtra::getMasthead() { - return mMasthead; + return ui.label_masthead->extractCroppedScaledPicture(); } - - diff --git a/retroshare-gui/src/gui/TheWire/WireGroupExtra.h b/retroshare-gui/src/gui/TheWire/WireGroupExtra.h index ce606feb3..429be088b 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupExtra.h +++ b/retroshare-gui/src/gui/TheWire/WireGroupExtra.h @@ -34,7 +34,6 @@ public: void setMasthead(const QPixmap &pixmap); QPixmap getMasthead(); - void setTagline(const std::string &str); void setLocation(const std::string &str); @@ -43,7 +42,7 @@ public: private slots: void addMasthead(); - + void on_removeButton_clicked(); private: void setUp(); private: diff --git a/retroshare-gui/src/gui/TheWire/WireGroupExtra.ui b/retroshare-gui/src/gui/TheWire/WireGroupExtra.ui index fb1da5e73..4c03b8fe8 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupExtra.ui +++ b/retroshare-gui/src/gui/TheWire/WireGroupExtra.ui @@ -7,7 +7,7 @@ 0 0 516 - 199 + 133
@@ -19,50 +19,127 @@ Form - + + + 0 + + + 0 + - - - Masthead - - - - - - - MastHead background Image - - + + + + + + + + Tagline: + + + + + + + + + + Remove + + + + + + + Location: + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + Select Image + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + QFrame::Plain + + + 1 + + + MastHead background Image + + + Qt::PlainText + + + false + + + Qt::AlignCenter + + + + - - - Select Image + + + Qt::Vertical - - - - - - Tagline: + + + 20 + 10 + - - - - - - - - - Location: - - - - - +
+ + + ZoomableLabel + QLabel +
gui/gxschannels/GxsChannelPostThumbnail.h
+
+
diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp index 8ab62260a..199800581 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.cpp @@ -65,8 +65,7 @@ WireGroupItem::WireGroupItem(WireGroupHolder *holder, const RsWireGroup &grp) setAttribute ( Qt::WA_DeleteOnClose, true ); setup(); - // disabled, still not yet functional Edit/Update - editButton->setEnabled(false); + editButton->setEnabled(true); } RsGxsGroupId &WireGroupItem::groupId() @@ -93,14 +92,14 @@ void WireGroupItem::setup() QImage circleImage = getCirclePhoto(orginalImage,orginalImage.size().width()); pixmap.convertFromImage(circleImage); - pixmap = pixmap.scaled(40,40); + pixmap = pixmap.scaled(40,40, Qt::KeepAspectRatio, Qt::SmoothTransformation); label_headshot->setPixmap(pixmap); } } else { // default. - QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32); + QPixmap pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32, Qt::KeepAspectRatio, Qt::SmoothTransformation); label_headshot->setPixmap(pixmap); } diff --git a/retroshare-gui/src/gui/TheWire/WireGroupItem.ui b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui index 2da79ddc6..a53448157 100644 --- a/retroshare-gui/src/gui/TheWire/WireGroupItem.ui +++ b/retroshare-gui/src/gui/TheWire/WireGroupItem.ui @@ -6,8 +6,8 @@ 0 0 - 276 - 114 + 292 + 115 diff --git a/retroshare-gui/src/gui/TorControl/TorControlWindow.cpp b/retroshare-gui/src/gui/TorControl/TorControlWindow.cpp new file mode 100644 index 000000000..6da6b8d7a --- /dev/null +++ b/retroshare-gui/src/gui/TorControl/TorControlWindow.cpp @@ -0,0 +1,230 @@ +#include +#include + +#include +#include +#include +#include + +#include +#include "util/rstime.h" + +#include "TorControlWindow.h" +#include "TorManager.h" +#include "TorControl.h" +#include "HiddenService.h" + +TorControlDialog::TorControlDialog(Tor::TorManager *tm,QWidget *parent) + : mTorManager(tm) +{ + setupUi(this) ; + + QObject::connect(tm->control(),SIGNAL(statusChanged(int,int)),this,SLOT(statusChanged())) ; + QObject::connect(tm->control(),SIGNAL(connected()),this,SLOT(statusChanged())); + QObject::connect(tm->control(),SIGNAL(disconnected()),this,SLOT(statusChanged())); + QObject::connect(tm->control(),SIGNAL(bootstrapStatusChanged()),this,SLOT(statusChanged())); + QObject::connect(tm->control(),SIGNAL(connectivityChanged()),this,SLOT(statusChanged())); + QObject::connect(tm ,SIGNAL(errorChanged()),this,SLOT(statusChanged())); + + //QTimer::singleShot(2000,this,SLOT(checkForHiddenService())) ; + + mIncomingServer = new QTcpServer(this) ; + mHiddenService = NULL ; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_UNKNOWN; + //mBootstrapPhaseFinished = false ; + + connect(mIncomingServer, SIGNAL(QTcpServer::newConnection()), this, SLOT(onIncomingConnection())); + + QTimer *timer = new QTimer ; + + QObject::connect(timer,SIGNAL(timeout()),this,SLOT(showLog())) ; + timer->start(500) ; + + // Hide some debug output for the released version + + setWindowFlags( Qt::Dialog | Qt::FramelessWindowHint ); + + adjustSize(); +} + +void TorControlDialog::onIncomingConnection() +{ + std::cerr << "Incoming connection !!" << std::endl; +} + +void TorControlDialog::statusChanged() +{ + int tor_control_status = mTorManager->control()->status(); + int torstatus = mTorManager->control()->torStatus(); + + QString tor_control_status_str,torstatus_str ; + + if(mTorManager->hasError()) + mErrorMsg = mTorManager->errorMessage() ; + + switch(tor_control_status) + { + default: + case Tor::TorControl::Error : tor_control_status_str = "Error" ; break ; + case Tor::TorControl::NotConnected: tor_control_status_str = "Not connected" ; break ; + case Tor::TorControl::Connecting: tor_control_status_str = "Connecting" ; break ; + case Tor::TorControl::Authenticating: tor_control_status_str = "Authenticating" ; break ; + case Tor::TorControl::Connected: tor_control_status_str = "Connected" ; break ; + } + + switch(torstatus) + { + default: + case Tor::TorControl::TorUnknown: torstatus_str = "Unknown" ; break ; + case Tor::TorControl::TorOffline: torstatus_str = "Tor offline" ; break ; + case Tor::TorControl::TorReady: torstatus_str = "Tor ready" ; break ; + } + + torStatus_LB->setText(torstatus_str) ; + + if(torstatus == Tor::TorControl::TorUnknown) + torStatus_LB->setToolTip(tr("Check that Tor is accessible in your executable path")) ; + else + torStatus_LB->setToolTip("") ; + + QVariantMap qvm = mTorManager->control()->bootstrapStatus(); + QString bootstrapstatus_str ; + + std::cerr << "Tor control status: " << tor_control_status_str.toStdString() << std::endl; + std::cerr << "Tor status: " << torstatus_str.toStdString() << std::endl; + + std::cerr << "Bootstrap status map: " << std::endl; + + for(auto it(qvm.begin());it!=qvm.end();++it) + std::cerr << " " << it.key().toStdString() << " : " << it.value().toString().toStdString() << std::endl; + + if(!qvm["progress"].toString().isNull()) + torBootstrapStatus_LB->setText(qvm["progress"].toString() + " % (" + qvm["summary"].toString() + ")") ; + else + torBootstrapStatus_LB->setText(tr("[Waiting for Tor...]")) ; + + QString service_id ; + QString onion_address ; + QHostAddress service_target_address ; + uint16_t service_port ; + uint16_t target_port ; + + if(mTorManager->getHiddenServiceInfo(service_id,onion_address,service_port, service_target_address,target_port)) + { + hiddenServiceAddress_LB->setText(QString::number(service_port) + ":" + service_target_address.toString() + ":" + QString::number(target_port)); + onionAddress_LB->setText(onion_address); + } + else + { + hiddenServiceAddress_LB->setText(QString("[Not ready]")) ; + onionAddress_LB->setText(QString("[Not ready]")) ; + } + + showLog(); + adjustSize(); + + QCoreApplication::processEvents(); // forces update +} + +void TorControlDialog::showLog() +{ + static std::set already_seen ; + + QString s ; + QStringList logmsgs = mTorManager->logMessages() ; + bool can_print = false ; + + for(QStringList::const_iterator it(logmsgs.begin());it!=logmsgs.end();++it) + { + s += *it + "\n" ; + + if(already_seen.find(*it) == already_seen.end()) + { + can_print = true ; + already_seen.insert(*it); + } + + if(can_print) + std::cerr << "[TOR DEBUG LOG] " << (*it).toStdString() << std::endl; + } + +// torLog_TB->setText(s) ;: + + std::cerr << "Connexion Proxy: " << mTorManager->control()->socksAddress().toString().toStdString() << ":" << mTorManager->control()->socksPort() << std::endl; +} + +TorControlDialog::TorStatus TorControlDialog::checkForTor(QString& error_msg) +{ + if(!mErrorMsg.isNull()) + { + error_msg = mErrorMsg ; + return TorControlDialog::TOR_STATUS_FAIL ; + } + + switch(mTorManager->control()->torStatus()) + { + case Tor::TorControl::TorReady: rstime::rs_usleep(1*1000*1000);return TOR_STATUS_OK ; + default: + return TOR_STATUS_UNKNOWN ; + } +} + +TorControlDialog::HiddenServiceStatus TorControlDialog::checkForHiddenService() +{ + std::cerr << "Checking for hidden services:" ; + + switch(mHiddenServiceStatus) + { + default: + case HIDDEN_SERVICE_STATUS_UNKNOWN: { + + std::cerr << " trying to setup. " ; + + if(!mTorManager->setupHiddenService()) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_FAIL ; + std::cerr << "Failed." << std::endl; + return mHiddenServiceStatus ; + } + std::cerr << "Done." << std::endl; + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_REQUESTED ; + return mHiddenServiceStatus ; + } + + case HIDDEN_SERVICE_STATUS_REQUESTED: { + QList hidden_services = mTorManager->control()->hiddenServices(); + + if(hidden_services.empty()) + { + std::cerr << "Not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + else + { + if(mHiddenService == NULL) + mHiddenService = *(hidden_services.begin()) ; + + Tor::HiddenService::Status hss = mHiddenService->status(); + + std::cerr << "New service acquired. Status is " << hss ; + + if(hss == Tor::HiddenService::Online) + { + mHiddenServiceStatus = HIDDEN_SERVICE_STATUS_OK ; + std::cerr << ": published and running!" << std::endl; + + return mHiddenServiceStatus ; + } + else + { + std::cerr << ": not ready yet." << std::endl; + return mHiddenServiceStatus ; + } + } + } + case HIDDEN_SERVICE_STATUS_OK : + std::cerr << "New service acquired." << std::endl; + return mHiddenServiceStatus ; + } +} + diff --git a/retroshare-gui/src/gui/TorControl/TorControlWindow.h b/retroshare-gui/src/gui/TorControl/TorControlWindow.h new file mode 100644 index 000000000..c4e8ce522 --- /dev/null +++ b/retroshare-gui/src/gui/TorControl/TorControlWindow.h @@ -0,0 +1,48 @@ +#include "ui_TorControlWindow.h" + +class QTcpServer ; + +namespace Tor { + class HiddenService ; + class TorManager ; +} + +class TorControlDialog: public QWidget, public Ui::TorControlDialog +{ + Q_OBJECT + +public: + TorControlDialog(Tor::TorManager *tm,QWidget *parent =NULL); + + enum TorStatus { + TOR_STATUS_UNKNOWN = 0x00, + TOR_STATUS_OK = 0x01, + TOR_STATUS_FAIL = 0x02 + }; + + enum HiddenServiceStatus { + HIDDEN_SERVICE_STATUS_UNKNOWN = 0x00, // no information known. + HIDDEN_SERVICE_STATUS_FAIL = 0x01, // some error occurred + HIDDEN_SERVICE_STATUS_REQUESTED = 0x02, // one service at least has been requested. Still being tested. + HIDDEN_SERVICE_STATUS_OK = 0x03 // one service responds and has been tested + }; + + // Should be called multiple times in a loop until it returns something else than *_UNKNOWN + + TorStatus checkForTor(QString& error_msg) ; + HiddenServiceStatus checkForHiddenService() ; + +protected slots: + void showLog(); + void statusChanged(); + void onIncomingConnection(); + +private: + QString mErrorMsg ; + HiddenServiceStatus mHiddenServiceStatus ; + + Tor::TorManager *mTorManager ; + Tor::HiddenService *mHiddenService ; + + QTcpServer *mIncomingServer ; +}; diff --git a/retroshare-gui/src/gui/TorControl/TorControlWindow.ui b/retroshare-gui/src/gui/TorControl/TorControlWindow.ui new file mode 100644 index 000000000..602146641 --- /dev/null +++ b/retroshare-gui/src/gui/TorControl/TorControlWindow.ui @@ -0,0 +1,134 @@ + + + TorControlDialog + + + + 0 + 0 + 600 + 228 + + + + + 0 + 0 + + + + Dialog + + + + + + + 75 + true + + + + Setting up Tor... + + + Qt::AlignCenter + + + + + + + + + + + + :/icons/tor-logo.png + + + false + + + + + + + + + Tor status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Unknown + + + + + + + Not started + + + + + + + Hidden service address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Tor bootstrap status: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + Onion address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Not set + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui index 9de9e6a3e..28f2e41ce 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiAddDialog.ui @@ -51,7 +51,7 @@
- + Travel @@ -110,7 +110,7 @@ - + 0 @@ -135,7 +135,7 @@ - + 0 @@ -170,7 +170,7 @@ - + 0 @@ -195,7 +195,7 @@ - + 0 @@ -266,6 +266,13 @@ + + + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
+
diff --git a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui index 7a86e6488..056e0a859 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiDialog.ui @@ -50,7 +50,7 @@ 510 - + 0 @@ -63,33 +63,48 @@ 0 - - - - - 0 - 150 - + + + + Qt::Vertical - - - - - - - Page Name + + + + 0 + 0 + - - - - Page Id + + + 0 + 150 + - - - - Orig Id + + + + + 0 + 0 + - + + + Page Name + + + + + Page Id + + + + + Orig Id + + + diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp index 1918df882..8dd0404d6 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.cpp @@ -56,18 +56,18 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) { ui.setupUi(this); - connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelEdit( void ) ) ); - connect(ui.pushButton_Revert, SIGNAL( clicked( void ) ), this, SLOT( revertEdit( void ) ) ); - connect(ui.pushButton_Submit, SIGNAL( clicked( void ) ), this, SLOT( submitEdit( void ) ) ); - connect(ui.pushButton_Preview, SIGNAL( clicked( void ) ), this, SLOT( previewToggle( void ) ) ); - connect(ui.pushButton_History, SIGNAL( clicked( void ) ), this, SLOT( historyToggle( void ) ) ); - connect(ui.toolButton_Show, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); - connect(ui.toolButton_Hide, SIGNAL( clicked( void ) ), this, SLOT( detailsToggle( void ) ) ); - connect(ui.textEdit, SIGNAL( textChanged( void ) ), this, SLOT( textChanged( void ) ) ); - connect(ui.checkBox_OldHistory, SIGNAL( clicked( void ) ), this, SLOT( oldHistoryChanged( void ) ) ); - connect(ui.checkBox_Merge, SIGNAL( clicked( void ) ), this, SLOT( mergeModeToggle( void ) ) ); - connect(ui.pushButton_Merge, SIGNAL( clicked( void ) ), this, SLOT( generateMerge( void ) ) ); - connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged( void ) ), this, SLOT( historySelected( void ) ) ); + connect(ui.pushButton_Cancel, SIGNAL( clicked() ), this, SLOT( cancelEdit() ) ); + connect(ui.pushButton_Revert, SIGNAL( clicked() ), this, SLOT( revertEdit() ) ); + connect(ui.postButton, SIGNAL( clicked() ), this, SLOT( submitEdit() ) ); + connect(ui.pushButton_Preview, SIGNAL( clicked() ), this, SLOT( previewToggle() ) ); + connect(ui.pushButton_History, SIGNAL( clicked() ), this, SLOT( historyToggle() ) ); + connect(ui.toolButton_Show, SIGNAL( clicked() ), this, SLOT( detailsToggle() ) ); + connect(ui.toolButton_Hide, SIGNAL( clicked() ), this, SLOT( detailsToggle() ) ); + connect(ui.textEdit, SIGNAL( textChanged() ), this, SLOT( textChanged() ) ); + connect(ui.checkBox_OldHistory, SIGNAL( clicked() ), this, SLOT( oldHistoryChanged() ) ); + connect(ui.checkBox_Merge, SIGNAL( clicked() ), this, SLOT( mergeModeToggle() ) ); + connect(ui.pushButton_Merge, SIGNAL( clicked() ), this, SLOT( generateMerge() ) ); + connect(ui.treeWidget_History, SIGNAL( itemSelectionChanged() ), this, SLOT( historySelected() ) ); mWikiQueue = new TokenQueue(rsWiki->getTokenService(), this); @@ -88,6 +88,7 @@ WikiEditDialog::WikiEditDialog(QWidget *parent) ui.toolButton_Show->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png"))); ui.toolButton_Hide->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png"))); ui.pushButton_Preview->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/search.png"))); + ui.pushButton_History->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/history-clock-white.png"))); ui.checkBox_OldHistory->setChecked(false); mOldHistoryEnabled = false; @@ -124,7 +125,7 @@ void WikiEditDialog::textChanged() mTextChanged = true; ui.pushButton_Revert->setEnabled(true); - ui.pushButton_Submit->setEnabled(true); + ui.postButton->setEnabled(true); ui.label_Status->setText("Modified"); // Disable Selection in Edit History. @@ -141,7 +142,7 @@ void WikiEditDialog::textReset() mTextChanged = false; ui.pushButton_Revert->setEnabled(false); - ui.pushButton_Submit->setEnabled(false); + ui.postButton->setEnabled(false); ui.label_Status->setText("Original"); // Enable Selection in Edit History. @@ -294,12 +295,12 @@ void WikiEditDialog::historyToggle() if (ui.groupBox_History->isHidden()) { ui.groupBox_History->show(); - ui.pushButton_History->setText(tr("Hide Edit History")); + ui.pushButton_History->setToolTip(tr("Hide Edit History")); } else { ui.groupBox_History->hide(); - ui.pushButton_History->setText(tr("Show Edit History")); + ui.pushButton_History->setToolTip(tr("Show Edit History")); } } @@ -409,7 +410,7 @@ void WikiEditDialog::setPreviousPage(RsWikiSnapshot &page) void WikiEditDialog::setNewPage() { mNewPage = true; - mRepublishMode = false; + mRepublishMode = false; mHistoryLoaded = false; ui.lineEdit_Page->setText(""); ui.lineEdit_PrevVersion->setText(""); @@ -418,14 +419,14 @@ void WikiEditDialog::setNewPage() redrawPage(); ui.treeWidget_History->clear(); ui.groupBox_History->hide(); - ui.pushButton_History->setText(tr("Show Edit History")); + ui.pushButton_History->setToolTip(tr("Show Edit History")); - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/addpage.png")); + ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/addpage.png")); ui.headerFrame->setHeaderText(tr("Create New Wiki Page")); setWindowTitle(tr("Create New Wiki Page")); /* No need for for REQUIRED ID */ - ui.comboBox_IdChooser->loadIds(0, RsGxsId()); + ui.comboBox_IdChooser->loadIds(0, RsGxsId()); textReset(); } @@ -433,11 +434,11 @@ void WikiEditDialog::setNewPage() void WikiEditDialog::setRepublishMode(RsGxsMessageId &origMsgId) { - mRepublishMode = true; - mRepublishOrigId = origMsgId; - ui.pushButton_Submit->setText(tr("Republish")); + mRepublishMode = true; + mRepublishOrigId = origMsgId; + ui.postButton->setText(tr("Republish")); /* No need for for REQUIRED ID */ - ui.comboBox_IdChooser->loadIds(0, RsGxsId()); + ui.comboBox_IdChooser->loadIds(0, RsGxsId()); } diff --git a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui index 04ce626fa..5433f4a7f 100644 --- a/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui +++ b/retroshare-gui/src/gui/WikiPoos/WikiEditDialog.ui @@ -13,11 +13,20 @@ - - + + 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -31,14 +40,14 @@
- + QFrame::StyledPanel QFrame::Raised - + @@ -54,7 +63,7 @@ Page Edit History - + @@ -100,18 +109,21 @@ - + QFrame::StyledPanel QFrame::Raised - + - + + + 6 + @@ -120,7 +132,7 @@ - + Qt::Vertical @@ -145,7 +157,7 @@ - + 0 @@ -165,7 +177,7 @@ Wiki Group: - frame + formFrame @@ -242,16 +254,23 @@ - + + + + 15 + 75 + true + + - Show Edit History + History - + Qt::Horizontal @@ -286,7 +305,7 @@ - + @@ -302,7 +321,7 @@ - + Qt::Horizontal @@ -315,7 +334,14 @@ - + + + + 12 + 75 + true + + Submit @@ -345,8 +371,6 @@
gui/gxs/GxsIdChooser.h
- - - + diff --git a/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui b/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui index 5926e8d94..9427358cd 100644 --- a/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui +++ b/retroshare-gui/src/gui/advsearch/AdvancedSearchDialog.ui @@ -6,8 +6,8 @@ 0 0 - 838 - 130 + 297 + 138 @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -31,20 +31,14 @@ 0 - - - - 0 - 130 - - + QFrame::StyledPanel QFrame::Raised - + @@ -53,12 +47,6 @@ 1 - - - 800 - 60 - - false @@ -68,59 +56,15 @@ Qt::AlignJustify|Qt::AlignTop - + 0 - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 1 - 0 - - - - - 600 - 26 - - - - false - - - - - - - Qt::Vertical - - - - 20 - 9 - - - - - + 6 @@ -142,8 +86,8 @@ Add a further search criterion. - - :/images/add_24x24.png:/images/add_24x24.png + + :/icons/png/add.png:/icons/png/add.png @@ -174,16 +118,10 @@ - + Qt::Horizontal - - - 381 - 27 - - @@ -203,7 +141,7 @@
- + 0 @@ -227,6 +165,7 @@ + diff --git a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp index eb9b9ce83..da3d24057 100644 --- a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp +++ b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.cpp @@ -21,97 +21,79 @@ *******************************************************************************/ #include "advancedsearchdialog.h" + #include "gui/common/FilesDefs.h" +#include + AdvancedSearchDialog::AdvancedSearchDialog(QWidget * parent) : QDialog (parent) { - setupUi(this); - dialogLayout = this->layout(); - metrics = new QFontMetrics(this->font()); + setupUi(this); - // the list of expressions - expressions = new QList(); + QFontMetrics metrics = QFontMetrics(this->font()); + searchCriteriaBox_VL->setContentsMargins(2, metrics.height()/2, 2, 2); + addExprButton->setIconSize(QSize(metrics.height(),metrics.height())*1.5); + resetButton->setIconSize(QSize(metrics.height(),metrics.height())*1.5); - // a area for holding the objects - expressionsLayout = new QVBoxLayout(); - expressionsLayout->setSpacing(0); - expressionsLayout->setMargin(0); - expressionsLayout->setObjectName(QString::fromUtf8("expressionsLayout")); - expressionsFrame->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::MinimumExpanding); - expressionsFrame->setLayout(expressionsLayout); - - // we now add the first expression widgets to the dialog via a vertical - // layout - reset();//addNewExpression(); + // Save current default size as minimum to only add expresssions size to it. + this->adjustSize(); + this->setMinimumSize(this->size()); - connect (this->addExprButton, SIGNAL(clicked()), - this, SLOT(addNewExpression())); - connect (this->resetButton, SIGNAL(clicked()), - this, SLOT(reset())); - connect(this->executeButton, SIGNAL(clicked()), - this, SLOT(prepareSearch())); + // the list of expressions + expressions = new QList(); - addExprButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/add.png")); + // we now add the first expression widgets to the dialog + reset();//addNewExpression(); + + connect ( addExprButton, SIGNAL(clicked()) + , this, SLOT(addNewExpression())); + connect ( resetButton, SIGNAL(clicked()) + , this, SLOT(reset())); + connect ( searchButton, SIGNAL(clicked()) + , this, SLOT(prepareSearch())); } void AdvancedSearchDialog::addNewExpression() { - int sizeChange = metrics->height() + 26; + ExpressionWidget *expr = new ExpressionWidget(searchCriteriaBox, (expressions->size() == 0)); + expressions->append(expr); - ExpressionWidget *expr; - if (expressions->size() == 0) - { - //create an initial expression - expr = new ExpressionWidget(expressionsFrame, true); - } else { - expr = new ExpressionWidget(expressionsFrame); - } - - expressions->append(expr); - expressionsLayout->addWidget(expr, 1, Qt::AlignLeft); - - - connect(expr, SIGNAL(signalDelete(ExpressionWidget*)), - this, SLOT(deleteExpression(ExpressionWidget*))); - - //expressionsLayout->invalidate(); - //searchCriteriaBox->setMinimumSize(searchCriteriaBox->minimumWidth(), - // searchCriteriaBox->minimumHeight() + sizeChange); - //searchCriteriaBox->adjustSize(); - expressionsFrame->adjustSize(); - this->setMinimumSize(this->minimumWidth(), this->minimumHeight()+sizeChange); - this->adjustSize(); + searchCriteriaBox_VL->addWidget(expr); + searchCriteriaBox_VL->setAlignment(Qt::AlignTop); + expr->adjustSize(); + if (searchCriteriaBox->minimumWidth() < expr->minimumWidth()) + searchCriteriaBox->setMinimumWidth(expr->minimumWidth()); + QSize exprHeight = QSize(0,expr->height()); + + connect( expr, SIGNAL(signalDelete(ExpressionWidget*)) + , this, SLOT(deleteExpression(ExpressionWidget*)) ); + + this->setMinimumSize(this->minimumSize() + exprHeight); + int marg = gradFrame_GL->contentsMargins().left()+gradFrame_GL->contentsMargins().right(); + marg += this->contentsMargins().left()+this->contentsMargins().right(); + if (this->minimumWidth() < (searchCriteriaBox->minimumWidth()+marg)) + this->setMinimumWidth(searchCriteriaBox->minimumWidth()+marg); } void AdvancedSearchDialog::deleteExpression(ExpressionWidget* expr) { - int sizeChange = metrics->height() + 26; - - expressions->removeAll(expr); - expr->hide(); - expressionsLayout->removeWidget(expr); - delete expr; - - expressionsLayout->invalidate(); - //searchCriteriaBox->setMinimumSize(searchCriteriaBox->minimumWidth(), - // searchCriteriaBox->minimumHeight() - sizeChange); - //searchCriteriaBox->adjustSize(); - expressionsFrame->adjustSize(); - this->setMinimumSize(this->minimumWidth(), this->minimumHeight()-sizeChange); - this->adjustSize(); + QSize exprHeight = QSize(0,expr->height()); + + expressions->removeAll(expr); + expr->hide(); + searchCriteriaBox_VL->removeWidget(expr); + delete expr; + + this->setMinimumSize(this->minimumSize() - exprHeight); + this->resize(this->size() - exprHeight); } void AdvancedSearchDialog::reset() { - ExpressionWidget *expr; while (!expressions->isEmpty()) - { - expr = expressions->takeLast(); - deleteExpression(expr); - } + deleteExpression(expressions->takeLast()); // now add a new default expressions addNewExpression(); @@ -129,7 +111,6 @@ RsRegularExpression::Expression * AdvancedSearchDialog::getRsExpr() // process the special case: first expression wholeExpression = expressions->at(0)->getRsExpression(); - // iterate through the items in elements and #warning Phenom (2017-07-21): I don t know if it is a real memLeak for wholeExpression. If not remove this warning and add a comment how it is deleted. @@ -140,21 +121,20 @@ RsRegularExpression::Expression * AdvancedSearchDialog::getRsExpr() wholeExpression = new RsRegularExpression::CompoundExpression(expressions->at(i)->getOperator(), wholeExpression, expressions->at(i)->getRsExpression()); - } + } return wholeExpression; } QString AdvancedSearchDialog::getSearchAsString() { QString str = expressions->at(0)->toString(); - // iterate through the items in elements and for (int i = 1; i < expressions->size(); ++i) { // extract the expression information and compound it with the // first expression str += QString(" ") + expressions->at(i)->toString(); - } + } return str; } diff --git a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h index 317809e6f..25ea74129 100644 --- a/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h +++ b/retroshare-gui/src/gui/advsearch/advancedsearchdialog.h @@ -22,13 +22,10 @@ #ifndef _AdvancedSearch_h_ #define _AdvancedSearch_h_ -#include -#include -#include -#include -#include #include "ui_AdvancedSearchDialog.h" + #include "expressionwidget.h" + #include class AdvancedSearchDialog : public QDialog, public Ui::AdvancedSearchDialog @@ -49,10 +46,7 @@ private slots: void prepareSearch(); private: - QLayout * dialogLayout; - QVBoxLayout * expressionsLayout; QList * expressions; - QFontMetrics * metrics; }; #endif // _AdvancedSearch_h_ diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.cpp b/retroshare-gui/src/gui/advsearch/expressionwidget.cpp index 2b6ad3b2e..f6b150065 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.cpp +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.cpp @@ -21,107 +21,60 @@ *******************************************************************************/ #include "expressionwidget.h" -ExpressionWidget::ExpressionWidget(QWidget * parent, bool initial) : QWidget(parent) +ExpressionWidget::ExpressionWidget(QWidget * parent, bool initial) + : QWidget(parent) + , isFirst (initial), inRangedConfig(false) + , searchType (NameSearch) // the default search type { - setupUi(this); - - inRangedConfig = false; - - // the default search type - searchType = NameSearch; - - exprLayout = this->layout(); - - exprOpFrame->setLayout (createLayout()); - exprTermFrame->setLayout (createLayout()); - exprConditionFrame->setLayout (createLayout()); - exprParamFrame->setLayout (createLayout()); - exprParamFrame->setSizePolicy(QSizePolicy::MinimumExpanding, - QSizePolicy::Fixed); - - elements = new QList(); - - exprOpElem = new ExprOpElement(); - exprOpFrame->layout()->addWidget(exprOpElem); - elements->append(exprOpElem); - - exprTermElem = new ExprTermsElement(); - exprTermFrame->layout()->addWidget(exprTermElem); - elements->append(exprTermElem); - connect (exprTermElem, SIGNAL(currentIndexChanged(int)), - this, SLOT (adjustExprForTermType(int))); - - exprCondElem = new ExprConditionElement(searchType); - exprConditionFrame->layout()->addWidget(exprCondElem); - elements->append(exprCondElem); - connect (exprCondElem, SIGNAL (currentIndexChanged(int)), - this, SLOT (adjustExprForConditionType(int))); - - exprParamElem= new ExprParamElement(searchType); - exprParamFrame->layout()->addWidget(exprParamElem); - elements->append(exprParamElem); - - // set up the default search: a search on name - adjustExprForTermType(searchType); - isFirst = initial; - deleteExprButton ->setVisible(!isFirst); - exprOpElem ->setVisible(!isFirst); - exprTermFrame ->show(); - exprConditionFrame ->show(); - exprParamFrame ->show(); - - // connect the delete button signal - connect (deleteExprButton, SIGNAL (clicked()), - this, SLOT(deleteExpression())); - - this->show(); -} + setupUi(this); -QLayout * ExpressionWidget::createLayout(QWidget * parent) -{ - QHBoxLayout * hboxLayout; - if (parent == 0) - { - hboxLayout = new QHBoxLayout(); - } else { - hboxLayout = new QHBoxLayout(parent); - } - hboxLayout->setSpacing(0); - hboxLayout->setMargin(0); - return hboxLayout; + connect (exprTermElem, SIGNAL(currentIndexChanged(int)), + this, SLOT (adjustExprForTermType(int))); + + connect (exprCondElem, SIGNAL (currentIndexChanged(int)), + this, SLOT (adjustExprForConditionType(int))); + + // set up the default search: a search on name + adjustExprForTermType(searchType); + exprOpElem ->setVisible(!isFirst); + deleteExprButton ->setVisible(!isFirst); + + // connect the delete button signal + connect (deleteExprButton, SIGNAL (clicked()), + this, SLOT(deleteExpression()) ); + + this->show(); } bool ExpressionWidget::isStringSearchExpression() { - return (searchType == NameSearch || searchType == PathSearch - || searchType == ExtSearch || searchType == HashSearch); + return ( searchType == NameSearch || searchType == PathSearch + || searchType == ExtSearch || searchType == HashSearch); } void ExpressionWidget::adjustExprForTermType(int index) { - ExprSearchType type = GuiExprElement::TermsIndexMap[index]; - searchType = type; - - // now adjust the relevant elements - // the condition combobox - exprCondElem->adjustForSearchType(type); - - // the parameter expression: can be a date, 1-2 edit fields - // or a size with units etc - exprParamElem->adjustForSearchType(type); - exprParamFrame->adjustSize(); - - exprLayout->invalidate(); - this->adjustSize(); + ExprSearchType type = GuiExprElement::TermsIndexMap[index]; + searchType = type; + + // now adjust the relevant elements + // the condition combobox + exprCondElem->adjustForSearchType(type); + + // the parameter expression: can be a date, 1-2 edit fields + // or a size with units etc + exprParamElem->adjustForSearchType(type); + + this->setMinimumWidth( exprOpElem->width()+exprTermElem->width() + + exprCondElem->width()+exprParamElem->width() + + deleteExprButton->width() ); } void ExpressionWidget::adjustExprForConditionType(int newCondition) { - // we adjust the appearance for a ranged selection - inRangedConfig = (newCondition == GuiExprElement::RANGE_INDEX); - exprParamElem->setRangedSearch(inRangedConfig); - exprParamFrame->layout()->invalidate(); - exprParamFrame->adjustSize(); + // we adjust the appearance for a ranged selection + inRangedConfig = (newCondition == GuiExprElement::RANGE_INDEX); + exprParamElem->setRangedSearch(inRangedConfig); } void ExpressionWidget::deleteExpression() @@ -156,7 +109,11 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() if (isStringSearchExpression()) { QString txt = exprParamElem->getStrSearchValue(); +#if QT_VERSION < QT_VERSION_CHECK(5,15,0) QStringList words = txt.split(" ", QString::SkipEmptyParts); +#else + QStringList words = txt.split(" ", Qt::SkipEmptyParts); +#endif for (int i = 0; i < words.size(); ++i) wordList.push_back(words.at(i).toUtf8().constData()); } else if (inRangedConfig){ @@ -165,12 +122,12 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() highVal = exprParamElem->getIntHighValue(); if (lowVal >highVal) { - lowVal = lowVal^highVal; // csoler: wow, that is some style! - highVal = lowVal^highVal; - lowVal = lowVal^highVal; + auto tmp=lowVal; + lowVal = highVal; + highVal = tmp; } } - + switch (searchType) { case NameSearch: @@ -193,11 +150,33 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() wordList); break; case DateSearch: - if (inRangedConfig) { - expr = new RsRegularExpression::DateExpression(exprCondElem->getRelOperator(), checkedConversion(lowVal), checkedConversion(highVal)); - } else { - expr = new RsRegularExpression::DateExpression(exprCondElem->getRelOperator(), checkedConversion(exprParamElem->getIntValue())); - } + switch(exprCondElem->getRelOperator()) // we need to convert expressions so that the delta is 1 day (i.e. 86400 secs) + { + // The conditions below account for 3 things: + // - the swap between variables in rsexpr.h:214 + // - the swap of variables when calling getRelOperator() (See guiexprelement.cpp:166) + // - the fact that some comparisions in the unit of days may add 86400 seconds. + + default: + case RsRegularExpression::Equals: + expr = new RsRegularExpression::DateExpression(RsRegularExpression::InRange, checkedConversion(exprParamElem->getIntValue()), checkedConversion(86400+exprParamElem->getIntValue())); + break; + case RsRegularExpression::InRange: + expr = new RsRegularExpression::DateExpression(RsRegularExpression::InRange, checkedConversion(lowVal), 86400+checkedConversion(highVal)); + break; + case RsRegularExpression::Greater: // means we expect file.date() < some day D. So file.date() < D, meaning Exp=Greater + expr = new RsRegularExpression::DateExpression(RsRegularExpression::Greater,checkedConversion(exprParamElem->getIntValue())); + break; + case RsRegularExpression::SmallerEquals: // means we expect file.date() >= some day D. So file.date() >= D, meaning Exp=SmallerEquals + expr = new RsRegularExpression::DateExpression(RsRegularExpression::SmallerEquals,checkedConversion(exprParamElem->getIntValue())); + break; + case RsRegularExpression::Smaller: // means we expect file.date() > some day D. So file.date() >= D+86400, meaning Exp=SmallerEquals + expr = new RsRegularExpression::DateExpression(RsRegularExpression::SmallerEquals, checkedConversion(86400+exprParamElem->getIntValue()-1)); + break; + case RsRegularExpression::GreaterEquals: // means we expect file.date() <= some day D. So file.date() < D+86400, meaning Exp=Greater + expr = new RsRegularExpression::DateExpression(RsRegularExpression::Greater, checkedConversion(86400+exprParamElem->getIntValue())); + break; + } break; case PopSearch: if (inRangedConfig) { @@ -208,20 +187,42 @@ RsRegularExpression::Expression* ExpressionWidget::getRsExpression() break; case SizeSearch: if (inRangedConfig) - { - if(lowVal >= (uint64_t)(1024*1024*1024) || highVal >= (uint64_t)(1024*1024*1024)) - expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(lowVal / (1024*1024)), (int)(highVal / (1024*1024))); - else - expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), lowVal, highVal); - } - else - { - uint64_t s = exprParamElem->getIntValue() ; + { + if(lowVal >= (uint64_t)(1024*1024*1024) || highVal >= (uint64_t)(1024*1024*1024)) + expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(lowVal / (1024*1024)), (int)(highVal / (1024*1024))); + else + expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), lowVal, highVal); + } + else + { + uint64_t s = exprParamElem->getIntValue() ; + auto cond = exprCondElem->getRelOperator(); + bool MB = false; - if(s >= (uint64_t)(1024*1024*1024)) - expr = new RsRegularExpression::SizeExpressionMB(exprCondElem->getRelOperator(), (int)(s/(1024*1024))) ; - else - expr = new RsRegularExpression::SizeExpression(exprCondElem->getRelOperator(), (int)s) ; + if(s >= (uint64_t)(1024*1024*1024)) + { + MB=true; + s >>= 20; + } + + // Specific case for Equal operator, which we convert to a range, so as to avoid matching arbitrary digits + + if(cond == RsRegularExpression::Equals) + { + // Now compute a proper interval. There is no optimal solution, so we aim for the simplest: add/remove 20% of the initial value. + + if(MB) + expr = new RsRegularExpression::SizeExpressionMB(RsRegularExpression::InRange, (int)(s*0.8) , (int)(s*1.2)); + else + expr = new RsRegularExpression::SizeExpression(RsRegularExpression::InRange, (int)(s*0.8) , (int)(s*1.2)); + } + else + { + if(MB) + expr = new RsRegularExpression::SizeExpressionMB(cond, (int)s); + else + expr = new RsRegularExpression::SizeExpression(cond, (int)s) ; + } } break; }; diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.h b/retroshare-gui/src/gui/advsearch/expressionwidget.h index 40ef3ec47..109ea2a35 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.h +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.h @@ -21,14 +21,16 @@ *******************************************************************************/ #ifndef _ExpressionWidget_h_ #define _ExpressionWidget_h_ -#include -#include -#include -#include -#include "guiexprelement.h" #include "ui_expressionwidget.h" +#include "guiexprelement.h" + +#include + +#include + +#include /** Represents an Advanced Search GUI Expression object which acts as a container @@ -74,20 +76,10 @@ private slots: private: - QLayout * createLayout(QWidget* parent = 0); - bool isStringSearchExpression(); - - QList * elements; - QLayout * exprLayout; - ExprOpElement * exprOpElem; - ExprTermsElement * exprTermElem; - ExprConditionElement * exprCondElem; - ExprParamElement* exprParamElem; - - bool inRangedConfig; bool isFirst; + bool inRangedConfig; ExprSearchType searchType; }; diff --git a/retroshare-gui/src/gui/advsearch/expressionwidget.ui b/retroshare-gui/src/gui/advsearch/expressionwidget.ui index 9e7d2d780..5b8584f00 100644 --- a/retroshare-gui/src/gui/advsearch/expressionwidget.ui +++ b/retroshare-gui/src/gui/advsearch/expressionwidget.ui @@ -2,104 +2,33 @@ ExpressionWidget - - - 0 - 0 - 800 - 34 - - - + 0 0 - - - 800 - 30 - - - - - 16777215 - 55 - - Expression Widget - - 6 - - - 6 - - + + + + + + + + + + - + 0 0 - - - 90 - 26 - - - - - - - - - 0 - 0 - - - - - 100 - 26 - - - - - - - - - 0 - 0 - - - - - 180 - 26 - - - - - - - - - 1 - 0 - - - - - 350 - 26 - - @@ -113,21 +42,34 @@ - - - - Qt::Horizontal - - - - 0 - 30 - - - -
+ + + ExprOpElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprTermsElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprConditionElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+ + ExprParamElement + QFrame +
gui/advsearch/guiexprelement.h
+ 1 +
+
diff --git a/retroshare-gui/src/gui/advsearch/guiexprelement.cpp b/retroshare-gui/src/gui/advsearch/guiexprelement.cpp index 44d1350a4..5dd138186 100644 --- a/retroshare-gui/src/gui/advsearch/guiexprelement.cpp +++ b/retroshare-gui/src/gui/advsearch/guiexprelement.cpp @@ -21,14 +21,10 @@ *******************************************************************************/ #include "guiexprelement.h" -#define STR_FIELDS_MIN_WIDTH 200 -#define SIZE_FIELDS_MIN_WIDTH 80 -#define DATE_FIELDS_MIN_WIDTH 100 -#define FIELDS_MIN_HEIGHT 26 - -#define LOGICAL_OP_CB_WIDTH 70 -#define STD_CB_WIDTH 90 -#define CONDITION_CB_WIDTH 170 +#define STR_FIELDS_MIN_WFACTOR 20.0 +#define SIZE_FIELDS_MIN_WFACTOR 8.0 +#define DATE_FIELDS_MIN_WFACTOR 10.0 +#define FIELDS_MIN_HFACTOR 1.2 const int GuiExprElement::AND_INDEX = 0; const int GuiExprElement::OR_INDEX = 1; @@ -37,10 +33,10 @@ const int GuiExprElement::XOR_INDEX = 2; const int GuiExprElement::NAME_INDEX = 0; const int GuiExprElement::PATH_INDEX = 1; const int GuiExprElement::EXT_INDEX = 2; -const int GuiExprElement::HASH_INDEX = 3; -/*const int GuiExprElement::KEYWORDS_INDEX = ???; -const int GuiExprElement::COMMENTS_INDEX = ???; -const int GuiExprElement::META_INDEX = ???;*/ +const int GuiExprElement::HASH_INDEX = 3; +//const int GuiExprElement::KEYWORDS_INDEX = ???; +//const int GuiExprElement::COMMENTS_INDEX = ???; +//const int GuiExprElement::META_INDEX = ???; const int GuiExprElement::DATE_INDEX = 4; const int GuiExprElement::SIZE_INDEX = 5; const int GuiExprElement::POP_INDEX = 6; @@ -76,14 +72,13 @@ bool GuiExprElement::initialised = false; GuiExprElement::GuiExprElement(QWidget * parent) - : QWidget(parent) + : QFrame(parent), searchType(NameSearch) { - if (!GuiExprElement::initialised) - { - initialiseOptionsLists(); - } - searchType = NameSearch; + if (!GuiExprElement::initialised) + initialiseOptionsLists(); + setObjectName("trans_InternalFrame"); + createLayout(this); } @@ -96,7 +91,7 @@ void GuiExprElement::initialiseOptionsLists() const QString NAME = tr("Name"); const QString PATH = tr("Path"); const QString EXT = tr("Extension"); - const QString HASH = tr("Hash"); + const QString HASH = tr("Hash"); //const QString KEYWORDS= tr("Keywords"); //const QString COMMENTS= tr("Comments"); //const QString META = tr("Meta"); @@ -128,7 +123,7 @@ void GuiExprElement::initialiseOptionsLists() //GuiExprElement::searchTermsOptionsList.append(META); GuiExprElement::searchTermsOptionsList.append(DATE); GuiExprElement::searchTermsOptionsList.append(SIZE); -// GuiExprElement::searchTermsOptionsList.append(POP); + //GuiExprElement::searchTermsOptionsList.append(POP); GuiExprElement::stringOptionsList.append(CONTAINS); GuiExprElement::stringOptionsList.append(CONTALL); @@ -160,18 +155,19 @@ void GuiExprElement::initialiseOptionsLists() /* W A R N I N G !!!! the cb elements correspond to their inverse rel op counterparts in rsexpr.h due to the nature of - the implementation.there + the implementation. For example consider "size greater than 100kb" selected in the GUI. The rsexpr.cc impl returns true if the CONDITION specified is greater than the file size passed as argument as rsexpr iterates through the files. So, the user wants files that are greater than 100kb but the impl returns - files where the condition is greater than the file size i.e. files whose size is less than or equal to the condition + files where the condition is greater than the file size i.e. files whose size is less than to the condition Therefore we invert the mapping of rel conditions here to match the behaviour of the impl. + Also the Equal nature of comparisons should be kept, since = is symmetric. */ - GuiExprElement::relConditionIndexMap[GuiExprElement::LT_INDEX] = RsRegularExpression::GreaterEquals; - GuiExprElement::relConditionIndexMap[GuiExprElement::LTE_INDEX] = RsRegularExpression::Greater; + GuiExprElement::relConditionIndexMap[GuiExprElement::LT_INDEX] = RsRegularExpression::Greater; + GuiExprElement::relConditionIndexMap[GuiExprElement::LTE_INDEX] = RsRegularExpression::GreaterEquals; GuiExprElement::relConditionIndexMap[GuiExprElement::EQUAL_INDEX] = RsRegularExpression::Equals; - GuiExprElement::relConditionIndexMap[GuiExprElement::GTE_INDEX] = RsRegularExpression::Smaller; - GuiExprElement::relConditionIndexMap[GuiExprElement::GT_INDEX] = RsRegularExpression::SmallerEquals; + GuiExprElement::relConditionIndexMap[GuiExprElement::GTE_INDEX] = RsRegularExpression::SmallerEquals; + GuiExprElement::relConditionIndexMap[GuiExprElement::GT_INDEX] = RsRegularExpression::Smaller; GuiExprElement::relConditionIndexMap[GuiExprElement::RANGE_INDEX] = RsRegularExpression::InRange; // the string to index map @@ -220,24 +216,29 @@ QStringList GuiExprElement::getConditionOptions(ExprSearchType t) return QStringList(); } -QHBoxLayout * GuiExprElement::createLayout(QWidget * parent) +QHBoxLayout * GuiExprElement::createLayout(QWidget * parent /*= nullptr*/) { - QHBoxLayout * hboxLayout; - if (parent == 0) - { - hboxLayout = new QHBoxLayout(); - } else { - hboxLayout = new QHBoxLayout(parent); - } + QHBoxLayout * hboxLayout = new QHBoxLayout(parent); hboxLayout->setMargin(0); hboxLayout->setSpacing(0); return hboxLayout; } +QSize GuiExprElement::getMinSize(float widthFactor/*=1*/, float heightFactor/*=1*/) +{ + QFontMetrics fm = QFontMetrics(font()); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + QSize size = QSize(fm.width("_")*widthFactor, fm.height()*heightFactor); +#else + QSize size = QSize(fm.horizontalAdvance("_")*widthFactor, fm.height()*heightFactor); +#endif + return size; +} + bool GuiExprElement::isStringSearchExpression() { - return (searchType == NameSearch || searchType == PathSearch - || searchType == ExtSearch || searchType == HashSearch); + return (searchType == NameSearch || searchType == PathSearch + || searchType == ExtSearch || searchType == HashSearch); } @@ -245,14 +246,12 @@ bool GuiExprElement::isStringSearchExpression() /* *********** L O G I C A L O P E L E M E N T ******************/ /* ********************************************************************/ ExprOpElement::ExprOpElement(QWidget * parent) - : GuiExprElement(parent) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(LOGICAL_OP_CB_WIDTH, FIELDS_MIN_HEIGHT); - cb->addItems(GuiExprElement::exprOpsList); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + cb->addItems(GuiExprElement::exprOpsList); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } QString ExprOpElement::toString() @@ -271,16 +270,14 @@ RsRegularExpression::LogicalOperator ExprOpElement::getLogicalOperator() /* *********** T E R M S E L E M E N T ******************/ /* **********************************************************/ ExprTermsElement::ExprTermsElement(QWidget * parent) - : GuiExprElement(parent) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(STD_CB_WIDTH, FIELDS_MIN_HEIGHT); - connect (cb, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - cb->addItems(GuiExprElement::searchTermsOptionsList); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + connect (cb, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + cb->addItems(GuiExprElement::searchTermsOptionsList); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } QString ExprTermsElement::toString() { @@ -290,17 +287,15 @@ QString ExprTermsElement::toString() /* ******************************************************************/ /* *********** C O N D I T I O N E L E M E N T ******************/ /* ******************************************************************/ -ExprConditionElement::ExprConditionElement(ExprSearchType type, QWidget * parent) - : GuiExprElement(parent) +ExprConditionElement::ExprConditionElement(QWidget * parent, ExprSearchType type) + : GuiExprElement(parent) { - internalframe = new QFrame(this); - internalframe->setLayout(createLayout()); - cb = new QComboBox(this); - cb->setMinimumSize(CONDITION_CB_WIDTH, FIELDS_MIN_HEIGHT); - connect (cb, SIGNAL(currentIndexChanged(int)), - this, SIGNAL(currentIndexChanged(int))); - cb->addItems(getConditionOptions(type)); - internalframe->layout()->addWidget(cb); + cb = new RSComboBox(this); + connect (cb, SIGNAL(currentIndexChanged(int)), + this, SIGNAL(currentIndexChanged(int))); + cb->addItems(getConditionOptions(type)); + layout()->addWidget(cb); + setMinimumSize(cb->sizeHint()); } @@ -334,174 +329,189 @@ void ExprConditionElement::adjustForSearchType(ExprSearchType type) /* **********************************************************/ /* *********** P A R A M E L E M E N T ******************/ /* **********************************************************/ -ExprParamElement::ExprParamElement(ExprSearchType type, QWidget * parent) - : GuiExprElement(parent) +ExprParamElement::ExprParamElement(QWidget * parent, ExprSearchType type) + : GuiExprElement(parent), inRangedConfig(false) { - internalframe = new QFrame(this); - internalframe->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - internalframe->setLayout(createLayout()); - inRangedConfig = false; - searchType = type; - adjustForSearchType(type); + adjustForSearchType(type); } QString ExprParamElement::toString() { - QString str = ""; - if (isStringSearchExpression()) - { - str = QString("\"") + getStrSearchValue() + QString("\""); - // we don't bother with case if hash search - if (searchType != HashSearch) { - str += (ignoreCase() ? QString(" (ignore case)") - : QString(" (case sensitive)")); + QString str = ""; + if (isStringSearchExpression()) + { + str = QString("\"") + getStrSearchValue() + QString("\""); + // we don't bother with case if hash search + if (searchType != HashSearch) { + str += (ignoreCase() ? QString(" (ignore case)") + : QString(" (case sensitive)")); + } + } else + { + if (searchType == DateSearch) { + QDateEdit * dateEdit = findChild ("param1"); + str = dateEdit->text(); + if (inRangedConfig) + { + str += QString(" ") + tr("to") + QString(" "); + dateEdit = findChild ("param2"); + str += dateEdit->text(); + } + } else if (searchType == SizeSearch) + { + QLineEdit * lineEditSize = findChild("param1"); + str = ("" == lineEditSize->text()) ? "0" + : lineEditSize->text(); + RSComboBox * cb = findChild ("unitsCb1"); + str += QString(" ") + cb->itemText(cb->currentIndex()); + if (inRangedConfig) + { + str += QString(" ") + tr("to") + QString(" "); + lineEditSize = findChild("param2"); + str += ("" == lineEditSize->text()) ? "0" + : lineEditSize->text(); + cb = findChild ("unitsCb2"); + str += QString(" ") + cb->itemText(cb->currentIndex()); + } + } } - } else - { - if (searchType == DateSearch) { - QDateEdit * dateEdit = internalframe->findChild ("param1"); - str = dateEdit->text(); - if (inRangedConfig) - { - str += QString(" ") + tr("to") + QString(" "); - dateEdit = internalframe->findChild ("param2"); - str += dateEdit->text(); - } - } else if (searchType == SizeSearch) - { - QLineEdit * lineEditSize = internalframe->findChild("param1"); - str = ("" == lineEditSize->text()) ? "0" - : lineEditSize->text(); - QComboBox * cb = internalframe->findChild ("unitsCb1"); - str += QString(" ") + cb->itemText(cb->currentIndex()); - if (inRangedConfig) - { - str += QString(" ") + tr("to") + QString(" "); - lineEditSize = internalframe->findChild("param2"); - str += ("" == lineEditSize->text()) ? "0" - : lineEditSize->text(); - cb = internalframe->findChild ("unitsCb2"); - str += QString(" ") + cb->itemText(cb->currentIndex()); - } - } - } - return str; + return str; } +void clearLayout(QLayout *layout) { + if (layout == NULL) + return; + QLayoutItem *item; + while((item = layout->takeAt(0))) { + if (item->layout()) { + clearLayout(item->layout()); + delete item->layout(); + } + if (item->widget()) { + delete item->widget(); + } + delete item; + } +} void ExprParamElement::adjustForSearchType(ExprSearchType type) -{ - // record which search type is active - searchType = type; - QRegExp regExp("0|[1-9][0-9]*"); - numValidator = new QRegExpValidator(regExp, this); - QRegExp hexRegExp("[A-Fa-f0-9]*"); - hexValidator = new QRegExpValidator(hexRegExp, this); - - // remove all elements - QList children = internalframe->findChildren(); - QWidget* child; - QLayout * lay_out = internalframe->layout(); - while (!children.isEmpty()) - { - child = children.takeLast(); - child->hide(); - lay_out->removeWidget(child); - delete child; - } - delete lay_out; +{ + // record which search type is active + searchType = type; + QRegExp regExp("0|[1-9][0-9]*"); + numValidator = new QRegExpValidator(regExp, this); + QRegExp hexRegExp("[A-Fa-f0-9]*"); + hexValidator = new QRegExpValidator(hexRegExp, this); - QHBoxLayout* hbox = createLayout(); - internalframe->setLayout(hbox); - internalframe->setMinimumSize(320,26); + QHBoxLayout* hbox = static_cast(layout()); + clearLayout(hbox); + + setMinimumSize(getMinSize(STR_FIELDS_MIN_WFACTOR,FIELDS_MIN_HFACTOR) ); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + + if (isStringSearchExpression()) + { + // set up for default of a simple input field + QLineEdit* lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(STR_FIELDS_MIN_WFACTOR,FIELDS_MIN_HFACTOR)); + lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + lineEdit->setObjectName("param1"); + hbox->addWidget(lineEdit); + + hbox->addSpacing(9); + + QCheckBox* icCb = new QCheckBox(tr("ignore case"), this); + icCb->setMinimumSize(getMinSize(icCb->text().length()+2,FIELDS_MIN_HFACTOR)); + icCb->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + icCb->setObjectName("ignoreCaseCB"); + icCb->setCheckState(Qt::Checked); + hbox->addWidget(icCb); + + // hex search specifics: hidden case sensitivity and hex validator + if (searchType == HashSearch) { + icCb->hide(); + lineEdit->setValidator(hexValidator); + } + setMinimumSize(lineEdit->minimumSize() + + QSize((searchType != HashSearch ? icCb->minimumWidth() : 0),0) ); + + } else if (searchType == DateSearch) + { + QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), this); + dateEdit->setMinimumSize(getMinSize(DATE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dateEdit->setDisplayFormat(tr("yyyy-MM-dd")); + dateEdit->setObjectName("param1"); + dateEdit->setMinimumDate(QDate(1970, 1, 1)); + dateEdit->setMaximumDate(QDate(2099, 12,31)); + hbox->addWidget(dateEdit, Qt::AlignLeft); + hbox->addStretch(); + setMinimumSize(dateEdit->minimumSize()); + + } else if (searchType == SizeSearch) + { + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setMaximumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + lineEdit->setObjectName("param1"); + lineEdit->setValidator(numValidator); + hbox->addWidget(lineEdit, Qt::AlignLeft); + + hbox->addSpacing(9); + + RSComboBox * cb = new RSComboBox(this); + cb->setObjectName("unitsCb1"); + cb->addItem(tr("KB"), QVariant(1024)); + cb->addItem(tr("MB"), QVariant(1024*1024)); + cb->addItem(tr("GB"), QVariant(1024*1024*1024)); + hbox->addWidget(cb); + hbox->addStretch(); + setMinimumSize(lineEdit->minimumSize() + QSize(9,0) + + QSize(cb->minimumWidth(),0) ); - if (isStringSearchExpression()) - { - // set up for default of a simple input field - QLineEdit* lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(STR_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - lineEdit->setObjectName("param1"); - hbox->addWidget(lineEdit); - hbox->addSpacing(9); - QCheckBox* icCb = new QCheckBox(tr("ignore case"), internalframe); - icCb->setObjectName("ignoreCaseCB"); - icCb->setCheckState(Qt::Checked); - // hex search specifics: hidden case sensitivity and hex validator - if (searchType == HashSearch) { - icCb->hide(); - lineEdit->setValidator(hexValidator); } - hbox->addWidget(icCb); - hbox->addStretch(); - - } else if (searchType == DateSearch) - { - QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), internalframe); - dateEdit->setMinimumSize(DATE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - dateEdit->setDisplayFormat(tr("dd.MM.yyyy")); - dateEdit->setObjectName("param1"); - dateEdit->setMinimumDate(QDate(1970, 1, 1)); - dateEdit->setMaximumDate(QDate(2099, 12,31)); - hbox->addWidget(dateEdit, Qt::AlignLeft); - hbox->addStretch(); - } else if (searchType == SizeSearch) - { - QLineEdit * lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setMaximumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - lineEdit->setObjectName("param1"); - lineEdit->setValidator(numValidator); - hbox->addWidget(lineEdit, Qt::AlignLeft); - QComboBox * cb = new QComboBox(internalframe); - cb->setObjectName("unitsCb1"); - cb-> addItem(tr("KB"), QVariant(1024)); - cb->addItem(tr("MB"), QVariant(1048576)); - cb->addItem(tr("GB"), QVariant(1073741824)); - hbox->addSpacing(9); - internalframe->layout()->addWidget(cb); - hbox->addStretch(); - } - - /* POP Search not implemented - else if (searchType == PopSearch) - { - QLineEdit * lineEdit = new QLineEdit(elem); - lineEdit->setObjectName("param1"); - lineEdit->setValidator(numValidator); - elem->layout()->addWidget(lineEdit); - }*/ - hbox->invalidate(); - internalframe->adjustSize(); - internalframe->show(); - this->adjustSize(); + /* POP Search not implemented + else if (searchType == PopSearch) + { + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setObjectName("param1"); + lineEdit->setValidator(numValidator); + hbox->addWidget(lineEdit); + hbox->addStretch(); + setMinimumSize(lineEdit->minimumSize()); + }*/ + hbox->invalidate(); + adjustSize(); + show(); } void ExprParamElement::setRangedSearch(bool ranged) -{ +{ if (inRangedConfig == ranged) return; // nothing to do here inRangedConfig = ranged; - QHBoxLayout* hbox = (dynamic_cast(internalframe->layout())); + QHBoxLayout* hbox = static_cast(layout()); // add additional or remove extra input fields depending on whether // ranged search or not if (inRangedConfig) { + + if(hbox->itemAt(hbox->count()-1)->spacerItem()) + delete hbox->takeAt(hbox->count()-1); + QLabel * toLbl = new QLabel(tr("to")); - toLbl->setMinimumSize(10, FIELDS_MIN_HEIGHT); + toLbl->setMinimumSize(getMinSize(2, FIELDS_MIN_HFACTOR)); toLbl->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); if (searchType == DateSearch) { - internalframe->setMinimumSize(250,26); - QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), internalframe); - dateEdit->setMinimumSize(DATE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); + QDateEdit * dateEdit = new QDateEdit(QDate::currentDate(), this); + dateEdit->setMinimumSize(getMinSize(DATE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); dateEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + dateEdit->setDisplayFormat(tr("yyyy-MM-dd")); dateEdit->setObjectName("param2"); - dateEdit->setDisplayFormat(tr("dd.MM.yyyy")); dateEdit->setMinimumDate(QDate(1970, 1, 1)); dateEdit->setMaximumDate(QDate(2099, 12,31)); @@ -510,18 +520,21 @@ void ExprParamElement::setRangedSearch(bool ranged) hbox->addSpacing(9); hbox->addWidget(dateEdit, Qt::AlignLeft); hbox->addStretch(); + setMinimumSize(minimumSize() + QSize(9,0) + + QSize(toLbl->minimumWidth(),0) + QSize(9,0) + + QSize(dateEdit->minimumWidth(),0) ); + } else if (searchType == SizeSearch) { - internalframe->setMinimumSize(340,26); - QLineEdit * lineEdit = new QLineEdit(internalframe); - lineEdit->setMinimumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); - lineEdit->setMaximumSize(SIZE_FIELDS_MIN_WIDTH, FIELDS_MIN_HEIGHT); + QLineEdit * lineEdit = new QLineEdit(this); + lineEdit->setMinimumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); + lineEdit->setMaximumSize(getMinSize(SIZE_FIELDS_MIN_WFACTOR, FIELDS_MIN_HFACTOR)); lineEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); lineEdit->setObjectName("param2"); lineEdit->setValidator(numValidator); - QComboBox * cb = new QComboBox(internalframe); + RSComboBox * cb = new RSComboBox(this); cb->setObjectName("unitsCb2"); - cb-> addItem(tr("KB"), QVariant(1024)); + cb->addItem(tr("KB"), QVariant(1024)); cb->addItem(tr("MB"), QVariant(1048576)); cb->addItem(tr("GB"), QVariant(1073741824)); @@ -532,28 +545,39 @@ void ExprParamElement::setRangedSearch(bool ranged) hbox->addSpacing(9); hbox->addWidget(cb); hbox->addStretch(); - } -// else if (searchType == PopSearch) -// { -// elem->layout()->addWidget(new QLabel(tr("to")), Qt::AlignCenter); -// QLineEdit * lineEdit = new QLineEdit(elem); -// lineEdit->setObjectName("param2"); -// lineEdit->setValidator(numValidator); -// elem->layout()->addWidget(slineEdit); -// } + setMinimumSize(minimumSize() + QSize(9,0) + + QSize(toLbl->minimumWidth(),0) + QSize(9,0) + + QSize(lineEdit->minimumWidth(),0) + QSize(9,0) + + QSize(cb->minimumWidth(),0) ); + + } +// else if (searchType == PopSearch) +// { +// QLineEdit * lineEdit = new QLineEdit(this); +// lineEdit->setObjectName("param2"); +// lineEdit->setValidator(numValidator); + +// hbox->addSpacing(9); +// hbox->addWidget(toLbl, Qt::AlignLeft); +// hbox->addSpacing(9); +// hbox->addWidget(lineEdit, Qt::AlignLeft); +// hbox->addStretch(); +// setMinimumSize(minimumSize() + QSize(9,0) +// + QSize(toLbl->minimumWidth(),0) + QSize(9,0) +// + QSize(lineEdit->minimumWidth(),0) ); +// } hbox->invalidate(); - internalframe->adjustSize(); - internalframe->show(); - this->adjustSize(); + adjustSize(); + show(); } else { adjustForSearchType(searchType); } } bool ExprParamElement::ignoreCase() -{ +{ return (isStringSearchExpression() - && (internalframe->findChild("ignoreCaseCB")) + && (findChild("ignoreCaseCB")) ->checkState()==Qt::Checked); } @@ -561,15 +585,15 @@ QString ExprParamElement::getStrSearchValue() { if (!isStringSearchExpression()) return ""; - QLineEdit * lineEdit = internalframe->findChild("param1"); + QLineEdit * lineEdit = findChild("param1"); return lineEdit->displayText(); } uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToField,bool *ok) { uint64_t val = 0; - if(ok!=NULL) - *ok=true ; + if(ok!=NULL) + *ok=true ; QString suffix = (isToField) ? "2": "1" ; // NOTE qFindChild necessary for MSVC 6 compatibility!! @@ -577,25 +601,29 @@ uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToFiel { case DateSearch: { - QDateEdit * dateEdit = internalframe->findChild (fieldName + suffix); - QDateTime * time = new QDateTime(dateEdit->date()); - val = (uint64_t)time->toTime_t(); + QDateEdit * dateEdit = findChild (fieldName + suffix); +#if QT_VERSION < QT_VERSION_CHECK(5,15,0) + QDateTime time = QDateTime(dateEdit->date()); +#else + QDateTime time = dateEdit->date().startOfDay(); +#endif + val = (uint64_t)time.toTime_t(); break; - } + } case SizeSearch: { - QLineEdit * lineEditSize = internalframe->findChild(fieldName + suffix); + QLineEdit * lineEditSize = findChild(fieldName + suffix); bool ok2 = false; val = (lineEditSize->displayText()).toULongLong(&ok2); if (ok2) - { - QComboBox * cb = internalframe->findChild((QString("unitsCb") + suffix)); + { + RSComboBox * cb = findChild((QString("unitsCb") + suffix)); QVariant data = cb->itemData(cb->currentIndex()); val *= data.toULongLong(); - } - else - if(ok!=NULL) - *ok=false ; + } + else + if(ok!=NULL) + *ok=false ; break; } @@ -615,8 +643,8 @@ uint64_t ExprParamElement::getIntValueFromField(QString fieldName, bool isToFiel case HashSearch: default: // shouldn't be here...val stays at -1 - if(ok!=NULL) - *ok=false ; + if(ok!=NULL) + *ok=false ; } return val; diff --git a/retroshare-gui/src/gui/advsearch/guiexprelement.h b/retroshare-gui/src/gui/advsearch/guiexprelement.h index 00748f4f7..50ebeaa15 100644 --- a/retroshare-gui/src/gui/advsearch/guiexprelement.h +++ b/retroshare-gui/src/gui/advsearch/guiexprelement.h @@ -22,25 +22,18 @@ #ifndef _GuiExprElement_h_ #define _GuiExprElement_h_ -#include -#include -#include -#include -#include +#include "gui/common/RSComboBox.h" + +#include "retroshare/rsexpr.h" + #include -#include -#include #include -#include -#include -#include #include -#include +#include +#include #include -#include - enum ExprSearchType { NameSearch, @@ -53,13 +46,13 @@ enum ExprSearchType }; -class GuiExprElement: public QWidget +class GuiExprElement: public QFrame { Q_OBJECT public: GuiExprElement(QWidget * parent = 0); - virtual void adjustForSearchType(ExprSearchType) {} + void adjustForSearchType(ExprSearchType) {} virtual ~GuiExprElement(){} virtual void set(int){} virtual void set(QObject*){} @@ -103,8 +96,8 @@ protected: condition combobox */ QStringList getConditionOptions(ExprSearchType t); - QHBoxLayout* createLayout(QWidget* parent = 0); - QFrame * internalframe; + QHBoxLayout* createLayout(QWidget* parent = nullptr); + QSize getMinSize(float widthFactor = 1.0, float heightFactor = 1.0); ExprSearchType searchType; @@ -125,7 +118,6 @@ protected: static QMap strConditionStrMap; static QMap relConditionStrMap; - }; /** the Expression operator combobox element */ @@ -134,11 +126,11 @@ class ExprOpElement : public GuiExprElement Q_OBJECT public: - ExprOpElement(QWidget * parent = 0); + ExprOpElement(QWidget * parent = nullptr); RsRegularExpression::LogicalOperator getLogicalOperator(); QString toString(); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Terms combobox element */ @@ -147,7 +139,7 @@ class ExprTermsElement : public GuiExprElement Q_OBJECT public: - ExprTermsElement(QWidget * parent = 0); + ExprTermsElement(QWidget * parent = nullptr); int getTermsIndex(); RsRegularExpression::RelOperator getRelOperator(); RsRegularExpression::StringOperator getStringOperator(); @@ -158,7 +150,7 @@ signals: void currentIndexChanged(int); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Conditions combobox element */ @@ -167,7 +159,7 @@ class ExprConditionElement : public GuiExprElement Q_OBJECT public: - ExprConditionElement(ExprSearchType, QWidget * parent = 0); + ExprConditionElement(QWidget * parent = nullptr, ExprSearchType type = NameSearch); RsRegularExpression::RelOperator getRelOperator(); RsRegularExpression::StringOperator getStringOperator(); void adjustForSearchType(ExprSearchType); @@ -178,7 +170,7 @@ signals: void currentIndexChanged(int); private: - QComboBox * cb; + RSComboBox * cb; }; /** the Parameter element */ @@ -187,7 +179,7 @@ class ExprParamElement : public GuiExprElement Q_OBJECT public: - ExprParamElement(ExprSearchType, QWidget * parent = 0); + ExprParamElement(QWidget * parent = nullptr, ExprSearchType type = NameSearch); QVariant* getRSExprValue(); void adjustForSearchType(ExprSearchType); void setRangedSearch(bool ranged = true); diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h index 429a5bfb4..065abacee 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.h +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.h @@ -27,8 +27,8 @@ #include "ChatDialog.h" #include "PopupChatWindow.h" -Q_DECLARE_METATYPE(RsGxsId) -Q_DECLARE_METATYPE(QList) +// Q_DECLARE_METATYPE(RsGxsId) +// Q_DECLARE_METATYPE(QList) class GxsIdChooser ; class QToolButton; @@ -101,7 +101,7 @@ private: void muteParticipant(const RsGxsId& id); void unMuteParticipant(const RsGxsId& id); bool isNicknameInLobby(const RsGxsId& id); - + ChatLobbyId lobbyId; QString _lobby_name ; time_t lastUpdateListTime; @@ -117,7 +117,7 @@ private: /** Qt Designer generated object */ Ui::ChatLobbyDialog ui; - + /** Ignored Users in Chatlobby by nickname until we had implemented Peer Ids in ver 0.6 */ std::set mutedParticipants; diff --git a/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui b/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui index 0a1635735..0851eba15 100644 --- a/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui +++ b/retroshare-gui/src/gui/chat/ChatLobbyDialog.ui @@ -13,7 +13,7 @@ MainWindow - + 0 @@ -48,7 +48,7 @@
- + 0 @@ -61,7 +61,10 @@ 0 - + + + 2 + 0 @@ -82,7 +85,7 @@ QFrame::Sunken - + 2 diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 2f43120ac..03f954964 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -165,7 +165,6 @@ ChatWidget::ChatWidget(QWidget *parent) connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont())); connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote())); connect(ui->actionDropPlacemark, SIGNAL(triggered()), this, SLOT(dropPlacemark())); - connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage())); connect(ui->actionImport_sticker, SIGNAL(triggered()), this, SLOT(saveSticker())); connect(ui->actionShow_Hidden_Images, SIGNAL(triggered()), ui->textBrowser, SLOT(showImages())); ui->actionShow_Hidden_Images->setIcon(ui->textBrowser->getBlockedImage()); @@ -183,7 +182,7 @@ ChatWidget::ChatWidget(QWidget *parent) connect(ui->chatTextEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(chatCharFormatChanged())); connect(ui->chatTextEdit, SIGNAL(textChanged()), this, SLOT(updateLenOfChatTextEdit())); - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); ui->statusMessageLabel->hide(); setAcceptDrops(true); @@ -290,12 +289,12 @@ void ChatWidget::addChatBarWidget(QWidget *w) void ChatWidget::addTitleBarWidget(QWidget *w) { - ui->pluginTitleFrame->layout()->addWidget(w) ; + ui->trans_Frame_PluginTitle->layout()->addWidget(w) ; } void ChatWidget::addTopBarWidget(QWidget *w) { - ui->pluginTopFrame->layout()->addWidget(w) ; + ui->trans_Frame_PluginTop->layout()->addWidget(w) ; } void ChatWidget::hideChatText(bool hidden) @@ -381,7 +380,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) hist_chat_type = RS_HISTORY_TYPE_PUBLIC; messageCount = Settings->getPublicChatHistoryCount(); - ui->titleBarFrame->setVisible(false); + ui->headerBFrame->setVisible(false); } if (rsHistory->getEnable(hist_chat_type)) @@ -403,7 +402,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) continue; QString name; - if (chatId.isLobbyId() || chatId.isDistantChatId()) + if (!chatId.isNotSet()) { RsIdentityDetails details; @@ -474,6 +473,7 @@ void ChatWidget::processSettings(bool load) // state of splitter ui->chatVSplitter->restoreState(Settings->value("ChatSplitter").toByteArray()); } else { + shrinkChatTextEdit(false); // save settings // state of splitter @@ -627,7 +627,7 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event) QString toolTipText = ui->textBrowser->anchorForPosition(helpEvent->pos()); if (toolTipText.isEmpty() && !ui->textBrowser->getShowImages()){ QString imageStr; - if (ui->textBrowser->checkImage(helpEvent->pos(), imageStr)) { + if (ImageUtil::checkImage(ui->textBrowser, helpEvent->pos(), imageStr)) { toolTipText = imageStr; } } else if (toolTipText.startsWith(PERSONID)){ @@ -642,7 +642,17 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event) } } - } else if (obj == ui->chatTextEdit) { + } else if (obj == ui->chatTextEdit) { + if (chatType() == CHATTYPE_LOBBY) { + #define EVENT_IS(q_event) (event->type() == QEvent::q_event) + if (EVENT_IS(FocusIn)) { + if (was_shrinked) { + shrinkChatTextEdit(false); + } + } + #undef EVENT_IS + } + if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); @@ -905,11 +915,19 @@ void ChatWidget::showEvent(QShowEvent */*event*/) QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar(); bool is_scrollbar_at_end = scrollbar->value() == scrollbar->maximum(); bool is_chat_text_edit_empty = ui->chatTextEdit->toPlainText().isEmpty(); + // show event will not be called on every change of focus if (is_scrollbar_at_end || !is_chat_text_edit_empty) { + if (!firstShow) { + shrinkChatTextEdit(false); + } focusDialog(); } else { - // otherwise focus will be get even not chat itself + // otherwise, focus will not even be gotten by chat itself ui->textBrowser->setFocus(); + + if (!firstShow && !was_shrinked) { + shrinkChatTextEdit(true); + } } ChatUserNotify::clearWaitingChat(chatId); @@ -923,6 +941,11 @@ void ChatWidget::showEvent(QShowEvent */*event*/) void ChatWidget::resizeEvent(QResizeEvent */*event*/) { + // it's about resize all chat window, not about chattextedit + // just unshrink it and do not bother + if (was_shrinked) { + shrinkChatTextEdit(false); + } // Workaround: now the scroll position is correct calculated QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar(); scrollbar->setValue(scrollbar->maximum()); @@ -1070,7 +1093,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx QImage image(icon.pixmap(height,height).toImage()); QByteArray byteArray; QBuffer buffer(&byteArray); - image.save(&buffer, "PNG"); // writes the image in PNG format inside the buffer + image.save(&buffer, "PNG"); // writes the image in PNG format inside the buffer QString iconBase64 = QString::fromLatin1(byteArray.toBase64().data()); strPreName = QString("\"[unsigned]\"").arg(iconBase64); } @@ -1127,10 +1150,7 @@ void ChatWidget::pasteText(const QString& S) void ChatWidget::contextMenuTextBrowser(QPoint point) { - QMatrix matrix; - matrix.translate(ui->textBrowser->horizontalScrollBar()->value(), ui->textBrowser->verticalScrollBar()->value()); - - QMenu *contextMnu = ui->textBrowser->createStandardContextMenu(matrix.map(point)); + QMenu *contextMnu = ui->textBrowser->createStandardContextMenuFromPoint(point); contextMnu->addSeparator(); contextMnu->addAction(ui->actionClearChatHistory); @@ -1138,14 +1158,12 @@ void ChatWidget::contextMenuTextBrowser(QPoint point) contextMnu->addAction(ui->actionQuote); contextMnu->addAction(ui->actionDropPlacemark); - if(ui->textBrowser->checkImage(point)) + if(ImageUtil::checkImage(ui->textBrowser, point)) { if (! ui->textBrowser->getShowImages()) contextMnu->addAction(ui->actionShow_Hidden_Images); - ui->actionSave_image->setData(point); ui->actionImport_sticker->setData(point); - contextMnu->addAction(ui->actionSave_image); contextMnu->addAction(ui->actionImport_sticker); } @@ -1286,7 +1304,7 @@ void ChatWidget::sendChat() void ChatWidget::on_closeInfoFrameButton_clicked() { - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); } void ChatWidget::on_searchButton_clicked(bool bValue) @@ -1511,23 +1529,43 @@ void ChatWidget::chooseFont() //Use NULL as parent as with this QFontDialog don't take care of title nether options. QFont font = misc::getFont(&ok, currentFont, nullptr, tr("Choose your font.")); - QTextCursor cursor = ui->chatTextEdit->textCursor(); if (ok) { + QTextCursor cursor = ui->chatTextEdit->textCursor(); + if (cursor.selection().isEmpty()){ currentFont = font; setFont(); } else { - //Merge Format doesn't works for only selection so add a new block. - QString text = "

" + cursor.selectedText().toHtmlEscaped() + "

"; - cursor.insertHtml(text); + // Merge Format doesn't works for only selection. + // and charFormat() get format for last char. + QTextCursor selCurs = cursor; + QTextCursor lastCurs = cursor; + int pos = cursor.selectionStart(); + lastCurs.setPosition(pos); + do + { + // Get format block in selection iterating char one by one + selCurs.setPosition(++pos); + if (selCurs.charFormat() != lastCurs.charFormat()) + { + // New char format, format last block. + QTextCharFormat charFormat = lastCurs.charFormat(); + charFormat.setFont(font); + lastCurs.setCharFormat(charFormat); + // Last block formated, start it to current char. + lastCurs.setPosition(pos-1); + } + // Add current char. + lastCurs.setPosition(pos, QTextCursor::KeepAnchor); + } while (pos < cursor.selectionEnd()); + + // Now format last block + if (lastCurs.selectionStart() != lastCurs.selectionEnd()) + { + QTextCharFormat charFormat = lastCurs.charFormat(); + charFormat.setFont(font); + lastCurs.setCharFormat(charFormat); + } } } } @@ -1583,7 +1621,12 @@ void ChatWidget::addSmiley() smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) QString plainText = ui->chatTextEdit->toPlainText(); - QChar start = plainText[ui->chatTextEdit->textCursor().position() - 1]; + + int startPosition = ui->chatTextEdit->textCursor().position(); + if (startPosition > 0) + startPosition -= 1; + + QChar start = plainText[startPosition]; if(!ui->chatTextEdit->textCursor().atStart() && start != QChar(' ')) smiley = QString(" ") + smiley; @@ -1648,7 +1691,7 @@ void ChatWidget::addExtraPicture() if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", file)) { QString encodedImage; uint32_t maxMessageSize = this->maxMessageSize(); - if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, maxMessageSize - 200)) { //-200 for the html stuff + if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, maxMessageSize - 200)) { //-200 for the html stuff QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); ui->chatTextEdit->textCursor().insertFragment(fragment); } @@ -1799,27 +1842,27 @@ void ChatWidget::updateStatus(const QString &peer_id, int status) switch (status) { case RS_STATUS_OFFLINE: - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online.")); break; case RS_STATUS_INACTIVE: - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply")); break; case RS_STATUS_ONLINE: - ui->infoFrame->setVisible(false); + ui->info_Frame->setVisible(false); break; case RS_STATUS_AWAY: ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply")); - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); break; case RS_STATUS_BUSY: ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply")); - ui->infoFrame->setVisible(true); + ui->info_Frame->setVisible(true); break; } @@ -1946,13 +1989,6 @@ void ChatWidget::dropPlacemark() // or not. } -void ChatWidget::saveImage() -{ - QPoint point = ui->actionSave_image->data().toPoint(); - QTextCursor cursor = ui->textBrowser->cursorForPosition(point); - ImageUtil::extractImage(window(), cursor); -} - void ChatWidget::saveSticker() { QPoint point = ui->actionImport_sticker->data().toPoint(); @@ -1962,3 +1998,50 @@ void ChatWidget::saveSticker() filename = Emoticons::importedStickerPath() + "/" + filename + ".png"; ImageUtil::extractImage(window(), cursor, filename); } + +void ChatWidget::shrinkChatTextEdit(bool shrink_me) +{ + // here and at eventfiltert check + if (chatType() != CHATTYPE_LOBBY) + return; + if (!Settings->getShrinkChatTextEdit()) { + if (was_shrinked) { + ui->chatVSplitter->setSizes(_chatvsplitter_saved_size); + } + _chatvsplitter_saved_size.clear(); + was_shrinked = false; + } + + if (Settings->getShrinkChatTextEdit()) { + if (shrink_me) { + if (!was_shrinked) { + _chatvsplitter_saved_size = ui->chatVSplitter->sizes(); + + QList shrinked_v_splitter_size = _chatvsplitter_saved_size; + // #define TEXT_BROWSER ui->chatVSplitter->indexOf(ui->textBrowser) + #define TEXT_BROWSER 0 + // when you will update the layout one more time change this appropriately + // #define BELOW_TEXT_BROWSER ui->chatVSplitter->indexOf(ui->chatVSplitter->widget(1)) + #define BELOW_TEXT_BROWSER 1 + int height_diff = shrinked_v_splitter_size[BELOW_TEXT_BROWSER] - ui->chatTextEdit->minimumHeight(); + shrinked_v_splitter_size[BELOW_TEXT_BROWSER] = ui->chatTextEdit->minimumHeight(); + shrinked_v_splitter_size[TEXT_BROWSER] += height_diff; + ui->chatVSplitter->setSizes( shrinked_v_splitter_size ); + #undef TEXT_BROWSER + #undef BELOW_TEXT_BROWSER + was_shrinked = true; + } + } else { // (!shrink_me) + if (was_shrinked) { + // to not shrink/unshrink at every entry into chat + // when unshrinked state is enough to a browser be scrollable, but shrinked - not + QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar(); + bool is_scrollbar_at_end = scrollbar->value() == scrollbar->maximum(); + ui->chatVSplitter->setSizes(_chatvsplitter_saved_size); + if (is_scrollbar_at_end) + scrollbar->setValue(scrollbar->maximum()); + was_shrinked = false; + } + } + } +} diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index b9ff7086f..e42df06fe 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -196,7 +196,6 @@ private slots: void quote(); void dropPlacemark(); - void saveImage(); void saveSticker(); private: @@ -215,6 +214,8 @@ private: void completeNickname(bool reverse); QAbstractItemModel *modelFromPeers(); + void shrinkChatTextEdit(bool shrink_me); + ChatId chatId; QString title; QString name; @@ -264,6 +265,9 @@ private: QCompleter *completer; ImHistoryBrowser* imBrowser; + QList _chatvsplitter_saved_size; + bool was_shrinked = false; + QList mChatWidgetHolder; ChatLobbyUserNotify* notify; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.ui b/retroshare-gui/src/gui/chat/ChatWidget.ui index 7ecbcfdc2..39bd84bb7 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.ui +++ b/retroshare-gui/src/gui/chat/ChatWidget.ui @@ -32,7 +32,7 @@ QLayout::SetMaximumSize - + 0 @@ -51,7 +51,7 @@ QFrame::Plain - + 2 @@ -84,10 +84,12 @@ - + + 11 75 + true true @@ -100,7 +102,14 @@ - + + + + 12 + 75 + true + + (Status) @@ -121,14 +130,14 @@ - + QFrame::NoFrame QFrame::Plain - + 3 @@ -311,14 +320,14 @@ - + QFrame::NoFrame QFrame::Plain - + 3 @@ -355,12 +364,6 @@ 0 - - QFrame::StyledPanel - - - QFrame::Raised - 0 @@ -375,10 +378,19 @@ 0 - + + + + + 0 + 0 + 0 + + + @@ -399,6 +411,15 @@ + + + + 0 + 0 + 0 + + + @@ -419,6 +440,15 @@ + + + + 154 + 154 + 154 + + + @@ -631,7 +661,7 @@ border-image: url(:/images/closepressed.png) 0 - 30 + 40 @@ -1019,15 +1049,6 @@ border-image: url(:/images/closepressed.png) Insert horizontal rule - - - - :/images/document_save.png:/images/document_save.png - - - Save image - - @@ -1089,21 +1110,6 @@ border-image: url(:/images/closepressed.png) - - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
- - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - RSTextBrowser - QTextBrowser -
gui/common/RSTextBrowser.h
-
HashBox QScrollArea @@ -1115,11 +1121,20 @@ border-image: url(:/images/closepressed.png) QTextEdit
gui/common/MimeTextEdit.h
+ + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + RSTextBrowser + QTextBrowser +
gui/common/RSTextBrowser.h
+
- - + diff --git a/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui b/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui index 7c4d01aaa..15dab649d 100644 --- a/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui +++ b/retroshare-gui/src/gui/chat/CreateLobbyDialog.ui @@ -37,10 +37,15 @@
- - + + - + + + + 15 + + A chat room is a decentralized and anonymous chat group. All participants receive all messages. Once the room is created you can invite other friend nodes with invite button on top right. @@ -103,7 +108,7 @@ - + Public (Visible by friends) @@ -230,6 +235,13 @@ + + + 12 + 75 + true + + Create @@ -250,17 +262,6 @@ - - StyledLabel - QLabel -
gui/common/StyledLabel.h
-
- - HeaderFrame - QFrame -
gui/common/HeaderFrame.h
- 1 -
FriendSelectionWidget QWidget @@ -272,6 +273,17 @@ QComboBox
gui/gxs/GxsIdChooser.h
+ + HeaderFrame + QFrame +
gui/common/HeaderFrame.h
+ 1 +
+ + RSComboBox + QComboBox +
gui/common/RSComboBox.h
+
diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp index 6c1f9128d..1f15345b1 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp @@ -34,6 +34,7 @@ #include "util/misc.h" #include "rshare.h" +#include #include #include @@ -88,7 +89,7 @@ PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags f // ui.actionSetOnTop->setVisible(false);// removed, because the window manager should handle this already. // ui.actionColor->setVisible(false);// moved to the context menu - ui.chattoolBar->hide(); // no widgets left! + ui.headerToolBar->hide(); // no widgets left! setAttribute(Qt::WA_DeleteOnClose, true); @@ -100,6 +101,17 @@ PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WindowFlags f connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); + voteNegative = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-down.png"), + tr("Ban this person (Sets negative opinion)"), this); + voteNeutral = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-neutral.png"), + tr("Give neutral opinion"), this); + votePositive = new QAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/thumbs-up.png"), + tr("Give positive opinion"), this); + + connect(votePositive, SIGNAL(triggered()), this, SLOT(voteParticipant())); + connect(voteNeutral, SIGNAL(triggered()), this, SLOT(voteParticipant())); + connect(voteNegative, SIGNAL(triggered()), this, SLOT(voteParticipant())); + connect(ui.tabWidget, SIGNAL(tabChanged(ChatDialog*)), this, SLOT(tabChanged(ChatDialog*))); connect(ui.tabWidget, SIGNAL(tabClosed(ChatDialog*)), this, SLOT(tabClosed(ChatDialog*))); @@ -116,6 +128,37 @@ void PopupChatWindow::showContextMenu(QPoint) QMenu contextMnu(this); contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/highlight.png"),tr("Choose window color..."),this,SLOT(setStyle())); + ChatId ch_id = getCurrentDialog()->getChatId(); + if (ch_id.isDistantChatId()) { + DistantChatPeerId dc_id = ch_id.toDistantChatId(); + DistantChatPeerInfo dc_info; + if(rsMsgs->getDistantChatStatus(dc_id, dc_info)) { + RsGxsId gxs_id = dc_info.to_id; + if(!gxs_id.isNull() && !rsIdentity->isOwnId(gxs_id)) { + contextMnu.addAction(votePositive); + contextMnu.addAction(voteNeutral); + contextMnu.addAction(voteNegative); + + votePositive->setEnabled(false); + voteNeutral ->setEnabled(false); + voteNegative->setEnabled(false); + + RsOpinion rs_rep; + rsReputations->getOwnOpinion(gxs_id, rs_rep); + if (rsReputations->getOwnOpinion(gxs_id, rs_rep)) { + votePositive->setEnabled(rs_rep != RsOpinion::POSITIVE); + voteNeutral->setEnabled( ( rs_rep == RsOpinion::POSITIVE ) + || ( rs_rep == RsOpinion::NEGATIVE ) ); + voteNegative->setEnabled(rs_rep != RsOpinion::NEGATIVE); + + votePositive->setData(QVariant::fromValue(gxs_id)); + voteNeutral ->setData(QVariant::fromValue(gxs_id)); + voteNegative->setData(QVariant::fromValue(gxs_id)); + } + } + } + } + if (Settings->getChatFlags() & RS_CHAT_TABBED_WINDOW) { if(tabbedWindow) @@ -440,7 +483,7 @@ void PopupChatWindow::calculateStyle(ChatDialog *dialog) } } - ui.chattoolBar->setStyleSheet(toolSheet); + ui.headerToolBar->setStyleSheet(toolSheet); ui.chatstatusbar->setStyleSheet(statusSheet); ui.chatcentralwidget->setStyleSheet(widgetSheet); } @@ -457,3 +500,17 @@ void PopupChatWindow::blink(bool on) setWindowIcon(on ? mBlinkIcon : *mEmptyIcon); } } + +void PopupChatWindow::voteParticipant() +{ + QAction *act = dynamic_cast(sender()) ; + if (!act) { + return ; + } + + RsOpinion opinion = RsOpinion::NEUTRAL; + if (act == voteNeutral) opinion = RsOpinion::NEUTRAL; + if (act == votePositive) opinion = RsOpinion::POSITIVE; + if (act == voteNegative) opinion = RsOpinion::NEGATIVE; + rsReputations->setOwnOpinion(act->data().value(), opinion); +} diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.h b/retroshare-gui/src/gui/chat/PopupChatWindow.h index 86f8ebc80..968531ea1 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.h +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.h @@ -27,6 +27,8 @@ #include "ui_PopupChatWindow.h" #include #include +Q_DECLARE_METATYPE(RsGxsId) +Q_DECLARE_METATYPE(QList) class ChatDialog; @@ -67,6 +69,7 @@ private slots: void setOnTop(); void blink(bool on); void showContextMenu(QPoint p); + void voteParticipant(); private: bool tabbedWindow; @@ -75,6 +78,9 @@ private: ChatDialog *chatDialog; QIcon mBlinkIcon; QIcon *mEmptyIcon; + QAction* votePositive; + QAction* voteNegative; + QAction* voteNeutral; ChatDialog *getCurrentDialog(); void saveSettings(); diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.ui b/retroshare-gui/src/gui/chat/PopupChatWindow.ui index ea6ea79af..0394a1c31 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.ui +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.ui @@ -43,7 +43,7 @@
- + false diff --git a/retroshare-gui/src/gui/common/AvatarDialog.cpp b/retroshare-gui/src/gui/common/AvatarDialog.cpp index 8eb24a184..dd302b570 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.cpp +++ b/retroshare-gui/src/gui/common/AvatarDialog.cpp @@ -40,6 +40,7 @@ #include "util/misc.h" #include "gui/common/FilesDefs.h" #include "util/HandleRichText.h" +#include "util/imageutil.h" #include "retroshare/rsinit.h" #define ICONNAME "groupicon.png" @@ -138,10 +139,11 @@ void AvatarDialog::getAvatar(QByteArray &avatar) return; } - QBuffer buffer(&avatar); + bool has_transparency = ImageUtil::hasAlphaContent(pixmap.toImage()); + QBuffer buffer(&avatar); buffer.open(QIODevice::WriteOnly); - pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format + pixmap.save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format } void AvatarDialog::load() @@ -166,7 +168,7 @@ void AvatarDialog::loadAvatarWidget() message += "\n RetroShare/stickers\n RetroShare/Data/stickers\n RetroShare/Data/Location/stickers"; ui->nostickersLabel->setText(message); } else { - ui->infoframe->hide(); + ui->info_Frame->hide(); } bool bOnlyOneGroup = (stickerTabs.count() == 1); @@ -272,7 +274,7 @@ void AvatarDialog::loadAvatarWidget() loadToolTips(firstpage); //Get widget's size - QSize sizeWidget = ui->avatarWidget->sizeHint(); + //QSize sizeWidget = ui->avatarWidget->sizeHint(); } diff --git a/retroshare-gui/src/gui/common/AvatarDialog.ui b/retroshare-gui/src/gui/common/AvatarDialog.ui index 9c5bc9482..a7b98cbcf 100644 --- a/retroshare-gui/src/gui/common/AvatarDialog.ui +++ b/retroshare-gui/src/gui/common/AvatarDialog.ui @@ -13,7 +13,7 @@ Change Avatar - + 0 @@ -37,14 +37,14 @@
- + QFrame::StyledPanel QFrame::Raised - + 3 @@ -52,14 +52,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + @@ -74,7 +74,7 @@ - + @@ -121,7 +121,7 @@ - + Qt::Vertical @@ -146,7 +146,7 @@ 0 0 431 - 359 + 356 @@ -180,7 +180,7 @@ - + 9 @@ -194,7 +194,7 @@ 9 - + Qt::Horizontal @@ -219,7 +219,7 @@ - frame + gradFrame headerFrame @@ -235,9 +235,7 @@
gui/gxschannels/GxsChannelPostThumbnail.h
- - - + buttonBox diff --git a/retroshare-gui/src/gui/common/ElidedLabel.cpp b/retroshare-gui/src/gui/common/ElidedLabel.cpp index c444c8113..2486d0cae 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.cpp +++ b/retroshare-gui/src/gui/common/ElidedLabel.cpp @@ -126,7 +126,12 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap); textLayout.setTextOption(to); - if (painter) painter->save(); + if (painter) + { + useFont.setPointSize(useFont.pointSize()); //Modify it to be copied in painter. Else painter keep defaut font size. + painter->save(); + painter->setFont(useFont); + } textLayout.beginLayout(); forever { //Get new line for text. @@ -148,7 +153,7 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText QTextLine lineEnd = textLayout.createLine(); if (!lineEnd.isValid() && (wordWrap #if QT_VERSION < QT_VERSION_CHECK(5,11,0) - || (fontMetrics.width(lastLine) < cr.width()) )) + || (fontMetrics.width(lastLine) < cr.width()) )) #else || (fontMetrics.horizontalAdvance(lastLine) < cr.width()) )) #endif @@ -220,10 +225,7 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText if(width+iTransX+cr.left() <= cr.right()) if (painter) - { - painter->setFont(useFont); painter->drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine); - } //Draw button to get ToolTip #if QT_VERSION < QT_VERSION_CHECK(5,11,0) @@ -256,7 +258,11 @@ void ElidedLabel::mousePressEvent(QMouseEvent *ev) return; // eat event } QLabel::mousePressEvent(ev); - emit clicked(ev->pos()); + + if(ev->buttons()==Qt::LeftButton) + emit clicked(ev->pos()); + else if(ev->buttons()==Qt::RightButton) + emit rightClicked(ev->pos()); } void ElidedLabel::setTextColor(const QColor &color) diff --git a/retroshare-gui/src/gui/common/ElidedLabel.h b/retroshare-gui/src/gui/common/ElidedLabel.h index 9290a61d1..2faa2f0ef 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.h +++ b/retroshare-gui/src/gui/common/ElidedLabel.h @@ -77,7 +77,8 @@ protected: signals: void elisionChanged(bool elided); - void clicked(QPoint pos); + void rightClicked(QPoint pos); + void clicked(QPoint pos); private: bool mElided; diff --git a/retroshare-gui/src/gui/common/Emoticons.cpp b/retroshare-gui/src/gui/common/Emoticons.cpp index d6bb17e4a..2341039cd 100644 --- a/retroshare-gui/src/gui/common/Emoticons.cpp +++ b/retroshare-gui/src/gui/common/Emoticons.cpp @@ -51,7 +51,7 @@ static QHash iconcache; void Emoticons::load() { loadSmiley(); - filters << "*.png" << "*.jpg" << "*.gif"; + filters << "*.png" << "*.jpg" << "*.jpeg" << "*.gif" << "*.webp"; stickerFolders << (QString::fromStdString(RsAccounts::AccountDirectory()) + "/stickers"); //under account, unique for user stickerFolders << (QString::fromStdString(RsAccounts::ConfigDirectory()) + "/stickers"); //under .retroshare, shared between users stickerFolders << (QString::fromStdString(RsAccounts::systemDataDirectory()) + "/stickers"); //exe's folder, shipped with RS @@ -205,10 +205,11 @@ void Emoticons::showSmileyWidget(QWidget *parent, QWidget *button, const char *s // (Cyril) Never use an absolute size. It needs to be scaled to the actual font size on the screen. // QFontMetricsF fm(parent->font()) ; - smTab->setIconSize(QSize(28*fm.height()/14.0,28*fm.height()/14.0)); + QSize size(28*fm.height()/14.0,28*fm.height()/14.0); + smTab->setIconSize(size); smTab->setMinimumWidth(400); smTab->setTabPosition(QTabWidget::South); - smTab->setStyleSheet("QTabBar::tab { height: 44px; width: 44px; }"); + smTab->setStyleSheet(QString("QTabBar::tab { height: %1px; width: %1px; padding: 0px; margin: 0px;}").arg(size.width()*1.1)); if (groupName.right(4).toLower() == ".png") smTab->addTab( tabGrpWidget, FilesDefs::getIconFromQtResourcePath(groupName), ""); diff --git a/retroshare-gui/src/gui/common/FilesDefs.cpp b/retroshare-gui/src/gui/common/FilesDefs.cpp index b7f0192a4..0048d5685 100644 --- a/retroshare-gui/src/gui/common/FilesDefs.cpp +++ b/retroshare-gui/src/gui/common/FilesDefs.cpp @@ -33,50 +33,56 @@ static QString getInfoFromFilename(const QString& filename, bool anyForUnknown, { QString ext = QFileInfo(filename).suffix().toLower(); - if (ext == "jpg" || ext == "jpeg" || ext == "tif" || ext == "tiff" || ext == "png" || ext == "gif" || ext == "bmp" || ext == "ico" || ext == "svg") { - return image ? ":/images/FileTypePicture.png" : QApplication::translate("FilesDefs", "Picture"); + if (ext == "jpg" || ext == "jpeg" || ext == "tif" || ext == "tiff" || ext == "png" || ext == "gif" || + ext == "bmp" || ext == "ico" || ext == "svg" || ext == "webp") { + return image ? ":/icons/filetype/picture.svg" : QApplication::translate("FilesDefs", "Picture"); } else if (ext == "avi" || ext == "mpg" || ext == "mpeg" || ext == "wmv" || ext == "divx" || ext == "ts" || ext == "mkv" || ext == "mp4" || ext == "flv" || ext == "mov" || ext == "asf" || ext == "xvid" || - ext == "vob" || ext == "qt" || ext == "rm" || ext == "3gp" || ext == "ogm") { - return image ? ":/images/FileTypeVideo.png" : QApplication::translate("FilesDefs", "Video"); - } else if (ext == "ogg" || ext == "mp3" || ext == "mp1" || ext == "mp2" || ext == "wav" || ext == "wma" || ext == "m4a" || ext == "flac" ||ext == "xpm") { - return image ? ":/images/FileTypeAudio.png" : QApplication::translate("FilesDefs", "Audio"); + ext == "vob" || ext == "qt" || ext == "rm" || ext == "3gp" || ext == "ogm" || ext == "webm") { + return image ? ":/icons/filetype/video.svg" : QApplication::translate("FilesDefs", "Video"); + } else if (ext == "ogg" || ext == "mp3" || ext == "mp1" || ext == "mp2" || ext == "wav" || ext == "wma" || + ext == "m4a" || ext == "flac" || ext == "xpm" || ext == "weba") { + return image ? ":/icons/filetype/audio.svg" : QApplication::translate("FilesDefs", "Audio"); } else if (ext == "tar" || ext == "bz2" || ext == "zip" || ext == "gz" || ext == "7z" || ext == "msi" || ext == "rar" || ext == "rpm" || ext == "ace" || ext == "jar" || ext == "tgz" || ext == "lha" || ext == "cab" || ext == "cbz"|| ext == "cbr" || ext == "alz" || ext == "sit" || ext == "arj" || ext == "deb") { - return image ? ":/images/FileTypeArchive.png" : QApplication::translate("FilesDefs", "Archive"); + return image ? ":/icons/filetype/archive.svg" : QApplication::translate("FilesDefs", "Archive"); } else if (ext == "app" || ext == "bat" || ext == "cgi" || ext == "com" || ext == "exe" || ext == "js" || ext == "pif" || ext == "py" || ext == "pl" || ext == "sh" || ext == "vb" || ext == "ws") { - return image ? ":/images/FileTypeProgram.png" : QApplication::translate("FilesDefs", "Program"); + return image ? ":/icons/filetype/program.svg" : QApplication::translate("FilesDefs", "Program"); } else if (ext == "iso" || ext == "nrg" || ext == "mdf" || ext == "img" || ext == "dmg" || ext == "bin" || ext == "uif") { - return image ? ":/images/FileTypeCDImage.png" : QApplication::translate("FilesDefs", "CD/DVD-Image"); + return image ? ":/icons/filetype/img.svg" : QApplication::translate("FilesDefs", "CD/DVD-Image"); } else if (ext == "txt" || ext == "ui" || ext == "doc" || ext == "rtf" || ext == "sxw" || ext == "xls" || ext == "pps" || ext == "xml" || ext == "nfo" || ext == "reg" || ext == "sxc" || ext == "odt" || ext == "ods" || ext == "dot" || ext == "ppt" || ext == "css" || ext == "crt" || ext == "html" || ext == "htm" || ext == "php") { - return image ? ":/images/FileTypeDocument.png" : QApplication::translate("FilesDefs", "Document"); + return image ? ":/icons/filetype/document.svg" : QApplication::translate("FilesDefs", "Document"); } else if (ext == "pdf") { - return image ? ":/images/mimetypes/pdf.png" : QApplication::translate("FilesDefs", "Document"); + return image ? ":/icons/filetype/pdf.svg" : QApplication::translate("FilesDefs", "Document"); } else if (ext == RsCollection::ExtensionString) { - return image ? ":/images/mimetypes/rscollection-16.png" : QApplication::translate("FilesDefs", "RetroShare collection file"); + return image ? ":/icons/filetype/collection.svg" : QApplication::translate("FilesDefs", "RetroShare collection file"); } else if (ext == "sub" || ext == "srt") { - return image ? ":/images/FileTypeAny.png" : QApplication::translate("FilesDefs", "Subtitles"); + return image ? ":/icons/filetype/any.svg" : QApplication::translate("FilesDefs", "Subtitles"); } else if (ext == "nds") { - return image ? ":/images/FileTypeAny.png" : QApplication::translate("FilesDefs", "Nintendo DS Rom"); + return image ? ":/icons/filetype/any.svg" : QApplication::translate("FilesDefs", "Nintendo DS Rom"); } else if (ext == "patch" || ext == "diff") { - return image ? ":/images/mimetypes/patch.png" : QApplication::translate("FilesDefs", "Patch"); + return image ? ":/icons/filetype/patch.svg" : QApplication::translate("FilesDefs", "Patch"); } else if (ext == "cpp") { - return image ? ":/images/mimetypes/source_cpp.png" : QApplication::translate("FilesDefs", "C++"); + return image ? ":/icons/filetype/cpp.svg" : QApplication::translate("FilesDefs", "C++"); } else if (ext == "h") { - return image ? ":/images/mimetypes/source_h.png" : QApplication::translate("FilesDefs", "Header"); + return image ? ":/icons/filetype/h.svg" : QApplication::translate("FilesDefs", "Header"); } else if (ext == "c") { - return image ? ":/images/mimetypes/source_c.png" : QApplication::translate("FilesDefs", "C "); + return image ? ":/icons/filetype/c.svg" : QApplication::translate("FilesDefs", "C "); + } else if (ext == "apk") { + return image ? ":/icons/filetype/apk.svg" : QApplication::translate("FilesDefs", "APK "); + } else if (ext == "dll") { + return image ? ":/icons/filetype/dll.svg" : QApplication::translate("FilesDefs", "DLL "); } if (anyForUnknown) { - return image ? ":/images/FileTypeAny.png" : ""; + return image ? ":/icons/filetype/any.svg" : ""; } return ""; @@ -156,7 +162,7 @@ QIcon FilesDefs::getIconFromGxsIdCache(const RsGxsId& id,const QIcon& setIcon, b if (setIcon.isNull()) { if (id.isNull()) - return getIconFromQtResourcePath(":/icons/notification.png"); + return getIconFromQtResourcePath(":/icons/notification.svg"); auto item = mIconCache.find(id); diff --git a/retroshare-gui/src/gui/common/FriendList.cpp b/retroshare-gui/src/gui/common/FriendList.cpp index 531a87f63..dd2d17875 100644 --- a/retroshare-gui/src/gui/common/FriendList.cpp +++ b/retroshare-gui/src/gui/common/FriendList.cpp @@ -55,6 +55,7 @@ #include "gui/chat/ChatUserNotify.h" #include "gui/connect/ConnectProgressDialog.h" #include "gui/common/ElidedLabel.h" +#include "gui/common/FilesDefs.h" #include "FriendList.h" #include "ui_FriendList.h" @@ -67,7 +68,7 @@ #define IMAGE_FRIENDINFO ":/images/info16.png" #define IMAGE_CHAT ":/icons/png/chats.png" #define IMAGE_MSG ":/icons/mail/write-mail.png" -#define IMAGE_CONNECT ":/images/connect_friend.png" +#define IMAGE_CONNECT ":/icons/connection.svg" #define IMAGE_COPYLINK ":/images/copyrslink.png" #define IMAGE_GROUP16 ":/images/user/group16.png" #define IMAGE_EDIT ":/icons/png/pencil-edit-button.png" @@ -297,8 +298,9 @@ void FriendList::peerTreeWidgetCustomPopupMenu() QMenu *contextMenu = new QMenu(this); - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -306,12 +308,14 @@ void FriendList::peerTreeWidgetCustomPopupMenu() hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("RetroShare", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); diff --git a/retroshare-gui/src/gui/common/FriendList.h b/retroshare-gui/src/gui/common/FriendList.h index 3a5c15bbe..efcf034d4 100644 --- a/retroshare-gui/src/gui/common/FriendList.h +++ b/retroshare-gui/src/gui/common/FriendList.h @@ -125,7 +125,7 @@ private: std::set openGroups; std::set openPeers; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorGroup; QColor mTextColorStatus[RS_STATUS_COUNT]; diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index 700564e5a..f8740466d 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -42,7 +42,12 @@ #define IS_MESSAGE_UNREAD(flags) (flags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER)) -#define IMAGE_GROUP24 ":/images/user/group24.png" +#define IMAGE_COWORKERS ":/icons/groups/green.svg" +#define IMAGE_FRIENDS ":/icons/groups/blue.svg" +#define IMAGE_FAMILY ":/icons/groups/purple.svg" +#define IMAGE_FAVORITES ":/icons/groups/yellow.svg" +#define IMAGE_OTHERCONTACTS ":/icons/groups/pink.svg" +#define IMAGE_OTHERGROUPS ":/icons/groups/red.svg" #define IMAGE_STAR_ON ":/images/star-on-16.png" #define IMAGE_STAR_OFF ":/images/star-off-16.png" @@ -54,7 +59,7 @@ static const uint16_t UNDEFINED_PROFILE_INDEX_VALUE = (sizeof(uintptr_t)==4)?0xf const QString RsFriendListModel::FilterString("filtered"); const uint32_t MAX_INTERNAL_DATA_UPDATE_DELAY = 300 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. -const uint32_t MAX_NODE_UPDATE_DELAY = 1 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. +const uint32_t MAX_NODE_UPDATE_DELAY = 10 ; // re-update the internal data every 5 mins. Should properly cover sleep/wake-up changes. static const uint32_t NODE_DETAILS_UPDATE_DELAY = 5; // update each node every 5 secs. @@ -236,7 +241,8 @@ RsFriendListModel::EntryIndex RsFriendListModel::EntryIndex::parent() const i.node_index = UNDEFINED_NODE_INDEX_VALUE; break; case ENTRY_TYPE_UNKNOWN: - RS_ERR("Unknown Entry type for parent."); + //Can be when request root index. + break; } return i; @@ -496,7 +502,7 @@ QVariant RsFriendListModel::sizeHintRole(const EntryIndex& e,int col) const y_factor *= 3.0; if(e.type == ENTRY_TYPE_GROUP) - y_factor = std::max(y_factor, 24.0f / 14.0f ); // allows to fit the 24 pixels icon for groups in the line + y_factor *= 1.5; switch(col) { @@ -663,7 +669,8 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const else return QVariant(QString::fromUtf8(group->group_info.name.c_str())); - //case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); + case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); + default: return QVariant(); } @@ -771,24 +778,29 @@ void RsFriendListModel::checkInternalData(bool force) { rstime_t now = time(NULL); - if(mLastInternalDataUpdate + MAX_INTERNAL_DATA_UPDATE_DELAY < now || force) + if( (mLastInternalDataUpdate + MAX_INTERNAL_DATA_UPDATE_DELAY < now) || force) updateInternalData(); - - if(mLastNodeUpdate + MAX_NODE_UPDATE_DELAY < now) - { - for(uint32_t i=0;igetPeerDetails(id,mLocations[i].node_info); - mLocations[i].last_update_ts = now; - } - - mLastNodeUpdate = now; - } +// else +// { +// preMods(); +// +// if(mLastNodeUpdate + MAX_NODE_UPDATE_DELAY < now) +// { +// for(uint32_t i=0;igetPeerDetails(id,mLocations[i].node_info); +// mLocations[i].last_update_ts = now; +// } +// +// mLastNodeUpdate = now; +// } +// postMods(); +// } } const RsFriendListModel::HierarchicalGroupInformation *RsFriendListModel::getGroupInfo(const EntryIndex& e) const @@ -864,8 +876,28 @@ QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) cons switch(entry.type) { - case ENTRY_TYPE_GROUP: return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_GROUP24)); + case ENTRY_TYPE_GROUP: + { + const HierarchicalGroupInformation *groupInfo = getGroupInfo(entry); + if (groupInfo->group_info.id.toStdString() == RS_GROUP_ID_FRIENDS.toStdString()) { + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_FRIENDS)); + } + if (groupInfo->group_info.id.toStdString() == RS_GROUP_ID_FAMILY.toStdString()) { + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_FAMILY)); + } + if (groupInfo->group_info.id.toStdString() == RS_GROUP_ID_COWORKERS.toStdString()) { + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_COWORKERS)); + } + if (groupInfo->group_info.id.toStdString() == RS_GROUP_ID_OTHERS.toStdString()) { + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_OTHERCONTACTS)); + } + if (groupInfo->group_info.id.toStdString() == RS_GROUP_ID_FAVORITES.toStdString()) { + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_FAVORITES)); + } + + return QVariant(FilesDefs::getIconFromQtResourcePath(IMAGE_OTHERGROUPS)); + } case ENTRY_TYPE_PROFILE: { if(!isProfileExpanded(entry)) @@ -1045,7 +1077,12 @@ std::map::const_iterator RsFriendListModel::createInvalidatedP if(rsPeers->getGPGDetails(pgp_id,hprof.profile_info)) { - std::cerr << "(EE) asked to create an invalidated profile that already exists!" << std::endl; + std::cerr << "(EE) asked to create an invalidated profile that already exists: " << pgp_id << std::endl; + + pgp_indices[pgp_id] = mProfiles.size(); + mProfiles.push_back(hprof); + it2 = pgp_indices.find(pgp_id); + return it2; } diff --git a/retroshare-gui/src/gui/common/FriendListModel.h b/retroshare-gui/src/gui/common/FriendListModel.h index 871dc14b9..646159377 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.h +++ b/retroshare-gui/src/gui/common/FriendListModel.h @@ -156,7 +156,7 @@ public: void clear() ; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorGroup; QColor mTextColorStatus[RS_STATUS_COUNT]; diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp index a2b355e06..2e91ded27 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp @@ -51,9 +51,9 @@ #define ROLE_SORT_STANDARD_GROUP Qt::UserRole + 2 #define ROLE_SORT_NAME Qt::UserRole + 3 #define ROLE_SORT_STATE Qt::UserRole + 4 -#define ROLE_FILTER_REASON Qt::UserRole + 5 +#define ROLE_SORT_SELECTED Qt::UserRole + 5 +#define ROLE_FILTER_REASON Qt::UserRole + 6 -#define IMAGE_GROUP16 ":/images/user/group16.png" #define IMAGE_FRIENDINFO ":/images/peerdetails_16x16.png" static bool isSelected(FriendSelectionWidget::Modus modus, QTreeWidgetItem *item) @@ -128,11 +128,45 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent) /* Refresh style to have the correct text color */ Rshare::refreshStyleSheet(this, false); + + mEventHandlerId_identities = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { + RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_identities, RsEventType::GXS_IDENTITY ); + mEventHandlerId_peers = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { + RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId_peers, RsEventType::PEER_CONNECTION ); } +void FriendSelectionWidget::handleEvent_main_thread(std::shared_ptr event) +{ + const RsGxsIdentityEvent *fe = dynamic_cast(event.get()); + + if(fe) + { + updateDisplay(true); + update(); // Qt flush + return; + } + const RsConnectionEvent *fp = dynamic_cast(event.get()); + + if(fp) + switch(fp->mConnectionInfoCode) + { + case RsConnectionEventCode::PEER_REMOVED: + case RsConnectionEventCode::PEER_ADDED: + updateDisplay(true); + update(); // Qt flush + break; + default: break ; + } +} + + FriendSelectionWidget::~FriendSelectionWidget() { - delete ui; + rsEvents->unregisterEventsHandler(mEventHandlerId_peers); + rsEvents->unregisterEventsHandler(mEventHandlerId_identities); + delete ui; } void FriendSelectionWidget::changeEvent(QEvent *e) @@ -382,12 +416,34 @@ void FriendSelectionWidget::secured_fillList() // Add item to the list ui->friendList->addTopLevelItem(groupItem); + QFontMetricsF fontMetrics(ui->friendList->font()); + int avatarHeight = fontMetrics.height() * 1.5; + ui->friendList->setIconSize(QSize(avatarHeight, avatarHeight)); + groupItem->setFlags(Qt::ItemIsUserCheckable | groupItem->flags()); groupItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless); groupItem->setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter); - groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(IMAGE_GROUP16)); - groupItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(groupInfo->id.toStdString())); + if (groupInfo->id.toStdString() == RS_GROUP_ID_FRIENDS.toStdString()) { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/blue.svg")); + } + else if (groupInfo->id.toStdString() == RS_GROUP_ID_FAMILY.toStdString()) { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/purple.svg")); + } + else if (groupInfo->id.toStdString() == RS_GROUP_ID_COWORKERS.toStdString()) { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/green.svg")); + } + else if (groupInfo->id.toStdString() == RS_GROUP_ID_OTHERS.toStdString()) { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/pink.svg")); + } + else if (groupInfo->id.toStdString() == RS_GROUP_ID_FAVORITES.toStdString()) { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/yellow.svg")); + } + else { + groupItem->setIcon(COLUMN_NAME, FilesDefs::getIconFromQtResourcePath(":/icons/groups/red.svg")); + } + + groupItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(groupInfo->id.toStdString())); groupItem->setExpanded(true); @@ -612,8 +668,13 @@ void FriendSelectionWidget::secured_fillList() emit itemAdded(IDTYPE_GXS, QString::fromStdString(detail.mId.toStdString()), gxsItem); if (std::find(gxsIdsSelected.begin(), gxsIdsSelected.end(), detail.mId) != gxsIdsSelected.end()) + { setSelected(mListModus, gxsItem, true); - } + gxsItem->setData(COLUMN_NAME,ROLE_SORT_SELECTED,0); + } + else + gxsItem->setData(COLUMN_NAME,ROLE_SORT_SELECTED,1); + } } if(mShowTypes & SHOW_CONTACTS) { @@ -1164,9 +1225,18 @@ std::string FriendSelectionWidget::idFromItem(QTreeWidgetItem *item) return item->data(COLUMN_DATA, ROLE_ID).toString().toStdString(); } +void FriendSelectionWidget::sortByChecked(bool sort) +{ + mCompareRole->clear(); + mCompareRole->setRole(COLUMN_NAME,ROLE_SORT_SELECTED); + + ui->friendList->resort(); +} + void FriendSelectionWidget::sortByState(bool sort) { - mCompareRole->setRole(COLUMN_NAME, ROLE_SORT_GROUP); + mCompareRole->clear(); + mCompareRole->setRole(COLUMN_NAME, ROLE_SORT_GROUP); mCompareRole->addRole(COLUMN_NAME, ROLE_SORT_STANDARD_GROUP); if (sort) { diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.h b/retroshare-gui/src/gui/common/FriendSelectionWidget.h index 7a2fb718e..f10a748fc 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.h +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.h @@ -24,6 +24,7 @@ #include #include +#include "retroshare/rsevents.h" #include namespace Ui { @@ -131,7 +132,8 @@ signals: public slots: void sortByState(bool sort); - void filterConnected(bool filter); + void sortByChecked(bool sort); + void filterConnected(bool filter); private slots: void groupsChanged(int type); @@ -151,6 +153,8 @@ private: void setSelectedIds_internal(IdType idType, const std::set &ids, bool add); private: + void handleEvent_main_thread(std::shared_ptr event); + bool mStarted; RSTreeWidgetItemCompareRole *mCompareRole; Modus mListModus; @@ -162,7 +166,7 @@ private: QAction *mActionSortByState; QAction *mActionFilterConnected; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorOnline; Ui::FriendSelectionWidget *ui; @@ -173,6 +177,9 @@ private: QList mContextMenuActions; std::set mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them. + + RsEventsHandlerId_t mEventHandlerId_identities; + RsEventsHandlerId_t mEventHandlerId_peers; }; Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes) diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.ui b/retroshare-gui/src/gui/common/FriendSelectionWidget.ui index d3682f014..065c9013b 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.ui +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.ui @@ -38,6 +38,11 @@ 0 + + + 11 + + Qt::CustomContextMenu diff --git a/retroshare-gui/src/gui/common/GroupChooser.cpp b/retroshare-gui/src/gui/common/GroupChooser.cpp index be456f96d..8cdf2fd2d 100644 --- a/retroshare-gui/src/gui/common/GroupChooser.cpp +++ b/retroshare-gui/src/gui/common/GroupChooser.cpp @@ -20,15 +20,16 @@ #include "GroupChooser.h" +#include + +#include + #include #include -#include -#include - /** Constructor */ GroupChooser::GroupChooser(QWidget *parent) -: QComboBox(parent), mFlags(0) + : RSComboBox(parent), mFlags(0) { return; } diff --git a/retroshare-gui/src/gui/common/GroupChooser.h b/retroshare-gui/src/gui/common/GroupChooser.h index fa7e2eba7..04d821bc2 100644 --- a/retroshare-gui/src/gui/common/GroupChooser.h +++ b/retroshare-gui/src/gui/common/GroupChooser.h @@ -20,13 +20,14 @@ #pragma once -#include +#include "gui/common/RSComboBox.h" + #include -class GroupChooser : public QComboBox +class GroupChooser : public RSComboBox { public: - GroupChooser(QWidget *parent = NULL); + GroupChooser(QWidget *parent = nullptr); void loadGroups(uint32_t chooserFlags, const RsNodeGroupId& defaultId); bool getChosenGroup(RsNodeGroupId& id); diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp index 685c54169..0597a652c 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.cpp @@ -60,16 +60,25 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterChanged())); connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint))); - connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); + connect(ui->treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*))); connect(ui->treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(itemActivated(QTreeWidgetItem*,int))); if (!style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, NULL, this)) { // need signal itemClicked too connect(ui->treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(itemActivated(QTreeWidgetItem*,int))); } + int H = QFontMetricsF(ui->treeWidget->font()).height() ; +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui->treeWidget->font()).width("_") ; + int D = QFontMetricsF(ui->treeWidget->font()).width("9999-99-99[]") ; +#else + int W = QFontMetricsF(ui->treeWidget->font()).horizontalAdvance("_") ; + int D = QFontMetricsF(ui->treeWidget->font()).horizontalAdvance("9999-99-99[]") ; +#endif + /* Add own item delegate */ RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); - itemDelegate->setSpacing(QSize(0, 2)); + itemDelegate->setSpacing(QSize(W/2, H/4)); ui->treeWidget->setItemDelegate(itemDelegate); /* Set compare role for each column */ @@ -87,10 +96,6 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : ui->treeWidget->enableColumnCustomize(true); ui->treeWidget->setColumnCustomizable(GTW_COLUMN_NAME, false); - int S = QFontMetricsF(font()).height() ; - int W = QFontMetricsF(font()).width("_") ; - int D = QFontMetricsF(font()).width("9999-99-99[]") ; - QTreeWidgetItem *headerItem = ui->treeWidget->headerItem(); headerItem->setText(GTW_COLUMN_NAME, tr("Name")); headerItem->setText(GTW_COLUMN_UNREAD, ""); @@ -143,7 +148,7 @@ GroupTreeWidget::GroupTreeWidget(QWidget *parent) : connect(ui->distantSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(distantSearch())) ; - ui->treeWidget->setIconSize(QSize(S*1.8,S*1.8)); + ui->treeWidget->setIconSize(QSize(H*1.8,H*1.8)); } GroupTreeWidget::~GroupTreeWidget() @@ -205,9 +210,9 @@ void GroupTreeWidget::updateColors() int color = item->data(GTW_COLUMN_DATA, ROLE_COLOR).toInt(); if (color >= 0) { - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, mTextColor[color]); + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, mTextColor[color]); } else { - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, QVariant()); + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, QVariant()); } } @@ -246,7 +251,6 @@ void GroupTreeWidget::itemActivated(QTreeWidgetItem *item, int column) QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIcon &icon, bool expand, int sortOrder /*= -1*/) { - QFont font; RSTreeWidgetItem *item = new RSTreeWidgetItem(); ui->treeWidget->addTopLevelItem(item); // To get StyleSheet for Items @@ -255,15 +259,16 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc item->setText(GTW_COLUMN_NAME, name); item->setData(GTW_COLUMN_DATA, ROLE_NAME, name); - font = item->font(GTW_COLUMN_NAME); - font.setBold(true); - item->setFont(GTW_COLUMN_NAME, font); + QFont itFont = item->font(GTW_COLUMN_NAME); + itFont.setBold(true); + itFont.setPointSize(ui->treeWidget->font().pointSize()); //use treeWidget font size defined in ui. + item->setFont(GTW_COLUMN_NAME, itFont); item->setIcon(GTW_COLUMN_NAME, icon); - int S = QFontMetricsF(font).height(); + //int S = QFontMetricsF(itFont).height(); - item->setSizeHint(GTW_COLUMN_NAME, QSize(S*1.9, S*1.9)); - item->setData(GTW_COLUMN_NAME, Qt::TextColorRole, textColorCategory()); + //item->setSizeHint(GTW_COLUMN_NAME, QSize(S*1.9, S*1.9)); //size hint is calculated by item delegate. Use itemDelegate->setSpacing() in constructor. + item->setData(GTW_COLUMN_NAME, Qt::ForegroundRole, textColorCategory()); item->setData(GTW_COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY); item->setExpanded(expand); @@ -385,6 +390,7 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList< if (item == NULL) { item = new RSTreeWidgetItem(compareRole); item->setData(GTW_COLUMN_DATA, ROLE_ID, itemInfo.id); + item->setFont(GTW_COLUMN_DATA, ui->treeWidget->font()); //static_cast(item)->setNoDataAsLast(true); //Uncomment this to sort data with QVariant() always at end. categoryItem->addChild(item); } @@ -506,18 +512,18 @@ void GroupTreeWidget::setUnreadCount(QTreeWidgetItem *item, int unreadCount) return; } - QFont font = item->font(GTW_COLUMN_NAME); + QFont itFont = item->font(GTW_COLUMN_NAME); if (unreadCount) { item->setText(GTW_COLUMN_UNREAD, QString::number(unreadCount)); - font.setBold(true); + itFont.setBold(true); } else { item->setText(GTW_COLUMN_UNREAD, ""); - font.setBold(false); + itFont.setBold(false); } item->setData(GTW_COLUMN_UNREAD, ROLE_SORT, unreadCount); - item->setFont(GTW_COLUMN_NAME, font); + item->setFont(GTW_COLUMN_NAME, itFont); } QTreeWidgetItem *GroupTreeWidget::getItemFromId(const QString &id) diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.h b/retroshare-gui/src/gui/common/GroupTreeWidget.h index 6125dac28..b27c37014 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.h +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.h @@ -158,7 +158,7 @@ private: private: - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColor[GROUPTREEWIDGET_COLOR_COUNT]; // Compare role used for each column diff --git a/retroshare-gui/src/gui/common/GroupTreeWidget.ui b/retroshare-gui/src/gui/common/GroupTreeWidget.ui index f925cf8ed..d3e0a14a5 100644 --- a/retroshare-gui/src/gui/common/GroupTreeWidget.ui +++ b/retroshare-gui/src/gui/common/GroupTreeWidget.ui @@ -70,6 +70,11 @@ 0 + + + 11 + + Qt::CustomContextMenu diff --git a/retroshare-gui/src/gui/common/HeaderFrame.ui b/retroshare-gui/src/gui/common/HeaderFrame.ui index 45a65943a..f9c436f68 100644 --- a/retroshare-gui/src/gui/common/HeaderFrame.ui +++ b/retroshare-gui/src/gui/common/HeaderFrame.ui @@ -16,15 +16,24 @@ 76 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + 0 @@ -37,7 +46,7 @@ 76 - + 12 @@ -67,7 +76,14 @@ - + + + + 22 + 75 + true + + Header text @@ -77,7 +93,7 @@ - + QFrame::HLine @@ -90,9 +106,9 @@ - StyledElidedLabel + ElidedLabel QLabel -
gui/common/StyledElidedLabel.h
+
gui/common/ElidedLabel.h
diff --git a/retroshare-gui/src/gui/common/LineEditClear.cpp b/retroshare-gui/src/gui/common/LineEditClear.cpp index b439aaa07..c3d68b512 100644 --- a/retroshare-gui/src/gui/common/LineEditClear.cpp +++ b/retroshare-gui/src/gui/common/LineEditClear.cpp @@ -29,17 +29,18 @@ #include #endif -#define IMAGE_FILTER ":/images/find-16.png" +#define IMAGE_FILTER ":/images/find.png" LineEditClear::LineEditClear(QWidget *parent) - : QLineEdit(parent) + : QLineEdit(parent) { mActionGroup = NULL; mFilterButton = NULL; + QFontMetrics fm(this->font()); mClearButton = new QToolButton(this); - mClearButton->setFixedSize(16, 16); - mClearButton->setIconSize(QSize(16, 16)); + mClearButton->setFixedSize(fm.height(), fm.height()); + mClearButton->setIconSize(QSize(fm.height(), fm.height())); mClearButton->setCursor(Qt::ArrowCursor); mClearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" "QToolButton { border-image: url(:/images/closenormal.png) }" @@ -50,7 +51,7 @@ LineEditClear::LineEditClear(QWidget *parent) mClearButton->setToolTip("Clear Filter"); connect(mClearButton, SIGNAL(clicked()), this, SLOT(clear())); - connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateClearButton(const QString&))); + connect(this, SIGNAL(textChanged(QString)), this, SLOT(updateClearButton(QString))); //#if QT_VERSION < 0x040700 #if QT_VERSION < 0x050000//PlaceHolder text only shown when not have focus in Qt4 @@ -124,15 +125,18 @@ void LineEditClear::showFilterIcon() } mFilterButton = new QToolButton(this); - mFilterButton->setFixedSize(16, 16); - mFilterButton->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER)); - //mFilterButton->setIconSize(filterPixmap.size()); - mFilterButton->setCursor(Qt::ArrowCursor); - mFilterButton->setStyleSheet("QToolButton { border: none; padding: 0px; }" - "QToolButton[popupMode=\"2\"] { padding-right: 10px; }" - "QToolButton::menu-indicator[popupMode=\"2\"] { subcontrol-origin: padding; subcontrol-position: bottom right; top: 5px; left: -3px; width: 7px; }"); - mFilterButton->move(2, 2); + mFilterButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); mFilterButton->setFocusPolicy(Qt::NoFocus); + mFilterButton->setPopupMode(QToolButton::InstantPopup); + mFilterButton->setAutoFillBackground(true); + mFilterButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + setFilterButtonIcon(QIcon()); + mFilterButton->setCursor(Qt::ArrowCursor); + mFilterButton->setStyleSheet("QToolButton { background: transparent; border: none; margin: 0px; padding: 0px; }" + "QToolButton[popupMode=\"2\"] { padding-right: 10px; }" + "QToolButton::menu-indicator[popupMode=\"2\"] { subcontrol-origin: padding; subcontrol-position: bottom right; top: 5px; left: -3px; width: 7px; }" + ); + mFilterButton->move(2, 2); reposButtons(); } @@ -155,9 +159,6 @@ void LineEditClear::addFilter(const QIcon &icon, const QString &text, int id, co showFilterIcon(); if (mActionGroup == NULL) { - mFilterButton->setFixedSize(26, 16); - mFilterButton->setPopupMode(QToolButton::InstantPopup); - mActionGroup = new QActionGroup(this); mActionGroup->setExclusive(true); @@ -222,10 +223,19 @@ void LineEditClear::activateAction(QAction *action) setPlaceholderText(*description); } - QIcon icon = action->icon(); - if (icon.isNull()) { - icon = FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER); - } - - mFilterButton->setIcon(icon); + setFilterButtonIcon(action->icon()); +} + +void LineEditClear::setFilterButtonIcon(const QIcon &icon) +{ + if (icon.isNull()) + mFilterButton->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_FILTER)); + else + mFilterButton->setIcon(icon); + + ensurePolished(); + QFontMetrics fm(this->font()); + QSize size(fm.width("___"), fm.height()); + mFilterButton->setFixedSize(size); + mFilterButton->setIconSize(size); } diff --git a/retroshare-gui/src/gui/common/LineEditClear.h b/retroshare-gui/src/gui/common/LineEditClear.h index e8aea0626..ae30f6127 100644 --- a/retroshare-gui/src/gui/common/LineEditClear.h +++ b/retroshare-gui/src/gui/common/LineEditClear.h @@ -61,6 +61,7 @@ protected: #endif void reposButtons(); void activateAction(QAction *action); + void setFilterButtonIcon(const QIcon &icon); private slots: void updateClearButton(const QString &text); diff --git a/retroshare-gui/src/gui/common/MimeTextEdit.cpp b/retroshare-gui/src/gui/common/MimeTextEdit.cpp index b24a65879..3d3398b0c 100644 --- a/retroshare-gui/src/gui/common/MimeTextEdit.cpp +++ b/retroshare-gui/src/gui/common/MimeTextEdit.cpp @@ -32,6 +32,7 @@ #include "MimeTextEdit.h" #include "util/HandleRichText.h" #include "gui/RetroShareLink.h" +#include "util/imageutil.h" #include @@ -246,6 +247,18 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e) QMenu *contextMenu = createStandardContextMenu(e->pos()); + if (ImageUtil::checkImage(this, e->pos())) { + contextMenu->addSeparator(); + + QAction *a = contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage())); + a->setData(e->pos()); + + a = contextMenu->addAction( tr("Copy image"), this, SLOT(copyImage())); + a->setData(e->pos()); + + contextMenu->addSeparator(); + } + /* Add actions for pasting links */ contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText())); QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler())); @@ -292,3 +305,27 @@ void MimeTextEdit::spoiler() { RsHtml::insertSpoilerText(this->textCursor()); } + +void MimeTextEdit::saveImage() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QPoint point = action->data().toPoint(); + QTextCursor cursor = cursorForPosition(point); + ImageUtil::extractImage(window(), cursor); +} + +void MimeTextEdit::copyImage() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QPoint point = action->data().toPoint(); + QTextCursor cursor = cursorForPosition(point); + ImageUtil::copyImage(window(), cursor); +} diff --git a/retroshare-gui/src/gui/common/MimeTextEdit.h b/retroshare-gui/src/gui/common/MimeTextEdit.h index 9c47cac23..b575c1ac9 100644 --- a/retroshare-gui/src/gui/common/MimeTextEdit.h +++ b/retroshare-gui/src/gui/common/MimeTextEdit.h @@ -75,6 +75,8 @@ private slots: void pasteOwnCertificateLink(); void pastePlainText(); void spoiler(); + void saveImage(); + void copyImage(); private: QString textUnderCursor() const; diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index a23687651..893433469 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -40,7 +40,6 @@ #include "gui/connect/ConnectFriendWizard.h" #include "gui/groups/CreateGroup.h" #include "gui/msgs/MessageComposer.h" -#include "gui/notifyqt.h" #include "gui/RetroShareLink.h" #include "retroshare-gui/RsAutoUpdatePage.h" #ifdef UNFINISHED_FD @@ -67,17 +66,17 @@ #define IMAGE_FRIENDINFO ":/images/info16.png" #define IMAGE_CHAT ":/icons/png/chats.png" #define IMAGE_MSG ":/icons/mail/write-mail.png" -#define IMAGE_CONNECT ":/images/connect_friend.png" +#define IMAGE_CONNECT ":/icons/connection.svg" #define IMAGE_COPYLINK ":/images/copyrslink.png" -#define IMAGE_GROUP16 ":/images/user/group16.png" +#define IMAGE_GROUPS ":/icons/groups/colored.svg" #define IMAGE_EDIT ":/icons/png/pencil-edit-button.png" -#define IMAGE_REMOVE ":/images/delete.png" -#define IMAGE_EXPAND ":/images/edit_add24.png" -#define IMAGE_COLLAPSE ":/images/edit_remove24.png" +#define IMAGE_EXPAND ":/icons/plus.svg" +#define IMAGE_COLLAPSE ":/icons/minus.svg" +#define IMAGE_REMOVE ":/icons/cancel.svg" +#define IMAGE_ADD ":/icons/png/add.png" /* Images for Status icons */ #define IMAGE_AVAILABLE ":/images/user/identityavaiblecyan24.png" #define IMAGE_PASTELINK ":/images/pasterslink.png" -#define IMAGE_GROUP24 ":/images/user/group24.png" #define COLUMN_DATA 0 // column for storing the userdata id @@ -100,10 +99,18 @@ /****** * #define FRIENDS_DEBUG 1 + * #define DEBUG_NEW_FRIEND_LIST 1 *****/ Q_DECLARE_METATYPE(ElidedLabel*) +#ifdef DEBUG_NEW_FRIEND_LIST +static std::ostream& operator<<(std::ostream& o,const QModelIndex& i) +{ + return o << "(" << i.row() << "," << i.column() << ")"; +} +#endif + class FriendListSortFilterProxyModel: public QSortFilterProxyModel { public: @@ -118,7 +125,7 @@ public: bool lessThan(const QModelIndex& left, const QModelIndex& right) const override { - bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; + bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; bool is_group_2 = right.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; if(is_group_1 ^ is_group_2) // if the two are different, put the group first. @@ -127,10 +134,13 @@ public: bool online1 = (left .data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); bool online2 = (right.data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); - if(online1 != online2 && m_sortByState) + if((online1 != online2) && m_sortByState) return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?online1:online2 ; // always put online nodes first - return left.data(RsFriendListModel::SortRole) < right.data(RsFriendListModel::SortRole) ; +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Comparing index " << left << " with index " << right << std::endl; +#endif + return QSortFilterProxyModel::lessThan(left,right); } bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override @@ -174,12 +184,21 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par { ui->setupUi(this); + int H = QFontMetricsF(ui->peerTreeWidget->font()).height(); +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + int W = QFontMetricsF(ui->peerTreeWidget->font()).width("_"); +#else + int W = QFontMetricsF(ui->peerTreeWidget->font()).horizontalAdvance("_"); +#endif + ui->filterLineEdit->setPlaceholderText(tr("Search")) ; ui->filterLineEdit->showFilterIcon(); mEventHandlerId_peer=0; // forces initialization mEventHandlerId_gssp=0; // forces initialization + mEventHandlerId_pssc=0; // forces initialization + rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_pssc, RsEventType::PEER_STATE_CHANGED ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_peer, RsEventType::PEER_CONNECTION ); rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId_gssp, RsEventType::GOSSIP_DISCOVERY ); @@ -193,7 +212,9 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par mProxyModel->setFilterRegExp(QRegExp(RsFriendListModel::FilterString)); ui->peerTreeWidget->setModel(mProxyModel); - ui->peerTreeWidget->setItemDelegate(new RSElidedItemDelegate()); + RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); + itemDelegate->setSpacing(QSize(W/2, H/4)); + ui->peerTreeWidget->setItemDelegate(itemDelegate); ui->peerTreeWidget->setWordWrap(false); /* Add filter actions */ @@ -210,29 +231,27 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par /* Set sort */ sortColumn(RsFriendListModel::COLUMN_THREAD_NAME, Qt::AscendingOrder); - toggleSortByState(false); + // workaround for Qt bug, should be solved in next Qt release 4.7.0 // http://bugreports.qt.nokia.com/browse/QTBUG-8270 QShortcut *Shortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->peerTreeWidget, 0, 0, Qt::WidgetShortcut); connect(Shortcut, SIGNAL(activated()), this, SLOT(removeItem()),Qt::QueuedConnection); - QFontMetricsF fontMetrics(ui->peerTreeWidget->font()); + /* Set initial column width */ + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_NAME , 22 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_IP , 15 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_ID , 32 * W); + ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT, 12 * W); - /* Set initial column width */ - int fontWidth = fontMetrics.width("W"); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_NAME , 22 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_IP , 15 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_ID , 32 * fontWidth); - ui->peerTreeWidget->setColumnWidth(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT, 12 * fontWidth); - - int avatarHeight = fontMetrics.height() * 3; - ui->peerTreeWidget->setIconSize(QSize(avatarHeight, avatarHeight)); + ui->peerTreeWidget->setIconSize(QSize(H*2, H*2)); mModel->checkInternalData(true); QHeaderView *h = ui->peerTreeWidget->header(); h->setContextMenuPolicy(Qt::CustomContextMenu); + processSettings(true); + connect(ui->peerTreeWidget->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumn(int,Qt::SortOrder))); connect(ui->peerTreeWidget, SIGNAL(expanded(const QModelIndex&)), this, SLOT(itemExpanded(const QModelIndex&))); @@ -240,11 +259,6 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par connect(mActionSortByState, SIGNAL(toggled(bool)), this, SLOT(toggleSortByState(bool))); connect(ui->peerTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(peerTreeWidgetCustomPopupMenu())); - // Using Queued connections here is pretty important since the notifications may come from a different thread. - - connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool))); connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) ); connect(ui->actionShowGroups, SIGNAL(triggered(bool)), this, SLOT(setShowGroups(bool)) ); @@ -272,6 +286,7 @@ NewFriendList::~NewFriendList() { rsEvents->unregisterEventsHandler(mEventHandlerId_peer); rsEvents->unregisterEventsHandler(mEventHandlerId_gssp); + rsEvents->unregisterEventsHandler(mEventHandlerId_pssc); delete mModel; delete mProxyModel; @@ -287,27 +302,13 @@ void NewFriendList::itemCollapsed(const QModelIndex& index) mModel->collapseItem(mProxyModel->mapToSource(index)); } -void NewFriendList::sortColumn(int col,Qt::SortOrder so) -{ - std::set expanded_indexes; - std::set selected_indexes; - - saveExpandedPathsAndSelection(expanded_indexes, selected_indexes); - mProxyModel->setSortingEnabled(true); - mProxyModel->sort(col,so); - mProxyModel->setSortingEnabled(false); - restoreExpandedPathsAndSelection(expanded_indexes, selected_indexes); - - mLastSortColumn = col; - mLastSortOrder = so; -} - void NewFriendList::headerContextMenuRequested(QPoint /*p*/) { QMenu displayMenu(tr("Show Items"), this); - QWidget *widget = new QWidget(&displayMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(&displayMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -315,12 +316,14 @@ void NewFriendList::headerContextMenuRequested(QPoint /*p*/) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("Show/hide...", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); @@ -381,77 +384,103 @@ void NewFriendList::addToolButton(QToolButton *toolButton) toolButton->setIconSize(QSize(S*1.5,S*1.5)); toolButton->setFocusPolicy(Qt::NoFocus); - ui->titleBarFrame->layout()->addWidget(toolButton); + ui->toolBarFrame->layout()->addWidget(toolButton); } -void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_indexes, std::set& selected_indexes) +void NewFriendList::saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel) { + QModelIndexList selectedIndexes = ui->peerTreeWidget->selectionModel()->selectedIndexes(); + QModelIndex current_index = selectedIndexes.empty()?QModelIndex():(*selectedIndexes.begin()); + #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << "Saving expended paths and selection..." << std::endl; #endif for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursSaveExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,selected_indexes); + recursSaveExpandedItems(mProxyModel->index(row,0),current_index,QString(),expanded_indexes,sel,0); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << " selected index: \"" << sel.toStdString() << "\"" << std::endl; +#endif } -void NewFriendList::restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const std::set& selected_indexes) +void NewFriendList::restoreExpandedPathsAndSelection(const std::set& expanded_indexes,const QString& index_to_select,QModelIndex& selected_index) { #ifdef DEBUG_NEW_FRIEND_LIST std::cerr << "Restoring expended paths and selection..." << std::endl; + std::cerr << " index to select: \"" << index_to_select.toStdString() << "\"" << std::endl; #endif ui->peerTreeWidget->blockSignals(true) ; for(int row = 0; row < mProxyModel->rowCount(); ++row) - recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,selected_indexes); + recursRestoreExpandedItems(mProxyModel->index(row,0),QString(),expanded_indexes,index_to_select,selected_index,0); ui->peerTreeWidget->blockSignals(false) ; } -void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QString& parent_path,std::set& exp, std::set& sel) +void NewFriendList::recursSaveExpandedItems(const QModelIndex& index,const QModelIndex& current_index,const QString& parent_path,std::set& exp, QString& sel,int indx) { - QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; + QString local_path = parent_path + (parent_path.isNull()?"":"/") + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() ; - if(ui->peerTreeWidget->selectionModel()->selection().contains(index)) - sel.insert(local_path) ; +#ifdef DEBUG_NEW_FRIEND_LIST + for(int i=0;ipeerTreeWidget->isExpanded(index)) { #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "Index " << local_path.toStdString() << " is expanded." << std::endl; + std::cerr << " expanded." << std::endl; #endif if(index.isValid()) exp.insert(local_path) ; for(int row=0;rowrowCount(index);++row) - recursSaveExpandedItems(index.child(row,0),local_path,exp,sel) ; + recursSaveExpandedItems(index.child(row,0),current_index,local_path,exp,sel,indx+1) ; } #ifdef DEBUG_NEW_FRIEND_LIST else - std::cerr << "Index " << local_path.toStdString() << " is not expanded." << std::endl; + std::cerr << " not expanded." << std::endl; #endif + + if(index == current_index) + sel = local_path ; } -void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const std::set &sel) +void NewFriendList::recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString& sel,QModelIndex& selected_index,int indx) { - QString local_path = parent_path + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() + " "; + QString local_path = parent_path + (parent_path.isNull()?"":"/") + index.sibling(index.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole).toString() ; #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "at index " << index.row() << ". data[1]=" << local_path.toStdString() << std::endl; -#endif + for(int i=0;ipeerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + if(sel == local_path) + std::cerr << " selecting" ; +#endif if(exp.find(local_path) != exp.end()) { #ifdef DEBUG_NEW_FRIEND_LIST - std::cerr << "re expanding index " << local_path.toStdString() << std::endl; + std::cerr << " re expanding " << std::endl; #endif ui->peerTreeWidget->setExpanded(index,true) ; for(int row=0;rowrowCount(index);++row) - recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel) ; + recursRestoreExpandedItems(index.child(row,0),local_path,exp,sel,selected_index,indx+1) ; + } +#ifdef DEBUG_NEW_FRIEND_LIST + else + std::cerr << std::endl; +#endif + + if(sel == local_path) + { + ui->peerTreeWidget->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + selected_index = index; } } @@ -463,20 +492,26 @@ void NewFriendList::processSettings(bool load) if (load) // load settings { std::cerr <<"Re-loading settings..." << std::endl; + // sort + mProxyModel->setSortByState( Settings->value("sortByState", mProxyModel->sortByState()).toBool()); + mProxyModel->setShowOfflineNodes(!Settings->value("hideUnconnected", !mProxyModel->showOfflineNodes()).toBool()); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Loading sortByState=" << mProxyModel->sortByState() << std::endl; +#endif + // states setShowUnconnected(!Settings->value("hideUnconnected", !mProxyModel->showOfflineNodes()).toBool()); - setShowState(Settings->value("showState", mModel->getDisplayStatusString()).toBool()); - setShowGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool()); + + mModel->setDisplayStatusString(Settings->value("showState", mModel->getDisplayStatusString()).toBool()); + mModel->setDisplayGroups(Settings->value("showGroups", mModel->getDisplayGroups()).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_IP,Settings->value("showIP", isColumnVisible(RsFriendListModel::COLUMN_THREAD_IP)).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_ID,Settings->value("showID", isColumnVisible(RsFriendListModel::COLUMN_THREAD_ID)).toBool()); setColumnVisible(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT,Settings->value("showLastContact", isColumnVisible(RsFriendListModel::COLUMN_THREAD_LAST_CONTACT)).toBool()); ui->peerTreeWidget->header()->restoreState(Settings->value("headers").toByteArray()); - // sort - toggleSortByState(Settings->value("sortByState", mProxyModel->sortByState()).toBool()); - - // open groups + // open groups int arrayIndex = Settings->beginReadArray("Groups"); for (int index = 0; index < arrayIndex; ++index) { Settings->setArrayIndex(index); @@ -501,8 +536,9 @@ void NewFriendList::processSettings(bool load) // sort Settings->setValue("sortByState", mProxyModel->sortByState()); - - Settings->endArray(); +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Saving sortByState=" << mProxyModel->sortByState() << std::endl; +#endif } } @@ -510,6 +546,7 @@ void NewFriendList::toggleSortByState(bool sort) { mProxyModel->setSortByState(sort); mProxyModel->setFilterRegExp(QRegExp(QString(RsFriendListModel::FilterString))) ;// triggers a re-display. + processSettings(false); } void NewFriendList::changeEvent(QEvent *e) @@ -535,8 +572,9 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() QMenu contextMenu(this); - QWidget *widget = new QWidget(&contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -544,12 +582,14 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); + iconLabel->setObjectName("trans_Icon"); QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/user/friends24.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("Friend list", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); @@ -647,8 +687,8 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() } } - QMenu *groupsMenu = contextMenu.addMenu(FilesDefs::getIconFromQtResourcePath(IMAGE_GROUP16), tr("Groups")); - groupsMenu->addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_EXPAND), tr("Create new group"), this, SLOT(createNewGroup())); + QMenu *groupsMenu = contextMenu.addMenu(FilesDefs::getIconFromQtResourcePath(IMAGE_GROUPS), tr("Groups")); + groupsMenu->addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_ADD), tr("Create new group"), this, SLOT(createNewGroup())); if (addToGroupMenu || moveToGroupMenu || foundGroup) { if (addToGroupMenu) { @@ -668,7 +708,7 @@ void NewFriendList::peerTreeWidgetCustomPopupMenu() mModel->getGroupData(parent,info); QAction *removeFromGroup = groupsMenu->addAction(tr("Remove from group ")+QString::fromUtf8(info.name.c_str())); - removeFromGroup->setData(parent.sibling(parent.row(),RsFriendListModel::COLUMN_THREAD_ID).data(Qt::DisplayRole)); + removeFromGroup->setData(QString::fromStdString(info.id.toStdString())); connect(removeFromGroup, SIGNAL(triggered()), this, SLOT(removeFromGroup())); } @@ -738,6 +778,7 @@ void NewFriendList::createNewGroup() { CreateGroup createGrpDialog (RsNodeGroupId(), this); createGrpDialog.exec(); + checkInternalData(true); } #ifdef NOT_USED @@ -1031,11 +1072,6 @@ void NewFriendList::forceUpdateDisplay() checkInternalData(true); } -// void NewFriendList::updateDisplay() -// { -// checkInternalData(false); -// } - void NewFriendList::moveToGroup() { RsFriendListModel::RsProfileDetails pinfo; @@ -1109,9 +1145,18 @@ void NewFriendList::removeGroup() void NewFriendList::applyWhileKeepingTree(std::function predicate) { std::set expanded_indexes; - std::set selected_indexes; + QString selected; - saveExpandedPathsAndSelection(expanded_indexes, selected_indexes); + saveExpandedPathsAndSelection(expanded_indexes, selected); + +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "After collecting selection, selected paths is: \"" << selected.toStdString() << "\", " ; + std::cerr << "expanded paths are: " << std::endl; + for(auto path:expanded_indexes) + std::cerr << " \"" << path.toStdString() << "\"" << std::endl; + std::cerr << "Current sort column is: " << mLastSortColumn << " and order is " << mLastSortOrder << std::endl; +#endif + whileBlocking(ui->peerTreeWidget)->clearSelection(); // This is a hack to avoid crashes on windows while calling endInsertRows(). I'm not sure wether these crashes are // due to a Qt bug, or a misuse of the proxy model on my side. Anyway, this solves them for good. @@ -1127,13 +1172,16 @@ void NewFriendList::applyWhileKeepingTree(std::function predicate) col_sizes[i] = ui->peerTreeWidget->columnWidth(i); } - +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Applying predicate..." << std::endl; +#endif mProxyModel->setSourceModel(nullptr); predicate(); + QModelIndex selected_index; mProxyModel->setSourceModel(mModel); - restoreExpandedPathsAndSelection(expanded_indexes, selected_indexes); + restoreExpandedPathsAndSelection(expanded_indexes,selected,selected_index); // restore hidden columns for(uint32_t i=0;i predicate) } // restore sorting - sortColumn(mLastSortColumn,mLastSortOrder); + // sortColumn(mLastSortColumn,mLastSortOrder); +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Sorting again with sort column: " << mLastSortColumn << " and order " << mLastSortOrder << std::endl; +#endif + mProxyModel->setSortingEnabled(true); + mProxyModel->sort(mLastSortColumn,mLastSortOrder); + mProxyModel->setSortingEnabled(false); + + if(selected_index.isValid()) + ui->peerTreeWidget->scrollTo(selected_index); } +void NewFriendList::sortColumn(int col,Qt::SortOrder so) +{ +#ifdef DEBUG_NEW_FRIEND_LIST + std::cerr << "Sorting with column=" << col << " and order=" << so << std::endl; +#endif + std::set expanded_indexes; + QString selected; + QModelIndex selected_index; + + saveExpandedPathsAndSelection(expanded_indexes, selected); + whileBlocking(ui->peerTreeWidget)->clearSelection(); + + mProxyModel->setSortingEnabled(true); + mProxyModel->sort(col,so); + mProxyModel->setSortingEnabled(false); + + restoreExpandedPathsAndSelection(expanded_indexes,selected,selected_index); + + if(selected_index.isValid()) + ui->peerTreeWidget->scrollTo(selected_index); + + mLastSortColumn = col; + mLastSortOrder = so; +} + + void NewFriendList::checkInternalData(bool force) { applyWhileKeepingTree([force,this]() { mModel->checkInternalData(force) ; }); @@ -1278,7 +1361,7 @@ bool NewFriendList::exportFriendlist(QString &fileName) if (!rsPeers->getPeerDetails(*list_iter2, detailSSL)) continue; - std::string certificate = rsPeers->GetRetroshareInvite(detailSSL.id, RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::DNS | RetroshareInviteFlags::RADIX_FORMAT); + std::string certificate = rsPeers->GetRetroshareInvite(detailSSL.id, RsPeers::defaultCertificateFlags | RetroshareInviteFlags::RADIX_FORMAT); // remove \n from certificate certificate.erase(std::remove(certificate.begin(), certificate.end(), '\n'), certificate.end()); @@ -1555,11 +1638,13 @@ void NewFriendList::toggleColumnVisible() void NewFriendList::setShowState(bool show) { applyWhileKeepingTree([show,this]() { mModel->setDisplayStatusString(show) ; }); + processSettings(false); } void NewFriendList::setShowGroups(bool show) { applyWhileKeepingTree([show,this]() { mModel->setDisplayGroups(show) ; }); + processSettings(false); } /** diff --git a/retroshare-gui/src/gui/common/NewFriendList.h b/retroshare-gui/src/gui/common/NewFriendList.h index 79b2d0a5a..cf2e892b3 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.h +++ b/retroshare-gui/src/gui/common/NewFriendList.h @@ -106,10 +106,10 @@ private: void applyWhileKeepingTree(std::function predicate); void expandGroup(const RsNodeGroupId& gid); - void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const std::set &sel); - void recursSaveExpandedItems(const QModelIndex& index,const QString& parent_path,std::set& exp, std::set& sel); - void saveExpandedPathsAndSelection(std::set& expanded_indexes, std::set& selected_indexes); - void restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const std::set& selected_indexes); + void recursRestoreExpandedItems(const QModelIndex& index, const QString& parent_path, const std::set& exp, const QString &sel, QModelIndex &selected_index,int indx); + void recursSaveExpandedItems(const QModelIndex& index, const QModelIndex& current_index, const QString& parent_path, std::set& exp, QString &sel,int indx); + void saveExpandedPathsAndSelection(std::set& expanded_indexes, QString& sel); + void restoreExpandedPathsAndSelection(const std::set& expanded_indexes, const QString &index_to_select, QModelIndex &selected_index); void checkInternalData(bool force); @@ -123,6 +123,7 @@ private: bool mShowState; RsEventsHandlerId_t mEventHandlerId_peer; RsEventsHandlerId_t mEventHandlerId_gssp; + RsEventsHandlerId_t mEventHandlerId_pssc; std::set openGroups; std::set openPeers; diff --git a/retroshare-gui/src/gui/common/NewFriendList.ui b/retroshare-gui/src/gui/common/NewFriendList.ui index 3ec1c6c03..20ae02eb2 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.ui +++ b/retroshare-gui/src/gui/common/NewFriendList.ui @@ -10,7 +10,7 @@ 292
- + 0 @@ -27,14 +27,14 @@ 0 - + QFrame::Box QFrame::Sunken - + 3 @@ -58,6 +58,11 @@ + + + 12 + + Qt::CustomContextMenu @@ -124,7 +129,7 @@ LineEditClear QLineEdit -
gui/common/LineEditClear.h
+
gui/common/LineEditClear.h
diff --git a/retroshare-gui/src/gui/common/RSComboBox.cpp b/retroshare-gui/src/gui/common/RSComboBox.cpp new file mode 100644 index 000000000..e11a3c99d --- /dev/null +++ b/retroshare-gui/src/gui/common/RSComboBox.cpp @@ -0,0 +1,59 @@ +/******************************************************************************* + * gui/common/RSComboBox.cpp * + * * + * Copyright (C) 2010, Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "RSComboBox.h" + +#include "gui/common/RSElidedItemDelegate.h" + +#include +#include + +RSComboBox::RSComboBox(QWidget *parent /*= nullptr*/) + :QComboBox(parent) +{ + // To Fix ComboBox item delegate not respecting stylesheet. See QDarkStyleSheet issues 214 + setItemDelegate(new RSElidedItemDelegate()); + view()->installEventFilter(this); +} + +bool RSComboBox::eventFilter(QObject *obj, QEvent *event) +{ + if(QAbstractItemView* view = dynamic_cast(obj)) + { + // To Fix ComboBox item delegate not respecting stylesheet. See QDarkStyleSheet issues 214 + // With QStyleItemDelegate QComboBox::item:checked doesn't works. + // With QComboBox ::item:checked, it's applied to hover ones. + if (event->type() == QEvent::Show) + { + if(QComboBox* cmb = dynamic_cast(view->parent()->parent()) ) + { + for (int curs = 0; curs < cmb->count(); ++curs) + { + QFont font = cmb->itemData(curs, Qt::FontRole).value(); + font.setBold(curs == cmb->currentIndex()); + cmb->setItemData(curs, QVariant(font), Qt::FontRole); + + } + } + } + } + // pass the event on to the parent class + return QWidget::eventFilter(obj, event); +} diff --git a/libbitdht/src/util/bdfile.h b/retroshare-gui/src/gui/common/RSComboBox.h similarity index 76% rename from libbitdht/src/util/bdfile.h rename to retroshare-gui/src/gui/common/RSComboBox.h index 5228f986a..8ce46a649 100644 --- a/libbitdht/src/util/bdfile.h +++ b/retroshare-gui/src/gui/common/RSComboBox.h @@ -1,9 +1,7 @@ /******************************************************************************* - * util/bdfile.h * + * gui/common/RSComboBox.h * * * - * BitDHT: An Flexible DHT library. * - * * - * Copyright 2011 by Robert Fernie * + * Copyright (C) 2010, Retroshare Team * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -19,12 +17,20 @@ * along with this program. If not, see . * * * *******************************************************************************/ -#pragma once -#include +#ifndef RSCOMBOBOX_H +#define RSCOMBOBOX_H -class bdFile +#include + +class RSComboBox : public QComboBox { - public: - static bool renameFile(const std::string& from, const std::string& to) ; -} ; + Q_OBJECT +public: + explicit RSComboBox(QWidget *parent = nullptr); + +protected: + bool eventFilter(QObject *obj, QEvent *event); +}; + +#endif // RSCOMBOBOX_H diff --git a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp index 34879b10c..f90591d8c 100644 --- a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp +++ b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp @@ -20,7 +20,7 @@ #include "RSElidedItemDelegate.h" -#include "gui/common/StyledElidedLabel.h" +#include "gui/common/ElidedLabel.h" #include "util/rsdebug.h" #include @@ -51,7 +51,7 @@ QTreeView::item:hover, QTreeWidget::item:hover, QListWidget::item:hover{ color: #0000EF; background-color: #FEDCBA; } -QQTreeView::item:selected:hover, TreeWidget::item:selected:hover, QListWidget::item:selected:hover{ +QTreeView::item:selected:hover, QTreeWidget::item:selected:hover, QListWidget::item:selected:hover{ color: #ABCDEF; background-color: #FE0000; } @@ -88,7 +88,12 @@ QSize RSElidedItemDelegate::sizeHint(const QStyleOptionViewItem &option, const Q QSize contSize = ownStyle->sizeFromContents( QStyle::CT_ItemViewItem,&ownOption ,QSize( checkRect.width()+iconRect.width()+textRect.width() - ,qMax(checkRect.height(),qMax(iconRect.height(),textRect.height()))),widget); + , qMax(checkRect.height(),qMax(iconRect.height(),textRect.height())) + ), widget ) ; + + contSize += QSize( 2*spacing().width() + , qMax(checkRect.height(),iconRect.height()) > textRect.height() + ? 0 : 2*spacing().height() ); return contSize; } @@ -97,7 +102,7 @@ inline QColor getImagePixelColor(QImage img, int x, int y) { #if QT_VERSION >= QT_VERSION_CHECK(5,6,0) #ifdef DEBUG_EID_PAINT -// RsDbg() << " RSEID: Found Color " << img.pixelColor(x,y).name(QColor::HexArgb).toStdString() << " at " << x << "," << y << std::endl; + //RsDbg(" RSEID: Found Color ", img.pixelColor(x,y).name(QColor::HexArgb).toStdString(), " at ", x, ",", y); #endif return img.pixelColor(x,y); #else @@ -109,7 +114,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & { if(!index.isValid()) { - RsErr() << __PRETTY_FUNCTION__ << " attempt to draw an invalid index." << std::endl; + RS_ERR(" attempt to draw an invalid index."); return ; } painter->save(); @@ -120,7 +125,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & ownOption.icon = option.icon; #ifdef DEBUG_EID_PAINT - RsDbg() << __PRETTY_FUNCTION__ << std::endl << " RSEID: Enter for item with text:" << ownOption.text.toStdString() << std::endl; + RS_DBG("\n RSEID: Enter for item with text:", ownOption.text.toStdString()); #endif const QWidget* widget = option.widget; @@ -138,17 +143,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & ownOption.font = font; ownOption.fontMetrics = QFontMetrics(font); #ifdef DEBUG_EID_PAINT - QFontInfo info(font); - RsDbg() << " RSEID: Found font in model:" << info.family().toStdString() << std::endl; + RsDbg(" RSEID: Found font in model:", font.family().toStdString(), " size:", font.pointSize()); #endif } // Get Text color from model if one exists QColor textColor; - if (index.data(Qt::TextColorRole).isValid()) { + if (index.data(Qt::ForegroundRole).isValid()) { //textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format. - textColor = index.data(Qt::TextColorRole).value(); + textColor = index.data(Qt::ForegroundRole).value(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Found text color in model:" << textColor.name().toStdString() << std::endl; + RsDbg(" RSEID: Found text color in model:", textColor.name().toStdString()); #endif } // Get Brush from model if one exists @@ -157,7 +161,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if (index.data(Qt::BackgroundRole).isValid()) { bgBrush = index.data(Qt::BackgroundRole).value(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Found bg brush in model:" << bgBrush.color().name().toStdString() << std::endl; + RsDbg(" RSEID: Found bg brush in model:", bgBrush.color().name().toStdString()); #endif } @@ -165,10 +169,10 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if ( (bgBrush.color().spec()==QColor::Invalid) || (textColor.spec()!=QColor::Invalid) ) { #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID:" - << ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "") - << ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "") - << " so get it from base image." << std::endl; + RsDbg( " RSEID:" + , ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "") + , ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "") + , " so get it from base image."); #endif // QPalette is not updated by StyleSheet all occurs in internal class. (QRenderRule) // https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#4138 @@ -179,7 +183,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & if (moSize.width() <= 20) moSize.setWidth(20); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: for item size = " << moSize.width() << "x" << moSize.height() << std::endl; + RsDbg(" RSEID: for item size = ", moSize.width(), "x", moSize.height()); #endif QImage moImg(moSize,QImage::Format_ARGB32); @@ -268,14 +272,14 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & { bgBrush = QBrush(moBGColor); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: bg brush setted to " << moBGColor.name(QColor::HexArgb).toStdString() << std::endl; + RsDbg(" RSEID: bg brush setted to ", moBGColor.name(QColor::HexArgb).toStdString()); #endif } if (textColor.spec()==QColor::Invalid) { textColor = moColor; #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: text color setted to " << moColor.name(QColor::HexArgb).toStdString() << std::endl; + RsDbg(" RSEID: text color setted to ", moColor.name(QColor::HexArgb).toStdString()); #endif } } @@ -378,18 +382,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & ownOption.text = ownOption.text.prepend("__"); #endif - QTextLayout textLayout(ownOption.text, painter->font()); - QTextOption to = textLayout.textOption(); - to.setWrapMode((ownOption.features & QStyleOptionViewItem::WrapText) ? QTextOption::WordWrap : QTextOption::NoWrap); + QTextOption::WrapMode wm = (ownOption.features & QStyleOptionViewItem::WrapText) ? QTextOption::WordWrap : QTextOption::NoWrap; const int textHMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1; const int textVMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameVMargin, nullptr, widget) + 1; textRect = textRect.adjusted(textHMargin, textVMargin, -textHMargin, -textVMargin); // remove width padding - StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),mPaintRoundedRect); + ElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,wm,mPaintRoundedRect); } painter->restore(); #ifdef DEBUG_EID_PAINT - RsDbg() << " RSEID: Finished" << std::endl; + RsDbg(" RSEID: Finished"); #endif } @@ -436,7 +438,7 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, //Update RSElidedItemDelegate as only one delegate for all items QRect rectElision; - bool elided = StyledElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),true,&rectElision); + bool elided = ElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),true,&rectElision); if (elided && (rectElision.contains(ev->pos()))){ QToolTip::showText(ev->globalPos(),QString("") + text + QString("")); return true; // eat event diff --git a/retroshare-gui/src/gui/common/RSFeedWidget.cpp b/retroshare-gui/src/gui/common/RSFeedWidget.cpp index 3293e3fae..7be4020b2 100644 --- a/retroshare-gui/src/gui/common/RSFeedWidget.cpp +++ b/retroshare-gui/src/gui/common/RSFeedWidget.cpp @@ -130,7 +130,7 @@ bool RSFeedWidget::eventFilter(QObject *object, QEvent *event) return QWidget::eventFilter(object, event); } -void RSFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem) +void RSFeedWidget::feedAdded(FeedItem */*feedItem*/, QTreeWidgetItem */*treeItem*/) { } @@ -433,7 +433,6 @@ void RSFeedWidget::feedItemDestroyed(qulonglong id) QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(const FeedItem *w) { QTreeWidgetItemIterator it(ui->treeWidget); - QTreeWidgetItem *treeItem=NULL; // this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems() #warning TODO diff --git a/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp b/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp index e1f517f42..63dd224f1 100644 --- a/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp +++ b/retroshare-gui/src/gui/common/RSImageBlockWidget.cpp @@ -31,7 +31,7 @@ RSImageBlockWidget::RSImageBlockWidget(QWidget *parent) : ui->setupUi(this); mDefaultRect = this->geometry(); - ui->infoFrame->installEventFilter(this); + ui->info_Frame->installEventFilter(this); mTimer = new RsProtectedTimer(this); mTimer->setSingleShot(true); diff --git a/retroshare-gui/src/gui/common/RSImageBlockWidget.ui b/retroshare-gui/src/gui/common/RSImageBlockWidget.ui index f483a1afd..ab40c379d 100644 --- a/retroshare-gui/src/gui/common/RSImageBlockWidget.ui +++ b/retroshare-gui/src/gui/common/RSImageBlockWidget.ui @@ -33,10 +33,19 @@ 0 - + + + + + 0 + 0 + 0 + + + @@ -57,6 +66,15 @@ + + + + 0 + 0 + 0 + + + @@ -77,6 +95,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,7 +131,7 @@ QFrame::Box - + 6 diff --git a/retroshare-gui/src/gui/common/RSTextBrowser.cpp b/retroshare-gui/src/gui/common/RSTextBrowser.cpp index 43bad4e7b..c11d4edef 100644 --- a/retroshare-gui/src/gui/common/RSTextBrowser.cpp +++ b/retroshare-gui/src/gui/common/RSTextBrowser.cpp @@ -22,6 +22,7 @@ #include "RSImageBlockWidget.h" #include "gui/common/FilesDefs.h" +#include "util/imageutil.h" #include //To get RsAccounts @@ -33,6 +34,7 @@ #include #include #include +#include #include @@ -51,6 +53,14 @@ RSTextBrowser::RSTextBrowser(QWidget *parent) : connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl))); } +void RSTextBrowser::append(const QString &text) +{ + //In Win RSTextBrowser don't recognize file:/// + QString fileText = text; + QTextBrowser::append(fileText.replace("file:///","file://")); + +} + void RSTextBrowser::linkClicked(const QUrl &url) { if (!mLinkClickActive) { @@ -128,14 +138,22 @@ QVariant RSTextBrowser::loadResource(int type, const QUrl &name) // case 2: always trust the image if it comes from local Config or Data directories. - if(type == QTextDocument::ImageResource) { + if(type == QTextDocument::ImageResource) + { QFileInfo fi = QFileInfo(name.path()); - if(fi.exists() && fi.isFile()) { + if(fi.exists() && fi.isFile()) + { QString cpath = fi.canonicalFilePath(); - if (cpath.startsWith(QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())).canonicalPath(),Qt::CaseInsensitive) - || cpath.startsWith(QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())).canonicalPath(),Qt::CaseInsensitive)) - return QTextBrowser::loadResource(type, name); - }} + QStringList autPath = { QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())).canonicalPath() + , QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())).canonicalPath() + , QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())+"/stylesheets/").canonicalPath() //May be link + , QDir(QString::fromUtf8(RsAccounts::systemDataDirectory().c_str())+"/stylesheets/").canonicalPath() //May be link + }; + for(auto& it : autPath) + if (!it.isEmpty() && cpath.startsWith(it, Qt::CaseInsensitive)) + return QPixmap(fi.absoluteFilePath()); + } + } // case 3: only display if the user allows it. Data resources can be bad (svg bombs) but we filter them out globally at the network layer. // It would be good to add here a home-made resource loader that only loads images and not svg crap, just in case. @@ -145,7 +163,11 @@ QVariant RSTextBrowser::loadResource(int type, const QUrl &name) // case 4: otherwise, do not display - std::cerr << "TEXTBROWSER: refusing load ressource request: type=" << type << " scheme=" << name.scheme().toStdString() << ", url=" << name.toString().toStdString() << std::endl; + std::cerr << "TEXTBROWSER: refusing load ressource request: type=" << type << " scheme=" + << name.scheme().toStdString() << ", url=" + << name.toString().left(50).toStdString() + << ((name.toString().length()>50)?"...":"") + << std::endl; if (mImageBlockWidget) mImageBlockWidget->show(); @@ -212,64 +234,6 @@ void RSTextBrowser::activateLinkClick(bool active) mLinkClickActive = active; } -/** - * @brief RSTextBrowser::checkImage - * @param pos where to check if image is shown in viewport coordinate - * @param imageStr return html source of cursor - * @return True if an image is under cursor - */ -bool RSTextBrowser::checkImage(QPoint pos, QString &imageStr) -{ - //Get text cursor under pos. But if pos is under text browser end line this return last cursor. - QTextCursor cursor = cursorForPosition(pos); - //First get rect of cursor (could be at left or right of image) - QRect cursorRectStart = cursorRect(cursor); - //Second get text - cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before - QRect cursorRectLeft = cursorRect(cursor); - cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2); - QRect cursorRectRight = cursorRect(cursor); - imageStr = cursor.selection().toHtml(); -#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG - mCursorRectStart = cursorRectStart; - mCursorRectLeft = cursorRectLeft; - mCursorRectRight = cursorRectRight; - - std::cerr << "cursorRect LTRB :" << cursorRectStart.left() << ";" << cursorRectStart.top() << ";" << cursorRectStart.right() << ";" << cursorRectStart.bottom() << std::endl; - std::cerr << "cursorRectLeft :" << cursorRectLeft.left() << ";" << cursorRectLeft.top() << ";" << cursorRectLeft.right() << ";" << cursorRectLeft.bottom() << std::endl; - std::cerr << "cursorRectRight :" << cursorRectRight.left() << ";" << cursorRectRight.top() << ";" << cursorRectRight.right() << ";" << cursorRectRight.bottom() << std::endl; - std::cerr << "pos XY :" << pos.x() << ";" << pos.y() << std::endl; -#endif - QRect cursorRectEnd = cursorRectStart; - //Finally set left with right of precedent character. - if (cursorRectEnd.top() < cursorRectLeft.bottom()) - { - cursorRectEnd.setLeft(cursorRectLeft.right()); - } else { - //Image on new line - cursorRectEnd.setLeft(0); - } - //And set Right with left of next character. - if (cursorRectEnd.bottom() > cursorRectRight.top()) - { - cursorRectEnd.setRight(cursorRectRight.left()); - } else { - //New line after Image. - } -#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG - mCursorRectEnd = cursorRectEnd; - - std::cerr << "final cursorRect:" << cursorRectEnd.left() << ";" << cursorRectEnd.top() << ";" << cursorRectEnd.right() << ";" << cursorRectEnd.bottom() << std::endl; - viewport()->update(); -#endif - //If pos is on text rect - if (cursorRectEnd.contains(pos)) - { - return imageStr.indexOf("base64,") != -1; - } - return false; -} - /** * @brief RSTextBrowser::anchorForPosition Replace anchorAt that doesn't works as expected. * @param pos Where to get anchor from text @@ -285,10 +249,10 @@ QString RSTextBrowser::anchorForPosition(const QPoint &pos) const rx.setMinimal(true); QString sel = cursor.selection().toHtml(); QStringList anchors; - int pos=0; - while ((pos = rx.indexIn(sel,pos)) != -1) { + int posX=0; + while ((posX = rx.indexIn(sel,posX)) != -1) { anchors << rx.cap(1); - pos += rx.matchedLength(); + posX += rx.matchedLength(); } if (!anchors.isEmpty()){ anchor = anchors.at(0); @@ -297,18 +261,59 @@ QString RSTextBrowser::anchorForPosition(const QPoint &pos) const return anchor; } -QMenu *RSTextBrowser::createStandardContextMenu() +void RSTextBrowser::addContextMenuAction(QAction *action) { - return createStandardContextMenu(QPoint()); + mContextMenuActions.push_back(action); } -QMenu *RSTextBrowser::createStandardContextMenu(const QPoint &position) + +void RSTextBrowser::contextMenuEvent(QContextMenuEvent *event) { - QMenu *menu = QTextBrowser::createStandardContextMenu(position); + emit calculateContextMenuActions(); + + QMenu *contextMenu = createStandardContextMenuFromPoint(event->pos()); + + QList::iterator it; + for (it = mContextMenuActions.begin(); it != mContextMenuActions.end(); ++it) { + contextMenu->addAction(*it); + } + + contextMenu->exec(QCursor::pos()); + + delete(contextMenu); +} + +QMenu *RSTextBrowser::createStandardContextMenuFromPoint(const QPoint &widgetPos) +{ + QMatrix matrix; + matrix.translate(horizontalScrollBar()->value(), verticalScrollBar()->value()); + + QMenu *menu = QTextBrowser::createStandardContextMenu(matrix.map(widgetPos)); menu->addSeparator(); QAction *a = menu->addAction(FilesDefs::getIconFromQtResourcePath("://icons/textedit/code.png"), tr("View &Source"), this, SLOT(viewSource())); a->setEnabled(!this->document()->isEmpty()); + if (ImageUtil::checkImage(this, widgetPos +#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG + , &mCursorRectStart, &mCursorRectLeft, &mCursorRectRight, &mCursorRectEnd +#endif + )) { + a = menu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage())); + a->setData(widgetPos); + + a = menu->addAction( tr("Copy image"), this, SLOT(copyImage())); + a->setData(widgetPos); + } + +#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG + std::cerr << "cursorRect LTRB :" << mCursorRectStart.left() << ";" << mCursorRectStart.top() << ";" << mCursorRectStart.right() << ";" << mCursorRectStart.bottom() << std::endl; + std::cerr << "cursorRectLeft :" << mCursorRectLeft.left() << ";" << mCursorRectLeft.top() << ";" << mCursorRectLeft.right() << ";" << mCursorRectLeft.bottom() << std::endl; + std::cerr << "cursorRectRight :" << mCursorRectRight.left() << ";" << mCursorRectRight.top() << ";" << mCursorRectRight.right() << ";" << mCursorRectRight.bottom() << std::endl; + std::cerr << "pos XY :" << widgetPos.x() << ";" << widgetPos.y() << std::endl; + std::cerr << "final cursorRect:" << mCursorRectEnd.left() << ";" << mCursorRectEnd.top() << ";" << mCursorRectEnd.right() << ";" << mCursorRectEnd.bottom() << std::endl; + viewport()->update(); +#endif + return menu; } @@ -330,3 +335,27 @@ void RSTextBrowser::viewSource() delete dialog; } + +void RSTextBrowser::saveImage() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QPoint point = action->data().toPoint(); + QTextCursor cursor = cursorForPosition(point); + ImageUtil::extractImage(window(), cursor); +} + +void RSTextBrowser::copyImage() +{ + QAction *action = dynamic_cast(sender()) ; + if (!action) { + return; + } + + QPoint point = action->data().toPoint(); + QTextCursor cursor = cursorForPosition(point); + ImageUtil::copyImage(window(), cursor); +} diff --git a/retroshare-gui/src/gui/common/RSTextBrowser.h b/retroshare-gui/src/gui/common/RSTextBrowser.h index 05a0e0d2e..a10a2b30a 100644 --- a/retroshare-gui/src/gui/common/RSTextBrowser.h +++ b/retroshare-gui/src/gui/common/RSTextBrowser.h @@ -39,14 +39,16 @@ class RSTextBrowser : public QTextBrowser public: explicit RSTextBrowser(QWidget *parent = 0); + void append(const QString &text); + void setPlaceholderText(const QString &text); void setImageBlockWidget(RSImageBlockWidget *widget); void resetImagesStatus(bool load); QPixmap getBlockedImage(); - bool checkImage(QPoint pos, QString &imageStr); - bool checkImage(QPoint pos) {QString imageStr; return checkImage(pos, imageStr); } QString anchorForPosition(const QPoint &pos) const; + // Add QAction to context menu (action won't be deleted) + void addContextMenuAction(QAction *action); void activateLinkClick(bool active); @@ -56,8 +58,10 @@ public: QVariant textColorQuotes() const { return highlighter->textColorQuotes();} bool getShowImages() const { return mShowImages; } - QMenu *createStandardContextMenu(); - QMenu *createStandardContextMenu(const QPoint &position); + QMenu *createStandardContextMenuFromPoint(const QPoint &widgetPos); + +Q_SIGNALS: + void calculateContextMenuActions(); public slots: void showImages(); @@ -68,9 +72,16 @@ private slots: void linkClicked(const QUrl &url); void destroyImageBlockWidget(); void viewSource(); + void saveImage(); + void copyImage(); protected: void paintEvent(QPaintEvent *event); + virtual void contextMenuEvent(QContextMenuEvent *event); + +private: + // Hide method from QTextBrowser + using QTextBrowser::createStandardContextMenu; private: QString mPlaceholderText; @@ -78,6 +89,7 @@ private: RSImageBlockWidget *mImageBlockWidget; bool mLinkClickActive; RsSyntaxHighlighter *highlighter; + QList mContextMenuActions; #ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG QRect mCursorRectStart; QRect mCursorRectLeft; diff --git a/retroshare-gui/src/gui/common/RSTreeView.cpp b/retroshare-gui/src/gui/common/RSTreeView.cpp index 624021f2f..454ab250e 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.cpp +++ b/retroshare-gui/src/gui/common/RSTreeView.cpp @@ -18,42 +18,73 @@ * * *******************************************************************************/ -#include -#include #include "RSTreeView.h" -RSTreeView::RSTreeView(QWidget *parent) : QTreeView(parent) +#include "util/rsdebug.h" + +#include +#include + +//#define DEBUG_RSTREEVIEW + +RSTreeView::RSTreeView(QWidget *parent) + : QTreeView(parent), autoSelect(false) { - setMouseTracking(false); // normally the default, but who knows if it's not goign to change in the future. + setMouseTracking(false); // normally the default, but who knows if it's not going to change in the future. } void RSTreeView::wheelEvent(QWheelEvent *e) { - if(e->modifiers() == Qt::ControlModifier) - { - emit zoomRequested(e->delta() > 0); - return; - } - else - QTreeView::wheelEvent(e); + if(e->modifiers() == Qt::ControlModifier) + { + emit zoomRequested(e->angleDelta().y() > 0); + return; + } + else + QTreeView::wheelEvent(e); } void RSTreeView::mouseMoveEvent(QMouseEvent *e) { - QModelIndex idx = indexAt(e->pos()); +#ifdef DEBUG_RSTREEVIEW + RS_DBG(e->localPos().x(), ":", e->localPos().y()); +#endif + if (autoSelect) + { + QModelIndex idx = indexAt(e->pos()); - if(idx.isValid() && idx != selectionModel()->currentIndex()) - selectionModel()->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect); + if(idx.isValid() && idx != selectionModel()->currentIndex()) + { +#ifdef DEBUG_RSTREEVIEW + RS_DBG("Selection changed"); +#endif + selectionModel()->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect); + } + } - QTreeView::mouseMoveEvent(e); + QTreeView::mouseMoveEvent(e); +} + +void RSTreeView::leaveEvent(QEvent *e) +{ +#ifdef DEBUG_RSTREEVIEW + RS_DBG(""); +#endif + if (autoSelect) + { + auto fp = focusPolicy(); + setFocusPolicy(Qt::NoFocus); // To not select first index when resetting current index. + selectionModel()->setCurrentIndex(QModelIndex(),QItemSelectionModel::Clear); // Close editor + setFocusPolicy(fp); + } + + QTreeView::leaveEvent(e); } void RSTreeView::setAutoSelect(bool b) { - if(b) - setMouseTracking(true); - else - setMouseTracking(false); + autoSelect = b; // Keep this because setMouseTracking can be called outside. + setMouseTracking(b); } void RSTreeView::resizeEvent(QResizeEvent *e) diff --git a/retroshare-gui/src/gui/common/RSTreeView.h b/retroshare-gui/src/gui/common/RSTreeView.h index 116ccac31..0ccd34134 100644 --- a/retroshare-gui/src/gui/common/RSTreeView.h +++ b/retroshare-gui/src/gui/common/RSTreeView.h @@ -29,26 +29,34 @@ class RSTreeView : public QTreeView Q_OBJECT public: - RSTreeView(QWidget *parent = 0); + RSTreeView(QWidget *parent = nullptr); + /** + * @brief set Placeholder Text + * @param text + */ void setPlaceholderText(const QString &text); - // Use this to make selection automatic based on mouse position. This is useful to trigger selection and therefore editing mode - // in trees that show editing widgets using a QStyledItemDelegate - - void setAutoSelect(bool b); + /** + * @brief Use this to make selection automatic based on mouse position. + * This is useful to trigger selection and therefore editing mode in trees that show editing widgets using a QStyledItemDelegate. + * @param b + */ + void setAutoSelect(bool b); signals: - void sizeChanged(QSize); - void zoomRequested(bool zoom_or_unzoom); + void sizeChanged(QSize); + void zoomRequested(bool zoom_or_unzoom); protected: virtual void mouseMoveEvent(QMouseEvent *e) override; // overriding so as to manage auto-selection + virtual void leaveEvent(QEvent *e) override; // overriding so as to manage auto-selection clear virtual void wheelEvent(QWheelEvent *e) override; // overriding so as to manage zoom - virtual void resizeEvent(QResizeEvent *e) override; + virtual void resizeEvent(QResizeEvent *e) override; virtual void paintEvent(QPaintEvent *event) override; QString placeholderText; + bool autoSelect; }; #endif diff --git a/retroshare-gui/src/gui/common/RSTreeWidget.cpp b/retroshare-gui/src/gui/common/RSTreeWidget.cpp index 09ef481f6..7e3a8b216 100644 --- a/retroshare-gui/src/gui/common/RSTreeWidget.cpp +++ b/retroshare-gui/src/gui/common/RSTreeWidget.cpp @@ -253,8 +253,9 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu) } if(!mContextMenuActions.isEmpty() || !mContextMenuMenus.isEmpty() || mEnableColumnCustomize) { - QWidget *widget = new QWidget(contextMenu); - widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); + QFrame *widget = new QFrame(contextMenu); + widget->setObjectName("gradFrame"); //Use qss + //widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}"); // create menu header QHBoxLayout *hbox = new QHBoxLayout(widget); @@ -262,15 +263,17 @@ QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu) hbox->setSpacing(6); QLabel *iconLabel = new QLabel(widget); - QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/images/settings.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); + iconLabel->setObjectName("trans_Icon"); + QPixmap pix = FilesDefs::getPixmapFromQtResourcePath(":/icons/png/options2.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5); iconLabel->setPixmap(pix); iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width()); hbox->addWidget(iconLabel); QLabel *textLabel = new QLabel("" + tr("Tree View Options") + "", widget); + textLabel->setObjectName("trans_Text"); hbox->addWidget(textLabel); - QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + QSpacerItem *spacerItem = new QSpacerItem(40, 24, QSizePolicy::Expanding, QSizePolicy::Minimum); hbox->addItem(spacerItem); widget->setLayout(hbox); diff --git a/retroshare-gui/src/gui/common/RSTreeWidgetItem.h b/retroshare-gui/src/gui/common/RSTreeWidgetItem.h index 14a22b97c..8e90baee6 100644 --- a/retroshare-gui/src/gui/common/RSTreeWidgetItem.h +++ b/retroshare-gui/src/gui/common/RSTreeWidgetItem.h @@ -32,6 +32,7 @@ public: RSTreeWidgetItemCompareRole(); explicit RSTreeWidgetItemCompareRole(QMap> map); + void clear() { QMap >::clear() ; } void setRole(const int column, const int role); void addRole(const int column, const int role); void findRoles(const int column, QList &roles) const; diff --git a/retroshare-gui/src/gui/common/RsCollectionDialog.ui b/retroshare-gui/src/gui/common/RsCollectionDialog.ui index ceaea3b99..d8693ef0a 100644 --- a/retroshare-gui/src/gui/common/RsCollectionDialog.ui +++ b/retroshare-gui/src/gui/common/RsCollectionDialog.ui @@ -23,7 +23,7 @@ true - + 0 @@ -50,14 +50,14 @@ - + QFrame::StyledPanel QFrame::Raised - + @@ -70,7 +70,7 @@ QFrame::Plain - + @@ -88,7 +88,7 @@ 0 - + 0 @@ -334,7 +334,7 @@ - + :/images/deletemail24.png:/images/deletemail24.png @@ -410,7 +410,7 @@ - + @@ -419,7 +419,7 @@ - + Qt::Horizontal @@ -498,7 +498,7 @@
- frame + gradFrame headerFrame
diff --git a/retroshare-gui/src/gui/common/SubscribeToolButton.cpp b/retroshare-gui/src/gui/common/SubscribeToolButton.cpp index 4015e641c..165b6caa1 100644 --- a/retroshare-gui/src/gui/common/SubscribeToolButton.cpp +++ b/retroshare-gui/src/gui/common/SubscribeToolButton.cpp @@ -72,7 +72,7 @@ void SubscribeToolButton::updateUi() delete mMenu ; mMenu = new QMenu; - mMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/cancel.png"), tr("Unsubscribe"), this, SLOT(unsubscribePrivate())); + mMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/icons/cancel.svg"), tr("Unsubscribe"), this, SLOT(unsubscribePrivate())); if (!mSubscribedActions.empty()) { mMenu->addSeparator(); diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp index 03f7b4205..6a407cb49 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp @@ -264,7 +264,7 @@ void ConfCertDialog::loadInvitePage() ui._shouldAddSignatures_CB->setEnabled(detail.gpgSigners.size() > 1) ; std::string invite ; - RetroshareInviteFlags flags = RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::RADIX_FORMAT; + RetroshareInviteFlags flags = RsPeers::defaultCertificateFlags | RetroshareInviteFlags::RADIX_FORMAT; if(!detail.isHiddenNode && ui._includeIPHistory_CB->isChecked()) flags |= RetroshareInviteFlags::FULL_IP_HISTORY; @@ -283,7 +283,7 @@ void ConfCertDialog::loadInvitePage() ui.stabWidget->setTabText(PageCertificate, tr("Retroshare Certificate")); } - QString infotext = getCertificateDescription(detail,ui._shouldAddSignatures_CB->isChecked(),ui._shortFormat_CB->isChecked(), ui._includeIPHistory_CB->isChecked() ); + QString infotext = getCertificateDescription(detail,ui._shouldAddSignatures_CB->isChecked(),ui._shortFormat_CB->isChecked(), flags ); ui.userCertificateText->setToolTip(infotext) ; @@ -297,19 +297,15 @@ void ConfCertDialog::loadInvitePage() ui.userCertificateText->setText(QString::fromUtf8(invite.c_str())); } -QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail,bool signatures_included,bool use_short_format,bool include_additional_locators) +QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail, bool signatures_included, bool use_short_format,RetroshareInviteFlags invite_flags) { //infotext += tr("

Use this certificate to make new friends. Send it by email, or give it hand to hand.

") ; QString infotext; if(use_short_format) - { infotext += tr("

This Retroshare ID contains:") ; - } else - { infotext += tr("

This certificate contains:") ; - } infotext += "

    " ; @@ -334,25 +330,36 @@ QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail,bo if(detail.isHiddenNode) infotext += tr("
  • onion address and port") +" (" + detail.hiddenNodeAddress.c_str() + ":" + QString::number(detail.hiddenNodePort)+ ")
  • "; - else if(!include_additional_locators) + else if(!!(invite_flags & RetroshareInviteFlags::FULL_IP_HISTORY)) + for(auto it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) + { + infotext += "
  • " ; + infotext += tr("IP address and port: ") + QString::fromStdString(*it) ; + infotext += "
  • " ; + } + else { - if(!detail.localAddr.empty()) infotext += tr("
  • IP address and port: ") + detail.localAddr.c_str() + ":" + QString::number(detail.localPort)+ "
  • "; - if(!detail.extAddr.empty()) infotext += tr("
  • IP address and port: ") + detail.extAddr.c_str() + ":" + QString::number(detail.extPort)+ "
  • "; + if(!!(invite_flags & RetroshareInviteFlags::CURRENT_LOCAL_IP) && !detail.localAddr.empty()) + infotext += tr("
  • IP address and port: ") + detail.localAddr.c_str() + ":" + QString::number(detail.localPort)+ "
  • "; + + if(!!(invite_flags & RetroshareInviteFlags::CURRENT_EXTERNAL_IP) && !detail.extAddr.empty()) + infotext += tr("
  • IP address and port: ") + detail.extAddr.c_str() + ":" + QString::number(detail.extPort)+ "
  • "; + } + + if(!!(invite_flags & RetroshareInviteFlags::DNS) && !detail.dyndns.empty()) + { + infotext += "
  • " ; + infotext += tr("DNS: : ") + QString::fromStdString(detail.dyndns); + infotext += "
  • " ; } - else for(auto it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) - { - infotext += "
  • " ; - infotext += tr("IP address and port: ") + QString::fromStdString(*it) ; - infotext += "
  • " ; - } infotext += QString("

    ") ; if(rsPeers->getOwnId() == detail.id) if(use_short_format) - infotext += tr("

    You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.

    ") ; - else - infotext += tr("

    You can use this certificate to make new friends. Send it by email, or give it hand to hand.

    ") ; + infotext += tr("

    You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.

    ") ; + else + infotext += tr("

    You can use this certificate to make new friends. Send it by email, or give it hand to hand.

    ") ; return infotext; } diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.h b/retroshare-gui/src/gui/connect/ConfCertDialog.h index a883dfd17..4760835da 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.h +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.h @@ -59,7 +59,7 @@ public: /* window will destroy itself! */ } static void loadAll(); - static QString getCertificateDescription(const RsPeerDetails& det, bool signatures_included, bool use_short_format, bool extra_locators_included); + static QString getCertificateDescription(const RsPeerDetails& det, bool signatures_included, bool use_short_format,RetroshareInviteFlags invite_flags); signals: void configChanged(); diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.ui b/retroshare-gui/src/gui/connect/ConfCertDialog.ui index a2f94bc5b..93f9a86ba 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.ui +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.ui @@ -6,8 +6,8 @@ 0 0 - 658 - 419 + 666 + 522 @@ -47,14 +47,14 @@ - + QFrame::StyledPanel QFrame::Raised - + diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp index 90f532fd5..4a7429f27 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp @@ -39,6 +39,7 @@ #include "ConnectFriendWizard.h" #include "ui_ConnectFriendWizard.h" #include "gui/common/PeerDefs.h" +#include "gui/connect/ConfCertDialog.h" #include "gui/notifyqt.h" #include "gui/common/GroupDefs.h" #include "gui/msgs/MessageComposer.h" @@ -79,6 +80,7 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) : { ui->setupUi(this); + error = 0; mTitleFontSize = 0; // Standard mTitleFontWeight = 0; // Standard @@ -107,8 +109,8 @@ ConnectFriendWizard::ConnectFriendWizard(QWidget *parent) : //ui->foffRadioButton->hide(); //ui->rsidRadioButton->hide(); - ui->cp_Label->hide(); - ui->requestinfolabel->hide(); + ui->info_Label_FrdReq->hide(); + ui->info_Label_Request->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))) ; @@ -295,8 +297,8 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -320,8 +322,8 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -358,8 +360,8 @@ void ConnectFriendWizard::setGpgId(const RsPgpId &gpgId, const RsPeerId &sslId, setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage, tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -374,8 +376,8 @@ void ConnectFriendWizard::setGpgId(const RsPgpId &gpgId, const RsPeerId &sslId, //setStartId(friendRequest ? Page_FriendRequest : Page_Conclusion); setStartId(Page_Conclusion); if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); + ui->info_Label_FrdReq->show(); + ui->info_Label_Request->show(); setTitleText(ui->ConclusionPage,tr("Friend request")); ui->ConclusionPage->setSubTitle(tr("Details about the request")); setButtonText(QWizard::FinishButton , tr("Accept")); @@ -530,7 +532,7 @@ void ConnectFriendWizard::initializePage(int id) } } - ui->cp_Label->setText(tr("You have a friend request from") + " " + QString::fromUtf8(peerDetails.name.c_str())); + ui->info_Label_FrdReq->setText(tr("You have a friend request from") + " " + QString::fromUtf8(peerDetails.name.c_str())); ui->nameEdit->setText(QString::fromUtf8(peerDetails.name.c_str())); ui->trustEdit->setText(trustString); ui->profileIdEdit->setText(QString::fromStdString(peerDetails.gpg_id.toStdString())); @@ -572,6 +574,16 @@ void ConnectFriendWizard::initializePage(int id) ui->ipEdit->setText(s); ui->signersEdit->setPlainText(ts); + ui->knownIpLabel->setHidden(peerDetails.ipAddressList.empty()); + ui->knownIpEdit->setHidden(peerDetails.ipAddressList.empty()); + { + QString ipList; + for(auto& it : peerDetails.ipAddressList) + ipList.append(QString::fromStdString(it) + "\n"); + + ui->knownIpEdit->setPlainText(ipList); + } + fillGroups(this, ui->groupComboBox, groupId); if(peerDetails.isHiddenNode) @@ -587,15 +599,16 @@ void ConnectFriendWizard::initializePage(int id) } if(mIsShortInvite) { - ui->nameEdit->setText(tr("[Unknown]")); - ui->addKeyToKeyring_CB->setChecked(false); - ui->addKeyToKeyring_CB->setEnabled(false); + if(ui->nameEdit->text().isEmpty()) + ui->nameEdit->setText(QString::fromUtf8(peerDetails.name.c_str())); + ui->addKeyToKeyring_CB->setChecked(false); + ui->addKeyToKeyring_CB->setEnabled(false); ui->signersEdit->hide(); ui->signersLabel->hide(); - ui->signGPGCheckBox->setChecked(false); - ui->signGPGCheckBox->setEnabled(false); - ui->acceptNoSignGPGCheckBox->setChecked(true); - ui->acceptNoSignGPGCheckBox->setEnabled(false); + ui->signGPGCheckBox->setChecked(false); + ui->signGPGCheckBox->setEnabled(false); + ui->acceptNoSignGPGCheckBox->setChecked(true); + ui->acceptNoSignGPGCheckBox->setEnabled(false); } ui->ipEdit->setTextInteractionFlags(Qt::TextSelectableByMouse); @@ -856,30 +869,32 @@ void ConnectFriendWizard::cleanFriendCert() { bool certValid = false; QString errorMsg ; + QString certDetail; std::string cert = ui->friendCertEdit->toPlainText().toUtf8().constData(); if (cert.empty()) { - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); ui->friendCertCleanLabel->setToolTip(""); - ui->friendCertCleanLabel->setStyleSheet(""); errorMsg = tr(""); } else { std::string cleanCert; uint32_t error_code; + RsPeerDetails details; - if (rsPeers->cleanCertificate(cert, cleanCert, mIsShortInvite, error_code)) - { + if (rsPeers->cleanCertificate(cert, cleanCert, mIsShortInvite, error_code, details)) + { certValid = true; if (cert != cleanCert) - { + { QTextCursor textCursor = ui->friendCertEdit->textCursor(); whileBlocking(ui->friendCertEdit)->setPlainText(QString::fromUtf8(cleanCert.c_str())); whileBlocking(ui->friendCertEdit)->setTextCursor(textCursor); - ui->friendCertCleanLabel->setStyleSheet(""); + // use dummy flags so that the content of the description is driven by what's in the "details" variable. + RetroshareInviteFlags dummy_flags = RetroshareInviteFlags::ALL; + certDetail = ConfCertDialog::getCertificateDescription(details,false,mIsShortInvite,dummy_flags); } if (mIsShortInvite) @@ -887,7 +902,7 @@ void ConnectFriendWizard::cleanFriendCert() else errorMsg = tr("Valid certificate") ; - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png")); + ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png")); } else { if (error_code > 0) { switch (error_code) { @@ -903,16 +918,17 @@ void ConnectFriendWizard::cleanFriendCert() default: errorMsg = tr("Not a valid Retroshare certificate!") ; - ui->friendCertCleanLabel->setStyleSheet("QLabel#friendCertCleanLabel {border: 1px solid #DCDC41; border-radius: 6px; background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2);}"); } } - ui->friendCertCleanLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); } } - ui->friendCertCleanLabel->setPixmap(certValid ? FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png") : FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); - ui->friendCertCleanLabel->setToolTip(errorMsg); + ui->friendCertCleanLabel->setPixmap(certValid ? FilesDefs::getPixmapFromQtResourcePath(":/images/accepted16.png") : FilesDefs::getPixmapFromQtResourcePath(":/images/delete.png")); + ui->friendCertCleanLabel->setToolTip("

    " + errorMsg + (certValid ? "\n" + certDetail : "") + "

    "); ui->friendCertCleanLabel->setText(errorMsg); + ui->friendCertCleanLabel->setProperty("WrongValue", !certValid && !errorMsg.isEmpty()); + ui->friendCertCleanLabel->style()->unpolish(ui->friendCertCleanLabel); + ui->friendCertCleanLabel->style()->polish( ui->friendCertCleanLabel); ui->TextPage->setComplete(certValid); } diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index 5e9cd7a34..65b736762 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -360,7 +360,7 @@ - + 0 @@ -370,6 +370,15 @@ + + + + 0 + 0 + 0 + + + @@ -390,6 +399,15 @@ + + + + 0 + 0 + 0 + + + @@ -410,6 +428,15 @@ + + + + 154 + 154 + 154 + + + @@ -431,6 +458,11 @@ + + + 10 + + true @@ -510,6 +542,14 @@ 0 + + + 11 + 75 + true + true + + Name: @@ -550,7 +590,7 @@
    - Email + ProfilId @@ -589,7 +629,7 @@ - Signers + Signers: @@ -635,6 +675,16 @@ + + + + Known IP: + + + + + + @@ -687,7 +737,7 @@ - + @@ -701,7 +751,7 @@ - + @@ -767,10 +817,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -791,6 +850,15 @@ + + + + 0 + 0 + 0 + + + @@ -811,6 +879,15 @@ + + + + 154 + 154 + 154 + + + @@ -832,6 +909,11 @@ + + + 12 + + true @@ -863,17 +945,17 @@ - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    ConnectFriendPage QWizardPage
    gui/connect/ConnectFriendWizard.h
    1
    + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    RSPlainTextEdit QPlainTextEdit @@ -881,8 +963,8 @@
    - + diff --git a/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp b/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp index ce1c843c8..e405430e5 100755 --- a/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp +++ b/retroshare-gui/src/gui/connect/ConnectProgressDialog.cpp @@ -235,38 +235,42 @@ void ConnectProgressDialog::initDialog() void ConnectProgressDialog::updateStatus() { - if (time(NULL) > mInitTS + CONNECT_TIMEOUT_PERIOD) - { - sayConnectTimeout(); - mState = CONNECT_STATE_FAILED; - } + if (time(NULL) > mInitTS + CONNECT_TIMEOUT_PERIOD) + { + sayConnectTimeout(); + mState = CONNECT_STATE_FAILED; + } - switch(mState) - { - case CONNECT_STATE_PROGRESS: + switch(mState) + { + case CONNECT_STATE_PROGRESS: - updateNetworkStatus(); - updateContactStatus(); + updateNetworkStatus(); + updateContactStatus(); + + if(!mIsPeerHiddenNode && !mAmIHiddenNode) + { #ifdef RS_USE_BITDHT - updateDhtStatus(); + updateDhtStatus(); #endif - updateLookupStatus(); - updateUdpStatus(); + updateLookupStatus(); + updateUdpStatus(); + } - return; - break; + return; + break; - default: - case CONNECT_STATE_CLOSED: - case CONNECT_STATE_FAILED: - case CONNECT_STATE_DENIED: - case CONNECT_STATE_CONNECTED: - break; - } + default: + case CONNECT_STATE_CLOSED: + case CONNECT_STATE_FAILED: + case CONNECT_STATE_DENIED: + case CONNECT_STATE_CONNECTED: + break; + } - /* shutdown actions */ - ui->progressFrame->setEnabled(false); - mTimer->stop(); + /* shutdown actions */ + ui->progressFrame->setEnabled(false); + mTimer->stop(); } @@ -282,42 +286,70 @@ void ConnectProgressDialog::stopAndClose() void ConnectProgressDialog::updateNetworkStatus() { - RsNetState netState = rsConfig->getNetState(); + QLabel *label = ui->NetResult; - QLabel *label = ui->NetResult; - switch(netState) - { - case RsNetState::BAD_UNKNOWN: - label->setText(tr("Unknown State")); - break; - case RsNetState::BAD_OFFLINE: - label->setText(tr("Offline")); - break; - case RsNetState::BAD_NATSYM: - label->setText(tr("Behind Symmetric NAT")); - break; - case RsNetState::BAD_NODHT_NAT: - label->setText(tr("Behind NAT & No DHT")); - break; - case RsNetState::WARNING_RESTART: - label->setText(tr("NET Restart")); - break; - case RsNetState::WARNING_NATTED: - label->setText(tr("Behind NAT")); - break; - case RsNetState::WARNING_NODHT: - label->setText(tr("No DHT")); - break; - case RsNetState::GOOD: - label->setText(tr("NET STATE GOOD!")); - break; - case RsNetState::ADV_FORWARD: - label->setText(tr("UNVERIFIABLE FORWARD!")); - break; - case RsNetState::ADV_DARK_FORWARD: - label->setText(tr("UNVERIFIABLE FORWARD & NO DHT")); - break; - } + if(mAmIHiddenNode || mIsPeerHiddenNode) + switch(rsConfig->getNetState()) + { + case RsNetState::BAD_UNKNOWN: + label->setText(tr("Unknown State")); + break; + case RsNetState::BAD_OFFLINE: + label->setText(tr("Offline")); + break; + case RsNetState::BAD_NATSYM: + label->setText(tr("Behind Symmetric NAT")); + break; + case RsNetState::WARNING_RESTART: + label->setText(tr("NET Restart")); + break; + case RsNetState::BAD_NODHT_NAT: + case RsNetState::WARNING_NATTED: + label->setText(tr("Behind NAT")); + break; + case RsNetState::WARNING_NODHT: + case RsNetState::GOOD: + label->setText(tr("NET STATE GOOD!")); + break; + case RsNetState::ADV_DARK_FORWARD: + case RsNetState::ADV_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD!")); + break; + } + else + switch(rsConfig->getNetState()) + { + case RsNetState::BAD_UNKNOWN: + label->setText(tr("Unknown State")); + break; + case RsNetState::BAD_OFFLINE: + label->setText(tr("Offline")); + break; + case RsNetState::BAD_NATSYM: + label->setText(tr("Behind Symmetric NAT")); + break; + case RsNetState::BAD_NODHT_NAT: + label->setText(tr("Behind NAT & No DHT")); + break; + case RsNetState::WARNING_RESTART: + label->setText(tr("NET Restart")); + break; + case RsNetState::WARNING_NATTED: + label->setText(tr("Behind NAT")); + break; + case RsNetState::WARNING_NODHT: + label->setText(tr("No DHT")); + break; + case RsNetState::GOOD: + label->setText(tr("NET STATE GOOD!")); + break; + case RsNetState::ADV_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD!")); + break; + case RsNetState::ADV_DARK_FORWARD: + label->setText(tr("UNVERIFIABLE FORWARD & NO DHT")); + break; + } } void ConnectProgressDialog::updateContactStatus() @@ -454,13 +486,9 @@ void ConnectProgressDialog::updateLookupStatus() mState = CONNECT_STATE_FAILED; if (mLookupStatus == CONNECT_LOOKUP_NODHTCONFIG) - { sayPeerNoDhtConfig(); - } else - { sayPeerOffline(); - } } case CONNECT_LOOKUP_FAIL: diff --git a/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp b/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp index b167ca1ed..36b6057b4 100644 --- a/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp +++ b/retroshare-gui/src/gui/connect/PGPKeyDialog.cpp @@ -45,6 +45,8 @@ #include "util/DateTime.h" #include "util/misc.h" +#define FRIEND_OPTIONS_TAB_INDEX 2 + QMap PGPKeyDialog::instances_pgp; PGPKeyDialog *PGPKeyDialog::instance(const RsPgpId& pgp_id) @@ -178,6 +180,7 @@ void PGPKeyDialog::load() { ui.make_friend_button->hide(); ui.signKeyButton->hide(); + ui.label_signKey->hide(); ui.denyFriendButton->hide(); ui.label_trustlevel->hide(); @@ -199,11 +202,13 @@ void PGPKeyDialog::load() { ui.make_friend_button->hide(); ui.denyFriendButton->show(); + ui.stabWidget->setTabEnabled(FRIEND_OPTIONS_TAB_INDEX,true); } else { ui.make_friend_button->show(); ui.denyFriendButton->hide(); + ui.stabWidget->setTabEnabled(FRIEND_OPTIONS_TAB_INDEX,false); } //web of trust diff --git a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui index 04b891fdf..eca49e965 100644 --- a/retroshare-gui/src/gui/connect/PGPKeyDialog.ui +++ b/retroshare-gui/src/gui/connect/PGPKeyDialog.ui @@ -30,14 +30,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + 3 @@ -56,11 +56,11 @@ 0 - + Profile info - + 0 @@ -68,9 +68,9 @@ 6 - + - + @@ -103,7 +103,7 @@ - + <html><head/><body><p>The trust level is an optional and local parameter that you can set in order to remember your option about a given PGP key. It is not used whatsoever to authorize connections. </p></body></html> @@ -112,8 +112,8 @@ Unset - - :/images/security-low-off-48.png:/images/security-low-off-48.png + + :/icons/security_low_off_128.png:/icons/security_low_off_128.png @@ -121,8 +121,8 @@ Unknown - - :/images/security-low-off-48.png:/images/security-low-off-48.png + + :/icons/security_low_off_128.png:/icons/security_low_off_128.png @@ -130,8 +130,8 @@ No trust - - :/images/security-low-48.png:/images/security-low-48.png + + :/icons/security_low_128.png:/icons/security_low_128.png @@ -139,8 +139,8 @@ Marginal - - :/images/security-medium-48.png:/images/security-medium-48.png + + :/icons/security_medium_128.png:/icons/security_medium_128.png @@ -148,8 +148,8 @@ Full - - :/images/security-high-48.png:/images/security-high-48.png + + :/icons/security_high_128.png:/icons/security_high_128.png @@ -157,8 +157,8 @@ Ultimate - - :/images/security-high-48.png:/images/security-high-48.png + + :/icons/security_high_128.png:/icons/security_high_128.png @@ -350,11 +350,11 @@ p, li { white-space: pre-wrap; } - + PGP key - + @@ -391,11 +391,11 @@ p, li { white-space: pre-wrap; } - + - Options + Friend options - + @@ -518,20 +518,26 @@ p, li { white-space: pre-wrap; } - - RSTextBrowser - QTextBrowser -
    gui/common/RSTextBrowser.h
    -
    HeaderFrame QFrame
    gui/common/HeaderFrame.h
    1
    + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    + + RSTextBrowser + QTextBrowser +
    gui/common/RSTextBrowser.h
    +
    + diff --git a/retroshare-gui/src/gui/feeds/AttachFileItem.ui b/retroshare-gui/src/gui/feeds/AttachFileItem.ui index d0421e864..b755fba22 100644 --- a/retroshare-gui/src/gui/feeds/AttachFileItem.ui +++ b/retroshare-gui/src/gui/feeds/AttachFileItem.ui @@ -16,15 +16,24 @@ 35 - + + + 0 + + + 0 + + + 0 + + + 0 + 0 - - 0 - - + 0 @@ -37,7 +46,7 @@ QFrame::Sunken - + 2 diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp index 757d10ec5..57adbb39d 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.cpp @@ -28,6 +28,7 @@ #include "gui/feeds/FeedHolder.h" #include "gui/RetroShareLink.h" #include "gui/gxs/GxsIdDetails.h" +#include "util/qtthreadsutils.h" #include "util/DateTime.h" #include "util/misc.h" #include "util/stringutil.h" @@ -185,13 +186,13 @@ void BaseBoardsCommentsItem::loadMessage() if (posts.size() == 1) { std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl; - const RsPostedPost& post(posts[0]); + RsPostedPost post(posts[0]); // no reference to temporary because it's passed to a thread! RsQThreadUtils::postToObject( [post,this]() { setPost(post,true); mIsLoadingMessage = false;}, this ); } else if(comments.size() == 1) { - const RsGxsComment& cmt = comments[0]; + RsGxsComment cmt(comments[0]); std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl; RsQThreadUtils::postToObject( [cmt,this]() @@ -286,12 +287,14 @@ void BaseBoardsCommentsItem::readToggled(bool checked) return; } - RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + setReadStatus(false, checked); // Can't call this inside an async call since the widget may be destroyed afterwards! + // So we do it right away. - uint32_t token; - rsPosted->setMessageReadStatus(token, msgPair, !checked); - - setReadStatus(false, checked); + RsThread::async( [this,checked]() { + RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + + rsPosted->setCommentReadStatus(msgPair, !checked); + }); } void BaseBoardsCommentsItem::readAndClearItem() @@ -422,7 +425,9 @@ void BoardsCommentsItem::makeUpVote() void BoardsCommentsItem::setComment(const RsGxsComment& cmt) { - ui->commLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(cmt.mComment.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS)); + uint32_t autorized_lines = (int)floor((ui->avatarLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + + ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS));; ui->nameLabel->setId(cmt.mMeta.mAuthorId); ui->datetimeLabel->setText(DateTime::formatLongDateTime(cmt.mMeta.mPublishTs)); @@ -534,9 +539,9 @@ void BoardsCommentsItem::setReadStatus(bool isNew, bool isUnread) ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); } - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } void BoardsCommentsItem::toggle() diff --git a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui index 65d76e355..53e233e0b 100644 --- a/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/BoardsCommentsItem.ui @@ -10,7 +10,14 @@ 157 - + + + 12 + 75 + true + + + 1 @@ -24,7 +31,7 @@ 1 - + 0 @@ -40,17 +47,20 @@ QFrame::Sunken - + 9 + + 3 + 8 - + @@ -65,6 +75,7 @@ + 12 75 true @@ -128,6 +139,7 @@ + 12 75 true @@ -144,6 +156,7 @@ + 12 75 true @@ -157,7 +170,7 @@ - + Qt::Horizontal @@ -239,7 +252,7 @@ - + @@ -272,14 +285,14 @@ - + Qt::Vertical 20 - 10 + 6 @@ -288,7 +301,7 @@ - + 0 @@ -309,7 +322,7 @@ QFrame::Sunken - + 5 @@ -364,12 +377,12 @@ - + 3 - 3 + 0 9 @@ -377,8 +390,11 @@ 0 + + 3 + - + Qt::Horizontal @@ -397,6 +413,7 @@ + 12 75 true @@ -419,7 +436,9 @@ + 12 75 + true true @@ -427,7 +446,7 @@ Name - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -443,6 +462,8 @@ MS Sans Serif 10 + 75 + true @@ -477,8 +498,6 @@
    gui/gxs/GxsIdLabel.h
    - - - + diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp index bfa33cde9..ecbba96af 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.cpp @@ -175,9 +175,9 @@ void ChannelsCommentsItem::setup() // hide expand button, replies is not implemented yet ui->expandButton->hide(); - ui->mainFrame->setProperty("new", false); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", false); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); ui->expandFrame->hide(); } @@ -292,20 +292,21 @@ void ChannelsCommentsItem::loadMessage() #ifdef DEBUG_ITEM std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl; #endif - const RsGxsChannelPost& post(posts[0]); + RsGxsChannelPost post(posts[0]); // no reference to temporary here, because we pass this to a thread RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this ); } else if(comments.size() == 1) { - const RsGxsComment& cmt = comments[0]; + RsGxsComment cmt(comments[0]); #ifdef DEBUG_ITEM std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl; #endif RsQThreadUtils::postToObject( [cmt,this]() { - uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height()) + / QFontMetricsF(ui->subjectLabel->font()).height()); ui->commLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(cmt.mComment.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -368,7 +369,7 @@ void ChannelsCommentsItem::loadComment() int comNb = comments.size(); - RsQThreadUtils::postToObject( [comNb,this]() + RsQThreadUtils::postToObject( [comNb]() { QString sComButText = tr("Comment"); if (comNb == 1) @@ -434,7 +435,8 @@ void ChannelsCommentsItem::fill() /* subject */ //ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str())); - uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + //uint32_t autorized_lines = (int)floor( (ui->avatarLabel->height() - ui->button_HL->sizeHint().height()) + // / QFontMetricsF(ui->subjectLabel->font()).height()); // fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy //ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -534,9 +536,9 @@ void ChannelsCommentsItem::setReadStatus(bool isNew, bool isUnread) ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png")); } - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } void ChannelsCommentsItem::doExpand(bool open) @@ -615,7 +617,7 @@ void ChannelsCommentsItem::readToggled(bool /*checked*/) RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); - rsGxsChannels->markRead(msgPair, isUnread()); + rsGxsChannels->setCommentReadStatus(msgPair, isUnread()); //setReadStatus(false, checked); // Updated by events } diff --git a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui index c1eec128c..cd0265c1d 100644 --- a/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui +++ b/retroshare-gui/src/gui/feeds/ChannelsCommentsItem.ui @@ -10,7 +10,7 @@ 157
    - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,17 +40,23 @@ QFrame::Sunken - + 9 + + 6 + + + 3 + - + 8 - + @@ -128,6 +134,7 @@ + 12 75 true @@ -144,6 +151,7 @@ + 12 75 true @@ -157,7 +165,7 @@ - + Qt::Horizontal @@ -254,7 +262,7 @@ 3 - 3 + 0 9 @@ -262,8 +270,11 @@ 0 + + 3 + - + Qt::Horizontal @@ -304,7 +315,9 @@ + 11 75 + true true @@ -312,7 +325,7 @@ Name - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -351,7 +364,7 @@
    - + @@ -384,14 +397,14 @@ - + Qt::Vertical 58 - 10 + 6 @@ -400,7 +413,7 @@ - + 0 @@ -421,7 +434,7 @@ QFrame::Sunken - + 5 @@ -477,8 +490,6 @@
    gui/gxs/GxsIdLabel.h
    - - - + diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp b/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp index 7f37aef8b..573c65c9d 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.cpp @@ -229,7 +229,7 @@ void ChatMsgItem::sendMessage() mi.title = tr("Quick Message").toUtf8().constData(); mi.msg = quickmsgText->toHtml().toUtf8().constData(); - mi.rspeerid_msgto.insert(mPeerId); + mi.destinations.insert(MsgAddress(mPeerId,MsgAddress::MSG_ADDRESS_MODE_TO)); rsMail->MessageSend(mi); diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.ui b/retroshare-gui/src/gui/feeds/ChatMsgItem.ui index 2a8725b09..64c994b6f 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.ui +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.ui @@ -10,7 +10,7 @@ 209 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,9 +40,9 @@ QFrame::Sunken - + - + @@ -60,7 +60,7 @@ - + Qt::Vertical @@ -75,7 +75,12 @@ - + + + + 17 + + Peer Name @@ -85,7 +90,7 @@ - + Qt::Horizontal @@ -149,7 +154,7 @@ - + 0 @@ -247,7 +252,7 @@ - + Qt::Horizontal @@ -307,7 +312,7 @@ - + 0 @@ -345,11 +350,6 @@
    gui/common/AvatarWidget.h
    1 - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    diff --git a/retroshare-gui/src/gui/feeds/FeedItem.cpp b/retroshare-gui/src/gui/feeds/FeedItem.cpp index 83c97eb3b..e9991e6d0 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/FeedItem.cpp @@ -23,7 +23,7 @@ #include "FeedHolder.h" /** Constructor */ -FeedItem::FeedItem(FeedHolder *fh, uint32_t feedId, QWidget *parent) : QWidget(parent), mHash(0),mFeedHolder(fh),mFeedId(feedId) +FeedItem::FeedItem(FeedHolder *fh, uint32_t feedId, QWidget *parent) : QWidget(parent),mFeedHolder(fh),mFeedId(feedId),mHash(0) { mWasExpanded = false; } diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp index 41c61d896..e9c38a022 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.cpp @@ -27,6 +27,7 @@ #include "gui/common/FilesDefs.h" #include "gui/NewsFeed.h" #include "gui/RetroShareLink.h" +#include "util/DateTime.h" /**** * #define DEBUG_ITEM 1 @@ -166,6 +167,11 @@ void GxsChannelGroupItem::fill() break ; } + if(mGroup.mMeta.mLastPost==0) + ui->infoLastPost->setText(tr("Never")); + else + ui->infoLastPost->setText(DateTime::formatLongDateTime(mGroup.mMeta.mLastPost)); + if (mIsHome) { /* disable buttons */ diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui index b5c3eb9aa..151e6920b 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.ui @@ -7,10 +7,18 @@ 0 0 618 - 161 + 176
    - + + + 11 + 75 + true + true + + + 1 @@ -24,7 +32,7 @@ 1 - + 0 @@ -34,6 +42,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +71,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +100,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +139,9 @@ QFrame::Sunken - + - + @@ -133,7 +168,7 @@ - + @@ -144,6 +179,7 @@ + 11 75 true true @@ -158,7 +194,9 @@ + 11 75 + true true @@ -171,7 +209,7 @@ - + Qt::Horizontal @@ -183,10 +221,24 @@ + + + + Last activity + + + + + + + TextLabel + + +
    - + @@ -207,7 +259,7 @@ - + Qt::Horizontal @@ -282,7 +334,7 @@ - + 0 @@ -303,7 +355,7 @@ Channel Description - + @@ -341,7 +393,6 @@ - diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index 733e3048b..17036a15e 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -49,6 +49,10 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, GxsFeedItem(feedHolder, feedId, group_meta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate), mGroupMeta(group_meta) { + mLoadingGroup = false; + mLoadingMessage = false; + mLoadingComment = false; + mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded mPost.mMeta.mGroupId = mGroupMeta.mGroupId; @@ -136,6 +140,19 @@ void GxsChannelPostItem::paintEvent(QPaintEvent *e) GxsChannelPostItem::~GxsChannelPostItem() { + auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300); + + while( (mLoadingGroup || mLoadingMessage || mLoadingComment) + && std::chrono::steady_clock::now() < timeout) + { + RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for " + << (mLoadingGroup ? "Group " : "") + << (mLoadingMessage ? "Message " : "") + << (mLoadingComment ? "Comment " : "") + << "loading." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + delete(ui); } @@ -221,9 +238,9 @@ void GxsChannelPostItem::setup() //ui->subjectLabel->setMinimumWidth(100); //ui->warning_label->setMinimumWidth(100); - ui->mainFrame->setProperty("new", false); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", false); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); ui->expandFrame->hide(); } @@ -277,6 +294,7 @@ void GxsChannelPostItem::loadGroup() std::cerr << "GxsChannelGroupItem::loadGroup()"; std::cerr << std::endl; #endif + mLoadingGroup = true; RsThread::async([this]() { @@ -306,6 +324,7 @@ void GxsChannelPostItem::loadGroup() * after a blocking call to RetroShare API complete */ mGroupMeta = group.mMeta; + mLoadingGroup = false; }, this ); }); @@ -316,6 +335,8 @@ void GxsChannelPostItem::loadMessage() std::cerr << "GxsChannelPostItem::loadMessage()"; std::cerr << std::endl; #endif + mLoadingMessage = true; + RsThread::async([this]() { // 1 - get group data @@ -337,7 +358,11 @@ void GxsChannelPostItem::loadMessage() #endif const RsGxsChannelPost& post(posts[0]); - RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this ); + RsQThreadUtils::postToObject( [post,this]() + { + setPost(post); + mLoadingMessage = false; + }, this ); } else if(comments.size() == 1) { @@ -356,7 +381,8 @@ void GxsChannelPostItem::loadMessage() setMessageId(cmt.mMeta.mThreadId); requestMessage(); - }, this ); + mLoadingMessage = false; + }, this ); } else @@ -366,7 +392,11 @@ void GxsChannelPostItem::loadMessage() std::cerr << std::endl; #endif - RsQThreadUtils::postToObject( [this]() { removeItem(); }, this ); + RsQThreadUtils::postToObject( [this]() + { + removeItem(); + mLoadingMessage = false; + }, this ); } }); } @@ -377,6 +407,7 @@ void GxsChannelPostItem::loadComment() std::cerr << "GxsChannelPostItem::loadComment()"; std::cerr << std::endl; #endif + mLoadingComment = true; RsThread::async([this]() { @@ -407,6 +438,7 @@ void GxsChannelPostItem::loadComment() sComButText = tr("Comments ").append("(%1)").arg(comNb); ui->commentButton->setText(sComButText); + mLoadingComment = false; }, this ); }); @@ -487,7 +519,7 @@ void GxsChannelPostItem::fill() /* subject */ ui->titleLabel->setText(QString::fromUtf8(mPost.mMeta.mMsgName.c_str())); - uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); + //uint32_t autorized_lines = (int)floor((ui->logoLabel->height() - ui->titleLabel->height() - ui->buttonHLayout->sizeHint().height())/QFontMetricsF(ui->subjectLabel->font()).height()); // fill first 4 lines of message. (csoler) Disabled the replacement of smileys and links, because the cost is too crazy //ui->subjectLabel->setText(RsHtml().formatText(NULL, RsStringUtil::CopyLines(QString::fromUtf8(mPost.mMsg.c_str()), autorized_lines), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); @@ -647,9 +679,9 @@ void GxsChannelPostItem::setReadStatus(bool isNew, bool isUnread) ui->newLabel->setVisible(isNew); - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } // void GxsChannelPostItem::setFileCleanUpWarning(uint32_t time_left) @@ -850,7 +882,7 @@ void GxsChannelPostItem::readToggled(bool /*checked*/) RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); - rsGxsChannels->markRead(msgPair, isUnread()); + rsGxsChannels->setMessageReadStatus(msgPair, isUnread()); //setReadStatus(false, checked); // Updated by events } diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h index 8370b885e..b3e7843c0 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -119,7 +119,12 @@ private: private: bool mInFill; bool mCloseOnRead; - bool mLoaded; + bool mLoaded; + + bool mLoadingMessage; + bool mLoadingGroup; + bool mLoadingComment; + RsGroupMetaData mGroupMeta; RsGxsChannelPost mPost; diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui index 3ce8c06b3..578fa1637 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -10,7 +10,7 @@ 231 - + 1 @@ -30,7 +30,7 @@ 1 - + 0 @@ -46,11 +46,11 @@ QFrame::Sunken - + - + @@ -86,6 +86,7 @@ + 11 75 true true @@ -125,7 +126,7 @@ - + Qt::Vertical @@ -139,6 +140,14 @@ + + + 11 + 75 + false + true + + TextLabel @@ -317,7 +326,7 @@ - + Qt::Horizontal @@ -385,7 +394,7 @@ - + 0 @@ -406,7 +415,7 @@ QFrame::Sunken - + 5 @@ -451,7 +460,7 @@ - + Qt::Vertical @@ -472,7 +481,7 @@ ElidedLabel QLabel -
    gui/common/ElidedLabel.h
    +
    gui/common/ElidedLabel.h
    1
    diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.h b/retroshare-gui/src/gui/feeds/GxsCircleItem.h index dc83dd30d..74f2cf44a 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.h +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.h @@ -24,8 +24,6 @@ #include #include "FeedItem.h" -#include "util/TokenQueue.h" - namespace Ui { class GxsCircleItem; } diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.ui b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui index c295d1b57..7a77f5bda 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.ui @@ -10,7 +10,7 @@ 108
    - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,7 +131,7 @@ QFrame::Sunken - + @@ -131,9 +158,9 @@ - + - + @@ -154,8 +181,9 @@ - 10 + 11 75 + true true @@ -177,6 +205,7 @@ + 11 75 true true @@ -188,7 +217,7 @@ - + Qt::Horizontal @@ -203,9 +232,9 @@ - + - + 10 @@ -220,6 +249,14 @@ + + + 11 + 75 + true + true + + name @@ -244,7 +281,7 @@ - + @@ -306,7 +343,7 @@ - + Qt::Horizontal @@ -358,8 +395,8 @@ - + diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp index 1d61bb98b..43c94a377 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.cpp @@ -125,7 +125,7 @@ void GxsForumGroupItem::loadGroup() std::cerr << std::endl; return; } - const RsGxsForumGroup& group(groups[0]); + RsGxsForumGroup group(groups[0]);// no reference to teporary accross threads! RsQThreadUtils::postToObject( [group,this]() { diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui index 88000d0cb..152d4951d 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.ui @@ -10,7 +10,7 @@ 464 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +131,9 @@ QFrame::Sunken - + - + @@ -133,7 +160,7 @@ - + @@ -144,6 +171,7 @@ + 11 75 true true @@ -158,7 +186,9 @@ + 11 75 + true true @@ -171,7 +201,7 @@ - + Qt::Horizontal @@ -186,7 +216,7 @@ - + @@ -207,7 +237,7 @@ - + Qt::Horizontal @@ -282,7 +312,7 @@ - + 0 @@ -303,7 +333,7 @@ Forum Description - + @@ -339,24 +369,34 @@ Moderator list - + - 0 + 6 - 0 + 9 - 0 + 9 - 0 + 9 - 0 + 9 - + + + TextLabel + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + @@ -367,7 +407,6 @@ - diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index a1a17448c..f4d091179 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -47,7 +47,13 @@ GxsForumMsgItem::GxsForumMsgItem(FeedHolder *feedHolder, uint32_t feedId, const { mMessage.mMeta.mMsgId = messageId; // useful for uniqueIdentifier() before the post is actually loaded mMessage.mMeta.mGroupId = groupId; - setup(); + + mLoadingGroup = false; + mLoadingMessage = false; + mLoadingSetAsRead = false; + mLoadingParentMessage = false; + + setup(); requestGroup(); requestMessage(); @@ -83,6 +89,19 @@ GxsForumMsgItem::GxsForumMsgItem(FeedHolder *feedHolder, uint32_t feedId, const GxsForumMsgItem::~GxsForumMsgItem() { + auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300); + + while( (mLoadingGroup || mLoadingMessage || mLoadingSetAsRead || mLoadingParentMessage) + && std::chrono::steady_clock::now() < timeout) + { + RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for " + << (mLoadingGroup ? "Group " : "") + << (mLoadingMessage ? "Message " : "") + << (mLoadingParentMessage ? "Parent message " : "") + << (mLoadingSetAsRead ? "Set as read" : "") + << "loading." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } delete(ui); } @@ -106,7 +125,7 @@ void GxsForumMsgItem::setup() connect(ui->subjectLabel, SIGNAL(linkActivated(QString)), this, SLOT(on_linkActivated(QString))); ui->timestamplabel->clear(); ui->parentNameLabel->clear(); - ui->nameLabel->clear(); + ui->currNameLabel->clear(); /* general ones */ connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle())); @@ -125,16 +144,6 @@ void GxsForumMsgItem::setup() ui->parentFrame->hide(); } -bool GxsForumMsgItem::isTop() -{ -// if (mMessage.mMeta.mMsgId == mMessage.mMeta.mThreadId || mMessage.mMeta.mThreadId.isNull()) { - if (mMessage.mMeta.mParentId.isNull()) { - return true; - } - - return false; -} - bool GxsForumMsgItem::setGroup(const RsGxsForumGroup &group, bool doFill) { if (groupId() != group.mMeta.mGroupId) { @@ -145,9 +154,8 @@ bool GxsForumMsgItem::setGroup(const RsGxsForumGroup &group, bool doFill) mGroup = group; - if (doFill) { - fill(); - } + if (doFill) + fillGroup(); return true; } @@ -162,10 +170,11 @@ bool GxsForumMsgItem::setMessage(const RsGxsForumMsg &msg, bool doFill) mMessage = msg; - if (!isTop()) - loadParentMessage(mMessage.mMeta.mParentId); - else if(doFill) - fill(); + if(! mMessage.mMeta.mParentId.isNull()) + loadParentMessage(mMessage.mMeta.mParentId); + + if(doFill) + fillMessage(); return true; } @@ -177,6 +186,8 @@ QString GxsForumMsgItem::groupName() void GxsForumMsgItem::loadGroup() { + mLoadingGroup = true; + RsThread::async([this]() { // 1 - get group data @@ -209,6 +220,7 @@ void GxsForumMsgItem::loadGroup() * after a blocking call to RetroShare API complete */ setGroup(group); + mLoadingGroup = false; }, this ); }); @@ -220,6 +232,7 @@ void GxsForumMsgItem::loadMessage() std::cerr << "GxsForumMsgItem::loadMessage(): messageId=" << messageId() << " groupId=" << groupId() ; std::cerr << std::endl; #endif + mLoadingMessage = true; RsThread::async([this]() { @@ -245,7 +258,7 @@ void GxsForumMsgItem::loadMessage() std::cerr << std::endl; return; } - const RsGxsForumMsg& msg(msgs[0]); + RsGxsForumMsg msg(msgs[0]); RsQThreadUtils::postToObject( [msg,this]() { @@ -254,6 +267,7 @@ void GxsForumMsgItem::loadMessage() * after a blocking call to RetroShare API complete */ setMessage(msg); + mLoadingMessage = false; }, this ); }); @@ -265,6 +279,7 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg) std::cerr << "GxsForumMsgItem::loadParentMessage()"; std::cerr << std::endl; #endif + mLoadingParentMessage = true; RsThread::async([parent_msg,this]() { @@ -290,7 +305,7 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg) std::cerr << std::endl; return; } - const RsGxsForumMsg& msg(msgs[0]); + RsGxsForumMsg msg(msgs[0]); RsQThreadUtils::postToObject( [msg,this]() { @@ -299,119 +314,106 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg) * after a blocking call to RetroShare API complete */ mParentMessage = msg; - fill(); + fillParentMessage(); + + mLoadingParentMessage = false; }, this ); }); } - -void GxsForumMsgItem::fill() +void GxsForumMsgItem::fillParentMessage() { - /* fill in */ + mInFill = true; -// if (isLoading()) { -// /* Wait for all requests */ -// return; -// } + ui->parentFrame->hide(); + RetroShareLink linkParent = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mParentMessage.mMeta.mGroupId, mParentMessage.mMeta.mMsgId, QString::fromUtf8(mParentMessage.mMeta.mMsgName.c_str())); + ui->parentSubLabel->setText(linkParent.toHtml()); + ui->parentMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mParentMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + ui->parentNameLabel->setId(mParentMessage.mMeta.mAuthorId); + + RsIdentityDetails idDetails ; + rsIdentity->getIdDetails(mParentMessage.mMeta.mAuthorId,idDetails); + + QPixmap pixmap ; + + if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(mParentMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); + + ui->parentAvatar->setPixmap(pixmap); + + mInFill = false; +} +void GxsForumMsgItem::fillMessage() +{ #ifdef DEBUG_ITEM - std::cerr << "GxsForumMsgItem::fill()"; - std::cerr << std::endl; + std::cerr << "GxsForumMsgItem::fill()"; + std::cerr << std::endl; #endif + mInFill = true; + + if(!mIsHome && mCloseOnRead && !IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) + removeItem(); + + QString title = tr("Forum Feed") + ": "; + RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, groupName()); + title += link.toHtml(); + ui->titleLabel->setText(title); + + setReadStatus(IS_MSG_NEW(mMessage.mMeta.mMsgStatus), IS_MSG_UNREAD(mMessage.mMeta.mMsgStatus) || IS_MSG_NEW(mMessage.mMeta.mMsgStatus)); + + if (!mIsHome && IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) + mCloseOnRead = true; + + RsIdentityDetails idDetails ; + rsIdentity->getIdDetails(mMessage.mMeta.mAuthorId,idDetails); + + QPixmap pixmap ; + + if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) + pixmap = GxsIdDetails::makeDefaultIcon(mMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); + + ui->currAvatar->setPixmap(pixmap); + + ui->currNameLabel->setId(mMessage.mMeta.mAuthorId); + + RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, mMessage.mMeta.mMsgId, messageName()); + ui->currSubLabel->setText(msgLink.toHtml()); + if (wasExpanded() || ui->expandFrame->isVisible()) + fillExpandFrame(); + + ui->timestamplabel->setText(DateTime::formatLongDateTime(mMessage.mMeta.mPublishTs)); + + /* header stuff */ + ui->subjectLabel->setText(msgLink.toHtml()); + + if (mIsHome) + { + /* disable buttons */ + ui->clearButton->setEnabled(false); + ui->clearButton->hide(); + } + + mInFill = false; +} +void GxsForumMsgItem::fillGroup() +{ mInFill = true; - if (!mIsHome) - { - if (mCloseOnRead && !IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) { - removeItem(); - } - } + ui->unsubscribeButton->setEnabled(IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags)) ; - QString title = tr("Forum Feed") + ": "; - RetroShareLink link = RetroShareLink::createGxsGroupLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, groupName()); - title += link.toHtml(); - ui->titleLabel->setText(title); - - if (IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags) || IS_GROUP_ADMIN(mGroup.mMeta.mSubscribeFlags)) { - ui->unsubscribeButton->setEnabled(true); - - setReadStatus(IS_MSG_NEW(mMessage.mMeta.mMsgStatus), IS_MSG_UNREAD(mMessage.mMeta.mMsgStatus) || IS_MSG_NEW(mMessage.mMeta.mMsgStatus)); - } else { - ui->unsubscribeButton->setEnabled(false); - } - - if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) { + if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) ui->iconLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); - } else { + else ui->iconLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums-default.png")); - } - - if (!mIsHome) { - if (IS_MSG_NEW(mMessage.mMeta.mMsgStatus)) { - mCloseOnRead = true; - } - } - - RsIdentityDetails idDetails ; - rsIdentity->getIdDetails(mMessage.mMeta.mAuthorId,idDetails); - - QPixmap pixmap ; - - if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) - pixmap = GxsIdDetails::makeDefaultIcon(mMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); - - ui->avatar->setPixmap(pixmap); - - ui->nameLabel->setId(mMessage.mMeta.mAuthorId); - - RetroShareLink msgLink = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mMessage.mMeta.mGroupId, mMessage.mMeta.mMsgId, messageName()); - ui->subLabel->setText(msgLink.toHtml()); - if (wasExpanded() || ui->expandFrame->isVisible()) { - fillExpandFrame(); - } - - ui->timestamplabel->setText(DateTime::formatLongDateTime(mMessage.mMeta.mPublishTs)); - - if (isTop()) { - ui->parentFrame->hide(); - } else { - - RetroShareLink linkParent = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_FORUM, mParentMessage.mMeta.mGroupId, mParentMessage.mMeta.mMsgId, QString::fromUtf8(mParentMessage.mMeta.mMsgName.c_str())); - ui->parentSubLabel->setText(linkParent.toHtml()); - ui->parentMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mParentMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); - - ui->parentNameLabel->setId(mParentMessage.mMeta.mAuthorId); - - RsIdentityDetails idDetails ; - rsIdentity->getIdDetails(mParentMessage.mMeta.mAuthorId,idDetails); - - QPixmap pixmap ; - - if(idDetails.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idDetails.mAvatar.mData, idDetails.mAvatar.mSize, pixmap,GxsIdDetails::SMALL)) - pixmap = GxsIdDetails::makeDefaultIcon(mParentMessage.mMeta.mAuthorId,GxsIdDetails::SMALL); - - ui->parentAvatar->setPixmap(pixmap); - - } - - /* header stuff */ - ui->subjectLabel->setText(msgLink.toHtml()); - - if (mIsHome) - { - /* disable buttons */ - ui->clearButton->setEnabled(false); - - ui->clearButton->hide(); - } mInFill = false; } void GxsForumMsgItem::fillExpandFrame() { - ui->msgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + ui->currMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); } QString GxsForumMsgItem::messageName() @@ -436,7 +438,7 @@ void GxsForumMsgItem::doExpand(bool open) ui->parentFrame->show(); } - setAsRead(); + setAsRead(true); } else { @@ -470,9 +472,9 @@ void GxsForumMsgItem::toggle() void GxsForumMsgItem::setReadStatus(bool isNew, bool /*isUnread*/) { - ui->mainFrame->setProperty("new", isNew); - ui->mainFrame->style()->unpolish(ui->mainFrame); - ui->mainFrame->style()->polish( ui->mainFrame); + ui->feedFrame->setProperty("new", isNew); + ui->feedFrame->style()->unpolish(ui->feedFrame); + ui->feedFrame->style()->polish( ui->feedFrame); } /*********** SPECIFIC FUNCTIONS ***********************/ @@ -484,7 +486,7 @@ void GxsForumMsgItem::readAndClearItem() std::cerr << std::endl; #endif - setAsRead(); + setAsRead(false); removeItem(); } @@ -498,20 +500,27 @@ void GxsForumMsgItem::unsubscribeForum() unsubscribe(); } -void GxsForumMsgItem::setAsRead() +void GxsForumMsgItem::setAsRead(bool doUpdate) { - if (mInFill) { - return; - } + if (mInFill) { + return; + } - mCloseOnRead = false; + mCloseOnRead = false; + mLoadingSetAsRead = true; - RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); + RsThread::async( [this, doUpdate]() { + RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); - uint32_t token; - rsGxsForums->setMessageReadStatus(token, msgPair, true); + rsGxsForums->markRead(msgPair, true); - setReadStatus(false, false); + if (doUpdate) { + RsQThreadUtils::postToObject( [this]() { + setReadStatus(false, true); + mLoadingSetAsRead = false; + } ); + } + }); } void GxsForumMsgItem::on_linkActivated(QString link) diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h index 410a97931..ec933d96e 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h @@ -77,15 +77,20 @@ signals: private: void setup(); - void fill(); - void fillExpandFrame(); + void fillGroup(); + void fillMessage(); + void fillParentMessage(); + void fillExpandFrame(); void setReadStatus(bool isNew, bool isUnread); - void setAsRead(); - bool isTop(); + void setAsRead(bool doUpdate); private: bool mInFill; bool mCloseOnRead; + bool mLoadingMessage; + bool mLoadingParentMessage; + bool mLoadingGroup; + bool mLoadingSetAsRead; RsGxsForumGroup mGroup; RsGxsForumMsg mMessage; diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui index 5967010b7..89aec4e1b 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui @@ -10,7 +10,7 @@ 360 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -45,6 +54,15 @@ + + + + 0 + 0 + 0 + + + @@ -56,6 +74,15 @@ + + + + 154 + 154 + 154 + + + @@ -77,7 +104,7 @@ QFrame::Sunken - + @@ -104,7 +131,7 @@ - + @@ -115,7 +142,9 @@ + 11 75 + true true @@ -134,7 +163,7 @@ - + Qt::Horizontal @@ -165,9 +194,9 @@ - + - + 75 @@ -196,7 +225,7 @@ - + Qt::Horizontal @@ -299,7 +328,7 @@ - + 32 @@ -331,9 +360,9 @@ - + - + 0 @@ -371,7 +400,7 @@ - + Qt::Horizontal @@ -389,7 +418,7 @@ - + Qt::Vertical @@ -402,7 +431,7 @@ - + @@ -426,7 +455,7 @@ - + Qt::Horizontal @@ -454,9 +483,9 @@ QFrame::Sunken - + - + 32 @@ -472,10 +501,12 @@ - + + 11 75 + true true @@ -488,9 +519,9 @@ - + - + 0 @@ -509,7 +540,7 @@ - + 0 @@ -530,7 +561,7 @@ - + Qt::Vertical @@ -543,9 +574,9 @@ - + - + 0 @@ -587,13 +618,12 @@ AvatarWidget - QLabel + QWidget
    gui/common/AvatarWidget.h
    1
    - diff --git a/retroshare-gui/src/gui/feeds/MsgItem.cpp b/retroshare-gui/src/gui/feeds/MsgItem.cpp index 87a01bcd9..0789d98c9 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/MsgItem.cpp @@ -31,6 +31,7 @@ #include "gui/common/AvatarDefs.h" #include "gui/common/FilesDefs.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include #include @@ -59,20 +60,73 @@ MsgItem::MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, //connect( gotoButton, SIGNAL( clicked( void ) ), this, SLOT( gotoHome ( void ) ) ); /* specific ones */ - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(checkMessageReadStatus())); connect( playButton, SIGNAL( clicked( void ) ), this, SLOT( playMedia ( void ) ) ); connect( deleteButton, SIGNAL( clicked( void ) ), this, SLOT( deleteMsg ( void ) ) ); connect( replyButton, SIGNAL( clicked( void ) ), this, SLOT( replyMsg ( void ) ) ); connect( sendinviteButton, SIGNAL( clicked( void ) ), this, SLOT( sendInvite ( void ) ) ); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); expandFrame->hide(); - inviteFrame->hide(); + info_Frame_Invite->hide(); updateItemStatic(); updateItem(); } +MsgItem::~MsgItem() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MsgItem::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_CHANGED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + MessageInfo msgInfo; + + if (!rsMail->getMessage(mMsgId, msgInfo)) { + removeItem(); + break; + } + + if (!mCloseOnRead) { + break; + } + + if (msgInfo.msgflags & RS_MSG_NEW) { + /* Message status is still "new" */ + break; + } + + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(mMsgId) != fe->mChangedMsgIds.end()) { + removeItem(); + } + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::TAG_CHANGED: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} + void MsgItem::updateItemStatic() { /* fill in */ @@ -92,44 +146,44 @@ void MsgItem::updateItemStatic() /* get peer Id */ if (mi.msgflags & RS_MSG_DISTANT) - avatar->setGxsId(mi.rsgxsid_srcId) ; + avatar->setGxsId(mi.from.toGxsId()) ; else - avatar->setId(ChatId(mi.rspeerid_srcId)) ; + avatar->setId(ChatId(mi.from.toRsPeerId())) ; QString title; QString srcName; - if ((mi.msgflags & RS_MSG_SYSTEM) && mi.rspeerid_srcId == rsPeers->getOwnId()) + if ((mi.msgflags & RS_MSG_SYSTEM) && mi.from.toRsPeerId() == rsPeers->getOwnId()) srcName = "RetroShare"; else { if(mi.msgflags & RS_MSG_DISTANT) { RsIdentityDetails details ; - rsIdentity->getIdDetails(mi.rsgxsid_srcId, details) ; + rsIdentity->getIdDetails(mi.from.toGxsId(), details) ; srcName = QString::fromUtf8(details.mNickname.c_str()); } else - srcName = QString::fromUtf8(rsPeers->getPeerName(mi.rspeerid_srcId).c_str()); + srcName = QString::fromUtf8(rsPeers->getPeerName(mi.from.toRsPeerId()).c_str()); } if (!mIsHome) { - if ((mi.msgflags & RS_MSG_USER_REQUEST) && (!mi.rsgxsid_srcId.isNull())) + if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // !mi.rsgxsid_srcId.isNull())) { title = QString::fromUtf8(mi.title.c_str()) + " " + tr("from") + " " + srcName; replyButton->setText(tr("Reply to invite")); subjectLabel->hide(); - inviteFrame->show(); + info_Frame_Invite->show(); } - else if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.rsgxsid_srcId.isNull()) + else if ((mi.msgflags & RS_MSG_USER_REQUEST) && mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // mi.rsgxsid_srcId.isNull()) { title = QString::fromUtf8(mi.title.c_str()) + " " + " " + srcName; subjectLabel->hide(); - inviteFrame->show(); - infoLabel->setText(tr("This message invites you to make friend! You may accept this request.")); + info_Frame_Invite->show(); + infoLabel_Invite->setText(tr("This message invites you to make friend! You may accept this request.")); sendinviteButton->hide(); replyButton->hide(); } @@ -137,7 +191,7 @@ void MsgItem::updateItemStatic() { title = tr("Message From") + ": " + srcName; sendinviteButton->hide(); - inviteFrame->hide(); + info_Frame_Invite->hide(); } } else @@ -179,7 +233,11 @@ void MsgItem::updateItemStatic() for(it = mi.files.begin(); it != mi.files.end(); ++it) { /* add file */ - SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, SFI_STATE_REMOTE, mi.rspeerid_srcId); + RsPeerId srcId ; + if(mi.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + srcId = mi.from.toRsPeerId(); + + SubFileItem *fi = new SubFileItem(it->hash, it->fname, it->path, it->size, SFI_STATE_REMOTE, srcId); mFileItems.push_back(fi); QLayout *layout = expandFrame->layout(); @@ -246,7 +304,6 @@ void MsgItem::doExpand(bool open) mCloseOnRead = false; rsMail->MessageRead(mMsgId, false); - mCloseOnRead = true; } else { @@ -332,26 +389,6 @@ void MsgItem::toggle() expand(expandFrame->isHidden()); } -void MsgItem::checkMessageReadStatus() -{ - if (!mCloseOnRead) { - return; - } - - MessageInfo msgInfo; - if (!rsMail->getMessage(mMsgId, msgInfo)) { - std::cerr << "MsgItem::checkMessageReadStatus() Couldn't find Msg" << std::endl; - return; - } - - if (msgInfo.msgflags & RS_MSG_NEW) { - /* Message status is still "new" */ - return; - } - - removeItem(); -} - void MsgItem::sendInvite() { MessageInfo mi; @@ -362,9 +399,12 @@ void MsgItem::sendInvite() if (!rsMail->getMessage(mMsgId, mi)) return; + if(mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + return; + //if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) //{ - MessageComposer::sendInvite(mi.rsgxsid_srcId,false); + MessageComposer::sendInvite(mi.from.toGxsId(),false); //} } diff --git a/retroshare-gui/src/gui/feeds/MsgItem.h b/retroshare-gui/src/gui/feeds/MsgItem.h index 32824ca23..2cb8645ba 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.h +++ b/retroshare-gui/src/gui/feeds/MsgItem.h @@ -24,6 +24,7 @@ #include "ui_MsgItem.h" #include "FeedItem.h" #include +#include class FeedHolder; class SubFileItem; @@ -35,6 +36,7 @@ class MsgItem : public FeedItem, private Ui::MsgItem public: /** Default Constructor */ MsgItem(FeedHolder *parent, uint32_t feedId, const std::string &msgId, bool isHome); + virtual ~MsgItem(); void updateItemStatic(); @@ -46,6 +48,7 @@ protected: private: void fillExpandFrame(); + void handleEvent_main_thread(std::shared_ptr event); private slots: /* default stuff */ @@ -56,7 +59,6 @@ private slots: void deleteMsg(); void replyMsg(); void sendInvite(); - void checkMessageReadStatus(); void updateItem(); @@ -66,6 +68,7 @@ private: bool mIsHome; bool mCloseOnRead; + RsEventsHandlerId_t mEventHandlerId; std::list mFileItems; }; diff --git a/retroshare-gui/src/gui/feeds/MsgItem.ui b/retroshare-gui/src/gui/feeds/MsgItem.ui index 9075554a9..b195e80c6 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.ui +++ b/retroshare-gui/src/gui/feeds/MsgItem.ui @@ -10,7 +10,7 @@ 180
    - + 1 @@ -24,7 +24,7 @@ 1
    - + 0 @@ -40,10 +40,10 @@ QFrame::Sunken - + - - + + 0 @@ -57,7 +57,7 @@ 0 - + 70 @@ -82,7 +82,7 @@ - 12 + 11 75 true true @@ -97,7 +97,7 @@ - + Qt::Horizontal @@ -142,7 +142,7 @@ - + @@ -164,7 +164,7 @@ - + Qt::Horizontal @@ -259,10 +259,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -283,6 +292,15 @@ + + + + 0 + 0 + 0 + + + @@ -303,6 +321,15 @@ + + + + 154 + 154 + 154 + + + @@ -333,7 +360,7 @@ QFrame::Box - + 6 @@ -347,7 +374,7 @@ 6 - + 16 @@ -366,7 +393,7 @@ - + This message invites you to make friend! You may accept this request and send your own Certificate back @@ -380,7 +407,7 @@ - + @@ -412,7 +439,7 @@ AvatarWidget - QLabel + QWidget
    gui/common/AvatarWidget.h
    1
    diff --git a/retroshare-gui/src/gui/feeds/PeerItem.ui b/retroshare-gui/src/gui/feeds/PeerItem.ui index 230cbd7a4..603002f7f 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.ui +++ b/retroshare-gui/src/gui/feeds/PeerItem.ui @@ -7,13 +7,13 @@ 0 0 476 - 262 + 283
    false - + 1 @@ -27,7 +27,7 @@ 1 - + 0 @@ -43,13 +43,13 @@ QFrame::Sunken - + 0 - + 0 @@ -59,8 +59,11 @@ 0 + + 0 + - + 70 @@ -75,84 +78,11 @@ - - - - - - Peer Name - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - 0 - 0 - - - - - 75 - true - true - - - - Connected - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - - Qt::Horizontal - - - - 190 - 13 - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - TextLabel - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - - - - + + + + 6 + @@ -203,7 +133,7 @@ - + Qt::Horizontal @@ -260,16 +190,97 @@ + + + + 6 + + + + + + 0 + 0 + + + + + 75 + true + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + + + + 17 + + + + Peer Name + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Qt::Horizontal + + + + 190 + 13 + + + + + + + + + 0 + 0 + + + + + 11 + 75 + true + true + + + + Connected + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + - + - + - + @@ -397,7 +408,7 @@ - + @@ -406,6 +417,14 @@ 0 + + + 11 + 75 + true + true + + TextLabel @@ -508,18 +527,18 @@ AvatarWidget - QLabel + QWidget
    gui/common/AvatarWidget.h
    1
    - StyledLabel + ElidedLabel QLabel -
    gui/common/StyledLabel.h
    +
    gui/common/ElidedLabel.h
    + 1
    - diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp index 4ed8a95c4..f4abafb08 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.cpp @@ -26,6 +26,7 @@ #include "gui/RetroShareLink.h" #include "gui/gxs/GxsIdDetails.h" #include "gui/common/FilesDefs.h" +#include "util/DateTime.h" /**** * #define DEBUG_ITEM 1 @@ -160,6 +161,10 @@ void PostedGroupItem::fill() ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png")); } + if(mGroup.mMeta.mLastPost==0) + ui->infoLastPost->setText(tr("Never")); + else + ui->infoLastPost->setText(DateTime::formatLongDateTime(mGroup.mMeta.mLastPost)); //TODO - nice icon for subscribed group // if (IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) { diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui index 27226fd28..b525facb9 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.ui +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.ui @@ -10,7 +10,7 @@ 161 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -34,6 +34,15 @@ + + + + 0 + 0 + 0 + + + @@ -54,6 +63,15 @@ + + + + 0 + 0 + 0 + + + @@ -74,6 +92,15 @@ + + + + 154 + 154 + 154 + + + @@ -104,9 +131,9 @@ QFrame::Sunken - + - + @@ -133,7 +160,7 @@ - + @@ -144,6 +171,7 @@ + 11 75 true true @@ -158,7 +186,9 @@ + 11 75 + true true @@ -171,7 +201,7 @@ - + Qt::Horizontal @@ -183,10 +213,37 @@ + + + + + 75 + true + + + + Last activity + + + + + + + + 75 + true + true + + + + TextLabel + + +
    - + @@ -207,7 +264,7 @@ - + Qt::Horizontal @@ -282,7 +339,7 @@ - + 0 @@ -303,14 +360,14 @@ Board Description - + - :/images/contacts24.png + :/images/contacts24.png @@ -340,8 +397,6 @@ - - diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.ui b/retroshare-gui/src/gui/feeds/SecurityIpItem.ui index a9471c6b1..11a742880 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.ui +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.ui @@ -10,7 +10,7 @@ 185 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -43,12 +43,12 @@ QFrame::Sunken - + 0 - + 0 @@ -66,7 +66,7 @@ 0 - + 70 @@ -79,13 +79,141 @@ 70 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + + + + 6 + + + 0 + + + + + + 11 + 75 + true + true + + + + Title + + + + + + + + 0 + 0 + + + + + 10 + + + + IP address: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + <html><head/><body><p>This warning is here to protect you against traffic forwarding attacks. In such a case, the friend you're connected to will not see your external IP, but the attacker's IP. </p><p><br/></p><p>However, if you just changed IPs for some reason (some ISPs regularly force change IPs) this warning just tells you that a friend connected to the new IP before Retroshare figured out the IP changed. Nothing's wrong in this case.</p><p><br/></p><p>You can easily suppress false warnings by white-listing your own IPs (e.g. the range of your ISP), or by completely disabling these warnings in Options-&gt;Notify-&gt;News Feed.</p></body></html> + + + IP Address + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + but reported: + + + + + + + + 0 + 0 + + + + IP address reported + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Peer: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Name (Location) + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + 75 + true + + + + TextLabel + + + Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + + + + - + 6 @@ -142,7 +270,7 @@ - + Qt::Horizontal @@ -196,130 +324,12 @@ - - - - - - - 75 - true - - - - TextLabel - - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing - - - - - - - - - 6 - - - 0 - - - - - - 0 - 0 - - - - IP address: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - true - - - - - - - <html><head/><body><p>This warning is here to protect you against traffic forwarding attacks. In such a case, the friend you're connected to will not see your external IP, but the attacker's IP. </p><p><br/></p><p>However, if you just changed IPs for some reason (some ISPs regularly force change IPs) this warning just tells you that a friend connected to the new IP before Retroshare figured out the IP changed. Nothing's wrong in this case.</p><p><br/></p><p>You can easily suppress false warnings by white-listing your own IPs (e.g. the range of your ISP), or by completely disabling these warnings in Options-&gt;Notify-&gt;News Feed.</p></body></html> - - - IP Address - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - but reported: - - - - - - - - 0 - 0 - - - - IP address reported - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Peer: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Title - - - - - - - - 0 - 0 - - - - Name (Location) - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - -
    - + @@ -333,22 +343,6 @@ - - - - - 0 - 0 - - - - Location - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - @@ -365,19 +359,6 @@ - - - - - 75 - true - - - - Location: - - - @@ -401,6 +382,35 @@ + + + + + 75 + true + + + + Location: + + + + + + + + 0 + 0 + + + + Location + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + @@ -412,15 +422,10 @@ AvatarWidget - QLabel + QWidget
    gui/common/AvatarWidget.h
    1
    - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    RsBanListToolButton QToolButton diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.cpp b/retroshare-gui/src/gui/feeds/SecurityItem.cpp index b2bbc2cf3..584eee212 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityItem.cpp @@ -138,6 +138,7 @@ void SecurityItem::updateItemStatic() title = tr("Missing/Damaged certificate. Not a real Retroshare user."); requestLabel->hide(); } + avatar->setDefaultAvatar(":icons/ssl.png"); break; case RS_FEED_ITEM_SEC_INTERNAL_ERROR: title = tr("Certificate caused an internal error."); @@ -186,7 +187,7 @@ void SecurityItem::updateItem() */ /* set peer name */ - peerNameLabel->setText(tr("A unknown peer")); + //peerNameLabel->setText(tr("A unknown peer")); nameLabel->setText(tr("Unknown") + " (" + tr("Profile ID: ") + QString::fromStdString(mGpgId.toStdString()) + ")"); idLabel->setText(QString::fromStdString(mSslId.toStdString())); @@ -205,15 +206,25 @@ void SecurityItem::updateItem() connLeftLabel->hide(); chatButton->hide(); - //quickmsgButton->hide(); - requestLabel->hide(); removeFriendButton->setEnabled(false); removeFriendButton->hide(); peerDetailsButton->setEnabled(false); - - friendRequesttoolButton->show(); - requestLabel->show(); + + if(mType == RS_FEED_ITEM_SEC_BAD_CERTIFICATE) + { + peerNameLabel->setText(tr("SSL request")); + friendRequesttoolButton->hide(); + requestLabel->hide(); + peerDetailsButton->hide(); + } + else + { + peerNameLabel->setText(tr("An unknown peer")); + friendRequesttoolButton->show(); + requestLabel->show(); + peerDetailsButton->show(); + } return; } diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.ui b/retroshare-gui/src/gui/feeds/SecurityItem.ui index de674a133..bc0524d18 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.ui +++ b/retroshare-gui/src/gui/feeds/SecurityItem.ui @@ -10,7 +10,7 @@ 246 - + 1 @@ -24,7 +24,7 @@ 1 - + 0 @@ -40,13 +40,13 @@ QFrame::Sunken - + 0 - - + + 0 @@ -63,7 +63,7 @@ 0 - + 70 @@ -76,13 +76,10 @@ 70 - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - + 6 @@ -90,7 +87,12 @@ 0 - + + + + 17 + + Peer Name @@ -109,6 +111,7 @@ + 11 75 true true @@ -123,13 +126,18 @@ - + 0 0 + + + 17 + + wants to be friend with you on RetroShare @@ -144,7 +152,7 @@ - + @@ -164,7 +172,7 @@ - + 6 @@ -276,7 +284,7 @@ - + Qt::Horizontal @@ -292,7 +300,7 @@ - + Qt::Horizontal @@ -351,11 +359,11 @@ - + - + - + @@ -463,7 +471,7 @@ - + @@ -472,6 +480,14 @@ 0 + + + 11 + 75 + true + true + + TextLabel @@ -570,19 +586,14 @@ AvatarWidget - QLabel + QWidget
    gui/common/AvatarWidget.h
    1
    - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    - + diff --git a/retroshare-gui/src/gui/feeds/SubFileItem.ui b/retroshare-gui/src/gui/feeds/SubFileItem.ui index 6717836b5..8fdd8230d 100644 --- a/retroshare-gui/src/gui/feeds/SubFileItem.ui +++ b/retroshare-gui/src/gui/feeds/SubFileItem.ui @@ -10,7 +10,7 @@ 128 - + 0 @@ -27,16 +27,16 @@ 0 - + QFrame::Box QFrame::Sunken - + - + @@ -215,7 +215,7 @@ - + diff --git a/retroshare-gui/src/gui/groups/CreateGroup.cpp b/retroshare-gui/src/gui/groups/CreateGroup.cpp index 91380f98b..2a3defc9c 100644 --- a/retroshare-gui/src/gui/groups/CreateGroup.cpp +++ b/retroshare-gui/src/gui/groups/CreateGroup.cpp @@ -41,7 +41,7 @@ CreateGroup::CreateGroup(const RsNodeGroupId &groupId, QWidget *parent) mIsStandard = false; - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/user/add_group256.png")); + ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/groups/colored.svg")); mGroupId = groupId; @@ -69,7 +69,7 @@ CreateGroup::CreateGroup(const RsNodeGroupId &groupId, QWidget *parent) } setWindowTitle(tr("Edit Group")); - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/images/user/edit_group64.png")); + ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/groups/colored.svg")); ui.headerFrame->setHeaderText(tr("Edit Group")); ui.groupName->setDisabled(mIsStandard); diff --git a/retroshare-gui/src/gui/groups/CreateGroup.ui b/retroshare-gui/src/gui/groups/CreateGroup.ui index 7abcd5a4e..838a15ac6 100644 --- a/retroshare-gui/src/gui/groups/CreateGroup.ui +++ b/retroshare-gui/src/gui/groups/CreateGroup.ui @@ -13,27 +13,36 @@ Create a Group - + + + 0 + + + 0 + + + 0 + + + 0 + 6 0 - - 0 - - + QFrame::StyledPanel QFrame::Raised - + - + diff --git a/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp b/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp index 630a3efbe..9e56c53cd 100644 --- a/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCircleChooser.cpp @@ -20,15 +20,15 @@ #include "GxsCircleChooser.h" -#include #include +#include #include /** Constructor */ GxsCircleChooser::GxsCircleChooser(QWidget *parent) -: QComboBox(parent) + : RSComboBox(parent) { return; } diff --git a/retroshare-gui/src/gui/gxs/GxsCircleChooser.h b/retroshare-gui/src/gui/gxs/GxsCircleChooser.h index f78b350b8..37234b230 100644 --- a/retroshare-gui/src/gui/gxs/GxsCircleChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsCircleChooser.h @@ -21,17 +21,18 @@ #ifndef _GXS_CIRCLES_CHOOSER_H #define _GXS_CIRCLES_CHOOSER_H -#include +#include "gui/common/RSComboBox.h" + #include -class GxsCircleChooser : public QComboBox +class GxsCircleChooser : public RSComboBox { - Q_OBJECT + Q_OBJECT public: - GxsCircleChooser(QWidget *parent = NULL); + GxsCircleChooser(QWidget *parent = nullptr); - void loadCircles(const RsGxsCircleId &defaultId); + void loadCircles(const RsGxsCircleId &defaultId); bool getChosenCircle(RsGxsCircleId &id); private: diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp index b80539cea..5d899104e 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.cpp @@ -60,7 +60,7 @@ void GxsCommentContainer::commentLoad(const RsGxsGroupId &grpId, const std::set< comments += "..."; } - GxsCommentDialog *commentDialog = new GxsCommentDialog(this, RsGxsId(),getTokenService(), getCommentService()); + GxsCommentDialog *commentDialog = new GxsCommentDialog(this, RsGxsId(),getCommentService()); QWidget *commentHeader = createHeaderWidget(grpId, msgId); commentDialog->setCommentHeader(commentHeader); diff --git a/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui index bad001d4f..72b64e4e0 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui +++ b/retroshare-gui/src/gui/gxs/GxsCommentContainer.ui @@ -46,7 +46,14 @@ - + + + + 12 + 75 + true + + Comment Container @@ -87,12 +94,7 @@
    gui/common/RSTabWidget.h
    1
    - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    + diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp index b610f9dd3..4757b036e 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.cpp @@ -30,13 +30,13 @@ #include /** Constructor */ -GxsCommentDialog::GxsCommentDialog(QWidget *parent, const RsGxsId &default_author, RsTokenService *token_service, RsGxsCommentService *comment_service) +GxsCommentDialog::GxsCommentDialog(QWidget *parent, const RsGxsId &default_author, RsGxsCommentService *comment_service) : QWidget(parent), ui(new Ui::GxsCommentDialog) { /* Invoke the Qt Designer generated QObject setup routine */ ui->setupUi(this); - setTokenService(token_service,comment_service); + setGxsService(comment_service); init(default_author); } @@ -67,9 +67,9 @@ void GxsCommentDialog::init(const RsGxsId& default_author) ui->sortBox->setIconSize(QSize(S*1.5,S*1.5)); } -void GxsCommentDialog::setTokenService(RsTokenService *token_service, RsGxsCommentService *comment_service) +void GxsCommentDialog::setGxsService(RsGxsCommentService *comment_service) { - ui->treeWidget->setup(token_service, comment_service); + ui->treeWidget->setup(comment_service); } GxsCommentDialog::GxsCommentDialog(QWidget *parent,const RsGxsId &default_author) @@ -95,8 +95,10 @@ void GxsCommentDialog::commentClear() } void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set& msg_versions,const RsGxsMessageId& most_recent_msgId,bool use_cache) { +#ifdef DEBUG_COMMENT_DIALOG std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")"; std::cerr << std::endl; +#endif mGrpId = grpId; mMostRecentMsgId = most_recent_msgId; diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.h b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h index 4be6edede..6a3eee16c 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.h @@ -33,10 +33,10 @@ class GxsCommentDialog: public QWidget public: GxsCommentDialog(QWidget *parent=nullptr,const RsGxsId& default_author=RsGxsId()); - GxsCommentDialog(QWidget *parent,const RsGxsId& default_author, RsTokenService *token_service, RsGxsCommentService *comment_service); + GxsCommentDialog(QWidget *parent, const RsGxsId& default_author, RsGxsCommentService *comment_service); virtual ~GxsCommentDialog(); - void setTokenService(RsTokenService *token_service, RsGxsCommentService *comment_service); + void setGxsService(RsGxsCommentService *comment_service); void setCommentHeader(QWidget *header); void commentLoad(const RsGxsGroupId &grpId, const std::set &msg_versions, const RsGxsMessageId &most_recent_msgId, bool use_cache=false); void commentClear(); diff --git a/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui index 734e490ca..7b50494d6 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsCommentDialog.ui @@ -97,7 +97,13 @@
    - + + + + 75 + true + + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">sort by</span></p></body></html> @@ -174,15 +180,20 @@
    + + GxsCommentTreeWidget + QTreeWidget +
    gui/gxs/GxsCommentTreeWidget.h
    +
    GxsIdChooser QComboBox
    gui/gxs/GxsIdChooser.h
    - GxsCommentTreeWidget - QTreeWidget -
    gui/gxs/GxsCommentTreeWidget.h
    + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index 343f88c91..517543b9a 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -25,12 +25,14 @@ #include "gui/common/RSTreeWidgetItem.h" #include "gui/gxs/GxsCreateCommentDialog.h" #include "gui/gxs/GxsIdTreeWidgetItem.h" +#include "util/qtthreadsutils.h" #include #include #include #include #include +#include #include #include #include @@ -247,7 +249,7 @@ void GxsCommentTreeWidget::mouseMoveEvent(QMouseEvent *e) } GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) - :QTreeWidget(parent), mTokenQueue(NULL), mRsTokenService(NULL), mCommentService(NULL) + :QTreeWidget(parent), mCommentService(NULL) { setVerticalScrollMode(ScrollPerPixel); setContextMenuPolicy(Qt::CustomContextMenu); @@ -297,9 +299,6 @@ void GxsCommentTreeWidget::updateContent() } GxsCommentTreeWidget::~GxsCommentTreeWidget() { - if (mTokenQueue) { - delete(mTokenQueue); - } } void GxsCommentTreeWidget::setCurrentCommentMsgId(QTreeWidgetItem *current, QTreeWidgetItem *previous) @@ -401,35 +400,23 @@ void GxsCommentTreeWidget::setVoteId(const RsGxsId &voterId) void GxsCommentTreeWidget::vote(const RsGxsGroupId &groupId, const RsGxsMessageId &threadId, const RsGxsMessageId &parentId, const RsGxsId &authorId, bool up) { - RsGxsVote vote; + RsThread::async([this,groupId,threadId,parentId,authorId,up]() + { + std::string error_string; + RsGxsMessageId vote_id; + RsGxsVoteType tvote = up?(RsGxsVoteType::UP):(RsGxsVoteType::DOWN); - vote.mMeta.mGroupId = groupId; - vote.mMeta.mThreadId = threadId; - vote.mMeta.mParentId = parentId; - vote.mMeta.mAuthorId = authorId; + bool res = mCommentService->voteForComment(groupId, threadId, parentId, authorId,tvote,vote_id, error_string); - if (up) - { - vote.mVoteType = GXS_VOTE_UP; - } - else - { - vote.mVoteType = GXS_VOTE_DOWN; - } + RsQThreadUtils::postToObject( [this,res,error_string]() + { -#ifdef DEBUG_GXSCOMMENT_TREEWIDGET - std::cerr << "GxsCommentTreeWidget::vote()"; - std::cerr << std::endl; - - std::cerr << "GroupId : " << vote.mMeta.mGroupId << std::endl; - std::cerr << "ThreadId : " << vote.mMeta.mThreadId << std::endl; - std::cerr << "ParentId : " << vote.mMeta.mParentId << std::endl; - std::cerr << "AuthorId : " << vote.mMeta.mAuthorId << std::endl; -#endif - - uint32_t token; - mCommentService->createNewVote(token, vote); - mTokenQueue->queueRequest(token, TOKENREQ_MSGINFO, RS_TOKREQ_ANSTYPE_ACK, COMMENT_VOTE_ACK); + if(res) + service_requestComments(mGroupId,mMsgVersions); + else + QMessageBox::critical(nullptr,tr("Cannot vote"),tr("Error while voting: ")+QString::fromStdString(error_string)); + }); + }); } @@ -477,19 +464,13 @@ void GxsCommentTreeWidget::replyToComment() void GxsCommentTreeWidget::copyComment() { QString txt = dynamic_cast(sender())->data().toString(); - - QMimeData *mimeData = new QMimeData(); - mimeData->setHtml(""+txt+""); - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setMimeData(mimeData, QClipboard::Clipboard); + QApplication::clipboard()->setText(txt) ; } -void GxsCommentTreeWidget::setup(RsTokenService *token_service, RsGxsCommentService *comment_service) +void GxsCommentTreeWidget::setup(RsGxsCommentService *comment_service) { - mRsTokenService = token_service; mCommentService = comment_service; - mTokenQueue = new TokenQueue(token_service, this); - connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint))); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customPopUpMenu(QPoint))); connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(setCurrentCommentMsgId(QTreeWidgetItem*, QTreeWidgetItem*))); return; @@ -529,25 +510,80 @@ void GxsCommentTreeWidget::service_requestComments(const RsGxsGroupId& group_id, std::cerr << "GxsCommentTreeWidget::service_requestComments for group " << group_id << std::endl; #endif - std::vector ids_to_ask; - - for(std::set::const_iterator it(msgIds.begin());it!=msgIds.end();++it) + RsThread::async([this,group_id,msgIds]() { -#ifdef DEBUG_GXSCOMMENT_TREEWIDGET - std::cerr << " asking for msg " << *it << std::endl; -#endif + std::vector comments; - ids_to_ask.push_back(std::make_pair(group_id,*it)); - } + if(!mCommentService->getRelatedComments(group_id,msgIds,comments)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to get comments" << std::endl; + return; + } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_RELATED_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD | RS_TOKREQOPT_MSG_LATEST; + RsQThreadUtils::postToObject( [this,comments]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete, note that + * Qt::QueuedConnection is important! + */ - uint32_t token; - mTokenQueue->requestMsgRelatedInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, ids_to_ask, GXSCOMMENTS_LOADTHREAD); + clearItems(); + + service_loadThread(comments); + + completeItems(); + + emit commentsLoaded(treeCount(this)); + + }, this ); + }); } +#ifdef TODO +void GxsCommentTreeWidget::async_msg_action(const CmtMethod &action) +{ + RsThread::async([this,action]() + { + // 1 - get message data from p3GxsForums + + std::set msgs_to_request ; + std::vector msgs; + + msgs_to_request.insert(mThreadId); + + if(!rsGxsForums->getForumContent(groupId(),msgs_to_request,msgs)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum message info for forum " << groupId() << " and thread " << mThreadId << std::endl; + return; + } + + if(msgs.size() != 1) + { + std::cerr << __PRETTY_FUNCTION__ << " more than 1 or no msgs selected in forum " << groupId() << std::endl; + return; + } + + // 2 - sort the messages into a proper hierarchy + + RsGxsForumMsg msg = msgs[0]; + + // 3 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [msg,action,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui + * thread, for example to update the data model with new information + * after a blocking call to RetroShare API complete */ + + (this->*action)(msg); + + }, this ); + + }); +} +#endif + /* Generic Handling */ void GxsCommentTreeWidget::clearItems() @@ -673,7 +709,7 @@ void GxsCommentTreeWidget::addItem(RsGxsMessageId itemId, RsGxsMessageId parentI } } -int treeCount(QTreeWidget *tree, QTreeWidgetItem *parent = 0) +int GxsCommentTreeWidget::treeCount(QTreeWidget *tree, QTreeWidgetItem *parent) { int count = 0; if (parent == 0) @@ -694,45 +730,11 @@ int treeCount(QTreeWidget *tree, QTreeWidgetItem *parent = 0) } return count; } -void GxsCommentTreeWidget::loadThread(const uint32_t &token) + +void GxsCommentTreeWidget::service_loadThread(const std::vector& comments) { - clearItems(); - - service_loadThread(token); - - completeItems(); - - emit commentsLoaded(treeCount(this)); -} - -void GxsCommentTreeWidget::acknowledgeComment(const uint32_t &token) -{ - RsGxsGrpMsgIdPair msgId; - mCommentService->acknowledgeComment(token, msgId); - - // simply reload data - service_requestComments(mGroupId,mMsgVersions); -} - - -void GxsCommentTreeWidget::acknowledgeVote(const uint32_t &token) -{ - RsGxsGrpMsgIdPair msgId; - if (mCommentService->acknowledgeVote(token, msgId)) - { - // reload data if vote was added. - service_requestComments(mGroupId,mMsgVersions); - } -} - - -void GxsCommentTreeWidget::service_loadThread(const uint32_t &token) -{ - std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; - std::cerr << std::endl; - - std::vector comments; - mCommentService->getRelatedComments(token, comments); + std::cerr << "GxsCommentTreeWidget::service_loadThread() ERROR must be overloaded!"; + std::cerr << std::endl; // This is inconsistent since we cannot know here that all comments are for the same thread. However they are only // requested in requestComments() where a single MsgId is used. @@ -821,10 +823,7 @@ void GxsCommentTreeWidget::insertComments(const std::vector& comme // now set all loaded comments as not new, since they have been loaded. for(auto cid:new_comments) - { - uint32_t token=0; - mCommentService->setCommentAsRead(token,mGroupId,cid); - } + mCommentService->setCommentReadStatus(RsGxsGrpMsgIdPair(mGroupId,cid),true); } QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMessageId& parent) @@ -852,50 +851,3 @@ QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMess return item; } - - -void GxsCommentTreeWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ -#ifdef DEBUG_GXSCOMMENT_TREEWIDGET - std::cerr << "GxsCommentTreeWidget::loadRequest() UserType: " << req.mUserType; - std::cerr << std::endl; -#endif - - if (queue != mTokenQueue) - { - std::cerr << "GxsCommentTreeWidget::loadRequest() Queue ERROR"; - std::cerr << std::endl; - return; - } - - /* now switch on req */ - switch(req.mType) - { - - case TOKENREQ_MSGINFO: - { - switch(req.mAnsType) - { - case RS_TOKREQ_ANSTYPE_ACK: - if (req.mUserType == COMMENT_VOTE_ACK) - { - acknowledgeVote(req.mToken); - } - else - { - acknowledgeComment(req.mToken); - } - break; - case RS_TOKREQ_ANSTYPE_DATA: - loadThread(req.mToken); - break; - } - } - break; - default: - std::cerr << "GxsCommentTreeWidget::loadRequest() UNKNOWN UserType "; - std::cerr << std::endl; - break; - - } -} diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index c4840eb46..43a6f55a5 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -24,26 +24,24 @@ #include #include -#include "util/TokenQueue.h" #include #include class RSTreeWidgetItemCompareRole; -class GxsCommentTreeWidget : public QTreeWidget, public TokenResponse +class GxsCommentTreeWidget : public QTreeWidget { Q_OBJECT public: GxsCommentTreeWidget(QWidget *parent = 0); ~GxsCommentTreeWidget(); - void setup(RsTokenService *token_service, RsGxsCommentService *comment_service); + void setup(RsGxsCommentService *comment_service); void requestComments(const RsGxsGroupId& group, const std::set &message_versions, const RsGxsMessageId &most_recent_message); void getCurrentMsgId(RsGxsMessageId& parentId); void applyRankings(std::map& positions); - void loadRequest(const TokenQueue *queue, const TokenRequest &req); void setVoteId(const RsGxsId &voterId); void setUseCache(bool b) { mUseCache = b ;} @@ -56,20 +54,17 @@ protected: /* to be overloaded */ virtual void service_requestComments(const RsGxsGroupId &group_id, const std::set &msgIds); - virtual void service_loadThread(const uint32_t &token); + virtual void service_loadThread(const std::vector& comments); virtual QTreeWidgetItem *service_createMissingItem(const RsGxsMessageId& parent); void clearItems(); void completeItems(); - void acknowledgeComment(const uint32_t& token); - void acknowledgeVote(const uint32_t &token); - - void loadThread(const uint32_t &token); - void insertComments(const std::vector& comments); void addItem(RsGxsMessageId itemId, RsGxsMessageId parentId, QTreeWidgetItem *item); + + static int treeCount(QTreeWidget *tree, QTreeWidgetItem *parent = 0); public slots: void customPopUpMenu(const QPoint& point); void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous); @@ -112,8 +107,6 @@ protected: RSTreeWidgetItemCompareRole *commentsRole; - TokenQueue *mTokenQueue; - RsTokenService *mRsTokenService; RsGxsCommentService *mCommentService; bool mUseCache; diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp index 3dacc3e6c..6585941c4 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.cpp @@ -51,8 +51,8 @@ void GxsCreateCommentDialog::loadComment(const QString &msgText, const QString & ui->avatarLabel->setGxsId(msgAuthorId); ui->avatarLabel->setFrameType(AvatarWidget::NO_FRAME); - ui->replaytolabel->setId(msgAuthorId); - ui->replaytolabel->setText( tr("Replying to") + " @" + msgAuthor); + ui->replyToLabel->setId(msgAuthorId); + ui->replyToLabel->setText( tr("Replying to") + " @" + msgAuthor); ui->commentTextEdit->setPlaceholderText( tr("Type your reply")); ui->postButton->setText("Reply"); @@ -99,7 +99,6 @@ void GxsCreateCommentDialog::createComment() return; } - uint32_t token; mCommentService->createComment(comment); close(); } @@ -116,11 +115,11 @@ void GxsCreateCommentDialog::checkLength(){ int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length(); if(charRemains >= 0) { text = tr("It remains %1 characters after HTML conversion.").arg(charRemains); - ui->infoLabel->setStyleSheet("QLabel#infoLabel { }"); + ui->info_Label->setStyleSheet("QLabel#info_Label { }"); }else{ text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); - ui->infoLabel->setStyleSheet("QLabel#infoLabel {color: red; font: bold; }"); + ui->info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }"); } ui->postButton->setEnabled(charRemains>=0); - ui->infoLabel->setText(text); + ui->info_Label->setText(text); } diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h index 1f38e2a98..4a21c6457 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.h @@ -25,7 +25,6 @@ #include #include "retroshare/rsgxscommon.h" -#include "util/TokenQueue.h" namespace Ui { class GxsCreateCommentDialog; diff --git a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui index 9a40b6f4a..aecd1b794 100644 --- a/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsCreateCommentDialog.ui @@ -7,13 +7,13 @@ 0 0 505 - 367 + 406 Make Comment - + 0 @@ -30,7 +30,7 @@ 0 - + 0 @@ -58,9 +58,9 @@ QFrame::Raised - + - + 52 @@ -73,16 +73,24 @@ 52 - + - + true + + + 11 + 75 + true + true + + <!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"> @@ -121,7 +129,7 @@ p, li { white-space: pre-wrap; } - + Qt::Vertical @@ -138,12 +146,12 @@ p, li { white-space: pre-wrap; } - + 6 - + Qt::Horizontal @@ -176,14 +184,14 @@ p, li { white-space: pre-wrap; } - + TextLabel - + @@ -208,21 +216,31 @@ p, li { white-space: pre-wrap; } + + + 12 + 75 + true + + Post - + 0 0 - - + + + 75 + true + @@ -240,6 +258,12 @@ p, li { white-space: pre-wrap; } QLabel
    gui/gxs/GxsIdLabel.h
    + + AvatarWidget + QWidget +
    gui/common/AvatarWidget.h
    + 1 +
    GxsIdChooser QComboBox @@ -250,12 +274,6 @@ p, li { white-space: pre-wrap; } QTextEdit
    gui/common/MimeTextEdit.h
    - - AvatarWidget - QLabel -
    gui/common/AvatarWidget.h
    - 1 -
    diff --git a/retroshare-gui/src/gui/gxs/GxsFeedItem.h b/retroshare-gui/src/gui/gxs/GxsFeedItem.h index c7c16ea79..bc75d1837 100644 --- a/retroshare-gui/src/gui/gxs/GxsFeedItem.h +++ b/retroshare-gui/src/gui/gxs/GxsFeedItem.h @@ -52,11 +52,6 @@ protected: //virtual bool isLoading(); //virtual void fillDisplay(RsGxsUpdateBroadcastBase *updateBroadcastBase, bool complete); -#ifdef TO_REMOVE - /* TokenResponse */ - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); -#endif - protected slots: void comments(const QString &title); void copyMessageLink(); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ff1919403..5afb5414b 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -92,7 +92,7 @@ GxsGroupDialog::~GxsGroupDialog() void GxsGroupDialog::init() { // connect up the buttons. - connect(ui.createButton, SIGNAL(clicked()), this, SLOT(submitGroup())); + connect(ui.postButton, SIGNAL(clicked()), this, SLOT(submitGroup())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancelDialog())); connect(ui.pubKeyShare_cb, SIGNAL(clicked()), this, SLOT(setShareList())); connect(ui.addAdmins_cb, SIGNAL(clicked()), this, SLOT(setAdminsList())); @@ -194,7 +194,7 @@ void GxsGroupDialog::setUiText(UiType uiType, const QString &text) //ui.contactsdockWidget->setWindowTitle(text); break; case UITYPE_BUTTONBOX_OK: - ui.createButton->setText(text); + ui.postButton->setText(text); break; } } @@ -210,7 +210,7 @@ void GxsGroupDialog::setUiToolTip(UiType uiType, const QString &text) ui.addAdmins_cb->setToolTip(text); break; case UITYPE_BUTTONBOX_OK: - ui.createButton->setToolTip(text); + ui.postButton->setToolTip(text); default: break; } @@ -232,14 +232,14 @@ void GxsGroupDialog::initMode() { ui.stackedWidget->setCurrentIndex(1); mReadonlyFlags = 0xffffffff; // Force all to readonly. - ui.createButton->hide(); + ui.postButton->hide(); } break; case MODE_EDIT: { ui.stackedWidget->setCurrentIndex(0); - ui.createButton->setText(tr("Submit Group Changes")); + ui.postButton->setText(tr("Submit Group Changes")); } break; } @@ -370,7 +370,7 @@ void GxsGroupDialog::setupVisibility() ui.groupLogo->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ICON); - ui.groupDesc->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); + ui.groupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DESCRIPTION); ui.distribGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); ui.distributionLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_DISTRIBUTION); @@ -384,8 +384,8 @@ void GxsGroupDialog::setupVisibility() ui.pubKeyShare_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_SHAREKEYS); ui.addAdmins_cb->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); - ui.label_8->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); ui.moderatorsLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); + ui.moderatorsValueLabel->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_ADDADMINS); ui.personalGroupBox->setVisible(mEnabledFlags & GXS_GROUP_FLAGS_PERSONALSIGN); @@ -410,11 +410,8 @@ void GxsGroupDialog::setupReadonly() { ui.publishGroupBox->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PUBLISHSIGN)); - ui.pubKeyShare_cb->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_SHAREKEYS)); - ui.personalGroupBox->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PERSONALSIGN)); - ui.idChooser->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_PERSONALSIGN)); //ui.distribGroupBox_2->setEnabled(!(mReadonlyFlags & GXS_GROUP_FLAGS_DISTRIBUTION)); @@ -465,12 +462,14 @@ void GxsGroupDialog::updateFromExistingMeta(const QString &description) ui.lastpostline->setText(tr("Never")); else ui.lastpostline->setText(DateTime::formatLongDateTime(mGrpMeta.mLastPost)); - ui.authorLabel->setId(mGrpMeta.mAuthorId); + ui.authorValueLabel->setId(mGrpMeta.mAuthorId); ui.createdline->setText(DateTime::formatLongDateTime(mGrpMeta.mPublishTs)); link = RetroShareLink::createMessage(mGrpMeta.mAuthorId, ""); - ui.authorLabel->setText(link.toHtml()); + + if(!mGrpMeta.mAuthorId.isNull()) + ui.authorValueLabel->setText(link.toHtml()); ui.IDline->setText(QString::fromStdString(mGrpMeta.mGroupId.toStdString())); ui.descriptiontextEdit->setPlainText(description); @@ -673,15 +672,9 @@ void GxsGroupDialog::createGroup() if (service_createGroup(meta)) { - // now update the UI #warning Missing code here! -#ifdef TODO - // - // get the Queue to handle response. What is this for? - if(mExternalTokenQueue != NULL) - mExternalTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID); -#endif - } + // now update the UI + } close(); } @@ -721,55 +714,57 @@ uint32_t GxsGroupDialog::getGroupSignFlags() void GxsGroupDialog::setGroupSignFlags(uint32_t signFlags) { - if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED) { - ui.publish_encrypt->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED) { - ui.publish_required->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) { - ui.publish_threads->setChecked(true); - } else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ) { - ui.publish_open->setChecked(true); - } + if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ENCRYPTED) + ui.publish_encrypt->setChecked(true); + else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_ALLSIGNED) + ui.publish_required->setChecked(true); + else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) + ui.publish_threads->setChecked(true); + else if (signFlags & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_NONEREQ) + ui.publish_open->setChecked(true); - if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) - ui.personal_required->setChecked(true); - - if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) - ui.personal_ifnopub->setChecked(true); - - if( (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) && (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) - ui.antiSpam_perms_CB->setCurrentIndex(2) ; - else if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) - ui.antiSpam_perms_CB->setCurrentIndex(1) ; - else - ui.antiSpam_perms_CB->setCurrentIndex(0) ; - - QString antispam_string ; - if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) antispam_string += tr("Message tracking") ; - if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature from known ID required") ; - else - if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature required") ; - - ui.antiSpamValueLabel->setText(antispam_string) ; - //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 & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && - (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) - { - // (cyril) very weird piece of code. Need to clear this up. - - ui.comments_allowed->setChecked(true); - ui.commentsValueLabel->setText("Allowed") ; - } - else - { - ui.comments_no->setChecked(true); - ui.commentsValueLabel->setText("Forbidden") ; - } + + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_REQUIRED) + ui.personal_required->setChecked(true); + + if (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN) + ui.personal_ifnopub->setChecked(true); + + if( (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) && (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG)) + ui.antiSpam_perms_CB->setCurrentIndex(2) ; + else if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) + ui.antiSpam_perms_CB->setCurrentIndex(1) ; + else + ui.antiSpam_perms_CB->setCurrentIndex(0) ; + + QString antispam_string ; + if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_TRACK_MESSAGES) antispam_string += tr("Message tracking") ; + if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature from known ID required") ; + else if(signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) antispam_string += (antispam_string.isNull()?"":" and ")+tr("PGP signature required") ; + + if(antispam_string.isNull()) + antispam_string = tr("[None]"); + + ui.antiSpamValueLabel->setText(antispam_string) ; + //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 & GXS_SERV::FLAG_GROUP_SIGN_PUBLISH_THREADHEAD) && + (signFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_IFNOPUBSIGN)) + { + // (cyril) very weird piece of code. Need to clear this up. + + ui.comments_allowed->setChecked(true); + ui.commentsValueLabel->setText("Allowed") ; + } + else + { + ui.comments_no->setChecked(true); + ui.commentsValueLabel->setText("Forbidden") ; + } } /**** Above logic is flawed, and will be removed shortly @@ -894,7 +889,7 @@ void GxsGroupDialog::setSelectedModerators(const std::set& ids) ui.adminsList->show(); ui.filtercomboBox->show(); - ui.adminsList->setSelectedIds(ids, false); + ui.adminsList->setSelectedIds(ids, true); QString moderatorsListString ; RsIdentityDetails det; @@ -915,8 +910,11 @@ void GxsGroupDialog::setSelectedModerators(const std::set& ids) moderatorsListString += link.toHtml() + " "; } - //ui.moderatorsLabel->setId(det.mId); - ui.moderatorsLabel->setText(moderatorsListString); + + if(moderatorsListString.isNull()) + moderatorsListString = tr("[None]"); + + ui.moderatorsValueLabel->setText(moderatorsListString); } /*********************************************************************************** diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index 4860f52a8..b5e9417d0 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -23,8 +23,6 @@ #include "ui_GxsGroupDialog.h" -#include "util/TokenQueue.h" - /******** * Notes: * @@ -284,9 +282,6 @@ private: std::list mShareList; QPixmap mPicture; - RsTokenService *mTokenService; - TokenQueue *mExternalTokenQueue; - TokenQueue *mInternalTokenQueue; RsGroupMetaData mGrpMeta; Mode mMode; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui index e6da1441e..867652e01 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.ui @@ -6,14 +6,14 @@ 0 0 - 701 - 529 + 746 + 533
    Create New - + 0 @@ -44,10 +44,10 @@ QFrame::Raised
    - 0 + 1 - + 0 @@ -59,7 +59,7 @@ - + 3 @@ -98,7 +98,7 @@
    - + 6 @@ -106,7 +106,7 @@ 6
    - + Name @@ -118,7 +118,7 @@
    - + Qt::Horizontal @@ -131,7 +131,7 @@ - + <html><head/><body><p>The identity here can be used to send feedback.</p></body></html> @@ -178,7 +178,7 @@ Description - + @@ -190,7 +190,7 @@ Publish Signatures - + 6 @@ -235,7 +235,7 @@ - + Qt::Horizontal @@ -255,7 +255,7 @@ Personal Signatures - + @@ -278,7 +278,7 @@ - + Qt::Horizontal @@ -298,7 +298,7 @@ Comments - + 6 @@ -329,7 +329,7 @@
    - + Qt::Horizontal @@ -349,16 +349,16 @@ Spam-protection - + - + Posts permissions: - + <html><head/><body><p>This combo box allows you to choose how posts are handled depending on the node the poster belongs to.</p><p><span style=" font-weight:600;">All allowed</span>: all posts are treated equally.</p><p><span style=" font-weight:600;">Defavor posts from unsigned IDs</span>: anonymous IDs will require a reputation of 0.4 to be received/forwarded.</p><p><span style=" font-weight:600;">Defavor posts from unsigned IDs and IDs from unknown nodes</span>: anonymous IDs and IDs signed by unknown Retroshare nodes will require a reputation of 0.4 to be received/forwarded.</p></body></html> @@ -380,7 +380,7 @@ - + Qt::Horizontal @@ -406,9 +406,9 @@
    - + - + @@ -426,7 +426,7 @@ Message Distribution - + 6 @@ -532,20 +532,7 @@ - - - Qt::Horizontal - - - - 0 - 17 - - - - - - + Qt::Horizontal @@ -563,205 +550,217 @@
    - + 0 - + Info - - - - - - - Author - - - - - - - Last Post - - - - - - - Name - - - - - - - Popularity - - - - - + + + 9 + + + 9 + + + 9 + + + 9 + + + + + Author: + + + + + + + Last Post + + + + + + + Name + + + + + + + Popularity + + + + + + + TextLabel + + + + + + + Anti Spam: + + + + + + + true + + + + + + + TextLabel + + + true + + + + + + + Comments: + + + + + + + GxsIdLabel + + + true + + + + + + + ID + + + + + + + true + + + + + + + Posts + + + + + + + + + + true + + + + + + + TextLabel - - - - Anti Spam: - - - - - - - true - - - - - - - TextLabel - - - true - - - - - - - Comments: - - - - - - - GxsIdLabel - - - true - - - - - - - ID - - - - - - - true - - - - - - - Posts - - - - - - - - - - true - - - - - - - - - TextLabel - - - - - - - - 0 - 0 - - - - - - - - - - Distribution: - - - - - - - true - - - - - - - true - - - - - - - Moderators: - - - - - - - TextLabel - - - true - - - - - - - - - - Created + + + + + 0 + 0 + + + + + Distribution: + + + + + + + true + + + + + + + true + + + + + + + Moderators: + + + + + + + TextLabel + + + true + + + + + + + true + + + + + + + Created + + + - + Description - + @@ -777,14 +776,14 @@ - + QFrame::StyledPanel QFrame::Raised - + @@ -793,7 +792,7 @@ - + Qt::Horizontal @@ -806,7 +805,14 @@ - + + + + 12 + 75 + true + + Create @@ -824,20 +830,14 @@
    gui/gxs/GxsIdLabel.h
    - GxsIdChooser + RSComboBox QComboBox -
    gui/gxs/GxsIdChooser.h
    +
    gui/common/RSComboBox.h
    - GxsCircleChooser - QComboBox -
    gui/gxs/GxsCircleChooser.h
    -
    - - HeaderFrame - QFrame -
    gui/common/HeaderFrame.h
    - 1 + ClickableLabel + QLabel +
    util/ClickableLabel.h
    FriendSelectionWidget @@ -845,20 +845,31 @@
    gui/common/FriendSelectionWidget.h
    1
    - - MimeTextEdit - QTextEdit -
    gui/common/MimeTextEdit.h
    -
    GroupChooser QComboBox
    gui/common/GroupChooser.h
    - ClickableLabel - QLabel -
    util/ClickableLabel.h
    + GxsCircleChooser + QComboBox +
    gui/gxs/GxsCircleChooser.h
    +
    + + GxsIdChooser + QComboBox +
    gui/gxs/GxsIdChooser.h
    +
    + + HeaderFrame + QFrame +
    gui/common/HeaderFrame.h
    + 1 +
    + + MimeTextEdit + QTextEdit +
    gui/common/MimeTextEdit.h
    diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp index fb530a3ef..b4fe2273f 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFeedItem.cpp @@ -31,7 +31,7 @@ * #define DEBUG_ITEM 1 **/ -GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool autoUpdate) : +GxsGroupFeedItem::GxsGroupFeedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, RsGxsIfaceHelper *iface, bool /*autoUpdate*/) : FeedItem(feedHolder,feedId,NULL) { #ifdef DEBUG_ITEM @@ -102,7 +102,7 @@ void GxsGroupFeedItem::copyGroupLink() } } -void GxsGroupFeedItem::fillDisplaySlot(bool complete) +void GxsGroupFeedItem::fillDisplaySlot(bool /*complete*/) { requestGroup(); } diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 963b3a8ad..9d8d66d61 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -42,13 +42,11 @@ /* Images for TreeWidget */ #define IMAGE_SUBSCRIBE ":/images/edit_add24.png" -#define IMAGE_UNSUBSCRIBE ":/images/cancel.png" +#define IMAGE_UNSUBSCRIBE ":/icons/cancel.svg" #define IMAGE_INFO ":/images/info16.png" -//#define IMAGE_GROUPAUTHD ":/images/konv_message2.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" #define IMAGE_EDIT ":/icons/png/pencil-edit-button.png" -#define IMAGE_SHARE ":/images/share-icon-16.png" -#define IMAGE_TABNEW ":/images/tab-new.png" +#define IMAGE_TABNEW ":/icons/newtab.svg" #define IMAGE_DELETE ":/images/delete.png" #define IMAGE_RETRIEVE ":/images/edit_add24.png" #define IMAGE_COMMENT "" @@ -72,8 +70,8 @@ static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120; // do not upd */ /** Constructor */ -GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *parent,bool allow_dist_sync) -: MainPage(parent) +GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl,const QString& settings_name, QWidget *parent,bool allow_dist_sync) +: MainPage(parent),mSettingsName(settings_name) { /* Invoke the Qt Designer generated object setup routine */ ui = new Ui::GxsGroupFrameDialog(); @@ -121,6 +119,9 @@ GxsGroupFrameDialog::GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *p sizes << 300 << width(); // Qt calculates the right sizes ui->splitter->setSizes(sizes); + // load settings + processSettings(true); + #ifndef UNFINISHED ui->todoPushButton->hide(); #endif @@ -168,7 +169,6 @@ void GxsGroupFrameDialog::initUi() } // load settings - mSettingsName = settingsGroupName(); processSettings(true); if (groupFrameSettingsType() != GroupFrameSettings::Nothing) { @@ -490,7 +490,7 @@ void GxsGroupFrameDialog::groupTreeCustomPopupMenu(QPoint point) ctxMenu2->setEnabled(isSubscribed); if (shareKeyType()) { - action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_SHARE), tr("Share publish permissions..."), this, SLOT(sharePublishKey())); + action = contextMnu.addAction(QIcon(""), tr("Share publish permissions..."), this, SLOT(sharePublishKey())); action->setEnabled(!mGroupId.isNull() && isPublisher); } @@ -726,7 +726,7 @@ void GxsGroupFrameDialog::loadComment(const RsGxsGroupId &grpId, const QVectorgetTokenService(), commentService); + commentDialog = new GxsCommentDialog(this,RsGxsId(), commentService); QWidget *commentHeader = createCommentHeaderWidget(grpId, most_recent_msgId); if (commentHeader) { @@ -1105,7 +1105,12 @@ void GxsGroupFrameDialog::updateGroupSummary() * Qt::QueuedConnection is important! */ - insertGroupsData(*groupInfo); + // Here we save the focus, and restore it afterwards: there's no need to grab the focus here and + // if we do, it may harm the navitation in forums, channels, boards, etc. + + auto w = QApplication::focusWidget(); + + insertGroupsData(*groupInfo); updateSearchResults(); mStateHelper->setLoading(TOKEN_TYPE_GROUP_SUMMARY, false); @@ -1132,7 +1137,12 @@ void GxsGroupFrameDialog::updateGroupSummary() delete groupInfo; - }, this ); + // Restore the focus. + + if(w) + w->setFocus(); + + }, this ); }); } @@ -1165,35 +1175,64 @@ void GxsGroupFrameDialog::updateGroupStatisticsReal(const RsGxsGroupId &groupId) * Qt::QueuedConnection is important! */ - QTreeWidgetItem *item = ui->groupTreeWidget->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString())); - if (!item) - return; + QTreeWidgetItem *item = ui->groupTreeWidget->getItemFromId(QString::fromStdString(stats.mGrpId.toStdString())); + + if (item) + ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread); - ui->groupTreeWidget->setUnreadCount(item, mCountChildMsgs ? (stats.mNumThreadMsgsUnread + stats.mNumChildMsgsUnread) : stats.mNumThreadMsgsUnread); mCachedGroupStats[groupId] = stats; getUserNotify()->updateIcon(); - }, this ); + }, this ); }); } void GxsGroupFrameDialog::getServiceStatistics(GxsServiceStatistic& stats) const { - stats = GxsServiceStatistic(); // clears everything + if(!mCachedGroupStats.empty()) + { + stats = GxsServiceStatistic(); // clears everything - for(auto& it: mCachedGroupStats) - { - const GxsGroupStatistic& s(it.second); + for(auto& it: mCachedGroupStats) + { + const GxsGroupStatistic& s(it.second); - stats.mNumMsgs += s.mNumMsgs; - stats.mNumGrps += 1; - stats.mSizeOfMsgs += s.mTotalSizeOfMsgs; - stats.mNumThreadMsgsNew += s.mNumThreadMsgsNew; - stats.mNumThreadMsgsUnread += s.mNumThreadMsgsUnread; - stats.mNumChildMsgsNew += s.mNumChildMsgsNew ; - stats.mNumChildMsgsUnread += s.mNumChildMsgsUnread ; - } + stats.mNumMsgs += s.mNumMsgs; + stats.mNumGrps += 1; + stats.mSizeOfMsgs += s.mTotalSizeOfMsgs; + stats.mNumThreadMsgsNew += s.mNumThreadMsgsNew; + stats.mNumThreadMsgsUnread += s.mNumThreadMsgsUnread; + stats.mNumChildMsgsNew += s.mNumChildMsgsNew ; + stats.mNumChildMsgsUnread += s.mNumChildMsgsUnread ; + } + + // Also save the service statistics in conf file, so that we can display it right away at start. + + Settings->beginGroup(mSettingsName); + Settings->setValue("NumMsgs", stats.mNumMsgs ); + Settings->setValue("NumGrps", stats.mNumGrps ); + Settings->setValue("SizeOfMessages", stats.mSizeOfMsgs ); + Settings->setValue("NumThreadMsgsNew", stats.mNumThreadMsgsNew ); + Settings->setValue("NumThreadMsgsUnread",stats.mNumThreadMsgsUnread); + Settings->setValue("NumChildMsgsNew", stats.mNumChildMsgsNew ); + Settings->setValue("NumChildMsgsUnread", stats.mNumChildMsgsUnread ); + Settings->endGroup(); + } + else // Get statistics from settings if no cache is already present: allows to display at start. + { + Settings->beginGroup(mSettingsName); + + stats.mNumMsgs = Settings->value("NumMsgs",QVariant(0)).toInt(); + stats.mNumGrps = Settings->value("NumGrps",QVariant(0)).toInt(); + stats.mSizeOfMsgs = Settings->value("SizeOfMessages",QVariant(0)).toInt(); + stats.mNumThreadMsgsNew = Settings->value("NumThreadMsgsNew",QVariant(0)).toInt(); + stats.mNumThreadMsgsUnread = Settings->value("NumThreadMsgsUnread",QVariant(0)).toInt(); + stats.mNumChildMsgsNew = Settings->value("NumChildMsgsNew",QVariant(0)).toInt(); + stats.mNumChildMsgsUnread = Settings->value("NumChildMsgsUnread",QVariant(0)).toInt(); + + Settings->endGroup(); + } } TurtleRequestId GxsGroupFrameDialog::distantSearch(const QString& search_string) // this should be overloaded in the child class diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h index 1cbd1fc8f..81bba553d 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.h @@ -71,7 +71,7 @@ public: }; public: - GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, QWidget *parent = 0,bool allow_dist_sync=false); + GxsGroupFrameDialog(RsGxsIfaceHelper *ifaceImpl, const QString& settings_name,QWidget *parent = 0,bool allow_dist_sync=false); virtual ~GxsGroupFrameDialog(); bool navigate(const RsGxsGroupId &groupId, const RsGxsMessageId& msgId); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui index 0a8fa4587..8cb249020 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.ui @@ -70,7 +70,14 @@
    - + + + + 12 + 75 + true + + Name @@ -168,11 +175,6 @@
    gui/common/RSTabWidget.h
    1 - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    GroupTreeWidget QWidget diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp index dfcafaaf2..9197e3665 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.cpp @@ -79,14 +79,14 @@ void GroupShareKey::setTyp() ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/channels.png")); ui->headerFrame->setHeaderText(tr("Share channel publish permissions")); - ui->sharekeyinfo_label->setText(tr("You can allow your friends to publish in your channel, or send the publish permissions to another Retroshare instance of yours. Select the friends which you want to be allowed to publish in this channel. Note: it is currently not possible to revoke channel publish permissions.")); + ui->info_Label_ShareKey->setText(tr("You can allow your friends to publish in your channel, or send the publish permissions to another Retroshare instance of yours. Select the friends which you want to be allowed to publish in this channel. Note: it is currently not possible to revoke channel publish permissions.")); } else if(mGrpType == FORUM_KEY_SHARE) { ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); ui->headerFrame->setHeaderText(tr("Share forum admin permissions")); - ui->sharekeyinfo_label->setText(tr("You can let your friends know about your forum by sharing it with them. Select the friends with which you want to share your forum.")); + ui->info_Label_ShareKey->setText(tr("You can let your friends know about your forum by sharing it with them. Select the friends with which you want to share your forum.")); } else if (mGrpType == POSTED_KEY_SHARE) @@ -96,7 +96,7 @@ void GroupShareKey::setTyp() ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/posted.png")); ui->headerFrame->setHeaderText(tr("Share board admin permissions")); - ui->sharekeyinfo_label->setText(tr("You can allow your friends to edit the board. Select them in the list below. Note: it is not possible to revoke Board admin permissions.")); + ui->info_Label_ShareKey->setText(tr("You can allow your friends to edit the board. Select them in the list below. Note: it is not possible to revoke Board admin permissions.")); } else diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h index ed8df360a..441d5e41d 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.h @@ -25,9 +25,6 @@ #include "ui_GxsGroupShareKey.h" -#define CHANNEL_KEY_SHARE 0x00000001 -#define FORUM_KEY_SHARE 0x00000002 -#define POSTED_KEY_SHARE 0x00000003 class GroupShareKey : public QDialog { @@ -40,6 +37,13 @@ public: GroupShareKey(QWidget *parent = 0, const RsGxsGroupId& grpId = RsGxsGroupId(), int grpType = 0); ~GroupShareKey(); + enum KeyShareType: uint8_t { + NO_KEY_SHARE = 0x00000000, + CHANNEL_KEY_SHARE = 0x00000001, + FORUM_KEY_SHARE = 0x00000002, + POSTED_KEY_SHARE = 0x00000003, + }; + protected: void changeEvent(QEvent *e); diff --git a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui index fb7db3b6e..b41aad127 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui +++ b/retroshare-gui/src/gui/gxs/GxsGroupShareKey.ui @@ -17,7 +17,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -78,7 +87,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -140,15 +158,12 @@
    - + 11 - - - QFrame::StyledPanel diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 9321c4de4..f40182563 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -19,18 +19,20 @@ *******************************************************************************/ #include "GxsIdChooser.h" + #include "GxsIdDetails.h" #include "RsGxsUpdateBroadcastBase.h" -#include "gui/Identity/IdEditDialog.h" #include "gui/common/FilesDefs.h" +#include "gui/Identity/IdEditDialog.h" #include "util/misc.h" +#include "util/qtthreadsutils.h" #include #include #include -#include +#include #include #define ROLE_SORT Qt::UserRole + 1 // Qt::UserRole is reserved for data @@ -50,7 +52,7 @@ /** Constructor */ GxsIdChooser::GxsIdChooser(QWidget *parent) - : QComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT) + : RSComboBox(parent), mFlags(IDCHOOSER_ANON_DEFAULT) { // mBase = new RsGxsUpdateBroadcastBase(rsIdentity, this); // connect(mBase, SIGNAL(fillDisplay(bool)), this, SLOT(fillDisplay(bool))); @@ -75,6 +77,24 @@ GxsIdChooser::GxsIdChooser(QWidget *parent) /* Connect signals */ connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(myCurrentIndexChanged(int))); connect(this, SIGNAL(activated(int)), this, SLOT(indexActivated(int))); + + // also capture identity creation/deletion events so as to update the UI accordingly + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { + RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }) ;}, mEventHandlerId, RsEventType::GXS_IDENTITY ); +} + +void GxsIdChooser::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::GXS_IDENTITY) return; + + const RsGxsIdentityEvent *fe = dynamic_cast(event.get()); + if(!fe) + return; + + updateDisplay(true); + update(); // Qt flush } void GxsIdChooser::setFlags(uint32_t flags) @@ -85,6 +105,7 @@ void GxsIdChooser::setFlags(uint32_t flags) GxsIdChooser::~GxsIdChooser() { + rsEvents->unregisterEventsHandler(mEventHandlerId); } void GxsIdChooser::fillDisplay(bool complete) diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h index 3cee770eb..61a610763 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.h +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h @@ -21,14 +21,15 @@ #ifndef _GXS_ID_CHOOSER_H #define _GXS_ID_CHOOSER_H -#include -#include +#include "retroshare/rsevents.h" +#include "gui/common/RSComboBox.h" + +#include "retroshare/rsgxsifacetypes.h" // This class implement a basic RS functionality which is that ComboBox displaying Id // should update regularly. They also should update only when visible, to save CPU time. // -struct RsGxsIfaceHelper; class RsGxsUpdateBroadcastBase; #define IDCHOOSER_ID_REQUIRED 0x0001 @@ -36,13 +37,12 @@ class RsGxsUpdateBroadcastBase; #define IDCHOOSER_NO_CREATE 0x0004 #define IDCHOOSER_NON_ANONYMOUS 0x0008 -class GxsIdChooser : public QComboBox +class GxsIdChooser : public RSComboBox { Q_OBJECT public: - GxsIdChooser(RsGxsIfaceHelper* ifaceImpl, QWidget *parent = NULL); - GxsIdChooser(QWidget *parent = NULL); + GxsIdChooser(QWidget *parent = nullptr); virtual ~GxsIdChooser(); void setFlags(uint32_t flags) ; @@ -79,6 +79,7 @@ private slots: private: void loadPrivateIds(); void setDefaultItem(); + void handleEvent_main_thread(std::shared_ptr event); uint32_t mFlags; RsGxsId mDefaultId; @@ -87,6 +88,8 @@ private: std::set mConstraintIdsSet ; // leave empty if all allowed // RsGxsUpdateBroadcastBase *mBase; + + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index a7d050dd5..b1961a6e6 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -61,6 +61,8 @@ #define MAX_ATTEMPTS 10 #define MAX_PROCESS_COUNT_PER_TIMER 50 +// #define DEBUG_GXSIDDETAILS 1 + //const int kRecognTagClass_DEVELOPMENT = 1; // //const int kRecognTagType_Dev_Ambassador = 1; @@ -405,6 +407,9 @@ const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id, AvatarSize size) // now look for the icon + if(id.isNull()) + std::cerr << "Weird: null ID" << std::endl; + QMutexLocker lock(&mIconCacheMutex); auto& it = mDefaultIconCache[id]; @@ -432,6 +437,31 @@ const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id, AvatarSize size) return image; } +void GxsIdDetails::debug_dumpImagesCache() +{ + QMutexLocker lock(&mIconCacheMutex); + + std::cerr << "Current icon cache:" << std::endl; + + for(const auto& it:mDefaultIconCache) // the & is important here, otherwise pairs are copied and isDetached() is always false! + { + std::cerr << " Identity " << it.first << ":" << std::endl; + + for(uint32_t i=0;i<4;++i) + { + std::cerr << " Size #" << i << ": " ; + + if(it.second[i].first>0) + { + int s = it.second[i].second.width()*it.second[i].second.height()*4; + std::cerr << " Present. Size=" << s << " bytes. Age: " << time(nullptr)-it.second[i].first << " secs. ago. Used: " << !it.second[i].second.isDetached() << std::endl; + } + else + std::cerr << " None." << std::endl; + } + } +} + void GxsIdDetails::checkCleanImagesCache() { time_t now = time(NULL); @@ -440,7 +470,9 @@ void GxsIdDetails::checkCleanImagesCache() if(mLastIconCacheCleaning + DELAY_BETWEEN_ICON_CACHE_CLEANING < now) { +#ifdef DEBUG_GXSIDDETAILS std::cerr << "(II) Cleaning the icons cache." << std::endl; +#endif int nb_deleted = 0; uint32_t size_deleted = 0; uint32_t total_size = 0; @@ -450,26 +482,43 @@ void GxsIdDetails::checkCleanImagesCache() for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();) { bool all_empty = true ; +#ifdef DEBUG_GXSIDDETAILS + std::cerr << " Examining pixmaps sizes for " << it->first << "." << std::endl; +#endif for(int i=0;i<4;++i) - if(it->second[i].first + ICON_CACHE_STORAGE_TIME < now && it->second[i].second.isDetached()) - { - int s = it->second[i].second.width()*it->second[i].second.height()*4; - - std::cerr << "Deleting pixmap " << it->first << " size " << i << " " << s << " bytes." << std::endl; - - it->second[i].second = QPixmap(); - ++nb_deleted; - size_deleted += s; - } - else + if(it->second[i].first>0) { - all_empty = false; - total_size += it->second[i].second.width()*it->second[i].second.height()*4; + if(it->second[i].first + ICON_CACHE_STORAGE_TIME < now && it->second[i].second.isDetached()) + { + int s = it->second[i].second.width()*it->second[i].second.height()*4; + +#ifdef DEBUG_GXSIDDETAILS + std::cerr << " Deleting pixmap " << it->first << " size " << i << " " << s << " bytes." << std::endl; +#endif + + it->second[i].second = QPixmap(); + it->second[i].first = 0; + ++nb_deleted; + size_deleted += s; + } + else + { + all_empty = false; + total_size += it->second[i].second.width()*it->second[i].second.height()*4; +#ifdef DEBUG_GXSIDDETAILS + std::cerr << " Keeking " << it->first << " size " << i << std::endl; +#endif + } } if(all_empty) - it = mDefaultIconCache.erase(it); + { +#ifdef DEBUG_GXSIDDETAILS + std::cerr << " Deleting entry " << it->first << " because no pixmaps are stored here. " << std::endl; +#endif + it = mDefaultIconCache.erase(it); + } else ++it; } @@ -490,10 +539,16 @@ bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len, Sha1CheckSum chksum = RsDirUtil::sha1sum(data,data_len); RsGxsId id(chksum.toByteArray()); + if(id.isNull()) + std::cerr << "Weird: null ID" << std::endl; + // We use a cache for images. QImage has its own smart pointer system, but it does not prevent // the same image to be allocated many times. We do this using a cache. The cache is also cleaned-up // on a regular time basis so as to get rid of unused images. +#ifdef DEBUG_GXSIDDETAILS + debug_dumpImagesCache(); +#endif checkCleanImagesCache(); // now look for the icon @@ -1018,11 +1073,13 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi QString GxsIdDetails::getName(const RsIdentityDetails &details) { - if( details.mReputation.mOverallReputationLevel == - RsReputationLevel::LOCALLY_NEGATIVE ) + if( details.mReputation.mOverallReputationLevel == RsReputationLevel::LOCALLY_NEGATIVE ) return tr("[Banned]"); - QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); + if( details.mId.isNull() ) + return tr("[Nobody]"); + + 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) @@ -1049,7 +1106,7 @@ QString nickname ; nickname = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; - comment = QString("%1:%2
    %3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"), + comment = QString("%1: %2
    %3: %4").arg(QApplication::translate("GxsIdDetails", "Identity name"), nickname, QApplication::translate("GxsIdDetails", "Identity Id"), QString::fromStdString(details.mId.toStdString())); diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 3c04c46eb..05568aa3a 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -113,7 +113,8 @@ public: static const QPixmap makeDefaultIcon(const RsGxsId& id, AvatarSize size = MEDIUM); static bool loadPixmapFromData(const unsigned char *data, size_t data_len, QPixmap& pix, AvatarSize size = MEDIUM); - static void checkCleanImagesCache(); + static void checkCleanImagesCache(); + static void debug_dumpImagesCache(); /* Processing */ static void enableProcess(bool enable); diff --git a/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp index 6cb741d14..62c15a699 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp @@ -60,7 +60,10 @@ void GxsIdLabel::setId(const RsGxsId &id) { mId = id; - GxsIdDetails::process(mId, fillLabelCallback, this); + if(id.isNull()) + setText(tr("[Nobody]")); + else + GxsIdDetails::process(mId, fillLabelCallback, this); } bool GxsIdLabel::getId(RsGxsId &id) diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index 0a8b9271b..053590e11 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -169,8 +169,11 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const QString embeddedImage; - if ( RsHtml::makeEmbeddedImage( pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation ).toImage(), embeddedImage, 8*S * 8*S ) ) + if ( RsHtml::makeEmbeddedImage( pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation ).toImage(), embeddedImage, -1 ) ) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); t = "
    " + embeddedImage + "" + t + "
    "; + } return t; } @@ -190,17 +193,25 @@ void GxsIdTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem QStyleOptionViewItem ownOption (option); initStyleOption(&ownOption, index); - RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); - QString cmt; + QString dt = index.data(Qt::UserRole).toString(); + RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); - if(id.isNull()) + // This is a trick: UserRole in Mail generally is 0000...00000 when there is a notification, and is empty when there are multiple + // destinations at once. This is not so nice to do that this way, but it's a quick workaround to a more complex method involving an + // additional Qt role only to determine the number of destinations. + + if(dt == "") + ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/svg/people2.svg"); + else if(id.isNull()) + { + if (ownOption.icon.isNull()) + ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/notification.svg"); + } + else { - if (ownOption.icon.isNull()) - ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/notification.png"); - } - else - { - if(! computeNameIconAndComment(id,ownOption.text,ownOption.icon,cmt)) + QString cmt; + + if(! computeNameIconAndComment(id,ownOption.text,ownOption.icon,cmt)) { if(mReloadPeriod > 3) { diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h index 15bdfeb87..1f38ecf04 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h @@ -109,7 +109,9 @@ public: QList icons; QString comment; - if(rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages) + if(id.isNull()) + name = QObject::tr("[System]"); + else if(RsPeerId(id)==rsPeers->getOwnId() || rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages) name = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(id)).c_str()) ; else if(!GxsIdDetails::MakeIdDesc(id, false, name, icons, comment,GxsIdDetails::ICON_TYPE_NONE)) return false; @@ -123,8 +125,13 @@ public: bool exist = false; - if(rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages) - { + if(id.isNull()) + { + name = QObject::tr("[System]"); + icon = QIcon(); + } + else if(RsPeerId(id)==rsPeers->getOwnId() || rsPeers->isFriend(RsPeerId(id))) // horrible trick because some widgets still use locations as IDs (e.g. messages) + { name = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(id)).c_str()) ; icon = FilesDefs::getIconFromQtResourcePath(":/icons/avatar_128.png"); } diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp b/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp index 1eb52356a..0f7c6dc0b 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsMessageFramePostWidget.cpp @@ -371,7 +371,7 @@ void GxsMessageFramePostWidget::loadPosts(const std::set& msgIds /**************************************************************/ GxsMessageFramePostThread::GxsMessageFramePostThread(const std::vector& posts,GxsMessageFramePostWidget *parent) - : mPosts(posts),QThread(parent), mParent(parent) + : QThread(parent), mPosts(posts), mParent(parent) { mStopped = false; } diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.cpp b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.cpp index 8d9a89a47..1f55f514f 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.cpp @@ -28,7 +28,6 @@ GxsMessageFrameWidget::GxsMessageFrameWidget(RsGxsIfaceHelper *ifaceImpl, QWidge { mNextTokenType = 0; - mTokenQueue = new TokenQueue(ifaceImpl->getTokenService(), this); mStateHelper = new UIStateHelper(this); /* Set read status */ @@ -46,8 +45,6 @@ GxsMessageFrameWidget::~GxsMessageFrameWidget() emit waitingChanged(this); } - - delete(mTokenQueue); } const RsGxsGroupId &GxsMessageFrameWidget::groupId() @@ -95,34 +92,6 @@ void GxsMessageFrameWidget::setGroupId(const RsGxsGroupId &groupId) void GxsMessageFrameWidget::setAllMessagesRead(bool read) { - uint32_t token = 0; - setAllMessagesReadDo(read, token); - - if (token) { - /* Wait for acknowlegde of the token */ - mAcknowledgeReadStatusToken = token; - mTokenQueue->queueRequest(mAcknowledgeReadStatusToken, 0, 0, mTokenTypeAcknowledgeReadStatus); - mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, true); - - emit waitingChanged(this); - } + setAllMessagesReadDo(read); } -void GxsMessageFrameWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - if (queue == mTokenQueue) - { - if (req.mUserType == mTokenTypeAcknowledgeReadStatus) { - if (mAcknowledgeReadStatusToken == req.mToken) { - /* Set read status is finished */ - mStateHelper->setLoading(mTokenTypeAcknowledgeReadStatus, false); - - emit waitingChanged(this); - } - return; - } - } - - std::cerr << "GxsMessageFrameWidget::loadRequest() ERROR: INVALID TYPE"; - std::cerr << std::endl; -} diff --git a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h index 36c2f4f67..758088595 100644 --- a/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsMessageFrameWidget.h @@ -22,12 +22,11 @@ #define GXSMESSAGEFRAMEWIDGET_H #include "gui/gxs/RsGxsUpdateBroadcastWidget.h" -#include "util/TokenQueue.h" struct RsGxsIfaceHelper; class UIStateHelper; -class GxsMessageFrameWidget : public QWidget, public TokenResponse +class GxsMessageFrameWidget : public QWidget { Q_OBJECT @@ -49,7 +48,6 @@ public: /* GXS functions */ uint32_t nextTokenType() { return ++mNextTokenType; } - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); signals: void groupChanged(QWidget *widget); @@ -58,10 +56,9 @@ signals: void groupDataLoaded(); protected: - virtual void setAllMessagesReadDo(bool read, uint32_t &token) = 0; + virtual void setAllMessagesReadDo(bool read) = 0; protected: - TokenQueue *mTokenQueue; UIStateHelper *mStateHelper; /* Set read status */ diff --git a/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp b/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp index bc1afa1c1..1784a6f8c 100644 --- a/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp +++ b/retroshare-gui/src/gui/gxs/GxsUserNotify.cpp @@ -26,7 +26,7 @@ #define TOKEN_TYPE_STATISTICS 1 -GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g,QObject *parent) : UserNotify(parent), mGroupFrameDialog(g) +GxsUserNotify::GxsUserNotify(RsGxsIfaceHelper */*ifaceImpl*/, const GxsGroupFrameDialog *g,QObject *parent) : UserNotify(parent), mGroupFrameDialog(g) { mNewThreadMessageCount = 0; mNewChildMessageCount = 0; diff --git a/retroshare-gui/src/gui/gxs/GxsUserNotify.h b/retroshare-gui/src/gui/gxs/GxsUserNotify.h index f9c5cd616..66890a1c3 100644 --- a/retroshare-gui/src/gui/gxs/GxsUserNotify.h +++ b/retroshare-gui/src/gui/gxs/GxsUserNotify.h @@ -24,9 +24,8 @@ #include #include "gui/common/UserNotify.h" #include "gui/gxs/GxsGroupFrameDialog.h" -#include "util/TokenQueue.h" -struct RsGxsIfaceHelper; +class RsGxsIfaceHelper; class RsGxsUpdateBroadcastBase; class GxsUserNotify : public UserNotify @@ -47,7 +46,6 @@ protected: bool mCountChildMsgs; // Count new child messages? private: - RsGxsUpdateBroadcastBase *mBase; const GxsGroupFrameDialog *mGroupFrameDialog; unsigned int mNewThreadMessageCount; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp index 3d51f0acb..05ce9bda6 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp @@ -74,7 +74,7 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); connect(removeAllFilesButton, SIGNAL(clicked() ), this , SLOT(clearAllAttachments())); //connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); - connect(subjectEdit,SIGNAL(textChanged(const QString&)),this,SLOT(updatePreviewText(const QString&))); + connect(subjectEdit,SIGNAL(textChanged(QString)),this,SLOT(updatePreviewText(QString))); connect(expandButton, SIGNAL(clicked()), this, SLOT( toggle())); connect(addThumbnailButton, SIGNAL(clicked() ), this , SLOT(addThumbnail())); @@ -183,8 +183,8 @@ void CreateGxsChannelMsg::contextMenu(QPoint /*point*/) int n_file = 0 ; - for(QList::const_iterator it(links.begin());it!=links.end();++it) - if((*it).type() == RetroShareLink::TYPE_FILE) + for(auto &it : links) + if(it.type() == RetroShareLink::TYPE_FILE) ++n_file ; QMenu contextMnu(this) ; @@ -203,42 +203,42 @@ void CreateGxsChannelMsg::pasteLink() { std::cerr << "Pasting links: " << std::endl; - QList links; + QList links; RSLinkClipboard::pasteLinks(links) ; - for(QList::const_iterator it(links.begin());it!=links.end();++it) - if((*it).type() == RetroShareLink::TYPE_FILE) + for(auto &it : links) + if(it.type() == RetroShareLink::TYPE_FILE) { // 0 - check that we actually have the file! // - std::cerr << "Pasting " << (*it).toString().toStdString() << std::endl; + std::cerr << "Pasting " << it.toString().toStdString() << std::endl; - FileInfo info ; - RsFileHash hash( (*it).hash().toStdString()) ; + FileInfo info ; + RsFileHash hash( it.hash().toStdString()) ; #ifdef TO_REMOVE - if(rsFiles->alreadyHaveFile( hash,info ) ) + if(rsFiles->alreadyHaveFile( hash,info ) ) #endif - addAttachment(hash, (*it).name().toUtf8().constData(), (*it).size(), rsFiles->alreadyHaveFile( hash,info ), RsPeerId()) ; + addAttachment(hash, it.name().toUtf8().constData(), it.size(), rsFiles->alreadyHaveFile( hash,info ), RsPeerId()) ; #ifdef TO_REMOVE - else - not_have.push_back( *it ) ; + else + not_have.push_back( *it ) ; #endif - } + } #ifdef TO_REMOVE - if(!not_have.empty()) - { - QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"

    " ; + if(!not_have.empty()) + { + QString msg = tr("You are about to add files you're not actually sharing. Do you still want this to happen?")+"

    " ; - for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) - msg += (*it).toString() + "
    " ; + for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) + msg += (*it).toString() + "
    " ; - if(QMessageBox::YesToAll == QMessageBox::question(NULL,tr("About to post un-owned files to a channel."),msg,QMessageBox::YesToAll | QMessageBox::No)) - for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) - addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ; - } + if(QMessageBox::YesToAll == QMessageBox::question(NULL,tr("About to post un-owned files to a channel."),msg,QMessageBox::YesToAll | QMessageBox::No)) + for(QList::const_iterator it(not_have.begin());it!=not_have.end();++it) + addAttachment(RsFileHash((*it).hash().toStdString()), (*it).name().toUtf8().constData(), (*it).size(), false, RsPeerId()) ; + } #endif } @@ -611,7 +611,7 @@ bool CreateGxsChannelMsg::setThumbNail(const std::string& path, int frame){ QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); - tNail.save(&buffer, "PNG"); + tNail.save(&buffer, "JPG"); QPixmap img; img.loadFromData(ba, "PNG"); img = img.scaled(thumbnail_label->width(), thumbnail_label->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); @@ -794,54 +794,25 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str /* rsGxsChannels */ if (rsGxsChannels) { - RsGxsChannelPost post; - - post.mMeta.mGroupId = mChannelId; - post.mMeta.mParentId.clear() ; - post.mMeta.mThreadId.clear() ; - post.mMeta.mMsgId.clear() ; - - post.mMeta.mOrigMsgId = mOrigPostId; - post.mMeta.mMsgName = subject; - post.mMsg = msg; - post.mFiles = files; - QByteArray ba; QBuffer buffer(&ba); + RsGxsImage image; + if(!picture.isNull()) { // send chan image buffer.open(QIODevice::WriteOnly); - preview_W->getCroppedScaledPicture().save(&buffer, "PNG"); // writes image into ba in PNG format - post.mThumbnail.copy((uint8_t *) ba.data(), ba.size()); + preview_W->getCroppedScaledPicture().save(&buffer, "JPG"); // writes image into ba in PNG format + image.copy((uint8_t *) ba.data(), ba.size()); } - int generateCount = 0; + std::string error_string; + RsGxsMessageId post_id; -#ifdef ENABLE_GENERATE - if (generateCheckBox->isChecked()) { - generateCount = generateSpinBox->value(); - if (QMessageBox::question(this, tr("Generate mass data"), tr("Do you really want to generate %1 messages ?").arg(generateCount), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { - return; - } - } -#endif - - uint32_t token; - if (generateCount) { -#ifdef ENABLE_GENERATE - for (int count = 0; count < generateCount; ++count) { - RsGxsChannelPost generatePost = post; - generatePost.mMeta.mMsgName = QString("%1 %2").arg(QString::fromUtf8(post.mMeta.mMsgName.c_str())).arg(count + 1, 3, 10, QChar('0')).toUtf8().constData(); - - rsGxsChannels->createPost(token, generatePost); - } -#endif - } else { - rsGxsChannels->createPost(token, post); - } + if(!rsGxsChannels->createPostV2(mChannelId,subject,msg,files,image,mOrigPostId,post_id,error_string)) + QMessageBox::critical(nullptr,tr("Cannot publish post"),QString::fromStdString(error_string)); } accept(); @@ -966,14 +937,14 @@ void CreateGxsChannelMsg::toggle() if (expandButton->isChecked()) { thumbnailFrame->hide(); - gridLayoutTextEdit->setContentsMargins(0,9,0,0); + subject_HL->setContentsMargins(0,9,0,0); expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/down-arrow.png"))); expandButton->setToolTip(tr("Show")); } else { thumbnailFrame->show(); - gridLayoutTextEdit->setContentsMargins(0,0,0,0); + subject_HL->setContentsMargins(0,0,0,0); expandButton->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/up-arrow.png"))); expandButton->setToolTip(tr("Hide")); } diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui index b29e9cdd8..510da23a1 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui @@ -20,7 +20,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png - + 0 @@ -40,14 +40,14 @@ 0 - + QFrame::StyledPanel QFrame::Raised - + 3 @@ -77,7 +77,7 @@ - + 9 @@ -99,7 +99,7 @@
    - + Qt::Horizontal @@ -113,6 +113,13 @@ + + + 12 + 75 + true + + Post @@ -141,8 +148,8 @@ 0 - - + + 0 @@ -163,7 +170,7 @@ QFrame::Plain - + 6 @@ -193,7 +200,7 @@ p, li { white-space: pre-wrap; } - + @@ -208,7 +215,7 @@ p, li { white-space: pre-wrap; } - + <html><head/><body><p>Choose aspect ratio policy. In 'Auto' mode, the most suitable aspect ratio is chosen for you.</p></body></html> @@ -254,7 +261,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -272,7 +279,7 @@ p, li { white-space: pre-wrap; } - + 9 @@ -317,7 +324,7 @@ p, li { white-space: pre-wrap; } - + 6 @@ -332,7 +339,7 @@ p, li { white-space: pre-wrap; }
    - + Qt::Vertical @@ -350,7 +357,7 @@ p, li { white-space: pre-wrap; }
    - + 6 @@ -388,10 +395,10 @@ p, li { white-space: pre-wrap; }
    - + - + @@ -481,7 +488,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -518,7 +525,7 @@ p, li { white-space: pre-wrap; } 0 - + 3 @@ -548,7 +555,7 @@ p, li { white-space: pre-wrap; } Drag and Drop Files from Search Results - +
    @@ -579,7 +586,7 @@ p, li { white-space: pre-wrap; }
    - + Qt::Horizontal @@ -604,6 +611,12 @@ p, li { white-space: pre-wrap; }
    + + ChannelPostThumbnailView + QWidget +
    gui/gxschannels/GxsChannelPostThumbnail.h
    + 1 +
    HeaderFrame QFrame @@ -617,10 +630,9 @@ p, li { white-space: pre-wrap; } 1 - ChannelPostThumbnailView - QWidget -
    gui/gxschannels/GxsChannelPostThumbnail.h
    - 1 + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 5d08ea707..47317c801 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -35,6 +35,7 @@ #include "gui/notifyqt.h" #include "gui/common/GroupTreeWidget.h" #include "util/qtthreadsutils.h" +#include "util/misc.h" // class GxsChannelGroupInfoData : public RsUserdata // { @@ -48,7 +49,7 @@ /** Constructor */ GxsChannelDialog::GxsChannelDialog(QWidget *parent): - GxsGroupFrameDialog(rsGxsChannels, parent, true), mEventHandlerId(0) + GxsGroupFrameDialog(rsGxsChannels, settingsGroupName(),parent, true), mEventHandlerId(0) { // Needs to be asynced because this function is called by another thread! rsEvents->registerEventsHandler( @@ -66,6 +67,7 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev { case RsChannelEventCode::STATISTICS_CHANGED: // [[fallthrough]]; updateDisplay(true); // no breaks, on purpose! + Q_FALLTHROUGH(); case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]]; case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]]; @@ -89,8 +91,8 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev const RsGxsChannelSearchResultEvent*f = dynamic_cast(event.get()); - if(nullptr != f) - for(auto it:f->mSearchResultsMap) + if(nullptr != f) + for(auto &it:f->mSearchResultsMap) updateSearchResults(it.first); } @@ -101,18 +103,23 @@ GxsChannelDialog::~GxsChannelDialog() QString GxsChannelDialog::getHelpString() const { - QString hlp_str = tr("

      Channels

    \ -

    Channels allow you to post data (e.g. movies, music) that will spread in the network

    \ -

    You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to \ - your friends. This promotes good channels in the network.

    \ -

    Only the channel's creator can post on that channel. Other peers \ - in the network can only read from it, unless the channel is private. You can however share \ - the posting rights or the reading rights with friend Retroshare nodes.

    \ -

    Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed.\ - Enable \"Allow Comments\" if you want to let users comment on your posts.

    \ -

    Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.

    \ -

    UI Tip: use Control + mouse wheel to control image size in the thumbnail view.

    \ - ").arg(QString::number(rsGxsChannels->getDefaultStoragePeriod()/86400)).arg(QString::number(rsGxsChannels->getDefaultSyncPeriod()/86400)); + int H = misc::getFontSizeFactor("HelpButton").height(); + + QString hlp_str = tr( + "

      Channels

    " + "

    Channels allow you to post data (e.g. movies, music) that will spread in the network

    " + "

    You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to" + " your friends. This promotes good channels in the network.

    " + "

    Only the channel's creator can post on that channel. Other peers" + " in the network can only read from it, unless the channel is private. You can however share" + " the posting rights or the reading rights with friend Retroshare nodes.

    " + "

    Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed." + " Enable \"Allow Comments\" if you want to let users comment on your posts.

    " + "

    Channel posts are kept for %2 days, and sync-ed over the last %3 days, unless you change this.

    " + "

    UI Tip: use Control + mouse wheel to control image size in the thumbnail view.

    " + ).arg( QString::number(2*H) + , QString::number(rsGxsChannels->getDefaultStoragePeriod()/86400) + , QString::number(rsGxsChannels->getDefaultSyncPeriod()/86400)); return hlp_str ; } @@ -207,7 +214,7 @@ GxsGroupDialog *GxsChannelDialog::createGroupDialog(GxsGroupDialog::Mode mode, R int GxsChannelDialog::shareKeyType() { - return CHANNEL_KEY_SHARE; + return GroupShareKey::CHANNEL_KEY_SHARE; } GxsMessageFrameWidget *GxsChannelDialog::createMessageFrameWidget(const RsGxsGroupId &groupId) @@ -259,11 +266,13 @@ void GxsChannelDialog::groupTreeCustomActions(RsGxsGroupId grpId, int subscribeF if (isSubscribed) { - QAction *action = autoDownload ? (new QAction(FilesDefs::getIconFromQtResourcePath(":/images/redled.png"), tr("Disable Auto-Download"), this)) - : (new QAction(FilesDefs::getIconFromQtResourcePath(":/images/start.png"),tr("Enable Auto-Download"), this)); + { + QAction *action = autoDownload ? (new QAction(FilesDefs::getIconFromQtResourcePath(":/images/redled.png"), tr("Disable Auto-Download"), this)) + : (new QAction(FilesDefs::getIconFromQtResourcePath(":/images/start.png"),tr("Enable Auto-Download"), this)); - connect(action, SIGNAL(triggered()), this, SLOT(toggleAutoDownload())); - actions.append(action); + connect(action, SIGNAL(triggered()), this, SLOT(toggleAutoDownload())); + actions.append(action); + } std::string dl_directory; rsGxsChannels->getChannelDownloadDirectory(grpId,dl_directory) ; @@ -281,20 +290,20 @@ void GxsChannelDialog::groupTreeCustomActions(RsGxsGroupId grpId, int subscribeF for(std::list::const_iterator it(lst.begin());it!=lst.end();++it) { - QAction *action = NULL; + QAction *fileAction = NULL; if(dl_directory == it->filename) { - action = new QAction(FilesDefs::getIconFromQtResourcePath(":/images/start.png"),QString::fromUtf8(it->filename.c_str()),NULL) ; + fileAction = new QAction(FilesDefs::getIconFromQtResourcePath(":/images/start.png"),QString::fromUtf8(it->filename.c_str()),NULL) ; found = true ; } else - action = new QAction(QString::fromUtf8(it->filename.c_str()),NULL) ; + fileAction = new QAction(QString::fromUtf8(it->filename.c_str()),NULL) ; - connect(action,SIGNAL(triggered()),this,SLOT(setDownloadDirectory())) ; - action->setData(QString::fromUtf8(it->filename.c_str())) ; + connect(fileAction,SIGNAL(triggered()),this,SLOT(setDownloadDirectory())) ; + fileAction->setData(QString::fromUtf8(it->filename.c_str())) ; - mnu->addAction(action) ; + mnu->addAction(fileAction) ; } if(!found && !dl_directory.empty()) @@ -360,24 +369,42 @@ void GxsChannelDialog::toggleAutoDownload() bool GxsChannelDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) { - return rsGxsChannels->getChannelStatistics(groupId,stat); + // What follows is a hack to replace the GXS group statistics by the actual count of unread messages in channels, + // which should take into account old post versions, discard comments and votes, etc. + + RsGxsChannelStatistics s; + bool res = rsGxsChannels->getChannelStatistics(groupId,s); + + if(!res) + return false; + + stat.mGrpId = groupId; + stat.mNumMsgs = s.mNumberOfPosts; + + stat.mTotalSizeOfMsgs = 0; // hopefuly unused. Required the loading of the full channel data, so not very convenient. + stat.mNumThreadMsgsNew = s.mNumberOfNewPosts; + stat.mNumThreadMsgsUnread = s.mNumberOfUnreadPosts; + stat.mNumChildMsgsNew = 0; + stat.mNumChildMsgsUnread = 0; + + return true; } bool GxsChannelDialog::getGroupData(std::list& groupInfo) { std::vector groups; - // request all group infos at once + // request all group infos at once - if(! rsGxsChannels->getChannelsInfo(std::list(),groups)) - return false; + if(! rsGxsChannels->getChannelsInfo(std::list(),groups)) + return false; - /* Save groups to fill icons and description */ + /* Save groups to fill icons and description */ for (auto& group: groups) - groupInfo.push_back(new RsGxsChannelGroup(group)); + groupInfo.push_back(new RsGxsChannelGroup(group)); - return true; + return true; } void GxsChannelDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *groupData, GroupItemInfo &groupItemInfo) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp index 365dab3f3..23f5f5b93 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.cpp @@ -33,8 +33,8 @@ #include "retroshare/rsfiles.h" -GxsChannelFilesStatusWidget::GxsChannelFilesStatusWidget(const RsGxsFile &file, QWidget *parent) : - QWidget(parent), mFile(file), ui(new Ui::GxsChannelFilesStatusWidget) +GxsChannelFilesStatusWidget::GxsChannelFilesStatusWidget(const RsGxsFile &file, QWidget *parent,bool used_as_editor) : + QWidget(parent), mFile(file), mUsedAsEditor(used_as_editor),ui(new Ui::GxsChannelFilesStatusWidget) { ui->setupUi(this); @@ -46,19 +46,16 @@ GxsChannelFilesStatusWidget::GxsChannelFilesStatusWidget(const RsGxsFile &file, connect(ui->downloadPushButton, SIGNAL(clicked()), this, SLOT(download())); connect(ui->resumeToolButton, SIGNAL(clicked()), this, SLOT(resume())); connect(ui->pauseToolButton, SIGNAL(clicked()), this, SLOT(pause())); - connect(ui->cancelToolButton, SIGNAL(clicked()), this, SLOT(cancel())); + connect(ui->cancelToolButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(ui->openFilePushButton, SIGNAL(clicked()), this, SLOT(openFile())); ui->downloadPushButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/download.png")); - ui->openFolderToolButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/arrow.png")); - QAction *openfolder = new QAction(tr("Open folder"), this); - connect(openfolder, SIGNAL(triggered()), this, SLOT(openFolder())); + ui->openFolderPushButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/folderopen.png")); + ui->openFolderPushButton->setToolTip(tr("Open folder")); + + connect(ui->openFolderPushButton, SIGNAL(clicked()), this, SLOT(openFolder())); - QMenu *menu = new QMenu(); - menu->addAction(openfolder); - ui->openFolderToolButton->setMenu(menu); - check(); } @@ -90,7 +87,9 @@ void GxsChannelFilesStatusWidget::setSize(uint64_t size) void GxsChannelFilesStatusWidget::check() { FileInfo fileInfo; - if (rsFiles->alreadyHaveFile(mFile.mHash, fileInfo)) { + + if(haveFile(fileInfo)) + { mState = STATE_LOCAL; setSize(fileInfo.size); @@ -103,27 +102,25 @@ void GxsChannelFilesStatusWidget::check() ui->openFilePushButton->setText(tr("Play")); ui->openFilePushButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/icons/png/play.png")); } - - } else { - FileInfo fileInfo; - bool detailsOk = rsFiles->FileDetails(mFile.mHash, RS_FILE_HINTS_DOWNLOAD | RS_FILE_HINTS_SPEC_ONLY, fileInfo); - - if (detailsOk) { - switch (fileInfo.downloadStatus) { + } + else + { + switch (fileInfo.downloadStatus) + { case FT_STATE_WAITING: mState = STATE_WAITING; break; case FT_STATE_DOWNLOADING: - if (fileInfo.avail == fileInfo.size) { + if (fileInfo.avail == fileInfo.size) mState = STATE_LOCAL; - } else { + else mState = STATE_DOWNLOAD; - } + setSize(fileInfo.size); ui->progressBar->setValue(fileInfo.avail / mDivisor); break; - case FT_STATE_COMPLETE: - mState = STATE_DOWNLOAD; + case FT_STATE_COMPLETE: // this should not happen, since the case is handled earlier + mState = STATE_ERROR; break; case FT_STATE_QUEUED: mState = STATE_WAITING; @@ -134,14 +131,11 @@ void GxsChannelFilesStatusWidget::check() case FT_STATE_CHECKING_HASH: mState = STATE_CHECKING; break; - case FT_STATE_FAILED: - mState = STATE_ERROR; - break; - } - } else { - mState = STATE_REMOTE; - } - } + default: + mState = STATE_REMOTE; + break; + } + } int repeat = 0; QString statusText; @@ -156,7 +150,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->hide(); ui->progressBar->hide(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); statusText = tr("Error"); @@ -171,7 +165,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->hide(); ui->progressBar->hide(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); break; @@ -184,7 +178,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->show(); ui->progressBar->show(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); break; @@ -197,7 +191,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->show(); ui->progressBar->hide(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); statusText = tr("Paused"); @@ -212,7 +206,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->show(); ui->progressBar->hide(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); statusText = tr("Waiting"); @@ -227,7 +221,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->show(); ui->progressBar->hide(); ui->openFilePushButton->hide(); - ui->openFolderToolButton->hide(); + ui->openFolderPushButton->hide(); statusText = tr("Checking"); @@ -242,7 +236,7 @@ void GxsChannelFilesStatusWidget::check() ui->cancelToolButton->hide(); ui->progressBar->hide(); ui->openFilePushButton->show(); - ui->openFolderToolButton->show(); + ui->openFolderPushButton->show(); break; } @@ -306,49 +300,87 @@ void GxsChannelFilesStatusWidget::resume() void GxsChannelFilesStatusWidget::cancel() { - if ((QMessageBox::question(this, "", tr("Are you sure that you want to cancel and delete the file?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) == QMessageBox::No) { - return; - } + // When QMessgeBox asks for cancel confirmtion, this makes the widget lose focus => since it is an editor widget, + // it gets destroyed by the parent list widget => subsequent code after the QMessageBox runs over a deleted object => crash + // In summary: no QMessageBox here when the Status widget is used as an editor. + + if(!mUsedAsEditor) + if ((QMessageBox::question(this, "", tr("Are you sure that you want to cancel and delete the file?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) == QMessageBox::No) { + return; + } rsFiles->FileCancel(mFile.mHash); emit onButtonClick();// Signals the parent widget to e.g. update the downloadable file count - check(); + check(); } void GxsChannelFilesStatusWidget::openFolder() { FileInfo fileInfo; - if (!rsFiles->alreadyHaveFile(mFile.mHash, fileInfo)) { + if (!haveFile(fileInfo)) return; - } - /* open folder with a suitable application */ - QDir dir = QFileInfo(QString::fromUtf8(fileInfo.path.c_str())).absoluteDir(); - if (dir.exists()) { - if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(dir.absolutePath()))) { - QMessageBox::warning(this, "", QString("%1 %2").arg(tr("Can't open folder"), dir.absolutePath())); - } - } + QFileInfo finfo; + finfo.setFile(QString::fromUtf8(fileInfo.path.c_str())); + + /* open folder with a suitable application */ + if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(finfo.absolutePath()))) { + if(!mUsedAsEditor) + QMessageBox::warning(this, "", QString("%1 %2").arg(tr("Can't open folder"), finfo.absolutePath())); + else + RsErr() << "Can't open folder " << finfo.absolutePath().toStdString() ; + } +} + +bool GxsChannelFilesStatusWidget::haveFile(FileInfo& info) +{ + bool already_has_file = rsFiles->alreadyHaveFile(mFile.mHash, info); + + if(!already_has_file) + if(!(rsFiles->FileDetails(mFile.mHash, RS_FILE_HINTS_DOWNLOAD | RS_FILE_HINTS_SPEC_ONLY, info) && info.downloadStatus==FT_STATE_COMPLETE)) + return false; + + // We need the code below because FileDetails() returns fileInfo.path as the directory when the file in COMPLETE and + // as a full path when the file is shared. The former is inconsistent with the documentation in rstypes.h, but I'm not + // sure what are the implications of changing the code in libretroshare so that the full path is always returned. + + QFileInfo finfo; + + if(QDir(QString::fromUtf8(info.path.c_str())).exists()) + finfo.setFile(QString::fromUtf8(info.path.c_str()),QString::fromUtf8(info.fname.c_str())); + else if(QFile(QString::fromUtf8(info.path.c_str())).exists()) + finfo.setFile(QString::fromUtf8(info.path.c_str())); + else + { + RsErr() << "Cannot find file!" << std::endl; + return false; + } + + info.path = finfo.absoluteFilePath().toStdString(); + return true; } void GxsChannelFilesStatusWidget::openFile() { FileInfo fileInfo; - if (!rsFiles->alreadyHaveFile(mFile.mHash, fileInfo)) { + if(!haveFile(fileInfo)) return; - } - /* open file with a suitable application */ - QFileInfo qinfo; - qinfo.setFile(QString::fromUtf8(fileInfo.path.c_str())); - if (qinfo.exists()) { - if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(qinfo.absoluteFilePath()))) { + QFileInfo finfo; + finfo.setFile(QString::fromUtf8(fileInfo.path.c_str())); + + if (finfo.exists()) { + if (!RsUrlHandler::openUrl(QUrl::fromLocalFile(finfo.absoluteFilePath()))) { std::cerr << "GxsChannelFilesStatusWidget(): can't open file " << fileInfo.path << std::endl; } }else{ - QMessageBox::information(this, tr("Play File"), - tr("File %1 does not exist at location.").arg(fileInfo.path.c_str())); - return; + if(!mUsedAsEditor) + QMessageBox::information(this, tr("Play File"), + tr("File %1 does not exist at location.").arg(fileInfo.path.c_str())); + else + RsErr() << "File " << fileInfo.path << " does not exist at location." ; + + return; } } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.h b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.h index 8f2f7f8e4..0dbb5c072 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.h @@ -34,9 +34,10 @@ class GxsChannelFilesStatusWidget : public QWidget Q_OBJECT public: - explicit GxsChannelFilesStatusWidget(const RsGxsFile &file, QWidget *parent = 0); + explicit GxsChannelFilesStatusWidget(const RsGxsFile &file, QWidget *parent = 0,bool used_as_editor=false); ~GxsChannelFilesStatusWidget(); + bool usedAsEditor() const { return mUsedAsEditor; } signals: void onButtonClick(); @@ -52,6 +53,7 @@ private slots: private: void setSize(uint64_t size); + bool haveFile(FileInfo& info); private: enum State @@ -73,6 +75,8 @@ private: uint64_t mSize; uint64_t mDivisor; + bool mUsedAsEditor; + Ui::GxsChannelFilesStatusWidget *ui; }; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui index c1b02ab83..e8ee2d512 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelFilesStatusWidget.ui @@ -6,14 +6,14 @@ 0 0 - 421 - 29 + 473 + 36 Form - + 0 @@ -27,11 +27,11 @@ 0 - + true - + 2 @@ -120,8 +120,8 @@ Qt::NoFocus - - :/images/cancel.png:/images/cancel.png + + :/icons/cancel.svg:/icons/cancel.svg @@ -139,7 +139,7 @@
    - + 0 diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp index a98e9016a..0af2631c5 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelGroupDialog.cpp @@ -21,10 +21,11 @@ #include #include "gui/gxs/GxsIdDetails.h" +#include "util/imageutil.h" #include "gui/common/FilesDefs.h" #include "GxsChannelGroupDialog.h" -#include +#include "retroshare/rsgxschannels.h" #include // To start with we only have open forums - with distribution controls. @@ -119,8 +120,10 @@ void GxsChannelGroupDialog::prepareChannelGroup(RsGxsChannelGroup &group, const QByteArray ba; QBuffer buffer(&ba); - buffer.open(QIODevice::WriteOnly); - pixmap.save(&buffer, "PNG"); // writes image into ba in PNG format + bool has_transparency = ImageUtil::hasAlphaContent(pixmap.toImage()); + + buffer.open(QIODevice::WriteOnly); + pixmap.save(&buffer, has_transparency?"PNG":"JPG"); // writes image into ba in PNG format group.mImage.copy((uint8_t *) ba.data(), ba.size()); } else { diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostFilesModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostFilesModel.cpp index be2f288ac..0796b6ce1 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostFilesModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostFilesModel.cpp @@ -33,11 +33,11 @@ #include "GxsChannelPostFilesModel.h" -//#define DEBUG_CHANNEL_MODEL +//#define DEBUG_CHANNEL_FILES_MODEL Q_DECLARE_METATYPE(ChannelPostFileInfo) -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_FILES_MODEL static std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere #endif @@ -161,8 +161,8 @@ QModelIndex RsGxsChannelPostFilesModel::index(int row, int column, const QModelI quintptr ref = getChildRef(parent.internalId(),row); -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << "index-3(" << row << "," << column << " parent=" << parent << ") : " << createIndex(row,column,ref) << std::endl; +#ifdef DEBUG_CHANNEL_FILES_MODEL + RsDbg() << "index-3(" << row << "," << column << " parent=" << parent << ") : " << createIndex(row,column,ref) ; #endif return createIndex(row,column,ref) ; } @@ -242,7 +242,7 @@ QVariant RsGxsChannelPostFilesModel::headerData(int section, Qt::Orientation /*o QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) const { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_FILES_MODEL std::cerr << "calling data(" << index << ") role=" << role << std::endl; #endif @@ -259,13 +259,13 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co quintptr ref = (index.isValid())?index.internalId():0 ; uint32_t entry = 0; -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_FILES_MODEL std::cerr << "data(" << index << ")" ; #endif if(!ref) { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_FILES_MODEL std::cerr << " [empty]" << std::endl; #endif return QVariant() ; @@ -273,7 +273,7 @@ QVariant RsGxsChannelPostFilesModel::data(const QModelIndex &index, int role) co if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFilteredFiles.size()) { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_FILES_MODEL std::cerr << "Bad pointer: " << (void*)ref << std::endl; #endif return QVariant() ; @@ -295,7 +295,7 @@ void RsGxsChannelPostFilesModel::setFilter(const QStringList& strings, uint32_t& { preMods(); - initEmptyHierarchy(); + mFilteredFiles.clear(); if(strings.empty()) { @@ -317,8 +317,6 @@ void RsGxsChannelPostFilesModel::setFilter(const QStringList& strings, uint32_t& } count = mFilteredFiles.size(); - std::cerr << "After filtering: " << count << " posts remain." << std::endl; - if (rowCount()>0) { beginInsertRows(QModelIndex(),0,rowCount()-1); @@ -344,10 +342,20 @@ public: case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: { FileInfo fi1,fi2; - rsFiles->FileDetails(f1.mHash,RS_FILE_HINTS_DOWNLOAD,fi1); - rsFiles->FileDetails(f2.mHash,RS_FILE_HINTS_DOWNLOAD,fi2); + bool r1 = rsFiles->FileDetails(f1.mHash,RS_FILE_HINTS_DOWNLOAD,fi1); + bool r2 = rsFiles->FileDetails(f2.mHash,RS_FILE_HINTS_DOWNLOAD,fi2); - return (ord==Qt::AscendingOrder)?(fi1.transferedfi2.transfered); + if(r1 && r2) + return (ord==Qt::AscendingOrder)?(fi1.transferedfi2.transfered); + else + { + FileInfo fitmp; + + if(!r1 && rsFiles->alreadyHaveFile(f1.mHash,fitmp)) fi1.downloadStatus = FT_STATE_COMPLETE; + if(!r2 && rsFiles->alreadyHaveFile(f2.mHash,fitmp)) fi2.downloadStatus = FT_STATE_COMPLETE; + + return (ord==Qt::AscendingOrder)?(fi1.downloadStatusfi2.downloadStatus); + } } } @@ -428,7 +436,6 @@ QVariant RsGxsChannelPostFilesModel::userRole(const ChannelPostFileInfo& fmpe,in void RsGxsChannelPostFilesModel::clear() { - initEmptyHierarchy(); emit channelLoaded(); @@ -446,7 +453,7 @@ void RsGxsChannelPostFilesModel::setFiles(const std::list & for(uint32_t i=0;i & postMods(); } + +void RsGxsChannelPostFilesModel::update_files(std::set& added_files,std::set& removed_files) +{ + // 1 - remove common files from both lists + +#ifdef DEBUG_CHANNEL_FILES_MODEL + RsDbg() << "RsGxsChannelPostsFilesModel:: updating files." ; +#endif + + for(auto afit=added_files.begin();afit!=added_files.end();) + { + auto rfit = removed_files.find(*afit); + + if(rfit != removed_files.end()) + { +#ifdef DEBUG_CHANNEL_FILES_MODEL + RsDbg() << " Eliminating common file " << rfit->mName ; +#endif + removed_files.erase(rfit); + auto tmp = afit; + ++tmp; + added_files.erase(afit); + afit = tmp; + } + else + ++afit; + } + + RsDbg() << " Remains: " << added_files.size() << " added files and " << removed_files.size() << " removed files" ; + + // 2 - add whatever file remains, + + for(const auto& f:removed_files) + { +#ifdef DEBUG_CHANNEL_FILES_MODEL + RsDbg() << " Removing deleted file " << f.mName ; +#endif + + for(uint32_t i=0;i& files); + void setFiles(const std::list& files); void setFilter(const QStringList &strings, uint32_t &count) ; + // This method adds/removes the given lists of files. Useful when a single post is updated + void update_files(std::set &added_files, std::set &removed_files); + #ifdef TODO - QModelIndex getIndexOfFile(const RsFileHash& hash) const; + QModelIndex getIndexOfFile(const RsFileHash& hash) const; void setSortMode(SortMode mode) ; - void setTextColorRead (QColor color) { mTextColorRead = color;} - void setTextColorUnread (QColor color) { mTextColorUnread = color;} - void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color;} - void setTextColorNotSubscribed (QColor color) { mTextColorNotSubscribed = color;} - void setTextColorMissing (QColor color) { mTextColorMissing = color;} - void setAuthorOpinion(const QModelIndex& indx,RsOpinion op); + void setTextColorRead (QColor color) { mTextColorRead = color;} + void setTextColorUnread (QColor color) { mTextColorUnread = color;} + void setTextColorUnreadChildren(QColor color) { mTextColorUnreadChildren = color;} + void setTextColorNotSubscribed (QColor color) { mTextColorNotSubscribed = color;} + void setTextColorMissing (QColor color) { mTextColorMissing = color;} + void setAuthorOpinion(const QModelIndex& indx,RsOpinion op); #endif // Helper functions @@ -112,25 +115,25 @@ public: Qt::ItemFlags flags(const QModelIndex& index) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; // Custom item roles QVariant sizeHintRole (int col) const; - QVariant displayRole (const ChannelPostFileInfo& fmpe, int col) const; - QVariant toolTipRole (const ChannelPostFileInfo& fmpe, int col) const; - QVariant userRole (const ChannelPostFileInfo& fmpe, int col) const; - QVariant sortRole (const ChannelPostFileInfo& fmpe, int col) const; - QVariant filterRole (const ChannelPostFileInfo& fmpe, int col) const; + QVariant displayRole (const ChannelPostFileInfo& fmpe, int col) const; + QVariant toolTipRole (const ChannelPostFileInfo& fmpe, int col) const; + QVariant userRole (const ChannelPostFileInfo& fmpe, int col) const; + QVariant sortRole (const ChannelPostFileInfo& fmpe, int col) const; + QVariant filterRole (const ChannelPostFileInfo& fmpe, int col) const; #ifdef TODO - QVariant decorationRole(const ForumModelPostEntry& fmpe, int col) const; - QVariant pinnedRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant missingRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant statusRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant authorRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant fontRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant textColorRole (const ForumModelPostEntry& fmpe, int col) const; - QVariant backgroundRole(const ForumModelPostEntry& fmpe, int col) const; + QVariant decorationRole(const ForumModelPostEntry& fmpe, int col) const; + QVariant pinnedRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant missingRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant statusRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant authorRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant fontRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant textColorRole (const ForumModelPostEntry& fmpe, int col) const; + QVariant backgroundRole(const ForumModelPostEntry& fmpe, int col) const; #endif /*! @@ -151,20 +154,20 @@ private: bool mFilteringEnabled; SortMode mSortMode; #endif - void preMods() ; - void postMods() ; + void preMods() ; + void postMods() ; quintptr getParentRow(quintptr ref,int& row) const; quintptr getChildRef(quintptr ref, int index) const; int getChildrenCount(quintptr ref) const; static bool convertTabEntryToRefPointer(uint32_t entry, quintptr& ref); - static bool convertRefPointerToTabEntry(quintptr ref,uint32_t& entry); + static bool convertRefPointerToTabEntry(quintptr ref,uint32_t& entry); #ifdef TODO - static void generateMissingItem(const RsGxsMessageId &msgId,ChannelPostsModelPostEntry& entry); + static void generateMissingItem(const RsGxsMessageId &msgId,ChannelPostsModelPostEntry& entry); #endif - void initEmptyHierarchy(); + void initEmptyHierarchy(); std::vector mFilteredFiles ; // store the list of files for the post std::vector mFiles ; // store the list of files for the post diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp index eb890b075..16cf96195 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.cpp @@ -217,6 +217,25 @@ float ChannelPostThumbnailView::thumbnail_h() const } } +void ZoomableLabel::keyPressEvent(QKeyEvent *e) +{ + switch(e->key()) + { + case Qt::Key_Delete: + + if(mClearEnabled) + { + mFullImage = QPixmap(); + emit cleared(); + e->accept(); + updateView(); + } + break; + default: + QLabel::keyPressEvent(e); + } +} + void ZoomableLabel::reset() { mCenterX = mFullImage.width()/2.0; @@ -331,7 +350,7 @@ void ZoomableLabel::updateView() std::cerr << " Image size: " << mFullImage.width() << " x " << mFullImage.height() << ", window size: " << width() << " x " << height() << std::endl; std::cerr << " cropped image: " << rect.left() << "," << rect.top() << "+" << rect.width() << "+" << rect.height() << std::endl; std::cerr << " saving crop to pix2.png" << std::endl; - mFullImage.copy(rect).save("pix2.png","PNG"); + mFullImage.copy(rect).save("pix2.png","JPG"); #endif QLabel::setPixmap(mFullImage.copy(rect)); } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h index d89fd5eca..7ee928f9e 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostThumbnail.h @@ -40,18 +40,22 @@ class ZoomableLabel: public QLabel Q_OBJECT public: - ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true) {} + ZoomableLabel(QWidget *parent): QLabel(parent),mUseStyleSheet(true),mZoomFactor(1.0),mCenterX(0.0),mCenterY(0.0),mZoomEnabled(true),mClearEnabled(false) {} void setPicture(const QPixmap& pix); void setEnableZoom(bool b) { mZoomEnabled = b; } + void setEnableClear(bool b) { mClearEnabled = b; } void reset(); QPixmap extractCroppedScaledPicture() const; void updateView(); + virtual void keyPressEvent(QKeyEvent *ev) override; + const QPixmap& originalImage() const { return mFullImage ; } signals: void clicked(); + void cleared(); protected: void mousePressEvent(QMouseEvent *ev) override; @@ -73,6 +77,7 @@ protected: int mLastX,mLastY; bool mMoving; bool mZoomEnabled; + bool mClearEnabled; }; // Class to paint the thumbnails with title @@ -102,7 +107,7 @@ public: static const int THUMBNAIL_W = 4; static const int THUMBNAIL_H = 6; - static constexpr char *CHAN_DEFAULT_IMAGE = ":images/thumb-default-video.png"; + static constexpr const char *CHAN_DEFAULT_IMAGE = ":images/thumb-default-video.png"; virtual ~ChannelPostThumbnailView(); ChannelPostThumbnailView(QWidget *parent=NULL,uint32_t flags=FLAG_ALLOW_PAN | FLAG_SHOW_TEXT | FLAG_SCALE_FONT); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp index 31eef8242..a42587d85 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.cpp @@ -27,6 +27,8 @@ #include "retroshare/rsgxschannels.h" #include "retroshare/rsexpr.h" +#include "gui/MainWindow.h" +#include "gui/mainpagestack.h" #include "gui/common/FilesDefs.h" #include "util/qtthreadsutils.h" #include "util/HandleRichText.h" @@ -35,10 +37,10 @@ #include "GxsChannelPostsModel.h" #include "GxsChannelPostFilesModel.h" -//#define DEBUG_CHANNEL_MODEL +//#define DEBUG_CHANNEL_MODEL_DATA +#define DEBUG_CHANNEL_MODEL Q_DECLARE_METATYPE(RsMsgMetaData) - Q_DECLARE_METATYPE(RsGxsChannelPost) std::ostream& operator<<(std::ostream& o, const QModelIndex& i);// defined elsewhere @@ -47,14 +49,6 @@ RsGxsChannelPostsModel::RsGxsChannelPostsModel(QObject *parent) : QAbstractItemModel(parent), mTreeMode(RsGxsChannelPostsModel::TREE_MODE_GRID), mColumns(6) { initEmptyHierarchy(); - - mEventHandlerId = 0; - // Needs to be asynced because this function is called by another thread! - - rsEvents->registerEventsHandler( [this](std::shared_ptr event) - { - RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); - }, mEventHandlerId, RsEventType::GXS_CHANNELS ); } RsGxsChannelPostsModel::~RsGxsChannelPostsModel() @@ -69,137 +63,10 @@ void RsGxsChannelPostsModel::setMode(TreeMode mode) if(mode == TREE_MODE_LIST) setNumColumns(2); - triggerViewUpdate(); -} - -void updateCommentCounts( std::vector& posts, std::vector& comments) -{ - // Store posts IDs in a std::map to avoid a quadratic cost - - std::map post_indices; - - for(uint32_t i=0;isecond>=posts.size() is impossible by construction, since post_indices - // is previously filled using posts ids. - - if(it == post_indices.end()) - continue; - - ++posts[it->second].mCommentCount; - - if(IS_MSG_NEW(comments[i].mMeta.mMsgStatus)) - ++posts[it->second].mUnreadCommentCount; - } + triggerViewUpdate(true,true); } -void RsGxsChannelPostsModel::handleEvent_main_thread(std::shared_ptr event) -{ - const RsGxsChannelEvent *e = dynamic_cast(event.get()); - - if(!e) - return; - - switch(e->mChannelEventCode) - { - case RsChannelEventCode::UPDATED_MESSAGE: - case RsChannelEventCode::READ_STATUS_CHANGED: - { - // Normally we should just emit dataChanged() on the index of the data that has changed: - // We need to update the data! - - // make a copy of e, so as to avoid destruction of the shared pointer during async thread execution, since [e] doesn't actually tell - // the original shared_ptr that it is copied! So no counter is updated in event, which will be destroyed (as e will be) during or even before - // the execution of the lambda. - - RsGxsChannelEvent E(*e); - - if(E.mChannelGroupId == mChannelGroup.mMeta.mGroupId) - RsThread::async([this, E]() - { - // 1 - get message data from p3GxsChannels. No need for pointers here, because we send only a single post to postToObject() - // At this point we dont know what kind of msg id we have. It can be a vote, a comment or an actual message. - - std::vector posts; - std::vector comments; - std::vector votes; - std::set msg_ids{ E.mChannelMsgId }; - - if(!rsGxsChannels->getChannelContent(E.mChannelGroupId,msg_ids, posts,comments,votes)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl; - return; - } - - // Check if what we have actually is a comment or a vote. If so we need to update the actual message they refer to - - if(posts.empty()) // means we have a comment or a vote - { - msg_ids.clear(); - - for(auto c:comments) msg_ids.insert(c.mMeta.mThreadId); - for(auto v:votes ) msg_ids.insert(v.mMeta.mThreadId); - - comments.clear(); - votes.clear(); - - if(!rsGxsChannels->getChannelContent(E.mChannelGroupId,msg_ids,posts,comments,votes)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl; - return; - } - } - - // Need to call this in order to get the actuall comment count. The previous call only retrieves the message, since we supplied the message ID. - // another way to go would be to save the comment ids of the existing message and re-insert them before calling getChannelContent. - - if(!rsGxsChannels->getChannelComments(E.mChannelGroupId,msg_ids,comments)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message comment data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl; - return; - } - - updateCommentCounts(posts,comments); - - // 2 - update the model in the UI thread. - - RsQThreadUtils::postToObject( [posts,this]() - { - for(uint32_t i=0;i& files) @@ -241,29 +111,39 @@ void RsGxsChannelPostsModel::getFilesList(std::list& files) files.push_back(it.second); } +bool RsGxsChannelPostsModel::postPassesFilter(const RsGxsChannelPost& post,const QStringList& strings,bool only_unread) const +{ + bool passes_strings = true; + + for(auto& s:strings) + passes_strings = passes_strings && QString::fromStdString(post.mMeta.mMsgName).contains(s,Qt::CaseInsensitive); + + if(strings.empty()) + passes_strings = true; + + if(passes_strings && (!only_unread || (IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)))) + return true; + + return false; +} + void RsGxsChannelPostsModel::setFilter(const QStringList& strings,bool only_unread, uint32_t& count) +{ + mFilteredStrings = strings; + mFilterUnread = only_unread; + + updateFilter(count); +} + +void RsGxsChannelPostsModel::updateFilter(uint32_t& count) { preMods(); - beginResetModel(); - mFilteredPosts.clear(); - //mFilteredPosts.push_back(0); - endResetModel(); for(size_t i=0;i 0) + return r; + else + return columnCount(); + } + else + return columnCount(); + } + else + return 2; +} int RsGxsChannelPostsModel::columnCount(const QModelIndex &/*parent*/) const { if(mTreeMode == TREE_MODE_GRID) @@ -365,12 +264,12 @@ bool RsGxsChannelPostsModel::convertRefPointerToTabEntry(quintptr ref, uint32_t& QModelIndex RsGxsChannelPostsModel::index(int row, int column, const QModelIndex & parent) const { - if(row < 0 || column < 0 || column >= (int)mColumns) + if(row < 0 || column < 0 || row >= rowCount() || column >= columnCount(row)) return QModelIndex(); quintptr ref = getChildRef(parent.internalId(),(mTreeMode == TREE_MODE_GRID)?(column + row*mColumns):row); -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_MODEL_DATA std::cerr << "index-3(" << row << "," << column << " parent=" << parent << ") : " << createIndex(row,column,ref) << std::endl; #endif return createIndex(row,column,ref) ; @@ -401,17 +300,8 @@ bool RsGxsChannelPostsModel::setNumColumns(int n) preMods(); - beginResetModel(); - endResetModel(); - mColumns = n; - if (rowCount()>0) - { - beginInsertRows(QModelIndex(),0,rowCount()-1); - endInsertRows(); - } - postMods(); return true; @@ -460,7 +350,7 @@ int RsGxsChannelPostsModel::getChildrenCount(quintptr ref) const QVariant RsGxsChannelPostsModel::data(const QModelIndex &index, int role) const { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_MODEL_DATA std::cerr << "calling data(" << index << ") role=" << role << std::endl; #endif @@ -477,13 +367,13 @@ QVariant RsGxsChannelPostsModel::data(const QModelIndex &index, int role) const quintptr ref = (index.isValid())?index.internalId():0 ; uint32_t entry = 0; -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_MODEL_DATA std::cerr << "data(" << index << ")" ; #endif if(!ref) { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_MODEL_DATA std::cerr << " [empty]" << std::endl; #endif return QVariant() ; @@ -491,7 +381,7 @@ QVariant RsGxsChannelPostsModel::data(const QModelIndex &index, int role) const if(!convertRefPointerToTabEntry(ref,entry) || entry >= mFilteredPosts.size()) { -#ifdef DEBUG_CHANNEL_MODEL +#ifdef DEBUG_CHANNEL_MODEL_DATA std::cerr << "Bad pointer: " << (void*)ref << std::endl; #endif return QVariant() ; @@ -540,7 +430,6 @@ const RsGxsGroupId& RsGxsChannelPostsModel::currentGroupId() const { return mChannelGroup.mMeta.mGroupId; } - void RsGxsChannelPostsModel::updateChannel(const RsGxsGroupId& channel_group_id) { if(channel_group_id.isNull()) @@ -564,6 +453,79 @@ bool operator<(const RsGxsChannelPost& p1,const RsGxsChannelPost& p2) return p1.mMeta.mPublishTs > p2.mMeta.mPublishTs; } +void RsGxsChannelPostsModel::updateSinglePost(const RsGxsChannelPost& post,std::set& added_files,std::set& removed_files) +{ +#ifdef DEBUG_CHANNEL_MODEL + RsDbg() << "updating single post for group id=" << currentGroupId() << " and msg id=" << post.mMeta.mMsgId ; +#endif + added_files.clear(); + removed_files.clear(); + + emit layoutAboutToBeChanged(); + + // linear search. Not good at all, but normally this is just for a single post. + + bool found = false; + const auto& new_post_meta(post.mMeta); + + for(uint32_t j=0;j& posts) { preMods(); @@ -571,8 +533,9 @@ void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vecto initEmptyHierarchy(); mChannelGroup = group; - createPostsArray(posts); +// createPostsArray(posts); + mPosts = posts; std::sort(mPosts.begin(),mPosts.end()); for(uint32_t i=0;isetCursor(Qt::WaitCursor) ; // Maybe we should pass that widget when calling update_posts + + RsThread::async([this, group_id]() { // 1 - get message data from p3GxsChannels @@ -616,30 +583,23 @@ void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id) RsGxsChannelGroup group = groups[0]; - // We use the heap because the arrays need to be stored accross async + std::vector *posts = new std::vector(); // We use the heap because the arrays need to be stored accross async + std::vector comments ; + std::vector votes ; - std::vector *posts = new std::vector(); - std::vector *comments = new std::vector(); - std::vector *votes = new std::vector(); - - if(!rsGxsChannels->getChannelAllContent(group_id, *posts,*comments,*votes)) + if(!rsGxsChannels->getChannelAllContent(group_id, *posts,comments,votes)) { std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel messages for channel " << group_id << std::endl; return; } std::cerr << "Got channel all content for channel " << group_id << std::endl; std::cerr << " posts : " << posts->size() << std::endl; - std::cerr << " comments: " << comments->size() << std::endl; - std::cerr << " votes : " << votes->size() << std::endl; - - // This shouldn't be needed normally. We need it until a background process computes the number of comments per - // post and stores it in the service string. Since we request all data, this process isn't costing much anyway. - - updateCommentCounts(*posts,*comments); + std::cerr << " comments: " << comments.size() << std::endl; + std::cerr << " votes : " << votes.size() << std::endl; // 2 - update the model in the UI thread. - RsQThreadUtils::postToObject( [group,posts,comments,votes,this]() + RsQThreadUtils::postToObject( [group,posts,this]() { /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information @@ -650,132 +610,14 @@ void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id) setPosts(group,*posts) ; delete posts; - delete comments; - delete votes; - }, this ); + MainWindow::getPage(MainWindow::Channels)->setCursor(Qt::ArrowCursor) ; + + }, this ); }); } -void RsGxsChannelPostsModel::createPostsArray(std::vector& posts) -{ - // collect new versions of posts if any - -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << "Inserting channel posts" << std::endl; -#endif - - std::vector new_versions ; - for (uint32_t i=0;i search_map ; - for (uint32_t i=0;i versions ; - std::map::const_iterator vit ; - - while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId))) - { -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ; -#endif - - // Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple - // times. In this case, we only need to replace the post with the newest version - - //uint32_t prev_index = current_index ; - current_index = vit->second ; - - if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further. - { -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << " already erased. Stopping." << std::endl; -#endif - break ; - } - - if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs) - { -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << " and is more recent => following" << std::endl; -#endif - for(std::set::const_iterator itt(posts[current_index].mOlderVersions.begin());itt!=posts[current_index].mOlderVersions.end();++itt) - posts[source_index].mOlderVersions.insert(*itt); - - posts[source_index].mOlderVersions.insert(posts[current_index].mMeta.mMsgId); - posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored - } -#ifdef DEBUG_CHANNEL_MODEL - else - std::cerr << " but is older -> Stopping" << std::endl; -#endif - } - } - } - -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << "Now adding " << posts.size() << " posts into array structure..." << std::endl; -#endif - - mPosts.clear(); - - for (std::vector::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it) - { - if(!(*it).mMeta.mMsgId.isNull()) - { -#ifdef DEBUG_CHANNEL_MODEL - std::cerr << " adding post \"" << (*it).mMeta.mMsgName << "\"" << std::endl; -#endif - mPosts.push_back(*it); - } -#ifdef DEBUG_CHANNEL_MODEL - else - std::cerr << " skipped older version post \"" << (*it).mMeta.mMsgName << "\"" << std::endl; -#endif - } -} - void RsGxsChannelPostsModel::setAllMsgReadStatus(bool read_status) { // No need to call preMods()/postMods() here because we're not changing the model @@ -798,11 +640,31 @@ void RsGxsChannelPostsModel::setAllMsgReadStatus(bool read_status) for(uint32_t i=0;imarkRead(p,read_status)) + if(!rsGxsChannels->setMessageReadStatus(p,read_status)) RsErr() << "setAllMsgReadStatus: failed to change status of msg " << p.first << " in group " << p.second << " to status " << read_status << std::endl; }); + + // 3 - update the local model data, since we don't catch the READ_STATUS_CHANGED event later, to avoid re-loading the msg. + + for(uint32_t i=0;i= mFilteredPosts.size()) return ; - rsGxsChannels->markRead(RsGxsGrpMsgIdPair(mPosts[mFilteredPosts[entry]].mMeta.mGroupId,mPosts[mFilteredPosts[entry]].mMeta.mMsgId),read_status); + rsGxsChannels->setMessageReadStatus(RsGxsGrpMsgIdPair(mPosts[mFilteredPosts[entry]].mMeta.mGroupId,mPosts[mFilteredPosts[entry]].mMeta.mMsgId),read_status); + + // Quick update to the msg itself. Normally setMsgReadStatus will launch an event, + // that we can catch to update the msg, but all the information is already here. + + if(read_status) + mPosts[mFilteredPosts[entry]].mMeta.mMsgStatus &= ~(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD | GXS_SERV::GXS_MSG_STATUS_GUI_NEW); + else + mPosts[mFilteredPosts[entry]].mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD; + + mPosts[mFilteredPosts[entry]].mUnreadCommentCount = 0; + + emit dataChanged(i,i); } QModelIndex RsGxsChannelPostsModel::getIndexOfMessage(const RsGxsMessageId& mid) const diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.h index d8385d24b..c447f11a3 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsModel.h @@ -101,9 +101,11 @@ public: SORT_MODE_CHILDREN_PUBLISH_TS = 0x01, }; #endif + static void computeCommentCounts( std::vector& posts, std::vector& comments); QModelIndex root() const{ return createIndex(0,0,(void*)NULL) ;} QModelIndex getIndexOfMessage(const RsGxsMessageId& mid) const; + int columnCount(int row) const; // columns in the row of this particular index. std::vector > getPostVersions(const RsGxsMessageId& mid) const; @@ -114,7 +116,7 @@ public: void updateChannel(const RsGxsGroupId& channel_group_id); const RsGxsGroupId& currentGroupId() const; - void triggerViewUpdate(); + void triggerViewUpdate(bool data_changed,bool layout_changed); // sets the number of columns. Returns 0 if nothing changes. bool setNumColumns(int n); @@ -138,8 +140,11 @@ public: void setMsgReadStatus(const QModelIndex &i, bool read_status); void setAllMsgReadStatus(bool read_status); + void updatePostWithNewComment(const RsGxsMessageId& msg_id); void setFilter(const QStringList &strings, bool only_unread,uint32_t &count) ; + bool postPassesFilter(const RsGxsChannelPost &post, const QStringList &strings, bool only_unread) const; + void updateFilter(uint32_t& count); #ifdef TODO void setAuthorOpinion(const QModelIndex& indx,RsOpinion op); @@ -215,6 +220,8 @@ private: void update_posts(const RsGxsGroupId& group_id); +private: + #ifdef TODO void setForumMessageSummary(const std::vector& messages); #endif @@ -229,10 +236,16 @@ private: //static void convertMsgToPostEntry(const RsGxsChannelGroup &mChannelGroup, const RsMsgMetaData &msg, bool useChildTS, ChannelModelPostEntry& fentry); //void computeMessagesHierarchy(const RsGxsChannelGroup& forum_group, const std::vector &msgs_array, std::vector &posts, std::map > > &mPostVersions); - void createPostsArray(std::vector &posts); - void setPosts(const RsGxsChannelGroup& group, std::vector &posts); - void initEmptyHierarchy(); - void handleEvent_main_thread(std::shared_ptr event); + void old_createPostsArray(std::vector &posts); + void createPostsArray(std::vector& posts); + void setPosts(const RsGxsChannelGroup& group, std::vector &posts); +public: + void updateSinglePost(const RsGxsChannelPost& post, std::set& added_files, std::set& removed_files); +private: + void initEmptyHierarchy(); + + QStringList mFilteredStrings; + bool mFilterUnread; std::vector mFilteredPosts; // stores the list of displayes indices due to filtering. std::vector mPosts ; // store the list of posts updated from rsForums. diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp index d3c4070b0..ea27be6f9 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp @@ -56,8 +56,6 @@ * #define DEBUG_CHANNEL ***/ -//static const int mTokenTypeGroupData = 1; - static const int CHANNEL_TABS_DETAILS= 0; static const int CHANNEL_TABS_POSTS = 1; static const int CHANNEL_TABS_FILES = 2; @@ -75,12 +73,13 @@ QColor SelectedColor = QRgb(0xff308dc7); #define COLUMN_SIZE_FONT_FACTOR_W 6 #define COLUMN_SIZE_FONT_FACTOR_H 10 -#define STAR_OVERLAY_IMAGE ":icons/star_overlay_128.png" -#define COMMENT_OVERLAY_IMAGE ":images/white-bubble-64.png" -#define IMAGE_COPYLINK ":icons/png/copy.png" -#define IMAGE_GRID_VIEW ":icons/png/menu.png" -#define IMAGE_DOWNLOAD ":icons/png/download.png" -#define IMAGE_UNREAD ":icons/png/message.png" +#define STAR_OVERLAY_IMAGE ":icons/star_overlay_128.png" +#define COMMENT_OVERLAY_IMAGE ":images/white-bubble-64.png" +#define UNREAD_COMMENT_OVERLAY_IMAGE ":images/orange-bubble-64.png" +#define IMAGE_COPYLINK ":icons/png/copy.png" +#define IMAGE_GRID_VIEW ":icons/png/menu.png" +#define IMAGE_DOWNLOAD ":icons/png/download.png" +#define IMAGE_UNREAD ":icons/png/message.png" Q_DECLARE_METATYPE(ChannelPostFileInfo) @@ -93,17 +92,17 @@ Q_DECLARE_METATYPE(ChannelPostFileInfo) int ChannelPostDelegate::cellSize(int col,const QFont& font,uint32_t parent_width) const { if(mUseGrid || col==0) - return mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height(); + return (int)floor(mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height()); else - return 0.8*parent_width - mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height(); + return (int)floor(0.8*parent_width - mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height()); } void ChannelPostDelegate::zoom(bool zoom_or_unzoom) { if(zoom_or_unzoom) - mZoom *= 1.02; + mZoom *= 1.02; else - mZoom /= 1.02; + mZoom /= 1.02; if(mZoom < 0.5) mZoom = 0.5; @@ -123,11 +122,7 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & RsGxsChannelPost post = index.data(Qt::UserRole).value() ; - // if(index.row() & 0x01) - // painter->fillRect( option.rect, option.palette.alternateBase().color()); - // else - painter->fillRect( option.rect, option.palette.base().color()); - + painter->fillRect( option.rect, option.palette.base().color()); painter->restore(); if(mUseGrid || index.column()==0) @@ -146,14 +141,7 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & if((option.state & QStyle::State_Selected) && post.mMeta.mPublishTs > 0) // check if post is selected and is not empty (end of last row) pixmap.fill(SelectedColor); // I dont know how to grab the backgroud color for selected objects automatically. else - { - // we need to do the alternate color manually - - //if(index.row() & 0x01) - // pixmap.fill(option.palette.alternateBase().color()); - //else - pixmap.fill(option.palette.base().color()); - } + pixmap.fill(option.palette.base().color()); w.render(&pixmap,QPoint(),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background @@ -166,37 +154,43 @@ void ChannelPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem & // { // QFile file("yourFile.png"); // file.open(QIODevice::WriteOnly); -// pixmap.save(&file, "PNG"); +// pixmap.save(&file, "JPG"); // file.close(); // } - if(mUseGrid || index.column()==0) + if(mZoom != 1.0) + pixmap = pixmap.scaled(mZoom*pixmap.size(),Qt::KeepAspectRatio,Qt::SmoothTransformation); + + if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) { - if(mZoom != 1.0) - pixmap = pixmap.scaled(mZoom*pixmap.size(),Qt::KeepAspectRatio,Qt::SmoothTransformation); + QPainter p(&pixmap); + QFontMetricsF fm(option.font); - if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) - { - QPainter p(&pixmap); - QFontMetricsF fm(option.font); + p.drawPixmap(mZoom*QPoint(0.1*fm.height(),-3.4*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*6*fm.height(),mZoom*6*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation)); + } - p.drawPixmap(mZoom*QPoint(0.1*fm.height(),-3.4*fm.height()),FilesDefs::getPixmapFromQtResourcePath(STAR_OVERLAY_IMAGE).scaled(mZoom*6*fm.height(),mZoom*6*fm.height(),Qt::KeepAspectRatio,Qt::SmoothTransformation)); - } + if(post.mUnreadCommentCount > 0) + { + QPainter p(&pixmap); + QFontMetricsF fm(option.font); - if(post.mUnreadCommentCount) - { - QPainter p(&pixmap); - QFontMetricsF fm(option.font); - - p.drawPixmap(QPoint(pixmap.width(),0.0)+mZoom*QPoint(-2.9*fm.height(),0.4*fm.height()), - FilesDefs::getPixmapFromQtResourcePath(COMMENT_OVERLAY_IMAGE).scaled(mZoom*3*fm.height(),mZoom*3*fm.height(), - Qt::KeepAspectRatio,Qt::SmoothTransformation)); - } + p.drawPixmap(QPoint(pixmap.width(),0.0)+mZoom*QPoint(-2.9*fm.height(),0.4*fm.height()), + FilesDefs::getPixmapFromQtResourcePath(UNREAD_COMMENT_OVERLAY_IMAGE).scaled(mZoom*3*fm.height(),mZoom*3*fm.height(), + Qt::KeepAspectRatio,Qt::SmoothTransformation)); + } + else if(post.mCommentCount > 0) + { + QPainter p(&pixmap); + QFontMetricsF fm(option.font); + p.drawPixmap(QPoint(pixmap.width(),0.0)+mZoom*QPoint(-2.9*fm.height(),0.4*fm.height()), + FilesDefs::getPixmapFromQtResourcePath(COMMENT_OVERLAY_IMAGE).scaled(mZoom*3*fm.height(),mZoom*3*fm.height(), + Qt::KeepAspectRatio,Qt::SmoothTransformation)); } painter->drawPixmap(option.rect.topLeft(), - pixmap.scaled(option.rect.width(),option.rect.width()*pixmap.height()/(float)pixmap.width(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); + pixmap.scaled(option.rect.width(),option.rect.width()*pixmap.height()/(float)pixmap.width(), + Qt::IgnoreAspectRatio,Qt::SmoothTransformation)); } else { @@ -264,6 +258,9 @@ QSize ChannelPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QM float cell_width = mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height(); float cell_height = mZoom*COLUMN_SIZE_FONT_FACTOR_W*fm.height()*aspect_ratio; +#ifdef DEBUG_CHANNEL_POSTS_WIDGET + RsDbg() << "SizeHint: mUseGrid=" << mUseGrid << " cell_width=" << cell_width << " cell_height=" << cell_height << " mZoom=" << mZoom ; +#endif if(mUseGrid || index.column()==0) return QSize(cell_width,cell_height); @@ -282,52 +279,54 @@ void ChannelPostDelegate::setWidgetGrid(bool use_grid) QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex& index) const { - ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; + ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; - if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE) - { - GxsChannelFilesStatusWidget* w = new GxsChannelFilesStatusWidget(file,parent); - connect(w,SIGNAL(onButtonClick()),this->parent(),SLOT(updateDAll_PB())); - return w; - } - else - return NULL; + if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE) + { + GxsChannelFilesStatusWidget* w = new GxsChannelFilesStatusWidget(file,parent,true); + w->setFocusPolicy(Qt::StrongFocus); + connect(w,SIGNAL(onButtonClick()),this->parent(),SLOT(updateDAll_PB())); + + return w; + } + else + return NULL; } void ChannelPostFilesDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { - editor->setGeometry(option.rect); + editor->setGeometry(option.rect); } void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { - ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; + ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; - // prepare - painter->save(); - painter->setClipRect(option.rect); + // prepare + painter->save(); + painter->setClipRect(option.rect); painter->save(); painter->fillRect( option.rect, option.backgroundBrush); - //optionFocusRect.backgroundColor = option.palette.color(colorgroup, (option.state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Background); + //optionFocusRect.backgroundColor = option.palette.color(colorgroup, (option.state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Background); painter->restore(); switch(index.column()) { case RsGxsChannelPostFilesModel::COLUMN_FILES_NAME: painter->drawText(option.rect,Qt::AlignLeft | Qt::AlignVCenter," " + QString::fromUtf8(file.mName.c_str())); - break; + break; case RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE: painter->drawText(option.rect,Qt::AlignRight | Qt::AlignVCenter,misc::friendlyUnit(qulonglong(file.mSize))); - break; + break; case RsGxsChannelPostFilesModel::COLUMN_FILES_DATE: painter->drawText(option.rect,Qt::AlignLeft | Qt::AlignVCenter,QDateTime::fromMSecsSinceEpoch(file.mPublishTime*1000).toString("MM/dd/yyyy, hh:mm")); - break; + break; case RsGxsChannelPostFilesModel::COLUMN_FILES_FILE: { - GxsChannelFilesStatusWidget w(file); + GxsChannelFilesStatusWidget w(file); w.setFixedWidth(option.rect.width()); - w.setFixedHeight(option.rect.height()); + w.setFixedHeight(option.rect.height()); - QPixmap pixmap(w.size()); + QPixmap pixmap(w.size()); // apparently we need to do the alternate colors manually //if(index.row() & 0x01) @@ -343,13 +342,13 @@ void ChannelPostFilesDelegate::paint(QPainter * painter, const QStyleOptionViewI default: painter->drawText(option.rect,Qt::AlignLeft,QString("[No data]")); - break; + break; } } QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { - ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; + ChannelPostFileInfo file = index.data(Qt::UserRole).value() ; QFontMetricsF fm(option.font); @@ -369,18 +368,18 @@ QSize ChannelPostFilesDelegate::sizeHint(const QStyleOptionViewItem& option, con /** Constructor */ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupId &channelId, QWidget *parent) : - GxsMessageFrameWidget(rsGxsChannels, parent), - ui(new Ui::GxsChannelPostsWidgetWithModel) + GxsMessageFrameWidget(rsGxsChannels, parent), + ui(new Ui::GxsChannelPostsWidgetWithModel) { - /* Invoke the Qt Designer generated object setup routine */ - ui->setupUi(this); + /* Invoke the Qt Designer generated object setup routine */ + ui->setupUi(this); ui->viewType_TB->setIcon(FilesDefs::getIconFromQtResourcePath(":icons/svg/gridlayout.svg")); ui->viewType_TB->setToolTip(tr("Click to switch to list view")); connect(ui->viewType_TB,SIGNAL(clicked()),this,SLOT(switchView())); ui->showUnread_TB->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png")); - ui->showUnread_TB->setChecked(false); + whileBlocking(ui->showUnread_TB)->setChecked(false); ui->showUnread_TB->setToolTip(tr("Show unread posts only")); connect(ui->showUnread_TB,SIGNAL(toggled(bool)),this,SLOT(switchOnlyUnread(bool))); @@ -393,7 +392,7 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI mChannelPostsDelegate->setAspectRatio(ChannelPostThumbnailView::ASPECT_RATIO_16_9); - connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(updateZoomFactor(bool))); + connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(onUpdateZoomFactor(bool))); connect(ui->commentsDialog,SIGNAL(commentsLoaded(int)),this,SLOT(updateCommentsCount(int))); ui->channelPostFiles_TV->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this)); @@ -412,12 +411,14 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI connect(ui->channelPostFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnPostFiles(int,Qt::SortOrder))); connect(ui->channelFiles_TV->header(),SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortColumnFiles(int,Qt::SortOrder))); - connect(ui->channelPostFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint))); + connect(ui->channelPostFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelPostFilesContextMenu(QPoint))); connect(ui->channelFiles_TV,SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showChannelFilesContextMenu(QPoint))); connect(ui->postsTree->selectionModel(),SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),this,SLOT(showPostDetails())); connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&))); + connect(ui->channel_TW,SIGNAL(currentChanged(int)),this,SLOT(currentTabChanged(int))); + connect(mChannelPostsModel,SIGNAL(channelPostsLoaded()),this,SLOT(postChannelPostLoad())); ui->postName_LB->hide(); @@ -429,94 +430,149 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI ui->postDetails_TE->setPlaceholderText(tr("No text to display")); - // Set initial size of the splitter - ui->splitter->setStretchFactor(0, 1); - ui->splitter->setStretchFactor(1, 0); + // Set initial size of the splitter + ui->splitter->setStretchFactor(0, 1); + ui->splitter->setStretchFactor(1, 0); - QFontMetricsF fm(font()); + QFontMetricsF fm(font()); - if(mChannelPostsModel->getMode() == RsGxsChannelPostsModel::TREE_MODE_GRID) - for(int i=0;icolumnCount();++i) - ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(i,font(),ui->postsTree->width())); + if(mChannelPostsModel->getMode() == RsGxsChannelPostsModel::TREE_MODE_GRID) + for(int i=0;icolumnCount();++i) + ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(i,font(),ui->postsTree->width())); - /* Setup UI helper */ + /* Setup UI helper */ - /* Connect signals */ - connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg())); - connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool))); - connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); + /* Connect signals */ + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg())); + connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool))); + connect(NotifyQt::getInstance(), SIGNAL(settingsChanged()), this, SLOT(settingsChanged())); - ui->postButton->setText(tr("Add new post")); - - /* add filter actions */ + ui->postButton->setText(tr("Add new post")); + + /* add filter actions */ ui->filterLineEdit->setPlaceholderText(tr("Search...")); - connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); + connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); ui->postsTree->setPlaceholderText(tr("No posts available in this channel")); ui->postsTree->setMinimumWidth(COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font()).height()+1); connect(ui->postsTree,SIGNAL(sizeChanged(QSize)),this,SLOT(handlePostsTreeSizeChange(QSize))); - /* Set initial section sizes */ - QHeaderView * channelpostfilesheader = ui->channelPostFiles_TV->header () ; - QHeaderView * channelfilesheader = ui->channelFiles_TV->header () ; + /* Set initial section sizes */ + QHeaderView * channelpostfilesheader = ui->channelPostFiles_TV->header () ; + QHeaderView * channelfilesheader = ui->channelFiles_TV->header () ; - channelpostfilesheader->resizeSection (RsGxsChannelPostFilesModel::COLUMN_FILES_NAME, fm.width("RetroShare-v0.6.5-1487-g6714648e5-Windows-x64-portable-20200518-Qt-5.14.2.7z")); - channelfilesheader->resizeSection (RsGxsChannelPostFilesModel::COLUMN_FILES_NAME, fm.width("RetroShare-v0.6.5-1487-g6714648e5-Windows-x64-portable-20200518-Qt-5.14.2.7z")); + channelpostfilesheader->resizeSection (RsGxsChannelPostFilesModel::COLUMN_FILES_NAME, fm.width("RetroShare-v0.6.5-1487-g6714648e5-Windows-x64-portable-20200518-Qt-5.14.2.7z")); + channelfilesheader->resizeSection (RsGxsChannelPostFilesModel::COLUMN_FILES_NAME, fm.width("RetroShare-v0.6.5-1487-g6714648e5-Windows-x64-portable-20200518-Qt-5.14.2.7z")); - /* Initialize feed widget */ - //ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder); - //ui->feedWidget->setFilterCallback(filterItem); + /* Initialize feed widget */ + //ui->feedWidget->setSortRole(ROLE_PUBLISH, Qt::DescendingOrder); + //ui->feedWidget->setFilterCallback(filterItem); - /* load settings */ - processSettings(true); + /* load settings */ + processSettings(true); ui->channelPostFiles_TV->setColumnHidden(RsGxsChannelPostFilesModel::COLUMN_FILES_DATE, true); // no need to show this here. - /* Initialize subscribe button */ - QIcon icon; + /* Initialize subscribe button */ + QIcon icon; icon.addPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/redled.png"), QIcon::Normal, QIcon::On); icon.addPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/start.png"), QIcon::Normal, QIcon::Off); #ifdef TO_REMOVE - mAutoDownloadAction = new QAction(icon, "", this); - mAutoDownloadAction->setCheckable(true); - connect(mAutoDownloadAction, SIGNAL(triggered()), this, SLOT(toggleAutoDownload())); + mAutoDownloadAction = new QAction(icon, "", this); + mAutoDownloadAction->setCheckable(true); + connect(mAutoDownloadAction, SIGNAL(triggered()), this, SLOT(toggleAutoDownload())); - ui->subscribeToolButton->addSubscribedAction(mAutoDownloadAction); + ui->subscribeToolButton->addSubscribedAction(mAutoDownloadAction); setAutoDownload(false); #endif - ui->commentsDialog->setTokenService(rsGxsChannels->getTokenService(),rsGxsChannels); + ui->commentsDialog->setGxsService(rsGxsChannels); - /* Initialize GUI */ - settingsChanged(); + /* Initialize GUI */ + settingsChanged(); setGroupId(channelId); - mChannelPostsModel->updateChannel(channelId); + mChannelPostsModel->updateChannel(channelId); - mEventHandlerId = 0; - // Needs to be asynced because this function is called by another thread! - rsEvents->registerEventsHandler( [this](std::shared_ptr event) + mEventHandlerId = 0; + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); }, mEventHandlerId, RsEventType::GXS_CHANNELS ); } -void GxsChannelPostsWidgetWithModel::updateZoomFactor(bool zoom_or_unzoom) +void GxsChannelPostsWidgetWithModel::keyPressEvent(QKeyEvent *e) { - mChannelPostsDelegate->zoom(zoom_or_unzoom); + QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); + + if(index.isValid() && mChannelPostsModel->getMode() == RsGxsChannelPostsModel::TREE_MODE_GRID) + { + int n = mChannelPostsModel->columnCount(index.row())-1; + + if(e->key() == Qt::Key_Left && index.column()==0) + { + ui->postsTree->setCurrentIndex(index.siblingAtColumn(n)); + e->accept(); + return; + } + if(e->key() == Qt::Key_Right && index.column()==n) + { + ui->postsTree->setCurrentIndex(index.siblingAtColumn(0)); + e->accept(); + return; + } + } + + GxsMessageFrameWidget::keyPressEvent(e); +} +void GxsChannelPostsWidgetWithModel::resizeEvent(QResizeEvent *e) +{ + GxsMessageFrameWidget::resizeEvent(e); + updateZoomFactor(0); +} +void GxsChannelPostsWidgetWithModel::currentTabChanged(int t) +{ + switch(t) + { + case CHANNEL_TABS_DETAILS: + case CHANNEL_TABS_FILES: + ui->showUnread_TB->setHidden(true); + ui->viewType_TB->setHidden(true); + break; + + case CHANNEL_TABS_POSTS: + ui->showUnread_TB->setHidden(false); + ui->viewType_TB->setHidden(false); + updateZoomFactor(0); // fixes a bug due to the widget now knowing its size when not displayed. + break; + } +} +void GxsChannelPostsWidgetWithModel::onUpdateZoomFactor(bool zoom_or_unzoom) +{ + if(zoom_or_unzoom) + updateZoomFactor(1); + else + updateZoomFactor(-1); +} +void GxsChannelPostsWidgetWithModel::updateZoomFactor(int what_to_do) +{ + if(what_to_do != 0) + mChannelPostsDelegate->zoom(what_to_do > 0); + + QSize s = ui->postsTree->size(); + int n_columns = std::max(1,(int)floor(s.width() / (float)(mChannelPostsDelegate->cellSize(0,font(),s.width())))); + mChannelPostsModel->setNumColumns(n_columns); // forces the update for(int i=0;icolumnCount();++i) ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(i,font(),ui->postsTree->width())); - QSize s = ui->postsTree->size(); - - int n_columns = std::max(1,(int)floor(s.width() / (mChannelPostsDelegate->cellSize(0,font(),s.width())))); - - mChannelPostsModel->setNumColumns(n_columns); // forces the update - - ui->postsTree->dataChanged(QModelIndex(),QModelIndex()); + if(what_to_do) + mChannelPostsModel->triggerViewUpdate(true,false); + else + mChannelPostsModel->triggerViewUpdate(false,true); } void GxsChannelPostsWidgetWithModel::sortColumnPostFiles(int col,Qt::SortOrder so) @@ -557,10 +613,10 @@ void GxsChannelPostsWidgetWithModel::postContextMenu(const QPoint&) } menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink())); - if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) - menu.addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/pencil-edit-button.png"), tr("Edit"), this, SLOT(editPost())); + if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) + menu.addAction(FilesDefs::getIconFromQtResourcePath(":/icons/png/pencil-edit-button.png"), tr("Edit"), this, SLOT(editPost())); - menu.exec(QCursor::pos()); + menu.exec(QCursor::pos()); } void GxsChannelPostsWidgetWithModel::markMessageUnread() @@ -622,7 +678,7 @@ void GxsChannelPostsWidgetWithModel::switchView() selectItem(msg_id); ui->postsTree->setFocus(); - mChannelPostsModel->triggerViewUpdate(); // This is already called by setMode(), but the model cannot know how many + mChannelPostsModel->triggerViewUpdate(false,true); // This is already called by setMode(), but the model cannot know how many // columns is actually has until we call handlePostsTreeSizeChange(), so // we have to call it again here. } @@ -630,29 +686,29 @@ void GxsChannelPostsWidgetWithModel::switchView() void GxsChannelPostsWidgetWithModel::copyMessageLink() { try - { - if (groupId().isNull()) - throw std::runtime_error("No channel currently selected!"); + { + if (groupId().isNull()) + throw std::runtime_error("No channel currently selected!"); - QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); + QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); - if(!index.isValid()) - throw std::runtime_error("No post under mouse!"); + if(!index.isValid()) + throw std::runtime_error("No post under mouse!"); - RsGxsChannelPost post = index.data(Qt::UserRole).value() ; + RsGxsChannelPost post = index.data(Qt::UserRole).value() ; - if(post.mMeta.mMsgId.isNull()) - throw std::runtime_error("Post has empty MsgId!"); + if(post.mMeta.mMsgId.isNull()) + throw std::runtime_error("Post has empty MsgId!"); - RetroShareLink link = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, groupId(), post.mMeta.mMsgId, QString::fromUtf8(post.mMeta.mMsgName.c_str())); + RetroShareLink link = RetroShareLink::createGxsMessageLink(RetroShareLink::TYPE_CHANNEL, groupId(), post.mMeta.mMsgId, QString::fromUtf8(post.mMeta.mMsgName.c_str())); - if (!link.valid()) - throw std::runtime_error("Link is not valid"); + if (!link.valid()) + throw std::runtime_error("Link is not valid"); - QList urls; - urls.push_back(link); - RSLinkClipboard::copyLinks(urls); - } + QList urls; + urls.push_back(link); + RSLinkClipboard::copyLinks(urls); + } catch(std::exception& e) { QMessageBox::critical(NULL,tr("Link creation error"),tr("Link could not be created: ")+e.what()); @@ -681,41 +737,41 @@ void GxsChannelPostsWidgetWithModel::download() rsFiles->FileRequest(file.mName, file.mHash, file.mSize, destination, RS_FILE_REQ_ANONYMOUS_ROUTING, sources); } - ui->postDAll_PB->hide(); + ui->postDAll_PB->hide(); } void GxsChannelPostsWidgetWithModel::updateDAll_PB() { - QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); - RsGxsChannelPost post = index.data(Qt::UserRole).value() ; + QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); + RsGxsChannelPost post = index.data(Qt::UserRole).value() ; - size_t newFileToDl = 0; - uint64_t newFileTotalSize = 0; - QString newFilesDetails; + size_t newFileToDl = 0; + uint64_t newFileTotalSize = 0; + QString newFilesDetails; - for(auto& file:post.mFiles) - { - FileInfo fileInfo; - if (!rsFiles->FileDetails(file.mHash, RS_FILE_HINTS_DOWNLOAD | RS_FILE_HINTS_SPEC_ONLY, fileInfo)) { - ++newFileToDl; - newFileTotalSize += file.mSize; - newFilesDetails += QString::fromUtf8(file.mName.c_str()) + " " + misc::friendlyUnit(file.mSize) + "\n"; - } - } + for(auto& file:post.mFiles) + { + FileInfo fileInfo; + if (!rsFiles->FileDetails(file.mHash, RS_FILE_HINTS_DOWNLOAD | RS_FILE_HINTS_SPEC_ONLY, fileInfo)) { + ++newFileToDl; + newFileTotalSize += file.mSize; + newFilesDetails += QString::fromUtf8(file.mName.c_str()) + " " + misc::friendlyUnit(file.mSize) + "\n"; + } + } - ui->postDAll_PB->setHidden(newFileToDl == 0); - ui->postDAll_PB->setToolTip((newFileToDl == 1 ? tr("Download this file:") : tr("Download All these %1 files:").arg(newFileToDl) ) + "\n" - + newFilesDetails - + tr("Totaling: %1").arg(misc::friendlyUnit(newFileTotalSize))); + ui->postDAll_PB->setHidden(newFileToDl == 0); + ui->postDAll_PB->setToolTip((newFileToDl == 1 ? tr("Download this file:") : tr("Download All these %1 files:").arg(newFileToDl) ) + "\n" + + newFilesDetails + + tr("Totaling: %1").arg(misc::friendlyUnit(newFileTotalSize))); } void GxsChannelPostsWidgetWithModel::editPost() { QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); - RsGxsChannelPost post = index.data(Qt::UserRole).value() ; + RsGxsChannelPost post = index.data(Qt::UserRole).value() ; - CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(post.mMeta.mGroupId,post.mMeta.mMsgId); + CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(post.mMeta.mGroupId,post.mMeta.mMsgId); msgDialog->show(); } @@ -725,7 +781,7 @@ void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s,bool forc return; int n_columns = std::max(1,(int)floor(s.width() / (mChannelPostsDelegate->cellSize(0,font(),ui->postsTree->width())))); - std::cerr << "nb columns: " << n_columns << " current count=" << mChannelPostsModel->columnCount() << std::endl; + RsDbg() << "nb columns: " << n_columns << " current count=" << mChannelPostsModel->columnCount() ; // save current post. The setNumColumns() indeed loses selection @@ -744,69 +800,126 @@ void GxsChannelPostsWidgetWithModel::handlePostsTreeSizeChange(QSize s,bool forc void GxsChannelPostsWidgetWithModel::handleEvent_main_thread(std::shared_ptr event) { - const RsGxsChannelEvent *e = dynamic_cast(event.get()); + const RsGxsChannelEvent *e = dynamic_cast(event.get()); - if(!e) - return; + if(!e) + return; - switch(e->mChannelEventCode) - { - case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]]; + switch(e->mChannelEventCode) + { + case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]]; case RsChannelEventCode::DELETED_CHANNEL: // [[fallthrough]]; - case RsChannelEventCode::NEW_COMMENT: // [[fallthrough]]; - case RsChannelEventCode::NEW_VOTE: // [[fallthrough]]; case RsChannelEventCode::UPDATED_CHANNEL: // [[fallthrough]]; - case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]]; - case RsChannelEventCode::UPDATED_MESSAGE: case RsChannelEventCode::RECEIVED_PUBLISH_KEY: case RsChannelEventCode::SYNC_PARAMETERS_UPDATED: { - if(e->mChannelGroupId == groupId()) - updateDisplay(true); - } + if(e->mChannelGroupId == groupId()) + updateDisplay(true,false); + } + break; - default: - break; - } + case RsChannelEventCode::READ_STATUS_CHANGED: // This is already handled by setMsgReadStatus() that has been called and issued this event. + break; + + case RsChannelEventCode::NEW_MESSAGE: + { + if(e->mChannelGroupId == groupId()) + { + RsDbg() << "Received new message in current channel, msgId=" << e->mChannelMsgId ; + + RsThread::async([this,E=*e]() // dereferencing to make a copy that will survive while e is deleted by the parent thread. + { + // 1 - get message data from p3GxsChannels. No need for pointers here, because we send only a single post to postToObject() + // At this point we dont know what kind of msg id we have. It can be a vote, a comment or an actual message. + + std::vector posts; + std::vector comments; + std::vector votes; + + const auto& msg_id(E.mChannelMsgId); + const auto& grp_id(E.mChannelGroupId); + + if(!rsGxsChannels->getChannelContent(grp_id, { msg_id }, posts,comments,votes) || posts.size() != 1) + { + RsErr() << " failed to retrieve channel message data for channel/msg " << grp_id << "/" << msg_id; + return; + } + + // 2 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [post=posts[0],this]() + { + std::set added_files,removed_files; + + mChannelPostsModel->updateSinglePost(post,added_files,removed_files); + + std::set added_filesi,removed_filesi; + + for(auto f:added_files) added_filesi.insert(ChannelPostFileInfo(f,post.mMeta.mPublishTs)); + for(auto f:removed_files) removed_filesi.insert(ChannelPostFileInfo(f,post.mMeta.mPublishTs)); + + mChannelFilesModel->update_files(added_filesi,removed_filesi); + + },this); + }); + } + } + break; + + case RsChannelEventCode::NEW_COMMENT: + + if(e->mChannelGroupId == groupId() && e->mChannelThreadId != ui->commentsDialog->messageId()) + mChannelPostsModel->updatePostWithNewComment(e->mChannelThreadId); [[fallthrough]]; + + case RsChannelEventCode::NEW_VOTE: + + if(e->mChannelGroupId == groupId() && e->mChannelThreadId == ui->commentsDialog->messageId()) + ui->commentsDialog->refresh(); + break; + + default: + break; + + } } void GxsChannelPostsWidgetWithModel::showPostDetails() { QModelIndex index = ui->postsTree->selectionModel()->currentIndex(); - RsGxsChannelPost post = index.data(Qt::UserRole).value() ; + RsGxsChannelPost post = index.data(Qt::UserRole).value() ; #ifdef DEBUG_CHANNEL_POSTS_WIDGET - std::cerr << "showPostDetails: current index is " << index.row() << "," << index.column() << std::endl; + RsDbg() << "showPostDetails: current index is " << index.row() << "," << index.column() ; #endif - //QTextDocument doc; - //doc.setHtml(post.mMsg.c_str()); + //QTextDocument doc; + //doc.setHtml(post.mMsg.c_str()); - if(post.mMeta.mPublishTs == 0) - { - ui->postDetails_TE->clear(); - ui->postLogo_LB->hide(); - ui->postName_LB->hide(); - ui->postTime_LB->hide(); - mChannelPostFilesModel->clear(); - ui->details_TW->setEnabled(false); - //mLastSelectedPosts[groupId()].clear(); + if(post.mMeta.mPublishTs == 0) + { + ui->postDetails_TE->clear(); + ui->postLogo_LB->hide(); + ui->postName_LB->hide(); + ui->postTime_LB->hide(); + mChannelPostFilesModel->clear(); + ui->details_TW->setEnabled(false); + //mLastSelectedPosts[groupId()].clear(); - return; - } - ui->details_TW->setEnabled(true); + return; + } + ui->details_TW->setEnabled(true); - ui->postLogo_LB->show(); - ui->postName_LB->show(); - ui->postTime_LB->show(); + ui->postLogo_LB->show(); + ui->postName_LB->show(); + ui->postTime_LB->show(); #ifdef DEBUG_CHANNEL_POSTS_WIDGET - std::cerr << "showPostDetails: setting mLastSelectedPosts[groupId()] to current post Id " << post.mMeta.mMsgId << ". Previous value: " << mLastSelectedPosts[groupId()] << std::endl; + RsDbg() << "showPostDetails: setting mLastSelectedPosts[groupId()] to current post Id " << post.mMeta.mMsgId << ". Previous value: " << mLastSelectedPosts[groupId()] ; #endif - mLastSelectedPosts[groupId()] = post.mMeta.mMsgId; + mLastSelectedPosts[groupId()] = post.mMeta.mMsgId; - std::list files; - for(auto& file:post.mFiles) - files.push_back(ChannelPostFileInfo(file,post.mMeta.mPublishTs)); + std::list files; + for(auto& file:post.mFiles) + files.push_back(ChannelPostFileInfo(file,post.mMeta.mPublishTs)); mChannelPostFilesModel->setFiles(files); @@ -816,46 +929,51 @@ void GxsChannelPostsWidgetWithModel::showPostDetails() ui->commentsDialog->commentLoad(post.mMeta.mGroupId, all_msgs_versions, post.mMeta.mMsgId,true); #ifdef DEBUG_CHANNEL_POSTS_WIDGET - std::cerr << "Showing details about selected index : "<< index.row() << "," << index.column() << std::endl; + RsDbg() << "Showing details about selected index : "<< index.row() << "," << index.column() ; #endif ui->postDetails_TE->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), /* RSHTML_FORMATTEXT_EMBED_SMILEYS |*/ RSHTML_FORMATTEXT_EMBED_LINKS)); - QPixmap postImage; + QPixmap postImage; - if (post.mThumbnail.mData != NULL) - GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData, post.mThumbnail.mSize, postImage,GxsIdDetails::ORIGINAL); - else - postImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); + if (post.mThumbnail.mData != NULL) + GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData, post.mThumbnail.mSize, postImage,GxsIdDetails::ORIGINAL); + else + postImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); int W = QFontMetricsF(font()).height() * 8; // Using fixed width so that the post will not displace the text when we browse. - ui->postLogo_LB->setPixmap(postImage); - ui->postLogo_LB->setFixedSize(W,postImage.height()/(float)postImage.width()*W); + ui->postLogo_LB->setPixmap(postImage); + ui->postLogo_LB->setFixedSize(W,postImage.height()/(float)postImage.width()*W); - ui->postName_LB->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())); + ui->postName_LB->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())); - ui->postTime_LB->setText(QDateTime::fromMSecsSinceEpoch(post.mMeta.mPublishTs*1000).toString("MM/dd/yyyy, hh:mm")); - ui->postTime_LB->setFixedWidth(W); + ui->postTime_LB->setText(QDateTime::fromMSecsSinceEpoch(post.mMeta.mPublishTs*1000).toString("MM/dd/yyyy, hh:mm")); + ui->postTime_LB->setFixedWidth(W); //ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_FILE); //ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE); ui->channelPostFiles_TV->setAutoSelect(true); - // Now also set the post as read + // Now also set the post as read - if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus)) - { - RsGxsGrpMsgIdPair postId; - postId.second = post.mMeta.mMsgId; - postId.first = post.mMeta.mGroupId; + if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus) || post.mUnreadCommentCount > 0) + { + mChannelPostsModel->setMsgReadStatus(index,true); - RsThread::async([postId]() { rsGxsChannels->markRead(postId, true) ; } ); - } + //RsGxsGrpMsgIdPair postId; + //postId.second = post.mMeta.mMsgId; + //postId.first = post.mMeta.mGroupId; - updateDAll_PB(); + //RsThread::async([postId]() + //{ + //rsGxsChannels->setMessageReadStatus(postId, true) ; + //} ); + } + + updateDAll_PB(); } void GxsChannelPostsWidgetWithModel::updateCommentsCount(int n) @@ -865,30 +983,30 @@ void GxsChannelPostsWidgetWithModel::updateCommentsCount(int n) else ui->details_TW->setTabText(2,tr("Comments")); } -void GxsChannelPostsWidgetWithModel::updateGroupData() +void GxsChannelPostsWidgetWithModel::updateData(bool update_group_data, bool update_posts) { - if(groupId().isNull()) + if(groupId().isNull()) { // clear post, files and comment widgets showPostDetails(); - return; + return; } - RsThread::async([this]() - { - RsGxsChannelGroup group; - std::vector groups; + RsThread::async([this,update_group_data,update_posts]() + { + std::vector groups; + RsGxsChannelGroup group; - if(rsGxsChannels->getChannelsInfo(std::list{ groupId() }, groups) && groups.size()==1) + if(rsGxsChannels->getChannelsInfo(std::list{ groupId() }, groups) && groups.size()==1) group = groups[0]; else if(!rsGxsChannels->getDistantSearchResultGroupData(groupId(),group)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to get group data for channel: " << groupId() << std::endl; - return; - } + { + std::cerr << __PRETTY_FUNCTION__ << " failed to get group data for channel: " << groupId() << std::endl; + return; + } - RsQThreadUtils::postToObject( [this,group]() + RsQThreadUtils::postToObject( [this,update_group_data,update_posts,group]() { if(mGroup.mMeta.mGroupId != group.mMeta.mGroupId) // this prevents any attempt to display the wrong index. Navigate() if needed will use mNavigatePendingMsgId { @@ -900,49 +1018,61 @@ void GxsChannelPostsWidgetWithModel::updateGroupData() updateCommentsCount(0); } - mGroup = group; - mChannelPostsModel->updateChannel(groupId()); - whileBlocking(ui->filterLineEdit)->clear(); - whileBlocking(ui->showUnread_TB)->setChecked(false); + if(update_group_data) + { + mGroup = group; + insertChannelDetails(mGroup); + } - insertChannelDetails(mGroup); + if(update_posts) + { + ui->postsTree->setPlaceholderText(tr("Loading...")); + + mChannelPostsModel->updateChannel(groupId()); + + whileBlocking(ui->filterLineEdit)->clear(); + whileBlocking(ui->showUnread_TB)->setChecked(false); + } emit groupDataLoaded(); emit groupChanged(this); // signals the parent widget to e.g. update the group tab name } ); - }); + }); } void GxsChannelPostsWidgetWithModel::postChannelPostLoad() { - std::cerr << "Post channel load..." << std::endl; + std::cerr << "Post channel load..." << std::endl; - if (!mNavigatePendingMsgId.isNull()) - navigate(mNavigatePendingMsgId); + if (!mNavigatePendingMsgId.isNull()) + navigate(mNavigatePendingMsgId); - else if( (mLastSelectedPosts.count(groupId()) > 0) + else if( (mLastSelectedPosts.count(groupId()) > 0) && !mLastSelectedPosts[groupId()].isNull()) - { - QModelIndex index = mChannelPostsModel->getIndexOfMessage(mLastSelectedPosts[groupId()]); + { + QModelIndex index = mChannelPostsModel->getIndexOfMessage(mLastSelectedPosts[groupId()]); - std::cerr << "Setting current index to " << index.row() << ","<< index.column() << " for current post " - << mLastSelectedPosts[groupId()].toStdString() << std::endl; + std::cerr << "Setting current index to " << index.row() << ","<< index.column() << " for current post " + << mLastSelectedPosts[groupId()].toStdString() << std::endl; - ui->postsTree->selectionModel()->setCurrentIndex(index,QItemSelectionModel::ClearAndSelect); - ui->postsTree->scrollTo(index);//May change if model reloaded - ui->postsTree->setFocus(); - } - else - std::cerr << "No pre-selected channel post." << std::endl; + ui->postsTree->selectionModel()->setCurrentIndex(index,QItemSelectionModel::ClearAndSelect); + ui->postsTree->scrollTo(index);//May change if model reloaded + ui->postsTree->setFocus(); + } + else + std::cerr << "No pre-selected channel post." << std::endl; - std::list files; + std::list files; mChannelPostsModel->getFilesList(files); mChannelFilesModel->setFiles(files); - ui->channelFiles_TV->setAutoSelect(true); - ui->channelFiles_TV->sortByColumn(ui->channelFiles_TV->header()->sortIndicatorSection() - ,ui->channelFiles_TV->header()->sortIndicatorOrder()); + ui->channelFiles_TV->setAutoSelect(true); + ui->channelFiles_TV->sortByColumn(ui->channelFiles_TV->header()->sortIndicatorSection() + ,ui->channelFiles_TV->header()->sortIndicatorOrder()); + + // if there's no posts, this is what's going to be displayed. + ui->postsTree->setPlaceholderText(tr("No posts available in this channel.")); ui->infoPosts->setText(QString::number(mChannelPostsModel->getNumberOfPosts()) + " / " + QString::number(mGroup.mMeta.mVisibleMsgCount)); @@ -963,88 +1093,80 @@ void GxsChannelPostsWidgetWithModel::postChannelPostLoad() best = i; mChannelPostsDelegate->setAspectRatio(static_cast(best)); - mChannelPostsModel->triggerViewUpdate(); handlePostsTreeSizeChange(ui->postsTree->size(),true); // force the update + + updateZoomFactor(0); } -void GxsChannelPostsWidgetWithModel::updateDisplay(bool complete) +void GxsChannelPostsWidgetWithModel::updateDisplay(bool update_group_data,bool update_posts) { - // First, clear all widget - blank(); + // First, clear all widget + #ifdef DEBUG_CHANNEL std::cerr << "udateDisplay: groupId()=" << groupId()<< std::endl; #endif - if(groupId().isNull()) + if(groupId().isNull()) { #ifdef DEBUG_CHANNEL std::cerr << " group_id=0. Return!"<< std::endl; #endif - return; + return; } - if(mGroup.mMeta.mGroupId.isNull() && !groupId().isNull()) + if(mGroup.mMeta.mGroupId != groupId()) { #ifdef DEBUG_FORUMS std::cerr << " inconsistent group data. Reloading!"<< std::endl; #endif - complete = true; + update_group_data = true; + update_posts = true; } - if(complete) // need to update the group data, reload the messages etc. - { -#warning csoler 2020-06-02 : todo - //saveExpandedItems(mSavedExpandedMessages); - //if(mGroupId != mChannelPostsModel->currentGroupId()) - // mThreadId.clear(); - - updateGroupData(); - - return; - } + updateData(update_group_data,update_posts); } GxsChannelPostsWidgetWithModel::~GxsChannelPostsWidgetWithModel() { - rsEvents->unregisterEventsHandler(mEventHandlerId); - // save settings - processSettings(false); + rsEvents->unregisterEventsHandler(mEventHandlerId); + // save settings + processSettings(false); //delete(mAutoDownloadAction); delete mFilesDelegate; - delete ui; + delete ui; } void GxsChannelPostsWidgetWithModel::processSettings(bool load) { - QHeaderView *channelpostfilesheader = ui->channelPostFiles_TV->header () ; - QHeaderView *channelfilesheader = ui->channelFiles_TV->header () ; - - Settings->beginGroup(QString("ChannelPostsWidget")); + QHeaderView *channelpostfilesheader = ui->channelPostFiles_TV->header () ; + QHeaderView *channelfilesheader = ui->channelFiles_TV->header () ; - if (load) { + Settings->beginGroup(QString("ChannelPostsWidget")); - // state of files tree - channelpostfilesheader->restoreState(Settings->value("PostFilesTree").toByteArray()); - channelfilesheader->restoreState(Settings->value("FilesTree").toByteArray()); + if (load) { - // state of splitter - ui->splitter->restoreState(Settings->value("SplitterChannelPosts").toByteArray()); - } else { - // state of files tree - Settings->setValue("PostFilesTree", channelpostfilesheader->saveState()); - Settings->setValue("FilesTree", channelfilesheader->saveState()); + // state of files tree + channelpostfilesheader->restoreState(Settings->value("PostFilesTree").toByteArray()); + channelfilesheader->restoreState(Settings->value("FilesTree").toByteArray()); - // state of splitter - Settings->setValue("SplitterChannelPosts", ui->splitter->saveState()); - } + // state of splitter + ui->splitter->restoreState(Settings->value("SplitterChannelPosts").toByteArray()); + } else { + // state of files tree + Settings->setValue("PostFilesTree", channelpostfilesheader->saveState()); + Settings->setValue("FilesTree", channelfilesheader->saveState()); - Settings->endGroup(); + // state of splitter + Settings->setValue("SplitterChannelPosts", ui->splitter->saveState()); + } + + Settings->endGroup(); } void GxsChannelPostsWidgetWithModel::settingsChanged() { - mUseThread = Settings->getChannelLoadThread(); + mUseThread = Settings->getChannelLoadThread(); - //mStateHelper->setWidgetVisible(ui->progressBar, mUseThread); + //mStateHelper->setWidgetVisible(ui->progressBar, mUseThread); } QString GxsChannelPostsWidgetWithModel::groupName(bool) @@ -1064,15 +1186,15 @@ void GxsChannelPostsWidgetWithModel::groupNameChanged(const QString &/*name*/) QIcon GxsChannelPostsWidgetWithModel::groupIcon() { - /* CHANNEL IMAGE */ - QPixmap chanImage; - if (mGroup.mImage.mData != NULL) { - GxsIdDetails::loadPixmapFromData(mGroup.mImage.mData, mGroup.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL); - } else { - chanImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); - } + /* CHANNEL IMAGE */ + QPixmap chanImage; + if (mGroup.mImage.mData != NULL) { + GxsIdDetails::loadPixmapFromData(mGroup.mImage.mData, mGroup.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL); + } else { + chanImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); + } - return QIcon(chanImage); + return QIcon(chanImage); } /*************************************************************************************/ @@ -1082,50 +1204,50 @@ QIcon GxsChannelPostsWidgetWithModel::groupIcon() // Callback from Widget->FeedHolder->ServiceDialog->CommentContainer->CommentDialog, void GxsChannelPostsWidgetWithModel::openComments(uint32_t /*type*/, const RsGxsGroupId &groupId, const QVector& msg_versions,const RsGxsMessageId &msgId, const QString &title) { - emit loadComment(groupId, msg_versions,msgId, title); + emit loadComment(groupId, msg_versions,msgId, title); } void GxsChannelPostsWidgetWithModel::createMsg() { - if (groupId().isNull()) { - return; - } + if (groupId().isNull()) { + return; + } - if (!IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) { - return; - } + if (!IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) { + return; + } - CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(groupId()); - msgDialog->show(); + CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(groupId()); + msgDialog->show(); - /* window will destroy itself! */ + /* window will destroy itself! */ } void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGroup &group) { // save selection if needed - /* IMAGE */ - QPixmap chanImage; - if (group.mImage.mData != NULL) { - GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL); - } else { + /* IMAGE */ + QPixmap chanImage; + if (group.mImage.mData != NULL) { + GxsIdDetails::loadPixmapFromData(group.mImage.mData, group.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL); + } else { chanImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE); - } + } if(group.mMeta.mGroupName.empty()) - ui->channelName_LB->setText(tr("[No name]")); + ui->channelName_LB->setText(tr("[No name]")); else - ui->channelName_LB->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); + ui->channelName_LB->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); - ui->logoLabel->setPixmap(chanImage); + ui->logoLabel->setPixmap(chanImage); ui->logoLabel->setFixedSize(QSize(ui->logoLabel->height()*chanImage.width()/(float)chanImage.height(),ui->logoLabel->height())); // make the logo have the same aspect ratio than the original image - ui->postButton->setEnabled(bool(group.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)); + ui->postButton->setEnabled(bool(group.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_PUBLISH)); #ifdef TO_REMOVE - bool autoDownload ; - rsGxsChannels->getChannelAutoDownload(group.mMeta.mGroupId,autoDownload); - setAutoDownload(autoDownload); + bool autoDownload ; + rsGxsChannels->getChannelAutoDownload(group.mMeta.mGroupId,autoDownload); + setAutoDownload(autoDownload); #endif setSubscribeButtonText(group.mMeta.mGroupId,group.mMeta.mSubscribeFlags, group.mMeta.mPop); @@ -1150,12 +1272,12 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou } - ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount)); + ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount)); - if(group.mMeta.mLastPost==0) - ui->infoLastPost->setText(tr("Never")); - else - ui->infoLastPost->setText(DateTime::formatLongDateTime(group.mMeta.mLastPost)); + if(group.mMeta.mLastPost==0) + ui->infoLastPost->setText(tr("Never")); + else + ui->infoLastPost->setText(DateTime::formatLongDateTime(group.mMeta.mLastPost)); uint32_t current_sync_time = GxsGroupFrameDialog::checkDelay(rsGxsChannels->getSyncPeriod(group.mMeta.mGroupId))/86400 ; @@ -1181,78 +1303,91 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou ui->infoSyncTimeLabel->setText(sync_string); - QString formatDescription = QString::fromUtf8(group.mDescription.c_str()); + QString formatDescription = QString::fromUtf8(group.mDescription.c_str()); - unsigned int formatFlag = RSHTML_FORMATTEXT_EMBED_LINKS; + unsigned int formatFlag = RSHTML_FORMATTEXT_EMBED_LINKS; - // embed smileys ? - if (Settings->valueFromGroup(QString("ChannelPostsWidget"), QString::fromUtf8("Emoteicons_ChannelDecription"), true).toBool()) { - formatFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS; - } + // embed smileys ? + if (Settings->valueFromGroup(QString("ChannelPostsWidget"), QString::fromUtf8("Emoteicons_ChannelDecription"), true).toBool()) { + formatFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS; + } - formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag); + formatDescription = RsHtml().formatText(NULL, formatDescription, formatFlag); - ui->infoDescription->setText(formatDescription); + ui->infoDescription->setText(formatDescription); - ui->infoAdministrator->setId(group.mMeta.mAuthorId) ; + ui->infoAdministrator->setId(group.mMeta.mAuthorId) ; - if(!group.mMeta.mAuthorId.isNull()) - { - RetroShareLink link = RetroShareLink::createMessage(group.mMeta.mAuthorId, ""); - ui->infoAdministrator->setText(link.toHtml()); - } - else - ui->infoAdministrator->setText("[No contact author]"); + if(!group.mMeta.mAuthorId.isNull()) + { + RetroShareLink link = RetroShareLink::createMessage(group.mMeta.mAuthorId, ""); + ui->infoAdministrator->setText(link.toHtml()); + } + else + ui->infoAdministrator->setText("[No contact author]"); - ui->infoCreated->setText(DateTime::formatLongDateTime(group.mMeta.mPublishTs)); + ui->infoCreated->setText(DateTime::formatLongDateTime(group.mMeta.mPublishTs)); - QString distrib_string ( "[unknown]" ); + QString distrib_string ( "[unknown]" ); - switch((RsGxsCircleType)group.mMeta.mCircleType) - { - case RsGxsCircleType::PUBLIC: distrib_string = tr("Public") ; - break ; - case RsGxsCircleType::EXTERNAL: - { - RsGxsCircleDetails det ; + switch((RsGxsCircleType)group.mMeta.mCircleType) + { + case RsGxsCircleType::PUBLIC: distrib_string = tr("Public") ; + break ; + case RsGxsCircleType::EXTERNAL: + { + RsGxsCircleDetails det ; - // !! What we need here is some sort of CircleLabel, which loads the circle and updates the label when done. + // !! What we need here is some sort of CircleLabel, which loads the circle and updates the label when done. - if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,det)) - distrib_string = tr("Restricted to members of circle \"")+QString::fromUtf8(det.mCircleName.c_str()) +"\""; - else - distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ; - } - break ; - case RsGxsCircleType::YOUR_EYES_ONLY: distrib_string = tr("Your eyes only"); - break ; - case RsGxsCircleType::LOCAL: distrib_string = tr("You and your friend nodes"); - break ; - default: - std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl; - } + if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,det)) + distrib_string = tr("Restricted to members of circle \"")+QString::fromUtf8(det.mCircleName.c_str()) +"\""; + else + distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ; + } + break ; + case RsGxsCircleType::YOUR_EYES_ONLY: distrib_string = tr("Your eyes only"); + break ; + case RsGxsCircleType::LOCAL: distrib_string = tr("You and your friend nodes"); + break ; + default: + std::cerr << "(EE) badly initialised group distribution ID = " << group.mMeta.mCircleType << std::endl; + } - ui->infoDistribution->setText(distrib_string); + ui->infoDistribution->setText(distrib_string); #ifdef TODO - ui->infoWidget->show(); - ui->feedWidget->hide(); - ui->fileWidget->hide(); + ui->infoWidget->show(); + ui->feedWidget->hide(); + ui->fileWidget->hide(); - //ui->feedToolButton->setEnabled(false); - //ui->fileToolButton->setEnabled(false); + //ui->feedToolButton->setEnabled(false); + //ui->fileToolButton->setEnabled(false); #endif setSubscribeButtonText(group.mMeta.mGroupId,group.mMeta.mSubscribeFlags, group.mMeta.mPop); showPostDetails(); } - -void GxsChannelPostsWidgetWithModel::showChannelFilesContextMenu(QPoint /*p*/) +void GxsChannelPostsWidgetWithModel::showChannelFilesContextMenu(QPoint p) { - QMenu contextMnu(this) ; + QModelIndex index = ui->channelFiles_TV->indexAt(p); - QAction *action = contextMnu.addAction(QIcon(), tr("Copy Retroshare link"), this, SLOT(copyChannelFilesLink())); - action->setData(QVariant::fromValue(sender())); + if(!index.isValid()) + return; + + QMenu contextMnu(this) ; + contextMnu.addAction(QIcon(), tr("Copy Retroshare link"), this, SLOT(copyChannelFilesLink()))->setData(QVariant::fromValue(index)); + contextMnu.exec(QCursor::pos()); +} +void GxsChannelPostsWidgetWithModel::showChannelPostFilesContextMenu(QPoint p) +{ + QModelIndex index = ui->channelPostFiles_TV->indexAt(p); + + if(!index.isValid()) + return; + + QMenu contextMnu(this) ; + contextMnu.addAction(QIcon(), tr("Copy Retroshare link"), this, SLOT(copyChannelFilesLink()))->setData(QVariant::fromValue(index)); contextMnu.exec(QCursor::pos()); } @@ -1260,16 +1395,11 @@ void GxsChannelPostsWidgetWithModel::copyChannelFilesLink() { // Block the popup if no results available QAction *action = dynamic_cast(sender()); - RSTreeView *tree = dynamic_cast(action->data().value()); - - QModelIndexList sel = tree->selectionModel()->selection().indexes(); - - if(sel.empty()) - return; + QModelIndex s = action->data().toModelIndex(); ChannelPostFileInfo file; - if(!static_cast(tree->model())->getFileData(sel.front(),file)) + if(!static_cast(s.model())->getFileData(s,file)) return; RetroShareLink link = RetroShareLink::createFile(QString::fromUtf8(file.mName.c_str()), file.mSize, QString::fromStdString(file.mHash.toStdString())); @@ -1318,70 +1448,70 @@ void GxsChannelPostsWidgetWithModel::switchOnlyUnread(bool) } void GxsChannelPostsWidgetWithModel::filterChanged(QString s) { - QStringList ql = s.split(' ',QString::SkipEmptyParts); - uint32_t count; - mChannelPostsModel->setFilter(ql,ui->showUnread_TB->isChecked(),count); - mChannelFilesModel->setFilter(ql,count); + QStringList ql = s.split(' ',QString::SkipEmptyParts); + uint32_t count; + mChannelPostsModel->setFilter(ql,ui->showUnread_TB->isChecked(),count); + mChannelFilesModel->setFilter(ql,count); } void GxsChannelPostsWidgetWithModel::blank() { - ui->postButton->setEnabled(false); - ui->subscribeToolButton->setEnabled(false); + ui->postButton->setEnabled(false); + ui->subscribeToolButton->setEnabled(false); - ui->channelName_LB->setText(tr("No Channel Selected")); - ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/channels.png")); - ui->infoPosts->setText(""); - ui->infoLastPost->setText(""); - ui->infoAdministrator->setText(""); - ui->infoDistribution->setText(""); - ui->infoCreated->setText(""); - ui->infoDescription->setText(""); + ui->channelName_LB->setText(tr("No Channel Selected")); + ui->logoLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/channels.png")); + ui->infoPosts->setText(""); + ui->infoLastPost->setText(""); + ui->infoAdministrator->setText(""); + ui->infoDistribution->setText(""); + ui->infoCreated->setText(""); + ui->infoDescription->setText(""); - mChannelPostsModel->clear(); - mChannelPostFilesModel->clear(); - ui->postDetails_TE->clear(); - ui->postLogo_LB->hide(); - ui->postName_LB->hide(); - ui->postTime_LB->hide(); - ui->postDAll_PB->hide(); - groupNameChanged(QString()); + mChannelPostsModel->clear(); + mChannelPostFilesModel->clear(); + ui->postDetails_TE->clear(); + ui->postLogo_LB->hide(); + ui->postName_LB->hide(); + ui->postTime_LB->hide(); + ui->postDAll_PB->hide(); + groupNameChanged(QString()); } bool GxsChannelPostsWidgetWithModel::navigate(const RsGxsMessageId& msgId) { - QModelIndex index = mChannelPostsModel->getIndexOfMessage(msgId); + QModelIndex index = mChannelPostsModel->getIndexOfMessage(msgId); - if(!index.isValid()) - { - std::cerr << "(EE) Cannot navigate to msg " << msgId << " in channel " << mGroup.mMeta.mGroupId << ": index unknown. Setting mNavigatePendingMsgId." << std::endl; + if(!index.isValid()) + { + std::cerr << "(EE) Cannot navigate to msg " << msgId << " in channel " << mGroup.mMeta.mGroupId << ": index unknown. Setting mNavigatePendingMsgId." << std::endl; - mNavigatePendingMsgId = msgId; // not found. That means the forum may not be loaded yet. So we keep that post in mind, for after loading. - return true; // we have to return true here, otherwise the caller will intepret the async loading as an error. - } + mNavigatePendingMsgId = msgId; // not found. That means the forum may not be loaded yet. So we keep that post in mind, for after loading. + return true; // we have to return true here, otherwise the caller will intepret the async loading as an error. + } - ui->postsTree->selectionModel()->setCurrentIndex(index,QItemSelectionModel::ClearAndSelect); - ui->postsTree->scrollTo(index);//May change if model reloaded - ui->postsTree->setFocus(); + ui->postsTree->selectionModel()->setCurrentIndex(index,QItemSelectionModel::ClearAndSelect); + ui->postsTree->scrollTo(index);//May change if model reloaded + ui->postsTree->setFocus(); - ui->channel_TW->setCurrentIndex(CHANNEL_TABS_POSTS); - ui->details_TW->setCurrentIndex(CHANNEL_TABS_DETAILS); + ui->channel_TW->setCurrentIndex(CHANNEL_TABS_POSTS); + ui->details_TW->setCurrentIndex(CHANNEL_TABS_DETAILS); - mNavigatePendingMsgId.clear(); + mNavigatePendingMsgId.clear(); - return true; + return true; } void GxsChannelPostsWidgetWithModel::subscribeGroup(bool subscribe) { - RsGxsGroupId grpId(groupId()); - if (grpId.isNull()) return; + RsGxsGroupId grpId(groupId()); + if (grpId.isNull()) return; - RsThread::async([=]() - { - rsGxsChannels->subscribeToChannel(grpId, subscribe); - } ); + RsThread::async([=]() + { + rsGxsChannels->subscribeToChannel(grpId, subscribe); + } ); } #ifdef TO_REMOVE @@ -1393,52 +1523,50 @@ void GxsChannelPostsWidgetWithModel::setAutoDownload(bool autoDl) void GxsChannelPostsWidgetWithModel::toggleAutoDownload() { - RsGxsGroupId grpId = groupId(); - if (grpId.isNull()) { - return; - } + RsGxsGroupId grpId = groupId(); + if (grpId.isNull()) { + return; + } - bool autoDownload; - if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value " - << "for channel: " << grpId.toStdString() << std::endl; - return; - } + bool autoDownload; + if(!rsGxsChannels->getChannelAutoDownload(grpId, autoDownload)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to get autodownload value " + << "for channel: " << grpId.toStdString() << std::endl; + return; + } - RsThread::async([this, grpId, autoDownload]() - { - if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload " - << "for channel: " << grpId.toStdString() << std::endl; - return; - } - }); + RsThread::async([this, grpId, autoDownload]() + { + if(!rsGxsChannels->setChannelAutoDownload(grpId, !autoDownload)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to set autodownload " + << "for channel: " << grpId.toStdString() << std::endl; + return; + } + }); } #endif class GxsChannelPostsReadData { public: - explicit GxsChannelPostsReadData(bool read) - { - mRead = read; - mLastToken = 0; - } + explicit GxsChannelPostsReadData(bool read) + { + mRead = read; + } public: - bool mRead; - uint32_t mLastToken; + bool mRead; }; -void GxsChannelPostsWidgetWithModel::setAllMessagesReadDo(bool read, uint32_t& /*token*/) +void GxsChannelPostsWidgetWithModel::setAllMessagesReadDo(bool read) { - if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) - return; + if (groupId().isNull() || !IS_GROUP_SUBSCRIBED(mGroup.mMeta.mSubscribeFlags)) + return; - //QModelIndex src_index; + //QModelIndex src_index; - mChannelPostsModel->setAllMsgReadStatus(read); + mChannelPostsModel->setAllMsgReadStatus(read); } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h index eaac53c0f..8891b57dd 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h @@ -47,7 +47,7 @@ class ChannelPostFilesDelegate: public QStyledItemDelegate Q_OBJECT public: - ChannelPostFilesDelegate(QObject *parent=0) : QStyledItemDelegate(parent){} + ChannelPostFilesDelegate(QObject *parent=0) : QStyledItemDelegate(parent){} virtual ~ChannelPostFilesDelegate(){} void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const override; @@ -104,11 +104,11 @@ public: /* GxsMessageFrameWidget */ virtual QIcon groupIcon() override; - virtual void groupIdChanged() override { updateDisplay(true); } + virtual void groupIdChanged() override { updateDisplay(true,true); } virtual QString groupName(bool) override; virtual bool navigate(const RsGxsMessageId&) override; - void updateDisplay(bool complete); + void updateDisplay(bool update_group_data, bool update_posts); #ifdef TODO /* FeedHolder */ @@ -137,11 +137,13 @@ protected: #endif /* GxsMessageFrameWidget */ - virtual void setAllMessagesReadDo(bool read, uint32_t &token) override; + virtual void setAllMessagesReadDo(bool read) override; + virtual void resizeEvent(QResizeEvent *e) override; + virtual void keyPressEvent(QKeyEvent *e) override; private slots: void showPostDetails(); - void updateGroupData(); + void updateData(bool update_group_data,bool update_posts); void download(); void updateDAll_PB(); void createMsg(); @@ -154,20 +156,23 @@ private slots: void editPost(); void postContextMenu(const QPoint&); void copyMessageLink(); - void updateZoomFactor(bool zoom_or_unzoom); + void onUpdateZoomFactor(bool zoom_or_unzoom); void switchView(); void switchOnlyUnread(bool b); void markMessageUnread(); public slots: + void currentTabChanged(int t); void sortColumnFiles(int col,Qt::SortOrder so); void sortColumnPostFiles(int col,Qt::SortOrder so); void updateCommentsCount(int n); void showChannelFilesContextMenu(QPoint p); + void showChannelPostFilesContextMenu(QPoint p); void copyChannelFilesLink(); private: - void processSettings(bool load); + void updateZoomFactor(int what_to_do); // -1=unzoom, 0=nothing, 1=zoom + void processSettings(bool load); RsGxsMessageId getCurrentItemId() const; void selectItem(const RsGxsMessageId& msg_id); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui index 4bdae007a..6bd0fb86b 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui @@ -55,6 +55,13 @@ 0 + + + 12 + 75 + true + + Subscribe @@ -77,6 +84,12 @@ + + + 75 + true + + Qt::NoFocus @@ -181,7 +194,7 @@ - 1 + 0 @@ -189,12 +202,12 @@ - + + 25 75 true - false @@ -322,7 +335,7 @@ <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - Posts (locally / at friends): + Items (locally / at friends): @@ -521,7 +534,7 @@ p, li { white-space: pre-wrap; } - + 75 @@ -644,33 +657,34 @@ p, li { white-space: pre-wrap; } QLineEdit
    gui/common/LineEditClear.h
    + + RSTreeView + QTreeView +
    gui/common/RSTreeView.h
    + 1 +
    GxsIdLabel QLabel
    gui/gxs/GxsIdLabel.h
    + + ElidedLabel + QLabel +
    gui/common/ElidedLabel.h
    + 1 +
    SubscribeToolButton QToolButton
    gui/common/SubscribeToolButton.h
    - - RSTreeView - QTreeView -
    gui/common/RSTreeView.h
    - 1 -
    GxsCommentDialog QWidget
    gui/gxs/GxsCommentDialog.h
    1
    - - StyledElidedLabel - QLabel -
    gui/common/StyledElidedLabel.h
    -
    diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp index 3cf29ecf1..4236b6f04 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.cpp @@ -19,6 +19,7 @@ *******************************************************************************/ #include "CreateGxsForumMsg.h" +#include "ui_CreateGxsForumMsg.h" #include #include @@ -39,6 +40,7 @@ #include "util/HandleRichText.h" #include "util/misc.h" +#include "util/qtthreadsutils.h" #include #include @@ -53,67 +55,64 @@ /** Constructor */ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId& mOId, const RsGxsId& posterId, bool isModerating) : QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), - mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId),mIsModerating(isModerating) + mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId),mIsModerating(isModerating), + ui(new Ui::CreateGxsForumMsg) { /* Invoke the Qt Designer generated object setup routine */ - ui.setupUi(this); + ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose, true); - /* Setup Queue */ - mForumQueue = new TokenQueue(rsGxsForums->getTokenService(), this); - mCirclesQueue = new TokenQueue(rsGxsCircles->getTokenService(), this); - /* Setup UI helper */ mStateHelper = new UIStateHelper(this); - mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui.postButton); - mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui.innerFrame); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui.forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui.forumSubject); - mStateHelper->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui.forumName); + mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->postButton); + mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->innerFrame); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumSubject, false); + mStateHelper->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName); - mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui.postButton); - mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui.innerFrame); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumSubject); - mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName); + mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->postButton); + mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->innerFrame); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumSubject, false); + mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName); - mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.postButton); - mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.innerFrame); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName); - mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumSubject); - mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName); + mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->postButton); + mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->innerFrame); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName); + mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumSubject, false); + mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName); QString text = mOId.isNull()?(pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message")):tr("Edit Message"); setWindowTitle(text); if (!mOId.isNull()) - ui.postButton->setText(tr ("Update")); + ui->postButton->setText(tr ("Update")); - ui.forumMessage->setPlaceholderText(tr ("Text")); + ui->forumMessage->setPlaceholderText(tr ("Text")); - ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); - ui.headerFrame->setHeaderText(text); + ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png")); + ui->headerFrame->setHeaderText(text); - ui.generateSpinBox->setEnabled(false); + ui->generateSpinBox->setEnabled(false); Settings->loadWidgetInformation(this); - connect(ui.hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); + connect(ui->hashBox, SIGNAL(fileHashingFinished(QList)), this, SLOT(fileHashingFinished(QList))); // connect up the buttons. - connect(ui.postButton, SIGNAL(clicked()), this, SLOT(createMsg())); - connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - connect(ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); - connect(ui.attachFileButton, SIGNAL(clicked()), this, SLOT(addFile())); - connect(ui.attachPictureButton, SIGNAL(clicked()), this, SLOT(addPicture())); - connect(ui.forumMessage, SIGNAL(textChanged()), this, SLOT(checkLength())); - connect(ui.generateCheckBox, SIGNAL(toggled(bool)), ui.generateSpinBox, SLOT(setEnabled(bool))); + connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg())); + connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + connect(ui->emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums())); + connect(ui->attachFileButton, SIGNAL(clicked()), this, SLOT(addFile())); + connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addPicture())); + connect(ui->forumMessage, SIGNAL(textChanged()), this, SLOT(checkLength())); + connect(ui->generateCheckBox, SIGNAL(toggled(bool)), ui->generateSpinBox, SLOT(setEnabled(bool))); setAcceptDrops(true); - ui.hashBox->setDropWidget(this); - ui.hashBox->setAutoHide(false); + ui->hashBox->setDropWidget(this); + ui->hashBox->setAutoHide(false); mParentMsgLoaded = false; mForumMetaLoaded = false; @@ -121,11 +120,11 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage newMsg(); - ui.hashGroupBox->hide(); + ui->hashGroupBox->hide(); #ifndef ENABLE_GENERATE - ui.generateCheckBox->hide(); - ui.generateSpinBox->hide(); + ui->generateCheckBox->hide(); + ui->generateSpinBox->hide(); #endif processSettings(true); } @@ -133,8 +132,9 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage CreateGxsForumMsg::~CreateGxsForumMsg() { processSettings(false); - delete(mForumQueue); - delete(mCirclesQueue); + + delete ui; + } void CreateGxsForumMsg::processSettings(bool load) @@ -147,14 +147,14 @@ void CreateGxsForumMsg::processSettings(bool load) RsGxsId gxs_id(Settings->value("IDChooser", QString::fromStdString(RsGxsId().toStdString())).toString().toStdString()); if(!gxs_id.isNull() && rsIdentity->isOwnId(gxs_id)) - ui.idChooser->setChosenId(gxs_id); + ui->idChooser->setChosenId(gxs_id); } else { // state of ID Chooser combobox RsGxsId id; - if(ui.idChooser->getChosenId(id)) + if(ui->idChooser->getChosenId(id)) Settings->setValue("IDChooser", QString::fromStdString(id.toStdString())); } @@ -176,11 +176,11 @@ void CreateGxsForumMsg::newMsg() std::set id_set ; id_set.insert(mPosterId) ; - ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId); - ui.idChooser->setIdConstraintSet(id_set); + ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId); + ui->idChooser->setIdConstraintSet(id_set); } else - ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId); + ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId); if (mForumId.isNull()) { mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); @@ -190,126 +190,119 @@ void CreateGxsForumMsg::newMsg() mStateHelper->clear(CREATEGXSFORUMMSG_FORUMINFO); mStateHelper->clear(CREATEGXSFORUMMSG_PARENTMSG); mStateHelper->clear(CREATEGXSFORUMMSG_ORIGMSG); - ui.forumName->setText(tr("No Forum")); + ui->forumName->setText(tr("No Forum")); return; } - {/* request Data */ - mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, true); + mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, true); - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_META; + if (mParentId.isNull()) + { + mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false); + mParentMsgLoaded = true; + } + else + { + mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, true); + mParentMsgLoaded = false; + } - std::list groupIds; - groupIds.push_back(mForumId); + if (mOrigMsgId.isNull()) + { + mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false); + mOrigMsgLoaded = true; + } + else + { + mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, true); + mOrigMsgLoaded = false; + } - //std::cerr << "ForumsV2Dialog::newMsg() Requesting Group Summary(" << mForumId << ")"<< std::endl; + RsThread::async( [this]() + { + // We only need group Meta information, but forums do not provide it currently - uint32_t token; - mForumQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEGXSFORUMMSG_FORUMINFO); - }/* request Data */ + std::vector forums_info; + rsGxsForums->getForumsInfo(std::list{ mForumId },forums_info); - if (mParentId.isNull()) { - mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true); - mParentMsgLoaded = true; - } else { - mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, true); + // Load parent message - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + RsGxsForumMsg parent_msg; - GxsMsgReq msgIds; - std::set &vect = msgIds[mForumId]; - vect.insert(mParentId); + if(!mParentId.isNull()) + { + std::vector parent_msgs; + rsGxsForums->getForumContent(mForumId,std::set{ mParentId },parent_msgs); - //std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")"; - //std::cerr << std::endl; + if(parent_msgs.size() == 1) + parent_msg = *parent_msgs.begin(); + else + RsErr() << "Cannot get parent message " << mParentId << " from forum." ; + } - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_PARENTMSG); - } + // Load original message (edit mode) - if (mOrigMsgId.isNull()) { - mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true); - mOrigMsgLoaded = true; - } else { - mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, true); + RsGxsForumMsg orig_msg; - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + if(!mOrigMsgId.isNull()) + { + std::vector orig_msgs; + rsGxsForums->getForumContent(mForumId,std::set{ mOrigMsgId },orig_msgs); - GxsMsgReq msgIds; - std::set &vect = msgIds[mForumId]; - vect.insert(mOrigMsgId); + if(orig_msgs.size() == 1) + orig_msg = *orig_msgs.begin(); + else + RsErr() << "Cannot get orig message " << mOrigMsgId << " from forum." ; + } - //std::cerr << "ForumsV2Dialog::newMsg() Requesting Parent Summary(" << mParentId << ")"; - //std::cerr << std::endl; + // Now update GUI with all that nice data - uint32_t token; - mForumQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, CREATEGXSFORUMMSG_ORIGMSG); - } + RsQThreadUtils::postToObject( [this,forums_info,parent_msg,orig_msg]() + { + if(forums_info.size() != 1) + { + RsErr() << "Cannot retrieve group information for forum " << mForumId ; + + return; + } + auto fg(forums_info.front()); + + mForumMetaLoaded = true; + mForumMeta = fg.mMeta; + + if(!parent_msg.mMsg.empty()) + { + mParentMsg = parent_msg; + mParentMsgLoaded = true; + } + if(!orig_msg.mMsg.empty()) + { + mOrigMsg = orig_msg; + mOrigMsgLoaded = true; + } + + if(!mForumMeta.mCircleId.isNull()) + loadCircleInfo(RsGxsGroupId(mForumMeta.mCircleId)); + + // Now update the GUI + + mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, mParentMsgLoaded); + mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false); + + mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, mOrigMsgLoaded); + mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false); + + mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, mForumMetaLoaded); + mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false); + + loadFormInformation(); + + },this); + }); } void CreateGxsForumMsg::loadFormInformation() { - if (!mOrigMsgId.isNull()) - { - if (mOrigMsgLoaded) { - mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true); - mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false); - } else { - //std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet"; - //std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false); - - return; - } - } - else - { - mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, true); - mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false); - } - - - if (!mParentId.isNull()) - { - if (mParentMsgLoaded) { - mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true); - mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false); - } else { - //std::cerr << "CreateGxsForumMsg::loadMsgInformation() ParentMsg not Loaded Yet"; - //std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false); - - return; - } - } - else - { - mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, true); - mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false); - } - - if (mForumMetaLoaded) { - mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, true); - mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false); - } else { - //std::cerr << "CreateGxsForumMsg::loadMsgInformation() ForumMeta not Loaded Yet"; - //std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); - - return; - } - - //std::cerr << "CreateGxsForumMsg::loadMsgInformation() Data Available!"; - //std::cerr << std::endl; - - //std::cerr << "CreateGxsForumMsg::loadMsgInformation() using signFlags=" << std::hex << mForumMeta.mSignFlags << std::dec << std::endl; - uint32_t fl = IDCHOOSER_ID_REQUIRED ; if( (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG) || (mForumMeta.mSignFlags & GXS_SERV::FLAG_AUTHOR_AUTHENTICATION_GPG_KNOWN)) @@ -318,19 +311,17 @@ void CreateGxsForumMsg::loadFormInformation() if(!mPosterId.isNull()) fl |= IDCHOOSER_NO_CREATE; - ui.idChooser->setFlags(fl) ; + ui->idChooser->setFlags(fl) ; QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str()); QString subj; if(!mOrigMsgId.isNull()) - { subj = QString::fromUtf8(mOrigMsg.mMeta.mMsgName.c_str()); - } else if (!mParentId.isNull()) { QString title = QString::fromUtf8(mParentMsg.mMeta.mMsgName.c_str()); - name += " " + tr("In Reply to") + ": "; + name += " - " + tr("In Reply to") + ": "; name += title; QString text = title; @@ -341,18 +332,19 @@ void CreateGxsForumMsg::loadFormInformation() subj = "Re: " + title; } - ui.forumName->setText(misc::removeNewLine(name)); + ui->forumName->setText(misc::removeNewLine(name)); + std::cerr << "Setting name to \"" << misc::removeNewLine(name).toStdString() << std::endl; if(!subj.isNull()) - ui.forumSubject->setText(misc::removeNewLine(subj)); + ui->forumSubject->setText(misc::removeNewLine(subj)); - if (ui.forumSubject->text().isEmpty()) + if (ui->forumSubject->text().isEmpty()) { - ui.forumSubject->setFocus(); - ui.forumSubject->setPlaceholderText(tr ("Title")); + ui->forumSubject->setFocus(); + ui->forumSubject->setPlaceholderText(tr ("Title")); } else - ui.forumMessage->setFocus(); + ui->forumMessage->setFocus(); #ifdef TOGXS if (mForumMeta.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) @@ -360,18 +352,18 @@ void CreateGxsForumMsg::loadFormInformation() if (1) #endif { - ui.signBox->setChecked(true); - ui.signBox->setEnabled(false); - ui.signBox->hide(); + ui->signBox->setChecked(true); + ui->signBox->setEnabled(false); + ui->signBox->hide(); } else { /* Uncheck sign box by default for anonymous forums */ - ui.signBox->setChecked(false); - ui.signBox->setEnabled(true); + ui->signBox->setChecked(false); + ui->signBox->setEnabled(true); } - //ui.forumMessage->setText(""); + //ui->forumMessage->setText(""); } static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; @@ -379,27 +371,27 @@ static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; void CreateGxsForumMsg::checkLength() { QString text; - RsHtml::optimizeHtml(ui.forumMessage, text); + RsHtml::optimizeHtml(ui->forumMessage, text); std::wstring msg = text.toStdWString(); int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length(); if(charRemains >= 0) { text = tr("It remains %1 characters after HTML conversion.").arg(charRemains); - ui.infoLabel->setStyleSheet("QLabel#infoLabel { }"); + ui->info_Label->setStyleSheet("QLabel#info_Label { }"); }else{ text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); - ui.infoLabel->setStyleSheet("QLabel#infoLabel {color: red; font: bold; }"); + ui->info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }"); } - ui.postButton->setToolTip(text); - ui.postButton->setEnabled(charRemains>=0); - ui.infoLabel->setText(text); + ui->postButton->setToolTip(text); + ui->postButton->setEnabled(charRemains>=0); + ui->info_Label->setText(text); } void CreateGxsForumMsg::createMsg() { - QString name = misc::removeNewLine(ui.forumSubject->text()); + QString name = misc::removeNewLine(ui->forumSubject->text()); QString desc; - RsHtml::optimizeHtml(ui.forumMessage, desc); + RsHtml::optimizeHtml(ui->forumMessage, desc); if(name.isEmpty() | desc.isEmpty()) { /* error message */ @@ -428,9 +420,9 @@ void CreateGxsForumMsg::createMsg() if ((msg.mMsg == "") && (msg.mMeta.mMsgName == "")) return; /* do nothing */ - if (ui.signBox->isChecked()) { + if (ui->signBox->isChecked()) { RsGxsId authorId; - switch (ui.idChooser->getChosenId(authorId)) { + switch (ui->idChooser->getChosenId(authorId)) { case GxsIdChooser::KnowId: case GxsIdChooser::UnKnowId: msg.mMeta.mAuthorId = authorId; @@ -460,23 +452,23 @@ void CreateGxsForumMsg::createMsg() QMessageBox::warning(this, tr("RetroShare"),tr("Congrats, you found a bug!")+" "+QString(__FILE__)+":"+QString(__LINE__), QMessageBox::Ok, QMessageBox::Ok); return; - }//switch (ui.idChooser->getChosenId(authorId)) + }//switch (ui->idChooser->getChosenId(authorId)) } else { //std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)"; //std::cerr << std::endl; QMessageBox::warning(this, tr("RetroShare"),tr("Please choose Signing Id, it is required"), QMessageBox::Ok, QMessageBox::Ok); return; - }//if (ui.signBox->isChecked()) + }//if (ui->signBox->isChecked()) int generateCount = 0; #ifdef ENABLE_GENERATE - if (ui.generateCheckBox->isChecked()) { - generateCount = ui.generateSpinBox->value(); + if (ui->generateCheckBox->isChecked()) { + generateCount = ui->generateSpinBox->value(); if (QMessageBox::question(this, tr("Generate mass data"), tr("Do you really want to generate %1 messages ?").arg(generateCount), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) { return; }//if (QMessageBox::question(this, - }//if (ui.generateCheckBox->isChecked()) + }//if (ui->generateCheckBox->isChecked()) #endif uint32_t token; @@ -503,7 +495,7 @@ void CreateGxsForumMsg::closeEvent (QCloseEvent * /*event*/) void CreateGxsForumMsg::reject() { - if (ui.forumMessage->document()->isModified()) { + if (ui->forumMessage->document()->isModified()) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("Cancel Forum Message"), tr("Forum Message has not been sent yet!\n" @@ -524,7 +516,7 @@ void CreateGxsForumMsg::reject() void CreateGxsForumMsg::smileyWidgetForums() { - Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false); + Emoticons::showSmileyWidget(this, ui->emoticonButton, SLOT(addSmileys()), false); } void CreateGxsForumMsg::addSmileys() @@ -533,17 +525,17 @@ void CreateGxsForumMsg::addSmileys() // add trailing space smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) - if(!ui.forumMessage->textCursor().atStart() && ui.forumMessage->toPlainText()[ui.forumMessage->textCursor().position() - 1] != QChar(' ')) + if(!ui->forumMessage->textCursor().atStart() && ui->forumMessage->toPlainText()[ui->forumMessage->textCursor().position() - 1] != QChar(' ')) smiley = QString(" ") + smiley; - ui.forumMessage->textCursor().insertText(smiley); + ui->forumMessage->textCursor().insertText(smiley); } void CreateGxsForumMsg::addFile() { QStringList files; if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) { - ui.hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING); - ui.hashGroupBox->show(); + ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING); + ui->hashGroupBox->show(); } } @@ -554,7 +546,7 @@ void CreateGxsForumMsg::addPicture() QString encodedImage; if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, MAX_ALLOWED_GXS_MESSAGE_SIZE - 200)) { QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); - ui.forumMessage->textCursor().insertFragment(fragment); + ui->forumMessage->textCursor().insertFragment(fragment); } } } @@ -576,194 +568,65 @@ void CreateGxsForumMsg::fileHashingFinished(QList hashedFiles) } if (!mesgString.isEmpty()) { - ui.forumMessage->textCursor().insertHtml(mesgString); + ui->forumMessage->textCursor().insertHtml(mesgString); } - ui.forumMessage->setFocus( Qt::OtherFocusReason ); - ui.hashGroupBox->hide(); + ui->forumMessage->setFocus( Qt::OtherFocusReason ); + ui->hashGroupBox->hide(); } -void CreateGxsForumMsg::loadForumInfo(const uint32_t &token) -{ - //std::cerr << "CreateGxsForumMsg::loadForumInfo()"; - //std::cerr << std::endl; - - std::list groupInfo; - rsGxsForums->getGroupSummary(token, groupInfo); - - if (groupInfo.size() == 1) - { - RsGroupMetaData fi = groupInfo.front(); - - mForumMeta = fi; - mForumMetaLoaded = true; - - if(!fi.mCircleId.isNull()) - { - //std::cerr << "Circle ID is not null: " << fi.mCircleId << ": loading circle info to add constraint to the GXS ID chooser." << std::endl; - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - std::list groupIds; - groupIds.push_back(RsGxsGroupId(fi.mCircleId)); - uint32_t _token; - - mCirclesQueue->requestGroupInfo(_token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds, CREATEGXSFORUMMSG_CIRCLENFO); - } - - loadFormInformation(); - } - else - { - std::cerr << "CreateGxsForumMsg::loadForumInfo() ERROR INVALID Number of Forums"; - std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false); - mStateHelper->setLoading(CREATEGXSFORUMMSG_FORUMINFO, false); - } -} -void CreateGxsForumMsg::loadForumCircleInfo(const uint32_t& token) +void CreateGxsForumMsg::loadCircleInfo(const RsGxsGroupId& circle_id) { //std::cerr << "Loading forum circle info" << std::endl; - std::vector circle_grp_v ; - rsGxsCircles->getGroupData(token, circle_grp_v); - - if (circle_grp_v.empty()) + RsThread::async( [circle_id,this]() { - std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl; - return ; - } - - if (circle_grp_v.size() != 1) - { - std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl; - return ; - } - - RsGxsCircleGroup cg = circle_grp_v.front(); + std::vector circle_grp_v ; + rsGxsCircles->getCirclesInfo(std::list{ circle_id }, circle_grp_v); - mForumCircleData = cg; - mForumCircleLoaded = true; - - //std::cerr << "Loaded content of circle " << cg.mMeta.mGroupId << std::endl; - - //for(std::set::const_iterator it(cg.mInvitedMembers.begin());it!=cg.mInvitedMembers.end();++it) - // std::cerr << " added constraint to circle element " << *it << std::endl; - - ui.idChooser->setIdConstraintSet(cg.mInvitedMembers) ; - ui.idChooser->setFlags(IDCHOOSER_NO_CREATE | ui.idChooser->flags()) ; // since there's a circle involved, no ID creation can be needed - - RsGxsId tmpid ; - if(ui.idChooser->countEnabledEntries() == 0) - { - QMessageBox::information(NULL,tr("No compatible ID for this forum"),tr("None of your identities is allowed to post in this forum. This could be due to the forum being limited to a circle that contains none of your identities, or forum flags requiring a PGP-signed identity.")) ; - close() ; - } -} - -void CreateGxsForumMsg::loadOrigMsg(const uint32_t &token) -{ - //std::cerr << "CreateGxsForumMsg::loadParentMsg()"; - //std::cerr << std::endl; - - // Only grab one.... ignore more (shouldn't be any). - std::vector msgs; - if (rsGxsForums->getMsgData(token, msgs)) - { - if (msgs.size() != 1) - { - /* error */ - std::cerr << "CreateGxsForumMsg::loadOrigMsg() ERROR wrong number of msgs"; - std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_ORIGMSG, false); - mStateHelper->setLoading(CREATEGXSFORUMMSG_ORIGMSG, false); - - return; - } - - mOrigMsg = msgs[0]; - mOrigMsgLoaded = true; - - loadFormInformation(); - } -} - - -void CreateGxsForumMsg::loadParentMsg(const uint32_t &token) -{ - //std::cerr << "CreateGxsForumMsg::loadParentMsg()"; - //std::cerr << std::endl; - - // Only grab one.... ignore more (shouldn't be any). - std::vector msgs; - if (rsGxsForums->getMsgData(token, msgs)) - { - if (msgs.size() != 1) - { - /* error */ - std::cerr << "CreateGxsForumMsg::loadParentMsg() ERROR wrong number of msgs"; - std::cerr << std::endl; - - mStateHelper->setActive(CREATEGXSFORUMMSG_PARENTMSG, false); - mStateHelper->setLoading(CREATEGXSFORUMMSG_PARENTMSG, false); - - return; - } - - mParentMsg = msgs[0]; - mParentMsgLoaded = true; - - loadFormInformation(); - } -} - -void CreateGxsForumMsg::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - //std::cerr << "CreateGxsForum::loadRequest() UserType: " << req.mUserType; - //std::cerr << std::endl; - - if (queue == mForumQueue) - { - /* now switch on req */ - switch(req.mUserType) - { - case CREATEGXSFORUMMSG_FORUMINFO: - loadForumInfo(req.mToken); - break; - case CREATEGXSFORUMMSG_ORIGMSG: - loadOrigMsg(req.mToken); - break; - case CREATEGXSFORUMMSG_PARENTMSG: - loadParentMsg(req.mToken); - break; - default: - std::cerr << "CreateGxsForumMsg::loadRequest() UNKNOWN UserType " << req.mUserType << " for token request in mForumQueue"; - std::cerr << std::endl; - } - } - - if(queue == mCirclesQueue) + if (circle_grp_v.empty()) { - switch(req.mUserType) - { - case CREATEGXSFORUMMSG_CIRCLENFO: - loadForumCircleInfo(req.mToken) ; - break ; - default: - std::cerr << "CreateGxsForumMsg::loadRequest() UNKNOWN UserType " << req.mUserType << " for token request in mCirclesQueue"; - std::cerr << std::endl; - } + std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl; + return ; } + + if (circle_grp_v.size() != 1) + { + std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl; + return ; + } + + RsGxsCircleGroup cg = circle_grp_v.front(); + + RsQThreadUtils::postToObject( [cg,this]() + { + mForumCircleData = cg; + mForumCircleLoaded = true; + + //std::cerr << "Loaded content of circle " << cg.mMeta.mGroupId << std::endl; + + //for(std::set::const_iterator it(cg.mInvitedMembers.begin());it!=cg.mInvitedMembers.end();++it) + // std::cerr << " added constraint to circle element " << *it << std::endl; + + ui->idChooser->setIdConstraintSet(cg.mInvitedMembers) ; + ui->idChooser->setFlags(IDCHOOSER_NO_CREATE | ui->idChooser->flags()) ; // since there's a circle involved, no ID creation can be needed + + RsGxsId tmpid ; + if(ui->idChooser->countEnabledEntries() == 0) + { + QMessageBox::information(NULL,tr("No compatible ID for this forum"),tr("None of your identities is allowed to post in this forum. This could be due to the forum being limited to a circle that contains none of your identities, or forum flags requiring a PGP-signed identity.")) ; + close() ; + } + }, this); + }); } + void CreateGxsForumMsg::setSubject(const QString& msg) { - ui.forumSubject->setText(msg); + ui->forumSubject->setText(msg); } void CreateGxsForumMsg::insertPastedText(const QString& msg) { - ui.forumMessage->append(msg); + ui->forumMessage->append(msg); } diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h index 0bb2b22b2..8697fbbc3 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.h @@ -21,16 +21,19 @@ #ifndef _CREATE_GXSFORUM_MSG_DIALOG_H #define _CREATE_GXSFORUM_MSG_DIALOG_H -#include "ui_CreateGxsForumMsg.h" - -#include "util/TokenQueue.h" +#include #include #include +#include "gui/common/HashBox.h" + +namespace Ui { + class CreateGxsForumMsg; +} class UIStateHelper; -class CreateGxsForumMsg : public QDialog, public TokenResponse +class CreateGxsForumMsg : public QDialog { Q_OBJECT @@ -39,7 +42,6 @@ public: ~CreateGxsForumMsg(); void newMsg(); /* cleanup */ - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); void insertPastedText(const QString& msg) ; void setSubject(const QString& msg); @@ -58,15 +60,11 @@ private slots: protected: void closeEvent (QCloseEvent * event); + void loadCircleInfo(const RsGxsGroupId& circle_id); private: void processSettings(bool load); void loadFormInformation(); - void loadForumInfo(const uint32_t &token); - void loadParentMsg(const uint32_t &token); - void loadOrigMsg(const uint32_t &token); - void loadForumCircleInfo(const uint32_t &token); - RsGxsGroupId mForumId; RsGxsCircleId mCircleId ; RsGxsMessageId mParentId; @@ -84,13 +82,10 @@ private: RsGroupMetaData mForumMeta; RsGxsCircleGroup mForumCircleData ; - TokenQueue *mForumQueue; - TokenQueue *mCirclesQueue; - UIStateHelper *mStateHelper; /** Qt Designer generated object */ - Ui::CreateGxsForumMsg ui; + Ui::CreateGxsForumMsg *ui; }; #endif diff --git a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui index 7af77f2d5..10105a630 100644 --- a/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui +++ b/retroshare-gui/src/gui/gxsforums/CreateGxsForumMsg.ui @@ -17,7 +17,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png
    - + 0 @@ -37,17 +37,17 @@
    - + QFrame::StyledPanel QFrame::Raised - + - + 0 @@ -68,7 +68,7 @@ QFrame::Raised - + 0 @@ -82,7 +82,7 @@ 0 - + 50 @@ -119,9 +119,9 @@ Forum Post - + - + @@ -141,8 +141,8 @@ <!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:'MS Sans Serif'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<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-family:'MS Sans Serif';"><br /></p></body></html> +</style></head><body style=" font-family:'MS Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<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:8.25pt;"><br /></p></body></html> @@ -160,7 +160,7 @@ p, li { white-space: pre-wrap; } QFrame::Sunken - + 0 @@ -249,7 +249,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -298,7 +298,7 @@ p, li { white-space: pre-wrap; } Attach files via drag and drop - + @@ -322,7 +322,7 @@ p, li { white-space: pre-wrap; } - + @@ -341,7 +341,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -355,6 +355,13 @@ p, li { white-space: pre-wrap; } + + + 12 + 75 + true + + Post @@ -375,17 +382,6 @@ p, li { white-space: pre-wrap; } - - HashBox - QScrollArea -
    gui/common/HashBox.h
    - 1 -
    - - MimeTextEdit - QTextEdit -
    gui/common/MimeTextEdit.h
    -
    GxsIdChooser QComboBox @@ -397,10 +393,20 @@ p, li { white-space: pre-wrap; }
    gui/common/HeaderFrame.h
    1
    + + HashBox + QScrollArea +
    gui/common/HashBox.h
    + 1 +
    + + MimeTextEdit + QTextEdit +
    gui/common/MimeTextEdit.h
    +
    - diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp index 424091867..16d0c307b 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumGroupDialog.cpp @@ -63,7 +63,7 @@ GxsForumGroupDialog::GxsForumGroupDialog(QWidget *parent) : GxsGroupDialog(ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent) { ui.pubKeyShare_cb->setEnabled(true) ; - ui.label_2->setToolTip(tr("

    Put one of your identities here to allow others to send feedback and also have moderator rights on the forum. You may as well leave that field blank and keep the forum anonymously administrated.

    ")); + ui.idChooserLabel->setToolTip(tr("

    Put one of your identities here to allow others to send feedback and also have moderator rights on the forum. You may as well leave that field blank and keep the forum anonymously administrated.

    ")); } GxsForumGroupDialog::GxsForumGroupDialog(Mode mode, RsGxsGroupId groupId, QWidget *parent) @@ -151,6 +151,7 @@ bool GxsForumGroupDialog::service_loadGroup(const RsGxsGenericGroupData *data, M // Local information. Description should be handled here. setSelectedModerators(pgroup->mAdminList.ids); + ui.adminsList->sortByChecked(true); mGroupData = *pgroup; // keeps the private information diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp index 3d168acf7..b68a50173 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.cpp @@ -117,14 +117,14 @@ int RsGxsForumModel::columnCount(const QModelIndex &/*parent*/) const return COLUMN_THREAD_NB_COLUMNS ; } -std::vector > RsGxsForumModel::getPostVersions(const RsGxsMessageId& mid) const +std::vector > RsGxsForumModel::getPostVersions(const RsGxsMessageId& mid) const { auto it = mPostVersions.find(mid); if(it != mPostVersions.end()) return it->second; else - return std::vector >(); + return std::vector >(); } bool RsGxsForumModel::getPostData(const QModelIndex& i,ForumModelPostEntry& fmpe) const @@ -563,11 +563,14 @@ QVariant RsGxsForumModel::toolTipRole(const ForumModelPostEntry& fmpe,int column return QVariant(); int S = QFontMetricsF(QApplication::font()).height(); - QImage pix( (*icons.begin()).pixmap(QSize(4*S,4*S)).toImage()); + QImage pix( (*icons.begin()).pixmap(QSize(5*S,5*S)).toImage()); QString embeddedImage; - if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, -1)) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
    " + embeddedImage + "" + comment + "
    "; + } return comment; } @@ -743,7 +746,7 @@ void RsGxsForumModel::clear() emit forumLoaded(); } -void RsGxsForumModel::setPosts(const RsGxsForumGroup& group, const std::vector& posts,const std::map > >& post_versions) +void RsGxsForumModel::setPosts(const RsGxsForumGroup& group, const std::vector& posts,const std::map > >& post_versions) { preMods(); @@ -797,7 +800,6 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id) // 1 - get message data from p3GxsForums std::list forumIds; - std::vector msg_metas; std::vector groups; forumIds.push_back(group_id); @@ -808,21 +810,19 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id) return; } - if(!rsGxsForums->getForumMsgMetaData(group_id,msg_metas)) - { - std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum message info for forum " << group_id << std::endl; - return; - } + // 2 - sort messages into a proper hierarchy - // 2 - sort the messages into a proper hierarchy - - auto post_versions = new std::map > >() ; - std::vector *vect = new std::vector(); + auto post_versions = new std::map > >() ; + std::vector *vect = new std::vector(); RsGxsForumGroup group = groups[0]; - computeMessagesHierarchy(group,msg_metas,*vect,*post_versions); + if(!rsGxsForums->getForumPostsHierarchy(group,*vect,*post_versions)) + { + std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve forum hierarchy of message info for forum " << group_id << std::endl; + return; + } - // 3 - update the model in the UI thread. + // 3 - update the model in the UI thread. RsQThreadUtils::postToObject( [group,vect,post_versions,this]() { @@ -832,10 +832,14 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id) * Qt::QueuedConnection is important! */ - setPosts(group,*vect,*post_versions) ; + std::vector psts; + for(const auto& p:*vect) + psts.push_back( ForumModelPostEntry(p)); - delete vect; - delete post_versions; + setPosts(group,psts,*post_versions) ; + + delete vect; + delete post_versions; }, this ); @@ -843,379 +847,7 @@ void RsGxsForumModel::update_posts(const RsGxsGroupId& group_id) }); } -ForumModelIndex RsGxsForumModel::addEntry(std::vector& posts,const ForumModelPostEntry& entry,ForumModelIndex parent) -{ - uint32_t N = posts.size(); - posts.push_back(entry); - posts[N].mParent = parent; - posts[parent].mChildren.push_back(N); -#ifdef DEBUG_FORUMMODEL - std::cerr << "Added new entry " << N << " children of " << parent << std::endl; -#endif - if(N == parent) - std::cerr << "(EE) trying to add a post as its own parent!" << std::endl; - return ForumModelIndex(N); -} - -void RsGxsForumModel::generateMissingItem(const RsGxsMessageId &msgId,ForumModelPostEntry& entry) -{ - entry.mPostFlags = ForumModelPostEntry::FLAG_POST_IS_MISSING ; - entry.mTitle = std::string(tr("[ ... Missing Message ... ]").toUtf8()); - entry.mMsgId = msgId; - entry.mAuthorId.clear(); - entry.mPublishTs=0; - entry.mReputationWarningLevel = 3; -} - -void RsGxsForumModel::convertMsgToPostEntry(const RsGxsForumGroup& mForumGroup,const RsMsgMetaData& msg, bool /*useChildTS*/, ForumModelPostEntry& fentry) -{ - fentry.mTitle = msg.mMsgName; - fentry.mAuthorId = msg.mAuthorId; - fentry.mMsgId = msg.mMsgId; - fentry.mPublishTs = msg.mPublishTs; - fentry.mPostFlags = 0; - fentry.mMsgStatus = msg.mMsgStatus; - - if(mForumGroup.mPinnedPosts.ids.find(msg.mMsgId) != mForumGroup.mPinnedPosts.ids.end()) - fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_PINNED; - - // Early check for a message that should be hidden because its author - // is flagged with a bad reputation - - computeReputationLevel(mForumGroup.mMeta.mSignFlags,fentry); -} - -void RsGxsForumModel::computeReputationLevel(uint32_t forum_sign_flags,ForumModelPostEntry& fentry) -{ - uint32_t idflags =0; - RsReputationLevel reputation_level = - rsReputations->overallReputationLevel(fentry.mAuthorId, &idflags); - - if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE) - fentry.mPostFlags |= ForumModelPostEntry::FLAG_POST_IS_REDACTED; - else - fentry.mPostFlags &= ~ForumModelPostEntry::FLAG_POST_IS_REDACTED; - - // We use a specific item model for forums in order to handle the post pinning. - - if(reputation_level == RsReputationLevel::UNKNOWN) - fentry.mReputationWarningLevel = 3 ; - else if(reputation_level == RsReputationLevel::LOCALLY_NEGATIVE) - fentry.mReputationWarningLevel = 2 ; - else if(reputation_level < rsGxsForums->minReputationForForwardingMessages(forum_sign_flags,idflags)) - fentry.mReputationWarningLevel = 1 ; - else - fentry.mReputationWarningLevel = 0 ; -} - -static bool decreasing_time_comp(const std::pair& e1,const std::pair& e2) { return e2.first < e1.first ; } - -void RsGxsForumModel::computeMessagesHierarchy(const RsGxsForumGroup& forum_group, - const std::vector& msgs_metas_array, - std::vector& posts, - std::map > >& mPostVersions - ) -{ - std::cerr << "updating messages data with " << msgs_metas_array.size() << " messages" << std::endl; - -#ifdef DEBUG_FORUMS - std::cerr << "Retrieved group data: " << std::endl; - std::cerr << " Group ID: " << forum_group.mMeta.mGroupId << std::endl; - std::cerr << " Admin lst: " << forum_group.mAdminList.ids.size() << " elements." << std::endl; - for(auto it(forum_group.mAdminList.ids.begin());it!=forum_group.mAdminList.ids.end();++it) - std::cerr << " " << *it << std::endl; - std::cerr << " Pinned Post: " << forum_group.mPinnedPosts.ids.size() << " messages." << std::endl; - for(auto it(forum_group.mPinnedPosts.ids.begin());it!=forum_group.mPinnedPosts.ids.end();++it) - std::cerr << " " << *it << std::endl; -#endif - - /* get messages */ - std::map msgs; - - for(uint32_t i=0;i > threadStack; - std::map > kids_array ; - std::set missing_parents; - - // First of all, remove all older versions of posts. This is done by first adding all posts into a hierarchy structure - // and then removing all posts which have a new versions available. The older versions are kept appart. - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Collecting post versions" << std::endl; -#endif - mPostVersions.clear(); - - for ( auto msgIt = msgs.begin(); msgIt != msgs.end();++msgIt) - { - if(!msgIt->second.mOrigMsgId.isNull() && msgIt->second.mOrigMsgId != msgIt->second.mMsgId) - { -#ifdef DEBUG_FORUMS - std::cerr << " Post " << msgIt->second.mMeta.mMsgId << " is a new version of " << msgIt->second.mMeta.mOrigMsgId << std::endl; -#endif - auto msgIt2 = msgs.find(msgIt->second.mOrigMsgId); - - // Ensuring that the post exists allows to only collect the existing data. - - if(msgIt2 == msgs.end()) - continue ; - - // Make sure that the author is the same than the original message, or is a moderator. This should always happen when messages are constructed using - // the UI but nothing can prevent a nasty user to craft a new version of a message with his own signature. - - if(msgIt2->second.mAuthorId != msgIt->second.mAuthorId) - { - if( !IS_FORUM_MSG_MODERATION(msgIt->second.mMsgFlags) ) // if authors are different the moderation flag needs to be set on the editing msg - continue ; - - if( !forum_group.canEditPosts(msgIt->second.mAuthorId)) // if author is not a moderator, continue - continue ; - } - - // always add the post a self version - - if(mPostVersions[msgIt->second.mOrigMsgId].empty()) - mPostVersions[msgIt->second.mOrigMsgId].push_back(std::make_pair(msgIt2->second.mPublishTs,msgIt2->second.mMsgId)) ; - - mPostVersions[msgIt->second.mOrigMsgId].push_back(std::make_pair(msgIt->second.mPublishTs,msgIt->second.mMsgId)) ; - } - } - - // The following code assembles all new versions of a given post into the same array, indexed by the oldest version of the post. - - for(auto it(mPostVersions.begin());it!=mPostVersions.end();++it) - { - auto& v(it->second) ; - - for(size_t i=0;ifirst) - { - RsGxsMessageId sub_msg_id = v[i].second ; - - auto it2 = mPostVersions.find(sub_msg_id); - - if(it2 != mPostVersions.end()) - { - for(size_t j=0;jsecond.size();++j) - if(it2->second[j].second != sub_msg_id) // dont copy it, since it is already present at slot i - v.push_back(it2->second[j]) ; - - mPostVersions.erase(it2) ; // it2 is never equal to it - } - } - } - } - - - // Now remove from msg ids, all posts except the most recent one. And make the mPostVersion be indexed by the most recent version of the post, - // which corresponds to the item in the tree widget. - -#ifdef DEBUG_FORUMS - std::cerr << "Final post versions: " << std::endl; -#endif - std::map > > mTmp; - std::map most_recent_versions ; - - for(auto it(mPostVersions.begin());it!=mPostVersions.end();++it) - { -#ifdef DEBUG_FORUMS - std::cerr << "Original post: " << it.key() << std::endl; -#endif - // Finally, sort the posts from newer to older - - std::sort(it->second.begin(),it->second.end(),decreasing_time_comp) ; - -#ifdef DEBUG_FORUMS - std::cerr << " most recent version " << (*it)[0].first << " " << (*it)[0].second << std::endl; -#endif - for(size_t i=1;isecond.size();++i) - { - msgs.erase(it->second[i].second) ; - -#ifdef DEBUG_FORUMS - std::cerr << " older version " << (*it)[i].first << " " << (*it)[i].second << std::endl; -#endif - } - - mTmp[it->second[0].second] = it->second ; // index the versions map by the ID of the most recent post. - - // Now make sure that message parents are consistent. Indeed, an old post may have the old version of a post as parent. So we need to change that parent - // to the newest version. So we create a map of which is the most recent version of each message, so that parent messages can be searched in it. - - for(size_t i=1;isecond.size();++i) - most_recent_versions[it->second[i].second] = it->second[0].second ; - } - mPostVersions = mTmp ; - - // The next step is to find the top level thread messages. These are defined as the messages without - // any parent message ID. - - // this trick is needed because while we remove messages, the parents a given msg may already have been removed - // and wrongly understand as a missing parent. - - std::map kept_msgs; - - for ( auto msgIt = msgs.begin(); msgIt != msgs.end();++msgIt) - { - - if(msgIt->second.mParentId.isNull()) - { - - /* add all threads */ - const RsMsgMetaData& msg = msgIt->second; - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Adding TopLevel Thread: mId: " << msg.mMsgId << std::endl; -#endif - - ForumModelPostEntry entry; - convertMsgToPostEntry(forum_group,msg, mUseChildTS, entry); - - ForumModelIndex entry_index = addEntry(posts,entry,0); - - //if (!mFlatView) - threadStack.push_back(std::make_pair(msg.mMsgId,entry_index)) ; - - //calculateExpand(msg, item); - //mItems.append(entry_index); - } - else - { -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Storing kid " << msgIt->first << " of message " << msgIt->second.mParentId << std::endl; -#endif - // The same missing parent may appear multiple times, so we first store them into a unique container. - - RsGxsMessageId parent_msg = msgIt->second.mParentId; - - if(msgs.find(parent_msg) == msgs.end()) - { - // also check that the message is not versionned - - std::map::const_iterator mrit = most_recent_versions.find(parent_msg) ; - - if(mrit != most_recent_versions.end()) - parent_msg = mrit->second ; - else - missing_parents.insert(parent_msg); - } - - kids_array[parent_msg].push_back(msgIt->first) ; - kept_msgs.insert(*msgIt) ; - } - } - - msgs = kept_msgs; - - // Also create a list of posts by time, when they are new versions of existing posts. Only the last one will have an item created. - - // Add a fake toplevel item for the parent IDs that we dont actually have. - - for(std::set::const_iterator it(missing_parents.begin());it!=missing_parents.end();++it) - { - // add dummy parent item - ForumModelPostEntry e ; - generateMissingItem(*it,e); - - ForumModelIndex e_index = addEntry(posts,e,0); // no parent -> parent is level 0 - //mItems.append( e_index ); - - threadStack.push_back(std::make_pair(*it,e_index)) ; - } -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Processing stack:" << std::endl; -#endif - // Now use a stack to go down the hierarchy - - while (!threadStack.empty()) - { - std::pair threadPair = threadStack.front(); - threadStack.pop_front(); - - std::map >::iterator it = kids_array.find(threadPair.first) ; - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Node: " << threadPair.first << std::endl; -#endif - if(it == kids_array.end()) - continue ; - - - for(std::list::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) - { - // We iterate through the top level thread items, and look for which message has the current item as parent. - // When found, the item is put in the thread list itself, as a potential new parent. - - auto mit = msgs.find(*it2) ; - - if(mit == msgs.end()) - { - std::cerr << "GxsForumsFillThread::run() Cannot find submessage " << *it2 << " !!!" << std::endl; - continue ; - } - - const RsMsgMetaData& msg(mit->second) ; -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() adding sub_item " << msg.mMsgId << std::endl; -#endif - - - ForumModelPostEntry e ; - convertMsgToPostEntry(forum_group,msg,mUseChildTS,e) ; - ForumModelIndex e_index = addEntry(posts,e, threadPair.second); - - //calculateExpand(msg, item); - - /* add item to process list */ - threadStack.push_back(std::make_pair(msg.mMsgId, e_index)); - - msgs.erase(mit); - } - -#ifdef DEBUG_FORUMS - std::cerr << "GxsForumsFillThread::run() Erasing entry " << it->first << " from kids tab." << std::endl; -#endif - kids_array.erase(it) ; // This is not strictly needed, but it improves performance by reducing the search space. - } - -#ifdef DEBUG_FORUMS - std::cerr << "Kids array now has " << kids_array.size() << " elements" << std::endl; - for(std::map >::const_iterator it(kids_array.begin());it!=kids_array.end();++it) - { - std::cerr << "Node " << it->first << std::endl; - for(std::list::const_iterator it2(it->second.begin());it2!=it->second.end();++it2) - std::cerr << " " << *it2 << std::endl; - } - - std::cerr << "GxsForumsFillThread::run() stopped: " << (wasStopped() ? "yes" : "no") << std::endl; -#endif -} void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,bool with_children) { @@ -1245,8 +877,8 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,bool with_children) { - int newStatus = (read_status ? mPosts[i].mMsgStatus & ~static_cast(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) - : mPosts[i].mMsgStatus | static_cast(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD)); + uint32_t newStatus = (read_status ? mPosts[i].mMsgStatus & ~static_cast(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD) + : mPosts[i].mMsgStatus | static_cast(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD)); bool bChanged = (mPosts[i].mMsgStatus != newStatus); mPosts[i].mMsgStatus = newStatus; //Remove Unprocessed and New flags @@ -1275,8 +907,8 @@ void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status, void *ref ; convertTabEntryToRefPointer(i,ref); // we dont use i+1 here because i is not a row, but an index in the mPosts tab - QModelIndex itemIndex = createIndex(i - 1, 0, ref); - emit dataChanged(itemIndex, itemIndex); + QModelIndex itemIndex = (mTreeMode == TREE_MODE_FLAT)?createIndex(i - 1, 0, ref):createIndex(mPosts[i].prow,0,ref); + emit dataChanged(itemIndex, itemIndex); } if(!with_children) @@ -1417,7 +1049,7 @@ void RsGxsForumModel::setAuthorOpinion(const QModelIndex& indx, RsOpinion op) for(uint32_t i=0;iupdateReputationLevel(mForumGroup.mMeta.mSignFlags,mPosts[i]); // notify the widgets that the data has changed. emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(0,COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL)); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h index 50de234fa..c69013c3e 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumModel.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumModel.h @@ -23,44 +23,19 @@ #include #include -// This class holds the actual hierarchy of posts, represented by identifiers -// It is responsible for auto-updating when necessary and holds a mutex to allow the Model to -// safely access the data. - -// The model contains a post in place 0 that is the parent of all posts. - -typedef uint32_t ForumModelIndex; - -struct ForumModelPostEntry +struct ForumModelPostEntry: public ForumPostEntry { - ForumModelPostEntry() : mPublishTs(0),mMostRecentTsInThread(0),mPostFlags(0),mReputationWarningLevel(0),mMsgStatus(0),prow(0) {} + ForumModelPostEntry() : mMostRecentTsInThread(0),prow(0) {} + ForumModelPostEntry(const ForumPostEntry& p) : mMostRecentTsInThread(0),prow(0) { *static_cast(this) = p; } - enum { // flags for display of posts. To be used in mPostFlags - FLAG_POST_IS_PINNED = 0x0001, - FLAG_POST_IS_MISSING = 0x0002, - FLAG_POST_IS_REDACTED = 0x0004, - FLAG_POST_HAS_UNREAD_CHILDREN = 0x0008, - FLAG_POST_HAS_READ_CHILDREN = 0x0010, - FLAG_POST_PASSES_FILTER = 0x0020, - FLAG_POST_CHILDREN_PASSES_FILTER = 0x0040, - }; - - std::string mTitle ; - RsGxsId mAuthorId ; - RsGxsMessageId mMsgId; - uint32_t mPublishTs; - uint32_t mMostRecentTsInThread; - uint32_t mPostFlags; - int mReputationWarningLevel; - int mMsgStatus; - - std::vector mChildren; - ForumModelIndex mParent; - int prow ; // parent row + uint32_t mMostRecentTsInThread; + int prow ; // parent row. Used by Qt abstract item models. }; // This class is the item model used by Qt to display the information +typedef uint32_t ForumModelIndex; + class RsGxsForumModel : public QAbstractItemModel { Q_OBJECT @@ -102,7 +77,7 @@ public: static const QString FilterString ; - std::vector > getPostVersions(const RsGxsMessageId& mid) const; + std::vector > getPostVersions(const RsGxsMessageId& mid) const; // This method will asynchroneously update the data void updateForum(const RsGxsGroupId& forumGroup); @@ -195,11 +170,11 @@ private: static void convertMsgToPostEntry(const RsGxsForumGroup &mForumGroup, const RsMsgMetaData &msg, bool useChildTS, ForumModelPostEntry& fentry); void computeMessagesHierarchy(const RsGxsForumGroup& forum_group, const std::vector &msgs_array, std::vector& posts, std::map > > &mPostVersions); - void setPosts(const RsGxsForumGroup& group, const std::vector& posts,const std::map > >& post_versions); + void setPosts(const RsGxsForumGroup& group, const std::vector& posts,const std::map > >& post_versions); void initEmptyHierarchy(std::vector& posts); std::vector mPosts ; // store the list of posts updated from rsForums. - std::map > > mPostVersions; + std::map > > mPostVersions; QColor mTextColorRead ; QColor mTextColorUnread ; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index fb962ca5c..11d04fdd8 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -276,7 +276,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget connect(ui->versions_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(changedVersion())); connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint))); - connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint))); connect(ui->forumName, SIGNAL(clicked(QPoint)), this, SLOT(showForumInfo())); ui->subscribeToolButton->hide() ; @@ -291,7 +290,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget connect(ui->threadTreeWidget, SIGNAL(clicked(QModelIndex)), this, SLOT(clickedThread(QModelIndex))); connect(ui->threadTreeWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), this, SLOT(changedSelection(const QModelIndex&,const QModelIndex&))); - connect(ui->viewBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changedViewBox())); //connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(togglethreadview())); ui->expandButton->hide(); @@ -304,7 +302,9 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString))); connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); - connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage())); + connect(ui->threadedView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleThreadedView(bool))); + connect(ui->flatView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleFlatView(bool))); + connect(ui->latestPostInThreadView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleLstPostInThreadView(bool))); /* Set own item delegate */ RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); @@ -321,6 +321,10 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget float f = QFontMetricsF(font()).height()/14.0f ; + QFontMetricsF fontMetrics(ui->threadTreeWidget->font()); + int iconHeight = fontMetrics.height() * 1.4; + ui->threadTreeWidget->setIconSize(QSize(iconHeight, iconHeight)); + /* Set header resize modes and initial section sizes */ QHeaderView * ttheader = ui->threadTreeWidget->header () ; @@ -415,7 +419,9 @@ void GxsForumThreadWidget::blank() ui->forumName->setText(""); ui->progressText->hide(); ui->progressBar->hide(); - ui->viewBox->setEnabled(false); + ui->threadedView_TB->setEnabled(false); + ui->flatView_TB->setEnabled(false); + ui->latestPostInThreadView_TB->setEnabled(false); ui->filterLineEdit->setEnabled(false); mThreadModel->clear(); @@ -450,7 +456,13 @@ void GxsForumThreadWidget::processSettings(bool load) ui->filterLineEdit->setCurrentFilter(Settings->value("filterColumn", RsGxsForumModel::COLUMN_THREAD_TITLE).toInt()); // index of viewBox - ui->viewBox->setCurrentIndex(Settings->value("viewBox", VIEW_THREADED).toInt()); + switch(Settings->value("viewBox", VIEW_THREADED).toInt()) + { + default: + case VIEW_THREADED : ui->threadedView_TB->setChecked(true); break; + case VIEW_FLAT : ui->flatView_TB->setChecked(true); break; + case VIEW_LAST_POST: ui->latestPostInThreadView_TB->setChecked(true); break; + } // state of thread tree header->restoreState(Settings->value("ThreadTree").toByteArray()); @@ -778,25 +790,6 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) contextMnu.exec(QCursor::pos()); } -void GxsForumThreadWidget::contextMenuTextBrowser(QPoint point) -{ - QMatrix matrix; - matrix.translate(ui->postText->horizontalScrollBar()->value(), ui->postText->verticalScrollBar()->value()); - - QMenu *contextMnu = ui->postText->createStandardContextMenu(matrix.map(point)); - - contextMnu->addSeparator(); - - if(ui->postText->checkImage(point)) - { - ui->actionSave_image->setData(point); - contextMnu->addAction(ui->actionSave_image); - } - - contextMnu->exec(ui->postText->viewport()->mapToGlobal(point)); - delete(contextMnu); -} - void GxsForumThreadWidget::headerContextMenuRequested(const QPoint &pos) { QMenu* header_context_menu = new QMenu(tr("Show column"), this); @@ -1044,7 +1037,9 @@ void GxsForumThreadWidget::updateForumDescription(bool success) ui->newthreadButton->show(); ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); - ui->viewBox->setEnabled(true); + ui->flatView_TB->setEnabled(true); + ui->threadedView_TB->setEnabled(true); + ui->latestPostInThreadView_TB->setEnabled(true); ui->filterLineEdit->setEnabled(true); QString anti_spam_features1 ; @@ -1198,7 +1193,7 @@ void GxsForumThreadWidget::insertMessage() // add/show combobox for versions, if applicable, and enable it. If no older versions of the post available, hide the combobox. - std::vector > post_versions = mThreadModel->getPostVersions(mOrigThreadId); + std::vector > post_versions = mThreadModel->getPostVersions(mOrigThreadId); #ifdef DEBUG_FORUMS std::cerr << "Looking into existing versions for post " << mOrigThreadId << ", thread history: " << post_versions.size() << std::endl; @@ -1486,7 +1481,7 @@ void GxsForumThreadWidget::markMsgAsUnreadChildren() markMsgAsReadUnread(false, true, false); } -void GxsForumThreadWidget::setAllMessagesReadDo(bool read, uint32_t &/*token*/) +void GxsForumThreadWidget::setAllMessagesReadDo(bool read) { markMsgAsReadUnread(read, true, true); } @@ -1806,28 +1801,25 @@ void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg) } } -void GxsForumThreadWidget::saveImage() -{ - QPoint point = ui->actionSave_image->data().toPoint(); - QTextCursor cursor = ui->postText->cursorForPosition(point); - ImageUtil::extractImage(window(), cursor); -} +void GxsForumThreadWidget::toggleThreadedView(bool b) { if(b) changedViewBox(VIEW_THREADED); } +void GxsForumThreadWidget::toggleFlatView(bool b) { if(b) changedViewBox(VIEW_FLAT); } +void GxsForumThreadWidget::toggleLstPostInThreadView(bool b) { if(b) changedViewBox(VIEW_LAST_POST); } -void GxsForumThreadWidget::changedViewBox() +void GxsForumThreadWidget::changedViewBox(int view_mode) { ui->threadTreeWidget->selectionModel()->clear(); ui->threadTreeWidget->selectionModel()->reset(); mThreadId.clear(); // save index - Settings->setValueToGroup("ForumThreadWidget", "viewBox", ui->viewBox->currentIndex()); + Settings->setValueToGroup("ForumThreadWidget", "viewBox", view_mode); - if(ui->viewBox->currentIndex() == VIEW_FLAT) + if(view_mode == VIEW_FLAT) mThreadModel->setTreeMode(RsGxsForumModel::TREE_MODE_FLAT); else mThreadModel->setTreeMode(RsGxsForumModel::TREE_MODE_TREE); - if(ui->viewBox->currentIndex() == VIEW_LAST_POST) + if(view_mode == VIEW_LAST_POST) mThreadModel->setSortMode(RsGxsForumModel::SORT_MODE_CHILDREN_PUBLISH_TS); else mThreadModel->setSortMode(RsGxsForumModel::SORT_MODE_PUBLISH_TS); @@ -1956,8 +1948,12 @@ void GxsForumThreadWidget::postForumLoading() ui->forumName->setText(QString::fromUtf8(mForumGroup.mMeta.mGroupName.c_str())); ui->threadTreeWidget->sortByColumn(RsGxsForumModel::COLUMN_THREAD_DATE, Qt::DescendingOrder); ui->threadTreeWidget->update(); - ui->viewBox->setEnabled(true); - ui->filterLineEdit->setEnabled(true); + ui->threadedView_TB->setEnabled(true); + ui->flatView_TB->setEnabled(true); + ui->flatView_TB->setEnabled(true); + ui->threadedView_TB->setEnabled(true); + ui->latestPostInThreadView_TB->setEnabled(true); + ui->filterLineEdit->setEnabled(true); recursRestoreExpandedItems(mThreadProxyModel->mapFromSource(mThreadModel->root()),mSavedExpandedMessages); //mUpdating = false; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 6df3c5c89..322c64fae 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -102,13 +102,12 @@ protected: virtual void updateDisplay(bool complete); /* GxsMessageFrameWidget */ - virtual void setAllMessagesReadDo(bool read, uint32_t &token); + virtual void setAllMessagesReadDo(bool read); void setMessageLoadingError(const QString& error); private slots: /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point); - void contextMenuTextBrowser(QPoint point); void headerContextMenuRequested(const QPoint& pos); void showForumInfo(); @@ -122,7 +121,11 @@ private slots: void replytoforummessage(); void editforummessage(); - void replyMessageData(const RsGxsForumMsg &msg); + void toggleThreadedView(bool); + void toggleFlatView(bool); + void toggleLstPostInThreadView(bool); + + void replyMessageData(const RsGxsForumMsg &msg); void editForumMessageData(const RsGxsForumMsg &msg); void replyForumMessageData(const RsGxsForumMsg &msg); void showAuthorInPeople(const RsGxsForumMsg& msg); @@ -130,8 +133,6 @@ private slots: // This method is used to perform an asynchroneous action on the message data. Any of the methods above can be used as parameter. void async_msg_action(const MsgMethod& method); - void saveImage(); - void markMsgAsRead(); void markMsgAsReadChildren(); void markMsgAsUnread(); @@ -153,7 +154,7 @@ private slots: void nextUnreadMessage(); void downloadAllFiles(); - void changedViewBox(); + void changedViewBox(int); void flagperson(); void filterColumnChanged(int column); @@ -214,7 +215,7 @@ private: unsigned int mNewCount; bool mDisplayBannedText; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorRead; QColor mTextColorUnread; QColor mTextColorUnreadChildren; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui index b5fe3f95d..5a9c51e93 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.ui @@ -6,7 +6,7 @@ 0 0 - 800 + 848 600 @@ -74,6 +74,13 @@ 0 + + + 12 + 75 + true + + Subscribe @@ -84,6 +91,12 @@
    + + + 75 + true + + Qt::NoFocus @@ -112,19 +125,29 @@ - + 0 0 + + + 12 + 75 + true + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> Forum Name + + 2 + @@ -173,22 +196,63 @@
    - - - - Lastest post in thread - - - - - Threaded View - - - - - Flat View - - + + + Threaded + + + ... + + + + :/icons/svg/threaded-view.svg:/icons/svg/threaded-view.svg + + + true + + + true + + + + + + + Flat + + + ... + + + + :/icons/svg/flat-view.svg:/icons/svg/flat-view.svg + + + true + + + true + + + + + + + Latest post in thread + + + ... + + + + :/icons/svg/lastpost-view.svg:/icons/svg/lastpost-view.svg + + + true + + + true + @@ -210,6 +274,11 @@ + + + 10 + + Qt::CustomContextMenu @@ -405,7 +474,7 @@ - + @@ -499,9 +568,6 @@ MS Sans Serif - - Qt::CustomContextMenu -
    @@ -509,52 +575,49 @@ - - - - :/images/document_save.png:/images/document_save.png - - - Save image - - - RSTextBrowser - QTextBrowser -
    gui/common/RSTextBrowser.h
    -
    - - LineEditClear - QLineEdit -
    gui/common/LineEditClear.h
    -
    - - StyledElidedLabel + ElidedLabel QLabel -
    gui/common/StyledElidedLabel.h
    -
    - - SubscribeToolButton - QToolButton -
    gui/common/SubscribeToolButton.h
    +
    gui/common/ElidedLabel.h
    + 1
    GxsIdLabel QLabel
    gui/gxs/GxsIdLabel.h
    + + LineEditClear + QLineEdit +
    gui/common/LineEditClear.h
    +
    RSImageBlockWidget QWidget
    gui/common/RSImageBlockWidget.h
    1
    + + RSTextBrowser + QTextBrowser +
    gui/common/RSTextBrowser.h
    +
    + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    + + SubscribeToolButton + QToolButton +
    gui/common/SubscribeToolButton.h
    +
    - + diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 9527d8675..5733d5a39 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -24,9 +24,10 @@ #include "CreateGxsForumMsg.h" #include "GxsForumUserNotify.h" #include "gui/notifyqt.h" -#include "gui/gxs/GxsGroupShareKey.h" -#include "util/qtthreadsutils.h" #include "gui/common/GroupTreeWidget.h" +#include "gui/gxs/GxsGroupShareKey.h" +#include "util/misc.h" +#include "util/qtthreadsutils.h" class GxsForumGroupInfoData : public RsUserdata { @@ -39,7 +40,7 @@ public: /** Constructor */ GxsForumsDialog::GxsForumsDialog(QWidget *parent) : - GxsGroupFrameDialog(rsGxsForums, parent), mEventHandlerId(0) + GxsGroupFrameDialog(rsGxsForums, settingsGroupName(),parent), mEventHandlerId(0) { mCountChildMsgs = true; @@ -103,20 +104,36 @@ bool GxsForumsDialog::getGroupData(std::list& groupInfo) bool GxsForumsDialog::getGroupStatistics(const RsGxsGroupId& groupId,GxsGroupStatistic& stat) { - return rsGxsForums->getForumStatistics(groupId,stat); + RsGxsForumStatistics s; + + if(!rsGxsForums->getForumStatistics(groupId,s)) + return false; + + stat.mGrpId = groupId; + stat.mNumMsgs = s.mNumberOfMessages; + + stat.mTotalSizeOfMsgs = 0; // hopefuly unused. Required the loading of the full channel data, so not very convenient. + stat.mNumThreadMsgsNew = s.mNumberOfNewMessages; + stat.mNumThreadMsgsUnread = s.mNumberOfUnreadMessages; + stat.mNumChildMsgsNew = 0; + stat.mNumChildMsgsUnread = 0; + + return true; } - - QString GxsForumsDialog::getHelpString() const { + int H = misc::getFontSizeFactor("HelpButton").height(); + QString hlp_str = tr( - "

      Forums

    \ -

    Retroshare Forums look like internet forums, but they work in a decentralized way

    \ -

    You see forums your friends are subscribed to, and you forward subscribed forums to \ - your friends. This automatically promotes interesting forums in the network.

    \ -

    Forum messages are kept for %1 days and sync-ed over the last %2 days, unless you configure it otherwise.

    \ - ").arg(QString::number(rsGxsForums->getDefaultStoragePeriod()/86400)).arg(QString::number(rsGxsForums->getDefaultSyncPeriod()/86400)); + "

      Forums

    " + "

    Retroshare Forums look like internet forums, but they work in a decentralized way

    " + "

    You see forums your friends are subscribed to, and you forward subscribed forums to" + " your friends. This automatically promotes interesting forums in the network.

    " + "

    Forum messages are kept for %2 days and sync-ed over the last %3 days, unless you configure it otherwise.

    " + ).arg( QString::number(2*H) + , QString::number(rsGxsForums->getDefaultStoragePeriod()/86400) + , QString::number(rsGxsForums->getDefaultSyncPeriod()/86400)); return hlp_str ; } @@ -233,9 +250,11 @@ void GxsForumsDialog::groupInfoToGroupItemInfo(const RsGxsGenericGroupData *grou groupItemInfo.description = QString::fromUtf8(forumGroupData->mDescription.c_str()); if (!groupData->mMeta.mCircleId.isNull() ) + { if (details.mRestrictedCircleId == details.mCircleId) groupItemInfo.icon = FilesDefs::getIconFromQtResourcePath(":icons/png/forums-red.png"); else groupItemInfo.icon = FilesDefs::getIconFromQtResourcePath(":icons/png/forums-signed.png"); + } } diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index c9a4f33c8..ff3771075 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -1,6 +1,9 @@ icons/onion.png + icons/svg/threaded-view.svg + icons/svg/flat-view.svg + icons/svg/lastpost-view.svg icons/svg/design.svg icons/svg/hidden.svg icons/svg/ratio-auto.svg @@ -12,6 +15,7 @@ icons/svg/display_options.svg icons/svg/listlayout.svg icons/svg/gridlayout.svg + icons/svg/people2.svg icons/stars/star0.png icons/stars/star1.png icons/stars/star2.png @@ -63,6 +67,7 @@ icons/logo_2_connected_128.png icons/outlook.png icons/question.png + icons/ssl.png icons/plugins_128.png icons/png/add.png icons/png/add-identity.png @@ -92,6 +97,7 @@ icons/png/forums.png icons/png/fullscreen_arrows.png icons/png/highlight.png + icons/png/history-clock-white.png icons/png/help.png icons/png/home.png icons/png/info.png @@ -139,6 +145,7 @@ icons/search_red_128.png icons/security_high_128.png icons/security_low_128.png + icons/security_low_off_128.png icons/security_medium_128.png icons/settings/appearance.svg icons/settings/channels.svg @@ -202,6 +209,7 @@ icons/svg/newsfeed.svg icons/svg/options.svg icons/svg/paste.svg + icons/svg/paste_image.svg icons/svg/people-notify.svg icons/svg/people.svg icons/svg/person.svg @@ -338,5 +346,42 @@ icons/notification.png icons/wire.png icons/wire-circle.png + icons/folder-account.svg + icons/notification.svg + icons/groups/blue.svg + icons/groups/colored.svg + icons/groups/green.svg + icons/groups/indigo.svg + icons/groups/pink.svg + icons/groups/purple.svg + icons/groups/red.svg + icons/groups/yellow.svg + icons/newtab.svg + icons/newwindow.svg + icons/cancel.svg + icons/connection.svg + icons/plus.svg + icons/minus.svg + icons/svg/calendar-blank.svg + icons/svg/calendar-month.svg + icons/svg/calendar-today.svg + icons/svg/calendar-week.svg + icons/svg/refresh.svg + icons/filetype/any.svg + icons/filetype/archive.svg + icons/filetype/audio.svg + icons/filetype/document.svg + icons/filetype/img.svg + icons/filetype/picture.svg + icons/filetype/program.svg + icons/filetype/video.svg + icons/filetype/c.svg + icons/filetype/cpp.svg + icons/filetype/h.svg + icons/filetype/pdf.svg + icons/filetype/apk.svg + icons/filetype/dll.svg + icons/filetype/collection.svg + icons/filetype/patch.svg diff --git a/retroshare-gui/src/gui/icons/account-convert.svg b/retroshare-gui/src/gui/icons/account-convert.svg new file mode 100644 index 000000000..1e5609fad --- /dev/null +++ b/retroshare-gui/src/gui/icons/account-convert.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/retroshare-gui/src/gui/icons/account-plus.svg b/retroshare-gui/src/gui/icons/account-plus.svg new file mode 100644 index 000000000..cf743afad --- /dev/null +++ b/retroshare-gui/src/gui/icons/account-plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/retroshare-gui/src/gui/icons/cancel.svg b/retroshare-gui/src/gui/icons/cancel.svg new file mode 100644 index 000000000..bb921b5fa --- /dev/null +++ b/retroshare-gui/src/gui/icons/cancel.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/connection.svg b/retroshare-gui/src/gui/icons/connection.svg new file mode 100644 index 000000000..b22e7275d --- /dev/null +++ b/retroshare-gui/src/gui/icons/connection.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/any.svg b/retroshare-gui/src/gui/icons/filetype/any.svg new file mode 100644 index 000000000..7e0cbf726 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/any.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/apk.svg b/retroshare-gui/src/gui/icons/filetype/apk.svg new file mode 100644 index 000000000..81b468fc7 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/apk.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/archive.svg b/retroshare-gui/src/gui/icons/filetype/archive.svg new file mode 100644 index 000000000..dc7f6ed1a --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/archive.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/audio.svg b/retroshare-gui/src/gui/icons/filetype/audio.svg new file mode 100644 index 000000000..d56eee2cc --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/audio.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/c.svg b/retroshare-gui/src/gui/icons/filetype/c.svg new file mode 100644 index 000000000..702863c5e --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/c.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/collection.svg b/retroshare-gui/src/gui/icons/filetype/collection.svg new file mode 100644 index 000000000..4a6b79ddf --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/collection.svg @@ -0,0 +1,190 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/cpp.svg b/retroshare-gui/src/gui/icons/filetype/cpp.svg new file mode 100644 index 000000000..fbacc8635 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/cpp.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/dll.svg b/retroshare-gui/src/gui/icons/filetype/dll.svg new file mode 100644 index 000000000..7dbca1de8 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/dll.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/document.svg b/retroshare-gui/src/gui/icons/filetype/document.svg new file mode 100644 index 000000000..e2976b503 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/document.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/h.svg b/retroshare-gui/src/gui/icons/filetype/h.svg new file mode 100644 index 000000000..bf4963ba8 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/h.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/img.svg b/retroshare-gui/src/gui/icons/filetype/img.svg new file mode 100644 index 000000000..66f8c4018 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/img.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/patch.svg b/retroshare-gui/src/gui/icons/filetype/patch.svg new file mode 100644 index 000000000..2df822b37 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/patch.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/pdf.svg b/retroshare-gui/src/gui/icons/filetype/pdf.svg new file mode 100644 index 000000000..3be7f47a8 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/pdf.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/picture.svg b/retroshare-gui/src/gui/icons/filetype/picture.svg new file mode 100644 index 000000000..91d8165b4 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/picture.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/program.svg b/retroshare-gui/src/gui/icons/filetype/program.svg new file mode 100644 index 000000000..7ae7e7305 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/program.svg @@ -0,0 +1,48 @@ + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/filetype/video.svg b/retroshare-gui/src/gui/icons/filetype/video.svg new file mode 100644 index 000000000..0dd6c78c7 --- /dev/null +++ b/retroshare-gui/src/gui/icons/filetype/video.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/folder-account.svg b/retroshare-gui/src/gui/icons/folder-account.svg new file mode 100644 index 000000000..1247cb476 --- /dev/null +++ b/retroshare-gui/src/gui/icons/folder-account.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/folder-open.svg b/retroshare-gui/src/gui/icons/folder-open.svg new file mode 100644 index 000000000..2cd0d4905 --- /dev/null +++ b/retroshare-gui/src/gui/icons/folder-open.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/folder.png b/retroshare-gui/src/gui/icons/folder.png index 01f942628..50b84dc56 100644 Binary files a/retroshare-gui/src/gui/icons/folder.png and b/retroshare-gui/src/gui/icons/folder.png differ diff --git a/retroshare-gui/src/gui/icons/folder.svg b/retroshare-gui/src/gui/icons/folder.svg new file mode 100644 index 000000000..4989f5d1c --- /dev/null +++ b/retroshare-gui/src/gui/icons/folder.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/folderopen.png b/retroshare-gui/src/gui/icons/folderopen.png index 544e5f0b7..9f83b2561 100644 Binary files a/retroshare-gui/src/gui/icons/folderopen.png and b/retroshare-gui/src/gui/icons/folderopen.png differ diff --git a/retroshare-gui/src/gui/icons/groups/blue.svg b/retroshare-gui/src/gui/icons/groups/blue.svg new file mode 100644 index 000000000..ee0b3786f --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/blue.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/colored.svg b/retroshare-gui/src/gui/icons/groups/colored.svg new file mode 100644 index 000000000..8483f270f --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/colored.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/green.svg b/retroshare-gui/src/gui/icons/groups/green.svg new file mode 100644 index 000000000..3ca8e3074 --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/green.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/indigo.svg b/retroshare-gui/src/gui/icons/groups/indigo.svg new file mode 100644 index 000000000..56efae8d7 --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/indigo.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/pink.svg b/retroshare-gui/src/gui/icons/groups/pink.svg new file mode 100644 index 000000000..e8b72e1df --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/pink.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/purple.svg b/retroshare-gui/src/gui/icons/groups/purple.svg new file mode 100644 index 000000000..f4d78db5b --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/purple.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/red.svg b/retroshare-gui/src/gui/icons/groups/red.svg new file mode 100644 index 000000000..07b706a28 --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/red.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/groups/yellow.svg b/retroshare-gui/src/gui/icons/groups/yellow.svg new file mode 100644 index 000000000..06982a820 --- /dev/null +++ b/retroshare-gui/src/gui/icons/groups/yellow.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/minus.svg b/retroshare-gui/src/gui/icons/minus.svg new file mode 100644 index 000000000..fc2ccfaa8 --- /dev/null +++ b/retroshare-gui/src/gui/icons/minus.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/newtab.svg b/retroshare-gui/src/gui/icons/newtab.svg new file mode 100644 index 000000000..5e7c4316b --- /dev/null +++ b/retroshare-gui/src/gui/icons/newtab.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/newwindow.svg b/retroshare-gui/src/gui/icons/newwindow.svg new file mode 100644 index 000000000..dd9e408cb --- /dev/null +++ b/retroshare-gui/src/gui/icons/newwindow.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/notification.svg b/retroshare-gui/src/gui/icons/notification.svg new file mode 100644 index 000000000..c0cb95ba0 --- /dev/null +++ b/retroshare-gui/src/gui/icons/notification.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/plus.svg b/retroshare-gui/src/gui/icons/plus.svg new file mode 100644 index 000000000..83b1dfbbb --- /dev/null +++ b/retroshare-gui/src/gui/icons/plus.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/png/history-clock-blue.png b/retroshare-gui/src/gui/icons/png/history-clock-blue.png new file mode 100644 index 000000000..562667468 Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/history-clock-blue.png differ diff --git a/retroshare-gui/src/gui/icons/png/history-clock-white.png b/retroshare-gui/src/gui/icons/png/history-clock-white.png new file mode 100644 index 000000000..95e93d7ae Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/history-clock-white.png differ diff --git a/retroshare-gui/src/gui/icons/security_low_off_128.png b/retroshare-gui/src/gui/icons/security_low_off_128.png new file mode 100644 index 000000000..a0f02b0a1 Binary files /dev/null and b/retroshare-gui/src/gui/icons/security_low_off_128.png differ diff --git a/retroshare-gui/src/gui/icons/ssl.png b/retroshare-gui/src/gui/icons/ssl.png new file mode 100644 index 000000000..ca1686616 Binary files /dev/null and b/retroshare-gui/src/gui/icons/ssl.png differ diff --git a/retroshare-gui/src/gui/icons/svg/calendar-blank.svg b/retroshare-gui/src/gui/icons/svg/calendar-blank.svg new file mode 100644 index 000000000..240eea35c --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/calendar-blank.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/calendar-month.svg b/retroshare-gui/src/gui/icons/svg/calendar-month.svg new file mode 100644 index 000000000..ad16153d4 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/calendar-month.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/calendar-today.svg b/retroshare-gui/src/gui/icons/svg/calendar-today.svg new file mode 100644 index 000000000..1673a26ca --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/calendar-today.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/calendar-week.svg b/retroshare-gui/src/gui/icons/svg/calendar-week.svg new file mode 100644 index 000000000..b958f1bd9 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/calendar-week.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/download.svg b/retroshare-gui/src/gui/icons/svg/download.svg index 4cd19ee40..9c260c8e8 100644 --- a/retroshare-gui/src/gui/icons/svg/download.svg +++ b/retroshare-gui/src/gui/icons/svg/download.svg @@ -1,18 +1,18 @@ + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + sodipodi:docname="download.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> @@ -36,18 +36,19 @@ inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="1366" - inkscape:window-height="706" + inkscape:window-height="705" id="namedview6" showgrid="false" inkscape:zoom="5.3636364" - inkscape:cx="22" - inkscape:cy="21.813559" + inkscape:cx="22.186441" + inkscape:cy="21.720339" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" - inkscape:current-layer="svg2" /> + inkscape:current-layer="svg2" + inkscape:pagecheckerboard="0" /> + style="fill:#00b400;fill-opacity:1" /> diff --git a/retroshare-gui/src/gui/icons/svg/flat-view.svg b/retroshare-gui/src/gui/icons/svg/flat-view.svg new file mode 100644 index 000000000..b08a1a281 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/flat-view.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/lastpost-view.svg b/retroshare-gui/src/gui/icons/svg/lastpost-view.svg new file mode 100644 index 000000000..16d0807e0 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/lastpost-view.svg @@ -0,0 +1,52 @@ + + + +image/svg+xml diff --git a/retroshare-gui/src/gui/icons/svg/paste_image.svg b/retroshare-gui/src/gui/icons/svg/paste_image.svg new file mode 100644 index 000000000..464798ffd --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/paste_image.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/refresh.svg b/retroshare-gui/src/gui/icons/svg/refresh.svg new file mode 100644 index 000000000..eddf8330e --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/refresh.svg @@ -0,0 +1,38 @@ + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/threaded-view.svg b/retroshare-gui/src/gui/icons/svg/threaded-view.svg new file mode 100644 index 000000000..4210acc40 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/threaded-view.svg @@ -0,0 +1,42 @@ + + + + + + + + diff --git a/retroshare-gui/src/gui/icons/svg/wire-notify.svg b/retroshare-gui/src/gui/icons/svg/wire-notify.svg new file mode 100644 index 000000000..7d4d6ccce --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/wire-notify.svg @@ -0,0 +1,56 @@ + + + +image/svg+xml diff --git a/retroshare-gui/src/gui/icons/svg/wire.svg b/retroshare-gui/src/gui/icons/svg/wire.svg new file mode 100644 index 000000000..9a8029016 --- /dev/null +++ b/retroshare-gui/src/gui/icons/svg/wire.svg @@ -0,0 +1,56 @@ + + + +image/svg+xml diff --git a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp index 19ffdac90..9f5f88e74 100644 --- a/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp +++ b/retroshare-gui/src/gui/im_history/ImHistoryBrowser.cpp @@ -44,12 +44,8 @@ #define ROLE_PLAINTEXT Qt::UserRole + 1 ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const ChatId& peerId) - : QThread(parent) -{ - m_chatId = peerId; - m_historyBrowser = parent; - stopped = false; -} + : QThread(parent), m_historyBrowser(parent), m_chatId(peerId), stopped(false) +{} ImHistoryBrowserCreateItemsThread::~ImHistoryBrowserCreateItemsThread() { @@ -285,10 +281,12 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg) QString name; if (m_chatId.isLobbyId() || m_chatId.isDistantChatId()) { RsIdentityDetails details; - if (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details)) + if (rsIdentity->getIdDetails(RsGxsId(msg.peerId), details)) name = QString::fromUtf8(details.mNickname.c_str()); - else + else if(!msg.peerName.empty()) name = QString::fromUtf8(msg.peerName.c_str()); + else + name = QString::fromUtf8(msg.peerId.toStdString().c_str()); } else { name = QString::fromUtf8(msg.peerName.c_str()); } diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index fcdd4f3cc..de468d270 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -22,10 +22,6 @@ images/streaming.png images/white-bubble-64.png images/orange-bubble-64.png - images/stock_signature_bad.png - images/stock_signature_ok.png - images/stock_signature_missing.png - images/stock_signature_unverified.png images/anonymous_128_blue.png images/browsable_128_green.png images/browsable_128_blue.png @@ -39,7 +35,6 @@ images/help/natgreen.png images/help/natred.png images/pgp.png - images/rs_wizard.png images/avatar_request.png images/avatar_refused.png images/avatar_request_unknown.png @@ -90,14 +85,6 @@ images/closepressed.png images/denied16.png images/filetype-association.png - images/FileTypeAny.png - images/FileTypeArchive.png - images/FileTypeAudio.png - images/FileTypeCDImage.png - images/FileTypeDocument.png - images/FileTypePicture.png - images/FileTypeProgram.png - images/FileTypeVideo.png images/foldermail.png images/folderopen.png images/fileopen.png @@ -107,9 +94,7 @@ images/graph-checking.png images/graph-blue.png images/avatar_background.png - images/button_cancel.png images/chat.png - images/cancel.png images/close-down.png images/copy.png images/delete.png @@ -205,10 +190,7 @@ images/junk.png images/junk_on.png images/junk_off.png - images/connect_friend.png images/kalarm.png - images/kbackgammon.png - images/kcmsystem24.png images/ledoff1.png images/ledon1.png images/locale.png @@ -273,16 +255,8 @@ images/replymailall24-hover.png images/reset.png images/resume.png - images/security-high-16.png - images/security-high-48.png - images/security-low-48.png - images/security-medium-48.png - images/security-high-off-48.png - images/security-low-off-48.png - images/security-medium-off-48.png images/save24.png images/send24.png - images/settings.png images/show_toolbox_frame.png images/start.png images/stop.png @@ -295,9 +269,6 @@ images/sort_incr.png images/sort_decrease.png images/sound.png - images/tab-dock.png - images/tab-undock.png - images/tab-new.png images/transferupdown.png images/tools_wizard.png images/uploads.png @@ -305,12 +276,6 @@ images/loader/indicator-32.gif images/loader/circleball-16.gif images/loader/progress.gif - images/mimetypes/pdf.png - images/mimetypes/rscollection-16.png - images/mimetypes/patch.png - images/mimetypes/source_c.png - images/mimetypes/source_cpp.png - images/mimetypes/source_h.png images/thumb-default-video.png images/user/add_user24.png images/user/add_user48.png @@ -354,13 +319,7 @@ images/up0down1.png images/up1down1.png images/up1down0.png - images/underconstruction.png images/user.png - images/view_calendar_day.png - images/view_calendar_week.png - images/view_calendar_month.png - images/view_calendar_list.png - images/view_split_top_bottom.png qss/chat/standard/private/info.xml qss/chat/standard/private/incoming.htm qss/chat/standard/private/outgoing.htm @@ -418,19 +377,18 @@ qss/chat/compact/history/main.css qss/chat/compact/history/variants/Standard.css qss/chat/compact/history/variants/Colored.css - qss/stylesheet/qss.default - qss/stylesheet/Standard.qss + qss/stylesheet/default.qss + qss/stylesheet/Standard_Light.qss + qss/stylesheet/Standard_Dark.qss images/tags/pgp-known.png images/tags/pgp-unknown.png images/tags/dev-ambassador.png images/tags/dev-translator.png images/tags/dev-patcher.png images/tags/developer.png - images/share-icon-16.png images/toasterEnable.png images/toasterDisable.png images/emblem-web.png - images/rsmessenger48.png images/SmileyText.png images/SimpleText.png images/ColoredText.png diff --git a/retroshare-gui/src/gui/images/FileTypeAny.png b/retroshare-gui/src/gui/images/FileTypeAny.png deleted file mode 100644 index 34e64b73c..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeAny.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeArchive.png b/retroshare-gui/src/gui/images/FileTypeArchive.png deleted file mode 100644 index b982beb6c..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeArchive.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeAudio.png b/retroshare-gui/src/gui/images/FileTypeAudio.png deleted file mode 100644 index 988b27bf7..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeAudio.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeCDImage.png b/retroshare-gui/src/gui/images/FileTypeCDImage.png deleted file mode 100644 index cb3ae8289..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeCDImage.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeDocument.png b/retroshare-gui/src/gui/images/FileTypeDocument.png deleted file mode 100644 index 41d20a5c3..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeDocument.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypePicture.png b/retroshare-gui/src/gui/images/FileTypePicture.png deleted file mode 100644 index 7e9bb14f6..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypePicture.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeProgram.png b/retroshare-gui/src/gui/images/FileTypeProgram.png deleted file mode 100644 index 63b9f6c32..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeProgram.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/FileTypeVideo.png b/retroshare-gui/src/gui/images/FileTypeVideo.png deleted file mode 100644 index 9bcc41b78..000000000 Binary files a/retroshare-gui/src/gui/images/FileTypeVideo.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/button_cancel.png b/retroshare-gui/src/gui/images/button_cancel.png deleted file mode 100644 index 3f0c98b7d..000000000 Binary files a/retroshare-gui/src/gui/images/button_cancel.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/cancel.png b/retroshare-gui/src/gui/images/cancel.png deleted file mode 100644 index 87cd0b012..000000000 Binary files a/retroshare-gui/src/gui/images/cancel.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/connect_friend.png b/retroshare-gui/src/gui/images/connect_friend.png deleted file mode 100755 index 3549e6d83..000000000 Binary files a/retroshare-gui/src/gui/images/connect_friend.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/kbackgammon.png b/retroshare-gui/src/gui/images/kbackgammon.png deleted file mode 100644 index 9bdda1083..000000000 Binary files a/retroshare-gui/src/gui/images/kbackgammon.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/kcmsystem24.png b/retroshare-gui/src/gui/images/kcmsystem24.png deleted file mode 100644 index cedcf7f0f..000000000 Binary files a/retroshare-gui/src/gui/images/kcmsystem24.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/patch.png b/retroshare-gui/src/gui/images/mimetypes/patch.png deleted file mode 100644 index 3925b7c2e..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/patch.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/pdf.png b/retroshare-gui/src/gui/images/mimetypes/pdf.png deleted file mode 100644 index 73946b90d..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/pdf.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/rscollection-16.png b/retroshare-gui/src/gui/images/mimetypes/rscollection-16.png deleted file mode 100644 index ab6d1686e..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/rscollection-16.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/source_c.png b/retroshare-gui/src/gui/images/mimetypes/source_c.png deleted file mode 100644 index 51e7d3976..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/source_c.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/source_cpp.png b/retroshare-gui/src/gui/images/mimetypes/source_cpp.png deleted file mode 100644 index 522dc111f..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/source_cpp.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/mimetypes/source_h.png b/retroshare-gui/src/gui/images/mimetypes/source_h.png deleted file mode 100644 index 116790f4e..000000000 Binary files a/retroshare-gui/src/gui/images/mimetypes/source_h.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/rs_wizard.png b/retroshare-gui/src/gui/images/rs_wizard.png deleted file mode 100644 index 387d21177..000000000 Binary files a/retroshare-gui/src/gui/images/rs_wizard.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/rsmessenger48.png b/retroshare-gui/src/gui/images/rsmessenger48.png deleted file mode 100644 index f01ab76b4..000000000 Binary files a/retroshare-gui/src/gui/images/rsmessenger48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-high-16.png b/retroshare-gui/src/gui/images/security-high-16.png deleted file mode 100644 index d93b4bdd9..000000000 Binary files a/retroshare-gui/src/gui/images/security-high-16.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-high-32.png b/retroshare-gui/src/gui/images/security-high-32.png deleted file mode 100755 index 95e73d93e..000000000 Binary files a/retroshare-gui/src/gui/images/security-high-32.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-high-48.png b/retroshare-gui/src/gui/images/security-high-48.png deleted file mode 100644 index fb54fd735..000000000 Binary files a/retroshare-gui/src/gui/images/security-high-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-high-off-48.png b/retroshare-gui/src/gui/images/security-high-off-48.png deleted file mode 100644 index d4149def2..000000000 Binary files a/retroshare-gui/src/gui/images/security-high-off-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-low-48.png b/retroshare-gui/src/gui/images/security-low-48.png deleted file mode 100644 index 9d5659f46..000000000 Binary files a/retroshare-gui/src/gui/images/security-low-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-low-off-48.png b/retroshare-gui/src/gui/images/security-low-off-48.png deleted file mode 100644 index 80901511d..000000000 Binary files a/retroshare-gui/src/gui/images/security-low-off-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-medium-48.png b/retroshare-gui/src/gui/images/security-medium-48.png deleted file mode 100644 index 9265eb46c..000000000 Binary files a/retroshare-gui/src/gui/images/security-medium-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/security-medium-off-48.png b/retroshare-gui/src/gui/images/security-medium-off-48.png deleted file mode 100644 index 89c83df46..000000000 Binary files a/retroshare-gui/src/gui/images/security-medium-off-48.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/settings.png b/retroshare-gui/src/gui/images/settings.png deleted file mode 100644 index 9e6d52b8b..000000000 Binary files a/retroshare-gui/src/gui/images/settings.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/share-icon-16.png b/retroshare-gui/src/gui/images/share-icon-16.png deleted file mode 100644 index a5de1924f..000000000 Binary files a/retroshare-gui/src/gui/images/share-icon-16.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/share-icon-24.png b/retroshare-gui/src/gui/images/share-icon-24.png deleted file mode 100644 index 09eee141f..000000000 Binary files a/retroshare-gui/src/gui/images/share-icon-24.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/share-icon-32.png b/retroshare-gui/src/gui/images/share-icon-32.png deleted file mode 100644 index 80fd96250..000000000 Binary files a/retroshare-gui/src/gui/images/share-icon-32.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/stock_signature_bad.png b/retroshare-gui/src/gui/images/stock_signature_bad.png deleted file mode 100644 index c8de64f7a..000000000 Binary files a/retroshare-gui/src/gui/images/stock_signature_bad.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/stock_signature_missing.png b/retroshare-gui/src/gui/images/stock_signature_missing.png deleted file mode 100644 index 66c03a4e6..000000000 Binary files a/retroshare-gui/src/gui/images/stock_signature_missing.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/stock_signature_ok.png b/retroshare-gui/src/gui/images/stock_signature_ok.png deleted file mode 100644 index 454421ad1..000000000 Binary files a/retroshare-gui/src/gui/images/stock_signature_ok.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/stock_signature_unverified.png b/retroshare-gui/src/gui/images/stock_signature_unverified.png deleted file mode 100644 index aae661fa6..000000000 Binary files a/retroshare-gui/src/gui/images/stock_signature_unverified.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/tab-dock.png b/retroshare-gui/src/gui/images/tab-dock.png deleted file mode 100644 index ba059de40..000000000 Binary files a/retroshare-gui/src/gui/images/tab-dock.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/tab-new.png b/retroshare-gui/src/gui/images/tab-new.png deleted file mode 100644 index 3bbbb51c1..000000000 Binary files a/retroshare-gui/src/gui/images/tab-new.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/tab-undock.png b/retroshare-gui/src/gui/images/tab-undock.png deleted file mode 100644 index f2827606c..000000000 Binary files a/retroshare-gui/src/gui/images/tab-undock.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/underconstruction.png b/retroshare-gui/src/gui/images/underconstruction.png deleted file mode 100644 index af754a98c..000000000 Binary files a/retroshare-gui/src/gui/images/underconstruction.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/view_calendar_day.png b/retroshare-gui/src/gui/images/view_calendar_day.png deleted file mode 100644 index a32fbb723..000000000 Binary files a/retroshare-gui/src/gui/images/view_calendar_day.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/view_calendar_list.png b/retroshare-gui/src/gui/images/view_calendar_list.png deleted file mode 100644 index f41b620b3..000000000 Binary files a/retroshare-gui/src/gui/images/view_calendar_list.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/view_calendar_month.png b/retroshare-gui/src/gui/images/view_calendar_month.png deleted file mode 100644 index e90194dcc..000000000 Binary files a/retroshare-gui/src/gui/images/view_calendar_month.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/view_calendar_week.png b/retroshare-gui/src/gui/images/view_calendar_week.png deleted file mode 100644 index eb12f42d8..000000000 Binary files a/retroshare-gui/src/gui/images/view_calendar_week.png and /dev/null differ diff --git a/retroshare-gui/src/gui/images/view_split_top_bottom.png b/retroshare-gui/src/gui/images/view_split_top_bottom.png deleted file mode 100644 index 8c0e4db56..000000000 Binary files a/retroshare-gui/src/gui/images/view_split_top_bottom.png and /dev/null differ diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 2be5efb35..4e0219b0c 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -121,6 +122,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); + mAlreadySent = false; + m_msgType = NORMAL; // needed to send system flags with reply msgFlags = 0; @@ -136,8 +139,8 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) m_completer = NULL; - ui.distantFrame->hide(); - ui.sizeLimitFrame->hide(); + ui.info_Frame_Distant->hide(); + ui.info_Frame_SizeLimit->hide(); ui.respond_to_CB->hide(); ui.fromLabel->hide(); @@ -148,7 +151,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.hashBox->hide(); // connect up the buttons. - connect( ui.actionSend, SIGNAL( triggered (bool)), this, SLOT( sendMessage( ) ) ); + connect( ui.actionSend, SIGNAL( triggered(bool)), this, SLOT( sendMessage() ), Qt::UniqueConnection ); //connect( ui.actionReply, SIGNAL( triggered (bool)), this, SLOT( replyMessage( ) ) ); connect(ui.boldbtn, SIGNAL(clicked()), this, SLOT(textBold())); connect(ui.underlinebtn, SIGNAL(clicked()), this, SLOT(textUnderline())); @@ -162,16 +165,16 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) connect(ui.actionContactsView, SIGNAL(triggered()), this, SLOT(toggleContacts())); connect(ui.actionSaveas, SIGNAL(triggered()), this, SLOT(saveasDraft())); connect(ui.actionAttach, SIGNAL(triggered()), this, SLOT(attachFile())); - connect(ui.titleEdit, SIGNAL(textChanged(const QString &)), this, SLOT(titleChanged())); + connect(ui.titleEdit, SIGNAL(textChanged(QString)), this, SLOT(titleChanged())); connect(ui.sizeincreaseButton, SIGNAL (clicked()), this, SLOT (fontSizeIncrease())); connect(ui.sizedecreaseButton, SIGNAL (clicked()), this, SLOT (fontSizeDecrease())); connect(ui.actionQuote, SIGNAL(triggered()), this, SLOT(blockQuote())); connect(ui.codeButton, SIGNAL (clicked()), this, SLOT (toggleCode())); - connect(ui.msgText, SIGNAL( checkSpellingChanged( bool ) ), this, SLOT( spellChecking( bool ) ) ); + connect(ui.msgText, SIGNAL( checkSpellingChanged(bool) ), this, SLOT( spellChecking(bool) ) ); - connect(ui.msgText, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)), this, SLOT(currentCharFormatChanged(const QTextCharFormat &))); + connect(ui.msgText, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(currentCharFormatChanged(QTextCharFormat))); connect(ui.msgText, SIGNAL(cursorPositionChanged()), this, SLOT(cursorPositionChanged())); connect(ui.msgText->document(), SIGNAL(modificationChanged(bool)), actionSave, SLOT(setEnabled(bool))); @@ -206,12 +209,12 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) connect(ui.filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged(int))); - connect(ui.addToButton, SIGNAL(clicked(void)), this, SLOT(addTo())); - connect(ui.addCcButton, SIGNAL(clicked(void)), this, SLOT(addCc())); - connect(ui.addBccButton, SIGNAL(clicked(void)), this, SLOT(addBcc())); - connect(ui.addRecommendButton, SIGNAL(clicked(void)), this, SLOT(addRecommend())); + connect(ui.addToButton, SIGNAL(clicked()), this, SLOT(addTo())); + connect(ui.addCcButton, SIGNAL(clicked()), this, SLOT(addCc())); + connect(ui.addBccButton, SIGNAL(clicked()), this, SLOT(addBcc())); + connect(ui.addRecommendButton, SIGNAL(clicked()), this, SLOT(addRecommend())); - connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&,int)), this, SLOT(peerStatusChanged(const QString&,int))); + connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(QString,int)), this, SLOT(peerStatusChanged(QString,int))); connect(ui.friendSelectionWidget, SIGNAL(contentChanged()), this, SLOT(buildCompleter())); connect(ui.friendSelectionWidget, SIGNAL(doubleClicked(int,QString)), this, SLOT(addTo())); connect(ui.friendSelectionWidget, SIGNAL(itemSelectionChanged()), this, SLOT(friendSelectionChanged())); @@ -232,7 +235,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.friendSelectionWidget->start(); QActionGroup *grp = new QActionGroup(this); - connect(grp, SIGNAL(triggered(QAction *)), this, SLOT(textAlign(QAction *))); + connect(grp, SIGNAL(triggered(QAction*)), this, SLOT(textAlign(QAction*))); actionAlignLeft = new QAction(QIcon(""), tr("&Left"), grp); actionAlignLeft->setShortcut(Qt::CTRL + Qt::Key_L); @@ -248,7 +251,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) actionAlignJustify->setCheckable(true); QActionGroup *grp2 = new QActionGroup(this); - connect(grp2, SIGNAL(triggered(QAction *)), this, SLOT(textStyle(QAction *))); + connect(grp2, SIGNAL(triggered(QAction*)), this, SLOT(textStyle(QAction*))); actionDisc = new QAction(QIcon(""), tr("Bullet list (disc)"), grp2); actionDisc->setCheckable(true); @@ -283,17 +286,44 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.filterComboBox->setCurrentIndex(3); connect(ui.comboStyle, SIGNAL(activated(int)),this, SLOT(changeFormatType(int))); - connect(ui.comboFont, SIGNAL(activated(const QString &)), this, SLOT(textFamily(const QString &))); + connect(ui.comboFont, SIGNAL(activated(QString)), this, SLOT(textFamily(QString))); + +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + ui.comboFont->setMaximumWidth(QFontMetrics(ui.comboFont->font()).width("_")*20); +#else + ui.comboFont->setMaximumWidth(QFontMetrics(ui.comboFont->font()).horizontalAdvance("_")*20); +#endif ui.comboSize->setEditable(true); + ui.comboSize->style()->polish(ui.comboSize); // Needed else QLineEdit inside QComboBox background is painted with black color. QFontDatabase db; foreach(int size, db.standardSizes()) - ui.comboSize->addItem(QString::number(size)); + ui.comboSize->addItem(QString::number(size)); - connect(ui.comboSize, SIGNAL(activated(const QString &)),this, SLOT(textSize(const QString &))); + QStyleOptionComboBox opt; QSize sh; + opt.initFrom(ui.comboSize); + opt.subControls = QStyle::SC_All; + opt.activeSubControls = QStyle::SC_None; + opt.editable = ui.comboSize->isEditable(); + sh = ui.comboSize->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, ui.comboSize); + //+4 because there is hardcoded margins in QCommonStyle::drawControl(CE_ComboBoxLabel) +#if QT_VERSION < QT_VERSION_CHECK(5,11,0) + sh.setWidth(sh.width() + ui.comboSize->fontMetrics().width("8")*2 + 4); +#else + sh.setWidth(sh.width() + ui.comboSize->fontMetrics().horizontalAdvance("8")*2 + 4); +#endif + ui.comboSize->setMaximumWidth(sh.width()); + ui.comboSize->view()->setMinimumWidth(sh.width() + ui.comboSize->view()->verticalScrollBar()->minimumWidth() + 4); + + connect(ui.comboSize, SIGNAL(activated(QString)),this, SLOT(textSize(QString))); ui.comboSize->setCurrentIndex(ui.comboSize->findText(QString::number(QApplication::font().pointSize()))); + ui.toolBarFrame->setMinimumHeight( ui.comboStyle->height() + + ui.toolBarFrameHLayout->contentsMargins().top() + + ui.toolBarFrameHLayout->contentsMargins().bottom() + ); + QMenu * alignmentmenu = new QMenu(); alignmentmenu->addAction(actionAlignLeft); alignmentmenu->addAction(actionAlignCenter); @@ -313,11 +343,11 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) ui.styleButton->setMenu(formatlistmenu); QPixmap pxm(24,24); - pxm.fill(Qt::black); + pxm.fill(ui.msgText->palette().text().color()); ui.colorbtn->setIcon(pxm); QPixmap pxm2(24,24); - pxm2.fill(Qt::white); + pxm2.fill(ui.msgText->palette().window().color()); ui.color2btn->setIcon(pxm2); /* Set header resize modes and initial section sizes */ @@ -369,7 +399,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WindowFlags flags) // create tag menu TagsMenu *menu = new TagsMenu (tr("Tags"), this); connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); - connect(menu, SIGNAL(tagSet(int, bool)), this, SLOT(tagSet(int, bool))); + connect(menu, SIGNAL(tagSet(int,bool)), this, SLOT(tagSet(int,bool))); connect(menu, SIGNAL(tagRemoveAll()), this, SLOT(tagRemoveAll())); ui.tagButton->setMenu(menu); @@ -408,21 +438,21 @@ void MessageComposer::updateCells(int,int) if(has_gxs) { ui.respond_to_CB->show(); - ui.distantFrame->show(); + ui.info_Frame_Distant->show(); ui.fromLabel->show(); checkLength(); } else { ui.respond_to_CB->hide(); - ui.distantFrame->hide() ; + ui.info_Frame_Distant->hide() ; ui.fromLabel->hide(); } if(rowCount > 20) - ui.sizeLimitFrame->show(); + ui.info_Frame_SizeLimit->show(); else - ui.sizeLimitFrame->hide(); + ui.info_Frame_SizeLimit->hide(); } void MessageComposer::processSettings(bool bLoad) @@ -619,7 +649,7 @@ void MessageComposer::addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId // PGPId+SslId are always here. But if the peer is not a friend the SSL id cannot be used. // (todo) If the PGP id doesn't get us a PGP key from the keyring, we need to create a short invite - RetroShareLink link = RetroShareLink::createUnknownSslCertificate(sslId, gpgId); + RetroShareLink link = RetroShareLink::createUnknownSslCertificate(sslId, gpgId); if (!link.valid()) return; @@ -630,61 +660,20 @@ void MessageComposer::addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId std::list msgList; std::list::const_iterator it; - rsMail->getMessageSummaries(msgList); - for(it = msgList.begin(); it != msgList.end(); ++it) { - if (it->msgflags & RS_MSG_TRASH) { - continue; - } - if ((it->msgflags & RS_MSG_BOXMASK) != RS_MSG_INBOX) { - continue; - } - if ((it->msgflags & RS_MSG_USER_REQUEST) == 0) { - continue; - } - if (it->title == title.toUtf8().constData()) { + rsMail->getMessageSummaries(Rs::Msgs::BoxName::BOX_INBOX,msgList); + + // do not re-add an existing request. + // note: the test with name() is very unsecure. We should use the ID instead. + + for(it = msgList.begin(); it != msgList.end(); ++it) + if((it->msgflags & RS_MSG_USER_REQUEST) && it->title == title.toUtf8().constData()) return; - } - } /* create a message */ QString msgText = tr("Hi %1,

    %2 wants to be friends with you on RetroShare.

    Respond now:
    %3

    Thanks,
    The RetroShare Team").arg(QString::fromUtf8(rsPeers->getGPGName(rsPeers->getGPGOwnId()).c_str()), link.name(), link.toHtml()); rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_USER_REQUEST); } -#ifdef UNUSED_CODE -void MessageComposer::sendChannelPublishKey(RsGxsChannelGroup &group) -{ -// QString channelName = QString::fromUtf8(group.mMeta.mGroupName.c_str()); - -// RetroShareLink link; -// if (!link.createGxsGroupLink(RetroShareLink::TYPE_CHANNEL, group.mMeta.mGroupId, channelName)) { -// return; -// } - -// QString title = tr("Publish key for channel %1").arg(channelName); - -// /* create a message */ -// QString msgText = tr("... %1 ...
    %2").arg(channelName, link.toHtml()); -// rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_PUBLISH_KEY); -} - -void MessageComposer::sendForumPublishKey(RsGxsForumGroup &group) -{ -// QString forumName = QString::fromUtf8(group.mMeta.mGroupName.c_str()); - -// RetroShareLink link; -// if (!link.createGxsGroupLink(RetroShareLink::TYPE_FORUM, group.mMeta.mGroupId, forumName)) { -// return; -// } - -// QString title = tr("Publish key for forum %1").arg(forumName); - -// /* create a message */ -// QString msgText = tr("... %1 ...
    %2").arg(forumName, link.toHtml()); -// rsMail->SystemMessage(title.toUtf8().constData(), msgText.toUtf8().constData(), RS_MSG_PUBLISH_KEY); -} -#endif - void MessageComposer::closeEvent (QCloseEvent * event) { bool bClose = true; @@ -772,7 +761,6 @@ void MessageComposer::buildCompleter() std::list::iterator peerIt; rsPeers->getFriendList(peers); - std::list gxsIds; QList gxsitems ; ui.friendSelectionWidget->items(gxsitems,FriendSelectionWidget::IDTYPE_GXS) ; @@ -781,9 +769,9 @@ void MessageComposer::buildCompleter() QStringList completerList; QStringList completerGroupList; - for (QList::const_iterator idIt = gxsitems.begin(); idIt != gxsitems.end(); ++idIt) + for (auto &idIt : gxsitems) { - RsGxsId id ( ui.friendSelectionWidget->idFromItem( *idIt ) ); + RsGxsId id ( ui.friendSelectionWidget->idFromItem( idIt ) ); RsIdentityDetails detail; if(rsIdentity->getIdDetails(id, detail)) @@ -903,6 +891,7 @@ void MessageComposer::addFile(const FileInfo &fileInfo) void MessageComposer::titleChanged() { calculateTitle(); + std::cerr << "Setting modified 004 = true" << std::endl; ui.msgText->document()->setModified(true); } @@ -1038,36 +1027,63 @@ MessageComposer *MessageComposer::newMsg(const std::string &msgId /* = ""*/) std::list groupInfoList; rsPeers->getGroupInfoList(groupInfoList); - std::list groupIds; - std::list::iterator groupIt; + // std::list groupIds; + // std::list::iterator groupIt; - // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgto, groupIds); - // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { - // msgComposer->addRecipient(MessageComposer::TO, *groupIt, true) ; - // } + // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgto, groupIds); + // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { + // msgComposer->addRecipient(MessageComposer::TO, *groupIt, true) ; + // } - // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgcc, groupIds); - // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { - // msgComposer->addRecipient(MessageComposer::CC, *groupIt, true) ; - // } + // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgcc, groupIds); + // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { + // msgComposer->addRecipient(MessageComposer::CC, *groupIt, true) ; + // } - // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgbcc, groupIds); - // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { - // msgComposer->addRecipient(MessageComposer::BCC, *groupIt, true) ; - // } + // calculateGroupsOfSslIds(groupInfoList, msgInfo.msgbcc, groupIds); + // for (groupIt = groupIds.begin(); groupIt != groupIds.end(); ++groupIt ) { + // msgComposer->addRecipient(MessageComposer::BCC, *groupIt, true) ; + // } - for (std::set::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ; - for (std::set::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ; - for (std::set::const_iterator it = msgInfo.rspeerid_msgbcc.begin(); it != msgInfo.rspeerid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ; - for (std::set::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ; - for (std::set::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ; - for (std::set::const_iterator it = msgInfo.rsgxsid_msgbcc.begin(); it != msgInfo.rsgxsid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ; + for(auto m:msgInfo.destinations) + switch(m.mode()) + { + case MsgAddress::MSG_ADDRESS_MODE_TO: + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + msgComposer->addRecipient(MessageComposer::TO,m.toGxsId()); + else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + msgComposer->addRecipient(MessageComposer::TO,m.toRsPeerId()); + break; + + case MsgAddress::MSG_ADDRESS_MODE_CC: + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + msgComposer->addRecipient(MessageComposer::CC,m.toGxsId()); + else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + msgComposer->addRecipient(MessageComposer::CC,m.toRsPeerId()); + break; + + case MsgAddress::MSG_ADDRESS_MODE_BCC: + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + msgComposer->addRecipient(MessageComposer::BCC,m.toGxsId()); + else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + msgComposer->addRecipient(MessageComposer::BCC,m.toRsPeerId()); + break; + default:break; + } + + // for (std::set::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ; + // for (std::set::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ; + // for (std::set::const_iterator it = msgInfo.rspeerid_msgbcc.begin(); it != msgInfo.rspeerid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ; + // for (std::set::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it ) msgComposer->addRecipient(MessageComposer::TO, *it) ; + // for (std::set::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::CC, *it) ; + // for (std::set::const_iterator it = msgInfo.rsgxsid_msgbcc.begin(); it != msgInfo.rsgxsid_msgbcc.end(); ++it ) msgComposer->addRecipient(MessageComposer::BCC, *it) ; MsgTagInfo tagInfo; rsMail->getMessageTag(msgId, tagInfo); - msgComposer->m_tagIds = tagInfo.tagIds; + msgComposer->m_tagIds = tagInfo; msgComposer->showTagLabels(); + std::cerr << "Setting modified 005 = false" << std::endl; msgComposer->ui.msgText->document()->setModified(false); } @@ -1083,7 +1099,7 @@ QString MessageComposer::buildReplyHeader(const MessageInfo &msgInfo) QString from; if(msgInfo.msgflags & RS_MSG_DISTANT) { - link = RetroShareLink::createMessage(msgInfo.rsgxsid_srcId, ""); + link = RetroShareLink::createMessage(msgInfo.from.toGxsId(), ""); if (link.valid()) { from += link.toHtml(); @@ -1091,57 +1107,39 @@ QString MessageComposer::buildReplyHeader(const MessageInfo &msgInfo) } else { - link = RetroShareLink::createMessage(msgInfo.rspeerid_srcId, ""); + link = RetroShareLink::createMessage(msgInfo.from.toRsPeerId(), ""); if (link.valid()) { from += link.toHtml(); } } + QString to,cc; - QString to; - for ( std::set::const_iterator it = msgInfo.rspeerid_msgto.begin(); it != msgInfo.rspeerid_msgto.end(); ++it) + for(auto m:msgInfo.destinations) { - link = RetroShareLink::createMessage(*it, ""); + RetroShareLink link; + + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + link = RetroShareLink::createMessage(m.toGxsId(), ""); + else + link = RetroShareLink::createMessage(m.toRsPeerId(), ""); + if (link.valid()) - { - if (!to.isEmpty()) - to += ", "; + if(m.mode()==MsgAddress::MSG_ADDRESS_MODE_TO) + { + if (!to.isEmpty()) + to += ", "; - to += link.toHtml(); - } - } - for ( std::set::const_iterator it = msgInfo.rsgxsid_msgto.begin(); it != msgInfo.rsgxsid_msgto.end(); ++it) - { - link = RetroShareLink::createMessage(*it, ""); - if (link.valid()) - { - if (!to.isEmpty()) - to += ", "; - - to += link.toHtml(); - } - } - - QString cc; - for (std::set::const_iterator it = msgInfo.rspeerid_msgcc.begin(); it != msgInfo.rspeerid_msgcc.end(); ++it) { - link = RetroShareLink::createMessage(*it, ""); - if (link.valid()) { - if (!cc.isEmpty()) { - cc += ", "; + to += link.toHtml(); } - cc += link.toHtml(); - } - } - for (std::set::const_iterator it = msgInfo.rsgxsid_msgcc.begin(); it != msgInfo.rsgxsid_msgcc.end(); ++it) { - link = RetroShareLink::createMessage(*it, ""); - if (link.valid()) { - if (!cc.isEmpty()) { - cc += ", "; - } - cc += link.toHtml(); - } - } + else if(m.mode()==MsgAddress::MSG_ADDRESS_MODE_CC) + { + if (!cc.isEmpty()) + cc += ", "; + cc += link.toHtml(); + } + } QString header = QString("-----%1-----").arg(tr("Original Message")); header += QString("
    %1: %2
    ").arg(tr("From"), from); @@ -1193,6 +1191,7 @@ void MessageComposer::setQuotedMsg(const QString &msg, const QString &header) ui.msgText->moveCursor(QTextCursor::Start); ui.msgText->setUndoRedoEnabled(true); + std::cerr << "Setting modified 006 = true" << std::endl; ui.msgText->document()->setModified(true); ui.msgText->setFocus( Qt::OtherFocusReason ); @@ -1205,6 +1204,11 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all) return NULL; } + if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID && msgInfo.from.toRsPeerId().isNull()) + { + QMessageBox::warning(nullptr,tr("Will not reply"),tr("There is no point in replying to a notification message!")); + return nullptr; + } MessageComposer *msgComposer = MessageComposer::newMsg(); msgComposer->m_msgParentId = msgId; msgComposer->m_msgType = REPLY; @@ -1214,14 +1218,18 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all) msgComposer->setTitleText(QString::fromUtf8(msgInfo.title.c_str()), REPLY); msgComposer->setQuotedMsg(QString::fromUtf8(msgInfo.msg.c_str()), buildReplyHeader(msgInfo)); - if(!msgInfo.rspeerid_srcId.isNull()) msgComposer->addRecipient(MessageComposer::TO, msgInfo.rspeerid_srcId); - if(!msgInfo.rsgxsid_srcId.isNull()) msgComposer->addRecipient(MessageComposer::TO, msgInfo.rsgxsid_srcId); + if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + msgComposer->addRecipient(MessageComposer::TO, msgInfo.from.toGxsId()); + else if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + msgComposer->addRecipient(MessageComposer::TO, msgInfo.from.toRsPeerId()); // make sure the current ID is among the ones the msg was actually sent to. - for(auto it(msgInfo.rsgxsid_msgto.begin());it!=msgInfo.rsgxsid_msgto.end();++it) - if(rsIdentity->isOwnId(*it)) +#warning: We do not know here what is the atual destination of the message, since it may have been sent to two of our IDs at once. + + for(auto m:msgInfo.destinations) + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID && rsIdentity->isOwnId(m.toGxsId())) { - msgComposer->ui.respond_to_CB->setDefaultId(*it) ; + msgComposer->ui.respond_to_CB->setDefaultId(m.toGxsId()) ; break ; } // Note: another solution is to do @@ -1230,23 +1238,27 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all) if (all) { - RsPeerId ownId = rsPeers->getOwnId(); + for(auto m:msgInfo.destinations) + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + msgComposer->addRecipient(MessageComposer::TO,m.toGxsId()); + else if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + msgComposer->addRecipient(MessageComposer::TO,m.toRsPeerId()); - for (std::set::iterator tli = msgInfo.rspeerid_msgto.begin(); tli != msgInfo.rspeerid_msgto.end(); ++tli) - if (ownId != *tli) - msgComposer->addRecipient(MessageComposer::TO, *tli) ; + // for (std::set::iterator tli = msgInfo.rspeerid_msgto.begin(); tli != msgInfo.rspeerid_msgto.end(); ++tli) + // if (ownId != *tli) + // msgComposer->addRecipient(MessageComposer::TO, *tli) ; - for (std::set::iterator tli = msgInfo.rspeerid_msgcc.begin(); tli != msgInfo.rspeerid_msgcc.end(); ++tli) - if (ownId != *tli) - msgComposer->addRecipient(MessageComposer::TO, *tli) ; + // for (std::set::iterator tli = msgInfo.rspeerid_msgcc.begin(); tli != msgInfo.rspeerid_msgcc.end(); ++tli) + // if (ownId != *tli) + // msgComposer->addRecipient(MessageComposer::TO, *tli) ; - for (std::set::iterator tli = msgInfo.rsgxsid_msgto.begin(); tli != msgInfo.rsgxsid_msgto.end(); ++tli) - //if (ownId != *tli) - msgComposer->addRecipient(MessageComposer::TO, *tli) ; + // for (std::set::iterator tli = msgInfo.rsgxsid_msgto.begin(); tli != msgInfo.rsgxsid_msgto.end(); ++tli) + // //if (ownId != *tli) + // msgComposer->addRecipient(MessageComposer::TO, *tli) ; - for (std::set::iterator tli = msgInfo.rsgxsid_msgcc.begin(); tli != msgInfo.rsgxsid_msgcc.end(); ++tli) - //if (ownId != *tli) - msgComposer->addRecipient(MessageComposer::TO, *tli) ; + // for (std::set::iterator tli = msgInfo.rsgxsid_msgcc.begin(); tli != msgInfo.rsgxsid_msgcc.end(); ++tli) + // //if (ownId != *tli) + // msgComposer->addRecipient(MessageComposer::TO, *tli) ; } // needed to send system flags with reply @@ -1255,7 +1267,7 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all) MsgTagInfo tagInfo; rsMail->getMessageTag(msgId, tagInfo); - msgComposer->m_tagIds = tagInfo.tagIds; + msgComposer->m_tagIds = tagInfo; msgComposer->showTagLabels(); msgComposer->calculateTitle(); @@ -1281,7 +1293,7 @@ MessageComposer *MessageComposer::forwardMsg(const std::string &msgId) msgComposer->setTitleText(QString::fromUtf8(msgInfo.title.c_str()), FORWARD); msgComposer->setQuotedMsg(QString::fromUtf8(msgInfo.msg.c_str()), buildReplyHeader(msgInfo)); - std::list& files_info = msgInfo.files; + const std::list& files_info = msgInfo.files; msgComposer->setFileList(files_info); @@ -1336,26 +1348,29 @@ void MessageComposer::setMsgText(const QString &msg, bool asHtml) c.movePosition(QTextCursor::End); ui.msgText->setTextCursor(c); + std::cerr << "Setting modified 007 = true" << std::endl; ui.msgText->document()->setModified(true); } void MessageComposer::sendMessage() { - if (sendMessage_internal(false)) { + /* check for existing title */ + + if (ui.titleEdit->text().isNull()) + if (QMessageBox::warning(this, tr("RetroShare"), tr("Do you want to send the message without a subject ?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) { + ui.titleEdit->setFocus(); + return ; // Don't send with an empty subject + } + + if (sendMessage_internal(false)) close(); - } } -bool MessageComposer::sendMessage_internal(bool bDraftbox) +bool MessageComposer::buildMessage(MessageInfo& mi) { - /* construct a message */ - MessageInfo mi; + // add a GXS signer/from in case the message is to be sent to a distant peer - // add a GXS signer/from in case the message is to be sent to a distant peer - - mi.rsgxsid_srcId = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()) ; - - //std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl; + //std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl; mi.title = misc::removeNewLine(ui.titleEdit->text()).toUtf8().constData(); // needed to send system flags with reply @@ -1365,14 +1380,6 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) RsHtml::optimizeHtml(ui.msgText, text); mi.msg = text.toUtf8().constData(); - /* check for existing title */ - if (bDraftbox == false && mi.title.empty()) { - if (QMessageBox::warning(this, tr("RetroShare"), tr("Do you want to send the message without a subject ?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) { - ui.titleEdit->setFocus(); - return false; // Don't send with an empty subject - } - } - int filesCount = ui.msgFileList->topLevelItemCount(); for (int i = 0; i < filesCount; ++i) { QTreeWidgetItem *item = ui.msgFileList->topLevelItem(i); @@ -1429,12 +1436,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) switch (type) { - case TO: mi.rspeerid_msgto.insert(*sslIt); - break; - case CC: mi.rspeerid_msgcc.insert(*sslIt); - break; - case BCC:mi.rspeerid_msgbcc.insert(*sslIt); - break; + case TO: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_TO)); break; + case CC: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_CC)); break; + case BCC: mi.destinations.insert(MsgAddress(*sslIt,MsgAddress::MSG_ADDRESS_MODE_BCC)); break; } } } @@ -1446,12 +1450,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) switch (type) { - case TO: mi.rspeerid_msgto.insert(pid); - break ; - case CC: mi.rspeerid_msgcc.insert(pid); - break ; - case BCC:mi.rspeerid_msgbcc.insert(pid); - break ; + case TO: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_TO)); break; + case CC: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_CC)); break; + case BCC: mi.destinations.insert(MsgAddress(pid,MsgAddress::MSG_ADDRESS_MODE_BCC)); break; } } break ; @@ -1461,12 +1462,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) switch (type) { - case TO: mi.rsgxsid_msgto.insert(gid) ; - break ; - case CC: mi.rsgxsid_msgcc.insert(gid) ; - break ; - case BCC:mi.rsgxsid_msgbcc.insert(gid) ; - break ; + case TO: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_TO)); break; + case CC: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_CC)); break; + case BCC: mi.destinations.insert(MsgAddress(gid,MsgAddress::MSG_ADDRESS_MODE_BCC)); break; } } break ; @@ -1476,6 +1474,49 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) break ; } } + bool at_least_one_gxsid = false; + + for(auto m:mi.destinations) + if(m.type() == MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + { + at_least_one_gxsid=true; + break; + } + + if(!at_least_one_gxsid) + mi.from = Rs::Msgs::MsgAddress(rsPeers->getOwnId(),MsgAddress::MSG_ADDRESS_MODE_TO); + else + { + auto gxs_id_from = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()); + + if(gxs_id_from.isNull()) + { + QMessageBox::warning(this, tr("RetroShare"), tr("Please create an identity to sign distant messages, or remove the distant peers from the destination list."), QMessageBox::Ok); + return false; // Don't send if cannot sign. + } + mi.from = MsgAddress(RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()),MsgAddress::MSG_ADDRESS_MODE_TO) ; + } + + return true; +} + +bool MessageComposer::sendMessage_internal(bool bDraftbox) +{ + if(mAlreadySent) + { + std::cerr << "Already_sent is true. Giving up." << std::endl; + return true; + } + + /* construct a message */ + MessageInfo mi; + + if(!buildMessage(mi)) + return false; + + std::cerr << "Setting already_sent=true" << std::endl; + + mAlreadySent = true; if (bDraftbox) { @@ -1500,21 +1541,15 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) else { /* check for the recipient */ - if (mi.rspeerid_msgto.empty() && mi.rspeerid_msgcc.empty() && mi.rspeerid_msgbcc.empty() - && mi.rsgxsid_msgto.empty() && mi.rsgxsid_msgcc.empty() && mi.rsgxsid_msgbcc.empty()) + if (mi.destinations.empty()) { QMessageBox::warning(this, tr("RetroShare"), tr("Please insert at least one recipient."), QMessageBox::Ok); return false; // Don't send with no recipient } - if(mi.rsgxsid_srcId.isNull() && !(mi.rsgxsid_msgto.empty() && mi.rsgxsid_msgcc.empty() && mi.rsgxsid_msgbcc.empty())) - { - QMessageBox::warning(this, tr("RetroShare"), tr("Please create an identity to sign distant messages, or remove the distant peers from the destination list."), QMessageBox::Ok); - return false; // Don't send if cannot sign. - } - if (rsMail->MessageSend(mi) == false) { + + if (rsMail->MessageSend(mi) == false) return false; - } if (m_msgParentId.empty() == false) { switch (m_msgType) { @@ -1536,19 +1571,17 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) /* insert new tags */ std::list::iterator tag; - for (tag = m_tagIds.begin(); tag != m_tagIds.end(); ++tag) { - if (std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), *tag) == tagInfo.tagIds.end()) { - rsMail->setMessageTag(mi.msgId, *tag, true); - } else { - tagInfo.tagIds.remove(*tag); - } - } + for (auto tag:m_tagIds) + if (tagInfo.find(tag) == tagInfo.end()) + rsMail->setMessageTag(mi.msgId, tag, true); + else + tagInfo.erase(tag); /* remove deleted tags */ - for (tag = tagInfo.tagIds.begin(); tag != tagInfo.tagIds.end(); ++tag) { - rsMail->setMessageTag(mi.msgId, *tag, false); - } + for (auto tag:tagInfo) + rsMail->setMessageTag(mi.msgId, tag, false); } + std::cerr << "Setting modified 001 = false" << std::endl; ui.msgText->document()->setModified(false); return true; @@ -1599,16 +1632,16 @@ bool MessageComposer::getRecipientFromRow(int row, enumType &type, destinationTy QString MessageComposer::getRecipientEmailAddress(const RsGxsId& id,const RsIdentityDetails& detail) { - return (QString("%2 <")+tr("Distant identity:")+" %2@%1>").arg(QString::fromStdString(id.toStdString())).arg(QString::fromUtf8(detail.mNickname.c_str())) ; + return (QString("%2 <")+tr("Distant identity:")+" %2@%1>").arg(QString::fromStdString(id.toStdString()), QString::fromUtf8(detail.mNickname.c_str())) ; } QString MessageComposer::getRecipientEmailAddress(const RsPeerId& /* id */,const RsPeerDetails& detail) { - QString location_name = detail.location.empty()?tr("[Missing]"):QString::fromUtf8(detail.location.c_str()) ; + QString location_name = detail.location.empty()?tr("[Missing]"):QString::fromUtf8(detail.location.c_str()) ; - return (QString("%1 (")+tr("Node name & id:")+" %2, %3)").arg(QString::fromUtf8(detail.name.c_str())) - .arg(location_name) - .arg(QString::fromUtf8(detail.id.toStdString().c_str())) ; + return (QString("%1 (")+tr("Node name & id:")+" %2, %3)").arg(QString::fromUtf8(detail.name.c_str()) + , location_name + , QString::fromUtf8(detail.id.toStdString().c_str())) ; } void MessageComposer::setRecipientToRow(int row, enumType type, destinationType dest_type, const std::string &id) @@ -1619,12 +1652,13 @@ void MessageComposer::setRecipientToRow(int row, enumType type, destinationType QComboBox *comboBox = dynamic_cast(ui.recipientWidget->cellWidget(row, COLUMN_RECIPIENT_TYPE)); if (comboBox == NULL) { - comboBox = new QComboBox; + comboBox = new RSComboBox; comboBox->addItem(tr("To"), TO); comboBox->addItem(tr("Cc"), CC); comboBox->addItem(tr("Bcc"), BCC); ui.recipientWidget->setCellWidget(row, COLUMN_RECIPIENT_TYPE, comboBox); + ui.recipientWidget->setRowHeight(row, comboBox->height()); comboBox->setLayoutDirection(Qt::RightToLeft); comboBox->installEventFilter(this); @@ -1789,7 +1823,7 @@ void MessageComposer::editingRecipientFinished() if (row >= rowCount) // not found return; - enumType type; + enumType type = TO; std::string id; // dummy destinationType dtype ; @@ -1818,13 +1852,13 @@ void MessageComposer::editingRecipientFinished() ui.friendSelectionWidget->items(gxsitems,FriendSelectionWidget::IDTYPE_GXS) ; RsIdentityDetails detail; - for (QList::const_iterator idIt = gxsitems.begin(); idIt != gxsitems.end(); ++idIt) + for (auto &idIt : gxsitems) { - RsGxsId id ( ui.friendSelectionWidget->idFromItem( *idIt ) ); + RsGxsId gxsId ( ui.friendSelectionWidget->idFromItem( idIt ) ); - if(rsIdentity->getIdDetails(id, detail) && text == getRecipientEmailAddress(id,detail)) + if(rsIdentity->getIdDetails(gxsId, detail) && text == getRecipientEmailAddress(gxsId,detail)) { - setRecipientToRow(row, type, PEER_TYPE_GXS, id.toStdString()); + setRecipientToRow(row, type, PEER_TYPE_GXS, gxsId.toStdString()); return ; } } @@ -2271,7 +2305,8 @@ void MessageComposer::addSmileys() // add trailing space smiley += QString(" "); // add preceding space when needed (not at start of text or preceding space already exists) - if(!ui.msgText->textCursor().atStart() && ui.msgText->toPlainText()[ui.msgText->textCursor().position() - 1] != QChar(' ')) + QString plainText = ui.msgText->toPlainText(); + if(!ui.msgText->textCursor().atStart() && plainText[ui.msgText->textCursor().position() - 1] != QChar(' ')) smiley = QString(" ") + smiley; ui.msgText->textCursor().insertText(smiley); } @@ -2308,14 +2343,14 @@ void MessageComposer::fontChanged(const QFont &f) void MessageComposer::colorChanged(const QColor &c) { - QPixmap pix(16, 16); + QPixmap pix(24, 24); pix.fill(c); ui.colorbtn->setIcon(pix); } void MessageComposer::colorChanged2(const QColor &c) { - QPixmap pix(16, 16); + QPixmap pix(24, 24); pix.fill(c); ui.color2btn->setIcon(pix); } @@ -2365,6 +2400,7 @@ bool MessageComposer::fileSave() QTextStream ts(&file); ts.setCodec(QTextCodec::codecForName("UTF-8")); ts << ui.msgText->document()->toHtml("UTF-8"); + std::cerr << "Setting modified 002 = false" << std::endl; ui.msgText->document()->setModified(false); return true; } @@ -2419,6 +2455,7 @@ void MessageComposer::filePrintPdf() void MessageComposer::setCurrentFileName(const QString &fileName) { this->fileName = fileName; + std::cerr << "Setting modified 003 = false" << std::endl; ui.msgText->document()->setModified(false); setWindowModified(false); @@ -2769,17 +2806,17 @@ void MessageComposer::tagSet(int tagId, bool set) return; } - std::list::iterator tag = std::find(m_tagIds.begin(), m_tagIds.end(), tagId); - if (tag == m_tagIds.end()) { - if (set) { - m_tagIds.push_back(tagId); - /* Keep the list sorted */ - m_tagIds.sort(); - } - } else { - if (set == false) { - m_tagIds.remove(tagId); - } + auto tag = m_tagIds.find(tagId); + + if (tag == m_tagIds.end()) + { + if (set) + m_tagIds.insert(tagId); + } + else + { + if (set == false) + m_tagIds.erase(tagId); } showTagLabels(); @@ -2806,11 +2843,11 @@ void MessageComposer::showTagLabels() rsMail->getMessageTagTypes(tags); std::map >::iterator tag; - for (std::list::iterator tagId = m_tagIds.begin(); tagId != m_tagIds.end(); ++tagId) { - tag = tags.types.find(*tagId); + for (auto tagId:m_tagIds) { + tag = tags.types.find(tagId); if (tag != tags.types.end()) { QLabel *tagLabel = new QLabel(TagDefs::name(tag->first, tag->second.first), this); - tagLabel->setMaximumHeight(16); + tagLabel->setMaximumHeight(QFontMetrics(tagLabel->font()).height()*1.2); tagLabel->setStyleSheet(TagDefs::labelStyleSheet(tag->second.second)); tagLabels.push_back(tagLabel); ui.tagLayout->addWidget(tagLabel); @@ -2820,13 +2857,14 @@ void MessageComposer::showTagLabels() ui.tagLayout->addStretch(); } } -void MessageComposer::on_closeSizeLimitFrameButton_clicked() + +void MessageComposer::on_closeInfoFrameButton_Distant_clicked() { - ui.sizeLimitFrame->setVisible(false); + ui.info_Frame_Distant->setVisible(false); } -void MessageComposer::on_closeInfoFrameButton_clicked() +void MessageComposer::on_closeInfoFrameButton_SizeLimit_clicked() { - ui.distantFrame->setVisible(false); + ui.info_Frame_SizeLimit->setVisible(false); } QString MessageComposer::inviteMessage() diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.h b/retroshare-gui/src/gui/msgs/MessageComposer.h index a5f6d773c..0df2dbd8e 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.h +++ b/retroshare-gui/src/gui/msgs/MessageComposer.h @@ -163,8 +163,8 @@ private slots: void tagSet(int tagId, bool set); void tagRemoveAll(); - void on_closeInfoFrameButton_clicked(); - void on_closeSizeLimitFrameButton_clicked(); + void on_closeInfoFrameButton_Distant_clicked(); + void on_closeInfoFrameButton_SizeLimit_clicked(); static QString inviteMessage(); @@ -172,6 +172,7 @@ private slots: private: static QString buildReplyHeader(const MessageInfo &msgInfo); + bool buildMessage(MessageInfo& mi); void processSettings(bool bLoad); @@ -250,7 +251,7 @@ private: std::string m_msgParentId; // parent message id std::string m_sDraftMsgId; // existing message id enumMessageType m_msgType; - std::list m_tagIds; + std::set m_tagIds; QList tagLabels; // needed to send system flags with reply @@ -264,6 +265,7 @@ private: QLabel *lineLabel; bool has_gxs; + bool mAlreadySent; // prevents a Qt bug that calls the same action twice. /** Qt Designer generated object */ Ui::MessageComposer ui; diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.ui b/retroshare-gui/src/gui/msgs/MessageComposer.ui index ff76237f9..9b5e8605c 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.ui +++ b/retroshare-gui/src/gui/msgs/MessageComposer.ui @@ -6,8 +6,8 @@ 0 0 - 1008 - 755 + 800 + 650 @@ -31,12 +31,6 @@ 0 - - - 300 - 524287 - - 220 @@ -70,7 +64,7 @@ 0 - + @@ -86,12 +80,6 @@ 0 - - - 300 - 16777215 - - 220 @@ -176,7 +164,7 @@ - + @@ -339,7 +327,7 @@ false - 25 + 30 @@ -350,7 +338,7 @@ Qt::Vertical - + @@ -366,7 +354,7 @@ QFrame::Sunken - + 6 @@ -379,504 +367,485 @@ 6 - - - - 1 + + + + + 150 + 16777215 + - - - - - 16777215 - 16777215 - - - - Qt::ClickFocus - - - - Paragraph - - - - - Heading 1 - - - - - Heading 2 - - - - - Heading 2 - - - - - Heading 3 - - - - - Heading 4 - - - - - Heading 5 - - - - - Heading 6 - - - + + Qt::ClickFocus + + + + Paragraph + - - - - - 100 - 16777215 - - - - Qt::ClickFocus - - + + + Heading 1 + - - - - - 45 - 16777215 - - - - Qt::ClickFocus - - - Font size - - - - 22 - 22 - - - + + + Heading 2 + - - - - - 1677 - 1677 - - - - Qt::NoFocus - - - Increase font size - - - - - - - :/icons/textedit/font-increase.png:/icons/textedit/font-increase.png - - - - 24 - 24 - - - - true - - + + + Heading 2 + - - - - - 167 - 167 - - - - Qt::NoFocus - - - Decrease font size - - - - - - - :/icons/textedit/font-decrease.png:/icons/textedit/font-decrease.png - - - - 24 - 24 - - - - true - - + + + Heading 3 + - - - - - 0 - 0 - - - - - 1677 - 1677 - - - - Qt::NoFocus - - - Bold - - - - - - - :/icons/textedit/bold.png:/icons/textedit/bold.png - - - - 24 - 24 - - - - true - - - true - - + + + Heading 4 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Italic - - - - - - - :/icons/textedit/italic.png:/icons/textedit/italic.png - - - - 24 - 24 - - - - true - - - true - - + + + Heading 5 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Add an Image - - - - - - - :/icons/textedit/photo-of-a-landscape.png:/icons/textedit/photo-of-a-landscape.png - - - - 24 - 24 - - - - true - - + + + Heading 6 + - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Alignment - - - - - - - :/icons/textedit/align.png:/icons/textedit/align.png - - - - 24 - 24 - - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::NoFocus - - - Sets text font to code style - - - - - - - :/icons/textedit/code.png:/icons/textedit/code.png - - - - 24 - 24 - - - - true - - - - - - - Qt::Horizontal - - - - 20 - 24 - - - - - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Underline - - - - - - - :/icons/textedit/underline.png:/icons/textedit/underline.png - - - - 24 - 24 - - - - true - - - true - - - - - - - Qt::NoFocus - - - - :/icons/textedit/smile.png:/icons/textedit/smile.png - - - - 24 - 24 - - - - true - - - - - - - - 0 - 0 - - - - - 167 - 167 - - - - Qt::NoFocus - - - Set Text color - - - - - - true - - - - - - - Set Text background color - - - - - - false - - - true - - - - - - - - - - - :/icons/textedit/numberd-list.png:/icons/textedit/numberd-list.png - - - - 24 - 24 - - - - false - - - QToolButton::InstantPopup - - - true - - - - + + + + + + Qt::ClickFocus + + + + + + + + 0 + 0 + + + + Qt::ClickFocus + + + Font size + + + + + + + Qt::NoFocus + + + Set Text color + + + + + + true + + + + + + + Qt::NoFocus + + + Set Text background color + + + + + + false + + + true + + + + + + + + 1677 + 1677 + + + + Qt::NoFocus + + + Increase font size + + + + + + + :/icons/textedit/font-increase.png:/icons/textedit/font-increase.png + + + + 24 + 24 + + + + true + + + + + + + + 167 + 167 + + + + Qt::NoFocus + + + Decrease font size + + + + + + + :/icons/textedit/font-decrease.png:/icons/textedit/font-decrease.png + + + + 24 + 24 + + + + true + + + + + + + + 0 + 0 + + + + + 1677 + 1677 + + + + Qt::NoFocus + + + Bold + + + + + + + :/icons/textedit/bold.png:/icons/textedit/bold.png + + + + 24 + 24 + + + + true + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Underline + + + + + + + :/icons/textedit/underline.png:/icons/textedit/underline.png + + + + 24 + 24 + + + + true + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Italic + + + + + + + :/icons/textedit/italic.png:/icons/textedit/italic.png + + + + 24 + 24 + + + + true + + + true + + + + + + + Qt::NoFocus + + + Sets text font to code style + + + + + + + :/icons/textedit/code.png:/icons/textedit/code.png + + + + 24 + 24 + + + + true + + + + + + + + + + + :/icons/textedit/numberd-list.png:/icons/textedit/numberd-list.png + + + + 24 + 24 + + + + false + + + QToolButton::InstantPopup + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Alignment + + + + + + + :/icons/textedit/align.png:/icons/textedit/align.png + + + + 24 + 24 + + + + QToolButton::InstantPopup + + + true + + + + + + + + 0 + 0 + + + + + 167 + 167 + + + + Qt::NoFocus + + + Add an Image + + + + + + + :/icons/textedit/photo-of-a-landscape.png:/icons/textedit/photo-of-a-landscape.png + + + + 24 + 24 + + + + true + + + + + + + Qt::NoFocus + + + + :/icons/textedit/smile.png:/icons/textedit/smile.png + + + + 24 + 24 + + + + true + + + + + + + Qt::Horizontal + + + + 20 + 24 + + + - + + + + + 0 + 0 + 0 + + + @@ -897,6 +866,15 @@ + + + + 0 + 0 + 0 + + + @@ -917,6 +895,15 @@ + + + + 154 + 154 + 154 + + + @@ -947,7 +934,7 @@ QFrame::Box - + 6 @@ -961,7 +948,7 @@ 6 - + 16 @@ -980,7 +967,7 @@ - + Distant messages stay into your Outbox until an acknowledgement of receipt has been received. @@ -990,7 +977,7 @@ - + 16 @@ -1027,10 +1014,19 @@ border-image: url(:/images/closepressed.png) - + + + + + 0 + 0 + 0 + + + @@ -1051,6 +1047,15 @@ border-image: url(:/images/closepressed.png) + + + + 0 + 0 + 0 + + + @@ -1071,6 +1076,15 @@ border-image: url(:/images/closepressed.png) + + + + 154 + 154 + 154 + + + @@ -1101,7 +1115,7 @@ border-image: url(:/images/closepressed.png) QFrame::Box - + 6 @@ -1115,7 +1129,7 @@ border-image: url(:/images/closepressed.png) 6 - + 16 @@ -1134,7 +1148,7 @@ border-image: url(:/images/closepressed.png) - + Sending messages to more than 20 people at once is not recommended. If you need to send invites, dedicated forums is what you need. @@ -1144,7 +1158,7 @@ border-image: url(:/images/closepressed.png) - + 16 @@ -1284,7 +1298,7 @@ border-image: url(:/images/closepressed.png) 0 0 - 1008 + 1215 25 @@ -1386,27 +1400,32 @@ border-image: url(:/images/closepressed.png) + + FriendSelectionWidget + QWidget +
    gui/common/FriendSelectionWidget.h
    + 1 +
    GxsIdChooser QComboBox
    gui/gxs/GxsIdChooser.h
    + + HashBox + QScrollArea +
    gui/common/HashBox.h
    + 1 +
    MimeTextEdit QTextEdit
    gui/common/MimeTextEdit.h
    - FriendSelectionWidget - QWidget -
    gui/common/FriendSelectionWidget.h
    - 1 -
    - - HashBox - QScrollArea -
    gui/common/HashBox.h
    - 1 + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    diff --git a/retroshare-gui/src/gui/msgs/MessageModel.cpp b/retroshare-gui/src/gui/msgs/MessageModel.cpp index 3d3367553..09508cad6 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.cpp +++ b/retroshare-gui/src/gui/msgs/MessageModel.cpp @@ -53,7 +53,7 @@ const QString RsMessageModel::FilterString("filtered"); RsMessageModel::RsMessageModel(QObject *parent) : QAbstractItemModel(parent) { - mCurrentBox = BOX_NONE; + mCurrentBox = Rs::Msgs::BoxName::BOX_NONE; mQuickViewFilter = QUICK_VIEW_ALL; mFilterType = FILTER_TYPE_NONE; mFilterStrings.clear(); @@ -88,7 +88,7 @@ int RsMessageModel::rowCount(const QModelIndex& parent) const int RsMessageModel::columnCount(const QModelIndex &/*parent*/) const { - return COLUMN_THREAD_NB_COLUMNS ; + return COLUMN_THREAD_NB_COLUMNS; } bool RsMessageModel::getMessageData(const QModelIndex& i,Rs::Msgs::MessageInfo& fmpe) const @@ -167,7 +167,8 @@ QVariant RsMessageModel::headerData(int section, Qt::Orientation /*orientation*/ { case COLUMN_THREAD_DATE: return tr("Date"); case COLUMN_THREAD_AUTHOR: return tr("From"); - case COLUMN_THREAD_SUBJECT: return tr("Subject"); + case COLUMN_THREAD_TO: return tr("To"); + case COLUMN_THREAD_SUBJECT: return tr("Subject"); case COLUMN_THREAD_TAGS: return tr("Tags"); default: return QVariant(); @@ -189,8 +190,9 @@ QVariant RsMessageModel::headerData(int section, Qt::Orientation /*orientation*/ { case COLUMN_THREAD_ATTACHMENT: return tr("Click to sort by attachments"); case COLUMN_THREAD_SUBJECT: return tr("Click to sort by subject"); - case COLUMN_THREAD_READ: return tr("Click to sort by read"); - case COLUMN_THREAD_AUTHOR: return tr("Click to sort by from"); + case COLUMN_THREAD_READ: return tr("Click to sort by read status"); + case COLUMN_THREAD_AUTHOR: return tr("Click to sort by author"); + case COLUMN_THREAD_TO: return tr("Click to sort by destination"); case COLUMN_THREAD_DATE: return tr("Click to sort by date"); case COLUMN_THREAD_TAGS: return tr("Click to sort by tags"); case COLUMN_THREAD_STAR: return tr("Click to sort by star"); @@ -269,7 +271,7 @@ QVariant RsMessageModel::data(const QModelIndex &index, int role) const case MsgFlagsRole: return fmpe.msgflags ; case UnreadRole: return fmpe.msgflags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER); case MsgIdRole: return QString::fromStdString(fmpe.msgId) ; - case SrcIdRole: return QString::fromStdString(fmpe.srcId.toStdString()) ; + case SrcIdRole: return QString::fromStdString(fmpe.from.toStdString()) ; default: return QVariant(); } @@ -312,6 +314,11 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int /*col if(s.isNull()) passes_strings = false; break; + case FILTER_TYPE_TO: s = sortRole(fmpe,COLUMN_THREAD_TO).toString(); + if(s.isNull()) + passes_strings = false; + break; + case FILTER_TYPE_DATE: s = displayRole(fmpe,COLUMN_THREAD_DATE).toString(); break; case FILTER_TYPE_CONTENT: { @@ -380,30 +387,35 @@ void RsMessageModel::setFilter(FilterType filter_type, const QStringList& string std::cerr << std::endl; #endif - preMods(); - mFilterType = filter_type; mFilterStrings = strings; - postMods(); + if(rowCount() > 0) + emit dataChanged(createIndex(0,0),createIndex(rowCount()-1,RsMessageModel::columnCount()-1)); } QVariant RsMessageModel::toolTipRole(const Rs::Msgs::MsgInfoSummary& fmpe,int column) const { - if(column == COLUMN_THREAD_AUTHOR) + if(column == COLUMN_THREAD_AUTHOR || column == COLUMN_THREAD_TO) { QString str,comment ; QList icons; - if(!GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.srcId.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR)) + if(column == COLUMN_THREAD_AUTHOR && !GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.from.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR)) return QVariant(); - int S = QFontMetricsF(QApplication::font()).height(); - QImage pix( (*icons.begin()).pixmap(QSize(4*S,4*S)).toImage()); + if(column == COLUMN_THREAD_TO && !GxsIdDetails::MakeIdDesc(RsGxsId(fmpe.to.toStdString()), true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR)) + return QVariant(); + + int S = QFontMetricsF(QApplication::font()).height(); + QImage pix( (*icons.begin()).pixmap(QSize(5*S,5*S)).toImage()); QString embeddedImage; - if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) + if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(5*S,5*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, -1)) + { + embeddedImage.insert(embeddedImage.indexOf("src="), "style=\"float:left\" "); comment = "
    " + embeddedImage + "" + comment + "
    "; + } return comment; } @@ -426,7 +438,8 @@ QVariant RsMessageModel::sizeHintRole(int col) const case COLUMN_THREAD_SUBJECT: return QVariant( QSize(factor * 170, factor*14 )); case COLUMN_THREAD_DATE: return QVariant( QSize(factor * 75 , factor*14 )); case COLUMN_THREAD_AUTHOR: return QVariant( QSize(factor * 75 , factor*14 )); - } + case COLUMN_THREAD_TO: return QVariant( QSize(factor * 75 , factor*14 )); + } } QVariant RsMessageModel::authorRole(const Rs::Msgs::MsgInfoSummary& /*fmpe*/,int /*column*/) const @@ -446,84 +459,138 @@ QVariant RsMessageModel::sortRole(const Rs::Msgs::MsgInfoSummary& fmpe,int colum case COLUMN_THREAD_SPAM: return QVariant((fmpe.msgflags & RS_MSG_SPAM)? 1:0); - case COLUMN_THREAD_AUTHOR:{ + case COLUMN_THREAD_AUTHOR:{ QString name; - if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.srcId.toStdString()),name)) + if(GxsIdTreeItemDelegate::computeName(RsGxsId(fmpe.from.toStdString()),name)) return name; return ""; //Not Found } - default: - return displayRole(fmpe,column); + + case COLUMN_THREAD_TO: // fallthrough. In this case, the "to" field is not filled because the msg potentially has multiple destinations. + default: + return displayRole(fmpe,column); } } QVariant RsMessageModel::displayRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const { - switch(col) - { - case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str())); - case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count)); + switch(col) + { + case COLUMN_THREAD_SUBJECT: return QVariant(QString::fromUtf8(fmpe.title.c_str())); + case COLUMN_THREAD_ATTACHMENT:return QVariant(QString::number(fmpe.count)); - case COLUMN_THREAD_STAR: - case COLUMN_THREAD_SPAM: - case COLUMN_THREAD_READ:return QVariant(); - case COLUMN_THREAD_DATE:{ - QDateTime qtime; - qtime.setTime_t(fmpe.ts); + case COLUMN_THREAD_STAR: + case COLUMN_THREAD_SPAM: + case COLUMN_THREAD_READ:return QVariant(); + case COLUMN_THREAD_DATE:{ + QDateTime qtime; + qtime.setTime_t(fmpe.ts); - return QVariant(DateTime::formatDateTime(qtime)); - } + return QVariant(DateTime::formatDateTime(qtime)); + } - case COLUMN_THREAD_TAGS:{ - // Tags - Rs::Msgs::MsgTagInfo tagInfo; - rsMsgs->getMessageTag(fmpe.msgId, tagInfo); + case COLUMN_THREAD_TAGS:{ + // Tags + Rs::Msgs::MsgTagInfo tagInfo; + rsMsgs->getMessageTag(fmpe.msgId, tagInfo); - Rs::Msgs::MsgTagType Tags; - rsMsgs->getMessageTagTypes(Tags); + Rs::Msgs::MsgTagType Tags; + rsMsgs->getMessageTagTypes(Tags); - QString text; + QString text; - // build tag names - for (auto tagit = tagInfo.tagIds.begin(); tagit != tagInfo.tagIds.end(); ++tagit) - { - if (!text.isNull()) - text += ","; + // build tag names + for (auto tag:tagInfo) + { + if (!text.isNull()) + text += ","; - auto Tag = Tags.types.find(*tagit); + auto Tag = Tags.types.find(tag); - if (Tag != Tags.types.end()) - text += TagDefs::name(Tag->first, Tag->second.first); - else - RS_WARN("Unknown tag ", (int)Tag->first, " in message ", fmpe.msgId); - } - return text; - } - case COLUMN_THREAD_AUTHOR:{ - QString name; - RsGxsId id = RsGxsId(fmpe.srcId.toStdString()); + if (Tag != Tags.types.end()) + text += TagDefs::name(Tag->first, Tag->second.first); + else + RS_WARN("Unknown tag ", (int)Tag->first, " in message ", fmpe.msgId); + } + return text; + } + case COLUMN_THREAD_TO: { + QString name; - if(id.isNull()) - return QVariant(tr("[Notification]")); - if(GxsIdTreeItemDelegate::computeName(id,name)) - return name; - return QVariant(tr("[Unknown]")); - } + switch(mCurrentBox) + { + case Rs::Msgs::BoxName::BOX_DRAFTS: // in this case, we display the full list of destinations + case Rs::Msgs::BoxName::BOX_TRASH: // in this case, we display the full list of destinations + case Rs::Msgs::BoxName::BOX_SENT: // in this case, we display the full list of destinations + { + for(auto d:fmpe.destinations) + { + QString tmp; + GxsIdTreeItemDelegate::computeName(RsGxsId(d.toStdString()),tmp); // not nice, but works. + if(tmp.isNull()) + name += QString(tr("[Notification]") + ", "); + else + name += tmp + ", " ; + } + name.chop(2); + return name; + } + break; + case Rs::Msgs::BoxName::BOX_NONE: // in these cases, we display the actual destination + case Rs::Msgs::BoxName::BOX_INBOX: // in these cases, we display the actual destination + case Rs::Msgs::BoxName::BOX_OUTBOX: + { + RsGxsId id = RsGxsId(fmpe.to.toStdString()); // use "to" field, which is populated in Outbox, . + if(id.isNull()) + return QVariant(tr("[Notification]")); + else + { + GxsIdTreeItemDelegate::computeName(id,name); + return name; + } + } + break; + } + } + break; - default: - return QVariant("[ TODO ]"); - } + case COLUMN_THREAD_AUTHOR:{ + QString name; + RsGxsId id = RsGxsId(fmpe.from.toStdString()); - return QVariant("[ERROR]"); + if(id.isNull()) + return QVariant(tr("[Notification]")); + if(GxsIdTreeItemDelegate::computeName(id,name)) + return name; + return QVariant(tr("[Unknown]")); + } + + default: + return QVariant("[ TODO ]"); + } + + return QVariant("[ERROR]"); } QVariant RsMessageModel::userRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col) const { switch(col) { - case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.srcId.toStdString())); - case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId)); + case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.from.toStdString())); + case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId)); + case COLUMN_THREAD_TO: + { + // First check if the .to field is filled. + + if(!fmpe.to.toStdString().empty()) + return QVariant(QString::fromStdString(fmpe.to.toStdString())); + + // In the Send box, .to is never filled. In this case we look into destinations. + + if(fmpe.destinations.size()==1) + return QVariant(QString::fromStdString((*fmpe.destinations.begin()).toStdString())); + } default: return QVariant(); } @@ -541,8 +608,8 @@ QVariant RsMessageModel::decorationRole(const Rs::Msgs::MsgInfoSummary& fmpe,int case COLUMN_THREAD_SUBJECT: { if(fmpe.msgflags & RS_MSG_NEW ) return FilesDefs::getIconFromQtResourcePath(":/images/message-state-new.png"); - if(fmpe.msgflags & RS_MSG_USER_REQUEST) return FilesDefs::getIconFromQtResourcePath(":/images/user/user_request16.png"); - if(fmpe.msgflags & RS_MSG_FRIEND_RECOMMENDATION) return FilesDefs::getIconFromQtResourcePath(":/images/user/friend_suggestion16.png"); + if(fmpe.msgflags & RS_MSG_USER_REQUEST) return FilesDefs::getIconFromQtResourcePath(":/images/user/user_request48.png"); + if(fmpe.msgflags & RS_MSG_FRIEND_RECOMMENDATION) return FilesDefs::getIconFromQtResourcePath(":/images/user/invite24.png"); if(fmpe.msgflags & RS_MSG_PUBLISH_KEY) return FilesDefs::getIconFromQtResourcePath(":/images/share-icon-16.png"); if(fmpe.msgflags & RS_MSG_UNREAD_BY_USER) @@ -566,8 +633,10 @@ QVariant RsMessageModel::decorationRole(const Rs::Msgs::MsgInfoSummary& fmpe,int case COLUMN_THREAD_SPAM: return FilesDefs::getIconFromQtResourcePath((fmpe.msgflags & RS_MSG_SPAM) ? (IMAGE_SPAM_ON ): (IMAGE_SPAM_OFF)); - case COLUMN_THREAD_AUTHOR://Return icon as place holder. - return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.srcId.toStdString()),QIcon(), exist); + case COLUMN_THREAD_TO://Return icon as place holder. + return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.to.toStdString()),QIcon(), exist); + case COLUMN_THREAD_AUTHOR://Return icon as place holder. + return FilesDefs::getIconFromGxsIdCache(RsGxsId(fmpe.from.toStdString()),QIcon(), exist); } return QVariant(); } @@ -594,7 +663,7 @@ void RsMessageModel::setMessages(const std::list& msgs for(auto it(msgs.begin());it!=msgs.end();++it) { mMessagesMap[(*it).msgId] = mMessages.size(); - mMessages.push_back(*it); + mMessages.push_back(*it); } // now update prow for all posts @@ -612,7 +681,7 @@ void RsMessageModel::setMessages(const std::list& msgs emit messagesLoaded(); } -void RsMessageModel::setCurrentBox(BoxName bn) +void RsMessageModel::setCurrentBox(Rs::Msgs::BoxName bn) { if(mCurrentBox != bn) { @@ -629,47 +698,20 @@ void RsMessageModel::setQuickViewFilter(QuickViewFilter fn) std::cerr << "Changing new quickview filter to " << fn << std::endl; #endif - mQuickViewFilter = fn ; - updateMessages(); + mQuickViewFilter = fn ; + + if(rowCount() > 0) + emit dataChanged(createIndex(0,0),createIndex(rowCount()-1,RsMessageModel::columnCount()-1)); } } -void RsMessageModel::getMessageSummaries(BoxName box,std::list& msgs) -{ - rsMsgs->getMessageSummaries(msgs); - - // filter out messages that are not in the right box. - - for(auto it(msgs.begin());it!=msgs.end();) - { - bool ok = false; - - switch(box) - { - case BOX_INBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_INBOX && !(it->msgflags & RS_MSG_TRASH); break ; - case BOX_SENT : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_SENTBOX && !(it->msgflags & RS_MSG_TRASH); break ; - case BOX_OUTBOX : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_OUTBOX && !(it->msgflags & RS_MSG_TRASH); break ; - case BOX_DRAFTS : ok = (it->msgflags & RS_MSG_BOXMASK) == RS_MSG_DRAFTBOX && !(it->msgflags & RS_MSG_TRASH); break ; - case BOX_TRASH : ok = (it->msgflags & RS_MSG_TRASH) ; break ; - default: - ++it; - continue; - } - - if(ok) - ++it; - else - it = msgs.erase(it) ; - } -} - void RsMessageModel::updateMessages() { emit messagesAboutToLoad(); std::list msgs; - getMessageSummaries(mCurrentBox,msgs); + rsMsgs->getMessageSummaries(mCurrentBox,msgs); setMessages(msgs); emit messagesLoaded(); diff --git a/retroshare-gui/src/gui/msgs/MessageModel.h b/retroshare-gui/src/gui/msgs/MessageModel.h index 8021c3e24..fb8c6daa5 100644 --- a/retroshare-gui/src/gui/msgs/MessageModel.h +++ b/retroshare-gui/src/gui/msgs/MessageModel.h @@ -43,28 +43,20 @@ public: explicit RsMessageModel(QObject *parent = NULL); ~RsMessageModel(){} - enum BoxName { - BOX_NONE = 0x00, - BOX_INBOX = 0x01, - BOX_OUTBOX = 0x02, - BOX_DRAFTS = 0x03, - BOX_SENT = 0x04, - BOX_TRASH = 0x05 - }; - enum Columns { COLUMN_THREAD_STAR = 0x00, COLUMN_THREAD_ATTACHMENT = 0x01, COLUMN_THREAD_SUBJECT = 0x02, COLUMN_THREAD_READ = 0x03, COLUMN_THREAD_AUTHOR = 0x04, - COLUMN_THREAD_SPAM = 0x05, - COLUMN_THREAD_DATE = 0x06, - COLUMN_THREAD_TAGS = 0x07, - COLUMN_THREAD_MSGID = 0x08, - COLUMN_THREAD_NB_COLUMNS = 0x09, - COLUMN_THREAD_CONTENT = 0x09 - }; + COLUMN_THREAD_TO = 0x05, + COLUMN_THREAD_SPAM = 0x06, + COLUMN_THREAD_DATE = 0x07, + COLUMN_THREAD_TAGS = 0x08, + COLUMN_THREAD_MSGID = 0x09, + COLUMN_THREAD_CONTENT = 0x0a, + COLUMN_THREAD_NB_COLUMNS = 0x0b + }; enum QuickViewFilter { QUICK_VIEW_ALL = 0x00, @@ -84,10 +76,11 @@ public: FILTER_TYPE_NONE = 0x00, FILTER_TYPE_SUBJECT = 0x01, // These numbers have been carefuly chosen to match the ones in rsmsgs.h FILTER_TYPE_FROM = 0x02, - FILTER_TYPE_DATE = 0x03, - FILTER_TYPE_CONTENT = 0x04, - FILTER_TYPE_TAGS = 0x05, - FILTER_TYPE_ATTACHMENTS = 0x06, + FILTER_TYPE_TO = 0x03, + FILTER_TYPE_DATE = 0x04, + FILTER_TYPE_CONTENT = 0x05, + FILTER_TYPE_TAGS = 0x06, + FILTER_TYPE_ATTACHMENTS = 0x07, }; enum Roles{ SortRole = Qt::UserRole+1, @@ -103,11 +96,10 @@ public: QModelIndex getIndexOfMessage(const std::string &mid) const; static const QString FilterString ; - static void getMessageSummaries(BoxName box, std::list& msgs); // This method will asynchroneously update the data - void setCurrentBox(BoxName bn) ; + void setCurrentBox(Rs::Msgs::BoxName bn) ; void setQuickViewFilter(QuickViewFilter fn) ; void setFilter(FilterType filter_type, const QStringList& strings) ; @@ -187,7 +179,7 @@ private: QColor mTextColorNotSubscribed ; QColor mTextColorMissing ; - BoxName mCurrentBox ; + Rs::Msgs::BoxName mCurrentBox ; QuickViewFilter mQuickViewFilter ; QStringList mFilterStrings; FilterType mFilterType; diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp index 071f794ff..b29f264fb 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.cpp @@ -22,13 +22,21 @@ #include "MessageUserNotify.h" #include "gui/notifyqt.h" #include "gui/MainWindow.h" +#include "util/qtthreadsutils.h" +#include "gui/settings/rsharesettings.h" #include "gui/msgs/MessageInterface.h" MessageUserNotify::MessageUserNotify(QObject *parent) : UserNotify(parent) { - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(updateIcon())); + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); +} + +MessageUserNotify::~MessageUserNotify() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); } bool MessageUserNotify::hasSetting(QString *name, QString *group) @@ -72,3 +80,39 @@ void MessageUserNotify::iconClicked() { MainWindow::showWindow(MainWindow::Messages); } + +void MessageUserNotify::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + std::set::const_iterator it; + + switch (fe->mMailStatusEventCode) + { + case RsMailStatusEventCode::NEW_MESSAGE: + for (it = fe->mChangedMsgIds.begin(); it != fe->mChangedMsgIds.end(); ++it) { + MessageInfo msgInfo; + if (rsMail->getMessage(*it, msgInfo)) { + NotifyQt::getInstance()->addToaster(RS_POPUP_MSG, msgInfo.msgId.c_str(), msgInfo.title.c_str(), msgInfo.msg.c_str() ); + } + } + updateIcon(); + break; + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::MESSAGE_REMOVED: + updateIcon(); + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::TAG_CHANGED: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} diff --git a/retroshare-gui/src/gui/msgs/MessageUserNotify.h b/retroshare-gui/src/gui/msgs/MessageUserNotify.h index 58b30e8fc..f9b7458ab 100644 --- a/retroshare-gui/src/gui/msgs/MessageUserNotify.h +++ b/retroshare-gui/src/gui/msgs/MessageUserNotify.h @@ -21,6 +21,7 @@ #ifndef MESSAGEUSERNOTIFY_H #define MESSAGEUSERNOTIFY_H +#include #include "gui/common/UserNotify.h" class MessageUserNotify : public UserNotify @@ -29,6 +30,7 @@ class MessageUserNotify : public UserNotify public: MessageUserNotify(QObject *parent = 0); + virtual ~MessageUserNotify(); virtual bool hasSetting(QString *name, QString *group) override; @@ -41,6 +43,11 @@ private: virtual QString getNotifyMessage(bool plural) override; virtual void iconClicked() override; + + void handleEvent_main_thread(std::shared_ptr event); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif // MESSAGEUSERNOTIFY_H diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.cpp b/retroshare-gui/src/gui/msgs/MessageWidget.cpp index 9b671129f..0d2e934f2 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWidget.cpp @@ -46,6 +46,7 @@ #include "util/HandleRichText.h" #include "util/DateTime.h" #include "util/QtVersion.h" +#include "util/qtthreadsutils.h" #include #include @@ -65,7 +66,7 @@ class RsHtmlMsg : public RsHtml { public: - RsHtmlMsg(uint msgFlags) : RsHtml() + explicit RsHtmlMsg(uint msgFlags) : RsHtml() { this->msgFlags = msgFlags; } @@ -134,6 +135,7 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f isWindow = false; currMsgFlags = 0; expandFiles = false; + ui.expandButton->hide(); ui.actionTextBesideIcon->setData(Qt::ToolButtonTextBesideIcon); ui.actionIconOnly->setData(Qt::ToolButtonIconOnly); @@ -143,7 +145,8 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(getallrecommended())); connect(ui.msgText, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl))); connect(ui.sendInviteButton, SIGNAL(clicked()), this, SLOT(sendInvite())); - + connect(ui.expandButton, SIGNAL(clicked()), this, SLOT(expandTo())); + connect(ui.replyButton, SIGNAL(clicked()), this, SLOT(reply())); connect(ui.replyallButton, SIGNAL(clicked()), this, SLOT(replyAll())); connect(ui.forwardButton, SIGNAL(clicked()), this, SLOT(forward())); @@ -159,9 +162,6 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f viewsource->setShortcut(QKeySequence("CTRL+O")); connect(viewsource, SIGNAL(triggered()), this, SLOT(viewSource())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), this, SLOT(messagesChanged())); - ui.imageBlockWidget->addButtonAction(tr("Load images always for this message"), this, SLOT(loadImagesAlways()), true); ui.msgText->setImageBlockWidget(ui.imageBlockWidget); @@ -192,13 +192,13 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f QFont font = QFont("Arial", 10, QFont::Bold); ui.subjectText->setFont(font); - ui.toText->setMaximumHeight(ui.toText->fontMetrics().lineSpacing()*1.5); + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*1.5); ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->setMaximumHeight(ui.ccText->fontMetrics().lineSpacing()*1.5); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->setMaximumHeight(ui.trans_CCText->fontMetrics().lineSpacing()*1.5); ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->setMaximumHeight(ui.bccText->fontMetrics().lineSpacing()*1.5); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->setMaximumHeight(ui.trans_BCCText->fontMetrics().lineSpacing()*1.5); ui.tagsLabel->setVisible(false); @@ -210,7 +210,10 @@ MessageWidget::MessageWidget(bool controlled, QWidget *parent, Qt::WindowFlags f ui.dateText-> setText(""); - ui.inviteFrame->hide(); + ui.info_Frame_Invite->hide(); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); } MessageWidget::~MessageWidget() @@ -218,6 +221,47 @@ MessageWidget::~MessageWidget() if (isControlled == false) { processSettings("MessageWidget", false); } + + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + +void MessageWidget::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType != RsEventType::MAIL_STATUS) { + return; + } + + const RsMailStatusEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailStatusEventCode) { + case RsMailStatusEventCode::MESSAGE_REMOVED: + if (fe->mChangedMsgIds.find(currMsgId) != fe->mChangedMsgIds.end()) { + if (isControlled) { + /* processed by MessagesDialog */ + return; + } + + /* messages was removed */ + if (isWindow) { + window()->close(); + } else { + deleteLater(); + } + } + break; + case RsMailStatusEventCode::TAG_CHANGED: + messagesTagsChanged(); + break; + case RsMailStatusEventCode::MESSAGE_SENT: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } } void MessageWidget::connectAction(enumActionType actionType, QToolButton* button) @@ -349,24 +393,25 @@ void MessageWidget::getcurrentrecommended() } std::list srcIds; - srcIds.push_back(msgInfo.rspeerid_srcId); + if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + srcIds.push_back(msgInfo.from.toRsPeerId()); QModelIndexList list = ui.msgList->selectionModel()->selectedIndexes(); std::map files ; - for (QModelIndexList::const_iterator it(list.begin());it!=list.end();++it) { - FileInfo& fi(files[it->row()]) ; + for (auto &it : list) { + FileInfo& fi(files[it.row()]) ; - switch (it->column()) { + switch (it.column()) { case COLUMN_FILE_NAME: - fi.fname = it->data().toString().toUtf8().constData(); + fi.fname = it.data().toString().toUtf8().constData(); break ; case COLUMN_FILE_SIZE: - fi.size = it->data(Qt::UserRole).toULongLong() ; + fi.size = it.data(Qt::UserRole).toULongLong() ; break ; case COLUMN_FILE_HASH: - fi.hash = RsFileHash(it->data().toString().toStdString()) ; + fi.hash = RsFileHash(it.data().toString().toStdString()) ; break ; } } @@ -397,7 +442,10 @@ void MessageWidget::getallrecommended() for(it = recList.begin(); it != recList.end(); ++it) { std::cerr << "MessageWidget::getallrecommended() Calling File Request" << std::endl; std::list srcIds; - srcIds.push_back(msgInfo.rspeerid_srcId); + + if(msgInfo.from.type()==MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + srcIds.push_back(msgInfo.from.toRsPeerId()); + rsFiles->FileRequest(it->fname, it->hash, it->size, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds); } } @@ -407,25 +455,6 @@ void MessageWidget::messagesTagsChanged() showTagLabels(); } -void MessageWidget::messagesChanged() -{ - if (isControlled) { - /* processed by MessagesDialog */ - return; - } - - /* test Message */ - MessageInfo msgInfo; - if (rsMail->getMessage(currMsgId, msgInfo) == false) { - /* messages was removed */ - if (isWindow) { - window()->close(); - } else { - deleteLater(); - } - } -} - void MessageWidget::clearTagLabels() { /* clear all tags */ @@ -448,15 +477,17 @@ void MessageWidget::showTagLabels() MsgTagInfo tagInfo; rsMail->getMessageTag(currMsgId, tagInfo); - if (tagInfo.tagIds.empty() == false) { + if (!tagInfo.empty()) + { ui.tagsLabel->setVisible(true); MsgTagType Tags; rsMail->getMessageTagTypes(Tags); std::map >::iterator Tag; - for (std::list::iterator tagId = tagInfo.tagIds.begin(); tagId != tagInfo.tagIds.end(); ++tagId) { - Tag = Tags.types.find(*tagId); + for (auto tag:tagInfo) + { + Tag = Tags.types.find(tag); if (Tag != Tags.types.end()) { QLabel *tagLabel = new QLabel(TagDefs::name(Tag->first, Tag->second.first), this); tagLabel->setMaximumHeight(16); @@ -491,17 +522,17 @@ void MessageWidget::fill(const std::string &msgId) if (currMsgId.empty()) { /* blank it */ ui.dateText-> setText(""); - ui.toText->setText(""); + ui.trans_ToText->setText(""); ui.fromText->setText(""); ui.filesText->setText(""); ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->clear(); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->clear(); ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->clear(); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->clear(); ui.subjectText->setText(""); ui.msgList->clear(); @@ -511,7 +542,7 @@ void MessageWidget::fill(const std::string &msgId) clearTagLabels(); checkLength(); - ui.inviteFrame->hide(); + ui.info_Frame_Invite->hide(); ui.expandFilesButton->setChecked(false); ui.downloadButton->setEnabled(false); togglefileview(true); @@ -522,6 +553,9 @@ void MessageWidget::fill(const std::string &msgId) ui.deleteButton->setEnabled(false); ui.moreButton->setEnabled(false); + ui.expandButton->hide(); + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*1.5); + currMsgFlags = 0; return; @@ -542,17 +576,21 @@ void MessageWidget::fill(const std::string &msgId) return; } - if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && msgInfo.rsgxsid_srcId.isNull()){ - ui.inviteFrame->show(); - ui.sendInviteButton->hide(); - ui.infoLabel->setText(tr("You got an invite to make friend! You may accept this request.")); - } else if ((msgInfo.msgflags & RS_MSG_USER_REQUEST) && (!msgInfo.rsgxsid_srcId.isNull())){ - ui.inviteFrame->show(); - ui.sendInviteButton->show(); - ui.infoLabel->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back")); - } else { - ui.inviteFrame->hide(); - } + if (msgInfo.msgflags & RS_MSG_USER_REQUEST) + if(msgInfo.from.type() == MsgAddress::MSG_ADDRESS_TYPE_RSPEERID) + { + ui.info_Frame_Invite->show(); + ui.sendInviteButton->hide(); + ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request.")); + } + else + { + ui.info_Frame_Invite->show(); + ui.sendInviteButton->show(); + ui.infoLabel_Invite->setText(tr("You got an invite to make friend! You may accept this request and send your own Certificate back")); + } + else + ui.info_Frame_Invite->hide(); const std::list &recList = msgInfo.files; std::list::const_iterator it; @@ -581,67 +619,60 @@ void MessageWidget::fill(const std::string &msgId) /* iterate through the sources */ RetroShareLink link; - QString text; + QString to_text,cc_text,bcc_text; - for(std::set::const_iterator pit = msgInfo.rspeerid_msgto.begin(); pit != msgInfo.rspeerid_msgto.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - for(std::set::const_iterator pit = msgInfo.rsgxsid_msgto.begin(); pit != msgInfo.rsgxsid_msgto.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - - ui.toText->setText(text); - - if (!msgInfo.rspeerid_msgcc.empty() || !msgInfo.rsgxsid_msgcc.empty()) + for(auto m:msgInfo.destinations) { + if(m.type()==MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + link = RetroShareLink::createMessage(m.toGxsId(), ""); + else + link = RetroShareLink::createMessage(m.toRsPeerId(), ""); + + if (link.valid()) + switch(m.mode()) + { + case MsgAddress::MSG_ADDRESS_MODE_TO: to_text += link.toHtml() + " "; break; + case MsgAddress::MSG_ADDRESS_MODE_CC: cc_text += link.toHtml() + " "; break; + case MsgAddress::MSG_ADDRESS_MODE_BCC: bcc_text += link.toHtml() + " "; break; + default: break; + } + } + + ui.trans_ToText->setText(to_text); + + int recipientsCount = ui.trans_ToText->toPlainText().split(QRegExp("(\\s|\\n|\\r)+"), QString::SkipEmptyParts).count(); + ui.expandButton->setText( QString::number(recipientsCount)+ " " + tr("more")); + + if (recipientsCount >=20) { + ui.expandButton->show(); + } else { + ui.expandButton->hide(); + ui.expandButton->setChecked(false); + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*1.5); + } + + if (!cc_text.isNull()) + { ui.ccLabel->setVisible(true); - ui.ccText->setVisible(true); + ui.trans_CCText->setVisible(true); - text.clear(); - for(std::set::const_iterator pit = msgInfo.rspeerid_msgcc.begin(); pit != msgInfo.rspeerid_msgcc.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - for(std::set::const_iterator pit = msgInfo.rsgxsid_msgcc.begin(); pit != msgInfo.rsgxsid_msgcc.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - - ui.ccText->setText(text); + ui.trans_CCText->setText(cc_text); } else { ui.ccLabel->setVisible(false); - ui.ccText->setVisible(false); - ui.ccText->clear(); + ui.trans_CCText->setVisible(false); + ui.trans_CCText->clear(); } - if (!msgInfo.rspeerid_msgbcc.empty() || !msgInfo.rsgxsid_msgbcc.empty()) + if (!bcc_text.isNull()) { ui.bccLabel->setVisible(true); - ui.bccText->setVisible(true); + ui.trans_BCCText->setVisible(true); - text.clear(); - for(std::set::const_iterator pit = msgInfo.rspeerid_msgbcc.begin(); pit != msgInfo.rspeerid_msgbcc.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - for(std::set::const_iterator pit = msgInfo.rsgxsid_msgbcc.begin(); pit != msgInfo.rsgxsid_msgbcc.end(); ++pit) { - link = RetroShareLink::createMessage(*pit, ""); - if (link.valid()) - text += link.toHtml() + " "; - } - - ui.bccText->setText(text); + ui.trans_BCCText->setText(bcc_text); } else { ui.bccLabel->setVisible(false); - ui.bccText->setVisible(false); - ui.bccText->clear(); + ui.trans_BCCText->setVisible(false); + ui.trans_BCCText->clear(); } ui.dateText->setText(DateTime::formatDateTime(msgInfo.ts)); @@ -655,21 +686,24 @@ void MessageWidget::fill(const std::string &msgId) // link.createMessage(ownId, ""); // } - if(msgInfo.msgflags & RS_MSG_DISTANT) // distant message + if(msgInfo.from.type()==Rs::Msgs::MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) // distant message { - tooltip_string = PeerDefs::rsidFromId(msgInfo.rsgxsid_srcId) ; - link = RetroShareLink::createMessage(msgInfo.rsgxsid_srcId, ""); + tooltip_string = PeerDefs::rsidFromId(msgInfo.from.toGxsId()) ; + link = RetroShareLink::createMessage(msgInfo.from.toGxsId(), ""); } else { - tooltip_string = PeerDefs::rsidFromId(msgInfo.rspeerid_srcId) ; - link = RetroShareLink::createMessage(msgInfo.rspeerid_srcId, ""); + tooltip_string = PeerDefs::rsidFromId(msgInfo.from.toRsPeerId()) ; + link = RetroShareLink::createMessage(msgInfo.from.toRsPeerId(), ""); } - if (((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.rspeerid_srcId == ownId) || msgInfo.rspeerid_srcId.isNull()) { + if ((msgInfo.msgflags & RS_MSG_SYSTEM) && msgInfo.from.toRsPeerId() == ownId) + { ui.fromText->setText("[Notification]"); if (toolButtonReply) toolButtonReply->setEnabled(false); - } else { + } + else + { ui.fromText->setText(link.toHtml()); ui.fromText->setToolTip(tooltip_string) ; if (toolButtonReply) toolButtonReply->setEnabled(true); @@ -683,7 +717,7 @@ void MessageWidget::fill(const std::string &msgId) if (Settings->valueFromGroup(QString("Messages"), QString::fromUtf8("Emoticons"), true).toBool()) { formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS ; } - text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), formatTextFlag); + QString text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), formatTextFlag); ui.msgText->resetImagesStatus(Settings->getMsgLoadEmbeddedImages() || (msgInfo.msgflags & RS_MSG_LOAD_EMBEDDED_IMAGES)); ui.msgText->setHtml(text); @@ -704,7 +738,8 @@ void MessageWidget::remove() return; } - bool deleteReal = false; +#ifdef TO_REMOVE + bool deleteReal = false; if (msgInfo.msgflags & RS_MSG_TRASH) { deleteReal = true; } else { @@ -729,8 +764,8 @@ void MessageWidget::remove() deleteLater(); } } - - emit messageRemoved(); +#endif + emit messageRemovalRequested(currMsgId); } void MessageWidget::print() @@ -860,19 +895,19 @@ void MessageWidget::loadImagesAlways() void MessageWidget::sendInvite() { - MessageInfo mi; + MessageInfo mi; - if (!rsMail) - return; + if (!rsMail) + return; - if (!rsMail->getMessage(currMsgId, mi)) - return; + if (!rsMail->getMessage(currMsgId, mi)) + return; - //if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want send a invite with your Certificate?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) - //{ - MessageComposer::sendInvite(mi.rsgxsid_srcId,false); - //} + if(mi.from.type()!=MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) + return; + //if ((QMessageBox::question(this, tr("Send invite?"),tr("Do you really want to send an invite with your Certificate?"),QMessageBox::Yes, QMessageBox::No))== QMessageBox::Yes) + MessageComposer::sendInvite(mi.from.toGxsId(),false); } void MessageWidget::setToolbarButtonStyle(Qt::ToolButtonStyle style) @@ -916,4 +951,15 @@ void MessageWidget::checkLength() text = tr("%1 (%2) ").arg(charlength).arg(misc::friendlyUnit(charlength)); ui.sizeLabel->setText(text); -} \ No newline at end of file +} + +void MessageWidget::expandTo() +{ + if (ui.expandButton->isChecked()) { + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*3.5); + ui.expandButton->setToolTip(tr("Show less")); + } else { + ui.trans_ToText->setMaximumHeight(ui.trans_ToText->fontMetrics().lineSpacing()*1.5); + ui.expandButton->setToolTip(tr("Show more")); + } +} diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.h b/retroshare-gui/src/gui/msgs/MessageWidget.h index 5acf627f6..53b043720 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.h +++ b/retroshare-gui/src/gui/msgs/MessageWidget.h @@ -22,6 +22,7 @@ #define _MESSAGEWIDGET_H #include +#include #include "ui_MessageWidget.h" class QToolButton; @@ -60,6 +61,7 @@ public: signals: void messageRemoved(); + void messageRemovalRequested(std::string); private slots: void reply(); @@ -71,11 +73,10 @@ private slots: void saveAs(); void refill(); void sendInvite(); - + void expandTo(); void msgfilelistWidgetCostumPopupMenu(QPoint); void messagesTagsChanged(); - void messagesChanged(); void togglefileview(bool noUpdate = false); void getcurrentrecommended(); @@ -93,11 +94,14 @@ private: void showTagLabels(); void setToolbarButtonStyle(Qt::ToolButtonStyle style); + void handleEvent_main_thread(std::shared_ptr event); + bool isControlled; bool isWindow; std::string currMsgId; unsigned int currMsgFlags; bool expandFiles; + RsEventsHandlerId_t mEventHandlerId; QList tagLabels; diff --git a/retroshare-gui/src/gui/msgs/MessageWidget.ui b/retroshare-gui/src/gui/msgs/MessageWidget.ui index c781dc5d1..de580d7e5 100644 --- a/retroshare-gui/src/gui/msgs/MessageWidget.ui +++ b/retroshare-gui/src/gui/msgs/MessageWidget.ui @@ -51,93 +51,6 @@ 3 - - - - - 0 - 0 - - - - - 9 - - - - Bcc: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 9 - - - - To: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 9 - - - - Cc: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - false - - - - - - - - 0 - 0 - - - - - 9 - - - - Tags: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -290,6 +203,114 @@
    + + + + + 0 + 0 + + + + + 9 + + + + Tags: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 9 + + + + Subject: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 9 + + + + Cc: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + + + + + + 0 + 0 + + + + + 9 + + + + Bcc: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 9 + + + + To: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + @@ -313,6 +334,25 @@ + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + true + + + @@ -346,8 +386,8 @@ - - + + 0 @@ -365,68 +405,9 @@ - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - true - - - - - - - - 0 - 0 - - - - - 16777215 - 16 - - - - true - - - - + - - - - - 0 - 0 - - - - - 9 - - - - Subject: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - @@ -448,6 +429,48 @@ + + + + 6 + + + + + + 0 + 0 + + + + + 16777215 + 16 + + + + true + + + + + + + + + + true + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon + + + + + @@ -461,10 +484,19 @@ - + + + + + 0 + 0 + 0 + + + @@ -485,6 +517,15 @@ + + + + 0 + 0 + 0 + + + @@ -505,6 +546,15 @@ + + + + 154 + 154 + 154 + + + @@ -535,7 +585,7 @@ QFrame::Box - + 6 @@ -549,7 +599,7 @@ 6 - + 16 @@ -568,7 +618,7 @@ - + You got an invite to make friend! You may accept this request and send your own Certificate back diff --git a/retroshare-gui/src/gui/msgs/MessageWindow.cpp b/retroshare-gui/src/gui/msgs/MessageWindow.cpp index ad1067367..0c9abf2a2 100644 --- a/retroshare-gui/src/gui/msgs/MessageWindow.cpp +++ b/retroshare-gui/src/gui/msgs/MessageWindow.cpp @@ -150,7 +150,7 @@ void MessageWindow::tagAboutToShow() MsgTagInfo tagInfo; rsMail->getMessageTag(msgWidget->msgId(), tagInfo); - menu->activateActions(tagInfo.tagIds); + menu->activateActions(tagInfo); } void MessageWindow::tagRemoveAll() diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp index ffc108a53..de91df5ff 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.cpp @@ -44,9 +44,10 @@ #include "gui/settings/rsharesettings.h" #include "util/DateTime.h" -#include "util/RsProtectedTimer.h" +#include "util/misc.h" #include "util/QtVersion.h" #include "util/qtthreadsutils.h" +#include "util/RsProtectedTimer.h" #include #include @@ -94,6 +95,7 @@ #define ROW_SENTBOX 3 #define ROW_TRASHBOX 4 +// #define DEBUG_MESSAGES_DIALOG 1 class MessageSortFilterProxyModel: public QSortFilterProxyModel { @@ -139,14 +141,15 @@ MessagesDialog::MessagesDialog(QWidget *parent) inChange = false; lockUpdate = 0; lastSelectedIndex = QModelIndex(); + mLastCurrentQuickViewRow = -1; msgWidget = new MessageWidget(true, this); ui.msgLayout->addWidget(msgWidget); - connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); + connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage())); connectActions(); - listMode = LIST_NOTHING; + //listMode = LIST_NOTHING; mMessageModel = new RsMessageModel(this); mMessageProxyModel = new MessageSortFilterProxyModel(this); @@ -165,6 +168,7 @@ MessagesDialog::MessagesDialog(QWidget *parent) ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_SUBJECT,itemDelegate); ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_AUTHOR,new GxsIdTreeItemDelegate()) ; + ui.messageTreeWidget->setItemDelegateForColumn(RsMessageModel::COLUMN_THREAD_TO,new GxsIdTreeItemDelegate()) ; // workaround for Qt bug, should be solved in next Qt release 4.7.0 // http://bugreports.qt.nokia.com/browse/QTBUG-8270 @@ -189,6 +193,7 @@ MessagesDialog::MessagesDialog(QWidget *parent) /* add filter actions */ ui.filterLineEdit->addFilter(QIcon(), tr("Subject"), RsMessageModel::COLUMN_THREAD_SUBJECT, tr("Search Subject")); ui.filterLineEdit->addFilter(QIcon(), tr("From"), RsMessageModel::COLUMN_THREAD_AUTHOR, tr("Search From")); + ui.filterLineEdit->addFilter(QIcon(), tr("To"), RsMessageModel::COLUMN_THREAD_TO, tr("Search To")); ui.filterLineEdit->addFilter(QIcon(), tr("Date"), RsMessageModel::COLUMN_THREAD_DATE, tr("Search Date")); ui.filterLineEdit->addFilter(QIcon(), tr("Content"), RsMessageModel::COLUMN_THREAD_CONTENT, tr("Search Content")); ui.filterLineEdit->addFilter(QIcon(), tr("Tags"), RsMessageModel::COLUMN_THREAD_TAGS, tr("Search Tags")); @@ -211,22 +216,27 @@ MessagesDialog::MessagesDialog(QWidget *parent) msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_SUBJECT, fm.width("You have a message")*3.0); msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_AUTHOR, fm.width("[Retroshare]")*1.1); + msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_TO, fm.width("[Retroshare]")*1.1); msgwheader->resizeSection (RsMessageModel::COLUMN_THREAD_DATE, fm.width("01/01/1970")*1.1); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_SUBJECT, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_AUTHOR, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_DATE, QHeaderView::Interactive); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_SUBJECT, QHeaderView::Interactive); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_AUTHOR, QHeaderView::Interactive); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_TO, QHeaderView::Interactive); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_DATE, QHeaderView::Interactive); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_STAR, QHeaderView::Fixed); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_ATTACHMENT, QHeaderView::Fixed); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_READ, QHeaderView::Fixed); - QHeaderView_setSectionResizeModeColumn(msgwheader, RsMessageModel::COLUMN_THREAD_SPAM, QHeaderView::Fixed); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_STAR, QHeaderView::Fixed); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_ATTACHMENT, QHeaderView::Fixed); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_READ, QHeaderView::Fixed); + msgwheader->setSectionResizeMode(RsMessageModel::COLUMN_THREAD_SPAM, QHeaderView::Fixed); ui.messageTreeWidget->setSortingEnabled(true); /* Set header sizes for the fixed columns and resize modes, must be set after processSettings */ msgwheader->setStretchLastSection(true); + QFontMetricsF fontMetrics(ui.messageTreeWidget->font()); + int iconHeight = fontMetrics.height() * 1.4; + ui.messageTreeWidget->setIconSize(QSize(iconHeight, iconHeight)); // fill folder list updateMessageSummaryList(); @@ -245,32 +255,26 @@ MessagesDialog::MessagesDialog(QWidget *parent) sortColumn(RsMessageModel::COLUMN_THREAD_DATE,Qt::DescendingOrder); - // load settings - processSettings(true); - //ui.messageTreeWidget->installEventFilter(this); // remove close button of the the first tab ui.tabWidget->hideCloseButton(0); ui.tabWidget->setHideTabBarWithOneTab(true); - int S = QFontMetricsF(font()).height(); - QString help_str = tr( - "

      Messages

    \ -

    Retroshare has its own internal email system. You can send/receive emails to/from connected friend nodes.

    \ -

    It is also possible to send messages to other people's Identities using the global routing system. These messages \ - are always encrypted and signed, and are relayed by intermediate nodes until they reach their final destination.

    \ -

    Distant messages stay into your Outbox until an acknowledgement of receipt has been received.

    \ -

    Generally, you may use messages to recommend files to your friends by pasting file links, \ - or recommend friend nodes to other friend nodes, in order to strengthen your network, or send feedback \ - to a channel's owner.

    \ - ").arg(QString::number(2*S), QString::number(S)) ; + int H = misc::getFontSizeFactor("HelpButton").height(); + QString help_str = tr( + "

      Messages

    " + "

    Retroshare has its own internal email system. You can send/receive emails to/from connected friend nodes.

    " + "

    It is also possible to send messages to other people's Identities using the global routing system. These messages" + " are always encrypted and signed, and are relayed by intermediate nodes until they reach their final destination.

    " + "

    Distant messages stay into your Outbox until an acknowledgement of receipt has been received.

    " + "

    Generally, you may use messages to recommend files to your friends by pasting file links," + " or recommend friend nodes to other friend nodes, in order to strengthen your network, or send feedback" + " to a channel's owner.

    " + ).arg(QString::number(2*H)) ; registerHelpButton(ui.helpButton,help_str,"MessagesDialog") ; - connect(NotifyQt::getInstance(), SIGNAL(messagesChanged()), mMessageModel, SLOT(updateMessages())); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(messagesTagsChanged())); - connect(ui.filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); connect(ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); @@ -279,10 +283,10 @@ MessagesDialog::MessagesDialog(QWidget *parent) connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint))); connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int))); - connect(ui.quickViewWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeQuickView(int))); connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int))); connect(ui.newmessageButton, SIGNAL(clicked()), this, SLOT(newmessage())); + connect(ui.quickViewWidget, SIGNAL(clicked(const QModelIndex&)), this, SLOT(resetQuickView(const QModelIndex&))); connect(ui.messageTreeWidget, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&))); connect(ui.messageTreeWidget, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&))); @@ -292,8 +296,16 @@ MessagesDialog::MessagesDialog(QWidget *parent) connect(ui.messageTreeWidget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), this, SLOT(currentChanged(const QModelIndex&,const QModelIndex&))); + // load settings + processSettings(true); + + ui.listWidget->setCurrentRow(0); // always starts with inbox => allows to setup the proper number of columns + mEventHandlerId=0; rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_STATUS ); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleTagEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); } void MessagesDialog::handleEvent_main_thread(std::shared_ptr event) @@ -310,9 +322,34 @@ void MessagesDialog::handleEvent_main_thread(std::shared_ptr even case RsMailStatusEventCode::MESSAGE_SENT: case RsMailStatusEventCode::MESSAGE_REMOVED: case RsMailStatusEventCode::NEW_MESSAGE: + case RsMailStatusEventCode::MESSAGE_CHANGED: + case RsMailStatusEventCode::TAG_CHANGED: + mMessageModel->updateMessages(); updateMessageSummaryList(); break; - default: + case RsMailStatusEventCode::MESSAGE_RECEIVED_ACK: + case RsMailStatusEventCode::SIGNATURE_FAILED: + break; + } +} + +void MessagesDialog::handleTagEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillQuickView(); + mMessageModel->updateMessages(); break; } } @@ -324,14 +361,23 @@ void MessagesDialog::preModelUpdate() mTmpSavedSelectedIds.clear(); getSelectedMessages(mTmpSavedSelectedIds); + mTmpSavedCurrentId.clear(); + const QModelIndex& m = ui.messageTreeWidget->currentIndex(); + if (m.isValid()) { + mTmpSavedCurrentId = m.sibling(m.row(), RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString(); + } +#ifdef DEBUG_MESSAGES_DIALOG std::cerr << "Pre-change: saving selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; +#endif } void MessagesDialog::postModelUpdate() { // restore selection +#ifdef DEBUG_MESSAGES_DIALOG std::cerr << "Post-change: restoring selection for " << mTmpSavedSelectedIds.size() << " indexes" << std::endl; +#endif QItemSelection sel; foreach(const QString& s,mTmpSavedSelectedIds) @@ -340,7 +386,17 @@ void MessagesDialog::postModelUpdate() sel.select(i.sibling(i.row(),0),i.sibling(i.row(),RsMessageModel::COLUMN_THREAD_NB_COLUMNS-1)); } - ui.messageTreeWidget->selectionModel()->select(sel,QItemSelectionModel::SelectCurrent); + // Restoring selection should not trigger anything, especially the re-display of the msg, which + // in turn will change the read status. + + whileBlocking(ui.messageTreeWidget->selectionModel())->select(sel,QItemSelectionModel::SelectCurrent); + + if (!mTmpSavedCurrentId.isEmpty()) { + QModelIndex index = mMessageProxyModel->mapFromSource(mMessageModel->getIndexOfMessage(mTmpSavedCurrentId.toStdString())); + if (index.isValid()) { + whileBlocking(ui.messageTreeWidget->selectionModel())->setCurrentIndex(index, QItemSelectionModel::Select); + } + } } void MessagesDialog::sortColumn(int col,Qt::SortOrder so) @@ -356,6 +412,9 @@ MessagesDialog::~MessagesDialog() { // save settings processSettings(false); + + rsEvents->unregisterEventsHandler(mEventHandlerId); + rsEvents->unregisterEventsHandler(mTagEventHandlerId); } UserNotify *MessagesDialog::createUserNotify(QObject *parent) @@ -365,7 +424,7 @@ UserNotify *MessagesDialog::createUserNotify(QObject *parent) void MessagesDialog::processSettings(bool load) { - int messageTreeVersion = 3; // version number for the settings to solve problems when modifying the column count + int messageTreeVersion = 4; // version number for the settings to solve problems when modifying the column count inProcessSettings = true; @@ -452,7 +511,7 @@ void MessagesDialog::fillQuickView() ui.quickViewWidget->clear(); // add static items - item = new QListWidgetItem(tr("Starred"), ui.quickViewWidget); + item = new QListWidgetItem(tr("Stared"), ui.quickViewWidget); item->setIcon(FilesDefs::getIconFromQtResourcePath(IMAGE_STAR_ON)); item->setData(ROLE_QUICKVIEW_TYPE, QUICKVIEW_TYPE_STATIC); item->setData(ROLE_QUICKVIEW_ID, QUICKVIEW_STATIC_ID_STARRED); @@ -618,13 +677,13 @@ void MessagesDialog::messageTreeWidgetCustomPopupMenu(QPoint /*point*/) QMenu contextMnu( this ); - QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/view_split_top_bottom.png"), tr("Open in a new window"), this, SLOT(openAsWindow())); + QAction *action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(":/icons/newwindow.svg"), tr("Open in a new window"), this, SLOT(openAsWindow())); if (nCount != 1) { action->setDisabled(true); } - action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/tab-dock.png"), tr("Open in a new tab"), this, SLOT(openAsTab())); + action = contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(":/icons/newtab.svg"), tr("Open in a new tab"), this, SLOT(openAsTab())); if (nCount != 1) { action->setDisabled(true); } @@ -704,12 +763,12 @@ void MessagesDialog::messageTreeWidgetCustomPopupMenu(QPoint /*point*/) // test if identity is known. If not, no need to call the people tab. Also some mails come from nodes and we wont show that node in the people tab either. // The problem here is that the field rsgxsid_srcId is always populated with either the GxsId or the node of the source, which is inconsistent. - if(nCount==1 && rsIdentity->getIdDetails(msgInfo.rsgxsid_srcId,details)) + if(nCount==1 && msgInfo.from.type() == MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) { - std::cerr << "Src ID = " << msgInfo.rsgxsid_srcId << std::endl; + std::cerr << "Src ID = " << msgInfo.from.toGxsId() << std::endl; - contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR_INFO),tr("Show author in People"),this,SLOT(showAuthorInPeopleTab())); - contextMnu.addSeparator(); + contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR_INFO),tr("Show in People"),this,SLOT(showAuthorInPeopleTab())); + contextMnu.addSeparator(); } contextMnu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_MESSAGE), tr("New Message"), this, SLOT(newmessage())); @@ -729,7 +788,7 @@ void MessagesDialog::showAuthorInPeopleTab() if (!rsMail->getMessage(mid, msgInfo)) return; - if(msgInfo.rsgxsid_srcId.isNull()) + if(msgInfo.from.type() != MsgAddress::MSG_ADDRESS_TYPE_RSGXSID) return ; /* window will destroy itself! */ @@ -739,7 +798,7 @@ void MessagesDialog::showAuthorInPeopleTab() return ; MainWindow::showWindow(MainWindow::People); - idDialog->navigate(RsGxsId(msgInfo.rsgxsid_srcId)) ; + idDialog->navigate(RsGxsId(msgInfo.from.toGxsId())) ; } void MessagesDialog::folderlistWidgetCustomPopupMenu(QPoint /*point*/) @@ -783,7 +842,7 @@ void MessagesDialog::openAsWindow() } msgWidget->activateWindow(); - connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); + connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage())); /* window will destroy itself! */ } @@ -803,7 +862,7 @@ void MessagesDialog::openAsTab() ui.tabWidget->addTab(msgWidget,FilesDefs::getIconFromQtResourcePath(IMAGE_MAIL), msgWidget->subject(true)); ui.tabWidget->setCurrentWidget(msgWidget); - connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved())); + connect(msgWidget, SIGNAL(messageRemovalRequested(std::string)), this, SLOT(removemessage())); /* window will destroy itself! */ } @@ -841,54 +900,76 @@ void MessagesDialog::changeBox(int box_row) if (item) { ui.quickViewWidget->setCurrentItem(NULL); - changeQuickView(-1); - listMode = LIST_BOX; + changeQuickView(-1); + //listMode = LIST_BOX; QString placeholderText = tr("No message available in your %1.").arg(item->text()); switch(box_row) { - case ROW_INBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_INBOX ); + case ROW_INBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_INBOX ); + break; + case ROW_OUTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_OUTBOX); break; - case ROW_OUTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_OUTBOX); + case ROW_DRAFTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_DRAFTS); break; - case ROW_DRAFTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_DRAFTS); + case ROW_SENTBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_SENT ); break; - case ROW_SENTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_SENT ); - break; - case ROW_TRASHBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_TRASH ); + case ROW_TRASHBOX: mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_TRASH ); break; default: - mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE); + mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_NONE); } insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex()); + ui.messageTreeWidget->setPlaceholderText(placeholderText); - } + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_READ,box_row!=ROW_INBOX); + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_STAR,box_row==ROW_OUTBOX); + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_SPAM,box_row==ROW_OUTBOX); + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_TAGS,box_row==ROW_OUTBOX); + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_MSGID,true); + ui.messageTreeWidget->setColumnHidden(RsMessageModel::COLUMN_THREAD_CONTENT,true); + } else { - mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE); + mMessageModel->setCurrentBox(Rs::Msgs::BoxName::BOX_NONE); } inChange = false; updateMessageSummaryList(); } +void MessagesDialog::resetQuickView(const QModelIndex& i) +{ + if(!i.isValid()) + return; + + int n = ui.quickViewWidget->currentRow(); + + if(mLastCurrentQuickViewRow == n) + { + changeQuickView(-1); + ui.quickViewWidget->setCurrentRow(-1); + } + else + changeQuickView(n); +} void MessagesDialog::changeQuickView(int newrow) { - + mLastCurrentQuickViewRow = newrow; RsMessageModel::QuickViewFilter f = RsMessageModel::QUICK_VIEW_ALL ; QListWidgetItem* item = ui.quickViewWidget->item(newrow); if(item ) { - ui.listWidget->setCurrentItem(NULL); - changeBox(-1); - - listMode = LIST_QUICKVIEW; + //ui.listWidget->setCurrentItem(NULL); + //changeBox(-1); + //listMode = LIST_QUICKVIEW; QString placeholderText; - switch (item->data(ROLE_QUICKVIEW_TYPE).toInt()) { + switch (item->data(ROLE_QUICKVIEW_TYPE).toInt()) + { case QUICKVIEW_TYPE_TAG: { placeholderText = tr("No message using %1 tag available.").arg(item->data(ROLE_QUICKVIEW_TEXT).toString()); @@ -913,21 +994,14 @@ void MessagesDialog::changeQuickView(int newrow) } } - insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex()); + //insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex()); ui.messageTreeWidget->setPlaceholderText(placeholderText); } mMessageModel->setQuickViewFilter(f); - mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model + mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model } -void MessagesDialog::messagesTagsChanged() -{ - fillQuickView(); - mMessageModel->updateMessages(); -} - - // click in messageTreeWidget void MessagesDialog::currentChanged(const QModelIndex& new_proxy_index,const QModelIndex& /*old_proxy_index*/) { @@ -951,21 +1025,16 @@ void MessagesDialog::clicked(const QModelIndex& proxy_index) case RsMessageModel::COLUMN_THREAD_READ: { mMessageModel->setMsgReadStatus(real_index, !isMessageRead(proxy_index)); - //Already updated by currentChanged - //insertMsgTxtAndFiles(proxy_index); - updateMessageSummaryList(); return; } case RsMessageModel::COLUMN_THREAD_STAR: { mMessageModel->setMsgStar(real_index, !hasMessageStar(proxy_index)); - updateMessageSummaryList(); return; } case RsMessageModel::COLUMN_THREAD_SPAM: { mMessageModel->setMsgJunk(real_index, !hasMessageSpam(proxy_index)); - updateMessageSummaryList(); return; } } @@ -1111,12 +1180,17 @@ void MessagesDialog::removemessage() bool doDelete = false; int listrow = ui.listWidget->currentRow(); - if (listrow == ROW_TRASHBOX) { + + if(listrow == ROW_TRASHBOX || (QApplication::keyboardModifiers() & Qt::ShiftModifier)) + doDelete = true; + + if(listrow == ROW_OUTBOX) + { + if(QMessageBox::question(nullptr,tr("Deletion is not recommended"),tr("Messages in this box are automatically deleted when received. Manually deleting a message does not guaranty that the message will not be delivered. Messages that cannot be delivered will however stay here indefinitly. Do you want to proceed and delete?")) + != QMessageBox::Yes) + return ; + doDelete = true; - } else { - if (QApplication::keyboardModifiers() & Qt::ShiftModifier) { - doDelete = true; - } } foreach (const QString& m, selectedMessages) { @@ -1163,6 +1237,7 @@ void MessagesDialog::filterChanged(const QString& text) { case RsMessageModel::COLUMN_THREAD_SUBJECT: f = RsMessageModel::FILTER_TYPE_SUBJECT ; break; case RsMessageModel::COLUMN_THREAD_AUTHOR: f = RsMessageModel::FILTER_TYPE_FROM ; break; + case RsMessageModel::COLUMN_THREAD_TO: f = RsMessageModel::FILTER_TYPE_TO ; break; case RsMessageModel::COLUMN_THREAD_DATE: f = RsMessageModel::FILTER_TYPE_DATE ; break; case RsMessageModel::COLUMN_THREAD_CONTENT: f = RsMessageModel::FILTER_TYPE_CONTENT ; break; case RsMessageModel::COLUMN_THREAD_TAGS: f = RsMessageModel::FILTER_TYPE_TAGS ; break; @@ -1187,6 +1262,7 @@ void MessagesDialog::filterColumnChanged(int column) { case RsMessageModel::COLUMN_THREAD_SUBJECT: f = RsMessageModel::FILTER_TYPE_SUBJECT ; break; case RsMessageModel::COLUMN_THREAD_AUTHOR: f = RsMessageModel::FILTER_TYPE_FROM ; break; + case RsMessageModel::COLUMN_THREAD_TO: f = RsMessageModel::FILTER_TYPE_TO ; break; case RsMessageModel::COLUMN_THREAD_DATE: f = RsMessageModel::FILTER_TYPE_DATE ; break; case RsMessageModel::COLUMN_THREAD_CONTENT: f = RsMessageModel::FILTER_TYPE_CONTENT ; break; case RsMessageModel::COLUMN_THREAD_TAGS: f = RsMessageModel::FILTER_TYPE_TAGS ; break; @@ -1220,7 +1296,7 @@ void MessagesDialog::updateMessageSummaryList() /* calculating the new messages */ std::list msgList; - rsMail->getMessageSummaries(msgList); + rsMail->getMessageSummaries(Rs::Msgs::BoxName::BOX_ALL,msgList); QMap tagCount; @@ -1236,17 +1312,14 @@ void MessagesDialog::updateMessageSummaryList() tagCount [*tagId] = nCount; } - if (it->msgflags & RS_MSG_STAR) { + if (it->msgflags & RS_MSG_STAR) ++starredCount; - } - if (it->msgflags & RS_MSG_SYSTEM) { + if (it->msgflags & RS_MSG_SYSTEM) ++systemCount; - } - if (it->msgflags & RS_MSG_SPAM) { + if (it->msgflags & RS_MSG_SPAM) ++spamCount; - } /* calculate box */ if (it->msgflags & RS_MSG_TRASH) { @@ -1264,7 +1337,7 @@ void MessagesDialog::updateMessageSummaryList() case RS_MSG_OUTBOX: ++newOutboxCount; break; - case RS_MSG_DRAFTBOX: + case RS_MSG_DRAFT: // not RS_MSG_DRAFTBOX because drafts are not considered outgoing ++newDraftCount; break; case RS_MSG_SENTBOX: @@ -1301,7 +1374,7 @@ void MessagesDialog::updateMessageSummaryList() break; } - +std::cerr << "NewInboxCount = " << newInboxCount << " NewDraftCount = " << newDraftCount << std::endl; QString textItem; /*updating the labels in leftcolumn*/ @@ -1335,7 +1408,7 @@ void MessagesDialog::updateMessageSummaryList() textItem = tr("Outbox") + " (" + QString::number(newOutboxCount)+")"; item->setText(textItem); QFont qf = item->font(); - qf.setBold(true); + qf.setBold(false); item->setFont(qf); } else @@ -1402,16 +1475,20 @@ void MessagesDialog::updateMessageSummaryList() QString text = qv_item->data(ROLE_QUICKVIEW_TEXT).toString(); switch (qv_item->data(ROLE_QUICKVIEW_ID).toInt()) { case QUICKVIEW_STATIC_ID_STARRED: - text += " (" + QString::number(starredCount) + ")"; + if(starredCount>0) + text += " (" + QString::number(starredCount) + ")"; break; case QUICKVIEW_STATIC_ID_SYSTEM: - text += " (" + QString::number(systemCount) + ")"; + if(systemCount > 0) + text += " (" + QString::number(systemCount) + ")"; break; case QUICKVIEW_STATIC_ID_SPAM: - text += " (" + QString::number(spamCount) + ")"; + if(spamCount > 0) + text += " (" + QString::number(spamCount) + ")"; break; case QUICKVIEW_STATIC_ID_ATTACHMENT: - text += " (" + QString::number(attachmentCount) + ")"; + if(attachmentCount > 0) + text += " (" + QString::number(attachmentCount) + ")"; break; } @@ -1425,11 +1502,10 @@ void MessagesDialog::updateMessageSummaryList() void MessagesDialog::tagAboutToShow() { -#ifdef TODO TagsMenu *menu = dynamic_cast(ui.tagButton->menu()); - if (menu == NULL) { + + if (menu == NULL) return; - } // activate actions from the first selected row MsgTagInfo tagInfo; @@ -1440,8 +1516,7 @@ void MessagesDialog::tagAboutToShow() if(!msgids.empty()) rsMail->getMessageTag(msgids.front().toStdString(), tagInfo); - menu->activateActions(tagInfo.tagIds); -#endif + menu->activateActions(tagInfo); } void MessagesDialog::tagRemoveAll() @@ -1455,9 +1530,8 @@ void MessagesDialog::tagRemoveAll() void MessagesDialog::tagSet(int tagId, bool set) { - if (tagId == 0) { + if (tagId == 0) return; - } QList msgids; getSelectedMessages(msgids); @@ -1469,7 +1543,7 @@ void MessagesDialog::tagSet(int tagId, bool set) void MessagesDialog::emptyTrash() { std::list msgs ; - mMessageModel->getMessageSummaries(RsMessageModel::BOX_TRASH,msgs); + rsMsgs->getMessageSummaries(Rs::Msgs::BoxName::BOX_TRASH,msgs); for(auto it(msgs.begin());it!=msgs.end();++it) rsMail->MessageDelete(it->msgId); diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.h b/retroshare-gui/src/gui/msgs/MessagesDialog.h index fab811ee7..1d10137c2 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.h +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.h @@ -66,7 +66,6 @@ protected: public slots: //void insertMessages(); - void messagesTagsChanged(); void messageRemoved(); void preModelUpdate(); void postModelUpdate(); @@ -80,6 +79,7 @@ private slots: void changeBox(int newrow); void changeQuickView(int newrow); + void resetQuickView(const QModelIndex& i); void updateCurrentMessage(); void clicked(const QModelIndex&); void doubleClicked(const QModelIndex&); @@ -112,6 +112,7 @@ private slots: private: void handleEvent_main_thread(std::shared_ptr event); + void handleTagEvent_main_thread(std::shared_ptr event); void updateInterface(); @@ -138,9 +139,10 @@ private: bool inChange; int lockUpdate; // use with LockUpdate - enum { LIST_NOTHING, LIST_BOX, LIST_QUICKVIEW } listMode; + // enum { LIST_NOTHING, LIST_BOX, LIST_QUICKVIEW } listMode; std::string mCurrMsgId; + int mLastCurrentQuickViewRow; // timer and index for showing message QTimer *timer; @@ -152,16 +154,18 @@ private: RsMessageModel *mMessageModel; MessageSortFilterProxyModel *mMessageProxyModel; - /* Color definitions (for standard see qss.default) */ + /* Color definitions (for standard see default.qss) */ QColor mTextColorInbox; /** Qt Designer generated object */ Ui::MessagesDialog ui; QList mTmpSavedSelectedIds; + QString mTmpSavedCurrentId; QModelIndex lastSelectedIndex; RsEventsHandlerId_t mEventHandlerId; + RsEventsHandlerId_t mTagEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/msgs/MessagesDialog.ui b/retroshare-gui/src/gui/msgs/MessagesDialog.ui index 183396a2c..5f1d83eca 100644 --- a/retroshare-gui/src/gui/msgs/MessagesDialog.ui +++ b/retroshare-gui/src/gui/msgs/MessagesDialog.ui @@ -10,7 +10,7 @@ 485 - + 0 @@ -36,7 +36,7 @@ Messages - + 0 @@ -55,7 +55,7 @@ Qt::Horizontal - + 0 @@ -72,11 +72,11 @@ 0 - + true - + 3 @@ -139,6 +139,11 @@ 0 + + + 11 + + Qt::CustomContextMenu @@ -188,23 +193,17 @@ - - + + 0 - + true - - QFrame::StyledPanel - - - QFrame::Raised - - + 3 @@ -254,6 +253,11 @@ 0 + + + 11 + + @@ -275,13 +279,13 @@
    - - + + 0 - + 3 @@ -321,7 +325,7 @@
    - + Qt::Horizontal @@ -352,7 +356,7 @@ Qt::NoFocus - + :/icons/help_64.png:/icons/help_64.png @@ -371,6 +375,11 @@ Qt::Vertical + + + 10 + + Qt::CustomContextMenu @@ -476,8 +485,8 @@ listWidget - + diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.cpp b/retroshare-gui/src/gui/msgs/TagsMenu.cpp index 357c37325..881ec268d 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.cpp +++ b/retroshare-gui/src/gui/msgs/TagsMenu.cpp @@ -30,6 +30,7 @@ #include "gui/common/TagDefs.h" #include "gui/settings/NewTag.h" #include "gui/notifyqt.h" +#include "util/qtthreadsutils.h" #include "gui/msgs/MessageInterface.h" @@ -46,11 +47,18 @@ TagsMenu::TagsMenu(const QString &title, QWidget *parent) : QMenu (title, parent) { connect(this, SIGNAL(triggered (QAction*)), this, SLOT(tagTriggered(QAction*))); - connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(fillTags())); + + mEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mEventHandlerId, RsEventType::MAIL_TAG ); fillTags(); } +TagsMenu::~TagsMenu() +{ + rsEvents->unregisterEventsHandler(mEventHandlerId); +} + void TagsMenu::paintEvent(QPaintEvent *e) { QMenu::paintEvent(e); @@ -89,6 +97,26 @@ void TagsMenu::paintEvent(QPaintEvent *e) } } +void TagsMenu::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + fillTags(); + break; + } +} + void TagsMenu::fillTags() { clear(); @@ -142,7 +170,7 @@ void TagsMenu::fillTags() addAction(action); } -void TagsMenu::activateActions(std::list& tagIds) +void TagsMenu::activateActions(std::set& tagIds) { foreach(QObject *object, children()) { QAction *action = qobject_cast (object); @@ -158,7 +186,7 @@ void TagsMenu::activateActions(std::list& tagIds) continue; } - std::list::iterator tagId = std::find(tagIds.begin(), tagIds.end(), values [ACTION_TAGSINDEX_ID]); + auto tagId = std::find(tagIds.begin(), tagIds.end(), values [ACTION_TAGSINDEX_ID]); action->setChecked(tagId != tagIds.end()); } } diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.h b/retroshare-gui/src/gui/msgs/TagsMenu.h index 279638aae..1cccb7e5f 100644 --- a/retroshare-gui/src/gui/msgs/TagsMenu.h +++ b/retroshare-gui/src/gui/msgs/TagsMenu.h @@ -24,6 +24,7 @@ #include #include +#include class TagsMenu : public QMenu { @@ -31,8 +32,9 @@ class TagsMenu : public QMenu public: TagsMenu(const QString &title, QWidget *parent); + virtual ~TagsMenu(); - void activateActions(std::list& tagIds); + void activateActions(std::set &tagIds); signals: void tagSet(int tagId, bool set); @@ -42,8 +44,14 @@ protected: virtual void paintEvent(QPaintEvent *e); private slots: - void fillTags(); void tagTriggered(QAction *action); + +private: + void handleEvent_main_thread(std::shared_ptr event); + void fillTags(); + +private: + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 7bb1b6cf2..d2dee5ac4 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -21,12 +21,6 @@ #include "gui/common/FilesDefs.h" #include -#include -#include -#include -//#include -#include - #include "notifyqt.h" #include #include @@ -55,6 +49,13 @@ #include "retroshare/rsplugin.h" +#include +#include +#include +//#include +#include +#include + /***** * #define NOTIFY_DEBUG ****/ @@ -223,37 +224,51 @@ bool NotifyQt::askForPassword(const std::string& title, const std::string& key_d { RsAutoUpdatePage::lockAllEvents() ; - QInputDialog dialog; + QString windowTitle; if (title == "") { - dialog.setWindowTitle(tr("Passphrase required")); + windowTitle = tr("Passphrase required"); } else if (title == "AuthSSLimpl::SignX509ReqWithGPG()") { - dialog.setWindowTitle(tr("You need to sign your node's certificate.")); + windowTitle = tr("You need to sign your node's certificate."); } else if (title == "p3IdService::service_CreateGroup()") { - dialog.setWindowTitle(tr("You need to sign your forum/chatrooms identity.")); + windowTitle = tr("You need to sign your forum/chatrooms identity."); } else { - dialog.setWindowTitle(QString::fromStdString(title)); + windowTitle = QString::fromStdString(title); } - dialog.setLabelText((prev_is_bad ? QString("%1

    ").arg(tr("Wrong password !")) : QString()) + QString("%1
    Profile: %2\n").arg(tr("Please enter your Retroshare passphrase"), QString::fromUtf8(key_details.c_str()))); - dialog.setTextEchoMode(QLineEdit::Password); - dialog.setModal(true); + QString labelText = ( prev_is_bad ? QString("%1

    ").arg(tr("Wrong password !")) : QString() ) + + QString("%1
    Profile: %2\n") + .arg( tr("Please enter your Retroshare passphrase") + , QString::fromUtf8(key_details.c_str()) ); + QLineEdit::EchoMode textEchoMode = QLineEdit::Password; + bool modal = true; - int ret = dialog.exec(); + bool sameThread = QThread::currentThread() == qApp->thread(); + Gui_InputDialogReturn ret; + qRegisterMetaType("Gui_InputDialogReturn"); + QMetaObject::invokeMethod( MainWindow::getInstance() + , "guiInputDialog" + , sameThread ? Qt::DirectConnection : Qt::BlockingQueuedConnection + , Q_RETURN_ARG(Gui_InputDialogReturn, ret) + , Q_ARG(QString, windowTitle) + , Q_ARG(QString, labelText) + , Q_ARG(QLineEdit::EchoMode, textEchoMode) + , Q_ARG(bool, modal) + ); - cancelled = false ; + cancelled = false ; RsAutoUpdatePage::unlockAllEvents() ; - if (ret == QDialog::Rejected) { - password.clear() ; - cancelled = true ; - return true ; - } + if (ret.execReturn == QDialog::Rejected) { + password.clear() ; + cancelled = true ; + return true ; + } - if (ret == QDialog::Accepted) { - password = dialog.textValue().toUtf8().constData(); - return true; - } + if (ret.execReturn == QDialog::Accepted) { + password = ret.textValue.toUtf8().constData(); + return true; + } return false; } @@ -462,11 +477,13 @@ void NotifyQt::notifyChatCleared(const ChatId& chat_id) emit chatCleared(chat_id); } -void NotifyQt::notifyTurtleSearchResult(uint32_t search_id,const std::list& found_groups) +void NotifyQt::notifyTurtleSearchResult(uint32_t /*search_id*/,const std::list& /*found_groups*/) { std::cerr << "(EE) missing code to handle GXS turtle search result." << std::endl; } +#ifdef TO_REMOVE +// Mai 2023: distant turtle search now uses RsEvents. void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,const std::list& files) { { @@ -492,6 +509,7 @@ void NotifyQt::notifyTurtleSearchResult(const RsPeerId& pid,uint32_t search_id,c emit gotTurtleSearchResult(search_id,det) ; } } +#endif void NotifyQt::notifyHistoryChanged(uint32_t msgId, int type) { @@ -548,18 +566,6 @@ void NotifyQt::notifyListChange(int list, int type) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg changed" << std::endl ; -#endif - emit messagesChanged() ; - break; - case NOTIFY_LIST_MESSAGE_TAGS: -#ifdef NOTIFY_DEBUG - std::cerr << "received msg tags changed" << std::endl ; -#endif - emit messagesTagsChanged(); - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: @@ -648,8 +654,6 @@ void NotifyQt::notifyListPreChange(int list, int /*type*/) break; case NOTIFY_LIST_SEARCHLIST: break; - case NOTIFY_LIST_MESSAGELIST: - break; case NOTIFY_LIST_CHANNELLIST: break; case NOTIFY_LIST_TRANSFERLIST: @@ -682,7 +686,6 @@ void NotifyQt::UpdateGUI() // the gui is running, then they get updated by callbacks. if(!already_updated) { - emit messagesChanged() ; emit neighboursChanged(); emit configChanged(); @@ -1162,3 +1165,123 @@ void NotifyQt::runningTick() } } +void NotifyQt::addToaster(uint notifyFlags, const std::string& id, const std::string& title, const std::string& msg) +{ + uint pos = 0; + + while (notifyFlags) { + uint type = notifyFlags & (1 << pos); + notifyFlags &= ~(1 << pos); + ++pos; + + ToasterItem *toaster = NULL; + + uint popupflags = Settings->getNotifyFlags(); + + switch(type) + { + case RS_POPUP_ENCRYPTED_MSG: + SoundManager::play(SOUND_MESSAGE_ARRIVED); + + if ((popupflags & RS_POPUP_MSG) && !_disableAllToaster) + { + toaster = new ToasterItem(new MessageToaster(std::string(), tr("Unknown title"), QString("[%1]").arg(tr("Encrypted message")))); + } + break; + case RS_POPUP_MSG: + SoundManager::play(SOUND_MESSAGE_ARRIVED); + + if ((popupflags & RS_POPUP_MSG) && !_disableAllToaster) + { + toaster = new ToasterItem(new MessageToaster(id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str()))); + } + break; + case RS_POPUP_CONNECT: + SoundManager::play(SOUND_USER_ONLINE); + + if ((popupflags & RS_POPUP_CONNECT) && !_disableAllToaster) + { + toaster = new ToasterItem(new OnlineToaster(RsPeerId(id))); + } + break; + case RS_POPUP_DOWNLOAD: + SoundManager::play(SOUND_DOWNLOAD_COMPLETE); + + if ((popupflags & RS_POPUP_DOWNLOAD) && !_disableAllToaster) + { + toaster = new ToasterItem(new DownloadToaster(RsFileHash(id), QString::fromUtf8(title.c_str()))); + } + break; + case RS_POPUP_CHAT: + if ((popupflags & RS_POPUP_CHAT) && !_disableAllToaster) + { + // TODO: fix for distant chat, look up if dstant chat uses RS_POPUP_CHAT + ChatDialog *chatDialog = ChatDialog::getChat(ChatId(RsPeerId(id))); + ChatWidget *chatWidget; + if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) { + // do not show when active + break; + } + toaster = new ToasterItem(new ChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str()))); + } + case RS_POPUP_GROUPCHAT: +#ifdef RS_DIRECT_CHAT + if ((popupflags & RS_POPUP_GROUPCHAT) && !_disableAllToaster) + { + MainWindow *mainWindow = MainWindow::getInstance(); + if (mainWindow && mainWindow->isActiveWindow() && !mainWindow->isMinimized()) { + if (MainWindow::getActivatePage() == MainWindow::Friends) { + if (FriendsDialog::isGroupChatActive()) { + // do not show when active + break; + } + } + } + toaster = new ToasterItem(new GroupChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str()))); + } +#endif // RS_DIRECT_CHAT + break; + case RS_POPUP_CHATLOBBY: + if ((popupflags & RS_POPUP_CHATLOBBY) && !_disableAllToaster) + { + ChatId chat_id(id); + + ChatDialog *chatDialog = ChatDialog::getChat(chat_id); + ChatWidget *chatWidget; + if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) { + // do not show when active + break; + } + + ChatLobbyDialog *chatLobbyDialog = dynamic_cast(chatDialog); + + RsGxsId sender(title); + if (!chatLobbyDialog || chatLobbyDialog->isParticipantMuted(sender)) + break; // participant is muted + + toaster = new ToasterItem(new ChatLobbyToaster(chat_id.toLobbyId(), sender, QString::fromUtf8(msg.c_str()))); + } + break; + case RS_POPUP_CONNECT_ATTEMPT: + if ((popupflags & RS_POPUP_CONNECT_ATTEMPT) && !_disableAllToaster) + { + // id = gpgid + // title = ssl name + // msg = peer id + toaster = new ToasterItem(new FriendRequestToaster(RsPgpId(id), QString::fromUtf8(title.c_str()), RsPeerId(msg))); + } + break; + } + + if (toaster) { + /* init attributes */ + toaster->widget->setWindowFlags(Qt::ToolTip | Qt::WindowStaysOnTopHint); + + /* add toaster to waiting list */ + //QMutexLocker lock(&waitingToasterMutex); + waitingToasterList.push_back(toaster); + } + } + /* Now start the waiting toasters */ + startWaitingToasters(); +} diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index 069ae8056..5782ef5b7 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -67,7 +67,9 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyChatStatus(const ChatId &chat_id,const std::string& status_string); virtual void notifyChatCleared(const ChatId &chat_id); virtual void notifyCustomState(const std::string& peer_id, const std::string& status_string); +#ifdef TO_REMOVE virtual void notifyTurtleSearchResult(const RsPeerId &pid, uint32_t search_id, const std::list& found_files); +#endif virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list& found_groups); virtual void notifyPeerHasNewAvatar(std::string peer_id) ; virtual void notifyOwnAvatarChanged() ; @@ -95,6 +97,7 @@ class NotifyQt: public QObject, public NotifyClient void testToaster(ToasterNotify *toasterNotify, /*RshareSettings::enumToasterPosition*/ int position, QPoint margin); void testToaster(QString tag, ToasterNotify *toasterNotify, /*RshareSettings::enumToasterPosition*/ int position, QPoint margin); + void addToaster(uint notifyFlags, const std::string& id, const std::string& title, const std::string& msg); void notifySettingsChanged(); signals: @@ -109,14 +112,11 @@ class NotifyQt: public QObject, public NotifyClient void lobbyListChanged() const ; void chatLobbyEvent(qulonglong,int,const RsGxsId&,const QString&) ; void neighboursChanged() const ; - void messagesChanged() const ; - void messagesTagsChanged() const; void configChanged() const ; void logInfoChanged(const QString&) const ; void chatStatusChanged(const ChatId&,const QString&) const ; void chatCleared(const ChatId&) const ; void peerHasNewCustomStateString(const QString& /* peer_id */, const QString& /* status_string */) const ; - void gotTurtleSearchResult(qulonglong search_id,FileDetail file) const ; void peerHasNewAvatar(const QString& peer_id) const ; void ownAvatarChanged() const ; void ownStatusMessageChanged() const ; diff --git a/retroshare-gui/src/gui/profile/ProfileManager.ui b/retroshare-gui/src/gui/profile/ProfileManager.ui index 9ec918e89..a2ffe541b 100644 --- a/retroshare-gui/src/gui/profile/ProfileManager.ui +++ b/retroshare-gui/src/gui/profile/ProfileManager.ui @@ -23,27 +23,36 @@ Profile Manager - + :/images/logo/logo_16.png:/images/logo/logo_16.png - - + + + 0 + + + 0 + + + 0 + + 0 0 - + 0 30 - + - + @@ -54,12 +63,12 @@ <!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:'Ubuntu'; font-size:11pt; 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;">Select a Retroshare node key from the list below to be used on another computer, and press &quot;Export selected key.&quot;</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> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">To create a new location on a different computer, select the identity manager in the login window. From there you can import the key file and create a new location for that key. </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> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Creating a new node with the same key allows your friend nodes to accept you automatically.</p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; 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-family:'Ubuntu'; font-size:11pt;">Select a Retroshare node key from the list below to be used on another computer, and press &quot;Export selected key.&quot;</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-family:'Ubuntu'; font-size:11pt;"><br /></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-family:'Ubuntu'; font-size:11pt;">To create a new location on a different computer, select the identity manager in the login window. From there you can import the key file and create a new location for that key. </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-family:'Ubuntu'; font-size:11pt;"><br /></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-family:'Ubuntu'; font-size:11pt;">Creating a new node with the same key allows your friend nodes to accept you automatically.</span></p></body></html>
    @@ -71,11 +80,11 @@ p, li { white-space: pre-wrap; }
    - + Full keys available in your keyring: - + diff --git a/retroshare-gui/src/gui/profile/ProfileWidget.cpp b/retroshare-gui/src/gui/profile/ProfileWidget.cpp index b6418ae56..cf823ab53 100644 --- a/retroshare-gui/src/gui/profile/ProfileWidget.cpp +++ b/retroshare-gui/src/gui/profile/ProfileWidget.cpp @@ -45,7 +45,7 @@ ProfileWidget::ProfileWidget(QWidget *parent, Qt::WindowFlags flags) connect(ui.CopyCertButton,SIGNAL(clicked()), this, SLOT(copyCert())); connect(ui.profile_Button,SIGNAL(clicked()), this, SLOT(profilemanager())); - ui.onlinesince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); + ui.onLineSince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); } void ProfileWidget::showEvent ( QShowEvent * /*event*/ ) @@ -59,7 +59,7 @@ void ProfileWidget::showEvent ( QShowEvent * /*event*/ ) ui.name->setText(QString::fromUtf8(detail.name.c_str())); ui.country->setText(QString::fromUtf8(detail.location.c_str())); - ui.peerid->setText(QString::fromStdString(detail.id.toStdString())); + ui.peerId->setText(QString::fromStdString(detail.id.toStdString())); ui.ipAddressList->clear(); for(std::list::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) diff --git a/retroshare-gui/src/gui/profile/ProfileWidget.ui b/retroshare-gui/src/gui/profile/ProfileWidget.ui index 4462acad5..2bd1fae73 100644 --- a/retroshare-gui/src/gui/profile/ProfileWidget.ui +++ b/retroshare-gui/src/gui/profile/ProfileWidget.ui @@ -16,17 +16,35 @@ 0 - - + + 0 - + + 0 + + + 0 + + + 0 + + 0 - - + + + 2 + + + 2 + + + 2 + + 2 @@ -41,7 +59,7 @@ Edit status message - + :/images/edit_16.png:/images/edit_16.png @@ -61,7 +79,7 @@ Copy Certificate - + :/images/view-certificate-copy-32.png:/images/view-certificate-copy-32.png @@ -81,7 +99,7 @@ Profile Manager - + :/images/contact_new.png:/images/contact_new.png @@ -99,7 +117,7 @@ - + Qt::Horizontal @@ -128,18 +146,18 @@ 569 - + - + QFrame::Box QFrame::Sunken - + - + @@ -154,9 +172,10 @@ - + + 12 75 true @@ -169,7 +188,7 @@ - + 0 @@ -207,7 +226,7 @@ - + 0 @@ -245,7 +264,7 @@ - + 0 @@ -264,7 +283,7 @@ - + 0 @@ -286,16 +305,16 @@ - + QFrame::Box QFrame::Sunken - + - + 0 @@ -333,7 +352,7 @@ - + 0 @@ -352,7 +371,7 @@ - + 0 @@ -390,7 +409,7 @@ - + 0 @@ -409,7 +428,7 @@ - + @@ -427,9 +446,10 @@ - + + 12 75 true @@ -445,16 +465,16 @@ - + QFrame::Box QFrame::Sunken - + - + @@ -472,9 +492,10 @@ - + + 12 75 true @@ -487,7 +508,7 @@ - + 0 @@ -547,7 +568,7 @@ - + 0 @@ -566,7 +587,7 @@ - + Qt::Horizontal @@ -620,7 +641,7 @@ - + Qt::Horizontal @@ -633,7 +654,7 @@ - + Qt::Horizontal @@ -646,7 +667,7 @@ - + 0 @@ -675,7 +696,7 @@ - + 100 @@ -722,13 +743,6 @@ - - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    diff --git a/retroshare-gui/src/gui/profile/StatusMessage.ui b/retroshare-gui/src/gui/profile/StatusMessage.ui index 0f537c280..c5a29369f 100644 --- a/retroshare-gui/src/gui/profile/StatusMessage.ui +++ b/retroshare-gui/src/gui/profile/StatusMessage.ui @@ -35,7 +35,7 @@ :/images/logo/logo_16.png:/images/logo/logo_16.png
    - + 9 @@ -44,12 +44,7 @@ 113 - - QFrame#frame{background: white; -border: 1px solid #CCCCCC;} - - - + 91 @@ -73,7 +68,7 @@ border: 1px solid #CCCCCC;} - + 100 @@ -90,7 +85,7 @@ p, li { white-space: pre-wrap; } <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:14pt; font-weight:600;">Status message</span></p></body></html> - + 100 @@ -107,7 +102,7 @@ p, li { white-space: pre-wrap; } <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:8pt; color:#666666;">Enter your message</span></p></body></html> - + 20 @@ -129,7 +124,7 @@ p, li { white-space: pre-wrap; } :/images/user/personal64.png - + 0 @@ -138,14 +133,6 @@ p, li { white-space: pre-wrap; } 241 - - QFrame#frame_2{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, -stop:0 #FEFEFE, stop:1 #E8E8E8); - -border: 1px solid #CCCCCC;} - - QFrame::StyledPanel @@ -166,11 +153,11 @@ border: 1px solid #CCCCCC;} - frame_2 - frame - label_3 - label_2 - label + gradFrame + plainBFrame + statusLabel + enterMsgLabel + iconLabel diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm index 1b8c4fe38..0b4df8458 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/hincoming.htm @@ -2,25 +2,26 @@ %css-style% +
    - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm index fcb291fe1..9342d3071 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/houtgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png index d9c28aaa7..fa45de4ab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png index 8a3e85ec3..68de5c296 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png index f18a209e2..db1424364 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CC.png index 23dd2df02..1af67f4cb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png index 346d6e3d6..60ab43b89 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png index e876448fc..77934e9d9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png index f21120bbd..bac53adab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png index 5212f419d..e9261c34c 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png index f1c15529a..25ed23587 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png index 3a6ccf16a..c162ec17a 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-right.png index ea72de738..b68140350 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick.png index a61428428..17ec2f461 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-blue/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BC.png index dd8882d96..071a260e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BL.png index e1289e246..9bcd7ffe3 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png index 65a70a294..655a2db64 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png index d498c3b85..61cf46ac0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CL.png index 7ef606a91..47f3f3d3b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png index 1d79a0904..38c07275f 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TC.png index a8b3d5385..b1233b2d2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png index 0a1c804de..7e43bfc0d 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TR.png index f17c5d47a..3bf52d2c9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png index 09424c08e..b3f423af0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-right.png index 5cbcb947f..61fd1bbe2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick.png index d508e6133..04eac5da6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-green/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BC.png index b23861b44..bef39f6a4 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png index 6d5e6e15e..eebfe3b91 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png index 68871cedd..2763880e9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CC.png index 2f01fe1c0..0ba2d15ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png index ebe042e97..70a084c58 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CR.png index 798c5541d..01ab49103 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png index 8cb903994..1ea171038 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png index c3200aff4..1fd1527ee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TR.png index 85d2a1b2d..dceabb543 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png index 49fe22b33..c76994a67 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-right.png index 28b8cd138..c61a7b2e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick.png index 578346f3a..d53955494 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-grey/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BC.png index 9b1ee55b7..7c89990fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BL.png index 1bb3bcac4..6c9dd1ff0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png index 639fc3878..3cec3cc27 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CC.png index 08621dcbd..87d7ba3da 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png index f19354d8b..ecb8de13e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CR.png index 7e504b16c..2dc4b7ad6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png index ce4a2357a..64fa0e7c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png index 70e3cad64..ef3d963d6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TR.png index a083920ed..b87e86f35 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png index f407cbbf7..8efd044b0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-right.png index b9011570c..ce25c9b62 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick.png index eaf56bd56..08bd0c310 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-orange/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png index 7bd1d84f9..c27064260 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png index 5018dc60a..4d22f79c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png index 994743d0c..00d2a6255 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CC.png index 8bca51700..e70c461f2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CL.png index c9a6aad38..b5095e4fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png index d538eea05..08b3a53ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png index 27c7d02b4..9900f8bee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png index c5e3fc3b1..12ce5c81e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TR.png index 9122e8ca2..b9d05761b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png index d1b1f6b64..7e332b401 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-right.png index d4a905aac..9bdd6ceb6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png index 313e2db04..8ef8a7a23 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/history/img/bubble-red/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/incoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/incoming.htm index 677e7a082..70d5dfe73 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/incoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/incoming.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css index 443b58d74..c56eaeb54 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/main.css @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px; } +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px; } +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px; } +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px; } .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm index 66ef6876c..fbc2a25b9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm index acf919dca..b60708aa9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/outgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm index 103d2bca1..d5cc3d402 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/history/system.htm @@ -3,21 +3,24 @@ +
    + - + - + - + - + - + - +
    %name% %time% - %message%
    +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm index 1b8c4fe38..da27694e7 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/hincoming.htm @@ -2,13 +2,14 @@ %css-style% +
    - + - + @@ -18,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm index fcb291fe1..10415c60a 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/houtgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png index d9c28aaa7..fa45de4ab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png index 8a3e85ec3..68de5c296 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png index f18a209e2..db1424364 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CC.png index 23dd2df02..1af67f4cb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png index 346d6e3d6..60ab43b89 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png index e876448fc..77934e9d9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png index f21120bbd..bac53adab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png index 5212f419d..e9261c34c 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png index f1c15529a..25ed23587 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png index 3a6ccf16a..c162ec17a 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-right.png index ea72de738..b68140350 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick.png index a61428428..17ec2f461 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-blue/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BC.png index dd8882d96..071a260e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BL.png index e1289e246..9bcd7ffe3 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png index 65a70a294..655a2db64 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png index d498c3b85..61cf46ac0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CL.png index 7ef606a91..47f3f3d3b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png index 1d79a0904..38c07275f 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TC.png index a8b3d5385..b1233b2d2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png index 0a1c804de..7e43bfc0d 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TR.png index f17c5d47a..3bf52d2c9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png index 09424c08e..b3f423af0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-right.png index 5cbcb947f..61fd1bbe2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick.png index d508e6133..04eac5da6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-green/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BC.png index b23861b44..bef39f6a4 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png index 6d5e6e15e..eebfe3b91 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png index 68871cedd..2763880e9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CC.png index 2f01fe1c0..0ba2d15ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png index ebe042e97..70a084c58 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CR.png index 798c5541d..01ab49103 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png index 8cb903994..1ea171038 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png index c3200aff4..1fd1527ee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TR.png index 85d2a1b2d..dceabb543 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png index 49fe22b33..c76994a67 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-right.png index 28b8cd138..c61a7b2e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick.png index 578346f3a..d53955494 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-grey/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BC.png index 9b1ee55b7..7c89990fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BL.png index 1bb3bcac4..6c9dd1ff0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png index 639fc3878..3cec3cc27 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CC.png index 08621dcbd..87d7ba3da 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png index f19354d8b..ecb8de13e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CR.png index 7e504b16c..2dc4b7ad6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png index ce4a2357a..64fa0e7c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png index 70e3cad64..ef3d963d6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TR.png index a083920ed..b87e86f35 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png index f407cbbf7..8efd044b0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-right.png index b9011570c..ce25c9b62 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick.png index eaf56bd56..08bd0c310 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-orange/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png index 7bd1d84f9..c27064260 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png index 5018dc60a..4d22f79c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png index 994743d0c..00d2a6255 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CC.png index 8bca51700..e70c461f2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CL.png index c9a6aad38..b5095e4fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png index d538eea05..08b3a53ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png index 27c7d02b4..9900f8bee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png index c5e3fc3b1..12ce5c81e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TR.png index 9122e8ca2..b9d05761b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png index d1b1f6b64..7e332b401 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-right.png index d4a905aac..9bdd6ceb6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png index 313e2db04..8ef8a7a23 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/private/img/bubble-red/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/incoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/incoming.htm index 677e7a082..2ca6d0ccd 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/incoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/incoming.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css index 443b58d74..c56eaeb54 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/main.css @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px; } +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px; } +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px; } +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px; } .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm index 66ef6876c..fbc2a25b9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm index acf919dca..b60708aa9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/outgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm index ec98b3b43..3be7fc603 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/private/system.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm index 3d9703654..5e5925b16 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/hincoming.htm @@ -2,25 +2,26 @@ %css-style% +
    - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm index 4cbc1a875..aad55004a 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/houtgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png index d9c28aaa7..fa45de4ab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png index 8a3e85ec3..68de5c296 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png index f18a209e2..db1424364 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CC.png index 23dd2df02..1af67f4cb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png index 346d6e3d6..60ab43b89 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png index e876448fc..77934e9d9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png index f21120bbd..bac53adab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png index 5212f419d..e9261c34c 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png index f1c15529a..25ed23587 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png index 3a6ccf16a..c162ec17a 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-right.png index ea72de738..b68140350 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick.png index a61428428..17ec2f461 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-blue/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BC.png index dd8882d96..071a260e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BL.png index e1289e246..9bcd7ffe3 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png index 65a70a294..655a2db64 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png index d498c3b85..61cf46ac0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CL.png index 7ef606a91..47f3f3d3b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png index 1d79a0904..38c07275f 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TC.png index a8b3d5385..b1233b2d2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png index 0a1c804de..7e43bfc0d 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TR.png index f17c5d47a..3bf52d2c9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png index 09424c08e..b3f423af0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-right.png index 5cbcb947f..61fd1bbe2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick.png index d508e6133..04eac5da6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-green/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BC.png index b23861b44..bef39f6a4 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png index 6d5e6e15e..eebfe3b91 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png index 68871cedd..2763880e9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CC.png index 2f01fe1c0..0ba2d15ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png index ebe042e97..70a084c58 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CR.png index 798c5541d..01ab49103 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png index 8cb903994..1ea171038 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png index c3200aff4..1fd1527ee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TR.png index 85d2a1b2d..dceabb543 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png index 49fe22b33..c76994a67 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-right.png index 28b8cd138..c61a7b2e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick.png index 578346f3a..d53955494 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-grey/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BC.png index 9b1ee55b7..7c89990fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BL.png index 1bb3bcac4..6c9dd1ff0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png index 639fc3878..3cec3cc27 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CC.png index 08621dcbd..87d7ba3da 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png index f19354d8b..ecb8de13e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CR.png index 7e504b16c..2dc4b7ad6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png index ce4a2357a..64fa0e7c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png index 70e3cad64..ef3d963d6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TR.png index a083920ed..b87e86f35 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png index f407cbbf7..8efd044b0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-right.png index b9011570c..ce25c9b62 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick.png index eaf56bd56..08bd0c310 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-orange/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png index 7bd1d84f9..c27064260 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png index 5018dc60a..4d22f79c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png index 994743d0c..00d2a6255 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CC.png index 8bca51700..e70c461f2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CL.png index c9a6aad38..b5095e4fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png index d538eea05..08b3a53ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png index 27c7d02b4..9900f8bee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png index c5e3fc3b1..12ce5c81e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TR.png index 9122e8ca2..b9d05761b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png index d1b1f6b64..7e332b401 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-right.png index d4a905aac..9bdd6ceb6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png index 313e2db04..8ef8a7a23 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/public/img/bubble-red/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/incoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/incoming.htm index 9788ee250..3ca559451 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/incoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/incoming.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css b/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css index 443b58d74..63b7067d9 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/main.css @@ -1,6 +1,6 @@ .name{ font-weight: bold; -color: #FF0000; + color: #FF0000; } .time { @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { float: right; } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { float: right; color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { float: right; color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } -.bubble-green { float: right;} -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-green { float: right; } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px;} +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px;} +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px;} +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px;} .bubble-blue { float: right;} -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .bubbleFooter { background-color: none; width:100%; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm index 836fe4510..6e3ff2027 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/ooutgoing.htm @@ -7,9 +7,9 @@ - + - + @@ -19,9 +19,9 @@ - + - +
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm index 14221ffa6..32e875781 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/outgoing.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm index ec98b3b43..603996b4f 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble/public/system.htm @@ -7,21 +7,21 @@ - + - + - + - + - +
    %message%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh deleted file mode 100644 index b1c977ac1..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble/src/images.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - #convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - #convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,10 ../bubble-blue/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,130 ../bubble-green/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg b/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg old mode 100644 new mode 100755 index f153fc374..6d76ccb92 --- a/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg +++ b/retroshare-gui/src/gui/qss/chat/Bubble/src/img.svg @@ -1,1066 +1,81 @@ - - - - - - - - - - - + + + + + - - - + + - - - + + - - - - + + - - + + + + + + + + + + + + - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + - + image/svg+xml - - + + - diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png index d9c28aaa7..fa45de4ab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png index 8a3e85ec3..68de5c296 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png index f18a209e2..db1424364 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CC.png index 23dd2df02..1af67f4cb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png index 346d6e3d6..60ab43b89 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png index e876448fc..77934e9d9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png index f21120bbd..bac53adab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png index 5212f419d..e9261c34c 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png index f1c15529a..25ed23587 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png index 3a6ccf16a..c162ec17a 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-right.png index ea72de738..b68140350 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick.png index a61428428..17ec2f461 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-blue/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BC.png index dd8882d96..071a260e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BL.png index e1289e246..9bcd7ffe3 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png index 65a70a294..655a2db64 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png index d498c3b85..61cf46ac0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CL.png index 7ef606a91..47f3f3d3b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png index 1d79a0904..38c07275f 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TC.png index a8b3d5385..b1233b2d2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png index 0a1c804de..7e43bfc0d 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TR.png index f17c5d47a..3bf52d2c9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png index 09424c08e..b3f423af0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-right.png index 5cbcb947f..61fd1bbe2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick.png index d508e6133..04eac5da6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-green/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BC.png index b23861b44..bef39f6a4 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png index 6d5e6e15e..eebfe3b91 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png index 68871cedd..2763880e9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CC.png index 2f01fe1c0..0ba2d15ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png index ebe042e97..70a084c58 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CR.png index 798c5541d..01ab49103 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png index 8cb903994..1ea171038 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png index c3200aff4..1fd1527ee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TR.png index 85d2a1b2d..dceabb543 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png index 49fe22b33..c76994a67 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-right.png index 28b8cd138..c61a7b2e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick.png index 578346f3a..d53955494 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-grey/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BC.png index 9b1ee55b7..7c89990fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BL.png index 1bb3bcac4..6c9dd1ff0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png index 639fc3878..3cec3cc27 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CC.png index 08621dcbd..87d7ba3da 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png index f19354d8b..ecb8de13e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CR.png index 7e504b16c..2dc4b7ad6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png index ce4a2357a..64fa0e7c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png index 70e3cad64..ef3d963d6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TR.png index a083920ed..b87e86f35 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png index f407cbbf7..8efd044b0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-right.png index b9011570c..ce25c9b62 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick.png index eaf56bd56..08bd0c310 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-orange/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png index 7bd1d84f9..c27064260 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png index 5018dc60a..4d22f79c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png index 994743d0c..00d2a6255 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CC.png index 8bca51700..e70c461f2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CL.png index c9a6aad38..b5095e4fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png index d538eea05..08b3a53ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png index 27c7d02b4..9900f8bee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png index c5e3fc3b1..12ce5c81e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TR.png index 9122e8ca2..b9d05761b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png index d1b1f6b64..7e332b401 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-right.png index d4a905aac..9bdd6ceb6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png index 313e2db04..8ef8a7a23 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble/src/img/bubble-red/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble/src/make_images.sh b/retroshare-gui/src/gui/qss/chat/Bubble/src/make_images.sh new file mode 100755 index 000000000..ccf0f226f --- /dev/null +++ b/retroshare-gui/src/gui/qss/chat/Bubble/src/make_images.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +echo "This script will export img.svg to all parts of bubble as png." +echo "This needs InkScape and XMLStarlet to be installed" + +mkdir -p img/bubble-orange +mkdir -p img/bubble-grey +mkdir -p img/bubble-red +mkdir -p img/bubble-blue +mkdir -p img/bubble-green + + +echo "Making Orange ones..." +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='borderColor']/_:stop[@id='brdLGStop1']/@stop-color" --value "#ff9600" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intRaisedColor']/_:stop[@id='intRLGStop1']/@stop-color" --value "#ffef56" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickColor']/_:stop[@id='intTLGStop1']/@stop-color" --value "#ff9e37" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickSideColor']/_:stop[@id='intTSLGStop1']/@stop-color" --value "#ffd147" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop1']/@stop-color" --value "#ff9133" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop2']/@stop-color" --value "#ffcf47" img.svg + +inkscape --export-use-hints --export-id="rect_TL;rect_TC;rect_TR;rect_CL;rect_CC;rect_CR;rect_BL;rect_BC;rect_BR;rect_tick;rect_tick-left;rect_tick-right" img.svg +mv img/*.png img/bubble-orange/ + + +echo "Making Grey ones..." +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='borderColor']/_:stop[@id='brdLGStop1']/@stop-color" --value "#d0d0d0" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intRaisedColor']/_:stop[@id='intRLGStop1']/@stop-color" --value "#f3f3f3" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickColor']/_:stop[@id='intTLGStop1']/@stop-color" --value "#d5d5d5" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickSideColor']/_:stop[@id='intTSLGStop1']/@stop-color" --value "#e8e8e8" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop1']/@stop-color" --value "#d0d0d0" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop2']/@stop-color" --value "#e7e7e7" img.svg + +inkscape --export-use-hints --export-id="rect_TL;rect_TC;rect_TR;rect_CL;rect_CC;rect_CR;rect_BL;rect_BC;rect_BR;rect_tick;rect_tick-left;rect_tick-right" img.svg +mv img/*.png img/bubble-grey/ + + +echo "Making Red ones..." +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='borderColor']/_:stop[@id='brdLGStop1']/@stop-color" --value "#ff383b" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intRaisedColor']/_:stop[@id='intRLGStop1']/@stop-color" --value "#ffb184" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickColor']/_:stop[@id='intTLGStop1']/@stop-color" --value "#ff6977" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickSideColor']/_:stop[@id='intTSLGStop1']/@stop-color" --value "#ff8f77" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop1']/@stop-color" --value "#ff657e" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop2']/@stop-color" --value "#ff8d77" img.svg + +inkscape --export-use-hints --export-id="rect_TL;rect_TC;rect_TR;rect_CL;rect_CC;rect_CR;rect_BL;rect_BC;rect_BR;rect_tick;rect_tick-left;rect_tick-right" img.svg +mv img/*.png img/bubble-red/ + + +echo "Making Blue ones..." +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='borderColor']/_:stop[@id='brdLGStop1']/@stop-color" --value "#1789cd" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intRaisedColor']/_:stop[@id='intRLGStop1']/@stop-color" --value "#80cdee" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickColor']/_:stop[@id='intTLGStop1']/@stop-color" --value "#b0f4ff" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickSideColor']/_:stop[@id='intTSLGStop1']/@stop-color" --value "#4de3ff" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop1']/@stop-color" --value "#c6f9ff" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop2']/@stop-color" --value "#5bbfee" img.svg + +inkscape --export-use-hints --export-id="rect_TL;rect_TC;rect_TR;rect_CL;rect_CC;rect_CR;rect_BL;rect_BC;rect_BR;rect_tick;rect_tick-left;rect_tick-right" img.svg +mv img/*.png img/bubble-blue/ + + +echo "Making Green ones..." +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='borderColor']/_:stop[@id='brdLGStop1']/@stop-color" --value "#17cd1d" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intRaisedColor']/_:stop[@id='intRLGStop1']/@stop-color" --value "#8fff47" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickColor']/_:stop[@id='intTLGStop1']/@stop-color" --value "#b8fc66" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intTickSideColor']/_:stop[@id='intTSLGStop1']/@stop-color" --value "#82ea2e" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop1']/@stop-color" --value "#c2ff6f" img.svg +xml ed --inplace --update "//_:defs[1]/_:linearGradient[@id='intLinearGradientStops']/_:stop[@id='intLGStop2']/@stop-color" --value "#82ea2e" img.svg + +inkscape --export-use-hints --export-id="rect_TL;rect_TC;rect_TR;rect_CL;rect_CC;rect_CR;rect_BL;rect_BC;rect_BR;rect_tick;rect_tick-left;rect_tick-right" img.svg +mv img/*.png img/bubble-green/ + +################ +# What was used to get color from orange +# +# +#for file in img/bubble-orange/*.png; +#do +# convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray img/bubble-grey/${file##*/} +# convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 img/bubble-red/${file##*/} +# convert $file -set option:modulate:colorspace hsb -modulate 110,80,10 img/bubble-blue/${file##*/} +# convert $file -set option:modulate:colorspace hsb -modulate 100,100,130 img/bubble-green/${file##*/} +#done diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/Kopie von incoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/Kopie von incoming.htm deleted file mode 100644 index 85aaeaa20..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/Kopie von incoming.htm +++ /dev/null @@ -1,30 +0,0 @@ - - - - -
    - - - - - - - - - - - - - - - - - - - - -
     %time%
    %message% %name%
    - -
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm index e90846d72..55a549564 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/hincoming.htm @@ -2,13 +2,14 @@ %css-style% +
    - + - + @@ -18,10 +19,10 @@ - + - - + +
     %time%
     %name%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm index 66a16951a..d34e49b25 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/houtgoing.htm @@ -2,14 +2,15 @@ %css-style% +
    - + - + @@ -18,10 +19,10 @@ - - + + - +
     %time%
     %name%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh deleted file mode 100644 index f6d2b0cd2..000000000 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/images.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -cd 'img/bubble-orange/' -for file in *.png; -do - convert $file -set option:modulate:colorspace hsb -modulate 100,50,100 -colorspace Gray ../bubble-grey/$file - convert $file -set option:modulate:colorspace hsb -modulate 110,80,80 ../bubble-red/$file -done - - - - #echo "hello ${file} - " - #convert $file -set option:modulate:colorspace hsb -modulate 100,20,100 ../bubble-grey/$file diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png index d9c28aaa7..fa45de4ab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png index 8a3e85ec3..68de5c296 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png index f18a209e2..db1424364 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CC.png index 23dd2df02..1af67f4cb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png index 346d6e3d6..60ab43b89 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png index e876448fc..77934e9d9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png index f21120bbd..bac53adab 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png index 5212f419d..e9261c34c 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png index f1c15529a..25ed23587 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png index 3a6ccf16a..c162ec17a 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-right.png index ea72de738..b68140350 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick.png index a61428428..17ec2f461 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-blue/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BC.png index dd8882d96..071a260e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BL.png index e1289e246..9bcd7ffe3 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png index 65a70a294..655a2db64 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png index d498c3b85..61cf46ac0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CL.png index 7ef606a91..47f3f3d3b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png index 1d79a0904..38c07275f 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TC.png index a8b3d5385..b1233b2d2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png index 0a1c804de..7e43bfc0d 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TR.png index f17c5d47a..3bf52d2c9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png index 09424c08e..b3f423af0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-right.png index 5cbcb947f..61fd1bbe2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick.png index d508e6133..04eac5da6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-green/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BC.png index b23861b44..bef39f6a4 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png index 6d5e6e15e..eebfe3b91 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png index 68871cedd..2763880e9 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CC.png index 2f01fe1c0..0ba2d15ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png index ebe042e97..70a084c58 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CR.png index 798c5541d..01ab49103 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png index 8cb903994..1ea171038 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png index c3200aff4..1fd1527ee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TR.png index 85d2a1b2d..dceabb543 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png index 49fe22b33..c76994a67 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-right.png index 28b8cd138..c61a7b2e7 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick.png index 578346f3a..d53955494 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-grey/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BC.png index 9b1ee55b7..7c89990fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BL.png index 1bb3bcac4..6c9dd1ff0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png index 639fc3878..3cec3cc27 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CC.png index 08621dcbd..87d7ba3da 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png index f19354d8b..ecb8de13e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CR.png index 7e504b16c..2dc4b7ad6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png index ce4a2357a..64fa0e7c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png index 70e3cad64..ef3d963d6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TR.png index a083920ed..b87e86f35 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png index f407cbbf7..8efd044b0 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-right.png index b9011570c..ce25c9b62 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick.png index eaf56bd56..08bd0c310 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-orange/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png index 7bd1d84f9..c27064260 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png index 5018dc60a..4d22f79c1 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png index 994743d0c..00d2a6255 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_BR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CC.png index 8bca51700..e70c461f2 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CL.png index c9a6aad38..b5095e4fb 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png index d538eea05..08b3a53ae 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_CR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png index 27c7d02b4..9900f8bee 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TC.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png index c5e3fc3b1..12ce5c81e 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TL.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TR.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TR.png index 9122e8ca2..b9d05761b 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TR.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_TR.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png index d1b1f6b64..7e332b401 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-left.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-right.png index d4a905aac..9bdd6ceb6 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-right.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick-right.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png index 313e2db04..8ef8a7a23 100644 Binary files a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png and b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/img/bubble-red/bubble_tick.png differ diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/incoming.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/incoming.htm index c0ea6893d..7e55bbe89 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/incoming.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/incoming.htm @@ -3,14 +3,13 @@ -
    - + - + @@ -20,10 +19,10 @@ - + - - + +
     %time%
     %name%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css index 8f09e4dd8..dd249dca7 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/main.css @@ -3,7 +3,7 @@ color: #FF0000; } -.time { +.time { font-size: 9px; } .incomingHeader { @@ -37,39 +37,59 @@ color: #FF0000; } .bubble-orange { } -.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); } +.bubble-orangeTL { background-image: url(%style-dir%/img/bubble-orange/bubble_TL.png); font-size: 9px; } +.bubble-orangeTC { background-image: url(%style-dir%/img/bubble-orange/bubble_TC.png); font-size: 9px; } +.bubble-orangeTR { background-image: url(%style-dir%/img/bubble-orange/bubble_TR.png); font-size: 9px; } +.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } .bubble-orangeCC { background-image: url(%style-dir%/img/bubble-orange/bubble_CC.png); } .bubble-orangeCR { background-image: url(%style-dir%/img/bubble-orange/bubble_CR.png); } -.bubble-orangeCL { background-image: url(%style-dir%/img/bubble-orange/bubble_CL.png); } -.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); } +.bubble-orangeBL { background-image: url(%style-dir%/img/bubble-orange/bubble_BL.png); font-size: 9px; } +.bubble-orangeBC { background-image: url(%style-dir%/img/bubble-orange/bubble_BC.png); font-size: 9px; } +.bubble-orangeBR { background-image: url(%style-dir%/img/bubble-orange/bubble_BR.png); font-size: 9px; } .bubble-grey { color: #666; } -.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); } +.bubble-greyTL { background-image: url(%style-dir%/img/bubble-grey/bubble_TL.png); font-size: 9px; } +.bubble-greyTC { background-image: url(%style-dir%/img/bubble-grey/bubble_TC.png); font-size: 9px; } +.bubble-greyTR { background-image: url(%style-dir%/img/bubble-grey/bubble_TR.png); font-size: 9px; } +.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } .bubble-greyCC { background-image: url(%style-dir%/img/bubble-grey/bubble_CC.png); } .bubble-greyCR { background-image: url(%style-dir%/img/bubble-grey/bubble_CR.png); } -.bubble-greyCL { background-image: url(%style-dir%/img/bubble-grey/bubble_CL.png); } -.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); } +.bubble-greyBL { background-image: url(%style-dir%/img/bubble-grey/bubble_BL.png); font-size: 9px; } +.bubble-greyBC { background-image: url(%style-dir%/img/bubble-grey/bubble_BC.png); font-size: 9px; } +.bubble-greyBR { background-image: url(%style-dir%/img/bubble-grey/bubble_BR.png); font-size: 9px; } .bubble-red { color: #B33; } -.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); } +.bubble-redTL { background-image: url(%style-dir%/img/bubble-red/bubble_TL.png); font-size: 9px; } +.bubble-redTC { background-image: url(%style-dir%/img/bubble-red/bubble_TC.png); font-size: 9px; } +.bubble-redTR { background-image: url(%style-dir%/img/bubble-red/bubble_TR.png); font-size: 9px; } +.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } .bubble-redCC { background-image: url(%style-dir%/img/bubble-red/bubble_CC.png); } .bubble-redCR { background-image: url(%style-dir%/img/bubble-red/bubble_CR.png); } -.bubble-redCL { background-image: url(%style-dir%/img/bubble-red/bubble_CL.png); } -.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); } +.bubble-redBL { background-image: url(%style-dir%/img/bubble-red/bubble_BL.png); font-size: 9px; } +.bubble-redBC { background-image: url(%style-dir%/img/bubble-red/bubble_BC.png); font-size: 9px; } +.bubble-redBR { background-image: url(%style-dir%/img/bubble-red/bubble_BR.png); font-size: 9px; } .bubble-green { } -.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); } +.bubble-greenTL { background-image: url(%style-dir%/img/bubble-green/bubble_TL.png); font-size: 9px;} +.bubble-greenTC { background-image: url(%style-dir%/img/bubble-green/bubble_TC.png); font-size: 9px;} +.bubble-greenTR { background-image: url(%style-dir%/img/bubble-green/bubble_TR.png); font-size: 9px;} +.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } .bubble-greenCC { background-image: url(%style-dir%/img/bubble-green/bubble_CC.png); } .bubble-greenCR { background-image: url(%style-dir%/img/bubble-green/bubble_CR.png); } -.bubble-greenCL { background-image: url(%style-dir%/img/bubble-green/bubble_CL.png); } -.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); } +.bubble-greenBL { background-image: url(%style-dir%/img/bubble-green/bubble_BL.png); font-size: 9px;} +.bubble-greenBC { background-image: url(%style-dir%/img/bubble-green/bubble_BC.png); font-size: 9px;} +.bubble-greenBR { background-image: url(%style-dir%/img/bubble-green/bubble_BR.png); font-size: 9px;} .bubble-blue { } -.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); } +.bubble-blueTL { background-image: url(%style-dir%/img/bubble-blue/bubble_TL.png); font-size: 9px; } +.bubble-blueTC { background-image: url(%style-dir%/img/bubble-blue/bubble_TC.png); font-size: 9px; } +.bubble-blueTR { background-image: url(%style-dir%/img/bubble-blue/bubble_TR.png); font-size: 9px; } +.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } .bubble-blueCC { background-image: url(%style-dir%/img/bubble-blue/bubble_CC.png); } .bubble-blueCR { background-image: url(%style-dir%/img/bubble-blue/bubble_CR.png); } -.bubble-blueCL { background-image: url(%style-dir%/img/bubble-blue/bubble_CL.png); } -.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); } +.bubble-blueBL { background-image: url(%style-dir%/img/bubble-blue/bubble_BL.png); font-size: 9px; } +.bubble-blueBC { background-image: url(%style-dir%/img/bubble-blue/bubble_BC.png); font-size: 9px; } +.bubble-blueBR { background-image: url(%style-dir%/img/bubble-blue/bubble_BR.png); font-size: 9px; } .time { color: #AAA; } diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm index c9028a9df..820d0daaf 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/ooutgoing.htm @@ -2,14 +2,15 @@ %css-style% + No firmado - + items found. elementos encontrados. @@ -2790,7 +3024,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Escriba un mensaje aquí - + Don't stop to color after No parar de colorear tras @@ -2948,12 +3182,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.ConfCertDialog - + Details Detalles - + Local Address Dirección local @@ -2964,12 +3198,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Dirección externa - + Node info: Información de nodo: - + Current address: Dirección actual: @@ -2985,31 +3219,36 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Puerto - + Include signatures Incluir firmas - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: No se pueden obtener los detalles del vecino. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Cifrado - + Not connected No conectado - + Retroshare node details Detalles del nodo RetroShare - + Node name : Nombre del nodo : @@ -3075,13 +3319,18 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Mensaje de estado: - + + Connectivity + + + + List of known addresses: Lista de direcciones conocidas: - - + + Retroshare Certificate Certificado de RetroShare @@ -3096,7 +3345,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto. - + Hidden Address Dirección oculta @@ -3107,11 +3356,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.ninguno + <p>This certificate contains: - <p>Este certificado contiene: + <p>Este certificado contiene: - + <li>a <b>node ID</b> and <b>name</b> <li>una <b>identificación de nodo</b> y <b>nombre</b> @@ -3124,12 +3374,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.una <b>dirección IP</b> y <b>puerto</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Puede usar este certificado para hacer nuevos amigos. Envíelo por correo electrónico, o proporciónelo en mano.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Este es el certificado <span style=" font-weight:600;">OpenSSL</span> de la identificación (ID) del nodo, que está firmada por la clave <span style=" font-weight:600;">PGP</span> de arriba. </p></body></html> @@ -3139,7 +3389,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.<html><head/><body><p>Este es el método de cifrado usado por <span style=" font-weight:600;">OpenSSL</span>. La conexión a nodos amigos</p><p>siempre se cifra fuertemente, y si está presente el DHE (intercambio de claves Diffie-Hellman)</p><p>la conexión además usa &quot;secreto perfecto hacia delante&quot; (perfect forward secrecy).</p></body></html> - + with con @@ -3345,12 +3595,12 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.Detalles de la solicitud - + Peer details Detalles del vecino - + Name: Nombre: @@ -3369,12 +3619,12 @@ resources. recursos. - + Location: Lugar: - + Options Opciones @@ -3411,12 +3661,12 @@ recursos.Pegar certificado - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Este recuadro espera el certificado de RetroShare de su amigo. ADVERTENCIA: Este es distinto de la clave del perfil de su amigo. No pegue aquí la clave del perfil de su amigo (ni siquiera una parte de ella). No va a funcionar.</p></body></html> - + Add friend to group: Añadir amigo a grupo: @@ -3426,7 +3676,7 @@ recursos.Autenticar amigo (firmar la clave PGP) - + Please paste below your friend's Retroshare ID @@ -3451,7 +3701,7 @@ recursos. - + Add as friend to connect with Añadir como amigo al conectarse con @@ -3460,7 +3710,7 @@ recursos.Para aceptar la solicitud de amigo, pulse en el botón Finalizar. - + Sorry, some error appeared Lo siento, ha ocurrido un error @@ -3480,32 +3730,32 @@ recursos.Detalles acerca de su amigo: - + Key validity: Validez de la clave: - + Profile ID: - + Signers Firmantes - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo a sus otros amigos. Las firmas de debajo atestiguan criptográficamente que los titulares de las claves listadas reconocen como auténtica la clave PGP actual.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Este vecino ya está en su lista de amigos. Añadiendolo sólo podrá establecer su dirección ip. - + To accept the Friend Request, click the Accept button. @@ -3551,7 +3801,7 @@ recursos. - + Certificate Load Failed Error al cargar el certificado @@ -3588,12 +3838,12 @@ recursos.El certificado parece ser válido - + Not a valid Retroshare certificate! ¡No es un certificado RetroShare válido! - + RetroShare Invitation Invitación de RetroShare @@ -3615,12 +3865,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? ¿Este es su propio certificado? No querría hacerse amigo de si mismo. ¿No es así? - + @@ -3668,7 +3918,37 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Tiene una solicitud de amistad de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3756,12 +4036,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Utilizar como fuente directa, cuando esté disponible - + IP-Addr: Dir-IP: - + IP-Address Dirección-IP @@ -3827,7 +4107,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Añadir al grupo de claves ('keyring') - + This key is already in your keyring Esta clave ya está en su grupo de claves ('keyring') @@ -3888,12 +4168,12 @@ incluso si no hace amigos. <p>Este certificado no tiene IP. Dependerá del descubrimiento y la DHT (tabla distribuida de hashes) para encontrarlo. A causa de que usted requiere que se limpie la lista blanca, el vecino generará una advertencia de seguridad en la pestaña de Novedades (feed). Desde allí puede añadir su IP a la lista blanca.</p> - + [Unknown] - + Added with certificate from %1 Añadido con el certificado de %1 @@ -3980,7 +4260,12 @@ incluso si no hace amigos. Resultado UDP - + + Status + Estado + + + <!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; } @@ -4410,7 +4695,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4562,7 +4847,7 @@ p, li { white-space: pre-wrap; } No hay limitaciones en el círculo seleccionado - + [Unknown] @@ -4577,7 +4862,7 @@ p, li { white-space: pre-wrap; } Eliminar - + Search Buscar @@ -4597,7 +4882,7 @@ p, li { white-space: pre-wrap; } Firmado por nodos conocidos - + Edit Circle Editar círculo @@ -4617,12 +4902,12 @@ p, li { white-space: pre-wrap; } Identidad anónima - + Circle name Nombre del círculo - + Update Actualizar @@ -4648,7 +4933,7 @@ p, li { white-space: pre-wrap; } Identidad vinculada a PGP - + Add Member Añadir miembro @@ -4792,7 +5077,7 @@ p, li { white-space: pre-wrap; } - + Attachments Adjuntos @@ -4838,7 +5123,7 @@ p, li { white-space: pre-wrap; } Arrastrar y soltar archivos de los resultados de la búsqueda - + Paste RetroShare Links Pegar enlaces de RetroShare @@ -4848,7 +5133,7 @@ p, li { white-space: pre-wrap; } Pegar enlace de RetroShare - + Drop file error. Error al arrastrar. @@ -4875,17 +5160,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Archivo ya añadido y hash generado + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Archivo ya añadido y hash generado + + + Please add a Subject Por favor, añada un asunto @@ -4916,12 +5225,12 @@ p, li { white-space: pre-wrap; } ¿De veras quiere generar %1 mensajes? - + You are about to add files you're not actually sharing. Do you still want this to happen? Está a punto de añadir archivos que actualmente no está compartiendo. ¿Seguro que quiere continuar? - + Edit Channel Post Editar mensaje del canal @@ -4941,7 +5250,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Está a punto de publicar archivos sin dueño en un canal. @@ -5033,7 +5342,7 @@ p, li { white-space: pre-wrap; } - + No Forum Ningún foro @@ -5493,7 +5802,7 @@ y utilizar el botón Importar para cargarla DHTGraphSource - + users usuarios @@ -6500,7 +6809,7 @@ y utilizar el botón Importar para cargarla FlatStyle_RDM - + Friends Directories Carpetas de amigos @@ -7006,7 +7315,7 @@ al menos un vecino no fue añadido al grupo Buscar a amigos - + Mark all Marcar todo @@ -7020,7 +7329,7 @@ al menos un vecino no fue añadido al grupo FriendsDialog - + Edit status message Editar mensaje de estado @@ -7124,7 +7433,7 @@ al menos un vecino no fue añadido al grupo Chat de difusión de RetroShare: Los mensajes se envían a todos los amigos conectados. - + Network Red @@ -7189,7 +7498,7 @@ al menos un vecino no fue añadido al grupo Se requiere que el campo del nodo tenga un mínimo de 3 caracteres - + Failed to generate your new certificate, maybe PGP password is wrong! ¡Fallo al generar su nuevo certificado, quizá la contraseña PGP está mal! @@ -7232,7 +7541,7 @@ al menos un vecino no fue añadido al grupo Usar perfil existente - + Node name Nombre del nodo @@ -7499,12 +7808,12 @@ y usar el botón Importar para cargarlo - + Profile generation failure Fallo al generar perfil - + Missing PGP certificate Certificado PGP desaparecido @@ -7923,7 +8232,7 @@ p, li { white-space: pre-wrap; } Estadísticas del router - + GroupBox GroupBox @@ -7988,7 +8297,7 @@ p, li { white-space: pre-wrap; } Factor de ramificado - + Details Detalles @@ -8011,7 +8320,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Claves administradas @@ -8220,7 +8529,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Título @@ -8230,13 +8539,30 @@ p, li { white-space: pre-wrap; } Buscar por el título - - + + + + Description Descripción - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Buscar por la descripción @@ -8246,42 +8572,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Ordenar en orden descendente + Ordenar en orden descendente - Sort Ascending Order - Ordenar en orden ascendente + Ordenar en orden ascendente - Sort by Name - Ordenar por nombre + Ordenar por nombre - Sort by Popularity - Ordenar por popularidad + Ordenar por popularidad - Sort by Last Post - Ordenar por última entrada + Ordenar por última entrada - Sort by Number of Posts - Ordenar por número de mensajes + Ordenar por número de mensajes - Sort by Unread - Ordenar por no leídos + Ordenar por no leídos - + You are admin (modify names and description using Edit menu) Usted es administrador (modifique nombres y descripciones usando el menú Editar) @@ -8296,40 +8615,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post Última publicación - + + Name Nombre - - Unread - - - - + Popularity Popularidad - - + + Never Nunca - Display - Mostrar + Mostrar - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8478,7 +8792,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Canales @@ -8503,12 +8817,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Canales</h1> <p>Los canales le permiten publicar datos (ej. películas, música) que se diseminarán por la red</p> <p>Puede ver los canales a los que están suscritos sus amigos, y reenviar automáticamente los canales a los que esté suscrito a sus amigos. Esto promueve buenos canales en la red.</p> <p>Sólo el creador del canal puede publicar en ese canal. Otros vecinos en la red sólo pueden leer de él, a no ser que el canal sea privado. Sin embargo, puede compartir los derechos de publicación o lectura con nodos RetroShare amigos.</p> <p>Los canales pueden hacerse anónimos, o ligados a una identidad de RetroShare de forma que los lectores puedan contactar con usted si lo necesitan. Habilite "Permitir comentarios" si quiere permitir a los usuarios comentar en sus posts.</p> <p>Los posts de canal se conservan durante %1 días, y se sincronizan para los últimos %2 días, a menos que cambie esto.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canales suscritos @@ -9033,7 +9347,7 @@ p, li { white-space: pre-wrap; } - + Add new post Añadir nuevo mensaje @@ -9133,12 +9447,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Comentarios @@ -9149,18 +9463,18 @@ p, li { white-space: pre-wrap; } - + Feeds Novedades (feeds) - - + + Click to switch to list view - + Show unread posts only @@ -9170,12 +9484,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9235,7 +9549,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9250,12 +9564,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9331,23 +9645,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Suscrito - - Subscribe Suscribirse - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Ningún canal seleccionado @@ -9369,11 +9696,6 @@ p, li { white-space: pre-wrap; } Channel Post Mensaje al canal - - - new message(s) - - GxsCircleItem @@ -9902,7 +10224,7 @@ before you can comment Iniciar nuevo tema para el foro seleccionado - + Search forums Buscar foros @@ -9911,12 +10233,12 @@ before you can comment Último mensaje - + New Thread Nuevo hilo - + Threaded View Vista por discusión @@ -9926,19 +10248,19 @@ before you can comment Vista plana - - + + Title Título - - + + Date Fecha - + Author Autor @@ -9953,7 +10275,17 @@ before you can comment Cargando - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10014,23 +10346,23 @@ before you can comment <p>Suscribiendose al foro reunirá los posts disponibles de los amigos a los que esté suscrito, y hará el foro visible al resto de sus amigos.</p><p>Posteriormente puede desuscribirse desde el menú contextual de la lista del foro a la izquierda.</p> - + No name Sin nombre - - + + Reply Responder - + <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> - + Loading... @@ -10068,12 +10400,12 @@ before you can comment Marcar como no leído - + Copy RetroShare Link Copiar enlace de RetroShare - + Hide Ocultar @@ -10086,7 +10418,7 @@ before you can comment [Excluido] - + [unknown] [desconocido] @@ -10116,8 +10448,8 @@ before you can comment Sólo para sus ojos - - + + Distribution Distribución @@ -10220,7 +10552,7 @@ before you can comment Mensaje original - + New thread Nuevo hilo @@ -10229,7 +10561,7 @@ before you can comment Estado de lectura - + Edit Editar @@ -10285,7 +10617,7 @@ before you can comment Mostrar autor en la pestaña Personas - + Author's reputation Reputación del autor @@ -10305,7 +10637,7 @@ before you can comment - + <b>Loading...<b> @@ -10345,6 +10677,11 @@ before you can comment Storage Almacenamiento + + + Last seen at friends: + + Moderators @@ -10439,7 +10776,7 @@ reenviado a sus amigos. En %1, %2 escribió: - + Forum name Nombre del foro @@ -10471,11 +10808,6 @@ reenviado a sus amigos. Forum Post Mensaje al foro - - - new message(s) - - GxsForumsDialog @@ -10924,7 +11256,7 @@ reenviado a sus amigos. Vista previa de impresión - + Unsubscribe Anular suscripción @@ -10939,7 +11271,7 @@ reenviado a sus amigos. Abrir en una nueva pestaña - + Remove this search @@ -10949,12 +11281,12 @@ reenviado a sus amigos. - + Request data - + Show Details Mostrar detalles @@ -11021,7 +11353,7 @@ reenviado a sus amigos. - + Search for @@ -11030,7 +11362,7 @@ reenviado a sus amigos. Compartir permisos de publicación - + Copy RetroShare Link Copiar enlace de RetroShare @@ -11045,7 +11377,7 @@ reenviado a sus amigos. Marcar todo como no leído - + AUTHD Autentificado @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11671,7 +12003,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11697,6 +12029,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11708,7 +12057,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11784,27 +12133,32 @@ p, li { white-space: pre-wrap; } Formulario - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11826,6 +12180,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11834,7 +12189,7 @@ p, li { white-space: pre-wrap; } El texto de debajo es su propio certificado de RetroShare. Envíeselo a sus amigos - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11850,12 +12205,12 @@ de código abierto, multi-sistema, privada y segura. ¿Necesita ayuda con RetroShare? - + Open Web Help Ayuda de Open Web - + Copy your Cert to Clipboard Copiar su certificado al portapapeles @@ -11904,7 +12259,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11913,7 +12268,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12206,14 +12561,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Todo - + Reputation Reputación @@ -12223,12 +12578,12 @@ p, li { white-space: pre-wrap; } Buscar - + Anonymous Id ID anónima - + Create new Identity Crear nueva identidad @@ -12372,7 +12727,7 @@ p, li { white-space: pre-wrap; } Identificación de la identidad - + Send message Enviar mensaje @@ -12464,7 +12819,7 @@ p, li { white-space: pre-wrap; } Global: - + Anonymous Anónimo @@ -12479,24 +12834,24 @@ p, li { white-space: pre-wrap; } Buscar identificación - + This identity is owned by you Esta identidad es propiedad de usted - - + + My own identities Mis propias identidades - - + + My contacts Mis contactos - + Show Items Mostrar elementos @@ -12511,7 +12866,7 @@ p, li { white-space: pre-wrap; } Enlazado a mi nodo - + Other circles Otros círculos @@ -12570,13 +12925,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). suscrito (recibe/reenvía peticiones de membresía de otros y recibe la lista de invitaciones). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). no suscrito (sólo recibe la lista de invitaciones). - + Your status: Su estatus: @@ -12636,7 +12996,7 @@ p, li { white-space: pre-wrap; } Miembro - + Edit Circle Editar círculo @@ -12684,7 +13044,7 @@ p, li { white-space: pre-wrap; } Conceder membresía - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12696,12 +13056,12 @@ Estas identidades pronto dejarán de estar soportadas. - + [Unknown node] [Nodo desconocido] - + Unverified signature from node Firma del nodo no verificada @@ -12713,12 +13073,12 @@ Estas identidades pronto dejarán de estar soportadas. Firma no comprobada - + [unverified] [no verificada] - + Identity owned by you, linked to your Retroshare node Identidad propiedad de usted, asociada a su nodo RetroShare @@ -12842,12 +13202,12 @@ Estas identidades pronto dejarán de estar soportadas. ¿Está seguro de que quiere enviar una invitación con su certificado? - + Banned Excluido - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identidades</h1> <p>En esta pestaña puede crear/editar <b>identidades pseudo-anónimas</b>, y <b>círculos</b>.</p> <p>Las <b>identidades</b> se usan para identificar sus datos de forma segura: firmar mensajes en salas de chat, foros y posts en canales, recibir comentarios usando el sistema de correo electrónico integrado de RetroShare, comentarios publicados tras los posts en los canales, chat usando túneles seguros, etc.</p> <p>Las identidades opcionalmente pueden estar <b>firmadas</b> por el certificado de su nodo RetroShare. Es más fácil confiar en las identidades firmadas pero son más fácilmente vinvulables con la dirección IP de su nodo.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> @@ -12856,7 +13216,7 @@ Estas identidades pronto dejarán de estar soportadas. Identidad desconocida: - + positive positivo @@ -13041,8 +13401,8 @@ Estas identidades pronto dejarán de estar soportadas. - - + + People Personas @@ -13053,7 +13413,7 @@ Estas identidades pronto dejarán de estar soportadas. Su avatar - + Linked to neighbor nodes Enlazado hacia nodos vecinos @@ -13063,7 +13423,7 @@ Estas identidades pronto dejarán de estar soportadas. Enlazado hacia nodos distantes - + Linked to a friend Retroshare node Enlazado hacia un nodo de RetroShare amigo @@ -13123,7 +13483,7 @@ Estas identidades pronto dejarán de estar soportadas. Propiedad de - + Node name: Nombre del nodo: @@ -13133,7 +13493,7 @@ Estas identidades pronto dejarán de estar soportadas. Identificación del nodo: - + Really delete? ¿Está seguro de borrar? @@ -13171,7 +13531,22 @@ Estas identidades pronto dejarán de estar soportadas. Seudónimo - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nueva identidad @@ -13188,14 +13563,14 @@ Estas identidades pronto dejarán de estar soportadas. - + N/A N/A - + Edit identity Editar identidad @@ -13206,24 +13581,27 @@ Estas identidades pronto dejarán de estar soportadas. Actualizar - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13242,17 +13620,27 @@ Estas identidades pronto dejarán de estar soportadas. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! ¡Error al obtener la clave! - + Error KeyID invalid Error, ID de la clave no válida - + Unknown GpgId ID PGP desconocida @@ -13262,7 +13650,7 @@ Estas identidades pronto dejarán de estar soportadas. Nombre real desconocido - + Create New Identity Crear nueva identidad @@ -13272,7 +13660,12 @@ Estas identidades pronto dejarán de estar soportadas. Tipo - + + Choose image... + + + + @@ -13312,12 +13705,11 @@ Estas identidades pronto dejarán de estar soportadas. Su avatar - Set Avatar - Establecer avatar + Establecer avatar - + Linked to your profile Enlazado a su perfil @@ -13327,7 +13719,7 @@ Estas identidades pronto dejarán de estar soportadas. Puede tener una o más identidades. Se usan cuando escribe un salas de chat, foros y comentarios de canales. Actúan como el destinatario para conversaciones distantes y el sistema de correo distante de RetroShare. - + The nickname is too short. Please input at least %1 characters. El apodo es demasiado corto. Por favor, introduzca al menos %1 caracteres. @@ -13436,8 +13828,12 @@ Estas identidades pronto dejarán de estar soportadas. + Quote + Citar + + Send - Enviar + Enviar @@ -13595,7 +13991,7 @@ Estas identidades pronto dejarán de estar soportadas. - + Options Opciones @@ -13627,12 +14023,12 @@ Estas identidades pronto dejarán de estar soportadas. Asistente para el inicio rápido - + RetroShare %1 a secure decentralized communication platform RetroShare %1 es una plataforma de comunicación descentralizada y segura - + Unfinished Incompleto @@ -13765,7 +14161,7 @@ Estas identidades pronto dejarán de estar soportadas. Mostrar - + Make sure this link has not been forged to drag you to a malicious website. Asegúrese de que este enlace no ha sido falsificado para arrastrarle a un sitio web malicioso. @@ -13810,7 +14206,7 @@ Estas identidades pronto dejarán de estar soportadas. Matriz de permisos del servicio - + Statistics Estadísticas @@ -13839,7 +14235,7 @@ Estas identidades pronto dejarán de estar soportadas. MessageComposer - + Compose Componer @@ -13941,7 +14337,7 @@ Estas identidades pronto dejarán de estar soportadas. - + Tags Etiquetas @@ -14036,12 +14432,12 @@ Estas identidades pronto dejarán de estar soportadas. Añadir cita - + Send To: Enviar a: - + &Left &Izquierda @@ -14075,7 +14471,7 @@ Estas identidades pronto dejarán de estar soportadas. Mis contactos - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hola,<br>Le recomiendo a un buen amigo mío, puede confiar en él tanto como confía en mí. <br> @@ -14101,12 +14497,12 @@ Estas identidades pronto dejarán de estar soportadas. - + Save Message Guardar mensaje - + Message has not been Sent. Do you want to save message to draft box? El mensaje no se ha enviado. @@ -14118,7 +14514,7 @@ Do you want to save message to draft box? Pegar enlace de RetroShare - + Add to "To" Añadir a "A" @@ -14373,7 +14769,7 @@ Do you want to save message ? Añadir otro archivo - + Hi,<br>I want to be friends with you on RetroShare.<br> Hola,<br>quiero establecer amistad contigo en RetroShare.<br> @@ -14382,12 +14778,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Tiene una invitación de amistad. - + Respond now: Responder ahora: @@ -14403,11 +14814,12 @@ Do you want to save message ? De: + Friend Nodes - Nodos amigos + Nodos amigos - + Bullet list (disc) Lista con puntos (discos) @@ -14447,13 +14859,13 @@ Do you want to save message ? Lista ordenada (números romanos en mayúscula) - - + + Thanks, <br> Gracias, <br> - + Distant identity: Identidad distante: @@ -14592,8 +15004,23 @@ Do you want to save message ? Mensaje - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14605,12 +15032,12 @@ Do you want to save message ? Archivos recomendados - + Download all Recommended Files Descargar todos los archivos recomendados - + Subject: Asunto: @@ -14685,12 +15112,18 @@ Do you want to save message ? Enviar invitación - + + Message Size: + + + + File Name Nombre de archivo - + + Size Tamaño @@ -14751,10 +15184,25 @@ Do you want to save message ? Descargar - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? ¿Enviar invitación? @@ -14765,12 +15213,12 @@ Do you want to save message ? - + Download all Dercargar todo - + Print Document Imprimir documento @@ -14785,7 +15233,7 @@ Do you want to save message ? Archivos HTML (*.htm *.html);;Todos los archivos(*) - + Load images always for this message Cargar siempre imágenes para este mensaje @@ -14926,7 +15374,7 @@ Do you want to save message ? MessagesDialog - + New Message Nuevo mensaje @@ -14982,14 +15430,14 @@ Do you want to save message ? - + Tags Etiquetas - + Inbox Bandeja de entrada @@ -15084,7 +15532,7 @@ Do you want to save message ? Reenviar mensaje - + Subject Asunto @@ -15196,7 +15644,7 @@ Do you want to save message ? - + Open in a new window Abrir en una ventana nueva @@ -15281,7 +15729,7 @@ Do you want to save message ? - + Drafts Borradores @@ -15410,7 +15858,7 @@ Do you want to save message ? Responder a mensaje - + Delete Message Borrar mensaje @@ -15421,7 +15869,7 @@ Do you want to save message ? - + Expand Abrir @@ -15431,7 +15879,7 @@ Do you want to save message ? Quitar objeto - + from de @@ -15440,6 +15888,11 @@ Do you want to save message ? Reply to invite Responder a la invitación + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15762,7 +16215,7 @@ Se informo del error: - + Groups Grupos @@ -15792,19 +16245,19 @@ Se informo del error: importar su lista de amigos incluyendo grupos - - + + Search Buscar - + ID - + Search ID @@ -15814,7 +16267,7 @@ Se informo del error: - + Show Items Mostrar elementos @@ -16018,19 +16471,19 @@ al menos un vecino no fue añadido al grupo - + Error Error - + File is not writeable! ¡El fichero no es escribible! - + File is not readable! ¡El fichero no es legible! @@ -16068,9 +16521,13 @@ al menos un vecino no fue añadido al grupo NewsFeed - Log entries - Entradas de registro (log) + Entradas de registro (log) + + + + Activity Stream + @@ -16087,7 +16544,7 @@ al menos un vecino no fue añadido al grupo Esto es una prueba. - + Newest on top Los más recientes arriba @@ -16098,20 +16555,43 @@ al menos un vecino no fue añadido al grupo + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Suscripción de noticias</h1> <p>La suscripción de registro (log feed) muestra los últimos eventos en su red, ordenados por la hora a la que los recibió. Esto le proporciona un compendio de la actividad de sus amigos. Puede configurar qué eventos mostrar pulsando en <b>Opciones</b>. </p> <p>Los distintos eventos mostrados son: <ul> <li>Intentos de conexión (útil para hacer amigos con nuevas personas y controlar quién está tratando de acceder a usted)</li> <li>Posts de canal y foro</li> <li>Nuevos canales y foros a los que puede suscribirse</li> <li>Mensajes privados de sus amigos</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Suscripción de noticias</h1> <p>La suscripción de registro (log feed) muestra los últimos eventos en su red, ordenados por la hora a la que los recibió. Esto le proporciona un compendio de la actividad de sus amigos. Puede configurar qué eventos mostrar pulsando en <b>Opciones</b>. </p> <p>Los distintos eventos mostrados son: <ul> <li>Intentos de conexión (útil para hacer amigos con nuevas personas y controlar quién está tratando de acceder a usted)</li> <li>Posts de canal y foro</li> <li>Nuevos canales y foros a los que puede suscribirse</li> <li>Mensajes privados de sus amigos</li> </ul> </p> + + + Log + Registro (log) - Log - Registro (log) + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16148,22 +16628,22 @@ al menos un vecino no fue añadido al grupo - + Test Prueba - + Chat Room Sala de chat - + Systray Icon Icono en la Bandeja de sistema - + Message Mensaje @@ -16188,12 +16668,11 @@ al menos un vecino no fue añadido al grupo Seguridad de la IP - Log - Registro (log) + Registro (log) - + Friend Connected Amigo conectado @@ -16207,7 +16686,12 @@ al menos un vecino no fue añadido al grupo Enlaces - + + Activity + + + + Mails Correos @@ -16244,7 +16728,12 @@ al menos un vecino no fue añadido al grupo Chat de grupo - + + Toaster position + + + + Chat rooms Salas de chat @@ -16269,22 +16758,22 @@ al menos un vecino no fue añadido al grupo Distingue mayúsculas y minúsculas - + Position Posición - + X Margin Distancia horizontal - + Y Margin Distancia vertical - + Systray message Mensaje en la bandeja del sistema @@ -16334,7 +16823,7 @@ al menos un vecino no fue añadido al grupo Notificación - + Disable All Toasters Deshabilitar todas las notitificaciones @@ -16348,7 +16837,7 @@ al menos un vecino no fue añadido al grupo Novedades (feed) - + Systray Bandeja del sistema @@ -16494,17 +16983,16 @@ Sin Anonimato D/S: desactiva el reenvío de archivos PGPKeyDialog - Dialog - Diálogo + Diálogo - + Profile info Información del perfil - + Name : Nombre : @@ -16559,22 +17047,21 @@ Sin Anonimato D/S: desactiva el reenvío de archivos Máxima - + This profile has signed your own profile key Este perfil ha firmado su propia clave del perfil - Key signatures : - Firmas de clave : + Firmas de clave : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este al resto de sus amigos. Las firmas de debajo atestiguan criptográficamente que los propietarios de las claves listadas reconocen la clave PGP actual como auténtica.</span></p></body></html> - + <!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; } @@ -16592,7 +17079,7 @@ p, li { white-space: pre-wrap; } Firmar esta clave - + PGP key Clave PGP @@ -16602,22 +17089,20 @@ p, li { white-space: pre-wrap; } Estas opciones se aplican a todos los nodos del perfil: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo al resto de sus amigos. Les ayuda a decidir si permitir conexiones desde esa clave en base a su propia confianza. Firmar una clave es absolutamente opcional y no puede deshacerse, así que hágalo con sabiduría.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Firmar la clave de un amigo es una forma de expresar su confianza en este amigo al resto de sus amigos. Les ayuda a decidir si permitir conexiones desde esa clave en base a su propia confianza. Firmar una clave es absolutamente opcional y no puede deshacerse, así que hágalo con sabiduría.</span></p></body></html> - + Keysigning: - Sign PGP key - Firmar clave PGP + Firmar clave PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Haga clic aquí si quiere rechazar conexiones a nodos autentificados por esta clave.</p></body></html> @@ -16637,7 +17122,7 @@ p, li { white-space: pre-wrap; } Aceptar conexiones - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Debajo tiene la clave del perfil del nodo en formato ASCII PGP. Identifica todos los nodos del mismo perfil. Un "certificado de RetroShare" que puede intercambiar para hacer amigos, está en los "detalles" de cada nodo individual. @@ -16707,28 +17192,28 @@ p, li { white-space: pre-wrap; } KB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: No se pueden obtener los detalles del vecino. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) El algoritmo de la clave proporcionada no está soportado por RetroShare (Sólo están soportadas las claves RSA por el momento) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16742,7 +17227,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. El nivel de confianza es una forma de expresar su propia confianza en esta clave. No es utilizado por la aplicación ni se comparte, pero puede serle útil para recordar buenas/malas claves. @@ -16787,27 +17272,47 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Actualmente no está permitiendo conexiones de nodos RetroShare firmadas por esta clave. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Error de firma - - Maybe password is wrong - Probablemente la contraseña es errónea + + Check the password! + - + Maybe password is wrong + Probablemente la contraseña es errónea + + + You haven't set a trust level for this key. No ha establecido una nivel de confianza para esta clave. - + + Retroshare profile Perfil de RetroShare - + This is your own PGP key, and it is signed by : Esta es su propia clave PGP, y está firmada por: @@ -16986,8 +17491,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc PeopleDialog - - + People Personas @@ -17004,7 +17508,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Interno - + Chat with this person Chatear con esta persona @@ -17155,7 +17659,7 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Fotografía - + TextLabel Texto de la etiqueta @@ -17199,8 +17703,8 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc - <N> Comments >> - + Comments + Comentarios @@ -17235,6 +17739,11 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Write a comment... Escribir un comentario... + + + Album + Álbum + PhotoItem @@ -17244,12 +17753,12 @@ Advertencia: En su opción de Transferencia-de-fichero, establezca permitir desc Formulario - + TextLabel Texto de la etiqueta - + <!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; } @@ -17345,7 +17854,7 @@ p, li { white-space: pre-wrap; } Ver foto - + PhotoShare Compartir fotos @@ -17386,7 +17895,7 @@ solicitar editarlo! - + Stop Detener @@ -17614,12 +18123,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autorizar todos los plugins - + Plugin look-up directories Directorios de búsqueda de plugin @@ -17678,7 +18187,7 @@ de un posible comportamiento malicioso de los plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Complementos</h1> <p>Los complementos (plugins) se cargan desde los directorios que aparecen en la lista del fondo.</p> <p>Por razones de seguridad, los complementos aceptados se cargan automáticamente hasta que el ejecutable principal de RetroShare o la librería del complemento cambian. En tal caso, el usuario necesita confirmarlos de nuevo. Después de que se inicie el programa, puede habilitar un complemento manualmente haciendo clic en el botón "Habilitar", y luego reiniciar RetroShare.</p> <p>Si quiere desarrollar sus propios complementos, contacte con el equipo de desarrolladores ¡ellos estarán contentos de auxiliarle!</p> - + Plugins Plugins @@ -18076,7 +18585,7 @@ de un posible comportamiento malicioso de los plugins. Enlaces - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18247,13 +18756,13 @@ de un posible comportamiento malicioso de los plugins. Lugar - - + + Comments Comentarios - + Copy RetroShare Link Copiar enlace de RetroShare @@ -18263,7 +18772,7 @@ de un posible comportamiento malicioso de los plugins. Mostrar autor en la pestaña Personas - + Comment Comentario @@ -18284,12 +18793,12 @@ de un posible comportamiento malicioso de los plugins. - + Hide Ocultar - + Vote up Votar positivo @@ -18303,7 +18812,7 @@ de un posible comportamiento malicioso de los plugins. \/ - + Set as read and remove item Ajustar como leer y eliminar elemento @@ -18364,7 +18873,7 @@ de un posible comportamiento malicioso de los plugins. - + Loading Cargando @@ -18454,13 +18963,7 @@ de un posible comportamiento malicioso de los plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18470,60 +18973,50 @@ de un posible comportamiento malicioso de los plugins. Administrador: - - - + + + unknown desconocido - + Distribution: Distribución: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Posts @@ -18534,7 +19027,7 @@ de un posible comportamiento malicioso de los plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18603,7 +19096,12 @@ de un posible comportamiento malicioso de los plugins. - + + Empty + Vacío + + + Copy RetroShare Link Copiar enlace de RetroShare @@ -18638,7 +19136,7 @@ de un posible comportamiento malicioso de los plugins. - + [No name] @@ -18766,8 +19264,18 @@ de un posible comportamiento malicioso de los plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19047,9 +19555,8 @@ y utilizar el botón Importar para cargarla PulseAddDialog - Post From: - Entrada de: + Entrada de: Account 1 @@ -19064,7 +19571,7 @@ y utilizar el botón Importar para cargarla Cuenta 3 - + Add to Pulse Añadir a Pulse @@ -19087,17 +19594,32 @@ y utilizar el botón Importar para cargarla URL - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19122,10 +19644,20 @@ y utilizar el botón Importar para cargarla Negativo - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19135,14 +19667,53 @@ y utilizar el botón Importar para cargarla - + + Post + + + + Cancel Cancelar - Post Pulse to Wire - Mensaje de Pulso para Wire + Mensaje de Pulso para Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19168,10 +19739,18 @@ y utilizar el botón Importar para cargarla Formulario - - - - + + + + + Click to view picture + + + + + + + Image Imágen @@ -19179,44 +19758,44 @@ y utilizar el botón Importar para cargarla PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19226,17 +19805,17 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19246,7 +19825,7 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19254,7 +19833,7 @@ y utilizar el botón Importar para cargarla PulseTopLevel - + retweeted @@ -19269,7 +19848,7 @@ y utilizar el botón Importar para cargarla - + follow Parent Group @@ -19279,7 +19858,7 @@ y utilizar el botón Importar para cargarla ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19304,7 +19883,7 @@ y utilizar el botón Importar para cargarla - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19340,29 +19919,29 @@ y utilizar el botón Importar para cargarla - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19440,7 +20019,7 @@ y utilizar el botón Importar para cargarla QObject - + Confirmation Confirmación @@ -19681,7 +20260,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Resultado - + Unable to make path Incapaz de hacer la ruta @@ -19716,7 +20295,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Solicitud del archivo cancelada - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Esta versión de RetroShare está usando OpenPGP SDK. Como efecto secundario, no está utilizando el juego de claves PGP compartido por el sistema, pero tiene su propio juego de claves compartido por todas las instancias de RetroShare. <br><br>No parece que tenga tal juego de claves, aunque las claves PGP son mencionadas por cuentas existentes de RetroShare, probablemente debido a que acaba de cambiar a esta nueva versión del programa. @@ -19873,7 +20452,7 @@ El error reportado es: segs - + TR up Transferencia de subida @@ -19918,7 +20497,7 @@ El error reportado es: deshabilitado - + Move IP %1 to whitelist Mover IP %1 a la lista blanca @@ -19934,7 +20513,7 @@ El error reportado es: - + %1 seconds ago hace %1 segundos @@ -20019,7 +20598,7 @@ Seguridad: No hay identificaciones anónimas - + Error Error @@ -20410,9 +20989,8 @@ Seguridad: No hay identificaciones anónimas Haz clic para continuar con el proceso de hashing - <p>This certificate contains: - <p>Este certificado contiene: + <p>Este certificado contiene: @@ -20781,7 +21359,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -21003,19 +21581,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Opciones de vista de árbol - Show column... - Mostrar columna... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Ordenar en orden descendente + + + + Sort Ascending Order + Ordenar en orden ascendente + + + + + [no title] + + + + + Show column … + + + + Show column... + Mostrar columna... - [no title] - [sin título] + [sin título] @@ -21451,7 +22058,7 @@ p, li { white-space: pre-wrap; } ¡Descargar! - + File Archivo @@ -21466,7 +22073,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Se han limpiado los nombres de archivo inadecuados @@ -21514,7 +22121,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Guardar - + Collection Editor Editor de colección @@ -21529,7 +22136,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Recuento de archivos - + Real Size: Waiting child... Tamaño real: Esperando descendientes... @@ -21544,12 +22151,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Esto es un directorio. Haga doble-clic para expandirlo. - + Download files Descargar archivos - + Specify... Especificar... @@ -21798,7 +22405,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr RsFriendListModel - + Name Nombre @@ -21818,7 +22425,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr IP - + Profile ID @@ -21831,10 +22438,15 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr RsGxsForumModel - + Title Título + + + UnRead + + Date @@ -21846,7 +22458,7 @@ Si crees que es correcto, elimina la correspondiente línea del archivo y reábr Autor - + Information for this identity is currently missing. La información para esta identidad actualmente está desaparecida. @@ -21888,7 +22500,7 @@ reenviado a sus amigos. - + [ ... Missing Message ... ] [ ... Mensaje perdido ... ] @@ -21896,7 +22508,7 @@ reenviado a sus amigos. RsMessageModel - + Date Fecha @@ -21956,7 +22568,7 @@ reenviado a sus amigos. - + [Notification] @@ -22315,7 +22927,7 @@ en la red (siempre informar de archivos disponibles) Nombre de archivo - + Download Descargar @@ -22394,7 +23006,7 @@ en la red (siempre informar de archivos disponibles) Abrir carpeta - + Create Collection... Crear colección... @@ -22414,7 +23026,7 @@ en la red (siempre informar de archivos disponibles) Descargar desde archivo de colección... - + Collection Colección @@ -22519,12 +23131,12 @@ en la red (siempre informar de archivos disponibles) Detalles del vecino - + Deny friend Bloquear amigo - + Chat Chat @@ -22534,7 +23146,7 @@ en la red (siempre informar de archivos disponibles) Iniciar chat - + Expand Expandir @@ -22804,13 +23416,13 @@ behind a firewall or a VPN. Descubrimiento activado (recomendado) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor ha sido configurado automáticamente por Retroshare. No deberías necesitar cambiar nada aquí. - + Discovery Off Descubrimiento inactivo @@ -23304,7 +23916,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Network Red @@ -23332,7 +23944,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Status Estado @@ -23429,7 +24041,7 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs. - + Service Address Dirección del servicio @@ -23464,12 +24076,12 @@ Si tienes problemas conectando a través de Tor, comprueba sus logs.Por favor, introduzca una dirección de servicio - + IP Range Rango de IPs - + Reported by DHT for IP masquerading Fue señalado por la DHT (tabla distribuida de hashes) para enmascaramiento de IP (IP masquerading) @@ -24145,7 +24757,7 @@ p, li { white-space: pre-wrap; } Falta el certificado PGP - + Wrong password ¡Contraseña errónea! @@ -24199,7 +24811,7 @@ Esta elección puede revertirse en la configuración. StatisticsWindow - + Add Friend Añadir a amigo @@ -24255,7 +24867,7 @@ Esta elección puede revertirse en la configuración. Matriz de permisos del servicio - + DHT DHT @@ -24795,7 +25407,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24809,13 +25421,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor está actualmente fuera de línea - + Tor is OK Tor está OK @@ -24824,6 +25435,31 @@ p, li { white-space: pre-wrap; } No tor configuration Sin configuración de Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25117,35 +25753,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Tiene %1 descargas completas + You have %1 completed transfers + - You have %1 completed download - Tiene %1 descarga completa + You have %1 completed transfer + - %1 completed downloads - %1 descargas completas + %1 completed transfers + - %1 completed download - %1 descarga completa + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Tiene %1 descargas completas + + + You have %1 completed download + Tiene %1 descarga completa + + + %1 completed downloads + %1 descargas completas + + + %1 completed download + %1 descarga completa TransfersDialog - + Downloads Descargas @@ -25156,7 +25803,7 @@ p, li { white-space: pre-wrap; } Enviando - + Name i.e: file name Nombre @@ -25367,7 +26014,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Transferencia de archivos</h1> <p>RetroShare tiene dos formas de transferir archivos: transferencias directas desde sus amigos, y transferencias distantes anónimas por túnel. Además, la transferencia de archivos es desde múltiples-fuentes y permite comportamiento de enjambre (puede ser fuente a la vez que descarga)</p> <p>Puede compartir archivos usando el <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> icono del lado izquierdo de la barra lateral. Estos archivos se listarán en la pestaña Mis Archivos. Puede decidir para cada grupo de amigos si pueden o no ver estos archivos en su pestaña de Archivos de Amigos</p> <p>La pestaña de búsqueda informa de archivos de las listas de archivos de sus amigos, y de archivos distantes que se pueden alcanzar de forma anónima usando la sistema de tunelización de múltiples-saltos.</p> - + Move in Queue... Mover en la lista de espera... @@ -25461,7 +26108,7 @@ p, li { white-space: pre-wrap; } Por favor, introduzca un nuevo - y válido - nombre de archivo - + Expand all Expandir todo @@ -25593,7 +26240,7 @@ p, li { white-space: pre-wrap; } - + Columns Columnas @@ -25604,7 +26251,7 @@ p, li { white-space: pre-wrap; } Transferencia de archivos - + Path Ruta @@ -25614,7 +26261,7 @@ p, li { white-space: pre-wrap; } Mostrar columna de ruta - + Could not delete preview file No se pudo borrar el archivo de vista previa @@ -25624,7 +26271,7 @@ p, li { white-space: pre-wrap; } ¿Intentarlo de nuevo? - + Create Collection... Crear colección... @@ -25639,7 +26286,7 @@ p, li { white-space: pre-wrap; } Ver colección... - + Collection Colección @@ -25885,7 +26532,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Vecino desconocido @@ -25981,7 +26628,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Tiene %1 nuevos mensajes @@ -26365,7 +27012,7 @@ p, li { white-space: pre-wrap; } Crear grupo - + Subscribe to Group Suscribirse al grupo @@ -26459,8 +27106,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Mostrar historial de ediciones @@ -26471,7 +27118,7 @@ p, li { white-space: pre-wrap; } - + Preview Vista previa @@ -26496,12 +27143,12 @@ p, li { white-space: pre-wrap; } Ocultar historial de ediciones - + Edit Page Editar página - + Create New Wiki Page Crear nueva página de la Wiki @@ -26521,7 +27168,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Crear nuevo grupo Wiki @@ -26563,7 +27210,7 @@ p, li { white-space: pre-wrap; } Intervalo de tiempo - + Create Account @@ -26573,12 +27220,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Refrescar @@ -26613,12 +27259,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26688,7 +27334,7 @@ p, li { white-space: pre-wrap; } Mostrando: - + Yourself Yo mismo @@ -26726,7 +27372,7 @@ p, li { white-space: pre-wrap; } Mensaje de Pulso para Wire - + RetroShare RetroShare @@ -26738,7 +27384,7 @@ p, li { white-space: pre-wrap; } - + The Wire Wire @@ -26746,7 +27392,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26827,8 +27473,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + Avatar Avatar @@ -26857,6 +27503,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26969,8 +27620,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Imágenes (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Imágenes (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_fi.ts b/retroshare-gui/src/lang/retroshare_fi.ts index 753dc6e63..4356c9860 100644 --- a/retroshare-gui/src/lang/retroshare_fi.ts +++ b/retroshare-gui/src/lang/retroshare_fi.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retrosharen versio @@ -79,7 +79,7 @@ Pidä hauskaa ;-) - + Only Hidden Node Ainoastaan piilotettu solmu @@ -128,12 +128,12 @@ Retroshare: tarkennettu haku - + Search Criteria Hakuehdot - + Add a further search criterion. Lisää hakuehto. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Albumi @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Lomake - - + + TextLabel Tekstiselite @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Työkalupalkki - + Icon Only Vain kuvakkeilla @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } Valitse työkalupainikkeiden tyyli. - + Icon Size = 8x8 Kuvakkeiden koko = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Kuvakkeiden koko = 128x128 - + Status Bar Tilarivi @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } Ota ilmaisinalueen työkaluvihje pois käytöstä - + Main page items: Pääsivun nimikkeet: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } Nimikeluettelo - + Icon Size = 32x32 Kuvakkeiden koko = 32x32 @@ -827,14 +827,23 @@ p, li { white-space: pre-wrap; } Vaihda avatar - + + TextLabel + + + + Your Avatar Picture Avatar-kuvasi - + + Browse... + + + Add Avatar - Lisää avatar + Lisää avatar @@ -842,25 +851,34 @@ p, li { white-space: pre-wrap; } Poista - + Set your Avatar picture Aseta avatarkuvasi - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Lataa avatar + Lataa avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Paina vaihtaaksesi avatarkuvasi @@ -868,7 +886,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s kt/s @@ -888,44 +906,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Retrosharen kaistanleveyden käyttö + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Näytä asetukset + TextLabel + + + + Reset Palauta asetukset - Receive Rate - Vastaanottonopeus + Vastaanottonopeus - Send Rate - Lähetysnopeus + Lähetysnopeus - + Always on Top Aina päällimmäisenä - Style - Tyyli + Tyyli - + Changes the transparency of the Bandwidth Graph Muuttaa siirtonopeuskuvaajan läpinäkyvyyttä - + 100 100 @@ -935,30 +974,27 @@ p, li { white-space: pre-wrap; } % näkyvä - Save - Tallenna + Tallenna - Cancel - Peru + Peru - + Since: Alkaen: - Hide Settings - Piilota asetukset + Piilota asetukset BandwidthStatsWidget - + Sum Summa @@ -980,7 +1016,7 @@ p, li { white-space: pre-wrap; } Lkm - + Average Keskiverto @@ -1114,7 +1150,7 @@ p, li { white-space: pre-wrap; } - + Comments Kommentit @@ -1192,6 +1228,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Pidän tästä + + + + 0 + 0 + + + + I dislike this + En pidä tästä + + + + Toggle Message Read Status + Vaihda viestin tila luetuksi tai päinvastoin + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopioi Retroshare-linkki + + + + + Expand + Laajenna + + + + Set as read and remove item + Merkitse luetuksi ja poista kohde + + + + Remove Item + Poista kohde + + + + Name + Nimi + + + + Comm value + + + + + Comment + Kommentti + + + + Comments + Kommentit + + + + Hide + Piilota + + BwCtrlWindow @@ -1327,6 +1442,16 @@ p, li { white-space: pre-wrap; } Log scale Lokin asteikko + + + Default + Oletus + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Pidän tästä + + + + 0 + 0 + + + + I dislike this + En pidä tästä + + + + Toggle Message Read Status + Vaihda viestin tila luetuksi tai päinvastoin + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopioi Retroshare-linkki + + + + + Expand + Laajenna + + + + Set as read and remove item + Merkitse luetuksi ja poista kohde + + + + Remove Item + Poista kohde + + + + Name + Nimi + + + + Comm value + + + + + Comment + Kommentti + + + + Comments + Kommentit + + + + Hide + Piilota + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to Keskustelut - You have %1 new messages - Sinulle on uusia viestejä %1 kpl + Sinulle on uusia viestejä %1 kpl + + + You have %1 new message + Sinulle on %1 uusi viesti + + + %1 new messages + %1 kpl uusia viestejä + + + %1 new message + %1 uusi viesti + + + + You have %1 mentions + - You have %1 new message - Sinulle on %1 uusi viesti + You have %1 mention + - %1 new messages - %1 kpl uusia viestejä + %1 mentions + - %1 new message - %1 uusi viesti + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Poista kaikki - - - mention(s) - - ChatLobbyWidget @@ -2119,13 +2334,11 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. Muunnelma: - Group chat - Ryhmäkeskustelu + Ryhmäkeskustelu - - + Private chat Yksityinen keskustelu @@ -2190,17 +2403,16 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. /me on lähettämässä viestiä /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Tässä välilehdessä voit määrittää, kuinka monta chat-viestiä Retroshare pitää tallennettuna kiintolevylle ja kuinka paljon edellisestä keskustelusta näytetään eri keskustelutoiminnoissa. Säilytyksen enimmäisaika mahdollistaa vanhojen viestien hävittämisen ja estää keskusteluhistorian täyttymisen (esim. keskusteluaulat ja etäiset keskustelut).</p></body></html> - Chatlobbies - Keskusteluaulat + Keskusteluaulat - + Enabled: Käytössä: @@ -2221,11 +2433,12 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. + Chat rooms Keskusteluhuoneet - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2286,11 +2499,17 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. + Broadcast Kuulutus - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Tallennettavien viestien lkm (0 = rajoittamaton): @@ -2437,8 +2656,23 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. Yksityinen keskustelu - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2607,7 +2841,7 @@ Kaksoisnapauta huonetta siirtyäksesi keskustelemaan. - + is typing... kirjoittaa... @@ -2626,12 +2860,12 @@ after HTML conversion. iso HTML-muuntamisen jälkeen. - + Choose your font. Valitse kirjasin. - + Do you really want to physically delete the history? Haluatko todella tuhota historian pysyvästi? @@ -2703,7 +2937,7 @@ iso HTML-muuntamisen jälkeen. Älä lopeta värittämistä, kun X kohdetta löydetty (vaatii konetehoa) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Hae edellinen </b><br/><i>Ctrl+Shift+G</i> @@ -2743,12 +2977,12 @@ iso HTML-muuntamisen jälkeen. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Merkitse tämä valittu teksti</b><br><i>Ctrl+M</i> - + Person id: Henkilön tunniste: @@ -2765,7 +2999,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Allekirjoittamaton - + items found. Kohteita löytyi. @@ -2785,7 +3019,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Kirjoita viesti tähän - + Don't stop to color after Älä lopeta värittämistä jälkeen @@ -2943,12 +3177,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. ConfCertDialog - + Details Tiedot - + Local Address Paikallinen osoite @@ -2959,12 +3193,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Ulkoinen osoite - + Node info: Solmun tiedot: - + Current address: Nykyinen osoite: @@ -2980,31 +3214,36 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Portti - + Include signatures Sisällytä allekirjoitukset - + RetroShare Retroshare - + - + Error : cannot get peer details. Virhe: vertaisen yksityiskohtia ei saatu. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3020,22 +3259,27 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Salaus - + Not connected Ei yhteyttä - + Retroshare node details Retroshare solmun tiedot - + Node name : Solmun nimi: @@ -3070,13 +3314,18 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Tilaviesti: - + + Connectivity + + + + List of known addresses: Tunnetut osoitteet: - - + + Retroshare Certificate Retroshare varmenne @@ -3091,7 +3340,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. - + Hidden Address Piilotettu osoite @@ -3102,11 +3351,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.ei mitään + <p>This certificate contains: - <p>Tämä varmenne sisältää: + <p>Tämä varmenne sisältää: - + <li>a <b>node ID</b> and <b>name</b> <li> <b>solmun tunniste</b> ja <b>nimi</b> @@ -3119,12 +3369,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan. <b>IP-osoite</b> ja <b>ja</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Voit käyttää tätä varmennetta luodaksesi uusia ystäviä. Lähetä se sähköpostitse tai anna se tavatessanne.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Tämä on solmun <span style=" font-weight:600;">OpenSSL</span> -varmenteen tunniste, joka on allekirjoitettu ylläolevalla <span style=" font-weight:600;">PGP</span> -avaimella. </p></body></html> @@ -3134,7 +3384,7 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.<html><head/><body><p>Tätä salaus-metodia käyttää <span style=" font-weight:600;">OpenSSL</span>. Yhteys ystäväsolmuihin</p><p>on aina vahvasti salattu ja jos DHE on läsnä yhteys edelleen käyttää</p><p>&quot;täydellistä forward secrecy-ominaisuutta&quot; (salausavaimen murtaminen ei johda aiemmin salattujen viestien tietoturvan vaarantumiseen).</p></body></html> - + with kanssa @@ -3340,12 +3590,12 @@ Kaksoisnapsauta sitä lisätäksesi hänen nimensä tekstinkirjoittajaan.Tietoja pyynnöstä - + Peer details Vertaisen tiedot - + Name: Nimi: @@ -3364,12 +3614,12 @@ resources. resursseja. - + Location: Sijainti: - + Options Asetukset @@ -3406,12 +3656,12 @@ resursseja. Liitä varmenne - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Tämä laatikko vaatii sinun ystäväsi Retroshare-varmenteen. VAROITUS: se on erilainen, kuin ystäväsi profiiliavain. Älä liitä ystäväsi profiiliavainta tähän (edes osaa siitä). Se ei tule toimimaan.</p></body></html> - + Add friend to group: Lisää ystävä ryhmään: @@ -3421,7 +3671,7 @@ resursseja. Varmenna ystävä (allekirjoita PGP-avain) - + Please paste below your friend's Retroshare ID @@ -3446,7 +3696,7 @@ resursseja. - + Add as friend to connect with Lisää ystäväksi, johon otat yhteyden @@ -3455,7 +3705,7 @@ resursseja. Paina Valmis-painiketta hyväksyäksesi ystäväpyynnön - + Sorry, some error appeared Valitettavasti on tapahtunut jokin virhe @@ -3475,32 +3725,32 @@ resursseja. Tietoja ystävästäsi: - + Key validity: Avaimen kelpoisuus: - + Profile ID: - + Signers Allekirjoittajat - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Allekirjoitukset alla kryptograafisesti todistavat, että luettelon avaimien omistajat tunnistavat nykyisen PGP-avaimen aidoksi.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Tämä vertainen on jo ystäväluettelossasi. Hänen lisäämisensä saattaa ainoastaan määrittää uuden IP-osoitteen. - + To accept the Friend Request, click the Accept button. @@ -3546,7 +3796,7 @@ resursseja. - + Certificate Load Failed Varmenteen lataus epäonnistui @@ -3583,12 +3833,12 @@ resursseja. Varmenne näyttää olevan kelvollinen - + Not a valid Retroshare certificate! Ei kelvollinen Retroshare-varmenne! - + RetroShare Invitation Retroshare-kutsu @@ -3610,12 +3860,12 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Tämä on oma varmenteesi! Et haluaisi olla oma ystäväsi. Ethän? - + @@ -3663,7 +3913,37 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Sinulle on ystäväpyyntö, lähettäjä - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3751,12 +4031,12 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Käytä suorana lähteenä, kun saatavilla - + IP-Addr: IP-osoite: - + IP-Address IP-osoite: @@ -3822,7 +4102,7 @@ Varoitus: Tiedostonsiirto-asetuksissa Salli suora lataus on asetettu Ei.Lisää avain avainnippuun - + This key is already in your keyring Tämä avain on jo avainnipussasi @@ -3883,12 +4163,12 @@ vaikkette ystävystyisikään. <p>Varmenteessa ei ole IP-osoitetta. Etsintä ja DHT hakevat osoitteen. Vertainen aiheuttaa tietoturvavaroituksen Uutissyöte-välilehdessä, koska olet määrittänyt sallittujen luettelossa olemisen pakolliseksi. Voit sallia vertaisen IP-osoitteen Uutissyöte-välilehdeltä.</p> - + [Unknown] [Tuntematon] - + Added with certificate from %1 Varmenne lisätty %1 @@ -3975,7 +4255,12 @@ vaikkette ystävystyisikään. UDP:n tulos - + + Status + Tila + + + <!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; } @@ -4405,7 +4690,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4557,7 +4842,7 @@ p, li { white-space: pre-wrap; } Piirien rajoituksia ei valittuna - + [Unknown] [Tuntematon] @@ -4572,7 +4857,7 @@ p, li { white-space: pre-wrap; } Poista - + Search Haku @@ -4592,7 +4877,7 @@ p, li { white-space: pre-wrap; } Tunnettujen solmujen allekirjoittama - + Edit Circle Muokkaa piiriä @@ -4612,12 +4897,12 @@ p, li { white-space: pre-wrap; } Nimetön tunniste - + Circle name Piiri nimi - + Update Päivitä @@ -4643,7 +4928,7 @@ p, li { white-space: pre-wrap; } PGP:n linkitetty tunniste - + Add Member Lisää jäsen @@ -4787,7 +5072,7 @@ p, li { white-space: pre-wrap; } - + Attachments Liitetiedostot @@ -4833,7 +5118,7 @@ p, li { white-space: pre-wrap; } Vedä ja pudota tiedostoja hakutuloksista - + Paste RetroShare Links Liitä Retroshare-linkit @@ -4843,7 +5128,7 @@ p, li { white-space: pre-wrap; } Liitä Retroshare-linkki - + Drop file error. Virhe pudotettaessa tiedostoa. @@ -4870,17 +5155,41 @@ p, li { white-space: pre-wrap; } - + RetroShare Retroshare - - File already Added and Hashed - Tiedosto on jo lisätty ja tiivistetty (hash) + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Tiedosto on jo lisätty ja tiivistetty (hash) + + + Please add a Subject Ole hyvä ja lisää aihe @@ -4911,12 +5220,12 @@ p, li { white-space: pre-wrap; } Haluatko todella luoda %1 viestiä? - + You are about to add files you're not actually sharing. Do you still want this to happen? Olet aikeissa lisätä tiedostoja, joita et todellisuudessa jaa. Haluatko silti tehdä tämän? - + Edit Channel Post Muokkaa kanavakirjoitusta @@ -4936,7 +5245,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Olet aikeissa lähettää kanavalle tiedostoja, jota et omista. @@ -5028,7 +5337,7 @@ p, li { white-space: pre-wrap; } - + No Forum Ei foorumia @@ -5488,7 +5797,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen DHTGraphSource - + users käyttäjät @@ -6495,7 +6804,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen FlatStyle_RDM - + Friends Directories Ystävien hakemistot @@ -7001,7 +7310,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Hae ystäviä - + Mark all Merkitse kaikki @@ -7015,7 +7324,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään FriendsDialog - + Edit status message Muokkaa tilaviestiä @@ -7119,7 +7428,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Retrosharen kuulutus: viestit lähetetään kaikille linjoilla oleville ystäville. - + Network Verkko @@ -7184,7 +7493,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Solmukenttä on pakollinen ja vähintään 3 merkkiä - + Failed to generate your new certificate, maybe PGP password is wrong! Uuden varmenteesi luonti epäonnistui, ehkä PGP-salasanasi oli väärin! @@ -7227,7 +7536,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Käytä olemassaolevaa profiilia - + Node name Solmun nimi @@ -7494,12 +7803,12 @@ ja käyttää tuo-painiketta sen lataamiseen - + Profile generation failure Profiilin luonti epäonnistui - + Missing PGP certificate Puuttuva PGP-varmenne @@ -7918,7 +8227,7 @@ p, li { white-space: pre-wrap; } Reitittimen tilastot - + GroupBox Ryhmälaatikko @@ -7983,7 +8292,7 @@ p, li { white-space: pre-wrap; } Haarautumiskerroin - + Details Tiedot @@ -8006,7 +8315,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Hallitut avaimet @@ -8215,7 +8524,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Otsikko @@ -8225,13 +8534,30 @@ p, li { white-space: pre-wrap; } Hae otsikkoa - - + + + + Description Kuvaus - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Hae kuvausta @@ -8241,42 +8567,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Laskeva järjestys + Laskeva järjestys - Sort Ascending Order - Nouseva järjestys + Nouseva järjestys - Sort by Name - Järjestä nimen mukaan + Järjestä nimen mukaan - Sort by Popularity - Järjestä suosion mukaan + Järjestä suosion mukaan - Sort by Last Post - Järjestä viimeisimmän viestin mukaan + Järjestä viimeisimmän viestin mukaan - Sort by Number of Posts - Järjestä viestien määrän mukaan + Järjestä viestien määrän mukaan - Sort by Unread - Järjestä lukemattomien mukaan + Järjestä lukemattomien mukaan - + You are admin (modify names and description using Edit menu) Olet ylläpitäjä (muokkaa nimiä ja kuvaksia käyttäen Muokkaa-valikkoa) @@ -8291,40 +8610,35 @@ p, li { white-space: pre-wrap; } Tunniste - - + + Last Post Viimeisin viesti - + + Name Nimi - - Unread - - - - + Popularity Suosio - - + + Never Ei koskaan - Display - Näytä + Näytä - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8473,7 +8787,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanavat @@ -8498,12 +8812,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kanavat</h1> <p>Kanavat sallivat sinun lähettää dataa (esim. elokuvia, musiikkia) , jotka leviävät verkostossa.</p> <p>Voit nähdä mitä kanavia ystäväsi tilaavat, ja automaattisesti edelleenlähettää tilatut kanavat ystävillesi. Tämä edistää verkoston hyviä kanavia.</p> <p>Ainoastaan kanavan luoja pystyy lähettämään kyseiselle kanavalle. Muut vertaiset verkostossa pystyvät vain lukemaan sitä, ellei kanava ole yksityinen. Kaikesta huolimatta voit jakaa lähetys- tai luku-oikeuksia ystäviesi Retroshare-solmuille.</p> <p>Kanavista voidaan tehdä nimettömiä, tai niihin voidaan liittää Retroshare-henkilöllisyys, että lukijat voivat yhteyden sinuun tarvittaessa. Salli "Salli kommentit", jos haluat käyttäjien kommentoivan viestejäsi.</p> <p>Kanavan viestit säilyvät %1 päivää, and pidetään ajan tasalla %2 päivän ajan, ellet sinä muuta tätä.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Tilatut kanavat @@ -9028,7 +9342,7 @@ p, li { white-space: pre-wrap; } - + Add new post Lisää uusi kirjoitus @@ -9128,12 +9442,12 @@ p, li { white-space: pre-wrap; } - + Files Tiedostot - + Comments Kommentit @@ -9144,18 +9458,18 @@ p, li { white-space: pre-wrap; } - + Feeds Syötteet - - + + Click to switch to list view - + Show unread posts only @@ -9165,12 +9479,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9230,7 +9544,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9245,12 +9559,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9326,23 +9640,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Tilattu - - Subscribe Aloita tilaus - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Ei kanavaa valittuna @@ -9364,11 +9691,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanavakirjoitus - - - new message(s) - - GxsCircleItem @@ -9902,7 +10224,7 @@ kuin voit kommentoida Aloita uusi viestiketju valitussa foorumissa - + Search forums Hae foorumeista @@ -9911,12 +10233,12 @@ kuin voit kommentoida Viimeisin viesti - + New Thread Uusi viestiketju - + Threaded View Ketjunäkymä @@ -9926,19 +10248,19 @@ kuin voit kommentoida Tasanäkymä - - + + Title Otsikko - - + + Date Päiväys - + Author Kirjoittaja @@ -9953,7 +10275,17 @@ kuin voit kommentoida Ladataan - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10014,23 +10346,23 @@ kuin voit kommentoida <p>Foorumin tilaaminen kerää kaikki saatavilla olevat viestit tilaajaystäviltäsi, ja tekee foorumista näkyvän kaikille muille ystävillesi.</p><p>Myöhemmin voit peruuttaa tilauksen foorumin kontekstivalikosta vasemmalla.</p> - + No name Ei nimeä - - + + Reply Vastaa - + <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> - + Loading... @@ -10068,12 +10400,12 @@ kuin voit kommentoida Merkitse lukemattomaksi - + Copy RetroShare Link Kopioi Retroshare-linkki - + Hide Piilota @@ -10086,7 +10418,7 @@ kuin voit kommentoida [Pannassa] - + [unknown] [tuntematon] @@ -10116,8 +10448,8 @@ kuin voit kommentoida Vain silmillesi - - + + Distribution @@ -10220,7 +10552,7 @@ kuin voit kommentoida Alkuperäinen viesti - + New thread Uusi viestiketju @@ -10229,7 +10561,7 @@ kuin voit kommentoida Lue tilaviesti - + Edit Muokkaa @@ -10285,7 +10617,7 @@ kuin voit kommentoida Näytä kirjoittaja Ihmiset-välilehdellä - + Author's reputation Kirjoittajan maine @@ -10305,7 +10637,7 @@ kuin voit kommentoida - + <b>Loading...<b> @@ -10345,6 +10677,11 @@ kuin voit kommentoida Storage + + + Last seen at friends: + + Moderators @@ -10438,7 +10775,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. %1, %2 kirjoitti: - + Forum name Foorumin nimi @@ -10470,11 +10807,6 @@ estää viestin lähettämisen eteenpäin ystävillesi. Forum Post Foorumiviesti - - - new message(s) - - GxsForumsDialog @@ -10923,7 +11255,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Tulostuksen esikatselu - + Unsubscribe Lopeta tilaus @@ -10938,7 +11270,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Avaa uuteen välilehteen - + Remove this search @@ -10948,12 +11280,12 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + Request data - + Show Details Näytä tiedot @@ -11020,7 +11352,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + Search for @@ -11029,7 +11361,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Jaa julkaisuoikeudet - + Copy RetroShare Link Kopioi Retroshare-linkki @@ -11044,7 +11376,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Merkitse kaikki lukemattomiksi - + AUTHD VAHVST @@ -11653,7 +11985,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11688,6 +12020,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11699,7 +12048,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11779,27 +12128,32 @@ p, li { white-space: pre-wrap; } Lomake - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11821,6 +12175,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11829,7 +12184,7 @@ p, li { white-space: pre-wrap; } Teksti alapuolella on Retroshare-varmenteesi. Lähetä se ystävillesi - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11846,12 +12201,12 @@ yksityinen ja turvallinen hajautettu viestintäalusta. Tarvitsetko apua Retrosharen kanssa? - + Open Web Help Avaa verkkotuki (englanniksi) - + Copy your Cert to Clipboard Kopioi varmenteesi leikepöydälle @@ -11900,7 +12255,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11909,7 +12264,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12202,14 +12557,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Kaikki - + Reputation Maine @@ -12219,12 +12574,12 @@ p, li { white-space: pre-wrap; } Haku - + Anonymous Id Nimetön tunniste - + Create new Identity Luo uusi henkilöllisyys @@ -12368,7 +12723,7 @@ p, li { white-space: pre-wrap; } Henkilöllisyystunniste - + Send message Lähetä viesti @@ -12460,7 +12815,7 @@ p, li { white-space: pre-wrap; } Yhteensä: - + Anonymous Nimetön @@ -12475,24 +12830,24 @@ p, li { white-space: pre-wrap; } Hae tunnistetta - + This identity is owned by you Tämä henkilöllisyys on sinun omistamasi - - + + My own identities Minun henkilöllisyyteni - - + + My contacts - + Show Items Näytä kohteet @@ -12507,7 +12862,7 @@ p, li { white-space: pre-wrap; } Linkitetty solmuuni - + Other circles Muut piirit @@ -12566,13 +12921,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). tilattu (Vastaanota/lähetä jäsenyyspyyntöjä toisilta ja kutsuluettelosta) + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). tilauksen peruuttaneet (Vastaanota ainoastaan kutsuluettelo). - + Your status: Sinun tilasi: @@ -12632,7 +12992,7 @@ p, li { white-space: pre-wrap; } Jäsen - + Edit Circle Muokkaa piiriä @@ -12680,7 +13040,7 @@ p, li { white-space: pre-wrap; } Myönnä jäsenyys - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12692,12 +13052,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + [Unknown node] [Tuntematon solmu] - + Unverified signature from node Vahvistamaton allekirjoitus solmulta @@ -12709,12 +13069,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tarkistamaton allekirjoitus - + [unverified] [vahvistamaton] - + Identity owned by you, linked to your Retroshare node Sinun omistama henkilöllisyys linkitettynä Retroshare-solmuusi @@ -12838,12 +13198,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Haluatko todella lähettää kutsun varmenteellasi? - + Banned Pannassa - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> @@ -12852,7 +13212,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tuntematon tunniste: - + positive positiviinen @@ -13037,8 +13397,8 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - - + + People Ihmiset @@ -13049,7 +13409,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinun avatar - + Linked to neighbor nodes Linkitetty naapurisolmuihin @@ -13059,7 +13419,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Linkitetty etäisiin solmuihin - + Linked to a friend Retroshare node Linkitetty ystävä Retroshare-solmuun @@ -13119,7 +13479,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Omistama - + Node name: Solmun nimi: @@ -13129,7 +13489,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Solmun tunniste : - + Really delete? Tuhotaanko? @@ -13167,7 +13527,22 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Nimimerkki - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Uusi henkilöllisyys @@ -13184,14 +13559,14 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + N/A Ei sovellu - + Edit identity Muokkaa henkilöllisyyttä @@ -13202,24 +13577,27 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Päivitä - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13238,17 +13616,27 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Virhe haettaessa avainta! - + Error KeyID invalid Virhe: viallinen avaimen tunniste - + Unknown GpgId Tuntematon GPG-tunniste @@ -13258,7 +13646,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tuntematon oikea nimi - + Create New Identity Luo uusi henkilöllisyys @@ -13268,7 +13656,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Tyyppi - + + Choose image... + + + + @@ -13308,12 +13701,11 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinun avatar - Set Avatar - Aseta Avatar + Aseta Avatar - + Linked to your profile Linkitetty profiiliisi @@ -13323,7 +13715,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Sinulla voi olla yksi tai useampi henkilöllisyys. Niitä käytetään usein kirjoitettaessa keskusteluhuoneisiin, foorumeille ja kanavakommentteihin. Ne toimivat kohteena etäiselle keskustelulle ja Retrosharen etäiselle postijärjestelmälle. - + The nickname is too short. Please input at least %1 characters. Nimimerkki on liian lyhyt. Syötä vähintään %1 merkkiä. @@ -13432,8 +13824,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. + Quote + Lainaa + + Send - Lähetä + Lähetä @@ -13591,7 +13987,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Options Asetukset @@ -13623,12 +14019,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Ohjattu nopea käynnistys - + RetroShare %1 a secure decentralized communication platform Retroshare %1 turvallinen hajautettu viestintäalusta - + Unfinished Kesken @@ -13761,7 +14157,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Näytä - + Make sure this link has not been forged to drag you to a malicious website. Varmista, että tämä linkki ei ole huijaus, joka johtaa haitalliselle sivustolle. @@ -13806,7 +14202,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Palveluiden käyttöoikeudet - + Statistics Tilastot @@ -13835,7 +14231,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. MessageComposer - + Compose Kirjoita viesti @@ -13937,7 +14333,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Tags Merkkaukset @@ -14032,12 +14428,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. Lisää lainauslohko (blockquote) - + Send To: Lähetä: - + &Left Tas&aa vasemmalle @@ -14071,7 +14467,7 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hei,<br>suosittelen ystävääni; voit luottaa häneen, kuten luotat minuun.<br> @@ -14097,12 +14493,12 @@ Näitä henkilöllisyyksien tuki lakkaa pian. - + Save Message Tallenna viesti - + Message has not been Sent. Do you want to save message to draft box? Viestiä ei ole lähetetty. @@ -14114,7 +14510,7 @@ Haluatko tallentaa viestin luonnoslaatikkoon? Liitä Retroshare-linkki - + Add to "To" Lisää vastaanottajiin @@ -14369,7 +14765,7 @@ Haluatko tallentaa viestin? Lisää ylimääräinen tiedosto - + Hi,<br>I want to be friends with you on RetroShare.<br> Hei,<br>haluan olla ystäväsi Retrosharessa.<br> @@ -14378,12 +14774,27 @@ Haluatko tallentaa viestin? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Sinulle on ystäväkutsu - + Respond now: Vastaa nyt: @@ -14399,11 +14810,12 @@ Haluatko tallentaa viestin? Lähettäjä: + Friend Nodes - Ystäväsolmut + Ystäväsolmut - + Bullet list (disc) @@ -14443,13 +14855,13 @@ Haluatko tallentaa viestin? - - + + Thanks, <br> Kiitos, <br> - + Distant identity: Etäinen henkilöllisyys: @@ -14588,8 +15000,23 @@ Haluatko tallentaa viestin? Viesti - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14601,12 +15028,12 @@ Haluatko tallentaa viestin? Suositellut tiedostot - + Download all Recommended Files Lataa kaikki suositellut tiedostot - + Subject: Aihe: @@ -14681,12 +15108,18 @@ Haluatko tallentaa viestin? Lähetä kutsu - + + Message Size: + + + + File Name Tiedoston nimi - + + Size Koko @@ -14747,10 +15180,25 @@ Haluatko tallentaa viestin? Lataa - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Lähetä kutsu? @@ -14761,12 +15209,12 @@ Haluatko tallentaa viestin? - + Download all Lataa kaikki - + Print Document Tulosta asiakirja @@ -14781,7 +15229,7 @@ Haluatko tallentaa viestin? HTML-tiedostot (*.htm *.html);;Kaikki tiedostot (*) - + Load images always for this message Lataa kuvat aina tämän viestin osalta @@ -14922,7 +15370,7 @@ Haluatko tallentaa viestin? MessagesDialog - + New Message Uusi viesti @@ -14978,14 +15426,14 @@ Haluatko tallentaa viestin? - + Tags Merkkaukset - + Inbox Saapuneet @@ -15080,7 +15528,7 @@ Haluatko tallentaa viestin? Välitä viesti - + Subject Aihe @@ -15192,7 +15640,7 @@ Haluatko tallentaa viestin? - + Open in a new window Avaa uudessa ikkunassa @@ -15277,7 +15725,7 @@ Haluatko tallentaa viestin? - + Drafts Luonnokset @@ -15406,7 +15854,7 @@ Haluatko tallentaa viestin? Vastaa viestiin - + Delete Message Tuhoa viesti @@ -15417,7 +15865,7 @@ Haluatko tallentaa viestin? - + Expand Laajenna @@ -15427,7 +15875,7 @@ Haluatko tallentaa viestin? Poista kohde - + from alkaen @@ -15436,6 +15884,11 @@ Haluatko tallentaa viestin? Reply to invite Vastaa kutsuun + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15758,7 +16211,7 @@ Raportoitu virhe: - + Groups Ryhmät @@ -15788,19 +16241,19 @@ Raportoitu virhe: tuo ystäväluettelo mukaan lukien ryhmät - - + + Search Haku - + ID Tunniste - + Search ID @@ -15810,7 +16263,7 @@ Raportoitu virhe: - + Show Items Näytä kohteet @@ -16014,19 +16467,19 @@ ainakin yksi vertainen jäi lisäämättä ryhmään - + Error Virhe - + File is not writeable! Tiedostoon ei voi kirjoittaa! - + File is not readable! Tiedostoa ei voi lukea! @@ -16064,9 +16517,13 @@ ainakin yksi vertainen jäi lisäämättä ryhmään NewsFeed - Log entries - Lokimerkinnät + Lokimerkinnät + + + + Activity Stream + @@ -16083,7 +16540,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään This is a test. - + Newest on top Uusin ylimmäisenä @@ -16094,20 +16551,43 @@ ainakin yksi vertainen jäi lisäämättä ryhmään + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Uutissyöte</h1> <p>Lokisyöte näyttää uusimmat tapahtumat verkostossasi vastaanottohetken mukaan järjestettynä. Näin saat yhteenvedon ystäviesi toiminnasta. Voit määrittää näytettävät tapahtumat <b>Asetuksista</b>. </p> <p>Näytettäviä tapahtumia: <ul> <li>Yhteydenottoyritykset (hyödyllisiä ystävien hankkimiseen ja yhteydenottojen hallintaan)</li> <li>Viestit kanaville ja foorumeille</li> <li>Uudet kanavat ja foorumit, jotka ovat tilattavissasi</li> <li>Yksityisviestit ystäviltäsi</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Uutissyöte</h1> <p>Lokisyöte näyttää uusimmat tapahtumat verkostossasi vastaanottohetken mukaan järjestettynä. Näin saat yhteenvedon ystäviesi toiminnasta. Voit määrittää näytettävät tapahtumat <b>Asetuksista</b>. </p> <p>Näytettäviä tapahtumia: <ul> <li>Yhteydenottoyritykset (hyödyllisiä ystävien hankkimiseen ja yhteydenottojen hallintaan)</li> <li>Viestit kanaville ja foorumeille</li> <li>Uudet kanavat ja foorumit, jotka ovat tilattavissasi</li> <li>Yksityisviestit ystäviltäsi</li> </ul> </p> + + + Log + Loki - Log - Loki + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16144,22 +16624,22 @@ ainakin yksi vertainen jäi lisäämättä ryhmään - + Test Test - + Chat Room Keskusteluhuone - + Systray Icon Ilmaisinalueen kuvake - + Message Viesti @@ -16184,12 +16664,11 @@ ainakin yksi vertainen jäi lisäämättä ryhmään IP-tietoturva - Log - Loki + Loki - + Friend Connected Ystävä linjoilla @@ -16203,7 +16682,12 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Linkit - + + Activity + + + + Mails Postit @@ -16240,7 +16724,12 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Ryhmäkeskustelu - + + Toaster position + + + + Chat rooms Keskusteluhuoneet @@ -16253,22 +16742,22 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Huomioi kirjainkoko - + Position Sijainti - + X Margin X-reuna - + Y Margin Y-reuna - + Systray message Ilmaisinalueen viesti @@ -16318,7 +16807,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Huomauta - + Disable All Toasters Estä kaikki ponnahdusviestit @@ -16332,7 +16821,7 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Syöte - + Systray Ilmaisinalue @@ -16478,17 +16967,16 @@ ainakin yksi vertainen jäi lisäämättä ryhmään PGPKeyDialog - Dialog - Ikkuna + Ikkuna - + Profile info Profiilin tiedot - + Name : Nimi: @@ -16543,22 +17031,21 @@ ainakin yksi vertainen jäi lisäämättä ryhmään Äärimmäinen - + This profile has signed your own profile key Tämä profiili on allekirjoitettu sinun profiiliavaimellasi - Key signatures : - Avain allekirjoitukset: + Avain allekirjoitukset: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Allekirjoitukset alla kryptograafisesti todistavat, että luettelon avaimien omistajat tunnistavat nykyisen PGP-avaimen aidoksi.</span></p></body></html> - + <!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; } @@ -16576,7 +17063,7 @@ p, li { white-space: pre-wrap; } Allekirjoita tämä avain - + PGP key PGP-avain @@ -16586,22 +17073,20 @@ p, li { white-space: pre-wrap; } Nämä vaihtoehdot koskevat kaikkia solmuja profiilissa: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Se auttaa heitä päättämään salliako yhteydet siitä avaimesta perustuen sinun omaan luottamukseen. Avaimen allekirjoittaminen on täysin vapaaehtoista, eikä sitä voi perua, joten tee niin harkiten.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Ystäväsi avaimen allekirjoittamisella ilmaiset luottamuksesi tähän ystävään muille ystävillesi. Se auttaa heitä päättämään salliako yhteydet siitä avaimesta perustuen sinun omaan luottamukseen. Avaimen allekirjoittaminen on täysin vapaaehtoista, eikä sitä voi perua, joten tee niin harkiten.</span></p></body></html> - + Keysigning: - Sign PGP key - Allekirjoita PGP-avain + Allekirjoita PGP-avain - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Napsauta tästä, jos haluat kieltäytyä yhteyksistä tämän avaimen todentamiin solmuihin.</p></body></html> @@ -16621,7 +17106,7 @@ p, li { white-space: pre-wrap; } Hyväksy yhteydet - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16691,28 +17176,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare Retroshare - - + + Error : cannot get peer details. Virhe haettaessa vertaisen tietoja. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Retroshare ei tue antamaasi avainalgoritmia (Tällä hetkellä vain RSA-avaimet käyvät) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16726,7 +17211,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Luottamustaso ilmaisee omaa luottamustasi tähän avaimeen. Ohjelma ei käytä sitä eikä sitä jaeta, mutta se voi olla hyödyllinen hyvien sekä huonojen avainten muistamiseen. @@ -16771,27 +17256,47 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Et hyväksy yhteyksiä tämän avaimen allekirjoittamilta Retroshare-solmuilta. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Virhe allekirjoitettaessa - - Maybe password is wrong - Salasana saattaa olla väärin + + Check the password! + - + Maybe password is wrong + Salasana saattaa olla väärin + + + You haven't set a trust level for this key. Et ole asettanut luottamustasoa tälle avaimelle. - + + Retroshare profile Retroshare-profiili - + This is your own PGP key, and it is signed by : Tämä on sinun oma PGP-avain ja sen on allekirjoittanut: @@ -16970,8 +17475,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E PeopleDialog - - + People Ihmiset @@ -16988,7 +17492,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Sisäinen - + Chat with this person Keskustele henkilön kanssa @@ -17139,7 +17643,7 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Valokuva - + TextLabel TekstiMerkki @@ -17183,8 +17687,8 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E - <N> Comments >> - + Comments + Kommentit @@ -17219,6 +17723,11 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Write a comment... Kirjoita kommentti... + + + Album + Albumi + PhotoItem @@ -17228,12 +17737,12 @@ Varoitus: Tiedostonsiirto-asetuksissa estit Salli suora latauksen valitsemalla E Lomake - + TextLabel TekstiMerkki - + <!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; } @@ -17329,7 +17838,7 @@ p, li { white-space: pre-wrap; } Näytä kuva - + PhotoShare PhotoShare @@ -17370,7 +17879,7 @@ yrität muokata sitä! - + Stop Pysäytä @@ -17598,12 +18107,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Hyväksy kaikki lisäosat - + Plugin look-up directories Lisäosien hakemistot @@ -17658,7 +18167,7 @@ tiivisteen tarkistaminen suojelee sinua vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Plugins Lisäosat @@ -18056,7 +18565,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Linkit - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18227,13 +18736,13 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Sivusto - - + + Comments Kommentit - + Copy RetroShare Link Kopioi Retroshare-linkki @@ -18243,7 +18752,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Näytä kirjoittaja Ihmiset-välilehdellä - + Comment Kommentti @@ -18264,12 +18773,12 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Hide Piilota - + Vote up Äänestä ylös @@ -18283,7 +18792,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. \/ - + Set as read and remove item Merkitse luetuksi ja poista kohde @@ -18344,7 +18853,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + Loading Ladataan @@ -18434,13 +18943,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18450,60 +18953,50 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. Ylläpitäjä: - - - + + + unknown tuntematon - + Distribution: Jakelu: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Viestejä @@ -18514,7 +19007,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18583,7 +19076,12 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + + Empty + Tyhjä + + + Copy RetroShare Link Kopioi Retroshare-linkki @@ -18618,7 +19116,7 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - + [No name] @@ -18746,8 +19244,18 @@ vahingoittamistarkoituksessa tehdyiltä lisäosilta. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19019,9 +19527,8 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseAddDialog - Post From: - Lähettäjä + Lähettäjä Account 1 @@ -19036,7 +19543,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Tili 3 - + Add to Pulse Lisää pulssiin @@ -19059,17 +19566,32 @@ ja käyttää "Tuo"-painiketta ladataksesi sen URL - + GroupLabel - + IDLabel - + + From: + Lähettäjä: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19094,10 +19616,20 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Kielteinen - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19107,14 +19639,53 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + + Post + + + + Cancel Peru - Post Pulse to Wire - Lähetä pulssi lennättimeen + Lähetä pulssi lennättimeen + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19140,10 +19711,18 @@ ja käyttää "Tuo"-painiketta ladataksesi sen Lomake - - - - + + + + + Click to view picture + + + + + + + Image Kuva @@ -19151,44 +19730,44 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19198,17 +19777,17 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19218,7 +19797,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19226,7 +19805,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen PulseTopLevel - + retweeted @@ -19241,7 +19820,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + follow Parent Group @@ -19251,7 +19830,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19276,7 +19855,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19312,29 +19891,29 @@ ja käyttää "Tuo"-painiketta ladataksesi sen - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19412,7 +19991,7 @@ ja käyttää "Tuo"-painiketta ladataksesi sen QObject - + Confirmation Vahvistus @@ -19654,7 +20233,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tulos - + Unable to make path Polun luominen epäonnistui @@ -19689,7 +20268,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tiedostopyyntö peruttu - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Tämä Retrosharen versio käyttää OpenPGP-SDK:ta. Tämän takia se ei käytä järjestelmäjaettua PGP-avainketjua, vaan sillä on oma avainketjunsa jaettuna kaikkien käynnissä olevien Retrosharejen kanssa.<br><br>Sinulla ei näytä olevan tällaista avainketjua, vaikka olemassaolevissa Retroshare-tileissä mainitaan PGP-avaimet. Tämä johtuu todennäköisesti siitä, että siirryit juuri ohjelman uudempaan versioon. @@ -19844,7 +20423,7 @@ Virhe: sekuntia - + TR up @@ -19889,7 +20468,7 @@ Virhe: estetty - + Move IP %1 to whitelist Lisää IP %1 sallittujen luetteloon @@ -19905,7 +20484,7 @@ Virhe: - + %1 seconds ago %1 sekuntia sitten @@ -19990,7 +20569,7 @@ Tietoturva: ei nimettömiä tunnisteita - + Error Virhe @@ -20381,9 +20960,8 @@ Tietoturva: ei nimettömiä tunnisteita Napsauta jatkaaksesi tiivisteen laskentaa - <p>This certificate contains: - <p>Tämä varmenne sisältää: + <p>Tämä varmenne sisältää: @@ -20757,7 +21335,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 kt @@ -20979,19 +21557,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... - Näytä sarake... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Laskeva järjestys + + + + Sort Ascending Order + Nouseva järjestys + + + + + [no title] + + + + + Show column … + + + + Show column... + Näytä sarake... - [no title] - [ei otsikkoa] + [ei otsikkoa] @@ -21427,7 +22034,7 @@ p, li { white-space: pre-wrap; } Lataa! - + File Tiedosto @@ -21442,7 +22049,7 @@ p, li { white-space: pre-wrap; } Tiiviste (hash) - + Bad filenames have been cleaned Virheelliset tiedostonimet muutettu @@ -21492,7 +22099,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tallenna - + Collection Editor Kokoelman muokkaus @@ -21507,7 +22114,7 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tiedostojen määrä - + Real Size: Waiting child... Todellinen koko: Odotetaan alihakemistoja... @@ -21522,12 +22129,12 @@ Merkit <b>",|,/,\,&lt;,&gt;,*,?</b> korvataan merkillä Tämä on hakemisto. Laajenna se kaksoisnapauttamalla. - + Download files Lataa tiedostot - + Specify... Määritä... @@ -21776,7 +22383,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u RsFriendListModel - + Name Nimi @@ -21796,7 +22403,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u IP - + Profile ID @@ -21809,10 +22416,15 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u RsGxsForumModel - + Title Otsikko + + + UnRead + + Date @@ -21824,7 +22436,7 @@ Jos se on mielestäsi kunnollinen, poista mainittu rivi tiedostosta ja avaa se u Kirjoittaja - + Information for this identity is currently missing. Tämän henkilöllisyyden tiedot ovat tällä hetkellä kateissa. @@ -21865,7 +22477,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. [Tuntematon] - + [ ... Missing Message ... ] [ ... Puuttuva viesti ... ] @@ -21873,7 +22485,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. RsMessageModel - + Date Päiväys @@ -21933,7 +22545,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. - + [Notification] @@ -22292,7 +22904,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Tiedoston nimi - + Download Lataa @@ -22371,7 +22983,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Avaa kansio - + Create Collection... Luo kokoelma... @@ -22391,7 +23003,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Lataa kokoelmatiedostosta... - + Collection Kokoelma @@ -22496,12 +23108,12 @@ estää viestin lähettämisen eteenpäin ystävillesi. Vertaisen tiedot - + Deny friend Torju ystävä - + Chat Keskustelu @@ -22511,7 +23123,7 @@ estää viestin lähettämisen eteenpäin ystävillesi. Aloita keskustelu - + Expand Laajenna @@ -22781,13 +23393,13 @@ vähän ystäviä. Tämä auttaa myös, jos olet palomuurin tai VPN:n takana.Etsintä käytössä (suositus) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor on Retrosharen automaattisesti määrittelemä. Sinun ei pitäisi tarvita muuttaa mitään tässä. - + Discovery Off Etsintä ei käytössä @@ -23280,7 +23892,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis <p>Välittäjänä toimiva Retroshare-solmu ei voi nähdä välitettyä liikennettä, koska se on salattu ja kahden välitetyn solmun vahvistama.</p> - + Network Verkko @@ -23308,7 +23920,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis - + Status Tila @@ -23405,7 +24017,7 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis - + Service Address Palvelun osoite @@ -23440,12 +24052,12 @@ Jos sinulla on ongelmia yhteydenluonnissa Tor-verkkoon, tarkista myös Tor-lokis Täytä palveluosoite - + IP Range IP-avaruus - + Reported by DHT for IP masquerading DHT raportoi IP:n naamioinnista @@ -24120,7 +24732,7 @@ p, li { white-space: pre-wrap; } Puuttuva PGP-varmenne - + Wrong password Väärä salasana @@ -24162,7 +24774,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Lisää ystävä @@ -24218,7 +24830,7 @@ This choice can be reverted in settings. Palveluiden käyttöoikeudet - + DHT DHT @@ -24758,7 +25370,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24772,13 +25384,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor ei ole nyt linjoilla - + Tor is OK Tor on OK @@ -24787,6 +25398,31 @@ p, li { white-space: pre-wrap; } No tor configuration Ei tor-asetuksia + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25080,35 +25716,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Sinulla on %1 kpl valmiita latauksia + You have %1 completed transfers + - You have %1 completed download - Sinulla on %1 valmis lataus + You have %1 completed transfer + - %1 completed downloads - %1 kpl valmiita latauksia + %1 completed transfers + - %1 completed download - %1 valmis lataus + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Sinulla on %1 kpl valmiita latauksia + + + You have %1 completed download + Sinulla on %1 valmis lataus + + + %1 completed downloads + %1 kpl valmiita latauksia + + + %1 completed download + %1 valmis lataus TransfersDialog - + Downloads Lataukset @@ -25119,7 +25766,7 @@ p, li { white-space: pre-wrap; } Lähetykset - + Name i.e: file name Nimi @@ -25326,7 +25973,7 @@ p, li { white-space: pre-wrap; } Määritä... - + Move in Queue... Siirrä jonossa... @@ -25420,7 +26067,7 @@ p, li { white-space: pre-wrap; } Kirjoita uusi ja validi tiedostonimi - + Expand all Laajenna kaikki @@ -25552,7 +26199,7 @@ p, li { white-space: pre-wrap; } - + Columns Sarakkeet @@ -25563,7 +26210,7 @@ p, li { white-space: pre-wrap; } Tiedostojen siirrot - + Path Polku @@ -25573,7 +26220,7 @@ p, li { white-space: pre-wrap; } Näytä Polku-sarake - + Could not delete preview file Esikatselutiedostoa ei voitu poistaa @@ -25583,7 +26230,7 @@ p, li { white-space: pre-wrap; } Yritä uudelleen? - + Create Collection... Luo kokoelma... @@ -25598,7 +26245,7 @@ p, li { white-space: pre-wrap; } Näytä kokoelma... - + Collection Kokoelma @@ -25844,7 +26491,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Tuntematon vertainen @@ -25940,7 +26587,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Sinulle on uusia viestejä %1 kpl @@ -26324,7 +26971,7 @@ p, li { white-space: pre-wrap; } Luo ryhmä - + Subscribe to Group Tilaa ryhmä @@ -26418,8 +27065,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Näytä muokkaushistoria @@ -26430,7 +27077,7 @@ p, li { white-space: pre-wrap; } - + Preview Esikatselu @@ -26455,12 +27102,12 @@ p, li { white-space: pre-wrap; } Piilota muokkaushistoria - + Edit Page Muokkaa sivua - + Create New Wiki Page Luo uusi wikisivu @@ -26480,7 +27127,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Luo uusi wikiryhmä @@ -26522,7 +27169,7 @@ p, li { white-space: pre-wrap; } Aikaväli - + Create Account @@ -26532,12 +27179,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Päivitä @@ -26572,12 +27218,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26647,7 +27293,7 @@ p, li { white-space: pre-wrap; } Näyttää: - + Yourself Sinä itse @@ -26685,7 +27331,7 @@ p, li { white-space: pre-wrap; } Lähetä pulssi lennättimeen - + RetroShare Retroshare @@ -26697,7 +27343,7 @@ p, li { white-space: pre-wrap; } - + The Wire Lennätin @@ -26705,7 +27351,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26786,8 +27432,8 @@ p, li { white-space: pre-wrap; } Lomake - - + + Avatar Avatar @@ -26816,6 +27462,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26928,8 +27579,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Kuvat (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Kuvat (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_fr.ts b/retroshare-gui/src/lang/retroshare_fr.ts index 87874f0f0..cc9597926 100644 --- a/retroshare-gui/src/lang/retroshare_fr.ts +++ b/retroshare-gui/src/lang/retroshare_fr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Version de Retroshare @@ -79,7 +79,7 @@ Amusez-vous ;-) - + Only Hidden Node Nœud caché seulement @@ -129,12 +129,12 @@ Retroshare : Recherche avancée - + Search Criteria Critère(s) de recherche - + Add a further search criterion. Ajouter un critère de recherche. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulaire - - + + TextLabel Etiquette @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barre d'outils - + Icon Only Icône seulement @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Choisissez le style des boutons outils. - + Icon Size = 8x8 Taille d'icône = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Taille d'icône = 128x128 - + Status Bar Barre de statut @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Désactive les infobulles en zone de notification - + Main page items: Articles de page principale : @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Liste d'articles - + Icon Size = 32x32 Taille icône = 32x32 @@ -828,14 +828,23 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Changer l'avatar - + + TextLabel + + + + Your Avatar Picture Votre image avatar - + + Browse... + + + Add Avatar - Ajouter avatar + Ajouter avatar @@ -843,25 +852,34 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Supprimer - + Set your Avatar picture Mettre votre image d'avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Charger l'avatar + Charger l'avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Cliquez pour modifier votre avatar @@ -869,7 +887,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à BWGraphSource - + KB/s KO/s @@ -889,44 +907,65 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à RetroShare Bandwidth Usage Utilisation de la bande passante par Retroshare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Options + TextLabel + + + + Reset Réinitialiser - Receive Rate - Vitesse de réception + Vitesse de réception - Send Rate - Vitesse d'émission + Vitesse d'émission - + Always on Top Toujours visible - Style - Style + Style - + Changes the transparency of the Bandwidth Graph Modifier la transparence du graphique de bande passande - + 100 100 @@ -936,30 +975,27 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à % opaque - Save - Sauvegarder + Sauvegarder - Cancel - Annuler + Annuler - + Since: Statistiques enregistrées depuis : - Hide Settings - Masquer les options + Masquer les options BandwidthStatsWidget - + Sum Somme @@ -981,7 +1017,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Compte - + Average Moyenne @@ -1115,7 +1151,7 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à - + Comments Commentaires @@ -1193,6 +1229,85 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à + + BoardsCommentsItem + + + I like this + J'aime ça + + + + 0 + 0 + + + + I dislike this + Je n'aime pas ça + + + + Toggle Message Read Status + Changer l'état de lecture du message + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Définir comme lu et supprimer l'élément + + + + Remove Item + + + + + Name + Nom + + + + Comm value + + + + + Comment + Commentaire + + + + Comments + Commentaires + + + + Hide + Cacher + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Mais rappelez-vous : Toutes les données *SERONT* perdus quand nous mettrons à Log scale Échelle de journal + + + Default + Par défaut + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + J'aime ça + + + + 0 + 0 + + + + I dislike this + Je n'aime pas ça + + + + Toggle Message Read Status + Changer l'état de lecture du message + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Définir comme lu et supprimer l'élément + + + + Remove Item + + + + + Name + Nom + + + + Comm value + + + + + Comment + Commentaire + + + + Comments + Commentaires + + + + Hide + Cacher + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Tchats - You have %1 new messages - Vous avez %1 nouveaux messages + Vous avez %1 nouveaux messages + + + You have %1 new message + Vous avez %1 nouveau message + + + %1 new messages + %1 nouveaux messages + + + %1 new message + %1 nouveau message + + + + You have %1 mentions + - You have %1 new message - Vous avez %1 nouveau message + You have %1 mention + - %1 new messages - %1 nouveaux messages + %1 mentions + - %1 new message - %1 nouveau message + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Tout supprimer - - - mention(s) - - ChatLobbyWidget @@ -2124,13 +2339,11 @@ Double-cliquez sur un salon pour y entrer et discuter. Variante : - Group chat - Tchat public + Tchat public - - + Private chat Tchat privé @@ -2195,17 +2408,16 @@ Double-cliquez sur un salon pour y entrer et discuter. /me envoie un message avec /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Dans cet onglet, vous pouvez configurer le nombre de messages de tchat que Retroshare gardera sauvegardé sur le disque et combien de la conversation précédente, elle affiche, pour les différents systèmes de discussions. La période de stockage max permet de supprimer les anciens messages et empêche l'historique des conversations de remplir les tchats volatiles (par exemple, les salons de tchat et tchat à distance).</p></body></html> - Chatlobbies - Salons de tchat + Salons de tchat - + Enabled: Activé : @@ -2226,11 +2438,12 @@ Double-cliquez sur un salon pour y entrer et discuter. + Chat rooms Salons de tchat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Sélectionné, si l'identité et le texte ci-dessus de même origine doivent être dans le même cas pour déclencher le comptage. @@ -2291,11 +2504,17 @@ Double-cliquez sur un salon pour y entrer et discuter. + Broadcast Tchat entre amis - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Nombre de messages sauvegardés (0 = illimité) : @@ -2442,8 +2661,23 @@ Double-cliquez sur un salon pour y entrer et discuter. Tchat privé - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Double-cliquez sur un salon pour y entrer et discuter. - + is typing... écrit... @@ -2631,12 +2865,12 @@ after HTML conversion. après la conversion en HTML. - + Choose your font. Choisissez votre police de caractère. - + Do you really want to physically delete the history? Etes-vous vraiment sûr de vouloir supprimer définitivement l'historique ? @@ -2708,7 +2942,7 @@ après la conversion en HTML. Ne pas cesser de colorer après X articles trouvés (nécessite davantage de CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trouver le précédent </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ après la conversion en HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marquer ce texte comme sélectionné</b><br><i>Ctrl+M</i> - + Person id: Id d'identité: @@ -2770,7 +3004,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Non signé - + items found. articles trouvés. @@ -2790,7 +3024,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Saisissez votre message ici - + Don't stop to color after Ne pas cesser de colorer après @@ -2948,12 +3182,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. ConfCertDialog - + Details Détails - + Local Address Adresse locale : @@ -2964,12 +3198,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Adresse externe : - + Node info: Information du nœud: - + Current address: Adresse courante: @@ -2985,31 +3219,36 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Port : - + Include signatures Inclure les signatures - + RetroShare Retroshare - + - + Error : cannot get peer details. Erreur : impossible d'obtenir les détails de ce contact. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Chiffrement - + Not connected Non connecté - + Retroshare node details Détails de noeud Retroshare - + Node name : Nom de noeud : @@ -3075,13 +3319,18 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Message d'état : - + + Connectivity + + + + List of known addresses: Liste des adresses connues: - - + + Retroshare Certificate Certificat Retroshare @@ -3096,7 +3345,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message. - + Hidden Address Adresse cachée @@ -3107,11 +3356,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.aucun + <p>This certificate contains: - <p>Ce certificat contient : + <p>Ce certificat contient : - + <li>a <b>node ID</b> and <b>name</b> <li>un <b>ID de noeud</b> et <b>nom</b> @@ -3124,12 +3374,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.une <b>addresse IP</b> et <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Vous pouvez utiliser ce certificat pour vous faire de nouveaux amis. Envoyez-le par courrier électronique, ou donnez-le de main à la main.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Ceci est l'ID du certificat <span style=" font-weight:600;">OpenSSL</span> du noeud, qui est signé par la clé <span style=" font-weight:600;">PGP</span> ci-dessus. </p></body></html> @@ -3139,7 +3389,7 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.<html><head/><body><p>Ceci est la méthode de chiffrement utilisée par <span style=" font-weight:600;">OpenSSL</span>. La connexion aux noeuds amis est </p><p>toujours lourdement chiffrée, et si la DHE est présente la connexion utilise ensuite </p><p>&quot;perfect forward secrecy&quot;.</p></body></html> - + with avec @@ -3345,12 +3595,12 @@ Double cliquez pour ajouter son nom dans le champ de saisie du message.Détails de la demande - + Peer details Détails du contact - + Name: Nom : @@ -3368,12 +3618,12 @@ resources. Veuillez noter que Retroshare nécessitera beaucoup de bande passante, mémoire et CPU si vous ajoutez de nombreux amis. Vous pouvez ajouter autant d'amis que vous le souhaitez, mais avec avec plus de 40 cela nécessitera probablement trop de ressources. - + Location: Emplacement : - + Options Options @@ -3410,12 +3660,12 @@ resources. Collez le certificat - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Cette boîte s'attend au certificat de votre ami Retroshare. AVERTISSEMENT : cela est différent de la clé PGP de votre ami. Ne collez pas ici la clé de profil de votre ami (même pas une partie). Cela ne fonctionnera pas.</p></body></html> - + Add friend to group: Ajouter l'ami à un groupe : @@ -3425,7 +3675,7 @@ resources. Ami authentifié (clé PGP signée) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with Ajouter cet ami pour communiquer avec lui @@ -3459,7 +3709,7 @@ resources. Pour accepter la demande d'amitié, cliquez sur le bouton Terminer. - + Sorry, some error appeared Désolé, des erreurs sont survenues @@ -3479,32 +3729,32 @@ resources. À propos de votre ami : - + Key validity: Validité de la clé : - + Profile ID: - + Signers Ils lui font aussi confiance : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est un moyen d'exprimer votre confiance en cet ami, à vos autres amis. Les signatures sous cryptographie attestent que les propriétaires des clés répertoriées reconnaissent la clé PGP actuelle comme authentique.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Ce contact est déjà dans votre liste d'am. L'ajouter se limitera à enregistrer son adresse IP. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Le chargement du certificat à échoué @@ -3587,12 +3837,12 @@ resources. Le certificat semble valide - + Not a valid Retroshare certificate! Certificat Retroshare non valide! - + RetroShare Invitation Invitation Retroshare @@ -3614,12 +3864,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? C'est votre propre certificat! Vous ne voulez pas devenir ami avec vous même. N'est-ce pas? - + @@ -3667,7 +3917,37 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Vous avez une demande d'amitié de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3755,12 +4035,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Utiliser en source directe, quand disponible - + IP-Addr: Addr-IP : - + IP-Address Adresse IP @@ -3826,7 +4106,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Ajouter la clé au trousseau - + This key is already in your keyring Cette clé est déjà dans votre trousseau @@ -3887,12 +4167,12 @@ contact même si vous n'êtes pas amis. <p>Ce certificat n'a pas d'IP. Vous devrez compter sur la découverte et la DHT pour le trouver. Parce que vous exigez l'autorisation liste blanche, le pair lèvera un avertissement de sécurité dans l'onglet "Fil d'actualités". De là, vous pourrez passer son IP en liste blanche.</p> - + [Unknown] [Inconnu] - + Added with certificate from %1 Ajoutée avec certificat depuis %1 @@ -3979,7 +4259,12 @@ contact même si vous n'êtes pas amis. Résultat UDP - + + Status + Statut + + + <!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; } @@ -4409,7 +4694,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4561,7 +4846,7 @@ p, li { white-space: pre-wrap; } Aucune limitation de cercle sélectionnée - + [Unknown] [Inconnu] @@ -4576,7 +4861,7 @@ p, li { white-space: pre-wrap; } Enlever - + Search Rechercher @@ -4596,7 +4881,7 @@ p, li { white-space: pre-wrap; } Signé par des noeuds connus - + Edit Circle Modifier le cercle @@ -4616,12 +4901,12 @@ p, li { white-space: pre-wrap; } ID anon - + Circle name Nom du cercle - + Update Mettre à jour @@ -4647,7 +4932,7 @@ p, li { white-space: pre-wrap; } ID PGP liée - + Add Member Ajouter membre @@ -4791,7 +5076,7 @@ p, li { white-space: pre-wrap; } - + Attachments Fichiers joints @@ -4837,7 +5122,7 @@ p, li { white-space: pre-wrap; } Glisser/déposer les fichiers à partir des résultats de recherche - + Paste RetroShare Links Coller le lien Retroshare @@ -4847,7 +5132,7 @@ p, li { white-space: pre-wrap; } Coller le lien Retroshare - + Drop file error. Erreur lors de l'ajout du fichier. @@ -4874,17 +5159,41 @@ p, li { white-space: pre-wrap; } - + RetroShare Retroshare - - File already Added and Hashed - Fichier déjà ajouté et hashé + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Fichier déjà ajouté et hashé + + + Please add a Subject Veuillez ajouter un sujet à votre message @@ -4915,12 +5224,12 @@ p, li { white-space: pre-wrap; } Voulez-vous vraiment générer %1 messages ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Vous êtes sur le point d'ajouter les fichiers que vous ne partagez pas actuellement. Voulez-vous toujours faire cela ? - + Edit Channel Post Modifier la publication de la chaîne @@ -4940,7 +5249,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Vous êtes sur le point de publier un fichier non-possédé sur la chaîne. @@ -5032,7 +5341,7 @@ p, li { white-space: pre-wrap; } - + No Forum Aucun forum @@ -5492,7 +5801,7 @@ et utiliser le bouton d'importation pour la charger DHTGraphSource - + users utilisateurs @@ -6499,7 +6808,7 @@ et utiliser le bouton d'importation pour la charger FlatStyle_RDM - + Friends Directories Dossiers partagés de mes amis @@ -7006,7 +7315,7 @@ au moins un contact n'a pas été ajouté au groupe Rechercher des amis - + Mark all Tout marquer @@ -7020,7 +7329,7 @@ au moins un contact n'a pas été ajouté au groupe FriendsDialog - + Edit status message Modifier le message d'état @@ -7124,7 +7433,7 @@ au moins un contact n'a pas été ajouté au groupe Retroshare broadcast chat : les messages sont envoyés à tous vos amis en ligne. - + Network Réseau @@ -7189,7 +7498,7 @@ au moins un contact n'a pas été ajouté au groupe Le champ noeud est exigé avec un minimum de 3 caractères - + Failed to generate your new certificate, maybe PGP password is wrong! Échec lors de la génération de votre nouveau certificat, peut-être que votre mot de passe PGP est faux ! @@ -7232,7 +7541,7 @@ au moins un contact n'a pas été ajouté au groupe Utiliser un profil existant - + Node name Nom de l'emplacement @@ -7507,12 +7816,12 @@ et l'utiliser au moyen du bouton d'importation afin de le charger - + Profile generation failure Échec lors de la génération du profil - + Missing PGP certificate Certificat PGP manquant @@ -7931,7 +8240,7 @@ p, li { white-space: pre-wrap; } Statistiques du routeur - + GroupBox GroupBox @@ -7996,7 +8305,7 @@ p, li { white-space: pre-wrap; } Embranchement de facteur - + Details Détails @@ -8019,7 +8328,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Clés gérées @@ -8228,7 +8537,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titre @@ -8238,13 +8547,30 @@ p, li { white-space: pre-wrap; } Rechercher titre - - + + + + Description Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Rechercher description @@ -8254,42 +8580,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Trier Ordre décroissant + Trier Ordre décroissant - Sort Ascending Order - Trier Ordre croissant + Trier Ordre croissant - Sort by Name - Trier par nom + Trier par nom - Sort by Popularity - Trier par popularité + Trier par popularité - Sort by Last Post - Trier par dernier message + Trier par dernier message - Sort by Number of Posts - Trier par quantité de messages + Trier par quantité de messages - Sort by Unread - Trier par Non lus + Trier par Non lus - + You are admin (modify names and description using Edit menu) Vous êtes administrateur (modifiez les noms et la description en utilisant le menu Edition) @@ -8304,40 +8623,35 @@ p, li { white-space: pre-wrap; } Id - - + + Last Post Dernier commentaire - + + Name Nom - - Unread - - - - + Popularity Popularité - - + + Never Jamais - Display - Affichage + Affichage - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8486,7 +8800,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Chaînes @@ -8519,12 +8833,12 @@ Les chaînes peuvent être anonymes, ou attachées à une identité Retroshare a Les publications sont conservés pendant %1 jours et synchronisés au cours des derniers %2 jours, à moins que vous ne les modifiez.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Chaînes abonnées @@ -9049,7 +9363,7 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Add new post Ajouter une nouvelle publication @@ -9149,12 +9463,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Files Fichiers - + Comments Commentaires @@ -9165,18 +9479,18 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Feeds Flux - - + + Click to switch to list view - + Show unread posts only @@ -9186,12 +9500,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + No files in the channel, or no channel selected - + No text to display @@ -9251,7 +9565,7 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Download this file: @@ -9266,12 +9580,12 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des - + Comments (%1) - + [No name] @@ -9347,23 +9661,36 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des + Copy Retroshare link + + + + Subscribed Abonné - - Subscribe S'abonner - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Aucune chaîne sélectionnée @@ -9385,11 +9712,6 @@ Les publications sont conservés pendant %1 jours et synchronisés au cours des Channel Post Message - - - new message(s) - - GxsCircleItem @@ -9923,7 +10245,7 @@ avant de pouvoir commenter Lancer un nouveau fil dans le forum sélectionné - + Search forums Chercher @@ -9932,12 +10254,12 @@ avant de pouvoir commenter Dernier article - + New Thread Nouveau fil - + Threaded View Affichage en arborescence @@ -9947,19 +10269,19 @@ avant de pouvoir commenter Affichage à plat - - + + Title Titre - - + + Date Date - + Author Auteur @@ -9974,7 +10296,17 @@ avant de pouvoir commenter Chargement - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10036,23 +10368,23 @@ avant de pouvoir commenter Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des forums à gauche.</p> - + No name Aucun nom - - + + Reply Répondre - + <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> - + Loading... @@ -10090,12 +10422,12 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Marquer comme non lu - + Copy RetroShare Link Copier le lien Retroshare - + Hide Cacher @@ -10108,7 +10440,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for [Banni] - + [unknown] [inconnu] @@ -10138,8 +10470,8 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Vos yeux seulement - - + + Distribution Distribution @@ -10242,7 +10574,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Message d'origine - + New thread Nouveau fil @@ -10251,7 +10583,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Lire l'état - + Edit Modifier @@ -10307,7 +10639,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Afficher l'auteur dans l'onglet gens - + Author's reputation Réputation de l'auteur @@ -10327,7 +10659,7 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for - + <b>Loading...<b> @@ -10367,6 +10699,11 @@ Ensuite vous pourrez vous désabonner via le menu contextuel de la liste des for Storage Stockage + + + Last seen at friends: + + Moderators @@ -10457,7 +10794,7 @@ prevents the message to be forwarded to your friends. Le %1, %2 a écrit : - + Forum name Nom de forum @@ -10489,11 +10826,6 @@ prevents the message to be forwarded to your friends. Forum Post Message - - - new message(s) - - GxsForumsDialog @@ -10944,7 +11276,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Aperçu avant impression - + Unsubscribe Se désabonner @@ -10959,7 +11291,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Ouvrir dans un nouvel onglet - + Remove this search @@ -10969,12 +11301,12 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de - + Request data - + Show Details Afficher détails @@ -11041,7 +11373,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de - + Search for @@ -11050,7 +11382,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Partager les permissions de publication - + Copy RetroShare Link Copier le lien Retroshare @@ -11065,7 +11397,7 @@ Les messages du forum sont conservés pour %1 jours et synchronisés au cours de Tout marquer comme non lu - + AUTHD Authentification @@ -11682,7 +12014,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11691,7 +12023,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11717,6 +12049,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11728,7 +12077,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11808,27 +12157,32 @@ p, li { white-space: pre-wrap; } Formulaire - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11850,6 +12204,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11858,7 +12213,7 @@ p, li { white-space: pre-wrap; } Le texte ci-dessous est votre propre certificat Retroshare. Envoyez-le à vos amis - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11875,12 +12230,12 @@ Plate-forme de communication décentralisée privée et sécurisée. Besoin d'aide avec RetroShare? - + Open Web Help Ouvrir l'aide Web - + Copy your Cert to Clipboard Copiez votre Certificat en mémoire. @@ -11929,7 +12284,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11938,7 +12293,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12231,14 +12586,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tout - + Reputation Réputation @@ -12248,12 +12603,12 @@ p, li { white-space: pre-wrap; } Rechercher - + Anonymous Id ID anonyme - + Create new Identity Créer une nouvelle identité @@ -12398,7 +12753,7 @@ Votes négatifs ID de l'identité - + Send message Envoyer message @@ -12470,7 +12825,7 @@ Votes négatifs Générale : - + Anonymous Anonymes @@ -12485,24 +12840,24 @@ Votes négatifs Chercher ID - + This identity is owned by you Cette identité est possédée par vous-même - - + + My own identities Mes propres identités - - + + My contacts Mes contacts - + Show Items Options d'affichage @@ -12517,7 +12872,7 @@ Votes négatifs Lié à mon noeud - + Other circles Autres cercles @@ -12576,13 +12931,18 @@ Votes négatifs subscribed (Receive/forward membership requests from others and invite list). Abonné (reçoit/transfère les demandes d'adhésion de la part d'autres et listes d'invitations). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). désabonné (reçoit seulement les listes d'invitations). - + Your status: Votre statut : @@ -12642,7 +13002,7 @@ Votes négatifs Membre - + Edit Circle Modifier le cercle @@ -12690,7 +13050,7 @@ Votes négatifs Autoriser à adhérer - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12702,12 +13062,12 @@ Ces identités ne seront bientôt plus supportées. - + [Unknown node] [Noeud inconnu] - + Unverified signature from node Signature non vérifiée, de la part du noeud @@ -12719,12 +13079,12 @@ Ces identités ne seront bientôt plus supportées. Signature non contrôlée - + [unverified] [non vérifié] - + Identity owned by you, linked to your Retroshare node Identité possédée par vous, liée à votre noeud Retroshare @@ -12848,12 +13208,12 @@ Ces identités ne seront bientôt plus supportées. Voulez-vous vraiment envoyer une invitation avec votre certificat ? - + Banned Banni - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identités</h1> <p>Dans cet onglet vous pouvez créer/éditer des <b>identités pseudo-anonymes</b>, et des <b>cercles</b>. <p><b>Les identités</b> sont utilisés pour identifier vos données de manière sécurisée : signez les messages dans les salons de tchat, les messages de forum et de canal, recevez des commentaires à l'aide du système de messagerie intégré Retroshare, publiez des commentaires après les messages de canaux, discutez en utilisant des tunnels sécurisés, etc.</p> @@ -12867,7 +13227,7 @@ Ces identités ne seront bientôt plus supportées. ID inconnu : - + positive positif @@ -13052,8 +13412,8 @@ Ces identités ne seront bientôt plus supportées. - - + + People Pers. @@ -13064,7 +13424,7 @@ Ces identités ne seront bientôt plus supportées. Votre avatar - + Linked to neighbor nodes Liée(s) aux noeuds voisins @@ -13074,7 +13434,7 @@ Ces identités ne seront bientôt plus supportées. Liée(s) aux noeuds distants - + Linked to a friend Retroshare node Liée(s) à un noeud Retroshare ami @@ -13134,7 +13494,7 @@ Ces identités ne seront bientôt plus supportées. Possédé par - + Node name: Nom de noeud : @@ -13144,7 +13504,7 @@ Ces identités ne seront bientôt plus supportées. ID de noeud : - + Really delete? Vraiment supprimer ? @@ -13182,7 +13542,22 @@ Ces identités ne seront bientôt plus supportées. Pseudonyme - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nouvelle identité @@ -13199,14 +13574,14 @@ Ces identités ne seront bientôt plus supportées. - + N/A N/A - + Edit identity Modifier l'identité @@ -13217,24 +13592,27 @@ Ces identités ne seront bientôt plus supportées. Mettre à jour - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13253,17 +13631,27 @@ Ces identités ne seront bientôt plus supportées. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Erreur lors de la récupération de la clé ! - + Error KeyID invalid Erreur ID de la clé invalide - + Unknown GpgId GpgId inconnu @@ -13273,7 +13661,7 @@ Ces identités ne seront bientôt plus supportées. Vrai nom inconnu - + Create New Identity Créer une nouvelle identité @@ -13283,7 +13671,12 @@ Ces identités ne seront bientôt plus supportées. Type - + + Choose image... + + + + @@ -13323,12 +13716,11 @@ Ces identités ne seront bientôt plus supportées. Votre avatar - Set Avatar - Mettre l'avatar + Mettre l'avatar - + Linked to your profile Liée à votre profil @@ -13338,7 +13730,7 @@ Ces identités ne seront bientôt plus supportées. Vous pouvez avoir une seule ou plusieurs identités. Elles sont utilisées lorsque vous écrivez dans des salons de tchat, forums, et dans les commentaires de chaînes. Elles agissent comme destination pour le tchat distant et pour le système de courrier distant de Retroshare. - + The nickname is too short. Please input at least %1 characters. Ce pseudonyme est trop court. Veuillez saisir au moins %1 caractères. @@ -13447,8 +13839,12 @@ Ces identités ne seront bientôt plus supportées. + Quote + Citer + + Send - Envoyer + Envoyer @@ -13606,7 +14002,7 @@ Ces identités ne seront bientôt plus supportées. - + Options Options @@ -13638,12 +14034,12 @@ Ces identités ne seront bientôt plus supportées. Assistant de configuration rapide - + RetroShare %1 a secure decentralized communication platform Retroshare %1 - Logiciel de communication sécurisé et décentralisé - + Unfinished Inachevé @@ -13776,7 +14172,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Afficher - + Make sure this link has not been forged to drag you to a malicious website. Assurez-vous que ce lien n'a pas été créé pour vous emmener vers un site Web malveillant. @@ -13821,7 +14217,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Matrice des autorisations de services - + Statistics Statistiques @@ -13850,7 +14246,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. MessageComposer - + Compose Écrire @@ -13952,7 +14348,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. - + Tags Mots clés @@ -14047,12 +14443,12 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Ajouter une citation - + Send To: Envoyer à : - + &Left Aligner à Gauche @@ -14086,7 +14482,7 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. Mes contacts - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Bonjour, <br>Je vous recommande un(e) bon(nne) ami(e), vous pouvez lui faire confiance autant qu'à moi. <br> @@ -14112,12 +14508,12 @@ Veuillez libérer de l'espace disque et cliquer sur Ok. - + Save Message Enregistrer le message - + Message has not been Sent. Do you want to save message to draft box? Le message n'a pas été envoyé @@ -14129,7 +14525,7 @@ Désirez-vous enregistrer le message dans les brouillons? Coller le lien Retroshare - + Add to "To" Ajouter à "A" @@ -14384,7 +14780,7 @@ Voulez-vous enregistrer votre message ? Ajouter un fichier supplémentaire - + Hi,<br>I want to be friends with you on RetroShare.<br> Salut,<br>je voudrais être ami avec vous sur RetroShare. <br> @@ -14393,12 +14789,27 @@ Voulez-vous enregistrer votre message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Vous avez une invitation de la part d'un ami - + Respond now: Répondre maintenant : @@ -14414,11 +14825,12 @@ Voulez-vous enregistrer votre message ? De : + Friend Nodes - Noeuds amis + Noeuds amis - + Bullet list (disc) Liste à puces (disque) @@ -14458,13 +14870,13 @@ Voulez-vous enregistrer votre message ? Liste ordonnée (romain majuscule) - - + + Thanks, <br> Remerciements, <br> - + Distant identity: Identité distante : @@ -14603,8 +15015,23 @@ Voulez-vous enregistrer votre message ? Message - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14616,12 +15043,12 @@ Voulez-vous enregistrer votre message ? Fichiers recommandés - + Download all Recommended Files Télécharger tous les fichiers recommandés - + Subject: Sujet : @@ -14696,12 +15123,18 @@ Voulez-vous enregistrer votre message ? Envoyer invitation - + + Message Size: + + + + File Name Nom du fichier - + + Size Taille @@ -14762,10 +15195,25 @@ Voulez-vous enregistrer votre message ? Télécharger - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Envoyer invitation ? @@ -14776,12 +15224,12 @@ Voulez-vous enregistrer votre message ? - + Download all Tout télécharger - + Print Document Imprimer le document @@ -14796,7 +15244,7 @@ Voulez-vous enregistrer votre message ? Fichiers HTML (*.htm *.html);;tous les fichiers (*) - + Load images always for this message Toujours charger les images pour ce message @@ -14937,7 +15385,7 @@ Voulez-vous enregistrer votre message ? MessagesDialog - + New Message Nouveau message @@ -14993,14 +15441,14 @@ Voulez-vous enregistrer votre message ? - + Tags Mots clés - + Inbox Boîte de réception @@ -15095,7 +15543,7 @@ Voulez-vous enregistrer votre message ? Faire suivre le(s) message(s) - + Subject Sujet @@ -15207,7 +15655,7 @@ Voulez-vous enregistrer votre message ? - + Open in a new window Ouvrir dans une nouvelle fenêtre @@ -15292,7 +15740,7 @@ Voulez-vous enregistrer votre message ? - + Drafts Brouillons @@ -15421,7 +15869,7 @@ Voulez-vous enregistrer votre message ? Répondre au message - + Delete Message Supprimer le message @@ -15432,7 +15880,7 @@ Voulez-vous enregistrer votre message ? - + Expand Développer @@ -15442,7 +15890,7 @@ Voulez-vous enregistrer votre message ? Effacer le message - + from depuis @@ -15451,6 +15899,11 @@ Voulez-vous enregistrer votre message ? Reply to invite Répondre à l'invitation + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15774,7 +16227,7 @@ Erreur remontée : - + Groups Groupes @@ -15804,19 +16257,19 @@ Erreur remontée : Importer votre liste d'amis en incluant les groupes - - + + Search - + ID ID - + Search ID Chercher ID @@ -15826,7 +16279,7 @@ Erreur remontée : - + Show Items Options d'affichage @@ -16031,19 +16484,19 @@ au moins un contact n'a pas été ajouté au groupe - + Error Erreur - + File is not writeable! Fichier impossible à écrire ! - + File is not readable! Fichier illisible ! @@ -16081,9 +16534,13 @@ au moins un contact n'a pas été ajouté au groupe NewsFeed - Log entries - Entrées du journal + Entrées du journal + + + + Activity Stream + @@ -16100,7 +16557,7 @@ au moins un contact n'a pas été ajouté au groupe C'est un test. - + Newest on top Les plus récents en haut @@ -16111,21 +16568,44 @@ au moins un contact n'a pas été ajouté au groupe + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Fil d'actualités</h1> <p>Le fil d'actualités affiche les derniers événements survenus dans votre réseau, triés selon le moment où vous les avez reçus. Cela vous donne un résumé de l'activité de vos amis. Vous pouvez configurer les événements à afficher en cliquant sur <b>Options</ b>. + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Fil d'actualités</h1> <p>Le fil d'actualités affiche les derniers événements survenus dans votre réseau, triés selon le moment où vous les avez reçus. Cela vous donne un résumé de l'activité de vos amis. Vous pouvez configurer les événements à afficher en cliquant sur <b>Options</ b>. Les divers événements affichés sont : <ul> <li>Les tentatives de connexion (utile pour ajouter de nouveaux amis et savoir qui essaie de vous contacter) </li> <li> Les nouveaux articles dans les chaînes et les forums</li> <li>Les nouvelles chaînes et forums auxquels vous pouvez vous abonner</li> <li>Les messages privés de vos amis </li> </ul> </p> - Log - Journal + Journal + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16162,22 +16642,22 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de - + Test Test - + Chat Room Salon de tchat - + Systray Icon Icônes sur la barre des tâches - + Message Message @@ -16202,12 +16682,11 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Sécurité IP - Log - Journal + Journal - + Friend Connected Ami connecté @@ -16221,7 +16700,12 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Liens - + + Activity + + + + Mails Courriels @@ -16258,7 +16742,12 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Tchat public - + + Toaster position + + + + Chat rooms Salons de tchat @@ -16283,22 +16772,22 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Sensible à la casse - + Position Position - + X Margin Axe Horizontal - + Y Margin Axe Vertical - + Systray message Message sur la barre des tâches @@ -16348,7 +16837,7 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Notifications - + Disable All Toasters Désactiver toutes les notifications grille-pain @@ -16362,7 +16851,7 @@ Les divers événements affichés sont : <ul> <li>Les tentatives de Flux - + Systray Zone de notification @@ -16508,17 +16997,16 @@ Trafic faible : 10% du trafic standard et TODO : tous les transferts de fichiers PGPKeyDialog - Dialog - Dialogue + Dialogue - + Profile info Info du profil - + Name : Nom : @@ -16573,22 +17061,21 @@ Trafic faible : 10% du trafic standard et TODO : tous les transferts de fichiers Ultime - + This profile has signed your own profile key Ce profil a signé votre propre clé de profil - Key signatures : - Signatures de clé : + Signatures de clé : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Les signatures ci-dessous certifient cryptographiquement que les propriétaires des clés listées reconnaissent la clé PGP actuelle comme authentique.</span></p></body></html> - + <!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; } @@ -16606,7 +17093,7 @@ p, li { white-space: pre-wrap; } Signer cette clé - + PGP key Clé PGP @@ -16616,22 +17103,20 @@ p, li { white-space: pre-wrap; } Ces options s'appliquent à tous les emplacement du profil : - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Cela les aide à décider, en se basant sur votre propre confiance, si ils doivent permettre des connexions depuis cette clé. Signer une clé est absolument facultatif et ne peut pas être défait, alors faites-le avec sagesse.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Signer la clé d'un ami est une façon d'exprimer à vos autres amis votre confiance en cet ami. Cela les aide à décider, en se basant sur votre propre confiance, si ils doivent permettre des connexions depuis cette clé. Signer une clé est absolument facultatif et ne peut pas être défait, alors faites-le avec sagesse.</span></p></body></html> - + Keysigning: - Sign PGP key - Signer la clé PGP + Signer la clé PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Cliuez ici si vous voulez refuser les connexions aux noeuds authentifiés par cette clé.</p></body></html> @@ -16651,7 +17136,7 @@ p, li { white-space: pre-wrap; } Accepter connexions - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Ci-dessous la clé de profil au format PGP ASCII. Elle identifie tous les emplacements du même profil. Un "certificat Retroshare" que vous pouvez échanger pour vous faire des amis, se trouve dans les "détails" de chaque emplacement. @@ -16721,28 +17206,28 @@ p, li { white-space: pre-wrap; } KO/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Erreur : impossible d'obtenir les détails de ce contact. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algorithme de la clé fournie n'est pas supporté par Retroshare (pour l'instant uniquement les clés RSA sont supportées) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16756,7 +17241,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Le niveau de confiance est une façon d'exprimer votre propre confiance en cette clé. Cela n'est pas utilisé par le logiciel, ni partagé, mais cela peut être utile pour vous afin de vous rappeler les bonnes/mauvaises clés. @@ -16801,27 +17286,47 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Actuellement, vous n'autorisez pas les connexions de nœuds Retroshare signés par cette clé. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure La signature a échoué - - Maybe password is wrong - Le mot de passe est peut-être incorrect + + Check the password! + - + Maybe password is wrong + Le mot de passe est peut-être incorrect + + + You haven't set a trust level for this key. Vous n'avez pas réglé de niveau de confiance pour cette clé. - + + Retroshare profile Profil Retroshare - + This is your own PGP key, and it is signed by : Ceci est votre propre clé PGP, et elle a été signée par : @@ -17000,8 +17505,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg PeopleDialog - - + People Pers. @@ -17018,7 +17522,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Interne - + Chat with this person Tchater avec cette personne @@ -17169,7 +17673,7 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Photo - + TextLabel Etiquette @@ -17213,8 +17717,8 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg - <N> Comments >> - + Comments + Commentaires @@ -17249,6 +17753,11 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Write a comment... Ecrivez un commentaire... + + + Album + Album + PhotoItem @@ -17258,12 +17767,12 @@ Attention: Dans vos Préférences de Fichiers, vous avez interdit le télécharg Formulaire - + TextLabel Etiquette - + <!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; } @@ -17359,7 +17868,7 @@ p, li { white-space: pre-wrap; } Afficher la photo - + PhotoShare PhotoShare @@ -17400,7 +17909,7 @@ avant de vouloir le modifier ! - + Stop Stop @@ -17628,12 +18137,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autoriser toutes les extensions - + Plugin look-up directories Dossiers des extensions @@ -17692,7 +18201,7 @@ comportements malveillants des extensions. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Extensions</h1> <p>Les extensions sont chargées depuis les répertoires affichés dans la liste tout en bas.</p> <p>Pour des raisons de sécurité, les extensions reconnues sont chargées automatiquement, jusqu'à ce que l'exécutable principal Retroshare ou que de la bibliothèque de plug-in ne changent. Dans un tel cas, l'utilisateur doit confirmer les plugins à nouveau. Après le démarrage du programme, vous pouvez activer un plugin manuellement en cliquant sur ​​le bouton "Activer" puis ensuite redémarrer Retroshare.</p> <p>Si vous voulez développer vos propres extensions, contactez l'équipe de développeurs, ils seront heureux de vous aider !</p> - + Plugins Extensions @@ -18090,7 +18599,7 @@ comportements malveillants des extensions. Liens - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18261,13 +18770,13 @@ comportements malveillants des extensions. Site - - + + Comments Commentaires - + Copy RetroShare Link @@ -18277,7 +18786,7 @@ comportements malveillants des extensions. Afficher l'auteur dans l'onglet gens - + Comment Commentaire @@ -18298,12 +18807,12 @@ comportements malveillants des extensions. - + Hide Cacher - + Vote up Voter pour @@ -18317,7 +18826,7 @@ comportements malveillants des extensions. \/ - + Set as read and remove item Définir comme lu et supprimer l'élément @@ -18378,7 +18887,7 @@ comportements malveillants des extensions. - + Loading Chargement @@ -18468,13 +18977,7 @@ comportements malveillants des extensions. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18484,60 +18987,50 @@ comportements malveillants des extensions. Administrateur : - - - + + + unknown inconnu - + Distribution: Distribution : - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Posts @@ -18548,7 +19041,7 @@ comportements malveillants des extensions. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18617,7 +19110,12 @@ comportements malveillants des extensions. - + + Empty + Vide + + + Copy RetroShare Link @@ -18652,7 +19150,7 @@ comportements malveillants des extensions. - + [No name] @@ -18780,8 +19278,18 @@ comportements malveillants des extensions. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19061,9 +19569,8 @@ et utiliser le bouton d'importation pour la charger PulseAddDialog - Post From: - Article de : + Article de : Account 1 @@ -19078,7 +19585,7 @@ et utiliser le bouton d'importation pour la charger Compte 3 - + Add to Pulse Ajouter a Pulse @@ -19101,17 +19608,32 @@ et utiliser le bouton d'importation pour la charger URL - + GroupLabel - + IDLabel - + + From: + De : + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19136,10 +19658,20 @@ et utiliser le bouton d'importation pour la charger Négative - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19149,14 +19681,53 @@ et utiliser le bouton d'importation pour la charger - + + Post + + + + Cancel Annuler - Post Pulse to Wire - Publier Pulse sur Wire + Publier Pulse sur Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19182,10 +19753,18 @@ et utiliser le bouton d'importation pour la charger Formulaire - - - - + + + + + Click to view picture + + + + + + + Image Image @@ -19193,44 +19772,44 @@ et utiliser le bouton d'importation pour la charger PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19240,17 +19819,17 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19260,7 +19839,7 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19268,7 +19847,7 @@ et utiliser le bouton d'importation pour la charger PulseTopLevel - + retweeted @@ -19283,7 +19862,7 @@ et utiliser le bouton d'importation pour la charger - + follow Parent Group @@ -19293,7 +19872,7 @@ et utiliser le bouton d'importation pour la charger ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19318,7 +19897,7 @@ et utiliser le bouton d'importation pour la charger - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19354,29 +19933,29 @@ et utiliser le bouton d'importation pour la charger - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19454,7 +20033,7 @@ et utiliser le bouton d'importation pour la charger QObject - + Confirmation Confirmation @@ -19695,7 +20274,7 @@ Les caractères <b>",|,/,\,&lt;,&gt;,*,?</b> seront rem Résultat - + Unable to make path Impossible de créer le chemin @@ -19730,7 +20309,7 @@ Les caractères <b>",|,/,\,&lt;,&gt;,*,?</b> seront rem Demande de fichier annulée - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Cette version de Retroshare utilise OpenPGP SDK. En contre partie, elle n'utilise plus le système de trousseau de clés PGP, mais possède son propre trousseau de clés partagé par toutes les instances de Retroshare. <br><br> Vous ne semblez pas posséder un tel trousseau, bien que des clés PGP apparaissent pour les comptes Retroshare existants, probablement parce que vous venez d'installer cette nouvelle version du logiciel. @@ -19886,7 +20465,7 @@ L'erreur rapportée est : secs - + TR up TR émis @@ -19931,7 +20510,7 @@ L'erreur rapportée est : désactivé - + Move IP %1 to whitelist Ajouter l'IP %1 en liste blanche @@ -19947,7 +20526,7 @@ L'erreur rapportée est : - + %1 seconds ago %1 secondes avant @@ -20032,7 +20611,7 @@ Securité : pas d'IDs anomymes - + Error Erreur @@ -20423,9 +21002,8 @@ Securité : pas d'IDs anomymes - <p>This certificate contains: - <p>Ce certificat contient : + <p>Ce certificat contient : @@ -20799,7 +21377,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 Ko @@ -21021,19 +21599,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Options d'affichage d'arborescence - Show column... - Afficher la colonne... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Trier Ordre décroissant + + + + Sort Ascending Order + Trier Ordre croissant + + + + + [no title] + + + + + Show column … + + + + Show column... + Afficher la colonne... - [no title] - [pas de titre] + [pas de titre] @@ -21469,7 +22076,7 @@ p, li { white-space: pre-wrap; } Télécharger ! - + File Fichier @@ -21484,7 +22091,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Les mauvais noms de fichiers ont été nettoyé @@ -21534,7 +22141,7 @@ Les fichiers concernés sont affichés en rouge. Sauvegarder - + Collection Editor Éditeur de collection @@ -21549,7 +22156,7 @@ Les fichiers concernés sont affichés en rouge. Compte fichiers - + Real Size: Waiting child... Taille réelle : attente d'enfant... @@ -21564,12 +22171,12 @@ Les fichiers concernés sont affichés en rouge. Ceci est un dossier. Double-cliquez pour l'étendre. - + Download files Télécharger les fichiers - + Specify... Spécifier... @@ -21818,7 +22425,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich RsFriendListModel - + Name Nom @@ -21838,7 +22445,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich IP - + Profile ID @@ -21851,10 +22458,15 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich RsGxsForumModel - + Title Titre + + + UnRead + + Date @@ -21866,7 +22478,7 @@ Si vous pensez qu'il est correct, supprimez la ligne correspondante du fich Auteur - + Information for this identity is currently missing. Les informations pour cette identité sont actuellement manquantes. @@ -21904,7 +22516,7 @@ prevents the message to be forwarded to your friends. [Inconnu] - + [ ... Missing Message ... ] [ ... Message manquant... ] @@ -21912,7 +22524,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Date @@ -21972,7 +22584,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22331,7 +22943,7 @@ prevents the message to be forwarded to your friends. Nom du fichier - + Download Télécharger @@ -22410,7 +23022,7 @@ prevents the message to be forwarded to your friends. Ouvrir répertoire - + Create Collection... Créer une collection ... @@ -22430,7 +23042,7 @@ prevents the message to be forwarded to your friends. Télécharger à partir d'un fichier collection... - + Collection Collection @@ -22535,12 +23147,12 @@ prevents the message to be forwarded to your friends. Détails du contact - + Deny friend Refuser cet ami - + Chat Tchat @@ -22550,7 +23162,7 @@ prevents the message to be forwarded to your friends. Dialoguer - + Expand Déplier @@ -22820,13 +23432,13 @@ derrière un pare-feu ou un VPN (virtual private network). Découverte activée (recommandé) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor a été configuré automatiquement par Retroshare. Vous ne devriez rien avoir à changer ici. - + Discovery Off Découverte désactivée @@ -23315,7 +23927,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Network Réseau @@ -23343,7 +23955,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Status Statut @@ -23440,7 +24052,7 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs - + Service Address Adresse de service @@ -23475,12 +24087,12 @@ Si vous avez des soucis concernant la connexion via Tor, pensez à lire les logs Veuillez remplir par une adresse de service - + IP Range Plage d'IP - + Reported by DHT for IP masquerading Rapporté par la DHT concernant masquerading d'IP (se fait passer pour). @@ -24156,7 +24768,7 @@ p, li { white-space: pre-wrap; } Certificat PGP manquant - + Wrong password Mauvais mot de passe @@ -24210,7 +24822,7 @@ Ce choix peut être inversé dans des paramétrages. StatisticsWindow - + Add Friend Ajouter un ami @@ -24266,7 +24878,7 @@ Ce choix peut être inversé dans des paramétrages. Matrice des autorisations des services - + DHT DHT @@ -24806,7 +25418,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24820,13 +25432,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor est hors ligne actuellement - + Tor is OK Tor est OK @@ -24835,6 +25446,31 @@ p, li { white-space: pre-wrap; } No tor configuration Pas de configuration de Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25128,35 +25764,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Vous avez %1 téléchargements terminés + You have %1 completed transfers + - You have %1 completed download - Vous avez %1 téléchargement terminé + You have %1 completed transfer + - %1 completed downloads - %1 téléchargements terminés + %1 completed transfers + - %1 completed download - %1 téléchargement terminé + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Vous avez %1 téléchargements terminés + + + You have %1 completed download + Vous avez %1 téléchargement terminé + + + %1 completed downloads + %1 téléchargements terminés + + + %1 completed download + %1 téléchargement terminé TransfersDialog - + Downloads Téléchargements @@ -25167,7 +25814,7 @@ p, li { white-space: pre-wrap; } Envois - + Name i.e: file name Nom @@ -25378,7 +26025,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Partage de fichiers</h1> <p>Retroshare utilise deux modes de transfert de fichiers : les transferts directs depuis vos amis, et les transferts distants anonymes par tunnels. En plus, le transfert de fichier est multi-source et permet l'essaimage (vous pouvez être une source pendant le téléchargement) </p> <p>Vous pouvez partager des fichiers en utilisant l'icône <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> dans la barre latérale gauche. Ces fichiers seront listés dans l'onglet "Vos fichiers". Vous pouvez décider pour chaque groupe d'amis s'ils peuvent ou pas voir ces fichiers dans l'onglet Mes amis</p> <p>L'onglet "Rechercher" liste les fichiers de vos amis et des fichiers distants qui peuvent être atteints anonymement en utilisant le système à effet tunnel à sauts multiples.</p> - + Move in Queue... Mettre en file d'attente... @@ -25472,7 +26119,7 @@ p, li { white-space: pre-wrap; } S'il vous plaît entrez un nouveau--et valide--nomdefichier - + Expand all Tout déplier @@ -25604,7 +26251,7 @@ p, li { white-space: pre-wrap; } - + Columns Colonnes @@ -25615,7 +26262,7 @@ p, li { white-space: pre-wrap; } Transferts de fichiers - + Path Chemin @@ -25625,7 +26272,7 @@ p, li { white-space: pre-wrap; } Afficher la colonne des chemins - + Could not delete preview file N'a pas pu supprimer le fichier d'aperçu @@ -25635,7 +26282,7 @@ p, li { white-space: pre-wrap; } Le réessayer ? - + Create Collection... Créer une collection ... @@ -25650,7 +26297,7 @@ p, li { white-space: pre-wrap; } Vue collection ... - + Collection Collection @@ -25896,7 +26543,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Contact inconnu @@ -25992,7 +26639,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Vous avez %1 nouveaux messages @@ -26368,7 +27015,7 @@ p, li { white-space: pre-wrap; } Créer un groupe - + Subscribe to Group S'abonner au groupe @@ -26462,8 +27109,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Afficher l'historique des modifications @@ -26474,7 +27121,7 @@ p, li { white-space: pre-wrap; } - + Preview Aperçu @@ -26499,12 +27146,12 @@ p, li { white-space: pre-wrap; } Masquer l'historique des modifications - + Edit Page Modifier la page - + Create New Wiki Page Créer une nouvelle Page Wiki @@ -26524,7 +27171,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Créer un nouveau Groupe Wiki @@ -26566,7 +27213,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -26576,12 +27223,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Rafraîchir @@ -26616,12 +27262,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26691,7 +27337,7 @@ p, li { white-space: pre-wrap; } Affichage : - + Yourself Moi @@ -26729,7 +27375,7 @@ p, li { white-space: pre-wrap; } Publier Pulse sur Wire - + RetroShare @@ -26741,7 +27387,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26749,7 +27395,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26830,8 +27476,8 @@ p, li { white-space: pre-wrap; } Formulaire - - + + Avatar Avatar @@ -26860,6 +27506,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26972,8 +27623,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Images (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Images (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_hu.ts b/retroshare-gui/src/lang/retroshare_hu.ts index 80d818c8d..7ef052108 100644 --- a/retroshare-gui/src/lang/retroshare_hu.ts +++ b/retroshare-gui/src/lang/retroshare_hu.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare verzió @@ -79,7 +79,7 @@ Kezdődhet a móka! ;) - + Only Hidden Node Csak rejtett csomópont @@ -129,12 +129,12 @@ RetroShare: Összetett keresés - + Search Criteria Keresési feltétel - + Add a further search criterion. További keresési feltétel hozzáadása. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Forma - - + + TextLabel Címke @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Eszköztár - + Icon Only Csak ikonok @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Válaszd ki az Eszköztár gombjainak stílusát! - + Icon Size = 8x8 Ikon mérte: 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Ikon mérete: 128x128 - + Status Bar Állapotjelző sáv @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Értesítési Terület elemleírásának letiltása - + Main page items: Főoldal elemei: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista - + Icon Size = 32x32 Ikon mérete: 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Avatár csere - + + TextLabel + + + + Your Avatar Picture Az Avatárod - + + Browse... + + + Add Avatar - Avatár hozzáadása + Avatár hozzáadása @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Eltávolítás - + Set your Avatar picture Avatár beállítása - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatár betöltése + Avatár betöltése AvatarWidget - - Choose avatar - - - - + Click to change your avatar Kattints az avatár megváltoztatásához @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare sávszélesség használat + + + PushButton + + - + Up + Fel + + + + Down + Le + + + + Clears the graph + + + + Show Settings Beállítások megjelenítése + TextLabel + + + + Reset Visszaállítás - Receive Rate - Fogadási arány + Fogadási arány - Send Rate - Küldési arány + Küldési arány - + Always on Top Mindig felül - Style - Stílus + Stílus - + Changes the transparency of the Bandwidth Graph A sávszélesség grafikon átlátszóságának megváltoztatása - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % átlátszóság - Save - Mentés + Mentés - Cancel - Mégse + Mégse - + Since: Átvitel kezdete: - Hide Settings - Beállítások elrejtése + Beállítások elrejtése BandwidthStatsWidget - + Sum Összegzett @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } Számláló - + Average Átlag @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments Hozzászólások @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Tetszik + + + + 0 + 0 + + + + I dislike this + Nem tetszik + + + + Toggle Message Read Status + Üzenet olvasottságának váltása + + + + Avatar + Avatár + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Lenyitás + + + + Set as read and remove item + Megjelölés olvasottként és eltávolítás + + + + Remove Item + + + + + Name + Név + + + + Comm value + + + + + Comment + Hozzászólás + + + + Comments + Hozzászólások + + + + Hide + Elrejt + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale Napló mérték + + + Default + Alapértelmezett + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Tetszik + + + + 0 + 0 + + + + I dislike this + Nem tetszik + + + + Toggle Message Read Status + Üzenet olvasottságának váltása + + + + Avatar + Avatár + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Lenyitás + + + + Set as read and remove item + Megjelölés olvasottként és eltávolítás + + + + Remove Item + + + + + Name + Név + + + + Comm value + + + + + Comment + Hozzászólás + + + + Comments + Hozzászólások + + + + Hide + Elrejt + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Társalgószobák - You have %1 new messages - %1 új üzeneted van + %1 új üzeneted van + + + You have %1 new message + %1 új üzeneted van + + + %1 new messages + %1 új üzenet + + + %1 new message + %1 új üzenet + + + + You have %1 mentions + - You have %1 new message - %1 új üzeneted van + You have %1 mention + - %1 new messages - %1 új üzenet + %1 mentions + - %1 new message - %1 új üzenet + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Összes eltávolítása - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Kattints duplán egy társalgószobára a belépéshez. Változat: - Group chat - Csoportos beszélgetés + Csoportos beszélgetés - - + Private chat Privát beszélgetés @@ -2191,17 +2404,16 @@ Kattints duplán egy társalgószobára a belépéshez. Felhasználónév elküldése ezzel: /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Ezen a fülön beállíthatod, hogy a különböző típusú üzenetekből mennyit tároljon el a RetroShare a merevlemezen és hogy mennyi előző beszélgetést állítson vissza az aktuális ablakba. A maximális tárolási idő beállítása lehetővé teszi a régi üzenetek mellőzését, illetve segít megakadályozni, hogy az előzmények tele legyenek kevésbé fontos beszélgetésekkel (például egyes társalgószobák vagy távoli üzenetek előzményei). </p></body></html> - Chatlobbies - Társalgószobák + Társalgószobák - + Enabled: Engedélyezve: @@ -2222,11 +2434,12 @@ Kattints duplán egy társalgószobára a belépéshez. + Chat rooms Társalgószobák - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Kattints duplán egy társalgószobára a belépéshez. + Broadcast Üzenőfal - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Elmentett üzenetek (0 = végtelen): @@ -2438,8 +2657,23 @@ Kattints duplán egy társalgószobára a belépéshez. Privát beszélgetés - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Kattints duplán egy társalgószobára a belépéshez. - + is typing... éppen ír... @@ -2631,12 +2865,12 @@ after HTML conversion. a HTML átalakítás után. - + Choose your font. Válassz betütípust. - + Do you really want to physically delete the history? Tényleg törölni akarod az előzményeket? @@ -2708,7 +2942,7 @@ a HTML átalakítás után. Ne hagyd abba a színezést X elem megtalálása után (több CPU erőforrás szükséges) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Előző keresése </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ a HTML átalakítás után. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Kiválasztott szöveg megjelölése</b><br><i>Ctrl+M</i> - + Person id: Személyazonosító @@ -2770,7 +3004,7 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.Aláiratlan - + items found. találat. @@ -2790,7 +3024,7 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.Írj be egy üzenetet ide - + Don't stop to color after Ne állj le a színezéssel, miután @@ -2948,12 +3182,12 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz. ConfCertDialog - + Details Részletek - + Local Address Helyi cím @@ -2964,12 +3198,12 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.Külső cím - + Node info: Csomópont adatai: - + Current address: Jelenlegi cím: @@ -2985,31 +3219,36 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.Port - + Include signatures Aláírásokat tartalmaz - + RetroShare RetroShare - + - + Error : cannot get peer details. Hiba: a partner adatai nem elérhetőek. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Titkosítás - + Not connected Nem csatlakozott - + Retroshare node details Retroshare csomópont részletei - + Node name : Csomópont neve : @@ -3075,13 +3319,18 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.Állapot üzenet: - + + Connectivity + + + + List of known addresses: Ismert címek felsorolása: - - + + Retroshare Certificate Retroshare tanúsítvány @@ -3096,7 +3345,7 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz. - + Hidden Address Rejtett cím @@ -3107,11 +3356,12 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.nincs + <p>This certificate contains: - <p>Ez a tanúsítvány tartalmaz: + <p>Ez a tanúsítvány tartalmaz: - + <li>a <b>node ID</b> and <b>name</b> <li>egy <b>csomópont azonosítót</b> és <b>nevet</b> @@ -3124,12 +3374,12 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.egy <b>IP címet</b> és <b>portot</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Használd ezt a tanúsítványt, hogy új barátokat szerezz. Küldd el emailben, vagy juttasd el a címzettnek egyéb módon.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Ez egy csomópont <span style=" font-weight:600;">OpenSSL</span> tanúsítvánnyal ellátott azonosítója, amely a fenti <span style=" font-weight:600;">PGP</span> kulccsal lett aláírva. </p></body></html> @@ -3139,7 +3389,7 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.<html><head/><body><p>Ez az <span style=" font-weight:600;">OpenSSL</span> által használt titkosítási eljárás. Az összeköttetés a barátok csomópontjaihoz</p><p>mindig erősen titkosított és ha a DHE jelen van, akkor az összeköttetés további </p><p>&quot;tökéletes továbbítási titkosítást&quot;.</p> használ.</body></html> - + with ­ @@ -3345,12 +3595,12 @@ A nevet kettős kattintással hozzáadhatod a szövegszerkesztőhöz.A kérelem részletei - + Peer details Partner részletei - + Name: Név: @@ -3369,12 +3619,12 @@ resources. erőforrást igényel. - + Location: Hely: - + Options Beállítások @@ -3411,12 +3661,12 @@ erőforrást igényel. Tanúsítvány beillesztése - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>A mezőbe a barátod Retroshare tanúsítványát illeszd be. FIGYELEM: ez különbözik a barátod profil kulcsától. Ne illeszd be ide a barátod profil kulcsát (vagy annak egy részét), mert nem fog működni!</p></body></html> - + Add friend to group: Barát hozzáadása a csoporthoz: @@ -3426,7 +3676,7 @@ erőforrást igényel. Barát azonosítása (PGP kulcs aláírása) - + Please paste below your friend's Retroshare ID @@ -3451,7 +3701,7 @@ erőforrást igényel. - + Add as friend to connect with Barát hozzáadása @@ -3460,7 +3710,7 @@ erőforrást igényel. A baráti kérelem elfogadásához kattints a Kész gombra. - + Sorry, some error appeared Sajnálom, hiba történt @@ -3480,32 +3730,32 @@ erőforrást igényel. A barátod részletei: - + Key validity: Kulcs érvényessége: - + Profile ID: - + Signers Aláírók - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Az aláírások kriptográfiailag bizonyítják, hogy az alábbi kulcsok hitelesnek ismerik el az aktuális PGP kulcsot.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. A személy már szerepel a barátlistádon. Az újbóli felvétele csak az IP címét fogja változtatni. - + To accept the Friend Request, click the Accept button. @@ -3551,7 +3801,7 @@ erőforrást igényel. - + Certificate Load Failed A tanúsítvány betöltése sikertelen @@ -3588,12 +3838,12 @@ erőforrást igényel. Úgy tűnik, érvényes a tanúsítvány - + Not a valid Retroshare certificate! Érvénytelen Retroshare tanúsítvány! - + RetroShare Invitation RetroShare meghívás @@ -3615,12 +3865,12 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Ez a saját tanusítványod! Ugye nem saját magadat akarod ismerősként megadni?! - + @@ -3668,7 +3918,37 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Van egy barát felkérésed tőle - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3756,12 +4036,12 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Közvetlen forrásként használat, amikor lehetséges - + IP-Addr: IP-cím: - + IP-Address IP-cím: @@ -3827,7 +4107,7 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Kulcs hozzáadása a kulcstartóhoz - + This key is already in your keyring Ez a kulcs már szerepel a kulcstartódban @@ -3888,12 +4168,12 @@ távoli üzeneteket szeretnél küldeni ennek a partnernek, <p>Ez a tanúsítvány nem tartalmaz IP-t. A felfedezésre és a DHT-re vagy utalva, hogy megtaláld. Mivel fehérlistás engedélyezést kértél, ezért egy biztonsági figyelmeztetést fogsz kapni a Hírek fülön. Itt hozzáadhatod a partner IP-jét a fehérlistához.</p> - + [Unknown] [Ismeretlen] - + Added with certificate from %1 Tanúsítvánnyal hozzáadva innen: %1 @@ -3980,7 +4260,12 @@ távoli üzeneteket szeretnél küldeni ennek a partnernek, UDP kapcsolat eredménye - + + Status + Állapot + + + <!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; } @@ -4402,7 +4687,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4554,7 +4839,7 @@ p, li { white-space: pre-wrap; } Nincs határ kiválasztva. - + [Unknown] [Ismeretlen] @@ -4569,7 +4854,7 @@ p, li { white-space: pre-wrap; } Eltávolítás - + Search Keresés @@ -4589,7 +4874,7 @@ p, li { white-space: pre-wrap; } Ismert csomópontok által aláírva - + Edit Circle Kör szerkesztése @@ -4609,12 +4894,12 @@ p, li { white-space: pre-wrap; } Névtelen azonosító - + Circle name Kör neve - + Update Frissít @@ -4640,7 +4925,7 @@ p, li { white-space: pre-wrap; } PGP-hez linkelt azonosító - + Add Member Tag hozzáadása @@ -4784,7 +5069,7 @@ p, li { white-space: pre-wrap; } - + Attachments Mellékletek @@ -4830,7 +5115,7 @@ p, li { white-space: pre-wrap; } Fájlok megragadása és bedobása a keresési találatokból - + Paste RetroShare Links RetroShare linkek beillesztése @@ -4840,7 +5125,7 @@ p, li { white-space: pre-wrap; } RetroShare hivatkozás beillesztése - + Drop file error. Hibás hozzáadás. @@ -4867,17 +5152,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - A fájl már hozzá van adva és hashelve van. + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + A fájl már hozzá van adva és hashelve van. + + + Please add a Subject Kérlek, adj meg egy tárgyat @@ -4908,12 +5217,12 @@ p, li { white-space: pre-wrap; } Valóban generálni szeretnél %1 üzenetet ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Fájlokat fogsz hozzáadni a megosztásodhoz. Biztos ezt szeretnéd tenni? - + Edit Channel Post Csatornabejegyzés létrehozása @@ -4933,7 +5242,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Nem birtokolt fájlok beküldése a csatornára. @@ -5025,7 +5334,7 @@ p, li { white-space: pre-wrap; } - + No Forum Nincs fórum @@ -5479,7 +5788,7 @@ az importálás gombot, hogy betöltsd. DHTGraphSource - + users felhasználók @@ -6482,7 +6791,7 @@ az importálás gombot, hogy betöltsd. FlatStyle_RDM - + Friends Directories Barátok mappái @@ -6988,7 +7297,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Barát keresése - + Mark all Jelöld mind @@ -7002,7 +7311,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz FriendsDialog - + Edit status message Állapot szerkesztése @@ -7106,7 +7415,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Retroshare üzenőfal: az ide írt üzeneteidet az összes barátod láthatja. - + Network Hálózat @@ -7171,7 +7480,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz A csomópont mező legalább 3 karaktert kell tartalmazzon - + Failed to generate your new certificate, maybe PGP password is wrong! Az új tanúsítványod létrehozása meghiúsult, talán rossz PGP jelszót adtál meg. @@ -7214,7 +7523,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Meglévő profil használata - + Node name Csomópont neve @@ -7481,12 +7790,12 @@ Most már átmásolhatod egy másik számítógépre - + Profile generation failure A profil létrehozása meghiúsult - + Missing PGP certificate Hiányzó PGP tanusítvány @@ -7864,7 +8173,7 @@ p, li { white-space: pre-wrap; } Útválasztó statisztikái - + GroupBox @@ -7929,7 +8238,7 @@ p, li { white-space: pre-wrap; } - + Details Részletek @@ -7952,7 +8261,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Nyilvántartott kulcsok @@ -8153,7 +8462,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Cím @@ -8163,13 +8472,30 @@ p, li { white-space: pre-wrap; } Cím keresése - - + + + + Description Leírás - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Leírás keresése @@ -8179,42 +8505,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Csökkenő sorbarendezés + Csökkenő sorbarendezés - Sort Ascending Order - Növekvő sorbarendezés + Növekvő sorbarendezés - Sort by Name - Rendezés név szerint + Rendezés név szerint - Sort by Popularity - Rendezés népszerűség szerint + Rendezés népszerűség szerint - Sort by Last Post - Rendezés utolsó üzenet szerint + Rendezés utolsó üzenet szerint - Sort by Number of Posts - Bejegyzések száma szerinti rendezés + Bejegyzések száma szerinti rendezés - Sort by Unread - Olvasatlanság szerinti rendezés + Olvasatlanság szerinti rendezés - + You are admin (modify names and description using Edit menu) @@ -8229,40 +8548,35 @@ p, li { white-space: pre-wrap; } Azonosító - - + + Last Post Utolsó bejegyzés - + + Name Név - - Unread - - - - + Popularity - - + + Never Soha - Display - Megjelenítés beállításai + Megjelenítés beállításai - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8411,7 +8725,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Csatornák @@ -8432,12 +8746,12 @@ p, li { white-space: pre-wrap; } Csatornáim - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Feliratkozások @@ -8938,7 +9252,7 @@ p, li { white-space: pre-wrap; } - + Add new post Új hozzászólás @@ -9038,12 +9352,12 @@ p, li { white-space: pre-wrap; } - + Files Fájlok - + Comments Hozzászólások @@ -9054,18 +9368,18 @@ p, li { white-space: pre-wrap; } - + Feeds Hírcsatornák - - + + Click to switch to list view - + Show unread posts only @@ -9075,12 +9389,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9140,7 +9454,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9155,12 +9469,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9236,23 +9550,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Feliratkozva - - Subscribe Feliratkozás - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nincs csatorna kiválasztva @@ -9274,11 +9601,6 @@ p, li { white-space: pre-wrap; } Channel Post Üzenet - - - new message(s) - - GxsCircleItem @@ -9804,7 +10126,7 @@ mielőtt hozzászólhatsz Új fonál indítása a kiválasztotta fórumban - + Search forums Fórumok keresése @@ -9813,12 +10135,12 @@ mielőtt hozzászólhatsz Utolsó beküldés - + New Thread Új szál - + Threaded View Fa nézet @@ -9828,19 +10150,19 @@ mielőtt hozzászólhatsz Egyszerű nézet - - + + Title Cím - - + + Date Dátum - + Author Szerző @@ -9855,7 +10177,17 @@ mielőtt hozzászólhatsz Töltés - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9912,23 +10244,23 @@ mielőtt hozzászólhatsz Tartalom keresése - + No name Nincs név - - + + Reply Válasz - + <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> - + Loading... @@ -9966,12 +10298,12 @@ mielőtt hozzászólhatsz Megjelölés olvasatlanként - + Copy RetroShare Link RetroShare hivatkozás másolása - + Hide Elrejt @@ -9984,7 +10316,7 @@ mielőtt hozzászólhatsz [Letiltva] - + [unknown] [ismeretlen] @@ -10014,8 +10346,8 @@ mielőtt hozzászólhatsz - - + + Distribution @@ -10118,7 +10450,7 @@ mielőtt hozzászólhatsz Eredeti üzenet - + New thread Új szál @@ -10127,7 +10459,7 @@ mielőtt hozzászólhatsz Elolvasott / nem olvasott - + Edit Szerkesztés @@ -10183,7 +10515,7 @@ mielőtt hozzászólhatsz Mutasd a szerzőt a Személyek fülön - + Author's reputation Szerző megitélése @@ -10203,7 +10535,7 @@ mielőtt hozzászólhatsz - + <b>Loading...<b> @@ -10243,6 +10575,11 @@ mielőtt hozzászólhatsz Storage Tárolás + + + Last seen at friends: + + Moderators @@ -10320,7 +10657,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. %1, %2 írta: - + Forum name Fórum címe @@ -10352,11 +10689,6 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Forum Post Fórum hozzászólás - - - new message(s) - - GxsForumsDialog @@ -10797,7 +11129,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Nyomtatási kép - + Unsubscribe Leiratkozás @@ -10812,7 +11144,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Megnyitás új fülön - + Remove this search @@ -10822,12 +11154,12 @@ megjelenítve és nem lesz továbbítva a barátaid számára. - + Request data - + Show Details Mutasd a részleteket @@ -10894,7 +11226,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. - + Search for @@ -10903,7 +11235,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Nyilvános engedélyek megosztása - + Copy RetroShare Link RetroShare hivatkozás másolása @@ -10918,7 +11250,7 @@ megjelenítve és nem lesz továbbítva a barátaid számára. Összes megjelölése olvasatlanként - + AUTHD HITELESÍTETT @@ -11519,7 +11851,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11528,7 +11860,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11554,7 +11886,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11632,27 +11964,32 @@ p, li { white-space: pre-wrap; } Forma - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11674,6 +12011,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11682,7 +12020,7 @@ p, li { white-space: pre-wrap; } Az alábbi szöveghalmaz a te RetroShare tanusítványod. Küld el a barátaidnak. - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11699,12 +12037,12 @@ privát és biztonságos decentralizált kommunikációt nyújtó szolgáltatás Segítségre van szükséged? - + Open Web Help Nyisd meg a segítség honlapot - + Copy your Cert to Clipboard Tanúsítványod másolása a vágólapra @@ -11752,17 +12090,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11777,7 +12110,12 @@ new short format RetroShare meghívó - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Mentés mint... @@ -12042,14 +12380,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Összes - + Reputation Népszerűség @@ -12059,12 +12397,12 @@ p, li { white-space: pre-wrap; } Keresés - + Anonymous Id Névtelen azonosító - + Create new Identity Új személyazonosság létrehozása @@ -12208,7 +12546,7 @@ p, li { white-space: pre-wrap; } Személyazonosság azonosító - + Send message Üzenet elküldése @@ -12280,7 +12618,7 @@ p, li { white-space: pre-wrap; } Általánosan - + Anonymous Névtelen @@ -12295,24 +12633,24 @@ p, li { white-space: pre-wrap; } Azonosító keresése - + This identity is owned by you Ez a személyazonosság a tiéd - - + + My own identities Saját személyazonosságaim - - + + My contacts Kapcsolataim - + Show Items Elemek megjelenítése @@ -12327,7 +12665,7 @@ p, li { white-space: pre-wrap; } - + Other circles Más körök @@ -12386,13 +12724,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: Tagsági állapotod: @@ -12452,7 +12795,7 @@ p, li { white-space: pre-wrap; } Tag - + Edit Circle Kör szerkesztése @@ -12500,7 +12843,7 @@ p, li { white-space: pre-wrap; } Tagság megadása - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12512,12 +12855,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + [Unknown node] [Ismeretlen csomópont] - + Unverified signature from node A csomópont aláírása nem hitelesített @@ -12529,12 +12872,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ellenőrizetlen aláírás - + [unverified] [hitelesítetlen] - + Identity owned by you, linked to your Retroshare node A te személyazonosságod, linkelve a Retroshare csomópontodhoz @@ -12654,12 +12997,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Küldesz meghívót - + Banned Letiltva - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Személyazonosságok</h1> <p>Ezen a fülön készíthetsz új vagy szerkesztheted a már meglévő <b>ál-névtelen személyazonosságokat</b>, és <b>köröket</b>.</p> <p>A <b>személyazonosságokat</b> használjuk az adataid biztonságos azonosításához: aláírják az üzeneteid a társalgószobákban, a fórum- és csatorna hozzászólásaidat, visszajelzést kapnak a Retroshare beépített e-mail rendszerén keresztül, hozzászólhatsz csatorna bejegyzésekhez, biztonságos alagutakon keresztül beszélgethetsz, stb.</p> <p>Személyazonosságaidat<b>aláírhatod</b> a Retroshare csomópontod tanúsítványával. Az aláírt Személyazonosságok jobban ellenőrizhetőbbek ezért megbízhatóbbnak számíthatnak, ugyanakkor hozzá vannak kapcsolva a csomópontod IP címéhez.</p> <p>Az úgynevezett<b>Álnevek</b> segítségével névtelenséged megőrzésével léphetsz kapcsolatba a többiekkel. Nem visszakereshető, ezáltal senki sem tudhatja, hogy pontosan kihez is tartozik egy ilyen személyazonosság.</p> <p>A <b>Körök</b> tulajdonképpen a hálózat személyazonosságainak (Álnév típusú, vagy aláírt) részhalmazai. Felhasználhatók arra, hogy szigorítsuk a hozzáférést egy fórumhoz, csatornához, stb. </p> <p>Egy <b>kör</b> szűkíthető további körökkel, ezáltal láthatatlanná téve bizonyos tartalmakat olyanok számára akik nem tagjai a szűkebb köröknek. Sőt egy kör önmaga is lehet korlátozott, ez azt jelenti, hogy csak a meghívott személyek számára lesz látható a tartalom.</p> @@ -12668,7 +13011,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ismeretlen azonosító: - + positive @@ -12837,8 +13180,8 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - - + + People Személyek @@ -12849,7 +13192,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Saját avatár - + Linked to neighbor nodes @@ -12859,7 +13202,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Linked to a friend Retroshare node @@ -12919,7 +13262,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Node name: @@ -12929,7 +13272,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Csomópont azonosító : - + Really delete? Tényleg törlöd? @@ -12967,7 +13310,22 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Álnév - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Új személyazonosság @@ -12984,14 +13342,14 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + N/A N/A - + Edit identity Személyazonosság szerkesztése @@ -13002,24 +13360,27 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Frissít - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13038,17 +13399,27 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Hiba a kulcs beolvasásakor! - + Error KeyID invalid Hiba, érvénytelen Kulcs azonosító - + Unknown GpgId Ismeretlen Gpg azonosító @@ -13058,7 +13429,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Ismeretlen igazi név - + Create New Identity Új személyazonosság létrehozása @@ -13068,7 +13439,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Típus - + + Choose image... + + + + @@ -13108,12 +13484,11 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Saját avatár - Set Avatar - Avatár beállítása + Avatár beállítása - + Linked to your profile @@ -13123,7 +13498,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Rendelkezhetsz egy vagy több személyazonossággal. Írhatsz velük társalgószobákba, hozzászólhatsz fórumokhoz és csatorna bejegyzésekhez. Végpontként viselkednek távoli beszélgetések valamint Retroshare távoli üzenetküldés esetén. - + The nickname is too short. Please input at least %1 characters. @@ -13232,8 +13607,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. + Quote + Idézés + + Send - Küldés + Küldés @@ -13391,7 +13770,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Options Beállítások @@ -13423,12 +13802,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Gyors beállítások varázsló - + RetroShare %1 a secure decentralized communication platform RetroShare %1 egy biztonságos, központosítatlan kommunikációs platform - + Unfinished Befejezetlen @@ -13561,7 +13940,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Mutat - + Make sure this link has not been forged to drag you to a malicious website. Bizonyosodj meg róla, hogy ez a hivatkozás nem egy veszélyes weboldalra mutat. @@ -13606,7 +13985,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Szolgáltatás jogosultságok mátrix - + Statistics Statisztika @@ -13635,7 +14014,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.MessageComposer - + Compose Írás @@ -13737,7 +14116,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Tags Címkék @@ -13832,12 +14211,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Hosszabb idézet - + Send To: Küldés neki: - + &Left &Bal @@ -13871,7 +14250,7 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból.Kapcsolataim - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Szia,<br>Szeretném a figyelmedbe ajánlani egy barátomat. Ha bennem megbízol, benne is megbízhatsz. <br> @@ -13897,12 +14276,12 @@ Ezek a személyazonosságok hamarosan kikerülnek a támogatásból. - + Save Message Üzenet mentése - + Message has not been Sent. Do you want to save message to draft box? Az üzenet nem lett elküldve. @@ -13914,7 +14293,7 @@ Szeretnéd piszkozatként menteni az üzenetet? RetroShare link beillesztése - + Add to "To" Hozzáadás címzettként @@ -14169,7 +14548,7 @@ Szeretnéd menteni az üzenetet? Extra fájl hozzáadása - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -14178,12 +14557,27 @@ Szeretnéd menteni az üzenetet? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Van egy barát felkérésed - + Respond now: Válasz most: @@ -14199,11 +14593,12 @@ Szeretnéd menteni az üzenetet? Feladó: + Friend Nodes - Barát csomópontok + Barát csomópontok - + Bullet list (disc) @@ -14243,13 +14638,13 @@ Szeretnéd menteni az üzenetet? - - + + Thanks, <br> Kösz, <br> - + Distant identity: Távoli személyazonosság: @@ -14388,8 +14783,23 @@ Szeretnéd menteni az üzenetet? Üzenet - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14401,12 +14811,12 @@ Szeretnéd menteni az üzenetet? Ajánlott fájlok - + Download all Recommended Files Az összes ajánlott fájl letöltése - + Subject: Tárgy: @@ -14481,12 +14891,18 @@ Szeretnéd menteni az üzenetet? Meghívó küldése - + + Message Size: + + + + File Name Fájlnév - + + Size Méret @@ -14547,22 +14963,37 @@ Szeretnéd menteni az üzenetet? Letöltés - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Küldesz meghívót? - + Download all Az összes letöltése - + Print Document Dokumentum nyomtatása @@ -14577,7 +15008,7 @@ Szeretnéd menteni az üzenetet? Html-Fájlok (*.htm *.html);;Összes fájl (*) - + Load images always for this message Ezen üzenethez mindig töltse be a képeket @@ -14718,7 +15149,7 @@ Szeretnéd menteni az üzenetet? MessagesDialog - + New Message Új üzenet @@ -14774,14 +15205,14 @@ Szeretnéd menteni az üzenetet? - + Tags Címkék - + Inbox Beérkezett üzenetek @@ -14876,7 +15307,7 @@ Szeretnéd menteni az üzenetet? Üzenet továbbítása - + Subject Tárgy @@ -14988,7 +15419,7 @@ Szeretnéd menteni az üzenetet? - + Open in a new window Megnyitás új ablakban @@ -15073,7 +15504,7 @@ Szeretnéd menteni az üzenetet? - + Drafts Piszkozatok @@ -15194,7 +15625,7 @@ Szeretnéd menteni az üzenetet? Válasz - + Delete Message Üzenet törlése @@ -15205,7 +15636,7 @@ Szeretnéd menteni az üzenetet? - + Expand Lenyitás @@ -15215,7 +15646,7 @@ Szeretnéd menteni az üzenetet? Eltávolítás - + from tőle @@ -15224,6 +15655,11 @@ Szeretnéd menteni az üzenetet? Reply to invite Válaszolj a meghívásra + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15541,7 +15977,7 @@ Reported error: - + Groups Csoportok @@ -15571,19 +16007,19 @@ Reported error: barátlista visszaállítása a megtartott csoportokkal - - + + Search Keresés - + ID Azonosító - + Search ID Azonosító keresése @@ -15593,7 +16029,7 @@ Reported error: - + Show Items Elemek megjelenítése @@ -15797,19 +16233,19 @@ legalább egy partner nem lett hozzáadva a csoporthoz - + Error Hiba - + File is not writeable! A fájl nem írható! - + File is not readable! A fájl nem olvasható! @@ -15847,9 +16283,13 @@ legalább egy partner nem lett hozzáadva a csoporthoz NewsFeed - Log entries - Naplóbejegyzések + Naplóbejegyzések + + + + Activity Stream + @@ -15866,7 +16306,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Ez egy teszt. - + Newest on top A legújabb felül @@ -15877,20 +16317,39 @@ legalább egy partner nem lett hozzáadva a csoporthoz - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log - Napló + Napló + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15927,22 +16386,22 @@ legalább egy partner nem lett hozzáadva a csoporthoz - + Test Teszt - + Chat Room Társalgószoba - + Systray Icon Tálca ikon - + Message Üzenet @@ -15967,12 +16426,11 @@ legalább egy partner nem lett hozzáadva a csoporthoz IP biztonság - Log - Napló + Napló - + Friend Connected Kapcsolódó ismerős @@ -15986,7 +16444,12 @@ legalább egy partner nem lett hozzáadva a csoporthoz Hivatkozások - + + Activity + + + + Mails Levelek @@ -16023,7 +16486,12 @@ legalább egy partner nem lett hozzáadva a csoporthoz Csoport beszélgetés - + + Toaster position + + + + Chat rooms Társalgószobák @@ -16036,22 +16504,22 @@ legalább egy partner nem lett hozzáadva a csoporthoz Kis- és nagybetű érzékeny - + Position Pozíció - + X Margin X margó - + Y Margin Y margó - + Systray message Tálca üzenet @@ -16101,7 +16569,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Értesítés - + Disable All Toasters @@ -16115,7 +16583,7 @@ legalább egy partner nem lett hozzáadva a csoporthoz Hírcsatorna - + Systray Rendszertálca @@ -16257,17 +16725,16 @@ legalább egy partner nem lett hozzáadva a csoporthoz PGPKeyDialog - Dialog - Párbeszéd + Párbeszéd - + Profile info Profil adatok - + Name : Név : @@ -16322,22 +16789,21 @@ legalább egy partner nem lett hozzáadva a csoporthoz Teljes - + This profile has signed your own profile key - Key signatures : - Kulcs aláírások: + Kulcs aláírások: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta: ez egyfajta segítség is a többiek számára. Az aláírások kriptográfiailag bizonyítják, hogy az alábbi kulcsok hitelesnek ismerik el az aktuális PGP kulcsot.</span></p></body></html> - + <!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; } @@ -16351,7 +16817,7 @@ p, li { white-space: pre-wrap; } Írd alá a kulcsot - + PGP key PGP kulcs @@ -16361,22 +16827,20 @@ p, li { white-space: pre-wrap; } Ezek a beállítások a következő profil összes csomópontjára érvényesek: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Ez segíthet nekik eldönteni, hogy elfogadják-e a kapcsolódást az adott kulcs tulajdonosától. Egy kulcs aláírása csak egy lehetőség, de visszavonhatatlan. Ezért fontold meg és dönts okosan.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">A barátod kulcsának aláírása alkalmas arra, hogy kifejezd a bizalmad iránta és ezt jelezd a többiek felé. Ez segíthet nekik eldönteni, hogy elfogadják-e a kapcsolódást az adott kulcs tulajdonosától. Egy kulcs aláírása csak egy lehetőség, de visszavonhatatlan. Ezért fontold meg és dönts okosan.</span></p></body></html> - + Keysigning: - Sign PGP key - PGP kulcs aláírása + PGP kulcs aláírása - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16396,7 +16860,7 @@ p, li { white-space: pre-wrap; } Kapcsolatok elfogadása - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16466,28 +16930,28 @@ p, li { white-space: pre-wrap; } kB/másodpercenként - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Hiba: a partner adatai nem elérhetőek. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) A RetroShare nem támogatja a kulcsot. (Jelenleg csak RSA kulcsok engedélyezettek) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16501,7 +16965,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16546,27 +17010,47 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Hibás aláírás - - Maybe password is wrong - Talán rossz a jelszó + + Check the password! + - + Maybe password is wrong + Talán rossz a jelszó + + + You haven't set a trust level for this key. - + + Retroshare profile RetroShare profil - + This is your own PGP key, and it is signed by : @@ -16745,8 +17229,7 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen PeopleDialog - - + People Személyek @@ -16763,7 +17246,7 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Belső - + Chat with this person Beszélgetés ezzel a személlyel @@ -16910,7 +17393,7 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Fénykép - + TextLabel Címke @@ -16954,8 +17437,8 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen - <N> Comments >> - + Comments + Hozzászólások @@ -16990,6 +17473,11 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Write a comment... Hozzászólás írása... + + + Album + Album + PhotoItem @@ -16999,12 +17487,12 @@ Figyelmeztetés: az Átvitel beállításainál Nem engedélyezted a közvetlen Forma - + TextLabel Címke - + <!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; } @@ -17100,7 +17588,7 @@ p, li { white-space: pre-wrap; } Fénykép megnézése - + PhotoShare Fényképmegosztás @@ -17140,7 +17628,7 @@ requesting to edit it! - + Stop Megállítás @@ -17368,12 +17856,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Összes beépülő engedélyezése - + Plugin look-up directories Beéplők könyvtárai @@ -17423,7 +17911,7 @@ lesznek ellenőrízve. Alapállapotban a hash érték ellenőrzése megvéd a kártevőként működő beépülők használatától. - + Plugins Beépülők @@ -17805,7 +18293,7 @@ a kártevőként működő beépülők használatától. Hivatkozások - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17968,13 +18456,13 @@ a kártevőként működő beépülők használatától. Oldal - - + + Comments Hozzászólások - + Copy RetroShare Link @@ -17984,7 +18472,7 @@ a kártevőként működő beépülők használatától. Mutasd a szerzőt a Személyek fülön - + Comment Hozzászólás @@ -18005,12 +18493,12 @@ a kártevőként működő beépülők használatától. - + Hide Elrejt - + Vote up Szavazás mellette @@ -18024,7 +18512,7 @@ a kártevőként működő beépülők használatától. \/ - + Set as read and remove item Megjelölés olvasottként és eltávolítás @@ -18085,7 +18573,7 @@ a kártevőként működő beépülők használatától. - + Loading Töltés @@ -18175,13 +18663,7 @@ a kártevőként működő beépülők használatától. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18191,60 +18673,50 @@ a kártevőként működő beépülők használatától. Adminisztrátor: - - - + + + unknown ismeretlen - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Bejegyzések @@ -18255,7 +18727,7 @@ a kártevőként működő beépülők használatától. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18324,7 +18796,12 @@ a kártevőként működő beépülők használatától. - + + Empty + Üres + + + Copy RetroShare Link @@ -18359,7 +18836,7 @@ a kártevőként működő beépülők használatától. - + [No name] @@ -18487,8 +18964,18 @@ a kártevőként működő beépülők használatától. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18758,9 +19245,8 @@ az importálás gombot, hogy betöltsd. PulseAddDialog - Post From: - Küldés ebből: + Küldés ebből: Account 1 @@ -18775,7 +19261,7 @@ az importálás gombot, hogy betöltsd. Profil 3 - + Add to Pulse Pulzushoz adás @@ -18798,17 +19284,32 @@ az importálás gombot, hogy betöltsd. URL - + GroupLabel - + IDLabel - + + From: + Feladó: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18833,10 +19334,20 @@ az importálás gombot, hogy betöltsd. rossz - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18846,14 +19357,53 @@ az importálás gombot, hogy betöltsd. - + + Post + + + + Cancel Mégse - Post Pulse to Wire - Pulzus küldése a vezetékhez + Pulzus küldése a vezetékhez + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18879,10 +19429,18 @@ az importálás gombot, hogy betöltsd. Forma - - - - + + + + + Click to view picture + + + + + + + Image Kép @@ -18890,44 +19448,44 @@ az importálás gombot, hogy betöltsd. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18937,17 +19495,17 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18957,7 +19515,7 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18965,7 +19523,7 @@ az importálás gombot, hogy betöltsd. PulseTopLevel - + retweeted @@ -18980,7 +19538,7 @@ az importálás gombot, hogy betöltsd. - + follow Parent Group @@ -18990,7 +19548,7 @@ az importálás gombot, hogy betöltsd. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19015,7 +19573,7 @@ az importálás gombot, hogy betöltsd. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19051,29 +19609,29 @@ az importálás gombot, hogy betöltsd. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19151,7 +19709,7 @@ az importálás gombot, hogy betöltsd. QObject - + Confirmation Megerősítés @@ -19393,7 +19951,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek le lesznek cs Eredmény - + Unable to make path Hibás útvonal @@ -19428,7 +19986,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek le lesznek cs Fájl kérése megszakítva - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. A RetroShare ezen verziója OpenPGP-SDK-t használ. Ennek hála, nem használja a rendszer PGP kulcstartóját, viszont van egy saját kulcstartója, amit az összes futó RetroShare elérhet. <br><br>Úgy tűnik, hogy még nem rendelkezel ilyen kulcstartóval annak ellenére, hogy már létrehozott RetroShare fiókjaidban szerepelnek PGP kulcsok. Ez valószínűleg azért lehetséges, mert most frissítettél az alkalmazás új verziójára. @@ -19575,7 +20133,7 @@ A hibajelentés: másodpercek - + TR up @@ -19620,7 +20178,7 @@ A hibajelentés: leállítva - + Move IP %1 to whitelist @@ -19636,7 +20194,7 @@ A hibajelentés: - + %1 seconds ago %1 másodperccel ezelőtt @@ -19721,7 +20279,7 @@ Biztonság: névtelen azonosítók nem engedélyezettek - + Error Hiba @@ -20112,9 +20670,8 @@ Biztonság: névtelen azonosítók nem engedélyezettek - <p>This certificate contains: - <p>Ez a tanúsítvány tartalmaz: + <p>Ez a tanúsítvány tartalmaz: @@ -20488,7 +21045,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20710,19 +21267,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Fa nézet beállítása - Show column... - Mutatandó oszlop... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Csökkenő sorbarendezés + + + + Sort Ascending Order + Növekvő sorbarendezés + + + + + [no title] + + + + + Show column … + + + + Show column... + Mutatandó oszlop... - [no title] - [nincs cím] + [nincs cím] @@ -21158,7 +21744,7 @@ p, li { white-space: pre-wrap; } Letöltés! - + File Fájl @@ -21173,7 +21759,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Rossz fájlnevek javítva @@ -21223,7 +21809,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Mentés - + Collection Editor Kollekció szerkesztő @@ -21238,7 +21824,7 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Fájlok száma - + Real Size: Waiting child... Valódi méret: Várakozás a gyerekre... @@ -21253,12 +21839,12 @@ A <b>",|,/,\,&lt;,&gt;,*,?</b> karakterek '_' Ez egy könyvtár. Kattints duplán a kibontásához. - + Download files Fájlok letöltése - + Specify... Meghatározás... @@ -21505,7 +22091,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Név @@ -21525,7 +22111,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21538,10 +22124,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Cím + + + UnRead + + Date @@ -21553,7 +22144,7 @@ If you believe it is correct, remove the corresponding line from the file and re Szerző - + Information for this identity is currently missing. A személyazonossághoz tartozó információ jelenleg hiányzik. @@ -21592,7 +22183,7 @@ prevents the message to be forwarded to your friends. [Ismeretlen] - + [ ... Missing Message ... ] [ ... Hiányzó üzenet ... ] @@ -21600,7 +22191,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Dátum @@ -21660,7 +22251,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22019,7 +22610,7 @@ prevents the message to be forwarded to your friends. Fájlnév - + Download Letöltés @@ -22098,7 +22689,7 @@ prevents the message to be forwarded to your friends. Mappa megnyitása - + Create Collection... Gyűjtemény létrehozása @@ -22118,7 +22709,7 @@ prevents the message to be forwarded to your friends. Letöltés kollekciófájlból... - + Collection Kollekció @@ -22223,12 +22814,12 @@ prevents the message to be forwarded to your friends. Partner részletei - + Deny friend Barát elutasítása - + Chat Beszélgetés @@ -22238,7 +22829,7 @@ prevents the message to be forwarded to your friends. Beszélgetés kezdeményezése - + Expand Lenyitás @@ -22505,13 +23096,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22977,7 +23568,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Hálózat @@ -23005,7 +23596,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Állapot @@ -23102,7 +23693,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Kiszolgáló címe @@ -23137,12 +23728,12 @@ If you have issues connecting over Tor check the Tor logs too. Kérlek adj meg egy szolgáltatás címet - + IP Range IP tartomány - + Reported by DHT for IP masquerading @@ -23809,7 +24400,7 @@ p, li { white-space: pre-wrap; } Hiányzó PGP tanúsítvány - + Wrong password Hibás jelszó @@ -23851,7 +24442,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Barát hozzáadása @@ -23907,7 +24498,7 @@ This choice can be reverted in settings. Szolgáltatás jogosultságok mátrix - + DHT DHT @@ -24447,7 +25038,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24457,13 +25048,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK Tor rendben @@ -24472,6 +25062,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24745,35 +25360,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - %1 letöltésed elkészült + You have %1 completed transfers + - You have %1 completed download - %1 letöltésed elkészült + You have %1 completed transfer + - %1 completed downloads - %1 elkészült letöltés + %1 completed transfers + - %1 completed download - %1 elkészült letöltés + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + %1 letöltésed elkészült + + + You have %1 completed download + %1 letöltésed elkészült + + + %1 completed downloads + %1 elkészült letöltés + + + %1 completed download + %1 elkészült letöltés TransfersDialog - + Downloads Letöltések @@ -24784,7 +25410,7 @@ p, li { white-space: pre-wrap; } Feltöltések - + Name i.e: file name Név @@ -24991,7 +25617,7 @@ p, li { white-space: pre-wrap; } Meghatározás... - + Move in Queue... Mozgatás a sorban... @@ -25085,7 +25711,7 @@ p, li { white-space: pre-wrap; } Kérlek, írj be egy új --és megfelelő-- fájlnevet - + Expand all Összes lenyitása @@ -25217,7 +25843,7 @@ p, li { white-space: pre-wrap; } - + Columns Oszlopok @@ -25228,7 +25854,7 @@ p, li { white-space: pre-wrap; } Fájl átvitelek - + Path Elérési út @@ -25238,7 +25864,7 @@ p, li { white-space: pre-wrap; } Elérési útvonal mutatása - + Could not delete preview file @@ -25248,7 +25874,7 @@ p, li { white-space: pre-wrap; } Újból megpróbálod? - + Create Collection... Gyűjtemény létrehozása @@ -25263,7 +25889,7 @@ p, li { white-space: pre-wrap; } Gyűjtemény megtekintése - + Collection Kollekció @@ -25509,7 +26135,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Ismeretlen partner @@ -25605,7 +26231,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages %1 új üzeneted van @@ -25981,7 +26607,7 @@ p, li { white-space: pre-wrap; } Csoport létrehozása - + Subscribe to Group Feliratkozás a csoporthoz @@ -26075,8 +26701,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Szerkesztési előzmények mutatása @@ -26087,7 +26713,7 @@ p, li { white-space: pre-wrap; } - + Preview Előnézet @@ -26112,12 +26738,12 @@ p, li { white-space: pre-wrap; } Szerkesztési előzmények elrejtése - + Edit Page Oldal szerkesztése - + Create New Wiki Page Új wiki oldal létrehozása @@ -26137,7 +26763,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Új wiki csoport létrehozása @@ -26179,7 +26805,7 @@ p, li { white-space: pre-wrap; } Időhatár - + Create Account @@ -26189,12 +26815,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Frissítés @@ -26229,12 +26854,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26304,7 +26929,7 @@ p, li { white-space: pre-wrap; } Mutatás: - + Yourself Saját magad @@ -26342,7 +26967,7 @@ p, li { white-space: pre-wrap; } Pulzus küldése a vezetékhez - + RetroShare RetroShare @@ -26354,7 +26979,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26362,7 +26987,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26443,8 +27068,8 @@ p, li { white-space: pre-wrap; } Forma - - + + Avatar Avatár @@ -26473,6 +27098,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26585,8 +27215,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Képek (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Képek (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_it.ts b/retroshare-gui/src/lang/retroshare_it.ts index 4c0818901..389d7d42d 100644 --- a/retroshare-gui/src/lang/retroshare_it.ts +++ b/retroshare-gui/src/lang/retroshare_it.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Versione Retroshare @@ -79,7 +79,7 @@ Divertiti ;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Ricerca Avanzata - + Search Criteria Criteri di Ricerca - + Add a further search criterion. Aggiungi un altro criterio di ricerca. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + TextLabel TextLabel @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barra degli strumenti - + Icon Only Solo icona @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Scegli lo stile dei bottoni degli strumenti - + Icon Size = 8x8 Dimensione icona = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Dimensione icona = 128x128 - + Status Bar Barra di stato @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Disabilita i suggerimenti sull'icona della barra delle applicazioni - + Main page items: Elementi della pagina principale: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista degli elementi - + Icon Size = 32x32 Dimensione Icona = 32x32 @@ -828,14 +828,23 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Modifica Avatar - + + TextLabel + + + + Your Avatar Picture Il Tuo Avatar - + + Browse... + + + Add Avatar - Aggiungi Avatar + Aggiungi Avatar @@ -843,25 +852,34 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Rimuovi - + Set your Avatar picture Imposta immagine Avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Carica Avatar + Carica Avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Clicca per cambiare il tuo avatar @@ -869,7 +887,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro RetroShare Bandwidth Usage Utilizzo di Banda da parte di RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostra Impostazioni + TextLabel + + + + Reset Reimposta - Receive Rate - Velocità di Ricezione + Velocità di Ricezione - Send Rate - Velocità di Invio + Velocità di Invio - + Always on Top Sempre in Primopiano - Style - Stile + Stile - + Changes the transparency of the Bandwidth Graph Cambia la trasparenza del Grafico dell'utilizzo di Banda - + 100 100 @@ -936,30 +975,27 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro % Opacità - Save - Salva + Salva - Cancel - Annulla + Annulla - + Since: Dal: - Hide Settings - Nascondi Impostazioni + Nascondi Impostazioni BandwidthStatsWidget - + Sum Totale @@ -981,7 +1017,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Conteggio - + Average Media @@ -1115,7 +1151,7 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro - + Comments Commenti @@ -1193,6 +1229,85 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro + + BoardsCommentsItem + + + I like this + Mi piace + + + + 0 + 0 + + + + I dislike this + Non mi piace + + + + Toggle Message Read Status + Cambia lo stato dei messaggi letti + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Allarga + + + + Set as read and remove item + Definisci letto e rimuovi elemento + + + + Remove Item + + + + + Name + Nome + + + + Comm value + + + + + Comment + Commento + + + + Comments + + + + + Hide + Nascondi + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Ma ricorda: Qualsiasi dato qui presente *SARÀ PERSO* quando aggiorneremo il pro Log scale Scala logaritmica + + + Default + Predefinito + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Mi piace + + + + 0 + 0 + + + + I dislike this + Non mi piace + + + + Toggle Message Read Status + Cambia lo stato dei messaggi letti + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Allarga + + + + Set as read and remove item + Definisci letto e rimuovi elemento + + + + Remove Item + + + + + Name + Nome + + + + Comm value + + + + + Comment + Commento + + + + Comments + + + + + Hide + Nascondi + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chat - You have %1 new messages - Hai %1 nuovi messaggi + Hai %1 nuovi messaggi + + + You have %1 new message + Hai %1 nuovo messaggio + + + %1 new messages + %1 nuovi messaggi + + + %1 new message + %1 nuovo messaggio + + + + You have %1 mentions + - You have %1 new message - Hai %1 nuovo messaggio + You have %1 mention + - %1 new messages - %1 nuovi messaggi + %1 mentions + - %1 new message - %1 nuovo messaggio + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Rimuovi tutto - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare.Variante - Group chat - Chat di gruppo + Chat di gruppo - - + Private chat Chat privata @@ -2191,17 +2404,16 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare./me sta inviando un messaggio con /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">In questa finestra puoi impostare quanti messaggi delle aree di conversazione RetroShare conserverà salvati sul disco e quanto verrà mostrato delle previe conversazioni, per i diversi sistemi di chat. Il periodo massimo di archiviazione consente di eliminare i messaggi vecchi e previene che lo storico delle conversazioni si riempa con chiacchiere volatili (p.es. aree di conversazione e conversazioni a distanza).</p></body></html> - Chatlobbies - Gruppi di chat + Gruppi di chat - + Enabled: Abilitato: @@ -2222,11 +2434,12 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. + Chat rooms Chat room - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. + Broadcast Trasmetti - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Messaggi salvati (0 = illimitato): @@ -2438,8 +2657,23 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare.Conversazione privata - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2608,7 +2842,7 @@ Fai doppio clic su una stanza di conversazione per entrare e conversare. - + is typing... sta scrivendo... @@ -2627,12 +2861,12 @@ after HTML conversion. dopo la conversione in HTML. - + Choose your font. - + Do you really want to physically delete the history? Vuoi veramente cancellare lo storico dal disco? @@ -2704,7 +2938,7 @@ dopo la conversione in HTML. Non smettere di colorare dopo X elementi trovati (richiede più potenza CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trova precedente </b><br/><i>Ctrl+Shift+G</i> @@ -2744,12 +2978,12 @@ dopo la conversione in HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Contrassegna questo testo selezionato</b><br><i>Ctr+M</i> - + Person id: @@ -2765,7 +2999,7 @@ Double click on it to add his name on text writer. Non firmato - + items found. elementi trovati. @@ -2785,7 +3019,7 @@ Double click on it to add his name on text writer. Digitare un messaggio qui - + Don't stop to color after Non smettere di colorare dopo @@ -2943,12 +3177,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Dettagli - + Local Address Indirizzo Locale @@ -2959,12 +3193,12 @@ Double click on it to add his name on text writer. Indirizzo Esterno - + Node info: - + Current address: @@ -2980,31 +3214,36 @@ Double click on it to add his name on text writer. Porta - + Include signatures Includi firme - + RetroShare RetroShare - + - + Error : cannot get peer details. Errore: impossibile ottenere dettagli contatto - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3020,22 +3259,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Cifratura - + Not connected Non connesso - + Retroshare node details Dettagli nodo RetroShare - + Node name : Nome nodo : @@ -3070,13 +3314,18 @@ Double click on it to add his name on text writer. Messaggio di stato: - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Certificato Retroshare @@ -3091,7 +3340,7 @@ Double click on it to add his name on text writer. - + Hidden Address Indirizzi Nascosti @@ -3102,11 +3351,12 @@ Double click on it to add his name on text writer. nessuno + <p>This certificate contains: - <p>Questo certificato contiene: + <p>Questo certificato contiene: - + <li>a <b>node ID</b> and <b>name</b> <li>un <b>ID nodo</b> ed un <b>nome</b> @@ -3119,12 +3369,12 @@ Double click on it to add his name on text writer. un <b>indirizz IP</b> ed una <b>porta</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Puoi usare questo certificato per farti nuovi amici. Invialo per email, o consegnalo di persona.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Questo è l'ID del certificato <span style=" font-weight:600;">OpenSSL</span> del nodo, che è firmato con questa chiave <span style=" font-weight:600;">PGP</span> indicata sopra. </p></body></html> @@ -3134,7 +3384,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Questo è un metodo di criptazione usato da <span style=" font-weight:600;">OpenSSL</span>. La connessione ai nodi amici</p><p>è sempre pesantemente criptata e in caso sia presente il DHE la connessione utilizzerà anche </p><p>&quot;la perfetta segretezza in avanti&quot;.</p></body></html> - + with con @@ -3330,12 +3580,12 @@ Double click on it to add his name on text writer. Dettagli su richiesta - + Peer details Dettagli contatto - + Name: Nome: @@ -3353,12 +3603,12 @@ resources. Tieni conto che se aggiungi troppi amici RetroShare richiederà quantità eccessive di banda, memoria e CPU. Puoi aggiungere quanti amici vuoi, ma oltre i 40 probabilmente serviranno troppo risorse. - + Location: Località: - + Options Opzioni @@ -3395,12 +3645,12 @@ resources. Incollare il certificato - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Questo riquadro richiede il certificato Retroshare del tuo amico. ATTENZIONE: Si tratta di una cosa diversa dalla chiave di profilo del tuo amico. Non incollare la chiave di profilo del tuo amico qui (nemmeno una sua parte). Non funzionerebbe.</p></body></html> - + Add friend to group: Aggiungi i tuoi amici al gruppo: @@ -3410,7 +3660,7 @@ resources. Autenticare amico (firma chiave PGP) - + Please paste below your friend's Retroshare ID @@ -3435,7 +3685,7 @@ resources. - + Add as friend to connect with Aggiungi come amico per connettersi con @@ -3444,7 +3694,7 @@ resources. Per accettare la Richiesta di Amicizia, fai clic sul bottone Fine. - + Sorry, some error appeared Siamo spiacenti, si è verificato qualche errore @@ -3464,32 +3714,32 @@ resources. Dettagli sul tuo amico: - + Key validity: Chiave validità: - + Profile ID: - + Signers Firmatari - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Le firme qui sotto attestano crittologicamente che i possessori delle chiavi elencate riconoscono l'attuale chiave PGP come autentica.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Questo contatto è già sulla tua lista amici. Aggiungendolo potrebbe aver appena impostato l'indirizzo ip. - + To accept the Friend Request, click the Accept button. @@ -3535,7 +3785,7 @@ resources. - + Certificate Load Failed Errore caricando il certificato @@ -3572,12 +3822,12 @@ resources. Il certificato sembra valido - + Not a valid Retroshare certificate! Non è un certificato Retroshare valido! - + RetroShare Invitation Inviti RetroShare @@ -3597,12 +3847,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3650,7 +3900,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Hai una richiesta di amicizia da - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3738,12 +4018,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Usa come fonte diretta, quando disponibile - + IP-Addr: Ind. IP: - + IP-Address Indirizzo IP @@ -3809,7 +4089,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Aggiungi chiave al portachiavi. - + This key is already in your keyring Questa chiave è già presente nel portachiavi @@ -3870,12 +4150,12 @@ anche se non hai amici. <p>Questo certificato non ha indirizzo IP. Dovrai utilizzare la ricerca e la DHT per trovare il tuo amico. Dato che richiedi l'uso di una lista di IP autorizzati, l'utente sarà segnalato nella lista degli elementi di sicurezza in ingresso. Da li potrai autorizzare il suo indirizzo IP.</p> - + [Unknown] - + Added with certificate from %1 Aggiunto con certificato da %1 @@ -3962,7 +4242,12 @@ anche se non hai amici. Risultato UDP - + + Status + + + + <!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; } @@ -4384,7 +4669,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4536,7 +4821,7 @@ p, li { white-space: pre-wrap; } Nessuna cerchia limitata selezionata - + [Unknown] @@ -4551,7 +4836,7 @@ p, li { white-space: pre-wrap; } Rimuovi - + Search Cerca @@ -4571,7 +4856,7 @@ p, li { white-space: pre-wrap; } Firmato da Nodi conosciuti - + Edit Circle Modifica Circolo @@ -4591,12 +4876,12 @@ p, li { white-space: pre-wrap; } Id Anonimo - + Circle name Nome della cerchia - + Update Aggiorna @@ -4622,7 +4907,7 @@ p, li { white-space: pre-wrap; } PGP Id Collegato - + Add Member Aggiungere membro @@ -4766,7 +5051,7 @@ p, li { white-space: pre-wrap; } - + Attachments Allegati @@ -4812,7 +5097,7 @@ p, li { white-space: pre-wrap; } Sposta e lascia i files dai risultati di ricerca - + Paste RetroShare Links Incolla collegamenti di RetroShare @@ -4822,7 +5107,7 @@ p, li { white-space: pre-wrap; } Incolla collegamento RetroShare - + Drop file error. Ignora errore file. @@ -4849,17 +5134,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - File già aggiunto e codificato + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + File già aggiunto e codificato + + + Please add a Subject Aggiungi un Oggetto @@ -4890,12 +5199,12 @@ p, li { white-space: pre-wrap; } Vuoi davvero generare %1 messaggi ? - + You are about to add files you're not actually sharing. Do you still want this to happen? Stai per aggiungere dei file che non stai condividendo veramente. Vuoi comunque che questo succeda? - + Edit Channel Post @@ -4915,7 +5224,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Stai per spedire file non di tua proprietà in un canale. @@ -5007,7 +5316,7 @@ p, li { white-space: pre-wrap; } - + No Forum Nessun forum @@ -5464,7 +5773,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari DHTGraphSource - + users utenti @@ -6471,7 +6780,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari FlatStyle_RDM - + Friends Directories Cartelle amici @@ -6977,7 +7286,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Cerca Amici - + Mark all Contrassegna tutto @@ -6991,7 +7300,7 @@ uno o più peer non sono stati aggiunti ad un gruppo FriendsDialog - + Edit status message Modificare il messaggio di stato @@ -7095,7 +7404,7 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Network Rete @@ -7160,7 +7469,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Il campo nodo richiede minimo 3 caratteri - + Failed to generate your new certificate, maybe PGP password is wrong! Impossibile generare il nuovo certificato, forse la password PGP è errata! @@ -7199,7 +7508,7 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Node name Nome nodo @@ -7466,12 +7775,12 @@ il bottone IMPORT per caricarlo - + Profile generation failure Generazione profilo fallita - + Missing PGP certificate Manca certificato PGP @@ -7843,7 +8152,7 @@ p, li { white-space: pre-wrap; } Statistiche del router - + GroupBox @@ -7908,7 +8217,7 @@ p, li { white-space: pre-wrap; } - + Details Dettagli @@ -7931,7 +8240,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Chiavi gestite @@ -8136,7 +8445,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titolo @@ -8146,13 +8455,30 @@ p, li { white-space: pre-wrap; } Ricerca titolo - - + + + + Description Descrizione - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Ricerca descrizione @@ -8162,42 +8488,27 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Ordinamento decrescente + Ordinamento decrescente - Sort Ascending Order - Ordinamento crescente + Ordinamento crescente - Sort by Name - Ordina per nome + Ordina per nome - Sort by Popularity - Ordina per popolarità + Ordina per popolarità - Sort by Last Post - Ordina per post recente + Ordina per post recente - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8212,40 +8523,35 @@ p, li { white-space: pre-wrap; } Id - - + + Last Post Ultimo post - + + Name Nome - - Unread - - - - + Popularity Popolarità - - + + Never Mai - Display - Mostra + Mostra - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8394,7 +8700,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Canali @@ -8415,12 +8721,12 @@ p, li { white-space: pre-wrap; } Miei canali - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canali sottoscritti @@ -8926,7 +9232,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -9026,12 +9332,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Commenti @@ -9042,18 +9348,18 @@ p, li { white-space: pre-wrap; } - + Feeds Dispaccio - - + + Click to switch to list view - + Show unread posts only @@ -9063,12 +9369,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9128,7 +9434,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9143,12 +9449,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9224,23 +9530,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Sottoscritto - - Subscribe Entra - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nessun Canale Selezionato @@ -9262,11 +9581,6 @@ p, li { white-space: pre-wrap; } Channel Post Post del Canale - - - new message(s) - - GxsCircleItem @@ -9784,7 +10098,7 @@ prima che tu possa commentare Avvia un nuovo argomento nel forum selezionato - + Search forums Ricerca forums @@ -9793,12 +10107,12 @@ prima che tu possa commentare Ultimo post - + New Thread Nuovo Thread - + Threaded View Vista per argomento @@ -9808,19 +10122,19 @@ prima che tu possa commentare Vista semplice - - + + Title Titolo - - + + Date Data - + Author Autore @@ -9835,7 +10149,17 @@ prima che tu possa commentare Sto caricando - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9892,23 +10216,23 @@ prima che tu possa commentare Ricerca di contenuti - + No name Nessun nome - - + + Reply Rispondi - + <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> - + Loading... @@ -9946,12 +10270,12 @@ prima che tu possa commentare Segna non letto - + Copy RetroShare Link Copia collegamento RetroShare - + Hide Nascondi @@ -9964,7 +10288,7 @@ prima che tu possa commentare [Bloccato] - + [unknown] [sconosciuto] @@ -9994,8 +10318,8 @@ prima che tu possa commentare - - + + Distribution Distribuzione @@ -10098,12 +10422,12 @@ prima che tu possa commentare Messaggio Originale - + New thread - + Edit Modifica @@ -10159,7 +10483,7 @@ prima che tu possa commentare Mostra l'autore nella scheda delle persone - + Author's reputation Reputazione autore @@ -10179,7 +10503,7 @@ prima che tu possa commentare - + <b>Loading...<b> @@ -10219,6 +10543,11 @@ prima che tu possa commentare Storage + + + Last seen at friends: + + Moderators @@ -10286,7 +10615,7 @@ This message is missing. You should receive it later. Il %1, %2 ha scritto: - + Forum name Nome forum @@ -10318,11 +10647,6 @@ This message is missing. You should receive it later. Forum Post Forum Post - - - new message(s) - - GxsForumsDialog @@ -10771,7 +11095,7 @@ This message is missing. You should receive it later. Anteprima stampa - + Unsubscribe Esci @@ -10786,7 +11110,7 @@ This message is missing. You should receive it later. Apri in nuova scheda - + Remove this search @@ -10796,12 +11120,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Mostra Dettagli @@ -10868,12 +11192,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Copia Collegamento RetroShare @@ -10888,7 +11212,7 @@ This message is missing. You should receive it later. Segna tutti come da leggere - + AUTHD AUTHD @@ -11453,7 +11777,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11462,7 +11786,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11488,7 +11812,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11566,49 +11890,55 @@ p, li { white-space: pre-wrap; } Modulo - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Copia nel PortaBlocco il Certificato @@ -11656,17 +11986,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11681,7 +12006,12 @@ new short format Invito RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Salva come... @@ -11946,14 +12276,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tutto - + Reputation Reputazione @@ -11963,12 +12293,12 @@ p, li { white-space: pre-wrap; } Cerca - + Anonymous Id Id Anonimo - + Create new Identity Crea nuova identità @@ -12112,7 +12442,7 @@ p, li { white-space: pre-wrap; } ID dell'identità - + Send message Invia Messaggio @@ -12184,7 +12514,7 @@ p, li { white-space: pre-wrap; } Complessivo: - + Anonymous Anonimo @@ -12199,24 +12529,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you Questa identità ti appartiene - - + + My own identities Le mie identità - - + + My contacts Contatti - + Show Items @@ -12231,7 +12561,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12290,13 +12620,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12356,7 +12691,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Modifica Circolo @@ -12404,7 +12739,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12413,12 +12748,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12430,12 +12765,12 @@ These identities will soon be not supported anymore. - + [unverified] [nonVerificato] - + Identity owned by you, linked to your Retroshare node Identità di tua proprietà, collegata al tuo nodo Retroshare @@ -12551,17 +12886,17 @@ These identities will soon be not supported anymore. - + Banned Bloccato - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive positivo @@ -12722,8 +13057,8 @@ These identities will soon be not supported anymore. - - + + People Persone @@ -12734,7 +13069,7 @@ These identities will soon be not supported anymore. Il Tuo Avatar - + Linked to neighbor nodes Collegato a nodi adiacenti @@ -12744,7 +13079,7 @@ These identities will soon be not supported anymore. Collegato a nodi distanti - + Linked to a friend Retroshare node Collegato a un nodo RetroShare tuo amico @@ -12804,7 +13139,7 @@ These identities will soon be not supported anymore. Appartenente a - + Node name: Nome nodo: @@ -12814,7 +13149,7 @@ These identities will soon be not supported anymore. ID Nodo : - + Really delete? Cancellare davvero? @@ -12852,7 +13187,22 @@ These identities will soon be not supported anymore. Pseudonimo - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nuova identità @@ -12869,14 +13219,14 @@ These identities will soon be not supported anymore. - + N/A N/D - + Edit identity Modifica Identità @@ -12887,24 +13237,27 @@ These identities will soon be not supported anymore. Aggiorna - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12923,17 +13276,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Errore ricevendo la chiave! - + Error KeyID invalid Errore KeyId non valido - + Unknown GpgId PGP Id sconosciuto @@ -12943,7 +13306,7 @@ These identities will soon be not supported anymore. Nome reale sconosciuto - + Create New Identity Crea Nuova Identità @@ -12953,7 +13316,12 @@ These identities will soon be not supported anymore. Tipo - + + Choose image... + + + + @@ -12993,12 +13361,11 @@ These identities will soon be not supported anymore. Il Tuo Avatar - Set Avatar - Imposta Avatar + Imposta Avatar - + Linked to your profile Collegato al tuo profilo @@ -13008,7 +13375,7 @@ These identities will soon be not supported anymore. Puoi avere una o più identità. Vengono impiegate quando scrivi nelle aree di discussione, sui forum e per i commenti nei canali. Fungono da destinazione per le conversazioni a distanza e per il sistema postale a distanza di RetroShare. - + The nickname is too short. Please input at least %1 characters. Nickname troppo corto. Inserisci almeno %1 caratteri. @@ -13117,8 +13484,12 @@ These identities will soon be not supported anymore. + Quote + Cita + + Send - Invia + Invia @@ -13276,7 +13647,7 @@ These identities will soon be not supported anymore. - + Options Opzioni @@ -13308,12 +13679,12 @@ These identities will soon be not supported anymore. Auto configuratore rapido - + RetroShare %1 a secure decentralized communication platform RetroShare %1 una piattaforma di comunicazione sicura decentralizzata - + Unfinished Non finito @@ -13444,7 +13815,7 @@ Libera un po' di spazio e clicca OK. Mostra - + Make sure this link has not been forged to drag you to a malicious website. Accertati che questo link non sia stato creato per condurti a siti malevoli. @@ -13489,7 +13860,7 @@ Libera un po' di spazio e clicca OK. Matrice dei permessi sui servizi - + Statistics Statistiche @@ -13518,7 +13889,7 @@ Libera un po' di spazio e clicca OK. MessageComposer - + Compose Componi @@ -13620,7 +13991,7 @@ Libera un po' di spazio e clicca OK. - + Tags Etichette @@ -13715,12 +14086,12 @@ Libera un po' di spazio e clicca OK. Aggiungi citazione - + Send To: Invia a: - + &Left &L-Sinistra @@ -13750,7 +14121,7 @@ Libera un po' di spazio e clicca OK. Contatti - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Ciao, <br>ti raccomando un mio buon amico; ci si può fidare di lui quanto di me. <br> @@ -13777,12 +14148,12 @@ Libera un po' di spazio e clicca OK. - + Save Message Salva messaggio - + Message has not been Sent. Do you want to save message to draft box? Messaggio non inviato @@ -13794,7 +14165,7 @@ Vuoi salvarlo nelle bozze? Incolla collegamento RetroShare - + Add to "To" Aggiungi in "A:" @@ -14049,7 +14420,7 @@ Vuoi salvarlo? Aggiungi File Extra - + Hi,<br>I want to be friends with you on RetroShare.<br> Ciao,<br>vorrei essere tuo amico sul network RetroShare.<br> @@ -14058,12 +14429,27 @@ Vuoi salvarlo? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Hai una richiesta di amicizia - + Respond now: Rispondi subito: @@ -14079,11 +14465,12 @@ Vuoi salvarlo? Da: + Friend Nodes - Nodi Amici + Nodi Amici - + Bullet list (disc) Elenco puntato (disco) @@ -14123,13 +14510,13 @@ Vuoi salvarlo? Elenco ordinato (romani maiuscolo) - - + + Thanks, <br> Grazie, <br> - + Distant identity: Identità distante: @@ -14268,8 +14655,23 @@ Vuoi salvarlo? Messaggio - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14281,12 +14683,12 @@ Vuoi salvarlo? Files raccomandati - + Download all Recommended Files Scarica tutti i files raccomandati - + Subject: Oggetto: @@ -14361,12 +14763,18 @@ Vuoi salvarlo? Manda invito - + + Message Size: + + + + File Name Nome File - + + Size Dimensione @@ -14427,18 +14835,33 @@ Vuoi salvarlo? Scarica - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Scarica tutto - + Print Document Stampa Documento @@ -14453,7 +14876,7 @@ Vuoi salvarlo? HTML-Files (*.htm *.html);;Tutti Files (*) - + Load images always for this message Carica sempre le immagini per questo messaggio @@ -14594,7 +15017,7 @@ Vuoi salvarlo? MessagesDialog - + New Message Nuovo messaggio @@ -14650,14 +15073,14 @@ Vuoi salvarlo? - + Tags Etichette - + Inbox Casella di posta: @@ -14752,7 +15175,7 @@ Vuoi salvarlo? Inoltra messaggio - + Subject Oggetto @@ -14865,7 +15288,7 @@ ricerca - + Open in a new window Apri in nuova finestra @@ -14950,7 +15373,7 @@ ricerca - + Drafts Bozze @@ -15075,7 +15498,7 @@ ricerca Messaggio di risposta - + Delete Message Cancella Messaggio @@ -15086,7 +15509,7 @@ ricerca - + Expand Allarga @@ -15096,7 +15519,7 @@ ricerca Rimuovi elemento - + from Da @@ -15105,6 +15528,11 @@ ricerca Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15420,7 +15848,7 @@ Errore riportato: - + Groups Gruppi @@ -15450,19 +15878,19 @@ Errore riportato: Esporta il tuo elenco amici, inclusi i gruppi - - + + Search - + ID ID - + Search ID @@ -15472,7 +15900,7 @@ Errore riportato: - + Show Items @@ -15676,19 +16104,19 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Error Errore - + File is not writeable! Non è possibile scrivere il file! - + File is not readable! Non è possibile leggere il file! @@ -15727,7 +16155,7 @@ uno o più peer non sono stati aggiunti ad un gruppo NewsFeed - Log entries + Activity Stream @@ -15745,7 +16173,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Questo è un test. - + Newest on top Più recenti in cima @@ -15756,20 +16184,35 @@ uno o più peer non sono stati aggiunti ad un gruppo - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15806,22 +16249,22 @@ uno o più peer non sono stati aggiunti ad un gruppo - + Test Test - + Chat Room - + Systray Icon Icona riquadro sistema - + Message Messaggio @@ -15846,12 +16289,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Sicurezza IP - - Log - - - - + Friend Connected Amico connesso @@ -15902,27 +16340,37 @@ uno o più peer non sono stati aggiunti ad un gruppo Conversazione di gruppo - + + Toaster position + + + + Chat rooms Chat room - + Position Posizione - + + Activity + + + + X Margin Margine X - + Y Margin Margine Y - + Systray message Messaggio riquadro sistema @@ -15973,7 +16421,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Notifica - + Disable All Toasters Disabilita tutte le notifiche del Toaster @@ -15987,7 +16435,7 @@ uno o più peer non sono stati aggiunti ad un gruppo Dispaccio - + Systray Riquadro sistema @@ -16133,17 +16581,16 @@ Basso Traffico: 10% di traffico standard e TODO: sospende tutti i trasferimenti PGPKeyDialog - Dialog - Dialogo + Dialogo - + Profile info - + Name : Nome: @@ -16198,22 +16645,21 @@ Basso Traffico: 10% di traffico standard e TODO: sospende tutti i trasferimenti Ultimo - + This profile has signed your own profile key - Key signatures : - Firme chiave : + Firme chiave : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Le firme qui sotto attestano crittologicamente che i possessori delle chiavi elencate riconoscono l'attuale chiave PGP come autentica.</span></p></body></html> - + <!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; } @@ -16227,7 +16673,7 @@ p, li { white-space: pre-wrap; } Firma questa chiave - + PGP key Chiave PGP @@ -16237,22 +16683,20 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Li aiuta a decidere quando accettare connessioni basate su quella chiave, fidandosi di te. Firmare una chiave è assolutamente facoltativo e la firma non si può revocare, quindi scegli saggiamente quando farlo.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Firmare la chiave di un amico è un modo di esprimergli la tua fiducia davanti agli altri amici. Li aiuta a decidere quando accettare connessioni basate su quella chiave, fidandosi di te. Firmare una chiave è assolutamente facoltativo e la firma non si può revocare, quindi scegli saggiamente quando farlo.</span></p></body></html> - + Keysigning: - Sign PGP key - Firma Chiave PGP + Firma Chiave PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16272,7 +16716,7 @@ p, li { white-space: pre-wrap; } Accetta connessioni - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16342,27 +16786,27 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Errore: impossibile ottenere dettagli contatto - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algoritmo a chiave fornito non è supportato da RetroShare (chiavi RSA solo sono supportate al momento) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16374,7 +16818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Il livello di fiducia è un modo per esprimere la fiducia che riponi in questa chiave. Non viene utilizzato dal programma, né viene condiviso, ma può esserti utile a ricordare le chiavi buone e quelle cattive. @@ -16419,27 +16863,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.Al momento non stai autorizzando connessioni da nodi RetroShare firmati con questa chiave. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Errore Firmando - - Maybe password is wrong - Forse la password è sbagliata + + Check the password! + - + Maybe password is wrong + Forse la password è sbagliata + + + You haven't set a trust level for this key. Non hai impostato il livello di fiducia per questa chiave. - + + Retroshare profile Profilo Retroshare - + This is your own PGP key, and it is signed by : Questa è la tua chiave PGP, ed è firmata da : @@ -16618,8 +17082,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Persone @@ -16636,7 +17099,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Interno - + Chat with this person Conversa con questa persona @@ -16779,7 +17242,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel Etichetta Testo @@ -16823,8 +17286,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Commenti @@ -16859,6 +17322,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Scrivi un commento... + + + Album + Album + PhotoItem @@ -16868,12 +17336,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Modulo - + TextLabel Etichetta Testo - + <!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; } @@ -16965,7 +17433,7 @@ p, li { white-space: pre-wrap; } Visualizza foto - + PhotoShare Sondivisione Foto @@ -17005,7 +17473,7 @@ requesting to edit it! - + Stop Stop @@ -17233,12 +17701,12 @@ Altro... PluginsPage - + Authorize all plugins Autorizza tutti i moduli aggiuntivi - + Plugin look-up directories Cartella scorcio moduli aggiuntivi @@ -17296,7 +17764,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;I Plugin</h1> <p>I plugins vengono caricati dalle cartelle elencate nella lista sottostante.</p><p>Per motivi di sicurezza, i plugin accettati vengono caricati automaticamente fino a quando non vengono modificati l'eseguibile principale di RetroShare o la libreria dei plugin. In tal caso, l'utente dovrà riconfermarli. Dopo l'avvio del programma, puoi abilitare manualmente un plugin cliccando sul bottone "Abilita" e riavviando RetroShare.</p> <p>Se vuoi sviluppare un tuo plugin, contatta il team degli sviluppatori, saranno felici di aiutarti!</p> - + Plugins Moduli aggiuntivi @@ -17682,7 +18150,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Link - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17845,13 +18313,13 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Sito - - + + Comments Commenti - + Copy RetroShare Link @@ -17861,7 +18329,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Mostra l'autore nella scheda delle persone - + Comment Commento @@ -17882,12 +18350,12 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + Hide Nascondi - + Vote up Vota per @@ -17901,7 +18369,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin \/ - + Set as read and remove item Definisci letto e rimuovi elemento @@ -17962,7 +18430,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + Loading Sto caricando... @@ -18052,13 +18520,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18068,60 +18530,50 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin Amministratore: - - - + + + unknown sconosciuto - + Distribution: Distribuzione: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Post @@ -18132,7 +18584,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18201,7 +18653,12 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + + Empty + Vuoto + + + Copy RetroShare Link @@ -18236,7 +18693,7 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - + [No name] @@ -18360,8 +18817,18 @@ Per il normale utilizzo abilitare il controllo dell'hash ti protegge plugin - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18631,9 +19098,8 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseAddDialog - Post From: - Post da: + Post da: Account 1 @@ -18648,7 +19114,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari Conto 3 - + Add to Pulse Aggiungere al segnale @@ -18671,17 +19137,32 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari URL - + GroupLabel - + IDLabel - + + From: + Da: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18706,10 +19187,20 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari Negativo - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18719,14 +19210,53 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + + Post + + + + Cancel Annulla - Post Pulse to Wire - Manda un segnale sul filo + Manda un segnale sul filo + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18752,10 +19282,18 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - - - - + + + + + Click to view picture + + + + + + + Image Immagine @@ -18763,44 +19301,44 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18810,17 +19348,17 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18830,7 +19368,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18838,7 +19376,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari PulseTopLevel - + retweeted @@ -18853,7 +19391,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + follow Parent Group @@ -18863,7 +19401,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18888,7 +19426,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18924,29 +19462,29 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19024,7 +19562,7 @@ Ora puoi copiarla su un altro computer e utilizzare il pulsante Importa per cari QObject - + Confirmation Conferma @@ -19265,7 +19803,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Risultato - + Unable to make path Percorso Impossibile @@ -19300,7 +19838,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Richiesta file cancellata - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Questa versione di RetroShare usa OpenPGP-SDK. Come effetto collaterale, non utilizza il portachiavi PGP condiviso di sistema, ma ha il proprio portachiavi condiviso da tutte le istanze di RetroShare. <br><br>Non sembri avere un tale portachiavi, sebbene chiavi PGP siano menzionati da account RetroShare esistenti, probabilmente perché hai appena cambiato per questa nuova versione del software. @@ -19446,7 +19984,7 @@ L’errore segnalato è: secondi - + TR up @@ -19491,7 +20029,7 @@ L’errore segnalato è: disabilitato - + Move IP %1 to whitelist Sposta l’IP %1 alla lista bianca @@ -19507,7 +20045,7 @@ L’errore segnalato è: - + %1 seconds ago %1 secondi fa @@ -19591,7 +20129,7 @@ Security: no anonymous IDs - + Error Errore @@ -19982,9 +20520,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Questo certificato contiene: + <p>Questo certificato contiene: @@ -20358,7 +20895,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20580,18 +21117,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + Ordinamento decrescente + + + + Sort Ascending Order + Ordinamento crescente + + + + + [no title] + + + + + Show column … @@ -21028,7 +21586,7 @@ p, li { white-space: pre-wrap; } Scarica! - + File File @@ -21043,7 +21601,7 @@ p, li { white-space: pre-wrap; } Segmento - + Bad filenames have been cleaned Nomi Files incorretti sono stati puliti @@ -21093,7 +21651,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Salva - + Collection Editor Editor di Raccolte @@ -21108,7 +21666,7 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Conteggio File - + Real Size: Waiting child... @@ -21123,12 +21681,12 @@ Caratteri <b>", |, \, &lt;&gt;,, *,?</b> saranno sostit Questa è una directory. Doppio click per espanderla. - + Download files - + Specify... Specifica... @@ -21377,7 +21935,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con RsFriendListModel - + Name Nome @@ -21397,7 +21955,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con IP - + Profile ID @@ -21410,10 +21968,15 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con RsGxsForumModel - + Title Titolo + + + UnRead + + Date @@ -21425,7 +21988,7 @@ Se ritieni sia corretto, rimuovi dal file la riga corrispondente e ri-aprilo con Autore - + Information for this identity is currently missing. @@ -21463,7 +22026,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Messaggio Perso ... ] @@ -21471,7 +22034,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -21531,7 +22094,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21889,7 +22452,7 @@ prevents the message to be forwarded to your friends. Nome File - + Download Scarica @@ -21968,7 +22531,7 @@ prevents the message to be forwarded to your friends. Apri cartella - + Create Collection... Crea Raccolta... @@ -21988,7 +22551,7 @@ prevents the message to be forwarded to your friends. Scarica da una raccolta di file... - + Collection Raccolta @@ -22093,12 +22656,12 @@ prevents the message to be forwarded to your friends. Dettagli contatto - + Deny friend Rifiuta amico - + Chat Conversazione @@ -22108,7 +22671,7 @@ prevents the message to be forwarded to your friends. Avvia conversazione - + Expand Allarga @@ -22375,13 +22938,13 @@ behind a firewall or a VPN. Scoperta Attivata (raccomandato) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Scoperta Disattivata @@ -22849,7 +23412,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Rete @@ -22877,7 +23440,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22974,7 +23537,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Indirizzo Servizio @@ -23009,12 +23572,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range Intervallo IP - + Reported by DHT for IP masquerading Segnalato dalla DHT per mascheramento IP @@ -23682,7 +24245,7 @@ p, li { white-space: pre-wrap; } Manca certificato PGP - + Wrong password @@ -23736,7 +24299,7 @@ Questa scelta può essere ripristinata in Impostazioni. StatisticsWindow - + Add Friend Aggiungi amico @@ -23792,7 +24355,7 @@ Questa scelta può essere ripristinata in Impostazioni. Matrice dei permessi sui servizi - + DHT DHT @@ -24332,7 +24895,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24342,13 +24905,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24357,6 +24919,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24630,35 +25217,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Hai scaricato il %1 + You have %1 completed transfers + - You have %1 completed download - Hai completato il %1 di scaricamento + You have %1 completed transfer + - %1 completed downloads - completato %1 scaricamenti + %1 completed transfers + - %1 completed download - completato %1 scaricamento + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Hai scaricato il %1 + + + You have %1 completed download + Hai completato il %1 di scaricamento + + + %1 completed downloads + completato %1 scaricamenti + + + %1 completed download + completato %1 scaricamento TransfersDialog - + Downloads Scaricamenti @@ -24669,7 +25267,7 @@ p, li { white-space: pre-wrap; } Caricamenti - + Name i.e: file name Nome @@ -24880,7 +25478,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Trasferimento File</h1> <p>RetroShare offre due modi per trasferie file: trasferimenti diretti dai tuoi amici, e trasferimenti a distanza anonimizzati con tunnel. Inoltre, il trasferimento file è multi-fonte e consente lo swarming (puoi essere una fonta mentre scarichi).</p> <p>Puoi condividere file usando l’icona <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> bekka barra laterale sinistra. Queste file verranno elencati nella finestrella "I Miei File". Per ciascun gruppo di amici, puoi stabilire se potranno vedere o meno questi file nella finestra "File degli Amici".</p> <p>La finestra di ricerca riporta i file nelle liste dei file dei tuoi amici, ed i file distanti che possono essere raggiunti anonimamente tramite il sistema di tunneling a multi-hop.</p> - + Move in Queue... Sposta in coda... @@ -24974,7 +25572,7 @@ p, li { white-space: pre-wrap; } Per favore inserisci un nuovo--e valido--nome per il file - + Expand all Espandi tutto @@ -25106,7 +25704,7 @@ p, li { white-space: pre-wrap; } - + Columns Colonne @@ -25117,7 +25715,7 @@ p, li { white-space: pre-wrap; } Trasferimento file - + Path Tracciato @@ -25127,7 +25725,7 @@ p, li { white-space: pre-wrap; } Visualizza colonna dei Percorsi - + Could not delete preview file Impossibile eliminare il file anteprima @@ -25137,7 +25735,7 @@ p, li { white-space: pre-wrap; } Riprovare? - + Create Collection... Crea Raccolta... @@ -25152,7 +25750,7 @@ p, li { white-space: pre-wrap; } Guarda Raccolta... - + Collection Raccolta @@ -25398,7 +25996,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Contatto sconosciuto @@ -25494,7 +26092,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Hai %1 nuovi messaggi @@ -25870,7 +26468,7 @@ p, li { white-space: pre-wrap; } Creare gruppo - + Subscribe to Group Sottoscrivi al Gruppo @@ -25964,8 +26562,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Visualizza storico modifiche @@ -25976,7 +26574,7 @@ p, li { white-space: pre-wrap; } - + Preview Anteprima @@ -26001,12 +26599,12 @@ p, li { white-space: pre-wrap; } Nascondi storico modifiche - + Edit Page Modifica pagina - + Create New Wiki Page Creare nuova pagina Wiki @@ -26026,7 +26624,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Crea nuovo gruppo Wiki @@ -26068,7 +26666,7 @@ p, li { white-space: pre-wrap; } Lasso di tempo - + Create Account @@ -26078,12 +26676,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Aggiornamento @@ -26118,12 +26715,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26193,7 +26790,7 @@ p, li { white-space: pre-wrap; } Mostrando: - + Yourself Te stesso @@ -26231,7 +26828,7 @@ p, li { white-space: pre-wrap; } Posta segnale sil filo - + RetroShare RetroShare @@ -26243,7 +26840,7 @@ p, li { white-space: pre-wrap; } - + The Wire Il Cavo @@ -26251,7 +26848,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26332,8 +26929,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar Avatar @@ -26362,6 +26959,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26474,8 +27076,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Immagini (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Immagini (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_ja_JP.ts b/retroshare-gui/src/lang/retroshare_ja_JP.ts index 1627fecee..ce4e63aeb 100644 --- a/retroshare-gui/src/lang/retroshare_ja_JP.ts +++ b/retroshare-gui/src/lang/retroshare_ja_JP.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshareバージョン @@ -79,7 +79,7 @@ 楽しんで ;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: 高度な検索 - + Search Criteria 検索基準 - + Add a further search criterion. さらに検索基準を追加 @@ -283,7 +283,7 @@ AlbumDialog - + Album アルバム @@ -414,7 +414,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -457,8 +457,8 @@ p, li { white-space: pre-wrap; } フォーム - - + + TextLabel ラベル @@ -525,7 +525,7 @@ p, li { white-space: pre-wrap; } ツールバー - + Icon Only アイコンのみ @@ -550,7 +550,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 アイコンサイズ = 8x8 @@ -575,7 +575,7 @@ p, li { white-space: pre-wrap; } アイコンサイズ = 128x128 - + Status Bar @@ -650,7 +650,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -665,7 +665,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 アイコンサイズ = 32x32 @@ -731,13 +731,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + ラベル + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -746,25 +751,30 @@ p, li { white-space: pre-wrap; } 削除 - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar クリックでアバターを変更 @@ -772,7 +782,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -792,44 +802,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare 帯域使用量 + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 設定を表示 + TextLabel + ラベル + + + Reset リセット - Receive Rate - 受信速度 + 受信速度 - Send Rate - 送信速度 + 送信速度 - + Always on Top 常に手前に表示 - Style - スタイル + スタイル - + Changes the transparency of the Bandwidth Graph 帯域グラフの透明度を変更 - + 100 100 @@ -839,30 +870,27 @@ p, li { white-space: pre-wrap; } % 不透明 - Save - 保存 + 保存 - Cancel - キャンセル + キャンセル - + Since: 開始: - Hide Settings - 設定を非表示 + 設定を非表示 BandwidthStatsWidget - + Sum @@ -884,7 +912,7 @@ p, li { white-space: pre-wrap; } カウント - + Average @@ -1018,7 +1046,7 @@ p, li { white-space: pre-wrap; } ラベル - + Comments コメント @@ -1096,6 +1124,85 @@ p, li { white-space: pre-wrap; } ラベル + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 未読/既読の切り替え + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + RetroShareリンクをコピー + + + + + Expand + 展開 + + + + Set as read and remove item + + + + + Remove Item + アイテムを削除 + + + + Name + 名前 + + + + Comm value + + + + + Comment + コメント + + + + Comments + + + + + Hide + 非表示 + + BwCtrlWindow @@ -1231,6 +1338,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1283,6 +1400,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 未読/既読の切り替え + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + RetroShareリンクをコピー + + + + + Expand + 展開 + + + + Set as read and remove item + + + + + Remove Item + アイテムを削除 + + + + Name + 名前 + + + + Comm value + + + + + Comment + コメント + + + + Comments + + + + + Hide + 非表示 + + ChatLobbyDialog @@ -1491,22 +1687,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1520,11 +1716,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1981,13 +2172,11 @@ Double click a chat room to enter and chat. - Group chat - グループチャット + グループチャット - - + Private chat プライベートチャット @@ -2052,17 +2241,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2083,11 +2267,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2148,11 +2333,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2291,8 +2482,23 @@ Double click a chat room to enter and chat. プライベートチャット - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2461,7 +2667,7 @@ Double click a chat room to enter and chat. - + is typing... 書き込み中... @@ -2478,12 +2684,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? 本当に履歴を削除しますか? @@ -2555,7 +2761,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2591,12 +2797,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2612,7 +2818,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2632,7 +2838,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2790,12 +2996,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 詳細 - + Local Address ローカル アドレス @@ -2806,12 +3012,12 @@ Double click on it to add his name on text writer. 外部アドレス - + Node info: - + Current address: @@ -2827,31 +3033,41 @@ Double click on it to add his name on text writer. ポート - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. エラー: ピア詳細を取得できません. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2867,22 +3083,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2917,13 +3133,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2938,7 +3159,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2949,17 +3170,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2969,7 +3195,7 @@ Double click on it to add his name on text writer. - + with @@ -3057,32 +3283,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: 名前: - + Location: 場所: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -3092,7 +3318,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -3117,12 +3343,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3142,32 +3368,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3213,17 +3439,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed 証明書の読み込みに失敗 - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3243,12 +3469,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3296,7 +3522,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3344,12 +3600,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3379,7 +3635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3437,12 +3693,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3517,7 +3773,12 @@ even if you don't make friends. - + + Status + 状態 + + + <!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; } @@ -3939,7 +4200,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4087,7 +4348,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4102,7 +4363,7 @@ p, li { white-space: pre-wrap; } - + Search 検索 @@ -4118,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -4134,12 +4395,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4161,7 +4422,7 @@ p, li { white-space: pre-wrap; } 作成 - + Add Member @@ -4291,7 +4552,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4337,7 +4598,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4347,7 +4608,7 @@ p, li { white-space: pre-wrap; } RetroShareリンクを貼り付け - + Drop file error. @@ -4374,17 +4635,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject 件名を追加してください @@ -4415,12 +4696,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4440,7 +4721,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4532,7 +4813,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4951,7 +5232,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5954,7 +6235,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6445,7 +6726,7 @@ at least one peer was not added to a group - + Mark all @@ -6459,7 +6740,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6563,7 +6844,7 @@ at least one peer was not added to a group - + Network @@ -6628,7 +6909,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6659,7 +6940,7 @@ at least one peer was not added to a group - + Node name @@ -6918,12 +7199,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7286,7 +7567,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7351,7 +7632,7 @@ p, li { white-space: pre-wrap; } - + Details 詳細 @@ -7374,7 +7655,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7575,7 +7856,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title タイトル @@ -7585,13 +7866,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description 説明 - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7601,42 +7899,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7651,40 +7914,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post 最新の投稿 - + + Name 名前 - - Unread - - - - + Popularity 人気度 - - + + Never - Display - 表示 + 表示 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7833,7 +8091,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7854,12 +8112,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels 購読済みのチャンネル @@ -8280,7 +8538,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8380,12 +8638,12 @@ p, li { white-space: pre-wrap; } - + Files ファイル - + Comments コメント @@ -8396,18 +8654,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8417,12 +8675,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8482,7 +8740,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8497,12 +8755,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8578,23 +8836,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe 購読 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected チャンネルが選択されていません。 @@ -8616,11 +8887,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -9113,7 +9379,7 @@ before you can comment - + Search forums @@ -9122,12 +9388,12 @@ before you can comment 最新の投稿 - + New Thread - + Threaded View @@ -9137,19 +9403,19 @@ before you can comment - - + + Title タイトル - - + + Date 期日 - + Author @@ -9164,7 +9430,17 @@ before you can comment ロード中 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9209,23 +9485,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -9263,12 +9539,12 @@ before you can comment - + Copy RetroShare Link RetroShareリンクをコピー - + Hide 非表示 @@ -9277,7 +9553,7 @@ before you can comment 展開 - + [unknown] @@ -9307,8 +9583,8 @@ before you can comment - - + + Distribution @@ -9391,12 +9667,12 @@ before you can comment - + New thread - + Edit @@ -9452,7 +9728,7 @@ before you can comment - + Author's reputation @@ -9472,7 +9748,7 @@ before you can comment - + <b>Loading...<b> @@ -9512,6 +9788,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9579,7 +9860,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9611,11 +9892,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -10028,7 +10304,7 @@ This message is missing. You should receive it later. - + Unsubscribe 購読中止 @@ -10043,7 +10319,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -10053,12 +10329,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10125,12 +10401,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link RetroShareリンクをコピー @@ -10145,7 +10421,7 @@ This message is missing. You should receive it later. すべてを未読に設定 - + AUTHD @@ -10667,7 +10943,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10676,7 +10952,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10702,7 +10978,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10776,49 +11052,55 @@ p, li { white-space: pre-wrap; } フォーム - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10866,17 +11148,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10891,7 +11168,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... 名前を付けて保存 @@ -11156,14 +11438,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -11173,12 +11455,12 @@ p, li { white-space: pre-wrap; } 検索 - + Anonymous Id - + Create new Identity @@ -11322,7 +11604,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11394,7 +11676,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11409,24 +11691,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11441,7 +11723,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11500,13 +11782,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11566,7 +11853,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11614,7 +11901,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11623,12 +11910,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11640,12 +11927,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11761,17 +12048,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11928,8 +12215,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11940,7 +12227,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11950,7 +12237,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12010,7 +12297,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12020,7 +12307,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12058,7 +12345,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12075,14 +12362,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity @@ -12093,24 +12380,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12130,12 +12420,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12145,7 +12460,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12155,7 +12470,12 @@ These identities will soon be not supported anymore. タイプ - + + Choose image... + + + + @@ -12195,12 +12515,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12210,7 +12525,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12315,8 +12630,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - 送信 + 送信 @@ -12474,7 +12793,7 @@ These identities will soon be not supported anymore. - + Options @@ -12506,12 +12825,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12640,7 +12959,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12685,7 +13004,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12714,7 +13033,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12816,7 +13135,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12911,12 +13230,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12946,7 +13265,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12972,12 +13296,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12988,7 +13312,7 @@ Do you want to save message to draft box? RetroShareリンクを貼り付け - + Add to "To" @@ -13242,7 +13566,7 @@ Do you want to save message ? さらにファイルを追加 - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13256,6 +13580,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13268,7 +13607,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13308,13 +13647,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13453,8 +13792,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13466,12 +13820,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13546,12 +13900,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13612,18 +13972,33 @@ Do you want to save message ? ダウンロード - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13638,7 +14013,7 @@ Do you want to save message ? - + Load images always for this message @@ -13747,7 +14122,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13767,14 +14142,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13845,7 +14220,7 @@ Do you want to save message ? - + Subject 件名 @@ -13925,7 +14300,7 @@ Do you want to save message ? - + Open in a new window @@ -14010,7 +14385,7 @@ Do you want to save message ? - + Drafts @@ -14099,7 +14474,7 @@ Do you want to save message ? - + Delete Message @@ -14110,7 +14485,7 @@ Do you want to save message ? - + Expand 展開 @@ -14120,7 +14495,7 @@ Do you want to save message ? アイテムを削除 - + from @@ -14129,6 +14504,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14428,7 +14808,7 @@ Reported error: - + Groups @@ -14458,19 +14838,19 @@ Reported error: - - + + Search 検索 - + ID ID - + Search ID @@ -14480,7 +14860,7 @@ Reported error: - + Show Items @@ -14679,18 +15059,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14728,7 +15108,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14742,7 +15122,7 @@ at least one peer was not added to a group - + Newest on top @@ -14753,20 +15133,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14799,22 +15194,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14835,12 +15230,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14887,27 +15277,37 @@ at least one peer was not added to a group グループチャット - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14957,7 +15357,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14967,7 +15367,7 @@ at least one peer was not added to a group - + Systray @@ -15094,17 +15494,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : 名前: @@ -15159,22 +15554,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15188,7 +15578,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15198,22 +15588,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15233,7 +15613,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15299,27 +15679,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. エラー: ピア詳細を取得できません. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15331,7 +15711,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15376,27 +15756,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure 署名失敗 - - Maybe password is wrong - おそらくパスワードが間違っています + + Check the password! + - + Maybe password is wrong + おそらくパスワードが間違っています + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15567,8 +15967,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15585,7 +15984,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15724,7 +16123,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel ラベル @@ -15764,8 +16163,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + コメント @@ -15796,6 +16195,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment コメントを追加 + + + Album + アルバム + PhotoItem @@ -15805,12 +16209,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.フォーム - + TextLabel ラベル - + <!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; } @@ -15890,7 +16294,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15930,7 +16334,7 @@ requesting to edit it! - + Stop @@ -16154,12 +16558,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories @@ -16168,7 +16572,7 @@ p, li { white-space: pre-wrap; } <無効> - + Plugins @@ -16502,7 +16906,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16637,13 +17041,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments コメント - + Copy RetroShare Link RetroShareリンクをコピー @@ -16653,7 +17057,7 @@ p, li { white-space: pre-wrap; } - + Comment コメント @@ -16674,12 +17078,12 @@ p, li { white-space: pre-wrap; } - + Hide 非表示 - + Vote up @@ -16689,7 +17093,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16750,7 +17154,7 @@ p, li { white-space: pre-wrap; } ラベル - + Loading ロード中 @@ -16812,13 +17216,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16828,60 +17226,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel ラベル - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16892,7 +17280,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16961,7 +17349,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link RetroShareリンクをコピー @@ -16996,7 +17389,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17112,8 +17505,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17381,12 +17784,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17401,17 +17799,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17436,10 +17849,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17449,13 +17872,48 @@ and use the import button to load it - + + Post + + + + Cancel キャンセル - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17478,10 +17936,18 @@ and use the import button to load it フォーム - - - - + + + + + Click to view picture + + + + + + + Image @@ -17489,44 +17955,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17536,17 +18002,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17556,7 +18022,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17564,7 +18030,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17579,7 +18045,7 @@ and use the import button to load it - + follow Parent Group @@ -17589,7 +18055,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17614,7 +18080,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17650,29 +18116,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17750,7 +18216,7 @@ and use the import button to load it QObject - + Confirmation @@ -17989,7 +18455,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -18024,7 +18490,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18162,7 +18628,7 @@ Reported error is: - + TR up @@ -18207,7 +18673,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18223,7 +18689,7 @@ Reported error is: - + %1 seconds ago @@ -18307,7 +18773,7 @@ Security: no anonymous IDs - + Error @@ -18697,11 +19163,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19035,7 +19496,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19257,18 +19718,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19705,7 +20187,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19720,7 +20202,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19768,7 +20250,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 保存 - + Collection Editor @@ -19783,7 +20265,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19798,12 +20280,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -20050,7 +20532,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name 名前 @@ -20070,7 +20552,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20083,10 +20565,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title タイトル + + + UnRead + + Date @@ -20098,7 +20585,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -20136,7 +20623,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -20144,7 +20631,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 期日 @@ -20204,7 +20691,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20558,7 +21045,7 @@ prevents the message to be forwarded to your friends. - + Download ダウンロード @@ -20637,7 +21124,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20657,7 +21144,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20762,12 +21249,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat チャット @@ -20777,7 +21264,7 @@ prevents the message to be forwarded to your friends. チャットを始める - + Expand 展開 @@ -21040,13 +21527,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21512,7 +21999,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21540,7 +22027,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status 状態 @@ -21637,7 +22124,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21672,12 +22159,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22342,7 +22829,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22384,7 +22871,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22440,7 +22927,7 @@ This choice can be reverted in settings. - + DHT @@ -22972,7 +23459,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22982,13 +23469,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22997,6 +23483,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23270,27 +23781,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23298,7 +23804,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23309,7 +23815,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name 名前 @@ -23516,7 +24022,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23610,7 +24116,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23742,7 +24248,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23753,7 +24259,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23763,7 +24269,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23773,7 +24279,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23788,7 +24294,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24030,7 +24536,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24126,7 +24632,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24494,7 +25000,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24588,8 +25094,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24600,7 +25106,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24625,12 +25131,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24650,7 +25156,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24688,7 +25194,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24698,12 +25204,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24738,12 +25243,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24781,7 +25286,7 @@ p, li { white-space: pre-wrap; } 新規 - + Yourself @@ -24795,7 +25300,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24807,7 +25312,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24815,7 +25320,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24896,8 +25401,8 @@ p, li { white-space: pre-wrap; } フォーム - - + + Avatar @@ -24926,6 +25431,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25038,7 +25548,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ko.ts b/retroshare-gui/src/lang/retroshare_ko.ts index 97514b191..d3aa306a1 100644 --- a/retroshare-gui/src/lang/retroshare_ko.ts +++ b/retroshare-gui/src/lang/retroshare_ko.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ 레트로 쉐어: 고급 검색 - + Search Criteria 검색 문구 - + Add a further search criterion. 검색 문구 더 추가합니다. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album 앨범 @@ -490,7 +490,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -533,8 +533,8 @@ p, li { white-space: pre-wrap; } 양식 - - + + TextLabel 텍스트 레이블 @@ -601,7 +601,7 @@ p, li { white-space: pre-wrap; } 도구 모음 - + Icon Only 아이콘만 @@ -626,7 +626,7 @@ p, li { white-space: pre-wrap; } 도구 단추 스타일을 선택하십시오. - + Icon Size = 8x8 아이콘 크기 = 8x8 @@ -651,7 +651,7 @@ p, li { white-space: pre-wrap; } 아이콘 크기 = 128x128 - + Status Bar 상태 표시줄 @@ -726,7 +726,7 @@ p, li { white-space: pre-wrap; } SysTray 풍선 도움말 비활성화 - + Main page items: @@ -741,7 +741,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 아이콘 크기 = 32x32 @@ -807,14 +807,23 @@ p, li { white-space: pre-wrap; } 아바타 바꾸기 - + + TextLabel + 텍스트 레이블 + + + Your Avatar Picture 아바타 사진 - + + Browse... + + + Add Avatar - 아바타 추가 + 아바타 추가 @@ -822,25 +831,34 @@ p, li { white-space: pre-wrap; } 제거 - + Set your Avatar picture 아바타 사진 설정 - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - 아바타 불러오기 + 아바타 불러오기 AvatarWidget - - Choose avatar - - - - + Click to change your avatar 아바타를 바꾸려면 누르십시오 @@ -848,7 +866,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -868,44 +886,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage 레트로 쉐어 대역폭 사용 + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 옵션 보이기 + TextLabel + 텍스트 레이블 + + + Reset 초기화 - Receive Rate - 수신율 + 수신율 - Send Rate - 송신율 + 송신율 - + Always on Top 항상 위로 - Style - 스타일 + 스타일 - + Changes the transparency of the Bandwidth Graph 대역폭 그래프 투명도를 바꿉니다 - + 100 100 @@ -915,30 +954,27 @@ p, li { white-space: pre-wrap; } % 투명도 - Save - 저장 + 저장 - Cancel - 취소 + 취소 - + Since: 시초: - Hide Settings - 설정 숨기기 + 설정 숨기기 BandwidthStatsWidget - + Sum 총합 @@ -960,7 +996,7 @@ p, li { white-space: pre-wrap; } 계수 - + Average @@ -1094,7 +1130,7 @@ p, li { white-space: pre-wrap; } 텍스트 레이블 - + Comments 설명 @@ -1172,6 +1208,85 @@ p, li { white-space: pre-wrap; } 텍스트 레이블 + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + 레트로 쉐어 링크 복사 + + + + + Expand + 확장 + + + + Set as read and remove item + 항목을 읽음으로 설정하고 제거 + + + + Remove Item + 항목 제거 + + + + Name + 이름 + + + + Comm value + + + + + Comment + 답글 달기 + + + + Comments + + + + + Hide + 숨김 + + BwCtrlWindow @@ -1307,6 +1422,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + 기본값 + + + + Dark + + ChannelPage @@ -1359,6 +1484,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + 레트로 쉐어 링크 복사 + + + + + Expand + 확장 + + + + Set as read and remove item + 항목을 읽음으로 설정하고 제거 + + + + Remove Item + 항목 제거 + + + + Name + 이름 + + + + Comm value + + + + + Comment + 답글 달기 + + + + Comments + + + + + Hide + 숨김 + + ChatLobbyDialog @@ -1567,22 +1771,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1596,11 +1800,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -2049,13 +2248,11 @@ Double click a chat room to enter and chat. - Group chat - 집단 대화 + 집단 대화 - - + Private chat 개인 대화 @@ -2120,17 +2317,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2151,11 +2343,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2216,11 +2409,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2359,8 +2558,23 @@ Double click a chat room to enter and chat. 개인 대화 - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2529,7 +2743,7 @@ Double click a chat room to enter and chat. - + is typing... 입력중 ... @@ -2546,12 +2760,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? 실제 기록을 정말로 삭제하시겠습니까? @@ -2623,7 +2837,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2659,12 +2873,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2680,7 +2894,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2700,7 +2914,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2858,12 +3072,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 세부 정보 - + Local Address 지역 주소 @@ -2874,12 +3088,12 @@ Double click on it to add his name on text writer. 외부 주소 - + Node info: - + Current address: @@ -2895,31 +3109,41 @@ Double click on it to add his name on text writer. 포트 - + Include signatures 서명 포함 - + RetroShare 레트로 쉐어 - + - + Error : cannot get peer details. 오류 : 동료 세부 정보를 가져올 수 없습니다 - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2935,22 +3159,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2985,13 +3209,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3006,7 +3235,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3017,17 +3246,22 @@ Double click on it to add his name on text writer. 없음 - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3037,7 +3271,7 @@ Double click on it to add his name on text writer. - + with @@ -3133,32 +3367,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: 이름: - + Location: 지역: - + Options 옵션 - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -3168,7 +3402,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -3193,12 +3427,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3218,32 +3452,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3289,17 +3523,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed 서명 불러오기에 실패했습니다 - + Not a valid Retroshare certificate! - + RetroShare Invitation 레트로 쉐어 초대 @@ -3319,12 +3553,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3372,7 +3606,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3424,12 +3688,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3459,7 +3723,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3517,12 +3781,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3597,7 +3861,12 @@ even if you don't make friends. - + + Status + 상태 + + + <!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; } @@ -4019,7 +4288,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4167,7 +4436,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4182,7 +4451,7 @@ p, li { white-space: pre-wrap; } - + Search 검색 @@ -4198,7 +4467,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -4214,12 +4483,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4241,7 +4510,7 @@ p, li { white-space: pre-wrap; } 만들기 - + Add Member @@ -4371,7 +4640,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4417,7 +4686,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links 레트로 쉐어 링크 붙여넣기 @@ -4427,7 +4696,7 @@ p, li { white-space: pre-wrap; } 레트로 쉐어 링크 붙여넣기 - + Drop file error. @@ -4454,17 +4723,37 @@ p, li { white-space: pre-wrap; } - + RetroShare 레트로 쉐어 - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject 제목을 입력해주십시오 @@ -4495,12 +4784,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4520,7 +4809,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4612,7 +4901,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -5031,7 +5320,7 @@ and use the import button to load it DHTGraphSource - + users @@ -6034,7 +6323,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6525,7 +6814,7 @@ at least one peer was not added to a group - + Mark all @@ -6539,7 +6828,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6643,7 +6932,7 @@ at least one peer was not added to a group - + Network @@ -6708,7 +6997,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6739,7 +7028,7 @@ at least one peer was not added to a group - + Node name @@ -6998,12 +7287,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7366,7 +7655,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7431,7 +7720,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7454,7 +7743,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7655,7 +7944,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 제목 @@ -7665,13 +7954,30 @@ p, li { white-space: pre-wrap; } 제목 검색 - - + + + + Description 설명 - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7681,42 +7987,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7731,40 +8002,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post 최신 게시글 - + + Name 이름 - - Unread - - - - + Popularity 인기도 - - + + Never - Display - 표시 + 표시 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7913,7 +8179,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7934,12 +8200,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels 가입한 채널 @@ -8364,7 +8630,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8464,12 +8730,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments 설명 @@ -8480,18 +8746,18 @@ p, li { white-space: pre-wrap; } - + Feeds 피드 - - + + Click to switch to list view - + Show unread posts only @@ -8501,12 +8767,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8566,7 +8832,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8581,12 +8847,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8662,23 +8928,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe 가입 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected 선택한 채널 없음 @@ -8700,11 +8979,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -9197,7 +9471,7 @@ before you can comment - + Search forums 포럼 검색 @@ -9206,12 +9480,12 @@ before you can comment 최신 게시글 - + New Thread - + Threaded View @@ -9221,19 +9495,19 @@ before you can comment - - + + Title 제목 - - + + Date 날짜 - + Author 작성자 @@ -9248,7 +9522,17 @@ before you can comment 불러오는 중 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9293,23 +9577,23 @@ before you can comment 작성자 검색 - + No name 이름 없음 - - + + Reply - + <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> - + Loading... @@ -9347,12 +9631,12 @@ before you can comment 읽지 않음으로 표시 - + Copy RetroShare Link 레트로 쉐어 링크 복사 - + Hide 숨김 @@ -9361,7 +9645,7 @@ before you can comment 확장 - + [unknown] @@ -9391,8 +9675,8 @@ before you can comment - - + + Distribution @@ -9479,12 +9763,12 @@ before you can comment - + New thread - + Edit 편집 @@ -9540,7 +9824,7 @@ before you can comment - + Author's reputation @@ -9560,7 +9844,7 @@ before you can comment - + <b>Loading...<b> @@ -9600,6 +9884,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9667,7 +9956,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9699,11 +9988,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -10116,7 +10400,7 @@ This message is missing. You should receive it later. - + Unsubscribe 탈퇴 @@ -10131,7 +10415,7 @@ This message is missing. You should receive it later. 새 탭에서 열기 - + Remove this search @@ -10141,12 +10425,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10213,12 +10497,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link 레트로 쉐어 링크 복사 @@ -10233,7 +10517,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10755,7 +11039,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10764,7 +11048,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10790,7 +11074,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10864,49 +11148,55 @@ p, li { white-space: pre-wrap; } 양식 - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10954,17 +11244,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10979,7 +11264,12 @@ new short format 레트로 쉐어 초대 - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... 다른 이름으로 저장... @@ -11244,14 +11534,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All 모두 - + Reputation @@ -11261,12 +11551,12 @@ p, li { white-space: pre-wrap; } 검색 - + Anonymous Id - + Create new Identity @@ -11410,7 +11700,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11482,7 +11772,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11497,24 +11787,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11529,7 +11819,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11588,13 +11878,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11654,7 +11949,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11702,7 +11997,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11711,12 +12006,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11728,12 +12023,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11849,17 +12144,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12016,8 +12311,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12028,7 +12323,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12038,7 +12333,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12098,7 +12393,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12108,7 +12403,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12146,7 +12441,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12163,14 +12458,14 @@ These identities will soon be not supported anymore. - + N/A 없음 - + Edit identity @@ -12181,24 +12476,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12218,12 +12516,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12233,7 +12556,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12243,7 +12566,12 @@ These identities will soon be not supported anymore. 형식 - + + Choose image... + + + + @@ -12283,12 +12611,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12298,7 +12621,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12403,8 +12726,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - 보내기 + 보내기 @@ -12562,7 +12889,7 @@ These identities will soon be not supported anymore. - + Options 옵션 @@ -12594,12 +12921,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12732,7 +13059,7 @@ These identities will soon be not supported anymore. 표시 - + Make sure this link has not been forged to drag you to a malicious website. @@ -12777,7 +13104,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12806,7 +13133,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12908,7 +13235,7 @@ These identities will soon be not supported anymore. - + Tags @@ -13003,12 +13330,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -13038,7 +13365,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -13064,12 +13396,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -13080,7 +13412,7 @@ Do you want to save message to draft box? 레트로 쉐어 링크 붙여넣기 - + Add to "To" @@ -13334,7 +13666,7 @@ Do you want to save message ? 추가 파일 추가 - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13348,6 +13680,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13360,7 +13707,7 @@ Do you want to save message ? 어디에서 : - + Bullet list (disc) @@ -13400,13 +13747,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13545,8 +13892,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13558,12 +13920,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: 제목: @@ -13638,12 +14000,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13704,18 +14072,33 @@ Do you want to save message ? 다운로드 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13730,7 +14113,7 @@ Do you want to save message ? - + Load images always for this message @@ -13839,7 +14222,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13859,14 +14242,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13937,7 +14320,7 @@ Do you want to save message ? - + Subject 제목 @@ -14021,7 +14404,7 @@ Do you want to save message ? - + Open in a new window @@ -14106,7 +14489,7 @@ Do you want to save message ? - + Drafts @@ -14195,7 +14578,7 @@ Do you want to save message ? - + Delete Message @@ -14206,7 +14589,7 @@ Do you want to save message ? - + Expand 확장 @@ -14216,7 +14599,7 @@ Do you want to save message ? 항목 제거 - + from @@ -14225,6 +14608,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14524,7 +14912,7 @@ Reported error: - + Groups @@ -14554,19 +14942,19 @@ Reported error: - - + + Search 검색 - + ID ID - + Search ID @@ -14576,7 +14964,7 @@ Reported error: - + Show Items @@ -14775,18 +15163,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14824,7 +15212,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14838,7 +15226,7 @@ at least one peer was not added to a group - + Newest on top @@ -14849,20 +15237,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14895,22 +15298,22 @@ at least one peer was not added to a group - + Test 시험 - + Chat Room - + Systray Icon - + Message @@ -14931,12 +15334,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14983,27 +15381,37 @@ at least one peer was not added to a group 집단 대화 - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -15053,7 +15461,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -15067,7 +15475,7 @@ at least one peer was not added to a group 피드 - + Systray @@ -15194,17 +15602,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -15259,22 +15662,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15288,7 +15686,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15298,22 +15696,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15333,7 +15721,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15399,27 +15787,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare Retroshare (뒤에몫) - - + + Error : cannot get peer details. 오류 : 동료 세부 정보를 가져올 수 없습니다 - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15431,7 +15819,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15476,27 +15864,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure 서명 실패 - - Maybe password is wrong - 비밀번호가 잘못된 것 같습니다 + + Check the password! + - + Maybe password is wrong + 비밀번호가 잘못된 것 같습니다 + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15667,8 +16075,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15685,7 +16092,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15824,7 +16231,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel 텍스트 레이블 @@ -15868,8 +16275,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + 설명 @@ -15900,6 +16307,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment 설명 추가 + + + Album + 앨범 + PhotoItem @@ -15909,12 +16321,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.양식 - + TextLabel 텍스트 레이블 - + <!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; } @@ -15994,7 +16406,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -16034,7 +16446,7 @@ requesting to edit it! - + Stop @@ -16258,17 +16670,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16594,7 +17006,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16729,13 +17141,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments 설명 - + Copy RetroShare Link 레트로 쉐어 링크 복사 @@ -16745,7 +17157,7 @@ p, li { white-space: pre-wrap; } - + Comment 답글 달기 @@ -16766,12 +17178,12 @@ p, li { white-space: pre-wrap; } - + Hide 숨김 - + Vote up @@ -16781,7 +17193,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item 항목을 읽음으로 설정하고 제거 @@ -16842,7 +17254,7 @@ p, li { white-space: pre-wrap; } 텍스트 레이블 - + Loading 불러오는 중 @@ -16888,13 +17300,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16904,60 +17310,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel 텍스트 레이블 - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16968,7 +17364,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17037,7 +17433,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link 레트로 쉐어 링크 복사 @@ -17072,7 +17473,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17188,8 +17589,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17457,12 +17868,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17477,17 +17883,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + 어디에서 : + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17512,10 +17933,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17525,13 +17956,48 @@ and use the import button to load it - + + Post + + + + Cancel 취소 - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17558,10 +18024,18 @@ and use the import button to load it 양식 - - - - + + + + + Click to view picture + + + + + + + Image @@ -17569,44 +18043,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17616,17 +18090,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17636,7 +18110,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17644,7 +18118,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17659,7 +18133,7 @@ and use the import button to load it - + follow Parent Group @@ -17669,7 +18143,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17694,7 +18168,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17730,29 +18204,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17830,7 +18304,7 @@ and use the import button to load it QObject - + Confirmation @@ -18069,7 +18543,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -18104,7 +18578,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18244,7 +18718,7 @@ Reported error is: - + TR up @@ -18289,7 +18763,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18305,7 +18779,7 @@ Reported error is: - + %1 seconds ago @@ -18389,7 +18863,7 @@ Security: no anonymous IDs - + Error @@ -18779,11 +19253,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19117,7 +19586,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19339,18 +19808,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19787,7 +20277,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19802,7 +20292,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19850,7 +20340,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 저장 - + Collection Editor @@ -19865,7 +20355,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19880,12 +20370,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -20132,7 +20622,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name 이름 @@ -20152,7 +20642,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20165,10 +20655,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 제목 + + + UnRead + + Date @@ -20180,7 +20675,7 @@ If you believe it is correct, remove the corresponding line from the file and re 작성자 - + Information for this identity is currently missing. @@ -20218,7 +20713,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -20226,7 +20721,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 날짜 @@ -20286,7 +20781,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20640,7 +21135,7 @@ prevents the message to be forwarded to your friends. - + Download 다운로드 @@ -20719,7 +21214,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20739,7 +21234,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20844,12 +21339,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat 대화 @@ -20859,7 +21354,7 @@ prevents the message to be forwarded to your friends. 대화 시작 - + Expand 확장 @@ -21122,13 +21617,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21594,7 +22089,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21622,7 +22117,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status 상태 @@ -21719,7 +22214,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21754,12 +22249,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22424,7 +22919,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22466,7 +22961,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22522,7 +23017,7 @@ This choice can be reverted in settings. - + DHT @@ -23054,7 +23549,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23064,13 +23559,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23079,6 +23573,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23352,27 +23871,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23380,7 +23894,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23391,7 +23905,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name 이름 @@ -23598,7 +24112,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23692,7 +24206,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23824,7 +24338,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23835,7 +24349,7 @@ p, li { white-space: pre-wrap; } - + Path 경로 @@ -23845,7 +24359,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23855,7 +24369,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23870,7 +24384,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24112,7 +24626,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24208,7 +24722,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24576,7 +25090,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24670,8 +25184,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24682,7 +25196,7 @@ p, li { white-space: pre-wrap; } - + Preview 미리보기 @@ -24707,12 +25221,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24732,7 +25246,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24770,7 +25284,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24780,12 +25294,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24820,12 +25333,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24859,7 +25372,7 @@ p, li { white-space: pre-wrap; } 새 피드 - + Yourself @@ -24873,7 +25386,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24885,7 +25398,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24893,7 +25406,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24974,8 +25487,8 @@ p, li { white-space: pre-wrap; } 양식 - - + + Avatar @@ -25004,6 +25517,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25116,7 +25634,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_nl.ts b/retroshare-gui/src/lang/retroshare_nl.ts index 8b6fd9559..c59474c60 100644 --- a/retroshare-gui/src/lang/retroshare_nl.ts +++ b/retroshare-gui/src/lang/retroshare_nl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare versie @@ -79,7 +79,7 @@ Veel plezier ;-) - + Only Hidden Node @@ -128,12 +128,12 @@ RetroShare: Geavanceerd Zoeken - + Search Criteria Zoek Criteria - + Add a further search criterion. Voeg een volgend zoek criterium toe @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; }⏎ AlbumDialog - + Album Album @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; }⏎ AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; }⏎ Formulier - - + + TextLabel Tekst label @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; }⏎ Werkbalk - + Icon Only Alleen pictogram @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; }⏎ Kies de stijl van de gereedschaps knoppen. - + Icon Size = 8x8 Pictogramgrootte = 8 x 8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; }⏎ Pictogramgroote = 128x128 - + Status Bar Status Bar @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; }⏎ - + Main page items: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; }⏎ - + Icon Size = 32x32 Pictogramgrootte = 32 x 32 @@ -827,14 +827,23 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Avatar wijzigen - + + TextLabel + Tekst label + + + Your Avatar Picture Uw Avatar afbeelding - + + Browse... + + + Add Avatar - Avatar toevoegen + Avatar toevoegen @@ -842,25 +851,34 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Verwijderen - + Set your Avatar picture Uw Avatar afbeelding instellen - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Laad Avatar + Laad Avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klik om je avatar te veranderen @@ -868,7 +886,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update RetroShare Bandwidth Usage Bandbreedte gebruik door RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Instellingen weergeven + TextLabel + Tekst label + + + Reset Opnieuw instellen - Receive Rate - Ontvang ranglijst + Ontvang ranglijst - Send Rate - Verzend ranglijst + Verzend ranglijst - + Always on Top Altijd op de voorgrond - Style - Stijl + Stijl - + Changes the transparency of the Bandwidth Graph Verander de doorzichtigheid van de grafische bandbreedte - + 100 100 @@ -935,30 +974,27 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Ondoorzichtig - Save - Opslaan + Opslaan - Cancel - Annuleren + Annuleren - + Since: Sinds - Hide Settings - Verberg instellingen + Verberg instellingen BandwidthStatsWidget - + Sum Som @@ -980,7 +1016,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Aantal - + Average Gemiddelde @@ -1114,7 +1150,7 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Tekst label - + Comments Opmerkingen @@ -1192,6 +1228,85 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Tekst label + + BoardsCommentsItem + + + I like this + Ik vind dit leuk! + + + + 0 + 0 + + + + I dislike this + Ik vindt dit niet leuk + + + + Toggle Message Read Status + Verander boodschap gelezen status + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopieer RetroShare Link + + + + + Expand + Uitbreiden + + + + Set as read and remove item + Markeer als gelezen en verplaats item + + + + Remove Item + Item verwijderen + + + + Name + Naam + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Maar onthoudt: Elke data hier *ZAL* verloren gaan als de protocollen een update Log scale + + + Default + Standaard + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Ik vind dit leuk! + + + + 0 + 0 + + + + I dislike this + Ik vindt dit niet leuk + + + + Toggle Message Read Status + Verander boodschap gelezen status + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopieer RetroShare Link + + + + + Expand + Uitbreiden + + + + Set as read and remove item + Markeer als gelezen en verplaats item + + + + Remove Item + Item verwijderen + + + + Name + Naam + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to - You have %1 new messages - U heeft %1 nieuwe berichten + U heeft %1 nieuwe berichten + + + You have %1 new message + U heeft %1 nieuw bericht + + + %1 new messages + %1 nieuwe berichten + + + %1 new message + %1 nieuw bericht + + + + You have %1 mentions + - You have %1 new message - U heeft %1 nieuw bericht + You have %1 mention + - %1 new messages - %1 nieuwe berichten + %1 mentions + - %1 new message - %1 nieuw bericht + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Verwijder alles - - - mention(s) - - ChatLobbyWidget @@ -2097,13 +2312,11 @@ Double click a chat room to enter and chat. - Group chat - Groeps chat + Groeps chat - - + Private chat Privé Chat @@ -2168,17 +2381,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/> <body><p align="justify"> op dit tabblad kunt u instellen hoeveel chatberichten Retroshare blijft opgeslagen op de schijf en hoeveel van de vorige conversatie wordt weergegeven, voor de verschillende chat-systemen. De maximale opslagperiode te ontdoen van oude berichten en voorkomt u dat de chatgeschiedenis uit te vullen met vluchtige chat (bijvoorbeeld chat lobby's en verre chat).</p></body></html> - Chatlobbies - Chatlobbies + Chatlobbies - + Enabled: Ingeschakeld: @@ -2199,11 +2411,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2264,11 +2477,17 @@ Double click a chat room to enter and chat. + Broadcast Uitzenden - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Opgeslagen berichten (0 = ongelimiteerd): @@ -2411,8 +2630,23 @@ Double click a chat room to enter and chat. Privé Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2581,7 +2815,7 @@ Double click a chat room to enter and chat. - + is typing... typt.... @@ -2598,12 +2832,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Wil je echt voorgoed de geschiedenis verwijderen? @@ -2675,7 +2909,7 @@ after HTML conversion. Niet stoppen met kleuren na X items gevonden (meer CPU nodig) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Zoek vorige</b> <br/><i>Ctrl + Shift + G</i> @@ -2715,12 +2949,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Markeer deze geselecteerde tekst</b><br><i>Ctrl + M</i> - + Person id: @@ -2736,7 +2970,7 @@ Double click on it to add his name on text writer. - + items found. objecten gevonden. @@ -2756,7 +2990,7 @@ Double click on it to add his name on text writer. Typ een bericht hier - + Don't stop to color after @@ -2914,12 +3148,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Gegevens - + Local Address Lokaal adres @@ -2930,12 +3164,12 @@ Double click on it to add his name on text writer. Extern adres - + Node info: - + Current address: @@ -2951,31 +3185,41 @@ Double click on it to add his name on text writer. Poort - + Include signatures Inclusief handtekeningen - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: kan geen verbindings gegevens vinden. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2991,22 +3235,22 @@ Double click on it to add his name on text writer. - + Encryption Versleuteling - + Not connected Niet verbonden - + Retroshare node details - + Node name : @@ -3041,13 +3285,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3062,7 +3311,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3073,17 +3322,22 @@ Double click on it to add his name on text writer. Geen - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3093,7 +3347,7 @@ Double click on it to add his name on text writer. - + with @@ -3285,12 +3539,12 @@ Double click on it to add his name on text writer. Gegevens van uw aanvraag - + Peer details Verbindings details - + Name: Naam: @@ -3303,12 +3557,12 @@ Double click on it to add his name on text writer. Knooppunt - + Location: Woonplaats: - + Options Opties @@ -3317,12 +3571,12 @@ Double click on it to add his name on text writer. Voeg het certificaat handmatig in - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Voeg een vriend toe aan een groep: @@ -3332,7 +3586,7 @@ Double click on it to add his name on text writer. Verifieer vriend (Teken PGP Sleutel) - + Please paste below your friend's Retroshare ID @@ -3357,7 +3611,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Voeg toe als vriend om mee verbonden te worden @@ -3366,7 +3620,7 @@ Double click on it to add his name on text writer. Om je vriend's verzoek te accepteren klik de Klaar knop - + Sorry, some error appeared Sorry, een error verscheen @@ -3386,32 +3640,32 @@ Double click on it to add his name on text writer. Gegevens van uw vriend: - + Key validity: Sleutel deugdelijkheid: - + Profile ID: - + Signers Ondertekenaars - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Deze verbinding staat al op je vriend zijn lijst. Toevoegen stelt waarschijnlijk alleen zijn ip adres in. - + To accept the Friend Request, click the Accept button. @@ -3457,7 +3711,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Certificaat fout @@ -3490,12 +3744,12 @@ Double click on it to add his name on text writer. Verbindings ID - + Not a valid Retroshare certificate! - + RetroShare Invitation RetroShare uitnodiging @@ -3515,12 +3769,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3568,7 +3822,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.U heeft een aanvraag om vriend te worden - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3656,12 +3940,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Gebruiken als directe bron indien mogelijk - + IP-Addr: IP-Adr: - + IP-Address IP Adres: @@ -3719,7 +4003,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Sleutel toevoegen aan keyring - + This key is already in your keyring Deze sleutel is al in uw keyring @@ -3777,12 +4061,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 Toegevoegd met certificaat van %1 @@ -3865,7 +4149,12 @@ even if you don't make friends. UDP Resultaat - + + Status + Status + + + <!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; } @@ -4287,7 +4576,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4435,7 +4724,7 @@ p, li { white-space: pre-wrap; } Geen Cirkel Limitaties Geselecteerd - + [Unknown] @@ -4450,7 +4739,7 @@ p, li { white-space: pre-wrap; } Verwijder - + Search Zoek @@ -4470,7 +4759,7 @@ p, li { white-space: pre-wrap; } Ondertekend door bekende knooppunten - + Edit Circle Bewerk Cirkel @@ -4490,12 +4779,12 @@ p, li { white-space: pre-wrap; } Anoniem ID - + Circle name - + Update @@ -4521,7 +4810,7 @@ p, li { white-space: pre-wrap; } PGP geaccocieerd ID - + Add Member @@ -4665,7 +4954,7 @@ p, li { white-space: pre-wrap; }⏎ - + Attachments Attachments @@ -4711,7 +5000,7 @@ p, li { white-space: pre-wrap; }⏎ Bestanden Slepen en Neerzetten uit het zoek resultaat - + Paste RetroShare Links PLak RetroShare Link's @@ -4721,7 +5010,7 @@ p, li { white-space: pre-wrap; }⏎ PLak RetroShare Link - + Drop file error. Verwijder bestands error @@ -4748,17 +5037,41 @@ p, li { white-space: pre-wrap; }⏎ - + RetroShare RetroShare - - File already Added and Hashed - Bestand is reeds toegevoegd en in de hash opgenomen + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Bestand is reeds toegevoegd en in de hash opgenomen + + + Please add a Subject Voeg een onderwerp toe @@ -4789,12 +5102,12 @@ p, li { white-space: pre-wrap; }⏎ Wilt u echt %1 berichten genereren? - + You are about to add files you're not actually sharing. Do you still want this to happen? U gaat nu bestanden toevoegen die niet gedeeld zijn. Weet u zeker dat u dat wilt? - + Edit Channel Post @@ -4814,7 +5127,7 @@ p, li { white-space: pre-wrap; }⏎ - + About to post un-owned files to a channel. U staat op het punt om bestanden waar u geen eigenaar van bent naar een Kanaal te posten. @@ -4906,7 +5219,7 @@ p, li { white-space: pre-wrap; } - + No Forum Geen Forum @@ -5361,7 +5674,7 @@ en daar de importeer functie gebruiken DHTGraphSource - + users gebruikers @@ -6364,7 +6677,7 @@ en daar de importeer functie gebruiken FlatStyle_RDM - + Friends Directories Vrienden directories @@ -6859,7 +7172,7 @@ at least one peer was not added to a group Zoek vrienden - + Mark all Selecteer alles @@ -6873,7 +7186,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Bewerk berichten status @@ -6977,7 +7290,7 @@ at least one peer was not added to a group Retroshare groepschat: berichten worden verstuurd naar alle verbonden vrienden. - + Network Netwerk @@ -7042,7 +7355,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7073,7 +7386,7 @@ at least one peer was not added to a group - + Node name @@ -7332,12 +7645,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7709,7 +8022,7 @@ p, li { white-space: pre-wrap; } Router Statistieken - + GroupBox @@ -7774,7 +8087,7 @@ p, li { white-space: pre-wrap; } - + Details Gegevens @@ -7797,7 +8110,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Beheerde sleutels @@ -7998,7 +8311,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8008,13 +8321,30 @@ p, li { white-space: pre-wrap; } Zoek Titel - - + + + + Description Beschrijving - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Zoek beschrijving @@ -8024,42 +8354,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sorteer op naam + Sorteer op naam - Sort by Popularity - Sorteer op populariteit + Sorteer op populariteit - Sort by Last Post - Sorteer op laatste post + Sorteer op laatste post - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8074,40 +8381,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Het laatste bericht - + + Name Naam - - Unread - - - - + Popularity Populariteit - - + + Never - Display - Toon + Toon - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8256,7 +8558,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanalen @@ -8277,12 +8579,12 @@ p, li { white-space: pre-wrap; } Mijn Kanalen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Geabonneerde kanalen @@ -8755,7 +9057,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8855,12 +9157,12 @@ p, li { white-space: pre-wrap; } - + Files Bestanden - + Comments Opmerkingen @@ -8871,18 +9173,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8892,12 +9194,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8957,7 +9259,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8972,12 +9274,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9053,23 +9355,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Geabonneerd - - Subscribe Registreren - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Geen kanaal geselecteerd @@ -9091,11 +9406,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanaal bericht - - - new message(s) - - GxsCircleItem @@ -9613,7 +9923,7 @@ voor je een opmerking kan doen Start een nieuw draadje in het geselecteerde forum - + Search forums Zoek forums @@ -9622,12 +9932,12 @@ voor je een opmerking kan doen Het laatste bericht - + New Thread Nieuw draadje - + Threaded View Threaded View @@ -9637,19 +9947,19 @@ voor je een opmerking kan doen Flat View - - + + Title Titel - - + + Date Datum - + Author Auteur @@ -9664,7 +9974,17 @@ voor je een opmerking kan doen Laden - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9721,23 +10041,23 @@ voor je een opmerking kan doen Zoek Inhoud - + No name Geen naam - - + + Reply Antwoord - + <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> - + Loading... @@ -9775,12 +10095,12 @@ voor je een opmerking kan doen Merk als ongelezen - + Copy RetroShare Link Kopieer RetroShare Link - + Hide Verberg @@ -9789,7 +10109,7 @@ voor je een opmerking kan doen Uitbreiden - + [unknown] @@ -9819,8 +10139,8 @@ voor je een opmerking kan doen - - + + Distribution @@ -9919,12 +10239,12 @@ voor je een opmerking kan doen Origineel bericht - + New thread - + Edit Bewerk @@ -9980,7 +10300,7 @@ voor je een opmerking kan doen - + Author's reputation @@ -10000,7 +10320,7 @@ voor je een opmerking kan doen - + <b>Loading...<b> @@ -10040,6 +10360,11 @@ voor je een opmerking kan doen Storage + + + Last seen at friends: + + Moderators @@ -10107,7 +10432,7 @@ This message is missing. You should receive it later. Op %1, %2 schreef: - + Forum name @@ -10139,11 +10464,6 @@ This message is missing. You should receive it later. Forum Post Forum bericht - - - new message(s) - - GxsForumsDialog @@ -10592,7 +10912,7 @@ This message is missing. You should receive it later. PrintVoorbeeld - + Unsubscribe Uitschrijven @@ -10607,7 +10927,7 @@ This message is missing. You should receive it later. Open in een nieuw tab - + Remove this search @@ -10617,12 +10937,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Details weergeven @@ -10689,12 +11009,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopieer RetroShare Link @@ -10709,7 +11029,7 @@ This message is missing. You should receive it later. Merk alles als ongelezen - + AUTHD AUTHD @@ -11243,7 +11563,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11252,7 +11572,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11278,7 +11598,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11356,49 +11676,55 @@ p, li { white-space: pre-wrap; }⏎ Formulier - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopieer uw certificaat naar het klembord @@ -11446,17 +11772,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11471,7 +11792,12 @@ new short format RetroShare uitnodiging - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Sla op als... @@ -11736,14 +12062,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alles - + Reputation Reputatie @@ -11753,12 +12079,12 @@ p, li { white-space: pre-wrap; } Zoek - + Anonymous Id Anoniem Id - + Create new Identity Maak een nieuwe identiteit @@ -11902,7 +12228,7 @@ p, li { white-space: pre-wrap; } - + Send message Verstuur bericht @@ -11974,7 +12300,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anoniem @@ -11989,24 +12315,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you Deze identiteit is eigendom van u - - + + My own identities - - + + My contacts - + Show Items @@ -12021,7 +12347,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12080,13 +12406,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12146,7 +12477,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Bewerk Cirkel @@ -12194,7 +12525,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12203,12 +12534,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12220,12 +12551,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node Identiteit eigendom van u, gekoppeld aan uw Retroshare knoop @@ -12341,17 +12672,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12508,8 +12839,8 @@ These identities will soon be not supported anymore. - - + + People Mensen @@ -12520,7 +12851,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12530,7 +12861,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12590,7 +12921,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12600,7 +12931,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12638,7 +12969,22 @@ These identities will soon be not supported anymore. Pseudoniem - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nieuwe identiteit @@ -12655,14 +13001,14 @@ These identities will soon be not supported anymore. - + N/A Onbekend - + Edit identity Identiteit aanpassen @@ -12673,24 +13019,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12709,17 +13058,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Fout bij ophalen sleutel! - + Error KeyID invalid SleutelID is ongeldig - + Unknown GpgId Onbekend GPG ID @@ -12729,7 +13088,7 @@ These identities will soon be not supported anymore. Onbekende echte naam - + Create New Identity Maak een nieuwe identiteit @@ -12739,7 +13098,12 @@ These identities will soon be not supported anymore. Type - + + Choose image... + + + + @@ -12779,12 +13143,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12794,7 +13153,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12899,8 +13258,12 @@ These identities will soon be not supported anymore. + Quote + Citaat + + Send - Verstuur + Verstuur @@ -13058,7 +13421,7 @@ These identities will soon be not supported anymore. - + Options Opties @@ -13090,12 +13453,12 @@ These identities will soon be not supported anymore. Snel start Wizard - + RetroShare %1 a secure decentralized communication platform RetroShare %1 is een beveiligd gedecentraliseerde communicatie platform - + Unfinished Niet afgemaakt @@ -13227,7 +13590,7 @@ Maak meer ruimte vrij en klik Ok. Toon - + Make sure this link has not been forged to drag you to a malicious website. Wees er zeker van dat deze link je niet naar een verdachte website stuurt @@ -13272,7 +13635,7 @@ Maak meer ruimte vrij en klik Ok. Service toestemming matrix - + Statistics Statistieken @@ -13301,7 +13664,7 @@ Maak meer ruimte vrij en klik Ok. MessageComposer - + Compose Opstellen @@ -13403,7 +13766,7 @@ Maak meer ruimte vrij en klik Ok. - + Tags Labels @@ -13498,12 +13861,12 @@ Maak meer ruimte vrij en klik Ok. Voeg een citaat blok toe - + Send To: Verstuur naar: - + &Left &links @@ -13533,7 +13896,12 @@ Maak meer ruimte vrij en klik Ok. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hallo,<br>ik wil een goede vriend van mij aanraden; als je mij vertrouwd kun je hem ook vertrouwen. <br> @@ -13559,12 +13927,12 @@ Maak meer ruimte vrij en klik Ok. - + Save Message Bewaar bericht - + Message has not been Sent. Do you want to save message to draft box? Bericht is niet verzonden.⏎ @@ -13576,7 +13944,7 @@ Wil je het bericht bewaren in de concepten map? PLak RetroShare Link - + Add to "To" Voeg toe aan "Aan" @@ -13831,7 +14199,7 @@ Wil je het bericht bewaren? Voeg extra bestand toe - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13845,6 +14213,21 @@ Wil je het bericht bewaren? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13857,7 +14240,7 @@ Wil je het bericht bewaren? Van: - + Bullet list (disc) @@ -13897,13 +14280,13 @@ Wil je het bericht bewaren? - - + + Thanks, <br> - + Distant identity: @@ -14042,8 +14425,23 @@ Wil je het bericht bewaren? Bericht - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14055,12 +14453,12 @@ Wil je het bericht bewaren? Aanbevolen bestanden - + Download all Recommended Files Download alle Aanbevolen bestanden - + Subject: Onderwerp: @@ -14135,12 +14533,18 @@ Wil je het bericht bewaren? - + + Message Size: + + + + File Name Bestandsnaam - + + Size Grootte @@ -14201,18 +14605,33 @@ Wil je het bericht bewaren? Download - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Download alles - + Print Document Print Document @@ -14227,7 +14646,7 @@ Wil je het bericht bewaren? HTML- bestand (*.htm *.html );;Alle bestanden (*) - + Load images always for this message Afbeeldingen altijd laden voor dit bericht @@ -14368,7 +14787,7 @@ Wil je het bericht bewaren? MessagesDialog - + New Message Nieuw bericht @@ -14424,14 +14843,14 @@ Wil je het bericht bewaren? - + Tags Labels - + Inbox Inbox @@ -14526,7 +14945,7 @@ Wil je het bericht bewaren? Stuur bericht door - + Subject Onderwerp @@ -14638,7 +15057,7 @@ Wil je het bericht bewaren? - + Open in a new window Open in een nieuw scherm @@ -14723,7 +15142,7 @@ Wil je het bericht bewaren? - + Drafts Concepten @@ -14844,7 +15263,7 @@ Wil je het bericht bewaren? Beantwoord bericht - + Delete Message Verwijder bericht @@ -14855,7 +15274,7 @@ Wil je het bericht bewaren? - + Expand Uitbreiden @@ -14865,7 +15284,7 @@ Wil je het bericht bewaren? Item verwijderen - + from van @@ -14874,6 +15293,11 @@ Wil je het bericht bewaren? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15187,7 +15611,7 @@ Reported error: - + Groups Groepen @@ -15217,19 +15641,19 @@ Reported error: importeer vriendenlijst, inclusief groepen - - + + Search - + ID ID - + Search ID @@ -15239,7 +15663,7 @@ Reported error: - + Show Items @@ -15438,18 +15862,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -15487,7 +15911,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15505,7 +15929,7 @@ at least one peer was not added to a group Dit is een test. - + Newest on top @@ -15516,20 +15940,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15566,22 +16005,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon Systeem tray ikoon - + Message Bericht @@ -15606,12 +16045,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Vriend verbonden @@ -15658,27 +16092,37 @@ at least one peer was not added to a group Groeps chat - + + Toaster position + + + + Chat rooms - + Position Positie - + + Activity + + + + X Margin X marge - + Y Margin Y marge - + Systray message Systemtray bericht @@ -15728,7 +16172,7 @@ at least one peer was not added to a group Notify - + Disable All Toasters Alle Toasters uitschakelen @@ -15742,7 +16186,7 @@ at least one peer was not added to a group Feed - + Systray @@ -15884,17 +16328,16 @@ Laag verkeer: 10% standaard verkeerd en TODO: pauseerd alle bestands overdrachte PGPKeyDialog - Dialog - Dialoog + Dialoog - + Profile info - + Name : @@ -15949,22 +16392,17 @@ Laag verkeer: 10% standaard verkeerd en TODO: pauseerd alle bestands overdrachte Uiterst - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15978,7 +16416,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15988,22 +16426,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Onderteken PGP Sleutel + Onderteken PGP Sleutel - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16023,7 +16455,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16089,28 +16521,28 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: kan geen verbindings gegevens vinden. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) De ingevoerde sleutel algoritme wordt niet ondersteund door RetroShare⏎ (Alleen RSA sleutels worden op dit moment ondersteund) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16122,7 +16554,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16167,27 +16599,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Handtekening fout - - Maybe password is wrong - Misschien is uw wachtwoord fout + + Check the password! + - + Maybe password is wrong + Misschien is uw wachtwoord fout + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16366,8 +16818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Mensen @@ -16384,7 +16835,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Interne - + Chat with this person @@ -16527,7 +16978,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel Tekst label @@ -16571,8 +17022,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Opmerkingen @@ -16607,6 +17058,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Schrijf een opmerking + + + Album + Album + PhotoItem @@ -16616,12 +17072,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulier - + TextLabel Tekst label - + <!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; } @@ -16717,7 +17173,7 @@ p, li { white-space: pre-wrap; }⏎ Bekijk Foto - + PhotoShare PhotoShare @@ -16758,7 +17214,7 @@ voordat je het kunt bewerken! - + Stop Stop @@ -16986,12 +17442,12 @@ p, li { white-space: pre-wrap; }⏎ PluginsPage - + Authorize all plugins Authoriseer alle plugins - + Plugin look-up directories Plugin look-up directories @@ -17031,7 +17487,7 @@ malicious behavior of crafted plugins. Controleer dit voor plugin ontwikkeling. Zij worden niet gecontroleerd voor de index. Echter, gewoonlijk zal het controleren van de index je beschermen tegen verdacht gebruik van de plugins - + Plugins Plugins @@ -17413,7 +17869,7 @@ malicious behavior of crafted plugins. Andere Onderwerpen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17584,13 +18040,13 @@ malicious behavior of crafted plugins. Site - - + + Comments Opmerkingen - + Copy RetroShare Link Kopieer RetroShare Link @@ -17600,7 +18056,7 @@ malicious behavior of crafted plugins. - + Comment Opmerking @@ -17621,12 +18077,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up Stemmen van @@ -17640,7 +18096,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item Markeer als gelezen en verplaats item @@ -17701,7 +18157,7 @@ malicious behavior of crafted plugins. Tekst label - + Loading Laden @@ -17787,13 +18243,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17803,60 +18253,50 @@ malicious behavior of crafted plugins. - - - + + + unknown onbekend - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Tekst label - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17867,7 +18307,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17936,7 +18376,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link Kopieer RetroShare Link @@ -17971,7 +18416,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18095,8 +18540,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18368,9 +18823,8 @@ en daar de importeer functie gebruiken PulseAddDialog - Post From: - Bericht van: + Bericht van: Account 1 @@ -18385,7 +18839,7 @@ en daar de importeer functie gebruiken Account 3 - + Add to Pulse Voeg aan Pulse toe @@ -18408,17 +18862,32 @@ en daar de importeer functie gebruiken URL - + GroupLabel - + IDLabel - + + From: + Van: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18443,10 +18912,20 @@ en daar de importeer functie gebruiken - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18456,14 +18935,53 @@ en daar de importeer functie gebruiken - + + Post + + + + Cancel Annuleren - Post Pulse to Wire - Post Pulse to Wire + Post Pulse to Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18489,10 +19007,18 @@ en daar de importeer functie gebruiken Formulier - - - - + + + + + Click to view picture + + + + + + + Image PLaatje @@ -18500,44 +19026,44 @@ en daar de importeer functie gebruiken PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18547,17 +19073,17 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18567,7 +19093,7 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18575,7 +19101,7 @@ en daar de importeer functie gebruiken PulseTopLevel - + retweeted @@ -18590,7 +19116,7 @@ en daar de importeer functie gebruiken - + follow Parent Group @@ -18600,7 +19126,7 @@ en daar de importeer functie gebruiken ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18625,7 +19151,7 @@ en daar de importeer functie gebruiken - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18661,29 +19187,29 @@ en daar de importeer functie gebruiken - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18761,7 +19287,7 @@ en daar de importeer functie gebruiken QObject - + Confirmation Bevestiging @@ -19003,7 +19529,7 @@ Karakters <b>",|,/,\,&lt;,&gt;,*,?</b> worden vervangen Resultaat - + Unable to make path Niet mogelijk om pad te maken @@ -19038,7 +19564,7 @@ Karakters <b>",|,/,\,&lt;,&gt;,*,?</b> worden vervangen Bestands aanvraag gestopt - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Deze versie van RetroShare maakt gebruik van OpenPGP-SDK. Als bijeffect gebruikt het niet de gedeelde PGP sleutelring maar heeft zijn eigen sleutelring die gebruikt wordt door alle RetroShare gevallen.<br><br> @@ -19181,7 +19707,7 @@ De error is: %2 secs - + TR up TR omhoog @@ -19226,7 +19752,7 @@ De error is: %2 - + Move IP %1 to whitelist @@ -19242,7 +19768,7 @@ De error is: %2 - + %1 seconds ago @@ -19326,7 +19852,7 @@ Security: no anonymous IDs - + Error Fout @@ -19716,11 +20242,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -20090,7 +20611,7 @@ p, li { white-space: pre-wrap; }⏎ RSGraphWidget - + %1 KB %1 KB @@ -20312,18 +20833,39 @@ p, li { white-space: pre-wrap; }⏎ RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20760,7 +21302,7 @@ p, li { white-space: pre-wrap; }⏎ Download! - + File Bestand @@ -20775,7 +21317,7 @@ p, li { white-space: pre-wrap; }⏎ Index - + Bad filenames have been cleaned Verkeerde bestandsnamen zijn opgeschoond @@ -20825,7 +21367,7 @@ Betrokken bestanden zijn rood gekleurd Opslaan - + Collection Editor Collection Editor @@ -20840,7 +21382,7 @@ Betrokken bestanden zijn rood gekleurd Bestandstotaal - + Real Size: Waiting child... Werkelijke grootte: Wachten ... @@ -20855,12 +21397,12 @@ Betrokken bestanden zijn rood gekleurd Dit is een directory. Dubbelklik om te openen - + Download files - + Specify... Specificeer... @@ -21109,7 +21651,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde RsFriendListModel - + Name Naam @@ -21129,7 +21671,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde IP - + Profile ID @@ -21142,10 +21684,15 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde RsGxsForumModel - + Title Titel + + + UnRead + + Date @@ -21157,7 +21704,7 @@ Als u denkt dat het is juist dat, de bijbehorende regel uit het bestand verwijde Auteur - + Information for this identity is currently missing. @@ -21195,7 +21742,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Bericht ontbreekt ... ] @@ -21203,7 +21750,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21263,7 +21810,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21618,7 +22165,7 @@ prevents the message to be forwarded to your friends. Bestandsnaam - + Download Download @@ -21697,7 +22244,7 @@ prevents the message to be forwarded to your friends. Open map - + Create Collection... Collectie maken... @@ -21717,7 +22264,7 @@ prevents the message to be forwarded to your friends. Download van collectief bestand... - + Collection Collectie @@ -21822,12 +22369,12 @@ prevents the message to be forwarded to your friends. Verbindings details - + Deny friend Weiger vriend - + Chat Chat @@ -21837,7 +22384,7 @@ prevents the message to be forwarded to your friends. Start chat - + Expand Uitbreiden @@ -22107,13 +22654,13 @@ je ook als ja achter een Firewall of VPN zit. Discovery ingeschakeld (aanbevolen) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Ontdekking uit @@ -22579,7 +23126,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Netwerk @@ -22607,7 +23154,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22704,7 +23251,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22739,12 +23286,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23412,7 +23959,7 @@ p, li { white-space: pre-wrap; } Ontbrekende PGP certificaat - + Wrong password @@ -23454,7 +24001,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Vriend toevoegen @@ -23510,7 +24057,7 @@ This choice can be reverted in settings. Service toestemming matrix - + DHT DHT @@ -24050,7 +24597,7 @@ p, li { white-space: pre-wrap; }⏎ TorStatus - + Tor @@ -24060,13 +24607,12 @@ p, li { white-space: pre-wrap; }⏎ - - + Tor is currently offline - + Tor is OK @@ -24075,6 +24621,31 @@ p, li { white-space: pre-wrap; }⏎ No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24348,35 +24919,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Je hebt %1 complete downloads + You have %1 completed transfers + - You have %1 completed download - Je hebt %1 complete download + You have %1 completed transfer + - %1 completed downloads - %1 complete downloads + %1 completed transfers + - %1 completed download - %1 complete download + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Je hebt %1 complete downloads + + + You have %1 completed download + Je hebt %1 complete download + + + %1 completed downloads + %1 complete downloads + + + %1 completed download + %1 complete download TransfersDialog - + Downloads Downloads @@ -24387,7 +24969,7 @@ p, li { white-space: pre-wrap; } Uploads - + Name i.e: file name Naam @@ -24594,7 +25176,7 @@ p, li { white-space: pre-wrap; } Specificeer... - + Move in Queue... Verplaats in Rij... @@ -24688,7 +25270,7 @@ p, li { white-space: pre-wrap; } Vul een nieuwe -en geldige- bestandsnaam in - + Expand all Alles uitklappen @@ -24820,7 +25402,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolommen @@ -24831,7 +25413,7 @@ p, li { white-space: pre-wrap; } Bestandsoverdrachten - + Path Pad @@ -24841,7 +25423,7 @@ p, li { white-space: pre-wrap; } Pad kolom weergeven - + Could not delete preview file Kan geen gegevens verwijderen voorvertoningsbestand @@ -24851,7 +25433,7 @@ p, li { white-space: pre-wrap; } Probeer het opnieuw? - + Create Collection... Collectie maken.. @@ -24866,7 +25448,7 @@ p, li { white-space: pre-wrap; } Bekijk collectie.. - + Collection Collectie @@ -25108,7 +25690,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Onbekenden verbinding @@ -25204,7 +25786,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages U heeft %1 nieuwe berichten @@ -25576,7 +26158,7 @@ p, li { white-space: pre-wrap; } Maak een groep - + Subscribe to Group Registreer bij deze Groep @@ -25670,8 +26252,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Toon Bewerkte Geschiedenis @@ -25682,7 +26264,7 @@ p, li { white-space: pre-wrap; } - + Preview Voorbeeld @@ -25707,12 +26289,12 @@ p, li { white-space: pre-wrap; } Verberg Bewerkte Geschiedenis - + Edit Page Bewerk pagina - + Create New Wiki Page Maak een nieuwe Wiki pagina @@ -25732,7 +26314,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Maak een nieuwe Wiki groep @@ -25774,7 +26356,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -25784,12 +26366,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Ververs @@ -25824,12 +26405,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25899,7 +26480,7 @@ p, li { white-space: pre-wrap; } Toon: - + Yourself Uzelf @@ -25937,7 +26518,7 @@ p, li { white-space: pre-wrap; } Post Pulse to Wire - + RetroShare RetroShare @@ -25949,7 +26530,7 @@ p, li { white-space: pre-wrap; } - + The Wire De Kabel @@ -25957,7 +26538,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26038,8 +26619,8 @@ p, li { white-space: pre-wrap; } Formulier - - + + Avatar Avatar @@ -26068,6 +26649,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26180,7 +26766,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_pl.ts b/retroshare-gui/src/lang/retroshare_pl.ts index d98bb81ec..ef7478036 100644 --- a/retroshare-gui/src/lang/retroshare_pl.ts +++ b/retroshare-gui/src/lang/retroshare_pl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Wyszukiwanie zaawansowane - + Search Criteria Kryteria wyszukiwania - + Add a further search criterion. Dodaj następne kryterium wyszukiwania. @@ -271,7 +271,7 @@ AlbumDialog - + Album Album @@ -410,7 +410,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -453,8 +453,8 @@ p, li { white-space: pre-wrap; } Formularz - - + + TextLabel @@ -529,7 +529,7 @@ p, li { white-space: pre-wrap; } - + Icon Only Tylko ikona @@ -554,7 +554,7 @@ p, li { white-space: pre-wrap; } Wybierz styl przycisków narzędzi - + Icon Size = 8x8 Rozmiar ikon = 8x8 @@ -579,7 +579,7 @@ p, li { white-space: pre-wrap; } Rozmiar ikon = 128x128 {128x?} - + Status Bar @@ -654,7 +654,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -669,7 +669,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Rozmiar ikon = 32x32 {32x?} @@ -735,13 +735,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -750,25 +755,30 @@ p, li { white-space: pre-wrap; } Usuń - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar Kliknij, aby zmienić swój awatar @@ -776,7 +786,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -796,44 +806,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Zużycie łącza przez RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Pokaż ustawienia + TextLabel + + + + Reset Zresetuj - Receive Rate - Prędkość pobierania + Prędkość pobierania - Send Rate - Prędkość wysyłania + Prędkość wysyłania - + Always on Top Zawsze na wierzchu - Style - Styl + Styl - + Changes the transparency of the Bandwidth Graph Zmienia przezroczystość wykresu zużycia łącza - + 100 100 @@ -843,30 +874,27 @@ p, li { white-space: pre-wrap; } % nieprzezroczysty - Save - Zapisz + Zapisz - Cancel - Anuluj + Anuluj - + Since: Od: - Hide Settings - Ukryj ustawienia + Ukryj ustawienia BandwidthStatsWidget - + Sum @@ -888,7 +916,7 @@ p, li { white-space: pre-wrap; } Liczba - + Average @@ -1022,7 +1050,7 @@ p, li { white-space: pre-wrap; } - + Comments Komentarze @@ -1100,6 +1128,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Przełącz status przeczytanej wiadomości + + + + Avatar + Awatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Rozwiń + + + + Set as read and remove item + + + + + Remove Item + Usuń element + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Ukryj + + BwCtrlWindow @@ -1235,6 +1342,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Domyślne + + + + Dark + + ChannelPage @@ -1287,6 +1404,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Przełącz status przeczytanej wiadomości + + + + Avatar + Awatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Rozwiń + + + + Set as read and remove item + + + + + Remove Item + Usuń element + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Ukryj + + ChatLobbyDialog @@ -1494,24 +1690,40 @@ into the image, so as to - You have %1 new messages - Masz %1 nowych wiadomości + Masz %1 nowych wiadomości + + + You have %1 new message + Masz %1 nową wiadomość + + + %1 new messages + %1 nowych wiadomości + + + %1 new message + %1 nowa wiadomość + + + + You have %1 mentions + - You have %1 new message - Masz %1 nową wiadomość + You have %1 mention + - %1 new messages - %1 nowych wiadomości + %1 mentions + - %1 new message - %1 nowa wiadomość + %1 mention + @@ -1524,11 +1736,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1993,13 +2200,11 @@ Double click a chat room to enter and chat. - Group chat - Chat grupowy + Chat grupowy - - + Private chat Chat prywatny @@ -2064,17 +2269,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2095,11 +2295,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2160,11 +2361,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2303,8 +2510,23 @@ Double click a chat room to enter and chat. Prywatny Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2473,7 +2695,7 @@ Double click a chat room to enter and chat. - + is typing... pisze... @@ -2490,12 +2712,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Czy naprawdę chcesz fizycznie usunąć historię? @@ -2567,7 +2789,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2603,12 +2825,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2624,7 +2846,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2644,7 +2866,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2802,12 +3024,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Szczegóły - + Local Address Adres Lokalny @@ -2818,12 +3040,12 @@ Double click on it to add his name on text writer. Adres zewnętrzny - + Node info: - + Current address: @@ -2839,31 +3061,41 @@ Double click on it to add his name on text writer. Port - + Include signatures Załącz podpisy - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2879,22 +3111,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2929,13 +3161,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2950,7 +3187,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2961,17 +3198,22 @@ Double click on it to add his name on text writer. brak - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2981,7 +3223,7 @@ Double click on it to add his name on text writer. - + with @@ -3089,12 +3331,12 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Nazwa: @@ -3103,22 +3345,22 @@ Double click on it to add his name on text writer. Email: - + Location: Miejsce: - + Options Opcje - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Dodaj przyjaciela do grupy: @@ -3128,7 +3370,7 @@ Double click on it to add his name on text writer. Uwierzytelnij znajomego (Podpisz Klucz PGP) - + Please paste below your friend's Retroshare ID @@ -3153,12 +3395,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -3178,32 +3420,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3249,17 +3491,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Ładowanie certyfikatu nie powiodło się - + Not a valid Retroshare certificate! - + RetroShare Invitation Zaproszenie RetroShare @@ -3279,12 +3521,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3332,7 +3574,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3388,12 +3660,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3431,7 +3703,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3489,12 +3761,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3569,7 +3841,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3991,7 +4268,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4139,7 +4416,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -4154,7 +4431,7 @@ p, li { white-space: pre-wrap; } - + Search Szukaj @@ -4170,7 +4447,7 @@ p, li { white-space: pre-wrap; } Podpisane - + Edit Circle @@ -4186,12 +4463,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4213,7 +4490,7 @@ p, li { white-space: pre-wrap; } Utwórz - + Add Member @@ -4347,7 +4624,7 @@ p, li { white-space: pre-wrap; } - + Attachments Załączniki @@ -4393,7 +4670,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4403,7 +4680,7 @@ p, li { white-space: pre-wrap; } Wklej Link RetroShare - + Drop file error. @@ -4430,17 +4707,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4471,12 +4768,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4496,7 +4793,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4588,7 +4885,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -5011,7 +5308,7 @@ and use the import button to load it DHTGraphSource - + users @@ -6014,7 +6311,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Katalogi Przyjaciół @@ -6505,7 +6802,7 @@ at least one peer was not added to a group Szukaj Przyjaciół - + Mark all Zaznacz wszystkie @@ -6519,7 +6816,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6623,7 +6920,7 @@ at least one peer was not added to a group - + Network @@ -6688,7 +6985,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6719,7 +7016,7 @@ at least one peer was not added to a group - + Node name @@ -6978,12 +7275,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7346,7 +7643,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7411,7 +7708,7 @@ p, li { white-space: pre-wrap; } - + Details Szczegóły @@ -7434,7 +7731,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7635,7 +7932,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Tytuł @@ -7645,13 +7942,30 @@ p, li { white-space: pre-wrap; } Szukaj Tytuł - - + + + + Description Opis - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Szukaj Opisu @@ -7661,42 +7975,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sortuj według Nazwy + Sortuj według Nazwy - Sort by Popularity - Sortuj według Popularności + Sortuj według Popularności - Sort by Last Post - Sortuj według Ostatniego Postu + Sortuj według Ostatniego Postu - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7711,40 +8002,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Ostatni Post - + + Name - - Unread - - - - + Popularity Popularność - - + + Never - Display - Wyświetl + Wyświetl - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7893,7 +8179,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanały @@ -7914,12 +8200,12 @@ p, li { white-space: pre-wrap; } Moje Kanały - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Subskrybowane kanały @@ -8356,7 +8642,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8456,12 +8742,12 @@ p, li { white-space: pre-wrap; } - + Files Pliki - + Comments Komentarze @@ -8472,18 +8758,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8493,12 +8779,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8558,7 +8844,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8573,12 +8859,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8654,23 +8940,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Subskrybowane - - Subscribe Zapisz się - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Nie wybrano kanału @@ -8692,11 +8991,6 @@ p, li { white-space: pre-wrap; } Channel Post Wiadomość - - - new message(s) - - GxsCircleItem @@ -9200,7 +9494,7 @@ before you can comment Rozpocznij nowy Wątek dla Wybranego Forum - + Search forums Przeszukaj fora @@ -9209,12 +9503,12 @@ before you can comment Ostatni Post - + New Thread Nowy Wątek - + Threaded View Widok Wątku @@ -9224,19 +9518,19 @@ before you can comment Widok Płaski - - + + Title Tytuł - - + + Date Data - + Author Autor @@ -9251,7 +9545,17 @@ before you can comment Wczytywanie - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9308,23 +9612,23 @@ before you can comment Szukaj Zawartości - + No name Bez nazwy - - + + Reply Odpowiedz - + <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> - + Loading... @@ -9362,12 +9666,12 @@ before you can comment Oznacz jako nieprzeczytane - + Copy RetroShare Link Skopiuj Link RetroShare - + Hide Ukryj @@ -9376,7 +9680,7 @@ before you can comment Rozwiń - + [unknown] @@ -9406,8 +9710,8 @@ before you can comment - - + + Distribution @@ -9506,12 +9810,12 @@ before you can comment Oryginalna Wiadomość - + New thread - + Edit Edytuj @@ -9567,7 +9871,7 @@ before you can comment - + Author's reputation @@ -9587,7 +9891,7 @@ before you can comment - + <b>Loading...<b> @@ -9627,6 +9931,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9694,7 +10003,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9726,11 +10035,6 @@ This message is missing. You should receive it later. Forum Post Wiadomość - - - new message(s) - - GxsForumsDialog @@ -10159,7 +10463,7 @@ This message is missing. You should receive it later. Podgląd wydruku - + Unsubscribe Wypisz się @@ -10174,7 +10478,7 @@ This message is missing. You should receive it later. Otwórz w nowej karcie - + Remove this search @@ -10184,12 +10488,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10256,12 +10560,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Skopiuj Link RetroShare @@ -10276,7 +10580,7 @@ This message is missing. You should receive it later. Oznacz wszystkie jako nieprzeczytane - + AUTHD @@ -10798,7 +11102,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10807,7 +11111,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10833,7 +11137,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10911,49 +11215,55 @@ p, li { white-space: pre-wrap; } Formularz - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -11001,17 +11311,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11026,7 +11331,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Zapisz jako... @@ -11291,14 +11601,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Wszyscy - + Reputation Reputacja @@ -11308,12 +11618,12 @@ p, li { white-space: pre-wrap; } Szukaj - + Anonymous Id - + Create new Identity Stwórz nową Tożsamość @@ -11457,7 +11767,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11529,7 +11839,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonim @@ -11544,24 +11854,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11576,7 +11886,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11635,13 +11945,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11701,7 +12016,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11749,7 +12064,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11758,12 +12073,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11775,12 +12090,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11896,17 +12211,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12063,8 +12378,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12075,7 +12390,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12085,7 +12400,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12145,7 +12460,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12155,7 +12470,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12193,7 +12508,7 @@ These identities will soon be not supported anymore. Pseudonim - + New identity @@ -12210,14 +12525,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -12228,24 +12543,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12265,12 +12583,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12280,7 +12623,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12290,7 +12633,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12330,12 +12678,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12345,7 +12688,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12450,8 +12793,12 @@ These identities will soon be not supported anymore. + Quote + Cytat + + Send - Wyślij + Wyślij @@ -12609,7 +12956,7 @@ These identities will soon be not supported anymore. - + Options Opcje @@ -12641,12 +12988,12 @@ These identities will soon be not supported anymore. Kreator szybkiego startu - + RetroShare %1 a secure decentralized communication platform RetroShare %1 bezpieczna, zdecentralizowana platforma komunikacji - + Unfinished Niedokończone @@ -12775,7 +13122,7 @@ These identities will soon be not supported anymore. Pokaż - + Make sure this link has not been forged to drag you to a malicious website. @@ -12820,7 +13167,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12849,7 +13196,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12951,7 +13298,7 @@ These identities will soon be not supported anymore. - + Tags Tagi @@ -13046,12 +13393,12 @@ These identities will soon be not supported anymore. - + Send To: Wyślij do: - + &Left &Lewo @@ -13081,7 +13428,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -13107,12 +13459,12 @@ These identities will soon be not supported anymore. - + Save Message Zapisz wiadomość - + Message has not been Sent. Do you want to save message to draft box? Wiadomość nie została wysłana. @@ -13124,7 +13476,7 @@ Czy chcesz zapisać wiadomość do wersji roboczych? Wklej Link RetroShare - + Add to "To" Dodaj do "Do" @@ -13379,7 +13731,7 @@ Czy chcesz zapisać wiadomość ? Dodaj dodatkowy plik - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13393,6 +13745,21 @@ Czy chcesz zapisać wiadomość ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13405,7 +13772,7 @@ Czy chcesz zapisać wiadomość ? Od klatki: - + Bullet list (disc) @@ -13445,13 +13812,13 @@ Czy chcesz zapisać wiadomość ? - - + + Thanks, <br> - + Distant identity: @@ -13590,8 +13957,23 @@ Czy chcesz zapisać wiadomość ? Wiadomość - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13603,12 +13985,12 @@ Czy chcesz zapisać wiadomość ? Rekomendowane Pliki - + Download all Recommended Files Pobierz wszystkie Polecane Pliki - + Subject: Temat: @@ -13683,12 +14065,18 @@ Czy chcesz zapisać wiadomość ? - + + Message Size: + + + + File Name Nazwa pliku - + + Size Rozmiar @@ -13749,18 +14137,33 @@ Czy chcesz zapisać wiadomość ? Pobierz - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Pobierz wszystkie - + Print Document Drukuj Dokument @@ -13775,7 +14178,7 @@ Czy chcesz zapisać wiadomość ? Pliki HTML (*.htm *.html);;Wszystkie pliki (*) - + Load images always for this message @@ -13908,7 +14311,7 @@ Czy chcesz zapisać wiadomość ? MessagesDialog - + New Message Nowa Wiadmość @@ -13956,14 +14359,14 @@ Czy chcesz zapisać wiadomość ? - + Tags Tagi - + Inbox Przychodzące @@ -14058,7 +14461,7 @@ Czy chcesz zapisać wiadomość ? - + Subject Tytuł @@ -14138,7 +14541,7 @@ Czy chcesz zapisać wiadomość ? - + Open in a new window @@ -14223,7 +14626,7 @@ Czy chcesz zapisać wiadomość ? - + Drafts @@ -14320,7 +14723,7 @@ Czy chcesz zapisać wiadomość ? Odpowiedz Wiadomością - + Delete Message @@ -14331,7 +14734,7 @@ Czy chcesz zapisać wiadomość ? - + Expand Rozwiń @@ -14341,7 +14744,7 @@ Czy chcesz zapisać wiadomość ? Usuń element - + from od @@ -14350,6 +14753,11 @@ Czy chcesz zapisać wiadomość ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14649,7 +15057,7 @@ Reported error: - + Groups Grupy @@ -14679,19 +15087,19 @@ Reported error: - - + + Search Szukaj - + ID ID - + Search ID @@ -14701,7 +15109,7 @@ Reported error: - + Show Items @@ -14900,18 +15308,18 @@ at least one peer was not added to a group - + Error Błąd - + File is not writeable! - + File is not readable! @@ -14949,7 +15357,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14967,7 +15375,7 @@ at least one peer was not added to a group To jest test. - + Newest on top @@ -14978,20 +15386,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15028,22 +15451,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon - + Message Wiadomość @@ -15064,12 +15487,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -15116,27 +15534,37 @@ at least one peer was not added to a group Rozmowy grupowe - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -15186,7 +15614,7 @@ at least one peer was not added to a group Powiadom - + Disable All Toasters @@ -15196,7 +15624,7 @@ at least one peer was not added to a group - + Systray @@ -15323,17 +15751,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -15388,22 +15811,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15417,7 +15835,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15427,22 +15845,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Podpisz klucz PGP + Podpisz klucz PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15462,7 +15874,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15528,27 +15940,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15560,7 +15972,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15605,27 +16017,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong - Być może hasło jest błędne + + Check the password! + - + Maybe password is wrong + Być może hasło jest błędne + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15796,8 +16228,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15814,7 +16245,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15957,7 +16388,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Zdjęcie - + TextLabel @@ -16001,8 +16432,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Komentarze @@ -16037,6 +16468,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Napisz komentarz... + + + Album + Album + PhotoItem @@ -16046,12 +16482,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formularz - + TextLabel - + <!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; } @@ -16143,7 +16579,7 @@ p, li { white-space: pre-wrap; } Pokaż Zdjęcie - + PhotoShare @@ -16183,7 +16619,7 @@ requesting to edit it! - + Stop Stop @@ -16411,17 +16847,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins Wtyczki @@ -16767,7 +17203,7 @@ p, li { white-space: pre-wrap; } Inne Tematy - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16906,13 +17342,13 @@ p, li { white-space: pre-wrap; } Strona - - + + Comments Komentarze - + Copy RetroShare Link @@ -16922,7 +17358,7 @@ p, li { white-space: pre-wrap; } - + Comment Skomentuj @@ -16943,12 +17379,12 @@ p, li { white-space: pre-wrap; } - + Hide Ukryj - + Vote up @@ -16962,7 +17398,7 @@ p, li { white-space: pre-wrap; } \/ - + Set as read and remove item @@ -17023,7 +17459,7 @@ p, li { white-space: pre-wrap; } - + Loading Wczytywanie @@ -17077,13 +17513,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17093,60 +17523,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown nieznane - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17157,7 +17577,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17226,7 +17646,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -17261,7 +17686,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17377,8 +17802,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17645,11 +18080,6 @@ and use the import button to load it PulseAddDialog - - - Post From: - - Account 1 Konto 1 @@ -17663,7 +18093,7 @@ and use the import button to load it Konto 3 - + Add to Pulse @@ -17682,17 +18112,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Od klatki: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17717,10 +18162,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17730,13 +18185,48 @@ and use the import button to load it - + + Post + + + + Cancel Anuluj - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17763,10 +18253,18 @@ and use the import button to load it Formularz - - - - + + + + + Click to view picture + + + + + + + Image Obraz @@ -17774,44 +18272,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17821,17 +18319,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17841,7 +18339,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17849,7 +18347,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17864,7 +18362,7 @@ and use the import button to load it - + follow Parent Group @@ -17874,7 +18372,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17899,7 +18397,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17935,29 +18433,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18035,7 +18533,7 @@ and use the import button to load it QObject - + Confirmation @@ -18275,7 +18773,7 @@ Symbole <b>",|,/,\,&lt;,&gt;,*,?</b> zostaną zastąpio - + Unable to make path @@ -18310,7 +18808,7 @@ Symbole <b>",|,/,\,&lt;,&gt;,*,?</b> zostaną zastąpio - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18448,7 +18946,7 @@ Reported error is: sekund - + TR up @@ -18493,7 +18991,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18509,7 +19007,7 @@ Reported error is: - + %1 seconds ago @@ -18593,7 +19091,7 @@ Security: no anonymous IDs - + Error Błąd @@ -18983,11 +19481,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -19326,7 +19819,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -19548,18 +20041,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19996,7 +20510,7 @@ p, li { white-space: pre-wrap; } - + File Plik @@ -20011,7 +20525,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned @@ -20061,7 +20575,7 @@ Pliki których to dotyczy są oznaczone na czerwono. Zapisz - + Collection Editor @@ -20076,7 +20590,7 @@ Pliki których to dotyczy są oznaczone na czerwono. - + Real Size: Waiting child... @@ -20091,12 +20605,12 @@ Pliki których to dotyczy są oznaczone na czerwono. - + Download files - + Specify... @@ -20343,7 +20857,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -20363,7 +20877,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -20376,10 +20890,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Tytuł + + + UnRead + + Date @@ -20391,7 +20910,7 @@ If you believe it is correct, remove the corresponding line from the file and re Autor - + Information for this identity is currently missing. @@ -20429,7 +20948,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Brakująca Wiadomość ... ] @@ -20437,7 +20956,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -20497,7 +21016,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20851,7 +21370,7 @@ prevents the message to be forwarded to your friends. Nazwa pliku - + Download Pobierz @@ -20930,7 +21449,7 @@ prevents the message to be forwarded to your friends. Otwórz folder - + Create Collection... @@ -20950,7 +21469,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -21055,12 +21574,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat Chat @@ -21070,7 +21589,7 @@ prevents the message to be forwarded to your friends. Rozpocznij rozmowę - + Expand Rozwiń @@ -21333,13 +21852,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21805,7 +22324,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21833,7 +22352,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Stan @@ -21930,7 +22449,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21965,12 +22484,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22635,7 +23154,7 @@ p, li { white-space: pre-wrap; } Brakujący Certyfikat PGP - + Wrong password @@ -22677,7 +23196,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Dodaj Przyjaciela @@ -22733,7 +23252,7 @@ This choice can be reverted in settings. - + DHT @@ -23269,7 +23788,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23279,13 +23798,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23294,6 +23812,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23567,35 +24110,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Masz %1 zakończonych pobierań + You have %1 completed transfers + - You have %1 completed download - Masz %1 zakończone pobieranie + You have %1 completed transfer + - %1 completed downloads - %1 zakończonych pobierań + %1 completed transfers + - %1 completed download - %1 zakończone pobieranie + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Masz %1 zakończonych pobierań + + + You have %1 completed download + Masz %1 zakończone pobieranie + + + %1 completed downloads + %1 zakończonych pobierań + + + %1 completed download + %1 zakończone pobieranie TransfersDialog - + Downloads Pobierania @@ -23606,7 +24160,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Nazwa @@ -23813,7 +24367,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23907,7 +24461,7 @@ p, li { white-space: pre-wrap; } - + Expand all Rozwiń wszystkie @@ -24039,7 +24593,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolumny @@ -24050,7 +24604,7 @@ p, li { white-space: pre-wrap; } Transfery plików - + Path Ścieżka @@ -24060,7 +24614,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24070,7 +24624,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -24085,7 +24639,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -24327,7 +24881,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -24423,7 +24977,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Masz %1 nowych wiadomości @@ -24795,7 +25349,7 @@ p, li { white-space: pre-wrap; } Stwórz Grupę - + Subscribe to Group @@ -24889,8 +25443,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Pokaż Historię Edycji @@ -24901,7 +25455,7 @@ p, li { white-space: pre-wrap; } - + Preview Podgląd @@ -24926,12 +25480,12 @@ p, li { white-space: pre-wrap; } Ukryj Historię Edycji - + Edit Page Edytuj Stronę - + Create New Wiki Page Utwórz Nową Stronę Wiki @@ -24951,7 +25505,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Utwórz Nową Grupę Wiki @@ -24989,7 +25543,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24999,12 +25553,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Odśwież @@ -25039,12 +25592,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25098,7 +25651,7 @@ p, li { white-space: pre-wrap; } Zarządzaj Kontami - + Yourself @@ -25124,7 +25677,7 @@ p, li { white-space: pre-wrap; } Konto 3 - + RetroShare RetroShare @@ -25136,7 +25689,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -25144,7 +25697,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25225,8 +25778,8 @@ p, li { white-space: pre-wrap; } Formularz - - + + Avatar Awatar @@ -25255,6 +25808,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25367,7 +25925,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_pt.ts b/retroshare-gui/src/lang/retroshare_pt.ts index 79a297a23..4835855cf 100644 --- a/retroshare-gui/src/lang/retroshare_pt.ts +++ b/retroshare-gui/src/lang/retroshare_pt.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Opções + TextLabel + + + + Reset Repor - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Omissão + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Nome: - + Location: - + Options Opções - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options Opções @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. Mostrar - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? De: - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13459,7 +13798,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13475,14 +13814,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13553,7 +13892,7 @@ Do you want to save message ? - + Subject @@ -13633,7 +13972,7 @@ Do you want to save message ? - + Open in a new window @@ -13718,7 +14057,7 @@ Do you want to save message ? - + Drafts @@ -13807,7 +14146,7 @@ Do you want to save message ? - + Delete Message @@ -13818,7 +14157,7 @@ Do you want to save message ? - + Expand @@ -13828,7 +14167,7 @@ Do you want to save message ? - + from @@ -13837,6 +14176,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14136,7 +14480,7 @@ Reported error: - + Groups @@ -14166,19 +14510,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14188,7 +14532,7 @@ Reported error: - + Show Items @@ -14387,18 +14731,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14436,7 +14780,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14450,7 +14794,7 @@ at least one peer was not added to a group - + Newest on top @@ -14461,20 +14805,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14507,22 +14866,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14543,12 +14902,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14595,27 +14949,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14665,7 +15029,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14675,7 +15039,7 @@ at least one peer was not added to a group - + Systray @@ -14802,17 +15166,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14867,22 +15226,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14896,7 +15250,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14906,22 +15260,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14941,7 +15285,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15007,27 +15351,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15039,7 +15383,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15084,27 +15428,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15275,8 +15635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15293,7 +15652,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15425,7 +15784,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15461,7 +15820,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15489,6 +15848,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15498,12 +15862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15583,7 +15947,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15623,7 +15987,7 @@ requesting to edit it! - + Stop @@ -15847,17 +16211,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16183,7 +16547,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16314,13 +16678,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16330,7 +16694,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16351,12 +16715,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16366,7 +16730,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16427,7 +16791,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16450,13 +16814,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16466,60 +16824,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16530,7 +16878,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16599,7 +16947,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16634,7 +16987,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16750,8 +17103,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17019,12 +17382,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17039,17 +17397,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17074,10 +17447,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17087,13 +17470,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17105,10 +17523,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17116,44 +17542,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17163,17 +17589,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17191,7 +17617,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17206,7 +17632,7 @@ and use the import button to load it - + follow Parent Group @@ -17216,7 +17642,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17241,7 +17667,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17277,29 +17703,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17377,7 +17803,7 @@ and use the import button to load it QObject - + Confirmation @@ -17616,7 +18042,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17651,7 +18077,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17789,7 +18215,7 @@ Reported error is: - + TR up @@ -17834,7 +18260,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17850,7 +18276,7 @@ Reported error is: - + %1 seconds ago @@ -17934,7 +18360,7 @@ Security: no anonymous IDs - + Error @@ -18324,11 +18750,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18662,7 +19083,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18884,18 +19305,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19332,7 +19774,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19347,7 +19789,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19395,7 +19837,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19410,7 +19852,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19425,12 +19867,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19677,7 +20119,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19697,7 +20139,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19710,10 +20152,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19725,7 +20172,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19763,7 +20210,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19771,7 +20218,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19831,7 +20278,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20185,7 +20632,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20264,7 +20711,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20284,7 +20731,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20389,12 +20836,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20404,7 +20851,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20667,13 +21114,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21139,7 +21586,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21167,7 +21614,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21264,7 +21711,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21299,12 +21746,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21969,7 +22416,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22011,7 +22458,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22067,7 +22514,7 @@ This choice can be reverted in settings. - + DHT @@ -22599,7 +23046,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22609,13 +23056,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22624,6 +23070,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22897,27 +23368,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22925,7 +23391,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22936,7 +23402,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23143,7 +23609,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23237,7 +23703,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23369,7 +23835,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23380,7 +23846,7 @@ p, li { white-space: pre-wrap; } - + Path Caminho @@ -23390,7 +23856,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23400,7 +23866,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23415,7 +23881,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23657,7 +24123,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23753,7 +24219,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24121,7 +24587,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24215,8 +24681,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24227,7 +24693,7 @@ p, li { white-space: pre-wrap; } - + Preview Antevisão @@ -24252,12 +24718,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24277,7 +24743,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24315,7 +24781,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24325,12 +24791,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24365,12 +24826,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24400,7 +24861,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24410,7 +24871,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24422,7 +24883,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24430,7 +24891,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24511,8 +24972,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24541,6 +25002,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24653,7 +25119,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ru.ts b/retroshare-gui/src/lang/retroshare_ru.ts index 4a6dff8e4..cfe0de745 100644 --- a/retroshare-gui/src/lang/retroshare_ru.ts +++ b/retroshare-gui/src/lang/retroshare_ru.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Версия платформы @@ -79,7 +79,7 @@ Развлекайтесь ;-) - + Only Hidden Node Только скрытый узел сети @@ -129,12 +129,12 @@ RetroShare: расширенный поиск - + Search Criteria Критерии поиска - + Add a further search criterion. Добавить дополнительный критерий поиска. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Альбом @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Форма - - + + TextLabel Текстовая метка @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Панель инструментов - + Icon Only Только значки @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Выберите стиль кнопки инструментов. - + Icon Size = 8x8 Размер значка = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Размер значка = 128x128 - + Status Bar Строка состояния @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Отключить подсказки в системном трее - + Main page items: Элементы интерфейса главного окна @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Выпадающие списки - + Icon Size = 32x32 Размер значка = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Изменить аватар - + + TextLabel + Текстовая метка + + + Your Avatar Picture Ваш аватар - + + Browse... + + + Add Avatar - Добавить аватар + Добавить аватар @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Удалить эту позицию - + Set your Avatar picture Установить ваш аватар - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Загрузить аватар + Загрузить аватар AvatarWidget - - Choose avatar - - - - + Click to change your avatar Нажать для изменения аватара @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s кБ/с @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Загруженность канала передачи данных + + + PushButton + + - + Up + Отдача + + + + Down + Скачивание + + + + Clears the graph + + + + Show Settings Показать настройки + TextLabel + Текстовая метка + + + Reset Сброс - Receive Rate - Скорость приёма + Скорость приёма - Send Rate - Скорость отдачи + Скорость отдачи - + Always on Top Поверх всех окон - Style - Стиль + Стиль - + Changes the transparency of the Bandwidth Graph Изменить прозрачность графика пропускной способности - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % непрозрачности - Save - Сохранить + Сохранить - Cancel - Отмена + Отмена - + Since: С: - Hide Settings - Скрыть настройки + Скрыть настройки BandwidthStatsWidget - + Sum Суммарно @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } Подсчёт - + Average Среднее @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } Текстовая метка - + Comments Комментарии @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } Текстовая метка + + BoardsCommentsItem + + + I like this + Мне нравится + + + + 0 + 0 + + + + I dislike this + Мне не понравилось + + + + Toggle Message Read Status + Изменить статус прочитанного сообщения + + + + Avatar + Аватар + + + + New Comment + + + + + Copy RetroShare Link + Скопировать ссылку RetroShare + + + + + Expand + + + + + Set as read and remove item + Установить как чтение и удаление элемента + + + + Remove Item + Удалить объект + + + + Name + Имя + + + + Comm value + + + + + Comment + Комментарий + + + + Comments + Комментарии + + + + Hide + + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale Логарифмическая шкала + + + Default + По умолчанию + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Мне нравится + + + + 0 + 0 + + + + I dislike this + Мне не понравилось + + + + Toggle Message Read Status + Изменить статус прочитанного сообщения + + + + Avatar + Аватар + + + + New Comment + + + + + Copy RetroShare Link + Скопировать ссылку RetroShare + + + + + Expand + + + + + Set as read and remove item + Установить как чтение и удаление элемента + + + + Remove Item + Удалить объект + + + + Name + Имя + + + + Comm value + + + + + Comment + Комментарий + + + + Comments + Комментарии + + + + Hide + + + ChatLobbyDialog @@ -1592,24 +1796,40 @@ into the image, so as to Чаты - You have %1 new messages - У вас %1 новых сообщений + У вас %1 новых сообщений + + + You have %1 new message + У вас %1 новых сообщений + + + %1 new messages + %1 новых сообщений + + + %1 new message + %1 новое сообщение + + + + You have %1 mentions + - You have %1 new message - У вас %1 новых сообщений + You have %1 mention + - %1 new messages - %1 новых сообщений + %1 mentions + - %1 new message - %1 новое сообщение + %1 mention + @@ -1622,11 +1842,6 @@ into the image, so as to Remove All Удалить всё - - - mention(s) - - ChatLobbyWidget @@ -2121,13 +2336,11 @@ Double click a chat room to enter and chat. Вариант: - Group chat - Групповой чат + Групповой чат - - + Private chat Приватный чат @@ -2192,17 +2405,16 @@ Double click a chat room to enter and chat. /me отправляет сообщение с /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">В этой вкладке вы можете задать, какое количество сообщений чата RetroShare будет хранить на диске, а также объём отображения состоявшихся бесед для различных систем чатов. Максимальный период хранения позволяет очищать историю чатов и предотвращает её заполнение временными чатами (например, обычные чаты или удалённые чаты).</p></body></html> - Chatlobbies - Комнаты чата + Комнаты чата - + Enabled: Включено: @@ -2223,11 +2435,12 @@ Double click a chat room to enter and chat. + Chat rooms Чат-комнаты - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Отметьте, если для подсчёта должны одновременно присутствовать и личность, и текст выше. @@ -2288,11 +2501,17 @@ Double click a chat room to enter and chat. + Broadcast Широковещательный чат - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Сохраняемые сообщения (0 = не ограничено): @@ -2439,8 +2658,23 @@ Double click a chat room to enter and chat. Приватный чат - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2613,7 +2847,7 @@ Double click a chat room to enter and chat. - + is typing... печатает... @@ -2632,12 +2866,12 @@ after HTML conversion. %1 символов после конвертирования в HTML. - + Choose your font. Выберите шрифт. - + Do you really want to physically delete the history? Вы действительно хотите удалить с диска историю сообщений? @@ -2709,7 +2943,7 @@ after HTML conversion. Продолжить выделять цветом после X найденных вхождений (требуется больше ресурсов процессора) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Найти предыдущее </b><br/><i>Ctrl+Shift+G</i> @@ -2749,12 +2983,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Отметить этот выделенный текст</b><br><i>Ctrl + M</i> - + Person id: Идентификатор личности: @@ -2770,7 +3004,7 @@ Double click on it to add his name on text writer. Не подписано - + items found. удовлетворяют условию. @@ -2790,7 +3024,7 @@ Double click on it to add his name on text writer. Печатайте ваши сообщения здесь - + Don't stop to color after Продолжить выделять цветом после @@ -2948,12 +3182,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Подробности - + Local Address Локальный адрес @@ -2964,12 +3198,12 @@ Double click on it to add his name on text writer. Внешний адрес - + Node info: Сведения об узле: - + Current address: Текущий адрес: @@ -2985,31 +3219,36 @@ Double click on it to add his name on text writer. Порт - + Include signatures Включая подписи - + RetroShare RetroShare - + - + Error : cannot get peer details. Ошибка: не могу получить совокупность деталей. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Шифрование - + Not connected не соединён - + Retroshare node details Сведения об узле Retroshare - + Node name : Имя узла: @@ -3075,13 +3319,18 @@ Double click on it to add his name on text writer. Сообщение о личном статусе: - + + Connectivity + + + + List of known addresses: Список известных адресов: - - + + Retroshare Certificate Сертификат Retroshare @@ -3096,7 +3345,7 @@ Double click on it to add his name on text writer. - + Hidden Address Скрытый адрес @@ -3107,11 +3356,12 @@ Double click on it to add his name on text writer. нет + <p>This certificate contains: - <p>Этот сертификат содержит: + <p>Этот сертификат содержит: - + <li>a <b>node ID</b> and <b>name</b> <li><b>идентификатор узла</b> и <b>имя</b> @@ -3124,12 +3374,12 @@ Double click on it to add his name on text writer. <b>IP-адрес</b> и <b>порт</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Вы можете использовать этот сертификат, чтобы пополнить список ваших контактов. Отправьте его потенциальному участнику по электронной почте или передайте лично в руки.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/> <body><p>Это идентификатор узла <span style="font-weight:600;"> OpenSSL</span> сертификат, которого подписан <span style="font-weight:600;"> PGP</span> ключём выше.</p></body></html> @@ -3139,7 +3389,7 @@ Double click on it to add his name on text writer. <html><head/> <body><p>Это метод шифрования, используемый <span style="font-weight:600;"> OpenSSL</span>. Подключение к доверенному узлу</p> <p>всегда шифруется стойким алгоритмом и если DHE присутствует, дальнейшее соединение использует метод</p> <p>«совершенной секретности с упреждением».</p></body></html> - + with с @@ -3345,12 +3595,12 @@ Double click on it to add his name on text writer. Подробности запроса - + Peer details Сведения об участнике - + Name: Имя: @@ -3368,12 +3618,12 @@ resources. Обратите внимание на тот факт, что вы можете добавлять в ваше окружение столько контактов, сколько пожелаете. Но их количество более 40, вероятно, приведёт к заметной загрузке CPU, памяти и пропускной способности вашего интернет-канала. - + Location: Расположение: - + Options Параметры @@ -3410,12 +3660,12 @@ resources. Вставить сертификат - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Сюда следует вводить сертификаты потенциальных контактов. ВНИМАНИЕ: сертификаты — это не просто пбличные PGP-ключи, это более сложная структура данных. Не вставляйте сюда PGP-ключи своих потенциальных контактов (ни полностью, ни частично) – это не сработает. Сертификат должен вводиться полностью!</p></body></html> - + Add friend to group: Добавить этот узел в группу: @@ -3425,7 +3675,7 @@ resources. Аутентификация доверенного узла (подписать его PGP-ключ) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with Добавить сертификат участника для последующего соединения с ним @@ -3459,7 +3709,7 @@ resources. Чтобы принять запрос на предложение обменяться сертификатами, нажмите кнопку «Завершить». - + Sorry, some error appeared К сожалению, появились некоторые ошибки @@ -3479,32 +3729,32 @@ resources. Подробная информация об узле: - + Key validity: Уровень доверия к ключу: - + Profile ID: - + Signers Подписавшие - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Подписание публичного ключа участника сети – это способ обозначить своё доверие тому или иному участнику. Сигнатуры, которые вы видите ниже, подтверждают, что ключи в списке заверены и признаются как подлинные.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Этот участник уже находится в вашем доверенном окружении. Добавление сертификата снова лишь установит актуальный IP-адрес этого узла. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Ошибка загрузки сертификата @@ -3587,12 +3837,12 @@ resources. Сертификат в порядке - + Not a valid Retroshare certificate! Недействительный сертификат RetroShare! - + RetroShare Invitation Приглашение в RetroShare @@ -3612,12 +3862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Это же ваш собственный сертификат! Вы не хотели бы соединиться с самим собой, не так ли? - + @@ -3665,7 +3915,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.У вас имеется запрос на соединение от - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3753,12 +4033,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Использовать как прямой источник, при возможности - + IP-Addr: IP-адрес: - + IP-Address IP-адрес: @@ -3824,7 +4104,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Добавить ключ в связку ключей - + This key is already in your keyring Это ключ уже в вашей связке @@ -3885,12 +4165,12 @@ even if you don't make friends. Этот сертификат не содержит в себе IP-адреса. В данном случае для установления соединения с узлом ваш клиент задействует сервис обнаружения и распределённую таблицу хешей DHT. Поскольку вам требуется разрешение белого списка, подключение к участнику вызовет предупреждение системы безопасности во вкладке новостей. Оттуда вы можете добавить его IP-адрес в белый список. - + [Unknown] - + Added with certificate from %1 Добавлено с сертификатом от %1 @@ -3977,7 +4257,12 @@ even if you don't make friends. Результат UDP - + + Status + Статус + + + <!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; } @@ -4407,7 +4692,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4559,7 +4844,7 @@ p, li { white-space: pre-wrap; } Не выбраны ограничения круга - + [Unknown] @@ -4574,7 +4859,7 @@ p, li { white-space: pre-wrap; } Удалить - + Search Поиск @@ -4594,7 +4879,7 @@ p, li { white-space: pre-wrap; } Подписано известными узлами - + Edit Circle Редактировать круг @@ -4614,12 +4899,12 @@ p, li { white-space: pre-wrap; } Анонимный идентификатор - + Circle name Название круга - + Update Обновить @@ -4645,7 +4930,7 @@ p, li { white-space: pre-wrap; } Идентификатор, привязанный к PGP-ключу - + Add Member Добавить члена @@ -4789,7 +5074,7 @@ p, li { white-space: pre-wrap; } - + Attachments Вложения @@ -4835,7 +5120,7 @@ p, li { white-space: pre-wrap; } Перетащить файлы из результатов поиска - + Paste RetroShare Links Вставить RetroShare-ссылки @@ -4845,7 +5130,7 @@ p, li { white-space: pre-wrap; } Вставить ссылку RetroShare - + Drop file error. Ошибка прикрепления файла. @@ -4872,17 +5157,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Файл уже добавлен и хеширован + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Файл уже добавлен и хеширован + + + Please add a Subject Добавьте тему сообщения @@ -4913,12 +5222,12 @@ p, li { white-space: pre-wrap; } Вы действительно хотите создать %1 сообщений? - + You are about to add files you're not actually sharing. Do you still want this to happen? Вы хотите добавить файлы которые не ещё не общедоступны. Продолжить в любом случае? - + Edit Channel Post Редактировать сообщение канала @@ -4938,7 +5247,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. О том, как размещать не свои файлы в канале. @@ -5030,7 +5339,7 @@ p, li { white-space: pre-wrap; } - + No Forum Нет форума @@ -5490,7 +5799,7 @@ and use the import button to load it DHTGraphSource - + users пользователи @@ -6497,7 +6806,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Папки доверенных участников @@ -7003,7 +7312,7 @@ at least one peer was not added to a group Поиск контактов - + Mark all Отметить все @@ -7017,7 +7326,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Изменить ваш статус @@ -7121,7 +7430,7 @@ at least one peer was not added to a group Широковещательный чат RetroShare: сообщения будут рассылаться всем подключённым узлам. - + Network Сеть @@ -7186,7 +7495,7 @@ at least one peer was not added to a group Поле для местоположения должно быть длиной минимум 3 символа - + Failed to generate your new certificate, maybe PGP password is wrong! Не удалось создать ваш новый сертификат. Может быть, введён неправильный пароль PGP! @@ -7229,7 +7538,7 @@ at least one peer was not added to a group Использовать существующий профиль - + Node name Название узла @@ -7496,12 +7805,12 @@ and use the import button to load it - + Profile generation failure Ошибка при создании профиля - + Missing PGP certificate Отсутствует сертификат PGP @@ -7920,7 +8229,7 @@ p, li { white-space: pre-wrap; } Статистика роутера - + GroupBox Группы @@ -7985,7 +8294,7 @@ p, li { white-space: pre-wrap; } Количество ветвей - + Details Подробности @@ -8008,7 +8317,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Управляемые ключи @@ -8217,7 +8526,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Название @@ -8227,13 +8536,30 @@ p, li { white-space: pre-wrap; } Поиск по названию - - + + + + Description Описание - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Поиск по описанию @@ -8243,42 +8569,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Сортировать по убыванию + Сортировать по убыванию - Sort Ascending Order - Сортировать по возрастанию + Сортировать по возрастанию - Sort by Name - Сортировать по имени + Сортировать по имени - Sort by Popularity - Сортировать по популярности + Сортировать по популярности - Sort by Last Post - Сортировать по последнему сообщению + Сортировать по последнему сообщению - Sort by Number of Posts - Сортировать по количеству сообщений + Сортировать по количеству сообщений - Sort by Unread - Сортировать по количеству непрочтённых сообщений + Сортировать по количеству непрочтённых сообщений - + You are admin (modify names and description using Edit menu) Вы администратор (изменяйте название и описание используя меню "Редактировать") @@ -8293,40 +8612,35 @@ p, li { white-space: pre-wrap; } Идентификатор - - + + Last Post Последнее непрочтённое - + + Name Имя - - Unread - - - - + Popularity Популярность - - + + Never Никогда - Display - Показать + Показать - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8475,7 +8789,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Каналы @@ -8500,12 +8814,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Каналы</h1> <p>Каналы дают возможность публиковать контент (например, кино или музыку), который подлежит раздаче пользователям сети.</p> <p>В списке каналов содержатся те каналы, на которые подписано ваше доверенное окружение, равно как и ваш узел автоматически отсылает окружению информацию о каналах, на которые подписаны вы. Такой механизм позволяет распространять по сети информацию о хороших каналах и блокировать неудачные.</p> <p>Оставлять сообщения в канале может только его создатель. Остальные участники могут лишь читать его содержимое и только в том случае, если канал не является приватным. Тем не менее, вы можете ⇥ дать права на чтение или модификацию канала пользователям из доверенного окружения.</p>⇥ <p>Канал может быть анонимным или псевдонимным, если за ним закреплён определённый идентификатор пользователя. ⇥ Включите режим «Разрешить комментарии», если Вы хотите дать пользователям возможность комментировать сообщения.</p> <p>Сообщения канала удаляются через %1 месяца.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Подписка на каналы @@ -9030,7 +9344,7 @@ p, li { white-space: pre-wrap; } - + Add new post Добавить новое сообщение @@ -9130,12 +9444,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Комментарии @@ -9146,18 +9460,18 @@ p, li { white-space: pre-wrap; } - + Feeds Каналы - - + + Click to switch to list view - + Show unread posts only @@ -9167,12 +9481,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9232,7 +9546,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9247,12 +9561,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9328,23 +9642,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe Подписаться - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Не выбраны каналы @@ -9366,11 +9693,6 @@ p, li { white-space: pre-wrap; } Channel Post Сообщение канала - - - new message(s) - - GxsCircleItem @@ -9904,7 +10226,7 @@ before you can comment Начать новую тему в выбранном форуме - + Search forums Поиск по форумам @@ -9913,12 +10235,12 @@ before you can comment Последнее сообщение - + New Thread Новая тема - + Threaded View Древовидный вид @@ -9928,19 +10250,19 @@ before you can comment Плоский вид - - + + Title Название - - + + Date Дата - + Author Автор @@ -9955,7 +10277,17 @@ before you can comment Загрузка - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10016,23 +10348,23 @@ before you can comment <p>Подписка на форум означает, что ваш клиент будет собирать среди доверенного окружения все имеющиеся сообщения, а также, в свою очередь, делать форумный котент видимым для других участников из вашего окружения.</p> <p>Впоследствии, при желании, вы сможете отписаться от форума, воспользовавшись контекстным меню.</p> - + No name Без названия - - + + Reply Ответ - + <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> - + Loading... @@ -10070,12 +10402,12 @@ before you can comment Отметить как непрочитанное - + Copy RetroShare Link Скопировать ссылку RetroShare - + Hide Скрыть @@ -10088,7 +10420,7 @@ before you can comment [Заблокировано] - + [unknown] [неизвестно] @@ -10118,8 +10450,8 @@ before you can comment Только для вас - - + + Distribution Распространение @@ -10222,7 +10554,7 @@ before you can comment Оригинал сообщения - + New thread Новая тема @@ -10231,7 +10563,7 @@ before you can comment Указывать состояние прочитано / не прочитано - + Edit Изменить @@ -10287,7 +10619,7 @@ before you can comment Показать этот идентификатор на вкладке "Участники" - + Author's reputation Репутация автора @@ -10307,7 +10639,7 @@ before you can comment - + <b>Loading...<b> @@ -10347,6 +10679,11 @@ before you can comment Storage Хранение сообщений + + + Last seen at friends: + + Moderators @@ -10439,7 +10776,7 @@ prevents the message to be forwarded to your friends. %1 %2 написал(а): - + Forum name Название форума @@ -10471,11 +10808,6 @@ prevents the message to be forwarded to your friends. Forum Post Сообщение форума - - - new message(s) - - GxsForumsDialog @@ -10924,7 +11256,7 @@ prevents the message to be forwarded to your friends. Предварительный просмотр - + Unsubscribe Отменить подписку @@ -10939,7 +11271,7 @@ prevents the message to be forwarded to your friends. Открыть в новой вкладке - + Remove this search @@ -10949,12 +11281,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details Показать подробности @@ -11021,7 +11353,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -11030,7 +11362,7 @@ prevents the message to be forwarded to your friends. Поделиться правами на запись - + Copy RetroShare Link Скопировать ссылку RetroShare @@ -11045,7 +11377,7 @@ prevents the message to be forwarded to your friends. Отметить всё как непрочитанное - + AUTHD Требуется подпись @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11671,7 +12003,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11697,6 +12029,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11708,7 +12057,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11788,27 +12137,32 @@ p, li { white-space: pre-wrap; } Форма - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11830,6 +12184,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11838,7 +12193,7 @@ p, li { white-space: pre-wrap; } Текст, который вы видите ниже, есть ваш сертификат. Отправьте его тому, с кем вы желаете соединиться - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11855,12 +12210,12 @@ private and secure decentralized communication platform. Вам нужна помощь по RetroShare? - + Open Web Help Открыть помощь в веб - + Copy your Cert to Clipboard Скопировать сертификат в буфер обмена @@ -11909,7 +12264,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11918,7 +12273,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12211,14 +12566,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Все участники - + Reputation Репутация @@ -12228,12 +12583,12 @@ p, li { white-space: pre-wrap; } Поиск - + Anonymous Id Анонимный идентификатор - + Create new Identity Создать новую личность @@ -12377,7 +12732,7 @@ p, li { white-space: pre-wrap; } Идентификатор личности - + Send message Отправить сообщение @@ -12469,7 +12824,7 @@ p, li { white-space: pre-wrap; } Общая: - + Anonymous Анонимные участники @@ -12484,24 +12839,24 @@ p, li { white-space: pre-wrap; } Поиск идентификатора - + This identity is owned by you Эта личность закреплена за вами - - + + My own identities Личности, созданные мною - - + + My contacts Мои контакты - + Show Items Показать... @@ -12516,7 +12871,7 @@ p, li { white-space: pre-wrap; } Личности, привязанные к моему узлу - + Other circles Другие круги @@ -12575,13 +12930,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). подписанный (получает/передаёт запросы членства от других). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). неподписанный (только получает приглашения). - + Your status: Ваш статус: @@ -12641,7 +13001,7 @@ p, li { white-space: pre-wrap; } Член - + Edit Circle Редактировать круг @@ -12689,7 +13049,7 @@ p, li { white-space: pre-wrap; } Разрешить членство - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12701,12 +13061,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [неизвестный узел] - + Unverified signature from node Неподтверждённая подпись от узла @@ -12718,12 +13078,12 @@ These identities will soon be not supported anymore. Непроверенная подпись - + [unverified] [не подтверждено] - + Identity owned by you, linked to your Retroshare node Личность закреплена за вами и привязана к вашему узлу RetroShare @@ -12847,12 +13207,12 @@ These identities will soon be not supported anymore. Отправить приглашение с Вашим сертификатом? - + Banned Заблокированные участники - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Личности</h1> <p>В этой вкладке вы имеете возможность создавать/редактировать <b>анонимные и псевдонимные личности</b>, а также <b>круги</b>.</p> <p><b>Личности</b> используются для безопасной публикации сообщений: от имени личностей вы посылаете сообщения в чаты, форумы и каналы, получаете отклики через встроенный в RetroShare почтовый сервис, публикуете комментарии в каналах, чатах. От имени личностей в определённых случаях прокладываются анонимные туннели и т. п.</p> <p>Личности не обязательно должны быть <b>подписаны</b> вашим личным сертификатом. Подписанные личности иногда полезны, если вы хотите подчеркнуть авторство того или иного сообщения. Однако по подписанным личностям зачастую можно отследить IP-адрес автора сообщения.</p> <p><b>Анонимные личности</b> позволяют вам анонимно, а значит – безопасно, взаимодействовать с другими участниками тёмной сети. Анонимные личности не могут быть подменены, но никто не может однозначно обозначить привязку анонимной личности к конкретному сертификату, а значит – и пользователю.</p> <p><b>Круги</b> – это совокупность личностей (анонимных или подписанных), информация о которых широко распространяется по тёмной сети. Круги используются для создания форумов и каналов, содержимое которых доступно только участникам конкретного круга </p> <p><b>Один круг</b> может быть ограничен другим кругом, как следствие, определяя видимость его участников определённому множеству участников, принадлежащему другому кругу. Есть возможность создавать самый приватный тип кругов, где информация о них доступна только членам самого круга, читайте – закрытого клуба.</p> <p><b>Локальный круг</b> есть совокупность доверенных узлов, представленных их PGP-идентификаторами, и широко используемых для ограничения доступности каналов и форумов. Такого рода круги не распространяются по сети и список его членов доступен только вам.</p> @@ -12861,7 +13221,7 @@ These identities will soon be not supported anymore. Неизвестный идентификатор: - + positive положительно @@ -13046,8 +13406,8 @@ These identities will soon be not supported anymore. - - + + People Участники @@ -13058,7 +13418,7 @@ These identities will soon be not supported anymore. Нажмите здесь, чтобы изменить свой аватар - + Linked to neighbor nodes Личности, привязанные к ближнему окружению @@ -13068,7 +13428,7 @@ These identities will soon be not supported anymore. Личности, привязанные к удалённому узлу - + Linked to a friend Retroshare node Личности, привязанные к доверенному окружению @@ -13128,7 +13488,7 @@ These identities will soon be not supported anymore. Принадлежит... - + Node name: Имя узла: @@ -13138,7 +13498,7 @@ These identities will soon be not supported anymore. Идентификатор узла: - + Really delete? Действительно удалить? @@ -13176,7 +13536,22 @@ These identities will soon be not supported anymore. Псевдоним - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Новая личность @@ -13193,14 +13568,14 @@ These identities will soon be not supported anymore. - + N/A Недоступен - + Edit identity Редактировать личность @@ -13211,24 +13586,27 @@ These identities will soon be not supported anymore. Обновить - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13247,17 +13625,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Ошибка при получении ключа! - + Error KeyID invalid Ошибка: недействительный идентификатор ключа - + Unknown GpgId Неизвестный идентификатор GPG @@ -13267,7 +13655,7 @@ These identities will soon be not supported anymore. Неизвестное имя - + Create New Identity Создать новую личность @@ -13277,7 +13665,12 @@ These identities will soon be not supported anymore. Тип - + + Choose image... + + + + @@ -13317,12 +13710,11 @@ These identities will soon be not supported anymore. Нажмите здесь, чтобы изменить аватар - Set Avatar - Установить аватар + Установить аватар - + Linked to your profile Привязан к моему профилю @@ -13332,7 +13724,7 @@ These identities will soon be not supported anymore. Вы можете иметь один или несколько идентификаторов. Они используются, когда вы пишете в чате лобби, на форумах и канале комментариев. Они выступают в качестве получателя для удалённого чата и удалённой почтовой системы Retroshare. - + The nickname is too short. Please input at least %1 characters. Псевдоним является слишком коротким. Пожалуйста, введите по крайней мере %1 символов. @@ -13441,8 +13833,12 @@ These identities will soon be not supported anymore. + Quote + Цитата + + Send - Отправить + Отправить @@ -13600,7 +13996,7 @@ These identities will soon be not supported anymore. - + Options Параметры @@ -13632,12 +14028,12 @@ These identities will soon be not supported anymore. Помощник быстрого старта - + RetroShare %1 a secure decentralized communication platform RetroShare %1 — безопасная децентрализованная коммуникационная платформа - + Unfinished Ещё не готово @@ -13770,7 +14166,7 @@ RetroShare безопасно приостановит доступ диска Показать - + Make sure this link has not been forged to drag you to a malicious website. Убедитесь, что эта ссылка не была подделана, чтобы перенаправить вас на вредоносный веб-сайт. @@ -13815,7 +14211,7 @@ RetroShare безопасно приостановит доступ диска Управление правами доступа - + Statistics Статистика функционирования @@ -13844,7 +14240,7 @@ RetroShare безопасно приостановит доступ диска MessageComposer - + Compose Составить @@ -13946,7 +14342,7 @@ RetroShare безопасно приостановит доступ диска - + Tags Метки @@ -14041,12 +14437,12 @@ RetroShare безопасно приостановит доступ диска Добавить цитату - + Send To: Отправить: - + &Left По левому краю @@ -14080,7 +14476,7 @@ RetroShare безопасно приостановит доступ диска Мои контакты - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Здравствуйте, <br>я рекомендую вам один из моих лучших контактов. Вы можете доверять ему ровно настолько, насколько вы доверяете мне. Это хороший узел, поверьте.<br> @@ -14106,12 +14502,12 @@ RetroShare безопасно приостановит доступ диска - + Save Message Сохранить сообщение - + Message has not been Sent. Do you want to save message to draft box? Сообщение не отправлено. @@ -14123,7 +14519,7 @@ Do you want to save message to draft box? Вставить ссылку RetroShare - + Add to "To" Добавить к "кому" @@ -14378,7 +14774,7 @@ Do you want to save message ? Добавить файл - + Hi,<br>I want to be friends with you on RetroShare.<br> Привет, <br>Есть предложение обменяться сертификатами друг с другом. Не возражаете?<br> @@ -14387,12 +14783,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Вы получили предложение на соединение с действующим узлом RetroShare - + Respond now: Ответить сейчас: @@ -14408,11 +14819,12 @@ Do you want to save message ? Из: + Friend Nodes - Доверенные узлы сети + Доверенные узлы сети - + Bullet list (disc) Маркированный список (диск) @@ -14452,13 +14864,13 @@ Do you want to save message ? Отсортированный список (в римской системе по убыванию) - - + + Thanks, <br> Спасибо, <br> - + Distant identity: Удалённая личность: @@ -14597,8 +15009,23 @@ Do you want to save message ? Сообщение - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14610,12 +15037,12 @@ Do you want to save message ? Рекомендованные файлы - + Download all Recommended Files Скачать все рекомендованные файлы - + Subject: Тема: @@ -14690,12 +15117,18 @@ Do you want to save message ? Послать приглашение - + + Message Size: + + + + File Name Имя файла - + + Size Размер @@ -14756,10 +15189,25 @@ Do you want to save message ? Скачать - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Послать приглашение @@ -14770,12 +15218,12 @@ Do you want to save message ? - + Download all Скачать всё - + Print Document Распечатать документ @@ -14790,7 +15238,7 @@ Do you want to save message ? HTML-файлы (*.htm *.html);;Все файлы (*) - + Load images always for this message Загружать изображения всегда для этого сообщения @@ -14931,7 +15379,7 @@ Do you want to save message ? MessagesDialog - + New Message Новое сообщение @@ -14987,14 +15435,14 @@ Do you want to save message ? - + Tags Метки - + Inbox Входящие @@ -15089,7 +15537,7 @@ Do you want to save message ? Переслать сообщение - + Subject Тема @@ -15201,7 +15649,7 @@ Do you want to save message ? - + Open in a new window Открыть в новом окне @@ -15286,7 +15734,7 @@ Do you want to save message ? - + Drafts Черновики @@ -15415,7 +15863,7 @@ Do you want to save message ? Ответить на сообщение - + Delete Message Удалить сообщение @@ -15426,7 +15874,7 @@ Do you want to save message ? - + Expand Развернуть @@ -15436,7 +15884,7 @@ Do you want to save message ? Удалить объект - + from от @@ -15445,6 +15893,11 @@ Do you want to save message ? Reply to invite Ответить на приглашение + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15768,7 +16221,7 @@ Reported error: - + Groups Группы @@ -15798,19 +16251,19 @@ Reported error: Импорт списка контактов, включая информацию о группах - - + + Search - + ID - + Search ID Поиск идентификатора @@ -15820,7 +16273,7 @@ Reported error: - + Show Items Показать... @@ -16024,19 +16477,19 @@ at least one peer was not added to a group - + Error Ошибка - + File is not writeable! Нет прав на запись файла! - + File is not readable! Нет прав на чтение файла! @@ -16074,9 +16527,13 @@ at least one peer was not added to a group NewsFeed - Log entries - Журнал + Журнал + + + + Activity Stream + @@ -16093,7 +16550,7 @@ at least one peer was not added to a group Это проверка. - + Newest on top Новые наверху @@ -16104,20 +16561,43 @@ at least one peer was not added to a group + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Новостная лента</h1> <p>Лента новостей отображает последние события вашей сети в порядке получения. Можно настроить какие виды событий отображать в журнале, нажав <b>Параметры</b>. </p> <p>События могут быть следующими: <ul> <li>попытка соединения (полезно для пополнения вашего окружения новыми доверенными участниками и отслеживания тех участников, которые пытаются к вам подключиться)</li> <li>появление сообщений в форумах и каналах</li> <li>появление новых форумов или каналов</li> <li>личные сообщения от ваших контактов</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Новостная лента</h1> <p>Лента новостей отображает последние события вашей сети в порядке получения. Можно настроить какие виды событий отображать в журнале, нажав <b>Параметры</b>. </p> <p>События могут быть следующими: <ul> <li>попытка соединения (полезно для пополнения вашего окружения новыми доверенными участниками и отслеживания тех участников, которые пытаются к вам подключиться)</li> <li>появление сообщений в форумах и каналах</li> <li>появление новых форумов или каналов</li> <li>личные сообщения от ваших контактов</li> </ul> </p> + + + Log + Журнал - Log - Журнал + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16154,22 +16634,22 @@ at least one peer was not added to a group - + Test Тест - + Chat Room Чат-комната - + Systray Icon Значок в системном трее - + Message Сообщение @@ -16194,12 +16674,11 @@ at least one peer was not added to a group IP-безопасность - Log - Журнал + Журнал - + Friend Connected Узел подключён @@ -16213,7 +16692,12 @@ at least one peer was not added to a group Публикации - + + Activity + + + + Mails Почта @@ -16250,7 +16734,12 @@ at least one peer was not added to a group Групповой чат - + + Toaster position + + + + Chat rooms Чат-комнаты @@ -16275,22 +16764,22 @@ at least one peer was not added to a group Учитывать регистр - + Position Местоположение - + X Margin Отступ по горизонтали - + Y Margin Отступ по вертикали - + Systray message Сообщение в панели уведомлений @@ -16340,7 +16829,7 @@ at least one peer was not added to a group Уведомления - + Disable All Toasters Отключить все всплывающие уведомления @@ -16354,7 +16843,7 @@ at least one peer was not added to a group Канал - + Systray Панель уведомлений @@ -16501,17 +16990,16 @@ at least one peer was not added to a group PGPKeyDialog - Dialog - Диалоговое окно + Диалоговое окно - + Profile info Сведения о профиле - + Name : Имя: @@ -16566,22 +17054,21 @@ at least one peer was not added to a group Окончательный - + This profile has signed your own profile key Этот ключ подписан вашим собственным PGP-ключом - Key signatures : - Ключ подписи: + Ключ подписи: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Подписание публичного ключа участника сети – это способ обозначить своё доверие тому или иному участнику. Подписи, которые вы видите ниже, подтверждают, что ключи в списке заверены и признаются как подлинные.</span></p></body></html> - + <!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; } @@ -16599,7 +17086,7 @@ p, li { white-space: pre-wrap; } Подписать этот ключ - + PGP key PGP-ключ @@ -16609,22 +17096,20 @@ p, li { white-space: pre-wrap; } Эти опции применяются для всех местоположений, привязанных к профилю: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Механизм подписания ключей может оказаться полезным другим участникам сети, которые, добавляя чужой сертификат в своё окружение, имеют возможность посмотреть, кто подписал ключ в сертификате. Следует отметить, что подписание чужих ключей не является обязательным и не может быть впоследствии отменено. Поэтому подходите к вопросу подписания, взвесив все «за» и «против».</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Механизм подписания ключей может оказаться полезным другим участникам сети, которые, добавляя чужой сертификат в своё окружение, имеют возможность посмотреть, кто подписал ключ в сертификате. Следует отметить, что подписание чужих ключей не является обязательным и не может быть впоследствии отменено. Поэтому подходите к вопросу подписания, взвесив все «за» и «против».</span></p></body></html> - + Keysigning: - Sign PGP key - Подписать PGP-ключ + Подписать PGP-ключ - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Щёлкните здесь, если вы хотите отказать в соединении узлам, привязанным к этому публичному ключу.</p></body></html> @@ -16644,7 +17129,7 @@ p, li { white-space: pre-wrap; } Разрешить подключения - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Ниже находится ключ профиля узла в формате PGP ASCII. Он идентифицирует все узлы данного профиля. Сертификат Retroshare, которым вы можете обменяться для добавление в доверенное окружение, находится в разделе "Подробности" каждого отдельного узла. @@ -16714,28 +17199,28 @@ p, li { white-space: pre-wrap; } кБ/с - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Ошибка: не могу получить совокупность деталей. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Предоставленный алгоритм ключа не поддерживается RetroShare (на данный момент поддерживаются только RSA-ключи) - + Warning: In your File-Transfer option, you select allow direct download to Yes. Предупреждение: в настройках файлообмена вы разрешили прямую загрузку. @@ -16747,7 +17232,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Предупреждение: в настройках файлообмена вы запретили прямую загрузку. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Уровень доверия является способом выразить доверие в этом ключе. Он не используется сторонним программным обеспечением, но может быть полезным для вас, чтобы запомнить хорошие/плохие ключи. @@ -16792,27 +17277,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.В настоящее время вы не разрешаете соединения от узлов Retroshare, подписанные этим ключом. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Ошибка в подписи - - Maybe password is wrong - Может быть, неправильный пароль + + Check the password! + - + Maybe password is wrong + Может быть, неправильный пароль + + + You haven't set a trust level for this key. Вы не настроили уровень доверия для этого ключа. - + + Retroshare profile Профиль RetroShare - + This is your own PGP key, and it is signed by : Это ваш собственный ключ PGP и он подписан: @@ -16991,8 +17496,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Участники @@ -17009,7 +17513,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Внутренний - + Chat with this person Начать чат @@ -17160,7 +17664,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Фото - + TextLabel Текстовая метка @@ -17204,8 +17708,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Комментарии @@ -17240,6 +17744,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Напишите комментарий... + + + Album + Альбом + PhotoItem @@ -17249,12 +17758,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Форма - + TextLabel Текстовая метка - + <!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; } @@ -17350,7 +17859,7 @@ p, li { white-space: pre-wrap; } Просмотр фото - + PhotoShare PhotoShare @@ -17391,7 +17900,7 @@ requesting to edit it! - + Stop Стоп @@ -17619,12 +18128,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Разрешить все плагины - + Plugin look-up directories Папки поиска плагинов @@ -17683,7 +18192,7 @@ malicious behavior of crafted plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Plugins</h1><p>Плагины загружаются из каталогов, перечисленных в нижней части списка.</p><p>По соображениям безопасности, разрешённые плагины загружаются автоматически до главного исполняемого файла RetroShare или изменения библиотеки плагинов. В таком случае, пользователь должен подтвердить их снова. После запуска программы, вы можете включить плагин вручную, нажав на кнопку "Включить" и перезагрузить RetroShare.</p> <p>Если вы хотите разрабатывать свои собственные плагины, свяжитесь с командой Разработчиков, они будут рады помочь вам!</p> - + Plugins Плагины @@ -18081,7 +18590,7 @@ malicious behavior of crafted plugins. Публикации - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18252,13 +18761,13 @@ malicious behavior of crafted plugins. Сайт - - + + Comments Комментарии - + Copy RetroShare Link Скопировать ссылку RetroShare @@ -18268,7 +18777,7 @@ malicious behavior of crafted plugins. - + Comment Комментарий @@ -18289,12 +18798,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up Голосовать "за" @@ -18308,7 +18817,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item Установить как чтение и удаление элемента @@ -18369,7 +18878,7 @@ malicious behavior of crafted plugins. Текстовая метка - + Loading Загрузка @@ -18459,13 +18968,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18475,60 +18978,50 @@ malicious behavior of crafted plugins. Администратор: - - - + + + unknown - + Distribution: Распространение: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Текстовая метка - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Сообщения @@ -18539,7 +19032,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18608,7 +19101,12 @@ malicious behavior of crafted plugins. - + + Empty + Пусто + + + Copy RetroShare Link Скопировать ссылку RetroShare @@ -18643,7 +19141,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18771,8 +19269,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19052,9 +19560,8 @@ and use the import button to load it PulseAddDialog - Post From: - Сообщение от: + Сообщение от: Account 1 @@ -19069,7 +19576,7 @@ and use the import button to load it Учётная запись 3 - + Add to Pulse Добавить в Pulse @@ -19092,17 +19599,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Из: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19127,10 +19649,20 @@ and use the import button to load it Отрицательное мнение - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19140,14 +19672,53 @@ and use the import button to load it - + + Post + + + + Cancel Отмена - Post Pulse to Wire - Сообщение-импульс для Телеграфа + Сообщение-импульс для Телеграфа + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19173,10 +19744,18 @@ and use the import button to load it Форма - - - - + + + + + Click to view picture + + + + + + + Image Изображение @@ -19184,44 +19763,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19231,17 +19810,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19251,7 +19830,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19259,7 +19838,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -19274,7 +19853,7 @@ and use the import button to load it - + follow Parent Group @@ -19284,7 +19863,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19309,7 +19888,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19345,29 +19924,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19445,7 +20024,7 @@ and use the import button to load it QObject - + Confirmation Подтверждение @@ -19687,7 +20266,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Результат - + Unable to make path Невозможно задать путь @@ -19722,7 +20301,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Запрос на файл отменён - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Эта версия RetroShare использует OpenPGP-SDK. В качестве побочного эффекта, она не использует системное публичное PGP хранилище, но имеет своё собственное хранилище, которое используется всеми экземплярами RetroShare. <br><br>Похоже, что вы не имеете такое хранилище, хотя ключи PGP упоминаются учётными записями RetroShare, вероятно, потому, что вы только что обновились до этой новой версии программного обеспечения. @@ -19876,7 +20455,7 @@ Reported error is: сек. - + TR up Отдача TR @@ -19921,7 +20500,7 @@ Reported error is: отключено - + Move IP %1 to whitelist Перенести IP %1 в белый список @@ -19937,7 +20516,7 @@ Reported error is: - + %1 seconds ago %1 секунд назад @@ -20022,7 +20601,7 @@ Security: no anonymous IDs - + Error Ошибка @@ -20413,9 +20992,8 @@ Security: no anonymous IDs Нажмите, чтобы возобновить процесс хеширования - <p>This certificate contains: - <p>Этот сертификат содержит: + <p>Этот сертификат содержит: @@ -20753,7 +21331,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 КБ @@ -20975,19 +21553,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Настройка древовидного представления - Show column... - Показать столбец... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Сортировать по убыванию + + + + Sort Ascending Order + Сортировать по возрастанию + + + + + [no title] + + + + + Show column … + + + + Show column... + Показать столбец... - [no title] - [без заголовка] + [без заголовка] @@ -21423,7 +22030,7 @@ p, li { white-space: pre-wrap; } Скачать! - + File Файл @@ -21438,7 +22045,7 @@ p, li { white-space: pre-wrap; } Хэш - + Bad filenames have been cleaned Были очищены неправильные имена файлов @@ -21488,7 +22095,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Сохранить - + Collection Editor Редактор коллекции @@ -21503,7 +22110,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Количество Файлов - + Real Size: Waiting child... Действительный размер: ждите... @@ -21518,12 +22125,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Это каталог. Нажмите дважды, чтобы развернуть его. - + Download files Скачать файлы - + Specify... Выбрать... @@ -21772,7 +22379,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Имя @@ -21792,7 +22399,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21805,10 +22412,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Название + + + UnRead + + Date @@ -21820,7 +22432,7 @@ If you believe it is correct, remove the corresponding line from the file and re Автор - + Information for this identity is currently missing. В настоящее время информация об этой личности отсутствует @@ -21860,7 +22472,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Пропущенное сообщение ... ] @@ -21868,7 +22480,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Дата @@ -21928,7 +22540,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22286,7 +22898,7 @@ prevents the message to be forwarded to your friends. Имя файла - + Download Скачать @@ -22365,7 +22977,7 @@ prevents the message to be forwarded to your friends. Открыть папку - + Create Collection... Создание коллекции... @@ -22385,7 +22997,7 @@ prevents the message to be forwarded to your friends. Загрузить из файла коллекции... - + Collection Коллекция @@ -22490,12 +23102,12 @@ prevents the message to be forwarded to your friends. Сведения об участнике - + Deny friend Отказать в соединении - + Chat Чат @@ -22505,7 +23117,7 @@ prevents the message to be forwarded to your friends. Начать чат - + Expand Развернуть @@ -22772,13 +23384,13 @@ behind a firewall or a VPN. Обнаружение включено (рекомендуется) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. Tor был автоматически настроен Retroshare. Здесь не нужно ничего менять. - + Discovery Off Обнаружение выключено @@ -23270,7 +23882,7 @@ If you have issues connecting over Tor check the Tor logs too. <p>В любом случае узел Retroshare, действующий как транслятор, не может видеть передаваемые данные, так как они зашифрованы и аутентифицированы двумя ретранслируемыми узлами.</p> - + Network Сеть @@ -23298,7 +23910,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Статус @@ -23395,7 +24007,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Адрес службы @@ -23430,12 +24042,12 @@ If you have issues connecting over Tor check the Tor logs too. Пожалуйста, заполните адрес службы - + IP Range Диапазон IP-адресов - + Reported by DHT for IP masquerading Получено из DHT; попытка подмены IP-адреса @@ -24109,7 +24721,7 @@ p, li { white-space: pre-wrap; } Отсутствует сертификат PGP - + Wrong password Неверный пароль @@ -24163,7 +24775,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Добавить доверенный узел @@ -24219,7 +24831,7 @@ This choice can be reverted in settings. Управление правами доступа - + DHT DHT @@ -24759,7 +25371,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24773,13 +25385,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor сейчас недоступен - + Tor is OK Tor в порядке @@ -24788,6 +25399,31 @@ p, li { white-space: pre-wrap; } No tor configuration Нет конфигурации Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25073,35 +25709,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - У вас %1 завершённых закачек + You have %1 completed transfers + - You have %1 completed download - У вас есть %1 завершённая загрузка + You have %1 completed transfer + - %1 completed downloads - %1 завершённых закачек + %1 completed transfers + - %1 completed download - %1 завершённых загрузок + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + У вас %1 завершённых закачек + + + You have %1 completed download + У вас есть %1 завершённая загрузка + + + %1 completed downloads + %1 завершённых закачек + + + %1 completed download + %1 завершённых загрузок TransfersDialog - + Downloads Обмен файлами @@ -25112,7 +25759,7 @@ p, li { white-space: pre-wrap; } Передача - + Name i.e: file name Имя @@ -25323,7 +25970,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;File Transfer</h1> <p>RetroShare поддерживает два метода передачи файлов: прямые передачи между друзьями и анонимные туннельные передачи. Кроме этого поддерживается загрузка от нескольких источников (вы также можете быть источником, пока скачиваете файл)</p> <p>Есть возможность раздавать свои файлы, воспользуйтесь значком <img src=":/images/directoryadd_24x24_shadow.png" width=16 /> на панели. Эти файлы будут добавлены в список разделяемых вами ресурсов. Дополнительно вы можете указать доступность этих файлов для ближнего окружения</p> <p>Вкладка "Поиск" позволяет искать файлы среди доступных ресурсов ваших контактов, а также у удалённых пользователей, через сервис анонимных туннелей.</p> - + Move in Queue... Переместить в очереди... @@ -25417,7 +26064,7 @@ p, li { white-space: pre-wrap; } Пожалуйста введите новое--и действительное--имя файла - + Expand all Раскрыть всё @@ -25549,7 +26196,7 @@ p, li { white-space: pre-wrap; } - + Columns Столбцы @@ -25560,7 +26207,7 @@ p, li { white-space: pre-wrap; } Файлообмен - + Path Путь @@ -25570,7 +26217,7 @@ p, li { white-space: pre-wrap; } Показать столбец "Путь" - + Could not delete preview file Не удалось удалить файл предварительного просмотра @@ -25580,7 +26227,7 @@ p, li { white-space: pre-wrap; } Попробуйте ещё раз? - + Create Collection... Создание коллекции... @@ -25595,7 +26242,7 @@ p, li { white-space: pre-wrap; } Просмотр коллекции... - + Collection Коллекция @@ -25841,7 +26488,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Неизвестный участник @@ -25937,7 +26584,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages У вас %1 новых сообщений @@ -26321,7 +26968,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group Подписаться на группу @@ -26415,8 +27062,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Показать историю редактирования @@ -26427,7 +27074,7 @@ p, li { white-space: pre-wrap; } - + Preview Предпросмотр @@ -26452,12 +27099,12 @@ p, li { white-space: pre-wrap; } Скрыть историю редактирования - + Edit Page Редактировать страницу - + Create New Wiki Page Создать новую страницу Wiki @@ -26477,7 +27124,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Создать новую группу Wiki @@ -26519,7 +27166,7 @@ p, li { white-space: pre-wrap; } Диапазон времени - + Create Account @@ -26529,12 +27176,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Обновить @@ -26569,12 +27215,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26644,7 +27290,7 @@ p, li { white-space: pre-wrap; } Показаны: - + Yourself Себя @@ -26682,7 +27328,7 @@ p, li { white-space: pre-wrap; } Сообщение-импульс для Телеграфа - + RetroShare RetroShare @@ -26694,7 +27340,7 @@ p, li { white-space: pre-wrap; } - + The Wire Провод @@ -26702,7 +27348,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26783,8 +27429,8 @@ p, li { white-space: pre-wrap; } Форма - - + + Avatar Аватар @@ -26813,6 +27459,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26925,8 +27576,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Изображения (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Изображения (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_sl.ts b/retroshare-gui/src/lang/retroshare_sl.ts index 7a7fe45cd..a8c42dad2 100644 --- a/retroshare-gui/src/lang/retroshare_sl.ts +++ b/retroshare-gui/src/lang/retroshare_sl.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -167,7 +167,7 @@ AlbumDialog - + Album @@ -282,7 +282,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -325,8 +325,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -393,7 +393,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -418,7 +418,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -443,7 +443,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -518,7 +518,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -533,7 +533,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -599,13 +599,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -614,25 +619,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -640,7 +650,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -660,44 +670,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Pokaži nastavitve + TextLabel + + + + Reset Ponastavi - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -707,30 +726,23 @@ p, li { white-space: pre-wrap; } - Save - Shrani + Shrani - Cancel - Prekliči + Prekliči - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -752,7 +764,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -886,7 +898,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -964,6 +976,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ime + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1099,6 +1190,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Privzeto + + + + Dark + + ChannelPage @@ -1151,6 +1252,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ime + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1359,22 +1539,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1388,11 +1568,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1825,13 +2000,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1896,17 +2065,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1927,11 +2091,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1992,11 +2157,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2135,8 +2306,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2305,7 +2491,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2322,12 +2508,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2399,7 +2585,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2435,12 +2621,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2456,7 +2642,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2476,7 +2662,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2634,12 +2820,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2650,12 +2836,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2671,31 +2857,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2711,22 +2907,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2761,13 +2957,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2782,7 +2983,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2793,17 +2994,22 @@ Double click on it to add his name on text writer. brez - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2813,7 +3019,7 @@ Double click on it to add his name on text writer. - + with @@ -2897,32 +3103,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Ime: - + Location: - + Options Možnosti - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2932,7 +3138,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2957,12 +3163,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2982,32 +3188,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3053,17 +3259,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3083,12 +3289,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3136,7 +3342,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3180,12 +3416,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3215,7 +3451,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3273,12 +3509,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3353,7 +3589,12 @@ even if you don't make friends. - + + Status + Stanje + + + <!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; } @@ -3775,7 +4016,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3915,7 +4156,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3930,7 +4171,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3946,7 +4187,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3962,12 +4203,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3989,7 +4230,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4115,7 +4356,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4161,7 +4402,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4171,7 +4412,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4198,17 +4439,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4239,12 +4500,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4264,7 +4525,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4352,7 +4613,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4767,7 +5028,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5770,7 +6031,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6261,7 +6522,7 @@ at least one peer was not added to a group - + Mark all @@ -6275,7 +6536,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6379,7 +6640,7 @@ at least one peer was not added to a group - + Network @@ -6444,7 +6705,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6475,7 +6736,7 @@ at least one peer was not added to a group - + Node name @@ -6734,12 +6995,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7102,7 +7363,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7167,7 +7428,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7190,7 +7451,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7391,7 +7652,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7401,13 +7662,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7417,42 +7695,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7467,40 +7710,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Ime - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7649,7 +7883,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7670,12 +7904,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8045,7 +8279,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8145,12 +8379,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8161,18 +8395,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8182,12 +8416,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8247,7 +8481,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8262,12 +8496,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8343,23 +8577,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8381,11 +8628,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8870,17 +9112,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8890,19 +9132,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8917,7 +9159,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8962,23 +9214,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -9016,17 +9268,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9056,8 +9308,8 @@ before you can comment - - + + Distribution @@ -9144,12 +9396,12 @@ before you can comment - + New thread - + Edit @@ -9205,7 +9457,7 @@ before you can comment - + Author's reputation @@ -9225,7 +9477,7 @@ before you can comment - + <b>Loading...<b> @@ -9265,6 +9517,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9332,7 +9589,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9364,11 +9621,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9774,7 +10026,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9789,7 +10041,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9799,12 +10051,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9871,12 +10123,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9891,7 +10143,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10405,7 +10657,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10414,7 +10666,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10440,7 +10692,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10514,49 +10766,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10604,17 +10862,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10629,7 +10882,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10894,14 +11152,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10911,12 +11169,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11060,7 +11318,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11132,7 +11390,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11147,24 +11405,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11179,7 +11437,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11238,13 +11496,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11304,7 +11567,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11352,7 +11615,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11361,12 +11624,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11378,12 +11641,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11499,17 +11762,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11666,8 +11929,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11678,7 +11941,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11688,7 +11951,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11748,7 +12011,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11758,7 +12021,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11796,7 +12059,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11813,14 +12076,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11831,24 +12094,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11868,12 +12134,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11883,7 +12174,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11893,7 +12184,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11933,12 +12229,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11948,7 +12239,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12053,7 +12344,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12212,7 +12503,7 @@ These identities will soon be not supported anymore. - + Options Možnosti @@ -12244,12 +12535,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12378,7 +12669,7 @@ These identities will soon be not supported anymore. Pokaži - + Make sure this link has not been forged to drag you to a malicious website. @@ -12423,7 +12714,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12452,7 +12743,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12554,7 +12845,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12649,12 +12940,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12684,7 +12975,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12710,12 +13006,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12726,7 +13022,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12980,7 +13276,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12994,6 +13290,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13006,7 +13317,7 @@ Do you want to save message ? Od: - + Bullet list (disc) @@ -13046,13 +13357,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13191,8 +13502,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13204,12 +13530,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13284,12 +13610,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13350,18 +13682,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13376,7 +13723,7 @@ Do you want to save message ? - + Load images always for this message @@ -13485,7 +13832,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13501,14 +13848,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13579,7 +13926,7 @@ Do you want to save message ? - + Subject @@ -13659,7 +14006,7 @@ Do you want to save message ? - + Open in a new window @@ -13744,7 +14091,7 @@ Do you want to save message ? - + Drafts @@ -13833,7 +14180,7 @@ Do you want to save message ? - + Delete Message @@ -13844,7 +14191,7 @@ Do you want to save message ? - + Expand @@ -13854,7 +14201,7 @@ Do you want to save message ? - + from @@ -13863,6 +14210,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14162,7 +14514,7 @@ Reported error: - + Groups @@ -14192,19 +14544,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14214,7 +14566,7 @@ Reported error: - + Show Items @@ -14413,18 +14765,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14462,7 +14814,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14476,7 +14828,7 @@ at least one peer was not added to a group - + Newest on top @@ -14487,20 +14839,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14533,22 +14900,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14569,12 +14936,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14621,27 +14983,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14691,7 +15063,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14701,7 +15073,7 @@ at least one peer was not added to a group - + Systray @@ -14828,17 +15200,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14893,22 +15260,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14922,7 +15284,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14932,22 +15294,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14967,7 +15319,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15033,27 +15385,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15065,7 +15417,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15110,27 +15462,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15301,8 +15669,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15319,7 +15686,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15451,7 +15818,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15487,7 +15854,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15515,6 +15882,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... ... + + + Album + + PhotoItem @@ -15524,12 +15896,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15609,7 +15981,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15649,7 +16021,7 @@ requesting to edit it! - + Stop @@ -15873,17 +16245,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16209,7 +16581,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16340,13 +16712,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16356,7 +16728,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16377,12 +16749,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16392,7 +16764,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16453,7 +16825,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16476,13 +16848,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16492,60 +16858,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown neznano - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16556,7 +16912,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16625,7 +16981,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16660,7 +17021,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16776,8 +17137,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17045,12 +17416,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17065,17 +17431,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + Od: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17100,10 +17481,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17113,13 +17504,48 @@ and use the import button to load it - + + Post + + + + Cancel Prekliči - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17138,10 +17564,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17149,44 +17583,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17196,17 +17630,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17216,7 +17650,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17224,7 +17658,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17239,7 +17673,7 @@ and use the import button to load it - + follow Parent Group @@ -17249,7 +17683,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17274,7 +17708,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17310,29 +17744,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17410,7 +17844,7 @@ and use the import button to load it QObject - + Confirmation @@ -17649,7 +18083,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17684,7 +18118,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17822,7 +18256,7 @@ Reported error is: - + TR up @@ -17867,7 +18301,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17883,7 +18317,7 @@ Reported error is: - + %1 seconds ago @@ -17967,7 +18401,7 @@ Security: no anonymous IDs - + Error @@ -18357,11 +18791,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18695,7 +19124,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18917,18 +19346,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19365,7 +19815,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19380,7 +19830,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19428,7 +19878,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Shrani - + Collection Editor @@ -19443,7 +19893,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19458,12 +19908,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19710,7 +20160,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Ime @@ -19730,7 +20180,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19743,10 +20193,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19758,7 +20213,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19796,7 +20251,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19804,7 +20259,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19864,7 +20319,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20218,7 +20673,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20297,7 +20752,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20317,7 +20772,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20422,12 +20877,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20437,7 +20892,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20700,13 +21155,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21172,7 +21627,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21200,7 +21655,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Stanje @@ -21297,7 +21752,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21332,12 +21787,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22002,7 +22457,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22044,7 +22499,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22100,7 +22555,7 @@ This choice can be reverted in settings. - + DHT @@ -22632,7 +23087,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22642,13 +23097,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22657,6 +23111,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22930,27 +23409,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22958,7 +23432,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22969,7 +23443,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Ime @@ -23176,7 +23650,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23270,7 +23744,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23402,7 +23876,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23413,7 +23887,7 @@ p, li { white-space: pre-wrap; } - + Path Pot @@ -23423,7 +23897,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23433,7 +23907,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23448,7 +23922,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23690,7 +24164,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23786,7 +24260,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24154,7 +24628,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24248,8 +24722,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24260,7 +24734,7 @@ p, li { white-space: pre-wrap; } - + Preview Predogled @@ -24285,12 +24759,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24310,7 +24784,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24348,7 +24822,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24358,12 +24832,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24398,12 +24871,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24433,7 +24906,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24443,7 +24916,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24455,7 +24928,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24463,7 +24936,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24544,8 +25017,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24574,6 +25047,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24686,7 +25164,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_sr.ts b/retroshare-gui/src/lang/retroshare_sr.ts index 2f058046b..6d5a3f97d 100644 --- a/retroshare-gui/src/lang/retroshare_sr.ts +++ b/retroshare-gui/src/lang/retroshare_sr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -122,12 +122,12 @@ Напредна претрага - + Search Criteria Критеријум претраге - + Add a further search criterion. Додајте додатни критеријум претраге. @@ -168,7 +168,7 @@ AlbumDialog - + Album @@ -283,7 +283,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -326,8 +326,8 @@ p, li { white-space: pre-wrap; } Образац - - + + TextLabel @@ -394,7 +394,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -419,7 +419,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -444,7 +444,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -519,7 +519,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -600,13 +600,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -615,25 +620,30 @@ p, li { white-space: pre-wrap; } Уклони - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar Кликните да промените аватар @@ -641,7 +651,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -661,44 +671,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage Употреба протока + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Прикажи подешавања + TextLabel + + + + Reset Поништи - Receive Rate - Брзина пријема + Брзина пријема - Send Rate - Брзина слања + Брзина слања - + Always on Top Увек на врху - Style - Стил + Стил - + Changes the transparency of the Bandwidth Graph Мења провидност графикона за проток - + 100 100 @@ -708,30 +739,27 @@ p, li { white-space: pre-wrap; } % непровидно - Save - Сачувај + Сачувај - Cancel - Откажи + Откажи - + Since: Од: - Hide Settings - Сакриј подешавања + Сакриј подешавања BandwidthStatsWidget - + Sum @@ -753,7 +781,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -887,7 +915,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -965,6 +993,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Промени статус порука + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Прошири + + + + Set as read and remove item + + + + + Remove Item + Уклони ставку + + + + Name + Назив + + + + Comm value + + + + + Comment + Коментар + + + + Comments + + + + + Hide + Сакриј + + BwCtrlWindow @@ -1100,6 +1207,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Подразумевано + + + + Dark + + ChannelPage @@ -1152,6 +1269,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Промени статус порука + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Прошири + + + + Set as read and remove item + + + + + Remove Item + Уклони ставку + + + + Name + Назив + + + + Comm value + + + + + Comment + Коментар + + + + Comments + + + + + Hide + Сакриј + + ChatLobbyDialog @@ -1360,22 +1556,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1389,11 +1585,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1830,13 +2021,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1901,17 +2086,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1932,11 +2112,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1997,11 +2178,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2140,8 +2327,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2310,7 +2512,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2327,12 +2529,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2404,7 +2606,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2440,12 +2642,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2461,7 +2663,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2481,7 +2683,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2639,12 +2841,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2655,12 +2857,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2676,31 +2878,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare Ретрошер - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2716,22 +2928,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2766,13 +2978,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2787,7 +3004,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2798,17 +3015,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2818,7 +3040,7 @@ Double click on it to add his name on text writer. - + with @@ -2902,32 +3124,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Назив: - + Location: Место: - + Options Опције - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2937,7 +3159,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2962,12 +3184,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2987,32 +3209,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3058,17 +3280,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3088,12 +3310,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3141,7 +3363,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3185,12 +3437,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3220,7 +3472,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3278,12 +3530,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3358,7 +3610,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3780,7 +4037,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3924,7 +4181,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3939,7 +4196,7 @@ p, li { white-space: pre-wrap; } - + Search Претражи @@ -3955,7 +4212,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3971,12 +4228,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3998,7 +4255,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4124,7 +4381,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4170,7 +4427,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4180,7 +4437,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4207,17 +4464,37 @@ p, li { white-space: pre-wrap; } - + RetroShare Ретрошер - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4248,12 +4525,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4273,7 +4550,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4365,7 +4642,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4780,7 +5057,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5783,7 +6060,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6274,7 +6551,7 @@ at least one peer was not added to a group - + Mark all @@ -6288,7 +6565,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6392,7 +6669,7 @@ at least one peer was not added to a group - + Network @@ -6457,7 +6734,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6488,7 +6765,7 @@ at least one peer was not added to a group - + Node name @@ -6747,12 +7024,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7115,7 +7392,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7180,7 +7457,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7203,7 +7480,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7404,7 +7681,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7414,13 +7691,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7430,42 +7724,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7480,40 +7739,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post Последња порука - + + Name Назив - - Unread - - - - + Popularity Популарност - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7662,7 +7912,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7683,12 +7933,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8058,7 +8308,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8158,12 +8408,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8174,18 +8424,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8195,12 +8445,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8260,7 +8510,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8275,12 +8525,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8356,23 +8606,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe Пријави ме - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8394,11 +8657,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8883,7 +9141,7 @@ before you can comment - + Search forums @@ -8892,12 +9150,12 @@ before you can comment Последња порука - + New Thread - + Threaded View @@ -8907,19 +9165,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8934,7 +9192,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8979,23 +9247,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -9033,12 +9301,12 @@ before you can comment - + Copy RetroShare Link - + Hide Сакриј @@ -9047,7 +9315,7 @@ before you can comment Прошири - + [unknown] @@ -9077,8 +9345,8 @@ before you can comment - - + + Distribution @@ -9161,12 +9429,12 @@ before you can comment - + New thread - + Edit @@ -9222,7 +9490,7 @@ before you can comment - + Author's reputation @@ -9242,7 +9510,7 @@ before you can comment - + <b>Loading...<b> @@ -9282,6 +9550,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9349,7 +9622,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9381,11 +9654,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9791,7 +10059,7 @@ This message is missing. You should receive it later. - + Unsubscribe Одјави ме @@ -9806,7 +10074,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9816,12 +10084,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9888,12 +10156,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9908,7 +10176,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10422,7 +10690,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10431,7 +10699,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10457,7 +10725,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10531,49 +10799,55 @@ p, li { white-space: pre-wrap; } Образац - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10621,17 +10895,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10646,7 +10915,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10911,14 +11185,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10928,12 +11202,12 @@ p, li { white-space: pre-wrap; } Претражи - + Anonymous Id - + Create new Identity @@ -11077,7 +11351,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11149,7 +11423,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11164,24 +11438,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11196,7 +11470,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11255,13 +11529,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11321,7 +11600,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11369,7 +11648,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11378,12 +11657,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11395,12 +11674,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11516,17 +11795,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11683,8 +11962,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11695,7 +11974,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11705,7 +11984,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11765,7 +12044,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11775,7 +12054,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11813,7 +12092,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11830,14 +12109,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11848,24 +12127,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11885,12 +12167,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11900,7 +12207,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11910,7 +12217,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11950,12 +12262,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11965,7 +12272,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12070,7 +12377,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12229,7 +12536,7 @@ These identities will soon be not supported anymore. - + Options Опције @@ -12261,12 +12568,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12395,7 +12702,7 @@ These identities will soon be not supported anymore. Прикажи - + Make sure this link has not been forged to drag you to a malicious website. @@ -12440,7 +12747,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12469,7 +12776,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12571,7 +12878,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12666,12 +12973,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12701,7 +13008,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12727,12 +13039,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12743,7 +13055,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12997,7 +13309,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13011,6 +13323,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13023,7 +13350,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13063,13 +13390,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13208,8 +13535,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13221,12 +13563,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13301,12 +13643,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13367,18 +13715,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13393,7 +13756,7 @@ Do you want to save message ? - + Load images always for this message @@ -13502,7 +13865,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13518,14 +13881,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13596,7 +13959,7 @@ Do you want to save message ? - + Subject Наслов @@ -13676,7 +14039,7 @@ Do you want to save message ? - + Open in a new window @@ -13761,7 +14124,7 @@ Do you want to save message ? - + Drafts @@ -13850,7 +14213,7 @@ Do you want to save message ? - + Delete Message @@ -13861,7 +14224,7 @@ Do you want to save message ? - + Expand Прошири @@ -13871,7 +14234,7 @@ Do you want to save message ? Уклони ставку - + from @@ -13880,6 +14243,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14179,7 +14547,7 @@ Reported error: - + Groups @@ -14209,19 +14577,19 @@ Reported error: - - + + Search Претражи - + ID ИД - + Search ID @@ -14231,7 +14599,7 @@ Reported error: - + Show Items @@ -14430,18 +14798,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14479,7 +14847,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14493,7 +14861,7 @@ at least one peer was not added to a group - + Newest on top @@ -14504,20 +14872,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14550,22 +14933,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14586,12 +14969,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14638,27 +15016,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14708,7 +15096,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14718,7 +15106,7 @@ at least one peer was not added to a group - + Systray @@ -14845,17 +15233,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14910,22 +15293,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14939,7 +15317,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14949,22 +15327,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14984,7 +15352,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15050,27 +15418,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare Ретрошер - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15082,7 +15450,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15127,27 +15495,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15318,8 +15702,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15336,7 +15719,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15475,7 +15858,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15515,7 +15898,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15543,6 +15926,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15552,12 +15940,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Образац - + TextLabel - + <!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; } @@ -15637,7 +16025,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15677,7 +16065,7 @@ requesting to edit it! - + Stop @@ -15901,17 +16289,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16237,7 +16625,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16368,13 +16756,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments - + Copy RetroShare Link @@ -16384,7 +16772,7 @@ p, li { white-space: pre-wrap; } - + Comment Коментар @@ -16405,12 +16793,12 @@ p, li { white-space: pre-wrap; } - + Hide Сакриј - + Vote up @@ -16420,7 +16808,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16481,7 +16869,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16515,13 +16903,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -16531,60 +16913,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16595,7 +16967,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16664,7 +17036,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16699,7 +17076,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16815,8 +17192,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17084,12 +17471,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17104,17 +17486,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17139,10 +17536,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17152,13 +17559,48 @@ and use the import button to load it - + + Post + + + + Cancel Поништи - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17177,10 +17619,18 @@ and use the import button to load it Образац - - - - + + + + + Click to view picture + + + + + + + Image @@ -17188,44 +17638,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17235,17 +17685,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17255,7 +17705,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17263,7 +17713,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17278,7 +17728,7 @@ and use the import button to load it - + follow Parent Group @@ -17288,7 +17738,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17313,7 +17763,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17349,29 +17799,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17449,7 +17899,7 @@ and use the import button to load it QObject - + Confirmation @@ -17688,7 +18138,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17723,7 +18173,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17861,7 +18311,7 @@ Reported error is: - + TR up @@ -17906,7 +18356,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17922,7 +18372,7 @@ Reported error is: - + %1 seconds ago @@ -18006,7 +18456,7 @@ Security: no anonymous IDs - + Error @@ -18396,11 +18846,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18734,7 +19179,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18956,18 +19401,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19404,7 +19870,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19419,7 +19885,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19467,7 +19933,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Сачувај - + Collection Editor @@ -19482,7 +19948,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19497,12 +19963,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19749,7 +20215,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Назив @@ -19769,7 +20235,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19782,10 +20248,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19797,7 +20268,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19835,7 +20306,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19843,7 +20314,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19903,7 +20374,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20257,7 +20728,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20336,7 +20807,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20356,7 +20827,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20461,12 +20932,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20476,7 +20947,7 @@ prevents the message to be forwarded to your friends. - + Expand Прошири @@ -20739,13 +21210,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21211,7 +21682,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21239,7 +21710,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21336,7 +21807,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21371,12 +21842,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22041,7 +22512,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22083,7 +22554,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22139,7 +22610,7 @@ This choice can be reverted in settings. - + DHT @@ -22671,7 +23142,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22681,13 +23152,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22696,6 +23166,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22969,27 +23464,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22997,7 +23487,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23008,7 +23498,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Назив @@ -23215,7 +23705,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23309,7 +23799,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23441,7 +23931,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23452,7 +23942,7 @@ p, li { white-space: pre-wrap; } - + Path Путања @@ -23462,7 +23952,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23472,7 +23962,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23487,7 +23977,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23729,7 +24219,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23825,7 +24315,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24193,7 +24683,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24287,8 +24777,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24299,7 +24789,7 @@ p, li { white-space: pre-wrap; } - + Preview Преглед @@ -24324,12 +24814,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24349,7 +24839,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24387,7 +24877,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24397,12 +24887,11 @@ p, li { white-space: pre-wrap; } - ... - + - + Refresh @@ -24437,12 +24926,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24472,7 +24961,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24482,7 +24971,7 @@ p, li { white-space: pre-wrap; } - + RetroShare Ретрошер @@ -24494,7 +24983,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24502,7 +24991,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24583,8 +25072,8 @@ p, li { white-space: pre-wrap; } Образац - - + + Avatar @@ -24613,6 +25102,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24725,7 +25219,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_sv.ts b/retroshare-gui/src/lang/retroshare_sv.ts index 30831234a..3bdd3ebc7 100644 --- a/retroshare-gui/src/lang/retroshare_sv.ts +++ b/retroshare-gui/src/lang/retroshare_sv.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -128,12 +128,12 @@ RetroShare: Avancerad sökning - + Search Criteria Sökkriterium - + Add a further search criterion. Lägg till ytterligare sökkriterium. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Formulär - - + + TextLabel Bildtext @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Verktygsfält - + Icon Only Endast ikon @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 Ikonstorlek = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Ikonstorlek = 128x128 - + Status Bar Statusfält @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Ikonstorlek = 32x32 @@ -827,14 +827,23 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot Byt profilbild - + + TextLabel + + + + Your Avatar Picture Din profilbild - + + Browse... + + + Add Avatar - Lägg till profilbild + Lägg till profilbild @@ -842,25 +851,34 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot Ta bort - + Set your Avatar picture Lägg till din probild - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Läs in profilbild + Läs in profilbild AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klicka för att ändra din profilbild @@ -868,7 +886,7 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot RetroShare Bandwidth Usage RetroShare bandbreddsanvändning + + + PushButton + + - + Up + Upp + + + + Down + Ner + + + + Clears the graph + + + + Show Settings Visa inställningar + TextLabel + + + + Reset Återställ - Receive Rate - Mottagningshastighet + Mottagningshastighet - Send Rate - Sändningshastighet + Sändningshastighet - + Always on Top Alltid överst - Style - Stil + Stil - + Changes the transparency of the Bandwidth Graph Ändrar transparensen på bandbreddsgrafen - + 100 100 @@ -935,30 +974,27 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot % Opak - Save - Spara + Spara - Cancel - Avbryt + Avbryt - + Since: Sedan: - Hide Settings - Dölj inställningar + Dölj inställningar BandwidthStatsWidget - + Sum @@ -980,7 +1016,7 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot Antal - + Average Medel @@ -1114,7 +1150,7 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot - + Comments Kommentarer @@ -1192,6 +1228,85 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot + + BoardsCommentsItem + + + I like this + Jag gillar detta + + + + 0 + 0 + + + + I dislike this + Jag gillar inte detta + + + + Toggle Message Read Status + Växla meddelandestatus + + + + Avatar + Profilbild + + + + New Comment + + + + + Copy RetroShare Link + Kopiera RetroShare-länk + + + + + Expand + + + + + Set as read and remove item + Markera som läst och ta bort objektet + + + + Remove Item + Ta bort objektet + + + + Name + Namn + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Dölj + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Kom bara ihåg... all data här, *KOMMER* att förloras när vi uppgraderar prot Log scale + + + Default + Standard + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Jag gillar detta + + + + 0 + 0 + + + + I dislike this + Jag gillar inte detta + + + + Toggle Message Read Status + Växla meddelandestatus + + + + Avatar + Profilbild + + + + New Comment + + + + + Copy RetroShare Link + Kopiera RetroShare-länk + + + + + Expand + + + + + Set as read and remove item + Markera som läst och ta bort objektet + + + + Remove Item + Ta bort objektet + + + + Name + Namn + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Dölj + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to - You have %1 new messages - Du har %1 nya meddelanden + Du har %1 nya meddelanden + + + You have %1 new message + Du har %1 nytt meddelande + + + %1 new messages + %1 nya meddelanden + + + %1 new message + %1 nytt meddelande + + + + You have %1 mentions + - You have %1 new message - Du har %1 nytt meddelande + You have %1 mention + - %1 new messages - %1 nya meddelanden + %1 mentions + - %1 new message - %1 nytt meddelande + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Ta bort alla - - - mention(s) - - ChatLobbyWidget @@ -2097,13 +2312,11 @@ Double click a chat room to enter and chat. - Group chat - Gruppchatt + Gruppchatt - - + Private chat Privatchatt @@ -2168,17 +2381,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - Chatlobbies - Chatlobbyn + Chatlobbyn - + Enabled: Aktiverad: @@ -2199,11 +2411,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2264,11 +2477,17 @@ Double click a chat room to enter and chat. + Broadcast Sändning - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Sparade meddelanden (0 = obegränsat) @@ -2411,8 +2630,23 @@ Double click a chat room to enter and chat. Privatchatt - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2581,7 +2815,7 @@ Double click a chat room to enter and chat. - + is typing... skriver... @@ -2598,12 +2832,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Vill du verkligen ta bort historiken? @@ -2675,7 +2909,7 @@ after HTML conversion. Sluta inte att färga efter X hittade (använder mer CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2715,12 +2949,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2736,7 +2970,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2756,7 +2990,7 @@ Double click on it to add his name on text writer. Skriv ett meddelande här - + Don't stop to color after @@ -2914,12 +3148,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaljer - + Local Address Lokal adress @@ -2930,12 +3164,12 @@ Double click on it to add his name on text writer. Extern adress - + Node info: - + Current address: @@ -2951,31 +3185,41 @@ Double click on it to add his name on text writer. Port - + Include signatures Inkludera signaturer - + RetroShare RetroShare - + - + Error : cannot get peer details. Fel: Kan inte hämta användaruppgifter. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2991,22 +3235,22 @@ Double click on it to add his name on text writer. - + Encryption Kryptering - + Not connected Inte ansluten - + Retroshare node details - + Node name : Nodnamn : @@ -3041,13 +3285,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Retroshare-certifikat @@ -3062,7 +3311,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3073,17 +3322,22 @@ Double click on it to add his name on text writer. ingen - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3093,7 +3347,7 @@ Double click on it to add his name on text writer. - + with med @@ -3285,12 +3539,12 @@ Double click on it to add his name on text writer. Fakta om begäran - + Peer details Användarinformation - + Name: Namn: @@ -3303,22 +3557,22 @@ Double click on it to add his name on text writer. Nod: - + Location: Plats: - + Options Alternativ - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Lägg till kontakt till grupp: @@ -3328,7 +3582,7 @@ Double click on it to add his name on text writer. Autentisera kontakt (Signera PGP-nyckel) - + Please paste below your friend's Retroshare ID @@ -3353,7 +3607,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Lägg till en kontakt att ansluta till @@ -3362,7 +3616,7 @@ Double click on it to add his name on text writer. Klicka på 'Slutför' för att acceptera denna kontaktförfrågan - + Sorry, some error appeared Något fel uppstod @@ -3382,32 +3636,32 @@ Double click on it to add his name on text writer. Fakta om din kontakt: - + Key validity: Nyckelvaliditet: - + Profile ID: - + Signers Signerad av: - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Denna användare finns redan på din kontaktlista. Att lägga till den kanske bara anger IP-adress. - + To accept the Friend Request, click the Accept button. @@ -3453,7 +3707,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Certifikatinläsning misslyckades @@ -3486,12 +3740,12 @@ Double click on it to add his name on text writer. Användar-ID - + Not a valid Retroshare certificate! - + RetroShare Invitation RetroShare-inbjudan @@ -3511,12 +3765,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3564,7 +3818,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du har en kontaktförfrågan från - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3652,12 +3936,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Använd som direkt källa, om tillgänglig - + IP-Addr: - + IP-Address IP-adress @@ -3715,7 +3999,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Lägg till nyckel till nyckelring - + This key is already in your keyring Den här nyckeln finns redan i din nyckelring @@ -3773,12 +4057,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3853,7 +4137,12 @@ even if you don't make friends. UDP Resultat - + + Status + Status + + + <!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; } @@ -4275,7 +4564,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4423,7 +4712,7 @@ p, li { white-space: pre-wrap; } Inga cirkel begränsningar valda - + [Unknown] @@ -4438,7 +4727,7 @@ p, li { white-space: pre-wrap; } Ta bort - + Search Sök @@ -4458,7 +4747,7 @@ p, li { white-space: pre-wrap; } Signerad av kända noder - + Edit Circle Editera cirkeln @@ -4478,12 +4767,12 @@ p, li { white-space: pre-wrap; } Anonymt Id - + Circle name - + Update @@ -4509,7 +4798,7 @@ p, li { white-space: pre-wrap; } PGP-länkat ID - + Add Member @@ -4653,7 +4942,7 @@ p, li { white-space: pre-wrap; } - + Attachments Bilagor @@ -4699,7 +4988,7 @@ p, li { white-space: pre-wrap; } Dra och släpp filer från sökresultat - + Paste RetroShare Links Klistra in RetroShare-länkar @@ -4709,7 +4998,7 @@ p, li { white-space: pre-wrap; } Klistra in RetroShare-länk - + Drop file error. Dra & släpp-fel @@ -4736,17 +5025,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Filen är redan tillagd och hash-beräknad + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Filen är redan tillagd och hash-beräknad + + + Please add a Subject Ange ett ämne @@ -4777,12 +5090,12 @@ p, li { white-space: pre-wrap; } Vill du verkligen generera %1 meddelanden? - + You are about to add files you're not actually sharing. Do you still want this to happen? Du är på väg att lägga till filer som du inte delar. Vill du verkligen fortsätta? - + Edit Channel Post @@ -4802,7 +5115,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Om att posta icke delade filer till en kanal @@ -4894,7 +5207,7 @@ p, li { white-space: pre-wrap; } - + No Forum Inga forum @@ -5349,7 +5662,7 @@ och där läsa in den med importfunktionen. DHTGraphSource - + users användare @@ -6352,7 +6665,7 @@ och där läsa in den med importfunktionen. FlatStyle_RDM - + Friends Directories Kontakters mappar @@ -6847,7 +7160,7 @@ at least one peer was not added to a group Sök kontakter - + Mark all Markera alla @@ -6861,7 +7174,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Redigera statusmeddelande @@ -6965,7 +7278,7 @@ at least one peer was not added to a group Retroshare utsändningschat: meddelanden skickas till alla anslutna vänner. - + Network Nätverk @@ -7030,7 +7343,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7061,7 +7374,7 @@ at least one peer was not added to a group - + Node name @@ -7324,12 +7637,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7701,7 +8014,7 @@ p, li { white-space: pre-wrap; } Router-statistik - + GroupBox @@ -7766,7 +8079,7 @@ p, li { white-space: pre-wrap; } - + Details Detaljer @@ -7789,7 +8102,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Hanterade nycklar @@ -7990,7 +8303,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8000,13 +8313,30 @@ p, li { white-space: pre-wrap; } Sök titel - - + + + + Description Beskrivning - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Sök beskrivning @@ -8016,42 +8346,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Sortera efter namn + Sortera efter namn - Sort by Popularity - Sortera efter popularitet + Sortera efter popularitet - Sort by Last Post - Sortera efter senaste inlägg + Sortera efter senaste inlägg - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8066,40 +8373,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Senaste inlägget - + + Name Namn - - Unread - - - - + Popularity Popularitet - - + + Never - Display - Visa + Visa - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8248,7 +8550,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanaler @@ -8269,12 +8571,12 @@ p, li { white-space: pre-wrap; } Mina kanaler - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Kanalabonnemang @@ -8739,7 +9041,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8839,12 +9141,12 @@ p, li { white-space: pre-wrap; } - + Files Filer - + Comments Kommentarer @@ -8855,18 +9157,18 @@ p, li { white-space: pre-wrap; } - + Feeds Flöden - - + + Click to switch to list view - + Show unread posts only @@ -8876,12 +9178,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8941,7 +9243,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8956,12 +9258,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9037,23 +9339,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Prenumererat - - Subscribe Prenumerera - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Inga kanaler markerade @@ -9075,11 +9390,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanalinlägg - - - new message(s) - - GxsCircleItem @@ -9597,7 +9907,7 @@ innan du kan kommentera Starta ny tråd i aktuellt forum - + Search forums Sök i forum @@ -9606,12 +9916,12 @@ innan du kan kommentera Senaste inlägget - + New Thread Ny tråd - + Threaded View Trådvy @@ -9621,19 +9931,19 @@ innan du kan kommentera Platt vy - - + + Title Rubrik - - + + Date Datum - + Author Författare @@ -9648,7 +9958,17 @@ innan du kan kommentera Läser in - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9705,23 +10025,23 @@ innan du kan kommentera Sökinnehåll - + No name Inget namn - - + + Reply Svara - + <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> - + Loading... @@ -9759,12 +10079,12 @@ innan du kan kommentera Markera som oläst - + Copy RetroShare Link Kopiera RetroShare-länk - + Hide Dölj @@ -9773,7 +10093,7 @@ innan du kan kommentera Expandera - + [unknown] @@ -9803,8 +10123,8 @@ innan du kan kommentera - - + + Distribution @@ -9903,12 +10223,12 @@ innan du kan kommentera Originalmeddelande - + New thread - + Edit Redigera @@ -9964,7 +10284,7 @@ innan du kan kommentera - + Author's reputation @@ -9984,7 +10304,7 @@ innan du kan kommentera - + <b>Loading...<b> @@ -10024,6 +10344,11 @@ innan du kan kommentera Storage + + + Last seen at friends: + + Moderators @@ -10091,7 +10416,7 @@ This message is missing. You should receive it later. I %1, skrev %2: - + Forum name Forumnamn @@ -10123,11 +10448,6 @@ This message is missing. You should receive it later. Forum Post Foruminlägg - - - new message(s) - - GxsForumsDialog @@ -10572,7 +10892,7 @@ This message is missing. You should receive it later. Förhandsgranskning - + Unsubscribe Avsluta prenumerationen @@ -10587,7 +10907,7 @@ This message is missing. You should receive it later. Öppna i ny flik - + Remove this search @@ -10597,12 +10917,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Visa detaljer @@ -10669,12 +10989,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopiera RetroShare-länk @@ -10689,7 +11009,7 @@ This message is missing. You should receive it later. Markera alla som olästa - + AUTHD AUTHD @@ -11215,7 +11535,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11224,7 +11544,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11250,7 +11570,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11328,49 +11648,55 @@ p, li { white-space: pre-wrap; } Formulär - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopiera certifikatet till Urklipp @@ -11418,17 +11744,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11443,7 +11764,12 @@ new short format RetroShare-inbjudan - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Spara som... @@ -11708,14 +12034,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alla - + Reputation Rykte @@ -11725,12 +12051,12 @@ p, li { white-space: pre-wrap; } Sök - + Anonymous Id Anonymt Id - + Create new Identity Skapa ny identitet @@ -11874,7 +12200,7 @@ p, li { white-space: pre-wrap; } Identitets-ID - + Send message Skicka meddelande @@ -11946,7 +12272,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonym @@ -11961,24 +12287,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11993,7 +12319,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12052,13 +12378,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12118,7 +12449,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Editera cirkeln @@ -12166,7 +12497,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12175,12 +12506,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12192,12 +12523,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12313,17 +12644,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12480,8 +12811,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12492,7 +12823,7 @@ These identities will soon be not supported anymore. Din avatar - + Linked to neighbor nodes @@ -12502,7 +12833,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12562,7 +12893,7 @@ These identities will soon be not supported anymore. Ägd av - + Node name: Nodnamn: @@ -12572,7 +12903,7 @@ These identities will soon be not supported anymore. Nod-ID : - + Really delete? @@ -12610,7 +12941,22 @@ These identities will soon be not supported anymore. Pseudonym - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Ny identitet @@ -12627,14 +12973,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity Editera identitet @@ -12645,24 +12991,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12681,17 +13030,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Ett fel uppstod vid hämtning av nyckeln! - + Error KeyID invalid Fel NyckelID felaktigt - + Unknown GpgId Okänt GpgId @@ -12701,7 +13060,7 @@ These identities will soon be not supported anymore. Okänt riktigt namn - + Create New Identity Skapa ny Identitet @@ -12711,7 +13070,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12751,12 +13115,7 @@ These identities will soon be not supported anymore. Din avatar - - Set Avatar - - - - + Linked to your profile @@ -12766,7 +13125,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12875,8 +13234,12 @@ These identities will soon be not supported anymore. + Quote + Citera + + Send - Skicka + Skicka @@ -13034,7 +13397,7 @@ These identities will soon be not supported anymore. - + Options Alternativ @@ -13066,12 +13429,12 @@ These identities will soon be not supported anymore. Snabbstartsguide - + RetroShare %1 a secure decentralized communication platform RetroShare %1 en säker, decentraliserad kommunikationsplattform - + Unfinished Pågående @@ -13204,7 +13567,7 @@ Frigör mer diskutrymme och klicka OK. Visa - + Make sure this link has not been forged to drag you to a malicious website. Tillse att den här länken inte leder till en webbsida med skadlig kod. @@ -13249,7 +13612,7 @@ Frigör mer diskutrymme och klicka OK. Tjänståtkomstmatrix - + Statistics Statistik @@ -13278,7 +13641,7 @@ Frigör mer diskutrymme och klicka OK. MessageComposer - + Compose Skriv @@ -13380,7 +13743,7 @@ Frigör mer diskutrymme och klicka OK. - + Tags Taggar @@ -13475,12 +13838,12 @@ Frigör mer diskutrymme och klicka OK. Lägg till blockcitat - + Send To: Skicka till: - + &Left &Vänster @@ -13510,7 +13873,12 @@ Frigör mer diskutrymme och klicka OK. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hej! Jag rekommenderar mina kontakter. Du kan autentisera dem också, när du autentiserar mig. @@ -13536,12 +13904,12 @@ Frigör mer diskutrymme och klicka OK. - + Save Message Spara meddelande - + Message has not been Sent. Do you want to save message to draft box? Meddelandet har inte skickats. @@ -13553,7 +13921,7 @@ Vill du spara meddelandet i Utkast? Klistra in RetroShare-länk - + Add to "To" Lägg till i "Till" @@ -13808,7 +14176,7 @@ Vill du spara meddelandet? Lägg till fil - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13822,6 +14190,21 @@ Vill du spara meddelandet? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13834,7 +14217,7 @@ Vill du spara meddelandet? Från: - + Bullet list (disc) @@ -13874,13 +14257,13 @@ Vill du spara meddelandet? - - + + Thanks, <br> - + Distant identity: @@ -14019,8 +14402,23 @@ Vill du spara meddelandet? Meddelande - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14032,12 +14430,12 @@ Vill du spara meddelandet? Rekommenderade filer - + Download all Recommended Files Ladda ner alla rekommenderade filer - + Subject: Ämne: @@ -14112,12 +14510,18 @@ Vill du spara meddelandet? - + + Message Size: + + + + File Name Filnamn - + + Size Storlek @@ -14178,18 +14582,33 @@ Vill du spara meddelandet? Ladda ner - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Ladda ner alla - + Print Document Skriv ut dokument @@ -14204,7 +14623,7 @@ Vill du spara meddelandet? HTML-filer (*.htm *.html);;Alla Filer (*) - + Load images always for this message Ladda alltid bilder för detta meddelande @@ -14345,7 +14764,7 @@ Vill du spara meddelandet? MessagesDialog - + New Message Nytt meddelande @@ -14401,14 +14820,14 @@ Vill du spara meddelandet? - + Tags Taggar - + Inbox Inkorg @@ -14503,7 +14922,7 @@ Vill du spara meddelandet? Vidarebefordra meddelande - + Subject Ämne @@ -14615,7 +15034,7 @@ Vill du spara meddelandet? - + Open in a new window Öppna i nytt fönster @@ -14700,7 +15119,7 @@ Vill du spara meddelandet? - + Drafts Utkast @@ -14821,7 +15240,7 @@ Vill du spara meddelandet? Svarsmeddelande - + Delete Message Ta bort meddelande @@ -14832,7 +15251,7 @@ Vill du spara meddelandet? - + Expand Expandera @@ -14842,7 +15261,7 @@ Vill du spara meddelandet? Ta bort objektet - + from Från @@ -14851,6 +15270,11 @@ Vill du spara meddelandet? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15164,7 +15588,7 @@ Reported error: - + Groups Grupper @@ -15194,19 +15618,19 @@ Reported error: importera din vänlista inklusive grupper - - + + Search Sök - + ID ID - + Search ID @@ -15216,7 +15640,7 @@ Reported error: - + Show Items @@ -15415,18 +15839,18 @@ at least one peer was not added to a group - + Error Fel - + File is not writeable! - + File is not readable! @@ -15464,7 +15888,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15482,7 +15906,7 @@ at least one peer was not added to a group Detta är ett test. - + Newest on top @@ -15493,20 +15917,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15543,22 +15982,22 @@ at least one peer was not added to a group - + Test Testa - + Chat Room - + Systray Icon Meddelandefältsikon - + Message Meddelande @@ -15583,12 +16022,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Kontakten anslöt @@ -15635,27 +16069,37 @@ at least one peer was not added to a group Gruppchatt - + + Toaster position + + + + Chat rooms - + Position Placering - + + Activity + + + + X Margin X-marginal - + Y Margin Y-marginal - + Systray message Systemmeddelande @@ -15705,7 +16149,7 @@ at least one peer was not added to a group Underrättelser - + Disable All Toasters @@ -15719,7 +16163,7 @@ at least one peer was not added to a group Flöde - + Systray @@ -15861,17 +16305,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : Namn : @@ -15926,22 +16365,17 @@ at least one peer was not added to a group Förbehållslöst - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15955,7 +16389,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15965,22 +16399,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Signera GPG-nyckel + Signera GPG-nyckel - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16000,7 +16428,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16066,27 +16494,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Fel: Kan inte hämta användaruppgifter. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Angiven nyckelalgoritm stöds inte av RetroShare. (För tillfället stöds endast RSA-nycklar) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16098,7 +16526,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16143,27 +16571,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Signatur misslyckades - - Maybe password is wrong - Lösenordet kanske är fel + + Check the password! + - + Maybe password is wrong + Lösenordet kanske är fel + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16342,8 +16790,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16360,7 +16807,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16503,7 +16950,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Bild - + TextLabel Bildtext @@ -16547,8 +16994,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Kommentarer @@ -16583,6 +17030,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Skriv en kommentar... + + + Album + Album + PhotoItem @@ -16592,12 +17044,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulär - + TextLabel Bildtext - + <!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; } @@ -16693,7 +17145,7 @@ p, li { white-space: pre-wrap; } Visa bild - + PhotoShare Bilddelning @@ -16734,7 +17186,7 @@ före redigering! - + Stop Stopp @@ -16962,12 +17414,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Tillåt alla insticksprogram - + Plugin look-up directories Mappar med insticksprogram @@ -17010,7 +17462,7 @@ fall görs som skydd mot skadligt beteende från felaktigt utformade insticksprogram. - + Plugins Insticksprogram @@ -17380,7 +17832,7 @@ felaktigt utformade insticksprogram. Andra rubriker - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17539,13 +17991,13 @@ felaktigt utformade insticksprogram. Webbplats - - + + Comments Kommentarer - + Copy RetroShare Link Kopiera RetroShare-länk @@ -17555,7 +18007,7 @@ felaktigt utformade insticksprogram. - + Comment Kommentar @@ -17576,12 +18028,12 @@ felaktigt utformade insticksprogram. - + Hide Dölj - + Vote up @@ -17595,7 +18047,7 @@ felaktigt utformade insticksprogram. \/ - + Set as read and remove item Markera som läst och ta bort objektet @@ -17656,7 +18108,7 @@ felaktigt utformade insticksprogram. - + Loading Läser in @@ -17738,13 +18190,7 @@ felaktigt utformade insticksprogram. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17754,60 +18200,50 @@ felaktigt utformade insticksprogram. - - - + + + unknown okänd - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17818,7 +18254,7 @@ felaktigt utformade insticksprogram. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17887,7 +18323,12 @@ felaktigt utformade insticksprogram. - + + Empty + + + + Copy RetroShare Link Kopiera RetroShare-länk @@ -17922,7 +18363,7 @@ felaktigt utformade insticksprogram. - + [No name] @@ -18046,8 +18487,18 @@ felaktigt utformade insticksprogram. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18319,9 +18770,8 @@ och där läsa in den med importfunktionen. PulseAddDialog - Post From: - Inlägg från: + Inlägg från: Account 1 @@ -18336,7 +18786,7 @@ och där läsa in den med importfunktionen. Konto 3 - + Add to Pulse Lägg till i Pulse @@ -18359,17 +18809,32 @@ och där läsa in den med importfunktionen. URL - + GroupLabel - + IDLabel - + + From: + Från: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18394,10 +18859,20 @@ och där läsa in den med importfunktionen. Negativ - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18407,14 +18882,53 @@ och där läsa in den med importfunktionen. - + + Post + + + + Cancel Avbryt - Post Pulse to Wire - Posta Pulse till Wire + Posta Pulse till Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18440,10 +18954,18 @@ och där läsa in den med importfunktionen. Formulär - - - - + + + + + Click to view picture + + + + + + + Image Bild @@ -18451,44 +18973,44 @@ och där läsa in den med importfunktionen. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18498,17 +19020,17 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18518,7 +19040,7 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18526,7 +19048,7 @@ och där läsa in den med importfunktionen. PulseTopLevel - + retweeted @@ -18541,7 +19063,7 @@ och där läsa in den med importfunktionen. - + follow Parent Group @@ -18551,7 +19073,7 @@ och där läsa in den med importfunktionen. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18576,7 +19098,7 @@ och där läsa in den med importfunktionen. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18612,29 +19134,29 @@ och där läsa in den med importfunktionen. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18712,7 +19234,7 @@ och där läsa in den med importfunktionen. QObject - + Confirmation Bekräftelse @@ -18954,7 +19476,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> kommer att ersätt Resultat - + Unable to make path Kunde inte skapa sökväg @@ -18989,7 +19511,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> kommer att ersätt Filbegäran avbruten - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Denna version av RetroShare använder OpenPGP-SDK. Som sidoeffekt använder den inte systemets delade PGP-nyckelring, utan har sin egen nyckelring som delas av alla RetroShare-instanser. <br><br>Du verkar inte ha någon sådan nyckelring, även om GPG-nycklar associeras med befintliga RetroShare-konton, troligen för att du just uppgraderat till denna nya version av programmet. @@ -19130,7 +19652,7 @@ Rapporterat fel är: %2 sek - + TR up @@ -19175,7 +19697,7 @@ Rapporterat fel är: %2 - + Move IP %1 to whitelist @@ -19191,7 +19713,7 @@ Rapporterat fel är: %2 - + %1 seconds ago @@ -19275,7 +19797,7 @@ Security: no anonymous IDs - + Error Fel @@ -19665,11 +20187,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -20039,7 +20556,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20261,18 +20778,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20709,7 +21247,7 @@ p, li { white-space: pre-wrap; } Ladda ner! - + File Fil @@ -20724,7 +21262,7 @@ p, li { white-space: pre-wrap; } Hash-summa - + Bad filenames have been cleaned Dåliga filnamn har rensats @@ -20774,7 +21312,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos Spara - + Collection Editor @@ -20789,7 +21327,7 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos - + Real Size: Waiting child... @@ -20804,12 +21342,12 @@ Tecknen <b>",|,/,\,&lt;,&gt;,*,?</b> ersätts med &apos - + Download files - + Specify... Specificera @@ -21058,7 +21596,7 @@ Om du tror att den är giltig, ta bort strängen från filen och öppna den på RsFriendListModel - + Name Namn @@ -21078,7 +21616,7 @@ Om du tror att den är giltig, ta bort strängen från filen och öppna den på IP - + Profile ID @@ -21091,10 +21629,15 @@ Om du tror att den är giltig, ta bort strängen från filen och öppna den på RsGxsForumModel - + Title + + + UnRead + + Date @@ -21106,7 +21649,7 @@ Om du tror att den är giltig, ta bort strängen från filen och öppna den på - + Information for this identity is currently missing. @@ -21144,7 +21687,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... Meddelande saknas ... ] @@ -21152,7 +21695,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21212,7 +21755,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21571,7 +22114,7 @@ prevents the message to be forwarded to your friends. Filnamn - + Download Ladda ner @@ -21650,7 +22193,7 @@ prevents the message to be forwarded to your friends. Öppna mapp - + Create Collection... Skapa samling... @@ -21670,7 +22213,7 @@ prevents the message to be forwarded to your friends. Ladda ner från samlingsfil... - + Collection Samling @@ -21775,12 +22318,12 @@ prevents the message to be forwarded to your friends. Användarinformation - + Deny friend Avvisa kontakt - + Chat Chatt @@ -21790,7 +22333,7 @@ prevents the message to be forwarded to your friends. Starta chatt - + Expand Expandera @@ -22060,13 +22603,13 @@ bra om du sitter bakom en brandvägg eller en VPN-tunnel. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22532,7 +23075,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Nätverk @@ -22560,7 +23103,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22657,7 +23200,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22692,12 +23235,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23365,7 +23908,7 @@ p, li { white-space: pre-wrap; } PGP-certifikat saknas - + Wrong password @@ -23407,7 +23950,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Lägg till kontakt @@ -23463,7 +24006,7 @@ This choice can be reverted in settings. Tjänståtkomstmatrix - + DHT DHT @@ -24003,7 +24546,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24013,13 +24556,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24028,6 +24570,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24301,35 +24868,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Du har %1 slutförda nedladdningar + You have %1 completed transfers + - You have %1 completed download - Du har %1 slutförd nedladdning + You have %1 completed transfer + - %1 completed downloads - %1 slutförda nedladdningar + %1 completed transfers + - %1 completed download - %1 slutförd nedladdning + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Du har %1 slutförda nedladdningar + + + You have %1 completed download + Du har %1 slutförd nedladdning + + + %1 completed downloads + %1 slutförda nedladdningar + + + %1 completed download + %1 slutförd nedladdning TransfersDialog - + Downloads Nerladdningar @@ -24340,7 +24918,7 @@ p, li { white-space: pre-wrap; } Uppladdningar - + Name i.e: file name Namn @@ -24547,7 +25125,7 @@ p, li { white-space: pre-wrap; } Specificera - + Move in Queue... Flytta i kön... @@ -24641,7 +25219,7 @@ p, li { white-space: pre-wrap; } Ange nytt giltigt filnamn - + Expand all Expandera alla @@ -24773,7 +25351,7 @@ p, li { white-space: pre-wrap; } - + Columns Kolumner @@ -24784,7 +25362,7 @@ p, li { white-space: pre-wrap; } Filöverföringar - + Path Sökväg @@ -24794,7 +25372,7 @@ p, li { white-space: pre-wrap; } Visa Väg-kolumn - + Could not delete preview file @@ -24804,7 +25382,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... Skapa samling... @@ -24819,7 +25397,7 @@ p, li { white-space: pre-wrap; } Visa samling... - + Collection Samling @@ -25061,7 +25639,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Okänd användare @@ -25157,7 +25735,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Du har %1 nya meddelanden @@ -25529,7 +26107,7 @@ p, li { white-space: pre-wrap; } Skapa grupp - + Subscribe to Group Prenumerera på grupp @@ -25623,8 +26201,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Visa redigeringshistorik @@ -25635,7 +26213,7 @@ p, li { white-space: pre-wrap; } - + Preview Förhandsgranskning @@ -25660,12 +26238,12 @@ p, li { white-space: pre-wrap; } Dölj redigeringshistorik - + Edit Page Redigera sida - + Create New Wiki Page Skapa nya Wiki-sida @@ -25685,7 +26263,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Skapa nya Wiki-grupp @@ -25727,7 +26305,7 @@ p, li { white-space: pre-wrap; } Tidsintervall - + Create Account @@ -25737,12 +26315,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Uppdatera @@ -25777,12 +26354,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25852,7 +26429,7 @@ p, li { white-space: pre-wrap; } Visar: - + Yourself Du själv @@ -25890,7 +26467,7 @@ p, li { white-space: pre-wrap; } Posta Pulse till Wire - + RetroShare RetroShare @@ -25902,7 +26479,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -25910,7 +26487,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25991,8 +26568,8 @@ p, li { white-space: pre-wrap; } Formulär - - + + Avatar Profilbild @@ -26021,6 +26598,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26133,7 +26715,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_tr.ts b/retroshare-gui/src/lang/retroshare_tr.ts index 78be8b683..b0d731573 100644 --- a/retroshare-gui/src/lang/retroshare_tr.ts +++ b/retroshare-gui/src/lang/retroshare_tr.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare sürümü @@ -79,7 +79,7 @@ Keyfinize bakın ;-) - + Only Hidden Node Yalnızca Gizli Düğüm @@ -129,12 +129,12 @@ RetroShare: Gelişmiş Arama - + Search Criteria Arama Ölçütü - + Add a further search criterion. Başka bir arama ölçütü ekler. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Albüm @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Form - - + + TextLabel Metin Etiketi @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Araç Çubuğu - + Icon Only Yalnız Simge @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Araç düğmelerinin biçemini seçin. - + Icon Size = 8x8 Simge Boyutu = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Simge Boyutu = 128x128 - + Status Bar Durum Çubuğu @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Sistem Tepsisi İpucu Kullanılmasın - + Main page items: Ana sayfa ögeleri: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Öge listesi - + Icon Size = 32x32 Simge Boyutu = 32x32 @@ -828,14 +828,23 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Avatarı Değiştir - + + TextLabel + Metin Etiketi + + + Your Avatar Picture Avatar Görseliniz - + + Browse... + + + Add Avatar - Avatar Ekle + Avatar Ekle @@ -843,25 +852,34 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Sil - + Set your Avatar picture Avatar görselinizi ayarlayın - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatar Yükle + Avatar Yükle AvatarWidget - - Choose avatar - - - - + Click to change your avatar Avatarınızı değiştirmek için tıklayın @@ -869,7 +887,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim RetroShare Bandwidth Usage RetroShare Bant Genişliği Kullanımı + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Ayarlara Bakın + TextLabel + Metin Etiketi + + + Reset Sıfırlayın - Receive Rate - Alma Hızı + Alma Hızı - Send Rate - Gönderme Hızı + Gönderme Hızı - + Always on Top Her zaman üstte - Style - Biçem + Biçem - + Changes the transparency of the Bandwidth Graph Bant genişliği grafiğinin saydamlığını ayarlar - + 100 100 @@ -936,30 +975,27 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim % Mat - Save - Kaydedin + Kaydedin - Cancel - İptal + İptal - + Since: Başlangıç: - Hide Settings - Ayarlar Gizlensin + Ayarlar Gizlensin BandwidthStatsWidget - + Sum Toplam @@ -981,7 +1017,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Sayı - + Average Ortalama @@ -1115,7 +1151,7 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Metin Etiketi - + Comments Yorumlar @@ -1193,6 +1229,85 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Metin Etiketi + + BoardsCommentsItem + + + I like this + Beğendim + + + + 0 + 0 + + + + I dislike this + Beğenmedim + + + + Toggle Message Read Status + İleti Okundu Durumunu Değiştir + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Genişlet + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ad + + + + Comm value + + + + + Comment + + + + + Comments + Yorumlar + + + + Hide + Gizle + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Unutmayın: Buradaki herhangi bir bilgi, iletişim kurallarını güncellediğim Log scale Günlük Ölçeği + + + Default + + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Beğendim + + + + 0 + 0 + + + + I dislike this + Beğenmedim + + + + Toggle Message Read Status + İleti Okundu Durumunu Değiştir + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Genişlet + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Ad + + + + Comm value + + + + + Comment + + + + + Comments + Yorumlar + + + + Hide + Gizle + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Sohbetler - You have %1 new messages - %1 yeni iletiniz var + %1 yeni iletiniz var + + + You have %1 new message + %1 yeni iletiniz var + + + %1 new messages + %1 yeni ileti + + + %1 new message + %1 yeni ileti + + + + You have %1 mentions + - You have %1 new message - %1 yeni iletiniz var + You have %1 mention + - %1 new messages - %1 yeni ileti + %1 mentions + - %1 new message - %1 yeni ileti + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Tümünü Kaldır - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Odaya katılıp sohbet etmek için çift tıklayın. Çeşit: - Group chat - Grup Sohbeti + Grup Sohbeti - - + Private chat Özel sohbet @@ -2191,17 +2404,16 @@ Odaya katılıp sohbet etmek için çift tıklayın. /me şununla bir ileti gönderiyorum /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Farklı sohbet sistemleri için RetroShare tarafından diskinizde saklanacak sohbet iletisi sayısı ve görüşme geçmişinin ne kadarını görüntüleneceği buradan ayarlanabilir. En fazla saklama süresi, eski iletilerin silinmesini ve sohbet geçmişinin geçici sohbetlerle dolmasını engeller (sohbet odaları ve uzak sohbet gibi).</p></body></html> - Chatlobbies - Sohbet Odaları + Sohbet Odaları - + Enabled: Etkin: @@ -2222,11 +2434,12 @@ Odaya katılıp sohbet etmek için çift tıklayın. + Chat rooms Sohbet odaları - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Denetlendi, sayının arttırılması için kimlik ve yukarıdaki metin aynı olmalıdır. @@ -2287,11 +2500,17 @@ Odaya katılıp sohbet etmek için çift tıklayın. + Broadcast Yayınla - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Kayıtlı iletiler (0 = sınırsız): @@ -2438,8 +2657,23 @@ Odaya katılıp sohbet etmek için çift tıklayın. Özel Sohbet - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Odaya katılıp sohbet etmek için çift tıklayın. - + is typing... yazıyor... @@ -2631,12 +2865,12 @@ after HTML conversion. karakter fazla olacak. - + Choose your font. Yazı türünüzü seçin. - + Do you really want to physically delete the history? Geçmişi tamamen silmek istediğinize emin misiniz? @@ -2708,7 +2942,7 @@ karakter fazla olacak. X nesne bulunduktan sonra renklendirmeye devam edilsin (daha fazla işlemci gücü gerekir) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Önceki </b><br/><i>Ctrl+Shift+G</i> @@ -2748,12 +2982,12 @@ karakter fazla olacak. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Seçili metni işaretleyin</b><br><i>Ctrl+M</i> - + Person id: Kişi kodu: @@ -2770,7 +3004,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. İmzalanmamış - + items found. öge bulundu. @@ -2790,7 +3024,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Buraya iletinizi yazın - + Don't stop to color after Şuradan sonra renklendirme durdurulmasın @@ -2948,12 +3182,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. ConfCertDialog - + Details Ayrıntılar - + Local Address Yerel Adres @@ -2964,12 +3198,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Dış Adres - + Node info: Düğüm bilgisi: - + Current address: Geçerli adres: @@ -2985,31 +3219,36 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Kapı - + Include signatures Imzalar katılsın - + RetroShare RetroShare - + - + Error : cannot get peer details. Hata: eş ayrıntıları alınamıyor. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3025,22 +3264,27 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Şifreleme - + Not connected Bağlı değil - + Retroshare node details RetroShare düğüm bilgileri - + Node name : Düğüm adı : @@ -3075,13 +3319,18 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. Durum iletisi: - + + Connectivity + + + + List of known addresses: Bilinen adreslerin listesi: - - + + Retroshare Certificate RetroShare Sertifikası @@ -3096,7 +3345,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. - + Hidden Address Gizli Adres @@ -3107,11 +3356,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. yok + <p>This certificate contains: - <p>Bu sertifikanın içeriği: + <p>Bu sertifikanın içeriği: - + <li>a <b>node ID</b> and <b>name</b> <li>bir <b>düğüm kodu</b> ve <b>ad</b> @@ -3124,12 +3374,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. bir <b>IP adresi</b> ve <b>kapı</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Yeni arkadaşlar eklemek için bu sertifikayı kullanabilirsiniz. Sertifikayı e-posta ile gönderebilir ya da elden ele verebilirsiniz.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Düğümün <span style=" font-weight:600;">OpenSSL</span> sertifikası kodu. Yukarıdaki <span style=" font-weight:600;">PGP</span> anahtarı tarafından imzalanmıştır. </p></body></html> @@ -3139,7 +3389,7 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. <html><head/><body><p><span style=" font-weight:600;">OpenSSL</span> tarafından kullanılan şifreleme yöntemi. Arkadaş düğümlerle kurulan bağlantı</p><p> her zaman yoğun bir şekilde şifrelenir ve DHE varsa bağlantı </p><p>&quot;mükemmel bir yönlendirme gizliliğine&quot;.</p> sahiptir</body></html> - + with ile @@ -3345,12 +3595,12 @@ Adını yazı alanına eklemek için üstüne çift tıklayın. İstek hakkında ayrıntılar - + Peer details Eş bilgileri - + Name: Ad: @@ -3368,12 +3618,12 @@ resources. Lütfen unutmayın, çok fazla arkadaş eklerseniz, RetroShare aşırı miktarda bant genişliğine, belleğe ve işlemci gücüne gerek duyar. İstediğiniz kadar ekleyebilirsiniz, ama 40 arkadaştan fazlası çok fazla kaynağa gerek duyabilir. - + Location: Konum: - + Options Ayarlar @@ -3410,12 +3660,12 @@ resources. Sertifikayı yapıştırın - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Arkadaşınızın RetroShare sertifikasını bu kutuya yapıştırın. UYARI: bu sertifika arkadaşınızın profil anahtarından farklıdır. Arkadaşınızın profil anahtarını (bir bölümünü bile) buraya yapıştırmayın, çalışmaz.</p></body></html> - + Add friend to group: Gruba arkadaş ekleyin: @@ -3425,7 +3675,7 @@ resources. Arkadaşı doğrulayın (PGP anahtarını imzalayın) - + Please paste below your friend's Retroshare ID @@ -3450,7 +3700,7 @@ resources. - + Add as friend to connect with Bağlantı kurulacak arkadaş olarak ekleyin @@ -3459,7 +3709,7 @@ resources. Arkadaşlık isteğini kabul etmek için Tamam üzerine tıklayın. - + Sorry, some error appeared Maalesef, bir sorun çıktı @@ -3479,32 +3729,32 @@ resources. Arkadaşınızın bilgileri: - + Key validity: Anahtar geçerliliği: - + Profile ID: - + Signers İmzalayanlar - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diğer arkadaşlarınıza bu arkadaşınıza güvendiğinizi gösterirsiniz. Aşağıdaki imzalar, listelenmiş anahtar sahiplerinin geçerli PGP anahtarını özgün olarak tanındığını şifreli olarak ispatlar.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Bu eş zaten arkadaş listenizde. Eklerseniz yalnız IP adresi değişebilir. - + To accept the Friend Request, click the Accept button. @@ -3550,7 +3800,7 @@ resources. - + Certificate Load Failed Sertifika Yüklenemedi @@ -3587,12 +3837,12 @@ resources. Sertifika geçerli görünüyor - + Not a valid Retroshare certificate! Geçerli bir Retroshare sertifikası değil! - + RetroShare Invitation RetroShare Çağrısı @@ -3614,12 +3864,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Bu sizin kendi sertifikanız! Kendi kendinizle arakadaş olmak istemezsiniz. Değil mi? - + @@ -3667,7 +3917,37 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Şu kişi arkadaşlık isteğinde bulundu - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3755,12 +4035,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Olabildiğinde doğrudan kaynak olarak kullanılsın - + IP-Addr: IP Adresi: - + IP-Address IP Adresi @@ -3826,7 +4106,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Anahtarı, anahtarlığa ekle - + This key is already in your keyring Bu anahtar zaten anahtarlığınızda bulunuyor @@ -3887,12 +4167,12 @@ kullanılabilir. <p>Bu sertifikada bir IP adresi yok. IP adresini bulmak için keşif ve DHT özelliğine güvenmelisiniz. Beyaz listeye eklenme zorunlu olsun seçeneğini etkinleştirdiğiniz için Haber Akışı sekmesinde eşle ilgili bir güvenlik uyarısı görüntülenecek. Oraya bakarak eşin IP adresini beyaz listeye alabilirsiniz.</p> - + [Unknown] [Bilinmiyor] - + Added with certificate from %1 Sertifikasıyla birlikte %1 üzerinden eklendi @@ -3979,7 +4259,12 @@ kullanılabilir. UDP Sonucu - + + Status + Durum + + + <!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; } @@ -4409,7 +4694,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4561,7 +4846,7 @@ p, li { white-space: pre-wrap; } Herhangi Bir Çevre Sınırlaması Seçilmemiş - + [Unknown] [Bilinmiyor] @@ -4576,7 +4861,7 @@ p, li { white-space: pre-wrap; } Sil - + Search Arama @@ -4596,7 +4881,7 @@ p, li { white-space: pre-wrap; } Bilinen düğümler tarafından imzalanmış - + Edit Circle Çevreyi Düzenle @@ -4616,12 +4901,12 @@ p, li { white-space: pre-wrap; } İsimsiz Kod - + Circle name Çevre adı - + Update Güncelle @@ -4647,7 +4932,7 @@ p, li { white-space: pre-wrap; } PGP Bağlantılı Kod - + Add Member Üye Ekle @@ -4791,7 +5076,7 @@ p, li { white-space: pre-wrap; } - + Attachments Ek dosyalar @@ -4837,7 +5122,7 @@ p, li { white-space: pre-wrap; } Arama Sonuçlarından Dosyaları Sürükleyip Bırakın - + Paste RetroShare Links RetroShare Bağlantılarını Yapıştır @@ -4847,7 +5132,7 @@ p, li { white-space: pre-wrap; } RetroShare Bağlantısını Yapıştır - + Drop file error. Dosya bırakma hatası. @@ -4874,17 +5159,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Dosya Zaten Eklenmiş ve Karılmış + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Dosya Zaten Eklenmiş ve Karılmış + + + Please add a Subject Lütfen bir konu ekleyin @@ -4915,12 +5224,12 @@ p, li { white-space: pre-wrap; } Gerçekten %1 ileti oluşturmak istiyor musunuz? - + You are about to add files you're not actually sharing. Do you still want this to happen? Gerçekte paylaşmadığınız dosyaları eklemek istediğinize emin misiniz? - + Edit Channel Post Kanal İletisini Düzenle @@ -4940,7 +5249,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Sahibi olmadığınız dosyaları bir kanala göndermek üzeresiniz. @@ -5032,7 +5341,7 @@ p, li { white-space: pre-wrap; } - + No Forum Forum Yok @@ -5492,7 +5801,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz DHTGraphSource - + users kullanıcılar @@ -6499,7 +6808,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz FlatStyle_RDM - + Friends Directories Arkadaş Klasörleri @@ -7005,7 +7314,7 @@ en az bir eş bir gruba eklenemedi Arkadaş Arama - + Mark all Tümünü işaretle @@ -7019,7 +7328,7 @@ en az bir eş bir gruba eklenemedi FriendsDialog - + Edit status message Durum iletisini düzenle @@ -7123,7 +7432,7 @@ en az bir eş bir gruba eklenemedi RetroShare sohbeti yayını: iletiler bağlı olan tüm arkadaşlara gönderilir. - + Network @@ -7188,7 +7497,7 @@ en az bir eş bir gruba eklenemedi Düğüm alanına en az 3 karakter yazmalısınız - + Failed to generate your new certificate, maybe PGP password is wrong! Yeni sertifikanız üretilemedi. PGP parolası yanlış olabilir! @@ -7231,7 +7540,7 @@ en az bir eş bir gruba eklenemedi Varolan profili kullan - + Node name Düğüm adı @@ -7498,12 +7807,12 @@ ve İçe Aktar düğmesini kullanarak yükleyebilirsiniz - + Profile generation failure Profil üretilemedi - + Missing PGP certificate PGP sertifikası eksik @@ -7910,7 +8219,7 @@ p, li { white-space: pre-wrap; } Yöneltici İstatistikleri - + GroupBox Grup Kutusu @@ -7975,7 +8284,7 @@ p, li { white-space: pre-wrap; } Dallanma Çarpanı - + Details Ayrıntılar @@ -7998,7 +8307,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Yönetilen Anahtarlar @@ -8207,7 +8516,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Başlık @@ -8217,13 +8526,30 @@ p, li { white-space: pre-wrap; } Başlık Arama - - + + + + Description Açıklama - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Açıklama Arama @@ -8233,42 +8559,35 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - Azalan Düzende Sırala + Azalan Düzende Sırala - Sort Ascending Order - Artan Düzende Sırala + Artan Düzende Sırala - Sort by Name - Ada Göre Sırala + Ada Göre Sırala - Sort by Popularity - Beğeniye Göre Sırala + Beğeniye Göre Sırala - Sort by Last Post - Son İletiye Göre Sırala + Son İletiye Göre Sırala - Sort by Number of Posts - İleti Sayısına Göre Sırala + İleti Sayısına Göre Sırala - Sort by Unread - Okunmamışlara Göre Sırala + Okunmamışlara Göre Sırala - + You are admin (modify names and description using Edit menu) Yöneticisiniz (Düzenle menüsünden ad ve açıklamaları değiştirebilirsiniz) @@ -8283,40 +8602,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post Son İleti - + + Name Ad - - Unread - - - - + Popularity - - + + Never Hiç - Display - Görünüm + Görünüm - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8465,7 +8779,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanallar @@ -8490,12 +8804,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kanallar</h1> <p>Kanallar ağa yaymak istediğiniz verileri (film, müzik gibi) göndermenizi sağlar.</p> <p>Arkadaşlarınızın abone olduğu kanalları görebilirsiniz. Abone olduğunuz kanallar da otomatik olarak arkadaşlarınıza iletilir. Böylece ağdaki iyi kanallar öne çıkar.</p> <p>Bir kanala yalnız kanalı oluşturan kişi veri gönderebilir. Kanal özel bir kanal değilse ağdaki diğer eşler bu verileri yalnızca okuyabilir. Bununla birlikte veri gönderme ya da okuma izinlerini arkadaşınız oluan RetroShare düğümleri ile paylaşabilirsiniz.</p> <p>Kanallar isimsiz olabileceği gibi bir RetroShare kimliğiyle ilişkilendirilebilir. Böylece okuyucular gerek duyduğunda sizinle iletişim kurabilir. Gönderdiğiniz verilere kullanıcıların yorum yapmasını istiyorsanız "Yorumlar Kullanılsın" seçeneğini etkinleştirin.</p> <p>Bu değeri değiştirmediyseniz, kanala gönderilen veriler %1 gün tutulur ve son %2 gündeki veriler eşitlenir.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Abone Olunan Kanallar @@ -9020,7 +9334,7 @@ p, li { white-space: pre-wrap; } - + Add new post Yeni ileti oluştur @@ -9120,12 +9434,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments Yorumlar @@ -9136,18 +9450,18 @@ p, li { white-space: pre-wrap; } - + Feeds Akış - - + + Click to switch to list view - + Show unread posts only @@ -9157,12 +9471,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9222,7 +9536,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9237,12 +9551,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9318,23 +9632,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe Abone Ol - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Bir Kanal Seçilmemiş @@ -9356,11 +9683,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanal İletisi - - - new message(s) - - GxsCircleItem @@ -9894,7 +10216,7 @@ bir kimlik oluşturmalısınız Seçilmiş Foruma Yeni Konu Ekle - + Search forums Forum Arama @@ -9903,12 +10225,12 @@ bir kimlik oluşturmalısınız Son İleti - + New Thread Yeni Konu - + Threaded View İç İçe Görünüm @@ -9918,19 +10240,19 @@ bir kimlik oluşturmalısınız Düz Görünüm - - + + Title Başlık - - + + Date Tarih - + Author Yazar @@ -9945,7 +10267,17 @@ bir kimlik oluşturmalısınız Yükleniyor - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10006,23 +10338,23 @@ bir kimlik oluşturmalısınız <p>Foruma abone olduğunuzda diğer abone olan arkadaşlarınızın gönderilerini alabilir ve forumu tüm diğer arkadaşlarınıza görünür kılabilirsiniz..</p><p>İstediğinizde soldaki forum listesine sağ tıklayarak abonelikten ayrılabilirsiniz.</p> - + No name Adsız - - + + Reply Yanıtla - + <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> - + Loading... @@ -10060,12 +10392,12 @@ bir kimlik oluşturmalısınız Okunmamış Olarak İşaretle - + Copy RetroShare Link RetroShare Bağlantısını Kopyala - + Hide Gizle @@ -10078,7 +10410,7 @@ bir kimlik oluşturmalısınız [Engellenmiş] - + [unknown] [bilinmiyor] @@ -10108,8 +10440,8 @@ bir kimlik oluşturmalısınız Yalnız sizin gözlerinize - - + + Distribution Dağıtım @@ -10212,7 +10544,7 @@ bir kimlik oluşturmalısınız Özgün İleti - + New thread Yeni konu @@ -10221,7 +10553,7 @@ bir kimlik oluşturmalısınız Okunma durumu - + Edit Düzenle @@ -10277,7 +10609,7 @@ bir kimlik oluşturmalısınız Kişiler sekmesinde yazar görüntülensin - + Author's reputation Yazarın değerlendirmesi @@ -10297,7 +10629,7 @@ bir kimlik oluşturmalısınız - + <b>Loading...<b> @@ -10337,6 +10669,11 @@ bir kimlik oluşturmalısınız Storage Depolama + + + Last seen at friends: + + Moderators @@ -10430,7 +10767,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: %1 zamanında, %2 kullanıcısının iletisi: - + Forum name Forum adı @@ -10462,11 +10799,6 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Forum Post Forum İletisi - - - new message(s) - - GxsForumsDialog @@ -10915,7 +11247,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Baskı Önizleme - + Unsubscribe Abonelikten Ayrıl @@ -10930,7 +11262,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Yeni sekmede açılsın - + Remove this search @@ -10940,12 +11272,12 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: - + Request data - + Show Details Ayrıntılara Bakın @@ -11012,7 +11344,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: - + Search for @@ -11021,7 +11353,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Yayınlama izinlerini paylaş - + Copy RetroShare Link RetroShare Bağlantısını Kopyala @@ -11036,7 +11368,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Tümünü okunmamış olarak işaretle - + AUTHD Doğrulanmış @@ -11653,7 +11985,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11662,7 +11994,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11688,6 +12020,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11699,7 +12048,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <span style=" font-size:8pt; font-weight:600;"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <span style=" font-size:8pt; font-weight:600;"><!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;"> @@ -11779,27 +12128,32 @@ p, li { white-space: pre-wrap; } Form - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11821,6 +12175,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11829,7 +12184,7 @@ p, li { white-space: pre-wrap; } Aşağıdaki metin sizin RetroShare sertifikanızdır. Bu metni arkadaşlarınıza gönderin - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11845,12 +12200,12 @@ merkezi olmayan kişisel ve güvenli bir iletişim platformu. RetroShare hakkında yardıma ihtiyacınız var mı? - + Open Web Help Web Yardımını Aç - + Copy your Cert to Clipboard Sertifikanızı Panoya Kopyalayın @@ -11899,7 +12254,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11908,7 +12263,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12201,14 +12556,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tümü - + Reputation Değerlendirme @@ -12218,12 +12573,12 @@ p, li { white-space: pre-wrap; } Arama - + Anonymous Id İsimsiz Kod - + Create new Identity Yeni kimlik ekle @@ -12367,7 +12722,7 @@ p, li { white-space: pre-wrap; } Kimlik Kodu - + Send message İleti Gönder @@ -12458,7 +12813,7 @@ p, li { white-space: pre-wrap; } Genel Değerlendirme: - + Anonymous İsimsiz @@ -12473,24 +12828,24 @@ p, li { white-space: pre-wrap; } Kod Arama - + This identity is owned by you Bu kimlik size ait - - + + My own identities Kendi kimliklerim - - + + My contacts Kişilerim - + Show Items Ögeleri Görüntüle @@ -12505,7 +12860,7 @@ p, li { white-space: pre-wrap; } Düğümümle bağlantılı - + Other circles Diğer çevreler @@ -12564,13 +12919,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). abone (diğer kişiler ve çağrı listesinden üyelik isteklerini alıp iletebilir). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). abone değil (yalnız çağrı listesini alabilir). - + Your status: Durumunuz: @@ -12630,7 +12990,7 @@ p, li { white-space: pre-wrap; } Üye - + Edit Circle Çevreyi Düzenle @@ -12678,7 +13038,7 @@ p, li { white-space: pre-wrap; } Üyeliği onayla - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12690,12 +13050,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + [Unknown node] [Düğüm bilinmiyor] - + Unverified signature from node Düğümden doğrulanmamış imza alındı @@ -12707,12 +13067,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Denetlenmemiş imza - + [unverified] [doğrulanmamış] - + Identity owned by you, linked to your Retroshare node RetroShare düğümünüze bağlı size ait kimlik @@ -12836,12 +13196,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Sertifikanız ile bir çağrı göndermek istediğinize emin misiniz? - + Banned Engellenmiş - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Kimlikler</h1> <p>Bu sekmeden <b>sahte isimsiz kimlikler</b> ve <b>çevreler</b> oluşturup düzenleyebilirsiniz. </p> <p><b>Kimlikler</b> verilerinizin güvenli olarak tanınmasını sağlamak için forum ve kanal iletilerini imzalamakta ve RetroShare iç e-posta sistemini kullanarak geri bildirimleri almak, kanal iletilerinden sonra yorum yapmak gibi işlemler için kullanılır</p> <p> Kimlikler isteğe bağlı olarak RetroShare düğümünüzün sertifikası ile <b>imzalanabilir</b>. İmzalanmış kimliklere güvenilmesi daha kolaydır ancak bunlar düğümünüzün IP adresinin kolayca belirlenmesini sağlar.</p> <p><b>İsimsiz kimlikler</b> diğer kullanıcılar ile kimliğinizi gizli tutarak etkileşimde bulunmanızı sağlar. Kandırılamazlar ancak hiç kimse verilen bir kimliğin gerçek sahibini ispatlayamaz.</p> <p><b>Çevreler</b> ağ üzerinde bir alanı paylaşan bir kimlik grubudur (isimsiz ya da imzalanmış). Çevreler forum ve kanal gibi ögelerin görüntülenmesini kısıtlamak için kullanılır. </p> <p>Bir <b>çevre</b> başka bir çevre tarafından ya da yalnız kendi üyeleri tarafından görülebilecek şekilde kendi içinde kısıtlanabilir.</p> @@ -12850,7 +13210,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Kod Bilinmiyor : - + positive olumlu @@ -13035,8 +13395,8 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - - + + People Kişiler @@ -13047,7 +13407,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Avatarınız - + Linked to neighbor nodes Komşu düğümlerle bağlantılı @@ -13057,7 +13417,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Uzak düğümlerle bağlantılı - + Linked to a friend Retroshare node Bir arkadaşın RetroShare düğümüyle bağlantılı @@ -13117,7 +13477,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Sahibi - + Node name: Düğüm adı: @@ -13127,7 +13487,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Düğüm Kodu: - + Really delete? Gerçekten silinsin mi? @@ -13165,7 +13525,22 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Takma Ad - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Yeni kimlik @@ -13182,14 +13557,14 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + N/A Kullanılamıyor - + Edit identity Kimliği düzenle @@ -13200,24 +13575,27 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Güncelle - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13236,17 +13614,27 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Anahtar alınamadı! - + Error KeyID invalid Anahtar kodu geçersiz - + Unknown GpgId GpgKodu bilinmiyor @@ -13256,7 +13644,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Gerçek ad bilinmiyor - + Create New Identity Yeni Kimlik Oluştur @@ -13266,7 +13654,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Tür - + + Choose image... + + + + @@ -13306,12 +13699,11 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Avatarınız - Set Avatar - Avatarı Ayarla + Avatarı Ayarla - + Linked to your profile Profilinizle bağlantılı @@ -13321,7 +13713,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Bir ya da bir kaç kimliğiniz olabilir. Kimlikler sohbet odalarında, forumlarda ve kanal yorumlarında yazışırken kullanılır. Uzak sohbet ve RetroShare uzak posta sistemi için hedef olarak kullanılırlar. - + The nickname is too short. Please input at least %1 characters. Takma ad çok kısa. Lütfen en az %1 karakter yazın. @@ -13430,8 +13822,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. + Quote + + + Send - Gönder + Gönder @@ -13589,7 +13985,7 @@ Bu kimliklere yakın zamanda destek verilmeyecek. - + Options Ayarlar @@ -13621,12 +14017,12 @@ Bu kimliklere yakın zamanda destek verilmeyecek. Hızlı Başlangıç Yardımcısı - + RetroShare %1 a secure decentralized communication platform RetroShare %1 merkezi olmayan güvenli bir iletişim platformudur - + Unfinished Tamamlanmamış @@ -13759,7 +14155,7 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın.Görüntüle - + Make sure this link has not been forged to drag you to a malicious website. Bu bağlantının sizi zararlı yazılım bulunduran bir web sitesine yönlendirmediğinden emin olun. @@ -13804,7 +14200,7 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın.Hizmet izinleri matrisi - + Statistics İstatistikler @@ -13833,7 +14229,7 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın.MessageComposer - + Compose Yeni İleti @@ -13935,7 +14331,7 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın. - + Tags Etiketler @@ -14030,12 +14426,12 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın.Blok Alıntısı Ekle - + Send To: Kime: - + &Left So&la @@ -14069,7 +14465,7 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın.Kişilerim - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Merhaba, <br>İyi bir arkadaşımı öneriyorum; bana güveniyorsan ona da güvenebilirsin. <br> @@ -14095,12 +14491,12 @@ Lütfen biraz boş disk alanı açıp Tamam düğmesine tıklayın. - + Save Message İletiyi Kaydet - + Message has not been Sent. Do you want to save message to draft box? İleti gönderilemedi @@ -14112,7 +14508,7 @@ Do you want to save message to draft box? RetroShare Bağlantısını Yapıştır - + Add to "To" "Kime" alanına ekle @@ -14367,7 +14763,7 @@ Do you want to save message ? Başka Dosya Ekleyin - + Hi,<br>I want to be friends with you on RetroShare.<br> Merhaba,<br>RetroShare üzerinde sizinle arkadaş olmak istiyorum.<br> @@ -14376,12 +14772,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Bir arkadaşlık isteğiniz var - + Respond now: Şimdi yanıtlayın: @@ -14397,11 +14808,12 @@ Do you want to save message ? Kimden: + Friend Nodes - Arkadaş Düğümleri + Arkadaş Düğümleri - + Bullet list (disc) İmli liste (disk) @@ -14441,13 +14853,13 @@ Do you want to save message ? Sıralı liste (büyük romen) - - + + Thanks, <br> Teşekkürler, <br> - + Distant identity: Uzak kimlik: @@ -14586,8 +14998,23 @@ Do you want to save message ? İleti - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14599,12 +15026,12 @@ Do you want to save message ? Önerilen Dosyalar - + Download all Recommended Files Önerilen Tüm Dosyaları İndir - + Subject: Konu: @@ -14679,12 +15106,18 @@ Do you want to save message ? Çağrı Gönder - + + Message Size: + + + + File Name Dosya Adı - + + Size Boyut @@ -14745,10 +15178,25 @@ Do you want to save message ? Indir - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Çağrı Gönder @@ -14759,12 +15207,12 @@ Do you want to save message ? - + Download all Tümünü indir - + Print Document Belgeyi Yazdır @@ -14779,7 +15227,7 @@ Do you want to save message ? HTML Dosyaları (*.htm *.html);;Tüm Dosyalar (*) - + Load images always for this message Bu iletideki görseller her zaman yüklensin @@ -14920,7 +15368,7 @@ Do you want to save message ? MessagesDialog - + New Message Yeni İleti @@ -14976,14 +15424,14 @@ Do you want to save message ? - + Tags Etiketler - + Inbox Gelen @@ -15078,7 +15526,7 @@ Do you want to save message ? İletiyi İlet - + Subject Konu @@ -15190,7 +15638,7 @@ Do you want to save message ? - + Open in a new window Yeni pencerede açılsın @@ -15275,7 +15723,7 @@ Do you want to save message ? - + Drafts Taslaklar @@ -15404,7 +15852,7 @@ Do you want to save message ? İletiyi Yanıtla - + Delete Message İletiyi Sil @@ -15415,7 +15863,7 @@ Do you want to save message ? - + Expand Genişlet @@ -15425,7 +15873,7 @@ Do you want to save message ? Ögeyi Sil - + from kimden @@ -15434,6 +15882,11 @@ Do you want to save message ? Reply to invite Çağrıyı Yanıtla + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15758,7 +16211,7 @@ Bildirilen hata: - + Groups Gruplar @@ -15788,19 +16241,19 @@ Bildirilen hata: arkadaş listenizi gruplarla birlikte içe aktarın - - + + Search Arama - + ID Kod - + Search ID @@ -15810,7 +16263,7 @@ Bildirilen hata: - + Show Items Ögeleri Görüntüle @@ -16014,19 +16467,19 @@ en az bir eş bir gruba eklenemedi - + Error Hata - + File is not writeable! Dosya yazılabilir değil! - + File is not readable! Dosya okunabilir değil! @@ -16064,9 +16517,13 @@ en az bir eş bir gruba eklenemedi NewsFeed - Log entries - Günlük kayıtları + Günlük kayıtları + + + + Activity Stream + @@ -16083,7 +16540,7 @@ en az bir eş bir gruba eklenemedi Bu bir denemedir. - + Newest on top Yeniden eskiye @@ -16094,20 +16551,43 @@ en az bir eş bir gruba eklenemedi + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Haber Akışı</h1> <p>Haber Akışı ağınızdaki son gelişmeleri aldığınız tarihe göre sıralayarak görüntüler. Bu özellik arkadaşlarınızın yaptığı işlemlerin bir özetini verir. Hangi işlemlerin görüntüleneceğini seçmek için <b>Ayarlar</b> üzerine tıklayabilirsiniz. </p> <p>Seçenekler şunlardır: <ul> <li>Bağlanma girişimleri (yeni kişiler ile arkadaş olmak ve size ulaşmaya çalışanları görmek için)</li> <li>Kanal ve Forum iletileri</li> <li>Abone olabileceğiniz yeni kanal ve forumlar</li> <li>Arkadaşlarınızdan gelen özel iletiler</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Haber Akışı</h1> <p>Haber Akışı ağınızdaki son gelişmeleri aldığınız tarihe göre sıralayarak görüntüler. Bu özellik arkadaşlarınızın yaptığı işlemlerin bir özetini verir. Hangi işlemlerin görüntüleneceğini seçmek için <b>Ayarlar</b> üzerine tıklayabilirsiniz. </p> <p>Seçenekler şunlardır: <ul> <li>Bağlanma girişimleri (yeni kişiler ile arkadaş olmak ve size ulaşmaya çalışanları görmek için)</li> <li>Kanal ve Forum iletileri</li> <li>Abone olabileceğiniz yeni kanal ve forumlar</li> <li>Arkadaşlarınızdan gelen özel iletiler</li> </ul> </p> + + + Log + Haber - Log - Haber + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16144,22 +16624,22 @@ en az bir eş bir gruba eklenemedi - + Test Deneme - + Chat Room Sohbet Odası - + Systray Icon Sistem Tepsisi Simgesi - + Message İleti @@ -16184,12 +16664,11 @@ en az bir eş bir gruba eklenemedi IP güvenliği - Log - Haber + Haber - + Friend Connected Arkadaş Bağlandı @@ -16203,7 +16682,12 @@ en az bir eş bir gruba eklenemedi Bağlantılar - + + Activity + + + + Mails Postalar @@ -16240,7 +16724,12 @@ en az bir eş bir gruba eklenemedi Grup Sohbeti - + + Toaster position + + + + Chat rooms Sohbet odaları @@ -16265,22 +16754,22 @@ en az bir eş bir gruba eklenemedi Büyük küçük harfe duyarlı - + Position Konum - + X Margin X Kenar Boşluğu - + Y Margin Y Kenar Boşluğu - + Systray message Sistem Tepsisi İletisi @@ -16330,7 +16819,7 @@ en az bir eş bir gruba eklenemedi Bildir - + Disable All Toasters Tüm Bildirimleri Devre Dışı Bırak @@ -16344,7 +16833,7 @@ en az bir eş bir gruba eklenemedi Akış - + Systray Sistem Tepsisi @@ -16490,17 +16979,16 @@ Düşük Trafik: %10 standart trafik ve YAPILACAK: tüm dosya aktarımları dura PGPKeyDialog - Dialog - Pencere + Pencere - + Profile info Profil bilgileri - + Name : Ad : @@ -16555,22 +17043,21 @@ Düşük Trafik: %10 standart trafik ve YAPILACAK: tüm dosya aktarımları dura Çok Fazla - + This profile has signed your own profile key Bu profil kendi profil anahtarınız ile imzalanmış - Key signatures : - Anahtar imzaları : + Anahtar imzaları : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diğer arkadaşlarınıza bu arkadaşınıza güvendiğinizi gösterirsiniz. Aşağıdaki imzalar, listelenmiş anahtar sahiplerinin geçerli PGP anahtarını özgün olarak tanındığını şifreli olarak ispatlar.</span></p></body></html> - + <!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; } @@ -16588,7 +17075,7 @@ p, li { white-space: pre-wrap; } Bu anahtarı imzala - + PGP key PGP anahtarı @@ -16598,22 +17085,20 @@ p, li { white-space: pre-wrap; } Bu seçenekler profildeki tüm düğümlere uygulanır: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diğer arkadaşlarınıza bu arkadaşınıza güvendiğinizi gösterirsiniz. Böylece arkadaşlarınız bu anahtara güvenme durumunuza göre bağlantıları onaylamaya karar verebilir. Anahtar imzalama işlemi isteğe bağlıdır ancak geri alınamaz. Bu nedenle ne yaptığınızdan emin olun.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Bir arkadaşınızın anahtarını imzaladığınızda, diğer arkadaşlarınıza bu arkadaşınıza güvendiğinizi gösterirsiniz. Böylece arkadaşlarınız bu anahtara güvenme durumunuza göre bağlantıları onaylamaya karar verebilir. Anahtar imzalama işlemi isteğe bağlıdır ancak geri alınamaz. Bu nedenle ne yaptığınızdan emin olun.</span></p></body></html> - + Keysigning: - Sign PGP key - PGP anahtarını imzala + PGP anahtarını imzala - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Bu anahtar ile kimliği doğrulanmış bağlantıları reddetmek için buraya tıklayın.</p></body></html> @@ -16633,7 +17118,7 @@ p, li { white-space: pre-wrap; } Bağlantıları onayla - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. Aşağıda düğümün ASCII biçimindeki PGP anahtarını görebilirsiniz. Bu bilgi aynı profildeki tüm düğümleri belirler. Arkadaş olmak için değiş tokuş edeceğiniz bir "RetroShare Sertifikası" her düğüm için "Ayrıntılar" bölümünde bulunabilir. @@ -16703,28 +17188,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Hata: eş ayrıntıları alınamadı. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Verilen anahtar algoritmasi RetroShare tarafından desteklenmiyor (Şu anda yalnız RSA anahtarları destekleniyor) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16738,7 +17223,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Güvenilirlik düzeyi bu anahtara güveninizi göstermenin bir yoludur. Yazılım tarafından kullanılmaz ya da paylaşılmaz ancak iyi ve kötü anahtarları anımsamanıza yardımcı olur. @@ -16783,27 +17268,47 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Bu anahtar ile imzalanmış RetroShare düğümlerinden gelen bağlantıları reddetmeyi seçtiniz. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure İmza Sorunu - - Maybe password is wrong - Parola yanlış olabilir + + Check the password! + - + Maybe password is wrong + Parola yanlış olabilir + + + You haven't set a trust level for this key. Bu anahtar için bir güvenilirlik düzeyi ayarlamamışsınız. - + + Retroshare profile RetroShare profili - + This is your own PGP key, and it is signed by : Bu sizin kendi PGP anahtarınız ve imzalayan : @@ -16982,8 +17487,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. PeopleDialog - - + People Kişiler @@ -17000,7 +17504,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. İç - + Chat with this person Bu kişiyle sohbet et @@ -17151,7 +17655,7 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Fotoğraf - + TextLabel Metin Etiketi @@ -17195,8 +17699,8 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. - <N> Comments >> - + Comments + Yorumlar @@ -17231,6 +17735,11 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Write a comment... Yorum yaz... + + + Album + Albüm + PhotoItem @@ -17240,12 +17749,12 @@ Uyarı: Dosya-Aktarımı ayarlarınızda, doğrudan indirmeye İzin verilmemiş. Form - + TextLabel Metin Etiketi - + <!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; } @@ -17341,7 +17850,7 @@ p, li { white-space: pre-wrap; } Fotoğrafı Görüntüle - + PhotoShare PhotoShare @@ -17382,7 +17891,7 @@ lütfen bir albüm seçin! - + Stop Durdur @@ -17610,12 +18119,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Tüm uygulama eklerini doğrula - + Plugin look-up directories Uygulama eklerinin aranacağı klasörler @@ -17674,7 +18183,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;Uygulama&nbsp;Ekleri</h1> <p>Uygulama ekleri aşağıdaki listedeki klasörlerden yüklenir.</p> <p>Güvenlik nedeniyle onaylanmış uygulama ekleri temel RetroShare çalıştırılabilir dosyası ya da uygulama eki kitaplıkları değişene kadar otomatik olarak yüklenir. Bu durumda kullanıcı uygulama eklerini yeniden onaylamalıdır. Bir uygulama ekini el ile etkinleştirmek için "Etkinleştir" düğmesine tıklayıp RetroShare yazılımını yeniden başlatın.</p><p>Kendi uygulama eklerinizi geliştirmek isterseniz, geliştirici ekibiyle görüşebilirsiniz. Size seve seve yardımcı olurlar!</p> - + Plugins Uygulama Ekleri @@ -18072,7 +18581,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Bağlantılar - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18243,13 +18752,13 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Site - - + + Comments Yorumlar - + Copy RetroShare Link @@ -18259,7 +18768,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Kişiler sekmesinde yazar görüntülensin - + Comment Yorum yapın @@ -18280,12 +18789,12 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + Hide Gizle - + Vote up Beğendim @@ -18299,7 +18808,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. \/ - + Set as read and remove item Okunmuş olarak işaretle ve ögeyi sil @@ -18360,7 +18869,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Metin Etiketi - + Loading Yükleniyor @@ -18450,13 +18959,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18466,60 +18969,50 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. Yönetici: - - - + + + unknown - + Distribution: Dağıtım: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Metin Etiketi - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts İletiler @@ -18530,7 +19023,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18599,7 +19092,12 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + + Empty + + + + Copy RetroShare Link @@ -18634,7 +19132,7 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - + [No name] @@ -18762,8 +19260,18 @@ uygulama eklerinde bulunabilecek zararlı yazılımlardan korur. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19035,9 +19543,8 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseAddDialog - Post From: - Şu Hesapla Gönderilsin: + Şu Hesapla Gönderilsin: Account 1 @@ -19052,7 +19559,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz 3. Hesap - + Add to Pulse Pulse üzerine ekle @@ -19075,17 +19582,32 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Adres - + GroupLabel - + IDLabel - + + From: + Kimden: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19110,10 +19632,20 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Olumsuz - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19123,14 +19655,53 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + + Post + + + + Cancel İptal - Post Pulse to Wire - Pulse Wire Üzerine Gönder + Pulse Wire Üzerine Gönder + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19156,10 +19727,18 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz Form - - - - + + + + + Click to view picture + + + + + + + Image Görsel @@ -19167,44 +19746,44 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19214,17 +19793,17 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19234,7 +19813,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19242,7 +19821,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz PulseTopLevel - + retweeted @@ -19257,7 +19836,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + follow Parent Group @@ -19267,7 +19846,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19292,7 +19871,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19328,29 +19907,29 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19428,7 +20007,7 @@ Kimliği İçe Aktar düğmesine tıklayarak yükleyebilirsiniz QObject - + Confirmation Onaylama @@ -19670,7 +20249,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Sonuç - + Unable to make path Yol oluşturulamadı @@ -19705,7 +20284,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Dosya isteği iptal edildi - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Bu RetroShare sürümü OpenPGP-SDK kullanır. Bu nedenle sistem paylaşımlı PGP anahtarlığını kullanamaz, ama çalışan tüm RetroShare kopyaları ile paylaşılan kendi anahtarlığı bulunur.<br><br>Büyük olasılıkla uygulamanın yeni sürümüne henüz geçtiğiniz için, var olan RetroShare hesaplarında PGP anahtarlarının olduğu anılmasına rağmen, böyle bir anahtarlığınız yok gibi görünüyor. @@ -19849,7 +20428,7 @@ Bildirilen hata: saniye - + TR up AK yük @@ -19894,7 +20473,7 @@ Bildirilen hata: devre dışı - + Move IP %1 to whitelist %1 IP adresini beyaz listeye taşı @@ -19910,7 +20489,7 @@ Bildirilen hata: - + %1 seconds ago %1 saniye önce @@ -19995,7 +20574,7 @@ Güvenlik: İsimsiz kodlar kullanılamaz - + Error Hata @@ -20386,9 +20965,8 @@ Güvenlik: İsimsiz kodlar kullanılamaz - <p>This certificate contains: - <p>Bu sertifikanın içeriği: + <p>Bu sertifikanın içeriği: @@ -20762,7 +21340,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20984,19 +21562,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Ağaç Görünümü Ayarları - Show column... - Görüntülenecek sütun... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Azalan Düzende Sırala + + + + Sort Ascending Order + Artan Düzende Sırala + + + + + [no title] + + + + + Show column … + + + + Show column... + Görüntülenecek sütun... - [no title] - [başlık yok] + [başlık yok] @@ -21432,7 +22039,7 @@ p, li { white-space: pre-wrap; } İndir! - + File Dosya @@ -21447,7 +22054,7 @@ p, li { white-space: pre-wrap; } Karma - + Bad filenames have been cleaned Kötü dosya adları temizlendi @@ -21497,7 +22104,7 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Kaydet - + Collection Editor Derleme Düzenleyici @@ -21512,7 +22119,7 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Dosya Sayısı - + Real Size: Waiting child... Gerçek Boyut: Alt öge bekleniyor... @@ -21527,12 +22134,12 @@ Sorunlu dosyalar kırmızı renkte görüntülenir. Bu bir klasör. Genişletmek için çift tıklayın. - + Download files - + Specify... Belirtin... @@ -21781,7 +22388,7 @@ Dosyanın doğru olduğunu düşünüyorsanız bu satırı silerek dosyayı Retr RsFriendListModel - + Name Ad @@ -21801,7 +22408,7 @@ Dosyanın doğru olduğunu düşünüyorsanız bu satırı silerek dosyayı Retr IP Adresi - + Profile ID @@ -21814,10 +22421,15 @@ Dosyanın doğru olduğunu düşünüyorsanız bu satırı silerek dosyayı Retr RsGxsForumModel - + Title Başlık + + + UnRead + + Date @@ -21829,7 +22441,7 @@ Dosyanın doğru olduğunu düşünüyorsanız bu satırı silerek dosyayı Retr Yazar - + Information for this identity is currently missing. Bu kimlikle ilgili bilgiler şu anda eksik. @@ -21870,7 +22482,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: [Bilinmiyor] - + [ ... Missing Message ... ] [... İleti Eksik ... ] @@ -21878,7 +22490,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: RsMessageModel - + Date Tarih @@ -21938,7 +22550,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: - + [Notification] @@ -22297,7 +22909,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Dosya Adı - + Download Indir @@ -22376,7 +22988,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Klasör Aç - + Create Collection... Derleme Oluştur... @@ -22396,7 +23008,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Derleme dosyasından indir... - + Collection Derleme @@ -22501,12 +23113,12 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Eş ayrıntıları - + Deny friend Arkadaşlık isteğini reddet - + Chat Sohbet @@ -22516,7 +23128,7 @@ arkadaşlarınız da olumlu olarak değerlendirmemiş: Sohbet Başlat - + Expand Genişlet @@ -22787,13 +23399,13 @@ yardımcı olur. Keşif Açık (Önerilir) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Keşif Kapalı @@ -23261,7 +23873,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -23289,7 +23901,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Durum @@ -23386,7 +23998,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Hizmet Adresi @@ -23421,12 +24033,12 @@ If you have issues connecting over Tor check the Tor logs too. Lütfen bir hizmet adresi yazın - + IP Range IP Aralığı - + Reported by DHT for IP masquerading DHT tarafından IP maskelemesi için bildirildi @@ -24094,7 +24706,7 @@ p, li { white-space: pre-wrap; } PGP Sertifikası Eksik - + Wrong password @@ -24148,7 +24760,7 @@ Bu seçim ayarlardan değiştirilebilir. StatisticsWindow - + Add Friend Arkadaş Ekle @@ -24204,7 +24816,7 @@ Bu seçim ayarlardan değiştirilebilir. Hizmet izinleri matrisi - + DHT DHT @@ -24744,7 +25356,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -24754,13 +25366,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24769,6 +25380,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25062,35 +25698,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - %1 dosya indirildi + You have %1 completed transfers + - You have %1 completed download - %1 dosya indirildi + You have %1 completed transfer + - %1 completed downloads - %1 dosya indirildi + %1 completed transfers + - %1 completed download - %1 dosya indirildi + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + %1 dosya indirildi + + + You have %1 completed download + %1 dosya indirildi + + + %1 completed downloads + %1 dosya indirildi + + + %1 completed download + %1 dosya indirildi TransfersDialog - + Downloads İndirmeler @@ -25101,7 +25748,7 @@ p, li { white-space: pre-wrap; } Yüklemeler - + Name i.e: file name Ad @@ -25312,7 +25959,7 @@ p, li { white-space: pre-wrap; } <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Dosya Aktarımı</h1> <p>RetroShare iki şekilde dosya aktarımı sunar: Arkadaşlarınızdan doğrudan aktarım ve uzak isimsiz tünel aktarımı. Ek olarak, dosya aktarımı birden çok kaynak kullanabilir ve karşılıklıdır (indirme yapılırken yükleme de yapılır)</p> <p>Sol yan çubuktaki <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> simgesini kullanarak dosyaları paylaşabilirsiniz. Paylaşılan dosyalar Dosyalarım sekmesi altında görüntülenir. Her bir arkadaş grubunuzun bu dosyaları kendi Arkadaşların Dosyaları sekmelerinde görüp görümeyeceğini seçebilirsiniz.</p> <p>Arama sekmesi arkadaşlarınızın dosya listelerinde arama yapar ve birden çok sıçramalı tünel sistemi üzerinden uzak dosyalara isimsiz olarak erişebilir.</p> - + Move in Queue... Kuyrukta Taşı... @@ -25406,7 +26053,7 @@ p, li { white-space: pre-wrap; } Lütfen yeni -ve geçerli- bir dosya adı yazın - + Expand all Tümünü genişlet @@ -25538,7 +26185,7 @@ p, li { white-space: pre-wrap; } - + Columns Sütunlar @@ -25549,7 +26196,7 @@ p, li { white-space: pre-wrap; } Dosya Aktarımları - + Path Yol @@ -25559,7 +26206,7 @@ p, li { white-space: pre-wrap; } Yol Sütunu Görüntülensin - + Could not delete preview file Önizleme dosyası silinemedi @@ -25569,7 +26216,7 @@ p, li { white-space: pre-wrap; } Yeniden denensin mi? - + Create Collection... Derleme Ekle... @@ -25584,7 +26231,7 @@ p, li { white-space: pre-wrap; } Derlemeyi Görüntüle... - + Collection Derleme @@ -25830,7 +26477,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Bilinmeyen Eş @@ -25926,7 +26573,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages %1 yeni iletiniz var @@ -26298,7 +26945,7 @@ p, li { white-space: pre-wrap; } Grup Ekle - + Subscribe to Group Gruba Abone Ol @@ -26392,8 +27039,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Düzenleme Geçmişi Görüntülensin @@ -26404,7 +27051,7 @@ p, li { white-space: pre-wrap; } - + Preview Önizleme @@ -26429,12 +27076,12 @@ p, li { white-space: pre-wrap; } Düzenleme Geçmişi Gizlensin - + Edit Page Sayfayı Düzenle - + Create New Wiki Page Yeni Wiki Sayfası Ekle @@ -26454,7 +27101,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Yeni Wiki Grubu Ekle @@ -26496,7 +27143,7 @@ p, li { white-space: pre-wrap; } ZamanAralığı - + Create Account @@ -26506,12 +27153,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Yenile @@ -26546,12 +27192,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26621,7 +27267,7 @@ p, li { white-space: pre-wrap; } Görüntülenen: - + Yourself Benimkiler @@ -26659,7 +27305,7 @@ p, li { white-space: pre-wrap; } Wire Üzerine Pulse Gönderin - + RetroShare @@ -26671,7 +27317,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26679,7 +27325,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26760,8 +27406,8 @@ p, li { white-space: pre-wrap; } Form - - + + Avatar Avatar @@ -26790,6 +27436,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26902,8 +27553,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Görseller (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Görseller (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_zh_CN.ts b/retroshare-gui/src/lang/retroshare_zh_CN.ts index f5769dd23..a07132cf4 100644 --- a/retroshare-gui/src/lang/retroshare_zh_CN.ts +++ b/retroshare-gui/src/lang/retroshare_zh_CN.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare 版本 @@ -79,7 +79,7 @@ 祝您使用愉快 ;-) - + Only Hidden Node 仅隐藏节点 @@ -129,12 +129,12 @@ RetroShare: 高级搜索 - + Search Criteria 搜索条件 - + Add a further search criterion. 追加搜索条件。 @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album 相册 @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } 表格 - - + + TextLabel 文字标签 @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } 工具栏 - + Icon Only 只允许图标 @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } 选择工具栏按钮风格 - + Icon Size = 8x8 图标大小 = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } 图标大小 = 128x128 - + Status Bar 状态烂 @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } 系统托盘图标不提示信息 - + Main page items: 主页项目: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } 项目列表 - + Icon Size = 32x32 图标大小 = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } 更换头像 - + + TextLabel + + + + Your Avatar Picture 您的头像文件 - + + Browse... + + + Add Avatar - 添加头像 + 添加头像 @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } 删除 - + Set your Avatar picture 设置头像 - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - 载入头像 + 载入头像 AvatarWidget - - Choose avatar - - - - + Click to change your avatar 点击更改您的头像 @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare 带宽使用 + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 显示设置 + TextLabel + + + + Reset 重置 - Receive Rate - 接收速度 + 接收速度 - Send Rate - 发送速度 + 发送速度 - + Always on Top 置顶 - Style - 样式 + 样式 - + Changes the transparency of the Bandwidth Graph 调整带宽图表的透明度 - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % 不透明 - Save - 保存 + 保存 - Cancel - 取消 + 取消 - + Since: 自从: - Hide Settings - 隐藏设置 + 隐藏设置 BandwidthStatsWidget - + Sum 总和 @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } 数量 - + Average 平均 @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 切换消息阅读状态 + + + + Avatar + 头像 + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展开 + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + 隐藏 + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale 日志 + + + Default + 默认 + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + 切换消息阅读状态 + + + + Avatar + 头像 + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展开 + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + 隐藏 + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to 聊天室 - You have %1 new messages - 您有 %1 个新消息 + 您有 %1 个新消息 + + + You have %1 new message + 您有 %1 个新消息 + + + %1 new messages + %1 个新消息 + + + %1 new message + %1 个新消息 + + + + You have %1 mentions + - You have %1 new message - 您有 %1 个新消息 + You have %1 mention + - %1 new messages - %1 个新消息 + %1 mentions + - %1 new message - %1 个新消息 + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All 删除全部 - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Double click a chat room to enter and chat. 变量: - Group chat - 群聊 + 群聊 - - + Private chat 私聊 @@ -2191,17 +2404,16 @@ Double click a chat room to enter and chat. /me发送消息给 /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">对于不同的聊天系统,这个选项卡是用来设置允许RetroShare可以保存多少聊天消息,以及显示多少条过去的对话。最大存储周期允许丢弃旧消息以防滞留过多不重要的消息(比如,聊天室和年代久远的聊天记录).</p></body></html> - Chatlobbies - 聊天室 + 聊天室 - + Enabled: 已启用: @@ -2222,11 +2434,12 @@ Double click a chat room to enter and chat. + Chat rooms 聊天室 - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2287,11 +2500,17 @@ Double click a chat room to enter and chat. + Broadcast 广播 - + + Node-to-node chat + + + + Saved messages (0 = unlimited): 已保存消息(0=无限制) @@ -2438,8 +2657,23 @@ Double click a chat room to enter and chat. 私聊 - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Double click a chat room to enter and chat. - + is typing... 正在输入... @@ -2629,12 +2863,12 @@ after HTML conversion. 警告:这条信息在HTML转换后还多余%1个字符 - + Choose your font. 选择字体 - + Do you really want to physically delete the history? 您确认要删除聊天记录? @@ -2706,7 +2940,7 @@ after HTML conversion. X物品发现后,请勿停止着色(需要更多CPU占用) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>查找以前的</b><br/><i>Ctrl+Shift+G</i> @@ -2746,12 +2980,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>标记选择文本</b><br><i>Ctrl+M</i> - + Person id: 个人ID @@ -2767,7 +3001,7 @@ Double click on it to add his name on text writer. 未签名 - + items found. 已找到 @@ -2787,7 +3021,7 @@ Double click on it to add his name on text writer. 在此输入消息 - + Don't stop to color after 请勿停止着色 @@ -2945,12 +3179,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details 详情 - + Local Address 本地地址 @@ -2961,12 +3195,12 @@ Double click on it to add his name on text writer. 公网地址 - + Node info: 节点信息: - + Current address: 当前地址: @@ -2982,31 +3216,36 @@ Double click on it to add his name on text writer. 端口 - + Include signatures 包含签名 - + RetroShare RetroShare - + - + Error : cannot get peer details. 错误:无法获取节点详情。 - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3022,22 +3261,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption 加密 - + Not connected 未连接 - + Retroshare node details RetroShare节点详情 - + Node name : 节点名 @@ -3072,13 +3316,18 @@ Double click on it to add his name on text writer. 状态消息: - + + Connectivity + + + + List of known addresses: 已知地址列表: - - + + Retroshare Certificate RetroShare 证书 @@ -3093,7 +3342,7 @@ Double click on it to add his name on text writer. - + Hidden Address 隐藏地址 @@ -3104,11 +3353,12 @@ Double click on it to add his name on text writer. + <p>This certificate contains: - <p>此证书包含: + <p>此证书包含: - + <li>a <b>node ID</b> and <b>name</b> <li>a <b>节点 ID</b> 和 <b>名字</b> @@ -3121,12 +3371,12 @@ Double click on it to add his name on text writer. an <b>IP地址</b> 和<b>端口</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>您可以使用此证书结交新朋友。通过电子邮件发送,或手动发送。</ p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>这是节点的ID <span style=" font-weight:600;">OpenSSL</span> 证书, 被下面用户签名过的:<span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3136,7 +3386,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>这个加密方式是 <span style=" font-weight:600;">OpenSSL</span>. 到好友的连接</p><p>是强加密的,如果有DHE</p><p>&quot;安全效果会更加完美&quot;.</p></body></html> - + with @@ -3342,12 +3592,12 @@ Double click on it to add his name on text writer. 请求详情 - + Peer details 节点详情 - + Name: 名称: @@ -3365,12 +3615,12 @@ resources. 请注意,如果你添加太多的好友,RetroShare 将会需要大量带宽,内存和CPU占用,你可以尽可能多的加好友,但是超过40个好友可能就会占用大量资源 - + Location: 位置: - + Options 选项 @@ -3407,12 +3657,12 @@ resources. 粘贴证书 - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>这里只能输入你的好友的RetroShare证书。 注意,这跟你好友账户的密钥是不一样的。不要再这里粘贴好友的密钥,没用的 (就算是密钥的一部分也不行)。</p></body></html> - + Add friend to group: 添加至好友分组: @@ -3422,7 +3672,7 @@ resources. 为好友的 PGP 密钥签名 - + Please paste below your friend's Retroshare ID @@ -3447,7 +3697,7 @@ resources. - + Add as friend to connect with 添加为可以建立连接的好友 @@ -3456,7 +3706,7 @@ resources. 点击完成可接受好友请求。 - + Sorry, some error appeared 抱歉,出现错误 @@ -3476,32 +3726,32 @@ resources. 您的好友详情: - + Key validity: 密钥有效性: - + Profile ID: - + Signers 签名者 - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">签署好友的钥匙是表达你对这个好友,给你的其他好友的信任的一种方式。 下面的签名加密地证明所列出的密钥的所有者将当前的PGP密钥识别为真实的</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. 此节点已经存在于您的好友列表中。重复添加仅设置其IP地址。 - + To accept the Friend Request, click the Accept button. @@ -3547,7 +3797,7 @@ resources. - + Certificate Load Failed 证书载入失败 @@ -3584,12 +3834,12 @@ resources. 证书似乎有效 - + Not a valid Retroshare certificate! 不是一个有效的 RetroShare 证书! - + RetroShare Invitation RetroShare 邀请 @@ -3611,12 +3861,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? 这是你自己的证书!你该不会是想和自己交朋友吧? - + @@ -3664,7 +3914,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.您有一个好友请求来自 - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3752,12 +4032,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.可用时,作为直连数据源。 - + IP-Addr: IP 地址: - + IP-Address IP 地址: @@ -3823,7 +4103,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.将密钥添加到钥匙环中 - + This key is already in your keyring 密钥已存在于您的钥匙环中 @@ -3884,12 +4164,12 @@ even if you don't make friends. <p>此证书没有IP。 你会依靠节点发现和DHT找到它。 由于您需要清除白名单,节点将在NewsFeed选项卡中引发安全警告。 从那里,你可以将他的IP列入白名单。</ p> - + [Unknown] [未知] - + Added with certificate from %1 添加来自1%的证书 @@ -3976,7 +4256,12 @@ even if you don't make friends. UDP 结果 - + + Status + 状态 + + + <!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; } @@ -4398,7 +4683,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4550,7 +4835,7 @@ p, li { white-space: pre-wrap; } 未选择圈子限制 - + [Unknown] [未知] @@ -4565,7 +4850,7 @@ p, li { white-space: pre-wrap; } 删除 - + Search 搜索 @@ -4585,7 +4870,7 @@ p, li { white-space: pre-wrap; } 签名者:已知节点 - + Edit Circle 编辑圈子 @@ -4605,12 +4890,12 @@ p, li { white-space: pre-wrap; } 匿名 ID - + Circle name 圈子名称 - + Update 更新 @@ -4636,7 +4921,7 @@ p, li { white-space: pre-wrap; } PGP 关联 ID - + Add Member 添加成员 @@ -4780,7 +5065,7 @@ p, li { white-space: pre-wrap; } - + Attachments 附件 @@ -4826,7 +5111,7 @@ p, li { white-space: pre-wrap; } 从搜索结果中拖拽文件 - + Paste RetroShare Links 粘贴 RetroShare 链接 @@ -4836,7 +5121,7 @@ p, li { white-space: pre-wrap; } 粘贴 RetroShare 链接 - + Drop file error. 文件拖拽出错。 @@ -4863,17 +5148,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - 文件已添加并生成散列校验值 + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + 文件已添加并生成散列校验值 + + + Please add a Subject 请添加主题 @@ -4904,12 +5213,12 @@ p, li { white-space: pre-wrap; } 你真的想生成 %1 消息吗? - + You are about to add files you're not actually sharing. Do you still want this to happen? 你正在添加未分享的文件,仍想继续? - + Edit Channel Post @@ -4929,7 +5238,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. 将要分享一个非所有者的文件到一个频道。 @@ -5021,7 +5330,7 @@ p, li { white-space: pre-wrap; } - + No Forum 无论坛 @@ -5480,7 +5789,7 @@ and use the import button to load it DHTGraphSource - + users 用户 @@ -6487,7 +6796,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories 好友目录 @@ -6991,7 +7300,7 @@ at least one peer was not added to a group 搜索好友 - + Mark all 标记全部 @@ -7005,7 +7314,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message 编辑状态消息 @@ -7109,7 +7418,7 @@ at least one peer was not added to a group RetroShare 广而告之:此处的消息会发给当前连接的所有好友。 - + Network 网络 @@ -7174,7 +7483,7 @@ at least one peer was not added to a group 节点字段需要最少3个字符 - + Failed to generate your new certificate, maybe PGP password is wrong! 新证书生成失败,可能您的 PGP 密码有误! @@ -7209,7 +7518,7 @@ at least one peer was not added to a group <html><head/><body><p>您的节点名称指定将在此计算机上运行的RetroShare实例。</p></body></html> - + Node name 节点名称 @@ -7476,12 +7785,12 @@ and use the import button to load it - + Profile generation failure 用户档案创建失败 - + Missing PGP certificate 丢失的 PGP 证书 @@ -7895,7 +8204,7 @@ p, li { white-space: pre-wrap; } 路由状态统计 - + GroupBox 群组 @@ -7960,7 +8269,7 @@ p, li { white-space: pre-wrap; } 分支因子 - + Details 详情 @@ -7983,7 +8292,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys 管理密钥 @@ -8192,7 +8501,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 标题 @@ -8202,13 +8511,30 @@ p, li { white-space: pre-wrap; } 搜索标题 - - + + + + Description 描述 - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description 搜索描述 @@ -8218,42 +8544,31 @@ p, li { white-space: pre-wrap; } - Sort Descending Order - 按降序排列 + 按降序排列 - Sort Ascending Order - 按升序排列 + 按升序排列 - Sort by Name - 按名称排序 + 按名称排序 - Sort by Popularity - 按活跃度排序 + 按活跃度排序 - Sort by Last Post - 按新贴文排序 + 按新贴文排序 - - Sort by Number of Posts - - - - Sort by Unread - 按未读信息分类 + 按未读信息分类 - + You are admin (modify names and description using Edit menu) 你是管理员(修改名字和描述请用编辑菜单) @@ -8268,40 +8583,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post 最新贴文 - + + Name - - Unread - - - - + Popularity 活跃度 - - + + Never 从不 - Display - 显示 + 显示 - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8450,7 +8760,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels 频道 @@ -8475,12 +8785,12 @@ p, li { white-space: pre-wrap; } <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;频道</h1> <p> 频道里你可以推送 (比如电影, 音乐) ,这些会传输到网络的各处</p> <p>您可以看到您的好友订阅的频道,并自动将订阅频道转发给您的好友。这促进了网络中的良好沟通。</p> <p>只有频道的创建者可以在该频道上发布。 网络中的其他对等体只能从其中读取,除非该信道是私有的。然而,您可以 与好友的RetroShare节点共享发布权限或阅读权限。</p> <p> 频道也能设置为匿名的,或附加到RetroShare身份, 以便读者可以在需要时联系您。</p> <p> 频道推送能保存 %1 days, 能同步%2天以内的消息,除非你修改了这个。</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels 订阅的频道 @@ -9001,7 +9311,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -9101,12 +9411,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -9117,18 +9427,18 @@ p, li { white-space: pre-wrap; } - + Feeds 订阅 - - + + Click to switch to list view - + Show unread posts only @@ -9138,12 +9448,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9203,7 +9513,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9218,12 +9528,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9299,23 +9609,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed 已订阅 - - Subscribe 订阅 - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected 未选择频道! @@ -9337,11 +9660,6 @@ p, li { white-space: pre-wrap; } Channel Post 频道文章 - - - new message(s) - - GxsCircleItem @@ -9858,7 +10176,7 @@ before you can comment 新建主题帖 - + Search forums 搜索论坛 @@ -9867,12 +10185,12 @@ before you can comment 最新贴文 - + New Thread 新帖子 - + Threaded View 话题视图 @@ -9882,19 +10200,19 @@ before you can comment 普通视图 - - + + Title 标题 - - + + Date 日期 - + Author 作者 @@ -9909,7 +10227,17 @@ before you can comment 正在载入 - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9970,23 +10298,23 @@ before you can comment <p>订阅论坛将收集 您订阅的好友的 可用帖子。</p><p>之后,您可以从左侧的论坛列表的上下文菜单中取消订阅。</p> - + No name 未命名 - - + + Reply 回复 - + <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> - + Loading... @@ -10024,12 +10352,12 @@ before you can comment 标为未读 - + Copy RetroShare Link 复制 RetroShare 链接 - + Hide 隐藏 @@ -10042,7 +10370,7 @@ before you can comment [被屏蔽的] - + [unknown] [未知] @@ -10072,8 +10400,8 @@ before you can comment 只有你能看见 - - + + Distribution 传播范围 @@ -10176,7 +10504,7 @@ before you can comment 原始贴文 - + New thread @@ -10185,7 +10513,7 @@ before you can comment 读取状态 - + Edit 编辑 @@ -10241,7 +10569,7 @@ before you can comment 在身份页显示作者 - + Author's reputation 作者的信誉 @@ -10261,7 +10589,7 @@ before you can comment - + <b>Loading...<b> @@ -10301,6 +10629,11 @@ before you can comment Storage 存储 + + + Last seen at friends: + + Moderators @@ -10393,7 +10726,7 @@ prevents the message to be forwarded to your friends. %1, %2 写道: - + Forum name 论坛名称 @@ -10425,11 +10758,6 @@ prevents the message to be forwarded to your friends. Forum Post 邮件 - - - new message(s) - - GxsForumsDialog @@ -10878,7 +11206,7 @@ prevents the message to be forwarded to your friends. 打印预览 - + Unsubscribe 退订 @@ -10893,7 +11221,7 @@ prevents the message to be forwarded to your friends. 在新标签中打开 - + Remove this search @@ -10903,12 +11231,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details 显示细节 @@ -10975,7 +11303,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -10984,7 +11312,7 @@ prevents the message to be forwarded to your friends. 共享发布权限 - + Copy RetroShare Link 复制 RetroShare 链接 @@ -10999,7 +11327,7 @@ prevents the message to be forwarded to your friends. 全部标为未读 - + AUTHD 仅签名文章 @@ -11608,7 +11936,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11617,7 +11945,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11643,6 +11971,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11654,7 +11999,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11734,27 +12079,32 @@ p, li { white-space: pre-wrap; } 表单 - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11776,6 +12126,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11784,7 +12135,7 @@ p, li { white-space: pre-wrap; } 下面的文本是你的 RetroShare 证书。把它发送给你的好友 - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11797,12 +12148,12 @@ private and secure decentralized communication platform. 初次使用向导 - + Open Web Help 打开网络帮助 - + Copy your Cert to Clipboard 复制您的证书到剪贴板 @@ -11851,7 +12202,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11860,7 +12211,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12149,14 +12500,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All 全部 - + Reputation 信誉 @@ -12166,12 +12517,12 @@ p, li { white-space: pre-wrap; } 搜索 - + Anonymous Id 匿名 ID - + Create new Identity 新建身份 @@ -12315,7 +12666,7 @@ p, li { white-space: pre-wrap; } 身份ID - + Send message 发送消息 @@ -12387,7 +12738,7 @@ p, li { white-space: pre-wrap; } 总体: - + Anonymous 匿名 @@ -12402,24 +12753,24 @@ p, li { white-space: pre-wrap; } 搜索 ID - + This identity is owned by you 这个身份被你是拥有者 - - + + My own identities 我所拥有的身份 - - + + My contacts 我的通讯录 - + Show Items 显示项目 @@ -12434,7 +12785,7 @@ p, li { white-space: pre-wrap; } 链接到我的节点 - + Other circles 其他圈子 @@ -12493,13 +12844,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). 订阅(接收/转发其他人的成员请求和邀请列表)。 + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). 未订阅(仅能收到邀请列表) - + Your status: 你的状态: @@ -12559,7 +12915,7 @@ p, li { white-space: pre-wrap; } 成员 - + Edit Circle 编辑圈子 @@ -12607,7 +12963,7 @@ p, li { white-space: pre-wrap; } 授予会员资格 - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12619,12 +12975,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [未知节点] - + Unverified signature from node 来自节点的未验证签名 @@ -12636,12 +12992,12 @@ These identities will soon be not supported anymore. 未检查的签名 - + [unverified] [未验证] - + Identity owned by you, linked to your Retroshare node 你所拥有的身份,链接到你的RetroShare节点 @@ -12765,17 +13121,17 @@ These identities will soon be not supported anymore. 你真的要以你的证书发送邀请吗 - + Banned 已屏蔽 - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;身份</h1> <p>身份在此选项卡中,你可以创建/编辑伪匿名身份<b>, 和<b>圈子</b>。</b> <p>身份<b> 身份用于安全地识别你的数据:为聊天室,论坛和频道文章中的消息签名, 使用 RetroShare 内置电子邮件系统接收反馈,在频道发布文章后 发表评论,使用安全隧道聊天等。</p> <p>身份可任意由<b>你 RetroShare 节点的证书</b>签名。 签名的身份更容易信任,但很容易链接到你节点的 IP 地址。</b> <p><b>匿名身份</b>允许您与其他用户匿名交互。 他们不能 被欺骗,但是没有人可以证明谁真正拥有一个特定的身份。</p> <p><b>圈子</b>是通过网络远程共享的身份(匿名或签名)组,它们可 用于限制论坛,频道等的可见性等<p>。</p> 一个<b>圈子</b>可以受限于另一个圈子,从而限制它对该圈子成员的可见性,甚至限制圈子本身的可见性,这意味着只有被邀请的成员可以看到。 - + positive 正面的 @@ -12960,8 +13316,8 @@ These identities will soon be not supported anymore. - - + + People 人物 @@ -12972,7 +13328,7 @@ These identities will soon be not supported anymore. 你的头像 - + Linked to neighbor nodes 链接到相邻节点 @@ -12982,7 +13338,7 @@ These identities will soon be not supported anymore. 链接到远程节点 - + Linked to a friend Retroshare node 链接到好友的RetroShare节点 @@ -13042,7 +13398,7 @@ These identities will soon be not supported anymore. 拥有者 - + Node name: 节点名称: @@ -13052,7 +13408,7 @@ These identities will soon be not supported anymore. 节点Id: - + Really delete? 真的要删除? @@ -13090,7 +13446,22 @@ These identities will soon be not supported anymore. 笔名 - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity 新建身份 @@ -13107,14 +13478,14 @@ These identities will soon be not supported anymore. - + N/A 不适用 - + Edit identity 编辑身份 @@ -13125,24 +13496,27 @@ These identities will soon be not supported anymore. 更新 - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13161,17 +13535,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! 错误:密钥获取出错! - + Error KeyID invalid 错误:密钥ID无效 - + Unknown GpgId 未知 GPG ID @@ -13181,7 +13565,7 @@ These identities will soon be not supported anymore. 未知真实姓名*** - + Create New Identity 创建新身份 @@ -13191,7 +13575,12 @@ These identities will soon be not supported anymore. 类型 - + + Choose image... + + + + @@ -13231,12 +13620,11 @@ These identities will soon be not supported anymore. 你的头像 - Set Avatar - 设置头像 + 设置头像 - + Linked to your profile 链接到你的用户档案 @@ -13246,7 +13634,7 @@ These identities will soon be not supported anymore. 您可以拥有一个或多个身份。 当您在聊天大厅,论坛和频道中撰写评论时,会使用它们。 它们作为远程聊天和RetroShare远程邮件系统的接收地址。 - + The nickname is too short. Please input at least %1 characters. 63/5000 昵称太短。 请输入至少%1个字符。 @@ -13356,8 +13744,12 @@ These identities will soon be not supported anymore. + Quote + 引用 + + Send - 发送 + 发送 @@ -13515,7 +13907,7 @@ These identities will soon be not supported anymore. - + Options 选项 @@ -13547,12 +13939,12 @@ These identities will soon be not supported anymore. 快速入门向导 - + RetroShare %1 a secure decentralized communication platform RetroShare %1 ― 一个分布式安全通信平台 - + Unfinished 未完成 @@ -13685,7 +14077,7 @@ RetroShare 将暂停对此目录的访问。 显示 - + Make sure this link has not been forged to drag you to a malicious website. 请确认此连接不是伪造,不是指向恶意网站。 @@ -13730,7 +14122,7 @@ RetroShare 将暂停对此目录的访问。 服务权限列表 - + Statistics 统计 @@ -13759,7 +14151,7 @@ RetroShare 将暂停对此目录的访问。 MessageComposer - + Compose 写信 @@ -13861,7 +14253,7 @@ RetroShare 将暂停对此目录的访问。 - + Tags 标签 @@ -13956,12 +14348,12 @@ RetroShare 将暂停对此目录的访问。 添加大段引用 - + Send To: 发送至: - + &Left &左对齐 @@ -13995,7 +14387,7 @@ RetroShare 将暂停对此目录的访问。 我的通讯录 - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> 你好,<br>我向你推荐我的一个好友;如果你信任我,也可以信任他们。<br> @@ -14021,12 +14413,12 @@ RetroShare 将暂停对此目录的访问。 - + Save Message 保存邮件 - + Message has not been Sent. Do you want to save message to draft box? 邮件未发送。 @@ -14038,7 +14430,7 @@ Do you want to save message to draft box? 粘贴 RetroShare 链接 - + Add to "To" 添加至"收件人" @@ -14293,7 +14685,7 @@ Do you want to save message ? 添加额外文件 - + Hi,<br>I want to be friends with you on RetroShare.<br> 你好,<br>我想与你成为 RetroShare 上的好友。<br> @@ -14302,12 +14694,27 @@ Do you want to save message ? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite 您有一条好友推荐 - + Respond now: 现在回应: @@ -14323,11 +14730,12 @@ Do you want to save message ? 发件人: + Friend Nodes - 好友节点 + 好友节点 - + Bullet list (disc) 列表(圆盘形) @@ -14367,13 +14775,13 @@ Do you want to save message ? 排序(拉丁字母倒序) - - + + Thanks, <br> 感谢, <br> - + Distant identity: 远程身份 @@ -14512,8 +14920,23 @@ Do you want to save message ? 邮件 - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14525,12 +14948,12 @@ Do you want to save message ? 推荐的文件 - + Download all Recommended Files 下载所有推荐文件 - + Subject: 主题: @@ -14605,12 +15028,18 @@ Do you want to save message ? 发送邀请 - + + Message Size: + + + + File Name 文件名称 - + + Size 大小 @@ -14671,10 +15100,25 @@ Do you want to save message ? 下载 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? 发送邀请? @@ -14685,12 +15129,12 @@ Do you want to save message ? - + Download all 下载全部 - + Print Document 打印文档 @@ -14705,7 +15149,7 @@ Do you want to save message ? HTML 文件 (*.htm *.html);;所有文件 (*) - + Load images always for this message 此消息总是载入图像 @@ -14846,7 +15290,7 @@ Do you want to save message ? MessagesDialog - + New Message 新信息 @@ -14902,14 +15346,14 @@ Do you want to save message ? - + Tags 标签 - + Inbox 收件箱 @@ -15004,7 +15448,7 @@ Do you want to save message ? 转发信件 - + Subject 主题 @@ -15116,7 +15560,7 @@ Do you want to save message ? - + Open in a new window 在新窗口中打开 @@ -15201,7 +15645,7 @@ Do you want to save message ? - + Drafts 草稿箱 @@ -15330,7 +15774,7 @@ Do you want to save message ? 回复消息 - + Delete Message 删除消息 @@ -15341,7 +15785,7 @@ Do you want to save message ? - + Expand 展开 @@ -15351,7 +15795,7 @@ Do you want to save message ? 删除项目 - + from 来自 @@ -15360,6 +15804,11 @@ Do you want to save message ? Reply to invite 回复邀请 + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15682,7 +16131,7 @@ Reported error: - + Groups 分组 @@ -15712,19 +16161,19 @@ Reported error: 导出你的好友列表包括分组 - - + + Search - + ID ID - + Search ID 搜索 ID @@ -15734,7 +16183,7 @@ Reported error: - + Show Items 显示项目 @@ -15938,18 +16387,18 @@ at least one peer was not added to a group - + Error 错误 - + File is not writeable! 无法写入文件! - + File is not readable! 无法读取文件! @@ -15986,9 +16435,13 @@ at least one peer was not added to a group NewsFeed - Log entries - 日志条目 + 日志条目 + + + + Activity Stream + @@ -16005,7 +16458,7 @@ at least one peer was not added to a group 这是一个测试。 - + Newest on top 新的在上面 @@ -16016,8 +16469,12 @@ at least one peer was not added to a group + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;事件中心</h1> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;事件中心</h1> <p>事件中心显示网络上最近的事件,按您收到的时间排序。 它为您提供了一份好友活动摘要。您可以点击<b>选项</b>设置要显示的事件。</p> <p>可显示的各种事件包括: @@ -16027,16 +16484,35 @@ at least one peer was not added to a group <li>好友发送的私人消息</li></ul> </p> - Log - 日志 + 日志 + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16073,22 +16549,22 @@ at least one peer was not added to a group - + Test 测试 - + Chat Room 聊天室 - + Systray Icon 系统托盘图标 - + Message 邮件 @@ -16113,12 +16589,11 @@ at least one peer was not added to a group IP安全 - Log - 日志 + 日志 - + Friend Connected 好友已连接 @@ -16132,7 +16607,12 @@ at least one peer was not added to a group 链接 - + + Activity + + + + Mails 邮件 @@ -16169,7 +16649,12 @@ at least one peer was not added to a group 群聊 - + + Toaster position + + + + Chat rooms 聊天室 @@ -16182,22 +16667,22 @@ at least one peer was not added to a group 区分大小写 - + Position 位置 - + X Margin X 边距 - + Y Margin Y 边距 - + Systray message 系统托盘消息 @@ -16247,7 +16732,7 @@ at least one peer was not added to a group 提示 - + Disable All Toasters 禁用所有弹出消息 @@ -16261,7 +16746,7 @@ at least one peer was not added to a group 日志订阅 - + Systray 系统托盘 @@ -16407,17 +16892,16 @@ at least one peer was not added to a group PGPKeyDialog - Dialog - 对话 + 对话 - + Profile info 用户信息 - + Name : 名字: @@ -16472,22 +16956,21 @@ at least one peer was not added to a group 绝对 - + This profile has signed your own profile key 节点是否对我的PGP密钥签名 - Key signatures : - 密钥签名。 + 密钥签名。 - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">签署好友的钥匙是表达你对这个好友,给你的其他好友的信任的一种方式。 下面的签名加密地证明所列出的密钥的所有者将当前的PGP密钥识别为真实的</span></p></body></html> - + <!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; } @@ -16505,7 +16988,7 @@ p, li { white-space: pre-wrap; } 为此密钥签名 - + PGP key PGP 密钥 @@ -16515,22 +16998,20 @@ p, li { white-space: pre-wrap; } 这些选项将应用到这个用户的所有节点 - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">签署好友的钥匙是表达你对这个好友,给你的其他好友的信任的一种方式。 它可以帮助他们决定是否允许基于您自己的信任的密钥进行连接。 签署密钥是绝对可选的,不能撤销,所以请做出明智的选择.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">签署好友的钥匙是表达你对这个好友,给你的其他好友的信任的一种方式。 它可以帮助他们决定是否允许基于您自己的信任的密钥进行连接。 签署密钥是绝对可选的,不能撤销,所以请做出明智的选择.</span></p></body></html> - + Keysigning: - Sign PGP key - 签署PGP密钥 + 签署PGP密钥 - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>如果要拒绝与此密钥验证的节点的连接,请单击此处。</p></body></html> @@ -16550,7 +17031,7 @@ p, li { white-space: pre-wrap; } 接受连接 - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16620,28 +17101,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. 错误:无法获取节点详情。 - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) RetroShare 不支持此密钥算法 (目前仅支持 RSA 密钥) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16655,7 +17136,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. 信任级别是表达您对此密钥的信任的一种方式。 它不被软件使用,也不是共享的,仅用于方便记住好/坏的密钥。 @@ -16700,27 +17181,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.您目前不允许通过此密钥签名的RetroShare节点进行连接。 - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure 签名失败 - - Maybe password is wrong - 密码可能不对 + + Check the password! + - + Maybe password is wrong + 密码可能不对 + + + You haven't set a trust level for this key. 你还没有对这个密钥设置信任等级 - + + Retroshare profile RetroShare用户档案 - + This is your own PGP key, and it is signed by : 这是你的密钥,签名人是: @@ -16899,8 +17400,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People 人物 @@ -16917,7 +17417,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.内部 - + Chat with this person 与此人聊天 @@ -17068,7 +17568,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.照片 - + TextLabel 文字标签 @@ -17112,7 +17612,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -17148,6 +17648,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... 写评论... + + + Album + 相册 + PhotoItem @@ -17157,12 +17662,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.表格 - + TextLabel 文字标签 - + <!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; } @@ -17258,7 +17763,7 @@ p, li { white-space: pre-wrap; } 查看照片 - + PhotoShare 分享照片 @@ -17298,7 +17803,7 @@ requesting to edit it! - + Stop 停止 @@ -17526,12 +18031,12 @@ p, li { white-space:pre-wrap;} PluginsPage - + Authorize all plugins 允许所有插件 - + Plugin look-up directories 插件查找目录 @@ -17590,7 +18095,7 @@ malicious behavior of crafted plugins. <h1><img width="24" src=":/icons/help_64.png">&nbsp;&nbsp;插件</h1> <p>插件从下列列表中目录中加载。</p> <p> 由于安全原因,接受的插件自动加载 直到主RetroShare可执行文件或插件库更改。 在 这种情况下,用户需要再次确认。 程序启动后,您可以通过单击“启用”按钮手动启用插件, 然后重新启动RetroShare。</p> <p>如果要开发自己的插件,请联系开发人员团队, 他们将乐意帮助您!</p> - + Plugins 插件 @@ -17980,7 +18485,7 @@ malicious behavior of crafted plugins. 链接: - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18151,13 +18656,13 @@ malicious behavior of crafted plugins. 站点 - - + + Comments 注释 - + Copy RetroShare Link @@ -18167,7 +18672,7 @@ malicious behavior of crafted plugins. 在身份页显示作者 - + Comment 评论 @@ -18188,12 +18693,12 @@ malicious behavior of crafted plugins. - + Hide 隐藏 - + Vote up @@ -18207,7 +18712,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item 设置为已读并删除条目 @@ -18268,7 +18773,7 @@ malicious behavior of crafted plugins. - + Loading 正在载入 @@ -18358,13 +18863,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18374,60 +18873,50 @@ malicious behavior of crafted plugins. 管理员: - - - + + + unknown 未知 - + Distribution: 传播范围 - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts 贴文 @@ -18438,7 +18927,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18507,7 +18996,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link @@ -18542,7 +19036,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -18666,8 +19160,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18939,9 +19443,8 @@ and use the import button to load it PulseAddDialog - Post From: - 贴文来自: + 贴文来自: Account 1 @@ -18956,7 +19459,7 @@ and use the import button to load it 账户3 - + Add to Pulse 添加至 Pulse @@ -18979,17 +19482,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + 发件人: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19014,10 +19532,20 @@ and use the import button to load it 负面的 - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19027,14 +19555,53 @@ and use the import button to load it - + + Post + + + + Cancel 取消 - Post Pulse to Wire - 向wire发刺探包 + 向wire发刺探包 + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19060,10 +19627,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image 图像 @@ -19071,44 +19646,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19118,17 +19693,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19138,7 +19713,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19146,7 +19721,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -19161,7 +19736,7 @@ and use the import button to load it - + follow Parent Group @@ -19171,7 +19746,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19196,7 +19771,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19232,29 +19807,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19332,7 +19907,7 @@ and use the import button to load it QObject - + Confirmation 确认 @@ -19572,7 +20147,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 结果 - + Unable to make path 无法创建路径 @@ -19607,7 +20182,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 文件请求已取消 - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. 此版本的 RetroShare 正在使用 OpenPGP-SDK。因此没有使用系统中的共享PGP钥匙环,而是自有钥匙环,在所有RetroShare实例间共享。<br><br> 您似乎没有这种钥匙环,尽管现有 RetroShare 账户中引用了PGP密钥,也许您刚刚才升级至此新版本。 @@ -19756,7 +20331,7 @@ Reported error is: s - + TR up 上行流量 @@ -19801,7 +20376,7 @@ Reported error is: 禁用 - + Move IP %1 to whitelist 添加%1至白名单 @@ -19817,7 +20392,7 @@ Reported error is: - + %1 seconds ago %1 秒前 @@ -19903,7 +20478,7 @@ Security: no anonymous IDs - + Error 错误 @@ -20294,9 +20869,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>此证书包含: + <p>此证书包含: @@ -20670,7 +21244,7 @@ p, li { white-space:pre-wrap;} RSGraphWidget - + %1 KB %1 KB @@ -20892,19 +21466,48 @@ p, li { white-space:pre-wrap;} RSTreeWidget - + Tree View Options 树状视图选项 - Show column... - 显示列 + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + 按降序排列 + + + + Sort Ascending Order + 按升序排列 + + + + + [no title] + + + + + Show column … + + + + Show column... + 显示列 - [no title] - [无标题] + [无标题] @@ -21340,7 +21943,7 @@ p, li { white-space:pre-wrap;} 下载! - + File 文件 @@ -21355,7 +21958,7 @@ p, li { white-space:pre-wrap;} 散列值 - + Bad filenames have been cleaned 无效文件名已修改。 @@ -21405,7 +22008,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 保存 - + Collection Editor 合集编辑者 @@ -21420,7 +22023,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 文件数量 - + Real Size: Waiting child... 真实大小:等待子集... @@ -21435,12 +22038,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace 这是一个目录,双击展开 - + Download files - + Specify... 指定... @@ -21689,7 +22292,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -21709,7 +22312,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -21722,10 +22325,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 标题 + + + UnRead + + Date @@ -21737,7 +22345,7 @@ If you believe it is correct, remove the corresponding line from the file and re 作者 - + Information for this identity is currently missing. 这个身份的信息现在丢失了 @@ -21777,7 +22385,7 @@ prevents the message to be forwarded to your friends. [未知] - + [ ... Missing Message ... ] [ ... 丢失消息 ... ] @@ -21785,7 +22393,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 日期 @@ -21845,7 +22453,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22204,7 +22812,7 @@ prevents the message to be forwarded to your friends. 文件名称 - + Download 下载 @@ -22283,7 +22891,7 @@ prevents the message to be forwarded to your friends. 打开文件夹 - + Create Collection... 创建资源集合 @@ -22303,7 +22911,7 @@ prevents the message to be forwarded to your friends. 从集合文件中下载... - + Collection 资源集合 @@ -22408,12 +23016,12 @@ prevents the message to be forwarded to your friends. 节点详情 - + Deny friend 拒绝好友 - + Chat 聊天 @@ -22423,7 +23031,7 @@ prevents the message to be forwarded to your friends. 开始聊天 - + Expand 展开 @@ -22693,13 +23301,13 @@ behind a firewall or a VPN. 节点探索开启(推荐) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off 节点探索关闭 @@ -23167,7 +23775,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network 网络 @@ -23195,7 +23803,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status 状态 @@ -23292,7 +23900,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address 服务地址 @@ -23327,12 +23935,12 @@ If you have issues connecting over Tor check the Tor logs too. 请填写服务地址 - + IP Range IP 范围 - + Reported by DHT for IP masquerading DHT报告IP伪装 @@ -23999,7 +24607,7 @@ p, li { white-space: pre-wrap; } 缺失 PGP 证书 - + Wrong password 密码错误 @@ -24055,7 +24663,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend 添加好友 @@ -24111,7 +24719,7 @@ This choice can be reverted in settings. 服务权限列表 - + DHT DHT @@ -24653,7 +25261,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24663,13 +25271,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor现在离线 - + Tor is OK Tor已就绪 @@ -24678,6 +25285,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24970,35 +25602,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - 您有 %1 个下载任务已完成 + You have %1 completed transfers + - You have %1 completed download - 您有 %1 个下载任务已完成 + You have %1 completed transfer + - %1 completed downloads - %1 个下载任务已完成 + %1 completed transfers + - %1 completed download - %1 个下载任务已完成 + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + 您有 %1 个下载任务已完成 + + + You have %1 completed download + 您有 %1 个下载任务已完成 + + + %1 completed downloads + %1 个下载任务已完成 + + + %1 completed download + %1 个下载任务已完成 TransfersDialog - + Downloads 下载 @@ -25009,7 +25652,7 @@ p, li { white-space: pre-wrap; } 上传 - + Name i.e: file name 名称 @@ -25225,7 +25868,7 @@ p, li { white-space: pre-wrap; } <p>搜索标签列出来自好友文件列表中的文件,及通过多跳隧道系统匿名可见的远程文件。</p> - + Move in Queue... 队列位置... @@ -25319,7 +25962,7 @@ p, li { white-space: pre-wrap; } 输入新的有效文件名 - + Expand all 全部展开 @@ -25451,7 +26094,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -25462,7 +26105,7 @@ p, li { white-space: pre-wrap; } 文件传输 - + Path 路径 @@ -25472,7 +26115,7 @@ p, li { white-space: pre-wrap; } 显示路径栏 - + Could not delete preview file 不能删除之前文件 @@ -25482,7 +26125,7 @@ p, li { white-space: pre-wrap; } 再试一次? - + Create Collection... 创建资源集合 @@ -25497,7 +26140,7 @@ p, li { white-space: pre-wrap; } 打开资源集合 - + Collection 资源集合 @@ -25743,7 +26386,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer 未知节点 @@ -25839,7 +26482,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages 您有 %1 个新消息 @@ -26219,7 +26862,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group 订阅小组 @@ -26313,8 +26956,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History 显示编辑历史 @@ -26325,7 +26968,7 @@ p, li { white-space: pre-wrap; } - + Preview 预览 @@ -26350,12 +26993,12 @@ p, li { white-space: pre-wrap; } 隐藏编辑历史 - + Edit Page 编辑页面 - + Create New Wiki Page 创建新Wiki页面 @@ -26375,7 +27018,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group 创建新Wiki组 @@ -26417,7 +27060,7 @@ p, li { white-space: pre-wrap; } 时间范围 - + Create Account @@ -26427,12 +27070,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh 刷新 @@ -26467,12 +27109,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26542,7 +27184,7 @@ p, li { white-space: pre-wrap; } 当前显示: - + Yourself 我自己 @@ -26580,7 +27222,7 @@ p, li { white-space: pre-wrap; } 向wire发刺探包 - + RetroShare @@ -26592,7 +27234,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26600,7 +27242,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26681,8 +27323,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar 头像 @@ -26711,6 +27353,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26823,8 +27470,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - 图片 (*.png *.xpm *.jpg *.tiff *.gif *.jpeg) + 图片 (*.png *.xpm *.jpg *.tiff *.gif *.jpeg) diff --git a/retroshare-gui/src/lang/retroshare_zh_TW.ts b/retroshare-gui/src/lang/retroshare_zh_TW.ts index d6d5a0959..92a16dae4 100644 --- a/retroshare-gui/src/lang/retroshare_zh_TW.ts +++ b/retroshare-gui/src/lang/retroshare_zh_TW.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -167,7 +167,7 @@ AlbumDialog - + Album @@ -286,7 +286,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -329,8 +329,8 @@ p, li { white-space: pre-wrap; } 表單 - - + + TextLabel @@ -397,7 +397,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -422,7 +422,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -447,7 +447,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -522,7 +522,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -537,7 +537,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -603,13 +603,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -618,25 +623,30 @@ p, li { white-space: pre-wrap; } 刪除 - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -644,7 +654,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -664,44 +674,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings 選項 + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -711,30 +730,19 @@ p, li { white-space: pre-wrap; } - - Save - - - - Cancel - 取消 + 取消 - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -756,7 +764,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -890,7 +898,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -968,6 +976,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展開 + + + + Set as read and remove item + 設置為已讀并刪除項目 + + + + Remove Item + 刪除項目 + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + 隱藏 + + BwCtrlWindow @@ -1103,6 +1190,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1155,6 +1252,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + 展開 + + + + Set as read and remove item + 設置為已讀并刪除項目 + + + + Remove Item + 刪除項目 + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + 隱藏 + + ChatLobbyDialog @@ -1363,22 +1539,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1392,11 +1568,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1821,13 +1992,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1892,17 +2057,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1923,11 +2083,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1988,11 +2149,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2131,8 +2298,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2301,7 +2483,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2318,12 +2500,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2395,7 +2577,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2431,12 +2613,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2452,7 +2634,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2472,7 +2654,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2630,12 +2812,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2646,12 +2828,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2667,31 +2849,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2707,22 +2899,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2757,13 +2949,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2778,7 +2975,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2789,17 +2986,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2809,7 +3011,7 @@ Double click on it to add his name on text writer. - + with @@ -2893,32 +3095,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: 名稱: - + Location: - + Options 選項 - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2928,7 +3130,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2953,12 +3155,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2978,32 +3180,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3049,17 +3251,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3079,12 +3281,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3132,7 +3334,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3176,12 +3408,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3211,7 +3443,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3269,12 +3501,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3349,7 +3581,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3771,7 +4008,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3915,7 +4152,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3930,7 +4167,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3946,7 +4183,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3962,12 +4199,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3989,7 +4226,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4115,7 +4352,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4161,7 +4398,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4171,7 +4408,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4198,17 +4435,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4239,12 +4496,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4264,7 +4521,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4352,7 +4609,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4767,7 +5024,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5770,7 +6027,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6261,7 +6518,7 @@ at least one peer was not added to a group - + Mark all @@ -6275,7 +6532,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6379,7 +6636,7 @@ at least one peer was not added to a group - + Network @@ -6444,7 +6701,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6475,7 +6732,7 @@ at least one peer was not added to a group - + Node name @@ -6734,12 +6991,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7102,7 +7359,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7167,7 +7424,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7190,7 +7447,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7391,7 +7648,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title 標題 @@ -7401,13 +7658,30 @@ p, li { white-space: pre-wrap; } 搜索標題 - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7417,42 +7691,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7467,40 +7706,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7649,7 +7879,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7670,12 +7900,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8068,7 +8298,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8168,12 +8398,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8184,18 +8414,18 @@ p, li { white-space: pre-wrap; } - + Feeds 訂閱 - - + + Click to switch to list view - + Show unread posts only @@ -8205,12 +8435,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8270,7 +8500,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8285,12 +8515,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8366,23 +8596,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8404,11 +8647,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8893,17 +9131,17 @@ before you can comment - + Search forums 搜索論壇 - + New Thread - + Threaded View @@ -8913,19 +9151,19 @@ before you can comment - - + + Title 標題 - - + + Date 日期 - + Author 作者 @@ -8940,7 +9178,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8985,23 +9233,23 @@ before you can comment 搜索作者 - + No name 未命名 - - + + Reply - + <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> - + Loading... @@ -9039,12 +9287,12 @@ before you can comment 標為未讀 - + Copy RetroShare Link - + Hide 隱藏 @@ -9053,7 +9301,7 @@ before you can comment 展開 - + [unknown] @@ -9083,8 +9331,8 @@ before you can comment - - + + Distribution @@ -9167,12 +9415,12 @@ before you can comment - + New thread - + Edit 編輯 @@ -9228,7 +9476,7 @@ before you can comment - + Author's reputation @@ -9248,7 +9496,7 @@ before you can comment - + <b>Loading...<b> @@ -9288,6 +9536,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9355,7 +9608,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9387,11 +9640,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9797,7 +10045,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9812,7 +10060,7 @@ This message is missing. You should receive it later. 在新標簽中打開 - + Remove this search @@ -9822,12 +10070,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9894,12 +10142,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9914,7 +10162,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10428,7 +10676,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10437,7 +10685,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10463,7 +10711,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10537,49 +10785,55 @@ p, li { white-space: pre-wrap; } 表單 - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10627,17 +10881,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10652,7 +10901,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10917,14 +11171,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10934,12 +11188,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11083,7 +11337,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11155,7 +11409,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11170,24 +11424,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11202,7 +11456,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11261,13 +11515,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11327,7 +11586,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11375,7 +11634,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11384,12 +11643,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11401,12 +11660,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11522,17 +11781,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11689,8 +11948,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11701,7 +11960,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11711,7 +11970,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11771,7 +12030,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11781,7 +12040,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11819,7 +12078,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11836,14 +12095,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11854,24 +12113,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11891,12 +12153,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11906,7 +12193,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11916,7 +12203,12 @@ These identities will soon be not supported anymore. 類型 - + + Choose image... + + + + @@ -11956,12 +12248,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11971,7 +12258,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12076,7 +12363,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12235,7 +12522,7 @@ These identities will soon be not supported anymore. - + Options 選項 @@ -12267,12 +12554,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12401,7 +12688,7 @@ These identities will soon be not supported anymore. 顯示 - + Make sure this link has not been forged to drag you to a malicious website. @@ -12446,7 +12733,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12475,7 +12762,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12577,7 +12864,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12672,12 +12959,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12707,7 +12994,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12733,12 +13025,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12749,7 +13041,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -13003,7 +13295,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13017,6 +13309,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13029,7 +13336,7 @@ Do you want to save message ? 從: - + Bullet list (disc) @@ -13069,13 +13376,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13214,8 +13521,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13227,12 +13549,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13307,12 +13629,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13373,18 +13701,33 @@ Do you want to save message ? 下載 - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13399,7 +13742,7 @@ Do you want to save message ? - + Load images always for this message @@ -13508,7 +13851,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13524,14 +13867,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13602,7 +13945,7 @@ Do you want to save message ? - + Subject @@ -13682,7 +14025,7 @@ Do you want to save message ? - + Open in a new window @@ -13767,7 +14110,7 @@ Do you want to save message ? - + Drafts @@ -13856,7 +14199,7 @@ Do you want to save message ? - + Delete Message @@ -13867,7 +14210,7 @@ Do you want to save message ? - + Expand 展開 @@ -13877,7 +14220,7 @@ Do you want to save message ? 刪除項目 - + from @@ -13886,6 +14229,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14185,7 +14533,7 @@ Reported error: - + Groups @@ -14215,19 +14563,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14237,7 +14585,7 @@ Reported error: - + Show Items @@ -14436,18 +14784,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14485,7 +14833,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14499,7 +14847,7 @@ at least one peer was not added to a group - + Newest on top @@ -14510,20 +14858,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14556,22 +14919,22 @@ at least one peer was not added to a group - + Test 測試 - + Chat Room - + Systray Icon - + Message @@ -14592,12 +14955,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14644,27 +15002,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14714,7 +15082,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14728,7 +15096,7 @@ at least one peer was not added to a group 訂閱 - + Systray @@ -14855,17 +15223,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14920,22 +15283,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14949,7 +15307,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14959,22 +15317,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14994,7 +15342,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15060,27 +15408,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15092,7 +15440,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15137,27 +15485,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15328,8 +15692,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15346,7 +15709,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15485,7 +15848,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15521,7 +15884,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15549,6 +15912,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... ... + + + Album + + PhotoItem @@ -15558,12 +15926,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.表單 - + TextLabel - + <!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; } @@ -15643,7 +16011,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15683,7 +16051,7 @@ requesting to edit it! - + Stop @@ -15907,17 +16275,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16243,7 +16611,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16374,13 +16742,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16390,7 +16758,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16411,12 +16779,12 @@ p, li { white-space: pre-wrap; } - + Hide 隱藏 - + Vote up @@ -16426,7 +16794,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item 設置為已讀并刪除項目 @@ -16487,7 +16855,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16529,13 +16897,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16545,60 +16907,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16609,7 +16961,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16678,7 +17030,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16713,7 +17070,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16829,8 +17186,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17098,12 +17465,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17118,17 +17480,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + 從: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17153,10 +17530,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17166,13 +17553,48 @@ and use the import button to load it - + + Post + + + + Cancel 取消 - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17199,10 +17621,18 @@ and use the import button to load it 表單 - - - - + + + + + Click to view picture + + + + + + + Image @@ -17210,44 +17640,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17257,17 +17687,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17277,7 +17707,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17285,7 +17715,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17300,7 +17730,7 @@ and use the import button to load it - + follow Parent Group @@ -17310,7 +17740,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17335,7 +17765,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17371,29 +17801,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17471,7 +17901,7 @@ and use the import button to load it QObject - + Confirmation @@ -17710,7 +18140,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17745,7 +18175,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17883,7 +18313,7 @@ Reported error is: s - + TR up @@ -17928,7 +18358,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17944,7 +18374,7 @@ Reported error is: - + %1 seconds ago @@ -18028,7 +18458,7 @@ Security: no anonymous IDs - + Error @@ -18418,11 +18848,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18756,7 +19181,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18978,18 +19403,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19426,7 +19872,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19441,7 +19887,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19489,7 +19935,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19504,7 +19950,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19519,12 +19965,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19771,7 +20217,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19791,7 +20237,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19804,10 +20250,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title 標題 + + + UnRead + + Date @@ -19819,7 +20270,7 @@ If you believe it is correct, remove the corresponding line from the file and re 作者 - + Information for this identity is currently missing. @@ -19857,7 +20308,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19865,7 +20316,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date 日期 @@ -19925,7 +20376,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20279,7 +20730,7 @@ prevents the message to be forwarded to your friends. - + Download 下載 @@ -20358,7 +20809,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20378,7 +20829,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20483,12 +20934,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20498,7 +20949,7 @@ prevents the message to be forwarded to your friends. - + Expand 展開 @@ -20761,13 +21212,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21233,7 +21684,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21261,7 +21712,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21358,7 +21809,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21393,12 +21844,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22063,7 +22514,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22105,7 +22556,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22161,7 +22612,7 @@ This choice can be reverted in settings. - + DHT @@ -22693,7 +23144,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22703,13 +23154,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22718,6 +23168,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22991,27 +23466,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23019,7 +23489,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23030,7 +23500,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23237,7 +23707,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23331,7 +23801,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23463,7 +23933,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23474,7 +23944,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23484,7 +23954,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23494,7 +23964,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23509,7 +23979,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23751,7 +24221,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23847,7 +24317,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24215,7 +24685,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24309,8 +24779,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24321,7 +24791,7 @@ p, li { white-space: pre-wrap; } - + Preview 預覽 @@ -24346,12 +24816,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24371,7 +24841,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24409,7 +24879,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24419,12 +24889,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24459,12 +24928,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24498,7 +24967,7 @@ p, li { white-space: pre-wrap; } 新建 - + Yourself @@ -24508,7 +24977,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24520,7 +24989,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24528,7 +24997,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24609,8 +25078,8 @@ p, li { white-space: pre-wrap; } 表單 - - + + Avatar @@ -24639,6 +25108,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24751,7 +25225,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index cfb9932ca..e33fe795d 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -66,7 +66,7 @@ CrashStackTrace gCrashStackTrace; # include "gui/settings/JsonApiPage.h" #endif // RS_JSONAPI -#include "TorControl/TorManager.h" +#include "retroshare/rstor.h" #include "TorControl/TorControlWindow.h" #include "retroshare/rsidentity.h" @@ -99,10 +99,6 @@ __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) #endif #endif -/*** WINDOWS DON'T LIKE THIS - REDEFINES VER numbers. -#include -****/ - #include #include #include @@ -243,7 +239,8 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); >> parameter('d',"debug-level" ,conf.debugLevel ,"level" ,"Set debug level." ,false) >> parameter('i',"ip-address" ,conf.forcedInetAddress,"nnn.nnn.nnn.nnn", "Force IP address to use (if cannot be detected)." ,false) >> parameter('p',"port" ,conf.forcedPort ,"port" ,"Set listenning port to use." ,false) - >> parameter('o',"opmode" ,conf.opModeStr ,"opmode" ,"Set Operating mode (Full, NoTurtle, Gaming, Minimal)." ,false); + >> parameter('o',"opmode" ,conf.opModeStr ,"opmode" ,"Set Operating mode (Full, NoTurtle, Gaming, Minimal)." ,false) + >> parameter('t',"opmode" ,conf.userSuppliedTorExecutable,"tor" ,"supply full tor eecutable path." ,false); #ifdef RS_JSONAPI as >> parameter('J', "jsonApiPort", conf.jsonApiPort, "jsonApiPort", "Enable JSON API on the specified port", false ) >> parameter('P', "jsonApiBindAddress", conf.jsonApiBindAddress, "jsonApiBindAddress", "JSON API Bind Address.", false); @@ -397,26 +394,28 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); if(is_auto_tor) { + if(!conf.userSuppliedTorExecutable.empty()) + RsTor::setTorExecutablePath(conf.userSuppliedTorExecutable); + // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service - QString tor_hidden_service_dir = QString::fromStdString(RsAccounts::AccountDirectory()) + QString("/hidden_service/") ; + std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->setTorDataDirectory(Rshare::dataDirectory() + QString("/tor/")); - torManager->setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run + RsTor::setTorDataDirectory(Rshare::dataDirectory().toStdString() + "/tor/"); + RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run - RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir.toUtf8())) ; + RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; - torManager->setupHiddenService(); + //RsTor::setupHiddenService(); - if(! torManager->start() || torManager->hasError()) + if(! RsTor::start() || RsTor::hasError()) { - QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+torManager->errorMessage()) ; + QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+QString::fromStdString(RsTor::errorMessage())) ; return 1 ; } { - TorControlDialog tcd(torManager) ; + TorControlDialog tcd; QString error_msg ; tcd.show(); @@ -460,30 +459,29 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); { // Tor works with viable hidden service. Let's use it! - QString service_id ; - QString onion_address ; + std::string service_id ; + std::string onion_address ; uint16_t service_port ; uint16_t service_target_port ; uint16_t proxy_server_port ; - QHostAddress service_target_address ; - QHostAddress proxy_server_address ; + std::string service_target_address ; + std::string proxy_server_address ; - Tor::TorManager *torManager = Tor::TorManager::instance(); - torManager->getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); - torManager->getProxyServerInfo(proxy_server_address,proxy_server_port) ; + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; std::cerr << "Got hidden service info: " << std::endl; - std::cerr << " onion address : " << onion_address.toStdString() << std::endl; - std::cerr << " service_id : " << service_id.toStdString() << std::endl; + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; std::cerr << " service port : " << service_port << std::endl; std::cerr << " target port : " << service_target_port << std::endl; - std::cerr << " target address : " << service_target_address.toString().toStdString() << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; - std::cerr << "Setting proxy server to " << service_target_address.toString().toStdString() << ":" << service_target_port << std::endl; + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; - rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address.toString().toStdString(), service_target_port); - rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address.toStdString(), service_port); - rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address.toString().toStdString(),proxy_server_port) ; + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; } Rshare::initPlugins(); @@ -538,11 +536,9 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); // avoid clashes between infos from threads. // - qRegisterMetaType("FileDetail") ; qRegisterMetaType("RsPeerId") ; std::cerr << "connecting signals and slots" << std::endl ; - QObject::connect(notify,SIGNAL(gotTurtleSearchResult(qulonglong,FileDetail)),w->transfersDialog->searchDialog ,SLOT(updateFiles(qulonglong,FileDetail))) ; QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; @@ -597,6 +593,10 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsGxsUpdateBroadcast::cleanup(); #endif + if (is_auto_tor) { + RsTor::stop(); + } + RsControl::instance()->rsGlobalShutDown(); delete(soundManager); diff --git a/retroshare-gui/src/qss/blacknight/check_sel.png b/retroshare-gui/src/qss/blacknight/check_sel.png deleted file mode 100644 index 300de11ee..000000000 Binary files a/retroshare-gui/src/qss/blacknight/check_sel.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/check_unsel.png b/retroshare-gui/src/qss/blacknight/check_unsel.png deleted file mode 100644 index 50ca1d0a5..000000000 Binary files a/retroshare-gui/src/qss/blacknight/check_unsel.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/clbg.png b/retroshare-gui/src/qss/blacknight/clbg.png deleted file mode 100644 index 45ce37337..000000000 Binary files a/retroshare-gui/src/qss/blacknight/clbg.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/down.png b/retroshare-gui/src/qss/blacknight/down.png deleted file mode 100644 index ce161569b..000000000 Binary files a/retroshare-gui/src/qss/blacknight/down.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/radio_sel.png b/retroshare-gui/src/qss/blacknight/radio_sel.png deleted file mode 100644 index 1239b6dc8..000000000 Binary files a/retroshare-gui/src/qss/blacknight/radio_sel.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/radio_unsel.png b/retroshare-gui/src/qss/blacknight/radio_unsel.png deleted file mode 100644 index 4c895c9da..000000000 Binary files a/retroshare-gui/src/qss/blacknight/radio_unsel.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blacknight/up.png b/retroshare-gui/src/qss/blacknight/up.png deleted file mode 100644 index 38d747789..000000000 Binary files a/retroshare-gui/src/qss/blacknight/up.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blue.qss b/retroshare-gui/src/qss/blue.qss deleted file mode 100644 index 894196f68..000000000 --- a/retroshare-gui/src/qss/blue.qss +++ /dev/null @@ -1,199 +0,0 @@ -.QWidget { - background-color: #c4dafa; - border-color: transparent; -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); - border: 1px solid #87ADE4; -} - -FriendsDialog QFrame#headFrame { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); - border: 1px solid #87ADE4; - border: 1px; - border-radius: 4px; -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -QDialog{ - background-color: #c4dafa; - -} - -QWidget#chatcentralwidget{ - background-color: #c4dafa; - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/blue/blue.png); - - -} - - -/* Customize the toolbar. */ -QToolBar#toolBarPage { - border-image: url(%THISPATH%/blue/blue.png); - -} - -QToolBar#toolBarAction { - border-image: url(%THISPATH%/blue/blue.png); - -} - -QTabBar::tab { - border-image: url(%THISPATH%/blue/tab1.png); - min-width: 8ex; - padding: 4px; - - -} - -QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - -} - -QTabBar::tab:selected, QTabBar::tab:hover { - - border-image: url(%THISPATH%/blue/tab_hover.png); - - -} - -QTabBar::tab:selected { - border-image: url(%THISPATH%/blue/tabselected.png); -} - -QPushButton#okButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelprefButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelButton { - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - -QPushButton#applyButton { - - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); -} - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); -} - -QStatusBar{ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E3EFFF, stop: 1 #87ADE4); -} - - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/blue/blue.png); - -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/blue/blue.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} -QSplitter#splitter{ - border-image: url(%THISPATH%/blue/blue.png); - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #E3EFFF, stop: 1 #87ADE4); - border: 1px solid #87ADE4; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e3e5ff, stop: 1 #879ae4); - border: 1px solid #879ae4; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - diff --git a/retroshare-gui/src/qss/blue/blue.png b/retroshare-gui/src/qss/blue/blue.png deleted file mode 100644 index 28a723edd..000000000 Binary files a/retroshare-gui/src/qss/blue/blue.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blue/blue2.png b/retroshare-gui/src/qss/blue/blue2.png deleted file mode 100644 index 7671a1649..000000000 Binary files a/retroshare-gui/src/qss/blue/blue2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blue/tab1.png b/retroshare-gui/src/qss/blue/tab1.png deleted file mode 100644 index 68d6960b4..000000000 Binary files a/retroshare-gui/src/qss/blue/tab1.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blue/tab_hover.png b/retroshare-gui/src/qss/blue/tab_hover.png deleted file mode 100644 index 1a5fc3ef4..000000000 Binary files a/retroshare-gui/src/qss/blue/tab_hover.png and /dev/null differ diff --git a/retroshare-gui/src/qss/blue/tabselected.png b/retroshare-gui/src/qss/blue/tabselected.png deleted file mode 100644 index 78a819cb8..000000000 Binary files a/retroshare-gui/src/qss/blue/tabselected.png and /dev/null differ diff --git a/retroshare-gui/src/qss/groove.qss b/retroshare-gui/src/qss/groove.qss deleted file mode 100644 index 51f8d8c4b..000000000 --- a/retroshare-gui/src/qss/groove.qss +++ /dev/null @@ -1,94 +0,0 @@ -.QWidget{ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6799B3, stop: 1 #377a90); -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - - border: 1px solid #4b8598; -} - -HeaderFrame { - -} - -QDialog{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6799B3, stop: 1 #377a90); - -} - -QWidget#chatcentralwidget{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6799B3, stop: 1 #377a90); - - -} - -QToolBar#chattoolBar{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - - border: 1px solid #4b8598; -} - -QFrame#Chatbuttonframe{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - - border: 1px solid #4b8598; -} - -QStatusBar{ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #6799B3, stop: 1 #377a90); - -} - -/* Customize the toolbar. */ -QToolBar { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - - border: 1px solid #4b8598; -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #6799B3, stop: 0.3 #377a90, - stop: 0.31 #0e5e73, stop: 1 #4b8598); - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #719cb2, stop: 0.3 #5e9bab, - stop: 0.31 #0e5e69, stop: 1 #4b9897); - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - - diff --git a/retroshare-gui/src/qss/orangesurfer.qss b/retroshare-gui/src/qss/orangesurfer.qss deleted file mode 100644 index a3c7c6174..000000000 --- a/retroshare-gui/src/qss/orangesurfer.qss +++ /dev/null @@ -1,231 +0,0 @@ -.QWidget { - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); - -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - border-image: url(%THISPATH%/orangesurfer/main.png); -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -QDialog, QMainWindow{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); -} - -QWidget#chatcentralwidget{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/orangesurfer/main.png); - - -} - -/* Customize the toolbar. */ -QToolBar#toolBarPage { - border-image: url(%THISPATH%/orangesurfer/main.png); - -} - -QToolBar#toolBarAction { - border-image: url(%THISPATH%/orangesurfer/main.png); - -} - - -QTabBar::tab { - border-image: url(%THISPATH%/orangesurfer/tab_normal.png); - border-top-left-radius: 4px; - border-top-right-radius: 4px; - min-width: 8ex; - padding: 4px; - - -} - -QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - -} - -QTabBar::tab:selected, QTabBar::tab:hover { - - border-image: url(%THISPATH%/orangesurfer/tab_hover.png); - - -} - -QTabBar::tab:selected { - border-image: url(%THISPATH%/orangesurfer/tab_pressed.png); -} - - -QPushButton#okButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelprefButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelButton { - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - -QPushButton#applyButton { - - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - - -QStatusBar{ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #67768D, stop: 0.4 #EDEEFD); - -} - -QSizeGrip { - image: url(%THISPATH%/orangesurfer/sizegrip.png); - width: 16px; - height: 16px; -} - -QMenu { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #67768D, stop: 0.4 #EDEEFD); - border: 1px solid black; -} - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); -} - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); -} - - -QTreeWidget { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); - - -} -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - - - - border-image: url(%THISPATH%/orangesurfer/border.png); - -} - -QTreeView { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); - - -} - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ - - border-image: url(%THISPATH%/orangesurfer/border.png); - -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/orangesurfer/main.png); - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/orangesurfer/main.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #F7B552, stop: 1 #FF5E07); - border: 1px solid #FF5E07; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fac26e, stop: 1 #f87d3b); - border: 1px solid #f87d3b; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} diff --git a/retroshare-gui/src/qss/orangesurfer/border.png b/retroshare-gui/src/qss/orangesurfer/border.png deleted file mode 100644 index e8bd39f07..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/border.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/main.png b/retroshare-gui/src/qss/orangesurfer/main.png deleted file mode 100644 index 2605e0d4d..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/main.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/main2.png b/retroshare-gui/src/qss/orangesurfer/main2.png deleted file mode 100644 index e977b4812..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/main2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/sizegrip.png b/retroshare-gui/src/qss/orangesurfer/sizegrip.png deleted file mode 100644 index be6cd102c..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/sizegrip.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/tab_hover.png b/retroshare-gui/src/qss/orangesurfer/tab_hover.png deleted file mode 100644 index 1a5fc3ef4..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/tab_hover.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/tab_normal.png b/retroshare-gui/src/qss/orangesurfer/tab_normal.png deleted file mode 100644 index f3a4b4694..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/tab_normal.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/tab_pressed.png b/retroshare-gui/src/qss/orangesurfer/tab_pressed.png deleted file mode 100644 index eeae9b138..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/tab_pressed.png and /dev/null differ diff --git a/retroshare-gui/src/qss/orangesurfer/toolbar.png b/retroshare-gui/src/qss/orangesurfer/toolbar.png deleted file mode 100644 index 2aae1f8ff..000000000 Binary files a/retroshare-gui/src/qss/orangesurfer/toolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle-v2.qss b/retroshare-gui/src/qss/qdarkstyle-v2.qss deleted file mode 100644 index 985143edd..000000000 --- a/retroshare-gui/src/qss/qdarkstyle-v2.qss +++ /dev/null @@ -1,2329 +0,0 @@ -/* QDarkStyleSheet -------------------------------------------------------- - -This is the main style sheet, the palette has nine main colors. -It is based on three selecting colors, three greyish (background) colors -plus three whitish (foreground) colors. Each set of widgets of the same -type have a header like this: - - ------------------ - GroupName -------- - ------------------ - -And each widget is separated with a header like this: - - QWidgetName ------ - -This makes more easy to find and change some css field. The basic -configuration is described bellow. - - SELECTION ------------ - - sel_light #179AE0 #148CD2 (selection/hover/active) - sel_normal #3375A3 #1464A0 (selected) - sel_dark #18465D #14506E (selected disabled) - - FOREGROUND ----------- - - for_light #EFF0F1 #F0F0F0 (texts/labels) - for_normal #AAAAAA (not used yet) - for_dark #505F69 #787878 (disabled texts) - - BACKGROUND ----------- - - bac_light #4D545B #505F69 (unpressed) - bac_normal #31363B #32414B (border, disabled, pressed, checked, toolbars, menus) - bac_dark #232629 #19232D (background) - -If a stranger configuration is required because of a bugfix or anything -else, keep the comment on that line to nobodys changed it, including the -issue number. ---------------------------------------------------------------------------- */ - - - -/* QWidget ---------------------------------------------------------------- */ - -QWidget { - background-color: #19232D; - border: 0px solid #32414B; - padding: 0px; - color: #F0F0F0; - selection-background-color: #1464A0; - selection-color: #F0F0F0; -} -QTreeView::item, QTreeWidget::item, QListWidget::item{ - color: #F0F0F0; -} - -QWidget:disabled { - background-color: #19232D; - color: #787878; - selection-background-color: #14506E; - selection-color: #787878; -} - -QWidget:item:selected { - background-color: #1464A0; -} - -QWidget:item:hover { - background-color: #148CD2; - color: #32414B; -} - -/* QMainWindow ------------------------------------------------------------ */ -/* This adjusts the splitter in the dock widget, not qsplitter */ - - -QMainWindow::separator { - background-color: #32414B; - border: 0 solid #19232D; - spacing: 0; - padding: 2px; -} - -QMainWindow::separator:hover { - background-color: #505F69; - border: 0px solid #148CD2; -} - -QMainWindow::separator:horizontal { - width: 5px; - margin-top: 2px; - margin-bottom: 2px; - image: url(%THISPATH%/qdarkstyle/rc/Vsepartoolbar.png); -} - -QMainWindow::separator:vertical { - height: 5px; - margin-left: 2px; - margin-right: 2px; - image: url(%THISPATH%/qdarkstyle/rc/Hsepartoolbar.png); -} - -/* QToolTip --------------------------------------------------------------- */ - -QToolTip { - background-color: #148CD2; - border: 1px solid #19232D; - color: #19232D; - padding: 0; /*remove padding, for fix combo box tooltip*/ - opacity: 230; /*reducing transparency to read better*/ -} - -/* QStatusBar ------------------------------------------------------------- */ - -QStatusBar { - border: 1px solid #32414B; - background: #32414B; /*fixes spyder #9120,#9121*/ -} - -QStatusBar QToolTip { - background-color: #148CD2; - border: 1px solid #19232D; - color: #19232D; - padding: 0; /*remove padding, for fix combo box tooltip*/ - opacity: 230; /*reducing transparency to read better*/ -} - -QStatusBar QLabel { - background-color: transparent; /*fixes spyder #9120,#9121*/ -} - -/* QCheckBox -------------------------------------------------------------- */ - -QCheckBox { - background-color: #19232D; - color: #F0F0F0; - spacing: 4px; - outline: none; - padding-top: 4px; - padding-bottom: 4px; -} - -QCheckBox:focus { - border: none; -} - -QCheckBox QWidget:disabled { - background-color: #19232D; - color: #787878; -} - -QCheckBox::indicator { - margin-left: 4px; - width: 16px; - height: 16px; -} - -QCheckBox::indicator:unchecked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked.png); -} - -QCheckBox::indicator:unchecked:hover, -QCheckBox::indicator:unchecked:focus, -QCheckBox::indicator:unchecked:pressed { - border: none; - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_focus.png); -} - -QCheckBox::indicator:unchecked:disabled { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_disabled.png); -} - -QCheckBox::indicator:checked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked.png); -} - -QCheckBox::indicator:checked:hover, -QCheckBox::indicator:checked:focus, -QCheckBox::indicator:checked:pressed { - border: none; - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_focus.png); -} - -QCheckBox::indicator:checked:disabled{ - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_disabled.png); -} - -QCheckBox::indicator:indeterminate { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_indeterminate.png); -} - -QCheckBox::indicator:indeterminate:disabled { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_indeterminate_disabled.png); -} - -QCheckBox::indicator:indeterminate:focus, -QCheckBox::indicator:indeterminate:hover, -QCheckBox::indicator:indeterminate:pressed { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_indeterminate_focus.png); -} - -/* QGroupBox -------------------------------------------------------------- */ - -QGroupBox { - font-weight: bold; - border: 1px solid #32414B; - border-radius: 4px; - padding: 4px; - margin-top: 16px; -} - - - -QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top left; - left: 3px; - padding-left: 3px; - padding-right: 5px; - padding-top: 8px; - padding-bottom: 16px; -} - -QGroupBox::indicator { - margin-left: 4px; - width: 16px; - height: 16px; -} - -QGroupBox::indicator { - margin-left: 2px; -} - -QGroupBox::indicator:unchecked:hover, -QGroupBox::indicator:unchecked:focus, -QGroupBox::indicator:unchecked:pressed { - border: none; - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_focus.png); -} - -QGroupBox::indicator:checked:hover, -QGroupBox::indicator:checked:focus, -QGroupBox::indicator:checked:pressed { - border: none; - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_focus.png); -} - -QGroupBox::indicator:checked:disabled { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_disabled.png); -} - -QGroupBox::indicator:unchecked:disabled { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_disabled.png); -} - -/* QRadioButton ----------------------------------------------------------- */ - -QRadioButton { - background-color: #19232D; - color: #F0F0F0; - spacing: 0; - padding: 0; - border: none; - outline: none; -} - -QRadioButton:focus { - border: none; -} - -QRadioButton:disabled { - background-color: #19232D; - color: #787878; - border: none; - outline: none; -} - -QRadioButton QWidget { - background-color: #19232D; - color: #F0F0F0; - spacing: 0px; - padding: 0px; - outline: none; - border: none; -} - -QRadioButton::indicator { - border: none; - outline: none; - margin-bottom: 2px; - width: 25px; - height: 25px; -} - -QRadioButton::indicator:unchecked { - image: url(%THISPATH%/qdarkstyle/rc/radio_unchecked.png); -} - -QRadioButton::indicator:unchecked:hover, -QRadioButton::indicator:unchecked:focus, -QRadioButton::indicator:unchecked:pressed { - border: none; - outline: none; - image: url(%THISPATH%/qdarkstyle/rc/radio_unchecked_focus.png); -} - -QRadioButton::indicator:checked { - border: none; - outline: none; - image: url(%THISPATH%/qdarkstyle/rc/radio_checked.png); -} - -QRadioButton::indicator:checked:hover, -QRadioButton::indicator:checked:focus, -QRadioButton::indicator:checked:pressed { - border: none; - outline: none; - image: url(%THISPATH%/qdarkstyle/rc/radio_checked_focus.png); -} - -QRadioButton::indicator:checked:disabled { - outline: none; - image: url(%THISPATH%/qdarkstyle/rc/radio_checked_disabled.png); -} - -QRadioButton::indicator:unchecked:disabled { - image: url(%THISPATH%/qdarkstyle/rc/radio_unchecked_disabled.png); -} - -/* QMenuBar --------------------------------------------------------------- */ - -QMenuBar { - background-color: #32414B; - padding: 2px; - border: 1px solid #19232D; - color: #F0F0F0; -} - -QMenuBar:focus { - border: 1px solid #148CD2; -} - -QMenuBar::item { - background: transparent; - padding: 4px; -} - -QMenuBar::item:selected { - padding: 4px; - background: transparent; - border: 0px solid #32414B; -} - -QMenuBar::item:pressed { - padding: 4px; - border: 0px solid #32414B; - background-color: #148CD2; - color: #F0F0F0; - margin-bottom: 0px; - padding-bottom: 0px; -} - -/* QMenu ------------------------------------------------------------------ */ - -QMenu { - border: 0px solid #32414B; - color: #F0F0F0; - margin: 0px; -} - -QMenu::separator { - height: 2px; - background-color: #505F69; - color: #F0F0F0; - padding-left: 4px; - margin-left: 2px; - margin-right: 2px; -} - -QMenu::icon { - margin: 0px; - padding-left:4px; -} - -QMenu::item { - padding: 4px 24px 4px 24px; - border: 1px transparent #32414B; /* reserve space for selection border */ -} - -QMenu::item:selected { - color: #F0F0F0; -} - - - -QMenu::indicator { - width: 12px; - height: 12px; - padding-left:6px; -} - -/* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ - -QMenu::indicator:non-exclusive:unchecked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked.png); -} - -QMenu::indicator:non-exclusive:unchecked:selected { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_disabled.png); -} - -QMenu::indicator:non-exclusive:checked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked.png); -} - -QMenu::indicator:non-exclusive:checked:selected { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_disabled.png); -} - -/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ - -QMenu::indicator:exclusive:unchecked { - image: url(%THISPATH%/qdarkstyle/rc/radio_unchecked.png); -} - -QMenu::indicator:exclusive:unchecked:selected { - image: url(%THISPATH%/qdarkstyle/rc/radio_unchecked_disabled.png); -} - -QMenu::indicator:exclusive:checked { - image: url(%THISPATH%/qdarkstyle/rc/radio_checked.png); -} - -QMenu::indicator:exclusive:checked:selected { - image: url(%THISPATH%/qdarkstyle/rc/radio_checked_disabled.png); -} - -QMenu::right-arrow { - margin: 5px; - image: url(%THISPATH%/qdarkstyle/rc/right_arrow.png) -} - -/* QAbstractItemView ------------------------------------------------------ */ - -QAbstractItemView { - alternate-background-color: #19232D; - color: #F0F0F0; - border: 1px solid #32414B; - border-radius: 4px; -} - -QAbstractItemView QLineEdit { - padding: 2px; -} - -/* QAbstractScrollArea ---------------------------------------------------- */ - -QAbstractScrollArea { - background-color: #19232D; - border: 1px solid #32414B; - border-radius: 4px; - padding: 4px; - color: #F0F0F0; -} - -QAbstractScrollArea:disabled { - color: #787878; -} - -/* QScrollArea ------------------------------------------------------------ */ - -QScrollArea QWidget QWidget:disabled { - background-color: #19232D; -} - -/* QScrollBar ------------------------------------------------------------- */ - -QScrollBar:horizontal { - height: 16px; - margin: 2px 16px 2px 16px; - border: 1px solid #32414B; - border-radius: 4px; - background-color: #19232D; -} - -QScrollBar::handle:horizontal { - background-color: #787878; - border: 1px solid #32414B; - border-radius: 4px; - min-width: 8px; - -} - -QScrollBar::handle:horizontal:hover { - background-color: #148CD2; - border: 1px solid #148CD2; - border-radius: 4px; - min-width: 8px; -} - -QScrollBar::add-line:horizontal { - margin: 0px 0px 0px 0px; - border-image: url(%THISPATH%/qdarkstyle/rc/right_arrow_disabled.png); - width: 10px; - height: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal { - margin: 0px 3px 0px 3px; - border-image: url(%THISPATH%/qdarkstyle/rc/left_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal:hover, -QScrollBar::add-line:horizontal:on { - border-image: url(%THISPATH%/qdarkstyle/rc/right_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover, -QScrollBar::sub-line:horizontal:on { - border-image: url(%THISPATH%/qdarkstyle/rc/left_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:horizontal, -QScrollBar::down-arrow:horizontal { - background: none; -} - -QScrollBar::add-page:horizontal, -QScrollBar::sub-page:horizontal { - background: none; -} - -QScrollBar:vertical { - background-color: #19232D; - width: 16px; - margin: 16px 2px 16px 2px; - border: 1px solid #32414B; - border-radius: 4px; -} - -QScrollBar::handle:vertical { - background-color: #787878; - border: 1px solid #32414B; - min-height: 8px; - border-radius: 4px; -} - -QScrollBar::handle:vertical:hover { - background-color: #148CD2; - border: 1px solid #148CD2; - border-radius: 4px; - min-height: 8px; - -} - -QScrollBar::sub-line:vertical { - margin: 3px 0px 3px 0px; - border-image: url(%THISPATH%/qdarkstyle/rc/up_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical { - margin: 3px 0px 3px 0px; - border-image: url(%THISPATH%/qdarkstyle/rc/down_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover, -QScrollBar::sub-line:vertical:on { - border-image: url(%THISPATH%/qdarkstyle/rc/up_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical:hover, -QScrollBar::add-line:vertical:on { - border-image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:vertical, -QScrollBar::down-arrow:vertical { - background: none; -} - -QScrollBar::add-page:vertical, -QScrollBar::sub-page:vertical { - background: none; -} - -/* QTextEdit--------------------------------------------------------------- */ - -QTextEdit { - background-color: #19232D; - color: #F0F0F0; - border: 1px solid #32414B; -} - -QTextEdit:hover { - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QTextEdit:selected { - background: #1464A0; - color: #32414B; -} - -/* QPlainTextEdit --------------------------------------------------------- */ - -QPlainTextEdit { - background-color: #19232D; - color: #F0F0F0; - border-radius: 4px; - border: 1px solid #32414B; -} - -QPlainTextEdit:hover { - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QPlainTextEdit:selected { - background: #1464A0; - color: #32414B; -} - -/* QSizeGrip --------------------------------------------------------------- */ - -QSizeGrip { - image: url(%THISPATH%/qdarkstyle/rc/sizegrip.png); - width: 12px; - height: 12px; -} - -/* QStackedWidget --------------------------------------------------------- */ - -QStackedWidget { - padding: 4px; - border: 1px solid #32414B; - border: 1px solid #19232D; -} - -/* QToolBar --------------------------------------------------------------- */ - -QToolBar { - background-color: #32414B; - border-bottom: 1px solid #19232D; - padding: 2px; - font-weight: bold; -} - -QToolBar QToolButton{ - background-color: #32414B; -} - -QToolBar::handle:horizontal { - width: 6px; - image: url(%THISPATH%/qdarkstyle/rc/Hmovetoolbar.png); -} - -QToolBar::handle:vertical { - height: 6px; - image: url(%THISPATH%/qdarkstyle/rc/Vmovetoolbar.png); -} - -QToolBar::separator:horizontal { - width: 3px; - image: url(%THISPATH%/qdarkstyle/rc/Hsepartoolbar.png); -} - -QToolBar::separator:vertical { - height: 3px; - image: url(%THISPATH%/qdarkstyle/rc/Vsepartoolbar.png); -} - -QToolButton#qt_toolbar_ext_button { - background: #32414B; - border: 0px; - color: #F0F0F0; - image: url(%THISPATH%/qdarkstyle/rc/right_arrow.png); -} - -/* QAbstractSpinBox ------------------------------------------------------- */ - -QAbstractSpinBox { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - padding-top: 2px; /* This fix 103, 111*/ - padding-bottom: 2px; /* This fix 103, 111*/ - padding-left: 4px; - padding-right: 4px; - border-radius: 4px; - /* min-width: 5px; removed to fix 109 */ -} - -QAbstractSpinBox:up-button { - background-color: transparent #19232D; - subcontrol-origin: border; - subcontrol-position: top right; - border-left: 1px solid #32414B; - margin: 1px; -} - -QAbstractSpinBox::up-arrow, -QAbstractSpinBox::up-arrow:disabled, -QAbstractSpinBox::up-arrow:off { - image: url(%THISPATH%/qdarkstyle/rc/up_arrow_disabled.png); - width: 9px; - height: 9px; -} - -QAbstractSpinBox::up-arrow:hover { - image: url(%THISPATH%/qdarkstyle/rc/up_arrow.png); -} - -QAbstractSpinBox:down-button { - background-color: transparent #19232D; - subcontrol-origin: border; - subcontrol-position: bottom right; - border-left: 1px solid #32414B; - margin: 1px; -} - -QAbstractSpinBox::down-arrow, -QAbstractSpinBox::down-arrow:disabled, -QAbstractSpinBox::down-arrow:off { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow_disabled.png); - width: 9px; - height: 9px; -} - -QAbstractSpinBox::down-arrow:hover { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); -} - -QAbstractSpinBox:hover{ - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QAbstractSpinBox:selected { - background: #1464A0; - color: #32414B; -} - -/* ------------------------------------------------------------------------ */ -/* DISPLAYS --------------------------------------------------------------- */ -/* ------------------------------------------------------------------------ */ - -/* QLabel ----------------------------------------------------------------- */ - -QLabel { - background-color: #19232D; - border: 0px solid #32414B; - padding: 2px; - margin: 0px; - color: #F0F0F0 -} - -QLabel::disabled { - background-color: #19232D; - border: 0px solid #32414B; - color: #787878; -} - -/* QTextBrowser ----------------------------------------------------------- */ - -QTextBrowser { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - border-radius: 4px; -} - -QTextBrowser:disabled { - background-color: #19232D; - border: 1px solid #32414B; - color: #787878; - border-radius: 4px; -} - -QTextBrowser:hover, -QTextBrowser:!hover, -QTextBrowser::selected, -QTextBrowser::pressed { - border: 1px solid #32414B; -} - -/* QGraphicsView --------------------------------------------------------- */ - -QGraphicsView { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - border-radius: 4px; -} - -QGraphicsView:disabled { - background-color: #19232D; - border: 1px solid #32414B; - color: #787878; - border-radius: 4px; -} - -QGraphicsView:hover, -QGraphicsView:!hover, -QGraphicsView::selected, -QGraphicsView::pressed { - border: 1px solid #32414B; -} - -/* QCalendarWidget -------------------------------------------------------- */ - -QCalendarWidget { - border: 1px solid #32414B; - border-radius: 4px; -} - -QCalendarWidget:disabled { - background-color: #19232D; - color: #787878; -} - -/* QLCDNumber ------------------------------------------------------------- */ - -QLCDNumber { - background-color: #19232D; - color: #F0F0F0; -} - -QLCDNumber:disabled { - background-color: #19232D; - color: #787878; -} - -/* QProgressBar ----------------------------------------------------------- */ - -QProgressBar { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - border-radius: 4px; - text-align: center; -} - -QProgressBar:disabled { - background-color: #19232D; - border: 1px solid #32414B; - color: #787878; - border-radius: 4px; - text-align: center; -} - -QProgressBar::chunk { - background-color: #1464A0; - color: #19232D; - border-radius: 4px; -} - -QProgressBar::chunk:disabled { - background-color: #14506E; - color: #787878; - border-radius: 4px; -} - - -/* ------------------------------------------------------------------------ */ -/* BUTTONS ---------------------------------------------------------------- */ -/* ------------------------------------------------------------------------ */ - -/* QPushButton ------------------------------------------------------------ */ - -QPushButton { - background-color: #505F69 ; - border: 1px solid #32414B; - color: #F0F0F0; - border-radius: 4px; - padding: 3px; - outline: none; -} - -QPushButton:disabled { - background-color: #32414B; - border: 1px solid #32414B; - color: #787878; - border-radius: 4px; - padding: 3px; -} - - -QPushButton:checked { - background-color: #32414B; - border: 1px solid #32414B; - border-radius: 4px; - padding: 3px; - outline: none; -} - -QPushButton:checked:disabled { - background-color: #19232D; - border: 1px solid #32414B; - color: #787878; - border-radius: 4px; - padding: 3px; - outline: none; -} - -QPushButton::menu-indicator { - subcontrol-origin: padding; - subcontrol-position: bottom right; - bottom: 4px; - -} - -QPushButton:pressed { - background-color: #19232D; - border: 1px solid #19232D; -} - -QPushButton:hover, -QPushButton:checked:hover{ - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QPushButton:pressed:hover{ - border: 1px solid #1464A0; -} - -QPushButton:selected, -QPushButton:checked:selected{ - background: #1464A0; - color: #32414B; -} - -/* QToolButton ------------------------------------------------------------ */ - -QToolButton { - background-color: transparent; - border: 1px solid #32414B; - border-radius: 4px; - margin: 0px; - padding: 2px; -} - -QToolButton:checked { - background-color: #19232D; - border: 1px solid #19232D; -} - -QToolButton:pressed { - background-color: #19232D; - border: 1px solid #19232D; - -} - -QToolButton:disabled { - border: 1px solid #32414B; -} - -QToolButton:hover, -QToolButton:checked:hover{ - border: 1px solid #148CD2; -} -QToolButton:pressed:hover{ - border: 1px solid #1464A0; -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ - -QToolButton[popupMode="1"] { - padding: 2px; - padding-right: 12px; /* only for MenuButtonPopup */ - border: 1px solid #32414B; /* make way for the popup button */ - border-radius: 4px; -} - -/* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ - -QToolButton[popupMode="2"] { - padding: 2px; - padding-right: 12px; /* only for InstantPopup */ - border: 1px solid #32414B; /* make way for the popup button */ -} - -QToolButton::menu-button { - padding: 2px; - border-radius: 4px; - border: 1px solid #32414B; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - /* 16px width + 4px for border = 20px allocated above */ - width: 16px; - outline: none; -} - -QToolButton::menu-button:hover, -QToolButton::menu-button:checked:hover { - border: 1px solid #148CD2; -} - -QToolButton::menu-indicator { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); - top: -8px; /* shift it a bit */ - left: -4px; /* shift it a bit */ -} - -QToolButton::menu-arrow { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); -} - -QToolButton::menu-arrow:open { - border: 1px solid #32414B; -} - -/* QCommandLinkButton ----------------------------------------------------- */ - -QCommandLinkButton { - background-color: transparent; - border: 1px solid #32414B; - color: #F0F0F0; - border-radius: 4px; - padding: 0px; - margin: 0px; -} - -QCommandLinkButton:disabled { - background-color: transparent; - color: #787878; -} - -/* ------------------------------------------------------------------------ */ -/* INPUTS - NO FIELDS ----------------------------------------------------- */ -/* ------------------------------------------------------------------------ */ - -/* QCombobox -------------------------------------------------------------- */ -QComboBox { - border: 1px solid #32414B; - border-radius: 4px; - selection-background-color: #1464A0; - padding-left: 4px; - padding-right: 4px; - min-height: 1.5em; /* fix #103, #111 */ - /* padding-top: 2px; removed to fix #132 */ - /* padding-bottom: 2px; removed to fix #132 */ - /* min-width: 75px; removed to fix #109 */ -} - -QComboBox QAbstractItemView { - background-color: #19232d; - border-radius: 4px; - border: 1px solid #32414B; - selection-color: #148CD2; - selection-background-color: #32414B; -} - -QComboBox:disabled { - background-color: #19232D; - color: #787878; -} - -QComboBox:hover{ - border: 1px solid #148CD2; -} - -QComboBox:on { - selection-background-color: #19232D; -} - -/* Needed to remove indicator - fix #132 */ -QComboBox::indicator { - background-color:transparent; - selection-background-color:transparent; - color:transparent; - selection-color:transparent; -} - -/* Needed to remove indicator - fix #132 */ -QComboBox::item:alternate { - background: #19232D; -} - -QComboBox::item:checked { - /*font-weight: bold;*/ - background-color: #148CD2; -} - -QComboBox::item:selected { - border: 0px solid transparent; -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border-left-width: 0px; - border-left-color: #32414B; - border-left-style: solid; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QComboBox::down-arrow { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow_disabled.png); -} - -QComboBox::down-arrow:on, -QComboBox::down-arrow:hover, -QComboBox::down-arrow:focus { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); -} - -/* QSlider ---------------------------------------------------------------- */ - -QSlider:disabled { - background: #19232D; -} - -QSlider:focus { - border: none; -} - -QSlider::groove:horizontal { - background: #32414B; - border: 1px solid #32414B; - height: 4px; - margin: 0px; - border-radius: 4px; -} - -QSlider::sub-page:horizontal { - background: #1464A0; - border: 1px solid #32414B; - height: 4px; - margin: 0px; - border-radius: 4px; -} - -QSlider::sub-page:horizontal:disabled { - background: #14506E; -} - -QSlider::handle:horizontal { - background: #787878; - border: 1px solid #32414B; - width: 8px; - height: 8px; - margin: -8px 0; - border-radius: 4px; -} - -QSlider::handle:horizontal:hover { - background: #148CD2; - border: 1px solid #148CD2; -} - -QSlider::groove:vertical { - background: #32414B; - border: 1px solid #32414B; - width: 4px; - margin: 0px; - border-radius: 4px; -} - -QSlider::sub-page:vertical { - background: #1464A0; - border: 1px solid #32414B; - width: 4px; - margin: 0px; - border-radius: 4px; -} - -QSlider::sub-page:vertical:disabled { - background: #14506E; -} - -QSlider::handle:vertical { - background: #787878; - border: 1px solid #32414B; - width: 8px; - height: 8px; - margin: 0 -8px; - border-radius: 4px; -} - -QSlider::handle:vertical:hover { - background: #148CD2; - border: 1px solid #148CD2; -} - -/* QLine ------------------------------------------------------------------ */ - -QLineEdit { - background-color: #19232D; - padding-top: 2px; /* This QLineEdit fix 103, 111 */ - padding-bottom: 2px; /* This QLineEdit fix 103, 111 */ - padding-left: 4px; - padding-right: 4px; - border-style: solid; - border: 1px solid #32414B; - border-radius: 4px; - color: #F0F0F0; -} - -QLineEdit:disabled { - background-color: #19232D; - color: #787878; -} - -QLineEdit:hover{ - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QLineEdit:selected{ - background: #1464A0; - color: #32414B; -} - -/* QTabWiget -------------------------------------------------------------- */ - -QTabWidget { - padding: 2px; - selection-background-color: #32414B; -} - - -QTabWidget QWidget QWidget /* add wanted borders fix #141, #126, #123 */ -QTabWidget QFrame { - border: 1px solid #32414B; -} - -QTabWidget QLabel { - border: 0px solid #32414B; /* label derived from frame, remove border #141 */ -} - -QTabWidget::pane { - border: 1px solid #32414B; - border-radius: 4px; - padding: 0px; /* fixes double border inside pane wit pyqt5 */ - margin: 0px; -} - -QTabWidget::pane:selected { - background-color: #32414B; - border: 1px solid #1464A0; -} - -/* QTabBar ---------------------------------------------------------------- */ - -QTabBar { - qproperty-drawBase: 0; - border-radius: 4px; - margin: 0px; - padding: 2px; - border: 0; - - /* left: 5px; move to the right by 5px - removed for fix */ - } - -QTabBar::close-button { - border: 0; - margin: 2px; - padding: 0; - image: url(%THISPATH%/qdarkstyle/rc/close.png); -} - -QTabBar::close-button:hover { - image: url(%THISPATH%/qdarkstyle/rc/close-hover.png); -} - -QTabBar::close-button:pressed { - image: url(%THISPATH%/qdarkstyle/rc/close-pressed.png); -} - -/* QTabBar::tab - selected ----------------------------------------------- */ - -QTabBar::tab:top:selected:disabled { - border-bottom: 3px solid #14506E; - color: #787878; - background-color: #32414B; -} - -QTabBar::tab:bottom:selected:disabled { - border-top: 3px solid #14506E; - color: #787878; - background-color: #32414B; -} - -QTabBar::tab:left:selected:disabled { - border-left: 3px solid #14506E; - color: #787878; - background-color: #32414B; -} - -QTabBar::tab:right:selected:disabled { - border-right: 3px solid #14506E; - color: #787878; - background-color: #32414B; -} - -/* QTabBar::tab - !selected and disabled ---------------------------------- */ - -QTabBar::tab:top:!selected:disabled { - border-bottom: 3px solid #19232D; - color: #787878; - background-color: #19232D; -} - -QTabBar::tab:bottom:!selected:disabled { - border-top: 3px solid #19232D; - color: #787878; - background-color: #19232D; -} - -QTabBar::tab:left:!selected:disabled { - border-right: 3px solid #19232D; - color: #787878; - background-color: #19232D; -} - -QTabBar::tab:right:!selected:disabled { - border-left: 3px solid #19232D; - color: #787878; - background-color: #19232D; -} - -/* QTabBar::tab - selected ----------------------------------------------- */ - -QTabBar::tab:top:!selected { - border-bottom: 2px solid #19232D; - margin-top: 2px; -} - -QTabBar::tab:bottom:!selected { - border-top: 2px solid #19232D; - margin-bottom: 3px; -} - -QTabBar::tab:left:!selected { - border-left: 2px solid #19232D; - margin-right: 2px; -} - -QTabBar::tab:right:!selected { - border-right: 2px solid #19232D; - margin-left: 2px; -} - - -QTabBar::tab:top { - background-color: #32414B; - color: #F0F0F0; - margin-left: 2px; - padding-left: 4px; - padding-right: 4px; - padding-top: 2px; - padding-bottom: 2px; - min-width: 5px; - border-bottom: 3px solid #32414B; - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} - -QTabBar::tab:top:selected { - background-color: #505F69; - color: #F0F0F0; - border-bottom: 3px solid #1464A0; - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} - -QTabBar::tab:top:!selected:hover { - border: 1px solid #148CD2; - border-bottom: 3px solid #148CD2; - padding: 0px; -} - -QTabBar::tab:bottom { - color: #F0F0F0; - border-top: 3px solid #32414B; - background-color: #32414B; - margin-left: 2px; - padding-left: 4px; - padding-right: 4px; - padding-top: 2px; - padding-bottom: 2px; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - min-width: 5px; -} - -QTabBar::tab:bottom:selected { - color: #F0F0F0; - background-color: #505F69; - border-top: 3px solid #1464A0; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; -} - -QTabBar::tab:bottom:!selected:hover { - border: 1px solid #148CD2; - border-top: 3px solid #148CD2; - padding: 0px; -} - -QTabBar::tab:left { - color: #F0F0F0; - background-color: #32414B; - margin-top: 2px; - padding-left: 2px; - padding-right: 2px; - padding-top: 4px; - padding-bottom: 4px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - min-height: 5px; -} - -QTabBar::tab:left:selected { - color: #F0F0F0; - background-color: #505F69; - border-left: 3px solid #1464A0; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QTabBar::tab:left:!selected:hover { - border: 1px solid #148CD2; - border-left: 3px solid #148CD2; - padding: 0px; -} - -QTabBar::tab:right { - color: #F0F0F0; - background-color: #32414B; - margin-top: 2px; - padding-left: 2px; - padding-right: 2px; - padding-top: 4px; - padding-bottom: 4px; - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; - min-height: 5px; -} - -QTabBar::tab:right:selected { - color: #F0F0F0; - background-color: #505F69; - border-right: 3px solid #1464A0; - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; -} - -QTabBar::tab:right:!selected:hover { - border: 1px solid #148CD2; - border-right: 3px solid #148CD2; - padding: 0px; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(%THISPATH%/qdarkstyle/rc/right_arrow.png); -} - -QTabBar QToolButton::left-arrow:enabled { - image: url(%THISPATH%/qdarkstyle/rc/left_arrow.png); -} - -QTabBar QToolButton::right-arrow:disabled { - image: url(%THISPATH%/qdarkstyle/rc/right_arrow_disabled.png); -} - -QTabBar QToolButton::left-arrow:disabled { - image: url(%THISPATH%/qdarkstyle/rc/left_arrow_disabled.png); -} - -QTabBar QToolButton{ - background-color: #32414B; /* fixes #136 */ - width: 16px; - height: 16px; -} - -/* QDockWiget ------------------------------------------------------------- */ - -QDockWidget { - outline: 1px solid #32414B; - background-color: #19232D; - border: 1px solid #32414B; - border-radius: 4px; - titlebar-close-icon: url(%THISPATH%/qdarkstyle/rc/close.png); - titlebar-normal-icon: url(%THISPATH%/qdarkstyle/rc/undock.png); -} - -QDockWidget::title { - padding: 6px; /* better size for title bar */ - border: none; - background-color: #32414B; -} - -QDockWidget::close-button { - background-color: #32414B; - border-radius: 4px; - border: none; -} - -QDockWidget::close-button:hover { - border: 1px solid #32414B; -} - -QDockWidget::close-button:pressed { - border: 1px solid #32414B; -} - -QDockWidget::float-button { - background-color: #32414B; - border-radius: 4px; - border: none; -} - -QDockWidget::float-button:hover { - border: 1px solid #32414B; -} - -QDockWidget::float-button:pressed { - border: 1px solid #32414B; -} - - -/* QTreeView QTableView QListView ----------------------------------------- */ - -QTreeView:branch:selected, -QTreeView:branch:hover { - background: url(%THISPATH%/qdarkstyle/rc/transparent.png); -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/rc/transparent.png); -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/rc/transparent.png); -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/rc/transparent.png); -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - image: url(%THISPATH%/qdarkstyle/rc/branch_closed.png); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - image: url(%THISPATH%/qdarkstyle/rc/branch_open.png); -} - -QTreeView::branch:has-children:!has-siblings:closed:hover, -QTreeView::branch:closed:has-children:has-siblings:hover { - image: url(%THISPATH%/qdarkstyle/rc/branch_closed-on.png); -} - -QTreeView::branch:open:has-children:!has-siblings:hover, -QTreeView::branch:open:has-children:has-siblings:hover { - image: url(%THISPATH%/qdarkstyle/rc/branch_open-on.png); -} - -QListView::item:!selected:hover, -QTreeView::item:!selected:hover, -QTableView::item:!selected:hover, -QColumnView::item:!selected:hover { - outline: 0; - color: #148CD2; - background-color: #32414B; -} - -QListView::item:selected:hover, -QTreeView::item:selected:hover, -QTableView::item:selected:hover, -QColumnView::item:selected:hover { - background: #1464A0; - color: #19232D; -} - -QTreeView::indicator:checked, -QListView::indicator:checked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked.png); -} - -QTreeView::indicator:unchecked, -QListView::indicator:unchecked { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked.png); -} - -QTreeView::indicator:checked:hover, -QTreeView::indicator:checked:focus, -QTreeView::indicator:checked:pressed, -QListView::indicator:checked:hover, -QListView::indicator:checked:focus, -QListView::indicator:checked:pressed { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_checked_focus.png); -} - -QTreeView::indicator:unchecked:hover, -QTreeView::indicator:unchecked:focus, -QTreeView::indicator:unchecked:pressed, -QListView::indicator:unchecked:hover, -QListView::indicator:unchecked:focus, -QListView::indicator:unchecked:pressed { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_unchecked_focus.png); -} - -QTreeView::indicator:indeterminate:hover, -QTreeView::indicator:indeterminate:focus, -QTreeView::indicator:indeterminate:pressed, -QListView::indicator:indeterminate:hover, -QListView::indicator:indeterminate:focus, -QListView::indicator:indeterminate:pressed { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_indeterminate_focus.png); -} - -QTreeView::indicator:indeterminate, -QListView::indicator:indeterminate { - image: url(%THISPATH%/qdarkstyle/rc/checkbox_indeterminate.png); -} - -QListView, -QTreeView, -QTableView, -QColumnView { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - gridline-color: #32414B; - border-radius: 4px; -} - -QListView:disabled, -QTreeView:disabled, -QTableView:disabled, -QColumnView:disabled { - background-color: #19232D; - color: #787878; -} - -QListView:selected, -QTreeView:selected, -QTableView:selected, -QColumnView:selected { - background: #1464A0; - color: #32414B; -} - -QListView:hover, -QTreeView::hover, -QTableView::hover, -QColumnView::hover { - background-color: #19232D; - border: 1px solid #148CD2; -} - -QListView::item:pressed, -QTreeView::item:pressed, -QTableView::item:pressed, -QColumnView::item:pressed { - background-color: #1464A0; -} - -QListView::item:selected:active, -QTreeView::item:selected:active, -QTableView::item:selected:active, -QColumnView::item:selected:active { - background-color: #1464A0; -} - -QTableCornerButton::section { - background-color: #19232D; - border: 1px transparent #32414B; - border-radius: 0px; -} - -/* QHeaderView ------------------------------------------------------------ */ - -QHeaderView { - background-color: #32414B; - border: 0px transparent #32414B; - padding: 0px; - margin: 0px; - border-radius: 0px; -} - -QHeaderView:disabled { - background-color: #32414B; - border: 1px transparent #32414B; - padding: 2px; -} - -QHeaderView::section { - background-color: #32414B; - color: #F0F0F0; - padding: 2px; - border-radius: 0px; - text-align: left; -} - -QHeaderView::section:checked { - color: #F0F0F0; - background-color: #1464A0; -} - -QHeaderView::section:checked:disabled { - color: #787878; - background-color: #14506E; -} - -QHeaderView::section::horizontal:disabled, -QHeaderView::section::vertical:disabled { - color: #787878; -} - -QHeaderView::section::vertical::first, -QHeaderView::section::vertical::only-one { - border-top: 1px solid #32414B; -} - -QHeaderView::section::vertical { - border-top: 1px solid #19232D; -} - -QHeaderView::section::horizontal::first, -QHeaderView::section::horizontal::only-one { - border-left: 1px solid #32414B; -} - -QHeaderView::section::horizontal { - border-left: 1px solid #19232D; -} - -/* Those settings (border/width/height/background-color) solve bug */ -/* transparent arrow background and size */ - -QHeaderView::down-arrow { - background-color: #32414B; - width: 16px; - height: 16px; - border-right: 1px solid #19232D; - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); -} - -QHeaderView::up-arrow { - background-color: #32414B; - width: 16px; - height: 16px; - border-right: 1px solid #19232D; - image: url(%THISPATH%/qdarkstyle/rc/up_arrow.png); -} - -/* QToolBox -------------------------------------------------------------- */ - -QToolBox { - padding: 0px; - border: 1px solid #32414B; -} - -QToolBox::selected { - padding: 0px; - border: 2px solid #1464A0; -} - -QToolBox::tab { - background-color: #19232D; - border: 1px solid #32414B; - color: #F0F0F0; - border-top-left-radius: 4px; - border-top-right-radius: 4px; -} - -QToolBox::tab:disabled { - color: #787878; -} - -QToolBox::tab:selected { - background-color: #505F69; - border-bottom: 2px solid #1464A0; -} - -QToolBox::tab:!selected { - background-color: #32414B; - border-bottom: 2px solid #32414B; -} - -QToolBox::tab:selected:disabled { - background-color: #32414B; - border-bottom: 2px solid #14506E; -} - -QToolBox::tab:!selected:disabled { - background-color: #19232D; -} - -QToolBox::tab:hover { - border-color: #148CD2; - border-bottom: 2px solid #148CD2; -} - -QToolBox QScrollArea QWidget QWidget { - padding: 0px; - background-color: #19232D; -} - -/* QFrame ----------------------------------------------------------------- */ - -QFrame { - border-radius: 4px; - border: 1px solid #32414B; - -} - -QFrame[frameShape="0"] { - border-radius: 4px; - border: 1px transparent #32414B; -} - -QFrame[height="3"], -QFrame[width="3"] { - background-color: #19232D; -} - -/* QSplitter -------------------------------------------------------------- */ - -QSplitter { - background-color: #32414B; - spacing: 0; - padding: 0; - margin: 0; -} - -QSplitter::separator { - background-color: #32414B; - border: 0 solid #19232D; - spacing: 0; - padding: 1px; - margin: 0; -} - -QSplitter::separator:hover { - background-color: #787878; -} - -QSplitter::separator:horizontal { - width: 5px; - image: url(%THISPATH%/qdarkstyle/rc/Vsepartoolbar.png); -} - -QSplitter::separator:vertical { - height: 5px; - image: url(%THISPATH%/qdarkstyle/rc/Hsepartoolbar.png); -} - - -/* QDateEdit-------------------------------------------------------------- */ - -QDateEdit { - selection-background-color: #1464A0; - border-style: solid; - border: 1px solid #32414B; - border-radius: 4px; - padding-top: 2px; /* This fix #103, #111*/ - padding-bottom: 2px; /* This fix #103, #111*/ - padding-left: 4px; - padding-right: 4px; - min-width: 10px; -} - -QDateEdit:on { - selection-background-color: #1464A0; -} - -QDateEdit::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right; - width: 20px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QDateEdit::down-arrow { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow_disabled.png); -} - -QDateEdit::down-arrow:on, -QDateEdit::down-arrow:hover, -QDateEdit::down-arrow:focus { - image: url(%THISPATH%/qdarkstyle/rc/down_arrow.png); -} - -QDateEdit QAbstractItemView { - background-color: #19232D; - border-radius: 4px; - border: 1px solid #32414B; - selection-background-color: #1464A0; -} - -QAbstractView:hover{ - border: 1px solid #148CD2; - color: #F0F0F0; -} - -QAbstractView:selected { - background: #1464A0; - color: #32414B; -} - - -PlotWidget { - padding: 0px; /* to fix cut labels in plots #134 */ -} - -NewFriendList { - qproperty-textColorStatusAway: #4040A0; - qproperty-textColorStatusBusy: #A04040; - qproperty-textColorStatusOnline: #40A040; - qproperty-textColorStatusInactive: #A0A040; - qproperty-textColorStatusOffline: gray; - qproperty-textColorGroup: rgb(123, 123, 123); -} - -NetworkDialog { - qproperty-backgroundColorSelf: darkred; - qproperty-backgroundColorOwnSign: darkred; - qproperty-backgroundColorAcceptConnection: black; - qproperty-backgroundColorHasSignedMe: darkred; - qproperty-backgroundColorDenied: #201F1F; -} - -RSTreeWidget#idTreeWidget::item:!selected { - color: #C0C0C0; -} - -GxsChannelPostItem > QFrame#mainFrame[new=true] { - border: 3px solid #82B9F4; - border-radius: 10px; -} - -GxsForumThreadWidget QPushButton#forumName -{ - qproperty-fontSizeFactor: 140; - color: #0099cc; - font-size: 14pt; - font: bold; -} - -ForumsDialog, GxsForumThreadWidget -{ - qproperty-textColorRead: darkgray; - qproperty-textColorUnread: white; - qproperty-textColorUnreadChildren: red; - qproperty-textColorNotSubscribed: white; - qproperty-textColorMissing: darkred; - qproperty-textColorPinned: #D07000; - - qproperty-backgroundColorPinned: #19232D; - qproperty-backgroundColorFiltered: darkGreen; -} - -GxsForumThreadWidget QWidget#threadTreeWidget { - selection-background-color: #005599; - show-decoration-selected: 1; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item { - padding: 2px; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { - background-color: #005599; -} - -QTreeView [new=true]{ - color: #0099cc; - -} - -/* changes for the subscribe Button */ - -PostedListWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed { - background: #03b1f3; - border-radius: 4px; - border: 1px solid gray; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled { - background: gray; - border-radius: 4px; - border: 1px solid gray; - color: lightgray; -} - -/* only for MenuButtonPopup */ -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"] { - padding-right: 0px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow { - image: none; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button { - image: none; - -} - -CreateGxsChannelMsg QPushButton#postButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -CreateGxsChannelMsg QPushButton#postButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -CreateCircleDialog QPushButton#createButton, CreateLobbyDialog QPushButton#createButton, -IdEditDialog QPushButton#createButton, CreateGxsForumMsg QPushButton#postButton, -GxsCreateCommentDialog QPushButton#postButton, GxsGroupDialog QPushButton#createButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -CreateCircleDialog QPushButton#createButton:hover, CreateLobbyDialog QPushButton#createButton:hover, -IdEditDialog QPushButton#createButton:hover, CreateGxsForumMsg QPushButton#postButton:hover, -GxsCreateCommentDialog QPushButton#postButton:hover, GxsGroupDialog QPushButton#createButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -CreateGxsForumMsg QPushButton#postButton:disabled, PostedCreatePostDialog QPushButton#submitButton:disabled, -CreateGxsChannelMsg QPushButton#postButton:disabled, GxsCreateCommentDialog QPushButton#postButton:disabled { - font: bold; - font-size: 12pt; - color: white; - background: #d40000; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -QTabBar#smTab::tab{ - height: 32px; - width: 32px; -} - -QLabel#avatarLabel{ - border: 2px solid #CCCCCC; - border-radius: 4px; -} - -PostedCreatePostDialog QPushButton#submitButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - min-width: 2em; - -} - -PostedCreatePostDialog QPushButton#submitButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 2em; - -} - -BoardPostDisplayWidget_compact QFrame#mainFrame { - border-radius: 4px; - border: 1px solid #32414B; - background-color: #19232D; -} - -BoardPostDisplayWidget_compact QFrame#mainFrame [new=false]{ - background: #19232D; -} - -BoardPostDisplayWidget_compact QFrame#mainFrame[new=true] { - background-color: #1464a0; -} - -GxsChannelPostItem QFrame#mainFrame { - border-radius: 4px; - border: 1px solid #32414B; - background-color: #19232D; -} - -GxsChannelPostItem QLabel#subjectLabel, GxsChannelPostItem QLabel#titleLabel { - font: 12pt; - font: bold italic; -} - -BoardPostDisplayWidget_compact QPushButton#shareButton { - background-color: transparent; - min-width: 80px; - max-height: 22px; -} - -BoardPostDisplayWidget_compact QFrame#voteFrame { - background: #141415; -} - -BoardPostDisplayWidget_compact QToolButton#voteDownButton, QToolButton#voteUpButton, -BoardPostDisplayWidget_card QToolButton#voteDownButton, QToolButton#voteUpButton -{ - border: none; -} - -BoardPostDisplayWidget_compact QLabel#pictureLabel{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -BoardPostDisplayWidget_compact QLabel#scoreLabel, QLabel#titleLabel, QLabel#fromBoldLabel , QLabel#fromLabel, QLabel#dateLabel, -BoardPostDisplayWidget_card QLabel#scoreLabel, QLabel#titleLabel{ - background-color: transparent; -} - -BoardPostDisplayWidget_compact QLabel#newLabel, -BoardPostDisplayWidget_card QLabel#newLabel { - border: 1px solid #00B712; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712); - border-radius: 3px; - color: black; -} - -BoardPostDisplayWidget_card QPushButton#shareButton{ - background-color: transparent; - min-width: 80px; - max-height: 22px; -} - -BoardPostDisplayWidget_card QFrame#voteFrame { - background: #141415; -} - -BoardPostDisplayWidget_card QFrame#mainFrame { - background-color: #19232D; -} - -BoardPostDisplayWidget_card QFrame#mainFrame [new=false]{ - background: #19232D; -} - -BoardPostDisplayWidget_card QFrame#mainFrame[new=true] { - background-color: #1464a0; -} - -BoardPostDisplayWidget_compact QLabel#titleLabel, -BoardPostDisplayWidget_card QLabel#titleLabel{ - font-size: 14pt; - font: bold; -} - -GxsForumMsgItem QFrame#frame{ - background-color: #19232D; -} - -PostedItem QFrame#mainFrame{ - background: #19232D; -} - -WireGroupItem QFrame#wire_frame{ - background: transparent; -} - -GxsChannelDialog GroupTreeWidget QTreeWidget#treeWidget::item{ - /*background-color: #F00000;*/ - /*padding: 2px;*/ -} - -RSTextBrowser, MimeTextEdit -{ - /*qproperty-textColorQuote: rgb(125, 125, 255);*/ - qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); -} - -PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame { - border: 2px solid #38444d; - border-radius: 6px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - -ChatLobbyWidget QTreeWidget#lobbyTreeWidget{ - font-size: 10pt; -} - -NewFriendList QTreeView#peerTreeWidget { - font-size: 12pt; -} - -ChannelsCommentsItem QFrame#mainFrame, BoardsCommentsItem QFrame#mainFrame { - background: #19232D; -} - -ChannelsCommentsItem QLabel#newCommentLabel, BoardsCommentsItem QLabel#newCommentLabel { - font: 12pt; - font: bold; -} - -ChannelsCommentsItem QLabel#subjectLabel, ChannelsCommentsItem QLabel#titleLabel , QLabel#nameLabel { - font: 12pt; - font: bold; -} - -BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel { - font: 12pt; - font: bold; -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -NewFriendList QTreeView#peerTreeWidget { - font-size: 12pt; -} diff --git a/retroshare-gui/src/qss/qdarkstyle.qss b/retroshare-gui/src/qss/qdarkstyle.qss deleted file mode 100644 index 77987ce4f..000000000 --- a/retroshare-gui/src/qss/qdarkstyle.qss +++ /dev/null @@ -1,1558 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) <2013-2014> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -QProgressBar:horizontal { - border: 1px solid #3A3939; - text-align: center; - padding: 1px; - background: #201F1F; - width: 15px; -} -QProgressBar::chunk:horizontal { - background-color: qlineargradient(spread:reflect, x1:1, y1:0.545, x2:1, y2:0, stop:0 rgba(28, 66, 111, 255), stop:1 rgba(37, 87, 146, 255)); - width: 15px; -} - -QFrame#titleBarFrame, QFrame#toolBarFrame -{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #616161, stop: 0.5 #505050, - stop: 0.6 #434343, stop:1 #656565); -} - -QToolTip -{ - border: 1px solid #3A3939; - background-color: rgb(90, 102, 117); - color: white; - padding: 1px; - opacity: 200; -} - -QWidget -{ - color: silver; - background-color: #302F2F; - selection-background-color:#78879b; - selection-color: black; - background-clip: border; - border-image: none; - outline: 0; -} -QTreeView::item, QTreeWidget::item, QListWidget::item{ - color: silver; -} - -QWidget:item:hover -{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #78879b, stop: 1 #78879b); - color: black; -} - -QWidget:item:selected -{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #78879b, stop: 1 #78879b); -} - -QTableWidget::item { - color: #C0C0C0; - background-color: #201F1F; -} - -QTableWidget::item:selected { - color: black; -} - -ForumsDialog, GxsForumThreadWidget -{ - qproperty-textColorRead: darkgray; - qproperty-textColorUnread: white; - qproperty-textColorUnreadChildren: red; - qproperty-textColorNotSubscribed: white; - qproperty-textColorMissing: darkred; - qproperty-textColorPinned: #D07000; - - qproperty-backgroundColorPinned: #202020; - qproperty-backgroundColorFiltered: darkGreen; -} - -QMenuBar -{ - background-color: #302F2F; - color: silver; -} - -QMenuBar::item -{ - background: transparent; -} - -QMenuBar::item:selected -{ - background: transparent; - border: 1px solid #3A3939; -} - -QMenuBar::item:pressed -{ - border: 1px solid #3A3939; - background-color: #78879b; - color: black; - margin-bottom:-1px; - padding-bottom:1px; -} - -QMenu -{ - border: 1px solid #3A3939; - color: silver; - margin: 2px; -} - -QMenu::icon -{ - margin: 5px; -} - -QMenu::item -{ - padding: 5px 30px 5px 30px; - margin-left: 5px; - border: 1px solid transparent; /* reserve space for selection border */ -} - -QMenu::item:selected -{ - color: black; -} - -QWidget:disabled -{ - color: #404040; - background-color: #302F2F; -} - -QAbstractItemView -{ - alternate-background-color: #3A3939; - color: silver; - border: 1px solid 3A3939; - border-radius: 3px; - padding: 1px; -} - -QWidget:focus, QMenuBar:focus -{ - border: 1px solid rgba(48, 86, 111); -} - -QTabWidget:focus, QCheckBox:focus, QRadioButton:focus -{ - border: none; -} - -QLineEdit -{ - background-color: #201F1F; - padding: 2px; - border-style: solid; - border: 1px solid #3A3939; - border-radius: 3px; - color: silver; -} - -QGroupBox { - border:1px solid #3A3939; - border-radius: 7px; - margin-top: 2ex; -} - -QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top center; - padding-left: 10px; - padding-right: 10px; -} - -QAbstractScrollArea -{ - border-radius: 3px; - border: 1px solid #3A3939; -} - -QScrollBar:horizontal -{ - height: 15px; - margin: 0px 11px 0px 11px; - border: 1px solid #3A3939; - border-radius: 6px; - background-color: QLinearGradient( x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #302F2F, stop: 1 #484846); -} - -QScrollBar::handle:horizontal -{ - background-color: QLinearGradient( x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #605F5F, stop: 1 #787876); - min-width: 5px; - border-radius: 5px; -} - -QScrollBar::sub-line:horizontal -{ - border-image: url(%THISPATH%/qdarkstyle/right_arrow_disabled.png); - width: 10px; - height: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - -QScrollBar::add-line:horizontal -{ - border-image: url(%THISPATH%/qdarkstyle/left_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:horizontal:hover,QScrollBar::sub-line:horizontal:on -{ - border-image: url(%THISPATH%/qdarkstyle/right_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: right; - subcontrol-origin: margin; -} - - -QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on -{ - border-image: url(%THISPATH%/qdarkstyle/left_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: left; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal -{ - background: none; -} - - -QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal -{ - background: none; -} - -QScrollBar:vertical -{ - background-color: QLinearGradient( x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 #302F2F, stop: 1 #484846); - width: 15px; - margin: 11px 0 11px 0; - border: 1px solid #3A3939; - border-radius: 6px; -} - -QScrollBar::handle:vertical -{ - background-color: QLinearGradient( x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 #605F5F, stop: 1 #787876); - min-height: 5px; - border-radius: 5px; -} - -QScrollBar::sub-line:vertical -{ - border-image: url(%THISPATH%/qdarkstyle/up_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - -QScrollBar::add-line:vertical -{ - - border-image: url(%THISPATH%/qdarkstyle/down_arrow_disabled.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on -{ - - border-image: url(%THISPATH%/qdarkstyle/up_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: top; - subcontrol-origin: margin; -} - - -QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on -{ - border-image: url(%THISPATH%/qdarkstyle/down_arrow.png); - height: 10px; - width: 10px; - subcontrol-position: bottom; - subcontrol-origin: margin; -} - -QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical -{ - background: none; -} - - -QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical -{ - background: none; -} - -QTextEdit -{ - background-color: #201F1F; - color: silver; - border: 1px solid #3A3939; -} - -QPlainTextEdit -{ - background-color: #201F1F; - color: silver; - border-radius: 3px; - border: 1px solid #3A3939; -} - -QHeaderView::section -{ - background-color: #3A3939; - color: silver; - padding-left: 4px; - border: 1px solid #6c6c6c; -} - -QCheckBox:disabled -{ - color: #404040; -} - -QSizeGrip { - image: url(%THISPATH%/qdarkstyle/sizegrip.png); - width: 12px; - height: 12px; -} - - -QMainWindow::separator -{ - background-color: #302F2F; - color: white; - padding-left: 4px; - spacing: 2px; - border: 1px dashed #3A3939; -} - -QMainWindow::separator:hover -{ - - background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #58677b, - stop:0.5 #78879b stop:1 #58677b); - color: white; - padding-left: 4px; - border: 1px solid #3A3939; - spacing: 2px; -} - - -QMenu::separator -{ - height: 1px; - background-color: #3A3939; - color: white; - padding-left: 4px; - margin-left: 10px; - margin-right: 5px; -} - - - -QRadioButton::indicator:checked, QRadioButton::indicator:unchecked{ - color: #b1b1b1; - background-color: #302F2F; - border: 1px solid silver; - border-radius: 5px; -} - - - -QRadioButton::indicator:checked -{ - background-color: qradialgradient( - cx: 0.5, cy: 0.5, - fx: 0.5, fy: 0.5, - radius: 1.0, - stop: 0.25 #78879b, - stop: 0.3 #302F2F - ); -} - -QCheckBox, QRadioButton -{ - padding: 3px; - outline: none; -} - -QCheckBox::indicator{ - color: #b1b1b1; - background-color: #302F2F; - border: 1px solid silver; - width: 9px; - height: 9px; -} - -QRadioButton::indicator -{ - border-radius: 7px; - width: 9px; - height: 9px; -} - -QCheckBox::indicator:pressed -{ - border: 1px solid #78879b; -} - -QRadioButton::indicator:hover, QCheckBox::indicator:hover -{ - border: 1px solid #78879b; -} - -QCheckBox::indicator:checked -{ - background-color: qradialgradient( - cx: 0.5, cy: 0.5, - fx: 0.5, fy: 0.5, - radius: 1.0, - stop: 0.25 #78879b, - stop: 0.3 #302F2F - ); - -} - -QCheckBox::indicator:disabled, QRadioButton::indicator:disabled -{ - border: 1px solid #444; -} - -QFrame -{ - border-radius: 3px; -} - -QStackedWidget -{ - border: none; -} - -QToolBar { - border: 1px solid #393838; - background: 1px solid #302F2F; - font-weight: bold; -} - -QToolBar::handle:horizontal { - image: url(%THISPATH%/qdarkstyle/Hmovetoolbar.png); -} -QToolBar::handle:vertical { - image: url(%THISPATH%/qdarkstyle/Vmovetoolbar.png); -} -QToolBar::separator:horizontal { - image: url(%THISPATH%/qdarkstyle/Hsepartoolbar.png); -} -QToolBar::separator:vertical { - image: url(%THISPATH%/qdarkstyle/Vsepartoolbars.png); -} - -QPushButton -{ - color: silver; - background-color: QLinearGradient( x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 #302F2F, stop: 1 #484846); - border-width: 1px; - border-color: #4A4949; - border-style: solid; - padding-top: 5px; - padding-bottom: 5px; - padding-left: 5px; - padding-right: 5px; - border-radius: 5px; - outline: none; -} - -QPushButton:disabled -{ - background-color: #302F2F; - border-width: 1px; - border-color: #3A3939; - border-style: solid; - padding-top: 5px; - padding-bottom: 5px; - padding-left: 10px; - padding-right: 10px; - /*border-radius: 3px;*/ - color: #454545; -} - -QComboBox -{ - selection-background-color: #78879b; - background-color: #201F1F; - border-style: solid; - border: 1px solid #3A3939; - border-radius: 3px; - padding: 2px; - min-width: 75px; -} - -QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover -{ - border: 1px solid #78879b; - color: silver; -} - -QComboBox:on -{ - background-color: #626873; - padding-top: 3px; - padding-left: 4px; - selection-background-color: #4a4a4a; -} - -/* Needed to remove indicator - fix #132 */ -QComboBox::indicator { - background-color:transparent; - selection-background-color:transparent; - color:transparent; - selection-color:transparent; -} - -QComboBox QAbstractItemView -{ - background-color: #201F1F; - border-radius: 3px; - border: 1px solid #3A3939; - selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #78879b, stop: 1 #78879b); -} - -QComboBox::drop-down -{ - subcontrol-origin: padding; - subcontrol-position: top right; - width: 15px; - - border-left-width: 0px; - border-left-color: darkgray; - border-left-style: solid; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QComboBox::down-arrow -{ - image: url(%THISPATH%/qdarkstyle/down_arrow_disabled.png); -} - -QComboBox::down-arrow:on, QComboBox::down-arrow:hover, -QComboBox::down-arrow:focus -{ - image: url(%THISPATH%/qdarkstyle/down_arrow.png); -} - -QPushButton:pressed -{ - background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #302F2F, stop: 1 #484846); -} - -QAbstractSpinBox { - padding-top: 2px; - padding-bottom: 2px; - border: 1px solid #3A3939; - background-color: #201F1F; - color: silver; - border-radius: 3px; - min-width: 75px; -} - -QAbstractSpinBox:up-button -{ - background-color: transparent; - subcontrol-origin: border; - subcontrol-position: center right; -} - -QAbstractSpinBox:down-button -{ - background-color: transparent; - subcontrol-origin: border; - subcontrol-position: center left; -} - -QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { - image: url(%THISPATH%/qdarkstyle/up_arrow_disabled.png); - width: 10px; - height: 10px; -} -QAbstractSpinBox::up-arrow:hover -{ - image: url(%THISPATH%/qdarkstyle/up_arrow.png); -} - - -QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off -{ - image: url(%THISPATH%/qdarkstyle/down_arrow_disabled.png); - width: 10px; - height: 10px; -} -QAbstractSpinBox::down-arrow:hover -{ - image: url(%THISPATH%/qdarkstyle/down_arrow.png); -} - - -QLabel -{ - background-color: transparent; /*fixes spyder #9120,#9121*/ -} - - -QTabWidget::pane { - border: 1px solid #3A3939; -} - -QTabBar -{ - qproperty-drawBase: 0; - padding-right: 15px; -} - -QTabBar:focus -{ - border: 0px transparent black; -} - -QTabBar::close-button { - image: url(%THISPATH%/qdarkstyle/close.png); - background: transparent; - icon-size: 10px; - padding: 5px; -} - -QTabBar::close-button:hover -{ - background: rgba(255, 255, 255, 20); - border-radius: 3px; -} - -QTabBar::close-button:pressed { - padding: 5px 4px 4px 5px; -} - -/* TOP - BOTTOM TABS */ -QTabBar::tab:top { - color: #b1b1b1; - border: 1px solid #3A3939; - background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, - stop:1 #302F2F, stop:0 #5A5959); - padding-left: 5px; - padding-right: 5px; - padding-top: 3px; - padding-bottom: 2px; - margin-right: -1px; - - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} - -QTabBar::tab:bottom { - color: #b1b1b1; - border: 1px solid #3A3939; - background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, - stop:1 #302F2F, stop:0 #5A5959); - padding-left: 5px; - padding-right: 5px; - padding-top: 3px; - padding-bottom: 2px; - margin-right: -1px; - - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; -} - -QTabBar::tab:top:last, QTabBar::tab:bottom:last -{ - margin-right: 0; -} - -QTabBar::tab:top:first:!selected, QTabBar::tab:bottom:first:!selected -{ - margin-left: 0px; -} - -QTabBar::tab:top:!selected -{ - color: #b1b1b1; - margin-top: 3px; - background-color: #302F2F; -} - -QTabBar::tab:top:selected -{ - margin-bottom: 0px; -} - -QTabBar::tab:bottom:!selected -{ - color: #b1b1b1; - margin-bottom: 3px; - background-color: #302F2F; -} - -QTabBar::tab:bottom:selected -{ - margin-top: 0px; -} - -/* LEFT - RIGHT TABS */ -QTabBar::tab:left { - color: #b1b1b1; - border: 1px solid #3A3939; - background-color: QLinearGradient(x1:1, y1:0, x2:0, y2:0, - stop:1 #302F2F, stop:0 #5A5959); - padding-left: 3px; - padding-right: 2px; - padding-top: 5px; - padding-bottom: 5px; - margin-bottom: -1px; - - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; -} - -QTabBar::tab:right { - color: #b1b1b1; - border: 1px solid #3A3939; - background-color: QLinearGradient(x1:0, y1:0, x2:1, y2:0, - stop:1 #302F2F, stop:0 #5A5959); - padding-left: 3px; - padding-right: 2px; - padding-top: 5px; - padding-bottom: 5px; - margin-bottom: -1px; - - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; -} - -QTabBar::tab:left:!selected -{ - color: #b1b1b1; - margin-right: 3px; - background-color: #302F2F; -} - -QTabBar::tab:left:selected -{ - margin-left: 0px; -} - -QTabBar::tab:right:!selected -{ - color: #b1b1b1; - margin-left: 3px; - background-color: #302F2F; -} - -QTabBar::tab:right:selected -{ - margin-right: 0px; -} - -QTabBar QToolButton::right-arrow:enabled { - image: url(%THISPATH%/qdarkstyle/right_arrow.png); - } - - QTabBar QToolButton::left-arrow:enabled { - image: url(%THISPATH%/qdarkstyle/left_arrow.png); - } - -QTabBar QToolButton::right-arrow:disabled { - image: url(%THISPATH%/qdarkstyle/right_arrow_disabled.png); - } - - QTabBar QToolButton::left-arrow:disabled { - image: url(%THISPATH%/qdarkstyle/left_arrow_disabled.png); - } - - -QDockWidget { - border: 1px solid #403F3F; - titlebar-close-icon: url(%THISPATH%/qdarkstyle/close.png); - titlebar-normal-icon: url(%THISPATH%/qdarkstyle/undock.png); -} - -QDockWidget::close-button, QDockWidget::float-button { - border: 1px solid transparent; - border-radius: 3px; - background: transparent; - icon-size: 10px; -} - -QDockWidget::close-button:hover, QDockWidget::float-button:hover { - background: rgba(255, 255, 255, 10); -} - -QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { - padding: 1px -1px -1px 1px; - background: rgba(255, 255, 255, 10); -} - -NewFriendList { - qproperty-textColorStatusAway: #4040A0; - qproperty-textColorStatusBusy: #A04040; - qproperty-textColorStatusOnline: #40A040; - qproperty-textColorStatusInactive: #A0A040; - qproperty-textColorStatusOffline: gray; - qproperty-textColorGroup: rgb(123, 123, 123); -} - -QTreeView, QListView -{ - border: 1px solid #78879b; - background-color: #201F1F; -} - -QTreeView::item { - background-color: #201F1F; -} - -QTreeView::item:selected { - color: black; -} - -RSTreeWidget#idTreeWidget::item:!selected { - color: #C0C0C0; -} - -NetworkDialog { - qproperty-backgroundColorSelf: darkred; - qproperty-backgroundColorOwnSign: darkred; - qproperty-backgroundColorAcceptConnection: black; - qproperty-backgroundColorHasSignedMe: darkred; - qproperty-backgroundColorDenied: #201F1F; -} - -QTreeView:branch:selected, QTreeView:branch:hover -{ - background: url(%THISPATH%/qdarkstyle/transparent.png); -} - -QTreeView::branch:has-siblings:!adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/transparent.png); -} - -QTreeView::branch:has-siblings:adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/transparent.png); -} - -QTreeView::branch:!has-children:!has-siblings:adjoins-item { - border-image: url(%THISPATH%/qdarkstyle/transparent.png); -} - -QTreeView::branch:has-children:!has-siblings:closed, -QTreeView::branch:closed:has-children:has-siblings { - image: url(%THISPATH%/qdarkstyle/branch_closed.png); -} - -QTreeView::branch:open:has-children:!has-siblings, -QTreeView::branch:open:has-children:has-siblings { - image: url(%THISPATH%/qdarkstyle/branch_open.png); -} - -QTreeView::branch:has-children:!has-siblings:closed:hover, -QTreeView::branch:closed:has-children:has-siblings:hover { - image: url(%THISPATH%/qdarkstyle/branch_closed-on.png); - } - -QTreeView::branch:open:has-children:!has-siblings:hover, -QTreeView::branch:open:has-children:has-siblings:hover { - image: url(%THISPATH%/qdarkstyle/branch_open-on.png); - } - -QListView::item:!selected:hover, QTableView::item:!selected:hover, QTreeView::item:!selected:hover { - background: rgba(0, 0, 0, 0); - outline: 0; - color: #FFFFFF; -} - -QListView::item:selected:hover, QTableView::item:selected:hover, QTreeView::item:selected:hover { - background: #78879b; - color: #FFFFFF; -} - -QSlider::groove:horizontal { - border: 1px solid #3A3939; - height: 8px; - background: #201F1F; - margin: 2px 0; - border-radius: 4px; -} - -QSlider::handle:horizontal { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0.0 silver, stop: 0.2 #a8a8a8, stop: 1 #727272); - border: 1px solid #3A3939; - width: 14px; - height: 14px; - margin: -4px 0; - border-radius: 7px; -} - -QSlider::groove:vertical { - border: 1px solid #3A3939; - width: 8px; - background: #201F1F; - margin: 0 0px; - border-radius: 4px; -} - -QSlider::handle:vertical { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 silver, - stop: 0.2 #a8a8a8, stop: 1 #727272); - border: 1px solid #3A3939; - width: 14px; - height: 14px; - margin: 0 -4px; - border-radius: 7px; -} - -QToolButton { - background-color: transparent; - border: 1px solid #3A3939; - border-radius: 3px; - margin: 3px; -} - -QToolButton:pressed, QToolButton::menu-button:pressed { - background-color: #4A4949; - border: 1px solid silver; -} - -QToolButton:hover, QToolButton::menu-button:hover { - background-color: #4A4949; - border: 1px solid gray; -} - -QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ - padding-right: 20px; /* make way for the popup button */ -} - -QToolButton[popupMode="2"] { /* only for MenuButtonPopup */ - padding-right: 10px; /* make way for the popup button */ -} - -/* the subcontrols below are used only in the MenuButtonPopup mode */ -QToolButton::menu-button { - border: 1px solid #3A3939; - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; - /* 16px width + 4px for border = 20px allocated above */ - width: 16px; -} - -QToolButton::menu-arrow { - image: url(%THISPATH%/qdarkstyle/down_arrow.png); -} - -QToolButton::menu-arrow:open { - top: 1px; left: 1px; /* shift it a bit */ -} - -QPushButton::menu-indicator { - subcontrol-origin: padding; - subcontrol-position: bottom right; - -} - -QTableView -{ - border: transparent; - gridline-color: #6c6c6c; - background-color: #201F1F; -} - - -QTableView, QHeaderView -{ - border-radius: 0px; -} - -QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed { - background: #78879b; - color: #FFFFFF; -} - -QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active { - background: #78879b; - color: #FFFFFF; -} - - -QHeaderView -{ - border: 1px transparent; - margin: 0px; - padding: 0px; -} - -QHeaderView::section { - background-color: #3A3939; - color: silver; - padding: 4px; - border: 1px solid #6c6c6c; - border-radius: 0px; - text-align: center; -} - -QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one -{ - border-top: 1px solid #6c6c6c; -} - -QHeaderView::section::vertical -{ - border-top: transparent; -} - -QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one -{ - border-left: 1px solid #6c6c6c; -} - -QHeaderView::section::horizontal -{ - border-left: transparent; -} - - -QHeaderView::section:checked - { - color: white; - background-color: #5A5959; - } - - /* style the sort indicator */ -QHeaderView::down-arrow { - image: url(%THISPATH%/qdarkstyle/down_arrow.png); -} - -QHeaderView::up-arrow { - image: url(%THISPATH%/qdarkstyle/up_arrow.png); -} - - -QTableCornerButton::section { - background-color: #3A3939; - border: 1px solid #3A3939; - border-radius: 0px; -} - -QToolBox::tab { - background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, - stop:1 #302F2F, stop:0 #5A5959); - padding-left: 3px; - padding-right: 2px; - padding-top: 5px; - padding-bottom: 5px; - margin-bottom: -1px; - - border-top-left-radius: 3px; - border-top-right-radius: 3px; - color: darkgray; - } - - QToolBox::tab:selected { /* italicize selected tabs */ - font: italic bold; - color: white; - } - -QStatusBar::item { - border: 1px solid #3A3939; - border-radius: 3px; - } - -/* OpModeStatus need to be at end to overload other values*/ -OpModeStatus { - qproperty-opMode_Full_Color: #007000; - qproperty-opMode_NoTurtle_Color: #000070; - qproperty-opMode_Gaming_Color: #707000; - qproperty-opMode_Minimal_Color: #700000; -} -OpModeStatus[opMode="Full"] { - background: #007000; -} -OpModeStatus[opMode="NoTurtle"] { - background: #000070; -} -OpModeStatus[opMode="Gaming"] { - background: #707000; -} -OpModeStatus[opMode="Minimal"] { - background: #700000; -} - -/*Property Values at end to overwrite other settings*/ - -[new=false] { - background: #202020; -} -[new=true] { - background: #005000; -} - -[WrongValue="true"] { - background-color: #702020; -} - -/* changes for the subscribe Button */ - -PostedListWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton { - font: bold; - font-size: 14pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsForumThreadWidget QWidget#threadTreeWidget { - selection-background-color: #445566; - show-decoration-selected: 1; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item { - padding: 2px; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { - background-color: #445566; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed { - background: #03b1f3; - border-radius: 4px; - border: 1px solid gray; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled { - background: gray; - border-radius: 4px; - border: 1px solid gray; - color: lightgray; -} - -/* only for MenuButtonPopup */ -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"] { - padding-right: 0px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow { - image: none; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button { - image: none; - -} - -GxsChannelPostItem QFrame#mainFrame { - background: #302F2F; -} - -GxsChannelPostItem > QFrame#mainFrame [new=false]{ - background: #302F2F; -} - -GxsChannelPostItem > QFrame#mainFrame[new=true] { - background-color: #005000; -} - -GxsChannelPostItem QLabel#subjectLabel, GxsChannelPostItem QLabel#titleLabel { - font: 12pt; - font: bold italic; -} - -CreateGxsChannelMsg QPushButton#postButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -CreateGxsChannelMsg QPushButton#postButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -CreateCircleDialog QPushButton#createButton, CreateLobbyDialog QPushButton#createButton, -IdEditDialog QPushButton#createButton, CreateGxsForumMsg QPushButton#postButton, -GxsCreateCommentDialog QPushButton#postButton, GxsGroupDialog QPushButton#createButton, -PulseAddDialog QPushButton#pushButton_Post, PulseTopLevel QToolButton#toolButton_follow, -PulseViewGroup QToolButton#toolButton_follow { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -CreateCircleDialog QPushButton#createButton:hover, CreateLobbyDialog QPushButton#createButton:hover, -IdEditDialog QPushButton#createButton:hover, CreateGxsForumMsg QPushButton#postButton:hover, -GxsCreateCommentDialog QPushButton#postButton:hover, GxsGroupDialog QPushButton#createButton:hover, -ShareManager QPushButton#closeButton:hover, PulseAddDialog QPushButton#pushButton_Post:hover, -PulseTopLevel QToolButton#toolButton_follow:hover, PulseViewGroup QToolButton#toolButton_follow:hover{ - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding-left: 6px; - padding-right: 6px; -} - -CreateGxsForumMsg QPushButton#postButton:disabled, PostedCreatePostDialog QPushButton#submitButton:disabled, -CreateGxsChannelMsg QPushButton#postButton:disabled, GxsCreateCommentDialog QPushButton#postButton:disabled, -PulseAddDialog QPushButton#pushButton_Post:disabled { - font: bold; - font-size: 12pt; - color: white; - background: #d40000; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#closeButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#addButton { - font: bold; - font-size: 12pt; - color: white; - background: #32CD32; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 4px; -} - -ShareManager QPushButton#addButton:hover { - background: #5AD75A; - border-radius: 4px; - min-width: 4em; - padding: 4px; -} - -QTabBar#smTab::tab{ - height: 32px; - width: 32px; -} - -QLabel#avatarLabel{ - border: 2px solid #CCCCCC; - border-radius: 4px; -} - -PostedCreatePostDialog QPushButton#submitButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - min-width: 2em; - -} - -PostedCreatePostDialog QPushButton#submitButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 2em; - -} - -GxsForumThreadWidget QPushButton#forumName -{ - qproperty-fontSizeFactor: 140; - color: #0099cc; - font-size: 14pt; - font: bold; -} - -GxsForumMsgItem QFrame#frame{ - background: #302F2F; -} - -PostedItem QFrame#mainFrame{ - background: #302F2F; -} - -BoardPostDisplayWidget_compact QPushButton#shareButton -{ - background-color: transparent; - border: none; - min-width: 75px; - max-height: 22px; -} - -BoardPostDisplayWidget_card QPushButton#shareButton -{ - background-color: transparent; - border: none; - min-width: 75px; -} - -BoardPostDisplayWidget_compact QFrame#voteFrame { - background: #141415; -} - -BoardPostDisplayWidget_card QFrame#voteFrame { - background: #141415; -} - -QPushButton#shareButton:hover, QPushButton#shareButton::menu-button:hover { - background-color: #4A4949; - border: 1px solid gray; -} - -BoardPostDisplayWidget_compact QToolButton#voteDownButton, QToolButton#voteUpButton, QToolButton#expandButton, QToolButton#readButton, -QToolButton#commentButton, QToolButton#notesButton -{ - border: none; -} - -BoardPostDisplayWidget_compact QLabel#pictureLabel{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -BoardPostDisplayWidget_compact > QFrame#frame [new=false]{ - background: #302F2F; -} - -BoardPostDisplayWidget_compact > QFrame#frame[new=true] { - background-color: #005000; -} - -BoardPostDisplayWidget_card QToolButton#voteDownButton, QToolButton#voteUpButton -{ - border: none; -} - -BoardPostDisplayWidget_card QFrame#frame{ - background: #302F2F; -} - -BoardPostDisplayWidget_card > QFrame#frame [new=false]{ - background: #302F2F; -} - -BoardPostDisplayWidget_card > QFrame#frame[new=true] { - background-color: #005000; -} - -BoardPostDisplayWidget_compact QLabel#newLabel { - border: 1px solid #00B712; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712); - border-radius: 3px; - color: black; -} - -BoardPostDisplayWidget_card QLabel#newLabel { - border: 1px solid #00B712; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #5AFF15, stop: 1 #00B712); - border-radius: 3px; - color: black; -} - -BoardPostDisplayWidget_compact QLabel#titleLabel, -BoardPostDisplayWidget_card QLabel#titleLabel{ - font-size: 14pt; - font: bold; -} - -WireGroupItem QFrame#wire_frame -{ - border: 1px solid #38444d; - background: transparent; -} - -PulseReply #line_replyLine , PulseMessage #line{ - color: #38444d; -} - -RSTextBrowser, MimeTextEdit -{ - /*qproperty-textColorQuote: rgb(125, 125, 255);*/ - qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); -} - -PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame { - border: 2px solid #38444d; - border-radius: 6px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - -PhotoShare QPushButton#pushButton_YourAlbums, QPushButton#pushButton_SubscribedAlbums, -QPushButton#pushButton_SharedAlbums { - font-size: 12pt; -} - -PhotoItem QFrame#photoFrame{ - border: 2px solid #3A3939; -} - -AlbumItem QFrame#albumFrame { - border: 2px solid #3A3939; - border-radius: 10px -} - -ChannelsCommentsItem QFrame#mainFrame, BoardsCommentsItem QFrame#mainFrame { - background: #302F2F; -} - -ChannelsCommentsItem QLabel#newCommentLabel, BoardsCommentsItem QLabel#newCommentLabel { - font: 12pt; - font: bold; -} - -ChannelsCommentsItem QLabel#subjectLabel, ChannelsCommentsItem QLabel#titleLabel , QLabel#nameLabel { - font: 12pt; - font: bold; -} - -BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel { - font: 12pt; - font: bold; -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -NewFriendList QTreeView#peerTreeWidget { - font-size: 12pt; -} diff --git a/retroshare-gui/src/qss/qdarkstyle/Hmovetoolbar.png b/retroshare-gui/src/qss/qdarkstyle/Hmovetoolbar.png deleted file mode 100644 index 520c3aac3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/Hmovetoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/Hsepartoolbar.png b/retroshare-gui/src/qss/qdarkstyle/Hsepartoolbar.png deleted file mode 100644 index 401bfb40a..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/Hsepartoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/Vmovetoolbar.png b/retroshare-gui/src/qss/qdarkstyle/Vmovetoolbar.png deleted file mode 100644 index 512edcecd..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/Vmovetoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/Vsepartoolbar.png b/retroshare-gui/src/qss/qdarkstyle/Vsepartoolbar.png deleted file mode 100644 index d9dc1561b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/Vsepartoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/branch_closed-on.png b/retroshare-gui/src/qss/qdarkstyle/branch_closed-on.png deleted file mode 100644 index d081e9b3b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/branch_closed-on.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/branch_closed.png b/retroshare-gui/src/qss/qdarkstyle/branch_closed.png deleted file mode 100644 index d652159a3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/branch_closed.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/branch_open-on.png b/retroshare-gui/src/qss/qdarkstyle/branch_open-on.png deleted file mode 100644 index ec372b27d..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/branch_open-on.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/branch_open.png b/retroshare-gui/src/qss/qdarkstyle/branch_open.png deleted file mode 100644 index 66f8e1ac6..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/branch_open.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/checkbox.png b/retroshare-gui/src/qss/qdarkstyle/checkbox.png deleted file mode 100644 index b4a9aa3b5..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/checkbox.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/close.png b/retroshare-gui/src/qss/qdarkstyle/close.png deleted file mode 100644 index ffdec9a14..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/close.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/down_arrow.png b/retroshare-gui/src/qss/qdarkstyle/down_arrow.png deleted file mode 100644 index e271f7f90..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/down_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/down_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/down_arrow_disabled.png deleted file mode 100644 index 5805d9842..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/down_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/left_arrow.png b/retroshare-gui/src/qss/qdarkstyle/left_arrow.png deleted file mode 100644 index f808d2d72..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/left_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/left_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/left_arrow_disabled.png deleted file mode 100644 index f5b9af8a3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/left_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/Hmovetoolbar.png b/retroshare-gui/src/qss/qdarkstyle/rc/Hmovetoolbar.png deleted file mode 100644 index cead99ed1..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/Hmovetoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/Hsepartoolbar.png b/retroshare-gui/src/qss/qdarkstyle/rc/Hsepartoolbar.png deleted file mode 100644 index 7f183c8b3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/Hsepartoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/Vmovetoolbar.png b/retroshare-gui/src/qss/qdarkstyle/rc/Vmovetoolbar.png deleted file mode 100644 index ac6a655e2..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/Vmovetoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/Vsepartoolbar.png b/retroshare-gui/src/qss/qdarkstyle/rc/Vsepartoolbar.png deleted file mode 100644 index 7bf62f168..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/Vsepartoolbar.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed-on.png b/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed-on.png deleted file mode 100644 index d081e9b3b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed-on.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed.png b/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed.png deleted file mode 100644 index d652159a3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/branch_closed.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/branch_open-on.png b/retroshare-gui/src/qss/qdarkstyle/rc/branch_open-on.png deleted file mode 100644 index ec372b27d..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/branch_open-on.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/branch_open.png b/retroshare-gui/src/qss/qdarkstyle/rc/branch_open.png deleted file mode 100644 index 66f8e1ac6..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/branch_open.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked.png deleted file mode 100644 index 4007c2ed3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked@2x.png deleted file mode 100644 index b9c3204f1..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled.png deleted file mode 100644 index 4762561b3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled@2x.png deleted file mode 100644 index 98bf5470c..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_disabled@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus.png deleted file mode 100644 index 91cb16c9f..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus@2x.png deleted file mode 100644 index 04b3bb514..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_checked_focus@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate.png deleted file mode 100644 index 6b846365c..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate@2x.png deleted file mode 100644 index baa502017..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled.png deleted file mode 100644 index 435048a08..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled@2x.png deleted file mode 100644 index 3e7f76c7c..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_disabled@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus.png deleted file mode 100644 index 4bf4d53c1..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus@2x.png deleted file mode 100644 index 1f5cb3e88..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_indeterminate_focus@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked.png deleted file mode 100644 index 54044babf..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked@2x.png deleted file mode 100644 index 1259a9841..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled.png deleted file mode 100644 index 75f049024..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled@2x.png deleted file mode 100644 index e4ecef9d5..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_disabled@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus.png deleted file mode 100644 index 5b0a18f01..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus@2x.png deleted file mode 100644 index 14bec86c2..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/checkbox_unchecked_focus@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/close-hover.png b/retroshare-gui/src/qss/qdarkstyle/rc/close-hover.png deleted file mode 100644 index fdbaf9bf0..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/close-hover.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/close-pressed.png b/retroshare-gui/src/qss/qdarkstyle/rc/close-pressed.png deleted file mode 100644 index 9b243bfe8..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/close-pressed.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/close.png b/retroshare-gui/src/qss/qdarkstyle/rc/close.png deleted file mode 100644 index 89407de72..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/close.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow.png b/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow.png deleted file mode 100644 index e271f7f90..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow_disabled.png deleted file mode 100644 index 5805d9842..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/down_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow.png b/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow.png deleted file mode 100644 index f808d2d72..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow_disabled.png deleted file mode 100644 index f5b9af8a3..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/left_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked.png deleted file mode 100644 index 368acce58..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked@2x.png deleted file mode 100644 index b5f5eed9b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled.png deleted file mode 100644 index 73ff735f2..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled@2x.png deleted file mode 100644 index 827e5928b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_disabled@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus.png deleted file mode 100644 index ad6d2cf82..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus@2x.png deleted file mode 100644 index 7e5930563..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_checked_focus@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked.png deleted file mode 100644 index 82f2abb8c..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked@2x.png deleted file mode 100644 index 793719b3b..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled.png deleted file mode 100644 index 5c54ee9df..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled@2x.png deleted file mode 100644 index d50153d1d..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_disabled@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus.png deleted file mode 100644 index f42d85c7f..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus@2x.png b/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus@2x.png deleted file mode 100644 index 0927b4959..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/radio_unchecked_focus@2x.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow.png b/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow.png deleted file mode 100644 index 9b0a4e6a7..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow_disabled.png deleted file mode 100644 index 5c0bee402..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/right_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/sizegrip.png b/retroshare-gui/src/qss/qdarkstyle/rc/sizegrip.png deleted file mode 100644 index 350583aaa..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/sizegrip.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-end.png b/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-end.png deleted file mode 100644 index cb5d3b51f..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-end.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-more.png b/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-more.png deleted file mode 100644 index 62711409d..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-branch-more.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-vline.png b/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-vline.png deleted file mode 100644 index 87536cce1..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/stylesheet-vline.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/transparent.png b/retroshare-gui/src/qss/qdarkstyle/rc/transparent.png deleted file mode 100644 index 483df2513..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/transparent.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/undock.png b/retroshare-gui/src/qss/qdarkstyle/rc/undock.png deleted file mode 100644 index 58cde37b8..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/undock.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow.png b/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow.png deleted file mode 100644 index abcc72452..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow_disabled.png deleted file mode 100644 index b9c8e3b53..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/rc/up_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/right_arrow.png b/retroshare-gui/src/qss/qdarkstyle/right_arrow.png deleted file mode 100644 index 9b0a4e6a7..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/right_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/right_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/right_arrow_disabled.png deleted file mode 100644 index 5c0bee402..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/right_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/sizegrip.png b/retroshare-gui/src/qss/qdarkstyle/sizegrip.png deleted file mode 100644 index 350583aaa..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/sizegrip.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-end.png b/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-end.png deleted file mode 100644 index cb5d3b51f..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-end.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-more.png b/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-more.png deleted file mode 100644 index 62711409d..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/stylesheet-branch-more.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/stylesheet-vline.png b/retroshare-gui/src/qss/qdarkstyle/stylesheet-vline.png deleted file mode 100644 index 87536cce1..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/stylesheet-vline.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/transparent.png b/retroshare-gui/src/qss/qdarkstyle/transparent.png deleted file mode 100644 index 483df2513..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/transparent.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/undock.png b/retroshare-gui/src/qss/qdarkstyle/undock.png deleted file mode 100644 index 804547aed..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/undock.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/up_arrow.png b/retroshare-gui/src/qss/qdarkstyle/up_arrow.png deleted file mode 100644 index abcc72452..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/up_arrow.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qdarkstyle/up_arrow_disabled.png b/retroshare-gui/src/qss/qdarkstyle/up_arrow_disabled.png deleted file mode 100644 index b9c8e3b53..000000000 Binary files a/retroshare-gui/src/qss/qdarkstyle/up_arrow_disabled.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qlive.qss b/retroshare-gui/src/qss/qlive.qss deleted file mode 100644 index d7df00f76..000000000 --- a/retroshare-gui/src/qss/qlive.qss +++ /dev/null @@ -1,141 +0,0 @@ -.QWidget{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #77AEF1, stop: 0.4 #86BBF7); -} - -QDialog{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #77AEF1, stop: 0.4 #86BBF7); -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - border-image: url(%THISPATH%/qlive/qb.png); -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -/* Customize the toolbar. */ -QToolBar#toolBarAction { - border-image: url(%THISPATH%/qlive/qb.png); - -} - -QToolBar#toolBarPage { - border-image: url(%THISPATH%/qlive/qb.png); - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/qlive/qb.png); - -} - -QMenu { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #77AEF1, stop: 0.4 #86BBF7); - - border: 1px solid black; - } - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F6F9FA, stop: 1 #C6D3E5); -} - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F6F9FA, stop: 1 #C6D3E5); -} -QTreeWidget { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #77AEF1, stop: 0.4 #86BBF7); - - } - - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F6F9FA, stop: 1 #C6D3E5); - -} - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F6F9FA, stop: 1 #C6D3E5); - -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/qlive/qb.png); - -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/qlive/qb.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} -QStatusBar{ - border-image: url(%THISPATH%/qlive/qb.png); -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #77AEF1, stop: 0.4 #86BBF7); - border: 1px solid #86BBF7; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #7fb0ec, stop: 1 #90a1e2); - border: 1px solid #90a1e2; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} \ No newline at end of file diff --git a/retroshare-gui/src/qss/qlive/qb.png b/retroshare-gui/src/qss/qlive/qb.png deleted file mode 100644 index cde1a8588..000000000 Binary files a/retroshare-gui/src/qss/qlive/qb.png and /dev/null differ diff --git a/retroshare-gui/src/qss/qlive/qb2.png b/retroshare-gui/src/qss/qlive/qb2.png deleted file mode 100644 index abd2f0b74..000000000 Binary files a/retroshare-gui/src/qss/qlive/qb2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/redscorpion.qss b/retroshare-gui/src/qss/redscorpion.qss deleted file mode 100644 index d0fb8d0ed..000000000 --- a/retroshare-gui/src/qss/redscorpion.qss +++ /dev/null @@ -1,321 +0,0 @@ -.QWidget { - background-color: #3E1716; -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; -} - - -QDialog{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -/* Customize the toolbar. */ -QToolBar#toolBarPage { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - -} - -QToolBar#toolBarAction { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - - -} - -QToolBar#chattoolBar{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - -} - - -/* it works only at the moment with vista Thema on XP*/ -QToolButton::hover { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FFD200, stop: 1 #FF6400); - - -} - -QToolButton::pressed { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FFD200, stop: 1 #FF6400); - - -} - -QPushButton { - /* background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred);*/ -} - -QPushButton#okButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelprefButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelButton { - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - -QPushButton#applyButton { - - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - -QToolButton { - color: black; -} - - QTabWidget::tab-bar { - left: 0px; /* move to the right by 5px */ - } - - /* Style the tab using the tab sub-control. Note that - it reads QTabBar _not_ QTabWidget */ - QTabBar::tab { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); - border: 2px solid #C4C4C3; - border-bottom-color: #C2C7CB; /* same as the pane color */ - border-top-left-radius: 4px; - border-top-right-radius: 4px; - min-width: 8ex; - padding: 2px; - } - - QTabBar::tab:selected, QTabBar::tab:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 darkred, stop: 1 red); - } - - QTabBar::tab:selected { - border-color: #9B9B9B; - border-bottom-color: #C2C7CB; /* same as pane color */ - } - - QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - } - -QStatusBar{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - -} - -QToolTip{ - background-color: darkred; -} - -QMenu { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); - border: 1px solid black; - } - -QMenu::item { - /* sets background of menu item. set this to something non-transparent - if you want menu color and menu item color to be different */ - background-color: transparent; - } - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FFD200, stop: 1 #FF6400); - } - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); -} - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 red, stop: 1 darkred); - -} - -QFrame#messengerframetop{ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; -} - -QFrame#Chatbuttonframe{ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - -} - -QFrame#frame_2{ - border-image: url(%THISPATH%/redscorpion/red.png); - - -border: 1px solid #CCCCCC; -} - -QFrame#buttonframe{ - border-image: url(%THISPATH%/redscorpion/red.png); - - -border: 1px solid #CCCCCC; -} - -QFrame#frame{ - border-image: url(%THISPATH%/redscorpion/red.png); - - border: 1px solid #CCCCCC; -} - -QFrame#chheaderframe{ - border-image: url(%THISPATH%/redscorpion/red.png); - - -border: 1px solid #CCCCCC; -} - - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} - -QLabel#infolabel{ - color: darkred; -} - -QLabel#friendstitlellabel{ - color: black; -} - -QLabel#networklabel{ - color: black; -} - -QLabel#labeltext{ - color: black; -} - -QRadioButton{ - color: white; -} - -QLabel{ - - color: white; -} - -QLabel#forumName{ - border: 2px solid red; - border-radius: 10px; - background: white; - color: black; -} - -QLabel#threadTitle{ - border: 2px solid red; - border-radius: 10px; - background: white; - color: black; -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #B71502, stop: 1 #900907); - border: 1px solid #7A3C37; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F55332, stop: 0.5 #C82B18, - stop: 0.51 #ca1b06, stop: 1 #ac0c0a); - border: 1px solid #7A3C37; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - -MainWindow QToolButton { - color: white; -} diff --git a/retroshare-gui/src/qss/redscorpion/red.png b/retroshare-gui/src/qss/redscorpion/red.png deleted file mode 100644 index 8c2246cdb..000000000 Binary files a/retroshare-gui/src/qss/redscorpion/red.png and /dev/null differ diff --git a/retroshare-gui/src/qss/redscorpion/red2.png b/retroshare-gui/src/qss/redscorpion/red2.png deleted file mode 100644 index 0b2a36121..000000000 Binary files a/retroshare-gui/src/qss/redscorpion/red2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/retroclassic.qss b/retroshare-gui/src/qss/retroclassic.qss new file mode 100644 index 000000000..df8802f3a --- /dev/null +++ b/retroshare-gui/src/qss/retroclassic.qss @@ -0,0 +1,186 @@ +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/standard_light/rc/transparent.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, +QTreeView::indicator:checked:focus, +QTreeView::indicator:checked:pressed { + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, +QTreeView::indicator:unchecked:focus, +QTreeView::indicator:unchecked:pressed { + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + gridline-color: #C9CDD0; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #9FCBFF; + color: #C9CDD0; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #73C7FF; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #9FCBFF; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #9FCBFF; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #19232D; + background-color: #CED1D4; +} + +QTableCornerButton::section { + background-color: #FAFAFA; + border: 1px transparent #C9CDD0; + border-radius: 0px; +} + +/**** Fix QTreeView Items ****/ + +QTreeView::item, +QListView::item, +QTableView::item, +QColumnView::item { + color: #101010; + background: transparent; +} + +QTreeView:branch:selected{ + background-color: #9FCBFF; +} + +QTreeView:branch:!selected:hover, +QTreeView:branch:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +/* HeaderFrame & TitleBarFrame */ + +QFrame[objectName^="headerFrame"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); +} +QFrame[objectName^="headerBFrame"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover{ + background: transparent; + color: white; +} + +QFrame[objectName^="toolBarFrame"], +QFrame[objectName^="toolBarFrameTop"] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); + border: 1px solid #CCCCCC; +} + +/* Forums */ + +GxsForumThreadWidget QWidget#threadTreeWidget { + selection-background-color: #9FCBFF; + show-decoration-selected: 1; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { + background-color: #9FCBFF; +} + +/* People */ + +IdDialog QWidget#idTreeWidget { + selection-background-color: #9FCBFF; + show-decoration-selected: 1; +} + +/* Wire */ +QLabel#label_masthead{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} diff --git a/retroshare-gui/src/qss/silver.qss b/retroshare-gui/src/qss/silver.qss deleted file mode 100644 index 32025e8fa..000000000 --- a/retroshare-gui/src/qss/silver.qss +++ /dev/null @@ -1,164 +0,0 @@ -.QWidget{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -FriendsDialog QFrame#headFrame { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); - border: 1px; - border-radius: 4px; -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -/* Customize the toolbar. */ -QToolBar#toolBarAction { - border-image: url(%THISPATH%/silver/silver.png); - -} - -/* Customize the toolbar. */ -QToolBar#toolBarPage { - border-image: url(%THISPATH%/silver/silver.png); - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/silver/silver.png); - -} - -QDialog{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QPushButton#okButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelprefButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelButton { - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - -QPushButton#applyButton { - - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QStatusBar{ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/silver/silver.png); - - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/silver/silver.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F9F9FF, stop: 1 #9F9DB9); - border: 1px solid #9F9DB9; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #eaeaff, stop: 1 #9f9dbc); - border: 1px solid #9F9DB9; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - diff --git a/retroshare-gui/src/qss/silver/silver.png b/retroshare-gui/src/qss/silver/silver.png deleted file mode 100644 index 2559aa8d8..000000000 Binary files a/retroshare-gui/src/qss/silver/silver.png and /dev/null differ diff --git a/retroshare-gui/src/qss/silver/silver2.png b/retroshare-gui/src/qss/silver/silver2.png deleted file mode 100644 index fe875f925..000000000 Binary files a/retroshare-gui/src/qss/silver/silver2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/uus.qss b/retroshare-gui/src/qss/uus.qss deleted file mode 100644 index ee1e7b82a..000000000 --- a/retroshare-gui/src/qss/uus.qss +++ /dev/null @@ -1,317 +0,0 @@ -.QWidget { - /*background-color: black;*/ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 0.4 #185772); - -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - border-image: url(%THISPATH%/uus/uus.png); -} - -FriendsDialog QFrame#headFrame { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - border: 1px; - border-radius: 4px; -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -QDialog{ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 0.4 #185772); -} - - -/* Customize the toolbar. */ -QToolBar#toolBarAction { - border-image: url(%THISPATH%/uus/uus.png); - -} -QToolBar#toolBarPage { - border-image: url(%THISPATH%/uus/uus.png); - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/uus/uus.png); - - -} - -QFrame#frame_2{ -background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 0.4 #185772); - border: 1px solid #CCCCCC; - -} - -QFrame#buttonframe{ -background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); -} - -/* it works only at the moment with vista Thema on XP*/ -QToolButton::hover { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - - -} - -QToolButton::pressed { - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - - -} - -/* Style the tab using the tab sub-control. Note that - it reads QTabBar _not_ QTabWidget */ -QTabBar::tab { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - border: 2px solid #BDDF7D; - border-bottom-color: #49881F; /* same as the pane color */ - border-top-left-radius: 4px; - border-top-right-radius: 4px; - min-width: 8ex; - padding: 2px; - -} - -QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - -} - -QTabBar::tab:selected, QTabBar::tab:hover { - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F0F8CB, stop: 1 #F0F8CD); - -} - -QTabBar::tab:selected { - border-color: #9B9B9B; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F5FFBC, stop: 1 #609C08); -} - -QHeaderView::section { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - color: white; - padding-left: 4px; - border: 1px solid #6c6c6c; - } - -QPushButton#okButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelprefButton { - min-height: 27px; - min-width: 77px; -} - -QPushButton#cancelButton { - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - - -QPushButton#applyButton { - - min-height: 25px; - max-height: 25px; - min-width: 75px; -} - -QPushButton { - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - border: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F);*/ -} - - -QPushButton::hover { - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F0F8CB, stop: 1 #F0F8CD);*/ -} - -QPushButton::pressed { - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F5FFBC, stop: 1 #609C08);*/ -} - - -QLabel -{ -color: white; -} - -QStatusBar{ - border-image: url(%THISPATH%/uus/uus.png); - -} - -QMenu { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 1 #185772); - border: 1px solid black; - } - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); -} - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); -} - -QTreeWidget { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 1 #185772); - - } - - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - -} - -QTreeView { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #376D85, stop: 1 #185772); - - } - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - -} - -QToolTip{ - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07); -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/uus/uus.png); - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ -} - -QFrame#Chatbuttonframe{ - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} - -QLabel#friendstitlellabel{ - color: black; -} - -QLabel#friendslabel{ - color: black; -} - -QLabel#networklabel{ - color: black; -} - -QLabel#channellabel{ - color: black; -} - -QLabel#forumslabel{ - color: black; -} - -QLabel#downloadslabel{ - color: black; -} - -QLabel#forumName{ - color: black; -} - -QLabel#threadTitle{ - color: black; -} - - -QLabel#labeltext{ - color: black; -} - -QStatusBar { - - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #BDDF7D, stop: 1 #49881F); - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: #49881F; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - diff --git a/retroshare-gui/src/qss/uus/uus.png b/retroshare-gui/src/qss/uus/uus.png deleted file mode 100644 index 1e4f98f98..000000000 Binary files a/retroshare-gui/src/qss/uus/uus.png and /dev/null differ diff --git a/retroshare-gui/src/qss/uus/uus2.png b/retroshare-gui/src/qss/uus/uus2.png deleted file mode 100644 index 6036684b0..000000000 Binary files a/retroshare-gui/src/qss/uus/uus2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/yaba.qss b/retroshare-gui/src/qss/yaba.qss deleted file mode 100644 index 06d35b9ad..000000000 --- a/retroshare-gui/src/qss/yaba.qss +++ /dev/null @@ -1,228 +0,0 @@ -.QWidget { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #6F6F6F, stop:1 #979797); - } - - -QFrame#titleBarFrame, QFrame#toolBarFrame { - - border-image: url(%THISPATH%/yaba/yaba.png); -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -FriendsDialog QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - border: 1px; - border-radius: 4px; -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - -} - -QDialog, QMainWindow, QStatusBar{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #6F6F6F, stop:1 #979797); -} - -QWidget#chatcentralwidget{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #6F6F6F, stop:1 #979797); -} - - -/* Channels */ - -ChannelFeed QFrame#headerFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - border: 1px solid #CCCCCC; -} - -/* Customize the toolbar. */ -QToolBar#toolBarAction { - border-image: url(%THISPATH%/yaba/yaba.png); - -} - -QToolBar#toolBarPage { - border-image: url(%THISPATH%/yaba/yaba.png); - -} - -QFrame#frame_2{ - border-image: url(%THISPATH%/yaba/yaba3.png); - -} - -QFrame#buttonframe{ - border-image: url(%THISPATH%/yaba/yaba3.png); - -} - -QFrame#chheaderframe{ - border-image: url(%THISPATH%/yaba/yaba3.png); - -} -QFrame#frame{ - border-image: url(%THISPATH%/yaba/yaba3.png); - -} - -QHeaderView::section { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #616161, stop: 0.5 #505050, - stop: 0.6 #434343, stop:1 #656565); - color: white; - padding-left: 4px; - border: 1px solid #6c6c6c; - } - - - QMenuBar { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #626262, stop:1 #989898); - } - - QTabWidget::pane { /* The tab widget frame */ - border-top: 2px solid #C2C7CB; - } - - QTabWidget::tab-bar { - left: 0px; /* move to the right by 5px */ - } - - /* Style the tab using the tab sub-control. Note that - it reads QTabBar _not_ QTabWidget */ - QTabBar::tab { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, - stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); - border: 2px solid #C4C4C3; - border-bottom-color: #C2C7CB; /* same as the pane color */ - border-top-left-radius: 4px; - border-top-right-radius: 4px; - min-width: 8ex; - padding: 2px; - } - - QTabBar::tab:selected, QTabBar::tab:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #fafafa, stop: 0.4 #f4f4f4, - stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); - } - - QTabBar::tab:selected { - border-color: #9B9B9B; - border-bottom-color: #C2C7CB; /* same as pane color */ - } - - QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - } - -QMenu { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #6F6F6F, stop:1 #979797); - border: 1px solid black; - } - - -QMenu::item { - /* sets background of menu item. set this to something non-transparent - if you want menu color and menu item color to be different */ - background-color: transparent; - } - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - } - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); -} - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FBC957, stop: 1 #D79704); - -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/yaba/yaba.png); - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/yaba/yaba.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} - -QLabel#fromText{ - font: bold ; - color: blue; - -} - -QToolBar#chattoolBar{ - border-image: url(%THISPATH%/yaba/yaba.png); - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: #979797; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} - diff --git a/retroshare-gui/src/qss/yaba/yaba.png b/retroshare-gui/src/qss/yaba/yaba.png deleted file mode 100644 index e8659f66d..000000000 Binary files a/retroshare-gui/src/qss/yaba/yaba.png and /dev/null differ diff --git a/retroshare-gui/src/qss/yaba/yaba2.png b/retroshare-gui/src/qss/yaba/yaba2.png deleted file mode 100644 index af6be6117..000000000 Binary files a/retroshare-gui/src/qss/yaba/yaba2.png and /dev/null differ diff --git a/retroshare-gui/src/qss/yaba/yaba3.png b/retroshare-gui/src/qss/yaba/yaba3.png deleted file mode 100644 index 5dd5a2a32..000000000 Binary files a/retroshare-gui/src/qss/yaba/yaba3.png and /dev/null differ diff --git a/retroshare-gui/src/qss/yeah.qss b/retroshare-gui/src/qss/yeah.qss deleted file mode 100644 index b154b7f53..000000000 --- a/retroshare-gui/src/qss/yeah.qss +++ /dev/null @@ -1,183 +0,0 @@ -.QWidget { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 lightgray, stop:1 darkgray); -} - -FriendsDialog QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - border: 1px; - border-radius: 4px; -} - -QFrame#titleBarFrame, QFrame#toolBarFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - border: 1px solid #CCCCCC; -} - -HeaderFrame { - background-image: url(:/images/headerFrame.png); - border: 0px; -} - -QDialog{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 lightgray, stop:1 darkgray); -} - - -/* Customize the toolbar. */ -QToolBar { - border-image: url(%THISPATH%/yeah/yeah.png); - -} - -QStatusBar{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 lightgray, stop:1 darkgray); -} - - -QHeaderView::section { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #616161, stop: 0.5 #505050, - stop: 0.6 #434343, stop:1 #656565); - color: white; - padding-left: 4px; - border: 1px solid #6c6c6c; -} - - -QMenuBar { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 lightgray, stop:1 darkgray); -} - - QTabWidget::pane { /* The tab widget frame */ - border-top: 2px solid #C2C7CB; - } - - QTabWidget::tab-bar { - left: 0px; /* move to the right by 5px */ - } - - /* Style the tab using the tab sub-control. Note that - it reads QTabBar _not_ QTabWidget */ - QTabBar::tab { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #E1E1E1, stop: 0.4 #DDDDDD, - stop: 0.5 #D8D8D8, stop: 1.0 #D3D3D3); - border: 2px solid #C4C4C3; - border-bottom-color: #C2C7CB; /* same as the pane color */ - border-top-left-radius: 4px; - border-top-right-radius: 4px; - min-width: 8ex; - padding: 2px; - } - - QTabBar::tab:selected, QTabBar::tab:hover { - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #fafafa, stop: 0.4 #f4f4f4, - stop: 0.5 #e7e7e7, stop: 1.0 #fafafa); - } - - QTabBar::tab:selected { - border-color: #9B9B9B; - border-bottom-color: #C2C7CB; /* same as pane color */ - } - - QTabBar::tab:!selected { - margin-top: 2px; /* make non-selected tabs look smaller */ - } - - QMenu { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 lightgray, stop:1 darkgray); - border: 1px solid black; - } - -QMenu::item { - /* sets background of menu item. set this to something non-transparent - if you want menu color and menu item color to be different */ - background-color: transparent; - } - -QMenu::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); - } - -QListWidget::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); -} - -QTreeWidget::item:selected { /* when user selects item using mouse or keyboard */ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FBC957, stop:1 #D79704); -} - -QTreeView::item:selected { /* when user selects item using mouse or keyboard */ - - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #FBC957, stop: 1 #D79704); - -} - -QFrame#messengerframetop{ - - border-image: url(%THISPATH%/yeah/yeah.png); - - /*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 #F7B552, stop: 1 #FF5E07);*/ -} - -QFrame#Chatbuttonframe{ - - border-image: url(%THISPATH%/yeah/yeah.png); - -} - -QLabel#subjectText{ - font: bold 12px; - -} - -QLabel#subjectlabel{ - font: bold 12px; - -} - -QLabel#fromlabel{ - font: bold 12px; - -} - -QLabel#datelabel{ - font: bold 12px; - -} - -QLabel#tolabel{ - font: bold 12px; - -} -QLabel#fromText{ - font: bold ; - color: blue; - -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: #979797; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -MainWindow QListWidget { - font-size: 12pt; -} diff --git a/retroshare-gui/src/qss/yeah/yeah.png b/retroshare-gui/src/qss/yeah/yeah.png deleted file mode 100644 index bd31010f7..000000000 Binary files a/retroshare-gui/src/qss/yeah/yeah.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/maxButton.png b/retroshare-gui/src/release/skin/Bliss/maxButton.png deleted file mode 100644 index 4d83bcd35..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/maxButton1.png b/retroshare-gui/src/release/skin/Bliss/maxButton1.png deleted file mode 100644 index a916ba483..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/maxButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/maxButton2.png b/retroshare-gui/src/release/skin/Bliss/maxButton2.png deleted file mode 100644 index aaba43674..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/maxButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/minButton.png b/retroshare-gui/src/release/skin/Bliss/minButton.png deleted file mode 100644 index 7f1553a6e..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/minButton1.png b/retroshare-gui/src/release/skin/Bliss/minButton1.png deleted file mode 100644 index a3c564cdd..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/minButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/minButton2.png b/retroshare-gui/src/release/skin/Bliss/minButton2.png deleted file mode 100644 index 01af810b0..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/minButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/quiButton.png b/retroshare-gui/src/release/skin/Bliss/quiButton.png deleted file mode 100644 index 6a657ae1a..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/quiButton1.png b/retroshare-gui/src/release/skin/Bliss/quiButton1.png deleted file mode 100644 index 174c7b2ee..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/quiButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/quiButton2.png b/retroshare-gui/src/release/skin/Bliss/quiButton2.png deleted file mode 100644 index f379e9431..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/quiButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/sl.png b/retroshare-gui/src/release/skin/Bliss/sl.png deleted file mode 100644 index 851821b6a..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/so.png b/retroshare-gui/src/release/skin/Bliss/so.png deleted file mode 100644 index 6497639b3..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/sr.png b/retroshare-gui/src/release/skin/Bliss/sr.png deleted file mode 100644 index 6689549b3..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Bliss/su.png b/retroshare-gui/src/release/skin/Bliss/su.png deleted file mode 100644 index 9862742f0..000000000 Binary files a/retroshare-gui/src/release/skin/Bliss/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/maxButton.png b/retroshare-gui/src/release/skin/Glassy/maxButton.png deleted file mode 100644 index 469d21e40..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/minButton.png b/retroshare-gui/src/release/skin/Glassy/minButton.png deleted file mode 100644 index 40c6ba78c..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/quiButton.png b/retroshare-gui/src/release/skin/Glassy/quiButton.png deleted file mode 100644 index da6390211..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/sl.png b/retroshare-gui/src/release/skin/Glassy/sl.png deleted file mode 100644 index f259a74c7..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/so.png b/retroshare-gui/src/release/skin/Glassy/so.png deleted file mode 100644 index 9b554663d..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/sr.png b/retroshare-gui/src/release/skin/Glassy/sr.png deleted file mode 100644 index f259a74c7..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Glassy/su.png b/retroshare-gui/src/release/skin/Glassy/su.png deleted file mode 100644 index 0e96fdbed..000000000 Binary files a/retroshare-gui/src/release/skin/Glassy/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/maxButton.png b/retroshare-gui/src/release/skin/Green/maxButton.png deleted file mode 100644 index 73f1fc27d..000000000 Binary files a/retroshare-gui/src/release/skin/Green/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/minButton.png b/retroshare-gui/src/release/skin/Green/minButton.png deleted file mode 100644 index 1c9adaa6c..000000000 Binary files a/retroshare-gui/src/release/skin/Green/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/quiButton.png b/retroshare-gui/src/release/skin/Green/quiButton.png deleted file mode 100644 index 6134015ef..000000000 Binary files a/retroshare-gui/src/release/skin/Green/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/sl.png b/retroshare-gui/src/release/skin/Green/sl.png deleted file mode 100644 index 06af00e82..000000000 Binary files a/retroshare-gui/src/release/skin/Green/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/so.png b/retroshare-gui/src/release/skin/Green/so.png deleted file mode 100644 index 661ffd761..000000000 Binary files a/retroshare-gui/src/release/skin/Green/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/sr.png b/retroshare-gui/src/release/skin/Green/sr.png deleted file mode 100644 index 7f62f1c0b..000000000 Binary files a/retroshare-gui/src/release/skin/Green/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Green/su.png b/retroshare-gui/src/release/skin/Green/su.png deleted file mode 100644 index 8e04d5077..000000000 Binary files a/retroshare-gui/src/release/skin/Green/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/maxButton.png b/retroshare-gui/src/release/skin/Night Vision/maxButton.png deleted file mode 100644 index cbb27c3cb..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/minButton.png b/retroshare-gui/src/release/skin/Night Vision/minButton.png deleted file mode 100644 index 5892a982c..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/quiButton.png b/retroshare-gui/src/release/skin/Night Vision/quiButton.png deleted file mode 100644 index 1443caa9d..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/sl.png b/retroshare-gui/src/release/skin/Night Vision/sl.png deleted file mode 100644 index acc9db3d1..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/so.png b/retroshare-gui/src/release/skin/Night Vision/so.png deleted file mode 100644 index 900e051a9..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/sr.png b/retroshare-gui/src/release/skin/Night Vision/sr.png deleted file mode 100644 index 0d0f296ec..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Night Vision/su.png b/retroshare-gui/src/release/skin/Night Vision/su.png deleted file mode 100644 index 32b195e0d..000000000 Binary files a/retroshare-gui/src/release/skin/Night Vision/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/maxButton.png b/retroshare-gui/src/release/skin/Vista/maxButton.png deleted file mode 100644 index cbb27c3cb..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/maxButton1.png b/retroshare-gui/src/release/skin/Vista/maxButton1.png deleted file mode 100644 index 1bed27a49..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/maxButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/maxButton2.png b/retroshare-gui/src/release/skin/Vista/maxButton2.png deleted file mode 100644 index a9ece6da2..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/maxButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/minButton.png b/retroshare-gui/src/release/skin/Vista/minButton.png deleted file mode 100644 index 5892a982c..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/minButton1.png b/retroshare-gui/src/release/skin/Vista/minButton1.png deleted file mode 100644 index 79207e5df..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/minButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/minButton2.png b/retroshare-gui/src/release/skin/Vista/minButton2.png deleted file mode 100644 index b52bdb299..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/minButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/quiButton.png b/retroshare-gui/src/release/skin/Vista/quiButton.png deleted file mode 100644 index 1443caa9d..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/quiButton1.png b/retroshare-gui/src/release/skin/Vista/quiButton1.png deleted file mode 100644 index 008b25e2e..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/quiButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/quiButton2.png b/retroshare-gui/src/release/skin/Vista/quiButton2.png deleted file mode 100644 index 3e79d9f08..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/quiButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/sl.png b/retroshare-gui/src/release/skin/Vista/sl.png deleted file mode 100644 index 05628496b..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/so.png b/retroshare-gui/src/release/skin/Vista/so.png deleted file mode 100644 index d9472686c..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/sr.png b/retroshare-gui/src/release/skin/Vista/sr.png deleted file mode 100644 index 60e8e091f..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/Vista/su.png b/retroshare-gui/src/release/skin/Vista/su.png deleted file mode 100644 index c62254cfb..000000000 Binary files a/retroshare-gui/src/release/skin/Vista/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/bg.png b/retroshare-gui/src/release/skin/VistaAlpha/bg.png deleted file mode 100644 index f7ead614a..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/bg.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/maxButton.png b/retroshare-gui/src/release/skin/VistaAlpha/maxButton.png deleted file mode 100644 index bb1c53ee4..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/maxButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/maxButton1.png b/retroshare-gui/src/release/skin/VistaAlpha/maxButton1.png deleted file mode 100644 index 1bed27a49..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/maxButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/maxButton2.png b/retroshare-gui/src/release/skin/VistaAlpha/maxButton2.png deleted file mode 100644 index a9ece6da2..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/maxButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/minButton.png b/retroshare-gui/src/release/skin/VistaAlpha/minButton.png deleted file mode 100644 index 379bfa4cb..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/minButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/minButton1.png b/retroshare-gui/src/release/skin/VistaAlpha/minButton1.png deleted file mode 100644 index 79207e5df..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/minButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/minButton2.png b/retroshare-gui/src/release/skin/VistaAlpha/minButton2.png deleted file mode 100644 index b52bdb299..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/minButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/quiButton.png b/retroshare-gui/src/release/skin/VistaAlpha/quiButton.png deleted file mode 100644 index e3882e9ff..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/quiButton.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png b/retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png deleted file mode 100644 index 008b25e2e..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/quiButton1.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png b/retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png deleted file mode 100644 index 3e79d9f08..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/quiButton2.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/sl.png b/retroshare-gui/src/release/skin/VistaAlpha/sl.png deleted file mode 100644 index 82deb022e..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/sl.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/so.png b/retroshare-gui/src/release/skin/VistaAlpha/so.png deleted file mode 100644 index 677255b01..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/so.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/sr.png b/retroshare-gui/src/release/skin/VistaAlpha/sr.png deleted file mode 100644 index 22f2e74fe..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/sr.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/VistaAlpha/su.png b/retroshare-gui/src/release/skin/VistaAlpha/su.png deleted file mode 100644 index 6f19cdc00..000000000 Binary files a/retroshare-gui/src/release/skin/VistaAlpha/su.png and /dev/null differ diff --git a/retroshare-gui/src/release/skin/skin.dat b/retroshare-gui/src/release/skin/skin.dat deleted file mode 100644 index 7a501621c..000000000 --- a/retroshare-gui/src/release/skin/skin.dat +++ /dev/null @@ -1,7 +0,0 @@ -[Skin] -Blur=false -Hintergrundfarbe=@Variant(\0\0\0\x43\x1\xff\xff\xd5\xd5\xd5\xd5\xd5\xd5\0\0) -SkinOn=true -Skinpfad=skin/Vista/ -Titelfarbe=@Variant(\0\0\0\x43\x1\xff\xff\0\0\0\0\0\0\0\0) -Titelschrift=@Variant(\0\0\0@\0\0\0\x1a\0\x43\0o\0m\0i\0\x63\0 \0S\0\x61\0n\0s\0 \0M\0S@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0K\x10) diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 11bb33dca..93734b454 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -113,7 +113,6 @@ CONFIG += gxscircles # Other Disabled Bits. #CONFIG += framecatcher -#CONFIG += blogs ## To enable unfinished services #CONFIG += wikipoos @@ -147,11 +146,11 @@ unix { target.path = "$${BIN_DIR}" INSTALLS += target - data_files.path="$${DATA_DIR}/" + data_files.path="$${RS_DATA_DIR}/" data_files.files=sounds qss INSTALLS += data_files - style_files.path="$${DATA_DIR}/stylesheets" + style_files.path="$${RS_DATA_DIR}/stylesheets" style_files.files=gui/qss/chat/Bubble gui/qss/chat/Bubble_Compact INSTALLS += style_files @@ -218,10 +217,6 @@ win32-g++|win32-clang-g++ { CONFIG -= console } - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - CONFIG(debug, debug|release) { } else { # Tell linker to use ASLR protection @@ -280,13 +275,22 @@ macx { mac_icon.files = $$files($$PWD/rsMacIcon.icns) mac_icon.path = Contents/Resources QMAKE_BUNDLE_DATA += mac_icon + dplQSS.files = $$PWD/qss + dplQSS.path = Contents/Resources + QMAKE_BUNDLE_DATA += dplQSS + dplChatStyles.files = \ + $$PWD/gui/qss/chat/Bubble \ + $$PWD/gui/qss/chat/Bubble_Compact + dplChatStyles.path = Contents/Resources/stylesheets + QMAKE_BUNDLE_DATA += dplChatStyles # mac_webui.files = $$files($$PWD/../../libresapi/src/webui) # mac_webui.path = Contents/Resources # QMAKE_BUNDLE_DATA += mac_webui + OBJECTS_DIR = temp/obj + CONFIG += version_detail_bash_script - LIBS += -lssl -lcrypto -lz - #LIBS += -lssl -lcrypto -lz -lgpgme -lgpg-error -lassuan + LIBS += -lssl -lcrypto -lz for(lib, LIB_DIR):exists($$lib/libminiupnpc.a){ LIBS += $$lib/libminiupnpc.a} LIBS += -framework CoreFoundation LIBS += -framework Security @@ -355,46 +359,6 @@ wikipoos { ################################### HEADERS & SOURCES ############################# -# Tor controller - -HEADERS += TorControl/AddOnionCommand.h \ - TorControl/AuthenticateCommand.h \ - TorControl/CryptoKey.h \ - TorControl/GetConfCommand.h \ - TorControl/HiddenService.h \ - TorControl/PendingOperation.h \ - TorControl/ProtocolInfoCommand.h \ - TorControl/SecureRNG.h \ - TorControl/SetConfCommand.h \ - TorControl/Settings.h \ - TorControl/StrUtil.h \ - TorControl/TorControl.h \ - TorControl/TorControlCommand.h \ - TorControl/TorControlSocket.h \ - TorControl/TorManager.h \ - TorControl/TorProcess.h \ - TorControl/TorProcess_p.h \ - TorControl/TorSocket.h \ - TorControl/Useful.h - -SOURCES += TorControl/AddOnionCommand.cpp \ - TorControl/AuthenticateCommand.cpp \ - TorControl/GetConfCommand.cpp \ - TorControl/HiddenService.cpp \ - TorControl/ProtocolInfoCommand.cpp \ - TorControl/SetConfCommand.cpp \ - TorControl/TorControlCommand.cpp \ - TorControl/TorControl.cpp \ - TorControl/TorControlSocket.cpp \ - TorControl/TorManager.cpp \ - TorControl/TorProcess.cpp \ - TorControl/TorSocket.cpp \ - TorControl/CryptoKey.cpp \ - TorControl/PendingOperation.cpp \ - TorControl/SecureRNG.cpp \ - TorControl/Settings.cpp \ - TorControl/StrUtil.cpp - # Input HEADERS += rshare.h \ retroshare-gui/configpage.h \ @@ -562,6 +526,7 @@ HEADERS += rshare.h \ gui/common/TagDefs.h \ gui/common/GroupDefs.h \ gui/common/Emoticons.h \ + gui/common/RSComboBox.h \ gui/common/RSListWidgetItem.h \ gui/common/RSTextEdit.h \ gui/common/RSPlainTextEdit.h \ @@ -597,8 +562,6 @@ HEADERS += rshare.h \ gui/common/RsBanListToolButton.h \ gui/common/FlowLayout.h \ gui/common/PictureFlow.h \ - gui/common/StyledLabel.h \ - gui/common/StyledElidedLabel.h \ gui/common/ToasterNotify.h \ gui/style/RSStyle.h \ gui/style/StyleDialog.h \ @@ -891,6 +854,7 @@ SOURCES += main.cpp \ gui/common/TagDefs.cpp \ gui/common/GroupDefs.cpp \ gui/common/Emoticons.cpp \ + gui/common/RSComboBox.cpp \ gui/common/RSListWidgetItem.cpp \ gui/common/RSTextEdit.cpp \ gui/common/RSPlainTextEdit.cpp \ @@ -926,8 +890,6 @@ SOURCES += main.cpp \ gui/common/RsBanListToolButton.cpp \ gui/common/FlowLayout.cpp \ gui/common/PictureFlow.cpp \ - gui/common/StyledLabel.cpp \ - gui/common/StyledElidedLabel.cpp \ gui/common/ToasterNotify.cpp \ gui/style/RSStyle.cpp \ gui/style/StyleDialog.cpp \ @@ -1038,7 +1000,9 @@ SOURCES += main.cpp \ # gui/feeds/ChanNewItem.cpp \ # gui/feeds/ChanMsgItem.cpp \ -RESOURCES += gui/images.qrc gui/icons.qrc lang/lang.qrc gui/help/content/content.qrc gui/emojione.qrc +RESOURCES += gui/images.qrc gui/icons.qrc lang/lang.qrc gui/help/content/content.qrc gui/emojione.qrc \ + gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc \ + gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc TRANSLATIONS += \ lang/retroshare_ca_ES.ts \ @@ -1121,6 +1085,14 @@ DEFINES *= CHANNELS_FRAME_CATCHER } +# Embedded Friend Server + +rs_efs { + DEFINES *= RS_EMBEDED_FRIEND_SERVER + SOURCES += gui/FriendServerControl.cpp + HEADERS += gui/FriendServerControl.h + FORMS += gui/FriendServerControl.ui +} # BELOW IS GXS Unfinished Services. @@ -1248,6 +1220,7 @@ gxsthewire { gui/TheWire/PulseReply.h \ gui/TheWire/PulseReplySeperator.h \ gui/TheWire/PulseMessage.h \ + gui/TheWire/CustomFrame.h \ FORMS += gui/TheWire/WireDialog.ui \ gui/TheWire/WireGroupItem.ui \ @@ -1270,6 +1243,7 @@ gxsthewire { gui/TheWire/PulseReply.cpp \ gui/TheWire/PulseReplySeperator.cpp \ gui/TheWire/PulseMessage.cpp \ + gui/TheWire/CustomFrame.cpp \ RESOURCES += gui/TheWire/TheWire_images.qrc } diff --git a/retroshare-gui/src/retroshare-process.nsi b/retroshare-gui/src/retroshare-process.nsi deleted file mode 100644 index 685f90214..000000000 --- a/retroshare-gui/src/retroshare-process.nsi +++ /dev/null @@ -1,502 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax -; This script need the http://nsis.sourceforge.net/Processes_plug-in -; This script need the http://nsis.sourceforge.net/KillProcDLL_plug-in - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.4.13d" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION}" - - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor LZMA - -VAR KILLEXENAME - - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "Visit the RetroShare forum for the latest news and support" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -; !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE Turkish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Polish - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .pqi file extension" - LangString DESC_sec_autostart ${LANG_ENGLISH} "Auto-Run and Login at Startup" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "RetroShare fichiers Association" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installe les fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installe RetroShare Skins" - LangString DESC_sec_startmenu ${LANG_FRENCH} "Crée les raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Crée une icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associate RetroShare with .pqi file extension" - LangString DESC_sec_autostart ${LANG_FRENCH} "Run and Auto-connexion au démarrage" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programmdateien" - LangString sec_data ${LANG_GERMAN} "Skins f�r das Programm" - LangString sec_shortcuts ${LANG_GERMAN} "Shortcuts" - LangString sec_link ${LANG_GERMAN} "Dateiverkn�pfungen" - LangString sec_autostart ${LANG_GERMAN} "Auto Startup" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die erforderlichen Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_GERMAN} "Erstellt eine RetroShare Verkn�pfung im Startmen�, Desktop oder im Schnellstarter." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .pqi Dateien verkn�pfen" - LangString DESC_sec_autostart ${LANG_GERMAN} "Beim Neustart automatisch RetroShare starten und sich anmelden" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar�" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_link ${LANG_TURKISH} ".pqi Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar�n� kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .pqi almas� i�in kaydettirir" - LangString DESC_sec_autostart ${LANG_TURKISH} "Isletim sistemi acildiginda Otomatik olarak calistir ve baglan" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.pqi扩展名" - LangString DESC_sec_autostart ${LANG_SIMPCHINESE} "启动时自动运行和登录" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .pqi z RetroShare" - LangString DESC_sec_autostart ${LANG_POLISH} "Uruchom i zaloguj podczas startu systemu" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -; CloseRetroShare: this will in a loop send the RetroShare window the WM_CLOSE -; message until it does not find a valid RetroShare window -; - -!macro CloseRetroShare UN -Function ${UN}CloseRetroShare - Push $0 - - IntFmt $R4 "%u" 0 - - goto skip - killloop: - DetailPrint "Killing RetroShare" - KillProcDLL::KillProc "RetroShare.exe" - loop: - Sleep 1000 - IntOp $R4 $R4 + 1 - IntCmp $R4 5 done - skip: - DetailPrint "Looking for running copies of RetroShare" - - ;Push "wxWindowClassNR" # the wcn - ;Push "RetroShare" # the known part of the wt - ;Call ${UN}EnhancedFindWindow - ;Pop $0 # will contain the window's handle - ;Pop $1 # will containg the full wcn - # both will containg "failed", if no matching wcn was found - - ;StrCmp $0 "failed" done - ;StrCmp $0 "0" done - ;DetailPrint "Stopping RetroShare" - ;SendMessage $0 16 0 0 # WM_CLOSE == 16 - Goto loop - done: - - IntFmt $R4 "%u" 0 - Processes::FindProcess "RetroShare.exe" - StrCmp $R0 "1" killloop reallydone - - reallydone: - Pop $0 -FunctionEnd -!macroend - - -!macro CheckForIt UN -Function ${UN}CheckForIt - - Processes::FindProcess $KILLEXENAME - StrCmp $R0 "1" foundit didntfindit - - foundit: - MessageBox MB_OKCANCEL "You must quit ${APPNAME} ($KILLEXENAME) \ - before installing this version.$\r$\nPlease quit it and press \ - OK to continue." IDOK tryagain - Abort - - tryagain: - - Sleep 2000 - Processes::FindProcess $KILLEXENAME - StrCmp $R0 "1" stillthere didntfindit - - stillthere: - MessageBox MB_OKCANCEL "There is still a copy of ${APPNAME} \ - ($KILLEXENAME) running.$\r$\nPress OK to force-quit the application, \ - or Cancel to exit." IDOK killit - Abort - - killit: - KillProcDLL::KillProc $KILLEXENAME - Sleep 1000 - - didntfindit: - -FunctionEnd -!macroend - -!macro QuitIt UN -Function ${UN}QuitIt - - # try nicely first - Call ${UN}CloseRetroShare - - # kill all the old ones - StrCpy $KILLEXENAME "RetroShare.exe" - Call ${UN}CheckForIt - StrCpy $KILLEXENAME "" -FunctionEnd -!macroend - - -; This function automatically uninstalls older versions. -; It is largely copied from: -; http://nsis.sourceforge.net/archive/viewpage.php?pageid=326 - - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "D:\Qt\2009.02\mingw\bin\mingwm10.dll" - File /r "D:\Qt\2009.02\qt\bin\QtCore4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtGui4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtNetwork4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtXml4.dll" - File /r "D:\Qt\2009.02\qt\bin\QtScript4.dll" - File /r "pthreadGCE2.dll" - File /r "pthreadGC2d.dll" - File /r "changelog.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; We're not ready for external skins... - ; Set Section qss need to remove svn path - SetOutPath "$INSTDIR\qss\" - File /r qss\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - SetOutPath "$INSTDIR\emoticons\" - File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$INSTDIR\style\" - File /r style\*.* - -SectionEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .pqi "" retroshare - WriteRegStr HKCR retroshare "" "PQI File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -Section $(sec_autostart) sec_autostart - - CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - - -;!insertmacro EnhancedFindWindow "" -;!insertmacro EnhancedFindWindow "un." - -!insertmacro CloseRetroShare "" -!insertmacro CloseRetroShare "un." - -!insertmacro CheckForIt "" -!insertmacro CheckForIt "un." - -!insertmacro QuitIt "" -!insertmacro QuitIt "un." - -;Uninstall section -Section "Uninstall" - - Call un.QuitIt - - ; Remove file association registry keys - DeleteRegKey HKCR .pqi - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autstart - Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" - - - - - -; eof diff --git a/retroshare-gui/src/retroshare-ultramodern.nsi b/retroshare-gui/src/retroshare-ultramodern.nsi deleted file mode 100644 index d224cc8f1..000000000 --- a/retroshare-gui/src/retroshare-ultramodern.nsi +++ /dev/null @@ -1,501 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.1 4049" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION}" -!define QTBASE "D:\qt\2010.01" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_setup_ultramodern.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "UMUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\UltraModernUI\Icon.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "Visit the RetroShare forum for the latest news and support" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\UltraModernUI\UnIcon.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define UMUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Turkish - - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "RetroShare fichiers Association" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installe les fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installe RetroShare Skins" - LangString DESC_sec_startmenu ${LANG_FRENCH} "Crée les raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Crée une icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - - LangString sec_main ${LANG_GERMAN} "Programmdateien" - LangString sec_data ${LANG_GERMAN} "Skins fuer das Programm" - LangString sec_shortcuts ${LANG_GERMAN} "Shortcuts" - LangString sec_link ${LANG_GERMAN} "Dateiverknuepfungen" - LangString sec_autostart ${LANG_GERMAN} "Auto Startup" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die erforderlichen Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_GERMAN} "Erstellt eine RetroShare Verkn�pfung im Startmen�, Desktop oder im Schnellstarter." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateien verkn�pfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar�" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar�n� kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas� i�in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "D:\Qt\2010.01\mingw\bin\mingwm10.dll" - File /r "D:\Qt\2010.01\qt\bin\QtCore4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtGui4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtNetwork4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtXml4.dll" - File /r "D:\Qt\2010.01\qt\bin\QtScript4.dll" - File /r "D:\Qt\2010.01\qt\bin\libgcc_s_dw2-1.dll" - File /r "D:\Qt\2010.01\qt\plugins\imageformats" - File /r "D:\Development\miniupnpc-1.3\miniupnpc.dll" - File /r ${QTBASE}\qt\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "release\libgpg-error-0.dll" - File /r "release\libgpgme-11.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\plugins\" - ;File /r "plugins\" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - ;SetOutPath "$INSTDIR\style\" - ;File /r style\*.* - -SectionEnd - -; These are the programs that are needed by RetroShare. -Section -Prerequisites - SetOutPath $INSTDIR\Prerequisites - MessageBox MB_YESNO "$(InstallGPG4WIN)" /SD IDYES IDNO leave - File "Prerequisites\gpg4win-1.1.4.exe" - ExecWait "$INSTDIR\Prerequisites\gpg4win-1.1.4.exe" - - leave: -SectionEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - -LangString InstallGPG4WIN ${LANG_ENGLISH} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_GERMAN} "Installiere Gpg4win ? Gpg4win ist erforderlich fuer RetroShare!" -LangString InstallGPG4WIN ${LANG_TURKISH} "Gpg4win Yükle? Gpg4win RetroShare için gerekli!" -LangString InstallGPG4WIN ${LANG_FRENCH} "RetroShare a besoin de GPG4win pour fonctionner. Lancer l'installation de GPG4win?" -LangString InstallGPG4WIN ${LANG_SIMPCHINESE} "Install Gpg4win ? Gpg4win是需要Retroshare!" -LangString InstallGPG4WIN ${LANG_POLISH} "Install Gpg4win ? Gpg4win wymagane jest Retroshare!" -LangString InstallGPG4WIN ${LANG_DANISH} "Installer Gpg4win? Gpg4win er nødvendig for RetroShare!" -LangString InstallGPG4WIN ${LANG_JAPANESE} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_KOREAN} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_RUSSIAN} "Install Gpg4win ? Gpg4win is required for RetroShare!" -LangString InstallGPG4WIN ${LANG_SWEDISH} "Installera Gpg4win? Gpg4win krävs för RetroShare!" - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Besuche RetroShare Support Forum " -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" - - -; eof diff --git a/retroshare-gui/src/retroshare.in b/retroshare-gui/src/retroshare.in deleted file mode 100644 index 994d26d7c..000000000 --- a/retroshare-gui/src/retroshare.in +++ /dev/null @@ -1,594 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.4e" -!define REVISION "$WCREV$" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION} ${REVISION}" -!define QTBASE "d:\qt\2010.05" -!define RSBASE "d:\Development\retroshare\retroshare-gui\" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_${REVISION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "$(FINISHPAGELINK)" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1032 "license\license-GR.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1034 "license\license-SP.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1040 "license\license-IT.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1046 "license\license-PT_BR.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Greek -!insertmacro MUI_LANGUAGE Italian -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE PortugueseBR -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Spanish -!insertmacro MUI_LANGUAGE Turkish - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_plugins ${LANG_ENGLISH} "Plugins" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_plugins ${LANG_ENGLISH} "Installs the RetroShare plugins." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_plugins ${LANG_FRENCH} "Plugins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "Association de fichiers" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installation des fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installation des Skins de RetroShare" - LangString DESC_sec_plugins ${LANG_FRENCH} "Installation des extensions de RetroShare " - LangString DESC_sec_startmenu ${LANG_FRENCH} "Création des raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Création de l'icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associer RetroShare avec l'extension de fichier .rsc" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programme" - LangString sec_data ${LANG_GERMAN} "Programm Skins" - LangString sec_plugins ${LANG_GERMAN} "Plug-ins" - LangString sec_shortcuts ${LANG_GERMAN} "Verknüpfungen" - LangString sec_link ${LANG_GERMAN} "Dateiverknüpfungen" - LangString sec_autostart ${LANG_GERMAN} "Autostart" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die RetroShare Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GERMAN} "Installiert die RetroShare Erweiterungen." - LangString DESC_sec_shortcuts ${LANG_GERMAN} "RetroShare Verknüpfung im Startmenüe, Desktop oder im Schnellstarter erstellen." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateiendung verknüpfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar?" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_plugins ${LANG_TURKISH} "Eklentiler" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar?n? kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_plugins ${LANG_TURKISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas? i?in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_plugins ${LANG_SIMPCHINESE} "Plugins" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_plugins ${LANG_SIMPCHINESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩展名" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_plugins ${LANG_POLISH} "Plugins" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_plugins ${LANG_POLISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_plugins ${LANG_DANISH} "Plugins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_DANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_plugins ${LANG_RUSSIAN} "Plugins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_RUSSIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_plugins ${LANG_SWEDISH} "Plugins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_SWEDISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_SPANISH} "Archivos de programa" - LangString sec_data ${LANG_SPANISH} "Estilos del programa" - LangString sec_plugins ${LANG_SPANISH} "Plugins" - LangString sec_shortcuts ${LANG_SPANISH} "Accesos directos" - LangString sec_link ${LANG_SPANISH} "Asociación de archivos" - LangString sec_autostart ${LANG_SPANISH} "Inicio automático" - LangString DESC_sec_main ${LANG_SPANISH} "Instala los archivos del programa RetroShare." - LangString DESC_sec_data ${LANG_SPANISH} "Instala los estilos para RetroShare" - LangString DESC_sec_plugins ${LANG_SPANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SPANISH} "Crear iconos de acceso directo de RetroShare." - LangString DESC_sec_link ${LANG_SPANISH} "Asociar RetroShare con la extensión de archivo .rsc" - LangString LANGUAGEID ${LANG_SPANISH} "1034" - - LangString sec_main ${LANG_ITALIAN} "Programmi" - LangString sec_data ${LANG_ITALIAN} "Temi del Programma" - LangString sec_plugins ${LANG_ITALIAN} "Plugins" - LangString sec_shortcuts ${LANG_ITALIAN} "Icone" - LangString sec_link ${LANG_ITALIAN} "Associazione dei File" - LangString sec_autostart ${LANG_ITALIAN} "Esecuzione Automatica" - LangString DESC_sec_main ${LANG_ITALIAN} "Installare i file programma di RetroShare." - LangString DESC_sec_data ${LANG_ITALIAN} "Installare i temi di RetroShare" - LangString DESC_sec_plugins ${LANG_ITALIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_ITALIAN} "Creare le icone per avviare RetroShare." - LangString DESC_sec_link ${LANG_ITALIAN} "Associa a RetroShare i file con estensione .rsc" - LangString LANGUAGEID ${LANG_ITALIAN} "1040" - - LangString sec_main ${LANG_GREEK} "Program Files" - LangString sec_data ${LANG_GREEK} "Program Skins" - LangString sec_plugins ${LANG_GREEK} "Plugins" - LangString sec_shortcuts ${LANG_GREEK} "Shortcuts" - LangString sec_link ${LANG_GREEK} "File Association" - LangString sec_autostart ${LANG_GREEK} "Auto Startup" - LangString DESC_sec_main ${LANG_GREEK} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_GREEK} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GREEK} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_GREEK} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_GREEK} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_GREEK} "1032" - - LangString sec_main ${LANG_PORTUGUESEBR} "Program Files" - LangString sec_data ${LANG_PORTUGUESEBR} "Program Skins" - LangString sec_plugins ${LANG_PORTUGUESEBR} "Plugins" - LangString sec_shortcuts ${LANG_PORTUGUESEBR} "Shortcuts" - LangString sec_link ${LANG_PORTUGUESEBR} "File Association" - LangString sec_autostart ${LANG_PORTUGUESEBR} "Auto Startup" - LangString DESC_sec_main ${LANG_PORTUGUESEBR} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_PORTUGUESEBR} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_PORTUGUESEBR} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_PORTUGUESEBR} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_PORTUGUESEBR} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_PORTUGUESEBR} "1046" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_plugins ${LANG_JAPANESE} "Plugins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_JAPANESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_plugins ${LANG_KOREAN} "Plugins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_KOREAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "${QTBASE}\mingw\bin\mingwm10.dll" - File /r "${QTBASE}\qt\bin\QtCore4.dll" - File /r "${QTBASE}\qt\bin\QtGui4.dll" - File /r "${QTBASE}\qt\bin\QtNetwork4.dll" - File /r "${QTBASE}\qt\bin\QtMultimedia4.dll" - File /r "${QTBASE}\qt\bin\QtXml4.dll" - File /r "${QTBASE}\qt\bin\QtScript4.dll" - File /r "${QTBASE}\qt\bin\QtSvg4.dll" - File /r "${QTBASE}\qt\bin\libgcc_s_dw2-1.dll" - File /r "${QTBASE}\qt\plugins\imageformats" - File /r ${QTBASE}\qt\qt_*.qm - File /r ${RSBASE}\src\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "d:\Development\lib\libminiupnpc-1.3\miniupnpc.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$APPDATA\RetroShare\stylesheets\" - File /r gui\qss\chat\Bubble - File /r gui\qss\chat\Bubble_Compact - - -SectionEnd - -SectionGroup $(sec_plugins) sec_plugins -Section Voip SEC001 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\VOIP\release\VOIP.dll" - -SectionEnd - -Section FeedReader SEC002 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\FeedReader\release\FeedReader.dll" - -SectionEnd -SectionGroupEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_plugins} $(DESC_sec_plugins) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Das RetroShare Support-Forum besuchen, um Neuigkeiten und Unterstützung zu erfahren" -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret et" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" -LangString FINISHPAGELINK ${LANG_SPANISH} "Visite los foros de RetroShare para las últimas noticias y soporte" -LangString FINISHPAGELINK ${LANG_ITALIAN} "Visita i forum di RetroShare per le ultime novità ed il supporto" -LangString FINISHPAGELINK ${LANG_GREEK} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_PORTUGUESEBR} "Visit the RetroShare forums for the latest news and support" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" -LangString ^UninstallLink ${LANG_SPANISH} "Desinstalar" -LangString ^UninstallLink ${LANG_ITALIAN} "Disinstallare" -LangString ^UninstallLink ${LANG_GREEK} "Απεγκατάσταση" -LangString ^UninstallLink ${LANG_PORTUGUESEBR} "Desinstalar" - -; eof diff --git a/retroshare-gui/src/retroshare.nsi b/retroshare-gui/src/retroshare.nsi deleted file mode 100644 index 9a604b44a..000000000 --- a/retroshare-gui/src/retroshare.nsi +++ /dev/null @@ -1,595 +0,0 @@ -; Script generated with the Venis Install Wizard & modified by defnax - -; Define your application name -!define APPNAME "RetroShare" -!define VERSION "0.5.5a" -!define REVISION "6725" -!define APPNAMEANDVERSION "${APPNAME} ${VERSION} ${REVISION}" -!define QTBASE "h:\qt\2010.05" -!define RSBASE "h:\Development\retroshare\retroshare-gui\" - -; Main Install settings -Name "${APPNAMEANDVERSION}" -InstallDir "$PROGRAMFILES\RetroShare" -InstallDirRegKey HKLM "Software\${APPNAME}" "" -OutFile "RetroShare_${VERSION}_${REVISION}_setup.exe" -BrandingText "${APPNAMEANDVERSION}" -; Use compression -SetCompressor /SOLID LZMA - -; Modern interface settings -!include Sections.nsh -!include "MUI.nsh" - -;Interface Settings -!define MUI_ABORTWARNING -;!define MUI_HEADERIMAGE -;!define MUI_HEADERIMAGE_BITMAP "retroshare.bmp" ; optional - -# MUI defines -!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico" -!define MUI_FINISHPAGE_NOAUTOCLOSE -!define MUI_LICENSEPAGE_RADIOBUTTONS -!define MUI_COMPONENTSPAGE_SMALLDESC -!define MUI_FINISHPAGE_LINK "$(FINISHPAGELINK)" -!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/" -!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe" -!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt -!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED -!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico" -!define MUI_UNFINISHPAGE_NOAUTOCLOSE -!define MUI_LANGDLL_REGISTRY_ROOT HKLM -!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY} -!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without havinf to reboot your computer. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - -;!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of RetroShare. \r\n\r\nIMPORTANT: Ensure that RetroShare is NOT RUNNING before continuing (you can exit from the taskbar menu), otherwise the installer cannot update the executables, and the installation will fail. \r\n\r\nClick Next to continue. " - - -; Defines the un-/installer logo of RetroShare -!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp" -!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp" - -; Set languages (first is default language) -!insertmacro MUI_RESERVEFILE_LANGDLL -ReserveFile "${NSISDIR}\Plugins\AdvSplash.dll" - -;-------------------------------- -;Configuration - - - ;!insertmacro MUI_RESERVEFILE_SPECIALBITMAP - - LicenseLangString myLicenseData 1030 "license\license.txt" - LicenseLangString myLicenseData 1031 "license\license-GER.txt" - LicenseLangString myLicenseData 1032 "license\license-GR.txt" - LicenseLangString myLicenseData 1033 "license\license.txt" - LicenseLangString myLicenseData 1034 "license\license-SP.txt" - LicenseLangString myLicenseData 1036 "license\license-FR.txt" - LicenseLangString myLicenseData 1040 "license\license-IT.txt" - LicenseLangString myLicenseData 1041 "license\license.txt" - LicenseLangString myLicenseData 1042 "license\license.txt" - LicenseLangString myLicenseData 1045 "license\license.txt" - LicenseLangString myLicenseData 1046 "license\license-PT_BR.txt" - LicenseLangString myLicenseData 1049 "license\license.txt" - LicenseLangString myLicenseData 1053 "license\license.txt" - LicenseLangString myLicenseData 1055 "license\license-TR.txt" - LicenseLangString myLicenseData 2052 "license\license.txt" - - LicenseData $(myLicenseData) - -# Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)" -!insertmacro MUI_PAGE_COMPONENTS -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES - -# Installer languages -!define MUI_LANGDLL_ALLLANGUAGES - -!insertmacro MUI_LANGUAGE English -!insertmacro MUI_LANGUAGE Danish -!insertmacro MUI_LANGUAGE French -!insertmacro MUI_LANGUAGE German -!insertmacro MUI_LANGUAGE Greek -!insertmacro MUI_LANGUAGE Italian -!insertmacro MUI_LANGUAGE Japanese -!insertmacro MUI_LANGUAGE Korean -!insertmacro MUI_LANGUAGE Polish -!insertmacro MUI_LANGUAGE PortugueseBR -!insertmacro MUI_LANGUAGE Russian -!insertmacro MUI_LANGUAGE Swedish -!insertmacro MUI_LANGUAGE SimpChinese -!insertmacro MUI_LANGUAGE Spanish -!insertmacro MUI_LANGUAGE Turkish - - - ;Component-selection page - ;Titles - - LangString sec_main ${LANG_ENGLISH} "Program Files" - LangString sec_data ${LANG_ENGLISH} "Program Skins" - LangString sec_shortcuts ${LANG_ENGLISH} "Shortcuts" - LangString sec_plugins ${LANG_ENGLISH} "Plugins" - LangString sec_link ${LANG_ENGLISH} "File Association" - LangString sec_autostart ${LANG_ENGLISH} "Auto Startup" - LangString DESC_sec_main ${LANG_ENGLISH} "Installs the RetroShare program files." - LangString DESC_sec_plugins ${LANG_ENGLISH} "Installs the RetroShare plugins." - LangString DESC_sec_data ${LANG_ENGLISH} "Installs RetroShare Skins" - LangString DESC_sec_shortcuts ${LANG_ENGLISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_ENGLISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_ENGLISH} "1033" - - LangString sec_main ${LANG_FRENCH} "RetroShare" - LangString sec_data ${LANG_FRENCH} "Programme de Skins" - LangString sec_plugins ${LANG_FRENCH} "Plugins" - LangString sec_shortcuts ${LANG_FRENCH} "Raccourcis" - LangString sec_link ${LANG_FRENCH} "Association de fichiers" - LangString sec_startmenu ${LANG_FRENCH} "Raccourcis du menu Démarrer" - LangString sec_autostart ${LANG_FRENCH} "Démarrage automatique" - LangString DESC_sec_main ${LANG_FRENCH} "Installation des fichiers du programme." - LangString DESC_sec_data ${LANG_FRENCH} "Installation des Skins de RetroShare" - LangString DESC_sec_plugins ${LANG_FRENCH} "Installation des extensions de RetroShare " - LangString DESC_sec_startmenu ${LANG_FRENCH} "Création des raccourcis du menu Démarrer" - LangString DESC_sec_shortcuts ${LANG_FRENCH} "Création de l'icône sur le bureau." - LangString DESC_sec_link ${LANG_FRENCH} "Associer RetroShare avec l'extension de fichier .rsc" - LangString LANGUAGEID ${LANG_FRENCH} "1036" - - LangString sec_main ${LANG_GERMAN} "Programme" - LangString sec_data ${LANG_GERMAN} "Programm Skins" - LangString sec_plugins ${LANG_GERMAN} "Plug-ins" - LangString sec_shortcuts ${LANG_GERMAN} "Verknüpfungen" - LangString sec_link ${LANG_GERMAN} "Dateiverknüpfungen" - LangString sec_autostart ${LANG_GERMAN} "Autostart" - LangString DESC_sec_main ${LANG_GERMAN} "Installiert die RetroShare Programmdateien." - LangString DESC_sec_data ${LANG_GERMAN} "Installiert RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GERMAN} "Installiert die RetroShare Erweiterungen." - LangString DESC_sec_shortcuts ${LANG_GERMAN} "RetroShare Verknüpfung im Startmenüe, Desktop oder im Schnellstarter erstellen." - LangString DESC_sec_link ${LANG_GERMAN} "RetroShare mit .rsc Dateiendung verknüpfen" - LangString LANGUAGEID ${LANG_GERMAN} "1031" - - LangString sec_main ${LANG_TURKISH} "Program Dosyalar?" - LangString sec_data ${LANG_TURKISH} "Program Skinleri" - LangString sec_shortcuts ${LANG_TURKISH} "Shortcut'lar" - LangString sec_plugins ${LANG_TURKISH} "Eklentiler" - LangString sec_link ${LANG_TURKISH} ".rsc Dosya Kaydet" - LangString sec_autostart ${LANG_TURKISH} "Otomatik calistir ve baglan" - LangString DESC_sec_main ${LANG_TURKISH} "Program dosyalar?n? kurar." - LangString DESC_sec_data ${LANG_TURKISH} "RetroShare Skin'leri kurar" - LangString DESC_sec_plugins ${LANG_TURKISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${TURKISH} "Shortcut yap Start menu , Desktop veya Quicklaunchbar icin." - LangString DESC_sec_link ${LANG_TURKISH} "RetroShare .rsc almas? i?in kaydettirir" - LangString LANGUAGEID ${LANG_TURKISH} "1055" - - LangString sec_main ${LANG_SIMPCHINESE} "程序文件" - LangString sec_data ${LANG_SIMPCHINESE} "程序皮肤" - LangString sec_plugins ${LANG_SIMPCHINESE} "Plugins" - LangString sec_shortcuts ${LANG_SIMPCHINESE} "快捷方式" - LangString sec_link ${LANG_SIMPCHINESE} "RetroShare文件关联" - LangString sec_autostart ${LANG_SIMPCHINESE} "自动启动" - LangString DESC_sec_main ${LANG_SIMPCHINESE} "安装RetroShare程序" - LangString DESC_sec_data ${LANG_SIMPCHINESE} "安装RetroShare皮肤" - LangString DESC_sec_plugins ${LANG_SIMPCHINESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SIMPCHINESE} "建RetroShare快捷方式" - LangString DESC_sec_link ${LANG_SIMPCHINESE} "关联.rsc扩展名" - LangString LANGUAGEID ${LANG_SIMPCHINESE} "2052" - - LangString sec_main ${LANG_POLISH} "Pliki programu" - LangString sec_data ${LANG_POLISH} "Skórki" - LangString sec_plugins ${LANG_POLISH} "Plugins" - LangString sec_shortcuts ${LANG_POLISH} "Skróty" - LangString sec_link ${LANG_POLISH} "Skojarz pliki" - LangString sec_autostart ${LANG_POLISH} "Automatyczne uruchamianie" - LangString DESC_sec_main ${LANG_POLISH} "Instaluje pliki programu RetroShare" - LangString DESC_sec_data ${LANG_POLISH} "Instaluje skórki programu RetroShare" - LangString DESC_sec_plugins ${LANG_POLISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_POLISH} "Utwórz ikony skrótów na pulpicie, w menu start oraz na pasku szybkiego uruchamiania." - LangString DESC_sec_link ${LANG_POLISH} "Skojarz pliki o rozszerzeniu .rsc z RetroShare" - LangString LANGUAGEID ${LANG_POLISH} "1045" - - LangString sec_main ${LANG_DANISH} "Program Files" - LangString sec_data ${LANG_DANISH} "Program Skins" - LangString sec_plugins ${LANG_DANISH} "Plugins" - LangString sec_shortcuts ${LANG_DANISH} "Shortcuts" - LangString sec_link ${LANG_DANISH} "File Association" - LangString sec_autostart ${LANG_DANISH} "Auto Startup" - LangString DESC_sec_main ${LANG_DANISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_DANISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_DANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_DANISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_DANISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_DANISH} "1030" - - LangString sec_main ${LANG_RUSSIAN} "Program Files" - LangString sec_data ${LANG_RUSSIAN} "Program Skins" - LangString sec_plugins ${LANG_RUSSIAN} "Plugins" - LangString sec_shortcuts ${LANG_RUSSIAN} "Shortcuts" - LangString sec_link ${LANG_RUSSIAN} "File Association" - LangString sec_autostart ${LANG_RUSSIAN} "Auto Startup" - LangString DESC_sec_main ${LANG_RUSSIAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_RUSSIAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_RUSSIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_RUSSIAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_RUSSIAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_RUSSIAN} "1049" - - LangString sec_main ${LANG_SWEDISH} "Program Files" - LangString sec_data ${LANG_SWEDISH} "Program Skins" - LangString sec_plugins ${LANG_SWEDISH} "Plugins" - LangString sec_shortcuts ${LANG_SWEDISH} "Shortcuts" - LangString sec_link ${LANG_SWEDISH} "File Association" - LangString sec_autostart ${LANG_SWEDISH} "Auto Startup" - LangString DESC_sec_main ${LANG_SWEDISH} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_SWEDISH} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_SWEDISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SWEDISH} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_SWEDISH} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_SWEDISH} "1053" - - LangString sec_main ${LANG_SPANISH} "Archivos de programa" - LangString sec_data ${LANG_SPANISH} "Estilos del programa" - LangString sec_plugins ${LANG_SPANISH} "Plugins" - LangString sec_shortcuts ${LANG_SPANISH} "Accesos directos" - LangString sec_link ${LANG_SPANISH} "Asociación de archivos" - LangString sec_autostart ${LANG_SPANISH} "Inicio automático" - LangString DESC_sec_main ${LANG_SPANISH} "Instala los archivos del programa RetroShare." - LangString DESC_sec_data ${LANG_SPANISH} "Instala los estilos para RetroShare" - LangString DESC_sec_plugins ${LANG_SPANISH} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_SPANISH} "Crear iconos de acceso directo de RetroShare." - LangString DESC_sec_link ${LANG_SPANISH} "Asociar RetroShare con la extensión de archivo .rsc" - LangString LANGUAGEID ${LANG_SPANISH} "1034" - - LangString sec_main ${LANG_ITALIAN} "Programmi" - LangString sec_data ${LANG_ITALIAN} "Temi del Programma" - LangString sec_plugins ${LANG_ITALIAN} "Plugins" - LangString sec_shortcuts ${LANG_ITALIAN} "Icone" - LangString sec_link ${LANG_ITALIAN} "Associazione dei File" - LangString sec_autostart ${LANG_ITALIAN} "Esecuzione Automatica" - LangString DESC_sec_main ${LANG_ITALIAN} "Installare i file programma di RetroShare." - LangString DESC_sec_data ${LANG_ITALIAN} "Installare i temi di RetroShare" - LangString DESC_sec_plugins ${LANG_ITALIAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_ITALIAN} "Creare le icone per avviare RetroShare." - LangString DESC_sec_link ${LANG_ITALIAN} "Associa a RetroShare i file con estensione .rsc" - LangString LANGUAGEID ${LANG_ITALIAN} "1040" - - LangString sec_main ${LANG_GREEK} "Program Files" - LangString sec_data ${LANG_GREEK} "Program Skins" - LangString sec_plugins ${LANG_GREEK} "Plugins" - LangString sec_shortcuts ${LANG_GREEK} "Shortcuts" - LangString sec_link ${LANG_GREEK} "File Association" - LangString sec_autostart ${LANG_GREEK} "Auto Startup" - LangString DESC_sec_main ${LANG_GREEK} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_GREEK} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_GREEK} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_GREEK} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_GREEK} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_GREEK} "1032" - - LangString sec_main ${LANG_PORTUGUESEBR} "Program Files" - LangString sec_data ${LANG_PORTUGUESEBR} "Program Skins" - LangString sec_plugins ${LANG_PORTUGUESEBR} "Plugins" - LangString sec_shortcuts ${LANG_PORTUGUESEBR} "Shortcuts" - LangString sec_link ${LANG_PORTUGUESEBR} "File Association" - LangString sec_autostart ${LANG_PORTUGUESEBR} "Auto Startup" - LangString DESC_sec_main ${LANG_PORTUGUESEBR} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_PORTUGUESEBR} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_PORTUGUESEBR} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_PORTUGUESEBR} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_PORTUGUESEBR} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_PORTUGUESEBR} "1046" - - LangString sec_main ${LANG_JAPANESE} "Program Files" - LangString sec_data ${LANG_JAPANESE} "Program Skins" - LangString sec_plugins ${LANG_JAPANESE} "Plugins" - LangString sec_shortcuts ${LANG_JAPANESE} "Shortcuts" - LangString sec_link ${LANG_JAPANESE} "File Association" - LangString sec_autostart ${LANG_JAPANESE} "Auto Startup" - LangString DESC_sec_main ${LANG_JAPANESE} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_JAPANESE} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_JAPANESE} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_JAPANESE} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_JAPANESE} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_JAPANESE} "1041" - - LangString sec_main ${LANG_KOREAN} "Program Files" - LangString sec_data ${LANG_KOREAN} "Program Skins" - LangString sec_plugins ${LANG_KOREAN} "Plugins" - LangString sec_shortcuts ${LANG_KOREAN} "Shortcuts" - LangString sec_link ${LANG_KOREAN} "File Association" - LangString sec_autostart ${LANG_KOREAN} "Auto Startup" - LangString DESC_sec_main ${LANG_KOREAN} "Installs the RetroShare program files." - LangString DESC_sec_data ${LANG_KOREAN} "Installs RetroShare Skins" - LangString DESC_sec_plugins ${LANG_KOREAN} "Installs the RetroShare plugins." - LangString DESC_sec_shortcuts ${LANG_KOREAN} "Create RetroShare shortcut icons." - LangString DESC_sec_link ${LANG_KOREAN} "Associate RetroShare with .rsc file extension" - LangString LANGUAGEID ${LANG_KOREAN} "1042" - - -!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS - -Section $(sec_main) sec_main - - ;Set Section required - SectionIn RO - - ; Set Section properties - SetOverwrite on - - ; Clears previous error logs - Delete "$INSTDIR\*.log" - - ; Set Section Files and Shortcuts - SetOutPath "$INSTDIR\" - File /r "release\RetroShare.exe" - File /r "..\..\retroshare-nogui\src\release\retroshare-nogui.exe" - File /r "${QTBASE}\mingw\bin\mingwm10.dll" - File /r "${QTBASE}\qt\bin\QtCore4.dll" - File /r "${QTBASE}\qt\bin\QtGui4.dll" - File /r "${QTBASE}\qt\bin\QtNetwork4.dll" - File /r "${QTBASE}\qt\bin\QtMultimedia4.dll" - File /r "${QTBASE}\qt\bin\QtXml4.dll" - File /r "${QTBASE}\qt\bin\QtScript4.dll" - File /r "${QTBASE}\qt\bin\QtSvg4.dll" - File /r "${QTBASE}\qt\bin\libgcc_s_dw2-1.dll" - File /r "${QTBASE}\qt\plugins\imageformats" - File /r ${QTBASE}\qt\qt_*.qm - File /r ${RSBASE}\src\qt_*.qm - File /r "release\pthreadGC2d.dll" - File /r "h:\Development\lib\libminiupnpc-1.3\miniupnpc.dll" - File /r "changelog.txt" - File /r /x Data "release\bdboot.txt" - - -SectionEnd - -Section $(sec_data) sec_data - - ; Set Section properties - SetOverwrite on - - ; Set Section Files and Shortcuts - SetOutPath "$APPDATA\RetroShare\" - ;File /r "data\*" - - ; Set Section qss and exclude svn - SetOutPath "$INSTDIR\qss\" - File /r /x .svn qss\*.* - - ; Set Section sounds and exclude svn - SetOutPath "$INSTDIR\sounds\" - File /r /x .svn sounds\*.* - - ; Set Section skin - ; SetOutPath "$INSTDIR\skin\" - ; File /r release\skin\*.* - - ; Add emoticons - ;SetOutPath "$INSTDIR\emoticons\" - ;File /r emoticons\*.* - - ; Add Chat Style - SetOutPath "$APPDATA\RetroShare\stylesheets\" - File /r gui\qss\chat\Bubble - File /r gui\qss\chat\Bubble_Compact - - -SectionEnd - -SectionGroup $(sec_plugins) sec_plugins -Section Voip SEC001 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\VOIP\release\VOIP.dll" - -SectionEnd - -Section FeedReader SEC002 - - ; Set Section properties - SetOverwrite on - - ; Set Section Plugins - SetOutPath "$APPDATA\RetroShare\extensions\" - - File /r "..\..\plugins\FeedReader\release\FeedReader.dll" - -SectionEnd - -SectionGroupEnd - -Section $(sec_link) sec_link - ; Delete any existing keys - - - ; Write the file association - WriteRegStr HKCR .rsc "" retroshare - WriteRegStr HKCR retroshare "" "RSC File" - WriteRegBin HKCR retroshare EditFlags 00000100 - WriteRegStr HKCR "retroshare\shell" "" open - WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"` - -SectionEnd - -SectionGroup $(sec_shortcuts) sec_shortcuts -Section StartMenu SEC0001 - - SetOutPath "$INSTDIR" - CreateDirectory "$SMPROGRAMS\${APPNAME}" - CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - CreateShortCut "$SMPROGRAMS\${APPNAME}\$(^UninstallLink).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - -SectionEnd - -Section Desktop SEC0002 - - - CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd - -Section Quicklaunchbar SEC0003 - - - CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 - -SectionEnd -SectionGroupEnd - -;Section $(sec_autostart) sec_autostart - -; WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" "$INSTDIR\${APPNAME}.exe -a" - -;SectionEnd - -;Section $(sec_autostart) sec_autostart - -; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0 -;SectionEnd - - -Section -FinishSection - - WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR" - WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe" - WriteUninstaller "$INSTDIR\uninstall.exe" - -SectionEnd - - - -;-------------------------------- -;Descriptions - -!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${sec_main} $(DESC_sec_main) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_data} $(DESC_sec_data) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_plugins} $(DESC_sec_plugins) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_shortcuts} $(DESC_sec_shortcuts) - !insertmacro MUI_DESCRIPTION_TEXT ${sec_link} $(DESC_sec_link) - ;!insertmacro MUI_DESCRIPTION_TEXT ${sec_autostart} $(DESC_sec_autostart) -!insertmacro MUI_FUNCTION_DESCRIPTION_END - -;Uninstall section -Section "Uninstall" - - ; Remove file association registry keys - DeleteRegKey HKCR .rsc - DeleteRegKey HKCR retroshare - - ; Remove program/uninstall regsitry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" - DeleteRegKey HKLM SOFTWARE\${APPNAME} - - DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroRun" - - ; Remove files and uninstaller - Delete $INSTDIR\RetroShare.exe - Delete $INSTDIR\*.dll - Delete $INSTDIR\*.dat - Delete $INSTDIR\*.txt - Delete $INSTDIR\*.ini - Delete $INSTDIR\*.log - - Delete $INSTDIR\uninstall.exe - - ; Remove the kadc.ini file. - ; Don't remove the directory, otherwise - ; we lose the XPGP keys. - ; Should make this an option though... - Delete "$APPDATA\${APPNAME}\kadc.ini" - Delete "$APPDATA\${APPNAME}\*.cfg" - Delete "$APPDATA\${APPNAME}\*.conf" - Delete "$APPDATA\${APPNAME}\*.log-save" - Delete "$APPDATA\${APPNAME}\*.log" - Delete "$APPDATA\${APPNAME}\*.failed" - - RMDir /r "$APPDATA\${APPNAME}\cache" - RMDir /r "$APPDATA\${APPNAME}\Partials" - - ; Remove shortcuts, if any - Delete "$SMPROGRAMS\${APPNAME}\*.*" - - ; Remove desktop shortcut - Delete "$DESKTOP\${APPNAME}.lnk" - - ; Remove Quicklaunch shortcut - Delete "$QUICKLAUNCH\${APPNAME}.lnk" - - ; Remove Autostart - ;Delete "$SMSTARTUP\${APPNAME}.lnk" - - ; Remove directories used - RMDir "$SMPROGRAMS\${APPNAME}" - RMDir /r "$INSTDIR" - RMDir /r "$INSTDIR\qss" - RMDir /r "$INSTDIR\emoticons" - RMDir /r "$INSTDIR\style" - RMDir /r "$INSTDIR\translations" - -SectionEnd - -Function .onInit - - InitPluginsDir - Push $R1 - File /oname=$PLUGINSDIR\spltmp.bmp "gui\images\splash.bmp" - advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp - Pop $R1 - Pop $R1 - !insertmacro MUI_LANGDLL_DISPLAY - - - -FunctionEnd - - -# Installer Language Strings -# TODO Update the Language Strings with the appropriate translations. - - -LangString FINISHPAGELINK ${LANG_ENGLISH} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_GERMAN} "Das RetroShare Support-Forum besuchen, um Neuigkeiten und Unterstützung zu erfahren" -LangString FINISHPAGELINK ${LANG_TURKISH} "Destek için Retroshare foruma ziyaret et" -LangString FINISHPAGELINK ${LANG_FRENCH} "Consultez le forum RetroShare pour vous tenir au courant des dernieres modifications, et obtenir de l'aide." -LangString FINISHPAGELINK ${LANG_SIMPCHINESE} "帮助论坛" -LangString FINISHPAGELINK ${LANG_POLISH} "Odwiedź forum RetroShare do najświeższych informacji i wsparcia" -LangString FINISHPAGELINK ${LANG_DANISH} "Besøg RetroShare fora for de seneste nyheder og støtte" -LangString FINISHPAGELINK ${LANG_JAPANESE} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_KOREAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_RUSSIAN} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_SWEDISH} "Besök RetroShare forum för de senaste nyheterna och stöd" -LangString FINISHPAGELINK ${LANG_SPANISH} "Visite los foros de RetroShare para las últimas noticias y soporte" -LangString FINISHPAGELINK ${LANG_ITALIAN} "Visita i forum di RetroShare per le ultime novità ed il supporto" -LangString FINISHPAGELINK ${LANG_GREEK} "Visit the RetroShare forums for the latest news and support" -LangString FINISHPAGELINK ${LANG_PORTUGUESEBR} "Visit the RetroShare forums for the latest news and support" - -LangString ^UninstallLink ${LANG_ENGLISH} "Uninstall" -LangString ^UninstallLink ${LANG_GERMAN} "Deinstallieren" -LangString ^UninstallLink ${LANG_TURKISH} "Kald�r" -LangString ^UninstallLink ${LANG_FRENCH} "Désinstaller" -LangString ^UninstallLink ${LANG_SIMPCHINESE} "卸载" -LangString ^UninstallLink ${LANG_POLISH} "Odinstaluj" -LangString ^UninstallLink ${LANG_DANISH} "Afinstaller" -LangString ^UninstallLink ${LANG_JAPANESE} "Uninstall" -LangString ^UninstallLink ${LANG_KOREAN} "Uninstall" -LangString ^UninstallLink ${LANG_RUSSIAN} "Uninstall" -LangString ^UninstallLink ${LANG_SWEDISH} "Avinstallera" -LangString ^UninstallLink ${LANG_SPANISH} "Desinstalar" -LangString ^UninstallLink ${LANG_ITALIAN} "Disinstallare" -LangString ^UninstallLink ${LANG_GREEK} "Απεγκατάσταση" -LangString ^UninstallLink ${LANG_PORTUGUESEBR} "Desinstalar" - -; eof diff --git a/retroshare-gui/src/rshare.cpp b/retroshare-gui/src/rshare.cpp index cbed6698a..8fb8fdc58 100644 --- a/retroshare-gui/src/rshare.cpp +++ b/retroshare-gui/src/rshare.cpp @@ -174,17 +174,17 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) if(args.empty()) sendArgsToRunningInstance = false; // if we find non-forwardable args, start a new instance - for(int i = 0; i < args.size(); ++i) + for(int iCurs = 0; iCurs < args.size(); ++iCurs) { const char* const* argit = forwardableArgs; bool found = false; - while(*argit && i < args.size()) + while(*argit && iCurs < args.size()) { - if(args.value(i) == "-"+QString(*argit) || args.value(i) == "--"+QString(*argit)) + if(args.value(iCurs) == "-"+QString(*argit) || args.value(iCurs) == "--"+QString(*argit)) { found = true; if(argNeedsValue(*argit)) - i++; + iCurs++; } argit++; } @@ -464,12 +464,12 @@ Rshare::showUsageMessageBox() /** Returns true if the specified argument expects a value. */ bool -Rshare::argNeedsValue(QString argName) +Rshare::argNeedsValue(const QString &argName) { return ( argName == ARG_DATADIR || argName == ARG_LOGFILE || - argName == ARG_LOGLEVEL || + argName == ARG_LOGLEVEL || argName == ARG_GUISTYLE || argName == ARG_GUISTYLESHEET || argName == ARG_LANGUAGE || @@ -486,25 +486,26 @@ Rshare::argNeedsValue(QString argName) void Rshare::parseArguments(QStringList args, bool firstRun) { - QString arg, value; + QString arg, argl, value; /* Loop through all command-line args/values and put them in a map */ - for (int i = 0; i < args.size(); ++i) { + for (int iCurs = 0; iCurs < args.size(); ++iCurs) { /* Get the argument name and set a blank value */ - arg = args.at(i);//.toLower(); Need Upper case for file name. - if (arg.toLower() == "empty") continue; + arg = args.at(iCurs);//.toLower(); Need Upper case for file name. + argl = arg.toLower(); + if (argl == "empty") continue; value = ""; /* Check if it starts with a - or -- */ if (arg.startsWith("-")) { arg = arg.mid((arg.startsWith("--") ? 2 : 1)); /* Check if it takes a value and there is one on the command-line */ - if (i < args.size()-1 && argNeedsValue(arg.toLower())) { - value = args.at(++i); + if (iCurs < args.size()-1 && argNeedsValue(arg)) { + value = args.at(++iCurs); } } else { /* Check if links or files without arg */ - if (arg.toLower().startsWith("retroshare://")) { + if (argl.startsWith("retroshare://")) { value = arg; arg = ARG_RSLINK_L; } else { @@ -518,8 +519,8 @@ Rshare::parseArguments(QStringList args, bool firstRun) /* handle opmode that could be change while running.*/ QString omValue = QString(value).prepend(";").append(";").toLower(); QString omValues = QString(";full;noturtle;gaming;minimal;"); - if ((arg == ARG_OPMODE_S || arg == ARG_OPMODE_L ) && - omValues.contains(omValue)) { + if ((arg == ARG_OPMODE_S || arg == ARG_OPMODE_L ) + && omValues.contains(omValue)) { _opmode = value; } @@ -542,8 +543,8 @@ Rshare::validateArguments(QString &errmsg) /* Check for a writable log file */ if (_args.contains(ARG_LOGFILE) && !_log.isOpen()) { errmsg = tr("Unable to open log file '%1': %2") - .arg(_args.value(ARG_LOGFILE)) - .arg(_log.errorString()); + .arg( _args.value(ARG_LOGFILE) + , _log.errorString()); return false; } /* Check for a valid log level */ @@ -688,8 +689,8 @@ void Rshare::resetLanguageAndStyle() // RetroShare: // Default: -// :/qss/stylesheet/qss.default -// :/qss/stylesheet/qss. +// :/qss/stylesheet/default.qss +// :/qss/stylesheet/.qss // Internal: // :/qss/stylesheet/.qss // External: @@ -699,8 +700,8 @@ void Rshare::resetLanguageAndStyle() // // Plugin: // Default: -// :/qss/stylesheet//_qss.default -// :/qss/stylesheet//_qss. +// :/qss/stylesheet//_default.qss +// :/qss/stylesheet//_.qss // Internal: // :/qss/stylesheet//_.qss // External: @@ -719,8 +720,8 @@ void Rshare::loadStyleSheet(const QString &sheetName) /* Get stylesheet from plugins */ if (rsPlugins) { int count = rsPlugins->nbPlugins(); - for (int i = 0; i < count; ++i) { - RsPlugin* plugin = rsPlugins->plugin(i); + for (int iCurs = 0; iCurs < count; ++iCurs) { + RsPlugin* plugin = rsPlugins->plugin(iCurs); if (plugin) { QString pluginStyleSheetName = QString::fromUtf8(plugin->qt_stylesheet().c_str()); if (!pluginStyleSheetName.isEmpty()) { @@ -732,22 +733,22 @@ void Rshare::loadStyleSheet(const QString &sheetName) foreach (QString name, names) { /* load the default stylesheet */ - QFile file(QString(":/qss/stylesheet/%1qss.default").arg(name)); + QFile file(QString(":/qss/stylesheet/%1default.qss").arg(name)); if (file.open(QFile::ReadOnly)) { styleSheet += QLatin1String(file.readAll()) + "\n"; file.close(); } /* load locale depended default stylesheet */ - file.setFileName(QString(":/qss/stylesheet/%1qss.%2").arg(name, locale)); + file.setFileName(QString(":/qss/stylesheet/%1%2.qss").arg(name, locale)); if (file.open(QFile::ReadOnly)) { styleSheet += QLatin1String(file.readAll()) + "\n"; file.close(); } - if (!sheetName.isEmpty()) { + if (!sheetName.isEmpty() && (sheetName != ":default")) { /* load stylesheet */ - if (sheetName.left(1) == ":") { + if (sheetName.at(0) == ':') { /* internal stylesheet */ file.setFileName(QString(":/qss/stylesheet/%1%2.qss").arg(name, sheetName.mid(1))); } else { @@ -786,7 +787,7 @@ void Rshare::getAvailableStyleSheets(QMap &styleSheets) foreach (fileInfo, fileInfoList) { if (fileInfo.isFile()) { QString name = fileInfo.baseName(); - styleSheets.insert(QString("%1 (%2)").arg(name, tr("built-in")), ":" + name); + styleSheets.insert(QString(" %1 (%2)").arg(name, tr("built-in")), ":" + name);//Add space to name to get them up because QMap sort by Key. } } fileInfoList = QDir(QString::fromUtf8(RsAccounts::ConfigDirectory().c_str()) + "/qss/").entryInfoList(QStringList("*.qss")); @@ -880,7 +881,7 @@ Rshare::createDataDirectory(QString *errmsg) } /** Set Rshare's data directory - externally */ -bool Rshare::setConfigDirectory(QString dir) +bool Rshare::setConfigDirectory(const QString& dir) { useConfigDir = true; configDir = dir; @@ -946,30 +947,42 @@ bool Rshare::loadCertificate(const RsPeerId &accountId, bool autoLogin) } std::string lockFile; - int retVal = RsInit::LockAndLoadCertificates(autoLogin, lockFile); - switch (retVal) { - case 0: break; - case 1: QMessageBox::warning( 0, - QObject::tr("Multiple instances"), - QObject::tr("Another RetroShare using the same profile is " - "already running on your system. Please close " - "that instance first\n Lock file:\n") + - QString::fromUtf8(lockFile.c_str())); - return false; - case 2: QMessageBox::critical( 0, - QObject::tr("Multiple instances"), - QObject::tr("An unexpected error occurred when Retroshare " - "tried to acquire the single instance lock\n Lock file:\n") + - QString::fromUtf8(lockFile.c_str())); - return false; - case 3: -// case 3: QMessageBox::critical( 0, -// QObject::tr("Login Failure"), -// QObject::tr("Maybe password is wrong") ); - return false; - default: std::cerr << "Rshare::loadCertificate() unexpected switch value " << retVal << std::endl; - return false; - } + RsInit::LoadCertificateStatus retVal = RsInit::LockAndLoadCertificates(autoLogin, lockFile); + + switch (retVal) + { + case RsInit::OK: + break; + case RsInit::ERR_ALREADY_RUNNING: QMessageBox::warning( nullptr, + QObject::tr("Multiple instances"), + QObject::tr("Another RetroShare using the same profile is " + "already running on your system. Please close " + "that instance first\n Lock file:\n") + + QString::fromUtf8(lockFile.c_str())); + return false; + case RsInit::ERR_CANT_ACQUIRE_LOCK: QMessageBox::critical( nullptr, + QObject::tr("Multiple instances"), + QObject::tr("An unexpected error occurred when Retroshare " + "tried to acquire the single instance lock\n Lock file:\n") + + QString::fromUtf8(lockFile.c_str())); + return false; + case RsInit::ERR_CERT_CRYPTO_IS_TOO_WEAK: QMessageBox::critical( nullptr, + QObject::tr("Old certificate"), + QObject::tr("This node uses old certificate settings that are considered too " + "weak by your current OpenSSL library version. You need to create a new node " + "possibly using the same profile.")); + return false; + case RsInit::ERR_CANNOT_CONFIGURE_TOR: QMessageBox::critical( nullptr, + QObject::tr("Tor error"), + QObject::tr("Cannot run/configure Tor. Make sure it is installed on your system.")); + return false; + // case 3: QMessageBox::critical( 0, + // QObject::tr("Login Failure"), + // QObject::tr("Maybe password is wrong") ); + return false; + default: std::cerr << "Rshare::loadCertificate() unexpected switch value " << retVal << std::endl; + return false; + } return true; } diff --git a/retroshare-gui/src/rshare.h b/retroshare-gui/src/rshare.h index e1b68f6b6..2b59b7875 100644 --- a/retroshare-gui/src/rshare.h +++ b/retroshare-gui/src/rshare.h @@ -38,7 +38,7 @@ #include "retroshare/rstypes.h" /** Pointer to this RetroShare application instance. */ -#define rApp ((Rshare *)qApp) +#define rApp (static_cast(qApp)) #define rDebug(fmt) (rApp->log(Log::Debug, (fmt))) #define rInfo(fmt) (rApp->log(Log::Info, (fmt))) @@ -130,7 +130,7 @@ public: static Log::LogMessage log(Log::LogLevel level, QString msg); /** Creates Rshare's data directory, if it doesn't already exist. */ - static bool setConfigDirectory(QString dir); + static bool setConfigDirectory(const QString &dir); /** Enters the main event loop and waits until exit() is called. The signal * running() will be emitted when the event loop has started. */ @@ -177,7 +177,7 @@ private: static void customizeDateFormat(); /** Returns true if the specified arguments wants a value. */ - static bool argNeedsValue(QString argName); + static bool argNeedsValue(const QString &argName); static QMap _args; /**< List of command-line arguments. */ static Log _log; /**< Logs debugging messages to file or stdout. */ @@ -185,7 +185,7 @@ private: static QString _stylesheet; /**< The current GUI stylesheet. */ static QString _language; /**< The current language. */ static QString _dateformat; /**< The format for dates in feed items etc. */ - static QString _opmode; /**< The operating mode passed by args. */ + static QString _opmode; /**< The operating mode passed by args. */ static QStringList _links; /**< List of links passed by arguments. */ static QStringList _files; /**< List of files passed by arguments. */ static QDateTime mStartupTime; // startup time diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp index 08ecf18c6..0ff9d851b 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.cpp @@ -18,8 +18,14 @@ * * *******************************************************************************/ +#include +#include +#include + #include "AspectRatioPixmapLabel.h" #include +#include "util/imageutil.h" +#include "gui/common/FilesDefs.h" AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : QLabel(parent) @@ -31,7 +37,7 @@ AspectRatioPixmapLabel::AspectRatioPixmapLabel(QWidget *parent) : void AspectRatioPixmapLabel::setPixmap ( const QPixmap & p) { pix = p; - QLabel::setPixmap(pix); + QLabel::setPixmap(scaledPixmap()); //std::cout << "Information size: " << pix.width() << 'x' << pix.height() << std::endl; } @@ -57,3 +63,53 @@ void AspectRatioPixmapLabel::resizeEvent(QResizeEvent * e) QLabel::resizeEvent(e); //std::cout << "Information resized: " << e->oldSize().width() << 'x' << e->oldSize().height() << " to " << e->size().width() << 'x' << e->size().height() << std::endl; } + +void AspectRatioPixmapLabel::addContextMenuAction(QAction *action) +{ + mContextMenuActions.push_back(action); +} + +void AspectRatioPixmapLabel::contextMenuEvent(QContextMenuEvent *event) +{ + emit calculateContextMenuActions(); + + QMenu *contextMenu = new QMenu(); + + QAction *actionSaveImage = contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage())); + QAction *actionCopyImage = contextMenu->addAction(tr("Copy image"), this, SLOT(copyImage())); + + if (pix.isNull()) { + actionSaveImage->setEnabled(false); + actionCopyImage->setEnabled(false); + } else { + actionSaveImage->setEnabled(true); + actionCopyImage->setEnabled(true); + } + + QList::iterator it; + for (it = mContextMenuActions.begin(); it != mContextMenuActions.end(); ++it) { + contextMenu->addAction(*it); + } + + contextMenu->exec(event->globalPos()); + + delete(contextMenu); +} + +void AspectRatioPixmapLabel::copyImage() +{ + if (pix.isNull()) { + return; + } + + QApplication::clipboard()->setPixmap(pix, QClipboard::Clipboard); +} + +void AspectRatioPixmapLabel::saveImage() +{ + if (pix.isNull()) { + return; + } + + ImageUtil::saveImage(window(), pix.toImage()); +} diff --git a/retroshare-gui/src/util/AspectRatioPixmapLabel.h b/retroshare-gui/src/util/AspectRatioPixmapLabel.h index ad7c40e4c..be6e79077 100644 --- a/retroshare-gui/src/util/AspectRatioPixmapLabel.h +++ b/retroshare-gui/src/util/AspectRatioPixmapLabel.h @@ -28,17 +28,33 @@ class AspectRatioPixmapLabel : public QLabel { Q_OBJECT + public: explicit AspectRatioPixmapLabel(QWidget *parent = nullptr); virtual int heightForWidth( int width ) const override; virtual QSize sizeHint() const override; QPixmap scaledPixmap() const; + + // Add QAction to context menu (action won't be deleted) + void addContextMenuAction(QAction *action); + +Q_SIGNALS: + void calculateContextMenuActions(); + public slots: void setPixmap ( const QPixmap & ); + protected: void resizeEvent(QResizeEvent *event) override; + virtual void contextMenuEvent(QContextMenuEvent *event); + +private slots: + void copyImage(); + void saveImage(); + private: QPixmap pix; + QList mContextMenuActions; }; #endif // ASPECTRATIOPIXMAPLABEL_H diff --git a/retroshare-gui/src/util/ClickableLabel.cpp b/retroshare-gui/src/util/ClickableLabel.cpp index e12e01c8d..6bbd5ca4a 100644 --- a/retroshare-gui/src/util/ClickableLabel.cpp +++ b/retroshare-gui/src/util/ClickableLabel.cpp @@ -22,7 +22,7 @@ /** Constructor */ ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f) - : QLabel(parent) { + : QLabel(parent, f) { } @@ -30,6 +30,6 @@ ClickableLabel::~ClickableLabel() { } -void ClickableLabel::mousePressEvent(QMouseEvent* event) { +void ClickableLabel::mousePressEvent(QMouseEvent* /*event*/) { emit clicked(); } diff --git a/retroshare-gui/src/util/HandleRichText.cpp b/retroshare-gui/src/util/HandleRichText.cpp index b635703d7..6f6eec750 100644 --- a/retroshare-gui/src/util/HandleRichText.cpp +++ b/retroshare-gui/src/util/HandleRichText.cpp @@ -334,6 +334,29 @@ void RsHtml::replaceAnchorWithImg(QDomDocument &doc, QDomElement &element, QText element.appendChild(img); } +void RsHtml::filterEmbeddedImages(QDomDocument &doc, QDomElement ¤tElement) +{ + QDomNodeList children = currentElement.childNodes(); + for(uint index = 0; index < (uint)children.length(); index++) { + QDomNode node = children.item(index); + if(node.isElement()) { + QDomElement element = node.toElement(); + if(element.tagName().toLower() == "img") { + if(element.hasAttribute("src")) { + QString src = element.attribute("src"); + // Do not allow things in the image source, except these: + // :/ internal resource needed for emotes + // data:image base64 embedded image needed for stickers + if(!src.startsWith(":/") && !src.startsWith("data:image", Qt::CaseInsensitive)) { + element.setAttribute("src", ":/images/imageblocked_24.png"); + } + } + } + filterEmbeddedImages(doc, element); + } + } +} + int RsHtml::indexInWithValidation(QRegExp &rx, const QString &text, EmbedInHtml &embedInfos, int pos) { int index = rx.indexIn(text, pos); @@ -618,13 +641,17 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo QString errorMsg; int errorLine; int errorColumn; - QDomDocument doc; + QDomDocument doc; if (doc.setContent(formattedText, &errorMsg, &errorLine, &errorColumn) == false) { - // convert text with QTextBrowser - QTextBrowser textBrowser; - textBrowser.setText(text); - formattedText=textBrowser.toHtml(); + // convert text with QTextDocument + QTextDocument textDoc; + if (Qt::mightBeRichText(formattedText)) + textDoc.setHtml(formattedText); + else + textDoc.setPlainText(text); + + formattedText=textDoc.toHtml(); formattedText.remove(0,formattedText.indexOf("<")); formattedText=saveSpace(formattedText); doc.setContent(formattedText, &errorMsg, &errorLine, &errorColumn); @@ -632,6 +659,7 @@ QString RsHtml::formatText(QTextDocument *textDocument, const QString &text, ulo } QDomElement body = doc.documentElement(); + filterEmbeddedImages(doc, body); // This should be first, becuse it should not overwrite embedded custom smileys if (flag & RSHTML_FORMATTEXT_EMBED_SMILEYS) { embedHtml(textDocument, doc, body, defEmbedImg, flag); } @@ -1188,7 +1216,7 @@ bool RsHtml::makeEmbeddedImage(const QString &fileName, QString &embeddedImage, fprintf (stderr, "RsHtml::makeEmbeddedImage() - image \"%s\" can't be load\n", fileName.toLatin1().constData()); return false; } - return RsHtml::makeEmbeddedImage(image, embeddedImage, maxPixels, maxBytes); + return RsHtml::makeEmbeddedImage(image, embeddedImage, maxPixels, maxBytes); } /** Converts image to embedded image HTML fragment **/ @@ -1196,7 +1224,7 @@ bool RsHtml::makeEmbeddedImage(const QImage &originalImage, QString &embeddedIma { rstime::RsScopeTimer s("Embed image"); QImage opt; - return ImageUtil::optimizeSizeHtml(embeddedImage, originalImage, opt, maxPixels, maxBytes); + return ImageUtil::optimizeSizeHtml(embeddedImage, originalImage, opt, maxPixels, maxBytes); } QString RsHtml::plainText(const QString &text) diff --git a/retroshare-gui/src/util/HandleRichText.h b/retroshare-gui/src/util/HandleRichText.h index 8189e4ce1..3e98ea21c 100644 --- a/retroshare-gui/src/util/HandleRichText.h +++ b/retroshare-gui/src/util/HandleRichText.h @@ -70,7 +70,7 @@ public: static QString toHtml(QString text, bool realHtml = true); static bool makeEmbeddedImage(const QString &fileName, QString &embeddedImage, const int maxPixels, const int maxBytes = -1); - static bool makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels, const int maxBytes = -1); + static bool makeEmbeddedImage(const QImage &originalImage, QString &embeddedImage, const int maxPixels, const int maxBytes = -1); static QString plainText(const QString &text); static QString plainText(const std::string &text); @@ -82,6 +82,7 @@ public: protected: void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement ¤tElement, EmbedInHtml& embedInfos, ulong flag); void replaceAnchorWithImg(QDomDocument& doc, QDomElement &element, QTextDocument *textDocument, const RetroShareLink &link); + void filterEmbeddedImages(QDomDocument &doc, QDomElement ¤tElement); virtual bool canReplaceAnchor(QDomDocument &doc, QDomElement &element, const RetroShareLink &link); virtual void anchorTextForImg(QDomDocument &doc, QDomElement &element, const RetroShareLink &link, QString &text); diff --git a/retroshare-gui/src/util/RichTextEdit.ui b/retroshare-gui/src/util/RichTextEdit.ui index 7b5ffc6ae..63e624b5e 100644 --- a/retroshare-gui/src/util/RichTextEdit.ui +++ b/retroshare-gui/src/util/RichTextEdit.ui @@ -48,7 +48,7 @@ 0 - + Qt::ClickFocus @@ -61,7 +61,7 @@ - + MS Sans Serif @@ -595,6 +595,11 @@ QTextEdit
    gui/common/MimeTextEdit.h
    + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    f_textedit diff --git a/retroshare-gui/src/util/imageutil.cpp b/retroshare-gui/src/util/imageutil.cpp index 47029505e..612387724 100644 --- a/retroshare-gui/src/util/imageutil.cpp +++ b/retroshare-gui/src/util/imageutil.cpp @@ -23,8 +23,12 @@ #include "util/rstime.h" #include +#include +#include #include #include +#include +#include #include #include #include @@ -37,6 +41,64 @@ ImageUtil::ImageUtil() {} +bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut) +{ + QString imageStr; + return checkImage(edit, pos, imageStr, cursorRectStartOut, cursorRectLeftOut, cursorRectRightOut, cursorRectEndOut); +} + +bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut) +{ + //Get text cursor under pos. But if pos is under text browser end line this return last cursor. + QTextCursor cursor = edit->cursorForPosition(pos); + //First get rect of cursor (could be at left or right of image) + QRect cursorRectStart = edit->cursorRect(cursor); + //Second get text + cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before + QRect cursorRectLeft = edit->cursorRect(cursor); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2); + QRect cursorRectRight = edit->cursorRect(cursor); + imageStr = cursor.selection().toHtml(); + + if (cursorRectStartOut) { + *cursorRectStartOut = cursorRectStart; + } + if (cursorRectLeftOut) { + *cursorRectLeftOut = cursorRectLeft; + } + if (cursorRectRightOut) { + *cursorRectRightOut = cursorRectRight; + } + + QRect cursorRectEnd = cursorRectStart; + //Finally set left with right of precedent character. + if (cursorRectEnd.top() < cursorRectLeft.bottom()) + { + cursorRectEnd.setLeft(cursorRectLeft.right()); + } else { + //Image on new line + cursorRectEnd.setLeft(0); + } + //And set Right with left of next character. + if (cursorRectEnd.bottom() > cursorRectRight.top()) + { + cursorRectEnd.setRight(cursorRectRight.left()); + } else { + //New line after Image. + } + + if (cursorRectEndOut) { + *cursorRectEndOut = cursorRectEnd; + } + + //If pos is on text rect + if (cursorRectEnd.contains(pos)) + { + return imageStr.indexOf("base64,") != -1; + } + return false; +} + void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file) { cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); @@ -53,13 +115,7 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file) if(!image.isNull()) { success = true; - if(!file.isEmpty() || misc::getSaveFileName(window, RshareSettings::LASTDIR_IMAGES, "Save Picture File", "Pictures (*.png *.xpm *.jpg)", file)) - { - if(!image.save(file, nullptr, 100)) - if(!image.save(file + ".png", nullptr, 100)) - QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Cannot save the image, invalid filename") - + "\n" + file); - } + saveImage(window, image, file); } } if(!success) @@ -68,12 +124,60 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file) } } -bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, int maxPixels, int maxBytes) +bool ImageUtil::saveImage(QWidget *window, const QImage &image, QString file) +{ + bool result = false; + + if (!file.isEmpty() || misc::getSaveFileName(window, RshareSettings::LASTDIR_IMAGES, QApplication::translate("ImageUtil", "Save Picture File"), QApplication::translate("ImageUtil", "Pictures (*.png *.xpm *.jpg)"), file)) { + if (image.save(file, nullptr, 100)) { + result = true; + } else { + if (image.save(file + ".png", nullptr, 100)) { + result = true; + } else { + QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Cannot save the image, invalid filename") + + "\n" + file); + } + } + } + + return result; +} + +void ImageUtil::copyImage(QWidget *window, QTextCursor cursor) +{ + cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1); + cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2); + QString imagestr = cursor.selection().toHtml(); + bool success = false; + int start = imagestr.indexOf("base64,") + 7; + int stop = imagestr.indexOf("\"", start); + int length = stop - start; + if((start >= 0) && (length > 0)) + { + QByteArray ba = QByteArray::fromBase64(imagestr.mid(start, length).toLatin1()); + QImage image = QImage::fromData(ba); + if(!image.isNull()) + { + success = true; + QClipboard *clipboard = QApplication::clipboard(); + QMimeData *data = new QMimeData; + data->setImageData(image); + clipboard->setMimeData(data, QClipboard::Clipboard); + } + } + if(!success) + { + QMessageBox::warning(window, QApplication::translate("ImageUtil", "Copy image"), QApplication::translate("ImageUtil", "Not an image")); + } +} + +bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, const char *format, int maxPixels, int maxBytes) { //nothing to do if it fits into the limits optimized = original; if ((maxPixels <= 0) || (optimized.width()*optimized.height() <= maxPixels)) { - int s = checkSize(bytearray, optimized); + int s = checkSize(bytearray, optimized,format); if((maxBytes <= 0) || (s <= maxBytes)) { return true; } @@ -92,7 +196,7 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, //if maxBytes not defined, do not reduce color space, just downscale if(maxBytes <= 0) { - checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation)); + checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation),format); return true; } @@ -100,9 +204,9 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, quantization(original, ct); //Use binary search to find a suitable image size + linear regression to guess the file size - double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); + double maxsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(maxwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither),format); if(maxsize <= maxBytes) return true; //success - double minsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); + double minsize = (double)checkSize(bytearray, optimized = original.scaledToWidth(minwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither),format); if(minsize > maxBytes) return false; //impossible // std::cout << "maxS: " << maxsize << " minS: " << minsize << std::endl; @@ -115,7 +219,7 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, double b = maxsize - m * ((double)maxwidth * (double)maxwidth / whratio); double a = ((double)(maxBytes - region/2) - b) / m; //maxBytes - region/2 target the center of the accepted region int nextwidth = (int)sqrt(a * whratio); - int nextsize = checkSize(bytearray, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither)); + int nextsize = checkSize(bytearray, optimized = original.scaledToWidth(nextwidth, Qt::SmoothTransformation).convertToFormat(QImage::Format_Indexed8, ct, Qt::ThresholdDither),format); if(nextsize <= maxBytes) { minsize = nextsize; minwidth = nextwidth; @@ -137,6 +241,25 @@ bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, //std::cout << html.toStdString() << std::endl; } +bool ImageUtil::hasAlphaContent(const QImage& image) +{ + if(!image.hasAlphaChannel()) + { + std::cerr << "Image of size " << image.width() << " x " << image.height() << ": No transparency content detected." << std::endl; + return false; + } + + for(int i=0;i -#include -#include #include +class QWidget; +class QTextEdit; +class QByteArray; + class ImageUtil { public: ImageUtil(); + static bool checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL); + static bool checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL); static void extractImage(QWidget *window, QTextCursor cursor, QString file = ""); - static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); - static bool optimizeSizeBytes(QByteArray &bytearray, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static void copyImage(QWidget *window, QTextCursor cursor); + static bool saveImage(QWidget *window, const QImage &image, QString file = ""); + static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1); + static bool optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, const char *format, int maxPixels, int maxBytes); + static bool hasAlphaContent(const QImage& image); private: - static int checkSize(QByteArray& embeddedImage, const QImage& img); + static int checkSize(QByteArray& embeddedImage, const QImage& img, const char *format); static void quantization(const QImage& img, QVector& palette); static void quantization(QList::iterator begin, QList::iterator end, int depth, QVector& palette); static void avgbucket(QList::iterator begin, QList::iterator end, QVector& palette); diff --git a/retroshare-gui/src/util/misc.cpp b/retroshare-gui/src/util/misc.cpp index e63ad2fd6..84c408de3 100644 --- a/retroshare-gui/src/util/misc.cpp +++ b/retroshare-gui/src/util/misc.cpp @@ -19,17 +19,20 @@ * * *******************************************************************************/ -#include +#include "misc.h" + +#include "gui/common/FilesDefs.h" +#include "util/rsdebug.h" + +#include +#include +#include #include #include -#include -#include -#include #include +#include -#include "misc.h" -#include "util/rsdebug.h" -#include "gui/common/FilesDefs.h" +#include // return best userfriendly storage unit (B, KiB, MiB, GiB, TiB) // use Binary prefix standards from IEC 60027-2 @@ -67,46 +70,46 @@ QString misc::fingerPrintStyleSplit(const QString& in) bool misc::isPreviewable(QString extension) { extension = extension.toUpper(); - if(extension == "AVI") return true; - if(extension == "MP3") return true; - if(extension == "OGG") return true; - if(extension == "OGM") return true; - if(extension == "WMV") return true; - if(extension == "WMA") return true; - if(extension == "MPEG") return true; - if(extension == "MPG") return true; - if(extension == "ASF") return true; - if(extension == "QT") return true; - if(extension == "RM") return true; - if(extension == "RMVB") return true; - if(extension == "RMV") return true; - if(extension == "SWF") return true; - if(extension == "FLV") return true; - if(extension == "WAV") return true; - if(extension == "MOV") return true; - if(extension == "VOB") return true; - if(extension == "MID") return true; - if(extension == "AC3") return true; - if(extension == "MP4") return true; - if(extension == "MP2") return true; - if(extension == "AVI") return true; - if(extension == "FLAC") return true; - if(extension == "AU") return true; - if(extension == "MPE") return true; - if(extension == "MOV") return true; - if(extension == "MKV") return true; - if(extension == "AIF") return true; - if(extension == "AIFF") return true; - if(extension == "AIFC") return true; - if(extension == "RA") return true; - if(extension == "RAM") return true; - if(extension == "M4P") return true; - if(extension == "M4A") return true; if(extension == "3GP") return true; if(extension == "AAC") return true; - if(extension == "SWA") return true; + if(extension == "AC3") return true; + if(extension == "AIF") return true; + if(extension == "AIFC") return true; + if(extension == "AIFF") return true; + if(extension == "ASF") return true; + if(extension == "AU") return true; + if(extension == "AVI") return true; + if(extension == "FLAC") return true; + if(extension == "FLV") return true; + if(extension == "M4P") return true; + if(extension == "M4A") return true; + if(extension == "MOV") return true; + if(extension == "MID") return true; + if(extension == "MKV") return true; + if(extension == "MP2") return true; + if(extension == "MP3") return true; + if(extension == "MP4") return true; if(extension == "MPC") return true; + if(extension == "MPE") return true; + if(extension == "MPEG") return true; + if(extension == "MPG") return true; if(extension == "MPP") return true; + if(extension == "OGG") return true; + if(extension == "OGM") return true; + if(extension == "QT") return true; + if(extension == "RA") return true; + if(extension == "RAM") return true; + if(extension == "RM") return true; + if(extension == "RMV") return true; + if(extension == "RMVB") return true; + if(extension == "SWA") return true; + if(extension == "SWF") return true; + if(extension == "VOB") return true; + if(extension == "WAV") return true; + if(extension == "WMA") return true; + if(extension == "WMV") return true; + if(extension == "WEBM") return true; + if(extension == "WEBA") return true; return false; } @@ -227,8 +230,6 @@ QString misc::userFriendlyUnit(double count, unsigned int decimal, double factor return "0"; } - QString output; - int i; for (i = 0; i < 5; ++i) { if (count < factor) { @@ -290,7 +291,7 @@ bool misc::getOpenAvatarPicture(QWidget *parent, QByteArray &image_data) // save image in QByteArray QBuffer buffer(&image_data); buffer.open(QIODevice::WriteOnly); - picture.save(&buffer, "PNG"); // writes image into ba in PNG format + picture.save(&buffer, "PNG"); // writes image into ba in PNG format return true; } @@ -434,3 +435,12 @@ void misc::clearLayout(QLayout * layout) { //delete item;//Auto deleted by Qt. } } + +QSizeF misc::getFontSizeFactor(const QString &group, const qreal defaultFactor /*= 1.0*/) +{ + static qreal appFontWidth = QFontMetrics(QApplication::font()).maxWidth(); + static qreal appFontHeight = QFontMetrics(QApplication::font()).height(); + qreal factor = Settings->valueFromGroup("FontHeighFactor",group,defaultFactor).toReal(); + return QSizeF(appFontWidth*factor,appFontHeight*factor); +} + diff --git a/retroshare-gui/src/util/misc.h b/retroshare-gui/src/util/misc.h index f09280ecf..2863a867c 100644 --- a/retroshare-gui/src/util/misc.h +++ b/retroshare-gui/src/util/misc.h @@ -22,14 +22,15 @@ #ifndef MISC_H #define MISC_H -#include +#include "gui/settings/rsharesettings.h" + +#include +#include #include #include #include -#include -#include -#include "gui/settings/rsharesettings.h" +#include /* Miscellaneaous functions that can be useful */ class misc : public QObject @@ -165,15 +166,15 @@ class misc : public QObject static QPixmap getOpenThumbnailedPicture(QWidget *parent, const QString &caption, int width, int height); static bool getOpenFileName(QWidget *parent, RshareSettings::enumLastDir type , const QString &caption, const QString &filter - , QString &file, QFileDialog::Options options = 0); + , QString &file, QFileDialog::Options options = QFileDialog::Options()); static bool getOpenFileNames(QWidget *parent, RshareSettings::enumLastDir type , const QString &caption, const QString &filter - , QStringList &files, QFileDialog::Options options = 0); + , QStringList &files, QFileDialog::Options options = QFileDialog::Options()); static bool getSaveFileName(QWidget *parent, RshareSettings::enumLastDir type , const QString &caption , const QString &filter - , QString &file, QString *selectedFilter = NULL - , QFileDialog::Options options = 0); + , QString &file, QString *selectedFilter = NULL + , QFileDialog::Options options = QFileDialog::Options()); static QFont getFont(bool *ok , const QFont &initial @@ -187,6 +188,9 @@ class misc : public QObject //Clear QLayout static void clearLayout(QLayout *layout); + static QSizeF getFontSizeFactor(const QString &group, const qreal defaultFactor = 1.0); + static QSizeF getFontSizeFactor() {return getFontSizeFactor("Main");} + }; // Trick to get a portable sleep() function @@ -201,7 +205,7 @@ class SleeperThread : public QThread{ template class SignalsBlocker { public: - SignalsBlocker(T *blocked) : blocked(blocked), previous(blocked->blockSignals(true)) {} + explicit SignalsBlocker(T *blocked) : blocked(blocked), previous(blocked->blockSignals(true)) {} ~SignalsBlocker() { blocked->blockSignals(previous); } T *operator->() { return blocked; } diff --git a/retroshare-gui/src/util/retroshareWin32.cpp b/retroshare-gui/src/util/retroshareWin32.cpp index 2e025a354..5693ef514 100644 --- a/retroshare-gui/src/util/retroshareWin32.cpp +++ b/retroshare-gui/src/util/retroshareWin32.cpp @@ -21,7 +21,6 @@ #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN #include #endif diff --git a/retroshare-service/CMakeLists.txt b/retroshare-service/CMakeLists.txt new file mode 100644 index 000000000..672644369 --- /dev/null +++ b/retroshare-service/CMakeLists.txt @@ -0,0 +1,170 @@ +# RetroShare decentralized communication platform +# +# Copyright (C) 2021-2022 Gioacchino Mazzurco +# Copyright (C) 2021-2022 Asociación Civil Altermundi +# +# SPDX-License-Identifier: CC0-1.0 + +cmake_minimum_required (VERSION 3.18.0) +project(retroshare-service) + +include(CMakeDependentOption) + +set( + RS_BIN_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/bin" + CACHE PATH + "Path where to install retroshare-service compiled binary" ) + +option( + RS_DEVELOPMENT_BUILD + "Disable optimization to speed up build, enable verbose build log. \ + just for development purposes, not suitable for library usage" + OFF ) + +option( + RS_JSON_API + "Use restbed to expose libretroshare as JSON API via HTTP" + ON ) + +option( + RS_SERVICE_DESKTOP + "Install icons and shortcuts for desktop environements" + OFF ) + +option( + RS_SERVICE_TERMINAL_LOGIN + "Enable RetroShare login via terminal" + ON ) + +cmake_dependent_option( + RS_SERVICE_TERMINAL_WEBUI_PASSWORD + "Enable settin Web UI password via terminal in retroshare-service" + OFF + "RS_WEBUI" + ON ) + +cmake_dependent_option( + RS_WEBUI + "Install RetroShare Web UI" + OFF + "RS_JSON_API" + ON ) + +################################################################################ + +set(FETCHCONTENT_QUIET OFF) +include(FetchContent) + +find_package(Git REQUIRED) + +################################################################################ + +if(RS_DEVELOPMENT_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +endif(RS_DEVELOPMENT_BUILD) + +################################################################################ + +list( + APPEND RS_SERVICE_SOURCES + src/retroshare-service.cc ) + +add_executable(${PROJECT_NAME} ${RS_SERVICE_SOURCES}) + +set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) + +install(TARGETS ${PROJECT_NAME} DESTINATION ${RS_BIN_INSTALL_DIR}) + +################################################################################ + +if(RS_DEVELOPMENT_BUILD) + target_compile_options(${PROJECT_NAME} PRIVATE "-O0") +endif(RS_DEVELOPMENT_BUILD) + +################################################################################ + +set(LIBRETROSHARE_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../libretroshare/") +if(EXISTS "${LIBRETROSHARE_DEVEL_DIR}/CMakeLists.txt" ) + message( + STATUS + "libretroshare source found at ${LIBRETROSHARE_DEVEL_DIR} using it" ) + add_subdirectory( + "${LIBRETROSHARE_DEVEL_DIR}" "${CMAKE_BINARY_DIR}/libretroshare" ) +else() + FetchContent_Declare( + libretroshare + GIT_REPOSITORY "https://gitlab.com/RetroShare/libretroshare.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(libretroshare) +endif() + +target_link_libraries(${PROJECT_NAME} PRIVATE retroshare) + +################################################################################ + +if(RS_SERVICE_DESKTOP) + if(UNIX AND NOT APPLE) + install( + FILES data/retroshare-service.svg + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/ ) + + install( + FILES data/retroshare-service_48x48.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps/retroshare-service.png ) + + install( + FILES data/retroshare-service_128x128.png + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps/retroshare-service.png ) + + install( + FILES data/retroshare-service.desktop + DESTINATION ${CMAKE_INSTALL_PREFIX}/data/retroshare-service.desktop ) + endif(UNIX AND NOT APPLE) +endif(RS_SERVICE_DESKTOP) + +################################################################################ + +if(RS_JSON_API) + target_compile_definitions(${PROJECT_NAME} PUBLIC RS_JSONAPI) +endif(RS_JSON_API) + +if(RS_SERVICE_TERMINAL_LOGIN) + target_compile_definitions(${PROJECT_NAME} PUBLIC RS_SERVICE_TERMINAL_LOGIN) +endif(RS_SERVICE_TERMINAL_LOGIN) + +if(RS_WEBUI) + set(RS_WEBUI_DEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../webui/") + if(EXISTS "${RS_WEBUI_DEVEL_DIR}/CMakeLists.txt" ) + message( + STATUS + "RetroShare WebUI source found at ${RS_WEBUI_DEVEL_DIR} using it" ) + add_subdirectory( + "${RS_WEBUI_DEVEL_DIR}" "${CMAKE_BINARY_DIR}/webui" ) + else() + FetchContent_Declare( + webui + GIT_REPOSITORY "https://gitlab.com/RetroShare/RetroShareWebUI.git" + GIT_TAG "origin/master" + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE + TIMEOUT 10 + ) + FetchContent_MakeAvailable(webui) + endif() + + add_dependencies(${PROJECT_NAME} retroshare-webui) + target_compile_definitions(${PROJECT_NAME} PUBLIC RS_WEBUI) +endif(RS_WEBUI) + +if(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) + target_compile_definitions( + ${PROJECT_NAME} PUBLIC RS_SERVICE_TERMINAL_WEBUI_PASSWORD ) +endif(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) + +################################################################################ diff --git a/retroshare-service/src/android/AndroidManifest.xml b/retroshare-service/src/android/AndroidManifest.xml index d41a72995..ecf8ba78a 100644 --- a/retroshare-service/src/android/AndroidManifest.xml +++ b/retroshare-service/src/android/AndroidManifest.xml @@ -2,9 +2,9 @@ - + @@ -14,59 +14,81 @@ - - - - - - - - - - - - - + + + + + - + + + + - - - - +]]> + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + @@ -76,17 +98,11 @@ ++ features based on the dependencies of the application. ++ Remove the comment if you do not require these default features. --> +]]> - + - - - - - - - - - + --> +]]> diff --git a/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java b/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java index 283fd10cc..3f2e3f375 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java +++ b/retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java @@ -19,6 +19,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +/* package org.retroshare.service; import android.content.BroadcastReceiver; @@ -36,3 +37,4 @@ public class AppUpdatedReceiver extends BroadcastReceiver RetroShareServiceAndroid.start(context); } } +*/ \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java b/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java new file mode 120000 index 000000000..60da18398 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/AssetHelper.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/AssetHelper.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java b/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java index 89c09c241..75bfbc063 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java +++ b/retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java @@ -19,6 +19,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +/* package org.retroshare.service; import android.content.BroadcastReceiver; @@ -35,3 +36,4 @@ public class BootCompletedReceiver extends BroadcastReceiver RetroShareServiceAndroid.start(context); } } +*/ \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java b/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java new file mode 120000 index 000000000..1f90a62c6 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/ErrorConditionWrap.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/ErrorConditionWrap.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java deleted file mode 100644 index 3cea999bf..000000000 --- a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * RetroShare - * Copyright (C) 2016-2018 Gioacchino Mazzurco - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * SPDX-FileCopyrightText: Retroshare Team - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -package org.retroshare.service; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.Intent; - -import org.qtproject.qt5.android.bindings.QtService; - -public class RetroShareServiceAndroid extends QtService -{ - public static void start(Context ctx) - { - ctx.startService(new Intent(ctx, RetroShareServiceAndroid.class)); - } - - public static void stop(Context ctx) - { - ctx.stopService(new Intent(ctx, RetroShareServiceAndroid.class)); - } - - public static boolean isRunning(Context ctx) - { - ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE); - for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) - if (RetroShareServiceAndroid.class.getName().equals(service.service.getClassName())) - return true; - return false; - } -} diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java new file mode 120000 index 000000000..480e21ac4 --- /dev/null +++ b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java @@ -0,0 +1 @@ +../../../../../../../libretroshare/src/rs_android/org/retroshare/service/RetroShareServiceAndroid.java \ No newline at end of file diff --git a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java index d1e1f78b7..dafe10301 100644 --- a/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java +++ b/retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java @@ -1,6 +1,6 @@ /* * RetroShare - * Copyright (C) 2016-2018 Gioacchino Mazzurco + * Copyright (C) 2016-2021 Gioacchino Mazzurco * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -50,7 +50,11 @@ public class RetroShareServiceControlActivity extends Activity else { button.setText("Starting..."); - RetroShareServiceAndroid.start(RetroShareServiceControlActivity.this); + RetroShareServiceAndroid.start( + RetroShareServiceControlActivity.this, + RetroShareServiceAndroid.DEFAULT_JSON_API_PORT, + RetroShareServiceAndroid.DEFAULT_JSON_API_BINDING_ADDRESS + ); serviceStarting = true; serviceStopping = false; } diff --git a/retroshare-service/src/retroshare-service-android.cc b/retroshare-service/src/retroshare-service-android.cc new file mode 100644 index 000000000..30204c8fd --- /dev/null +++ b/retroshare-service/src/retroshare-service-android.cc @@ -0,0 +1,29 @@ +/* + * RetroShare Service Android + * Copyright (C) 2021 Gioacchino Mazzurco + * Copyright (C) 2021 Asociación Civil Altermundi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * SPDX-FileCopyrightText: Retroshare Team + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include "rs_android/rsjni.hpp" + +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* _reserved) +{ + RS_DBG(vm); + return JNI_OnLoad_retroshare(vm, _reserved); +} diff --git a/retroshare-service/src/retroshare-service.cc b/retroshare-service/src/retroshare-service.cc index e80d468e1..040a2012d 100644 --- a/retroshare-service/src/retroshare-service.cc +++ b/retroshare-service/src/retroshare-service.cc @@ -1,6 +1,7 @@ /* * RetroShare Service - * Copyright (C) 2016-2019 Gioacchino Mazzurco + * Copyright (C) 2016-2022 Gioacchino Mazzurco + * Copyright (C) 2021-2022 Asociación Civil Altermundi * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -19,39 +20,34 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include "util/stacktrace.h" -#include "util/argstream.h" -#include "util/rskbdinput.h" -#include "retroshare/rsinit.h" - -#ifdef RS_JSONAPI -#include "retroshare/rsjsonapi.h" - -#ifdef RS_WEBUI -#include "retroshare/rswebui.h" -#endif -#endif - -static CrashStackTrace gCrashStackTrace; #include #include #include #include -#ifdef __ANDROID__ -# include -# include -# include -# include - -# include "util/androiddebug.h" -#endif // def __ANDROID__ - +#include "retroshare/rsinit.h" +#include "retroshare/rstor.h" +#include "retroshare/rspeers.h" #include "retroshare/rsinit.h" #include "retroshare/rsiface.h" + +#include "util/stacktrace.h" +#include "util/argstream.h" +#include "util/rskbdinput.h" +#include "util/rsdir.h" #include "util/rsdebug.h" +#ifdef RS_JSONAPI +# include "retroshare/rsjsonapi.h" + +# ifdef RS_WEBUI +# include "retroshare/rswebui.h" +# endif // def RS_WEBUI +#endif // def RS_JSONAPI + +static CrashStackTrace gCrashStackTrace; + #ifdef RS_SERVICE_TERMINAL_LOGIN class RsServiceNotify: public NotifyClient { @@ -74,9 +70,6 @@ public: }; #endif // def RS_SERVICE_TERMINAL_LOGIN -#ifdef __ANDROID__ -void signalHandler(int /*signal*/) { QCoreApplication::exit(0); } -#else static std::atomic keepRunning(true); static int receivedSignal = 0; @@ -87,16 +80,10 @@ void signalHandler(int signal) receivedSignal = signal; keepRunning = false; } -#endif // def __ANDROID__ int main(int argc, char* argv[]) { -#ifdef __ANDROID__ - AndroidStdIOCatcher dbg; (void) dbg; - QAndroidService app(argc, argv); -#endif // def __ANDROID__ - signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); #ifdef SIGBREAK @@ -128,7 +115,7 @@ int main(int argc, char* argv[]) RsConfigOptions conf; #ifdef RS_JSONAPI - conf.jsonApiPort = RsJsonApi::DEFAULT_PORT; // enable JSonAPI by default + conf.jsonApiPort = RsJsonApi::DEFAULT_PORT; // enable JSON API by default #ifdef RS_WEBUI std::string webui_base_directory = RsWebUi::DEFAULT_BASE_DIRECTORY; #endif @@ -139,19 +126,13 @@ int main(int argc, char* argv[]) "output to stderr instead of log file." ) >> option( 'u',"udp", conf.udpListenerOnly, "Only listen to UDP." ) - >> parameter( 'c',"base-dir", conf.optBaseDir, "directory", - "Set base directory.", false ) - >> parameter( 'l', "log-file", conf.logfname, "logfile", - "Set Log filename.", false ) - >> parameter( 'd', "debug-level", conf.debugLevel, "level", - "Set debug level.", false ) - >> parameter( 'i', "ip-address", conf.forcedInetAddress, "IP", - "Force IP address to use (if cannot be detected).", false ) - >> parameter( 'o', "opmode", conf.opModeStr, "opmode", - "Set Operating mode (Full, NoTurtle, Gaming, Minimal).", - false ) - >> parameter( 'p', "port", conf.forcedPort, "port", - "Set listenning port to use.", false ); + >> parameter( 'c',"base-dir", conf.optBaseDir, "directory", "Set base directory.", false ) + >> parameter( 'l', "log-file", conf.logfname, "logfile", "Set Log filename.", false ) + >> parameter( 'd', "debug-level", conf.debugLevel, "level", "Set debug level.", false ) + >> parameter( 'i', "ip-address", conf.forcedInetAddress, "IP", "Force IP address to use (if cannot be detected).", false ) + >> parameter( 'o', "opmode", conf.opModeStr, "opmode", "Set Operating mode (Full, NoTurtle, Gaming, Minimal).", false ) + >> parameter( 'p', "port", conf.forcedPort, "port", "Set listenning port to use.", false ) + >> parameter( 't', "tor", conf.userSuppliedTorExecutable, "tor", "Set Tor executable full path.", false ); #ifdef RS_SERVICE_TERMINAL_LOGIN as >> parameter( 'U', "user-id", prefUserString, "ID", @@ -189,8 +170,11 @@ int main(int argc, char* argv[]) as >> help( 'h', "help", "Display this Help" ); as.defaultErrorHandling(true, true); + if(!conf.userSuppliedTorExecutable.empty()) + RsTor::setTorExecutablePath(conf.userSuppliedTorExecutable); + #if (defined(RS_JSONAPI) && defined(RS_WEBUI)) && defined(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) - std::string webui_pass1 = "Y"; + std::string webui_pass1; if(askWebUiPassword) { std::string webui_pass2 = "N"; @@ -224,8 +208,8 @@ int main(int argc, char* argv[]) int initResult = RsInit::InitRetroShare(conf); if(initResult != RS_INIT_OK) { - RsErr() << "Retroshare core initalization failed with: " << initResult - << std::endl; + RsFatal() << "Retroshare core initalization failed with: " << initResult + << std::endl; return -initResult; } @@ -311,34 +295,51 @@ int main(int argc, char* argv[]) << std::endl; return -result; } + + if(RsAccounts::isTorAuto()) + { + + std::cerr << "(II) Hidden service is ready:" << std::endl; + + std::string service_id ; + std::string onion_address ; + uint16_t service_port ; + uint16_t service_target_port ; + uint16_t proxy_server_port ; + std::string service_target_address ; + std::string proxy_server_address ; + + RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); + RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; + + std::cerr << " onion address : " << onion_address << std::endl; + std::cerr << " service_id : " << service_id << std::endl; + std::cerr << " service port : " << service_port << std::endl; + std::cerr << " target port : " << service_target_port << std::endl; + std::cerr << " target address : " << service_target_address << std::endl; + + std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; + + rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); + rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); + rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; + } } #endif // def RS_SERVICE_TERMINAL_LOGIN #if (defined(RS_JSONAPI) && defined(RS_WEBUI)) && defined(RS_SERVICE_TERMINAL_WEBUI_PASSWORD) if(rsJsonApi && !webui_pass1.empty()) - { + { rsWebUi->setHtmlFilesDirectory(webui_base_directory); rsWebUi->setUserPassword(webui_pass1); rsWebUi->restart(); - } + } #endif -#ifdef __ANDROID__ - rsControl->setShutdownCallback(QCoreApplication::exit); - - QObject::connect( - &app, &QCoreApplication::aboutToQuit, - [](){ - if(RsControl::instance()->isReady()) - RsControl::instance()->rsGlobalShutDown(); } ); - - return app.exec(); -#else // def __ANDROID__ rsControl->setShutdownCallback([&](int){keepRunning = false;}); while(keepRunning) std::this_thread::sleep_for(std::chrono::milliseconds(500)); return 0; -#endif } diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro index cbd1b9d13..6458e03ed 100644 --- a/retroshare-service/src/retroshare-service.pro +++ b/retroshare-service/src/retroshare-service.pro @@ -1,6 +1,6 @@ # RetroShare service qmake build script # -# Copyright (C) 2018-2019, Gioacchino Mazzurco +# Copyright (C) 2018-2021, Gioacchino Mazzurco # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the @@ -22,9 +22,6 @@ TARGET = retroshare-service -QT += core -QT -= gui - !include("../../libretroshare/src/use_libretroshare.pri"):error("Including") SOURCES += retroshare-service.cc @@ -32,8 +29,6 @@ SOURCES += retroshare-service.cc ################################# Linux ########################################## android-* { - QT += androidextras - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android DISTFILES += android/AndroidManifest.xml \ @@ -45,6 +40,9 @@ android-* { android/build.gradle \ android/gradle/wrapper/gradle-wrapper.properties \ android/gradlew.bat + + SOURCES -= retroshare-service.cc + SOURCES += retroshare-service-android.cc } @@ -89,16 +87,7 @@ macx { ################################# Windows ########################################## win32-g++|win32-clang-g++ { - CONFIG(debug, debug|release) { - # show console output - CONFIG += console - } else { - CONFIG -= console - } - - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra + CONFIG += console CONFIG(debug, debug|release) { } else { diff --git a/retroshare-webui b/retroshare-webui new file mode 160000 index 000000000..b0ddb0918 --- /dev/null +++ b/retroshare-webui @@ -0,0 +1 @@ +Subproject commit b0ddb09184e8fff86bd3325e00c6d4b329ae1790 diff --git a/retroshare.pri b/retroshare.pri index 2c2201ef3..9ed316b9a 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -1,7 +1,8 @@ # RetroShare common qmake build script # -# Copyright (C) 2004-2019, Retroshare Team -# Copyright (C) 2016-2019, Gioacchino Mazzurco +# Copyright (C) 2004-2021 Retroshare Team +# Copyright (C) 2016-2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Lesser General Public License as published by the @@ -50,6 +51,11 @@ retroshare_plugins:CONFIG -= no_retroshare_plugins CONFIG *= retroshare_service no_retroshare_service:CONFIG -= retroshare_service +# To disable RetroShare FriendServer append the following assignation to +# qmake command line "CONFIG+=no_rs_friendserver" +CONFIG *= retroshare_friendserver +no_rs_friendserver:CONFIG -= retroshare_friendserver + # To disable SQLCipher support append the following assignation to qmake # command line "CONFIG+=no_sqlcipher" CONFIG *= sqlcipher @@ -134,16 +140,17 @@ rs_macos10.12:CONFIG -= rs_macos10.11 rs_macos10.13:CONFIG -= rs_macos10.11 rs_macos10.14:CONFIG -= rs_macos10.11 rs_macos10.15:CONFIG -= rs_macos10.11 +rs_macos11.1:CONFIG -= rs_macos10.11 # To enable JSON API append the following assignation to qmake command line # "CONFIG+=rs_jsonapi" CONFIG *= no_rs_jsonapi rs_jsonapi:CONFIG -= no_rs_jsonapi -# Disable i2p BOB support for automatically setting up an i2p tunnel for RS -# "CONFIG+=no_rs_bob" -CONFIG *= rs_bob -no_rs_bob:CONFIG -= rs_bob +# To enable forums indexing append the following assignation to qmake command +# line "CONFIG+=rs_deep_forums_index" +CONFIG *= no_rs_deep_forums_index +rs_deep_forums_index:CONFIG -= no_rs_deep_forums_index # To enable channel indexing append the following assignation to qmake command # line "CONFIG+=rs_deep_channels_index" @@ -204,10 +211,16 @@ no_rs_service_terminal_login:CONFIG -= rs_service_terminal_login CONFIG+=rs_dh_init_check no_rs_dh_init_check:CONFIG -= rs_dh_init_check -# To export all symbols for the plugins on Windows build we need to build libretroshare as -# shared library. Fix linking error (ld.exe: Error: export ordinal too large) due to too -# many exported symbols. -retroshare_plugins:win32:CONFIG *= libretroshare_shared +# To disable I2P sam3 support append the following assignation to qmake command +# line "CONFIG+=no_rs_sam3" +CONFIG *= rs_sam3 +no_rs_sam3:CONFIG -= rs_sam3 + +# To disable I2P sam3 library submodule build append the following assignation +# to qmake command line "CONFIG+=no_rs_sam3_libsam3" +CONFIG *= rs_sam3_libsam3 +no_rs_sam3_libsam3:CONFIG -= rs_sam3_libsam3 + # Specify host precompiled jsonapi-generator path, appending the following # assignation to qmake command line @@ -559,10 +572,7 @@ rs_webui { DEFINES *= RS_WEBUI } -rs_bob { - DEFINES *= RS_USE_I2P_BOB -} - +rs_deep_forums_index:DEFINES *= RS_DEEP_FORUMS_INDEX rs_deep_channels_index:DEFINES *= RS_DEEP_CHANNEL_INDEX rs_deep_files_index:DEFINES *= RS_DEEP_FILES_INDEX @@ -576,6 +586,13 @@ rs_broadcast_discovery:DEFINES *= RS_BROADCAST_DISCOVERY no_rs_dh_init_check:DEFINES *= RS_DISABLE_DIFFIE_HELLMAN_INIT_CHECK +rs_sam3: { + DEFINES *= RS_USE_I2P_SAM3 + # this allows a downgrade from a SAMv3 build to a BOB build, can be removed in the future + DEFINES *= RS_I2P_SAM3_BOB_COMPAT +} +rs_sam3_libsam3: DEFINES *= RS_USE_I2P_SAM3_LIBSAM3 + debug { rs_mutex_debug:DEFINES *= RS_MUTEX_DEBUG @@ -596,6 +613,18 @@ profiling { QMAKE_LFLAGS *= -pg } +# Enable all warnings +QMAKE_CFLAGS *= -Wall -Wextra +QMAKE_CXXFLAGS *= -Wall -Wextra + +# Disable unwanted warnings +QMAKE_CFLAGS *= -Wno-misleading-indentation -Wno-dangling-else +QMAKE_CXXFLAGS *= -Wno-misleading-indentation -Wno-dangling-else + +# Treat warnings as error for better removing +#QMAKE_CFLAGS += -Werror +#QMAKE_CXXFLAGS += -Werror + ################################################################################ ## Last goes platform specific statements common to all RetroShare subprojects # ################################################################################ @@ -609,6 +638,8 @@ linux-* { isEmpty(RS_PLUGIN_DIR) : RS_PLUGIN_DIR = "$${PREFIX}/lib/retroshare/extensions6" QMAKE_LIBDIR *= "$$RS_LIB_DIR" + QMAKE_LIBDIR += "$${PREFIX}/lib64" + QMAKE_LIBDIR += "$${PREFIX}/lib/x86_64-linux-gnu" rs_autologin { # try libsecret first since it is not limited to gnome keyring and libgnome-keyring is deprecated @@ -646,6 +677,11 @@ android-* { RS_THREAD_LIB = } +# To export all symbols for the plugins on Windows build we need to build +# libretroshare as shared library. Fix linking error (ld.exe: Error: export +# ordinal too large) due to too many exported symbols. +retroshare_plugins:win32:CONFIG *= libretroshare_shared + win32-g++|win32-clang-g++ { !isEmpty(EXTERNAL_LIB_DIR) { message(Use pre-compiled libraries in $${EXTERNAL_LIB_DIR}.) @@ -755,6 +791,13 @@ macx-* { QMAKE_CXXFLAGS += -Wno-nullability-completeness QMAKE_CFLAGS += -Wno-nullability-completeness } + rs_macos11.1 { + message(***retroshare.pri: Set Target and SDK to MacOS 11.1 ) + QMAKE_MACOSX_DEPLOYMENT_TARGET=11.1 + QMAKE_MAC_SDK = macosx11.1 + QMAKE_CXXFLAGS += -Wno-nullability-completeness + QMAKE_CFLAGS += -Wno-nullability-completeness + } @@ -763,6 +806,10 @@ macx-* { INCLUDEPATH += "/usr/local/include" RS_UPNP_LIB = miniupnpc QT += macextras + INCLUDEPATH += "/usr/local/opt/openssl/include" + QMAKE_LIBDIR += "/usr/local/opt/openssl/lib" + QMAKE_LIBDIR += "/usr/local/opt/sqlcipher/lib" + QMAKE_LIBDIR += "/usr/local/opt/miniupnpc/lib" } # If not yet defined attempt UPnP library autodetection should works at least @@ -798,5 +845,4 @@ contains(RS_UPNP_LIB, upnp):DEFINES*=RS_USE_LIBUPNP isEmpty(BIN_DIR) : BIN_DIR = $${RS_BIN_DIR} isEmpty(INC_DIR) : INC_DIR = $${RS_INCLUDE_DIR} isEmpty(LIBDIR) : LIBDIR = $${QMAKE_LIBDIR} -isEmpty(DATA_DIR) : DATA_DIR = $${RS_DATA_DIR} isEmpty(PLUGIN_DIR): PLUGIN_DIR= $${RS_PLUGIN_DIR} diff --git a/supportlibs/jni.hpp b/supportlibs/jni.hpp new file mode 160000 index 000000000..66f73a6aa --- /dev/null +++ b/supportlibs/jni.hpp @@ -0,0 +1 @@ +Subproject commit 66f73a6aa82367d6ba23e7e842f95dfb33c451d6 diff --git a/supportlibs/libsam3 b/supportlibs/libsam3 new file mode 160000 index 000000000..8623304b6 --- /dev/null +++ b/supportlibs/libsam3 @@ -0,0 +1 @@ +Subproject commit 8623304b62294dafbe477573f321a464fef721dd diff --git a/tests/librssimulator/librssimulator.pro b/tests/librssimulator/librssimulator.pro index 1f6ded77d..75a73fdd3 100644 --- a/tests/librssimulator/librssimulator.pro +++ b/tests/librssimulator/librssimulator.pro @@ -89,7 +89,7 @@ linux-* { INCLUDEPATH *= $${OPENPGPSDK_DIR} ../openpgpsdk DESTDIR = lib - QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 + QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 QMAKE_CC = $${QMAKE_CXX} SSL_DIR = /usr/include/openssl @@ -172,10 +172,6 @@ win32 { 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 diff --git a/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh new file mode 100755 index 000000000..03b99a94e --- /dev/null +++ b/tests/test_JSON_API_DirDetails_handle_correct_64bit_integer_type.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +# Copyright (C) 2021 Gioacchino Mazzurco +# Copyright (C) 2021 Asociación Civil Altermundi +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, version 3. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see +# +# SPDX-FileCopyrightText: Retroshare Team +# SPDX-License-Identifier: AGPL-3.0-only + + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" || true +} + +define_default_value API_BASE_URL "http://127.0.0.1:9092" +define_default_value API_TOKEN "0000:0000" + +function tLog() +{ + local mCategory="$1" ; shift + echo "$mCategory $(date) $@" >&2 +} + +mCmd="curl -u $API_TOKEN $API_BASE_URL/rsFiles/requestDirDetails" + +mReply="$($mCmd)" +mCurlRet="$?" + +if [ "$mCurlRet" != 0 ]; then + tLog E "$mCmd failed: $mCurlRet '$mReply'" + exit -3 +fi + +[ "$(echo "$mReply" | jq '.retval')" == "true" ] || +{ + tLog E "/rsFiles/requestDirDetails failed: '$mReply'" + exit -1 +} + +[ "$(echo "$mReply" | jq '.details.handle')" != "0" ] || +{ + tLog E ".details.handle has wrong type int: '$mReply'" + exit -1 +} + +[ "$(echo "$mReply" | jq '.details.handle.xstr64')" == "\"0\"" ] && + [ "$(echo "$mReply" | jq '.details.handle.xint64')" == "0" ] && +{ + tLog I '.details.handle has correct type' + exit 0 +} + +tLog E "Unkown error in test $0: '$mReply'" +exit -2 diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc index 925e90be2..442a25cc1 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.cc @@ -134,11 +134,11 @@ const RsPgpId& rs_nxs_test::RsDummyPgpUtils::getPGPOwnId() { return mOwnId; } -RsPgpId rs_nxs_test::RsDummyPgpUtils::getPGPId(const RsPeerId& /*sslid*/) { +RsPgpId rs_nxs_test::RsDummyPgpUtils::getPgpId(const RsPeerId& /*sslid*/) { return RsPgpId().random(); } -bool rs_nxs_test::RsDummyPgpUtils::getGPGAllList(std::list& /*ids*/) { +bool rs_nxs_test::RsDummyPgpUtils::getPgpAllList(std::list& /*ids*/) { return true; } diff --git a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h index aee8f989e..6e993a658 100644 --- a/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h +++ b/tests/unittests/libretroshare/gxs/nxs_test/nxsdummyservices.h @@ -164,8 +164,8 @@ namespace rs_nxs_test virtual ~RsDummyPgpUtils(){} const RsPgpId &getPGPOwnId() ; - RsPgpId getPGPId(const RsPeerId& sslid) ; - bool getGPGAllList(std::list &ids) ; + RsPgpId getPgpId(const RsPeerId& sslid) ; + bool getPgpAllList(std::list &ids) ; bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc index 2d274897a..49e440e5e 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.cc @@ -24,7 +24,7 @@ FakePgpAuxUtils::FakePgpAuxUtils(const RsPeerId& ownId) { - mOwnId = getPGPId(ownId); + mOwnId = getPgpId(ownId); addPeerIdToPgpList(ownId); } @@ -39,7 +39,7 @@ void FakePgpAuxUtils::addPeerListToPgpList(const std::list &ids) void FakePgpAuxUtils::addPeerIdToPgpList(const RsPeerId &id) { - RsPgpId pgpId = getPGPId(id); + RsPgpId pgpId = getPgpId(id); if (mPgpList.end() == std::find(mPgpList.begin(), mPgpList.end(), pgpId)) { mPgpList.push_back(pgpId); @@ -51,7 +51,7 @@ const RsPgpId & FakePgpAuxUtils::getPGPOwnId() return mOwnId; } -RsPgpId FakePgpAuxUtils::getPGPId(const RsPeerId& sslid) +RsPgpId FakePgpAuxUtils::getPgpId(const RsPeerId& sslid) { /* convert an sslId */ std::string idstring = sslid.toStdString(); @@ -95,7 +95,7 @@ bool FakePgpAuxUtils::VerifySignBin(const void* /*data*/, uint32_t /*len*/, unsi return true; } -bool FakePgpAuxUtils::getGPGAllList(std::list &ids) +bool FakePgpAuxUtils::getPgpAllList(std::list &ids) { ids = mPgpList; return true; diff --git a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h index 63b20b85d..f866164a6 100644 --- a/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h +++ b/tests/unittests/libretroshare/services/gxs/FakePgpAuxUtils.h @@ -28,7 +28,7 @@ public: FakePgpAuxUtils(const RsPeerId& ownId); virtual const RsPgpId &getPGPOwnId(); - virtual RsPgpId getPGPId(const RsPeerId& sslid); + virtual RsPgpId getPgpId(const RsPeerId& sslid); virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const; virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const; @@ -36,7 +36,7 @@ public: virtual void addPeerListToPgpList(const std::list &ids); virtual void addPeerIdToPgpList(const RsPeerId &id); - virtual bool getGPGAllList(std::list &ids); + virtual bool getPgpAllList(std::list &ids); private: RsPgpId mOwnId; std::list mPgpList;
    - + - + @@ -18,10 +19,10 @@ - - + + - +
     %time%
     %name%
    diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm index 84a6c69d7..0733677e8 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/outgoing.htm @@ -2,14 +2,15 @@ %css-style% +
    - + - + @@ -18,12 +19,11 @@ - - + + - +
     %time%
     %name%
    - diff --git a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm index ad8287db2..b8340a65b 100644 --- a/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm +++ b/retroshare-gui/src/gui/qss/chat/Bubble_Compact/private/system.htm @@ -2,14 +2,15 @@ %css-style% +
    - + - + @@ -18,12 +19,11 @@ - - + + - +
     %time%
     %name%
    - diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm deleted file mode 100644 index e9696af8a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._hincoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._houtgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._houtgoing.htm deleted file mode 100644 index a9944feee..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._houtgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._images.sh b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._images.sh deleted file mode 100644 index a104569d8..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._images.sh and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._img b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._img deleted file mode 100644 index 0be496cbe..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._img and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._incoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._incoming.htm deleted file mode 100644 index 7528a621a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._incoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml deleted file mode 100644 index 908cf35de..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._info.xml and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._main.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._main.css deleted file mode 100644 index f3c8bd7d9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._main.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._ooutgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._outgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._outgoing.htm deleted file mode 100644 index cc4288eaf..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._outgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm deleted file mode 100644 index 8f6e1cd65..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._system.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._variants b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._variants deleted file mode 100644 index 7a8b2196d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/._variants and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-grey b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-grey deleted file mode 100644 index 7f843c3c7..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-grey and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-orange b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-orange deleted file mode 100644 index c849b46c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-orange and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-red b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-red deleted file mode 100644 index 36474caa0..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/._bubble-red and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BL.png deleted file mode 100644 index 5ad3fa3cc..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BR.png deleted file mode 100644 index 8107270d2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CC.png deleted file mode 100644 index 04138fb9f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CL.png deleted file mode 100644 index d9685f280..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CR.png deleted file mode 100644 index 01dcb89f9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TC.png deleted file mode 100644 index 7afb6592a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TL.png deleted file mode 100644 index c693cd8c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TR.png deleted file mode 100644 index eef19c90d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-left.png deleted file mode 100644 index 31da1c955..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-right.png deleted file mode 100644 index fe647fd4c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick.png deleted file mode 100644 index e21c59595..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-grey/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BL.png deleted file mode 100644 index 3e2817d90..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CC.png deleted file mode 100644 index 9a76ea6e9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CL.png deleted file mode 100644 index 9d28ffa78..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CR.png deleted file mode 100644 index fe6b42c2f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TL.png deleted file mode 100644 index 3fcc48bf2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TR.png deleted file mode 100644 index 4700b0f5f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-left.png deleted file mode 100644 index 0fafe1637..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick.png deleted file mode 100644 index d465c5903..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-orange/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BC.png deleted file mode 100644 index c5f4aebe6..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BL.png deleted file mode 100644 index 530ceef99..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BR.png deleted file mode 100644 index fc93c0bb3..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CC.png deleted file mode 100644 index 0deb77aef..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CR.png deleted file mode 100644 index 090c20552..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TL.png deleted file mode 100644 index 0122dffb2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TR.png deleted file mode 100644 index fa8728f59..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-left.png deleted file mode 100644 index fc9cbc77d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f578..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick.png deleted file mode 100644 index 6d6ea2625..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/img/bubble-red/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._color.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._color.css deleted file mode 100644 index 95d0e16e2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._color.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css deleted file mode 100644 index 98da5fc9a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/history/variants/._standard.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm deleted file mode 100644 index e9696af8a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._hincoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._houtgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._houtgoing.htm deleted file mode 100644 index a9944feee..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._houtgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._images.sh b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._images.sh deleted file mode 100644 index a104569d8..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._images.sh and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._img b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._img deleted file mode 100644 index 0be496cbe..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._img and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._incoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._incoming.htm deleted file mode 100644 index 7528a621a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._incoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml deleted file mode 100644 index 908cf35de..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._info.xml and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._main.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._main.css deleted file mode 100644 index f3c8bd7d9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._main.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._ooutgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._outgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._outgoing.htm deleted file mode 100644 index cc4288eaf..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._outgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm deleted file mode 100644 index 8f6e1cd65..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._system.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._variants b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._variants deleted file mode 100644 index 7a8b2196d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/._variants and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-grey b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-grey deleted file mode 100644 index 7f843c3c7..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-grey and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-orange b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-orange deleted file mode 100644 index c849b46c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-orange and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-red b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-red deleted file mode 100644 index 36474caa0..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/._bubble-red and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-blue/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-blue/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-blue/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-green/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BL.png deleted file mode 100644 index 5ad3fa3cc..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BR.png deleted file mode 100644 index 8107270d2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CC.png deleted file mode 100644 index 04138fb9f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CL.png deleted file mode 100644 index d9685f280..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CR.png deleted file mode 100644 index 01dcb89f9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TC.png deleted file mode 100644 index 7afb6592a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TL.png deleted file mode 100644 index c693cd8c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TR.png deleted file mode 100644 index eef19c90d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-left.png deleted file mode 100644 index 31da1c955..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-right.png deleted file mode 100644 index fe647fd4c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick.png deleted file mode 100644 index e21c59595..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-grey/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BL.png deleted file mode 100644 index 3e2817d90..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CC.png deleted file mode 100644 index 9a76ea6e9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CL.png deleted file mode 100644 index 9d28ffa78..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CR.png deleted file mode 100644 index fe6b42c2f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TL.png deleted file mode 100644 index 3fcc48bf2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TR.png deleted file mode 100644 index 4700b0f5f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-left.png deleted file mode 100644 index 0fafe1637..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick.png deleted file mode 100644 index d465c5903..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-orange/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BC.png deleted file mode 100644 index c5f4aebe6..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BL.png deleted file mode 100644 index 530ceef99..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BR.png deleted file mode 100644 index fc93c0bb3..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CC.png deleted file mode 100644 index 0deb77aef..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CR.png deleted file mode 100644 index 090c20552..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TL.png deleted file mode 100644 index 0122dffb2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TR.png deleted file mode 100644 index fa8728f59..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-left.png deleted file mode 100644 index fc9cbc77d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f578..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick.png deleted file mode 100644 index 6d6ea2625..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/img/bubble-red/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._color.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._color.css deleted file mode 100644 index 95d0e16e2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._color.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css deleted file mode 100644 index 98da5fc9a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/private/variants/._standard.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._hincoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._hincoming.htm deleted file mode 100644 index e9696af8a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._hincoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._houtgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._houtgoing.htm deleted file mode 100644 index a9944feee..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._houtgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._images.sh b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._images.sh deleted file mode 100644 index a104569d8..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._images.sh and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._img b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._img deleted file mode 100644 index 0be496cbe..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._img and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._incoming.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._incoming.htm deleted file mode 100644 index 7528a621a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._incoming.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml deleted file mode 100644 index 908cf35de..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._info.xml and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._main.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._main.css deleted file mode 100644 index f3c8bd7d9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._main.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm deleted file mode 100644 index ca9e4c69d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._ooutgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._outgoing.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._outgoing.htm deleted file mode 100644 index cc4288eaf..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._outgoing.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm deleted file mode 100644 index 8f6e1cd65..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._system.htm and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._variants b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._variants deleted file mode 100644 index 7a8b2196d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/._variants and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-grey b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-grey deleted file mode 100644 index 7f843c3c7..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-grey and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-orange b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-orange deleted file mode 100644 index c849b46c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-orange and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-red b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-red deleted file mode 100644 index 36474caa0..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/._bubble-red and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-blue/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-blue/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-blue/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-green/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BL.png deleted file mode 100644 index 5ad3fa3cc..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BR.png deleted file mode 100644 index 8107270d2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CC.png deleted file mode 100644 index 04138fb9f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CL.png deleted file mode 100644 index d9685f280..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CR.png deleted file mode 100644 index 01dcb89f9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TC.png deleted file mode 100644 index 7afb6592a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TL.png deleted file mode 100644 index c693cd8c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TR.png deleted file mode 100644 index eef19c90d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-left.png deleted file mode 100644 index 31da1c955..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-right.png deleted file mode 100644 index fe647fd4c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick.png deleted file mode 100644 index e21c59595..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-grey/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BL.png deleted file mode 100644 index 3e2817d90..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CC.png deleted file mode 100644 index 9a76ea6e9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CL.png deleted file mode 100644 index 9d28ffa78..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CR.png deleted file mode 100644 index fe6b42c2f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TL.png deleted file mode 100644 index 3fcc48bf2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TR.png deleted file mode 100644 index 4700b0f5f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-left.png deleted file mode 100644 index 0fafe1637..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick.png deleted file mode 100644 index d465c5903..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-orange/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BC.png deleted file mode 100644 index c5f4aebe6..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BL.png deleted file mode 100644 index 530ceef99..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BR.png deleted file mode 100644 index fc93c0bb3..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CC.png deleted file mode 100644 index 0deb77aef..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CR.png deleted file mode 100644 index 090c20552..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TL.png deleted file mode 100644 index 0122dffb2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TR.png deleted file mode 100644 index fa8728f59..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-left.png deleted file mode 100644 index fc9cbc77d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f578..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick.png deleted file mode 100644 index 6d6ea2625..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/img/bubble-red/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._color.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._color.css deleted file mode 100644 index 95d0e16e2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._color.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css deleted file mode 100644 index 98da5fc9a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/public/variants/._standard.css and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._images.sh b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._images.sh deleted file mode 100644 index f21d98621..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._images.sh and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img deleted file mode 100644 index 0be496cbe..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/._img and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-grey b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-grey deleted file mode 100644 index 7f843c3c7..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-grey and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-orange b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-orange deleted file mode 100644 index c849b46c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-orange and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-red b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-red deleted file mode 100644 index 36474caa0..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/._bubble-red and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-blue/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-blue/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-blue/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store deleted file mode 100644 index 321346b56..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-green/._.DS_Store and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png deleted file mode 100644 index 9bd67714c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BL.png deleted file mode 100644 index 5ad3fa3cc..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BR.png deleted file mode 100644 index 8107270d2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CC.png deleted file mode 100644 index 04138fb9f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CL.png deleted file mode 100644 index d9685f280..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CR.png deleted file mode 100644 index 01dcb89f9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TC.png deleted file mode 100644 index 7afb6592a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TL.png deleted file mode 100644 index c693cd8c1..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TR.png deleted file mode 100644 index eef19c90d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-left.png deleted file mode 100644 index 31da1c955..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-right.png deleted file mode 100644 index fe647fd4c..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick.png deleted file mode 100644 index e21c59595..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-grey/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png deleted file mode 100644 index 3d99b6c95..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BL.png deleted file mode 100644 index 3e2817d90..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png deleted file mode 100644 index 31bb15794..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CC.png deleted file mode 100644 index 9a76ea6e9..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CL.png deleted file mode 100644 index 9d28ffa78..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CR.png deleted file mode 100644 index fe6b42c2f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png deleted file mode 100644 index 7234ba76b..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TL.png deleted file mode 100644 index 3fcc48bf2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TR.png deleted file mode 100644 index 4700b0f5f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-left.png deleted file mode 100644 index 0fafe1637..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png deleted file mode 100644 index c633e9c6a..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick.png deleted file mode 100644 index d465c5903..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-orange/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BC.png deleted file mode 100644 index c5f4aebe6..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BL.png deleted file mode 100644 index 530ceef99..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BR.png deleted file mode 100644 index fc93c0bb3..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_BR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CC.png deleted file mode 100644 index 0deb77aef..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png deleted file mode 100644 index 7522f9163..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CR.png deleted file mode 100644 index 090c20552..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_CR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png deleted file mode 100644 index ec0a6376f..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TC.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TL.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TL.png deleted file mode 100644 index 0122dffb2..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TL.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TR.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TR.png deleted file mode 100644 index fa8728f59..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_TR.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-left.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-left.png deleted file mode 100644 index fc9cbc77d..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-left.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png deleted file mode 100644 index 32650f578..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick-right.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick.png b/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick.png deleted file mode 100644 index 6d6ea2625..000000000 Binary files a/retroshare-gui/src/gui/qss/chat/__MACOSX__Bubble/src/img/bubble-red/._bubble_tick.png and /dev/null differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss deleted file mode 100644 index e79ec6d1c..000000000 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ /dev/null @@ -1,1226 +0,0 @@ -/* Standard stylesheet for RetroShare */ - -/* Standard rules */ - -QFrame#toolBarFrame, QFrame#toolBarFrameTop { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -/* HeaderFrame */ - -HeaderFrame > QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -HeaderFrame > QFrame#frame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} - -AvatarDialog QFrame#infoframe -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* GenCertDialog */ - -GenCertDialog QLabel#genprofileinfo_label, QLabel#header_label, QLabel#entropy_label -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -GenCertDialog QLabel#label_hiddenaddr { - border: 1px solid #50FF5B; - border-radius: 6px; - background: #CCFFCC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA); -} -GenCertDialog QLabel#no_node_label, GenCertDialog QLabel#no_gpg_key_label { - border: 1px solid #FFC550; - border-radius: 6px; - background: #FFEECC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFEECC, stop:1 #FFE3AB); - padding: 4px; - font-size: 14pt; -} - -GenCertDialog > QFrame#headerFrame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} - -GenCertDialog > QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -/* ConnectFriendWizard */ - -ConnectFriendWizard { -/* QWizard cannot be resized horizontal when banner pixmap is set - qproperty-bannerPixmap: url(:/images/connect/connectFriendBanner1.png);*/ - qproperty-titleFontSize: 16; - qproperty-titleFontWeight: 500; -/* qproperty-titleColor: white; */ -} - -/* FriendsDialog */ - -FriendsDialog QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -FriendsDialog QFrame#headFrame > QLabel#nicknameLabel { - color: rgb(255, 255, 255); -} - -FriendsDialog QTextEdit#msgText, FriendsDialog QTextEdit#lineEdit { - border: 1px solid #CCCCCC; -} - -/* Channels */ - -ChannelFeed QFrame#headFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F2F2F2, stop:1 #E6E6E6); - border: 1px solid #CCCCCC; -} - -ChannelFeed QLabel#logoLabel, EditChanDetails QLabel#logoLabel, CreateChannel QLabel#logoLabel { - border: 2px solid white; -} - -CreateChannelMsg QFrame#fileFrame { - border: 2px solid black; - background: white; -} - -GxsCreateCommentDialog QTextEdit#commentTextEdit { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; -} - -GxsCreateCommentDialog QLabel#titleLabel { - font-size: 12pt; - font-weight: 600; - color: black; -} - -GxsCreateCommentDialog QLabel#replaytolabel { - font-weight: bold; - color: gray; -} - -GxsCreateCommentDialog QFrame#frame { - background: white; -} - -CreateGxsChannelMsg QPushButton#postButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -CreateGxsChannelMsg QPushButton#postButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -CreateCircleDialog QPushButton#createButton, CreateLobbyDialog QPushButton#createButton, -IdEditDialog QPushButton#createButton, CreateGxsForumMsg QPushButton#postButton, -GxsCreateCommentDialog QPushButton#postButton, GxsGroupDialog QPushButton#createButton, -PulseAddDialog QPushButton#pushButton_Post, PulseTopLevel QToolButton#toolButton_follow, -PulseViewGroup QToolButton#toolButton_follow, WikiEditDialog QPushButton#pushButton_Submit{ - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -CreateCircleDialog QPushButton#createButton:hover, CreateLobbyDialog QPushButton#createButton:hover, -IdEditDialog QPushButton#createButton:hover, CreateGxsForumMsg QPushButton#postButton:hover, -GxsCreateCommentDialog QPushButton#postButton:hover, GxsGroupDialog QPushButton#createButton:hover, -ShareManager QPushButton#closeButton:hover, PulseAddDialog QPushButton#pushButton_Post:hover, -PulseTopLevel QToolButton#toolButton_follow:hover, PulseViewGroup QToolButton#toolButton_follow:hover, -WikiEditDialog QPushButton#pushButton_Submit:hover{ - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#closeButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; - padding-left: 6px; - padding-right: 6px; -} - -ShareManager QPushButton#addButton{ - font: bold; - font-size: 12pt; - color: white; - background: #32CD32; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 4px; -} - -ShareManager QPushButton#addButton:hover{ - background: #5AD75A; - border-radius: 4px; - min-width: 4em; - padding: 4px; -} - -SearchDialog QPushButton#pushButtonSearch { - font: bold; - font-size: 12pt; - color: white; - background: #32CD32; - border-radius: 4px; - max-height: 25px; - min-width: 4em; - padding: 4px; -} - -SearchDialog QPushButton#pushButtonSearch:hover{ - background: #5AD75A; - border-radius: 4px; - min-width: 4em; - padding: 4px; -} - -CreateGxsForumMsg QPushButton#postButton:disabled, PostedCreatePostDialog QPushButton#submitButton:disabled, -CreateGxsChannelMsg QPushButton#postButton:disabled, GxsCreateCommentDialog QPushButton#postButton:disabled, -PulseAddDialog QPushButton#pushButton_Post:disabled, WikiEditDialog QPushButton#pushButton_Submit:disabled { - font: bold; - font-size: 12pt; - color: white; - background: #d40000; - border-radius: 4px; - max-height: 20px; - min-width: 4em; - padding-left: 6px; - padding-right: 6px; -} - -/* Forums */ - -GxsForumThreadWidget QPushButton#forumName -{ - font: bold; - font-size: 12pt; -} - -CreateForumMsg > QToolBar#toolBar, CreateForumV2Msg > QToolBar#toolBar { - background-image: url(:/images/headerFrame.png); -} - -/* MessengerWindow */ - -MessengerWindow QFrame#logoFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -MessengerWindow QFrame#messengerframetop{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -/* Create Distant Chat Invite */ - -CreateMsgLinkDialog QLabel#distantchatinfo_label -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* Chat lobby */ - -ChatLobbyWidget QLabel#lobbyinfo_label -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ChatLobbyWidget QLabel#lobbyname_lineEdit -{ - font: bold; - font-size: 16pt; -} - -ChatLobbyWidget QGroupBox#lobbyinfo_groupBox -{ - - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, - stop:0 #FEFEFE, stop:1 #E8E8E8); - border-radius: 6px; - border: 1px solid #CCCCCC; - - padding: 14 6px; - font-size: 12pt; - font-weight: bold; - -} - -ChatLobbyWidget QGroupBox::title#lobbyinfo_groupBox -{ - padding: 4 12px; - background: #039bd5; - color: white; -} - -ChatLobbyWidget QLabel#lobbyInfoLabel { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - - -ChatLobbyDialog QFrame#participantsFrame { - border: transparent; -} - -ChatLobbyDialog QListWidget#participantsList { - border: 1px solid #B8B6B1; - border-radius: 6px; - background: white; -} - -CreateLobbyDialog QFrame#roomFrame { - border: 2px solid #CCCCCC; - border-radius:6px; - background: white; -} - -CreateLobbyDialog QLabel#lobbyInfoLabel { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ChatWidget QTextEdit#chatTextEdit, ChatWidget QTextBrowser#textBrowser { - border: 1px solid #0099cc; - border-radius: 6px; - background: white; -} - -ChatWidget QFrame#infoFrame { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ChatWidget QFrame#titleBarFrame, QFrame#toolBarFrameTop { - -} - -PopupChatWindow QToolBar#chattoolBar{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -/* Messages */ - -MessageComposer QToolBar#toolBar { - -} - -MessagesDialog QFrame#folderFrame, MessagesDialog QFrame#quickViewFrame { - background: transparent; - -} - -/* Profile */ - -ProfileWidget QFrame#frame_1, ProfileWidget QFrame#frame_2, ProfileWidget QFrame#frame_3 { - background-color: white; - border: 2px solid #CCCCCC; -} - -/* Settings */ - -PluginItem > QFrame#frame { - border: 2px solid #A8B8D1; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FCFDFE, stop: 1 #E2E8EF); - border-radius: 0px -} - -/* Network */ - -/*NetworkView > QGraphWidget#graphicsView -{ - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 lightgray, stop:1 darkgray); -} -*/ - -/* GetStartedDialog */ - -GetStartedDialog QTextEdit { - border: 1px solid #B8B6B1; - border-radius: 6px; - background: white; -} - -/* GenCertDialog */ - -/* GenCertDialog > QFrame#headerFrame { - background-image: url(:/images/genbackground.png); -} - -GenCertDialog > QFrame#headerFrame > QLabel#headerLabel { - color: rgb(255, 255, 255); -} -*/ - -/* ConnectFriendWizard */ - -ConnectFriendWizard QWizardPage#ConclusionPage > QGroupBox#peerDetailsFrame { - border: 2px solid #039bd5; - border-radius:6px; - background: white; - padding: 12 12px; -} - -ConnectFriendWizard QLabel#fr_label, QLabel#requestinfolabel, QLabel#cp_Label -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ConnectFriendWizard QGroupBox::title#peerDetailsFrame -{ - padding: 4 12px; - background: transparent; - padding: 4 12px; - background: #039bd5; - color: white; -} - -/* Toaster */ - -ChatToaster > QFrame#windowFrame, -ChatLobbyToaster > QFrame#windowFrame, -DownloadToaster > QFrame#windowFrame, -FriendRequestToaster > QFrame#windowFrame, -GroupChatToaster > QFrame#windowFrame, -MessageToaster >QFrame#windowFrame, -OnlineToaster > QFrame#windowFrame { - background-image: url(:/images/toaster/backgroundtoaster.png); -} - -/* Feeds */ - -AttachFileItem > QFrame#frame { - border: 2px solid black; - background: white; -} - -ChanNewItem > QFrame#frame { - border: 2px solid #D3D3D3; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFFF, stop:1 #F2F2F2); - border-radius: 10px; -} - -ChanNewItem QLabel#logoLabel { - border: 2px solid #D3D3D3; - border-radius: 2px; -} - -GxsChannelPostItem > QFrame#mainFrame[new=false] { - background-color: white; -} - -GxsChannelPostItem > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -GxsChannelPostItem QLabel#newLabel{ - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; - color: white; -} - -GxsChannelPostItem QLabel#subjectLabel, GxsChannelPostItem QLabel#titleLabel { - font: 11pt; - font: bold italic; -} - -GxsChannelPostItem QFrame#msgFrame { - border: 2px solid #82B9F4; - border-radius: 3px; -} - -GxsChannelPostItem QLabel#logoLabel { - border: 2px solid #D3D3D3; -} - -GxsChannelPostItem QLabel#logoLabel { - background-color: black; -} - -GxsCircleItem QFrame#mainFrame { - background-color: white; -} - -GxsCircleItem QLabel#gxsIdLabel, QLabel#nameLabel, QLabel#titleLabel { - font: 11pt; - font: bold italic; -} - - -ForumNewItem > QFrame#frame, ForumMsgItem > QFrame#frame { - border: 2px solid #CCCCCC; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC); - border-radius: 10px; -} - -ForumNewItem > QLabel#nextNameLabel, ForumMsgItem > QLabel#nameLabel { - color: rgb(59, 89, 152); -} - -ForumMsgItem QLabel#iconLabel { - border: 2px solid #CCCCCC; - background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #EEEEEE, stop: 1 #CCCCCC); - border-radius: 10px -} - -ForumMsgItem QFrame#prevFrame { - border: 2px solid black; - border-radius: 10px; -} - -SubFileItem QProgressBar#progressBar { - border: 1px solid black; - text-align: center; - color: white; - padding: 1px; - border-top-left-radius: 7px; - border-bottom-left-radius: 7px; - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fff, stop: 0.4999 #eee, stop: 0.5 #ddd, stop: 1 #eee); - min-width: 15px; -} - -SubFileItem QProgressBar#progressBar::chunk { - background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #78d, stop: 0.4999 #46a, stop: 0.5 #45a, stop: 1 #238); - border-top-left-radius: 7px; - border-bottom-left-radius: 7px; - border: 1px solid black; - min-width: 15px; -} - -PluginItem QLabel#infoLabel { - - color: #054A02; - font: bold; - -} - -ConfCertDialog QPlainTextEdit#plainTextEdit { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ServerPage QPlainTextEdit#plainTextEdit { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ServerPage QPlainTextEdit#hiddenpageInHelpPlainTextEdit { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -ServerPage QPlainTextEdit#pteBobSimple { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - - -/* ProfileManager */ - -ProfileManager > QFrame#headerFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px solid #CCCCCC; -} - -ProfileManager QTextEdit#textEdit -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* RSImageBlockWidget */ - -RSImageBlockWidget QFrame#infoFrame { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* ShareManager */ - -ShareManager QLabel#labelInstructions { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* MessageWidget */ - -MessageWidget QFrame#decryptFrame { - border: 1px solid #50FF5B; - border-radius: 6px; - background: #CCFFCC; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #CCFFCC, stop:1 #AAFFAA); -} - -MessageWidget QFrame#inviteFrame { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -/* Posted Links */ - -PostedCreatePostDialog QLabel#info_label { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -QLabel#sharekeyinfo_label{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -QLabel#subscribersLabel{ - border: 1px solid #CCCCCC; - border-radius: 6px; - -} - -QFrame#distantFrame{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -QLabel#avatarLabel{ - border: 2px solid #CCCCCC; - border-radius: 4px; -} - -IdDialog QFrame#headerFramePerson { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -IdDialog QFrame#headerFrameCircle { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 1px; - border-radius: 4px; -} - -IdDialog QLabel#headerTextLabel { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#headerTextLabel_Person { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#headerTextLabel_Circles { - color: rgb(255, 255, 255); -} - -IdDialog QLabel#avlabel { - border: 4px solid white; - border-radius: 10px; -} - -IdDialog QFrame#inviteFrame { - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -IdEditDialog QLabel#info_label -{ - border: 1px solid #DCDC41; - border-radius: 6px; - background: #FFFFD7; - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); -} - -GenCertDialog QComboBox#genPGPuser { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QSpinBox#hiddenport_spinBox { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#hiddenaddr_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#password2_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#password_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#nickname_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#node_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QLineEdit#name_input { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; - font: bold; -} - -GenCertDialog QPushButton#genButton { - border-image: url(:/images/btn_blue.png) 4; - border-width: 4; - font: bold; - color: white; -} - -GenCertDialog QPushButton#genButton:hover { - border-image: url(:/images/btn_blue_hover.png) 4; -} - -GenCertDialog QPushButton#genButton:disabled { - border-image: url(:/images/btn_27.png) 4; -/* font-size: 16pt; */ - font: bold; - color: black; -} - -ConnectFriendWizard QRadioButton { - font-size: 16pt; -} - -ConnectFriendWizard QPlainTextEdit#friendCertEdit { - border: none; - background: white; -} - -ConnectFriendWizard QFrame#friendFrame { - border: 2px solid #0099cc; - border-radius: 6px; - background: white; -} - -StartDialog QPushButton#loadButton { - border-image: url(:/images/btn_blue.png) 4; - border-width: 4; - font: bold; - color: white; -} - -StartDialog QPushButton#loadButton:hover { - border-image: url(:/images/btn_blue_hover.png) 4; -} - -StartDialog QFrame#loginframe{ - border-image: url(:/images/logo/background_lessblue.png) 0 0 0 0 stretch stretch; - border-width: 0px; -} - -GenCertDialog QFrame#profileframe{ - border-image: url(:/images/logo/background.png) 0 0 0 0 stretch stretch; - border-width: 0px; -} - -PostedListWidgetWithModel QComboBox#sortStrategy_CB { - font: bold; - color: #0099cc; -} - -PostedListWidgetWithModel QToolButton#submitPostButton, GxsChannelPostsWidgetWithModel QToolButton#postButton, -GxsForumThreadWidget QToolButton#newthreadButton { - font: bold; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -PostedListWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -PostedListWidgetWithModel QFrame#headerFrame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); - border: 1px solid #CCCCCC; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsForumThreadWidget QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsForumMsgItem QFrame#mainFrame, PeerItem QFrame#mainFrame, GxsForumGroupItem QFrame#mainFrame, -GxsChannelGroupItem QFrame#mainFrame, MsgItem QFrame#mainFrame, ChatMsgItem QFrame#mainFrame -SecurityIpItem QFrame#mainFrame, MsgItem QFrame#msgFrame, SecurityItem QFrame#mainFrame{ - background-color: white; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:hover { - background: #03b1f3; - border-radius: 4px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:pressed { - background: #03b1f3; - border-radius: 4px; - border: 1px solid gray; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton:disabled { - background: gray; - border-radius: 4px; - border: 1px solid gray; - color: lightgray; -} - -/* only for MenuButtonPopup */ - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"], -PostedListWidgetWithModel QToolButton#subscribeToolButton[popupMode="1"]{ - padding-right: 0px; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-arrow, -PostedListWidgetWithModel QToolButton#subscribeToolButton::menu-arrow{ - image: none; -} - -GxsChannelPostsWidgetWithModel QToolButton#subscribeToolButton::menu-button, -PostedListWidgetWithModel QToolButton#subscribeToolButton::menu-button{ - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { - padding-right: 0px; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { - image: none; -} - -GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { - padding-right: 0px; -} - -GxsGroupDialog QLabel#groupLogo{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -GxsChannelGroupItem QFrame#frame, GxsForumGroupItem QFrame#frame, -PostedGroupItem QFrame#frame { - background-color: white; -} - -HomePage QLabel#userCertLabel { - color: #0099cc; - font: bold; -} - -HomePage QPlainTextEdit#userCertEdit { - - background: transparent; -} - -HomePage QToolButton#addButton { - font: bold; - font-size: 15pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -HomePage QToolButton#addButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - - -PostedItem QFrame#mainFrame { - background-color: white; -} - -PostedItem > QFrame#mainFrame [new=false]{ - background: white; -} - -PostedItem QFrame#voteFrame { - background: #f8f9fa; -} - -BoardPostDisplayWidget_compact QFrame#mainFrame { - background-color: white; -} - -BoardPostDisplayWidget_compact > QFrame#mainFrame [new=false]{ - background: white; -} - -BoardPostDisplayWidget_compact > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -BoardPostDisplayWidget_compact QLabel#pictureLabel{ - border: 2px solid #CCCCCC; - border-radius: 3px; -} - -BoardPostDisplayWidget_compact QLabel#fromBoldLabel , -BoardPostDisplayWidget_card QLabel#fromBoldLabel { - font: bold; -} - -BoardPostDisplayWidget_compact QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel , -BoardPostDisplayWidget_card QLabel#fromBoldLabel, QLabel#fromLabel, QLabel#dateLabel, QLabel#siteBoldLabel{ - color: #787c7e; -} - -BoardPostDisplayWidget_compact QLabel#newLabel { - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; -} - -BoardPostDisplayWidget_card QLabel#newLabel { - border: 1px solid #167BE7; - background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); - border-radius: 3px; -} - -PostedCardView QFrame#voteFrame { - background: #f8f9fa; -} - -BoardPostDisplayWidget_card QFrame#mainFrame{ - background: white; -} - -BoardPostDisplayWidget_card > QFrame#mainFrame [new=false]{ - background: white; -} - -BoardPostDisplayWidget_card > QFrame#mainFrame[new=true] { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); -} - -BoardPostDisplayWidget_compact QLabel#titleLabel, -BoardPostDisplayWidget_card QLabel#titleLabel{ - font-size: 14pt; - font: bold; -} - -GxsCommentDialog QComboBox#sortBox { - font: bold; - color: #0099cc; -} - -PostedListWidgetWithModel QTextBrowser#infoDescription { - background: transparent; - border: none; -} - -PostedCreatePostDialog QPushButton#submitButton { - font: bold; - font-size: 12pt; - color: white; - background: #0099cc; - border-radius: 4px; - max-height: 27px; - min-width: 4em; - padding: 2px; -} - -PostedCreatePostDialog QPushButton#submitButton:hover { - background: #03b1f3; - border-radius: 4px; - min-width: 4em; - padding: 2px; -} - -MessageWidget QTextBrowser#toText , QTextBrowser#ccText , QTextBrowser#bccText { - background: transparent; - border: none; -} - -WireGroupItem QWidget:hover{ - background-color: #7ecbfb; -} - -WireDialog QFrame#frame{ - background-color: white; -} - -WireDialog QWidget#scrollAreaWidgetContents_groups{ - background-color: white; -} - -MessagesDialog QWidget#messageTreeWidget::item { - padding: 2px; -} - -MessagesDialog QWidget#messageTreeWidget::item:selected { - background-color: #cde8ff; - color: black; -} - -MessagesDialog QWidget#messageTreeWidget::item:hover { - background-color: #e5f3ff; - color: black; -} - -GxsForumThreadWidget QWidget#threadTreeWidget { - selection-background-color: #cde8ff; - show-decoration-selected: 1; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item { - padding: 2px; -} - -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , -GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { - background-color: #cde8ff; -} - -GxsChannelDialog GroupTreeWidget QTreeWidget#treeWidget::item{ - /*background-color: #F00000;*/ - /*padding: 2px*/ -} - -MainWindow QListWidget { - font-size: 12pt; -} - -PulseTopLevel QFrame#frame, PulseViewGroup QFrame#frame, PulseReply QFrame#frame { - border: 2px solid #c4cfd6; - background: white; -} - -PulseAddDialog QTextEdit#textEdit_Pulse { - border: 2px solid #c4cfd6; - border-radius: 6px; - background: white; -} - -PulseAddDialog QFrame#frame_input, QFrame#frame_reply, QFrame#frame { - border: 0px; -} - -PulseAddDialog QLabel#label_groupName { - font-size: 12pt; -} - -PulseReply #line_replyLine , PulseMessage #line{ - color: #c4cfd6; -} - -PulseReply QLabel#label_groupName{ - color: #5b7083; -} - -WireDialog QLabel#label_viewMode { - font-size: 12pt; -} - -WireGroupDialog QFrame#frame { - background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); - border: 0px; -} - -PhotoShare QPushButton#pushButton_YourAlbums, QPushButton#pushButton_SubscribedAlbums, -QPushButton#pushButton_SharedAlbums { - font-size: 12pt; -} - -AlbumItem QFrame#albumFrame { - border: 2px solid #CCCCCC; - border-radius: 10px -} - -PhotoItem QFrame#photoFrame { - border: 2px solid #CCCCCC; - border-radius: 10px -} - -PhotoItem QWidget:hover { - background-color: #7ecbfb; -} - -PhotoSlideShow QLabel#albumLabel { - font-size: 12pt; -} - -ChannelsCommentsItem QFrame#mainFrame, BoardsCommentsItem QFrame#mainFrame { - background-color: white; -} - -ChannelsCommentsItem QLabel#newCommentLabel, BoardsCommentsItem QLabel#newCommentLabel { - font-size: 12pt; - font: bold; -} - -ChannelsCommentsItem QLabel#subjectLabel, ChannelsCommentsItem QLabel#titleLabel , QLabel#nameLabel { - font-size: 12pt; - font: bold; -} - -BoardsCommentsItem QLabel#subjectLabel, QLabel#titleLabel , QLabel#nameLabel { - font-size: 12pt; - font: bold; -} - -NewFriendList QTreeView#peerTreeWidget::item:selected, QTreeView#peerTreeWidget::branch:selected:active { - background: #cde8ff; -} - -NewFriendList QTreeView#peerTreeWidget { - font-size: 12pt; -} - -NewFriendList QTreeView::branch:has-children:!has-siblings:closed, -NewFriendList QTreeView::branch:closed:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-right.png); -} - -NewFriendList QTreeView::branch:open:has-children:!has-siblings, -NewFriendList QTreeView::branch:open:has-children:has-siblings { - border-image: none; - image: url(:/images/arrow-down.png); -} diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss new file mode 100644 index 000000000..7497440c5 --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Dark.qss @@ -0,0 +1,2561 @@ + /* Standard Dark stylesheet for RetroShare + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + + It use a public one for general widgets https://github.com/ColinDuquesnoy/QDarkStyleSheet + /qdarkstyle/dark/style.qss + Updated at 2021-11-04 Tag v3.0.2 + Replace all ":/qss_icons/dark" by ":/standard_dark" + */ + +/* --------------------------------------------------------------------------- + + WARNING! File created programmatically. All changes made in this file will be lost! + + Created by the qtsass compiler v0.3.0 + + The definitions are in the "qdarkstyle.qss._styles.scss" module + +--------------------------------------------------------------------------- */ +/* Light Style - QDarkStyleSheet ------------------------------------------ */ +/* + +See Qt documentation: + + - https://doc.qt.io/qt-5/stylesheet.html + - https://doc.qt.io/qt-5/stylesheet-reference.html + - https://doc.qt.io/qt-5/stylesheet-examples.html + +--------------------------------------------------------------------------- */ +/* Reset elements ------------------------------------------------------------ + +Resetting everything helps to unify styles across different operating systems + +--------------------------------------------------------------------------- */ +* { + padding: 0px; + margin: 0px; + border: 0px; + border-style: none; + border-image: none; + outline: 0; +} + +/* specific reset for elements inside QToolBar */ +QToolBar * { + margin: 0px; + padding: 0px; +} + +/* QWidget ---------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QWidget { + background-color: #19232D; + border: 0px solid #455364; + padding: 0px; + color: #E0E1E3; + selection-background-color: #346792; + selection-color: #E0E1E3; +} + +QWidget:disabled { + background-color: #19232D; + color: #9DA9B5; + selection-background-color: #26486B; + selection-color: #9DA9B5; +} + +QWidget::item:selected { + background-color: #346792; +} + +QWidget::item:hover:!selected { + background-color: #1A72BB; +} + +/* QMainWindow ------------------------------------------------------------ + +This adjusts the splitter in the dock widget, not qsplitter +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow + +--------------------------------------------------------------------------- */ +QMainWindow::separator { + background-color: #455364; + border: 0px solid #19232D; + spacing: 0px; + padding: 2px; +} + +QMainWindow::separator:hover { + background-color: #60798B; + border: 0px solid #1A72BB; +} + +QMainWindow::separator:horizontal { + width: 5px; + margin-top: 2px; + margin-bottom: 2px; + image: url(":/standard_dark/rc/toolbar_separator_vertical.png"); +} + +QMainWindow::separator:vertical { + height: 5px; + margin-left: 2px; + margin-right: 2px; + image: url(":/standard_dark/rc/toolbar_separator_horizontal.png"); +} + +/* QToolTip --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip + +--------------------------------------------------------------------------- */ +QToolTip { + background-color: #346792; + color: #E0E1E3; + /* If you remove the border property, background stops working on Windows */ + border: none; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Remove opacity, fix #174 - may need to use RGBA */ +} + +/* QStatusBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar + +--------------------------------------------------------------------------- */ +QStatusBar { + border: 1px solid #455364; + /* Fixes Spyder #9120, #9121 */ + background: #455364; + /* Fixes #205, white vertical borders separating items */ +} + +QStatusBar::item { + border: none; +} + +QStatusBar QToolTip { + background-color: #1A72BB; + border: 1px solid #19232D; + color: #19232D; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Reducing transparency to read better */ + opacity: 230; +} + +QStatusBar QLabel { + /* Fixes Spyder #9120, #9121 */ + background: transparent; +} + +/* QCheckBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox + +--------------------------------------------------------------------------- */ +QCheckBox { + background-color: #19232D; + color: #E0E1E3; + spacing: 4px; + outline: none; + padding-top: 4px; + padding-bottom: 4px; +} + +QCheckBox:focus { + border: none; +} + +QCheckBox QWidget:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QCheckBox::indicator { + margin-left: 2px; + height: 14px; + width: 14px; +} + +QCheckBox::indicator:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QCheckBox::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QCheckBox::indicator:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QCheckBox::indicator:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +QCheckBox::indicator:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QCheckBox::indicator:indeterminate:disabled { + image: url(":/standard_dark/rc/checkbox_indeterminate_disabled.png"); +} + +QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +/* QGroupBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox + +--------------------------------------------------------------------------- */ +QGroupBox { + font-weight: bold; + border: 1px solid #455364; + border-radius: 4px; + padding: 2px; + margin-top: 6px; + margin-bottom: 4px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 4px; + padding-left: 2px; + padding-right: 4px; + padding-top: -4px; +} + +QGroupBox::indicator { + margin-left: 2px; + margin-top: 2px; + padding: 0; + height: 14px; + width: 14px; +} + +QGroupBox::indicator:unchecked { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QGroupBox::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QGroupBox::indicator:checked { + border: none; + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QGroupBox::indicator:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +/* QRadioButton ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton + +--------------------------------------------------------------------------- */ +QRadioButton { + background-color: #19232D; + color: #E0E1E3; + spacing: 4px; + padding-top: 4px; + padding-bottom: 4px; + border: none; + outline: none; +} + +QRadioButton:focus { + border: none; +} + +QRadioButton:disabled { + background-color: #19232D; + color: #9DA9B5; + border: none; + outline: none; +} + +QRadioButton QWidget { + background-color: #19232D; + color: #E0E1E3; + spacing: 0px; + padding: 0px; + outline: none; + border: none; +} + +QRadioButton::indicator { + border: none; + outline: none; + margin-left: 2px; + height: 14px; + width: 14px; +} + +QRadioButton::indicator:unchecked { + image: url(":/standard_dark/rc/radio_unchecked.png"); +} + +QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_unchecked_focus.png"); +} + +QRadioButton::indicator:unchecked:disabled { + image: url(":/standard_dark/rc/radio_unchecked_disabled.png"); +} + +QRadioButton::indicator:checked { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked.png"); +} + +QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked_focus.png"); +} + +QRadioButton::indicator:checked:disabled { + outline: none; + image: url(":/standard_dark/rc/radio_checked_disabled.png"); +} + +/* QMenuBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar + +--------------------------------------------------------------------------- */ +QMenuBar { + background-color: #455364; + padding: 2px; + border: 1px solid #19232D; + color: #E0E1E3; + selection-background-color: #1A72BB; +} + +QMenuBar:focus { + border: 1px solid #346792; +} + +QMenuBar::item { + background: transparent; + padding: 4px; +} + +QMenuBar::item:selected { + padding: 4px; + background: transparent; + border: 0px solid #455364; + background-color: #1A72BB; +} + +QMenuBar::item:pressed { + padding: 4px; + border: 0px solid #455364; + background-color: #1A72BB; + color: #E0E1E3; + margin-bottom: 0px; + padding-bottom: 0px; +} + +/* QMenu ------------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu + +--------------------------------------------------------------------------- */ +QMenu { + border: 0px solid #455364; + color: #E0E1E3; + margin: 0px; + background-color: #37414F; + selection-background-color: #1A72BB; +} + +QMenu::separator { + height: 1px; + background-color: #60798B; + color: #E0E1E3; +} + +QMenu::item { + background-color: #37414F; + padding: 4px 24px 4px 28px; + /* Reserve space for selection border */ + border: 1px transparent #455364; +} + +QMenu::item:selected { + color: #E0E1E3; + background-color: #1A72BB; +} + +QMenu::item:pressed { + background-color: #1A72BB; +} + +QMenu::icon { + padding-left: 10px; + width: 14px; + height: 14px; +} + +QMenu::indicator { + padding-left: 8px; + width: 12px; + height: 12px; + /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ + /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +} + +QMenu::indicator:non-exclusive:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QMenu::indicator:non-exclusive:unchecked:hover, QMenu::indicator:non-exclusive:unchecked:focus, QMenu::indicator:non-exclusive:unchecked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QMenu::indicator:non-exclusive:unchecked:disabled { + image: url(":/standard_dark/rc/checkbox_unchecked_disabled.png"); +} + +QMenu::indicator:non-exclusive:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QMenu::indicator:non-exclusive:checked:hover, QMenu::indicator:non-exclusive:checked:focus, QMenu::indicator:non-exclusive:checked:pressed { + border: none; + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/standard_dark/rc/checkbox_checked_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:disabled { + image: url(":/standard_dark/rc/checkbox_indeterminate_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:focus, QMenu::indicator:non-exclusive:indeterminate:hover, QMenu::indicator:non-exclusive:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +QMenu::indicator:exclusive:unchecked { + image: url(":/standard_dark/rc/radio_unchecked.png"); +} + +QMenu::indicator:exclusive:unchecked:hover, QMenu::indicator:exclusive:unchecked:focus, QMenu::indicator:exclusive:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_unchecked_focus.png"); +} + +QMenu::indicator:exclusive:unchecked:disabled { + image: url(":/standard_dark/rc/radio_unchecked_disabled.png"); +} + +QMenu::indicator:exclusive:checked { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked.png"); +} + +QMenu::indicator:exclusive:checked:hover, QMenu::indicator:exclusive:checked:focus, QMenu::indicator:exclusive:checked:pressed { + border: none; + outline: none; + image: url(":/standard_dark/rc/radio_checked_focus.png"); +} + +QMenu::indicator:exclusive:checked:disabled { + outline: none; + image: url(":/standard_dark/rc/radio_checked_disabled.png"); +} + +QMenu::right-arrow { + margin: 5px; + padding-left: 12px; + image: url(":/standard_dark/rc/arrow_right.png"); + height: 12px; + width: 12px; +} + +/* QAbstractItemView ------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QAbstractItemView { + alternate-background-color: #19232D; + color: #E0E1E3; + border: 1px solid #455364; + border-radius: 4px; +} + +QAbstractItemView QLineEdit { + padding: 2px; +} + +/* QAbstractScrollArea ---------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QAbstractScrollArea { + background-color: #19232D; + border: 1px solid #455364; + border-radius: 4px; + /* fix #159 */ + padding: 2px; + /* remove min-height to fix #244 */ + color: #E0E1E3; +} + +QAbstractScrollArea:disabled { + color: #9DA9B5; +} + +/* QScrollArea ------------------------------------------------------------ + +--------------------------------------------------------------------------- */ +QScrollArea QWidget QWidget:disabled { + background-color: #19232D; +} + +/* QScrollBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar + +--------------------------------------------------------------------------- */ +QScrollBar:horizontal { + height: 16px; + margin: 2px 16px 2px 16px; + border: 1px solid #455364; + border-radius: 4px; + background-color: #19232D; +} + +QScrollBar:vertical { + background-color: #19232D; + width: 16px; + margin: 16px 2px 16px 2px; + border: 1px solid #455364; + border-radius: 4px; +} + +QScrollBar::handle:horizontal { + background-color: #60798B; + border: 1px solid #455364; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:hover { + background-color: #346792; + border: #346792; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:focus { + border: 1px solid #1A72BB; +} + +QScrollBar::handle:vertical { + background-color: #60798B; + border: 1px solid #455364; + min-height: 8px; + border-radius: 4px; +} + +QScrollBar::handle:vertical:hover { + background-color: #346792; + border: #346792; + border-radius: 4px; + min-height: 8px; +} + +QScrollBar::handle:vertical:focus { + border: 1px solid #1A72BB; +} + +QScrollBar::add-line:horizontal { + margin: 0px 0px 0px 0px; + border-image: url(":/standard_dark/rc/arrow_right_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on { + border-image: url(":/standard_dark/rc/arrow_right.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on { + border-image: url(":/standard_dark/rc/arrow_down.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + margin: 0px 3px 0px 3px; + border-image: url(":/standard_dark/rc/arrow_left_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on { + border-image: url(":/standard_dark/rc/arrow_left.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_dark/rc/arrow_up_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on { + border-image: url(":/standard_dark/rc/arrow_up.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal { + background: none; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + background: none; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + +/* QTextEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets + +--------------------------------------------------------------------------- */ +QTextEdit { + background-color: #19232D; + color: #E0E1E3; + border-radius: 4px; + border: 1px solid #455364; +} + +QTextEdit:focus { + border: 1px solid #1A72BB; +} + +QTextEdit:selected { + background: #346792; + color: #455364; +} + +/* QPlainTextEdit --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QPlainTextEdit { + background-color: #19232D; + color: #E0E1E3; + border-radius: 4px; + border: 1px solid #455364; +} + +QPlainTextEdit:focus { + border: 1px solid #1A72BB; +} + +QPlainTextEdit:selected { + background: #346792; + color: #455364; +} + +/* QSizeGrip -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip + +--------------------------------------------------------------------------- */ +QSizeGrip { + background: transparent; + width: 12px; + height: 12px; + image: url(":/standard_dark/rc/window_grip.png"); +} + +/* QStackedWidget --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QStackedWidget { + padding: 2px; + border: 1px solid #455364; + border: 1px solid #19232D; +} + +/* QToolBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar + +--------------------------------------------------------------------------- */ +QToolBar { + background-color: #455364; + border-bottom: 1px solid #19232D; + padding: 1px; + font-weight: bold; + spacing: 2px; +} + +QToolBar:disabled { + /* Fixes #272 */ + background-color: #455364; +} + +QToolBar::handle:horizontal { + width: 16px; + image: url(":/standard_dark/rc/toolbar_move_horizontal.png"); +} + +QToolBar::handle:vertical { + height: 16px; + image: url(":/standard_dark/rc/toolbar_move_vertical.png"); +} + +QToolBar::separator:horizontal { + width: 16px; + image: url(":/standard_dark/rc/toolbar_separator_horizontal.png"); +} + +QToolBar::separator:vertical { + height: 16px; + image: url(":/standard_dark/rc/toolbar_separator_vertical.png"); +} + +QToolButton#qt_toolbar_ext_button { + background: #455364; + border: 0px; + color: #E0E1E3; + image: url(":/standard_dark/rc/arrow_right.png"); +} + +/* QAbstractSpinBox ------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractSpinBox { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; + /* min-width: 5px; removed to fix 109 */ +} + +QAbstractSpinBox:up-button { + background-color: transparent #19232D; + subcontrol-origin: border; + subcontrol-position: top right; + border-left: 1px solid #455364; + border-bottom: 1px solid #455364; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-bottom: -1px; +} + +QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off { + image: url(":/standard_dark/rc/arrow_up_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::up-arrow:hover { + image: url(":/standard_dark/rc/arrow_up.png"); +} + +QAbstractSpinBox:down-button { + background-color: transparent #19232D; + subcontrol-origin: border; + subcontrol-position: bottom right; + border-left: 1px solid #455364; + border-top: 1px solid #455364; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-top: -1px; +} + +QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::down-arrow:hover { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QAbstractSpinBox:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QAbstractSpinBox:focus { + border: 1px solid #1A72BB; +} + +QAbstractSpinBox:selected { + background: #346792; + color: #455364; +} + +/* ------------------------------------------------------------------------ */ +/* DISPLAYS --------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QLabel ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe + +--------------------------------------------------------------------------- */ +QLabel { + background-color: #19232D; + border: 0px solid #455364; + padding: 2px; + margin: 0px; + color: #E0E1E3; +} + +QLabel:disabled { + background-color: #19232D; + border: 0px solid #455364; + color: #9DA9B5; +} + +/* QTextBrowser ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QTextBrowser { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; +} + +QTextBrowser:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; +} + +QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed { + border: 1px solid #455364; +} + +/* QGraphicsView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QGraphicsView { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; +} + +QGraphicsView:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; +} + +QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed { + border: 1px solid #455364; +} + +/* QCalendarWidget -------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCalendarWidget { + border: 1px solid #455364; + border-radius: 4px; +} + +QCalendarWidget:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +/* QLCDNumber ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QLCDNumber { + background-color: #19232D; + color: #E0E1E3; +} + +QLCDNumber:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +/* QProgressBar ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar + +--------------------------------------------------------------------------- */ +QProgressBar { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; + text-align: center; +} + +QProgressBar:disabled { + background-color: #19232D; + border: 1px solid #455364; + color: #9DA9B5; + border-radius: 4px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #346792; + color: #19232D; + border-radius: 4px; +} + +QProgressBar::chunk:disabled { + background-color: #26486B; + color: #9DA9B5; + border-radius: 4px; +} + +/* ------------------------------------------------------------------------ */ +/* BUTTONS ---------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QPushButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton + +--------------------------------------------------------------------------- */ +QPushButton { + background-color: #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; +} + +QPushButton:disabled { + background-color: #455364; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; +} + +QPushButton:checked { + background-color: #60798B; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:disabled { + background-color: #60798B; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:selected { + background: #60798B; +} + +QPushButton:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QPushButton:pressed { + background-color: #60798B; +} + +QPushButton:selected { + background: #60798B; + color: #E0E1E3; +} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + bottom: 4px; +} + +QDialogButtonBox QPushButton { + /* Issue #194 #248 - Special case of QPushButton inside dialogs, for better UI */ + min-width: 80px; +} + +/* QToolButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton + +--------------------------------------------------------------------------- */ +QToolButton { + background-color: #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; + /* The subcontrols below are used only in the DelayedPopup mode */ + /* The subcontrols below are used only in the MenuButtonPopup mode */ + /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +} + +QToolButton:disabled { + background-color: #455364; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; +} + +QToolButton:checked { + background-color: #60798B; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:disabled { + background-color: #60798B; + color: #9DA9B5; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QToolButton:checked:pressed { + background-color: #60798B; +} + +QToolButton:checked:selected { + background: #60798B; + color: #E0E1E3; +} + +QToolButton:hover { + background-color: #54687A; + color: #E0E1E3; +} + +QToolButton:pressed { + background-color: #60798B; +} + +QToolButton:selected { + background: #60798B; + color: #E0E1E3; +} + +QToolButton[popupMode="0"] { + /* Only for DelayedPopup */ + padding-right: 2px; +} + +QToolButton[popupMode="1"] { + /* Only for MenuButtonPopup */ + padding-right: 20px; +} + +QToolButton[popupMode="1"]::menu-button { + border: none; +} + +QToolButton[popupMode="1"]::menu-button:hover { + border: none; + border-left: 1px solid #455364; + border-radius: 0; +} + +QToolButton[popupMode="2"] { + /* Only for InstantPopup */ + padding-right: 2px; +} + +QToolButton::menu-button { + padding: 2px; + border-radius: 4px; + width: 12px; + border: none; + outline: none; +} + +QToolButton::menu-button:hover { + border: 1px solid #346792; +} + +QToolButton::menu-button:checked:hover { + border: 1px solid #346792; +} + +QToolButton::menu-indicator { + image: url(":/standard_dark/rc/arrow_down.png"); + height: 8px; + width: 8px; + top: 0; + /* Exclude a shift for better image */ + left: -2px; + /* Shift it a bit */ +} + +QToolButton::menu-arrow { + image: url(":/standard_dark/rc/arrow_down.png"); + height: 8px; + width: 8px; +} + +QToolButton::menu-arrow:hover { + image: url(":/standard_dark/rc/arrow_down_focus.png"); +} + +/* QCommandLinkButton ----------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCommandLinkButton { + background-color: transparent; + border: 1px solid #455364; + color: #E0E1E3; + border-radius: 4px; + padding: 0px; + margin: 0px; +} + +QCommandLinkButton:disabled { + background-color: transparent; + color: #9DA9B5; +} + +/* ------------------------------------------------------------------------ */ +/* INPUTS - NO FIELDS ----------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QComboBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QComboBox { + border: 1px solid #455364; + border-radius: 4px; + selection-background-color: #346792; + padding-left: 4px; + padding-right: 4px; + /* padding-right = 36; 4 + 16*2 See scrollbar size */ + /* changed to 4px to fix #239 */ + /* Fixes #103, #111 */ + min-height: 1.5em; + /* padding-top: 2px; removed to fix #132 */ + /* padding-bottom: 2px; removed to fix #132 */ + /* min-width: 75px; removed to fix #109 */ + /* Needed to remove indicator - fix #132 */ +} + +QComboBox QAbstractItemView { + border: 1px solid #455364; + border-radius: 0; + background-color: #19232D; + selection-background-color: #346792; +} + +QComboBox QAbstractItemView:hover { + background-color: #19232D; + color: #E0E1E3; +} + +QComboBox QAbstractItemView:selected { + background: #346792; + color: #455364; +} + +QComboBox QAbstractItemView:alternate { + background: #19232D; +} + +QComboBox:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QComboBox:hover { + border: 1px solid #346792; +} + +QComboBox:focus { + border: 1px solid #1A72BB; +} + +QComboBox:on { + selection-background-color: #346792; +} + +QComboBox::indicator { + border: none; + border-radius: 0; + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + /* Needed to remove indicator - fix #132 */ +} + +QComboBox::indicator:alternate { + background: #19232D; +} + +QComboBox::item:alternate { + background: #19232D; +} + +QComboBox::item:checked { + font-weight: bold; +} + +QComboBox::item:selected { + border: 0px solid transparent; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #455364; +} + +QComboBox::down-arrow { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +/* QSlider ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider + +--------------------------------------------------------------------------- */ +QSlider:disabled { + background: #19232D; +} + +QSlider:focus { + border: none; +} + +QSlider::groove:horizontal { + background: #455364; + border: 1px solid #455364; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::groove:vertical { + background: #455364; + border: 1px solid #455364; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical { + background: #346792; + border: 1px solid #455364; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical :disabled { + background: #26486B; +} + +QSlider::sub-page:horizontal { + background: #346792; + border: 1px solid #455364; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { + background: #26486B; +} + +QSlider::handle:horizontal { + background: #9DA9B5; + border: 1px solid #455364; + width: 8px; + height: 8px; + margin: -8px 0px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: #346792; + border: 1px solid #346792; +} + +QSlider::handle:horizontal:focus { + border: 1px solid #1A72BB; +} + +QSlider::handle:vertical { + background: #9DA9B5; + border: 1px solid #455364; + width: 8px; + height: 8px; + margin: 0 -8px; + border-radius: 4px; +} + +QSlider::handle:vertical:hover { + background: #346792; + border: 1px solid #346792; +} + +QSlider::handle:vertical:focus { + border: 1px solid #1A72BB; +} + +/* QLineEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit + +--------------------------------------------------------------------------- */ +QLineEdit { + background-color: #19232D; + padding-top: 2px; + /* This QLineEdit fix 103, 111 */ + padding-bottom: 2px; + /* This QLineEdit fix 103, 111 */ + padding-left: 4px; + padding-right: 4px; + border-style: solid; + border: 1px solid #455364; + border-radius: 4px; + color: #E0E1E3; +} + +QLineEdit:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QLineEdit:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QLineEdit:focus { + border: 1px solid #1A72BB; +} + +QLineEdit:selected { + background-color: #346792; + color: #455364; +} + +/* QTabWiget -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabWidget { + padding: 2px; + selection-background-color: #455364; +} + +QTabWidget QWidget { + /* Fixes #189 */ + border-radius: 4px; +} + +QTabWidget::pane { + border: 1px solid #455364; + border-radius: 4px; + margin: 0px; + /* Fixes double border inside pane with pyqt5 */ + padding: 0px; +} + +QTabWidget::pane:selected { + background-color: #455364; + border: 1px solid #346792; +} + +/* QTabBar ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabBar, QDockWidget QTabBar { + qproperty-drawBase: 0; + border-radius: 4px; + margin: 0px; + padding: 2px; + border: 0; + /* left: 5px; move to the right by 5px - removed for fix */ +} + +QTabBar::close-button, QDockWidget QTabBar::close-button { + border: 0; + margin: 0; + padding: 4px; + image: url(":/standard_dark/rc/window_close.png"); +} + +QTabBar::close-button:hover, QDockWidget QTabBar::close-button:hover { + image: url(":/standard_dark/rc/window_close_focus.png"); +} + +QTabBar::close-button:pressed, QDockWidget QTabBar::close-button:pressed { + image: url(":/standard_dark/rc/window_close_pressed.png"); +} + +QTabBar::tab, QDockWidget QTabBar::tab { + /* !selected and disabled ----------------------------------------- */ + /* selected ------------------------------------------------------- */ +} + +QTabBar::tab:top:selected:disabled, QDockWidget QTabBar::tab:top:selected:disabled { + border-bottom: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:bottom:selected:disabled, QDockWidget QTabBar::tab:bottom:selected:disabled { + border-top: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:left:selected:disabled, QDockWidget QTabBar::tab:left:selected:disabled { + border-right: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:right:selected:disabled, QDockWidget QTabBar::tab:right:selected:disabled { + border-left: 3px solid #26486B; + color: #9DA9B5; + background-color: #455364; +} + +QTabBar::tab:top:!selected:disabled, QDockWidget QTabBar::tab:top:!selected:disabled { + border-bottom: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:bottom:!selected:disabled, QDockWidget QTabBar::tab:bottom:!selected:disabled { + border-top: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:left:!selected:disabled, QDockWidget QTabBar::tab:left:!selected:disabled { + border-right: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:right:!selected:disabled, QDockWidget QTabBar::tab:right:!selected:disabled { + border-left: 3px solid #19232D; + color: #9DA9B5; + background-color: #19232D; +} + +QTabBar::tab:top:!selected, QDockWidget QTabBar::tab:top:!selected { + border-bottom: 2px solid #19232D; + margin-top: 2px; +} + +QTabBar::tab:bottom:!selected, QDockWidget QTabBar::tab:bottom:!selected { + border-top: 2px solid #19232D; + margin-bottom: 2px; +} + +QTabBar::tab:left:!selected, QDockWidget QTabBar::tab:left:!selected { + border-left: 2px solid #19232D; + margin-right: 2px; +} + +QTabBar::tab:right:!selected, QDockWidget QTabBar::tab:right:!selected { + border-right: 2px solid #19232D; + margin-left: 2px; +} + +QTabBar::tab:top, QDockWidget QTabBar::tab:top { + background-color: #455364; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + min-width: 5px; + border-bottom: 3px solid #455364; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:selected, QDockWidget QTabBar::tab:top:selected { + background-color: #54687A; + border-bottom: 3px solid #259AE9; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:!selected:hover, QDockWidget QTabBar::tab:top:!selected:hover { + border: 1px solid #1A72BB; + border-bottom: 3px solid #1A72BB; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:bottom, QDockWidget QTabBar::tab:bottom { + border-top: 3px solid #455364; + background-color: #455364; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + min-width: 5px; +} + +QTabBar::tab:bottom:selected, QDockWidget QTabBar::tab:bottom:selected { + background-color: #54687A; + border-top: 3px solid #259AE9; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabBar::tab:bottom:!selected:hover, QDockWidget QTabBar::tab:bottom:!selected:hover { + border: 1px solid #1A72BB; + border-top: 3px solid #1A72BB; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:left, QDockWidget QTabBar::tab:left { + background-color: #455364; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:left:selected, QDockWidget QTabBar::tab:left:selected { + background-color: #54687A; + border-right: 3px solid #259AE9; +} + +QTabBar::tab:left:!selected:hover, QDockWidget QTabBar::tab:left:!selected:hover { + border: 1px solid #1A72BB; + border-right: 3px solid #1A72BB; + /* Fixes different behavior #271 */ + margin-right: 0px; + padding-right: -1px; +} + +QTabBar::tab:right, QDockWidget QTabBar::tab:right { + background-color: #455364; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:right:selected, QDockWidget QTabBar::tab:right:selected { + background-color: #54687A; + border-left: 3px solid #259AE9; +} + +QTabBar::tab:right:!selected:hover, QDockWidget QTabBar::tab:right:!selected:hover { + border: 1px solid #1A72BB; + border-left: 3px solid #1A72BB; + /* Fixes different behavior #271 */ + margin-left: 0px; + padding-left: 0px; +} + +QTabBar QToolButton, QDockWidget QTabBar QToolButton { + /* Fixes #136 */ + background-color: #455364; + height: 12px; + width: 12px; +} + +QTabBar QToolButton:pressed, QDockWidget QTabBar QToolButton:pressed { + background-color: #455364; +} + +QTabBar QToolButton:pressed:hover, QDockWidget QTabBar QToolButton:pressed:hover { + border: 1px solid #346792; +} + +QTabBar QToolButton::left-arrow:enabled, QDockWidget QTabBar QToolButton::left-arrow:enabled { + image: url(":/standard_dark/rc/arrow_left.png"); +} + +QTabBar QToolButton::left-arrow:disabled, QDockWidget QTabBar QToolButton::left-arrow:disabled { + image: url(":/standard_dark/rc/arrow_left_disabled.png"); +} + +QTabBar QToolButton::right-arrow:enabled, QDockWidget QTabBar QToolButton::right-arrow:enabled { + image: url(":/standard_dark/rc/arrow_right.png"); +} + +QTabBar QToolButton::right-arrow:disabled, QDockWidget QTabBar QToolButton::right-arrow:disabled { + image: url(":/standard_dark/rc/arrow_right_disabled.png"); +} + +/* QDockWiget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QDockWidget { + outline: 1px solid #455364; + background-color: #19232D; + border: 1px solid #455364; + border-radius: 4px; + titlebar-close-icon: url(":/standard_dark/rc/transparent.png"); + titlebar-normal-icon: url(":/standard_dark/rc/transparent.png"); +} + +QDockWidget::title { + /* Better size for title bar */ + padding: 3px; + spacing: 4px; + border: none; + background-color: #455364; +} + +QDockWidget::close-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_dark/rc/window_close.png"); +} + +QDockWidget::close-button:hover { + image: url(":/standard_dark/rc/window_close_focus.png"); +} + +QDockWidget::close-button:pressed { + image: url(":/standard_dark/rc/window_close_pressed.png"); +} + +QDockWidget::float-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_dark/rc/window_undock.png"); +} + +QDockWidget::float-button:hover { + image: url(":/standard_dark/rc/window_undock_focus.png"); +} + +QDockWidget::float-button:pressed { + image: url(":/standard_dark/rc/window_undock_pressed.png"); +} + +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/standard_dark/rc/transparent.png"); +} + +QTreeView:branch:has-siblings:!adjoins-item { + border-image: url(":/standard_dark/rc/branch_line.png") 0; +} + +QTreeView:branch:has-siblings:adjoins-item { + border-image: url(":/standard_dark/rc/branch_more.png") 0; +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item { + border-image: url(":/standard_dark/rc/branch_end.png") 0; +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/standard_dark/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/standard_dark/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/standard_dark/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/standard_dark/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked, +QListView::indicator:checked, +QTableView::indicator:checked, +QColumnView::indicator:checked { + image: url(":/standard_dark/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed, +QListView::indicator:checked:hover, +QListView::indicator:checked:focus, +QListView::indicator:checked:pressed, +QTableView::indicator:checked:hover, +QTableView::indicator:checked:focus, +QTableView::indicator:checked:pressed, +QColumnView::indicator:checked:hover, +QColumnView::indicator:checked:focus, +QColumnView::indicator:checked:pressed { + image: url(":/standard_dark/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked, +QListView::indicator:unchecked, +QTableView::indicator:unchecked, +QColumnView::indicator:unchecked { + image: url(":/standard_dark/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed, +QListView::indicator:unchecked:hover, +QListView::indicator:unchecked:focus, +QListView::indicator:unchecked:pressed, +QTableView::indicator:unchecked:hover, +QTableView::indicator:unchecked:focus, +QTableView::indicator:unchecked:pressed, +QColumnView::indicator:unchecked:hover, +QColumnView::indicator:unchecked:focus, +QColumnView::indicator:unchecked:pressed { + image: url(":/standard_dark/rc/checkbox_unchecked_focus.png"); +} + +QTreeView::indicator:indeterminate, +QListView::indicator:indeterminate, +QTableView::indicator:indeterminate, +QColumnView::indicator:indeterminate { + image: url(":/standard_dark/rc/checkbox_indeterminate.png"); +} + +QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed, +QListView::indicator:indeterminate:hover, +QListView::indicator:indeterminate:focus, +QListView::indicator:indeterminate:pressed, +QTableView::indicator:indeterminate:hover, +QTableView::indicator:indeterminate:focus, +QTableView::indicator:indeterminate:pressed, +QColumnView::indicator:indeterminate:hover, +QColumnView::indicator:indeterminate:focus, +QColumnView::indicator:indeterminate:pressed { + image: url(":/standard_dark/rc/checkbox_indeterminate_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + gridline-color: #455364; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #19232D; + color: #9DA9B5; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #346792; + color: #455364; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #1A72BB; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #346792; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #346792; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #E0E1E3; + background-color: #37414F; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #E0E1E3; + background-color: #37414F; +} + +QTableCornerButton::section { + background-color: #19232D; + border: 1px transparent #455364; + border-radius: 0px; +} + +/* QHeaderView ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview + +--------------------------------------------------------------------------- */ +QHeaderView { + background-color: #455364; + border: 0px transparent #455364; + padding: 0; + margin: 0; + border-radius: 0; +} + +QHeaderView:disabled { + background-color: #455364; + border: 1px transparent #455364; +} + +QHeaderView::section { + background-color: #455364; + color: #E0E1E3; + border-radius: 0; + text-align: left; + font-size: 13px; +} + +QHeaderView::section::horizontal { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-left: 1px solid #19232D; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one { + border-left: 1px solid #455364; +} + +QHeaderView::section::horizontal:disabled { + color: #9DA9B5; +} + +QHeaderView::section::vertical { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-top: 1px solid #19232D; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one { + border-top: 1px solid #455364; +} + +QHeaderView::section::vertical:disabled { + color: #9DA9B5; +} + +QHeaderView::down-arrow { + /* Those settings (border/width/height/background-color) solve bug */ + /* transparent arrow background and size */ + background-color: #455364; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QHeaderView::up-arrow { + background-color: #455364; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_dark/rc/arrow_up.png"); +} + +/* QToolBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox + +--------------------------------------------------------------------------- */ +QToolBox { + padding: 0px; + border: 0px; + border: 1px solid #455364; +} + +QToolBox:selected { + padding: 0px; + border: 2px solid #346792; +} + +QToolBox::tab { + background-color: #19232D; + border: 1px solid #455364; + color: #E0E1E3; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QToolBox::tab:disabled { + color: #9DA9B5; +} + +QToolBox::tab:selected { + background-color: #60798B; + border-bottom: 2px solid #346792; +} + +QToolBox::tab:selected:disabled { + background-color: #455364; + border-bottom: 2px solid #26486B; +} + +QToolBox::tab:!selected { + background-color: #455364; + border-bottom: 2px solid #455364; +} + +QToolBox::tab:!selected:disabled { + background-color: #19232D; +} + +QToolBox::tab:hover { + border-color: #1A72BB; + border-bottom: 2px solid #1A72BB; +} + +QToolBox QScrollArea QWidget QWidget { + padding: 0px; + border: 0px; + background-color: #19232D; +} + +/* QFrame ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe +https://doc.qt.io/qt-5/qframe.html#-prop +https://doc.qt.io/qt-5/qframe.html#details +https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color + +--------------------------------------------------------------------------- */ +/* (dot) .QFrame fix #141, #126, #123 */ +.QFrame { + border-radius: 4px; + border: 1px solid #455364; + /* No frame */ + /* HLine */ + /* HLine */ +} + +.QFrame[frameShape="0"] { + border-radius: 4px; + border: 1px transparent #455364; +} + +.QFrame[frameShape="4"] { + max-height: 2px; + border: none; + background-color: #455364; +} + +.QFrame[frameShape="5"] { + max-width: 2px; + border: none; + background-color: #455364; +} + +/* QSplitter -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter + +--------------------------------------------------------------------------- */ +QSplitter { + background-color: #455364; + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QSplitter::handle { + background-color: #455364; + border: 0px solid #19232D; + spacing: 0px; + padding: 1px; + margin: 0px; +} + +QSplitter::handle:hover { + background-color: #9DA9B5; +} + +QSplitter::handle:horizontal { + width: 5px; + image: url(":/standard_dark/rc/line_vertical.png"); +} + +QSplitter::handle:vertical { + height: 5px; + image: url(":/standard_dark/rc/line_horizontal.png"); +} + +/* QDateEdit, QDateTimeEdit ----------------------------------------------- + +--------------------------------------------------------------------------- */ +QDateEdit, QDateTimeEdit { + selection-background-color: #346792; + border-style: solid; + border: 1px solid #455364; + border-radius: 4px; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + min-width: 10px; +} + +QDateEdit:on, QDateTimeEdit:on { + selection-background-color: #346792; +} + +QDateEdit::drop-down, QDateTimeEdit::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #455364; +} + +QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(":/standard_dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus { + image: url(":/standard_dark/rc/arrow_down.png"); +} + +QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView { + background-color: #19232D; + border-radius: 4px; + border: 1px solid #455364; + selection-background-color: #346792; +} + +/* QAbstractView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractView:hover { + border: 1px solid #346792; + color: #E0E1E3; +} + +QAbstractView:selected { + background: #346792; + color: #455364; +} + +/* PlotWidget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +PlotWidget { + /* Fix cut labels in plots #134 */ + padding: 0px; +} + +/**********************************/ +/* RetroShare specific part */ +/**********************************/ + +/**** Fix QPushButton ****/ + +QPushButton, +QPushButton:disabled, +QPushButton:checked { + padding-left: 6px; + padding-right: 6px; +} + +/**** Fix QTreeView Items ****/ + +QTreeView::item, +QListView::item, +QTableView::item, +QColumnView::item { + color: #F0F0F0; + background: transparent; +} +QTreeView:branch:!selected:hover, +QTreeView:branch:selected:!active { + color: #E0E1E3; + background-color: #37414F; +} + +/**** Fix QSplitter ****/ + +QSplitter { + background-color: rgba(0,0,0,0); +} +QSplitter::handle { + background-color: rgba(0,0,0,0); + border: 0px; + border-radius: 2px; + padding: 0px; +} + + +/**** Standard rules ****/ + +QFrame[objectName^="feedFrame"],/* Frame used in Feeds*/ +QFrame[objectName^="plainFrame"],/* Frame used in Widget with plain background*/ +QFrame[objectName^="plainBFrame"] {/* Frame used in Widget with plain bordered background*/ + background-color: #19232D; +} +QFrame[objectName^="plainBFrame"] { + border: 1px solid #32414B; +} + +/* Frame used in old Feeds*/ +QFrame#feedFrame[new=false] { + background-color: #19232D; +} +/* Frame used in new Feeds*/ +QFrame#feedFrame[new=true] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #19232D, stop:0.8 #1251A0, stop: 0.81 #1251A0, stop: 1 #19232D); +} +QFrame#feedFrame QLabel { + background: transparent; +} + +QFrame[objectName^="gradFrame"],/* Frame used in Widget with gradient colored background*/ +QFrame#bottomFrame,/* Frame used at the bottom of dialog*/ +QFrame#toasterFrame,/* Frame used in Toasters*/ +QFrame#toolBarFrame {/* Frame used for buttons*/ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #19232D, stop:1 #32414B); + border: 1px solid #455364; +} +QFrame#toolBarFrame > LineEditClear { + background-color: #29333D; +} +QFrame[objectName^="gradFrame"] QComboBox, +QFrame[objectName^="gradFrame"] QLineEdit, +QFrame[objectName^="gradFrame"] QTextEdit { + background-color: #29333D; +} +QFrame[objectName^="gradFrame"] QComboBox QAbstractItemView { + background-color: #555555; + selection-background-color: #1464A0; +} + +QLabel#avatarLabel{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} + + +/* HeaderFrame & TitleBarFrame */ + +QFrame[objectName^="headerFrame"], +QFrame[objectName^="headerBFrame"], +QToolBar#headerToolBar, +QFrame#titleBarFrame { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #455364, stop: 0.5 #54687A,stop: 0.6 #44586A, stop:1 #455364); + border: 0px; +} +QFrame[objectName^="headerBFrame"] { + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover, +QFrame#titleBarFrame > *:!hover { + background: transparent; + color: white; +} +QFrame#titleBarFrame QComboBox, +QFrame#titleBarFrame QLineEdit, +QFrame#titleBarFrame QTextEdit { + background: #29333D; +} + + +/**** Special Page tweak ****/ + + +/* Forums */ + +GxsForumThreadWidget QWidget#threadTreeWidget { + selection-background-color: #005599; + show-decoration-selected: 1; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item { + padding: 2px; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { + background-color: #005599; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 80, 80, 80, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background-color: #166716; + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background-color: #673232; + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background-color: #166716; + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background-color: #673232; + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_card QLabel#pictureLabel, +BoardPostDisplayWidget_compact QLabel#pictureLabel{ + border: 2px solid #444444; + border-radius: 3px; +} + + +/*************** Optional ***************/ + +/**** WikiPoos ****/ +WikiEditDialog QPushButton#pushButton_History { + color: white; + background: #5bb62b; + border-radius: 4px; + max-height: 20px; + min-width: 4em; + padding: 2px; + padding-left: 6px; + padding-right: 6px; +} + +WikiEditDialog QPushButton#pushButton_History:hover { + background: #57af29; +} + + +/**** The Wire ****/ + +WireGroupItem QFrame#wire_frame QLabel{ + background: transparent; +} +WireGroupItem QFrame#wire_frame:hover { + background-color: #2e8bab; +} + +PulseTopLevel QFrame#frame, +PulseViewGroup QFrame#frame, +PulseReply QFrame#frame { + border: 2px solid #38444d; + border-radius: 6px; +} + +PulseAddDialog QTextEdit#textEdit_Pulse { + border: 2px solid #c4cfd6; + border-radius: 6px; + background: white; + color: black; +} + +PulseReply #line_replyLine, +PulseMessage #line{ + color: #c4cfd6; +} + +PulseReply QLabel#label_groupName{ + color: #5b7083; +} + +/**** Color definitions ****/ + +ForumsDialog, GxsForumThreadWidget +{ + qproperty-textColorRead: darkgray; + qproperty-textColorUnread: white; + qproperty-textColorUnreadChildren: red; + qproperty-textColorNotSubscribed: white; + qproperty-textColorMissing: darkred; + qproperty-textColorPinned: #D07000; + + qproperty-backgroundColorPinned: #19232D; + qproperty-backgroundColorFiltered: darkGreen; +} + +GroupTreeWidget +{ + qproperty-textColorCategory: rgb(3, 155, 198); + qproperty-textColorPrivateKey: rgb(249,185,0); +} + +NetworkDialog { + qproperty-backgroundColorSelf: darkred; + qproperty-backgroundColorOwnSign: darkred; + qproperty-backgroundColorAcceptConnection: black; + qproperty-backgroundColorHasSignedMe: darkred; + qproperty-backgroundColorDenied: #201F1F; + qproperty-textColor: white; +} + +NewFriendList { + qproperty-textColorStatusAway: #4040A0; + qproperty-textColorStatusBusy: #A04040; + qproperty-textColorStatusOnline: #40A040; + qproperty-textColorStatusInactive: #A0A040; + qproperty-textColorStatusOffline: gray; + qproperty-textColorGroup: rgb(123, 123, 123); +} + +RSTextBrowser, MimeTextEdit +{ + /*qproperty-textColorQuote: rgb(125, 125, 255);*/ + qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); +} + +/* OpModeStatus need to be at end to overload other values*/ + +OpModeStatus { + qproperty-opMode_Full_Color: #007000; + qproperty-opMode_NoTurtle_Color: #000070; + qproperty-opMode_Gaming_Color: #707000; + qproperty-opMode_Minimal_Color: #700000; +} +OpModeStatus[opMode="Full"] { + color: #F0F0F0; + background: #007000; +} +OpModeStatus[opMode="NoTurtle"] { + color: #F0F0F0; + background: #000070; +} +OpModeStatus[opMode="Gaming"] { + color: #F0F0F0; + background: #707000; +} +OpModeStatus[opMode="Minimal"] { + color: #F0F0F0; + background: #700000; +} + +/*Property Values at end to overwrite other settings*/ + +[new=false] { + background: #19232D; +} +[new=true] { + background: #1251A0; +} + +[valid=true] { + background: rgba(0,255,0,15%); +} + +[valid=false] { + background: rgba(255,0,0,15%); +} + +[WrongValue="true"] { + background-color: #702020; +} + +/**** The Wire ****/ + +QLabel#label_masthead{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss new file mode 100644 index 000000000..061ca0518 --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard_Light.qss @@ -0,0 +1,2708 @@ +/* Standard Light stylesheet for RetroShare + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + + It use a public one for general widgets https://github.com/ColinDuquesnoy/QDarkStyleSheet + /qdarkstyle/light/style.qss + Updated at 2021-11-04 Tag v3.0.2 + Replace all ":/qss_icons/light" by ":/standard_light" + */ + +/* --------------------------------------------------------------------------- + + WARNING! File created programmatically. All changes made in this file will be lost! + + Created by the qtsass compiler v0.3.0 + + The definitions are in the "qdarkstyle.qss._styles.scss" module + +--------------------------------------------------------------------------- */ +/* Dark Style - QDarkStyleSheet ------------------------------------------ */ +/* + +See Qt documentation: + + - https://doc.qt.io/qt-5/stylesheet.html + - https://doc.qt.io/qt-5/stylesheet-reference.html + - https://doc.qt.io/qt-5/stylesheet-examples.html + +--------------------------------------------------------------------------- */ +/* Reset elements ------------------------------------------------------------ + +Resetting everything helps to unify styles across different operating systems + +--------------------------------------------------------------------------- */ +* { + padding: 0px; + margin: 0px; + border: 0px; + border-style: none; + border-image: none; + outline: 0; +} + +/* specific reset for elements inside QToolBar */ +QToolBar * { + margin: 0px; + padding: 0px; +} + +/* QWidget ---------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QWidget { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + padding: 0px; + color: #19232D; + selection-background-color: #9FCBFF; + selection-color: #19232D; +} + +QWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; + selection-background-color: #DAEDFF; + selection-color: #788D9C; +} + +QWidget::item:selected { + background-color: #9FCBFF; +} + +QWidget::item:hover:!selected { + background-color: #73C7FF; +} + +/* QMainWindow ------------------------------------------------------------ + +This adjusts the splitter in the dock widget, not qsplitter +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow + +--------------------------------------------------------------------------- */ +QMainWindow::separator { + background-color: #C9CDD0; + border: 0px solid #FAFAFA; + spacing: 0px; + padding: 2px; +} + +QMainWindow::separator:hover { + background-color: #ACB1B6; + border: 0px solid #73C7FF; +} + +QMainWindow::separator:horizontal { + width: 5px; + margin-top: 2px; + margin-bottom: 2px; + image: url(":/standard_light/rc/toolbar_separator_vertical.png"); +} + +QMainWindow::separator:vertical { + height: 5px; + margin-left: 2px; + margin-right: 2px; + image: url(":/standard_light/rc/toolbar_separator_horizontal.png"); +} + +/* QToolTip --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip + +--------------------------------------------------------------------------- */ +QToolTip { + background-color: #9FCBFF; + color: #19232D; + /* If you remove the border property, background stops working on Windows */ + border: none; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Remove opacity, fix #174 - may need to use RGBA */ +} + +/* QStatusBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar + +--------------------------------------------------------------------------- */ +QStatusBar { + border: 1px solid #C9CDD0; + /* Fixes Spyder #9120, #9121 */ + background: #C9CDD0; + /* Fixes #205, white vertical borders separating items */ +} + +QStatusBar::item { + border: none; +} + +QStatusBar QToolTip { + background-color: #73C7FF; + border: 1px solid #FAFAFA; + color: #FAFAFA; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Reducing transparency to read better */ + opacity: 230; +} + +QStatusBar QLabel { + /* Fixes Spyder #9120, #9121 */ + background: transparent; +} + +/* QCheckBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox + +--------------------------------------------------------------------------- */ +QCheckBox { + background-color: #FAFAFA; + color: #19232D; + spacing: 4px; + outline: none; + padding-top: 4px; + padding-bottom: 4px; +} + +QCheckBox:focus { + border: none; +} + +QCheckBox QWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QCheckBox::indicator { + margin-left: 2px; + height: 14px; + width: 14px; +} + +QCheckBox::indicator:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QCheckBox::indicator:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QCheckBox::indicator:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QCheckBox::indicator:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +QCheckBox::indicator:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QCheckBox::indicator:indeterminate:disabled { + image: url(":/standard_light/rc/checkbox_indeterminate_disabled.png"); +} + +QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +/* QGroupBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox + +--------------------------------------------------------------------------- */ +QGroupBox { + font-weight: bold; + border: 1px solid #C9CDD0; + border-radius: 4px; + padding: 2px; + margin-top: 6px; + margin-bottom: 4px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 4px; + padding-left: 2px; + padding-right: 4px; + padding-top: -4px; +} + +QGroupBox::indicator { + margin-left: 2px; + margin-top: 2px; + padding: 0; + height: 14px; + width: 14px; +} + +QGroupBox::indicator:unchecked { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QGroupBox::indicator:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QGroupBox::indicator:checked { + border: none; + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QGroupBox::indicator:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +/* QRadioButton ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton + +--------------------------------------------------------------------------- */ +QRadioButton { + background-color: #FAFAFA; + color: #19232D; + spacing: 4px; + padding-top: 4px; + padding-bottom: 4px; + border: none; + outline: none; +} + +QRadioButton:focus { + border: none; +} + +QRadioButton:disabled { + background-color: #FAFAFA; + color: #788D9C; + border: none; + outline: none; +} + +QRadioButton QWidget { + background-color: #FAFAFA; + color: #19232D; + spacing: 0px; + padding: 0px; + outline: none; + border: none; +} + +QRadioButton::indicator { + border: none; + outline: none; + margin-left: 2px; + height: 14px; + width: 14px; +} + +QRadioButton::indicator:unchecked { + image: url(":/standard_light/rc/radio_unchecked.png"); +} + +QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_unchecked_focus.png"); +} + +QRadioButton::indicator:unchecked:disabled { + image: url(":/standard_light/rc/radio_unchecked_disabled.png"); +} + +QRadioButton::indicator:checked { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked.png"); +} + +QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked_focus.png"); +} + +QRadioButton::indicator:checked:disabled { + outline: none; + image: url(":/standard_light/rc/radio_checked_disabled.png"); +} + +/* QMenuBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar + +--------------------------------------------------------------------------- */ +QMenuBar { + background-color: #C9CDD0; + padding: 2px; + border: 1px solid #FAFAFA; + color: #19232D; + selection-background-color: #73C7FF; +} + +QMenuBar:focus { + border: 1px solid #9FCBFF; +} + +QMenuBar::item { + background: transparent; + padding: 4px; +} + +QMenuBar::item:selected { + padding: 4px; + background: transparent; + border: 0px solid #C9CDD0; + background-color: #73C7FF; +} + +QMenuBar::item:pressed { + padding: 4px; + border: 0px solid #C9CDD0; + background-color: #73C7FF; + color: #19232D; + margin-bottom: 0px; + padding-bottom: 0px; +} + +/* QMenu ------------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu + +--------------------------------------------------------------------------- */ +QMenu { + border: 0px solid #C9CDD0; + color: #19232D; + margin: 0px; + background-color: #CED1D4; + selection-background-color: #73C7FF; +} + +QMenu::separator { + height: 1px; + background-color: #ACB1B6; + color: #19232D; +} + +QMenu::item { + background-color: #CED1D4; + padding: 4px 24px 4px 28px; + /* Reserve space for selection border */ + border: 1px transparent #C9CDD0; +} + +QMenu::item:selected { + color: #19232D; + background-color: #73C7FF; +} + +QMenu::item:pressed { + background-color: #73C7FF; +} + +QMenu::icon { + padding-left: 10px; + width: 14px; + height: 14px; +} + +QMenu::indicator { + padding-left: 8px; + width: 12px; + height: 12px; + /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ + /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +} + +QMenu::indicator:non-exclusive:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QMenu::indicator:non-exclusive:unchecked:hover, QMenu::indicator:non-exclusive:unchecked:focus, QMenu::indicator:non-exclusive:unchecked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QMenu::indicator:non-exclusive:unchecked:disabled { + image: url(":/standard_light/rc/checkbox_unchecked_disabled.png"); +} + +QMenu::indicator:non-exclusive:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QMenu::indicator:non-exclusive:checked:hover, QMenu::indicator:non-exclusive:checked:focus, QMenu::indicator:non-exclusive:checked:pressed { + border: none; + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/standard_light/rc/checkbox_checked_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:disabled { + image: url(":/standard_light/rc/checkbox_indeterminate_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:focus, QMenu::indicator:non-exclusive:indeterminate:hover, QMenu::indicator:non-exclusive:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +QMenu::indicator:exclusive:unchecked { + image: url(":/standard_light/rc/radio_unchecked.png"); +} + +QMenu::indicator:exclusive:unchecked:hover, QMenu::indicator:exclusive:unchecked:focus, QMenu::indicator:exclusive:unchecked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_unchecked_focus.png"); +} + +QMenu::indicator:exclusive:unchecked:disabled { + image: url(":/standard_light/rc/radio_unchecked_disabled.png"); +} + +QMenu::indicator:exclusive:checked { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked.png"); +} + +QMenu::indicator:exclusive:checked:hover, QMenu::indicator:exclusive:checked:focus, QMenu::indicator:exclusive:checked:pressed { + border: none; + outline: none; + image: url(":/standard_light/rc/radio_checked_focus.png"); +} + +QMenu::indicator:exclusive:checked:disabled { + outline: none; + image: url(":/standard_light/rc/radio_checked_disabled.png"); +} + +QMenu::right-arrow { + margin: 5px; + padding-left: 12px; + image: url(":/standard_light/rc/arrow_right.png"); + height: 12px; + width: 12px; +} + +/* QAbstractItemView ------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QAbstractItemView { + alternate-background-color: #FAFAFA; + color: #19232D; + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QAbstractItemView QLineEdit { + padding: 2px; +} + +/* QAbstractScrollArea ---------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QAbstractScrollArea { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + border-radius: 4px; + /* fix #159 */ + padding: 2px; + /* remove min-height to fix #244 */ + color: #19232D; +} + +QAbstractScrollArea:disabled { + color: #788D9C; +} + +/* QScrollArea ------------------------------------------------------------ + +--------------------------------------------------------------------------- */ +QScrollArea QWidget QWidget:disabled { + background-color: #FAFAFA; +} + +/* QScrollBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar + +--------------------------------------------------------------------------- */ +QScrollBar:horizontal { + height: 16px; + margin: 2px 16px 2px 16px; + border: 1px solid #C9CDD0; + border-radius: 4px; + background-color: #FAFAFA; +} + +QScrollBar:vertical { + background-color: #FAFAFA; + width: 16px; + margin: 16px 2px 16px 2px; + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QScrollBar::handle:horizontal { + background-color: #ACB1B6; + border: 1px solid #C9CDD0; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:hover { + background-color: #9FCBFF; + border: #9FCBFF; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:focus { + border: 1px solid #73C7FF; +} + +QScrollBar::handle:vertical { + background-color: #ACB1B6; + border: 1px solid #C9CDD0; + min-height: 8px; + border-radius: 4px; +} + +QScrollBar::handle:vertical:hover { + background-color: #9FCBFF; + border: #9FCBFF; + border-radius: 4px; + min-height: 8px; +} + +QScrollBar::handle:vertical:focus { + border: 1px solid #73C7FF; +} + +QScrollBar::add-line:horizontal { + margin: 0px 0px 0px 0px; + border-image: url(":/standard_light/rc/arrow_right_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on { + border-image: url(":/standard_light/rc/arrow_right.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on { + border-image: url(":/standard_light/rc/arrow_down.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + margin: 0px 3px 0px 3px; + border-image: url(":/standard_light/rc/arrow_left_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on { + border-image: url(":/standard_light/rc/arrow_left.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/standard_light/rc/arrow_up_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on { + border-image: url(":/standard_light/rc/arrow_up.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal { + background: none; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + background: none; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + +/* QTextEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets + +--------------------------------------------------------------------------- */ +QTextEdit { + background-color: #FAFAFA; + color: #19232D; + border-radius: 4px; + border: 1px solid #C9CDD0; +} + +QTextEdit:focus { + border: 1px solid #73C7FF; +} + +QTextEdit:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* QPlainTextEdit --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QPlainTextEdit { + background-color: #FAFAFA; + color: #19232D; + border-radius: 4px; + border: 1px solid #C9CDD0; +} + +QPlainTextEdit:focus { + border: 1px solid #73C7FF; +} + +QPlainTextEdit:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* QSizeGrip -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip + +--------------------------------------------------------------------------- */ +QSizeGrip { + background: transparent; + width: 12px; + height: 12px; + image: url(":/standard_light/rc/window_grip.png"); +} + +/* QStackedWidget --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QStackedWidget { + padding: 2px; + border: 1px solid #C9CDD0; + border: 1px solid #FAFAFA; +} + +/* QToolBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar + +--------------------------------------------------------------------------- */ +QToolBar { + background-color: #C9CDD0; + border-bottom: 1px solid #FAFAFA; + padding: 1px; + font-weight: bold; + spacing: 2px; +} + +QToolBar:disabled { + /* Fixes #272 */ + background-color: #C9CDD0; +} + +QToolBar::handle:horizontal { + width: 16px; + image: url(":/standard_light/rc/toolbar_move_horizontal.png"); +} + +QToolBar::handle:vertical { + height: 16px; + image: url(":/standard_light/rc/toolbar_move_vertical.png"); +} + +QToolBar::separator:horizontal { + width: 16px; + image: url(":/standard_light/rc/toolbar_separator_horizontal.png"); +} + +QToolBar::separator:vertical { + height: 16px; + image: url(":/standard_light/rc/toolbar_separator_vertical.png"); +} + +QToolButton#qt_toolbar_ext_button { + background: #C9CDD0; + border: 0px; + color: #19232D; + image: url(":/standard_light/rc/arrow_right.png"); +} + +/* QAbstractSpinBox ------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractSpinBox { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; + /* min-width: 5px; removed to fix 109 */ +} + +QAbstractSpinBox:up-button { + background-color: transparent #FAFAFA; + subcontrol-origin: border; + subcontrol-position: top right; + border-left: 1px solid #C9CDD0; + border-bottom: 1px solid #C9CDD0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-bottom: -1px; +} + +QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off { + image: url(":/standard_light/rc/arrow_up_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::up-arrow:hover { + image: url(":/standard_light/rc/arrow_up.png"); +} + +QAbstractSpinBox:down-button { + background-color: transparent #FAFAFA; + subcontrol-origin: border; + subcontrol-position: bottom right; + border-left: 1px solid #C9CDD0; + border-top: 1px solid #C9CDD0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-top: -1px; +} + +QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::down-arrow:hover { + image: url(":/standard_light/rc/arrow_down.png"); +} + +QAbstractSpinBox:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QAbstractSpinBox:focus { + border: 1px solid #73C7FF; +} + +QAbstractSpinBox:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* ------------------------------------------------------------------------ */ +/* DISPLAYS --------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QLabel ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe + +--------------------------------------------------------------------------- */ +QLabel { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + padding: 2px; + margin: 0px; + color: #19232D; +} + +QLabel:disabled { + background-color: #FAFAFA; + border: 0px solid #C9CDD0; + color: #788D9C; +} + +/* QTextBrowser ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QTextBrowser { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; +} + +QTextBrowser:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; +} + +QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed { + border: 1px solid #C9CDD0; +} + +/* QGraphicsView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QGraphicsView { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; +} + +QGraphicsView:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; +} + +QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed { + border: 1px solid #C9CDD0; +} + +/* QCalendarWidget -------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCalendarWidget { + border: 1px solid #C9CDD0; + border-radius: 4px; +} + +QCalendarWidget:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +/* QLCDNumber ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QLCDNumber { + background-color: #FAFAFA; + color: #19232D; +} + +QLCDNumber:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +/* QProgressBar ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar + +--------------------------------------------------------------------------- */ +QProgressBar { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; + text-align: center; +} + +QProgressBar:disabled { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #788D9C; + border-radius: 4px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #9FCBFF; + color: #FAFAFA; + border-radius: 4px; +} + +QProgressBar::chunk:disabled { + background-color: #DAEDFF; + color: #788D9C; + border-radius: 4px; +} + +/* ------------------------------------------------------------------------ */ +/* BUTTONS ---------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QPushButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton + +--------------------------------------------------------------------------- */ +QPushButton { + background-color: #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; +} + +QPushButton:disabled { + background-color: #C9CDD0; + color: #788D9C; + border-radius: 4px; + padding: 2px; +} + +QPushButton:checked { + background-color: #ACB1B6; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:disabled { + background-color: #ACB1B6; + color: #788D9C; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QPushButton:checked:selected { + background: #ACB1B6; +} + +QPushButton:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QPushButton:pressed { + background-color: #ACB1B6; +} + +QPushButton:selected { + background: #ACB1B6; + color: #19232D; +} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + bottom: 4px; +} + +QDialogButtonBox QPushButton { + /* Issue #194 #248 - Special case of QPushButton inside dialogs, for better UI */ + min-width: 80px; +} + +/* QToolButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton + +--------------------------------------------------------------------------- */ +QToolButton { + background-color: #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; + /* The subcontrols below are used only in the DelayedPopup mode */ + /* The subcontrols below are used only in the MenuButtonPopup mode */ + /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +} + +QToolButton:disabled { + background-color: #C9CDD0; + color: #788D9C; + border-radius: 4px; + padding: 2px; +} + +QToolButton:checked { + background-color: #ACB1B6; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:disabled { + background-color: #ACB1B6; + color: #788D9C; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QToolButton:checked:pressed { + background-color: #ACB1B6; +} + +QToolButton:checked:selected { + background: #ACB1B6; + color: #19232D; +} + +QToolButton:hover { + background-color: #B9BDC1; + color: #19232D; +} + +QToolButton:pressed { + background-color: #ACB1B6; +} + +QToolButton:selected { + background: #ACB1B6; + color: #19232D; +} + +QToolButton[popupMode="0"] { + /* Only for DelayedPopup */ + padding-right: 2px; +} + +QToolButton[popupMode="1"] { + /* Only for MenuButtonPopup */ + padding-right: 20px; +} + +QToolButton[popupMode="1"]::menu-button { + border: none; +} + +QToolButton[popupMode="1"]::menu-button:hover { + border: none; + border-left: 1px solid #C9CDD0; + border-radius: 0; +} + +QToolButton[popupMode="2"] { + /* Only for InstantPopup */ + padding-right: 2px; +} + +QToolButton::menu-button { + padding: 2px; + border-radius: 4px; + width: 12px; + border: none; + outline: none; +} + +QToolButton::menu-button:hover { + border: 1px solid #9FCBFF; +} + +QToolButton::menu-button:checked:hover { + border: 1px solid #9FCBFF; +} + +QToolButton::menu-indicator { + image: url(":/standard_light/rc/arrow_down.png"); + height: 8px; + width: 8px; + top: 0; + /* Exclude a shift for better image */ + left: -2px; + /* Shift it a bit */ +} + +QToolButton::menu-arrow { + image: url(":/standard_light/rc/arrow_down.png"); + height: 8px; + width: 8px; +} + +QToolButton::menu-arrow:hover { + image: url(":/standard_light/rc/arrow_down_focus.png"); +} + +/* QCommandLinkButton ----------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCommandLinkButton { + background-color: transparent; + border: 1px solid #C9CDD0; + color: #19232D; + border-radius: 4px; + padding: 0px; + margin: 0px; +} + +QCommandLinkButton:disabled { + background-color: transparent; + color: #788D9C; +} + +/* ------------------------------------------------------------------------ */ +/* INPUTS - NO FIELDS ----------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QComboBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QComboBox { + border: 1px solid #C9CDD0; + border-radius: 4px; + selection-background-color: #9FCBFF; + padding-left: 4px; + padding-right: 4px; + /* padding-right = 36; 4 + 16*2 See scrollbar size */ + /* changed to 4px to fix #239 */ + /* Fixes #103, #111 */ + min-height: 1.5em; + /* padding-top: 2px; removed to fix #132 */ + /* padding-bottom: 2px; removed to fix #132 */ + /* min-width: 75px; removed to fix #109 */ + /* Needed to remove indicator - fix #132 */ +} + +QComboBox QAbstractItemView { + border: 1px solid #C9CDD0; + border-radius: 0; + background-color: #FAFAFA; + selection-background-color: #9FCBFF; +} + +QComboBox QAbstractItemView:hover { + background-color: #FAFAFA; + color: #19232D; +} + +QComboBox QAbstractItemView:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +QComboBox QAbstractItemView:alternate { + background: #FAFAFA; +} + +QComboBox:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QComboBox:hover { + border: 1px solid #9FCBFF; +} + +QComboBox:focus { + border: 1px solid #73C7FF; +} + +QComboBox:on { + selection-background-color: #9FCBFF; +} + +QComboBox::indicator { + border: none; + border-radius: 0; + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + /* Needed to remove indicator - fix #132 */ +} + +QComboBox::indicator:alternate { + background: #FAFAFA; +} + +QComboBox::item:alternate { + background: #FAFAFA; +} + +QComboBox::item:checked { + font-weight: bold; +} + +QComboBox::item:selected { + border: 0px solid transparent; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #C9CDD0; +} + +QComboBox::down-arrow { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus { + image: url(":/standard_light/rc/arrow_down.png"); +} + +/* QSlider ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider + +--------------------------------------------------------------------------- */ +QSlider:disabled { + background: #FAFAFA; +} + +QSlider:focus { + border: none; +} + +QSlider::groove:horizontal { + background: #C9CDD0; + border: 1px solid #C9CDD0; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::groove:vertical { + background: #C9CDD0; + border: 1px solid #C9CDD0; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical { + background: #9FCBFF; + border: 1px solid #C9CDD0; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical :disabled { + background: #DAEDFF; +} + +QSlider::sub-page:horizontal { + background: #9FCBFF; + border: 1px solid #C9CDD0; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { + background: #DAEDFF; +} + +QSlider::handle:horizontal { + background: #788D9C; + border: 1px solid #C9CDD0; + width: 8px; + height: 8px; + margin: -8px 0px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: #9FCBFF; + border: 1px solid #9FCBFF; +} + +QSlider::handle:horizontal:focus { + border: 1px solid #73C7FF; +} + +QSlider::handle:vertical { + background: #788D9C; + border: 1px solid #C9CDD0; + width: 8px; + height: 8px; + margin: 0 -8px; + border-radius: 4px; +} + +QSlider::handle:vertical:hover { + background: #9FCBFF; + border: 1px solid #9FCBFF; +} + +QSlider::handle:vertical:focus { + border: 1px solid #73C7FF; +} + +/* QLineEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit + +--------------------------------------------------------------------------- */ +QLineEdit { + background-color: #FAFAFA; + padding-top: 2px; + /* This QLineEdit fix 103, 111 */ + padding-bottom: 2px; + /* This QLineEdit fix 103, 111 */ + padding-left: 4px; + padding-right: 4px; + border-style: solid; + border: 1px solid #C9CDD0; + border-radius: 4px; + color: #19232D; +} + +QLineEdit:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QLineEdit:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QLineEdit:focus { + border: 1px solid #73C7FF; +} + +QLineEdit:selected { + background-color: #9FCBFF; + color: #C9CDD0; +} + +/* QTabWiget -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabWidget { + padding: 2px; + selection-background-color: #C9CDD0; +} + +QTabWidget QWidget { + /* Fixes #189 */ + border-radius: 4px; +} + +QTabWidget::pane { + border: 1px solid #C9CDD0; + border-radius: 4px; + margin: 0px; + /* Fixes double border inside pane with pyqt5 */ + padding: 0px; +} + +QTabWidget::pane:selected { + background-color: #C9CDD0; + border: 1px solid #9FCBFF; +} + +/* QTabBar ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabBar, QDockWidget QTabBar { + qproperty-drawBase: 0; + border-radius: 4px; + margin: 0px; + padding: 2px; + border: 0; + /* left: 5px; move to the right by 5px - removed for fix */ +} + +QTabBar::close-button, QDockWidget QTabBar::close-button { + border: 0; + margin: 0; + padding: 4px; + image: url(":/standard_light/rc/window_close.png"); +} + +QTabBar::close-button:hover, QDockWidget QTabBar::close-button:hover { + image: url(":/standard_light/rc/window_close_focus.png"); +} + +QTabBar::close-button:pressed, QDockWidget QTabBar::close-button:pressed { + image: url(":/standard_light/rc/window_close_pressed.png"); +} + +QTabBar::tab, QDockWidget QTabBar::tab { + /* !selected and disabled ----------------------------------------- */ + /* selected ------------------------------------------------------- */ +} + +QTabBar::tab:top:selected:disabled, QDockWidget QTabBar::tab:top:selected:disabled { + border-bottom: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:bottom:selected:disabled, QDockWidget QTabBar::tab:bottom:selected:disabled { + border-top: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:left:selected:disabled, QDockWidget QTabBar::tab:left:selected:disabled { + border-right: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:right:selected:disabled, QDockWidget QTabBar::tab:right:selected:disabled { + border-left: 3px solid #DAEDFF; + color: #788D9C; + background-color: #C9CDD0; +} + +QTabBar::tab:top:!selected:disabled, QDockWidget QTabBar::tab:top:!selected:disabled { + border-bottom: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:bottom:!selected:disabled, QDockWidget QTabBar::tab:bottom:!selected:disabled { + border-top: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:left:!selected:disabled, QDockWidget QTabBar::tab:left:!selected:disabled { + border-right: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:right:!selected:disabled, QDockWidget QTabBar::tab:right:!selected:disabled { + border-left: 3px solid #FAFAFA; + color: #788D9C; + background-color: #FAFAFA; +} + +QTabBar::tab:top:!selected, QDockWidget QTabBar::tab:top:!selected { + border-bottom: 2px solid #FAFAFA; + margin-top: 2px; +} + +QTabBar::tab:bottom:!selected, QDockWidget QTabBar::tab:bottom:!selected { + border-top: 2px solid #FAFAFA; + margin-bottom: 2px; +} + +QTabBar::tab:left:!selected, QDockWidget QTabBar::tab:left:!selected { + border-left: 2px solid #FAFAFA; + margin-right: 2px; +} + +QTabBar::tab:right:!selected, QDockWidget QTabBar::tab:right:!selected { + border-right: 2px solid #FAFAFA; + margin-left: 2px; +} + +QTabBar::tab:top, QDockWidget QTabBar::tab:top { + background-color: #C9CDD0; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + min-width: 5px; + border-bottom: 3px solid #C9CDD0; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:selected, QDockWidget QTabBar::tab:top:selected { + background-color: #B9BDC1; + border-bottom: 3px solid #37AEFE; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:!selected:hover, QDockWidget QTabBar::tab:top:!selected:hover { + border: 1px solid #73C7FF; + border-bottom: 3px solid #73C7FF; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:bottom, QDockWidget QTabBar::tab:bottom { + border-top: 3px solid #C9CDD0; + background-color: #C9CDD0; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + min-width: 5px; +} + +QTabBar::tab:bottom:selected, QDockWidget QTabBar::tab:bottom:selected { + background-color: #B9BDC1; + border-top: 3px solid #37AEFE; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabBar::tab:bottom:!selected:hover, QDockWidget QTabBar::tab:bottom:!selected:hover { + border: 1px solid #73C7FF; + border-top: 3px solid #73C7FF; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:left, QDockWidget QTabBar::tab:left { + background-color: #C9CDD0; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:left:selected, QDockWidget QTabBar::tab:left:selected { + background-color: #B9BDC1; + border-right: 3px solid #37AEFE; +} + +QTabBar::tab:left:!selected:hover, QDockWidget QTabBar::tab:left:!selected:hover { + border: 1px solid #73C7FF; + border-right: 3px solid #73C7FF; + /* Fixes different behavior #271 */ + margin-right: 0px; + padding-right: -1px; +} + +QTabBar::tab:right, QDockWidget QTabBar::tab:right { + background-color: #C9CDD0; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:right:selected, QDockWidget QTabBar::tab:right:selected { + background-color: #B9BDC1; + border-left: 3px solid #37AEFE; +} + +QTabBar::tab:right:!selected:hover, QDockWidget QTabBar::tab:right:!selected:hover { + border: 1px solid #73C7FF; + border-left: 3px solid #73C7FF; + /* Fixes different behavior #271 */ + margin-left: 0px; + padding-left: 0px; +} + +QTabBar QToolButton, QDockWidget QTabBar QToolButton { + /* Fixes #136 */ + background-color: #C9CDD0; + height: 12px; + width: 12px; +} + +QTabBar QToolButton:pressed, QDockWidget QTabBar QToolButton:pressed { + background-color: #C9CDD0; +} + +QTabBar QToolButton:pressed:hover, QDockWidget QTabBar QToolButton:pressed:hover { + border: 1px solid #9FCBFF; +} + +QTabBar QToolButton::left-arrow:enabled, QDockWidget QTabBar QToolButton::left-arrow:enabled { + image: url(":/standard_light/rc/arrow_left.png"); +} + +QTabBar QToolButton::left-arrow:disabled, QDockWidget QTabBar QToolButton::left-arrow:disabled { + image: url(":/standard_light/rc/arrow_left_disabled.png"); +} + +QTabBar QToolButton::right-arrow:enabled, QDockWidget QTabBar QToolButton::right-arrow:enabled { + image: url(":/standard_light/rc/arrow_right.png"); +} + +QTabBar QToolButton::right-arrow:disabled, QDockWidget QTabBar QToolButton::right-arrow:disabled { + image: url(":/standard_light/rc/arrow_right_disabled.png"); +} + +/* QDockWiget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QDockWidget { + outline: 1px solid #C9CDD0; + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + border-radius: 4px; + titlebar-close-icon: url(":/standard_light/rc/transparent.png"); + titlebar-normal-icon: url(":/standard_light/rc/transparent.png"); +} + +QDockWidget::title { + /* Better size for title bar */ + padding: 3px; + spacing: 4px; + border: none; + background-color: #C9CDD0; +} + +QDockWidget::close-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_light/rc/window_close.png"); +} + +QDockWidget::close-button:hover { + image: url(":/standard_light/rc/window_close_focus.png"); +} + +QDockWidget::close-button:pressed { + image: url(":/standard_light/rc/window_close_pressed.png"); +} + +QDockWidget::float-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/standard_light/rc/window_undock.png"); +} + +QDockWidget::float-button:hover { + image: url(":/standard_light/rc/window_undock_focus.png"); +} + +QDockWidget::float-button:pressed { + image: url(":/standard_light/rc/window_undock_pressed.png"); +} + +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/standard_light/rc/transparent.png"); +} + +QTreeView:branch:has-siblings:!adjoins-item { + border-image: url(":/standard_light/rc/branch_line.png") 0; +} + +QTreeView:branch:has-siblings:adjoins-item { + border-image: url(":/standard_light/rc/branch_more.png") 0; +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item { + border-image: url(":/standard_light/rc/branch_end.png") 0; +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/standard_light/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/standard_light/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked, +QListView::indicator:checked, +QTableView::indicator:checked, +QColumnView::indicator:checked { + image: url(":/standard_light/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed, +QListView::indicator:checked:hover, +QListView::indicator:checked:focus, +QListView::indicator:checked:pressed, +QTableView::indicator:checked:hover, +QTableView::indicator:checked:focus, +QTableView::indicator:checked:pressed, +QColumnView::indicator:checked:hover, +QColumnView::indicator:checked:focus, +QColumnView::indicator:checked:pressed { + image: url(":/standard_light/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked, +QListView::indicator:unchecked, +QTableView::indicator:unchecked, +QColumnView::indicator:unchecked { + image: url(":/standard_light/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed, +QListView::indicator:unchecked:hover, +QListView::indicator:unchecked:focus, +QListView::indicator:unchecked:pressed, +QTableView::indicator:unchecked:hover, +QTableView::indicator:unchecked:focus, +QTableView::indicator:unchecked:pressed, +QColumnView::indicator:unchecked:hover, +QColumnView::indicator:unchecked:focus, +QColumnView::indicator:unchecked:pressed { + image: url(":/standard_light/rc/checkbox_unchecked_focus.png"); +} + +QTreeView::indicator:indeterminate, +QListView::indicator:indeterminate, +QTableView::indicator:indeterminate, +QColumnView::indicator:indeterminate { + image: url(":/standard_light/rc/checkbox_indeterminate.png"); +} + +QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed, +QListView::indicator:indeterminate:hover, +QListView::indicator:indeterminate:focus, +QListView::indicator:indeterminate:pressed, +QTableView::indicator:indeterminate:hover, +QTableView::indicator:indeterminate:focus, +QTableView::indicator:indeterminate:pressed, +QColumnView::indicator:indeterminate:hover, +QColumnView::indicator:indeterminate:focus, +QColumnView::indicator:indeterminate:pressed { + image: url(":/standard_light/rc/checkbox_indeterminate_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + gridline-color: #C9CDD0; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #FAFAFA; + color: #788D9C; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #9FCBFF; + color: #C9CDD0; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #73C7FF; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #9FCBFF; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #9FCBFF; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #19232D; + background-color: #CED1D4; +} + +QTableCornerButton::section { + background-color: #FAFAFA; + border: 1px transparent #C9CDD0; + border-radius: 0px; +} + +/* QHeaderView ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview + +--------------------------------------------------------------------------- */ +QHeaderView { + background-color: #C9CDD0; + border: 0px transparent #C9CDD0; + padding: 0; + margin: 0; + border-radius: 0; +} + +QHeaderView:disabled { + background-color: #C9CDD0; + border: 1px transparent #C9CDD0; +} + +QHeaderView::section { + background-color: #C9CDD0; + color: #19232D; + border-radius: 0; + text-align: left; + font-size: 13px; +} + +QHeaderView::section::horizontal { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-left: 1px solid #FAFAFA; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one { + border-left: 1px solid #C9CDD0; +} + +QHeaderView::section::horizontal:disabled { + color: #788D9C; +} + +QHeaderView::section::vertical { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-top: 1px solid #FAFAFA; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one { + border-top: 1px solid #C9CDD0; +} + +QHeaderView::section::vertical:disabled { + color: #788D9C; +} + +QHeaderView::down-arrow { + /* Those settings (border/width/height/background-color) solve bug */ + /* transparent arrow background and size */ + background-color: #C9CDD0; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_light/rc/arrow_down.png"); +} + +QHeaderView::up-arrow { + background-color: #C9CDD0; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/standard_light/rc/arrow_up.png"); +} + +/* QToolBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox + +--------------------------------------------------------------------------- */ +QToolBox { + padding: 0px; + border: 0px; + border: 1px solid #C9CDD0; +} + +QToolBox:selected { + padding: 0px; + border: 2px solid #9FCBFF; +} + +QToolBox::tab { + background-color: #FAFAFA; + border: 1px solid #C9CDD0; + color: #19232D; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QToolBox::tab:disabled { + color: #788D9C; +} + +QToolBox::tab:selected { + background-color: #ACB1B6; + border-bottom: 2px solid #9FCBFF; +} + +QToolBox::tab:selected:disabled { + background-color: #C9CDD0; + border-bottom: 2px solid #DAEDFF; +} + +QToolBox::tab:!selected { + background-color: #C9CDD0; + border-bottom: 2px solid #C9CDD0; +} + +QToolBox::tab:!selected:disabled { + background-color: #FAFAFA; +} + +QToolBox::tab:hover { + border-color: #73C7FF; + border-bottom: 2px solid #73C7FF; +} + +QToolBox QScrollArea QWidget QWidget { + padding: 0px; + border: 0px; + background-color: #FAFAFA; +} + +/* QFrame ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe +https://doc.qt.io/qt-5/qframe.html#-prop +https://doc.qt.io/qt-5/qframe.html#details +https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color + +--------------------------------------------------------------------------- */ +/* (dot) .QFrame fix #141, #126, #123 */ +.QFrame { + border-radius: 4px; + border: 1px solid #C9CDD0; + /* No frame */ + /* HLine */ + /* HLine */ +} + +.QFrame[frameShape="0"] { + border-radius: 4px; + border: 1px transparent #C9CDD0; +} + +.QFrame[frameShape="4"] { + max-height: 2px; + border: none; + background-color: #C9CDD0; +} + +.QFrame[frameShape="5"] { + max-width: 2px; + border: none; + background-color: #C9CDD0; +} + +/* QSplitter -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter + +--------------------------------------------------------------------------- */ +QSplitter { + background-color: #C9CDD0; + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QSplitter::handle { + background-color: #C9CDD0; + border: 0px solid #FAFAFA; + spacing: 0px; + padding: 1px; + margin: 0px; +} + +QSplitter::handle:hover { + background-color: #788D9C; +} + +QSplitter::handle:horizontal { + width: 5px; + image: url(":/standard_light/rc/line_vertical.png"); +} + +QSplitter::handle:vertical { + height: 5px; + image: url(":/standard_light/rc/line_horizontal.png"); +} + +/* QDateEdit, QDateTimeEdit ----------------------------------------------- + +--------------------------------------------------------------------------- */ +QDateEdit, QDateTimeEdit { + selection-background-color: #9FCBFF; + border-style: solid; + border: 1px solid #C9CDD0; + border-radius: 4px; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + min-width: 10px; +} + +QDateEdit:on, QDateTimeEdit:on { + selection-background-color: #9FCBFF; +} + +QDateEdit::drop-down, QDateTimeEdit::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #C9CDD0; +} + +QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(":/standard_light/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus { + image: url(":/standard_light/rc/arrow_down.png"); +} + +QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView { + background-color: #FAFAFA; + border-radius: 4px; + border: 1px solid #C9CDD0; + selection-background-color: #9FCBFF; +} + +/* QAbstractView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractView:hover { + border: 1px solid #9FCBFF; + color: #19232D; +} + +QAbstractView:selected { + background: #9FCBFF; + color: #C9CDD0; +} + +/* PlotWidget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +PlotWidget { + /* Fix cut labels in plots #134 */ + padding: 0px; +} + +/**********************************/ +/* RetroShare specific part */ +/**********************************/ + +/**** Fix QPushButton ****/ + +QPushButton, +QPushButton:disabled, +QPushButton:checked { + padding-left: 6px; + padding-right: 6px; +} + +/**** Fix QTreeView Items ****/ + +QTreeView::item, +QListView::item, +QTableView::item, +QColumnView::item { + color: #101010; + background: transparent; +} +QTreeView:branch:!selected:hover, +QTreeView:branch:selected:!active { + color: #19232D; + background-color: #CED1D4; +} + +/**** Fix QSplitter ****/ + +QSplitter { + background-color: rgba(0,0,0,0); +} +QSplitter::handle { + background-color: rgba(0,0,0,0); + border: 0px; + border-radius: 2px; + padding: 0px; +} + + +/**** Standard rules ****/ + +QFrame[objectName^="feedFrame"],/* Frame used in Feeds*/ +QFrame[objectName^="plainFrame"],/* Frame used in Widget with plain background*/ +QFrame[objectName^="plainBFrame"] {/* Frame used in Widget with plain bordered background*/ + background-color: white; +} +QFrame[objectName^="plainBFrame"] { + border: 1px solid #CCCCCC; +} + +/* Frame used in old Feeds*/ +QFrame#feedFrame[new=false] { + background-color: #white; +} +/* Frame used in new Feeds*/ +QFrame#feedFrame[new=true] { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:0.8 #E6F2FD, stop: 0.81 #E6F2FD, stop: 1 #D2E7FD); +} +QFrame#feedFrame QLabel { + background: transparent; +} + +QFrame[objectName^="gradFrame"],/* Frame used in Widget with gradient colored background*/ +QFrame#bottomFrame,/* Frame used at the bottom of dialog*/ +QFrame#toasterFrame,/* Frame used in Toasters*/ +QFrame#toolBarFrame {/* Frame used for buttons*/ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FEFEFE, stop:1 #E8E8E8); + border: 1px solid #CCCCCC; +} +QFrame#toolBarFrame > LineEditClear { + background-color: white; +} +QFrame[objectName^="gradFrame"] QComboBox, +QFrame[objectName^="gradFrame"] QLineEdit, +QFrame[objectName^="gradFrame"] QTextEdit { + background-color: white; +} +QFrame[objectName^="gradFrame"] QComboBox QAbstractItemView { + background-color: #CCCCCC; + selection-background-color: #1464A0; +} + +QLabel#avatarLabel{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} + + +/* HeaderFrame */ + +QFrame[objectName^="headerFrame"], +QFrame[objectName^="headerBFrame"], +QToolBar#headerToolBar { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 0px; +} +QFrame[objectName^="headerBFrame"] { + border: 1px; + border-radius: 4px; +} +QFrame[objectName^="headerFrame"] > *:!hover, +QFrame[objectName^="headerBFrame"] > *:!hover { + background: transparent; + color: white; +} + +/* TitleBarFrame */ + +QFrame#titleBarFrame { + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #F0F8FD, stop:1 #E6F2FD); + border: 0px; +} +QFrame#titleBarFrame > *:!hover { + background: transparent; + color: black; +} +QFrame#titleBarFrame QComboBox, +QFrame#titleBarFrame QLineEdit, +QFrame#titleBarFrame QTextEdit { + background: white; +} + +/**** Special Page tweak ****/ + + +/* ConnectFriendWizard */ + +ConnectFriendWizard QPlainTextEdit#friendCertEdit { + border: none; + background: white; + color: black; +} + +ConnectFriendWizard QFrame#friendFrame { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; +} + +ConnectFriendWizard QWizardPage#ConclusionPage > QGroupBox#peerDetailsFrame { + border: 2px solid #039bd5; + border-radius:6px; + background: white; + color: black; + padding: 12 12px; +} + +ConnectFriendWizard QGroupBox::title#peerDetailsFrame +{ + padding: 4 12px; + background: transparent; + padding: 4 12px; + background: #039bd5; + color: white; +} + + +/* GetStartedDialog */ + +GetStartedDialog QTextEdit { + border: 1px solid #B8B6B1; + border-radius: 6px; + background: white; + color: black; +} + + +/* HomePage */ + +HomePage QLabel#userCertLabel { + color: #0099cc; +} + + +/* Chat lobby */ + +ChatLobbyWidget QGroupBox#lobbyinfo_groupBox +{ + color: black; + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, + stop:0 #FEFEFE, stop:1 #E8E8E8); + border-radius: 6px; + border: 1px solid #CCCCCC; + + padding: 14 6px; + +} +ChatLobbyWidget QGroupBox#lobbyinfo_groupBox > QLabel +{ + color: black;/*Needed for white font system*/ +} + +ChatLobbyWidget QGroupBox::title#lobbyinfo_groupBox +{ + padding: 4 12px; + background: #039bd5; + color: white; +} + +ChatLobbyDialog QListWidget#participantsList { + border: 1px solid #B8B6B1; + border-radius: 6px; + background: white; + color: black; +} + +CreateLobbyDialog QFrame#roomFrame { + border: 2px solid #CCCCCC; + border-radius:6px; + background: white; +} + +ChatWidget QTextEdit#chatTextEdit, +ChatWidget QTextBrowser#textBrowser { + border: 1px solid #0099cc; + border-radius: 6px; + background: white; + color: black; +} + + +/* MessagesDialog */ + +MessagesDialog QWidget#messageTreeWidget::item { + padding: 2px; +} + +MessagesDialog QWidget#messageTreeWidget::item:selected { + background-color: #cde8ff; + color: black; +} + +MessagesDialog QWidget#messageTreeWidget::item:hover { + background-color: #e5f3ff; + color: black; +} + + +/* Forums */ + +GxsForumThreadWidget QWidget#threadTreeWidget { + selection-background-color: #cde8ff; + show-decoration-selected: 1; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item { + padding: 2px; +} + +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:active , +GxsForumThreadWidget QWidget#threadTreeWidget::item:selected:!active { + background-color: #cde8ff; +} + +/* GxsCreateCommentDialog */ + +GxsCreateCommentDialog QTextEdit#commentTextEdit { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; + color: black;/*Needed for white font system*/ +} + + +/* GxsCommentDialog */ + +GxsCommentDialog QComboBox#sortBox { + color: #0099cc; +} + + +/* GxsGroupDialog */ + +GxsGroupDialog QLabel#groupLogo{ + border: 2px solid #CCCCCC; + border-radius: 3px; +} + + +/* Settings */ + +PluginItem > QFrame#pluginFrame { + border: 2px solid #A8B8D1; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #FCFDFE, stop: 1 #E2E8EF); + border-radius: 0px +} +PluginItem QLabel#infoLabel { + color: #054A02; +} + + +/* Feeds */ + +AttachFileItem > QFrame#frame { + border: 2px solid black; + background: white; +} + +GxsChannelPostItem QLabel#newLabel{ + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; + color: white; +} +GxsChannelPostItem QFrame#msgFrame { + border: 2px solid #82B9F4; + border-radius: 3px; +} +GxsChannelPostItem QLabel#logoLabel { + border: 2px solid #D3D3D3; + background-color: black; +} + +SubFileItem QProgressBar#progressBar { + border: 1px solid black; + text-align: center; + color: white; + padding: 1px; + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fff, stop: 0.4999 #eee, stop: 0.5 #ddd, stop: 1 #eee); + min-width: 15px; +} +SubFileItem QProgressBar#progressBar::chunk { + background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #78d, stop: 0.4999 #46a, stop: 0.5 #45a, stop: 1 #238); + border-top-left-radius: 7px; + border-bottom-left-radius: 7px; + border: 1px solid black; + min-width: 15px; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 20, 20, 20, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background: #32CD32; + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background: #CD3232; + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background: #32CD32; + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background: #CD3232; + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_compact QLabel#pictureLabel { + border: 2px solid #CCCCCC; + border-radius: 3px; +} + +PostedListWidgetWithModel QComboBox#sortStrategy_CB { + color: #0099cc; +} + +PostedListWidgetWithModel QTextBrowser#infoDescription { + background: transparent; + border: none; +} + +BoardPostDisplayWidget_compact QLabel#fromBoldLabel, +BoardPostDisplayWidget_compact QLabel#fromLabel, +BoardPostDisplayWidget_compact QLabel#dateLabel, +BoardPostDisplayWidget_compact QLabel#siteBoldLabel, +BoardPostDisplayWidget_card QLabel#fromBoldLabel, +BoardPostDisplayWidget_card QLabel#fromLabel, +BoardPostDisplayWidget_card QLabel#dateLabel, +BoardPostDisplayWidget_card QLabel#siteBoldLabel { + color: #787c7e; +} + + +/* MessengerWindow */ + +MessengerWindow QFrame#messengerframetop{ + background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #9BDBF9, stop:1 #1592CD); + border: 0px; +} + + +/*************** Optional ***************/ + +/**** WikiPoos ****/ +WikiEditDialog QPushButton#pushButton_History { + color: white; + background: #5bb62b; + border-radius: 4px; + max-height: 20px; + min-width: 4em; + padding: 2px; + padding-left: 6px; + padding-right: 6px; +} + +WikiEditDialog QPushButton#pushButton_History:hover { + background: #57af29; +} + + +/**** The Wire ****/ + +WireGroupItem QFrame#wire_frame:hover { + background-color: #7ecbfb; +} +WireGroupItem QFrame#wire_frame > QLabel { + background: transparent; +} + +PulseTopLevel QFrame#plainFrame, +PulseViewGroup QFrame#plainFrame, +PulseReply QFrame#plainFrame { + border: 2px solid #c4cfd6; + background: white; +} + +PulseAddDialog QTextEdit#textEdit_Pulse { + border: 2px solid #c4cfd6; + border-radius: 6px; + background: white; + color: black; +} + +PulseReply #line_replyLine, +PulseMessage #line{ + color: #c4cfd6; +} + +PulseReply QLabel#label_groupName{ + color: #5b7083; +} + +QLabel#label_masthead{ + border: 2px solid #CCCCCC; + border-radius: 4px; +} + +/**** PhotoShare ****/ +AlbumItem QFrame#albumFrame { + border: 2px solid #CCCCCC; + border-radius: 10px +} + +PhotoItem QFrame#photoFrame { + border: 2px solid #CCCCCC; + border-radius: 10px +} + +PhotoItem QWidget:hover { + background-color: #7ecbfb; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/default.qss b/retroshare-gui/src/gui/qss/stylesheet/default.qss new file mode 100644 index 000000000..d1730bfef --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/default.qss @@ -0,0 +1,420 @@ +/* Default stylesheet + This file is used as default for all stylesheets and can be overloaded + Don't use font-size or font-weight, they are defined in .ui files. + Icon size are defined in .cpp files. + + For decoration, use px (pixel or dot) + For horizontal size, use em (width of M char) + For vertical size, use ex (height of x char to respect DotPerInch of your system) + See: https://doc.qt.io/qt-5/stylesheet-reference.html#length + https://doc.qt.io/qt-5/stylesheet-syntax.html + */ + +/**** Standard rules ****/ + +/* Transparent background objects = name starting by trans_*/ +QObject[objectName^="trans_"] { + background: transparent; +} +/* Specific for scrollarea contents */ +QScrollArea[objectName^="trans_"] > QWidget > QWidget { + background: transparent; +} + +/* Informatives background objects = name starting by info*/ +QObject[objectName^="info_"]:enabled {/*enabled is needed for not be overrided :https://doc.qt.io/qt-5/stylesheet-syntax.html#conflict-resolution*/ + color: black; + border: 1px solid #DCDC41; + border-radius: 6px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); +} +/* For label inside informative frame */ +QFrame[objectName^="info_"] > QLabel +{ + color: black; + background: transparent; +} + +/* Specifics Buttons */ +QPushButton#applyButton:enabled,/*enabled is needed for not be overrided :https://doc.qt.io/qt-5/stylesheet-syntax.html#conflict-resolution*/ +QPushButton#createButton:enabled, +QPushButton#postButton:enabled, +QToolButton#addButton:enabled, +QToolButton#followButton:enabled { + color: white; + background: #0099cc; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ + min-width: 4em; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#applyButton:disabled, +QPushButton#createButton:disabled, +QPushButton#postButton:disabled, +QToolButton#addButton:disabled, +QToolButton#followButton:disabled { + color: white; + background: #d40000; + border-radius: 4px; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#applyButton:hover, +QPushButton#createButton:hover, +QPushButton#postButton:hover, +QToolButton#addButton:hover, +QToolButton#followButton:hover { + color: white; + background: #03b1f3; + border-radius: 4px; + padding-left: 6px; + padding-right: 6px; +} + +QPushButton#searchButton:enabled, +QPushButton#addButton:enabled { + color: white; + background: #32CD32; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ + min-width: 4em; + padding: 4px; +} + +QPushButton#searchButton:hover, +QPushButton#addButton:hover { + color: white; + background: #5AD75A; + border-radius: 4px; + padding: 4px; +} + +QToolButton#subscribeToolButton:enabled { + color: white; + background: #0099cc; + border-radius: 4px; + min-height: 4ex; + /*max-height: 4ex; This doesn't work on windows*/ +} + +QToolButton#subscribeToolButton:disabled { + background: gray; + border-radius: 4px; + border: 1px solid gray; + color: lightgray; +} + +QToolButton#subscribeToolButton:hover { + background: #03b1f3; + border-radius: 4px; +} + +QToolButton#subscribeToolButton:pressed { + background: #03b1f3; + border-radius: 4px; + border: 1px solid gray; +} + +QToolButton#subscribeToolButton[popupMode="1"]{ + padding-right: 0px; +} + +QToolButton#subscribeToolButton::menu-arrow{ + image: none; +} + +QToolButton#subscribeToolButton::menu-button{ + image: none; +} + + +QLabel#newLabel:enabled { + border: 1px solid #167BE7; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2291E0, stop: 1 #3EB3FF); + border-radius: 3px; + color: black; +} + + +/* StartDialog + To get the same style for all user and not use last connected one. */ + +StartDialog QFrame#loginframe{ + border-image: url(:/images/logo/background_lessblue.png) 0 0 0 0 stretch stretch; + border-width: 0px; +} +StartDialog QFrame#loginframe QCheckBox, +StartDialog QFrame#loginframe QLabel { + background: transparent; +} +StartDialog QGroupBox#profilGBox { + background: rgba(0,0,0,10%); + border-radius: 3px; + border-width: 0px; +} + +StartDialog QGroupBox#profilGBox * { + background-color: white; + color: black; +} + +StartDialog QPushButton#loadButton { + background: transparent; + border-image: url(:/images/btn_blue.png) 4; + border-width: 4; + color: white; +} +StartDialog QPushButton#loadButton:hover { + background: transparent; + border-image: url(:/images/btn_blue_hover.png) 4; +} + + + +/* GenCertDialog + Change colors here because GUI is not started yet so no user StyleSheet loads */ + +GenCertDialog QFrame#profileframe{ + border-image: url(:/images/logo/background.png) 0 0 0 0 stretch stretch; + border-width: 0px; +} +GenCertDialog QFrame#profileframe QCheckBox, +GenCertDialog QFrame#profileframe QLabel { + background: transparent; +} + +GenCertDialog QLabel#info_Label:enabled { + color: black; + border: 1px solid #DCDC41; + border-radius: 6px; + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFD7, stop:1 #FFFFB2); +} + +GenCertDialog QGroupBox#groupBox, +GenCertDialog QGroupBox#profile_groupBox { + background: rgba(0,0,0,10%); +} +GenCertDialog QGroupBox#profile_groupBox QComboBox, +GenCertDialog QGroupBox#profile_groupBox QSpinBox, +GenCertDialog QGroupBox#profile_groupBox QLineEdit, +GenCertDialog QComboBox#genPGPuser { + border: 2px solid #0099cc; + border-radius: 6px; + background: white; + color: black; +} + +GenCertDialog QPushButton#genButton { + border-image: url(:/images/btn_blue.png) 4; + border-width: 4; + color: white; +} +GenCertDialog QPushButton#genButton:hover { + border-image: url(:/images/btn_blue_hover.png) 4; +} +GenCertDialog QPushButton#genButton:disabled { + border-image: url(:/images/btn_27.png) 4; + color: black; +} + + +/* AvatarWidget */ + +AvatarWidget{border-width: 10px;} +AvatarWidget[frameState="NORMAL"]{border-image:url(:/images/avatarstatus-bg-116.png);} +AvatarWidget[frameState="OFFLINE"]{border-image:url(:/images/avatarstatus-bg-offline-116.png);} +AvatarWidget[frameState="INACTIVE"]{border-image:url(:/images/avatarstatus-bg-idle-116.png);} +AvatarWidget[frameState="ONLINE"]{border-image:url(:/images/avatarstatus-bg-online-116.png);} +AvatarWidget[frameState="AWAY"]{border-image:url(:/images/avatarstatus-bg-away-116.png);} +AvatarWidget[frameState="BUSY"]{border-image:url(:/images/avatarstatus-bg-busy-116.png);} + + +/* ConnectFriendWizard */ + +ConnectFriendWizard { +/* QWizard cannot be resized horizontal when banner pixmap is set + qproperty-bannerPixmap: url(:/images/connect/connectFriendBanner1.png);*/ + qproperty-titleFontSize: 16; + qproperty-titleFontWeight: 500; +/* qproperty-titleColor: white; */ +} + + +/* GxsChannelFilesStatusWidget */ + +GxsChannelFilesStatusWidget QToolButton#openFolderToolButton[popupMode="0"] { + padding-right: 0px; +} + +GxsChannelFilesStatusWidget QToolButton#openFolderToolButton::menu-indicator { + image: none; +} + + +/* Forums */ + +GxsForumThreadWidget QLabel#forumName +{ + color: #0099cc; +} + + +/* Posted */ + +BoardPostDisplayWidget_compact QFrame#voteFrame, +BoardPostDisplayWidget_card QFrame#voteFrame, +PostedItem QFrame#voteFrame { + background: rgba( 20, 20, 20, 20% ); +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton, +BoardPostDisplayWidget_compact QToolButton#voteUpButton { + background: rgba(50,205,50,50%); + border: none; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton, +BoardPostDisplayWidget_compact QToolButton#voteDownButton { + background: rgba(205,50,50,50%); + border: none; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:hover { + background: rgba(50,205,50,75%); + border: 2px solid #808080; + border-radius: 4px; +} +BoardPostDisplayWidget_card QToolButton#voteDownButton:hover, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:hover { + background: rgba(205,50,50,75%); + border: 2px solid #808080; + border-radius: 4px; +} + +BoardPostDisplayWidget_card QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteUpButton:disabled, +BoardPostDisplayWidget_card QToolButton#voteDownButton:disabled, +BoardPostDisplayWidget_compact QToolButton#voteDownButton:disabled { + background: transparent; + border: none; +} + + +/**** Color definitions ****/ + +ForumsDialog, GxsForumThreadWidget +{ + qproperty-textColorRead: darkgray; + qproperty-textColorUnread: black; + qproperty-textColorUnreadChildren: darkgray; + qproperty-textColorNotSubscribed: black; + qproperty-textColorMissing: darkRed; + qproperty-textColorPinned: darkOrange; + + qproperty-backgroundColorPinned: rgb(255, 200, 180); + qproperty-backgroundColorFiltered: rgb(255, 240, 210); +} + +FriendSelectionWidget +{ + qproperty-textColorOnline: blue; +} + +GroupTreeWidget +{ + qproperty-textColorCategory: rgb(79, 79, 79); + qproperty-textColorPrivateKey: rgb(35,91,159); +} + +MessagesDialog +{ + qproperty-textColorInbox: rgb(49, 106, 197); +} + +NetworkDialog +{ + qproperty-backgroundColorSelf: yellow; + qproperty-backgroundColorOwnSign: rgb(69, 255, 69); + qproperty-backgroundColorAcceptConnection: rgb(67, 192, 67); + qproperty-backgroundColorHasSignedMe: rgb(178, 66, 178); + qproperty-backgroundColorDenied: lightGray; + qproperty-textColor: black; +} + +NewFriendList +{ + qproperty-textColorStatusOffline: black; + qproperty-textColorStatusAway: gray; + qproperty-textColorStatusBusy: gray; + qproperty-textColorStatusOnline: darkGreen; + qproperty-textColorStatusInactive: gray; + qproperty-textColorGroup: rgb(123, 123, 123); +} + +SearchDialog +{ + qproperty-textColorLocal: red; + qproperty-textColorDownloading: green; + qproperty-textColorNoSources: rgb(0, 0, 19); + qproperty-textColorLowSources: rgb(0, 0, 38); + qproperty-textColorHighSources: rgb(0, 0, 228); +} + +RSTextBrowser, MimeTextEdit +{ + /*qproperty-textColorQuote: rgb(120, 153, 34);*/ + qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); +} + +/* OpModeStatus need to be at end to overload other values*/ + +OpModeStatus { + qproperty-opMode_Full_Color: #CCFFCC; + qproperty-opMode_NoTurtle_Color: #CCCCFF; + qproperty-opMode_Gaming_Color: #FFFFCC; + qproperty-opMode_Minimal_Color: #FFCCCC; +} +OpModeStatus[opMode="Full"] { + color: black; + background: #CCFFCC; +} +OpModeStatus[opMode="NoTurtle"] { + color: black; + background: #CCCCFF; +} +OpModeStatus[opMode="Gaming"] { + color: black; + background: #FFFFCC; +} +OpModeStatus[opMode="Minimal"] { + color: black; + background: #FFCCCC; +} + +/*Property Values at end to overwrite other settings*/ + +[new=false] { + /*background: rgba(248,248,248,75%);*/ +} +[new=true] { + background: rgba(220,236,253,75%); +} + +[valid=true] { + background: rgba(0,255,0,15%); +} + +[valid=false] { + background: rgba(255,0,0,15%); +} + +[WrongValue="true"] { + background-color: #FF8080; +} diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc new file mode 100644 index 000000000..be5703005 --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/Standard_Dark.qrc @@ -0,0 +1,214 @@ + + + rc/.keep + rc/arrow_down.png + rc/arrow_down@2x.png + rc/arrow_down_disabled.png + rc/arrow_down_disabled@2x.png + rc/arrow_down_focus.png + rc/arrow_down_focus@2x.png + rc/arrow_down_pressed.png + rc/arrow_down_pressed@2x.png + rc/arrow_left.png + rc/arrow_left@2x.png + rc/arrow_left_disabled.png + rc/arrow_left_disabled@2x.png + rc/arrow_left_focus.png + rc/arrow_left_focus@2x.png + rc/arrow_left_pressed.png + rc/arrow_left_pressed@2x.png + rc/arrow_right.png + rc/arrow_right@2x.png + rc/arrow_right_disabled.png + rc/arrow_right_disabled@2x.png + rc/arrow_right_focus.png + rc/arrow_right_focus@2x.png + rc/arrow_right_pressed.png + rc/arrow_right_pressed@2x.png + rc/arrow_up.png + rc/arrow_up@2x.png + rc/arrow_up_disabled.png + rc/arrow_up_disabled@2x.png + rc/arrow_up_focus.png + rc/arrow_up_focus@2x.png + rc/arrow_up_pressed.png + rc/arrow_up_pressed@2x.png + rc/base_icon.png + rc/base_icon@2x.png + rc/base_icon_disabled.png + rc/base_icon_disabled@2x.png + rc/base_icon_focus.png + rc/base_icon_focus@2x.png + rc/base_icon_pressed.png + rc/base_icon_pressed@2x.png + rc/branch_closed.png + rc/branch_closed@2x.png + rc/branch_closed_disabled.png + rc/branch_closed_disabled@2x.png + rc/branch_closed_focus.png + rc/branch_closed_focus@2x.png + rc/branch_closed_pressed.png + rc/branch_closed_pressed@2x.png + rc/branch_end.png + rc/branch_end@2x.png + rc/branch_end_disabled.png + rc/branch_end_disabled@2x.png + rc/branch_end_focus.png + rc/branch_end_focus@2x.png + rc/branch_end_pressed.png + rc/branch_end_pressed@2x.png + rc/branch_line.png + rc/branch_line@2x.png + rc/branch_line_disabled.png + rc/branch_line_disabled@2x.png + rc/branch_line_focus.png + rc/branch_line_focus@2x.png + rc/branch_line_pressed.png + rc/branch_line_pressed@2x.png + rc/branch_more.png + rc/branch_more@2x.png + rc/branch_more_disabled.png + rc/branch_more_disabled@2x.png + rc/branch_more_focus.png + rc/branch_more_focus@2x.png + rc/branch_more_pressed.png + rc/branch_more_pressed@2x.png + rc/branch_open.png + rc/branch_open@2x.png + rc/branch_open_disabled.png + rc/branch_open_disabled@2x.png + rc/branch_open_focus.png + rc/branch_open_focus@2x.png + rc/branch_open_pressed.png + rc/branch_open_pressed@2x.png + rc/checkbox_checked.png + rc/checkbox_checked@2x.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_disabled@2x.png + rc/checkbox_checked_focus.png + rc/checkbox_checked_focus@2x.png + rc/checkbox_checked_pressed.png + rc/checkbox_checked_pressed@2x.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate@2x.png + rc/checkbox_indeterminate_disabled.png + rc/checkbox_indeterminate_disabled@2x.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_indeterminate_focus@2x.png + rc/checkbox_indeterminate_pressed.png + rc/checkbox_indeterminate_pressed@2x.png + rc/checkbox_unchecked.png + rc/checkbox_unchecked@2x.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_disabled@2x.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked_focus@2x.png + rc/checkbox_unchecked_pressed.png + rc/checkbox_unchecked_pressed@2x.png + rc/line_horizontal.png + rc/line_horizontal@2x.png + rc/line_horizontal_disabled.png + rc/line_horizontal_disabled@2x.png + rc/line_horizontal_focus.png + rc/line_horizontal_focus@2x.png + rc/line_horizontal_pressed.png + rc/line_horizontal_pressed@2x.png + rc/line_vertical.png + rc/line_vertical@2x.png + rc/line_vertical_disabled.png + rc/line_vertical_disabled@2x.png + rc/line_vertical_focus.png + rc/line_vertical_focus@2x.png + rc/line_vertical_pressed.png + rc/line_vertical_pressed@2x.png + rc/radio_checked.png + rc/radio_checked@2x.png + rc/radio_checked_disabled.png + rc/radio_checked_disabled@2x.png + rc/radio_checked_focus.png + rc/radio_checked_focus@2x.png + rc/radio_checked_pressed.png + rc/radio_checked_pressed@2x.png + rc/radio_unchecked.png + rc/radio_unchecked@2x.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_disabled@2x.png + rc/radio_unchecked_focus.png + rc/radio_unchecked_focus@2x.png + rc/radio_unchecked_pressed.png + rc/radio_unchecked_pressed@2x.png + rc/toolbar_move_horizontal.png + rc/toolbar_move_horizontal@2x.png + rc/toolbar_move_horizontal_disabled.png + rc/toolbar_move_horizontal_disabled@2x.png + rc/toolbar_move_horizontal_focus.png + rc/toolbar_move_horizontal_focus@2x.png + rc/toolbar_move_horizontal_pressed.png + rc/toolbar_move_horizontal_pressed@2x.png + rc/toolbar_move_vertical.png + rc/toolbar_move_vertical@2x.png + rc/toolbar_move_vertical_disabled.png + rc/toolbar_move_vertical_disabled@2x.png + rc/toolbar_move_vertical_focus.png + rc/toolbar_move_vertical_focus@2x.png + rc/toolbar_move_vertical_pressed.png + rc/toolbar_move_vertical_pressed@2x.png + rc/toolbar_separator_horizontal.png + rc/toolbar_separator_horizontal@2x.png + rc/toolbar_separator_horizontal_disabled.png + rc/toolbar_separator_horizontal_disabled@2x.png + rc/toolbar_separator_horizontal_focus.png + rc/toolbar_separator_horizontal_focus@2x.png + rc/toolbar_separator_horizontal_pressed.png + rc/toolbar_separator_horizontal_pressed@2x.png + rc/toolbar_separator_vertical.png + rc/toolbar_separator_vertical@2x.png + rc/toolbar_separator_vertical_disabled.png + rc/toolbar_separator_vertical_disabled@2x.png + rc/toolbar_separator_vertical_focus.png + rc/toolbar_separator_vertical_focus@2x.png + rc/toolbar_separator_vertical_pressed.png + rc/toolbar_separator_vertical_pressed@2x.png + rc/transparent.png + rc/transparent@2x.png + rc/transparent_disabled.png + rc/transparent_disabled@2x.png + rc/transparent_focus.png + rc/transparent_focus@2x.png + rc/transparent_pressed.png + rc/transparent_pressed@2x.png + rc/window_close.png + rc/window_close@2x.png + rc/window_close_disabled.png + rc/window_close_disabled@2x.png + rc/window_close_focus.png + rc/window_close_focus@2x.png + rc/window_close_pressed.png + rc/window_close_pressed@2x.png + rc/window_grip.png + rc/window_grip@2x.png + rc/window_grip_disabled.png + rc/window_grip_disabled@2x.png + rc/window_grip_focus.png + rc/window_grip_focus@2x.png + rc/window_grip_pressed.png + rc/window_grip_pressed@2x.png + rc/window_minimize.png + rc/window_minimize@2x.png + rc/window_minimize_disabled.png + rc/window_minimize_disabled@2x.png + rc/window_minimize_focus.png + rc/window_minimize_focus@2x.png + rc/window_minimize_pressed.png + rc/window_minimize_pressed@2x.png + rc/window_undock.png + rc/window_undock@2x.png + rc/window_undock_disabled.png + rc/window_undock_disabled@2x.png + rc/window_undock_focus.png + rc/window_undock_focus@2x.png + rc/window_undock_pressed.png + rc/window_undock_pressed@2x.png + + + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/.keep @@ -0,0 +1 @@ + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png new file mode 100644 index 000000000..5575ab5ce Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png new file mode 100644 index 000000000..4596a5ce8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled.png new file mode 100644 index 000000000..bdf8c1abb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png new file mode 100644 index 000000000..dc1bcb524 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus.png new file mode 100644 index 000000000..94fcdc359 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png new file mode 100644 index 000000000..2b12f74d0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed.png new file mode 100644 index 000000000..4058c58b3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png new file mode 100644 index 000000000..d43b0affa Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_down_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png new file mode 100644 index 000000000..7fbc35065 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png new file mode 100644 index 000000000..dc649ca70 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png new file mode 100644 index 000000000..fa3b282cc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png new file mode 100644 index 000000000..87c928ea3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png new file mode 100644 index 000000000..52a0d9102 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus@2x.png new file mode 100644 index 000000000..0ee702924 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png new file mode 100644 index 000000000..c04ce0943 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png new file mode 100644 index 000000000..02218c80d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_left_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png new file mode 100644 index 000000000..fd31b4f2a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png new file mode 100644 index 000000000..4dbc93120 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png new file mode 100644 index 000000000..bb4cdb036 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled@2x.png new file mode 100644 index 000000000..50f173096 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png new file mode 100644 index 000000000..9dd8f0f0b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png new file mode 100644 index 000000000..1ac9d5c9e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed.png new file mode 100644 index 000000000..8ce10fcbe Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed@2x.png new file mode 100644 index 000000000..86e3b9286 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_right_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up.png new file mode 100644 index 000000000..2ea571e47 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png new file mode 100644 index 000000000..51b1d7234 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled.png new file mode 100644 index 000000000..146b65f16 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled@2x.png new file mode 100644 index 000000000..cacee7f74 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus.png new file mode 100644 index 000000000..ab33162c7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus@2x.png new file mode 100644 index 000000000..0c8ef33f4 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png new file mode 100644 index 000000000..c3368d096 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png new file mode 100644 index 000000000..a63819665 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/arrow_up_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/base_icon_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed.png new file mode 100644 index 000000000..d484c324b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png new file mode 100644 index 000000000..f49651b70 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled.png new file mode 100644 index 000000000..aa622523c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png new file mode 100644 index 000000000..ac318f5b1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png new file mode 100644 index 000000000..0a98eab66 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png new file mode 100644 index 000000000..39fd0d0e2 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png new file mode 100644 index 000000000..049f4bfe5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png new file mode 100644 index 000000000..f58ae2238 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_closed_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png new file mode 100644 index 000000000..210984565 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png new file mode 100644 index 000000000..91f3bd02d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png new file mode 100644 index 000000000..fe819bc14 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png new file mode 100644 index 000000000..580247709 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus.png new file mode 100644 index 000000000..9a978c0cc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus@2x.png new file mode 100644 index 000000000..ece9b825d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed.png new file mode 100644 index 000000000..1d4050997 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed@2x.png new file mode 100644 index 000000000..4822745c4 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_end_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png new file mode 100644 index 000000000..75cc027f8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png new file mode 100644 index 000000000..727370558 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png new file mode 100644 index 000000000..01c6cffa7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png new file mode 100644 index 000000000..57789e942 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png new file mode 100644 index 000000000..599626230 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png new file mode 100644 index 000000000..34e7d603f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png new file mode 100644 index 000000000..6a54b0948 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png new file mode 100644 index 000000000..fb74fd324 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_line_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png new file mode 100644 index 000000000..045f963fa Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more@2x.png new file mode 100644 index 000000000..ccde09316 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png new file mode 100644 index 000000000..8630b91c9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png new file mode 100644 index 000000000..37d2cdbbd Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png new file mode 100644 index 000000000..38067367f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png new file mode 100644 index 000000000..d80ccb8cc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png new file mode 100644 index 000000000..a306eb288 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png new file mode 100644 index 000000000..7044b2822 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_more_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png new file mode 100644 index 000000000..445ec7181 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png new file mode 100644 index 000000000..febb31878 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png new file mode 100644 index 000000000..3b840d767 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png new file mode 100644 index 000000000..d6c5b40ed Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus.png new file mode 100644 index 000000000..fecf8733e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus@2x.png new file mode 100644 index 000000000..296d17553 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png new file mode 100644 index 000000000..8a7cffab5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png new file mode 100644 index 000000000..24e282c85 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/branch_open_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked.png new file mode 100644 index 000000000..aa5f56720 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png new file mode 100644 index 000000000..60b4fb2ae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png new file mode 100644 index 000000000..208f3709e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png new file mode 100644 index 000000000..7c8ad0c58 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png new file mode 100644 index 000000000..a35def37f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png new file mode 100644 index 000000000..925cd3620 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png new file mode 100644 index 000000000..f95dc13eb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png new file mode 100644 index 000000000..641c047ae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate.png new file mode 100644 index 000000000..02de1ad2c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png new file mode 100644 index 000000000..8fabf6ea4 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png new file mode 100644 index 000000000..df99affe0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png new file mode 100644 index 000000000..3102eaa3f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png new file mode 100644 index 000000000..370454348 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png new file mode 100644 index 000000000..8da0a8c98 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png new file mode 100644 index 000000000..b971d7fae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png new file mode 100644 index 000000000..9e37b8433 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png new file mode 100644 index 000000000..80bcf2b66 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png new file mode 100644 index 000000000..df0fa4d5a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png new file mode 100644 index 000000000..ede58c818 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png new file mode 100644 index 000000000..6721b38f5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus.png new file mode 100644 index 000000000..3883d2d5a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png new file mode 100644 index 000000000..35c061c0d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png new file mode 100644 index 000000000..d98639eed Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png new file mode 100644 index 000000000..88a52460d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png new file mode 100644 index 000000000..bc858c8d0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png new file mode 100644 index 000000000..7ea4f9c1c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png new file mode 100644 index 000000000..72e073a78 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png new file mode 100644 index 000000000..09a439df9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png new file mode 100644 index 000000000..c84512bb5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png new file mode 100644 index 000000000..8dd58f609 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png new file mode 100644 index 000000000..7ca2605bd Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png new file mode 100644 index 000000000..bd9661781 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png new file mode 100644 index 000000000..49a910526 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png new file mode 100644 index 000000000..cbb017ee6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png new file mode 100644 index 000000000..965854688 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png new file mode 100644 index 000000000..7836a9465 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png new file mode 100644 index 000000000..512ee7d23 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png new file mode 100644 index 000000000..af503251d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed.png new file mode 100644 index 000000000..b8dd21535 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png new file mode 100644 index 000000000..e1d43a83e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/line_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png new file mode 100644 index 000000000..2a1d26a4f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png new file mode 100644 index 000000000..eb2cbb46c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png new file mode 100644 index 000000000..f78c15360 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled@2x.png new file mode 100644 index 000000000..30168e86b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png new file mode 100644 index 000000000..6d9c9801c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png new file mode 100644 index 000000000..63476a075 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed.png new file mode 100644 index 000000000..421ecb44a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed@2x.png new file mode 100644 index 000000000..9030e1013 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_checked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked.png new file mode 100644 index 000000000..23b06ced3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked@2x.png new file mode 100644 index 000000000..41e790ac7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled.png new file mode 100644 index 000000000..075ca8557 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png new file mode 100644 index 000000000..61cd48ffe Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus.png new file mode 100644 index 000000000..d58758039 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png new file mode 100644 index 000000000..0f12c860b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png new file mode 100644 index 000000000..37c09a6d8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png new file mode 100644 index 000000000..9e424e4b3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png new file mode 100644 index 000000000..9d2f51f06 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png new file mode 100644 index 000000000..c35b46532 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png new file mode 100644 index 000000000..013ac4578 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png new file mode 100644 index 000000000..f713dd4d0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png new file mode 100644 index 000000000..6d0d42588 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png new file mode 100644 index 000000000..0a5ca39b1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png new file mode 100644 index 000000000..e414c0c52 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png new file mode 100644 index 000000000..e8e8af20f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png new file mode 100644 index 000000000..140846d75 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png new file mode 100644 index 000000000..7edf454a3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png new file mode 100644 index 000000000..5cd85dd72 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png new file mode 100644 index 000000000..07d5ae1bf Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png new file mode 100644 index 000000000..9aac0365a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png new file mode 100644 index 000000000..c3b1d1805 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png new file mode 100644 index 000000000..30b3921e2 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png new file mode 100644 index 000000000..bd0120745 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png new file mode 100644 index 000000000..96e2689ff Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png new file mode 100644 index 000000000..5944e44c9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png new file mode 100644 index 000000000..941e14509 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png new file mode 100644 index 000000000..e44a33be6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png new file mode 100644 index 000000000..590b31471 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png new file mode 100644 index 000000000..ca88313f6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png new file mode 100644 index 000000000..38004682a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png new file mode 100644 index 000000000..d4b88c047 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png new file mode 100644 index 000000000..b503c8093 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png new file mode 100644 index 000000000..2725a7fa1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png new file mode 100644 index 000000000..6aa1fbdd7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png new file mode 100644 index 000000000..8e54cfa8e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png new file mode 100644 index 000000000..fcdfc0f21 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png new file mode 100644 index 000000000..51b083965 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png new file mode 100644 index 000000000..9d6f84d51 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png new file mode 100644 index 000000000..3876a8e87 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/transparent_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png new file mode 100644 index 000000000..0115ca3f3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close@2x.png new file mode 100644 index 000000000..41dcd8160 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled.png new file mode 100644 index 000000000..55144fff8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled@2x.png new file mode 100644 index 000000000..766aef7c1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus.png new file mode 100644 index 000000000..61df25f82 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus@2x.png new file mode 100644 index 000000000..2ea50b1a9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed.png new file mode 100644 index 000000000..042311def Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed@2x.png new file mode 100644 index 000000000..b54d9a16d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_close_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip.png new file mode 100644 index 000000000..9ea1c438f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip@2x.png new file mode 100644 index 000000000..b31309e8b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled.png new file mode 100644 index 000000000..b66e23b99 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled@2x.png new file mode 100644 index 000000000..ee3d0ba88 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus.png new file mode 100644 index 000000000..400af158c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus@2x.png new file mode 100644 index 000000000..83c9ec634 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed.png new file mode 100644 index 000000000..f71dd8c9a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed@2x.png new file mode 100644 index 000000000..109878a35 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_grip_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize.png new file mode 100644 index 000000000..07517b943 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize@2x.png new file mode 100644 index 000000000..434bb07cd Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled.png new file mode 100644 index 000000000..a1ee4aeda Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled@2x.png new file mode 100644 index 000000000..8454ad832 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus.png new file mode 100644 index 000000000..3b56123f1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus@2x.png new file mode 100644 index 000000000..a66fb71ec Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed.png new file mode 100644 index 000000000..9b70c0ade Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed@2x.png new file mode 100644 index 000000000..5750a8e7e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_minimize_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock.png new file mode 100644 index 000000000..9be9cdf77 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock@2x.png new file mode 100644 index 000000000..40345ab94 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled.png new file mode 100644 index 000000000..ea92aee04 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled@2x.png new file mode 100644 index 000000000..fb8d5483c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus.png new file mode 100644 index 000000000..5b0338d9b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus@2x.png new file mode 100644 index 000000000..9fea75b09 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed.png new file mode 100644 index 000000000..4bc657b21 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed@2x.png new file mode 100644 index 000000000..2ea0c2c71 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/dark/rc/window_undock_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc new file mode 100644 index 000000000..f6af4ae87 --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/Standard_Light.qrc @@ -0,0 +1,214 @@ + + + rc/.keep + rc/arrow_down.png + rc/arrow_down@2x.png + rc/arrow_down_disabled.png + rc/arrow_down_disabled@2x.png + rc/arrow_down_focus.png + rc/arrow_down_focus@2x.png + rc/arrow_down_pressed.png + rc/arrow_down_pressed@2x.png + rc/arrow_left.png + rc/arrow_left@2x.png + rc/arrow_left_disabled.png + rc/arrow_left_disabled@2x.png + rc/arrow_left_focus.png + rc/arrow_left_focus@2x.png + rc/arrow_left_pressed.png + rc/arrow_left_pressed@2x.png + rc/arrow_right.png + rc/arrow_right@2x.png + rc/arrow_right_disabled.png + rc/arrow_right_disabled@2x.png + rc/arrow_right_focus.png + rc/arrow_right_focus@2x.png + rc/arrow_right_pressed.png + rc/arrow_right_pressed@2x.png + rc/arrow_up.png + rc/arrow_up@2x.png + rc/arrow_up_disabled.png + rc/arrow_up_disabled@2x.png + rc/arrow_up_focus.png + rc/arrow_up_focus@2x.png + rc/arrow_up_pressed.png + rc/arrow_up_pressed@2x.png + rc/base_icon.png + rc/base_icon@2x.png + rc/base_icon_disabled.png + rc/base_icon_disabled@2x.png + rc/base_icon_focus.png + rc/base_icon_focus@2x.png + rc/base_icon_pressed.png + rc/base_icon_pressed@2x.png + rc/branch_closed.png + rc/branch_closed@2x.png + rc/branch_closed_disabled.png + rc/branch_closed_disabled@2x.png + rc/branch_closed_focus.png + rc/branch_closed_focus@2x.png + rc/branch_closed_pressed.png + rc/branch_closed_pressed@2x.png + rc/branch_end.png + rc/branch_end@2x.png + rc/branch_end_disabled.png + rc/branch_end_disabled@2x.png + rc/branch_end_focus.png + rc/branch_end_focus@2x.png + rc/branch_end_pressed.png + rc/branch_end_pressed@2x.png + rc/branch_line.png + rc/branch_line@2x.png + rc/branch_line_disabled.png + rc/branch_line_disabled@2x.png + rc/branch_line_focus.png + rc/branch_line_focus@2x.png + rc/branch_line_pressed.png + rc/branch_line_pressed@2x.png + rc/branch_more.png + rc/branch_more@2x.png + rc/branch_more_disabled.png + rc/branch_more_disabled@2x.png + rc/branch_more_focus.png + rc/branch_more_focus@2x.png + rc/branch_more_pressed.png + rc/branch_more_pressed@2x.png + rc/branch_open.png + rc/branch_open@2x.png + rc/branch_open_disabled.png + rc/branch_open_disabled@2x.png + rc/branch_open_focus.png + rc/branch_open_focus@2x.png + rc/branch_open_pressed.png + rc/branch_open_pressed@2x.png + rc/checkbox_checked.png + rc/checkbox_checked@2x.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_disabled@2x.png + rc/checkbox_checked_focus.png + rc/checkbox_checked_focus@2x.png + rc/checkbox_checked_pressed.png + rc/checkbox_checked_pressed@2x.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate@2x.png + rc/checkbox_indeterminate_disabled.png + rc/checkbox_indeterminate_disabled@2x.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_indeterminate_focus@2x.png + rc/checkbox_indeterminate_pressed.png + rc/checkbox_indeterminate_pressed@2x.png + rc/checkbox_unchecked.png + rc/checkbox_unchecked@2x.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_disabled@2x.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked_focus@2x.png + rc/checkbox_unchecked_pressed.png + rc/checkbox_unchecked_pressed@2x.png + rc/line_horizontal.png + rc/line_horizontal@2x.png + rc/line_horizontal_disabled.png + rc/line_horizontal_disabled@2x.png + rc/line_horizontal_focus.png + rc/line_horizontal_focus@2x.png + rc/line_horizontal_pressed.png + rc/line_horizontal_pressed@2x.png + rc/line_vertical.png + rc/line_vertical@2x.png + rc/line_vertical_disabled.png + rc/line_vertical_disabled@2x.png + rc/line_vertical_focus.png + rc/line_vertical_focus@2x.png + rc/line_vertical_pressed.png + rc/line_vertical_pressed@2x.png + rc/radio_checked.png + rc/radio_checked@2x.png + rc/radio_checked_disabled.png + rc/radio_checked_disabled@2x.png + rc/radio_checked_focus.png + rc/radio_checked_focus@2x.png + rc/radio_checked_pressed.png + rc/radio_checked_pressed@2x.png + rc/radio_unchecked.png + rc/radio_unchecked@2x.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_disabled@2x.png + rc/radio_unchecked_focus.png + rc/radio_unchecked_focus@2x.png + rc/radio_unchecked_pressed.png + rc/radio_unchecked_pressed@2x.png + rc/toolbar_move_horizontal.png + rc/toolbar_move_horizontal@2x.png + rc/toolbar_move_horizontal_disabled.png + rc/toolbar_move_horizontal_disabled@2x.png + rc/toolbar_move_horizontal_focus.png + rc/toolbar_move_horizontal_focus@2x.png + rc/toolbar_move_horizontal_pressed.png + rc/toolbar_move_horizontal_pressed@2x.png + rc/toolbar_move_vertical.png + rc/toolbar_move_vertical@2x.png + rc/toolbar_move_vertical_disabled.png + rc/toolbar_move_vertical_disabled@2x.png + rc/toolbar_move_vertical_focus.png + rc/toolbar_move_vertical_focus@2x.png + rc/toolbar_move_vertical_pressed.png + rc/toolbar_move_vertical_pressed@2x.png + rc/toolbar_separator_horizontal.png + rc/toolbar_separator_horizontal@2x.png + rc/toolbar_separator_horizontal_disabled.png + rc/toolbar_separator_horizontal_disabled@2x.png + rc/toolbar_separator_horizontal_focus.png + rc/toolbar_separator_horizontal_focus@2x.png + rc/toolbar_separator_horizontal_pressed.png + rc/toolbar_separator_horizontal_pressed@2x.png + rc/toolbar_separator_vertical.png + rc/toolbar_separator_vertical@2x.png + rc/toolbar_separator_vertical_disabled.png + rc/toolbar_separator_vertical_disabled@2x.png + rc/toolbar_separator_vertical_focus.png + rc/toolbar_separator_vertical_focus@2x.png + rc/toolbar_separator_vertical_pressed.png + rc/toolbar_separator_vertical_pressed@2x.png + rc/transparent.png + rc/transparent@2x.png + rc/transparent_disabled.png + rc/transparent_disabled@2x.png + rc/transparent_focus.png + rc/transparent_focus@2x.png + rc/transparent_pressed.png + rc/transparent_pressed@2x.png + rc/window_close.png + rc/window_close@2x.png + rc/window_close_disabled.png + rc/window_close_disabled@2x.png + rc/window_close_focus.png + rc/window_close_focus@2x.png + rc/window_close_pressed.png + rc/window_close_pressed@2x.png + rc/window_grip.png + rc/window_grip@2x.png + rc/window_grip_disabled.png + rc/window_grip_disabled@2x.png + rc/window_grip_focus.png + rc/window_grip_focus@2x.png + rc/window_grip_pressed.png + rc/window_grip_pressed@2x.png + rc/window_minimize.png + rc/window_minimize@2x.png + rc/window_minimize_disabled.png + rc/window_minimize_disabled@2x.png + rc/window_minimize_focus.png + rc/window_minimize_focus@2x.png + rc/window_minimize_pressed.png + rc/window_minimize_pressed@2x.png + rc/window_undock.png + rc/window_undock@2x.png + rc/window_undock_disabled.png + rc/window_undock_disabled@2x.png + rc/window_undock_focus.png + rc/window_undock_focus@2x.png + rc/window_undock_pressed.png + rc/window_undock_pressed@2x.png + + + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/.keep b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/.keep new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/.keep @@ -0,0 +1 @@ + diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down.png new file mode 100644 index 000000000..f07aa76f0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down@2x.png new file mode 100644 index 000000000..b16b9df17 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled.png new file mode 100644 index 000000000..d94e55b95 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled@2x.png new file mode 100644 index 000000000..a1bc87416 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus.png new file mode 100644 index 000000000..fcd681205 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus@2x.png new file mode 100644 index 000000000..a0463e5e9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed.png new file mode 100644 index 000000000..bbe79a97e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed@2x.png new file mode 100644 index 000000000..28ae890ae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_down_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left.png new file mode 100644 index 000000000..070870107 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left@2x.png new file mode 100644 index 000000000..c067c7ac1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled.png new file mode 100644 index 000000000..76ae59b10 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled@2x.png new file mode 100644 index 000000000..815f33c07 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus.png new file mode 100644 index 000000000..c0856669a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus@2x.png new file mode 100644 index 000000000..48af7238c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed.png new file mode 100644 index 000000000..f47340e3c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed@2x.png new file mode 100644 index 000000000..51b5b7a07 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_left_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right.png new file mode 100644 index 000000000..45f7857e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right@2x.png new file mode 100644 index 000000000..bafdf16c9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled.png new file mode 100644 index 000000000..82d1dd284 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled@2x.png new file mode 100644 index 000000000..8d95d8323 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus.png new file mode 100644 index 000000000..3b3c1b6f8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus@2x.png new file mode 100644 index 000000000..8a3870bdd Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed.png new file mode 100644 index 000000000..b4176d59d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed@2x.png new file mode 100644 index 000000000..24dfe4e19 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_right_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up.png new file mode 100644 index 000000000..7e185babf Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up@2x.png new file mode 100644 index 000000000..6925245e3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled.png new file mode 100644 index 000000000..54394e210 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled@2x.png new file mode 100644 index 000000000..0f582d323 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus.png new file mode 100644 index 000000000..4bc54733f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus@2x.png new file mode 100644 index 000000000..bdf7f6b2d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed.png new file mode 100644 index 000000000..04bc9e4ec Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed@2x.png new file mode 100644 index 000000000..cd6231f26 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/arrow_up_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed.png new file mode 100644 index 000000000..1aeed5554 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed@2x.png new file mode 100644 index 000000000..f42fc6610 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/base_icon_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed.png new file mode 100644 index 000000000..f41c767e6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed@2x.png new file mode 100644 index 000000000..24bb5fba2 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled.png new file mode 100644 index 000000000..2a6b24dea Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled@2x.png new file mode 100644 index 000000000..91d7d6518 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus.png new file mode 100644 index 000000000..2058d895f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus@2x.png new file mode 100644 index 000000000..18d665af9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed.png new file mode 100644 index 000000000..35f982fab Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed@2x.png new file mode 100644 index 000000000..2008d6256 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_closed_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end.png new file mode 100644 index 000000000..6b0bfe03d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end@2x.png new file mode 100644 index 000000000..9ce5439cb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled.png new file mode 100644 index 000000000..dfa9baa8d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled@2x.png new file mode 100644 index 000000000..8ef19e30d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus.png new file mode 100644 index 000000000..85f17bad7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus@2x.png new file mode 100644 index 000000000..d756b2919 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed.png new file mode 100644 index 000000000..7a868658e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed@2x.png new file mode 100644 index 000000000..561e6ebf6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_end_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line.png new file mode 100644 index 000000000..e55608ddc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line@2x.png new file mode 100644 index 000000000..59967fd60 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled.png new file mode 100644 index 000000000..d758b7b6c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled@2x.png new file mode 100644 index 000000000..a35c3a66d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus.png new file mode 100644 index 000000000..800cc587c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus@2x.png new file mode 100644 index 000000000..7d21d64a9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed.png new file mode 100644 index 000000000..638046579 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed@2x.png new file mode 100644 index 000000000..7ca30cd61 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_line_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more.png new file mode 100644 index 000000000..140129295 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more@2x.png new file mode 100644 index 000000000..5a3b1e98f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled.png new file mode 100644 index 000000000..d801611bb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled@2x.png new file mode 100644 index 000000000..2505e2a7c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus.png new file mode 100644 index 000000000..be5b2cbfa Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus@2x.png new file mode 100644 index 000000000..ca0f99e0e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed.png new file mode 100644 index 000000000..6e744b78e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed@2x.png new file mode 100644 index 000000000..fdaf01f03 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_more_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open.png new file mode 100644 index 000000000..e43b940cb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open@2x.png new file mode 100644 index 000000000..691e38c18 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled.png new file mode 100644 index 000000000..9e445449e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled@2x.png new file mode 100644 index 000000000..246bdbbed Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus.png new file mode 100644 index 000000000..a4b332e3e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus@2x.png new file mode 100644 index 000000000..27c8dcacf Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed.png new file mode 100644 index 000000000..205f9414e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed@2x.png new file mode 100644 index 000000000..d09878a61 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/branch_open_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked.png new file mode 100644 index 000000000..f63f2b38f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked@2x.png new file mode 100644 index 000000000..7617ed7dc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled.png new file mode 100644 index 000000000..2eab1ba0c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled@2x.png new file mode 100644 index 000000000..518d55d5e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus.png new file mode 100644 index 000000000..fccb71edc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus@2x.png new file mode 100644 index 000000000..e12217d0a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed.png new file mode 100644 index 000000000..d93ca9903 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed@2x.png new file mode 100644 index 000000000..7ee1d3514 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_checked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate.png new file mode 100644 index 000000000..8f4d0f161 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate@2x.png new file mode 100644 index 000000000..3d106399b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled.png new file mode 100644 index 000000000..0a093c819 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled@2x.png new file mode 100644 index 000000000..06db251f9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus.png new file mode 100644 index 000000000..33fd572bd Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus@2x.png new file mode 100644 index 000000000..691ddf1da Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed.png new file mode 100644 index 000000000..2aff90928 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed@2x.png new file mode 100644 index 000000000..fb4e03861 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_indeterminate_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked.png new file mode 100644 index 000000000..3c0608784 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked@2x.png new file mode 100644 index 000000000..fa0648786 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled.png new file mode 100644 index 000000000..bba927e50 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled@2x.png new file mode 100644 index 000000000..592d5949a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus.png new file mode 100644 index 000000000..7e460184a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus@2x.png new file mode 100644 index 000000000..3f96917b5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed.png new file mode 100644 index 000000000..5fd771d1a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed@2x.png new file mode 100644 index 000000000..57f25fbae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/checkbox_unchecked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal.png new file mode 100644 index 000000000..22a0b1e2b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal@2x.png new file mode 100644 index 000000000..8bd474944 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled.png new file mode 100644 index 000000000..3dc9c69e0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled@2x.png new file mode 100644 index 000000000..a2d3664af Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus.png new file mode 100644 index 000000000..136faa84c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus@2x.png new file mode 100644 index 000000000..398d22432 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed.png new file mode 100644 index 000000000..e2027b14e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed@2x.png new file mode 100644 index 000000000..24b83299b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical.png new file mode 100644 index 000000000..0a4c5f364 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical@2x.png new file mode 100644 index 000000000..e67ccf52b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled.png new file mode 100644 index 000000000..9700752d9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled@2x.png new file mode 100644 index 000000000..0f57c568f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus.png new file mode 100644 index 000000000..15ef20825 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus@2x.png new file mode 100644 index 000000000..a35e97ed0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed.png new file mode 100644 index 000000000..7399cd38e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed@2x.png new file mode 100644 index 000000000..e018b9af8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/line_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked.png new file mode 100644 index 000000000..878b6c53c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked@2x.png new file mode 100644 index 000000000..ed20cd4cf Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled.png new file mode 100644 index 000000000..1aa26ee00 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled@2x.png new file mode 100644 index 000000000..72b69d59b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus.png new file mode 100644 index 000000000..90a54c6e1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus@2x.png new file mode 100644 index 000000000..81771885f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed.png new file mode 100644 index 000000000..10170e374 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed@2x.png new file mode 100644 index 000000000..378608298 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_checked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked.png new file mode 100644 index 000000000..639a55480 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked@2x.png new file mode 100644 index 000000000..a2f23fd6f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled.png new file mode 100644 index 000000000..6f7424ca7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled@2x.png new file mode 100644 index 000000000..bf9330f24 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus.png new file mode 100644 index 000000000..2316d7872 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus@2x.png new file mode 100644 index 000000000..9695890ba Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed.png new file mode 100644 index 000000000..2f2a7ba21 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed@2x.png new file mode 100644 index 000000000..22a7e7139 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/radio_unchecked_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal.png new file mode 100644 index 000000000..a1109caf8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal@2x.png new file mode 100644 index 000000000..69bb6347d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled.png new file mode 100644 index 000000000..e11055a6a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled@2x.png new file mode 100644 index 000000000..9085b627e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus.png new file mode 100644 index 000000000..3c0be5a0e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus@2x.png new file mode 100644 index 000000000..f01973d05 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed.png new file mode 100644 index 000000000..94c0f5b6d Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed@2x.png new file mode 100644 index 000000000..612ea774f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical.png new file mode 100644 index 000000000..b16c48c40 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical@2x.png new file mode 100644 index 000000000..853962cd6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled.png new file mode 100644 index 000000000..9b3caec07 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled@2x.png new file mode 100644 index 000000000..bdda6796a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus.png new file mode 100644 index 000000000..6a432a4ba Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus@2x.png new file mode 100644 index 000000000..817a8da55 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed.png new file mode 100644 index 000000000..50228af7b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed@2x.png new file mode 100644 index 000000000..1946791ad Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_move_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal.png new file mode 100644 index 000000000..f6661b4b1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal@2x.png new file mode 100644 index 000000000..77cadc217 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled.png new file mode 100644 index 000000000..a65e13e46 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled@2x.png new file mode 100644 index 000000000..77b9abcaf Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus.png new file mode 100644 index 000000000..843633ffa Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus@2x.png new file mode 100644 index 000000000..21d4011fc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed.png new file mode 100644 index 000000000..edf05752f Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed@2x.png new file mode 100644 index 000000000..977ec62a9 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_horizontal_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical.png new file mode 100644 index 000000000..2776d87b5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical@2x.png new file mode 100644 index 000000000..ab9e773a8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled.png new file mode 100644 index 000000000..cb443940b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled@2x.png new file mode 100644 index 000000000..f4e241ab2 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus.png new file mode 100644 index 000000000..4a45d55c0 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus@2x.png new file mode 100644 index 000000000..c58d8d120 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed.png new file mode 100644 index 000000000..408fa169a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed@2x.png new file mode 100644 index 000000000..92feb3652 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/toolbar_separator_vertical_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed.png new file mode 100644 index 000000000..3a95111e5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed@2x.png new file mode 100644 index 000000000..4c4b95225 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/transparent_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close.png new file mode 100644 index 000000000..607170bae Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close@2x.png new file mode 100644 index 000000000..607f894a6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled.png new file mode 100644 index 000000000..449deec63 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled@2x.png new file mode 100644 index 000000000..eda9fb4ce Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus.png new file mode 100644 index 000000000..1cd49c73e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus@2x.png new file mode 100644 index 000000000..a13da2129 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed.png new file mode 100644 index 000000000..c5e2a9143 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed@2x.png new file mode 100644 index 000000000..278288ed1 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_close_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip.png new file mode 100644 index 000000000..c03b1dce3 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip@2x.png new file mode 100644 index 000000000..7074bd6d2 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled.png new file mode 100644 index 000000000..3c479884b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled@2x.png new file mode 100644 index 000000000..eb4a063a7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus.png new file mode 100644 index 000000000..46c77d37a Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus@2x.png new file mode 100644 index 000000000..f487c6adb Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed.png new file mode 100644 index 000000000..a4d075905 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed@2x.png new file mode 100644 index 000000000..54dc3d8a8 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_grip_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize.png new file mode 100644 index 000000000..9e1a7f12c Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize@2x.png new file mode 100644 index 000000000..dcd2570cc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled.png new file mode 100644 index 000000000..9fd0ef169 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled@2x.png new file mode 100644 index 000000000..251cefcce Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus.png new file mode 100644 index 000000000..4d748783b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus@2x.png new file mode 100644 index 000000000..97901fed5 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed.png new file mode 100644 index 000000000..78de6557b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed@2x.png new file mode 100644 index 000000000..6b961459b Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_minimize_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock.png new file mode 100644 index 000000000..4da192f33 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock@2x.png new file mode 100644 index 000000000..5cfe75ccc Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled.png new file mode 100644 index 000000000..b0db9c7a7 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled@2x.png new file mode 100644 index 000000000..9468c9f32 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_disabled@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus.png new file mode 100644 index 000000000..85fb0468e Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus@2x.png new file mode 100644 index 000000000..e13b2f075 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_focus@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed.png new file mode 100644 index 000000000..d368cc9ad Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed@2x.png b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed@2x.png new file mode 100644 index 000000000..b30f0dbb6 Binary files /dev/null and b/retroshare-gui/src/gui/qss/stylesheet/qdarkstyle/light/rc/window_undock_pressed@2x.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/qss.default b/retroshare-gui/src/gui/qss/stylesheet/qss.default deleted file mode 100644 index 7e1ecf8b2..000000000 --- a/retroshare-gui/src/gui/qss/stylesheet/qss.default +++ /dev/null @@ -1,275 +0,0 @@ -/* Default stylesheet - This file is used as default for all stylesheets and can be overloaded */ - -/* AvatarWidget */ - -AvatarWidget{border-width: 10px;} -AvatarWidget[frameState="NORMAL"]{border-image:url(:/images/avatarstatus-bg-116.png);} -AvatarWidget[frameState="OFFLINE"]{border-image:url(:/images/avatarstatus-bg-offline-116.png);} -AvatarWidget[frameState="INACTIVE"]{border-image:url(:/images/avatarstatus-bg-idle-116.png);} -AvatarWidget[frameState="ONLINE"]{border-image:url(:/images/avatarstatus-bg-online-116.png);} -AvatarWidget[frameState="AWAY"]{border-image:url(:/images/avatarstatus-bg-away-116.png);} -AvatarWidget[frameState="BUSY"]{border-image:url(:/images/avatarstatus-bg-busy-116.png);} - -/* Font */ - -QLabel#titleBarLabel -{ - font-weight: bold; - qproperty-fontSizeFactor: 115; -} - -QLabel#toasterLabel -{ - font-weight: bold; -} - -ChatWidget QLabel#titleLabel, ChatWidget QLabel#statusLabel -{ - qproperty-fontSizeFactor: 125; -} - -ChatWidget QFrame#pluginTitleFrame, QFrame#pluginTopFrame -{ - background: transparent; -} - -FriendsDialog QLabel#nicknameLabel -{ - qproperty-fontSizeFactor: 200; -} - -ChatMsgItem QLabel#peerNameLabel -{ - qproperty-fontSizeFactor: 175; -} - -PeerItem QLabel#peerNameLabel -{ - qproperty-fontSizeFactor: 175; -} - -SecurityItem QLabel#peerNameLabel, SecurityItem QLabel#requestLabel -{ - qproperty-fontSizeFactor: 175; -} - -SecurityIpItem QLabel#titleLabel -{ - qproperty-fontSizeFactor: 175; -} - -PostedItem QLabel#titleLabel -{ - qproperty-fontSizeFactor: 120; -} - -PostedItem QLabel#scoreLabel -{ - qproperty-fontSizeFactor: 140; -} - -GxsChannelPostItem QLabel#titleLabel -{ - qproperty-fontSizeFactor: 125; -} - -PluginItem QLabel#subjectLabel -{ - qproperty-fontSizeFactor: 125; -} - -RSettingsWin QLabel#pageName -{ - qproperty-fontSizeFactor: 125; -} - -ConfCertDialog QLabel#servicePermissionsLabel -{ - qproperty-fontSizeFactor: 125; -} - -GxsChannelPostsWidgetWithModel QLabel#channelName_LB -{ - qproperty-fontSizeFactor: 250; -} - -PostedListWidgetWithModel QLabel#namelabel -{ - qproperty-fontSizeFactor: 250; -} - -CreateLobbyDialog QLabel#lobbyInfoLabel -{ - qproperty-fontSizeFactor: 150; -} - -HeaderFrame QLabel#headerLabel -{ - qproperty-fontSizeFactor: 225; -} - -ConnectFrientWizard QLabel#fr_label -{ - qproperty-fontSizeFactor: 125; -} - -ConnectFrientWizard QLabel#requestinfolabel -{ - qproperty-fontSizeFactor: 125; -} - -ShareManager QLabel#labelInstructions -{ - qproperty-fontSizeFactor: 125; -} - -CryptoPage QLabel#publicLabel, CryptoPage QLabel#otherLabel -{ - qproperty-fontSizeFactor: 125; -} - -ProfileWidget QLabel#publicLabel, ProfileWidget QLabel#otherLabel, ProfileWidget QLabel#myLabel -{ - qproperty-fontSizeFactor: 125; -} - -PostedCreatePostDialog QLabel#info_label -{ - qproperty-fontSizeFactor: 125; -} - -/* Color definitions */ - -ForumsDialog, GxsForumThreadWidget -{ - qproperty-textColorRead: darkgray; - qproperty-textColorUnread: black; - qproperty-textColorUnreadChildren: darkgray; - qproperty-textColorNotSubscribed: black; - qproperty-textColorMissing: darkRed; - qproperty-textColorPinned: darkOrange; - - qproperty-backgroundColorPinned: rgb(255, 200, 180); - qproperty-backgroundColorFiltered: rgb(255, 240, 210); -} - -GxsForumThreadWidget StyledElidedLabel#forumName -{ - padding: 2px; - font: bold; - font-size: 15pt; -} - -GroupTreeWidget -{ - qproperty-textColorCategory: rgb(79, 79, 79); - qproperty-textColorPrivateKey: rgb(35,91,159); -} - -FriendSelectionWidget -{ - qproperty-textColorOnline: blue; -} - -MessagesDialog -{ - qproperty-textColorInbox: rgb(49, 106, 197); -} - -NewFriendList -{ - qproperty-textColorStatusOffline: black; - qproperty-textColorStatusAway: gray; - qproperty-textColorStatusBusy: gray; - qproperty-textColorStatusOnline: darkGreen; - qproperty-textColorStatusInactive: gray; - qproperty-textColorGroup: rgb(123, 123, 123); -} - -SearchDialog -{ - qproperty-textColorLocal: red; - qproperty-textColorDownloading: green; - qproperty-textColorNoSources: rgb(0, 0, 19); - qproperty-textColorLowSources: rgb(0, 0, 38); - qproperty-textColorHighSources: rgb(0, 0, 228); -} - -NetworkDialog -{ - qproperty-backgroundColorSelf: yellow; - qproperty-backgroundColorOwnSign: rgb(69, 255, 69); - qproperty-backgroundColorAcceptConnection: rgb(67, 192, 67); - qproperty-backgroundColorHasSignedMe: rgb(178, 66, 178); - qproperty-backgroundColorDenied: lightGray; -} - -RSTextBrowser, MimeTextEdit -{ - /*qproperty-textColorQuote: rgb(120, 153, 34);*/ - qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970); -} - -QLabel#headerTextLabel_Person -{ - qproperty-fontSizeFactor: 225; -} - -QLabel#headerTextLabel_Circles -{ - qproperty-fontSizeFactor: 225; -} - -IdEditDialog QLabel#info_label -{ - qproperty-fontSizeFactor: 125; -} - -GenCertDialog QLabel#header_label -{ - qproperty-fontSizeFactor: 120; -} - -GenCertDialog QLabel#genprofileinfo_label -{ - qproperty-fontSizeFactor: 120; -} - -GenCertDialog QLabel#entropy_label -{ - qproperty-fontSizeFactor: 115; -} - -/* OpModeStatus need to be at end to overload other values*/ -OpModeStatus { - qproperty-opMode_Full_Color: #CCFFCC; - qproperty-opMode_NoTurtle_Color: #CCCCFF; - qproperty-opMode_Gaming_Color: #FFFFCC; - qproperty-opMode_Minimal_Color: #FFCCCC; -} -OpModeStatus[opMode="Full"] { - background: #CCFFCC; -} -OpModeStatus[opMode="NoTurtle"] { - background: #CCCCFF; -} -OpModeStatus[opMode="Gaming"] { - background: #FFFFCC; -} -OpModeStatus[opMode="Minimal"] { - background: #FFCCCC; -} - -/*Property Values at end to overwrite other settings*/ - -[new=false] { - background: #F8F8F8; -} -[new=true] { - background: #DCECFD; -} - -[WrongValue="true"] { - background-color: #FF8080; -} diff --git a/retroshare-gui/src/gui/settings/AppearancePage.cpp b/retroshare-gui/src/gui/settings/AppearancePage.cpp index 407d5c061..8ad086ae9 100755 --- a/retroshare-gui/src/gui/settings/AppearancePage.cpp +++ b/retroshare-gui/src/gui/settings/AppearancePage.cpp @@ -18,20 +18,13 @@ * * *******************************************************************************/ -#include -#include -#include -#include -#include -#include - -#include "lang/languagesupport.h" -#include #include "AppearancePage.h" -#include "rsharesettings.h" -#include "util/misc.h" + +#include "rshare.h" #include "gui/MainWindow.h" #include "gui/notifyqt.h" +#include "gui/common/FilesDefs.h" +#include "gui/settings/rsharesettings.h" #include "gui/statusbar/peerstatus.h" #include "gui/statusbar/natstatus.h" #include "gui/statusbar/dhtstatus.h" @@ -42,7 +35,18 @@ #include "gui/statusbar/SoundStatus.h" #include "gui/statusbar/ToasterDisable.h" #include "gui/statusbar/SysTrayStatus.h" -#include "gui/common/FilesDefs.h" +#include "lang/languagesupport.h" +#include "util/misc.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include /** Constructor */ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) @@ -51,8 +55,6 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - connect(ui.cmboStyleSheet, SIGNAL(activated(int)), this, SLOT(loadStyleSheet(int))); - connect(ui.grpStatus, SIGNAL(toggled(bool)), this /* pMainWindow->statusBar(), */, SLOT(switch_status_grpStatus(bool))); connect(ui.checkBoxStatusCompactMode, SIGNAL(toggled(bool)), this /* pMainWindow, */, SLOT(switch_status_compactMode(bool))); connect(ui.checkBoxDisableSysTrayToolTip, SIGNAL(toggled(bool)), this /* pMainWindow, */, SLOT(switch_status_showToolTip(bool))); @@ -70,14 +72,16 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) /* Populate combo boxes */ foreach (QString code, LanguageSupport::languageCodes()) { - ui.cmboLanguage->addItem(FilesDefs::getIconFromQtResourcePath(":/images/flags/" + code + ".png"), LanguageSupport::languageName(code), code); - } - foreach (QString style, QStyleFactory::keys()) { - ui.cmboStyle->addItem(style, style.toLower()); + ui.cmboLanguage->addItem(FilesDefs::getIconFromQtResourcePath(":/images/flags/" + code + ".png"), LanguageSupport::languageName(code), code); } - // add empty entry representing "no style sheet" - ui.cmboStyleSheet->addItem("", ""); + // Note: apparently, on some linux systems (e.g. Debian 11), the gtk2 style makes Qt libs crash when the environment variable is not set. + // So we first check that it's here before start. + + foreach (QString style, QStyleFactory::keys()) { + if(style.toLower() != "gtk2" || (getenv("QT_QPA_PLATFORMTHEME")!=nullptr && !strcmp(getenv("QT_QPA_PLATFORMTHEME"),"gtk2"))) + ui.cmboStyle->addItem(style, style.toLower()); + } QMap styleSheets; Rshare::getAvailableStyleSheets(styleSheets); @@ -92,7 +96,8 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) connect(ui.cmboLanguage, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLanguageCode() )); connect(ui.cmboStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(updateInterfaceStyle() )); connect(ui.cmboStyleSheet, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSheetName() )); - connect(ui.checkBoxDisableSysTrayToolTip, SIGNAL(toggled(bool)), this, SLOT(updateStatusToolTip() )); + connect(ui.cmboStyleSheet, SIGNAL(activated(int)) , this, SLOT(loadStyleSheet(int) )); + connect(ui.checkBoxDisableSysTrayToolTip, SIGNAL(toggled(bool)) , this, SLOT(updateStatusToolTip() )); connect(ui.mainPageButtonType_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(updateRbtPageOnToolBar() )); // connect(ui.menuItemsButtonType_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(updateActionButtonLoc() )); @@ -128,10 +133,31 @@ void AppearancePage::switch_status(MainWindow::StatusElement s,const QString& ke void AppearancePage::updateLanguageCode() { Settings->setLanguageCode(LanguageSupport::languageCode(ui.cmboLanguage->currentText())); } void AppearancePage::updateInterfaceStyle() { - Rshare::setStyle(ui.cmboStyle->currentText()); - Settings->setInterfaceStyle(ui.cmboStyle->currentText()); +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(Qt::WaitCursor); +#endif + Rshare::setStyle(ui.cmboStyle->currentText()); + Settings->setInterfaceStyle(ui.cmboStyle->currentText()); +#ifndef QT_NO_CURSOR + QApplication::restoreOverrideCursor(); +#endif } -void AppearancePage::updateSheetName() { Settings->setSheetName(ui.cmboStyleSheet->itemData(ui.cmboStyleSheet->currentIndex()).toString()); } +void AppearancePage::updateSheetName() +{ + Settings->setSheetName(ui.cmboStyleSheet->itemData(ui.cmboStyleSheet->currentIndex()).toString()); +} + +void AppearancePage::loadStyleSheet(int index) +{ +#ifndef QT_NO_CURSOR + QApplication::setOverrideCursor(Qt::WaitCursor); +#endif + Rshare::loadStyleSheet(ui.cmboStyleSheet->itemData(index).toString()); +#ifndef QT_NO_CURSOR + QApplication::restoreOverrideCursor(); +#endif +} + void AppearancePage::updateRbtPageOnToolBar() { Settings->setPageButtonLoc(!ui.mainPageButtonType_CB->currentIndex()); @@ -245,9 +271,9 @@ void AppearancePage::load() index = ui.mainPageButtonType_CB->findData(Settings->getPageButtonLoc()); if (index != 0) { - ui.cmboTollButtonsStyle->hide(); - }else { - ui.cmboTollButtonsStyle->show(); + ui.cmboTollButtonsStyle->show(); + }else { + ui.cmboTollButtonsStyle->hide(); } whileBlocking(ui.mainPageButtonType_CB)->setCurrentIndex(!Settings->getPageButtonLoc()); @@ -334,8 +360,3 @@ void AppearancePage::load() whileBlocking(ui.checkBoxShowSystrayOnStatus)->setChecked(Settings->valueFromGroup("StatusBar", "ShowSysTrayOnStatusBar", QVariant(false)).toBool()); } - -void AppearancePage::loadStyleSheet(int index) -{ - Rshare::loadStyleSheet(ui.cmboStyleSheet->itemData(index).toString()); -} diff --git a/retroshare-gui/src/gui/settings/AppearancePage.ui b/retroshare-gui/src/gui/settings/AppearancePage.ui index a06a4933e..96e5effe8 100755 --- a/retroshare-gui/src/gui/settings/AppearancePage.ui +++ b/retroshare-gui/src/gui/settings/AppearancePage.ui @@ -45,7 +45,7 @@ - + 150 @@ -105,7 +105,7 @@ - + 150 @@ -146,7 +146,7 @@ - + 150 @@ -209,7 +209,7 @@ - + Buttons @@ -253,7 +253,7 @@ 0 - + Icon Only @@ -303,7 +303,7 @@ - + Icon Size = 8x8 @@ -466,6 +466,13 @@ + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/settings/ChannelPage.cpp b/retroshare-gui/src/gui/settings/ChannelPage.cpp index ef2fa6307..857cc972e 100644 --- a/retroshare-gui/src/gui/settings/ChannelPage.cpp +++ b/retroshare-gui/src/gui/settings/ChannelPage.cpp @@ -22,6 +22,7 @@ #include "rsharesettings.h" #include "util/misc.h" #include "gui/notifyqt.h" +#include "retroshare/rsgxschannels.h" ChannelPage::ChannelPage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) @@ -35,6 +36,9 @@ ChannelPage::ChannelPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.emoteicon_checkBox,SIGNAL(toggled(bool)),this,SLOT(updateEmotes())) ; + // Connecting the spin box with the maximum auto download size in channels + connect(ui.autoDownloadSpinBox, SIGNAL(valueChanged(int)), this, SLOT(updateMaxAutoDownloadSizeLimit(int))); + } ChannelPage::~ChannelPage() @@ -49,6 +53,13 @@ void ChannelPage::load() Settings->beginGroup(QString("ChannelPostsWidget")); whileBlocking(ui.emoteicon_checkBox)->setChecked(Settings->value("Emoteicons_ChannelDecription", true).toBool()); Settings->endGroup(); + + // Getting the maximum auto download size from the configuration + uint64_t maxAutoDownloadSize; + rsGxsChannels->getMaxAutoDownloadSizeLimit(maxAutoDownloadSize); + int temp=(maxAutoDownloadSize/(Size_Of_1_GB)); + whileBlocking(ui.autoDownloadSpinBox)->setValue(temp); + } void ChannelPage::updateEmotes() @@ -57,3 +68,10 @@ void ChannelPage::updateEmotes() Settings->setValue("Emoteicons_ChannelDecription", ui.emoteicon_checkBox->isChecked()); Settings->endGroup(); } + +// Function to update the maximum size allowed for auto download in channels +void ChannelPage::updateMaxAutoDownloadSizeLimit(int value) +{ + uint64_t temp=(static_cast(value)*Size_Of_1_GB); + rsGxsChannels->setMaxAutoDownloadSizeLimit(temp); +} diff --git a/retroshare-gui/src/gui/settings/ChannelPage.h b/retroshare-gui/src/gui/settings/ChannelPage.h index 93f32cabc..adb573711 100644 --- a/retroshare-gui/src/gui/settings/ChannelPage.h +++ b/retroshare-gui/src/gui/settings/ChannelPage.h @@ -25,6 +25,8 @@ #include "ui_ChannelPage.h" #include "gui/common/FilesDefs.h" +#define Size_Of_1_GB (1024 * 1024 * 1024) // It is the size of 1 GB in bytes. + class ChannelPage : public ConfigPage { Q_OBJECT @@ -43,6 +45,9 @@ public: private slots: void updateEmotes(); + // Function to update the maximum size allowed for auto download in channels + void updateMaxAutoDownloadSizeLimit(int value); + private: Ui::ChannelPage ui; }; diff --git a/retroshare-gui/src/gui/settings/ChannelPage.ui b/retroshare-gui/src/gui/settings/ChannelPage.ui index 5e75e442e..8ea42f71a 100644 --- a/retroshare-gui/src/gui/settings/ChannelPage.ui +++ b/retroshare-gui/src/gui/settings/ChannelPage.ui @@ -6,22 +6,23 @@ 0 0 - 423 + 526 334 - - - - - Tabs + + + + + Qt::Vertical - - - - - - + + + 20 + 5 + + + @@ -39,18 +40,43 @@
    + + + + Tabs + + + + + + + + - - - Qt::Vertical + + + Downloads - - - 20 - 40 - - - + + + + + 1 + + + 200 + + + + + + + Maximum Auto Download Size (in GBs) + + + + +
    diff --git a/retroshare-gui/src/gui/settings/ChatPage.cpp b/retroshare-gui/src/gui/settings/ChatPage.cpp index 357f2698c..1f35fe62c 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.cpp +++ b/retroshare-gui/src/gui/settings/ChatPage.cpp @@ -18,26 +18,27 @@ * * *******************************************************************************/ +#include "ChatPage.h" + +#include "rsharesettings.h" +#include "gui/MainWindow.h" +#include "gui/notifyqt.h" +#include "gui/RetroShareLink.h" +#include "gui/chat/ChatDialog.h" +#include "util/misc.h" + +#include "retroshare/rsconfig.h" +#include "retroshare/rshistory.h" +#include "retroshare/rsmsgs.h" +#include "retroshare/rsnotify.h" +#include "retroshare/rspeers.h" + #include #include #include + #include -#include -#include -#include -#include "ChatPage.h" -#include "gui/MainWindow.h" -#include -#include "gui/chat/ChatDialog.h" -#include "gui/notifyqt.h" -#include "rsharesettings.h" -#include "util/misc.h" -#include - -#include -#include - #define VARIANT_STANDARD "Standard" #define IMAGE_CHAT_CREATE ":/icons/png/add.png" #define IMAGE_CHAT_OPEN ":/icons/png/typing.png" @@ -124,9 +125,6 @@ void ChatPage::updateFontsAndEmotes() /** Saves the changes on this page */ void ChatPage::updateChatParams() { - // state of distant Chat combobox - Settings->setValue("DistantChat", ui.distantChatComboBox->currentIndex()); - Settings->setChatScreenFont(fontTempChat.toString()); NotifyQt::getInstance()->notifyChatFontChanged(); @@ -134,6 +132,7 @@ void ChatPage::updateChatParams() Settings->setChatSendAsPlainTextByDef(ui.sendAsPlainTextByDef->isChecked()); Settings->setChatLoadEmbeddedImages(ui.loadEmbeddedImages->isChecked()); Settings->setChatDoNotSendIsTyping(ui.DontSendTyping->isChecked()); + Settings->setShrinkChatTextEdit(ui.shrinkChatTextEdit->isChecked()); } void ChatPage::updateChatSearchParams() @@ -247,6 +246,7 @@ ChatPage::ChatPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.sendAsPlainTextByDef, SIGNAL(toggled(bool)), this, SLOT(updateChatParams())); connect(ui.loadEmbeddedImages, SIGNAL(toggled(bool)), this, SLOT(updateChatParams())); connect(ui.DontSendTyping, SIGNAL(toggled(bool)), this, SLOT(updateChatParams())); + connect(ui.shrinkChatTextEdit, SIGNAL(toggled(bool)), this, SLOT(updateChatParams())); connect(ui.sbSearch_CharToStart, SIGNAL(valueChanged(int)), this, SLOT(updateChatSearchParams())); connect(ui.cbSearch_CaseSensitively, SIGNAL(toggled(bool)), this, SLOT(updateChatSearchParams())); @@ -295,6 +295,29 @@ ChatPage::ChatPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.privateStyle, SIGNAL(currentIndexChanged(int)), this,SLOT(on_privateList_currentRowChanged(int))); connect(ui.historyStyle, SIGNAL(currentIndexChanged(int)), this,SLOT(on_historyList_currentRowChanged(int))); + //Resize system size square + qreal logicalPPCX = ui.systemSize_Frame->logicalDpiX()/2.54; + qreal logicalPPCY = ui.systemSize_Frame->logicalDpiY()/2.54; + + ui.systemSize_Frame->setMinimumSize(logicalPPCX,logicalPPCY); + ui.systemSize_Frame->setMaximumSize(logicalPPCX,logicalPPCY); + ui.systemSize_Frame->setToolTip(QString("Your system reports a screen with %1 DPI (Dots Per Inches) = %2 PPC (Pixels Per Centimeters).") + .arg(ui.systemSize_Frame->logicalDpiX()).arg(logicalPPCX)); + + //Resize system font size square + qreal ptFontSize = (qreal)QApplication::font().pointSize(); + qreal pxFontSize = (qreal)QFontMetrics(QApplication::font()).height(); + qreal px1ptSize = pxFontSize / ptFontSize; + //1 pt = 1/72 inch = 2.54/72 cm + qreal px1cmSize = (px1ptSize * 72.0) / 2.54; + + ui.systemFontSize_Frame->setMinimumSize(px1cmSize,px1cmSize); + ui.systemFontSize_Frame->setMaximumSize(px1cmSize,px1cmSize); + + ui.systemFontSize_Frame->setToolTip(QString("Your default font is %1 points high = %2 mm. Qt print it with %3 pixels.\nSo Font use %4 PPC (Pixels Per Centimeters).") + .arg(ptFontSize).arg((ptFontSize*25.4)/72.0).arg(pxFontSize).arg(px1cmSize)); + + /* Add user notify */ const QList &userNotifyList = MainWindow::getInstance()->getUserNotifyList() ; QList::const_iterator it; @@ -369,9 +392,23 @@ ChatPage::load() whileBlocking(ui.minimumContrast)->setValue(Settings->value("MinimumContrast", 4.5).toDouble()); Settings->endGroup(); - // state of distant Chat combobox - int index = Settings->value("DistantChat", 0).toInt(); - whileBlocking(ui.distantChatComboBox)->setCurrentIndex(index); + // state of distant Chat combobox + + switch(rsMsgs->getDistantChatPermissionFlags()) + { + default: + case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE: + whileBlocking(ui.distantChatComboBox)->setCurrentIndex(0); + break ; + + case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS: + whileBlocking(ui.distantChatComboBox)->setCurrentIndex(1); + break ; + + case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY: + whileBlocking(ui.distantChatComboBox)->setCurrentIndex(2); + break ; + } fontTempChat.fromString(Settings->getChatScreenFont()); @@ -379,6 +416,7 @@ ChatPage::load() whileBlocking(ui.sendAsPlainTextByDef)->setChecked(Settings->getChatSendAsPlainTextByDef()); whileBlocking(ui.loadEmbeddedImages)->setChecked(Settings->getChatLoadEmbeddedImages()); whileBlocking(ui.DontSendTyping)->setChecked(Settings->getChatDoNotSendIsTyping()); + whileBlocking(ui.shrinkChatTextEdit)->setChecked(Settings->getShrinkChatTextEdit()); std::string advsetting; if(rsConfig->getConfigurationOption(RS_CONFIG_ADVANCED, advsetting) && (advsetting == "YES")) diff --git a/retroshare-gui/src/gui/settings/ChatPage.ui b/retroshare-gui/src/gui/settings/ChatPage.ui index 484a632f8..0f60752ac 100644 --- a/retroshare-gui/src/gui/settings/ChatPage.ui +++ b/retroshare-gui/src/gui/settings/ChatPage.ui @@ -95,6 +95,16 @@ + + + + When focus on text browser after showing chat room + + + Shrink text edit field when not needed + + + @@ -395,6 +405,78 @@ + + + + + + If your system is set up correctly, this next square should measure 1 cm. + + + true + + + + + + + + 64 + 64 + + + + + 64 + 64 + + + + QFrame::Box + + + QFrame::Plain + + + + + + + + + + + This next square is scaled accordingly to your system font size. + + + true + + + + + + + + 64 + 64 + + + + + 64 + 64 + + + + QFrame::Box + + + QFrame::Plain + + + + + @@ -527,7 +609,7 @@ - + @@ -543,7 +625,7 @@ - + 0 @@ -644,7 +726,7 @@ - + Everyone @@ -725,7 +807,7 @@ - + @@ -741,7 +823,7 @@ - + 0 @@ -1176,7 +1258,7 @@ - + @@ -1192,7 +1274,7 @@ - + 0 @@ -1285,6 +1367,11 @@ QComboBox
    gui/gxs/GxsIdChooser.h
    + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    diff --git a/retroshare-gui/src/gui/settings/CryptoPage.cpp b/retroshare-gui/src/gui/settings/CryptoPage.cpp index 99317c14d..6c171bb1a 100755 --- a/retroshare-gui/src/gui/settings/CryptoPage.cpp +++ b/retroshare-gui/src/gui/settings/CryptoPage.cpp @@ -61,6 +61,10 @@ CryptoPage::CryptoPage(QWidget * parent, Qt::WindowFlags flags) //connect(ui.exportprofile,SIGNAL(clicked()), this, SLOT(profilemanager())); connect(ui.exportprofile,SIGNAL(clicked()), this, SLOT(exportProfile())); + // Remove this because it duplicates functionality of the HomePage. + ui.retroshareId_LB->hide(); + ui.retroshareId_content_LB->hide(); + ui.stackPageCertificate->hide(); ui.onlinesince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); } @@ -103,8 +107,8 @@ void CryptoPage::showEvent ( QShowEvent * /*event*/ ) ui.pgpfingerprint->setText(misc::fingerPrintStyleSplit(QString::fromStdString(detail.fpr.toStdString()))); std::string invite ; - rsPeers->getShortInvite(invite,rsPeers->getOwnId(),RetroshareInviteFlags::RADIX_FORMAT | RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP); - ui.retroshareid->setText(QString::fromUtf8(invite.c_str())); + rsPeers->getShortInvite(invite,rsPeers->getOwnId(),RetroshareInviteFlags::RADIX_FORMAT | RsPeers::defaultCertificateFlags); + ui.retroshareId_content_LB->setText(QString::fromUtf8(invite.c_str())); /* set retroshare version */ ui.version->setText(Rshare::retroshareVersion(true)); @@ -139,7 +143,7 @@ void CryptoPage::load() { std::string cert ; - RetroshareInviteFlags flags = RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_IP; + RetroshareInviteFlags flags = RetroshareInviteFlags::DNS | RetroshareInviteFlags::CURRENT_LOCAL_IP | RetroshareInviteFlags::CURRENT_EXTERNAL_IP; if(ui._shortFormat_CB->isChecked()) { @@ -161,7 +165,7 @@ CryptoPage::load() RsPeerDetails detail; rsPeers->getPeerDetails(rsPeers->getOwnId(),detail); - ui.certplainTextEdit->setToolTip(ConfCertDialog::getCertificateDescription(detail, ui._includeSignatures_CB->isChecked(), ui._shortFormat_CB->isChecked(), ui._includeAllIPs_CB->isChecked() )); + ui.certplainTextEdit->setToolTip(ConfCertDialog::getCertificateDescription(detail, ui._includeSignatures_CB->isChecked(), ui._shortFormat_CB->isChecked(), flags)); } void diff --git a/retroshare-gui/src/gui/settings/CryptoPage.ui b/retroshare-gui/src/gui/settings/CryptoPage.ui index 6f45b9ea8..29a336721 100755 --- a/retroshare-gui/src/gui/settings/CryptoPage.ui +++ b/retroshare-gui/src/gui/settings/CryptoPage.ui @@ -7,25 +7,19 @@ 0 0 869 - 487 + 493
    - - - 0 - - - - Node information - + + - + Retroshare ID: @@ -211,9 +205,10 @@ - + + 12 75 true @@ -247,7 +242,7 @@ - <html><head/><body><p>Use this to export your profile key. You can then import it in a different computer and make a new node with the same profile. Doing so, existing friends that you also add to the new node will automatically recognise that new node as friend.</p></body></html> + <html><head/><body><p>Use this button to export your profile key. You can then import it in a different computer and make a new node with the same profile. Doing so, existing friends that you also add to the new node will automatically recognise that new node as friend.</p></body></html> Export @@ -302,9 +297,10 @@ - + + 12 75 true @@ -396,9 +392,10 @@ - + + 12 75 true @@ -471,7 +468,7 @@ - + 75 @@ -536,10 +533,7 @@ - - - Certificate - + @@ -638,13 +632,6 @@ - - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    diff --git a/retroshare-gui/src/gui/settings/JsonApiPage.cc b/retroshare-gui/src/gui/settings/JsonApiPage.cc index 5f1bb225f..a824a5fa0 100644 --- a/retroshare-gui/src/gui/settings/JsonApiPage.cc +++ b/retroshare-gui/src/gui/settings/JsonApiPage.cc @@ -80,7 +80,6 @@ void JsonApiPage::enableJsonApi(bool checked) bool JsonApiPage::updateParams() { bool ok = true; - bool changed = false; uint16_t port = static_cast(ui.portSpinBox->value()); QString listenAddress = ui.listenAddressLineEdit->text(); diff --git a/retroshare-gui/src/gui/settings/MessagePage.cpp b/retroshare-gui/src/gui/settings/MessagePage.cpp index 91a24ab02..ff302317d 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.cpp +++ b/retroshare-gui/src/gui/settings/MessagePage.cpp @@ -27,6 +27,7 @@ #include "gui/common/TagDefs.h" #include #include "NewTag.h" +#include "util/qtthreadsutils.h" MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) @@ -54,10 +55,14 @@ MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags) connect(ui.loadEmbeddedImages, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmbededImages() )); connect(ui.openComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(updateMsgOpen() )); connect(ui.emoticonscheckBox, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmoticons() )); + + mTagEventHandlerId = 0; + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [this,event]() { handleEvent_main_thread(event); }); }, mTagEventHandlerId, RsEventType::MAIL_TAG ); } MessagePage::~MessagePage() { + rsEvents->unregisterEventsHandler(mTagEventHandlerId); delete(m_pTags); } @@ -134,6 +139,27 @@ MessagePage::load() fillTags(); } +void MessagePage::handleEvent_main_thread(std::shared_ptr event) +{ + if (event->mType != RsEventType::MAIL_TAG) { + return; + } + + const RsMailTagEvent *fe = dynamic_cast(event.get()); + if (!fe) { + return; + } + + switch (fe->mMailTagEventCode) { + case RsMailTagEventCode::TAG_ADDED: + case RsMailTagEventCode::TAG_CHANGED: + case RsMailTagEventCode::TAG_REMOVED: + rsMail->getMessageTagTypes(*m_pTags); + fillTags(); + break; + } +} + // fill tags void MessagePage::fillTags() { diff --git a/retroshare-gui/src/gui/settings/MessagePage.h b/retroshare-gui/src/gui/settings/MessagePage.h index f3a4c12a7..774d31b95 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.h +++ b/retroshare-gui/src/gui/settings/MessagePage.h @@ -62,11 +62,13 @@ private slots: void updateLoadEmoticons(); private: + void handleEvent_main_thread(std::shared_ptr event); void fillTags(); /* Pointer for not include of rsmsgs.h */ MsgTagType *m_pTags; std::list m_changedTagIds; + RsEventsHandlerId_t mTagEventHandlerId; Ui::MessagePage ui; }; diff --git a/retroshare-gui/src/gui/settings/MessagePage.ui b/retroshare-gui/src/gui/settings/MessagePage.ui index 58da48b9f..fd55218e8 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.ui +++ b/retroshare-gui/src/gui/settings/MessagePage.ui @@ -24,7 +24,7 @@ - + Everyone @@ -75,7 +75,7 @@ - +
    @@ -174,6 +174,13 @@
    + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/settings/NotifyPage.ui b/retroshare-gui/src/gui/settings/NotifyPage.ui index 8abfa09d9..fba357bcf 100755 --- a/retroshare-gui/src/gui/settings/NotifyPage.ui +++ b/retroshare-gui/src/gui/settings/NotifyPage.ui @@ -382,7 +382,7 @@
    - + 0 @@ -495,6 +495,13 @@ systray_ChatLobby pushButtonDisableAll + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/settings/PluginItem.ui b/retroshare-gui/src/gui/settings/PluginItem.ui index 063c27377..202baf819 100644 --- a/retroshare-gui/src/gui/settings/PluginItem.ui +++ b/retroshare-gui/src/gui/settings/PluginItem.ui @@ -10,12 +10,21 @@ 177
    - - + + + 0 + + + 0 + + + 0 + + 0 - + true @@ -28,11 +37,11 @@ QFrame::StyledPanel - + - + - + QLayout::SetDefaultConstraint @@ -73,16 +82,22 @@ - + + + + 75 + true + + TextLabel - + 0 @@ -91,6 +106,7 @@ + 12 75 true @@ -104,7 +120,7 @@ - + @@ -140,7 +156,7 @@ p, li { white-space: pre-wrap; } - + Qt::Horizontal @@ -196,7 +212,7 @@ p, li { white-space: pre-wrap; } - + @@ -205,9 +221,9 @@ p, li { white-space: pre-wrap; } QFrame::Raised - + - + File name: @@ -230,7 +246,7 @@ p, li { white-space: pre-wrap; } - + File hash: @@ -253,7 +269,7 @@ p, li { white-space: pre-wrap; } - + Status: @@ -285,13 +301,6 @@ p, li { white-space: pre-wrap; } - - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    diff --git a/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp b/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp index 7d869ab57..76622625b 100644 --- a/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp +++ b/retroshare-gui/src/gui/settings/RSPermissionMatrixWidget.cpp @@ -96,14 +96,18 @@ void RSPermissionMatrixWidget::updateDisplay() void RSPermissionMatrixWidget::mousePressEvent(QMouseEvent *e) { +#ifdef DEBUG_PERMISSION_MATRIX std::cerr << "mouse pressed at x=" << e->x() << ", y=" << e->y() << std::endl; +#endif uint32_t service_id ; RsPeerId peer_id ; if(computeServiceAndPeer(e->x(),e->y(),service_id,peer_id)) { +#ifdef DEBUG_PERMISSION_MATRIX std::cerr << "Peer id: " << peer_id << ", service: " << service_id << std::endl; +#endif // Make sure the service is not globally disabled diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index e17fc9919..adb1d655c 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -21,6 +21,7 @@ #include "ServerPage.h" #include +#include "gui/MainWindow.h" #include "rshare.h" #include "rsharesettings.h" #include "util/i2pcommon.h" @@ -47,6 +48,10 @@ #include #include +#ifdef RS_USE_I2P_SAM3 +#include +#endif + #define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" #define ICON_STATUS_WORKING ":/images/yellowled.png" #define ICON_STATUS_OK ":/images/ledon1.png" @@ -64,11 +69,11 @@ /// // Tabs numbers *after* non relevant tabs are removed. So do not use them to add/remove tabs!! -const static uint32_t TAB_HIDDEN_SERVICE_OUTGOING = 0; +//nst static uint32_t TAB_HIDDEN_SERVICE_OUTGOING = 0; const static uint32_t TAB_HIDDEN_SERVICE_INCOMING = 1; -const static uint32_t TAB_HIDDEN_SERVICE_I2P_BOB = 2; +const static uint32_t TAB_HIDDEN_SERVICE_I2P = 2; -const static uint32_t TAB_NETWORK = 0; +//nst static uint32_t TAB_NETWORK = 0; const static uint32_t TAB_HIDDEN_SERVICE = 1; const static uint32_t TAB_IP_FILTERS = 2; const static uint32_t TAB_RELAYS = 3; @@ -79,14 +84,14 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) : ConfigPage(parent, flags) , manager(NULL), mOngoingConnectivityCheck(-1) , mIsHiddenNode(false), mHiddenType(RS_HIDDEN_TYPE_NONE) - , mBobAccessible(false) + , mSamAccessible(false) , mEventHandlerId(0) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); -#ifndef RS_USE_I2P_BOB - ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P_BOB); // warning: the order of operation here is very important. +#ifndef RS_USE_I2P_SAM3 + ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P); // warning: the order of operation here is very important. #endif if(RsAccounts::isHiddenNode()) @@ -98,20 +103,31 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) { // Here we use absolute numbers instead of consts defined above, because the consts correspond to the tab number *after* this tab removal. - ui.hiddenpage_proxyAddress_i2p->hide() ; - ui.hiddenpage_proxyLabel_i2p->hide() ; - ui.hiddenpage_proxyPort_i2p->hide() ; - ui.label_i2p_outgoing->hide() ; - ui.iconlabel_i2p_outgoing->hide() ; - ui.plainTextEdit->hide() ; + ui.hiddenpage_proxyAddress_tor->setEnabled(false) ; + ui.hiddenpage_proxyPort_tor->setEnabled(false) ; + ui.hiddenpage_localAddress->setEnabled(false) ; + ui.hiddenpage_localPort->setEnabled(false) ; + ui.hiddenpage_serviceAddress->setEnabled(false) ; + ui.hiddenpage_servicePort->setEnabled(false) ; + ui.testIncoming_PB->hide() ; + ui.l_incomingTestResult->hide() ; + ui.iconlabel_service_incoming->hide() ; + + // ui.hiddenpage_proxyAddress_i2p->hide() ; + // ui.hiddenpage_proxyLabel_i2p->hide() ; + // ui.hiddenpage_proxyPort_i2p->hide() ; + // ui.label_i2p_outgoing->hide() ; + // ui.iconlabel_i2p_outgoing->hide() ; + + ui.info_SocksProxy->hide() ; ui.hiddenpage_configuration->hide() ; ui.l_hiddenpage_configuration->hide() ; - ui.hiddenpageInHelpPlainTextEdit->hide() ; + ui.info_HiddenPageInHelp->hide() ; ui.hiddenpage_outHeader->setText(tr("Tor has been automatically configured by Retroshare. You shouldn't need to change anything here.")) ; ui.hiddenpage_inHeader->setText(tr("Tor has been automatically configured by Retroshare. You shouldn't need to change anything here.")) ; - ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P_BOB); // warning: the order of operation here is very important. + ui.hiddenServiceTab->removeTab(TAB_HIDDEN_SERVICE_I2P); // warning: the order of operation here is very important. } } else @@ -153,8 +169,8 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) ui.leBobB32Addr->hide(); ui.pbBobGenAddr->hide(); - QObject::connect(ui.filteredIpsTable,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ipFilterContextMenu(const QPoint&))) ; - QObject::connect(ui.whiteListIpsTable,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ipWhiteListContextMenu(const QPoint&))) ; + QObject::connect(ui.filteredIpsTable,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ipFilterContextMenu(QPoint))) ; + QObject::connect(ui.whiteListIpsTable,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(ipWhiteListContextMenu(QPoint))) ; QObject::connect(ui.denyAll_CB,SIGNAL(toggled(bool)),this,SLOT(toggleIpFiltering(bool))); QObject::connect(ui.includeFromDHT_CB,SIGNAL(toggled(bool)),this,SLOT(toggleAutoIncludeDHT(bool))); QObject::connect(ui.includeFromFriends_CB,SIGNAL(toggled(bool)),this,SLOT(toggleAutoIncludeFriends(bool))); @@ -162,18 +178,18 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.groupIPRanges_SB,SIGNAL(valueChanged(int)),this,SLOT(setGroupIpLimit(int))); QObject::connect(ui.ipInputAddBlackList_PB,SIGNAL(clicked()),this,SLOT(addIpRangeToBlackList())); QObject::connect(ui.ipInputAddWhiteList_PB,SIGNAL(clicked()),this,SLOT(addIpRangeToWhiteList())); - QObject::connect(ui.ipInput_LE,SIGNAL(textChanged(const QString&)),this,SLOT(checkIpRange(const QString&))); + QObject::connect(ui.ipInput_LE,SIGNAL(textChanged(QString)),this,SLOT(checkIpRange(QString))); QObject::connect(ui.filteredIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedBlackListIP(int,int,int,int))); QObject::connect(ui.whiteListIpsTable,SIGNAL(currentCellChanged(int,int,int,int)),this,SLOT(updateSelectedWhiteListIP(int,int,int,int))); - QObject::connect(ui.pbBobStart, SIGNAL(clicked()), this, SLOT(startBOB())); - QObject::connect(ui.pbBobRestart, SIGNAL(clicked()), this, SLOT(restartBOB())); - QObject::connect(ui.pbBobStop, SIGNAL(clicked()), this, SLOT(stopBOB())); + QObject::connect(ui.pbBobStart, SIGNAL(clicked()), this, SLOT(startSam())); + QObject::connect(ui.pbBobRestart, SIGNAL(clicked()), this, SLOT(restartSam())); + QObject::connect(ui.pbBobStop, SIGNAL(clicked()), this, SLOT(stopSam())); QObject::connect(ui.pbBobGenAddr, SIGNAL(clicked()), this, SLOT(getNewKey())); QObject::connect(ui.pbBobLoadKey, SIGNAL(clicked()), this, SLOT(loadKey())); - QObject::connect(ui.cb_enableBob, SIGNAL(toggled(bool)), this, SLOT(enableBob(bool))); + QObject::connect(ui.cb_enableBob, SIGNAL(toggled(bool)), this, SLOT(enableSam(bool))); - QObject::connect(ui.cbBobAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleBobAdvancedSettings(bool))); + QObject::connect(ui.cbBobAdvanced, SIGNAL(toggled(bool)), this, SLOT(toggleSamAdvancedSettings(bool))); QObject::connect(ui.sbBobLengthIn, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); QObject::connect(ui.sbBobLengthOut, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); @@ -182,23 +198,19 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.sbBobVarianceIn, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); QObject::connect(ui.sbBobVarianceOut, SIGNAL(valueChanged(int)), this, SLOT(tunnelSettingsChanged(int))); - // These two spin boxes are used for the same thing - keep them in sync! - QObject::connect(ui.hiddenpage_proxyPort_i2p, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortNormal(int))); - QObject::connect(ui.hiddenpage_proxyPort_i2p_2, SIGNAL(valueChanged(int)), this, SLOT(syncI2PProxyPortBob(int))); - // These two line edits are used for the same thing - keep them in sync! QObject::connect(ui.hiddenpage_proxyAddress_i2p, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrNormal(QString))); - QObject::connect(ui.hiddenpage_proxyAddress_i2p_2, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrBob(QString))); + QObject::connect(ui.hiddenpage_proxyAddress_i2p_2, SIGNAL(textChanged(QString)), this, SLOT(syncI2PProxyAddrSam(QString))); connect(NotifyQt::getInstance(), SIGNAL(connectionWithoutCert()), this, SLOT(connectionWithoutCert())); QObject::connect(ui.localPort,SIGNAL(valueChanged(int)),this,SLOT(saveAddresses())); QObject::connect(ui.extPort,SIGNAL(valueChanged(int)),this,SLOT(saveAddresses())); - 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.testIncoming_PB, SIGNAL( clicked( ) ), this, SLOT( saveAndTestInProxy() ) ); + 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.testIncoming_PB, SIGNAL( clicked() ), this, SLOT( saveAndTestInProxy() ) ); #ifdef SERVER_DEBUG std::cerr << "ServerPage::ServerPage() called"; @@ -207,9 +219,9 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) connect(ui.discComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(saveAddresses())); connect(ui.netModeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(saveAddresses())); - connect(ui.localAddress, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); - connect(ui.extAddress, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); - connect(ui.dynDNS, SIGNAL(textChanged(QString)),this,SLOT(saveAddresses())); + connect(ui.localAddress, SIGNAL(editingFinished()),this,SLOT(saveAddresses())); + connect(ui.extAddress, SIGNAL(editingFinished()),this,SLOT(saveAddresses())); + connect(ui.dynDNS, SIGNAL(editingFinished()),this,SLOT(saveAddresses())); connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); connect(ui.hiddenpage_proxyAddress_tor, SIGNAL(editingFinished()),this,SLOT(saveAddresses())); @@ -230,7 +242,7 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui.addPushButton,SIGNAL(clicked()),this,SLOT(addServer())); QObject::connect(ui.removePushButton,SIGNAL(clicked()),this,SLOT(removeServer())); - QObject::connect(ui.DhtLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(checkKey())); + QObject::connect(ui.DhtLineEdit,SIGNAL(textChanged(QString)),this,SLOT(checkKey())); QObject::connect(ui.enableCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled())); QObject::connect(ui.serverCheckBox,SIGNAL(stateChanged(int)),this,SLOT(updateEnabled())); @@ -373,7 +385,7 @@ void ServerPage::load() } mIsHiddenNode = (detail.netMode == RS_NETMODE_HIDDEN); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::getSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::getSettings, &mSamSettings); loadCommon(); updateStatus(); @@ -435,8 +447,8 @@ void ServerPage::load() { if (detail.vs_disc != RS_VS_DISC_OFF) netIndex = 1; // PRIVATE - else - netIndex = 3; // NONE + //else //Use default value + // netIndex = 3; // NONE } whileBlocking(ui.discComboBox)->setCurrentIndex(netIndex); @@ -461,6 +473,7 @@ void ServerPage::load() whileBlocking(ui.ipAddressList)->clear(); + detail.ipAddressList.sort(); for(std::list::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(*it)); @@ -826,10 +839,10 @@ void ServerPage::ipWhiteListContextMenu(const QPoint& /* point */) return ; } - QString range0 = RsNetUtil::printAddrRange(addr,0) ; - QString range1 = RsNetUtil::printAddrRange(addr,1) ; - QString range2 = RsNetUtil::printAddrRange(addr,2) ; - +// QString range0 = RsNetUtil::printAddrRange(addr,0) ; +// QString range1 = RsNetUtil::printAddrRange(addr,1) ; +// QString range2 = RsNetUtil::printAddrRange(addr,2) ; +// // contextMenu.addAction(QObject::tr("Whitelist only IP " )+range0,this,SLOT(enableBannedIp()))->setEnabled(false) ; //#warning UNIMPLEMENTED CODE // contextMenu.addAction(QObject::tr("Whitelist entire range ")+range1,this,SLOT(enableBannedIp()))->setEnabled(false) ; @@ -870,9 +883,9 @@ void ServerPage::updateStatus() loadFilteredIps() ; - updateStatusBob(); + updateStatusSam(); - // this is used by BOB + // this is used by SAM if (mOngoingConnectivityCheck > 0) { mOngoingConnectivityCheck--; @@ -932,6 +945,28 @@ void ServerPage::updateStatus() else ui.iconlabel_ext->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/images/ledoff1.png")); + if (ui.ipAddressList->isEnabled() ) + { + whileBlocking(ui.ipAddressList)->clear(); + detail.ipAddressList.sort(); + for(auto& it : detail.ipAddressList) + whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(it).replace("sec",tr("sec")).replace("loc",tr("local")).replace("ext",tr("external"))); + } + + QString toolTip = tr("List of OpenDns servers used."); + if (ui.IPServersLV->isEnabled() ) + { + std::list ip_list; + rsPeers->getCurrentExtIPList(ip_list); + if ( !ip_list.empty() ) + { + toolTip += tr("\n\nList of found external IP:\n"); + for(std::list::const_iterator it(ip_list.begin());it!=ip_list.end();++it) + toolTip += " " + QString::fromStdString(*it) +"\n" ; + } + } + if(ui.IPServersLV->toolTip() != toolTip) + ui.IPServersLV->setToolTip(toolTip); } void ServerPage::toggleUPnP() @@ -1098,7 +1133,7 @@ void ServerPage::loadHiddenNode() ui.iconlabel_upnp->hide(); ui.label_nat->hide(); - ui.label_warningBandwidth->hide(); + ui.info_warningBandwidth->hide(); ui.iconlabel_netLimited->hide(); ui.textlabel_netLimited->hide(); ui.iconlabel_ext->hide(); @@ -1160,6 +1195,7 @@ void ServerPage::loadHiddenNode() // show what we have in ipAddresses. (should be nothing!) ui.ipAddressList->clear(); + detail.ipAddressList.sort(); for(std::list::const_iterator it(detail.ipAddressList.begin());it!=detail.ipAddressList.end();++it) whileBlocking(ui.ipAddressList)->addItem(QString::fromStdString(*it)); @@ -1333,6 +1369,7 @@ void ServerPage::saveAddressesHiddenNode() void ServerPage::updateOutProxyIndicator() { + MainWindow::getInstance()->torstatusReset(); QTcpSocket socket ; // Tor @@ -1349,32 +1386,50 @@ void ServerPage::updateOutProxyIndicator() ui.iconlabel_tor_outgoing->setToolTip(tr("Tor proxy is not enabled")) ; } - // 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(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; - ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; - } - else - { - ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; - } - - // I2P - BOB - socket.connectToHost(ui.hiddenpage_proxyAddress_i2p_2->text(), 2827); - if(true == (mBobAccessible = socket.waitForConnected(500))) + if (mHiddenType == RS_HIDDEN_TYPE_I2P && mSamSettings.enable) + { + // I2P - SAM + // Note: there is only "the SAM port", there is no additional proxy port! + samStatus ss; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::status, &ss); + if(ss.state == samStatus::samState::online) + { + socket.disconnectFromHost(); + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; + } + else + { + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; + } + } + else + { + socket.connectToHost(ui.hiddenpage_proxyAddress_i2p->text(),ui.hiddenpage_proxyPort_i2p->text().toInt()); + if(socket.waitForConnected(500)) + { + socket.disconnectFromHost(); + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("Proxy seems to work.")) ; + } + else + { + ui.iconlabel_i2p_outgoing->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + ui.iconlabel_i2p_outgoing->setToolTip(tr("I2P proxy is not enabled")) ; + } + } + socket.connectToHost(ui.hiddenpage_proxyAddress_i2p_2->text(), 7656); + if(true == (mSamAccessible = socket.waitForConnected(1000))) { socket.disconnectFromHost(); ui.iconlabel_i2p_outgoing_2->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)) ; - ui.iconlabel_i2p_outgoing_2->setToolTip(tr("BOB is running and accessible")) ; + ui.iconlabel_i2p_outgoing_2->setToolTip(tr("SAMv3 is running and accessible")) ; } else { ui.iconlabel_i2p_outgoing_2->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; - ui.iconlabel_i2p_outgoing_2->setToolTip(tr("BOB is not accessible! Is it running?")) ; + ui.iconlabel_i2p_outgoing_2->setToolTip(tr("SAMv3 is not accessible! Is i2p running and SAM enabled?")) ; } } @@ -1385,28 +1440,18 @@ void ServerPage::updateInProxyIndicator() if(!mIsHiddenNode) return ; - //ui.iconlabel_tor_incoming->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; + //ui.iconlabel_tor_incoming->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)) ; //ui.testIncomingTor_PB->setIcon(FilesDefs::getIconFromQtResourcePath(":/loader/circleball-16.gif")) ; QMovie *movie = new QMovie(":/images/loader/circleball-16.gif"); ui.iconlabel_service_incoming->setMovie(movie); movie->start(); - if (mHiddenType == RS_HIDDEN_TYPE_I2P && mBobSettings.enable) { - - QTcpSocket tcpSocket; - - const QString host = ui.hiddenpage_proxyAddress_i2p->text(); - qint16 port = ui.hiddenpage_proxyPort_i2p->text().toInt(); - QByteArray addr = ui.leBobB32Addr->text().toUtf8(); - addr.push_back('\n'); - - mOngoingConnectivityCheck = 5; // timeout in sec - - tcpSocket.connectToHost(host, port); - tcpSocket.write(addr); // write addr - tcpSocket.write(addr); // trigger connection error since RS expects a tls connection - tcpSocket.close(); - tcpSocket.waitForDisconnected(5 * 1000); + if (mHiddenType == RS_HIDDEN_TYPE_I2P && mSamSettings.enable) { + // there is no inproxy for SAMv3, since every connection goes through sam itself + auto secw = new samEstablishConnectionWrapper(); + secw->address = mSamSettings.address; + secw->connection = nullptr; + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::establishConnection, this, secw); return; } @@ -1419,18 +1464,10 @@ void ServerPage::updateInProxyIndicator() QNetworkProxy proxy ; proxy.setType(QNetworkProxy::Socks5Proxy); - 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.setHostName(ui.hiddenpage_proxyAddress_tor->text()); + proxy.setPort(ui.hiddenpage_proxyPort_tor->text().toInt()); + proxy.setCapabilities(QNetworkProxy::HostNameLookupCapability | proxy.capabilities()) ; QNetworkProxy::setApplicationProxy(proxy) ; @@ -1445,53 +1482,58 @@ void ServerPage::updateInProxyIndicator() QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy) ; } -void ServerPage::startBOB() +void ServerPage::startSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::start); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::start); updateStatus(); } -void ServerPage::restartBOB() +void ServerPage::restartSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::stop); - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::start); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::stop); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::start); updateStatus(); } -void ServerPage::stopBOB() +void ServerPage::stopSam() { - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::stop); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::stop); updateStatus(); } void ServerPage::getNewKey() { - bobSettings *bs = new bobSettings(); - - rsAutoProxyMonitor::taskAsync(autoProxyType::I2PBOB, autoProxyTask::receiveKey, this, bs); - - updateStatus(); + i2p::address *addr = new i2p::address(); + rsAutoProxyMonitor::taskAsync(autoProxyType::I2PSAM3, autoProxyTask::receiveKey, this, addr); } void ServerPage::loadKey() { - mBobSettings.address.privateKey = ui.pteBobServerKey->toPlainText().toStdString(); - mBobSettings.address.publicKey = i2p::publicKeyFromPrivate(mBobSettings.address.privateKey); - mBobSettings.address.base32 = i2p::keyToBase32Addr(mBobSettings.address.publicKey); + auto priv = ui.pteBobServerKey->toPlainText().toStdString(); + auto pub = i2p::publicKeyFromPrivate(priv); + if (pub.empty()) { + // something went wrong! + ui.pteBobServerKey->setPlainText("FAILED! Something went wrong while parsing the key!"); + return; + } - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + mSamSettings.address.privateKey = priv; + mSamSettings.address.publicKey = pub; + mSamSettings.address.base32 = i2p::keyToBase32Addr(mSamSettings.address.publicKey); + + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); } -void ServerPage::enableBob(bool checked) +void ServerPage::enableSam(bool checked) { - mBobSettings.enable = checked; + mSamSettings.enable = checked; - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); - setUpBobElements(); + setUpSamElements(); } int8_t fitRange(int i, int min, int max) { @@ -1513,21 +1555,21 @@ void ServerPage::tunnelSettingsChanged(int) vi = ui.sbBobVarianceIn->value(); vo = ui.sbBobVarianceOut->value(); - mBobSettings.inLength = fitRange(li, 0, 7); - mBobSettings.outLength = fitRange(lo, 0, 7); - mBobSettings.inQuantity = fitRange(qi, 1, 16); - mBobSettings.outQuantity = fitRange(qo, 1, 16); - mBobSettings.inVariance = fitRange(vi, -1, 2); - mBobSettings.outVariance = fitRange(vo, -1, 2); + mSamSettings.inLength = fitRange(li, 0, 7); + mSamSettings.outLength = fitRange(lo, 0, 7); + mSamSettings.inQuantity = fitRange(qi, 1, 16); + mSamSettings.outQuantity = fitRange(qo, 1, 16); + mSamSettings.inVariance = fitRange(vi, -1, 2); + mSamSettings.outVariance = fitRange(vo, -1, 2); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::setSettings, &mBobSettings); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); } -void ServerPage::toggleBobAdvancedSettings(bool checked) +void ServerPage::toggleSamAdvancedSettings(bool checked) { ui.swBobAdvanced->setCurrentIndex(checked ? 1 : 0); - if (!mBobSettings.address.privateKey.empty()) { + if (!mSamSettings.address.privateKey.empty()) { if (checked) { ui.pbBobGenAddr->show(); } else { @@ -1536,57 +1578,91 @@ void ServerPage::toggleBobAdvancedSettings(bool checked) } } -void ServerPage::syncI2PProxyPortNormal(int i) -{ - ui.hiddenpage_proxyPort_i2p_2->setValue(i); -} - -void ServerPage::syncI2PProxyPortBob(int i) -{ - ui.hiddenpage_proxyPort_i2p->setValue(i); - - // update port - saveBob(); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::reloadConfig); -} - void ServerPage::syncI2PProxyAddrNormal(QString t) { ui.hiddenpage_proxyAddress_i2p_2->setText(t); } -void ServerPage::syncI2PProxyAddrBob(QString t) +void ServerPage::syncI2PProxyAddrSam(QString t) { ui.hiddenpage_proxyAddress_i2p->setText(t); // update addr - saveBob(); - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::reloadConfig); + saveSam(); + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::reloadConfig); } void ServerPage::taskFinished(taskTicket *&ticket) { - if (ticket->task == autoProxyTask::receiveKey) { - bobSettings *s = NULL; - switch (ticket->types.front()) { - case autoProxyType::I2PBOB: - // update settings - s = (struct bobSettings *)ticket->data; - mBobSettings = *s; - delete s; - s = NULL; - ticket->data = NULL; - break; - default: - break; - } - } +#ifdef RS_USE_I2P_SAM3 + switch (ticket->task) { + case autoProxyTask::receiveKey: + { + i2p::address *addr = nullptr; + addr = static_cast(ticket->data); + + if (ticket->types.front() != autoProxyType::I2PSAM3) + RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); + else { + // update settings + auto copy = *addr; + RsQThreadUtils::postToObject( + [this, copy]() + { + mSamSettings.address = copy; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::setSettings, &mSamSettings); + updateStatusSam(); + + }); + } + + delete addr; + addr = nullptr; + ticket->data = nullptr; + + + break; + } + case autoProxyTask::establishConnection: + { + samEstablishConnectionWrapper *secw = nullptr; + secw = static_cast(ticket->data); + + if (ticket->types.front() != autoProxyType::I2PSAM3) + RS_WARN("auto proxy task finished but not for SMA, not exptected! Also not a serious problem."); + else { + bool res = ticket->result == autoProxyStatus::ok && !!secw->connection->ses; + // update settings + if (res) { + sam3CloseConnection(secw->connection); + secw->connection = nullptr; // freed by above call + } + + RsQThreadUtils::postToObject( + [this, res]() + { + updateInProxyIndicatorResult(res); + + }); + } + + if (secw->connection) + delete secw->connection; + delete secw; + secw = nullptr; + ticket->data = nullptr; + break; + } + default: + RS_DBG("unsupported task!", ticket->task); + } if (ticket->data) std::cerr << "(WW) ServerPage::taskFinished data set. This should NOT happen - check the code!" << std::endl; delete ticket; - ticket = NULL; + ticket = nullptr; + #endif //RS_USE_I2P_SAM3 } void ServerPage::connectionWithoutCert() @@ -1613,14 +1689,13 @@ void ServerPage::loadCommon() // I2P rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, proxyaddr, proxyport, status); whileBlocking(ui.hiddenpage_proxyAddress_i2p) -> setText(QString::fromStdString(proxyaddr)); - whileBlocking(ui.hiddenpage_proxyAddress_i2p_2)->setText(QString::fromStdString(proxyaddr)); // this one is for bob tab + whileBlocking(ui.hiddenpage_proxyAddress_i2p_2)->setText(QString::fromStdString(proxyaddr)); // this one is for sam tab whileBlocking(ui.hiddenpage_proxyPort_i2p) -> setValue(proxyport); - whileBlocking(ui.hiddenpage_proxyPort_i2p_2)->setValue(proxyport); // this one is for bob tab // don't use whileBlocking here - ui.cb_enableBob->setChecked(mBobSettings.enable); + ui.cb_enableBob->setChecked(mSamSettings.enable); - if (!mBobSettings.address.privateKey.empty()) { + if (!mSamSettings.address.privateKey.empty()) { ui.lBobB32Addr->show(); ui.leBobB32Addr->show(); } @@ -1642,10 +1717,10 @@ void ServerPage::saveCommon() rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, new_proxyaddr, new_proxyport); } - saveBob(); + saveSam(); } -void ServerPage::saveBob() +void ServerPage::saveSam() { std::string orig_proxyaddr, new_proxyaddr; uint16_t orig_proxyport, new_proxyport; @@ -1656,20 +1731,29 @@ void ServerPage::saveBob() new_proxyaddr = ui.hiddenpage_proxyAddress_i2p -> text().toStdString(); new_proxyport = ui.hiddenpage_proxyPort_i2p -> value(); - if ((new_proxyaddr != orig_proxyaddr) || (new_proxyport != orig_proxyport)) { + // SAMv3 has no proxy port, everything goes through the SAM port. + if ((new_proxyaddr != orig_proxyaddr) /* || (new_proxyport != orig_proxyport) */) { rsPeers->setProxyServer(RS_HIDDEN_TYPE_I2P, new_proxyaddr, new_proxyport); } } -void ServerPage::updateStatusBob() +void ServerPage::updateStatusSam() { - QString addr = QString::fromStdString(mBobSettings.address.base32); + QString addr = QString::fromStdString(mSamSettings.address.base32); if (ui.leBobB32Addr->text() != addr) { ui.leBobB32Addr->setText(addr); ui.hiddenpage_serviceAddress->setText(addr); - ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey)); + ui.pteBobServerKey->setPlainText(QString::fromStdString(mSamSettings.address.privateKey)); - if (!mBobSettings.address.privateKey.empty()) { + std::string signingKeyType, cryptoKeyType; + if (i2p::getKeyTypes(mSamSettings.address.publicKey, signingKeyType, cryptoKeyType)) + ui.samKeyInfo->setText(tr("Your key uses the following algorithms: %1 and %2"). + arg(QString::fromStdString(signingKeyType)). + arg(QString::fromStdString(cryptoKeyType))); + else + ui.samKeyInfo->setText(tr("unkown key type")); + + if (!mSamSettings.address.privateKey.empty()) { // we have an addr -> show fields ui.lBobB32Addr->show(); ui.leBobB32Addr->show(); @@ -1686,128 +1770,82 @@ void ServerPage::updateStatusBob() ui.pbBobGenAddr->hide(); } - saveAddresses(); + saveAddresses(); } - bobStates bs; - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::status, &bs); + samStatus ss; + rsAutoProxyMonitor::taskSync(autoProxyType::I2PSAM3, autoProxyTask::status, &ss); QString bobSimpleText = QString(); - bobSimpleText.append(tr("RetroShare uses BOB to set up a %1 tunnel at %2:%3 (named %4)\n\n" - "When changing options (e.g. port) use the buttons at the bottom to restart BOB.\n\n"). - arg(mBobSettings.address.privateKey.empty() ? tr("client") : tr("server"), + bobSimpleText.append(tr("RetroShare uses SAMv3 to set up a %1 tunnel at %2:%3\n(id: %4)\n\n" + "When changing options use the buttons at the bottom to restart SAMv3.\n\n"). + arg(mSamSettings.address.privateKey.empty() ? tr("client") : tr("server"), ui.hiddenpage_proxyAddress_i2p_2->text(), - ui.hiddenpage_proxyPort_i2p_2->text(), - bs.tunnelName.empty() ? tr("unknown") : - QString::fromStdString(bs.tunnelName))); + "7656", + ss.sessionName.empty() ? tr("unknown") : + QString::fromStdString(ss.sessionName))); - // update BOB UI based on state - std::string errorString; - switch (bs.cs) { - case csDoConnect: - case csConnected: - case csDoDisconnect: - case csWaitForBob: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); + // update SAM UI based on state + QString s; + QString icon; + switch (ss.state) { + case samStatus::samState::offline: + enableSamElements(false); - enableBobElements(false); + ui.pbBobStart->setEnabled(true); + ui.pbBobRestart->setEnabled(false); + ui.pbBobStop->setEnabled(false); - { - QString s; - switch (bs.ct) { - case ctRunCheck: - s = tr("connectivity check"); - break; - case ctRunGetKeys: - s = tr("generating key"); - break; - case ctRunSetUp: - s = tr("starting up"); - break; - case ctRunShutDown: - s = tr("shuting down"); - default: - break; - } - bobSimpleText.append(tr("BOB is processing a request: %1").arg(s)); - } + s = tr("Offline, no SAM session is established yet.\n"); + icon = ICON_STATUS_ERROR; + break; + case samStatus::samState::connectSession: + enableSamElements(false); - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - case csError: - // get error msg from bob - rsAutoProxyMonitor::taskSync(autoProxyType::I2PBOB, autoProxyTask::getErrorInfo, &errorString); - - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_ERROR)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is broken\n") + QString::fromStdString(errorString)); - - enableBobElements(false); - - bobSimpleText.append(tr("BOB encountered an error:\n")); - bobSimpleText.append(QString::fromStdString(errorString)); - - ui.pbBobStart->setEnabled(true); - ui.pbBobRestart->setEnabled(false); + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(false); ui.pbBobStop->setEnabled(true); - break; - case csDisconnected: - case csIdel: - switch (bs.ct) { - case ctRunSetUp: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_OK)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is running")); - enableBobElements(false); + s = tr("SAM is trying to establish a session ... this can take some time.\n"); + icon = ICON_STATUS_WORKING; + break; + case samStatus::samState::connectForward: + enableSamElements(false); - bobSimpleText.append(tr("BOB is working fine: tunnel established")); + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(false); + ui.pbBobStop->setEnabled(true); - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(true); - ui.pbBobStop->setEnabled(true); - break; - case ctRunCheck: - case ctRunGetKeys: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_WORKING)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB is processing a request")); + s = tr("SAM session established! Now setting up a forward session ...\n"); + icon = ICON_STATUS_WORKING; + break; + case samStatus::samState::online: + enableSamElements(true); - enableBobElements(false); + ui.pbBobStart->setEnabled(false); + ui.pbBobRestart->setEnabled(true); + ui.pbBobStop->setEnabled(true); - bobSimpleText.append(tr("BOB is processing a request")); + s = tr("Online, SAM is working as exptected\n"); + icon = ICON_STATUS_OK; + break; + } + ui.iconlabel_i2p_bob->setPixmap(icon); + ui.iconlabel_i2p_bob->setToolTip(s); + bobSimpleText.append(s); - ui.pbBobStart->setEnabled(false); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - case ctRunShutDown: - case ctIdle: - ui.iconlabel_i2p_bob->setPixmap(FilesDefs::getPixmapFromQtResourcePath(ICON_STATUS_UNKNOWN)); - ui.iconlabel_i2p_bob->setToolTip(tr("BOB tunnel is not running")); - enableBobElements(true); + ui.info_BobSimple->setPlainText(bobSimpleText); - bobSimpleText.append(tr("BOB is inactive: tunnel closed")); - - ui.pbBobStart->setEnabled(true); - ui.pbBobRestart->setEnabled(false); - ui.pbBobStop->setEnabled(false); - break; - } - break; - - } - ui.pteBobSimple->setPlainText(bobSimpleText); // disable elements when BOB is not accessible - if (!mBobAccessible) { + if (!mSamAccessible) { ui.pbBobStart->setEnabled(false); - ui.pbBobStart->setToolTip("BOB is not accessible"); + ui.pbBobStart->setToolTip("SAMv3 is not accessible"); ui.pbBobRestart->setEnabled(false); - ui.pbBobRestart->setToolTip("BOB is not accessible"); - // don't disable the stop button! (in case bob is running you are otherwise unable to stop and disable it) - ui.pbBobStop->setToolTip("BOB is not accessible"); + ui.pbBobRestart->setToolTip("SAMv3 is not accessible"); + // don't disable the stop button! (in case SAM is running you are otherwise unable to stop and disable it) + ui.pbBobStop->setToolTip("SAMv3 is not accessible"); } else { ui.pbBobStart->setToolTip(""); ui.pbBobRestart->setToolTip(""); @@ -1815,26 +1853,34 @@ void ServerPage::updateStatusBob() } } -void ServerPage::setUpBobElements() +void ServerPage::setUpSamElements() { - ui.gbBob->setEnabled(mBobSettings.enable); - if (mBobSettings.enable) { + ui.gbBob->setEnabled(mSamSettings.enable); + if (mSamSettings.enable) { ui.hiddenpage_proxyAddress_i2p->setEnabled(false); - ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P/BOB settings to change this value"); + ui.hiddenpage_proxyAddress_i2p->setToolTip("Use I2P settings to change this value"); ui.hiddenpage_proxyPort_i2p->setEnabled(false); - ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P/BOB settings to change this value"); + ui.hiddenpage_proxyPort_i2p->setToolTip("Use I2P settings to change this value"); - ui.leBobB32Addr->setText(QString::fromStdString(mBobSettings.address.base32)); - ui.pteBobServerKey->setPlainText(QString::fromStdString(mBobSettings.address.privateKey)); + ui.leBobB32Addr->setText(QString::fromStdString(mSamSettings.address.base32)); + ui.pteBobServerKey->setPlainText(QString::fromStdString(mSamSettings.address.privateKey)); + + std::string signingKeyType, cryptoKeyType; + if (i2p::getKeyTypes(mSamSettings.address.publicKey, signingKeyType, cryptoKeyType)) + ui.samKeyInfo->setText(tr("You key uses %1 for signing and %2 for crypto"). + arg(QString::fromStdString(signingKeyType)). + arg(QString::fromStdString(cryptoKeyType))); + else + ui.samKeyInfo->setText(tr("unkown key type")); // cast to int to avoid problems int li, lo, qi, qo, vi, vo; - li = mBobSettings.inLength; - lo = mBobSettings.outLength; - qi = mBobSettings.inQuantity; - qo = mBobSettings.outQuantity; - vi = mBobSettings.inVariance; - vo = mBobSettings.outVariance; + li = mSamSettings.inLength; + lo = mSamSettings.outLength; + qi = mSamSettings.inQuantity; + qo = mSamSettings.outQuantity; + vi = mSamSettings.inVariance; + vo = mSamSettings.outVariance; ui.sbBobLengthIn ->setValue(li); ui.sbBobLengthOut ->setValue(lo); @@ -1850,7 +1896,7 @@ void ServerPage::setUpBobElements() } } -void ServerPage::enableBobElements(bool enable) +void ServerPage::enableSamElements(bool enable) { if (enable) { ui.pbBobGenAddr->setEnabled(true); @@ -1863,13 +1909,13 @@ void ServerPage::enableBobElements(bool enable) ui.cb_enableBob->setToolTip(tr("")); } else { ui.pbBobGenAddr->setEnabled(false); - ui.pbBobGenAddr->setToolTip(tr("stop BOB tunnel first to generate a new key")); + ui.pbBobGenAddr->setToolTip(tr("stop SAM tunnel first to generate a new key")); ui.pbBobLoadKey->setEnabled(false); - ui.pbBobLoadKey->setToolTip(tr("stop BOB tunnel first to load a key")); + ui.pbBobLoadKey->setToolTip(tr("stop SAM tunnel first to load a key")); ui.cb_enableBob->setEnabled(false); - ui.cb_enableBob->setToolTip(tr("stop BOB tunnel first to disable BOB")); + ui.cb_enableBob->setToolTip(tr("stop SAM tunnel first to disable SAM")); } } @@ -1896,6 +1942,7 @@ void ServerPage::handleNetworkReply(QNetworkReply *reply) { int error = reply->error() ; + RS_INFO("error:", error); if(reply->isOpen() && error == QNetworkReply::SslHandshakeFailedError) updateInProxyIndicatorResult(true); else diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index de971881b..7d82f2190 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -34,7 +34,7 @@ #endif #include -#include +#include #include "retroshare-gui/configpage.h" #include "retroshare-gui/RsAutoUpdatePage.h" @@ -97,22 +97,19 @@ private slots: void handleNetworkReply(QNetworkReply *reply); void updateInProxyIndicator(); - // i2p bob - void startBOB(); - void restartBOB(); - void stopBOB(); + // i2p SAMv3 + void startSam(); + void restartSam(); + void stopSam(); void getNewKey(); void loadKey(); - void enableBob(bool checked); + void enableSam(bool checked); void tunnelSettingsChanged(int); - void toggleBobAdvancedSettings(bool checked); - - void syncI2PProxyPortNormal(int i); - void syncI2PProxyPortBob(int i); + void toggleSamAdvancedSettings(bool checked); void syncI2PProxyAddrNormal(QString); - void syncI2PProxyAddrBob(QString); + void syncI2PProxyAddrSam(QString); void connectionWithoutCert(); @@ -133,11 +130,11 @@ public: private: void loadCommon(); void saveCommon(); - void saveBob(); - void updateStatusBob(); + void saveSam(); + void updateStatusSam(); - void setUpBobElements(); - void enableBobElements(bool enable); + void setUpSamElements(); + void enableSamElements(bool enable); void updateInProxyIndicatorResult(bool success); @@ -160,8 +157,8 @@ private: bool mIsHiddenNode; uint32_t mHiddenType; - bobSettings mBobSettings; - bool mBobAccessible; // keeps track wether bob is accessable or not to en/disable the corresponding buttons + samSettings mSamSettings; + bool mSamAccessible; // keeps track wether SAM is accessable or not to en/disable the corresponding buttons RsEventsHandlerId_t mEventHandlerId; void handleEvent(std::shared_ptr event); diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 5ef7308b1..60abc5fd8 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -6,8 +6,8 @@ 0 0 - 712 - 502 + 738 + 579
    @@ -195,7 +195,7 @@
    - + Automatic (UPnP) @@ -214,7 +214,7 @@ - + 200 @@ -416,7 +416,224 @@ - + + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 154 + 154 + 154 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + border: 1px solid #DCDC41; border-radius: 6px; @@ -487,7 +704,7 @@ connecting when you have few friends. It also helps if you're behind a firewall or a VPN. - Allow RetroShare to ask my ip to these websites: + Allow RetroShare to ask my ip to these DNS servers: true @@ -502,6 +719,9 @@ behind a firewall or a VPN. 0 + + List of OpenDns servers used. + QAbstractItemView::NoEditTriggers @@ -665,7 +885,7 @@ behind a firewall or a VPN. - + 0 @@ -861,7 +1081,7 @@ You can connect to Hidden Nodes, even if you are running a standard Node, so why - + 0 @@ -908,9 +1128,9 @@ If you have issues connecting over Tor check the Tor logs too. - + - Automatic I2P/BOB + Automatic I2P @@ -918,7 +1138,7 @@ If you have issues connecting over Tor check the Tor logs too. - Enable I2P BOB - changing this requires a restart to fully take effect + Enable I2P SAMv3 - changing this requires a restart to fully take effect @@ -950,7 +1170,7 @@ If you have issues connecting over Tor check the Tor logs too. - I2P Basic Open Bridge + I2P Simple Anonymous Messaging @@ -982,21 +1202,17 @@ If you have issues connecting over Tor check the Tor logs too. - - - I2P proxy port + + + Qt::Horizontal - - - - - - 10 + + + 40 + 20 + - - 65535 - - + @@ -1016,7 +1232,7 @@ If you have issues connecting over Tor check the Tor logs too. <html><head/><body><p>This led is green when the port listen on the left is active on your computer. It does not</p><p>mean that your Retroshare traffic transits though I2P. It will do so only if </p><p>you connect to Hidden nodes, or if you are running a Hidden node yourself.</p></body></html> - BOB accessible + SAM accessible @@ -1073,12 +1289,12 @@ If you have issues connecting over Tor check the Tor logs too. true - 1 + 0 - + 0 @@ -1304,6 +1520,13 @@ If you have issues connecting over Tor check the Tor logs too. + + + + <key info> + + + @@ -1359,7 +1582,7 @@ If you have issues connecting over Tor check the Tor logs too. - BOB status + SAM status @@ -1959,13 +2182,230 @@ If you have issues connecting over Tor check the Tor logs too. - + 0 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 154 + 154 + 154 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + border: 1px solid #DCDC41; border-radius: 6px; @@ -2037,13 +2477,230 @@ If you have issues connecting over Tor check the Tor logs too. - + 0 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 154 + 154 + 154 + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + + + + 255 + 255 + 215 + + + + + 255 + 255 + 178 + + + + + + + + border: 1px solid #DCDC41; border-radius: 6px; @@ -2080,6 +2737,13 @@ If you have issues connecting over Tor check the Tor logs too. + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    localAddress localPort diff --git a/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp b/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp index 15a0bf70f..84df07589 100644 --- a/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp +++ b/retroshare-gui/src/gui/settings/ServicePermissionsPage.cpp @@ -35,10 +35,10 @@ ServicePermissionsPage::ServicePermissionsPage(QWidget * parent, Qt::WindowFlags ui.cb_hideOffline->setChecked(true); - connect(ui.cb_hideOffline, SIGNAL(toggled(bool)), ui.frame, SLOT(setHideOffline(bool))); + connect(ui.cb_hideOffline, SIGNAL(toggled(bool)), ui.gradFrame, SLOT(setHideOffline(bool))); //QObject::connect(ui.tableWidget,SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(tableItemChanged(QTableWidgetItem *))); - ui.frame->setHideOffline(ui.cb_hideOffline->isChecked()); + ui.gradFrame->setHideOffline(ui.cb_hideOffline->isChecked()); // Not implemented? ui.pushButton->hide(); diff --git a/retroshare-gui/src/gui/settings/ServicePermissionsPage.ui b/retroshare-gui/src/gui/settings/ServicePermissionsPage.ui index 488ba9518..2dd6f7bc1 100644 --- a/retroshare-gui/src/gui/settings/ServicePermissionsPage.ui +++ b/retroshare-gui/src/gui/settings/ServicePermissionsPage.ui @@ -10,7 +10,7 @@ 331 - + @@ -45,16 +45,16 @@ 0 - + - + - + ServicePermissions @@ -71,7 +71,7 @@ - + Qt::Horizontal diff --git a/retroshare-gui/src/gui/settings/TransferPage.cpp b/retroshare-gui/src/gui/settings/TransferPage.cpp index 2faa8d5f7..915eaa679 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.cpp +++ b/retroshare-gui/src/gui/settings/TransferPage.cpp @@ -30,6 +30,7 @@ #include "retroshare/rspeers.h" #include +#include #include #include @@ -40,6 +41,14 @@ TransferPage::TransferPage(QWidget * parent, Qt::WindowFlags flags) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); + int max_tr_low,max_tr_high; + rsTurtle->getMaxTRForwardRateLimits(max_tr_low,max_tr_high); + + ui._max_tr_up_per_sec_SB->setMinimum(max_tr_low); + ui._max_tr_up_per_sec_SB->setMaximum(max_tr_high); + + whileBlocking(ui._trustFriendNodesWithBannedFiles_CB)->setChecked(rsFiles->trustFriendNodesWithBannedFiles()); + QObject::connect(ui._queueSize_SB,SIGNAL(valueChanged(int)),this,SLOT(updateQueueSize(int))) ; QObject::connect(ui._max_up_SB,SIGNAL(valueChanged(int)),this,SLOT(updateMaxUploadSlots(int))) ; QObject::connect(ui._defaultStrategy_CB,SIGNAL(activated(int)),this,SLOT(updateDefaultStrategy(int))) ; @@ -47,12 +56,14 @@ TransferPage::TransferPage(QWidget * parent, Qt::WindowFlags flags) QObject::connect(ui._diskSpaceLimit_SB,SIGNAL(valueChanged(int)),this,SLOT(updateDiskSizeLimit(int))) ; QObject::connect(ui._max_tr_up_per_sec_SB, SIGNAL( valueChanged( int ) ), this, SLOT( updateMaxTRUpRate(int) ) ); QObject::connect(ui._filePermDirectDL_CB,SIGNAL(activated(int)),this,SLOT(updateFilePermDirectDL(int))); + QObject::connect(ui._trustFriendNodesWithBannedFiles_CB,SIGNAL(toggled(bool)),this,SLOT(toggleTrustFriendNodesWithBannedFiles(bool))) ; QObject::connect(ui.incomingButton, SIGNAL(clicked( bool ) ), this , SLOT( setIncomingDirectory() ) ); QObject::connect(ui.autoDLColl_CB, SIGNAL(toggled(bool)), this, SLOT(updateAutoDLColl())); QObject::connect(ui.partialButton, SIGNAL(clicked( bool ) ), this , SLOT( setPartialsDirectory() ) ); QObject::connect(ui.editShareButton, SIGNAL(clicked()), this, SLOT(editDirectories())); QObject::connect(ui.autoCheckDirectories_CB, SIGNAL(clicked(bool)), this, SLOT(toggleAutoCheckDirectories(bool))); + QObject::connect(ui.minimumFontSize_SB, SIGNAL(valueChanged(int)), this, SLOT(updateFontSize())) ; QObject::connect(ui.autoCheckDirectories_CB, SIGNAL(toggled(bool)), this,SLOT(updateAutoCheckDirectories())) ; QObject::connect(ui.autoCheckDirectoriesDelay_SB,SIGNAL(valueChanged(int)),this,SLOT(updateAutoScanDirectoriesPeriod())) ; @@ -87,7 +98,10 @@ void TransferPage::updateIgnoreLists() std::cerr << " suffixes: " ; for(auto it(ls.begin());it!=ls.end();++it) std::cerr << "\"" << *it << "\" " ; std::cerr << std::endl; #endif } - +void TransferPage::toggleTrustFriendNodesWithBannedFiles(bool b) +{ + rsFiles->setTrustFriendNodesWithBannedFiles(b); +} void TransferPage::updateMaxTRUpRate(int b) { rsTurtle->setMaxTRForwardRate(b) ; @@ -188,6 +202,10 @@ void TransferPage::load() whileBlocking(ui.suffixesIgnoreList_CB)->setChecked( ignore_flags & RS_FILE_SHARE_FLAGS_IGNORE_SUFFIXES ) ; whileBlocking(ui.prefixesIgnoreList_LE)->setText( ignore_prefixes_string ); whileBlocking(ui.suffixesIgnoreList_LE)->setText( ignore_suffixes_string ); + + Settings->beginGroup(QString("File")); + whileBlocking(ui.minimumFontSize_SB)->setValue( Settings->value("MinimumFontSize", 11 ).toInt()); + Settings->endGroup(); } void TransferPage::updateDefaultStrategy(int i) @@ -197,11 +215,19 @@ void TransferPage::updateDefaultStrategy(int i) case 0: rsFiles->setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_STREAMING) ; break ; - case 2: rsFiles->setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ; - break ; + case 2: +#ifdef WINDOWS_SYS + if(QMessageBox::Yes != QMessageBox::warning(nullptr,tr("Warning"),tr("On Windows systems, randomly writing in the middle of large empty files may hang the software for several seconds. Do you want to use this option anyway (otherwise use \"progressive\")?"),QMessageBox::Yes,QMessageBox::No)) + { + ui._defaultStrategy_CB->setCurrentIndex(1); + return; + } +#endif + rsFiles->setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) ; + break ; case 1: rsFiles->setDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_PROGRESSIVE) ; - break ; + break ; default: ; } } @@ -290,6 +316,13 @@ void TransferPage::editDirectories() ShareManager::showYourself() ; } +void TransferPage::updateFontSize() +{ + Settings->beginGroup(QString("File")); + Settings->setValue("MinimumFontSize", ui.minimumFontSize_SB->value()); + Settings->endGroup(); +} + void TransferPage::updateAutoCheckDirectories() { rsFiles->setWatchEnabled(ui.autoCheckDirectories_CB->isChecked()) ; } void TransferPage::updateAutoScanDirectoriesPeriod() { rsFiles->setWatchPeriod(ui.autoCheckDirectoriesDelay_SB->value()); } void TransferPage::updateShareDownloadDirectory() { rsFiles->shareDownloadDirectory(ui.shareDownloadDirectoryCB->isChecked());} diff --git a/retroshare-gui/src/gui/settings/TransferPage.h b/retroshare-gui/src/gui/settings/TransferPage.h index 19ceedfca..a2a0a1061 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.h +++ b/retroshare-gui/src/gui/settings/TransferPage.h @@ -58,6 +58,8 @@ class TransferPage: public ConfigPage void updateAutoDLColl(); void setPartialsDirectory(); void toggleAutoCheckDirectories(bool); + void toggleTrustFriendNodesWithBannedFiles(bool); + void updateFontSize(); void updateAutoCheckDirectories() ; void updateAutoScanDirectoriesPeriod() ; diff --git a/retroshare-gui/src/gui/settings/TransferPage.ui b/retroshare-gui/src/gui/settings/TransferPage.ui index 4c925ebb1..b6d8cd7ff 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.ui +++ b/retroshare-gui/src/gui/settings/TransferPage.ui @@ -7,14 +7,14 @@ 0 0 701 - 527 + 638 - 0 + 1 @@ -30,7 +30,7 @@ - Edit Share + Configure shared directories @@ -67,6 +67,9 @@ + + <html><head/><body><p>Retroshare will quickly scan shared directories for new/removed files. It will not detect changes in existing files for efficiency reasons. It is however possible to force a full re-scan of the entire hierarchy including possibly modified files using the &quot;check files&quot; button in shared files tab.</p></body></html> + minute(s) @@ -289,7 +292,7 @@ <!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:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; 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-family:'Sans'; font-size:8pt; font-weight:600;">RetroShare</span><span style=" font-family:'Sans'; font-size:8pt;"> is capable of transferring data and search requests between peers that are not necessarily friends. This traffic however only transits through a connected list of friends and is anonymous.</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-family:'Sans'; font-size:8pt;"><br /></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-family:'Sans'; font-size:8pt;">You can separately setup share flags for each shared directory in the shared files dialog to be:</span></p> @@ -299,6 +302,40 @@ p, li { white-space: pre-wrap; } + + + + + Minimum font size for Shared Files + + + + + + + 11 + + + 64 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::Vertical @@ -401,12 +438,12 @@ p, li { white-space: pre-wrap; } - + true - <html><head/><body><p><span style=" font-weight:600;">Streaming </span>causes the transfer to request 1MB file chunks in increasing order, facilitating preview while downloading. <span style=" font-weight:600;">Random</span> is purely random and favors swarming behavior. <span style=" font-weight:600;">Progressive</span> is a compromise, selecting the next chunk at random within less than 50MB after the end of the partial file. That allows some randomness while preventing large empty file initialization times.</p></body></html> + <html><head/><body><p><span style=" font-weight:600;">Streaming </span>causes the transfer to request 1MB file chunks in increasing order, facilitating preview while downloading. <span style=" font-weight:600;">Random</span> is purely random and favors swarming behavior (although not recommended on Windows systems). <span style=" font-weight:600;">Progressive</span> is a good compromise, selecting the next chunk at random within less than 50MB after the end of the partial file. That allows some randomness while preventing large empty file initialization times.</p></body></html> @@ -467,7 +504,7 @@ p, li { white-space: pre-wrap; } - + <html><head/><body><p>Anonymous tunnels can be end-o-end encrypted. In order to maintain backward compatibility, this can be made optional (choosing &quot;Accepted&quot;), but in the end, all Retroshare nodes will be switched to &quot;Enforced&quot;, meaning that all anonymous transfers will be end-to-end encrypted. With &quot;Accepted&quot;, it is likely that you will transfer using twice as many tunnels, since there is no way to know that an encrypted and a clear tunnel actually transfer from the same source.</p></body></html> @@ -484,7 +521,7 @@ p, li { white-space: pre-wrap; } - + <html><head/><body><p>How RS manage direct download setting.</p></body></html> @@ -510,7 +547,7 @@ p, li { white-space: pre-wrap; } - + Trust friend nodes with banned files @@ -538,6 +575,13 @@ p, li { white-space: pre-wrap; } + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/settings/WebuiPage.cpp b/retroshare-gui/src/gui/settings/WebuiPage.cpp index 8bdc11146..f0006fec3 100644 --- a/retroshare-gui/src/gui/settings/WebuiPage.cpp +++ b/retroshare-gui/src/gui/settings/WebuiPage.cpp @@ -65,6 +65,9 @@ void WebuiPage::selectWebInterfaceDirectory() return; whileBlocking(ui.webInterfaceFiles_LE)->setText(dirname); + + QString S; + updateParams(S); } bool WebuiPage::updateParams(QString &errmsg) @@ -82,6 +85,8 @@ bool WebuiPage::updateParams(QString &errmsg) // store config Settings->setWebinterfaceEnabled(ui.enableWebUI_CB->isChecked()); Settings->setWebinterfaceFilesDirectory(ui.webInterfaceFiles_LE->text()); + + rsWebUi->setHtmlFilesDirectory(ui.webInterfaceFiles_LE->text().toStdString()); } return ok; } @@ -196,6 +201,9 @@ void WebuiPage::onApplyClicked() { rsWebUi->setUserPassword(ui.password_LE->text().toStdString()); + QString errmsg; + updateParams(errmsg); + if(!restart()) { QMessageBox::warning(0, tr("failed to start Webinterface"), "Failed to start the webinterface."); diff --git a/retroshare-gui/src/gui/settings/rsettingswin.cpp b/retroshare-gui/src/gui/settings/rsettingswin.cpp index 6d3f10bbc..46c85ea8e 100644 --- a/retroshare-gui/src/gui/settings/rsettingswin.cpp +++ b/retroshare-gui/src/gui/settings/rsettingswin.cpp @@ -52,8 +52,6 @@ # include "JsonApiPage.h" #endif -#define IMAGE_GENERAL ":/images/kcmsystem24.png" - #define ITEM_SPACING 2 #include "rsettingswin.h" @@ -178,7 +176,7 @@ SettingsPage::initStackedWidget() addPage(new ServicePermissionsPage() ); // PERMISSIONS #ifdef RS_JSONAPI JsonApiPage *jsonapi_p = new JsonApiPage() ; - addPage(new JsonApiPage()); + addPage(jsonapi_p); #ifdef RS_WEBUI WebuiPage *webui_p = new WebuiPage() ; addPage(new WebuiPage() ); @@ -226,8 +224,8 @@ SettingsPage::setNewPage(int page) mHelpBrowser->clear(); return ; } - ui.pageName->setText(pagew->pageName()); - ui.pageicon->setPixmap(pagew->iconPixmap()) ; + ui.pageNameLabel->setText(pagew->pageName()); + ui.pageIconLabel->setPixmap(pagew->iconPixmap()) ; ui.stackedWidget->setCurrentIndex(page); ui.listWidget->setCurrentRow(page); diff --git a/retroshare-gui/src/gui/settings/rsettingswin.h b/retroshare-gui/src/gui/settings/rsettingswin.h index a3242aaa4..74fb0d40c 100755 --- a/retroshare-gui/src/gui/settings/rsettingswin.h +++ b/retroshare-gui/src/gui/settings/rsettingswin.h @@ -30,7 +30,7 @@ class FloatingHelpBrowser; -#define IMAGE_PREFERENCES ":/icons/png/options.png" +#define PREF_IMAGE_PREFERENCES ":/icons/png/options.png" class SettingsPage: public MainPage { @@ -46,7 +46,7 @@ public: void postModDirectories(bool update_local); - virtual QIcon iconPixmap() const { return FilesDefs::getIconFromQtResourcePath(IMAGE_PREFERENCES) ; } //MainPage + virtual QIcon iconPixmap() const { return FilesDefs::getIconFromQtResourcePath(PREF_IMAGE_PREFERENCES) ; } //MainPage virtual QString pageName() const { return tr("Preferences") ; } //MainPage protected: diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp index 86a93559e..586d4df4f 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.cpp +++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp @@ -129,7 +129,7 @@ void RshareSettings::initSettings() #endif setDefault(SETTING_LANGUAGE, LanguageSupport::defaultLanguageCode()); - setDefault(SETTING_SHEETNAME, ":Standard"); + setDefault(SETTING_SHEETNAME, ":Standard_Light"); /* defaults here are not ideal.... but dusent matter */ @@ -537,6 +537,16 @@ void RshareSettings::setChatSendAsPlainTextByDef(bool bValue) setValueToGroup("Chat", "SendAsPlainTextByDef", bValue); } +bool RshareSettings::getShrinkChatTextEdit() +{ + return valueFromGroup("Chat", "ShrinkChatTextEdit", false).toBool(); +} + +void RshareSettings::setShrinkChatTextEdit(bool bValue) +{ + setValueToGroup("Chat", "ShrinkChatTextEdit", bValue); +} + bool RshareSettings::getChatSearchShowBarByDefault() { return valueFromGroup("Chat", "SearchShowBarByDefault", false).toBool(); diff --git a/retroshare-gui/src/gui/settings/rsharesettings.h b/retroshare-gui/src/gui/settings/rsharesettings.h index abf728391..362e52606 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.h +++ b/retroshare-gui/src/gui/settings/rsharesettings.h @@ -217,6 +217,9 @@ public: bool getChatSendAsPlainTextByDef(); void setChatSendAsPlainTextByDef(bool bValue); + bool getShrinkChatTextEdit(); + void setShrinkChatTextEdit(bool bValue); + bool getChatSearchShowBarByDefault(); void setChatSearchShowBarByDefault(bool bValue); diff --git a/retroshare-gui/src/gui/settings/settings.ui b/retroshare-gui/src/gui/settings/settings.ui index 8d774dce2..18b910fb3 100755 --- a/retroshare-gui/src/gui/settings/settings.ui +++ b/retroshare-gui/src/gui/settings/settings.ui @@ -47,7 +47,7 @@ - + 0 @@ -56,6 +56,7 @@ + 12 75 true @@ -66,7 +67,7 @@ - + 24 @@ -215,13 +216,6 @@ - - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    diff --git a/retroshare-gui/src/gui/settings/settingsw.ui b/retroshare-gui/src/gui/settings/settingsw.ui index fa6f197db..d1cbd3caf 100644 --- a/retroshare-gui/src/gui/settings/settingsw.ui +++ b/retroshare-gui/src/gui/settings/settingsw.ui @@ -78,7 +78,7 @@
    - + 24 @@ -91,7 +91,7 @@ - + 0 @@ -100,6 +100,7 @@ + 12 75 true @@ -169,13 +170,6 @@
    - - - StyledLabel - QLabel -
    gui/common/StyledLabel.h
    -
    -
    diff --git a/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.cpp b/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.cpp index 87a87a5f8..f621d355b 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.cpp +++ b/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.cpp @@ -42,7 +42,7 @@ #define DEFAULT_ALWAYS_ON_TOP false #define DEFAULT_OPACITY 100 #define DEFAULT_STYLE LineGraph -#define DEFAULT_GRAPHCOLOR DefaultColor +#define DEFAULT_GRAPHCOLOR false #define DEFAULT_DIRECTION DefaultDirection #define ADD_TO_FILTER(f,v,b) (f = ((b) ? ((f) | (v)) : ((f) & ~(v)))) @@ -135,16 +135,16 @@ void BandwidthGraph::toggleReceiveRate(bool b) void BandwidthGraph::switchGraphColor() { - if(ui.frmGraph->getFlags() & RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE) - { - ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE); - ui.btnGraphColor->setIcon(FilesDefs::getIconFromQtResourcePath(IMG_GRAPH_LIGHT)); - } - else + if(ui.btnGraphColor->isChecked()) { ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE); ui.btnGraphColor->setIcon(FilesDefs::getIconFromQtResourcePath(IMG_GRAPH_DARK)); } + else + { + ui.frmGraph->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE); + ui.btnGraphColor->setIcon(FilesDefs::getIconFromQtResourcePath(IMG_GRAPH_LIGHT)); + } saveSettings(); } @@ -158,9 +158,9 @@ BandwidthGraph::loadSettings() setOpacity(ui.sldrOpacity->value()); /* Set whether we are plotting bandwidth as area graphs or not */ - int graphColor = getSetting(SETTING_GRAPHCOLOR, DEFAULT_GRAPHCOLOR).toInt(); + ui.btnGraphColor->setChecked(getSetting(SETTING_GRAPHCOLOR, DEFAULT_GRAPHCOLOR).toBool()); - if(graphColor>0) + if(ui.btnGraphColor->isChecked()) { ui.frmGraph->setFlags(RSGraphWidget::RSGRAPH_FLAGS_DARK_STYLE); ui.btnGraphColor->setIcon(FilesDefs::getIconFromQtResourcePath(IMG_GRAPH_DARK)); diff --git a/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.ui b/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.ui index 56f1818f8..17d2ee6c5 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.ui +++ b/retroshare-gui/src/gui/statistics/BandwidthGraphWindow.ui @@ -61,7 +61,7 @@ PushButton - false + true
    @@ -180,7 +180,15 @@ QFrame::Raised - + + + + 0 + 0 + 218 + 88 + + 1 diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h index c0ae4b4b2..0445ab76f 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.h @@ -18,6 +18,8 @@ * * *******************************************************************************/ +#pragma once + #include "ui_BandwidthStatsWidget.h" #include "BWGraph.h" diff --git a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui index dc36efbad..f62171aa1 100644 --- a/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui +++ b/retroshare-gui/src/gui/statistics/BandwidthStatsWidget.ui @@ -49,7 +49,7 @@ - + 0 @@ -69,7 +69,7 @@ - + Up @@ -90,7 +90,7 @@ - + 0 @@ -110,7 +110,7 @@ - + @@ -120,7 +120,7 @@ - + Current @@ -141,7 +141,7 @@ - + Default @@ -179,6 +179,11 @@
    gui/statistics/BWGraph.h
    1 + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    diff --git a/retroshare-gui/src/gui/statistics/GxsIdStatistics.cpp b/retroshare-gui/src/gui/statistics/GxsIdStatistics.cpp index c7fe1068c..3037839c2 100644 --- a/retroshare-gui/src/gui/statistics/GxsIdStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GxsIdStatistics.cpp @@ -44,6 +44,7 @@ #include "util/misc.h" #include "util/qtthreadsutils.h" +#ifdef TODO static QColor colorScale(float f) { if(f == 0) @@ -51,6 +52,7 @@ static QColor colorScale(float f) else return QColor::fromHsv((int)((1.0-f)*280),200,255) ; } +#endif GxsIdStatistics::GxsIdStatistics(QWidget *parent) : RsAutoUpdatePage(4000,parent) diff --git a/retroshare-gui/src/gui/statistics/Histogram.cpp b/retroshare-gui/src/gui/statistics/Histogram.cpp index 6cd1c4906..77e272b31 100644 --- a/retroshare-gui/src/gui/statistics/Histogram.cpp +++ b/retroshare-gui/src/gui/statistics/Histogram.cpp @@ -33,15 +33,15 @@ Histogram::Histogram(double start, double end, int bins) std::cerr << "Null histogram created! Please check your parameters" << std::endl; } -void Histogram::draw(QPainter *painter) const +void Histogram::draw(QPainter */*painter*/) const { } void Histogram::insert(double val) { - long int bin = (uint32_t)floor((val - mStart)/(mEnd - mStart) * mBins.size()); + long int bin = (long int)floor((val - mStart)/(mEnd - mStart) * mBins.size()); - if(bin >= 0 && bin < mBins.size()) + if(bin >= 0 && bin < (long int)mBins.size()) ++mBins[bin]; } diff --git a/retroshare-gui/src/gui/statistics/Histogram.h b/retroshare-gui/src/gui/statistics/Histogram.h index ca71d3b82..3931b15db 100644 --- a/retroshare-gui/src/gui/statistics/Histogram.h +++ b/retroshare-gui/src/gui/statistics/Histogram.h @@ -20,6 +20,7 @@ #include #include +#include class QPainter; diff --git a/retroshare-gui/src/gui/statusbar/OpModeStatus.cpp b/retroshare-gui/src/gui/statusbar/OpModeStatus.cpp index f44f6d29c..994974342 100644 --- a/retroshare-gui/src/gui/statusbar/OpModeStatus.cpp +++ b/retroshare-gui/src/gui/statusbar/OpModeStatus.cpp @@ -30,7 +30,7 @@ #include OpModeStatus::OpModeStatus(QWidget *parent) - : QComboBox(parent) + : RSComboBox(parent) { onUpdate = false; opMode_Full_Color = QColor("#CCFFCC"); diff --git a/retroshare-gui/src/gui/statusbar/OpModeStatus.h b/retroshare-gui/src/gui/statusbar/OpModeStatus.h index 80fc111a5..9ffe282a3 100644 --- a/retroshare-gui/src/gui/statusbar/OpModeStatus.h +++ b/retroshare-gui/src/gui/statusbar/OpModeStatus.h @@ -21,9 +21,9 @@ #ifndef OP_MODE_STATUS_H #define OP_MODE_STATUS_H -#include +#include "gui/common/RSComboBox.h" -class OpModeStatus : public QComboBox +class OpModeStatus : public RSComboBox { Q_OBJECT Q_PROPERTY(QColor opMode_Full_Color READ getOpMode_Full_Color WRITE setOpMode_Full_Color DESIGNABLE true) diff --git a/retroshare-gui/src/gui/statusbar/torstatus.cpp b/retroshare-gui/src/gui/statusbar/torstatus.cpp index f046f09cc..d43de1df3 100644 --- a/retroshare-gui/src/gui/statusbar/torstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/torstatus.cpp @@ -28,11 +28,10 @@ #include "retroshare/rsconfig.h" #include "retroshare/rsinit.h" #include "retroshare/rspeers.h" +#include "retroshare/rstor.h" #include #include "util/misc.h" -#include "TorControl/TorManager.h" -#include "TorControl/TorControl.h" #include "gui/common/FilesDefs.h" #include @@ -92,8 +91,8 @@ void TorStatus::getTorStatus() if(RsAccounts::isTorAuto()) { // get Tor status - int tor_control_status = Tor::TorManager::instance()->control()->status(); - int torstatus = Tor::TorManager::instance()->control()->torStatus(); + RsTorConnectivityStatus tor_control_status = RsTor::torConnectivityStatus(); + RsTorStatus torstatus = RsTor::torStatus(); QString tor_control_status_str,torstatus_str ; bool tor_control_ok ; @@ -101,30 +100,31 @@ void TorStatus::getTorStatus() switch(tor_control_status) { default: - case Tor::TorControl::Error : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; - case Tor::TorControl::NotConnected: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; - case Tor::TorControl::Connecting: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; - case Tor::TorControl::Authenticating: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; - case Tor::TorControl::Connected: tor_control_ok = true ; tor_control_status_str = "Connected" ; break ; - } + case RsTorConnectivityStatus::ERROR : tor_control_ok = false ; tor_control_status_str = "Error" ; break ; + case RsTorConnectivityStatus::NOT_CONNECTED: tor_control_ok = false ; tor_control_status_str = "Not connected" ; break ; + case RsTorConnectivityStatus::CONNECTING: tor_control_ok = false ; tor_control_status_str = "Connecting" ; break ; + case RsTorConnectivityStatus::AUTHENTICATING: tor_control_ok = false ; tor_control_status_str = "Authenticating" ; break ; + case RsTorConnectivityStatus::AUTHENTICATED: tor_control_ok = false ; tor_control_status_str = "Connected" ; break ; + case RsTorConnectivityStatus::HIDDEN_SERVICE_READY: tor_control_ok = true ; tor_control_status_str = "Hidden service ready" ; break ; + } switch(torstatus) { default: - case Tor::TorControl::TorUnknown: torstatus_str = "Unknown" ; break ; - case Tor::TorControl::TorOffline: torstatus_str = "Tor offline" ; break ; - case Tor::TorControl::TorReady: torstatus_str = "Tor ready" ; break ; + case RsTorStatus::UNKNOWN: torstatus_str = "Unknown" ; break ; + case RsTorStatus::OFFLINE: torstatus_str = "Tor offline" ; break ; + case RsTorStatus::READY: torstatus_str = "Tor ready" ; break ; } #define MIN_RS_NET_SIZE 10 - if(torstatus == Tor::TorControl::TorOffline || !online || !tor_control_ok) + if(torstatus == RsTorStatus::OFFLINE || !online || !tor_control_ok) { // RED - some issue. torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-stopping.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is currently offline")); } - else if(torstatus == Tor::TorControl::TorReady && online && tor_control_ok) + else if(torstatus == RsTorStatus::READY && online && tor_control_ok) { torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tor-on.png").scaledToHeight(1.5*S,Qt::SmoothTransformation)); torstatusLabel->setToolTip( text + tr("Tor is OK")); @@ -141,12 +141,12 @@ void TorStatus::getTorStatus() if(!_updated) { RsPeerDetails pd; - uint32_t hiddentype; - if (rsPeers->getPeerDetails(rsPeers->getOwnId(), pd)) { + uint32_t hiddentype = RS_HIDDEN_TYPE_UNKNOWN; + + if (rsPeers->getPeerDetails(rsPeers->getOwnId(), pd)) + { if(pd.netMode == RS_NETMODE_HIDDEN) - { hiddentype = pd.hiddenType; - } } std::string proxyaddr; uint16_t proxyport; @@ -168,7 +168,7 @@ void TorStatus::getTorStatus() torstatusLabel->setToolTip( text + tr("Tor proxy is not available")); } } - if(hiddentype == RS_HIDDEN_TYPE_I2P) + else if(hiddentype == RS_HIDDEN_TYPE_I2P) { statusTor->setText("" + tr("I2P") + ":"); rsPeers->getProxyServer(RS_HIDDEN_TYPE_I2P, proxyaddr, proxyport, status); @@ -185,6 +185,11 @@ void TorStatus::getTorStatus() torstatusLabel->setToolTip( text + tr("i2p proxy is not available")); } } + else + { + torstatusLabel->setPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/tile_inactive_48.png").scaledToHeight(S,Qt::SmoothTransformation)); + torstatusLabel->setToolTip(tr("No tor configuration")); + } _updated = true; } } diff --git a/retroshare-gui/src/gui/style/StyleDialog.ui b/retroshare-gui/src/gui/style/StyleDialog.ui index 312453628..1da590d9b 100644 --- a/retroshare-gui/src/gui/style/StyleDialog.ui +++ b/retroshare-gui/src/gui/style/StyleDialog.ui @@ -102,7 +102,7 @@
    - + 0 @@ -183,6 +183,11 @@
    gui/common/HeaderFrame.h
    1 + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    diff --git a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.ui b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.ui index b6408ed93..e45b87103 100644 --- a/retroshare-gui/src/gui/toaster/ChatLobbyToaster.ui +++ b/retroshare-gui/src/gui/toaster/ChatLobbyToaster.ui @@ -22,30 +22,48 @@ 100
    - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + Name - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/toaster/ChatToaster.ui b/retroshare-gui/src/gui/toaster/ChatToaster.ui index 8b517684b..1c6ee5ae2 100644 --- a/retroshare-gui/src/gui/toaster/ChatToaster.ui +++ b/retroshare-gui/src/gui/toaster/ChatToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + Name - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/toaster/DownloadToaster.ui b/retroshare-gui/src/gui/toaster/DownloadToaster.ui index de68906b7..86ef2a666 100644 --- a/retroshare-gui/src/gui/toaster/DownloadToaster.ui +++ b/retroshare-gui/src/gui/toaster/DownloadToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -82,13 +100,20 @@ + + + 12 + 75 + true + + Download completed - + Qt::Horizontal @@ -126,7 +151,7 @@ - + diff --git a/retroshare-gui/src/gui/toaster/FriendRequestToaster.ui b/retroshare-gui/src/gui/toaster/FriendRequestToaster.ui index ae203707a..e420b68b4 100644 --- a/retroshare-gui/src/gui/toaster/FriendRequestToaster.ui +++ b/retroshare-gui/src/gui/toaster/FriendRequestToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + Friend Request - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/toaster/GroupChatToaster.ui b/retroshare-gui/src/gui/toaster/GroupChatToaster.ui index 83ffdfd9a..9f701023a 100644 --- a/retroshare-gui/src/gui/toaster/GroupChatToaster.ui +++ b/retroshare-gui/src/gui/toaster/GroupChatToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + Name - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/toaster/MessageToaster.cpp b/retroshare-gui/src/gui/toaster/MessageToaster.cpp index 93772ca68..1f4894ba3 100644 --- a/retroshare-gui/src/gui/toaster/MessageToaster.cpp +++ b/retroshare-gui/src/gui/toaster/MessageToaster.cpp @@ -21,7 +21,11 @@ #include "MessageToaster.h" #include "../MainWindow.h" +#include #include +#include + +#include "gui/msgs/MessageInterface.h" MessageToaster::MessageToaster(const std::string &peerId, const QString &title, const QString &message) : QWidget(NULL) { @@ -39,8 +43,24 @@ MessageToaster::MessageToaster(const std::string &peerId, const QString &title, ui.textLabel->setText(message); ui.textLabel->setToolTip(message); - std::string name = (!RsPeerId(peerId).isNull())? (rsPeers->getPeerName(RsPeerId(peerId))): (rsPeers->getGPGName(RsPgpId(peerId))) ; - ui.toasterLabel->setText(ui.toasterLabel->text() + " " + QString::fromUtf8(name.c_str())); + MessageInfo mi; + + if (!rsMail->getMessage(peerId, mi)) + return; + + QString srcName; + + if(mi.msgflags & RS_MSG_DISTANT) + { + RsIdentityDetails details ; + rsIdentity->getIdDetails(mi.from.toGxsId(), details) ; + + srcName = QString::fromUtf8(details.mNickname.c_str()); + } + else + srcName = QString::fromUtf8(rsPeers->getPeerName(mi.from.toRsPeerId()).c_str()); + + ui.toasterLabel->setText(ui.toasterLabel->text() + " " + srcName); } void MessageToaster::openmessageClicked() diff --git a/retroshare-gui/src/gui/toaster/MessageToaster.ui b/retroshare-gui/src/gui/toaster/MessageToaster.ui index 89dcb79a4..1dce4be57 100644 --- a/retroshare-gui/src/gui/toaster/MessageToaster.ui +++ b/retroshare-gui/src/gui/toaster/MessageToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + 1 new Message from - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/toaster/OnlineToaster.ui b/retroshare-gui/src/gui/toaster/OnlineToaster.ui index a40f9f80c..248870e66 100644 --- a/retroshare-gui/src/gui/toaster/OnlineToaster.ui +++ b/retroshare-gui/src/gui/toaster/OnlineToaster.ui @@ -22,30 +22,48 @@ 100 - + 0 - + + 0 + + + 0 + + + 0 + + 0 - + QFrame::WinPanel QFrame::Raised - - + + + 2 + + + 2 + + + 2 + + 2 2 - + 6 @@ -79,13 +97,20 @@ + + + 12 + 75 + true + + RetroShare - + Qt::Horizontal @@ -123,7 +148,7 @@ - + 2 diff --git a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui index ffa98afbd..df4f39a2c 100644 --- a/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui +++ b/retroshare-gui/src/gui/unfinished/ApplicationWindow.ui @@ -53,6 +53,15 @@ + + + + 0 + 0 + 0 + + + @@ -73,6 +82,15 @@ + + + + 0 + 0 + 0 + + + @@ -93,6 +111,15 @@ + + + + 154 + 154 + 154 + + + diff --git a/retroshare-gui/src/gui/unfinished/CalDialog.ui b/retroshare-gui/src/gui/unfinished/CalDialog.ui index 8615caa12..598e7f870 100644 --- a/retroshare-gui/src/gui/unfinished/CalDialog.ui +++ b/retroshare-gui/src/gui/unfinished/CalDialog.ui @@ -1,7 +1,8 @@ - + + CalDialog - - + + 0 0 @@ -9,76 +10,68 @@ 540 - + Form - - + + 0 - + 6 - + 0 - + 6 - + 0 - - - + + + QTabWidget::Rounded - + 0 - + Qt::ElideNone - - - - 0 - 0 - 734 - 501 - - - + + Local Calendars - - - - + + + + QLayout::SetMaximumSize - - - + + + 75 true - + Shared Calendar List - - - - + + + + 0 0 - + 289 0 @@ -88,154 +81,154 @@ - - - + + + 75 true - + Share Details - - - + + + QLayout::SetMaximumSize - - - + + + Name: - - + + - - - + + + Location: - - - + + + QLayout::SetMaximumSize - - - - + + + + 0 0 - - - - + + + + 0 0 - + 30 0 - + 0 16777215 - + 0 0 - + ... - - - + + + Status: - - - + + + 100 0 - + 0 16777215 - + Private - + Public - - - + + + Allow List: - + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - + + - - <Disabled> + + <Disabled> - - - + + + QLayout::SetMaximumSize - + Qt::Horizontal - + 40 20 @@ -244,15 +237,15 @@ - - + + Add - - + + Remove @@ -261,16 +254,8 @@ - - - - 26 - 45 - 760 - 509 - - - + + Peer Calendars @@ -278,8 +263,15 @@ + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    - +
    diff --git a/retroshare-gui/src/gui/unfinished/GamesDialog.ui b/retroshare-gui/src/gui/unfinished/GamesDialog.ui index 074504d9d..95c5a4daf 100644 --- a/retroshare-gui/src/gui/unfinished/GamesDialog.ui +++ b/retroshare-gui/src/gui/unfinished/GamesDialog.ui @@ -77,7 +77,7 @@ p, li { white-space: pre-wrap; }
    - + GameType: 0. Want to Add your Game here? @@ -326,6 +326,13 @@ p, li { white-space: pre-wrap; }
    + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/unfinished/LibraryDialog.ui b/retroshare-gui/src/gui/unfinished/LibraryDialog.ui index da20212c0..e7bb8319a 100644 --- a/retroshare-gui/src/gui/unfinished/LibraryDialog.ui +++ b/retroshare-gui/src/gui/unfinished/LibraryDialog.ui @@ -169,7 +169,7 @@
    - + 0 @@ -805,6 +805,13 @@ p, li { white-space: pre-wrap; }
    + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    diff --git a/retroshare-gui/src/gui/unfinished/PhotoDialog.cpp b/retroshare-gui/src/gui/unfinished/PhotoDialog.cpp index 42fd5acee..83009c267 100644 --- a/retroshare-gui/src/gui/unfinished/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/unfinished/PhotoDialog.cpp @@ -42,7 +42,7 @@ /* Images for context menu icons */ #define IMAGE_REMOVEFRIEND ":/images/removefriend16.png" -#define IMAGE_REMOVE ":/images/cancel.png" +#define IMAGE_REMOVE ":/icons/cancel.svg" #define IMAGE_CHAT ":/images/chat.png" /* Images for Status icons */ #define IMAGE_PEER ":/images/user/identity16.png" diff --git a/retroshare-gui/src/gui/unfinished/PhotoShow.ui b/retroshare-gui/src/gui/unfinished/PhotoShow.ui index 112a63e4d..49e0be621 100644 --- a/retroshare-gui/src/gui/unfinished/PhotoShow.ui +++ b/retroshare-gui/src/gui/unfinished/PhotoShow.ui @@ -68,7 +68,7 @@ - + 320 x 320 @@ -94,7 +94,7 @@ - + 1 Sec @@ -243,8 +243,15 @@ + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    - + diff --git a/retroshare-gui/src/gui/unfinished/StatisticDialog.ui b/retroshare-gui/src/gui/unfinished/StatisticDialog.ui index 9543c0b83..6904b8b8f 100644 --- a/retroshare-gui/src/gui/unfinished/StatisticDialog.ui +++ b/retroshare-gui/src/gui/unfinished/StatisticDialog.ui @@ -486,7 +486,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -496,7 +505,7 @@ - + 0 0 @@ -862,9 +871,9 @@
    - + - + 1 0 @@ -879,11 +888,20 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 - + 120 @@ -900,7 +918,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -938,7 +965,7 @@ - + 0 0 @@ -968,7 +995,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -976,7 +1012,16 @@ 6 - + + 3 + + + 3 + + + 3 + + 3 @@ -1060,7 +1105,16 @@ 3 - + + 0 + + + 0 + + + 0 + + 0 @@ -1068,7 +1122,16 @@ 0 - + + 0 + + + 0 + + + 0 + + 0 @@ -1173,7 +1236,16 @@ 1 - + + 0 + + + 0 + + + 0 + + 0 diff --git a/retroshare-gui/src/gui/unfinished/profile/ProfileEdit.ui b/retroshare-gui/src/gui/unfinished/profile/ProfileEdit.ui index a4cdaf000..d1ff3203a 100644 --- a/retroshare-gui/src/gui/unfinished/profile/ProfileEdit.ui +++ b/retroshare-gui/src/gui/unfinished/profile/ProfileEdit.ui @@ -1,56 +1,57 @@ - + + ProfileEdit - - + + 0 0 - 540 + 571 469 - + Profile Edit - + Qt::LeftToRight - - - - + + + + Qt::Vertical - - + + - - + + 75 true - + Profile - - + + Qt::CustomContextMenu - + false - + Category - + Thoughts @@ -58,99 +59,99 @@ - - - - - + + + + + 75 true - + Edit Profile Category - - + + - + Birthday - + School - + University - + Phone Number - + Favourite Books - + Favourite Music - + Favourite Films - - - + + + Qt::RightToLeft - + or Custom Entry - - + + - - + + - - + + - - + + Add Entry - - + + :/images/add_24x24.png:/images/add_24x24.png - + Qt::Horizontal - + 71 28 @@ -159,36 +160,36 @@ - - + + Qt::RightToLeft - + Move - - + + :/images/down.png:/images/down.png - - + + Move - - + + :/images/up.png:/images/up.png - + Qt::Horizontal - + 71 28 @@ -197,15 +198,15 @@ - - + + Qt::RightToLeft - + Close Editor - - + + :/images/close_normal.png:/images/close_normal.png @@ -214,8 +215,15 @@ + + + RSComboBox + QComboBox +
    gui/common/RSComboBox.h
    +
    +
    - +
    diff --git a/retroshare-gui/src/lang/retroshare_af.ts b/retroshare-gui/src/lang/retroshare_af.ts index 450f45326..8848041e8 100644 --- a/retroshare-gui/src/lang/retroshare_af.ts +++ b/retroshare-gui/src/lang/retroshare_af.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: - + Location: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13794,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13806,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13884,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13964,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14049,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14138,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14149,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14159,7 @@ Do you want to save message ? - + from @@ -13829,6 +14168,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14472,7 @@ Reported error: - + Groups @@ -14158,19 +14502,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14524,7 @@ Reported error: - + Show Items @@ -14379,18 +14723,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14772,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14786,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14797,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14858,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14894,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14941,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15021,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15031,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15158,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15218,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15242,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15252,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15277,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15343,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15375,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15420,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15627,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15644,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15776,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15812,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15840,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15854,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15939,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15979,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16203,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16539,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16670,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16686,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16707,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16722,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16783,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16442,13 +16806,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16458,60 +16816,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16522,7 +16870,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16591,7 +16939,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16626,7 +16979,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16742,8 +17095,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17011,12 +17374,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17031,17 +17389,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17066,10 +17439,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17079,13 +17462,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17097,10 +17515,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17108,44 +17534,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17155,17 +17581,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17175,7 +17601,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17198,7 +17624,7 @@ and use the import button to load it - + follow Parent Group @@ -17208,7 +17634,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17233,7 +17659,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17269,29 +17695,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17369,7 +17795,7 @@ and use the import button to load it QObject - + Confirmation @@ -17608,7 +18034,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17643,7 +18069,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17781,7 +18207,7 @@ Reported error is: - + TR up @@ -17826,7 +18252,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17842,7 +18268,7 @@ Reported error is: - + %1 seconds ago @@ -17926,7 +18352,7 @@ Security: no anonymous IDs - + Error @@ -18316,11 +18742,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18654,7 +19075,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18876,18 +19297,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19324,7 +19766,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19339,7 +19781,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19387,7 +19829,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19402,7 +19844,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19417,12 +19859,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19669,7 +20111,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19689,7 +20131,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19702,10 +20144,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19717,7 +20164,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19755,7 +20202,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19763,7 +20210,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19823,7 +20270,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20177,7 +20624,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20256,7 +20703,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20276,7 +20723,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20381,12 +20828,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20396,7 +20843,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20659,13 +21106,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21131,7 +21578,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21159,7 +21606,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21256,7 +21703,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21291,12 +21738,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21961,7 +22408,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22003,7 +22450,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22059,7 +22506,7 @@ This choice can be reverted in settings. - + DHT @@ -22591,7 +23038,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22601,13 +23048,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22616,6 +23062,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22889,27 +23360,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22917,7 +23383,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22928,7 +23394,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23135,7 +23601,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23229,7 +23695,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23361,7 +23827,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23372,7 +23838,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23382,7 +23848,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23392,7 +23858,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23407,7 +23873,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23649,7 +24115,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23745,7 +24211,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24113,7 +24579,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24207,8 +24673,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24219,7 +24685,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24244,12 +24710,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24269,7 +24735,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24307,7 +24773,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24317,12 +24783,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24357,12 +24818,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24392,7 +24853,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24402,7 +24863,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24414,7 +24875,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24422,7 +24883,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24503,8 +24964,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24533,6 +24994,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24645,7 +25111,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_bg.ts b/retroshare-gui/src/lang/retroshare_bg.ts index d912bc552..86615025a 100644 --- a/retroshare-gui/src/lang/retroshare_bg.ts +++ b/retroshare-gui/src/lang/retroshare_bg.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -128,12 +128,12 @@ - + Search Criteria - + Add a further search criterion. @@ -178,7 +178,7 @@ AlbumDialog - + Album @@ -297,7 +297,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -340,8 +340,8 @@ p, li { white-space: pre-wrap; } Формуляр - - + + TextLabel @@ -408,7 +408,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -433,7 +433,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -458,7 +458,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -533,7 +533,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -548,7 +548,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -614,13 +614,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -629,25 +634,30 @@ p, li { white-space: pre-wrap; } Премахване на - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -655,7 +665,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -675,44 +685,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Настройки + TextLabel + + + + Reset Връщане - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -722,30 +741,23 @@ p, li { white-space: pre-wrap; } - Save - Запазване + Запазване - Cancel - Отмяна + Отмяна - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -767,7 +779,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -901,7 +913,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -979,6 +991,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Разширяване + + + + Set as read and remove item + Задай като четене и премахване на елемент + + + + Remove Item + Премахни елемент + + + + Name + Име + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Скрий + + BwCtrlWindow @@ -1114,6 +1205,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + По подразбиране + + + + Dark + + ChannelPage @@ -1166,6 +1267,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + Разширяване + + + + Set as read and remove item + Задай като четене и премахване на елемент + + + + Remove Item + Премахни елемент + + + + Name + Име + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + Скрий + + ChatLobbyDialog @@ -1374,22 +1554,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1403,11 +1583,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1832,13 +2007,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1903,17 +2072,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1934,11 +2098,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1999,11 +2164,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2142,8 +2313,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2312,7 +2498,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2329,12 +2515,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2406,7 +2592,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2442,12 +2628,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2463,7 +2649,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2483,7 +2669,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2641,12 +2827,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2657,12 +2843,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2678,31 +2864,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2718,22 +2914,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2768,13 +2964,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2789,7 +2990,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2800,17 +3001,22 @@ Double click on it to add his name on text writer. без - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2820,7 +3026,7 @@ Double click on it to add his name on text writer. - + with @@ -2904,32 +3110,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Име: - + Location: - + Options Настройки - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2939,7 +3145,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2964,12 +3170,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2989,32 +3195,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3060,17 +3266,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3090,12 +3296,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3143,7 +3349,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3187,12 +3423,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3222,7 +3458,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3280,12 +3516,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3360,7 +3596,12 @@ even if you don't make friends. - + + Status + Статус + + + <!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; } @@ -3782,7 +4023,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3926,7 +4167,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3941,7 +4182,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3957,7 +4198,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3973,12 +4214,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4000,7 +4241,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4126,7 +4367,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4172,7 +4413,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4182,7 +4423,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4209,17 +4450,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4250,12 +4511,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4275,7 +4536,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4363,7 +4624,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4778,7 +5039,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5781,7 +6042,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6272,7 +6533,7 @@ at least one peer was not added to a group - + Mark all @@ -6286,7 +6547,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6390,7 +6651,7 @@ at least one peer was not added to a group - + Network @@ -6455,7 +6716,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6486,7 +6747,7 @@ at least one peer was not added to a group - + Node name @@ -6745,12 +7006,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7113,7 +7374,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7178,7 +7439,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7201,7 +7462,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7402,7 +7663,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Заглавие @@ -7412,13 +7673,30 @@ p, li { white-space: pre-wrap; } Търсене в заглавието - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7428,42 +7706,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7478,40 +7721,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Име - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7660,7 +7894,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7681,12 +7915,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8083,7 +8317,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8183,12 +8417,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8199,18 +8433,18 @@ p, li { white-space: pre-wrap; } - + Feeds Информационни канали - - + + Click to switch to list view - + Show unread posts only @@ -8220,12 +8454,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8285,7 +8519,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8300,12 +8534,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8381,23 +8615,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8419,11 +8666,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8908,17 +9150,17 @@ before you can comment - + Search forums Търсене Форуми - + New Thread - + Threaded View @@ -8928,19 +9170,19 @@ before you can comment - - + + Title Заглавие - - + + Date Дата - + Author Автор @@ -8955,7 +9197,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9000,23 +9252,23 @@ before you can comment Търсене на автор - + No name Няма име - - + + Reply - + <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> - + Loading... @@ -9054,12 +9306,12 @@ before you can comment Маркирай като непрочетено - + Copy RetroShare Link - + Hide Скрий @@ -9068,7 +9320,7 @@ before you can comment Разширяване - + [unknown] @@ -9098,8 +9350,8 @@ before you can comment - - + + Distribution @@ -9186,12 +9438,12 @@ before you can comment - + New thread - + Edit Редактиране @@ -9247,7 +9499,7 @@ before you can comment - + Author's reputation @@ -9267,7 +9519,7 @@ before you can comment - + <b>Loading...<b> @@ -9307,6 +9559,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9374,7 +9631,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9406,11 +9663,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9816,7 +10068,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9831,7 +10083,7 @@ This message is missing. You should receive it later. Отваряне в нов раздел - + Remove this search @@ -9841,12 +10093,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9913,12 +10165,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9933,7 +10185,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10447,7 +10699,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10456,7 +10708,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10482,7 +10734,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10556,49 +10808,55 @@ p, li { white-space: pre-wrap; } Формуляр - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10646,17 +10904,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10671,7 +10924,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10936,14 +11194,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10953,12 +11211,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11102,7 +11360,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11174,7 +11432,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11189,24 +11447,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11221,7 +11479,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11280,13 +11538,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11346,7 +11609,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11394,7 +11657,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11403,12 +11666,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11420,12 +11683,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11541,17 +11804,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11708,8 +11971,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11720,7 +11983,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11730,7 +11993,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11790,7 +12053,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11800,7 +12063,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11838,7 +12101,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11855,14 +12118,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11873,24 +12136,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11910,12 +12176,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11925,7 +12216,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11935,7 +12226,12 @@ These identities will soon be not supported anymore. Тип - + + Choose image... + + + + @@ -11975,12 +12271,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11990,7 +12281,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12095,7 +12386,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12254,7 +12545,7 @@ These identities will soon be not supported anymore. - + Options Настройки @@ -12286,12 +12577,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12420,7 +12711,7 @@ These identities will soon be not supported anymore. Показване - + Make sure this link has not been forged to drag you to a malicious website. @@ -12465,7 +12756,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12494,7 +12785,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12596,7 +12887,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12691,12 +12982,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12726,7 +13017,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12752,12 +13048,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12768,7 +13064,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -13022,7 +13318,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13036,6 +13332,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13048,7 +13359,7 @@ Do you want to save message ? От: - + Bullet list (disc) @@ -13088,13 +13399,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13233,8 +13544,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13246,12 +13572,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13326,12 +13652,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13392,18 +13724,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13418,7 +13765,7 @@ Do you want to save message ? - + Load images always for this message @@ -13527,7 +13874,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13543,14 +13890,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13621,7 +13968,7 @@ Do you want to save message ? - + Subject @@ -13701,7 +14048,7 @@ Do you want to save message ? - + Open in a new window @@ -13786,7 +14133,7 @@ Do you want to save message ? - + Drafts @@ -13875,7 +14222,7 @@ Do you want to save message ? - + Delete Message @@ -13886,7 +14233,7 @@ Do you want to save message ? - + Expand Разширяване @@ -13896,7 +14243,7 @@ Do you want to save message ? Премахни елемент - + from @@ -13905,6 +14252,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14204,7 +14556,7 @@ Reported error: - + Groups @@ -14234,19 +14586,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14256,7 +14608,7 @@ Reported error: - + Show Items @@ -14455,18 +14807,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14504,7 +14856,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14518,7 +14870,7 @@ at least one peer was not added to a group - + Newest on top @@ -14529,20 +14881,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14575,22 +14942,22 @@ at least one peer was not added to a group - + Test Тест - + Chat Room - + Systray Icon - + Message @@ -14611,12 +14978,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14663,27 +15025,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14733,7 +15105,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14747,7 +15119,7 @@ at least one peer was not added to a group Емисия - + Systray @@ -14874,17 +15246,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14939,22 +15306,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14968,7 +15330,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14978,22 +15340,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15013,7 +15365,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -15079,27 +15431,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15111,7 +15463,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15156,27 +15508,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15347,8 +15715,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15365,7 +15732,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15504,7 +15871,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15540,7 +15907,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15572,6 +15939,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment Добави коментар + + + Album + + PhotoItem @@ -15581,12 +15953,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Формуляр - + TextLabel - + <!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; } @@ -15666,7 +16038,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15706,7 +16078,7 @@ requesting to edit it! - + Stop @@ -15930,17 +16302,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16266,7 +16638,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16397,13 +16769,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16413,7 +16785,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16434,12 +16806,12 @@ p, li { white-space: pre-wrap; } - + Hide Скрий - + Vote up @@ -16449,7 +16821,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item Задай като четене и премахване на елемент @@ -16510,7 +16882,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16556,13 +16928,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16572,60 +16938,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown непознат - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16636,7 +16992,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16705,7 +17061,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16740,7 +17101,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16856,8 +17217,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17125,12 +17496,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17145,17 +17511,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + От: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17180,10 +17561,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17193,13 +17584,48 @@ and use the import button to load it - + + Post + + + + Cancel Отмяна - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17222,10 +17648,18 @@ and use the import button to load it Формуляр - - - - + + + + + Click to view picture + + + + + + + Image @@ -17233,44 +17667,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17280,17 +17714,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17300,7 +17734,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17308,7 +17742,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17323,7 +17757,7 @@ and use the import button to load it - + follow Parent Group @@ -17333,7 +17767,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17358,7 +17792,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17394,29 +17828,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17494,7 +17928,7 @@ and use the import button to load it QObject - + Confirmation @@ -17733,7 +18167,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17768,7 +18202,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17906,7 +18340,7 @@ Reported error is: - + TR up @@ -17951,7 +18385,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17967,7 +18401,7 @@ Reported error is: - + %1 seconds ago @@ -18051,7 +18485,7 @@ Security: no anonymous IDs - + Error @@ -18441,11 +18875,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18779,7 +19208,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -19001,18 +19430,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19449,7 +19899,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19464,7 +19914,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19512,7 +19962,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Запазване - + Collection Editor @@ -19527,7 +19977,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19542,12 +19992,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19794,7 +20244,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Име @@ -19814,7 +20264,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19827,10 +20277,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Заглавие + + + UnRead + + Date @@ -19842,7 +20297,7 @@ If you believe it is correct, remove the corresponding line from the file and re Автор - + Information for this identity is currently missing. @@ -19880,7 +20335,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19888,7 +20343,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Дата @@ -19948,7 +20403,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20302,7 +20757,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20381,7 +20836,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20401,7 +20856,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20506,12 +20961,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20521,7 +20976,7 @@ prevents the message to be forwarded to your friends. - + Expand Разширяване @@ -20784,13 +21239,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21256,7 +21711,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21284,7 +21739,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Статус @@ -21381,7 +21836,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21416,12 +21871,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -22086,7 +22541,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22128,7 +22583,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22184,7 +22639,7 @@ This choice can be reverted in settings. - + DHT @@ -22716,7 +23171,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22726,13 +23181,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22741,6 +23195,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23014,27 +23493,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -23042,7 +23516,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -23053,7 +23527,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Име @@ -23260,7 +23734,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23354,7 +23828,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23486,7 +23960,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23497,7 +23971,7 @@ p, li { white-space: pre-wrap; } - + Path Пътека @@ -23507,7 +23981,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23517,7 +23991,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23532,7 +24006,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23774,7 +24248,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23870,7 +24344,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24238,7 +24712,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24332,8 +24806,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24344,7 +24818,7 @@ p, li { white-space: pre-wrap; } - + Preview Преглед @@ -24369,12 +24843,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24394,7 +24868,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24432,7 +24906,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24442,12 +24916,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -24482,12 +24955,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24521,7 +24994,7 @@ p, li { white-space: pre-wrap; } Нов - + Yourself @@ -24531,7 +25004,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24543,7 +25016,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24551,7 +25024,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24632,8 +25105,8 @@ p, li { white-space: pre-wrap; } Формуляр - - + + Avatar @@ -24662,6 +25135,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24774,7 +25252,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_ca_ES.ts b/retroshare-gui/src/lang/retroshare_ca_ES.ts index 70582e0b4..fe57c6488 100644 --- a/retroshare-gui/src/lang/retroshare_ca_ES.ts +++ b/retroshare-gui/src/lang/retroshare_ca_ES.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Retroshare versió @@ -79,7 +79,7 @@ Passa-t'ho bé ;-) - + Only Hidden Node Només node ocult @@ -128,12 +128,12 @@ RetroShare: Cerca Avançada - + Search Criteria Criteris de Cerca - + Add a further search criterion. Afegeix un altre criteri de cerca. @@ -338,7 +338,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Àlbum @@ -493,7 +493,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -536,8 +536,8 @@ p, li { white-space: pre-wrap; } Formulari - - + + TextLabel EtiquetaTexte @@ -612,7 +612,7 @@ p, li { white-space: pre-wrap; } Barra d'eines - + Icon Only Només icones @@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; } Escull l'estil dels botons de les eines. - + Icon Size = 8x8 Mida icona = 8x8 @@ -662,7 +662,7 @@ p, li { white-space: pre-wrap; } Mida Icona = 128x128 - + Status Bar Barra d'estat @@ -737,7 +737,7 @@ p, li { white-space: pre-wrap; } Deshabilitar consells sobre l'àrea de notificació - + Main page items: Elements de la pàgina principal: @@ -752,7 +752,7 @@ p, li { white-space: pre-wrap; } Llista d'elements - + Icon Size = 32x32 Mida icona = 32x32 @@ -827,14 +827,23 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Canvia l'avatar - + + TextLabel + + + + Your Avatar Picture La fotografia del teu avatar - + + Browse... + + + Add Avatar - Afegir avatar + Afegir avatar @@ -842,25 +851,34 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Treure - + Set your Avatar picture Tria la fotografia del teu avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Carrega avatar + Carrega avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Feu clic per canviar l'avatar @@ -868,7 +886,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem BWGraphSource - + KB/s KB/s @@ -888,44 +906,65 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem RetroShare Bandwidth Usage Ús d'ampla de banda del RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostra la configuració + TextLabel + + + + Reset Restablir - Receive Rate - Taxa de Recepció + Taxa de Recepció - Send Rate - Taxa d'enviament + Taxa d'enviament - + Always on Top Sempre per damunt - Style - Estil + Estil - + Changes the transparency of the Bandwidth Graph Canvia la transparència de la gràfica d'ample de banda - + 100 100 @@ -935,30 +974,27 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem % Opac - Save - Desa + Desa - Cancel - Cancel·la + Cancel·la - + Since: Des de: - Hide Settings - Amagar opcions + Amagar opcions BandwidthStatsWidget - + Sum Suma @@ -980,7 +1016,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Comptador - + Average Mitjana @@ -1114,7 +1150,7 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem - + Comments Comentaris @@ -1192,6 +1228,85 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem + + BoardsCommentsItem + + + I like this + M'agrada + + + + 0 + 0 + + + + I dislike this + No m'agrada + + + + Toggle Message Read Status + Canvia l'estat dels missatges llegits + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copia l'enllaç RetroShare + + + + + Expand + Ampliar + + + + Set as read and remove item + Marcar com llegit i eliminar l'element + + + + Remove Item + Eliminar l'element + + + + Name + Nom + + + + Comm value + + + + + Comment + Comentari + + + + Comments + Comentaris + + + + Hide + Amagar + + BwCtrlWindow @@ -1327,6 +1442,16 @@ Però recorda: Totes les dades generades aquí *SERAN* perdudes quan actualitzem Log scale Escala logaritmica + + + Default + Per defecte + + + + Dark + + ChannelPage @@ -1383,6 +1508,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + M'agrada + + + + 0 + 0 + + + + I dislike this + No m'agrada + + + + Toggle Message Read Status + Canvia l'estat dels missatges llegits + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copia l'enllaç RetroShare + + + + + Expand + Ampliar + + + + Set as read and remove item + Marcar com llegit i eliminar l'element + + + + Remove Item + Eliminar l'element + + + + Name + Nom + + + + Comm value + + + + + Comment + Comentari + + + + Comments + Comentaris + + + + Hide + Amagar + + ChatLobbyDialog @@ -1590,24 +1794,40 @@ into the image, so as to Xats - You have %1 new messages - Tens %1 nous missatges + Tens %1 nous missatges + + + You have %1 new message + Tens %1 nou missatge + + + %1 new messages + %1 missatges nous + + + %1 new message + %1 missatges nous + + + + You have %1 mentions + - You have %1 new message - Tens %1 nou missatge + You have %1 mention + - %1 new messages - %1 missatges nous + %1 mentions + - %1 new message - %1 missatges nous + %1 mention + @@ -1620,11 +1840,6 @@ into the image, so as to Remove All Suprimeix-ho tot - - - mention(s) - - ChatLobbyWidget @@ -2119,13 +2334,11 @@ Fes doble clic a les sales per entrar-hi i xatejar. Variant: - Group chat - Xat en grup + Xat en grup - - + Private chat Xat privat @@ -2190,17 +2403,16 @@ Fes doble clic a les sales per entrar-hi i xatejar. /me està enviant un missatge amb /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">En aquesta pestanya pots modificar quants missatges de xat el RetroShare mantindrà emmagatzemats en disc i quantes de les converses prèvies mostrarà pels diferents sistemes de xat. El període màxim d'emmagatzematge et permet descartar missatges vells i impedeix que l'historial de xat s'ompli amb xats esporàdics (per ex. sales de xat i xats distants).</p></body></html> - Chatlobbies - Salesxat + Salesxat - + Enabled: Activat: @@ -2221,11 +2433,12 @@ Fes doble clic a les sales per entrar-hi i xatejar. + Chat rooms Sales de xat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Marca'l si identitats i texts a la part superior han de coincidir en majúscules/minúscules pel comptador. @@ -2286,11 +2499,17 @@ Fes doble clic a les sales per entrar-hi i xatejar. + Broadcast Difusió - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Missatges emmagatzemats (0 = il·limitat): @@ -2437,8 +2656,23 @@ Fes doble clic a les sales per entrar-hi i xatejar. Xat privat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2611,7 +2845,7 @@ Fes doble clic a les sales per entrar-hi i xatejar. - + is typing... està escrivint... @@ -2630,12 +2864,12 @@ after HTML conversion. després de convertir a HTML. - + Choose your font. Escull el tipus de lletra - + Do you really want to physically delete the history? Segur que vols eliminar físicament l'historial? @@ -2707,7 +2941,7 @@ després de convertir a HTML. No deixis de colorejar fins trobar X elements (Necessita més UCP) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Trobar anterior </b><br/><i>Ctrl+Shift+G</i> @@ -2747,12 +2981,12 @@ després de convertir a HTML. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marca el text seleccionat</b><br><i>Ctrl+M</i> - + Person id: Id de la persona: @@ -2769,7 +3003,7 @@ Doble clic per afegir el seu nom al text escrit. No signat - + items found. Elements trobats. @@ -2789,7 +3023,7 @@ Doble clic per afegir el seu nom al text escrit. Escriu un missatge aquí - + Don't stop to color after No t'aturis a colorejar després de @@ -2947,12 +3181,12 @@ Doble clic per afegir el seu nom al text escrit. ConfCertDialog - + Details Detalls - + Local Address Adreça local @@ -2963,12 +3197,12 @@ Doble clic per afegir el seu nom al text escrit. Adreça externa - + Node info: Informació de node: - + Current address: Adreça actual: @@ -2984,31 +3218,36 @@ Doble clic per afegir el seu nom al text escrit. Port - + Include signatures Inclou les signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. Error: no es poden obtenir detalls del contacte. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3024,22 +3263,27 @@ Doble clic per afegir el seu nom al text escrit. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Encriptació - + Not connected No connectat - + Retroshare node details Detalls del node de RetroShare - + Node name : Nom del node : @@ -3074,13 +3318,18 @@ Doble clic per afegir el seu nom al text escrit. Missatge d'estat: - + + Connectivity + + + + List of known addresses: Llista d'adreces conegudes: - - + + Retroshare Certificate Certificat RetroShare @@ -3095,7 +3344,7 @@ Doble clic per afegir el seu nom al text escrit. - + Hidden Address Adreça oculta @@ -3106,11 +3355,12 @@ Doble clic per afegir el seu nom al text escrit. cap + <p>This certificate contains: - <p>Aquest certificat conté: + <p>Aquest certificat conté: - + <li>a <b>node ID</b> and <b>name</b> <li>un<b>ID de node</b> i <b>nom</b> @@ -3123,12 +3373,12 @@ Doble clic per afegir el seu nom al text escrit. una <b>adreça IP</b> i <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Pots utilitzar aquest certificat per fer nous amics. Envia'l per correu o entrega'l en ma.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Aquesta és la ID del node <span style=" font-weight:600;">OpenSSL</span> certifcat, signat pels a sobre llistats <span style=" font-weight:600;">clau</span> PGP. </p></body></html> @@ -3138,7 +3388,7 @@ Doble clic per afegir el seu nom al text escrit. <html><head/><body><p>Aquest és el mètode d'encriptat utilitzat per <span style=" font-weight:600;">OpenSSL</span>. La conexió cap a nodes amics</p><p>és sempre forta i si hi ha DHE disponible la conexió a més a més utilitza</p><p>&quot;perfect forward secrecy&quot;.</p></body></html> - + with amb @@ -3344,12 +3594,12 @@ Doble clic per afegir el seu nom al text escrit. Detalls sobre la petició - + Peer details Detalls del contacte - + Name: Nom: @@ -3367,12 +3617,12 @@ resources. Si us plau, tingues en compte que RetroShare necessitarà una quantitat excessiva d'ample de banda, memòria i CPU si afegeixes masses amics. Pots afegir tants amics com vulguis, però més de 40 serà probablement excessiu. - + Location: Ubicació: - + Options Opcions @@ -3409,12 +3659,12 @@ resources. Enganxar certificat - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> <html><head/><body><p>Aquesta casella espera el certificat de Retroshare del teu amic. AVÍS: No és el mateix que la clau del perfil del teu amic. No enganxis la clau del perfil del teu amic aquí (Ni tan sols part d'ella). No funcionarà.</p></body></html> - + Add friend to group: Afegir amic al grup: @@ -3424,7 +3674,7 @@ resources. Autentica amic (Signa clau PGP) - + Please paste below your friend's Retroshare ID @@ -3449,7 +3699,7 @@ resources. - + Add as friend to connect with Afegir com amic amb qui connectar @@ -3458,7 +3708,7 @@ resources. Per acceptar la petició de l'amic, clica al botó acabar. - + Sorry, some error appeared Ho sentim, ha aparegut algun error @@ -3478,32 +3728,32 @@ resources. Detalls sobre el teu amic: - + Key validity: Validesa de la clau: - + Profile ID: - + Signers Signants - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Les signatures a sota testimonien criptogràficament que els propietaris de les claus llistades reconeixen la clau PGP com autèntica. </span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Aquest contacte ja és a la llista d'amics. Afegir-lo potser només actualitzi la seva adreça IP. - + To accept the Friend Request, click the Accept button. @@ -3549,7 +3799,7 @@ resources. - + Certificate Load Failed Càrrega de certificat fallida @@ -3586,12 +3836,12 @@ resources. El certificat sembla vàlid - + Not a valid Retroshare certificate! No és un certificat de Retroshare vàlid! - + RetroShare Invitation Invitació al RetroShare @@ -3613,12 +3863,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? Aquest és el teu certificat! No vols fer-te amic amb tu mateix, oi? - + @@ -3666,7 +3916,37 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Tens una petició d'amic de - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3754,12 +4034,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Utilitza com a font directa quan estigui disponible - + IP-Addr: Adreça IP: - + IP-Address Adreça IP: @@ -3825,7 +4105,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Afegeix clau al clauer - + This key is already in your keyring Aquesta claus ja és al clauer @@ -3886,12 +4166,12 @@ encara que no sigueu amics. <p>Aquest certificat no té IP. Només podràs utilitzar descobriment i DHT per trobar-lo. Com que és necessari que estigui a la llista blanca d'IPs el contacte provocarà un avís a la pestanya de Novetats. Des d'allí podràs afegir la IP a la llista blanca.</p> - + [Unknown] [Desconegut] - + Added with certificate from %1 Afegit amb el certificat de %1 @@ -3978,7 +4258,12 @@ encara que no sigueu amics. Resultat UDP - + + Status + Estat + + + <!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; } @@ -4408,7 +4693,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4560,7 +4845,7 @@ p, li { white-space: pre-wrap; } No s'ha seleccionat cap cercle de limitacions - + [Unknown] [Desconegut] @@ -4575,7 +4860,7 @@ p, li { white-space: pre-wrap; } Treure - + Search Cercar @@ -4595,7 +4880,7 @@ p, li { white-space: pre-wrap; } Signat per nodes coneguts - + Edit Circle Editar cercle @@ -4615,12 +4900,12 @@ p, li { white-space: pre-wrap; } Id anonima - + Circle name Nom del cercle - + Update Actualitza @@ -4646,7 +4931,7 @@ p, li { white-space: pre-wrap; } Id enllaç PGP - + Add Member Afegir Membre @@ -4790,7 +5075,7 @@ p, li { white-space: pre-wrap; } - + Attachments Adjunts @@ -4836,7 +5121,7 @@ p, li { white-space: pre-wrap; } Arrossegar i deixar arxius dels resultats de la cerca - + Paste RetroShare Links Enganxar enllaços RetroShare @@ -4846,7 +5131,7 @@ p, li { white-space: pre-wrap; } Enganxa l'enllaç RetroShare - + Drop file error. Error al deixar l'arxiu. @@ -4873,17 +5158,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Arxiu ja afegit i hash calculat + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Arxiu ja afegit i hash calculat + + + Please add a Subject Si us plau, afegeix un assumpte @@ -4914,12 +5223,12 @@ p, li { white-space: pre-wrap; } Segur que vols generar %1 missatges? - + You are about to add files you're not actually sharing. Do you still want this to happen? Estàs a punt d'afegir arxius que ara mateix no comparteixes. Segur que ho vols fer? - + Edit Channel Post Editar publicació al canal @@ -4939,7 +5248,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Apunt de publicar arxius no propis a un canal. @@ -5031,7 +5340,7 @@ p, li { white-space: pre-wrap; } - + No Forum Sense fòrum @@ -5490,7 +5799,7 @@ i utilitzar el botó d'importació per carregar-lo DHTGraphSource - + users usuaris @@ -6497,7 +6806,7 @@ i utilitzar el botó d'importació per carregar-lo FlatStyle_RDM - + Friends Directories Directoris dels amics @@ -7003,7 +7312,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Busca als amics - + Mark all Marcar tots/es @@ -7017,7 +7326,7 @@ com a mínim un dels contactes no s'ha afegit a un grup FriendsDialog - + Edit status message Editar missatge d'estat @@ -7121,7 +7430,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Xat de difusió del RetroShare: Els missatges són enviats a tots els amics connectats. - + Network Xarxa @@ -7186,7 +7495,7 @@ com a mínim un dels contactes no s'ha afegit a un grup El camp node és necessari amb un mínim de 3 caràcters - + Failed to generate your new certificate, maybe PGP password is wrong! Ha fallat la generació del teu nou certificat, potser la contrasenya PGP sigui incorrecta! @@ -7229,7 +7538,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Tornar a utilitzar un perfil existent - + Node name Nom del node @@ -7496,12 +7805,12 @@ i utilitzar el botó d'importació per carregar-lo - + Profile generation failure Generació de perfil fallat - + Missing PGP certificate Falta certificat PGP @@ -7920,7 +8229,7 @@ p, li { white-space: pre-wrap; } Estadístiques d'encaminador - + GroupBox Selecció de grup @@ -7985,7 +8294,7 @@ p, li { white-space: pre-wrap; } Factor de ramificació - + Details Detalls @@ -8008,7 +8317,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Claus administrades @@ -8218,7 +8527,7 @@ Nota: No es poden revocar els permisos d'administrador publicats GroupTreeWidget - + Title Títol @@ -8228,13 +8537,30 @@ Nota: No es poden revocar els permisos d'administrador publicatsCerca títol - - + + + + Description Descripció - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Descripció de cerca @@ -8244,42 +8570,35 @@ Nota: No es poden revocar els permisos d'administrador publicats - Sort Descending Order - Ordena en ordre descendent + Ordena en ordre descendent - Sort Ascending Order - Ordena en ordre ascendent + Ordena en ordre ascendent - Sort by Name - Ordena per nom + Ordena per nom - Sort by Popularity - Ordena per popularitat + Ordena per popularitat - Sort by Last Post - Ordena per darrer missatge + Ordena per darrer missatge - Sort by Number of Posts - Ordenar per nombre de publicacións + Ordenar per nombre de publicacións - Sort by Unread - Ordena per no llegit + Ordena per no llegit - + You are admin (modify names and description using Edit menu) Ets l'administrador (Modifica noms i descripció utilitzant el menú Editar) @@ -8294,40 +8613,35 @@ Nota: No es poden revocar els permisos d'administrador publicatsId - - + + Last Post Darrera publicació - + + Name Nom - - Unread - - - - + Popularity Popularitat - - + + Never Mai - Display - Mostra + Mostra - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8476,7 +8790,7 @@ Nota: No es poden revocar els permisos d'administrador publicats GxsChannelDialog - + Channels Canals @@ -8501,12 +8815,12 @@ Nota: No es poden revocar els permisos d'administrador publicats<h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Canals</h1> <p>Canals et permet publicar dades (Ex: pel·lícules, música) que es propagaran per la xarxa</p> <p>Pots veure els canals als que tens amics subscrits i tu faràs el mateix amb els teus. Això promociona els canals populars dins la xarxa.</p> <p>Només el creador del canal pot publicar en un canal. Els altres contactes a la xarxa només poden llegir el canal, a no ser que el canal sigui privat. No obstant, pots compartir els drets de publicació o lectura amb nodes de Retroshare amics.</p> <p>Els canals poden ser anònims o associats a una identitat de Retroshare per tal que els lectors puguin contactar amb tu si volen. Activa "Permetre comentaris" si vols permetre que els usuaris facin comentaris sobre el que publiques.</p><p>Les entrades publicades es mantenen durant %1 dies, i es sincronitzen pels últims %2 dies, a no ser que ho canviïs.</p> - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Canals subscrits @@ -9031,7 +9345,7 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Add new post Afegir nova publicació @@ -9131,12 +9445,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Files Arxius - + Comments Comentaris @@ -9147,18 +9461,18 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Feeds Fonts - - + + Click to switch to list view - + Show unread posts only @@ -9168,12 +9482,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + No files in the channel, or no channel selected - + No text to display @@ -9233,7 +9547,7 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Download this file: @@ -9248,12 +9562,12 @@ Nota: No es poden revocar els permisos d'administrador publicats - + Comments (%1) - + [No name] @@ -9329,23 +9643,36 @@ Nota: No es poden revocar els permisos d'administrador publicats + Copy Retroshare link + + + + Subscribed Subscrit - - Subscribe Subscriure's - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected No hi ha canal seleccionat @@ -9367,11 +9694,6 @@ Nota: No es poden revocar els permisos d'administrador publicatsChannel Post Entrada al canal - - - new message(s) - - GxsCircleItem @@ -9905,7 +10227,7 @@ abans de poder comentar Comença nova conversa al fòrum seleccionat - + Search forums Cercar fòrums @@ -9914,12 +10236,12 @@ abans de poder comentar Darrer missatge - + New Thread Nova conversa - + Threaded View Vista per conversa @@ -9929,19 +10251,19 @@ abans de poder comentar Vista plana - - + + Title Títol - - + + Date Data - + Author Autor @@ -9956,7 +10278,17 @@ abans de poder comentar Carregant - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -10017,23 +10349,23 @@ abans de poder comentar <p>Subscriure's al fòrum buscarà les entrades publicades disponibles dels teus amics subscrits, i farà el fòrum visible a tots els teus altres amics.</p><p>Després podràs des-subscriure't des del menú contextual de la llista de fòrums a l'esquerra.</p> - + No name Sense nom - - + + Reply Resposta - + <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> - + Loading... @@ -10071,12 +10403,12 @@ abans de poder comentar Marca com no llegit - + Copy RetroShare Link Copia l'enllaç RetroShare - + Hide Amagar @@ -10089,7 +10421,7 @@ abans de poder comentar [Expulsat] - + [unknown] [desconegut] @@ -10119,8 +10451,8 @@ abans de poder comentar Només per tu - - + + Distribution Distribució @@ -10223,7 +10555,7 @@ abans de poder comentar Missatge original - + New thread Nova conversa @@ -10232,7 +10564,7 @@ abans de poder comentar Estat de lectura - + Edit Editar @@ -10288,7 +10620,7 @@ abans de poder comentar Mostrar autor a la pestanya de gent - + Author's reputation Reputació de l'autor @@ -10308,7 +10640,7 @@ abans de poder comentar - + <b>Loading...<b> @@ -10348,6 +10680,11 @@ abans de poder comentar Storage Emmagatzematge + + + Last seen at friends: + + Moderators @@ -10438,7 +10775,7 @@ prevents the message to be forwarded to your friends. A %1, %2 va escriure: - + Forum name Nom del fòrum @@ -10470,11 +10807,6 @@ prevents the message to be forwarded to your friends. Forum Post Entrada al fòrum - - - new message(s) - - GxsForumsDialog @@ -10923,7 +11255,7 @@ prevents the message to be forwarded to your friends. PreviaImpressió - + Unsubscribe Donar de baixa @@ -10938,7 +11270,7 @@ prevents the message to be forwarded to your friends. Obrir en una pestanya nova - + Remove this search @@ -10948,12 +11280,12 @@ prevents the message to be forwarded to your friends. - + Request data - + Show Details Mostra detalls @@ -11020,7 +11352,7 @@ prevents the message to be forwarded to your friends. - + Search for @@ -11029,7 +11361,7 @@ prevents the message to be forwarded to your friends. Compartir permisos de publicació - + Copy RetroShare Link Copia l'enllaç RetroShare @@ -11044,7 +11376,7 @@ prevents the message to be forwarded to your friends. Marca tot com no llegit - + AUTHD AUTHD @@ -11661,7 +11993,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11670,7 +12002,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11696,6 +12028,23 @@ p, li { white-space: pre-wrap; } <!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:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></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-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Website Translators:</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> + + + + <!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:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> @@ -11707,7 +12056,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Swedish: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Daniel Wester</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">wester@speedmail.se</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">&gt;</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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">German: </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Jan</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;"> </span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Keller</span><span style=" font-family:'MS Shell Dlg 2';"> &lt;</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">trilarion@users.sourceforge.net</span><span style=" font-family:'MS Shell Dlg 2';">&gt;</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-family:'MS Shell Dlg 2'; font-weight:600;">Polish: </span><span style=" font-family:'MS Shell Dlg 2';">Maciej Mrug</span></p></body></html> - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> + <!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;"> @@ -11789,27 +12138,32 @@ p, li { white-space: pre-wrap; } Formulari - - Did you receive a Retroshare id from a friend? + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> - + Add friend - + + Did you receive a Retroshare ID from a friend? + + + + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11831,6 +12185,7 @@ p, li { white-space: pre-wrap; } + ... ... @@ -11839,7 +12194,7 @@ p, li { white-space: pre-wrap; } El text a sota és el teu certificat de Retroshare. Envia'l als teus amic - + Open Source cross-platform, private and secure decentralized communication platform. @@ -11855,12 +12210,12 @@ private and secure decentralized communication platform. Necessites ajuda amb el RetroShare? - + Open Web Help Ajuda a la web oberta - + Copy your Cert to Clipboard Copiar el teu certificat al porta-retalls @@ -11909,7 +12264,7 @@ new short format - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> @@ -11918,7 +12273,7 @@ new short format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -12211,14 +12566,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Tot - + Reputation Reputació @@ -12228,12 +12583,12 @@ p, li { white-space: pre-wrap; } Cerca - + Anonymous Id Id anònim - + Create new Identity Crear nova identitat @@ -12377,7 +12732,7 @@ p, li { white-space: pre-wrap; } Id d'identitat - + Send message Enviar missatge @@ -12469,7 +12824,7 @@ p, li { white-space: pre-wrap; } Global: - + Anonymous Anònim @@ -12484,24 +12839,24 @@ p, li { white-space: pre-wrap; } ID cerca - + This identity is owned by you Aquesta identitat és propietat teva - - + + My own identities Les meves identitats - - + + My contacts Els meus contactes - + Show Items Mostrar elements @@ -12516,7 +12871,7 @@ p, li { white-space: pre-wrap; } Associat al meu node - + Other circles Altres cercles @@ -12575,13 +12930,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). Subscrit (Envia/reenvia peticions de pertinença d'altres i llista d'invitats) + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). No subscrit (Només rep la llista d'invitats). - + Your status: El teu estat: @@ -12641,7 +13001,7 @@ p, li { white-space: pre-wrap; } Membre - + Edit Circle Editar cercle @@ -12689,7 +13049,7 @@ p, li { white-space: pre-wrap; } Permet pertinença - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12701,12 +13061,12 @@ Aquestes identitats deixaran de ser suportades en breu. - + [Unknown node] [Node desconegut] - + Unverified signature from node Signatura no verificada del node @@ -12718,12 +13078,12 @@ Aquestes identitats deixaran de ser suportades en breu. Signatura no comprovada - + [unverified] [no verificat] - + Identity owned by you, linked to your Retroshare node Identitat propietat teva, enllaçat amb el teu node de RetroShare @@ -12847,12 +13207,12 @@ Aquestes identitats deixaran de ser suportades en breu. Estàs segur de voler enviar una invitació amb el teu certificat? - + Banned Expulsat - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identitats</h1><p>En aquesta pestanya pots crear/editar identitats <b>pseudo-anònimes</b> i <b>cercles</b>.</p><p>Les <b>Identitats</b> s'utilitzen per identificar les teves dades: signar missatges publicats a les sales de xat, fòrums i canals, rebre comentaris utilitzant el sistema intern de correu electrònic o publicar-ne a entrades dels canals, xatejar utilitzant túnels segurs, etc.</p> <p>Les identitats poden estar <b>signades</b> pel certificat del seu node de Rertoshare. És més fàcil confiar en identitats signades però es poden seguir fàcilment fins a la IP del node al que pertanyen.</p> <p>Les <b>identitats anònimes</b> et permetran interactuar amb altres usuaris de forma anònima. No es poden falsificar, però ningú pot provar qui té en realitat una determinada identitat.</p> <p>Els <b>cercles</b> són grups d'identitats (anònimes o signades) que són compartides a certa distancia, salts entre nodes, per la xarxa. Es poden utilitzar per restringir la visibilitat de fòrums, canals, etc. </p> <p>Un <b>cercle</b> pot estar restringit a un altre cercle, limitant la visibilitat als membres d'aquest cercle o inclús es pot auto-restringir, que vol dir que només es visible a membres invitats.</p> @@ -12861,7 +13221,7 @@ Aquestes identitats deixaran de ser suportades en breu. ID desconegut: - + positive positiu @@ -13046,8 +13406,8 @@ Aquestes identitats deixaran de ser suportades en breu. - - + + People Gent @@ -13058,7 +13418,7 @@ Aquestes identitats deixaran de ser suportades en breu. El teu avatar - + Linked to neighbor nodes Associat a nodes veïns @@ -13068,7 +13428,7 @@ Aquestes identitats deixaran de ser suportades en breu. Associat a nodes distants - + Linked to a friend Retroshare node Associat a un node de RetroShare d'un amic @@ -13128,7 +13488,7 @@ Aquestes identitats deixaran de ser suportades en breu. Propietat de - + Node name: Nom del node: @@ -13138,7 +13498,7 @@ Aquestes identitats deixaran de ser suportades en breu. ID node : - + Really delete? Segur que vols esborrar? @@ -13176,7 +13536,22 @@ Aquestes identitats deixaran de ser suportades en breu. Pseudònim - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Nova identitat @@ -13193,14 +13568,14 @@ Aquestes identitats deixaran de ser suportades en breu. - + N/A N/A - + Edit identity Editar identitat @@ -13211,24 +13586,27 @@ Aquestes identitats deixaran de ser suportades en breu. Actualitza - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -13247,17 +13625,27 @@ Aquestes identitats deixaran de ser suportades en breu. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Error obtenint clau! - + Error KeyID invalid Error de IDClau invàlida - + Unknown GpgId IdGPG desconegut @@ -13267,7 +13655,7 @@ Aquestes identitats deixaran de ser suportades en breu. Nom real desconegut - + Create New Identity Crear nova identitat @@ -13277,7 +13665,12 @@ Aquestes identitats deixaran de ser suportades en breu. Tipus - + + Choose image... + + + + @@ -13317,12 +13710,11 @@ Aquestes identitats deixaran de ser suportades en breu. El teu avatar - Set Avatar - Escull avatar + Escull avatar - + Linked to your profile Associat al teu perfil @@ -13332,7 +13724,7 @@ Aquestes identitats deixaran de ser suportades en breu. Pots tindre una o més identitats. S'utilitzen quan escrius en sales de xat, fòrums i comentes en canals. Funcionen també com a destinataris en xats distants i en el sistema de correu distant de RetroShare. - + The nickname is too short. Please input at least %1 characters. El sobrenom és massa curt. Si us plau, introdueix com a mínim %1 caràcters. @@ -13441,8 +13833,12 @@ Aquestes identitats deixaran de ser suportades en breu. + Quote + Cita + + Send - Enviar + Enviar @@ -13600,7 +13996,7 @@ Aquestes identitats deixaran de ser suportades en breu. - + Options Opcions @@ -13632,12 +14028,12 @@ Aquestes identitats deixaran de ser suportades en breu. Auxiliar d'inici ràpid - + RetroShare %1 a secure decentralized communication platform RetroShare %1 és una plataforma de comunicació segura descentralitzada - + Unfinished Inacabat @@ -13768,7 +14164,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Mostra - + Make sure this link has not been forged to drag you to a malicious website. Assegura't de que aquest enllaç no ha estat modificat per portar-te a un lloc web malicios. @@ -13813,7 +14209,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Taula de permisos dels serveis - + Statistics Estadístiques @@ -13842,7 +14238,7 @@ Si us plau, allibera una mica d'espai i clica Ok. MessageComposer - + Compose Redacta @@ -13944,7 +14340,7 @@ Si us plau, allibera una mica d'espai i clica Ok. - + Tags Etiquetes @@ -14039,12 +14435,12 @@ Si us plau, allibera una mica d'espai i clica Ok. Afegir citació - + Send To: Enviar a: - + &Left &Esquerra @@ -14078,7 +14474,7 @@ Si us plau, allibera una mica d'espai i clica Ok. Els meus contactes - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hola,<br>Et recomano un bon amic meu; pots confiar en ell si confies en mi. <br> @@ -14104,12 +14500,12 @@ Si us plau, allibera una mica d'espai i clica Ok. - + Save Message Desar el missatge - + Message has not been Sent. Do you want to save message to draft box? El missatge no s'ha enviat. @@ -14121,7 +14517,7 @@ Vols desar el missatge a la bústia d'esborranys? Enganxa l'enllaç RetroShare - + Add to "To" Afegir a "A" @@ -14376,7 +14772,7 @@ Voleu desar el missatge? Afegir arxiu extra - + Hi,<br>I want to be friends with you on RetroShare.<br> Hola,<br> vull ser amic amb tu en el RetroShare.<br> @@ -14385,12 +14781,27 @@ Voleu desar el missatge? Invite message + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + You have a friend invite Tens una petició d'amistat - + Respond now: Respondre ara: @@ -14406,11 +14817,12 @@ Voleu desar el missatge? De: + Friend Nodes - Nodes de l'amic + Nodes de l'amic - + Bullet list (disc) Llista amb símbol (disc) @@ -14450,13 +14862,13 @@ Voleu desar el missatge? Llista ordenada (romanic ascendent) - - + + Thanks, <br> Gràcies, <br> - + Distant identity: Identitat distant: @@ -14595,8 +15007,23 @@ Voleu desar el missatge? Missatge - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14608,12 +15035,12 @@ Voleu desar el missatge? Arxius recomanats - + Download all Recommended Files Descarregar tots els arxius recomanats - + Subject: Assumpte: @@ -14688,12 +15115,18 @@ Voleu desar el missatge? Envia invitació - + + Message Size: + + + + File Name Nom d'arxiu - + + Size Mida @@ -14754,10 +15187,25 @@ Voleu desar el missatge? Descarregar - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + Send invite? Enviar invitació? @@ -14768,12 +15216,12 @@ Voleu desar el missatge? - + Download all Descarregar tot - + Print Document Imprimir document @@ -14788,7 +15236,7 @@ Voleu desar el missatge? Arxius-HTML (*.htm *.html);;Tots els arxius (*) - + Load images always for this message Carregar sempre les imatges per aquest missatge @@ -14929,7 +15377,7 @@ Voleu desar el missatge? MessagesDialog - + New Message Missatge nou @@ -14985,14 +15433,14 @@ Voleu desar el missatge? - + Tags Etiquetes - + Inbox Safata d'entrada @@ -15087,7 +15535,7 @@ Voleu desar el missatge? Reenviar missatge - + Subject Assumpte @@ -15199,7 +15647,7 @@ Voleu desar el missatge? - + Open in a new window Obrir en una finestra nova @@ -15284,7 +15732,7 @@ Voleu desar el missatge? - + Drafts Esborranys @@ -15413,7 +15861,7 @@ Voleu desar el missatge? Respondre missatge - + Delete Message Esborrar missatge @@ -15424,7 +15872,7 @@ Voleu desar el missatge? - + Expand Ampliar @@ -15434,7 +15882,7 @@ Voleu desar el missatge? Eliminar l'element - + from des de @@ -15443,6 +15891,11 @@ Voleu desar el missatge? Reply to invite Respondre a la invitació + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15764,7 +16217,7 @@ Error reportat: - + Groups Grups @@ -15794,19 +16247,19 @@ Error reportat: importar la teva llista d'amics, incloent els grups - - + + Search - + ID ID - + Search ID ID cerca @@ -15816,7 +16269,7 @@ Error reportat: - + Show Items Mostrar elements @@ -16020,19 +16473,19 @@ com a mínim un dels contactes no s'ha afegit a un grup - + Error Error - + File is not writeable! L'arxiu no es pot escriure! - + File is not readable! L'arxiu no es pot llegir! @@ -16070,9 +16523,13 @@ com a mínim un dels contactes no s'ha afegit a un grup NewsFeed - Log entries - Entrades en el registre + Entrades en el registre + + + + Activity Stream + @@ -16089,7 +16546,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Això és un test. - + Newest on top El més nou a dalt @@ -16100,21 +16557,44 @@ com a mínim un dels contactes no s'ha afegit a un grup + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> + + + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Novetats</h1> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Novetats</h1> <p>La font de noticies mostra els últims esdeveniments a la xarxa ordenats per hora de recepció. Això et proporciona un resum de l'activitat dels teus amics. Pots triar quins esdeveniments es mostren a <b>Opcions</b>. </p> <p>Els esdeveniments mostrats són: <ul> <li>Intents de connexió (útil per fer amics amb gent nova i controlar qui està intentant connectar-te)</li> <li>Publicacions a canals i fòrums</li> <li>Nous canals i fòrums als que et pots subscriure</li> <li>Missatges privats dels teus amics</li> </ul> </p> - Log - Registre + Registre + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -16151,22 +16631,22 @@ com a mínim un dels contactes no s'ha afegit a un grup - + Test Test - + Chat Room Sala de xat - + Systray Icon Icona de l'àrea de notificació - + Message Missatge @@ -16191,12 +16671,11 @@ com a mínim un dels contactes no s'ha afegit a un grup Seguretat Ip - Log - Registre + Registre - + Friend Connected Amic connectat @@ -16210,7 +16689,12 @@ com a mínim un dels contactes no s'ha afegit a un grup Enllaços - + + Activity + + + + Mails Correus @@ -16247,7 +16731,12 @@ com a mínim un dels contactes no s'ha afegit a un grup Xat en grup - + + Toaster position + + + + Chat rooms Sales de xat @@ -16272,22 +16761,22 @@ com a mínim un dels contactes no s'ha afegit a un grup Diferenciar majúscules/minúscules - + Position Posició - + X Margin Marge X - + Y Margin Marge Y - + Systray message Missatge de l'area de notificació @@ -16338,7 +16827,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Notificar - + Disable All Toasters Deshabilitar totes les notificacions @@ -16352,7 +16841,7 @@ com a mínim un dels contactes no s'ha afegit a un grup Font - + Systray Àrea de notificació @@ -16498,17 +16987,16 @@ Tràfic baix: 10 %s del tràfic estàndard i PENDENT: posar en pausa totes les t PGPKeyDialog - Dialog - Diàleg + Diàleg - + Profile info Informació del perfil - + Name : Nom : @@ -16563,22 +17051,21 @@ Tràfic baix: 10 %s del tràfic estàndard i PENDENT: posar en pausa totes les t Definitiu - + This profile has signed your own profile key Aquest perfil ha signat la clau del teu perfil - Key signatures : - Signatures de la clau : + Signatures de la clau : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Les signatures a sota testimonien criptogràficament que els propietaris de les claus llistades reconeixen la clau PGP com autèntica. </span></p></body></html> - + <!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; } @@ -16596,7 +17083,7 @@ p, li { white-space: pre-wrap; } Signa aquesta clau - + PGP key Clau PGP @@ -16606,22 +17093,20 @@ p, li { white-space: pre-wrap; } Aquestes opcions s'apliquen a tots els nodes del perfil: - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Els ajudarà a decidir si volen acceptar o no connexions d'aquesta clau basant-se en la teva confiança. Signar una clau és completament opcional i no es pot desfer, fes-ho amb cura.</span></p></body></html> + <html><head/><body><p><span style=" font-size:10pt;">Signar la clau d'un amic és una forma d'expressar la teva confiança en aquest amic als teus altres amics. Els ajudarà a decidir si volen acceptar o no connexions d'aquesta clau basant-se en la teva confiança. Signar una clau és completament opcional i no es pot desfer, fes-ho amb cura.</span></p></body></html> - + Keysigning: - Sign PGP key - Signa clau PGP + Signa clau PGP - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> <html><head/><body><p>Fes clic aquí si vols rebutjar les connexions a nodes autenticats per aquesta clau.</p></body></html> @@ -16641,7 +17126,7 @@ p, li { white-space: pre-wrap; } Acceptar connexions - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. A sota teniu la clau del perfil del node en format PGP ASCII. Identifica tots els nodes del mateix perfil. Un "certificat de Retroshare" que pots intercanviar per fer amics, és a "detalls" de cada node. @@ -16711,28 +17196,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Error: no es poden obtenir detalls del contacte. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) L'algorisme de la clau proporcionada no és suportada pel RetroShare (Només suporta claus RSA per ara) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16746,7 +17231,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. El nivell de confiança és una forma d'expressar la teva confiança en aquesta clau. No s'utilitza pel programa ni es comparteix, però et pot ser útil per recordar claus bones/dolentes. @@ -16791,27 +17276,47 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir No estàs permetent connexions de nodes de Retroshare signats amb aquesta clau. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Fracàs en la signatura - - Maybe password is wrong - Potser la contrasenya sigui incorrecta + + Check the password! + - + Maybe password is wrong + Potser la contrasenya sigui incorrecta + + + You haven't set a trust level for this key. No has establert un nivell de confiança per aquesta clau. - + + Retroshare profile Perfil de Retroshare - + This is your own PGP key, and it is signed by : Aquesta és la teva clau PGP i està signada per : @@ -16990,8 +17495,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir PeopleDialog - - + People Gent @@ -17008,7 +17512,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Interna - + Chat with this person Xat amb aquesta persona @@ -17159,7 +17663,7 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Foto - + TextLabel EtiquetaTexte @@ -17203,8 +17707,8 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir - <N> Comments >> - + Comments + Comentaris @@ -17239,6 +17743,11 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Write a comment... Escriure un comentari... + + + Album + Àlbum + PhotoItem @@ -17248,12 +17757,12 @@ Avís: En les opcions de Transferència d'arxius, has marcat descarrega dir Formulari - + TextLabel EtiquetaTexte - + <!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; } @@ -17349,7 +17858,7 @@ p, li { white-space: pre-wrap; } Veure foto - + PhotoShare PhotoShare @@ -17390,7 +17899,7 @@ abans de demanar editar-lo! - + Stop Atura @@ -17618,12 +18127,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Autoritzar tots els complements - + Plugin look-up directories Directoris on buscar complements @@ -17683,7 +18192,7 @@ modificats. <h1><img width="24" src=":/images/help_64.png">&nbsp;&nbsp;Complements</h1> <p>Els complements es carreguen dels directoris del llistat inferior.</p> <p> Per raons de seguretat, els complements acceptats es carreguen automàticament mentre l'executable principal del Retroshare o els complements no canviïn. En tal cas, l'usuari haurà de confirmar-ho altre cop. Un cop el programa s'ha iniciat, pots habilitar un complement manualment fent clic al botó "Activa" i després reiniciant el Retroshare.</p> <p>Si vols desenvolupar els teus propis complements contacta amb els desenvolupadors i estaran contents d'ajudar-te!</p> - + Plugins Complements @@ -18081,7 +18590,7 @@ modificats. Enllaços - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -18252,13 +18761,13 @@ modificats. Lloc - - + + Comments Comentaris - + Copy RetroShare Link Copia l'enllaç RetroShare @@ -18268,7 +18777,7 @@ modificats. Mostrar autor a la pestanya de gent - + Comment Comentari @@ -18289,12 +18798,12 @@ modificats. - + Hide Amagar - + Vote up Votar positiu @@ -18308,7 +18817,7 @@ modificats. \/ - + Set as read and remove item Marcar com llegit i eliminar l'element @@ -18369,7 +18878,7 @@ modificats. - + Loading Carregant @@ -18459,13 +18968,7 @@ modificats. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18475,60 +18978,50 @@ modificats. Administrador: - - - + + + unknown desconegut - + Distribution: Distribució: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Publicacions @@ -18539,7 +19032,7 @@ modificats. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18608,7 +19101,12 @@ modificats. - + + Empty + Buit + + + Copy RetroShare Link Copia l'enllaç RetroShare @@ -18643,7 +19141,7 @@ modificats. - + [No name] @@ -18771,8 +19269,18 @@ modificats. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -19051,9 +19559,8 @@ i utilitzar el botó d'importació per carregar-lo PulseAddDialog - Post From: - Entrada de: + Entrada de: Account 1 @@ -19068,7 +19575,7 @@ i utilitzar el botó d'importació per carregar-lo Compte 3 - + Add to Pulse Afegir al Pols @@ -19091,17 +19598,32 @@ i utilitzar el botó d'importació per carregar-lo URL - + GroupLabel - + IDLabel - + + From: + De: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -19126,10 +19648,20 @@ i utilitzar el botó d'importació per carregar-lo Negatiu - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -19139,14 +19671,53 @@ i utilitzar el botó d'importació per carregar-lo - + + Post + + + + Cancel Cancel·la - Post Pulse to Wire - Publica Pols a Wire + Publica Pols a Wire + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -19172,10 +19743,18 @@ i utilitzar el botó d'importació per carregar-lo Formulari - - - - + + + + + Click to view picture + + + + + + + Image Imatge @@ -19183,44 +19762,44 @@ i utilitzar el botó d'importació per carregar-lo PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19230,17 +19809,17 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -19250,7 +19829,7 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -19258,7 +19837,7 @@ i utilitzar el botó d'importació per carregar-lo PulseTopLevel - + retweeted @@ -19273,7 +19852,7 @@ i utilitzar el botó d'importació per carregar-lo - + follow Parent Group @@ -19283,7 +19862,7 @@ i utilitzar el botó d'importació per carregar-lo ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -19308,7 +19887,7 @@ i utilitzar el botó d'importació per carregar-lo - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -19344,29 +19923,29 @@ i utilitzar el botó d'importació per carregar-lo - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19444,7 +20023,7 @@ i utilitzar el botó d'importació per carregar-lo QObject - + Confirmation Confirmació @@ -19686,7 +20265,7 @@ Els caràcters <b>",|,/,\,&lt;&gt;,*,?</b> es substitui Resultat - + Unable to make path Incapaç de crear ruta @@ -19721,7 +20300,7 @@ Els caràcters <b>",|,/,\,&lt;&gt;,*,?</b> es substitui Petició d'arxiu cancel·lada - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Aquesta versió de RetroShare utilitza l'OpenPGP-SDK. Com a efecte secundari no utilitza el clauer PGP del sistema, sinó un clauer compartit per totes les instancies de RetroShare. <br><br>No sembla que tinguis aquest clauer, tot i que tens claus PGP als comptes existents de RetroShare, probablement perquè acabes de canviar a aquesta nova versió del programa. @@ -19876,7 +20455,7 @@ L'error reportat és: seg - + TR up TR pujats @@ -19921,7 +20500,7 @@ L'error reportat és: desactivat - + Move IP %1 to whitelist Mou la IP %1 a la llista blanca @@ -19937,7 +20516,7 @@ L'error reportat és: - + %1 seconds ago fa %1 segons @@ -20022,7 +20601,7 @@ Seguretat: IDs anònimes no - + Error Error @@ -20413,9 +20992,8 @@ Seguretat: IDs anònimes no Clica per continuar amb el càlcul de hash - <p>This certificate contains: - <p>Aquest certificat conté: + <p>Aquest certificat conté: @@ -20789,7 +21367,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 kB @@ -21011,19 +21589,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Opcions de la vista d'arbre - Show column... - Mostrar columna... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + Ordena en ordre descendent + + + + Sort Ascending Order + Ordena en ordre ascendent + + + + + [no title] + + + + + Show column … + + + + Show column... + Mostrar columna... - [no title] - [sense títol] + [sense títol] @@ -21459,7 +22066,7 @@ p, li { white-space: pre-wrap; } Descarrega! - + File Arxiu @@ -21474,7 +22081,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned S'han netejat noms d'arxiu no permesos @@ -21524,7 +22131,7 @@ Els arxius afectats es llisten en vermell. Desa - + Collection Editor Editor de col·lecció @@ -21539,7 +22146,7 @@ Els arxius afectats es llisten en vermell. Comptador d'arxius - + Real Size: Waiting child... Mida real: Esperant pels fills... @@ -21554,12 +22161,12 @@ Els arxius afectats es llisten en vermell. Això és un directori. Doble clic per desplegar-lo. - + Download files Descarregar arxius - + Specify... Especificar... @@ -21808,7 +22415,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a RsFriendListModel - + Name Nom @@ -21828,7 +22435,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a IP - + Profile ID @@ -21841,10 +22448,15 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a RsGxsForumModel - + Title Títol + + + UnRead + + Date @@ -21856,7 +22468,7 @@ Si creus que és correcta, treu la línia corresponent de l'arxiu i torna&a Autor - + Information for this identity is currently missing. No hi ha informació per aquesta identitat @@ -21894,7 +22506,7 @@ prevents the message to be forwarded to your friends. [Desconegut] - + [ ... Missing Message ... ] [ ... Missatge perdut ... ] @@ -21902,7 +22514,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Data @@ -21962,7 +22574,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -22321,7 +22933,7 @@ prevents the message to be forwarded to your friends. Nom d'arxiu - + Download Descarregar @@ -22400,7 +23012,7 @@ prevents the message to be forwarded to your friends. Obrir directori - + Create Collection... Crear col·lecció... @@ -22420,7 +23032,7 @@ prevents the message to be forwarded to your friends. Descarregar d'arxiu de col·lecció... - + Collection Col·lecció @@ -22525,12 +23137,12 @@ prevents the message to be forwarded to your friends. Detalls del contacte - + Deny friend Negar l'amic - + Chat Xat @@ -22540,7 +23152,7 @@ prevents the message to be forwarded to your friends. Inicia xat - + Expand Ampliar @@ -22810,13 +23422,13 @@ d'un tallafocs o una VPN. Descobriment activat (Recomanat) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. S'ha configurat Tor automàticament per part de Retroshare. No hauria de fer falta que canviessis res aquí. - + Discovery Off Descobriment desactivat @@ -23311,7 +23923,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< <p>En qualsevol cas, un node de Retroshare funcionant com a repetidor no pot veure el tràfic que repeteix, ja que està encriptat i autenticat pels dos nodes interessats.</p> - + Network Xarxa @@ -23339,7 +23951,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< - + Status Estat @@ -23436,7 +24048,7 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< - + Service Address Adreça del servei @@ -23471,12 +24083,12 @@ Si tens problemes connectant-te sobre Tor comprova també els registres de Tor.< Si us plau, escriu una adreça de servei - + IP Range Rang IP - + Reported by DHT for IP masquerading Anunciat per DHT per enmascarament IP @@ -24156,7 +24768,7 @@ p, li { white-space: pre-wrap; } Falta certificat PGP - + Wrong password Contrasenya incorrecta @@ -24210,7 +24822,7 @@ Això es pot canviar a les opcions de configuració. StatisticsWindow - + Add Friend Afegeix amic @@ -24266,7 +24878,7 @@ Això es pot canviar a les opcions de configuració. Taula de permisos dels serveis - + DHT DHT @@ -24806,7 +25418,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24820,13 +25432,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline Tor és fora de línia - + Tor is OK Tor està OK @@ -24835,6 +25446,31 @@ p, li { white-space: pre-wrap; } No tor configuration Sense configuració Tor + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -25130,35 +25766,46 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - You have %1 completed downloads - Tens %1 descarregues completes + You have %1 completed transfers + - You have %1 completed download - Tens %1 descarrega completa + You have %1 completed transfer + - %1 completed downloads - %1 descarregues completades + %1 completed transfers + - %1 completed download - %1 descarrega completada + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Tens %1 descarregues completes + + + You have %1 completed download + Tens %1 descarrega completa + + + %1 completed downloads + %1 descarregues completades + + + %1 completed download + %1 descarrega completada TransfersDialog - + Downloads Descarregues @@ -25169,7 +25816,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Pujades - + Name i.e: file name Nom @@ -25380,7 +26027,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú <h1><img width="32" src=":/images/help_64.png">&nbsp;&nbsp;Transferència d'arxiu</h1> <p>Retroshare contempla dues formes de fer això: transferències directes dels teus amics, i transferències distants amb túnels anònims. A més amés, les transferències d'arxius són multi-origen i permet fer-les en eixam (pots ser origen mentre descarregues)</p> <p>Pots compartir arxius amb <img src=":/images/directoryadd_24x24_shadow.png" width=%2 /> la icona de la barra lateral esquerra. Aquests arxius es llistaran a la pestanya els meus arxius. Pots triar per cada grup d'amics si poden o no veure'l a la pestanya arxius d'amics.</p> <p>La pestanya cerca dona resultats pels arxius del teus amics i arxius que es poden accedir distants anònimament utilitzant el sistema de túnels multi-salt.</p> - + Move in Queue... Moure a la cua... @@ -25474,7 +26121,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Si us plau, introdueix un nou--i vàlid--nom d'arxiu - + Expand all Expandeix tot @@ -25606,7 +26253,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Columns Columnes @@ -25617,7 +26264,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Transferències d'arxius - + Path Ruta @@ -25627,7 +26274,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Mostra columna de ruta - + Could not delete preview file No s'ha pogut esborrar l'arxiu de previsualització @@ -25637,7 +26284,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Tornar-ho a intentar? - + Create Collection... Crear col·lecció... @@ -25652,7 +26299,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Veure col·lecció... - + Collection Col·lecció @@ -25898,7 +26545,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Unknown Peer Contacte desconegut @@ -25994,7 +26641,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú UserNotify - + You have %1 new messages Tens %1 nous missatges @@ -26378,7 +27025,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Crear grup - + Subscribe to Group Subscriure's al grup @@ -26472,8 +27119,8 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - - + + Show Edit History Mostra historial d'edició @@ -26484,7 +27131,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + Preview Visualització prèvia @@ -26509,12 +27156,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Amagar l'historial d'edició - + Edit Page Editar pàgina - + Create New Wiki Page Crear nova pàgina wiki @@ -26534,7 +27181,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú WikiGroupDialog - + Create New Wiki Group Crear nou grup wiki @@ -26576,7 +27223,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Rang de temps - + Create Account @@ -26586,12 +27233,11 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - ... - ... + ... - + Refresh Refrescar @@ -26626,12 +27272,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + > - + Most Recent @@ -26701,7 +27347,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Mostrant: - + Yourself Tu mateix @@ -26739,7 +27385,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Publica Pols a Wire - + RetroShare RetroShare @@ -26751,7 +27397,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú - + The Wire The Wire @@ -26759,7 +27405,7 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú WireGroupDialog - + Create New Wire @@ -26840,8 +27486,8 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Formulari - - + + Avatar Avatar @@ -26870,6 +27516,11 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú Sub/Un + + + Edit Profile + + misc @@ -26982,8 +27633,12 @@ Si tens molt ample de banda pots augmentar-lo fins a 30-40, per permetre que tú + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Imatges (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Imatges (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_cs.ts b/retroshare-gui/src/lang/retroshare_cs.ts index 00397da2c..24f243cde 100644 --- a/retroshare-gui/src/lang/retroshare_cs.ts +++ b/retroshare-gui/src/lang/retroshare_cs.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: rozšířené hledání - + Search Criteria Kritéria pro vyhledávání - + Add a further search criterion. Přidat další kriterium pro vyhledávání @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulář - - + + TextLabel Textový popisek @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Pozice ovládacích prvků - + Icon Only Pouze ikony @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Zvol styl ovládacích prvků - + Icon Size = 8x8 Ikona 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Velikost ikony = 128x128 - + Status Bar Stavový řádek @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Deaktivovat upozornění v systémové liště - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Ikona 32x32 @@ -828,14 +828,23 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Změnit fotku - + + TextLabel + Textový popisek + + + Your Avatar Picture Tvá fotka - + + Browse... + + + Add Avatar - Přidat fotku + Přidat fotku @@ -843,25 +852,34 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Odebrat - + Set your Avatar picture Zobrazit fotku - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Načíst fotku + Načíst fotku AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klikněte pro změnu svého avatara @@ -869,7 +887,7 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo RetroShare Bandwidth Usage Využití přenosové rychlosti + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Zobrazit nastavení + TextLabel + Textový popisek + + + Reset Reset - Receive Rate - Rychlost stahování + Rychlost stahování - Send Rate - Rychlost odesílání + Rychlost odesílání - + Always on Top Podržet nad ostatními - Style - Styl + Styl - + Changes the transparency of the Bandwidth Graph Změní průhlednost grafu rychlosti připojení - + 100 100 @@ -936,30 +975,27 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo % Opaque - Save - Uložit + Uložit - Cancel - Zrušit + Zrušit - + Since: Od: - Hide Settings - Skrýt nastavení + Skrýt nastavení BandwidthStatsWidget - + Sum Suma @@ -981,7 +1017,7 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Počet - + Average Průměr @@ -1115,7 +1151,7 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Textový popisek - + Comments Komentáře @@ -1193,6 +1229,85 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Textový popisek + + BoardsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Označit zprávu za přečtenou + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopírovat RetroShare odkaz + + + + + Expand + Rozbalit + + + + Set as read and remove item + Označit za přečtené a odstranit položku + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + Komentáře + + + + Comments + + + + + Hide + Skrýt + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Ale měj na paměti, že veškerá zdejší nastavení se mohou změnit s každo Log scale Logaritmické měřítko + + + Default + Výchozí + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + 0 + + + + I dislike this + + + + + Toggle Message Read Status + Označit zprávu za přečtenou + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Kopírovat RetroShare odkaz + + + + + Expand + Rozbalit + + + + Set as read and remove item + Označit za přečtené a odstranit položku + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + Komentáře + + + + Comments + + + + + Hide + Skrýt + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to - You have %1 new messages - Máte %1 nových zpráv + Máte %1 nových zpráv + + + You have %1 new message + Máte %1 novou zprávu + + + %1 new messages + %1 nových zpráv + + + %1 new message + %1 nová zpráva + + + + You have %1 mentions + - You have %1 new message - Máte %1 novou zprávu + You have %1 mention + - %1 new messages - %1 nových zpráv + %1 mentions + - %1 new message - %1 nová zpráva + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Smazat vše - - - mention(s) - - ChatLobbyWidget @@ -2114,13 +2329,11 @@ Double click a chat room to enter and chat. - Group chat - Skupinový chat + Skupinový chat - - + Private chat Soukromý chat @@ -2185,17 +2398,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">Zde se nastavuje uchovávání historie na vašem HDD pro různé druhy chatu. Zprávy staršího data budou smazány, aby nedošlo k přesycení sítě (např. pro konverzační místnosti a vzdálený chat).</p></body></html> - Chatlobbies - Konverzační místnosti + Konverzační místnosti - + Enabled: Aktivováno: @@ -2216,11 +2428,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2281,11 +2494,17 @@ Double click a chat room to enter and chat. + Broadcast Rozhlas - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Uložené zprávy (0 = bez omezení) @@ -2432,8 +2651,23 @@ Double click a chat room to enter and chat. Soukromá konverzace - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2602,7 +2836,7 @@ Double click a chat room to enter and chat. - + is typing... píše... @@ -2619,12 +2853,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Chcete opravdu vymazati historii z počítače? @@ -2696,7 +2930,7 @@ after HTML conversion. Nezastavovat vybarvování po X nálezech (vyšší zátěž CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Hledat předchozí </b><br/><i>Ctrl+Shift+G</i> @@ -2736,12 +2970,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Označ vybraný text</b><br><i>Ctrl+M</i> - + Person id: @@ -2757,7 +2991,7 @@ Double click on it to add his name on text writer. - + items found. Nalezeno. @@ -2777,7 +3011,7 @@ Double click on it to add his name on text writer. Zde napiš zprávu... - + Don't stop to color after Nezastavovat vybarvování po @@ -2935,12 +3169,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaily - + Local Address Lokální adresa @@ -2951,12 +3185,12 @@ Double click on it to add his name on text writer. Externí adresa - + Node info: - + Current address: @@ -2972,31 +3206,36 @@ Double click on it to add his name on text writer. Port - + Include signatures Zahrnout podpisy - + RetroShare RetroShare - + - + Error : cannot get peer details. Chyba : nemohu získat údaje kontaktu - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3012,22 +3251,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Šifrování - + Not connected Nespojen - + Retroshare node details Detaily o uzlu - + Node name : Jméno uzlu : @@ -3062,13 +3306,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate Certifikát @@ -3083,7 +3332,7 @@ Double click on it to add his name on text writer. - + Hidden Address Skrytá adresa @@ -3094,11 +3343,12 @@ Double click on it to add his name on text writer. žádný + <p>This certificate contains: - <p>Tento certifikát obsahuje + <p>Tento certifikát obsahuje - + <li>a <b>node ID</b> and <b>name</b> <li>a <b>ID uzlu</b> a <b>jméno</b> @@ -3111,12 +3361,12 @@ Double click on it to add his name on text writer. an <b>IP adresa</b> a <b>port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Tento certifikát musíš předat svým budoucím kontaktům. Použij emailu nebo jiné komunikační platformy.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Toto je ID<span style=" font-weight:600;">OpenSSL</span> certifikátu uzlu, který podepsán výše uvedeným <span style=" font-weight:600;">PGP</span> klíčem. </p></body></html> @@ -3126,7 +3376,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Šifrovcí metoda použitá <span style=" font-weight:600;">OpenSSL</span>. Spojení s kontakty</p><p>je vždy silně šifrováno a pokud je použito DHE, spojení navíc využívá</p><p>&quot;zabezpečené přeposílání&quot;.</p></body></html> - + with s @@ -3318,12 +3568,12 @@ Double click on it to add his name on text writer. Podrobnosti požadavku - + Peer details Podrobnosti o kontaktu - + Name: Jméno: @@ -3336,22 +3586,22 @@ Double click on it to add his name on text writer. Uzel: - + Location: Umístění: - + Options Možnosti - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Přidat do skupiny: @@ -3361,7 +3611,7 @@ Double click on it to add his name on text writer. Autentizovat kontakt (podepsat PGP klíč), potvrzuje vaši plnou důvěru,nelze vzít zpět! - + Please paste below your friend's Retroshare ID @@ -3386,7 +3636,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Přidat jako kontakt pro přímé spojení @@ -3395,7 +3645,7 @@ Double click on it to add his name on text writer. Klikni na "Finish" pro přidání kontaktu - + Sorry, some error appeared Je to smutné, ale došlo k nějaké chybě @@ -3415,32 +3665,32 @@ Double click on it to add his name on text writer. Detaily vašeho kontaktu: - + Key validity: Validita klíče: - + Profile ID: - + Signers Podepsali - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Tento protějšek se již nachází ve vašem seznamu kontaktů. Jeho opětovné přidání může nanejvýš nastavit jeho novou IP adresu. - + To accept the Friend Request, click the Accept button. @@ -3486,7 +3736,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Načítání certifikátu selhalo @@ -3519,12 +3769,12 @@ Double click on it to add his name on text writer. ID protějšku - + Not a valid Retroshare certificate! - + RetroShare Invitation Pozvánka do RetroShare - sociální P2P sítě zaměřené především na sdílení souborů. @@ -3544,12 +3794,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3597,7 +3847,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Žádost o přidání do kontaktu od: - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3693,12 +3973,12 @@ RetroShare neaspiruje na to být nejlepší sociální sítí, má své mouchy a Stahovat přímo od pokud možno - + IP-Addr: - + IP-Address @@ -3756,7 +4036,7 @@ RetroShare neaspiruje na to být nejlepší sociální sítí, má své mouchy a Přidat klíč do klíčenky - + This key is already in your keyring Tento klíč je již v klíčence @@ -3817,12 +4097,12 @@ které nemáte přímo v kontaktech. <p>V certifikátu není IP adresa. Discovery a DHT se ji pokusí najít. Po jejím nalezení se v Událostech objeví bezpečnostní upozornění, pomocí kterého můžete tuto adresu přidat do whitelist pro úspěšné spojení.</p> - + [Unknown] - + Added with certificate from %1 Přidán s certifikátem od %1 @@ -3909,7 +4189,12 @@ které nemáte přímo v kontaktech. UDP výsledek - + + Status + Status + + + <!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; } @@ -4331,7 +4616,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4479,7 +4764,7 @@ p, li { white-space: pre-wrap; } Nevybrány žádné limity Kruhu - + [Unknown] @@ -4494,7 +4779,7 @@ p, li { white-space: pre-wrap; } Odstranit - + Search Hledat @@ -4514,7 +4799,7 @@ p, li { white-space: pre-wrap; } Podepsáno známými uzly - + Edit Circle Upravit Kruh @@ -4534,12 +4819,12 @@ p, li { white-space: pre-wrap; } Anonymní ID - + Circle name - + Update @@ -4565,7 +4850,7 @@ p, li { white-space: pre-wrap; } PGP link ID - + Add Member @@ -4709,7 +4994,7 @@ p, li { white-space: pre-wrap; } - + Attachments Přílohy @@ -4755,7 +5040,7 @@ p, li { white-space: pre-wrap; } Přetáhněte soubory z výsledků vyhledávání - + Paste RetroShare Links Vložit RetroShare odkazy @@ -4765,7 +5050,7 @@ p, li { white-space: pre-wrap; } Vložit RetroShare odkaz - + Drop file error. Nastala chyba při přetahování souboru. @@ -4792,17 +5077,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Soubor je již přidán a zatříděn + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Soubor je již přidán a zatříděn + + + Please add a Subject Prosím zadejte předmět @@ -4833,12 +5142,12 @@ p, li { white-space: pre-wrap; } Opravdu chcete vygenerovat %1 zpráv? - + You are about to add files you're not actually sharing. Do you still want this to happen? Chcete přidat soubory, které však přímo nesdílíte. Opravdu? - + Edit Channel Post @@ -4858,7 +5167,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Ohledně vkládání nevlastněných souborů do kanálu @@ -4950,7 +5259,7 @@ p, li { white-space: pre-wrap; } - + No Forum Žádné fórum @@ -5405,7 +5714,7 @@ tam ji importujte. DHTGraphSource - + users uživatelé @@ -6408,7 +6717,7 @@ tam ji importujte. FlatStyle_RDM - + Friends Directories Sdílené soubory a složky mých kontaktů @@ -6903,7 +7212,7 @@ at least one peer was not added to a group Hledat kontakty - + Mark all Označit vše @@ -6917,7 +7226,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Editovat status @@ -7021,7 +7330,7 @@ at least one peer was not added to a group RetroShare rozhlas: zpráva je odeslána všem připojeným kontaktům. - + Network Síť @@ -7086,7 +7395,7 @@ at least one peer was not added to a group Jméno node musí obsahovat alespoň 3 znaky - + Failed to generate your new certificate, maybe PGP password is wrong! Nemůžu vygenerovat nový certifikát, možná jste špatně napsali PGP heslo! @@ -7117,7 +7426,7 @@ at least one peer was not added to a group - + Node name @@ -7384,12 +7693,12 @@ a vytvořit nový node využívající stejný profil. - + Profile generation failure - + Missing PGP certificate @@ -7765,7 +8074,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne Statistiky směrovače - + GroupBox @@ -7830,7 +8139,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Details Detaily @@ -7853,7 +8162,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne GlobalRouterStatisticsWidget - + Managed keys @@ -8054,7 +8363,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne GroupTreeWidget - + Title Nadpis @@ -8064,13 +8373,30 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne Hledat podle jména fóra - - + + + + Description Popis - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -8080,42 +8406,19 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Seřadit podle jména + Seřadit podle jména - Sort by Popularity - Seřadit podle oblíbenosti + Seřadit podle oblíbenosti - Sort by Last Post - Seřadit podle posledního příspěvku + Seřadit podle posledního příspěvku - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8130,40 +8433,35 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - - + + Last Post Poslední příspěvek - + + Name - - Unread - - - - + Popularity Popularita - - + + Never - Display - Zobrazit + Zobrazit - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8312,7 +8610,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne GxsChannelDialog - + Channels Kanály @@ -8333,12 +8631,12 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne Moje kanály - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Odebírané kanály @@ -8783,7 +9081,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Add new post @@ -8883,12 +9181,12 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Files Soubory - + Comments Komentáře @@ -8899,18 +9197,18 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Feeds Kanály - - + + Click to switch to list view - + Show unread posts only @@ -8920,12 +9218,12 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + No files in the channel, or no channel selected - + No text to display @@ -8985,7 +9283,7 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Download this file: @@ -9000,12 +9298,12 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne - + Comments (%1) - + [No name] @@ -9081,23 +9379,36 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne + Copy Retroshare link + + + + Subscribed Přihlášen - - Subscribe Odebírat - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Není vybrán žádný kanál @@ -9119,11 +9430,6 @@ Při používání sítě proto pokud možno používejte pouhou přezdívku, ne Channel Post Zpráva - - - new message(s) - - GxsCircleItem @@ -9616,7 +9922,7 @@ before you can comment Založit nové vlákno ve vybraném fóru - + Search forums Hledat ve fórech @@ -9625,12 +9931,12 @@ before you can comment Poslední příspěvek - + New Thread - + Threaded View podle vláken @@ -9640,19 +9946,19 @@ before you can comment Vše za sebou - - + + Title Nadpis - - + + Date Datum - + Author Autor @@ -9667,7 +9973,17 @@ before you can comment Načítám - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9724,23 +10040,23 @@ before you can comment Hledat v obsahu zprávy - + No name Bez jména - - + + Reply Odpovědět - + <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> - + Loading... @@ -9778,12 +10094,12 @@ before you can comment Označit za nepřečtené - + Copy RetroShare Link Kopírovat RetroShare odkaz - + Hide Skrýt @@ -9792,7 +10108,7 @@ before you can comment Rozbalit - + [unknown] @@ -9822,8 +10138,8 @@ before you can comment - - + + Distribution @@ -9922,12 +10238,12 @@ before you can comment Původní zpráva - + New thread - + Edit Editovat @@ -9983,7 +10299,7 @@ before you can comment - + Author's reputation @@ -10003,7 +10319,7 @@ before you can comment - + <b>Loading...<b> @@ -10043,6 +10359,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -10110,7 +10431,7 @@ This message is missing. You should receive it later. Na %1, %2 odpověděl: - + Forum name @@ -10142,11 +10463,6 @@ This message is missing. You should receive it later. Forum Post Zpráva - - - new message(s) - - GxsForumsDialog @@ -10575,7 +10891,7 @@ This message is missing. You should receive it later. Náhled tisku - + Unsubscribe Neodebírat @@ -10590,7 +10906,7 @@ This message is missing. You should receive it later. Otevřít v nové kartě - + Remove this search @@ -10600,12 +10916,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -10672,12 +10988,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -10692,7 +11008,7 @@ This message is missing. You should receive it later. Označit vše za nepřečtené - + AUTHD AUTHD @@ -11214,7 +11530,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11223,7 +11539,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11249,7 +11565,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11323,49 +11639,55 @@ p, li { white-space: pre-wrap; } Formulář - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Kopírovat váš certifikát do schránky @@ -11413,17 +11735,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11438,7 +11755,12 @@ new short format Pozvánka do RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Uložit jako... @@ -11703,14 +12025,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Vše - + Reputation @@ -11720,12 +12042,12 @@ p, li { white-space: pre-wrap; } Hledat - + Anonymous Id - + Create new Identity Vytvořit novou identitu @@ -11869,7 +12191,7 @@ p, li { white-space: pre-wrap; } - + Send message Odeslat zprávu @@ -11941,7 +12263,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Anonymní sdílení @@ -11956,24 +12278,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11988,7 +12310,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12047,13 +12369,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12113,7 +12440,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle Upravit Kruh @@ -12161,7 +12488,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12170,12 +12497,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12187,12 +12514,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12308,17 +12635,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12475,8 +12802,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12487,7 +12814,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -12497,7 +12824,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12557,7 +12884,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12567,7 +12894,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12605,7 +12932,7 @@ These identities will soon be not supported anymore. - + New identity @@ -12622,14 +12949,14 @@ These identities will soon be not supported anymore. - + N/A nedostupné - + Edit identity @@ -12640,24 +12967,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12677,12 +13007,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12692,7 +13047,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12702,7 +13057,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12742,12 +13102,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -12757,7 +13112,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12862,8 +13217,12 @@ These identities will soon be not supported anymore. + Quote + Citovat + + Send - Odeslat + Odeslat @@ -13021,7 +13380,7 @@ These identities will soon be not supported anymore. - + Options Nastavení @@ -13053,12 +13412,12 @@ These identities will soon be not supported anymore. Průvodce nastavením - + RetroShare %1 a secure decentralized communication platform RetroShare %1 - bezpečná decentralizovaná komunikační platforma - + Unfinished Nedokončeno @@ -13187,7 +13546,7 @@ These identities will soon be not supported anymore. Zobrazit - + Make sure this link has not been forged to drag you to a malicious website. Ujistěte se, že tento odkaz nebyl zfalšován za účelem dostat vás na škodlivé webové stránky. @@ -13232,7 +13591,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -13261,7 +13620,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose Napsat zprávu @@ -13363,7 +13722,7 @@ These identities will soon be not supported anymore. - + Tags Štítky @@ -13458,12 +13817,12 @@ These identities will soon be not supported anymore. Odsadí citaci - + Send To: Odeslat komu: - + &Left Zarovnat v&levo @@ -13493,7 +13852,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Ahoj,<br>doporučuji ti tento kontakt. Když důvěřuješ mě, můžeš důvěřovat také tomuto kontaktu. <br> @@ -13519,12 +13883,12 @@ These identities will soon be not supported anymore. - + Save Message Uložit zprávu - + Message has not been Sent. Do you want to save message to draft box? Zpráva nebyla odeslána. @@ -13536,7 +13900,7 @@ Chcete ji uložit jako koncept? Vložit RetroShare odkaz - + Add to "To" Přidat do "Komu" @@ -13790,7 +14154,7 @@ Do you want to save message ? Přidat další soubor - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13804,6 +14168,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13816,7 +14195,7 @@ Do you want to save message ? Od: - + Bullet list (disc) @@ -13856,13 +14235,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -14001,8 +14380,23 @@ Do you want to save message ? Zpráva - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14014,12 +14408,12 @@ Do you want to save message ? Doporučené soubory - + Download all Recommended Files Stáhnou všechny doporučené soubory - + Subject: Předmět: @@ -14094,12 +14488,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name Jméno souboru - + + Size Velikost @@ -14160,18 +14560,33 @@ Do you want to save message ? Stáhnout - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Stáhnout vše - + Print Document Vytisknout dokument @@ -14186,7 +14601,7 @@ Do you want to save message ? HTML soubory (*.htm *.html);;Všechny soubory (*) - + Load images always for this message @@ -14327,7 +14742,7 @@ Do you want to save message ? MessagesDialog - + New Message Nová zpráva @@ -14383,14 +14798,14 @@ Do you want to save message ? - + Tags Štítky - + Inbox Příchozí @@ -14465,7 +14880,7 @@ Do you want to save message ? Přeposlat zprávu - + Subject Předmět @@ -14577,7 +14992,7 @@ Do you want to save message ? - + Open in a new window Otevřít v novém okně @@ -14662,7 +15077,7 @@ Do you want to save message ? - + Drafts Koncepty @@ -14771,7 +15186,7 @@ Do you want to save message ? Odpovědět - + Delete Message Smazat zprávu @@ -14782,7 +15197,7 @@ Do you want to save message ? - + Expand Rozbalit @@ -14792,7 +15207,7 @@ Do you want to save message ? Odstranit položku - + from @@ -14801,6 +15216,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15107,7 +15527,7 @@ Reported error: - + Groups Skupiny @@ -15137,19 +15557,19 @@ Reported error: - - + + Search - + ID ID - + Search ID @@ -15159,7 +15579,7 @@ Reported error: - + Show Items @@ -15358,18 +15778,18 @@ at least one peer was not added to a group - + Error Chyba - + File is not writeable! - + File is not readable! @@ -15407,7 +15827,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15425,7 +15845,7 @@ at least one peer was not added to a group Toto je test. - + Newest on top @@ -15436,20 +15856,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15486,22 +15921,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room - + Systray Icon - + Message Zpráva @@ -15526,12 +15961,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected se připojil. @@ -15578,27 +16008,37 @@ at least one peer was not added to a group Skupinová konverzace - + + Toaster position + + + + Chat rooms - + Position Pozice - + + Activity + + + + X Margin Okraj X - + Y Margin Okraj Y - + Systray message @@ -15648,7 +16088,7 @@ at least one peer was not added to a group Oznámení - + Disable All Toasters @@ -15662,7 +16102,7 @@ at least one peer was not added to a group Kanál - + Systray @@ -15801,17 +16241,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : Jméno : @@ -15866,22 +16301,17 @@ at least one peer was not added to a group Absolutní - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15895,7 +16325,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15905,22 +16335,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Podepsat PGP klíč + Podepsat PGP klíč - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15940,7 +16364,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16006,27 +16430,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Chyba : nemohu získat údaje kontaktu - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16038,7 +16462,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16083,27 +16507,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Podepisování selhalo - - Maybe password is wrong - Možná že bylo špatně zadané heslo + + Check the password! + - + Maybe password is wrong + Možná že bylo špatně zadané heslo + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16282,8 +16726,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16300,7 +16743,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16439,7 +16882,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel Textový popisek @@ -16483,8 +16926,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Komentáře @@ -16515,6 +16958,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Add Comment Přidat komentář + + + Album + Album + PhotoItem @@ -16524,12 +16972,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formulář - + TextLabel Textový popisek - + <!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; } @@ -16613,7 +17061,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -16653,7 +17101,7 @@ requesting to edit it! - + Stop @@ -16877,17 +17325,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Povolit všechny pluginy - + Plugin look-up directories Adresář se zásuvnými moduly - + Plugins Zásuvné moduly @@ -17217,7 +17665,7 @@ p, li { white-space: pre-wrap; } Odeslané odkazy - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17352,13 +17800,13 @@ p, li { white-space: pre-wrap; } 0 - - + + Comments Komentáře - + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -17368,7 +17816,7 @@ p, li { white-space: pre-wrap; } - + Comment Komentáře @@ -17389,12 +17837,12 @@ p, li { white-space: pre-wrap; } - + Hide Skrýt - + Vote up @@ -17404,7 +17852,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item Označit za přečtené a odstranit položku @@ -17465,7 +17913,7 @@ p, li { white-space: pre-wrap; } Textový popisek - + Loading Nahrávám @@ -17511,13 +17959,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17527,60 +17969,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown neznámé - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel Textový popisek - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -17591,7 +18023,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17660,7 +18092,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link Kopírovat RetroShare odkaz @@ -17695,7 +18132,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -17811,8 +18248,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18084,12 +18531,7 @@ tam ji importujte. PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -18104,17 +18546,32 @@ tam ji importujte. - + GroupLabel - + IDLabel - + + From: + Od: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18139,10 +18596,20 @@ tam ji importujte. - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18152,13 +18619,48 @@ tam ji importujte. - + + Post + + + + Cancel Zrušit - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -18185,10 +18687,18 @@ tam ji importujte. Formulář - - - - + + + + + Click to view picture + + + + + + + Image @@ -18196,44 +18706,44 @@ tam ji importujte. PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18243,17 +18753,17 @@ tam ji importujte. - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18263,7 +18773,7 @@ tam ji importujte. - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18271,7 +18781,7 @@ tam ji importujte. PulseTopLevel - + retweeted @@ -18286,7 +18796,7 @@ tam ji importujte. - + follow Parent Group @@ -18296,7 +18806,7 @@ tam ji importujte. ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18321,7 +18831,7 @@ tam ji importujte. - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18357,29 +18867,29 @@ tam ji importujte. - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18457,7 +18967,7 @@ tam ji importujte. QObject - + Confirmation Potvrzení @@ -18696,7 +19206,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Výsledek - + Unable to make path @@ -18731,7 +19241,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Požadavek o stáhnutí souboru byl zrušen. - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -18869,7 +19379,7 @@ Reported error is: - + TR up @@ -18914,7 +19424,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -18930,7 +19440,7 @@ Reported error is: - + %1 seconds ago @@ -19014,7 +19524,7 @@ Security: no anonymous IDs - + Error Chyba @@ -19405,9 +19915,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Tento certifikát obsahuje + <p>Tento certifikát obsahuje @@ -19752,7 +20261,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -19974,18 +20483,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20422,7 +20952,7 @@ p, li { white-space: pre-wrap; } Stáhnout! - + File Soubor @@ -20437,7 +20967,7 @@ p, li { white-space: pre-wrap; } Kontrolní součet - + Bad filenames have been cleaned @@ -20485,7 +21015,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Uložit - + Collection Editor @@ -20500,7 +21030,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -20515,12 +21045,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... Zvolit... @@ -20767,7 +21297,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -20787,7 +21317,7 @@ If you believe it is correct, remove the corresponding line from the file and re IP - + Profile ID @@ -20800,10 +21330,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Nadpis + + + UnRead + + Date @@ -20815,7 +21350,7 @@ If you believe it is correct, remove the corresponding line from the file and re Autor - + Information for this identity is currently missing. @@ -20853,7 +21388,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] [ ... chybějící zpráva ... ] @@ -20861,7 +21396,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -20921,7 +21456,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21276,7 +21811,7 @@ Vysoká pravděpodobnost že soubor bude nalezen Jméno souboru - + Download Stáhnout @@ -21355,7 +21890,7 @@ Vysoká pravděpodobnost že soubor bude nalezen Otevřít složku - + Create Collection... @@ -21375,7 +21910,7 @@ Vysoká pravděpodobnost že soubor bude nalezen Stáhnou podle souboru kolekce... - + Collection Kolekce @@ -21480,12 +22015,12 @@ Vysoká pravděpodobnost že soubor bude nalezen Podrobnosti o kontaktu - + Deny friend Odmítnout kontakt - + Chat Konverzace @@ -21495,7 +22030,7 @@ Vysoká pravděpodobnost že soubor bude nalezen Konverzovat - + Expand Rozbalit @@ -21762,13 +22297,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22234,7 +22769,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Síť @@ -22262,7 +22797,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22359,7 +22894,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22394,12 +22929,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23066,7 +23601,7 @@ p, li { white-space: pre-wrap; } Chybí PGP certifikát - + Wrong password @@ -23108,7 +23643,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Přidat mezi kontakty @@ -23164,7 +23699,7 @@ This choice can be reverted in settings. - + DHT DHT @@ -23696,7 +24231,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -23706,13 +24241,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -23721,6 +24255,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -23994,27 +24553,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -24022,7 +24576,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads Stahování @@ -24033,7 +24587,7 @@ p, li { white-space: pre-wrap; } Odesílání - + Name i.e: file name Jméno @@ -24240,7 +24794,7 @@ p, li { white-space: pre-wrap; } Zvolit... - + Move in Queue... Přesunout do fronty... @@ -24334,7 +24888,7 @@ p, li { white-space: pre-wrap; } Prosím vložte nové--a platné--jméno souboru - + Expand all Rozbalit vše @@ -24466,7 +25020,7 @@ p, li { white-space: pre-wrap; } - + Columns Sloupce @@ -24477,7 +25031,7 @@ p, li { white-space: pre-wrap; } - + Path Cesta @@ -24487,7 +25041,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24497,7 +25051,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -24512,7 +25066,7 @@ p, li { white-space: pre-wrap; } - + Collection Kolekce @@ -24754,7 +25308,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Neznámý Peer @@ -24850,7 +25404,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Máte %1 nových zpráv @@ -25222,7 +25776,7 @@ p, li { white-space: pre-wrap; } Vytvořit skupinu - + Subscribe to Group @@ -25316,8 +25870,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -25328,7 +25882,7 @@ p, li { white-space: pre-wrap; } - + Preview Náhled @@ -25353,12 +25907,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -25378,7 +25932,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -25416,7 +25970,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -25426,12 +25980,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh @@ -25466,12 +26019,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25505,7 +26058,7 @@ p, li { white-space: pre-wrap; } Nový - + Yourself @@ -25519,7 +26072,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -25531,7 +26084,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -25539,7 +26092,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25620,8 +26173,8 @@ p, li { white-space: pre-wrap; } Formulář - - + + Avatar Avatar @@ -25650,6 +26203,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -25762,7 +26320,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_da.ts b/retroshare-gui/src/lang/retroshare_da.ts index 9a05b487d..41f99845c 100644 --- a/retroshare-gui/src/lang/retroshare_da.ts +++ b/retroshare-gui/src/lang/retroshare_da.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Indstillinger + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,19 @@ p, li { white-space: pre-wrap; } - - Save - - - - Cancel - Annuller + Annuller - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +887,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +965,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Navn + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1179,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1241,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + Navn + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1528,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1557,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1981,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2046,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2072,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2138,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2287,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2472,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2489,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2566,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2602,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2623,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2643,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2801,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Detaljer - + Local Address Lokale Adresse @@ -2635,12 +2817,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2838,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2888,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2938,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2964,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2975,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +3000,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3084,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: Navn: - + Location: - + Options Indstillinger - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3119,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3144,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3169,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3240,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3270,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3323,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3397,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3432,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3490,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3570,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3997,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4137,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4152,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4168,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4184,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4211,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4337,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4383,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4393,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4420,37 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4481,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4506,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4594,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5009,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6012,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6503,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6517,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6621,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6686,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6717,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6976,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7344,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7409,7 @@ p, li { white-space: pre-wrap; } - + Details Detaljer @@ -7175,7 +7432,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7633,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7643,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7676,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7691,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name Navn - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7864,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7885,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8253,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8353,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8369,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8390,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8455,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8470,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8551,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8602,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9086,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9106,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9133,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9188,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -8994,17 +9242,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9282,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9366,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9427,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9447,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9487,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9559,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9591,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9996,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10011,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10021,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10093,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10113,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10627,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10636,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10662,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10736,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10832,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10852,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11122,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11139,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11288,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11360,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11375,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11407,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11466,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11537,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11585,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11594,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11611,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11732,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11899,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11911,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11921,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11981,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11991,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12029,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12046,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12064,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12104,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12144,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12154,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12199,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12209,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12314,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12473,7 @@ These identities will soon be not supported anymore. - + Options Indstillinger @@ -12218,12 +12505,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12639,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12684,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12713,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12815,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12910,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12945,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12976,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12992,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13246,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13260,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13287,7 @@ Do you want to save message ? Fra: - + Bullet list (disc) @@ -13020,13 +13327,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13472,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13500,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13580,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13652,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13693,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13798,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13810,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13888,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13968,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14053,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14142,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14153,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14163,7 @@ Do you want to save message ? - + from @@ -13829,6 +14172,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14476,7 @@ Reported error: - + Groups @@ -14158,19 +14506,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14528,7 @@ Reported error: - + Show Items @@ -14379,18 +14727,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14776,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14790,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14801,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14862,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14898,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14945,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15025,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15035,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15162,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15222,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15246,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15256,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15281,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15347,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15379,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15424,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong - Måske password er forkert + + Check the password! + - + Maybe password is wrong + Måske password er forkert + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15635,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15652,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15784,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15820,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15848,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15862,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15947,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15987,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16211,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16547,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16678,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16694,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16715,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16730,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16791,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16449,13 +16821,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16465,60 +16831,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16529,7 +16885,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16598,7 +16954,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16633,7 +16994,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16749,8 +17110,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17018,12 +17389,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17038,17 +17404,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + Fra: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17073,10 +17454,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17086,13 +17477,48 @@ and use the import button to load it - + + Post + + + + Cancel Annuller - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17104,10 +17530,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17115,44 +17549,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17162,17 +17596,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17182,7 +17616,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17190,7 +17624,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17205,7 +17639,7 @@ and use the import button to load it - + follow Parent Group @@ -17215,7 +17649,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17240,7 +17674,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17276,29 +17710,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17376,7 +17810,7 @@ and use the import button to load it QObject - + Confirmation @@ -17615,7 +18049,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17650,7 +18084,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17788,7 +18222,7 @@ Reported error is: - + TR up @@ -17833,7 +18267,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17849,7 +18283,7 @@ Reported error is: - + %1 seconds ago @@ -17933,7 +18367,7 @@ Security: no anonymous IDs - + Error @@ -18323,11 +18757,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18661,7 +19090,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18883,18 +19312,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19331,7 +19781,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19346,7 +19796,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19394,7 +19844,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19409,7 +19859,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19424,12 +19874,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19676,7 +20126,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name Navn @@ -19696,7 +20146,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19709,10 +20159,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19724,7 +20179,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19762,7 +20217,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19770,7 +20225,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19830,7 +20285,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20184,7 +20639,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20263,7 +20718,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20283,7 +20738,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20388,12 +20843,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20403,7 +20858,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20666,13 +21121,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21138,7 +21593,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21166,7 +21621,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21263,7 +21718,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21298,12 +21753,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21968,7 +22423,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22010,7 +22465,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22066,7 +22521,7 @@ This choice can be reverted in settings. - + DHT @@ -22598,7 +23053,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22608,13 +23063,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22623,6 +23077,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22896,27 +23375,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22924,7 +23398,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22935,7 +23409,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name Navn @@ -23142,7 +23616,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23236,7 +23710,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23368,7 +23842,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23379,7 +23853,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23389,7 +23863,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23399,7 +23873,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23414,7 +23888,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23656,7 +24130,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23752,7 +24226,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24120,7 +24594,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24214,8 +24688,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24226,7 +24700,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24251,12 +24725,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24276,7 +24750,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24314,7 +24788,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24324,12 +24798,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24364,12 +24833,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24399,7 +24868,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24409,7 +24878,7 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare @@ -24421,7 +24890,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24429,7 +24898,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24510,8 +24979,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24540,6 +25009,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24652,7 +25126,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_de.ts b/retroshare-gui/src/lang/retroshare_de.ts index ec5c0cd1b..4fa1bb85b 100644 --- a/retroshare-gui/src/lang/retroshare_de.ts +++ b/retroshare-gui/src/lang/retroshare_de.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version RetroShare-Version @@ -79,7 +79,7 @@ Viel Spaß ;-) - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Erweiterte Suche - + Search Criteria Suchkriterien - + Add a further search criterion. Ein weiteres Suchkriterium hinzufügen. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Album @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formular - - + + TextLabel TextLabel @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Werkzeugleiste - + Icon Only Nur Symbole @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Wähle den Stil für die Werkzeugschaltflächen - + Icon Size = 8x8 Symbolgröße = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Symbolgröße = 128x128 - + Status Bar Statusleiste @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Symbolgröße = 32x32 @@ -828,14 +828,23 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Avatar wechseln - + + TextLabel + TextLabel + + + Your Avatar Picture Dein Avatarbild - + + Browse... + + + Add Avatar - Avatar hinzufügen + Avatar hinzufügen @@ -843,25 +852,34 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Entfernen - + Set your Avatar picture Dein Avatarbild festlegen - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Avatar laden + Avatar laden AvatarWidget - - Choose avatar - - - - + Click to change your avatar Klick zum Ändern deines Avatars @@ -869,7 +887,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto RetroShare Bandwidth Usage RetroShare Bandbreitennutzung + + + PushButton + + - + Up + Hoch + + + + Down + Herunter + + + + Clears the graph + + + + Show Settings Einstellungen anzeigen + TextLabel + TextLabel + + + Reset Zurücksetzen - Receive Rate - Empfangsrate + Empfangsrate - Send Rate - Senderate + Senderate - + Always on Top Immer im Vordergrund - Style - Stil + Stil - + Changes the transparency of the Bandwidth Graph Ändert die Transparenz des Bandbreiten-Graphen - + 100 100 @@ -936,30 +975,27 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto % undurchsichtig - Save - Speichern + Speichern - Cancel - Abbrechen + Abbrechen - + Since: Seit: - Hide Settings - Einstellungen verbergen + Einstellungen verbergen BandwidthStatsWidget - + Sum Summe @@ -981,7 +1017,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Anzahl - + Average Durchschnitt @@ -1115,7 +1151,7 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto TextLabel - + Comments Kommentare @@ -1193,6 +1229,85 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto TextLabel + + BoardsCommentsItem + + + I like this + Das gefällt mir + + + + 0 + 0 + + + + I dislike this + Das gefällt mir nicht + + + + Toggle Message Read Status + Lesestatus der Nachricht umschalten + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + RetroShare-Link kopieren + + + + + Expand + Erweitern + + + + Set as read and remove item + Als gelesen markieren und Eintrag entfernen + + + + Remove Item + + + + + Name + Name + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Verbergen + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Aber denke daran, dass alle Daten hier VERLOREN gehen werden, wenn wir die Proto Log scale + + + Default + Standard + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Das gefällt mir + + + + 0 + 0 + + + + I dislike this + Das gefällt mir nicht + + + + Toggle Message Read Status + Lesestatus der Nachricht umschalten + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + RetroShare-Link kopieren + + + + + Expand + Erweitern + + + + Set as read and remove item + Als gelesen markieren und Eintrag entfernen + + + + Remove Item + + + + + Name + Name + + + + Comm value + + + + + Comment + Kommentar + + + + Comments + + + + + Hide + Verbergen + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chats - You have %1 new messages - Du hast %1 neue Nachrichten + Du hast %1 neue Nachrichten + + + You have %1 new message + Du hast %1 neue Nachricht + + + %1 new messages + %1 neue Nachrichten + + + %1 new message + %1 neue Nachricht + + + + You have %1 mentions + - You have %1 new message - Du hast %1 neue Nachricht + You have %1 mention + - %1 new messages - %1 neue Nachrichten + %1 mentions + - %1 new message - %1 neue Nachricht + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Alle entfernen - - - mention(s) - - ChatLobbyWidget @@ -2114,13 +2329,11 @@ Double click a chat room to enter and chat. Variante: - Group chat - Gruppenchat + Gruppenchat - - + Private chat Privater Chat @@ -2185,17 +2398,16 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">In diesem Tab kannst du für die verschiedenen Chatsysteme festlegen, wieviele Nachrichten RetroShare auf Festplatte gespeichert hält, und wieviel der vorangehenden Unterhaltung angezeigt wird. Die maximale Speicherzeit erlaubt das Verwerfen alter Nachrichten und verhindert das unberechenbare Füllen des Unterhaltungsverlaufs (z. B. Chatlobbys und Fernchat).</p></body></html> - Chatlobbies - Chatlobbys + Chatlobbys - + Enabled: Aktiviert: @@ -2216,11 +2428,12 @@ Double click a chat room to enter and chat. + Chat rooms Chaträume - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2281,11 +2494,17 @@ Double click a chat room to enter and chat. + Broadcast Rundschreiben - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Gespeicherte Nachrichten (0 = unbegrenzt) @@ -2432,8 +2651,23 @@ Double click a chat room to enter and chat. Privater Chat - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2602,7 +2836,7 @@ Double click a chat room to enter and chat. - + is typing... tippt... @@ -2620,12 +2854,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Möchtest du wirklich den Nachrichtenverlauf löschen? @@ -2697,7 +2931,7 @@ after HTML conversion. Nach Finden von X Elementen mit dem Einfärben nicht aufhören (benötigt mehr CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Vorherige finden </b><br/><i>Strg+Umschalt+G</i> @@ -2737,12 +2971,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Markiere diesen ausgewählten Text</b><br><i>Strg+M</i> - + Person id: @@ -2758,7 +2992,7 @@ Double click on it to add his name on text writer. - + items found. Elemente gefunden. @@ -2778,7 +3012,7 @@ Double click on it to add his name on text writer. Hier eine Nachricht eingeben - + Don't stop to color after Nach Finden von @@ -2936,12 +3170,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Details - + Local Address Lokale Adresse @@ -2952,12 +3186,12 @@ Double click on it to add his name on text writer. Externe Adresse - + Node info: - + Current address: @@ -2973,31 +3207,36 @@ Double click on it to add his name on text writer. Port - + Include signatures Signaturen einschließen - + RetroShare RetroShare - + - + Error : cannot get peer details. Fehler: Kann Nachbardetails nicht ermitteln. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -3013,22 +3252,27 @@ Double click on it to add his name on text writer. - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + Encryption Verschlüsselung - + Not connected Nicht verbunden - + Retroshare node details RetroShare-Netzknotendetails - + Node name : Netzknotenname : @@ -3063,13 +3307,18 @@ Double click on it to add his name on text writer. Statusnachricht: - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate RetroShare-Zertifikat @@ -3084,7 +3333,7 @@ Double click on it to add his name on text writer. - + Hidden Address Versteckte Adresse @@ -3095,11 +3344,12 @@ Double click on it to add his name on text writer. keine + <p>This certificate contains: - <p>Dieses Zertifikat enthält: + <p>Dieses Zertifikat enthält: - + <li>a <b>node ID</b> and <b>name</b> <li>eine <b>Netzknoten-ID</b> und <b>Name</b> @@ -3112,12 +3362,12 @@ Double click on it to add his name on text writer. eine <b>IP-Adresse</b> und <b>Port</b> - + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> Du kannst dieses Zertifikat zum Schließen von neuen Freundschaften verwenden. Versende es per E-Mail oder gib es von Hand zu Hand. - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> <html><head/><body><p>Dies ist die ID des <span style=" font-weight:600;">OpenSSL</span>-Zertifikates des Netzknotens, welches mit obigem <span style=" font-weight:600;">PGP</span>-Schlüssel signiert wurde.</p></body></html> @@ -3127,7 +3377,7 @@ Double click on it to add his name on text writer. <html><head/><body><p>Dies ist die Verschlüsselungsmethode die von <span style=" font-weight:600;">OpenSSL</span> benutzt wird. Die Verbindung zu befreundeten Netzknoten ist immer stark verschlüsselt.</p><p>Und wenn DHE vorhanden ist dann verwendet die Verbindung noch dazu</p><p>&quot;Perfect Forward Secrecy&quot;.</p></body></html> - + with mit @@ -3319,12 +3569,12 @@ Double click on it to add his name on text writer. Details der Anfrage - + Peer details Nachbardetails - + Name: Name: @@ -3337,12 +3587,12 @@ Double click on it to add his name on text writer. Netzknoten: - + Location: Ort: - + Options Optionen @@ -3367,12 +3617,12 @@ Double click on it to add his name on text writer. Zertifikat einfügen - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Freund zur Gruppe hinzufügen: @@ -3382,7 +3632,7 @@ Double click on it to add his name on text writer. Freund authentifizieren (PGP-Schlüssel unterzeichnen) - + Please paste below your friend's Retroshare ID @@ -3407,7 +3657,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Als Freund hinzufügen, zu dem verbunden wird @@ -3416,7 +3666,7 @@ Double click on it to add his name on text writer. Abschließen-Knopf anklicken, um die Anfrage zu akzeptieren - + Sorry, some error appeared Entschuldigung, es trat ein Fehler auf @@ -3436,32 +3686,32 @@ Double click on it to add his name on text writer. Details über deinen Freund: - + Key validity: Schlüssel-Gültigkeit: - + Profile ID: - + Signers Unterzeichner - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Dieser Nachbar ist bereits in deiner Freundliste vorhanden. Das nochmalige Hinzufügen ändert nur seine IP. - + To accept the Friend Request, click the Accept button. @@ -3507,7 +3757,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Das Zertifikat konnte nicht geladen werden @@ -3544,12 +3794,12 @@ Double click on it to add his name on text writer. Zertifikat scheint gültig zu sein - + Not a valid Retroshare certificate! Kein gültiges RetroShare-Zertifikat! - + RetroShare Invitation RetroShare-Einladung @@ -3569,12 +3819,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3622,7 +3872,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du hast eine Freundschaftsanfrage von - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3710,12 +3990,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Wenn verfügbar als direkte Quelle nutzen - + IP-Addr: IP-Adr.: - + IP-Address IP-Adresse @@ -3773,7 +4053,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Schlüssel zum Schlüsselbund hinzufügen. - + This key is already in your keyring Schlüssel ist bereits in deinem Schlüsselbund. @@ -3833,12 +4113,12 @@ Das Zertifikat hat die falsche Versionsnummer. Beachte, dass v0.6- und v0.5-Netz <p>Dieses Zertifikat enthält keine IP. Du wirst auf Discovery und DHT angewiesen sein un sie herauszufinden. Da du Whitelist-Freigabe forderst wird der Nachbar eine Sicherheitswarnung im Neuigkeitenreiter auslösen. Von dort kannst die die IP freigeben.</p> - + [Unknown] [Unbekannt] - + Added with certificate from %1 Hinzugefügt mit Zertifikat von %1 @@ -3925,7 +4205,12 @@ Das Zertifikat hat die falsche Versionsnummer. Beachte, dass v0.6- und v0.5-Netz UDP-Ergebnis - + + Status + Status + + + <!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; } @@ -4347,7 +4632,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4499,7 +4784,7 @@ p, li { white-space: pre-wrap; } Keine Einschränkungen für Kreis gewählt - + [Unknown] [Unbekannt] @@ -4514,7 +4799,7 @@ p, li { white-space: pre-wrap; } Entfernen - + Search Suchen @@ -4534,7 +4819,7 @@ p, li { white-space: pre-wrap; } Von bekannten Netzknoten unterzeichnet - + Edit Circle Kreis bearbeiten @@ -4554,12 +4839,12 @@ p, li { white-space: pre-wrap; } Anonyme ID - + Circle name Kreisname - + Update Aktualisieren @@ -4585,7 +4870,7 @@ p, li { white-space: pre-wrap; } PGP-verknüpfte ID - + Add Member Mitglied hinzufügen @@ -4729,7 +5014,7 @@ p, li { white-space: pre-wrap; } - + Attachments Anhänge @@ -4775,7 +5060,7 @@ p, li { white-space: pre-wrap; } Drag'n'Drop Dateien aus den Suchergebnissen - + Paste RetroShare Links RetroShare-Links einfügen @@ -4785,7 +5070,7 @@ p, li { white-space: pre-wrap; } RetroShare-Link einfügen - + Drop file error. Dateifehler bei Drag'n'Drop. @@ -4812,17 +5097,41 @@ p, li { white-space: pre-wrap; } - + RetroShare RetroShare - - File already Added and Hashed - Datei wurde schon hinzugefügt und gehasht + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Datei wurde schon hinzugefügt und gehasht + + + Please add a Subject Bitte einen Betreff hinzufügen @@ -4853,12 +5162,12 @@ p, li { white-space: pre-wrap; } Möchtest du wirklich %1 Nachrichten erzeugen? - + You are about to add files you're not actually sharing. Do you still want this to happen? Du bist dabei, Dateien hinzuzufügen, die du nicht freigegeben hast. Willst du das wirklich tun? - + Edit Channel Post @@ -4878,7 +5187,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. Du willst Dateien zu einem Kanal hinzufügen, die dir nicht gehören. @@ -4970,7 +5279,7 @@ p, li { white-space: pre-wrap; } - + No Forum Kein Forum @@ -5425,7 +5734,7 @@ und den Import zum Laden verwenden DHTGraphSource - + users Benutzer @@ -6428,7 +6737,7 @@ und den Import zum Laden verwenden FlatStyle_RDM - + Friends Directories Dateien von Freunden @@ -6927,7 +7236,7 @@ at least one peer was not added to a group Freunde suchen - + Mark all Alle markieren @@ -6941,7 +7250,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Statusnachricht bearbeiten @@ -7045,7 +7354,7 @@ at least one peer was not added to a group RetroShare-Rundschreiben: Nachrichten werden an alle verbundenen Freunde gesendet. - + Network Netzwerk @@ -7110,7 +7419,7 @@ at least one peer was not added to a group Das Feld Netzknoten ist mit min. 3 Zeichen zu versehen - + Failed to generate your new certificate, maybe PGP password is wrong! Das Erzeugen deines neuen Zertifikats ist fehlgeschlagen. Vielleicht ist das PGP-Passwort falsch? @@ -7145,7 +7454,7 @@ at least one peer was not added to a group - + Node name Knotenname @@ -7412,12 +7721,12 @@ und den Import zum Laden verwenden - + Profile generation failure Profilerzeugung fehlgeschlagen - + Missing PGP certificate Fehlendes PGP-Zertifikat @@ -7789,7 +8098,7 @@ p, li { white-space: pre-wrap; } Routerstatistiken - + GroupBox @@ -7854,7 +8163,7 @@ p, li { white-space: pre-wrap; } - + Details Details @@ -7877,7 +8186,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys Verwaltete Schlüssel @@ -8086,7 +8395,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Titel @@ -8096,13 +8405,30 @@ p, li { white-space: pre-wrap; } Titel durchsuchen - - + + + + Description Beschreibung - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Beschreibung durchsuchen @@ -8112,42 +8438,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Nach Name sortieren + Nach Name sortieren - Sort by Popularity - Nach Beliebtheit sortieren + Nach Beliebtheit sortieren - Sort by Last Post - Nach letztem Beitrag sortieren + Nach letztem Beitrag sortieren - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8162,40 +8465,35 @@ p, li { white-space: pre-wrap; } ID - - + + Last Post Letzter Beitrag - + + Name Name - - Unread - - - - + Popularity Beliebtheit - - + + Never Nie - Display - Anzeigen + Anzeigen - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8344,7 +8642,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Kanäle @@ -8365,12 +8663,12 @@ p, li { white-space: pre-wrap; } Eigene Kanäle - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Abonnierte Kanäle @@ -8887,7 +9185,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8987,12 +9285,12 @@ p, li { white-space: pre-wrap; } - + Files Dateien - + Comments Kommentare @@ -9003,18 +9301,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -9024,12 +9322,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -9089,7 +9387,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -9104,12 +9402,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9185,23 +9483,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Abonniert - - Subscribe Abonnieren - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Keinen Kanal gewählt @@ -9223,11 +9534,6 @@ p, li { white-space: pre-wrap; } Channel Post Kanalbeitrag - - - new message(s) - - GxsCircleItem @@ -9745,7 +10051,7 @@ bevor du kommentieren kannst. Ein neues Thema im ausgewählten Forum starten - + Search forums Foren durchsuchen @@ -9754,12 +10060,12 @@ bevor du kommentieren kannst. Letzter Beitrag - + New Thread Neues Thema - + Threaded View Hierarchische Ansicht @@ -9769,19 +10075,19 @@ bevor du kommentieren kannst. Ebene Ansicht - - + + Title Titel - - + + Date Datum - + Author Autor @@ -9796,7 +10102,17 @@ bevor du kommentieren kannst. Lade - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9853,23 +10169,23 @@ bevor du kommentieren kannst. Inhalt durchsuchen - + No name Kein Name - - + + Reply Antwort - + <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> - + Loading... @@ -9907,12 +10223,12 @@ bevor du kommentieren kannst. Als ungelesen markieren - + Copy RetroShare Link RetroShare-Link kopieren - + Hide Verbergen @@ -9925,7 +10241,7 @@ bevor du kommentieren kannst. [Gebannt] - + [unknown] [unbekannt] @@ -9955,8 +10271,8 @@ bevor du kommentieren kannst. Nur Ihre Augen - - + + Distribution Verteilung @@ -10059,12 +10375,12 @@ bevor du kommentieren kannst. Ursprüngliche Nachricht - + New thread - + Edit Bearbeiten @@ -10120,7 +10436,7 @@ bevor du kommentieren kannst. - + Author's reputation @@ -10140,7 +10456,7 @@ bevor du kommentieren kannst. - + <b>Loading...<b> @@ -10180,6 +10496,11 @@ bevor du kommentieren kannst. Storage Speicherung + + + Last seen at friends: + + Moderators @@ -10247,7 +10568,7 @@ This message is missing. You should receive it later. Am %1, schrieb %2: - + Forum name Forumsname @@ -10279,11 +10600,6 @@ This message is missing. You should receive it later. Forum Post Forumsbeitrag - - - new message(s) - - GxsForumsDialog @@ -10732,7 +11048,7 @@ This message is missing. You should receive it later. Druckvorschau - + Unsubscribe Abbestellen @@ -10747,7 +11063,7 @@ This message is missing. You should receive it later. In neuem Reiter öffnen - + Remove this search @@ -10757,12 +11073,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Details anzeigen @@ -10829,12 +11145,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link RetroShare-Link kopieren @@ -10849,7 +11165,7 @@ This message is missing. You should receive it later. Alle als ungelesen markieren - + AUTHD AUTHD @@ -11422,7 +11738,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11431,7 +11747,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11457,7 +11773,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11535,27 +11851,22 @@ p, li { white-space: pre-wrap; } Formular - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! @@ -11565,23 +11876,34 @@ p, li { white-space: pre-wrap; } + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help Webhilfe öffnen - + Copy your Cert to Clipboard Dein Zertifikat in die Zwischenablage kopieren @@ -11629,17 +11951,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11654,7 +11971,12 @@ new short format RetroShare-Einladung - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... Speichern als... @@ -11919,14 +12241,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Alle - + Reputation Reputation @@ -11936,12 +12258,12 @@ p, li { white-space: pre-wrap; } Suchen - + Anonymous Id Anonyme ID - + Create new Identity Neue Identität erstellen @@ -12085,7 +12407,7 @@ p, li { white-space: pre-wrap; } Identitäts-ID - + Send message Nachricht senden @@ -12157,7 +12479,7 @@ p, li { white-space: pre-wrap; } Insgesamt: - + Anonymous Anonym @@ -12172,24 +12494,24 @@ p, li { white-space: pre-wrap; } Kennung suchen - + This identity is owned by you Diese Identität gehört dir - - + + My own identities Meine eigenen Identitäten - - + + My contacts Meine Kontakte - + Show Items @@ -12204,7 +12526,7 @@ p, li { white-space: pre-wrap; } - + Other circles Andere Kreise @@ -12263,13 +12585,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: Ihr Status: @@ -12329,7 +12656,7 @@ p, li { white-space: pre-wrap; } Mitglied - + Edit Circle Kreis bearbeiten @@ -12377,7 +12704,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12386,12 +12713,12 @@ These identities will soon be not supported anymore. - + [Unknown node] [Unbekannter Knoten] - + Unverified signature from node @@ -12403,12 +12730,12 @@ These identities will soon be not supported anymore. Ungeprüfte Signatur - + [unverified] [unbestätigt] - + Identity owned by you, linked to your Retroshare node Dir gehörende, mit deinem RetroShare-Netzknoten verknüpfte Identität @@ -12524,17 +12851,17 @@ These identities will soon be not supported anymore. - + Banned Gebannt - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive positiv @@ -12707,8 +13034,8 @@ These identities will soon be not supported anymore. - - + + People Leute @@ -12719,7 +13046,7 @@ These identities will soon be not supported anymore. Dein Avatar - + Linked to neighbor nodes Mit Nachbarknoten verknüpft @@ -12729,7 +13056,7 @@ These identities will soon be not supported anymore. Mit entfernten Netzknoten verknüpft - + Linked to a friend Retroshare node Mit befreundetem RetroShare-Netzknoten verknüpft @@ -12789,7 +13116,7 @@ These identities will soon be not supported anymore. Im Besitz von - + Node name: Netzknotenname: @@ -12799,7 +13126,7 @@ These identities will soon be not supported anymore. Netzknoten-ID : - + Really delete? Wirklich löschen? @@ -12837,7 +13164,22 @@ These identities will soon be not supported anymore. Pseudonym - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + New identity Neue Identität @@ -12854,14 +13196,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity Identität bearbeiten @@ -12872,24 +13214,27 @@ These identities will soon be not supported anymore. Aktualisieren - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12908,17 +13253,27 @@ These identities will soon be not supported anymore. Cannot create identity. Something went wrong. Check your profile password. + + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + Error getting key! Fehler beim Holen des Schlüssels! - + Error KeyID invalid Fehler Schlüssel-ID ungültig - + Unknown GpgId Unbekannte PGP-ID @@ -12928,7 +13283,7 @@ These identities will soon be not supported anymore. Unbekannter Klarname - + Create New Identity Neue Identität erstellen @@ -12938,7 +13293,12 @@ These identities will soon be not supported anymore. Typ - + + Choose image... + + + + @@ -12978,12 +13338,11 @@ These identities will soon be not supported anymore. Dein Avatar - Set Avatar - Avatar festlegen + Avatar festlegen - + Linked to your profile Mit deinem Profil verknüpft @@ -12993,7 +13352,7 @@ These identities will soon be not supported anymore. Du kannst eine oder mehrere Identitäten haben. Sie werden genutzt, um in Chatlobbys, Foren und Kanalkommentaren zu schreiben. Sie dienen als Zieladresse für Fernchat und das RetroShare-Fernnachrichtensystem. - + The nickname is too short. Please input at least %1 characters. Der Spitzname ist zu kurz. Bitte mindestens %1 Zeichen eingeben. @@ -13102,8 +13461,12 @@ These identities will soon be not supported anymore. + Quote + + + Send - Senden + Senden @@ -13261,7 +13624,7 @@ These identities will soon be not supported anymore. - + Options Optionen @@ -13293,12 +13656,12 @@ These identities will soon be not supported anymore. Schnellstart-Assistent - + RetroShare %1 a secure decentralized communication platform RetroShare %1 - eine sichere und dezentralisierte Kommunikationsplattform - + Unfinished unfertig @@ -13431,7 +13794,7 @@ Bitte gib etwas Speicher frei und drücke OK. Anzeigen - + Make sure this link has not been forged to drag you to a malicious website. Vergewissere dich, dass dieser Link nicht gefälscht ist, um dich auf eine bösartige Webseite zu locken. @@ -13476,7 +13839,7 @@ Bitte gib etwas Speicher frei und drücke OK. Serviceberechtigungsmatrix - + Statistics Statistiken @@ -13505,7 +13868,7 @@ Bitte gib etwas Speicher frei und drücke OK. MessageComposer - + Compose Verfassen @@ -13607,7 +13970,7 @@ Bitte gib etwas Speicher frei und drücke OK. - + Tags Schlagwörter @@ -13702,12 +14065,12 @@ Bitte gib etwas Speicher frei und drücke OK. Blockquote hinzufügen - + Send To: Senden an: - + &Left &Links @@ -13741,7 +14104,7 @@ Bitte gib etwas Speicher frei und drücke OK. Meine Kontakte - + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Hallo, <br> ich empfehle dir einen guten Freund von mir. Du kannst ihm vertrauen, wenn du mir vertraust. <br> @@ -13767,12 +14130,12 @@ Bitte gib etwas Speicher frei und drücke OK. - + Save Message Nachricht speichern - + Message has not been Sent. Do you want to save message to draft box? Nachricht wurde noch nicht gesendet. @@ -13784,7 +14147,7 @@ Möchtest du die Nachricht in den Entwürfen speichern? RetroShare Link einfügen - + Add to "To" Zu "An" hinzufügen @@ -14039,7 +14402,7 @@ Möchtest du die Nachricht speichern ? Zusätzliche Datei hinzufügen - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -14053,6 +14416,21 @@ Möchtest du die Nachricht speichern ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -14065,11 +14443,12 @@ Möchtest du die Nachricht speichern ? Von: + Friend Nodes - Befreundete Netzknoten + Befreundete Netzknoten - + Bullet list (disc) Ungeordnete Liste (Punkt) @@ -14109,13 +14488,13 @@ Möchtest du die Nachricht speichern ? Geordnete Liste (Römisch groß) - - + + Thanks, <br> Danke, <br> - + Distant identity: Fernidentität: @@ -14254,8 +14633,23 @@ Möchtest du die Nachricht speichern ? Nachricht - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -14267,12 +14661,12 @@ Möchtest du die Nachricht speichern ? Empfohlene Dateien - + Download all Recommended Files Alle Dateien herunterladen - + Subject: Betreff: @@ -14347,12 +14741,18 @@ Möchtest du die Nachricht speichern ? Einladung senden - + + Message Size: + + + + File Name Dateiname - + + Size Größe @@ -14413,18 +14813,33 @@ Möchtest du die Nachricht speichern ? Herunterladen - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Alle herunterladen - + Print Document Dokument drucken @@ -14439,7 +14854,7 @@ Möchtest du die Nachricht speichern ? HTML-Dateien (*.htm *.html);;Alle Dateien (*) - + Load images always for this message Bilde für diese Nachricht immer laden @@ -14580,7 +14995,7 @@ Möchtest du die Nachricht speichern ? MessagesDialog - + New Message Neue Nachricht @@ -14636,14 +15051,14 @@ Möchtest du die Nachricht speichern ? - + Tags Schlagwörter - + Inbox Posteingang @@ -14738,7 +15153,7 @@ Möchtest du die Nachricht speichern ? Weiterleiten - + Subject Betreff @@ -14850,7 +15265,7 @@ Möchtest du die Nachricht speichern ? - + Open in a new window In neuem Fenster öffnen @@ -14935,7 +15350,7 @@ Möchtest du die Nachricht speichern ? - + Drafts Entwürfe @@ -15064,7 +15479,7 @@ Möchtest du die Nachricht speichern ? Auf Nachricht antworten - + Delete Message Nachricht löschen @@ -15075,7 +15490,7 @@ Möchtest du die Nachricht speichern ? - + Expand Erweitern @@ -15085,7 +15500,7 @@ Möchtest du die Nachricht speichern ? Element entfernen - + from von @@ -15094,6 +15509,11 @@ Möchtest du die Nachricht speichern ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15409,7 +15829,7 @@ Reported error: - + Groups Gruppen @@ -15439,19 +15859,19 @@ Reported error: - - + + Search Suchen - + ID - + Search ID Kennung suchen @@ -15461,7 +15881,7 @@ Reported error: - + Show Items @@ -15662,19 +16082,19 @@ at least one peer was not added to a group - + Error Fehler - + File is not writeable! Datei ist nicht schreibbar! - + File is not readable! Datei ist nicht lesbar! @@ -15712,9 +16132,13 @@ at least one peer was not added to a group NewsFeed - Log entries - Protokolleinträge + Protokolleinträge + + + + Activity Stream + @@ -15731,7 +16155,7 @@ at least one peer was not added to a group Dies ist ein Test. - + Newest on top Neueste oben @@ -15742,20 +16166,39 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log - Protokoll + Protokoll + + + + Activity + NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15792,22 +16235,22 @@ at least one peer was not added to a group - + Test Test - + Chat Room Chatraum - + Systray Icon Systray Icon - + Message Nachricht @@ -15832,9 +16275,13 @@ at least one peer was not added to a group IP-Sicherheit - Log - Protokoll + Protokoll + + + + Activity + @@ -15884,7 +16331,12 @@ at least one peer was not added to a group Gruppenchat - + + Toaster position + + + + Chat rooms Chaträume @@ -15893,22 +16345,22 @@ at least one peer was not added to a group Chaträume - + Position Position - + X Margin Abstand X - + Y Margin Abstand Y - + Systray message Nachricht im Systemabschnitt @@ -15958,7 +16410,7 @@ at least one peer was not added to a group Meldungen - + Disable All Toasters Alle Hinweise deaktivieren @@ -15972,7 +16424,7 @@ at least one peer was not added to a group Neuigkeiten - + Systray Benachrichtigungsfeld @@ -16118,17 +16570,16 @@ Minimalmodus: 10% vom Standarddatenaufkommen und (unfertig) pausiert alle Datei PGPKeyDialog - Dialog - Dialog + Dialog - + Profile info Profilinfo - + Name : Name : @@ -16183,22 +16634,21 @@ Minimalmodus: 10% vom Standarddatenaufkommen und (unfertig) pausiert alle Datei Ultimativ - + This profile has signed your own profile key - Key signatures : - Schlüsselsignaturen : + Schlüsselsignaturen : - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -16212,7 +16662,7 @@ p, li { white-space: pre-wrap; } Diesen Schlüssel signieren - + PGP key PGP-Schlüssel @@ -16222,22 +16672,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - PGP-Schlüssel unterzeichnen + PGP-Schlüssel unterzeichnen - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -16257,7 +16701,7 @@ p, li { white-space: pre-wrap; } Verbindungen annehmen - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16323,28 +16767,28 @@ p, li { white-space: pre-wrap; } kB/s - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Fehler: Kann Nachbardetails nicht ermitteln. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Der angegebene Schlüsselalgorithmus wird von RetroShare nicht unterstützt. (Im Moment werden nur RSA-Schlüssel unterstützt) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16356,7 +16800,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. Das Vertrauensniveau drückt dein eigenes Vertrauen in diesen Schlüssel aus. Es wird weder von der Software genutzt noch geteilt, kann aber zum Merken guter bzw. schlechter Schlüssel nützlich sein. @@ -16401,27 +16845,47 @@ Warning: In your File-Transfer option, you select allow direct download to No.Du erlaubst momentan keine mit diesem Schlüssel signierte Verbindungen von RetroShare-Netzknoten. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Signaturfehler - - Maybe password is wrong - Vielleicht ist das Passwort falsch + + Check the password! + - + Maybe password is wrong + Vielleicht ist das Passwort falsch + + + You haven't set a trust level for this key. Sie haben für diesen Schlüssel kein Vertrauensniveau festgelegt. - + + Retroshare profile RetroShare-Profil - + This is your own PGP key, and it is signed by : Dies ist dein eigener PGP-Schlüssel und er wurde signiert von: @@ -16600,8 +17064,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People Leute @@ -16618,7 +17081,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Intern - + Chat with this person Mit dieser Person chatten @@ -16765,7 +17228,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Foto - + TextLabel TextLabel @@ -16809,8 +17272,8 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> - + Comments + Kommentare @@ -16845,6 +17308,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Schreibe einen Kommentar... + + + Album + Album + PhotoItem @@ -16854,12 +17322,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Formular - + TextLabel TextLabel - + <!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; } @@ -16955,7 +17423,7 @@ p, li { white-space: pre-wrap; } Foto ansehen - + PhotoShare Fotofreigabe @@ -16996,7 +17464,7 @@ kannst musst du eines auswählen! - + Stop Stop @@ -17224,12 +17692,12 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins Alle Plug-ins erlauben - + Plugin look-up directories Plug-in Ordner @@ -17279,7 +17747,7 @@ schützt dich aber eine Überprüfung des Prüfsumme vor schädlichem Verhalten von Plug-ins. - + Plugins Plug-ins @@ -17661,7 +18129,7 @@ schädlichem Verhalten von Plug-ins. Andere Themen - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17832,13 +18300,13 @@ schädlichem Verhalten von Plug-ins. Site - - + + Comments Kommentare - + Copy RetroShare Link RetroShare-Link kopieren @@ -17848,7 +18316,7 @@ schädlichem Verhalten von Plug-ins. - + Comment Kommentar @@ -17869,12 +18337,12 @@ schädlichem Verhalten von Plug-ins. - + Hide Verbergen - + Vote up Daumen hoch @@ -17888,7 +18356,7 @@ schädlichem Verhalten von Plug-ins. \/ - + Set as read and remove item Als gelesen markieren und Eintrag entfernen @@ -17949,7 +18417,7 @@ schädlichem Verhalten von Plug-ins. TextLabel - + Loading Lade @@ -18039,13 +18507,7 @@ schädlichem Verhalten von Plug-ins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -18055,60 +18517,50 @@ schädlichem Verhalten von Plug-ins. Administrator: - - - + + + unknown unbekannt - + Distribution: Verteilung: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Beiträge @@ -18119,7 +18571,7 @@ schädlichem Verhalten von Plug-ins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -18188,7 +18640,12 @@ schädlichem Verhalten von Plug-ins. - + + Empty + + + + Copy RetroShare Link RetroShare-Link kopieren @@ -18223,7 +18680,7 @@ schädlichem Verhalten von Plug-ins. - + [No name] @@ -18347,8 +18804,18 @@ schädlichem Verhalten von Plug-ins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18620,9 +19087,8 @@ und den Import zum Laden verwenden PulseAddDialog - Post From: - Beitrag von: + Beitrag von: Account 1 @@ -18637,7 +19103,7 @@ und den Import zum Laden verwenden Konto 3 - + Add to Pulse Zu Puls hinzufügen @@ -18660,17 +19126,32 @@ und den Import zum Laden verwenden URL - + GroupLabel - + IDLabel - + + From: + Von: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18695,10 +19176,20 @@ und den Import zum Laden verwenden Negativ - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18708,14 +19199,53 @@ und den Import zum Laden verwenden - + + Post + + + + Cancel Abbrechen - Post Pulse to Wire - Puls an Wire senden + Puls an Wire senden + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18741,10 +19271,18 @@ und den Import zum Laden verwenden Formular - - - - + + + + + Click to view picture + + + + + + + Image Bild @@ -18752,44 +19290,44 @@ und den Import zum Laden verwenden PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18799,17 +19337,17 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18819,7 +19357,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18827,7 +19365,7 @@ und den Import zum Laden verwenden PulseTopLevel - + retweeted @@ -18842,7 +19380,7 @@ und den Import zum Laden verwenden - + follow Parent Group @@ -18852,7 +19390,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18877,7 +19415,7 @@ und den Import zum Laden verwenden - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18913,29 +19451,29 @@ und den Import zum Laden verwenden - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -19013,7 +19551,7 @@ und den Import zum Laden verwenden QObject - + Confirmation Bestätigung @@ -19255,7 +19793,7 @@ Die Zeichen <b>",|,/,\,&lt;,&gt;,*,?</b> werden durch & Ergebnis - + Unable to make path Konnte Ordner nicht erstellen @@ -19290,7 +19828,7 @@ Die Zeichen <b>",|,/,\,&lt;,&gt;,*,?</b> werden durch & Dateianforderung abgebrochen - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Diese Version von RetroShare benutzt das OpenPGP-SDK. Der Schlüsselring des Systems wird nicht mehr verwendet, sondern ein eigener Schlüsselring für alle laufenden Instanzen.<br><br>Du scheinst keinen solchen Schlüsselring zu besitzen, obwohl Schlüssel von existierenden RetroShare-Accounts benötigt werden. Vielleicht hast du auch gerade zu dieser Version gewechselt. @@ -19433,7 +19971,7 @@ Der gemeldete Fehler ist: s - + TR up TR rauf @@ -19478,7 +20016,7 @@ Der gemeldete Fehler ist: deaktivert - + Move IP %1 to whitelist IP %1 in Whitelist verschieben @@ -19494,7 +20032,7 @@ Der gemeldete Fehler ist: - + %1 seconds ago Vor %1 Sekunden @@ -19579,7 +20117,7 @@ Sicherheit: keine anonymen Kennungen - + Error Fehler @@ -19970,9 +20508,8 @@ Sicherheit: keine anonymen Kennungen - <p>This certificate contains: - <p>Dieses Zertifikat enthält: + <p>Dieses Zertifikat enthält: @@ -20347,7 +20884,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KiB @@ -20569,19 +21106,48 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options Baumansichtoptionen - Show column... - Spalte anzeigen... + Show Header + + + + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … + + + + Show column... + Spalte anzeigen... - [no title] - [kein Titel] + [kein Titel] @@ -21017,7 +21583,7 @@ p, li { white-space: pre-wrap; } Herunterladen - + File Datei @@ -21032,7 +21598,7 @@ p, li { white-space: pre-wrap; } Prüfsumme - + Bad filenames have been cleaned Fehlerhafte Dateinamen wurden bereinigt @@ -21082,7 +21648,7 @@ Die betroffenen Dateien sind rot markiert Speichern - + Collection Editor Kollektionseditor @@ -21097,7 +21663,7 @@ Die betroffenen Dateien sind rot markiert Anzahl Dateien - + Real Size: Waiting child... Echte Größe: Warte auf Kind... @@ -21112,12 +21678,12 @@ Die betroffenen Dateien sind rot markiert Dies ist ein Verzeichnis. Doppelklicke, um es aufzuklappen. - + Download files - + Specify... @@ -21366,7 +21932,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil RsFriendListModel - + Name Name @@ -21386,7 +21952,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil IP - + Profile ID @@ -21399,10 +21965,15 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil RsGxsForumModel - + Title Titel + + + UnRead + + Date @@ -21414,7 +21985,7 @@ Wenn du glaubst dass es eine korrekte Datei ist, entferne die entsprechende Zeil Autor - + Information for this identity is currently missing. @@ -21452,7 +22023,7 @@ prevents the message to be forwarded to your friends. [Unbekannt] - + [ ... Missing Message ... ] [ ... Fehlende Nachricht ... ] @@ -21460,7 +22031,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Datum @@ -21520,7 +22091,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21879,7 +22450,7 @@ prevents the message to be forwarded to your friends. Dateiname - + Download Herunterladen @@ -21958,7 +22529,7 @@ prevents the message to be forwarded to your friends. Ordner öffnen - + Create Collection... Kollektion erstellen... @@ -21978,7 +22549,7 @@ prevents the message to be forwarded to your friends. Von Kollektion herunterladen... - + Collection Kollektion @@ -22083,12 +22654,12 @@ prevents the message to be forwarded to your friends. Nachbardetails - + Deny friend Freund blockieren - + Chat Chat @@ -22098,7 +22669,7 @@ prevents the message to be forwarded to your friends. Chat starten - + Expand Erweitern @@ -22368,13 +22939,13 @@ Es hilft auch, wenn du dich hinter einer Firewall/VPN befindest. Discovery Ein (empfohlen) - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off Discovery Aus @@ -22840,7 +23411,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Netzwerk @@ -22868,7 +23439,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Status @@ -22965,7 +23536,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address Dienstadresse @@ -23000,12 +23571,12 @@ If you have issues connecting over Tor check the Tor logs too. Bitte geben Sie eine Dienstadresse ein - + IP Range IP-Bereich - + Reported by DHT for IP masquerading Von DHT für IP-Maskierung gemeldet @@ -23673,7 +24244,7 @@ p, li { white-space: pre-wrap; } Fehlendes PGP-Zertifikat - + Wrong password Falsches Passwort @@ -23727,7 +24298,7 @@ Du kannst die Auswahl in den Optionen zurücksetzen. StatisticsWindow - + Add Friend Freund hinzufügen @@ -23783,7 +24354,7 @@ Du kannst die Auswahl in den Optionen zurücksetzen. Serviceberechtigungsmatrix - + DHT DHT @@ -24323,7 +24894,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor Tor @@ -24333,13 +24904,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -24348,6 +24918,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24621,35 +25216,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Du hast %1 fertige Downloads + You have %1 completed transfers + - You have %1 completed download - Du hast %1 fertigen Download + You have %1 completed transfer + - %1 completed downloads - %1 fertige Downloads + %1 completed transfers + - %1 completed download - %1 fertiger Download + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Du hast %1 fertige Downloads + + + You have %1 completed download + Du hast %1 fertigen Download + + + %1 completed downloads + %1 fertige Downloads + + + %1 completed download + %1 fertiger Download TransfersDialog - + Downloads Downloads @@ -24660,7 +25266,7 @@ p, li { white-space: pre-wrap; } Uploads - + Name i.e: file name Name @@ -24867,7 +25473,7 @@ p, li { white-space: pre-wrap; } Spezifizieren... - + Move in Queue... In Warteschlange verschieben... @@ -24961,7 +25567,7 @@ p, li { white-space: pre-wrap; } Bitte gib einen neuen -- und gültigen -- Dateinamen ein - + Expand all Alle erweitern @@ -25093,7 +25699,7 @@ p, li { white-space: pre-wrap; } - + Columns Spalten @@ -25104,7 +25710,7 @@ p, li { white-space: pre-wrap; } Dateiübertragungen - + Path Pfad @@ -25114,7 +25720,7 @@ p, li { white-space: pre-wrap; } Pfadspalte anzeigen - + Could not delete preview file Konnte Vorschaudatei nicht löschen @@ -25124,7 +25730,7 @@ p, li { white-space: pre-wrap; } Nochmal versuchen? - + Create Collection... Kollektion erstellen... @@ -25139,7 +25745,7 @@ p, li { white-space: pre-wrap; } Kollektion ansehen... - + Collection Kollektion @@ -25385,7 +25991,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Unbekannter Nachbar @@ -25481,7 +26087,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Du hast %1 neue Nachrichten @@ -25861,7 +26467,7 @@ p, li { white-space: pre-wrap; } Gruppe erstellen - + Subscribe to Group Gruppe abonnieren @@ -25955,8 +26561,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Bearbeitungsverlauf anzeigen @@ -25967,7 +26573,7 @@ p, li { white-space: pre-wrap; } - + Preview Vorschau @@ -25992,12 +26598,12 @@ p, li { white-space: pre-wrap; } Bearbeitungsverlauf ausblenden - + Edit Page Seite bearbeiten - + Create New Wiki Page Neue Wiki-Seite erstellen @@ -26017,7 +26623,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Neue Wiki-Gruppe erstellen @@ -26059,7 +26665,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -26069,12 +26675,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh Aktualisieren @@ -26109,12 +26710,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -26184,7 +26785,7 @@ p, li { white-space: pre-wrap; } Zeige: - + Yourself Du @@ -26222,7 +26823,7 @@ p, li { white-space: pre-wrap; } Puls an Wire senden - + RetroShare RetroShare @@ -26234,7 +26835,7 @@ p, li { white-space: pre-wrap; } - + The Wire The Wire @@ -26242,7 +26843,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -26323,8 +26924,8 @@ p, li { white-space: pre-wrap; } Formular - - + + Avatar Avatar @@ -26353,6 +26954,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26465,8 +27071,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Bilder (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Bilder (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_el.ts b/retroshare-gui/src/lang/retroshare_el.ts index d8f599554..a334a32f9 100644 --- a/retroshare-gui/src/lang/retroshare_el.ts +++ b/retroshare-gui/src/lang/retroshare_el.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -129,12 +129,12 @@ RetroShare: Σύνθετη Αναζήτηση - + Search Criteria Κριτήρια αναζήτησης - + Add a further search criterion. Προσθήκη κριτηρίου αναζήτησης @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; }⏎ AlbumDialog - + Album Άλμπουμ @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; }⏎ AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; }⏎ Φόρμα - - + + TextLabel Ετικετα κειμενου @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Γραμμή εργαλείων - + Icon Only Μόνο εικόνα @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Επιλέξτε την εμφάνιση των πλήκτρων των εργαλείων. - + Icon Size = 8x8 Μέγεθος εικόνας = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Μέγεθος Εικόνας = 128x128 - + Status Bar Γραμμή κατάστασης @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 Μέγεθος εικόνας = 32x32 @@ -828,14 +828,23 @@ p, li { white-space: pre-wrap; } Αλλαγή Άβαταρ - + + TextLabel + + + + Your Avatar Picture Η μικρογραφία σας - + + Browse... + + + Add Avatar - Προσθήκη Άβαταρ + Προσθήκη Άβαταρ @@ -843,25 +852,34 @@ p, li { white-space: pre-wrap; } Μετακινηση - + Set your Avatar picture Ορισμός εικόνας Avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Μεταφόρτωση μικρογραφίας + Μεταφόρτωση μικρογραφίας AvatarWidget - - Choose avatar - - - - + Click to change your avatar Πατηστε εδω για αλλαγη εικονιδιου @@ -869,7 +887,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage RetroShare Χρήση εύρους ζώνης + + + PushButton + + - + Up + + + + + Down + Κάτω + + + + Clears the graph + + + + Show Settings Εμφανιση ρυθμισεων + TextLabel + + + + Reset Επαναφορά - Receive Rate - Rate ελλειφθει + Rate ελλειφθει - Send Rate - Αποστολη Rate + Αποστολη Rate - + Always on Top Παντα μπροστα - Style - Στιλ + Στιλ - + Changes the transparency of the Bandwidth Graph Αλλαγη διαφανειας του ευρυζωνικου γραφικου - + 100 100 @@ -936,30 +975,27 @@ p, li { white-space: pre-wrap; } % Αδιαφανεια - Save - Αποθήκευση + Αποθήκευση - Cancel - Διακοπη + Διακοπη - + Since: Από: - Hide Settings - Απόκρυψη ρυθμίσεων + Απόκρυψη ρυθμίσεων BandwidthStatsWidget - + Sum Άθροισμα @@ -981,7 +1017,7 @@ p, li { white-space: pre-wrap; } Καταμέτρηση - + Average Μέσος όρος @@ -1115,7 +1151,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -1193,6 +1229,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + Μου αρέσει + + + + 0 + 0 + + + + I dislike this + Δεν μου αρέσει + + + + Toggle Message Read Status + Αναγνωση καταστασης της εναλλαγης μυνηματος + + + + Avatar + Εικονιδιο + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Ορισμος ως αναγνωσμένο και κατάργηση στοιχείου + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1328,6 +1443,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + Προεπιλογή + + + + Dark + + ChannelPage @@ -1380,6 +1505,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Μου αρέσει + + + + 0 + 0 + + + + I dislike this + Δεν μου αρέσει + + + + Toggle Message Read Status + Αναγνωση καταστασης της εναλλαγης μυνηματος + + + + Avatar + Εικονιδιο + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + Ορισμος ως αναγνωσμένο και κατάργηση στοιχείου + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1587,24 +1791,40 @@ into the image, so as to - You have %1 new messages - Έχετε %1 νέα μηνύματα + Έχετε %1 νέα μηνύματα + + + You have %1 new message + Έχετε %1 νέο μήνυμα + + + %1 new messages + %1 νέα μηνύματα + + + %1 new message + %1 νέο μήνυμα + + + + You have %1 mentions + - You have %1 new message - Έχετε %1 νέο μήνυμα + You have %1 mention + - %1 new messages - %1 νέα μηνύματα + %1 mentions + - %1 new message - %1 νέο μήνυμα + %1 mention + @@ -1617,11 +1837,6 @@ into the image, so as to Remove All Αφαίρεση Όλων - - - mention(s) - - ChatLobbyWidget @@ -2098,13 +2313,11 @@ Double click a chat room to enter and chat. - Group chat - Ομαδική συνομιλία + Ομαδική συνομιλία - - + Private chat Ιδιωτική συνομιλία @@ -2169,17 +2382,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -2200,11 +2408,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -2265,11 +2474,17 @@ Double click a chat room to enter and chat. + Broadcast Ραδιοφωνική μετάδοση - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Αποθηκευμένα μηνύματα (0 = απεριόριστο): @@ -2416,8 +2631,23 @@ Double click a chat room to enter and chat. Ιδιωτική συνομιλία - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2586,7 +2816,7 @@ Double click a chat room to enter and chat. - + is typing... γράφει... @@ -2603,12 +2833,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? Θέλετε πραγματικά να διαγράψετε το ιστορικό; @@ -2680,7 +2910,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Εύρεση Προηγούμενου </b><br/><i>Ctrl+Shift+G</i> @@ -2720,12 +2950,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Επισήμανση επιλεγμένου κειμένου</b><br><i>Ctrl+M</i> - + Person id: @@ -2741,7 +2971,7 @@ Double click on it to add his name on text writer. - + items found. στοιχεία βρέθηκαν. @@ -2761,7 +2991,7 @@ Double click on it to add his name on text writer. Πληκτρολογείστε μήνυμα εδώ - + Don't stop to color after @@ -2919,12 +3149,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details Λεπτομέρειες - + Local Address Τοπική διεύθυνση @@ -2935,12 +3165,12 @@ Double click on it to add his name on text writer. Εξωτερική διεύθυνση - + Node info: - + Current address: @@ -2956,31 +3186,36 @@ Double click on it to add his name on text writer. Υποδοχη - + Include signatures Περιλαμβάνουν υπογραφές - + RetroShare RetroShare - + - + Error : cannot get peer details. Σφάλμα: οι peer λεπτομέρειες δεν μπορουν να παρθουν. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2996,22 +3231,22 @@ Double click on it to add his name on text writer. - + Encryption Κρυπτογράφηση - + Not connected Μη συνδεδεμένος - + Retroshare node details Πληροφορίες κόμβου του Retroshare - + Node name : Όνομα κόμβου: @@ -3046,13 +3281,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -3067,7 +3307,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -3078,21 +3318,27 @@ Double click on it to add his name on text writer. κανένας + <p>This certificate contains: - <p>Αυτό το πιστοποιητικό περιλαμβάνει: + <p>Αυτό το πιστοποιητικό περιλαμβάνει: - + <li>a <b>node ID</b> and <b>name</b> <li>η <b>ταυτότητα του κόμβου</b> και <b>όνομα</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> <p>Μπορείτε να χρησιμοποιήσετε αυτό το πιστοποιητικό για να κάνετε νέους φίλους. Στείλτε το με email ή δώστε το σε αυτούς αυτοπροσώπως.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -3102,7 +3348,7 @@ Double click on it to add his name on text writer. - + with με @@ -3294,12 +3540,12 @@ Double click on it to add his name on text writer. Λεπτομέρειες σχετικά με το αίτημα - + Peer details Peer λεπτομέρειες - + Name: Όνομα: @@ -3312,12 +3558,12 @@ Double click on it to add his name on text writer. Κόμβος: - + Location: Τοποθεσία: - + Options Επιλογές @@ -3326,12 +3572,12 @@ Double click on it to add his name on text writer. Εισάγεται το πιστοποιητικό χειρονακτικός - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: Προσθηκη φίλου στην Ομάδα: @@ -3341,7 +3587,7 @@ Double click on it to add his name on text writer. Έλεγχος ταυτότητας φίλου (υπογραφη PGP κλειδίου) - + Please paste below your friend's Retroshare ID @@ -3366,7 +3612,7 @@ Double click on it to add his name on text writer. - + Add as friend to connect with Πρόσθηκη ως φίλο-για να συνδεθείτε με @@ -3375,7 +3621,7 @@ Double click on it to add his name on text writer. Για να αποδεχθείε την αίτηση του φίλου, πατήστε το πλαισιο Τέλος. - + Sorry, some error appeared Συγγνώμη, εμφανίστηκς κάποιο σφαλμα @@ -3395,32 +3641,32 @@ Double click on it to add his name on text writer. Λεπτομέρειες σχετικά με τον φίλο σας: - + Key validity: Ισχύς κλειδιού: - + Profile ID: - + Signers Υπογράφοντες - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. Αυτός ο ομότιμος είναι ήδη στην λιστα φιλων. Προσθέτοντας μπορεί να ρυθμιστεί μόνο η διεύθυνση ip. - + To accept the Friend Request, click the Accept button. @@ -3466,7 +3712,7 @@ Double click on it to add his name on text writer. - + Certificate Load Failed Η φορτωση του πιστοποιητικου απετυχε @@ -3499,12 +3745,12 @@ Double click on it to add his name on text writer. Peer id - + Not a valid Retroshare certificate! - + RetroShare Invitation Πρόσκληση RetroShare @@ -3524,12 +3770,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3577,7 +3823,37 @@ Warning: In your File-Transfer option, you select allow direct download to No.Έχετε ένα αίτημα φίλιας από - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3665,12 +3941,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Use as direct source, when available - + IP-Addr: - + IP-Address Διεύθυνση IP @@ -3720,7 +3996,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3778,12 +4054,12 @@ even if you don't make friends. - + [Unknown] [Άγνωστο] - + Added with certificate from %1 @@ -3858,7 +4134,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -4280,7 +4561,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -4428,7 +4709,7 @@ p, li { white-space: pre-wrap; } Δεν υπάρχουν περιορισμοί επιλεγμένου Κύκλου - + [Unknown] [Άγνωστο] @@ -4443,7 +4724,7 @@ p, li { white-space: pre-wrap; } Αφαίρεση - + Search Αναζητηση @@ -4459,7 +4740,7 @@ p, li { white-space: pre-wrap; } Υπέγραψε - + Edit Circle Επεξεργασια κύκλου @@ -4475,12 +4756,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -4502,7 +4783,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4646,7 +4927,7 @@ p, li { white-space: pre-wrap; }⏎ - + Attachments Συνημμένα @@ -4692,7 +4973,7 @@ p, li { white-space: pre-wrap; }⏎ Drag and Drop τα αρχεία από τα αποτελέσματα αναζήτησης - + Paste RetroShare Links Επικολλήση των Λινκ @@ -4702,7 +4983,7 @@ p, li { white-space: pre-wrap; }⏎ Επικολληση του Λινκ - + Drop file error. Σφάλμα αρχείου. @@ -4729,17 +5010,41 @@ p, li { white-space: pre-wrap; }⏎ - + RetroShare RetroShare - - File already Added and Hashed - Το αρχείο εχει προσθέθει και κατακερματίζεται + + This file already in this post: + - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + File already Added and Hashed + Το αρχείο εχει προσθέθει και κατακερματίζεται + + + Please add a Subject Παρακαλείσθε να προσθέσετε ένα θέμα @@ -4770,12 +5075,12 @@ p, li { white-space: pre-wrap; }⏎ - + You are about to add files you're not actually sharing. Do you still want this to happen? Είστε έτοιμοι να προσθέσετε τα αρχεία που στην πραγματικότητα δεν μοιράζεστε. Είστε βέβαιοι ότι θέλετε να συμβεί αυτό; - + Edit Channel Post @@ -4795,7 +5100,7 @@ p, li { white-space: pre-wrap; }⏎ - + About to post un-owned files to a channel. Περίπου για να τοποθετήθουν τα un-owned αρχεία σε ένα κανάλι. @@ -4887,7 +5192,7 @@ p, li { white-space: pre-wrap; } - + No Forum Κανενα φόρουμ @@ -5330,7 +5635,7 @@ and use the import button to load it DHTGraphSource - + users χρήστες @@ -6333,7 +6638,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories Καταλογοι φιλων @@ -6830,7 +7135,7 @@ at least one peer was not added to a group Αναζήτηση φίλων - + Mark all Επισημάνση όλων @@ -6844,7 +7149,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message Επεξεργασια μήνυματος κατάστασης @@ -6948,7 +7253,7 @@ at least one peer was not added to a group - + Network Δίκτυο @@ -7013,7 +7318,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -7044,7 +7349,7 @@ at least one peer was not added to a group - + Node name @@ -7303,12 +7608,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7680,7 +7985,7 @@ p, li { white-space: pre-wrap; } Στατιστικά στοιχεία του δρομολογητή - + GroupBox @@ -7745,7 +8050,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7768,7 +8073,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7969,7 +8274,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title Τίτλος @@ -7979,13 +8284,30 @@ p, li { white-space: pre-wrap; } Αναζήτηση τίτλου - - + + + + Description Περιγραφή - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description Αναζήτηση περιγραφής @@ -7995,42 +8317,19 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - Sort by Name - Ταξινόμηση κατά όνομα + Ταξινόμηση κατά όνομα - Sort by Popularity - Ταξινόμηση κατά δημοτικότητα + Ταξινόμηση κατά δημοτικότητα - Sort by Last Post - Ταξινόμηση κατά το τελευταιο ποσταρισμα + Ταξινόμηση κατά το τελευταιο ποσταρισμα - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -8045,40 +8344,35 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity Δημοτικότητα - - + + Never - Display - Εμφάνιση + Εμφάνιση - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -8227,7 +8521,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels Κανάλια @@ -8248,12 +8542,12 @@ p, li { white-space: pre-wrap; } Τα κανάλια μου - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels Εγγεγραμμένα Κανάλια @@ -8722,7 +9016,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8822,12 +9116,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8838,18 +9132,18 @@ p, li { white-space: pre-wrap; } - + Feeds Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8859,12 +9153,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8924,7 +9218,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8939,12 +9233,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -9020,23 +9314,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed Εγγεγραμμένος - - Subscribe Εγγραφη - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected Δεν υπάρχει επιλεγμένο κανάλι @@ -9058,11 +9365,6 @@ p, li { white-space: pre-wrap; } Channel Post Ποσταρισμα στο καναλι - - - new message(s) - - GxsCircleItem @@ -9571,7 +9873,7 @@ before you can comment Έναρξη νέας μηνυματοσειράς στο επιλεγμενο φόρουμ - + Search forums Αναζήτηση στα φόρουμ @@ -9580,12 +9882,12 @@ before you can comment Τελευταιο ποστ - + New Thread Νέο θεμα - + Threaded View Περασμένη κλωστή άποψη @@ -9595,19 +9897,19 @@ before you can comment Επίπεδη προβολή - - + + Title Τίτλος - - + + Date Ημερομηνία - + Author Δημιουργος @@ -9622,7 +9924,17 @@ before you can comment Φορτωση - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -9679,23 +9991,23 @@ before you can comment Αναζήτηση περιεχομένου - + No name Δεν υπάρχει όνομα - - + + Reply Απάντηση - + <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> - + Loading... @@ -9733,12 +10045,12 @@ before you can comment Χαρακτηρισμός ως μη αναγνωσμένα - + Copy RetroShare Link Αντιγραφη του Λινκ - + Hide Απόκρυψη @@ -9747,7 +10059,7 @@ before you can comment Επεκταση - + [unknown] @@ -9777,8 +10089,8 @@ before you can comment - - + + Distribution @@ -9877,12 +10189,12 @@ before you can comment Αρχικό μήνυμα - + New thread - + Edit Επεξεργασία @@ -9938,7 +10250,7 @@ before you can comment - + Author's reputation @@ -9958,7 +10270,7 @@ before you can comment - + <b>Loading...<b> @@ -9998,6 +10310,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -10065,7 +10382,7 @@ This message is missing. You should receive it later. Στις % 1, %2 έγραψε: - + Forum name Όνομα φόρουμ @@ -10097,11 +10414,6 @@ This message is missing. You should receive it later. Forum Post Ποσταρισμα στο φορουμ - - - new message(s) - - GxsForumsDialog @@ -10542,7 +10854,7 @@ This message is missing. You should receive it later. Προεπισκόπηση εκτύπωσης - + Unsubscribe Καταργηση εγγραφης @@ -10557,7 +10869,7 @@ This message is missing. You should receive it later. Άνοιγμα σε νέα καρτέλα - + Remove this search @@ -10567,12 +10879,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details Εμφάνιση Λεπτομερειών @@ -10639,12 +10951,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link Αντιγραφή του RetroShare Συνδέσμου @@ -10659,7 +10971,7 @@ This message is missing. You should receive it later. Επισήμανση όλων ως μη αναγνωσμένων - + AUTHD AUTHD @@ -11185,7 +11497,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -11194,7 +11506,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -11220,7 +11532,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -11300,49 +11612,55 @@ p, li { white-space: pre-wrap; }⏎ - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard Αντιγράψετε σας Cert πρόχειρο @@ -11390,17 +11708,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -11415,7 +11728,12 @@ new short format Πρόσκληση RetroShare - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -11680,14 +11998,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All Όλα - + Reputation Φήμη @@ -11697,12 +12015,12 @@ p, li { white-space: pre-wrap; } Αναζητηση - + Anonymous Id - + Create new Identity Δημιουργια νέας ταυτότητας @@ -11846,7 +12164,7 @@ p, li { white-space: pre-wrap; } - + Send message Αποστολή μηνύματος @@ -11918,7 +12236,7 @@ p, li { white-space: pre-wrap; } - + Anonymous Ανώνυμος @@ -11933,24 +12251,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11965,7 +12283,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -12024,13 +12342,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -12090,7 +12413,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -12138,7 +12461,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -12147,12 +12470,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -12164,12 +12487,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -12285,17 +12608,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -12452,8 +12775,8 @@ These identities will soon be not supported anymore. - - + + People @@ -12464,7 +12787,7 @@ These identities will soon be not supported anymore. Το άβατάρ σας - + Linked to neighbor nodes @@ -12474,7 +12797,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -12534,7 +12857,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -12544,7 +12867,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -12582,7 +12905,7 @@ These identities will soon be not supported anymore. Ψευδώνυμο - + New identity Νέα ταυτότητα @@ -12599,14 +12922,14 @@ These identities will soon be not supported anymore. - + N/A N/A - + Edit identity Επεξεργασία Ταυτότητας @@ -12617,24 +12940,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -12654,12 +12980,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -12669,7 +13020,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -12679,7 +13030,12 @@ These identities will soon be not supported anymore. Τυπος - + + Choose image... + + + + @@ -12719,12 +13075,7 @@ These identities will soon be not supported anymore. Το άβατάρ σας - - Set Avatar - - - - + Linked to your profile @@ -12734,7 +13085,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12839,8 +13190,12 @@ These identities will soon be not supported anymore. + Quote + Απόσπασμα + + Send - Αποστολη + Αποστολη @@ -12998,7 +13353,7 @@ These identities will soon be not supported anymore. - + Options Επιλογές @@ -13030,12 +13385,12 @@ These identities will soon be not supported anymore. Οδηγός γρήγορης έναρξης - + RetroShare %1 a secure decentralized communication platform Το RetroShare %1 ειναι μια πλατφόρμα ασφαλούς αποκεντρωμένης επικοινωνίας - + Unfinished Ημιτελής @@ -13168,7 +13523,7 @@ These identities will soon be not supported anymore. Εμφανιση - + Make sure this link has not been forged to drag you to a malicious website. Βεβαιωθείτε ότι αυτή η σύνδεση δεν σφυρηλατήθηκε για να σας σύρει σε μια κακόβουλη ιστοσελίδα. @@ -13213,7 +13568,7 @@ These identities will soon be not supported anymore. - + Statistics Στατιστικές @@ -13242,7 +13597,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose Συνθέση @@ -13344,7 +13699,7 @@ These identities will soon be not supported anymore. - + Tags Ετικέτες @@ -13439,12 +13794,12 @@ These identities will soon be not supported anymore. Προσθέστε Blockquote - + Send To: Αποστολή σε: - + &Left &Αριστερά @@ -13474,7 +13829,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> Γεια σας, <br>θα ήθελα να σαςσυστήσω ένα καλό φίλο μου, μπορείτε να τον εμπιστευθείτε πάρα πολύ όταν μπορείτε και με εμπιστεύεσται. <br> @@ -13500,12 +13860,12 @@ These identities will soon be not supported anymore. - + Save Message Αποθηκεύση μυνηματος - + Message has not been Sent. Do you want to save message to draft box? Μήνυμα δεν έχει σταλεί. @@ -13517,7 +13877,7 @@ Do you want to save message to draft box? Επικολληση του Λινκ - + Add to "To" Προσθηκη του "Σε" @@ -13772,7 +14132,7 @@ Do you want to save message ? Προσθηκη επιπλεον αρχειου - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -13786,6 +14146,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -13798,7 +14173,7 @@ Do you want to save message ? Από: - + Bullet list (disc) @@ -13838,13 +14213,13 @@ Do you want to save message ? - - + + Thanks, <br> Ευχαριστούμε, <br> - + Distant identity: @@ -13983,8 +14358,23 @@ Do you want to save message ? Μυνημα - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13996,12 +14386,12 @@ Do you want to save message ? Συνιστάμενα αρχεία - + Download all Recommended Files Λυψη ολων των συνιστωμενων αρχειων - + Subject: Θέμα: @@ -14076,12 +14466,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name Ονομα αρχειου - + + Size Μεγεθος @@ -14142,18 +14538,33 @@ Do you want to save message ? Λυψη - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all Λυψη ολων - + Print Document Εκτύπωση εγγράφου @@ -14168,7 +14579,7 @@ Do you want to save message ? Αρχεία HTML (*.htm * .html)??Όλα τα αρχεία (*) - + Load images always for this message @@ -14309,7 +14720,7 @@ Do you want to save message ? MessagesDialog - + New Message Νέο μήνυμα @@ -14365,14 +14776,14 @@ Do you want to save message ? - + Tags Ετικέτες - + Inbox "Εισερχόμενα" @@ -14467,7 +14878,7 @@ Do you want to save message ? Μήνυμα προς τα εμπρός - + Subject Θέμα: @@ -14579,7 +14990,7 @@ Do you want to save message ? - + Open in a new window Άνοιγμα σε νέο παράθυρο @@ -14664,7 +15075,7 @@ Do you want to save message ? - + Drafts Σχέδια @@ -14773,7 +15184,7 @@ Do you want to save message ? Μήνυμα απάντησης - + Delete Message Διαγραφή μηνύματος @@ -14784,7 +15195,7 @@ Do you want to save message ? - + Expand Επεκταση @@ -14794,7 +15205,7 @@ Do you want to save message ? Απομακρυνση στοιχειου - + from από @@ -14803,6 +15214,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -15116,7 +15532,7 @@ Reported error: - + Groups Ομαδες @@ -15146,19 +15562,19 @@ Reported error: - - + + Search - + ID ID - + Search ID @@ -15168,7 +15584,7 @@ Reported error: - + Show Items @@ -15368,18 +15784,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! Το αρχείο δεν είναι αναγνώσιμο! @@ -15418,7 +15834,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -15436,7 +15852,7 @@ at least one peer was not added to a group Αυτό είναι μια δοκιμη. - + Newest on top @@ -15447,20 +15863,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -15497,22 +15928,22 @@ at least one peer was not added to a group - + Test Δοκιμή - + Chat Room - + Systray Icon Εικονίδιο Systray - + Message Μυνημα @@ -15537,12 +15968,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected Φίλος συνδεθηκε @@ -15589,27 +16015,37 @@ at least one peer was not added to a group Ομαδικη συνομιλια - + + Toaster position + + + + Chat rooms - + Position Θέση - + + Activity + + + + X Margin X περιθώριο - + Y Margin Y περιθώριο - + Systray message Μήνυμα Systray @@ -15659,7 +16095,7 @@ at least one peer was not added to a group Κοινοποιηση - + Disable All Toasters @@ -15673,7 +16109,7 @@ at least one peer was not added to a group Feed - + Systray @@ -15815,17 +16251,16 @@ Low Traffic: 10% standard traffic and TODO: pauses all file-transfers PGPKeyDialog - Dialog - Διαλόγος + Διαλόγος - + Profile info - + Name : Όνομα: @@ -15880,22 +16315,17 @@ Low Traffic: 10% standard traffic and TODO: pauses all file-transfersΤελικη - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -15909,7 +16339,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -15919,22 +16349,16 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - Sign PGP key - Υπογραφη PGP κλειδίου + Υπογραφη PGP κλειδίου - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -15954,7 +16378,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -16020,27 +16444,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare RetroShare - - + + Error : cannot get peer details. Σφάλμα: οι peer λεπτομέρειες δεν μπορουν να παρθουν. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) Ο παρεχόμενος αλγόριθμος κλειδιού δεν υποστηρίζεται από το RetroShare⏎ (κλειδιά RSA μόνο υποστηρίζονται προς το παρόν) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -16052,7 +16476,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -16097,27 +16521,47 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure Αποτυχια υπογραφης - - Maybe password is wrong - Μαλλον ο κωδικος ειναι λαθος + + Check the password! + - + Maybe password is wrong + Μαλλον ο κωδικος ειναι λαθος + + + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -16296,8 +16740,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -16314,7 +16757,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -16457,7 +16900,7 @@ Warning: In your File-Transfer option, you select allow direct download to No.Φωτογραφία - + TextLabel Ετικετα κειμενου @@ -16501,7 +16944,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -16537,6 +16980,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.Write a comment... Γράψτε ένα σχόλιο... + + + Album + Άλμπουμ + PhotoItem @@ -16546,12 +16994,12 @@ Warning: In your File-Transfer option, you select allow direct download to No.Φορμα - + TextLabel Ετικετα κειμενου - + <!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; } @@ -16647,7 +17095,7 @@ p, li { white-space: pre-wrap; }⏎ Εμφανιση φωτογραφιας - + PhotoShare PhotoShare @@ -16687,7 +17135,7 @@ requesting to edit it! - + Stop Παυση @@ -16915,12 +17363,12 @@ p, li { white-space: pre-wrap; }⏎ PluginsPage - + Authorize all plugins Επιτρέπουν όλα τα plugins - + Plugin look-up directories Plugin look-up καταλόγους @@ -16960,7 +17408,7 @@ malicious behavior of crafted plugins. Ελέγξτε αυτό για την ανάπτυξη των plugins. Αυτοί δεν θα ελεγχθεί για τον κατακερματισμό. Ωστόσο, υπό κανονικές συνθήκες, έλεγχος hash σας προστατεύει από κακόβουλη συμπεριφορά του δημιουργημένο plugins. - + Plugins Plugins @@ -17322,7 +17770,7 @@ malicious behavior of crafted plugins. Άλλα θέματα - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -17481,13 +17929,13 @@ malicious behavior of crafted plugins. Τοποθεσία - - + + Comments Σχολια - + Copy RetroShare Link @@ -17497,7 +17945,7 @@ malicious behavior of crafted plugins. - + Comment Σχόλιο @@ -17518,12 +17966,12 @@ malicious behavior of crafted plugins. - + Hide - + Vote up @@ -17537,7 +17985,7 @@ malicious behavior of crafted plugins. \/ - + Set as read and remove item Ορισμος ως αναγνωσμένο και κατάργηση στοιχείου @@ -17598,7 +18046,7 @@ malicious behavior of crafted plugins. - + Loading Φορτωση @@ -17680,13 +18128,7 @@ malicious behavior of crafted plugins. - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 0 @@ -17696,60 +18138,50 @@ malicious behavior of crafted plugins. - - - + + + unknown Άγνωστο - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts Δημοσιεύσεις @@ -17760,7 +18192,7 @@ malicious behavior of crafted plugins. - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -17829,7 +18261,12 @@ malicious behavior of crafted plugins. - + + Empty + + + + Copy RetroShare Link @@ -17864,7 +18301,7 @@ malicious behavior of crafted plugins. - + [No name] @@ -17984,8 +18421,18 @@ malicious behavior of crafted plugins. - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -18253,9 +18700,8 @@ and use the import button to load it PulseAddDialog - Post From: - Καταχώρηση από: + Καταχώρηση από: Account 1 @@ -18270,7 +18716,7 @@ and use the import button to load it Λογαριασμός 3 - + Add to Pulse Προσθηκη στο Pulse @@ -18293,17 +18739,32 @@ and use the import button to load it URL - + GroupLabel - + IDLabel - + + From: + Από: + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -18328,10 +18789,20 @@ and use the import button to load it Αρνητικό - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -18341,14 +18812,53 @@ and use the import button to load it - + + Post + + + + Cancel Διακοπη - Post Pulse to Wire - Θέση παλμό για σύρμα + Θέση παλμό για σύρμα + + + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures + @@ -18374,10 +18884,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image Εικόνα @@ -18385,44 +18903,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18432,17 +18950,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -18452,7 +18970,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -18460,7 +18978,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -18475,7 +18993,7 @@ and use the import button to load it - + follow Parent Group @@ -18485,7 +19003,7 @@ and use the import button to load it ... - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -18510,7 +19028,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -18546,29 +19064,29 @@ and use the import button to load it - - - + + + 1 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -18646,7 +19164,7 @@ and use the import button to load it QObject - + Confirmation Επιβεβαίωση @@ -18887,7 +19405,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Αποτέλεσμα - + Unable to make path Δεν είναι δυνατή η διαδρομή @@ -18922,7 +19440,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Ακυρώθηκε η αίτηση αρχειου - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. Αυτή η έκδοση του RetroShare χρησιμοποιεί το OpenPGP-SDK. Ως παρενέργεια, δεν χρησιμοποιεί το κοινό σύστημα διαχείρισης κλειδιών του PGP, αλλά έχει είναι δική ΜΠΡΕΛΟΚ συμμερίζονται όλες οι παρουσίες RetroShare. <br><br>Δεν φαίνεται να έχουν ένα τέτοιο μπρελόκ, αν και τα κλειδιά του PGP αναφέρονται από τους υπάρχοντες λογαριασμούς eMule ομάδα + Ultra, πιθανώς επειδή έχετε αλλάξει μόνο σε αυτήν την νέα έκδοση του λογισμικού. @@ -19062,7 +19580,7 @@ Reported error is: δευτερόλεπτα - + TR up @@ -19107,7 +19625,7 @@ Reported error is: απενεργοποιημένο - + Move IP %1 to whitelist @@ -19123,7 +19641,7 @@ Reported error is: - + %1 seconds ago %1 δευτερόλεπτα πριν @@ -19207,7 +19725,7 @@ Security: no anonymous IDs - + Error Σφάλμα @@ -19598,9 +20116,8 @@ Security: no anonymous IDs - <p>This certificate contains: - <p>Αυτό το πιστοποιητικό περιλαμβάνει: + <p>Αυτό το πιστοποιητικό περιλαμβάνει: @@ -19967,7 +20484,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB %1 KB @@ -20189,18 +20706,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -20637,7 +21175,7 @@ p, li { white-space: pre-wrap; } Λυψη! - + File Αρχειο @@ -20652,7 +21190,7 @@ p, li { white-space: pre-wrap; } Hash - + Bad filenames have been cleaned Τα κακα ονόματα αρχείων έχουν εκκαθαριστεί @@ -20702,7 +21240,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace Αποθηκευση - + Collection Editor @@ -20717,7 +21255,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -20732,12 +21270,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... Καθορίσμος... @@ -20984,7 +21522,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -21004,7 +21542,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -21017,10 +21555,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title Τίτλος + + + UnRead + + Date @@ -21032,7 +21575,7 @@ If you believe it is correct, remove the corresponding line from the file and re Δημιουργος - + Information for this identity is currently missing. @@ -21070,7 +21613,7 @@ prevents the message to be forwarded to your friends. [Άγνωστο] - + [ ... Missing Message ... ] [ ... Λείπει ενα μήνυμα...] @@ -21078,7 +21621,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date Ημερομηνία @@ -21138,7 +21681,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -21492,7 +22035,7 @@ prevents the message to be forwarded to your friends. Ονομα αρχειου - + Download Λυψη @@ -21571,7 +22114,7 @@ prevents the message to be forwarded to your friends. Άνοιγμα Φακέλου - + Create Collection... Δημιουργία Συλλογής ... @@ -21591,7 +22134,7 @@ prevents the message to be forwarded to your friends. Λυψη απο συλλογη αρχειων... - + Collection Συλλογή @@ -21696,12 +22239,12 @@ prevents the message to be forwarded to your friends. Peer λεπτομέρειες - + Deny friend Αρνησει φίλου - + Chat Συνομιλια @@ -21711,7 +22254,7 @@ prevents the message to be forwarded to your friends. Εναρξη συνομιλιας - + Expand Επεκταση @@ -21978,13 +22521,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -22450,7 +22993,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network Δίκτυο @@ -22478,7 +23021,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status Κατασταση @@ -22575,7 +23118,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -22610,12 +23153,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -23280,7 +23823,7 @@ p, li { white-space: pre-wrap; } Λείπει το PGP πιστοποιητικό - + Wrong password @@ -23322,7 +23865,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend Προσθήκη φίλου @@ -23378,7 +23921,7 @@ This choice can be reverted in settings. - + DHT DHT @@ -23918,7 +24461,7 @@ p, li { white-space: pre-wrap; }⏎ TorStatus - + Tor @@ -23928,13 +24471,12 @@ p, li { white-space: pre-wrap; }⏎ - - + Tor is currently offline - + Tor is OK @@ -23943,6 +24485,31 @@ p, li { white-space: pre-wrap; }⏎ No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -24216,35 +24783,46 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads - Έχετε %1 ολοκληρώμενη λυψη + You have %1 completed transfers + - You have %1 completed download - Η λήψη %1 ολοκληρώθηκε + You have %1 completed transfer + - %1 completed downloads - %1 ολοκληρώμενη λυψη + %1 completed transfers + - %1 completed download - %1 ολοκληρώμενη λυψη + %1 completed transfer + - - completed transfer(s) - + You have %1 completed downloads + Έχετε %1 ολοκληρώμενη λυψη + + + You have %1 completed download + Η λήψη %1 ολοκληρώθηκε + + + %1 completed downloads + %1 ολοκληρώμενη λυψη + + + %1 completed download + %1 ολοκληρώμενη λυψη TransfersDialog - + Downloads Λήψεις @@ -24255,7 +24833,7 @@ p, li { white-space: pre-wrap; } Προσθήκες - + Name i.e: file name Ονομα @@ -24462,7 +25040,7 @@ p, li { white-space: pre-wrap; } Καθορίσμος... - + Move in Queue... Μετακίνηση στην ουρά... @@ -24556,7 +25134,7 @@ p, li { white-space: pre-wrap; } Παρακαλούμε εισάγετε ένα νέο--και έγκυρο--όνομα αρχείου - + Expand all Επεκταση ολων @@ -24688,7 +25266,7 @@ p, li { white-space: pre-wrap; } - + Columns Στήλες @@ -24699,7 +25277,7 @@ p, li { white-space: pre-wrap; } - + Path Διαδρομή @@ -24709,7 +25287,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -24719,7 +25297,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... Δημιουργία Συλλογής ... @@ -24734,7 +25312,7 @@ p, li { white-space: pre-wrap; } Εμφάνιση Συλλογής ... - + Collection Συλλογή @@ -24976,7 +25554,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer Άγνωστο Peer @@ -25072,7 +25650,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages Έχετε %1 νεα μυνηματα @@ -25444,7 +26022,7 @@ p, li { white-space: pre-wrap; } Δημιουργία ομάδας - + Subscribe to Group Εγγραφείτε στην ομάδα @@ -25538,8 +26116,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History Εμφανιση ιστορικόυ @@ -25550,7 +26128,7 @@ p, li { white-space: pre-wrap; } - + Preview Προεπισκόπηση @@ -25575,12 +26153,12 @@ p, li { white-space: pre-wrap; } Απόκρυψη ιστορικόυ - + Edit Page Επεξεργασια σελίδας - + Create New Wiki Page Δημιουργία νέας σελίδας Wiki @@ -25600,7 +26178,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group Δημιουργία νέας ομάδας Wiki @@ -25642,7 +26220,7 @@ p, li { white-space: pre-wrap; } TimeRange - + Create Account @@ -25652,12 +26230,11 @@ p, li { white-space: pre-wrap; } - ... - ... + ... - + Refresh Ανανέωση @@ -25692,12 +26269,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -25767,7 +26344,7 @@ p, li { white-space: pre-wrap; } Εμφανιση: - + Yourself τον εαυτό σας @@ -25805,7 +26382,7 @@ p, li { white-space: pre-wrap; } Θέση παλμό για σύρμα - + RetroShare RetroShare @@ -25817,7 +26394,7 @@ p, li { white-space: pre-wrap; } - + The Wire Το σύρμα @@ -25825,7 +26402,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -25906,8 +26483,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar Εικονιδιο @@ -25936,6 +26513,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -26048,8 +26630,12 @@ p, li { white-space: pre-wrap; } + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) + + + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) - Εικόνες (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Εικόνες (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) diff --git a/retroshare-gui/src/lang/retroshare_en.ts b/retroshare-gui/src/lang/retroshare_en.ts index 9f848eea8..d11bfb453 100644 --- a/retroshare-gui/src/lang/retroshare_en.ts +++ b/retroshare-gui/src/lang/retroshare_en.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version @@ -79,7 +79,7 @@ - + Only Hidden Node @@ -121,12 +121,12 @@ - + Search Criteria - + Add a further search criterion. @@ -160,7 +160,7 @@ AlbumDialog - + Album @@ -275,7 +275,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -318,8 +318,8 @@ p, li { white-space: pre-wrap; } - - + + TextLabel @@ -386,7 +386,7 @@ p, li { white-space: pre-wrap; } - + Icon Only @@ -411,7 +411,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 8x8 @@ -436,7 +436,7 @@ p, li { white-space: pre-wrap; } - + Status Bar @@ -511,7 +511,7 @@ p, li { white-space: pre-wrap; } - + Main page items: @@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; } - + Icon Size = 32x32 @@ -592,13 +592,18 @@ p, li { white-space: pre-wrap; } - + + TextLabel + + + + Your Avatar Picture - - Add Avatar + + Browse... @@ -607,25 +612,30 @@ p, li { white-space: pre-wrap; } - + Set your Avatar picture - - Load Avatar + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. AvatarWidget - - Choose avatar - - - - + Click to change your avatar @@ -633,7 +643,7 @@ p, li { white-space: pre-wrap; } BWGraphSource - + KB/s @@ -653,44 +663,53 @@ p, li { white-space: pre-wrap; } RetroShare Bandwidth Usage + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings + TextLabel + + + + Reset - - Receive Rate - - - - - Send Rate - - - - + Always on Top - - Style - - - - + Changes the transparency of the Bandwidth Graph - + 100 @@ -700,30 +719,15 @@ p, li { white-space: pre-wrap; } - - Save - - - - - Cancel - - - - + Since: - - - Hide Settings - - BandwidthStatsWidget - + Sum @@ -745,7 +749,7 @@ p, li { white-space: pre-wrap; } - + Average @@ -879,7 +883,7 @@ p, li { white-space: pre-wrap; } - + Comments @@ -957,6 +961,85 @@ p, li { white-space: pre-wrap; } + + BoardsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + BwCtrlWindow @@ -1092,6 +1175,16 @@ p, li { white-space: pre-wrap; } Log scale + + + Default + + + + + Dark + + ChannelPage @@ -1144,6 +1237,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + + + + + 0 + + + + + I dislike this + + + + + Toggle Message Read Status + + + + + Avatar + + + + + New Comment + + + + + Copy RetroShare Link + + + + + + Expand + + + + + Set as read and remove item + + + + + Remove Item + + + + + Name + + + + + Comm value + + + + + Comment + + + + + Comments + + + + + Hide + + + ChatLobbyDialog @@ -1352,22 +1524,22 @@ into the image, so as to - You have %1 new messages + You have %1 mentions - You have %1 new message + You have %1 mention - %1 new messages + %1 mentions - %1 new message + %1 mention @@ -1381,11 +1553,6 @@ into the image, so as to Remove All - - - mention(s) - - ChatLobbyWidget @@ -1810,13 +1977,7 @@ Double click a chat room to enter and chat. - - Group chat - - - - - + Private chat @@ -1881,17 +2042,12 @@ Double click a chat room to enter and chat. - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> - - Chatlobbies - - - - + Enabled: @@ -1912,11 +2068,12 @@ Double click a chat room to enter and chat. + Chat rooms - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. @@ -1977,11 +2134,17 @@ Double click a chat room to enter and chat. + Broadcast - + + Node-to-node chat + + + + Saved messages (0 = unlimited): @@ -2120,8 +2283,23 @@ Double click a chat room to enter and chat. - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2290,7 +2468,7 @@ Double click a chat room to enter and chat. - + is typing... @@ -2307,12 +2485,12 @@ after HTML conversion. - + Choose your font. - + Do you really want to physically delete the history? @@ -2384,7 +2562,7 @@ after HTML conversion. - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> @@ -2420,12 +2598,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> - + Person id: @@ -2441,7 +2619,7 @@ Double click on it to add his name on text writer. - + items found. @@ -2461,7 +2639,7 @@ Double click on it to add his name on text writer. - + Don't stop to color after @@ -2619,12 +2797,12 @@ Double click on it to add his name on text writer. ConfCertDialog - + Details - + Local Address @@ -2635,12 +2813,12 @@ Double click on it to add his name on text writer. - + Node info: - + Current address: @@ -2656,31 +2834,41 @@ Double click on it to add his name on text writer. - + Include signatures - + RetroShare - + - + Error : cannot get peer details. - + Retroshare ID - + + <p>This Retroshare ID contains: + + + + + <p>This certificate contains: + + + + <li> <b>onion address</b> and <b>port</b> @@ -2696,22 +2884,22 @@ Double click on it to add his name on text writer. - + Encryption - + Not connected - + Retroshare node details - + Node name : @@ -2746,13 +2934,18 @@ Double click on it to add his name on text writer. - + + Connectivity + + + + List of known addresses: - - + + Retroshare Certificate @@ -2767,7 +2960,7 @@ Double click on it to add his name on text writer. - + Hidden Address @@ -2778,17 +2971,22 @@ Double click on it to add his name on text writer. - + <li>a <b>node ID</b> and <b>name</b> - + + <p>You can use this Retroshare ID to make new friends. Send it by email, or give it hand to hand.</p> + + + + <p>You can use this certificate to make new friends. Send it by email, or give it hand to hand.</p> - + <html><head/><body><p>This is the ID of the node's <span style=" font-weight:600;">OpenSSL</span> certifcate, which is signed by the above <span style=" font-weight:600;">PGP</span> key. </p></body></html> @@ -2798,7 +2996,7 @@ Double click on it to add his name on text writer. - + with @@ -2882,32 +3080,32 @@ Double click on it to add his name on text writer. - + Peer details - + Name: - + Location: - + Options - + <html><head/><body><p>This box expects your friend's Retroshare certificate. WARNING: this is different from your friend's profile key. Do not paste your friend's profile key here (not even a part of it). It's not going to work.</p></body></html> - + Add friend to group: @@ -2917,7 +3115,7 @@ Double click on it to add his name on text writer. - + Please paste below your friend's Retroshare ID @@ -2942,12 +3140,12 @@ Double click on it to add his name on text writer. - + Add as friend to connect with - + Sorry, some error appeared @@ -2967,32 +3165,32 @@ Double click on it to add his name on text writer. - + Key validity: - + Profile ID: - + Signers - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + This peer is already on your friend list. Adding it might just set it's ip address. - + To accept the Friend Request, click the Accept button. @@ -3038,17 +3236,17 @@ Double click on it to add his name on text writer. - + Certificate Load Failed - + Not a valid Retroshare certificate! - + RetroShare Invitation @@ -3068,12 +3266,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This is your own certificate! You would not want to make friend with yourself. Wouldn't you? - + @@ -3121,7 +3319,37 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + + Signature failed + + + + + Signature failed. Uncheck the key signature box if you want to make friends without signing the friends' certificate + + + + + Valid Retroshare ID + + + + Valid certificate @@ -3165,12 +3393,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + IP-Addr: - + IP-Address @@ -3200,7 +3428,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + This key is already in your keyring @@ -3258,12 +3486,12 @@ even if you don't make friends. - + [Unknown] - + Added with certificate from %1 @@ -3338,7 +3566,12 @@ even if you don't make friends. - + + Status + + + + <!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; } @@ -3760,7 +3993,7 @@ p, li { white-space: pre-wrap; } CreateCircleDialog - + Circle Details @@ -3900,7 +4133,7 @@ p, li { white-space: pre-wrap; } - + [Unknown] @@ -3915,7 +4148,7 @@ p, li { white-space: pre-wrap; } - + Search @@ -3931,7 +4164,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -3947,12 +4180,12 @@ p, li { white-space: pre-wrap; } - + Circle name - + Update @@ -3974,7 +4207,7 @@ p, li { white-space: pre-wrap; } - + Add Member @@ -4100,7 +4333,7 @@ p, li { white-space: pre-wrap; } - + Attachments @@ -4146,7 +4379,7 @@ p, li { white-space: pre-wrap; } - + Paste RetroShare Links @@ -4156,7 +4389,7 @@ p, li { white-space: pre-wrap; } - + Drop file error. @@ -4183,17 +4416,37 @@ p, li { white-space: pre-wrap; } - + RetroShare - - File already Added and Hashed + + This file already in this post: - + + Post refers to non shared files + + + + + This post contains files that you are currently not sharing. Do you still want to post? + + + + + Post refers to temporary shared files + + + + + The following files will only be shared for 30 days. Think about adding them to a shared directory. + + + + Please add a Subject @@ -4224,12 +4477,12 @@ p, li { white-space: pre-wrap; } - + You are about to add files you're not actually sharing. Do you still want this to happen? - + Edit Channel Post @@ -4249,7 +4502,7 @@ p, li { white-space: pre-wrap; } - + About to post un-owned files to a channel. @@ -4337,7 +4590,7 @@ p, li { white-space: pre-wrap; } - + No Forum @@ -4752,7 +5005,7 @@ and use the import button to load it DHTGraphSource - + users @@ -5755,7 +6008,7 @@ and use the import button to load it FlatStyle_RDM - + Friends Directories @@ -6246,7 +6499,7 @@ at least one peer was not added to a group - + Mark all @@ -6260,7 +6513,7 @@ at least one peer was not added to a group FriendsDialog - + Edit status message @@ -6364,7 +6617,7 @@ at least one peer was not added to a group - + Network @@ -6429,7 +6682,7 @@ at least one peer was not added to a group - + Failed to generate your new certificate, maybe PGP password is wrong! @@ -6460,7 +6713,7 @@ at least one peer was not added to a group - + Node name @@ -6719,12 +6972,12 @@ and use the import button to load it - + Profile generation failure - + Missing PGP certificate @@ -7087,7 +7340,7 @@ p, li { white-space: pre-wrap; } - + GroupBox @@ -7152,7 +7405,7 @@ p, li { white-space: pre-wrap; } - + Details @@ -7175,7 +7428,7 @@ p, li { white-space: pre-wrap; } GlobalRouterStatisticsWidget - + Managed keys @@ -7376,7 +7629,7 @@ p, li { white-space: pre-wrap; } GroupTreeWidget - + Title @@ -7386,13 +7639,30 @@ p, li { white-space: pre-wrap; } - - + + + + Description - + + Number of Unread message + + + + + Friend's Posts + + + + + Search Score + + + + Search Description @@ -7402,42 +7672,7 @@ p, li { white-space: pre-wrap; } - - Sort Descending Order - - - - - Sort Ascending Order - - - - - Sort by Name - - - - - Sort by Popularity - - - - - Sort by Last Post - - - - - Sort by Number of Posts - - - - - Sort by Unread - - - - + You are admin (modify names and description using Edit menu) @@ -7452,40 +7687,31 @@ p, li { white-space: pre-wrap; } - - + + Last Post - + + Name - - Unread - - - - + Popularity - - + + Never - - Display - - - - + <html><head/><body><p>Searches a single keyword into the reachable network.</p><p>Objects already provided by friend nodes are not reported.</p></body></html> @@ -7634,7 +7860,7 @@ p, li { white-space: pre-wrap; } GxsChannelDialog - + Channels @@ -7655,12 +7881,12 @@ p, li { white-space: pre-wrap; } - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Channels</h1> <p>Channels allow you to post data (e.g. movies, music) that will spread in the network</p> <p>You can see the channels your friends are subscribed to, and you automatically forward subscribed channels to your friends. This promotes good channels in the network.</p> <p>Only the channel's creator can post on that channel. Other peers in the network can only read from it, unless the channel is private. You can however share the posting rights or the reading rights with friend Retroshare nodes.</p> <p>Channels can be made anonymous, or attached to a Retroshare identity so that readers can contact you if needed. Enable "Allow Comments" if you want to let users comment on your posts.</p> <p>Channel posts are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> <p>UI Tip: use Control + mouse wheel to control image size in the thumbnail view.</p> - + Subscribed Channels @@ -8023,7 +8249,7 @@ p, li { white-space: pre-wrap; } - + Add new post @@ -8123,12 +8349,12 @@ p, li { white-space: pre-wrap; } - + Files - + Comments @@ -8139,18 +8365,18 @@ p, li { white-space: pre-wrap; } - + Feeds - - + + Click to switch to list view - + Show unread posts only @@ -8160,12 +8386,12 @@ p, li { white-space: pre-wrap; } - + No files in the channel, or no channel selected - + No text to display @@ -8225,7 +8451,7 @@ p, li { white-space: pre-wrap; } - + Download this file: @@ -8240,12 +8466,12 @@ p, li { white-space: pre-wrap; } - + Comments (%1) - + [No name] @@ -8321,23 +8547,36 @@ p, li { white-space: pre-wrap; } + Copy Retroshare link + + + + Subscribed - - Subscribe - - Hit this button to retrieve the data you need to subscribe to this channel + + Channel info missing - + + To subscribe, first request the channel information by right-clicking Request Data in the search results. + + + + + Channel info requested... + + + + No Channel Selected @@ -8359,11 +8598,6 @@ p, li { white-space: pre-wrap; } Channel Post - - - new message(s) - - GxsCircleItem @@ -8848,17 +9082,17 @@ before you can comment - + Search forums - + New Thread - + Threaded View @@ -8868,19 +9102,19 @@ before you can comment - - + + Title - - + + Date - + Author @@ -8895,7 +9129,17 @@ before you can comment - + + <html><head/><body><p>Click here to clear current selected thread and display more information about this forum.</p></body></html> + + + + + Forum Name + + + + Lastest post in thread @@ -8940,23 +9184,23 @@ before you can comment - + No name - - + + Reply - + <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> - + Loading... @@ -8994,17 +9238,17 @@ before you can comment - + Copy RetroShare Link - + Hide - + [unknown] @@ -9034,8 +9278,8 @@ before you can comment - - + + Distribution @@ -9118,12 +9362,12 @@ before you can comment - + New thread - + Edit @@ -9179,7 +9423,7 @@ before you can comment - + Author's reputation @@ -9199,7 +9443,7 @@ before you can comment - + <b>Loading...<b> @@ -9239,6 +9483,11 @@ before you can comment Storage + + + Last seen at friends: + + Moderators @@ -9306,7 +9555,7 @@ This message is missing. You should receive it later. - + Forum name @@ -9338,11 +9587,6 @@ This message is missing. You should receive it later. Forum Post - - - new message(s) - - GxsForumsDialog @@ -9748,7 +9992,7 @@ This message is missing. You should receive it later. - + Unsubscribe @@ -9763,7 +10007,7 @@ This message is missing. You should receive it later. - + Remove this search @@ -9773,12 +10017,12 @@ This message is missing. You should receive it later. - + Request data - + Show Details @@ -9845,12 +10089,12 @@ This message is missing. You should receive it later. - + Search for - + Copy RetroShare Link @@ -9865,7 +10109,7 @@ This message is missing. You should receive it later. - + AUTHD @@ -10379,7 +10623,7 @@ This message is missing. You should receive it later. <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; font-weight:400; font-style:normal;"> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">RetroShare is an Open Source cross-platform, </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">private and secure decentralized communication platform. </span></p> <p align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">It lets you share securely your friends, </span></p> @@ -10388,7 +10632,7 @@ p, li { white-space: pre-wrap; } <p align="center" 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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">Useful external links to more information:</span></p> <ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" font-family:'MS Shell Dlg 2'; font-size:8pt;" align="justify" style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.cc/"><span style=" font-size:12pt; text-decoration: underline; color:#007af4;">Retroshare Webpage</span></a></li> -<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshare.readthedocs.io/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> +<li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retrosharedocs.readthedocs.io/en/latest/"><span style=" color:#007af4;">Retroshare Wiki</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/RetroShare/RetroShare"><span style=" color:#007af4;">Retroshare Project Page</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://retroshareteam.wordpress.com/"><span style=" color:#007af4;">RetroShare Team Blog</span></a></li> <li style=" font-family:'MS Shell Dlg 2'; font-size:12pt; text-decoration: underline; color:#0000ff;" align="justify" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://twitter.com/retroshare"><span style=" color:#007af4;">RetroShare Dev Twitter</span></a></li></ul></body></html> @@ -10414,7 +10658,7 @@ p, li { white-space: pre-wrap; } <!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;"> +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:9pt; 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-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:600;">RetroShare Translations:</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-family:'MS Shell Dlg 2'; font-size:8pt;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://retroshare.sourceforge.net/wiki/index.php/Translation"><span style=" font-family:'MS Shell Dlg 2'; text-decoration: underline; color:#0000ff;">http://retroshare.sourceforge.net/wiki/index.php/Translation</span></a></p> @@ -10488,49 +10732,55 @@ p, li { white-space: pre-wrap; } - - Did you receive a Retroshare id from a friend? - - - - + Add friend - + Do you need help with Retroshare? - + <html><head/><body><p>Share your RetroShare ID</p></body></html> - + This is your Retroshare ID. Copy and share with your friends! + ... - + + <html><head/><body><p>Copy your RetroShare ID to clipboard</p></body></html> + + + + Open Source cross-platform, private and secure decentralized communication platform. - + + Did you receive a Retroshare ID from a friend? + + + + Open Web Help - + Copy your Cert to Clipboard @@ -10578,17 +10828,12 @@ new short format - - <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your certificate on this page and send it to friends, and add your friends' certificate.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange certificates with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> - - - - + Use new (short) certificate format - + Your Retroshare certificate is copied to Clipboard, paste and send it to your friend via email or some other way @@ -10603,7 +10848,12 @@ new short format - + + <h1><img width="%1" src=":/icons/help_64.png">&nbsp;&nbsp;Welcome to Retroshare!</h1> <p>You need to <b>make friends</b>! After you create a network of friends or join an existing network, you'll be able to exchange files, chat, talk in forums, etc. </p> <div align=center> <IMG align="center" width="%2" src=":/images/network_map.png"/> </div> <p>To do so, copy your Retroshare ID on this page and send it to friends, and add your friends' Retroshare ID.</p> <p>Another option is to search the internet for "Retroshare chat servers" (independently administrated). These servers allow you to exchange Retroshare ID with a dedicated Retroshare node, through which you will be able to anonymously meet other people.</p> + + + + Save as... @@ -10868,14 +11118,14 @@ p, li { white-space: pre-wrap; } IdDialog - - - + + + All - + Reputation @@ -10885,12 +11135,12 @@ p, li { white-space: pre-wrap; } - + Anonymous Id - + Create new Identity @@ -11034,7 +11284,7 @@ p, li { white-space: pre-wrap; } - + Send message @@ -11106,7 +11356,7 @@ p, li { white-space: pre-wrap; } - + Anonymous @@ -11121,24 +11371,24 @@ p, li { white-space: pre-wrap; } - + This identity is owned by you - - + + My own identities - - + + My contacts - + Show Items @@ -11153,7 +11403,7 @@ p, li { white-space: pre-wrap; } - + Other circles @@ -11212,13 +11462,18 @@ p, li { white-space: pre-wrap; } subscribed (Receive/forward membership requests from others and invite list). + + + unsubscribed (Only receive invite list). Last seen: %1 days ago. + + unsubscribed (Only receive invite list). - + Your status: @@ -11278,7 +11533,7 @@ p, li { white-space: pre-wrap; } - + Edit Circle @@ -11326,7 +11581,7 @@ p, li { white-space: pre-wrap; } - + This identity has a unsecure fingerprint (It's probably quite old). You should get rid of it now and use a new one. @@ -11335,12 +11590,12 @@ These identities will soon be not supported anymore. - + [Unknown node] - + Unverified signature from node @@ -11352,12 +11607,12 @@ These identities will soon be not supported anymore. - + [unverified] - + Identity owned by you, linked to your Retroshare node @@ -11473,17 +11728,17 @@ These identities will soon be not supported anymore. - + Banned - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Identities</h1> <p>In this tab you can create/edit <b>pseudo-anonymous identities</b>, and <b>circles</b>.</p> <p><b>Identities</b> are used to securely identify your data: sign messages in chat lobbies, forum and channel posts, receive feedback using the Retroshare built-in email system, post comments after channel posts, chat using secured tunnels, etc.</p> <p>Identities can optionally be <b>signed</b> by your Retroshare node's certificate. Signed identities are easier to trust but are easily linked to your node's IP address.</p> <p><b>Anonymous identities</b> allow you to anonymously interact with other users. They cannot be spoofed, but noone can prove who really owns a given identity.</p> <p><b>Circles</b> are groups of identities (anonymous or signed), that are shared at a distance over the network. They can be used to restrict the visibility to forums, channels, etc. </p> <p>An <b>circle</b> can be restricted to another circle, thereby limiting its visibility to members of that circle or even self-restricted, meaning that it is only visible to invited members.</p> - + positive @@ -11640,8 +11895,8 @@ These identities will soon be not supported anymore. - - + + People @@ -11652,7 +11907,7 @@ These identities will soon be not supported anymore. - + Linked to neighbor nodes @@ -11662,7 +11917,7 @@ These identities will soon be not supported anymore. - + Linked to a friend Retroshare node @@ -11722,7 +11977,7 @@ These identities will soon be not supported anymore. - + Node name: @@ -11732,7 +11987,7 @@ These identities will soon be not supported anymore. - + Really delete? @@ -11770,7 +12025,7 @@ These identities will soon be not supported anymore. - + New identity @@ -11787,14 +12042,14 @@ These identities will soon be not supported anymore. - + N/A - + Edit identity @@ -11805,24 +12060,27 @@ These identities will soon be not supported anymore. - + + Profile password needed. - + + Identity creation failed - + + Cannot create an identity linked to your profile without your profile password. - + Identity creation success @@ -11842,12 +12100,37 @@ These identities will soon be not supported anymore. - + + Identity update failed + + + + + Cannot update identity. Something went wrong. Check your profile password. + + + + Error KeyID invalid - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + + Unknown GpgId @@ -11857,7 +12140,7 @@ These identities will soon be not supported anymore. - + Create New Identity @@ -11867,7 +12150,12 @@ These identities will soon be not supported anymore. - + + Choose image... + + + + @@ -11907,12 +12195,7 @@ These identities will soon be not supported anymore. - - Set Avatar - - - - + Linked to your profile @@ -11922,7 +12205,7 @@ These identities will soon be not supported anymore. - + The nickname is too short. Please input at least %1 characters. @@ -12027,7 +12310,7 @@ These identities will soon be not supported anymore. - Send + Quote @@ -12186,7 +12469,7 @@ These identities will soon be not supported anymore. - + Options @@ -12218,12 +12501,12 @@ These identities will soon be not supported anymore. - + RetroShare %1 a secure decentralized communication platform - + Unfinished @@ -12352,7 +12635,7 @@ These identities will soon be not supported anymore. - + Make sure this link has not been forged to drag you to a malicious website. @@ -12397,7 +12680,7 @@ These identities will soon be not supported anymore. - + Statistics @@ -12426,7 +12709,7 @@ These identities will soon be not supported anymore. MessageComposer - + Compose @@ -12528,7 +12811,7 @@ These identities will soon be not supported anymore. - + Tags @@ -12623,12 +12906,12 @@ These identities will soon be not supported anymore. - + Send To: - + &Left @@ -12658,7 +12941,12 @@ These identities will soon be not supported anymore. - + + Friend Nodes + + + + Hello,<br>I recommend a good friend of mine; you can trust them too when you trust me. <br> @@ -12684,12 +12972,12 @@ These identities will soon be not supported anymore. - + Save Message - + Message has not been Sent. Do you want to save message to draft box? @@ -12700,7 +12988,7 @@ Do you want to save message to draft box? - + Add to "To" @@ -12954,7 +13242,7 @@ Do you want to save message ? - + Hi,<br>I want to be friends with you on RetroShare.<br> @@ -12968,6 +13256,21 @@ Do you want to save message ? Respond now: + + + Message Size: %1 + + + + + It remains %1 characters after HTML conversion. + + + + + Warning: This message is too big of %1 characters after HTML conversion. + + @@ -12980,7 +13283,7 @@ Do you want to save message ? - + Bullet list (disc) @@ -13020,13 +13323,13 @@ Do you want to save message ? - - + + Thanks, <br> - + Distant identity: @@ -13165,8 +13468,23 @@ Do you want to save message ? - - new mail(s) + + You have %1 new mails + + + + + You have %1 new mail + + + + + %1 new mails + + + + + %1 new mail @@ -13178,12 +13496,12 @@ Do you want to save message ? - + Download all Recommended Files - + Subject: @@ -13258,12 +13576,18 @@ Do you want to save message ? - + + Message Size: + + + + File Name - + + Size @@ -13324,18 +13648,33 @@ Do you want to save message ? - + + You got an invite to make friend! You may accept this request. + + + + + You got an invite to make friend! You may accept this request and send your own Certificate back + + + + Document source + + + %1 (%2) + + - + Download all - + Print Document @@ -13350,7 +13689,7 @@ Do you want to save message ? - + Load images always for this message @@ -13455,7 +13794,7 @@ Do you want to save message ? MessagesDialog - + New Message @@ -13467,14 +13806,14 @@ Do you want to save message ? - + Tags - + Inbox @@ -13545,7 +13884,7 @@ Do you want to save message ? - + Subject @@ -13625,7 +13964,7 @@ Do you want to save message ? - + Open in a new window @@ -13710,7 +14049,7 @@ Do you want to save message ? - + Drafts @@ -13799,7 +14138,7 @@ Do you want to save message ? - + Delete Message @@ -13810,7 +14149,7 @@ Do you want to save message ? - + Expand @@ -13820,7 +14159,7 @@ Do you want to save message ? - + from @@ -13829,6 +14168,11 @@ Do you want to save message ? Reply to invite + + + This message invites you to make friend! You may accept this request. + + Message From @@ -14128,7 +14472,7 @@ Reported error: - + Groups @@ -14158,19 +14502,19 @@ Reported error: - - + + Search - + ID - + Search ID @@ -14180,7 +14524,7 @@ Reported error: - + Show Items @@ -14379,18 +14723,18 @@ at least one peer was not added to a group - + Error - + File is not writeable! - + File is not readable! @@ -14428,7 +14772,7 @@ at least one peer was not added to a group NewsFeed - Log entries + Activity Stream @@ -14442,7 +14786,7 @@ at least one peer was not added to a group - + Newest on top @@ -14453,20 +14797,35 @@ at least one peer was not added to a group - <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;News Feed</h1> <p>The Log Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel and Forum posts</li> <li>New Channels and Forums you can subscribe to</li> <li>Private messages from your friends</li> </ul> </p> + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Activity Feed</h1> <p>The Activity Feed displays the last events on your network, sorted by the time you received them. This gives you a summary of the activity of your friends. You can configure which events to show by pressing on <b>Options</b>. </p> <p>The various events shown are: <ul> <li>Connection attempts (useful to make friends with new people and control who's trying to reach you)</li> <li>Channel, Forum and Board posts</li> <li>Circle membership requests and invites</li> <li>New Channels, Forums and Boards you can subscribe to</li> <li>Channel and Board comments</li> <li>New Mail messages</li> <li>Private messages from your friends</li> </ul> </p> - Log + Activity NewsFeedUserNotify - - logged event(s) + + You have %1 logged events + + + + + You have %1 logged event + + + + + %1 logged events + + + + + %1 logged event @@ -14499,22 +14858,22 @@ at least one peer was not added to a group - + Test - + Chat Room - + Systray Icon - + Message @@ -14535,12 +14894,7 @@ at least one peer was not added to a group - - Log - - - - + Friend Connected @@ -14587,27 +14941,37 @@ at least one peer was not added to a group - + + Toaster position + + + + Chat rooms - + Position - + + Activity + + + + X Margin - + Y Margin - + Systray message @@ -14657,7 +15021,7 @@ at least one peer was not added to a group - + Disable All Toasters @@ -14667,7 +15031,7 @@ at least one peer was not added to a group - + Systray @@ -14794,17 +15158,12 @@ at least one peer was not added to a group PGPKeyDialog - - Dialog - - - - + Profile info - + Name : @@ -14859,22 +15218,17 @@ at least one peer was not added to a group - + This profile has signed your own profile key - - Key signatures : - - - - + <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. The signatures below cryptographically attest that owners of the listed keys recognise the current PGP key as authentic.</span></p></body></html> - + <!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; } @@ -14888,7 +15242,7 @@ p, li { white-space: pre-wrap; } - + PGP key @@ -14898,22 +15252,12 @@ p, li { white-space: pre-wrap; } - - <html><head/><body><p><span style=" font-size:10pt;">Signing a friend's key is a way to express your trust into this friend, to your other friends. It helps them to decide whether to allow connections from that key based on your own trust. Signing a key is absolutely optional and cannot be undone, so do it wisely.</span></p></body></html> - - - - + Keysigning: - - Sign PGP key - - - - + <html><head/><body><p>Click here if you want to refuse connections to nodes authenticated by this key.</p></body></html> @@ -14933,7 +15277,7 @@ p, li { white-space: pre-wrap; } - + Below is the node's profile key in PGP ASCII format. It identifies all nodes of the same profile. A "Retroshare certificate" that you can exchange in order to make friends, is in the the "details" of each separate node. @@ -14999,27 +15343,27 @@ p, li { white-space: pre-wrap; } - - + + RetroShare - - + + Error : cannot get peer details. - + The supplied key algorithm is not supported by RetroShare (Only RSA keys are supported at the moment) - + Warning: In your File-Transfer option, you select allow direct download to Yes. @@ -15031,7 +15375,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + The trust level is a way to express your own trust in this key. It is not used by the software nor shared, but can be useful to you in order to remember good/bad keys. @@ -15076,27 +15420,43 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + + Profile password needed. + + + + + Identity creation failed + + + + + Cannot create an identity linked to your profile without your profile password. + + + + Signature Failure - - Maybe password is wrong + + Check the password! - + You haven't set a trust level for this key. - + + Retroshare profile - + This is your own PGP key, and it is signed by : @@ -15267,8 +15627,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. PeopleDialog - - + People @@ -15285,7 +15644,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + Chat with this person @@ -15417,7 +15776,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel @@ -15453,7 +15812,7 @@ Warning: In your File-Transfer option, you select allow direct download to No. - <N> Comments >> + Comments @@ -15481,6 +15840,11 @@ Warning: In your File-Transfer option, you select allow direct download to No.... + + + Album + + PhotoItem @@ -15490,12 +15854,12 @@ Warning: In your File-Transfer option, you select allow direct download to No. - + TextLabel - + <!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; } @@ -15575,7 +15939,7 @@ p, li { white-space: pre-wrap; } - + PhotoShare @@ -15615,7 +15979,7 @@ requesting to edit it! - + Stop @@ -15839,17 +16203,17 @@ p, li { white-space: pre-wrap; } PluginsPage - + Authorize all plugins - + Plugin look-up directories - + Plugins @@ -16175,7 +16539,7 @@ p, li { white-space: pre-wrap; } PostedDialog - + <h1><img width="32" src=":/icons/help_64.png">&nbsp;&nbsp;Boards</h1> <p>The Boards service allows you to share images, blog posts & internet links, that spread among Retroshare nodes like forums and channels</p> <p>Posts can be commented by subscribed users. A promotion system also gives the opportunity to enlight important links.</p> <p>There is no restriction on which links are shared. Be careful when clicking on them.</p> <p>Boards are kept for %1 days, and sync-ed over the last %2 days, unless you change this.</p> @@ -16306,13 +16670,13 @@ p, li { white-space: pre-wrap; } - - + + Comments - + Copy RetroShare Link @@ -16322,7 +16686,7 @@ p, li { white-space: pre-wrap; } - + Comment @@ -16343,12 +16707,12 @@ p, li { white-space: pre-wrap; } - + Hide - + Vote up @@ -16358,7 +16722,7 @@ p, li { white-space: pre-wrap; } - + Set as read and remove item @@ -16419,7 +16783,7 @@ p, li { white-space: pre-wrap; } - + Loading @@ -16442,13 +16806,7 @@ p, li { white-space: pre-wrap; } - - - <html><head/><body><p>This includes posts, comments to posts and votes to comments.</p></body></html> - - - - + 0 @@ -16458,60 +16816,50 @@ p, li { white-space: pre-wrap; } - - - + + + unknown - + Distribution: - + Last activity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updates when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Created - + TextLabel - + Popularity: - - <html><head/><body><p>Includes all posts, comments and votes. This number is progressively updated when new friend connect. The local vs. at friends difference may indicate that you would get older posts by increasing the synchronization period.</p></body></html> - - - - + Contributions: - + Sync period: - + Posts @@ -16522,7 +16870,7 @@ p, li { white-space: pre-wrap; } - <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14px; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> + <html><head/><body><p><span style=" font-family:'-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol'; font-size:14pt; color:#24292e; background-color:#ffffff;">Select sorting</span></p></body></html> @@ -16591,7 +16939,12 @@ p, li { white-space: pre-wrap; } - + + Empty + + + + Copy RetroShare Link @@ -16626,7 +16979,7 @@ p, li { white-space: pre-wrap; } - + [No name] @@ -16742,8 +17095,18 @@ p, li { white-space: pre-wrap; } - - new board post(s) + + You have %1 new board posts + + + + + You have %1 new board post + + + + + %1 new board post @@ -17011,12 +17374,7 @@ and use the import button to load it PulseAddDialog - - Post From: - - - - + Add to Pulse @@ -17031,17 +17389,32 @@ and use the import button to load it - + GroupLabel - + IDLabel - + + From: + + + + + Head + + + + + Head Shot + + + + Response Sentiment: @@ -17066,10 +17439,20 @@ and use the import button to load it - + + + Whats happening? + + + + + + + + Drag and Drop Image @@ -17079,13 +17462,48 @@ and use the import button to load it - + + Post + + + + Cancel - - Post Pulse to Wire + + Post + + + + + Reply to Pulse + + + + + Pulse your reply + + + + + Republish Pulse + + + + + Like Pulse + + + + + Hide Pictures + + + + + Add Pictures @@ -17097,10 +17515,18 @@ and use the import button to load it - - - - + + + + + Click to view picture + + + + + + + Image @@ -17108,44 +17534,44 @@ and use the import button to load it PulseReply - + icn - + retweeted - + REPLY - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17155,17 +17581,17 @@ and use the import button to load it - + <html><head/><body><p><span style=" font-weight:600;">Sidler</span></p></body></html> - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> - + <html><head/><body><p><span style=" color:#2e3436;">· Apr 13 ·</span></p></body></html> @@ -17175,7 +17601,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">Replying to @sidler</span></p></body></html> @@ -17183,7 +17609,7 @@ and use the import button to load it PulseTopLevel - + retweeted @@ -17198,7 +17624,7 @@ and use the import button to load it - + follow Parent Group @@ -17208,7 +17634,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#555753;">@sidler_here</span></p></body></html> @@ -17233,7 +17659,7 @@ and use the import button to load it - + <html><head/><body><p><span style=" color:#2e3436;">3:58 AM · Apr 13, 2020 ·</span></p></body></html> @@ -17269,29 +17695,29 @@ and use the import button to load it - - - + + + 1 - + REPUBLISH - + LIKE - + SHOW - + FOLLOW @@ -17369,7 +17795,7 @@ and use the import button to load it QObject - + Confirmation @@ -17608,7 +18034,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Unable to make path @@ -17643,7 +18069,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances. <br><br>You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software. @@ -17781,7 +18207,7 @@ Reported error is: - + TR up @@ -17826,7 +18252,7 @@ Reported error is: - + Move IP %1 to whitelist @@ -17842,7 +18268,7 @@ Reported error is: - + %1 seconds ago @@ -17926,7 +18352,7 @@ Security: no anonymous IDs - + Error @@ -18316,11 +18742,6 @@ Security: no anonymous IDs Click to resume the hashing process - - - <p>This certificate contains: - - Idle @@ -18654,7 +19075,7 @@ p, li { white-space: pre-wrap; } RSGraphWidget - + %1 KB @@ -18868,7 +19289,12 @@ p, li { white-space: pre-wrap; } - + + Save image + + + + Document source @@ -18876,18 +19302,39 @@ p, li { white-space: pre-wrap; } RSTreeWidget - + Tree View Options - Show column... + Show Header - - [no title] + + Sort by column … + + + + + Sort Descending Order + + + + + Sort Ascending Order + + + + + + [no title] + + + + + Show column … @@ -19324,7 +19771,7 @@ p, li { white-space: pre-wrap; } - + File @@ -19339,7 +19786,7 @@ p, li { white-space: pre-wrap; } - + Bad filenames have been cleaned @@ -19387,7 +19834,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Collection Editor @@ -19402,7 +19849,7 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Real Size: Waiting child... @@ -19417,12 +19864,12 @@ Characters <b>",|,/,\,&lt;,&gt;,*,?</b> will be replace - + Download files - + Specify... @@ -19669,7 +20116,7 @@ If you believe it is correct, remove the corresponding line from the file and re RsFriendListModel - + Name @@ -19689,7 +20136,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Profile ID @@ -19702,10 +20149,15 @@ If you believe it is correct, remove the corresponding line from the file and re RsGxsForumModel - + Title + + + UnRead + + Date @@ -19717,7 +20169,7 @@ If you believe it is correct, remove the corresponding line from the file and re - + Information for this identity is currently missing. @@ -19755,7 +20207,7 @@ prevents the message to be forwarded to your friends. - + [ ... Missing Message ... ] @@ -19763,7 +20215,7 @@ prevents the message to be forwarded to your friends. RsMessageModel - + Date @@ -19823,7 +20275,7 @@ prevents the message to be forwarded to your friends. - + [Notification] @@ -20177,7 +20629,7 @@ prevents the message to be forwarded to your friends. - + Download @@ -20256,7 +20708,7 @@ prevents the message to be forwarded to your friends. - + Create Collection... @@ -20276,7 +20728,7 @@ prevents the message to be forwarded to your friends. - + Collection @@ -20381,12 +20833,12 @@ prevents the message to be forwarded to your friends. - + Deny friend - + Chat @@ -20396,7 +20848,7 @@ prevents the message to be forwarded to your friends. - + Expand @@ -20659,13 +21111,13 @@ behind a firewall or a VPN. - + Tor has been automatically configured by Retroshare. You shouldn't need to change anything here. - + Discovery Off @@ -21131,7 +21583,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Network @@ -21159,7 +21611,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Status @@ -21256,7 +21708,7 @@ If you have issues connecting over Tor check the Tor logs too. - + Service Address @@ -21291,12 +21743,12 @@ If you have issues connecting over Tor check the Tor logs too. - + IP Range - + Reported by DHT for IP masquerading @@ -21961,7 +22413,7 @@ p, li { white-space: pre-wrap; } - + Wrong password @@ -22003,7 +22455,7 @@ This choice can be reverted in settings. StatisticsWindow - + Add Friend @@ -22059,7 +22511,7 @@ This choice can be reverted in settings. - + DHT @@ -22591,7 +23043,7 @@ p, li { white-space: pre-wrap; } TorStatus - + Tor @@ -22601,13 +23053,12 @@ p, li { white-space: pre-wrap; } - - + Tor is currently offline - + Tor is OK @@ -22616,6 +23067,31 @@ p, li { white-space: pre-wrap; } No tor configuration + + + Tor proxy is OK + + + + + Tor proxy is not available + + + + + I2P + + + + + i2p proxy is OK + + + + + i2p proxy is not available + + TransferPage @@ -22889,27 +23365,22 @@ p, li { white-space: pre-wrap; } - You have %1 completed downloads + You have %1 completed transfers - You have %1 completed download + You have %1 completed transfer - %1 completed downloads + %1 completed transfers - %1 completed download - - - - - completed transfer(s) + %1 completed transfer @@ -22917,7 +23388,7 @@ p, li { white-space: pre-wrap; } TransfersDialog - + Downloads @@ -22928,7 +23399,7 @@ p, li { white-space: pre-wrap; } - + Name i.e: file name @@ -23135,7 +23606,7 @@ p, li { white-space: pre-wrap; } - + Move in Queue... @@ -23229,7 +23700,7 @@ p, li { white-space: pre-wrap; } - + Expand all @@ -23361,7 +23832,7 @@ p, li { white-space: pre-wrap; } - + Columns @@ -23372,7 +23843,7 @@ p, li { white-space: pre-wrap; } - + Path @@ -23382,7 +23853,7 @@ p, li { white-space: pre-wrap; } - + Could not delete preview file @@ -23392,7 +23863,7 @@ p, li { white-space: pre-wrap; } - + Create Collection... @@ -23407,7 +23878,7 @@ p, li { white-space: pre-wrap; } - + Collection @@ -23649,7 +24120,7 @@ p, li { white-space: pre-wrap; } - + Unknown Peer @@ -23745,7 +24216,7 @@ p, li { white-space: pre-wrap; } UserNotify - + You have %1 new messages @@ -24113,7 +24584,7 @@ p, li { white-space: pre-wrap; } - + Subscribe to Group @@ -24207,8 +24678,8 @@ p, li { white-space: pre-wrap; } - - + + Show Edit History @@ -24219,7 +24690,7 @@ p, li { white-space: pre-wrap; } - + Preview @@ -24244,12 +24715,12 @@ p, li { white-space: pre-wrap; } - + Edit Page - + Create New Wiki Page @@ -24269,7 +24740,7 @@ p, li { white-space: pre-wrap; } WikiGroupDialog - + Create New Wiki Group @@ -24307,7 +24778,7 @@ p, li { white-space: pre-wrap; } WireDialog - + Create Account @@ -24317,12 +24788,7 @@ p, li { white-space: pre-wrap; } - - ... - - - - + Refresh @@ -24357,12 +24823,12 @@ p, li { white-space: pre-wrap; } - + > - + Most Recent @@ -24392,7 +24858,7 @@ p, li { white-space: pre-wrap; } - + Yourself @@ -24402,7 +24868,7 @@ p, li { white-space: pre-wrap; } - + RetroShare @@ -24414,7 +24880,7 @@ p, li { white-space: pre-wrap; } - + The Wire @@ -24422,7 +24888,7 @@ p, li { white-space: pre-wrap; } WireGroupDialog - + Create New Wire @@ -24503,8 +24969,8 @@ p, li { white-space: pre-wrap; } - - + + Avatar @@ -24533,6 +24999,11 @@ p, li { white-space: pre-wrap; } Sub/Un + + + Edit Profile + + misc @@ -24645,7 +25116,7 @@ p, li { white-space: pre-wrap; } - Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif) + Pictures (*.png *.jpeg *.xpm *.jpg *.tiff *.gif *.webp) diff --git a/retroshare-gui/src/lang/retroshare_es.ts b/retroshare-gui/src/lang/retroshare_es.ts index f99b0a44f..3df49a47e 100644 --- a/retroshare-gui/src/lang/retroshare_es.ts +++ b/retroshare-gui/src/lang/retroshare_es.ts @@ -4,7 +4,7 @@ AWidget - + Retroshare version Versión de RetroShare @@ -79,7 +79,7 @@ Que se divierta ;-) - + Only Hidden Node Sólo nodo oculto @@ -129,12 +129,12 @@ RetroShare: Búsqueda avanzada - + Search Criteria Criterios de búsqueda - + Add a further search criterion. Añadir un criterio de búsqueda adicional. @@ -339,7 +339,7 @@ p, li { white-space: pre-wrap; } AlbumDialog - + Album Álbum @@ -494,7 +494,7 @@ p, li { white-space: pre-wrap; } AlbumGroupDialog - + Create New Album @@ -537,8 +537,8 @@ p, li { white-space: pre-wrap; } Formulario - - + + TextLabel Texto de la etiqueta @@ -613,7 +613,7 @@ p, li { white-space: pre-wrap; } Barra de herramientas - + Icon Only Sólo icono @@ -638,7 +638,7 @@ p, li { white-space: pre-wrap; } Elija el estilo de los botones de herramientas. - + Icon Size = 8x8 Tamaño de icono = 8x8 @@ -663,7 +663,7 @@ p, li { white-space: pre-wrap; } Tamaño de icono = 128x128 - + Status Bar Barra de estado @@ -738,7 +738,7 @@ p, li { white-space: pre-wrap; } Deshabilitar sugerencias en bandeja de sistema - + Main page items: Elementos de la página principal: @@ -753,7 +753,7 @@ p, li { white-space: pre-wrap; } Lista de elementos - + Icon Size = 32x32 Tamaño de icono = 32x32 @@ -828,14 +828,23 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro Cambiar avatar - + + TextLabel + + + + Your Avatar Picture La imagen de su avatar - + + Browse... + + + Add Avatar - Añadir avatar + Añadir avatar @@ -843,25 +852,34 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro Eliminar - + Set your Avatar picture Establecer imagen de avatar - + + Import image + + + + + Image files (*.jpg *.png);;All files (*) + + + + + Use the mouse to zoom and adjust the image for your avatar. + + + Load Avatar - Cargar avatar + Cargar avatar AvatarWidget - - Choose avatar - - - - + Click to change your avatar Pulse aquí para cambiar su avatar @@ -869,7 +887,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro BWGraphSource - + KB/s KB/s @@ -889,44 +907,65 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro RetroShare Bandwidth Usage Ancho de banda usado por RetroShare + + + PushButton + + - + Up + + + + + Down + + + + + Clears the graph + + + + Show Settings Mostrar ajustes + TextLabel + + + + Reset Reinicializar - Receive Rate - Tasa de recepción + Tasa de recepción - Send Rate - Tasa de envío + Tasa de envío - + Always on Top Siempre encima - Style - Estilo + Estilo - + Changes the transparency of the Bandwidth Graph Cambia la transparencia de la gráfica de tráfico de red - + 100 100 @@ -936,30 +975,27 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro % Transparencia - Save - Guardar + Guardar - Cancel - Cancelar + Cancelar - + Since: Desde: - Hide Settings - Ocultar ajustes + Ocultar ajustes BandwidthStatsWidget - + Sum Agregado @@ -981,7 +1017,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro Recuento - + Average Media @@ -1115,7 +1151,7 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro - + Comments Comentarios @@ -1193,6 +1229,85 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro + + BoardsCommentsItem + + + I like this + Esto me gusta + + + + 0 + 0 + + + + I dislike this + Esto no me gusta + + + + Toggle Message Read Status + Cambiar el estado de lectura del mensaje + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copiar enlace de RetroShare + + + + + Expand + + + + + Set as read and remove item + Ajustar como leer y eliminar elemento + + + + Remove Item + + + + + Name + Nombre + + + + Comm value + + + + + Comment + Comentario + + + + Comments + Comentarios + + + + Hide + Ocultar + + BwCtrlWindow @@ -1328,6 +1443,16 @@ Pero recuerde: Todos los datos aquí *SE PERDERÁN* cuando se actualicen los pro Log scale Escala logarítmica + + + Default + + + + + Dark + + ChannelPage @@ -1384,6 +1509,85 @@ into the image, so as to + + ChannelsCommentsItem + + + I like this + Esto me gusta + + + + 0 + 0 + + + + I dislike this + Esto no me gusta + + + + Toggle Message Read Status + Cambiar el estado de lectura del mensaje + + + + Avatar + Avatar + + + + New Comment + + + + + Copy RetroShare Link + Copiar enlace de RetroShare + + + + + Expand + + + + + Set as read and remove item + Ajustar como leer y eliminar elemento + + + + Remove Item + + + + + Name + Nombre + + + + Comm value + + + + + Comment + Comentario + + + + Comments + Comentarios + + + + Hide + Ocultar + + ChatLobbyDialog @@ -1591,24 +1795,40 @@ into the image, so as to Chats - You have %1 new messages - Tiene %1 nuevos mensajes + Tiene %1 nuevos mensajes + + + You have %1 new message + Tiene %1 nuevo mensaje + + + %1 new messages + %1 nuevos mensajes + + + %1 new message + %1 nuevo mensaje + + + + You have %1 mentions + - You have %1 new message - Tiene %1 nuevo mensaje + You have %1 mention + - %1 new messages - %1 nuevos mensajes + %1 mentions + - %1 new message - %1 nuevo mensaje + %1 mention + @@ -1621,11 +1841,6 @@ into the image, so as to Remove All Borrar todo - - - mention(s) - - ChatLobbyWidget @@ -2120,13 +2335,11 @@ Haga doble clic en una sala de chat para entrar y conversar. Variante: - Group chat - Chat en grupo + Chat en grupo - - + Private chat Chat privado @@ -2191,17 +2404,16 @@ Haga doble clic en una sala de chat para entrar y conversar. /me está enviando un mensaje con /me - + <html><head/><body><p align="justify">In this tab you can setup how many chat messages Retroshare will keep saved on the disc and how much of the previous conversation it will display, for the different chat systems. The max storage period allows to discard old messages and prevents the chat history from filling up with volatile chat (e.g. chat lobbies and distant chat).</p></body></html> <html><head/><body><p align="justify">En esta pestaña puedes configurar cuantos mensajes guardará en disco RetroShare y cuantas conversaciones previas mostrará para los distintos sistemas de chateo. El periodo máximo de almacenado permite eliminar mensajes viejos y evita que el historial de chateo se llene de conversaciones intrascendentes (salas de chateo y chateo distante)</p></body></html> - Chatlobbies - Salasdechat + Salasdechat - + Enabled: Habilitar: @@ -2222,11 +2434,12 @@ Haga doble clic en una sala de chat para entrar y conversar. + Chat rooms Salas de chat - + Checked, if the identity and the text above occurrences must be in the same case to trigger count. Márquelo, si las apariciones de la identidad y el texto anterior deben coincidir en mayúsculas y minúsculas para incrementar el recuento. @@ -2287,11 +2500,17 @@ Haga doble clic en una sala de chat para entrar y conversar. + Broadcast Difusión - + + Node-to-node chat + + + + Saved messages (0 = unlimited): Mensajes guardados (0 = ilimitados): @@ -2438,8 +2657,23 @@ Haga doble clic en una sala de chat para entrar y conversar. Chat privado - - mention(s) + + You have %1 mentions + + + + + You have %1 mention + + + + + %1 mentions + + + + + %1 mention @@ -2612,7 +2846,7 @@ Haga doble clic en una sala de chat para entrar y conversar. - + is typing... está escribiendo... @@ -2631,12 +2865,12 @@ after HTML conversion. %1 caracteres tras la conversión a HTML. - + Choose your font. Escoja su fuente. - + Do you really want to physically delete the history? ¿Seguro que quiere borrar el historial? @@ -2708,7 +2942,7 @@ after HTML conversion. No detenerse a colorear después de que X elementos se encontrasen (necesita más CPU) - + <b>Find Previous </b><br/><i>Ctrl+Shift+G</i> <b>Buscar anterior</b><br/><i>Ctrl+Mayús+G</i> @@ -2748,12 +2982,12 @@ after HTML conversion. - + <b>Mark this selected text</b><br><i>Ctrl+M</i> <b>Marcar este texto seleccionado</b><br><i>Ctrl+M</i> - + Person id: Identificación persona: @@ -2770,7 +3004,7 @@ Haga doble clic sobre este para añadir su nombre en el compositor de texto.